ts-generic-collections-linq
Version:
TypeScript library provides strongly-typed, queryable collections.
580 lines • 39 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
import { Group, ITEM_NOT_FOUND_MSG, MULTIPLE_INSTANCES_FOUND_MSG } from './common';
/**
* @record
* @template T
*/
export function IList() { }
if (false) {
/**
* @param {?} item
* @return {?}
*/
IList.prototype.add = function (item) { };
/**
* @param {?} items
* @return {?}
*/
IList.prototype.addRange = function (items) { };
/**
* @param {?} predicate
* @return {?}
*/
IList.prototype.remove = function (predicate) { };
/**
* @param {?} index
* @return {?}
*/
IList.prototype.removeAt = function (index) { };
/**
* @return {?}
*/
IList.prototype.clear = function () { };
}
/**
* @template T
*/
export class List {
/**
* @param {?=} array
*/
constructor(array = null) {
this.list = new Array();
if (array)
this.list = array;
}
/* IList */
/**
* @param {?} item
* @return {?}
*/
add(item) {
this.list.push(item);
}
/**
* @param {?} items
* @return {?}
*/
addRange(items) {
items.forEach((/**
* @param {?} x
* @return {?}
*/
x => this.add(x)));
}
/**
* @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 {?} index
* @return {?}
*/
removeAt(index) {
this.list.splice(index, 1);
}
/**
* @return {?}
*/
clear() {
this.list = new Array();
}
/* 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 = null) {
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 List();
this.list.filter((/**
* @param {?} element
* @return {?}
*/
element => {
if (predicate(element)) {
temp.add(element);
}
}));
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 {?} list
* @return {?}
*/
union(list) {
this.addRange(list.toArray());
return this;
}
/**
* @return {?}
*/
reverse() {
return new List(this.list.slice().reverse());
}
/**
* @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 {?} no
* @return {?}
*/
skip(no) {
if (no > 0) {
return new List(this.list.slice(no, this.list.length - 1));
}
return this;
}
/**
* @param {?} no
* @return {?}
*/
take(no) {
if (no > 0) {
return new List(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
*/
List.prototype.list;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGlzdC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL3RzLWdlbmVyaWMtY29sbGVjdGlvbnMtbGlucS8iLCJzb3VyY2VzIjpbImxpYi9saXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7QUFDQSxPQUFPLEVBQUUsS0FBSyxFQUFjLGtCQUFrQixFQUFFLDRCQUE0QixFQUFFLE1BQU0sVUFBVSxDQUFDOzs7OztBQUUvRiwyQkFNQzs7Ozs7O0lBTEcsMENBQW9COzs7OztJQUNwQixnREFBNEI7Ozs7O0lBQzVCLGtEQUE4Qzs7Ozs7SUFDOUMsZ0RBQStCOzs7O0lBQy9CLHdDQUFlOzs7OztBQUduQixNQUFNLE9BQU8sSUFBSTs7OztJQUliLFlBQVksUUFBa0IsSUFBSTtRQUYxQixTQUFJLEdBQWEsSUFBSSxLQUFLLEVBQUssQ0FBQztRQUdwQyxJQUFJLEtBQUs7WUFDTCxJQUFJLENBQUMsSUFBSSxHQUFHLEtBQUssQ0FBQztJQUMxQixDQUFDOzs7Ozs7SUFJRCxHQUFHLENBQUMsSUFBTztRQUNQLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ3pCLENBQUM7Ozs7O0lBRUQsUUFBUSxDQUFDLEtBQVU7UUFDZixLQUFLLENBQUMsT0FBTzs7OztRQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBQyxDQUFDO0lBQ3BDLENBQUM7Ozs7O0lBRUQsTUFBTSxDQUFDLFNBQThCOztZQUM3QixJQUFJLEdBQUcsSUFBSSxLQUFLLEVBQUs7UUFFekIsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPOzs7O1FBQUMsT0FBTyxDQUFDLEVBQUU7WUFDeEIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsRUFDdkI7Z0JBQ0ksSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQzthQUN0QjtRQUNMLENBQUMsRUFBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJ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SUFBSSxDQUFDLE9BQU87Ozs7UUFBQyxDQUFDLENBQUMsRUFBRTtZQUVsQixJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUU7Z0JBQ1IsR0FBRyxHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQzthQUN0QjtpQkFDSTs7b0JBQ0csR0FBRyxHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUM7Z0JBQ3RCLElBQUksR0FBRyxHQUFHLEdBQUcsRUFBRTtvQkFDWCxHQUFHLEdBQUcsR0FBRyxDQUFDO2lCQUNiO2FBQ0o7WUFDRCxDQUFDLEVBQUUsQ0FBQztRQUNSLENBQUMsRUFBQyxDQUFDO1FBRUgsT0FBTyxHQUFHLENBQUM7SUFDZixDQUFDOzs7OztJQUVELEtBQUssQ0FBQyxZQUFpQyxJQUFJO1FBQ3ZDLElBQUksQ0FBQyxTQUFTLEVBQUU7WUFDWixPQUFPLElBQUksQ0FBQyxNQUFNLENBQUM7U0FDdEI7O1lBRUcsS0FBSyxHQUFXLENBQUM7UUFDckIsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPOzs7O1FBQUMsQ0FBQyxDQUFDLEVBQUU7WUFDbEIsSUFBRyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUU7Z0JBQ2IsS0FBSyxFQUFFLENBQUM7YUFDWDtRQUNMLENBQUMsRUFBQyxDQUFDO1FBRUgsT0FBTyxLQUFLLENBQUM7SUFDakIsQ0FBQztDQUVKOzs7Ozs7SUFyWEcsb0JBQXdDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSUVudW1lcmFibGUsIElDb21wYXJlciwgSUVxdWFsaXR5Q29tcGFyZXIgfSBmcm9tICcuL2ludGVyZmFjZXMnO1xyXG5pbXBvcnQgeyBHcm91cCwgb2JqQ29tcGFyZSwgSVRFTV9OT1RfRk9VTkRfTVNHLCBNVUxUSVBMRV9JTlNUQU5DRVNfRk9VTkRfTVNHIH0gZnJvbSAnLi9jb21tb24nO1xyXG5cclxuZXhwb3J0IGludGVyZmFjZSBJTGlzdDxUPiBleHRlbmRzIElFbnVtZXJhYmxlPFQ+IHtcclxuICAgIGFkZChpdGVtOiBUKSA6IHZvaWQ7XHJcbiAgICBhZGRSYW5nZShpdGVtczogVFtdKSA6IHZvaWQ7XHJcbiAgICByZW1vdmUocHJlZGljYXRlOiAoaXRlbTpUKSA9PiBib29sZWFuKSA6IHZvaWQ7XHJcbiAgICByZW1vdmVBdChpbmRleDogbnVtYmVyKSA6IHZvaWQ7XHJcbiAgICBjbGVhcigpIDogdm9pZDsgICAgXHJcbn1cclxuXHJcbmV4cG9ydCBjbGFzcyBMaXN0PFQ+IGltcGxlbWVudHMgSUxpc3Q8VD4ge1xyXG5cclxuICAgIHByaXZhdGUgbGlzdDogQXJyYXk8VD4gPSBuZXcgQXJyYXk8VD4oKTsgICAgXHJcblxyXG4gICAgY29uc3RydWN0b3IoYXJyYXk6IEFycmF5PFQ+ID0gbnVsbCkge1xyXG4gICAgICAgIGlmIChhcnJheSlcclxuICAgICAgICAgICAgdGhpcy5saXN0ID0gYXJyYXk7XHJcbiAgICB9XHJcblxyXG4gICAgLyogSUxpc3QgKi9cclxuXHJcbiAgICBhZGQoaXRlbTogVCkgOiB2b2lkIHtcclxuICAgICAgICB0aGlzLmxpc3QucHVzaChpdGVtKTtcclxuICAgIH1cclxuXHJcbiAgICBhZGRSYW5nZShpdGVtczogVFtdKSA6IHZvaWQge1xyXG4gICAgICAgIGl0ZW1zLmZvckVhY2goeCA9PiB0aGlzLmFkZCh4KSk7XHJcbiAgICB9XHJcblxyXG4gICAgcmVtb3ZlKHByZWRpY2F0ZTogKGl0ZW06VCkgPT4gYm9vbGVhbikgOiB2b2lkIHtcclxuICAgICAgICBsZXQgdGVtcCA9IG5ldyBBcnJheTxUPigpO1xyXG5cclxuICAgICAgICB0aGlzLmxpc3QuZm9yRWFjaChlbGVtZW50ID0+IHtcclxuICAgICAgICAgICAgaWYgKCFwcmVkaWNhdGUoZWxlbWVudCkpXHJcbiAgICAgICAgICAgIHtcclxuICAgICAgICAgICAgICAgIHRlbXAucHVzaChlbGVtZW50KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICB0aGlzLmxpc3QgPSB0ZW1wO1xyXG4gICAgfVxyXG5cclxuICAgIHJlbW92ZUF0KGluZGV4OiBudW1iZXIpIDogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5saXN0LnNwbGljZShpbmRleCwgMSk7XHJcbiAgICB9XHJcblxyXG4gICAgY2xlYXIoKSA6IHZvaWQge1xyXG4gICAgICAgIHRoaXMubGlzdCA9IG5ldyBBcnJheTxUPigpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qIElFbnVtZXJhYmxlICovXHJcblxyXG4gICAgYXNFbnVtZXJhYmxlKCkgOiBJRW51bWVyYWJsZTxUPiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IGxlbmd0aCgpOiBudW1iZXIge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmxpc3QubGVuZ3RoO1xyXG4gICAgfVxyXG5cclxuICAgIGVsZW1lbnRBdChpbmRleDogbnVtYmVyKSA6IFQge1xyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmxpc3RbaW5kZXhdO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgYW55KHByZWRpY2F0ZT86IChpdGVtOiBUKT0+IGJvb2xlYW4pIDogYm9vbGVhbiB7XHJcbiAgICAgICAgaWYgKCFwcmVkaWNhdGUpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMubGlzdC5sZW5ndGggPiAwO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZm9yIChsZXQgaT0wOyBpPHRoaXMubGlzdC5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBpZiAocHJlZGljYXRlKHRoaXMubGlzdFtpXSkpXHJcbiAgICAgICAgICAgIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuXHJcbiAgICBhbGwocHJlZGljYXRlPzogKGl0ZW06IFQpPT4gYm9vbGVhbikgOiBib29sZWFuIHtcclxuICAgICAgICBpZiAoIXByZWRpY2F0ZSkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5saXN0Lmxlbmd0aCA+IDA7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIFxyXG4gICAgICAgIGZvciAobGV0IGk9MDsgaTx0aGlzLmxpc3QubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgaWYgKCFwcmVkaWNhdGUodGhpcy5saXN0W2ldKSlcclxuICAgICAgICAgICAge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgfVxyXG5cclxuICAgIHNpbmdsZShwcmVkaWNhdGU6IChpdGVtOiBUKT0+IGJvb2xlYW4gPSBudWxsKSA6IFQge1xyXG4gICAgICAgIGlmICh0aGlzLmxpc3QubGVuZ3RoIDw9IDApIHtcclxuICAgICAgICAgICAgdGhyb3cgSVRFTV9OT1RfRk9VTkRfTVNHO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHByZWRpY2F0ZSkge1xyXG4gICAgICAgICAgICBsZXQgaXRlbSA9IHRoaXMuc2luZ2xlT3JEZWZhdWx0KHByZWRpY2F0ZSk7XHJcblxyXG4gICAgICAgICAgICBpZiAoIWl0ZW0pIHtcclxuICAgICAgICAgICAgICAgIHRocm93IElURU1fTk9UX0ZPVU5EX01TRztcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmV0dXJuIGl0ZW07XHJcbiAgICAgICAgfVxyXG4gICAgICAgIFxyXG4gICAgICAgIHJldHVybiB0aGlzLmxpc3RbMF07XHJcbiAgICB9XHJcblxyXG4gICAgZmlyc3QocHJlZGljYXRlOiAoaXRlbTogVCk9PiBib29sZWFuID0gbnVsbCkgOiBUIHtcclxuICAgICAgICBpZiAodGhpcy5saXN0Lmxlbmd0aCA8PSAwKSB7XHJcbiAgICAgICAgICAgIHRocm93IElURU1fTk9UX0ZPVU5EX01TRztcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChwcmVkaWNhdGUpIHtcclxuICAgICAgICAgICAgbGV0IGl0ZW0gPSB0aGlzLmZpcnN0T3JEZWZhdWx0KHByZWRpY2F0ZSk7XHJcblxyXG4gICAgICAgICAgICBpZiAoIWl0ZW0pIHtcclxuICAgICAgICAgICAgICAgIHRocm93IElURU1fTk9UX0ZPVU5EX01TRztcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmV0dXJuIGl0ZW07XHJcbiAgICAgICAgfVxyXG4gICAgICAgIFxyXG4gICAgICAgIHJldHVybiB0aGlzLmxpc3RbMF07XHJcbiAgICB9XHJcbiAgICBcclxuICAgIGxhc3QocHJlZGljYXRlOiAoaXRlbTogVCk9PiBib29sZWFuID0gbnVsbCkgOiBUIHtcclxuICAgICAgICBpZiAodGhpcy5saXN0Lmxlbmd0aCA8PSAwKSB7XHJcbiAgICAgICAgICAgIHRocm93IElURU1fTk9UX0ZPVU5EX01TRztcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChwcmVkaWNhdGUpIHtcclxuICAgICAgICAgICAgbGV0IGl0ZW0gPSB0aGlzLmxhc3RPckRlZmF1bHQocHJlZGljYXRlKTtcclxuXHJcbiAgICAgICAgICAgIGlmICghaXRlbSkge1xyXG4gICAgICAgICAgICAgICAgdGhyb3cgSVRFTV9OT1RfRk9VTkRfTVNHO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gaXRlbTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzLmxpc3RbdGhpcy5saXN0Lmxlbmd0aCAtIDFdO1xyXG4gICAgfSAgICBcclxuXHJcbiAgICBzaW5nbGVPckRlZmF1bHQocHJlZGljYXRlOiAoaXRlbTogVCk9PiBib29sZWFuKSA6IFQge1xyXG4gICAgICAgIGxldCB0ZW1wID0gbmV3IEFycmF5PFQ+KCk7XHJcblxyXG4gICAgICAgIHRoaXMubGlzdC5maWx0ZXIoZWxlbWVudCA9PiB7XHJcbiAgICAgICAgICAgIGlmIChwcmVkaWNhdGUoZWxlbWVudCkpXHJcbiAgICAgICAgICAgIHtcclxuICAgICAgICAgICAgICAgIHRlbXAucHVzaChlbGVtZW50KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICBpZiAodGVtcC5sZW5ndGggPiAxKSB7XHJcbiAgICAgICAgICAgIHRocm93IE1VTFRJUExFX0lOU1RBTkNFU19GT1VORF9NU0c7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAodGVtcC5sZW5ndGggPD0gMCkge1xyXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiB0ZW1wWzBdO1xyXG4gICAgfSAgICBcclxuXHJcbiAgICBmaXJzdE9yRGVmYXVsdChwcmVkaWNhdGU6IChpdGVtOiBUKT0+IGJvb2xlYW4pIDogVCB7XHJcbiAgICAgICAgZm9yIChsZXQgaT0wOyBpPHRoaXMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgbGV0IGl0ZW0gPSB0aGlzLmxpc3RbaV07XHJcbiAgICAgICAgICAgIGlmIChwcmVkaWNhdGUoaXRlbSkpXHJcbiAgICAgICAgICAgIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBpdGVtO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgIH1cclxuXHJcbiAgICBsYXN0T3JEZWZhdWx0KHByZWRpY2F0ZTogKGl0ZW06IFQpPT4gYm9vbGVhbikgOiBUIHtcclxuICAgICAgICBmb3IgKGxldCBpPXRoaXMubGVuZ3RoOyBpPj0wOyBpLS0pIHtcclxuICAgICAgICAgICAgbGV0IGl0ZW0gPSB0aGlzLmxpc3RbaSAtIDFdO1xyXG4gICAgICAgICAgICBpZiAocHJlZGljYXRlKGl0ZW0pKVxyXG4gICAgICAgICAgICB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gaXRlbTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICB9ICAgIFxyXG5cclxuICAgIHdoZXJlKHByZWRpY2F0ZTogKGl0ZW06IFQpPT4gYm9vbGVhbikgOiBJRW51bWVyYWJsZTxUPiB7XHJcbiAgICAgICAgbGV0IHRlbXAgPSBuZXcgTGlzdDxUPigpO1xyXG5cclxuICAgICAgICB0aGlzLmxpc3QuZmlsdGVyKGVsZW1lbnQgPT4ge1xyXG4gICAgICAgICAgICBpZiAocHJlZGljYXRlKGVsZW1lbnQpKVxyXG4gICAgICAgICAgICB7XHJcbiAgICAgICAgICAgICAgICB0ZW1wLmFkZChlbGVtZW50KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICByZXR1cm4gdGVtcDtcclxuICAgIH1cclxuXHJcbiAgICBzZWxlY3Q8VFJlc3VsdD4ocHJlZGljYXRlOiAoaXRlbTogVCk9PiBUUmVzdWx0KSA6IElFbnVtZXJhYmxlPFRSZXN1bHQ+IHtcclxuICAgICAgICBsZXQgdGVtcCA9IG5ldyBMaXN0PFRSZXN1bHQ+KCk7XHJcblxyXG4gICAgICAgIHRoaXMuZm9yRWFjaCh4ID0+IHRlbXAuYWRkKHByZWRpY2F0ZSh4KSkpO1xyXG5cclxuICAgICAgICByZXR1cm4gdGVtcDtcclxuICAgIH1cclxuXHJcbiAgICBmb3JFYWNoKHByZWRpY2F0ZTogKGl0ZW06IFQpPT4gdm9pZCkgOiB2b2lkIHtcclxuICAgICAgICB0aGlzLmxpc3QuZm9yRWFjaCh4ID0+IHByZWRpY2F0ZSh4KSk7XHJcbiAgICB9XHJcblxyXG4gICAgdG9BcnJheSgpIDogQXJyYXk8VD4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmxpc3Quc2xpY2UoKTtcclxuICAgIH1cclxuXHJcbiAgICBqb2luPFRPdXRlciwgVE1hdGNoLCBUUmVzdWx0PihvdXRlcjogSUVudW1lcmFibGU8VE91dGVyPiwgY29uZGl0aW9uSW5uZXI6IChpdGVtOiBUKT0+IFRNYXRjaCwgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbmRpdGlvbk91dGVyOiAoaXRlbTogVE91dGVyKT0+IFRNYXRjaCwgc2VsZWN0OiAoeDogVCwgeTpUT3V0ZXIpPT4gVFJlc3VsdCwgbGVmdEpvaW46IGJvb2xlYW4gPSBmYWxzZSkgOiBJRW51bWVyYWJsZTxUUmVzdWx0PiB7XHJcbiAgICAgICAgbGV0IHJlc3VsdExpc3QgPSBuZXcgTGlzdDxUUmVzdWx0PigpO1xyXG5cclxuICAgICAgICB0aGlzLmxpc3QuZm9yRWFjaCh4ID0+IHtcclxuICAgICAgICAgICAgbGV0IG91dGVyRW50cmllcyA9IG91dGVyLnRvQXJyYXkoKS5maWx0ZXIoeSA9PiBjb25kaXRpb25Jbm5lcih4KSA9PT0gY29uZGl0aW9uT3V0ZXIoeSkpO1xyXG5cclxuICAgICAgICAgICAgaWYgKGxlZnRKb2luICYmIG91dGVyRW50cmllcyAmJiBvdXRlckVudHJpZXMubGVuZ3RoIDw9IDApIHtcclxuICAgICAgICAgICAgICAgIHJlc3VsdExpc3QuYWRkKHNlbGVjdCh4LCBudWxsKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBvdXRlckVudHJpZXMuZm9yRWFjaCh6ID0+IHJlc3VsdExpc3QuYWRkKHNlbGVjdCh4LCB6KSkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSlcclxuXHJcbiAgICAgICAgcmV0dXJuIHJlc3VsdExpc3Q7XHJcbiAgICB9XHJcblxyXG4gICAgZ3JvdXBCeShwcmVkaWNhdGU6IChpdGVtOiBUKSA9PiBBcnJheTxhbnk+KSA6IElFbnVtZXJhYmxlPEdyb3VwPFQ+PiB7XHJcbiAgICAgICAgbGV0IGdyb3VwcyA9IHt9O1xyXG4gICAgICAgIHRoaXMubGlzdC5mb3JFYWNoKGZ1bmN0aW9uIChvKSB7XHJcbiAgICAgICAgICB2YXIgZ3JvdXAgPSBKU09OLnN0cmluZ2lmeShwcmVkaWNhdGUobykpO1xyXG4gICAgICAgICAgZ3JvdXBzW2dyb3VwXSA9IGdyb3Vwc1tncm91cF0gfHwgW107XHJcbiAgICAgICAgICBncm91cHNbZ3JvdXBdLnB1c2gobyk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgbGV0IGcgPSBPYmplY3Qua2V5cyhncm91cHMpLm1hcChmdW5jdGlvbiAoZ3JvdXApIHsgICAgICAgICAgICAgXHJcbiAgICAgICAgICAgIGxldCBhID0gZ3JvdXAuc3Vic3RyKDEsIGdyb3VwLmxlbmd0aCAtIDIpOyAgICAgICAgICAgIFxyXG5cclxuICAgICAgICAgICAgbGV0IGdycD0gbmV3IEdyb3VwPFQ+KG5ldyBMaXN0KGEuc3BsaXQoJywnKSkuc2VsZWN0KHggPT4geC5yZXBsYWNlKC9eKFwiKT8oLio/KShcIik/JC9pZywgXCIkMlwiKSkudG9BcnJheSgpLCBcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JvdXBzW2dyb3VwXSk7XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gZ3JwO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICByZXR1cm4gbmV3IExpc3Q8R3JvdXA8VD4+KGcpOyAgICAgICAgXHJcbiAgICB9XHJcblxyXG4gICAgc2VsZWN0TWFueTxUUmVzdWx0PihwcmVkaWNhdGU6IChpdGVtOiBUKT0+IEFycmF5PFRSZXN1bHQ+KSA6IElFbnVtZXJhYmxlPFRSZXN1bHQ+IHtcclxuICAgICAgICByZXR1cm4gdGhpcy5saXN0LnJlZHVjZSgob3V0LCBpbngpID0+IHtcclxuICAgICAgICAgICAgdmFyIGl0ZW1zID0gcHJlZGljYXRlKGlueCk7XHJcbiAgICAgICAgICAgIG91dC5hZGRSYW5nZShpdGVtcyk7XHJcbiAgICAgICAgICAgIHJldHVybiBvdXQ7XHJcbiAgICAgICAgICB9LCBuZXcgTGlzdDxUUmVzdWx0PihuZXcgQXJyYXk8VFJlc3VsdD4oKSkpO1xyXG4gICAgfVxyXG5cclxuICAgIG9yZGVyQnkoY29tcGFyZXI6IElDb21wYXJlcjxUPikgOiBJRW51bWVyYWJsZTxUPiB7XHJcbiAgICAgICAgbGV0IHRlbXAgPSB0aGlzLmxpc3Quc29ydCgoeCx5KSA9PiBjb21wYXJlci5jb21wYXJlKHgsIHkpKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIG5ldyBMaXN0PFQ+KHRlbXApO1xyXG4gICAgfVxyXG5cclxuICAgIHVuaW9uKGxpc3Q6IElFbnVtZXJhYmxlPFQ+KSA6IElFbnVtZXJhYmxlPFQ+IHtcclxuICAgICAgICB0aGlzLmFkZFJhbmdlKGxpc3QudG9BcnJheSgpKTtcclxuXHJcbiAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfVxyXG5cclxuICAgIHJldmVyc2UoKTogSUVudW1lcmFibGU8VD4ge1xyXG4gICAgICAgIHJldHVybiBuZXcgTGlzdDxUPih0aGlzLmxpc3Quc2xpY2UoKS5yZXZlcnNlKCkpO1xyXG4gICAgfVxyXG5cclxuICAgIGRpc3RpbmN0KGNvbXBhcmVyOiBJRXF1YWxpdHlDb21wYXJlcjxUPikgOiBJRW51bWVyYWJsZTxUPiB7XHJcbiAgICAgICAgbGV0IHVuaXF1ZXMgPSBuZXcgTGlzdDxUPigpO1xyXG4gICAgICAgIHRoaXMuZm9yRWFjaCh4ID0+IHtcclxuICAgICAgICAgICAgaWYgKHVuaXF1ZXMubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKCF1bmlxdWVzLmFueSh5ID0+IGNvbXBhcmVyLmVxdWFscyh4LCB5KSkpXHJcbiAgICAgICAgICAgICAgICB7XHJcbiAgICAgICAgICAgICAgICAgICAgdW5pcXVlcy5hZGQoeCk7XHJcbiAgICAgICAgICAgICAgICB9ICAgICAgICAgICAgICAgXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB1bmlxdWVzLmFkZCh4KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICByZXR1cm4gdW5pcXVlcztcclxuICAgIH1cclxuXHJcbiAgICBza2lwKG5vOiBudW1iZXIpIDogSUVudW1lcmFibGU8VD4ge1xyXG4gICAgICAgIGlmIChubyA+IDApIHtcclxuICAgICAgICAgICAgcmV0dXJuIG5ldyBMaXN0KHRoaXMubGlzdC5zbGljZShubywgdGhpcy5saXN0Lmxlbmd0aCAtIDEpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgXHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9XHJcblxyXG4gICAgdGFrZShubzogbnVtYmVyKSA6IElFbnVtZXJhYmxlPFQ+IHtcclxuICAgICAgICBpZiAobm8gPiAwKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBuZXcgTGlzdCh0aGlzLmxpc3Quc2xpY2UoMCwgbm8pKTtcclxuICAgICAgICB9ICAgICAgICBcclxuXHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9XHJcblxyXG4gICAgc3VtKHByZWRpY2F0ZTogKGl0ZW06IFQpPT4gbnVtYmVyKSA6IG51bWJlciB7XHJcbiAgICAgICAgbGV0IHN1bTogbnVtYmVyID0gMDtcclxuICAgICAgICB0aGlzLmxpc3QuZm9yRWFjaCh4ID0+IHN1bSA9IHN1bSArIHByZWRpY2F0ZSh4KSk7XHJcblxyXG4gICAgICAgIHJldHVybiBzdW07XHJcbiAgICB9XHJcblxyXG4gICAgYXZnKHByZWRpY2F0ZTogKGl0ZW06IFQpPT4gbnVtYmVyKSA6IG51bWJlciB7ICAgICAgICBcclxuICAgICAgICByZXR1cm4gdGhpcy5zdW0ocHJlZGljYXRlKSAvIHRoaXMubGVuZ3RoO1xyXG4gICAgfVxyXG5cclxuICAgIG1pbihwcmVkaWNhdGU6IChpdGVtOiBUKT0+IG51bWJlcikgOiBudW1iZXIge1xyXG4gICAgICAgIGxldCBtaW46IG51bWJlciA9IDA7XHJcbiAgICAgICAgbGV0IGkgPSAwO1xyXG4gICAgICAgIHRoaXMubGlzdC5mb3JFYWNoKHggPT4gXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgICBpZiAoaSA9PSAwKSB7XHJcbiAgICAgICAgICAgICAgICBtaW4gPSBwcmVkaWNhdGUoeCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBsZXQgdmFsID0gcHJlZGljYXRlKHgpO1xyXG4gICAgICAgICAgICAgICAgaWYgKHZhbCA8IG1pbikge1xyXG4gICAgICAgICAgICAgICAgICAgIG1pbiA9IHZhbDtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSAgICAgICAgICAgIFxyXG4gICAgICAgICAgICBpKys7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIHJldHVybiBtaW47XHJcbiAgICB9XHJcbiAgICBcclxuICAgIG1heChwcmVkaWNhdGU6IChpdGVtOiBUKT0+IG51bWJlcikgOiBudW1iZXIge1xyXG4gICAgICAgIGxldCBtYXg6IG51bWJlciA9IDA7XHJcbiAgICAgICAgbGV0IGkgPSAwO1xyXG4gICAgICAgIHRoaXMubGlzdC5mb3JFYWNoKHggPT4gXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgICBpZiAoaSA9PSAwKSB7XHJcbiAgICAgICAgICAgICAgICBtYXggPSBwcmVkaWNhdGUoeCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBsZXQgdmFsID0gcHJlZGljYXRlKHgpO1xyXG4gICAgICAgICAgICAgICAgaWYgKHZhbCA+IG1heCkge1xyXG4gICAgICAgICAgICAgICAgICAgIG1heCA9IHZhbDtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSAgICAgICAgICAgIFxyXG4gICAgICAgICAgICBpKys7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIHJldHVybiBtYXg7XHJcbiAgICB9ICAgIFxyXG4gICAgXHJcbiAgICBjb3VudChwcmVkaWNhdGU6IChpdGVtOiBUKT0+IGJvb2xlYW4gPSBudWxsKSA6IG51bWJlciB7XHJcbiAgICAgICAgaWYgKCFwcmVkaWNhdGUpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMubGVuZ3RoO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgbGV0IGNvdW50OiBudW1iZXIgPSAwO1xyXG4gICAgICAgIHRoaXMubGlzdC5mb3JFYWNoKHggPT4ge1xyXG4gICAgICAgICAgICBpZihwcmVkaWNhdGUoeCkpIHtcclxuICAgICAgICAgICAgICAgIGNvdW50Kys7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgcmV0dXJuIGNvdW50O1xyXG4gICAgfVxyXG5cclxufSJdfQ==