@wizco/fenixds-ngx
Version:
Componentes fenix design system para Angular.
405 lines • 45.3 kB
JavaScript
import { Component, EventEmitter, Input, Output, SkipSelf, } from '@angular/core';
import { HttpClientModule, HttpEventType, } from '@angular/common/http';
import { CommonModule } from '@angular/common';
import * as i0 from "@angular/core";
import * as i1 from "@angular/common/http";
import * as i2 from "@angular/common";
export class UploadComponent {
http;
/* Texto de descrição do arquivo */
description = '(XX MB de tamanho máximo e é permitido qualquer tipo de arquivos)';
/* config <AngularFileUploaderConfig> configuração do componente principais parâmetros */
config = {
uploadAPI: {
url: '',
method: 'POST',
headers: {
'Content-Type': 'text/plain;charset=UTF-8',
},
responseType: 'json',
withCredentials: false,
},
};
/*
* Opção de resetar o componente
*/
resetUpload = false;
/*
* Evento Resposta da requisição sendo sucesso ou erro
*/
ApiResponse = new EventEmitter();
/*
* Evento javascript puro para retorno do arquivo
*/
fileSelected = new EventEmitter();
/**
* @ignore
*/
theme = '';
/**
* @ignore
*/
id = 0;
/**
* @ignore
*/
hideProgressBar = false;
/**
* @ignore
*/
maxSize = 20 * 1024000; // mb to bytes.
/**
* @ignore
*/
uploadAPI = '';
/**
* @ignore
*/
method = 'POST';
/**
* @ignore
*/
formatsAllowed = '*';
/**
* @ignore
*/
formatsAllowedText = '';
/**
* @ignore
*/
multiple = false;
/**
* @ignore
*/
headers = {};
/**
* @ignore
*/
params = {};
/**
* @ignore
*/
responseType = 'blob';
/**
* @ignore
*/
hideResetBtn = false;
/**
* @ignore
*/
hideSelectBtn = false;
/**
* @ignore
*/
allowedFiles = [];
/**
* @ignore
*/
notAllowedFiles = [];
/**
* @ignore
*/
Caption = [];
/**
* @ignore
*/
isAllowedFileSingle = true;
/**
* @ignore
*/
progressBarShow = false;
/**
* @ignore
*/
enableUploadBtn = false;
/**
* @ignore
*/
uploadMsg = false;
/**
* @ignore
*/
afterUpload = false;
/**
* @ignore
*/
uploadStarted = false;
/**
* @ignore
*/
uploadMsgText = '';
/**
* @ignore
*/
uploadMsgClass = 'text-success';
/**
* @ignore
*/
uploadPercent = 0;
/**
* @ignore
*/
replaceTexts = {
selectFileBtn: 'Selecionar Arquivo',
resetBtn: 'Resetar',
uploadBtn: 'Enviar',
dragNDropBox: 'Arraste e solte',
attachPinBtn: 'Anexar Arquivo...',
afterUploadMsg_success: 'Enviado com sucesso !',
afterUploadMsg_error: 'Falha no envio !',
sizeLimit: 'Tamanho máximo',
};
/**
* @ignore
*/
currentUploads = [];
/**
* @ignore
*/
fileNameIndex = true;
/**
* @ignore
*/
withCredentials = false;
/**
* @ignore
*/
autoUpload = true;
/**
* @ignore
*/
idDate = +new Date();
constructor(http) {
this.http = http;
}
/**
* @ignore
*/
ngOnChanges(changes) {
// Track changes in Configuration and see if user has even provided Configuration.
if (changes.config && this.config) {
// Assign User Configurations to Library Properties.
this.theme = this.config.theme || '';
this.id =
this.config.id ||
parseInt((this.idDate / 10000).toString().split('.')[1], 10) +
Math.floor(Math.random() * 20) * 10000;
this.hideProgressBar = this.config.hideProgressBar || false;
this.hideResetBtn = this.config.hideResetBtn || false;
this.hideSelectBtn = this.config.hideSelectBtn || false;
this.maxSize = (this.config.maxSize || 20) * 1024000; // mb to bytes.
if (this.config.uploadAPI) {
this.uploadAPI = this.config.uploadAPI.url;
this.method = this.config.uploadAPI.method || 'POST';
this.formatsAllowed = this.config.formatsAllowed || '*';
this.multiple = this.config.multiple || false;
this.headers = this.config.uploadAPI.headers || {};
this.params = this.config.uploadAPI.params || {};
this.responseType = this.config.uploadAPI.responseType || 'json';
this.withCredentials = this.config.uploadAPI.withCredentials || false;
}
this.formatsAllowedText =
this.formatsAllowed === '*' ? '' : '(' + this.formatsAllowed + ')';
this.fileNameIndex = this.config.fileNameIndex === false ? false : true;
this.autoUpload = this.config.autoUpload || false;
if (this.config.replaceTexts) {
this.replaceTexts = {
...this.replaceTexts,
...this.config.replaceTexts,
};
}
}
// Reset when resetUpload value changes from false to true.
if (changes.resetUpload) {
if (changes.resetUpload.currentValue === true) {
this.resetFileUpload();
}
}
}
/* Função resetar componente */
resetFileUpload() {
this.allowedFiles = [];
this.Caption = [];
this.notAllowedFiles = [];
this.uploadMsg = false;
this.enableUploadBtn = false;
}
/* Detectar mudança */
onChange(event) {
this.fileSelected.emit(event);
this.notAllowedFiles = [];
const fileExtRegExp = /(?:\.([^.]+))?$/;
let fileList;
if (this.afterUpload || !this.multiple) {
this.allowedFiles = [];
this.Caption = [];
this.afterUpload = false;
}
if (event.type === 'drop') {
fileList = event.dataTransfer.files;
}
else {
fileList = event.target.files || event.srcElement.files;
}
// 'forEach' does not exist on 'filelist' that's why this good old 'for' is used.
// tslint:disable-next-line: for-of
for (let i = 0; i < fileList.length; i++) {
const _currentFileExt = fileExtRegExp.exec(fileList[i].name);
const currentFileExt = typeof _currentFileExt[1] === 'string'
? _currentFileExt[1].toLowerCase()
: '';
const isFormatValid = this.formatsAllowed.includes('*')
? true
: this.formatsAllowed.includes(currentFileExt);
const isSizeValid = fileList[i].size <= this.maxSize;
// Check whether current file format and size is correct as specified in the configurations.
if (isFormatValid && isSizeValid) {
this.allowedFiles.push(fileList[i]);
}
else {
this.notAllowedFiles.push({
fileName: fileList[i].name,
fileSize: this.convertSize(fileList[i].size),
errorMsg: !isFormatValid ? 'Invalid format' : 'Invalid size',
});
}
}
// If there's any allowedFiles.
if (this.allowedFiles.length > 0) {
this.enableUploadBtn = true;
// Upload the files directly if theme is attach pin (as upload btn is not there for this theme) or autoUpload is true.
if (this.theme === 'attachPin' || this.autoUpload) {
this.uploadFiles();
}
}
else {
this.enableUploadBtn = false;
}
this.uploadMsg = false;
this.uploadStarted = false;
this.uploadPercent = 0;
event.target.value = null;
}
/* Função para enviar arquivo para servidor */
uploadFiles() {
this.progressBarShow = true;
this.uploadStarted = true;
this.notAllowedFiles = [];
let isError = false;
this.isAllowedFileSingle = this.allowedFiles.length <= 1;
const formData = new FormData();
// Add data to be sent in this request
this.allowedFiles.forEach((file, i) => {
formData.append(this.Caption[i] || 'file' + (this.fileNameIndex ? i : ''), this.allowedFiles[i]);
});
this.http
.request(this.method.toUpperCase(), this.uploadAPI, {
body: formData,
reportProgress: true,
observe: 'events',
headers: this.headers,
params: this.params,
responseType: this.responseType,
withCredentials: this.withCredentials,
})
.subscribe((event) => {
// Upload Progress
if (event.type === HttpEventType.UploadProgress) {
this.enableUploadBtn = false; // button should be disabled if process uploading
const currentDone = event.loaded / event.total;
this.uploadPercent = Math.round((event.loaded / event.total) * 100);
}
else if (event.type === HttpEventType.Response) {
if (event.status === 200 || event.status === 201) {
// Success
this.progressBarShow = false;
this.enableUploadBtn = false;
this.uploadMsg = true;
this.afterUpload = true;
if (!isError) {
this.uploadMsgText =
this.replaceTexts.afterUploadMsg_success ||
'Successfully Uploaded !';
this.uploadMsgClass = 'text-success lead';
}
}
else {
// Failure
isError = true;
this.handleErrors();
}
this.ApiResponse.emit(event);
}
else {
//console.log('Event Other: ', event);
}
}, (error) => {
// Failure
isError = true;
this.handleErrors();
this.ApiResponse.emit(error);
});
}
handleErrors() {
this.progressBarShow = false;
this.enableUploadBtn = false;
this.uploadMsg = true;
this.afterUpload = true;
this.uploadMsgText =
this.replaceTexts.afterUploadMsg_error || 'Error in uploading files';
this.uploadMsgClass = 'text-danger lead';
}
removeFile(i, sf_na) {
if (sf_na === 'sf') {
this.allowedFiles.splice(i, 1);
this.Caption.splice(i, 1);
}
else {
this.notAllowedFiles.splice(i, 1);
}
if (this.allowedFiles.length === 0) {
this.enableUploadBtn = false;
}
}
convertSize(fileSize) {
return fileSize < 1024000
? (fileSize / 1024).toFixed(2) + ' KB'
: (fileSize / 1024000).toFixed(2) + ' MB';
}
attachpinOnclick() {
const element = document.getElementById('sel' + this.id);
if (element !== null) {
element.click();
}
}
drop(event) {
event.stopPropagation();
event.preventDefault();
this.onChange(event);
}
allowDrop(event) {
event.stopPropagation();
event.preventDefault();
event.dataTransfer.dropEffect = 'copy';
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: UploadComponent, deps: [{ token: i1.HttpClient, skipSelf: true }], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: UploadComponent, isStandalone: true, selector: "wco-file-upload", inputs: { description: "description", config: "config", resetUpload: "resetUpload" }, outputs: { ApiResponse: "apiResponse", fileSelected: "fileSelected" }, usesOnChanges: true, ngImport: i0, template: "<label for=\"sel{{id}}\" class=\"wco-form-upload\" (drop)=\"drop($event)\" (dragover)=\"allowDrop($event)\">\n <div class=\"wco-form-upload__info\">\n <span>Arraste-os aqui ou</span>\n <span>\n <span class=\"material-icons-outlined\">\nupload_file\n</span>\n <span>{{replaceTexts.selectFileBtn}}</span>\n </span>\n </div>\n <span class=\"upload__info\" *ngIf=\"!allowedFiles.length\" >{{description}}</span>\n <ng-container *ngIf=\"allowedFiles.length\">\n <span class=\"upload__info\" *ngFor=\"let sf of allowedFiles;let i=index\">\n {{sf.name}} <small>({{convertSize(sf.size)}})</small>\n </span>\n </ng-container>\n <input type=\"file\" id=\"sel{{id}}\" (change)=\"onChange($event)\" style=\"display: none\" title=\"Select file\"\n name=\"files[]\" [accept]=\"formatsAllowed\" [attr.multiple]=\"multiple ? '' : null\" />\n</label>", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: HttpClientModule }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: UploadComponent, decorators: [{
type: Component,
args: [{ selector: 'wco-file-upload', standalone: true, imports: [CommonModule, HttpClientModule], template: "<label for=\"sel{{id}}\" class=\"wco-form-upload\" (drop)=\"drop($event)\" (dragover)=\"allowDrop($event)\">\n <div class=\"wco-form-upload__info\">\n <span>Arraste-os aqui ou</span>\n <span>\n <span class=\"material-icons-outlined\">\nupload_file\n</span>\n <span>{{replaceTexts.selectFileBtn}}</span>\n </span>\n </div>\n <span class=\"upload__info\" *ngIf=\"!allowedFiles.length\" >{{description}}</span>\n <ng-container *ngIf=\"allowedFiles.length\">\n <span class=\"upload__info\" *ngFor=\"let sf of allowedFiles;let i=index\">\n {{sf.name}} <small>({{convertSize(sf.size)}})</small>\n </span>\n </ng-container>\n <input type=\"file\" id=\"sel{{id}}\" (change)=\"onChange($event)\" style=\"display: none\" title=\"Select file\"\n name=\"files[]\" [accept]=\"formatsAllowed\" [attr.multiple]=\"multiple ? '' : null\" />\n</label>" }]
}], ctorParameters: () => [{ type: i1.HttpClient, decorators: [{
type: SkipSelf
}] }], propDecorators: { description: [{
type: Input
}], config: [{
type: Input
}], resetUpload: [{
type: Input
}], ApiResponse: [{
type: Output,
args: ['apiResponse']
}], fileSelected: [{
type: Output
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXBsb2FkLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1jb21wb25lbnRzL3NyYy9saWIvdXBsb2FkL3VwbG9hZC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtY29tcG9uZW50cy9zcmMvbGliL3VwbG9hZC91cGxvYWQuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLFNBQVMsRUFDVCxZQUFZLEVBQ1osS0FBSyxFQUVMLE1BQU0sRUFDTixRQUFRLEdBQ1QsTUFBTSxlQUFlLENBQUM7QUFFdkIsT0FBTyxFQUVMLGdCQUFnQixFQUNoQixhQUFhLEdBR2QsTUFBTSxzQkFBc0IsQ0FBQztBQUU5QixPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7Ozs7QUFjL0MsTUFBTSxPQUFPLGVBQWU7SUErS007SUE5S2hDLG1DQUFtQztJQUMxQixXQUFXLEdBQ2xCLG1FQUFtRSxDQUFDO0lBQ3RFLHlGQUF5RjtJQUNoRixNQUFNLEdBQThCO1FBQzNDLFNBQVMsRUFBRTtZQUNULEdBQUcsRUFBRSxFQUFFO1lBQ1AsTUFBTSxFQUFFLE1BQU07WUFDZCxPQUFPLEVBQUU7Z0JBQ1AsY0FBYyxFQUFFLDBCQUEwQjthQUMzQztZQUNELFlBQVksRUFBRSxNQUFNO1lBQ3BCLGVBQWUsRUFBRSxLQUFLO1NBQ3ZCO0tBQ0YsQ0FBQztJQUVGOztPQUVHO0lBQ00sV0FBVyxHQUFHLEtBQUssQ0FBQztJQUU3Qjs7T0FFRztJQUNvQixXQUFXLEdBQUcsSUFBSSxZQUFZLEVBQUUsQ0FBQztJQUN4RDs7T0FFRztJQUNPLFlBQVksR0FBb0MsSUFBSSxZQUFZLEVBRXZFLENBQUM7SUFFSjs7T0FFRztJQUNILEtBQUssR0FBVyxFQUFFLENBQUM7SUFDbkI7O09BRUc7SUFDSCxFQUFFLEdBQVcsQ0FBQyxDQUFDO0lBQ2Y7O09B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UCxDQUFDLFlBQVksRUFBRSxnQkFBZ0IsQ0FBQzs7MEJBbUw1QixRQUFRO3lDQTdLWixXQUFXO3NCQUFuQixLQUFLO2dCQUdHLE1BQU07c0JBQWQsS0FBSztnQkFlRyxXQUFXO3NCQUFuQixLQUFLO2dCQUtpQixXQUFXO3NCQUFqQyxNQUFNO3VCQUFDLGFBQWE7Z0JBSVgsWUFBWTtzQkFBckIsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENvbXBvbmVudCxcbiAgRXZlbnRFbWl0dGVyLFxuICBJbnB1dCxcbiAgT25DaGFuZ2VzLFxuICBPdXRwdXQsXG4gIFNraXBTZWxmLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuaW1wb3J0IHtcbiAgSHR0cENsaWVudCxcbiAgSHR0cENsaWVudE1vZHVsZSxcbiAgSHR0cEV2ZW50VHlwZSxcbiAgSHR0cEhlYWRlcnMsXG4gIEh0dHBQYXJhbXMsXG59IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcblxuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7XG4gIEFuZ3VsYXJGaWxlVXBsb2FkZXJDb25maWcsXG4gIFJlcGxhY2VUZXh0cyxcbiAgVXBsb2FkSW5mb1R5cGVzLFxufSBmcm9tICcuL3VwbG9hZC50eXBlcyc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3djby1maWxlLXVwbG9hZCcsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtDb21tb25Nb2R1bGUsIEh0dHBDbGllbnRNb2R1bGVdLFxuICB0ZW1wbGF0ZVVybDogJy4vdXBsb2FkLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vdXBsb2FkLmNvbXBvbmVudC5zY3NzJ10sXG59KVxuZXhwb3J0IGNsYXNzIFVwbG9hZENvbXBvbmVudCBpbXBsZW1lbnRzIE9uQ2hhbmdlcyB7XG4gIC8qIFRleHRvIGRlIGRlc2NyacOnw6NvIGRvIGFycXVpdm8gKi9cbiAgQElucHV0KCkgZGVzY3JpcHRpb246IHN0cmluZyA9XG4gICAgJyhYWCBNQiBkZSB0YW1hbmhvIG3DoXhpbW8gZSDDqSBwZXJtaXRpZG8gcXVhbHF1ZXIgdGlwbyBkZSBhcnF1aXZvcyknO1xuICAvKiBjb25maWcgPEFuZ3VsYXJGaWxlVXBsb2FkZXJDb25maWc+IGNvbmZpZ3VyYcOnw6NvIGRvIGNvbXBvbmVudGUgcHJpbmNpcGFpcyBwYXLDom1ldHJvcyAqL1xuICBASW5wdXQoKSBjb25maWc6IEFuZ3VsYXJGaWxlVXBsb2FkZXJDb25maWcgPSB7XG4gICAgdXBsb2FkQVBJOiB7XG4gICAgICB1cmw6ICcnLFxuICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICBoZWFkZXJzOiB7XG4gICAgICAgICdDb250ZW50LVR5cGUnOiAndGV4dC9wbGFpbjtjaGFyc2V0PVVURi04JyxcbiAgICAgIH0sXG4gICAgICByZXNwb25zZVR5cGU6ICdqc29uJyxcbiAgICAgIHdpdGhDcmVkZW50aWFsczogZmFsc2UsXG4gICAgfSxcbiAgfTtcblxuICAvKlxuICAgKiBPcMOnw6NvIGRlIHJlc2V0YXIgbyBjb21wb25lbnRlXG4gICAqL1xuICBASW5wdXQoKSByZXNldFVwbG9hZCA9IGZhbHNlO1xuXG4gIC8qXG4gICAqIEV2ZW50byBSZXNwb3N0YSBkYSByZXF1aXNpw6fDo28gc2VuZG8gc3VjZXNzbyBvdSBlcnJvXG4gICAqL1xuICBAT3V0cHV0KCdhcGlSZXNwb25zZScpIEFwaVJlc3BvbnNlID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICAvKlxuICAgKiBFdmVudG8gamF2YXNjcmlwdCBwdXJvIHBhcmEgcmV0b3JubyBkbyBhcnF1aXZvXG4gICAqL1xuICBAT3V0cHV0KCkgZmlsZVNlbGVjdGVkOiBFdmVudEVtaXR0ZXI8VXBsb2FkSW5mb1R5cGVzW10+ID0gbmV3IEV2ZW50RW1pdHRlcjxcbiAgICBVcGxvYWRJbmZvVHlwZXNbXVxuICA+KCk7XG5cbiAgLyoqXG4gICAqIEBpZ25vcmVcbiAgICovXG4gIHRoZW1lOiBzdHJpbmcgPSAnJztcbiAgLyoqXG4gICAqIEBpZ25vcmVcbiAgICovXG4gIGlkOiBudW1iZXIgPSAwO1xuICAvKipcbiAgICogQGlnbm9yZVxuICAgKi9cbiAgaGlkZVByb2dyZXNzQmFyOiBib29sZWFuID0gZmFsc2U7XG4gIC8qKlxuICAgKiBAaWdub3JlXG4gICAqL1xuICBtYXhTaXplOiBudW1iZXIgPSAyMCAqIDEwMjQwMDA7IC8vIG1iIHRvIGJ5dGVzLlxuICAvKipcbiAgICogQGlnbm9yZVxuICAgKi9cbiAgdXBsb2FkQVBJOiBzdHJpbmcgPSAnJztcbiAgLyoqXG4gICAqIEBpZ25vcmVcbiAgICovXG4gIG1ldGhvZDogc3RyaW5nID0gJ1BPU1QnO1xuICAvKipcbiAgICogQGlnbm9yZVxuICAgKi9cbiAgZm9ybWF0c0FsbG93ZWQ6IHN0cmluZyA9ICcqJztcbiAgLyoqXG4gICAqIEBpZ25vcmVcbiAgICovXG4gIGZvcm1hdHNBbGxvd2VkVGV4dDogc3RyaW5nID0gJyc7XG4gIC8qKlxuICAgKiBAaWdub3JlXG4gICAqL1xuICBtdWx0aXBsZTogYm9vbGVhbiA9IGZhbHNlO1xuICAvKipcbiAgICogQGlnbm9yZVxuICAgKi9cbiAgaGVhZGVyczogSHR0cEhlYWRlcnMgfCB7IFtoZWFkZXI6IHN0cmluZ106IHN0cmluZyB8IHN0cmluZ1tdIH0gPSB7fTtcbiAgLyoqXG4gICAqIEBpZ25vcmVcbiAgICovXG4gIHBhcmFtczogSHR0cFBhcmFtcyB8IHsgW3BhcmFtOiBzdHJpbmddOiBzdHJpbmcgfCBzdHJpbmdbXSB9ID0ge307XG4gIC8qKlxuICAgKiBAaWdub3JlXG4gICAqL1xuICByZXNwb25zZVR5cGU6ICdqc29uJyB8ICdhcnJheWJ1ZmZlcicgfCAnYmxvYicgfCAndGV4dCcgPSAnYmxvYic7XG4gIC8qKlxuICAgKiBAaWdub3JlXG4gICAqL1xuICBoaWRlUmVzZXRCdG46IGJvb2xlYW4gPSBmYWxzZTtcbiAgLyoqXG4gICAqIEBpZ25vcmVcbiAgICovXG4gIGhpZGVTZWxlY3RCdG46IGJvb2xlYW4gPSBmYWxzZTtcbiAgLyoqXG4gICAqIEBpZ25vcmVcbiAgICovXG4gIGFsbG93ZWRGaWxlczogRmlsZVtdID0gW107XG4gIC8qKlxuICAgKiBAaWdub3JlXG4gICAqL1xuICBub3RBbGxvd2VkRmlsZXM6IHtcbiAgICBmaWxlTmFtZTogc3RyaW5nO1xuICAgIGZpbGVTaXplOiBzdHJpbmc7XG4gICAgZXJyb3JNc2c6IHN0cmluZztcbiAgfVtdID0gW107XG4gIC8qKlxuICAgKiBAaWdub3JlXG4gICAqL1xuICBDYXB0aW9uOiBzdHJpbmdbXSA9IFtdO1xuICAvKipcbiAgICogQGlnbm9yZVxuICAgKi9cbiAgaXNBbGxvd2VkRmlsZVNpbmdsZSA9IHRydWU7XG4gIC8qKlxuICAgKiBAaWdub3JlXG4gICAqL1xuICBwcm9ncmVzc0JhclNob3cgPSBmYWxzZTtcbiAgLyoqXG4gICAqIEBpZ25vcmVcbiAgICovXG4gIGVuYWJsZVVwbG9hZEJ0biA9IGZhbHNlO1xuICAvKipcbiAgICogQGlnbm9yZVxuICAgKi9cbiAgdXBsb2FkTXNnID0gZmFsc2U7XG4gIC8qKlxuICAgKiBAaWdub3JlXG4gICAqL1xuICBhZnRlclVwbG9hZCA9IGZhbHNlO1xuICAvKipcbiAgICogQGlnbm9yZVxuICAgKi9cbiAgdXBsb2FkU3RhcnRlZCA9IGZhbHNlO1xuICAvKipcbiAgICogQGlnbm9yZVxuICAgKi9cbiAgdXBsb2FkTXNnVGV4dDogc3RyaW5nID0gJyc7XG4gIC8qKlxuICAgKiBAaWdub3JlXG4gICAqL1xuICB1cGxvYWRNc2dDbGFzczogc3RyaW5nID0gJ3RleHQtc3VjY2Vzcyc7XG4gIC8qKlxuICAgKiBAaWdub3JlXG4gICAqL1xuICB1cGxvYWRQZXJjZW50OiBudW1iZXIgPSAwO1xuICAvKipcbiAgICogQGlnbm9yZVxuICAgKi9cbiAgcmVwbGFjZVRleHRzOiBSZXBsYWNlVGV4dHMgPSB7XG4gICAgc2VsZWN0RmlsZUJ0bjogJ1NlbGVjaW9uYXIgQXJxdWl2bycsXG4gICAgcmVzZXRCdG46ICdSZXNldGFyJyxcbiAgICB1cGxvYWRCdG46ICdFbnZpYXInLFxuICAgIGRyYWdORHJvcEJveDogJ0FycmFzdGUgZSBzb2x0ZScsXG4gICAgYXR0YWNoUGluQnRuOiAnQW5leGFyIEFycXVpdm8uLi4nLFxuICAgIGFmdGVyVXBsb2FkTXNnX3N1Y2Nlc3M6ICdFbnZpYWRvIGNvbSBzdWNlc3NvICEnLFxuICAgIGFmdGVyVXBsb2FkTXNnX2Vycm9yOiAnRmFsaGEgbm8gZW52aW8gIScsXG4gICAgc2l6ZUxpbWl0OiAnVGFtYW5obyBtw6F4aW1vJyxcbiAgfTtcbiAgLyoqXG4gICAqIEBpZ25vcmVcbiAgICovXG4gIGN1cnJlbnRVcGxvYWRzOiBhbnlbXSA9IFtdO1xuICAvKipcbiAgICogQGlnbm9yZVxuICAgKi9cbiAgZmlsZU5hbWVJbmRleCA9IHRydWU7XG4gIC8qKlxuICAgKiBAaWdub3JlXG4gICAqL1xuICB3aXRoQ3JlZGVudGlhbHMgPSBmYWxzZTtcbiAgLyoqXG4gICAqIEBpZ25vcmVcbiAgICovXG4gIGF1dG9VcGxvYWQgPSB0cnVlO1xuICAvKipcbiAgICogQGlnbm9yZVxuICAgKi9cbiAgcHJpdmF0ZSBpZERhdGU6IG51bWJlciA9ICtuZXcgRGF0ZSgpO1xuXG4gIGNvbnN0cnVjdG9yKEBTa2lwU2VsZigpIHByaXZhdGUgaHR0cDogSHR0cENsaWVudCkge31cblxuICAvKipcbiAgICogQGlnbm9yZVxuICAgKi9cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogYW55KSB7XG4gICAgLy8gVHJhY2sgY2hhbmdlcyBpbiBDb25maWd1cmF0aW9uIGFuZCBzZWUgaWYgdXNlciBoYXMgZXZlbiBwcm92aWRlZCBDb25maWd1cmF0aW9uLlxuICAgIGlmIChjaGFuZ2VzLmNvbmZpZyAmJiB0aGlzLmNvbmZpZykge1xuICAgICAgLy8gQXNzaWduIFVzZXIgQ29uZmlndXJhdGlvbnMgdG8gTGlicmFyeSBQcm9wZXJ0aWVzLlxuICAgICAgdGhpcy50aGVtZSA9IHRoaXMuY29uZmlnLnRoZW1lIHx8ICcnO1xuICAgICAgdGhpcy5pZCA9XG4gICAgICAgIHRoaXMuY29uZmlnLmlkIHx8XG4gICAgICAgIHBhcnNlSW50KCh0aGlzLmlkRGF0ZSAvIDEwMDAwKS50b1N0cmluZygpLnNwbGl0KCcuJylbMV0sIDEwKSArXG4gICAgICAgICAgTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogMjApICogMTAwMDA7XG4gICAgICB0aGlzLmhpZGVQcm9ncmVzc0JhciA9IHRoaXMuY29uZmlnLmhpZGVQcm9ncmVzc0JhciB8fCBmYWxzZTtcbiAgICAgIHRoaXMuaGlkZVJlc2V0QnRuID0gdGhpcy5jb25maWcuaGlkZVJlc2V0QnRuIHx8IGZhbHNlO1xuICAgICAgdGhpcy5oaWRlU2VsZWN0QnRuID0gdGhpcy5jb25maWcuaGlkZVNlbGVjdEJ0biB8fCBmYWxzZTtcbiAgICAgIHRoaXMubWF4U2l6ZSA9ICh0aGlzLmNvbmZpZy5tYXhTaXplIHx8IDIwKSAqIDEwMjQwMDA7IC8vIG1iIHRvIGJ5dGVzLlxuICAgICAgaWYgKHRoaXMuY29uZmlnLnVwbG9hZEFQSSkge1xuICAgICAgICB0aGlzLnVwbG9hZEFQSSA9IHRoaXMuY29uZmlnLnVwbG9hZEFQSS51cmw7XG4gICAgICAgIHRoaXMubWV0aG9kID0gdGhpcy5jb25maWcudXBsb2FkQVBJLm1ldGhvZCB8fCAnUE9TVCc7XG4gICAgICAgIHRoaXMuZm9ybWF0c0FsbG93ZWQgPSB0aGlzLmNvbmZpZy5mb3JtYXRzQWxsb3dlZCB8fCAnKic7XG4gICAgICAgIHRoaXMubXVsdGlwbGUgPSB0aGlzLmNvbmZpZy5tdWx0aXBsZSB8fCBmYWxzZTtcbiAgICAgICAgdGhpcy5oZWFkZXJzID0gdGhpcy5jb25maWcudXBsb2FkQVBJLmhlYWRlcnMgfHwge307XG4gICAgICAgIHRoaXMucGFyYW1zID0gdGhpcy5jb25maWcudXBsb2FkQVBJLnBhcmFtcyB8fCB7fTtcbiAgICAgICAgdGhpcy5yZXNwb25zZVR5cGUgPSB0aGlzLmNvbmZpZy51cGxvYWRBUEkucmVzcG9uc2VUeXBlIHx8ICdqc29uJztcbiAgICAgICAgdGhpcy53aXRoQ3JlZGVudGlhbHMgPSB0aGlzLmNvbmZpZy51cGxvYWRBUEkud2l0aENyZWRlbnRpYWxzIHx8IGZhbHNlO1xuICAgICAgfVxuICAgICAgdGhpcy5mb3JtYXRzQWxsb3dlZFRleHQgPVxuICAgICAgICB0aGlzLmZvcm1hdHNBbGxvd2VkID09PSAnKicgPyAnJyA6ICcoJyArIHRoaXMuZm9ybWF0c0FsbG93ZWQgKyAnKSc7XG4gICAgICB0aGlzLmZpbGVOYW1lSW5kZXggPSB0aGlzLmNvbmZpZy5maWxlTmFtZUluZGV4ID09PSBmYWxzZSA/IGZhbHNlIDogdHJ1ZTtcbiAgICAgIHRoaXMuYXV0b1VwbG9hZCA9IHRoaXMuY29uZmlnLmF1dG9VcGxvYWQgfHwgZmFsc2U7XG4gICAgICBpZiAodGhpcy5jb25maWcucmVwbGFjZVRleHRzKSB7XG4gICAgICAgIHRoaXMucmVwbGFjZVRleHRzID0ge1xuICAgICAgICAgIC4uLnRoaXMucmVwbGFjZVRleHRzLFxuICAgICAgICAgIC4uLnRoaXMuY29uZmlnLnJlcGxhY2VUZXh0cyxcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBSZXNldCB3aGVuIHJlc2V0VXBsb2FkIHZhbHVlIGNoYW5nZXMgZnJvbSBmYWxzZSB0byB0cnVlLlxuICAgIGlmIChjaGFuZ2VzLnJlc2V0VXBsb2FkKSB7XG4gICAgICBpZiAoY2hhbmdlcy5yZXNldFVwbG9hZC5jdXJyZW50VmFsdWUgPT09IHRydWUpIHtcbiAgICAgICAgdGhpcy5yZXNldEZpbGVVcGxvYWQoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKiBGdW7Dp8OjbyByZXNldGFyIGNvbXBvbmVudGUgKi9cbiAgcmVzZXRGaWxlVXBsb2FkKCkge1xuICAgIHRoaXMuYWxsb3dlZEZpbGVzID0gW107XG4gICAgdGhpcy5DYXB0aW9uID0gW107XG4gICAgdGhpcy5ub3RBbGxvd2VkRmlsZXMgPSBbXTtcbiAgICB0aGlzLnVwbG9hZE1zZyA9IGZhbHNlO1xuICAgIHRoaXMuZW5hYmxlVXBsb2FkQnRuID0gZmFsc2U7XG4gIH1cblxuICAvKiBEZXRlY3RhciBtdWRhbsOnYSAgKi9cbiAgb25DaGFuZ2UoZXZlbnQ6IGFueSkge1xuICAgIHRoaXMuZmlsZVNlbGVjdGVkLmVtaXQoZXZlbnQpO1xuICAgIHRoaXMubm90QWxsb3dlZEZpbGVzID0gW107XG4gICAgY29uc3QgZmlsZUV4dFJlZ0V4cDogUmVnRXhwID0gLyg/OlxcLihbXi5dKykpPyQvO1xuICAgIGxldCBmaWxlTGlzdDogRmlsZUxpc3Q7XG5cbiAgICBpZiAodGhpcy5hZnRlclVwbG9hZCB8fCAhdGhpcy5tdWx0aXBsZSkge1xuICAgICAgdGhpcy5hbGxvd2VkRmlsZXMgPSBbXTtcbiAgICAgIHRoaXMuQ2FwdGlvbiA9IFtdO1xuICAgICAgdGhpcy5hZnRlclVwbG9hZCA9IGZhbHNlO1xuICAgIH1cblxuICAgIGlmIChldmVudC50eXBlID09PSAnZHJvcCcpIHtcbiAgICAgIGZpbGVMaXN0ID0gZXZlbnQuZGF0YVRyYW5zZmVyLmZpbGVzO1xuICAgIH0gZWxzZSB7XG4gICAgICBmaWxlTGlzdCA9IGV2ZW50LnRhcmdldC5maWxlcyB8fCBldmVudC5zcmNFbGVtZW50LmZpbGVzO1xuICAgIH1cblxuICAgIC8vICdmb3JFYWNoJyBkb2VzIG5vdCBleGlzdCBvbiAnZmlsZWxpc3QnIHRoYXQncyB3aHkgdGhpcyBnb29kIG9sZCAnZm9yJyBpcyB1c2VkLlxuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTogZm9yLW9mXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBmaWxlTGlzdC5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgX2N1cnJlbnRGaWxlRXh0OiBhbnkgPSBmaWxlRXh0UmVnRXhwLmV4ZWMoZmlsZUxpc3RbaV0ubmFtZSk7XG4gICAgICBjb25zdCBjdXJyZW50RmlsZUV4dCA9XG4gICAgICAgIHR5cGVvZiBfY3VycmVudEZpbGVFeHRbMV0gPT09ICdzdHJpbmcnXG4gICAgICAgICAgPyBfY3VycmVudEZpbGVFeHRbMV0udG9Mb3dlckNhc2UoKVxuICAgICAgICAgIDogJyc7XG4gICAgICBjb25zdCBpc0Zvcm1hdFZhbGlkID0gdGhpcy5mb3JtYXRzQWxsb3dlZC5pbmNsdWRlcygnKicpXG4gICAgICAgID8gdHJ1ZVxuICAgICAgICA6IHRoaXMuZm9ybWF0c0FsbG93ZWQuaW5jbHVkZXMoY3VycmVudEZpbGVFeHQpO1xuXG4gICAgICBjb25zdCBpc1NpemVWYWxpZCA9IGZpbGVMaXN0W2ldLnNpemUgPD0gdGhpcy5tYXhTaXplO1xuXG4gICAgICAvLyBDaGVjayB3aGV0aGVyIGN1cnJlbnQgZmlsZSBmb3JtYXQgYW5kIHNpemUgaXMgY29ycmVjdCBhcyBzcGVjaWZpZWQgaW4gdGhlIGNvbmZpZ3VyYXRpb25zLlxuICAgICAgaWYgKGlzRm9ybWF0VmFsaWQgJiYgaXNTaXplVmFsaWQpIHtcbiAgICAgICAgdGhpcy5hbGxvd2VkRmlsZXMucHVzaChmaWxlTGlzdFtpXSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLm5vdEFsbG93ZWRGaWxlcy5wdXNoKHtcbiAgICAgICAgICBmaWxlTmFtZTogZmlsZUxpc3RbaV0ubmFtZSxcbiAgICAgICAgICBmaWxlU2l6ZTogdGhpcy5jb252ZXJ0U2l6ZShmaWxlTGlzdFtpXS5zaXplKSxcbiAgICAgICAgICBlcnJvck1zZzogIWlzRm9ybWF0VmFsaWQgPyAnSW52YWxpZCBmb3JtYXQnIDogJ0ludmFsaWQgc2l6ZScsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIElmIHRoZXJlJ3MgYW55IGFsbG93ZWRGaWxlcy5cbiAgICBpZiAodGhpcy5hbGxvd2VkRmlsZXMubGVuZ3RoID4gMCkge1xuICAgICAgdGhpcy5lbmFibGVVcGxvYWRCdG4gPSB0cnVlO1xuICAgICAgLy8gVXBsb2FkIHRoZSBmaWxlcyBkaXJlY3RseSBpZiB0aGVtZSBpcyBhdHRhY2ggcGluIChhcyB1cGxvYWQgYnRuIGlzIG5vdCB0aGVyZSBmb3IgdGhpcyB0aGVtZSkgb3IgYXV0b1VwbG9hZCBpcyB0cnVlLlxuICAgICAgaWYgKHRoaXMudGhlbWUgPT09ICdhdHRhY2hQaW4nIHx8IHRoaXMuYXV0b1VwbG9hZCkge1xuICAgICAgICB0aGlzLnVwbG9hZEZpbGVzKCk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuZW5hYmxlVXBsb2FkQnRuID0gZmFsc2U7XG4gICAgfVxuXG4gICAgdGhpcy51cGxvYWRNc2cgPSBmYWxzZTtcbiAgICB0aGlzLnVwbG9hZFN0YXJ0ZWQgPSBmYWxzZTtcbiAgICB0aGlzLnVwbG9hZFBlcmNlbnQgPSAwO1xuICAgIGV2ZW50LnRhcmdldC52YWx1ZSA9IG51bGw7XG4gIH1cblxuICAvKiBGdW7Dp8OjbyBwYXJhIGVudmlhciBhcnF1aXZvIHBhcmEgc2Vydmlkb3IgKi9cbiAgdXBsb2FkRmlsZXMoKSB7XG4gICAgdGhpcy5wcm9ncmVzc0JhclNob3cgPSB0cnVlO1xuICAgIHRoaXMudXBsb2FkU3RhcnRlZCA9IHRydWU7XG4gICAgdGhpcy5ub3RBbGxvd2VkRmlsZXMgPSBbXTtcbiAgICBsZXQgaXNFcnJvciA9IGZhbHNlO1xuICAgIHRoaXMuaXNBbGxvd2VkRmlsZVNpbmdsZSA9IHRoaXMuYWxsb3dlZEZpbGVzLmxlbmd0aCA8PSAxO1xuICAgIGNvbnN0IGZvcm1EYXRhID0gbmV3IEZvcm1EYXRhKCk7XG5cbiAgICAvLyBBZGQgZGF0YSB0byBiZSBzZW50IGluIHRoaXMgcmVxdWVzdFxuICAgIHRoaXMuYWxsb3dlZEZpbGVzLmZvckVhY2goKGZpbGUsIGkpID0+IHtcbiAgICAgIGZvcm1EYXRhLmFwcGVuZChcbiAgICAgICAgdGhpcy5DYXB0aW9uW2ldIHx8ICdmaWxlJyArICh0aGlzLmZpbGVOYW1lSW5kZXggPyBpIDogJycpLFxuICAgICAgICB0aGlzLmFsbG93ZWRGaWxlc1tpXVxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIHRoaXMuaHR0cFxuICAgICAgLnJlcXVlc3QodGhpcy5tZXRob2QudG9VcHBlckNhc2UoKSwgdGhpcy51cGxvYWRBUEksIHtcbiAgICAgICAgYm9keTogZm9ybURhdGEsXG4gICAgICAgIHJlcG9ydFByb2dyZXNzOiB0cnVlLFxuICAgICAgICBvYnNlcnZlOiAnZXZlbnRzJyxcbiAgICAgICAgaGVhZGVyczogdGhpcy5oZWFkZXJzLFxuICAgICAgICBwYXJhbXM6IHRoaXMucGFyYW1zLFxuICAgICAgICByZXNwb25zZVR5cGU6IHRoaXMucmVzcG9uc2VUeXBlLFxuICAgICAgICB3aXRoQ3JlZGVudGlhbHM6IHRoaXMud2l0aENyZWRlbnRpYWxzLFxuICAgICAgfSlcbiAgICAgIC5zdWJzY3JpYmUoXG4gICAgICAgIChldmVudCkgPT4ge1xuICAgICAgICAgIC8vIFVwbG9hZCBQcm9ncmVzc1xuICAgICAgICAgIGlmIChldmVudC50eXBlID09PSBIdHRwRXZlbnRUeXBlLlVwbG9hZFByb2dyZXNzKSB7XG4gICAgICAgICAgICB0aGlzLmVuYWJsZVVwbG9hZEJ0biA9IGZhbHNlOyAvLyBidXR0b24gc2hvdWxkIGJlIGRpc2FibGVkIGlmIHByb2Nlc3MgdXBsb2FkaW5nXG4gICAgICAgICAgICBjb25zdCBjdXJyZW50RG9uZSA9IGV2ZW50LmxvYWRlZCAvIGV2ZW50LnRvdGFsO1xuICAgICAgICAgICAgdGhpcy51cGxvYWRQZXJjZW50ID0gTWF0aC5yb3VuZCgoZXZlbnQubG9hZGVkIC8gZXZlbnQudG90YWwpICogMTAwKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKGV2ZW50LnR5cGUgPT09IEh0dHBFdmVudFR5cGUuUmVzcG9uc2UpIHtcbiAgICAgICAgICAgIGlmIChldmVudC5zdGF0dXMgPT09IDIwMCB8fCBldmVudC5zdGF0dXMgPT09IDIwMSkge1xuICAgICAgICAgICAgICAvLyBTdWNjZXNzXG4gICAgICAgICAgICAgIHRoaXMucHJvZ3Jlc3NCYXJTaG93ID0gZmFsc2U7XG4gICAgICAgICAgICAgIHRoaXMuZW5hYmxlVXBsb2FkQnRuID0gZmFsc2U7XG4gICAgICAgICAgICAgIHRoaXMudXBsb2FkTXNnID0gdHJ1ZTtcbiAgICAgICAgICAgICAgdGhpcy5hZnRlclVwbG9hZCA9IHRydWU7XG4gICAgICAgICAgICAgIGlmICghaXNFcnJvcikge1xuICAgICAgICAgICAgICAgIHRoaXMudXBsb2FkTXNnVGV4dCA9XG4gICAgICAgICAgICAgICAgICB0aGlzLnJlcGxhY2VUZXh0cy5hZnRlclVwbG9hZE1zZ19zdWNjZXNzIHx8XG4gICAgICAgICAgICAgICAgICAnU3VjY2Vzc2Z1bGx5IFVwbG9hZGVkICEnO1xuICAgICAgICAgICAgICAgIHRoaXMudXBsb2FkTXNnQ2xhc3MgPSAndGV4dC1zdWNjZXNzIGxlYWQnO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAvLyBGYWlsdXJlXG4gICAgICAgICAgICAgIGlzRXJyb3IgPSB0cnVlO1xuICAgICAgICAgICAgICB0aGlzLmhhbmRsZUVycm9ycygpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5BcGlSZXNwb25zZS5lbWl0KGV2ZW50KTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy9jb25zb2xlLmxvZygnRXZlbnQgT3RoZXI6ICcsIGV2ZW50KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIChlcnJvcikgPT4ge1xuICAgICAgICAgIC8vIEZhaWx1cmVcbiAgICAgICAgICBpc0Vycm9yID0gdHJ1ZTtcbiAgICAgICAgICB0aGlzLmhhbmRsZUVycm9ycygpO1xuICAgICAgICAgIHRoaXMuQXBpUmVzcG9uc2UuZW1pdChlcnJvcik7XG4gICAgICAgIH1cbiAgICAgICk7XG4gIH1cblxuICBoYW5kbGVFcnJvcnMoKSB7XG4gICAgdGhpcy5wcm9ncmVzc0JhclNob3cgPSBmYWxzZTtcbiAgICB0aGlzLmVuYWJsZVVwbG9hZEJ0biA9IGZhbHNlO1xuICAgIHRoaXMudXBsb2FkTXNnID0gdHJ1ZTtcbiAgICB0aGlzLmFmdGVyVXBsb2FkID0gdHJ1ZTtcbiAgICB0aGlzLnVwbG9hZE1zZ1RleHQgPVxuICAgICAgdGhpcy5yZXBsYWNlVGV4dHMuYWZ0ZXJVcGxvYWRNc2dfZXJyb3IgfHwgJ0Vycm9yIGluIHVwbG9hZGluZyBmaWxlcyc7XG4gICAgdGhpcy51cGxvYWRNc2dDbGFzcyA9ICd0ZXh0LWRhbmdlciBsZWFkJztcbiAgfVxuXG4gIHJlbW92ZUZpbGUoaTogYW55LCBzZl9uYTogYW55KSB7XG4gICAgaWYgKHNmX25hID09PSAnc2YnKSB7XG4gICAgICB0aGlzLmFsbG93ZWRGaWxlcy5zcGxpY2UoaSwgMSk7XG4gICAgICB0aGlzLkNhcHRpb24uc3BsaWNlKGksIDEpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLm5vdEFsbG93ZWRGaWxlcy5zcGxpY2UoaSwgMSk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuYWxsb3dlZEZpbGVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhpcy5lbmFibGVVcGxvYWRCdG4gPSBmYWxzZTtcbiAgICB9XG4gIH1cblxuICBjb252ZXJ0U2l6ZShmaWxlU2l6ZTogbnVtYmVyKTogc3RyaW5nIHtcbiAgICByZXR1cm4gZmlsZVNpemUgPCAxMDI0MDAwXG4gICAgICA/IChmaWxlU2l6ZSAvIDEwMjQpLnRvRml4ZWQoMikgKyAnIEtCJ1xuICAgICAgOiAoZmlsZVNpemUgLyAxMDI0MDAwKS50b0ZpeGVkKDIpICsgJyBNQic7XG4gIH1cblxuICBhdHRhY2hwaW5PbmNsaWNrKCkge1xuICAgIGNvbnN0IGVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2VsJyArIHRoaXMuaWQpO1xuICAgIGlmIChlbGVtZW50ICE9PSBudWxsKSB7XG4gICAgICBlbGVtZW50LmNsaWNrKCk7XG4gICAgfVxuICB9XG5cbiAgZHJvcChldmVudDogYW55KSB7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICB0aGlzLm9uQ2hhbmdlKGV2ZW50KTtcbiAgfVxuXG4gIGFsbG93RHJvcChldmVudDogYW55KSB7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICBldmVudC5kYXRhVHJhbnNmZXIuZHJvcEVmZmVjdCA9ICdjb3B5JztcbiAgfVxufVxuIiwiPGxhYmVsIGZvcj1cInNlbHt7aWR9fVwiIGNsYXNzPVwid2NvLWZvcm0tdXBsb2FkXCIgKGRyb3ApPVwiZHJvcCgkZXZlbnQpXCIgKGRyYWdvdmVyKT1cImFsbG93RHJvcCgkZXZlbnQpXCI+XG4gIDxkaXYgY2xhc3M9XCJ3Y28tZm9ybS11cGxvYWRfX2luZm9cIj5cbiAgICA8c3Bhbj5BcnJhc3RlLW9zIGFxdWkgb3U8L3NwYW4+XG4gICAgPHNwYW4+XG4gICAgICA8c3BhbiBjbGFzcz1cIm1hdGVyaWFsLWljb25zLW91dGxpbmVkXCI+XG51cGxvYWRfZmlsZVxuPC9zcGFuPlxuICAgICAgPHNwYW4+e3tyZXBsYWNlVGV4dHMuc2VsZWN0RmlsZUJ0bn19PC9zcGFuPlxuICAgIDwvc3Bhbj5cbiAgPC9kaXY+XG4gIDxzcGFuIGNsYXNzPVwidXBsb2FkX19pbmZvXCIgKm5nSWY9XCIhYWxsb3dlZEZpbGVzLmxlbmd0aFwiID57e2Rlc2NyaXB0aW9ufX08L3NwYW4+XG4gIDxuZy1jb250YWluZXIgKm5nSWY9XCJhbGxvd2VkRmlsZXMubGVuZ3RoXCI+XG4gICAgPHNwYW4gY2xhc3M9XCJ1cGxvYWRfX2luZm9cIiAqbmdGb3I9XCJsZXQgc2Ygb2YgYWxsb3dlZEZpbGVzO2xldCBpPWluZGV4XCI+XG4gICAgICB7e3NmLm5hbWV9fSA8c21hbGw+KHt7Y29udmVydFNpemUoc2Yuc2l6ZSl9fSk8L3NtYWxsPlxuICAgIDwvc3Bhbj5cbiAgPC9uZy1jb250YWluZXI+XG4gIDxpbnB1dCB0eXBlPVwiZmlsZVwiIGlkPVwic2Vse3tpZH19XCIgKGNoYW5nZSk9XCJvbkNoYW5nZSgkZXZlbnQpXCIgc3R5bGU9XCJkaXNwbGF5OiBub25lXCIgdGl0bGU9XCJTZWxlY3QgZmlsZVwiXG4gIG5hbWU9XCJmaWxlc1tdXCIgW2FjY2VwdF09XCJmb3JtYXRzQWxsb3dlZFwiIFthdHRyLm11bHRpcGxlXT1cIm11bHRpcGxlID8gJycgOiBudWxsXCIgLz5cbjwvbGFiZWw+Il19