ngx-mat-dropdown
Version:
Angular Dropdown with search/filter option
681 lines • 60.7 kB
JavaScript
/**
* @fileoverview added by tsickle
* Generated from: lib/mat-select-search/mat-select-search.component.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, EventEmitter, forwardRef, Inject, Input, ViewChild, HostBinding, Optional } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { MatSelect } from '@angular/material/select';
import { delay, take, takeUntil } from 'rxjs/operators';
import { Subject } from 'rxjs';
import { MatOption } from '@angular/material/core';
var MatSelectSearchComponent = /** @class */ (function () {
function MatSelectSearchComponent(matSelect, changeDetectorRef, matOption) {
if (matOption === void 0) { matOption = null; }
this.matSelect = matSelect;
this.changeDetectorRef = changeDetectorRef;
this.matOption = matOption;
/**
* Label of the search placeholder
*/
this.placeholderLabel = 'Search';
this.multiple = false;
this.showSearch = true;
/**
* Label to be shown when no entries are found. Set to null if no message should be shown.
*/
this.noEntriesFoundLabel = 'No Data';
this.onChange = (/**
* @param {?} _
* @return {?}
*/
function (_) { });
this.onTouched = (/**
* @param {?} _
* @return {?}
*/
function (_) { });
/**
* Whether the backdrop class has been set
*/
this.overlayClassSet = false;
/**
* Event that emits when the current value changes
*/
this.change = new EventEmitter();
this.AllClicked = new EventEmitter();
/**
* Subject that emits when the component has been destroyed.
*/
this._onDestroy = new Subject();
}
Object.defineProperty(MatSelectSearchComponent.prototype, "isInsideMatOption", {
//@ViewChild('innerSelectall', { read: ElementRef }) innerSelectall: ElementRef;
get:
//@ViewChild('innerSelectall', { read: ElementRef }) innerSelectall: ElementRef;
/**
* @return {?}
*/
function () {
return !!this.matOption;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MatSelectSearchComponent.prototype, "value", {
/** Current search value */
get: /**
* Current search value
* @return {?}
*/
function () {
return this._value;
},
enumerable: true,
configurable: true
});
/**
* @return {?}
*/
MatSelectSearchComponent.prototype.ngOnInit = /**
* @return {?}
*/
function () {
var _this = this;
// set custom panel class
/** @type {?} */
var panelClass = 'mat-select-search-panel';
if (this.matSelect.panelClass) {
if (Array.isArray(this.matSelect.panelClass)) {
this.matSelect.panelClass.push(panelClass);
}
else if (typeof this.matSelect.panelClass === 'string') {
this.matSelect.panelClass = [this.matSelect.panelClass, panelClass];
}
else if (typeof this.matSelect.panelClass === 'object') {
this.matSelect.panelClass[panelClass] = true;
}
}
else {
this.matSelect.panelClass = panelClass;
}
// set custom mat-option class if the component was placed inside a mat-option
if (this.matOption) {
this.matOption.disabled = true;
this.matOption._getHostElement().classList.add('contains-mat-select-search');
}
// when the select dropdown panel is opened or closed
this.matSelect.openedChange
// .pipe(takeUntil(this._onDestroy))
.pipe(delay(1), takeUntil(this._onDestroy))
.subscribe((/**
* @param {?} opened
* @return {?}
*/
function (opened) {
if (opened) {
// focus the search field when opening
_this.getWidth();
_this._focus();
}
else {
// clear it when closing
_this._reset();
}
}));
// set the first item active after the options changed
this.matSelect.openedChange
.pipe(take(1))
.pipe(takeUntil(this._onDestroy))
.subscribe((/**
* @return {?}
*/
function () {
_this._options = _this.matSelect.options;
_this._options.changes
.pipe(takeUntil(_this._onDestroy))
.subscribe((/**
* @return {?}
*/
function () {
/** @type {?} */
var keyManager = _this.matSelect._keyManager;
if (keyManager && _this.matSelect.panelOpen) {
// avoid "expression has been changed" error
setTimeout((/**
* @return {?}
*/
function () {
keyManager.setFirstItemActive();
_this.getWidth();
// set no entries found class on mat option
if (_this.matOption) {
if (_this._noEntriesFound()) {
_this.matOption._getHostElement().classList.add('mat-select-search-no-entries-found');
}
else {
_this.matOption._getHostElement().classList.remove('mat-select-search-no-entries-found');
}
}
}), 1);
}
}));
}));
// detect changes when the input changes
this.change
.pipe(takeUntil(this._onDestroy))
.subscribe((/**
* @return {?}
*/
function () {
_this.changeDetectorRef.detectChanges();
}));
this.initMultipleHandling();
};
/**
* @return {?}
*/
MatSelectSearchComponent.prototype.ngOnDestroy = /**
* @return {?}
*/
function () {
this._onDestroy.next();
this._onDestroy.complete();
};
/**
* @return {?}
*/
MatSelectSearchComponent.prototype.ngAfterViewInit = /**
* @return {?}
*/
function () {
var _this = this;
setTimeout((/**
* @return {?}
*/
function () {
_this.setOverlayClass();
}));
this.matSelect.openedChange
.pipe(take(1), takeUntil(this._onDestroy)).subscribe((/**
* @return {?}
*/
function () {
_this.matSelect.options.changes
.pipe(takeUntil(_this._onDestroy))
.subscribe((/**
* @return {?}
*/
function () {
_this.changeDetectorRef.markForCheck();
}));
}));
};
/**
* @param {?} event
* @return {?}
*/
MatSelectSearchComponent.prototype._handleKeydown = /**
* @param {?} event
* @return {?}
*/
function (event) {
if (event.keyCode === 32) {
// do not propagate spaces to MatSelect, as this would select the currently active option
event.stopPropagation();
}
};
/**
* @param {?} value
* @return {?}
*/
MatSelectSearchComponent.prototype.writeValue = /**
* @param {?} value
* @return {?}
*/
function (value) {
/** @type {?} */
var valueChanged = value !== this._value;
if (valueChanged) {
this._value = value;
this.change.emit({ type: 'Text', val: value });
}
};
/**
* @param {?} value
* @return {?}
*/
MatSelectSearchComponent.prototype.onInputChange = /**
* @param {?} value
* @return {?}
*/
function (value) {
/** @type {?} */
var valueChanged = value !== this._value;
if (valueChanged) {
this._value = value;
this.onChange({ type: 'Text', val: value });
this.change.emit({ type: 'Text', val: value });
}
};
/**
* @param {?} value
* @return {?}
*/
MatSelectSearchComponent.prototype.onBlur = /**
* @param {?} value
* @return {?}
*/
function (value) {
this.writeValue(value);
this.onTouched();
};
/**
* @param {?} fn
* @return {?}
*/
MatSelectSearchComponent.prototype.registerOnChange = /**
* @param {?} fn
* @return {?}
*/
function (fn) {
this.onChange = fn;
};
/**
* @param {?} fn
* @return {?}
*/
MatSelectSearchComponent.prototype.registerOnTouched = /**
* @param {?} fn
* @return {?}
*/
function (fn) {
this.onTouched = fn;
};
/**
* @return {?}
*/
MatSelectSearchComponent.prototype._focus = /**
* @return {?}
*/
function () {
if (!this.searchSelectInput || !this.matSelect.panel) {
return;
}
// save and restore scrollTop of panel, since it will be reset by focus()
// note: this is hacky
/** @type {?} */
var panel = this.matSelect.panel.nativeElement;
/** @type {?} */
var scrollTop = panel.scrollTop;
// focus
this.searchSelectInput.nativeElement.focus();
panel.scrollTop = scrollTop;
};
/**
* Resets the current search value
* {boolean} focus whether to focus after resetting
*
*/
/**
* Resets the current search value
* {boolean} focus whether to focus after resetting
*
* @param {?=} focus
* @return {?}
*/
MatSelectSearchComponent.prototype._reset = /**
* Resets the current search value
* {boolean} focus whether to focus after resetting
*
* @param {?=} focus
* @return {?}
*/
function (focus) {
if (!this.searchSelectInput) {
return;
}
this.searchSelectInput.nativeElement.value = '';
this.onInputChange('');
if (focus) {
this._focus();
}
};
/**
* Sets the overlay class to correct offsetY
* so that the selected option is at the position of the select box when opening
*/
/**
* Sets the overlay class to correct offsetY
* so that the selected option is at the position of the select box when opening
* @private
* @return {?}
*/
MatSelectSearchComponent.prototype.setOverlayClass = /**
* Sets the overlay class to correct offsetY
* so that the selected option is at the position of the select box when opening
* @private
* @return {?}
*/
function () {
var _this = this;
if (this.overlayClassSet) {
return;
}
/** @type {?} */
var overlayClasses = ['cdk-overlay-pane-select-search'];
if (!this.matOption) {
// add offset to panel if component is not placed inside mat-option
overlayClasses.push('cdk-overlay-pane-select-search-with-offset');
}
this.matSelect.overlayDir.attach
.pipe(takeUntil(this._onDestroy))
.subscribe((/**
* @return {?}
*/
function () {
// note: this is hacky, but currently there is no better way to do this
// note: this is hacky, but currently there is no better way to do this
/** @type {?} */
var element;
/** @type {?} */
var overlayElement;
if (_this.searchSelectInput) {
element = _this.searchSelectInput.nativeElement;
while (element = element.parentElement) {
if (element.classList.contains('cdk-overlay-pane')) {
overlayElement = element;
break;
}
}
}
if (overlayElement) {
overlayClasses.forEach((/**
* @param {?} overlayClass
* @return {?}
*/
function (overlayClass) {
overlayElement.classList.add(overlayClass);
}));
}
}));
this.overlayClassSet = true;
};
/**
* Initializes handling <mat-select [multiple]="true">
* Note: to improve this code, mat-select should be extended to allow disabling resetting the selection while filtering.
*/
/**
* Initializes handling <mat-select [multiple]="true">
* Note: to improve this code, mat-select should be extended to allow disabling resetting the selection while filtering.
* @private
* @return {?}
*/
MatSelectSearchComponent.prototype.initMultipleHandling = /**
* Initializes handling <mat-select [multiple]="true">
* Note: to improve this code, mat-select should be extended to allow disabling resetting the selection while filtering.
* @private
* @return {?}
*/
function () {
var _this = this;
// if <mat-select [multiple]="true">
// store previously selected values and restore them when they are deselected
// because the option is not available while we are currently filtering
this.matSelect.valueChange
.pipe(takeUntil(this._onDestroy))
.subscribe((/**
* @param {?} values
* @return {?}
*/
function (values) {
if (_this.matSelect.multiple) {
/** @type {?} */
var restoreSelectedValues_1 = false;
if (_this._value && _this._value.length
&& _this.previousSelectedValues && Array.isArray(_this.previousSelectedValues)) {
if (!values || !Array.isArray(values)) {
values = [];
}
/** @type {?} */
var optionValues_1 = _this.matSelect.options.map((/**
* @param {?} option
* @return {?}
*/
function (option) { return option.value; }));
_this.previousSelectedValues.forEach((/**
* @param {?} previousValue
* @return {?}
*/
function (previousValue) {
if (values.indexOf(previousValue) === -1 && optionValues_1.indexOf(previousValue) === -1) {
// if a value that was selected before is deselected and not found in the options, it was deselected
// due to the filtering, so we restore it.
values.push(previousValue);
restoreSelectedValues_1 = true;
}
}));
}
if (restoreSelectedValues_1) {
_this.matSelect._onChange(values);
}
_this.previousSelectedValues = values;
}
}));
};
/**
* @private
* @return {?}
*/
MatSelectSearchComponent.prototype.getWidth = /**
* @private
* @return {?}
*/
function () {
if (!this.innerSelectSearch || !this.innerSelectSearch.nativeElement) {
return;
}
/** @type {?} */
var element = this.innerSelectSearch.nativeElement;
/** @type {?} */
var panelElement;
while (element = element.parentElement) {
if (element.classList.contains('mat-select-panel')) {
panelElement = element;
break;
}
}
if (panelElement) {
this.innerSelectSearch.nativeElement.style.width = panelElement.clientWidth + 'px';
}
////innerSelectall
//if (!this.innerSelectall || !this.innerSelectall.nativeElement) {
// return;
//}
//let Selectallelement: HTMLElement = this.innerSelectall.nativeElement;
//let SelectallpanelElement: HTMLElement;
//while (Selectallelement = Selectallelement.parentElement) {
// if (Selectallelement.classList.contains('mat-select-panel')) {
// SelectallpanelElement = Selectallelement;
// break;
// }
//}
//if (SelectallpanelElement) {
// this.innerSelectall.nativeElement.style.width = SelectallpanelElement.clientWidth + 'px';
//}
};
/**
* @return {?}
*/
MatSelectSearchComponent.prototype._noEntriesFound = /**
* @return {?}
*/
function () {
if (!this._options) {
return;
}
if (this.matOption) {
return this.noEntriesFoundLabel && this.value && this._options.length === 1;
}
else {
return this.noEntriesFoundLabel && this.value && this._options.length === 0;
}
};
/**
* @param {?} change
* @param {?} check
* @return {?}
*/
MatSelectSearchComponent.prototype.toggleSelection = /**
* @param {?} change
* @param {?} check
* @return {?}
*/
function (change, check) {
if (change.checked) {
//this.model.update.emit(this.values);
this.onChange({ type: 'Check', val: change.checked });
this.change.emit({ type: 'Check', val: change.checked });
}
else {
this.onChange({ type: 'Check', val: change.checked });
this.change.emit({ type: 'Check', val: change.checked });
}
};
/**
* @param {?} check
* @return {?}
*/
MatSelectSearchComponent.prototype.ischecked = /**
* @param {?} check
* @return {?}
*/
function (check) {
console.log(this.matSelect.options, this.matSelect.value);
/** @type {?} */
var selected = this.matSelect.selected;
return this.matSelect.options && selected && selected.length > 0 && this.matSelect.options.length == selected.length;
};
/**
* @return {?}
*/
MatSelectSearchComponent.prototype.isIndeterminate = /**
* @return {?}
*/
function () {
/** @type {?} */
var selected = this.matSelect.selected;
return this.matSelect.options && selected.length > 0 && selected.length < this.matSelect.options.length;
};
MatSelectSearchComponent.decorators = [
{ type: Component, args: [{
selector: 'mat-select-search',
template: "\r\n<input *ngIf=\"showSearch\" matInput class=\"mat-select-search-input mat-select-search-hidden\" />\r\n<input matInput class=\"mat-select-checkbox mat-select-search-hidden\"*ngIf=\"multiple\" />\r\n\r\n<div #innerSelectSearch class=\"mat-select-search-inner\" *ngIf=\"showSearch\"\r\n [ngClass]=\"{'mat-select-search-inner-multiple': matSelect.multiple}\">\r\n <input matInput autocomplete=\"off\"\r\n class=\"mat-select-search-input\"\r\n #searchSelectInput\r\n (keydown)=\"_handleKeydown($event)\"\r\n (input)=\"onInputChange($event.target.value)\"\r\n (blur)=\"onBlur($event.target.value)\"\r\n placeholder=\"Search\" />\r\n <button mat-button *ngIf=\"value\"\r\n mat-icon-button\r\n aria-label=\"Clear\"\r\n (click)=\"_reset(true)\"\r\n class=\"mat-select-search-clear\">\r\n <mat-icon>close</mat-icon>\r\n </button>\r\n</div>\r\n\r\n<div *ngIf=\"noEntriesFoundLabel && value && _options?.length === 0\"\r\n class=\"mat-select-search-no-entries-found\">\r\n {{noEntriesFoundLabel}}\r\n</div>\r\n",
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef((/**
* @return {?}
*/
function () { return MatSelectSearchComponent; })),
multi: true
}
],
changeDetection: ChangeDetectionStrategy.OnPush,
styles: [".mat-select-search-hidden{visibility:hidden}.mat-select-search-inner{position:absolute;top:0;width:calc(100% + 3px);border-bottom:1px solid #ccc;background:#fff;z-index:100;font-size:inherit;box-shadow:none;border-radius:0;-webkit-transform:translate3d(0,0,0)}.mat-select-search-inner.mat-select-search-inner-multiple{width:100%}::ng-deep .mat-select-search-panel{transform:none!important;overflow-x:hidden}.mat-select-search-input{padding:10px 30px 10px 10px;box-sizing:border-box}.mat-select-checkbox{padding:10px;box-sizing:border-box}.mat-select-search-no-entries-found{padding:10px}.mat-select-search-clear{position:absolute;right:4px;top:5px}:host.mat-select-search-inside-mat-option .mat-select-search-input{padding-top:0;padding-bottom:0;height:3em;line-height:3em}:host.mat-select-search-inside-mat-option .mat-select-checkbox{padding-top:0;padding-bottom:0;height:3em;line-height:3em}:host.mat-select-search-inside-mat-option .mat-select-search-clear{top:3px}::ng-deep .cdk-overlay-pane-select-search.cdk-overlay-pane-select-search-with-offset{margin-top:0}::ng-deep .mat-option[aria-disabled=true].contains-mat-select-search{position:static;padding:0}::ng-deep .mat-option[aria-disabled=true].contains-mat-select-search .mat-icon{margin-right:0}::ng-deep .mat-option[aria-disabled=true].contains-mat-select-search .mat-option-pseudo-checkbox{display:none}::ng-deep .mat-option[aria-disabled=true].contains-mat-select-search.mat-select-search-no-entries-found{height:6em}.mat-select-all-inner{position:absolute;top:52px;width:calc(100% + 3px);background:#fff;z-index:100;font-size:inherit;box-shadow:none;border-radius:0;-webkit-transform:translate3d(0,0,0)}"]
}] }
];
/** @nocollapse */
MatSelectSearchComponent.ctorParameters = function () { return [
{ type: MatSelect, decorators: [{ type: Inject, args: [MatSelect,] }] },
{ type: ChangeDetectorRef },
{ type: MatOption, decorators: [{ type: Optional }, { type: Inject, args: [MatOption,] }] }
]; };
MatSelectSearchComponent.propDecorators = {
placeholderLabel: [{ type: Input }],
multiple: [{ type: Input, args: ['multiple',] }],
showSearch: [{ type: Input, args: ['showSearch',] }],
noEntriesFoundLabel: [{ type: Input }],
searchSelectInput: [{ type: ViewChild, args: ['searchSelectInput', { read: ElementRef },] }],
innerSelectSearch: [{ type: ViewChild, args: ['innerSelectSearch', { read: ElementRef },] }],
isInsideMatOption: [{ type: HostBinding, args: ['class.mat-select-search-inside-mat-option',] }]
};
return MatSelectSearchComponent;
}());
export { MatSelectSearchComponent };
if (false) {
/**
* Label of the search placeholder
* @type {?}
*/
MatSelectSearchComponent.prototype.placeholderLabel;
/** @type {?} */
MatSelectSearchComponent.prototype.multiple;
/** @type {?} */
MatSelectSearchComponent.prototype.showSearch;
/**
* Label to be shown when no entries are found. Set to null if no message should be shown.
* @type {?}
*/
MatSelectSearchComponent.prototype.noEntriesFoundLabel;
/**
* Reference to the search input field
* @type {?}
*/
MatSelectSearchComponent.prototype.searchSelectInput;
/** @type {?} */
MatSelectSearchComponent.prototype.innerSelectSearch;
/**
* @type {?}
* @private
*/
MatSelectSearchComponent.prototype._value;
/** @type {?} */
MatSelectSearchComponent.prototype.onChange;
/** @type {?} */
MatSelectSearchComponent.prototype.onTouched;
/**
* Reference to the MatSelect options
* @type {?}
*/
MatSelectSearchComponent.prototype._options;
/**
* Previously selected values when using <mat-select [multiple]="true">
* @type {?}
* @private
*/
MatSelectSearchComponent.prototype.previousSelectedValues;
/**
* Whether the backdrop class has been set
* @type {?}
* @private
*/
MatSelectSearchComponent.prototype.overlayClassSet;
/**
* Event that emits when the current value changes
* @type {?}
* @private
*/
MatSelectSearchComponent.prototype.change;
/**
* @type {?}
* @private
*/
MatSelectSearchComponent.prototype.AllClicked;
/**
* Subject that emits when the component has been destroyed.
* @type {?}
* @private
*/
MatSelectSearchComponent.prototype._onDestroy;
/** @type {?} */
MatSelectSearchComponent.prototype.matSelect;
/**
* @type {?}
* @private
*/
MatSelectSearchComponent.prototype.changeDetectorRef;
/** @type {?} */
MatSelectSearchComponent.prototype.matOption;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWF0LXNlbGVjdC1zZWFyY2guY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vbmd4LW1hdC1kcm9wZG93bi8iLCJzb3VyY2VzIjpbImxpYi9tYXQtc2VsZWN0LXNlYXJjaC9tYXQtc2VsZWN0LXNlYXJjaC5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxPQUFPLEVBRUgsdUJBQXVCLEVBQUUsaUJBQWlCLEVBQzFDLFNBQVMsRUFBRSxVQUFVLEVBQUUsWUFBWSxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUM5RCxTQUFTLEVBQ1QsV0FBVyxFQUNYLFFBQVEsRUFDWCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQXdCLGlCQUFpQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDekUsT0FBTyxFQUFHLFNBQVMsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBR3RELE9BQU8sRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3hELE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDL0IsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBRW5EO0lBd0RJLGtDQUFzQyxTQUFvQixFQUM5QyxpQkFBb0MsRUFBd0MsU0FBMkI7UUFBM0IsMEJBQUEsRUFBQSxnQkFBMkI7UUFEN0UsY0FBUyxHQUFULFNBQVMsQ0FBVztRQUM5QyxzQkFBaUIsR0FBakIsaUJBQWlCLENBQW1CO1FBQXdDLGNBQVMsR0FBVCxTQUFTLENBQWtCOzs7O1FBekMxRyxxQkFBZ0IsR0FBRyxRQUFRLENBQUM7UUFDbEIsYUFBUSxHQUFZLEtBQUssQ0FBQztRQUN4QixlQUFVLEdBQVksSUFBSSxDQUFDOzs7O1FBRXZDLHdCQUFtQixHQUFHLFNBQVMsQ0FBQztRQWdCekMsYUFBUTs7OztRQUFhLFVBQUMsQ0FBTSxJQUFPLENBQUMsRUFBQztRQUNyQyxjQUFTOzs7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QUFBLEFBM1hELElBMlhDO1NBOVdZLHdCQUF3Qjs7Ozs7O0lBR2pDLG9EQUFxQzs7SUFDckMsNENBQTZDOztJQUM3Qyw4Q0FBZ0Q7Ozs7O0lBRWhELHVEQUF5Qzs7Ozs7SUFHekMscURBQW9GOztJQUNwRixxREFBbUY7Ozs7O0lBVW5GLDBDQUF1Qjs7SUFFdkIsNENBQXFDOztJQUNyQyw2Q0FBc0M7Ozs7O0lBR3RDLDRDQUFzQzs7Ozs7O0lBR3RDLDBEQUFzQzs7Ozs7O0lBR3RDLG1EQUFnQzs7Ozs7O0lBR2hDLDBDQUF5Qzs7Ozs7SUFFekMsOENBQWlEOzs7Ozs7SUFFakQsOENBQXlDOztJQUc3Qiw2Q0FBOEM7Ozs7O0lBQ3RELHFEQUE0Qzs7SUFBRSw2Q0FBaUUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xyXG4gICAgQWZ0ZXJWaWV3SW5pdCxcclxuICAgIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LCBDaGFuZ2VEZXRlY3RvclJlZixcclxuICAgIENvbXBvbmVudCwgRWxlbWVudFJlZiwgRXZlbnRFbWl0dGVyLCBmb3J3YXJkUmVmLCBJbmplY3QsIElucHV0LCBPbkRlc3Ryb3ksIE9uSW5pdCwgUXVlcnlMaXN0LFxyXG4gICAgVmlld0NoaWxkLFxyXG4gICAgSG9zdEJpbmRpbmcsXHJcbiAgICBPcHRpb25hbFxyXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBDb250cm9sVmFsdWVBY2Nlc3NvciwgTkdfVkFMVUVfQUNDRVNTT1IgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XHJcbmltcG9ydCB7ICBNYXRTZWxlY3QgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9zZWxlY3QnO1xyXG5pbXBvcnQgeyAgIE1hdENoZWNrYm94Q2hhbmdlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvY2hlY2tib3gnO1xyXG5cclxuaW1wb3J0IHsgZGVsYXksIHRha2UsIHRha2VVbnRpbCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcclxuaW1wb3J0IHsgU3ViamVjdCB9IGZyb20gJ3J4anMnO1xyXG5pbXBvcnQgeyBNYXRPcHRpb24gfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9jb3JlJztcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gICAgc2VsZWN0b3I6ICdtYXQtc2VsZWN0LXNlYXJjaCcsXHJcbiAgICB0ZW1wbGF0ZVVybDogJy4vbWF0LXNlbGVjdC1zZWFyY2guY29tcG9uZW50Lmh0bWwnLFxyXG4gICAgc3R5bGVVcmxzOiBbJy4vbWF0LXNlbGVjdC1zZWFyY2guY29tcG9uZW50LnNjc3MnXSxcclxuICAgIHByb3ZpZGVyczogW1xyXG4gICAgICAgIHtcclxuICAgICAgICAgICAgcHJvdmlkZTogTkdfVkFMVUVfQUNDRVNTT1IsXHJcbiAgICAgICAgICAgIHVzZUV4aXN0aW5nOiBmb3J3YXJkUmVmKCgpID0+IE1hdFNlbGVjdFNlYXJjaENvbXBvbmVudCksXHJcbiAgICAgICAgICAgIG11bHRpOiB0cnVlXHJcbiAgICAgICAgfVxyXG4gICAgXSxcclxuICAgIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBNYXRTZWxlY3RTZWFyY2hDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uRGVzdHJveSwgQWZ0ZXJWaWV3SW5pdCwgQ29udHJvbFZhbHVlQWNjZXNzb3Ige1xyXG5cclxuICAgIC8qKiBMYWJlbCBvZiB0aGUgc2VhcmNoIHBsYWNlaG9sZGVyICovXHJcbiAgICBASW5wdXQoKSBwbGFjZWhvbGRlckxhYmVsID0gJ1NlYXJjaCc7XHJcbiAgICBASW5wdXQoJ211bHRpcGxlJykgbXVsdGlwbGU6IGJvb2xlYW4gPSBmYWxzZTtcclxuICAgIEBJbnB1dCgnc2hvd1NlYXJjaCcpIHNob3dTZWFyY2g6IGJvb2xlYW4gPSB0cnVlO1xyXG4gICAgLyoqIExhYmVsIHRvIGJlIHNob3duIHdoZW4gbm8gZW50cmllcyBhcmUgZm91bmQuIFNldCB0byBudWxsIGlmIG5vIG1lc3NhZ2Ugc2hvdWxkIGJlIHNob3duLiAqL1xyXG4gICAgQElucHV0KCkgbm9FbnRyaWVzRm91bmRMYWJlbCA9ICdObyBEYXRhJztcclxuXHJcbiAgICAvKiogUmVmZXJlbmNlIHRvIHRoZSBzZWFyY2ggaW5wdXQgZmllbGQgKi9cclxuICAgIEBWaWV3Q2hpbGQoJ3NlYXJjaFNlbGVjdElucHV0JywgeyByZWFkOiBFbGVtZW50UmVmIH0pIHNlYXJjaFNlbGVjdElucHV0OiBFbGVtZW50UmVmO1xyXG4gICAgQFZpZXdDaGlsZCgnaW5uZXJTZWxlY3RTZWFyY2gnLCB7IHJlYWQ6IEVsZW1lbnRSZWZ9KSBpbm5lclNlbGVjdFNlYXJjaDogRWxlbWVudFJlZjtcclxuICAgIC8vQFZpZXdDaGlsZCgnaW5uZXJTZWxlY3RhbGwnLCB7IHJlYWQ6IEVsZW1lbnRSZWYgfSkgaW5uZXJTZWxlY3RhbGw6IEVsZW1lbnRSZWY7XHJcbiAgICBASG9zdEJpbmRpbmcoJ2NsYXNzLm1hdC1zZWxlY3Qtc2VhcmNoLWluc2lkZS1tYXQtb3B0aW9uJylcclxuICAgIGdldCBpc0luc2lkZU1hdE9wdGlvbigpOiBib29sZWFuIHtcclxuICAgICAgICByZXR1cm4gISF0aGlzLm1hdE9wdGlvbjtcclxuICAgIH1cclxuICAgIC8qKiBDdXJyZW50IHNlYXJjaCB2YWx1ZSAqL1xyXG4gICAgZ2V0IHZhbHVlKCk6IHN0cmluZyB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3ZhbHVlO1xyXG4gICAgfVxyXG4gICAgcHJpdmF0ZSBfdmFsdWU6IHN0cmluZztcclxuXHJcbiAgICBvbkNoYW5nZTogRnVuY3Rpb24gPSAoXzogYW55KSA9PiB7IH07XHJcbiAgICBvblRvdWNoZWQ6IEZ1bmN0aW9uID0gKF86IGFueSkgPT4geyB9O1xyXG5cclxuICAgIC8qKiBSZWZlcmVuY2UgdG8gdGhlIE1hdFNlbGVjdCBvcHRpb25zICovXHJcbiAgICBwdWJsaWMgX29wdGlvbnM6IFF1ZXJ5TGlzdDxNYXRPcHRpb24+O1xyXG5cclxuICAgIC8qKiBQcmV2aW91c2x5IHNlbGVjdGVkIHZhbHVlcyB3aGVuIHVzaW5nIDxtYXQtc2VsZWN0IFttdWx0aXBsZV09XCJ0cnVlXCI+Ki9cclxuICAgIHByaXZhdGUgcHJldmlvdXNTZWxlY3RlZFZhbHVlczogYW55W107XHJcblxyXG4gICAgLyoqIFdoZXRoZXIgdGhlIGJhY2tkcm9wIGNsYXNzIGhhcyBiZWVuIHNldCAqL1xyXG4gICAgcHJpdmF0ZSBvdmVybGF5Q2xhc3NTZXQgPSBmYWxzZTtcclxuXHJcbiAgICAvKiogRXZlbnQgdGhhdCBlbWl0cyB3aGVuIHRoZSBjdXJyZW50IHZhbHVlIGNoYW5nZXMgKi9cclxuICAgIHByaXZhdGUgY2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XHJcblxyXG4gICAgcHJpdmF0ZSBBbGxDbGlja2VkID0gbmV3IEV2ZW50RW1pdHRlcjxib29sZWFuPigpO1xyXG4gICAgLyoqIFN1YmplY3QgdGhhdCBlbWl0cyB3aGVuIHRoZSBjb21wb25lbnQgaGFzIGJlZW4gZGVzdHJveWVkLiAqL1xyXG4gICAgcHJpdmF0ZSBfb25EZXN0cm95ID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcclxuXHJcblxyXG4gICAgY29uc3RydWN0b3IoQEluamVjdChNYXRTZWxlY3QpIHB1YmxpYyBtYXRTZWxlY3Q6IE1hdFNlbGVjdCxcclxuICAgICAgICBwcml2YXRlIGNoYW5nZURldGVjdG9yUmVmOiBDaGFuZ2VEZXRlY3RvclJlZiwgQE9wdGlvbmFsKCkgQEluamVjdChNYXRPcHRpb24pIHB1YmxpYyBtYXRPcHRpb246IE1hdE9wdGlvbiA9IG51bGwpIHtcclxuXHJcblxyXG4gICAgfVxyXG5cclxuICAgIG5nT25Jbml0KCkge1xyXG4gICAgICAgIC8vIHNldCBjdXN0b20gcGFuZWwgY2xhc3NcclxuICAgICAgICBjb25zdCBwYW5lbENsYXNzID0gJ21hdC1zZWxlY3Qtc2VhcmNoLXBhbmVsJztcclxuICAgICAgICBpZiAodGhpcy5tYXRTZWxlY3QucGFuZWxDbGFzcykge1xyXG4gICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheSh0aGlzLm1hdFNlbGVjdC5wYW5lbENsYXNzKSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5tYXRTZWxlY3QucGFuZWxDbGFzcy5wdXNoKHBhbmVsQ2xhc3MpO1xyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiB0aGlzLm1hdFNlbGVjdC5wYW5lbENsYXNzID09PSAnc3RyaW5nJykge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5tYXRTZWxlY3QucGFuZWxDbGFzcyA9IFt0aGlzLm1hdFNlbGVjdC5wYW5lbENsYXNzLCBwYW5lbENsYXNzXTtcclxuICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgdGhpcy5tYXRTZWxlY3QucGFuZWxDbGFzcyA9PT0gJ29iamVjdCcpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMubWF0U2VsZWN0LnBhbmVsQ2xhc3NbcGFuZWxDbGFzc10gPSB0cnVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy5tYXRTZWxlY3QucGFuZWxDbGFzcyA9IHBhbmVsQ2xhc3M7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIHNldCBjdXN0b20gbWF0LW9wdGlvbiBjbGFzcyBpZiB0aGUgY29tcG9uZW50IHdhcyBwbGFjZWQgaW5zaWRlIGEgbWF0LW9wdGlvblxyXG4gICAgICAgIGlmICh0aGlzLm1hdE9wdGlvbikge1xyXG4gICAgICAgICAgICB0aGlzLm1hdE9wdGlvbi5kaXNhYmxlZCA9IHRydWU7XHJcbiAgICAgICAgICAgIHRoaXMubWF0T3B0aW9uLl9nZXRIb3N0RWxlbWVudCgpLmNsYXNzTGlzdC5hZGQoJ2NvbnRhaW5zLW1hdC1zZWxlY3Qtc2VhcmNoJyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIHdoZW4gdGhlIHNlbGVjdCBkcm9wZG93biBwYW5lbCBpcyBvcGVuZWQgb3IgY2xvc2VkXHJcbiAgICAgICAgdGhpcy5tYXRTZWxlY3Qub3BlbmVkQ2hhbmdlXHJcbiAgICAgICAgICAgIC8vIC5waXBlKHRha2VVbnRpbCh0aGlzLl9vbkRlc3Ryb3kpKVxyXG4gICAgICAgICAgICAucGlwZShcclxuICAgICAgICAgICAgICAgIGRlbGF5KDEpLFxyXG4gICAgICAgICAgICAgICAgdGFrZVVudGlsKHRoaXMuX29uRGVzdHJveSlcclxuICAgICAgICAgICAgKVxyXG4gICAgICAgICAgICAuc3Vic2NyaWJlKChvcGVuZWQpID0+IHtcclxuICAgICAgICAgICAgICAgIGlmIChvcGVuZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAvLyBmb2N1cyB0aGUgc2VhcmNoIGZpZWxkIHdoZW4gb3BlbmluZ1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZ2V0V2lkdGgoKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fZm9jdXMoKTtcclxuXHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIGNsZWFyIGl0IHdoZW4gY2xvc2luZ1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3Jlc2V0KCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAvLyBzZXQgdGhlIGZpcnN0IGl0ZW0gYWN0aXZlIGFmdGVyIHRoZSBvcHRpb25zIGNoYW5nZWRcclxuICAgICAgICB0aGlzLm1hdFNlbGVjdC5vcGVuZWRDaGFuZ2VcclxuICAgICAgICAgICAgLnBpcGUodGFrZSgxKSlcclxuICAgICAgICAgICAgLnBpcGUodGFrZVVudGlsKHRoaXMuX29uRGVzdHJveSkpXHJcbiAgICAgICAgICAgIC5zdWJzY3JpYmUoKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fb3B0aW9ucyA9IHRoaXMubWF0U2VsZWN0Lm9wdGlvbnM7XHJcbiAgICAgICAgICAgICAgICBcclxuICAgICAgICAgICAgICAgIHRoaXMuX29wdGlvbnMuY2hhbmdlc1xyXG4gICAgICAgICAgICAgICAgICAgIC5waXBlKHRha2VVbnRpbCh0aGlzLl9vbkRlc3Ryb3kpKVxyXG4gICAgICAgICAgICAgICAgICAgIC5zdWJzY3JpYmUoKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBrZXlNYW5hZ2VyID0gdGhpcy5tYXRTZWxlY3QuX2tleU1hbmFnZXI7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChrZXlNYW5hZ2VyICYmIHRoaXMubWF0U2VsZWN0LnBhbmVsT3Blbikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYXZvaWQgXCJleHByZXNzaW9uIGhhcyBiZWVuIGNoYW5nZWRcIiBlcnJvclxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2V5TWFuYWdlci5zZXRGaXJzdEl0ZW1BY3RpdmUoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmdldFdpZHRoKCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNldCBubyBlbnRyaWVzIGZvdW5kIGNsYXNzIG9uIG1hdCBvcHRpb25cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5tYXRPcHRpb24pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuX25vRW50cmllc0ZvdW5kKCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubWF0T3B0aW9uLl9nZXRIb3N0RWxlbWVudCgpLmNsYXNzTGlzdC5hZGQoJ21hdC1zZWxlY3Qtc2VhcmNoLW5vLWVudHJpZXMtZm91bmQnKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubWF0T3B0aW9uLl9nZXRIb3N0RWxlbWVudCgpLmNsYXNzTGlzdC5yZW1vdmUoJ21hdC1zZWxlY3Qtc2VhcmNoLW5vLWVudHJpZXMtZm91bmQnKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sIDEpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgLy8gZGV0ZWN0IGNoYW5nZXMgd2hlbiB0aGUgaW5wdXQgY2hhbmdlc1xyXG4gICAgICAgIHRoaXMuY2hhbmdlXHJcbiAgICAgICAgICAgIC5waXBlKHRha2VVbnRpbCh0aGlzLl9vbkRlc3Ryb3kpKVxyXG4gICAgICAgICAgICAuc3Vic2NyaWJlKCgpID0+IHtcclxuICAgICAgICAgICAgICAgIHRoaXMuY2hhbmdlRGV0ZWN0b3JSZWYuZGV0ZWN0Q2hhbmdlcygpO1xyXG4gICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgdGhpcy5pbml0TXVsdGlwbGVIYW5kbGluZygpO1xyXG4gICAgfVxyXG5cclxuICAgIG5nT25EZXN0cm95KCkge1xyXG4gICAgICAgIHRoaXMuX29uRGVzdHJveS5uZXh0KCk7XHJcbiAgICAgICAgdGhpcy5fb25EZXN0cm95LmNvbXBsZXRlKCk7XHJcbiAgICB9XHJcblxyXG4gICAgbmdBZnRlclZpZXdJbml0KCkge1xyXG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgICAgICAgICB0aGlzLnNldE92ZXJsYXlDbGFzcygpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHRoaXMubWF0U2VsZWN0Lm9wZW5lZENoYW5nZVxyXG4gICAgICAgICAgICAucGlwZShcclxuICAgICAgICAgICAgICAgIHRha2UoMSksXHJcbiAgICAgICAgICAgICAgICB0YWtlVW50aWwodGhpcy5fb25EZXN0cm95KVxyXG4gICAgICAgICAgICApLnN1YnNjcmliZSgoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLm1hdFNlbGVjdC5vcHRpb25zLmNoYW5nZXNcclxuICAgICAgICAgICAgICAgICAgICAucGlwZSh0YWtlVW50aWwodGhpcy5fb25EZXN0cm95KSlcclxuICAgICAgICAgICAgICAgICAgICAuc3Vic2NyaWJlKCgpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jaGFuZ2VEZXRlY3RvclJlZi5tYXJrRm9yQ2hlY2soKTtcclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gIFxyXG4gICAgX2hhbmRsZUtleWRvd24oZXZlbnQ6IEtleWJvYXJkRXZlbnQpIHtcclxuICAgICAgICBpZiAoZXZlbnQua2V5Q29kZSA9PT0gMzIpIHtcclxuICAgICAgICAgICAgLy8gZG8gbm90IHByb3BhZ2F0ZSBzcGFjZXMgdG8gTWF0U2VsZWN0LCBhcyB0aGlzIHdvdWxkIHNlbGVjdCB0aGUgY3VycmVudGx5IGFjdGl2ZSBvcHRpb25cclxuICAgICAgICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgIH1cclxuXHJcblxyXG4gICAgd3JpdGVWYWx1ZSh2YWx1ZTogc3RyaW5nKSB7XHJcbiAgICAgICAgY29uc3QgdmFsdWVDaGFuZ2VkID0gdmFsdWUgIT09IHRoaXMuX3ZhbHVlO1xyXG4gICAgICAgIGlmICh2YWx1ZUNoYW5nZWQpIHtcclxuICAgICAgICAgICAgdGhpcy5fdmFsdWUgPSB2YWx1ZTtcclxuICAgICAgICAgICAgdGhpcy5jaGFuZ2UuZW1pdCh7IHR5cGU6ICdUZXh0JywgdmFsOiB2YWx1ZSB9KTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgb25JbnB1dENoYW5nZSh2YWx1ZSkge1xyXG4gICAgICAgIGNvbnN0IHZhbHVlQ2hhbmdlZCA9IHZhbHVlICE9PSB0aGlzLl92YWx1ZTtcclxuICAgICAgICBpZiAodmFsdWVDaGFuZ2VkKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX3ZhbHVlID0gdmFsdWU7XHJcbiAgICAgICAgICAgIHRoaXMub25DaGFuZ2UoeyB0eXBlOiAnVGV4dCcsIHZhbDogdmFsdWUgfSk7XHJcbiAgICAgICAgICAgIHRoaXMuY2hhbmdlLmVtaXQoeyB0eXBlOiAnVGV4dCcsIHZhbDogdmFsdWUgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIG9uQmx1cih2YWx1ZTogc3RyaW5nKSB7XHJcbiAgICAgICAgdGhpcy53cml0ZVZhbHVlKHZhbHVlKTtcclxuICAgICAgICB0aGlzLm9uVG91Y2hlZCgpO1xyXG4gICAgfVxyXG5cclxuICAgIHJlZ2lzdGVyT25DaGFuZ2UoZm46IEZ1bmN0aW9uKSB7XHJcbiAgICAgICAgdGhpcy5vbkNoYW5nZSA9IGZuO1xyXG4gICAgfVxyXG5cclxuICAgIHJlZ2lzdGVyT25Ub3VjaGVkKGZuOiBGdW5jdGlvbikge1xyXG4gICAgICAgIHRoaXMub25Ub3VjaGVkID0gZm47XHJcbiAgICB9XHJcblxyXG4gICBcclxuICAgIHB1YmxpYyBfZm9jdXMoKSB7XHJcbiAgICAgICAgaWYgKCF0aGlzLnNlYXJjaFNlbGVjdElucHV0IHx8ICF0aGlzLm1hdFNlbGVjdC5wYW5lbCkge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIHNhdmUgYW5kIHJlc3RvcmUgc2Nyb2xsVG9wIG9mIHBhbmVsLCBzaW5jZSBpdCB3aWxsIGJlIHJlc2V0IGJ5IGZvY3VzKClcclxuICAgICAgICAvLyBub3RlOiB0aGlzIGlzIGhhY2t5XHJcbiAgICAgICAgY29uc3QgcGFuZWwgPSB0aGlzLm1hdFNlbGVjdC5wYW5lbC5uYXRpdmVFbGVtZW50O1xyXG4gICAgICAgIGNvbnN0IHNjcm9sbFRvcCA9IHBhbmVsLnNjcm9sbFRvcDtcclxuXHJcbiAgICAgICAgLy8gZm9jdXNcclxuICAgICAgICB0aGlzLnNlYXJjaFNlbGVjdElucHV0Lm5hdGl2ZUVsZW1lbnQuZm9jdXMoKTtcclxuXHJcbiAgICAgICAgcGFuZWwuc2Nyb2xsVG9wID0gc2Nyb2xsVG9wO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmVzZXRzIHRoZSBjdXJyZW50IHNlYXJjaCB2YWx1ZVxyXG4gICAgICoge2Jvb2xlYW59IGZvY3VzIHdoZXRoZXIgdG8gZm9jdXMgYWZ0ZXIgcmVzZXR0aW5nXHJcbiAgICAgKiBcclxuICAgICAqL1xyXG4gICAgcHVibGljIF9yZXNldChmb2N1cz86IGJvb2xlYW4pIHtcclxuICAgICAgICBpZiAoIXRoaXMuc2VhcmNoU2VsZWN0SW5wdXQpIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLnNlYXJjaFNlbGVjdElucHV0Lm5hdGl2ZUVsZW1lbnQudmFsdWUgPSAnJztcclxuICAgICAgICB0aGlzLm9uSW5wdXRDaGFuZ2UoJycpO1xyXG4gICAgICAgIGlmIChmb2N1cykge1xyXG4gICAgICAgICAgICB0aGlzLl9mb2N1cygpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFNldHMgdGhlIG92ZXJsYXkgY2xhc3MgIHRvIGNvcnJlY3Qgb2Zmc2V0WVxyXG4gICAgICogc28gdGhhdCB0aGUgc2VsZWN0ZWQgb3B0aW9uIGlzIGF0IHRoZSBwb3NpdGlvbiBvZiB0aGUgc2VsZWN0IGJveCB3aGVuIG9wZW5pbmdcclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBzZXRPdmVybGF5Q2xhc3MoKSB7XHJcbiAgICAgICAgaWYgKHRoaXMub3ZlcmxheUNsYXNzU2V0KSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgY29uc3Qgb3ZlcmxheUNsYXNzZXM6IHN0cmluZ1tdID0gWydjZGstb3ZlcmxheS1wYW5lLXNlbGVjdC1zZWFyY2gnXTtcclxuXHJcbiAgICAgICAgaWYgKCF0aGlzLm1hdE9wdGlvbikge1xyXG4gICAgICAgICAgICAvLyBhZGQgb2Zmc2V0IHRvIHBhbmVsIGlmIGNvbXBvbmVudCBpcyBub3QgcGxhY2VkIGluc2lkZSBtYXQtb3B0aW9uXHJcbiAgICAgICAgICAgIG92ZXJsYXlDbGFzc2VzLnB1c2goJ2Nkay1vdmVybGF5LXBhbmUtc2VsZWN0LXNlYXJjaC13aXRoLW9mZnNldCcpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5tYXRTZWxlY3Qub3ZlcmxheURpci5hdHRhY2hcclxuICAgICAgICAgICAgLnBpcGUodGFrZVVudGlsKHRoaXMuX29uRGVzdHJveSkpXHJcbiAgICAgICAgICAgIC5zdWJzY3JpYmUoKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgLy8gbm90ZTogdGhpcyBpcyBoYWNreSwgYnV0IGN1cnJlbnRseSB0aGVyZSBpcyBubyBiZXR0ZXIgd2F5IHRvIGRvIHRoaXNcclxuXHJcbiAgICAgICAgICAgICAgICBsZXQgZWxlbWVudDogSFRNTEVsZW1lbnQ7XHJcbiAgICAgICAgICAgICAgICBsZXQgb3ZlcmxheUVsZW1lbnQ6IEhUTUxFbGVtZW50O1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuc2VhcmNoU2VsZWN0SW5wdXQpIHtcclxuICAgICAgICAgICAgICAgICAgICBlbGVtZW50ID0gdGhpcy5zZWFyY2hTZWxlY3RJbnB1dC5uYXRpdmVFbGVtZW50O1xyXG4gICAgICAgICAgICAgICAgICAgIHdoaWxlIChlbGVtZW50ID0gZWxlbWVudC5wYXJlbnRFbGVtZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlbGVtZW50LmNsYXNzTGlzdC5jb250YWlucygnY2RrLW92ZXJsYXktcGFuZScpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdmVybGF5RWxlbWVudCA9IGVsZW1lbnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGlmIChvdmVybGF5RWxlbWVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgIG92ZXJsYXlDbGFzc2VzLmZvckVhY2gob3ZlcmxheUNsYXNzID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgb3ZlcmxheUVsZW1lbnQuY2xhc3NMaXN0LmFkZChvdmVybGF5Q2xhc3MpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgdGhpcy5vdmVybGF5Q2xhc3NTZXQgPSB0cnVlO1xyXG4gICAgfVxyXG5cclxuXHJcbiAgICAvKipcclxuICAgICAqIEluaXRpYWxpemVzIGhhbmRsaW5nIDxtYXQtc2VsZWN0IFttdWx0aXBsZV09XCJ0cnVlXCI+XHJcbiAgICAgKiBOb3RlOiB0byBpbXByb3ZlIHRoaXMgY29kZSwgbWF0LXNlbGVjdCBzaG91bGQgYmUgZXh0ZW5kZWQgdG8gYWxsb3cgZGlzYWJsaW5nIHJlc2V0dGluZyB0aGUgc2VsZWN0aW9uIHdoaWxlIGZpbHRlcmluZy5cclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBpbml0TXVsdGlwbGVIYW5kbGluZygpIHtcclxuICAgICAgICAvLyBpZiA8bWF0LXNlbGVjdCBbbXVsdGlwbGVdPVwidHJ1ZVwiPlxyXG4gICAgICAgIC8vIHN0b3JlIHByZXZpb3VzbHkgc2VsZWN0ZWQgdmFsdWVzIGFuZCByZXN0b3JlIHRoZW0gd2hlbiB0aGV5IGFyZSBkZXNlbGVjdGVkXHJcbiAgICAgICAgLy8gYmVjYXVzZSB0aGUgb3B0aW9uIGlzIG5vdCBhdmFpbGFibGUgd2hpbGUgd2UgYXJlIGN1cnJlbnRseSBmaWx0ZXJpbmdcclxuICAgICAgICB0aGlzLm1hdFNlbGVjdC52YWx1ZUNoYW5nZVxyXG4gICAgICAgICAgICAucGlwZSh0YWtlVW50aWwodGhpcy5fb25EZXN0cm95KSlcclxuICAgICAgICAgICAgLnN1YnNjcmliZSgodmFsdWVzKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5tYXRTZWxlY3QubXVsdGlwbGUpIHtcclxuICAgICAgICAgICAgICAgICAgICBsZXQgcmVzdG9yZVNlbGVjdGVkVmFsdWVzID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuX3ZhbHVlICYmIHRoaXMuX3ZhbHVlLmxlbmd0aFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAmJiB0aGlzLnByZXZpb3VzU2VsZWN0ZWRWYWx1ZXMgJiYgQXJyYXkuaXNBcnJheSh0aGlzLnByZXZpb3VzU2VsZWN0ZWRWYWx1ZXMpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghdmFsdWVzIHx8ICFBcnJheS5pc0FycmF5KHZhbHVlcykpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlcyA9IFtdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG9wdGlvblZhbHVlcyA9IHRoaXMubWF0U2VsZWN0Lm9wdGlvbnMubWFwKG9wdGlvbiA9PiBvcHRpb24udmFsdWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnByZXZpb3VzU2VsZWN0ZWRWYWx1ZXMuZm9yRWFjaChwcmV2aW91c1ZhbHVlID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZXMuaW5kZXhPZihwcmV2aW91c1ZhbHVlKSA9PT0gLTEgJiYgb3B0aW9uVmFsdWVzLmluZGV4T2YocHJldmlvdXNWYWx1ZSkgPT09IC0xKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaWYgYSB2YWx1ZSB0aGF0IHdhcyBzZWxlY3RlZCBiZWZvcmUgaXMgZGVzZWxlY3RlZCBhbmQgbm90IGZvdW5kIGluIHRoZSBvcHRpb25zLCBpdCB3YXMgZGVzZWxlY3RlZFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGR1ZSB0byB0aGUgZmlsdGVyaW5nLCBzbyB3ZSByZXN0b3JlIGl0LlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlcy5wdXNoKHByZXZpb3VzVmFsdWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3RvcmVTZWxlY3RlZFZhbHVlcyA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3RvcmVTZWxlY3RlZFZhbHVlcykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm1hdFNlbGVjdC5fb25DaGFuZ2UodmFsdWVzKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucHJldmlvdXNTZWxlY3RlZFZhbHVlcyA9IHZhbHVlcztcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBnZXRXaWR0aCgpIHtcclxuICAgICAgICBpZiAoIXRoaXMuaW5uZXJTZWxlY3RTZWFyY2ggfHwgIXRoaXMuaW5uZXJTZWxlY3RTZWFyY2gubmF0aXZlRWxlbWVudCkge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGxldCBlbGVtZW50OiBIVE1MRWxlbWVudCA9IHRoaXMuaW5uZXJTZWxlY3RTZWFyY2gubmF0aXZlRWxlbWVudDtcclxuICAgICAgICBsZXQgcGFuZWxFbGVtZW50OiBIVE1MRWxlbWVudDtcclxuICAgICAgICB3aGlsZSAoZWxlbWVudCA9IGVsZW1lbnQucGFyZW50RWxlbWVudCkge1xyXG4gICAgICAgICAgICBpZiAoZWxlbWVudC5jbGFzc0xpc3QuY29udGFpbnMoJ21hdC1zZWxlY3QtcGFuZWwnKSkge1xyXG4gICAgICAgICAgICAgICAgcGFuZWxFbGVtZW50ID0gZWxlbWVudDtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChwYW5lbEVsZW1lbnQpIHtcclxuICAgICAgICAgICAgdGhpcy5pbm5lclNlbGVjdFNlYXJjaC5uYXRpdmVFbGVtZW50LnN0eWxlLndpZHRoID0gcGFuZWxFbGVtZW50LmNsaWVudFdpZHRoICsgJ3B4JztcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vLy9pbm5lclNlbGVjdGFsbFxyXG4gICAgICAgIC8vaWYgKCF0aGlzLmlubmVyU2VsZWN0YWxsIHx8ICF0aGlzLmlubmVyU2VsZWN0YWxsLm5hdGl2ZUVsZW1lbnQpIHtcclxuICAgICAgICAvLyAgICByZXR1cm47XHJcbiAgICAgICAgLy99XHJcbiAgICAgICAgLy9sZXQgU2VsZWN0YWxsZWxlbWVudDogSFRNTEVsZW1lbnQgPSB0aGlzLmlubmVyU2VsZWN0YWxsLm5hdGl2ZUVsZW1lbnQ7XHJcbiAgICAgICAgLy9sZXQgU2VsZWN0YWxscGFuZWxFbGVtZW50OiBIVE1MRWxlbWVudDtcclxuICAgICAgICAvL3doaWxlIChTZWxlY3RhbGxlbGVtZW50ID0gU2VsZWN0YWxsZWxlbWVudC5wYXJlbnRFbGVtZW50KSB7XHJcbiAgICAgICAgLy8gICAgaWYgKFNlbGVjdGFsbGVsZW1lbnQuY2xhc3NMaXN0LmNvbnRhaW5zKCdtYXQtc2VsZWN0LXBhbmVsJykpIHtcclxuICAgICAgICAvLyAgICAgICAgU2VsZWN0YWxscGFuZWxFbGVtZW50ID0gU2VsZWN0YWxsZWxlbWVudDtcclxuICAgICAgICAvLyAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgLy8gICAgfVxyXG4gICAgICAgIC8vfVxyXG4gICAgICAgIC8vaWYgKFNlbGVjdGFsbHBhbmVsRWxlbWVudCkge1xyXG4gICAgICAgIC8vICAgIHRoaXMuaW5uZXJTZWxlY3RhbGwubmF0aXZlRWxlbWVudC5zdHlsZS53aWR0aCA9IFNlbGVjdGFsbHBhbmVsRWxlbWVudC5jbGllbnRXaWR0aCArICdweCc7XHJcbiAgICAgICAgLy99XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIF9ub0VudHJpZXNGb3VuZCgpOiBib29sZWFuIHtcclxuICAgICAgICBpZiAoIXRoaXMuX29wdGlvbnMpIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAodGhpcy5tYXRPcHRpb24pIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMubm9FbnRyaWVzRm91bmRMYWJlbCAmJiB0aGlzLnZhbHVlICYmIHRoaXMuX29wdGlvbnMubGVuZ3RoID09PSAxO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLm5vRW50cmllc0ZvdW5kTGFiZWwgJiYgdGhpcy52YWx1ZSAmJiB0aGlzLl9vcHRpb25zLmxlbmd0aCA9PT0gMDtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICB0b2dnbGVTZWxlY3Rpb24oY2hhbmdlOiBNYXRDaGVja2JveENoYW5nZSwgY2hlY2spOiB2b2lkIHtcclxuICAgICAgICBpZiAoY2hhbmdlLmNoZWNrZWQpIHtcclxuICAgICAgICAgICAgLy90aGlzLm1vZGVsLnVwZGF0ZS5lbWl0KHRoaXMudmFsdWVzKTtcclxuICAgICAgICAgICAgdGhpcy5vbkNoYW5nZSh7IHR5cGU6ICdDaGVjaycsIHZhbDogY2hhbmdlLmNoZWNrZWQgfSk7XHJcbiAgICAgICAgICAgIHRoaXMuY2hhbmdlLmVtaXQoeyB0eXBlOiAnQ2hlY2snLCB2YWw6IGNoYW5nZS5jaGVja2VkIH0pO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMub25DaGFuZ2UoeyB0eXBlOiAnQ2hlY2snLCB2YWw6IGNoYW5nZS5jaGVja2VkIH0pO1xyXG4gICAgICAgICAgICB0aGlzLmNoYW5nZS5lbWl0KHsgdHlwZTogJ0NoZWNrJywgdmFsOiBjaGFuZ2UuY2hlY2tlZCB9KTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgaXNjaGVja2VkKGNoZWNrKTogYm9vbGVhbiB7XHJcbiAgICAgICAgY29uc29sZS5sb2codGhpcy5tYXRTZWxlY3Qub3B0aW9ucywgdGhpcy5tYXRTZWxlY3QudmFsdWUpO1xyXG4gICAgICAgIGxldCBzZWxlY3RlZDogYW55ID0gdGhpcy5tYXRTZWxlY3Quc2VsZWN0ZWQ7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMubWF0U2VsZWN0Lm9wdGlvbnMgJiYgc2VsZWN0ZWQgJiYgc2VsZWN0ZWQubGVuZ3RoID4gMCAmJiB0aGlzLm1hdFNlbGVjdC5vcHRpb25zLmxlbmd0aCA9PSBzZWxlY3RlZC5sZW5ndGg7XHJcbiAgICB9XHJcbiAgICBpc0luZGV0ZXJtaW5hdGUoKTogYm9vbGVhbiB7XHJcbiAgICAgICAgbGV0IHNlbGVjdGVkOiBhbnkgPSB0aGlzLm1hdFNlbGVjdC5zZWxlY3RlZDtcclxuICAgICAgICByZXR1cm4gdGhpcy5tYXRTZWxlY3Qub3B0aW9ucyAmJiBzZWxlY3RlZC5sZW5ndGggPiAwICYmIHNlbGVjdGVkLmxlbmd0aCA8IHRoaXMubWF0U2VsZWN0Lm9wdGlvbnMubGVuZ3RoO1xyXG4gICAgfVxyXG59XHJcbiJdfQ==