UNPKG

@ionic/angular

Version:

Angular specific wrappers for @ionic/core

275 lines • 37.7 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; } /** * @internal */ getActiveView() { return this.activeView; } 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhY2stY29udHJvbGxlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL2NvbW1vbi9zcmMvZGlyZWN0aXZlcy9uYXZpZ2F0aW9uL3N0YWNrLWNvbnRyb2xsZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBS0EsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFHdkUsT0FBTyxFQUdMLGNBQWMsRUFDZCxXQUFXLEVBQ1gsTUFBTSxFQUNOLFVBQVUsRUFDVixXQUFXLEVBQ1gsVUFBVSxHQUNYLE1BQU0sZUFBZSxDQUFDO0FBRXZCLHVCQUF1QjtBQUV2QixNQUFNLE9BQU8sZUFBZTtJQVExQixZQUNFLFVBQThCLEVBQ3RCLFdBQXVDLEVBQ3ZDLE1BQWMsRUFDZCxPQUFzQixFQUN0QixJQUFZLEVBQ1osUUFBa0I7UUFKbEIsZ0JBQVcsR0FBWCxXQUFXLENBQTRCO1FBQ3ZDLFdBQU0sR0FBTixNQUFNLENBQVE7UUFDZCxZQUFPLEdBQVAsT0FBTyxDQUFlO1FBQ3RCLFNBQUksR0FBSixJQUFJLENBQVE7UUFDWixhQUFRLEdBQVIsUUFBUSxDQUFVO1FBYnBCLFVBQUssR0FBZ0IsRUFBRSxDQUFDO1FBRXhCLG1CQUFjLEdBQUcsS0FBSyxDQUFDO1FBR3ZCLFdBQU0sR0FBRyxDQUFDLENBQUM7UUFVakIsSUFBSSxDQUFDLFVBQVUsR0FBRyxVQUFVLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztJQUNsRixDQUFDO0lBRUQsVUFBVSxDQUFDLEdBQXNCLEVBQUUsY0FBOEI7UUFDL0QsTUFBTSxHQUFHLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsY0FBYyxDQUFDLENBQUM7UUFDaEQsTUFBTSxPQUFPLEdBQUcsR0FBRyxFQUFFLFFBQVEsRUFBRSxhQUE0QixDQUFDO1FBQzVELE1BQU0sY0FBYyxHQUFHLG1C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YW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgQ29tcG9uZW50UmVmLCBOZ1pvbmUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEFjdGl2YXRlZFJvdXRlLCBSb3V0ZXIgfSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xuaW1wb3J0IHR5cGUgeyBBbmltYXRpb25CdWlsZGVyLCBSb3V0ZXJEaXJlY3Rpb24gfSBmcm9tICdAaW9uaWMvY29yZS9jb21wb25lbnRzJztcblxuaW1wb3J0IHsgYmluZExpZmVjeWNsZUV2ZW50cyB9IGZyb20gJy4uLy4uL3Byb3ZpZGVycy9hbmd1bGFyLWRlbGVnYXRlJztcbmltcG9ydCB7IE5hdkNvbnRyb2xsZXIgfSBmcm9tICcuLi8uLi9wcm92aWRlcnMvbmF2LWNvbnRyb2xsZXInO1xuXG5pbXBvcnQge1xuICBSb3V0ZVZpZXcsXG4gIFN0YWNrRGlkQ2hhbmdlRXZlbnQsXG4gIGNvbXB1dGVTdGFja0lkLFxuICBkZXN0cm95VmlldyxcbiAgZ2V0VXJsLFxuICBpbnNlcnRWaWV3LFxuICBpc1RhYlN3aXRjaCxcbiAgdG9TZWdtZW50cyxcbn0gZnJvbSAnLi9zdGFjay11dGlscyc7XG5cbi8vIFRPRE8oRlctMjgyNyk6IHR5cGVzXG5cbmV4cG9ydCBjbGFzcyBTdGFja0NvbnRyb2xsZXIge1xuICBwcml2YXRlIHZpZXdzOiBSb3V0ZVZpZXdbXSA9IFtdO1xuICBwcml2YXRlIHJ1bm5pbmdUYXNrPzogUHJvbWlzZTxhbnk+O1xuICBwcml2YXRlIHNraXBUcmFuc2l0aW9uID0gZmFsc2U7XG4gIHByaXZhdGUgdGFic1ByZWZpeDogc3RyaW5nW10gfCB1bmRlZmluZWQ7XG4gIHByaXZhdGUgYWN0aXZlVmlldzogUm91dGVWaWV3IHwgdW5kZWZpbmVkO1xuICBwcml2YXRlIG5leHRJZCA9IDA7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgdGFic1ByZWZpeDogc3RyaW5nIHwgdW5kZWZpbmVkLFxuICAgIHByaXZhdGUgY29udGFpbmVyRWw6IEhUTUxJb25Sb3V0ZXJPdXRsZXRFbGVtZW50LFxuICAgIHByaXZhdGUgcm91dGVyOiBSb3V0ZXIsXG4gICAgcHJpdmF0ZSBuYXZDdHJsOiBOYXZDb250cm9sbGVyLFxuICAgIHByaXZhdGUgem9uZTogTmdab25lLFxuICAgIHByaXZhdGUgbG9jYXRpb246IExvY2F0aW9uXG4gICkge1xuICAgIHRoaXMudGFic1ByZWZpeCA9IHRhYnNQcmVmaXggIT09IHVuZGVmaW5lZCA/IHRvU2VnbWVudHModGFic1ByZWZpeCkgOiB1bmRlZmluZWQ7XG4gIH1cblxuICBjcmVhdGVWaWV3KHJlZjogQ29tcG9uZW50UmVmPGFueT4sIGFjdGl2YXRlZFJvdXRlOiBBY3RpdmF0ZWRSb3V0ZSk6IFJvdXRlVmlldyB7XG4gICAgY29uc3QgdXJsID0gZ2V0VXJsKHRoaXMucm91dGVyLCBhY3RpdmF0ZWRSb3V0ZSk7XG4gICAgY29uc3QgZWxlbWVudCA9IHJlZj8ubG9jYXRpb24/Lm5hdGl2ZUVsZW1lbnQgYXMgSFRNTEVsZW1lbnQ7XG4gICAgY29uc3QgdW5saXN0ZW5FdmVudHMgPSBiaW5kTGlmZWN5Y2xlRXZlbnRzKHRoaXMuem9uZSwgcmVmLmluc3RhbmNlLCBlbGVtZW50KTtcbiAgICByZXR1cm4ge1xuICAgICAgaWQ6IHRoaXMubmV4dElkKyssXG4gICAgICBzdGFja0lkOiBjb21wdXRlU3RhY2tJZCh0aGlzLnRhYnNQcmVmaXgsIHVybCksXG4gICAgICB1bmxpc3RlbkV2ZW50cyxcbiAgICAgIGVsZW1lbnQsXG4gICAgICByZWYsXG4gICAgICB1cmwsXG4gICAgfTtcbiAgfVxuXG4gIGdldEV4aXN0aW5nVmlldyhhY3RpdmF0ZWRSb3V0ZTogQWN0aXZhdGVkUm91dGUpOiBSb3V0ZVZpZXcgfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IGFjdGl2YXRlZFVybEtleSA9IGdldFVybCh0aGlzLnJvdXRlciwgYWN0aXZhdGVkUm91dGUpO1xuICAgIGNvbnN0IHZpZXcgPSB0aGlzLnZpZXdzLmZpbmQoKHZ3KSA9PiB2dy51cmwgPT09IGFjdGl2YXRlZFVybEtleSk7XG4gICAgaWYgKHZpZXcpIHtcbiAgICAgIHZpZXcucmVmLmNoYW5nZURldGVjdG9yUmVmLnJlYXR0YWNoKCk7XG4gICAgfVxuICAgIHJldHVybiB2aWV3O1xuICB9XG5cbiAgc2V0QWN0aXZlKGVudGVyaW5nVmlldzogUm91dGVWaWV3KTogUHJvbWlzZTxTdGFja0RpZENoYW5nZUV2ZW50PiB7XG4gICAgY29uc3QgY29uc3VtZVJlc3VsdCA9IHRoaXMubmF2Q3RybC5jb25zdW1lVHJhbnNpdGlvbigpO1xuICAgIGxldCB7IGRpcmVjdGlvbiwgYW5pbWF0aW9uLCBhbmltYXRpb25CdWlsZGVyIH0gPSBjb25zdW1lUmVzdWx0O1xuICAgIGNvbnN0IGxlYXZpbmdWaWV3ID0gdGhpcy5hY3RpdmVWaWV3O1xuICAgIGNvbnN0IHRhYlN3aXRjaCA9IGlzVGFiU3dpdGNoKGVudGVyaW5nVmlldywgbGVhdmluZ1ZpZXcpO1xuICAgIGlmICh0YWJTd2l0Y2gpIHtcbiAgICAgIGRpcmVjdGlvbiA9ICdiYWNrJztcbiAgICAgIGFuaW1hdGlvbiA9IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBjb25zdCB2aWV3c1NuYXBzaG90ID0gdGhpcy52aWV3cy5zbGljZSgpO1xuXG4gICAgbGV0IGN1cnJlbnROYXZpZ2F0aW9uO1xuXG4gICAgY29uc3Qgcm91dGVyID0gdGhpcy5yb3V0ZXIgYXMgYW55O1xuXG4gICAgLy8gQW5ndWxhciA+PSA3LjIuMFxuICAgIGlmIChyb3V0ZXIuZ2V0Q3VycmVudE5hdmlnYXRpb24pIHtcbiAgICAgIGN1cnJlbnROYXZpZ2F0aW9uID0gcm91dGVyLmdldEN1cnJlbnROYXZpZ2F0aW9uKCk7XG5cbiAgICAgIC8vIEFuZ3VsYXIgPCA3LjIuMFxuICAgIH0gZWxzZSBpZiAocm91dGVyLm5hdmlnYXRpb25zPy52YWx1ZSkge1xuICAgICAgY3VycmVudE5hdmlnYXRpb24gPSByb3V0ZXIubmF2aWdhdGlvbnMudmFsdWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSWYgdGhlIG5hdmlnYXRpb24gYWN0aW9uXG4gICAgICogc2V0cyBgcmVwbGFjZVVybDogdHJ1ZWBcbiAgICAgKiB0aGVuIHdlIG5lZWQgdG8gbWFrZSBzdXJlXG4gICAgICogd2UgcmVtb3ZlIHRoZSBsYXN0IGl0ZW1cbiAgICAgKiBmcm9tIG91ciB2aWV3cyBzdGFja1xuICAgICAqL1xuICAgIGlmIChjdXJyZW50TmF2aWdhdGlvbj8uZXh0cmFzPy5yZXBsYWNlVXJsKSB7XG4gICAgICBpZiAodGhpcy52aWV3cy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHRoaXMudmlld3Muc3BsaWNlKC0xLCAxKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCByZXVzZWQgPSB0aGlzLnZpZXdzLmluY2x1ZGVzKGVudGVyaW5nVmlldyk7XG4gICAgY29uc3Qgdmlld3MgPSB0aGlzLmluc2VydFZpZXcoZW50ZXJpbmdWaWV3LCBkaXJlY3Rpb24pO1xuXG4gICAgLy8gVHJpZ2dlciBjaGFuZ2UgZGV0ZWN0aW9uIGJlZm9yZSB0cmFuc2l0aW9uIHN0YXJ0c1xuICAgIC8vIFRoaXMgd2lsbCBjYWxsIG5nT25Jbml0KCkgdGhlIGZpcnN0IHRpbWUgdG9vLCBqdXN0IGFmdGVyIHRoZSB2aWV3XG4gICAgLy8gd2FzIGF0dGFjaGVkIHRvIHRoZSBkb20sIGJ1dCBCRUZPUkUgdGhlIHRyYW5zaXRpb24gc3RhcnRzXG4gICAgaWYgKCFyZXVzZWQpIHtcbiAgICAgIGVudGVyaW5nVmlldy5yZWYuY2hhbmdlRGV0ZWN0b3JSZWYuZGV0ZWN0Q2hhbmdlcygpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIElmIHdlIGFyZSBnb2luZyBiYWNrIGZyb20gYSBwYWdlIHRoYXRcbiAgICAgKiB3YXMgcHJlc2VudGVkIHVzaW5nIGEgY3VzdG9tIGFuaW1hdGlvblxuICAgICAqIHdlIHNob3VsZCBkZWZhdWx0IHRvIHVzaW5nIHRoYXRcbiAgICAgKiB1bmxlc3MgdGhlIGRldmVsb3BlciBleHBsaWNpdGx5XG4gICAgICogcHJvdmlkZWQgYW5vdGhlciBhbmltYXRpb24uXG4gICAgICovXG4gICAgY29uc3QgY3VzdG9tQW5pbWF0aW9uID0gZW50ZXJpbmdWaWV3LmFuaW1hdGlvbkJ1aWxkZXI7XG4gICAgaWYgKGFuaW1hdGlvbkJ1aWxkZXIgPT09IHVuZGVmaW5lZCAmJiBkaXJlY3Rpb24gPT09ICdiYWNrJyAmJiAhdGFiU3dpdGNoICYmIGN1c3RvbUFuaW1hdGlvbiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBhbmltYXRpb25CdWlsZGVyID0gY3VzdG9tQW5pbWF0aW9uO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNhdmUgYW55IGN1c3RvbSBhbmltYXRpb24gc28gdGhhdCBuYXZpZ2F0aW5nXG4gICAgICogYmFjayB3aWxsIHVzZSB0aGlzIGN1c3RvbSBhbmltYXRpb24gYnkgZGVmYXVsdC5cbiAgICAgKi9cbiAgICBpZiAobGVhdmluZ1ZpZXcpIHtcbiAgICAgIGxlYXZpbmdWaWV3LmFuaW1hdGlvbkJ1aWxkZXIgPSBhbmltYXRpb25CdWlsZGVyO1xuICAgIH1cblxuICAgIC8vIFdhaXQgdW50aWwgcHJldmlvdXMgdHJhbnNpdGlvbnMgZmluaXNoXG4gICAgcmV0dXJuIHRoaXMuem9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy53YWl0KCgpID0+IHtcbiAgICAgICAgLy8gZGlzY29ubmVjdCBsZWF2aW5nIHBhZ2UgZnJvbSBjaGFuZ2UgZGV0ZWN0aW9uIHRvXG4gICAgICAgIC8vIHJlZHVjZSBqYW5rIGR1cmluZyB0aGUgcGFnZSB0cmFuc2l0aW9uXG4gICAgICAgIGlmIChsZWF2aW5nVmlldykge1xuICAgICAgICAgIGxlYXZpbmdWaWV3LnJlZi5jaGFuZ2VEZXRlY3RvclJlZi5kZXRhY2goKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBJbiBjYXNlIHRoZSBlbnRlcmluZ1ZpZXcgaXMgdGhlIHNhbWUgYXMgdGhlIGxlYXZpbmdQYWdlIHdlIG5lZWQgdG8gcmVhdHRhY2goKVxuICAgICAgICBlbnRlcmluZ1ZpZXcucmVmLmNoYW5nZURldGVjdG9yUmVmLnJlYXR0YWNoKCk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMudHJhbnNpdGlvbihlbnRlcmluZ1ZpZXcsIGxlYXZpbmdWaWV3LCBhbmltYXRpb24sIHRoaXMuY2FuR29CYWNrKDEpLCBmYWxzZSwgYW5pbWF0aW9uQnVpbGRlcilcbiAgICAgICAgICAudGhlbigoKSA9PiBjbGVhbnVwQXN5bmMoZW50ZXJpbmdWaWV3LCB2aWV3cywgdmlld3NTbmFwc2hvdCwgdGhpcy5sb2NhdGlvbiwgdGhpcy56b25lKSlcbiAgICAgICAgICAudGhlbigoKSA9PiAoe1xuICAgICAgICAgICAgZW50ZXJpbmdWaWV3LFxuICAgICAgICAgICAgZGlyZWN0aW9uLFxuICAgICAgICAgICAgYW5pbWF0aW9uLFxuICAgICAgICAgICAgdGFiU3dpdGNoLFxuICAgICAgICAgIH0pKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgY2FuR29CYWNrKGRlZXA6IG51bWJlciwgc3RhY2tJZCA9IHRoaXMuZ2V0QWN0aXZlU3RhY2tJZCgpKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0U3RhY2soc3RhY2tJZCkubGVuZ3RoID4gZGVlcDtcbiAgfVxuXG4gIHBvcChkZWVwOiBudW1iZXIsIHN0YWNrSWQgPSB0aGlzLmdldEFjdGl2ZVN0YWNrSWQoKSk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIHJldHVybiB0aGlzLnpvbmUucnVuKCgpID0+IHtcbiAgICAgIGNvbnN0IHZpZXdzID0gdGhpcy5nZXRTdGFjayhzdGFja0lkKTtcbiAgICAgIGlmICh2aWV3cy5sZW5ndGggPD0gZGVlcCkge1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGZhbHNlKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHZpZXcgPSB2aWV3c1t2aWV3cy5sZW5ndGggLSBkZWVwIC0gMV07XG4gICAgICBsZXQgdXJsID0gdmlldy51cmw7XG5cbiAgICAgIGNvbnN0IHZpZXdTYXZlZERhdGEgPSB2aWV3LnNhdmVkRGF0YTtcbiAgICAgIGlmICh2aWV3U2F2ZWREYXRhKSB7XG4gICAgICAgIGNvbnN0IHByaW1hcnlPdXRsZXQgPSB2aWV3U2F2ZWREYXRhLmdldCgncHJpbWFyeScpO1xuICAgICAgICBpZiAocHJpbWFyeU91dGxldD8ucm91dGU/Ll9yb3V0ZXJTdGF0ZT8uc25hcHNob3QudXJsKSB7XG4gICAgICAgICAgdXJsID0gcHJpbWFyeU91dGxldC5yb3V0ZS5fcm91dGVyU3RhdGUuc25hcHNob3QudXJsO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBjb25zdCB7IGFuaW1hdGlvbkJ1aWxkZXIgfSA9IHRoaXMubmF2Q3RybC5jb25zdW1lVHJhbnNpdGlvbigpO1xuICAgICAgcmV0dXJuIHRoaXMubmF2Q3RybC5uYXZpZ2F0ZUJhY2sodXJsLCB7IC4uLnZpZXcuc2F2ZWRFeHRyYXMsIGFuaW1hdGlvbjogYW5pbWF0aW9uQnVpbGRlciB9KS50aGVuKCgpID0+IHRydWUpO1xuICAgIH0pO1xuICB9XG5cbiAgc3RhcnRCYWNrVHJhbnNpdGlvbigpOiBQcm9taXNlPGJvb2xlYW4+IHwgUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgbGVhdmluZ1ZpZXcgPSB0aGlzLmFjdGl2ZVZpZXc7XG4gICAgaWYgKGxlYXZpbmdWaWV3KSB7XG4gICAgICBjb25zdCB2aWV3cyA9IHRoaXMuZ2V0U3RhY2sobGVhdmluZ1ZpZXcuc3RhY2tJZCk7XG4gICAgICBjb25zdCBlbnRlcmluZ1ZpZXcgPSB2aWV3c1t2aWV3cy5sZW5ndGggLSAyXTtcbiAgICAgIGNvbnN0IGN1c3RvbUFuaW1hdGlvbiA9IGVudGVyaW5nVmlldy5hbmltYXRpb25CdWlsZGVyO1xuXG4gICAgICByZXR1cm4gdGhpcy53YWl0KCgpID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMudHJhbnNpdGlvbihcbiAgICAgICAgICBlbnRlcmluZ1ZpZXcsIC8vIGVudGVyaW5nIHZpZXdcbiAgICAgICAgICBsZWF2aW5nVmlldywgLy8gbGVhdmluZyB2aWV3XG4gICAgICAgICAgJ2JhY2snLFxuICAgICAgICAgIHRoaXMuY2FuR29CYWNrKDIpLFxuICAgICAgICAgIHRydWUsXG4gICAgICAgICAgY3VzdG9tQW5pbWF0aW9uXG4gICAgICAgICk7XG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICB9XG5cbiAgZW5kQmFja1RyYW5zaXRpb24oc2hvdWxkQ29tcGxldGU6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICBpZiAoc2hvdWxkQ29tcGxldGUpIHtcbiAgICAgIHRoaXMuc2tpcFRyYW5zaXRpb24gPSB0cnVlO1xuICAgICAgdGhpcy5wb3AoMSk7XG4gICAgfSBlbHNlIGlmICh0aGlzLmFjdGl2ZVZpZXcpIHtcbiAgICAgIGNsZWFudXAodGhpcy5hY3RpdmVWaWV3LCB0aGlzLnZpZXdzLCB0aGlzLnZpZXdzLCB0aGlzLmxvY2F0aW9uLCB0aGlzLnpvbmUpO1xuICAgIH1cbiAgfVxuXG4gIGdldExhc3RVcmwoc3RhY2tJZD86IHN0cmluZyk6IFJvdXRlVmlldyB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3Qgdmlld3MgPSB0aGlzLmdldFN0YWNrKHN0YWNrSWQpO1xuICAgIHJldHVybiB2aWV3cy5sZW5ndGggPiAwID8gdmlld3Nbdmlld3MubGVuZ3RoIC0gMV0gOiB1bmRlZmluZWQ7XG4gIH1cblxuICAvKipcbiAgICogQGludGVybmFsXG4gICAqL1xuICBnZXRSb290VXJsKHN0YWNrSWQ/OiBzdHJpbmcpOiBSb3V0ZVZpZXcgfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IHZpZXdzID0gdGhpcy5nZXRTdGFjayhzdGFja0lkKTtcbiAgICByZXR1cm4gdmlld3MubGVuZ3RoID4gMCA/IHZpZXdzWzBdIDogdW5kZWZpbmVkO1xuICB9XG5cbiAgZ2V0QWN0aXZlU3RhY2tJZCgpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLmFjdGl2ZVZpZXcgPyB0aGlzLmFjdGl2ZVZpZXcuc3RhY2tJZCA6IHVuZGVmaW5lZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIGdldEFjdGl2ZVZpZXcoKTogUm91dGVWaWV3IHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5hY3RpdmVWaWV3O1xuICB9XG5cbiAgaGFzUnVubmluZ1Rhc2soKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMucnVubmluZ1Rhc2sgIT09IHVuZGVmaW5lZDtcbiAgfVxuXG4gIGRlc3Ryb3koKTogdm9pZCB7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb25cbiAgICB0aGlzLmNvbnRhaW5lckVsID0gdW5kZWZpbmVkITtcbiAgICB0aGlzLnZpZXdzLmZvckVhY2goZGVzdHJveVZpZXcpO1xuICAgIHRoaXMuYWN0aXZlVmlldyA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLnZpZXdzID0gW107XG4gIH1cblxuICBwcml2YXRlIGdldFN0YWNrKHN0YWNrSWQ6IHN0cmluZyB8IHVuZGVmaW5lZCkge1xuICAgIHJldHVybiB0aGlzLnZpZXdzLmZpbHRlcigodikgPT4gdi5zdGFja0lkID09PSBzdGFja0lkKTtcbiAgfVxuXG4gIHByaXZhdGUgaW5zZXJ0VmlldyhlbnRlcmluZ1ZpZXc6IFJvdXRlVmlldywgZGlyZWN0aW9uOiBSb3V0ZXJEaXJlY3Rpb24pIHtcbiAgICB0aGlzLmFjdGl2ZVZpZXcgPSBlbnRlcmluZ1ZpZXc7XG4gICAgdGhpcy52aWV3cyA9IGluc2VydFZpZXcodGhpcy52aWV3cywgZW50ZXJpbmdWaWV3LCBkaXJlY3Rpb24pO1xuICAgIHJldHVybiB0aGlzLnZpZXdzLnNsaWNlKCk7XG4gIH1cblxuICBwcml2YXRlIHRyYW5zaXRpb24oXG4gICAgZW50ZXJpbmdWaWV3OiBSb3V0ZVZpZXcgfCB1bmRlZmluZWQsXG4gICAgbGVhdmluZ1ZpZXc6IFJvdXRlVmlldyB8IHVuZGVmaW5lZCxcbiAgICBkaXJlY3Rpb246ICdmb3J3YXJkJyB8ICdiYWNrJyB8IHVuZGVmaW5lZCxcbiAgICBzaG93R29CYWNrOiBib29sZWFuLFxuICAgIHByb2dyZXNzQW5pbWF0aW9uOiBib29sZWFuLFxuICAgIGFuaW1hdGlvbkJ1aWxkZXI/OiBBbmltYXRpb25CdWlsZGVyXG4gICkge1xuICAgIGlmICh0aGlzLnNraXBUcmFuc2l0aW9uKSB7XG4gICAgICB0aGlzLnNraXBUcmFuc2l0aW9uID0gZmFsc2U7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGZhbHNlKTtcbiAgICB9XG4gICAgaWYgKGxlYXZpbmdWaWV3ID09PSBlbnRlcmluZ1ZpZXcpIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoZmFsc2UpO1xuICAgIH1cbiAgICBjb25zdCBlbnRlcmluZ0VsID0gZW50ZXJpbmdWaWV3ID8gZW50ZXJpbmdWaWV3LmVsZW1lbnQgOiB1bmRlZmluZWQ7XG4gICAgY29uc3QgbGVhdmluZ0VsID0gbGVhdmluZ1ZpZXcgPyBsZWF2aW5nVmlldy5lbGVtZW50IDogdW5kZWZpbmVkO1xuICAgIGNvbnN0IGNvbnRhaW5lckVsID0gdGhpcy5jb250YWluZXJFbDtcbiAgICBpZiAoZW50ZXJpbmdFbCAmJiBlbnRlcmluZ0VsICE9PSBsZWF2aW5nRWwpIHtcbiAgICAgIGVudGVyaW5nRWwuY2xhc3NMaXN0LmFkZCgnaW9uLXBhZ2UnKTtcbiAgICAgIGVudGVyaW5nRWwuY2xhc3NMaXN0LmFkZCgnaW9uLXBhZ2UtaW52aXNpYmxlJyk7XG4gICAgICBpZiAoZW50ZXJpbmdFbC5wYXJlbnRFbGVtZW50ICE9PSBjb250YWluZXJFbCkge1xuICAgICAgICBjb250YWluZXJFbC5hcHBlbmRDaGlsZChlbnRlcmluZ0VsKTtcbiAgICAgIH1cblxuICAgICAgaWYgKChjb250YWluZXJFbCBhcyBhbnkpLmNvbW1pdCkge1xuICAgICAgICByZXR1cm4gY29udGFpbmVyRWwuY29tbWl0KGVudGVyaW5nRWwsIGxlYXZpbmdFbCwge1xuICAgICAgICAgIGR1cmF0aW9uOiBkaXJlY3Rpb24gPT09IHVuZGVmaW5lZCA/IDAgOiB1bmRlZmluZWQsXG4gICAgICAgICAgZGlyZWN0aW9uLFxuICAgICAgICAgIHNob3dHb0JhY2ssXG4gICAgICAgICAgcHJvZ3Jlc3NBbmltYXRpb24sXG4gICAgICAgICAgYW5pbWF0aW9uQnVpbGRlcixcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoZmFsc2UpO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyB3YWl0PFQ+KHRhc2s6ICgpID0+IFByb21pc2U8VD4pOiBQcm9taXNlPFQ+IHtcbiAgICBpZiAodGhpcy5ydW5uaW5nVGFzayAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBhd2FpdCB0aGlzLnJ1bm5pbmdUYXNrO1xuICAgICAgdGhpcy5ydW5uaW5nVGFzayA9IHVuZGVmaW5lZDtcbiAgICB9XG4gICAgY29uc3QgcHJvbWlzZSA9ICh0aGlzLnJ1bm5pbmdUYXNrID0gdGFzaygpKTtcbiAgICBwcm9taXNlLmZpbmFsbHkoKCkgPT4gKHRoaXMucnVubmluZ1Rhc2sgPSB1bmRlZmluZWQpKTtcbiAgICByZXR1cm4gcHJvbWlzZTtcbiAgfVxufVxuXG5jb25zdCBjbGVhbnVwQXN5bmMgPSAoXG4gIGFjdGl2ZVJvdXRlOiBSb3V0ZVZpZXcsXG4gIHZpZXdzOiBSb3V0ZVZpZXdbXSxcbiAgdmlld3NTbmFwc2hvdDogUm91dGVWaWV3W10sXG4gIGxvY2F0aW9uOiBMb2NhdGlvbixcbiAgem9uZTogTmdab25lXG4pID0+IHtcbiAgaWYgKHR5cGVvZiAocmVxdWVzdEFuaW1hdGlvbkZyYW1lIGFzIGFueSkgPT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gbmV3IFByb21pc2U8dm9pZD4oKHJlc29sdmUpID0+IHtcbiAgICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB7XG4gICAgICAgIGNsZWFudXAoYWN0aXZlUm91dGUsIHZpZXdzLCB2aWV3c1NuYXBzaG90LCBsb2NhdGlvbiwgem9uZSk7XG4gICAgICAgIHJlc29sdmUoKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbn07XG5cbmNvbnN0IGNsZWFudXAgPSAoXG4gIGFjdGl2ZVJvdXRlOiBSb3V0ZVZpZXcsXG4gIHZpZXdzOiBSb3V0ZVZpZXdbXSxcbiAgdmlld3NTbmFwc2hvdDogUm91dGVWaWV3W10sXG4gIGxvY2F0aW9uOiBMb2NhdGlvbixcbiAgem9uZTogTmdab25lXG4pID0+IHtcbiAgLyoqXG4gICAqIFJlLWVudGVyIHRoZSBBbmd1bGFyIHpvbmUgd2hlbiBkZXN0cm95aW5nIHBhZ2UgY29tcG9uZW50cy4gVGhpcyB3aWxsIGFsbG93XG4gICAqIGxpZmVjeWNsZSBldmVudHMgKGBuZ09uRGVzdHJveWApIHRvIGJlIHJ1biBpbnNpZGUgdGhlIEFuZ3VsYXIgem9uZS5cbiAgICovXG4gIHpvbmUucnVuKCgpID0+IHZpZXdzU25hcHNob3QuZmlsdGVyKCh2aWV3KSA9PiAhdmlld3MuaW5jbHVkZXModmlldykpLmZvckVhY2goZGVzdHJveVZpZXcpKTtcblxuICB2aWV3cy5mb3JFYWNoKCh2aWV3KSA9PiB7XG4gICAgLyoqXG4gICAgICogSW4gdGhlIGV2ZW50IHRoYXQgYSB1c2VyIG5hdmlnYXRlZCBtdWx0aXBsZVxuICAgICAqIHRpbWVzIGluIHJhcGlkIHN1Y2Nlc3Npb24sIHdlIHdhbnQgdG8gbWFrZSBzdXJlXG4gICAgICogd2UgZG9uJ3QgcHJlLWVtcHRpdmVseSBkZXRhY2ggYSB2aWV3IHdoaWxlXG4gICAgICogaXQgaXMgaW4gbWlkLXRyYW5zaXRpb24uXG4gICAgICpcbiAgICAgKiBJbiB0aGlzIGluc3RhbmNlIHdlIGFsc28gZG8gbm90IGNhcmUgYWJvdXQgcXVlcnlcbiAgICAgKiBwYXJhbXMgb3IgZnJhZ21lbnRzIGFzIGl0IHdpbGwgYmUgdGhlIHNhbWUgdmlldyByZWdhcmRsZXNzXG4gICAgICovXG4gICAgY29uc3QgbG9jYXRpb25XaXRob3V0UGFyYW1zID0gbG9jYXRpb24ucGF0aCgpLnNwbGl0KCc/JylbMF07XG4gICAgY29uc3QgbG9jYXRpb25XaXRob3V0RnJhZ21lbnQgPSBsb2NhdGlvbldpdGhvdXRQYXJhbXMuc3BsaXQoJyMnKVswXTtcblxuICAgIGlmICh2aWV3ICE9PSBhY3RpdmVSb3V0ZSAmJiB2aWV3LnVybCAhPT0gbG9jYXRpb25XaXRob3V0RnJhZ21lbnQpIHtcbiAgICAgIGNvbnN0IGVsZW1lbnQgPSB2aWV3LmVsZW1lbnQ7XG4gICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZSgnYXJpYS1oaWRkZW4nLCAndHJ1ZScpO1xuICAgICAgZWxlbWVudC5jbGFzc0xpc3QuYWRkKCdpb24tcGFnZS1oaWRkZW4nKTtcbiAgICAgIHZpZXcucmVmLmNoYW5nZURldGVjdG9yUmVmLmRldGFjaCgpO1xuICAgIH1cbiAgfSk7XG59O1xuIl19