UNPKG

ais-uploader

Version:

Simple uploader library for Angular 2+

545 lines 56.6 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ import * as tslib_1 from "tslib"; import { Component, EventEmitter, Inject, Output, PLATFORM_ID, ViewChild, ViewEncapsulation, } from '@angular/core'; import { isPlatformServer } from '@angular/common'; import { DocumentFileType } from './models/uploader-item'; import { AisUploaderService } from './ais-uploader.service'; import { UploaderTypesPipe } from './pipes/uploader-enum.pipe'; export class AisUploaderComponent { /** * @param {?} platformId * @param {?} uploderService * @param {?} uploaderEnum */ constructor(platformId, uploderService, uploaderEnum) { this.uploderService = uploderService; this.uploaderEnum = uploaderEnum; this.onChange = new EventEmitter(); this.onProgress = new EventEmitter(); this.onError = new EventEmitter(); this._allowedExtensions = []; if (isPlatformServer(platformId) || typeof ((/** @type {?} */ (window))).MouseEvent === 'function') { return; } /** * @param {?} event * @param {?} params * @return {?} */ function CustomEvent(event, params) { params = params || { bubbles: false, cancelable: false, detail: undefined }; /** @type {?} */ const evt = document.createEvent('CustomEvent'); evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail); return evt; } CustomEvent.prototype = ((/** @type {?} */ (window))).Event.prototype; ((/** @type {?} */ (window))).CustomEvent = CustomEvent; } /** * @return {?} */ ngOnInit() { this._generateAllowedExtensions(); } /** * @return {?} */ ngOnDestroy() { if (this._progressSub$) { this._progressSub$.unsubscribe(); } if (this._uploaderSub$) { this._uploaderSub$.unsubscribe(); } } // return file name or arr file names if isMultiple: true /** * @return {?} */ get fileName() { if (this.config.isMultiple) { return this.filesNames; } if (!this._file) { return ''; } return this._file.name; } // return arr file names if isMultiple: true /** * @return {?} */ get filesNames() { if (!this._files || !this._files.length) { return undefined; } return this._files.map(file => file.name); } // return info message /** * @return {?} */ get tooltipMessage() { if (!this.config.supportedFormats.length) { return `Max. size is ${this.config.maxSize ? this.config.maxSize : 'unlimited'} Mb`; } /** @type {?} */ const formats = this.uploaderEnum.transform(this.config.supportedFormats); return `Supported formats are ${formats || 'All formats'}. Max. size is ${this.config.maxSize ? this.config.maxSize : 'unlimited'} Mb`; } // open selction window /** * @return {?} */ select() { /** @type {?} */ let event; if (typeof ((/** @type {?} */ (window))).MouseEvent === 'function') { event = new MouseEvent('click', {}); } else { event = new CustomEvent('click'); } this.fileSelector.nativeElement.dispatchEvent(event); } // remove file from files arr /** * @param {?} i * @return {?} */ delete(i) { this._files.splice(i, 1); } // remove file or all files /** * @param {?=} emit * @return {?} */ clear(emit = true) { this._file = undefined; this._files = undefined; this.fileSelector.nativeElement.value = ''; if (emit) { this.onChange.emit(''); } } /** * @param {?} event * @return {?} */ loadFile(event) { return tslib_1.__awaiter(this, void 0, void 0, function* () { if (this.config.isMultiple) { /** @type {?} */ const _files = event.target.files; for (const file of _files) { /** @type {?} */ const isValid = yield this.validate(file); if (!isValid) { return; } } this._files = [..._files]; } else { /** @type {?} */ const _file = event.target.files[0]; if (!_file) { return; } /** @type {?} */ const isValid = yield this.validate(_file); if (!isValid) { return; } this._file = _file; } if (this.config.isAutoupload) { try { /** @type {?} */ const res = yield this.upload(); this.onChange.emit(res); } catch (e) { this.onError.emit(e); } return; } if (!this.config.isPreviewDisabled) { this._makePreview(); return; } this.onChange.emit(this._file.name); }); } // upload to server /** * @return {?} */ upload() { if (this._progressSub$) { this._progressSub$.unsubscribe(); } this._onLoaderSub(); if (!this.config.isMultiple) { return new Promise(resolve => { this._uploaderSub$ = this.uploderService.upload(this._file, this.config).subscribe(res => { this.onProgress.emit(0); this.uploadingProgress = 0; resolve(res); }, err => { this.onError.emit('Uploading error'); this.preventUploading(); resolve(undefined); }); }); } else { return new Promise(resolve => { this._uploaderSub$ = this.uploderService.uploadMultiple(this._files, this.config).subscribe(res => { this.onProgress.emit(0); this.uploadingProgress = 0; resolve(res); }, err => { this.onError.emit('Uploading error'); this.preventUploading(); resolve(undefined); }); }); } } // cancel current uploading /** * @return {?} */ preventUploading() { if (!this.uploadingProgress) { return; } if (this._progressSub$) { this._progressSub$.unsubscribe(); } if (this._uploaderSub$) { this._uploaderSub$.unsubscribe(); } this.onProgress.emit(0); this.uploadingProgress = 0; this.clear(); } /** * @private * @param {?} file * @return {?} */ validate(file) { return tslib_1.__awaiter(this, void 0, void 0, function* () { if (!file || !this.config) { this.throwError('Uploader error'); return false; } if (this.config.maxSize && file.size / 1024 / 1024 > this.config.maxSize) { this.throwError(`File size should be no more than ${this.config.maxSize}Mb`); return false; } if (this.config.supportedFormats.length && file.type && !this.config.supportedFormats.includes(file.type)) { this.throwError(`Unsupported file format`); return false; } if (this.config.supportedFormats.length && !file.type && !this._validateFormat(file.name)) { this.throwError(`Unsupported file format`); return false; } if (this.config.imageResolution) { /** @type {?} */ let resolution = this.config.imageResolution.split('x'); /** @type {?} */ let img; if (!resolution || !resolution.length || resolution.length !== 2) { this.throwError(`Unsupported resolution format`); return false; } resolution = resolution.map(r => Math.ceil(Number(r))).filter(n => !!n); if (!resolution || !resolution.length || resolution.length !== 2) { this.throwError(`Unsupported resolution format`); return false; } try { img = yield this._addImageProcess(file); } catch (e) { console.warn('Resolution property allows only for Images - Error Skipped'); return true; } if (img.width !== resolution[0] || img.height !== resolution[1]) { this.throwError(`Unsupported resolution format! Correct resolution is ${this.config.imageResolution}`); return false; } } return true; }); } /** * @private * @param {?} file * @return {?} */ _addImageProcess(file) { return tslib_1.__awaiter(this, void 0, void 0, function* () { return new Promise((resolve, reject) => { // @ts-ignore /** @type {?} */ const _URL = window.URL || window.webkitURL; /** @type {?} */ const img = new Image(); /** @type {?} */ const objectUrl = _URL.createObjectURL(file); img.onload = () => { _URL.revokeObjectURL(objectUrl); return resolve({ height: img.height, width: img.width }); }; img.onerror = reject; img.src = objectUrl; }); }); } /** * @private * @return {?} */ _onLoaderSub() { this._progressSub$ = this.uploderService.uploadingProgress .subscribe(progress => { this.onProgress.emit(progress); this.uploadingProgress = progress; }); } /** * @private * @return {?} */ _makePreview() { if (!this.config.isMultiple) { /** @type {?} */ const reader = new FileReader(); reader.onload = (event) => { this.onChange.emit(event.target.result); }; reader.readAsDataURL(this._file); } else { /** @type {?} */ const dataArr = []; for (let i = 0; i < this._files.length; i++) { /** @type {?} */ const reader = new FileReader(); reader.onload = (event) => { dataArr[i] = (event.target.result); }; reader.readAsDataURL(this._files[i]); if (i == this._files.length - 1) { this.onChange.emit(dataArr); } } } } /** * @private * @param {?} name * @return {?} */ _validateFormat(name) { if (!this.config.supportedFormats.length) { return true; } /** @type {?} */ const extension = name.split('.').pop().toLowerCase(); return this._allowedExtensions.some(s => s === extension); } /** * @private * @param {?} message * @return {?} */ throwError(message) { this.onError.emit(message); this.fileSelector.nativeElement.value = ''; } // tslint:disable-next-line:cyclomatic-complexity /** * @private * @return {?} */ _generateAllowedExtensions() { if (!this.config || !this.config.supportedFormats) { return; } for (const format of this.config.supportedFormats) { switch (format) { case DocumentFileType.DOC: this._allowedExtensions.push('doc'); break; case DocumentFileType.DOCX: this._allowedExtensions.push('docx'); break; case DocumentFileType.XLSX: this._allowedExtensions.push('xlsx'); break; case DocumentFileType.XLS: this._allowedExtensions.push('xls'); break; case DocumentFileType.PDF: this._allowedExtensions.push('pdf'); break; case DocumentFileType.TXT: this._allowedExtensions.push('txt'); break; case DocumentFileType.PPTX: this._allowedExtensions.push('pptx'); break; case DocumentFileType.PPT: this._allowedExtensions.push('ppt'); break; case DocumentFileType.AVI: this._allowedExtensions.push('avi'); break; case DocumentFileType.FLV: this._allowedExtensions.push('flv'); break; case DocumentFileType.MP4: this._allowedExtensions.push('mp4'); break; case DocumentFileType.MPEG: this._allowedExtensions.push('mpeg'); break; case DocumentFileType.OGG: this._allowedExtensions.push('ogg'); break; case DocumentFileType.WEBM: this._allowedExtensions.push('webm'); break; case DocumentFileType.JPEG: this._allowedExtensions.push('jpeg'); break; case DocumentFileType.JPG: this._allowedExtensions.push('jpg'); break; case DocumentFileType.PNG: this._allowedExtensions.push('png'); break; case DocumentFileType.TIFF: this._allowedExtensions.push('tiff'); break; case DocumentFileType.WBMP: this._allowedExtensions.push('wbmp'); break; case DocumentFileType.WEBP: this._allowedExtensions.push('webp'); break; case DocumentFileType.SVG: this._allowedExtensions.push('svg'); break; case DocumentFileType.GIF: this._allowedExtensions.push('gif'); break; case DocumentFileType.CSV: this._allowedExtensions.push('csv'); break; case DocumentFileType.MSCSV: this._allowedExtensions.push('csv'); break; case DocumentFileType.MOV: this._allowedExtensions.push('mov'); break; case DocumentFileType.MP3: this._allowedExtensions.push('mp3'); break; case DocumentFileType.WAV: this._allowedExtensions.push('wav'); break; case DocumentFileType.XWAV: this._allowedExtensions.push('wav'); break; default: break; } } } } AisUploaderComponent.decorators = [ { type: Component, args: [{ selector: 'ais-uploader', template: "<input id=\"uploader_lib\" #fileSelector type=\"file\" [accept]=\"config?.supportedFormats | uploaderTypes:true\"\r\n (change)=\"loadFile($event)\">\r\n", encapsulation: ViewEncapsulation.None, styles: ["#uploader_lib{display:none}@keyframes blink{0%,100%{box-shadow:0 2px 2px rgba(0,0,0,.24),0 0 2px rgba(0,0,0,.12)}50%{box-shadow:none}}@-webkit-keyframes blink{0%,100%{box-shadow:0 2px 2px rgba(0,0,0,.24),0 0 2px rgba(0,0,0,.12)}50%{box-shadow:0 0 0}}.blink{-webkit-animation:3s linear infinite blink;animation:3s linear infinite blink}"] }] } ]; /** @nocollapse */ AisUploaderComponent.ctorParameters = () => [ { type: String, decorators: [{ type: Inject, args: [PLATFORM_ID,] }] }, { type: AisUploaderService }, { type: UploaderTypesPipe } ]; AisUploaderComponent.propDecorators = { onChange: [{ type: Output }], onProgress: [{ type: Output }], onError: [{ type: Output }], fileSelector: [{ type: ViewChild, args: ['fileSelector',] }] }; if (false) { /** @type {?} */ AisUploaderComponent.prototype.config; /** @type {?} */ AisUploaderComponent.prototype.uploadingProgress; /** @type {?} */ AisUploaderComponent.prototype.onChange; /** @type {?} */ AisUploaderComponent.prototype.onProgress; /** @type {?} */ AisUploaderComponent.prototype.onError; /** @type {?} */ AisUploaderComponent.prototype.fileSelector; /** * @type {?} * @private */ AisUploaderComponent.prototype._file; /** * @type {?} * @private */ AisUploaderComponent.prototype._files; /** * @type {?} * @private */ AisUploaderComponent.prototype._allowedExtensions; /** * @type {?} * @private */ AisUploaderComponent.prototype._progressSub$; /** * @type {?} * @private */ AisUploaderComponent.prototype._uploaderSub$; /** * @type {?} * @private */ AisUploaderComponent.prototype.uploderService; /** * @type {?} * @private */ AisUploaderComponent.prototype.uploaderEnum; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWlzLXVwbG9hZGVyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL2Fpcy11cGxvYWRlci8iLCJzb3VyY2VzIjpbImxpYi9haXMtdXBsb2FkZXIuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsT0FBTyxFQUNILFNBQVMsRUFDVCxZQUFZLEVBQ1osTUFBTSxFQUdOLE1BQU0sRUFDTixXQUFXLEVBQ1gsU0FBUyxFQUNULGlCQUFpQixHQUNwQixNQUFNLGVBQWUsQ0FBQztBQUd2QixPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNuRCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUMxRCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUM1RCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQVEvRCxNQUFNLE9BQU8sb0JBQW9COzs7Ozs7SUFjN0IsWUFDeUIsVUFBa0IsRUFDL0IsY0FBa0MsRUFDbEMsWUFBK0I7UUFEL0IsbUJBQWMsR0FBZCxjQUFjLENBQW9CO1FBQ2xDLGlCQUFZLEdBQVosWUFBWSxDQUFtQjtRQWRqQyxhQUFRLEdBQXNCLElBQUksWUFBWSxFQUFFLENBQUM7UUFDakQsZUFBVSxHQUF5QixJQUFJLFlBQVksRUFBRSxDQUFDO1FBQ3RELFlBQU8sR0FBeUIsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQUtyRCx1QkFBa0IsR0FBYSxFQUFFLENBQUM7UUFTdEMsSUFBSSxnQkFBZ0IsQ0FBQyxVQUFVLENBQUMsSUFBSSxPQUFPLENBQUMsbUJBQUssTUFBTSxFQUFBLENBQUMsQ0FBQyxVQUFVLEtBQUssVUFBVSxFQUFFO1lBQ2hGLE9BQU87U0FDVjs7Ozs7O1FBRUQsU0FBUyxXQUFXLENBQUMsS0FBSyxFQUFFLE1BQU07WUFDOUIsTUFBTSxHQUFHLE1BQU0sSUFBSSxFQUFDLE9BQU8sRUFBRSxLQUFLLEVB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S0FBSyxDQUFDLENBQUM7b0JBQ3BDLE1BQU07Z0JBQ1YsS0FBSyxnQkFBZ0IsQ0FBQyxHQUFHO29CQUNyQixJQUFJLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO29CQUNwQyxNQUFNO2dCQUNWLEtBQUssZ0JBQWdCLENBQUMsR0FBRztvQkFDckIsSUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztvQkFDcEMsTUFBTTtnQkFDVixLQUFLLGdCQUFnQixDQUFDLElBQUk7b0JBQ3RCLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7b0JBQ3BDLE1BQU07Z0JBQ1Y7b0JBQ0ksTUFBTTthQUNiO1NBQ0o7SUFDTCxDQUFDOzs7WUF6WUosU0FBUyxTQUFDO2dCQUNQLFFBQVEsRUFBRSxjQUFjO2dCQUN4QiwwS0FBNEM7Z0JBRTVDLGFBQWEsRUFBRSxpQkFBaUIsQ0FBQyxJQUFJOzthQUN4Qzs7Ozt5Q0FnQlEsTUFBTSxTQUFDLFdBQVc7WUF4QmxCLGtCQUFrQjtZQUNsQixpQkFBaUI7Ozt1QkFXckIsTUFBTTt5QkFDTixNQUFNO3NCQUNOLE1BQU07MkJBRU4sU0FBUyxTQUFDLGNBQWM7Ozs7SUFOekIsc0NBQXVCOztJQUN2QixpREFBMEI7O0lBQzFCLHdDQUEyRDs7SUFDM0QsMENBQWdFOztJQUNoRSx1Q0FBNkQ7O0lBRTdELDRDQUF3Qzs7Ozs7SUFDeEMscUNBQW9COzs7OztJQUNwQixzQ0FBdUI7Ozs7O0lBQ3ZCLGtEQUEwQzs7Ozs7SUFDMUMsNkNBQW9DOzs7OztJQUNwQyw2Q0FBb0M7Ozs7O0lBSWhDLDhDQUEwQzs7Ozs7SUFDMUMsNENBQXVDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcclxuICAgIENvbXBvbmVudCxcclxuICAgIEV2ZW50RW1pdHRlcixcclxuICAgIEluamVjdCxcclxuICAgIE9uRGVzdHJveSxcclxuICAgIE9uSW5pdCxcclxuICAgIE91dHB1dCxcclxuICAgIFBMQVRGT1JNX0lELFxyXG4gICAgVmlld0NoaWxkLFxyXG4gICAgVmlld0VuY2Fwc3VsYXRpb24sXHJcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IFVwbG9hZGVyQ29uZmlnIH0gZnJvbSAnLi9tb2RlbHMvdXBsb2FkZXItY29uZmlnJztcclxuaW1wb3J0IHsgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XHJcbmltcG9ydCB7IGlzUGxhdGZvcm1TZXJ2ZXIgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xyXG5pbXBvcnQgeyBEb2N1bWVudEZpbGVUeXBlIH0gZnJvbSAnLi9tb2RlbHMvdXBsb2FkZXItaXRlbSc7XHJcbmltcG9ydCB7IEFpc1VwbG9hZGVyU2VydmljZSB9IGZyb20gJy4vYWlzLXVwbG9hZGVyLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBVcGxvYWRlclR5cGVzUGlwZSB9IGZyb20gJy4vcGlwZXMvdXBsb2FkZXItZW51bS5waXBlJztcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gICAgc2VsZWN0b3I6ICdhaXMtdXBsb2FkZXInLFxyXG4gICAgdGVtcGxhdGVVcmw6ICcuL2Fpcy11cGxvYWRlci5jb21wb25lbnQuaHRtbCcsXHJcbiAgICBzdHlsZVVybHM6IFsnLi9haXMtdXBsb2FkZXIuY29tcG9uZW50LnNjc3MnXSxcclxuICAgIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBBaXNVcGxvYWRlckNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcclxuICAgIGNvbmZpZzogVXBsb2FkZXJDb25maWc7XHJcbiAgICB1cGxvYWRpbmdQcm9ncmVzczogbnVtYmVyO1xyXG4gICAgQE91dHB1dCgpIG9uQ2hhbmdlOiBFdmVudEVtaXR0ZXI8YW55PiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcclxuICAgIEBPdXRwdXQoKSBvblByb2dyZXNzOiBFdmVudEVtaXR0ZXI8bnVtYmVyPiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcclxuICAgIEBPdXRwdXQoKSBvbkVycm9yOiBFdmVudEVtaXR0ZXI8c3RyaW5nPiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcclxuXHJcbiAgICBAVmlld0NoaWxkKCdmaWxlU2VsZWN0b3InKSBmaWxlU2VsZWN0b3I7XHJcbiAgICBwcml2YXRlIF9maWxlOiBGaWxlO1xyXG4gICAgcHJpdmF0ZSBfZmlsZXM6IEZpbGVbXTtcclxuICAgIHByaXZhdGUgX2FsbG93ZWRFeHRlbnNpb25zOiBzdHJpbmdbXSA9IFtdO1xyXG4gICAgcHJpdmF0ZSBfcHJvZ3Jlc3NTdWIkOiBTdWJzY3JpcHRpb247XHJcbiAgICBwcml2YXRlIF91cGxvYWRlclN1YiQ6IFN1YnNjcmlwdGlvbjtcclxuXHJcbiAgICBjb25zdHJ1Y3RvcihcclxuICAgICAgICBASW5qZWN0KFBMQVRGT1JNX0lEKSBwbGF0Zm9ybUlkOiBzdHJpbmcsXHJcbiAgICAgICAgcHJpdmF0ZSB1cGxvZGVyU2VydmljZTogQWlzVXBsb2FkZXJTZXJ2aWNlLFxyXG4gICAgICAgIHByaXZhdGUgdXBsb2FkZXJFbnVtOiBVcGxvYWRlclR5cGVzUGlwZSxcclxuICAgICkge1xyXG4gICAgICAgIGlmIChpc1BsYXRmb3JtU2VydmVyKHBsYXRmb3JtSWQpIHx8IHR5cGVvZiAoPGFueT53aW5kb3cpLk1vdXNlRXZlbnQgPT09ICdmdW5jdGlvbicpIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZnVuY3Rpb24gQ3VzdG9tRXZlbnQoZXZlbnQsIHBhcmFtcyk6IGFueSB7XHJcbiAgICAgICAgICAgIHBhcmFtcyA9IHBhcmFtcyB8fCB7YnViYmxlczogZmFsc2UsIGNhbmNlbGFibGU6IGZhbHNlLCBkZXRhaWw6IHVuZGVmaW5lZH07XHJcbiAgICAgICAgICAgIGNvbnN0IGV2dDogYW55ID0gZG9jdW1lbnQuY3JlYXRlRXZlbnQoJ0N1c3RvbUV2ZW50Jyk7XHJcbiAgICAgICAgICAgIGV2dC5pbml0Q3VzdG9tRXZlbnQoZXZlbnQsIHBhcmFtcy5idWJibGVzLCBwYXJhbXMuY2FuY2VsYWJsZSwgcGFyYW1zLmRldGFpbCk7XHJcbiAgICAgICAgICAgIHJldHVybiBldnQ7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBDdXN0b21FdmVudC5wcm90b3R5cGUgPSAoPGFueT53aW5kb3cpLkV2ZW50LnByb3RvdHlwZTtcclxuICAgICAgICAoPGFueT53aW5kb3cpLkN1c3RvbUV2ZW50ID0gQ3VzdG9tRXZlbnQ7XHJcbiAgICB9XHJcblxyXG4gICAgbmdPbkluaXQoKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5fZ2VuZXJhdGVBbGxvd2VkRXh0ZW5zaW9ucygpO1xyXG4gICAgfVxyXG5cclxuICAgIG5nT25EZXN0cm95KCk6IHZvaWQge1xyXG4gICAgICAgIGlmICh0aGlzLl9wcm9ncmVzc1N1YiQpIHtcclxuICAgICAgICAgICAgdGhpcy5fcHJvZ3Jlc3NTdWIkLnVuc3Vic2NyaWJlKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh0aGlzLl91cGxvYWRlclN1YiQpIHtcclxuICAgICAgICAgICAgdGhpcy5fdXBsb2FkZXJTdWIkLnVuc3Vic2NyaWJlKCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8vIHJldHVybiBmaWxlIG5hbWUgb3IgYXJyIGZpbGUgbmFtZXMgaWYgaXNNdWx0aXBsZTogdHJ1ZVxyXG4gICAgZ2V0IGZpbGVOYW1lKCk6IHN0cmluZyB8IHN0cmluZ1tdIHtcclxuICAgICAgICBpZiAodGhpcy5jb25maWcuaXNNdWx0aXBsZSkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5maWxlc05hbWVzO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoIXRoaXMuX2ZpbGUpIHtcclxuICAgICAgICAgICAgcmV0dXJuICcnO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdGhpcy5fZmlsZS5uYW1lO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIHJldHVybiBhcnIgZmlsZSBuYW1lcyBpZiBpc011bHRpcGxlOiB0cnVlXHJcbiAgICBnZXQgZmlsZXNOYW1lcygpOiBzdHJpbmdbXSB7XHJcbiAgICAgICAgaWYgKCF0aGlzLl9maWxlcyB8fCAhdGhpcy5fZmlsZXMubGVuZ3RoKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiB0aGlzLl9maWxlcy5tYXAoZmlsZSA9PiBmaWxlLm5hbWUpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIHJldHVybiBpbmZvIG1lc3NhZ2VcclxuICAgIGdldCB0b29sdGlwTWVzc2FnZSgpOiBzdHJpbmcge1xyXG4gICAgICAgIGlmICghdGhpcy5jb25maWcuc3VwcG9ydGVkRm9ybWF0cy5sZW5ndGgpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGBNYXguIHNpemUgaXMgJHt0aGlzLmNvbmZpZy5tYXhTaXplID8gdGhpcy5jb25maWcubWF4U2l6ZSA6ICd1bmxpbWl0ZWQnfSBNYmA7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbnN0IGZvcm1hdHMgPSB0aGlzLnVwbG9hZGVyRW51bS50cmFuc2Zvcm0odGhpcy5jb25maWcuc3VwcG9ydGVkRm9ybWF0cyk7XHJcbiAgICAgICAgcmV0dXJuIGBTdXBwb3J0ZWQgZm9ybWF0cyBhcmUgJHtmb3JtYXRzIHx8ICdBbGwgZm9ybWF0cyd9LiBNYXguIHNpemUgaXMgJHt0aGlzLmNvbmZpZy5tYXhTaXplID9cclxuICAgICAgICAgICAgdGhpcy5jb25maWcubWF4U2l6ZSA6ICd1bmxpbWl0ZWQnfSBNYmA7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gb3BlbiBzZWxjdGlvbiB3aW5kb3dcclxuICAgIHNlbGVjdCgpOiB2b2lkIHtcclxuICAgICAgICBsZXQgZXZlbnQ6IGFueTtcclxuICAgICAgICBpZiAodHlwZW9mICg8YW55PndpbmRvdykuTW91c2VFdmVudCA9PT0gJ2Z1bmN0aW9uJykge1xyXG4gICAgICAgICAgICBldmVudCA9IG5ldyBNb3VzZUV2ZW50KCdjbGljaycsIHt9KTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBldmVudCA9IG5ldyBDdXN0b21FdmVudCgnY2xpY2snKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5maWxlU2VsZWN0b3IubmF0aXZlRWxlbWVudC5kaXNwYXRjaEV2ZW50KGV2ZW50KTtcclxuICAgIH1cclxuXHJcbiAgICAvLyByZW1vdmUgZmlsZSBmcm9tIGZpbGVzIGFyclxyXG4gICAgZGVsZXRlKGk6IG51bWJlcik6IHZvaWQge1xyXG4gICAgICAgIHRoaXMuX2ZpbGVzLnNwbGljZShpLCAxKTtcclxuICAgIH1cclxuXHJcbiAgICAvLyByZW1vdmUgZmlsZSBvciBhbGwgZmlsZXNcclxuICAgIGNsZWFyKGVtaXQ6IGJvb2xlYW4gPSB0cnVlKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5fZmlsZSA9IHVuZGVmaW5lZDtcclxuICAgICAgICB0aGlzLl9maWxlcyA9IHVuZGVmaW5lZDtcclxuICAgICAgICB0aGlzLmZpbGVTZWxlY3Rvci5uYXRpdmVFbGVtZW50LnZhbHVlID0gJyc7XHJcbiAgICAgICAgaWYgKGVtaXQpIHtcclxuICAgICAgICAgICAgdGhpcy5vbkNoYW5nZS5lbWl0KCcnKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgYXN5bmMgbG9hZEZpbGUoZXZlbnQpOiBQcm9taXNlPGFueT4ge1xyXG4gICAgICAgIGlmICh0aGlzLmNvbmZpZy5pc011bHRpcGxlKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IF9maWxlcyA9IGV2ZW50LnRhcmdldC5maWxlcztcclxuICAgICAgICAgICAgZm9yIChjb25zdCBmaWxlIG9mIF9maWxlcykge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgaXNWYWxpZCA9IGF3YWl0IHRoaXMudmFsaWRhdGUoZmlsZSk7XHJcbiAgICAgICAgICAgICAgICBpZiAoIWlzVmFsaWQpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgdGhpcy5fZmlsZXMgPSBbLi4uX2ZpbGVzXTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBjb25zdCBfZmlsZSA9IGV2ZW50LnRhcmdldC5maWxlc1swXTtcclxuICAgICAgICAgICAgaWYgKCFfZmlsZSkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNvbnN0IGlzVmFsaWQgPSBhd2FpdCB0aGlzLnZhbGlkYXRlKF9maWxlKTtcclxuICAgICAgICAgICAgaWYgKCFpc1ZhbGlkKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgdGhpcy5fZmlsZSA9IF9maWxlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAodGhpcy5jb25maWcuaXNBdXRvdXBsb2FkKSB7XHJcbiAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCByZXMgPSBhd2FpdCB0aGlzLnVwbG9hZCgpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5vbkNoYW5nZS5lbWl0KHJlcyk7XHJcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMub25FcnJvci5lbWl0KGUpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKCF0aGlzLmNvbmZpZy5pc1ByZXZpZXdEaXNhYmxlZCkge1xyXG4gICAgICAgICAgICB0aGlzLl9tYWtlUHJldmlldygpO1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMub25DaGFuZ2UuZW1pdCh0aGlzLl9maWxlLm5hbWUpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIHVwbG9hZCB0byBzZXJ2ZXJcclxuICAgIHVwbG9hZCgpOiBQcm9taXNlPGFueT4ge1xyXG4gICAgICAgIGlmICh0aGlzLl9wcm9ncmVzc1N1YiQpIHtcclxuICAgICAgICAgICAgdGhpcy5fcHJvZ3Jlc3NTdWIkLnVuc3Vic2NyaWJlKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMuX29uTG9hZGVyU3ViKCk7XHJcbiAgICAgICAgaWYgKCF0aGlzLmNvbmZpZy5pc011bHRpcGxlKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX3VwbG9hZGVyU3ViJCA9IHRoaXMudXBsb2RlclNlcnZpY2UudXBsb2FkKHRoaXMuX2ZpbGUsIHRoaXMuY29uZmlnKS5zdWJzY3JpYmUocmVzID0+IHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLm9uUHJvZ3Jlc3MuZW1pdCgwKTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnVwbG9hZGluZ1Byb2dyZXNzID0gMDtcclxuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHJlcyk7XHJcbiAgICAgICAgICAgICAgICB9LCBlcnIgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMub25FcnJvci5lbWl0KCdVcGxvYWRpbmcgZXJyb3InKTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnByZXZlbnRVcGxvYWRpbmcoKTtcclxuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHVuZGVmaW5lZCk7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKHJlc29sdmUgPT4ge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fdXBsb2FkZXJTdWIkID0gdGhpcy51cGxvZGVyU2VydmljZS51cGxvYWRNdWx0aXBsZSh0aGlzLl9maWxlcywgdGhpcy5jb25maWcpLnN1YnNjcmliZShyZXMgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMub25Qcm9ncmVzcy5lbWl0KDApO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMudXBsb2FkaW5nUHJvZ3Jlc3MgPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUocmVzKTtcclxuICAgICAgICAgICAgICAgIH0sIGVyciA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5vbkVycm9yLmVtaXQoJ1VwbG9hZGluZyBlcnJvcicpO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucHJldmVudFVwbG9hZGluZygpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUodW5kZWZpbmVkKTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLy8gY2FuY2VsIGN1cnJlbnQgdXBsb2FkaW5nXHJcbiAgICBwcmV2ZW50VXBsb2FkaW5nKCk6IHZvaWQge1xyXG4gICAgICAgIGlmICghdGhpcy51cGxvYWRpbmdQcm9ncmVzcykge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh0aGlzLl9wcm9ncmVzc1N1YiQpIHtcclxuICAgICAgICAgICAgdGhpcy5fcHJvZ3Jlc3NTdWIkLnVuc3Vic2NyaWJlKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh0aGlzLl91cGxvYWRlclN1YiQpIHtcclxuICAgICAgICAgICAgdGhpcy5fdXBsb2FkZXJTdWIkLnVuc3Vic2NyaWJlKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMub25Qcm9ncmVzcy5lbWl0KDApO1xyXG4gICAgICAgIHRoaXMudXBsb2FkaW5nUHJvZ3Jlc3MgPSAwO1xyXG4gICAgICAgIHRoaXMuY2xlYXIoKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGFzeW5jIHZhbGlkYXRlKGZpbGUpOiBQcm9taXNlPGJvb2xlYW4+IHtcclxuICAgICAgICBpZiAoIWZpbGUgfHwgIXRoaXMuY29uZmlnKSB7XHJcbiAgICAgICAgICAgIHRoaXMudGhyb3dFcnJvcignVXBsb2FkZXIgZXJyb3InKTtcclxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAodGhpcy5jb25maWcubWF4U2l6ZSAmJlxyXG4gICAgICAgICAgICBmaWxlLnNpemUgLyAxMDI0IC8gMTAyNCA+IHRoaXMuY29uZmlnLm1heFNpemUpIHtcclxuICAgICAgICAgICAgdGhpcy50aHJvd0Vycm9yKGBGaWxlIHNpemUgc2hvdWxkIGJlIG5vIG1vcmUgdGhhbiAke3RoaXMuY29uZmlnLm1heFNpemV9TWJgKTtcclxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAodGhpcy5jb25maWcuc3VwcG9ydGVkRm9ybWF0cy5sZW5ndGggJiYgZmlsZS50eXBlICYmXHJcbiAgICAgICAgICAgICF0aGlzLmNvbmZpZy5zdXBwb3J0ZWRGb3JtYXRzLmluY2x1ZGVzKGZpbGUudHlwZSkpIHtcclxuICAgICAgICAgICAgdGhpcy50aHJvd0Vycm9yKGBVbnN1cHBvcnRlZCBmaWxlIGZvcm1hdGApO1xyXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh0aGlzLmNvbmZpZy5zdXBwb3J0ZWRGb3JtYXRzLmxlbmd0aCAmJiAhZmlsZS50eXBlICYmXHJcbiAgICAgICAgICAgICF0aGlzLl92YWxpZGF0ZUZvcm1hdChmaWxlLm5hbWUpKSB7XHJcbiAgICAgICAgICAgIHRoaXMudGhyb3dFcnJvcihgVW5zdXBwb3J0ZWQgZmlsZSBmb3JtYXRgKTtcclxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAodGhpcy5jb25maWcuaW1hZ2VSZXNvbHV0aW9uKSB7XHJcbiAgICAgICAgICAgIGxldCByZXNvbHV0aW9uOiBBcnJheTxzdHJpbmcgfCBudW1iZXI+ID0gdGhpcy5jb25maWcuaW1hZ2VSZXNvbHV0aW9uLnNwbGl0KCd4Jyk7XHJcbiAgICAgICAgICAgIGxldCBpbWc7XHJcbiAgICAgICAgICAgIGlmICghcmVzb2x1dGlvbiB8fCAhcmVzb2x1dGlvbi5sZW5ndGggfHwgcmVzb2x1dGlvbi5sZW5ndGggIT09IDIpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMudGhyb3dFcnJvcihgVW5zdXBwb3J0ZWQgcmVzb2x1dGlvbiBmb3JtYXRgKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXNvbHV0aW9uID0gcmVzb2x1dGlvbi5tYXAociA9PiBNYXRoLmNlaWwoTnVtYmVyKHIpKSkuZmlsdGVyKG4gPT4gISFuKTtcclxuICAgICAgICAgICAgaWYgKCFyZXNvbHV0aW9uIHx8ICFyZXNvbHV0aW9uLmxlbmd0aCB8fCByZXNvbHV0aW9uLmxlbmd0aCAhPT0gMikge1xyXG4gICAgICAgICAgICAgICAgdGhpcy50aHJvd0Vycm9yKGBVbnN1cHBvcnRlZCByZXNvbHV0aW9uIGZvcm1hdGApO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICBpbWcgPSBhd2FpdCB0aGlzLl9hZGRJbWFnZVByb2Nlc3MoZmlsZSk7XHJcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybignUmVzb2x1dGlvbiBwcm9wZXJ0eSBhbGxvd3Mgb25seSBmb3IgSW1hZ2VzIC0gRXJyb3IgU2tpcHBlZCcpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKGltZy53aWR0aCAhPT0gcmVzb2x1dGlvblswXSB8fCBpbWcuaGVpZ2h0ICE9PSByZXNvbHV0aW9uWzFdKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnRocm93RXJyb3IoYFVuc3VwcG9ydGVkIHJlc29sdXRpb24gZm9ybWF0ISBDb3JyZWN0IHJlc29sdXRpb24gaXMgJHt0aGlzLmNvbmZpZy5pbWFnZVJlc29sdXRpb259YCk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBhc3luYyBfYWRkSW1hZ2VQcm9jZXNzKGZpbGUpOiBQcm9taXNlPGFueT4ge1xyXG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XHJcbiAgICAgICAgICAgIC8vIEB0cy1pZ25vcmVcclxuICAgICAgICAgICAgY29uc3QgX1VSTCA9IHdpbmRvdy5VUkwgfHwgd2luZG93LndlYmtpdFVSTDtcclxuICAgICAgICAgICAgY29uc3QgaW1nID0gbmV3IEltYWdlKCk7XHJcbiAgICAgICAgICAgIGNvbnN0IG9iamVjdFVybCA9IF9VUkwuY3JlYXRlT2JqZWN0VVJMKGZpbGUpO1xyXG4gICAgICAgICAgICBpbWcub25sb2FkID0gKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgX1VSTC5yZXZva2VPYmplY3RVUkwob2JqZWN0VXJsKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKHtoZWlnaHQ6IGltZy5oZWlnaHQsIHdpZHRoOiBpbWcud2lkdGh9KTtcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgaW1nLm9uZXJyb3IgPSByZWplY3Q7XHJcbiAgICAgICAgICAgIGltZy5zcmMgPSBvYmplY3RVcmw7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfb25Mb2FkZXJTdWIoKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5fcHJvZ3Jlc3NTdWIkID0gdGhpcy51cGxvZGVyU2VydmljZS51cGxvYWRpbmdQcm9ncmVzc1xyXG4gICAgICAgICAgICAuc3Vic2NyaWJlKHByb2dyZXNzID0+IHtcclxuICAgICAgICAgICAgICAgIHRoaXMub25Qcm9ncmVzcy5lbWl0KHByb2dyZXNzKTtcclxuICAgICAgICAgICAgICAgIHRoaXMudXBsb2FkaW5nUHJvZ3Jlc3MgPSBwcm9ncmVzcztcclxuICAgICAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfbWFrZVByZXZpZXcoKTogdm9pZCB7XHJcbiAgICAgICAgaWYgKCF0aGlzLmNvbmZpZy5pc011bHRpcGxlKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7XHJcbiAgICAgICAgICAgIHJlYWRlci5vbmxvYWQgPSAoZXZlbnQ6IGFueSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5vbkNoYW5nZS5lbWl0KGV2ZW50LnRhcmdldC5yZXN1bHQpO1xyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICByZWFkZXIucmVhZEFzRGF0YVVSTCh0aGlzLl9maWxlKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBjb25zdCBkYXRhQXJyID0gW107XHJcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5fZmlsZXMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7XHJcbiAgICAgICAgICAgICAgICByZWFkZXIub25sb2FkID0gKGV2ZW50OiBhbnkpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBkYXRhQXJyW2ldID0gKGV2ZW50LnRhcmdldC5yZXN