UNPKG

@visa/nova-angular

Version:

Visa Product Design System Nova Angular library

362 lines 53.4 kB
/** * Copyright (c) 2025 Visa, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * **/ import { coerceBooleanProperty } from '@angular/cdk/coercion'; import { ContentChild, ContentChildren, Directive, ElementRef, EventEmitter, HostBinding, HostListener, Input, Output, QueryList, Renderer2 } from '@angular/core'; import { AppReadyService } from '../_utilities/services/app-stable-check.service'; import { UUIDService } from '../_utilities/services/uuid.service'; import { AccordionHeadingDirective } from '../accordion-heading/accordion-heading.directive'; import { ButtonDirective } from '../button/button.directive'; import { TabItemDisclosureDirective } from '../disclosure-tab-item/disclosure-tab-item.directive'; import { DropdownListDirective } from '../dropdown-list/dropdown-list.directive'; import { DropdownMenuDirective } from '../dropdown-menu/dropdown-menu.directive'; import { FloatingUIElementDirective } from '../floating-ui-element/floating-ui-element.directive'; import { FloatingUITriggerDirective } from '../floating-ui-trigger/floating-ui-trigger.directive'; import { FloatingUIPlacements, FloatingUIVisibility } from '../floating-ui/floating-ui.constants'; import { FloatingUIService } from '../floating-ui/floating-ui.service'; import { IconToggleComponent } from '../icon-toggle/icon-toggle.component'; import { IconToggleDirective } from '../icon-toggle/icon-toggle.directive'; import { ListboxDirective } from '../listbox/listbox.directive'; import { NovaLibService } from '../nova-lib.service'; import { TooltipDirective } from '../tooltip/tooltip.directive'; import * as i0 from "@angular/core"; import * as i1 from "../floating-ui/floating-ui.service"; import * as i2 from "../_utilities/services/uuid.service"; import * as i3 from "../nova-lib.service"; import * as i4 from "../_utilities/services/app-stable-check.service"; export class FloatingUIContainer { /** * Provides custom class&#40;es&#41; for custom styling. */ get class() { return this._class; } set class(value) { this._class = value; } get hostClasses() { return this.class; } /** @ignore */ get isShown() { return this._isShown; } set isShown(value) { this._isShown = coerceBooleanProperty(value); } /** * Placement of floating content relevant to triggering element. * @default FloatingUIPlacements.BOTTOM_START * @see 'FloatingUIPlacements'. */ get placement() { return this._placement; } set placement(value) { this._placement = value; } /** * Middleware for FloatingUIService. * @default [ offset(2), flip(), shift() ] for tooltip <br /> * @default [ offset(0), flip(), shift() ] for combobox <br /> * @see [Floating UI](https://floating-ui.com/docs/middleware) for options. */ get middleware() { return this._middleware; } set middleware(value) { this._middleware = value; } /** * Events array for FloatingUIService. <br /> * This array specifies whether to show or hide the floating element on a given UIEvent. <br /> * This should be an array of [UIEvent, FloatingUIVisibility]. * @default [ [new UIEvent('mouseenter'), FloatingUIVisibility.SHOW], <br /> [new UIEvent('mouseleave'), FloatingUIVisibility.HIDE], <br /> [new UIEvent('focus'), FloatingUIVisibility.SHOW], <br /> [new UIEvent('blur'), FloatingUIVisibility.HIDE] <br />] for tooltip * @default [ [new UIEvent('click')] ] for dropdown-menu and floating-ui-element * @default [] Ie. events are removed for combobox. */ get eventsArray() { return this._eventsArray; } set eventsArray(value) { this._eventsArray = value; } /** * Closes the menu on item is click/select when true. <br> * If <code>multiselect</code> is set to <code>true</code>, it will not take effect.<br> * @default true */ get closeOnClick() { return this._closeOnClick; } set closeOnClick(value) { this._closeOnClick = coerceBooleanProperty(value); } // this is an angular-specific override. Spacing between dropdown-menu and button/trigger // is handled within floating-ui.service get hostMarginBlockStart() { return '0'; } constructor(el, floatingUIService, uuidService, novaLibService, renderer, appReadyService) { this.el = el; this.floatingUIService = floatingUIService; this.uuidService = uuidService; this.novaLibService = novaLibService; this.renderer = renderer; this.appReadyService = appReadyService; this._isCombobox = false; this._tooltipDefaultEvents = [ [new UIEvent('mouseenter'), FloatingUIVisibility.SHOW], [new UIEvent('mouseleave'), FloatingUIVisibility.HIDE], [new UIEvent('focus'), FloatingUIVisibility.SHOW], [new UIEvent('blur'), FloatingUIVisibility.HIDE] ]; this._dropdownMenuDefaultEvents = [[new UIEvent('click')]]; this._class = ''; // override the standard class attr with a new one. this._isShown = false; this._placement = FloatingUIPlacements.BOTTOM_START; this._closeOnClick = true; /** * Emits whether or not the floating UI element is visible. */ this.floatingUIToggled = new EventEmitter(); this._tabPressed = false; } clickOut(event) { // listen for document click and close menu if click is outside of component if (this.appReadyService.isBrowserAndDomAvailable() && this.isShown && !this.el.nativeElement.contains(event.target)) { this.floatingUIService.hidefloatingUI(); } } tab(event) { if (event.key === 'Tab') { // used in focusout function this._tabPressed = true; } } focusout(event) { if (this._tabPressed) { // if focus out is a result of tabbing out of this component, hide the floating UI if (event.relatedTarget && !this.el.nativeElement.contains(event.relatedTarget)) { this.floatingUIService.hidefloatingUI(); } this._tabPressed = false; } } ngAfterContentInit() { let floatingElem = null; let _toggleIcon; let _toggleIconComponent; const toggleInChildContainer = this.containers.some((container) => container.toggleIcon === this.toggleIcon) || this.disclosureTabs.some((tab) => tab.button.toggleIcon === this.toggleIcon) || this.accordionHeadings.some((heading) => heading.hostButton?.toggleIcon === this.toggleIcon || heading._buttonHeading?.toggleIcon === this.toggleIcon); const toggleComponentInChildContainer = this.containers.some((container) => container.toggleIconComponent === this.toggleIconComponent) || this.disclosureTabs.some((tab) => tab.button.toggleIconComponent === this.toggleIconComponent) || this.accordionHeadings.some((heading) => heading.hostButton?.toggleIconComponent === this.toggleIconComponent || heading._buttonHeading?.toggleIconComponent === this.toggleIconComponent); if (this.toggleIcon && !toggleInChildContainer) { _toggleIcon = this.toggleIcon; _toggleIcon.icon.icon = this.isShown ? _toggleIcon.expandedIcon : _toggleIcon.collapsedIcon; } else if (this.toggleIconComponent && !toggleComponentInChildContainer) { _toggleIconComponent = this.toggleIconComponent; _toggleIconComponent._floatingUIToggle = true; _toggleIconComponent.rotated = this.isShown; } const tooltipInChildContainer = this.containers.some((container) => container.tooltip === this.tooltip); const menuInChildContainer = this.containers.some((container) => container.menu === this.menu); const dropdownInChildContainer = this.containers.some((container) => container.genericDropdown === this.genericDropdown); if (this.menu && !menuInChildContainer) { floatingElem = this.menu; this.renderer.setStyle(this.menu.el.nativeElement, 'position', 'absolute'); this.trigger._triggersDropdownMenu = true; floatingElem.id = this.menu.id ? this.menu.id : this.uuidService.getUUID('v-floating-'); this.menu._isShown = this.isShown; this.eventsArray = this.eventsArray ? this.eventsArray : this._dropdownMenuDefaultEvents; this.setUpListItems(); } else if (this.tooltip && !tooltipInChildContainer) { floatingElem = this.tooltip; this.trigger._triggersTooltip = true; this.eventsArray = this.eventsArray ? this.eventsArray : this._tooltipDefaultEvents; } else if (this.genericDropdown && !dropdownInChildContainer) { floatingElem = this.genericDropdown; this.renderer.setStyle(this.genericDropdown.el.nativeElement, 'position', 'absolute'); this.eventsArray = this.eventsArray ? this.eventsArray : this._dropdownMenuDefaultEvents; this.setUpListItems(); } if (this.trigger?.el && floatingElem?.el) { floatingElem.id = floatingElem.id ? floatingElem.id : this.uuidService.getUUID('v-floating-'); this.trigger._floatingElemID = floatingElem.id; if (this.tooltip?.arrow) { this.floatingUIService.customizeFloatingUI(this.placement, this.middleware, this.tooltip.display || 'block', this.tooltip.arrow); } else { if (!this.middleware && this._isCombobox) { this.middleware = this.floatingUIService.comboboxMiddleware; } this.floatingUIService.customizeFloatingUI(this.placement, this.middleware); } this.floatingUIService.setUpfloatingUI(this.trigger.el, floatingElem.el, this.eventsArray); } this.floatingUIService.isShownEmitter.subscribe((isShown) => { if (this.trigger) this.trigger._isShown = isShown; if (this.menu) this.menu._isShown = isShown; if (this.accordionHeadings.length === 0) { if (_toggleIcon) { _toggleIcon.icon.icon = isShown ? _toggleIcon.expandedIcon : _toggleIcon.collapsedIcon; } else if (_toggleIconComponent) { _toggleIconComponent.rotated = isShown; } } this.isShown = isShown; this.floatingUIToggled.emit(isShown); }); } setUpListItems() { const isMultiSelect = this.listbox?.multiselect ? true : false; if (this.closeOnClick && !isMultiSelect) { if (this.menu) { // this is for v-dropdown-menu let children; if (this.dropdownItems.length > 0) { // using dropdownItems children = this.dropdownItems.length > 0 ? this.dropdownItems : null; if (children) { children.forEach((item) => { if (!item.el.nativeElement.disabled) { this.renderer.listen(item.el.nativeElement, 'click', (event) => { this.floatingUIService.hidefloatingUI(); }); } }); } } else { // not using dropdownItems, gather all children, for buttons, disregard the triggering button children = this.buttons.length > 1 ? this.buttons : this.listbox?.listItems.length > 0 ? this.listbox.listItems : null; if (children) { children.forEach((child) => { // don't call for the trigger button if (child.el.nativeElement === this.trigger?.el.nativeElement) return; child.clicked.subscribe(() => { this.floatingUIService.hidefloatingUI(); }); }); } } } else if (this.listbox) { // this is for v-combobox this.listItemClose(); this.listbox.listItems.changes.subscribe(() => { this.listItemClose(); }); } } } listItemClose() { this.listbox.listItems.forEach((item) => { item.clicked.subscribe(() => { this.floatingUIService.hidefloatingUI(); }); }); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FloatingUIContainer, deps: [{ token: i0.ElementRef }, { token: i1.FloatingUIService }, { token: i2.UUIDService }, { token: i3.NovaLibService }, { token: i0.Renderer2 }, { token: i4.AppReadyService }], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: FloatingUIContainer, isStandalone: true, selector: "[v-floating-ui-container], [v-combobox]", inputs: { class: "class", isShown: "isShown", placement: "placement", middleware: "middleware", eventsArray: "eventsArray", closeOnClick: "closeOnClick" }, outputs: { floatingUIToggled: "floatingUIToggled" }, host: { listeners: { "document:click": "clickOut($event)", "document:keydown": "tab($event)", "focusout": "focusout($event)" }, properties: { "class": "this.hostClasses", "style.--v-dropdown-menu-surface-margin-block-start": "this.hostMarginBlockStart" } }, providers: [FloatingUIService], queries: [{ propertyName: "menu", first: true, predicate: DropdownMenuDirective, descendants: true }, { propertyName: "tooltip", first: true, predicate: TooltipDirective, descendants: true }, { propertyName: "genericDropdown", first: true, predicate: FloatingUIElementDirective, descendants: true }, { propertyName: "trigger", first: true, predicate: FloatingUITriggerDirective, descendants: true }, { propertyName: "toggleIcon", first: true, predicate: IconToggleDirective, descendants: true }, { propertyName: "toggleIconComponent", first: true, predicate: IconToggleComponent, descendants: true }, { propertyName: "listbox", first: true, predicate: ListboxDirective, descendants: true }, { propertyName: "containers", predicate: FloatingUIContainer, descendants: true }, { propertyName: "disclosureTabs", predicate: TabItemDisclosureDirective, descendants: true }, { propertyName: "buttons", predicate: ButtonDirective, descendants: true }, { propertyName: "dropdownItems", predicate: DropdownListDirective, descendants: true }, { propertyName: "accordionHeadings", predicate: AccordionHeadingDirective, descendants: true }], ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FloatingUIContainer, decorators: [{ type: Directive, args: [{ standalone: true, selector: '[v-floating-ui-container], [v-combobox]', providers: [FloatingUIService] }] }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i1.FloatingUIService }, { type: i2.UUIDService }, { type: i3.NovaLibService }, { type: i0.Renderer2 }, { type: i4.AppReadyService }], propDecorators: { containers: [{ type: ContentChildren, args: [FloatingUIContainer, { descendants: true }] }], disclosureTabs: [{ type: ContentChildren, args: [TabItemDisclosureDirective, { descendants: true }] }], menu: [{ type: ContentChild, args: [DropdownMenuDirective] }], tooltip: [{ type: ContentChild, args: [TooltipDirective] }], genericDropdown: [{ type: ContentChild, args: [FloatingUIElementDirective] }], trigger: [{ type: ContentChild, args: [FloatingUITriggerDirective] }], toggleIcon: [{ type: ContentChild, args: [IconToggleDirective] }], toggleIconComponent: [{ type: ContentChild, args: [IconToggleComponent] }], listbox: [{ type: ContentChild, args: [ListboxDirective] }], buttons: [{ type: ContentChildren, args: [ButtonDirective, { descendants: true }] }], dropdownItems: [{ type: ContentChildren, args: [DropdownListDirective, { descendants: true }] }], accordionHeadings: [{ type: ContentChildren, args: [AccordionHeadingDirective, { descendants: true }] }], class: [{ type: Input }], hostClasses: [{ type: HostBinding, args: ['class'] }], isShown: [{ type: Input }], placement: [{ type: Input }], middleware: [{ type: Input }], eventsArray: [{ type: Input }], closeOnClick: [{ type: Input }], floatingUIToggled: [{ type: Output }], hostMarginBlockStart: [{ type: HostBinding, args: ['style.--v-dropdown-menu-surface-margin-block-start'] }], clickOut: [{ type: HostListener, args: ['document:click', ['$event']] }], tab: [{ type: HostListener, args: ['document:keydown', ['$event']] }], focusout: [{ type: HostListener, args: ['focusout', ['$event']] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmxvYXRpbmctdWktY29udGFpbmVyLmRpcmVjdGl2ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL2xpYnMvbm92YS1saWIvc3JjL2xpYi9mbG9hdGluZy11aS1jb250YWluZXIvZmxvYXRpbmctdWktY29udGFpbmVyLmRpcmVjdGl2ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7O0lBZUk7QUFDSixPQUFPLEVBQWdCLHFCQUFxQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDNUUsT0FBTyxFQUVMLFlBQVksRUFDWixlQUFlLEVBQ2YsU0FBUyxFQUNULFVBQVUsRUFDVixZQUFZLEVBQ1osV0FBVyxFQUNYLFlBQVksRUFDWixLQUFLLEVBQ0wsTUFBTSxFQUNOLFNBQVMsRUFDVCxTQUFTLEVBQ1YsTUFBTSxlQUFlLENBQUM7QUFFdkIsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLGlEQUFpRCxDQUFDO0FBQ2xGLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQztBQUNsRSxPQUFPLEVBQUUseUJBQXlCLEVBQUUsTUFBTSxrREFBa0QsQ0FBQztBQUM3RixPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDN0QsT0FBTyxFQUFFLDBCQUEwQixFQUFFLE1BQU0sc0RBQXNELENBQUM7QUFFbEcsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sMENBQTBDLENBQUM7QUFDakYsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sMENBQTBDLENBQUM7QUFDakYsT0FBTyxFQUFFLDBCQUEwQixFQUFFLE1BQU0sc0RBQXNELENBQUM7QUFDbEcsT0FBTyxFQUFFLDBCQUEwQixFQUFFLE1BQU0sc0RBQXNELENBQUM7QUFDbEcsT0FBTyxFQUNMLG9CQUFvQixFQUNwQixvQkFBb0IsRUFFckIsTUFBTSxzQ0FBc0MsQ0FBQztBQUM5QyxPQUFPLEVBQUUsaUJBQWlCLEVB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QUFTO3NCQURaLEtBQUs7Z0JBZ0JGLFVBQVU7c0JBRGIsS0FBSztnQkFrQkYsV0FBVztzQkFEZCxLQUFLO2dCQWVGLFlBQVk7c0JBRGYsS0FBSztnQkFZSSxpQkFBaUI7c0JBQTFCLE1BQU07Z0JBS0gsb0JBQW9CO3NCQUR2QixXQUFXO3VCQUFDLG9EQUFvRDtnQkFlakUsUUFBUTtzQkFEUCxZQUFZO3VCQUFDLGdCQUFnQixFQUFFLENBQUMsUUFBUSxDQUFDO2dCQWMxQyxHQUFHO3NCQURGLFlBQVk7dUJBQUMsa0JBQWtCLEVBQUUsQ0FBQyxRQUFRLENBQUM7Z0JBUzVDLFFBQVE7c0JBRFAsWUFBWTt1QkFBQyxVQUFVLEVBQUUsQ0FBQyxRQUFRLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqICAgICAgICAgICAgICBDb3B5cmlnaHQgKGMpIDIwMjUgVmlzYSwgSW5jLlxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICoqL1xuaW1wb3J0IHsgQm9vbGVhbklucHV0LCBjb2VyY2VCb29sZWFuUHJvcGVydHkgfSBmcm9tICdAYW5ndWxhci9jZGsvY29lcmNpb24nO1xuaW1wb3J0IHtcbiAgQWZ0ZXJDb250ZW50SW5pdCxcbiAgQ29udGVudENoaWxkLFxuICBDb250ZW50Q2hpbGRyZW4sXG4gIERpcmVjdGl2ZSxcbiAgRWxlbWVudFJlZixcbiAgRXZlbnRFbWl0dGVyLFxuICBIb3N0QmluZGluZyxcbiAgSG9zdExpc3RlbmVyLFxuICBJbnB1dCxcbiAgT3V0cHV0LFxuICBRdWVyeUxpc3QsXG4gIFJlbmRlcmVyMlxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IE1pZGRsZXdhcmUgfSBmcm9tICdAZmxvYXRpbmctdWkvZG9tJztcbmltcG9ydCB7IEFwcFJlYWR5U2VydmljZSB9IGZyb20gJy4uL191dGlsaXRpZXMvc2VydmljZXMvYXBwLXN0YWJsZS1jaGVjay5zZXJ2aWNlJztcbmltcG9ydCB7IFVVSURTZXJ2aWNlIH0gZnJvbSAnLi4vX3V0aWxpdGllcy9zZXJ2aWNlcy91dWlkLnNlcnZpY2UnO1xuaW1wb3J0IHsgQWNjb3JkaW9uSGVhZGluZ0RpcmVjdGl2ZSB9IGZyb20gJy4uL2FjY29yZGlvbi1oZWFkaW5nL2FjY29yZGlvbi1oZWFkaW5nLmRpcmVjdGl2ZSc7XG5pbXBvcnQgeyBCdXR0b25EaXJlY3RpdmUgfSBmcm9tICcuLi9idXR0b24vYnV0dG9uLmRpcmVjdGl2ZSc7XG5pbXBvcnQgeyBUYWJJdGVtRGlzY2xvc3VyZURpcmVjdGl2ZSB9IGZyb20gJy4uL2Rpc2Nsb3N1cmUtdGFiLWl0ZW0vZGlzY2xvc3VyZS10YWItaXRlbS5kaXJlY3RpdmUnO1xuaW1wb3J0IHsgRHJvcGRvd25JdGVtRGlyZWN0aXZlIH0gZnJvbSAnLi4vZHJvcGRvd24taXRlbS9kcm9wZG93bi1pdGVtLmRpcmVjdGl2ZSc7XG5pbXBvcnQgeyBEcm9wZG93bkxpc3REaXJlY3RpdmUgfSBmcm9tICcuLi9kcm9wZG93bi1saXN0L2Ryb3Bkb3duLWxpc3QuZGlyZWN0aXZlJztcbmltcG9ydCB7IERyb3Bkb3duTWVudURpcmVjdGl2ZSB9IGZyb20gJy4uL2Ryb3Bkb3duLW1lbnUvZHJvcGRvd24tbWVudS5kaXJlY3RpdmUnO1xuaW1wb3J0IHsgRmxvYXRpbmdVSUVsZW1lbnREaXJlY3RpdmUgfSBmcm9tICcuLi9mbG9hdGluZy11aS1lbGVtZW50L2Zsb2F0aW5nLXVpLWVsZW1lbnQuZGlyZWN0aXZlJztcbmltcG9ydCB7IEZsb2F0aW5nVUlUcmlnZ2VyRGlyZWN0aXZlIH0gZnJvbSAnLi4vZmxvYXRpbmctdWktdHJpZ2dlci9mbG9hdGluZy11aS10cmlnZ2VyLmRpcmVjdGl2ZSc7XG5pbXBvcnQge1xuICBGbG9hdGluZ1VJUGxhY2VtZW50cyxcbiAgRmxvYXRpbmdVSVZpc2liaWxpdHksXG4gIFVJRXZlbnRWaXNpYmlsaXR5UGFpclxufSBmcm9tICcuLi9mbG9hdGluZy11aS9mbG9hdGluZy11aS5jb25zdGFudHMnO1xuaW1wb3J0IHsgRmxvYXRpbmdVSVNlcnZpY2UgfSBmcm9tICcuLi9mbG9hdGluZy11aS9mbG9hdGluZy11aS5zZXJ2aWNlJztcbmltcG9ydCB7IEljb25Ub2dnbGVDb21wb25lbnQgfSBmcm9tICcuLi9pY29uLXRvZ2dsZS9pY29uLXRvZ2dsZS5jb21wb25lbnQnO1xuaW1wb3J0IHsgSWNvblRvZ2dsZURpcmVjdGl2ZSB9IGZyb20gJy4uL2ljb24tdG9nZ2xlL2ljb24tdG9nZ2xlLmRpcmVjdGl2ZSc7XG5pbXBvcnQgeyBMaXN0Ym94SXRlbUNvbXBvbmVudCB9IGZyb20gJy4uL2xpc3Rib3gtaXRlbS9saXN0Ym94LWl0ZW0uY29tcG9uZW50JztcbmltcG9ydCB7IExpc3Rib3hEaXJlY3RpdmUgfSBmcm9tICcuLi9saXN0Ym94L2xpc3Rib3guZGlyZWN0aXZlJztcbmltcG9ydCB7IE5vdmFMaWJTZXJ2aWNlIH0gZnJvbSAnLi4vbm92YS1saWIuc2VydmljZSc7XG5pbXBvcnQgeyBUb29sdGlwRGlyZWN0aXZlIH0gZnJvbSAnLi4vdG9vbHRpcC90b29sdGlwLmRpcmVjdGl2ZSc7XG5cbkBEaXJlY3RpdmUoe1xuICBzdGFuZGFsb25lOiB0cnVlLFxuICBzZWxlY3RvcjogJ1t2LWZsb2F0aW5nLXVpLWNvbnRhaW5lcl0sIFt2LWNvbWJvYm94XScsXG4gIHByb3ZpZGVyczogW0Zsb2F0aW5nVUlTZXJ2aWNlXVxufSlcbmV4cG9ydCBjbGFzcyBGbG9hdGluZ1VJQ29udGFpbmVyIGltcGxlbWVudHMgQWZ0ZXJDb250ZW50SW5pdCB7XG4gIEBDb250ZW50Q2hpbGRyZW4oRmxvYXRpbmdVSUNvbnRhaW5lciwgeyBkZXNjZW5kYW50czogdHJ1ZSB9KSBjb250YWluZXJzOiBRdWVyeUxpc3Q8RmxvYXRpbmdVSUNvbnRhaW5lcj47XG4gIEBDb250ZW50Q2hpbGRyZW4oVGFiSXRlbURpc2Nsb3N1cmVEaXJlY3RpdmUsIHsgZGVzY2VuZGFudHM6IHRydWUgfSlcbiAgZGlzY2xvc3VyZVRhYnM6IFF1ZXJ5TGlzdDxUYWJJdGVtRGlzY2xvc3VyZURpcmVjdGl2ZT47XG4gIEBDb250ZW50Q2hpbGQoRHJvcGRvd25NZW51RGlyZWN0aXZlKSBtZW51OiBEcm9wZG93bk1lbnVEaXJlY3RpdmU7XG4gIEBDb250ZW50Q2hpbGQoVG9vbHRpcERpcmVjdGl2ZSkgdG9vbHRpcDogVG9vbHRpcERpcmVjdGl2ZTtcbiAgQENvbnRlbnRDaGlsZChGbG9hdGluZ1VJRWxlbWVudERpcmVjdGl2ZSlcbiAgZ2VuZXJpY0Ryb3Bkb3duOiBGbG9hdGluZ1VJRWxlbWVudERpcmVjdGl2ZTtcbiAgQENvbnRlbnRDaGlsZChGbG9hdGluZ1VJVHJpZ2dlckRpcmVjdGl2ZSkgdHJpZ2dlcjogRmxvYXRpbmdVSVRyaWdnZXJEaXJlY3RpdmU7XG4gIEBDb250ZW50Q2hpbGQoSWNvblRvZ2dsZURpcmVjdGl2ZSkgdG9nZ2xlSWNvbjogSWNvblRvZ2dsZURpcmVjdGl2ZTtcbiAgQENvbnRlbnRDaGlsZChJY29uVG9nZ2xlQ29tcG9uZW50KSB0b2dnbGVJY29uQ29tcG9uZW50OiBJY29uVG9nZ2xlQ29tcG9uZW50O1xuICBAQ29udGVudENoaWxkKExpc3Rib3hEaXJlY3RpdmUpIGxpc3Rib3g6IExpc3Rib3hEaXJlY3RpdmU7XG4gIEBDb250ZW50Q2hpbGRyZW4oQnV0dG9uRGlyZWN0aXZlLCB7IGRlc2NlbmRhbnRzOiB0cnVlIH0pIGJ1dHRvbnM6IFF1ZXJ5TGlzdDxCdXR0b25EaXJlY3RpdmU+O1xuICBAQ29udGVudENoaWxkcmVuKERyb3Bkb3duTGlzdERpcmVjdGl2ZSwgeyBkZXNjZW5kYW50czogdHJ1ZSB9KSBkcm9wZG93bkl0ZW1zOiBRdWVyeUxpc3Q8RHJvcGRvd25JdGVtRGlyZWN0aXZlPjtcbiAgQENvbnRlbnRDaGlsZHJlbihBY2NvcmRpb25IZWFkaW5nRGlyZWN0aXZlLCB7IGRlc2NlbmRhbnRzOiB0cnVlIH0pIGFjY29yZGlvbkhlYWRpbmdzOiBRdWVyeUxpc3Q8QWNjb3JkaW9uSGVhZGluZ0RpcmVjdGl2ZT47XG5cbiAgX2lzQ29tYm9ib3g6IGJvb2xlYW4gPSBmYWxzZTtcbiAgZHJvcGRvd25NZW51U2hvd246IGJvb2xlYW47XG4gIF90b29sdGlwRGVmYXVsdEV2ZW50czogVUlFdmVudFZpc2liaWxpdHlQYWlyID0gW1xuICAgIFtuZXcgVUlFdmVudCgnbW91c2VlbnRlcicpLCBGbG9hdGluZ1VJVmlzaWJpbGl0eS5TSE9XXSxcbiAgICBbbmV3IFVJRXZlbnQoJ21vdXNlbGVhdmUnKSwgRmxvYXRpbmdVSVZpc2liaWxpdHkuSElERV0sXG4gICAgW25ldyBVSUV2ZW50KCdmb2N1cycpLCBGbG9hdGluZ1VJVmlzaWJpbGl0eS5TSE9XXSxcbiAgICBbbmV3IFVJRXZlbnQoJ2JsdXInKSwgRmxvYXRpbmdVSVZpc2liaWxpdHkuSElERV1cbiAgXTtcbiAgX2Ryb3Bkb3duTWVudURlZmF1bHRFdmVudHM6IFVJRXZlbnRWaXNpYmlsaXR5UGFpciA9IFtbbmV3IFVJRXZlbnQoJ2NsaWNrJyldXTtcblxuICAvKipcbiAgICogUHJvdmlkZXMgY3VzdG9tIGNsYXNzJiM0MDtlcyYjNDE7IGZvciBjdXN0b20gc3R5bGluZy5cbiAgICovXG4gIEBJbnB1dCgpXG4gIHB1YmxpYyBnZXQgY2xhc3MoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5fY2xhc3M7XG4gIH1cbiAgcHVibGljIHNldCBjbGFzcyh2YWx1ZTogc3RyaW5nKSB7XG4gICAgdGhpcy5fY2xhc3MgPSB2YWx1ZTtcbiAgfVxuICBfY2xhc3M6IHN0cmluZyA9ICcnOyAvLyBvdmVycmlkZSB0aGUgc3RhbmRhcmQgY2xhc3MgYXR0ciB3aXRoIGEgbmV3IG9uZS5cbiAgQEhvc3RCaW5kaW5nKCdjbGFzcycpXG4gIGdldCBob3N0Q2xhc3NlcygpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLmNsYXNzO1xuICB9XG5cbiAgLyoqIEBpZ25vcmUgKi9cbiAgQElucHV0KClcbiAgZ2V0IGlzU2hvd24oKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuX2lzU2hvd247XG4gIH1cbiAgc2V0IGlzU2hvd24odmFsdWU6IEJvb2xlYW5JbnB1dCkge1xuICAgIHRoaXMuX2lzU2hvd24gPSBjb2VyY2VCb29sZWFuUHJvcGVydHkodmFsdWUpO1xuICB9XG4gIF9pc1Nob3duOiBib29sZWFuID0gZmFsc2U7XG5cbiAgLyoqXG4gICAqIFBsYWNlbWVudCBvZiBmbG9hdGluZyBjb250ZW50IHJlbGV2YW50IHRvIHRyaWdnZXJpbmcgZWxlbWVudC5cbiAgICogQGRlZmF1bHQgRmxvYXRpbmdVSVBsYWNlbWVudHMuQk9UVE9NX1NUQVJUXG4gICAqIEBzZWUgJ0Zsb2F0aW5nVUlQbGFjZW1lbnRzJy5cbiAgICovXG4gIEBJbnB1dCgpXG4gIGdldCBwbGFjZW1lbnQoKTogRmxvYXRpbmdVSVBsYWNlbWVudHMge1xuICAgIHJldHVybiB0aGlzLl9wbGFjZW1lbnQ7XG4gIH1cbiAgc2V0IHBsYWNlbWVudCh2YWx1ZTogRmxvYXRpbmdVSVBsYWNlbWVudHMpIHtcbiAgICB0aGlzLl9wbGFjZW1lbnQgPSB2YWx1ZTtcbiAgfVxuICBfcGxhY2VtZW50OiBGbG9hdGluZ1VJUGxhY2VtZW50cyA9IEZsb2F0aW5nVUlQbGFjZW1lbnRzLkJPVFRPTV9TVEFSVDtcblxuICAvKipcbiAgICogTWlkZGxld2FyZSBmb3IgRmxvYXRpbmdVSVNlcnZpY2UuXG4gICAqIEBkZWZhdWx0IFsgb2Zmc2V0KDIpLCBmbGlwKCksIHNoaWZ0KCkgXSBmb3IgdG9vbHRpcCA8YnIgLz5cbiAgICogQGRlZmF1bHQgWyBvZmZzZXQoMCksIGZsaXAoKSwgc2hpZnQoKSBdIGZvciBjb21ib2JveCA8YnIgLz5cbiAgICogQHNlZSBbRmxvYXRpbmcgVUldKGh0dHBzOi8vZmxvYXRpbmctdWkuY29tL2RvY3MvbWlkZGxld2FyZSkgZm9yIG9wdGlvbnMuXG4gICAqL1xuICBASW5wdXQoKVxuICBnZXQgbWlkZGxld2FyZSgpOiBNaWRkbGV3YXJlW10ge1xuICAgIHJldHVybiB0aGlzLl9taWRkbGV3YXJlO1xuICB9XG4gIHNldCBtaWRkbGV3YXJlKHZhbHVlOiBNaWRkbGV3YXJlW10pIHtcbiAgICB0aGlzLl9taWRkbGV3YXJlID0gdmFsdWU7XG4gIH1cbiAgX21pZGRsZXdhcmU6IE1pZGRsZXdhcmVbXTtcblxuICAvKipcbiAgICogRXZlbnRzIGFycmF5IGZvciBGbG9hdGluZ1VJU2VydmljZS4gPGJyIC8+XG4gICAqIFRoaXMgYXJyYXkgc3BlY2lmaWVzIHdoZXRoZXIgdG8gc2hvdyBvciBoaWRlIHRoZSBmbG9hdGluZyBlbGVtZW50IG9uIGEgZ2l2ZW4gVUlFdmVudC4gPGJyIC8+XG4gICAqIFRoaXMgc2hvdWxkIGJlIGFuIGFycmF5IG9mIFtVSUV2ZW50LCBGbG9hdGluZ1VJVmlzaWJpbGl0eV0uXG4gICAqIEBkZWZhdWx0IFsgW25ldyBVSUV2ZW50KCdtb3VzZWVudGVyJyksIEZsb2F0aW5nVUlWaXNpYmlsaXR5LlNIT1ddLCA8YnIgLz4gW25ldyBVSUV2ZW50KCdtb3VzZWxlYXZlJyksIEZsb2F0aW5nVUlWaXNpYmlsaXR5LkhJREVdLCA8YnIgLz4gW25ldyBVSUV2ZW50KCdmb2N1cycpLCBGbG9hdGluZ1VJVmlzaWJpbGl0eS5TSE9XXSwgPGJyIC8+IFtuZXcgVUlFdmVudCgnYmx1cicpLCBGbG9hdGluZ1VJVmlzaWJpbGl0eS5ISURFXSA8YnIgLz5dIGZvciB0b29sdGlwXG4gICAqIEBkZWZhdWx0IFsgW25ldyBVSUV2ZW50KCdjbGljaycpXSBdIGZvciBkcm9wZG93bi1tZW51IGFuZCBmbG9hdGluZy11aS1lbGVtZW50XG4gICAqIEBkZWZhdWx0IFtdIEllLiBldmVudHMgYXJlIHJlbW92ZWQgZm9yIGNvbWJvYm94LlxuICAgKi9cbiAgQElucHV0KClcbiAgZ2V0IGV2ZW50c0FycmF5KCk6IFVJRXZlbnRWaXNpYmlsaXR5UGFpciB7XG4gICAgcmV0dXJuIHRoaXMuX2V2ZW50c0FycmF5O1xuICB9XG4gIHNldCBldmVudHNBcnJheSh2YWx1ZTogVUlFdmVudFZpc2liaWxpdHlQYWlyKSB7XG4gICAgdGhpcy5fZXZlbnRzQXJyYXkgPSB2YWx1ZTtcbiAgfVxuICBfZXZlbnRzQXJyYXk6IFVJRXZlbnRWaXNpYmlsaXR5UGFpcjtcblxuICAvKipcbiAgICogQ2xvc2VzIHRoZSBtZW51IG9uIGl0ZW0gaXMgY2xpY2svc2VsZWN0IHdoZW4gdHJ1ZS4gPGJyPlxuICAgKiBJZiA8Y29kZT5tdWx0aXNlbGVjdDwvY29kZT4gaXMgc2V0IHRvIDxjb2RlPnRydWU8L2NvZGU+LCBpdCB3aWxsIG5vdCB0YWtlIGVmZmVjdC48YnI+XG4gICAqIEBkZWZhdWx0IHRydWVcbiAgICovXG4gIEBJbnB1dCgpXG4gIGdldCBjbG9zZU9uQ2xpY2soKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuX2Nsb3NlT25DbGljaztcbiAgfVxuICBzZXQgY2xvc2VPbkNsaWNrKHZhbHVlOiBCb29sZWFuSW5wdXQpIHtcbiAgICB0aGlzLl9jbG9zZU9uQ2xpY2sgPSBjb2VyY2VCb29sZWFuUHJvcGVydHkodmFsdWUpO1xuICB9XG4gIF9jbG9zZU9uQ2xpY2s6IGJvb2xlYW4gPSB0cnVlO1xuXG4gIC8qKlxuICAgKiBFbWl0cyB3aGV0aGVyIG9yIG5vdCB0aGUgZmxvYXRpbmcgVUkgZWxlbWVudCBpcyB2aXNpYmxlLlxuICAgKi9cbiAgQE91dHB1dCgpIGZsb2F0aW5nVUlUb2dnbGVkID0gbmV3IEV2ZW50RW1pdHRlcjxib29sZWFuPigpO1xuXG4gIC8vIHRoaXMgaXMgYW4gYW5ndWxhci1zcGVjaWZpYyBvdmVycmlkZS4gU3BhY2luZyBiZXR3ZWVuIGRyb3Bkb3duLW1lbnUgYW5kIGJ1dHRvbi90cmlnZ2VyXG4gIC8vIGlzIGhhbmRsZWQgd2l0aGluIGZsb2F0aW5nLXVpLnNlcnZpY2VcbiAgQEhvc3RCaW5kaW5nKCdzdHlsZS4tLXYtZHJvcGRvd24tbWVudS1zdXJmYWNlLW1hcmdpbi1ibG9jay1zdGFydCcpXG4gIGdldCBob3N0TWFyZ2luQmxvY2tTdGFydCgpOiBzdHJpbmcge1xuICAgIHJldHVybiAnMCc7XG4gIH1cblxuICBjb25zdHJ1Y3RvcihcbiAgICBwdWJsaWMgZWw6IEVsZW1lbnRSZWYsXG4gICAgcHVibGljIGZsb2F0aW5nVUlTZXJ2aWNlOiBGbG9hdGluZ1VJU2VydmljZSxcbiAgICBwcml2YXRlIHV1aWRTZXJ2aWNlOiBVVUlEU2VydmljZSxcbiAgICBwdWJsaWMgbm92YUxpYlNlcnZpY2U6IE5vdmFMaWJTZXJ2aWNlLFxuICAgIHByaXZhdGUgcmVuZGVyZXI6IFJlbmRlcmVyMixcbiAgICBwcml2YXRlIGFwcFJlYWR5U2VydmljZTogQXBwUmVhZHlTZXJ2aWNlXG4gICkgeyB9XG5cbiAgQEhvc3RMaXN0ZW5lcignZG9jdW1lbnQ6Y2xpY2snLCBbJyRldmVudCddKVxuICBjbGlja091dChldmVudDogRXZlbnQpIHtcbiAgICAvLyBsaXN0ZW4gZm9yIGRvY3VtZW50IGNsaWNrIGFuZCBjbG9zZSBtZW51IGlmIGNsaWNrIGlzIG91dHNpZGUgb2YgY29tcG9uZW50XG4gICAgaWYgKFxuICAgICAgdGhpcy5hcHBSZWFkeVNlcnZpY2UuaXNCcm93c2VyQW5kRG9tQXZhaWxhYmxlKCkgJiZcbiAgICAgIHRoaXMuaXNTaG93biAmJlxuICAgICAgIXRoaXMuZWwubmF0aXZlRWxlbWVudC5jb250YWlucyhldmVudC50YXJnZXQpXG4gICAgKSB7XG4gICAgICB0aGlzLmZsb2F0aW5nVUlTZXJ2aWNlLmhpZGVmbG9hdGluZ1VJKCk7XG4gICAgfVxuICB9XG5cbiAgX3RhYlByZXNzZWQgPSBmYWxzZTtcbiAgQEhvc3RMaXN0ZW5lcignZG9jdW1lbnQ6a2V5ZG93bicsIFsnJGV2ZW50J10pXG4gIHRhYihldmVudDogS2V5Ym9hcmRFdmVudCkge1xuICAgIGlmIChldmVudC5rZXkgPT09ICdUYWInKSB7XG4gICAgICAvLyB1c2VkIGluIGZvY3Vzb3V0IGZ1bmN0aW9uXG4gICAgICB0aGlzLl90YWJQcmVzc2VkID0gdHJ1ZTtcbiAgICB9XG4gIH1cblxuICBASG9zdExpc3RlbmVyKCdmb2N1c291dCcsIFsnJGV2ZW50J10pXG4gIGZvY3Vzb3V0KGV2ZW50OiBGb2N1c0V2ZW50KSB7XG4gICAgaWYgKHRoaXMuX3RhYlByZXNzZWQpIHtcbiAgICAgIC8vIGlmIGZvY3VzIG91dCBpcyBhIHJlc3VsdCBvZiB0YWJiaW5nIG91dCBvZiB0aGlzIGNvbXBvbmVudCwgaGlkZSB0aGUgZmxvYXRpbmcgVUlcbiAgICAgIGlmIChldmVudC5yZWxhdGVkVGFyZ2V0ICYmICF0aGlzLmVsLm5hdGl2ZUVsZW1lbnQuY29udGFpbnMoZXZlbnQucmVsYXRlZFRhcmdldCkpIHtcbiAgICAgICAgdGhpcy5mbG9hdGluZ1VJU2VydmljZS5oaWRlZmxvYXRpbmdVSSgpO1xuICAgICAgfVxuICAgICAgdGhpcy5fdGFiUHJlc3NlZCA9IGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIG5nQWZ0ZXJDb250ZW50SW5pdCgpOiB2b2lkIHtcbiAgICBsZXQgZmxvYXRpbmdFbGVtOiBEcm9wZG93bk1lbnVEaXJlY3RpdmUgfCBUb29sdGlwRGlyZWN0aXZlIHwgRmxvYXRpbmdVSUVsZW1lbnREaXJlY3RpdmUgfCBudWxsID0gbnVsbDtcbiAgICBsZXQgX3RvZ2dsZUljb246IEljb25Ub2dnbGVEaXJlY3RpdmU7XG4gICAgbGV0IF90b2dnbGVJY29uQ29tcG9uZW50OiBJY29uVG9nZ2xlQ29tcG9uZW50O1xuICAgIGNvbnN0IHRvZ2dsZUluQ2hpbGRDb250YWluZXIgPVxuICAgICAgdGhpcy5jb250YWluZXJzLnNvbWUoKGNvbnRhaW5lcikgPT4gY29udGFpbmVyLnRvZ2dsZUljb24gPT09IHRoaXMudG9nZ2xlSWNvbikgfHxcbiAgICAgIHRoaXMuZGlzY2xvc3VyZVRhYnMuc29tZSgodGFiKSA9PiB0YWIuYnV0dG9uLnRvZ2dsZUljb24gPT09IHRoaXMudG9nZ2xlSWNvbikgfHxcbiAgICAgIHRoaXMuYWNjb3JkaW9uSGVhZGluZ3Muc29tZShcbiAgICAgICAgKGhlYWRpbmcpID0+XG4gICAgICAgICAgaGVhZGluZy5ob3N0QnV0dG9uPy50b2dnbGVJY29uID09PSB0aGlzLnRvZ2dsZUljb24gfHwgaGVhZGluZy5fYnV0dG9uSGVhZGluZz8udG9nZ2xlSWNvbiA9PT0gdGhpcy50b2dnbGVJY29uXG4gICAgICApO1xuICAgIGNvbnN0IHRvZ2dsZUNvbXBvbmVudEluQ2hpbGRDb250YWluZXIgPVxuICAgICAgdGhpcy5jb250YWluZXJzLnNvbWUoKGNvbnRhaW5lcikgPT4gY29udGFpbmVyLnRvZ2dsZUljb25Db21wb25lbnQgPT09IHRoaXMudG9nZ2xlSWNvbkNvbXBvbmVudCkgfHxcbiAgICAgIHRoaXMuZGlzY2xvc3VyZVRhYnMuc29tZSgodGFiKSA9PiB0YWIuYnV0dG9uLnRvZ2dsZUljb25Db21wb25lbnQgPT09IHRoaXMudG9nZ2xlSWNvbkNvbXBvbmVudCkgfHxcbiAgICAgIHRoaXMuYWNjb3JkaW9uSGVhZGluZ3Muc29tZShcbiAgICAgICAgKGhlYWRpbmcpID0+XG4gICAgICAgICAgaGVhZGluZy5ob3N0QnV0dG9uPy50b2dnbGVJY29uQ29tcG9uZW50ID09PSB0aGlzLnRvZ2dsZUljb25Db21wb25lbnQgfHxcbiAgICAgICAgICBoZWFkaW5nLl9idXR0b25IZWFkaW5nPy50b2dnbGVJY29uQ29tcG9uZW50ID09PSB0aGlzLnRvZ2dsZUljb25Db21wb25lbnRcbiAgICAgICk7XG5cbiAgICBpZiAodGhpcy50b2dnbGVJY29uICYmICF0b2dnbGVJbkNoaWxkQ29udGFpbmVyKSB7XG4gICAgICBfdG9nZ2xlSWNvbiA9IHRoaXMudG9nZ2xlSWNvbjtcbiAgICAgIF90b2dnbGVJY29uLmljb24uaWNvbiA9IHRoaXMuaXNTaG93biA/IF90b2dnbGVJY29uLmV4cGFuZGVkSWNvbiA6IF90b2dnbGVJY29uLmNvbGxhcHNlZEljb247XG4gICAgfSBlbHNlIGlmICh0aGlzLnRvZ2dsZUljb25Db21wb25lbnQgJiYgIXRvZ2dsZUNvbXBvbmVudEluQ2hpbGRDb250YWluZXIpIHtcbiAgICAgIF90b2dnbGVJY29uQ29tcG9uZW50ID0gdGhpcy50b2dnbGVJY29uQ29tcG9uZW50O1xuICAgICAgX3RvZ2dsZUljb25Db21wb25lbnQuX2Zsb2F0aW5nVUlUb2dnbGUgPSB0cnVlO1xuICAgICAgX3RvZ2dsZUljb25Db21wb25lbnQucm90YXRlZCA9IHRoaXMuaXNTaG93bjtcbiAgICB9XG5cbiAgICBjb25zdCB0b29sdGlwSW5DaGlsZENvbnRhaW5lciA9IHRoaXMuY29udGFpbmVycy5zb21lKChjb250YWluZXIpID0+IGNvbnRhaW5lci50b29sdGlwID09PSB0aGlzLnRvb2x0aXApO1xuICAgIGNvbnN0IG1lbnVJbkNoaWxkQ29udGFpbmVyID0gdGhpcy5jb250YWluZXJzLnNvbWUoKGNvbnRhaW5lcikgPT4gY29udGFpbmVyLm1lbnUgPT09IHRoaXMubWVudSk7XG4gICAgY29uc3QgZHJvcGRvd25JbkNoaWxkQ29udGFpbmVyID0gdGhpcy5jb250YWluZXJzLnNvbWUoXG4gICAgICAoY29udGFpbmVyKSA9PiBjb250YWluZXIuZ2VuZXJpY0Ryb3Bkb3duID09PSB0aGlzLmdlbmVyaWNEcm9wZG93blxuICAgICk7XG5cbiAgICBpZiAodGhpcy5tZW51ICYmICFtZW51SW5DaGlsZENvbnRhaW5lcikge1xuICAgICAgZmxvYXRpbmdFbGVtID0gdGhpcy5tZW51O1xuICAgICAgdGhpcy5yZW5kZXJlci5zZXRTdHlsZSh0aGlzLm1lbnUuZWwubmF0aXZlRWxlbWVudCwgJ3Bvc2l0aW9uJywgJ2Fic29sdXRlJyk7XG4gICAgICB0aGlzLnRyaWdnZXIuX3RyaWdnZXJzRHJvcGRvd25NZW51ID0gdHJ1ZTtcbiAgICAgIGZsb2F0aW5nRWxlbS5pZCA9IHRoaXMubWVudS5pZCA/IHRoaXMubWVudS5pZCA6IHRoaXMudXVpZFNlcnZpY2UuZ2V0VVVJRCgndi1mbG9hdGluZy0nKTtcbiAgICAgIHRoaXMubWVudS5faXNTaG93biA9IHRoaXMuaXNTaG93bjtcbiAgICAgIHRoaXMuZXZlbnRzQXJyYXkgPSB0aGlzLmV2ZW50c0FycmF5ID8gdGhpcy5ldmVudHNBcnJheSA6IHRoaXMuX2Ryb3Bkb3duTWVudURlZmF1bHRFdmVudHM7XG4gICAgICB0aGlzLnNldFVwTGlzdEl0ZW1zKCk7XG4gICAgfSBlbHNlIGlmICh0aGlzLnRvb2x0aXAgJiYgIXRvb2x0aXBJbkNoaWxkQ29udGFpbmVyKSB7XG4gICAgICBmbG9hdGluZ0VsZW0gPSB0aGlzLnRvb2x0aXA7XG4gICAgICB0aGlzLnRyaWdnZXIuX3RyaWdnZXJzVG9vbHRpcCA9IHRydWU7XG4gICAgICB0aGlzLmV2ZW50c0FycmF5ID0gdGhpcy5ldmVudHNBcnJheSA/IHRoaXMuZXZlbnRzQXJyYXkgOiB0aGlzLl90b29sdGlwRGVmYXVsdEV2ZW50cztcbiAgICB9IGVsc2UgaWYgKHRoaXMuZ2VuZXJpY0Ryb3Bkb3duICYmICFkcm9wZG93bkluQ2hpbGRDb250YWluZXIpIHtcbiAgICAgIGZsb2F0aW5nRWxlbSA9IHRoaXMuZ2VuZXJpY0Ryb3Bkb3duO1xuICAgICAgdGhpcy5yZW5kZXJlci5zZXRTdHlsZSh0aGlzLmdlbmVyaWNEcm9wZG93bi5lbC5uYXRpdmVFbGVtZW50LCAncG9zaXRpb24nLCAnYWJzb2x1dGUnKTtcbiAgICAgIHRoaXMuZXZlbnRzQXJyYXkgPSB0aGlzLmV2ZW50c0FycmF5ID8gdGhpcy5ldmVudHNBcnJheSA6IHRoaXMuX2Ryb3Bkb3duTWVudURlZmF1bHRFdmVudHM7XG4gICAgICB0aGlzLnNldFVwTGlzdEl0ZW1zKCk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMudHJpZ2dlcj8uZWwgJiYgZmxvYXRpbmdFbGVtPy5lbCkge1xuICAgICAgZmxvYXRpbmdFbGVtLmlkID0gZmxvYXRpbmdFbGVtLmlkID8gZmxvYXRpbmdFbGVtLmlkIDogdGhpcy51dWlkU2VydmljZS5nZXRVVUlEKCd2LWZsb2F0aW5nLScpO1xuICAgICAgdGhpcy50cmlnZ2VyLl9mbG9hdGluZ0VsZW1JRCA9IGZsb2F0aW5nRWxlbS5pZDtcbiAgICAgIGlmICh0aGlzLnRvb2x0aXA/LmFycm93KSB7XG4gICAgICAgIHRoaXMuZmxvYXRpbmdVSVNlcnZpY2UuY3VzdG9taXplRmxvYXRpbmdVSShcbiAgICAgICAgICB0aGlzLnBsYWNlbWVudCxcbiAgICAgICAgICB0aGlzLm1pZGRsZXdhcmUsXG4gICAgICAgICAgdGhpcy50b29sdGlwLmRpc3BsYXkgfHwgJ2Jsb2NrJyxcbiAgICAgICAgICB0aGlzLnRvb2x0aXAuYXJyb3dcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmICghdGhpcy5taWRkbGV3YXJlICYmIHRoaXMuX2lzQ29tYm9ib3gpIHtcbiAgICAgICAgICB0aGlzLm1pZGRsZXdhcmUgPSB0aGlzLmZsb2F0aW5nVUlTZXJ2aWNlLmNvbWJvYm94TWlkZGxld2FyZTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmZsb2F0aW5nVUlTZXJ2aWNlLmN1c3RvbWl6ZUZsb2F0aW5nVUkodGhpcy5wbGFjZW1lbnQsIHRoaXMubWlk