angular2-csv
Version:
> Helper library for create CSV file in Angular 6
471 lines (459 loc) • 48.8 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('@angular/common')) :
typeof define === 'function' && define.amd ? define('angular2-csv', ['exports', '@angular/core', '@angular/common'], factory) :
(factory((global['angular2-csv'] = {}),global.ng.core,global.ng.common));
}(this, (function (exports,i0,common) { 'use strict';
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
var Angular2CsvService = (function () {
function Angular2CsvService() {
}
Angular2CsvService.decorators = [
{ type: i0.Injectable, args: [{
providedIn: 'root'
},] },
];
/** @nocollapse */
Angular2CsvService.ctorParameters = function () { return []; };
/** @nocollapse */ Angular2CsvService.ngInjectableDef = i0.defineInjectable({ factory: function Angular2CsvService_Factory() { return new Angular2CsvService(); }, token: Angular2CsvService, providedIn: "root" });
return Angular2CsvService;
}());
/*! *****************************************************************************
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} checked by tsc
*/
var Angular2CsvComponent = (function () {
function Angular2CsvComponent() {
this.filename = this.filename || 'mycsv.csv';
this.options = this.objectAssign({}, ConfigDefaults, this.options);
this.label_btn = "download";
this.csv = '';
}
/**
* Event Download
*/
/**
* Event Download
* @return {?}
*/
Angular2CsvComponent.prototype.onDownload = /**
* Event Download
* @return {?}
*/
function () {
this.generateCsv();
};
/**
* ngOnInit
*/
/**
* ngOnInit
* @return {?}
*/
Angular2CsvComponent.prototype.ngOnInit = /**
* ngOnInit
* @return {?}
*/
function () { };
/**
* [generateCsv description]
*/
/**
* [generateCsv description]
* @return {?}
*/
Angular2CsvComponent.prototype.generateCsv = /**
* [generateCsv description]
* @return {?}
*/
function () {
if (this.options.useBom) {
this.csv += CsvConfigConsts.BOM;
}
if (this.options.showTitle) {
this.csv += this.options.title + '\r\n\n';
}
this.getHeaders();
this.getBody();
if (this.csv === '') {
console.log('Invalid data');
return;
}
var /** @type {?} */ blob = new Blob([this.csv], { type: 'text/csv;charset=utf8;' });
if (navigator.msSaveBlob) {
var /** @type {?} */ filename = this.options.filename.replace(/ /g, '_') + '.csv';
navigator.msSaveBlob(blob, filename);
}
else {
var /** @type {?} */ uri = 'data:attachment/csv;charset=utf-8,' + encodeURI(this.csv);
var /** @type {?} */ link = document.createElement('a');
link.href = URL.createObjectURL(blob);
link.setAttribute('visibility', 'hidden');
link.download = this.filename.replace(/ /g, '_') + '.csv';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
this.csv = '';
};
/**
* Create Headers for Csv File
*/
/**
* Create Headers for Csv File
* @return {?}
*/
Angular2CsvComponent.prototype.getHeaders = /**
* Create Headers for Csv File
* @return {?}
*/
function () {
if (this.options.headers.length > 0) {
var /** @type {?} */ row = '';
try {
for (var _a = __values(this.options.headers), _b = _a.next(); !_b.done; _b = _a.next()) {
var column = _b.value;
row += column + this.options.fieldSeparator;
}
}
catch (e_1_1) {
e_1 = { error: e_1_1 };
}
finally {
try {
if (_b && !_b.done && (_c = _a.return))
_c.call(_a);
}
finally {
if (e_1)
throw e_1.error;
}
}
row = row.slice(0, -1);
this.csv += row + CsvConfigConsts.EOL;
}
var e_1, _c;
};
/**
* Create Headers
*/
/**
* Create Headers
* @return {?}
*/
Angular2CsvComponent.prototype.getBody = /**
* Create Headers
* @return {?}
*/
function () {
try {
for (var _a = __values(this.data), _b = _a.next(); !_b.done; _b = _a.next()) {
var dataRow = _b.value;
var /** @type {?} */ row = '';
if (this.isEmptyObject(dataRow) && this.options.removeNewLines) {
continue;
}
if (typeof this.options.keys !== 'undefined' && this.options.keys.length) {
try {
for (var _c = __values(this.options.keys), _d = _c.next(); !_d.done; _d = _c.next()) {
var key = _d.value;
row += this.formartData(dataRow[key]) + this.options.fieldSeparator;
}
}
catch (e_2_1) {
e_2 = { error: e_2_1 };
}
finally {
try {
if (_d && !_d.done && (_e = _c.return))
_e.call(_c);
}
finally {
if (e_2)
throw e_2.error;
}
}
row = row.slice(0, -1);
this.csv += row + CsvConfigConsts.EOL;
}
else {
for (var /** @type {?} */ key in dataRow) {
if (dataRow[key]) {
row += this.formartData(dataRow[key]) + this.options.fieldSeparator;
}
}
this.csv += row + CsvConfigConsts.EOL;
}
}
}
catch (e_3_1) {
e_3 = { error: e_3_1 };
}
finally {
try {
if (_b && !_b.done && (_f = _a.return))
_f.call(_a);
}
finally {
if (e_3)
throw e_3.error;
}
}
var e_3, _f, e_2, _e;
};
/**
* Format Data
*/
/**
* Format Data
* @param {?} data
* @return {?}
*/
Angular2CsvComponent.prototype.formartData = /**
* Format Data
* @param {?} data
* @return {?}
*/
function (data) {
if (this.options.decimalseparator === 'locale' && this.isFloat(data)) {
return data.toLocaleString();
}
if (this.options.decimalseparator !== '.' && this.isFloat(data)) {
return data.toString().replace('.', this.options.decimalseparator);
}
if (typeof data === 'string') {
data = data.replace(/"/g, '""');
if (this.options.quoteStrings || data.indexOf(',') > -1 || data.indexOf("\n") > -1 || data.indexOf("\r") > -1) {
data = this.options.quoteStrings + data + this.options.quoteStrings;
}
return data;
}
if (typeof data === 'boolean') {
return data ? 'TRUE' : 'FALSE';
}
return data;
};
/**
* Validate if object is not empty
*/
/**
* Validate if object is not empty
* @param {?} obj
* @return {?}
*/
Angular2CsvComponent.prototype.isEmptyObject = /**
* Validate if object is not empty
* @param {?} obj
* @return {?}
*/
function (obj) {
return (obj && (Object.keys(obj).length === 0));
};
/**
* Get Input is Float
*/
/**
* Get Input is Float
* @param {?} input
* @return {?}
*/
Angular2CsvComponent.prototype.isFloat = /**
* Get Input is Float
* @param {?} input
* @return {?}
*/
function (input) {
return +input === input && (!isFinite(input) || Boolean(input % 1));
};
/**
* Add object Values
*/
/**
* Add object Values
* @param {?} val
* @return {?}
*/
Angular2CsvComponent.prototype.toObject = /**
* Add object Values
* @param {?} val
* @return {?}
*/
function (val) {
if (val === null || val === undefined) {
throw new TypeError('Object.assign cannot be called with null or undefined');
}
return Object(val);
};
/**
* Add Values to Object
*/
/**
* Add Values to Object
* @param {?} target
* @param {...?} source
* @return {?}
*/
Angular2CsvComponent.prototype.objectAssign = /**
* Add Values to Object
* @param {?} target
* @param {...?} source
* @return {?}
*/
function (target) {
var source = [];
for (var _i = 1; _i < arguments.length; _i++) {
source[_i - 1] = arguments[_i];
}
var /** @type {?} */ from;
var /** @type {?} */ to = this.toObject(target);
var /** @type {?} */ symbols;
var /** @type {?} */ hasOwnProperty = Object.prototype.hasOwnProperty;
var /** @type {?} */ propIsEnumerable = Object.prototype.propertyIsEnumerable;
for (var /** @type {?} */ s = 1; s < arguments.length; s++) {
from = Object(arguments[s]);
for (var /** @type {?} */ key in from) {
if (hasOwnProperty.call(from, key)) {
to[key] = from[key];
}
}
if (((Object)).getOwnPropertySymbols) {
symbols = ((Object)).getOwnPropertySymbols(from);
try {
for (var symbols_1 = __values(symbols), symbols_1_1 = symbols_1.next(); !symbols_1_1.done; symbols_1_1 = symbols_1.next()) {
var symbol = symbols_1_1.value;
if (propIsEnumerable.call(from, symbol)) {
to[symbol] = from[symbol];
}
}
}
catch (e_4_1) {
e_4 = { error: e_4_1 };
}
finally {
try {
if (symbols_1_1 && !symbols_1_1.done && (_a = symbols_1.return))
_a.call(symbols_1);
}
finally {
if (e_4)
throw e_4.error;
}
}
}
}
return to;
var e_4, _a;
};
Angular2CsvComponent.decorators = [
{ type: i0.Component, args: [{
selector: 'angular2csv',
template: "<button (click)=\"onDownload()\">{{ label_btn }}</button>",
styles: []
},] },
];
/** @nocollapse */
Angular2CsvComponent.ctorParameters = function () { return []; };
Angular2CsvComponent.propDecorators = {
data: [{ type: i0.Input }],
filename: [{ type: i0.Input }],
options: [{ type: i0.Input }]
};
return Angular2CsvComponent;
}());
/**
* CsvConfigConsts
*/
var CsvConfigConsts = (function () {
function CsvConfigConsts() {
}
CsvConfigConsts.EOL = '\r\n';
CsvConfigConsts.BOM = '\ufeff';
CsvConfigConsts.DEFAULT_FIELD_SEPARATOR = ',';
CsvConfigConsts.DEFAULT_DECIMAL_SEPARATOR = '.';
CsvConfigConsts.DEFAULT_QUOTE = '"';
CsvConfigConsts.DEFAULT_SHOW_TITLE = false;
CsvConfigConsts.DEFAULT_TITLE = 'My Report';
CsvConfigConsts.DEFAULT_FILENAME = 'mycsv.csv';
CsvConfigConsts.DEFAULT_SHOW_LABELS = false;
CsvConfigConsts.DEFAULT_USE_BOM = true;
CsvConfigConsts.DEFAULT_HEADER = [];
CsvConfigConsts.DEFAULT_KEY = [];
CsvConfigConsts.DEFAULT_REMOVE_NEW_LINES = false;
return CsvConfigConsts;
}());
/**
* Default Configurations
*/
var /** @type {?} */ ConfigDefaults = {
filename: CsvConfigConsts.DEFAULT_FILENAME,
fieldSeparator: CsvConfigConsts.DEFAULT_FIELD_SEPARATOR,
quoteStrings: CsvConfigConsts.DEFAULT_QUOTE,
decimalseparator: CsvConfigConsts.DEFAULT_DECIMAL_SEPARATOR,
showLabels: CsvConfigConsts.DEFAULT_SHOW_LABELS,
showTitle: CsvConfigConsts.DEFAULT_SHOW_TITLE,
title: CsvConfigConsts.DEFAULT_TITLE,
useBom: CsvConfigConsts.DEFAULT_USE_BOM,
headers: CsvConfigConsts.DEFAULT_HEADER,
keys: CsvConfigConsts.DEFAULT_KEY,
removeNewLines: CsvConfigConsts.DEFAULT_REMOVE_NEW_LINES
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
var Angular2CsvModule = (function () {
function Angular2CsvModule() {
}
Angular2CsvModule.decorators = [
{ type: i0.NgModule, args: [{
imports: [
common.CommonModule
],
declarations: [Angular2CsvComponent],
exports: [Angular2CsvComponent]
},] },
];
return Angular2CsvModule;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
exports.Angular2CsvService = Angular2CsvService;
exports.Angular2CsvComponent = Angular2CsvComponent;
exports.CsvConfigConsts = CsvConfigConsts;
exports.ConfigDefaults = ConfigDefaults;
exports.Angular2CsvModule = Angular2CsvModule;
Object.defineProperty(exports, '__esModule', { value: true });
})));
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYW5ndWxhcjItY3N2LnVtZC5qcy5tYXAiLCJzb3VyY2VzIjpbIm5nOi8vYW5ndWxhcjItY3N2L2xpYi9hbmd1bGFyMi1jc3Yuc2VydmljZS50cyIsbnVsbCwibmc6Ly9hbmd1bGFyMi1jc3YvbGliL2FuZ3VsYXIyLWNzdi5jb21wb25lbnQudHMiLCJuZzovL2FuZ3VsYXIyLWNzdi9saWIvYW5ndWxhcjItY3N2Lm1vZHVsZS50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbkBJbmplY3RhYmxlKHtcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnXG59KVxuZXhwb3J0IGNsYXNzIEFuZ3VsYXIyQ3N2U2VydmljZSB7XG5cbiAgY29uc3RydWN0b3IoKSB7IH1cbn1cbiIsIi8qISAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxyXG5Db3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTsgeW91IG1heSBub3QgdXNlXHJcbnRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlXHJcbkxpY2Vuc2UgYXQgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXHJcblxyXG5USElTIENPREUgSVMgUFJPVklERUQgT04gQU4gKkFTIElTKiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZXHJcbktJTkQsIEVJVEhFUiBFWFBSRVNTIE9SIElNUExJRUQsIElOQ0xVRElORyBXSVRIT1VUIExJTUlUQVRJT04gQU5ZIElNUExJRURcclxuV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIFRJVExFLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSxcclxuTUVSQ0hBTlRBQkxJVFkgT1IgTk9OLUlORlJJTkdFTUVOVC5cclxuXHJcblNlZSB0aGUgQXBhY2hlIFZlcnNpb24gMi4wIExpY2Vuc2UgZm9yIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9uc1xyXG5hbmQgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXHJcbioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqICovXHJcbi8qIGdsb2JhbCBSZWZsZWN0LCBQcm9taXNlICovXHJcblxyXG52YXIgZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uKGQsIGIpIHtcclxuICAgIGV4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHxcclxuICAgICAgICAoeyBfX3Byb3RvX186IFtdIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikgeyBkLl9fcHJvdG9fXyA9IGI7IH0pIHx8XHJcbiAgICAgICAgZnVuY3Rpb24gKGQsIGIpIHsgZm9yICh2YXIgcCBpbiBiKSBpZiAoYi5oYXNPd25Qcm9wZXJ0eShwKSkgZFtwXSA9IGJbcF07IH07XHJcbiAgICByZXR1cm4gZXh0ZW5kU3RhdGljcyhkLCBiKTtcclxufTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2V4dGVuZHMoZCwgYikge1xyXG4gICAgZXh0ZW5kU3RhdGljcyhkLCBiKTtcclxuICAgIGZ1bmN0aW9uIF9fKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gZDsgfVxyXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xyXG59XHJcblxyXG5leHBvcnQgdmFyIF9fYXNzaWduID0gZnVuY3Rpb24oKSB7XHJcbiAgICBfX2Fzc2lnbiA9IE9iamVjdC5hc3NpZ24gfHwgZnVuY3Rpb24gX19hc3NpZ24odCkge1xyXG4gICAgICAgIGZvciAodmFyIHMsIGkgPSAxLCBuID0gYXJndW1lbnRzLmxlbmd0aDsgaSA8IG47IGkrKykge1xyXG4gICAgICAgICAgICBzID0gYXJndW1lbnRzW2ldO1xyXG4gICAgICAgICAgICBmb3IgKHZhciBwIGluIHMpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocywgcCkpIHRbcF0gPSBzW3BdO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdDtcclxuICAgIH1cclxuICAgIHJldHVybiBfX2Fzc2lnbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19yZXN0KHMsIGUpIHtcclxuICAgIHZhciB0ID0ge307XHJcbiAgICBmb3IgKHZhciBwIGluIHMpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocywgcCkgJiYgZS5pbmRleE9mKHApIDwgMClcclxuICAgICAgICB0W3BdID0gc1twXTtcclxuICAgIGlmIChzICE9IG51bGwgJiYgdHlwZW9mIE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMgPT09IFwiZnVuY3Rpb25cIilcclxuICAgICAgICBmb3IgKHZhciBpID0gMCwgcCA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMocyk7IGkgPCBwLmxlbmd0aDsgaSsrKSBpZiAoZS5pbmRleE9mKHBbaV0pIDwgMClcclxuICAgICAgICAgICAgdFtwW2ldXSA9IHNbcFtpXV07XHJcbiAgICByZXR1cm4gdDtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZGVjb3JhdGUoZGVjb3JhdG9ycywgdGFyZ2V0LCBrZXksIGRlc2MpIHtcclxuICAgIHZhciBjID0gYXJndW1lbnRzLmxlbmd0aCwgciA9IGMgPCAzID8gdGFyZ2V0IDogZGVzYyA9PT0gbnVsbCA/IGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHRhcmdldCwga2V5KSA6IGRlc2MsIGQ7XHJcbiAgICBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIFJlZmxlY3QuZGVjb3JhdGUgPT09IFwiZnVuY3Rpb25cIikgciA9IFJlZmxlY3QuZGVjb3JhdGUoZGVjb3JhdG9ycywgdGFyZ2V0LCBrZXksIGRlc2MpO1xyXG4gICAgZWxzZSBmb3IgKHZhciBpID0gZGVjb3JhdG9ycy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkgaWYgKGQgPSBkZWNvcmF0b3JzW2ldKSByID0gKGMgPCAzID8gZChyKSA6IGMgPiAzID8gZCh0YXJnZXQsIGtleSwgcikgOiBkKHRhcmdldCwga2V5KSkgfHwgcjtcclxuICAgIHJldHVybiBjID4gMyAmJiByICYmIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGtleSwgciksIHI7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3BhcmFtKHBhcmFtSW5kZXgsIGRlY29yYXRvcikge1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uICh0YXJnZXQsIGtleSkgeyBkZWNvcmF0b3IodGFyZ2V0LCBrZXksIHBhcmFtSW5kZXgpOyB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX21ldGFkYXRhKG1ldGFkYXRhS2V5LCBtZXRhZGF0YVZhbHVlKSB7XHJcbiAgICBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIFJlZmxlY3QubWV0YWRhdGEgPT09IFwiZnVuY3Rpb25cIikgcmV0dXJuIFJlZmxlY3QubWV0YWRhdGEobWV0YWRhdGFLZXksIG1ldGFkYXRhVmFsdWUpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hd2FpdGVyKHRoaXNBcmcsIF9hcmd1bWVudHMsIFAsIGdlbmVyYXRvcikge1xyXG4gICAgcmV0dXJuIG5ldyAoUCB8fCAoUCA9IFByb21pc2UpKShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XHJcbiAgICAgICAgZnVuY3Rpb24gZnVsZmlsbGVkKHZhbHVlKSB7IHRyeSB7IHN0ZXAoZ2VuZXJhdG9yLm5leHQodmFsdWUpKTsgfSBjYXRjaCAoZSkgeyByZWplY3QoZSk7IH0gfVxyXG4gICAgICAgIGZ1bmN0aW9uIHJlamVjdGVkKHZhbHVlKSB7IHRyeSB7IHN0ZXAoZ2VuZXJhdG9yW1widGhyb3dcIl0odmFsdWUpKTsgfSBjYXRjaCAoZSkgeyByZWplY3QoZSk7IH0gfVxyXG4gICAgICAgIGZ1bmN0aW9uIHN0ZXAocmVzdWx0KSB7IHJlc3VsdC5kb25lID8gcmVzb2x2ZShyZXN1bHQudmFsdWUpIDogbmV3IFAoZnVuY3Rpb24gKHJlc29sdmUpIHsgcmVzb2x2ZShyZXN1bHQudmFsdWUpOyB9KS50aGVuKGZ1bGZpbGxlZCwgcmVqZWN0ZWQpOyB9XHJcbiAgICAgICAgc3RlcCgoZ2VuZXJhdG9yID0gZ2VuZXJhdG9yLmFwcGx5KHRoaXNBcmcsIF9hcmd1bWVudHMgfHwgW10pKS5uZXh0KCkpO1xyXG4gICAgfSk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2dlbmVyYXRvcih0aGlzQXJnLCBib2R5KSB7XHJcbiAgICB2YXIgXyA9IHsgbGFiZWw6IDAsIHNlbnQ6IGZ1bmN0aW9uKCkgeyBpZiAodFswXSAmIDEpIHRocm93IHRbMV07IHJldHVybiB0WzFdOyB9LCB0cnlzOiBbXSwgb3BzOiBbXSB9LCBmLCB5LCB0LCBnO1xyXG4gICAgcmV0dXJuIGcgPSB7IG5leHQ6IHZlcmIoMCksIFwidGhyb3dcIjogdmVyYigxKSwgXCJyZXR1cm5cIjogdmVyYigyKSB9LCB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgKGdbU3ltYm9sLml0ZXJhdG9yXSA9IGZ1bmN0aW9uKCkgeyByZXR1cm4gdGhpczsgfSksIGc7XHJcbiAgICBmdW5jdGlvbiB2ZXJiKG4pIHsgcmV0dXJuIGZ1bmN0aW9uICh2KSB7IHJldHVybiBzdGVwKFtuLCB2XSk7IH07IH1cclxuICAgIGZ1bmN0aW9uIHN0ZXAob3ApIHtcclxuICAgICAgICBpZiAoZikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkdlbmVyYXRvciBpcyBhbHJlYWR5IGV4ZWN1dGluZy5cIik7XHJcbiAgICAgICAgd2hpbGUgKF8pIHRyeSB7XHJcbiAgICAgICAgICAgIGlmIChmID0gMSwgeSAmJiAodCA9IG9wWzBdICYgMiA/IHlbXCJyZXR1cm5cIl0gOiBvcFswXSA/IHlbXCJ0aHJvd1wiXSB8fCAoKHQgPSB5W1wicmV0dXJuXCJdKSAmJiB0LmNhbGwoeSksIDApIDogeS5uZXh0KSAmJiAhKHQgPSB0LmNhbGwoeSwgb3BbMV0pKS5kb25lKSByZXR1cm4gdDtcclxuICAgICAgICAgICAgaWYgKHkgPSAwLCB0KSBvcCA9IFtvcFswXSAmIDIsIHQudmFsdWVdO1xyXG4gICAgICAgICAgICBzd2l0Y2ggKG9wWzBdKSB7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDA6IGNhc2UgMTogdCA9IG9wOyBicmVhaztcclxuICAgICAgICAgICAgICAgIGNhc2UgNDogXy5sYWJlbCsrOyByZXR1cm4geyB2YWx1ZTogb3BbMV0sIGRvbmU6IGZhbHNlIH07XHJcbiAgICAgICAgICAgICAgICBjYXNlIDU6IF8ubGFiZWwrKzsgeSA9IG9wWzFdOyBvcCA9IFswXTsgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDc6IG9wID0gXy5vcHMucG9wKCk7IF8udHJ5cy5wb3AoKTsgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgICAgICAgICAgIGlmICghKHQgPSBfLnRyeXMsIHQgPSB0Lmxlbmd0aCA+IDAgJiYgdFt0Lmxlbmd0aCAtIDFdKSAmJiAob3BbMF0gPT09IDYgfHwgb3BbMF0gPT09IDIpKSB7IF8gPSAwOyBjb250aW51ZTsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChvcFswXSA9PT0gMyAmJiAoIXQgfHwgKG9wWzFdID4gdFswXSAmJiBvcFsxXSA8IHRbM10pKSkgeyBfLmxhYmVsID0gb3BbMV07IGJyZWFrOyB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wWzBdID09PSA2ICYmIF8ubGFiZWwgPCB0WzFdKSB7IF8ubGFiZWwgPSB0WzFdOyB0ID0gb3A7IGJyZWFrOyB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHQgJiYgXy5sYWJlbCA8IHRbMl0pIHsgXy5sYWJlbCA9IHRbMl07IF8ub3BzLnB1c2gob3ApOyBicmVhazsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0WzJdKSBfLm9wcy5wb3AoKTtcclxuICAgICAgICAgICAgICAgICAgICBfLnRyeXMucG9wKCk7IGNvbnRpbnVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIG9wID0gYm9keS5jYWxsKHRoaXNBcmcsIF8pO1xyXG4gICAgICAgIH0gY2F0Y2ggKGUpIHsgb3AgPSBbNiwgZV07IHkgPSAwOyB9IGZpbmFsbHkgeyBmID0gdCA9IDA7IH1cclxuICAgICAgICBpZiAob3BbMF0gJiA1KSB0aHJvdyBvcFsxXTsgcmV0dXJuIHsgdmFsdWU6IG9wWzBdID8gb3BbMV0gOiB2b2lkIDAsIGRvbmU6IHRydWUgfTtcclxuICAgIH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZXhwb3J0U3RhcihtLCBleHBvcnRzKSB7XHJcbiAgICBmb3IgKHZhciBwIGluIG0pIGlmICghZXhwb3J0cy5oYXNPd25Qcm9wZXJ0eShwKSkgZXhwb3J0c1twXSA9IG1bcF07XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3ZhbHVlcyhvKSB7XHJcbiAgICB2YXIgbSA9IHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiBvW1N5bWJvbC5pdGVyYXRvcl0sIGkgPSAwO1xyXG4gICAgaWYgKG0pIHJldHVybiBtLmNhbGwobyk7XHJcbiAgICByZXR1cm4ge1xyXG4gICAgICAgIG5leHQ6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgaWYgKG8gJiYgaSA+PSBvLmxlbmd0aCkgbyA9IHZvaWQgMDtcclxuICAgICAgICAgICAgcmV0dXJuIHsgdmFsdWU6IG8gJiYgb1tpKytdLCBkb25lOiAhbyB9O1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3JlYWQobywgbikge1xyXG4gICAgdmFyIG0gPSB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgb1tTeW1ib2wuaXRlcmF0b3JdO1xyXG4gICAgaWYgKCFtKSByZXR1cm4gbztcclxuICAgIHZhciBpID0gbS5jYWxsKG8pLCByLCBhciA9IFtdLCBlO1xyXG4gICAgdHJ5IHtcclxuICAgICAgICB3aGlsZSAoKG4gPT09IHZvaWQgMCB8fCBuLS0gPiAwKSAmJiAhKHIgPSBpLm5leHQoKSkuZG9uZSkgYXIucHVzaChyLnZhbHVlKTtcclxuICAgIH1cclxuICAgIGNhdGNoIChlcnJvcikgeyBlID0geyBlcnJvcjogZXJyb3IgfTsgfVxyXG4gICAgZmluYWxseSB7XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgaWYgKHIgJiYgIXIuZG9uZSAmJiAobSA9IGlbXCJyZXR1cm5cIl0pKSBtLmNhbGwoaSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGZpbmFsbHkgeyBpZiAoZSkgdGhyb3cgZS5lcnJvcjsgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIGFyO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19zcHJlYWQoKSB7XHJcbiAgICBmb3IgKHZhciBhciA9IFtdLCBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKylcclxuICAgICAgICBhciA9IGFyLmNvbmNhdChfX3JlYWQoYXJndW1lbnRzW2ldKSk7XHJcbiAgICByZXR1cm4gYXI7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2F3YWl0KHYpIHtcclxuICAgIHJldHVybiB0aGlzIGluc3RhbmNlb2YgX19hd2FpdCA/ICh0aGlzLnYgPSB2LCB0aGlzKSA6IG5ldyBfX2F3YWl0KHYpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hc3luY0dlbmVyYXRvcih0aGlzQXJnLCBfYXJndW1lbnRzLCBnZW5lcmF0b3IpIHtcclxuICAgIGlmICghU3ltYm9sLmFzeW5jSXRlcmF0b3IpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJTeW1ib2wuYXN5bmNJdGVyYXRvciBpcyBub3QgZGVmaW5lZC5cIik7XHJcbiAgICB2YXIgZyA9IGdlbmVyYXRvci5hcHBseSh0aGlzQXJnLCBfYXJndW1lbnRzIHx8IFtdKSwgaSwgcSA9IFtdO1xyXG4gICAgcmV0dXJuIGkgPSB7fSwgdmVyYihcIm5leHRcIiksIHZlcmIoXCJ0aHJvd1wiKSwgdmVyYihcInJldHVyblwiKSwgaVtTeW1ib2wuYXN5bmNJdGVyYXRvcl0gPSBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzOyB9LCBpO1xyXG4gICAgZnVuY3Rpb24gdmVyYihuKSB7IGlmIChnW25dKSBpW25dID0gZnVuY3Rpb24gKHYpIHsgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChhLCBiKSB7IHEucHVzaChbbiwgdiwgYSwgYl0pID4gMSB8fCByZXN1bWUobiwgdik7IH0pOyB9OyB9XHJcbiAgICBmdW5jdGlvbiByZXN1bWUobiwgdikgeyB0cnkgeyBzdGVwKGdbbl0odikpOyB9IGNhdGNoIChlKSB7IHNldHRsZShxWzBdWzNdLCBlKTsgfSB9XHJcbiAgICBmdW5jdGlvbiBzdGVwKHIpIHsgci52YWx1ZSBpbnN0YW5jZW9mIF9fYXdhaXQgPyBQcm9taXNlLnJlc29sdmUoci52YWx1ZS52KS50aGVuKGZ1bGZpbGwsIHJlamVjdCkgOiBzZXR0bGUocVswXVsyXSwgcik7IH1cclxuICAgIGZ1bmN0aW9uIGZ1bGZpbGwodmFsdWUpIHsgcmVzdW1lKFwibmV4dFwiLCB2YWx1ZSk7IH1cclxuICAgIGZ1bmN0aW9uIHJlamVjdCh2YWx1ZSkgeyByZXN1bWUoXCJ0aHJvd1wiLCB2YWx1ZSk7IH1cclxuICAgIGZ1bmN0aW9uIHNldHRsZShmLCB2KSB7IGlmIChmKHYpLCBxLnNoaWZ0KCksIHEubGVuZ3RoKSByZXN1bWUocVswXVswXSwgcVswXVsxXSk7IH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fYXN5bmNEZWxlZ2F0b3Iobykge1xyXG4gICAgdmFyIGksIHA7XHJcbiAgICByZXR1cm4gaSA9IHt9LCB2ZXJiKFwibmV4dFwiKSwgdmVyYihcInRocm93XCIsIGZ1bmN0aW9uIChlKSB7IHRocm93IGU7IH0pLCB2ZXJiKFwicmV0dXJuXCIpLCBpW1N5bWJvbC5pdGVyYXRvcl0gPSBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzOyB9LCBpO1xyXG4gICAgZnVuY3Rpb24gdmVyYihuLCBmKSB7IGlbbl0gPSBvW25dID8gZnVuY3Rpb24gKHYpIHsgcmV0dXJuIChwID0gIXApID8geyB2YWx1ZTogX19hd2FpdChvW25dKHYpKSwgZG9uZTogbiA9PT0gXCJyZXR1cm5cIiB9IDogZiA/IGYodikgOiB2OyB9IDogZjsgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hc3luY1ZhbHVlcyhvKSB7XHJcbiAgICBpZiAoIVN5bWJvbC5hc3luY0l0ZXJhdG9yKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiU3ltYm9sLmFzeW5jSXRlcmF0b3IgaXMgbm90IGRlZmluZWQuXCIpO1xyXG4gICAgdmFyIG0gPSBvW1N5bWJvbC5hc3luY0l0ZXJhdG9yXSwgaTtcclxuICAgIHJldHVybiBtID8gbS5jYWxsKG8pIDogKG8gPSB0eXBlb2YgX192YWx1ZXMgPT09IFwiZnVuY3Rpb25cIiA/IF9fdmFsdWVzKG8pIDogb1tTeW1ib2wuaXRlcmF0b3JdKCksIGkgPSB7fSwgdmVyYihcIm5leHRcIiksIHZlcmIoXCJ0aHJvd1wiKSwgdmVyYihcInJldHVyblwiKSwgaVtTeW1ib2wuYXN5bmNJdGVyYXRvcl0gPSBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzOyB9LCBpKTtcclxuICAgIGZ1bmN0aW9uIHZlcmIobikgeyBpW25dID0gb1tuXSAmJiBmdW5jdGlvbiAodikgeyByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkgeyB2ID0gb1tuXSh2KSwgc2V0dGxlKHJlc29sdmUsIHJlamVjdCwgdi5kb25lLCB2LnZhbHVlKTsgfSk7IH07IH1cclxuICAgIGZ1bmN0aW9uIHNldHRsZShyZXNvbHZlLCByZWplY3QsIGQsIHYpIHsgUHJvbWlzZS5yZXNvbHZlKHYpLnRoZW4oZnVuY3Rpb24odikgeyByZXNvbHZlKHsgdmFsdWU6IHYsIGRvbmU6IGQgfSk7IH0sIHJlamVjdCk7IH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fbWFrZVRlbXBsYXRlT2JqZWN0KGNvb2tlZCwgcmF3KSB7XHJcbiAgICBpZiAoT2JqZWN0LmRlZmluZVByb3BlcnR5KSB7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjb29rZWQsIFwicmF3XCIsIHsgdmFsdWU6IHJhdyB9KTsgfSBlbHNlIHsgY29va2VkLnJhdyA9IHJhdzsgfVxyXG4gICAgcmV0dXJuIGNvb2tlZDtcclxufTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2ltcG9ydFN0YXIobW9kKSB7XHJcbiAgICBpZiAobW9kICYmIG1vZC5fX2VzTW9kdWxlKSByZXR1cm4gbW9kO1xyXG4gICAgdmFyIHJlc3VsdCA9IHt9O1xyXG4gICAgaWYgKG1vZCAhPSBudWxsKSBmb3IgKHZhciBrIGluIG1vZCkgaWYgKE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1vZCwgaykpIHJlc3VsdFtrXSA9IG1vZFtrXTtcclxuICAgIHJlc3VsdC5kZWZhdWx0ID0gbW9kO1xyXG4gICAgcmV0dXJuIHJlc3VsdDtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9faW1wb3J0RGVmYXVsdChtb2QpIHtcclxuICAgIHJldHVybiAobW9kICYmIG1vZC5fX2VzTW9kdWxlKSA/IG1vZCA6IHsgZGVmYXVsdDogbW9kIH07XHJcbn1cclxuIiwiaW1wb3J0IHsgQ29tcG9uZW50LCBPbkluaXQsIElucHV0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2FuZ3VsYXIyY3N2JyxcbiAgdGVtcGxhdGU6IGA8YnV0dG9uIChjbGljayk9XCJvbkRvd25sb2FkKClcIj57eyBsYWJlbF9idG4gfX08L2J1dHRvbj5gLFxuICBzdHlsZXM6IFtdXG59KVxuXG5leHBvcnQgY2xhc3MgQW5ndWxhcjJDc3ZDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuXG4gIEBJbnB1dCgpIGRhdGE6IGFueVtdO1xuICBASW5wdXQoKSBmaWxlbmFtZTogc3RyaW5nICA9IHRoaXMuZmlsZW5hbWUgfHwgJ215Y3N2LmNzdic7XG4gIEBJbnB1dCgpIG9wdGlvbnM6IE9wdGlvbnMgPSB0aGlzLm9iamVjdEFzc2lnbih7fSwgQ29uZmlnRGVmYXVsdHMsIHRoaXMub3B0aW9ucyk7XG5cbiAgbGFiZWxfYnRuOiBzdHJpbmcgPSBcImRvd25sb2FkXCI7XG4gIGNzdjogc3RyaW5nID0gJyc7XG5cbiAgY29uc3RydWN0b3IoKSB7fVxuICAvKipcbiAgICogRXZlbnQgRG93bmxvYWRcbiAgICovXG4gIG9uRG93bmxvYWQoKTogdm9pZCB7XG4gICAgdGhpcy5nZW5lcmF0ZUNzdigpO1xuICB9XG4gIC8qKlxuICAgKiBuZ09uSW5pdFxuICAgKi9cbiAgbmdPbkluaXQoKSB7fVxuICAvKipcbiAgICogW2dlbmVyYXRlQ3N2IGRlc2NyaXB0aW9uXVxuICAgKi9cbiAgZ2VuZXJhdGVDc3YoKTogdm9pZCB7XG5cbiAgICBpZiAodGhpcy5vcHRpb25zLnVzZUJvbSkge1xuICAgICAgdGhpcy5jc3YgKz0gQ3N2Q29uZmlnQ29uc3RzLkJPTTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5vcHRpb25zLnNob3dUaXRsZSkge1xuICAgICAgdGhpcy5jc3YgKz0gdGhpcy5vcHRpb25zLnRpdGxlICsgJ1xcclxcblxcbic7XG4gICAgfVxuXG4gICAgdGhpcy5nZXRIZWFkZXJzKCk7XG4gICAgdGhpcy5nZXRCb2R5KCk7XG5cbiAgICBpZiAodGhpcy5jc3YgPT09ICcnKSB7XG4gICAgICBjb25zb2xlLmxvZygnSW52YWxpZCBkYXRhJyk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbGV0IGJsb2IgPSBuZXcgQmxvYihbdGhpcy5jc3ZdLCB7dHlwZTogJ3RleHQvY3N2O2NoYXJzZXQ9dXRmODsnfSk7XG5cbiAgICBpZiAobmF2aWdhdG9yLm1zU2F2ZUJsb2IpIHtcblxuICAgICAgbGV0IGZpbGVuYW1lID0gdGhpcy5vcHRpb25zLmZpbGVuYW1lLnJlcGxhY2UoLyAvZywgJ18nKSArICcuY3N2JztcbiAgICAgIG5hdmlnYXRvci5tc1NhdmVCbG9iKGJsb2IsIGZpbGVuYW1lKTtcblxuICAgIH0gZWxzZSB7XG5cbiAgICAgIGxldCB1cmkgPSAnZGF0YTphdHRhY2htZW50L2NzdjtjaGFyc2V0PXV0Zi04LCcgKyBlbmNvZGVVUkkodGhpcy5jc3YpO1xuICAgICAgbGV0IGxpbmsgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdhJyk7XG5cbiAgICAgIGxpbmsuaHJlZiA9IFVSTC5jcmVhdGVPYmplY3RVUkwoYmxvYik7XG5cbiAgICAgIGxpbmsuc2V0QXR0cmlidXRlKCd2aXNpYmlsaXR5JywgJ2hpZGRlbicpO1xuICAgICAgbGluay5kb3dubG9hZCA9IHRoaXMuZmlsZW5hbWUucmVwbGFjZSgvIC9nLCAnXycpICsgJy5jc3YnO1xuXG4gICAgICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKGxpbmspO1xuXG4gICAgICBsaW5rLmNsaWNrKCk7XG5cbiAgICAgIGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQobGluayk7XG4gICAgfVxuXG4gICAgdGhpcy5jc3YgPSAnJztcbiAgfVxuICAvKipcbiAgICogQ3JlYXRlIEhlYWRlcnMgZm9yIENzdiBGaWxlXG4gICAqL1xuICBnZXRIZWFkZXJzKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLm9wdGlvbnMuaGVhZGVycy5sZW5ndGggPiAwKSB7XG4gICAgICBsZXQgcm93ID0gJyc7XG4gICAgICBmb3IgKGxldCBjb2x1bW4gb2YgdGhpcy5vcHRpb25zLmhlYWRlcnMpIHtcbiAgICAgICAgcm93ICs9IGNvbHVtbiArIHRoaXMub3B0aW9ucy5maWVsZFNlcGFyYXRvcjtcbiAgICAgIH1cblxuICAgICAgcm93ID0gcm93LnNsaWNlKDAsIC0xKTtcbiAgICAgIHRoaXMuY3N2ICs9IHJvdyArIENzdkNvbmZpZ0NvbnN0cy5FT0w7XG4gICAgfVxuICB9XG4gIC8qKlxuICAgKiBDcmVhdGUgSGVhZGVyc1xuICAgKi9cbiAgZ2V0Qm9keSgpOiB2b2lkIHtcblxuICAgIGZvciAobGV0IGRhdGFSb3cgb2YgdGhpcy5kYXRhKSB7XG5cbiAgICAgIGxldCByb3cgPSAnJztcblxuICAgICAgaWYodGhpcy5pc0VtcHR5T2JqZWN0KGRhdGFSb3cpICYmIHRoaXMub3B0aW9ucy5yZW1vdmVOZXdMaW5lcykge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKHR5cGVvZiB0aGlzLm9wdGlvbnMua2V5cyAhPT0gJ3VuZGVmaW5lZCcgJiYgdGhpcy5vcHRpb25zLmtleXMubGVuZ3RoKSB7XG5cbiAgICAgICAgZm9yIChsZXQga2V5IG9mIHRoaXMub3B0aW9ucy5rZXlzKSB7XG4gICAgICAgICAgcm93ICs9IHRoaXMuZm9ybWFydERhdGEoZGF0YVJvd1trZXldKSArIHRoaXMub3B0aW9ucy5maWVsZFNlcGFyYXRvcjtcbiAgICAgICAgfVxuXG4gICAgICAgIHJvdyA9IHJvdy5zbGljZSgwLCAtMSk7XG4gICAgICAgIHRoaXMuY3N2ICs9IHJvdyArIENzdkNvbmZpZ0NvbnN0cy5FT0w7XG5cbiAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgZm9yIChsZXQga2V5IGluIGRhdGFSb3cpIHtcbiAgICAgICAgICBpZihkYXRhUm93W2tleV0pIHtcbiAgICAgICAgICAgIHJvdyArPSB0aGlzLmZvcm1hcnREYXRhKGRhdGFSb3dba2V5XSkgKyB0aGlzLm9wdGlvbnMuZmllbGRTZXBhcmF0b3I7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuY3N2ICs9IHJvdyArIENzdkNvbmZpZ0NvbnN0cy5FT0w7XG5cbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgLyoqXG4gICAqIEZvcm1hdCBEYXRhXG4gICAqL1xuICBmb3JtYXJ0RGF0YShkYXRhOiBhbnkpIHtcblxuICAgIGlmICh0aGlzLm9wdGlvbnMuZGVjaW1hbHNlcGFyYXRvciA9PT0gJ2xvY2FsZScgJiYgdGhpcy5pc0Zsb2F0KGRhdGEpKSB7XG4gICAgICByZXR1cm4gZGF0YS50b0xvY2FsZVN0cmluZygpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLm9wdGlvbnMuZGVjaW1hbHNlcGFyYXRvciAhPT0gJy4nICYmIHRoaXMuaXNGbG9hdChkYXRhKSkge1xuICAgICAgcmV0dXJuIGRhdGEudG9TdHJpbmcoKS5yZXBsYWNlKCcuJywgdGhpcy5vcHRpb25zLmRlY2ltYWxzZXBhcmF0b3IpO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgZGF0YSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGRhdGEgPSBkYXRhLnJlcGxhY2UoL1wiL2csICdcIlwiJyk7XG5cbiAgICAgIGlmICh0aGlzLm9wdGlvbnMucXVvdGVTdHJpbmdzIHx8IGRhdGEuaW5kZXhPZignLCcpID4gLTEgfHwgZGF0YS5pbmRleE9mKFwiXFxuXCIpID4gLTEgfHwgZGF0YS5pbmRleE9mKFwiXFxyXCIpID4gLTEpIHtcbiAgICAgICAgZGF0YSA9IHRoaXMub3B0aW9ucy5xdW90ZVN0cmluZ3MgKyBkYXRhICsgdGhpcy5vcHRpb25zLnF1b3RlU3RyaW5ncztcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGRhdGE7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBkYXRhID09PSAnYm9vbGVhbicpIHtcbiAgICAgIHJldHVybiBkYXRhID8gJ1RSVUUnIDogJ0ZBTFNFJztcbiAgICB9XG5cbiAgICByZXR1cm4gZGF0YTtcbiAgfVxuICAvKipcbiAgICogVmFsaWRhdGUgaWYgb2JqZWN0IGlzIG5vdCBlbXB0eVxuICAgKi9cbiAgaXNFbXB0eU9iamVjdChvYmo6IGFueSkge1xuICAgIHJldHVybiAob2JqICYmIChPYmplY3Qua2V5cyhvYmopLmxlbmd0aCA9PT0gMCkpO1xuICB9XG4gIC8qKlxuICAgKiBHZXQgSW5wdXQgaXMgRmxvYXRcbiAgICovXG4gIGlzRmxvYXQoaW5wdXQ6IGFueSkge1xuICAgIHJldHVybiAraW5wdXQgPT09IGlucHV0ICYmICghaXNGaW5pdGUoaW5wdXQpIHx8IEJvb2xlYW4oaW5wdXQgJSAxKSk7XG4gIH1cbiAgLyoqXG4gICAqIEFkZCBvYmplY3QgVmFsdWVzXG4gICAqL1xuICB0b09iamVjdCh2YWw6IGFueSkge1xuICAgIGlmICh2YWwgPT09IG51bGwgfHwgdmFsID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ09iamVjdC5hc3NpZ24gY2Fubm90IGJlIGNhbGxlZCB3aXRoIG51bGwgb3IgdW5kZWZpbmVkJyk7XG4gICAgfVxuICAgIHJldHVybiBPYmplY3QodmFsKTtcbiAgfVxuICAvKipcbiAgICogQWRkIFZhbHVlcyB0byBPYmplY3RcbiAgICovXG4gIG9iamVjdEFzc2lnbih0YXJnZXQ6IGFueSwgLi4uc291cmNlOiBhbnlbXSkge1xuICAgIGxldCBmcm9tOiBhbnk7XG4gICAgbGV0IHRvID0gdGhpcy50b09iamVjdCh0YXJnZXQpO1xuICAgIGxldCBzeW1ib2xzOiBhbnk7XG5cbiAgICBsZXQgaGFzT3duUHJvcGVydHkgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xuICAgIGxldCBwcm9wSXNFbnVtZXJhYmxlID0gT2JqZWN0LnByb3RvdHlwZS5wcm9wZXJ0eUlzRW51bWVyYWJsZTtcblxuICAgIGZvciAobGV0IHMgPSAxOyBzIDwgYXJndW1lbnRzLmxlbmd0aDsgcysrKSB7XG4gICAgICBmcm9tID0gT2JqZWN0KGFyZ3VtZW50c1tzXSk7XG5cbiAgICAgIGZvciAobGV0IGtleSBpbiBmcm9tKSB7XG4gICAgICAgIGlmIChoYXNPd25Qcm9wZXJ0eS5jYWxsKGZyb20sIGtleSkpIHtcbiAgICAgICAgICB0b1trZXldID0gZnJvbVtrZXldO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmICgoPGFueT4gT2JqZWN0KS5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMpIHtcbiAgICAgICAgc3ltYm9scyA9ICg8YW55PiBPYmplY3QpLmdldE93blByb3BlcnR5U3ltYm9scyhmcm9tKTtcbiAgICAgICAgZm9yIChsZXQgc3ltYm9sIG9mIHN5bWJvbHMpIHtcbiAgICAgICAgICBpZiAocHJvcElzRW51bWVyYWJsZS5jYWxsKGZyb20sIHN5bWJvbCkpIHtcbiAgICAgICAgICAgIHRvW3N5bWJvbF0gPSBmcm9tW3N5bWJvbF07XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHRvO1xuICB9XG59XG4vKipcbiAqIE9wdGlvbiBJbnRlcmZhY2VcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBPcHRpb25zIHtcbiAgZmlsZW5hbWU6IHN0cmluZztcbiAgZmllbGRTZXBhcmF0b3I6IHN0cmluZztcbiAgcXVvdGVTdHJpbmdzOiBzdHJpbmc7XG4gIGRlY2ltYWxzZXBhcmF0b3I6IHN0cmluZztcbiAgc2hvd0xhYmVsczogYm9vbGVhbjtcbiAgc2hvd1RpdGxlOiBib29sZWFuO1xuICB0aXRsZTogc3RyaW5nO1xuICB1c2VCb206IGJvb2xlYW47XG4gIGhlYWRlcnM6IHN0cmluZ1tdO1xuICBrZXlzOiBzdHJpbmdbXTtcbiAgcmVtb3ZlTmV3TGluZXM6IGJvb2xlYW47XG59XG4vKipcbiAqIENzdkNvbmZpZ0NvbnN0c1xuICovXG5leHBvcnQgY2xhc3MgQ3N2Q29uZmlnQ29uc3RzIHtcblxuICBwdWJsaWMgc3RhdGljIEVPTCA9ICdcXHJcXG4nO1xuICBwdWJsaWMgc3RhdGljIEJPTSA9ICdcXHVmZWZmJztcblxuICBwdWJsaWMgc3RhdGljIERFRkFVTFRfRklFTERfU0VQQVJBVE9SID0gJywnO1xuICBwdWJsaWMgc3RhdGljIERFRkFVTFRfREVDSU1BTF9TRVBBUkFUT1IgPSAnLic7XG4gIHB1YmxpYyBzdGF0aWMgREVGQVVMVF9RVU9URSA9ICdcIic7XG4gIHB1YmxpYyBzdGF0aWMgREVGQVVMVF9TSE9XX1RJVExFID0gZmFsc2U7XG4gIHB1YmxpYyBzdGF0aWMgREVGQVVMVF9USVRMRSA9ICdNeSBSZXBvcnQnO1xuICBwdWJsaWMgc3RhdGljIERFRkFVTFRfRklMRU5BTUUgPSAnbXljc3YuY3N2JztcbiAgcHVibGljIHN0YXRpYyBERUZBVUxUX1NIT1dfTEFCRUxTID0gZmFsc2U7XG4gIHB1YmxpYyBzdGF0aWMgREVGQVVMVF9VU0VfQk9NID0gdHJ1ZTtcbiAgcHVibGljIHN0YXRpYyBERUZBVUxUX0hFQURFUjogc3RyaW5nW10gPSBbXTtcbiAgcHVibGljIHN0YXRpYyBERUZBVUxUX0tFWTogc3RyaW5nW10gPSBbXTtcbiAgcHVibGljIHN0YXRpYyBERUZBVUxUX1JFTU9WRV9ORVdfTElORVMgPSBmYWxzZTtcbn1cbi8qKlxuICogRGVmYXVsdCBDb25maWd1cmF0aW9uc1xuICovXG5leHBvcnQgY29uc3QgQ29uZmlnRGVmYXVsdHM6IE9wdGlvbnMgPSB7XG4gIGZpbGVuYW1lOiBDc3ZDb25maWdDb25zdHMuREVGQVVMVF9GSUxFTkFNRSxcbiAgZmllbGRTZXBhcmF0b3I6IENzdkNvbmZpZ0NvbnN0cy5ERUZBVUxUX0ZJRUxEX1NFUEFSQVRPUixcbiAgcXVvdGVTdHJpbmdzOiBDc3ZDb25maWdDb25zdHMuREVGQVVMVF9RVU9URSxcbiAgZGVjaW1hbHNlcGFyYXRvcjogQ3N2Q29uZmlnQ29uc3RzLkRFRkFVTFRfREVDSU1BTF9TRVBBUkFUT1IsXG4gIHNob3dMYWJlbHM6IENzdkNvbmZpZ0NvbnN0cy5ERUZBVUxUX1NIT1dfTEFCRUxTLFxuICBzaG93VGl0bGU6IENzdkNvbmZpZ0NvbnN0cy5ERUZBVUxUX1NIT1dfVElUTEUsXG4gIHRpdGxlOiBDc3ZDb25maWdDb25zdHMuREVGQVVMVF9USVRMRSxcbiAgdXNlQm9tOiBDc3ZDb25maWdDb25zdHMuREVGQVVMVF9VU0VfQk9NLFxuICBoZWFkZXJzOiBDc3ZDb25maWdDb25zdHMuREVGQVVMVF9IRUFERVIsXG4gIGtleXM6IENzdkNvbmZpZ0NvbnN0cy5ERUZBVUxUX0tFWSxcbiAgcmVtb3ZlTmV3TGluZXM6IENzdkNvbmZpZ0NvbnN0cy5ERUZBVUxUX1JFTU9WRV9ORVdfTElORVNcbn07XG4iLCJpbXBvcnQgeyBOZ01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcblxuaW1wb3J0IHsgQW5ndWxhcjJDc3ZDb21wb25lbnQgfSBmcm9tICcuL2FuZ3VsYXIyLWNzdi5jb21wb25lbnQnO1xuXG5ATmdNb2R1bGUoe1xuICBpbXBvcnRzOiBbXG4gICAgQ29tbW9uTW9kdWxlXG4gIF0sXG4gIGRlY2xhcmF0aW9uczogW0FuZ3VsYXIyQ3N2Q29tcG9uZW50XSxcbiAgZXhwb3J0czogW0FuZ3VsYXIyQ3N2Q29tcG9uZW50XVxufSlcbmV4cG9ydCBjbGFzcyBBbmd1bGFyMkNzdk1vZHVsZSB7IH1cbiJdLCJuYW1lcyI6WyJJbmplY3RhYmxlIiwidHNsaWJfMS5fX3ZhbHVlcyIsIkNvbXBvbmVudCIsIklucHV0IiwiTmdNb2R1bGUiLCJDb21tb25Nb2R1bGUiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7QUFBQTtRQU9FO1NBQWlCOztvQkFMbEJBLGFBQVUsU0FBQzt3QkFDVixVQUFVLEVBQUUsTUFBTTtxQkFDbkI7Ozs7O2lDQUpEOzs7SUNBQTs7Ozs7Ozs7Ozs7Ozs7QUFjQSxzQkE0RnlCLENBQUM7UUFDdEIsSUFBSSxDQUFDLEdBQUcsT0FBTyxNQUFNLEtBQUssVUFBVSxJQUFJLENBQUMsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNsRSxJQUFJLENBQUM7WUFBRSxPQUFP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