UNPKG

ts-generic-collections-linq

Version:

TypeScript library provides strongly-typed, queryable collections.

693 lines 50.8 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ import { List } from './list'; import { Group, objCompare, ITEM_NOT_FOUND_MSG, MULTIPLE_INSTANCES_FOUND_MSG } from './common'; import { Dictionary, KeyValuePair } from './dictionary'; /** * @template TKey */ class StringComparer { /** * @param {?} x * @param {?} y * @return {?} */ compare(x, y) { /** @type {?} */ var xKey = (/** @type {?} */ ((/** @type {?} */ (x)))); /** @type {?} */ var yKey = (/** @type {?} */ ((/** @type {?} */ (y)))); if (xKey > yKey) { return 1; } else if (xKey == yKey) { return 0; } else { return -1; } } } /** * @template TKey */ class NumberComparer { /** * @param {?} x * @param {?} y * @return {?} */ compare(x, y) { /** @type {?} */ var xKey = (/** @type {?} */ ((/** @type {?} */ (x)))); /** @type {?} */ var yKey = (/** @type {?} */ ((/** @type {?} */ (y)))); if (xKey > yKey) { return 1; } else if (xKey == yKey) { return 0; } else { return -1; } } } /** * @template TKey, TValue */ export class SortedDictionary { /** * @param {?} comparer * @param {?=} list */ constructor(comparer, list = null) { this.list = new Array(); if (list) { this.list = list; } this.comparer = comparer; if (this.list && this.list.length > 0) { if (this.comparer) { this.list.sort((/** * @param {?} x * @param {?} y * @return {?} */ (x, y) => this.comparer.compare(x.key, y.key))); } else { /** @type {?} */ var value = this.list[0].key; if (typeof value === "string") { this.comparer = new StringComparer(); this.list = this.list.sort((/** * @param {?} x * @param {?} y * @return {?} */ (x, y) => this.comparer.compare(x.key, y.key))); } else if (typeof value === "number") { this.comparer = new NumberComparer(); this.list = this.list.sort((/** * @param {?} x * @param {?} y * @return {?} */ (x, y) => this.comparer.compare(x.key, y.key))); } } } } /* IList */ /** * @param {?} key * @param {?} value * @return {?} */ add(key, value) { /** @type {?} */ let pair = new KeyValuePair(key, value); if (this.containsKey(key)) { throw "Duplicate key. Cannot add."; } this.list.push(pair); if (this.comparer) { this.list = this.list.sort((/** * @param {?} x * @param {?} y * @return {?} */ (x, y) => this.comparer.compare(x.key, y.key))); } } /** * @param {?} items * @return {?} */ addRange(items) { items.forEach((/** * @param {?} x * @return {?} */ x => this.add(x.key, x.value))); } /** * @param {?} index * @return {?} */ removeAt(index) { this.list.splice(index, 1); } /** * @return {?} */ clear() { this.list = new Array(); } /** * @param {?} predicate * @return {?} */ remove(predicate) { /** @type {?} */ let temp = new Array(); this.list.forEach((/** * @param {?} element * @return {?} */ element => { if (!predicate(element)) { temp.push(element); } })); this.list = temp; } /** * @param {?} key * @return {?} */ containsKey(key) { return this.any((/** * @param {?} x * @return {?} */ x => objCompare(x.key, key))); } /** * @param {?} value * @return {?} */ containsValue(value) { return this.any((/** * @param {?} x * @return {?} */ x => objCompare(x.value, value))); } /** * @param {?} key * @return {?} */ tryGetValue(key) { /** @type {?} */ let item = this.singleOrDefault((/** * @param {?} x * @return {?} */ x => objCompare(x.key, key))); if (item) { return item.value; } return null; } /* IEnumerable */ /** * @return {?} */ asEnumerable() { return this; } /** * @return {?} */ get length() { return this.list.length; } /** * @param {?} index * @return {?} */ elementAt(index) { try { return this.list[index]; } catch (e) { return null; } } /** * @param {?=} predicate * @return {?} */ any(predicate) { if (!predicate) { return this.list.length > 0; } for (let i = 0; i < this.list.length; i++) { if (predicate(this.list[i])) { return true; } } return false; } /** * @param {?=} predicate * @return {?} */ all(predicate) { if (!predicate) { return this.list.length > 0; } for (let i = 0; i < this.list.length; i++) { if (!predicate(this.list[i])) { return false; } } return true; } /** * @param {?=} predicate * @return {?} */ single(predicate = null) { if (this.list.length <= 0) { throw ITEM_NOT_FOUND_MSG; } if (predicate) { /** @type {?} */ let item = this.singleOrDefault(predicate); if (!item) { throw ITEM_NOT_FOUND_MSG; } return item; } return this.list[0]; } /** * @param {?=} predicate * @return {?} */ first(predicate = null) { if (this.list.length <= 0) { throw ITEM_NOT_FOUND_MSG; } if (predicate) { /** @type {?} */ let item = this.firstOrDefault(predicate); if (!item) { throw ITEM_NOT_FOUND_MSG; } return item; } return this.list[0]; } /** * @param {?} predicate * @return {?} */ last(predicate) { if (this.list.length <= 0) { throw ITEM_NOT_FOUND_MSG; } if (predicate) { /** @type {?} */ let item = this.lastOrDefault(predicate); if (!item) { throw ITEM_NOT_FOUND_MSG; } return item; } return this.list[this.list.length - 1]; } /** * @param {?} predicate * @return {?} */ singleOrDefault(predicate) { /** @type {?} */ let temp = new Array(); this.list.filter((/** * @param {?} element * @return {?} */ element => { if (predicate(element)) { temp.push(element); } })); if (temp.length > 1) { throw MULTIPLE_INSTANCES_FOUND_MSG; } if (temp.length <= 0) { return null; } return temp[0]; } /** * @param {?} predicate * @return {?} */ firstOrDefault(predicate) { for (let i = 0; i < this.length; i++) { /** @type {?} */ let item = this.list[i]; if (predicate(item)) { return item; } } return null; } /** * @param {?} predicate * @return {?} */ lastOrDefault(predicate) { for (let i = this.length; i >= 0; i--) { /** @type {?} */ let item = this.list[i - 1]; if (predicate(item)) { return item; } } return null; } /** * @param {?} predicate * @return {?} */ where(predicate) { /** @type {?} */ let temp = new Dictionary(); this.list.filter((/** * @param {?} element * @return {?} */ element => { if (predicate(element)) { temp.add(element.key, element.value); } })); return temp; } /** * @template TResult * @param {?} predicate * @return {?} */ select(predicate) { /** @type {?} */ let temp = new List(); this.forEach((/** * @param {?} x * @return {?} */ x => temp.add(predicate(x)))); return temp; } /** * @param {?} predicate * @return {?} */ forEach(predicate) { this.list.forEach((/** * @param {?} x * @return {?} */ x => predicate(x))); } /** * @return {?} */ toArray() { return this.list.slice(); } /** * @template TOuter, TMatch, TResult * @param {?} outer * @param {?} conditionInner * @param {?} conditionOuter * @param {?} select * @param {?=} leftJoin * @return {?} */ join(outer, conditionInner, conditionOuter, select, leftJoin = false) { /** @type {?} */ let resultList = new List(); this.list.forEach((/** * @param {?} x * @return {?} */ x => { /** @type {?} */ let outerEntries = outer.toArray().filter((/** * @param {?} y * @return {?} */ y => conditionInner(x) === conditionOuter(y))); if (leftJoin && outerEntries && outerEntries.length <= 0) { resultList.add(select(x, null)); } else { outerEntries.forEach((/** * @param {?} z * @return {?} */ z => resultList.add(select(x, z)))); } })); return resultList; } /** * @param {?} predicate * @return {?} */ groupBy(predicate) { /** @type {?} */ let groups = {}; this.list.forEach((/** * @param {?} o * @return {?} */ function (o) { /** @type {?} */ var group = JSON.stringify(predicate(o)); groups[group] = groups[group] || []; groups[group].push(o); })); /** @type {?} */ let g = Object.keys(groups).map((/** * @param {?} group * @return {?} */ function (group) { /** @type {?} */ let a = group.substr(1, group.length - 2); /** @type {?} */ let grp = new Group(new List(a.split(',')).select((/** * @param {?} x * @return {?} */ x => x.replace(/^(")?(.*?)(")?$/ig, "$2"))).toArray(), groups[group]); return grp; })); return new List(g); } /** * @template TResult * @param {?} predicate * @return {?} */ selectMany(predicate) { return this.list.reduce((/** * @param {?} out * @param {?} inx * @return {?} */ (out, inx) => { /** @type {?} */ var items = predicate(inx); out.addRange(items); return out; }), new List(new Array())); } /** * @param {?} comparer * @return {?} */ orderBy(comparer) { /** @type {?} */ let temp = this.list.sort((/** * @param {?} x * @param {?} y * @return {?} */ (x, y) => comparer.compare(x, y))); return new List(temp); } /** * @param {?} comparer * @return {?} */ distinct(comparer) { /** @type {?} */ let uniques = new List(); this.forEach((/** * @param {?} x * @return {?} */ x => { if (uniques.length > 0) { if (!uniques.any((/** * @param {?} y * @return {?} */ y => comparer.equals(x, y)))) { uniques.add(x); } } else { uniques.add(x); } })); return uniques; } /** * @param {?} list * @return {?} */ union(list) { this.addRange(list.toArray()); return this; } /** * @return {?} */ reverse() { return new List(this.list.slice().reverse()); } /** * @param {?} no * @return {?} */ skip(no) { if (no > 0) { return new Dictionary(this.list.slice(no, this.list.length - 1)); } return this; } /** * @param {?} no * @return {?} */ take(no) { if (no > 0) { return new Dictionary(this.list.slice(0, no)); } return this; } /** * @param {?} predicate * @return {?} */ sum(predicate) { /** @type {?} */ let sum = 0; this.list.forEach((/** * @param {?} x * @return {?} */ x => sum = sum + predicate(x))); return sum; } /** * @param {?} predicate * @return {?} */ avg(predicate) { return this.sum(predicate) / this.length; } /** * @param {?} predicate * @return {?} */ min(predicate) { /** @type {?} */ let min = 0; /** @type {?} */ let i = 0; this.list.forEach((/** * @param {?} x * @return {?} */ x => { if (i == 0) { min = predicate(x); } else { /** @type {?} */ let val = predicate(x); if (val < min) { min = val; } } i++; })); return min; } /** * @param {?} predicate * @return {?} */ max(predicate) { /** @type {?} */ let max = 0; /** @type {?} */ let i = 0; this.list.forEach((/** * @param {?} x * @return {?} */ x => { if (i == 0) { max = predicate(x); } else { /** @type {?} */ let val = predicate(x); if (val > max) { max = val; } } i++; })); return max; } /** * @param {?=} predicate * @return {?} */ count(predicate = null) { if (!predicate) { return this.length; } /** @type {?} */ let count = 0; this.list.forEach((/** * @param {?} x * @return {?} */ x => { if (predicate(x)) { count++; } })); return count; } } if (false) { /** * @type {?} * @private */ SortedDictionary.prototype.list; /** * @type {?} * @private */ SortedDictionary.prototype.comparer; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic29ydGVkLmRpY3Rpb25hcnkuanMiLCJzb3VyY2VSb290Ijoibmc6Ly90cy1nZW5lcmljLWNvbGxlY3Rpb25zLWxpbnEvIiwic291cmNlcyI6WyJsaWIvc29ydGVkLmRpY3Rpb25hcnkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQUNBLE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxRQUFRLENBQUM7QUFDOUIsT0FBTyxFQUFFLEtBQUssRUFBRSxVQUFVLEVBQUUsa0JBQWtCLEVBQUUsNEJBQTRCLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFDL0YsT0FBTyxFQUFlLFVBQVUsRUFBRSxZQUFZLEVBQUUsTUFBTSxjQUFjLENBQUM7Ozs7QUFFckUsTUFBTSxjQUFjOzs7Ozs7SUFDaEIsT0FBTyxDQUFDLENBQU8sRUFBRSxDQUFPOztZQUNoQixJQUFJLEdBQUcsbUJBQUEsbUJBQUEsQ0FBQyxFQUFXLEVBQVU7O1lBQzdCLElBQUksR0FBRyxtQkFBQSxtQkFBQSxDQUFDLEVBQVcsRUFBVTtRQUVqQyxJQUFJLElBQUksR0FBRyxJQUFJLEVBQUU7WUFDYixPQUFPLENBQUMsQ0FBQztTQUNaO2FBQ0ksSUFBSSxJQUFJLElBQUksSUFBSSxFQUFFO1lBQ25CLE9BQU8sQ0FBQyxDQUFDO1NBQ1o7YUFDSTtZQUNELE9BQU8sQ0FBQyxDQUFDLENBQUM7U0FDYjtJQUNMLENBQUM7Q0FDSjs7OztBQUVELE1BQU0sY0FBYzs7Ozs7O0lBQ2hCLE9BQU8sQ0FBQyxDQUFPLEVBQUUsQ0FBTzs7WUFDaEIsSUFBSSxHQUFHLG1CQUFBLG1CQUFBLENBQUMsRUFBVyxFQUFVOztZQUM3QixJQUFJLEdBQUcsbUJBQUEsbUJBQUEsQ0FBQyxFQUFXLEVBQVU7UUFFakMsSUFBSSxJQUFJLEdBQUcsSUFBSSxFQUFFO1lBQ2IsT0FBTyxDQUFDLENBQUM7U0FDWjthQUNJLElBQUksSUFBSSxJQUFJLElBQUksRUFBRTtZQUNuQixPQUFPLENBQUMsQ0FBQztTQUNaO2FBQ0k7WUFDRCxPQUFPLENBQUMsQ0FBQyxDQUFDO1NBQ2I7SUFDTCxDQUFDO0NBQ0o7Ozs7QUFFRCxNQUFNLE9BQU8sZ0JBQWdCOzs7OztJQUt6QixZQUFZLFFBQXlCLEVBQUUsT0FBMEMsSUFBSTtRQUg3RSxTQUFJLEdBQXNDLElBQUksS0FBSyxFQUE4QixDQUFDO1FBSXRGLElBQUksSUFBSSxFQUFFO1lBQ04sSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7U0FDcEI7UUFFRCxJQUFJLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQztRQUV6QixJQUFJLElBQUksQ0FBQyxJQUFJLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUNyQztZQUNJLElBQUksSUFBSSxDQUFDLFFBQVEsRUFBRTtnQkFDZixJQUFJLENBQUMsSUFBSSxDQUFDLElBQUk7Ozs7O2dCQUFDLENBQUMsQ0FBQyxFQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUMsQ0FBQzthQUNoRTtpQkFDSTs7b0JBQ0csS0FBSyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRztnQkFFNUIsSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRLEVBQUU7b0JBQzNCLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxjQUFjLEVBQVEsQ0FBQztvQkFFM0MsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUk7Ozs7O29CQUFDLENBQUMsQ0FBQyxFQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUMsQ0FBQztpQkFDNUU7cUJBQ0ksSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRLEVBQUU7b0JBQ2hDLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxjQUFjLEVBQVEsQ0FBQztvQkFFM0MsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUk7Ozs7O29CQUFDLENBQUMsQ0FBQyxFQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUMsQ0FBQztpQkFDNUU7YUFDSjtTQUNKO0lBQ0wsQ0FBQzs7Ozs7OztJQUlELEdBQUcsQ0FBQyxHQUFTLEVBQUUsS0FBYTs7WUFDcEIsSUFBSSxHQUFHLElBQUksWUFBWSxDQUFlLEdBQUcsRUFBRSxLQUFLLENBQUM7UUFFckQsSUFBSSxJQUFJLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxFQUFFO1lBQ3ZCLE1BQU0sNEJBQTRCLENBQUE7U0FDckM7UUFFRCxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUVyQixJQUFJLElBQUksQ0FBQyxRQUFRLEVBQUU7WUFDZixJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSTs7Ozs7WUFBQyxDQUFDLENBQUMsRUFBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFDLENBQUM7U0FDNUU7SUFDTCxDQUFDOzs7OztJQUVELFFBQVEsQ0FBQyxLQUFtQztRQUN4QyxLQUFLLENBQUMsT0FBTzs7OztRQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxLQUFLLENBQUMsRUFBQyxDQUFDO0lBQ2pELENBQUM7Ozs7O0lBRUQsUUFBUSxDQUFDLEtBQWE7UUFDbEIsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQy9CLENBQUM7Ozs7SUFFRCxLQUFLO1FBQ0QsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLEtBQUssRUFBOEIsQ0FBQztJQUN4RCxDQUFDOzs7OztJQUVELE1BQU0sQ0FBQyxTQUF1RDs7WUFDdEQsSUFBSSxHQUFHLElBQUksS0FBSyxFQUE4QjtRQUVsRCxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU87Ozs7UUFBQyxPQUFPLENBQUMsRUFBRTtZQUN4QixJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxFQUN2QjtnQkFDSSxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO2FBQ3RCO1FBQ0wsQ0FBQyxFQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztJQUNyQixDQUFDOzs7OztJQUVELFdBQVcsQ0FBQyxHQUFTO1FBQ2pCLE9BQU8sSUFBSSxDQUFDLEdBQUc7Ozs7UUFBQyxDQUFDLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxFQUFDLENBQUM7SUFDakQsQ0FBQzs7Ozs7SUFFRCxhQUFhLENBQUMsS0FBYTtRQUN2QixPQUFPLElBQUksQ0FBQyxHQUFHOzs7O1FBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsRUFBQyxDQUFDO0lBQ3JELENBQUM7Ozs7O0lBRUQsV0FBVyxDQUFDLEdBQVM7O1lBQ2IsSUFBSSxHQUFHLElBQUksQ0FBQyxlQUFlOzs7O1FBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsRUFBQztRQUU1RCxJQUFJLElBQUksRUFBRTtZQUNOLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQztTQUNyQjtRQUVELE9BQU8sSUFBSSxDQUFDO0lBQ2hCLENBQUM7Ozs7O0lBSUQsWUFBWTtRQUNSLE9BQU8sSUFBSSxDQUFDO0lBQ2hCLENBQUM7Ozs7SUFFRCxJQUFJLE1BQU07UUFDTixPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDO0lBQzVCLENBQUM7Ozs7O0lBRUQsU0FBUyxDQUFDLEtBQWE7UUFDbkIsSUFBSTtZQUNBLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztTQUMzQjtRQUNELE9BQU8sQ0FBQyxFQUFFO1lBQ04sT0FBTyxJQUFJLENBQUM7U0FDZjtJQUNMLENBQUM7Ozs7O0lBRUQsR0FBRyxDQUFDLFNBQXdEO1FBQ3hELElBQUksQ0FBQyxTQUFTLEVBQUU7WUFDWixPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQztTQUMvQjtRQUVELEtBQUssSUFBSSxDQUFDLEdBQUMsQ0FBQyxFQUFFLENBQUMsR0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtZQUNuQyxJQUFJLFNBQVMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQzNCO2dCQUNJLE9BQU8sSUFBSSxDQUFDO2FBQ2Y7U0FDSjtRQUNELE9BQU8sS0FBSyxDQUFDO0lBQ2pCLENBQUM7Ozs7O0lBRUQsR0FBRyxDQUFDLFNBQXdEO1FBQ3hELElBQUksQ0FBQyxTQUFTLEVBQUU7WUFDWixPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQztTQUMvQjtRQUVELEtBQUssSUFBSSxDQUFDLEdBQUMsQ0FBQyxFQUFFLENBQUMsR0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtZQUNuQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFDNUI7Z0JBQ0ksT0FBTyxLQUFLLENBQUM7YUFDaEI7U0FDSjtRQUNELE9BQU8sSUFBSSxDQUFDO0lBQ2hCLENBQUM7Ozs7O0lBRUQsTUFBTSxDQUFDLFlBQTBELElBQUk7UUFDakUsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sSUFBSSxDQUFDLEVBQUU7WUFDdkIsTUFBTSxrQkFBa0IsQ0FBQztTQUM1QjtRQUVELElBQUksU0FBUyxFQUFFOztnQkFDUCxJQUFJLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxTQUFTLENBQUM7WUFFMUMsSUFBSSxDQUFDLElBQUksRUFBRTtnQkFDUCxNQUFNLGtCQUFrQixDQUFDO2FBQzVCO1lBRUQsT0FBTyxJQUFJLENBQUM7U0FDZjtRQUVELE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUN4QixDQUFDOzs7OztJQUVELEtBQUssQ0FBQyxZQUEwRCxJQUFJO1FBQ2hFLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLElBQUksQ0FBQyxFQUFFO1lBQ3ZCLE1BQU0sa0JBQWtCLENBQUM7U0FDNUI7UUFFRCxJQUFJLFNBQVMsRUFBRTs7Z0JBQ1AsSUFBSSxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsU0FBUyxDQUFDO1lBRXpDLElBQUksQ0FBQyxJQUFJLEVBQUU7Z0JBQ1AsTUFBTSxrQkFBa0IsQ0FBQzthQUM1QjtZQUVELE9BQU8sSUFBSSxDQUFDO1NBQ2Y7UUFFRCxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDeEIsQ0FBQzs7Ozs7SUFFRCxJQUFJLENBQUMsU0FBdUQ7UUFDeEQsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sSUFBSSxDQUFDLEVBQUU7WUFDdkIsTUFBTSxrQkFBa0IsQ0FBQztTQUM1QjtRQUVELElBQUksU0FBUyxFQUFFOztnQkFDUCxJQUFJLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxTQUFTLENBQUM7WUFFeEMsSUFBSSxDQUFDLElBQUksRUFBRTtnQkFDUCxNQUFNLGtCQUFrQixDQUFDO2FBQzVCO1lBRUQsT0FBTyxJQUFJLENBQUM7U0FDZjtRQUVELE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQztJQUMzQyxDQUFDOzs7OztJQUVELGVBQWUsQ0FBQyxTQUF1RDs7WUFDL0QsSUFBSSxHQUFHLElBQUksS0FBSyxFQUE4QjtRQUVsRCxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU07Ozs7UUFBQyxPQUFPLENBQUMsRUFBRTtZQUN2QixJQUFJLFNBQVMsQ0FBQyxPQUFPLENBQUMsRUFDdEI7Z0JBQ0ksSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQzthQUN0QjtRQUNMLENBQUMsRUFBQyxDQUFDO1FBRUgsSUFBSSxJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtZQUNqQixNQUFNLDRCQUE0QixDQUFDO1NBQ3RDO1FBRUQsSUFBSSxJQUFJLENBQUMsTUFBTSxJQUFJLENBQUMsRUFBRTtZQUNsQixPQUFPLElBQUksQ0FBQztTQUNmO1FBRUQsT0FBTyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDbkIsQ0FBQzs7Ozs7SUFFRCxjQUFjLENBQUMsU0FBdUQ7UUFDbEUsS0FBSyxJQUFJLENBQUMsR0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7O2dCQUMxQixJQUFJLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7WUFDdkIsSUFBSSxTQUFTLENBQUMsSUFBSSxDQUFDLEVBQ25CO2dCQUNJLE9BQU8sSUFBSSxDQUFDO2FBQ2Y7U0FDSjtRQUVELE9BQU8sSUFBSSxDQUFDO0lBQ2hCLENBQUM7Ozs7O0lBRUQsYUFBYSxDQUFDLFNBQXVEO1FBQ2pFLEtBQUssSUFBSSxDQUFDLEdBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLElBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFOztnQkFDM0IsSUFBSSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUMzQixJQUFJLFNBQVMsQ0FBQyxJQUFJLENBQUMsRUFDbkI7Z0JBQ0ksT0FBTyxJQUFJLENBQUM7YUFDZjtTQUNKO1FBRUQsT0FBTyxJQUFJLENBQUM7SUFDaEIsQ0FBQzs7Ozs7SUFFRCxLQUFLLENBQUMsU0FBdUQ7O1lBQ3JELElBQUksR0FBRyxJQUFJLFVBQVUsRUFBZ0I7UUFFekMsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNOzs7O1FBQUMsT0FBTyxDQUFDLEVBQUU7WUFDdkIsSUFBSSxTQUFTLENBQUMsT0FBTyxDQUFDLEVBQ3RCO2dCQUNJLElBQUksQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBRSxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUM7YUFDeEM7UUFDTCxDQUFDLEVBQUMsQ0FBQztRQUVILE9BQU8sSUFBSSxDQUFDO0lBQ2hCLENBQUM7Ozs7OztJQUVELE1BQU0sQ0FBVSxTQUF1RDs7WUFDL0QsSUFBSSxHQUFHLElBQUksSUFBSSxFQUFXO1FBRTlCLElBQUksQ0FBQyxPQUFPOzs7O1FBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFDLENBQUM7UUFFMUMsT0FBTyxJQUFJLENBQUM7SUFDaEIsQ0FBQzs7Ozs7SUFFRCxPQUFPLENBQUMsU0FBb0Q7UUFDeEQsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPOzs7O1FBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUMsQ0FBQztJQUN6QyxDQUFDOzs7O0lBRUQsT0FBTztRQUNILE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUM3QixDQUFDOzs7Ozs7Ozs7O0lBRUQsSUFBSSxDQUEwQixLQUEwQixFQUFFLGNBQTJELEVBQ3JGLGNBQXVDLEVBQUUsTUFBMkQsRUFBRSxXQUFvQixLQUFLOztZQUN2SixVQUFVLEdBQUcsSUFBSSxJQUFJLEVBQVc7UUFFcEMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPOzs7O1FBQUMsQ0FBQyxDQUFDLEVBQUU7O2dCQUNkLFlBQVksR0FBRyxLQUFLLENBQUMsT0FBTyxFQUFFLENBQUMsTUFBTTs7OztZQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQyxLQUFLLGNBQWMsQ0FBQyxDQUFDLENBQUMsRUFBQztZQUV2RixJQUFJLFFBQVEsSUFBSSxZQUFZLElBQUksWUFBWSxDQUFDLE1BQU0sSUFBSSxDQUFDLEVBQUU7Z0JBQ3RELFVBQVUsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDO2FBQ25DO2lCQUNJO2dCQUNELFlBQVksQ0FBQyxPQUFPOzs7O2dCQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUMsQ0FBQzthQUMzRDtRQUNMLENBQUMsRUFBQyxDQUFBO1FBRUYsT0FBTyxVQUFVLENBQUM7SUFDdEIsQ0FBQzs7Ozs7SUFFRCxPQUFPLENBQUMsU0FBMkQ7O1lBQzNELE1BQU0sR0FBRyxFQUFFO1FBQ2YsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPOzs7O1FBQUMsVUFBVSxDQUFDOztnQkFDdkIsS0FBSyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3hDLE1BQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDO1lBQ3BDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDeEIsQ0FBQyxFQUFDLENBQUM7O1lBQ0MsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRzs7OztRQUFDLFVBQVUsS0FBSzs7Z0JBQ3ZDLENBQUMsR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBRSxLQUFLLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQzs7Z0JBRXJDLEdBQUcsR0FBRSxJQUFJLEtBQUssQ0FBNkIsSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLE1BQU07Ozs7WUFBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsbUJBQW1CLEVBQUUsSUFBSSxDQUFDLEVBQUMsQ0FBQyxPQUFPLEVBQUUsRUFDekcsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBRXRDLE9BQU8sR0FBRyxDQUFDO1FBQ2YsQ0FBQyxFQUFDO1FBRUYsT0FBTyxJQUFJLElBQUksQ0FBb0MsQ0FBQyxDQUFDLENBQUM7SUFDMUQsQ0FBQzs7Ozs7O0lBRUQsVUFBVSxDQUFVLFNBQThEO1FBQzlFLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNOzs7OztRQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxFQUFFOztnQkFDN0IsS0FBSyxHQUFHLFNBQVMsQ0FBQyxHQUFHLENBQUM7WUFDMUIsR0FBRyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUNwQixPQUFPLEdBQUcsQ0FBQztRQUNiLENBQUMsR0FBRSxJQUFJLElBQUksQ0FBVSxJQUFJLEtBQUssRUFBVyxDQUFDLENBQUMsQ0FBQztJQUNsRCxDQUFDOzs7OztJQUVELE9BQU8sQ0FBQyxRQUErQzs7WUFDL0MsSUFBSSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSTs7Ozs7UUFBQyxDQUFDLENBQUMsRUFBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFDO1FBRTFELE9BQU8sSUFBSSxJQUFJLENBQTZCLElBQUksQ0FBQyxDQUFDO0lBQ3RELENBQUM7Ozs7O0lBRUQsUUFBUSxDQUFDLFFBQXVEOztZQUN4RCxPQUFPLEdBQUcsSUFBSSxJQUFJLEVBQThCO1FBQ3BELElBQUksQ0FBQyxPQUFPOzs7O1FBQUMsQ0FBQyxDQUFDLEVBQUU7WUFDYixJQUFJLE9BQU8sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO2dCQUNwQixJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUc7Ozs7Z0JBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBQyxFQUM1QztvQkFDSSxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO2lCQUNsQjthQUNKO2lCQUNJO2dCQUNELE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7YUFDbEI7UUFDTCxDQUFDLEVBQUMsQ0FBQztRQUVILE9BQU8sT0FBTyxDQUFDO0lBQ25CLENBQUM7Ozs7O0lBRUQsS0FBSyxDQUFDLElBQTZDO1FBQzlDLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7UUFFOUIsT0FBTyxJQUFJLENBQUM7SUFDakIsQ0FBQzs7OztJQUVELE9BQU87UUFDSCxPQUFPLElBQUksSUFBSSxDQUE2QixJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7SUFDN0UsQ0FBQzs7Ozs7SUFFRCxJQUFJLENBQUMsRUFBVTtRQUNYLElBQUksRUFBRSxHQUFHLENBQUMsRUFBRTtZQUNSLE9BQU8sSUFBSSxVQUFVLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7U0FDcEU7UUFFRCxPQUFPLElBQUksQ0FBQztJQUNoQixDQUFDOzs7OztJQUVELElBQUksQ0FBQyxFQUFVO1FBQ1gsSUFBSSxFQUFFLEdBQUcsQ0FBQyxFQUFFO1lBQ1IsT0FBTyxJQUFJLFVBQVUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQztTQUNqRDtRQUVELE9BQU8sSUFBSSxDQUFDO0lBQ2hCLENBQUM7Ozs7O0lBRUQsR0FBRyxDQUFDLFNBQXNEOztZQUNsRCxHQUFHLEdBQVcsQ0FBQztRQUNuQixJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU87Ozs7UUFBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEdBQUcsR0FBRyxHQUFHLEdBQUcsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFDLENBQUM7UUFFakQsT0FBTyxHQUFHLENBQUM7SUFDZixDQUFDOzs7OztJQUVELEdBQUcsQ0FBQyxTQUFzRDtRQUN0RCxPQUFPLElBQUksQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztJQUM3QyxDQUFDOzs7OztJQUVELEdBQUcsQ0FBQyxTQUFzRDs7WUFDbEQsR0FBRyxHQUFXLENBQUM7O1lBQ2YsQ0FBQyxHQUFHLENBQUM7UUFDVCxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU87Ozs7UUFBQyxDQUFDLENBQUMsRUFBRTtZQUVsQixJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUU7Z0JBQ1IsR0FBRyxHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQzthQUN0QjtpQkFDSTs7b0JBQ0csR0FBRyxHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUM7Z0JBQ3RCLElBQUksR0FBRyxHQUFHLEdBQUcsRUFBRTtvQkFDWCxHQUFHLEdBQUcsR0FBRyxDQUFDO2lCQUNiO2FBQ0o7WUFDRCxDQUFDLEVBQUUsQ0FBQztRQUNSLENBQUMsRUFBQyxDQUFDO1FBRUgsT0FBTyxHQUFHLENBQUM7SUFDZixDQUFDOzs7OztJQUVELEdBQUcsQ0FBQyxTQUFzRDs7WUFDbEQsR0FBRyxHQUFXLENBQUM7O1lBQ2YsQ0FBQyxHQUFHLENBQUM7UUFDVCxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU87Ozs7UUFBQyxDQUFDLENBQUMsRUFBRTtZQUVsQixJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUU7Z0JBQ1IsR0FBRyxHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQzthQUN0QjtpQkFDSTs7b0JBQ0csR0FBRyxHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUM7Z0JBQ3RCLElBQUksR0FBRyxHQUFHLEdBQUcsRUFBRTtvQkFDWCxHQUFHLEdBQUcsR0FBRyxDQUFDO2lCQUNiO2FBQ0o7WUFDRCxDQUFDLEVBQUUsQ0FBQztRQUNSLENBQUMsRUFBQyxDQUFDO1FBRUgsT0FBTyxHQUFHLENBQUM7SUFDZixDQUFDOzs7OztJQUVELEtBQUssQ0FBQyxZQUEwRCxJQUFJO1FBQ2hFLElBQUksQ0FBQyxTQUFTLEVBQUU7WUFDWixPQUFPLElBQUksQ0FBQyxNQUFNLENBQUM7U0FDdEI7O1lBRUcsS0FBSyxHQUFXLENBQUM7UUFDckIsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPOzs7O1FBQUMsQ0FBQyxDQUFDLEVBQUU7WUFDbEIsSUFBRyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUU7Z0JBQ2IsS0FBSyxFQUFFLENBQUM7YUFDWDtRQUNMLENBQUMsRUFBQyxDQUFDO1FBRUgsT0FBTyxLQUFLLENBQUM7SUFDakIsQ0FBQztDQUNKOzs7Ozs7SUF6YUcsZ0NBQTBGOzs7OztJQUMxRixvQ0FBa0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJRW51bWVyYWJsZSwgSUNvbXBhcmVyLCBJRXF1YWxpdHlDb21wYXJlciB9IGZyb20gJy4vaW50ZXJmYWNlcyc7XHJcbmltcG9ydCB7IExpc3QgfSBmcm9tICcuL2xpc3QnO1xyXG5pbXBvcnQgeyBHcm91cCwgb2JqQ29tcGFyZSwgSVRFTV9OT1RfRk9VTkRfTVNHLCBNVUxUSVBMRV9JTlNUQU5DRVNfRk9VTkRfTVNHIH0gZnJvbSAnLi9jb21tb24nO1xyXG5pbXBvcnQgeyBJRGljdGlvbmFyeSwgRGljdGlvbmFyeSwgS2V5VmFsdWVQYWlyIH0gZnJvbSAnLi9kaWN0aW9uYXJ5JztcclxuXHJcbmNsYXNzIFN0cmluZ0NvbXBhcmVyPFRLZXk+IGltcGxlbWVudHMgSUNvbXBhcmVyPFRLZXk+IHtcclxuICAgIGNvbXBhcmUoeDogVEtleSwgeTogVEtleSkgOiBudW1iZXIge1xyXG4gICAgICAgIHZhciB4S2V5ID0geCBhcyB1bmtub3duIGFzIHN0cmluZztcclxuICAgICAgICB2YXIgeUtleSA9IHkgYXMgdW5rbm93biBhcyBzdHJpbmc7XHJcblxyXG4gICAgICAgIGlmICh4S2V5ID4geUtleSkge1xyXG4gICAgICAgICAgICByZXR1cm4gMTsgICAgICAgICAgICBcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAoeEtleSA9PSB5S2V5KSB7XHJcbiAgICAgICAgICAgIHJldHVybiAwO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgcmV0dXJuIC0xO1xyXG4gICAgICAgIH0gICAgICAgIFxyXG4gICAgfVxyXG59XHJcblxyXG5jbGFzcyBOdW1iZXJDb21wYXJlcjxUS2V5PiBpbXBsZW1lbnRzIElDb21wYXJlcjxUS2V5PiB7XHJcbiAgICBjb21wYXJlKHg6IFRLZXksIHk6IFRLZXkpIDogbnVtYmVyIHtcclxuICAgICAgICB2YXIgeEtleSA9IHggYXMgdW5rbm93biBhcyBudW1iZXI7XHJcbiAgICAgICAgdmFyIHlLZXkgPSB5IGFzIHVua25vd24gYXMgbnVtYmVyO1xyXG5cclxuICAgICAgICBpZiAoeEtleSA+IHlLZXkpIHtcclxuICAgICAgICAgICAgcmV0dXJuIDE7ICAgICAgICAgICAgXHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2UgaWYgKHhLZXkgPT0geUtleSkge1xyXG4gICAgICAgICAgICByZXR1cm4gMDtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIHJldHVybiAtMTtcclxuICAgICAgICB9ICAgICAgIFxyXG4gICAgfVxyXG59XHJcblxyXG5leHBvcnQgY2xhc3MgU29ydGVkRGljdGlvbmFyeTxUS2V5LCBUVmFsdWU+IGltcGxlbWVudHMgSURpY3Rpb25hcnk8VEtleSwgVFZhbHVlPlxyXG57XHJcbiAgICBwcml2YXRlIGxpc3Q6IEFycmF5PEtleVZhbHVlUGFpcjxUS2V5LCBUVmFsdWU+PiA9IG5ldyBBcnJheTxLZXlWYWx1ZVBhaXI8VEtleSwgVFZhbHVlPj4oKTtcclxuICAgIHByaXZhdGUgY29tcGFyZXI6IElDb21wYXJlcjxUS2V5PjtcclxuXHJcbiAgICBjb25zdHJ1Y3Rvcihjb21wYXJlcjogSUNvbXBhcmVyPFRLZXk+LCBsaXN0OiBBcnJheTxLZXlWYWx1ZVBhaXI8VEtleSwgVFZhbHVlPj4gPSBudWxsKSB7XHJcbiAgICAgICAgaWYgKGxpc3QpIHtcclxuICAgICAgICAgICAgdGhpcy5saXN0ID0gbGlzdDsgICAgICAgICAgICBcclxuICAgICAgICB9ICAgICAgICBcclxuXHJcbiAgICAgICAgdGhpcy5jb21wYXJlciA9IGNvbXBhcmVyO1xyXG5cclxuICAgICAgICBpZiAodGhpcy5saXN0ICYmIHRoaXMubGlzdC5sZW5ndGggPiAwKVxyXG4gICAgICAgIHtcclxuICAgICAgICAgICAgaWYgKHRoaXMuY29tcGFyZXIpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMubGlzdC5zb3J0KCh4LHkpID0+IHRoaXMuY29tcGFyZXIuY29tcGFyZSh4LmtleSwgeS5rZXkpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHZhciB2YWx1ZSA9IHRoaXMubGlzdFswXS5rZXk7XHJcbiAgICBcclxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCIpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbXBhcmVyID0gbmV3IFN0cmluZ0NvbXBhcmVyPFRLZXk+KCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMubGlzdCA9IHRoaXMubGlzdC5zb3J0KCh4LHkpID0+IHRoaXMuY29tcGFyZXIuY29tcGFyZSh4LmtleSwgeS5rZXkpKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJudW1iZXJcIikge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29tcGFyZXIgPSBuZXcgTnVtYmVyQ29tcGFyZXI8VEtleT4oKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5saXN0ID0gdGhpcy5saXN0LnNvcnQoKHgseSkgPT4gdGhpcy5jb21wYXJlci5jb21wYXJlKHgua2V5LCB5LmtleSkpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qIElMaXN0ICovXHJcblxyXG4gICAgYWRkKGtleTogVEtleSwgdmFsdWU6IFRWYWx1ZSkgOiB2b2lkIHtcclxuICAgICAgICBsZXQgcGFpciA9IG5ldyBLZXlWYWx1ZVBhaXI8VEtleSwgVFZhbHVlPihrZXksIHZhbHVlKTtcclxuXHJcbiAgICAgICAgaWYgKHRoaXMuY29udGFpbnNLZXkoa2V5KSkge1xyXG4gICAgICAgICAgICB0aHJvdyBcIkR1cGxpY2F0ZSBrZXkuIENhbm5vdCBhZGQuXCJcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMubGlzdC5wdXNoKHBhaXIpO1xyXG5cclxuICAgICAgICBpZiAodGhpcy5jb21wYXJlcikge1xyXG4gICAgICAgICAgICB0aGlzLmxpc3QgPSB0aGlzLmxpc3Quc29ydCgoeCx5KSA9PiB0aGlzLmNvbXBhcmVyLmNvbXBhcmUoeC5rZXksIHkua2V5KSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGFkZFJhbmdlKGl0ZW1zOiBLZXlWYWx1ZVBhaXI8VEtleSwgVFZhbHVlPltdKSA6IHZvaWQge1xyXG4gICAgICAgIGl0ZW1zLmZvckVhY2goeCA9PiB0aGlzLmFkZCh4LmtleSwgeC52YWx1ZSkpO1xyXG4gICAgfVxyXG5cclxuICAgIHJlbW92ZUF0KGluZGV4OiBudW1iZXIpIDogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5saXN0LnNwbGljZShpbmRleCwgMSk7XHJcbiAgICB9XHJcblxyXG4gICAgY2xlYXIoKSA6IHZvaWQge1xyXG4gICAgICAgIHRoaXMubGlzdCA9IG5ldyBBcnJheTxLZXlWYWx1ZVBhaXI8VEtleSwgVFZhbHVlPj4oKTtcclxuICAgIH0gICAgXHJcblxyXG4gICAgcmVtb3ZlKHByZWRpY2F0ZTogKGl0ZW06S2V5VmFsdWVQYWlyPFRLZXksIFRWYWx1ZT4pID0+IGJvb2xlYW4pIDogdm9pZCB7XHJcbiAgICAgICAgbGV0IHRlbXAgPSBuZXcgQXJyYXk8S2V5VmFsdWVQYWlyPFRLZXksIFRWYWx1ZT4+KCk7XHJcblxyXG4gICAgICAgIHRoaXMubGlzdC5mb3JFYWNoKGVsZW1lbnQgPT4ge1xyXG4gICAgICAgICAgICBpZiAoIXByZWRpY2F0ZShlbGVtZW50KSlcclxuICAgICAgICAgICAge1xyXG4gICAgICAgICAgICAgICAgdGVtcC5wdXNoKGVsZW1lbnQpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIHRoaXMubGlzdCA9IHRlbXA7XHJcbiAgICB9ICAgIFxyXG5cclxuICAgIGNvbnRhaW5zS2V5KGtleTogVEtleSkgOiBib29sZWFuIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5hbnkoeCA9PiBvYmpDb21wYXJlKHgua2V5LCBrZXkpKTtcclxuICAgIH1cclxuXHJcbiAgICBjb250YWluc1ZhbHVlKHZhbHVlOiBUVmFsdWUpIDogYm9vbGVhbiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuYW55KHggPT4gb2JqQ29tcGFyZSh4LnZhbHVlLCB2YWx1ZSkpO1xyXG4gICAgfVxyXG5cclxuICAgIHRyeUdldFZhbHVlKGtleTogVEtleSkgOiBUVmFsdWUge1xyXG4gICAgICAgIGxldCBpdGVtID0gdGhpcy5zaW5nbGVPckRlZmF1bHQoeCA9PiBvYmpDb21wYXJlKHgua2V5LCBrZXkpKTtcclxuXHJcbiAgICAgICAgaWYgKGl0ZW0pIHtcclxuICAgICAgICAgICAgcmV0dXJuIGl0ZW0udmFsdWU7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgIH1cclxuXHJcbiAgICAvKiBJRW51bWVyYWJsZSAqL1xyXG5cclxuICAgIGFzRW51bWVyYWJsZSgpIDogSUVudW1lcmFibGU8S2V5VmFsdWVQYWlyPFRLZXksIFRWYWx1ZT4+IHtcclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH1cclxuXHJcbiAgICBnZXQgbGVuZ3RoKCk6IG51bWJlciB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMubGlzdC5sZW5ndGg7XHJcbiAgICB9XHJcblxyXG4gICAgZWxlbWVudEF0KGluZGV4OiBudW1iZXIpIDogS2V5VmFsdWVQYWlyPFRLZXksIFRWYWx1ZT4ge1xyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmxpc3RbaW5kZXhdO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgICAgICB9XHJcbiAgICB9ICAgIFxyXG5cclxuICAgIGFueShwcmVkaWNhdGU/OiAoaXRlbTogS2V5VmFsdWVQYWlyPFRLZXksIFRWYWx1ZT4pPT4gYm9vbGVhbikgOiBib29sZWFuIHtcclxuICAgICAgICBpZiAoIXByZWRpY2F0ZSkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5saXN0Lmxlbmd0aCA+IDA7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBmb3IgKGxldCBpPTA7IGk8dGhpcy5saXN0Lmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGlmIChwcmVkaWNhdGUodGhpcy5saXN0W2ldKSlcclxuICAgICAgICAgICAge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG5cclxuICAgIGFsbChwcmVkaWNhdGU/OiAoaXRlbTogS2V5VmFsdWVQYWlyPFRLZXksIFRWYWx1ZT4pPT4gYm9vbGVhbikgOiBib29sZWFuIHtcclxuICAgICAgICBpZiAoIXByZWRpY2F0ZSkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5saXN0Lmxlbmd0aCA+IDA7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIFxyXG4gICAgICAgIGZvciAobGV0IGk9MDsgaTx0aGlzLmxpc3QubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgaWYgKCFwcmVkaWNhdGUodGhpcy5saXN0W2ldKSlcclxuICAgICAgICAgICAge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgfSAgICBcclxuXHJcbiAgICBzaW5nbGUocHJlZGljYXRlOiAoaXRlbTogS2V5VmFsdWVQYWlyPFRLZXksIFRWYWx1ZT4pPT4gYm9vbGVhbiA9IG51bGwpIDogS2V5VmFsdWVQYWlyPFRLZXksIFRWYWx1ZT4ge1xyXG4gICAgICAgIGlmICh0aGlzLmxpc3QubGVuZ3RoIDw9IDApIHtcclxuICAgICAgICAgICAgdGhyb3cgSVRFTV9OT1RfRk9VTkRfTVNHO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHByZWRpY2F0ZSkge1xyXG4gICAgICAgICAgICBsZXQgaXRlbSA9IHRoaXMuc2luZ2xlT3JEZWZhdWx0KHByZWRpY2F0ZSk7XHJcblxyXG4gICAgICAgICAgICBpZiAoIWl0ZW0pIHtcclxuICAgICAgICAgICAgICAgIHRocm93IElURU1fTk9UX0ZPVU5EX01TRztcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmV0dXJuIGl0ZW07XHJcbiAgICAgICAgfVxyXG4gICAgICAgIFxyXG4gICAgICAgIHJldHVybiB0aGlzLmxpc3RbMF07XHJcbiAgICB9XHJcblxyXG4gICAgZmlyc3QocHJlZGljYXRlOiAoaXRlbTogS2V5VmFsdWVQYWlyPFRLZXksIFRWYWx1ZT4pPT4gYm9vbGVhbiA9IG51bGwpIDogS2V5VmFsdWVQYWlyPFRLZXksIFRWYWx1ZT4ge1xyXG4gICAgICAgIGlmICh0aGlzLmxpc3QubGVuZ3RoIDw9IDApIHtcclxuICAgICAgICAgICAgdGhyb3cgSVRFTV9OT1RfRk9VTkRfTVNHO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHByZWRpY2F0ZSkge1xyXG4gICAgICAgICAgICBsZXQgaXRlbSA9IHRoaXMuZmlyc3RPckRlZmF1bHQocHJlZGljYXRlKTtcclxuXHJcbiAgICAgICAgICAgIGlmICghaXRlbSkge1xyXG4gICAgICAgICAgICAgICAgdGhyb3cgSVRFTV9OT1RfRk9VTkRfTVNHO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gaXRlbTtcclxuICAgICAgICB9XHJcbiAgICAgICAgXHJcbiAgICAgICAgcmV0dXJuIHRoaXMubGlzdFswXTtcclxuICAgIH1cclxuICAgIFxyXG4gICAgbGFzdChwcmVkaWNhdGU6IChpdGVtOiBLZXlWYWx1ZVBhaXI8VEtleSwgVFZhbHVlPik9PiBib29sZWFuKSA6IEtleVZhbHVlUGFpcjxUS2V5LCBUVmFsdWU+IHtcclxuICAgICAgICBpZiAodGhpcy5saXN0Lmxlbmd0aCA8PSAwKSB7XHJcbiAgICAgICAgICAgIHRocm93IElURU1fTk9UX0ZPVU5EX01TRztcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChwcmVkaWNhdGUpIHtcclxuICAgICAgICAgICAgbGV0IGl0ZW0gPSB0aGlzLmxhc3RPckRlZmF1bHQocHJlZGljYXRlKTtcclxuXHJcbiAgICAgICAgICAgIGlmICghaXRlbSkge1xyXG4gICAgICAgICAgICAgICAgdGhyb3cgSVRFTV9OT1RfRk9VTkRfTVNHO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gaXRlbTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzLmxpc3RbdGhpcy5saXN0Lmxlbmd0aCAtIDFdO1xyXG4gICAgfSAgICBcclxuXHJcbiAgICBzaW5nbGVPckRlZmF1bHQocHJlZGljYXRlOiAoaXRlbTogS2V5VmFsdWVQYWlyPFRLZXksIFRWYWx1ZT4pPT4gYm9vbGVhbikgOiBLZXlWYWx1ZVBhaXI8VEtleSwgVFZhbHVlPiB7XHJcbiAgICAgICAgbGV0IHRlbXAgPSBuZXcgQXJyYXk8S2V5VmFsdWVQYWlyPFRLZXksIFRWYWx1ZT4+KCk7XHJcblxyXG4gICAgICAgIHRoaXMubGlzdC5maWx0ZXIoZWxlbWVudCA9PiB7XHJcbiAgICAgICAgICAgIGlmIChwcmVkaWNhdGUoZWxlbWVudCkpXHJcbiAgICAgICAgICAgIHtcclxuICAgICAgICAgICAgICAgIHRlbXAucHVzaChlbGVtZW50KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICBpZiAodGVtcC5sZW5ndGggPiAxKSB7XHJcbiAgICAgICAgICAgIHRocm93IE1VTFRJUExFX0lOU1RBTkNFU19GT1VORF9NU0c7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAodGVtcC5sZW5ndGggPD0gMCkge1xyXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiB0ZW1wWzBdO1xyXG4gICAgfSAgICBcclxuXHJcbiAgICBmaXJzdE9yRGVmYXVsdChwcmVkaWNhdGU6IChpdGVtOiBLZXlWYWx1ZVBhaXI8VEtleSwgVFZhbHVlPik9PiBib29sZWFuKSA6IEtleVZhbHVlUGFpcjxUS2V5LCBUVmFsdWU+IHsgICAgICAgIFxyXG4gICAgICAgIGZvciAobGV0IGk9MDsgaTx0aGlzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGxldCBpdGVtID0gdGhpcy5saXN0W2ldO1xyXG4gICAgICAgICAgICBpZiAocHJlZGljYXRlKGl0ZW0pKVxyXG4gICAgICAgICAgICB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gaXRlbTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgbGFzdE9yRGVmYXVsdChwcmVkaWNhdGU6IChpdGVtOiBLZXlWYWx1ZVBhaXI8VEtleSwgVFZhbHVlPik9PiBib29sZWFuKSA6IEtleVZhbHVlUGFpcjxUS2V5LCBUVmFsdWU+IHtcclxuICAgICAgICBmb3IgKGxldCBpPXRoaXMubGVuZ3RoOyBpPj0wOyBpLS0pIHtcclxuICAgICAgICAgICAgbGV0IGl0ZW0gPSB0aGlzLmxpc3RbaSAtIDFdO1xyXG4gICAgICAgICAgICBpZiAocHJlZGljYXRlKGl0ZW0pKVxyXG4gICAgICAgICAgICB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gaXRlbTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICB9ICAgIFxyXG5cclxuICAgIHdoZXJlKHByZWRpY2F0ZTogKGl0ZW06IEtleVZhbHVlUGFpcjxUS2V5LCBUVmFsdWU+KT0+IGJvb2xlYW4pIDogSURpY3Rpb25hcnk8VEtleSwgVFZhbHVlPiB7XHJcbiAgICAgICAgbGV0IHRlbXAgPSBuZXcgRGljdGlvbmFyeTxUS2V5LCBUVmFsdWU+KCk7XHJcblxyXG4gICAgICAgIHRoaXMubGlzdC5maWx0ZXIoZWxlbWVudCA9PiB7XHJcbiAgICAgICAgICAgIGlmIChwcmVkaWNhdGUoZWxlbWVudCkpXHJcbiAgICAgICAgICAgIHtcclxuICAgICAgICAgICAgICAgIHRlbXAuYWRkKGVsZW1lbnQua2V5LCBlbGVtZW50LnZhbHVlKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICByZXR1cm4gdGVtcDtcclxuICAgIH1cclxuXHJcbiAgICBzZWxlY3Q8VFJlc3VsdD4ocHJlZGljYXRlOiAoaXRlbTogS2V5VmFsdWVQYWlyPFRLZXksIFRWYWx1ZT4pPT4gVFJlc3VsdCkgOiBJRW51bWVyYWJsZTxUUmVzdWx0PiB7XHJcbiAgICAgICAgbGV0IHRlbXAgPSBuZXcgTGlzdDxUUmVzdWx0PigpO1xyXG5cclxuICAgICAgICB0aGlzLmZvckVhY2goeCA9PiB0ZW1wLmFkZChwcmVkaWNhdGUoeCkpKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIHRlbXA7XHJcbiAgICB9XHJcblxyXG4gICAgZm9yRWFjaChwcmVkaWNhdGU6IChpdGVtOiBLZXlWYWx1ZVBhaXI8VEtleSwgVFZhbHVlPik9PiB2b2lkKSA6IHZvaWQge1xyXG4gICAgICAgIHRoaXMubGlzdC5mb3JFYWNoKHggPT4gcHJlZGljYXRlKHgpKTtcclxuICAgIH1cclxuXHJcbiAgICB0b0FycmF5KCkgOiBBcnJheTxLZXlWYWx1ZVBhaXI8VEtleSwgVFZhbHVlPj4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmxpc3Quc2xpY2UoKTtcclxuICAgIH1cclxuXHJcbiAgICBqb2luPFRPdXRlciwgVE1hdGNoLCBUUmVzdWx0PihvdXRlcjogSUVudW1lcmFibGU8VE91dGVyPiwgY29uZGl0aW9uSW5uZXI6IChpdGVtOiBLZXlWYWx1ZVBhaXI8VEtleSwgVFZhbHVlPik9PiBUTWF0Y2gsIFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25kaXRpb25PdXRlcjogKGl0ZW06IFRPdXRlcik9PiBUTWF0Y2gsIHNlbGVjdDogKHg6IEtleVZhbHVlUGFpcjxUS2V5LCBUVmFsdWU+LCB5OlRPdXRlcik9PiBUUmVzdWx0LCBsZWZ0Sm9pbjogYm9vbGVhbiA9IGZhbHNlKSA6IElFbnVtZXJhYmxlPFRSZXN1bHQ+IHtcclxuICAgICAgICBsZXQgcmVzdWx0TGlzdCA9IG5ldyBMaXN0PFRSZXN1bHQ+KCk7XHJcblxyXG4gICAgICAgIHRoaXMubGlzdC5mb3JFYWNoKHggPT4ge1xyXG4gICAgICAgICAgICBsZXQgb3V0ZXJFbnRyaWVzID0gb3V0ZXIudG9BcnJheSgpLmZpbHRlcih5ID0+IGNvbmRpdGlvbklubmVyKHgpID09PSBjb25kaXRpb25PdXRlcih5KSk7XHJcblxyXG4gICAgICAgICAgICBpZiAobGVmdEpvaW4gJiYgb3V0ZXJFbnRyaWVzICYmIG91dGVyRW50cmllcy5sZW5ndGggPD0gMCkge1xyXG4gICAgICAgICAgICAgICAgcmVzdWx0TGlzdC5hZGQoc2VsZWN0KHgsIG51bGwpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIG91dGVyRW50cmllcy5mb3JFYWNoKHogPT4gcmVzdWx0TGlzdC5hZGQoc2VsZWN0KHgsIHopKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KVxyXG5cclxuICAgICAgICByZXR1cm4gcmVzdWx0TGlzdDtcclxuICAgIH1cclxuXHJcbiAgICBncm91cEJ5KHByZWRpY2F0ZTogKGl0ZW06IEtleVZhbHVlUGFpcjxUS2V5LCBUVmFsdWU+KSA9PiBBcnJheTxhbnk+KSA6IElFbnVtZXJhYmxlPEdyb3VwPEtleVZhbHVlUGFpcjxUS2V5LCBUVmFsdWU+Pj4ge1xyXG4gICAgICAgIGxldCBncm91cHMgPSB7fTtcclxuICAgICAgICB0aGlzLmxpc3QuZm9yRWFjaChmdW5jdGlvbiAobykge1xyXG4gICAgICAgICAgdmFyIGdyb3VwID0gSlNPTi5zdHJpbmdpZnkocHJlZGljYXRlKG8pKTtcclxuICAgICAgICAgIGdyb3Vwc1tncm91cF0gPSBncm91cHNbZ3JvdXBdIHx8IFtdO1xyXG4gICAgICAgICAgZ3JvdXBzW2dyb3VwXS5wdXNoKG8pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIGxldCBnID0gT2JqZWN0LmtleXMoZ3JvdXBzKS5tYXAoZnVuY3Rpb24gKGdyb3VwKSB7ICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICBsZXQgYSA9IGdyb3VwLnN1YnN0cigxLCBncm91cC5sZW5ndGggLSAyKTtcclxuICAgICAgICAgICAgXHJcbiAgICAgICAgICAgIGxldCBncnA9IG5ldyBHcm91cDxLZXlWYWx1ZVBhaXI8VEtleSwgVFZhbHVlPj4obmV3IExpc3QoYS5zcGxpdCgnLCcpKS5zZWxlY3QoeCA9PiB4LnJlcGxhY2UoL14oXCIpPyguKj8pKFwiKT8kL2lnLCBcIiQyXCIpKS50b0FycmF5KCksIFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncm91cHNbZ3JvdXBdKTsgICAgICAgICAgICBcclxuXHJcbiAgICAgICAgICAgIHJldHVybiBncnA7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIHJldHVybiBuZXcgTGlzdDxHcm91cDxLZXlWYWx1ZVBhaXI8VEtleSwgVFZhbHVlPj4+KGcpOyAgICAgICAgXHJcbiAgICB9XHJcblxyXG4gICAgc2VsZWN0TWFueTxUUmVzdWx0PihwcmVkaWNhdGU6IChpdGVtOiBLZXlWYWx1ZVBhaXI8VEtleSwgVFZhbHVlPik9PiBBcnJheTxUUmVzdWx0PikgOiBJRW51bWVyYWJsZTxUUmVzdWx0PiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMubGlzdC5yZWR1Y2UoKG91dCwgaW54KSA9PiB7XHJcbiAgICAgICAgICAgIHZhciBpdGVtcyA9IHByZWRpY2F0ZShpbngpO1xyXG4gICAgICAgICAgICBvdXQuYWRkUmFuZ2UoaXRlbXMpO1xyXG4gICAgICAgICAgICByZXR1cm4gb3V0O1xyXG4gICAgICAgICAgfSwgbmV3IExpc3Q8VFJlc3VsdD4obmV3IEFycmF5PFRSZXN1bHQ+KCkpKTtcclxuICAgIH1cclxuXHJcbiAgICBvcmRlckJ5KGNvbXBhcmVyOiBJQ29tcGFyZXI8S2V5VmFsdWVQYWlyPFRLZXksIFRWYWx1ZT4+KSA6IElFbnVtZXJhYmxlPEtleVZhbHVlUGFpcjxUS2V5LCBUVmFsdWU+PiB7XHJcbiAgICAgICAgbGV0IHRlbXAgPSB0aGlzLmxpc3Quc29ydCgoeCx5KSA9PiBjb21wYXJlci5jb21wYXJlKHgsIHkpKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIG5ldyBMaXN0PEtleVZhbHVlUGFpcjxUS2V5LCBUVmFsdWU+Pih0ZW1wKTtcclxuICAgIH1cclxuXHJcbiAgICBkaXN0aW5jdChjb21wYXJlcjogSUVxdWFsaXR5Q29tcGFyZXI8S2V5VmFsdWVQYWlyPFRLZXksIFRWYWx1ZT4+KSA6IElFbnVtZXJhYmxlPEtleVZhbHVlUGFpcjxUS2V5LCBUVmFsdWU+PiB7XHJcbiAgICAgICAgbGV0IHVuaXF1ZXMgPSBuZXcgTGlzdDxLZXlWYWx1ZVBhaXI8VEtleSwgVFZhbHVlPj4oKTtcclxuICAgICAgICB0aGlzLmZvckVhY2goeCA9PiB7XHJcbiAgICAgICAgICAgIGlmICh1bmlxdWVzLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgICAgIGlmICghdW5pcXVlcy5hbnkoeSA9PiBjb21wYXJlci5lcXVhbHMoeCwgeSkpKVxyXG4gICAgICAgICAgICAgICAge1xyXG4gICAgICAgICAgICAgICAgICAgIHVuaXF1ZXMuYWRkKHgpO1xyXG4gICAgICAgICAgICAgICAgfSAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgdW5pcXVlcy5hZGQoeCk7XHJcbiAgICAgICAgICAgIH0gICAgICAgICAgICBcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgcmV0dXJuIHVuaXF1ZXM7XHJcbiAgICB9XHJcblxyXG4gICAgdW5pb24obGlzdDogSUVudW1lcmFibGU8S2V5VmFsdWVQYWlyPFRLZXksIFRWYWx1ZT4+KSA6IElEaWN0aW9uYXJ5PFRLZXksIFRWYWx1ZT4ge1xyXG4gICAgICAgICB0aGlzLmFkZFJhbmdlKGxpc3QudG9BcnJheSgpKTtcclxuXHJcbiAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfSAgICBcclxuXHJcbiAgICByZXZlcnNlKCk6IElFbnVtZXJhYmxlPEtleVZhbHVlUGFpcjxUS2V5LCBUVmFsdWU+PiB7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBMaXN0PEtleVZhbHVlUGFpcjxUS2V5LCBUVmFsdWU+Pih0aGlzLmxpc3Quc2xpY2UoKS5yZXZlcnNlKCkpO1xyXG4gICAgfVxyXG5cclxuICAgIHNraXAobm86IG51bWJlcikgOiBJRGljdGlvbmFyeTxUS2V5LCBUVmFsdWU+IHtcclxuICAgICAgICBpZiAobm8gPiAwKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBuZXcgRGljdGlvbmFyeSh0aGlzLmxpc3Quc2xpY2Uobm8sIHRoaXMubGlzdC5sZW5ndGggLSAxKSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIFxyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfVxyXG5cclxuICAgIHRha2Uobm86IG51bWJlcikgOiBJRGljdGlvbmFyeTxUS2V5LCBUVmFsdWU+IHtcclxuICAgICAgICBpZiAobm8gPiAwKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBuZXcgRGljdGlvbmFyeSh0aGlzLmxpc3Quc2xpY2UoMCwgbm8pKTtcclxuICAgICAgICB9ICAgICAgICBcclxuXHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9ICAgIFxyXG5cclxuICAgIHN1bShwcmVkaWNhdGU6IChpdGVtOiBLZXlWYWx1ZVBhaXI8VEtleSwgVFZhbHVlPik9PiBudW1iZXIpIDogbnVtYmVyIHtcclxuICAgICAgICBsZXQgc3VtOiBudW1iZXIgPSAwO1xyXG4gICAgICAgIHRoaXMubGlzdC5mb3JFYWNoKHggPT4gc3VtID0gc3VtICsgcHJlZGljYXRlKHgpKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIHN1bTtcclxuICAgIH1cclxuXHJcbiAgICBhdmcocHJlZGljYXRlOiAoaXRlbTogS2V5VmFsdWVQYWlyPFRLZXksIFRWYWx1ZT4pPT4gbnVtYmVyKSA6IG51bWJlciB7ICAgICAgICBcclxuICAgICAgICByZXR1cm4gdGhpcy5zdW0ocHJlZGljYXRlKSAvIHRoaXMubGVuZ3RoO1xyXG4gICAgfVxyXG5cclxuICAgIG1pbihwcmVkaWNhdGU6IChpdGVtOiBLZXlWYWx1ZVBhaXI8VEtleSwgVFZhbHVlPik9PiBudW1iZXIpIDogbnVtYmVyIHtcclxuICAgICAgICBsZXQgbWluOiBudW1iZXIgPSAwO1xyXG4gICAgICAgIGxldCBpID0gMDtcclxuICAgICAgICB0aGlzLmxpc3QuZm9yRWFjaCh4ID0+IFxyXG4gICAgICAgIHtcclxuICAgICAgICAgICAgaWYgKGkgPT0gMCkge1xyXG4gICAgICAgICAgICAgICAgbWluID0gcHJlZGljYXRlKHgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgbGV0IHZhbCA9IHByZWRpY2F0ZSh4KTtcclxuICAgICAgICAgICAgICAgIGlmICh2YWwgPCBtaW4pIHtcclxuICAgICAgICAgICAgICAgICAgICBtaW4gPSB2YWw7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0gICAgICAgICAgICBcclxuICAgICAgICAgICAgaSsrO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICByZXR1cm4gbWluO1xyXG4gICAgfVxyXG4gICAgXHJcbiAgICBtYXgocHJlZGljYXRlOiAoaXRlbTogS2V5VmFsdWVQYWlyPFRLZXksIFRWYWx1ZT4pPT4gbnVtYmVyKSA6IG51bWJlciB7XHJcbiAgICAgICAgbGV0IG1heDogbnVtYmVyID0gMDtcclxuICAgICAgICBsZXQgaSA9IDA7XHJcbiAgICAgICAgdGhpcy5saXN0LmZvckVhY2goeCA9PiBcclxuICAgICAgICB7XHJcbiAgICAgICAgICAgIGlmIChpID09IDApIHtcclxuICAgICAgICAgICAgICAgIG1heCA9IHByZWRpY2F0ZSh4KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGxldCB2YWwgPSBwcmV