@sourceloop/user-onboarding-client
Version:
Library for providing a smooth user onboarding
525 lines • 76.2 kB
JavaScript
import { Injectable, } from '@angular/core';
import Shepherd from 'shepherd.js';
import { Status, } from '../models';
import { NavigationEnd } from '@angular/router';
import { Subject } from 'rxjs';
import { DEFAULT_MAX_WAIT_TIME, INTERVAL } from '../models/constants';
import * as i0 from "@angular/core";
import * as i1 from "./tour-store-service.service";
import * as i2 from "@angular/router";
export class TourServiceService {
constructor(tourStoreService, router, componentFactory, injector, appRef) {
this.tourStoreService = tourStoreService;
this.router = router;
this.componentFactory = componentFactory;
this.injector = injector;
this.appRef = appRef;
this.tourComplete = new Subject();
this.tourComplete$ = this.tourComplete.asObservable();
this.tourStepChange = new Subject();
this.tourStepChange$ = this.tourStepChange.asObservable();
this.tourCancel = new Subject();
this.tourCancel$ = this.tourCancel.asObservable();
this.interval = INTERVAL;
this._maxWaitTime = DEFAULT_MAX_WAIT_TIME;
this._exitOnEsc = true;
this.tourFailed = new Subject();
this.tourFailed$ = this.tourFailed.asObservable();
}
set maxWaitTime(maxTime) {
if (maxTime > 0) {
this._maxWaitTime = maxTime;
}
}
get maxWaitTime() {
return this._maxWaitTime;
}
set exitOnEsc(esc) {
this._exitOnEsc = esc;
}
get exitOnEsc() {
return this._exitOnEsc;
}
addRemovedSteps(removedSteps) {
const count = removedSteps.length;
for (let i = 0; i < count; i++) {
this.tour.steps.splice(0, 0, this.tour.steps.pop());
}
}
getTour() {
return this.tour;
}
actionAssignment(e, b, wrapperNormalNext, wrapperNormalPrev, wrapperNext, wrapperPrev, func, tourId, props) {
if (b.key === 'prevAction') {
b.action =
e.prevRoute === e.currentRoute ? wrapperNormalPrev : wrapperPrev;
}
else if (b.key === 'nextAction') {
b.action =
e.nextRoute === e.currentRoute ? wrapperNormalNext : wrapperNext;
}
else {
b.action = func.bind({ tour: this.tour, tourId, props });
}
}
waitForElement(tourStep, tourId) {
if (tourStep.attachTo === undefined) {
return Promise.resolve('');
}
else {
const startTime = new Date().getTime();
return new Promise((resolve, reject) => {
const timer = setInterval(() => {
const now = new Date().getTime();
const element = this.checkElement(tourStep.attachTo);
if (element) {
clearInterval(timer);
resolve(element);
}
else if (now - startTime >= this._maxWaitTime) {
clearInterval(timer);
reject({ tourId, message: `Error in loading tour` });
}
else {
// do nothing
}
}, this.interval);
});
}
}
triggerTour(tourInstance, props) {
let removedSteps = [];
const sessionId = this.tourStoreService.getSessionId();
if (!sessionId) {
this.tourStoreService.generateSessionId();
}
this.tourStoreService
.loadState({ tourId: tourInstance.tourId, sessionId })
.subscribe(tourState => {
if (tourState && Object.keys(tourState).length) {
if (tourState.status === Status.Complete) {
return;
}
removedSteps = this.getRemovedSteps(tourInstance.tourSteps, tourState);
tourInstance.tourSteps = this.getTourSteps(tourInstance.tourSteps, tourState);
}
else {
tourState = {
sessionId: this.tourStoreService.getSessionId(),
step: tourInstance.tourSteps[0].id,
props,
status: Status.InProgress,
};
this.tourStoreService
.saveState({
tourId: tourInstance.tourId,
state: tourState,
})
.subscribe();
}
tourInstance.tourSteps.forEach((e, index) => {
e.buttons.forEach(b => {
const key = b.key;
const func = this.tourStoreService.getFnByKey(key);
const wrapperNext = () => {
this.navigateAndMoveToNextStep(e, tourInstance, tourState, index);
};
const wrapperPrev = () => {
this.navigateAndMoveToPrevStep(e, tourInstance, tourState, index, removedSteps);
};
const wrapperNormalNext = () => {
this.moveToNextStep(tourInstance, tourState, e, index);
};
const wrapperNormalPrev = () => {
this.moveToPrevStep(tourInstance, tourState, e, index, removedSteps);
};
this.actionAssignment(e, b, wrapperNormalNext, wrapperNormalPrev, wrapperNext, wrapperPrev, func, tourInstance.tourId, tourState.props);
});
});
this.tour.addSteps(tourInstance.tourSteps);
this.waitForElement(tourInstance.tourSteps[0], tourInstance.tourId).then(element => {
if (element) {
element.scrollIntoView(true);
}
this.tour.start();
if (removedSteps.length) {
removedSteps.forEach((er, index) => {
er.buttons.forEach(br => {
const k = br.key;
const funcRemoved = this.tourStoreService.getFnByKey(k);
const wrapperNextRemoved = () => {
this.navigateAndMoveToNextStepRemoved(er, tourInstance, tourState, index, removedSteps);
};
const wrapperPrevRemoved = () => {
this.navigateAndMoveToPrevStepRemoved(er, tourInstance, tourState, index, removedSteps);
};
const wrapperNormalNextRemoved = () => {
this.moveToNextStepRemoved(tourInstance, tourState, er, index, removedSteps);
};
const wrapperNormalPrevRemoved = () => {
this.moveToPrevStepRemoved(tourInstance, tourState, er, index, removedSteps);
};
this.actionAssignment(er, br, wrapperNormalNextRemoved, wrapperNormalPrevRemoved, wrapperNextRemoved, wrapperPrevRemoved, funcRemoved, tourInstance.tourId, tourState.props);
});
});
this.tour.addSteps(removedSteps);
this.addRemovedSteps(removedSteps);
}
}, err => {
this.tourFailed.next(err);
});
});
}
run(tourId, params, props, filterFn, inputs) {
this.tourStoreService
.loadTour({
tourId,
sessionId: this.tourStoreService.getSessionId(),
})
.subscribe(tourInstance => {
this.checkAndThrowError(tourInstance);
if (params) {
let steps = JSON.stringify(tourInstance.tourSteps);
Object.keys(params).forEach(key => {
steps = steps.replace(new RegExp(`\\{\\{${key}\\}\\}`), params[key]);
});
tourInstance.tourSteps = JSON.parse(steps);
}
this.tour = new Shepherd.Tour({
useModalOverlay: true,
exitOnEsc: this._exitOnEsc,
defaultStepOptions: {
cancelIcon: {
enabled: true,
},
scrollTo: { behavior: 'smooth', block: 'center' },
},
});
this.tour.on('complete', (event) => {
event.tourId = tourInstance.tourId;
this.tourComplete.next(event);
});
// on pressing esc cancel event is emitted by shepherd
this.tour.on('cancel', (event) => {
event.tourId = tourInstance.tourId;
this.tourCancel.next(event);
});
if (filterFn) {
tourInstance.tourSteps = filterFn(tourInstance.tourSteps);
}
if (tourInstance.tourSteps[0].attachTo) {
tourInstance.tourSteps[0].attachTo.scrollTo = false;
}
this.checkComponents(tourInstance, inputs).then(() => {
this.triggerTour(tourInstance, props);
});
});
}
async checkComponents(tourInstance, inputs) {
for (const step of tourInstance.tourSteps) {
if (typeof step.text !== 'string' && typeof step.text !== 'function') {
const htmlStep = await this.parseComponent({
forStep: step.id,
component: this.tourStoreService.getComponentByKey(step.text.component),
}, inputs);
step.text = htmlStep.html;
}
}
}
checkElement(attachTo) {
switch (attachTo.type) {
case 'string':
return document.querySelector(attachTo.element);
case 'element':
return attachTo.element;
case 'function':
const fn = this.tourStoreService.getFnByKey(attachTo.element);
return fn();
default:
return false;
}
}
getRemovedSteps(tourSteps, tourState) {
let f = true;
return tourSteps.filter(e => {
if (e.id === tourState.step || !f) {
f = false;
}
return f;
});
}
getTourSteps(tourSteps, tourState) {
let flag = false;
return tourSteps.filter(e => {
if (e.id === tourState.step || flag) {
flag = true;
}
return flag;
});
}
pauseAllVideos() {
document.querySelectorAll('video').forEach(vid => vid.pause());
}
setTourComplete(tourId, props) {
this.tourStoreService
.saveState({
tourId,
state: {
sessionId: this.tourStoreService.getSessionId(),
step: '',
props,
status: Status.Complete,
},
})
.subscribe();
}
checkAndThrowError(tourInstance) {
if (!tourInstance) {
throw new Error(`No Tour Present`);
}
else if (tourInstance.tourSteps.length === 0) {
throw new Error(`No Tour Steps Found`);
}
else if (tourInstance.tourSteps[0].buttons) {
tourInstance.tourSteps[0].buttons.forEach(button => {
if (button.key === `prevAction`) {
throw new Error(`Step 1 can't have a previous button`);
}
});
}
else {
//do nothing
}
}
moveToNextStep(tourInstance, tourState, step, index) {
if (index === tourInstance.tourSteps.length - 1) {
this.setTourComplete(tourInstance.tourId, tourState.props);
this.tour.next();
}
else {
this.waitForElement(tourInstance.tourSteps[index + 1], tourInstance.tourId).then(() => {
this.tourStoreService
.saveState({
tourId: tourInstance.tourId,
state: {
sessionId: this.tourStoreService.getSessionId(),
step: step.nextStepId,
props: tourState.props,
status: Status.InProgress,
},
})
.subscribe();
this.tour.show(step.nextStepId);
this.tourStepChange.next({
tourId: tourInstance.tourId,
currentStepId: step.nextStepId,
previousStepId: step.id,
moveForward: true,
});
this.pauseAllVideos();
}, err => {
this.tourFailed.next(err);
});
}
}
moveToPrevStep(tourInstance, tourState, step, index, removedSteps) {
let waitForLastElementOfRemovedSteps = false;
if (index === 0 && removedSteps.length) {
waitForLastElementOfRemovedSteps = true;
}
this.waitForElement(waitForLastElementOfRemovedSteps
? removedSteps[removedSteps.length - 1]
: tourInstance.tourSteps[index - 1], tourInstance.tourId).then(() => {
this.tourStoreService
.saveState({
tourId: tourInstance.tourId,
state: {
sessionId: this.tourStoreService.getSessionId(),
step: waitForLastElementOfRemovedSteps
? removedSteps[removedSteps.length - 1].id
: step.prevStepId,
props: tourState.props,
status: Status.InProgress,
},
})
.subscribe();
if (waitForLastElementOfRemovedSteps) {
this.tour.show(removedSteps[removedSteps.length - 1].id);
}
else {
this.tour.show(step.prevStepId);
}
this.tourStepChange.next({
tourId: tourInstance.tourId,
currentStepId: waitForLastElementOfRemovedSteps
? removedSteps[removedSteps.length - 1].id
: step.prevStepId,
previousStepId: step.id,
moveForward: false,
});
this.pauseAllVideos();
}, err => {
this.tourFailed.next(err);
});
}
moveToNextStepRemoved(tourInstance, tourState, step, index, removedSteps) {
let waitForFirstElementOfSteps = false;
if (index === removedSteps.length - 1) {
waitForFirstElementOfSteps = true;
}
this.waitForElement(waitForFirstElementOfSteps
? tourInstance.tourSteps[0]
: removedSteps[index + 1], tourInstance.tourId).then(() => {
this.tourStoreService
.saveState({
tourId: tourInstance.tourId,
state: {
sessionId: this.tourStoreService.getSessionId(),
step: waitForFirstElementOfSteps
? tourInstance.tourSteps[0].id
: step.nextStepId,
props: tourState.props,
status: Status.InProgress,
},
})
.subscribe();
if (waitForFirstElementOfSteps) {
this.tour.show(tourInstance.tourSteps[0].id);
}
else {
this.tour.show(step.nextStepId);
}
this.tourStepChange.next({
tourId: tourInstance.tourId,
currentStepId: waitForFirstElementOfSteps
? tourInstance.tourSteps[0].id
: step.nextStepId,
previousStepId: step.id,
moveForward: true,
});
this.pauseAllVideos();
}, err => {
this.tourFailed.next(err);
});
}
moveToPrevStepRemoved(tourInstance, tourState, step, index, removedSteps) {
this.waitForElement(removedSteps[index - 1], tourInstance.tourId).then(() => {
this.tourStoreService
.saveState({
tourId: tourInstance.tourId,
state: {
sessionId: this.tourStoreService.getSessionId(),
step: step.prevStepId,
props: tourState.props,
status: Status.InProgress,
},
})
.subscribe();
this.tour.show(step.prevStepId);
this.tourStepChange.next({
tourId: tourInstance.tourId,
currentStepId: step.prevStepId,
previousStepId: step.id,
moveForward: false,
});
this.pauseAllVideos();
}, err => {
this.tourFailed.next(err);
});
}
navigateAndMoveToNextStep(currentStep, tourInstance, tourState, index) {
if (index < tourInstance.tourSteps.length - 1) {
this.router.navigate([currentStep.nextRoute]);
this.router.events.subscribe((event) => {
const nextStep = tourInstance.tourSteps.filter(ts => ts.id === currentStep.nextStepId)[0];
if (event instanceof NavigationEnd &&
event.url === nextStep.currentRoute) {
this.moveToNextStep(tourInstance, tourState, currentStep, index);
}
});
}
else {
this.moveToNextStep(tourInstance, tourState, currentStep, index);
}
}
navigateAndMoveToPrevStep(currentStep, tourInstance, tourState, index, removedSteps) {
let moveToLastRemovedStep = false;
if (index === 0 && removedSteps.length) {
moveToLastRemovedStep = true;
}
const prevRoute = moveToLastRemovedStep
? removedSteps[removedSteps.length - 1].prevRoute
: currentStep.prevRoute;
this.router.navigate([prevRoute]);
this.router.events.subscribe((event) => {
let prevStep;
if (moveToLastRemovedStep) {
prevStep = removedSteps[removedSteps.length - 1];
}
else {
prevStep = tourInstance.tourSteps.filter(ts => ts.id === currentStep.prevStepId)[0];
}
if (event instanceof NavigationEnd &&
event.url === prevStep.currentRoute) {
this.moveToPrevStep(tourInstance, tourState, currentStep, index, removedSteps);
}
});
}
navigateAndMoveToNextStepRemoved(currentStep, tourInstance, tourState, index, removedSteps) {
let moveToFirstStep = false;
if (index === removedSteps.length - 1) {
moveToFirstStep = true;
}
const nextRoute = moveToFirstStep
? tourInstance.tourSteps[0].nextRoute
: currentStep.nextRoute;
this.router.navigate([nextRoute]);
this.router.events.subscribe((event) => {
let nextStep;
if (moveToFirstStep) {
nextStep = tourInstance.tourSteps[0];
}
else {
nextStep = tourInstance.tourSteps.filter(ts => ts.id === currentStep.nextStepId)[0];
}
if (event instanceof NavigationEnd &&
event.url === nextStep.currentRoute) {
this.moveToNextStepRemoved(tourInstance, tourState, currentStep, index, removedSteps);
}
});
}
navigateAndMoveToPrevStepRemoved(currentStep, tourInstance, tourState, index, removedSteps) {
this.router.navigate([currentStep.prevRoute]);
this.router.events.subscribe((event) => {
const prevStep = tourInstance.tourSteps.filter(ts => ts.id === currentStep.prevStepId)[0];
if (event instanceof NavigationEnd &&
event.url === prevStep.currentRoute) {
this.moveToPrevStepRemoved(tourInstance, tourState, currentStep, index, removedSteps);
}
});
}
parseComponent(step, input) {
return Promise.resolve({
forStep: step.forStep,
html: () => {
const factory = this.componentFactory.resolveComponentFactory(step.component);
const constructedComponent = factory.create(this.injector);
Object.keys(input ?? {}).forEach(k => {
constructedComponent.instance[k] = input[k];
});
constructedComponent.instance['tour'] = this.tour;
this.appRef.attachView(constructedComponent.hostView);
return constructedComponent.location.nativeElement;
},
});
}
}
TourServiceService.ɵfac = function TourServiceService_Factory(t) { return new (t || TourServiceService)(i0.ɵɵinject(i1.TourStoreServiceService), i0.ɵɵinject(i2.Router), i0.ɵɵinject(i0.ComponentFactoryResolver), i0.ɵɵinject(i0.Injector), i0.ɵɵinject(i0.ApplicationRef)); };
TourServiceService.ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: TourServiceService, factory: TourServiceService.ɵfac, providedIn: 'root' });
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(TourServiceService, [{
type: Injectable,
args: [{
providedIn: 'root',
}]
}], function () { return [{ type: i1.TourStoreServiceService }, { type: i2.Router }, { type: i0.ComponentFactoryResolver }, { type: i0.Injector }, { type: i0.ApplicationRef }]; }, null); })();
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG91ci1zZXJ2aWNlLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbGliL3RvdXItc2VydmljZS5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUtBLE9BQU8sRUFHTCxVQUFVLEdBRVgsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxRQUFRLE1BQU0sYUFBYSxDQUFDO0FBQ25DLE9BQU8sRUFPTCxNQUFNLEdBS1AsTUFBTSxXQUFXLENBQUM7QUFDbkIsT0FBTyxFQUFTLGFBQWEsRUFBMkIsTUFBTSxpQkFBaUIsQ0FBQztBQUNoRixPQUFPLEVBQUMsT0FBTyxFQUFDLE1BQU0sTUFBTSxDQUFDO0FBQzdCLE9BQU8sRUFBQyxxQkFBcUIsRUFBRSxRQUFRLEVBQUMsTUFBTSxxQkFBcUIsQ0FBQzs7OztBQUtwRSxNQUFNLE9BQU8sa0JBQWtCO0lBa0I3QixZQUNtQixnQkFBeUMsRUFDekMsTUFBYyxFQUNkLGdCQUEwQyxFQUMxQyxRQUFrQixFQUNsQixNQUFzQjtRQUp0QixxQkFBZ0IsR0FBaEIsZ0JBQWdCLENBQXlCO1FBQ3pDLFdBQU0sR0FBTixNQUFNLENBQVE7UUFDZCxxQkFBZ0IsR0FBaEIsZ0JBQWdCLENBQTBCO1FBQzFDLGFBQVEsR0FBUixRQUFRLENBQVU7UUFDbEIsV0FBTSxHQUFOLE1BQU0sQ0FBZ0I7UUF0QnhCLGlCQUFZLEdBQUcsSUFBSSxPQUFPLEVBQWdCLENBQUM7UUFDNUQsa0JBQWEsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLFlBQVksRUFBRSxDQUFDO1FBQ2hDLG1CQUFjLEdBQUcsSUFBSSxPQUFPLEVBQWtCLENBQUM7UUFDaEUsb0JBQWUsR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLFlBQVksRUFBRSxDQUFDO1FBQ3BDLGVBQVUsR0FBRyxJQUFJLE9BQU8sRUFBYyxDQUFDO1FBQ3hELGdCQUFXLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUM1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Q0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLG9CQUFvQixDQUFDLFFBQVEsQ0FBQyxDQUFDO2dCQUN0RCxPQUFPLG9CQUFvQixDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUM7WUFDckQsQ0FBQztTQUNGLENBQUMsQ0FBQztJQUNMLENBQUM7O29GQTdzQlUsa0JBQWtCO3dFQUFsQixrQkFBa0IsV0FBbEIsa0JBQWtCLG1CQUZqQixNQUFNO3VGQUVQLGtCQUFrQjtjQUg5QixVQUFVO2VBQUM7Z0JBQ1YsVUFBVSxFQUFFLE1BQU07YUFDbkIiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgKGMpIDIwMjMgU291cmNlZnVzZSBUZWNobm9sb2dpZXNcbi8vXG4vLyBUaGlzIHNvZnR3YXJlIGlzIHJlbGVhc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cbi8vIGh0dHBzOi8vb3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvTUlUXG5pbXBvcnQge1RvdXJTdG9yZVNlcnZpY2VTZXJ2aWNlfSBmcm9tICcuL3RvdXItc3RvcmUtc2VydmljZS5zZXJ2aWNlJztcbmltcG9ydCB7XG4gIEFwcGxpY2F0aW9uUmVmLFxuICBDb21wb25lbnRGYWN0b3J5UmVzb2x2ZXIsXG4gIEluamVjdGFibGUsXG4gIEluamVjdG9yLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCBTaGVwaGVyZCBmcm9tICdzaGVwaGVyZC5qcyc7XG5pbXBvcnQge1xuICBUb3VyLFxuICBUb3VyQnV0dG9uLFxuICBUb3VyU3RlcCxcbiAgVG91clN0YXRlLFxuICBGaWx0ZXJGdW5jdGlvbixcbiAgUHJvcHMsXG4gIFN0YXR1cyxcbiAgVG91clN0ZXBDaGFuZ2UsXG4gIFRvdXJDb21wbGV0ZSxcbiAgVG91ckNhbmNlbCxcbiAgQ29tcG9uZW50U3RlcCxcbn0gZnJvbSAnLi4vbW9kZWxzJztcbmltcG9ydCB7Um91dGVyLCBOYXZpZ2F0aW9uRW5kLCBFdmVudCBhcyBOYXZpZ2F0aW9uRXZlbnR9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQge1N1YmplY3R9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHtERUZBVUxUX01BWF9XQUlUX1RJTUUsIElOVEVSVkFMfSBmcm9tICcuLi9tb2RlbHMvY29uc3RhbnRzJztcblxuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiAncm9vdCcsXG59KVxuZXhwb3J0IGNsYXNzIFRvdXJTZXJ2aWNlU2VydmljZSB7XG4gIHByaXZhdGUgcmVhZG9ubHkgdG91ckNvbXBsZXRlID0gbmV3IFN1YmplY3Q8VG91ckNvbXBsZXRlPigpO1xuICB0b3VyQ29tcGxldGUkID0gdGhpcy50b3VyQ29tcGxldGUuYXNPYnNlcnZhYmxlKCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgdG91clN0ZXBDaGFuZ2UgPSBuZXcgU3ViamVjdDxUb3VyU3RlcENoYW5nZT4oKTtcbiAgdG91clN0ZXBDaGFuZ2UkID0gdGhpcy50b3VyU3RlcENoYW5nZS5hc09ic2VydmFibGUoKTtcbiAgcHJpdmF0ZSByZWFkb25seSB0b3VyQ2FuY2VsID0gbmV3IFN1YmplY3Q8VG91ckNhbmNlbD4oKTtcbiAgdG91ckNhbmNlbCQgPSB0aGlzLnRvdXJDYW5jZWwuYXNPYnNlcnZhYmxlKCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgaW50ZXJ2YWwgPSBJTlRFUlZBTDtcbiAgcHJpdmF0ZSBfbWF4V2FpdFRpbWUgPSBERUZBVUxUX01BWF9XQUlUX1RJTUU7XG4gIHByaXZhdGUgX2V4aXRPbkVzYyA9IHRydWU7XG4gIHByaXZhdGUgcmVhZG9ubHkgdG91ckZhaWxlZCA9IG5ldyBTdWJqZWN0PHtcbiAgICB0b3VySWQ6IHN0cmluZztcbiAgICBtZXNzYWdlOiBzdHJpbmc7XG4gIH0+KCk7XG4gIHRvdXJGYWlsZWQkID0gdGhpcy50b3VyRmFpbGVkLmFzT2JzZXJ2YWJsZSgpO1xuXG4gIHByaXZhdGUgdG91cjogU2hlcGhlcmQuVG91cjtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHJlYWRvbmx5IHRvdXJTdG9yZVNlcnZpY2U6IFRvdXJTdG9yZVNlcnZpY2VTZXJ2aWNlLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgcm91dGVyOiBSb3V0ZXIsXG4gICAgcHJpdmF0ZSByZWFkb25seSBjb21wb25lbnRGYWN0b3J5OiBDb21wb25lbnRGYWN0b3J5UmVzb2x2ZXIsXG4gICAgcHJpdmF0ZSByZWFkb25seSBpbmplY3RvcjogSW5qZWN0b3IsXG4gICAgcHJpdmF0ZSByZWFkb25seSBhcHBSZWY6IEFwcGxpY2F0aW9uUmVmLFxuICApIHt9XG5cbiAgcHVibGljIHNldCBtYXhXYWl0VGltZShtYXhUaW1lOiBudW1iZXIpIHtcbiAgICBpZiAobWF4VGltZSA+IDApIHtcbiAgICAgIHRoaXMuX21heFdhaXRUaW1lID0gbWF4VGltZTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgZ2V0IG1heFdhaXRUaW1lKCkge1xuICAgIHJldHVybiB0aGlzLl9tYXhXYWl0VGltZTtcbiAgfVxuXG4gIHB1YmxpYyBzZXQgZXhpdE9uRXNjKGVzYzogYm9vbGVhbikge1xuICAgIHRoaXMuX2V4aXRPbkVzYyA9IGVzYztcbiAgfVxuXG4gIHB1YmxpYyBnZXQgZXhpdE9uRXNjKCkge1xuICAgIHJldHVybiB0aGlzLl9leGl0T25Fc2M7XG4gIH1cbiAgcHJpdmF0ZSBhZGRSZW1vdmVkU3RlcHMocmVtb3ZlZFN0ZXBzKTogdm9pZCB7XG4gICAgY29uc3QgY291bnQgPSByZW1vdmVkU3RlcHMubGVuZ3RoO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY291bnQ7IGkrKykge1xuICAgICAgdGhpcy50b3VyLnN0ZXBzLnNwbGljZSgwLCAwLCB0aGlzLnRvdXIuc3RlcHMucG9wKCkpO1xuICAgIH1cbiAgfVxuXG4gIGdldFRvdXIoKSB7XG4gICAgcmV0dXJuIHRoaXMudG91cjtcbiAgfVxuXG4gIHByaXZhdGUgYWN0aW9uQXNzaWdubWVudChcbiAgICBlOiBUb3VyU3RlcCxcbiAgICBiOiBUb3VyQnV0dG9uLFxuICAgIHdyYXBwZXJOb3JtYWxOZXh0LFxuICAgIHdyYXBwZXJOb3JtYWxQcmV2LFxuICAgIHdyYXBwZXJOZXh0LFxuICAgIHdyYXBwZXJQcmV2LFxuICAgIGZ1bmMsXG4gICAgdG91cklkOiBzdHJpbmcsXG4gICAgcHJvcHM6IFByb3BzLFxuICApOiB2b2lkIHtcbiAgICBpZiAoYi5rZXkgPT09ICdwcmV2QWN0aW9uJykge1xuICAgICAgYi5hY3Rpb24gPVxuICAgICAgICBlLnByZXZSb3V0ZSA9PT0gZS5jdXJyZW50Um91dGUgPyB3cmFwcGVyTm9ybWFsUHJldiA6IHdyYXBwZXJQcmV2O1xuICAgIH0gZWxzZSBpZiAoYi5rZXkgPT09ICduZXh0QWN0aW9uJykge1xuICAgICAgYi5hY3Rpb24gPVxuICAgICAgICBlLm5leHRSb3V0ZSA9PT0gZS5jdXJyZW50Um91dGUgPyB3cmFwcGVyTm9ybWFsTmV4dCA6IHdyYXBwZXJOZXh0O1xuICAgIH0gZWxzZSB7XG4gICAgICBiLmFjdGlvbiA9IGZ1bmMuYmluZCh7dG91cjogdGhpcy50b3VyLCB0b3VySWQsIHByb3BzfSk7XG4gICAgfVxuICB9XG5c