UNPKG

@ionic/angular

Version:

Angular specific wrappers for @ionic/core

269 lines • 37.3 kB
import { bindLifecycleEvents } from '../../providers/angular-delegate'; import { computeStackId, destroyView, getUrl, insertView, isTabSwitch, toSegments, } from './stack-utils'; // TODO(FW-2827): types export class StackController { constructor(tabsPrefix, containerEl, router, navCtrl, zone, location) { this.containerEl = containerEl; this.router = router; this.navCtrl = navCtrl; this.zone = zone; this.location = location; this.views = []; this.skipTransition = false; this.nextId = 0; this.tabsPrefix = tabsPrefix !== undefined ? toSegments(tabsPrefix) : undefined; } createView(ref, activatedRoute) { const url = getUrl(this.router, activatedRoute); const element = ref?.location?.nativeElement; const unlistenEvents = bindLifecycleEvents(this.zone, ref.instance, element); return { id: this.nextId++, stackId: computeStackId(this.tabsPrefix, url), unlistenEvents, element, ref, url, }; } getExistingView(activatedRoute) { const activatedUrlKey = getUrl(this.router, activatedRoute); const view = this.views.find((vw) => vw.url === activatedUrlKey); if (view) { view.ref.changeDetectorRef.reattach(); } return view; } setActive(enteringView) { const consumeResult = this.navCtrl.consumeTransition(); let { direction, animation, animationBuilder } = consumeResult; const leavingView = this.activeView; const tabSwitch = isTabSwitch(enteringView, leavingView); if (tabSwitch) { direction = 'back'; animation = undefined; } const viewsSnapshot = this.views.slice(); let currentNavigation; const router = this.router; // Angular >= 7.2.0 if (router.getCurrentNavigation) { currentNavigation = router.getCurrentNavigation(); // Angular < 7.2.0 } else if (router.navigations?.value) { currentNavigation = router.navigations.value; } /** * If the navigation action * sets `replaceUrl: true` * then we need to make sure * we remove the last item * from our views stack */ if (currentNavigation?.extras?.replaceUrl) { if (this.views.length > 0) { this.views.splice(-1, 1); } } const reused = this.views.includes(enteringView); const views = this.insertView(enteringView, direction); // Trigger change detection before transition starts // This will call ngOnInit() the first time too, just after the view // was attached to the dom, but BEFORE the transition starts if (!reused) { enteringView.ref.changeDetectorRef.detectChanges(); } /** * If we are going back from a page that * was presented using a custom animation * we should default to using that * unless the developer explicitly * provided another animation. */ const customAnimation = enteringView.animationBuilder; if (animationBuilder === undefined && direction === 'back' && !tabSwitch && customAnimation !== undefined) { animationBuilder = customAnimation; } /** * Save any custom animation so that navigating * back will use this custom animation by default. */ if (leavingView) { leavingView.animationBuilder = animationBuilder; } // Wait until previous transitions finish return this.zone.runOutsideAngular(() => { return this.wait(() => { // disconnect leaving page from change detection to // reduce jank during the page transition if (leavingView) { leavingView.ref.changeDetectorRef.detach(); } // In case the enteringView is the same as the leavingPage we need to reattach() enteringView.ref.changeDetectorRef.reattach(); return this.transition(enteringView, leavingView, animation, this.canGoBack(1), false, animationBuilder) .then(() => cleanupAsync(enteringView, views, viewsSnapshot, this.location, this.zone)) .then(() => ({ enteringView, direction, animation, tabSwitch, })); }); }); } canGoBack(deep, stackId = this.getActiveStackId()) { return this.getStack(stackId).length > deep; } pop(deep, stackId = this.getActiveStackId()) { return this.zone.run(() => { const views = this.getStack(stackId); if (views.length <= deep) { return Promise.resolve(false); } const view = views[views.length - deep - 1]; let url = view.url; const viewSavedData = view.savedData; if (viewSavedData) { const primaryOutlet = viewSavedData.get('primary'); if (primaryOutlet?.route?._routerState?.snapshot.url) { url = primaryOutlet.route._routerState.snapshot.url; } } const { animationBuilder } = this.navCtrl.consumeTransition(); return this.navCtrl.navigateBack(url, { ...view.savedExtras, animation: animationBuilder }).then(() => true); }); } startBackTransition() { const leavingView = this.activeView; if (leavingView) { const views = this.getStack(leavingView.stackId); const enteringView = views[views.length - 2]; const customAnimation = enteringView.animationBuilder; return this.wait(() => { return this.transition(enteringView, // entering view leavingView, // leaving view 'back', this.canGoBack(2), true, customAnimation); }); } return Promise.resolve(); } endBackTransition(shouldComplete) { if (shouldComplete) { this.skipTransition = true; this.pop(1); } else if (this.activeView) { cleanup(this.activeView, this.views, this.views, this.location, this.zone); } } getLastUrl(stackId) { const views = this.getStack(stackId); return views.length > 0 ? views[views.length - 1] : undefined; } /** * @internal */ getRootUrl(stackId) { const views = this.getStack(stackId); return views.length > 0 ? views[0] : undefined; } getActiveStackId() { return this.activeView ? this.activeView.stackId : undefined; } hasRunningTask() { return this.runningTask !== undefined; } destroy() { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion this.containerEl = undefined; this.views.forEach(destroyView); this.activeView = undefined; this.views = []; } getStack(stackId) { return this.views.filter((v) => v.stackId === stackId); } insertView(enteringView, direction) { this.activeView = enteringView; this.views = insertView(this.views, enteringView, direction); return this.views.slice(); } transition(enteringView, leavingView, direction, showGoBack, progressAnimation, animationBuilder) { if (this.skipTransition) { this.skipTransition = false; return Promise.resolve(false); } if (leavingView === enteringView) { return Promise.resolve(false); } const enteringEl = enteringView ? enteringView.element : undefined; const leavingEl = leavingView ? leavingView.element : undefined; const containerEl = this.containerEl; if (enteringEl && enteringEl !== leavingEl) { enteringEl.classList.add('ion-page'); enteringEl.classList.add('ion-page-invisible'); if (enteringEl.parentElement !== containerEl) { containerEl.appendChild(enteringEl); } if (containerEl.commit) { return containerEl.commit(enteringEl, leavingEl, { duration: direction === undefined ? 0 : undefined, direction, showGoBack, progressAnimation, animationBuilder, }); } } return Promise.resolve(false); } async wait(task) { if (this.runningTask !== undefined) { await this.runningTask; this.runningTask = undefined; } const promise = (this.runningTask = task()); promise.finally(() => (this.runningTask = undefined)); return promise; } } const cleanupAsync = (activeRoute, views, viewsSnapshot, location, zone) => { if (typeof requestAnimationFrame === 'function') { return new Promise((resolve) => { requestAnimationFrame(() => { cleanup(activeRoute, views, viewsSnapshot, location, zone); resolve(); }); }); } return Promise.resolve(); }; const cleanup = (activeRoute, views, viewsSnapshot, location, zone) => { /** * Re-enter the Angular zone when destroying page components. This will allow * lifecycle events (`ngOnDestroy`) to be run inside the Angular zone. */ zone.run(() => viewsSnapshot.filter((view) => !views.includes(view)).forEach(destroyView)); views.forEach((view) => { /** * In the event that a user navigated multiple * times in rapid succession, we want to make sure * we don't pre-emptively detach a view while * it is in mid-transition. * * In this instance we also do not care about query * params or fragments as it will be the same view regardless */ const locationWithoutParams = location.path().split('?')[0]; const locationWithoutFragment = locationWithoutParams.split('#')[0]; if (view !== activeRoute && view.url !== locationWithoutFragment) { const element = view.element; element.setAttribute('aria-hidden', 'true'); element.classList.add('ion-page-hidden'); view.ref.changeDetectorRef.detach(); } }); }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhY2stY29udHJvbGxlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9kaXJlY3RpdmVzL25hdmlnYXRpb24vc3RhY2stY29udHJvbGxlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFLQSxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQztBQUd2RSxPQUFPLEVBR0wsY0FBYyxFQUNkLFdBQVcsRUFDWCxNQUFNLEVBQ04sVUFBVSxFQUNWLFdBQVcsRUFDWCxVQUFVLEdBQ1gsTUFBTSxlQUFlLENBQUM7QUFFdkIsdUJBQXVCO0FBRXZCLE1BQU0sT0FBTyxlQUFlO0lBUTFCLFlBQ0UsVUFBOEIsRUFDdEIsV0FBdUMsRUFDdkMsTUFBYyxFQUNkLE9BQXNCLEVBQ3RCLElBQVksRUFDWixRQUFrQjtRQUpsQixnQkFBVyxHQUFYLFdBQVcsQ0FBNEI7UUFDdkMsV0FBTSxHQUFOLE1BQU0sQ0FBUTtRQUNkLFlBQU8sR0FBUCxPQUFPLENBQWU7UUFDdEIsU0FBSSxHQUFKLElBQUksQ0FBUTtRQUNaLGFBQVEsR0FBUixRQUFRLENBQVU7UUFicEIsVUFBSyxHQUFnQixFQUFFLENBQUM7UUFFeEIsbUJBQWMsR0FBRyxLQUFLLENBQUM7UUFHdkIsV0FBTSxHQUFHLENBQUMsQ0FBQztRQVVqQixJQUFJLENBQUMsVUFBVSxHQUFHLFVBQVUsS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO0lBQ2xGLENBQUM7SUFFRCxVQUFVLENBQUMsR0FBc0IsRUFBRSxjQUE4QjtRQUMvRCxNQUFNLEdBQUcsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxjQUFjLENBQUMsQ0FBQztRQUNoRCxNQUFNLE9BQU8sR0FBRyxHQUFHLEVBQUUsUUFBUSxFQUFFLGFBQTRCLENBQUM7UUFDNUQsTUFBTSxjQUFjLEdBQUcsbUJBQW1CLENBQUMs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QU0sT0FBTyxHQUFHLENBQ2QsV0FBc0IsRUFDdEIsS0FBa0IsRUFDbEIsYUFBMEIsRUFDMUIsUUFBa0IsRUFDbEIsSUFBWSxFQUNaLEVBQUU7SUFDRjs7O09BR0c7SUFDSCxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDO0lBRTNGLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRTtRQUNyQjs7Ozs7Ozs7V0FRRztRQUNILE1BQU0scUJBQXFCLEdBQUcsUUFBUSxDQUFDLElBQUksRUFBRSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM1RCxNQUFNLHVCQUF1QixHQUFHLHFCQUFxQixDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUVwRSxJQUFJLElBQUksS0FBSyxXQUFXLElBQUksSUFBSSxDQUFDLEdBQUcsS0FBSyx1QkFBdUIsRUFBRTtZQUNoRSxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDO1lBQzdCLE9BQU8sQ0FBQyxZQUFZLENBQUMsYUFBYSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQzVDLE9BQU8sQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLGlCQUFpQixDQUFDLENBQUM7WUFDekMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLEVBQUUsQ0FBQztTQUNyQztJQUNILENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgTG9jYXRpb24gfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgQ29tcG9uZW50UmVmLCBOZ1pvbmUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEFjdGl2YXRlZFJvdXRlLCBSb3V0ZXIgfSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xuaW1wb3J0IHsgQW5pbWF0aW9uQnVpbGRlciwgUm91dGVyRGlyZWN0aW9uIH0gZnJvbSAnQGlvbmljL2NvcmUnO1xuXG5pbXBvcnQgeyBiaW5kTGlmZWN5Y2xlRXZlbnRzIH0gZnJvbSAnLi4vLi4vcHJvdmlkZXJzL2FuZ3VsYXItZGVsZWdhdGUnO1xuaW1wb3J0IHsgTmF2Q29udHJvbGxlciB9IGZyb20gJy4uLy4uL3Byb3ZpZGVycy9uYXYtY29udHJvbGxlcic7XG5cbmltcG9ydCB7XG4gIFJvdXRlVmlldyxcbiAgU3RhY2tFdmVudCxcbiAgY29tcHV0ZVN0YWNrSWQsXG4gIGRlc3Ryb3lWaWV3LFxuICBnZXRVcmwsXG4gIGluc2VydFZpZXcsXG4gIGlzVGFiU3dpdGNoLFxuICB0b1NlZ21lbnRzLFxufSBmcm9tICcuL3N0YWNrLXV0aWxzJztcblxuLy8gVE9ETyhGVy0yODI3KTogdHlwZXNcblxuZXhwb3J0IGNsYXNzIFN0YWNrQ29udHJvbGxlciB7XG4gIHByaXZhdGUgdmlld3M6IFJvdXRlVmlld1tdID0gW107XG4gIHByaXZhdGUgcnVubmluZ1Rhc2s/OiBQcm9taXNlPGFueT47XG4gIHByaXZhdGUgc2tpcFRyYW5zaXRpb24gPSBmYWxzZTtcbiAgcHJpdmF0ZSB0YWJzUHJlZml4OiBzdHJpbmdbXSB8IHVuZGVmaW5lZDtcbiAgcHJpdmF0ZSBhY3RpdmVWaWV3OiBSb3V0ZVZpZXcgfCB1bmRlZmluZWQ7XG4gIHByaXZhdGUgbmV4dElkID0gMDtcblxuICBjb25zdHJ1Y3RvcihcbiAgICB0YWJzUHJlZml4OiBzdHJpbmcgfCB1bmRlZmluZWQsXG4gICAgcHJpdmF0ZSBjb250YWluZXJFbDogSFRNTElvblJvdXRlck91dGxldEVsZW1lbnQsXG4gICAgcHJpdmF0ZSByb3V0ZXI6IFJvdXRlcixcbiAgICBwcml2YXRlIG5hdkN0cmw6IE5hdkNvbnRyb2xsZXIsXG4gICAgcHJpdmF0ZSB6b25lOiBOZ1pvbmUsXG4gICAgcHJpdmF0ZSBsb2NhdGlvbjogTG9jYXRpb25cbiAgKSB7XG4gICAgdGhpcy50YWJzUHJlZml4ID0gdGFic1ByZWZpeCAhPT0gdW5kZWZpbmVkID8gdG9TZWdtZW50cyh0YWJzUHJlZml4KSA6IHVuZGVmaW5lZDtcbiAgfVxuXG4gIGNyZWF0ZVZpZXcocmVmOiBDb21wb25lbnRSZWY8YW55PiwgYWN0aXZhdGVkUm91dGU6IEFjdGl2YXRlZFJvdXRlKTogUm91dGVWaWV3IHtcbiAgICBjb25zdCB1cmwgPSBnZXRVcmwodGhpcy5yb3V0ZXIsIGFjdGl2YXRlZFJvdXRlKTtcbiAgICBjb25zdCBlbGVtZW50ID0gcmVmPy5sb2NhdGlvbj8ubmF0aXZlRWxlbWVudCBhcyBIVE1MRWxlbWVudDtcbiAgICBjb25zdCB1bmxpc3RlbkV2ZW50cyA9IGJpbmRMaWZlY3ljbGVFdmVudHModGhpcy56b25lLCByZWYuaW5zdGFuY2UsIGVsZW1lbnQpO1xuICAgIHJldHVybiB7XG4gICAgICBpZDogdGhpcy5uZXh0SWQrKyxcbiAgICAgIHN0YWNrSWQ6IGNvbXB1dGVTdGFja0lkKHRoaXMudGFic1ByZWZpeCwgdXJsKSxcbiAgICAgIHVubGlzdGVuRXZlbnRzLFxuICAgICAgZWxlbWVudCxcbiAgICAgIHJlZixcbiAgICAgIHVybCxcbiAgICB9O1xuICB9XG5cbiAgZ2V0RXhpc3RpbmdWaWV3KGFjdGl2YXRlZFJvdXRlOiBBY3RpdmF0ZWRSb3V0ZSk6IFJvdXRlVmlldyB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3QgYWN0aXZhdGVkVXJsS2V5ID0gZ2V0VXJsKHRoaXMucm91dGVyLCBhY3RpdmF0ZWRSb3V0ZSk7XG4gICAgY29uc3QgdmlldyA9IHRoaXMudmlld3MuZmluZCgodncpID0+IHZ3LnVybCA9PT0gYWN0aXZhdGVkVXJsS2V5KTtcbiAgICBpZiAodmlldykge1xuICAgICAgdmlldy5yZWYuY2hhbmdlRGV0ZWN0b3JSZWYucmVhdHRhY2goKTtcbiAgICB9XG4gICAgcmV0dXJuIHZpZXc7XG4gIH1cblxuICBzZXRBY3RpdmUoZW50ZXJpbmdWaWV3OiBSb3V0ZVZpZXcpOiBQcm9taXNlPFN0YWNrRXZlbnQ+IHtcbiAgICBjb25zdCBjb25zdW1lUmVzdWx0ID0gdGhpcy5uYXZDdHJsLmNvbnN1bWVUcmFuc2l0aW9uKCk7XG4gICAgbGV0IHsgZGlyZWN0aW9uLCBhbmltYXRpb24sIGFuaW1hdGlvbkJ1aWxkZXIgfSA9IGNvbnN1bWVSZXN1bHQ7XG4gICAgY29uc3QgbGVhdmluZ1ZpZXcgPSB0aGlzLmFjdGl2ZVZpZXc7XG4gICAgY29uc3QgdGFiU3dpdGNoID0gaXNUYWJTd2l0Y2goZW50ZXJpbmdWaWV3LCBsZWF2aW5nVmlldyk7XG4gICAgaWYgKHRhYlN3aXRjaCkge1xuICAgICAgZGlyZWN0aW9uID0gJ2JhY2snO1xuICAgICAgYW5pbWF0aW9uID0gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIGNvbnN0IHZpZXdzU25hcHNob3QgPSB0aGlzLnZpZXdzLnNsaWNlKCk7XG5cbiAgICBsZXQgY3VycmVudE5hdmlnYXRpb247XG5cbiAgICBjb25zdCByb3V0ZXIgPSB0aGlzLnJvdXRlciBhcyBhbnk7XG5cbiAgICAvLyBBbmd1bGFyID49IDcuMi4wXG4gICAgaWYgKHJvdXRlci5nZXRDdXJyZW50TmF2aWdhdGlvbikge1xuICAgICAgY3VycmVudE5hdmlnYXRpb24gPSByb3V0ZXIuZ2V0Q3VycmVudE5hdmlnYXRpb24oKTtcblxuICAgICAgLy8gQW5ndWxhciA8IDcuMi4wXG4gICAgfSBlbHNlIGlmIChyb3V0ZXIubmF2aWdhdGlvbnM/LnZhbHVlKSB7XG4gICAgICBjdXJyZW50TmF2aWdhdGlvbiA9IHJvdXRlci5uYXZpZ2F0aW9ucy52YWx1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBJZiB0aGUgbmF2aWdhdGlvbiBhY3Rpb25cbiAgICAgKiBzZXRzIGByZXBsYWNlVXJsOiB0cnVlYFxuICAgICAqIHRoZW4gd2UgbmVlZCB0byBtYWtlIHN1cmVcbiAgICAgKiB3ZSByZW1vdmUgdGhlIGxhc3QgaXRlbVxuICAgICAqIGZyb20gb3VyIHZpZXdzIHN0YWNrXG4gICAgICovXG4gICAgaWYgKGN1cnJlbnROYXZpZ2F0aW9uPy5leHRyYXM/LnJlcGxhY2VVcmwpIHtcbiAgICAgIGlmICh0aGlzLnZpZXdzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgdGhpcy52aWV3cy5zcGxpY2UoLTEsIDEpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IHJldXNlZCA9IHRoaXMudmlld3MuaW5jbHVkZXMoZW50ZXJpbmdWaWV3KTtcbiAgICBjb25zdCB2aWV3cyA9IHRoaXMuaW5zZXJ0VmlldyhlbnRlcmluZ1ZpZXcsIGRpcmVjdGlvbik7XG5cbiAgICAvLyBUcmlnZ2VyIGNoYW5nZSBkZXRlY3Rpb24gYmVmb3JlIHRyYW5zaXRpb24gc3RhcnRzXG4gICAgLy8gVGhpcyB3aWxsIGNhbGwgbmdPbkluaXQoKSB0aGUgZmlyc3QgdGltZSB0b28sIGp1c3QgYWZ0ZXIgdGhlIHZpZXdcbiAgICAvLyB3YXMgYXR0YWNoZWQgdG8gdGhlIGRvbSwgYnV0IEJFRk9SRSB0aGUgdHJhbnNpdGlvbiBzdGFydHNcbiAgICBpZiAoIXJldXNlZCkge1xuICAgICAgZW50ZXJpbmdWaWV3LnJlZi5jaGFuZ2VEZXRlY3RvclJlZi5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSWYgd2UgYXJlIGdvaW5nIGJhY2sgZnJvbSBhIHBhZ2UgdGhhdFxuICAgICAqIHdhcyBwcmVzZW50ZWQgdXNpbmcgYSBjdXN0b20gYW5pbWF0aW9uXG4gICAgICogd2Ugc2hvdWxkIGRlZmF1bHQgdG8gdXNpbmcgdGhhdFxuICAgICAqIHVubGVzcyB0aGUgZGV2ZWxvcGVyIGV4cGxpY2l0bHlcbiAgICAgKiBwcm92aWRlZCBhbm90aGVyIGFuaW1hdGlvbi5cbiAgICAgKi9cbiAgICBjb25zdCBjdXN0b21BbmltYXRpb24gPSBlbnRlcmluZ1ZpZXcuYW5pbWF0aW9uQnVpbGRlcjtcbiAgICBpZiAoYW5pbWF0aW9uQnVpbGRlciA9PT0gdW5kZWZpbmVkICYmIGRpcmVjdGlvbiA9PT0gJ2JhY2snICYmICF0YWJTd2l0Y2ggJiYgY3VzdG9tQW5pbWF0aW9uICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGFuaW1hdGlvbkJ1aWxkZXIgPSBjdXN0b21BbmltYXRpb247XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2F2ZSBhbnkgY3VzdG9tIGFuaW1hdGlvbiBzbyB0aGF0IG5hdmlnYXRpbmdcbiAgICAgKiBiYWNrIHdpbGwgdXNlIHRoaXMgY3VzdG9tIGFuaW1hdGlvbiBieSBkZWZhdWx0LlxuICAgICAqL1xuICAgIGlmIChsZWF2aW5nVmlldykge1xuICAgICAgbGVhdmluZ1ZpZXcuYW5pbWF0aW9uQnVpbGRlciA9IGFuaW1hdGlvbkJ1aWxkZXI7XG4gICAgfVxuXG4gICAgLy8gV2FpdCB1bnRpbCBwcmV2aW91cyB0cmFuc2l0aW9ucyBmaW5pc2hcbiAgICByZXR1cm4gdGhpcy56b25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcbiAgICAgIHJldHVybiB0aGlzLndhaXQoKCkgPT4ge1xuICAgICAgICAvLyBkaXNjb25uZWN0IGxlYXZpbmcgcGFnZSBmcm9tIGNoYW5nZSBkZXRlY3Rpb24gdG9cbiAgICAgICAgLy8gcmVkdWNlIGphbmsgZHVyaW5nIHRoZSBwYWdlIHRyYW5zaXRpb25cbiAgICAgICAgaWYgKGxlYXZpbmdWaWV3KSB7XG4gICAgICAgICAgbGVhdmluZ1ZpZXcucmVmLmNoYW5nZURldGVjdG9yUmVmLmRldGFjaCgpO1xuICAgICAgICB9XG4gICAgICAgIC8vIEluIGNhc2UgdGhlIGVudGVyaW5nVmlldyBpcyB0aGUgc2FtZSBhcyB0aGUgbGVhdmluZ1BhZ2Ugd2UgbmVlZCB0byByZWF0dGFjaCgpXG4gICAgICAgIGVudGVyaW5nVmlldy5yZWYuY2hhbmdlRGV0ZWN0b3JSZWYucmVhdHRhY2goKTtcblxuICAgICAgICByZXR1cm4gdGhpcy50cmFuc2l0aW9uKGVudGVyaW5nVmlldywgbGVhdmluZ1ZpZXcsIGFuaW1hdGlvbiwgdGhpcy5jYW5Hb0JhY2soMSksIGZhbHNlLCBhbmltYXRpb25CdWlsZGVyKVxuICAgICAgICAgIC50aGVuKCgpID0+IGNsZWFudXBBc3luYyhlbnRlcmluZ1ZpZXcsIHZpZXdzLCB2aWV3c1NuYXBzaG90LCB0aGlzLmxvY2F0aW9uLCB0aGlzLnpvbmUpKVxuICAgICAgICAgIC50aGVuKCgpID0+ICh7XG4gICAgICAgICAgICBlbnRlcmluZ1ZpZXcsXG4gICAgICAgICAgICBkaXJlY3Rpb24sXG4gICAgICAgICAgICBhbmltYXRpb24sXG4gICAgICAgICAgICB0YWJTd2l0Y2gsXG4gICAgICAgICAgfSkpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICBjYW5Hb0JhY2soZGVlcDogbnVtYmVyLCBzdGFja0lkID0gdGhpcy5nZXRBY3RpdmVTdGFja0lkKCkpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5nZXRTdGFjayhzdGFja0lkKS5sZW5ndGggPiBkZWVwO1xuICB9XG5cbiAgcG9wKGRlZXA6IG51bWJlciwgc3RhY2tJZCA9IHRoaXMuZ2V0QWN0aXZlU3RhY2tJZCgpKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgcmV0dXJuIHRoaXMuem9uZS5ydW4oKCkgPT4ge1xuICAgICAgY29uc3Qgdmlld3MgPSB0aGlzLmdldFN0YWNrKHN0YWNrSWQpO1xuICAgICAgaWYgKHZpZXdzLmxlbmd0aCA8PSBkZWVwKSB7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoZmFsc2UpO1xuICAgICAgfVxuICAgICAgY29uc3QgdmlldyA9IHZpZXdzW3ZpZXdzLmxlbmd0aCAtIGRlZXAgLSAxXTtcbiAgICAgIGxldCB1cmwgPSB2aWV3LnVybDtcblxuICAgICAgY29uc3Qgdmlld1NhdmVkRGF0YSA9IHZpZXcuc2F2ZWREYXRhO1xuICAgICAgaWYgKHZpZXdTYXZlZERhdGEpIHtcbiAgICAgICAgY29uc3QgcHJpbWFyeU91dGxldCA9IHZpZXdTYXZlZERhdGEuZ2V0KCdwcmltYXJ5Jyk7XG4gICAgICAgIGlmIChwcmltYXJ5T3V0bGV0Py5yb3V0ZT8uX3JvdXRlclN0YXRlPy5zbmFwc2hvdC51cmwpIHtcbiAgICAgICAgICB1cmwgPSBwcmltYXJ5T3V0bGV0LnJvdXRlLl9yb3V0ZXJTdGF0ZS5zbmFwc2hvdC51cmw7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGNvbnN0IHsgYW5pbWF0aW9uQnVpbGRlciB9ID0gdGhpcy5uYXZDdHJsLmNvbnN1bWVUcmFuc2l0aW9uKCk7XG4gICAgICByZXR1cm4gdGhpcy5uYXZDdHJsLm5hdmlnYXRlQmFjayh1cmwsIHsgLi4udmlldy5zYXZlZEV4dHJhcywgYW5pbWF0aW9uOiBhbmltYXRpb25CdWlsZGVyIH0pLnRoZW4oKCkgPT4gdHJ1ZSk7XG4gICAgfSk7XG4gIH1cblxuICBzdGFydEJhY2tUcmFuc2l0aW9uKCk6IFByb21pc2U8Ym9vbGVhbj4gfCBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBsZWF2aW5nVmlldyA9IHRoaXMuYWN0aXZlVmlldztcbiAgICBpZiAobGVhdmluZ1ZpZXcpIHtcbiAgICAgIGNvbnN0IHZpZXdzID0gdGhpcy5nZXRTdGFjayhsZWF2aW5nVmlldy5zdGFja0lkKTtcbiAgICAgIGNvbnN0IGVudGVyaW5nVmlldyA9IHZpZXdzW3ZpZXdzLmxlbmd0aCAtIDJdO1xuICAgICAgY29uc3QgY3VzdG9tQW5pbWF0aW9uID0gZW50ZXJpbmdWaWV3LmFuaW1hdGlvbkJ1aWxkZXI7XG5cbiAgICAgIHJldHVybiB0aGlzLndhaXQoKCkgPT4ge1xuICAgICAgICByZXR1cm4gdGhpcy50cmFuc2l0aW9uKFxuICAgICAgICAgIGVudGVyaW5nVmlldywgLy8gZW50ZXJpbmcgdmlld1xuICAgICAgICAgIGxlYXZpbmdWaWV3LCAvLyBsZWF2aW5nIHZpZXdcbiAgICAgICAgICAnYmFjaycsXG4gICAgICAgICAgdGhpcy5jYW5Hb0JhY2soMiksXG4gICAgICAgICAgdHJ1ZSxcbiAgICAgICAgICBjdXN0b21BbmltYXRpb25cbiAgICAgICAgKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cblxuICBlbmRCYWNrVHJhbnNpdGlvbihzaG91bGRDb21wbGV0ZTogYm9vbGVhbik6IHZvaWQge1xuICAgIGlmIChzaG91bGRDb21wbGV0ZSkge1xuICAgICAgdGhpcy5za2lwVHJhbnNpdGlvbiA9IHRydWU7XG4gICAgICB0aGlzLnBvcCgxKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuYWN0aXZlVmlldykge1xuICAgICAgY2xlYW51cCh0aGlzLmFjdGl2ZVZpZXcsIHRoaXMudmlld3MsIHRoaXMudmlld3MsIHRoaXMubG9jYXRpb24sIHRoaXMuem9uZSk7XG4gICAgfVxuICB9XG5cbiAgZ2V0TGFzdFVybChzdGFja0lkPzogc3RyaW5nKTogUm91dGVWaWV3IHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCB2aWV3cyA9IHRoaXMuZ2V0U3RhY2soc3RhY2tJZCk7XG4gICAgcmV0dXJuIHZpZXdzLmxlbmd0aCA+IDAgPyB2aWV3c1t2aWV3cy5sZW5ndGggLSAxXSA6IHVuZGVmaW5lZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIGdldFJvb3RVcmwoc3RhY2tJZD86IHN0cmluZyk6IFJvdXRlVmlldyB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3Qgdmlld3MgPSB0aGlzLmdldFN0YWNrKHN0YWNrSWQpO1xuICAgIHJldHVybiB2aWV3cy5sZW5ndGggPiAwID8gdmlld3NbMF0gOiB1bmRlZmluZWQ7XG4gIH1cblxuICBnZXRBY3RpdmVTdGFja0lkKCk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMuYWN0aXZlVmlldyA/IHRoaXMuYWN0aXZlVmlldy5zdGFja0lkIDogdW5kZWZpbmVkO1xuICB9XG5cbiAgaGFzUnVubmluZ1Rhc2soKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMucnVubmluZ1Rhc2sgIT09IHVuZGVmaW5lZDtcbiAgfVxuXG4gIGRlc3Ryb3koKTogdm9pZCB7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb25cbiAgICB0aGlzLmNvbnRhaW5lckVsID0gdW5kZWZpbmVkITtcbiAgICB0aGlzLnZpZXdzLmZvckVhY2goZGVzdHJveVZpZXcpO1xuICAgIHRoaXMuYWN0aXZlVmlldyA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLnZpZXdzID0gW107XG4gIH1cblxuICBwcml2YXRlIGdldFN0YWNrKHN0YWNrSWQ6IHN0cmluZyB8IHVuZGVmaW5lZCkge1xuICAgIHJldHVybiB0aGlzLnZpZXdzLmZpbHRlcigodikgPT4gdi5zdGFja0lkID09PSBzdGFja0lkKTtcbiAgfVxuXG4gIHByaXZhdGUgaW5zZXJ0VmlldyhlbnRlcmluZ1ZpZXc6IFJvdXRlVmlldywgZGlyZWN0aW9uOiBSb3V0ZXJEaXJlY3Rpb24pIHtcbiAgICB0aGlzLmFjdGl2ZVZpZXcgPSBlbnRlcmluZ1ZpZXc7XG4gICAgdGhpcy52aWV3cyA9IGluc2VydFZpZXcodGhpcy52aWV3cywgZW50ZXJpbmdWaWV3LCBkaXJlY3Rpb24pO1xuICAgIHJldHVybiB0aGlzLnZpZXdzLnNsaWNlKCk7XG4gIH1cblxuICBwcml2YXRlIHRyYW5zaXRpb24oXG4gICAgZW50ZXJpbmdWaWV3OiBSb3V0ZVZpZXcgfCB1bmRlZmluZWQsXG4gICAgbGVhdmluZ1ZpZXc6IFJvdXRlVmlldyB8IHVuZGVmaW5lZCxcbiAgICBkaXJlY3Rpb246ICdmb3J3YXJkJyB8ICdiYWNrJyB8IHVuZGVmaW5lZCxcbiAgICBzaG93R29CYWNrOiBib29sZWFuLFxuICAgIHByb2dyZXNzQW5pbWF0aW9uOiBib29sZWFuLFxuICAgIGFuaW1hdGlvbkJ1aWxkZXI/OiBBbmltYXRpb25CdWlsZGVyXG4gICkge1xuICAgIGlmICh0aGlzLnNraXBUcmFuc2l0aW9uKSB7XG4gICAgICB0aGlzLnNraXBUcmFuc2l0aW9uID0gZmFsc2U7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGZhbHNlKTtcbiAgICB9XG4gICAgaWYgKGxlYXZpbmdWaWV3ID09PSBlbnRlcmluZ1ZpZXcpIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoZmFsc2UpO1xuICAgIH1cbiAgICBjb25zdCBlbnRlcmluZ0VsID0gZW50ZXJpbmdWaWV3ID8gZW50ZXJpbmdWaWV3LmVsZW1lbnQgOiB1bmRlZmluZWQ7XG4gICAgY29uc3QgbGVhdmluZ0VsID0gbGVhdmluZ1ZpZXcgPyBsZWF2aW5nVmlldy5lbGVtZW50IDogdW5kZWZpbmVkO1xuICAgIGNvbnN0IGNvbnRhaW5lckVsID0gdGhpcy5jb250YWluZXJFbDtcbiAgICBpZiAoZW50ZXJpbmdFbCAmJiBlbnRlcmluZ0VsICE9PSBsZWF2aW5nRWwpIHtcbiAgICAgIGVudGVyaW5nRWwuY2xhc3NMaXN0LmFkZCgnaW9uLXBhZ2UnKTtcbiAgICAgIGVudGVyaW5nRWwuY2xhc3NMaXN0LmFkZCgnaW9uLXBhZ2UtaW52aXNpYmxlJyk7XG4gICAgICBpZiAoZW50ZXJpbmdFbC5wYXJlbnRFbGVtZW50ICE9PSBjb250YWluZXJFbCkge1xuICAgICAgICBjb250YWluZXJFbC5hcHBlbmRDaGlsZChlbnRlcmluZ0VsKTtcbiAgICAgIH1cblxuICAgICAgaWYgKChjb250YWluZXJFbCBhcyBhbnkpLmNvbW1pdCkge1xuICAgICAgICByZXR1cm4gY29udGFpbmVyRWwuY29tbWl0KGVudGVyaW5nRWwsIGxlYXZpbmdFbCwge1xuICAgICAgICAgIGR1cmF0aW9uOiBkaXJlY3Rpb24gPT09IHVuZGVmaW5lZCA/IDAgOiB1bmRlZmluZWQsXG4gICAgICAgICAgZGlyZWN0aW9uLFxuICAgICAgICAgIHNob3dHb0JhY2ssXG4gICAgICAgICAgcHJvZ3Jlc3NBbmltYXRpb24sXG4gICAgICAgICAgYW5pbWF0aW9uQnVpbGRlcixcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoZmFsc2UpO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyB3YWl0PFQ+KHRhc2s6ICgpID0+IFByb21pc2U8VD4pOiBQcm9taXNlPFQ+IHtcbiAgICBpZiAodGhpcy5ydW5uaW5nVGFzayAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBhd2FpdCB0aGlzLnJ1bm5pbmdUYXNrO1xuICAgICAgdGhpcy5ydW5uaW5nVGFzayA9IHVuZGVmaW5lZDtcbiAgICB9XG4gICAgY29uc3QgcHJvbWlzZSA9ICh0aGlzLnJ1bm5pbmdUYXNrID0gdGFzaygpKTtcbiAgICBwcm9taXNlLmZpbmFsbHkoKCkgPT4gKHRoaXMucnVubmluZ1Rhc2sgPSB1bmRlZmluZWQpKTtcbiAgICByZXR1cm4gcHJvbWlzZTtcbiAgfVxufVxuXG5jb25zdCBjbGVhbnVwQXN5bmMgPSAoXG4gIGFjdGl2ZVJvdXRlOiBSb3V0ZVZpZXcsXG4gIHZpZXdzOiBSb3V0ZVZpZXdbXSxcbiAgdmlld3NTbmFwc2hvdDogUm91dGVWaWV3W10sXG4gIGxvY2F0aW9uOiBMb2NhdGlvbixcbiAgem9uZTogTmdab25lXG4pID0+IHtcbiAgaWYgKHR5cGVvZiAocmVxdWVzdEFuaW1hdGlvbkZyYW1lIGFzIGFueSkgPT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gbmV3IFByb21pc2U8dm9pZD4oKHJlc29sdmUpID0+IHtcbiAgICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB7XG4gICAgICAgIGNsZWFudXAoYWN0aXZlUm91dGUsIHZpZXdzLCB2aWV3c1NuYXBzaG90LCBsb2NhdGlvbiwgem9uZSk7XG4gICAgICAgIHJlc29sdmUoKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbn07XG5cbmNvbnN0IGNsZWFudXAgPSAoXG4gIGFjdGl2ZVJvdXRlOiBSb3V0ZVZpZXcsXG4gIHZpZXdzOiBSb3V0ZVZpZXdbXSxcbiAgdmlld3NTbmFwc2hvdDogUm91dGVWaWV3W10sXG4gIGxvY2F0aW9uOiBMb2NhdGlvbixcbiAgem9uZTogTmdab25lXG4pID0+IHtcbiAgLyoqXG4gICAqIFJlLWVudGVyIHRoZSBBbmd1bGFyIHpvbmUgd2hlbiBkZXN0cm95aW5nIHBhZ2UgY29tcG9uZW50cy4gVGhpcyB3aWxsIGFsbG93XG4gICAqIGxpZmVjeWNsZSBldmVudHMgKGBuZ09uRGVzdHJveWApIHRvIGJlIHJ1biBpbnNpZGUgdGhlIEFuZ3VsYXIgem9uZS5cbiAgICovXG4gIHpvbmUucnVuKCgpID0+IHZpZXdzU25hcHNob3QuZmlsdGVyKCh2aWV3KSA9PiAhdmlld3MuaW5jbHVkZXModmlldykpLmZvckVhY2goZGVzdHJveVZpZXcpKTtcblxuICB2aWV3cy5mb3JFYWNoKCh2aWV3KSA9PiB7XG4gICAgLyoqXG4gICAgICogSW4gdGhlIGV2ZW50IHRoYXQgYSB1c2VyIG5hdmlnYXRlZCBtdWx0aXBsZVxuICAgICAqIHRpbWVzIGluIHJhcGlkIHN1Y2Nlc3Npb24sIHdlIHdhbnQgdG8gbWFrZSBzdXJlXG4gICAgICogd2UgZG9uJ3QgcHJlLWVtcHRpdmVseSBkZXRhY2ggYSB2aWV3IHdoaWxlXG4gICAgICogaXQgaXMgaW4gbWlkLXRyYW5zaXRpb24uXG4gICAgICpcbiAgICAgKiBJbiB0aGlzIGluc3RhbmNlIHdlIGFsc28gZG8gbm90IGNhcmUgYWJvdXQgcXVlcnlcbiAgICAgKiBwYXJhbXMgb3IgZnJhZ21lbnRzIGFzIGl0IHdpbGwgYmUgdGhlIHNhbWUgdmlldyByZWdhcmRsZXNzXG4gICAgICovXG4gICAgY29uc3QgbG9jYXRpb25XaXRob3V0UGFyYW1zID0gbG9jYXRpb24ucGF0aCgpLnNwbGl0KCc/JylbMF07XG4gICAgY29uc3QgbG9jYXRpb25XaXRob3V0RnJhZ21lbnQgPSBsb2NhdGlvbldpdGhvdXRQYXJhbXMuc3BsaXQoJyMnKVswXTtcblxuICAgIGlmICh2aWV3ICE9PSBhY3RpdmVSb3V0ZSAmJiB2aWV3LnVybCAhPT0gbG9jYXRpb25XaXRob3V0RnJhZ21lbnQpIHtcbiAgICAgIGNvbnN0IGVsZW1lbnQgPSB2aWV3LmVsZW1lbnQ7XG4gICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZSgnYXJpYS1oaWRkZW4nLCAndHJ1ZScpO1xuICAgICAgZWxlbWVudC5jbGFzc0xpc3QuYWRkKCdpb24tcGFnZS1oaWRkZW4nKTtcbiAgICAgIHZpZXcucmVmLmNoYW5nZURldGVjdG9yUmVmLmRldGFjaCgpO1xuICAgIH1cbiAgfSk7XG59O1xuIl19