com.phloxui
Version:
PhloxUI Ng2+ Framework
628 lines (627 loc) • 47 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
import * as tslib_1 from "tslib";
import { Component, ElementRef, Input, Output, EventEmitter } from '@angular/core';
import { TextBox } from '../../../../../component/dataview/input/TextBox.component';
import { I18N } from '../../../../../decorator/I18N.decorator';
import { Option } from '../../../../../decorator/Option.decorator';
import { NeedFocusService } from '../../../../../service/NeedFocusService.service';
import { FormatterFactory } from '../../../../../service/FormatterFactory.service';
const /** @type {?} */ TYPE_NAME = "material-text-box";
const /** @type {?} */ NORMAL = 'normal';
const /** @type {?} */ SUCCESS = 'success';
const /** @type {?} */ WARNING = 'warning';
const /** @type {?} */ ERROR = 'error';
const /** @type {?} */ DEFAULT_BUTTON_ICON = 'close';
const /** @type {?} */ DEFAULT_BUTTON_POSITION = 'suffix';
export class MaterialTextBox extends TextBox {
/**
* @param {?} elementRef
* @param {?} formatterFactory
* @param {?} needFocusService
*/
constructor(elementRef, formatterFactory, needFocusService) {
super(elementRef, formatterFactory, needFocusService);
this.active = false;
this.clearFunc = () => { this.formattedData = ''; };
}
/**
* @return {?}
*/
ngOnInit() {
super.ngOnInit();
this.refreshActiveTextBox();
}
/**
* @return {?}
*/
_displayHelp() {
let /** @type {?} */ hasHelp = this.hasHelp();
return hasHelp && this.isShowHelp();
}
/**
* @return {?}
*/
refreshActiveTextBox() {
let /** @type {?} */ val = this.getFormattedData();
if (val !== null && typeof val !== 'undefined') {
if (typeof val === 'string' && val === '') {
this.active = false;
}
else {
this.active = true;
}
}
else {
this.active = false;
}
}
/**
* @param {?} inputValue
* @param {?} results
* @return {?}
*/
onValidationEnd(inputValue, results) {
}
/**
* @param {?} data
* @param {?} inputVal
* @return {?}
*/
onDataChange(data, inputVal) {
super.onDataChange(data, inputVal);
this.refreshActiveTextBox();
}
/**
* @param {?} $event
* @return {?}
*/
doFocus($event) {
super.doFocus($event);
this.active = true;
this.classFocused = true;
}
/**
* @param {?} $event
* @return {?}
*/
doLostFocus($event) {
super.doLostFocus($event);
this.refreshActiveTextBox();
this.classFocused = false;
}
/**
* @return {?}
*/
getClassMatFocused() {
return this.isReadOnly() ? { 'mat-focused': this._isClassFocused() } : {};
}
/**
* @return {?}
*/
_isActive() {
return this.active;
}
/**
* @return {?}
*/
_isClassFocused() {
return this.classFocused;
}
/**
* @param {?} $event
* @return {?}
*/
onValueChanged($event) {
super.onValueChanged($event);
this.refreshActiveTextBox();
}
/**
* @param {?} data
* @return {?}
*/
selfSaveData(data) {
super.selfSaveData(data);
this.refreshActiveTextBox();
}
/**
* @return {?}
*/
getDescription() {
return this.description;
}
/**
* @param {?} description
* @return {?}
*/
setDescription(description) {
this.description = description;
}
/**
* @return {?}
*/
getLabel() {
return this.label;
}
/**
* @param {?} label
* @return {?}
*/
setLabel(label) {
this.label = label;
}
/**
* @return {?}
*/
resetValidationResult() {
super.resetValidationResult();
this.active = false;
}
/**
* @param {?} $event
* @return {?}
*/
onBtnClick($event) {
if (!this.isReadOnly() && !this.isDisabled()) {
this.setButtonHandler(this.showClearButton ? this.clearFunc : this.buttonHandler);
if (this.buttonHandler !== null && this.buttonHandler !== undefined) {
this.buttonHandler(this, $event);
}
}
}
/**
* @return {?}
*/
isShowClearButton() {
return this.showClearButton;
}
/**
* @param {?} showClearButton
* @return {?}
*/
setShowClearButton(showClearButton) {
this.showClearButton = showClearButton;
}
/**
* @return {?}
*/
getButtonIcon() {
return this.showClearButton ? DEFAULT_BUTTON_ICON : this.buttonIcon;
}
/**
* @param {?} buttonIcon
* @return {?}
*/
setButtonIcon(buttonIcon) {
this.buttonIcon = buttonIcon;
}
/**
* @return {?}
*/
getButtonPosition() {
return this.showClearButton ? DEFAULT_BUTTON_POSITION : (!this.buttonPosition ? DEFAULT_BUTTON_POSITION : this.buttonPosition);
}
/**
* @param {?} buttonPosition
* @return {?}
*/
setButtonPosition(buttonPosition) {
this.buttonPosition = buttonPosition;
}
/**
* @return {?}
*/
getButtonHandler() {
return this.showClearButton ? this.clearFunc : (!this.buttonHandler ? this.clearFunc : this.buttonHandler);
}
/**
* @param {?} buttonHandler
* @return {?}
*/
setButtonHandler(buttonHandler) {
this.buttonHandler = buttonHandler;
}
/**
* @param {?} $event
* @return {?}
*/
onKeyUp($event) {
if (this.isReadOnly() || this.isDisabled()) {
return;
}
super.onKeyUp($event);
}
/**
* @param {?} $event
* @return {?}
*/
onKeyDown($event) {
if (this.isReadOnly() || this.isDisabled()) {
return;
}
super.onKeyDown($event);
}
}
MaterialTextBox.TYPE_NAME = TYPE_NAME;
MaterialTextBox.decorators = [
{ type: Component, args: [{
moduleId: module.id,
selector: TYPE_NAME,
template: `<div class="material-input material-text-box" [style.width]="getWidth()">
<div class="textbox-wrapper" [class.active]="_isActive()">
<mat-form-field [ngClass]="getClassMatFocused()">
<input matInput placeholder="{{getLabel() | phx_text}}" [attr.maxlength]="getMaxLength()" type="{{getType()}}" class="form-control" [disabled]="isDisabled()" [readonly]="isReadOnly()" [class.dirty]="isDataDirty()" (change)="onValueChanged($event)" (focusin)="onFocusing($event)" (blur)="onLostFocusing($event)" (keyup)="onKeyUp($event)"
(keydown)="onKeyDown($event)" [value]="formattedData | phx_text" [class.normal]="isNormal() && !isDisabled()" [class.success]="isSuccess() && !isDisabled()" [class.warning]="isWarning() && !isDisabled()" [class.error]="isError() && !isDisabled()">
<button mat-button *ngIf="(getButtonIcon() || isShowClearButton()) && (formattedData && getButtonPosition() === 'suffix' && !(isDisabled() || isReadOnly()))" matSuffix mat-icon-button (click)="onBtnClick($event)">
<mat-icon>{{getButtonIcon()}}</mat-icon>
</button>
<button mat-button *ngIf="(getButtonIcon() || isShowClearButton()) && (formattedData && getButtonPosition() === 'prefix' && !(isDisabled() || isReadOnly()))" matPrefix mat-icon-button (click)="onBtnClick($event)">
<mat-icon>{{getButtonIcon()}}</mat-icon>
</button>
<button mat-button *ngIf="(getButtonIcon() || isShowClearButton()) && (formattedData && getButtonPosition() === 'suffix' && (isDisabled() || isReadOnly()))" disabled matSuffix mat-icon-button (click)="onBtnClick($event)">
<mat-icon>{{getButtonIcon()}}</mat-icon>
</button>
<button mat-button *ngIf="(getButtonIcon() || isShowClearButton()) && (formattedData && getButtonPosition() === 'prefix' && (isDisabled() || isReadOnly()))" disabled matPrefix mat-icon-button (click)="onBtnClick($event)">
<mat-icon>{{getButtonIcon()}}</mat-icon>
</button>
</mat-form-field>
</div>
<div class="validation" [style.display]="getValidationResultMessage() ? undefined : 'none'" [class.normal]="isNormal() && !isDisabled()" [class.success]="isSuccess() && !isDisabled()" [class.warning]="isWarning() && !isDisabled()" [class.error]="isError() && !isDisabled()">
<ng-template [ngIf]="getValidationResultMessage()" [ngIfElse]="validation_else">
{{getValidationResultMessage() | phx_text}}
</ng-template>
<ng-template #validation_else>
<!-- We've to put whitespace if there is no validation msg to prevent empty dom -->
<!-- since if validate msg's <div> dom is empty, the component positioning -->
<!-- will be misplaced. -->
{{ ' ' }}
</ng-template>
</div>
<div class="description" [style.display]="getValidationResultMessage() ? 'none' : undefined" [class.normal]="isNormal() && !isDisabled()" [class.success]="isSuccess() && !isDisabled()" [class.warning]="isWarning() && !isDisabled()" [class.error]="isError() && !isDisabled()">
<ng-template [ngIf]="getDescription()" [ngIfElse]="description_else">
{{ getDescription() | phx_text }}
</ng-template>
<ng-template #description_else>
<!-- We've to put whitespace if there is no description to prevent empty dom -->
<!-- since if description's <div> dom is empty, the component positioning -->
<!-- will be misplaced. -->
{{ ' ' }}
</ng-template>
</div>
<div class="help">
{{getHelp() | phx_text}}
</div>
</div>
`
},] },
];
/** @nocollapse */
MaterialTextBox.ctorParameters = () => [
{ type: ElementRef, },
{ type: FormatterFactory, },
{ type: NeedFocusService, },
];
MaterialTextBox.propDecorators = {
"dataParent": [{ type: Input },],
"ignoreParentData": [{ type: Input },],
"data": [{ type: Input },],
"ignoreParentDisabled": [{ type: Input },],
"delegateHistory": [{ type: Input },],
"onDisabled": [{ type: Input },],
"onEnabled": [{ type: Input },],
"loadingEnabled": [{ type: Input },],
"i18nKey": [{ type: Input },],
"bypass": [{ type: Input, args: ['i18nBypass',] },],
"options": [{ type: Input },],
"disabled": [{ type: Input },],
"field": [{ type: Input },],
"name": [{ type: Input },],
"typeOfData": [{ type: Input },],
"readOnly": [{ type: Input },],
"help": [{ type: Input },],
"formatter": [{ type: Input, args: ['formatter',] },],
"formatterName": [{ type: Input, args: ['formatterName',] },],
"formatterOptions": [{ type: Input, args: ['formatterOptions',] },],
"formatterUsePropertyValue": [{ type: Input, args: ['formatterUsePropertyValue',] },],
"type": [{ type: Input },],
"width": [{ type: Input },],
"label": [{ type: Input },],
"description": [{ type: Input },],
"maxLength": [{ type: Input, args: ['phxMaxLength',] },],
"buttonIcon": [{ type: Input },],
"buttonPosition": [{ type: Input },],
"buttonHandler": [{ type: Input },],
"showClearButton": [{ type: Input },],
"loadEvent": [{ type: Output, args: ['phxLoad',] },],
"startValidateEvent": [{ type: Output, args: ['phxStartValidate',] },],
"endValidateEvent": [{ type: Output, args: ['phxEndValidate',] },],
"beforeFocusEvent": [{ type: Output, args: ['phxBeforeFocus',] },],
"focusEvent": [{ type: Output, args: ['phxFocus',] },],
"beforeLostFocusEvent": [{ type: Output, args: ['phxBeforeLostFocus',] },],
"lostFocusEvent": [{ type: Output, args: ['phxLostFocus',] },],
"beforeChangeEvent": [{ type: Output, args: ['phxBeforeChange',] },],
"changeEvent": [{ type: Output, args: ['phxChange',] },],
"beforeKeyUpEvent": [{ type: Output, args: ['phxBeforeKeyUp',] },],
"keyUpEvent": [{ type: Output, args: ['phxKeyUp',] },],
"beforeKeyDownEvent": [{ type: Output, args: ['phxBeforeKeyDown',] },],
"keyDownEvent": [{ type: Output, args: ['phxKeyDown',] },],
};
tslib_1.__decorate([
Option(),
tslib_1.__metadata("design:type", Object)
], MaterialTextBox.prototype, "dataParent", void 0);
tslib_1.__decorate([
Option(),
tslib_1.__metadata("design:type", Boolean)
], MaterialTextBox.prototype, "ignoreParentData", void 0);
tslib_1.__decorate([
Option(),
tslib_1.__metadata("design:type", Object)
], MaterialTextBox.prototype, "data", void 0);
tslib_1.__decorate([
Option(),
tslib_1.__metadata("design:type", Boolean)
], MaterialTextBox.prototype, "ignoreParentDisabled", void 0);
tslib_1.__decorate([
Option(),
tslib_1.__metadata("design:type", Boolean)
], MaterialTextBox.prototype, "delegateHistory", void 0);
tslib_1.__decorate([
Option(),
tslib_1.__metadata("design:type", Function)
], MaterialTextBox.prototype, "onDisabled", void 0);
tslib_1.__decorate([
Option(),
tslib_1.__metadata("design:type", Function)
], MaterialTextBox.prototype, "onEnabled", void 0);
tslib_1.__decorate([
Option(),
tslib_1.__metadata("design:type", Boolean)
], MaterialTextBox.prototype, "loadingEnabled", void 0);
tslib_1.__decorate([
Option(),
tslib_1.__metadata("design:type", String)
], MaterialTextBox.prototype, "i18nKey", void 0);
tslib_1.__decorate([
Option('i18nBypass'),
tslib_1.__metadata("design:type", Boolean)
], MaterialTextBox.prototype, "bypass", void 0);
tslib_1.__decorate([
Option(),
tslib_1.__metadata("design:type", Boolean)
], MaterialTextBox.prototype, "disabled", void 0);
tslib_1.__decorate([
Option(),
tslib_1.__metadata("design:type", String)
], MaterialTextBox.prototype, "field", void 0);
tslib_1.__decorate([
Option(),
tslib_1.__metadata("design:type", String)
], MaterialTextBox.prototype, "name", void 0);
tslib_1.__decorate([
Option(),
tslib_1.__metadata("design:type", String)
], MaterialTextBox.prototype, "typeOfData", void 0);
tslib_1.__decorate([
Option(),
tslib_1.__metadata("design:type", Boolean)
], MaterialTextBox.prototype, "readOnly", void 0);
tslib_1.__decorate([
I18N(),
Option(),
tslib_1.__metadata("design:type", Object)
], MaterialTextBox.prototype, "help", void 0);
tslib_1.__decorate([
Option('formatter.instance'),
tslib_1.__metadata("design:type", Object)
], MaterialTextBox.prototype, "formatter", void 0);
tslib_1.__decorate([
Option('formatter.name'),
tslib_1.__metadata("design:type", String)
], MaterialTextBox.prototype, "formatterName", void 0);
tslib_1.__decorate([
Option('formatter.options'),
tslib_1.__metadata("design:type", Object)
], MaterialTextBox.prototype, "formatterOptions", void 0);
tslib_1.__decorate([
Option('formatter.usePropertyValue'),
tslib_1.__metadata("design:type", Boolean)
], MaterialTextBox.prototype, "formatterUsePropertyValue", void 0);
tslib_1.__decorate([
Option(),
tslib_1.__metadata("design:type", String)
], MaterialTextBox.prototype, "type", void 0);
tslib_1.__decorate([
Option(),
tslib_1.__metadata("design:type", String)
], MaterialTextBox.prototype, "width", void 0);
tslib_1.__decorate([
I18N(),
Option(),
tslib_1.__metadata("design:type", String)
], MaterialTextBox.prototype, "label", void 0);
tslib_1.__decorate([
I18N(),
Option(),
tslib_1.__metadata("design:type", String)
], MaterialTextBox.prototype, "description", void 0);
tslib_1.__decorate([
Option('maxLength'),
tslib_1.__metadata("design:type", Number)
], MaterialTextBox.prototype, "maxLength", void 0);
tslib_1.__decorate([
Option(),
tslib_1.__metadata("design:type", String)
], MaterialTextBox.prototype, "buttonIcon", void 0);
tslib_1.__decorate([
Option(),
tslib_1.__metadata("design:type", String)
], MaterialTextBox.prototype, "buttonPosition", void 0);
tslib_1.__decorate([
Option(),
tslib_1.__metadata("design:type", Function)
], MaterialTextBox.prototype, "buttonHandler", void 0);
tslib_1.__decorate([
Option(),
tslib_1.__metadata("design:type", Boolean)
], MaterialTextBox.prototype, "showClearButton", void 0);
tslib_1.__decorate([
Option('load'),
tslib_1.__metadata("design:type", EventEmitter)
], MaterialTextBox.prototype, "loadEvent", void 0);
tslib_1.__decorate([
Option('startValidate'),
tslib_1.__metadata("design:type", EventEmitter)
], MaterialTextBox.prototype, "startValidateEvent", void 0);
tslib_1.__decorate([
Option('endValidate'),
tslib_1.__metadata("design:type", EventEmitter)
], MaterialTextBox.prototype, "endValidateEvent", void 0);
tslib_1.__decorate([
Option('beforeFocus'),
tslib_1.__metadata("design:type", EventEmitter)
], MaterialTextBox.prototype, "beforeFocusEvent", void 0);
tslib_1.__decorate([
Option('focus'),
tslib_1.__metadata("design:type", EventEmitter)
], MaterialTextBox.prototype, "focusEvent", void 0);
tslib_1.__decorate([
Option('beforeLostFocus'),
tslib_1.__metadata("design:type", EventEmitter)
], MaterialTextBox.prototype, "beforeLostFocusEvent", void 0);
tslib_1.__decorate([
Option('lostFocus'),
tslib_1.__metadata("design:type", EventEmitter)
], MaterialTextBox.prototype, "lostFocusEvent", void 0);
tslib_1.__decorate([
Option('beforeChange'),
tslib_1.__metadata("design:type", EventEmitter)
], MaterialTextBox.prototype, "beforeChangeEvent", void 0);
tslib_1.__decorate([
Option('change'),
tslib_1.__metadata("design:type", EventEmitter)
], MaterialTextBox.prototype, "changeEvent", void 0);
tslib_1.__decorate([
Option('beforeKeyUp'),
tslib_1.__metadata("design:type", EventEmitter)
], MaterialTextBox.prototype, "beforeKeyUpEvent", void 0);
tslib_1.__decorate([
Option('keyUp'),
tslib_1.__metadata("design:type", EventEmitter)
], MaterialTextBox.prototype, "keyUpEvent", void 0);
tslib_1.__decorate([
Option('beforeKeyDown'),
tslib_1.__metadata("design:type", EventEmitter)
], MaterialTextBox.prototype, "beforeKeyDownEvent", void 0);
tslib_1.__decorate([
Option('keyDown'),
tslib_1.__metadata("design:type", EventEmitter)
], MaterialTextBox.prototype, "keyDownEvent", void 0);
function MaterialTextBox_tsickle_Closure_declarations() {
/** @type {!Array<{type: !Function, args: (undefined|!Array<?>)}>} */
MaterialTextBox.decorators;
/**
* @nocollapse
* @type {function(): !Array<(null|{type: ?, decorators: (undefined|!Array<{type: !Function, args: (undefined|!Array<?>)}>)})>}
*/
MaterialTextBox.ctorParameters;
/** @type {!Object<string,!Array<{type: !Function, args: (undefined|!Array<?>)}>>} */
MaterialTextBox.propDecorators;
/** @type {?} */
MaterialTextBox.TYPE_NAME;
/** @type {?} */
MaterialTextBox.prototype.dataParent;
/** @type {?} */
MaterialTextBox.prototype.ignoreParentData;
/** @type {?} */
MaterialTextBox.prototype.data;
/** @type {?} */
MaterialTextBox.prototype.ignoreParentDisabled;
/** @type {?} */
MaterialTextBox.prototype.delegateHistory;
/** @type {?} */
MaterialTextBox.prototype.onDisabled;
/** @type {?} */
MaterialTextBox.prototype.onEnabled;
/** @type {?} */
MaterialTextBox.prototype.loadingEnabled;
/** @type {?} */
MaterialTextBox.prototype.i18nKey;
/** @type {?} */
MaterialTextBox.prototype.bypass;
/** @type {?} */
MaterialTextBox.prototype.options;
/** @type {?} */
MaterialTextBox.prototype.disabled;
/** @type {?} */
MaterialTextBox.prototype.field;
/** @type {?} */
MaterialTextBox.prototype.name;
/** @type {?} */
MaterialTextBox.prototype.typeOfData;
/** @type {?} */
MaterialTextBox.prototype.readOnly;
/** @type {?} */
MaterialTextBox.prototype.help;
/** @type {?} */
MaterialTextBox.prototype.formatter;
/** @type {?} */
MaterialTextBox.prototype.formatterName;
/** @type {?} */
MaterialTextBox.prototype.formatterOptions;
/** @type {?} */
MaterialTextBox.prototype.formatterUsePropertyValue;
/** @type {?} */
MaterialTextBox.prototype.type;
/** @type {?} */
MaterialTextBox.prototype.width;
/** @type {?} */
MaterialTextBox.prototype.label;
/** @type {?} */
MaterialTextBox.prototype.description;
/** @type {?} */
MaterialTextBox.prototype.maxLength;
/** @type {?} */
MaterialTextBox.prototype.buttonIcon;
/** @type {?} */
MaterialTextBox.prototype.buttonPosition;
/** @type {?} */
MaterialTextBox.prototype.buttonHandler;
/** @type {?} */
MaterialTextBox.prototype.showClearButton;
/** @type {?} */
MaterialTextBox.prototype.loadEvent;
/** @type {?} */
MaterialTextBox.prototype.startValidateEvent;
/** @type {?} */
MaterialTextBox.prototype.endValidateEvent;
/** @type {?} */
MaterialTextBox.prototype.beforeFocusEvent;
/** @type {?} */
MaterialTextBox.prototype.focusEvent;
/** @type {?} */
MaterialTextBox.prototype.beforeLostFocusEvent;
/** @type {?} */
MaterialTextBox.prototype.lostFocusEvent;
/** @type {?} */
MaterialTextBox.prototype.beforeChangeEvent;
/** @type {?} */
MaterialTextBox.prototype.changeEvent;
/** @type {?} */
MaterialTextBox.prototype.beforeKeyUpEvent;
/** @type {?} */
MaterialTextBox.prototype.keyUpEvent;
/** @type {?} */
MaterialTextBox.prototype.beforeKeyDownEvent;
/** @type {?} */
MaterialTextBox.prototype.keyDownEvent;
/** @type {?} */
MaterialTextBox.prototype.active;
/** @type {?} */
MaterialTextBox.prototype.classFocused;
/** @type {?} */
MaterialTextBox.prototype.clearFunc;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTWF0ZXJpYWxUZXh0Qm94LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL2NvbS5waGxveHVpLyIsInNvdXJjZXMiOlsibGliL3RoZW1lL21hdGVyaWFsL2NvbXBvbmVudC9kYXRhdmlldy9pbnB1dC9NYXRlcmlhbFRleHRCb3guY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsT0FBTyxFQUFFLFNBQVMsRUFBVSxVQUFVLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxZQUFZLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFM0YsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLDJEQUEyRCxDQUFDO0FBR3BGLE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSx5Q0FBeUMsQ0FBQztBQUMvRCxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sMkNBQTJDLENBQUM7QUFDbkUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0saURBQWlELENBQUM7QUFFbkYsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0saURBQWlELENBQUM7QUFLbkYsdUJBQU0sU0FBUyxHQUFXLG1CQUFtQixDQUFDO0FBRTlDLHVCQUFNLE1BQU0sR0FBVyxRQUFRLENBQUM7QUFDaEMsdUJBQU0sT0FBTyxHQUFXLFNBQVMsQ0FBQztBQUNsQyx1QkFBTSxPQUFPLEdBQVcsU0FBUyxDQUFDO0FBQ2xDLHVCQUFNLEtBQUssR0FBVyxPQUFPLENBQUM7QUFFOUIsdUJBQU0sbUJBQW1CLEdBQUcsT0FBTyxDQUFDO0FBQ3BDLHVCQUFNLHVCQUF1QixHQUFHLFFBQVEsQ0FBQztBQW9EekMsTUFBTSxzQkFBdUIsU0FBUSxPQUFPOzs7Ozs7SUEwSjFDLFlBQVksVUFBc0IsRUFBRSxnQkFBa0MsRUFBRSxnQkFBa0M7UUFDeEcsS0FBSyxDQUFDLFVBQVUsRUFBRSxnQkFBZ0IsRUFBRSxnQkFBZ0IsQ0FBQyxDQUFDO1FBRXRELElBQUksQ0FBQyxNQUFNLEdBQUcsS0FBSyxDQUFDO1FBQ3BC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TUFBTSxDQUFDLFNBQVMsQ0FBQztzQ0FFTSxZQUFZIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBPbkluaXQsIEVsZW1lbnRSZWYsIElucHV0LCBPdXRwdXQsIEV2ZW50RW1pdHRlciB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgSUhhc0RhdGEgfSBmcm9tICcuLi8uLi8uLi8uLi8uLi9jb21wb25lbnQvSUhhc0RhdGEnO1xuaW1wb3J0IHsgVGV4dEJveCB9IGZyb20gJy4uLy4uLy4uLy4uLy4uL2NvbXBvbmVudC9kYXRhdmlldy9pbnB1dC9UZXh0Qm94LmNvbXBvbmVudCc7XG5pbXBvcnQgeyBWYWxpZGF0aW9uUmVzdWx0IH0gZnJvbSAnLi4vLi4vLi4vLi4vLi4vY29tcG9uZW50L21vZGVsL1ZhbGlkYXRpb25SZXN1bHQnO1xuaW1wb3J0IHsgSUhhc0hlbHAgfSBmcm9tICcuLi8uLi8uLi8uLi8uLi9jb21wb25lbnQvSUhhc0hlbHAnO1xuaW1wb3J0IHsgSTE4TiB9IGZyb20gJy4uLy4uLy4uLy4uLy4uL2RlY29yYXRvci9JMThOLmRlY29yYXRvcic7XG5pbXBvcnQgeyBPcHRpb24gfSBmcm9tICcuLi8uLi8uLi8uLi8uLi9kZWNvcmF0b3IvT3B0aW9uLmRlY29yYXRvcic7XG5pbXBvcnQgeyBOZWVkRm9jdXNTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vLi4vLi4vLi4vc2VydmljZS9OZWVkRm9jdXNTZXJ2aWNlLnNlcnZpY2UnO1xuaW1wb3J0IHsgSUZvcm1hdHRlciB9IGZyb20gJy4uLy4uLy4uLy4uLy4uL3NoYXJlL2Zvcm1hdHRlci9JRm9ybWF0dGVyJztcbmltcG9ydCB7IEZvcm1hdHRlckZhY3RvcnkgfSBmcm9tICcuLi8uLi8uLi8uLi8uLi9zZXJ2aWNlL0Zvcm1hdHRlckZhY3Rvcnkuc2VydmljZSc7XG5cblxuZGVjbGFyZSB2YXIgJDogYW55O1xuXG5jb25zdCBUWVBFX05BTUU6IHN0cmluZyA9IFwibWF0ZXJpYWwtdGV4dC1ib3hcIjtcblxuY29uc3QgTk9STUFMOiBzdHJpbmcgPSAnbm9ybWFsJztcbmNvbnN0IFNVQ0NFU1M6IHN0cmluZyA9ICdzdWNjZXNzJztcbmNvbnN0IFdBUk5JTkc6IHN0cmluZyA9ICd3YXJuaW5nJztcbmNvbnN0IEVSUk9SOiBzdHJpbmcgPSAnZXJyb3InO1xuXG5jb25zdCBERUZBVUxUX0JVVFRPTl9JQ09OID0gJ2Nsb3NlJztcbmNvbnN0IERFRkFVTFRfQlVUVE9OX1BPU0lUSU9OID0gJ3N1ZmZpeCc7XG5cbkBDb21wb25lbnQoe1xuICBtb2R1bGVJZDogbW9kdWxlLmlkLFxuICBzZWxlY3RvcjogVFlQRV9OQU1FLFxuICB0ZW1wbGF0ZTogYDxkaXYgY2xhc3M9XCJtYXRlcmlhbC1pbnB1dCBtYXRlcmlhbC10ZXh0LWJveFwiIFtzdHlsZS53aWR0aF09XCJnZXRXaWR0aCgpXCI+XG5cdDxkaXYgY2xhc3M9XCJ0ZXh0Ym94LXdyYXBwZXJcIiBbY2xhc3MuYWN0aXZlXT1cIl9pc0FjdGl2ZSgpXCI+XG5cdFx0PG1hdC1mb3JtLWZpZWxkIFtuZ0NsYXNzXT1cImdldENsYXNzTWF0Rm9jdXNlZCgpXCI+XG5cdFx0XHQ8aW5wdXQgbWF0SW5wdXQgcGxhY2Vob2xkZXI9XCJ7e2dldExhYmVsKCkgfCBwaHhfdGV4dH19XCIgW2F0dHIubWF4bGVuZ3RoXT1cImdldE1heExlbmd0aCgpXCIgdHlwZT1cInt7Z2V0VHlwZSgpfX1cIiBjbGFzcz1cImZvcm0tY29udHJvbFwiIFtkaXNhYmxlZF09XCJpc0Rpc2FibGVkKClcIiBbcmVhZG9ubHldPVwiaXNSZWFkT25seSgpXCIgW2NsYXNzLmRpcnR5XT1cImlzRGF0YURpcnR5KClcIiAoY2hhbmdlKT1cIm9uVmFsdWVDaGFuZ2VkKCRldmVudClcIiAoZm9jdXNpbik9XCJvbkZvY3VzaW5nKCRldmVudClcIiAoYmx1cik9XCJvbkxvc3RGb2N1c2luZygkZXZlbnQpXCIgKGtleXVwKT1cIm9uS2V5VXAoJGV2ZW50KVwiXG5cdFx0XHQgIChrZXlkb3duKT1cIm9uS2V5RG93bigkZXZlbnQpXCIgW3ZhbHVlXT1cImZvcm1hdHRlZERhdGEgfCBwaHhfdGV4dFwiIFtjbGFzcy5ub3JtYWxdPVwiaXNOb3JtYWwoKSAmJiAhaXNEaXNhYmxlZCgpXCIgW2NsYXNzLnN1Y2Nlc3NdPVwiaXNTdWNjZXNzKCkgJiYgIWlzRGlzYWJsZWQoKVwiIFtjbGFzcy53YXJuaW5nXT1cImlzV2FybmluZygpICYmICFpc0Rpc2FibGVkKClcIiBbY2xhc3MuZXJyb3JdPVwiaXNFcnJvcigpICYmICFpc0Rpc2FibGVkKClcIj5cblx0XHRcdFx0PGJ1dHRvbiBtYXQtYnV0dG9uICpuZ0lmPVwiKGdldEJ1dHRvbkljb24oKSB8fCBpc1Nob3dDbGVhckJ1dHRvbigpKSAmJiAoZm9ybWF0dGVkRGF0YSAmJiBnZXRCdXR0b25Qb3NpdGlvbigpID09PSAnc3VmZml4JyAmJiAhKGlzRGlzYWJsZWQoKSB8fCBpc1JlYWRPbmx5KCkpKVwiIG1hdFN1ZmZpeCBtYXQtaWNvbi1idXR0b24gKGNsaWNrKT1cIm9uQnRuQ2xpY2soJGV2ZW50KVwiPlxuICAgIFx0XHRcdDxtYXQtaWNvbj57e2dldEJ1dHRvbkljb24oKX19PC9tYXQtaWNvbj5cblx0XHRcdFx0PC9idXR0b24+XG5cdFx0XHRcdDxidXR0b24gbWF0LWJ1dHRvbiAqbmdJZj1cIihnZXRCdXR0b25JY29uKCkgfHwgaXNTaG93Q2xlYXJCdXR0b24oKSkgJiYgKGZvcm1hdHRlZERhdGEgJiYgZ2V0QnV0dG9uUG9zaXRpb24oKSA9PT0gJ3ByZWZpeCcgJiYgIShpc0Rpc2FibGVkKCkgfHwgaXNSZWFkT25seSgpKSlcIiBtYXRQcmVmaXggbWF0LWljb24tYnV0dG9uIChjbGljayk9XCJvbkJ0bkNsaWNrKCRldmVudClcIj5cbiAgICBcdFx0XHQ8bWF0LWljb24+e3tnZXRCdXR0b25JY29uKCl9fTwvbWF0LWljb24+XG5cdFx0XHRcdDwvYnV0dG9uPlxuXHRcdFx0XHQ8YnV0dG9uIG1hdC1idXR0b24gKm5nSWY9XCIoZ2V0QnV0dG9uSWNvbigpIHx8IGlzU2hvd0NsZWFyQnV0dG9uKCkpICYmIChmb3JtYXR0ZWREYXRhICYmIGdldEJ1dHRvblBvc2l0aW9uKCkgPT09ICdzdWZmaXgnICYmIChpc0Rpc2FibGVkKCkgfHwgaXNSZWFkT25seSgpKSlcIiBkaXNhYmxlZCBtYXRTdWZmaXggbWF0LWljb24tYnV0dG9uIChjbGljayk9XCJvbkJ0bkNsaWNrKCRldmVudClcIj5cbiAgICBcdFx0XHQ8bWF0LWljb24+e3tnZXRCdXR0b25JY29uKCl9fTwvbWF0LWljb24+XG5cdFx0XHRcdDwvYnV0dG9uPlxuXHRcdFx0XHQ8YnV0dG9uIG1hdC1idXR0b24gKm5nSWY9XCIoZ2V0QnV0dG9uSWNvbigpIHx8IGlzU2hvd0NsZWFyQnV0dG9uKCkpICYmIChmb3JtYXR0ZWREYXRhICYmIGdldEJ1dHRvblBvc2l0aW9uKCkgPT09ICdwcmVmaXgnICYmIChpc0Rpc2FibGVkKCkgfHwgaXNSZWFkT25seSgpKSlcIiBkaXNhYmxlZCBtYXRQcmVmaXggbWF0LWljb24tYnV0dG9uIChjbGljayk9XCJvbkJ0bkNsaWNrKCRldmVudClcIj5cbiAgICBcdFx0XHQ8bWF0LWljb24+e3tnZXRCdXR0b25JY29uKCl9fTwvbWF0LWljb24+XG5cdFx0XHRcdDwvYnV0dG9uPlxuXHRcdDwvbWF0LWZvcm0tZmllbGQ+XG5cdDwvZGl2PlxuXHQ8ZGl2IGNsYXNzPVwidmFsaWRhdGlvblwiIFtzdHlsZS5kaXNwbGF5XT1cImdldFZhbGlkYXRpb25SZXN1bHRNZXNzYWdlKCkgPyB1bmRlZmluZWQgOiAnbm9uZSdcIiBbY2xhc3Mubm9ybWFsXT1cImlzTm9ybWFsKCkgJiYgIWlzRGlzYWJsZWQoKVwiIFtjbGFzcy5zdWNjZXNzXT1cImlzU3VjY2VzcygpICYmICFpc0Rpc2FibGVkKClcIiBbY2xhc3Mud2FybmluZ109XCJpc1dhcm5pbmcoKSAmJiAhaXNEaXNhYmxlZCgpXCIgW2NsYXNzLmVycm9yXT1cImlzRXJyb3IoKSAmJiAhaXNEaXNhYmxlZCgpXCI+XG5cdFx0PG5nLXRlbXBsYXRlIFtuZ0lmXT1cImdldFZhbGlkYXRpb25SZXN1bHRNZXNzYWdlKClcIiBbbmdJZkVsc2VdPVwidmFsaWRhdGlvbl9lbHNlXCI+XG5cdFx0XHR7e2dldFZhbGlkYXRpb25SZXN1bHRNZXNzYWdlKCkgfCBwaHhfdGV4dH19XG5cdFx0PC9uZy10ZW1wbGF0ZT5cblx0XHQ8bmctdGVtcGxhdGUgI3ZhbGlkYXRpb25fZWxzZT5cblx0XHRcdDwhLS0gV2UndmUgdG8gcHV0IHdoaXRlc3BhY2UgaWYgdGhlcmUgaXMgbm8gdmFsaWRhdGlvbiBtc2cgdG8gcHJldmVudCBlbXB0eSBkb20gLS0+XG5cdFx0XHQ8IS0tIHNpbmNlIGlmIHZhbGlkYXRlIG1zZydzIDxkaXY+IGRvbSBpcyBlbXB0eSwgdGhlIGNvbXBvbmVudCBwb3NpdGlvbmluZyAtLT5cblx0XHRcdDwhLS0gd2lsbCBiZSBtaXNwbGFjZWQuIC0tPlxuXHRcdFx0e3sgJyZuYnNwOycgfX1cblx0XHQ8L25nLXRlbXBsYXRlPlxuXHQ8L2Rpdj5cblx0PGRpdiBjbGFzcz1cImRlc2NyaXB0aW9uXCIgW3N0eWxlLmRpc3BsYXldPVwiZ2V0VmFsaWRhdGlvblJlc3VsdE1lc3NhZ2UoKSA/ICdub25lJyA6IHVuZGVmaW5lZFwiIFtjbGFzcy5ub3JtYWxdPVwiaXNOb3JtYWwoKSAmJiAhaXNEaXNhYmxlZCgpXCIgW2NsYXNzLnN1Y2Nlc3NdPVwiaXNTdWNjZXNzKCkgJiYgIWlzRGlzYWJsZWQoKVwiIFtjbGFzcy53YXJuaW5nXT1cImlzV2FybmluZygpICYmICFpc0Rpc2FibGVkKClcIiBbY2xhc3MuZXJyb3JdPVwiaXNFcnJvcigpICYmICFpc0Rpc2FibGVkKClcIj5cblx0XHQ8bmctdGVtcGxhdGUgW25nSWZdPVwiZ2V0RGVzY3JpcHRpb24oKVwiIFtuZ0lmRWxzZV09XCJkZXNjcmlwdGlvbl9lbHNlXCI+XG5cdFx0XHR7eyBnZXREZXNjcmlwdGlvbigpIHwgcGh4X3RleHQgfX1cblx0XHQ8L25nLXRlbXBsYXRlPlxuXHRcdDxuZy10ZW1wbGF0ZSAjZGVzY3JpcHRpb25fZWxzZT5cblx0XHRcdDwhLS0gV2UndmUgdG8gcHV0IHdoaXRlc3BhY2UgaWYgdGhlcmUgaXMgbm8gZGVzY3JpcHRpb24gdG8gcHJldmVudCBlbXB0eSBkb20gLS0+XG5cdFx0XHQ8IS0tIHNpbmNlIGlmIGRlc2NyaXB0aW9uJ3MgPGRpdj4gZG9tIGlzIGVtcHR5LCB0aGUgY29tcG9uZW50IHBvc2l0aW9uaW5nIC0tPlxuXHRcdFx0PCEtLSB3aWxsIGJlIG1pc3BsYWNlZC4gLS0+XG5cdFx0XHR7eyAnJm5ic3A7JyB9fVxuXHRcdDwvbmctdGVtcGxhdGU+XG5cdDwvZGl2PlxuXHQ8ZGl2IGNsYXNzPVwiaGVscFwiPlxuXHRcdHt7Z2V0SGVscCgpIHwgcGh4X3RleHR9fVxuXHQ8L2Rpdj5cbjwvZGl2PlxuYFxufSlcbmV4cG9ydCBjbGFzcyBNYXRlcmlhbFRleHRCb3ggZXh0ZW5kcyBUZXh0Qm94IGltcGxlbWVudHMgT25Jbml0LCBJSGFzSGVscCB7XG5cbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBUWVBFX05BTUU6IHN0cmluZyA9IFRZUEVfTkFNRTtcblxuICAvLyBSZS1kZWNsYXJlIGZpZWxkIHRvIGRlY2xhcmUgbmcgQElucHV0LlxuICAvLyAtLS0gZnJvbSBBYnN0cmFjdEhhc0RhdGFcbiAgQElucHV0KClcbiAgQE9wdGlvbigpXG4gIHByb3RlY3RlZCBkYXRhUGFyZW50OiBJSGFzRGF0YTtcbiAgQElucHV0KClcbiAgQE9wdGlvbigpXG4gIHByb3RlY3RlZCBpZ25vcmVQYXJlbnREYXRhOiBib29sZWFuO1xuICBASW5wdXQoKVxuICBAT3B0aW9uKClcbiAgcHJvdGVjdGVkIGRhdGE6IGFueTtcbiAgQElucHV0KClcbiAgQE9wdGlvbigpXG4gIHByb3RlY3RlZCBpZ25vcmVQYXJlbnREaXNhYmxlZDogYm9vbGVhbjtcbiAgQElucHV0KClcbiAgQE9wdGlvbigpXG4gIHByb3RlY3RlZCBkZWxlZ2F0ZUhpc3Rvcnk6IGJvb2xlYW47XG4gIEBJbnB1dCgpXG4gIEBPcHRpb24oKVxuICBwcm90ZWN0ZWQgb25EaXNhYmxlZDogRnVuY3Rpb247XG4gIEBJbnB1dCgpXG4gIEBPcHRpb24oKVxuICBwcm90ZWN0ZWQgb25FbmFibGVkOiBGdW5jdGlvbjtcbiAgQElucHV0KClcbiAgQE9wdGlvbigpXG4gIHByb3RlY3RlZCBsb2FkaW5nRW5hYmxlZDogYm9vbGVhbjtcbiAgQElucHV0KClcbiAgQE9wdGlvbigpXG4gIHByb3RlY3RlZCBpMThuS2V5OiBzdHJpbmc7XG4gIEBJbnB1dCgnaTE4bkJ5cGFzcycpXG4gIEBPcHRpb24oJ2kxOG5CeXBhc3MnKVxuICBwcm90ZWN0ZWQgYnlwYXNzOiBib29sZWFuO1xuICBASW5wdXQoKVxuICBwcm90ZWN0ZWQgb3B0aW9uczogYW55O1xuICBASW5wdXQoKVxuICBAT3B0aW9uKClcbiAgcHJvdGVjdGVkIGRpc2FibGVkOiBib29sZWFuO1xuICAvLyAtLS0gZnJvbSBBYnN0cmFjdERhdGFWaWV3XG4gIEBJbnB1dCgpXG4gIEBPcHRpb24oKVxuICBwcm90ZWN0ZWQgZmllbGQ6IHN0cmluZztcbiAgLy8gLS0tIGZyb20gQWJzdHJhY3RJbnB1dERhdGFWaWV3XG4gIEBJbnB1dCgpXG4gIEBPcHRpb24oKVxuICBwcm90ZWN0ZWQgbmFtZTogc3RyaW5nO1xuICBASW5wdXQoKVxuICBAT3B0aW9uKClcbiAgcHJvdGVjdGVkIHR5cGVPZkRhdGE6IHN0cmluZztcbiAgQElucHV0KClcbiAgQE9wdGlvbigpXG4gIHByb3RlY3RlZCByZWFkT25seTogYm9vbGVhbjtcbiAgQElucHV0KClcbiAgQEkxOE4oKVxuICBAT3B0aW9uKClcbiAgcHJvdGVjdGVkIGhlbHA6IGFueTtcbiAgLy8gLS0tIGZyb20gQWJzdHJhY3RIYXNGb3JtYXR0ZXJJbnB1dERhdGFWaWV3XG4gIEBJbnB1dCgnZm9ybWF0dGVyJylcbiAgQE9wdGlvbignZm9ybWF0dGVyLmluc3RhbmNlJylcbiAgcHJvdGVjdGVkIGZvcm1hdHRlcjogSUZvcm1hdHRlcjtcbiAgQElucHV0KCdmb3JtYXR0ZXJOYW1lJylcbiAgQE9wdGlvbignZm9ybWF0dGVyLm5hbWUnKVxuICBwcm90ZWN0ZWQgZm9ybWF0dGVyTmFtZTogc3RyaW5nO1xuICBASW5wdXQoJ2Zvcm1hdHRlck9wdGlvbnMnKVxuICBAT3B0aW9uKCdmb3JtYXR0ZXIub3B0aW9ucycpXG4gIHByb3RlY3RlZCBmb3JtYXR0ZXJPcHRpb25zOiBhbnk7XG4gIEBJbnB1dCgnZm9ybWF0dGVyVXNlUHJvcGVydHlWYWx1ZScpXG4gIEBPcHRpb24oJ2Zvcm1hdHRlci51c2VQcm9wZXJ0eVZhbHVlJylcbiAgcHJvdGVjdGVkIGZvcm1hdHRlclVzZVByb3BlcnR5VmFsdWU6IGJvb2xlYW47XG4gIC8vIC0tLSBmcm9tIFRleHRCb3hcbiAgQElucHV0KClcbiAgQE9wdGlvbigpXG4gIHByb3RlY3RlZCB0eXBlOiBzdHJpbmc7XG4gIEBJbnB1dCgpXG4gIEBPcHRpb24oKVxuICBwcm90ZWN0ZWQgd2lkdGg6IHN0cmluZztcbiAgLy8gLS0tIHNlbGZcbiAgQEkxOE4oKVxuICBAT3B0aW9uKClcbiAgQElucHV0KClcbiAgcHJvdGVjdGVkIGxhYmVsOiBzdHJpbmc7XG4gIEBJMThOKClcbiAgQE9wdGlvbigpXG4gIEBJbnB1dCgpXG4gIHByb3RlY3RlZCBkZXNjcmlwdGlvbjogc3RyaW5nO1xuICBAT3B0aW9uKCdtYXhMZW5ndGgnKVxuICBASW5wdXQoJ3BoeE1heExlbmd0aCcpXG4gIHByb3RlY3RlZCBtYXhMZW5ndGg6IG51bWJlcjtcbiAgQElucHV0KClcbiAgQE9wdGlvbigpXG4gIHByb3RlY3RlZCBidXR0b25JY29uOiBzdHJpbmc7XG4gIEBJbnB1dCgpXG4gIEBPcHRpb24oKVxuICBwcm90ZWN0ZWQgYnV0dG9uUG9zaXRpb246IHN0cmluZztcbiAgQElucHV0KClcbiAgQE9wdGlvbigpXG4gIHByb3RlY3RlZCBidXR0b25IYW5kbGVyOiBGdW5jdGlvbjtcbiAgQElucHV0KClcbiAgQE9wdGlvbigpXG4gIHByb3RlY3RlZCBzaG93Q2xlYXJCdXR0b246IGJvb2xlYW47XG5cbiAgLy8gUmUtZGVjbGFyZSBmaWVsZCB0byBkZWNsYXJlIG5nIEBPdXRwdXQuXG4gIC8vIC0tLSBmcm9tIEFic3RyYWN0SGFzRGF0YVxuICBAT3V0cHV0KCdwaHhMb2FkJylcbiAgQE9wdGlvbignbG9hZCcpXG4gIHByb3RlY3RlZCBsb2FkRXZlbnQ6IEV2ZW50RW1pdHRlcjxhbnk+O1xuICAvLyAtLS0gZnJvbSBBYnN0cmFjdERhdGFWaWV3XG4gIC8vIC0tLSBmcm9tIEFic3RyYWN0SW5wdXREYXRhVmlld1xuICBAT3V0cHV0KCdwaHhTdGFydFZhbGlkYXRlJylcbiAgQE9wdGlvbignc3RhcnRWYWxpZGF0ZScpXG4gIHByb3RlY3RlZCBzdGFydFZhbGlkYXRlRXZlbnQ6IEV2ZW50RW1pdHRlcjxhbnk+O1xuICBAT3V0cHV0KCdwaHhFbmRWYWxpZGF0ZScpXG4gIEBPcHRpb24oJ2VuZFZhbGlkYXRlJylcbiAgcHJvdGVjdGVkIGVuZFZhbGlkYXRlRXZlbnQ6IEV2ZW50RW1pdHRlcjxhbnk+O1xuICBAT3V0cHV0KCdwaHhCZWZvcmVGb2N1cycpXG4gIEBPcHRpb24oJ2JlZm9yZUZvY3VzJylcbiAgcHJvdGVjdGVkIGJlZm9yZUZvY3VzRXZlbnQ6IEV2ZW50RW1pdHRlcjxhbnk+O1xuICBAT3V0cHV0KCdwaHhGb2N1cycpXG4gIEBPcHRpb24oJ2ZvY3VzJylcbiAgcHJvdGVjdGVkIGZvY3VzRXZlbnQ6IEV2ZW50RW1pdHRlcjxhbnk+O1xuICBAT3V0cHV0KCdwaHhCZWZvcmVMb3N0Rm9jdXMnKVxuICBAT3B0aW9uKCdiZWZvcmVMb3N0Rm9jdXMnKVxuICBwcm90ZWN0ZWQgYmVmb3JlTG9zdEZvY3VzRXZlbnQ6IEV2ZW50RW1pdHRlcjxhbnk+O1xuICBAT3V0cHV0KCdwaHhMb3N0Rm9jdXMnKVxuICBAT3B0aW9uKCdsb3N0Rm9jdXMnKVxuICBwcm90ZWN0ZWQgbG9zdEZvY3VzRXZlbnQ6IEV2ZW50RW1pdHRlcjxhbnk+O1xuICBAT3V0cHV0KCdwaHhCZWZvcmVDaGFuZ2UnKVxuICBAT3B0aW9uKCdiZWZvcmVDaGFuZ2UnKVxuICBwcm90ZWN0ZWQgYmVmb3JlQ2hhbmdlRXZlbnQ6IEV2ZW50RW1pdHRlcjxhbnk+O1xuICBAT3V0cHV0KCdwaHhDaGFuZ2UnKVxuICBAT3B0aW9uKCdjaGFuZ2UnKVxuICBwcm90ZWN0ZWQgY2hhbmdlRXZlbnQ6IEV2ZW50RW1pdHRlcjxhbnk+O1xuICAvLyAtLS0gZnJvbSBBYnN0cmFjdEhhc0Zvcm1hdHRlcklucHV0RGF0YVZpZXdcbiAgLy8gLS0tIGZyb20gVGV4dEJveFxuICBAT3B0aW9uKCdiZWZvcmVLZXlVcCcpXG4gIEBPdXRwdXQoJ3BoeEJlZm9yZUtleVVwJylcbiAgcHJvdGVjdGVkIGJlZm9yZUtleVVwRXZlbnQ6IEV2ZW50RW1pdHRlcjxhbnk+O1xuICBAT3B0aW9uKCdrZXlVcCcpXG4gIEBPdXRwdXQoJ3BoeEtleVVwJylcbiAgcHJvdGVjdGVkIGtleVVwRXZlbnQ6IEV2ZW50RW1pdHRlcjxhbnk+O1xuICBAT3B0aW9uKCdiZWZvcmVLZXlEb3duJylcbiAgQE91dHB1dCgncGh4QmVmb3JlS2V5RG93bicpXG4gIHByb3RlY3RlZCBiZWZvcmVLZXlEb3duRXZlbnQ6IEV2ZW50RW1pdHRlcjxhbnk+O1xuICBAT3B0aW9uKCdrZXlEb3duJylcbiAgQE91dHB1dCgncGh4S2V5RG93bicpXG4gIHByb3RlY3RlZCBrZXlEb3duRXZlbnQ6IEV2ZW50RW1pdHRlcjxhbnk+O1xuXG4gIHByaXZhdGUgYWN0aXZlOiBib29sZWFuO1xuICBwcml2YXRlIGNsYXNzRm9jdXNlZDogYm9vbGVhbjtcbiAgcHJpdmF0ZSBjbGVhckZ1bmM6IEZ1bmN0aW9uO1xuXG4gIGNvbnN0cnVjdG9yKGVsZW1lbnRSZWY6IEVsZW1lbnRSZWYsIGZvcm1hdHRlckZhY3Rvcnk6IEZvcm1hdHRlckZhY3RvcnksIG5lZWRGb2N1c1NlcnZpY2U6IE5lZWRGb2N1c1NlcnZpY2UpIHtcbiAgICBzdXBlcihlbGVtZW50UmVmLCBmb3JtYXR0ZXJGYWN0b3J5LCBuZWVkRm9jdXNTZXJ2aWNlKTtcblxuICAgIHRoaXMuYWN0aXZlID0gZmFsc2U7XG4gICAgdGhpcy5jbGVhckZ1bmMgPSAoKSA9PiB7IHRoaXMuZm9ybWF0dGVkRGF0YSA9ICcnOyB9O1xuXG4gIH1cblxuICBwdWJsaWMgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgc3VwZXIubmdPbkluaXQoKTtcbiAgICB0aGlzLnJlZnJlc2hBY3RpdmVUZXh0Qm94KCk7XG4gIH1cblxuICBwdWJsaWMgX2Rpc3BsYXlIZWxwKCk6IGJvb2xlYW4ge1xuICAgIGxldCBoYXNIZWxwID0gdGhpcy5oYXNIZWxwKCk7XG5cbiAgICByZXR1cm4gaGFzSGVscCAmJiB0aGlzLmlzU2hvd0hlbHAoKTtcbiAgfVxuXG4gIHByaXZhdGUgcmVmcmVzaEFjdGl2ZVRleHRCb3goKTogdm9pZCB7XG4gICAgbGV0IHZhbCA9IHRoaXMuZ2V0Rm9ybWF0dGVkRGF0YSgpO1xuXG4gICAgaWYgKHZhbCAhPT0gbnVsbCAmJiB0eXBlb2YgdmFsICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgaWYgKHR5cGVvZiB2YWwgPT09ICdzdHJpbmcnICYmIHZhbCA9PT0gJycpIHtcbiAgICAgICAgdGhpcy5hY3RpdmUgPSBmYWxzZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuYWN0aXZlID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5hY3RpdmUgPSBmYWxzZTtcbiAgICB9XG4gIH0gXG5cbiAgcHJvdGVjdGVkIG9uVmFsaWRhdGlvbkVuZChpbnB1dFZhbHVlOiBhbnksIHJlc3VsdHM6IFZhbGlkYXRpb25SZXN1bHRbXSk6IHZvaWQge1xuICB9XG5cbiAgcHJvdGVjdGVkIG9uRGF0YUNoYW5nZShkYXRhOiBhbnksIGlucHV0VmFsOiBhbnkpOiB2b2lkIHtcbiAgICBzdXBlci5vbkRhdGFDaGFuZ2UoZGF0YSwgaW5wdXRWYWwpO1xuXG4gICAgdGhpcy5yZWZyZXNoQWN0aXZlVGV4dEJveCgpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGRvRm9jdXMoJGV2ZW50OiBFdmVudCk6IHZvaWQge1xuICAgIHN1cGVyLmRvRm9jdXMoJGV2ZW50KTtcblxuICAgIHRoaXMuYWN0aXZlID0gdHJ1ZTtcbiAgICB0aGlzLmNsYXNzRm9jdXNlZCA9IHRydWU7XG4gIH1cblxuICBwcm90ZWN0ZWQgZG9Mb3N0Rm9jdXMoJGV2ZW50OiBFdmVudCk6IHZvaWQge1xuICAgIHN1cGVyLmRvTG9zdEZvY3VzKCRldmVudCk7XG5cbiAgICB0aGlzLnJlZnJlc2hBY3RpdmVUZXh0Qm94KCk7XG4gICAgdGhpcy5jbGFzc0ZvY3VzZWQgPSBmYWxzZTtcbiAgfVxuXG4gIHB1YmxpYyBnZXRDbGFzc01hdEZvY3VzZWQoKTogYW55IHtcbiAgICByZXR1cm4gdGhpcy5pc1JlYWRPbmx5KCkgPyB7ICdtYXQtZm9jdXNlZCc6IHRoaXMuX2lzQ2xhc3NGb2N1c2VkKCkgfSA6IHt9O1xuICB9XG5cbiAgcHVibGljIF9pc0FjdGl2ZSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5hY3RpdmU7XG4gIH1cblxuICBwdWJsaWMgX2lzQ2xhc3NGb2N1c2VkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmNsYXNzRm9jdXNlZDtcbiAgfVxuXG4gIHB1YmxpYyBvblZhbHVlQ2hhbmdlZCgkZXZlbnQ6IEV2ZW50KSB7XG4gICAgc3VwZXIub25WYWx1ZUNoYW5nZWQoJGV2ZW50KTtcblxuICAgIHRoaXMucmVmcmVzaEFjdGl2ZVRleHRCb3goKTtcbiAgfVxuXG4gIHB1YmxpYyBzZWxmU2F2ZURhdGEoZGF0YTogYW55KTogdm9pZCB7XG4gICAgc3VwZXIuc2VsZlNhdmVEYXRhKGRhdGEpO1xuXG4gICAgdGhpcy5yZWZyZXNoQWN0aXZlVGV4dEJveCgpO1xuICB9XG5cbiAgcHVibGljIGdldERlc2NyaXB0aW9uKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuZGVzY3JpcHRpb247XG4gIH1cblxuICBwdWJsaWMgc2V0RGVzY3JpcHRpb24oZGVzY3JpcHRpb246IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMuZGVzY3JpcHRpb24gPSBkZXNjcmlwdGlvbjtcbiAgfVxuXG4gIHB1YmxpYyBnZXRMYWJlbCgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLmxhYmVsO1xuICB9XG5cbiAgcHVibGljIHNldExhYmVsKGxhYmVsOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLmxhYmVsID0gbGFiZWw7XG4gIH1cblxuICBwdWJsaWMgcmVzZXRWYWxpZGF0aW9uUmVzdWx0KCk6IHZvaWQge1xuICAgIHN1cGVyLnJlc2V0VmFsaWRhdGlvblJlc3VsdCgpO1xuXG4gICAgdGhpcy5hY3RpdmUgPSBmYWxzZTtcbiAgfVxuXG4gIHB1YmxpYyBvbkJ0bkNsaWNrKCRldmVudDogRXZlbnQpIHtcbiAgICBpZiAoIXRoaXMuaXNSZWFkT25seSgpICYmICF0aGlzLmlzRGlzYWJsZWQoKSkge1xuXG4gICAgICB0aGlzLnNldEJ1dHRvbkhhbmRsZXIodGhpcy5zaG93Q2xlYXJCdXR0b24gPyB0aGlzLmNsZWFyRnVuYyA6IHRoaXMuYnV0dG9uSGFuZGxlcik7XG5cbiAgICAgIGlmICh0aGlzLmJ1dHRvbkhhbmRsZXIgIT09IG51bGwgJiYgdGhpcy5idXR0b25IYW5kbGVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhpcy5idXR0b25IYW5kbGVyKHRoaXMsICRldmVudCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGlzU2hvd0NsZWFyQnV0dG9uKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnNob3dDbGVhckJ1dHRvbjtcbiAgfVxuXG4gIHB1YmxpYyBzZXRTaG93Q2xlYXJCdXR0b24oc2hvd0NsZWFyQnV0dG9uOiBib29sZWFuKTogdm9pZCB7XG4gICAgdGhpcy5zaG93Q2xlYXJCdXR0b24gPSBzaG93Q2xlYXJCdXR0b247XG4gIH1cblxuICBwdWJsaWMgZ2V0QnV0dG9uSWNvbigpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLnNob3dDbGVhckJ1dHRvbiA/IERFRkFVTFRfQlVUVE9OX0lDT04gOiB0aGlzLmJ1dHRvbkljb247XG4gIH1cblxuICBwdWJsaWMgc2V0QnV0dG9uSWNvbihidXR0b25JY29uOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLmJ1dHRvbkljb24gPSBidXR0b25JY29uO1xuICB9XG5cbiAgcHVibGljIGdldEJ1dHRvblBvc2l0aW9uKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuc2hvd0NsZWFyQnV0dG9uID8gREVGQVVMVF9CVVRUT05fUE9TSVRJT04gOiAoIXRoaXMuYnV0dG9uUG9zaXRpb24gPyBERUZBVUxUX0JVVFRPTl9QT1NJVElPTiA6IHRoaXMuYnV0dG9uUG9zaXRpb24pO1xuICB9XG5cbiAgcHVibGljIHNldEJ1dHRvblBvc2l0aW9uKGJ1dHRvblBvc2l0aW9uOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLmJ1dHRvblBvc2l0aW9uID0gYnV0dG9uUG9zaXRpb247XG4gIH1cblxuICBwdWJsaWMgZ2V0QnV0dG9uSGFuZGxlcigpOiBGdW5jdGlvbiB7XG4gICAgcmV0dXJuIHRoaXMuc2hvd0NsZWFyQnV0dG9uID8gdGhpcy5jbGVhckZ1bmMgOiAoIXRoaXMuYnV0dG9uSGFuZGxlciA/IHRoaXMuY2xlYXJGdW5jIDogdGhpcy5idXR0b25IYW5kbGVyKTtcbiAgfVxuXG4gIHB1YmxpYyBzZXRCdXR0b25IYW5kbGVyKGJ1dHRvbkhhbmRsZXI6IEZ1bmN0aW9uKTogdm9pZCB7XG4gICAgdGhpcy5idXR0b25IYW5kbGVyID0gYnV0dG9uSGFuZGxlcjtcbiAgfVxuXG4gIHB1YmxpYyBvbktleVVwKCRldmVudDogYW55KTogdm9pZCB7XG4gICAgaWYgKHRoaXMuaXNSZWFkT25seSgpIHx8IHRoaXMuaXNEaXNhYmxlZCgpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgc3VwZXIub25LZXlVcCgkZXZlbnQpO1xuICB9XG5cbiAgcHVibGljIG9uS2V5RG93bigkZXZlbnQ6IGFueSk6IHZvaWQge1xuICAgIGlmICh0aGlzLmlzUmVhZE9ubHkoKSB8fCB0aGlzLmlzRGlzYWJsZWQoKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHN1cGVyLm9uS2V5RG93bigkZXZlbnQpO1xuICB9XG59XG4iXX0=