@w11k/ngx-present
Version:
Angular based Presentation Tool
759 lines • 50 kB
JavaScript
/**
* @fileoverview added by tsickle
* Generated from: lib/slide-by-slide/slide-by-slide.service.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
import { Injectable, Injector } from '@angular/core';
import { Router } from '@angular/router';
import { skipNil, skipPropertyNil } from '@w11k/rx-ninja';
import { Commands, Facade } from '@w11k/tydux';
import { combineLatest, Subject } from 'rxjs';
import { filter, map, take, takeUntil, withLatestFrom } from 'rxjs/operators';
import { isNotEditable, nonNavigationEvent } from '../core/event.service';
import { PresentationService } from '../core/presentation.service';
import { Slide } from '../core/presentation.types';
import { flattenDeep, maxDepth } from '../core/utils';
import { tableOfContentSlides } from '../theming/table-of-content';
import { calculateCoordinates, compareCoordinates, coordinateToSlideMap, equalCoordinates, isValidCoordinate, routeParamsToCoordinate, } from './slide-by-slide.functions';
import * as i0 from "@angular/core";
import * as i1 from "../core/presentation.service";
import * as i2 from "@angular/router";
export class SlideBySlideState {
constructor() {
this.coordinatesMaxDepth = 0;
this.slides = [];
this.slideMap = {};
}
}
if (false) {
/** @type {?} */
SlideBySlideState.prototype.coordinatesMaxDepth;
/** @type {?} */
SlideBySlideState.prototype.slides;
/** @type {?} */
SlideBySlideState.prototype.slideMap;
/** @type {?} */
SlideBySlideState.prototype.currentSlide;
/** @type {?} */
SlideBySlideState.prototype.currentMode;
}
export class SlideBySlideMutator extends Commands {
constructor() {
super();
}
/**
* @param {?} slide
* @return {?}
*/
setCurrentSlide(slide) {
this.state.currentSlide = slide;
}
/**
* @param {?} mode
* @return {?}
*/
setCurrentMode(mode) {
this.state.currentMode = mode;
}
/**
* @param {?} slides
* @return {?}
*/
setSlides(slides) {
this.state.coordinatesMaxDepth = maxDepth(slides);
this.state.slides = flattenDeep(slides);
this.state.slideMap = coordinateToSlideMap(this.state.slides);
}
}
export class SlideBySlideService extends Facade {
/**
* @param {?} injector
* @param {?} presentation
* @param {?} router
*/
constructor(injector, presentation, router) {
super('SlideBySlide', new SlideBySlideState(), new SlideBySlideMutator());
this.presentation = presentation;
this.router = router;
this.onDestroy$ = new Subject();
this.presentation.select((/**
* @param {?} state
* @return {?}
*/
state => state.slides))
.pipe(takeUntil(this.onDestroy$))
.subscribe((/**
* @param {?} slides
* @return {?}
*/
slides => this.commands.setSlides(slides)));
}
/**
* @param {?} coordinatesToKeep
* @param {?=} mode
* @return {?}
*/
navigateToNext(coordinatesToKeep, mode) {
this.nextSlide(coordinatesToKeep)
.pipe(take(1))
.subscribe((/**
* @param {?} slide
* @return {?}
*/
slide => this.navigateAbsolute(slide, mode)));
}
/**
* @param {?} coordinatesToKeep
* @param {?=} mode
* @return {?}
*/
navigateToPrevious(coordinatesToKeep, mode) {
this.previousSlide(coordinatesToKeep)
.pipe(take(1))
.subscribe((/**
* @param {?} slide
* @return {?}
*/
slide => this.navigateAbsolute(slide, mode)));
}
/**
* @param {?} coordinatesToKeep
* @param {?=} prefix
* @return {?}
*/
previousSlide(coordinatesToKeep, prefix) {
return this.navigateRelative(-1, coordinatesToKeep);
}
/**
* @param {?} coordinatesToKeep
* @return {?}
*/
nextSlide(coordinatesToKeep) {
return this.navigateRelative(1, coordinatesToKeep);
}
/**
* @param {?=} mode
* @return {?}
*/
navigateToNextToc(mode) {
this.nextToc('forward')
.pipe(take(1))
.subscribe((/**
* @param {?} slide
* @return {?}
*/
slide => this.navigateAbsolute(slide, mode)));
}
/**
* @param {?=} mode
* @return {?}
*/
navigateToPreviousToc(mode) {
this.nextToc('backward')
.pipe(take(1))
.subscribe((/**
* @param {?} slide
* @return {?}
*/
slide => this.navigateAbsolute(slide, mode)));
}
/**
* @param {?} direction
* @return {?}
*/
nextToc(direction) {
/** @type {?} */
const currentSlide$ = this.select((/**
* @param {?} state
* @return {?}
*/
state => state.currentSlide))
.pipe(skipNil());
/** @type {?} */
const tocSlides$ = this.select((/**
* @param {?} state
* @return {?}
*/
state => state.slides))
.pipe(skipNil(), filter((/**
* @param {?} x
* @return {?}
*/
x => x.length !== 0)), map(tableOfContentSlides));
return combineLatest(currentSlide$, tocSlides$)
.pipe(map((/**
* @param {?} __0
* @return {?}
*/
([currentSlide, tocSlides]) => {
if (direction === 'forward') {
return tocSlides.find((/**
* @param {?} tocSlide
* @return {?}
*/
tocSlide => {
return compareCoordinates(tocSlide.coordinates, currentSlide.coordinates) === 1;
}));
}
else {
return tocSlides.slice().reverse().find((/**
* @param {?} tocSlide
* @return {?}
*/
tocSlide => {
return compareCoordinates(tocSlide.coordinates, currentSlide.coordinates) === -1;
}));
}
})));
}
/**
* @param {?} move
* @param {?} coordinatesToKeep
* @return {?}
*/
navigateRelative(move, coordinatesToKeep) {
/** @type {?} */
const currentSlide$ = this.select((/**
* @param {?} state
* @return {?}
*/
state => state.currentSlide))
.pipe(skipNil());
/** @type {?} */
const slides$ = this.select((/**
* @param {?} state
* @return {?}
*/
state => state.slides))
.pipe(skipNil(), filter((/**
* @param {?} x
* @return {?}
*/
x => x.length !== 0)));
/** @type {?} */
const depth$ = this.select((/**
* @param {?} state
* @return {?}
*/
state => state.coordinatesMaxDepth))
.pipe(skipNil());
return combineLatest(slides$, currentSlide$, depth$)
.pipe(map((/**
* @param {?} __0
* @return {?}
*/
([slides, current, depth]) => calculateCoordinates(slides, current, move, coordinatesToKeep, depth))));
}
/**
* @param {?} target
* @param {?=} mode
* @return {?}
*/
navigateAbsolute(target, mode) {
/** @type {?} */
let slide;
if (target instanceof Slide) {
slide = target;
}
else {
slide = this.state.slides.find((/**
* @param {?} x
* @return {?}
*/
x => equalCoordinates(target, x.coordinates)));
}
if (slide === undefined) {
return;
}
/** @type {?} */
let modeWithFallback;
if (mode !== undefined) {
modeWithFallback = mode;
}
else if (this.state.currentMode !== undefined) {
modeWithFallback = this.state.currentMode;
}
else {
modeWithFallback = 'slide';
}
/** @type {?} */
const link = [`/${modeWithFallback}`, ...slide.coordinates];
return this.router.navigate(link, { queryParamsHandling: 'merge' });
}
/**
* @param {?=} prefix
* @return {?}
*/
navigateToFirst(prefix) {
this.firstSlide()
.pipe(take(1), takeUntil(this.onDestroy$))
.subscribe((/**
* @param {?} slide
* @return {?}
*/
slide => this.navigateAbsolute(slide, prefix)));
}
/**
* @return {?}
*/
firstSlide() {
return this.select((/**
* @param {?} state
* @return {?}
*/
state => state.slides))
.pipe(skipNil(), filter((/**
* @param {?} slides
* @return {?}
*/
slides => slides.length > 0)), map((/**
* @param {?} slides
* @return {?}
*/
slides => slides[0])));
}
/**
* @param {?} coordinates
* @return {?}
*/
isValidCoordinate(coordinates) {
return this.presentation.select((/**
* @param {?} state
* @return {?}
*/
state => state.slides))
.pipe(skipNil(), filter((/**
* @param {?} slides
* @return {?}
*/
slides => slides.length > 0)), map((/**
* @param {?} slides
* @return {?}
*/
slides => isValidCoordinate(slides, coordinates))));
}
/**
* @private
* @param {?} coordinates
* @return {?}
*/
coordinatesToSlide(coordinates) {
return this.state.slideMap[coordinates.join('.')];
}
/**
* @param {?} route
* @return {?}
*/
setCurrentModeAndSlide(route) {
/** @type {?} */
const coordinates = routeParamsToCoordinate(route.params);
/** @type {?} */
const mode = (/** @type {?} */ (route.url[0].path));
/** @type {?} */
const slide = this.coordinatesToSlide(coordinates);
this.commands.setCurrentSlide(slide);
this.commands.setCurrentMode(mode);
}
/**
* @return {?}
*/
ngOnDestroy() {
this.onDestroy$.next();
}
}
SlideBySlideService.decorators = [
{ type: Injectable, args: [{
providedIn: 'root'
},] }
];
/** @nocollapse */
SlideBySlideService.ctorParameters = () => [
{ type: Injector },
{ type: PresentationService },
{ type: Router }
];
/** @nocollapse */ SlideBySlideService.ɵprov = i0.ɵɵdefineInjectable({ factory: function SlideBySlideService_Factory() { return new SlideBySlideService(i0.ɵɵinject(i0.INJECTOR), i0.ɵɵinject(i1.PresentationService), i0.ɵɵinject(i2.Router)); }, token: SlideBySlideService, providedIn: "root" });
if (false) {
/**
* @type {?}
* @private
*/
SlideBySlideService.prototype.onDestroy$;
/**
* @type {?}
* @private
*/
SlideBySlideService.prototype.presentation;
/**
* @type {?}
* @private
*/
SlideBySlideService.prototype.router;
}
export class NavigateSectionForward {
/**
* @param {?} service
*/
constructor(service) {
this.service = service;
}
/**
* @param {?} events$
* @return {?}
*/
init(events$) {
events$
.pipe(filter(isNotEditable),
// arrow down + alt || arrow right + alt
filter((/**
* @param {?} event
* @return {?}
*/
event => {
if (event.keyCode === 40 && event.altKey) {
return true;
}
else if (event.keyCode === 39 && event.altKey) {
return true;
}
return false;
})))
.subscribe((/**
* @return {?}
*/
() => {
this.service.navigateToNextToc();
}));
}
}
NavigateSectionForward.decorators = [
{ type: Injectable }
];
/** @nocollapse */
NavigateSectionForward.ctorParameters = () => [
{ type: SlideBySlideService }
];
if (false) {
/**
* @type {?}
* @private
*/
NavigateSectionForward.prototype.service;
}
export class NavigateSlideForward {
/**
* @param {?} service
*/
constructor(service) {
this.service = service;
}
/**
* @param {?} events$
* @return {?}
*/
init(events$) {
events$
.pipe(filter(nonNavigationEvent),
// arrow down, arrow right, or page down
filter((/**
* @param {?} event
* @return {?}
*/
event => event.keyCode === 40 || event.keyCode === 39 || event.keyCode === 34)))
.subscribe((/**
* @return {?}
*/
() => {
this.service.navigateToNext(-1);
}));
}
}
NavigateSlideForward.decorators = [
{ type: Injectable }
];
/** @nocollapse */
NavigateSlideForward.ctorParameters = () => [
{ type: SlideBySlideService }
];
if (false) {
/**
* @type {?}
* @private
*/
NavigateSlideForward.prototype.service;
}
export class NavigateSectionBackward {
/**
* @param {?} service
*/
constructor(service) {
this.service = service;
}
/**
* @param {?} events$
* @return {?}
*/
init(events$) {
events$
.pipe(filter(isNotEditable),
// arrow up + alt || arrow left + alt
filter((/**
* @param {?} event
* @return {?}
*/
event => {
if (event.keyCode === 38 && event.altKey) {
return true;
}
else if (event.keyCode === 37 && event.altKey) {
return true;
}
return false;
})))
.subscribe((/**
* @return {?}
*/
() => {
this.service.navigateToPreviousToc();
}));
}
}
NavigateSectionBackward.decorators = [
{ type: Injectable }
];
/** @nocollapse */
NavigateSectionBackward.ctorParameters = () => [
{ type: SlideBySlideService }
];
if (false) {
/**
* @type {?}
* @private
*/
NavigateSectionBackward.prototype.service;
}
export class NavigateSlideBackward {
/**
* @param {?} service
*/
constructor(service) {
this.service = service;
}
/**
* @param {?} events$
* @return {?}
*/
init(events$) {
events$
.pipe(filter(nonNavigationEvent),
// arrow up, arrow left or page up
filter((/**
* @param {?} event
* @return {?}
*/
event => event.keyCode === 38 || event.keyCode === 37 || event.keyCode === 33)))
.subscribe((/**
* @return {?}
*/
() => {
this.service.navigateToPrevious(-1);
}));
}
}
NavigateSlideBackward.decorators = [
{ type: Injectable }
];
/** @nocollapse */
NavigateSlideBackward.ctorParameters = () => [
{ type: SlideBySlideService }
];
if (false) {
/**
* @type {?}
* @private
*/
NavigateSlideBackward.prototype.service;
}
export class NavigateToFirstSlide {
/**
* @param {?} service
*/
constructor(service) {
this.service = service;
}
/**
* @param {?} events$
* @return {?}
*/
init(events$) {
events$
.pipe(filter(nonNavigationEvent),
// pos 1
filter((/**
* @param {?} event
* @return {?}
*/
event => event.keyCode === 36)))
.subscribe((/**
* @return {?}
*/
() => {
this.service.navigateToFirst();
}));
}
}
NavigateToFirstSlide.decorators = [
{ type: Injectable }
];
/** @nocollapse */
NavigateToFirstSlide.ctorParameters = () => [
{ type: SlideBySlideService }
];
if (false) {
/**
* @type {?}
* @private
*/
NavigateToFirstSlide.prototype.service;
}
export class NavigateToOverview {
/**
* @param {?} service
* @param {?} presentation
*/
constructor(service, presentation) {
this.service = service;
this.presentation = presentation;
}
/**
* @param {?} events$
* @return {?}
*/
init(events$) {
/** @type {?} */
const config$ = this.presentation.select((/**
* @param {?} state
* @return {?}
*/
state => state.config.navigation.overview))
.pipe(skipPropertyNil('component'));
/** @type {?} */
const slide$ = this.service.select()
.pipe(withLatestFrom(config$), map((/**
* @param {?} __0
* @return {?}
*/
([state, config]) => state.slides.find((/**
* @param {?} slide
* @return {?}
*/
slide => slide.component === config.component)))));
events$
.pipe(filter(nonNavigationEvent),
// pos 1
filter((/**
* @param {?} event
* @return {?}
*/
event => {
// o
return event.keyCode === 79;
})), withLatestFrom(slide$))
.subscribe((/**
* @param {?} __0
* @return {?}
*/
([event, slide]) => {
this.service.navigateAbsolute(slide);
}));
}
}
NavigateToOverview.decorators = [
{ type: Injectable }
];
/** @nocollapse */
NavigateToOverview.ctorParameters = () => [
{ type: SlideBySlideService },
{ type: PresentationService }
];
if (false) {
/**
* @type {?}
* @private
*/
NavigateToOverview.prototype.service;
/**
* @type {?}
* @private
*/
NavigateToOverview.prototype.presentation;
}
export class TogglePresenter {
/**
* @param {?} service
* @param {?} router
*/
constructor(service, router) {
this.service = service;
this.router = router;
}
/**
* @param {?} events$
* @return {?}
*/
init(events$) {
/** @type {?} */
const slide$ = this.service.select();
events$
.pipe(filter(isNotEditable),
// letter p
filter((/**
* @param {?} event
* @return {?}
*/
event => event.keyCode === 80 && event.altKey)), withLatestFrom(slide$))
.subscribe((/**
* @param {?} __0
* @return {?}
*/
([event, state]) => {
/** @type {?} */
let mode;
if (state.currentMode === 'presenter') {
mode = 'slide';
}
else {
mode = 'presenter';
}
/** @type {?} */
let coordinates = [];
if (state.currentSlide !== undefined) {
coordinates = state.currentSlide.coordinates;
}
/** @type {?} */
const link = [mode, ...coordinates];
this.router.navigate(link, { queryParamsHandling: 'merge' });
}));
}
}
TogglePresenter.decorators = [
{ type: Injectable }
];
/** @nocollapse */
TogglePresenter.ctorParameters = () => [
{ type: SlideBySlideService },
{ type: Router }
];
if (false) {
/**
* @type {?}
* @private
*/
TogglePresenter.prototype.service;
/**
* @type {?}
* @private
*/
TogglePresenter.prototype.router;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2xpZGUtYnktc2xpZGUuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiJuZzovL0B3MTFrL25neC1wcmVzZW50LyIsInNvdXJjZXMiOlsibGliL3NsaWRlLWJ5LXNsaWRlL3NsaWRlLWJ5LXNsaWRlLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLFFBQVEsRUFBYSxNQUFNLGVBQWUsQ0FBQztBQUNoRSxPQUFPLEVBQTBCLE1BQU0sRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ2pFLE9BQU8sRUFBRSxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDMUQsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDL0MsT0FBTyxFQUFFLGFBQWEsRUFBYyxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDMUQsT0FBTyxFQUFFLE1BQU0sRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxjQUFjLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM5RSxPQUFPLEVBQUUsYUFBYSxFQUEwQixrQkFBa0IsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQ2xHLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQ25FLE9BQU8sRUFBZSxLQUFLLEVBQVUsTUFBTSw0QkFBNEIsQ0FBQztBQUN4RSxPQUFPLEVBQUUsV0FBVyxFQUFFLFFBQVEsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN0RCxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUNuRSxPQUFPLEVBQ0wsb0JBQW9CLEVBQ3BCLGtCQUFrQixFQUNsQixvQkFBb0IsRUFDcEIsZ0JBQWdCLEVBQ2hCLGlCQUFpQixFQUNqQix1QkFBdUIsR0FDeEIsTUFBTSw0QkFBNEIsQ0FBQzs7OztBQUlwQyxNQUFNLE9BQU8saUJBQWlCO0lBTzVCO1FBTk8sd0JBQW1C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LEdBQUcsQ0FBQyxJQUFJLEVBQUUsR0FBRyxXQUFXLENBQUM7WUFDbkMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLEVBQUUsbUJBQW1CLEVBQUUsT0FBTyxFQUFDLENBQUMsQ0FBQztRQUM5RCxDQUFDLEVBQUMsQ0FBQztJQUNQLENBQUM7OztZQWxDRixVQUFVOzs7O1lBRTZCLG1CQUFtQjtZQTVXMUIsTUFBTTs7Ozs7OztJQTRXekIsa0NBQTZDOzs7OztJQUM3QyxpQ0FBK0IiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlLCBJbmplY3RvciwgT25EZXN0cm95IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBBY3RpdmF0ZWRSb3V0ZVNuYXBzaG90LCBSb3V0ZXIgfSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xuaW1wb3J0IHsgc2tpcE5pbCwgc2tpcFByb3BlcnR5TmlsIH0gZnJvbSAnQHcxMWsvcngtbmluamEnO1xuaW1wb3J0IHsgQ29tbWFuZHMsIEZhY2FkZSB9IGZyb20gJ0B3MTFrL3R5ZHV4JztcbmltcG9ydCB7IGNvbWJpbmVMYXRlc3QsIE9ic2VydmFibGUsIFN1YmplY3QgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IGZpbHRlciwgbWFwLCB0YWtlLCB0YWtlVW50aWwsIHdpdGhMYXRlc3RGcm9tIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgaXNOb3RFZGl0YWJsZSwgS2V5Ym9hcmRFdmVudFByb2Nlc3Nvciwgbm9uTmF2aWdhdGlvbkV2ZW50IH0gZnJvbSAnLi4vY29yZS9ldmVudC5zZXJ2aWNlJztcbmltcG9ydCB7IFByZXNlbnRhdGlvblNlcnZpY2UgfSBmcm9tICcuLi9jb3JlL3ByZXNlbnRhdGlvbi5zZXJ2aWNlJztcbmltcG9ydCB7IENvb3JkaW5hdGVzLCBTbGlkZSwgU2xpZGVzIH0gZnJvbSAnLi4vY29yZS9wcmVzZW50YXRpb24udHlwZXMnO1xuaW1wb3J0IHsgZmxhdHRlbkRlZXAsIG1heERlcHRoIH0gZnJvbSAnLi4vY29yZS91dGlscyc7XG5pbXBvcnQgeyB0YWJsZU9mQ29udGVudFNsaWRlcyB9IGZyb20gJy4uL3RoZW1pbmcvdGFibGUtb2YtY29udGVudCc7XG5pbXBvcnQge1xuICBjYWxjdWxhdGVDb29yZGluYXRlcyxcbiAgY29tcGFyZUNvb3JkaW5hdGVzLFxuICBjb29yZGluYXRlVG9TbGlkZU1hcCxcbiAgZXF1YWxDb29yZGluYXRlcyxcbiAgaXNWYWxpZENvb3JkaW5hdGUsXG4gIHJvdXRlUGFyYW1zVG9Db29yZGluYXRlLFxufSBmcm9tICcuL3NsaWRlLWJ5LXNsaWRlLmZ1bmN0aW9ucyc7XG5cbmV4cG9ydCB0eXBlIE1vZGUgPSAnc2xpZGUnIHwgJ3ByZXNlbnRlcic7XG5cbmV4cG9ydCBjbGFzcyBTbGlkZUJ5U2xpZGVTdGF0ZSB7XG4gIHB1YmxpYyBjb29yZGluYXRlc01heERlcHRoID0gMDtcbiAgcHVibGljIHNsaWRlczogU2xpZGVbXSA9IFtdO1xuICBwdWJsaWMgc2xpZGVNYXA6IHsgW2tleTogc3RyaW5nXTogU2xpZGUgfSA9IHt9O1xuICBwdWJsaWMgY3VycmVudFNsaWRlOiBTbGlkZSB8IHVuZGVmaW5lZDtcbiAgcHVibGljIGN1cnJlbnRNb2RlOiBNb2RlIHwgdW5kZWZpbmVkO1xuXG4gIGNvbnN0cnVjdG9yKCkge31cbn1cblxuZXhwb3J0IGNsYXNzIFNsaWRlQnlTbGlkZU11dGF0b3IgZXh0ZW5kcyBDb21tYW5kczxTbGlkZUJ5U2xpZGVTdGF0ZT4ge1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKCk7XG4gIH1cblxuICBzZXRDdXJyZW50U2xpZGUoc2xpZGU6IFNsaWRlKSB7XG4gICAgdGhpcy5zdGF0ZS5jdXJyZW50U2xpZGUgPSBzbGlkZTtcbiAgfVxuXG4gIHNldEN1cnJlbnRNb2RlKG1vZGU6IE1vZGUpIHtcbiAgICB0aGlzLnN0YXRlLmN1cnJlbnRNb2RlID0gbW9kZTtcbiAgfVxuXG4gIHNldFNsaWRlcyhzbGlkZXM6IFNsaWRlcykge1xuICAgIHRoaXMuc3RhdGUuY29vcmRpbmF0ZXNNYXhEZXB0aCA9IG1heERlcHRoKHNsaWRlcyk7XG4gICAgdGhpcy5zdGF0ZS5zbGlkZXMgPSBmbGF0dGVuRGVlcChzbGlkZXMpO1xuICAgIHRoaXMuc3RhdGUuc2xpZGVNYXAgPSBjb29yZGluYXRlVG9TbGlkZU1hcCh0aGlzLnN0YXRlLnNsaWRlcyk7XG4gIH1cblxufVxuXG5ASW5qZWN0YWJsZSh7XG4gIHByb3ZpZGVkSW46ICdyb290J1xufSlcbmV4cG9ydCBjbGFzcyBTbGlkZUJ5U2xpZGVTZXJ2aWNlIGV4dGVuZHMgRmFjYWRlPFNsaWRlQnlTbGlkZVN0YXRlLCBTbGlkZUJ5U2xpZGVNdXRhdG9yPiBpbXBsZW1lbnRzIE9uRGVzdHJveSB7XG5cbiAgY29uc3RydWN0b3IoaW5qZWN0b3I6IEluamVjdG9yLFxuICAgICAgICAgICAgICBwcml2YXRlIHJlYWRvbmx5IHByZXNlbnRhdGlvbjogUHJlc2VudGF0aW9uU2VydmljZSxcbiAgICAgICAgICAgICAgcHJpdmF0ZSByZWFkb25seSByb3V0ZXI6IFJvdXRlcikge1xuICAgIHN1cGVyKCdTbGlkZUJ5U2xpZGUnLCBuZXcgU2xpZGVCeVNsaWRlU3RhdGUoKSwgbmV3IFNsaWRlQnlTbGlkZU11dGF0b3IoKSk7XG5cbiAgICB0aGlzLnByZXNlbnRhdGlvbi5zZWxlY3Qoc3RhdGUgPT4gc3RhdGUuc2xpZGVzKVxuICAgICAgLnBpcGUodGFrZVVudGlsKHRoaXMub25EZXN0cm95JCkpXG4gICAgICAuc3Vic2NyaWJlKHNsaWRlcyA9PiB0aGlzLmNvbW1hbmRzLnNldFNsaWRlcyhzbGlkZXMpKTtcbiAgfVxuXG4gIG5hdmlnYXRlVG9OZXh0KGNvb3JkaW5hdGVzVG9LZWVwOiBudW1iZXIgfCB1bmRlZmluZWQsIG1vZGU/OiBzdHJpbmcpIHtcbiAgICB0aGlzLm5leHRTbGlkZShjb29yZGluYXRlc1RvS2VlcClcbiAgICAgIC5waXBlKHRha2UoMSkpXG4gICAgICAuc3Vic2NyaWJlKHNsaWRlID0+IHRoaXMubmF2aWdhdGVBYnNvbHV0ZShzbGlkZSwgbW9kZSkpO1xuICB9XG5cbiAgbmF2aWdhdGVUb1ByZXZpb3VzKGNvb3JkaW5hdGVzVG9LZWVwOiBudW1iZXIgfCB1bmRlZmluZWQsIG1vZGU/OiBzdHJpbmcpIHtcbiAgICB0aGlzLnByZXZpb3VzU2xpZGUoY29vcmRpbmF0ZXNUb0tlZXApXG4gICAgICAucGlwZSh0YWtlKDEpKVxuICAgICAgLnN1YnNjcmliZShzbGlkZSA9PiB0aGlzLm5hdmlnYXRlQWJzb2x1dGUoc2xpZGUsIG1vZGUpKTtcbiAgfVxuXG4gIHByZXZpb3VzU2xpZGUoY29vcmRpbmF0ZXNUb0tlZXA6IG51bWJlciB8IHVuZGVmaW5lZCwgcHJlZml4Pzogc3RyaW5nKTogT2JzZXJ2YWJsZTxTbGlkZSB8IHVuZGVmaW5lZD4ge1xuICAgIHJldHVybiB0aGlzLm5hdmlnYXRlUmVsYXRpdmUoLTEsIGNvb3JkaW5hdGVzVG9LZWVwKTtcbiAgfVxuXG4gIG5leHRTbGlkZShjb29yZGluYXRlc1RvS2VlcDogbnVtYmVyIHwgdW5kZWZpbmVkKTogT2JzZXJ2YWJsZTxTbGlkZSB8IHVuZGVmaW5lZD4ge1xuICAgIHJldHVybiB0aGlzLm5hdmlnYXRlUmVsYXRpdmUoMSwgY29vcmRpbmF0ZXNUb0tlZXApO1xuICB9XG5cbiAgbmF2aWdhdGVUb05leHRUb2MobW9kZT86IHN0cmluZykge1xuICAgIHRoaXMubmV4dFRvYygnZm9yd2FyZCcpXG4gICAgICAucGlwZSh0YWtlKDEpKVxuICAgICAgLnN1YnNjcmliZShzbGlkZSA9PiB0aGlzLm5hdmlnYXRlQWJzb2x1dGUoc2xpZGUsIG1vZGUpKTtcbiAgfVxuXG4gIG5hdmlnYXRlVG9QcmV2aW91c1RvYyhtb2RlPzogc3RyaW5nKSB7XG4gICAgdGhpcy5uZXh0VG9jKCdiYWNrd2FyZCcpXG4gICAgICAucGlwZSh0YWtlKDEpKVxuICAgICAgLnN1YnNjcmliZShzbGlkZSA9PiB0aGlzLm5hdmlnYXRlQWJzb2x1dGUoc2xpZGUsIG1vZGUpKTtcbiAgfVxuXG4gIG5leHRUb2MoZGlyZWN0aW9uOiAnZm9yd2FyZCcgfCAnYmFja3dhcmQnKTogT2JzZXJ2YWJsZTxTbGlkZSB8IHVuZGVmaW5lZD4ge1xuICAgIGNvbnN0IGN1cnJlbnRTbGlkZSQgPSB0aGlzLnNlbGVjdChzdGF0ZSA9PiBzdGF0ZS5jdXJyZW50U2xpZGUpXG4gICAgICAucGlwZShcbiAgICAgICAgc2tpcE5pbCgpLFxuICAgICAgKTtcblxuICAgIGNvbnN0IHRvY1NsaWRlcyQgPSB0aGlzLnNlbGVjdChzdGF0ZSA9PiBzdGF0ZS5zbGlkZXMpXG4gICAgICAucGlwZShcbiAgICAgICAgc2tpcE5pbCgpLFxuICAgICAgICBmaWx0ZXIoeCA9PiB4Lmxlbmd0aCAhPT0gMCksXG4gICAgICAgIG1hcCh0YWJsZU9mQ29udGVudFNsaWRlcyksXG4gICAgICApO1xuXG4gICAgcmV0dXJuIGNvbWJpbmVMYXRlc3QoY3VycmVudFNsaWRlJCwgdG9jU2xpZGVzJClcbiAgICAgIC5waXBlKFxuICAgICAgICBtYXAoKFtjdXJyZW50U2xpZGUsIHRvY1NsaWRlc10pID0+IHtcbiAgICAgICAgICBpZiAoZGlyZWN0aW9uID09PSAnZm9yd2FyZCcpIHtcbiAgICAgICAgICAgIHJldHVybiB0b2NTbGlkZXMuZmluZCh0b2NTbGlkZSA9PiB7XG4gICAgICAgICAgICAgIHJldHVybiBjb21wYXJlQ29vcmRpbmF0ZXModG9jU2xpZGUuY29vcmRpbmF0ZXMsIGN1cnJlbnRTbGlkZS5jb29yZGluYXRlcykgPT09IDE7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHRvY1NsaWRlcy5zbGljZSgpLnJldmVyc2UoKS5maW5kKHRvY1NsaWRlID0+IHtcbiAgICAgICAgICAgICAgcmV0dXJuIGNvbXBhcmVDb29yZGluYXRlcyh0b2NTbGlkZS5jb29yZGluYXRlcywgY3VycmVudFNsaWRlLmNvb3JkaW5hdGVzKSA9PT0gLTE7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pLFxuICAgICAgKTtcbiAgfVxuXG4gIG5hdmlnYXRlUmVsYXRpdmUobW92ZTogbnVtYmVyLCBjb29yZGluYXRlc1RvS2VlcDogbnVtYmVyIHwgdW5kZWZpbmVkKTogT2JzZXJ2YWJsZTxTbGlkZSB8IHVuZGVmaW5lZD4ge1xuICAgIGNvbnN0IGN1cnJlbnRTbGlkZSQgPSB0aGlzLnNlbGVjdChzdGF0ZSA9PiBzdGF0ZS5jdXJyZW50U2xpZGUpXG4gICAgICAucGlwZShcbiAgICAgICAgc2tpcE5pbCgpXG4gICAgICApO1xuXG4gICAgY29uc3Qgc2xpZGVzJCA9IHRoaXMuc2VsZWN0KHN0YXRlID0+IHN0YXRlLnNsaWRlcylcbiAgICAgIC5waXBlKFxuICAgICAgICBza2lwTmlsKCksXG4gICAgICAgIGZpbHRlcih4ID0+IHgubGVuZ3RoICE9PSAwKSxcbiAgICAgICk7XG5cbiAgICBjb25zdCBkZXB0aCQgPSB0aGlzLnNlbGVjdChzdGF0ZSA9PiBzdGF0ZS5jb29yZGluYXRlc01heERlcHRoKVxuICAgICAgLnBpcGUoXG4gICAgICAgIHNraXBOaWwoKVxuICAgICAgKTtcblxuICAgIHJldHVybiBjb21iaW5lTGF0ZXN0KHNsaWRlcyQsIGN1cnJlbnRTbGlkZSQsIGRlcHRoJClcbiAgICAgIC5waXBlKFxuICAgICAgICBtYXAoKFtzbGlkZXMsIGN1cnJlbnQsIGRlcHRoXSkgPT4gY2FsY3VsYXRlQ29vcmRpbmF0ZXMoc2xpZGVzLCBjdXJyZW50LCBtb3ZlLCBjb29yZGluYXRlc1RvS2VlcCwgZGVwdGgpKSxcbiAgICAgICk7XG4gIH1cblxuICBuYXZpZ2F0ZUFic29sdXRlKHRhcmdldDogQ29vcmRpbmF0ZXMgfCBTbGlkZSB8IHVuZGVmaW5lZCwgbW9kZT86IHN0cmluZykge1xuICAgIGxldCBzbGlkZTogU2xpZGUgfCB1bmRlZmluZWQ7XG5cbiAgICBpZiAodGFyZ2V0IGluc3RhbmNlb2YgU2xpZGUpIHtcbiAgICAgIHNsaWRlID0gdGFyZ2V0O1xuICAgIH0gZWxzZSB7XG4gICAgICBzbGlkZSA9IHRoaXMuc3RhdGUuc2xpZGVzLmZpbmQoeCA9PiBlcXVhbENvb3JkaW5hdGVzKHRhcmdldCwgeC5jb29yZGluYXRlcykpO1xuICAgIH1cblxuICAgIGlmIChzbGlkZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbGV0IG1vZGVXaXRoRmFsbGJhY2s6IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAgIGlmIChtb2RlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIG1vZGVXaXRoRmFsbGJhY2sgPSBtb2RlO1xuICAgIH0gZWxzZSBpZiAodGhpcy5zdGF0ZS5jdXJyZW50TW9kZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBtb2RlV2l0aEZhbGxiYWNrID0gdGhpcy5zdGF0ZS5jdXJyZW50TW9kZTtcbiAgICB9IGVsc2Uge1xuICAgICAgbW9kZVdpdGhGYWxsYmFjayA9ICdzbGlkZSc7XG4gICAgfVxuXG4gICAgY29uc3QgbGluayA9IFsgYC8ke21vZGVXaXRoRmFsbGJhY2t9YCwgLi4uc2xpZGUuY29vcmRpbmF0ZXMgXTtcblxuICAgIHJldHVybiB0aGlzLnJvdXRlci5uYXZpZ2F0ZShsaW5rLCB7IHF1ZXJ5UGFyYW1zSGFuZGxpbmc6ICdtZXJnZScgfSk7XG4gIH1cblxuICBuYXZpZ2F0ZVRvRmlyc3QocHJlZml4Pzogc3RyaW5nKSB7XG4gICAgdGhpcy5maXJzdFNsaWRlKClcbiAgICAgIC5waXBlKFxuICAgICAgICB0YWtlKDEpLFxuICAgICAgICB0YWtlVW50aWwodGhpcy5vbkRlc3Ryb3kkKSxcbiAgICAgIClcbiAgICAgIC5zdWJzY3JpYmUoc2xpZGUgPT4gdGhpcy5uYXZpZ2F0ZUFic29sdXRlKHNsaWRlLCBwcmVmaXgpKTtcbiAgfVxuXG4gIGZpcnN0U2xpZGUoKTogT2JzZXJ2YWJsZTxTbGlkZT4ge1xuICAgIHJldHVybiB0aGlzLnNlbGVjdChzdGF0ZSA9PiBzdGF0ZS5zbGlkZXMpXG4gICAgICAucGlwZShcbiAgICAgICAgc2tpcE5pbCgpLFxuICAgICAgICBmaWx0ZXIoc2xpZGVzID0+IHNsaWRlcy5sZW5ndGggPiAwKSxcbiAgICAgICAgbWFwKHNsaWRlcyA9PiBzbGlkZXNbMF0pXG4gICAgICApO1xuICB9XG5cbiAgaXNWYWxpZENvb3JkaW5hdGUoY29vcmRpbmF0ZXM6IENvb3JkaW5hdGVzKTogT2JzZXJ2YWJsZTxib29sZWFuPiB7XG4gICAgcmV0dXJuIHRoaXMucHJlc2VudGF0aW9uLnNlbGVjdChzdGF0ZSA9PiBzdGF0ZS5zbGlkZXMpXG4gICAgICAucGlwZShcbiAgICAgICAgc2tpcE5pbCgpLFxuICAgICAgICBmaWx0ZXIoc2xpZGVzID0+IHNsaWRlcy5sZW5ndGggPiAwKSxcbiAgICAgICAgbWFwKHNsaWRlcyA9PiBpc1ZhbGlkQ29vcmRpbmF0ZShzbGlkZXMsIGNvb3JkaW5hdGVzKSlcbiAgICAgICk7XG4gIH1cblxuICBwcml2YXRlIGNvb3JkaW5hdGVzVG9TbGlkZShjb29yZGluYXRlczogQ29vcmRpbmF0ZXMpOiBTbGlkZSB7XG4gICAgcmV0dXJuIHRoaXMuc3RhdGUuc2xpZGVNYXBbY29vcmRpbmF0ZXMuam9pbignLicpXTtcbiAgfVxuXG4gIHNldEN1cnJlbnRNb2RlQW5kU2xpZGUocm91dGU6IEFjdGl2YXRlZFJvdXRlU25hcHNob3QpIHtcbiAgICBjb25zdCBjb29yZGluYXRlcyA9IHJvdXRlUGFyYW1zVG9Db29yZGluYXRlKHJvdXRlLnBhcmFtcyk7XG4gICAgY29uc3QgbW9kZTogTW9kZSA9IHJvdXRlLnVybFswXS5wYXRoIGFzIE1vZGU7XG4gICAgY29uc3Qgc2xpZGUgPSB0aGlzLmNvb3JkaW5hdGVzVG9TbGlkZShjb29yZGluYXRlcyk7XG5cbiAgICB0aGlzLmNvbW1hbmRzLnNldEN1cnJlbnRTbGlkZShzbGlkZSk7XG4gICAgdGhpcy5jb21tYW5kcy5zZXRDdXJyZW50TW9kZShtb2RlKTtcbiAgfVxuXG4gIHByaXZhdGUgcmVhZG9ubHkgb25EZXN0cm95JCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5vbkRlc3Ryb3kkLm5leHQoKTtcbiAgfVxufVxuXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgTmF2aWdhdGVTZWN0aW9uRm9yd2FyZCBpbXBsZW1lbnRzIEtleWJvYXJkRXZlbnRQcm9jZXNzb3Ige1xuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlYWRvbmx5IHNlcnZpY2U6IFNsaWRlQnlTbGlkZVNlcnZpY2UpIHt9XG5cbiAgaW5pdChldmVudHMkOiBPYnNlcnZhYmxlPEtleWJvYXJkRXZlbnQ+KSB7XG4gICAgZXZlbnRzJFxuICAgICAgLnBpcGUoXG4gICAgICAgIGZpbHRlcihpc05vdEVkaXRhYmxlKSxcbiAgICAgICAgLy8gYXJyb3cgZG93biArIGFsdCB8fMKgYXJyb3cgcmlnaHQgKyBhbHRcbiAgICAgICAgZmlsdGVyKGV2ZW50ID0+IHtcbiAgICAgICAgICBpZiAoZXZlbnQua2V5Q29kZSA9PT0gNDAgJiYgZXZlbnQuYWx0S2V5KSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICB9IGVsc2UgaWYgKGV2ZW50LmtleUNvZGUgPT09IDM5ICYmIGV2ZW50LmFsdEtleSkge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9KSxcbiAgICAgIClcbiAgICAgIC5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICB0aGlzLnNlcnZpY2UubmF2aWdhdGVUb05leHRUb2MoKTtcbiAgICAgIH0pO1xuICB9XG59XG5cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBOYXZpZ2F0ZVNsaWRlRm9yd2FyZCBpbXBsZW1lbnRzIEtleWJvYXJkRXZlbnRQcm9jZXNzb3Ige1xuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlYWRvbmx5IHNlcnZpY2U6IFNsaWRlQnlTbGlkZVNlcnZpY2UpIHt9XG5cbiAgaW5pdChldmVudHMkOiBPYnNlcnZhYmxlPEtleWJvYXJkRXZlbnQ+KSB7XG4gICAgZXZlbnRzJFxuICAgICAgLnBpcGUoXG4gICAgICAgIGZpbHRlcihub25OYXZpZ2F0aW9uRXZlbnQpLFxuICAgICAgICAvLyBhcnJvdyBkb3duLCBhcnJvdyByaWdodCwgb3IgcGFnZSBkb3duXG4gICAgICAgIGZpbHRlcihldmVudCA9PiBldmVudC5rZXlDb2RlID09PSA0MCB8fCBldmVudC5rZXlDb2RlID09PSAzOSB8fCBldmVudC5rZXlDb2RlID09PSAzNClcbiAgICAgIClcbiAgICAgIC5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICB0aGlzLnNlcnZpY2UubmF2aWdhdGVUb05leHQoLTEpO1xuICAgICAgfSk7XG4gIH1cbn1cblxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIE5hdmlnYXRlU2VjdGlvbkJhY2t3YXJkIGltcGxlbWVudHMgS2V5Ym9hcmRFdmVudFByb2Nlc3NvciB7XG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVhZG9ubHkgc2VydmljZTogU2xpZGVCeVNsaWRlU2VydmljZSkge31cblxuICBpbml0KGV2ZW50cyQ6IE9ic2VydmFibGU8S2V5Ym9hcmRFdmVudD4pIHtcbiAgICBldmVudHMkXG4gICAgICAucGlwZShcbiAgICAgICAgZmlsdGVyKGlzTm90RWRpdGFibGUpLFxuICAgICAgICAvLyBhcnJvdyB1cCArIGFsdCB8fCBhcnJvdyBsZWZ0ICsgYWx0XG4gICAgICAgIGZpbHRlcihldmVudCA9PiB7XG4gICAgICAgICAgaWYgKGV2ZW50LmtleUNvZGUgPT09IDM4ICYmIGV2ZW50LmFsdEtleSkge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgfSBlbHNlIGlmIChldmVudC5rZXlDb2RlID09PSAzNyAmJiBldmVudC5hbHRLZXkpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfSksXG4gICAgICApXG4gICAgICAuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgdGhpcy5zZXJ2aWNlLm5hdmlnYXRlVG9QcmV2aW91c1RvYygpO1xuICAgICAgfSk7XG4gIH1cbn1cblxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIE5hdmlnYXRlU2xpZGVCYWNrd2FyZCBpbXBsZW1lbnRzIEtleWJvYXJkRXZlbnRQcm9jZXNzb3Ige1xuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlYWRvbmx5IHNlcnZpY2U6IFNsaWRlQnlTbGlkZVNlcnZpY2UpIHt9XG5cbiAgaW5pdChldmVudHMkOiBPYnNlcnZhYmxlPEtleWJvYXJkRXZlbnQ+KSB7XG4gICAgZXZlbnRzJFxuICAgICAgLnBpcGUoXG4gICAgICAgIGZpbHRlcihub25OYXZpZ2F0aW9uRXZlbnQpLFxuICAgICAgICAvLyBhcnJvdyB1cCwgYXJyb3cgbGVmdCBvciBwYWdlIHVwXG4gICAgICAgIGZpbHRlcihldmVudCA9PiBldmVudC5rZXlDb2RlID09PSAzOCB8fCBldmVudC5rZXlDb2RlID09PSAzNyB8fCBldmVudC5rZXlDb2RlID09PSAzMylcbiAgICAgIClcbiAgICAgIC5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICB0aGlzLnNlcnZpY2UubmF2aWdhdGVUb1ByZXZpb3VzKC0xKTtcbiAgICAgIH0pO1xuICB9XG59XG5cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBOYXZpZ2F0ZVRvRmlyc3RTbGlkZSBpbXBsZW1lbnRzIEtleWJvYXJkRXZlbnRQcm9jZXNzb3Ige1xuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlYWRvbmx5IHNlcnZpY2U6IFNsaWRlQnlTbGlkZVNlcnZpY2UpIHt9XG5cbiAgaW5pdChldmVudHMkOiBPYnNlcnZhYmxlPEtleWJvYXJkRXZlbnQ+KSB7XG4gICAgZXZlbnRzJFxuICAgICAgLnBpcGUoXG4gICAgICAgIGZpbHRlcihub25OYXZpZ2F0aW9uRXZlbnQpLFxuICAgICAgICAvLyBwb3MgMVxuICAgICAgICBmaWx0ZXIoZXZlbnQgPT4gZXZlbnQua2V5Q29kZSA9PT0gMzYpXG4gICAgICApXG4gICAgICAuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgdGhpcy5zZXJ2aWNlLm5hdmlnYXRlVG9GaXJzdCgpO1xuICAgICAgfSk7XG4gIH1cbn1cblxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIE5hdmlnYXRlVG9PdmVydmlldyBpbXBsZW1lbnRzIEtleWJvYXJkRXZlbnRQcm9jZXNzb3Ige1xuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlYWRvbmx5IHNlcnZpY2U6IFNsaWRlQnlTbGlkZVNlcnZpY2UsXG4gICAgICAgICAgICAgIHByaXZhdGUgcmVhZG9ubHkgcHJlc2VudGF0aW9uOiBQcmVzZW50YXRpb25TZXJ2aWNlKSB7fVxuXG4gIGluaXQoZXZlbnRzJDogT2JzZXJ2YWJsZTxLZXlib2FyZEV2ZW50Pikge1xuXG4gICAgY29uc3QgY29uZmlnJCA9IHRoaXMucHJlc2VudGF0aW9uLnNlbGVjdChzdGF0ZSA9PiBzdGF0ZS5jb25maWcubmF2aWdhdGlvbi5vdmVydmlldylcbiAgICAgIC5waXBlKFxuICAgICAgICBza2lwUHJvcGVydHlOaWwoJ2NvbXBvbmVudCcpXG4gICAgICApO1xuXG4gICAgY29uc3Qgc2xpZGUkID0gdGhpcy5zZXJ2aWNlLnNlbGVjdCgpXG4gICAgICAucGlwZShcbiAgICAgICAgd2l0aExhdGVzdEZyb20oY29uZmlnJCksXG4gICAgICAgIG1hcCgoW3N0YXRlLCBjb25maWddKSA9PiBzdGF0ZS5zbGlkZXMuZmluZChzbGlkZSA9PiBzbGlkZS5jb21wb25lbnQgPT09IGNvbmZpZy5jb21wb25lbnQpKVxuICAgICAgKTtcblxuICAgIGV2ZW50cyRcbiAgICAgIC5waXBlKFxuICAgICAgICBmaWx0ZXIobm9uTmF2aWdhdGlvbkV2ZW50KSxcbiAgICAgICAgLy8gcG9zIDFcbiAgICAgICAgZmlsdGVyKGV2ZW50ID0+IHtcbiAgICAgICAgICAvLyBvXG4gICAgICAgICAgcmV0dXJuIGV2ZW50LmtleUNvZGUgPT09IDc5O1xuICAgICAgICB9KSxcbiAgICAgICAgd2l0aExhdGVzdEZyb20oc2xpZGUkKVxuICAgICAgKVxuICAgICAgLnN1YnNjcmliZSgoW2V2ZW50LCBzbGlkZV0pID0+IHtcbiAgICAgICAgdGhpcy5zZXJ2aWNlLm5hdmlnYXRlQWJzb2x1dGUoc2xpZGUpO1xuICAgICAgfSk7XG4gIH1cbn1cblxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIFRvZ2dsZVByZXNlbnRlciBpbXBsZW1lbnRzIEtleWJvYXJkRXZlbnRQcm9jZXNzb3Ige1xuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlYWRvbmx5IHNlcnZpY2U6IFNsaWRlQnlTbGlkZVNlcnZpY2UsXG4gICAgICAgICAgICAgIHByaXZhdGUgcmVhZG9ubHkgcm91dGVyOiBSb3V0ZXIpIHt9XG5cbiAgaW5pdChldmVudHMkOiBPYnNlcnZhYmxlPEtleWJvYXJkRXZlbnQ+KSB7XG5cbiAgICBjb25zdCBzbGlkZSQgPSB0aGlzLnNlcnZpY2Uuc2VsZWN0KCk7XG5cbiAgICBldmVudHMkXG4gICAgICAucGlwZShcbiAgICAgICAgZmlsdGVyKGlzTm90RWRpdGFibGUpLFxuICAgICAgICAvLyBsZXR0ZXIgcFxuICAgICAgICBmaWx0ZXIoZXZlbnQgPT4gZXZlbnQua2V5Q29kZSA9PT0gODAgJiYgZXZlbnQuYWx0S2V5KSxcbiAgICAgICAgd2l0aExhdGVzdEZyb20oc2xpZGUkKVxuICAgICAgKVxuICAgICAgLnN1YnNjcmliZSgoW2V2ZW50LCBzdGF0ZV0pID0+IHtcbiAgICAgICAgbGV0IG1vZGU6IE1vZGU7XG5cbiAgICAgICAgaWYgKHN0YXRlLmN1cnJlbnRNb2RlID09PSAncHJlc2VudGVyJykge1xuICAgICAgICAgIG1vZGUgPSAnc2xpZGUnO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG1vZGUgPSAncHJlc2VudGVyJztcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBjb29yZGluYXRlczogQ29vcmRpbmF0ZXMgPSBbXTtcblxuICAgICAgICBpZiAoc3RhdGUuY3VycmVudFNsaWRlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBjb29yZGluYXRlcyA9IHN0YXRlLmN1cnJlbnRTbGlkZS5jb29yZGluYXRlcztcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGxpbmsgPSBbbW9kZSwgLi4uY29vcmRpbmF0ZXNdO1xuICAgICAgICB0aGlzLnJvdXRlci5uYXZpZ2F0ZShsaW5rLCB7IHF1ZXJ5UGFyYW1zSGFuZGxpbmc6ICdtZXJnZSd9KTtcbiAgICAgIH0pO1xuICB9XG59XG4iXX0=