ng-zorro-antd
Version:
An enterprise-class UI components based on Ant Design and Angular
328 lines • 44.5 kB
JavaScript
/**
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE
*/
import { ENTER } from '@angular/cdk/keycodes';
import { HttpEventType, HttpHeaders, HttpRequest, HttpResponse } from '@angular/common/http';
import { Component, Input, Optional, ViewChild, ViewEncapsulation } from '@angular/core';
import { fromEvent, Observable, of, Subject, Subscription } from 'rxjs';
import { map, switchMap, takeUntil, tap } from 'rxjs/operators';
import { warn } from 'ng-zorro-antd/core/logger';
import * as i0 from "@angular/core";
import * as i1 from "@angular/common/http";
export class NzUploadBtnComponent {
constructor(ngZone, http, elementRef) {
this.ngZone = ngZone;
this.http = http;
this.elementRef = elementRef;
this.reqs = {};
this.destroy = false;
this.destroy$ = new Subject();
if (!http) {
throw new Error(`Not found 'HttpClient', You can import 'HttpClientModule' in your root module.`);
}
}
onClick() {
if (this.options.disabled || !this.options.openFileDialogOnClick) {
return;
}
this.file.nativeElement.click();
}
// skip safari bug
onFileDrop(e) {
if (this.options.disabled || e.type === 'dragover') {
e.preventDefault();
return;
}
if (this.options.directory) {
this.traverseFileTree(e.dataTransfer.items);
}
else {
const files = Array.prototype.slice
.call(e.dataTransfer.files)
.filter((file) => this.attrAccept(file, this.options.accept));
if (files.length) {
this.uploadFiles(files);
}
}
e.preventDefault();
}
onChange(e) {
if (this.options.disabled) {
return;
}
const hie = e.target;
this.uploadFiles(hie.files);
hie.value = '';
}
traverseFileTree(files) {
const _traverseFileTree = (item, path) => {
if (item.isFile) {
item.file((file) => {
if (this.attrAccept(file, this.options.accept)) {
this.uploadFiles([file]);
}
});
}
else if (item.isDirectory) {
const dirReader = item.createReader();
dirReader.readEntries((entries) => {
for (const entrieItem of entries) {
_traverseFileTree(entrieItem, `${path}${item.name}/`);
}
});
}
};
for (const file of files) {
_traverseFileTree(file.webkitGetAsEntry(), '');
}
}
attrAccept(file, acceptedFiles) {
if (file && acceptedFiles) {
const acceptedFilesArray = Array.isArray(acceptedFiles) ? acceptedFiles : acceptedFiles.split(',');
const fileName = `${file.name}`;
const mimeType = `${file.type}`;
const baseMimeType = mimeType.replace(/\/.*$/, '');
return acceptedFilesArray.some(type => {
const validType = type.trim();
if (validType.charAt(0) === '.') {
return (fileName
.toLowerCase()
.indexOf(validType.toLowerCase(), fileName.toLowerCase().length - validType.toLowerCase().length) !== -1);
}
else if (/\/\*$/.test(validType)) {
// This is something like a image/* mime type
return baseMimeType === validType.replace(/\/.*$/, '');
}
return mimeType === validType;
});
}
return true;
}
attachUid(file) {
if (!file.uid) {
file.uid = Math.random().toString(36).substring(2);
}
return file;
}
uploadFiles(fileList) {
let filters$ = of(Array.prototype.slice.call(fileList));
if (this.options.filters) {
this.options.filters.forEach(f => {
filters$ = filters$.pipe(switchMap(list => {
const fnRes = f.fn(list);
return fnRes instanceof Observable ? fnRes : of(fnRes);
}));
});
}
filters$.subscribe(list => {
list.forEach((file) => {
this.attachUid(file);
this.upload(file, list);
});
}, e => {
warn(`Unhandled upload filter error`, e);
});
}
upload(file, fileList) {
if (!this.options.beforeUpload) {
return this.post(file);
}
const before = this.options.beforeUpload(file, fileList);
if (before instanceof Observable) {
before.subscribe((processedFile) => {
const processedFileType = Object.prototype.toString.call(processedFile);
if (processedFileType === '[object File]' || processedFileType === '[object Blob]') {
this.attachUid(processedFile);
this.post(processedFile);
}
else if (typeof processedFile === 'boolean' && processedFile !== false) {
this.post(file);
}
}, e => {
warn(`Unhandled upload beforeUpload error`, e);
});
}
else if (before !== false) {
return this.post(file);
}
}
post(file) {
if (this.destroy) {
return;
}
let process$ = of(file);
let transformedFile;
const opt = this.options;
const { uid } = file;
const { action, data, headers, transformFile } = opt;
const args = {
action: typeof action === 'string' ? action : '',
name: opt.name,
headers,
file,
postFile: file,
data,
withCredentials: opt.withCredentials,
onProgress: opt.onProgress
? e => {
opt.onProgress(e, file);
}
: undefined,
onSuccess: (ret, xhr) => {
this.clean(uid);
opt.onSuccess(ret, file, xhr);
},
onError: xhr => {
this.clean(uid);
opt.onError(xhr, file);
}
};
if (typeof action === 'function') {
const actionResult = action(file);
if (actionResult instanceof Observable) {
process$ = process$.pipe(switchMap(() => actionResult), map(res => {
args.action = res;
return file;
}));
}
else {
args.action = actionResult;
}
}
if (typeof transformFile === 'function') {
const transformResult = transformFile(file);
process$ = process$.pipe(switchMap(() => (transformResult instanceof Observable ? transformResult : of(transformResult))), tap(newFile => (transformedFile = newFile)));
}
if (typeof data === 'function') {
const dataResult = data(file);
if (dataResult instanceof Observable) {
process$ = process$.pipe(switchMap(() => dataResult), map(res => {
args.data = res;
return transformedFile ?? file;
}));
}
else {
args.data = dataResult;
}
}
if (typeof headers === 'function') {
const headersResult = headers(file);
if (headersResult instanceof Observable) {
process$ = process$.pipe(switchMap(() => headersResult), map(res => {
args.headers = res;
return transformedFile ?? file;
}));
}
else {
args.headers = headersResult;
}
}
process$.subscribe(newFile => {
args.postFile = newFile;
const req$ = (opt.customRequest || this.xhr).call(this, args);
if (!(req$ instanceof Subscription)) {
warn(`Must return Subscription type in '[nzCustomRequest]' property`);
}
this.reqs[uid] = req$;
opt.onStart(file);
});
}
xhr(args) {
const formData = new FormData();
if (args.data) {
Object.keys(args.data).map(key => {
formData.append(key, args.data[key]);
});
}
formData.append(args.name, args.postFile);
if (!args.headers) {
args.headers = {};
}
if (args.headers['X-Requested-With'] !== null) {
args.headers['X-Requested-With'] = `XMLHttpRequest`;
}
else {
delete args.headers['X-Requested-With'];
}
const req = new HttpRequest('POST', args.action, formData, {
reportProgress: true,
withCredentials: args.withCredentials,
headers: new HttpHeaders(args.headers)
});
return this.http.request(req).subscribe((event) => {
if (event.type === HttpEventType.UploadProgress) {
if (event.total > 0) {
event.percent = (event.loaded / event.total) * 100;
}
args.onProgress(event, args.file);
}
else if (event instanceof HttpResponse) {
args.onSuccess(event.body, args.file, event);
}
}, err => {
this.abort(args.file);
args.onError(err, args.file);
});
}
clean(uid) {
const req$ = this.reqs[uid];
if (req$ instanceof Subscription) {
req$.unsubscribe();
}
delete this.reqs[uid];
}
abort(file) {
if (file) {
this.clean(file && file.uid);
}
else {
Object.keys(this.reqs).forEach(uid => this.clean(uid));
}
}
ngOnInit() {
// Caretaker note: `input[type=file].click()` will open a native OS file picker,
// it doesn't require Angular to run `ApplicationRef.tick()`.
this.ngZone.runOutsideAngular(() => {
fromEvent(this.elementRef.nativeElement, 'click')
.pipe(takeUntil(this.destroy$))
.subscribe(() => this.onClick());
fromEvent(this.elementRef.nativeElement, 'keydown')
.pipe(takeUntil(this.destroy$))
.subscribe(event => {
if (this.options.disabled) {
return;
}
if (event.key === 'Enter' || event.keyCode === ENTER) {
this.onClick();
}
});
});
}
ngOnDestroy() {
this.destroy = true;
this.destroy$.next();
this.abort();
}
}
NzUploadBtnComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: NzUploadBtnComponent, deps: [{ token: i0.NgZone }, { token: i1.HttpClient, optional: true }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
NzUploadBtnComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.5", type: NzUploadBtnComponent, selector: "[nz-upload-btn]", inputs: { options: "options" }, host: { listeners: { "drop": "onFileDrop($event)", "dragover": "onFileDrop($event)" }, properties: { "attr.tabindex": "\"0\"", "attr.role": "\"button\"", "class.ant-upload-disabled": "options.disabled" }, classAttribute: "ant-upload" }, viewQueries: [{ propertyName: "file", first: true, predicate: ["file"], descendants: true, static: true }], exportAs: ["nzUploadBtn"], ngImport: i0, template: "<input\n type=\"file\"\n #file\n (change)=\"onChange($event)\"\n [attr.accept]=\"options.accept\"\n [attr.directory]=\"options.directory ? 'directory' : null\"\n [attr.webkitdirectory]=\"options.directory ? 'webkitdirectory' : null\"\n [multiple]=\"options.multiple\"\n style=\"display: none\"\n/>\n<ng-content></ng-content>\n", encapsulation: i0.ViewEncapsulation.None });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.5", ngImport: i0, type: NzUploadBtnComponent, decorators: [{
type: Component,
args: [{ selector: '[nz-upload-btn]', exportAs: 'nzUploadBtn', host: {
class: 'ant-upload',
'[attr.tabindex]': '"0"',
'[attr.role]': '"button"',
'[class.ant-upload-disabled]': 'options.disabled',
'(drop)': 'onFileDrop($event)',
'(dragover)': 'onFileDrop($event)'
}, preserveWhitespaces: false, encapsulation: ViewEncapsulation.None, template: "<input\n type=\"file\"\n #file\n (change)=\"onChange($event)\"\n [attr.accept]=\"options.accept\"\n [attr.directory]=\"options.directory ? 'directory' : null\"\n [attr.webkitdirectory]=\"options.directory ? 'webkitdirectory' : null\"\n [multiple]=\"options.multiple\"\n style=\"display: none\"\n/>\n<ng-content></ng-content>\n" }]
}], ctorParameters: function () { return [{ type: i0.NgZone }, { type: i1.HttpClient, decorators: [{
type: Optional
}] }, { type: i0.ElementRef }]; }, propDecorators: { file: [{
type: ViewChild,
args: ['file', { static: true }]
}], options: [{
type: Input
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXBsb2FkLWJ0bi5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9jb21wb25lbnRzL3VwbG9hZC91cGxvYWQtYnRuLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uL2NvbXBvbmVudHMvdXBsb2FkL3VwbG9hZC1idG4uY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7OztHQUdHO0FBRUgsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQzlDLE9BQU8sRUFBeUIsYUFBYSxFQUFFLFdBQVcsRUFBRSxXQUFXLEVBQUUsWUFBWSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDcEgsT0FBTyxFQUNMLFNBQVMsRUFFVCxLQUFLLEVBSUwsUUFBUSxFQUNSLFNBQVMsRUFDVCxpQkFBaUIsRUFDbEIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsRUFBRSxFQUFFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDeEUsT0FBTyxFQUFFLEdBQUcsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLEdBQUcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRWhFLE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQzs7O0FBb0JqRCxNQUFNLE9BQU8sb0JBQW9CO0lBZ1QvQixZQUFvQixNQUFjLEVBQXNCLElBQWdCLEVBQVUsVUFBc0I7UUFBcEYsV0FBTSxHQUFOLE1BQU0sQ0FBUTtRQUFzQixTQUFJLEdBQUosSUFBSSxDQUFZO1FBQVUsZUFBVSxHQUFWLFVBQVUsQ0FBWTtRQS9TeEcsU0FBSSxHQUFvQyxFQUFFLENBQUM7UUFDbkMsWUFBTyxHQUFHLEtBQUssQ0FBQztRQUNoQixhQUFRLEdBQUcsSUFBSSxPQUFPLEVBQVEsQ0FBQztRQThTckMsSUFBSSxDQUFDLElBQUksRUFBRTtZQUNULE1BQU0sSUFBSSxLQUFLLENBQUMs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RSxLQUFLO3dCQUN4QixhQUFhLEVBQUUsVUFBVTt3QkFDekIsNkJBQTZCLEVBQUUsa0JBQWtCO3dCQUNqRCxRQUFRLEVBQUUsb0JBQW9CO3dCQUM5QixZQUFZLEVBQUUsb0JBQW9CO3FCQUNuQyx1QkFDb0IsS0FBSyxpQkFDWCxpQkFBaUIsQ0FBQyxJQUFJOzswQkFrVEEsUUFBUTtxRUE1U1IsSUFBSTtzQkFBeEMsU0FBUzt1QkFBQyxNQUFNLEVBQUUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFO2dCQUMxQixPQUFPO3NCQUFmLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vZ2l0aHViLmNvbS9ORy1aT1JSTy9uZy16b3Jyby1hbnRkL2Jsb2IvbWFzdGVyL0xJQ0VOU0VcbiAqL1xuXG5pbXBvcnQgeyBFTlRFUiB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9rZXljb2Rlcyc7XG5pbXBvcnQgeyBIdHRwQ2xpZW50LCBIdHRwRXZlbnQsIEh0dHBFdmVudFR5cGUsIEh0dHBIZWFkZXJzLCBIdHRwUmVxdWVzdCwgSHR0cFJlc3BvbnNlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uL2h0dHAnO1xuaW1wb3J0IHtcbiAgQ29tcG9uZW50LFxuICBFbGVtZW50UmVmLFxuICBJbnB1dCxcbiAgTmdab25lLFxuICBPbkluaXQsXG4gIE9uRGVzdHJveSxcbiAgT3B0aW9uYWwsXG4gIFZpZXdDaGlsZCxcbiAgVmlld0VuY2Fwc3VsYXRpb25cbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBmcm9tRXZlbnQsIE9ic2VydmFibGUsIG9mLCBTdWJqZWN0LCBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IG1hcCwgc3dpdGNoTWFwLCB0YWtlVW50aWwsIHRhcCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuaW1wb3J0IHsgd2FybiB9IGZyb20gJ25nLXpvcnJvLWFudGQvY29yZS9sb2dnZXInO1xuaW1wb3J0IHsgTnpTYWZlQW55IH0gZnJvbSAnbmctem9ycm8tYW50ZC9jb3JlL3R5cGVzJztcblxuaW1wb3J0IHsgTnpVcGxvYWRGaWxlLCBOelVwbG9hZFhIUkFyZ3MsIFppcEJ1dHRvbk9wdGlvbnMgfSBmcm9tICcuL2ludGVyZmFjZSc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ1tuei11cGxvYWQtYnRuXScsXG4gIGV4cG9ydEFzOiAnbnpVcGxvYWRCdG4nLFxuICB0ZW1wbGF0ZVVybDogJy4vdXBsb2FkLWJ0bi5jb21wb25lbnQuaHRtbCcsXG4gIGhvc3Q6IHtcbiAgICBjbGFzczogJ2FudC11cGxvYWQnLFxuICAgICdbYXR0ci50YWJpbmRleF0nOiAnXCIwXCInLFxuICAgICdbYXR0ci5yb2xlXSc6ICdcImJ1dHRvblwiJyxcbiAgICAnW2NsYXNzLmFudC11cGxvYWQtZGlzYWJsZWRdJzogJ29wdGlvbnMuZGlzYWJsZWQnLFxuICAgICcoZHJvcCknOiAnb25GaWxlRHJvcCgkZXZlbnQpJyxcbiAgICAnKGRyYWdvdmVyKSc6ICdvbkZpbGVEcm9wKCRldmVudCknXG4gIH0sXG4gIHByZXNlcnZlV2hpdGVzcGFjZXM6IGZhbHNlLFxuICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lXG59KVxuZXhwb3J0IGNsYXNzIE56VXBsb2FkQnRuQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3kge1xuICByZXFzOiB7IFtrZXk6IHN0cmluZ106IFN1YnNjcmlwdGlvbiB9ID0ge307XG4gIHByaXZhdGUgZGVzdHJveSA9IGZhbHNlO1xuICBwcml2YXRlIGRlc3Ryb3kkID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcbiAgQFZpZXdDaGlsZCgnZmlsZScsIHsgc3RhdGljOiB0cnVlIH0pIGZpbGUhOiBFbGVtZW50UmVmPEhUTUxJbnB1dEVsZW1lbnQ+O1xuICBASW5wdXQoKSBvcHRpb25zITogWmlwQnV0dG9uT3B0aW9ucztcblxuICBvbkNsaWNrKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLm9wdGlvbnMuZGlzYWJsZWQgfHwgIXRoaXMub3B0aW9ucy5vcGVuRmlsZURpYWxvZ09uQ2xpY2spIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5maWxlLm5hdGl2ZUVsZW1lbnQuY2xpY2soKTtcbiAgfVxuXG4gIC8vIHNraXAgc2FmYXJpIGJ1Z1xuICBvbkZpbGVEcm9wKGU6IERyYWdFdmVudCk6IHZvaWQge1xuICAgIGlmICh0aGlzLm9wdGlvbnMuZGlzYWJsZWQgfHwgZS50eXBlID09PSAnZHJhZ292ZXInKSB7XG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICh0aGlzLm9wdGlvbnMuZGlyZWN0b3J5KSB7XG4gICAgICB0aGlzLnRyYXZlcnNlRmlsZVRyZWUoZS5kYXRhVHJhbnNmZXIhLml0ZW1zKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgZmlsZXM6IEZpbGVbXSA9IEFycmF5LnByb3RvdHlwZS5zbGljZVxuICAgICAgICAuY2FsbChlLmRhdGFUcmFuc2ZlciEuZmlsZXMpXG4gICAgICAgIC5maWx0ZXIoKGZpbGU6IEZpbGUpID0+IHRoaXMuYXR0ckFjY2VwdChmaWxlLCB0aGlzLm9wdGlvbnMuYWNjZXB0KSk7XG4gICAgICBpZiAoZmlsZXMubGVuZ3RoKSB7XG4gICAgICAgIHRoaXMudXBsb2FkRmlsZXMoZmlsZXMpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgfVxuXG4gIG9uQ2hhbmdlKGU6IEV2ZW50KTogdm9pZCB7XG4gICAgaWYgKHRoaXMub3B0aW9ucy5kaXNhYmxlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBoaWUgPSBlLnRhcmdldCBhcyBIVE1MSW5wdXRFbGVtZW50O1xuICAgIHRoaXMudXBsb2FkRmlsZXMoaGllLmZpbGVzISk7XG4gICAgaGllLnZhbHVlID0gJyc7XG4gIH1cblxuICBwcml2YXRlIHRyYXZlcnNlRmlsZVRyZWUoZmlsZXM6IERhdGFUcmFuc2Zlckl0ZW1MaXN0KTogdm9pZCB7XG4gICAgY29uc3QgX3RyYXZlcnNlRmlsZVRyZWUgPSAoaXRlbTogTnpTYWZlQW55LCBwYXRoOiBzdHJpbmcpOiB2b2lkID0+IHtcbiAgICAgIGlmIChpdGVtLmlzRmlsZSkge1xuICAgICAgICBpdGVtLmZpbGUoKGZpbGU6IEZpbGUpID0+IHtcbiAgICAgICAgICBpZiAodGhpcy5hdHRyQWNjZXB0KGZpbGUsIHRoaXMub3B0aW9ucy5hY2NlcHQpKSB7XG4gICAgICAgICAgICB0aGlzLnVwbG9hZEZpbGVzKFtmaWxlXSk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSBpZiAoaXRlbS5pc0RpcmVjdG9yeSkge1xuICAgICAgICBjb25zdCBkaXJSZWFkZXIgPSBpdGVtLmNyZWF0ZVJlYWRlcigpO1xuXG4gICAgICAgIGRpclJlYWRlci5yZWFkRW50cmllcygoZW50cmllczogTnpTYWZlQW55KSA9PiB7XG4gICAgICAgICAgZm9yIChjb25zdCBlbnRyaWVJdGVtIG9mIGVudHJpZXMpIHtcbiAgICAgICAgICAgIF90cmF2ZXJzZUZpbGVUcmVlKGVudHJpZUl0ZW0sIGAke3BhdGh9JHtpdGVtLm5hbWV9L2ApO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIGZvciAoY29uc3QgZmlsZSBvZiBmaWxlcyBhcyBOelNhZmVBbnkpIHtcbiAgICAgIF90cmF2ZXJzZUZpbGVUcmVlKGZpbGUud2Via2l0R2V0QXNFbnRyeSgpLCAnJyk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhdHRyQWNjZXB0KGZpbGU6IEZpbGUsIGFjY2VwdGVkRmlsZXM/OiBzdHJpbmcgfCBzdHJpbmdbXSk6IGJvb2xlYW4ge1xuICAgIGlmIChmaWxlICYmIGFjY2VwdGVkRmlsZXMpIHtcbiAgICAgIGNvbnN0IGFjY2VwdGVkRmlsZXNBcnJheSA9IEFycmF5LmlzQXJyYXkoYWNjZXB0ZWRGaWxlcykgPyBhY2NlcHRlZEZpbGVzIDogYWNjZXB0ZWRGaWxlcy5zcGxpdCgnLCcpO1xuICAgICAgY29uc3QgZmlsZU5hbWUgPSBgJHtmaWxlLm5hbWV9YDtcbiAgICAgIGNvbnN0IG1pbWVUeXBlID0gYCR7ZmlsZS50eXBlfWA7XG4gICAgICBjb25zdCBiYXNlTWltZVR5cGUgPSBtaW1lVHlwZS5yZXBsYWNlKC9cXC8uKiQvLCAnJyk7XG5cbiAgICAgIHJldHVybiBhY2NlcHRlZEZpbGVzQXJyYXkuc29tZSh0eXBlID0+IHtcbiAgICAgICAgY29uc3QgdmFsaWRUeXBlID0gdHlwZS50cmltKCk7XG4gICAgICAgIGlmICh2YWxpZFR5cGUuY2hhckF0KDApID09PSAnLicpIHtcbiAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgZmlsZU5hbWVcbiAgICAgICAgICAgICAgLnRvTG93ZXJDYXNlKClcbiAgICAgICAgICAgICAgLmluZGV4T2YodmFsaWRUeXBlLnRvTG93ZXJDYXNlKCksIGZpbGVOYW1lLnRvTG93ZXJDYXNlKCkubGVuZ3RoIC0gdmFsaWRUeXBlLnRvTG93ZXJDYXNlKCkubGVuZ3RoKSAhPT0gLTFcbiAgICAgICAgICApO1xuICAgICAgICB9IGVsc2UgaWYgKC9cXC9cXCokLy50ZXN0KHZhbGlkVHlwZSkpIHtcbiAgICAgICAgICAvLyBUaGlzIGlzIHNvbWV0aGluZyBsaWtlIGEgaW1hZ2UvKiBtaW1lIHR5cGVcbiAgICAgICAgICByZXR1cm4gYmFzZU1pbWVUeXBlID09PSB2YWxpZFR5cGUucmVwbGFjZSgvXFwvLiokLywgJycpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBtaW1lVHlwZSA9PT0gdmFsaWRUeXBlO1xuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcHJpdmF0ZSBhdHRhY2hVaWQoZmlsZTogTnpVcGxvYWRGaWxlKTogTnpVcGxvYWRGaWxlIHtcbiAgICBpZiAoIWZpbGUudWlkKSB7XG4gICAgICBmaWxlLnVpZCA9IE1hdGgucmFuZG9tKCkudG9TdHJpbmcoMzYpLnN1YnN0cmluZygyKTtcbiAgICB9XG4gICAgcmV0dXJuIGZpbGU7XG4gIH1cblxuICB1cGxvYWRGaWxlcyhmaWxlTGlzdDogRmlsZUxpc3QgfCBGaWxlW10pOiB2b2lkIHtcbiAgICBsZXQgZmlsdGVycyQ6IE9ic2VydmFibGU8TnpVcGxvYWRGaWxlW10+ID0gb2YoQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoZmlsZUxpc3QpKTtcbiAgICBpZiAodGhpcy5vcHRpb25zLmZpbHRlcnMpIHtcbiAgICAgIHRoaXMub3B0aW9ucy5maWx0ZXJzLmZvckVhY2goZiA9PiB7XG4gICAgICAgIGZpbHRlcnMkID0gZmlsdGVycyQucGlwZShcbiAgICAgICAgICBzd2l0Y2hNYXAobGlzdCA9PiB7XG4gICAgICAgICAgICBjb25zdCBmblJlcyA9IGYuZm4obGlzdCk7XG4gICAgICAgICAgICByZXR1cm4gZm5SZXMgaW5zdGFuY2VvZiBPYnNlcnZhYmxlID8gZm5SZXMgOiBvZihmblJlcyk7XG4gICAgICAgICAgfSlcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICBmaWx0ZXJzJC5zdWJzY3JpYmUoXG4gICAgICBsaXN0ID0+IHtcbiAgICAgICAgbGlzdC5mb3JFYWNoKChmaWxlOiBOelVwbG9hZEZpbGUpID0+IHtcbiAgICAgICAgICB0aGlzLmF0dGFjaFVpZChmaWxlKTtcbiAgICAgICAgICB0aGlzLnVwbG9hZChmaWxlLCBsaXN0KTtcbiAgICAgICAgfSk7XG4gICAgICB9LFxuICAgICAgZSA9PiB7XG4gICAgICAgIHdhcm4oYFVuaGFuZGxlZCB1cGxvYWQgZmlsdGVyIGVycm9yYCwgZSk7XG4gICAgICB9XG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgdXBsb2FkKGZpbGU6IE56VXBsb2FkRmlsZSwgZmlsZUxpc3Q6IE56VXBsb2FkRmlsZVtdKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLm9wdGlvbnMuYmVmb3JlVXBsb2FkKSB7XG4gICAgICByZXR1cm4gdGhpcy5wb3N0KGZpbGUpO1xuICAgIH1cbiAgICBjb25zdCBiZWZvcmUgPSB0aGlzLm9wdGlvbnMuYmVmb3JlVXBsb2FkKGZpbGUsIGZpbGVMaXN0KTtcbiAgICBpZiAoYmVmb3JlIGluc3RhbmNlb2YgT2JzZXJ2YWJsZSkge1xuICAgICAgYmVmb3JlLnN1YnNjcmliZShcbiAgICAgICAgKHByb2Nlc3NlZEZpbGU6IE56VXBsb2FkRmlsZSkgPT4ge1xuICAgICAgICAgIGNvbnN0IHByb2Nlc3NlZEZpbGVUeXBlID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHByb2Nlc3NlZEZpbGUpO1xuICAgICAgICAgIGlmIChwcm9jZXNzZWRGaWxlVHlwZSA9PT0gJ1tvYmplY3QgRmlsZV0nIHx8IHByb2Nlc3NlZEZpbGVUeXBlID09PSAnW29iamVjdCBCbG9iXScpIHtcbiAgICAgICAgICAgIHRoaXMuYXR0YWNoVWlkKHByb2Nlc3NlZEZpbGUpO1xuICAgICAgICAgICAgdGhpcy5wb3N0KHByb2Nlc3NlZEZpbGUpO1xuICAgICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHByb2Nlc3NlZEZpbGUgPT09ICdib29sZWFuJyAmJiBwcm9jZXNzZWRGaWxlICE9PSBmYWxzZSkge1xuICAgICAgICAgICAgdGhpcy5wb3N0KGZpbGUpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgZSA9PiB7XG4gICAgICAgICAgd2FybihgVW5oYW5kbGVkIHVwbG9hZCBiZWZvcmVVcGxvYWQgZXJyb3JgLCBlKTtcbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9IGVsc2UgaWYgKGJlZm9yZSAhPT0gZmFsc2UpIHtcbiAgICAgIHJldHVybiB0aGlzLnBvc3QoZmlsZSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBwb3N0KGZpbGU6IE56VXBsb2FkRmlsZSk6IHZvaWQge1xuICAgIGlmICh0aGlzLmRlc3Ryb3kpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgbGV0IHByb2Nlc3MkOiBPYnNlcnZhYmxlPHN0cmluZyB8IEJsb2IgfCBGaWxlIHwgTnpVcGxvYWRGaWxlPiA9IG9mKGZpbGUpO1xuICAgIGxldCB0cmFuc2Zvcm1lZEZpbGU6IHN0cmluZyB8IEJsb2IgfCBGaWxlIHwgTnpVcGxvYWRGaWxlIHwgdW5kZWZpbmVkO1xuICAgIGNvbnN0IG9wdCA9IHRoaXMub3B0aW9ucztcbiAgICBjb25zdCB7IHVpZCB9ID0gZmlsZTtcbiAgICBjb25zdCB7IGFjdGlvbiwgZGF0YSwgaGVhZGVycywgdHJhbnNmb3JtRmlsZSB9ID0gb3B0O1xuXG4gICAgY29uc3QgYXJnczogTnpVcGxvYWRYSFJBcmdzID0ge1xuICAgICAgYWN0aW9uOiB0eXBlb2YgYWN0aW9uID09PSAnc3RyaW5nJyA/IGFjdGlvbiA6ICcnLFxuICAgICAgbmFtZTogb3B0Lm5hbWUsXG4gICAgICBoZWFkZXJzLFxuICAgICAgZmlsZSxcbiAgICAgIHBvc3RGaWxlOiBmaWxlLFxuICAgICAgZGF0YSxcbiAgICAgIHdpdGhDcmVkZW50aWFsczogb3B0LndpdGhDcmVkZW50aWFscyxcbiAgICAgIG9uUHJvZ3Jlc3M6IG9wdC5vblByb2dyZXNzXG4gICAgICAgID8gZSA9PiB7XG4gICAgICAgICAgICBvcHQub25Qcm9ncmVzcyEoZSwgZmlsZSk7XG4gICAgICAgICAgfVxuICAgICAgICA6IHVuZGVmaW5lZCxcbiAgICAgIG9uU3VjY2VzczogKHJldCwgeGhyKSA9PiB7XG4gICAgICAgIHRoaXMuY2xlYW4odWlkKTtcbiAgICAgICAgb3B0Lm9uU3VjY2VzcyEocmV0LCBmaWxlLCB4aHIpO1xuICAgICAgfSxcbiAgICAgIG9uRXJyb3I6IHhociA9PiB7XG4gICAgICAgIHRoaXMuY2xlYW4odWlkKTtcbiAgICAgICAgb3B0Lm9uRXJyb3IhKHhociwgZmlsZSk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIGlmICh0eXBlb2YgYWN0aW9uID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBjb25zdCBhY3Rpb25SZXN1bHQgPSAoYWN0aW9uIGFzIChmaWxlOiBOelVwbG9hZEZpbGUpID0+IHN0cmluZyB8IE9ic2VydmFibGU8c3RyaW5nPikoZmlsZSk7XG4gICAgICBpZiAoYWN0aW9uUmVzdWx0IGluc3RhbmNlb2YgT2JzZXJ2YWJsZSkge1xuICAgICAgICBwcm9jZXNzJCA9IHByb2Nlc3MkLnBpcGUoXG4gICAgICAgICAgc3dpdGNoTWFwKCgpID0+IGFjdGlvblJlc3VsdCksXG4gICAgICAgICAgbWFwKHJlcyA9PiB7XG4gICAgICAgICAgICBhcmdzLmFjdGlvbiA9IHJlcztcbiAgICAgICAgICAgIHJldHVybiBmaWxlO1xuICAgICAgICAgIH0pXG4gICAgICAgICk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBhcmdzLmFjdGlvbiA9IGFjdGlvblJlc3VsdDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIHRyYW5zZm9ybUZpbGUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGNvbnN0IHRyYW5zZm9ybVJlc3VsdCA9IHRyYW5zZm9ybUZpbGUoZmlsZSk7XG4gICAgICBwcm9jZXNzJCA9IHByb2Nlc3MkLnBpcGUoXG4gICAgICAgIHN3aXRjaE1hcCgoKSA9PiAodHJhbnNmb3JtUmVzdWx0IGluc3RhbmNlb2YgT2JzZXJ2YWJsZSA/IHRyYW5zZm9ybVJlc3VsdCA6IG9mKHRyYW5zZm9ybVJlc3VsdCkpKSxcbiAgICAgICAgdGFwKG5ld0ZpbGUgPT4gKHRyYW5zZm9ybWVkRmlsZSA9IG5ld0ZpbGUpKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIGRhdGEgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGNvbnN0IGRhdGFSZXN1bHQgPSAoZGF0YSBhcyAoZmlsZTogTnpVcGxvYWRGaWxlKSA9PiB7fSB8IE9ic2VydmFibGU8e30+KShmaWxlKTtcbiAgICAgIGlmIChkYXRhUmVzdWx0IGluc3RhbmNlb2YgT2JzZXJ2YWJsZSkge1xuICAgICAgICBwcm9jZXNzJCA9IHByb2Nlc3MkLnBpcGUoXG4gICAgICAgICAgc3dpdGNoTWFwKCgpID0+IGRhdGFSZXN1bHQpLFxuICAgICAgICAgIG1hcChyZXMgPT4ge1xuICAgICAgICAgICAgYXJncy5kYXRhID0gcmVzO1xuICAgICAgICAgICAgcmV0dXJuIHRyYW5zZm9ybWVkRmlsZSA/PyBmaWxlO1xuICAgICAgICAgIH0pXG4gICAgICAgICk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBhcmdzLmRhdGEgPSBkYXRhUmVzdWx0O1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0eXBlb2YgaGVhZGVycyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgY29uc3QgaGVhZGVyc1Jlc3VsdCA9IChoZWFkZXJzIGFzIChmaWxlOiBOelVwbG9hZEZpbGUpID0+IHt9IHwgT2JzZXJ2YWJsZTx7fT4pKGZpbGUpO1xuICAgICAgaWYgKGhlYWRlcnNSZXN1bHQgaW5zdGFuY2VvZiBPYnNlcnZhYmxlKSB7XG4gICAgICAgIHByb2Nlc3MkID0gcHJvY2VzcyQucGlwZShcbiAgICAgICAgICBzd2l0Y2hNYXAoKCkgPT4gaGVhZGVyc1Jlc3VsdCksXG4gICAgICAgICAgbWFwKHJlcyA9PiB7XG4gICAgICAgICAgICBhcmdzLmhlYWRlcnMgPSByZXM7XG4gICAgICAgICAgICByZXR1cm4gdHJhbnNmb3JtZWRGaWxlID8/IGZpbGU7XG4gICAgICAgICAgfSlcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGFyZ3MuaGVhZGVycyA9IGhlYWRlcnNSZXN1bHQ7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcHJvY2VzcyQuc3Vic2NyaWJlKG5ld0ZpbGUgPT4ge1xuICAgICAgYXJncy5wb3N0RmlsZSA9IG5ld0ZpbGU7XG4gICAgICBjb25zdCByZXEkID0gKG9wdC5jdXN0b21SZXF1ZXN0IHx8IHRoaXMueGhyKS5jYWxsKHRoaXMsIGFyZ3MpO1xuICAgICAgaWYgKCEocmVxJCBpbnN0YW5jZW9mIFN1YnNjcmlwdGlvbikpIHtcbiAgICAgICAgd2FybihgTXVzdCByZXR1cm4gU3Vic2NyaXB0aW9uIHR5cGUgaW4gJ1tuekN1c3RvbVJlcXVlc3RdJyBwcm9wZXJ0eWApO1xuICAgICAgfVxuICAgICAgdGhpcy5yZXFzW3VpZF0gPSByZXEkO1xuICAgICAgb3B0Lm9uU3RhcnQhKGZpbGUpO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSB4aHIoYXJnczogTnpVcGxvYWRYSFJBcmdzKTogU3Vic2NyaXB0aW9uIHtcbiAgICBjb25zdCBmb3JtRGF0YSA9IG5ldyBGb3JtRGF0YSgpO1xuXG4gICAgaWYgKGFyZ3MuZGF0YSkge1xuICAgICAgT2JqZWN0LmtleXMoYXJncy5kYXRhKS5tYXAoa2V5ID0+IHtcbiAgICAgICAgZm9ybURhdGEuYXBwZW5kKGtleSwgYXJncy5kYXRhIVtrZXldKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGZvcm1EYXRhLmFwcGVuZChhcmdzLm5hbWUhLCBhcmdzLnBvc3RGaWxlIGFzIE56U2FmZUFueSk7XG5cbiAgICBpZiAoIWFyZ3MuaGVhZGVycykge1xuICAgICAgYXJncy5oZWFkZXJzID0ge307XG4gICAgfVxuICAgIGlmIChhcmdzLmhlYWRlcnNbJ1gtUmVxdWVzdGVkLVdpdGgnXSAhPT0gbnVsbCkge1xuICAgICAgYXJncy5oZWFkZXJzWydYLVJlcXVlc3RlZC1XaXRoJ10gPSBgWE1MSHR0cFJlcXVlc3RgO1xuICAgIH0gZWxzZSB7XG4gICAgICBkZWxldGUgYXJncy5oZWFkZXJzWydYLVJlcXVlc3RlZC1XaXRoJ107XG4gICAgfVxuICAgIGNvbnN0IHJlcSA9IG5ldyBIdHRwUmVxdWVzdCgnUE9TVCcsIGFyZ3MuYWN0aW9uISwgZm9ybURhdGEsIHtcbiAgICAgIHJlcG9ydFByb2dyZXNzOiB0cnVlLFxuICAgICAgd2l0aENyZWRlbnRpYWxzOiBhcmdzLndpdGhDcmVkZW50aWFscyxcbiAgICAgIGhlYWRlcnM6IG5ldyBIdHRwSGVhZGVycyhhcmdzLmhlYWRlcnMpXG4gICAgfSk7XG4gICAgcmV0dXJuIHRoaXMuaHR0cC5yZXF1ZXN0KHJlcSkuc3Vic2NyaWJlKFxuICAgICAgKGV2ZW50OiBIdHRwRXZlbnQ8TnpTYWZlQW55PikgPT4ge1xuICAgICAgICBpZiAoZXZlbnQudHlwZSA9PT0gSHR0cEV2ZW50VHlwZS5VcGxvYWRQcm9ncmVzcykge1xuICAgICAgICAgIGlmIChldmVudC50b3RhbCEgPiAwKSB7XG4gICAgICAgICAgICAoZXZlbnQgYXMgTnpTYWZlQW55KS5wZXJjZW50ID0gKGV2ZW50LmxvYWRlZCAvIGV2ZW50LnRvdGFsISkgKiAxMDA7XG4gICAgICAgICAgfVxuICAgICAgICAgIGFyZ3Mub25Qcm9ncmVzcyEoZXZlbnQsIGFyZ3MuZmlsZSk7XG4gICAgICAgIH0gZWxzZSBpZiAoZXZlbnQgaW5zdGFuY2VvZiBIdHRwUmVzcG9uc2UpIHtcbiAgICAgICAgICBhcmdzLm9uU3VjY2VzcyEoZXZlbnQuYm9keSwgYXJncy5maWxlLCBldmVudCk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBlcnIgPT4ge1xuICAgICAgICB0aGlzLmFib3J0KGFyZ3MuZmlsZSk7XG4gICAgICAgIGFyZ3Mub25FcnJvciEoZXJyLCBhcmdzLmZpbGUpO1xuICAgICAgfVxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIGNsZWFuKHVpZDogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgcmVxJCA9IHRoaXMucmVxc1t1aWRdO1xuICAgIGlmIChyZXEkIGluc3RhbmNlb2YgU3Vic2NyaXB0aW9uKSB7XG4gICAgICByZXEkLnVuc3Vic2NyaWJlKCk7XG4gICAgfVxuICAgIGRlbGV0ZSB0aGlzLnJlcXNbdWlkXTtcbiAgfVxuXG4gIGFib3J0KGZpbGU/OiBOelVwbG9hZEZpbGUpOiB2b2lkIHtcbiAgICBpZiAoZmlsZSkge1xuICAgICAgdGhpcy5jbGVhbihmaWxlICYmIGZpbGUudWlkKTtcbiAgICB9IGVsc2Uge1xuICAgICAgT2JqZWN0LmtleXModGhpcy5yZXFzKS5mb3JFYWNoKHVpZCA9PiB0aGlzLmNsZWFuKHVpZCkpO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgbmdab25lOiBOZ1pvbmUsIEBPcHRpb25hbCgpIHByaXZhdGUgaHR0cDogSHR0cENsaWVudCwgcHJpdmF0ZSBlbGVtZW50UmVmOiBFbGVtZW50UmVmKSB7XG4gICAgaWYgKCFodHRwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYE5vdCBmb3VuZCAnSHR0cENsaWVudCcsIFlvdSBjYW4gaW1wb3J0ICdIdHRwQ2xpZW50TW9kdWxlJyBpbiB5b3VyIHJvb3QgbW9kdWxlLmApO1xuICAgIH1cbiAgfVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIC8vIENhcmV0YWtlciBub3RlOiBgaW5wdXRbdHlwZT1maWxlXS5jbGljaygpYCB3aWxsIG9wZW4gYSBuYXRpdmUgT1MgZmlsZSBwaWNrZXIsXG4gICAgLy8gaXQgZG9lc24ndCByZXF1aXJlIEFuZ3VsYXIgdG8gcnVuIGBBcHBsaWNhdGlvblJlZi50aWNrKClgLlxuICAgIHRoaXMubmdab25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcbiAgICAgIGZyb21FdmVudCh0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudCwgJ2NsaWNrJylcbiAgICAgICAgLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKVxuICAgICAgICAuc3Vic2NyaWJlKCgpID0+IHRoaXMub25DbGljaygpKTtcblxuICAgICAgZnJvbUV2ZW50PEtleWJvYXJkRXZlbnQ+KHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LCAna2V5ZG93bicpXG4gICAgICAgIC5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSlcbiAgICAgICAgLnN1YnNjcmliZShldmVudCA9PiB7XG4gICAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5kaXNhYmxlZCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoZXZlbnQua2V5ID09PSAnRW50ZXInIHx8IGV2ZW50LmtleUNvZGUgPT09IEVOVEVSKSB7XG4gICAgICAgICAgICB0aGlzLm9uQ2xpY2soKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5kZXN0cm95ID0gdHJ1ZTtcbiAgICB0aGlzLmRlc3Ryb3kkLm5leHQoKTtcbiAgICB0aGlzLmFib3J0KCk7XG4gIH1cbn1cbiIsIjxpbnB1dFxuICB0eXBlPVwiZmlsZVwiXG4gICNmaWxlXG4gIChjaGFuZ2UpPVwib25DaGFuZ2UoJGV2ZW50KVwiXG4gIFthdHRyLmFjY2VwdF09XCJvcHRpb25zLmFjY2VwdFwiXG4gIFthdHRyLmRpcmVjdG9yeV09XCJvcHRpb25zLmRpcmVjdG9yeSA/ICdkaXJlY3RvcnknIDogbnVsbFwiXG4gIFthdHRyLndlYmtpdGRpcmVjdG9yeV09XCJvcHRpb25zLmRpcmVjdG9yeSA/ICd3ZWJraXRkaXJlY3RvcnknIDogbnVsbFwiXG4gIFttdWx0aXBsZV09XCJvcHRpb25zLm11bHRpcGxlXCJcbiAgc3R5bGU9XCJkaXNwbGF5OiBub25lXCJcbi8+XG48bmctY29udGVudD48L25nLWNvbnRlbnQ+XG4iXX0=