@angular-mdl/core
Version:
Angular components, directives and styles based on material design lite https://getmdl.io.
462 lines • 42 kB
JavaScript
import { Component, ElementRef, EventEmitter, forwardRef, HostBinding, Inject, InjectionToken, Input, Optional, Output, Renderer2, ViewChild, ViewEncapsulation, } from "@angular/core";
import { NG_VALUE_ACCESSOR } from "@angular/forms";
import { toBoolean } from "../common/boolean-property";
import { toNumber } from "../common/number.property";
import { noop } from "../common/noop";
import * as i0 from "@angular/core";
import * as i1 from "../icon/mdl-icon.component";
import * as i2 from "../button/mdl-button.component";
import * as i3 from "@angular/forms";
import * as i4 from "@angular/common";
export const DISABLE_NATIVE_VALIDITY_CHECKING = new InjectionToken("disableNativeValidityChecking");
let nextId = 0;
const IS_FOCUSED = "is-focused";
const IS_DISABLED = "is-disabled";
const IS_INVALID = "is-invalid";
const IS_DIRTY = "is-dirty";
/* eslint-disable @angular-eslint/no-conflicting-lifecycle */
export class MdlTextFieldComponent {
constructor(renderer, elmRef, nativeCheckGlobalDisabled) {
this.renderer = renderer;
this.elmRef = elmRef;
this.nativeCheckGlobalDisabled = nativeCheckGlobalDisabled;
// eslint-disable-next-line
this.blurEmitter = new EventEmitter();
// eslint-disable-next-line
this.focusEmitter = new EventEmitter();
// eslint-disable-next-line
this.keyupEmitter = new EventEmitter();
this.type = "text";
this.id = `mdl-textfield-${nextId++}`;
this.tabindex = null;
this.maxlength = null;
this.isTextfield = true;
this.isUpgraded = true;
this.valueIntern = null;
this.onTouchedCallback = noop;
this.onChangeCallback = noop;
this.disabledIntern = false;
this.readonlyIntern = false;
this.requiredIntern = false;
this.autofocusIntern = false;
this.isFloatingLabelIntern = false;
this.rowsIntern = null;
this.maxrowsIntern = -1;
// @experimental
this.disableNativeValidityCheckingIntern = false;
this.el = elmRef.nativeElement;
}
get value() {
return this.valueIntern;
}
set value(v) {
this.valueIntern =
this.type === "number" ? (v === "" ? null : parseFloat(v)) : v;
this.onChangeCallback(this.value);
}
get disabled() {
return this.disabledIntern;
}
set disabled(value) {
this.disabledIntern = toBoolean(value);
}
get readonly() {
return this.readonlyIntern;
}
set readonly(value) {
this.readonlyIntern = toBoolean(value);
}
get required() {
return this.requiredIntern;
}
set required(value) {
this.requiredIntern = toBoolean(value);
}
get autofocus() {
return this.autofocusIntern;
}
set autofocus(value) {
this.autofocusIntern = toBoolean(value);
}
get isFloatingLabel() {
return this.isFloatingLabelIntern;
}
set isFloatingLabel(value) {
this.isFloatingLabelIntern = toBoolean(value);
}
get rows() {
return this.rowsIntern;
}
set rows(value) {
this.rowsIntern = toNumber(value);
}
get maxrows() {
return this.maxrowsIntern;
}
set maxrows(value) {
this.maxrowsIntern = toNumber(value) ?? -1;
}
get disableNativeValidityChecking() {
return this.disableNativeValidityCheckingIntern;
}
set disableNativeValidityChecking(value) {
this.disableNativeValidityCheckingIntern = toBoolean(value);
}
writeValue(value) {
this.valueIntern = value;
this.checkDirty();
}
registerOnChange(fn) {
this.onChangeCallback = fn;
}
registerOnTouched(fn) {
this.onTouchedCallback = fn;
}
setDisabledState(isDisabled) {
this.disabled = isDisabled;
}
// eslint-disable-next-line @angular-eslint/no-conflicting-lifecycle
ngOnChanges() {
this.checkDisabled();
}
// eslint-disable-next-line @angular-eslint/no-conflicting-lifecycle
ngDoCheck() {
this.checkValidity();
this.checkDirty();
}
setFocus() {
if (!this.inputEl) {
return;
}
this.inputEl.nativeElement.dispatchEvent(new Event("focus"));
}
keydownTextarea($event) {
const currentRowCount = this.inputEl?.nativeElement.value.split("\n").length;
// eslint-disable-next-line
if ($event.keyCode === 13) {
if (currentRowCount >= this.maxrows && this.maxrows !== -1) {
$event.preventDefault();
}
}
}
// model value.
triggerChange(event) {
this.value = event.target.value;
this.onTouchedCallback();
}
onFocus(event) {
this.renderer.addClass(this.el, IS_FOCUSED);
this.focusEmitter.emit(event);
}
onBlur(event) {
this.renderer.removeClass(this.el, IS_FOCUSED);
this.onTouchedCallback();
this.blurEmitter.emit(event);
}
onKeyup(event) {
this.keyupEmitter.emit(event);
}
checkDisabled() {
if (this.disabled) {
this.renderer.addClass(this.el, IS_DISABLED);
}
else {
this.renderer.removeClass(this.el, IS_DISABLED);
}
}
checkValidity() {
// check the global setting - if globally disabled do no check
if (this.nativeCheckGlobalDisabled === true) {
return;
}
// check local setting - if locally disabled do no check
if (this.disableNativeValidityChecking) {
return;
}
if (this.inputEl && this.inputEl.nativeElement.validity) {
if (!this.inputEl.nativeElement.validity.valid) {
this.renderer.addClass(this.el, IS_INVALID);
}
else {
this.renderer.removeClass(this.el, IS_INVALID);
}
}
}
checkDirty() {
const dirty = this.inputEl &&
this.inputEl.nativeElement.value &&
this.inputEl.nativeElement.value.length > 0;
if (dirty) {
this.renderer.addClass(this.el, IS_DIRTY);
}
else {
this.renderer.removeClass(this.el, IS_DIRTY);
}
}
}
MdlTextFieldComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: MdlTextFieldComponent, deps: [{ token: i0.Renderer2 }, { token: i0.ElementRef }, { token: DISABLE_NATIVE_VALIDITY_CHECKING, optional: true }], target: i0.ɵɵFactoryTarget.Component });
MdlTextFieldComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: MdlTextFieldComponent, selector: "mdl-textfield", inputs: { type: "type", label: "label", pattern: "pattern", min: "min", max: "max", step: "step", name: "name", id: "id", errorMessage: ["error-msg", "errorMessage"], placeholder: "placeholder", autocomplete: "autocomplete", icon: "icon", tabindex: "tabindex", maxlength: "maxlength", value: "value", disabled: "disabled", readonly: "readonly", required: "required", autofocus: "autofocus", isFloatingLabel: ["floating-label", "isFloatingLabel"], rows: "rows", maxrows: "maxrows", disableNativeValidityChecking: "disableNativeValidityChecking" }, outputs: { blurEmitter: "blur", focusEmitter: "focus", keyupEmitter: "keyup" }, host: { properties: { "class.has-placeholder": "this.placeholder", "class.mdl-textfield--expandable": "this.icon", "class.mdl-textfield": "this.isTextfield", "class.is-upgraded": "this.isUpgraded", "class.mdl-textfield--floating-label": "this.isFloatingLabel" } }, providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => MdlTextFieldComponent),
multi: true,
},
], viewQueries: [{ propertyName: "inputEl", first: true, predicate: ["input"], descendants: true }], usesOnChanges: true, ngImport: i0, template: `
<div *ngIf="!icon">
<textarea
*ngIf="rows"
#input
[rows]="rows"
class="mdl-textfield__input"
type="text"
[attr.name]="name"
[id]="id"
[placeholder]="placeholder ? placeholder : ''"
(focus)="onFocus($event)"
(blur)="onBlur($event)"
(keydown)="keydownTextarea($event)"
(keyup)="onKeyup($event)"
[(ngModel)]="value"
[disabled]="disabled"
[required]="required"
[autofocus]="autofocus"
[readonly]="readonly"
[maxlength]="maxlength"
></textarea>
<input
*ngIf="!rows"
#input
class="mdl-textfield__input"
[type]="type"
[attr.name]="name"
[id]="id"
[pattern]="pattern ? pattern : '.*'"
[attr.min]="min"
[attr.max]="max"
[attr.step]="step"
[placeholder]="placeholder ? placeholder : ''"
[autocomplete]="autocomplete ? autocomplete : ''"
(focus)="onFocus($event)"
(blur)="onBlur($event)"
(keyup)="onKeyup($event)"
[(ngModel)]="value"
[disabled]="disabled"
[required]="required"
[autofocus]="autofocus"
[readonly]="readonly"
[attr.tabindex]="tabindex"
[maxlength]="maxlength"
/>
<label class="mdl-textfield__label" [attr.for]="id">{{ label }}</label>
<span class="mdl-textfield__error">{{ errorMessage }}</span>
</div>
<div *ngIf="icon">
<button mdl-button mdl-button-type="icon" (click)="setFocus()">
<mdl-icon>{{ icon }}</mdl-icon>
</button>
<div class="mdl-textfield__expandable-holder">
<input
#input
class="mdl-textfield__input"
[type]="type"
[attr.name]="name"
[id]="id"
[pattern]="pattern ? pattern : '.*'"
[attr.min]="min"
[attr.max]="max"
[attr.step]="step"
[placeholder]="placeholder ? placeholder : ''"
[autocomplete]="autocomplete ? autocomplete : ''"
(focus)="onFocus($event)"
(blur)="onBlur($event)"
(keyup)="onKeyup($event)"
[(ngModel)]="value"
[disabled]="disabled"
[required]="required"
[autofocus]="autofocus"
[readonly]="readonly"
[attr.tabindex]="tabindex"
[maxlength]="maxlength"
/>
<label class="mdl-textfield__label" [attr.for]="id">{{ label }}</label>
<span class="mdl-textfield__error">{{ errorMessage }}</span>
</div>
</div>
`, isInline: true, dependencies: [{ kind: "component", type: i1.MdlIconComponent, selector: "mdl-icon" }, { kind: "component", type: i2.MdlButtonComponent, selector: "mdl-button, button[mdl-button], a[mdl-button]", inputs: ["mdl-button-type", "mdl-colored", "disabled"], exportAs: ["mdlButton"] }, { kind: "directive", type: i3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i3.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i3.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], encapsulation: i0.ViewEncapsulation.None });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: MdlTextFieldComponent, decorators: [{
type: Component,
args: [{
selector: "mdl-textfield",
template: `
<div *ngIf="!icon">
<textarea
*ngIf="rows"
#input
[rows]="rows"
class="mdl-textfield__input"
type="text"
[attr.name]="name"
[id]="id"
[placeholder]="placeholder ? placeholder : ''"
(focus)="onFocus($event)"
(blur)="onBlur($event)"
(keydown)="keydownTextarea($event)"
(keyup)="onKeyup($event)"
[(ngModel)]="value"
[disabled]="disabled"
[required]="required"
[autofocus]="autofocus"
[readonly]="readonly"
[maxlength]="maxlength"
></textarea>
<input
*ngIf="!rows"
#input
class="mdl-textfield__input"
[type]="type"
[attr.name]="name"
[id]="id"
[pattern]="pattern ? pattern : '.*'"
[attr.min]="min"
[attr.max]="max"
[attr.step]="step"
[placeholder]="placeholder ? placeholder : ''"
[autocomplete]="autocomplete ? autocomplete : ''"
(focus)="onFocus($event)"
(blur)="onBlur($event)"
(keyup)="onKeyup($event)"
[(ngModel)]="value"
[disabled]="disabled"
[required]="required"
[autofocus]="autofocus"
[readonly]="readonly"
[attr.tabindex]="tabindex"
[maxlength]="maxlength"
/>
<label class="mdl-textfield__label" [attr.for]="id">{{ label }}</label>
<span class="mdl-textfield__error">{{ errorMessage }}</span>
</div>
<div *ngIf="icon">
<button mdl-button mdl-button-type="icon" (click)="setFocus()">
<mdl-icon>{{ icon }}</mdl-icon>
</button>
<div class="mdl-textfield__expandable-holder">
<input
#input
class="mdl-textfield__input"
[type]="type"
[attr.name]="name"
[id]="id"
[pattern]="pattern ? pattern : '.*'"
[attr.min]="min"
[attr.max]="max"
[attr.step]="step"
[placeholder]="placeholder ? placeholder : ''"
[autocomplete]="autocomplete ? autocomplete : ''"
(focus)="onFocus($event)"
(blur)="onBlur($event)"
(keyup)="onKeyup($event)"
[(ngModel)]="value"
[disabled]="disabled"
[required]="required"
[autofocus]="autofocus"
[readonly]="readonly"
[attr.tabindex]="tabindex"
[maxlength]="maxlength"
/>
<label class="mdl-textfield__label" [attr.for]="id">{{ label }}</label>
<span class="mdl-textfield__error">{{ errorMessage }}</span>
</div>
</div>
`,
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => MdlTextFieldComponent),
multi: true,
},
],
encapsulation: ViewEncapsulation.None,
}]
}], ctorParameters: function () { return [{ type: i0.Renderer2 }, { type: i0.ElementRef }, { type: undefined, decorators: [{
type: Optional
}, {
type: Inject,
args: [DISABLE_NATIVE_VALIDITY_CHECKING]
}] }]; }, propDecorators: { blurEmitter: [{
type: Output,
args: ["blur"]
}], focusEmitter: [{
type: Output,
args: ["focus"]
}], keyupEmitter: [{
type: Output,
args: ["keyup"]
}], inputEl: [{
type: ViewChild,
args: ["input"]
}], type: [{
type: Input
}], label: [{
type: Input
}], pattern: [{
type: Input
}], min: [{
type: Input
}], max: [{
type: Input
}], step: [{
type: Input
}], name: [{
type: Input
}], id: [{
type: Input
}], errorMessage: [{
type: Input,
args: ["error-msg"]
}], placeholder: [{
type: HostBinding,
args: ["class.has-placeholder"]
}, {
type: Input
}], autocomplete: [{
type: Input
}], icon: [{
type: HostBinding,
args: ["class.mdl-textfield--expandable"]
}, {
type: Input
}], tabindex: [{
type: Input
}], maxlength: [{
type: Input
}], isTextfield: [{
type: HostBinding,
args: ["class.mdl-textfield"]
}], isUpgraded: [{
type: HostBinding,
args: ["class.is-upgraded"]
}], value: [{
type: Input
}], disabled: [{
type: Input
}], readonly: [{
type: Input
}], required: [{
type: Input
}], autofocus: [{
type: Input
}], isFloatingLabel: [{
type: HostBinding,
args: ["class.mdl-textfield--floating-label"]
}, {
type: Input,
args: ["floating-label"]
}], rows: [{
type: Input
}], maxrows: [{
type: Input
}], disableNativeValidityChecking: [{
type: Input
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWRsLXRleHRmaWVsZC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9jb3JlL3NyYy9saWIvdGV4dGZpZWxkL21kbC10ZXh0ZmllbGQuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCxTQUFTLEVBRVQsVUFBVSxFQUNWLFlBQVksRUFDWixVQUFVLEVBQ1YsV0FBVyxFQUNYLE1BQU0sRUFDTixjQUFjLEVBQ2QsS0FBSyxFQUVMLFFBQVEsRUFDUixNQUFNLEVBQ04sU0FBUyxFQUNULFNBQVMsRUFDVCxpQkFBaUIsR0FDbEIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUF3QixpQkFBaUIsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRXpFLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUN2RCxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDckQsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLGdCQUFnQixDQUFDOzs7Ozs7QUFFdEMsTUFBTSxDQUFDLE1BQU0sZ0NBQWdDLEdBQUcsSUFBSSxjQUFjLENBQ2hFLCtCQUErQixDQUNoQyxDQUFDO0FBRUYsSUFBSSxNQUFNLEdBQUcsQ0FBQyxDQUFDO0FBRWYsTUFBTSxVQUFVLEdBQUcsWUFBWSxDQUFDO0FBQ2hDLE1BQU0sV0FBVyxHQUFHLGFBQWEsQ0FBQztBQUNsQyxNQUFNLFVBQVUsR0FBRyxZQUFZLENBQUM7QUFDaEMsTUFBTSxRQUFRLEdBQUcsVUFBVSxDQUFDO0FBK0Y1Qiw4REFBOEQ7QUFDOUQsTUFBTSxPQUFPLHFCQUFxQjtJQWdFaEMsWUFDVSxRQUFtQixFQUNuQixNQUFrQixFQUdsQix5QkFBa0M7UUFKbEMsYUFBUSxHQUFSLFFBQVEsQ0FBVztRQUNuQixXQUFNLEdBQU4sTUFBTSxDQUFZO1FBR2xCLDhCQUF5QixHQUF6Qix5QkFBeUIs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QU07dUJBQUMsT0FBTztnQkFHZixPQUFPO3NCQUROLFNBQVM7dUJBQUMsT0FBTztnQkFHbEIsSUFBSTtzQkFESCxLQUFLO2dCQUdOLEtBQUs7c0JBREosS0FBSztnQkFHTixPQUFPO3NCQUROLEtBQUs7Z0JBR04sR0FBRztzQkFERixLQUFLO2dCQUdOLEdBQUc7c0JBREYsS0FBSztnQkFHTixJQUFJO3NCQURILEtBQUs7Z0JBR04sSUFBSTtzQkFESCxLQUFLO2dCQUdOLEVBQUU7c0JBREQsS0FBSztnQkFJTixZQUFZO3NCQURYLEtBQUs7dUJBQUMsV0FBVztnQkFJbEIsV0FBVztzQkFGVixXQUFXO3VCQUFDLHVCQUF1Qjs7c0JBQ25DLEtBQUs7Z0JBR04sWUFBWTtzQkFEWCxLQUFLO2dCQUlOLElBQUk7c0JBRkgsV0FBVzt1QkFBQyxpQ0FBaUM7O3NCQUM3QyxLQUFLO2dCQUdOLFFBQVE7c0JBRFAsS0FBSztnQkFHTixTQUFTO3NCQURSLEtBQUs7Z0JBR04sV0FBVztzQkFEVixXQUFXO3VCQUFDLHFCQUFxQjtnQkFHbEMsVUFBVTtzQkFEVCxXQUFXO3VCQUFDLG1CQUFtQjtnQkErQm5CLEtBQUs7c0JBQWpCLEtBQUs7Z0JBT0YsUUFBUTtzQkFEWCxLQUFLO2dCQVVGLFFBQVE7c0JBRFgsS0FBSztnQkFVRixRQUFRO3NCQURYLEtBQUs7Z0JBVUYsU0FBUztzQkFEWixLQUFLO2dCQVdGLGVBQWU7c0JBRmxCLFdBQVc7dUJBQUMscUNBQXFDOztzQkFDakQsS0FBSzt1QkFBQyxnQkFBZ0I7Z0JBVW5CLElBQUk7c0JBRFAsS0FBSztnQkFVRixPQUFPO3NCQURWLEtBQUs7Z0JBVUYsNkJBQTZCO3NCQURoQyxLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ29tcG9uZW50LFxuICBEb0NoZWNrLFxuICBFbGVtZW50UmVmLFxuICBFdmVudEVtaXR0ZXIsXG4gIGZvcndhcmRSZWYsXG4gIEhvc3RCaW5kaW5nLFxuICBJbmplY3QsXG4gIEluamVjdGlvblRva2VuLFxuICBJbnB1dCxcbiAgT25DaGFuZ2VzLFxuICBPcHRpb25hbCxcbiAgT3V0cHV0LFxuICBSZW5kZXJlcjIsXG4gIFZpZXdDaGlsZCxcbiAgVmlld0VuY2Fwc3VsYXRpb24sXG59IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XG5pbXBvcnQgeyBDb250cm9sVmFsdWVBY2Nlc3NvciwgTkdfVkFMVUVfQUNDRVNTT1IgfSBmcm9tIFwiQGFuZ3VsYXIvZm9ybXNcIjtcblxuaW1wb3J0IHsgdG9Cb29sZWFuIH0gZnJvbSBcIi4uL2NvbW1vbi9ib29sZWFuLXByb3BlcnR5XCI7XG5pbXBvcnQgeyB0b051bWJlciB9IGZyb20gXCIuLi9jb21tb24vbnVtYmVyLnByb3BlcnR5XCI7XG5pbXBvcnQgeyBub29wIH0gZnJvbSBcIi4uL2NvbW1vbi9ub29wXCI7XG5cbmV4cG9ydCBjb25zdCBESVNBQkxFX05BVElWRV9WQUxJRElUWV9DSEVDS0lORyA9IG5ldyBJbmplY3Rpb25Ub2tlbjxib29sZWFuPihcbiAgXCJkaXNhYmxlTmF0aXZlVmFsaWRpdHlDaGVja2luZ1wiXG4pO1xuXG5sZXQgbmV4dElkID0gMDtcblxuY29uc3QgSVNfRk9DVVNFRCA9IFwiaXMtZm9jdXNlZFwiO1xuY29uc3QgSVNfRElTQUJMRUQgPSBcImlzLWRpc2FibGVkXCI7XG5jb25zdCBJU19JTlZBTElEID0gXCJpcy1pbnZhbGlkXCI7XG5jb25zdCBJU19ESVJUWSA9IFwiaXMtZGlydHlcIjtcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiBcIm1kbC10ZXh0ZmllbGRcIixcbiAgdGVtcGxhdGU6IGBcbiAgICA8ZGl2ICpuZ0lmPVwiIWljb25cIj5cbiAgICAgIDx0ZXh0YXJlYVxuICAgICAgICAqbmdJZj1cInJvd3NcIlxuICAgICAgICAjaW5wdXRcbiAgICAgICAgW3Jvd3NdPVwicm93c1wiXG4gICAgICAgIGNsYXNzPVwibWRsLXRleHRmaWVsZF9faW5wdXRcIlxuICAgICAgICB0eXBlPVwidGV4dFwiXG4gICAgICAgIFthdHRyLm5hbWVdPVwibmFtZVwiXG4gICAgICAgIFtpZF09XCJpZFwiXG4gICAgICAgIFtwbGFjZWhvbGRlcl09XCJwbGFjZWhvbGRlciA/IHBsYWNlaG9sZGVyIDogJydcIlxuICAgICAgICAoZm9jdXMpPVwib25Gb2N1cygkZXZlbnQpXCJcbiAgICAgICAgKGJsdXIpPVwib25CbHVyKCRldmVudClcIlxuICAgICAgICAoa2V5ZG93bik9XCJrZXlkb3duVGV4dGFyZWEoJGV2ZW50KVwiXG4gICAgICAgIChrZXl1cCk9XCJvbktleXVwKCRldmVudClcIlxuICAgICAgICBbKG5nTW9kZWwpXT1cInZhbHVlXCJcbiAgICAgICAgW2Rpc2FibGVkXT1cImRpc2FibGVkXCJcbiAgICAgICAgW3JlcXVpcmVkXT1cInJlcXVpcmVkXCJcbiAgICAgICAgW2F1dG9mb2N1c109XCJhdXRvZm9jdXNcIlxuICAgICAgICBbcmVhZG9ubHldPVwicmVhZG9ubHlcIlxuICAgICAgICBbbWF4bGVuZ3RoXT1cIm1heGxlbmd0aFwiXG4gICAgICA+PC90ZXh0YXJlYT5cbiAgICAgIDxpbnB1dFxuICAgICAgICAqbmdJZj1cIiFyb3dzXCJcbiAgICAgICAgI2lucHV0XG4gICAgICAgIGNsYXNzPVwibWRsLXRleHRmaWVsZF9faW5wdXRcIlxuICAgICAgICBbdHlwZV09XCJ0eXBlXCJcbiAgICAgICAgW2F0dHIubmFtZV09XCJuYW1lXCJcbiAgICAgICAgW2lkXT1cImlkXCJcbiAgICAgICAgW3BhdHRlcm5dPVwicGF0dGVybiA/IHBhdHRlcm4gOiAnLionXCJcbiAgICAgICAgW2F0dHIubWluXT1cIm1pblwiXG4gICAgICAgIFthdHRyLm1heF09XCJtYXhcIlxuICAgICAgICBbYXR0ci5zdGVwXT1cInN0ZXBcIlxuICAgICAgICBbcGxhY2Vob2xkZXJdPVwicGxhY2Vob2xkZXIgPyBwbGFjZWhvbGRlciA6ICcnXCJcbiAgICAgICAgW2F1dG9jb21wbGV0ZV09XCJhdXRvY29tcGxldGUgPyBhdXRvY29tcGxldGUgOiAnJ1wiXG4gICAgICAgIChmb2N1cyk9XCJvbkZvY3VzKCRldmVudClcIlxuICAgICAgICAoYmx1cik9XCJvbkJsdXIoJGV2ZW50KVwiXG4gICAgICAgIChrZXl1cCk9XCJvbktleXVwKCRldmVudClcIlxuICAgICAgICBbKG5nTW9kZWwpXT1cInZhbHVlXCJcbiAgICAgICAgW2Rpc2FibGVkXT1cImRpc2FibGVkXCJcbiAgICAgICAgW3JlcXVpcmVkXT1cInJlcXVpcmVkXCJcbiAgICAgICAgW2F1dG9mb2N1c109XCJhdXRvZm9jdXNcIlxuICAgICAgICBbcmVhZG9ubHldPVwicmVhZG9ubHlcIlxuICAgICAgICBbYXR0ci50YWJpbmRleF09XCJ0YWJpbmRleFwiXG4gICAgICAgIFttYXhsZW5ndGhdPVwibWF4bGVuZ3RoXCJcbiAgICAgIC8+XG4gICAgICA8bGFiZWwgY2xhc3M9XCJtZGwtdGV4dGZpZWxkX19sYWJlbFwiIFthdHRyLmZvcl09XCJpZFwiPnt7IGxhYmVsIH19PC9sYWJlbD5cbiAgICAgIDxzcGFuIGNsYXNzPVwibWRsLXRleHRmaWVsZF9fZXJyb3JcIj57eyBlcnJvck1lc3NhZ2UgfX08L3NwYW4+XG4gICAgPC9kaXY+XG4gICAgPGRpdiAqbmdJZj1cImljb25cIj5cbiAgICAgIDxidXR0b24gbWRsLWJ1dHRvbiBtZGwtYnV0dG9uLXR5cGU9XCJpY29uXCIgKGNsaWNrKT1cInNldEZvY3VzKClcIj5cbiAgICAgICAgPG1kbC1pY29uPnt7IGljb24gfX08L21kbC1pY29uPlxuICAgICAgPC9idXR0b24+XG4gICAgICA8ZGl2IGNsYXNzPVwibWRsLXRleHRmaWVsZF9fZXhwYW5kYWJsZS1ob2xkZXJcIj5cbiAgICAgICAgPGlucHV0XG4gICAgICAgICAgI2lucHV0XG4gICAgICAgICAgY2xhc3M9XCJtZGwtdGV4dGZpZWxkX19pbnB1dFwiXG4gICAgICAgICAgW3R5cGVdPVwidHlwZVwiXG4gICAgICAgICAgW2F0dHIubmFtZV09XCJuYW1lXCJcbiAgICAgICAgICBbaWRdPVwiaWRcIlxuICAgICAgICAgIFtwYXR0ZXJuXT1cInBhdHRlcm4gPyBwYXR0ZXJuIDogJy4qJ1wiXG4gICAgICAgICAgW2F0dHIubWluXT1cIm1pblwiXG4gICAgICAgICAgW2F0dHIubWF4XT1cIm1heFwiXG4gICAgICAgICAgW2F0dHIuc3RlcF09XCJzdGVwXCJcbiAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwicGxhY2Vob2xkZXIgPyBwbGFjZWhvbGRlciA6ICcnXCJcbiAgICAgICAgICBbYXV0b2NvbXBsZXRlXT1cImF1dG9jb21wbGV0ZSA/IGF1dG9jb21wbGV0ZSA6ICcnXCJcbiAgICAgICAgICAoZm9jdXMpPVwib25Gb2N1cygkZXZlbnQpXCJcbiAgICAgICAgICAoYmx1cik9XCJvbkJsdXIoJGV2ZW50KVwiXG4gICAgICAgICAgKGtleXVwKT1cIm9uS2V5dXAoJGV2ZW50KVwiXG4gICAgICAgICAgWyhuZ01vZGVsKV09XCJ2YWx1ZVwiXG4gICAgICAgICAgW2Rpc2FibGVkXT1cImRpc2FibGVkXCJcbiAgICAgICAgICBbcmVxdWlyZWRdPVwicmVxdWlyZWRcIlxuICAgICAgICAgIFthdXRvZm9jdXNdPVwiYXV0b2ZvY3VzXCJcbiAgICAgICAgICBbcmVhZG9ubHldPVwicmVhZG9ubHlcIlxuICAgICAgICAgIFthdHRyLnRhYmluZGV4XT1cInRhYmluZGV4XCJcbiAgICAgICAgICBbbWF4bGVuZ3RoXT1cIm1heGxlbmd0aFwiXG4gICAgICAgIC8+XG4gICAgICAgIDxsYWJlbCBjbGFzcz1cIm1kbC10ZXh0ZmllbGRfX2xhYmVsXCIgW2F0dHIuZm9yXT1cImlkXCI+e3sgbGFiZWwgfX08L2xhYmVsPlxuICAgICAgICA8c3BhbiBjbGFzcz1cIm1kbC10ZXh0ZmllbGRfX2Vycm9yXCI+e3sgZXJyb3JNZXNzYWdlIH19PC9zcGFuPlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gIGAsXG4gIHByb3ZpZGVyczogW1xuICAgIHtcbiAgICAgIHByb3ZpZGU6IE5HX1ZBTFVFX0FDQ0VTU09SLFxuICAgICAgdXNlRXhpc3Rpbmc6IGZvcndhcmRSZWYoKCkgPT4gTWRsVGV4dEZpZWxkQ29tcG9uZW50KSxcbiAgICAgIG11bHRpOiB0cnVlLFxuICAgIH0sXG4gIF0sXG4gIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXG59KVxuLyogZXNsaW50LWRpc2FibGUgIEBhbmd1bGFyLWVzbGludC9uby1jb25mbGljdGluZy1saWZlY3ljbGUgKi9cbmV4cG9ydCBjbGFzcyBNZGxUZXh0RmllbGRDb21wb25lbnRcbiAgaW1wbGVtZW50cyBDb250cm9sVmFsdWVBY2Nlc3NvciwgT25DaGFuZ2VzLCBEb0NoZWNrXG57XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZVxuICBAT3V0cHV0KFwiYmx1clwiKVxuICBibHVyRW1pdHRlcjogRXZlbnRFbWl0dGVyPEZvY3VzRXZlbnQ+ID0gbmV3IEV2ZW50RW1pdHRlcjxGb2N1c0V2ZW50PigpO1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmVcbiAgQE91dHB1dChcImZvY3VzXCIpXG4gIGZvY3VzRW1pdHRlcjogRXZlbnRFbWl0dGVyPEZvY3VzRXZlbnQ+ID0gbmV3IEV2ZW50RW1pdHRlcjxGb2N1c0V2ZW50PigpO1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmVcbiAgQE91dHB1dChcImtleXVwXCIpXG4gIGtleXVwRW1pdHRlcjogRXZlbnRFbWl0dGVyPEtleWJvYXJkRXZlbnQ+ID0gbmV3IEV2ZW50RW1pdHRlcjxLZXlib2FyZEV2ZW50PigpO1xuICBAVmlld0NoaWxkKFwiaW5wdXRcIilcbiAgaW5wdXRFbDogRWxlbWVudFJlZiB8IHVuZGVmaW5lZDtcbiAgQElucHV0KClcbiAgdHlwZSA9IFwidGV4dFwiO1xuICBASW5wdXQoKVxuICBsYWJlbDogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICBASW5wdXQoKVxuICBwYXR0ZXJuOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gIEBJbnB1dCgpXG4gIG1pbjogbnVtYmVyIHwgc3RyaW5nIHwgdW5kZWZpbmVkO1xuICBASW5wdXQoKVxuICBtYXg6IG51bWJlciB8IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgQElucHV0KClcbiAgc3RlcDogbnVtYmVyIHwgc3RyaW5nIHwgdW5kZWZpbmVkO1xuICBASW5wdXQoKVxuICBuYW1lOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gIEBJbnB1dCgpXG4gIGlkID0gYG1kbC10ZXh0ZmllbGQtJHtuZXh0SWQrK31gO1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmVcbiAgQElucHV0KFwiZXJyb3ItbXNnXCIpXG4gIGVycm9yTWVzc2FnZTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICBASG9zdEJpbmRpbmcoXCJjbGFzcy5oYXMtcGxhY2Vob2xkZXJcIilcbiAgQElucHV0KClcbiAgcGxhY2Vob2xkZXI6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgQElucHV0KClcbiAgYXV0b2NvbXBsZXRlOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gIEBIb3N0QmluZGluZyhcImNsYXNzLm1kbC10ZXh0ZmllbGQtLWV4cGFuZGFibGVcIilcbiAgQElucHV0KClcbiAgaWNvbjogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICBASW5wdXQoKVxuICB0YWJpbmRleDogbnVtYmVyIHwgc3RyaW5nIHwgbnVsbCA9IG51bGw7XG4gIEBJbnB1dCgpXG4gIG1heGxlbmd0aDogbnVtYmVyIHwgc3RyaW5nIHwgbnVsbCA9IG51bGw7XG4gIEBIb3N0QmluZGluZyhcImNsYXNzLm1kbC10ZXh0ZmllbGRcIilcbiAgaXNUZXh0ZmllbGQgPSB0cnVlO1xuICBASG9zdEJpbmRpbmcoXCJjbGFzcy5pcy11cGdyYWRlZFwiKVxuICBpc1VwZ3JhZGVkID0gdHJ1ZTtcbiAgcHJpdmF0ZSB2YWx1ZUludGVybjogc3RyaW5nIHwgbnVtYmVyIHwgbnVsbCA9IG51bGw7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBlbDogSFRNTEVsZW1lbnQ7XG4gIHByaXZhdGUgb25Ub3VjaGVkQ2FsbGJhY2s6ICgpID0+IHZvaWQgPSBub29wO1xuICBwcml2YXRlIG9uQ2hhbmdlQ2FsbGJhY2s6IChfOiB1bmtub3duKSA9PiB2b2lkID0gbm9vcDtcbiAgcHJpdmF0ZSBkaXNhYmxlZEludGVybiA9IGZhbHNlO1xuICBwcml2YXRlIHJlYWRvbmx5SW50ZXJuID0gZmFsc2U7XG4gIHByaXZhdGUgcmVxdWlyZWRJbnRlcm4gPSBmYWxzZTtcbiAgcHJpdmF0ZSBhdXRvZm9jdXNJbnRlcm4gPSBmYWxzZTtcbiAgcHJpdmF0ZSBpc0Zsb2F0aW5nTGFiZWxJbnRlcm4gPSBmYWxzZTtcbiAgcHJpdmF0ZSByb3dzSW50ZXJuOiBudW1iZXIgfCB1bmRlZmluZWQgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBtYXhyb3dzSW50ZXJuID0gLTE7XG4gIC8vIEBleHBlcmltZW50YWxcbiAgcHJpdmF0ZSBkaXNhYmxlTmF0aXZlVmFsaWRpdHlDaGVja2luZ0ludGVybiA9IGZhbHNlO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVuZGVyZXI6IFJlbmRlcmVyMixcbiAgICBwcml2YXRlIGVsbVJlZjogRWxlbWVudFJlZixcbiAgICBAT3B0aW9uYWwoKVxuICAgIEBJbmplY3QoRElTQUJMRV9OQVRJVkVfVkFMSURJVFlfQ0hFQ0tJTkcpXG4gICAgcHJpdmF0ZSBuYXRpdmVDaGVja0dsb2JhbERpc2FibGVkOiBib29sZWFuXG4gICkge1xuICAgIHRoaXMuZWwgPSBlbG1SZWYubmF0aXZlRWxlbWVudDtcbiAgfVxuXG4gIGdldCB2YWx1ZSgpOiBzdHJpbmcgfCBudW1iZXIgfCBudWxsIHtcbiAgICByZXR1cm4gdGhpcy52YWx1ZUludGVybjtcbiAgfVxuXG4gIEBJbnB1dCgpIHNldCB2YWx1ZSh2OiBzdHJpbmcgfCBudW1iZXIgfCBudWxsKSB7XG4gICAgdGhpcy52YWx1ZUludGVybiA9XG4gICAgICB0aGlzLnR5cGUgPT09IFwibnVtYmVyXCIgPyAodiA9PT0gXCJcIiA/IG51bGwgOiBwYXJzZUZsb2F0KHYgYXMgc3RyaW5nKSkgOiB2O1xuICAgIHRoaXMub25DaGFuZ2VDYWxsYmFjayh0aGlzLnZhbHVlKTtcbiAgfVxuXG4gIEBJbnB1dCgpXG4gIGdldCBkaXNhYmxlZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5kaXNhYmxlZEludGVybjtcbiAgfVxuXG4gIHNldCBkaXNhYmxlZCh2YWx1ZTogYm9vbGVhbiB8IHN0cmluZykge1xuICAgIHRoaXMuZGlzYWJsZWRJbnRlcm4gPSB0b0Jvb2xlYW4odmFsdWUpO1xuICB9XG5cbiAgQElucHV0KClcbiAgZ2V0IHJlYWRvbmx5KCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnJlYWRvbmx5SW50ZXJuO1xuICB9XG5cbiAgc2V0IHJlYWRvbmx5KHZhbHVlOiBib29sZWFuKSB7XG4gICAgdGhpcy5yZWFkb25seUludGVybiA9IHRvQm9vbGVhbih2YWx1ZSk7XG4gIH1cblxuICBASW5wdXQoKVxuICBnZXQgcmVxdWlyZWQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWlyZWRJbnRlcm47XG4gIH1cblxuICBzZXQgcmVxdWlyZWQodmFsdWU6IGJvb2xlYW4gfCBzdHJpbmcpIHtcbiAgICB0aGlzLnJlcXVpcmVkSW50ZXJuID0gdG9Cb29sZWFuKHZhbHVlKTtcbiAgfVxuXG4gIEBJbnB1dCgpXG4gIGdldCBhdXRvZm9jdXMoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuYXV0b2ZvY3VzSW50ZXJuO1xuICB9XG5cbiAgc2V0IGF1dG9mb2N1cyh2YWx1ZTogYm9vbGVhbiB8IHN0cmluZykge1xuICAgIHRoaXMuYXV0b2ZvY3VzSW50ZXJuID0gdG9Cb29sZWFuKHZhbHVlKTtcbiAgfVxuXG4gIEBIb3N0QmluZGluZyhcImNsYXNzLm1kbC10ZXh0ZmllbGQtLWZsb2F0aW5nLWxhYmVsXCIpXG4gIEBJbnB1dChcImZsb2F0aW5nLWxhYmVsXCIpXG4gIGdldCBpc0Zsb2F0aW5nTGFiZWwoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuaXNGbG9hdGluZ0xhYmVsSW50ZXJuO1xuICB9XG5cbiAgc2V0IGlzRmxvYXRpbmdMYWJlbCh2YWx1ZTogYm9vbGVhbiB8IHN0cmluZykge1xuICAgIHRoaXMuaXNGbG9hdGluZ0xhYmVsSW50ZXJuID0gdG9Cb29sZWFuKHZhbHVlKTtcbiAgfVxuXG4gIEBJbnB1dCgpXG4gIGdldCByb3dzKCk6IG51bWJlciB8IHN0cmluZyB8IG51bGwgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLnJvd3NJbnRlcm47XG4gIH1cblxuICBzZXQgcm93cyh2YWx1ZTogbnVtYmVyIHwgc3RyaW5nIHwgbnVsbCB8IHVuZGVmaW5lZCkge1xuICAgIHRoaXMucm93c0ludGVybiA9IHRvTnVtYmVyKHZhbHVlKTtcbiAgfVxuXG4gIEBJbnB1dCgpXG4gIGdldCBtYXhyb3dzKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMubWF4cm93c0ludGVybjtcbiAgfVxuXG4gIHNldCBtYXhyb3dzKHZhbHVlOiBudW1iZXIgfCBzdHJpbmcgfCBudWxsKSB7XG4gICAgdGhpcy5tYXhyb3dzSW50ZXJuID0gdG9OdW1iZXIodmFsdWUpID8/IC0xO1xuICB9XG5cbiAgQElucHV0KClcbiAgZ2V0IGRpc2FibGVOYXRpdmVWYWxpZGl0eUNoZWNraW5nKCk6IGJvb2xlYW4gfCBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLmRpc2FibGVOYXRpdmVWYWxpZGl0eUNoZWNraW5nSW50ZXJuO1xuICB9XG5cbiAgc2V0IGRpc2FibGVOYXRpdmVWYWxpZGl0eUNoZWNraW5nKHZhbHVlOiBib29sZWFuIHwgc3RyaW5nKSB7XG4gICAgdGhpcy5kaXNhYmxlTmF0aXZlVmFsaWRpdHlDaGVja2luZ0ludGVybiA9IHRvQm9vbGVhbih2YWx1ZSk7XG4gIH1cblxuICBwdWJsaWMgd3JpdGVWYWx1ZSh2YWx1ZTogc3RyaW5nIHwgbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy52YWx1ZUludGVybiA9IHZhbHVlO1xuICAgIHRoaXMuY2hlY2tEaXJ0eSgpO1xuICB9XG5cbiAgcHVibGljIHJlZ2lzdGVyT25DaGFuZ2UoZm46ICgpID0+IHVua25vd24pOiB2b2lkIHtcbiAgICB0aGlzLm9uQ2hhbmdlQ2FsbGJhY2sgPSBmbjtcbiAgfVxuXG4gIHB1YmxpYyByZWdpc3Rlck9uVG91Y2hlZChmbjogKCkgPT4gdW5rbm93bik6IHZvaWQge1xuICAgIHRoaXMub25Ub3VjaGVkQ2FsbGJhY2sgPSBmbjtcbiAgfVxuXG4gIHB1YmxpYyBzZXREaXNhYmxlZFN0YXRlKGlzRGlzYWJsZWQ6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICB0aGlzLmRpc2FibGVkID0gaXNEaXNhYmxlZDtcbiAgfVxuXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAYW5ndWxhci1lc2xpbnQvbm8tY29uZmxpY3RpbmctbGlmZWN5Y2xlXG4gIG5nT25DaGFuZ2VzKCk6IHZvaWQge1xuICAgIHRoaXMuY2hlY2tEaXNhYmxlZCgpO1xuICB9XG5cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEBhbmd1bGFyLWVzbGludC9uby1jb25mbGljdGluZy1saWZlY3ljbGVcbiAgbmdEb0NoZWNrKCk6IHZvaWQge1xuICAgIHRoaXMuY2hlY2tWYWxpZGl0eSgpO1xuICAgIHRoaXMuY2hlY2tEaXJ0eSgpO1xuICB9XG5cbiAgc2V0Rm9jdXMoKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLmlucHV0RWwpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgKHRoaXMuaW5wdXRFbC5uYXRpdmVFbGVtZW50IGFzIEhUTUxJbnB1dEVsZW1lbnQpLmRpc3BhdGNoRXZlbnQoXG4gICAgICBuZXcgRXZlbnQoXCJmb2N1c1wiKVxuICAgICk7XG4gIH1cblxuICBrZXlkb3duVGV4dGFyZWEoJGV2ZW50OiBLZXlib2FyZEV2ZW50KTogdm9pZCB7XG4gICAgY29uc3QgY3VycmVudFJvd0NvdW50ID1cbiAgICAgIHRoaXMuaW5wdXRFbD8ubmF0aXZlRWxlbWVudC52YWx1ZS5zcGxpdChcIlxcblwiKS5sZW5ndGg7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lXG4gICAgaWYgKCRldmVudC5rZXlDb2RlID09PSAxMykge1xuICAgICAgaWYgKGN1cnJlbnRSb3dDb3VudCA+PSB0aGlzLm1heHJvd3MgJiYgdGhpcy5tYXhyb3dzICE9PSAtMSkge1xuICAgICAgICAkZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBtb2RlbCB2YWx1ZS5cbiAgdHJpZ2dlckNoYW5nZShldmVudDogRXZlbnQpOiB2b2lkIHtcbiAgICB0aGlzLnZhbHVlID0gKGV2ZW50LnRhcmdldCBhcyBIVE1MSW5wdXRFbGVtZW50KS52YWx1ZTtcbiAgICB0aGlzLm9uVG91Y2hlZENhbGxiYWNrKCk7XG4gIH1cblxuICBvbkZvY3VzKGV2ZW50OiBGb2N1c0V2ZW50KTogdm9pZCB7XG4gICAgdGhpcy5yZW5kZXJlci5hZGRDbGFzcyh0aGlzLmVsLCBJU19GT0NVU0VEKTtcbiAgICB0aGlzLmZvY3VzRW1pdHRlci5lbWl0KGV2ZW50KTtcbiAgfVxuXG4gIG9uQmx1cihldmVudDogRm9jdXNFdmVudCk6IHZvaWQge1xuICAgIHRoaXMucmVuZGVyZXIucmVtb3ZlQ2xhc3ModGhpcy5lbCwgSVNfRk9DVVNFRCk7XG4gICAgdGhpcy5vblRvdWNoZWRDYWxsYmFjaygpO1xuICAgIHRoaXMuYmx1ckVtaXR0ZXIuZW1pdChldmVudCk7XG4gIH1cblxuICBvbktleXVwKGV2ZW50OiBLZXlib2FyZEV2ZW50KTogdm9pZCB7XG4gICAgdGhpcy5rZXl1cEVtaXR0ZXIuZW1pdChldmVudCk7XG4gIH1cblxuICBwcml2YXRlIGNoZWNrRGlzYWJsZWQoKSB7XG4gICAgaWYgKHRoaXMuZGlzYWJsZWQpIHtcbiAgICAgIHRoaXMucmVuZGVyZXIuYWRkQ2xhc3ModGhpcy5lbCwgSVNfRElTQUJMRUQpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnJlbmRlcmVyLnJlbW92ZUNsYXNzKHRoaXMuZWwsIElTX0RJU0FCTEVEKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGNoZWNrVmFsaWRpdHkoKSB7XG4gICAgLy8gY2hlY2sgdGhlIGdsb2JhbCBzZXR0aW5nIC0gaWYgZ2xvYmFsbHkgZGlzYWJsZWQgZG8gbm8gY2hlY2tcbiAgICBpZiAodGhpcy5uYXRpdmVDaGVja0dsb2JhbERpc2FibGVkID09PSB0cnVlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIC8vIGNoZWNrIGxvY2FsIHNldHRpbmcgLSBpZiBsb2NhbGx5IGRpc2FibGVkIGRvIG5vIGNoZWNrXG4gICAgaWYgKHRoaXMuZGlzYWJsZU5hdGl2ZVZhbGlkaXR5Q2hlY2tpbmcpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHRoaXMuaW5wdXRFbCAmJiB0aGlzLmlucHV0RWwubmF0aXZlRWxlbWVudC52YWxpZGl0eSkge1xuICAgICAgaWYgKCF0aGlzLmlucHV0RWwubmF0aXZlRWxlbWVudC52YWxpZGl0eS52YWxpZCkge1xuICAgICAgICB0aGlzLnJlbmRlcmVyLmFkZENsYXNzKHRoaXMuZWwsIElTX0lOVkFMSUQpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5yZW5kZXJlci5yZW1vdmVDbGFzcyh0aGlzLmVsLCBJU19JTlZBTElEKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGNoZWNrRGlydHkoKSB7XG4gICAgY29uc3QgZGlydHkgPVxuICAgICAgdGhpcy5pbnB1dEVsICYmXG4gICAgICB0aGlzLmlucHV0RWwubmF0aXZlRWxlbWVudC52YWx1ZSAmJlxuICAgICAgdGhpcy5pbnB1dEVsLm5hdGl2ZUVsZW1lbnQudmFsdWUubGVuZ3RoID4gMDtcbiAgICBpZiAoZGlydHkpIHtcbiAgICAgIHRoaXMucmVuZGVyZXIuYWRkQ2xhc3ModGhpcy5lbCwgSVNfRElSVFkpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnJlbmRlcmVyLnJlbW92ZUNsYXNzKHRoaXMuZWwsIElTX0RJUlRZKTtcbiAgICB9XG4gIH1cbn1cbiJdfQ==