UNPKG

ngx-uploadx

Version:
150 lines 19.4 kB
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==