ngx-suspense
Version:
This library is an experimetnal implementation of React Suspense for Angular.
127 lines • 20.3 kB
JavaScript
import { __decorate, __param } from "tslib";
import { Injectable, Inject, Optional } from "@angular/core";
import { BehaviorSubject, Observable, Subject, combineLatest, merge, of, timer, } from "rxjs";
import { concatMap, filter, tap, mapTo, skip, startWith, switchMap, takeUntil, shareReplay, } from "rxjs/operators";
import { LOADING_CONFIG_TOKEN, LOADING_DEFUALT_CONFIG, } from "./ngx-suspense.config";
let NgxSuspenseService = class NgxSuspenseService {
constructor(userConfig = LOADING_DEFUALT_CONFIG) {
this.userConfig = userConfig;
this.loadingSubject = new BehaviorSubject(false);
this.loading$ = this.loadingSubject.asObservable();
this.taskStartSubject = new Subject();
this.taskStart$ = this.taskStartSubject.asObservable();
this.taskEndSubject = new Subject();
this.taskEnd$ = this.taskEndSubject.asObservable();
}
ngOnDestroy() {
if (this.sub && typeof this.sub.unsubscribe === "function") {
this.sub.unsubscribe();
}
}
set busyTimer({ busyDelayMs, busyMinDurationMs }) {
if (typeof busyDelayMs === "number") {
this.userConfig.busyDelayMs = busyDelayMs;
}
if (typeof busyMinDurationMs === "number") {
this.userConfig.busyMinDurationMs = busyMinDurationMs;
}
}
get config() {
return this.userConfig;
}
show() {
this.loadingSubject.next(true);
}
hide() {
this.loadingSubject.next(false);
}
controller() {
this.busyMinDurationTimer = timer(this.config.busyMinDurationMs + this.config.busyDelayMs);
this.busyDelayTimer = timer(this.config.busyDelayMs);
const busyDelayTimerStart = this.taskStart$.pipe(switchMap(() => this.busyDelayTimer));
const busyDelayTimerEnd = busyDelayTimerStart.pipe(takeUntil(this.taskEnd$));
const emitOnTaskEnd = this.taskEnd$.pipe(mapTo(1));
const emitOnDelayTimerEnd = busyDelayTimerEnd.pipe(mapTo(-1));
const emitOnMinDurationEnd = this.busyMinDurationTimer.pipe(mapTo(-1));
// Start loading skeleton
const raceBetweenTaskAndDelay = combineLatest([
emitOnTaskEnd.pipe(startWith(null)),
emitOnDelayTimerEnd.pipe(startWith(null)),
]).pipe(skip(1));
const taskEndBeforeDelay = raceBetweenTaskAndDelay.pipe(filter(([taskEndFirst, timerEndFirst]) => {
return taskEndFirst === 1 && timerEndFirst === null;
}));
const shouldNotShowSpinner = taskEndBeforeDelay.pipe(mapTo(false));
const taskEndAfterTimeout = raceBetweenTaskAndDelay.pipe(filter(([taskEndFirst, timerEndFirst]) => {
return taskEndFirst === null && timerEndFirst === -1;
}));
const shouldShowSpinner = taskEndAfterTimeout.pipe(mapTo(true));
const showSpinner = shouldShowSpinner.pipe(tap(() => {
this.show();
}));
// hide loading skeleton
const raceBetweenTaskAndMinDuration = combineLatest([
emitOnTaskEnd.pipe(startWith(null)),
emitOnMinDurationEnd.pipe(startWith(null)),
]).pipe(skip(1));
const hideSpinnerUntilMinDurationEnd = raceBetweenTaskAndMinDuration.pipe(filter(([taskEndFirst, timerEndFirst]) => {
return taskEndFirst === 1 && timerEndFirst === null;
}));
const hideSpinnerAfterTimerAndTaskEnd = raceBetweenTaskAndMinDuration.pipe(filter(([taskEndFirst, timerEndFirst]) => {
return taskEndFirst === 1 && timerEndFirst === -1;
}));
const hideSpinner = merge(
// case 1: should not show spinner at all
shouldNotShowSpinner,
// case 2: task end, but wait until min duration timer ends
combineLatest([hideSpinnerUntilMinDurationEnd, emitOnMinDurationEnd]),
// case 3: task takes a long time, wait unitl its end
hideSpinnerAfterTimerAndTaskEnd).pipe(tap(() => {
this.hide();
}));
return showSpinner.pipe(takeUntil(hideSpinner));
}
showLoadingStatus() {
if (this.sub && typeof this.sub.unsubscribe === "function") {
this.sub.unsubscribe();
}
this.sub = this.controller().subscribe();
return (source) => {
return new Observable((subscriber) => {
const emitOnObsEnd = source.pipe(tap(() => {
this.taskEndSubject.next();
}));
const sub = of(null)
.pipe(tap(() => {
this.taskStartSubject.next();
}), concatMap(() => emitOnObsEnd), shareReplay(1))
.subscribe(subscriber);
return () => {
sub.unsubscribe();
};
});
};
}
showingFor(obs$) {
if (this.sub && typeof this.sub.unsubscribe === "function") {
this.sub.unsubscribe();
}
this.sub = this.controller().subscribe();
const emitOnObsEnd = obs$.pipe(tap(() => {
this.taskEndSubject.next();
}));
return of(null).pipe(tap(() => {
this.taskStartSubject.next();
}), concatMap(() => emitOnObsEnd), shareReplay(1));
}
};
NgxSuspenseService.ctorParameters = () => [
{ type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [LOADING_CONFIG_TOKEN,] }] }
];
NgxSuspenseService = __decorate([
Injectable(),
__param(0, Optional()),
__param(0, Inject(LOADING_CONFIG_TOKEN))
], NgxSuspenseService);
export { NgxSuspenseService };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LXN1c3BlbnNlLnNlcnZpY2UuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9uZ3gtc3VzcGVuc2UvIiwic291cmNlcyI6WyJsaWIvbmd4LXN1c3BlbnNlLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBYSxNQUFNLGVBQWUsQ0FBQztBQUN4RSxPQUFPLEVBQ0wsZUFBZSxFQUNmLFVBQVUsRUFDVixPQUFPLEVBRVAsYUFBYSxFQUNiLEtBQUssRUFDTCxFQUFFLEVBQ0YsS0FBSyxHQUVOLE1BQU0sTUFBTSxDQUFDO0FBQ2QsT0FBTyxFQUNMLFNBQVMsRUFDVCxNQUFNLEVBQ04sR0FBRyxFQUNILEtBQUssRUFDTCxJQUFJLEVBQ0osU0FBUyxFQUNULFNBQVMsRUFDVCxTQUFTLEVBQ1QsV0FBVyxHQUNaLE1BQU0sZ0JBQWdCLENBQUM7QUFDeEIsT0FBTyxFQUNMLG9CQUFvQixFQUNwQixzQkFBc0IsR0FFdkIsTUFBTSx1QkFBdUIsQ0FBQztBQUcvQixJQUFhLGtCQUFrQixHQUEvQixNQUFhLGtCQUFrQjtJQWtCN0IsWUFHVSxhQUE2QixzQkFBc0I7UUFBbkQsZUFBVSxHQUFWLFVBQVUsQ0FBeUM7UUFwQnJELG1CQUFjLEdBQUcsSUFBSSxlQUFlLENBQVUsS0FBSyxDQUFDLENBQUM7UUFDN0QsYUFBUSxHQUF3QixJQUFJLENBQUMsY0FBYyxDQUFDLFlBQVksRUFBRSxDQUFDO1FBRTNELHFCQUFnQixHQUFHLElBQUksT0FBTyxFQUFFLENBQUM7UUFDakMsZUFBVSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUNsRCxtQkFBYyxHQUFHLElBQUksT0FBTyxFQUFFLENBQUM7UUFDL0IsYUFBUSxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsWUFBWSxFQUFFLENBQUM7SUFlbkQsQ0FBQztJQUVKLFdBQVc7UUFDVCxJQUFJLElBQUksQ0FBQyxHQUFH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O1FBQ0wsQ0FBQyxDQUFDO0lBQ0osQ0FBQztJQUVELFVBQVUsQ0FBSSxJQUFtQjtRQUMvQixJQUFJLElBQUksQ0FBQyxHQUFHLElBQUksT0FBTyxJQUFJLENBQUMsR0FBRyxDQUFDLFdBQVcsS0FBSyxVQUFVLEVBQUU7WUFDMUQsSUFBSSxDQUFDLEdBQUcsQ0FBQyxXQUFXLEVBQUUsQ0FBQztTQUN4QjtRQUNELElBQUksQ0FBQyxHQUFHLEdBQUcsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBQ3pDLE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQzVCLEdBQUcsQ0FBQyxHQUFHLEVBQUU7WUFDUCxJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksRUFBRSxDQUFDO1FBQzdCLENBQUMsQ0FBQyxDQUNILENBQUM7UUFDRixPQUFPLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQ2xCLEdBQUcsQ0FBQyxHQUFHLEVBQUU7WUFDUCxJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDL0IsQ0FBQyxDQUFDLEVBQ0YsU0FBUyxDQUFDLEdBQUcsRUFBRSxDQUFDLFlBQVksQ0FBQyxFQUM3QixXQUFXLENBQUMsQ0FBQyxDQUFDLENBQ2YsQ0FBQztJQUNKLENBQUM7Q0FDRixDQUFBOzs0Q0FwSkksUUFBUSxZQUNSLE1BQU0sU0FBQyxvQkFBb0I7O0FBcEJuQixrQkFBa0I7SUFEOUIsVUFBVSxFQUFFO0lBb0JSLFdBQUEsUUFBUSxFQUFFLENBQUE7SUFDVixXQUFBLE1BQU0sQ0FBQyxvQkFBb0IsQ0FBQyxDQUFBO0dBcEJwQixrQkFBa0IsQ0F1SzlCO1NBdktZLGtCQUFrQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUsIEluamVjdCwgT3B0aW9uYWwsIE9uRGVzdHJveSB9IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XG5pbXBvcnQge1xuICBCZWhhdmlvclN1YmplY3QsXG4gIE9ic2VydmFibGUsXG4gIFN1YmplY3QsXG4gIFN1YnNjcmliZXIsXG4gIGNvbWJpbmVMYXRlc3QsXG4gIG1lcmdlLFxuICBvZixcbiAgdGltZXIsXG4gIFN1YnNjcmlwdGlvbixcbn0gZnJvbSBcInJ4anNcIjtcbmltcG9ydCB7XG4gIGNvbmNhdE1hcCxcbiAgZmlsdGVyLFxuICB0YXAsXG4gIG1hcFRvLFxuICBza2lwLFxuICBzdGFydFdpdGgsXG4gIHN3aXRjaE1hcCxcbiAgdGFrZVVudGlsLFxuICBzaGFyZVJlcGxheSxcbn0gZnJvbSBcInJ4anMvb3BlcmF0b3JzXCI7XG5pbXBvcnQge1xuICBMT0FESU5HX0NPTkZJR19UT0tFTixcbiAgTE9BRElOR19ERUZVQUxUX0NPTkZJRyxcbiAgSUxvYWRpbmdDb25maWcsXG59IGZyb20gXCIuL25neC1zdXNwZW5zZS5jb25maWdcIjtcblxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIE5neFN1c3BlbnNlU2VydmljZSBpbXBsZW1lbnRzIE9uRGVzdHJveSB7XG4gIHByaXZhdGUgbG9hZGluZ1N1YmplY3QgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+KGZhbHNlKTtcbiAgbG9hZGluZyQ6IE9ic2VydmFibGU8Ym9vbGVhbj4gPSB0aGlzLmxvYWRpbmdTdWJqZWN0LmFzT2JzZXJ2YWJsZSgpO1xuXG4gIHByaXZhdGUgdGFza1N0YXJ0U3ViamVjdCA9IG5ldyBTdWJqZWN0KCk7XG4gIHByaXZhdGUgdGFza1N0YXJ0JCA9IHRoaXMudGFza1N0YXJ0U3ViamVjdC5hc09ic2VydmFibGUoKTtcbiAgcHJpdmF0ZSB0YXNrRW5kU3ViamVjdCA9IG5ldyBTdWJqZWN0KCk7XG4gIHByaXZhdGUgdGFza0VuZCQgPSB0aGlzLnRhc2tFbmRTdWJqZWN0LmFzT2JzZXJ2YWJsZSgpO1xuXG4gIC8vIGFjY29yZGluZyB0byBGYWNlYm9vayBVSSB0ZWFtIHJlc2VhcmNoLCBpdCB3b3VsZCBiZSBhIGJldHRlclxuICAvLyB1c2VyIGV4cGVyaWVuY2UgdG8gc2hvdyBzcGlubmVyIGEgbGl0dGxlIGJpdCBsb25nZXIgdGhhblxuICAvLyB3aGVuIHVzZXIgaGFzIGEgaGlnaCBpbnRlcm5ldCBzcGVlZC5cbiAgLy8gQXZvaWQgZmxhc2hpbmcgc2NyZWVuXG4gIHByaXZhdGUgYnVzeU1pbkR1cmF0aW9uVGltZXI7XG4gIHByaXZhdGUgYnVzeURlbGF5VGltZXI7XG5cbiAgcHJpdmF0ZSBzdWI6IFN1YnNjcmlwdGlvbjtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBAT3B0aW9uYWwoKVxuICAgIEBJbmplY3QoTE9BRElOR19DT05GSUdfVE9LRU4pXG4gICAgcHJpdmF0ZSB1c2VyQ29uZmlnOiBJTG9hZGluZ0NvbmZpZyA9IExPQURJTkdfREVGVUFMVF9DT05GSUdcbiAgKSB7fVxuXG4gIG5nT25EZXN0cm95KCkge1xuICAgIGlmICh0aGlzLnN1YiAmJiB0eXBlb2YgdGhpcy5zdWIudW5zdWJzY3JpYmUgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgdGhpcy5zdWIudW5zdWJzY3JpYmUoKTtcbiAgICB9XG4gIH1cblxuICBzZXQgYnVzeVRpbWVyKHsgYnVzeURlbGF5TXMsIGJ1c3lNaW5EdXJhdGlvbk1zIH0pIHtcbiAgICBpZiAodHlwZW9mIGJ1c3lEZWxheU1zID09PSBcIm51bWJlclwiKSB7XG4gICAgICB0aGlzLnVzZXJDb25maWcuYnVzeURlbGF5TXMgPSBidXN5RGVsYXlNcztcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIGJ1c3lNaW5EdXJhdGlvbk1zID09PSBcIm51bWJlclwiKSB7XG4gICAgICB0aGlzLnVzZXJDb25maWcuYnVzeU1pbkR1cmF0aW9uTXMgPSBidXN5TWluRHVyYXRpb25NcztcbiAgICB9XG4gIH1cblxuICBnZXQgY29uZmlnKCkge1xuICAgIHJldHVybiB0aGlzLnVzZXJDb25maWc7XG4gIH1cblxuICBzaG93KCkge1xuICAgIHRoaXMubG9hZGluZ1N1YmplY3QubmV4dCh0cnVlKTtcbiAgfVxuXG4gIGhpZGUoKSB7XG4gICAgdGhpcy5sb2FkaW5nU3ViamVjdC5uZXh0KGZhbHNlKTtcbiAgfVxuXG4gIHByaXZhdGUgY29udHJvbGxlcigpIHtcbiAgICB0aGlzLmJ1c3lNaW5EdXJhdGlvblRpbWVyID0gdGltZXIoXG4gICAgICB0aGlzLmNvbmZpZy5idXN5TWluRHVyYXRpb25NcyArIHRoaXMuY29uZmlnLmJ1c3lEZWxheU1zXG4gICAgKTtcbiAgICB0aGlzLmJ1c3lEZWxheVRpbWVyID0gdGltZXIodGhpcy5jb25maWcuYnVzeURlbGF5TXMpO1xuICAgIGNvbnN0IGJ1c3lEZWxheVRpbWVyU3RhcnQgPSB0aGlzLnRhc2tTdGFydCQucGlwZShcbiAgICAgIHN3aXRjaE1hcCgoKSA9PiB0aGlzLmJ1c3lEZWxheVRpbWVyKVxuICAgICk7XG4gICAgY29uc3QgYnVzeURlbGF5VGltZXJFbmQgPSBidXN5RGVsYXlUaW1lclN0YXJ0LnBpcGUoXG4gICAgICB0YWtlVW50aWwodGhpcy50YXNrRW5kJClcbiAgICApO1xuICAgIGNvbnN0IGVtaXRPblRhc2tFbmQgPSB0aGlzLnRhc2tFbmQkLnBpcGUobWFwVG8oMSkpO1xuICAgIGNvbnN0IGVtaXRPbkRlbGF5VGltZXJFbmQgPSBidXN5RGVsYXlUaW1lckVuZC5waXBlKG1hcFRvKC0xKSk7XG4gICAgY29uc3QgZW1pdE9uTWluRHVyYXRpb25FbmQgPSB0aGlzLmJ1c3lNaW5EdXJhdGlvblRpbWVyLnBpcGUobWFwVG8oLTEpKTtcblxuICAgIC8vIFN0YXJ0IGxvYWRpbmcgc2tlbGV0b25cbiAgICBjb25zdCByYWNlQmV0d2VlblRhc2tBbmREZWxheSA9IGNvbWJpbmVMYXRlc3QoW1xuICAgICAgZW1pdE9uVGFza0VuZC5waXBlKHN0YXJ0V2l0aChudWxsKSksXG4gICAgICBlbWl0T25EZWxheVRpbWVyRW5kLnBpcGUoc3RhcnRXaXRoKG51bGwpKSxcbiAgICBdKS5waXBlKHNraXAoMSkpO1xuICAgIGNvbnN0IHRhc2tFbmRCZWZvcmVEZWxheSA9IHJhY2VCZXR3ZWVuVGFza0FuZERlbGF5LnBpcGUoXG4gICAgICBmaWx0ZXIoKFt0YXNrRW5kRmlyc3QsIHRpbWVyRW5kRmlyc3RdKSA9PiB7XG4gICAgICAgIHJldHVybiB0YXNrRW5kRmlyc3QgPT09IDEgJiYgdGltZXJFbmRGaXJzdCA9PT0gbnVsbDtcbiAgICAgIH0pXG4gICAgKTtcbiAgICBjb25zdCBzaG91bGROb3RTaG93U3Bpbm5lciA9IHRhc2tFbmRCZWZvcmVEZWxheS5waXBlKG1hcFRvKGZhbHNlKSk7XG4gICAgY29uc3QgdGFza0VuZEFmdGVyVGltZW91dCA9IHJhY2VCZXR3ZWVuVGFza0FuZERlbGF5LnBpcGUoXG4gICAgICBmaWx0ZXIoKFt0YXNrRW5kRmlyc3QsIHRpbWVyRW5kRmlyc3RdKSA9PiB7XG4gICAgICAgIHJldHVybiB0YXNrRW5kRmlyc3QgPT09IG51bGwgJiYgdGltZXJFbmRGaXJzdCA9PT0gLTE7XG4gICAgICB9KVxuICAgICk7XG4gICAgY29uc3Qgc2hvdWxkU2hvd1NwaW5uZXIgPSB0YXNrRW5kQWZ0ZXJUaW1lb3V0LnBpcGUobWFwVG8odHJ1ZSkpO1xuICAgIGNvbnN0IHNob3dTcGlubmVyID0gc2hvdWxkU2hvd1NwaW5uZXIucGlwZShcbiAgICAgIHRhcCgoKSA9PiB7XG4gICAgICAgIHRoaXMuc2hvdygpO1xuICAgICAgfSlcbiAgICApO1xuXG4gICAgLy8gaGlkZSBsb2FkaW5nIHNrZWxldG9uXG4gICAgY29uc3QgcmFjZUJldHdlZW5UYXNrQW5kTWluRHVyYXRpb24gPSBjb21iaW5lTGF0ZXN0KFtcbiAgICAgIGVtaXRPblRhc2tFbmQucGlwZShzdGFydFdpdGgobnVsbCkpLFxuICAgICAgZW1pdE9uTWluRHVyYXRpb25FbmQucGlwZShzdGFydFdpdGgobnVsbCkpLFxuICAgIF0pLnBpcGUoc2tpcCgxKSk7XG4gICAgY29uc3QgaGlkZVNwaW5uZXJVbnRpbE1pbkR1cmF0aW9uRW5kID0gcmFjZUJldHdlZW5UYXNrQW5kTWluRHVyYXRpb24ucGlwZShcbiAgICAgIGZpbHRlcigoW3Rhc2tFbmRGaXJzdCwgdGltZXJFbmRGaXJzdF0pID0+IHtcbiAgICAgICAgcmV0dXJuIHRhc2tFbmRGaXJzdCA9PT0gMSAmJiB0aW1lckVuZEZpcnN0ID09PSBudWxsO1xuICAgICAgfSlcbiAgICApO1xuICAgIGNvbnN0IGhpZGVTcGlubmVyQWZ0ZXJUaW1lckFuZFRhc2tFbmQgPSByYWNlQmV0d2VlblRhc2tBbmRNaW5EdXJhdGlvbi5waXBlKFxuICAgICAgZmlsdGVyKChbdGFza0VuZEZpcnN0LCB0aW1lckVuZEZpcnN0XSkgPT4ge1xuICAgICAgICByZXR1cm4gdGFza0VuZEZpcnN0ID09PSAxICYmIHRpbWVyRW5kRmlyc3QgPT09IC0xO1xuICAgICAgfSlcbiAgICApO1xuICAgIGNvbnN0IGhpZGVTcGlubmVyID0gbWVyZ2UoXG4gICAgICAvLyBjYXNlIDE6IHNob3VsZCBub3Qgc2hvdyBzcGlubmVyIGF0IGFsbFxuICAgICAgc2hvdWxkTm90U2hvd1NwaW5uZXIsXG4gICAgICAvLyBjYXNlIDI6IHRhc2sgZW5kLCBidXQgd2FpdCB1bnRpbCBtaW4gZHVyYXRpb24gdGltZXIgZW5kc1xuICAgICAgY29tYmluZUxhdGVzdChbaGlkZVNwaW5uZXJVbnRpbE1pbkR1cmF0aW9uRW5kLCBlbWl0T25NaW5EdXJhdGlvbkVuZF0pLFxuICAgICAgLy8gY2FzZSAzOiB0YXNrIHRha2VzIGEgbG9uZyB0aW1lLCB3YWl0IHVuaXRsIGl0cyBlbmRcbiAgICAgIGhpZGVTcGlubmVyQWZ0ZXJUaW1lckFuZFRhc2tFbmRcbiAgICApLnBpcGUoXG4gICAgICB0YXAoKCkgPT4ge1xuICAgICAgICB0aGlzLmhpZGUoKTtcbiAgICAgIH0pXG4gICAgKTtcbiAgICByZXR1cm4gc2hvd1NwaW5uZXIucGlwZSh0YWtlVW50aWwoaGlkZVNwaW5uZXIpKTtcbiAgfVxuXG4gIHNob3dMb2FkaW5nU3RhdHVzKCkge1xuICAgIGlmICh0aGlzLnN1YiAmJiB0eXBlb2YgdGhpcy5zdWIudW5zdWJzY3JpYmUgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgdGhpcy5zdWIudW5zdWJzY3JpYmUoKTtcbiAgICB9XG4gICAgdGhpcy5zdWIgPSB0aGlzLmNvbnRyb2xsZXIoKS5zdWJzY3JpYmUoKTtcbiAgICByZXR1cm4gKHNvdXJjZSkgPT4ge1xuICAgICAgcmV0dXJuIG5ldyBPYnNlcnZhYmxlKChzdWJzY3JpYmVyOiBTdWJzY3JpYmVyPGFueT4pID0+IHtcbiAgICAgICAgY29uc3QgZW1pdE9uT2JzRW5kID0gc291cmNlLnBpcGUoXG4gICAgICAgICAgdGFwKCgpID0+IHtcbiAgICAgICAgICAgIHRoaXMudGFza0VuZFN1YmplY3QubmV4dCgpO1xuICAgICAgICAgIH0pXG4gICAgICAgICk7XG4gICAgICAgIGNvbnN0IHN1YiA9IG9mKG51bGwpXG4gICAgICAgICAgLnBpcGUoXG4gICAgICAgICAgICB0YXAoKCkgPT4ge1xuICAgICAgICAgICAgICB0aGlzLnRhc2tTdGFydFN1YmplY3QubmV4dCgpO1xuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICBjb25jYXRNYXAoKCkgPT4gZW1pdE9uT2JzRW5kKSxcbiAgICAgICAgICAgIHNoYXJlUmVwbGF5KDEpXG4gICAgICAgICAgKVxuICAgICAgICAgIC5zdWJzY3JpYmUoc3Vic2NyaWJlcik7XG5cbiAgICAgICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgICBzdWIudW5zdWJzY3JpYmUoKTtcbiAgICAgICAgfTtcbiAgICAgIH0pO1xuICAgIH07XG4gIH1cblxuICBzaG93aW5nRm9yPFQ+KG9icyQ6IE9ic2VydmFibGU8VD4pOiBPYnNlcnZhYmxlPFQ+IHtcbiAgICBpZiAodGhpcy5zdWIgJiYgdHlwZW9mIHRoaXMuc3ViLnVuc3Vic2NyaWJlID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgIHRoaXMuc3ViLnVuc3Vic2NyaWJlKCk7XG4gICAgfVxuICAgIHRoaXMuc3ViID0gdGhpcy5jb250cm9sbGVyKCkuc3Vic2NyaWJlKCk7XG4gICAgY29uc3QgZW1pdE9uT2JzRW5kID0gb2JzJC5waXBlKFxuICAgICAgdGFwKCgpID0+IHtcbiAgICAgICAgdGhpcy50YXNrRW5kU3ViamVjdC5uZXh0KCk7XG4gICAgICB9KVxuICAgICk7XG4gICAgcmV0dXJuIG9mKG51bGwpLnBpcGUoXG4gICAgICB0YXAoKCkgPT4ge1xuICAgICAgICB0aGlzLnRhc2tTdGFydFN1YmplY3QubmV4dCgpO1xuICAgICAgfSksXG4gICAgICBjb25jYXRNYXAoKCkgPT4gZW1pdE9uT2JzRW5kKSxcbiAgICAgIHNoYXJlUmVwbGF5KDEpXG4gICAgKTtcbiAgfVxufVxuIl19