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: ` `, 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: ` `, }] }], 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=