@neocomplexx/ngx-neo-pipes
Version:
This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 7.0.5.
814 lines • 73.9 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core')) :
typeof define === 'function' && define.amd ? define('@neocomplexx/ngx-neo-pipes', ['exports', '@angular/core'], factory) :
(factory((global.neocomplexx = global.neocomplexx || {}, global.neocomplexx['ngx-neo-pipes'] = {}),global.ng.core));
}(this, (function (exports,core) { 'use strict';
/*! *****************************************************************************
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of the
License at http://www.apache.org/licenses/LICENSE-2.0
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
MERCHANTABLITY OR NON-INFRINGEMENT.
See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
function __values(o) {
var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0;
if (m)
return m.call(o);
return {
next: function () {
if (o && i >= o.length)
o = void 0;
return { value: o && o[i++], done: !o };
}
};
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* Filter object array from property
*/
var FuncFilterPipe = /** @class */ (function () {
function FuncFilterPipe() {
}
/**
* @param {?} items
* @param {?} callback
* @return {?}
*/
FuncFilterPipe.prototype.transform = /**
* @param {?} items
* @param {?} callback
* @return {?}
*/
function (items, callback) {
if (!items || !callback) {
return [];
}
return items.filter(callback);
};
FuncFilterPipe.decorators = [
{ type: core.Pipe, args: [{
name: 'functionFilter'
},] },
{ type: core.Injectable }
];
return FuncFilterPipe;
}());
/**
* Filter object array from property
*/
var TextPipe = /** @class */ (function () {
function TextPipe() {
}
/**
* @author jcangelosi
* Filtra el arreglo items comparando el valor de su campo field (de tipo string) con el valor de value
* idea general : items.field == value
* NO FUNCIONA CON NUMEROS
*/
/**
* @author jcangelosi
* Filtra el arreglo items comparando el valor de su campo field (de tipo string) con el valor de value
* idea general : items.field == value
* NO FUNCIONA CON NUMEROS
* @param {?} items
* @param {?} field
* @param {?} value
* @return {?}
*/
TextPipe.prototype.transform = /**
* @author jcangelosi
* Filtra el arreglo items comparando el valor de su campo field (de tipo string) con el valor de value
* idea general : items.field == value
* NO FUNCIONA CON NUMEROS
* @param {?} items
* @param {?} field
* @param {?} value
* @return {?}
*/
function (items, field, value) {
if (!items) {
return [];
}
if (!field || !value) {
return items;
}
return items.filter(function (singleItem) { return singleItem[field].toLowerCase().includes(value.toLowerCase()); });
};
TextPipe.decorators = [
{ type: core.Pipe, args: [{
name: 'textFilter'
},] },
{ type: core.Injectable }
];
return TextPipe;
}());
/**
* Array filter with string value with 2 indirection level
*/
var TextPipeTwoLevel = /** @class */ (function () {
function TextPipeTwoLevel() {
}
/**
* @author jcangelosi
* Filtra el arreglo items comparando el valor de su campo secondfield con el valor de value
* idea general : items.field.secondField == value
* NO FUNCIONA CON NUMEROS
*/
/**
* @author jcangelosi
* Filtra el arreglo items comparando el valor de su campo secondfield con el valor de value
* idea general : items.field.secondField == value
* NO FUNCIONA CON NUMEROS
* @param {?} items
* @param {?} firstField
* @param {?} secondField
* @param {?} value
* @return {?}
*/
TextPipeTwoLevel.prototype.transform = /**
* @author jcangelosi
* Filtra el arreglo items comparando el valor de su campo secondfield con el valor de value
* idea general : items.field.secondField == value
* NO FUNCIONA CON NUMEROS
* @param {?} items
* @param {?} firstField
* @param {?} secondField
* @param {?} value
* @return {?}
*/
function (items, firstField, secondField, value) {
if (!items) {
return [];
}
if (!firstField || !secondField || !value) {
return items;
}
return items.filter(function (singleItem) { return (singleItem[firstField][secondField]).toLowerCase().includes(value.toLowerCase()); });
};
TextPipeTwoLevel.decorators = [
{ type: core.Pipe, args: [{
name: 'textFilter2Level'
},] },
{ type: core.Injectable }
];
return TextPipeTwoLevel;
}());
var NumberPipe = /** @class */ (function () {
function NumberPipe() {
}
/**
* @author jcangelosi
* Filtra el arreglo items comparando el valor de su campo field (de tipo number) con el valor de value
* idea general : items.field == value
* SOLO FUNCIONA CON NUMEROS
*/
/**
* @author jcangelosi
* Filtra el arreglo items comparando el valor de su campo field (de tipo number) con el valor de value
* idea general : items.field == value
* SOLO FUNCIONA CON NUMEROS
* @param {?} items
* @param {?} field
* @param {?} value
* @return {?}
*/
NumberPipe.prototype.transform = /**
* @author jcangelosi
* Filtra el arreglo items comparando el valor de su campo field (de tipo number) con el valor de value
* idea general : items.field == value
* SOLO FUNCIONA CON NUMEROS
* @param {?} items
* @param {?} field
* @param {?} value
* @return {?}
*/
function (items, field, value) {
if (!items) {
return [];
}
if (!field || !value) {
return items;
}
return items.filter(function (singleItem) { return singleItem[field].toString().includes(value.toString()); });
};
NumberPipe.decorators = [
{ type: core.Pipe, args: [{
name: 'numberFilter'
},] },
{ type: core.Injectable }
];
return NumberPipe;
}());
var ToStringPipe = /** @class */ (function () {
function ToStringPipe() {
}
/**
* @param {?} items
* @param {?} value
* @return {?}
*/
ToStringPipe.prototype.transform = /**
* @param {?} items
* @param {?} value
* @return {?}
*/
function (items, value) {
if (!items) {
return [];
}
if (!value) {
return items;
}
return items.filter(function (singleItem) { return singleItem.toString().toLowerCase().includes(value.toLowerCase()); });
};
ToStringPipe.decorators = [
{ type: core.Pipe, args: [{
name: 'toStringFilter'
},] },
{ type: core.Injectable }
];
return ToStringPipe;
}());
var NumberPipeTwoLevel = /** @class */ (function () {
function NumberPipeTwoLevel() {
}
/**
* @author jcangelosi
* Filtra el arreglo items comparando el valor de su campo secondfield con el valor de value
* idea general : items.field.secondField == value
* SOLO FUNCIONA CON NUMEROS
*/
/**
* @author jcangelosi
* Filtra el arreglo items comparando el valor de su campo secondfield con el valor de value
* idea general : items.field.secondField == value
* SOLO FUNCIONA CON NUMEROS
* @param {?} items
* @param {?} firstField
* @param {?} secondField
* @param {?} value
* @return {?}
*/
NumberPipeTwoLevel.prototype.transform = /**
* @author jcangelosi
* Filtra el arreglo items comparando el valor de su campo secondfield con el valor de value
* idea general : items.field.secondField == value
* SOLO FUNCIONA CON NUMEROS
* @param {?} items
* @param {?} firstField
* @param {?} secondField
* @param {?} value
* @return {?}
*/
function (items, firstField, secondField, value) {
if (!items) {
return [];
}
if (!firstField || !secondField || !value) {
return items;
}
return items.filter(function (singleItem) { return singleItem[firstField][secondField].toString().includes(value.toString()); });
};
NumberPipeTwoLevel.decorators = [
{ type: core.Pipe, args: [{
name: 'numberFilter2Level'
},] },
{ type: core.Injectable }
];
return NumberPipeTwoLevel;
}());
var RangePipe = /** @class */ (function () {
function RangePipe() {
}
/**
* @author jcangelosi
* Filtrara el arreglo en base a un rango de valores numericos dentro de un string
* Acepta lo siguiente: <numero, numero1-numero2 (>=numero1 y <numero2), >=numero2
*/
/**
* @author jcangelosi
* Filtrara el arreglo en base a un rango de valores numericos dentro de un string
* Acepta lo siguiente: <numero, numero1-numero2 (>=numero1 y <numero2), >=numero2
* @param {?} items
* @param {?} field
* @param {?} value
* @return {?}
*/
RangePipe.prototype.transform = /**
* @author jcangelosi
* Filtrara el arreglo en base a un rango de valores numericos dentro de un string
* Acepta lo siguiente: <numero, numero1-numero2 (>=numero1 y <numero2), >=numero2
* @param {?} items
* @param {?} field
* @param {?} value
* @return {?}
*/
function (items, field, value) {
if (!items) {
return [];
}
if (!field || !value) {
return items;
}
if (value.toString().includes('<')) { // Caso 1: es menor
// Caso 1: es menor
/** @type {?} */
var numeros = value.split('<');
/** @type {?} */
var numero_1 = +numeros[1];
return items.filter(function (singleItem) { return singleItem[field] < numero_1; });
}
if (value.toString().includes('-')) { // Caso 2: Rango
// Caso 2: Rango
/** @type {?} */
var numeros = value.split('-');
/** @type {?} */
var numero1_1 = +numeros[0];
/** @type {?} */
var numero2_1 = +numeros[1];
return items.filter(function (singleItem) { return singleItem[field] >= numero1_1 && singleItem[field] < numero2_1; });
}
if (value.toString().includes('>=')) { // Caso 3: Mayor o Igual
// Caso 3: Mayor o Igual
/** @type {?} */
var numeros = value.split('>=');
/** @type {?} */
var numero_2 = +numeros[1];
return items.filter(function (singleItem) { return singleItem[field] >= numero_2; });
}
// Caso 4, item vacio
return items;
};
RangePipe.decorators = [
{ type: core.Pipe, args: [{
name: 'rangeFilter'
},] },
{ type: core.Injectable }
];
return RangePipe;
}());
var RangePipeTwoLevel = /** @class */ (function () {
function RangePipeTwoLevel() {
}
/**
* @author jcangelosi
* Filtra el arreglo items comparando el valor de su campo secondfield en base a un rango de valores numericos dentro de un string
* Acepta lo siguiente: <numero, numero1-numero2 (>=numero1 y <numero2), >=numero2
*/
/**
* @author jcangelosi
* Filtra el arreglo items comparando el valor de su campo secondfield en base a un rango de valores numericos dentro de un string
* Acepta lo siguiente: <numero, numero1-numero2 (>=numero1 y <numero2), >=numero2
* @param {?} items
* @param {?} firstField
* @param {?} secondField
* @param {?} value
* @return {?}
*/
RangePipeTwoLevel.prototype.transform = /**
* @author jcangelosi
* Filtra el arreglo items comparando el valor de su campo secondfield en base a un rango de valores numericos dentro de un string
* Acepta lo siguiente: <numero, numero1-numero2 (>=numero1 y <numero2), >=numero2
* @param {?} items
* @param {?} firstField
* @param {?} secondField
* @param {?} value
* @return {?}
*/
function (items, firstField, secondField, value) {
if (!items) {
return [];
}
if (!firstField || !secondField || !value) {
return items;
}
if (value.toString().includes('<')) { // Caso 1: es menor
// Caso 1: es menor
/** @type {?} */
var numeros = value.split('<');
/** @type {?} */
var numero_3 = +numeros[1];
return items.filter(function (singleItem) { return singleItem[firstField][secondField] < numero_3; });
}
if (value.toString().includes('-')) { // Caso 2: Rango
// Caso 2: Rango
/** @type {?} */
var numeros = value.split('-');
/** @type {?} */
var numero1_2 = +numeros[0];
/** @type {?} */
var numero2_2 = +numeros[1];
return items.filter(function (singleItem) {
return singleItem[firstField][secondField] >= numero1_2 &&
singleItem[firstField][secondField] < numero2_2;
});
}
if (value.toString().includes('>')) { // Caso 3: Mayor o Igual
// Caso 3: Mayor o Igual
/** @type {?} */
var numeros = value.split('>');
/** @type {?} */
var numero_4 = +numeros[1];
return items.filter(function (singleItem) { return singleItem[firstField][secondField] >= numero_4; });
}
// Caso 4, item vacio
return items;
};
RangePipeTwoLevel.decorators = [
{ type: core.Pipe, args: [{
name: 'rangeFilter2Level'
},] },
{ type: core.Injectable }
];
return RangePipeTwoLevel;
}());
var DatePipe = /** @class */ (function () {
function DatePipe() {
}
/**
* @author jcangelosi
* Filtrara el arreglo items por una fecha representada por un string
*/
/**
* @author jcangelosi
* Filtrara el arreglo items por una fecha representada por un string
* @param {?} items
* @param {?} field
* @param {?} value
* @return {?}
*/
DatePipe.prototype.transform = /**
* @author jcangelosi
* Filtrara el arreglo items por una fecha representada por un string
* @param {?} items
* @param {?} field
* @param {?} value
* @return {?}
*/
function (items, field, value) {
if (!items) {
return [];
}
if (!field || !value) {
return items;
}
// caso contrario la fecha es valida
/** @type {?} */
var valores = value.split('-');
/** @type {?} */
var fecha = valores[2] + '/' + valores[1] + '/' + valores[0];
return items.filter(function (singleItem) { return singleItem[field].toLowerCase().includes(fecha); });
};
DatePipe.decorators = [
{ type: core.Pipe, args: [{
name: 'dateFilter'
},] },
{ type: core.Injectable }
];
return DatePipe;
}());
/**
* Pipe que se utiliza para separar los string de los nombres de los enumerables por palabra, de manera que queden mas agradables
* visualmente.
*/
var BeautifyPipe = /** @class */ (function () {
function BeautifyPipe() {
}
/**
* @param {?} text
* @return {?}
*/
BeautifyPipe.prototype.transform = /**
* @param {?} text
* @return {?}
*/
function (text) {
var e_1, _a;
if (text) {
/** @type {?} */
var palabras = text.split(/(?=[A-Z])/);
/** @type {?} */
var palabraAretornar = '';
try {
for (var palabras_1 = __values(palabras), palabras_1_1 = palabras_1.next(); !palabras_1_1.done; palabras_1_1 = palabras_1.next()) {
var palabra = palabras_1_1.value;
palabraAretornar = palabraAretornar.concat(' ', palabra);
}
}
catch (e_1_1) {
e_1 = { error: e_1_1 };
}
finally {
try {
if (palabras_1_1 && !palabras_1_1.done && (_a = palabras_1.return))
_a.call(palabras_1);
}
finally {
if (e_1)
throw e_1.error;
}
}
return palabraAretornar;
}
return text;
};
BeautifyPipe.decorators = [
{ type: core.Pipe, args: [{ name: 'beautify' },] }
];
return BeautifyPipe;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* Filter object array from property
*/
var PadLeftPipe = /** @class */ (function () {
function PadLeftPipe() {
}
/**
* @param {?} value
* @param {?} size
* @param {?} pad
* @return {?}
*/
PadLeftPipe.prototype.transform = /**
* @param {?} value
* @param {?} size
* @param {?} pad
* @return {?}
*/
function (value, size, pad) {
/** @type {?} */
var s = String(value);
while (s.length < (size || 2)) {
s = pad + s;
}
return s;
};
PadLeftPipe.decorators = [
{ type: core.Pipe, args: [{
name: 'padLeft'
},] },
{ type: core.Injectable }
];
return PadLeftPipe;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* Filter object array from property
*/
var SafeStringPipe = /** @class */ (function () {
function SafeStringPipe() {
}
/**
* @param {?} value
* @return {?}
*/
SafeStringPipe.prototype.transform = /**
* @param {?} value
* @return {?}
*/
function (value) {
if (value) {
return value;
}
else {
return '-';
}
};
SafeStringPipe.decorators = [
{ type: core.Pipe, args: [{
name: 'safeString'
},] },
{ type: core.Injectable }
];
return SafeStringPipe;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* Pipe que se utiliza para separar los string de los nombres de los enumerables por palabra, de manera que queden mas agradables
* visualmente.
* Se le pasa por parámetro el string separador, el cual no se visualizará en pantalla.
*/
var SplitBeautyPipe = /** @class */ (function () {
function SplitBeautyPipe() {
}
/**
* @param {?} text
* @param {?} args
* @return {?}
*/
SplitBeautyPipe.prototype.transform = /**
* @param {?} text
* @param {?} args
* @return {?}
*/
function (text, args) {
var e_1, _a;
if (text && args) {
/** @type {?} */
var palabras = text.split(args);
/** @type {?} */
var palabraAretornar = '';
try {
for (var palabras_1 = __values(palabras), palabras_1_1 = palabras_1.next(); !palabras_1_1.done; palabras_1_1 = palabras_1.next()) {
var palabra = palabras_1_1.value;
palabraAretornar = palabraAretornar.concat(' ', palabra);
}
}
catch (e_1_1) {
e_1 = { error: e_1_1 };
}
finally {
try {
if (palabras_1_1 && !palabras_1_1.done && (_a = palabras_1.return))
_a.call(palabras_1);
}
finally {
if (e_1)
throw e_1.error;
}
}
return palabraAretornar;
}
return text;
};
SplitBeautyPipe.decorators = [
{ type: core.Pipe, args: [{ name: 'splitBeauty' },] }
];
return SplitBeautyPipe;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* Filter object array from property
*/
var UnisexPipe = /** @class */ (function () {
function UnisexPipe() {
}
/**
* @param {?} value
* @param {?=} last
* @return {?}
*/
UnisexPipe.prototype.transform = /**
* @param {?} value
* @param {?=} last
* @return {?}
*/
function (value, last) {
if (last === void 0) {
last = 'x';
}
if (value) {
if (value.slice(-1) === last) {
return value.slice(0, -1) + "o/a";
}
return value;
}
else {
throw new Error('Undefined value in unisex pipe');
}
};
UnisexPipe.decorators = [
{ type: core.Pipe, args: [{
name: 'unisex'
},] },
{ type: core.Injectable }
];
return UnisexPipe;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* Filter object array from property
*/
var AccentPipe = /** @class */ (function () {
function AccentPipe() {
}
/**
* @param {?} value
* @param {?} replace
* @return {?}
*/
AccentPipe.prototype.transform = /**
* @param {?} value
* @param {?} replace
* @return {?}
*/
function (value, replace) {
if (value) {
if (replace) {
/** @type {?} */
var val = value;
val = val.replace(/1a/g, 'á');
val = val.replace(/1e/g, 'é');
val = val.replace(/1i/g, 'í');
val = val.replace(/1o/g, 'ó');
val = val.replace(/1u/g, 'ú');
return val;
}
else {
return value.replace(/1/g, '');
}
}
};
AccentPipe.decorators = [
{ type: core.Pipe, args: [{
name: 'accent'
},] },
{ type: core.Injectable }
];
return AccentPipe;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
var NgxNeoPipesModule = /** @class */ (function () {
function NgxNeoPipesModule() {
}
/**
* @return {?}
*/
NgxNeoPipesModule.forRoot = /**
* @return {?}
*/
function () {
return {
ngModule: NgxNeoPipesModule,
};
};
NgxNeoPipesModule.decorators = [
{ type: core.NgModule, args: [{
declarations: [NumberPipe, TextPipe, TextPipeTwoLevel, NumberPipeTwoLevel, ToStringPipe, FuncFilterPipe,
BeautifyPipe, DatePipe, RangePipe, RangePipeTwoLevel, PadLeftPipe, SafeStringPipe, SplitBeautyPipe, UnisexPipe, AccentPipe],
exports: [NumberPipe, TextPipe, TextPipeTwoLevel, NumberPipeTwoLevel, ToStringPipe, FuncFilterPipe,
BeautifyPipe, DatePipe, RangePipe, RangePipeTwoLevel, PadLeftPipe, SafeStringPipe, SplitBeautyPipe, UnisexPipe, AccentPipe],
},] }
];
return NgxNeoPipesModule;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
exports.NgxNeoPipesModule = NgxNeoPipesModule;
exports.FuncFilterPipe = FuncFilterPipe;
exports.TextPipe = TextPipe;
exports.TextPipeTwoLevel = TextPipeTwoLevel;
exports.NumberPipe = NumberPipe;
exports.ToStringPipe = ToStringPipe;
exports.NumberPipeTwoLevel = NumberPipeTwoLevel;
exports.RangePipe = RangePipe;
exports.RangePipeTwoLevel = RangePipeTwoLevel;
exports.DatePipe = DatePipe;
exports.BeautifyPipe = BeautifyPipe;
exports.SafeStringPipe = SafeStringPipe;
exports.UnisexPipe = UnisexPipe;
exports.AccentPipe = AccentPipe;
exports.ɵa = PadLeftPipe;
exports.ɵb = SplitBeautyPipe;
Object.defineProperty(exports, '__esModule', { value: true });
})));
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmVvY29tcGxleHgtbmd4LW5lby1waXBlcy51bWQuanMubWFwIiwic291cmNlcyI6WyJub2RlX21vZHVsZXMvdHNsaWIvdHNsaWIuZXM2LmpzIiwibmc6Ly9AbmVvY29tcGxleHgvbmd4LW5lby1waXBlcy9saWIvZmlsdGVycy5waXBlLnRzIiwibmc6Ly9AbmVvY29tcGxleHgvbmd4LW5lby1waXBlcy9saWIvbnVtYmVyLnBpcGUudHMiLCJuZzovL0BuZW9jb21wbGV4eC9uZ3gtbmVvLXBpcGVzL2xpYi9zYWZlLXN0cmluZy5waXBlLnRzIiwibmc6Ly9AbmVvY29tcGxleHgvbmd4LW5lby1waXBlcy9saWIvc3BsaXRCZWF1dHkucGlwZS50cyIsIm5nOi8vQG5lb2NvbXBsZXh4L25neC1uZW8tcGlwZXMvbGliL3VuaXNleC5waXBlLnRzIiwibmc6Ly9AbmVvY29tcGxleHgvbmd4LW5lby1waXBlcy9saWIvYWNjZW50LnBpcGUudHMiLCJuZzovL0BuZW9jb21wbGV4eC9uZ3gtbmVvLXBpcGVzL2xpYi9uZ3gtbmVvLXBpcGVzLm1vZHVsZS50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKiEgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcclxuQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7IHlvdSBtYXkgbm90IHVzZVxyXG50aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4gWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZVxyXG5MaWNlbnNlIGF0IGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxyXG5cclxuVEhJUyBDT0RFIElTIFBST1ZJREVEIE9OIEFOICpBUyBJUyogQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWVxyXG5LSU5ELCBFSVRIRVIgRVhQUkVTUyBPUiBJTVBMSUVELCBJTkNMVURJTkcgV0lUSE9VVCBMSU1JVEFUSU9OIEFOWSBJTVBMSUVEXHJcbldBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBUSVRMRSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UsXHJcbk1FUkNIQU5UQUJMSVRZIE9SIE5PTi1JTkZSSU5HRU1FTlQuXHJcblxyXG5TZWUgdGhlIEFwYWNoZSBWZXJzaW9uIDIuMCBMaWNlbnNlIGZvciBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnNcclxuYW5kIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxyXG4qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiAqL1xyXG4vKiBnbG9iYWwgUmVmbGVjdCwgUHJvbWlzZSAqL1xyXG5cclxudmFyIGV4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbihkLCBiKSB7XHJcbiAgICBleHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8XHJcbiAgICAgICAgKHsgX19wcm90b19fOiBbXSB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHsgZC5fX3Byb3RvX18gPSBiOyB9KSB8fFxyXG4gICAgICAgIGZ1bmN0aW9uIChkLCBiKSB7IGZvciAodmFyIHAgaW4gYikgaWYgKGIuaGFzT3duUHJvcGVydHkocCkpIGRbcF0gPSBiW3BdOyB9O1xyXG4gICAgcmV0dXJuIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19leHRlbmRzKGQsIGIpIHtcclxuICAgIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbiAgICBmdW5jdGlvbiBfXygpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7IH1cclxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcclxufVxyXG5cclxuZXhwb3J0IHZhciBfX2Fzc2lnbiA9IGZ1bmN0aW9uKCkge1xyXG4gICAgX19hc3NpZ24gPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uIF9fYXNzaWduKHQpIHtcclxuICAgICAgICBmb3IgKHZhciBzLCBpID0gMSwgbiA9IGFyZ3VtZW50cy5sZW5ndGg7IGkgPCBuOyBpKyspIHtcclxuICAgICAgICAgICAgcyA9IGFyZ3VtZW50c1tpXTtcclxuICAgICAgICAgICAgZm9yICh2YXIgcCBpbiBzKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHMsIHApKSB0W3BdID0gc1twXTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHQ7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gX19hc3NpZ24uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcmVzdChzLCBlKSB7XHJcbiAgICB2YXIgdCA9IHt9O1xyXG4gICAgZm9yICh2YXIgcCBpbiBzKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHMsIHApICYmIGUuaW5kZXhPZihwKSA8IDApXHJcbiAgICAgICAgdFtwXSA9IHNbcF07XHJcbiAgICBpZiAocyAhPSBudWxsICYmIHR5cGVvZiBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzID09PSBcImZ1bmN0aW9uXCIpXHJcbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIHAgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzKHMpOyBpIDwgcC5sZW5ndGg7IGkrKykgaWYgKGUuaW5kZXhPZihwW2ldKSA8IDApXHJcbiAgICAgICAgICAgIHRbcFtpXV0gPSBzW3BbaV1dO1xyXG4gICAgcmV0dXJuIHQ7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2RlY29yYXRlKGRlY29yYXRvcnMsIHRhcmdldCwga2V5LCBkZXNjKSB7XHJcbiAgICB2YXIgYyA9IGFyZ3VtZW50cy5sZW5ndGgsIHIgPSBjIDwgMyA/IHRhcmdldCA6IGRlc2MgPT09IG51bGwgPyBkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcih0YXJnZXQsIGtleSkgOiBkZXNjLCBkO1xyXG4gICAgaWYgKHR5cGVvZiBSZWZsZWN0ID09PSBcIm9iamVjdFwiICYmIHR5cGVvZiBSZWZsZWN0LmRlY29yYXRlID09PSBcImZ1bmN0aW9uXCIpIHIgPSBSZWZsZWN0LmRlY29yYXRlKGRlY29yYXRvcnMsIHRhcmdldCwga2V5LCBkZXNjKTtcclxuICAgIGVsc2UgZm9yICh2YXIgaSA9IGRlY29yYXRvcnMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIGlmIChkID0gZGVjb3JhdG9yc1tpXSkgciA9IChjIDwgMyA/IGQocikgOiBjID4gMyA/IGQodGFyZ2V0LCBrZXksIHIpIDogZCh0YXJnZXQsIGtleSkpIHx8IHI7XHJcbiAgICByZXR1cm4gYyA+IDMgJiYgciAmJiBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBrZXksIHIpLCByO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19wYXJhbShwYXJhbUluZGV4LCBkZWNvcmF0b3IpIHtcclxuICAgIHJldHVybiBmdW5jdGlvbiAodGFyZ2V0LCBrZXkpIHsgZGVjb3JhdG9yKHRhcmdldCwga2V5LCBwYXJhbUluZGV4KTsgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19tZXRhZGF0YShtZXRhZGF0YUtleSwgbWV0YWRhdGFWYWx1ZSkge1xyXG4gICAgaWYgKHR5cGVvZiBSZWZsZWN0ID09PSBcIm9iamVjdFwiICYmIHR5cGVvZiBSZWZsZWN0Lm1ldGFkYXRhID09PSBcImZ1bmN0aW9uXCIpIHJldHVybiBSZWZsZWN0Lm1ldGFkYXRhKG1ldGFkYXRhS2V5LCBtZXRhZGF0YVZhbHVlKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fYXdhaXRlcih0aGlzQXJnLCBfYXJndW1lbnRzLCBQLCBnZW5lcmF0b3IpIHtcclxuICAgIHJldHVybiBuZXcgKFAgfHwgKFAgPSBQcm9taXNlKSkoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xyXG4gICAgICAgIGZ1bmN0aW9uIGZ1bGZpbGxlZCh2YWx1ZSkgeyB0cnkgeyBzdGVwKGdlbmVyYXRvci5uZXh0KHZhbHVlKSk7IH0gY2F0Y2ggKGUpIHsgcmVqZWN0KGUpOyB9IH1cclxuICAgICAgICBmdW5jdGlvbiByZWplY3RlZCh2YWx1ZSkgeyB0cnkgeyBzdGVwKGdlbmVyYXRvcltcInRocm93XCJdKHZhbHVlKSk7IH0gY2F0Y2ggKGUpIHsgcmVqZWN0KGUpOyB9IH1cclxuICAgICAgICBmdW5jdGlvbiBzdGVwKHJlc3VsdCkgeyByZXN1bHQuZG9uZSA/IHJlc29sdmUocmVzdWx0LnZhbHVlKSA6IG5ldyBQKGZ1bmN0aW9uIChyZXNvbHZlKSB7IHJlc29sdmUocmVzdWx0LnZhbHVlKTsgfSkudGhlbihmdWxmaWxsZWQsIHJlamVjdGVkKTsgfVxyXG4gICAgICAgIHN0ZXAoKGdlbmVyYXRvciA9IGdlbmVyYXRvci5hcHBseSh0aGlzQXJnLCBfYXJndW1lbnRzIHx8IFtdKSkubmV4dCgpKTtcclxuICAgIH0pO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19nZW5lcmF0b3IodGhpc0FyZywgYm9keSkge1xyXG4gICAgdmFyIF8gPSB7IGxhYmVsOiAwLCBzZW50OiBmdW5jdGlvbigpIHsgaWYgKHRbMF0gJiAxKSB0aHJvdyB0WzFdOyByZXR1cm4gdFsxXTsgfSwgdHJ5czogW10sIG9wczogW10gfSwgZiwgeSwgdCwgZztcclxuICAgIHJldHVybiBnID0geyBuZXh0OiB2ZXJiKDApLCBcInRocm93XCI6IHZlcmIoMSksIFwicmV0dXJuXCI6IHZlcmIoMikgfSwgdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIChnW1N5bWJvbC5pdGVyYXRvcl0gPSBmdW5jdGlvbigpIHsgcmV0dXJuIHRoaXM7IH0pLCBnO1xyXG4gICAgZnVuY3Rpb24gdmVyYihuKSB7IHJldHVybiBmdW5jdGlvbiAodikgeyByZXR1cm4gc3RlcChbbiwgdl0pOyB9OyB9XHJcbiAgICBmdW5jdGlvbiBzdGVwKG9wKSB7XHJcbiAgICAgICAgaWYgKGYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJHZW5lcmF0b3IgaXMgYWxyZWFkeSBleGVjdXRpbmcuXCIpO1xyXG4gICAgICAgIHdoaWxlIChfKSB0cnkge1xyXG4gICAgICAgICAgICBpZiAoZiA9IDEsIHkgJiYgKHQgPSBvcFswXSAmIDIgPyB5W1wicmV0dXJuXCJdIDogb3BbMF0gPyB5W1widGhyb3dcIl0gfHwgKCh0ID0geVtcInJldHVyblwiXSkgJiYgdC5jYWxsKHkpLCAwKSA6IHkubmV4dCkgJiYgISh0ID0gdC5jYWxsKHksIG9wWzFdKSkuZG9uZSkgcmV0dXJuIHQ7XHJcbiAgICAgICAgICAgIGlmICh5ID0gMCwgdCkgb3AgPSBbb3BbMF0gJiAyLCB0LnZhbHVlXTtcclxuICAgICAgICAgICAgc3dpdGNoIChvcFswXSkge1xyXG4gICAgICAgICAgICAgICAgY2FzZSAwOiBjYXNlIDE6IHQgPSBvcDsgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDQ6IF8ubGFiZWwrKzsgcmV0dXJuIHsgdmFsdWU6IG9wWzFdLCBkb25lOiBmYWxzZSB9O1xyXG4gICAgICAgICAgICAgICAgY2FzZSA1OiBfLmxhYmVsKys7IHkgPSBvcFsxXTsgb3AgPSBbMF07IGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgY2FzZSA3OiBvcCA9IF8ub3BzLnBvcCgpOyBfLnRyeXMucG9wKCk7IGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcclxuICAgICAgICAgICAgICAgICAgICBpZiAoISh0ID0gXy50cnlzLCB0ID0gdC5sZW5ndGggPiAwICYmIHRbdC5sZW5ndGggLSAxXSkgJiYgKG9wWzBdID09PSA2IHx8IG9wWzBdID09PSAyKSkgeyBfID0gMDsgY29udGludWU7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAob3BbMF0gPT09IDMgJiYgKCF0IHx8IChvcFsxXSA+IHRbMF0gJiYgb3BbMV0gPCB0WzNdKSkpIHsgXy5sYWJlbCA9IG9wWzFdOyBicmVhazsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChvcFswXSA9PT0gNiAmJiBfLmxhYmVsIDwgdFsxXSkgeyBfLmxhYmVsID0gdFsxXTsgdCA9IG9wOyBicmVhazsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0ICYmIF8ubGFiZWwgPCB0WzJdKSB7IF8ubGFiZWwgPSB0WzJdOyBfLm9wcy5wdXNoKG9wKTsgYnJlYWs7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAodFsyXSkgXy5vcHMucG9wKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgXy50cnlzLnBvcCgpOyBjb250aW51ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBvcCA9IGJvZHkuY2FsbCh0aGlzQXJnLCBfKTtcclxuICAgICAgICB9IGNhdGNoIChlKSB7IG9wID0gWzYsIGVdOyB5ID0gMDsgfSBmaW5hbGx5IHsgZiA9IHQgPSAwOyB9XHJcbiAgICAgICAgaWYgKG9wWzBdICYgNSkgdGhyb3cgb3BbMV07IHJldHVybiB7IHZhbHVlOiBvcFswXSA/IG9wWzFdIDogdm9pZCAwLCBkb25lOiB0cnVlIH07XHJcbiAgICB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2V4cG9ydFN0YXIobSwgZXhwb3J0cykge1xyXG4gICAgZm9yICh2YXIgcCBpbiBtKSBpZiAoIWV4cG9ydHMuaGFzT3duUHJvcGVydHkocCkpIGV4cG9ydHNbcF0gPSBtW3BdO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX192YWx1ZXMobykge1xyXG4gICAgdmFyIG0gPSB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgb1tTeW1ib2wuaXRlcmF0b3JdLCBpID0gMDtcclxuICAgIGlmIChtKSByZXR1cm4gbS5jYWxsKG8pO1xyXG4gICAgcmV0dXJuIHtcclxuICAgICAgICBuZXh0OiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGlmIChvICYmIGkgPj0gby5sZW5ndGgpIG8gPSB2b2lkIDA7XHJcbiAgICAgICAgICAgIHJldHVybiB7IHZhbHVlOiBvICYmIG9baSsrXSwgZG9uZTogIW8gfTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19yZWFkKG8sIG4pIHtcclxuICAgIHZhciBtID0gdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIG9bU3ltYm9sLml0ZXJhdG9yXTtcclxuICAgIGlmICghbSkgcmV0dXJuIG87XHJcbiAgICB2YXIgaSA9IG0uY2FsbChvKSwgciwgYXIgPSBbXSwgZTtcclxuICAgIHRyeSB7XHJcbiAgICAgICAgd2hpbGUgKChuID09PSB2b2lkIDAgfHwgbi0tID4gMCkgJiYgIShyID0gaS5uZXh0KCkpLmRvbmUpIGFyLnB1c2goci52YWx1ZSk7XHJcbiAgICB9XHJcbiAgICBjYXRjaCAoZXJyb3IpIHsgZSA9IHsgZXJyb3I6IGVycm9yIH07IH1cclxuICAgIGZpbmFsbHkge1xyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIGlmIChyICYmICFyLmRvbmUgJiYgKG0gPSBpW1wicmV0dXJuXCJdKSkgbS5jYWxsKGkpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBmaW5hbGx5IHsgaWYgKGUpIHRocm93IGUuZXJyb3I7IH1cclxuICAgIH1cclxuICAgIHJldHVybiBhcjtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fc3ByZWFkKCkge1xyXG4gICAgZm9yICh2YXIgYXIgPSBbXSwgaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspXHJcbiAgICAgICAgYXIgPSBhci5jb25jYXQoX19yZWFkKGFyZ3VtZW50c1tpXSkpO1xyXG4gICAgcmV0dXJuIGFyO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hd2FpdCh2KSB7XHJcbiAgICByZXR1cm4gdGhpcyBpbnN0YW5jZW9mIF9fYXdhaXQgPyAodGhpcy52ID0gdiwgdGhpcykgOiBuZXcgX19hd2FpdCh2KTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fYXN5bmNHZW5lcmF0b3IodGhpc0FyZywgX2FyZ3VtZW50cywgZ2VuZXJhdG9yKSB7XHJcbiAgICBpZiAoIVN5bWJvbC5hc3luY0l0ZXJhdG9yKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiU3ltYm9sLmFzeW5jSXRlcmF0b3IgaXMgbm90IGRlZmluZWQuXCIpO1xyXG4gICAgdmFyIGcgPSBnZW5lcmF0b3IuYXBwbHkodGhpc0FyZywgX2FyZ3VtZW50cyB8fCBbXSksIGksIHEgPSBbXTtcclxuICAgIHJldHVybiBpID0ge30sIHZlcmIoXCJuZXh0XCIpLCB2ZXJiKFwidGhyb3dcIiksIHZlcmIoXCJyZXR1cm5cIiksIGlbU3ltYm9sLmFzeW5jSXRlcmF0b3JdID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpczsgfSwgaTtcclxuICAgIGZ1bmN0aW9uIHZlcmIobikgeyBpZiAoZ1tuXSkgaVtuXSA9IGZ1bmN0aW9uICh2KSB7IHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAoYSwgYikgeyBxLnB1c2goW24sIHYsIGEsIGJdKSA+IDEgfHwgcmVzdW1lKG4sIHYpOyB9KTsgfTsgfVxyXG4gICAgZnVuY3Rpb24gcmVzdW1lKG4sIHYpIHsgdHJ5IHsgc3RlcChnW25dKHYpKTsgfSBjYXRjaCAoZSkgeyBzZXR0bGUocVswXVszXSwgZSk7IH0gfVxyXG4gICAgZnVuY3Rpb24gc3RlcChyKSB7IHIudmFsdWUgaW5zdGFuY2VvZiBfX2F3YWl0ID8gUHJvbWlzZS5yZXNvbHZlKHIudmFsdWUudikudGhlbihmdWxmaWxsLCByZWplY3QpIDogc2V0dGxlKHFbMF1bMl0sIHIpOyB9XHJcbiAgICBmdW5jdGlvbiBmdWxmaWxsKHZhbHVlKSB7IHJlc3VtZShcIm5leHRcIiwgdmFsdWUpOyB9XHJcbiAgICBmdW5jdGlvbiByZWplY3QodmFsdWUpIHsgcmVzdW1lKFwidGhyb3dcIiwgdmFsdWUpOyB9XHJcbiAgICBmdW5jdGlvbiBzZXR0bGUoZiwgdikgeyBpZiAoZih2KSwgcS5zaGlmdCgpLCBxLmxlbmd0aCkgcmVzdW1lKHFbMF1bMF0sIHFbMF1bMV0pOyB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2FzeW5jRGVsZWdhdG9yKG8pIHtcclxuICAgIHZhciBpLCBwO1xyXG4gICAgcmV0dXJuIGkgPSB7fSwgdmVyYihcIm5leHRcIiksIHZlcmIoXCJ0aHJvd1wiLCBmdW5jdGlvbiAoZSkgeyB0aHJvdyBlOyB9KSwgdmVyYihcInJldHVyblwiKSwgaVtTeW1ib2wuaXRlcmF0b3JdID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpczsgfSwgaTtcclxuICAgIGZ1bmN0aW9uIHZlcmIobiwgZikgeyBpW25dID0gb1tuXSA/IGZ1bmN0aW9uICh2KSB7IHJldHVybiAocCA9ICFwKSA/IHsgdmFsdWU6IF9fYXdhaXQob1tuXSh2KSksIGRvbmU6IG4gPT09IFwicmV0dXJuXCIgfSA6IGYgPyBmKHYpIDogdjsgfSA6IGY7IH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fYXN5bmNWYWx1ZXMobykge1xyXG4gICAgaWYgKCFTeW1ib2wuYXN5bmNJdGVyYXRvcikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlN5bWJvbC5hc3luY0l0ZXJhdG9yIGlzIG5vdCBkZWZpbmVkLlwiKTtcclxuICAgIHZhciBtID0gb1tTeW1ib2wuYXN5bmNJdGVyYXRvcl0sIGk7XHJcbiAgICByZXR1cm4gbSA/IG0uY2FsbChvKSA6IChvID0gdHlwZW9mIF9fdmFsdWVzID09PSBcImZ1bmN0aW9uXCIgPyBfX3ZhbHVlcyhvKSA6IG9bU3ltYm9sLml0ZXJhdG9yXSgpLCBpID0ge30sIHZlcmIoXCJuZXh0XCIpLCB2ZXJiKFwidGhyb3dcIiksIHZlcmIoXCJyZXR1cm5cIiksIGlbU3ltYm9sLmFzeW5jSXRlcmF0b3JdID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpczsgfSwgaSk7XHJcbiAgICBmdW5jdGlvbiB2ZXJiKG4pIHsgaVtuXSA9IG9bbl0gJiYgZnVuY3Rpb24gKHYpIHsgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHsgdiA9IG9bbl0odiksIHNldHRsZShyZXNvbHZlLCByZWplY3QsIHYuZG9uZSwgdi52YWx1ZSk7IH0pOyB9OyB9XHJcbiAgICBmdW5jdGlvbiBzZXR0bGUocmVzb2x2ZSwgcmVqZWN0LCBkLCB2KSB7IFByb21pc2UucmVzb2x2ZSh2KS50aGVuKGZ1bmN0aW9uKHYpIHsgcmVzb2x2ZSh7IHZhbHVlOiB2LCBkb25lOiBkIH0pOyB9LCByZWplY3QpOyB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX21ha2VUZW1wbGF0ZU9iamVjdChjb29rZWQsIHJhdykge1xyXG4gICAgaWYgKE9iamVjdC5kZWZpbmVQcm9wZXJ0eSkgeyBPYmplY3QuZGVmaW5lUHJvcGVydHkoY29va2VkLCBcInJhd1wiLCB7IHZhbHVlOiByYXcgfSk7IH0gZWxzZSB7IGNvb2tlZC5yYXcgPSByYXc7IH1cclxuICAgIHJldHVybiBjb29rZWQ7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19pbXBvcnRTdGFyKG1vZCkge1xyXG4gICAgaWYgKG1vZCAmJiBtb2QuX19lc01vZHVsZSkgcmV0dXJuIG1vZDtcclxuICAgIHZhciByZXN1bHQgPSB7fTtcclxuICAgIGlmIChtb2QgIT0gbnVsbCkgZm9yICh2YXIgayBpbiBtb2QpIGlmIChPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtb2QsIGspKSByZXN1bHRba10gPSBtb2Rba107XHJcbiAgICByZXN1bHQuZGVmYXVsdCA9IG1vZDtcclxuICAgIHJldHVybiByZXN1bHQ7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2ltcG9ydERlZmF1bHQobW9kKSB7XHJcbiAgICByZXR1cm4gKG1vZCAmJiBtb2QuX19lc01vZHVsZSkgPyBtb2QgOiB7IGRlZmF1bHQ6IG1vZCB9O1xyXG59XHJcbiIsImltcG9ydCB7IFBpcGUsIFBpcGVUcmFuc2Zvcm0sIEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuXHJcbi8qKlxyXG4gKiBGaWx0ZXIgb2JqZWN0IGFycmF5IGZyb20gcHJvcGVydHlcclxuICovXHJcbkBQaXBlKHtcclxuICAgIG5hbWU6ICdmdW5jdGlvbkZpbHRlcidcclxufSlcclxuQEluamVjdGFibGUoKVxyXG5leHBvcnQgY2xhc3MgRnVuY0ZpbHRlclBpcGUgaW1wbGVtZW50cyBQaXBlVHJhbnNmb3JtIHtcclxuICAgIHRyYW5zZm9ybShpdGVtczogYW55W10sIGNhbGxiYWNrOiAodmFsdWU6IGFueSkgPT4gYm9vbGVhbik6IGFueVtdIHtcclxuXHJcbiAgICAgICAgaWYgKCFpdGVtcyB8fCAhY2FsbGJhY2spIHtcclxuICAgICAgICAgICAgcmV0dXJuIFtdO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIGl0ZW1zLmZpbHRlcihjYWxsYmFjayk7XHJcbiAgICB9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBGaWx0ZXIgb2JqZWN0IGFycmF5IGZyb20gcHJvcGVydHlcclxuICovXHJcbkBQaXBlKHtcclxuICAgIG5hbWU6ICd0ZXh0RmlsdGVyJ1xyXG59KVxyXG5ASW5qZWN0YWJsZSgpXHJcbmV4cG9ydCBjbGFzcyBUZXh0UGlwZSBpbXBsZW1lbnRzIFBpcGVUcmFuc2Zvcm0ge1xyXG4gICAgLyoqXHJcbiAgICAgKiBAYXV0aG9yIGpjYW5nZWxvc2lcclxuICAgICAqIEZpbHRyYSBlbCBhcnJlZ2xvIGl0ZW1zIGNvbXBhcmFuZG8gZWwgdmFsb3IgZGUgc3UgY2FtcG8gZmllbGQgKGRlIHRpcG8gc3RyaW5nKSBjb24gZWwgdmFsb3IgZGUgdmFsdWVcclxuICAgICAqIGlkZWEgZ2VuZXJhbCA6IGl0ZW1zLmZpZWxkID09IHZhbHVlXHJcbiAgICAgKiBOTyBGVU5DSU9OQSBDT04gTlVNRVJPU1xyXG4gICAgICovXHJcbiAgICB0cmFuc2Zvcm0oaXRlbXM6IGFueVtdLCBmaWVsZDogc3RyaW5nLCB2YWx1ZTogc3RyaW5nKTogYW55W10ge1xyXG4gICAgICAgIGlmICghaXRlbXMpIHtcclxuICAgICAgICAgICAgcmV0dXJuIFtdO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoIWZpZWxkIHx8ICF2YWx1ZSkge1xyXG4gICAgICAgICAgICByZXR1cm4gaXRlbXM7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBpdGVtcy5maWx0ZXIoc2luZ2xlSXRlbSA9PiBzaW5nbGVJdGVtW2ZpZWxkXS50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKHZhbHVlLnRvTG93ZXJDYXNlKCkpKTtcclxuICAgIH1cclxufVxyXG4vKipcclxuICogQXJyYXkgZmlsdGVyIHdpdGggc3RyaW5nIHZhbHVlIHdpdGggMiBpbmRpcmVjdGlvbiBsZXZlbFxyXG4gKi9cclxuQFBpcGUoe1xyXG4gICAgbmFtZTogJ3RleHRGaWx0ZXIyTGV2ZWwnXHJcbn0pXHJcbkBJbmplY3RhYmxlKClcclxuZXhwb3J0IGNsYXNzIFRleHRQaXBlVHdvTGV2ZWwgaW1wbGVtZW50cyBQaXBlVHJhbnNmb3JtIHtcclxuICAgIC8qKlxyXG4gICAgICogQGF1dGhvciBqY2FuZ2Vsb3NpXHJcbiAgICAgKiBGaWx0cmEgZWwgYXJyZWdsbyBpdGVtcyBjb21wYXJhbmRvIGVsIHZhbG9yIGRlIHN1IGNhbXBvIHNlY29uZGZpZWxkIGNvbiBlbCB2YWxvciBkZSB2YWx1ZVxyXG4gICAgICogaWRlYSBnZW5lcmFsIDogaXRlbXMuZmllbGQuc2Vjb25kRmllbGQgPT0gdmFsdWVcclxuICAgICAqIE5PIEZVTkNJT05BIENPTiBOVU1FUk9TXHJcbiAgICAgKi9cclxuICAgIHRyYW5zZm9ybShpdGVtczogYW55W10sIGZpcnN0RmllbGQ6IHN0cmluZywgc2Vjb25kRmllbGQ6IHN0cmluZywgdmFsdWU6IHN0cmluZyk6IGFueVtdIHtcclxuXHJcbiAgICAgICAgaWYgKCFpdGVtcykge1xyXG4gICAgICAgICAgICByZXR1cm4gW107XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICghZmlyc3RGaWVsZCB8fCAhc2Vjb25kRmllbGQgfHwgIXZhbHVlKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBpdGVtcztcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIGl0ZW1zLmZpbHRlcihzaW5nbGVJdGVtID0+IChzaW5nbGVJdGVtW2ZpcnN0RmllbGRdW3NlY29uZEZpZWxkXSkudG9Mb3dlckNhc2UoKS5pbmNsdWRlcyh2YWx1ZS50b0xvd2VyQ2FzZSgpKSk7XHJcbiAgICB9XHJcbn1cclxuXHJcbkBQaXBlKHtcclxuICAgIG5hbWU6ICdudW1iZXJGaWx0ZXInXHJcbn0pXHJcbkBJbmplY3RhYmxlKClcclxuZXhwb3J0IGNsYXNzIE51bWJlclBpcGUgaW1wbGVtZW50cyBQaXBlVHJhbnNmb3JtIHtcclxuICAgIC8qKlxyXG4gICAgKiBAYXV0aG9yIGpjYW5nZWxvc2lcclxuICAgICogRmlsdHJhIGVsIGFycmVnbG8gaXRlbXMgY29tcGFyYW5kbyBlbCB2YWxvciBkZSBzdSBjYW1wbyBmaWVsZCAoZGUgdGlwbyBudW1iZXIpIGNvbiBlbCB2YWxvciBkZSB2YWx1ZVxyXG4gICAgKiBpZGVhIGdlbmVyYWwgOiBpdGVtcy5maWVsZCA9PSB2YWx1ZVxyXG4gICAgKiBTT0xPIEZVTkNJT05BIENPTiBOVU1FUk9TXHJcbiAgICAqL1xyXG4gICAgdHJhbnNmb3JtKGl0ZW1zOiBhbnlbXSwgZmllbGQ6IHN0cmluZywgdmFsdWU6IG51bWJlcik6IGFueVtdIHtcclxuICAgICAgICBpZiAoIWl0ZW1zKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBbXTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKCFmaWVsZCB8fCAhdmFsdWUpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGl0ZW1zO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gaXRlbXMuZmlsdGVyKHNpbmdsZUl0ZW0gPT4gc2luZ2xlSXRlbVtmaWVsZF0udG9TdHJpbmcoKS5pbmNsdWRlcyh2YWx1ZS50b1N0cmluZygpKSk7XHJcbiAgICB9XHJcbn1cclxuXHJcbkBQaXBlKHtcclxuICAgIG5hbWU6ICd0b1N0cmluZ0ZpbHRlcidcclxufSlcclxuQEluamVjdGFibGUoKVxyXG5leHBvcnQgY2xhc3MgVG9TdHJpbmdQaXBlIGltcGxlbWVudHMgUGlwZVRyYW5zZm9ybSB7XHJcbiAgICB0cmFuc2Zvcm0oaXRlbXM6IGFueVtdLCB2YWx1ZTogc3RyaW5nKTogYW55W10ge1xyXG4gICAgICAgIGlmICghaXRlbXMpIHtcclxuICAgICAgICAgICAgcmV0dXJuIFtdO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoIXZhbHVlKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBpdGVtcztcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIGl0ZW1zLmZpbHRlcihzaW5nbGVJdGVtID0+IHNpbmdsZUl0ZW0udG9TdHJpbmcoKS50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKHZhbHVlLnRvTG93ZXJDYXNlKCkpKTtcclxuICAgIH1cclxufVxyXG5cclxuQFBpcGUoe1xyXG4gICAgbmFtZTogJ251bWJlckZpbHRlcjJMZXZlbCdcclxufSlcclxuQEluamVjdGFibGUoKVxyXG5leHBvcnQgY2xhc3MgTnVtYmVyUGlwZVR3b0xldmVsIGltcGxlbWVudHMgUGlwZVRyYW5zZm9ybSB7XHJcbiAgICAvKipcclxuICAgICAqIEBhdXRob3IgamNhbmdlbG9zaVxyXG4gICAgICogRmlsdHJhIGVsIGFycmVnbG8gaXRlbXMgY29tcGFyYW5kbyBlbCB2YWxvciBkZSBzdSBjYW1wbyBzZWNvbmRmaWVsZCBjb24gZWwgdmFsb3IgZGUgdmFsdWVcclxuICAgICAqIGlkZWEgZ2VuZXJhbCA6IGl0ZW1zLmZpZWxkLnNlY29uZEZpZWxkID09IHZhbHVlXHJcbiAgICAgKiBTT0xPIEZVTkNJT05BIENPTiBOVU1FUk9TXHJcbiAgICAgKi9cclxuICAgIHRyYW5zZm9ybShpdGVtczogYW55W10sIGZpcnN0RmllbGQ6IHN0cmluZywgc2Vjb25kRmllbGQ6IHN0cmluZywgdmFsdWU6IG51bWJlcik6IGFueVtdIHtcclxuICAgICAgICBpZiAoIWl0ZW1zKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBbXTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKCFmaXJzdEZpZWxkIHx8ICFzZWNvbmRGaWVsZCB8fCAhdmFsdWUpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGl0ZW1zO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gaXRlbXMuZmlsdGVyKHNpbmdsZUl0ZW0gPT4gc2luZ2xlSXRlbVtmaXJzdEZpZWxkXVtzZWNvbmRGaWVsZF0udG9TdHJpbmcoKS5pbmNsdWRlcyh2YWx1ZS50b1N0cmluZygpKSk7XHJcbiAgICB9XHJcbn1cclxuXHJcbkBQaXBlKHtcclxuICAgIG5hbWU6ICdyYW5nZUZpbHRlcidcclxufSlcclxuQEluamVjdGFibGUoKVxyXG5leHBvcnQgY2xhc3MgUmFuZ2VQaXBlIGltcGxlbWVudHMgUGlwZVRyYW5zZm9ybSB7XHJcbiAgICAvKipcclxuICAgICAqIEBhdXRob3IgamNhbmdlbG9zaVxyXG4gICAgICogIEZpbHRyYXJhIGVsIGFycmVnbG8gZW4gYmFzZSBhIHVuIHJhbmdvIGRlIHZhbG9yZXMgbnVtZXJpY29zIGRlbnRybyBkZSB1biBzdHJpbmdcclxuICAgICAqICBBY2VwdGEgbG8gc2lndWllbnRlOiA8bnVtZXJvLCBudW1lcm8xLW51bWVybzIgKD49bnVtZXJvMSB5IDxudW1lcm8yKSwgPj1udW1lcm8yXHJcbiAgICAgKi9cclxuICAgIHRyYW5zZm9ybShpdGVtczogYW55W10sIGZpZWxkOiBzdHJpbmcsIHZhbHVlOiBzdHJpbmcpOiBhbnlbXSB7XHJcbiAgICAgICAgaWYgKCFpdGVtcykge1xyXG4gICAgICAgICAgICByZXR1cm4gW107XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICghZmllbGQgfHwgIXZhbHVlKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBpdGVtcztcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHZhbHVlLnRvU3RyaW5nKCkuaW5jbHVkZXMoJzwnKSkgeyAvLyBDYXNvIDE6IGVzIG1lbm9yXHJcbiAgICAgICAgICAgIGNvbnN0IG51bWVyb3MgPSB2YWx1ZS5zcGxpdCgnPCcpO1xyXG4gICAgICAgICAgICBjb25zdCBudW1lcm86IG51bWJlciA9ICtudW1lcm9zWzFdO1xyXG4gICAgICAgICAgICByZXR1cm4gaXRlbXMuZmlsdGVyKHNpbmdsZUl0ZW0gPT4gc2luZ2xlSXRlbVtmaWVsZF0gPCBudW1lcm8pO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAodmFsdWUudG9TdHJpbmcoKS5pbmNsdWRlcygnLScpKSB7IC8vIENhc28gMjogUmFuZ29cclxuICAgICAgICAgICAgY29uc3QgbnVtZXJvcyA9IHZhbHVlLnNwbGl0KCctJyk7XHJcbiAgICAgICAgICAgIGNvbnN0IG51bWVybzE6IG51bWJlciA9ICsgbnVtZXJvc1swXTtcclxuICAgICAgICAgICAgY29uc3QgbnVtZXJvMjogbnVtYmVyID0gKyBudW1lcm9zWzFdO1xyXG4gICAgICAgICAgICByZXR1cm4gaXRlbXMuZmlsdGVyKHNpbmdsZUl0ZW0gPT4gc2luZ2xlSXRlbVtmaWVsZF0gPj0gbnVtZXJvMSAmJiBzaW5nbGVJdGVtW2ZpZWxkXSA8IG51bWVybzIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAodmFsdWUudG9TdHJpbmcoKS5pbmNsdWRlcygnPj0nKSkgeyAvLyBDYXNvIDM6IE1heW9yIG8gSWd1YWxcclxuICAgICAgICAgICAgY29uc3QgbnVtZXJvcyA9IHZhbHVlLnNwbGl0KCc+PScpO1xyXG4gICAgICAgICAgICBjb25zdCBudW1lcm86IG51bWJlciA9ICsgbnVtZXJvc1sxXTtcclxuICAgICAgICAgICAgcmV0dXJuIGl0ZW1zLmZpbHRlcihzaW5nbGVJdGVtID0+IHNpbmdsZUl0ZW1bZmllbGRdID49IG51bWVybyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIENhc28gNCwgaXRlbSB2YWNpb1xyXG4gICAgICAgIHJldHVybiBpdGVtcztcclxuICAgIH1cclxufVxyXG5cclxuQFBpcGUoe1xyXG4gICAgbmFtZTogJ3JhbmdlRmlsdGVyMkxldmVsJ1xyXG59KVxyXG5ASW5qZWN0YWJsZSgpXHJcbmV4cG9ydCBjbGFzcyBSYW5nZVBpcGVUd29MZXZlbCBpbXBsZW1lbnRzIFBpcGVUcmFuc2Zvcm0ge1xyXG4gICAgLyoqXHJcbiAgICAgKiBAYXV0aG9yIGpjYW5nZWxvc2lcclxuICAgICAqIEZpbHRyYSBlbCBhcnJlZ2xvIGl0ZW1zIGNvbXBhcmFuZG8gZWwgdmFsb3IgZGUgc3UgY2FtcG8gc2Vjb25kZmllbGQgZW4gYmFzZSBhIHVuIHJhbmdvIGRlIHZhbG9yZXMgbnVtZXJpY29zIGRlbnRybyBkZSB1biBzdHJpbmdcclxuICAgICAqICBBY2VwdGEgbG8gc2lndWllbnRlOiA8bnVtZXJvLCBudW1lcm8xLW51bWVybzIgKD49bnVtZXJvMSB5IDxudW1lcm8yKSwgPj1udW1lcm8yXHJcbiAgICAgKi9cclxuICAgIHRyYW5zZm9ybShpdGVtczogYW55W10sIGZpcnN0RmllbGQ6IHN0cmluZywgc2Vjb25kRmllbGQ6IHN0cmluZywgdmFsdWU6IHN0cmluZyk6IGFueVtdIHtcclxuICAgICAgICBpZiAoIWl0ZW1zKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBbXTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKCFmaXJzdEZpZWxkIHx8ICFzZWNvbmRGaWVsZCB8fCAhdmFsdWUpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGl0ZW1zO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAodmFsdWUudG9TdHJpbmcoKS5pbmNsdWRlcygnPCcpKSB7IC8vIENhc28gMTogZXMgbWVub3JcclxuICAgICAgICAgICAgY29uc3QgbnVtZXJvcyA9IHZhbHVlLnNwbGl0KCc8Jyk7XHJcbiAgICAgICAgICAgIGNvbnN0IG51bWVybzogbnVtYmVyID0gK251bWVyb3NbMV07XHJcbiAgICAgICAgICAgIHJldHVybiBpdGVtcy5maWx0ZXIoc2luZ2xlSXRlbSA9PiBzaW5nbGVJdGVtW2ZpcnN0RmllbGRdW3NlY29uZEZpZWxkXSA8IG51bWVybyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh2YWx1ZS50b1N0cmluZygpLmluY2x1ZGVzKCctJykpIHsgLy8gQ2FzbyAyOiBSYW5nb1xyXG4gICAgICAgICAgICBjb25zdCBudW1lcm9zID0gdmFsdWUuc3BsaXQoJy0nKTtcclxuICAgICAgICAgICAgY29uc3QgbnVtZXJvMTogbnVtYmVyID0gKyBudW1lcm9zWzBdO1xyXG4gICAgICAgICAgICBjb25zdCBudW1lcm8yOiBudW1iZXIgPSArIG51bWVyb3NbMV07XHJcbiAgICAgICAgICAgIHJldHVybiBpdGVtcy5maWx0ZXIoc2luZ2xlSXRlbSA9PiBzaW5nbGVJdGVtW2ZpcnN0RmllbGRdW3NlY29uZEZpZWxkXSA+PSBudW1lcm8xICYmXHJcbiAgICAgICAgICAgICAgICBzaW5nbGVJdGVtW2ZpcnN0RmllbGRdW3NlY29uZEZpZWxkXSA8IG51bWVybzIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAodmFsdWUudG9TdHJpbmcoKS5pbmNsdWRlcygnPicpKSB7IC8vIENhc28gMzogTWF5b3IgbyBJZ3VhbFxyXG4gICAgICAgICAgICBjb25zdCBudW1lcm9zID0gdmFsdWUuc3BsaXQoJz4nKTtcclxuICAgICAgICAgICAgY29uc3QgbnVtZXJvOiBudW1iZXIgPSArIG51bWVyb3NbMV07XHJcbiAgICAgICAgICAgIHJldHVybiBpdGVtcy5maWx0ZXIoc2luZ2xlSXRlbSA9PiBzaW5nbGVJdGVtW2ZpcnN0RmllbGRdW3NlY29uZEZpZWxkXSA+PSBudW1lcm8pO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBDYXNvIDQsIGl0ZW0gdmFjaW9cclxuICAgICAgICByZXR1cm4gaXRlbXM7XHJcbiAgICB9XHJcbn1cclxuXHJcbkBQaXBlKHtcclxuICAgIG5hbWU6ICdkYXRlRmlsdGVyJ1xyXG59KVxyXG5ASW5qZWN0YWJsZSgpXHJcbi8qKlxyXG4gKiBGaWx0cmFyYSBhcnJlZ2xvcyBtZWRpYW50ZSB1biBsb3MgdmFsb3JlcyBkZSB1biBjYW1wbyBkZSB0aXBvIGZlY2hhXHJcbiAqL1xyXG5leHBvcnQgY2xhc3MgRGF0ZVBpcGUgaW1wbGVtZW50cyBQaXBlVHJhbnNmb3JtIHtcclxuICAgIC8qKlxyXG4gICAgICogQGF1dGhvciBqY2FuZ2Vsb3NpXHJcbiAgICAgKiBGaWx0cmFyYSBlbCBhcnJlZ2xvIGl0ZW1zIHBvciB1bmEgZmVjaGEgcmVwcmVzZW50YWRhIHBvciB1biBzdHJpbmdcclxuICAgICAqL1xyXG4gICAgdHJhbnNmb3JtKGl0ZW1zOiBzdHJpbmdbXSwgZmllbGQ6IHN0cmluZywgdmFsdWU6IHN0cmluZyk6IGFueVtdIHtcclxuICAgICAgICBpZiAoIWl0ZW1zKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBbXTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKCFmaWVsZCB8fCAhdmFsdWUpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGl0ZW1zO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBjYXNvIGNvbnRyYXJpbyBsYSBmZWNoYSBlcyB2YWxpZGFcclxuICAgICAgICBjb25zdCB2YWxvcmVzOiBTdHJpbmdbXSA9IHZhbHVlLnNwbGl0KCctJyk7XHJcbiAgICAgICAgY29uc3QgZmVjaGE6IFN0cmluZyA9IHZhbG9yZXNbMl0gKyAnLycgKyB2YWxvcmVzWzFdICsgJy8nICsgdmFsb3Jlc1swXTtcclxuICAgICAgICByZXR1cm4gaXRlbXMuZmlsdGVyKHNpbmdsZUl0ZW0gPT4gc2luZ2xlSXRlbVtmaWVsZF0udG9Mb3dlckNhc2UoKS5pbmNsdWRlcyhmZWNoYSkpO1xyXG4gICAgfVxyXG59XHJcbi8qKlxyXG4gKiBQaXBlIHF1ZSBzZSB1dGlsaXphIHBhcmEgc2VwYXJhciBsb3Mgc3RyaW5nIGRlIGxvcyBub21icmVzIGRlIGxvcyBlbnVtZXJhYmxlcyBwb3IgcGFsYWJyYSwgZGUgbWFuZXJhIHF1ZSBxdWVkZW4gbWFzIGFncmFkYWJsZXNcclxuICogdmlzdWFsbWVudGUuXHJcbiAqL1xyXG5AUGlwZSh7IG5hbWU6ICdiZWF1dGlmeScgfSlcclxuZXhwb3J0IGNsYXNzIEJlYXV0aWZ5UGlwZSBpbXBsZW1lbnRzIFBpcGVUcmFuc2Zvcm0ge1xyXG4gICAgdHJhbnNmb3JtKHRleHQ6IHN0cmluZykge1xyXG4gICAgICAgIGlmICh0ZXh0KSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHBhbGFicmFzOiBzdHJpbmdbXSA9IHRleHQuc3BsaXQoLyg/PVtBLVpdKS8pO1xyXG4gICAgICAgICAgICBsZXQgcGFsYWJyYUFyZXRvcm5hciA9ICcnO1xyXG4gICAgICAgICAgICBmb3IgKGNvbnN0IHBhbGFicmEgb2YgcGFsYWJyYXMpIHtcclxuICAgICAgICAgICAgICAgIHBhbGFicmFBcmV0b3JuYXIgPSBwYWxhYnJhQXJldG9ybmFyLmNvbmNhdCgnICcsIHBhbGFicmEpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiBwYWxhYnJhQXJldG9ybmFyO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdGV4dDtcclxuICAgIH1cclxufVxyXG4iLCIvKipcclxuICogQGF1dGhvciBTZWJhc3RpYW4gTGFycmlldVxyXG4gKiBAZW1haWwgc2xhcnJpZXVAdGVhbS5uZW9jb21wbGV4eC5jb21cclxuICogQGNyZWF0ZSBkYXRlIDIwMTktMDItMDEgMTU6MTI6NThcclxuICovXHJcbmltcG9ydCB7IFBpcGUsIFBpcGVUcmFuc2Zvcm0sIEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuXHJcbi8qKlxyXG4gKiBGaWx0ZXIgb2JqZWN0IGFycmF5IGZyb20gcHJvcGVydHlcclxuICovXHJcbkBQaXBlKHtcclxuICAgIG5hbWU6ICdwYWRMZWZ0J1xyXG59KVxyXG5ASW5qZWN0YWJsZSgpXHJcbmV4cG9ydCBjbGFzcyBQYWRMZWZ0UGlwZSBpbXBsZW1lbnRzIFBpcGVUcmFuc2Zvcm0ge1xyXG5cclxuICAgIHRyYW5zZm9ybSh2YWx1ZTogbnVtYmVyIHwgc3RyaW5nLCBzaXplOiBudW1iZXIsIHBhZDogc3RyaW5nKSB7XHJcbiAgICAgICAgbGV0IHMgPSBTdHJpbmcodmFsdWUpO1xyXG4gICAgICAgIHdoaWxlIChzLmxlbmd0aCA8IChzaXplIHx8IDIpKSB7IHMgPSBwYWQgKyBzOyB9XHJcbiAgICAgICAgcmV0dXJuIHM7XHJcbiAgICB9XHJcbn1cclxuIiwiLyoqXHJcbiAqIEBhdXRob3IgU2ViYXN0aWFuIExhcnJpZXVcclxuICogQGVtYWlsIHNsYXJyaWV1QHRlYW0ubmVvY29tcGxleHguY29tXHJcbiAqIEBjcmVhdGUgZGF0ZSAyMDE5LTAyLTAxIDE1OjEyOjU4XHJcbiAqL1xyXG5pbXBvcnQgeyBQaXBlLCBQaXBlVHJhbnNmb3JtLCBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcblxyXG4vKipcclxuICogRmlsdGVyIG9iamVjdCBhcnJheSBmcm9tIHByb3BlcnR5XHJcbiAqL1xyXG5AUGlwZSh7XHJcbiAgICBuYW1lOiAnc2FmZVN0cmluZydcclxufSlcclxuQEluamVjdGFibGUoKVxyXG5leHBvcnQgY2xhc3MgU2FmZVN0cmluZ1BpcGUgaW1wbGVtZW50cyBQaXBlVHJhbnNmb3JtIHtcclxuXHJcbiAgICB0cmFuc2Zvcm0odmFsdWU6IGFueSkge1xyXG4gICAgICAgIGlmICh2YWx1ZSkge1xyXG4gICAgICAgICAgICByZXR1cm4gdmFsdWU7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgcmV0dXJuICctJztcclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cclxuIiwiaW1wb3J0IHsgUGlwZVRyYW5zZm9ybSwgUGlwZSB9IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XHJcblxyXG4vKipcclxuICogUGlwZSBxdWUgc2UgdXRpbGl6YSBwYXJhIHNlcGFyYXIgbG9zIHN0cmluZyBkZSBsb3Mgbm9tYnJlcyBkZSBsb3MgZW51bWVyYWJsZXMgcG9yIHBhbGFicmEsIGRlIG1hbmVyYSBxdWUgcXVlZGVuIG1hcyBhZ3JhZGFibGVzXHJcbiAqIHZpc3VhbG1lbnRlLlxyXG4gKiBTZSBsZSBwYXNhIHBvciBwYXLDg8KhbWV0cm8gZWwgc3RyaW5nIHNlcGFyYWRvciwgZWwgY3VhbCBubyBzZSB2aXN1YWxpemFyw4PCoSBlbiBwYW50YWxsYS5cclxuICovXHJcbkBQaXBlKHsgbmFtZTogJ3NwbGl0QmVhdXR5JyB9KVxyXG5leHBvcnQgY2xhc3MgU3BsaXRCZWF1dHlQaXBlIGltcGxlbWVudHMgUGlwZVRyYW5zZm9ybSB7XHJcbiAgICBcclxuICAgIHRyYW5zZm9ybSh0ZXh0OiBzdHJpbmcsIGFyZ3M6IHN0cmluZyk6IHN0cmluZyB7XHJcbiAgICAgICAgaWYgKHRleHQgJiYgYXJncykge1xyXG4gICAgICAgICAgICBjb25zdCBwYWxhYnJhczogc3RyaW5nW10gPSB0ZXh0LnNwbGl0KGFyZ3MpO1xyXG4gICAgICAgICAgICBsZXQgcGFsYWJyYUFyZXRvcm5hciA9ICcnO1xyXG4gICAgICAgICAgICBmb3IgKGNvbnN0IHBhbGFicmEgb2YgcGFsYWJyYXMpIHtcclxuICAgICAgICAgICAgICAgIHBhbGFicmFBcmV0b3JuYXIgPSBwYWxhYnJhQXJldG9ybmFyLmNvbmNhdCgnICcsIHBhbGFicmEpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiBwYWxhYnJhQXJldG9ybmFyO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdGV4dDtcclxuICAgIH1cclxufVxyXG4iLCIvKipcclxuICogQGF1dGhvciBTZWJhc3RpYW4gTGFycmlldVxyXG4gKiBAZW1haWwgc2xhcnJpZXVAdGVhbS5uZW9jb21wbGV4eC5jb21cclxuICogQGNyZWF0ZSBkYXRlIDIwMjAtMDEtMTcgMTY6MzE6MzJcclxuICovXHJcbmltcG9ydCB7IFBpcGUsIFBpcGVUcmFuc2Zvcm0sIEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuXHJcbi8qKlxyXG4gKiBGaWx0ZXIgb2JqZWN0IGFycmF5IGZyb20gcHJvcGVydHlcclxuICovXHJcbkBQaXBlKHtcclxuICAgIG5hbWU6ICd1bmlzZXgnXHJcbn0pXHJcbkBJbmplY3RhYmxlKClcclxuZXhwb3J0IGNsYXNzIFVuaXNleFBpcGUgaW1wbGVtZW50cyBQaXBlVHJhbnNmb3JtIHtcclxuXHJcbiAgICB0cmFuc2Zvcm0odmFsdWU6IHN0cmluZywgbGFzdDogc3RyaW5nID0gJ3gnKSB7XHJcbiAgICAgICAgaWYgKHZhbHVlKSB7XHJcbiAgICAgICAgICAgIGlmICh2YWx1ZS5zbGljZSgtMSkgPT09IGxhc3QpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBgJHt2YWx1ZS5zbGljZSgwLCAtMSl9by9hYDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm4gdmFsdWU7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbmRlZmluZWQgdmFsdWUgaW4gdW5pc2V4IHBpcGUnKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cclxuIiwiLyogZGF0ZSAyMDIwLTAzLTEzIDEwOjQwOjMwXHJcbiAqIEBhdXRob3IgU2ViYXN0aWFuIExhcnJpZXVcclxuICogQGVtYWlsIHNsYXJyaWV1QHRlYW0ubmVvY29tcGxleHguY29tXHJcbiAqIEBjcmVhdGUgZGF0ZSAyMDIwLTAxLTE3IDE2OjMxOjMyXHJcbiAqL1xyXG5pbXBvcnQgeyBQaXBlLCBQaXBlVHJhbnNmb3JtLCBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcblxyXG4vKipcclxuICogRmlsdGVyIG9iamVjdCBhcnJheSBmcm9tIHByb3BlcnR5XHJcbiAqL1xyXG5AUGlwZSh7XHJcbiAgICBuYW1lOiAnYWNjZW50J1xyXG59KVxyXG5ASW5qZWN0YWJsZSgpXHJcbmV4cG9ydCBjbGFzcyBBY2NlbnRQaXBlIGltcGxlbWVudHMgUGlwZVRyYW5zZm9ybSB7XHJcblxyXG4gICAgdHJhbnNmb3JtKHZhbHVlOiBzdHJpbmcsIHJlcGxhY2U6IGJvb2xlYW4pIHtcclxuICAgICAgICBpZiAodmFsdWUpIHtcclxuICAgICAgICAgICAgaWYgKHJlcGxhY2UpIHtcclxuICAgICAgICAgICAgICAgIGxldCB2YWwgPSB2YWx1ZTtcclxuICAgICAgICAgICAgICAgIHZhbCA9IHZhbC5yZXBsYWNlKC8xYS9nLCAnw4PCoScpO1xyXG4gICAgICAgICAgICAgICAgdmFsID0gdmFsLnJlcGxhY2UoLzFlL2csICfDg8KpJyk7XHJcbiAgICAgICAgICAgICAgICB2YWwgPSB2YWwucmVwbGFjZSgvMWkvZywgJ8ODwq0nKTtcclxuICAgICAgICAgICAgICAgIHZhbCA9IHZhbC5yZXBsYWNlKC8xby9nLCAnw4PCsycpO1xyXG4gICAgICAgICAgICAgICAgdmFsID0gdmFsLnJlcGxhY2UoLzF1L2csICfDg8K6Jyk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdmFsO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlLnJlcGxhY2UoLzEvZywgJycpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59XHJcbiIsImltcG9ydCB7IE5nTW9kdWxlLCBNb2R1bGVXaXRoUHJvdmlkZXJzIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7XHJcbiAgTnVtYmVyUGlwZSwgVGV4dFBpcGUsIFRleHRQaXBlVHdvTGV2ZWwsIE51bWJlclBpcGVUd29MZXZlbCxcclxuICBCZWF1dGlmeVBpcGUsIERhdGVQaXBlLCBSYW5nZVBpcGUsIFJhbmdlUGlwZVR3b0xldmVsLCBUb1N0cmluZ1BpcGUsIEZ1bmNGaWx0ZXJQaXBlXHJcbn0gZnJvbSAnLi9maWx0ZXJzLnBpcGUnO1xyXG5pbXBvcnQgeyBQYWRMZWZ0UGlwZSB9IGZyb20gJy4vbnVtYmVyLnBpcGUnO1xyXG5pbXBvcnQgeyBTYWZlU3RyaW5nUGlwZSB9IGZyb20gJy4vc2FmZS1zdHJpbmcucGlwZSc7XHJcbmltcG9ydCB7IFNwbGl0QmVhdXR5UGlwZSB9IGZyb20gJy4vc3BsaXRCZWF1dHkucGlwZSc7XHJcbmltcG9ydCB7IFVuaXNleFBpcGUgfSBmcm9tICcuL3VuaXNleC5waXBlJztcclxuaW1wb3J0IHsgQWNjZW50UGlwZSB9IGZyb20gJy4vYWNjZW50LnBpcGUnO1xyXG5cclxuQE5nTW9kdWxlKHtcclxuICBkZWNsYXJhdGlvbnM6IFtOdW1iZXJQaXBlLCBUZXh0UGlwZSwgVGV4dFBpcGVUd29MZXZlbCwgTnVtYmVyUGlwZVR3b0xldmVsLCBUb1N0cmluZ1BpcGUsIEZ1bmNGaWx0ZXJQaXBlLFxyXG4gICAgQmVhdXRpZnlQaXBlLCBEYXRlUGlwZSwgUmFuZ2VQaXBlLCBSYW5nZVBpcGVUd29MZXZlbCwgUGFkTGVmdFBpcGUsIFNhZmVTdHJpbmdQaXBlLCBTcGxpdEJlYXV0eVBpcGUsIFVuaXNleFBpcGUsIEFjY2VudFBpcGVdLFxyXG4gIGV4cG9ydHM6IFtOdW1iZXJQaXBlLCBUZXh0UGlwZSwgVGV4dFBpcGVUd29MZXZlbCwgTnVtYmVyUGlwZVR3b0xldmVsLCBUb1N0cmluZ1BpcGUsIEZ1bmNGaWx0ZXJQaXBlLFxyXG4gICAgQmVhdXRpZnlQaXBlLCBEYXRlUGlwZSwgUmFuZ2VQaXBlLCBSYW5nZVBpcGVUd29MZXZlbCwgUGFkTGVmdFBpcGUsIFNhZmVTdHJpbmdQaXBlLCBTcGxpdEJlYXV0eVBpcGUsIFVuaXNleFBpcGUsIEFjY2VudFBpcGVdLFxyXG59KVxyXG5leHBvcnQgY2xhc3MgTmd4TmVvUGlwZXNNb2R1bGUge1xyXG4gIHN0YXRpYyBmb3JSb290KCk6IE1vZHVsZVdpdGhQcm92aWRlcnMge1xyXG4gICAgcmV0dXJuIHtcclxuICAgICAgbmdNb2R1bGU6IE5neE5lb1BpcGVzTW9kdWxlLFxyXG4gICAgfTtcclxuICB9XHJcbn1cclxuIl0sIm5hbWVzIjpbIlBpcGUiLCJJbmplY3RhYmxlIiwidHNsaWJfMS5fX3ZhbHVlcyIsIk5nTW9kdWxlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7SUFBQTs7Ozs7Ozs7Ozs7Ozs7QUFjQSxhQTRGZ0IsUUFBUSxDQUFDLENBQUM7UUFDdEIsSUFBSSxDQUFDLEdBQUcsT0FBTyxNQUFNLEtBQUssVUFBVSxJQUFJLENBQUMsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNsRSxJQUFJLENBQUM7WUFBRSxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDeEIsT0FBTztZQUNILElBQUksRUFBRTtnQkFDRixJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLE1BQU07b0JBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDO2dCQUNuQyxPQUFPLEVBQUUsS0FBSyxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQzthQUMzQztTQUNKLENBQUM7SUFDTixDQUFDOzs7Ozs7Ozs7QUM5R0Q7UUFBQTtTQWFDOzs7Ozs7UUFSRyxrQ0FBUzs7Ozs7WUFBVCxVQUFVLEtBQVksRUFBRSxRQUFpQztnQkFFckQsSUFBSSxDQUFDLEtBQUssSUFBSSxDQUFDLFFBQVEsRUFBRTtvQkFDckIsT0FBTyxFQUFFLENBQUM7aUJBQ2I7Z0JBRUQsT0FBTyxLQUFLLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO2FBQ2pDOztvQkFaSkEsU0FBSSxTQUFDO3dCQUNGLElBQUksRUFBRSxnQkFBZ0I7cUJBQ3pCO29CQUNBQyxlQUFVOztRQVVYLHFCQUFDO0tBYkQsSUFhQzs7OztBQUtEO1FBQUE7U0FvQkM7Ozs7Ozs7Ozs7Ozs7Ozs7O1FBVEcsNEJBQVM7Ozs7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