import { ChangeDetectionStrategy, Component, ContentChildren, Directive, EventEmitter, Inject, Input, Output, PLATFORM_ID, ViewEncapsulation, } from '@angular/core';
import { isPlatformBrowser } from '@angular/common';
import { BehaviorSubject, combineLatest, NEVER, Subject, timer, zip } from 'rxjs';
import { distinctUntilChanged, map, startWith, switchMap, take, takeUntil } from 'rxjs/operators';
import { ngbCompleteTransition, ngbRunTransition } from '../util/transition/ngbTransition';
import { ngbCarouselTransitionIn, ngbCarouselTransitionOut, NgbSlideEventDirection, } from './carousel-transition';
import * as i0 from "@angular/core";
import * as i1 from "./carousel-config";
import * as i2 from "@angular/common";
let nextId = 0;
/**
* A directive that wraps the individual carousel slide.
*/
export class NgbSlide {
constructor(tplRef) {
this.tplRef = tplRef;
/**
* Slide id that must be unique for the entire document.
*
* If not provided, will be generated in the `ngb-slide-xx` format.
*/
this.id = `ngb-slide-${nextId++}`;
/**
* An event emitted when the slide transition is finished
*
* @since 8.0.0
*/
this.slid = new EventEmitter();
}
}
NgbSlide.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.6", ngImport: i0, type: NgbSlide, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive });
NgbSlide.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.2.6", type: NgbSlide, selector: "ng-template[ngbSlide]", inputs: { id: "id" }, outputs: { slid: "slid" }, ngImport: i0 });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.6", ngImport: i0, type: NgbSlide, decorators: [{
type: Directive,
args: [{ selector: 'ng-template[ngbSlide]' }]
}], ctorParameters: function () { return [{ type: i0.TemplateRef }]; }, propDecorators: { id: [{
type: Input
}], slid: [{
type: Output
}] } });
/**
* Carousel is a component to easily create and control slideshows.
*
* Allows to set intervals, change the way user interacts with the slides and provides a programmatic API.
*/
export class NgbCarousel {
constructor(config, _platformId, _ngZone, _cd, _container) {
this._platformId = _platformId;
this._ngZone = _ngZone;
this._cd = _cd;
this._container = _container;
this.NgbSlideEventSource = NgbSlideEventSource;
this._destroy$ = new Subject();
this._interval$ = new BehaviorSubject(0);
this._mouseHover$ = new BehaviorSubject(false);
this._focused$ = new BehaviorSubject(false);
this._pauseOnHover$ = new BehaviorSubject(false);
this._pauseOnFocus$ = new BehaviorSubject(false);
this._pause$ = new BehaviorSubject(false);
this._wrap$ = new BehaviorSubject(false);
/**
* An event emitted just before the slide transition starts.
*
* See [`NgbSlideEvent`](#/components/carousel/api#NgbSlideEvent) for payload details.
*/
this.slide = new EventEmitter();
/**
* An event emitted right after the slide transition is completed.
*
* See [`NgbSlideEvent`](#/components/carousel/api#NgbSlideEvent) for payload details.
*
* @since 8.0.0
*/
this.slid = new EventEmitter();
/*
* Keep the ids of the panels currently transitionning
* in order to allow only the transition revertion
*/
this._transitionIds = null;
this.animation = config.animation;
this.interval = config.interval;
this.wrap = config.wrap;
this.keyboard = config.keyboard;
this.pauseOnHover = config.pauseOnHover;
this.pauseOnFocus = config.pauseOnFocus;
this.showNavigationArrows = config.showNavigationArrows;
this.showNavigationIndicators = config.showNavigationIndicators;
}
/**
* Time in milliseconds before the next slide is shown.
*/
set interval(value) {
this._interval$.next(value);
}
get interval() {
return this._interval$.value;
}
/**
* If `true`, will 'wrap' the carousel by switching from the last slide back to the first.
*/
set wrap(value) {
this._wrap$.next(value);
}
get wrap() {
return this._wrap$.value;
}
/**
* If `true`, will pause slide switching when mouse cursor hovers the slide.
*
* @since 2.2.0
*/
set pauseOnHover(value) {
this._pauseOnHover$.next(value);
}
get pauseOnHover() {
return this._pauseOnHover$.value;
}
/**
* If `true`, will pause slide switching when the focus is inside the carousel.
*/
set pauseOnFocus(value) {
this._pauseOnFocus$.next(value);
}
get pauseOnFocus() {
return this._pauseOnFocus$.value;
}
set mouseHover(value) {
this._mouseHover$.next(value);
}
get mouseHover() {
return this._mouseHover$.value;
}
set focused(value) {
this._focused$.next(value);
}
get focused() {
return this._focused$.value;
}
arrowLeft() {
this.focus();
this.prev(NgbSlideEventSource.ARROW_LEFT);
}
arrowRight() {
this.focus();
this.next(NgbSlideEventSource.ARROW_RIGHT);
}
ngAfterContentInit() {
// setInterval() doesn't play well with SSR and protractor,
// so we should run it in the browser and outside Angular
if (isPlatformBrowser(this._platformId)) {
this._ngZone.runOutsideAngular(() => {
const hasNextSlide$ = combineLatest([
this.slide.pipe(map((slideEvent) => slideEvent.current), startWith(this.activeId)),
this._wrap$,
this.slides.changes.pipe(startWith(null)),
]).pipe(map(([currentSlideId, wrap]) => {
const slideArr = this.slides.toArray();
const currentSlideIdx = this._getSlideIdxById(currentSlideId);
return wrap ? slideArr.length > 1 : currentSlideIdx < slideArr.length - 1;
}), distinctUntilChanged());
combineLatest([
this._pause$,
this._pauseOnHover$,
this._mouseHover$,
this._pauseOnFocus$,
this._focused$,
this._interval$,
hasNextSlide$,
])
.pipe(map(([pause, pauseOnHover, mouseHover, pauseOnFocus, focused, interval, hasNextSlide]) => pause || (pauseOnHover && mouseHover) || (pauseOnFocus && focused) || !hasNextSlide ? 0 : interval), distinctUntilChanged(), switchMap((interval) => (interval > 0 ? timer(interval, interval) : NEVER)), takeUntil(this._destroy$))
.subscribe(() => this._ngZone.run(() => this.next(NgbSlideEventSource.TIMER)));
});
}
this.slides.changes.pipe(takeUntil(this._destroy$)).subscribe(() => {
this._transitionIds?.forEach((id) => ngbCompleteTransition(this._getSlideElement(id)));
this._transitionIds = null;
this._cd.markForCheck();
// The following code need to be done asynchronously, after the dom becomes stable,
// otherwise all changes will be undone.
this._ngZone.onStable.pipe(take(1)).subscribe(() => {
for (const { id } of this.slides) {
const element = this._getSlideElement(id);
if (id === this.activeId) {
element.classList.add('active');
}
else {
element.classList.remove('active');
}
}
});
});
}
ngAfterContentChecked() {
let activeSlide = this._getSlideById(this.activeId);
this.activeId = activeSlide ? activeSlide.id : this.slides.length ? this.slides.first.id : '';
}
ngAfterViewInit() {
// Initialize the 'active' class (not managed by the template)
if (this.activeId) {
const element = this._getSlideElement(this.activeId);
if (element) {
element.classList.add('active');
}
}
}
ngOnDestroy() {
this._destroy$.next();
}
/**
* Navigates to a slide with the specified identifier.
*/
select(slideId, source) {
this._cycleToSelected(slideId, this._getSlideEventDirection(this.activeId, slideId), source);
}
/**
* Navigates to the previous slide.
*/
prev(source) {
this._cycleToSelected(this._getPrevSlide(this.activeId), NgbSlideEventDirection.END, source);
}
/**
* Navigates to the next slide.
*/
next(source) {
this._cycleToSelected(this._getNextSlide(this.activeId), NgbSlideEventDirection.START, source);
}
/**
* Pauses cycling through the slides.
*/
pause() {
this._pause$.next(true);
}
/**
* Restarts cycling through the slides from start to end.
*/
cycle() {
this._pause$.next(false);
}
/**
* Set the focus on the carousel.
*/
focus() {
this._container.nativeElement.focus();
}
_cycleToSelected(slideIdx, direction, source) {
const transitionIds = this._transitionIds;
if (transitionIds && (transitionIds[0] !== slideIdx || transitionIds[1] !== this.activeId)) {
// Revert prevented
return;
}
let selectedSlide = this._getSlideById(slideIdx);
if (selectedSlide && selectedSlide.id !== this.activeId) {
this._transitionIds = [this.activeId, slideIdx];
this.slide.emit({
prev: this.activeId,
current: selectedSlide.id,
direction: direction,
paused: this._pause$.value,
source,
});
const options = {
animation: this.animation,
runningTransition: 'stop',
context: { direction },
};
const transitions = [];
const activeSlide = this._getSlideById(this.activeId);
if (activeSlide) {
const activeSlideTransition = ngbRunTransition(this._ngZone, this._getSlideElement(activeSlide.id), ngbCarouselTransitionOut, options);
activeSlideTransition.subscribe(() => {
activeSlide.slid.emit({ isShown: false, direction, source });
});
transitions.push(activeSlideTransition);
}
const previousId = this.activeId;
this.activeId = selectedSlide.id;
const nextSlide = this._getSlideById(this.activeId);
const transition = ngbRunTransition(this._ngZone, this._getSlideElement(selectedSlide.id), ngbCarouselTransitionIn, options);
transition.subscribe(() => {
nextSlide?.slid.emit({ isShown: true, direction, source });
});
transitions.push(transition);
zip(...transitions)
.pipe(take(1))
.subscribe(() => {
this._transitionIds = null;
this.slid.emit({
prev: previousId,
current: selectedSlide.id,
direction: direction,
paused: this._pause$.value,
source,
});
});
}
// we get here after the interval fires or any external API call like next(), prev() or select()
this._cd.markForCheck();
}
_getSlideEventDirection(currentActiveSlideId, nextActiveSlideId) {
const currentActiveSlideIdx = this._getSlideIdxById(currentActiveSlideId);
const nextActiveSlideIdx = this._getSlideIdxById(nextActiveSlideId);
return currentActiveSlideIdx > nextActiveSlideIdx ? NgbSlideEventDirection.END : NgbSlideEventDirection.START;
}
_getSlideById(slideId) {
return this.slides.find((slide) => slide.id === slideId) || null;
}
_getSlideIdxById(slideId) {
const slide = this._getSlideById(slideId);
return slide != null ? this.slides.toArray().indexOf(slide) : -1;
}
_getNextSlide(currentSlideId) {
const slideArr = this.slides.toArray();
const currentSlideIdx = this._getSlideIdxById(currentSlideId);
const isLastSlide = currentSlideIdx === slideArr.length - 1;
return isLastSlide
? this.wrap
? slideArr[0].id
: slideArr[slideArr.length - 1].id
: slideArr[currentSlideIdx + 1].id;
}
_getPrevSlide(currentSlideId) {
const slideArr = this.slides.toArray();
const currentSlideIdx = this._getSlideIdxById(currentSlideId);
const isFirstSlide = currentSlideIdx === 0;
return isFirstSlide
? this.wrap
? slideArr[slideArr.length - 1].id
: slideArr[0].id
: slideArr[currentSlideIdx - 1].id;
}
_getSlideElement(slideId) {
return this._container.nativeElement.querySelector(`#slide-${slideId}`);
}
}
NgbCarousel.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.6", ngImport: i0, type: NgbCarousel, deps: [{ token: i1.NgbCarouselConfig }, { token: PLATFORM_ID }, { token: i0.NgZone }, { token: i0.ChangeDetectorRef }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
NgbCarousel.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.6", type: NgbCarousel, selector: "ngb-carousel", inputs: { animation: "animation", activeId: "activeId", interval: "interval", wrap: "wrap", keyboard: "keyboard", pauseOnHover: "pauseOnHover", pauseOnFocus: "pauseOnFocus", showNavigationArrows: "showNavigationArrows", showNavigationIndicators: "showNavigationIndicators" }, outputs: { slide: "slide", slid: "slid" }, host: { attributes: { "tabIndex": "0" }, listeners: { "keydown.arrowLeft": "keyboard && arrowLeft()", "keydown.arrowRight": "keyboard && arrowRight()", "mouseenter": "mouseHover = true", "mouseleave": "mouseHover = false", "focusin": "focused = true", "focusout": "focused = false" }, properties: { "style.display": "\"block\"", "attr.aria-activedescendant": "'slide-' + activeId" }, classAttribute: "carousel slide" }, queries: [{ propertyName: "slides", predicate: NgbSlide }], exportAs: ["ngbCarousel"], ngImport: i0, template: `
Slide {{ i + 1 }} of {{ c }}
`, isInline: true, dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.6", ngImport: i0, type: NgbCarousel, decorators: [{
type: Component,
args: [{
selector: 'ngb-carousel',
exportAs: 'ngbCarousel',
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
host: {
class: 'carousel slide',
'[style.display]': '"block"',
tabIndex: '0',
'(keydown.arrowLeft)': 'keyboard && arrowLeft()',
'(keydown.arrowRight)': 'keyboard && arrowRight()',
'(mouseenter)': 'mouseHover = true',
'(mouseleave)': 'mouseHover = false',
'(focusin)': 'focused = true',
'(focusout)': 'focused = false',
'[attr.aria-activedescendant]': `'slide-' + activeId`,
},
template: `
Slide {{ i + 1 }} of {{ c }}
`,
}]
}], ctorParameters: function () { return [{ type: i1.NgbCarouselConfig }, { type: undefined, decorators: [{
type: Inject,
args: [PLATFORM_ID]
}] }, { type: i0.NgZone }, { type: i0.ChangeDetectorRef }, { type: i0.ElementRef }]; }, propDecorators: { slides: [{
type: ContentChildren,
args: [NgbSlide]
}], animation: [{
type: Input
}], activeId: [{
type: Input
}], interval: [{
type: Input
}], wrap: [{
type: Input
}], keyboard: [{
type: Input
}], pauseOnHover: [{
type: Input
}], pauseOnFocus: [{
type: Input
}], showNavigationArrows: [{
type: Input
}], showNavigationIndicators: [{
type: Input
}], slide: [{
type: Output
}], slid: [{
type: Output
}] } });
export var NgbSlideEventSource;
(function (NgbSlideEventSource) {
NgbSlideEventSource["TIMER"] = "timer";
NgbSlideEventSource["ARROW_LEFT"] = "arrowLeft";
NgbSlideEventSource["ARROW_RIGHT"] = "arrowRight";
NgbSlideEventSource["INDICATOR"] = "indicator";
})(NgbSlideEventSource || (NgbSlideEventSource = {}));
export const NGB_CAROUSEL_DIRECTIVES = [NgbCarousel, NgbSlide];
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2Fyb3VzZWwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY2Fyb3VzZWwvY2Fyb3VzZWwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUdOLHVCQUF1QixFQUV2QixTQUFTLEVBQ1QsZUFBZSxFQUNmLFNBQVMsRUFFVCxZQUFZLEVBQ1osTUFBTSxFQUNOLEtBQUssRUFHTCxNQUFNLEVBQ04sV0FBVyxFQUdYLGlCQUFpQixHQUVqQixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUlwRCxPQUFPLEVBQUUsZUFBZSxFQUFFLGFBQWEsRUFBRSxLQUFLLEVBQWMsT0FBTyxFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDOUYsT0FBTyxFQUFFLG9CQUFvQixFQUFFLEdBQUcsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUNsRyxPQUFPLEVBQUUscUJBQXFCLEVBQUUsZ0JBQWdCLEVBQXdCLE1BQU0sa0NBQWtDLENBQUM7QUFDakgsT0FBTyxFQUNOLHVCQUF1QixFQUN2Qix3QkFBd0IsRUFDeEIsc0JBQXNCLEdBRXRCLE1BQU0sdUJBQXVCLENBQUM7Ozs7QUFFL0IsSUFBSSxNQUFNLEdBQUcsQ0FBQyxDQUFDO0FBRWY7O0dBRUc7QUFFSCxNQUFNLE9BQU8sUUFBUTtJQWVwQixZQUFtQixNQUF3QjtRQUF4QixXQUFNLEdBQU4sTUFBTSxDQUFrQjtRQWQzQzs7OztXQUlHO1FBQ00sT0FBRSxHQUFHLGFBQWEsTUFBTSxFQUFFLEVBQUUsQ0FBQztRQUV0Qzs7OztXQUlHO1FBQ08sU0FBSSxHQUFHLElBQUksWUFBWSxFQUF1QixDQUFDO0lBRVgsQ0FBQzs7cUdBZm5DLFFBQVE7eUZBQVIsUUFBUTsyRkFBUixRQUFRO2tCQURwQixTQUFTO21CQUFDLEVB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LEVBQUUsbUJBQW1CO3dCQUNuQyxjQUFjLEVBQUUsb0JBQW9CO3dCQUNwQyxXQUFXLEVBQUUsZ0JBQWdCO3dCQUM3QixZQUFZLEVBQUUsaUJBQWlCO3dCQUMvQiw4QkFBOEIsRUFBRSxxQkFBcUI7cUJBQ3JEO29CQUNELFFBQVEsRUFBRTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7RUFzQ1Q7aUJBQ0Q7OzBCQTBJRSxNQUFNOzJCQUFDLFdBQVc7MEhBeElPLE1BQU07c0JBQWhDLGVBQWU7dUJBQUMsUUFBUTtnQkFrQmhCLFNBQVM7c0JBQWpCLEtBQUs7Z0JBT0csUUFBUTtzQkFBaEIsS0FBSztnQkFNRixRQUFRO3NCQURYLEtBQUs7Z0JBYUYsSUFBSTtzQkFEUCxLQUFLO2dCQVlHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBUUYsWUFBWTtzQkFEZixLQUFLO2dCQWFGLFlBQVk7c0JBRGYsS0FBSztnQkFjRyxvQkFBb0I7c0JBQTVCLEtBQUs7Z0JBT0csd0JBQXdCO3NCQUFoQyxLQUFLO2dCQU9JLEtBQUs7c0JBQWQsTUFBTTtnQkFTRyxJQUFJO3NCQUFiLE1BQU07O0FBaVhSLE1BQU0sQ0FBTixJQUFZLG1CQUtYO0FBTEQsV0FBWSxtQkFBbUI7SUFDOUIsc0NBQWUsQ0FBQTtJQUNmLCtDQUF3QixDQUFBO0lBQ3hCLGlEQUEwQixDQUFBO0lBQzFCLDhDQUF1QixDQUFBO0FBQ3hCLENBQUMsRUFMVyxtQkFBbUIsS0FBbkIsbUJBQW1CLFFBSzlCO0FBRUQsTUFBTSxDQUFDLE1BQU0sdUJBQXVCLEdBQUcsQ0FBQyxXQUFXLEVBQUUsUUFBUSxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuXHRBZnRlckNvbnRlbnRDaGVja2VkLFxuXHRBZnRlckNvbnRlbnRJbml0LFxuXHRDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcblx0Q2hhbmdlRGV0ZWN0b3JSZWYsXG5cdENvbXBvbmVudCxcblx0Q29udGVudENoaWxkcmVuLFxuXHREaXJlY3RpdmUsXG5cdEVsZW1lbnRSZWYsXG5cdEV2ZW50RW1pdHRlcixcblx0SW5qZWN0LFxuXHRJbnB1dCxcblx0Tmdab25lLFxuXHRPbkRlc3Ryb3ksXG5cdE91dHB1dCxcblx0UExBVEZPUk1fSUQsXG5cdFF1ZXJ5TGlzdCxcblx0VGVtcGxhdGVSZWYsXG5cdFZpZXdFbmNhcHN1bGF0aW9uLFxuXHRBZnRlclZpZXdJbml0LFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IGlzUGxhdGZvcm1Ccm93c2VyIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcblxuaW1wb3J0IHsgTmdiQ2Fyb3VzZWxDb25maWcgfSBmcm9tICcuL2Nhcm91c2VsLWNvbmZpZyc7XG5cbmltcG9ydCB7IEJlaGF2aW9yU3ViamVjdCwgY29tYmluZUxhdGVzdCwgTkVWRVIsIE9ic2VydmFibGUsIFN1YmplY3QsIHRpbWVyLCB6aXAgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IGRpc3RpbmN0VW50aWxDaGFuZ2VkLCBtYXAsIHN0YXJ0V2l0aCwgc3dpdGNoTWFwLCB0YWtlLCB0YWtlVW50aWwgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBuZ2JDb21wbGV0ZVRyYW5zaXRpb24sIG5nYlJ1blRyYW5zaXRpb24sIE5nYlRyYW5zaXRpb25PcHRpb25zIH0gZnJvbSAnLi4vdXRpbC90cmFuc2l0aW9uL25nYlRyYW5zaXRpb24nO1xuaW1wb3J0IHtcblx0bmdiQ2Fyb3VzZWxUcmFuc2l0aW9uSW4sXG5cdG5nYkNhcm91c2VsVHJhbnNpdGlvbk91dCxcblx0TmdiU2xpZGVFdmVudERpcmVjdGlvbixcblx0TmdiQ2Fyb3VzZWxDdHgsXG59IGZyb20gJy4vY2Fyb3VzZWwtdHJhbnNpdGlvbic7XG5cbmxldCBuZXh0SWQgPSAwO1xuXG4vKipcbiAqIEEgZGlyZWN0aXZlIHRoYXQgd3JhcHMgdGhlIGluZGl2aWR1YWwgY2Fyb3VzZWwgc2xpZGUuXG4gKi9cbkBEaXJlY3RpdmUoeyBzZWxlY3RvcjogJ25nLXRlbXBsYXRlW25nYlNsaWRlXScgfSlcbmV4cG9ydCBjbGFzcyBOZ2JTbGlkZSB7XG5cdC8qKlxuXHQgKiBTbGlkZSBpZCB0aGF0IG11c3QgYmUgdW5pcXVlIGZvciB0aGUgZW50aXJlIGRvY3VtZW50LlxuXHQgKlxuXHQgKiBJZiBub3QgcHJvdmlkZWQsIHdpbGwgYmUgZ2VuZXJhdGVkIGluIHRoZSBgbmdiLXNsaWRlLXh4YCBmb3JtYXQuXG5cdCAqL1xuXHRASW5wdXQoKSBpZCA9IGBuZ2Itc2xpZGUtJHtuZXh0SWQrK31gO1xuXG5cdC8qKlxuXHQgKiBBbiBldmVudCBlbWl0dGVkIHdoZW4gdGhlIHNsaWRlIHRyYW5zaXRpb24gaXMgZmluaXNoZWRcblx0ICpcblx0ICogQHNpbmNlIDguMC4wXG5cdCAqL1xuXHRAT3V0cHV0KCkgc2xpZCA9IG5ldyBFdmVudEVtaXR0ZXI8TmdiU2luZ2xlU2xpZGVFdmVudD4oKTtcblxuXHRjb25zdHJ1Y3RvcihwdWJsaWMgdHBsUmVmOiBUZW1wbGF0ZVJlZjxhbnk+KSB7fVxufVxuXG4vKipcbiAqIENhcm91c2VsIGlzIGEgY29tcG9uZW50IHRvIGVhc2lseSBjcmVhdGUgYW5kIGNvbnRyb2wgc2xpZGVzaG93cy5cbiAqXG4gKiBBbGxvd3MgdG8gc2V0IGludGVydmFscywgY2hhbmdlIHRoZSB3YXkgdXNlciBpbnRlcmFjdHMgd2l0aCB0aGUgc2xpZGVzIGFuZCBwcm92aWRlcyBhIHByb2dyYW1tYXRpYyBBUEkuXG4gKi9cbkBDb21wb25lbnQoe1xuXHRzZWxlY3RvcjogJ25nYi1jYXJvdXNlbCcsXG5cdGV4cG9ydEFzOiAnbmdiQ2Fyb3VzZWwnLFxuXHRjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcblx0ZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcblx0aG9zdDoge1xuXHRcdGNsYXNzOiAnY2Fyb3VzZWwgc2xpZGUnLFxuXHRcdCdbc3R5bGUuZGlzcGxheV0nOiAnXCJibG9ja1wiJyxcblx0XHR0YWJJbmRleDogJzAnLFxuXHRcdCcoa2V5ZG93bi5hcnJvd0xlZnQpJzogJ2tleWJvYXJkICYmIGFycm93TGVmdCgpJyxcblx0XHQnKGtleWRvd24uYXJyb3dSaWdodCknOiAna2V5Ym9hcmQgJiYgYXJyb3dSaWdodCgpJyxcblx0XHQnKG1vdXNlZW50ZXIpJzogJ21vdXNlSG92ZXIgPSB0cnVlJyxcblx0XHQnKG1vdXNlbGVhdmUpJzogJ21vdXNlSG92ZXIgPSBmYWxzZScsXG5cdFx0Jyhmb2N1c2luKSc6ICdmb2N1c2VkID0gdHJ1ZScsXG5cdFx0Jyhmb2N1c291dCknOiAnZm9jdXNlZCA9IGZhbHNlJyxcblx0XHQnW2F0dHIuYXJpYS1hY3RpdmVkZXNjZW5kYW50XSc6IGAnc2xpZGUtJyArIGFjdGl2ZUlkYCxcblx0fSxcblx0dGVtcGxhdGU6IGBcblx0XHQ8ZGl2IGNsYXNzPVwiY2Fyb3VzZWwtaW5kaWNhdG9yc1wiIFtjbGFzcy52aXN1YWxseS1oaWRkZW5dPVwiIXNob3dOYXZpZ2F0aW9uSW5kaWNhdG9yc1wiIHJvbGU9XCJ0YWJsaXN0XCI+XG5cdFx0XHQ8YnV0dG9uXG5cdFx0XHRcdHR5cGU9XCJidXR0b25cIlxuXHRcdFx0XHRkYXRhLWJzLXRhcmdldFxuXHRcdFx0XHQqbmdGb3I9XCJsZXQgc2xpZGUgb2Ygc2xpZGVzXCJcblx0XHRcdFx0W2NsYXNzLmFjdGl2ZV09XCJzbGlkZS5pZCA9PT0gYWN0aXZlSWRcIlxuXHRcdFx0XHRyb2xlPVwidGFiXCJcblx0XHRcdFx0W2F0dHIuYXJpYS1sYWJlbGxlZGJ5XT1cIidzbGlkZS0nICsgc2xpZGUuaWRcIlxuXHRcdFx0XHRbYXR0ci5hcmlhLWNvbnRyb2xzXT1cIidzbGlkZS0nICsgc2xpZGUuaWRcIlxuXHRcdFx0XHRbYXR0ci5hcmlhLXNlbGVjdGVkXT1cInNsaWRlLmlkID09PSBhY3RpdmVJZFwiXG5cdFx0XHRcdChjbGljayk9XCJmb2N1cygpOyBzZWxlY3Qoc2xpZGUuaWQsIE5nYlNsaWRlRXZlbnRTb3VyY2UuSU5ESUNBVE9SKVwiXG5cdFx0XHQ+PC9idXR0b24+XG5cdFx0PC9kaXY+XG5cdFx0PGRpdiBjbGFzcz1cImNhcm91c2VsLWlubmVyXCI+XG5cdFx0XHQ8ZGl2XG5cdFx0XHRcdCpuZ0Zvcj1cImxldCBzbGlkZSBvZiBzbGlkZXM7IGluZGV4IGFzIGk7IGNvdW50IGFzIGNcIlxuXHRcdFx0XHRjbGFzcz1cImNhcm91c2VsLWl0ZW1cIlxuXHRcdFx0XHRbaWRdPVwiJ3NsaWRlLScgKyBzbGlkZS5pZFwiXG5cdFx0XHRcdHJvbGU9XCJ0YWJwYW5lbFwiXG5cdFx0XHQ+XG5cdFx0XHRcdDxzcGFuXG5cdFx0XHRcdFx0Y2xhc3M9XCJ2aXN1YWxseS1oaWRkZW5cIlxuXHRcdFx0XHRcdGkxOG49XCJDdXJyZW50bHkgc2VsZWN0ZWQgc2xpZGUgbnVtYmVyIHJlYWQgYnkgc2NyZWVuIHJlYWRlckBAbmdiLmNhcm91c2VsLnNsaWRlLW51bWJlclwiXG5cdFx0XHRcdD5cblx0XHRcdFx0XHRTbGlkZSB7eyBpICsgMSB9fSBvZiB7eyBjIH19XG5cdFx0XHRcdDwvc3Bhbj5cblx0XHRcdFx0PG5nLXRlbXBsYXRlIFtuZ1RlbXBsYXRlT3V0bGV0XT1cInNsaWRlLnRwbFJlZlwiPjwvbmctdGVtcGxhdGU+XG5cdFx0XHQ8L2Rpdj5cblx0XHQ8L2Rpdj5cblx0XHQ8YnV0dG9uIGNsYXNzPVwiY2Fyb3VzZWwtY29udHJvbC1wcmV2XCIgdHlwZT1cImJ1dHRvblwiIChjbGljayk9XCJhcnJvd0xlZnQoKVwiICpuZ0lmPVwic2hvd05hdmlnYXRpb25BcnJvd3NcIj5cblx0XHRcdDxzcGFuIGNsYXNzPVwiY2Fyb3VzZWwtY29udHJvbC1wcmV2LWljb25cIiBhcmlhLWhpZGRlbj1cInRydWVcIj48L3NwYW4+XG5cdFx0XHQ8c3BhbiBjbGFzcz1cInZpc3VhbGx5LWhpZGRlblwiIGkxOG49XCJAQG5nYi5jYXJvdXNlbC5wcmV2aW91c1wiPlByZXZpb3VzPC9zcGFuPlxuXHRcdDwvYnV0dG9uPlxuXHRcdDxidXR0b24gY2xhc3M9XCJjYXJvdXNlbC1jb250cm9sLW5leHRcIiB0eXBlPVwiYnV0dG9uXCIgKGNsaWNrKT1cImFycm93UmlnaHQoKVwiICpuZ0lmPVwic2hvd05hdmlnYXRpb25BcnJvd3NcIj5cblx0XHRcdDxzcGFuIGNsYXNzPVwiY2Fyb3VzZWwtY29udHJvbC1uZXh0LWljb25cIiBhcmlhLWhpZGRlbj1cInRydWVcIj48L3NwYW4+XG5cdFx0XHQ8c3BhbiBjbGFzcz1cInZpc3VhbGx5LWhpZGRlblwiIGkxOG49XCJAQG5nYi5jYXJvdXNlbC5uZXh0XCI+TmV4dDwvc3Bhbj5cblx0XHQ8L2J1dHRvbj5cblx0YCxcbn0pXG5leHBvcnQgY2xhc3MgTmdiQ2Fyb3VzZWwgaW1wbGVtZW50cyBBZnRlckNvbnRlbnRDaGVja2VkLCBBZnRlckNvbnRlbnRJbml0LCBBZnRlclZpZXdJbml0LCBPbkRlc3Ryb3kge1xuXHRAQ29udGVudENoaWxkcmVuKE5nYlNsaWRlKSBzbGlkZXM6IFF1ZXJ5TGlzdDxOZ2JTbGlkZT47XG5cblx0cHVibGljIE5nYlNsaWRlRXZlbnRTb3VyY2UgPSBOZ2JTbGlkZUV2ZW50U291cmNlO1xuXG5cdHByaXZhdGUgX2Rlc3Ryb3kkID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcblx0cHJpdmF0ZSBfaW50ZXJ2YWwkID0gbmV3IEJlaGF2aW9yU3ViamVjdCgwKTtcblx0cHJpdmF0ZSBfbW91c2VIb3ZlciQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0KGZhbHNlKTtcblx0cHJpdmF0ZSBfZm9jdXNlZCQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0KGZhbHNlKTtcblx0cHJpdmF0ZSBfcGF1c2VPbkhvdmVyJCA9IG5ldyBCZWhhdmlvclN1YmplY3QoZmFsc2UpO1xuXHRwcml2YXRlIF9wYXVzZU9uRm9jdXMkID0gbmV3IEJlaGF2aW9yU3ViamVjdChmYWxzZSk7XG5cdHByaXZhdGUgX3BhdXNlJCA9IG5ldyBCZWhhdmlvclN1YmplY3QoZmFsc2UpO1xuXHRwcml2YXRlIF93cmFwJCA9IG5ldyBCZWhhdmlvclN1YmplY3QoZmFsc2UpO1xuXG5cdC8qKlxuXHQgKiBBIGZsYWcgdG8gZW5hYmxlL2Rpc2FibGUgdGhlIGFuaW1hdGlvbnMuXG5cdCAqXG5cdCAqIEBzaW5jZSA4LjAuMFxuXHQgKi9cblx0QElucHV0KCkgYW5pbWF0aW9uOiBib29sZWFuO1xuXG5cdC8qKlxuXHQgKiBUaGUgc2xpZGUgaWQgdGhhdCBzaG91bGQgYmUgZGlzcGxheWVkICoqaW5pdGlhbGx5KiouXG5cdCAqXG5cdCAqIEZvciBzdWJzZXF1ZW50IGludGVyYWN0aW9ucyB1c2UgbWV0aG9kcyBgc2VsZWN0KClgLCBgbmV4dCgpYCwgZXRjLiBhbmQgdGhlIGAoc2xpZGUpYCBvdXRwdXQuXG5cdCAqL1xuXHRASW5wdXQoKSBhY3RpdmVJZDogc3RyaW5nO1xuXG5cdC8qKlxuXHQgKiBUaW1lIGluIG1pbGxpc2Vjb25kcyBiZWZvcmUgdGhlIG5leHQgc2xpZGUgaXMgc2hvd24uXG5cdCAqL1xuXHRASW5wdXQoKVxuXHRzZXQgaW50ZXJ2YWwodmFsdWU6IG51bWJlcikge1xuXHRcdHRoaXMuX2ludGVydmFsJC5uZXh0KHZhbHVlKTtcblx0fVxuXG5cdGdldCBpbnRlcnZhbCgpIHtcblx0XHRyZXR1cm4gdGhpcy5faW50ZXJ2YWwkLnZhbHVlO1xuXHR9XG5cblx0LyoqXG5cdCAqIElmIGB0cnVlYCwgd2lsbCAnd3JhcCcgdGhlIGNhcm91c2VsIGJ5IHN3aXRjaGluZyBmcm9tIHRoZSBsYXN0IHNsaWRlIGJhY2sgdG8gdGhlIGZpcnN0LlxuXHQgKi9cblx0QElucHV0KClcblx0c2V0IHdyYXAodmFsdWU6IGJvb2xlYW4pIHtcblx0XHR0aGlzLl93cmFwJC5uZXh0KHZhbHVlKTtcblx0fVxuXG5cdGdldCB3cmFwKCkge1xuXHRcdHJldHVybiB0aGlzLl93cmFwJC52YWx1ZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBJZiBgdHJ1ZWAsIGFsbG93cyB0byBpbnRlcmFjdCB3aXRoIGNhcm91c2VsIHVzaW5nIGtleWJvYXJkICdhcnJvdyBsZWZ0JyBhbmQgJ2Fycm93IHJpZ2h0Jy5cblx0ICovXG5cdEBJbnB1dCgpIGtleWJvYXJkOiBib29sZWFuO1xuXG5cdC8qKlxuXHQgKiBJZiBgdHJ1ZWAsIHdpbGwgcGF1c2Ugc2xpZGUgc3dpdGNoaW5nIHdoZW4gbW91c2UgY3Vyc29yIGhvdmVycyB0aGUgc2xpZGUuXG5cdCAqXG5cdCAqIEBzaW5jZSAyLjIuMFxuXHQgKi9cblx0QElucHV0KClcblx0c2V0IHBhdXNlT25Ib3Zlcih2YWx1ZTogYm9vbGVhbikge1xuXHRcdHRoaXMuX3BhdXNlT25Ib3ZlciQubmV4dCh2YWx1ZSk7XG5cdH1cblxuXHRnZXQgcGF1c2VPbkhvdmVyKCkge1xuXHRcdHJldHVybiB0aGlzLl9wYXVzZU9uSG92ZXIkLnZhbHVlO1xuXHR9XG5cblx0LyoqXG5cdCAqIElmIGB0cnVlYCwgd2lsbCBwYXVzZSBzbGlkZSBzd2l0Y2hpbmcgd2hlbiB0aGUgZm9jdXMgaXMgaW5zaWRlIHRoZSBjYXJvdXNlbC5cblx0ICovXG5cdEBJbnB1dCgpXG5cdHNldCBwYXVzZU9uRm9jdXModmFsdWU6IGJvb2xlYW4pIHtcblx0XHR0aGlzLl9wYXVzZU9uRm9jdXMkLm5leHQodmFsdWUpO1xuXHR9XG5cblx0Z2V0IHBhdXNlT25Gb2N1cygpIHtcblx0XHRyZXR1cm4gdGhpcy5fcGF1c2VPbkZvY3VzJC52YWx1ZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBJZiBgdHJ1ZWAsICdwcmV2aW91cycgYW5kICduZXh0JyBuYXZpZ2F0aW9uIGFycm93cyB3aWxsIGJlIHZpc2libGUgb24gdGhlIHNsaWRlLlxuXHQgKlxuXHQgKiBAc2luY2UgMi4yLjBcblx0ICovXG5cdEBJbnB1dCgpIHNob3dOYXZpZ2F0aW9uQXJyb3dzOiBib29sZWFuO1xuXG5cdC8qKlxuXHQgKiBJZiBgdHJ1ZWAsIG5hdmlnYXRpb24gaW5kaWNhdG9ycyBhdCB0aGUgYm90dG9tIG9mIHRoZSBzbGlkZSB3aWxsIGJlIHZpc2libGUuXG5cdCAqXG5cdCAqIEBzaW5jZSAyLjIuMFxuXHQgKi9cblx0QElucHV0KCkgc2hvd05hdmlnYXRpb25JbmRpY2F0b3JzOiBib29sZWFuO1xuXG5cdC8qKlxuXHQgKiBBbiBldmVudCBlbWl0dGVkIGp1c3QgYmVmb3JlIHRoZSBzbGlkZSB0cmFuc2l0aW9uIHN0YXJ0cy5cblx0ICpcblx0ICogU2VlIFtgTmdiU2xpZGVFdmVudGBdKCMvY29tcG9uZW50cy9jYXJvdXNlbC9hcGkjTmdiU2xpZGVFdmVudCkgZm9yIHBheWxvYWQgZGV0YWlscy5cblx0ICovXG5cdEBPdXRwdXQoKSBzbGlkZSA9IG5ldyBFdmVudEVtaXR0ZXI8TmdiU2xpZGVFdmVudD4oKTtcblxuXHQvKipcblx0ICogQW4gZXZlbnQgZW1pdHRlZCByaWdodCBhZnRlciB0aGUgc2xpZGUgdHJhbnNpdGlvbiBpcyBjb21wbGV0ZWQuXG5cdCAqXG5cdCAqIFNlZSBbYE5nYlNsaWRlRXZlbnRgXSgjL2NvbXBvbmVudHMvY2Fyb3VzZWwvYXBpI05nYlNsaWRlRXZlbnQpIGZvciBwYXlsb2FkIGRldGFpbHMuXG5cdCAqXG5cdCAqIEBzaW5jZSA4LjAuMFxuXHQgKi9cblx0QE91dHB1dCgpIHNsaWQgPSBuZXcgRXZlbnRFbWl0dGVyPE5nYlNsaWRlRXZlbnQ+KCk7XG5cblx0Lypcblx0ICogS2VlcCB0aGUgaWRzIG9mIHRoZSBwYW5lbHMgY3VycmVudGx5IHRyYW5zaXRpb25uaW5nXG5cdCAqIGluIG9yZGVyIHRvIGFsbG93IG9ubHkgdGhlIHRyYW5zaXRpb24gcmV2ZXJ0aW9uXG5cdCAqL1xuXHRwcml2YXRlIF90cmFuc2l0aW9uSWRzOiBbc3RyaW5nLCBzdHJpbmddIHwgbnVsbCA9IG51bGw7XG5cblx0c2V0IG1vdXNlSG92ZXIodmFsdWU6IGJvb2xlYW4pIHtcblx0XHR0aGlzLl9tb3VzZUhvdmVyJC5uZXh0KHZhbHVlKTtcblx0fVxuXG5cdGdldCBtb3VzZUhvdmVyKCkge1xuXHRcdHJldHVybiB0aGlzLl9tb3VzZUhvdmVyJC52YWx1ZTtcblx0fVxuXG5cdHNldCBmb2N1c2VkKHZhbHVlOiBib29sZWFuKSB7XG5cdFx0dGhpcy5fZm9jdXNlZCQubmV4dCh2YWx1ZSk7XG5cdH1cblxuXHRnZXQgZm9jdXNlZCgpIHtcblx0XHRyZXR1cm4gdGhpcy5fZm9jdXNlZCQudmFsdWU7XG5cdH1cblxuXHRjb25zdHJ1Y3Rvcihcblx0XHRjb25maWc6IE5nYkNhcm91c2VsQ29uZmlnLFxuXHRcdEBJbmplY3QoUExBVEZPUk1fSUQpIHByaXZhdGUgX3BsYXRmb3JtSWQsXG5cdFx0cHJpdmF0ZSBfbmdab25lOiBOZ1pvbmUsXG5cdFx0cHJpdmF0ZSBfY2Q6IENoYW5nZURldGVjdG9yUmVmLFxuXHRcdHByaXZhdGUgX2NvbnRhaW5lcjogRWxlbWVudFJlZixcblx0KSB7XG5cdFx0dGhpcy5hbmltYXRpb24gPSBjb25maWcuYW5pbWF0aW9uO1xuXHRcdHRoaXMuaW50ZXJ2YWwgPSBjb25maWcuaW50ZXJ2YWw7XG5cdFx0dGhpcy53cmFwID0gY29uZmlnLndyYXA7XG5cdFx0dGhpcy5rZXlib2FyZCA9IGNvbmZpZy5rZXlib2FyZDtcblx0XHR0aGlzLnBhdXNlT25Ib3ZlciA9IGNvbmZpZy5wYXVzZU9uSG92ZXI7XG5cdFx0dGhpcy5wYXVzZU9uRm9jdXMgPSBjb25maWcucGF1c2VPbkZvY3VzO1xuXHRcdHRoaXMuc2hvd05hdmlnYXRpb25BcnJvd3MgPSBjb25maWcuc2hvd05hdmlnYXRpb25BcnJvd3M7XG5cdFx0dGhpcy5zaG93TmF2aWdhdGlvbkluZGljYXRvcnMgPSBjb25maWcuc2hvd05hdmlnYXRpb25JbmRpY2F0b3JzO1xuXHR9XG5cblx0YXJyb3dMZWZ0KCkge1xuXHRcdHRoaXMuZm9jdXMoKTtcblx0XHR0aGlzLnByZXYoTmdiU2xpZGVFdmVudFNvdXJjZS5BUlJPV19MRUZUKTtcblx0fVxuXG5cdGFycm93UmlnaHQoKSB7XG5cdFx0dGhpcy5mb2N1cygpO1xuXHRcdHRoaXMubmV4dChOZ2JTbGlkZUV2ZW50U291cmNlLkFSUk9XX1JJR0hUKTtcblx0fVxuXG5cdG5nQWZ0ZXJDb250ZW50SW5pdCgpIHtcblx0XHQvLyBzZXRJbnRlcnZhbCgpIGRvZXNuJ3QgcGxheSB3ZWxsIHdpdGggU1NSIGFuZCBwcm90cmFjdG9yLFxuXHRcdC8vIHNvIHdlIHNob3VsZCBydW4gaXQgaW4gdGhlIGJyb3dzZXIgYW5kIG91dHNpZGUgQW5ndWxhclxuXHRcdGlmIChpc1BsYXRmb3JtQnJvd3Nlcih0aGlzLl9wbGF0Zm9ybUlkKSkge1xuXHRcdFx0dGhpcy5fbmdab25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcblx0XHRcdFx0Y29uc3QgaGFzTmV4dFNsaWRlJCA9IGNvbWJpbmVMYXRlc3QoW1xuXHRcdFx0XHRcdHRoaXMuc2xpZGUucGlwZShcblx0XHRcdFx0XHRcdG1hcCgoc2xpZGVFdmVudCkgPT4gc2xpZGVFdmVudC5jdXJyZW50KSxcblx0XHRcdFx0XHRcdHN0YXJ0V2l0aCh0aGlzLmFjdGl2ZUlkKSxcblx0XHRcdFx0XHQpLFxuXHRcdFx0XHRcdHRoaXMuX3dyYXAkLFxuXHRcdFx0XHRcdHRoaXMuc2xpZGVzLmNoYW5nZXMucGlwZShzdGFydFdpdGgobnVsbCkpLFxuXHRcdFx0XHRdKS5waXBlKFxuXHRcdFx0XHRcdG1hcCgoW2N1cnJlbnRTbGlkZUlkLCB3cmFwXSkgPT4ge1xuXHRcdFx0XHRcdFx0Y29uc3Qgc2xpZGVBcnIgPSB0aGlzLnNsaWRlcy50b0FycmF5KCk7XG5cdFx0XHRcdFx0XHRjb25zdCBjdXJyZW50U2xpZGVJZHggPSB0aGlzLl9nZXRTbGlkZUlkeEJ5SWQoY3VycmVudFNsaWRlSWQpO1xuXHRcdFx0XHRcdFx0cmV0dXJuIHdyYXAgPyBzbGlkZUFyci5sZW5ndGggPiAxIDogY3VycmVudFNsaWRlSWR4IDwgc2xpZGVBcnIubGVuZ3RoIC0gMTtcblx0XHRcdFx0XHR9KSxcblx0XHRcdFx0XHRkaXN0aW5jdFVudGlsQ2hhbmdlZCgpLFxuXHRcdFx0XHQpO1xuXHRcdFx0XHRjb21iaW5lTGF0ZXN0KFtcblx0XHRcdFx0XHR0aGlzLl9wYXVzZSQsXG5cdFx0XHRcdFx0dGhpcy5fcGF1c2VPbkhvdmVyJCxcblx0XHRcdFx0XHR0aGlzLl9tb3VzZUhvdmVyJCxcblx0XHRcdFx0XHR0aGlzLl9wYXVzZU9uRm9jdXMkLFxuXHRcdFx0XHRcdHRoaXMuX2ZvY3VzZWQkLFxuXHRcdFx0XHRcdHRoaXMuX2ludGVydmFsJCxcblx0XHRcdFx0XHRoYXNOZXh0U2xpZGUkLFxuXHRcdFx0XHRdKVxuXHRcdFx0XHRcdC5waXBlKFxuXHRcdFx0XHRcdFx0bWFwKFxuXHRcdFx0XHRcdFx0XHQoW3BhdXNlLCBwYXVzZU9uSG92ZXIsIG1vdXNlSG92ZXIsIHBhdXNlT25Gb2N1cywgZm9jdXNlZCwgaW50ZXJ2YWwsIGhhc05leHRTbGlkZV06IFtcblx0XHRcdFx0XHRcdFx0XHRib29sZWFuLFxuXHRcdFx0XHRcdFx0XHRcdGJvb2xlYW4sXG5cdFx0XHRcdFx0XHRcdFx0Ym9vbGVhbixcblx0XHRcdFx0XHRcdFx0XHRib29sZWFuLFxuXHRcdFx0XHRcdFx0XHRcdGJvb2xlYW4sXG5cdFx0XHRcdFx0XHRcdFx0bnVtYmVyLFxuXHRcdFx0XHRcdFx0XHRcdGJvb2xlYW4sXG5cdFx0XHRcdFx0XHRcdF0pID0+XG5cdFx0XHRcdFx0XHRcdFx0cGF1c2UgfHwgKHBhdXNlT25Ib3ZlciAmJiBtb3VzZUhvdmVyKSB8fCAocGF1c2VPbkZvY3VzICYmIGZvY3VzZWQpIHx8ICFoYXNOZXh0U2xpZGUgPyAwIDogaW50ZXJ2YWwsXG5cdFx0XHRcdFx0XHQpLFxuXG5cdFx0XHRcdFx0XHRkaXN0aW5jdFVudGlsQ2hhbmdlZCgpLFxuXHRcdFx0XHRcdFx0c3dpdGNoTWFwKChpbnRlcnZhbCkgPT4gKGludGVydmFsID4gMCA/IHRpbWVyKGludGVydmFsLCBpbnRlcnZhbCkgOiBORVZFUikpLFxuXHRcdFx0XHRcdFx0dGFrZVVudGlsKHRoaXMuX2Rlc3Ryb3kkKSxcblx0XHRcdFx0XHQpXG5cdFx0XHRcdFx0LnN1YnNjcmliZSgoKSA9PiB0aGlzLl9uZ1pvbmUucnVuKCgpID0+IHRoaXMubmV4dChOZ2JTbGlkZUV2ZW50U291cmNlLlRJTUVSKSkpO1xuXHRcdFx0fSk7XG5cdFx0fVxuXG5cdFx0dGhpcy5zbGlkZXMuY2hhbmdlcy5waXBlKHRha2VVbnRpbCh0aGlzLl9kZXN0cm95JCkpLnN1YnNjcmliZSgoKSA9PiB7XG5cdFx0XHR0aGlzLl90cmFuc2l0aW9uSWRzPy5mb3JFYWNoKChpZCkgPT4gbmdiQ29tcGxldGVUcmFuc2l0aW9uKHRoaXMuX2dldFNsaWRlRWxlbWVudChpZCkpKTtcblx0XHRcdHRoaXMuX3RyYW5zaXRpb25JZHMgPSBudWxsO1xuXG5cdFx0XHR0aGlzLl9jZC5tYXJrRm9yQ2hlY2soKTtcblxuXHRcdFx0Ly8gVGhlIGZvbGxvd2luZyBjb2RlIG5lZWQgdG8gYmUgZG9uZSBhc3luY2hyb25vdXNseSwgYWZ0ZXIgdGhlIGRvbSBiZWNvbWVzIHN0YWJsZSxcblx0XHRcdC8vIG90aGVyd2lzZSBhbGwgY2hhbmdlcyB3aWxsIGJlIHVuZG9uZS5cblx0XHRcdHRoaXMuX25nWm9uZS5vblN0YWJsZS5waXBlKHRha2UoMSkpLnN1YnNjcmliZSgoKSA9PiB7XG5cdFx0XHRcdGZvciAoY29uc3QgeyBpZCB9IG9mIHRoaXMuc2xpZGVzKSB7XG5cdFx0XHRcdFx0Y29uc3QgZWxlbWVudCA9IHRoaXMuX2dldFNsaWRlRWxlbWVudChpZCk7XG5cdFx0XHRcdFx0aWYgKGlkID09PSB0aGlzLmFjdGl2ZUlkKSB7XG5cdFx0XHRcdFx0XHRlbGVtZW50LmNsYXNzTGlzdC5hZGQoJ2FjdGl2ZScpO1xuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRlbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoJ2FjdGl2ZScpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cdFx0fSk7XG5cdH1cblxuXHRuZ0FmdGVyQ29udGVudENoZWNrZWQoKSB7XG5cdFx0bGV0IGFjdGl2ZVNsaWRlID0gdGhpcy5fZ2V0U2xpZGVCeUlkKHRoaXMuYWN0aXZlSWQpO1xuXHRcdHRoaXMuYWN0aXZlSWQgPSBhY3RpdmVTbGlkZSA/IGFjdGl2ZVNsaWRlLmlkIDogdGhpcy5zbGlkZXMubGVuZ3RoID8gdGhpcy5zbGlkZXMuZmlyc3QuaWQgOiAnJztcblx0fVxuXG5cdG5nQWZ0ZXJWaWV3SW5pdCgpIHtcblx0XHQvLyBJbml0aWFsaXplIHRoZSAnYWN0aXZlJyBjbGFzcyAobm90IG1hbmFnZWQgYnkgdGhlIHRlbXBsYXRlKVxuXHRcdGlmICh0aGlzLmFjdGl2ZUlkKSB7XG5cdFx0XHRjb25zdCBlbGVtZW50ID0gdGhpcy5fZ2V0U2xpZGVFbGVtZW50KHRoaXMuYWN0aXZlSWQpO1xuXHRcdFx0aWYgKGVsZW1lbnQpIHtcblx0XHRcdFx0ZWxlbWVudC5jbGFzc0xpc3QuYWRkKCdhY3RpdmUnKTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHRuZ09uRGVzdHJveSgpIHtcblx0XHR0aGlzLl9kZXN0cm95JC5uZXh0KCk7XG5cdH1cblxuXHQvKipcblx0ICogTmF2aWdhdGVzIHRvIGEgc2xpZGUgd2l0aCB0aGUgc3BlY2lmaWVkIGlkZW50aWZpZXIuXG5cdCAqL1xuXHRzZWxlY3Qoc2xpZGVJZDogc3RyaW5nLCBzb3VyY2U/OiBOZ2JTbGlkZUV2ZW50U291cmNlKSB7XG5cdFx0dGhpcy5fY3ljbGVUb1NlbGVjdGVkKHNsaWRlSWQsIHRoaXMuX2dldFNsaWRlRXZlbnREaXJlY3Rpb24odGhpcy5hY3RpdmVJZCwgc2xpZGVJZCksIHNvdXJjZSk7XG5cdH1cblxuXHQvKipcblx0ICogTmF2aWdhdGVzIHRvIHRoZSBwcmV2aW91cyBzbGlkZS5cblx0ICovXG5cdHByZXYoc291cmNlPzogTmdiU2xpZGVFdmVudFNvdXJjZSkge1xuXHRcdHRoaXMuX2N5Y2xlVG9TZWxlY3RlZCh0aGlzLl9nZXRQcmV2U2xpZGUodGhpcy5hY3RpdmVJZCksIE5nYlNsaWRlRXZlbnREaXJlY3Rpb24uRU5ELCBzb3VyY2UpO1xuXHR9XG5cblx0LyoqXG5cdCAqIE5hdmlnYXRlcyB0byB0aGUgbmV4dCBzbGlkZS5cblx0ICovXG5cdG5leHQoc291cmNlPzogTmdiU2xpZGVFdmVudFNvdXJjZSkge1xuXHRcdHRoaXMuX2N5Y2xlVG9TZWxlY3RlZCh0aGlzLl9nZXROZXh0U2xpZGUodGhpcy5hY3RpdmVJZCksIE5nYlNsaWRlRXZlbnREaXJlY3Rpb24uU1RBUlQsIHNvdXJjZSk7XG5cdH1cblxuXHQvKipcblx0ICogUGF1c2VzIGN5Y2xpbmcgdGhyb3VnaCB0aGUgc2xpZGVzLlxuXHQgKi9cblx0cGF1c2UoKSB7XG5cdFx0dGhpcy5fcGF1c2UkLm5leHQodHJ1ZSk7XG5cdH1cblxuXHQvKipcblx0ICogUmVzdGFydHMgY3ljbGluZyB0aHJvdWdoIHRoZSBzbGlkZXMgZnJvbSBzdGFydCB0byBlbmQuXG5cdCAqL1xuXHRjeWNsZSgpIHtcblx0XHR0aGlzLl9wYXVzZSQubmV4dChmYWxzZSk7XG5cdH1cblxuXHQvKipcblx0ICogU2V0IHRoZSBmb2N1cyBvbiB0aGUgY2Fyb3VzZWwuXG5cdCAqL1xuXHRmb2N1cygpIHtcblx0XHR0aGlzLl9jb250YWluZXIubmF0aXZlRWxlbWVudC5mb2N1cygpO1xuXHR9XG5cblx0cHJpdmF0ZSBfY3ljbGVUb1NlbGVjdGVkKHNsaWRlSWR4OiBzdHJpbmcsIGRpcmVjdGlvbjogTmdiU2xpZGVFdmVudERpcmVjdGlvbiwgc291cmNlPzogTmdiU2xpZGVFdmVudFNvdXJjZSkge1xuXHRcdGNvbnN0IHRyYW5zaXRpb25JZHMgPSB0aGlzLl90cmFuc2l0aW9uSWRzO1xuXHRcdGlmICh0cmFuc2l0aW9uSWRzICYmICh0cmFuc2l0aW9uSWRzWzBdICE9PSBzbGlkZUlkeCB8fCB0cmFuc2l0aW9uSWRzWzFdICE9PSB0aGlzLmFjdGl2ZUlkKSkge1xuXHRcdFx0Ly8gUmV2ZXJ0IHByZXZlbnRlZFxuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdGxldCBzZWxlY3RlZFNsaWRlID0gdGhpcy5fZ2V0U2xpZGVCeUlkKHNsaWRlSWR4KTtcblx0XHRpZiAoc2VsZWN0ZWRTbGlkZSAmJiBzZWxlY3RlZFNsaWRlLmlkICE9PSB0aGlzLmFjdGl2ZUlkKSB7XG5cdFx0XHR0aGlzLl90cmFuc2l0aW9uSWRzID0gW3RoaXMuYWN0aXZlSWQsIHNsaWRlSWR4XTtcblx0XHRcdHRoaXMuc2xpZGUuZW1pdCh7XG5cdFx0XHRcdHByZXY6IHRoaXMuYWN0aXZlSWQsXG5cdFx0XHRcdGN1cnJlbnQ6IHNlbGVjdGVkU2xpZGUuaWQsXG5cdFx0XHRcdGRpcmVjdGlvbjogZGlyZWN0aW9uLFxuXHRcdFx0XHRwYXVzZWQ6IHRoaXMuX3BhdXNlJC52YWx1ZSxcblx0XHRcdFx0c291cmNlLFxuXHRcdFx0fSk7XG5cblx0XHRcdGNvbnN0IG9wdGlvbnM6IE5nYlRyYW5zaXRpb25PcHRpb25zPE5nYkNhcm91c2VsQ3R4PiA9IHtcblx0XHRcdFx0YW5pbWF0aW9uOiB0aGlzLmFuaW1hdGlvbixcblx0XHRcdFx0cnVubmluZ1RyYW5zaXRpb246ICdzdG9wJyxcblx0XHRcdFx0Y29udGV4dDogeyBkaXJlY3Rpb24gfSxcblx0XHRcdH07XG5cblx0XHRcdGNvbnN0IHRyYW5zaXRpb25zOiBBcnJheTxPYnNlcnZhYmxlPGFueT4+ID0gW107XG5cdFx0XHRjb25zdCBhY3RpdmVTbGlkZSA9IHRoaXMuX2dldFNsaWRlQnlJZCh0aGlzLmFjdGl2ZUlkKTtcblx0XHRcdGlmIChhY3RpdmVTbGlkZSkge1xuXHRcdFx0XHRjb25zdCBhY3RpdmVTbGlkZVRyYW5zaXRpb24gPSBuZ2JSdW5UcmFuc2l0aW9uKFxuXHRcdFx0XHRcdHRoaXMuX25nWm9uZSxcblx0XHRcdFx0XHR0aGlzLl9nZXRTbGlkZUVsZW1lbnQoYWN0aXZlU2xpZGUuaWQpLFxuXHRcdFx0XHRcdG5nYkNhcm91c2VsVHJhbnNpdGlvbk91dCxcblx0XHRcdFx0XHRvcHRpb25zLFxuXHRcdFx0XHQpO1xuXHRcdFx0XHRhY3RpdmVTbGlkZVRyYW5zaXRpb24uc3Vic2NyaWJlKCgpID0+IHtcblx0XHRcdFx0XHRhY3RpdmVTbGlkZS5zbGlkLmVtaXQoeyBpc1Nob3duOiBmYWxzZSwgZGlyZWN0aW9uLCBzb3VyY2UgfSk7XG5cdFx0XHRcdH0pO1xuXHRcdFx0XHR0cmFuc2l0aW9ucy5wdXNoKGFjdGl2ZVNsaWRlVHJhbnNpdGlvbik7XG5cdFx0XHR9XG5cblx0XHRcdGNvbnN0IHByZXZpb3VzSWQgPSB0aGlzLmFjdGl2ZUlkO1xuXHRcdFx0dGhpcy5hY3RpdmVJZCA9IHNlbGVjdGVkU2xpZGUuaWQ7XG5cdFx0XHRjb25zdCBuZXh0U2xpZGUgPSB0aGlzLl9nZXRTbGlkZUJ5SWQodGhpcy5hY3RpdmVJZCk7XG5cdFx0XHRjb25zdCB0cmFuc2l0aW9uID0gbmdiUnVuVHJhbnNpdGlvbihcblx0XHRcdFx0dGhpcy5fbmdab25lLFxuXHRcdFx0XHR0aGlzLl9nZXRTbGlkZUVsZW1lbnQoc2VsZWN0ZWRTbGlkZS5pZCksXG5cdFx0XHRcdG5nYkNhcm91c2VsVHJhbnNpdGlvbkluLFxuXHRcdFx0XHRvcHRpb25zLFxuXHRcdFx0KTtcblx0XHRcdHRyYW5zaXRpb24uc3Vic2NyaWJlKCgpID0+IHtcblx0XHRcdFx0bmV4dFNsaWRlPy5zbGlkLmVtaXQoeyBpc1Nob3duOiB0cnVlLCBkaXJlY3Rpb24sIHNvdXJjZSB9KTtcblx0XHRcdH0pO1xuXHRcdFx0dHJhbnNpdGlvbnMucHVzaCh0cmFuc2l0aW9uKTtcblxuXHRcdFx0emlwKC4uLnRyYW5zaXRpb25zKVxuXHRcdFx0XHQucGlwZSh0YWtlKDEpKVxuXHRcdFx0XHQuc3Vic2NyaWJlKCgpID0+IHtcblx0XHRcdFx0XHR0aGlzLl90cmFuc2l0aW9uSWRzID0gbnVsbDtcblx0XHRcdFx0XHR0aGlzLnNsaWQuZW1pdCh7XG5cdFx0XHRcdFx0XHRwcmV2OiBwcmV2aW91c0lkLFxuXHRcdFx0XHRcdFx0Y3VycmVudDogc2VsZWN0ZWRTbGlkZSEuaWQsXG5cdFx0XHRcdFx0XHRkaXJlY3Rpb246IGRpcmVjdGlvbixcblx0XHRcdFx0XHRcdHBhdXNlZDogdGhpcy5fcGF1c2UkLnZhbHVlLFxuXHRcdFx0XHRcdFx0c291cmNlLFxuXHRcdFx0XHRcdH0pO1xuXHRcdFx0XHR9KTtcblx0XHR9XG5cblx0XHQvLyB3ZSBnZXQgaGVyZSBhZnRlciB0aGUgaW50ZXJ2YWwgZmlyZXMgb3IgYW55IGV4dGVybmFsIEFQSSBjYWxsIGxpa2UgbmV4dCgpLCBwcmV2KCkgb3Igc2VsZWN0KClcblx0XHR0aGlzLl9jZC5tYXJrRm9yQ2hlY2soKTtcblx0fVxuXG5cdHByaXZhdGUgX2dldFNsaWRlRXZlbnREaXJlY3Rpb24oY3VycmVudEFjdGl2ZVNsaWRlSWQ6IHN0cmluZywgbmV4dEFjdGl2ZVNsaWRlSWQ6IHN0cmluZyk6IE5nYlNsaWRlRXZlbnREaXJlY3Rpb24ge1xuXHRcdGNvbnN0IGN1cnJlbnRBY3RpdmVTbGlkZUlkeCA9IHRoaXMuX2dldFNsaWRlSWR4QnlJZChjdXJyZW50QWN0aXZlU2xpZGVJZCk7XG5cdFx0Y29uc3QgbmV4dEFjdGl2ZVNsaWRlSWR4ID0gdGhpcy5fZ2V0U2xpZGVJZHhCeUlkKG5leHRBY3RpdmVTbGlkZUlkKTtcblxuXHRcdHJldHVybiBjdXJyZW50QWN0aXZlU2xpZGVJZHggPiBuZXh0QWN0aXZlU2xpZGVJZHggPyBOZ2JTbGlkZUV2ZW50RGlyZWN0aW9uLkVORCA6IE5nYlNsaWRlRXZlbnREaXJlY3Rpb24uU1RBUlQ7XG5cdH1cblxuXHRwcml2YXRlIF9nZXRTbGlkZUJ5SWQoc2xpZGVJZDogc3RyaW5nKTogTmdiU2xpZGUgfCBudWxsIHtcblx0XHRyZXR1cm4gdGhpcy5zbGlkZXMuZmluZCgoc2xpZGUpID0+IHNsaWRlLmlkID09PSBzbGlkZUlkKSB8fCBudWxsO1xuXHR9XG5cblx0cHJpdmF0ZSBfZ2V0U2xpZGVJZHhCeUlkKHNsaWRlSWQ6IHN0cmluZyk6IG51bWJlciB7XG5cdFx0Y29uc3Qgc2xpZGUgPSB0aGlzLl9nZXRTbGlkZUJ5SWQoc2xpZGVJZCk7XG5cdFx0cmV0dXJuIHNsaWRlICE9IG51bGwgPyB0aGlzLnNsaWRlcy50b0FycmF5KCkuaW5kZXhPZihzbGlkZSkgOiAtMTtcblx0fVxuXG5cdHByaXZhdGUgX2dldE5leHRTbGlkZShjdXJyZW50U2xpZGVJZDogc3RyaW5nKTogc3RyaW5nIHtcblx0XHRjb25zdCBzbGlkZUFyciA9IHRoaXMuc2xpZGVzLnRvQXJyYXkoKTtcblx0XHRjb25zdCBjdXJyZW50U2xpZGVJZHggPSB0aGlzLl9nZXRTbGlkZUlkeEJ5SWQoY3VycmVudFNsaWRlSWQpO1xuXHRcdGNvbnN0IGlzTGFzdFNsaWRlID0gY3VycmVudFNsaWRlSWR4ID09PSBzbGlkZUFyci5sZW5ndGggLSAxO1xuXG5cdFx0cmV0dXJuIGlzTGFzdFNsaWRlXG5cdFx0XHQ/IHRoaXMud3JhcFxuXHRcdFx0XHQ/IHNsaWRlQXJyWzBdLmlkXG5cdFx0XHRcdDogc2xpZGVBcnJbc2xpZGVBcnIubGVuZ3RoIC0gMV0uaWRcblx0XHRcdDogc2xpZGVBcnJbY3VycmVudFNsaWRlSWR4ICsgMV0uaWQ7XG5cdH1cblxuXHRwcml2YXRlIF9nZXRQcmV2U2xpZGUoY3VycmVudFNsaWRlSWQ6IHN0cmluZyk6IHN0cmluZyB7XG5cdFx0Y29uc3Qgc2xpZGVBcnIgPSB0aGlzLnNsaWRlcy50b0FycmF5KCk7XG5cdFx0Y29uc3QgY3VycmVudFNsaWRlSWR4ID0gdGhpcy5fZ2V0U2xpZGVJZHhCeUlkKGN1cnJlbnRTbGlkZUlkKTtcblx0XHRjb25zdCBpc0ZpcnN0U2xpZGUgPSBjdXJyZW50U2xpZGVJZHggPT09IDA7XG5cblx0XHRyZXR1cm4gaXNGaXJzdFNsaWRlXG5cdFx0XHQ/IHRoaXMud3JhcFxuXHRcdFx0XHQ/IHNsaWRlQXJyW3NsaWRlQXJyLmxlbmd0aCAtIDFdLmlkXG5cdFx0XHRcdDogc2xpZGVBcnJbMF0uaWRcblx0XHRcdDogc2xpZGVBcnJbY3VycmVudFNsaWRlSWR4IC0gMV0uaWQ7XG5cdH1cblxuXHRwcml2YXRlIF9nZXRTbGlkZUVsZW1lbnQoc2xpZGVJZDogc3RyaW5nKTogSFRNTEVsZW1lbnQge1xuXHRcdHJldHVybiB0aGlzLl9jb250YWluZXIubmF0aXZlRWxlbWVudC5xdWVyeVNlbGVjdG9yKGAjc2xpZGUtJHtzbGlkZUlkfWApO1xuXHR9XG59XG5cbi8qKlxuICogQSBzbGlkZSBjaGFuZ2UgZXZlbnQgZW1pdHRlZCByaWdodCBhZnRlciB0aGUgc2xpZGUgdHJhbnNpdGlvbiBpcyBjb21wbGV0ZWQuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTmdiU2xpZGVFdmVudCB7XG5cdC8qKlxuXHQgKiBUaGUgcHJldmlvdXMgc2xpZGUgaWQuXG5cdCAqL1xuXHRwcmV2OiBzdHJpbmc7XG5cblx0LyoqXG5cdCAqIFRoZSBjdXJyZW50IHNsaWRlIGlkLlxuXHQgKi9cblx0Y3VycmVudDogc3RyaW5nO1xuXG5cdC8qKlxuXHQgKiBUaGUgc2xpZGUgZXZlbnQgZGlyZWN0aW9uLlxuXHQgKlxuXHQgKiA8c3BhbiBjbGFzcz1cImJhZGdlIGJnLWluZm8gdGV4dC1kYXJrXCI+c2luY2UgMTIuMC4wPC9zcGFuPiBQb3NzaWJsZSB2YWx1ZXMgYXJlIGAnc3RhcnQnIHwgJ2VuZCdgLlxuXHQgKlxuXHQgKiA8c3BhbiBjbGFzcz1cImJhZGdlIGJnLXNlY29uZGFyeVwiPmJlZm9yZSAxMi4wLjA8L3NwYW4+IFBvc3NpYmxlIHZhbHVlcyB3ZXJlIGAnbGVmdCcgfCAncmlnaHQnYC5cblx0ICovXG5cdGRpcmVjdGlvbjogTmdiU2xpZGVFdmVudERpcmVjdGlvbjtcblxuXHQvKipcblx0ICogV2hldGhlciB0aGUgcGF1c2UoKSBtZXRob2Qgd2FzIGNhbGxlZCAoYW5kIG5vIGN5Y2xlKCkgY2FsbCB3YXMgZG9uZSBhZnRlcndhcmRzKS5cblx0ICpcblx0ICogQHNpbmNlIDUuMS4wXG5cdCAqL1xuXHRwYXVzZWQ6IGJvb2xlYW47XG5cblx0LyoqXG5cdCAqIFNvdXJjZSB0cmlnZ2VyaW5nIHRoZSBzbGlkZSBjaGFuZ2UgZXZlbnQuXG5cdCAqXG5cdCAqIFBvc3NpYmxlIHZhbHVlcyBhcmUgYCd0aW1lcicgfCAnYXJyb3dMZWZ0JyB8ICdhcnJvd1JpZ2h0JyB8ICdpbmRpY2F0b3InYFxuXHQgKlxuXHQgKiBAc2luY2UgNS4xLjBcblx0ICovXG5cdHNvdXJjZT86IE5nYlNsaWRlRXZlbnRTb3VyY2U7XG59XG5cbi8qKlxuICogQSBzbGlkZSBjaGFuZ2UgZXZlbnQgZW1pdHRlZCByaWdodCBhZnRlciB0aGUgc2xpZGUgdHJhbnNpdGlvbiBpcyBjb21wbGV0ZWQuXG4gKlxuICogQHNpbmNlIDguMC4wXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTmdiU2luZ2xlU2xpZGVFdmVudCB7XG5cdC8qKlxuXHQgKiB0cnVlIGlmIHRoZSBzbGlkZSBpcyBzaG93biwgZmFsc2Ugb3RoZXJ3aXNlXG5cdCAqL1xuXHRpc1Nob3duOiBib29sZWFuO1xuXG5cdC8qKlxuXHQgKiBUaGUgc2xpZGUgZXZlbnQgZGlyZWN0aW9uLlxuXHQgKlxuXHQgKiA8c3BhbiBjbGFzcz1cImJhZGdlIGJnLWluZm8gdGV4dC1kYXJrXCI+c2luY2UgMTIuMC4wPC9zcGFuPiBQb3NzaWJsZSB2YWx1ZXMgYXJlIGAnc3RhcnQnIHwgJ2VuZCdgLlxuXHQgKlxuXHQgKiA8c3BhbiBjbGFzcz1cImJhZGdlIGJnLXNlY29uZGFyeVwiPmJlZm9yZSAxMi4wLjA8L3NwYW4+IFBvc3NpYmxlIHZhbHVlcyB3ZXJlIGAnbGVmdCcgfCAncmlnaHQnYC5cblx0ICovXG5cdGRpcmVjdGlvbjogTmdiU2xpZGVFdmVudERpcmVjdGlvbjtcblxuXHQvKipcblx0ICogU291cmNlIHRyaWdnZXJpbmcgdGhlIHNsaWRlIGNoYW5nZSBldmVudC5cblx0ICpcblx0ICogUG9zc2libGUgdmFsdWVzIGFyZSBgJ3RpbWVyJyB8ICdhcnJvd0xlZnQnIHwgJ2Fycm93UmlnaHQnIHwgJ2luZGljYXRvcidgXG5cdCAqXG5cdCAqL1xuXHRzb3VyY2U/OiBOZ2JTbGlkZUV2ZW50U291cmNlO1xufVxuXG5leHBvcnQgZW51bSBOZ2JTbGlkZUV2ZW50U291cmNlIHtcblx0VElNRVIgPSAndGltZXInLFxuXHRBUlJPV19MRUZUID0gJ2Fycm93TGVmdCcsXG5cdEFSUk9XX1JJR0hUID0gJ2Fycm93UmlnaHQnLFxuXHRJTkRJQ0FUT1IgPSAnaW5kaWNhdG9yJyxcbn1cblxuZXhwb3J0IGNvbnN0IE5HQl9DQVJPVVNFTF9ESVJFQ1RJVkVTID0gW05nYkNhcm91c2VsLCBOZ2JTbGlkZV07XG4iXX0=