@stratio/egeo
Version:
677 lines • 49.4 kB
JavaScript
/**
* @fileoverview added by tsickle
* Generated from: lib/st-select/st-select.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/*
* © 2017 Stratio Big Data Inc., Sucursal en España.
*
* This software is licensed under the Apache License, Version 2.0.
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the terms of the License for more details.
*
* SPDX-License-Identifier: Apache-2.0.
*/
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, EventEmitter, forwardRef, HostBinding, Injector, Input, Output, ViewChild } from '@angular/core';
import { FormControl, NG_VALUE_ACCESSOR } from '@angular/forms';
import { cloneDeep as _cloneDeep, flatten as _flatten, has as _has } from 'lodash';
import { StCheckValidationsDirective } from './st-check-validations';
import { StDropDownMenuItem } from '../st-dropdown-menu/st-dropdown-menu.interface';
var StSelectComponent = /** @class */ (function () {
function StSelectComponent(_selectElement, _injector, _cd) {
this._selectElement = _selectElement;
this._injector = _injector;
this._cd = _cd;
this.placeholder = '';
this.name = '';
this.label = '';
this.tooltip = null;
this.selected = undefined;
this.itemsBeforeScroll = 8;
this.enabledSearcher = false;
this.isLoading = false;
this.forceValidations = false;
this.placeholderSearch = 'Search...';
this.keyBoardMove = false;
this.expand = new EventEmitter();
this.select = new EventEmitter();
this.scrollAtBottom = new EventEmitter();
this.search = new EventEmitter();
this.expandedMenu = false;
this.searchInput = new FormControl();
this.inputFormControl = new FormControl();
this._inputHTMLElement = undefined;
this._isDisabled = false;
this._options = [];
}
// TODO: MOVE THIS TO FORM-BASE
// TODO: MOVE THIS TO FORM-BASE
/**
* @param {?} errorMessage
* @return {?}
*/
StSelectComponent.prototype.notifyError =
// TODO: MOVE THIS TO FORM-BASE
/**
* @param {?} errorMessage
* @return {?}
*/
function (errorMessage) {
this.errorMessage = errorMessage;
};
Object.defineProperty(StSelectComponent.prototype, "disabled", {
get: /**
* @return {?}
*/
function () {
return this._isDisabled;
},
/*
****** getters && setters ******
*/
set: /*
****** getters && setters ******
*/
/**
* @param {?} value
* @return {?}
*/
function (value) {
this._isDisabled = value;
this._cd.markForCheck();
},
enumerable: true,
configurable: true
});
Object.defineProperty(StSelectComponent.prototype, "options", {
get: /**
* @return {?}
*/
function () {
return this._options;
},
set: /**
* @param {?} options
* @return {?}
*/
function (options) {
this._options = _cloneDeep(options);
/** @type {?} */
var selectedItem = this.findByProperty('selected', true);
this.removeAllSelected();
if (selectedItem) {
this.selected = selectedItem;
}
},
enumerable: true,
configurable: true
});
Object.defineProperty(StSelectComponent.prototype, "selectedValue", {
get: /**
* @return {?}
*/
function () {
return this.selected && this.selected.label ? this.selected.label : '';
},
enumerable: true,
configurable: true
});
Object.defineProperty(StSelectComponent.prototype, "disableValue", {
get: /**
* @return {?}
*/
function () {
return this._isDisabled === true ? '' : null;
},
enumerable: true,
configurable: true
});
Object.defineProperty(StSelectComponent.prototype, "selectId", {
get: /**
* @return {?}
*/
function () {
/** @type {?} */
var select = this._selectElement.nativeElement;
return select.getAttribute('id') !== null ? select.id : null;
},
enumerable: true,
configurable: true
});
Object.defineProperty(StSelectComponent.prototype, "inputId", {
get: /**
* @return {?}
*/
function () {
return this.selectId !== null ? this.selectId + "-input" : null;
},
enumerable: true,
configurable: true
});
Object.defineProperty(StSelectComponent.prototype, "labelId", {
get: /**
* @return {?}
*/
function () {
return this.selectId !== null ? this.selectId + "-label" : null;
},
enumerable: true,
configurable: true
});
Object.defineProperty(StSelectComponent.prototype, "optionsId", {
get: /**
* @return {?}
*/
function () {
return this.selectId !== null ? this.selectId + "-options" : null;
},
enumerable: true,
configurable: true
});
Object.defineProperty(StSelectComponent.prototype, "inputName", {
get: /**
* @return {?}
*/
function () {
return this.name && this.name.length > 0 ? this.name : null;
},
enumerable: true,
configurable: true
});
Object.defineProperty(StSelectComponent.prototype, "hasLabel", {
get: /**
* @return {?}
*/
function () {
return this.label !== undefined && this.label !== null && this.label.length > 0;
},
enumerable: true,
configurable: true
});
/**
* @return {?}
*/
StSelectComponent.prototype.showError = /**
* @return {?}
*/
function () {
return this.errorMessage && this.errorMessage.length && (this.inputFormControl.touched || this.forceValidations) && !this._isDisabled;
};
/*
****** Control value accessor && validate methods ******
*/
/*
****** Control value accessor && validate methods ******
*/
/**
* @return {?}
*/
StSelectComponent.prototype.onSearch = /*
****** Control value accessor && validate methods ******
*/
/**
* @return {?}
*/
function () {
this.search.emit(this.searchInput.value);
this._cd.markForCheck();
};
/**
* @param {?} event
* @return {?}
*/
StSelectComponent.prototype.onSearchClick = /**
* @param {?} event
* @return {?}
*/
function (event) {
event.preventDefault();
event.stopPropagation();
};
// Set the function to be called when the control receives a change event.
// Set the function to be called when the control receives a change event.
/**
* @param {?} fn
* @return {?}
*/
StSelectComponent.prototype.registerOnChange =
// Set the function to be called when the control receives a change event.
/**
* @param {?} fn
* @return {?}
*/
function (fn) {
this.onChange = fn;
};
// Set the function to be called when the control receives a touch event.
// Set the function to be called when the control receives a touch event.
/**
* @param {?} fn
* @return {?}
*/
StSelectComponent.prototype.registerOnTouched =
// Set the function to be called when the control receives a touch event.
/**
* @param {?} fn
* @return {?}
*/
function (fn) {
this.onTouched = fn;
};
/**
* @param {?} disabled
* @return {?}
*/
StSelectComponent.prototype.setDisabledState = /**
* @param {?} disabled
* @return {?}
*/
function (disabled) {
this._isDisabled = disabled;
this._cd.markForCheck();
};
// Write a new value to the element.
// Write a new value to the element.
/**
* @param {?} newValue
* @return {?}
*/
StSelectComponent.prototype.writeValue =
// Write a new value to the element.
/**
* @param {?} newValue
* @return {?}
*/
function (newValue) {
if (!this.selected || this.selected.value !== newValue) {
this.selected = this.findByProperty('value', newValue);
this._cd.markForCheck();
}
};
/*
****** Component methods ******
*/
/*
****** Component methods ******
*/
/**
* @return {?}
*/
StSelectComponent.prototype.ngAfterViewInit = /*
****** Component methods ******
*/
/**
* @return {?}
*/
function () {
this._inputHTMLElement = this.inputElement.nativeElement;
/** @type {?} */
var directive = this._injector.get(StCheckValidationsDirective, null);
if (directive) {
directive.registerOnChange(this.notifyError.bind(this));
}
};
/**
* @return {?}
*/
StSelectComponent.prototype.onButtonClick = /**
* @return {?}
*/
function () {
if (!this._isDisabled) {
this.toggleButton();
this.expandedMenu ? this._inputHTMLElement.focus() : this._inputHTMLElement.blur();
}
};
/**
* @param {?} event
* @return {?}
*/
StSelectComponent.prototype.onButtonKeyPress = /**
* @param {?} event
* @return {?}
*/
function (event) {
if (event.code === 'Enter') {
this.toggleButton();
}
};
/**
* @return {?}
*/
StSelectComponent.prototype.clearSearchInput = /**
* @return {?}
*/
function () {
this.searchInput.setValue('');
this.search.emit('');
};
/**
* @return {?}
*/
StSelectComponent.prototype.createResetButton = /**
* @return {?}
*/
function () {
return this.default !== undefined && ((!this.selected && this.inputFormControl.touched) || (this.selected && this.selected.value !== this.default));
};
/**
* @return {?}
*/
StSelectComponent.prototype.resetToDefault = /**
* @return {?}
*/
function () {
this.writeValue(this.default);
this.select.emit(this.default);
if (this.onChange) {
this.onChange(this.default);
}
this._cd.markForCheck();
};
/**
* @return {?}
*/
StSelectComponent.prototype.onClickOutside = /**
* @return {?}
*/
function () {
this.expandedMenu = false;
this.expand.emit(this.expandedMenu); // Notify expand change
};
/**
* @param {?} option
* @return {?}
*/
StSelectComponent.prototype.onChangeOption = /**
* @param {?} option
* @return {?}
*/
function (option) {
this.selected = option && option.value !== undefined ? option : undefined;
/** @type {?} */
var value = option && option.value !== undefined ? option.value : undefined;
if (this.onChange) {
this.onChange(value);
}
if (this.onTouched) {
this.onTouched();
}
this.select.emit(value);
if (value || (option && option.hasOwnProperty('value') && !option.value)) {
this.onClickOutside();
}
this._cd.markForCheck();
};
/**
* @return {?}
*/
StSelectComponent.prototype.onScrollAtBottom = /**
* @return {?}
*/
function () {
this.scrollAtBottom.emit();
};
/*
****** Util component methods ******
*/
// Search element by property in option list
/*
****** Util component methods ******
*/
// Search element by property in option list
/**
* @private
* @param {?} propName
* @param {?} propValue
* @return {?}
*/
StSelectComponent.prototype.findByProperty = /*
****** Util component methods ******
*/
// Search element by property in option list
/**
* @private
* @param {?} propName
* @param {?} propValue
* @return {?}
*/
function (propName, propValue) {
if (this.isStDropdownItemList(this.options)) {
return this.options.find((/**
* @param {?} item
* @return {?}
*/
function (item) { return _has(item, propName) && item[propName] === propValue; }));
}
else if (this.isStDropdownGroupList(this.options)) {
return _flatten(this.options.map((/**
* @param {?} group
* @return {?}
*/
function (group) { return group.items; }))).find((/**
* @param {?} item
* @return {?}
*/
function (item) { return _has(item, propName) && item[propName] === propValue; }));
}
};
// Check if options are a instance of StDropDownMenuItem[]
// Check if options are a instance of StDropDownMenuItem[]
/**
* @private
* @param {?} items
* @return {?}
*/
StSelectComponent.prototype.isStDropdownItemList =
// Check if options are a instance of StDropDownMenuItem[]
/**
* @private
* @param {?} items
* @return {?}
*/
function (items) {
return this.options && this.options.length > 0 && !_has(((/** @type {?} */ (items)))[0], 'items');
};
// Check if options are a instance of StDropDownMenuGroup[]
// Check if options are a instance of StDropDownMenuGroup[]
/**
* @private
* @param {?} items
* @return {?}
*/
StSelectComponent.prototype.isStDropdownGroupList =
// Check if options are a instance of StDropDownMenuGroup[]
/**
* @private
* @param {?} items
* @return {?}
*/
function (items) {
return this.options && this.options.length > 0 && _has(((/** @type {?} */ (items)))[0], 'items');
};
/**
* @private
* @return {?}
*/
StSelectComponent.prototype.toggleButton = /**
* @private
* @return {?}
*/
function () {
this.expandedMenu = !this.expandedMenu;
this.expand.emit(this.expandedMenu); // Notify expand change
this._cd.markForCheck();
};
// TODO: Remove when remove from StDropDownMenuItem model the selected property
// TODO: Remove when remove from StDropDownMenuItem model the selected property
/**
* @private
* @return {?}
*/
StSelectComponent.prototype.removeAllSelected =
// TODO: Remove when remove from StDropDownMenuItem model the selected property
/**
* @private
* @return {?}
*/
function () {
if (this.isStDropdownItemList(this.options)) {
return this.options.forEach((/**
* @param {?} item
* @return {?}
*/
function (item) {
if (item.selected) {
delete item.selected;
}
}));
}
else if (this.isStDropdownGroupList(this.options)) {
this.options.forEach((/**
* @param {?} group
* @return {?}
*/
function (group) { return group.items.forEach((/**
* @param {?} item
* @return {?}
*/
function (item) {
if (item.selected) {
delete item.selected;
}
})); }));
}
};
StSelectComponent.decorators = [
{ type: Component, args: [{
selector: 'st-select',
template: "<!--\n\n \u00A9 2017 Stratio Big Data Inc., Sucursal en Espa\u00F1a.\n\n This software is licensed under the Apache License, Version 2.0.\n This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;\n without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n See the terms of the License for more details.\n\n SPDX-License-Identifier: Apache-2.0.\n\n-->\n<st-dropdown-menu\n class=\"st-select-menu\"\n [items]=\"options\"\n [attr.id]=\"optionsId\"\n [active]=\"expandedMenu\"\n [placement]=\"'bottom-start'\"\n [keyBoardMove]=\"keyBoardMove\"\n [selectedItem]=\"selected\"\n (change)=\"onChangeOption($event)\"\n (scrollAtBottom)=\"onScrollAtBottom()\"\n [isLoading]=\"isLoading\"\n [itemsBeforeScroll]=\"itemsBeforeScroll\"\n>\n <div (click)=\"onButtonClick()\" (keypress)=\"onButtonKeyPress($event)\" #button class=\"button-container\"\n (clickOutside)=\"onClickOutside()\">\n <div>\n <label *ngIf=\"hasLabel\" [ngClass]=\"{disabled: disabled, error: showError()}\"\n st-label\n for=\"inputId\"\n class=\"st-label\"\n [attr.title]=\"tooltip\"\n [attr.id]=\"labelId\"\n [attr.disabled]=\"disableValue\">{{label}}</label>\n <div class=\"input-container\">\n <input\n #input\n [formControl]=\"inputFormControl\"\n autocomplete=\"off\"\n aria-haspopup=\"true\"\n class=\"st-input\"\n type=\"text\"\n [readonly]=\"true\"\n [attr.aria-expanded]=\"expandedMenu\"\n [attr.disabled]=\"disableValue\"\n [attr.id]=\"inputId\"\n [attr.name]=\"inputName\"\n [placeholder]=\"placeholder\"\n [value]=\"selectedValue\"\n\n />\n <span *ngIf=\"createResetButton()\" class=\"st-form-control-reset-button\" (click)=\"resetToDefault()\"\n [style.opacity]=\"expandedMenu ? 1 : 0\">\n <i class=\"icon-reload2\"></i>\n </span>\n <i class=\"icon-arrow2_down arrow\" [attr.disabled]=\"disableValue\"></i>\n </div>\n </div>\n </div>\n <div dropdown-header *ngIf=\"enabledSearcher\"\n (click)=\"onSearchClick($event)\"\n class=\"search-input\">\n <input\n id=\"searchInput\"\n autocomplete=\"off\"\n aria-haspopup=\"true\"\n class=\"st-input\"\n type=\"text\"\n [attr.aria-expanded]=\"expandedMenu\"\n [attr.disabled]=\"disableValue\"\n [attr.id]=\"searchInput\"\n [placeholder]=\"placeholderSearch\"\n [formControl]=\"searchInput\"\n (focus)=\"enabledSearcher\"\n (input)=\"onSearch()\"\n />\n <i class=\"st-search-icon sth-search-icon icon-search\" tabindex=\"0\" *ngIf=\"!searchInput.value?.length\"></i>\n <i class=\"st-search-icon sth-search-icon icon-cross\" tabindex=\"0\" *ngIf=\"searchInput.value?.length\"\n (click)=\"clearSearchInput()\" (keyup.enter)=\"clearSearchInput()\"></i>\n </div>\n\n</st-dropdown-menu>\n\n<div class=\"st-input-error-layout\" *ngIf=\"showError()\">\n <span class=\"st-input-error-message\">{{errorMessage}}</span>\n</div>\n",
host: {
'class': 'st-select'
},
changeDetection: ChangeDetectionStrategy.OnPush,
providers: [
{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef((/**
* @return {?}
*/
function () { return StSelectComponent; })), multi: true }
],
styles: ["@charset \"UTF-8\";.button-container{position:relative}.arrow{position:absolute;right:8px;top:8px;padding:5px 5px 5px 9px;cursor:pointer}.st-select-menu{position:relative}.input-container{position:relative;display:inline-block;width:100%}.search-input{margin:15px}.st-search-icon{position:absolute;right:28px;top:28px;cursor:pointer}.st-search-icon:focus{outline:0}"]
}] }
];
/** @nocollapse */
StSelectComponent.ctorParameters = function () { return [
{ type: ElementRef },
{ type: Injector },
{ type: ChangeDetectorRef }
]; };
StSelectComponent.propDecorators = {
placeholder: [{ type: Input }],
name: [{ type: Input }],
label: [{ type: Input }],
tooltip: [{ type: Input }],
errorMessage: [{ type: Input }],
selected: [{ type: Input }],
default: [{ type: Input }],
itemsBeforeScroll: [{ type: Input }],
enabledSearcher: [{ type: Input }],
isLoading: [{ type: Input }],
forceValidations: [{ type: Input }],
placeholderSearch: [{ type: Input }],
keyBoardMove: [{ type: Input }],
expand: [{ type: Output }],
select: [{ type: Output }],
scrollAtBottom: [{ type: Output }],
search: [{ type: Output }],
inputElement: [{ type: ViewChild, args: ['input', { static: false },] }],
buttonElement: [{ type: ViewChild, args: ['button', { static: false },] }],
expandedMenu: [{ type: HostBinding, args: ['class.st-select-opened',] }],
disabled: [{ type: Input }],
options: [{ type: Input }]
};
return StSelectComponent;
}());
export { StSelectComponent };
if (false) {
/** @type {?} */
StSelectComponent.prototype.placeholder;
/** @type {?} */
StSelectComponent.prototype.name;
/** @type {?} */
StSelectComponent.prototype.label;
/** @type {?} */
StSelectComponent.prototype.tooltip;
/** @type {?} */
StSelectComponent.prototype.errorMessage;
/** @type {?} */
StSelectComponent.prototype.selected;
/** @type {?} */
StSelectComponent.prototype.default;
/** @type {?} */
StSelectComponent.prototype.itemsBeforeScroll;
/** @type {?} */
StSelectComponent.prototype.enabledSearcher;
/** @type {?} */
StSelectComponent.prototype.isLoading;
/** @type {?} */
StSelectComponent.prototype.forceValidations;
/** @type {?} */
StSelectComponent.prototype.placeholderSearch;
/** @type {?} */
StSelectComponent.prototype.keyBoardMove;
/** @type {?} */
StSelectComponent.prototype.expand;
/** @type {?} */
StSelectComponent.prototype.select;
/** @type {?} */
StSelectComponent.prototype.scrollAtBottom;
/** @type {?} */
StSelectComponent.prototype.search;
/** @type {?} */
StSelectComponent.prototype.inputElement;
/** @type {?} */
StSelectComponent.prototype.buttonElement;
/** @type {?} */
StSelectComponent.prototype.expandedMenu;
/** @type {?} */
StSelectComponent.prototype.searchInput;
/** @type {?} */
StSelectComponent.prototype.inputFormControl;
/** @type {?} */
StSelectComponent.prototype.onChange;
/** @type {?} */
StSelectComponent.prototype.onTouched;
/**
* @type {?}
* @private
*/
StSelectComponent.prototype._inputHTMLElement;
/**
* @type {?}
* @private
*/
StSelectComponent.prototype._isDisabled;
/**
* @type {?}
* @private
*/
StSelectComponent.prototype._options;
/**
* @type {?}
* @private
*/
StSelectComponent.prototype._selectElement;
/**
* @type {?}
* @private
*/
StSelectComponent.prototype._injector;
/**
* @type {?}
* @private
*/
StSelectComponent.prototype._cd;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3Qtc2VsZWN0LmpzIiwic291cmNlUm9vdCI6Im5nOi8vQHN0cmF0aW8vZWdlby8iLCJzb3VyY2VzIjpbImxpYi9zdC1zZWxlY3Qvc3Qtc2VsZWN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7OztBQVVBLE9BQU8sRUFFSix1QkFBdUIsRUFDdkIsaUJBQWlCLEVBQ2pCLFNBQVMsRUFDVCxVQUFVLEVBQ1YsWUFBWSxFQUNaLFVBQVUsRUFDVixXQUFXLEVBQ1gsUUFBUSxFQUNSLEtBQUssRUFDTCxNQUFNLEVBQ04sU0FBUyxFQUNYLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBd0IsV0FBVyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDdEYsT0FBTyxFQUFFLFNBQVMsSUFBSSxVQUFVLEVBQUUsT0FBTyxJQUFJLFFBQVEsRUFBRSxHQUFHLElBQUksSUFBSSxFQUFFLE1BQU0sUUFBUSxDQUFDO0FBRW5GLE9BQU8sRUFBRSwyQkFBMkIsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ3JFLE9BQU8sRUFBdUIsa0JBQWtCLEVBQUUsTUFBTSxnREFBZ0QsQ0FBQztBQUV6RztJQW1ERywyQkFBb0IsY0FBMEIsRUFDMUIsU0FBbUIsRUFDbkIsR0FBc0I7UUFGdEIsbUJBQWMsR0FBZCxjQUFjLENBQVk7UUFDMUIsY0FBUyxHQUFULFNBQVMsQ0FBVTtRQUNuQixRQUFHLEdBQUgsR0FBRyxDQUFtQjtRQXZDakMsZ0JBQVcsR0FBVyxFQUFFLENBQUM7UUFDekIsU0FBSSxHQUFXLEVBQUUsQ0FBQztRQUNsQixVQUFLLEdBQVcsRUFBRSxDQUFDO1FBQ25CLFlBQU8sR0FBa0IsSUFBSSxDQUFDO1FBRTlCLGFBQVEsR0FBdUIsU0FBUyxDQUFDO1FBRXpDLHNCQUFpQixHQUFXLENBQUMsQ0FBQztRQUM5QixvQkFBZSxHQUFZLEtBQUssQ0FBQztRQUNqQyxjQUFTLEdBQVksS0FBSyxDQUFDO1FBQzNCLHFCQUFnQixHQUFZLEtBQUss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QUNwRCw2Q0FBeUQ7O0lBRXpELHFDQUEyQjs7SUFDM0Isc0NBQXNCOzs7OztJQUV0Qiw4Q0FBb0U7Ozs7O0lBQ3BFLHdDQUFxQzs7Ozs7SUFDckMscUNBQW9FOzs7OztJQUd4RCwyQ0FBa0M7Ozs7O0lBQ2xDLHNDQUEyQjs7Ozs7SUFDM0IsZ0NBQThCIiwic291cmNlc0NvbnRlbnQiOlsiLypcbiAqIMKpIDIwMTcgU3RyYXRpbyBCaWcgRGF0YSBJbmMuLCBTdWN1cnNhbCBlbiBFc3Bhw7FhLlxuICpcbiAqIFRoaXMgc29mdHdhcmUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC5cbiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7XG4gKiB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLlxuICogU2VlIHRoZSB0ZXJtcyBvZiB0aGUgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuICpcbiAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wLlxuICovXG5pbXBvcnQge1xuICAgQWZ0ZXJWaWV3SW5pdCxcbiAgIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gICBDb21wb25lbnQsXG4gICBFbGVtZW50UmVmLFxuICAgRXZlbnRFbWl0dGVyLFxuICAgZm9yd2FyZFJlZixcbiAgIEhvc3RCaW5kaW5nLFxuICAgSW5qZWN0b3IsXG4gICBJbnB1dCxcbiAgIE91dHB1dCxcbiAgIFZpZXdDaGlsZFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBGb3JtQ29udHJvbCwgTkdfVkFMVUVfQUNDRVNTT1IgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBjbG9uZURlZXAgYXMgX2Nsb25lRGVlcCwgZmxhdHRlbiBhcyBfZmxhdHRlbiwgaGFzIGFzIF9oYXMgfSBmcm9tICdsb2Rhc2gnO1xuXG5pbXBvcnQgeyBTdENoZWNrVmFsaWRhdGlvbnNEaXJlY3RpdmUgfSBmcm9tICcuL3N0LWNoZWNrLXZhbGlkYXRpb25zJztcbmltcG9ydCB7IFN0RHJvcERvd25NZW51R3JvdXAsIFN0RHJvcERvd25NZW51SXRlbSB9IGZyb20gJy4uL3N0LWRyb3Bkb3duLW1lbnUvc3QtZHJvcGRvd24tbWVudS5pbnRlcmZhY2UnO1xuXG5AQ29tcG9uZW50KHtcbiAgIHNlbGVjdG9yOiAnc3Qtc2VsZWN0JyxcbiAgIHRlbXBsYXRlVXJsOiAnLi9zdC1zZWxlY3QuaHRtbCcsXG4gICBzdHlsZVVybHM6IFsnLi9zdC1zZWxlY3Quc2NzcyddLFxuICAgaG9zdDoge1xuICAgICAgJ2NsYXNzJzogJ3N0LXNlbGVjdCdcbiAgIH0sXG4gICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgIHByb3ZpZGVyczogW1xuICAgICAgeyBwcm92aWRlOiBOR19WQUxVRV9BQ0NFU1NPUiwgdXNlRXhpc3Rpbmc6IGZvcndhcmRSZWYoKCkgPT4gU3RTZWxlY3RDb21wb25lbnQpLCBtdWx0aTogdHJ1ZSB9XG4gICBdXG59KVxuZXhwb3J0IGNsYXNzIFN0U2VsZWN0Q29tcG9uZW50IGltcGxlbWVudHMgQWZ0ZXJWaWV3SW5pdCwgQ29udHJvbFZhbHVlQWNjZXNzb3Ige1xuXG4gICBASW5wdXQoKSBwbGFjZWhvbGRlcjogc3RyaW5nID0gJyc7XG4gICBASW5wdXQoKSBuYW1lOiBzdHJpbmcgPSAnJztcbiAgIEBJbnB1dCgpIGxhYmVsOiBzdHJpbmcgPSAnJztcbiAgIEBJbnB1dCgpIHRvb2x0aXA6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuICAgQElucHV0KCkgZXJyb3JNZXNzYWdlOiBzdHJpbmc7XG4gICBASW5wdXQoKSBzZWxlY3RlZDogU3REcm9wRG93bk1lbnVJdGVtID0gdW5kZWZpbmVkO1xuICAgQElucHV0KCkgZGVmYXVsdDogYW55O1xuICAgQElucHV0KCkgaXRlbXNCZWZvcmVTY3JvbGw6IG51bWJlciA9IDg7XG4gICBASW5wdXQoKSBlbmFibGVkU2VhcmNoZXI6IGJvb2xlYW4gPSBmYWxzZTtcbiAgIEBJbnB1dCgpIGlzTG9hZGluZzogYm9vbGVhbiA9IGZhbHNlO1xuICAgQElucHV0KCkgZm9yY2VWYWxpZGF0aW9uczogYm9vbGVhbiA9IGZhbHNlO1xuXG4gICBASW5wdXQoKSBwbGFjZWhvbGRlclNlYXJjaD86IHN0cmluZyA9ICdTZWFyY2guLi4nO1xuICAgQElucHV0KCkga2V5Qm9hcmRNb3ZlOiBib29sZWFuID0gZmFsc2U7XG5cbiAgIEBPdXRwdXQoKSBleHBhbmQ6IEV2ZW50RW1pdHRlcjxib29sZWFuPiA9IG5ldyBFdmVudEVtaXR0ZXI8Ym9vbGVhbj4oKTtcbiAgIEBPdXRwdXQoKSBzZWxlY3Q6IEV2ZW50RW1pdHRlcjxhbnk+ID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XG4gICBAT3V0cHV0KCkgc2Nyb2xsQXRCb3R0b206IEV2ZW50RW1pdHRlcjxhbnk+ID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XG4gICBAT3V0cHV0KCkgc2VhcmNoOiBFdmVudEVtaXR0ZXI8c3RyaW5nPiA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpO1xuXG4gICBAVmlld0NoaWxkKCdpbnB1dCcsIHtzdGF0aWM6IGZhbHNlfSkgaW5wdXRFbGVtZW50OiBFbGVtZW50UmVmO1xuICAgQFZpZXdDaGlsZCgnYnV0dG9uJywge3N0YXRpYzogZmFsc2V9KSBidXR0b25FbGVtZW50OiBFbGVtZW50UmVmO1xuXG4gICBASG9zdEJpbmRpbmcoJ2NsYXNzLnN0LXNlbGVjdC1vcGVuZWQnKVxuXG4gICBwdWJsaWMgZXhwYW5kZWRNZW51OiBib29sZWFuID0gZmFsc2U7XG4gICBwdWJsaWMgc2VhcmNoSW5wdXQ6IEZvcm1Db250cm9sID0gbmV3IEZvcm1Db250cm9sKCk7XG4gICBwdWJsaWMgaW5wdXRGb3JtQ29udHJvbDogRm9ybUNvbnRyb2wgPSBuZXcgRm9ybUNvbnRyb2woKTtcblxuICAgb25DaGFuZ2U6IChfOiBhbnkpID0+IHZvaWQ7XG4gICBvblRvdWNoZWQ6ICgpID0+IHZvaWQ7XG5cbiAgIHByaXZhdGUgX2lucHV0SFRNTEVsZW1lbnQ6IEhUTUxJbnB1dEVsZW1lbnQgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG4gICBwcml2YXRlIF9pc0Rpc2FibGVkOiBib29sZWFuID0gZmFsc2U7XG4gICBwcml2YXRlIF9vcHRpb25zOiBTdERyb3BEb3duTWVudUl0ZW1bXSB8IFN0RHJvcERvd25NZW51R3JvdXBbXSA9IFtdO1xuXG5cbiAgIGNvbnN0cnVjdG9yKHByaXZhdGUgX3NlbGVjdEVsZW1lbnQ6IEVsZW1lbnRSZWYsXG4gICAgICAgICAgICAgICBwcml2YXRlIF9pbmplY3RvcjogSW5qZWN0b3IsXG4gICAgICAgICAgICAgICBwcml2YXRlIF9jZDogQ2hhbmdlRGV0ZWN0b3JSZWYpIHtcbiAgIH1cblxuICAgLy8gVE9ETzogTU9WRSBUSElTIFRPIEZPUk0tQkFTRVxuICAgbm90aWZ5RXJyb3IoZXJyb3JNZXNzYWdlOiBzdHJpbmcpOiB2b2lkIHtcbiAgICAgIHRoaXMuZXJyb3JNZXNzYWdlID0gZXJyb3JNZXNzYWdlO1xuICAgfVxuXG4gICAvKlxuICAgICoqKioqKiBnZXR0ZXJzICYmIHNldHRlcnMgKioqKioqXG4gICAgKi9cbiAgIEBJbnB1dCgpXG4gICBzZXQgZGlzYWJsZWQodmFsdWU6IGJvb2xlYW4pIHtcbiAgICAgIHRoaXMuX2lzRGlzYWJsZWQgPSB2YWx1ZTtcbiAgICAgIHRoaXMuX2NkLm1hcmtGb3JDaGVjaygpO1xuICAgfVxuXG4gICBnZXQgZGlzYWJsZWQoKTogYm9vbGVhbiB7XG4gICAgICByZXR1cm4gdGhpcy5faXNEaXNhYmxlZDtcbiAgIH1cblxuICAgQElucHV0KClcbiAgIHNldCBvcHRpb25zKG9wdGlvbnM6IFN0RHJvcERvd25NZW51SXRlbVtdIHwgU3REcm9wRG93bk1lbnVHcm91cFtdKSB7XG4gICAgICB0aGlzLl9vcHRpb25zID0gX2Nsb25lRGVlcChvcHRpb25zKTtcbiAgICAgIGNvbnN0IHNlbGVjdGVkSXRlbTogU3REcm9wRG93bk1lbnVJdGVtIHwgdW5kZWZpbmVkID0gdGhpcy5maW5kQnlQcm9wZXJ0eSgnc2VsZWN0ZWQnLCB0cnVlKTtcbiAgICAgIHRoaXMucmVtb3ZlQWxsU2VsZWN0ZWQoKTtcbiAgICAgIGlmIChzZWxlY3RlZEl0ZW0pIHtcbiAgICAgICAgIHRoaXMuc2VsZWN0ZWQgPSBzZWxlY3RlZEl0ZW07XG4gICAgICB9XG4gICB9XG5cbiAgIGdldCBvcHRpb25zKCk6IFN0RHJvcERvd25NZW51SXRlbVtdIHwgU3REcm9wRG93bk1lbnVHcm91cFtdIHtcbiAgICAgIHJldHVybiB0aGlzLl9vcHRpb25zO1xuICAgfVxuXG4gICBnZXQgc2VsZWN0ZWRWYWx1ZSgpOiBzdHJpbmcge1xuICAgICAgcmV0dXJuIHRoaXMuc2VsZWN0ZWQgJiYgdGhpcy5zZWxlY3RlZC5sYWJlbCA/IHRoaXMuc2VsZWN0ZWQubGFiZWwgOiAnJztcbiAgIH1cblxuICAgZ2V0IGRpc2FibGVWYWx1ZSgpOiBzdHJpbmcgfCBudWxsIHtcbiAgICAgIHJldHVybiB0aGlzLl9pc0Rpc2FibGVkID09PSB0cnVlID8gJycgOiBudWxsO1xuICAgfVxuXG4gICBnZXQgc2VsZWN0SWQoKTogc3RyaW5nIHwgbnVsbCB7XG4gICAgICBjb25zdCBzZWxlY3Q6IEhUTUxFbGVtZW50ID0gdGhpcy5fc2VsZWN0RWxlbWVudC5uYXRpdmVFbGVtZW50O1xuICAgICAgcmV0dXJuIHNlbGVjdC5nZXRBdHRyaWJ1dGUoJ2lkJykgIT09IG51bGwgPyBzZWxlY3QuaWQgOiBudWxsO1xuICAgfVxuXG4gICBnZXQgaW5wdXRJZCgpOiBzdHJpbmcgfCBudWxsIHtcbiAgICAgIHJldHVybiB0aGlzLnNlbGVjdElkICE9PSBudWxsID8gYCR7dGhpcy5zZWxlY3RJZH0taW5wdXRgIDogbnVsbDtcbiAgIH1cblxuICAgZ2V0IGxhYmVsSWQoKTogc3RyaW5nIHwgbnVsbCB7XG4gICAgICByZXR1cm4gdGhpcy5zZWxlY3RJZCAhPT0gbnVsbCA/IGAke3RoaXMuc2VsZWN0SWR9LWxhYmVsYCA6IG51bGw7XG4gICB9XG5cbiAgIGdldCBvcHRpb25zSWQoKTogc3RyaW5nIHwgbnVsbCB7XG4gICAgICByZXR1cm4gdGhpcy5zZWxlY3RJZCAhPT0gbnVsbCA/IGAke3RoaXMuc2VsZWN0SWR9LW9wdGlvbnNgIDogbnVsbDtcbiAgIH1cblxuICAgZ2V0IGlucHV0TmFtZSgpOiBzdHJpbmcgfCBudWxsIHtcbiAgICAgIHJldHVybiB0aGlzLm5hbWUgJiYgdGhpcy5uYW1lLmxlbmd0aCA+IDAgPyB0aGlzLm5hbWUgOiBudWxsO1xuICAgfVxuXG4gICBnZXQgaGFzTGFiZWwoKTogYm9vbGVhbiB7XG4gICAgICByZXR1cm4gdGhpcy5sYWJlbCAhPT0gdW5kZWZpbmVkICYmIHRoaXMubGFiZWwgIT09IG51bGwgJiYgdGhpcy5sYWJlbC5sZW5ndGggPiAwO1xuICAgfVxuXG4gICBzaG93RXJyb3IoKTogYm9vbGVhbiB7XG4gICAgICByZXR1cm4gdGhpcy5lcnJvck1lc3NhZ2UgJiYgdGhpcy5lcnJvck1lc3NhZ2UubGVuZ3RoICYmICh0aGlzLmlucHV0Rm9ybUNvbnRyb2wudG91Y2hlZCB8fCB0aGlzLmZvcmNlVmFsaWRhdGlvbnMpICYmICF0aGlzLl9pc0Rpc2FibGVkO1xuICAgfVxuXG4gICAvKlxuICAgICoqKioqKiBDb250cm9sIHZhbHVlIGFjY2Vzc29yICYmIHZhbGlkYXRlIG1ldGhvZHMgKioqKioqXG4gICAgKi9cblxuICAgb25TZWFyY2goKTogdm9pZCB7XG4gICAgICB0aGlzLnNlYXJjaC5lbWl0KHRoaXMuc2VhcmNoSW5wdXQudmFsdWUpO1xuICAgICAgdGhpcy5fY2QubWFya0ZvckNoZWNrKCk7XG4gICB9XG5cbiAgIG9uU2VhcmNoQ2xpY2soZXZlbnQ6IEV2ZW50KTogdm9pZCB7XG4gICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICB9XG5cbiAgIC8vIFNldCB0aGUgZnVuY3Rpb24gdG8gYmUgY2FsbGVkIHdoZW4gdGhlIGNvbnRyb2wgcmVjZWl2ZXMgYSBjaGFuZ2UgZXZlbnQuXG4gICByZWdpc3Rlck9uQ2hhbmdlKGZuOiAoXzogYW55KSA9PiB2b2lkKTogdm9pZCB7XG4gICAgICB0aGlzLm9uQ2hhbmdlID0gZm47XG4gICB9XG5cbiAgIC8vIFNldCB0aGUgZnVuY3Rpb24gdG8gYmUgY2FsbGVkIHdoZW4gdGhlIGNvbnRyb2wgcmVjZWl2ZXMgYSB0b3VjaCBldmVudC5cbiAgIHJlZ2lzdGVyT25Ub3VjaGVkKGZuOiAoKSA9PiB2b2lkKTogdm9pZCB7XG4gICAgICB0aGlzLm9uVG91Y2hlZCA9IGZuO1xuICAgfVxuXG4gICBzZXREaXNhYmxlZFN0YXRlKGRpc2FibGVkOiBib29sZWFuKTogdm9pZCB7XG4gICAgICB0aGlzLl9pc0Rpc2FibGVkID0gZGlzYWJsZWQ7XG4gICAgICB0aGlzLl9jZC5tYXJrRm9yQ2hlY2soKTtcbiAgIH1cblxuICAgLy8gV3JpdGUgYSBuZXcgdmFsdWUgdG8gdGhlIGVsZW1lbnQuXG4gICB3cml0ZVZhbHVlKG5ld1ZhbHVlOiBhbnkpOiB2b2lkIHtcbiAgICAgIGlmICghdGhpcy5zZWxlY3RlZCB8fCB0aGlzLnNlbGVjdGVkLnZhbHVlICE9PSBuZXdWYWx1ZSkge1xuICAgICAgICAgdGhpcy5zZWxlY3RlZCA9IHRoaXMuZmluZEJ5UHJvcGVydHkoJ3ZhbHVlJywgbmV3VmFsdWUpO1xuICAgICAgICAgdGhpcy5fY2QubWFya0ZvckNoZWNrKCk7XG4gICAgICB9XG4gICB9XG5cbiAgIC8qXG4gICAgKioqKioqIENvbXBvbmVudCBtZXRob2RzICoqKioqKlxuICAgICovXG5cbiAgIG5nQWZ0ZXJWaWV3SW5pdCgpOiB2b2lkIHtcbiAgICAgIHRoaXMuX2lucHV0SFRNTEVsZW1lbnQgPSB0aGlzLmlucHV0RWxlbWVudC5uYXRpdmVFbGVtZW50O1xuICAgICAgY29uc3QgZGlyZWN0aXZlOiBTdENoZWNrVmFsaWRhdGlvbnNEaXJlY3RpdmUgPSB0aGlzLl9pbmplY3Rvci5nZXQoU3RDaGVja1ZhbGlkYXRpb25zRGlyZWN0aXZlLCBudWxsKTtcbiAgICAgIGlmIChkaXJlY3RpdmUpIHtcbiAgICAgICAgIGRpcmVjdGl2ZS5yZWdpc3Rlck9uQ2hhbmdlKHRoaXMubm90aWZ5RXJyb3IuYmluZCh0aGlzKSk7XG4gICAgICB9XG4gICB9XG5cbiAgIG9uQnV0dG9uQ2xpY2soKTogdm9pZCB7XG4gICAgICBpZiAoIXRoaXMuX2lzRGlzYWJsZWQpIHtcbiAgICAgICAgIHRoaXMudG9nZ2xlQnV0dG9uKCk7XG4gICAgICAgICB0aGlzLmV4cGFuZGVkTWVudSA/IHRoaXMuX2lucHV0SFRNTEVsZW1lbnQuZm9jdXMoKSA6IHRoaXMuX2lucHV0SFRNTEVsZW1lbnQuYmx1cigpO1xuICAgICAgfVxuICAgfVxuXG4gICBvbkJ1dHRvbktleVByZXNzKGV2ZW50OiBLZXlib2FyZEV2ZW50KTogdm9pZCB7XG4gICAgICBpZiAoZXZlbnQuY29kZSA9PT0gJ0VudGVyJykge1xuICAgICAgICAgdGhpcy50b2dnbGVCdXR0b24oKTtcbiAgICAgIH1cbiAgIH1cblxuICAgY2xlYXJTZWFyY2hJbnB1dCgpOiB2b2lkIHtcbiAgICAgIHRoaXMuc2VhcmNoSW5wdXQuc2V0VmFsdWUoJycpO1xuICAgICAgdGhpcy5zZWFyY2guZW1pdCgnJyk7XG4gICB9XG5cbiAgIGNyZWF0ZVJlc2V0QnV0dG9uKCk6IGJvb2xlYW4ge1xuICAgICAgcmV0dXJuIHRoaXMuZGVmYXVsdCAhPT0gdW5kZWZpbmVkICYmICgoIXRoaXMuc2VsZWN0ZWQgJiYgdGhpcy5pbnB1dEZvcm1Db250cm9sLnRvdWNoZWQpIHx8ICh0aGlzLnNlbGVjdGVkICYmIHRoaXMuc2VsZWN0ZWQudmFsdWUgIT09IHRoaXMuZGVmYXVsdCkpO1xuICAgfVxuXG4gICByZXNldFRvRGVmYXVsdCgpOiB2b2lkIHtcbiAgICAgIHRoaXMud3JpdGVWYWx1ZSh0aGlzLmRlZmF1bHQpO1xuICAgICAgdGhpcy5zZWxlY3QuZW1pdCh0aGlzLmRlZmF1bHQpO1xuICAgICAgaWYgKHRoaXMub25DaGFuZ2UpIHtcbiAgICAgICAgIHRoaXMub25DaGFuZ2UodGhpcy5kZWZhdWx0KTtcbiAgICAgIH1cbiAgICAgIHRoaXMuX2NkLm1hcmtGb3JDaGVjaygpO1xuICAgfVxuXG4gICBvbkNsaWNrT3V0c2lkZSgpOiB2b2lkIHtcbiAgICAgIHRoaXMuZXhwYW5kZWRNZW51ID0gZmFsc2U7XG4gICAgICB0aGlzLmV4cGFuZC5lbWl0KHRoaXMuZXhwYW5kZWRNZW51KTsgLy8gTm90aWZ5IGV4cGFuZCBjaGFuZ2VcbiAgIH1cblxuICAgb25DaGFuZ2VPcHRpb24ob3B0aW9uOiBTdERyb3BEb3duTWVudUl0ZW0pOiB2b2lkIHtcbiAgICAgIHRoaXMuc2VsZWN0ZWQgPSBvcHRpb24gJiYgb3B0aW9uLnZhbHVlICE9PSB1bmRlZmluZWQgPyBvcHRpb24gOiB1bmRlZmluZWQ7XG4gICAgICBjb25zdCB2YWx1ZTogYW55ID0gb3B0aW9uICYmIG9wdGlvbi52YWx1ZSAhPT0gdW5kZWZpbmVkID8gb3B0aW9uLnZhbHVlIDogdW5kZWZpbmVkO1xuICAgICAgaWYgKHRoaXMub25DaGFuZ2UpIHtcbiAgICAgICAgIHRoaXMub25DaGFuZ2UodmFsdWUpO1xuICAgICAgfVxuICAgICAgaWYgKHRoaXMub25Ub3VjaGVkKSB7XG4gICAgICAgICB0aGlzLm9uVG91Y2hlZCgpO1xuICAgICAgfVxuICAgICAgdGhpcy5zZWxlY3QuZW1pdCh2YWx1ZSk7XG5cbiAgICAgIGlmICh2YWx1ZSB8fCAob3B0aW9uICYmIG9wdGlvbi5oYXNPd25Qcm9wZXJ0eSgndmFsdWUnKSAmJiAhb3B0aW9uLnZhbHVlKSkge1xuICAgICAgICAgdGhpcy5vbkNsaWNrT3V0c2lkZSgpO1xuICAgICAgfVxuICAgICAgdGhpcy5fY2QubWFya0ZvckNoZWNrKCk7XG4gICB9XG5cbiAgIG9uU2Nyb2xsQXRCb3R0b20oKTogdm9pZCB7XG4gICAgICB0aGlzLnNjcm9sbEF0Qm90dG9tLmVtaXQoKTtcbiAgIH1cblxuICAgLypcbiAgICAqKioqKiogVXRpbCBjb21wb25lbnQgbWV0aG9kcyAqKioqKipcbiAgICAqL1xuXG4gICAvLyBTZWFyY2ggZWxlbWVudCBieSBwcm9wZXJ0eSBpbiBvcHRpb24gbGlzdFxuICAgcHJpdmF0ZSBmaW5kQnlQcm9wZXJ0eShwcm9wTmFtZTogJ3ZhbHVlJyB8ICdzZWxlY3RlZCcsIHByb3BWYWx1ZTogYW55KTogU3REcm9wRG93bk1lbnVJdGVtIHwgdW5kZWZpbmVkIHtcbiAgICAgIGlmICh0aGlzLmlzU3REcm9wZG93bkl0ZW1MaXN0KHRoaXMub3B0aW9ucykpIHtcbiAgICAgICAgIHJldHVybiB0aGlzLm9wdGlvbnMuZmluZChpdGVtID0+IF9oYXMoaXRlbSwgcHJvcE5hbWUpICYmIGl0ZW1bcHJvcE5hbWVdID09PSBwcm9wVmFsdWUpO1xuICAgICAgfSBlbHNlIGlmICh0aGlzLmlzU3REcm9wZG93bkdyb3VwTGlzdCh0aGlzLm9wdGlvbnMpKSB7XG4gICAgICAgICByZXR1cm4gX2ZsYXR0ZW4odGhpcy5vcHRpb25zLm1hcChncm91cCA9PiBncm91cC5pdGVtcykpLmZpbmQoaXRlbSA9PiBfaGFzKGl0ZW0sIHByb3BOYW1lKSAmJiBpdGVtW3Byb3BOYW1lXSA9PT0gcHJvcFZhbHVlKTtcbiAgICAgIH1cbiAgIH1cblxuICAgLy8gQ2hlY2sgaWYgb3B0aW9ucyBhcmUgYSBpbnN0YW5jZSBvZiBTdERyb3BEb3duTWVudUl0ZW1bXVxuICAgcHJpdmF0ZSBpc1N0RHJvcGRvd25JdGVtTGlzdChpdGVtczogU3REcm9wRG93bk1lbnVJdGVtW10gfCBTdERyb3BEb3duTWVudUdyb3VwW10pOiBpdGVtcyBpcyBTdERyb3BEb3duTWVudUl0ZW1bXSB7XG4gICAgICByZXR1cm4gdGhpcy5vcHRpb25zICYmIHRoaXMub3B0aW9ucy5sZW5ndGggPiAwICYmICFfaGFzKChpdGVtcyBhcyBTdERyb3BEb3duTWVudUdyb3VwW10pWzBdLCAnaXRlbXMnKTtcbiAgIH1cblxuICAgLy8gQ2hlY2sgaWYgb3B0aW9ucyBhcmUgYSBpbnN0YW5jZSBvZiBTdERyb3BEb3duTWVudUdyb3VwW11cbiAgIHByaXZhdGUgaXNTdERyb3Bkb3duR3JvdXBMaXN0KGl0ZW1zOiBTdERyb3BEb3duTWVudUl0ZW1bXSB8IFN0RHJvcERvd25NZW51R3JvdXBbXSk6IGl0ZW1zIGlzIFN0RHJvcERvd25NZW51R3JvdXBbXSB7XG4gICAgICByZXR1cm4gdGhpcy5vcHRpb25zICYmIHRoaXMub3B0aW9ucy5sZW5ndGggPiAwICYmIF9oYXMoKGl0ZW1zIGFzIFN0RHJvcERvd25NZW51R3JvdXBbXSlbMF0sICdpdGVtcycpO1xuICAgfVxuXG4gICBwcml2YXRlIHRvZ2dsZUJ1dHRvbigpOiB2b2lkIHtcbiAgICAgIHRoaXMuZXhwYW5kZWRNZW51ID0gIXRoaXMuZXhwYW5kZWRNZW51O1xuICAgICAgdGhpcy5leHBhbmQuZW1pdCh0aGlzLmV4cGFuZGVkTWVudSk7IC8vIE5vdGlmeSBleHBhbmQgY2hhbmdlXG4gICAgICB0aGlzLl9jZC5tYXJrRm9yQ2hlY2soKTtcbiAgIH1cblxuICAgLy8gVE9ETzogUmVtb3ZlIHdoZW4gcmVtb3ZlIGZyb20gU3REcm9wRG93bk1lbnVJdGVtIG1vZGVsIHRoZSBzZWxlY3RlZCBwcm9wZXJ0eVxuICAgcHJpdmF0ZSByZW1vdmVBbGxTZWxlY3RlZCgpOiB2b2lkIHtcbiAgICAgIGlmICh0aGlzLmlzU3REcm9wZG93bkl0ZW1MaXN0KHRoaXMub3B0aW9ucykpIHtcbiAgICAgICAgIHJldHVybiB0aGlzLm9wdGlvbnMuZm9yRWFjaChpdGVtID0+IHtcbiAgICAgICAgICAgIGlmIChpdGVtLnNlbGVjdGVkKSB7XG4gICAgICAgICAgICAgICBkZWxldGUgaXRlbS5zZWxlY3RlZDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgIH0pO1xuICAgICAgfSBlbHNlIGlmICh0aGlzLmlzU3REcm9wZG93bkdyb3VwTGlzdCh0aGlzLm9wdGlvbnMpKSB7XG4gICAgICAgICB0aGlzLm9wdGlvbnMuZm9yRWFjaChncm91cCA9PiBncm91cC5pdGVtcy5mb3JFYWNoKGl0ZW0gPT4ge1xuICAgICAgICAgICAgaWYgKGl0ZW0uc2VsZWN0ZWQpIHtcbiAgICAgICAgICAgICAgIGRlbGV0ZSBpdGVtLnNlbGVjdGVkO1xuICAgICAgICAgICAgfVxuICAgICAgICAgfSkpO1xuICAgICAgfVxuICAgfVxufVxuIl19