ngx-joyride
Version:
[](https://badge.fury.io/js/ngx-joyride) [](https://travis-ci.org/tnicola/ngx-joyride) [ {
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