@microsoft/windows-admin-center-sdk
Version:
Microsoft - Windows Admin Center Shell
261 lines • 32.1 kB
JavaScript
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=