ngx-dropdown-menu-search
Version:
A simple Angular 6 dropdown menu with search.
163 lines (160 loc) • 20.4 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
import { Component, EventEmitter, Input, Output, ElementRef, ViewChild } from '@angular/core';
export class NgxDropdownMenuSearchComponent {
constructor() {
this.onDropdownClick = new EventEmitter();
this.onOptionSelect = new EventEmitter();
}
/**
* @return {?}
*/
ngOnInit() {
this.heightAndLineHeight = {
'height': this.config ? this.config.height : '20px',
'line-height': this.config ? this.config.lineHeight : '20px'
};
}
/**
* @return {?}
*/
dropdownClick() {
if (this.config && !this.config.isDisabled) {
this.optionsVisible = true;
this.onDropdownClick.emit();
//automatically select hidden input so we can quickly find an item
setTimeout(() => this.hiddenSearchInput.nativeElement.select(), 10);
}
}
/**
* @param {?} event
* @param {?} term
* @return {?}
*/
onInputChange(event, term) {
/** @type {?} */
let lowerCaseTerm = term.toLocaleLowerCase();
/** @type {?} */
let foundOption = this.options.find((option) => {
if (option.name) {
return this.includes(option.name.toLocaleLowerCase(), lowerCaseTerm);
}
});
this.scrollToFoundOption(foundOption);
this.selectOptionOnEnterClick(event, foundOption);
}
/**
* @param {?} option
* @param {?} name
* @return {?}
*/
onOptionClick(option, name) {
this.selectedOption = name;
this.optionsVisible = false;
this.onOptionSelect.emit(option);
}
/**
* @param {?} event
* @return {?}
*/
autoCloseDropdown(event) {
if (!event.target.closest(".dropdown")) {
this.optionsVisible = false;
}
}
/**
* @param {?} container
* @param {?} value
* @return {?}
*/
includes(container, value) {
if (container) {
/** @type {?} */
let includesValue;
/** @type {?} */
let index = container.indexOf(value);
if (index >= 0) {
includesValue = true;
}
return includesValue;
}
}
/**
* @param {?} foundOption
* @return {?}
*/
scrollToFoundOption(foundOption) {
if (foundOption) {
this.element = document.getElementById(foundOption.name);
this.element.scrollIntoView();
}
}
/**
* @param {?} event
* @param {?} foundOption
* @return {?}
*/
selectOptionOnEnterClick(event, foundOption) {
if (event.keyCode === 13) {
this.optionsVisible = false;
this.onOptionClick(foundOption, this.element.id);
}
}
}
NgxDropdownMenuSearchComponent.decorators = [
{ type: Component, args: [{
selector: 'ngx-dropdown-menu-search',
template: `<div class="ht0 dropdown relative" (window:mouseup)="autoCloseDropdown($event)">
<div [ngStyle]="heightAndLineHeight" *ngIf="!config?.searchEnabled || (config?.searchEnabled && !optionsVisible)" [ngClass]="{'disabled' : config?.isDisabled, 'cursorClass' : !config?.isDisabled, 'gray-border-darker' : !errorVisible, 'red-border-light' : errorVisible}" (click)="dropdownClick()" class="dropdown-label setBorder border-radius in-block setPadding">
<span class="in-block setMargin ellipsis">{{selectedOption}}</span>
<span [style.line-height]="config?.lineHeight" class="chevron-down-icon ft-size18"></span>
</div>
<input [ngStyle]="heightAndLineHeight" [(ngModel)]="searchTerm" *ngIf="optionsVisible && config?.searchEnabled" (click)="optionsVisible = true" class="dropdown setPadding setWidth100 border-radius gray-border-darker setBorder" type="text" placeholder="Search">
<div *ngIf="optionsVisible" style="width: 100%" [ngClass]="{'bottom0' : config?.flow === 'up'}" class="setMaxHeight scrollable mgn-bottom text-left shadow absolute z white-bg setZ border mgn-bottom50 gray-border-darker border-radius setPaddingTopBottom" id="{{config?.scrollbarVisible ? 'scrollbar-style' : null}}">
<ul *ngFor="let option of options | searchFilter:searchTerm; let i = index">
<li [ngClass]="{'gray-bg' : option.name === element?.id}" (mouseup)="onOptionClick(option, option.name)" id="{{option.name}}" class="option cursorClass">{{option.name}}<i *ngIf="option.name === selectedOption" class="fa fa-check mgn-left10" aria-hidden="true"></i></li>
</ul>
</div>
<input *ngIf="optionsVisible" #hiddenSearchInput type="text" class="hidden-search" (keyup)="onInputChange($event, hiddenSearchInput.value)">
</div>`,
styles: [`input:focus{outline:0}.dropdown-label{background-color:#fff;width:100%;position:relative}.bottom0{bottom:0}.chevron-down-icon{display:inline-block;width:8px;height:8px;border-bottom:1px solid #98999a;border-right:1px solid #98999a;position:absolute;right:.625em;top:50%;-webkit-transform:translateY(-50%) rotate(45deg);transform:translateY(-50%) rotate(45deg)}.gray-border-darker{border-color:#bbc0c3}.cursorClass{cursor:pointer}.hidden-search{position:absolute;width:50%;left:0;top:35px}.ft-size18{font-size:1.125rem}.absolute{position:absolute}.setPaddingTopBottom{padding-top:.063rem;padding-bottom:.063rem}.right10{right:.625rem;top:.5rem}.ellipsis{width:90%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.setPadding{padding-left:.5rem;padding-right:.5rem}.shadow{box-shadow:0 .125em .313em 0 rgba(0,0,0,.16),0 .125em .625em 0 rgba(0,0,0,.12)}.z{z-index:99}.white-bg{background-color:#fff}.setMargin{margin:0}.scrollable{overflow-y:scroll;overflow-x:hidden;-webkit-overflow-scrolling:touch}#scrollbar-style::-webkit-scrollbar-track{-webkit-box-shadow:inset 0 0 6px rgba(0,0,0,.3);border-radius:10px;background-color:#f6f8f8}#scrollbar-style::-webkit-scrollbar{width:5px;background-color:#f6f8f8}#scrollbar-style::-webkit-scrollbar-thumb{border-radius:10px;-webkit-box-shadow:inset 0 0 6px rgba(0,0,0,.3);background-color:#d6d9db}.mgn-bottom50{margin-bottom:3.125rem}.text-left{text-align:left}.setMaxHeight{max-height:14rem}.setLeft90{left:90%}.setWidth100{width:100%}.mgn-left10{margin-left:.625rem}.relative{position:relative}.border-radius{border-radius:.25em}.in-block{display:inline-block}.setPaddingLeft{padding-left:60px!important}.setPaddingLeft26{padding-left:26px!important}.option:hover{background-color:#e6e8e9}.setWidth50{width:50%}ul{padding-left:0;margin:0}ul li{padding-left:.5rem;padding-top:.2rem;padding-bottom:.2rem}.setBorder{border-width:1px;border-style:solid}.setZ{z-index:300}`]
},] },
];
/** @nocollapse */
NgxDropdownMenuSearchComponent.ctorParameters = () => [];
NgxDropdownMenuSearchComponent.propDecorators = {
errorVisible: [{ type: Input }],
options: [{ type: Input }],
selectedOption: [{ type: Input }],
config: [{ type: Input }],
onDropdownClick: [{ type: Output }],
onOptionSelect: [{ type: Output }],
hiddenSearchInput: [{ type: ViewChild, args: ['hiddenSearchInput',] }]
};
if (false) {
/** @type {?} */
NgxDropdownMenuSearchComponent.prototype.errorVisible;
/** @type {?} */
NgxDropdownMenuSearchComponent.prototype.options;
/** @type {?} */
NgxDropdownMenuSearchComponent.prototype.selectedOption;
/** @type {?} */
NgxDropdownMenuSearchComponent.prototype.config;
/** @type {?} */
NgxDropdownMenuSearchComponent.prototype.onDropdownClick;
/** @type {?} */
NgxDropdownMenuSearchComponent.prototype.onOptionSelect;
/** @type {?} */
NgxDropdownMenuSearchComponent.prototype.hiddenSearchInput;
/** @type {?} */
NgxDropdownMenuSearchComponent.prototype.element;
/** @type {?} */
NgxDropdownMenuSearchComponent.prototype.heightAndLineHeight;
/** @type {?} */
NgxDropdownMenuSearchComponent.prototype.optionsVisible;
/** @type {?} */
NgxDropdownMenuSearchComponent.prototype.searchTerm;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LWRyb3Bkb3duLW1lbnUtc2VhcmNoLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL25neC1kcm9wZG93bi1tZW51LXNlYXJjaC8iLCJzb3VyY2VzIjpbImxpYi9uZ3gtZHJvcGRvd24tbWVudS1zZWFyY2guY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7QUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQVUsTUFBTSxFQUFFLFVBQVUsRUFBRSxTQUFTLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFzQnRHLE1BQU07SUFrQkY7K0JBWGtELElBQUksWUFBWSxFQUFXOzhCQUM1QixJQUFJLFlBQVksRUFBVztLQVczRTs7OztJQUVELFFBQVE7UUFDSixJQUFJLENBQUMsbUJBQW1CLEdBQUc7WUFDdkIsUUFBUSxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxNQUFNO1lBQ25ELGFBQWEsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsTUFBTTtTQUMvRCxDQUFBO0tBQ0o7Ozs7SUFFTSxhQUFhO1FBQ2hCLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7WUFDekMsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLENBQUM7WUFDM0IsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLEVBQUUsQ0FBQzs7WUFFNUIsVUFBVSxDQUFFLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxhQUFhLENBQUMsTUFBTSxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUM7U0FDeEU7Ozs7Ozs7SUFHRSxhQUFhLENBQUMsS0FBSyxFQUFFLElBQVk7O1FBQ3RDLElBQUksYUFBYSxHQUFHLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDOztRQUM3QyxJQUFJLFdBQVcsR0FBSSxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBRSxDQUFDLE1BQU0sRUFBRSxFQUFFO1lBQzNDLEVBQUUsQ0FBQSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO2dCQUNmLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsaUJBQWlCLEVBQUUsRUFBRSxhQUFhLENBQUMsQ0FBQzthQUN0RTtTQUNKLENBQUMsQ0FBQztRQUNMLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUN0QyxJQUFJLENBQUMsd0JBQXdCLENBQUMsS0FBSyxFQUFFLFdBQVcsQ0FBQyxDQUFDOzs7Ozs7O0lBRzdDLGFBQWEsQ0FBQyxNQUFXLEVBQUUsSUFBUztRQUN2QyxJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQztRQUMzQixJQUFJLENBQUMsY0FBYyxHQUFHLEtBQUssQ0FBQztRQUM1QixJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQzs7Ozs7O0lBRzlCLGlCQUFpQixDQUFDLEtBQUs7UUFDMUIsRUFBRSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDckMsSUFBSSxDQUFDLGNBQWMsR0FBRyxLQUFLLENBQUM7U0FDL0I7Ozs7Ozs7SUFHRyxRQUFRLENBQUMsU0FBYyxFQUFFLEtBQWE7UUFDNUMsRUFBRSxDQUFBLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQzs7WUFDYixJQUFJLGFBQWEsQ0FBVTs7WUFDM0IsSUFBSSxLQUFLLEdBQVcsU0FBUyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUM3QyxFQUFFLENBQUEsQ0FBQyxLQUFLLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDWixhQUFhLEdBQUcsSUFBSSxDQUFDO2FBQ3hCO1lBQ0QsTUFBTSxDQUFDLGFBQWEsQ0FBQztTQUN0Qjs7Ozs7O0lBR0ssbUJBQW1CLENBQUMsV0FBVztRQUNuQyxFQUFFLENBQUEsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDO1lBQ2IsSUFBSSxDQUFDLE9BQU8sR0FBRyxRQUFRLENBQUMsY0FBYyxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUN6RCxJQUFJLENBQUMsT0FBTyxDQUFDLGNBQWMsRUFBRSxDQUFDO1NBQ2pDOzs7Ozs7O0lBR0csd0JBQXdCLENBQUMsS0FBSyxFQUFFLFdBQVc7UUFDL0MsRUFBRSxDQUFBLENBQUMsS0FBSyxDQUFDLE9BQU8sS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQ3RCLElBQUksQ0FBQyxjQUFjLEdBQUcsS0FBSyxDQUFDO1lBQzVCLElBQUksQ0FBQyxhQUFhLENBQUMsV0FBVyxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLENBQUM7U0FDcEQ7Ozs7WUFyR1IsU0FBUyxTQUFDO2dCQUNQLFFBQVEsRUFBRSwwQkFBMEI7Z0JBQ3BDLFFBQVEsRUFBRTs7Ozs7Ozs7Ozs7Ozs7T0FjUDtnQkFDSCxNQUFNLEVBQUUsQ0FBQywrM0RBQSszRCxDQUFDO2FBQzU0RDs7Ozs7MkJBR0ksS0FBSztzQkFDTCxLQUFLOzZCQUNMLEtBQUs7cUJBQ0wsS0FBSzs4QkFFTCxNQUFNOzZCQUNOLE1BQU07Z0NBRU4sU0FBUyxTQUFDLG1CQUFtQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgRXZlbnRFbWl0dGVyLCBJbnB1dCwgT25Jbml0LCBPdXRwdXQsIEVsZW1lbnRSZWYsIFZpZXdDaGlsZCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgSUNvbmZpZyB9IGZyb20gJy4vY29uZmlnLm1vZGVscyc7XG5cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAnbmd4LWRyb3Bkb3duLW1lbnUtc2VhcmNoJyxcbiAgICB0ZW1wbGF0ZTogYDxkaXYgY2xhc3M9XCJodDAgZHJvcGRvd24gcmVsYXRpdmVcIiAod2luZG93Om1vdXNldXApPVwiYXV0b0Nsb3NlRHJvcGRvd24oJGV2ZW50KVwiPlxuXHQ8ZGl2IFtuZ1N0eWxlXT1cImhlaWdodEFuZExpbmVIZWlnaHRcIiAqbmdJZj1cIiFjb25maWc/LnNlYXJjaEVuYWJsZWQgfHwgKGNvbmZpZz8uc2VhcmNoRW5hYmxlZCAmJiAhb3B0aW9uc1Zpc2libGUpXCIgW25nQ2xhc3NdPVwieydkaXNhYmxlZCcgOiBjb25maWc/LmlzRGlzYWJsZWQsICdjdXJzb3JDbGFzcycgOiAhY29uZmlnPy5pc0Rpc2FibGVkLCAnZ3JheS1ib3JkZXItZGFya2VyJyA6ICFlcnJvclZpc2libGUsICdyZWQtYm9yZGVyLWxpZ2h0JyA6IGVycm9yVmlzaWJsZX1cIiAgKGNsaWNrKT1cImRyb3Bkb3duQ2xpY2soKVwiIGNsYXNzPVwiZHJvcGRvd24tbGFiZWwgc2V0Qm9yZGVyIGJvcmRlci1yYWRpdXMgaW4tYmxvY2sgc2V0UGFkZGluZ1wiPlxuXHRcdDxzcGFuIGNsYXNzPVwiaW4tYmxvY2sgc2V0TWFyZ2luIGVsbGlwc2lzXCI+e3tzZWxlY3RlZE9wdGlvbn19PC9zcGFuPlxuXHRcdDxzcGFuIFtzdHlsZS5saW5lLWhlaWdodF09XCJjb25maWc/LmxpbmVIZWlnaHRcIiBjbGFzcz1cImNoZXZyb24tZG93bi1pY29uIGZ0LXNpemUxOFwiPjwvc3Bhbj5cblx0PC9kaXY+XG5cblx0PGlucHV0IFtuZ1N0eWxlXT1cImhlaWdodEFuZExpbmVIZWlnaHRcIiBbKG5nTW9kZWwpXT1cInNlYXJjaFRlcm1cIiAqbmdJZj1cIm9wdGlvbnNWaXNpYmxlICYmIGNvbmZpZz8uc2VhcmNoRW5hYmxlZFwiIChjbGljayk9XCJvcHRpb25zVmlzaWJsZSA9IHRydWVcIiBjbGFzcz1cImRyb3Bkb3duIHNldFBhZGRpbmcgc2V0V2lkdGgxMDAgYm9yZGVyLXJhZGl1cyBncmF5LWJvcmRlci1kYXJrZXIgc2V0Qm9yZGVyXCIgdHlwZT1cInRleHRcIiBwbGFjZWhvbGRlcj1cIlNlYXJjaFwiPlxuXG5cdDxkaXYgKm5nSWY9XCJvcHRpb25zVmlzaWJsZVwiIHN0eWxlPVwid2lkdGg6IDEwMCVcIiBbbmdDbGFzc109XCJ7J2JvdHRvbTAnIDogY29uZmlnPy5mbG93ID09PSAndXAnfVwiIGNsYXNzPVwic2V0TWF4SGVpZ2h0IHNjcm9sbGFibGUgbWduLWJvdHRvbSB0ZXh0LWxlZnQgc2hhZG93IGFic29sdXRlIHogd2hpdGUtYmcgc2V0WiBib3JkZXIgbWduLWJvdHRvbTUwIGdyYXktYm9yZGVyLWRhcmtlciBib3JkZXItcmFkaXVzIHNldFBhZGRpbmdUb3BCb3R0b21cIiBpZD1cInt7Y29uZmlnPy5zY3JvbGxiYXJWaXNpYmxlID8gJ3Njcm9sbGJhci1zdHlsZScgOiBudWxsfX1cIj5cblx0XHQ8dWwgKm5nRm9yPVwibGV0IG9wdGlvbiBvZiBvcHRpb25zIHwgc2VhcmNoRmlsdGVyOnNlYXJjaFRlcm07IGxldCBpID0gaW5kZXhcIj5cblx0XHRcdDxsaSBbbmdDbGFzc109XCJ7J2dyYXktYmcnIDogb3B0aW9uLm5hbWUgPT09IGVsZW1lbnQ/LmlkfVwiIChtb3VzZXVwKT1cIm9uT3B0aW9uQ2xpY2sob3B0aW9uLCBvcHRpb24ubmFtZSlcIiBpZD1cInt7b3B0aW9uLm5hbWV9fVwiICBjbGFzcz1cIm9wdGlvbiBjdXJzb3JDbGFzc1wiPnt7b3B0aW9uLm5hbWV9fTxpICpuZ0lmPVwib3B0aW9uLm5hbWUgPT09IHNlbGVjdGVkT3B0aW9uXCIgY2xhc3M9XCJmYSBmYS1jaGVjayBtZ24tbGVmdDEwXCIgYXJpYS1oaWRkZW49XCJ0cnVlXCI+PC9pPjwvbGk+XG5cdFx0PC91bD5cblx0PC9kaXY+XG5cdDxpbnB1dCAqbmdJZj1cIm9wdGlvbnNWaXNpYmxlXCIgI2hpZGRlblNlYXJjaElucHV0IHR5cGU9XCJ0ZXh0XCIgY2xhc3M9XCJoaWRkZW4tc2VhcmNoXCIgKGtleXVwKT1cIm9uSW5wdXRDaGFuZ2UoJGV2ZW50LCBoaWRkZW5TZWFyY2hJbnB1dC52YWx1ZSlcIj5cbjwvZGl2PmAsXG4gICAgc3R5bGVzOiBbYGlucHV0OmZvY3Vze291dGxpbmU6MH0uZHJvcGRvd24tbGFiZWx7YmFja2dyb3VuZC1jb2xvcjojZmZmO3dpZHRoOjEwMCU7cG9zaXRpb246cmVsYXRpdmV9LmJvdHRvbTB7Ym90dG9tOjB9LmNoZXZyb24tZG93bi1pY29ue2Rpc3BsYXk6aW5saW5lLWJsb2NrO3dpZHRoOjhweDtoZWlnaHQ6OHB4O2JvcmRlci1ib3R0b206MXB4IHNvbGlkICM5ODk5OWE7Ym9yZGVyLXJpZ2h0OjFweCBzb2xpZCAjOTg5OTlhO3Bvc2l0aW9uOmFic29sdXRlO3JpZ2h0Oi42MjVlbTt0b3A6NTAlOy13ZWJraXQtdHJhbnNmb3JtOnRyYW5zbGF0ZVkoLTUwJSkgcm90YXRlKDQ1ZGVnKTt0cmFuc2Zvcm06dHJhbnNsYXRlWSgtNTAlKSByb3RhdGUoNDVkZWcpfS5ncmF5LWJvcmRlci1kYXJrZXJ7Ym9yZGVyLWNvbG9yOiNiYmMwYzN9LmN1cnNvckNsYXNze2N1cnNvcjpwb2ludGVyfS5oaWRkZW4tc2VhcmNoe3Bvc2l0aW9uOmFic29sdXRlO3dpZHRoOjUwJTtsZWZ0OjA7dG9wOjM1cHh9LmZ0LXNpemUxOHtmb250LXNpemU6MS4xMjVyZW19LmFic29sdXRle3Bvc2l0aW9uOmFic29sdXRlfS5zZXRQYWRkaW5nVG9wQm90dG9te3BhZGRpbmctdG9wOi4wNjNyZW07cGFkZGluZy1ib3R0b206LjA2M3JlbX0ucmlnaHQxMHtyaWdodDouNjI1cmVtO3RvcDouNXJlbX0uZWxsaXBzaXN7d2lkdGg6OTAlO292ZXJmbG93OmhpZGRlbjt0ZXh0LW92ZXJmbG93OmVsbGlwc2lzO3doaXRlLXNwYWNlOm5vd3JhcH0uc2V0UGFkZGluZ3twYWRkaW5nLWxlZnQ6LjVyZW07cGFkZGluZy1yaWdodDouNXJlbX0uc2hhZG93e2JveC1zaGFkb3c6MCAuMTI1ZW0gLjMxM2VtIDAgcmdiYSgwLDAsMCwuMTYpLDAgLjEyNWVtIC42MjVlbSAwIHJnYmEoMCwwLDAsLjEyKX0uent6LWluZGV4Ojk5fS53aGl0ZS1iZ3tiYWNrZ3JvdW5kLWNvbG9yOiNmZmZ9LnNldE1hcmdpbnttYXJnaW46MH0uc2Nyb2xsYWJsZXtvdmVyZmxvdy15OnNjcm9sbDtvdmVyZmxvdy14OmhpZGRlbjstd2Via2l0LW92ZXJmbG93LXNjcm9sbGluZzp0b3VjaH0jc2Nyb2xsYmFyLXN0eWxlOjotd2Via2l0LXNjcm9sbGJhci10cmFja3std2Via2l0LWJveC1zaGFkb3c6aW5zZXQgMCAwIDZweCByZ2JhKDAsMCwwLC4zKTtib3JkZXItcmFkaXVzOjEwcHg7YmFja2dyb3VuZC1jb2xvcjojZjZmOGY4fSNzY3JvbGxiYXItc3R5bGU6Oi13ZWJraXQtc2Nyb2xsYmFye3dpZHRoOjVweDtiYWNrZ3JvdW5kLWNvbG9yOiNmNmY4Zjh9I3Njcm9sbGJhci1zdHlsZTo6LXdlYmtpdC1zY3JvbGxiYXItdGh1bWJ7Ym9yZGVyLXJhZGl1czoxMHB4Oy13ZWJraXQtYm94LXNoYWRvdzppbnNldCAwIDAgNnB4IHJnYmEoMCwwLDAsLjMpO2JhY2tncm91bmQtY29sb3I6I2Q2ZDlkYn0ubWduLWJvdHRvbTUwe21hcmdpbi1ib3R0b206My4xMjVyZW19LnRleHQtbGVmdHt0ZXh0LWFsaWduOmxlZnR9LnNldE1heEhlaWdodHttYXgtaGVpZ2h0OjE0cmVtfS5zZXRMZWZ0OTB7bGVmdDo5MCV9LnNldFdpZHRoMTAwe3dpZHRoOjEwMCV9Lm1nbi1sZWZ0MTB7bWFyZ2luLWxlZnQ6LjYyNXJlbX0ucmVsYXRpdmV7cG9zaXRpb246cmVsYXRpdmV9LmJvcmRlci1yYWRpdXN7Ym9yZGVyLXJhZGl1czouMjVlbX0uaW4tYmxvY2t7ZGlzcGxheTppbmxpbmUtYmxvY2t9LnNldFBhZGRpbmdMZWZ0e3BhZGRpbmctbGVmdDo2MHB4IWltcG9ydGFudH0uc2V0UGFkZGluZ0xlZnQyNntwYWRkaW5nLWxlZnQ6MjZweCFpbXBvcnRhbnR9Lm9wdGlvbjpob3ZlcntiYWNrZ3JvdW5kLWNvbG9yOiNlNmU4ZTl9LnNldFdpZHRoNTB7d2lkdGg6NTAlfXVse3BhZGRpbmctbGVmdDowO21hcmdpbjowfXVsIGxpe3BhZGRpbmctbGVmdDouNXJlbTtwYWRkaW5nLXRvcDouMnJlbTtwYWRkaW5nLWJvdHRvbTouMnJlbX0uc2V0Qm9yZGVye2JvcmRlci13aWR0aDoxcHg7Ym9yZGVyLXN0eWxlOnNvbGlkfS5zZXRae3otaW5kZXg6MzAwfWBdXG59KVxuZXhwb3J0IGNsYXNzIE5neERyb3Bkb3duTWVudVNlYXJjaENvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XG5cbiAgICBASW5wdXQoKSBlcnJvclZpc2libGU6IGJvb2xlYW47XG4gICAgQElucHV0KCkgb3B0aW9uczogYW55W107XG4gICAgQElucHV0KCkgc2VsZWN0ZWRPcHRpb246IGFueTtcbiAgICBASW5wdXQoKSBjb25maWc6IElDb25maWc7XG5cbiAgICBAT3V0cHV0KCkgb25Ecm9wZG93bkNsaWNrOiBFdmVudEVtaXR0ZXIgPCBhbnkgPiA9IG5ldyBFdmVudEVtaXR0ZXIgPCBhbnkgPiAoKTtcbiAgICBAT3V0cHV0KCkgb25PcHRpb25TZWxlY3Q6IEV2ZW50RW1pdHRlciA8IGFueSA+ID0gbmV3IEV2ZW50RW1pdHRlciA8IGFueSA+ICgpO1xuXG4gICAgQFZpZXdDaGlsZCgnaGlkZGVuU2VhcmNoSW5wdXQnKSBoaWRkZW5TZWFyY2hJbnB1dDogRWxlbWVudFJlZjtcblxuICAgIHB1YmxpYyBlbGVtZW50OiBhbnk7XG4gICAgcHVibGljIGhlaWdodEFuZExpbmVIZWlnaHQ6IGFueTtcbiAgICBwdWJsaWMgb3B0aW9uc1Zpc2libGU6IGJvb2xlYW47XG4gICAgcHVibGljIHNlYXJjaFRlcm06IHN0cmluZztcblxuXG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgfVxuXG4gICAgbmdPbkluaXQoKSB7XG4gICAgICAgIHRoaXMuaGVpZ2h0QW5kTGluZUhlaWdodCA9IHtcbiAgICAgICAgICAgICdoZWlnaHQnOiB0aGlzLmNvbmZpZyA/IHRoaXMuY29uZmlnLmhlaWdodCA6ICcyMHB4JyxcbiAgICAgICAgICAgICdsaW5lLWhlaWdodCc6IHRoaXMuY29uZmlnID8gdGhpcy5jb25maWcubGluZUhlaWdodCA6ICcyMHB4J1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIGRyb3Bkb3duQ2xpY2soKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLmNvbmZpZyAmJiAhdGhpcy5jb25maWcuaXNEaXNhYmxlZCkge1xuICAgICAgICAgICAgdGhpcy5vcHRpb25zVmlzaWJsZSA9IHRydWU7XG4gICAgICAgICAgICB0aGlzLm9uRHJvcGRvd25DbGljay5lbWl0KCk7XG4gICAgICAgICAgICAvL2F1dG9tYXRpY2FsbHkgc2VsZWN0IGhpZGRlbiBpbnB1dCBzbyB3ZSBjYW4gcXVpY2tseSBmaW5kIGFuIGl0ZW1cbiAgICAgICAgICAgIHNldFRpbWVvdXQoICgpID0+IHRoaXMuaGlkZGVuU2VhcmNoSW5wdXQubmF0aXZlRWxlbWVudC5zZWxlY3QoKSwgMTApOyBcbiAgICAgICAgfSBcbiAgICB9XG5cbiAgICBwdWJsaWMgb25JbnB1dENoYW5nZShldmVudCwgdGVybTogc3RyaW5nKTogdm9pZCB7XG4gICAgICBsZXQgbG93ZXJDYXNlVGVybSA9IHRlcm0udG9Mb2NhbGVMb3dlckNhc2UoKTtcbiAgICAgIGxldCBmb3VuZE9wdGlvbiA9ICB0aGlzLm9wdGlvbnMuZmluZCggKG9wdGlvbikgPT4ge1xuICAgICAgICAgICAgaWYob3B0aW9uLm5hbWUpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuaW5jbHVkZXMob3B0aW9uLm5hbWUudG9Mb2NhbGVMb3dlckNhc2UoKSwgbG93ZXJDYXNlVGVybSk7ICBcbiAgICAgICAgICAgIH0gICAgICAgICAgIFxuICAgICAgICB9KTtcbiAgICAgIHRoaXMuc2Nyb2xsVG9Gb3VuZE9wdGlvbihmb3VuZE9wdGlvbik7ICAgICBcbiAgICAgIHRoaXMuc2VsZWN0T3B0aW9uT25FbnRlckNsaWNrKGV2ZW50LCBmb3VuZE9wdGlvbik7XG4gICAgfVxuXG4gICAgcHVibGljIG9uT3B0aW9uQ2xpY2sob3B0aW9uOiBhbnksIG5hbWU6IGFueSk6IHZvaWQge1xuICAgICAgICB0aGlzLnNlbGVjdGVkT3B0aW9uID0gbmFtZTtcbiAgICAgICAgdGhpcy5vcHRpb25zVmlzaWJsZSA9IGZhbHNlO1xuICAgICAgICB0aGlzLm9uT3B0aW9uU2VsZWN0LmVtaXQob3B0aW9uKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgYXV0b0Nsb3NlRHJvcGRvd24oZXZlbnQpIHtcbiAgICAgICAgaWYgKCFldmVudC50YXJnZXQuY2xvc2VzdChcIi5kcm9wZG93blwiKSkge1xuICAgICAgICAgICAgdGhpcy5vcHRpb25zVmlzaWJsZSA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBpbmNsdWRlcyhjb250YWluZXI6IGFueSwgdmFsdWU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgICAgaWYoY29udGFpbmVyKSB7XG4gICAgICAgIGxldCBpbmNsdWRlc1ZhbHVlOiBib29sZWFuO1xuICAgICAgICBsZXQgaW5kZXg6IG51bWJlciA9IGNvbnRhaW5lci5pbmRleE9mKHZhbHVlKTtcbiAgICAgICAgaWYoaW5kZXggPj0gMCkge1xuICAgICAgICAgICAgaW5jbHVkZXNWYWx1ZSA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGluY2x1ZGVzVmFsdWU7XG4gICAgICB9ICAgICAgXG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzY3JvbGxUb0ZvdW5kT3B0aW9uKGZvdW5kT3B0aW9uKTogdm9pZCB7XG4gICAgICAgIGlmKGZvdW5kT3B0aW9uKSB7XG4gICAgICAgICAgICB0aGlzLmVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChmb3VuZE9wdGlvbi5uYW1lKTtcbiAgICAgICAgICAgIHRoaXMuZWxlbWVudC5zY3JvbGxJbnRvVmlldygpOyAgICAgICAgICBcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgc2VsZWN0T3B0aW9uT25FbnRlckNsaWNrKGV2ZW50LCBmb3VuZE9wdGlvbik6IHZvaWQge1xuICAgICAgICBpZihldmVudC5rZXlDb2RlID09PSAxMykge1xuICAgICAgICAgICAgdGhpcy5vcHRpb25zVmlzaWJsZSA9IGZhbHNlO1xuICAgICAgICAgICAgdGhpcy5vbk9wdGlvbkNsaWNrKGZvdW5kT3B0aW9uLCB0aGlzLmVsZW1lbnQuaWQpO1xuICAgICAgICB9XG4gICAgfVxuXG5cbn1cbiJdfQ==