import { Component, ContentChildren, Directive, EventEmitter, Host, Input, Optional, Output, ViewEncapsulation, } from '@angular/core'; import { isString } from '../util/util'; import { ngbRunTransition } from '../util/transition/ngbTransition'; import { ngbCollapsingTransition } from '../util/transition/ngbCollapseTransition'; import { take } from 'rxjs/operators'; import * as i0 from "@angular/core"; import * as i1 from "./accordion-config"; import * as i2 from "@angular/common"; let nextId = 0; /** * A directive that wraps an accordion panel header with any HTML markup and a toggling button * marked with [`NgbPanelToggle`](#/components/accordion/api#NgbPanelToggle). * See the [header customization demo](#/components/accordion/examples#header) for more details. * * You can also use [`NgbPanelTitle`](#/components/accordion/api#NgbPanelTitle) to customize only the panel title. * * @since 4.1.0 */ export class NgbPanelHeader { constructor(templateRef) { this.templateRef = templateRef; } } NgbPanelHeader.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.6", ngImport: i0, type: NgbPanelHeader, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive }); NgbPanelHeader.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.2.6", type: NgbPanelHeader, selector: "ng-template[ngbPanelHeader]", ngImport: i0 }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.6", ngImport: i0, type: NgbPanelHeader, decorators: [{ type: Directive, args: [{ selector: 'ng-template[ngbPanelHeader]' }] }], ctorParameters: function () { return [{ type: i0.TemplateRef }]; } }); /** * A directive that wraps only the panel title with HTML markup inside. * * You can also use [`NgbPanelHeader`](#/components/accordion/api#NgbPanelHeader) to customize the full panel header. */ export class NgbPanelTitle { constructor(templateRef) { this.templateRef = templateRef; } } NgbPanelTitle.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.6", ngImport: i0, type: NgbPanelTitle, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive }); NgbPanelTitle.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.2.6", type: NgbPanelTitle, selector: "ng-template[ngbPanelTitle]", ngImport: i0 }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.6", ngImport: i0, type: NgbPanelTitle, decorators: [{ type: Directive, args: [{ selector: 'ng-template[ngbPanelTitle]' }] }], ctorParameters: function () { return [{ type: i0.TemplateRef }]; } }); /** * A directive that wraps the accordion panel content. */ export class NgbPanelContent { constructor(templateRef) { this.templateRef = templateRef; } } NgbPanelContent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.6", ngImport: i0, type: NgbPanelContent, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive }); NgbPanelContent.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.2.6", type: NgbPanelContent, selector: "ng-template[ngbPanelContent]", ngImport: i0 }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.6", ngImport: i0, type: NgbPanelContent, decorators: [{ type: Directive, args: [{ selector: 'ng-template[ngbPanelContent]' }] }], ctorParameters: function () { return [{ type: i0.TemplateRef }]; } }); /** * A directive that wraps an individual accordion panel with title and collapsible content. */ export class NgbPanel { constructor() { /** * If `true`, the panel is disabled an can't be toggled. */ this.disabled = false; /** * An optional id for the panel that must be unique on the page. * * If not provided, it will be auto-generated in the `ngb-panel-xxx` format. */ this.id = `ngb-panel-${nextId++}`; this.isOpen = false; /* A flag to specified that the transition panel classes have been initialized */ this.initClassDone = false; /* A flag to specified if the panel is currently being animated, to ensure its presence in the dom */ this.transitionRunning = false; /** * An event emitted when the panel is shown, after the transition. It has no payload. * * @since 8.0.0 */ this.shown = new EventEmitter(); /** * An event emitted when the panel is hidden, after the transition. It has no payload. * * @since 8.0.0 */ this.hidden = new EventEmitter(); } ngAfterContentChecked() { // We are using @ContentChildren instead of @ContentChild as in the Angular version being used // only @ContentChildren allows us to specify the {descendants: false} option. // Without {descendants: false} we are hitting bugs described in: // https://github.com/ng-bootstrap/ng-bootstrap/issues/2240 this.titleTpl = this.titleTpls.first; this.headerTpl = this.headerTpls.first; this.contentTpl = this.contentTpls.first; } } NgbPanel.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.6", ngImport: i0, type: NgbPanel, deps: [], target: i0.ɵɵFactoryTarget.Directive }); NgbPanel.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.2.6", type: NgbPanel, selector: "ngb-panel", inputs: { disabled: "disabled", id: "id", title: "title", type: "type", cardClass: "cardClass" }, outputs: { shown: "shown", hidden: "hidden" }, queries: [{ propertyName: "titleTpls", predicate: NgbPanelTitle }, { propertyName: "headerTpls", predicate: NgbPanelHeader }, { propertyName: "contentTpls", predicate: NgbPanelContent }], ngImport: i0 }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.6", ngImport: i0, type: NgbPanel, decorators: [{ type: Directive, args: [{ selector: 'ngb-panel' }] }], propDecorators: { disabled: [{ type: Input }], id: [{ type: Input }], title: [{ type: Input }], type: [{ type: Input }], cardClass: [{ type: Input }], shown: [{ type: Output }], hidden: [{ type: Output }], titleTpls: [{ type: ContentChildren, args: [NgbPanelTitle, { descendants: false }] }], headerTpls: [{ type: ContentChildren, args: [NgbPanelHeader, { descendants: false }] }], contentTpls: [{ type: ContentChildren, args: [NgbPanelContent, { descendants: false }] }] } }); export class NgbRefDirective { constructor(_El) { this._El = _El; this.ngbRef = new EventEmitter(); } ngOnInit() { this.ngbRef.emit(this._El.nativeElement); } ngOnDestroy() { this.ngbRef.emit(null); } } NgbRefDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.6", ngImport: i0, type: NgbRefDirective, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); NgbRefDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.2.6", type: NgbRefDirective, selector: "[ngbRef]", outputs: { ngbRef: "ngbRef" }, ngImport: i0 }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.6", ngImport: i0, type: NgbRefDirective, decorators: [{ type: Directive, args: [{ selector: '[ngbRef]' }] }], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { ngbRef: [{ type: Output }] } }); /** * Accordion is a collection of collapsible panels (bootstrap cards). * * It can ensure only one panel is opened at a time and allows to customize panel * headers. */ export class NgbAccordion { constructor(config, _ngZone, _changeDetector) { this._ngZone = _ngZone; this._changeDetector = _changeDetector; /** * An array or comma separated strings of panel ids that should be opened **initially**. * * For subsequent changes use methods like `expand()`, `collapse()`, etc. and * the `(panelChange)` event. */ this.activeIds = []; /** * If `true`, panel content will be detached from DOM and not simply hidden when the panel is collapsed. */ this.destroyOnHide = true; /** * Event emitted right before the panel toggle happens. * * See [NgbPanelChangeEvent](#/components/accordion/api#NgbPanelChangeEvent) for payload details. */ this.panelChange = new EventEmitter(); /** * An event emitted when the expanding animation is finished on the panel. The payload is the panel id. * * @since 8.0.0 */ this.shown = new EventEmitter(); /** * An event emitted when the collapsing animation is finished on the panel, and before the panel element is removed. * The payload is the panel id. * * @since 8.0.0 */ this.hidden = new EventEmitter(); this.animation = config.animation; this.type = config.type; this.closeOtherPanels = config.closeOthers; } /** * Checks if a panel with a given id is expanded. */ isExpanded(panelId) { return this.activeIds.indexOf(panelId) > -1; } /** * Expands a panel with a given id. * * Has no effect if the panel is already expanded or disabled. */ expand(panelId) { this._changeOpenState(this._findPanelById(panelId), true); } /** * Expands all panels, if `[closeOthers]` is `false`. * * If `[closeOthers]` is `true`, it will expand the first panel, unless there is already a panel opened. */ expandAll() { if (this.closeOtherPanels) { if (this.activeIds.length === 0 && this.panels.length) { this._changeOpenState(this.panels.first, true); } } else { this.panels.forEach((panel) => this._changeOpenState(panel, true)); } } /** * Collapses a panel with the given id. * * Has no effect if the panel is already collapsed or disabled. */ collapse(panelId) { this._changeOpenState(this._findPanelById(panelId), false); } /** * Collapses all opened panels. */ collapseAll() { this.panels.forEach((panel) => { this._changeOpenState(panel, false); }); } /** * Toggles a panel with the given id. * * Has no effect if the panel is disabled. */ toggle(panelId) { const panel = this._findPanelById(panelId); if (panel) { this._changeOpenState(panel, !panel.isOpen); } } ngAfterContentChecked() { // active id updates if (isString(this.activeIds)) { this.activeIds = this.activeIds.split(/\s*,\s*/); } // update panels open states this.panels.forEach((panel) => { panel.isOpen = !panel.disabled && this.activeIds.indexOf(panel.id) > -1; }); // closeOthers updates if (this.activeIds.length > 1 && this.closeOtherPanels) { this._closeOthers(this.activeIds[0], false); this._updateActiveIds(); } // Setup the initial classes here this._ngZone.onStable.pipe(take(1)).subscribe(() => { this.panels.forEach((panel) => { const panelElement = panel.panelDiv; if (panelElement) { if (!panel.initClassDone) { panel.initClassDone = true; ngbRunTransition(this._ngZone, panelElement, ngbCollapsingTransition, { animation: false, runningTransition: 'continue', context: { direction: panel.isOpen ? 'show' : 'hide', dimension: 'height' }, }); } } else { // Classes must be initialized next time it will be in the dom panel.initClassDone = false; } }); }); } _changeOpenState(panel, nextState) { if (panel != null && !panel.disabled && panel.isOpen !== nextState) { let defaultPrevented = false; this.panelChange.emit({ panelId: panel.id, nextState: nextState, preventDefault: () => { defaultPrevented = true; }, }); if (!defaultPrevented) { panel.isOpen = nextState; panel.transitionRunning = true; if (nextState && this.closeOtherPanels) { this._closeOthers(panel.id); } this._updateActiveIds(); this._runTransitions(this.animation); } } } _closeOthers(panelId, enableTransition = true) { this.panels.forEach((panel) => { if (panel.id !== panelId && panel.isOpen) { panel.isOpen = false; panel.transitionRunning = enableTransition; } }); } _findPanelById(panelId) { return this.panels.find((p) => p.id === panelId) || null; } _updateActiveIds() { this.activeIds = this.panels.filter((panel) => panel.isOpen && !panel.disabled).map((panel) => panel.id); } _runTransitions(animation) { // detectChanges is performed to ensure that all panels are in the dom (via transitionRunning = true) // before starting the animation this._changeDetector.detectChanges(); this.panels.forEach((panel) => { // When panel.transitionRunning is true, the transition needs to be started OR reversed, // The direction (show or hide) is choosen by each panel.isOpen state if (panel.transitionRunning) { const panelElement = panel.panelDiv; ngbRunTransition(this._ngZone, panelElement, ngbCollapsingTransition, { animation, runningTransition: 'stop', context: { direction: panel.isOpen ? 'show' : 'hide', dimension: 'height' }, }).subscribe(() => { panel.transitionRunning = false; const { id } = panel; if (panel.isOpen) { panel.shown.emit(); this.shown.emit(id); } else { panel.hidden.emit(); this.hidden.emit(id); } }); } }); } } NgbAccordion.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.6", ngImport: i0, type: NgbAccordion, deps: [{ token: i1.NgbAccordionConfig }, { token: i0.NgZone }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); NgbAccordion.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.6", type: NgbAccordion, selector: "ngb-accordion", inputs: { animation: "animation", activeIds: "activeIds", closeOtherPanels: ["closeOthers", "closeOtherPanels"], destroyOnHide: "destroyOnHide", type: "type" }, outputs: { panelChange: "panelChange", shown: "shown", hidden: "hidden" }, host: { attributes: { "role": "tablist" }, properties: { "attr.aria-multiselectable": "!closeOtherPanels" }, classAttribute: "accordion" }, queries: [{ propertyName: "panels", predicate: NgbPanel }], exportAs: ["ngbAccordion"], ngImport: i0, template: `
`, isInline: true, dependencies: [{ kind: "directive", type: i0.forwardRef(function () { return i2.NgForOf; }), selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i0.forwardRef(function () { return i2.NgIf; }), selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i0.forwardRef(function () { return i2.NgTemplateOutlet; }), selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i0.forwardRef(function () { return NgbRefDirective; }), selector: "[ngbRef]", outputs: ["ngbRef"] }, { kind: "directive", type: i0.forwardRef(function () { return NgbPanelHeader; }), selector: "ng-template[ngbPanelHeader]" }, { kind: "directive", type: i0.forwardRef(function () { return NgbPanelToggle; }), selector: "button[ngbPanelToggle]", inputs: ["ngbPanelToggle"] }], encapsulation: i0.ViewEncapsulation.None }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.6", ngImport: i0, type: NgbAccordion, decorators: [{ type: Component, args: [{ selector: 'ngb-accordion', exportAs: 'ngbAccordion', encapsulation: ViewEncapsulation.None, host: { class: 'accordion', role: 'tablist', '[attr.aria-multiselectable]': '!closeOtherPanels' }, template: `
`, }] }], ctorParameters: function () { return [{ type: i1.NgbAccordionConfig }, { type: i0.NgZone }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { panels: [{ type: ContentChildren, args: [NgbPanel] }], animation: [{ type: Input }], activeIds: [{ type: Input }], closeOtherPanels: [{ type: Input, args: ['closeOthers'] }], destroyOnHide: [{ type: Input }], type: [{ type: Input }], panelChange: [{ type: Output }], shown: [{ type: Output }], hidden: [{ type: Output }] } }); /** * A directive to put on a button that toggles panel opening and closing. * * To be used inside the [`NgbPanelHeader`](#/components/accordion/api#NgbPanelHeader) * * @since 4.1.0 */ export class NgbPanelToggle { constructor(accordion, panel) { this.accordion = accordion; this.panel = panel; } set ngbPanelToggle(panel) { if (panel) { this.panel = panel; } } } NgbPanelToggle.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.6", ngImport: i0, type: NgbPanelToggle, deps: [{ token: NgbAccordion }, { token: NgbPanel, host: true, optional: true }], target: i0.ɵɵFactoryTarget.Directive }); NgbPanelToggle.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.2.6", type: NgbPanelToggle, selector: "button[ngbPanelToggle]", inputs: { ngbPanelToggle: "ngbPanelToggle" }, host: { attributes: { "type": "button" }, listeners: { "click": "accordion.toggle(panel.id)" }, properties: { "disabled": "panel.disabled", "class.collapsed": "!panel.isOpen", "attr.aria-expanded": "panel.isOpen", "attr.aria-controls": "panel.id" } }, ngImport: i0 }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.6", ngImport: i0, type: NgbPanelToggle, decorators: [{ type: Directive, args: [{ selector: 'button[ngbPanelToggle]', host: { type: 'button', '[disabled]': 'panel.disabled', '[class.collapsed]': '!panel.isOpen', '[attr.aria-expanded]': 'panel.isOpen', '[attr.aria-controls]': 'panel.id', '(click)': 'accordion.toggle(panel.id)', }, }] }], ctorParameters: function () { return [{ type: NgbAccordion }, { type: NgbPanel, decorators: [{ type: Optional }, { type: Host }] }]; }, propDecorators: { ngbPanelToggle: [{ type: Input }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWNjb3JkaW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2FjY29yZGlvbi9hY2NvcmRpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUdOLFNBQVMsRUFDVCxlQUFlLEVBQ2YsU0FBUyxFQUVULFlBQVksRUFDWixJQUFJLEVBQ0osS0FBSyxFQUNMLFFBQVEsRUFDUixNQUFNLEVBR04saUJBQWlCLEdBSWpCLE1BQU0sZUFBZSxDQUFDO0FBRXZCLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFHeEMsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFDcEUsT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0sMENBQTBDLENBQUM7QUFDbkYsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLGdCQUFnQixDQUFDOzs7O0FBRXRDLElBQUksTUFBTSxHQUFHLENBQUMsQ0FBQztBQWNmOzs7Ozs7OztHQVFHO0FBRUgsTUFBTSxPQUFPLGNBQWM7SUFDMUIsWUFBbUIsV0FBNkI7UUFBN0IsZ0JBQVcsR0FBWCxXQUFXLENBQWtCO0lBQUcsQ0FBQzs7MkdBRHhDLGNBQWM7K0ZBQWQsY0FBYzsyRkFBZCxjQUFjO2tCQUQxQixTQUFTO21CQUFDLEVBQUUsUUFBUSxFQUFFLDZCQUE2QixFQUFFOztBQUt0RDs7OztHQUlHO0FBRUgsTUFBTSxPQUFPLGFBQWE7SUFDekIsWUFBbUIsV0FBNkI7UUFBN0IsZ0JBQVcsR0FBWCxXQUFXLENBQWtCO0lBQUcsQ0FBQzs7MEdBRHhDLGFBQWE7OEZBQWIsYUFBYTsyRkFBYixhQUFhO2tCQUR6QixTQUFTO21CQUFDLEVBQUUsUUFBUSxFQUFFLDRCQUE0QixFQUFFOztBQUtyRDs7R0FFRztBQUVILE1BQU0sT0FBTyxlQUFlO0lBQzNCLFlBQW1CLFdBQTZCO1FBQTdCLGdCQUFXLEdBQVgsV0FBVyxDQUFrQjtJQUFHLENBQUM7OzRHQUR4Qyxl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LElBQUksQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDO1NBQ25CO0lBQ0YsQ0FBQzs7MkdBUlcsY0FBYzsrRkFBZCxjQUFjOzJGQUFkLGNBQWM7a0JBWDFCLFNBQVM7bUJBQUM7b0JBQ1YsUUFBUSxFQUFFLHdCQUF3QjtvQkFDbEMsSUFBSSxFQUFFO3dCQUNMLElBQUksRUFBRSxRQUFRO3dCQUNkLFlBQVksRUFBRSxnQkFBZ0I7d0JBQzlCLG1CQUFtQixFQUFFLGVBQWU7d0JBQ3BDLHNCQUFzQixFQUFFLGNBQWM7d0JBQ3RDLHNCQUFzQixFQUFFLFVBQVU7d0JBQ2xDLFNBQVMsRUFBRSw0QkFBNEI7cUJBQ3ZDO2lCQUNEOzswQkFXNkMsUUFBUTs7MEJBQUksSUFBSTs0Q0FOekQsY0FBYztzQkFEakIsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG5cdEFmdGVyQ29udGVudENoZWNrZWQsXG5cdENoYW5nZURldGVjdG9yUmVmLFxuXHRDb21wb25lbnQsXG5cdENvbnRlbnRDaGlsZHJlbixcblx0RGlyZWN0aXZlLFxuXHRFbGVtZW50UmVmLFxuXHRFdmVudEVtaXR0ZXIsXG5cdEhvc3QsXG5cdElucHV0LFxuXHRPcHRpb25hbCxcblx0T3V0cHV0LFxuXHRRdWVyeUxpc3QsXG5cdFRlbXBsYXRlUmVmLFxuXHRWaWV3RW5jYXBzdWxhdGlvbixcblx0Tmdab25lLFxuXHRPbkluaXQsXG5cdE9uRGVzdHJveSxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbmltcG9ydCB7IGlzU3RyaW5nIH0gZnJvbSAnLi4vdXRpbC91dGlsJztcblxuaW1wb3J0IHsgTmdiQWNjb3JkaW9uQ29uZmlnIH0gZnJvbSAnLi9hY2NvcmRpb24tY29uZmlnJztcbmltcG9ydCB7IG5nYlJ1blRyYW5zaXRpb24gfSBmcm9tICcuLi91dGlsL3RyYW5zaXRpb24vbmdiVHJhbnNpdGlvbic7XG5pbXBvcnQgeyBuZ2JDb2xsYXBzaW5nVHJhbnNpdGlvbiB9IGZyb20gJy4uL3V0aWwvdHJhbnNpdGlvbi9uZ2JDb2xsYXBzZVRyYW5zaXRpb24nO1xuaW1wb3J0IHsgdGFrZSB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxubGV0IG5leHRJZCA9IDA7XG5cbi8qKlxuICogVGhlIGNvbnRleHQgZm9yIHRoZSBbTmdiUGFuZWxIZWFkZXJdKCMvY29tcG9uZW50cy9hY2NvcmRpb24vYXBpI05nYlBhbmVsSGVhZGVyKSB0ZW1wbGF0ZVxuICpcbiAqIEBzaW5jZSA0LjEuMFxuICovXG5leHBvcnQgaW50ZXJmYWNlIE5nYlBhbmVsSGVhZGVyQ29udGV4dCB7XG5cdC8qKlxuXHQgKiBgVHJ1ZWAgaWYgY3VycmVudCBwYW5lbCBpcyBvcGVuZWRcblx0ICovXG5cdG9wZW5lZDogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBBIGRpcmVjdGl2ZSB0aGF0IHdyYXBzIGFuIGFjY29yZGlvbiBwYW5lbCBoZWFkZXIgd2l0aCBhbnkgSFRNTCBtYXJrdXAgYW5kIGEgdG9nZ2xpbmcgYnV0dG9uXG4gKiBtYXJrZWQgd2l0aCBbYE5nYlBhbmVsVG9nZ2xlYF0oIy9jb21wb25lbnRzL2FjY29yZGlvbi9hcGkjTmdiUGFuZWxUb2dnbGUpLlxuICogU2VlIHRoZSBbaGVhZGVyIGN1c3RvbWl6YXRpb24gZGVtb10oIy9jb21wb25lbnRzL2FjY29yZGlvbi9leGFtcGxlcyNoZWFkZXIpIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogWW91IGNhbiBhbHNvIHVzZSBbYE5nYlBhbmVsVGl0bGVgXSgjL2NvbXBvbmVudHMvYWNjb3JkaW9uL2FwaSNOZ2JQYW5lbFRpdGxlKSB0byBjdXN0b21pemUgb25seSB0aGUgcGFuZWwgdGl0bGUuXG4gKlxuICogQHNpbmNlIDQuMS4wXG4gKi9cbkBEaXJlY3RpdmUoeyBzZWxlY3RvcjogJ25nLXRlbXBsYXRlW25nYlBhbmVsSGVhZGVyXScgfSlcbmV4cG9ydCBjbGFzcyBOZ2JQYW5lbEhlYWRlciB7XG5cdGNvbnN0cnVjdG9yKHB1YmxpYyB0ZW1wbGF0ZVJlZjogVGVtcGxhdGVSZWY8YW55Pikge31cbn1cblxuLyoqXG4gKiBBIGRpcmVjdGl2ZSB0aGF0IHdyYXBzIG9ubHkgdGhlIHBhbmVsIHRpdGxlIHdpdGggSFRNTCBtYXJrdXAgaW5zaWRlLlxuICpcbiAqIFlvdSBjYW4gYWxzbyB1c2UgW2BOZ2JQYW5lbEhlYWRlcmBdKCMvY29tcG9uZW50cy9hY2NvcmRpb24vYXBpI05nYlBhbmVsSGVhZGVyKSB0byBjdXN0b21pemUgdGhlIGZ1bGwgcGFuZWwgaGVhZGVyLlxuICovXG5ARGlyZWN0aXZlKHsgc2VsZWN0b3I6ICduZy10ZW1wbGF0ZVtuZ2JQYW5lbFRpdGxlXScgfSlcbmV4cG9ydCBjbGFzcyBOZ2JQYW5lbFRpdGxlIHtcblx0Y29uc3RydWN0b3IocHVibGljIHRlbXBsYXRlUmVmOiBUZW1wbGF0ZVJlZjxhbnk+KSB7fVxufVxuXG4vKipcbiAqIEEgZGlyZWN0aXZlIHRoYXQgd3JhcHMgdGhlIGFjY29yZGlvbiBwYW5lbCBjb250ZW50LlxuICovXG5ARGlyZWN0aXZlKHsgc2VsZWN0b3I6ICduZy10ZW1wbGF0ZVtuZ2JQYW5lbENvbnRlbnRdJyB9KVxuZXhwb3J0IGNsYXNzIE5nYlBhbmVsQ29udGVudCB7XG5cdGNvbnN0cnVjdG9yKHB1YmxpYyB0ZW1wbGF0ZVJlZjogVGVtcGxhdGVSZWY8YW55Pikge31cbn1cblxuLyoqXG4gKiBBIGRpcmVjdGl2ZSB0aGF0IHdyYXBzIGFuIGluZGl2aWR1YWwgYWNjb3JkaW9uIHBhbmVsIHdpdGggdGl0bGUgYW5kIGNvbGxhcHNpYmxlIGNvbnRlbnQuXG4gKi9cbkBEaXJlY3RpdmUoeyBzZWxlY3RvcjogJ25nYi1wYW5lbCcgfSlcbmV4cG9ydCBjbGFzcyBOZ2JQYW5lbCBpbXBsZW1lbnRzIEFmdGVyQ29udGVudENoZWNrZWQge1xuXHQvKipcblx0ICogIElmIGB0cnVlYCwgdGhlIHBhbmVsIGlzIGRpc2FibGVkIGFuIGNhbid0IGJlIHRvZ2dsZWQuXG5cdCAqL1xuXHRASW5wdXQoKSBkaXNhYmxlZCA9IGZhbHNlO1xuXG5cdC8qKlxuXHQgKiAgQW4gb3B0aW9uYWwgaWQgZm9yIHRoZSBwYW5lbCB0aGF0IG11c3QgYmUgdW5pcXVlIG9uIHRoZSBwYWdlLlxuXHQgKlxuXHQgKiAgSWYgbm90IHByb3ZpZGVkLCBpdCB3aWxsIGJlIGF1dG8tZ2VuZXJhdGVkIGluIHRoZSBgbmdiLXBhbmVsLXh4eGAgZm9ybWF0LlxuXHQgKi9cblx0QElucHV0KCkgaWQgPSBgbmdiLXBhbmVsLSR7bmV4dElkKyt9YDtcblxuXHRpc09wZW4gPSBmYWxzZTtcblxuXHQvKiBBIGZsYWcgdG8gc3BlY2lmaWVkIHRoYXQgdGhlIHRyYW5zaXRpb24gcGFuZWwgY2xhc3NlcyBoYXZlIGJlZW4gaW5pdGlhbGl6ZWQgKi9cblx0aW5pdENsYXNzRG9uZSA9IGZhbHNlO1xuXG5cdC8qIEEgZmxhZyB0byBzcGVjaWZpZWQgaWYgdGhlIHBhbmVsIGlzIGN1cnJlbnRseSBiZWluZyBhbmltYXRlZCwgdG8gZW5zdXJlIGl0cyBwcmVzZW5jZSBpbiB0aGUgZG9tICovXG5cdHRyYW5zaXRpb25SdW5uaW5nID0gZmFsc2U7XG5cblx0LyoqXG5cdCAqICBUaGUgcGFuZWwgdGl0bGUuXG5cdCAqXG5cdCAqICBZb3UgY2FuIGFsdGVybmF0aXZlbHkgdXNlIFtgTmdiUGFuZWxUaXRsZWBdKCMvY29tcG9uZW50cy9hY2NvcmRpb24vYXBpI05nYlBhbmVsVGl0bGUpIHRvIHNldCBwYW5lbCB0aXRsZS5cblx0ICovXG5cdEBJbnB1dCgpIHRpdGxlOiBzdHJpbmc7XG5cblx0LyoqXG5cdCAqIFR5cGUgb2YgdGhlIGN1cnJlbnQgcGFuZWwuXG5cdCAqXG5cdCAqIEJvb3RzdHJhcCBwcm92aWRlcyBzdHlsZXMgZm9yIHRoZSBmb2xsb3dpbmcgdHlwZXM6IGAnc3VjY2VzcydgLCBgJ2luZm8nYCwgYCd3YXJuaW5nJ2AsIGAnZGFuZ2VyJ2AsIGAncHJpbWFyeSdgLFxuXHQgKiBgJ3NlY29uZGFyeSdgLCBgJ2xpZ2h0J2AgYW5kIGAnZGFyaydgLlxuXHQgKi9cblx0QElucHV0KCkgdHlwZTogc3RyaW5nO1xuXG5cdC8qKlxuXHQgKiBBbiBvcHRpb25hbCBjbGFzcyBhcHBsaWVkIHRvIHRoZSBhY2NvcmRpb24gY2FyZCBlbGVtZW50IHRoYXQgd3JhcHMgYm90aCBwYW5lbCB0aXRsZSBhbmQgY29udGVudC5cblx0ICpcblx0ICogQHNpbmNlIDUuMy4wXG5cdCAqL1xuXHRASW5wdXQoKSBjYXJkQ2xhc3M6IHN0cmluZztcblxuXHQvKipcblx0ICogQW4gZXZlbnQgZW1pdHRlZCB3aGVuIHRoZSBwYW5lbCBpcyBzaG93biwgYWZ0ZXIgdGhlIHRyYW5zaXRpb24uIEl0IGhhcyBubyBwYXlsb2FkLlxuXHQgKlxuXHQgKiBAc2luY2UgOC4wLjBcblx0ICovXG5cdEBPdXRwdXQoKSBzaG93biA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcblxuXHQvKipcblx0ICogQW4gZXZlbnQgZW1pdHRlZCB3aGVuIHRoZSBwYW5lbCBpcyBoaWRkZW4sIGFmdGVyIHRoZSB0cmFuc2l0aW9uLiBJdCBoYXMgbm8gcGF5bG9hZC5cblx0ICpcblx0ICogQHNpbmNlIDguMC4wXG5cdCAqL1xuXHRAT3V0cHV0KCkgaGlkZGVuID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuXG5cdHRpdGxlVHBsPzogTmdiUGFuZWxUaXRsZTtcblx0aGVhZGVyVHBsPzogTmdiUGFuZWxIZWFkZXI7XG5cdGNvbnRlbnRUcGw/OiBOZ2JQYW5lbENvbnRlbnQ7XG5cdHBhbmVsRGl2OiBIVE1MRWxlbWVudCB8IG51bGw7XG5cblx0QENvbnRlbnRDaGlsZHJlbihOZ2JQYW5lbFRpdGxlLCB7IGRlc2NlbmRhbnRzOiBmYWxzZSB9KSB0aXRsZVRwbHM6IFF1ZXJ5TGlzdDxOZ2JQYW5lbFRpdGxlPjtcblx0QENvbnRlbnRDaGlsZHJlbihOZ2JQYW5lbEhlYWRlciwgeyBkZXNjZW5kYW50czogZmFsc2UgfSkgaGVhZGVyVHBsczogUXVlcnlMaXN0PE5nYlBhbmVsSGVhZGVyPjtcblx0QENvbnRlbnRDaGlsZHJlbihOZ2JQYW5lbENvbnRlbnQsIHsgZGVzY2VuZGFudHM6IGZhbHNlIH0pIGNvbnRlbnRUcGxzOiBRdWVyeUxpc3Q8TmdiUGFuZWxDb250ZW50PjtcblxuXHRuZ0FmdGVyQ29udGVudENoZWNrZWQoKSB7XG5cdFx0Ly8gV2UgYXJlIHVzaW5nIEBDb250ZW50Q2hpbGRyZW4gaW5zdGVhZCBvZiBAQ29udGVudENoaWxkIGFzIGluIHRoZSBBbmd1bGFyIHZlcnNpb24gYmVpbmcgdXNlZFxuXHRcdC8vIG9ubHkgQENvbnRlbnRDaGlsZHJlbiBhbGxvd3MgdXMgdG8gc3BlY2lmeSB0aGUge2Rlc2NlbmRhbnRzOiBmYWxzZX0gb3B0aW9uLlxuXHRcdC8vIFdpdGhvdXQge2Rlc2NlbmRhbnRzOiBmYWxzZX0gd2UgYXJlIGhpdHRpbmcgYnVncyBkZXNjcmliZWQgaW46XG5cdFx0Ly8gaHR0cHM6Ly9naXRodWIuY29tL25nLWJvb3RzdHJhcC9uZy1ib290c3RyYXAvaXNzdWVzLzIyNDBcblx0XHR0aGlzLnRpdGxlVHBsID0gdGhpcy50aXRsZVRwbHMuZmlyc3Q7XG5cdFx0dGhpcy5oZWFkZXJUcGwgPSB0aGlzLmhlYWRlclRwbHMuZmlyc3Q7XG5cdFx0dGhpcy5jb250ZW50VHBsID0gdGhpcy5jb250ZW50VHBscy5maXJzdDtcblx0fVxufVxuXG4vKipcbiAqIEFuIGV2ZW50IGVtaXR0ZWQgcmlnaHQgYmVmb3JlIHRvZ2dsaW5nIGFuIGFjY29yZGlvbiBwYW5lbC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBOZ2JQYW5lbENoYW5nZUV2ZW50IHtcblx0LyoqXG5cdCAqIFRoZSBpZCBvZiB0aGUgYWNjb3JkaW9uIHBhbmVsIGJlaW5nIHRvZ2dsZWQuXG5cdCAqL1xuXHRwYW5lbElkOiBzdHJpbmc7XG5cblx0LyoqXG5cdCAqIFRoZSBuZXh0IHN0YXRlIG9mIHRoZSBwYW5lbC5cblx0ICpcblx0ICogYHRydWVgIGlmIGl0IHdpbGwgYmUgb3BlbmVkLCBgZmFsc2VgIGlmIGNsb3NlZC5cblx0ICovXG5cdG5leHRTdGF0ZTogYm9vbGVhbjtcblxuXHQvKipcblx0ICogQ2FsbGluZyB0aGlzIGZ1bmN0aW9uIHdpbGwgcHJldmVudCBwYW5lbCB0b2dnbGluZy5cblx0ICovXG5cdHByZXZlbnREZWZhdWx0OiAoKSA9PiB2b2lkO1xufVxuXG5ARGlyZWN0aXZlKHsgc2VsZWN0b3I6ICdbbmdiUmVmXScgfSlcbmV4cG9ydCBjbGFzcyBOZ2JSZWZEaXJlY3RpdmUgaW1wbGVtZW50cyBPbkluaXQsIE9uRGVzdHJveSB7XG5cdEBPdXRwdXQoKSBuZ2JSZWYgPSBuZXcgRXZlbnRFbWl0dGVyPEhUTUxFbGVtZW50IHwgbnVsbD4oKTtcblx0Y29uc3RydWN0b3IocHJpdmF0ZSBfRWw6IEVsZW1lbnRSZWYpIHt9XG5cblx0bmdPbkluaXQoKSB7XG5cdFx0dGhpcy5uZ2JSZWYuZW1pdCh0aGlzLl9FbC5uYXRpdmVFbGVtZW50KTtcblx0fVxuXG5cdG5nT25EZXN0cm95KCkge1xuXHRcdHRoaXMubmdiUmVmLmVtaXQobnVsbCk7XG5cdH1cbn1cblxuLyoqXG4gKiBBY2NvcmRpb24gaXMgYSBjb2xsZWN0aW9uIG9mIGNvbGxhcHNpYmxlIHBhbmVscyAoYm9vdHN0cmFwIGNhcmRzKS5cbiAqXG4gKiBJdCBjYW4gZW5zdXJlIG9ubHkgb25lIHBhbmVsIGlzIG9wZW5lZCBhdCBhIHRpbWUgYW5kIGFsbG93cyB0byBjdXN0b21pemUgcGFuZWxcbiAqIGhlYWRlcnMuXG4gKi9cbkBDb21wb25lbnQoe1xuXHRzZWxlY3RvcjogJ25nYi1hY2NvcmRpb24nLFxuXHRleHBvcnRBczogJ25nYkFjY29yZGlvbicsXG5cdGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXG5cdGhvc3Q6IHsgY2xhc3M6ICdhY2NvcmRpb24nLCByb2xlOiAndGFibGlzdCcsICdbYXR0ci5hcmlhLW11bHRpc2VsZWN0YWJsZV0nOiAnIWNsb3NlT3RoZXJQYW5lbHMnIH0sXG5cdHRlbXBsYXRlOiBgXG5cdFx0PG5nLXRlbXBsYXRlICN0IG5nYlBhbmVsSGVhZGVyIGxldC1wYW5lbD5cblx0XHRcdDxidXR0b24gY2xhc3M9XCJhY2NvcmRpb24tYnV0dG9uXCIgW25nYlBhbmVsVG9nZ2xlXT1cInBhbmVsXCI+XG5cdFx0XHRcdHt7IHBhbmVsLnRpdGxlIH19PG5nLXRlbXBsYXRlIFtuZ1RlbXBsYXRlT3V0bGV0XT1cInBhbmVsLnRpdGxlVHBsPy50ZW1wbGF0ZVJlZlwiPjwvbmctdGVtcGxhdGU+XG5cdFx0XHQ8L2J1dHRvbj5cblx0XHQ8L25nLXRlbXBsYXRlPlxuXHRcdDxuZy10ZW1wbGF0ZSBuZ0ZvciBsZXQtcGFuZWwgW25nRm9yT2ZdPVwicGFuZWxzXCI+XG5cdFx0XHQ8ZGl2IFtjbGFzc109XCInYWNjb3JkaW9uLWl0ZW0gJyArIChwYW5lbC5jYXJkQ2xhc3MgfHwgJycpXCI+XG5cdFx0XHRcdDxkaXZcblx0XHRcdFx0XHRyb2xlPVwidGFiXCJcblx0XHRcdFx0XHRpZD1cInt7IHBhbmVsLmlkIH19LWhlYWRlclwiXG5cdFx0XHRcdFx0W2NsYXNzXT1cIidhY2NvcmRpb24taGVhZGVyICcgKyAocGFuZWwudHlwZSA/ICdiZy0nICsgcGFuZWwudHlwZSA6IHR5cGUgPyAnYmctJyArIHR5cGUgOiAnJylcIlxuXHRcdFx0XHQ+XG5cdFx0XHRcdFx0PG5nLXRlbXBsYXRlXG5cdFx0XHRcdFx0XHRbbmdUZW1wbGF0ZU91dGxldF09XCJwYW5lbC5oZWFkZXJUcGw/LnRlbXBsYXRlUmVmIHx8IHRcIlxuXHRcdFx0XHRcdFx0W25nVGVtcGxhdGVPdXRsZXRDb250ZXh0XT1cInsgJGltcGxpY2l0OiBwYW5lbCwgb3BlbmVkOiBwYW5lbC5pc09wZW4gfVwiXG5cdFx0XHRcdFx0PjwvbmctdGVtcGxhdGU+XG5cdFx0XHRcdDwvZGl2PlxuXHRcdFx0XHQ8ZGl2XG5cdFx0XHRcdFx0aWQ9XCJ7eyBwYW5lbC5pZCB9fVwiXG5cdFx0XHRcdFx0KG5nYlJlZik9XCJwYW5lbC5wYW5lbERpdiA9ICRldmVudFwiXG5cdFx0XHRcdFx0cm9sZT1cInRhYnBhbmVsXCJcblx0XHRcdFx0XHRbYXR0ci5hcmlhLWxhYmVsbGVkYnldPVwicGFuZWwuaWQgKyAnLWhlYWRlcidcIlxuXHRcdFx0XHRcdCpuZ0lmPVwiIWRlc3Ryb3lPbkhpZGUgfHwgcGFuZWwuaXNPcGVuIHx8IHBhbmVsLnRyYW5zaXRpb25SdW5uaW5nXCJcblx0XHRcdFx0PlxuXHRcdFx0XHRcdDxkaXYgY2xhc3M9XCJhY2NvcmRpb24tYm9keVwiPlxuXHRcdFx0XHRcdFx0PG5nLXRlbXBsYXRlIFtuZ1RlbXBsYXRlT3V0bGV0XT1cInBhbmVsLmNvbnRlbnRUcGw/LnRlbXBsYXRlUmVmIHx8IG51bGxcIj48L25nLXRlbXBsYXRlPlxuXHRcdFx0XHRcdDwvZGl2PlxuXHRcdFx0XHQ8L2Rpdj5cblx0XHRcdDwvZGl2PlxuXHRcdDwvbmctdGVtcGxhdGU+XG5cdGAsXG59KVxuZXhwb3J0IGNsYXNzIE5nYkFjY29yZGlvbiBpbXBsZW1lbnRzIEFmdGVyQ29udGVudENoZWNrZWQge1xuXHRAQ29udGVudENoaWxkcmVuKE5nYlBhbmVsKSBwYW5lbHM6IFF1ZXJ5TGlzdDxOZ2JQYW5lbD47XG5cblx0LyoqXG5cdCAqIElmIGB0cnVlYCwgYWNjb3JkaW9uIHdpbGwgYmUgYW5pbWF0ZWQuXG5cdCAqXG5cdCAqIEBzaW5jZSA4LjAuMFxuXHQgKi9cblx0QElucHV0KCkgYW5pbWF0aW9uO1xuXG5cdC8qKlxuXHQgKiBBbiBhcnJheSBvciBjb21tYSBzZXBhcmF0ZWQgc3RyaW5ncyBvZiBwYW5lbCBpZHMgdGhhdCBzaG91bGQgYmUgb3BlbmVkICoqaW5pdGlhbGx5KiouXG5cdCAqXG5cdCAqIEZvciBzdWJzZXF1ZW50IGNoYW5nZXMgdXNlIG1ldGhvZHMgbGlrZSBgZXhwYW5kKClgLCBgY29sbGFwc2UoKWAsIGV0Yy4gYW5kXG5cdCAqIHRoZSBgKHBhbmVsQ2hhbmdlKWAgZXZlbnQuXG5cdCAqL1xuXHRASW5wdXQoKSBhY3RpdmVJZHM6IHN0cmluZyB8IHJlYWRvbmx5IHN0cmluZ1tdID0gW107XG5cblx0LyoqXG5cdCAqICBJZiBgdHJ1ZWAsIG9ubHkgb25lIHBhbmVsIGNvdWxkIGJlIG9wZW5lZCBhdCBhIHRpbWUuXG5cdCAqXG5cdCAqICBPcGVuaW5nIGEgbmV3IHBhbmVsIHdpbGwgY2xvc2Ugb3RoZXJzLlxuXHQgKi9cblx0QElucHV0KCdjbG9zZU90aGVycycpIGNsb3NlT3RoZXJQYW5lbHM6IGJvb2xlYW47XG5cblx0LyoqXG5cdCAqIElmIGB0cnVlYCwgcGFuZWwgY29udGVudCB3aWxsIGJlIGRldGFjaGVkIGZyb20gRE9NIGFuZCBub3Qgc2ltcGx5IGhpZGRlbiB3aGVuIHRoZSBwYW5lbCBpcyBjb2xsYXBzZWQuXG5cdCAqL1xuXHRASW5wdXQoKSBkZXN0cm95T25IaWRlID0gdHJ1ZTtcblxuXHQvKipcblx0ICogVHlwZSBvZiBwYW5lbHMuXG5cdCAqXG5cdCAqIEJvb3RzdHJhcCBwcm92aWRlcyBzdHlsZXMgZm9yIHRoZSBmb2xsb3dpbmcgdHlwZXM6IGAnc3VjY2VzcydgLCBgJ2luZm8nYCwgYCd3YXJuaW5nJ2AsIGAnZGFuZ2VyJ2AsIGAncHJpbWFyeSdgLFxuXHQgKiBgJ3NlY29uZGFyeSdgLCBgJ2xpZ2h0J2AgYW5kIGAnZGFyaydgLlxuXHQgKi9cblx0QElucHV0KCkgdHlwZTogc3RyaW5nO1xuXG5cdC8qKlxuXHQgKiBFdmVudCBlbWl0dGVkIHJpZ2h0IGJlZm9yZSB0aGUgcGFuZWwgdG9nZ2xlIGhhcHBlbnMuXG5cdCAqXG5cdCAqIFNlZSBbTmdiUGFuZWxDaGFuZ2VFdmVudF0oIy9jb21wb25lbnRzL2FjY29yZGlvbi9hcGkjTmdiUGFuZWxDaGFuZ2VFdmVudCkgZm9yIHBheWxvYWQgZGV0YWlscy5cblx0ICovXG5cdEBPdXRwdXQoKSBwYW5lbENoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8TmdiUGFuZWxDaGFuZ2VFdmVudD4oKTtcblxuXHQvKipcblx0ICogQW4gZXZlbnQgZW1pdHRlZCB3aGVuIHRoZSBleHBhbmRpbmcgYW5pbWF0aW9uIGlzIGZpbmlzaGVkIG9uIHRoZSBwYW5lbC4gVGhlIHBheWxvYWQgaXMgdGhlIHBhbmVsIGlkLlxuXHQgKlxuXHQgKiBAc2luY2UgOC4wLjBcblx0ICovXG5cdEBPdXRwdXQoKSBzaG93biA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpO1xuXG5cdC8qKlxuXHQgKiBBbiBldmVudCBlbWl0dGVkIHdoZW4gdGhlIGNvbGxhcHNpbmcgYW5pbWF0aW9uIGlzIGZpbmlzaGVkIG9uIHRoZSBwYW5lbCwgYW5kIGJlZm9yZSB0aGUgcGFuZWwgZWxlbWVudCBpcyByZW1vdmVkLlxuXHQgKiBUaGUgcGF5bG9hZCBpcyB0aGUgcGFuZWwgaWQuXG5cdCAqXG5cdCAqIEBzaW5jZSA4LjAuMFxuXHQgKi9cblx0QE91dHB1dCgpIGhpZGRlbiA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpO1xuXG5cdGNvbnN0cnVjdG9yKGNvbmZpZzogTmdiQWNjb3JkaW9uQ29uZmlnLCBwcml2YXRlIF9uZ1pvbmU6IE5nWm9uZSwgcHJpdmF0ZSBfY2hhbmdlRGV0ZWN0b3I6IENoYW5nZURldGVjdG9yUmVmKSB7XG5cdFx0dGhpcy5hbmltYXRpb24gPSBjb25maWcuYW5pbWF0aW9uO1xuXHRcdHRoaXMudHlwZSA9IGNvbmZpZy50eXBlO1xuXHRcdHRoaXMuY2xvc2VPdGhlclBhbmVscyA9IGNvbmZpZy5jbG9zZU90aGVycztcblx0fVxuXG5cdC8qKlxuXHQgKiBDaGVja3MgaWYgYSBwYW5lbCB3aXRoIGEgZ2l2ZW4gaWQgaXMgZXhwYW5kZWQuXG5cdCAqL1xuXHRpc0V4cGFuZGVkKHBhbmVsSWQ6IHN0cmluZyk6IGJvb2xlYW4ge1xuXHRcdHJldHVybiB0aGlzLmFjdGl2ZUlkcy5pbmRleE9mKHBhbmVsSWQpID4gLTE7XG5cdH1cblxuXHQvKipcblx0ICogRXhwYW5kcyBhIHBhbmVsIHdpdGggYSBnaXZlbiBpZC5cblx0ICpcblx0ICogSGFzIG5vIGVmZmVjdCBpZiB0aGUgcGFuZWwgaXMgYWxyZWFkeSBleHBhbmRlZCBvciBkaXNhYmxlZC5cblx0ICovXG5cdGV4cGFuZChwYW5lbElkOiBzdHJpbmcpOiB2b2lkIHtcblx0XHR0aGlzLl9jaGFuZ2VPcGVuU3RhdGUodGhpcy5fZmluZFBhbmVsQnlJZChwYW5lbElkKSwgdHJ1ZSk7XG5cdH1cblxuXHQvKipcblx0ICogRXhwYW5kcyBhbGwgcGFuZWxzLCBpZiBgW2Nsb3NlT3RoZXJzXWAgaXMgYGZhbHNlYC5cblx0ICpcblx0ICogSWYgYFtjbG9zZU90aGVyc11gIGlzIGB0cnVlYCwgaXQgd2lsbCBleHBhbmQgdGhlIGZpcnN0IHBhbmVsLCB1bmxlc3MgdGhlcmUgaXMgYWxyZWFkeSBhIHBhbmVsIG9wZW5lZC5cblx0ICovXG5cdGV4cGFuZEFsbCgpOiB2b2lkIHtcblx0XHRpZiAodGhpcy5jbG9zZU90aGVyUGFuZWxzKSB7XG5cdFx0XHRpZiAodGhpcy5hY3RpdmVJZHMubGVuZ3RoID09PSAwICYmIHRoaXMucGFuZWxzLmxlbmd0aCkge1xuXHRcdFx0XHR0aGlzLl9jaGFuZ2VPcGVuU3RhdGUodGhpcy5wYW5lbHMuZmlyc3QsIHRydWUpO1xuXHRcdFx0fVxuXHRcdH0gZWxzZSB7XG5cdFx0XHR0aGlzLnBhbmVscy5mb3JFYWNoKChwYW5lbCkgPT4gdGhpcy5fY2hhbmdlT3BlblN0YXRlKHBhbmVsLCB0cnVlKSk7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIENvbGxhcHNlcyBhIHBhbmVsIHdpdGggdGhlIGdpdmVuIGlkLlxuXHQgKlxuXHQgKiBIYXMgbm8gZWZmZWN0IGlmIHRoZSBwYW5lbCBpcyBhbHJlYWR5IGNvbGxhcHNlZCBvciBkaXNhYmxlZC5cblx0ICovXG5cdGNvbGxhcHNlKHBhbmVsSWQ6IHN0cmluZykge1xuXHRcdHRoaXMuX2NoYW5nZU9wZW5TdGF0ZSh0aGlzLl9maW5kUGFuZWxCeUlkKHBhbmVsSWQpLCBmYWxzZSk7XG5cdH1cblxuXHQvKipcblx0ICogQ29sbGFwc2VzIGFsbCBvcGVuZWQgcGFuZWxzLlxuXHQgKi9cblx0Y29sbGFwc2VBbGwoKSB7XG5cdFx0dGhpcy5wYW5lbHMuZm9yRWFjaCgocGFuZWwpID0+IHtcblx0XHRcdHRoaXMuX2NoYW5nZU9wZW5TdGF0ZShwYW5lbCwgZmFsc2UpO1xuXHRcdH0pO1xuXHR9XG5cblx0LyoqXG5cdCAqIFRvZ2dsZXMgYSBwYW5lbCB3aXRoIHRoZSBnaXZlbiBpZC5cblx0ICpcblx0ICogSGFzIG5vIGVmZmVjdCBpZiB0aGUgcGFuZWwgaXMgZGlzYWJsZWQuXG5cdCAqL1xuXHR0b2dnbGUocGFuZWxJZDogc3RyaW5nKSB7XG5cdFx0Y29uc3QgcGFuZWwgPSB0aGlzLl9maW5kUGFuZWxCeUlkKHBhbmVsSWQpO1xuXHRcdGlmIChwYW5lbCkge1xuXHRcdFx0dGhpcy5fY2hhbmdlT3BlblN0YXRlKHBhbmVsLCAhcGFuZWwuaXNPcGVuKTtcblx0XHR9XG5cdH1cblxuXHRuZ0FmdGVyQ29udGVudENoZWNrZWQoKSB7XG5cdFx0Ly8gYWN0aXZlIGlkIHVwZGF0ZXNcblx0XHRpZiAoaXNTdHJpbmcodGhpcy5hY3RpdmVJZHMpKSB7XG5cdFx0XHR0aGlzLmFjdGl2ZUlkcyA9IHRoaXMuYWN0aXZlSWRzLnNwbGl0KC9cXHMqLFxccyovKTtcblx0XHR9XG5cblx0XHQvLyB1cGRhdGUgcGFuZWxzIG9wZW4gc3RhdGVzXG5cdFx0dGhpcy5wYW5lbHMuZm9yRWFjaCgocGFuZWwpID0+IHtcblx0XHRcdHBhbmVsLmlzT3BlbiA9ICFwYW5lbC5kaXNhYmxlZCAmJiB0aGlzLmFjdGl2ZUlkcy5pbmRleE9mKHBhbmVsLmlkKSA+IC0xO1xuXHRcdH0pO1xuXG5cdFx0Ly8gY2xvc2VPdGhlcnMgdXBkYXRlc1xuXHRcdGlmICh0aGlzLmFjdGl2ZUlkcy5sZW5ndGggPiAxICYmIHRoaXMuY2xvc2VPdGhlclBhbmVscykge1xuXHRcdFx0dGhpcy5fY2xvc2VPdGhlcnModGhpcy5hY3RpdmVJZHNbMF0sIGZhbHNlKTtcblx0XHRcdHRoaXMuX3VwZGF0ZUFjdGl2ZUlkcygpO1xuXHRcdH1cblxuXHRcdC8vIFNldHVwIHRoZSBpbml0aWFsIGNsYXNzZXMgaGVyZVxuXHRcdHRoaXMuX25nWm9uZS5vblN0YWJsZS5waXBlKHRha2UoMSkpLnN1YnNjcmliZSgoKSA9PiB7XG5cdFx0XHR0aGlzLnBhbmVscy5mb3JFYWNoKChwYW5lbCkgPT4ge1xuXHRcdFx0XHRjb25zdCBwYW5lbEVsZW1lbnQgPSBwYW5lbC5wYW5lbERpdjtcblx0XHRcdFx0aWYgKHBhbmVsRWxlbWVudCkge1xuXHRcdFx0XHRcdGlmICghcGFuZWwuaW5pdENsYXNzRG9uZSkge1xuXHRcdFx0XHRcdFx0cGFuZWwuaW5pdENsYXNzRG9uZSA9IHRydWU7XG5cdFx0XHRcdFx0XHRuZ2JSdW5UcmFuc2l0aW9uKHRoaXMuX25nWm9uZSwgcGFuZWxFbGVtZW50LCBuZ2JDb2xsYXBzaW5nVHJhbnNpdGlvbiwge1xuXHRcdFx0XHRcdFx0XHRhbmltYXRpb246IGZhbHNlLFxuXHRcdFx0XHRcdFx0XHRydW5uaW5nVHJhbnNpdGlvbjogJ2NvbnRpbnVlJyxcblx0XHRcdFx0XHRcdFx0Y29udGV4dDogeyBkaXJlY3Rpb246IHBhbmVsLmlzT3BlbiA/ICdzaG93JyA6ICdoaWRlJywgZGltZW5zaW9uOiAnaGVpZ2h0JyB9LFxuXHRcdFx0XHRcdFx0fSk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdC8vIENsYXNzZXMgbXVzdCBiZSBpbml0aWFsaXplZCBuZXh0IHRpbWUgaXQgd2lsbCBiZSBpbiB0aGUgZG9tXG5cdFx0XHRcdFx0cGFuZWwuaW5pdENsYXNzRG9uZSA9IGZhbHNlO1xuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblx0XHR9KTtcblx0fVxuXG5cdHByaXZhdGUgX2NoYW5nZU9wZW5TdGF0ZShwYW5lbDogTmdiUGFuZWwgfCBudWxsLCBuZXh0U3RhdGU6IGJvb2xlYW4pIHtcblx0XHRpZiAocGFuZWwgIT0gbnVsbCAmJiAhcGFuZWwuZGlzYWJsZWQgJiYgcGFuZWwuaXNPcGVuICE9PSBuZXh0U3RhdGUpIHtcblx0XHRcdGxldCBkZWZhdWx0UHJldmVudGVkID0gZmFsc2U7XG5cblx0XHRcdHRoaXMucGFuZWxDaGFuZ2UuZW1pdCh7XG5cdFx0XHRcdHBhbmVsSWQ6IHBhbmVsLmlkLFxuXHRcdFx0XHRuZXh0U3RhdGU6IG5leHRTdGF0ZSxcblx0XHRcdFx0cHJldmVudERlZmF1bHQ6ICgpID0+IHtcblx0XHRcdFx0XHRkZWZhdWx0UHJldmVudGVkID0gdHJ1ZTtcblx0XHRcdFx0fSxcblx0XHRcdH0pO1xuXG5cdFx0XHRpZiAoIWRlZmF1bHRQcmV2ZW50ZWQpIHtcblx0XHRcdFx0cGFuZWwuaXNPcGVuID0gbmV4dFN0YXRlO1xuXHRcdFx0XHRwYW5lbC50cmFuc2l0aW9uUnVubmluZyA9IHRydWU7XG5cblx0XHRcdFx0aWYgKG5leHRTdGF0ZSAmJiB0aGlzLmNsb3NlT3RoZXJQYW5lbHMpIHtcblx0XHRcdFx0XHR0aGlzLl9jbG9zZU90aGVycyhwYW5lbC5pZCk7XG5cdFx0XHRcdH1cblx0XHRcdFx0dGhpcy5fdXBkYXRlQWN0aXZlSWRzKCk7XG5cdFx0XHRcdHRoaXMuX3J1blRyYW5zaXRpb25zKHRoaXMuYW5pbWF0aW9uKTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHRwcml2YXRlIF9jbG9zZU90aGVycyhwYW5lbElkOiBzdHJpbmcsIGVuYWJsZVRyYW5zaXRpb24gPSB0cnVlKSB7XG5cdFx0dGhpcy5wYW5lbHMuZm9yRWFjaCgocGFuZWwpID0+IHtcblx0XHRcdGlmIChwYW5lbC5pZCAhPT0gcGFuZWxJZCAmJiBwYW5lbC5pc09wZW4pIHtcblx0XHRcdFx0cGFuZWwuaXNPcGVuID0gZmFsc2U7XG5cdFx0XHRcdHBhbmVsLnRyYW5zaXRpb25SdW5uaW5nID0gZW5hYmxlVHJhbnNpdGlvbjtcblx0XHRcdH1cblx0XHR9KTtcblx0fVxuXG5cdHByaXZhdGUgX2ZpbmRQYW5lbEJ5SWQocGFuZWxJZDogc3RyaW5nKTogTmdiUGFuZWwgfCBudWxsIHtcblx0XHRyZXR1cm4gdGhpcy5wYW5lbHMuZmluZCgocCkgPT4gcC5pZCA9PT0gcGFuZWxJZCkgfHwgbnVsbDtcblx0fVxuXG5cdHByaXZhdGUgX3VwZGF0ZUFjdGl2ZUlkcygpIHtcblx0XHR0aGlzLmFjdGl2ZUlkcyA9IHRoaXMucGFuZWxzLmZpbHRlcigocGFuZWwpID0+IHBhbmVsLmlzT3BlbiAmJiAhcGFuZWwuZGlzYWJsZWQpLm1hcCgocGFuZWwpID0+IHBhbmVsLmlkKTtcblx0fVxuXG5cdHByaXZhdGUgX3J1blRyYW5zaXRpb25zKGFuaW1hdGlvbjogYm9vbGVhbikge1xuXHRcdC8vIGRldGVjdENoYW5nZXMgaXMgcGVyZm9ybWVkIHRvIGVuc3VyZSB0aGF0IGFsbCBwYW5lbHMgYXJlIGluIHRoZSBkb20gKHZpYSB0cmFuc2l0aW9uUnVubmluZyA9IHRydWUpXG5cdFx0Ly8gYmVmb3JlIHN0YXJ0aW5nIHRoZSBhbmltYXRpb25cblx0XHR0aGlzLl9jaGFuZ2VEZXRlY3Rvci5kZXRlY3RDaGFuZ2VzKCk7XG5cblx0XHR0aGlzLnBhbmVscy5mb3JFYWNoKChwYW5lbCkgPT4ge1xuXHRcdFx0Ly8gV2hlbiBwYW5lbC50cmFuc2l0aW9uUnVubmluZyBpcyB0cnVlLCB0aGUgdHJhbnNpdGlvbiBuZWVkcyB0byBiZSBzdGFydGVkIE9SIHJldmVyc2VkLFxuXHRcdFx0Ly8gVGhlIGRpcmVjdGlvbiAoc2hvdyBvciBoaWRlKSBpcyBjaG9vc2VuIGJ5IGVhY2ggcGFuZWwuaXNPcGVuIHN0YXRlXG5cdFx0XHRpZiAocGFuZWwudHJhbnNpdGlvblJ1bm5pbmcpIHtcblx0XHRcdFx0Y29uc3QgcGFuZWxFbGVtZW50ID0gcGFuZWwucGFuZWxEaXY7XG5cdFx0XHRcdG5nYlJ1blRyYW5zaXRpb24odGhpcy5fbmdab25lLCBwYW5lbEVsZW1lbnQhLCBuZ2JDb2xsYXBzaW5nVHJhbnNpdGlvbiwge1xuXHRcdFx0XHRcdGFuaW1hdGlvbixcblx0XHRcdFx0XHRydW5uaW5nVHJhbnNpdGlvbjogJ3N0b3AnLFxuXHRcdFx0XHRcdGNvbnRleHQ6IHsgZGlyZWN0aW9uOiBwYW5lbC5pc09wZW4gPyAnc2hvdycgOiAnaGlkZScsIGRpbWVuc2lvbjogJ2hlaWdodCcgfSxcblx0XHRcdFx0fSkuc3Vic2NyaWJlKCgpID0+IHtcblx0XHRcdFx0XHRwYW5lbC50cmFuc2l0aW9uUnVubmluZyA9IGZhbHNlO1xuXHRcdFx0XHRcdGNvbnN0IHsgaWQgfSA9IHBhbmVsO1xuXHRcdFx0XHRcdGlmIChwYW5lbC5pc09wZW4pIHtcblx0XHRcdFx0XHRcdHBhbmVsLnNob3duLmVtaXQoKTtcblx0XHRcdFx0XHRcdHRoaXMuc2hvd24uZW1pdChpZCk7XG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdHBhbmVsLmhpZGRlbi5lbWl0KCk7XG5cdFx0XHRcdFx0XHR0aGlzLmhpZGRlbi5lbWl0KGlkKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0pO1xuXHRcdFx0fVxuXHRcdH0pO1xuXHR9XG59XG5cbi8qKlxuICogQSBkaXJlY3RpdmUgdG8gcHV0IG9uIGEgYnV0dG9uIHRoYXQgdG9nZ2xlcyBwYW5lbCBvcGVuaW5nIGFuZCBjbG9zaW5nLlxuICpcbiAqIFRvIGJlIHVzZWQgaW5zaWRlIHRoZSBbYE5nYlBhbmVsSGVhZGVyYF0oIy9jb21wb25lbnRzL2FjY29yZGlvbi9hcGkjTmdiUGFuZWxIZWFkZXIpXG4gKlxuICogQHNpbmNlIDQuMS4wXG4gKi9cbkBEaXJlY3RpdmUoe1xuXHRzZWxlY3RvcjogJ2J1dHRvbltuZ2JQYW5lbFRvZ2dsZV0nLFxuXHRob3N0OiB7XG5cdFx0dHlwZTogJ2J1dHRvbicsXG5cdFx0J1tkaXNhYmxlZF0nOiAncGFuZWwuZGlzYWJsZWQnLFxuXHRcdCdbY2xhc3MuY29sbGFwc2VkXSc6ICchcGFuZWwuaXNPcGVuJyxcblx0XHQnW2F0dHIuYXJpYS1leHBhbmRlZF0nOiAncGFuZWwuaXNPcGVuJyxcblx0XHQnW2F0dHIuYXJpYS1jb250cm9sc10nOiAncGFuZWwuaWQnLFxuXHRcdCcoY2xpY2spJzogJ2FjY29yZGlvbi50b2dnbGUocGFuZWwuaWQpJyxcblx0fSxcbn0pXG5leHBvcnQgY2xhc3MgTmdiUGFuZWxUb2dnbGUge1xuXHRzdGF0aWMgbmdBY2NlcHRJbnB1dFR5cGVfbmdiUGFuZWxUb2dnbGU6IE5nYlBhbmVsIHwgJyc7XG5cblx0QElucHV0KClcblx0c2V0IG5nYlBhbmVsVG9nZ2xlKHBhbmVsOiBOZ2JQYW5lbCkge1xuXHRcdGlmIChwYW5lbCkge1xuXHRcdFx0dGhpcy5wYW5lbCA9IHBhbmVsO1xuXHRcdH1cblx0fVxuXG5cdGNvbnN0cnVjdG9yKHB1YmxpYyBhY2NvcmRpb246IE5nYkFjY29yZGlvbiwgQE9wdGlvbmFsKCkgQEhvc3QoKSBwdWJsaWMgcGFuZWw6IE5nYlBhbmVsKSB7fVxufVxuIl19