UNPKG

kwikui

Version:

KwikID's UI Component Library in Angular

296 lines 43.1 kB
import { Component, EventEmitter, forwardRef, Input, Output } from "@angular/core"; import { FormControl, FormGroup, NG_VALUE_ACCESSOR } from "@angular/forms"; import { TUI_DATE_FORMAT, TUI_DATE_SEPARATOR, TuiDay } from "@taiga-ui/cdk"; import { checkObjectKeyExists, isNotEmptyValue, isNull } from "kwikid-toolkit"; import { Subscription } from "rxjs"; import { distinctUntilChanged } from "rxjs/operators"; import { throwErrorMessage } from "../../../../helpers/kwikui.common.helpers"; import { DEFAULT_VALUES, VALIDATE_KEY_VALUES } from "./input-date.constants"; import { isValidKeyValue } from "./input-date.validation"; import * as i0 from "@angular/core"; import * as i1 from "@taiga-ui/kit"; import * as i2 from "@taiga-ui/core"; import * as i3 from "@angular/forms"; import * as i4 from "@angular/common"; export class KwikUIInputDateComponent { constructor() { this.disabled = DEFAULT_VALUES.disabled; this.focus = DEFAULT_VALUES.focus; this.formControl = new FormControl({}); this.formControlName = DEFAULT_VALUES.formControlName; this.hintContent = DEFAULT_VALUES.hintContent; this.icon = DEFAULT_VALUES.icon; this.id = DEFAULT_VALUES.id; this.invalid = DEFAULT_VALUES.invalid; this.label = DEFAULT_VALUES.label; this.max = DEFAULT_VALUES.max; this.maxCalculatedFromToday = DEFAULT_VALUES.maxCalculatedFromToday; this.min = DEFAULT_VALUES.min; this.minCalculatedFromToday = { year: 0, month: 0, day: 0 }; this.placeholder = DEFAULT_VALUES.placeholder; this.postfix = DEFAULT_VALUES.postfix; this.prefix = DEFAULT_VALUES.prefix; this.properties = { readOnly: false }; this.size = DEFAULT_VALUES.size; this.validators = { required: true }; this.getKeyValue = new EventEmitter(); this.formGroup = new FormGroup({}); this.subscriptions = new Subscription(); } ngOnInit() { this.formGroup.addControl(this.formControlName, this.formControl); this.focus = this.focus === undefined ? false : this.focus; this.invalid = this.invalid === undefined ? false : this.invalid && this.focus; this.validators = Object.assign({}, this.validators); this.properties = Object.assign({}, this.properties); this.setDisabled(); this.min = isNotEmptyValue(this.min) ? new TuiDay(this.min.year, this.min.month, this.min.day) : this.calculateMinDateFromToday(this.minCalculatedFromToday); this.max = isNotEmptyValue(this.max) ? new TuiDay(this.max.year, this.max.month, this.max.day) : this.calculateMaxDateFromToday(this.maxCalculatedFromToday); this.subscriptions.add(this.formGroup.controls[this.formControlName].valueChanges .pipe(distinctUntilChanged()) // makes sure the value has actually changed. .subscribe((value) => this.handleInputValueChange(value))); } ngOnChanges(changes) { const verifyChange = (key) => { return changes.hasOwnProperty(key) && !changes[key].firstChange; }; for (const change of Object.entries(changes)) { const key = change[0]; const value = change[1].currentValue; this.validateInputProperty(key, value); } if (verifyChange("minCalculatedFromToday")) { this.min = isNotEmptyValue(this.min) ? new TuiDay(this.min.year, this.min.month, this.min.day) : this.calculateMinDateFromToday(this.minCalculatedFromToday); } if (verifyChange("maxCalculatedFromToday")) { this.max = isNotEmptyValue(this.max) ? new TuiDay(this.max.year, this.max.month, this.max.day) : this.calculateMaxDateFromToday(this.maxCalculatedFromToday); } if (verifyChange("formControl")) { this.formControl = changes.formControl.currentValue; } if (verifyChange("invalid")) { this.invalid = Boolean(changes.invalid.currentValue); this.setError(); } if (verifyChange("focus")) { this.focus = Boolean(changes.focus.currentValue); } if (verifyChange("disabled")) { this.disabled = Boolean(changes.disabled.currentValue); this.setDisabled(); } } ngOnDestroy() { this.subscriptions.unsubscribe(); // ensure when component is destroyed the subscription is also and not left open. } validateInputProperty(key, value) { if (VALIDATE_KEY_VALUES[key] && !isValidKeyValue(key, value)) { this[key] = DEFAULT_VALUES[key]; throwErrorMessage("kwikui-input-date", this.id, key, value, DEFAULT_VALUES[key]); } } /** * @description Handles setting up of error and focus on the input field is it is invalid */ setDisabled() { if (this.formGroup.controls[this.formControlName] !== undefined) { if (this.disabled === true) { this.formGroup.controls[this.formControlName].disable({ emitEvent: false }); } else { this.formGroup.controls[this.formControlName].enable({ emitEvent: false }); } } } /** * @description Handles setting up of error and focus on the input field is it is invalid */ setReset() { this.formGroup.controls[this.formControlName].reset(); } /** * @description Handles setting up of error and focus on the input field is it is invalid */ setError() { if (this.formGroup.controls[this.formControlName] !== undefined && this.formGroup.controls[this.formControlName].invalid) { this.invalid = true; this.focus = true; } else { this.invalid = false; this.focus = false; } } /** * @description Handles firing of 2 events on (keyup) event * * @param value */ handleInputValueChange(value) { if (isNull(value)) { this.emitEvent(this.getKeyValue, { key: this.formControlName, value: null }); } else { const dateValue = new Date(value.year, value.month, value.day); const minDateValue = new Date(this.min.year, this.min.month, this.min.day); const maxDateValue = new Date(this.max.year, this.max.month, this.max.day); if (minDateValue <= dateValue && maxDateValue >= dateValue) { this.invalid = false; this.focus = false; if (value === this.formControl.value) { this.emitEvent(this.getKeyValue, { key: this.formControlName, value: this.formControl.value }); } } else { this.setReset(); this.setError(); } } } handleFocusedChange(e) { if (!this.invalid) { this.focus = e; } } /** * Calculates the TuiDay object for the min date based on the minCalculatedFromToday input * @returns TuiDay */ calculateMinDateFromToday(minCalculatedFromToday) { const currentDate = new Date(); let minYear = 0; let minMonth = 0; let minDay = 1; if (checkObjectKeyExists(minCalculatedFromToday, "year")) { minYear = Number(currentDate.getFullYear() - minCalculatedFromToday.year); } if (checkObjectKeyExists(minCalculatedFromToday, "month")) { minMonth = Number(currentDate.getMonth() - minCalculatedFromToday.month); } if (checkObjectKeyExists(minCalculatedFromToday, "day")) { minDay = Number(currentDate.getDate() - minCalculatedFromToday.day); } const targetDate = new Date(minYear, minMonth, minDay); const minDate = new TuiDay(targetDate.getFullYear(), targetDate.getMonth(), targetDate.getDate()); return minDate; } /** * Calculates the TuiDay object for the max date based on the maxCalculatedFromToday input * @returns TuiDay */ calculateMaxDateFromToday(maxCalculatedFromToday) { const currentDate = new Date(); let maxYear = 9999; let maxMonth = 11; let maxDay = 31; if (checkObjectKeyExists(maxCalculatedFromToday, "year")) { maxYear = Number(currentDate.getFullYear() + maxCalculatedFromToday.year); } if (checkObjectKeyExists(maxCalculatedFromToday, "month")) { maxMonth = Number(currentDate.getMonth() + maxCalculatedFromToday.month); } if (checkObjectKeyExists(maxCalculatedFromToday, "day")) { maxDay = Number(currentDate.getDate() + maxCalculatedFromToday.day); } const targetDate = new Date(maxYear, maxMonth, maxDay); const maxDate = new TuiDay(targetDate.getFullYear(), targetDate.getMonth(), targetDate.getDate()); return maxDate; } emitEvent(event, data) { event.emit(data); } /** Method Implementations for Abstract Control */ writeValue(value) { } registerOnChange(fn) { } registerOnTouched(fn) { } setDisabledState(isDisabled) { } } /** @nocollapse */ KwikUIInputDateComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: KwikUIInputDateComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); /** @nocollapse */ KwikUIInputDateComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.17", type: KwikUIInputDateComponent, selector: "kwikui-input-date", inputs: { disabled: "disabled", focus: "focus", formControl: "formControl", formControlName: "formControlName", hintContent: "hintContent", icon: "icon", id: "id", invalid: "invalid", label: "label", max: "max", maxCalculatedFromToday: "maxCalculatedFromToday", min: "min", minCalculatedFromToday: "minCalculatedFromToday", placeholder: "placeholder", postfix: "postfix", prefix: "prefix", properties: "properties", size: "size", validators: "validators" }, outputs: { getKeyValue: "getKeyValue" }, providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef((() => KwikUIInputDateComponent)), multi: true }, { provide: TUI_DATE_FORMAT, useValue: `DMY` }, { provide: TUI_DATE_SEPARATOR, useValue: `-` } ], usesOnChanges: true, ngImport: i0, template: "<div [formGroup]=\"formGroup\">\n <tui-input-date\n tuiUnfinishedValidator=\"Finish filling the field\"\n [formControlName]=\"formControlName\"\n [max]=\"max\"\n [min]=\"min\"\n [nativeId]=\"id\"\n [pseudoFocus]=\"focus ?? null\"\n [pseudoInvalid]=\"invalid === undefined ? null : invalid\"\n [readOnly]=\"properties?.readOnly ?? false\"\n [tuiHintContent]=\"hintContent\"\n [tuiTextfieldCleaner]=\"true\"\n [tuiTextfieldIconLeft]=\"icon\"\n [tuiTextfieldPostfix]=\"postfix\"\n [tuiTextfieldPrefix]=\"prefix\"\n [tuiTextfieldSize]=\"size\"\n (focusedChange)=\"handleFocusedChange($event)\"\n >\n {{ label }}\n <span\n class=\"tui-required\"\n *ngIf=\"validators.required\"\n ></span>\n <input\n tuiTextfield\n [attr.placeholder]=\"placeholder ?? ''\"\n [attr.required]=\"validators.required\"\n />\n </tui-input-date>\n</div>\n", styles: [""], components: [{ type: i1.TuiInputDateComponent, selector: "tui-input-date:not([multiple])", inputs: ["min", "max", "disabledItemHandler", "markerHandler", "items", "defaultActiveYearMonth"] }, { type: i2.TuiTextfieldComponent, selector: "input[tuiTextfield], textarea[tuiTextfield]" }], directives: [{ type: i3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i1.TuiInputDateDirective, selector: "tui-input-date:not([multiple])" }, { type: i1.TuiUnfinishedValidatorDirective, selector: "[tuiUnfinishedValidator]" }, { type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i3.FormControlName, selector: "[formControlName]", inputs: ["disabled", "formControlName", "ngModel"], outputs: ["ngModelChange"] }, { type: i2.TuiHintOptionsDirective, selector: "[tuiHintContent]", inputs: ["tuiHintContent", "tuiHintDirection", "tuiHintAppearance", "tuiHintShowDelay", "tuiHintHideDelay"] }, { type: i2.TuiTextfieldCleanerDirective, selector: "[tuiTextfieldCleaner]", inputs: ["tuiTextfieldCleaner"] }, { type: i2.TuiTextfieldIconLeftDirective, selector: "[tuiTextfieldIconLeft]", inputs: ["tuiTextfieldIconLeft"] }, { type: i2.TuiTextfieldPostfixDirective, selector: "[tuiTextfieldPostfix]", inputs: ["tuiTextfieldPostfix"] }, { type: i2.TuiTextfieldPrefixDirective, selector: "[tuiTextfieldPrefix]", inputs: ["tuiTextfieldPrefix"] }, { type: i2.TuiTextfieldSizeDirective, selector: "[tuiTextfieldSize]", inputs: ["tuiTextfieldSize"] }, { type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: KwikUIInputDateComponent, decorators: [{ type: Component, args: [{ selector: "kwikui-input-date", templateUrl: "./input-date.component.html", styleUrls: ["./input-date.component.scss"], providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef((() => KwikUIInputDateComponent)), multi: true }, { provide: TUI_DATE_FORMAT, useValue: `DMY` }, { provide: TUI_DATE_SEPARATOR, useValue: `-` } ] }] }], ctorParameters: function () { return []; }, propDecorators: { disabled: [{ type: Input }], focus: [{ type: Input }], formControl: [{ type: Input }], formControlName: [{ type: Input }], hintContent: [{ type: Input }], icon: [{ type: Input }], id: [{ type: Input }], invalid: [{ type: Input }], label: [{ type: Input }], max: [{ type: Input }], maxCalculatedFromToday: [{ type: Input }], min: [{ type: Input }], minCalculatedFromToday: [{ type: Input }], placeholder: [{ type: Input }], postfix: [{ type: Input }], prefix: [{ type: Input }], properties: [{ type: Input }], size: [{ type: Input }], validators: [{ type: Input }], getKeyValue: [{ type: Output }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5wdXQtZGF0ZS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9rd2lrdWkvc3JjL2xpYi9jb21wb25lbnRzL2NvcmUvaW5wdXRzL2lucHV0LWRhdGUvaW5wdXQtZGF0ZS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9rd2lrdWkvc3JjL2xpYi9jb21wb25lbnRzL2NvcmUvaW5wdXRzL2lucHV0LWRhdGUvaW5wdXQtZGF0ZS5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsU0FBUyxFQUNULFlBQVksRUFDWixVQUFVLEVBQ1YsS0FBSyxFQUdMLE1BQU0sRUFFUCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBRUwsV0FBVyxFQUNYLFNBQVMsRUFDVCxpQkFBaUIsRUFDbEIsTUFBTSxnQkFBZ0IsQ0FBQztBQUN4QixPQUFPLEVBQUUsZUFBZSxFQUFFLGtCQUFrQixFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUM1RSxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsZUFBZSxFQUFFLE1BQU0sRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQy9FLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDcEMsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDdEQsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sMkNBQTJDLENBQUM7QUFDOUUsT0FBTyxFQUFFLGNBQWMsRUFBRSxtQkFBbUIsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBRTdFLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQzs7Ozs7O0FBZ0IxRCxNQUFNLE9BQU8sd0JBQXdCO0lBc0RuQztRQXBEUyxhQUFRLEdBQVksY0FBYyxDQUFDLFFBQVEsQ0FBQztRQUU1QyxVQUFL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QU8sRUFBRSxlQUFlLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBRTt3QkFDN0MsRUFBRSxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsUUFBUSxFQUFFLEdBQUcsRUFBRTtxQkFDL0M7aUJBQ0Y7MEVBR1UsUUFBUTtzQkFBaEIsS0FBSztnQkFFRyxLQUFLO3NCQUFiLEtBQUs7Z0JBRUcsV0FBVztzQkFBbkIsS0FBSztnQkFFRyxlQUFlO3NCQUF2QixLQUFLO2dCQUVHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBRUcsSUFBSTtzQkFBWixLQUFLO2dCQUVHLEVBQUU7c0JBQVYsS0FBSztnQkFFRyxPQUFPO3NCQUFmLEtBQUs7Z0JBRUcsS0FBSztzQkFBYixLQUFLO2dCQUVHLEdBQUc7c0JBQVgsS0FBSztnQkFFRyxzQkFBc0I7c0JBQTlCLEtBQUs7Z0JBTUcsR0FBRztzQkFBWCxLQUFLO2dCQUVHLHNCQUFzQjtzQkFBOUIsS0FBSztnQkFNRyxXQUFXO3NCQUFuQixLQUFLO2dCQUVHLE9BQU87c0JBQWYsS0FBSztnQkFFRyxNQUFNO3NCQUFkLEtBQUs7Z0JBRUcsVUFBVTtzQkFBbEIsS0FBSztnQkFFRyxJQUFJO3NCQUFaLEtBQUs7Z0JBRUcsVUFBVTtzQkFBbEIsS0FBSztnQkFFSSxXQUFXO3NCQUFwQixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ29tcG9uZW50LFxuICBFdmVudEVtaXR0ZXIsXG4gIGZvcndhcmRSZWYsXG4gIElucHV0LFxuICBPbkNoYW5nZXMsXG4gIE9uSW5pdCxcbiAgT3V0cHV0LFxuICBTaW1wbGVDaGFuZ2VzXG59IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XG5pbXBvcnQge1xuICBDb250cm9sVmFsdWVBY2Nlc3NvcixcbiAgRm9ybUNvbnRyb2wsXG4gIEZvcm1Hcm91cCxcbiAgTkdfVkFMVUVfQUNDRVNTT1Jcbn0gZnJvbSBcIkBhbmd1bGFyL2Zvcm1zXCI7XG5pbXBvcnQgeyBUVUlfREFURV9GT1JNQVQsIFRVSV9EQVRFX1NFUEFSQVRPUiwgVHVpRGF5IH0gZnJvbSBcIkB0YWlnYS11aS9jZGtcIjtcbmltcG9ydCB7IGNoZWNrT2JqZWN0S2V5RXhpc3RzLCBpc05vdEVtcHR5VmFsdWUsIGlzTnVsbCB9IGZyb20gXCJrd2lraWQtdG9vbGtpdFwiO1xuaW1wb3J0IHsgU3Vic2NyaXB0aW9uIH0gZnJvbSBcInJ4anNcIjtcbmltcG9ydCB7IGRpc3RpbmN0VW50aWxDaGFuZ2VkIH0gZnJvbSBcInJ4anMvb3BlcmF0b3JzXCI7XG5pbXBvcnQgeyB0aHJvd0Vycm9yTWVzc2FnZSB9IGZyb20gXCIuLi8uLi8uLi8uLi9oZWxwZXJzL2t3aWt1aS5jb21tb24uaGVscGVyc1wiO1xuaW1wb3J0IHsgREVGQVVMVF9WQUxVRVMsIFZBTElEQVRFX0tFWV9WQUxVRVMgfSBmcm9tIFwiLi9pbnB1dC1kYXRlLmNvbnN0YW50c1wiO1xuaW1wb3J0IHsgVEt3aWtVSUlucHV0RGF0ZVNpemUgfSBmcm9tIFwiLi9pbnB1dC1kYXRlLmRlZmluaXRpb25zXCI7XG5pbXBvcnQgeyBpc1ZhbGlkS2V5VmFsdWUgfSBmcm9tIFwiLi9pbnB1dC1kYXRlLnZhbGlkYXRpb25cIjtcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiBcImt3aWt1aS1pbnB1dC1kYXRlXCIsXG4gIHRlbXBsYXRlVXJsOiBcIi4vaW5wdXQtZGF0ZS5jb21wb25lbnQuaHRtbFwiLFxuICBzdHlsZVVybHM6IFtcIi4vaW5wdXQtZGF0ZS5jb21wb25lbnQuc2Nzc1wiXSxcbiAgcHJvdmlkZXJzOiBbXG4gICAge1xuICAgICAgcHJvdmlkZTogTkdfVkFMVUVfQUNDRVNTT1IsXG4gICAgICB1c2VFeGlzdGluZzogZm9yd2FyZFJlZigoKSA9PiBLd2lrVUlJbnB1dERhdGVDb21wb25lbnQpLFxuICAgICAgbXVsdGk6IHRydWVcbiAgICB9LFxuICAgIHsgcHJvdmlkZTogVFVJX0RBVEVfRk9STUFULCB1c2VWYWx1ZTogYERNWWAgfSxcbiAgICB7IHByb3ZpZGU6IFRVSV9EQVRFX1NFUEFSQVRPUiwgdXNlVmFsdWU6IGAtYCB9XG4gIF1cbn0pXG5leHBvcnQgY2xhc3MgS3dpa1VJSW5wdXREYXRlQ29tcG9uZW50XG4gIGltcGxlbWVudHMgT25Jbml0LCBPbkNoYW5nZXMsIENvbnRyb2xWYWx1ZUFjY2Vzc29yIHtcbiAgQElucHV0KCkgZGlzYWJsZWQ6IGJvb2xlYW4gPSBERUZBVUxUX1ZBTFVFUy5kaXNhYmxlZDtcblxuICBASW5wdXQoKSBmb2N1czogYm9vbGVhbiA9IERFRkFVTFRfVkFMVUVTLmZvY3VzO1xuXG4gIEBJbnB1dCgpIGZvcm1Db250cm9sOiBGb3JtQ29udHJvbCA9IG5ldyBGb3JtQ29udHJvbCh7fSk7XG5cbiAgQElucHV0KCkgZm9ybUNvbnRyb2xOYW1lOiBzdHJpbmcgPSBERUZBVUxUX1ZBTFVFUy5mb3JtQ29udHJvbE5hbWU7XG5cbiAgQElucHV0KCkgaGludENvbnRlbnQ6IHN0cmluZyA9IERFRkFVTFRfVkFMVUVTLmhpbnRDb250ZW50O1xuXG4gIEBJbnB1dCgpIGljb246IHN0cmluZyA9IERFRkFVTFRfVkFMVUVTLmljb247XG5cbiAgQElucHV0KCkgaWQ6IHN0cmluZyA9IERFRkFVTFRfVkFMVUVTLmlkO1xuXG4gIEBJbnB1dCgpIGludmFsaWQ6IGJvb2xlYW4gPSBERUZBVUxUX1ZBTFVFUy5pbnZhbGlkO1xuXG4gIEBJbnB1dCgpIGxhYmVsOiBzdHJpbmcgPSBERUZBVUxUX1ZBTFVFUy5sYWJlbDtcblxuICBASW5wdXQoKSBtYXg6IGFueSA9IERFRkFVTFRfVkFMVUVTLm1heDtcblxuICBASW5wdXQoKSBtYXhDYWxjdWxhdGVkRnJvbVRvZGF5OiB7XG4gICAgeWVhcj86IG51bWJlcjtcbiAgICBtb250aD86IG51bWJlcjtcbiAgICBkYXk/OiBudW1iZXI7XG4gIH0gPSBERUZBVUxUX1ZBTFVFUy5tYXhDYWxjdWxhdGVkRnJvbVRvZGF5O1xuXG4gIEBJbnB1dCgpIG1pbjogYW55ID0gREVGQVVMVF9WQUxVRVMubWluO1xuXG4gIEBJbnB1dCgpIG1pbkNhbGN1bGF0ZWRGcm9tVG9kYXk6IHtcbiAgICB5ZWFyPzogbnVtYmVyO1xuICAgIG1vbnRoPzogbnVtYmVyO1xuICAgIGRheT86IG51bWJlcjtcbiAgfSA9IHsgeWVhcjogMCwgbW9udGg6IDAsIGRheTogMCB9O1xuXG4gIEBJbnB1dCgpIHBsYWNlaG9sZGVyOiBzdHJpbmcgPSBERUZBVUxUX1ZBTFVFUy5wbGFjZWhvbGRlcjtcblxuICBASW5wdXQoKSBwb3N0Zml4OiBzdHJpbmcgPSBERUZBVUxUX1ZBTFVFUy5wb3N0Zml4O1xuXG4gIEBJbnB1dCgpIHByZWZpeDogc3RyaW5nID0gREVGQVVMVF9WQUxVRVMucHJlZml4O1xuXG4gIEBJbnB1dCgpIHByb3BlcnRpZXMgPSB7IHJlYWRPbmx5OiBmYWxzZSB9O1xuXG4gIEBJbnB1dCgpIHNpemU6IFRLd2lrVUlJbnB1dERhdGVTaXplID0gREVGQVVMVF9WQUxVRVMuc2l6ZTtcblxuICBASW5wdXQoKSB2YWxpZGF0b3JzID0geyByZXF1aXJlZDogdHJ1ZSB9O1xuXG4gIEBPdXRwdXQoKSBnZXRLZXlWYWx1ZTogRXZlbnRFbWl0dGVyPGFueT4gPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcblxuICBmb3JtR3JvdXA6IEZvcm1Hcm91cCA9IG5ldyBGb3JtR3JvdXAoe30pO1xuXG4gIHN1YnNjcmlwdGlvbnMgPSBuZXcgU3Vic2NyaXB0aW9uKCk7XG5cbiAgY29uc3RydWN0b3IoKSB7fVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIHRoaXMuZm9ybUdyb3VwLmFkZENvbnRyb2wodGhpcy5mb3JtQ29udHJvbE5hbWUsIHRoaXMuZm9ybUNvbnRyb2wpO1xuICAgIHRoaXMuZm9jdXMgPSB0aGlzLmZvY3VzID09PSB1bmRlZmluZWQgPyBmYWxzZSA6IHRoaXMuZm9jdXM7XG4gICAgdGhpcy5pbnZhbGlkID1cbiAgICAgIHRoaXMuaW52YWxpZCA9PT0gdW5kZWZpbmVkID8gZmFsc2UgOiB0aGlzLmludmFsaWQgJiYgdGhpcy5mb2N1cztcbiAgICB0aGlzLnZhbGlkYXRvcnMgPSB7IC4uLnRoaXMudmFsaWRhdG9ycyB9O1xuICAgIHRoaXMucHJvcGVydGllcyA9IHsgLi4udGhpcy5wcm9wZXJ0aWVzIH07XG4gICAgdGhpcy5zZXREaXNhYmxlZCgpO1xuXG4gICAgdGhpcy5taW4gPSBpc05vdEVtcHR5VmFsdWUodGhpcy5taW4pXG4gICAgICA/IG5ldyBUdWlEYXkodGhpcy5taW4ueWVhciwgdGhpcy5taW4ubW9udGgsIHRoaXMubWluLmRheSlcbiAgICAgIDogdGhpcy5jYWxjdWxhdGVNaW5EYXRlRnJvbVRvZGF5KHRoaXMubWluQ2FsY3VsYXRlZEZyb21Ub2RheSk7XG4gICAgdGhpcy5tYXggPSBpc05vdEVtcHR5VmFsdWUodGhpcy5tYXgpXG4gICAgICA/IG5ldyBUdWlEYXkodGhpcy5tYXgueWVhciwgdGhpcy5tYXgubW9udGgsIHRoaXMubWF4LmRheSlcbiAgICAgIDogdGhpcy5jYWxjdWxhdGVNYXhEYXRlRnJvbVRvZGF5KHRoaXMubWF4Q2FsY3VsYXRlZEZyb21Ub2RheSk7XG5cbiAgICB0aGlzLnN1YnNjcmlwdGlvbnMuYWRkKFxuICAgICAgdGhpcy5mb3JtR3JvdXAuY29udHJvbHNbdGhpcy5mb3JtQ29udHJvbE5hbWVdLnZhbHVlQ2hhbmdlc1xuICAgICAgICAucGlwZShkaXN0aW5jdFVudGlsQ2hhbmdlZCgpKSAvLyBtYWtlcyBzdXJlIHRoZSB2YWx1ZSBoYXMgYWN0dWFsbHkgY2hhbmdlZC5cbiAgICAgICAgLnN1YnNjcmliZSgodmFsdWUpID0+IHRoaXMuaGFuZGxlSW5wdXRWYWx1ZUNoYW5nZSh2YWx1ZSkpXG4gICAgKTtcbiAgfVxuXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpIHtcbiAgICBjb25zdCB2ZXJpZnlDaGFuZ2UgPSAoa2V5OiBzdHJpbmcpID0+IHtcbiAgICAgIHJldHVybiBjaGFuZ2VzLmhhc093blByb3BlcnR5KGtleSkgJiYgIWNoYW5nZXNba2V5XS5maXJzdENoYW5nZTtcbiAgICB9O1xuXG4gICAgZm9yIChjb25zdCBjaGFuZ2Ugb2YgT2JqZWN0LmVudHJpZXMoY2hhbmdlcykpIHtcbiAgICAgIGNvbnN0IGtleTogc3RyaW5nID0gY2hhbmdlWzBdO1xuICAgICAgY29uc3QgdmFsdWU6IGFueSA9IGNoYW5nZVsxXS5jdXJyZW50VmFsdWU7XG4gICAgICB0aGlzLnZhbGlkYXRlSW5wdXRQcm9wZXJ0eShrZXksIHZhbHVlKTtcbiAgICB9XG5cbiAgICBpZiAodmVyaWZ5Q2hhbmdlKFwibWluQ2FsY3VsYXRlZEZyb21Ub2RheVwiKSkge1xuICAgICAgdGhpcy5taW4gPSBpc05vdEVtcHR5VmFsdWUodGhpcy5taW4pXG4gICAgICAgID8gbmV3IFR1aURheSh0aGlzLm1pbi55ZWFyLCB0aGlzLm1pbi5tb250aCwgdGhpcy5taW4uZGF5KVxuICAgICAgICA6IHRoaXMuY2FsY3VsYXRlTWluRGF0ZUZyb21Ub2RheSh0aGlzLm1pbkNhbGN1bGF0ZWRGcm9tVG9kYXkpO1xuICAgIH1cbiAgICBpZiAodmVyaWZ5Q2hhbmdlKFwibWF4Q2FsY3VsYXRlZEZyb21Ub2RheVwiKSkge1xuICAgICAgdGhpcy5tYXggPSBpc05vdEVtcHR5VmFsdWUodGhpcy5tYXgpXG4gICAgICAgID8gbmV3IFR1aURheSh0aGlzLm1heC55ZWFyLCB0aGlzLm1heC5tb250aCwgdGhpcy5tYXguZGF5KVxuICAgICAgICA6IHRoaXMuY2FsY3VsYXRlTWF4RGF0ZUZyb21Ub2RheSh0aGlzLm1heENhbGN1bGF0ZWRGcm9tVG9kYXkpO1xuICAgIH1cblxuICAgIGlmICh2ZXJpZnlDaGFuZ2UoXCJmb3JtQ29udHJvbFwiKSkge1xuICAgICAgdGhpcy5mb3JtQ29udHJvbCA9IGNoYW5nZXMuZm9ybUNvbnRyb2wuY3VycmVudFZhbHVlO1xuICAgIH1cbiAgICBpZiAodmVyaWZ5Q2hhbmdlKFwiaW52YWxpZFwiKSkge1xuICAgICAgdGhpcy5pbnZhbGlkID0gQm9vbGVhbihjaGFuZ2VzLmludmFsaWQuY3VycmVudFZhbHVlKTtcbiAgICAgIHRoaXMuc2V0RXJyb3IoKTtcbiAgICB9XG4gICAgaWYgKHZlcmlmeUNoYW5nZShcImZvY3VzXCIpKSB7XG4gICAgICB0aGlzLmZvY3VzID0gQm9vbGVhbihjaGFuZ2VzLmZvY3VzLmN1cnJlbnRWYWx1ZSk7XG4gICAgfVxuICAgIGlmICh2ZXJpZnlDaGFuZ2UoXCJkaXNhYmxlZFwiKSkge1xuICAgICAgdGhpcy5kaXNhYmxlZCA9IEJvb2xlYW4oY2hhbmdlcy5kaXNhYmxlZC5jdXJyZW50VmFsdWUpO1xuICAgICAgdGhpcy5zZXREaXNhYmxlZCgpO1xuICAgIH1cbiAgfVxuXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMuc3Vic2NyaXB0aW9ucy51bnN1YnNjcmliZSgpO1xuICAgIC8vIGVuc3VyZSB3aGVuIGNvbXBvbmVudCBpcyBkZXN0cm95ZWQgdGhlIHN1YnNjcmlwdGlvbiBpcyBhbHNvIGFuZCBub3QgbGVmdCBvcGVuLlxuICB9XG5cbiAgcHJpdmF0ZSB2YWxpZGF0ZUlucHV0UHJvcGVydHkoa2V5OiBzdHJpbmcsIHZhbHVlOiBhbnkpOiB2b2lkIHtcbiAgICBpZiAoVkFMSURBVEVfS0VZX1ZBTFVFU1trZXldICYmICFpc1ZhbGlkS2V5VmFsdWUoa2V5LCB2YWx1ZSkpIHtcbiAgICAgIHRoaXNba2V5XSA9IERFRkFVTFRfVkFMVUVTW2tleV07XG4gICAgICB0aHJvd0Vycm9yTWVzc2FnZShcbiAgICAgICAgXCJrd2lrdWktaW5wdXQtZGF0ZVwiLFxuICAgICAgICB0aGlzLmlkLFxuICAgICAgICBrZXksXG4gICAgICAgIHZhbHVlLFxuICAgICAgICBERUZBVUxUX1ZBTFVFU1trZXldXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gSGFuZGxlcyBzZXR0aW5nIHVwIG9mIGVycm9yIGFuZCBmb2N1cyBvbiB0aGUgaW5wdXQgZmllbGQgaXMgaXQgaXMgaW52YWxpZFxuICAgKi9cbiAgc2V0RGlzYWJsZWQoKSB7XG4gICAgaWYgKHRoaXMuZm9ybUdyb3VwLmNvbnRyb2xzW3RoaXMuZm9ybUNvbnRyb2xOYW1lXSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBpZiAodGhpcy5kaXNhYmxlZCA9PT0gdHJ1ZSkge1xuICAgICAgICB0aGlzLmZvcm1Hcm91cC5jb250cm9sc1t0aGlzLmZvcm1Db250cm9sTmFtZV0uZGlzYWJsZSh7XG4gICAgICAgICAgZW1pdEV2ZW50OiBmYWxzZVxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuZm9ybUdyb3VwLmNvbnRyb2xzW3RoaXMuZm9ybUNvbnRyb2xOYW1lXS5lbmFibGUoe1xuICAgICAgICAgIGVtaXRFdmVudDogZmFsc2VcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBIYW5kbGVzIHNldHRpbmcgdXAgb2YgZXJyb3IgYW5kIGZvY3VzIG9uIHRoZSBpbnB1dCBmaWVsZCBpcyBpdCBpcyBpbnZhbGlkXG4gICAqL1xuICBzZXRSZXNldCgpIHtcbiAgICB0aGlzLmZvcm1Hcm91cC5jb250cm9sc1t0aGlzLmZvcm1Db250cm9sTmFtZV0ucmVzZXQoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gSGFuZGxlcyBzZXR0aW5nIHVwIG9mIGVycm9yIGFuZCBmb2N1cyBvbiB0aGUgaW5wdXQgZmllbGQgaXMgaXQgaXMgaW52YWxpZFxuICAgKi9cbiAgc2V0RXJyb3IoKSB7XG4gICAgaWYgKFxuICAgICAgdGhpcy5mb3JtR3JvdXAuY29udHJvbHNbdGhpcy5mb3JtQ29udHJvbE5hbWVdICE9PSB1bmRlZmluZWQgJiZcbiAgICAgIHRoaXMuZm9ybUdyb3VwLmNvbnRyb2xzW3RoaXMuZm9ybUNvbnRyb2xOYW1lXS5pbnZhbGlkXG4gICAgKSB7XG4gICAgICB0aGlzLmludmFsaWQgPSB0cnVlO1xuICAgICAgdGhpcy5mb2N1cyA9IHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuaW52YWxpZCA9IGZhbHNlO1xuICAgICAgdGhpcy5mb2N1cyA9IGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gSGFuZGxlcyBmaXJpbmcgb2YgMiBldmVudHMgb24gKGtleXVwKSBldmVudFxuICAgKlxuICAgKiBAcGFyYW0gdmFsdWVcbiAgICovXG4gIGhhbmRsZUlucHV0VmFsdWVDaGFuZ2UodmFsdWU6IGFueSkge1xuICAgIGlmIChpc051bGwodmFsdWUpKSB7XG4gICAgICB0aGlzLmVtaXRFdmVudCh0aGlzLmdldEtleVZhbHVlLCB7XG4gICAgICAgIGtleTogdGhpcy5mb3JtQ29udHJvbE5hbWUsXG4gICAgICAgIHZhbHVlOiBudWxsXG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgZGF0ZVZhbHVlID0gbmV3IERhdGUodmFsdWUueWVhciwgdmFsdWUubW9udGgsIHZhbHVlLmRheSk7XG5cbiAgICAgIGNvbnN0IG1pbkRhdGVWYWx1ZSA9IG5ldyBEYXRlKFxuICAgICAgICB0aGlzLm1pbi55ZWFyLFxuICAgICAgICB0aGlzLm1pbi5tb250aCxcbiAgICAgICAgdGhpcy5taW4uZGF5XG4gICAgICApO1xuICAgICAgY29uc3QgbWF4RGF0ZVZhbHVlID0gbmV3IERhdGUoXG4gICAgICAgIHRoaXMubWF4LnllYXIsXG4gICAgICAgIHRoaXMubWF4Lm1vbnRoLFxuICAgICAgICB0aGlzLm1heC5kYXlcbiAgICAgICk7XG5cbiAgICAgIGlmIChtaW5EYXRlVmFsdWUgPD0gZGF0ZVZhbHVlICYmIG1heERhdGVWYWx1ZSA+PSBkYXRlVmFsdWUpIHtcbiAgICAgICAgdGhpcy5pbnZhbGlkID0gZmFsc2U7XG4gICAgICAgIHRoaXMuZm9jdXMgPSBmYWxzZTtcbiAgICAgICAgaWYgKHZhbHVlID09PSB0aGlzLmZvcm1Db250cm9sLnZhbHVlKSB7XG4gICAgICAgICAgdGhpcy5lbWl0RXZlbnQodGhpcy5nZXRLZXlWYWx1ZSwge1xuICAgICAgICAgICAga2V5OiB0aGlzLmZvcm1Db250cm9sTmFtZSxcbiAgICAgICAgICAgIHZhbHVlOiB0aGlzLmZvcm1Db250cm9sLnZhbHVlXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuc2V0UmVzZXQoKTtcbiAgICAgICAgdGhpcy5zZXRFcnJvcigpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGhhbmRsZUZvY3VzZWRDaGFuZ2UoZTogYW55KSB7XG4gICAgaWYgKCF0aGlzLmludmFsaWQpIHtcbiAgICAgIHRoaXMuZm9jdXMgPSBlO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDYWxjdWxhdGVzIHRoZSBUdWlEYXkgb2JqZWN0IGZvciB0aGUgbWluIGRhdGUgYmFzZWQgb24gdGhlIG1pbkNhbGN1bGF0ZWRGcm9tVG9kYXkgaW5wdXRcbiAgICogQHJldHVybnMgVHVpRGF5XG4gICAqL1xuICBjYWxjdWxhdGVNaW5EYXRlRnJvbVRvZGF5KG1pbkNhbGN1bGF0ZWRGcm9tVG9kYXk6IHtcbiAgICB5ZWFyPzogbnVtYmVyO1xuICAgIG1vbnRoPzogbnVtYmVyO1xuICAgIGRheT86IG51bWJlcjtcbiAgfSk6IFR1aURheSB7XG4gICAgY29uc3QgY3VycmVudERhdGUgPSBuZXcgRGF0ZSgpO1xuXG4gICAgbGV0IG1pblllYXIgPSAwO1xuICAgIGxldCBtaW5Nb250aCA9IDA7XG4gICAgbGV0IG1pbkRheSA9IDE7XG5cbiAgICBpZiAoY2hlY2tPYmplY3RLZXlFeGlzdHMobWluQ2FsY3VsYXRlZEZyb21Ub2RheSwgXCJ5ZWFyXCIpKSB7XG4gICAgICBtaW5ZZWFyID0gTnVtYmVyKGN1cnJlbnREYXRlLmdldEZ1bGxZZWFyKCkgLSBtaW5DYWxjdWxhdGVkRnJvbVRvZGF5LnllYXIpO1xuICAgIH1cbiAgICBpZiAoY2hlY2tPYmplY3RLZXlFeGlzdHMobWluQ2FsY3VsYXRlZEZyb21Ub2RheSwgXCJtb250aFwiKSkge1xuICAgICAgbWluTW9udGggPSBOdW1iZXIoY3VycmVudERhdGUuZ2V0TW9udGgoKSAtIG1pbkNhbGN1bGF0ZWRGcm9tVG9kYXkubW9udGgpO1xuICAgIH1cbiAgICBpZiAoY2hlY2tPYmplY3RLZXlFeGlzdHMobWluQ2FsY3VsYXRlZEZyb21Ub2RheSwgXCJkYXlcIikpIHtcbiAgICAgIG1pbkRheSA9IE51bWJlcihjdXJyZW50RGF0ZS5nZXREYXRlKCkgLSBtaW5DYWxjdWxhdGVkRnJvbVRvZGF5LmRheSk7XG4gICAgfVxuXG4gICAgY29uc3QgdGFyZ2V0RGF0ZSA9IG5ldyBEYXRlKG1pblllYXIsIG1pbk1vbnRoLCBtaW5EYXkpO1xuXG4gICAgY29uc3QgbWluRGF0ZSA9IG5ldyBUdWlEYXkoXG4gICAgICB0YXJnZXREYXRlLmdldEZ1bGxZZWFyKCksXG4gICAgICB0YXJnZXREYXRlLmdldE1vbnRoKCksXG4gICAgICB0YXJnZXREYXRlLmdldERhdGUoKVxuICAgICk7XG5cbiAgICByZXR1cm4gbWluRGF0ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDYWxjdWxhdGVzIHRoZSBUdWlEYXkgb2JqZWN0IGZvciB0aGUgbWF4IGRhdGUgYmFzZWQgb24gdGhlIG1heENhbGN1bGF0ZWRGcm9tVG9kYXkgaW5wdXRcbiAgICogQHJldHVybnMgVHVpRGF5XG4gICAqL1xuICBjYWxjdWxhdGVNYXhEYXRlRnJvbVRvZGF5KG1heENhbGN1bGF0ZWRGcm9tVG9kYXk6IHtcbiAgICB5ZWFyPzogbnVtYmVyO1xuICAgIG1vbnRoPzogbnVtYmVyO1xuICAgIGRheT86IG51bWJlcjtcbiAgfSk6IFR1aURheSB7XG4gICAgY29uc3QgY3VycmVudERhdGUgPSBuZXcgRGF0ZSgpO1xuXG4gICAgbGV0IG1heFllYXIgPSA5OTk5O1xuICAgIGxldCBtYXhNb250aCA9IDExO1xuICAgIGxldCBtYXhEYXkgPSAzMTtcblxuICAgIGlmIChjaGVja09iamVjdEtleUV4aXN0cyhtYXhDYWxjdWxhdGVkRnJvbVRvZGF5LCBcInllYXJcIikpIHtcbiAgICAgIG1heFllYXIgPSBOdW1iZXIoY3VycmVudERhdGUuZ2V0RnVsbFllYXIoKSArIG1heENhbGN1bGF0ZWRGcm9tVG9kYXkueWVhcik7XG4gICAgfVxuICAgIGlmIChjaGVja09iamVjdEtleUV4aXN0cyhtYXhDYWxjdWxhdGVkRnJvbVRvZGF5LCBcIm1vbnRoXCIpKSB7XG4gICAgICBtYXhNb250aCA9IE51bWJlcihjdXJyZW50RGF0ZS5nZXRNb250aCgpICsgbWF4Q2FsY3VsYXRlZEZyb21Ub2RheS5tb250aCk7XG4gICAgfVxuICAgIGlmIChjaGVja09iamVjdEtleUV4aXN0cyhtYXhDYWxjdWxhdGVkRnJvbVRvZGF5LCBcImRheVwiKSkge1xuICAgICAgbWF4RGF5ID0gTnVtYmVyKGN1cnJlbnREYXRlLmdldERhdGUoKSArIG1heENhbGN1bGF0ZWRGcm9tVG9kYXkuZGF5KTtcbiAgICB9XG4gICAgY29uc3QgdGFyZ2V0RGF0ZSA9IG5ldyBEYXRlKG1heFllYXIsIG1heE1vbnRoLCBtYXhEYXkpO1xuXG4gICAgY29uc3QgbWF4RGF0ZSA9IG5ldyBUdWlEYXkoXG4gICAgICB0YXJnZXREYXRlLmdldEZ1bGxZZWFyKCksXG4gICAgICB0YXJnZXREYXRlLmdldE1vbnRoKCksXG4gICAgICB0YXJnZXREYXRlLmdldERhdGUoKVxuICAgICk7XG5cbiAgICByZXR1cm4gbWF4RGF0ZTtcbiAgfVxuXG4gIGVtaXRFdmVudChldmVudDogYW55LCBkYXRhOiBhbnkpIHtcbiAgICBldmVudC5lbWl0KGRhdGEpO1xuICB9XG5cbiAgLyoqIE1ldGhvZCBJbXBsZW1lbnRhdGlvbnMgZm9yIEFic3RyYWN0IENvbnRyb2wgKi9cbiAgd3JpdGVWYWx1ZSh2YWx1ZTogYW55KTogdm9pZCB7fVxuXG4gIHJlZ2lzdGVyT25DaGFuZ2UoZm46IGFueSk6IHZvaWQge31cblxuICByZWdpc3Rlck9uVG91Y2hlZChmbjogYW55KTogdm9pZCB7fVxuXG4gIHNldERpc2FibGVkU3RhdGU/KGlzRGlzYWJsZWQ6IGJvb2xlYW4pOiB2b2lkIHt9XG59XG4iLCI8ZGl2IFtmb3JtR3JvdXBdPVwiZm9ybUdyb3VwXCI+XG4gIDx0dWktaW5wdXQtZGF0ZVxuICAgIHR1aVVuZmluaXNoZWRWYWxpZGF0b3I9XCJGaW5pc2ggZmlsbGluZyB0aGUgZmllbGRcIlxuICAgIFtmb3JtQ29udHJvbE5hbWVdPVwiZm9ybUNvbnRyb2xOYW1lXCJcbiAgICBbbWF4XT1cIm1heFwiXG4gICAgW21pbl09XCJtaW5cIlxuICAgIFtuYXRpdmVJZF09XCJpZFwiXG4gICAgW3BzZXVkb0ZvY3VzXT1cImZvY3VzID8/IG51bGxcIlxuICAgIFtwc2V1ZG9JbnZhbGlkXT1cImludmFsaWQgPT09IHVuZGVmaW5lZCA/IG51bGwgOiBpbnZhbGlkXCJcbiAgICBbcmVhZE9ubHldPVwicHJvcGVydGllcz8ucmVhZE9ubHkgPz8gZmFsc2VcIlxuICAgIFt0dWlIaW50Q29udGVudF09XCJoaW50Q29udGVudFwiXG4gICAgW3R1aVRleHRmaWVsZENsZWFuZXJdPVwidHJ1ZVwiXG4gICAgW3R1aVRleHRmaWVsZEljb25MZWZ0XT1cImljb25cIlxuICAgIFt0dWlUZXh0ZmllbGRQb3N0Zml4XT1cInBvc3RmaXhcIlxuICAgIFt0dWlUZXh0ZmllbGRQcmVmaXhdPVwicHJlZml4XCJcbiAgICBbdHVpVGV4dGZpZWxkU2l6ZV09XCJzaXplXCJcbiAgICAoZm9jdXNlZENoYW5nZSk9XCJoYW5kbGVGb2N1c2VkQ2hhbmdlKCRldmVudClcIlxuICA+XG4gICAge3sgbGFiZWwgfX1cbiAgICA8c3BhblxuICAgICAgY2xhc3M9XCJ0dWktcmVxdWlyZWRcIlxuICAgICAgKm5nSWY9XCJ2YWxpZGF0b3JzLnJlcXVpcmVkXCJcbiAgICA+PC9zcGFuPlxuICAgIDxpbnB1dFxuICAgICAgdHVpVGV4dGZpZWxkXG4gICAgICBbYXR0ci5wbGFjZWhvbGRlcl09XCJwbGFjZWhvbGRlciA/PyAnJ1wiXG4gICAgICBbYXR0ci5yZXF1aXJlZF09XCJ2YWxpZGF0b3JzLnJlcXVpcmVkXCJcbiAgICAvPlxuICA8L3R1aS1pbnB1dC1kYXRlPlxuPC9kaXY+XG4iXX0=