@hxui/angular
Version:
This README includes the steps that are necessary to import the HxUi-angular into a project or to contribute with development.
444 lines (443 loc) • 51.2 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
import { Input, forwardRef, Component, ViewChild, Output, EventEmitter, IterableDiffers, ViewEncapsulation, Renderer2 } from '@angular/core';
import { NG_VALUE_ACCESSOR, FormControl } from '@angular/forms';
import * as _ from 'lodash';
import { SelectizeConfig } from './selectize.config';
export const /** @type {?} */ SELECTIZE_VALUE_ACCESSOR = {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => SelectizeComponent),
multi: true
};
export class SelectizeComponent {
/**
* @param {?} _differs
* @param {?} renderer
*/
constructor(_differs, renderer) {
this._differs = _differs;
this.renderer = renderer;
this.enabled = true;
this.onBlur = new EventEmitter(false);
/**
* Invoked anytime a key is pressed down on the selectize search field
* @param e
*/
this.onKeydown = e => {
console.log(e);
const /** @type {?} */ TABKEY = 9;
if (e.keyCode === TABKEY) {
e.preventDefault();
e.stopImmediatePropagation();
e.stopPropagation();
}
};
}
/**
* @return {?}
*/
ngOnInit() {
if (this.id && this.id.length > 0) {
this.renderer.setAttribute(this.selectizeInput.nativeElement, 'id', this.id);
}
this.reset();
}
/**
* @return {?}
*/
reset() {
this.selectize = $(this.selectizeInput.nativeElement).selectize(this.config)[0].selectize;
this.selectize.on('change', this.onSelectizeValueChange.bind(this));
this.selectize.on('blur', this.onBlurEvent.bind(this));
this.selectize.on('type', this.onSelectizeType.bind(this));
this.selectize.on('item_add', this.onSelectizeItemSelected.bind(this));
this.updatePlaceholder();
this.onEnabledStatusChange();
}
/**
* @return {?}
*/
ngOnDestroy() {
this.selectize.off('change');
this.selectize.off('blur');
this.selectize.off('type');
}
/**
* Change detection for primitive types.
* @param {?} changes
* @return {?}
*/
ngOnChanges(changes) {
if (this.selectize) {
if (changes.hasOwnProperty('placeholder') ||
changes.hasOwnProperty('hasOptionsPlaceholder') ||
changes.hasOwnProperty('noOptionsPlaceholder')) {
this.updatePlaceholder();
}
if (changes.hasOwnProperty('enabled')) {
this.onEnabledStatusChange();
}
}
}
/**
* Implementing deep check for option comparison
*
* FIXME -> Implement deep check to only compare against label and value fields.
* @return {?}
*/
ngDoCheck() {
if (this._options_differ) {
const /** @type {?} */ changes = this._options_differ.diff(this._options);
if (changes) {
this._applyOptionsChanges(changes);
}
}
if (this._optgroups_differ) {
const /** @type {?} */ changes = this._optgroups_differ.diff(this._optgroups);
if (changes) {
this._applyOptionGroupChanges(changes);
}
}
}
/**
* @param {?} changes
* @return {?}
*/
_applyOptionsChanges(changes) {
changes.forEachAddedItem((record) => {
this.onSelectizeOptionAdd(record.item);
});
changes.forEachRemovedItem((record) => {
this.onSelectizeOptionRemove(record.item);
});
this.updatePlaceholder();
this.evalHasError();
}
/**
* @param {?} changes
* @return {?}
*/
_applyOptionGroupChanges(changes) {
changes.forEachAddedItem((record) => {
this.onSelectizeOptGroupAdd(record.item);
});
changes.forEachRemovedItem((record) => {
this.onSelectizeOptGroupRemove(record.item);
});
this.updatePlaceholder();
this.evalHasError();
}
/**
* @return {?}
*/
clearhighlight() {
// remove highlight to help selectize bug
// https://github.com/selectize/selectize.js/issues/1141
this.selectize.$dropdown_content.removeHighlight();
}
/**
* @return {?}
*/
onBlurEvent() {
if (this.formControl) {
this.formControl.markAsTouched();
}
this.onBlur.emit();
this.evalHasError();
}
/**
* @param {?} optgroup
* @return {?}
*/
onSelectizeOptGroupAdd(optgroup) {
this.selectize.addOptionGroup(optgroup[this.getOptgroupField()], optgroup);
}
/**
* @param {?} optgroup
* @return {?}
*/
onSelectizeOptGroupRemove(optgroup) {
this.selectize.removeOptionGroup(optgroup[this.getOptgroupField()]);
}
/**
* Refresh selected values when options change.
* @param {?} option
* @return {?}
*/
onSelectizeOptionAdd(option) {
this.selectize.addOption(_.cloneDeep(option));
const /** @type {?} */ valueField = this.config.valueField;
if (this.value) {
const /** @type {?} */ items = typeof this.value === 'string' || typeof this.value === 'number'
? [this.value]
: this.value;
if (items &&
items instanceof Array &&
items.find(value => value === option[valueField])) {
this.selectize.addItem(option[valueField], true);
}
}
}
/**
* @param {?} option
* @return {?}
*/
onSelectizeOptionRemove(option) {
this.selectize.removeOption(option[this.config.valueField]);
}
/**
* @return {?}
*/
evalHasError() {
const /** @type {?} */ parent = $(this.selectize.$control).parent();
if (this.formControl) {
if (this.formControl.touched && this.formControl.invalid) {
parent.addClass(this.errorClass || 'has-error');
}
else if (parent.hasClass('has-error')) {
parent.removeClass(this.errorClass || 'has-error');
}
}
}
/**
* Update the current placeholder based on the given input parameter.
* @return {?}
*/
updatePlaceholder() {
if (this.selectize.items.length === 0 &&
this.selectize.settings.placeholder !== this.getPlaceholder()) {
this.selectize.settings.placeholder = this.getPlaceholder();
this.selectize.updatePlaceholder();
this.selectize.showInput(); // Without this, when options are cleared placeholder only appears after focus.
}
}
/**
* Called when a change is detected in the 'enabled' input field.
* Sets the selectize state based on the new value.
* @return {?}
*/
onEnabledStatusChange() {
this.enabled ? this.selectize.enable() : this.selectize.disable();
}
/**
* Dispatches change event when a value change is detected.
* @param {?} $event
* @return {?}
*/
onSelectizeValueChange($event) {
// In some cases this gets called before registerOnChange.
if (this.onChangeCallback) {
// Map selectize's value collection back to original ISelectizeItem object
const /** @type {?} */ data = this.selectize.items.map(v => {
return this.selectize.options[v];
});
this.onChangeCallback(data);
}
}
/**
* Invoked when the user types while filtering options.
* @param {?} str
* @return {?}
*/
onSelectizeType(str) {
if (str.length === 0) {
this.clearhighlight();
this.selectize.close();
}
}
/**
* @param {?} $event
* @return {?}
*/
onSelectizeItemSelected($event) {
this.clearhighlight();
if (this.config.closeAfterSelect) {
this.selectize.close();
}
}
/**
* Returns the applicable placeholder.
* @return {?}
*/
getPlaceholder() {
if (this.hasOptionsPlaceholder) {
if (this.options && this.options.length > 0) {
return this.hasOptionsPlaceholder;
}
}
if (this.noOptionsPlaceholder) {
if (!this.options || this.options.length === 0) {
return this.noOptionsPlaceholder;
}
}
return this.placeholder;
}
/**
* Implementation from ControlValueAccessor
*
* @param {?} obj
* @return {?}
*/
writeValue(obj) {
if (obj === this.value) {
return;
}
this.value = obj;
if (!obj || obj.length === 0) {
this.selectize.setValue('');
return;
}
const /** @type {?} */ stringValue = obj.map(v => {
if (!Object.keys(this.selectize.options).some(x => x === v.value)) {
this.selectize.addOption(v);
}
return v.value;
});
this.selectize.setValue(stringValue);
}
/**
* Implementation from ControlValueAccessor, callback for (ngModelChange)
* @param {?} fn
* @return {?}
*/
registerOnChange(fn) {
this.onChangeCallback = fn;
}
/**
* Implementation from ControlValueAccessor
* @param {?} fn
* @return {?}
*/
registerOnTouched(fn) {
this.onTouchedCallback = fn;
}
/**
* @return {?}
*/
getOptgroupField() {
return this.config['optgroupField']
? this.config['optgroupField']
: 'optgroup';
}
/**
* @param {?} value
* @return {?}
*/
set options(value) {
this._options = value;
if (!this._options_differ && value) {
this._options_differ = this._differs.find(value).create();
}
}
/**
* @return {?}
*/
get options() {
return this._options;
}
/**
* @param {?} value
* @return {?}
*/
set optgroups(value) {
this._optgroups = value;
if (!this._optgroups_differ && value) {
this._optgroups_differ = this._differs.find(value).create();
}
}
/**
* @return {?}
*/
get optgroups() {
return this._optgroups;
}
}
SelectizeComponent.decorators = [
{ type: Component, args: [{
selector: 'hxa-selectize',
template: `<select #selectizeInput></select>`,
providers: [SELECTIZE_VALUE_ACCESSOR],
encapsulation: ViewEncapsulation.None,
styles: [`.selectize-control{position:relative}.selectize-dropdown,.selectize-input,.selectize-input input{color:#2a2c2d;font-family:inherit;font-size:.92rem;line-height:1.5;-webkit-font-smoothing:inherit}.selectize-control.single .selectize-input.input-active,.selectize-input{background:0 0;cursor:text;display:inline-block}.selectize-input{border:1px solid rgba(0,0,0,.2);padding:8px;display:inline-block;width:100%;overflow:hidden;position:relative;z-index:1;box-sizing:border-box;box-shadow:none;border-radius:0;border-width:0 0 1px}.selectize-control.multi .selectize-input.has-items{padding:6px 8px 3px}.selectize-input.full{background-color:transparent}.selectize-input.disabled,.selectize-input.disabled *{cursor:default!important}.selectize-input.focus{box-shadow:none}.selectize-input.dropdown-active{border-radius:0}.selectize-input>*{vertical-align:baseline;display:inline-block;zoom:1}.selectize-control.multi .selectize-input>div{cursor:pointer;margin:4px;padding:2px 6px;background:rgba(0,0,0,.05);color:#2a2c2d;border:0 solid transparent;border-radius:290486px;font-size:.75rem;justify-content:center;line-height:1.5;white-space:nowrap}.selectize-control.multi .selectize-input>div.active{background:#e8e8e8;color:#2a2c2d;border:0 solid #cacaca}.selectize-control.multi .selectize-input.disabled>div,.selectize-control.multi .selectize-input.disabled>div.active{color:#787878;background:rgba(77,77,77,.05);border:0 solid rgba(77,77,77,0)}.selectize-input>input{display:inline-block!important;padding:0!important;min-height:0!important;max-height:none!important;max-width:100%!important;margin:0 2px 0 0!important;text-indent:0!important;border:0!important;background:0 0!important;line-height:inherit!important;-webkit-user-select:auto!important}.selectize-input>input::-ms-clear{display:none}.selectize-input>input:focus{outline:0!important}.selectize-input::after{content:' ';display:block;clear:left}.selectize-input.dropdown-active::before{content:' ';display:block;position:absolute;background:#f0f0f0;height:1px;bottom:0;left:0;right:0}.hx-select-control:after{display:none}.selectize-dropdown{position:absolute;z-index:10;border:transparent;background:#fff;margin:-1px 0 0;border-top:0;box-sizing:border-box;box-shadow:0 6px 12px rgba(0,0,0,.145);border-radius:0}.selectize-dropdown [data-selectable]{cursor:pointer;overflow:hidden}.selectize-dropdown [data-selectable] .highlight{background:rgba(35,49,43,.23);border-radius:1px;font-weight:700}.selectize-dropdown .optgroup-header,.selectize-dropdown [data-selectable]{padding:5px 8px}.selectize-dropdown .optgroup:first-child .optgroup-header{border-top:0}.selectize-dropdown .optgroup-header{color:#2a2c2d;background:#fff;cursor:default}.selectize-dropdown .active{background-color:#41b987;color:#fff}.selectize-dropdown .active.create{color:#fff}.selectize-dropdown .create{color:rgba(42,44,45,.5)}.selectize-dropdown-content{overflow-y:auto;overflow-x:hidden;max-height:200px;-webkit-overflow-scrolling:touch}.selectize-control.single .selectize-input,.selectize-control.single .selectize-input input{cursor:pointer}.selectize-control.single .selectize-input.input-active,.selectize-control.single .selectize-input.input-active input{cursor:text}.selectize-control.single .selectize-input:after{content:' ';display:block;position:absolute;top:50%;right:15px;margin-top:-3px;width:0;height:0;border-style:solid;border-width:5px 5px 0;border-color:grey transparent transparent}.selectize-control.single .selectize-input.dropdown-active:after{margin-top:-4px;border-width:0 5px 5px;border-color:transparent transparent grey}.selectize-control.rtl.single .selectize-input:after{left:15px;right:auto}.selectize-control.rtl .selectize-input>input{margin:0 4px 0 -2px!important}.selectize-control .selectize-input.disabled{opacity:.5;background-color:#fafafa}.selectize-control.plugin-remove_button [data-value]{position:relative;padding-right:.7rem!important}.selectize-control.plugin-remove_button [data-value].is-medium{padding-right:1rem!important}.selectize-control.plugin-remove_button [data-value] .hx-delete{margin-left:-.2rem;height:16px;width:16px;max-height:16px;max-width:16px;min-height:16px;min-width:16px}.selectize-control.plugin-remove_button [data-value].is-medium .hx-delete{margin-left:-.5rem}.selectize-control.plugin-remove_button [data-value].is-large .hx-delete{margin-left:-.2rem;height:20px;width:20px;max-height:20px;max-width:20px;min-height:20px;min-width:20px}.selectize-control.plugin-remove_button .disabled [data-value] .hx-remove:hover{background:0 0}.selectize-control.plugin-remove_button .disabled [data-value] .hx-remove{border-left-color:rgba(77,77,77,0)}.selectize-control.plugin-remove_button .remove-single{position:absolute;right:28px;top:6px;font-size:23px}`]
},] },
];
/** @nocollapse */
SelectizeComponent.ctorParameters = () => [
{ type: IterableDiffers, },
{ type: Renderer2, },
];
SelectizeComponent.propDecorators = {
"config": [{ type: Input },],
"id": [{ type: Input },],
"placeholder": [{ type: Input },],
"hasOptionsPlaceholder": [{ type: Input },],
"noOptionsPlaceholder": [{ type: Input },],
"enabled": [{ type: Input },],
"value": [{ type: Input },],
"formControl": [{ type: Input },],
"errorClass": [{ type: Input },],
"onBlur": [{ type: Output },],
"selectizeInput": [{ type: ViewChild, args: ['selectizeInput',] },],
"options": [{ type: Input },],
"optgroups": [{ type: Input },],
};
function SelectizeComponent_tsickle_Closure_declarations() {
/** @type {!Array<{type: !Function, args: (undefined|!Array<?>)}>} */
SelectizeComponent.decorators;
/**
* @nocollapse
* @type {function(): !Array<(null|{type: ?, decorators: (undefined|!Array<{type: !Function, args: (undefined|!Array<?>)}>)})>}
*/
SelectizeComponent.ctorParameters;
/** @type {!Object<string,!Array<{type: !Function, args: (undefined|!Array<?>)}>>} */
SelectizeComponent.propDecorators;
/** @type {?} */
SelectizeComponent.prototype._options;
/** @type {?} */
SelectizeComponent.prototype._options_differ;
/** @type {?} */
SelectizeComponent.prototype._optgroups;
/** @type {?} */
SelectizeComponent.prototype._optgroups_differ;
/** @type {?} */
SelectizeComponent.prototype.config;
/** @type {?} */
SelectizeComponent.prototype.id;
/** @type {?} */
SelectizeComponent.prototype.placeholder;
/** @type {?} */
SelectizeComponent.prototype.hasOptionsPlaceholder;
/** @type {?} */
SelectizeComponent.prototype.noOptionsPlaceholder;
/** @type {?} */
SelectizeComponent.prototype.enabled;
/** @type {?} */
SelectizeComponent.prototype.value;
/** @type {?} */
SelectizeComponent.prototype.formControl;
/** @type {?} */
SelectizeComponent.prototype.errorClass;
/** @type {?} */
SelectizeComponent.prototype.onBlur;
/** @type {?} */
SelectizeComponent.prototype.selectizeInput;
/** @type {?} */
SelectizeComponent.prototype.selectize;
/** @type {?} */
SelectizeComponent.prototype.onTouchedCallback;
/** @type {?} */
SelectizeComponent.prototype.onChangeCallback;
/**
* Invoked anytime a key is pressed down on the selectize search field
* \@param e
* @type {?}
*/
SelectizeComponent.prototype.onKeydown;
/** @type {?} */
SelectizeComponent.prototype._differs;
/** @type {?} */
SelectizeComponent.prototype.renderer;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VsZWN0aXplLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL0BoeHVpL2FuZ3VsYXIvIiwic291cmNlcyI6WyJsaWIvc2VsZWN0aXplL3NlbGVjdGl6ZS5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQUFBLE9BQU8sRUFDTCxLQUFLLEVBS0wsVUFBVSxFQUNWLFNBQVMsRUFDVCxTQUFTLEVBQ1QsTUFBTSxFQUNOLFlBQVksRUFDWixlQUFlLEVBSWYsaUJBQWlCLEVBQ2pCLFNBQVMsRUFFVixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQ0wsaUJBQWlCLEVBRWpCLFdBQVcsRUFDWixNQUFNLGdCQUFnQixDQUFDO0FBRXhCLE9BQU8sS0FBSyxDQUFDLE1BQU0sUUFBUSxDQUFDO0FBQzVCLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUtyRCxNQUFNLENBQUMsdUJBQU0sd0JBQXdCLEdBQVE7SUFDM0MsT0FBTyxFQUFFLGlCQUFpQjtJQUMxQixXQUFXLEVBQUUsVUFBVSxDQUFDLEdBQUcsRUFBRSxDQUFDLGtCQUFrQixDQUFDO0lBQ2pELEtBQUssRUFBRSxJQUFJO0NBQ1osQ0FBQztBQVNGLE1BQU07Ozs7O0lBMkJKLFlBQW9CLFFBQXlCLEVBQVUsUUFBbUI7UUFBdEQsYUFBUSxHQUFSLFFBQVEsQ0FBaUI7UUFBVSxhQUFRLEdBQVIsUUFBUSxDQUFXO3VCQWZ2RCxJQUFJO3NCQUtnQixJQUFJLFlBQVksQ0FBTyxLQUFLLENBQUM7Ozs7O3lCQTROeEQsQ0FBQyxDQUFDLEVBQUU7WUFDZCxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ2YsdUJBQU0sTUFBTSxHQUFHLENBQUMsQ0FBQztZQUNqQixFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxLQUFLLE1BQU0sQ0FBQyxDQUFDLENBQUM7Z0JBQ3pCLENBQUMsQ0FBQyxjQUFjLEVBQUUsQ0FBQztnQkFDbkIsQ0FBQyxD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SSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUM7U0FDN0Q7Ozs7O0lBR0gsSUFBSSxTQUFTO1FBQ1gsTUFBTSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUM7S0FDeEI7OztZQXRWRixTQUFTLFNBQUM7Z0JBQ1QsUUFBUSxFQUFFLGVBQWU7Z0JBQ3pCLFFBQVEsRUFBRSxtQ0FBbUM7Z0JBQzdDLFNBQVMsRUFBRSxDQUFDLHdCQUF3QixDQUFDO2dCQUNyQyxhQUFhLEVBQUUsaUJBQWlCLENBQUMsSUFBSTtnQkFDckMsTUFBTSxFQUFFLENBQUMsNnBKQUE2cEosQ0FBQzthQUN4cUo7Ozs7WUFoQ0MsZUFBZTtZQUtmLFNBQVM7Ozt1QkFtQ1IsS0FBSzttQkFDTCxLQUFLOzRCQUNMLEtBQUs7c0NBQ0wsS0FBSztxQ0FDTCxLQUFLO3dCQUNMLEtBQUs7c0JBQ0wsS0FBSzs0QkFDTCxLQUFLOzJCQUNMLEtBQUs7dUJBRUwsTUFBTTsrQkFFTixTQUFTLFNBQUMsZ0JBQWdCO3dCQXNTMUIsS0FBSzswQkFZTCxLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcclxuICBJbnB1dCxcclxuICBPbkluaXQsXHJcbiAgT25DaGFuZ2VzLFxyXG4gIFNpbXBsZUNoYW5nZXMsXHJcbiAgRG9DaGVjayxcclxuICBmb3J3YXJkUmVmLFxyXG4gIENvbXBvbmVudCxcclxuICBWaWV3Q2hpbGQsXHJcbiAgT3V0cHV0LFxyXG4gIEV2ZW50RW1pdHRlcixcclxuICBJdGVyYWJsZURpZmZlcnMsXHJcbiAgSXRlcmFibGVEaWZmZXIsXHJcbiAgSXRlcmFibGVDaGFuZ2VSZWNvcmQsXHJcbiAgSXRlcmFibGVDaGFuZ2VzLFxyXG4gIFZpZXdFbmNhcHN1bGF0aW9uLFxyXG4gIFJlbmRlcmVyMixcclxuICBPbkRlc3Ryb3lcclxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHtcclxuICBOR19WQUxVRV9BQ0NFU1NPUixcclxuICBDb250cm9sVmFsdWVBY2Nlc3NvcixcclxuICBGb3JtQ29udHJvbFxyXG59IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcclxuXHJcbmltcG9ydCAqIGFzIF8gZnJvbSAnbG9kYXNoJztcclxuaW1wb3J0IHsgU2VsZWN0aXplQ29uZmlnIH0gZnJvbSAnLi9zZWxlY3RpemUuY29uZmlnJztcclxuaW1wb3J0IHtJU2VsZWN0aXplSXRlbX0gZnJvbSAnLi9zZWxlY3RpemUtaXRlbS5pbnRlcmZhY2UnO1xyXG5cclxuZGVjbGFyZSB2YXIgJDogYW55O1xyXG5cclxuZXhwb3J0IGNvbnN0IFNFTEVDVElaRV9WQUxVRV9BQ0NFU1NPUjogYW55ID0ge1xyXG4gIHByb3ZpZGU6IE5HX1ZBTFVFX0FDQ0VTU09SLFxyXG4gIHVzZUV4aXN0aW5nOiBmb3J3YXJkUmVmKCgpID0+IFNlbGVjdGl6ZUNvbXBvbmVudCksXHJcbiAgbXVsdGk6IHRydWVcclxufTtcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAnaHhhLXNlbGVjdGl6ZScsXHJcbiAgdGVtcGxhdGU6IGA8c2VsZWN0ICNzZWxlY3RpemVJbnB1dD48L3NlbGVjdD5gLFxyXG4gIHByb3ZpZGVyczogW1NFTEVDVElaRV9WQUxVRV9BQ0NFU1NPUl0sXHJcbiAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcclxuICBzdHlsZXM6IFtgLnNlbGVjdGl6ZS1jb250cm9se3Bvc2l0aW9uOnJlbGF0aXZlfS5zZWxlY3RpemUtZHJvcGRvd24sLnNlbGVjdGl6ZS1pbnB1dCwuc2VsZWN0aXplLWlucHV0IGlucHV0e2NvbG9yOiMyYTJjMmQ7Zm9udC1mYW1pbHk6aW5oZXJpdDtmb250LXNpemU6LjkycmVtO2xpbmUtaGVpZ2h0OjEuNTstd2Via2l0LWZvbnQtc21vb3RoaW5nOmluaGVyaXR9LnNlbGVjdGl6ZS1jb250cm9sLnNpbmdsZSAuc2VsZWN0aXplLWlucHV0LmlucHV0LWFjdGl2ZSwuc2VsZWN0aXplLWlucHV0e2JhY2tncm91bmQ6MCAwO2N1cnNvcjp0ZXh0O2Rpc3BsYXk6aW5saW5lLWJsb2NrfS5zZWxlY3RpemUtaW5wdXR7Ym9yZGVyOjFweCBzb2xpZCByZ2JhKDAsMCwwLC4yKTtwYWRkaW5nOjhweDtkaXNwbGF5OmlubGluZS1ibG9jazt3aWR0aDoxMDAlO292ZXJmbG93OmhpZGRlbjtwb3NpdGlvbjpyZWxhdGl2ZTt6LWluZGV4OjE7Ym94LXNpemluZzpib3JkZXItYm94O2JveC1zaGFkb3c6bm9uZTtib3JkZXItcmFkaXVzOjA7Ym9yZGVyLXdpZHRoOjAgMCAxcHh9LnNlbGVjdGl6ZS1jb250cm9sLm11bHRpIC5zZWxlY3RpemUtaW5wdXQuaGFzLWl0ZW1ze3BhZGRpbmc6NnB4IDhweCAzcHh9LnNlbGVjdGl6ZS1pbnB1dC5mdWxse2JhY2tncm91bmQtY29sb3I6dHJhbnNwYXJlbnR9LnNlbGVjdGl6ZS1pbnB1dC5kaXNhYmxlZCwuc2VsZWN0aXplLWlucHV0LmRpc2FibGVkICp7Y3Vyc29yOmRlZmF1bHQhaW1wb3J0YW50fS5zZWxlY3RpemUtaW5wdXQuZm9jdXN7Ym94LXNoYWRvdzpub25lfS5zZWxlY3RpemUtaW5wdXQuZHJvcGRvd24tYWN0aXZle2JvcmRlci1yYWRpdXM6MH0uc2VsZWN0aXplLWlucHV0Pip7dmVydGljYWwtYWxpZ246YmFzZWxpbmU7ZGlzcGxheTppbmxpbmUtYmxvY2s7em9vbToxfS5zZWxlY3RpemUtY29udHJvbC5tdWx0aSAuc2VsZWN0aXplLWlucHV0PmRpdntjdXJzb3I6cG9pbnRlcjttYXJnaW46NHB4O3BhZGRpbmc6MnB4IDZweDtiYWNrZ3JvdW5kOnJnYmEoMCwwLDAsLjA1KTtjb2xvcjojMmEyYzJkO2JvcmRlcjowIHNvbGlkIHRyYW5zcGFyZW50O2JvcmRlci1yYWRpdXM6MjkwNDg2cHg7Zm9udC1zaXplOi43NXJlbTtqdXN0aWZ5LWNvbnRlbnQ6Y2VudGVyO2xpbmUtaGVpZ2h0OjEuNTt3aGl0ZS1zcGFjZTpub3dyYXB9LnNlbGVjdGl6ZS1jb250cm9sLm11bHRpIC5zZWxlY3RpemUtaW5wdXQ+ZGl2LmFjdGl2ZXtiYWNrZ3JvdW5kOiNlOGU4ZTg7Y29sb3I6IzJhMmMyZDtib3JkZXI6MCBzb2xpZCAjY2FjYWNhfS5zZWxlY3RpemUtY29udHJvbC5tdWx0aSAuc2VsZWN0aXplLWlucHV0LmRpc2FibGVkPmRpdiwuc2VsZWN0aXplLWNvbnRyb2wubXVsdGkgLnNlbGVjdGl6ZS1pbnB1dC5kaXNhYmxlZD5kaXYuYWN0aXZle2NvbG9yOiM3ODc4Nzg7YmFja2dyb3VuZDpyZ2JhKDc3LDc3LDc3LC4wNSk7Ym9yZGVyOjAgc29saWQgcmdiYSg3Nyw3Nyw3NywwKX0uc2VsZWN0aXplLWlucHV0PmlucHV0e2Rpc3BsYXk6aW5saW5lLWJsb2NrIWltcG9ydGFudDtwYWRkaW5nOjAhaW1wb3J0YW50O21pbi1oZWlnaHQ6MCFpbXBvcnRhbnQ7bWF4LWhlaWdodDpub25lIWltcG9ydGFudDttYXgtd2lkdGg6MTAwJSFpbXBvcnRhbnQ7bWFyZ2luOjAgMnB4IDAgMCFpbXBvcnRhbnQ7dGV4dC1pbmRlbnQ6MCFpbXBvcnRhbnQ7Ym9yZGVyOjAhaW1wb3J0YW50O2JhY2tncm91bmQ6MCAwIWltcG9ydGFudDtsaW5lLWhlaWdodDppbmhlcml0IWltcG9ydGFudDstd2Via2l0LXVzZXItc2VsZWN0OmF1dG8haW1wb3J0YW50fS5zZWxlY3RpemUtaW5wdXQ+aW5wdXQ6Oi1tcy1jbGVhcntkaXNwbGF5Om5vbmV9LnNlbGVjdGl6ZS1pbnB1dD5pbnB1dDpmb2N1c3tvdXRsaW5lOjAhaW1wb3J0YW50fS5zZWxlY3RpemUtaW5wdXQ6OmFmdGVye2NvbnRlbnQ6JyAnO2Rpc3BsYXk6YmxvY2s7Y2xlYXI6bGVmdH0uc2VsZWN0aXplLWlucHV0LmRyb3Bkb3duLWFjdGl2ZTo6YmVmb3Jle2NvbnRlbnQ6JyAnO2Rpc3BsYXk6YmxvY2s7cG9zaXRpb246YWJzb2x1dGU7YmFja2dyb3VuZDojZjBmMGYwO2hlaWdodDoxcHg7Ym90dG9tOjA7bGVmdDowO3JpZ2h0OjB9Lmh4LXNlbGVjdC1jb250cm9sOmFmdGVye2Rpc3BsYXk6bm9uZX0uc2VsZWN0aXplLWRyb3Bkb3due3Bvc2l0aW9uOmFic29sdXRlO3otaW5kZXg6MTA7Ym9yZGVyOnRyYW5zcGFyZW50O2JhY2tncm91bmQ6I2ZmZjttYXJnaW46LTFweCAwIDA7Ym9yZGVyLXRvcDowO2JveC1zaXppbmc6Ym9yZGVyLWJveDtib3gtc2hhZG93OjAgNnB4IDEycHggcmdiYSgwLDAsMCwuMTQ1KTtib3JkZXItcmFkaXVzOjB9LnNlbGVjdGl6ZS1kcm9wZG93biBbZGF0YS1zZWxlY3RhYmxlXXtjdXJzb3I6cG9pbnRlcjtvdmVyZmxvdzpoaWRkZW59LnNlbGVjdGl6ZS1kcm9wZG93biBbZGF0YS1zZWxlY3RhYmxlXSAuaGlnaGxpZ2h0e2JhY2tncm91bmQ6cmdiYSgzNSw0OSw0MywuMjMpO2JvcmRlci1yYWRpdXM6MXB4O2ZvbnQtd2VpZ2h0OjcwMH0uc2VsZWN0aXplLWRyb3Bkb3duIC5vcHRncm91cC1oZWFkZXIsLnNlbGVjdGl6ZS1kcm9wZG93biBbZGF0YS1zZWxlY3RhYmxlXXtwYWRkaW5nOjVweCA4cHh9LnNlbGVjdGl6ZS1kcm9wZG93biAub3B0Z3JvdXA6Zmlyc3QtY2hpbGQgLm9wdGdyb3VwLWhlYWRlcntib3JkZXItdG9wOjB9LnNlbGVjdGl6ZS1kcm9wZG93biAub3B0Z3JvdXAtaGVhZGVye2NvbG9yOiMyYTJjMmQ7YmFja2dyb3VuZDojZmZmO2N1cnNvcjpkZWZhdWx0fS5zZWxlY3RpemUtZHJvcGRvd24gLmFjdGl2ZXtiYWNrZ3JvdW5kLWNvbG9yOiM0MWI5ODc7Y29sb3I6I2ZmZn0uc2VsZWN0aXplLWRyb3Bkb3duIC5hY3RpdmUuY3JlYXRle2NvbG9yOiNmZmZ9LnNlbGVjdGl6ZS1kcm9wZG93biAuY3JlYXRle2NvbG9yOnJnYmEoNDIsNDQsNDUsLjUpfS5zZWxlY3RpemUtZHJvcGRvd24tY29udGVudHtvdmVyZmxvdy15OmF1dG87b3ZlcmZsb3cteDpoaWRkZW47bWF4LWhlaWdodDoyMDBweDstd2Via2l0LW92ZXJmbG93LXNjcm9sbGluZzp0b3VjaH0uc2VsZWN0aXplLWNvbnRyb2wuc2luZ2xlIC5zZWxlY3RpemUtaW5wdXQsLnNlbGVjdGl6ZS1jb250cm9sLnNpbmdsZSAuc2VsZWN0aXplLWlucHV0IGlucHV0e2N1cnNvcjpwb2ludGVyfS5zZWxlY3RpemUtY29udHJvbC5zaW5nbGUgLnNlbGVjdGl6ZS1pbnB1dC5pbnB1dC1hY3RpdmUsLnNlbGVjdGl6ZS1jb250cm9sLnNpbmdsZSAuc2VsZWN0aXplLWlucHV0LmlucHV0LWFjdGl2ZSBpbnB1dHtjdXJzb3I6dGV4dH0uc2VsZWN0aXplLWNvbnRyb2wuc2luZ2xlIC5zZWxlY3RpemUtaW5wdXQ6YWZ0ZXJ7Y29udGVudDonICc7ZGlzcGxheTpibG9jaztwb3NpdGlvbjphYnNvbHV0ZTt0b3A6NTAlO3JpZ2h0OjE1cHg7bWFyZ2luLXRvcDotM3B4O3dpZHRoOjA7aGVpZ2h0OjA7Ym9yZGVyLXN0eWxlOnNvbGlkO2JvcmRlci13aWR0aDo1cHggNXB4IDA7Ym9yZGVyLWNvbG9yOmdyZXkgdHJhbnNwYXJlbnQgdHJhbnNwYXJlbnR9LnNlbGVjdGl6ZS1jb250cm9sLnNpbmdsZSAuc2VsZWN0aXplLWlucHV0LmRyb3Bkb3duLWFjdGl2ZTphZnRlcnttYXJnaW4tdG9wOi00cHg7Ym9yZGVyLXdpZHRoOjAgNXB4IDVweDtib3JkZXItY29sb3I6dHJhbnNwYXJlbnQgdHJhbnNwYXJlbnQgZ3JleX0uc2VsZWN0aXplLWNvbnRyb2wucnRsLnNpbmdsZSAuc2VsZWN0aXplLWlucHV0OmFmdGVye2xlZnQ6MTVweDtyaWdodDphdXRvfS5zZWxlY3RpemUtY29udHJvbC5ydGwgLnNlbGVjdGl6ZS1pbnB1dD5pbnB1dHttYXJnaW46MCA0cHggMCAtMnB4IWltcG9ydGFudH0uc2VsZWN0aXplLWNvbnRyb2wgLnNlbGVjdGl6ZS1pbnB1dC5kaXNhYmxlZHtvcGFjaXR5Oi41O2JhY2tncm91bmQtY29sb3I6I2ZhZmFmYX0uc2VsZWN0aXplLWNvbnRyb2wucGx1Z2luLXJlbW92ZV9idXR0b24gW2RhdGEtdmFsdWVde3Bvc2l0aW9uOnJlbGF0aXZlO3BhZGRpbmctcmlnaHQ6LjdyZW0haW1wb3J0YW50fS5zZWxlY3RpemUtY29udHJvbC5wbHVnaW4tcmVtb3ZlX2J1dHRvbiBbZGF0YS12YWx1ZV0uaXMtbWVkaXVte3BhZGRpbmctcmlnaHQ6MXJlbSFpbXBvcnRhbnR9LnNlbGVjdGl6ZS1jb250cm9sLnBsdWdpbi1yZW1vdmVfYnV0dG9uIFtkYXRhLXZhbHVlXSAuaHgtZGVsZXRle21hcmdpbi1sZWZ0Oi0uMnJlbTtoZWlnaHQ6MTZweDt3aWR0aDoxNnB4O21heC1oZWlnaHQ6MTZweDttYXgtd2lkdGg6MTZweDttaW4taGVpZ2h0OjE2cHg7bWluLXdpZHRoOjE2cHh9LnNlbGVjdGl6ZS1jb250cm9sLnBsdWdpbi1yZW1vdmVfYnV0dG9uIFtkYXRhLXZhbHVlXS5pcy1tZWRpdW0gLmh4LWRlbGV0ZXttYXJnaW4tbGVmdDotLjVyZW19LnNlbGVjdGl6ZS1jb250cm9sLnBsdWdpbi1yZW1vdmVfYnV0dG9uIFtkYXRhLXZhbHVlXS5pcy1sYXJnZSAuaHgtZGVsZXRle21hcmdpbi1sZWZ0Oi0uMnJlbTtoZWlnaHQ6MjBweDt3aWR0aDoyMHB4O21heC1oZWlnaHQ6MjBweDttYXgtd2lkdGg6MjBweDttaW4taGVpZ2h0OjIwcHg7bWluLXdpZHRoOjIwcHh9LnNlbGVjdGl6ZS1jb250cm9sLnBsdWdpbi1yZW1vdmVfYnV0dG9uIC5kaXNhYmxlZCBbZGF0YS12YWx1ZV0gLmh4LXJlbW92ZTpob3ZlcntiYWNrZ3JvdW5kOjAgMH0uc2VsZWN0aXplLWNvbnRyb2wucGx1Z2luLXJlbW92ZV9idXR0b24gLmRpc2FibGVkIFtkYXRhLXZhbHVlXSAuaHgtcmVtb3Zle2JvcmRlci1sZWZ0LWNvbG9yOnJnYmEoNzcsNzcsNzcsMCl9LnNlbGVjdGl6ZS1jb250cm9sLnBsdWdpbi1yZW1vdmVfYnV0dG9uIC5yZW1vdmUtc2luZ2xle3Bvc2l0aW9uOmFic29sdXRlO3JpZ2h0OjI4cHg7dG9wOjZweDtmb250LXNpemU6MjNweH1gXVxyXG59KVxyXG5leHBvcnQgY2xhc3MgU2VsZWN0aXplQ29tcG9uZW50XHJcbiAgaW1wbGVtZW50cyBPbkluaXQsIE9uQ2hhbmdlcywgRG9DaGVjaywgQ29udHJvbFZhbHVlQWNjZXNzb3IsIE9uRGVzdHJveSB7XHJcbiAgcHJpdmF0ZSBfb3B0aW9uczogYW55W107XHJcbiAgcHJpdmF0ZSBfb3B0aW9uc19kaWZmZXI6IEl0ZXJhYmxlRGlmZmVyPGFueT47XHJcbiAgcHJpdmF0ZSBfb3B0Z3JvdXBzOiBhbnlbXTtcclxuICBwcml2YXRlIF9vcHRncm91cHNfZGlmZmVyOiBJdGVyYWJsZURpZmZlcjxhbnk+O1xyXG5cclxuICBASW5wdXQoKSBjb25maWc6IFNlbGVjdGl6ZUNvbmZpZztcclxuICBASW5wdXQoKSBpZDogc3RyaW5nO1xyXG4gIEBJbnB1dCgpIHBsYWNlaG9sZGVyOiBzdHJpbmc7XHJcbiAgQElucHV0KCkgaGFzT3B0aW9uc1BsYWNlaG9sZGVyOiBzdHJpbmc7XHJcbiAgQElucHV0KCkgbm9PcHRpb25zUGxhY2Vob2xkZXI6IHN0cmluZztcclxuICBASW5wdXQoKSBlbmFibGVkID0gdHJ1ZTtcclxuICBASW5wdXQoKSB2YWx1ZTogSVNlbGVjdGl6ZUl0ZW1bXTtcclxuICBASW5wdXQoKSBmb3JtQ29udHJvbDogRm9ybUNvbnRyb2w7XHJcbiAgQElucHV0KCkgZXJyb3JDbGFzczogc3RyaW5nO1xyXG5cclxuICBAT3V0cHV0KCkgb25CbHVyOiBFdmVudEVtaXR0ZXI8dm9pZD4gPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KGZhbHNlKTtcclxuXHJcbiAgQFZpZXdDaGlsZCgnc2VsZWN0aXplSW5wdXQnKSBzZWxlY3RpemVJbnB1dDogYW55O1xyXG5cclxuICBwcml2YXRlIHNlbGVjdGl6ZTogYW55O1xyXG5cclxuICAvLyBDb250cm9sIHZhbHVlIGFjY2Vzc29ycy5cclxuICBwcml2YXRlIG9uVG91Y2hlZENhbGxiYWNrOiAoKSA9PiB7fTtcclxuICBwcml2YXRlIG9uQ2hhbmdlQ2FsbGJhY2s6IChfOiBhbnkpID0+IHt9O1xyXG5cclxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIF9kaWZmZXJzOiBJdGVyYWJsZURpZmZlcnMsIHByaXZhdGUgcmVuZGVyZXI6IFJlbmRlcmVyMikge31cclxuXHJcbiAgbmdPbkluaXQoKTogdm9pZCB7XHJcbiAgICBpZiAodGhpcy5pZCAmJiB0aGlzLmlkLmxlbmd0aCA+IDApIHtcclxuICAgICAgdGhpcy5yZW5kZXJlci5zZXRBdHRyaWJ1dGUoXHJcbiAgICAgICAgdGhpcy5zZWxlY3RpemVJbnB1dC5uYXRpdmVFbGVtZW50LFxyXG4gICAgICAgICdpZCcsXHJcbiAgICAgICAgdGhpcy5pZFxyXG4gICAgICApO1xyXG4gICAgfVxyXG4gICAgdGhpcy5yZXNldCgpO1xyXG4gIH1cclxuXHJcbiAgcmVzZXQoKSB7XHJcbiAgICB0aGlzLnNlbGVjdGl6ZSA9ICQodGhpcy5zZWxlY3RpemVJbnB1dC5uYXRpdmVFbGVtZW50KS5zZWxlY3RpemUoXHJcbiAgICAgIHRoaXMuY29uZmlnXHJcbiAgICApWzBdLnNlbGVjdGl6ZTtcclxuICAgIHRoaXMuc2VsZWN0aXplLm9uKCdjaGFuZ2UnLCB0aGlzLm9uU2VsZWN0aXplVmFsdWVDaGFuZ2UuYmluZCh0aGlzKSk7XHJcbiAgICB0aGlzLnNlbGVjdGl6ZS5vbignYmx1cicsIHRoaXMub25CbHVyRXZlbnQuYmluZCh0aGlzKSk7XHJcbiAgICB0aGlzLnNlbGVjdGl6ZS5vbigndHlwZScsIHRoaXMub25TZWxlY3RpemVUeXBlLmJpbmQodGhpcykpO1xyXG4gICAgdGhpcy5zZWxlY3RpemUub24oJ2l0ZW1fYWRkJywgdGhpcy5vblNlbGVjdGl6ZUl0ZW1TZWxlY3RlZC5iaW5kKHRoaXMpKTtcclxuICAgIHRoaXMudXBkYXRlUGxhY2Vob2xkZXIoKTtcclxuICAgIHRoaXMub25FbmFibGVkU3RhdHVzQ2hhbmdlKCk7XHJcbiAgfVxyXG5cclxuICBuZ09uRGVzdHJveSgpIHtcclxuICAgIHRoaXMuc2VsZWN0aXplLm9mZignY2hhbmdlJyk7XHJcbiAgICB0aGlzLnNlbGVjdGl6ZS5vZmYoJ2JsdXInKTtcclxuICAgIHRoaXMuc2VsZWN0aXplLm9mZigndHlwZScpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQ2hhbmdlIGRldGVjdGlvbiBmb3IgcHJpbWl0aXZlIHR5cGVzLlxyXG4gICAqL1xyXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcclxuICAgIGlmICh0aGlzLnNlbGVjdGl6ZSkge1xyXG4gICAgICBpZiAoXHJcbiAgICAgICAgY2hhbmdlcy5oYXNPd25Qcm9wZXJ0eSgncGxhY2Vob2xkZXInKSB8fFxyXG4gICAgICAgIGNoYW5nZXMuaGFzT3duUHJvcGVydHkoJ2hhc09wdGlvbnNQbGFjZWhvbGRlcicpIHx8XHJcbiAgICAgICAgY2hhbmdlcy5oYXNPd25Qcm9wZXJ0eSgnbm9PcHRpb25zUGxhY2Vob2xkZXInKVxyXG4gICAgICApIHtcclxuICAgICAgICB0aGlzLnVwZGF0ZVBsYWNlaG9sZGVyKCk7XHJcbiAgICAgIH1cclxuICAgICAgaWYgKGNoYW5nZXMuaGFzT3duUHJvcGVydHkoJ2VuYWJsZWQnKSkge1xyXG4gICAgICAgIHRoaXMub25FbmFibGVkU3RhdHVzQ2hhbmdlKCk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEltcGxlbWVudGluZyBkZWVwIGNoZWNrIGZvciBvcHRpb24gY29tcGFyaXNvblxyXG4gICAqXHJcbiAgICogRklYTUUgLT4gSW1wbGVtZW50IGRlZXAgY2hlY2sgdG8gb25seSBjb21wYXJlIGFnYWluc3QgbGFiZWwgYW5kIHZhbHVlIGZpZWxkcy5cclxuICAgKi9cclxuICBuZ0RvQ2hlY2soKTogdm9pZCB7XHJcbiAgICBpZiAodGhpcy5fb3B0aW9uc19kaWZmZXIpIHtcclxuICAgICAgY29uc3QgY2hhbmdlcyA9IHRoaXMuX29wdGlvbnNfZGlmZmVyLmRpZmYodGhpcy5fb3B0aW9ucyk7XHJcbiAgICAgIGlmIChjaGFuZ2VzKSB7XHJcbiAgICAgICAgdGhpcy5fYXBwbHlPcHRpb25zQ2hhbmdlcyhjaGFuZ2VzKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgaWYgKHRoaXMuX29wdGdyb3Vwc19kaWZmZXIpIHtcclxuICAgICAgY29uc3QgY2hhbmdlcyA9IHRoaXMuX29wdGdyb3Vwc19kaWZmZXIuZGlmZih0aGlzLl9vcHRncm91cHMpO1xyXG4gICAgICBpZiAoY2hhbmdlcykge1xyXG4gICAgICAgIHRoaXMuX2FwcGx5T3B0aW9uR3JvdXBDaGFuZ2VzKGNoYW5nZXMpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIF9hcHBseU9wdGlvbnNDaGFuZ2VzKGNoYW5nZXM6IEl0ZXJhYmxlQ2hhbmdlczxhbnk+KTogdm9pZCB7XHJcbiAgICBjaGFuZ2VzLmZvckVhY2hBZGRlZEl0ZW0oKHJlY29yZDogSXRlcmFibGVDaGFuZ2VSZWNvcmQ8YW55PikgPT4ge1xyXG4gICAgICB0aGlzLm9uU2VsZWN0aXplT3B0aW9uQWRkKHJlY29yZC5pdGVtKTtcclxuICAgIH0pO1xyXG4gICAgY2hhbmdlcy5mb3JFYWNoUmVtb3ZlZEl0ZW0oKHJlY29yZDogSXRlcmFibGVDaGFuZ2VSZWNvcmQ8YW55PikgPT4ge1xyXG4gICAgICB0aGlzLm9uU2VsZWN0aXplT3B0aW9uUmVtb3ZlKHJlY29yZC5pdGVtKTtcclxuICAgIH0pO1xyXG4gICAgdGhpcy51cGRhdGVQbGFjZWhvbGRlcigpO1xyXG4gICAgdGhpcy5ldmFsSGFzRXJyb3IoKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgX2FwcGx5T3B0aW9uR3JvdXBDaGFuZ2VzKGNoYW5nZXM6IGFueSk6IHZvaWQge1xyXG4gICAgY2hhbmdlcy5mb3JFYWNoQWRkZWRJdGVtKChyZWNvcmQ6IEl0ZXJhYmxlQ2hhbmdlUmVjb3JkPGFueT4pID0+IHtcclxuICAgICAgdGhpcy5vblNlbGVjdGl6ZU9wdEdyb3VwQWRkKHJlY29yZC5pdGVtKTtcclxuICAgIH0pO1xyXG4gICAgY2hhbmdlcy5mb3JFYWNoUmVtb3ZlZEl0ZW0oKHJlY29yZDogSXRlcmFibGVDaGFuZ2VSZWNvcmQ8YW55PikgPT4ge1xyXG4gICAgICB0aGlzLm9uU2VsZWN0aXplT3B0R3JvdXBSZW1vdmUocmVjb3JkLml0ZW0pO1xyXG4gICAgfSk7XHJcbiAgICB0aGlzLnVwZGF0ZVBsYWNlaG9sZGVyKCk7XHJcbiAgICB0aGlzLmV2YWxIYXNFcnJvcigpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBjbGVhcmhpZ2hsaWdodCgpOiB2b2lkIHtcclxuICAgIC8vIHJlbW92ZSBoaWdobGlnaHQgdG8gaGVscCBzZWxlY3RpemUgYnVnXHJcbiAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vc2VsZWN0aXplL3NlbGVjdGl6ZS5qcy9pc3N1ZXMvMTE0MVxyXG4gICAgdGhpcy5zZWxlY3RpemUuJGRyb3Bkb3duX2NvbnRlbnQucmVtb3ZlSGlnaGxpZ2h0KCk7XHJcbiAgfVxyXG5cclxuICBvbkJsdXJFdmVudCgpIHtcclxuICAgIGlmICh0aGlzLmZvcm1Db250cm9sKSB7XHJcbiAgICAgIHRoaXMuZm9ybUNvbnRyb2wubWFya0FzVG91Y2hlZCgpO1xyXG4gICAgfVxyXG4gICAgdGhpcy5vbkJsdXIuZW1pdCgpO1xyXG4gICAgdGhpcy5ldmFsSGFzRXJyb3IoKTtcclxuICB9XHJcblxyXG4gIG9uU2VsZWN0aXplT3B0R3JvdXBBZGQob3B0Z3JvdXA6IGFueSk6IHZvaWQge1xyXG4gICAgdGhpcy5zZWxlY3RpemUuYWRkT3B0aW9uR3JvdXAob3B0Z3JvdXBbdGhpcy5nZXRPcHRncm91cEZpZWxkKCldLCBvcHRncm91cCk7XHJcbiAgfVxyXG5cclxuICBvblNlbGVjdGl6ZU9wdEdyb3VwUmVtb3ZlKG9wdGdyb3VwOiBhbnkpOiB2b2lkIHtcclxuICAgIHRoaXMuc2VsZWN0aXplLnJlbW92ZU9wdGlvbkdyb3VwKG9wdGdyb3VwW3RoaXMuZ2V0T3B0Z3JvdXBGaWVsZCgpXSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBSZWZyZXNoIHNlbGVjdGVkIHZhbHVlcyB3aGVuIG9wdGlvbnMgY2hhbmdlLlxyXG4gICAqL1xyXG4gIG9uU2VsZWN0aXplT3B0aW9uQWRkKG9wdGlvbjogYW55KTogdm9pZCB7XHJcbiAgICB0aGlzLnNlbGVjdGl6ZS5hZGRPcHRpb24oXy5jbG9uZURlZXAob3B0aW9uKSk7XHJcbiAgICBjb25zdCB2YWx1ZUZpZWxkID0gdGhpcy5jb25maWcudmFsdWVGaWVsZDtcclxuICAgIGlmICh0aGlzLnZhbHVlKSB7XHJcbiAgICAgIGNvbnN0IGl0ZW1zID1cclxuICAgICAgICB0eXBlb2YgdGhpcy52YWx1ZSA9PT0gJ3N0cmluZycgfHwgdHlwZW9mIHRoaXMudmFsdWUgPT09ICdudW1iZXInXHJcbiAgICAgICAgICA/IFt0aGlzLnZhbHVlXVxyXG4gICAgICAgICAgOiB0aGlzLnZhbHVlO1xyXG4gICAgICBpZiAoXHJcbiAgICAgICAgaXRlbXMgJiZcclxuICAgICAgICBpdGVtcyBpbnN0YW5jZW9mIEFycmF5ICYmXHJcbiAgICAgICAgaXRlbXMuZmluZCh2YWx1ZSA9PiB2YWx1ZSA9PT0gb3B0aW9uW3ZhbHVlRmllbGRdKVxyXG4gICAgICApIHtcclxuICAgICAgICB0aGlzLnNlbGVjdGl6ZS5hZGRJdGVtKG9wdGlvblt2YWx1ZUZpZWxkXSwgdHJ1ZSk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcblxyXG4gIG9uU2VsZWN0aXplT3B0aW9uUmVtb3ZlKG9wdGlvbjogYW55KTogdm9pZCB7XHJcbiAgICB0aGlzLnNlbGVjdGl6ZS5yZW1vdmVPcHRpb24ob3B0aW9uW3RoaXMuY29uZmlnLnZhbHVlRmllbGRdKTtcclxuICB9XHJcblxyXG4gIGV2YWxIYXNFcnJvcigpIHtcclxuICAgIGNvbnN0IHBhcmVudCA9ICQodGhpcy5zZWxlY3RpemUuJGNvbnRyb2wpLnBhcmVudCgpO1xyXG4gICAgaWYgKHRoaXMuZm9ybUNvbnRyb2wpIHtcclxuICAgICAgaWYgKHRoaXMuZm9ybUNvbnRyb2wudG91Y2hlZCAmJiB0aGlzLmZvcm1Db250cm9sLmludmFsaWQpIHtcclxuICAgICAgICBwYXJlbnQuYWRkQ2xhc3ModGhpcy5lcnJvckNsYXNzIHx8ICdoYXMtZXJyb3InKTtcclxuICAgICAgfSBlbHNlIGlmIChwYXJlbnQuaGFzQ2xhc3MoJ2hhcy1lcnJvcicpKSB7XHJcbiAgICAgICAgcGFyZW50LnJlbW92ZUNsYXNzKHRoaXMuZXJyb3JDbGFzcyB8fCAnaGFzLWVycm9yJyk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFVwZGF0ZSB0aGUgY3VycmVudCBwbGFjZWhvbGRlciBiYXNlZCBvbiB0aGUgZ2l2ZW4gaW5wdXQgcGFyYW1ldGVyLlxyXG4gICAqL1xyXG4gIHVwZGF0ZVBsYWNlaG9sZGVyKCk6IHZvaWQge1xyXG4gICAgaWYgKFxyXG4gICAgICB0aGlzLnNlbGVjdGl6ZS5pdGVtcy5sZW5ndGggPT09IDAgJiZcclxuICAgICAgdGhpcy5zZWxlY3RpemUuc2V0dGluZ3MucGxhY2Vob2xkZXIgIT09IHRoaXMuZ2V0UGxhY2Vob2xkZXIoKVxyXG4gICAgKSB7XHJcbiAgICAgIHRoaXMuc2VsZWN0aXplLnNldHRpbmdzLnBsYWNlaG9sZGVyID0gdGhpcy5nZXRQbGFjZWhvbGRlcigpO1xyXG4gICAgICB0aGlzLnNlbGVjdGl6ZS51cGRhdGVQbGFjZWhvbGRlcigpO1xyXG4gICAgICB0aGlzLnNlbGVjdGl6ZS5zaG93SW5wdXQoKTsgLy8gV2l0aG91dCB0aGlzLCB3aGVuIG9wdGlvbnMgYXJlIGNsZWFyZWQgcGxhY2Vob2xkZXIgb25seSBhcHBlYXJzIGFmdGVyIGZvY3VzLlxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQ2FsbGVkIHdoZW4gYSBjaGFuZ2UgaXMgZGV0ZWN0ZWQgaW4gdGhlICdlbmFibGVkJyBpbnB1dCBmaWVsZC5cclxuICAgKiBTZXRzIHRoZSBzZWxlY3RpemUgc3RhdGUgYmFzZWQgb24gdGhlIG5ldyB2YWx1ZS5cclxuICAgKi9cclxuICBvbkVuYWJsZWRTdGF0dXNDaGFuZ2UoKTogdm9pZCB7XHJcbiAgICB0aGlzLmVuYWJsZWQgPyB0aGlzLnNlbGVjdGl6ZS5lbmFibGUoKSA6IHRoaXMuc2VsZWN0aXplLmRpc2FibGUoKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIERpc3BhdGNoZXMgY2hhbmdlIGV2ZW50IHdoZW4gYSB2YWx1ZSBjaGFuZ2UgaXMgZGV0ZWN0ZWQuXHJcbiAgICogQHBhcmFtICRldmVudFxyXG4gICAqL1xyXG4gIG9uU2VsZWN0aXplVmFsdWVDaGFuZ2UoJGV2ZW50OiBhbnkpOiB2b2lkIHtcclxuICAgIC8vIEluIHNvbWUgY2FzZXMgdGhpcyBnZXRzIGNhbGxlZCBiZWZvcmUgcmVnaXN0ZXJPbkNoYW5nZS5cclxuICAgIGlmICh0aGlzLm9uQ2hhbmdlQ2FsbGJhY2spIHtcclxuICAgICAgLy8gTWFwIHNlbGVjdGl6ZSdzIHZhbHVlIGNvbGxlY3Rpb24gYmFjayB0byBvcmlnaW5hbCBJU2VsZWN0aXplSXRlbSBvYmplY3RcclxuICAgICAgY29uc3QgZGF0YSA9IHRoaXMuc2VsZWN0aXplLml0ZW1zLm1hcCh2ID0+IHtcclxuICAgICAgICByZXR1cm4gdGhpcy5zZWxlY3RpemUub3B0aW9uc1t2XTtcclxuICAgICAgfSk7XHJcblxyXG4gICAgICB0aGlzLm9uQ2hhbmdlQ2FsbGJhY2soZGF0YSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBJbnZva2VkIHdoZW4gdGhlIHVzZXIgdHlwZXMgd2hpbGUgZmlsdGVyaW5nIG9wdGlvbnMuXHJcbiAgICogQHBhcmFtIHN0clxyXG4gICAqL1xyXG4gIG9uU2VsZWN0aXplVHlwZShzdHI6IHN0cmluZyk6IHZvaWQge1xyXG4gICAgaWYgKHN0ci5sZW5ndGggPT09IDApIHtcclxuICAgICAgdGhpcy5jbGVhcmhpZ2hsaWdodCgpO1xyXG4gICAgICB0aGlzLnNlbGVjdGl6ZS5jbG9zZSgpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgb25TZWxlY3RpemVJdGVtU2VsZWN0ZWQoJGV2ZW50OiBhbnkpOiB2b2lkIHtcclxuICAgIHRoaXMuY2xlYXJoaWdobGlnaHQoKTtcclxuXHJcbiAgICBpZiAodGhpcy5jb25maWcuY2xvc2VBZnRlclNlbGVjdCkge1xyXG4gICAgICB0aGlzLnNlbGVjdGl6ZS5jbG9zZSgpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogSW52b2tlZCBhbnl0aW1lIGEga2V5IGlzIHByZXNzZWQgZG93biBvbiB0aGUgc2VsZWN0aXplIHNlYXJjaCBmaWVsZFxyXG4gICAqIEBwYXJhbSBlXHJcbiAgICovXHJcbiAgb25LZXlkb3duID0gZSA9PiB7XHJcbiAgICBjb25zb2xlLmxvZyhlKTtcclxuICAgIGNvbnN0IFRBQktFWSA9IDk7XHJcbiAgICBpZiAoZS5rZXlDb2RlID09PSBUQUJLRVkpIHtcclxuICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICBlLnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpO1xyXG4gICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogUmV0dXJucyB0aGUgYXBwbGljYWJsZSBwbGFjZWhvbGRlci5cclxuICAgKi9cclxuICBnZXRQbGFjZWhvbGRlcigpOiBzdHJpbmcge1xyXG4gICAgaWYgKHRoaXMuaGFzT3B0aW9uc1BsYWNlaG9sZGVyKSB7XHJcbiAgICAgIGlmICh0aGlzLm9wdGlvbnMgJiYgdGhpcy5vcHRpb25zLmxlbmd0aCA+IDApIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5oYXNPcHRpb25zUGxhY2Vob2xkZXI7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIGlmICh0aGlzLm5vT3B0aW9uc1BsYWNlaG9sZGVyKSB7XHJcbiAgICAgIGlmICghdGhpcy5vcHRpb25zIHx8IHRoaXMub3B0aW9ucy5sZW5ndGggPT09IDApIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5ub09wdGlvbnNQbGFjZWhvbGRlcjtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRoaXMucGxhY2Vob2xkZXI7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBJbXBsZW1lbnRhdGlvbiBmcm9tIENvbnRyb2xWYWx1ZUFjY2Vzc29yXHJcbiAgICpcclxuICAgKiBAcGFyYW0gb2JqXHJcbiAgICovXHJcbiAgd3JpdGVWYWx1ZShvYmo6IElTZWxlY3RpemVJdGVtW10pOiB2b2lkIHtcclxuICAgIGlmIChvYmogPT09IHRoaXMudmFsdWUpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMudmFsdWUgPSBvYmo7XHJcblxyXG4gICAgaWYgKCFvYmogfHwgb2JqLmxlbmd0aCA9PT0gMCkge1xyXG4gICAgICB0aGlzLnNlbGVjdGl6ZS5zZXRWYWx1ZSgnJyk7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCBzdHJpbmdWYWx1ZSA9IG9iai5tYXAodiA9PiB7XHJcbiAgICAgIGlmICghT2JqZWN0LmtleXModGhpcy5zZWxlY3RpemUub3B0aW9ucykuc29tZSh4ID0+IHggPT09IHYudmFsdWUpKSB7XHJcbiAgICAgICAgdGhpcy5zZWxlY3RpemUuYWRkT3B0aW9uKHYpO1xyXG4gICAgICB9XHJcbiAgICAgIHJldHVybiB2LnZhbHVlO1xyXG4gICAgfSk7XHJcblxyXG4gICAgdGhpcy5zZWxlY3RpemUuc2V0VmFsdWUoc3RyaW5nVmFsdWUpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogSW1wbGVtZW50YXRpb24gZnJvbSBDb250cm9sVmFsdWVBY2Nlc3NvciwgY2FsbGJhY2sgZm9yIChuZ01vZGVsQ2hhbmdlKVxyXG4gICAqIEBwYXJhbSBmblxyXG4gICAqL1xyXG4gIHJlZ2lzdGVyT25DaGFuZ2UoZm46IGFueSk6IHZvaWQge1xyXG4gICAgdGhpcy5vbkNoYW5nZUNhbGxiYWNrID0gZm47XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBJbXBsZW1lbnRhdGlvbiBmcm9