UNPKG

@ng-bootstrap/ng-bootstrap

Version:
297 lines 31.9 kB
import { ChangeDetectorRef, ContentChildren, DestroyRef, Directive, ElementRef, inject, Input, Output, } from '@angular/core'; import { NgbScrollSpyService } from './scrollspy.service'; import { isString } from '../util/util'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import * as i0 from "@angular/core"; /** * A helper directive to that links menu items and fragments together. * * It will automatically add the `.active` class to the menu item when the associated fragment becomes active. * * @since 15.1.0 */ export class NgbScrollSpyItem { constructor() { this._changeDetector = inject(ChangeDetectorRef); this._scrollSpyMenu = inject(NgbScrollSpyMenu, { optional: true }); this._scrollSpyAPI = this._scrollSpyMenu ?? inject(NgbScrollSpyService); this._destroyRef = inject(DestroyRef); this._isActive = false; } /** * References the scroll spy directive, the id of the associated fragment and the parent menu item. * * Can be used like: * - `ngbScrollSpyItem="fragmentId"` * - `[ngbScrollSpyItem]="scrollSpy" fragment="fragmentId" * - `[ngbScrollSpyItem]="[scrollSpy, 'fragmentId']"` parent="parentId"` * - `[ngbScrollSpyItem]="[scrollSpy, 'fragmentId', 'parentId']"` * * As well as together with `[fragment]` and `[parent]` inputs. */ set data(data) { if (Array.isArray(data)) { this._scrollSpyAPI = data[0]; this.fragment = data[1]; this.parent ??= data[2]; } else if (data instanceof NgbScrollSpy) { this._scrollSpyAPI = data; } else if (isString(data)) { this.fragment = data; } } ngOnInit() { // if it is not a part of a bigger menu, it should handle activation itself if (!this._scrollSpyMenu) { this._scrollSpyAPI.active$.pipe(takeUntilDestroyed(this._destroyRef)).subscribe((active) => { if (active === this.fragment) { this._activate(); } else { this._deactivate(); } this._changeDetector.markForCheck(); }); } } /** * @internal */ _activate() { this._isActive = true; if (this._scrollSpyMenu) { this._scrollSpyMenu.getItem(this.parent ?? '')?._activate(); } } /** * @internal */ _deactivate() { this._isActive = false; if (this._scrollSpyMenu) { this._scrollSpyMenu.getItem(this.parent ?? '')?._deactivate(); } } /** * Returns `true`, if the associated fragment is active. */ isActive() { return this._isActive; } /** * Scrolls to the associated fragment. */ scrollTo(options) { this._scrollSpyAPI.scrollTo(this.fragment, options); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.0", ngImport: i0, type: NgbScrollSpyItem, deps: [], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.0.0", type: NgbScrollSpyItem, isStandalone: true, selector: "[ngbScrollSpyItem]", inputs: { data: ["ngbScrollSpyItem", "data"], fragment: "fragment", parent: "parent" }, host: { listeners: { "click": "scrollTo();" }, properties: { "class.active": "isActive()" } }, exportAs: ["ngbScrollSpyItem"], ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0", ngImport: i0, type: NgbScrollSpyItem, decorators: [{ type: Directive, args: [{ selector: '[ngbScrollSpyItem]', standalone: true, exportAs: 'ngbScrollSpyItem', host: { '[class.active]': 'isActive()', '(click)': 'scrollTo();', }, }] }], propDecorators: { data: [{ type: Input, args: ['ngbScrollSpyItem'] }], fragment: [{ type: Input }], parent: [{ type: Input }] } }); /** * An optional scroll spy menu directive to build hierarchical menus * and simplify the [`NgbScrollSpyItem`](#/components/scrollspy/api#NgbScrollSpyItem) configuration. * * @since 15.1.0 */ export class NgbScrollSpyMenu { constructor() { this._scrollSpyRef = inject(NgbScrollSpyService); this._destroyRef = inject(DestroyRef); this._map = new Map(); this._lastActiveItem = null; } set scrollSpy(scrollSpy) { this._scrollSpyRef = scrollSpy; } get active() { return this._scrollSpyRef.active; } get active$() { return this._scrollSpyRef.active$; } scrollTo(fragment, options) { this._scrollSpyRef.scrollTo(fragment, options); } getItem(id) { return this._map.get(id); } ngAfterViewInit() { this._items.changes.pipe(takeUntilDestroyed(this._destroyRef)).subscribe(() => this._rebuildMap()); this._rebuildMap(); this._scrollSpyRef.active$.pipe(takeUntilDestroyed(this._destroyRef)).subscribe((activeId) => { this._lastActiveItem?._deactivate(); const item = this._map.get(activeId); if (item) { item._activate(); this._lastActiveItem = item; } }); } _rebuildMap() { this._map.clear(); for (let item of this._items) { this._map.set(item.fragment, item); } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.0", ngImport: i0, type: NgbScrollSpyMenu, deps: [], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.0.0", type: NgbScrollSpyMenu, isStandalone: true, selector: "[ngbScrollSpyMenu]", inputs: { scrollSpy: ["ngbScrollSpyMenu", "scrollSpy"] }, queries: [{ propertyName: "_items", predicate: NgbScrollSpyItem, descendants: true }], ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0", ngImport: i0, type: NgbScrollSpyMenu, decorators: [{ type: Directive, args: [{ selector: '[ngbScrollSpyMenu]', standalone: true, }] }], propDecorators: { _items: [{ type: ContentChildren, args: [NgbScrollSpyItem, { descendants: true }] }], scrollSpy: [{ type: Input, args: ['ngbScrollSpyMenu'] }] } }); /** * A directive to put on a scrollable container. * * It will instantiate a [`NgbScrollSpyService`](#/components/scrollspy/api#NgbScrollSpyService). * * @since 15.1.0 */ export class NgbScrollSpy { constructor() { this._initialFragment = null; this._service = inject(NgbScrollSpyService); this._nativeElement = inject(ElementRef).nativeElement; /** * An event raised when the active section changes. * * Payload is the id of the new active section, empty string if none. */ this.activeChange = this._service.active$; } set active(fragment) { this._initialFragment = fragment; this.scrollTo(fragment); } /** * Getter/setter for the currently active fragment id. */ get active() { return this._service.active; } /** * Returns an observable that emits currently active section id. */ get active$() { return this._service.active$; } ngAfterViewInit() { this._service.start({ processChanges: this.processChanges, root: this._nativeElement, rootMargin: this.rootMargin, threshold: this.threshold, ...(this._initialFragment && { initialFragment: this._initialFragment }), }); } /** * @internal */ _registerFragment(fragment) { this._service.observe(fragment.id); } /** * @internal */ _unregisterFragment(fragment) { this._service.unobserve(fragment.id); } /** * Scrolls to a fragment that is identified by the `ngbScrollSpyFragment` directive. * An id or an element reference can be passed. */ scrollTo(fragment, options) { this._service.scrollTo(fragment, { ...(this.scrollBehavior && { behavior: this.scrollBehavior }), ...options, }); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.0", ngImport: i0, type: NgbScrollSpy, deps: [], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.0.0", type: NgbScrollSpy, isStandalone: true, selector: "[ngbScrollSpy]", inputs: { processChanges: "processChanges", rootMargin: "rootMargin", scrollBehavior: "scrollBehavior", threshold: "threshold", active: "active" }, outputs: { activeChange: "activeChange" }, host: { attributes: { "tabindex": "0" }, styleAttribute: "overflow-y: auto" }, providers: [NgbScrollSpyService], exportAs: ["ngbScrollSpy"], ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0", ngImport: i0, type: NgbScrollSpy, decorators: [{ type: Directive, args: [{ selector: '[ngbScrollSpy]', standalone: true, exportAs: 'ngbScrollSpy', host: { tabindex: '0', style: 'overflow-y: auto', }, providers: [NgbScrollSpyService], }] }], propDecorators: { processChanges: [{ type: Input }], rootMargin: [{ type: Input }], scrollBehavior: [{ type: Input }], threshold: [{ type: Input }], active: [{ type: Input }], activeChange: [{ type: Output }] } }); /** * A directive to put on a fragment observed inside a scrollspy container. * * @since 15.1.0 */ export class NgbScrollSpyFragment { constructor() { this._destroyRef = inject(DestroyRef); this._scrollSpy = inject(NgbScrollSpy); } ngAfterViewInit() { this._scrollSpy._registerFragment(this); this._destroyRef.onDestroy(() => this._scrollSpy._unregisterFragment(this)); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.0", ngImport: i0, type: NgbScrollSpyFragment, deps: [], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.0.0", type: NgbScrollSpyFragment, isStandalone: true, selector: "[ngbScrollSpyFragment]", inputs: { id: ["ngbScrollSpyFragment", "id"] }, host: { properties: { "id": "id" } }, ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0", ngImport: i0, type: NgbScrollSpyFragment, decorators: [{ type: Directive, args: [{ selector: '[ngbScrollSpyFragment]', standalone: true, host: { '[id]': 'id', }, }] }], propDecorators: { id: [{ type: Input, args: ['ngbScrollSpyFragment'] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2Nyb2xsc3B5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3Njcm9sbHNweS9zY3JvbGxzcHkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUVOLGlCQUFpQixFQUNqQixlQUFlLEVBQ2YsVUFBVSxFQUNWLFNBQVMsRUFDVCxVQUFVLEVBQ1YsTUFBTSxFQUNOLEtBQUssRUFFTCxNQUFNLEdBRU4sTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUE4QixtQkFBbUIsRUFBc0IsTUFBTSxxQkFBcUIsQ0FBQztBQUUxRyxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQ3hDLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLDRCQUE0QixDQUFDOztBQWFoRTs7Ozs7O0dBTUc7QUFVSCxNQUFNLE9BQU8sZ0JBQWdCO0lBVDdCO1FBVVMsb0JBQWUsR0FBRyxNQUFNLENBQUMsaUJBQWlCLENBQUMsQ0FBQztRQUM1QyxtQkFBYyxHQUFHLE1BQU0sQ0FBQyxnQkFBZ0IsRUFBRSxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQzlELGtCQUFhLEdBQW9CLElBQUksQ0FBQyxjQUFjLElBQUksTUFBTSxDQUFDLG1CQUFtQixDQUFDLENBQUM7UUFDcEYsZ0JBQVcsR0FBRyxNQUFNLENBQUMsVUFBVSxDQUFDLENBQUM7UUFFakMsY0FBUyxHQUFHLEtBQUssQ0FBQztLQWtGMUI7SUFoRkE7Ozs7Ozs7Ozs7T0FVRztJQUNILElBQStCLElBQUksQ0FBQyxJQUE2RDtRQUNoRyxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUU7WUFDeEIsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDN0IsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDeEIsSUFBSSxDQUFDLE1BQU0sS0FBSyxJQUFJ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QkFFTyxNQUFNO3NCQUFsQixLQUFLO2dCQVVJLFlBQVk7c0JBQXJCLE1BQU07O0FBb0RSOzs7O0dBSUc7QUFRSCxNQUFNLE9BQU8sb0JBQW9CO0lBUGpDO1FBUVMsZ0JBQVcsR0FBRyxNQUFNLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDakMsZUFBVSxHQUFHLE1BQU0sQ0FBQyxZQUFZLENBQUMsQ0FBQztLQVkxQztJQUpBLGVBQWU7UUFDZCxJQUFJLENBQUMsVUFBVSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3hDLElBQUksQ0FBQyxXQUFXLENBQUMsU0FBUyxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztJQUM3RSxDQUFDOzhHQWJXLG9CQUFvQjtrR0FBcEIsb0JBQW9COzsyRkFBcEIsb0JBQW9CO2tCQVBoQyxTQUFTO21CQUFDO29CQUNWLFFBQVEsRUFBRSx3QkFBd0I7b0JBQ2xDLFVBQVUsRUFBRSxJQUFJO29CQUNoQixJQUFJLEVBQUU7d0JBQ0wsTUFBTSxFQUFFLElBQUk7cUJBQ1o7aUJBQ0Q7OEJBUytCLEVBQUU7c0JBQWhDLEtBQUs7dUJBQUMsc0JBQXNCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcblx0QWZ0ZXJWaWV3SW5pdCxcblx0Q2hhbmdlRGV0ZWN0b3JSZWYsXG5cdENvbnRlbnRDaGlsZHJlbixcblx0RGVzdHJveVJlZixcblx0RGlyZWN0aXZlLFxuXHRFbGVtZW50UmVmLFxuXHRpbmplY3QsXG5cdElucHV0LFxuXHRPbkluaXQsXG5cdE91dHB1dCxcblx0UXVlcnlMaXN0LFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IE5nYlNjcm9sbFNweVByb2Nlc3NDaGFuZ2VzLCBOZ2JTY3JvbGxTcHlTZXJ2aWNlLCBOZ2JTY3JvbGxUb09wdGlvbnMgfSBmcm9tICcuL3Njcm9sbHNweS5zZXJ2aWNlJztcbmltcG9ydCB7IE9ic2VydmFibGUgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IGlzU3RyaW5nIH0gZnJvbSAnLi4vdXRpbC91dGlsJztcbmltcG9ydCB7IHRha2VVbnRpbERlc3Ryb3llZCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUvcnhqcy1pbnRlcm9wJztcblxuLyoqXG4gKiBDb21tb24gaW50ZXJmYWNlIGZvciB0aGUgc2Nyb2xsIHNweSBBUEkuXG4gKlxuICogQGludGVybmFsXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTmdiU2Nyb2xsU3B5UmVmIHtcblx0Z2V0IGFjdGl2ZSgpOiBzdHJpbmc7XG5cdGdldCBhY3RpdmUkKCk6IE9ic2VydmFibGU8c3RyaW5nPjtcblx0c2Nyb2xsVG8oZnJhZ21lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50LCBvcHRpb25zPzogTmdiU2Nyb2xsVG9PcHRpb25zKTogdm9pZDtcbn1cblxuLyoqXG4gKiBBIGhlbHBlciBkaXJlY3RpdmUgdG8gdGhhdCBsaW5rcyBtZW51IGl0ZW1zIGFuZCBmcmFnbWVudHMgdG9nZXRoZXIuXG4gKlxuICogSXQgd2lsbCBhdXRvbWF0aWNhbGx5IGFkZCB0aGUgYC5hY3RpdmVgIGNsYXNzIHRvIHRoZSBtZW51IGl0ZW0gd2hlbiB0aGUgYXNzb2NpYXRlZCBmcmFnbWVudCBiZWNvbWVzIGFjdGl2ZS5cbiAqXG4gKiBAc2luY2UgMTUuMS4wXG4gKi9cbkBEaXJlY3RpdmUoe1xuXHRzZWxlY3RvcjogJ1tuZ2JTY3JvbGxTcHlJdGVtXScsXG5cdHN0YW5kYWxvbmU6IHRydWUsXG5cdGV4cG9ydEFzOiAnbmdiU2Nyb2xsU3B5SXRlbScsXG5cdGhvc3Q6IHtcblx0XHQnW2NsYXNzLmFjdGl2ZV0nOiAnaXNBY3RpdmUoKScsXG5cdFx0JyhjbGljayknOiAnc2Nyb2xsVG8oKTsnLFxuXHR9LFxufSlcbmV4cG9ydCBjbGFzcyBOZ2JTY3JvbGxTcHlJdGVtIGltcGxlbWVudHMgT25Jbml0IHtcblx0cHJpdmF0ZSBfY2hhbmdlRGV0ZWN0b3IgPSBpbmplY3QoQ2hhbmdlRGV0ZWN0b3JSZWYpO1xuXHRwcml2YXRlIF9zY3JvbGxTcHlNZW51ID0gaW5qZWN0KE5nYlNjcm9sbFNweU1lbnUsIHsgb3B0aW9uYWw6IHRydWUgfSk7XG5cdHByaXZhdGUgX3Njcm9sbFNweUFQSTogTmdiU2Nyb2xsU3B5UmVmID0gdGhpcy5fc2Nyb2xsU3B5TWVudSA/PyBpbmplY3QoTmdiU2Nyb2xsU3B5U2VydmljZSk7XG5cdHByaXZhdGUgX2Rlc3Ryb3lSZWYgPSBpbmplY3QoRGVzdHJveVJlZik7XG5cblx0cHJpdmF0ZSBfaXNBY3RpdmUgPSBmYWxzZTtcblxuXHQvKipcblx0ICogUmVmZXJlbmNlcyB0aGUgc2Nyb2xsIHNweSBkaXJlY3RpdmUsIHRoZSBpZCBvZiB0aGUgYXNzb2NpYXRlZCBmcmFnbWVudCBhbmQgdGhlIHBhcmVudCBtZW51IGl0ZW0uXG5cdCAqXG5cdCAqIENhbiBiZSB1c2VkIGxpa2U6XG5cdCAqICAtIGBuZ2JTY3JvbGxTcHlJdGVtPVwiZnJhZ21lbnRJZFwiYFxuXHQgKiAgLSBgW25nYlNjcm9sbFNweUl0ZW1dPVwic2Nyb2xsU3B5XCIgZnJhZ21lbnQ9XCJmcmFnbWVudElkXCJcblx0ICogIC0gYFtuZ2JTY3JvbGxTcHlJdGVtXT1cIltzY3JvbGxTcHksICdmcmFnbWVudElkJ11cImAgcGFyZW50PVwicGFyZW50SWRcImBcblx0ICogIC0gYFtuZ2JTY3JvbGxTcHlJdGVtXT1cIltzY3JvbGxTcHksICdmcmFnbWVudElkJywgJ3BhcmVudElkJ11cImBcblx0ICpcblx0ICogIEFzIHdlbGwgYXMgdG9nZXRoZXIgd2l0aCBgW2ZyYWdtZW50XWAgYW5kIGBbcGFyZW50XWAgaW5wdXRzLlxuXHQgKi9cblx0QElucHV0KCduZ2JTY3JvbGxTcHlJdGVtJykgc2V0IGRhdGEoZGF0YTogTmdiU2Nyb2xsU3B5IHwgc3RyaW5nIHwgW05nYlNjcm9sbFNweSwgc3RyaW5nLCBzdHJpbmc/XSkge1xuXHRcdGlmIChBcnJheS5pc0FycmF5KGRhdGEpKSB7XG5cdFx0XHR0aGlzLl9zY3JvbGxTcHlBUEkgPSBkYXRhWzBdO1xuXHRcdFx0dGhpcy5mcmFnbWVudCA9IGRhdGFbMV07XG5cdFx0XHR0aGlzLnBhcmVudCA/Pz0gZGF0YVsyXTtcblx0XHR9IGVsc2UgaWYgKGRhdGEgaW5zdGFuY2VvZiBOZ2JTY3JvbGxTcHkpIHtcblx0XHRcdHRoaXMuX3Njcm9sbFNweUFQSSA9IGRhdGE7XG5cdFx0fSBlbHNlIGlmIChpc1N0cmluZyhkYXRhKSkge1xuXHRcdFx0dGhpcy5mcmFnbWVudCA9IGRhdGE7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIFRoZSBpZCBvZiB0aGUgYXNzb2NpYXRlZCBmcmFnbWVudC5cblx0ICovXG5cdEBJbnB1dCgpIGZyYWdtZW50OiBzdHJpbmc7XG5cblx0LyoqXG5cdCAqIFRoZSBpZCBvZiB0aGUgcGFyZW50IHNjcm9sbCBzcHkgbWVudSBpdGVtLlxuXHQgKi9cblx0QElucHV0KCkgcGFyZW50OiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cblx0bmdPbkluaXQoKTogdm9pZCB7XG5cdFx0Ly8gaWYgaXQgaXMgbm90IGEgcGFydCBvZiBhIGJpZ2dlciBtZW51LCBpdCBzaG91bGQgaGFuZGxlIGFjdGl2YXRpb24gaXRzZWxmXG5cdFx0aWYgKCF0aGlzLl9zY3JvbGxTcHlNZW51KSB7XG5cdFx0XHR0aGlzLl9zY3JvbGxTcHlBUEkuYWN0aXZlJC5waXBlKHRha2VVbnRpbERlc3Ryb3llZCh0aGlzLl9kZXN0cm95UmVmKSkuc3Vic2NyaWJlKChhY3RpdmU6IHN0cmluZykgPT4ge1xuXHRcdFx0XHRpZiAoYWN0aXZlID09PSB0aGlzLmZyYWdtZW50KSB7XG5cdFx0XHRcdFx0dGhpcy5fYWN0aXZhdGUoKTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHR0aGlzLl9kZWFjdGl2YXRlKCk7XG5cdFx0XHRcdH1cblx0XHRcdFx0dGhpcy5fY2hhbmdlRGV0ZWN0b3IubWFya0ZvckNoZWNrKCk7XG5cdFx0XHR9KTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogQGludGVybmFsXG5cdCAqL1xuXHRfYWN0aXZhdGUoKTogdm9pZCB7XG5cdFx0dGhpcy5faXNBY3RpdmUgPSB0cnVlO1xuXHRcdGlmICh0aGlzLl9zY3JvbGxTcHlNZW51KSB7XG5cdFx0XHR0aGlzLl9zY3JvbGxTcHlNZW51LmdldEl0ZW0odGhpcy5wYXJlbnQgPz8gJycpPy5fYWN0aXZhdGUoKTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogQGludGVybmFsXG5cdCAqL1xuXHRfZGVhY3RpdmF0ZSgpOiB2b2lkIHtcblx0XHR0aGlzLl9pc0FjdGl2ZSA9IGZhbHNlO1xuXHRcdGlmICh0aGlzLl9zY3JvbGxTcHlNZW51KSB7XG5cdFx0XHR0aGlzLl9zY3JvbGxTcHlNZW51LmdldEl0ZW0odGhpcy5wYXJlbnQgPz8gJycpPy5fZGVhY3RpdmF0ZSgpO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBSZXR1cm5zIGB0cnVlYCwgaWYgdGhlIGFzc29jaWF0ZWQgZnJhZ21lbnQgaXMgYWN0aXZlLlxuXHQgKi9cblx0aXNBY3RpdmUoKTogYm9vbGVhbiB7XG5cdFx0cmV0dXJuIHRoaXMuX2lzQWN0aXZlO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNjcm9sbHMgdG8gdGhlIGFzc29jaWF0ZWQgZnJhZ21lbnQuXG5cdCAqL1xuXHRzY3JvbGxUbyhvcHRpb25zPzogTmdiU2Nyb2xsVG9PcHRpb25zKTogdm9pZCB7XG5cdFx0dGhpcy5fc2Nyb2xsU3B5QVBJLnNjcm9sbFRvKHRoaXMuZnJhZ21lbnQsIG9wdGlvbnMpO1xuXHR9XG59XG5cbi8qKlxuICogQW4gb3B0aW9uYWwgc2Nyb2xsIHNweSBtZW51IGRpcmVjdGl2ZSB0byBidWlsZCBoaWVyYXJjaGljYWwgbWVudXNcbiAqIGFuZCBzaW1wbGlmeSB0aGUgW2BOZ2JTY3JvbGxTcHlJdGVtYF0oIy9jb21wb25lbnRzL3Njcm9sbHNweS9hcGkjTmdiU2Nyb2xsU3B5SXRlbSkgY29uZmlndXJhdGlvbi5cbiAqXG4gKiBAc2luY2UgMTUuMS4wXG4gKi9cbkBEaXJlY3RpdmUoe1xuXHRzZWxlY3RvcjogJ1tuZ2JTY3JvbGxTcHlNZW51XScsXG5cdHN0YW5kYWxvbmU6IHRydWUsXG59KVxuZXhwb3J0IGNsYXNzIE5nYlNjcm9sbFNweU1lbnUgaW1wbGVtZW50cyBOZ2JTY3JvbGxTcHlSZWYsIEFmdGVyVmlld0luaXQge1xuXHRwcml2YXRlIF9zY3JvbGxTcHlSZWY6IE5nYlNjcm9sbFNweVJlZiA9IGluamVjdChOZ2JTY3JvbGxTcHlTZXJ2aWNlKTtcblx0cHJpdmF0ZSBfZGVzdHJveVJlZiA9IGluamVjdChEZXN0cm95UmVmKTtcblx0cHJpdmF0ZSBfbWFwID0gbmV3IE1hcDxzdHJpbmcsIE5nYlNjcm9sbFNweUl0ZW0+KCk7XG5cdHByaXZhdGUgX2xhc3RBY3RpdmVJdGVtOiBOZ2JTY3JvbGxTcHlJdGVtIHwgbnVsbCA9IG51bGw7XG5cblx0QENvbnRlbnRDaGlsZHJlbihOZ2JTY3JvbGxTcHlJdGVtLCB7IGRlc2NlbmRhbnRzOiB0cnVlIH0pIHByaXZhdGUgX2l0ZW1zOiBRdWVyeUxpc3Q8TmdiU2Nyb2xsU3B5SXRlbT47XG5cblx0QElucHV0KCduZ2JTY3JvbGxTcHlNZW51Jykgc2V0IHNjcm9sbFNweShzY3JvbGxTcHk6IE5nYlNjcm9sbFNweSkge1xuXHRcdHRoaXMuX3Njcm9sbFNweVJlZiA9IHNjcm9sbFNweTtcblx0fVxuXG5cdGdldCBhY3RpdmUoKTogc3RyaW5nIHtcblx0XHRyZXR1cm4gdGhpcy5fc2Nyb2xsU3B5UmVmLmFjdGl2ZTtcblx0fVxuXHRnZXQgYWN0aXZlJCgpOiBPYnNlcnZhYmxlPHN0cmluZz4ge1xuXHRcdHJldHVybiB0aGlzLl9zY3JvbGxTcHlSZWYuYWN0aXZlJDtcblx0fVxuXHRzY3JvbGxUbyhmcmFnbWVudDogc3RyaW5nLCBvcHRpb25zPzogTmdiU2Nyb2xsVG9PcHRpb25zKTogdm9pZCB7XG5cdFx0dGhpcy5fc2Nyb2xsU3B5UmVmLnNjcm9sbFRvKGZyYWdtZW50LCBvcHRpb25zKTtcblx0fVxuXG5cdGdldEl0ZW0oaWQ6IHN0cmluZyk6IE5nYlNjcm9sbFNweUl0ZW0gfCB1bmRlZmluZWQge1xuXHRcdHJldHVybiB0aGlzLl9tYXAuZ2V0KGlkKTtcblx0fVxuXG5cdG5nQWZ0ZXJWaWV3SW5pdCgpIHtcblx0XHR0aGlzLl9pdGVtcy5jaGFuZ2VzLnBpcGUodGFrZVVudGlsRGVzdHJveWVkKHRoaXMuX2Rlc3Ryb3lSZWYpKS5zdWJzY3JpYmUoKCkgPT4gdGhpcy5fcmVidWlsZE1hcCgpKTtcblx0XHR0aGlzLl9yZWJ1aWxkTWFwKCk7XG5cblx0XHR0aGlzLl9zY3JvbGxTcHlSZWYuYWN0aXZlJC5waXBlKHRha2VVbnRpbERlc3Ryb3llZCh0aGlzLl9kZXN0cm95UmVmKSkuc3Vic2NyaWJlKChhY3RpdmVJZCkgPT4ge1xuXHRcdFx0dGhpcy5fbGFzdEFjdGl2ZUl0ZW0/Ll9kZWFjdGl2YXRlKCk7XG5cdFx0XHRjb25zdCBpdGVtID0gdGhpcy5fbWFwLmdldChhY3RpdmVJZCk7XG5cdFx0XHRpZiAoaXRlbSkge1xuXHRcdFx0XHRpdGVtLl9hY3RpdmF0ZSgpO1xuXHRcdFx0XHR0aGlzLl9sYXN0QWN0aXZlSXRlbSA9IGl0ZW07XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH1cblxuXHRwcml2YXRlIF9yZWJ1aWxkTWFwKCkge1xuXHRcdHRoaXMuX21hcC5jbGVhcigpO1xuXHRcdGZvciAobGV0IGl0ZW0gb2YgdGhpcy5faXRlbXMpIHtcblx0XHRcdHRoaXMuX21hcC5zZXQoaXRlbS5mcmFnbWVudCwgaXRlbSk7XG5cdFx0fVxuXHR9XG59XG5cbi8qKlxuICogQSBkaXJlY3RpdmUgdG8gcHV0IG9uIGEgc2Nyb2xsYWJsZSBjb250YWluZXIuXG4gKlxuICogSXQgd2lsbCBpbnN0YW50aWF0ZSBhIFtgTmdiU2Nyb2xsU3B5U2VydmljZWBdKCMvY29tcG9uZW50cy9zY3JvbGxzcHkvYXBpI05nYlNjcm9sbFNweVNlcnZpY2UpLlxuICpcbiAqIEBzaW5jZSAxNS4xLjBcbiAqL1xuQERpcmVjdGl2ZSh7XG5cdHNlbGVjdG9yOiAnW25nYlNjcm9sbFNweV0nLFxuXHRzdGFuZGFsb25lOiB0cnVlLFxuXHRleHBvcnRBczogJ25nYlNjcm9sbFNweScsXG5cdGhvc3Q6IHtcblx0XHR0YWJpbmRleDogJzAnLFxuXHRcdHN0eWxlOiAnb3ZlcmZsb3cteTogYXV0bycsXG5cdH0sXG5cdHByb3ZpZGVyczogW05nYlNjcm9sbFNweVNlcnZpY2VdLFxufSlcbmV4cG9ydCBjbGFzcyBOZ2JTY3JvbGxTcHkgaW1wbGVtZW50cyBOZ2JTY3JvbGxTcHlSZWYsIEFmdGVyVmlld0luaXQge1xuXHRzdGF0aWMgbmdBY2NlcHRJbnB1dFR5cGVfc2Nyb2xsQmVoYXZpb3I6IHN0cmluZztcblxuXHRwcml2YXRlIF9pbml0aWFsRnJhZ21lbnQ6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuXHRwcml2YXRlIF9zZXJ2aWNlID0gaW5qZWN0KE5nYlNjcm9sbFNweVNlcnZpY2UpO1xuXHRwcml2YXRlIF9uYXRpdmVFbGVtZW50ID0gaW5qZWN0PEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+PihFbGVtZW50UmVmKS5uYXRpdmVFbGVtZW50O1xuXG5cdC8qKlxuXHQgKiBBIGZ1bmN0aW9uIHRoYXQgaXMgY2FsbGVkIHdoZW4gdGhlIGBJbnRlcnNlY3Rpb25PYnNlcnZlcmAgZGV0ZWN0cyBhIGNoYW5nZS5cblx0ICpcblx0ICogU2VlIFtgTmdiU2Nyb2xsU3B5T3B0aW9uc2BdKCMvY29tcG9uZW50cy9zY3JvbGxzcHkvYXBpI05nYlNjcm9sbFNweU9wdGlvbnMpIGZvciBtb3JlIGRldGFpbHMuXG5cdCAqL1xuXHRASW5wdXQoKSBwcm9jZXNzQ2hhbmdlczogTmdiU2Nyb2xsU3B5UHJvY2Vzc0NoYW5nZXM7XG5cblx0LyoqXG5cdCAqIEFuIGBJbnRlcnNlY3Rpb25PYnNlcnZlcmAgcm9vdCBtYXJnaW4uXG5cdCAqL1xuXHRASW5wdXQoKSByb290TWFyZ2luOiBzdHJpbmc7XG5cblx0LyoqXG5cdCAqIFRoZSBzY3JvbGwgYmVoYXZpb3IgZm9yIHRoZSBgLnNjcm9sbFRvKClgIG1ldGhvZC5cblx0ICovXG5cdEBJbnB1dCgpIHNjcm9sbEJlaGF2aW9yOiAnYXV0bycgfCAnc21vb3RoJztcblxuXHQvKipcblx0ICogQW4gYEludGVyc2VjdGlvbk9ic2VydmVyYCB0aHJlc2hvbGQuXG5cdCAqL1xuXHRASW5wdXQoKSB0aHJlc2hvbGQ6IG51bWJlciB8IG51bWJlcltdO1xuXG5cdEBJbnB1dCgpIHNldCBhY3RpdmUoZnJhZ21lbnQ6IHN0cmluZykge1xuXHRcdHRoaXMuX2luaXRpYWxGcmFnbWVudCA9IGZyYWdtZW50O1xuXHRcdHRoaXMuc2Nyb2xsVG8oZnJhZ21lbnQpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFuIGV2ZW50IHJhaXNlZCB3aGVuIHRoZSBhY3RpdmUgc2VjdGlvbiBjaGFuZ2VzLlxuXHQgKlxuXHQgKiBQYXlsb2FkIGlzIHRoZSBpZCBvZiB0aGUgbmV3IGFjdGl2ZSBzZWN0aW9uLCBlbXB0eSBzdHJpbmcgaWYgbm9uZS5cblx0ICovXG5cdEBPdXRwdXQoKSBhY3RpdmVDaGFuZ2UgPSB0aGlzLl9zZXJ2aWNlLmFjdGl2ZSQ7XG5cblx0LyoqXG5cdCAqIEdldHRlci9zZXR0ZXIgZm9yIHRoZSBjdXJyZW50bHkgYWN0aXZlIGZyYWdtZW50IGlkLlxuXHQgKi9cblx0Z2V0IGFjdGl2ZSgpOiBzdHJpbmcge1xuXHRcdHJldHVybiB0aGlzLl9zZXJ2aWNlLmFjdGl2ZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZXR1cm5zIGFuIG9ic2VydmFibGUgdGhhdCBlbWl0cyBjdXJyZW50bHkgYWN0aXZlIHNlY3Rpb24gaWQuXG5cdCAqL1xuXHRnZXQgYWN0aXZlJCgpOiBPYnNlcnZhYmxlPHN0cmluZz4ge1xuXHRcdHJldHVybiB0aGlzLl9zZXJ2aWNlLmFjdGl2ZSQ7XG5cdH1cblxuXHRuZ0FmdGVyVmlld0luaXQoKTogdm9pZCB7XG5cdFx0dGhpcy5fc2VydmljZS5zdGFydCh7XG5cdFx0XHRwcm9jZXNzQ2hhbmdlczogdGhpcy5wcm9jZXNzQ2hhbmdlcyxcblx0XHRcdHJvb3Q6IHRoaXMuX25hdGl2ZUVsZW1lbnQsXG5cdFx0XHRyb290TWFyZ2luOiB0aGlzLnJvb3RNYXJnaW4sXG5cdFx0XHR0aHJlc2hvbGQ6IHRoaXMudGhyZXNob2xkLFxuXHRcdFx0Li4uKHRoaXMuX2luaXRpYWxGcmFnbWVudCAmJiB7IGluaXRpYWxGcmFnbWVudDogdGhpcy5faW5pdGlhbEZyYWdtZW50IH0pLFxuXHRcdH0pO1xuXHR9XG5cblx0LyoqXG5cdCAqIEBpbnRlcm5hbFxuXHQgKi9cblx0X3JlZ2lzdGVyRnJhZ21lbnQoZnJhZ21lbnQ6IE5nYlNjcm9sbFNweUZyYWdtZW50KTogdm9pZCB7XG5cdFx0dGhpcy5fc2VydmljZS5vYnNlcnZlKGZyYWdtZW50LmlkKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAaW50ZXJuYWxcblx0ICovXG5cdF91bnJlZ2lzdGVyRnJhZ21lbnQoZnJhZ21lbnQ6IE5nYlNjcm9sbFNweUZyYWdtZW50KTogdm9pZCB7XG5cdFx0dGhpcy5fc2VydmljZS51bm9ic2VydmUoZnJhZ21lbnQuaWQpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNjcm9sbHMgdG8gYSBmcmFnbWVudCB0aGF0IGlzIGlkZW50aWZpZWQgYnkgdGhlIGBuZ2JTY3JvbGxTcHlGcmFnbWVudGAgZGlyZWN0aXZlLlxuXHQgKiBBbiBpZCBvciBhbiBlbGVtZW50IHJlZmVyZW5jZSBjYW4gYmUgcGFzc2VkLlxuXHQgKi9cblx0c2Nyb2xsVG8oZnJhZ21lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50LCBvcHRpb25zPzogTmdiU2Nyb2xsVG9PcHRpb25zKTogdm9pZCB7XG5cdFx0dGhpcy5fc2VydmljZS5zY3JvbGxUbyhmcmFnbWVudCwge1xuXHRcdFx0Li4uKHRoaXMuc2Nyb2xsQmVoYXZpb3IgJiYgeyBiZWhhdmlvcjogdGhpcy5zY3JvbGxCZWhhdmlvciB9KSxcblx0XHRcdC4uLm9wdGlvbnMsXG5cdFx0fSk7XG5cdH1cbn1cblxuLyoqXG4gKiBBIGRpcmVjdGl2ZSB0byBwdXQgb24gYSBmcmFnbWVudCBvYnNlcnZlZCBpbnNpZGUgYSBzY3JvbGxzcHkgY29udGFpbmVyLlxuICpcbiAqIEBzaW5jZSAxNS4xLjBcbiAqL1xuQERpcmVjdGl2ZSh7XG5cdHNlbGVjdG9yOiAnW25nYlNjcm9sbFNweUZyYWdtZW50XScsXG5cdHN0YW5kYWxvbmU6IHRydWUsXG5cdGhvc3Q6IHtcblx0XHQnW2lkXSc6ICdpZCcsXG5cdH0sXG59KVxuZXhwb3J0IGNsYXNzIE5nYlNjcm9sbFNweUZyYWdtZW50IGltcGxlbWVudHMgQWZ0ZXJWaWV3SW5pdCB7XG5cdHByaXZhdGUgX2Rlc3Ryb3lSZWYgPSBpbmplY3QoRGVzdHJveVJlZik7XG5cdHByaXZhdGUgX3Njcm9sbFNweSA9IGluamVjdChOZ2JTY3JvbGxTcHkpO1xuXG5cdC8qKlxuXHQgKiBUaGUgdW5pcXVlIGlkIG9mIHRoZSBmcmFnbWVudC5cblx0ICogSXQgbXVzdCBiZSBhIHN0cmluZyB1bmlxdWUgdG8gdGhlIGRvY3VtZW50LCBhcyBpdCB3aWxsIGJlIHNldCBhcyB0aGUgaWQgb2YgdGhlIGVsZW1lbnQuXG5cdCAqL1xuXHRASW5wdXQoJ25nYlNjcm9sbFNweUZyYWdtZW50JykgaWQ6IHN0cmluZztcblxuXHRuZ0FmdGVyVmlld0luaXQoKSB7XG5cdFx0dGhpcy5fc2Nyb2xsU3B5Ll9yZWdpc3RlckZyYWdtZW50KHRoaXMpO1xuXHRcdHRoaXMuX2Rlc3Ryb3lSZWYub25EZXN0cm95KCgpID0+IHRoaXMuX3Njcm9sbFNweS5fdW5yZWdpc3RlckZyYWdtZW50KHRoaXMpKTtcblx0fVxufVxuIl19