UNPKG

ngx-joyride

Version:

[![npm version](https://badge.fury.io/js/ngx-joyride.svg)](https://badge.fury.io/js/ngx-joyride) [![Build Status](https://travis-ci.org/tnicola/ngx-joyride.svg?branch=master)](https://travis-ci.org/tnicola/ngx-joyride) [![codecov](https://codecov.io/gh/

225 lines 35.7 kB
import { Injectable } from '@angular/core'; import { JoyrideBackdropService } from './joyride-backdrop.service'; import { EventListenerService } from './event-listener.service'; import { JoyrideStepsContainerService, StepActionType } from './joyride-steps-container.service'; import { DocumentService } from './document.service'; import { StepDrawerService } from './step-drawer.service'; import { DomRefService } from './dom.service'; import { NO_POSITION } from '../directives/joyride.directive'; import { JoyrideOptionsService } from './joyride-options.service'; import { Router } from '@angular/router'; import { ReplaySubject } from 'rxjs'; import { JoyrideStepDoesNotExist, JoyrideStepOutOfRange } from '../models/joyride-error.class'; import { LoggerService } from './logger.service'; const SCROLLBAR_SIZE = 20; export const DISTANCE_FROM_TARGET = 15; export const ARROW_SIZE = 10; export class JoyrideStepService { constructor(backDropService, eventListener, stepsContainerService, documentService, DOMService, stepDrawerService, optionsService, router, logger) { this.backDropService = backDropService; this.eventListener = eventListener; this.stepsContainerService = stepsContainerService; this.documentService = documentService; this.DOMService = DOMService; this.stepDrawerService = stepDrawerService; this.optionsService = optionsService; this.router = router; this.logger = logger; this.winTopPosition = 0; this.winBottomPosition = 0; this.stepsObserver = new ReplaySubject(); this.initViewportPositions(); this.subscribeToScrollEvents(); this.subscribeToResizeEvents(); } initViewportPositions() { this.winTopPosition = 0; this.winBottomPosition = this.DOMService.getNativeWindow().innerHeight - SCROLLBAR_SIZE; } subscribeToScrollEvents() { this.eventListener.startListeningScrollEvents(); this.eventListener.scrollEvent.subscribe(scroll => { this.winTopPosition = scroll.scrollY; this.winBottomPosition = this.winTopPosition + this.DOMService.getNativeWindow().innerHeight - SCROLLBAR_SIZE; if (this.currentStep) this.backDropService.redraw(this.currentStep, scroll); }); } subscribeToResizeEvents() { this.eventListener.resizeEvent.subscribe(() => { if (this.currentStep) this.backDropService.redrawTarget(this.currentStep); }); } drawStep(step) { step.position = step.position === NO_POSITION ? this.optionsService.getStepDefaultPosition() : step.position; this.stepDrawerService.draw(step); } startTour() { this.stepsObserver = new ReplaySubject(); this.stepsContainerService.init(); this.documentService.setDocumentHeight(); this.tryShowStep(StepActionType.NEXT); this.eventListener.startListeningResizeEvents(); this.subscribeToStepsUpdates(); return this.stepsObserver.asObservable(); } close() { this.removeCurrentStep(); this.notifyTourIsFinished(); this.DOMService.getNativeWindow().scrollTo(0, 0); this.eventListener.stopListeningResizeEvents(); this.backDropService.remove(); } prev() { this.removeCurrentStep(); this.currentStep.prevCliked.emit(); this.tryShowStep(StepActionType.PREV); } next() { this.removeCurrentStep(); this.currentStep.nextClicked.emit(); this.tryShowStep(StepActionType.NEXT); } navigateToStepPage(action) { let stepRoute = this.stepsContainerService.getStepRoute(action); if (stepRoute) { this.router.navigate([stepRoute]); } } subscribeToStepsUpdates() { this.stepsContainerService.stepHasBeenModified.subscribe(updatedStep => { if (this.currentStep && this.currentStep.name === updatedStep.name) { this.currentStep = updatedStep; } }); } tryShowStep(actionType) { this.navigateToStepPage(actionType); const timeout = this.optionsService.getWaitingTime(); if (timeout > 100) this.backDropService.remove(); setTimeout(() => { try { this.showStep(actionType); } catch (error) { if (error instanceof JoyrideStepDoesNotExist) { this.tryShowStep(actionType); } else if (error instanceof JoyrideStepOutOfRange) { this.logger.error('Forcing the tour closure: First or Last step not found in the DOM.'); this.close(); } else { throw new Error(error); } } }, timeout); } showStep(actionType) { this.currentStep = this.stepsContainerService.get(actionType); if (this.currentStep == null) throw new JoyrideStepDoesNotExist(''); // Scroll the element to get it visible if it's in a scrollable element this.scrollIfElementBeyondOtherElements(); this.backDropService.draw(this.currentStep); this.drawStep(this.currentStep); this.scrollIfStepAndTargetAreNotVisible(); this.notifyStepClicked(actionType); } notifyStepClicked(actionType) { let stepInfo = { number: this.stepsContainerService.getStepNumber(this.currentStep.name), name: this.currentStep.name, route: this.currentStep.route, actionType }; this.stepsObserver.next(stepInfo); } notifyTourIsFinished() { if (this.currentStep) this.currentStep.tourDone.emit(); this.stepsObserver.complete(); } removeCurrentStep() { if (this.currentStep) this.stepDrawerService.remove(this.currentStep); } scrollIfStepAndTargetAreNotVisible() { this.scrollWhenTargetOrStepAreHiddenBottom(); this.scrollWhenTargetOrStepAreHiddenTop(); } scrollWhenTargetOrStepAreHiddenBottom() { let totalTargetBottom = this.getMaxTargetAndStepBottomPosition(); if (totalTargetBottom > this.winBottomPosition) { this.DOMService.getNativeWindow().scrollBy(0, totalTargetBottom - this.winBottomPosition); } } scrollWhenTargetOrStepAreHiddenTop() { let totalTargetTop = this.getMaxTargetAndStepTopPosition(); if (totalTargetTop < this.winTopPosition) { this.DOMService.getNativeWindow().scrollBy(0, totalTargetTop - this.winTopPosition); } } getMaxTargetAndStepBottomPosition() { let targetAbsoluteTop = this.documentService.getElementAbsoluteTop(this.currentStep.targetViewContainer.element); if (this.currentStep.position === 'top') { return targetAbsoluteTop + this.currentStep.stepInstance.targetHeight; } else if (this.currentStep.position === 'bottom') { return (targetAbsoluteTop + this.currentStep.stepInstance.targetHeight + this.currentStep.stepInstance.stepHeight + ARROW_SIZE + DISTANCE_FROM_TARGET); } else if (this.currentStep.position === 'right' || this.currentStep.position === 'left') { return Math.max(targetAbsoluteTop + this.currentStep.stepInstance.targetHeight, targetAbsoluteTop + this.currentStep.stepInstance.targetHeight / 2 + this.currentStep.stepInstance.stepHeight / 2); } } getMaxTargetAndStepTopPosition() { let targetAbsoluteTop = this.documentService.getElementAbsoluteTop(this.currentStep.targetViewContainer.element); if (this.currentStep.position === 'top') { return targetAbsoluteTop - (this.currentStep.stepInstance.stepHeight + ARROW_SIZE + DISTANCE_FROM_TARGET); } else if (this.currentStep.position === 'bottom') { return targetAbsoluteTop; } else if (this.currentStep.position === 'right' || this.currentStep.position === 'left') { return Math.min(targetAbsoluteTop, targetAbsoluteTop + this.currentStep.stepInstance.targetHeight / 2 - this.currentStep.stepInstance.stepHeight / 2); } } scrollIfElementBeyondOtherElements() { if (this.isElementBeyondOthers() === 2) { this.documentService.scrollToTheTop(this.currentStep.targetViewContainer.element); } if (this.isElementBeyondOthers() === 2) { this.documentService.scrollToTheBottom(this.currentStep.targetViewContainer.element); } if (this.isElementBeyondOthers() === 1 && this.documentService.isParentScrollable(this.currentStep.targetViewContainer.element)) { this.documentService.scrollIntoView(this.currentStep.targetViewContainer.element, this.currentStep.isElementOrAncestorFixed); } if (this.isElementBeyondOthers() === 1 && this.documentService.isParentScrollable(this.currentStep.targetViewContainer.element)) { this.currentStep.targetViewContainer.element.nativeElement.scrollIntoView(); } } isElementBeyondOthers() { return this.documentService.isElementBeyondOthers(this.currentStep.targetViewContainer.element, this.currentStep.isElementOrAncestorFixed, 'backdrop'); } } JoyrideStepService.decorators = [ { type: Injectable } ]; JoyrideStepService.ctorParameters = () => [ { type: JoyrideBackdropService }, { type: EventListenerService }, { type: JoyrideStepsContainerService }, { type: DocumentService }, { type: DomRefService }, { type: StepDrawerService }, { type: JoyrideOptionsService }, { type: Router }, { type: LoggerService } ]; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiam95cmlkZS1zdGVwLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtam95cmlkZS9zcmMvbGliL3NlcnZpY2VzL2pveXJpZGUtc3RlcC5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFM0MsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDcEUsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDaEUsT0FBTyxFQUFFLDRCQUE0QixFQUFFLGNBQWMsRUFBRSxNQUFNLG1DQUFtQyxDQUFDO0FBQ2pHLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUNyRCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUMxRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzlDLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUM5RCxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUNsRSxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDekMsT0FBTyxFQUFFLGFBQWEsRUFBYyxNQUFNLE1BQU0sQ0FBQztBQUVqRCxPQUFPLEVBQUUsdUJBQXVCLEVBQUUscUJBQXFCLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUMvRixPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFFakQsTUFBTSxjQUFjLEdBQUcsRUFBRSxDQUFDO0FBRTFCLE1BQU0sQ0FBQyxNQUFNLG9CQUFvQixHQUFHLEVBQUUsQ0FBQztBQUN2QyxNQUFNLENBQUMsTUFBTSxVQUFVLEdBQUcsRUFBRSxDQUFDO0FBVTdCLE1BQU0sT0FBTyxrQkFBa0I7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QUM1QixlQUFlO1lBRWYsYUFBYTtZQURiLGlCQUFpQjtZQUdqQixxQkFBcUI7WUFDckIsTUFBTTtZQUlOLGFBQWEiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IEpveXJpZGVTdGVwIH0gZnJvbSAnLi4vbW9kZWxzL2pveXJpZGUtc3RlcC5jbGFzcyc7XHJcbmltcG9ydCB7IEpveXJpZGVCYWNrZHJvcFNlcnZpY2UgfSBmcm9tICcuL2pveXJpZGUtYmFja2Ryb3Auc2VydmljZSc7XHJcbmltcG9ydCB7IEV2ZW50TGlzdGVuZXJTZXJ2aWNlIH0gZnJvbSAnLi9ldmVudC1saXN0ZW5lci5zZXJ2aWNlJztcclxuaW1wb3J0IHsgSm95cmlkZVN0ZXBzQ29udGFpbmVyU2VydmljZSwgU3RlcEFjdGlvblR5cGUgfSBmcm9tICcuL2pveXJpZGUtc3RlcHMtY29udGFpbmVyLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBEb2N1bWVudFNlcnZpY2UgfSBmcm9tICcuL2RvY3VtZW50LnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBTdGVwRHJhd2VyU2VydmljZSB9IGZyb20gJy4vc3RlcC1kcmF3ZXIuc2VydmljZSc7XHJcbmltcG9ydCB7IERvbVJlZlNlcnZpY2UgfSBmcm9tICcuL2RvbS5zZXJ2aWNlJztcclxuaW1wb3J0IHsgTk9fUE9TSVRJT04gfSBmcm9tICcuLi9kaXJlY3RpdmVzL2pveXJpZGUuZGlyZWN0aXZlJztcclxuaW1wb3J0IHsgSm95cmlkZU9wdGlvbnNTZXJ2aWNlIH0gZnJvbSAnLi9qb3lyaWRlLW9wdGlvbnMuc2VydmljZSc7XHJcbmltcG9ydCB7IFJvdXRlciB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XHJcbmltcG9ydCB7IFJlcGxheVN1YmplY3QsIE9ic2VydmFibGUgfSBmcm9tICdyeGpzJztcclxuaW1wb3J0IHsgSm95cmlkZVN0ZXBJbmZvIH0gZnJvbSAnLi4vbW9kZWxzL2pveXJpZGUtc3RlcC1pbmZvLmNsYXNzJztcclxuaW1wb3J0IHsgSm95cmlkZVN0ZXBEb2VzTm90RXhpc3QsIEpveXJpZGVTdGVwT3V0T2ZSYW5nZSB9IGZyb20gJy4uL21vZGVscy9qb3lyaWRlLWVycm9yLmNsYXNzJztcclxuaW1wb3J0IHsgTG9nZ2VyU2VydmljZSB9IGZyb20gJy4vbG9nZ2VyLnNlcnZpY2UnO1xyXG5cclxuY29uc3QgU0NST0xMQkFSX1NJWkUgPSAyMDtcclxuXHJcbmV4cG9ydCBjb25zdCBESVNUQU5DRV9GUk9NX1RBUkdFVCA9IDE1O1xyXG5leHBvcnQgY29uc3QgQVJST1dfU0laRSA9IDEwO1xyXG5cclxuZXhwb3J0IGludGVyZmFjZSBJSm95cmlkZVN0ZXBTZXJ2aWNlIHtcclxuICAgIHN0YXJ0VG91cigpOiBPYnNlcnZhYmxlPEpveXJpZGVTdGVwSW5mbz47XHJcbiAgICBjbG9zZSgpOiBhbnk7XHJcbiAgICBwcmV2KCk6IGFueTtcclxuICAgIG5leHQoKTogYW55O1xyXG59XHJcblxyXG5ASW5qZWN0YWJsZSgpXHJcbmV4cG9ydCBjbGFzcyBKb3lyaWRlU3RlcFNlcnZpY2UgaW1wbGVtZW50cyBJSm95cmlkZVN0ZXBTZXJ2aWNlIHtcclxuICAgIHByaXZhdGUgY3VycmVudFN0ZXA6IEpveXJpZGVTdGVwO1xyXG4gICAgcHJpdmF0ZSB3aW5Ub3BQb3NpdGlvbjogbnVtYmVyID0gMDtcclxuICAgIHByaXZhdGUgd2luQm90dG9tUG9zaXRpb246IG51bWJlciA9IDA7XHJcbiAgICBwcml2YXRlIHN0ZXBzT2JzZXJ2ZXI6IFJlcGxheVN1YmplY3Q8Sm95cmlkZVN0ZXBJbmZvPiA9IG5ldyBSZXBsYXlTdWJqZWN0PEpveXJpZGVTdGVwSW5mbz4oKTtcclxuXHJcbiAgICBjb25zdHJ1Y3RvcihcclxuICAgICAgICBwcml2YXRlIHJlYWRvbmx5IGJhY2tEcm9wU2VydmljZTogSm95cmlkZUJhY2tkcm9wU2VydmljZSxcclxuICAgICAgICBwcml2YXRlIHJlYWRvbmx5IGV2ZW50TGlzdGVuZXI6IEV2ZW50TGlzdGVuZXJTZXJ2aWNlLFxyXG4gICAgICAgIHByaXZhdGUgcmVhZG9ubHkgc3RlcHNDb250YWluZXJTZXJ2aWNlOiBKb3lyaWRlU3RlcHNDb250YWluZXJTZXJ2aWNlLFxyXG4gICAgICAgIHByaXZhdGUgcmVhZG9ubHkgZG9jdW1lbnRTZXJ2aWNlOiBEb2N1bWVudFNlcnZpY2UsXHJcbiAgICAgICAgcHJpdmF0ZSByZWFkb25seSBET01TZXJ2aWNlOiBEb21SZWZTZXJ2aWNlLFxyXG4gICAgICAgIHByaXZhdGUgcmVhZG9ubHkgc3RlcERyYXdlclNlcnZpY2U6IFN0ZXBEcmF3ZXJTZXJ2aWNlLFxyXG4gICAgICAgIHByaXZhdGUgcmVhZG9ubHkgb3B0aW9uc1NlcnZpY2U6IEpveXJpZGVPcHRpb25zU2VydmljZSxcclxuICAgICAgICBwcml2YXRlIHJlYWRvbmx5IHJvdXRlcjogUm91dGVyLFxyXG4gICAgICAgIHByaXZhdGUgcmVhZG9ubHkgbG9nZ2VyOiBMb2dnZXJTZXJ2aWNlXHJcbiAgICApIHtcclxuICAgICAgICB0aGlzLmluaXRWaWV3cG9ydFBvc2l0aW9ucygpO1xyXG4gICAgICAgIHRoaXMuc3Vic2NyaWJlVG9TY3JvbGxFdmVudHMoKTtcclxuICAgICAgICB0aGlzLnN1YnNjcmliZVRvUmVzaXplRXZlbnRzKCk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBpbml0Vmlld3BvcnRQb3NpdGlvbnMoKSB7XHJcbiAgICAgICAgdGhpcy53aW5Ub3BQb3NpdGlvbiA9IDA7XHJcbiAgICAgICAgdGhpcy53aW5Cb3R0b21Qb3NpdGlvbiA9IHRoaXMuRE9NU2VydmljZS5nZXROYXRpdmVXaW5kb3coKS5pbm5lckhlaWdodCAtIFNDUk9MTEJBUl9TSVpFO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgc3Vic2NyaWJlVG9TY3JvbGxFdmVudHMoKSB7XHJcbiAgICAgICAgdGhpcy5ldmVudExpc3RlbmVyLnN0YXJ0TGlzdGVuaW5nU2Nyb2xsRXZlbnRzKCk7XHJcbiAgICAgICAgdGhpcy5ldmVudExpc3RlbmVyLnNjcm9sbEV2ZW50LnN1YnNjcmliZShzY3JvbGwgPT4ge1xyXG4gICAgICAgICAgICB0aGlzLndpblRvcFBvc2l0aW9uID0gc2Nyb2xsLnNjcm9sbFk7XHJcbiAgICAgICAgICAgIHRoaXMud2luQm90dG9tUG9zaXRpb24gPSB0aGlzLndpblRvcFBvc2l0aW9uICsgdGhpcy5ET01TZXJ2aWNlLmdldE5hdGl2ZVdpbmRvdygpLmlubmVySGVpZ2h0IC0gU0NST0xMQkFSX1NJWkU7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLmN1cnJlbnRTdGVwKSB0aGlzLmJhY2tEcm9wU2VydmljZS5yZWRyYXcodGhpcy5jdXJyZW50U3RlcCwgc2Nyb2xsKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIHN1YnNjcmliZVRvUmVzaXplRXZlbnRzKCkge1xyXG4gICAgICAgIHRoaXMuZXZlbnRMaXN0ZW5lci5yZXNpemVFdmVudC5zdWJzY3JpYmUoKCkgPT4ge1xyXG4gICAgICAgICAgICBpZiAodGhpcy5jdXJyZW50U3RlcCkgdGhpcy5iYWNrRHJvcFNlcnZpY2UucmVkcmF3VGFyZ2V0KHRoaXMuY3VycmVudFN0ZXApO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgZHJhd1N0ZXAoc3RlcDogSm95cmlkZVN0ZXApIHtcclxuICAgICAgICBzdGVwLnBvc2l0aW9uID0gc3RlcC5wb3NpdGlvbiA9PT0gTk9fUE9TSVRJT04gPyB0aGlzLm9wdGlvbnNTZXJ2aWNlLmdldFN0ZXBEZWZhdWx0UG9zaXRpb24oKSA6IHN0ZXAucG9zaXRpb247XHJcbiAgICAgICAgdGhpcy5zdGVwRHJhd2VyU2VydmljZS5kcmF3KHN0ZXApO1xyXG4gICAgfVxyXG5cclxuICAgIHN0YXJ0VG91cigpOiBPYnNlcnZhYmxlPEpveXJpZGVTdGVwSW5mbz4ge1xyXG4gICAgICAgIHRoaXMuc3RlcHNPYnNlcnZlciA9IG5ldyBSZXBsYXlTdWJqZWN0PEpveXJpZGVTdGVwSW5mbz4oKTtcclxuICAgICAgICB0aGlzLnN0ZXBzQ29udGFpbmVyU2VydmljZS5pbml0KCk7XHJcbiAgICAgICAgdGhpcy5kb2N1bWVudFNlcnZpY2Uuc2V0RG9jdW1lbnRIZWlnaHQoKTtcclxuXHJcbiAgICAgICAgdGhpcy50cnlTaG93U3RlcChTdGVwQWN0aW9uVHlwZS5ORVhUKTtcclxuICAgICAgICB0aGlzLmV2ZW50TGlzdGVuZXIuc3RhcnRMaXN0ZW5pbmdSZXNpemVFdmVudHMoKTtcclxuICAgICAgICB0aGlzLnN1YnNjcmliZVRvU3RlcHNVcGRhdGVzKCk7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuc3RlcHNPYnNlcnZlci5hc09ic2VydmFibGUoKTtcclxuICAgIH1cclxuXHJcbiAgICBjbG9zZSgpIHtcclxuICAgICAgICB0aGlzLnJlbW92ZUN1cnJlbnRTdGVwKCk7XHJcbiAgICAgICAgdGhpcy5ub3RpZnlUb3VySXNGaW5pc2hlZCgpO1xyXG4gICAgICAgIHRoaXMuRE9NU2VydmljZS5nZXROYXRpdmVXaW5kb3coKS5zY3JvbGxUbygwLCAwKTtcclxuICAgICAgICB0aGlzLmV2ZW50TGlzdGVuZXIuc3RvcExpc3RlbmluZ1Jlc2l6ZUV2ZW50cygpO1xyXG4gICAgICAgIHRoaXMuYmFja0Ryb3BTZXJ2aWNlLnJlbW92ZSgpO1xyXG4gICAgfVxyXG5cclxuICAgIHByZXYoKSB7XHJcbiAgICAgICAgdGhpcy5yZW1vdmVDdXJyZW50U3RlcCgpO1xyXG4gICAgICAgIHRoaXMuY3VycmVudFN0ZXAucHJldkNsaWtlZC5lbWl0KCk7XHJcbiAgICAgICAgdGhpcy50cnlTaG93U3RlcChTdGVwQWN0aW9uVHlwZS5QUkVWKTtcclxuICAgIH1cclxuXHJcbiAgICBuZXh0KCkge1xyXG4gICAgICAgIHRoaXMucmVtb3ZlQ3VycmVudFN0ZXAoKTtcclxuICAgICAgICB0aGlzLmN1cnJlbnRTdGVwLm5leHRDbGlja2VkLmVtaXQoKTtcclxuICAgICAgICB0aGlzLnRyeVNob3dTdGVwKFN0ZXBBY3Rpb25UeXBlLk5FWFQpO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgbmF2aWdhdGVUb1N0ZXBQYWdlKGFjdGlvbjogU3RlcEFjdGlvblR5cGUpIHtcclxuICAgICAgICBsZXQgc3RlcFJvdXRlID0gdGhpcy5zdGVwc0NvbnRhaW5lclNlcnZpY2UuZ2V0U3RlcFJvdXRlKGFjdGlvbik7XHJcbiAgICAgICAgaWYgKHN0ZXBSb3V0ZSkge1xyXG4gICAgICAgICAgICB0aGlzLnJvdXRlci5uYXZpZ2F0ZShbc3RlcFJvdXRlXSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgc3Vic2NyaWJlVG9TdGVwc1VwZGF0ZXMoKSB7XHJcbiAgICAgICAgdGhpcy5zdGVwc0NvbnRhaW5lclNlcnZpY2Uuc3RlcEhhc0JlZW5Nb2RpZmllZC5zdWJzY3JpYmUodXBkYXRlZFN0ZXAgPT4ge1xyXG4gICAgICAgICAgICBpZiAodGhpcy5jdXJyZW50U3RlcCAmJiB0aGlzLmN1cnJlbnRTdGVwLm5hbWUgPT09IHVwZGF0ZWRTdGVwLm5hbWUpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuY3VycmVudFN0ZXAgPSB1cGRhdGVkU3RlcDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgdHJ5U2hvd1N0ZXAoYWN0aW9uVHlwZTogU3RlcEFjdGlvblR5cGUpIHtcclxuICAgICAgICB0aGlzLm5hdmlnYXRlVG9TdGVwUGFnZShhY3Rpb25UeXBlKTtcclxuICAgICAgICBjb25zdCB0aW1lb3V0ID0gdGhpcy5vcHRpb25zU2VydmljZS5nZXRXYWl0aW5nVGltZSgpO1xyXG4gICAgICAgIGlmICh0aW1lb3V0ID4gMTAwKSB0aGlzLmJhY2tEcm9wU2VydmljZS5yZW1vdmUoKTtcclxuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcclxuICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgIHRoaXMuc2hvd1N0ZXAoYWN0aW9uVHlwZSk7XHJcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBKb3lyaWRlU3RlcERvZXNOb3RFeGlzdCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMudHJ5U2hvd1N0ZXAoYWN0aW9uVHlwZSk7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGVycm9yIGluc3RhbmNlb2YgSm95cmlkZVN0ZXBPdXRPZlJhbmdlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2dnZXIuZXJyb3IoJ0ZvcmNpbmcgdGhlIHRvdXIgY2xvc3VyZTogRmlyc3Qgb3IgTGFzdCBzdGVwIG5vdCBmb3VuZCBpbiB0aGUgRE9NLicpO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY2xvc2UoKTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGVycm9yKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0sIHRpbWVvdXQpO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgc2hvd1N0ZXAoYWN0aW9uVHlwZTogU3RlcEFjdGlvblR5cGUpIHtcclxuICAgICAgICB0aGlzLmN1cnJlbnRTdGVwID0gdGhpcy5zdGVwc0NvbnRhaW5lclNlcnZpY2UuZ2V0KGFjdGlvblR5cGUpO1xyXG5cclxuICAgICAgICBpZiAodGhpcy5jdXJyZW50U3RlcCA9PSBudWxsKSB0aHJvdyBuZXcgSm95cmlkZVN0ZXBEb2VzTm90RXhpc3QoJycpO1xyXG4gICAgICAgIC8vIFNjcm9sbCB0aGUgZWxlbWVudCB0byBnZXQgaXQgdmlzaWJsZSBpZiBpdCdzIGluIGEgc2Nyb2xsYWJsZSBlbGVtZW50XHJcbiAgICAgICAgdGhpcy5zY3JvbGxJZkVsZW1lbnRCZXlvbmRPdGhlckVsZW1lbnRzKCk7XHJcbiAgICAgICAgdGhpcy5iYWNrRHJvcFNlcnZpY2UuZHJhdyh0aGlzLmN1cnJlbnRTdGVwKTtcclxuICAgICAgICB0aGlzLmRyYXdTdGVwKHRoaXMuY3VycmVudFN0ZXApO1xyXG4gICAgICAgIHRoaXMuc2Nyb2xsSWZTdGVwQW5kVGFyZ2V0QXJlTm90VmlzaWJsZSgpO1xyXG4gICAgICAgIHRoaXMubm90aWZ5U3RlcENsaWNrZWQoYWN0aW9uVHlwZSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBub3RpZnlTdGVwQ2xpY2tlZChhY3Rpb25UeXBlOiBTdGVwQWN0aW9uVHlwZSkge1xyXG4gICAgICAgIGxldCBzdGVwSW5mbzogSm95cmlkZVN0ZXBJbmZvID0ge1xyXG4gICAgICAgICAgICBudW1iZXI6IHRoaXMuc3RlcHNDb250YWluZXJTZXJ2aWNlLmdldFN0ZXBOdW1iZXIodGhpcy5jdXJyZW50U3RlcC5uYW1lKSxcclxuICAgICAgICAgICAgbmFtZTogdGhpcy5jdXJyZW50U3RlcC5uYW1lLFxyXG4gICAgICAgICAgICByb3V0ZTogdGhpcy5jdXJyZW50U3RlcC5yb3V0ZSxcclxuICAgICAgICAgICAgYWN0aW9uVHlwZVxyXG4gICAgICAgIH07XHJcbiAgICAgICAgdGhpcy5zdGVwc09ic2VydmVyLm5leHQoc3RlcEluZm8pO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgbm90aWZ5VG91cklzRmluaXNoZWQoKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuY3VycmVudFN0ZXApIHRoaXMuY3VycmVudFN0ZXAudG91ckRvbmUuZW1pdCgpO1xyXG4gICAgICAgIHRoaXMuc3RlcHNPYnNlcnZlci5jb21wbGV0ZSgpO1xyXG4gICAgfVxyXG4gICAgcHJpdmF0ZSByZW1vdmVDdXJyZW50U3RlcCgpIHtcclxuICAgICAgICBpZiAodGhpcy5jdXJyZW50U3RlcCkgdGhpcy5zdGVwRHJhd2VyU2VydmljZS5yZW1vdmUodGhpcy5jdXJyZW50U3RlcCk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBzY3JvbGxJZlN0ZXBBbmRUYXJnZXRBcmVOb3RWaXNpYmxlKCkge1xyXG4gICAgICAgIHRoaXMuc2Nyb2xsV2hlblRhcmdldE9yU3RlcEFyZUhpZGRlbkJvdHRvbSgpO1xyXG4gICAgICAgIHRoaXMuc2Nyb2xsV2hlblRhcmdldE9yU3RlcEFyZUhpZGRlblRvcCgpO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgc2Nyb2xsV2hlblRhcmdldE9yU3RlcEFyZUhpZGRlbkJvdHRvbSgpIHtcclxuICAgICAgICBsZXQgdG90YWxUYXJnZXRCb3R0b20gPSB0aGlzLmdldE1heFRhcmdldEFuZFN0ZXBCb3R0b21Qb3NpdGlvbigpO1xyXG4gICAgICAgIGlmICh0b3RhbFRhcmdldEJvdHRvbSA+IHRoaXMud2luQm90dG9tUG9zaXRpb24pIHtcclxuICAgICAgICAgICAgdGhpcy5ET01TZXJ2aWNlLmdldE5hdGl2ZVdpbmRvdygpLnNjcm9sbEJ5KDAsIHRvdGFsVGFyZ2V0Qm90dG9tIC0gdGhpcy53aW5Cb3R0b21Qb3NpdGlvbik7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgc2Nyb2xsV2hlblRhcmdldE9yU3RlcEFyZUhpZGRlblRvcCgpIHtcclxuICAgICAgICBsZXQgdG90YWxUYXJnZXRUb3AgPSB0aGlzLmdldE1heFRhcmdldEFuZFN0ZXBUb3BQb3NpdGlvbigpO1xyXG4gICAgICAgIGlmICh0b3RhbFRhcmdldFRvcCA8IHRoaXMud2luVG9wUG9zaXRpb24pIHtcclxuICAgICAgICAgICAgdGhpcy5ET01TZXJ2aWNlLmdldE5hdGl2ZVdpbmRvdygpLnNjcm9sbEJ5KDAsIHRvdGFsVGFyZ2V0VG9wIC0gdGhpcy53aW5Ub3BQb3NpdGlvbik7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgZ2V0TWF4VGFyZ2V0QW5kU3RlcEJvdHRvbVBvc2l0aW9uKCk6IG51bWJlciB7XHJcbiAgICAgICAgbGV0IHRhcmdldEFic29sdXRlVG9wID0gdGhpcy5kb2N1bWVudFNlcnZpY2UuZ2V0RWxlbWVudEFic29sdXRlVG9wKHRoaXMuY3VycmVudFN0ZXAudGFyZ2V0Vmlld0NvbnRhaW5lci5lbGVtZW50KTtcclxuICAgICAgICBpZiAodGhpcy5jdXJyZW50U3RlcC5wb3NpdGlvbiA9PT0gJ3RvcCcpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRhcmdldEFic29sdXRlVG9wICsgdGhpcy5jdXJyZW50U3RlcC5zdGVwSW5zdGFuY2UudGFyZ2V0SGVpZ2h0O1xyXG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5jdXJyZW50U3RlcC5wb3NpdGlvbiA9PT0gJ2JvdHRvbScpIHtcclxuICAgICAgICAgICAgcmV0dXJuIChcclxuICAgICAgICAgICAgICAgIHRhcmdldEFic29sdXRlVG9wICtcclxuICAgICAgICAgICAgICAgIHRoaXMuY3VycmVudFN0ZXAuc3RlcEluc3RhbmNlLnRhcmdldEhlaWdodCArXHJcbiAgICAgICAgICAgICAgICB0aGlzLmN1cnJlbnRTdGVwLnN0ZXBJbnN0YW5jZS5zdGVwSGVpZ2h0ICtcclxuICAgICAgICAgICAgICAgIEFSUk9XX1NJWkUgK1xyXG4gICAgICAgICAgICAgICAgRElTVEFOQ0VfRlJPTV9UQVJHRVRcclxuICAgICAgICAgICAgKTtcclxuICAgICAgICB9IGVsc2UgaWYgKHRoaXMuY3VycmVudFN0ZXAucG9zaXRpb24gPT09ICdyaWdodCcgfHwgdGhpcy5jdXJyZW50U3RlcC5wb3NpdGlvbiA9PT0gJ2xlZnQnKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBNYXRoLm1heChcclxuICAgICAgICAgICAgICAgIHRhcmdldEFic29sdXRlVG9wICsgdGhpcy5jdXJyZW50U3RlcC5zdGVwSW5zdGFuY2UudGFyZ2V0SGVpZ2h0LFxyXG4gICAgICAgICAgICAgICAgdGFyZ2V0QWJzb2x1dGVUb3AgKyB0aGlzLmN1cnJlbnRTdGVwLnN0ZXBJbnN0YW5jZS50YXJnZXRIZWlnaHQgLyAyICsgdGhpcy5jdXJyZW50U3RlcC5zdGVwSW5zdGFuY2Uuc3RlcEhlaWdodCAvIDJcclxuICAgICAgICAgICAgKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBnZXRNYXhUYXJnZXRBbmRTdGVwVG9wUG9zaXRpb24oKSB7XHJcbiAgICAgICAgbGV0IHRhcmdldEFic29sdXRlVG9wID0gdGhpcy5kb2N1bWVudFNlcnZpY2UuZ2V0RWxlbWVudEFic29sdXRlVG9wKHRoaXMuY3VycmVudFN0ZXAudGFyZ2V0Vmlld0NvbnRhaW5lci5lbGVtZW50KTtcclxuICAgICAgICBpZiAodGhpcy5jdXJyZW50U3RlcC5wb3NpdGlvbiA9PT0gJ3RvcCcpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRhcmdldEFic29sdXRlVG9wIC0gKHRoaXMuY3VycmVudFN0ZXAuc3RlcEluc3RhbmNlLnN0ZXBIZWlnaHQgKyBBUlJPV19TSVpFICsgRElTVEFOQ0VfRlJPTV9UQVJHRVQpO1xyXG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5jdXJyZW50U3RlcC5wb3NpdGlvbiA9PT0gJ2JvdHRvbScpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRhcmdldEFic29sdXRlVG9wO1xyXG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5jdXJyZW50U3RlcC5wb3NpdGlvbiA9PT0gJ3JpZ2h0JyB8fCB0aGlzLmN1cnJlbnRTdGVwLnBvc2l0aW9uID09PSAnbGVmdCcpIHtcclxuICAgICAgICAgICAgcmV0dXJuIE1hdGgubWluKFxyXG4gICAgICAgICAgICAgICAgdGFyZ2V0QWJzb2x1dGVUb3AsXHJcbiAgICAgICAgICAgICAgICB0YXJnZXRBYnNvbHV0ZVRvcCArIHRoaXMuY3VycmVudFN0ZXAuc3RlcEluc3RhbmNlLnRhcmdldEhlaWdodCAvIDIgLSB0aGlzLmN1cnJlbnRTdGVwLnN0ZXBJbnN0YW5jZS5zdGVwSGVpZ2h0IC8gMlxyXG4gICAgICAgICAgICApO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIHNjcm9sbElmRWxlbWVudEJleW9uZE90aGVyRWxlbWVudHMoKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuaXNFbGVtZW50QmV5b25kT3RoZXJzKCkgPT09IDIpIHtcclxuICAgICAgICAgICAgdGhpcy5kb2N1bWVudFNlcnZpY2Uuc2Nyb2xsVG9UaGVUb3AodGhpcy5jdXJyZW50U3RlcC50YXJnZXRWaWV3Q29udGFpbmVyLmVsZW1lbnQpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAodGhpcy5pc0VsZW1lbnRCZXlvbmRPdGhlcnMoKSA9PT0gMikge1xyXG4gICAgICAgICAgICB0aGlzLmRvY3VtZW50U2VydmljZS5zY3JvbGxUb1RoZUJvdHRvbSh0aGlzLmN1cnJlbnRTdGVwLnRhcmdldFZpZXdDb250YWluZXIuZWxlbWVudCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh0aGlzLmlzRWxlbWVudEJleW9uZE90aGVycygpID09PSAxICYmIHRoaXMuZG9jdW1lbnRTZXJ2aWNlLmlzUGFyZW50U2Nyb2xsYWJsZSh0aGlzLmN1cnJlbnRTdGVwLnRhcmdldFZpZXdDb250YWluZXIuZWxlbWVudCkpIHtcclxuICAgICAgICAgICAgdGhpcy5kb2N1bWVudFNlcnZpY2Uuc2Nyb2xsSW50b1ZpZXcodGhpcy5jdXJyZW50U3RlcC50YXJnZXRWaWV3Q29udGFpbmVyLmVsZW1lbnQsIHRoaXMuY3VycmVudFN0ZXAuaXNFbGVtZW50T3JBbmNlc3RvckZpeGVkKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHRoaXMuaXNFbGVtZW50QmV5b25kT3RoZXJzKCkgPT09IDEgJiYgdGhpcy5kb2N1bWVudFNlcnZpY2UuaXNQYXJlbnRTY3JvbGxhYmxlKHRoaXMuY3VycmVudFN0ZXAudGFyZ2V0Vmlld0NvbnRhaW5lci5lbGVtZW50KSkge1xyXG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRTdGVwLnRhcmdldFZpZXdDb250YWluZXIuZWxlbWVudC5uYXRpdmVFbGVtZW50LnNjcm9sbEludG9WaWV3KCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgaXNFbGVtZW50QmV5b25kT3RoZXJzKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmRvY3VtZW50U2VydmljZS5pc0VsZW1lbnRCZXlvbmRPdGhlcnMoXHJcbiAgICAgICAgICAgIHRoaXMuY3VycmVudFN0ZXAudGFyZ2V0Vmlld0NvbnRhaW5lci5lbGVtZW50LFxyXG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRTdGVwLmlzRWxlbWVudE9yQW5jZXN0b3JGaXhlZCxcclxuICAgICAgICAgICAgJ2JhY2tkcm9wJ1xyXG4gICAgICAgICk7XHJcbiAgICB9XHJcbn1cclxuIl19