UNPKG

@microsoft/windows-admin-center-sdk

Version:

Microsoft - Windows Admin Center Shell

261 lines 32.1 kB
import { Component, ElementRef, EventEmitter, HostBinding, HostListener, Inject, Input, Optional, Output, Renderer2, ViewChild } from '@angular/core'; import { KeyCode } from '@microsoft/windows-admin-center-sdk/core/data/accessibility-manager'; import { SME_LAYOUT_PROVIDER } from '../common/layout'; import { DropdownService } from './dropdown.service'; import * as i0 from "@angular/core"; import * as i1 from "./dropdown.service"; import * as i2 from "@angular/common"; const _c0 = ["smeDropdownContent"]; const _c1 = ["smeDropdownToggle"]; const _c2 = [[["", 8, "sme-dropdown-toggle"]], [["", 8, "sme-dropdown-content"]]]; const _c3 = function (a0, a1, a2, a3) { return { "sme-layout-hidden": a0, "sme-layout-inline-block": a1, "sme-arrange-overflow-auto-x": a2, "sme-arrange-overflow-auto-y": a3 }; }; const _c4 = [".sme-dropdown-toggle", ".sme-dropdown-content"]; /** * * @smeDoc {@label Dropdown @id sme-dropdown-component @internal} * * @overview * @file {@filepath ./examples/dropdown-overview.md} * * @example {@label Basic Usage @id basic-usage} * @file {@filename component.html @filepath ./examples/basic-usage.component.html} * * @example {@label Dropdown with advanced content @id advanced-dropdown} * @file {@filename component.html @filepath ./examples/advanced-dropdown.component.html} * @file {@filename component.ts @filepath ./examples/advanced-dropdown.component.ts} * */ /** * Component to create an dropdown */ export class DropdownComponent { /** * Initializes a new instance of the DropdownDirective */ constructor(renderer, element, dropdownService, layout) { this.renderer = renderer; this.element = element; this.dropdownService = dropdownService; this.layout = layout; this.toggled = new EventEmitter(); this.isContextMenu = false; /** * Determine if the dropdown will use the sme-form-field to limit its max-width */ this.dropdownApplyFormFieldOffsetWidth = true; /** * Indicates the open state of the dropdown */ this.isOpen = false; /** * Indicates how far the dropdown content has been translated to remain fully on screen */ this.left = 0; /** * Indicates how far the dropdown content has been translated to remain fully on screen */ this.top = 0; /** * Indicates if the dropdown is larger than the horizontal space available */ this.overflowX = false; /** * Indicates if the dropdown is larger than the vertical space available */ this.overflowY = false; /** * Indicates that dropdown should be disabled. */ this.disabled = false; renderer.addClass(element.nativeElement, 'sme-layout-relative'); this.autoToggle = true; } /** * Event Emitter for when the dropdown opens or closes. Emits a boolean to indicate if the dropdown is open * @deprecated since 9/25/2019. Please use 'toggled' instead */ // eslint-disable-next-line @angular-eslint/no-output-on-prefix get onToggled() { return this.toggled; } /** * Angulars On Init Lifecycle Hook */ ngOnInit() { if (this.layout) { this.layoutChangeSubscriber = this.layout.layoutChanged.subscribe(() => { // Use setTimeout to postponed the dropdown UI update to next refresh cycle. // This the current refresh cycle can be used for any components to update its own UI which may impact dropdown UI. setTimeout(() => { this.dropdownService.updatePosition(this, this.calculateHeight, this.displayToSide); }); }); } } ngAfterViewInit() { // load the context menu code here so as to allow all child views to be completely initialized if (!this.isContextMenu) { this.unsubscribeToggleClick = this.renderer.listen(this.toggleElement.nativeElement, 'click', (event) => this.onToggleClick(event)); } else { this.dropdownService.open(this, this.calculateHeight, this.displayToSide).then(() => { this.isOpen = true; }); } } /** * Angulars On Destroy Lifecycle Hook */ ngOnDestroy() { this.close(); // this.unsubscribeToggleClick(); if (this.layoutChangeSubscriber) { this.layoutChangeSubscriber.unsubscribe(); } } /** * Opens this dropdown */ open() { this.toggle(true, this.calculateHeight, this.displayToSide); } /** * Listen to keyboard event and close dropdown when users do not focus on dropdown list */ onKeyup(event) { if (event.keyCode === KeyCode.Tab) { let element = event.target; while (!this.contentElement.nativeElement.isSameNode(element) && !this.element.nativeElement.isSameNode(element)) { if (element.classList.contains('sme-focus-trap')) { return; } element = element.parentElement; } this.close(event); } else if ((event.keyCode === KeyCode.LeftArrow && event.target.className.indexOf('sme-dropdown-toggle') > -1)) { this.close(event); } else if (event.keyCode === KeyCode.Escape) { // prevent event propagation when inside a dialog event.preventDefault(); event.stopPropagation(); event.stopImmediatePropagation(); } } /** * Closes this dropdown * @param event keyboard event including the current event target */ close(event) { this.toggle(false, null, this.displayToSide, event); } /** * Toggles the dropdown * @param open Optional. If provided, forces the dropdown open or closed. */ toggle(open, calculateHeight, displayToSide, event) { // If we are already in the correct state, return if (!MsftSme.isNullOrUndefined(open) && open === this.isOpen) { return; } if (this.isOpen) { // close if opened this.dropdownService.close(this); if (event) { this.dropdownService.closeNested(this, event); } // emit the current state of the dropdown this.onToggled.emit(this.isOpen); } else { // open if closed this.dropdownService.open(this, calculateHeight, displayToSide).then(() => { this.toggleElement.nativeElement.addEventListener('closeEvent', () => { this.isOpen = false; }, false); // emit the current state of the dropdown this.onToggled.emit(this.isOpen); }); } } /** * Handler for the click event for the toggle element * @param event the mouse event of the click * @param manualToggle determine whether this is manually toggle */ onToggleClick(event, manualToggle) { event.stopPropagation(); if (this.autoToggle || manualToggle) { // toggle the dropdown if not disabled if (!this.disabled) { this.toggle(null, this.calculateHeight, this.displayToSide); } } return false; } } /** @nocollapse */ DropdownComponent.ɵfac = function DropdownComponent_Factory(t) { return new (t || DropdownComponent)(i0.ɵɵdirectiveInject(i0.Renderer2), i0.ɵɵdirectiveInject(i0.ElementRef), i0.ɵɵdirectiveInject(i1.DropdownService), i0.ɵɵdirectiveInject(SME_LAYOUT_PROVIDER, 8)); }; /** @nocollapse */ DropdownComponent.ɵcmp = /** @pureOrBreakMyCode */ i0.ɵɵdefineComponent({ type: DropdownComponent, selectors: [["sme-dropdown"]], viewQuery: function DropdownComponent_Query(rf, ctx) { if (rf & 1) { i0.ɵɵviewQuery(_c0, 5); i0.ɵɵviewQuery(_c1, 7); } if (rf & 2) { let _t; i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.contentElement = _t.first); i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.toggleElement = _t.first); } }, hostVars: 2, hostBindings: function DropdownComponent_HostBindings(rf, ctx) { if (rf & 1) { i0.ɵɵlistener("keyup", function DropdownComponent_keyup_HostBindingHandler($event) { return ctx.onKeyup($event); }); } if (rf & 2) { i0.ɵɵclassProp("sme-disabled", ctx.disabled); } }, inputs: { autoToggle: "autoToggle", autoWidth: "autoWidth", calculateHeight: "calculateHeight", displayToSide: "displayToSide", isContextMenu: "isContextMenu", dropdownApplyFormFieldOffsetWidth: "dropdownApplyFormFieldOffsetWidth", disabled: "disabled" }, outputs: { onToggled: "onToggled", toggled: "toggled" }, ngContentSelectors: _c4, decls: 6, vars: 6, consts: [["data-uta-id", "dropdown-toggle", 1, "sme-dropdown-toggle-container"], ["smeDropdownToggle", ""], ["data-uta-id", "dropdown-content", 1, "sme-layout-dropdown", "sme-layout-fixed", "sme-position-below", "sme-scheme-dropdown", "sme-layer-nav", "sme-shadow-dropdown", 3, "ngClass"], ["smeDropdownContent", ""]], template: function DropdownComponent_Template(rf, ctx) { if (rf & 1) { i0.ɵɵprojectionDef(_c2); i0.ɵɵelementStart(0, "div", 0, 1); i0.ɵɵprojection(2); i0.ɵɵelementEnd(); i0.ɵɵelementStart(3, "div", 2, 3); i0.ɵɵprojection(5, 1); i0.ɵɵelementEnd(); } if (rf & 2) { i0.ɵɵadvance(3); i0.ɵɵproperty("ngClass", i0.ɵɵpureFunction4(1, _c3, !ctx.isOpen, ctx.isOpen, ctx.overflowX, ctx.overflowY)); } }, dependencies: [i2.NgClass], encapsulation: 2 }); (function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(DropdownComponent, [{ type: Component, args: [{ selector: 'sme-dropdown', template: "<div #smeDropdownToggle class=\"sme-dropdown-toggle-container\" data-uta-id=\"dropdown-toggle\">\r\n <ng-content select=\".sme-dropdown-toggle\"></ng-content>\r\n</div>\r\n<div #smeDropdownContent\r\n class=\"sme-layout-dropdown sme-layout-fixed sme-position-below sme-scheme-dropdown sme-layer-nav sme-shadow-dropdown\"\r\n [ngClass]=\"{'sme-layout-hidden': !isOpen, 'sme-layout-inline-block': isOpen, 'sme-arrange-overflow-auto-x': overflowX, 'sme-arrange-overflow-auto-y': overflowY}\"\r\n data-uta-id=\"dropdown-content\">\r\n <ng-content select=\".sme-dropdown-content\"></ng-content>\r\n</div>\r\n" }] }], function () { return [{ type: i0.Renderer2 }, { type: i0.ElementRef }, { type: i1.DropdownService }, { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [SME_LAYOUT_PROVIDER] }] }]; }, { onToggled: [{ type: Output }], toggled: [{ type: Output }], autoToggle: [{ type: Input }], autoWidth: [{ type: Input }], calculateHeight: [{ type: Input }], displayToSide: [{ type: Input }], isContextMenu: [{ type: Input }], contentElement: [{ type: ViewChild, args: ['smeDropdownContent'] }], toggleElement: [{ type: ViewChild, args: ['smeDropdownToggle', { static: true }] }], dropdownApplyFormFieldOffsetWidth: [{ type: Input }], disabled: [{ type: HostBinding, args: ['class.sme-disabled'] }, { type: Input }], onKeyup: [{ type: HostListener, args: ['keyup', ['$event']] }] }); })(); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHJvcGRvd24uY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vYW5ndWxhci9zcmMvY29udHJvbHMvZHJvcGRvd24vZHJvcGRvd24uY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vYW5ndWxhci9zcmMvY29udHJvbHMvZHJvcGRvd24vZHJvcGRvd24uY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUVILFNBQVMsRUFDVCxVQUFVLEVBQ1YsWUFBWSxFQUNaLFdBQVcsRUFDWCxZQUFZLEVBQ1osTUFBTSxFQUNOLEtBQUssRUFHTCxRQUFRLEVBQ1IsTUFBTSxFQUNOLFNBQVMsRUFDVCxTQUFTLEVBQ1osTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLHFFQUFxRSxDQUFDO0FBQzlGLE9BQU8sRUFBVSxtQkFBbUIsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQy9ELE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQzs7Ozs7Ozs7O0FBR3JEOzs7Ozs7Ozs7Ozs7OztHQWNHO0FBRUg7O0dBRUc7QUFLSCxNQUFNLE9BQU8saUJBQWlCO0lBd0YxQjs7T0FFRztJQUNILFlBQ1ksUUFBbUIsRUFDbkIsT0FBbUIsRUFDbkIsZUFBZ0MsRUFDUyxNQUFjO1FBSHZELGFBQVEsR0FBUixRQUFRLENBQVc7UUFDbkIsWUFBTyxHQUFQLE9BQU8sQ0FBWTtRQUNuQixvQkFBZSxHQUFmLGVBQWUsQ0FBaUI7UUFDUyxXQUFNLEdBQU4sTUFBTSxDQUFRO1FBcEZsRCxZQUFPLEdBQUcsSUFBSSxZQUFZLEVBQVcsQ0FBQztRQXlCaEQsa0JBQWEsR0FBRyxLQUFLLENBQUM7UUFhN0I7O1dBRUc7UUFFSSxzQ0FBaUMsR0FBRyxJQUFJLENBQUM7UUFFaEQ7O1dBRUc7UUFDSSxXQUFNLEdBQUcsS0FBSyxDQUFDO1FB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QUksTUFBTTt1QkFBQyxtQkFBbUI7d0JBdkZ0QixTQUFTO2tCQUE3QixNQUFNO1lBR1UsT0FBTztrQkFBdkIsTUFBTTtZQUtTLFVBQVU7a0JBQXpCLEtBQUs7WUFLVSxTQUFTO2tCQUF4QixLQUFLO1lBTUMsZUFBZTtrQkFEckIsS0FBSztZQU9DLGFBQWE7a0JBRG5CLEtBQUs7WUFJQyxhQUFhO2tCQURuQixLQUFLO1lBTUMsY0FBYztrQkFEcEIsU0FBUzttQkFBQyxvQkFBb0I7WUFPeEIsYUFBYTtrQkFEbkIsU0FBUzttQkFBQyxtQkFBbUIsRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUU7WUFPekMsaUNBQWlDO2tCQUR2QyxLQUFLO1lBZ0NVLFFBQVE7a0JBRHZCLFdBQVc7bUJBQUMsb0JBQW9COztrQkFDaEMsS0FBSztZQWtFQyxPQUFPO2tCQURiLFlBQVk7bUJBQUMsT0FBTyxFQUFFLENBQUMsUUFBUSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcclxuICAgIEFmdGVyVmlld0luaXQsXHJcbiAgICBDb21wb25lbnQsXHJcbiAgICBFbGVtZW50UmVmLFxyXG4gICAgRXZlbnRFbWl0dGVyLFxyXG4gICAgSG9zdEJpbmRpbmcsXHJcbiAgICBIb3N0TGlzdGVuZXIsXHJcbiAgICBJbmplY3QsXHJcbiAgICBJbnB1dCxcclxuICAgIE9uRGVzdHJveSxcclxuICAgIE9uSW5pdCxcclxuICAgIE9wdGlvbmFsLFxyXG4gICAgT3V0cHV0LFxyXG4gICAgUmVuZGVyZXIyLFxyXG4gICAgVmlld0NoaWxkXHJcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IEtleUNvZGUgfSBmcm9tICdAbWljcm9zb2Z0L3dpbmRvd3MtYWRtaW4tY2VudGVyLXNkay9jb3JlL2RhdGEvYWNjZXNzaWJpbGl0eS1tYW5hZ2VyJztcclxuaW1wb3J0IHsgTGF5b3V0LCBTTUVfTEFZT1VUX1BST1ZJREVSIH0gZnJvbSAnLi4vY29tbW9uL2xheW91dCc7XHJcbmltcG9ydCB7IERyb3Bkb3duU2VydmljZSB9IGZyb20gJy4vZHJvcGRvd24uc2VydmljZSc7XHJcbmltcG9ydCB7IERyb3Bkb3duIH0gZnJvbSAnLi9tb2RlbHMnO1xyXG5cclxuLyoqXHJcbiAqXHJcbiAqIEBzbWVEb2Mge0BsYWJlbCBEcm9wZG93biBAaWQgc21lLWRyb3Bkb3duLWNvbXBvbmVudCBAaW50ZXJuYWx9XHJcbiAqXHJcbiAqIEBvdmVydmlld1xyXG4gKiBAZmlsZSB7QGZpbGVwYXRoIC4vZXhhbXBsZXMvZHJvcGRvd24tb3ZlcnZpZXcubWR9XHJcbiAqXHJcbiAqIEBleGFtcGxlIHtAbGFiZWwgQmFzaWMgVXNhZ2UgQGlkIGJhc2ljLXVzYWdlfVxyXG4gKiBAZmlsZSB7QGZpbGVuYW1lIGNvbXBvbmVudC5odG1sIEBmaWxlcGF0aCAuL2V4YW1wbGVzL2Jhc2ljLXVzYWdlLmNvbXBvbmVudC5odG1sfVxyXG4gKlxyXG4gKiBAZXhhbXBsZSB7QGxhYmVsIERyb3Bkb3duIHdpdGggYWR2YW5jZWQgY29udGVudCBAaWQgYWR2YW5jZWQtZHJvcGRvd259XHJcbiAqIEBmaWxlIHtAZmlsZW5hbWUgY29tcG9uZW50Lmh0bWwgQGZpbGVwYXRoIC4vZXhhbXBsZXMvYWR2YW5jZWQtZHJvcGRvd24uY29tcG9uZW50Lmh0bWx9XHJcbiAqIEBmaWxlIHtAZmlsZW5hbWUgY29tcG9uZW50LnRzIEBmaWxlcGF0aCAuL2V4YW1wbGVzL2FkdmFuY2VkLWRyb3Bkb3duLmNvbXBvbmVudC50c31cclxuICpcclxuICovXHJcblxyXG4vKipcclxuICogQ29tcG9uZW50IHRvIGNyZWF0ZSBhbiBkcm9wZG93blxyXG4gKi9cclxuQENvbXBvbmVudCh7XHJcbiAgICBzZWxlY3RvcjogJ3NtZS1kcm9wZG93bicsXHJcbiAgICB0ZW1wbGF0ZVVybDogJy4vZHJvcGRvd24uY29tcG9uZW50Lmh0bWwnXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBEcm9wZG93bkNvbXBvbmVudCBpbXBsZW1lbnRzIE9uRGVzdHJveSwgT25Jbml0LCBEcm9wZG93biwgQWZ0ZXJWaWV3SW5pdCB7XHJcbiAgICBwcml2YXRlIGxheW91dENoYW5nZVN1YnNjcmliZXI7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBFdmVudCBFbWl0dGVyIGZvciB3aGVuIHRoZSBkcm9wZG93biBvcGVucyBvciBjbG9zZXMuIEVtaXRzIGEgYm9vbGVhbiB0byBpbmRpY2F0ZSBpZiB0aGUgZHJvcGRvd24gaXMgb3BlblxyXG4gICAgICogQGRlcHJlY2F0ZWQgc2luY2UgOS8yNS8yMDE5LiBQbGVhc2UgdXNlICd0b2dnbGVkJyBpbnN0ZWFkXHJcbiAgICAgKi9cclxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAYW5ndWxhci1lc2xpbnQvbm8tb3V0cHV0LW9uLXByZWZpeFxyXG4gICAgQE91dHB1dCgpIHB1YmxpYyBnZXQgb25Ub2dnbGVkKCk6IEV2ZW50RW1pdHRlcjxib29sZWFuPiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMudG9nZ2xlZDtcclxuICAgIH1cclxuICAgIEBPdXRwdXQoKSBwdWJsaWMgdG9nZ2xlZCA9IG5ldyBFdmVudEVtaXR0ZXI8Ym9vbGVhbj4oKTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEl0IGluZGljYXRlcyBzaG91bGQgYXV0b21hdGljYWxseSB0b2dnbGUgdG8gZHJvcGRvd24gd2hlbiB0aGUgdG9nZ2xlIGVsZW1lbnQgaXMgY2xpY2tlZC4gRGVmYXVsdHMgdG8gdHJ1ZVxyXG4gICAgICovXHJcbiAgICBASW5wdXQoKSBwdWJsaWMgYXV0b1RvZ2dsZTogYm9vbGVhbjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEl0IGluZGljYXRlcyB3aGV0aGVyIHRvIHNldCB0aGUgZHJvcGRvd24gY29udGVudCB3aWR0aCB0byBiZSBiYXNlZCBvbiB0aGUgYWN0dWFsIGNvbnRlbnRcclxuICAgICAqL1xyXG4gICAgQElucHV0KCkgcHVibGljIGF1dG9XaWR0aDogYm9vbGVhbjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEl0IGRldGVybWluZSB3aGV0aGVyIHRvIGNhbGN1bGF0ZSBoZWlnaHQgZm9yIHRoZSBkcm9wZG93blxyXG4gICAgICovXHJcbiAgICBASW5wdXQoKVxyXG4gICAgcHVibGljIGNhbGN1bGF0ZUhlaWdodDogYm9vbGVhbjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEl0IGRldGVybWluZXMgd2hldGhlciB0byBkaXNwbGF5IGRyb3Bkb3duIG1lbnUgdG8gc2lkZSBvZiB0b2dnbGUuIERlZmF1bHRzIHRvIGJlbG93XHJcbiAgICAgKi9cclxuICAgIEBJbnB1dCgpXHJcbiAgICBwdWJsaWMgZGlzcGxheVRvU2lkZTogYm9vbGVhbjtcclxuXHJcbiAgICBASW5wdXQoKVxyXG4gICAgcHVibGljIGlzQ29udGV4dE1lbnUgPSBmYWxzZTtcclxuICAgIC8qKlxyXG4gICAgICogVGhlIGNvbnRlbnQgZWxlbWVudC4gVGhpcyBtdXN0IGJlIHByb3ZpZGVkIGJ5IHRoZSBEcm9wZG93bkNvbnRlbnREaXJlY3RpdmUgb3IgcG9zc2libHkgc29tZSBjdXN0b20gaW1wbGVtZW50YXRpb25cclxuICAgICAqL1xyXG4gICAgQFZpZXdDaGlsZCgnc21lRHJvcGRvd25Db250ZW50JylcclxuICAgIHB1YmxpYyBjb250ZW50RWxlbWVudDogRWxlbWVudFJlZjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoZSB0b2dnbGUgZWxlbWVudC4gVGhpcyBtdXN0IGJlIHByb3ZpZGVkIGJ5IHRoZSBEcm9wZG93blRvZ2dsZURpcmVjdGl2ZSBvciBwb3NzaWJseSBzb21lIGN1c3RvbSBpbXBsZW1lbnRhdGlvblxyXG4gICAgICovXHJcbiAgICBAVmlld0NoaWxkKCdzbWVEcm9wZG93blRvZ2dsZScsIHsgc3RhdGljOiB0cnVlIH0pXHJcbiAgICBwdWJsaWMgdG9nZ2xlRWxlbWVudDogRWxlbWVudFJlZjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIERldGVybWluZSBpZiB0aGUgZHJvcGRvd24gd2lsbCB1c2UgdGhlIHNtZS1mb3JtLWZpZWxkIHRvIGxpbWl0IGl0cyBtYXgtd2lkdGhcclxuICAgICAqL1xyXG4gICAgQElucHV0KClcclxuICAgIHB1YmxpYyBkcm9wZG93bkFwcGx5Rm9ybUZpZWxkT2Zmc2V0V2lkdGggPSB0cnVlO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogSW5kaWNhdGVzIHRoZSBvcGVuIHN0YXRlIG9mIHRoZSBkcm9wZG93blxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgaXNPcGVuID0gZmFsc2U7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBJbmRpY2F0ZXMgaG93IGZhciB0aGUgZHJvcGRvd24gY29udGVudCBoYXMgYmVlbiB0cmFuc2xhdGVkIHRvIHJlbWFpbiBmdWxseSBvbiBzY3JlZW5cclxuICAgICAqL1xyXG4gICAgcHVibGljIGxlZnQgPSAwO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogSW5kaWNhdGVzIGhvdyBmYXIgdGhlIGRyb3Bkb3duIGNvbnRlbnQgaGFzIGJlZW4gdHJhbnNsYXRlZCB0byByZW1haW4gZnVsbHkgb24gc2NyZWVuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyB0b3AgPSAwO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogSW5kaWNhdGVzIGlmIHRoZSBkcm9wZG93biBpcyBsYXJnZXIgdGhhbiB0aGUgaG9yaXpvbnRhbCBzcGFjZSBhdmFpbGFibGVcclxuICAgICAqL1xyXG4gICAgcHVibGljIG92ZXJmbG93WCA9IGZhbHNlO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogSW5kaWNhdGVzIGlmIHRoZSBkcm9wZG93biBpcyBsYXJnZXIgdGhhbiB0aGUgdmVydGljYWwgc3BhY2UgYXZhaWxhYmxlXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBvdmVyZmxvd1kgPSBmYWxzZTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEluZGljYXRlcyB0aGF0IGRyb3Bkb3duIHNob3VsZCBiZSBkaXNhYmxlZC5cclxuICAgICAqL1xyXG4gICAgQEhvc3RCaW5kaW5nKCdjbGFzcy5zbWUtZGlzYWJsZWQnKVxyXG4gICAgQElucHV0KCkgcHVibGljIGRpc2FibGVkID0gZmFsc2U7XHJcblxyXG4gICAgcHJpdmF0ZSB1bnN1YnNjcmliZVRvZ2dsZUNsaWNrOiBGdW5jdGlvbjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEluaXRpYWxpemVzIGEgbmV3IGluc3RhbmNlIG9mIHRoZSBEcm9wZG93bkRpcmVjdGl2ZVxyXG4gICAgICovXHJcbiAgICBjb25zdHJ1Y3RvcihcclxuICAgICAgICBwcml2YXRlIHJlbmRlcmVyOiBSZW5kZXJlcjIsXHJcbiAgICAgICAgcHJpdmF0ZSBlbGVtZW50OiBFbGVtZW50UmVmLFxyXG4gICAgICAgIHByaXZhdGUgZHJvcGRvd25TZXJ2aWNlOiBEcm9wZG93blNlcnZpY2UsXHJcbiAgICAgICAgQE9wdGlvbmFsKCkgQEluamVjdChTTUVfTEFZT1VUX1BST1ZJREVSKSBwcml2YXRlIGxheW91dDogTGF5b3V0KSB7XHJcbiAgICAgICAgcmVuZGVyZXIuYWRkQ2xhc3MoZWxlbWVudC5uYXRpdmVFbGVtZW50LCAnc21lLWxheW91dC1yZWxhdGl2ZScpO1xyXG4gICAgICAgIHRoaXMuYXV0b1RvZ2dsZSA9IHRydWU7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAqIEFuZ3VsYXJzIE9uIEluaXQgTGlmZWN5Y2xlIEhvb2tcclxuICAgICovXHJcbiAgICBwdWJsaWMgbmdPbkluaXQoKSB7XHJcbiAgICAgICAgaWYgKHRoaXMubGF5b3V0KSB7XHJcbiAgICAgICAgICAgIHRoaXMubGF5b3V0Q2hhbmdlU3Vic2NyaWJlciA9IHRoaXMubGF5b3V0LmxheW91dENoYW5nZWQuc3Vic2NyaWJlKCgpID0+IHtcclxuICAgICAgICAgICAgICAgIC8vIFVzZSBzZXRUaW1lb3V0IHRvIHBvc3Rwb25lZCB0aGUgZHJvcGRvd24gVUkgdXBkYXRlIHRvIG5leHQgcmVmcmVzaCBjeWNsZS5cclxuICAgICAgICAgICAgICAgIC8vIFRoaXMgdGhlIGN1cnJlbnQgcmVmcmVzaCBjeWNsZSBjYW4gYmUgdXNlZCBmb3IgYW55IGNvbXBvbmVudHMgdG8gdXBkYXRlIGl0cyBvd24gVUkgd2hpY2ggbWF5IGltcGFjdCBkcm9wZG93biBVSS5cclxuICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZHJvcGRvd25TZXJ2aWNlLnVwZGF0ZVBvc2l0aW9uKHRoaXMsIHRoaXMuY2FsY3VsYXRlSGVpZ2h0LCB0aGlzLmRpc3BsYXlUb1NpZGUpO1xyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgbmdBZnRlclZpZXdJbml0KCk6IHZvaWQge1xyXG4gICAgICAgIC8vIGxvYWQgdGhlIGNvbnRleHQgbWVudSBjb2RlIGhlcmUgc28gYXMgdG8gYWxsb3cgYWxsIGNoaWxkIHZpZXdzIHRvIGJlIGNvbXBsZXRlbHkgaW5pdGlhbGl6ZWRcclxuICAgICAgICBpZiAoIXRoaXMuaXNDb250ZXh0TWVudSkge1xyXG4gICAgICAgICAgICB0aGlzLnVuc3Vic2NyaWJlVG9nZ2xlQ2xpY2sgPSB0aGlzLnJlbmRlcmVyLmxpc3Rlbih0aGlzLnRvZ2dsZUVsZW1lbnQubmF0aXZlRWxlbWVudCwgJ2NsaWNrJyxcclxuICAgICAgICAgICAgICAgIChldmVudCkgPT4gdGhpcy5vblRvZ2dsZUNsaWNrKGV2ZW50KSk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy5kcm9wZG93blNlcnZpY2Uub3Blbih0aGlzLCB0aGlzLmNhbGN1bGF0ZUhlaWdodCwgdGhpcy5kaXNwbGF5VG9TaWRlKS50aGVuKCgpID0+IHtcclxuICAgICAgICAgICAgICAgIHRoaXMuaXNPcGVuID0gdHJ1ZTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQW5ndWxhcnMgT24gRGVzdHJveSBMaWZlY3ljbGUgSG9va1xyXG4gICAgICovXHJcbiAgICBwdWJsaWMgbmdPbkRlc3Ryb3koKSB7XHJcbiAgICAgICAgdGhpcy5jbG9zZSgpO1xyXG4gICAgICAgIC8vIHRoaXMudW5zdWJzY3JpYmVUb2dnbGVDbGljaygpO1xyXG5cclxuICAgICAgICBpZiAodGhpcy5sYXlvdXRDaGFuZ2VTdWJzY3JpYmVyKSB7XHJcbiAgICAgICAgICAgIHRoaXMubGF5b3V0Q2hhbmdlU3Vic2NyaWJlci51bnN1YnNjcmliZSgpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIE9wZW5zIHRoaXMgZHJvcGRvd25cclxuICAgICAqL1xyXG4gICAgcHVibGljIG9wZW4oKSB7XHJcbiAgICAgICAgdGhpcy50b2dnbGUodHJ1ZSwgdGhpcy5jYWxjdWxhdGVIZWlnaHQsIHRoaXMuZGlzcGxheVRvU2lkZSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBMaXN0ZW4gdG8ga2V5Ym9hcmQgZXZlbnQgYW5kIGNsb3NlIGRyb3Bkb3duIHdoZW4gdXNlcnMgZG8gbm90IGZvY3VzIG9uIGRyb3Bkb3duIGxpc3RcclxuICAgICAqL1xyXG4gICAgQEhvc3RMaXN0ZW5lcigna2V5dXAnLCBbJyRldmVudCddKVxyXG4gICAgcHVibGljIG9uS2V5dXAoZXZlbnQ6IEtleWJvYXJkRXZlbnQpIHtcclxuICAgICAgICBpZiAoZXZlbnQua2V5Q29kZSA9PT0gS2V5Q29kZS5UYWIpIHtcclxuICAgICAgICAgICAgbGV0IGVsZW1lbnQgPSA8SFRNTEVsZW1lbnQ+ZXZlbnQudGFyZ2V0O1xyXG4gICAgICAgICAgICB3aGlsZSAoIXRoaXMuY29udGVudEVsZW1lbnQubmF0aXZlRWxlbWVudC5pc1NhbWVOb2RlKGVsZW1lbnQpICYmICF0aGlzLmVsZW1lbnQubmF0aXZlRWxlbWVudC5pc1NhbWVOb2RlKGVsZW1lbnQpKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoZWxlbWVudC5jbGFzc0xpc3QuY29udGFpbnMoJ3NtZS1mb2N1cy10cmFwJykpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbGVtZW50ID0gZWxlbWVudC5wYXJlbnRFbGVtZW50O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHRoaXMuY2xvc2UoZXZlbnQpO1xyXG4gICAgICAgIH0gZWxzZSBpZiAoKGV2ZW50LmtleUNvZGUgPT09IEtleUNvZGUuTGVmdEFycm93ICYmICg8SFRNTEVsZW1lbnQ+ZXZlbnQudGFyZ2V0KS5jbGFzc05hbWUuaW5kZXhPZignc21lLWRyb3Bkb3duLXRvZ2dsZScpID4gLTEpKSB7XHJcbiAgICAgICAgICAgIHRoaXMuY2xvc2UoZXZlbnQpO1xyXG4gICAgICAgIH0gZWxzZSBpZiAoZXZlbnQua2V5Q29kZSA9PT0gS2V5Q29kZS5Fc2NhcGUpIHtcclxuICAgICAgICAgICAgLy8gcHJldmVudCBldmVudCBwcm9wYWdhdGlvbiB3aGVuIGluc2lkZSBhIGRpYWxvZ1xyXG4gICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcclxuICAgICAgICAgICAgZXZlbnQuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ2xvc2VzIHRoaXMgZHJvcGRvd25cclxuICAgICAqIEBwYXJhbSBldmVudCBrZXlib2FyZCBldmVudCBpbmNsdWRpbmcgdGhlIGN1cnJlbnQgZXZlbnQgdGFyZ2V0XHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBjbG9zZShldmVudD86IEtleWJvYXJkRXZlbnQpIHtcclxuICAgICAgICB0aGlzLnRvZ2dsZShmYWxzZSwgbnVsbCwgdGhpcy5kaXNwbGF5VG9TaWRlLCBldmVudCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUb2dnbGVzIHRoZSBkcm9wZG93blxyXG4gICAgICogQHBhcmFtIG9wZW4gT3B0aW9uYWwuIElmIHByb3ZpZGVkLCBmb3JjZXMgdGhlIGRyb3Bkb3duIG9wZW4gb3IgY2xvc2VkLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgdG9nZ2xlKG9wZW4/OiBib29sZWFuLCBjYWxjdWxhdGVIZWlnaHQ/OiBib29sZWFuLCBkaXNwbGF5VG9TaWRlPzogYm9vbGVhbiwgZXZlbnQ/OiBLZXlib2FyZEV2ZW50KSB7XHJcbiAgICAgICAgLy8gSWYgd2UgYXJlIGFscmVhZHkgaW4gdGhlIGNvcnJlY3Qgc3RhdGUsIHJldHVyblxyXG4gICAgICAgIGlmICghTXNmdFNtZS5pc051bGxPclVuZGVmaW5lZChvcGVuKSAmJiBvcGVuID09PSB0aGlzLmlzT3Blbikge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAodGhpcy5pc09wZW4pIHtcclxuICAgICAgICAgICAgLy8gY2xvc2UgaWYgb3BlbmVkXHJcbiAgICAgICAgICAgIHRoaXMuZHJvcGRvd25TZXJ2aWNlLmNsb3NlKHRoaXMpO1xyXG4gICAgICAgICAgICBpZiAoZXZlbnQpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuZHJvcGRvd25TZXJ2aWNlLmNsb3NlTmVzdGVkKHRoaXMsIGV2ZW50KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAvLyBlbWl0IHRoZSBjdXJyZW50IHN0YXRlIG9mIHRoZSBkcm9wZG93blxyXG4gICAgICAgICAgICB0aGlzLm9uVG9nZ2xlZC5lbWl0KHRoaXMuaXNPcGVuKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAvLyBvcGVuIGlmIGNsb3NlZFxyXG4gICAgICAgICAgICB0aGlzLmRyb3Bkb3duU2VydmljZS5vcGVuKHRoaXMsIGNhbGN1bGF0ZUhlaWdodCwgZGlzcGxheVRvU2lkZSkudGhlbigoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnRvZ2dsZUVsZW1lbnQubmF0aXZlRWxlbWVudC5hZGRFdmVudExpc3RlbmVyKCdjbG9zZUV2ZW50JywgKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaXNPcGVuID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICB9LCBmYWxzZSk7XHJcbiAgICAgICAgICAgICAgICAvLyBlbWl0IHRoZSBjdXJyZW50IHN0YXRlIG9mIHRoZSBkcm9wZG93blxyXG4gICAgICAgICAgICAgICAgdGhpcy5vblRvZ2dsZWQuZW1pdCh0aGlzLmlzT3Blbik7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBIYW5kbGVyIGZvciB0aGUgY2xpY2sgZXZlbnQgZm9yIHRoZSB0b2dnbGUgZWxlbWVudFxyXG4gICAgICogQHBhcmFtIGV2ZW50IHRoZSBtb3VzZSBldmVudCBvZiB0aGUgY2xpY2tcclxuICAgICAqIEBwYXJhbSBtYW51YWxUb2dnbGUgZGV0ZXJtaW5lIHdoZXRoZXIgdGhpcyBpcyBtYW51YWxseSB0b2dnbGVcclxuICAgICAqL1xyXG4gICAgcHVibGljIG9uVG9nZ2xlQ2xpY2soZXZlbnQ6IGFueSwgbWFudWFsVG9nZ2xlPzogYm9vbGVhbikge1xyXG4gICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xyXG5cclxuICAgICAgICBpZiAodGhpcy5hdXRvVG9nZ2xlIHx8IG1hbnVhbFRvZ2dsZSkge1xyXG4gICAgICAgICAgICAvLyB0b2dnbGUgdGhlIGRyb3Bkb3duIGlmIG5vdCBkaXNhYmxlZFxyXG4gICAgICAgICAgICBpZiAoIXRoaXMuZGlzYWJsZWQpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMudG9nZ2xlKG51bGwsIHRoaXMuY2FsY3VsYXRlSGVpZ2h0LCB0aGlzLmRpc3BsYXlUb1NpZGUpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcbn1cclxuIiwiPGRpdiAjc21lRHJvcGRvd25Ub2dnbGUgY2xhc3M9XCJzbWUtZHJvcGRvd24tdG9nZ2xlLWNvbnRhaW5lclwiIGRhdGEtdXRhLWlkPVwiZHJvcGRvd24tdG9nZ2xlXCI+XHJcbiAgPG5nLWNvbnRlbnQgc2VsZWN0PVwiLnNtZS1kcm9wZG93bi10b2dnbGVcIj48L25nLWNvbnRlbnQ+XHJcbjwvZGl2PlxyXG48ZGl2ICNzbWVEcm9wZG93bkNvbnRlbnRcclxuICBjbGFzcz1cInNtZS1sYXlvdXQtZHJvcGRvd24gc21lLWxheW91dC1maXhlZCBzbWUtcG9zaXRpb24tYmVsb3cgc21lLXNjaGVtZS1kcm9wZG93biBzbWUtbGF5ZXItbmF2IHNtZS1zaGFkb3ctZHJvcGRvd25cIlxyXG4gIFtuZ0NsYXNzXT1cInsnc21lLWxheW91dC1oaWRkZW4nOiAhaXNPcGVuLCAnc21lLWxheW91dC1pbmxpbmUtYmxvY2snOiBpc09wZW4sICdzbWUtYXJyYW5nZS1vdmVyZmxvdy1hdXRvLXgnOiBvdmVyZmxvd1gsICdzbWUtYXJyYW5nZS1vdmVyZmxvdy1hdXRvLXknOiBvdmVyZmxvd1l9XCJcclxuICBkYXRhLXV0YS1pZD1cImRyb3Bkb3duLWNvbnRlbnRcIj5cclxuICA8bmctY29udGVudCBzZWxlY3Q9XCIuc21lLWRyb3Bkb3duLWNvbnRlbnRcIj48L25nLWNvbnRlbnQ+XHJcbjwvZGl2PlxyXG4iXX0=