ngx-uploadx
Version:
Angular Resumable Upload Module
150 lines • 19.4 kB
JavaScript
import { inject, Injectable, NgZone } from '@angular/core';
import { fromEvent, Subject } from 'rxjs';
import { debounceTime, map } from 'rxjs/operators';
import { UPLOADX_AJAX } from './ajax';
import { IdService } from './id.service';
import { UPLOADX_FACTORY_OPTIONS, UPLOADX_OPTIONS } from './options';
import { store } from './store';
import { iosOverride, isBrowser, onLine, pick } from './utils';
import * as i0 from "@angular/core";
export const UPLOAD_STATE_KEYS = [
'file',
'name',
'progress',
'remaining',
'response',
'responseHeaders',
'responseStatus',
'size',
'speed',
'status',
'uploadId',
'url'
];
const DUE_TIME = 5;
export class UploadxService {
/** Upload Queue */
queue = [];
options;
eventsStream = new Subject();
subs = [];
ngZone = inject(NgZone);
ajax = inject(UPLOADX_AJAX);
idService = inject(IdService);
constructor() {
const options = inject(UPLOADX_OPTIONS, { optional: true });
const defaults = inject(UPLOADX_FACTORY_OPTIONS);
this.options = Object.assign({}, defaults, options);
if (isBrowser()) {
this.subs.push(fromEvent(window, 'online').subscribe(() => this.control({ action: 'upload' })), fromEvent(window, 'offline').subscribe(() => this.control({ action: 'pause' })));
}
}
/** Upload status events */
get events() {
return this.eventsStream.asObservable();
}
/**
* Initializes service
* @param options global module options
* @returns Observable that emits a new value on progress or status changes
*/
init(options = {}) {
Object.assign(this.options, options);
return this.events;
}
/**
* Initializes service
* @param options global module options
* @returns Observable that emits the current array of uploaders
*/
connect(options) {
return this.init(options).pipe(map(() => this.queue), debounceTime(DUE_TIME));
}
/**
* Terminates all uploads and clears the queue
*/
disconnect() {
this.queue.forEach(uploader => (uploader.status = 'paused'));
this.queue = [];
}
/**
* Returns current uploads state
* @example
* // restore background uploads
* this.uploads = this.uploadService.state();
*/
state() {
return this.queue.map(uploader => pick(uploader, UPLOAD_STATE_KEYS));
}
ngOnDestroy() {
this.disconnect();
this.subs.forEach(sub => sub.unsubscribe());
}
/**
* Creates uploaders for files and adds them to the upload queue
*/
handleFiles(files, options = {}) {
const instanceOptions = { ...this.options, ...iosOverride, ...options };
store.clear(instanceOptions.storeIncompleteHours);
this.options.concurrency = instanceOptions.concurrency;
('name' in files ? [files] : Array.from(files)).forEach(file => this.addUploaderInstance(file, instanceOptions));
}
/**
* Upload control
* @example
* // pause all
* this.uploadService.control({ action: 'pause' });
* // pause upload with uploadId
* this.uploadService.control({ action: 'pause', uploadId});
* // set token
* this.uploadService.control({ token: `TOKEN` });
*/
control(evt) {
const target = evt.uploadId
? this.queue.filter(({ uploadId }) => uploadId === evt.uploadId)
: this.queue;
target.forEach(uploader => uploader.configure(evt));
}
/**
* Number of active uploads
*/
get activeUploadsCount() {
return this.queue.filter(({ status }) => status === 'uploading' || status === 'retry').length;
}
/**
* Performs http requests
*/
async request(config) {
config.data ||= config.body;
return this.ajax.request(config);
}
stateChange = (uploader) => {
this.ngZone.run(() => this.eventsStream.next(pick(uploader, UPLOAD_STATE_KEYS)));
if (uploader.status !== 'uploading' && uploader.status !== 'added') {
this.ngZone.runOutsideAngular(() => setTimeout(() => this.processQueue()));
}
};
async addUploaderInstance(file, options) {
const uploader = new options.uploaderClass(file, options, this.stateChange, this.ajax);
uploader.uploadId = await this.idService.generateId(uploader);
this.queue.push(uploader);
uploader.status = 'added';
if (options.autoUpload && onLine()) {
uploader.status = 'queue';
}
}
processQueue() {
this.queue = this.queue.filter(({ status }) => status !== 'cancelled');
this.queue
.filter(({ status }) => status === 'queue')
.slice(0, Math.max(this.options.concurrency - this.activeUploadsCount, 0))
.forEach(uploader => uploader.upload());
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: UploadxService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: UploadxService, providedIn: 'root' });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: UploadxService, decorators: [{
type: Injectable,
args: [{ providedIn: 'root' }]
}], ctorParameters: () => [] });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXBsb2FkeC5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3VwbG9hZHgvbGliL3VwbG9hZHguc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQWEsTUFBTSxlQUFlLENBQUM7QUFDdEUsT0FBTyxFQUFFLFNBQVMsRUFBYyxPQUFPLEVBQWdCLE1BQU0sTUFBTSxDQUFDO0FBQ3BFLE9BQU8sRUFBRSxZQUFZLEVBQUUsR0FBRyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDbkQsT0FBTyxFQUFtQyxZQUFZLEVBQUUsTUFBTSxRQUFRLENBQUM7QUFDdkUsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUV6QyxPQUFPLEVBQ0wsdUJBQXVCLEVBQ3ZCLGVBQWUsRUFHaEIsTUFBTSxXQUFXLENBQUM7QUFDbkIsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUVoQyxPQUFPLEVBQUUsV0FBVyxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLE1BQU0sU0FBUyxDQUFDOztBQUUvRCxNQUFNLENBQUMsTUFBTSxpQkFBaUIsR0FBMEI7SUFDdEQsTUFBTTtJQUNOLE1BQU07SUFDTixVQUFVO0lBQ1YsV0FBVztJQUNYLFVBQVU7SUFDVixpQkFBaUI7SUFDakIsZ0JBQWdCO0lBQ2hCLE1BQU07SUFDTixPQUFPO0lBQ1AsUUFBUTtJQUNSLFVBQVU7SUFDVixLQUFLO0NBQ04sQ0FBQztBQUVGLE1BQU0sUUFBUSxHQUFHLENBQUMsQ0FBQztBQUduQixNQUFNLE9BQU8sY0FBYztJQUN6QixtQkFBbUI7SUFDbkIsS0FBSyxHQUFlLEVBQUUsQ0FBQztJQUNkLE9BQU8sQ0FBd0I7SUFDdkIsWUFBWSxHQUF5QixJQUFJLE9BQU8sRUFBRSxDQUFDO0lBQzVELElBQUksR0FBbUIsRUFBRSxDQUFDO0lB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RUFBRSxDQUFDLE1BQU0sS0FBSyxPQUFPLENBQUM7YUFDMUMsS0FBSyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFDLENBQUMsQ0FBQzthQUN6RSxPQUFPLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxRQUFRLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQztJQUM1QyxDQUFDO3dHQTNJVSxjQUFjOzRHQUFkLGNBQWMsY0FERCxNQUFNOzs0RkFDbkIsY0FBYztrQkFEMUIsVUFBVTttQkFBQyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBpbmplY3QsIEluamVjdGFibGUsIE5nWm9uZSwgT25EZXN0cm95IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBmcm9tRXZlbnQsIE9ic2VydmFibGUsIFN1YmplY3QsIFN1YnNjcmlwdGlvbiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgZGVib3VuY2VUaW1lLCBtYXAgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBBamF4UmVxdWVzdENvbmZpZywgQWpheFJlc3BvbnNlLCBVUExPQURYX0FKQVggfSBmcm9tICcuL2FqYXgnO1xuaW1wb3J0IHsgSWRTZXJ2aWNlIH0gZnJvbSAnLi9pZC5zZXJ2aWNlJztcbmltcG9ydCB7IFVwbG9hZFN0YXRlLCBVcGxvYWR4Q29udHJvbEV2ZW50IH0gZnJvbSAnLi9pbnRlcmZhY2VzJztcbmltcG9ydCB7XG4gIFVQTE9BRFhfRkFDVE9SWV9PUFRJT05TLFxuICBVUExPQURYX09QVElPTlMsXG4gIFVwbG9hZHhGYWN0b3J5T3B0aW9ucyxcbiAgVXBsb2FkeE9wdGlvbnNcbn0gZnJvbSAnLi9vcHRpb25zJztcbmltcG9ydCB7IHN0b3JlIH0gZnJvbSAnLi9zdG9yZSc7XG5pbXBvcnQgeyBVcGxvYWRlciB9IGZyb20gJy4vdXBsb2FkZXInO1xuaW1wb3J0IHsgaW9zT3ZlcnJpZGUsIGlzQnJvd3Nlciwgb25MaW5lLCBwaWNrIH0gZnJvbSAnLi91dGlscyc7XG5cbmV4cG9ydCBjb25zdCBVUExPQURfU1RBVEVfS0VZUzogKGtleW9mIFVwbG9hZFN0YXRlKVtdID0gW1xuICAnZmlsZScsXG4gICduYW1lJyxcbiAgJ3Byb2dyZXNzJyxcbiAgJ3JlbWFpbmluZycsXG4gICdyZXNwb25zZScsXG4gICdyZXNwb25zZUhlYWRlcnMnLFxuICAncmVzcG9uc2VTdGF0dXMnLFxuICAnc2l6ZScsXG4gICdzcGVlZCcsXG4gICdzdGF0dXMnLFxuICAndXBsb2FkSWQnLFxuICAndXJsJ1xuXTtcblxuY29uc3QgRFVFX1RJTUUgPSA1O1xuXG5ASW5qZWN0YWJsZSh7IHByb3ZpZGVkSW46ICdyb290JyB9KVxuZXhwb3J0IGNsYXNzIFVwbG9hZHhTZXJ2aWNlIGltcGxlbWVudHMgT25EZXN0cm95IHtcbiAgLyoqIFVwbG9hZCBRdWV1ZSAqL1xuICBxdWV1ZTogVXBsb2FkZXJbXSA9IFtdO1xuICByZWFkb25seSBvcHRpb25zOiBVcGxvYWR4RmFjdG9yeU9wdGlvbnM7XG4gIHByaXZhdGUgcmVhZG9ubHkgZXZlbnRzU3RyZWFtOiBTdWJqZWN0PFVwbG9hZFN0YXRlPiA9IG5ldyBTdWJqZWN0KCk7XG4gIHByaXZhdGUgc3ViczogU3Vic2NyaXB0aW9uW10gPSBbXTtcbiAgcHJpdmF0ZSBuZ1pvbmUgPSBpbmplY3QoTmdab25lKTtcbiAgcmVhZG9ubHkgYWpheCA9IGluamVjdChVUExPQURYX0FKQVgpO1xuICBwcml2YXRlIGlkU2VydmljZSA9IGluamVjdChJZFNlcnZpY2UpO1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIGNvbnN0IG9wdGlvbnMgPSBpbmplY3QoVVBMT0FEWF9PUFRJT05TLCB7IG9wdGlvbmFsOiB0cnVlIH0pO1xuICAgIGNvbnN0IGRlZmF1bHRzID0gaW5qZWN0KFVQTE9BRFhfRkFDVE9SWV9PUFRJT05TKTtcbiAgICB0aGlzLm9wdGlvbnMgPSBPYmplY3QuYXNzaWduKHt9LCBkZWZhdWx0cywgb3B0aW9ucyk7XG4gICAgaWYgKGlzQnJvd3NlcigpKSB7XG4gICAgICB0aGlzLnN1YnMucHVzaChcbiAgICAgICAgZnJvbUV2ZW50KHdpbmRvdywgJ29ubGluZScpLnN1YnNjcmliZSgoKSA9PiB0aGlzLmNvbnRyb2woeyBhY3Rpb246ICd1cGxvYWQnIH0pKSxcbiAgICAgICAgZnJvbUV2ZW50KHdpbmRvdywgJ29mZmxpbmUnKS5zdWJzY3JpYmUoKCkgPT4gdGhpcy5jb250cm9sKHsgYWN0aW9uOiAncGF1c2UnIH0pKVxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICAvKiogVXBsb2FkIHN0YXR1cyBldmVudHMgKi9cbiAgZ2V0IGV2ZW50cygpOiBPYnNlcnZhYmxlPFVwbG9hZFN0YXRlPiB7XG4gICAgcmV0dXJuIHRoaXMuZXZlbnRzU3RyZWFtLmFzT2JzZXJ2YWJsZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEluaXRpYWxpemVzIHNlcnZpY2VcbiAgICogQHBhcmFtIG9wdGlvbnMgZ2xvYmFsIG1vZHVsZSBvcHRpb25zXG4gICAqIEByZXR1cm5zIE9ic2VydmFibGUgdGhhdCBlbWl0cyBhIG5ldyB2YWx1ZSBvbiBwcm9ncmVzcyBvciBzdGF0dXMgY2hhbmdlc1xuICAgKi9cbiAgaW5pdChvcHRpb25zOiBVcGxvYWR4T3B0aW9ucyA9IHt9KTogT2JzZXJ2YWJsZTxVcGxvYWRTdGF0ZT4ge1xuICAgIE9iamVjdC5hc3NpZ24odGhpcy5vcHRpb25zLCBvcHRpb25zKTtcbiAgICByZXR1cm4gdGhpcy5ldmVudHM7XG4gIH1cblxuICAvKipcbiAgICogSW5pdGlhbGl6ZXMgc2VydmljZVxuICAgKiBAcGFyYW0gb3B0aW9ucyBnbG9iYWwgbW9kdWxlIG9wdGlvbnNcbiAgICogQHJldHVybnMgT2JzZXJ2YWJsZSB0aGF0IGVtaXRzIHRoZSBjdXJyZW50IGFycmF5IG9mIHVwbG9hZGVyc1xuICAgKi9cbiAgY29ubmVjdChvcHRpb25zPzogVXBsb2FkeE9wdGlvbnMpOiBPYnNlcnZhYmxlPFVwbG9hZGVyW10+IHtcbiAgICByZXR1cm4gdGhpcy5pbml0KG9wdGlvbnMpLnBpcGUoXG4gICAgICBtYXAoKCkgPT4gdGhpcy5xdWV1ZSksXG4gICAgICBkZWJvdW5jZVRpbWUoRFVFX1RJTUUpXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUZXJtaW5hdGVzIGFsbCB1cGxvYWRzIGFuZCBjbGVhcnMgdGhlIHF1ZXVlXG4gICAqL1xuICBkaXNjb25uZWN0KCk6IHZvaWQge1xuICAgIHRoaXMucXVldWUuZm9yRWFjaCh1cGxvYWRlciA9PiAodXBsb2FkZXIuc3RhdHVzID0gJ3BhdXNlZCcpKTtcbiAgICB0aGlzLnF1ZXVlID0gW107XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBjdXJyZW50IHVwbG9hZHMgc3RhdGVcbiAgICogQGV4YW1wbGVcbiAgICogLy8gcmVzdG9yZSBiYWNrZ3JvdW5kIHVwbG9hZHNcbiAgICogdGhpcy51cGxvYWRzID0gdGhpcy51cGxvYWRTZXJ2aWNlLnN0YXRlKCk7XG4gICAqL1xuICBzdGF0ZSgpOiBVcGxvYWRTdGF0ZVtdIHtcbiAgICByZXR1cm4gdGhpcy5xdWV1ZS5tYXAodXBsb2FkZXIgPT4gcGljayh1cGxvYWRlciwgVVBMT0FEX1NUQVRFX0tFWVMpKTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMuZGlzY29ubmVjdCgpO1xuICAgIHRoaXMuc3Vicy5mb3JFYWNoKHN1YiA9PiBzdWIudW5zdWJzY3JpYmUoKSk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyB1cGxvYWRlcnMgZm9yIGZpbGVzIGFuZCBhZGRzIHRoZW0gdG8gdGhlIHVwbG9hZCBxdWV1ZVxuICAgKi9cbiAgaGFuZGxlRmlsZXMoZmlsZXM6IEZpbGVMaXN0IHwgRmlsZSB8IEZpbGVbXSwgb3B0aW9ucyA9IHt9IGFzIFVwbG9hZHhPcHRpb25zKTogdm9pZCB7XG4gICAgY29uc3QgaW5zdGFuY2VPcHRpb25zOiBVcGxvYWR4RmFjdG9yeU9wdGlvbnMgPSB7IC4uLnRoaXMub3B0aW9ucywgLi4uaW9zT3ZlcnJpZGUsIC4uLm9wdGlvbnMgfTtcbiAgICBzdG9yZS5jbGVhcihpbnN0YW5jZU9wdGlvbnMuc3RvcmVJbmNvbXBsZXRlSG91cnMpO1xuICAgIHRoaXMub3B0aW9ucy5jb25jdXJyZW5jeSA9IGluc3RhbmNlT3B0aW9ucy5jb25jdXJyZW5jeTtcbiAgICAoJ25hbWUnIGluIGZpbGVzID8gW2ZpbGVzXSA6IEFycmF5LmZyb20oZmlsZXMpKS5mb3JFYWNoKGZpbGUgPT5cbiAgICAgIHRoaXMuYWRkVXBsb2FkZXJJbnN0YW5jZShmaWxlLCBpbnN0YW5jZU9wdGlvbnMpXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVcGxvYWQgY29udHJvbFxuICAgKiBAZXhhbXBsZVxuICAgKiAvLyBwYXVzZSBhbGxcbiAgICogdGhpcy51cGxvYWRTZXJ2aWNlLmNvbnRyb2woeyBhY3Rpb246ICdwYXVzZScgfSk7XG4gICAqIC8vIHBhdXNlIHVwbG9hZCB3aXRoIHVwbG9hZElkXG4gICAqIHRoaXMudXBsb2FkU2VydmljZS5jb250cm9sKHsgYWN0aW9uOiAncGF1c2UnLCB1cGxvYWRJZH0pO1xuICAgKiAvLyBzZXQgdG9rZW5cbiAgICogdGhpcy51cGxvYWRTZXJ2aWNlLmNvbnRyb2woeyB0b2tlbjogYFRPS0VOYCB9KTtcbiAgICovXG4gIGNvbnRyb2woZXZ0OiBVcGxvYWR4Q29udHJvbEV2ZW50KTogdm9pZCB7XG4gICAgY29uc3QgdGFyZ2V0ID0gZXZ0LnVwbG9hZElkXG4gICAgICA/IHRoaXMucXVldWUuZmlsdGVyKCh7IHVwbG9hZElkIH0pID0+IHVwbG9hZElkID09PSBldnQudXBsb2FkSWQpXG4gICAgICA6IHRoaXMucXVldWU7XG4gICAgdGFyZ2V0LmZvckVhY2godXBsb2FkZXIgPT4gdXBsb2FkZXIuY29uZmlndXJlKGV2dCkpO1xuICB9XG5cbiAgLyoqXG4gICAqIE51bWJlciBvZiBhY3RpdmUgdXBsb2Fkc1xuICAgKi9cbiAgZ2V0IGFjdGl2ZVVwbG9hZHNDb3VudCgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLnF1ZXVlLmZpbHRlcigoeyBzdGF0dXMgfSkgPT4gc3RhdHVzID09PSAndXBsb2FkaW5nJyB8fCBzdGF0dXMgPT09ICdyZXRyeScpLmxlbmd0aDtcbiAgfVxuXG4gIC8qKlxuICAgKiBQZXJmb3JtcyBodHRwIHJlcXVlc3RzXG4gICAqL1xuICBhc3luYyByZXF1ZXN0PFQgPSBzdHJpbmc+KGNvbmZpZzogQWpheFJlcXVlc3RDb25maWcpOiBQcm9taXNlPEFqYXhSZXNwb25zZTxUPj4ge1xuICAgIGNvbmZpZy5kYXRhIHx8PSBjb25maWcuYm9keTtcbiAgICByZXR1cm4gdGhpcy5hamF4LnJlcXVlc3QoY29uZmlnKTtcbiAgfVxuXG4gIHByaXZhdGUgc3RhdGVDaGFuZ2UgPSAodXBsb2FkZXI6IFVwbG9hZGVyKSA9PiB7XG4gICAgdGhpcy5uZ1pvbmUucnVuKCgpID0+IHRoaXMuZXZlbnRzU3RyZWFtLm5leHQocGljayh1cGxvYWRlciwgVVBMT0FEX1NUQVRFX0tFWVMpKSk7XG4gICAgaWYgKHVwbG9hZGVyLnN0YXR1cyAhPT0gJ3VwbG9hZGluZycgJiYgdXBsb2FkZXIuc3RhdHVzICE9PSAnYWRkZWQnKSB7XG4gICAgICB0aGlzLm5nWm9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PiBzZXRUaW1lb3V0KCgpID0+IHRoaXMucHJvY2Vzc1F1ZXVlKCkpKTtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBhc3luYyBhZGRVcGxvYWRlckluc3RhbmNlKGZpbGU6IEZpbGUsIG9wdGlvbnM6IFVwbG9hZHhGYWN0b3J5T3B0aW9ucyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHVwbG9hZGVyID0gbmV3IG9wdGlvbnMudXBsb2FkZXJDbGFzcyhmaWxlLCBvcHRpb25zLCB0aGlzLnN0YXRlQ2hhbmdlLCB0aGlzLmFqYXgpO1xuICAgICh1cGxvYWRlciBhcyB7IHVwbG9hZElkOiBzdHJpbmcgfSkudXBsb2FkSWQgPSBhd2FpdCB0aGlzLmlkU2VydmljZS5nZW5lcmF0ZUlkKHVwbG9hZGVyKTtcbiAgICB0aGlzLnF1ZXVlLnB1c2godXBsb2FkZXIpO1xuICAgIHVwbG9hZGVyLnN0YXR1cyA9ICdhZGRlZCc7XG4gICAgaWYgKG9wdGlvbnMuYXV0b1VwbG9hZCAmJiBvbkxpbmUoKSkge1xuICAgICAgdXBsb2FkZXIuc3RhdHVzID0gJ3F1ZXVlJztcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHByb2Nlc3NRdWV1ZSgpOiB2b2lkIHtcbiAgICB0aGlzLnF1ZXVlID0gdGhpcy5xdWV1ZS5maWx0ZXIoKHsgc3RhdHVzIH0pID0+IHN0YXR1cyAhPT0gJ2NhbmNlbGxlZCcpO1xuICAgIHRoaXMucXVldWVcbiAgICAgIC5maWx0ZXIoKHsgc3RhdHVzIH0pID0+IHN0YXR1cyA9PT0gJ3F1ZXVlJylcbiAgICAgIC5zbGljZSgwLCBNYXRoLm1heCh0aGlzLm9wdGlvbnMuY29uY3VycmVuY3kgLSB0aGlzLmFjdGl2ZVVwbG9hZHNDb3VudCwgMCkpXG4gICAgICAuZm9yRWFjaCh1cGxvYWRlciA9PiB1cGxvYWRlci51cGxvYWQoKSk7XG4gIH1cbn1cbiJdfQ==