truly-ui
Version:
Web Components for Desktop Applications.
307 lines (305 loc) • 42.2 kB
JavaScript
/*
MIT License
Copyright (c) 2019 Temainfo Software
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
import { Component, EventEmitter, Inject, Input, LOCALE_ID, Optional, Output, Self, ViewChild } from '@angular/core';
import { TlInput } from '../input/input';
import { TlCalendar } from '../calendar/calendar';
import { ReverseFormatDate } from '../core/helper/reverseformatdate';
import { KeyEvent } from '../core/enums/key-events';
import { ValueAccessorBase } from '../input/core/value-accessor';
import { Subscription } from 'rxjs';
import * as i0 from "@angular/core";
import * as i1 from "@angular/forms";
import * as i2 from "@angular/cdk/overlay";
import * as i3 from "../date/directives/date.directive";
import * as i4 from "../input/input";
import * as i5 from "./datepicker-content/datepicker-content";
export class TlDatePicker extends ValueAccessorBase {
constructor(changes, locale, ngControl) {
super();
this.changes = changes;
this.locale = locale;
this.ngControl = ngControl;
this.label = '';
this.name = '';
this.labelSize = '';
this.textAlign = 'left';
this.isoDate = true;
this.labelPlacement = 'left';
this.formatDate = 'dd/mm/yyyy';
this.readonly = false;
this.disabled = false;
this.placeholder = 'Datepicker Field';
this.clearButton = true;
this.autoClose = false;
this.openOnFocus = true;
this.holidays = [];
this.selectDay = new EventEmitter();
this.completeMask = new EventEmitter();
this.isOpen = false;
this.positionOverlay = '';
this.description = '';
this.date = new Date();
this.year = new Date().getFullYear();
this.month = new Date().getMonth();
this.day = new Date().getDate();
this.subscription = new Subscription();
this.setControl();
}
get control() {
return this.ngControl.control;
}
setControl() {
if (this.ngControl) {
this.ngControl.valueAccessor = this;
}
}
ngOnInit() {
this.setDateMask();
}
ngAfterContentInit() {
this.decomposeDate(this.value);
this.listenControlChanges();
}
listenControlChanges() {
if (this.control) {
this.subscription.add(this.control.valueChanges.subscribe((date) => {
if (!this.isOpen && date) {
this.decomposeDate(date);
return;
}
if (!date) {
this.description = null;
}
}));
}
}
decomposeDate(date) {
if (date && this.value) {
const dateStr = new Date(date).toLocaleDateString(this.locale, { timeZone: 'UTC' });
const formatted = ReverseFormatDate(this.stringUnmasked(dateStr), this.formatDate);
this.description = this.getFormattedDate(formatted);
this.setDateObject(formatted);
}
}
setDateMask() {
this.tlInput.mask = this.getMask();
}
setDateObject(dateObject) {
this.day = dateObject.day;
this.month = dateObject.month - 1;
this.year = dateObject.year;
}
getMask() {
const format = this.formatDate.toLowerCase();
const dd = format.replace('dd', '00');
const mm = dd.replace('mm', '00');
return mm.replace('yyyy', '0000');
}
getObjectValues() {
return {
day: this.day,
fullDate: this.date,
month: this.month,
year: this.year
};
}
handleAutoClose() {
if (this.autoClose) {
this.isOpen = false;
}
}
handleOpenOnFocus() {
if (this.openOnFocus) {
this.isOpen = true;
}
}
getFormattedDate($event) {
let strDate;
const date = this.formatDate;
strDate = date.replace('dd', this.formatDayAndMonth($event.day));
strDate = strDate.replace('mm', this.formatDayAndMonth($event.month));
strDate = strDate.replace('yyyy', $event.year);
return strDate;
}
setValue($event) {
this.description = this.getFormattedDate({ ...$event, month: $event.month + 1 });
this.value = $event.fullDate.toISOString();
}
formatDayAndMonth(value) {
if (String(value).length === 1) {
return `0${value}`;
}
return value;
}
handleDateChange() {
const date = ReverseFormatDate(this.description, this.formatDate);
if (!isNaN(date.day) && !isNaN(date.month) && !isNaN(date.year)) {
this.setDateObject(date);
this.date = new Date(date.year, date.month - 1, date.day);
this.changes.detectChanges();
}
}
onBlur() {
this.propagateTouched();
}
onCompleteMask() {
const timeout = setTimeout(() => {
this.handleDateChange();
if (this.isoDate) {
this.value = this.getObjectValues().fullDate.toISOString();
}
else {
this.value = this.getObjectValues().fullDate;
}
this.changes.detectChanges();
this.completeMask.emit(this.getObjectValues());
clearTimeout(timeout);
}, 500);
}
onDateInputFocus() {
if (this.value && !this.isOpen) {
const inputDate = ReverseFormatDate(this.stringUnmasked(this.description), this.formatDate);
this.setDateObject(inputDate);
}
this.handleOpenOnFocus();
}
onSelectDay($event) {
this.setDateObject($event);
this.date = $event.fullDate;
this.selectDay.emit($event);
this.setValue($event);
this.handleAutoClose();
this.changes.detectChanges();
}
onPositionChange($event) {
this.positionOverlay = $event.connectionPair.originY;
}
onBackDropClick() {
this.isOpen = false;
}
onClearInput($event) {
this.value = null;
$event.stopPropagation();
}
handleArrowKeys($event) {
const object = {
[KeyEvent.ARROWUP]: () => this.handleArrowUp($event),
[KeyEvent.ARROWDOWN]: () => this.handleArrowDown($event),
[KeyEvent.TAB]: () => this.handleTab(),
[KeyEvent.ESCAPE]: () => this.handleEscape($event),
[KeyEvent.ARROWRIGHT]: () => $event.preventDefault(),
[KeyEvent.ARROWLEFT]: () => $event.preventDefault(),
};
if (object[$event]) {
object[$event]();
}
}
handleArrowUp($event) {
if (this.isOpen) {
$event.preventDefault();
$event.stopPropagation();
}
}
handleTab() {
if (this.isOpen) {
this.isOpen = false;
this.changes.detectChanges();
}
}
handleEscape($event) {
if (this.isOpen) {
$event.preventDefault();
$event.stopPropagation();
this.isOpen = false;
}
}
handleArrowDown($event) {
if (this.isOpen) {
$event.preventDefault();
$event.stopPropagation();
}
}
stringUnmasked(value) {
return String(value).replace(/(\|-|_|\(|\)|:|\+)/gi, '');
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
}
/** @nocollapse */ TlDatePicker.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: TlDatePicker, deps: [{ token: i0.ChangeDetectorRef }, { token: LOCALE_ID }, { token: i1.NgControl, optional: true, self: true }], target: i0.ɵɵFactoryTarget.Component });
/** @nocollapse */ TlDatePicker.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: TlDatePicker, selector: "tl-datepicker", inputs: { label: "label", name: "name", labelSize: "labelSize", textAlign: "textAlign", iconAfter: "iconAfter", isoDate: "isoDate", labelPlacement: "labelPlacement", formatDate: "formatDate", readonly: "readonly", disabled: "disabled", placeholder: "placeholder", clearButton: "clearButton", autoClose: "autoClose", openOnFocus: "openOnFocus", holidays: "holidays" }, outputs: { selectDay: "selectDay", completeMask: "completeMask" }, viewQueries: [{ propertyName: "calendar", first: true, predicate: TlCalendar, descendants: true, static: true }, { propertyName: "tlInput", first: true, predicate: TlInput, descendants: true, static: true }, { propertyName: "calendarContent", first: true, predicate: ["calendarContent"], descendants: true, static: true }, { propertyName: "arrow", first: true, predicate: ["arrow"], descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: "<tl-input #tlinput\n [label]=\"label\"\n [labelSize]=\"labelSize\"\n [name]=\"name\"\n (overlayOrigin)=\"trigger = $event\"\n (focus)=\"onDateInputFocus()\"\n (click)=\"isOpen = !isOpen\"\n (keydown)=\"handleArrowKeys($event)\"\n (keypress)=\"handleDateChange()\"\n (completeMask)=\"onCompleteMask()\"\n (blur)=\"onBlur()\"\n (clear)=\"onClearInput($event)\"\n [iconAfter]=\"iconAfter\"\n date\n [control]=\"control\"\n [formatDate]=\"formatDate\"\n [textAlign]=\"textAlign\"\n [labelPlacement]=\"labelPlacement\"\n [readonly]=\"readonly ? true : null\"\n [disabled]=\"disabled ? true : null\"\n [(ngModel)]=\"description\"\n [placeholder]=\"placeholder\"\n [clearButton]=\"clearButton\">\n</tl-input>\n<input class=\"hidden-input\" notform [value]=\"value\">\n<ng-template cdkConnectedOverlay\n (backdropClick)=\"onBackDropClick()\"\n (positionChange)=\"onPositionChange($event)\"\n [cdkConnectedOverlayHasBackdrop]=\"true\"\n [cdkConnectedOverlayOrigin]=\"trigger\"\n [cdkConnectedOverlayBackdropClass]=\"'cdk-overlay-transparent-backdrop'\"\n [cdkConnectedOverlayOpen]=\"isOpen\">\n <tl-datepicker-content\n [input]=\"tlinput\"\n [date]=\"date\"\n [holidays]=\"holidays\"\n [overlayPosition]=\"positionOverlay\"\n (selectDayContent)=\"onSelectDay($event)\">\n </tl-datepicker-content>\n</ng-template>\n", styles: [".hidden-input{width:1px;height:1px;left:0;top:0;position:absolute;border:0;display:none}\n"], dependencies: [{ kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i2.CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "directive", type: i3.DateDirective, selector: "[date][ngModel],[date][formControl],[date][formControlName]", inputs: ["formatDate", "isoDate", "control"] }, { kind: "component", type: i4.TlInput, selector: "tl-input", inputs: ["textBefore", "textAfter", "labelPlacement", "labelSize", "name", "label", "color", "iconBefore", "iconAfter", "clearButton", "readonly", "required", "disabled", "autocomplete", "maxlength", "tabindex", "textAlign", "mask", "placeholder", "type", "height", "withBorder", "flatBorder"], outputs: ["clear", "overlayOrigin", "clickAddon", "click", "focus", "blur", "valid", "completeMask"] }, { kind: "component", type: i5.TlDatePickerContent, selector: "tl-datepicker-content", inputs: ["date", "input", "overlayPosition", "holidays"], outputs: ["selectDayContent"] }] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: TlDatePicker, decorators: [{
type: Component,
args: [{ selector: 'tl-datepicker', template: "<tl-input #tlinput\n [label]=\"label\"\n [labelSize]=\"labelSize\"\n [name]=\"name\"\n (overlayOrigin)=\"trigger = $event\"\n (focus)=\"onDateInputFocus()\"\n (click)=\"isOpen = !isOpen\"\n (keydown)=\"handleArrowKeys($event)\"\n (keypress)=\"handleDateChange()\"\n (completeMask)=\"onCompleteMask()\"\n (blur)=\"onBlur()\"\n (clear)=\"onClearInput($event)\"\n [iconAfter]=\"iconAfter\"\n date\n [control]=\"control\"\n [formatDate]=\"formatDate\"\n [textAlign]=\"textAlign\"\n [labelPlacement]=\"labelPlacement\"\n [readonly]=\"readonly ? true : null\"\n [disabled]=\"disabled ? true : null\"\n [(ngModel)]=\"description\"\n [placeholder]=\"placeholder\"\n [clearButton]=\"clearButton\">\n</tl-input>\n<input class=\"hidden-input\" notform [value]=\"value\">\n<ng-template cdkConnectedOverlay\n (backdropClick)=\"onBackDropClick()\"\n (positionChange)=\"onPositionChange($event)\"\n [cdkConnectedOverlayHasBackdrop]=\"true\"\n [cdkConnectedOverlayOrigin]=\"trigger\"\n [cdkConnectedOverlayBackdropClass]=\"'cdk-overlay-transparent-backdrop'\"\n [cdkConnectedOverlayOpen]=\"isOpen\">\n <tl-datepicker-content\n [input]=\"tlinput\"\n [date]=\"date\"\n [holidays]=\"holidays\"\n [overlayPosition]=\"positionOverlay\"\n (selectDayContent)=\"onSelectDay($event)\">\n </tl-datepicker-content>\n</ng-template>\n", styles: [".hidden-input{width:1px;height:1px;left:0;top:0;position:absolute;border:0;display:none}\n"] }]
}], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: undefined, decorators: [{
type: Inject,
args: [LOCALE_ID]
}] }, { type: i1.NgControl, decorators: [{
type: Optional
}, {
type: Self
}] }]; }, propDecorators: { label: [{
type: Input
}], name: [{
type: Input
}], labelSize: [{
type: Input
}], textAlign: [{
type: Input
}], iconAfter: [{
type: Input
}], isoDate: [{
type: Input
}], labelPlacement: [{
type: Input
}], formatDate: [{
type: Input
}], readonly: [{
type: Input
}], disabled: [{
type: Input
}], placeholder: [{
type: Input
}], clearButton: [{
type: Input
}], autoClose: [{
type: Input
}], openOnFocus: [{
type: Input
}], holidays: [{
type: Input
}], selectDay: [{
type: Output
}], completeMask: [{
type: Output
}], calendar: [{
type: ViewChild,
args: [TlCalendar, { static: true }]
}], tlInput: [{
type: ViewChild,
args: [TlInput, { static: true }]
}], calendarContent: [{
type: ViewChild,
args: ['calendarContent', { static: true }]
}], arrow: [{
type: ViewChild,
args: ['arrow', { static: true }]
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0ZXBpY2tlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL3RydWx5LXVpL3NyYy9jb21wb25lbnRzL2RhdGVwaWNrZXIvZGF0ZXBpY2tlci50cyIsIi4uLy4uLy4uLy4uL3Byb2plY3RzL3RydWx5LXVpL3NyYy9jb21wb25lbnRzL2RhdGVwaWNrZXIvZGF0ZXBpY2tlci5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQW9CRztBQUNILE9BQU8sRUFHTCxTQUFTLEVBRVQsWUFBWSxFQUFFLE1BQU0sRUFDcEIsS0FBSyxFQUFFLFNBQVMsRUFFUixRQUFRLEVBQ2hCLE1BQU0sRUFBRSxJQUFJLEVBQ1osU0FBUyxFQUNWLE1BQU0sZUFBZSxDQUFDO0FBRXZCLE9BQU8sRUFBQyxPQUFPLEVBQUMsTUFBTSxnQkFBZ0IsQ0FBQztBQUN2QyxPQUFPLEVBQUMsVUFBVSxFQUFDLE1BQU0sc0JBQXNCLENBQUM7QUFFaEQsT0FBTyxFQUFDLGlCQUFpQixFQUFDLE1BQU0sa0NBQWtDLENBQUM7QUFFbkUsT0FBTyxFQUFDLFFBQVEsRUFBQyxNQUFNLDBCQUEwQixDQUFDO0FBQ2xELE9BQU8sRUFBQyxpQkFBaUIsRUFBQyxNQUFNLDhCQUE4QixDQUFDO0FBQy9ELE9BQU8sRUFBQyxZQUFZLEVBQUMsTUFBTSxNQUFNLENBQUM7Ozs7Ozs7QUFlbEMsTUFBTSxPQUFPLFlBQWEsU0FBUSxpQkFBZ0M7SUE4RGhFLFlBQW9CLE9BQTBCLEVBQ1IsTUFBYyxFQUNiLFNBQW9CO1FBQ3pELEtBQUssRUFBRSxDQUFDO1FBSFUsWUFBTyxHQUFQLE9BQU8sQ0FBbUI7UUFDUixXQUFNLEdBQU4sTUFBTSxDQUFRO1FBQ2IsY0FBUyxHQUFULFNBQVMsQ0FBVztRQTlEbEQsVUFBSyxHQUFHLEVBQUUsQ0FBQztRQUVYLFNBQUksR0FBRyxFQUFFLENBQUM7UUFFVixjQUFTLEdBQUcsRUFBRSxDQUFDO1FB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O3VCQUFDLE9BQU8sRUFBRSxFQUFDLE1BQU0sRUFBRSxJQUFJLEVBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuIE1JVCBMaWNlbnNlXG5cbiBDb3B5cmlnaHQgKGMpIDIwMTkgVGVtYWluZm8gU29mdHdhcmVcblxuIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHlcbiBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLCB0byBkZWFsXG4gaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0c1xuIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGxcbiBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXNcbiBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluIGFsbFxuIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxuIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRVxuIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLFxuIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFXG4gU09GVFdBUkUuXG4gKi9cbmltcG9ydCB7XG4gIEFmdGVyQ29udGVudEluaXQsXG4gIENoYW5nZURldGVjdG9yUmVmLFxuICBDb21wb25lbnQsXG4gIENvbnRlbnRDaGlsZCxcbiAgRXZlbnRFbWl0dGVyLCBJbmplY3QsXG4gIElucHV0LCBMT0NBTEVfSUQsXG4gIE9uRGVzdHJveSxcbiAgT25Jbml0LCBPcHRpb25hbCxcbiAgT3V0cHV0LCBTZWxmLFxuICBWaWV3Q2hpbGRcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge05nQ29udHJvbH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHtUbElucHV0fSBmcm9tICcuLi9pbnB1dC9pbnB1dCc7XG5pbXBvcnQge1RsQ2FsZW5kYXJ9IGZyb20gJy4uL2NhbGVuZGFyL2NhbGVuZGFyJztcblxuaW1wb3J0IHtSZXZlcnNlRm9ybWF0RGF0ZX0gZnJvbSAnLi4vY29yZS9oZWxwZXIvcmV2ZXJzZWZvcm1hdGRhdGUnO1xuaW1wb3J0IHtDb25uZWN0ZWRPdmVybGF5UG9zaXRpb25DaGFuZ2V9IGZyb20gJ0Bhbmd1bGFyL2Nkay9vdmVybGF5JztcbmltcG9ydCB7S2V5RXZlbnR9IGZyb20gJy4uL2NvcmUvZW51bXMva2V5LWV2ZW50cyc7XG5pbXBvcnQge1ZhbHVlQWNjZXNzb3JCYXNlfSBmcm9tICcuLi9pbnB1dC9jb3JlL3ZhbHVlLWFjY2Vzc29yJztcbmltcG9ydCB7U3Vic2NyaXB0aW9ufSBmcm9tICdyeGpzJztcbmltcG9ydCB7Q2FsZW5kYXJIb2xpZGF5fSBmcm9tICcuLi9jYWxlbmRhci9pbnRlcmZhY2VzL2NhbGVuZGFyLWhvbGlkYXkuaW50ZXJmYWNlJztcblxuZXhwb3J0IGludGVyZmFjZSBEYXRlT2plY3Qge1xuICBkYXk6IG51bWJlcjtcbiAgbW9udGg6IG51bWJlcjtcbiAgeWVhcjogbnVtYmVyO1xufVxuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICd0bC1kYXRlcGlja2VyJyxcbiAgdGVtcGxhdGVVcmw6ICcuL2RhdGVwaWNrZXIuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL2RhdGVwaWNrZXIuc2NzcyddXG59KVxuXG5leHBvcnQgY2xhc3MgVGxEYXRlUGlja2VyIGV4dGVuZHMgVmFsdWVBY2Nlc3NvckJhc2U8RGF0ZSB8IHN0cmluZz4gaW1wbGVtZW50cyBPbkluaXQsIEFmdGVyQ29udGVudEluaXQsIE9uRGVzdHJveSB7XG5cbiAgQElucHV0KCkgbGFiZWwgPSAnJztcblxuICBASW5wdXQoKSBuYW1lID0gJyc7XG5cbiAgQElucHV0KCkgbGFiZWxTaXplID0gJyc7XG5cbiAgQElucHV0KCkgdGV4dEFsaWduID0gJ2xlZnQnO1xuXG4gIEBJbnB1dCgpIGljb25BZnRlcjtcblxuICBASW5wdXQoKSBpc29EYXRlID0gdHJ1ZTtcblxuICBASW5wdXQoKSBsYWJlbFBsYWNlbWVudCA9ICdsZWZ0JztcblxuICBASW5wdXQoKSBmb3JtYXREYXRlID0gJ2RkL21tL3l5eXknO1xuXG4gIEBJbnB1dCgpIHJlYWRvbmx5ID0gZmFsc2U7XG5cbiAgQElucHV0KCkgZGlzYWJsZWQgPSBmYWxzZTtcblxuICBASW5wdXQoKSBwbGFjZWhvbGRlciA9ICdEYXRlcGlja2VyIEZpZWxkJztcblxuICBASW5wdXQoKSBjbGVhckJ1dHRvbiA9IHRydWU7XG5cbiAgQElucHV0KCkgYXV0b0Nsb3NlID0gZmFsc2U7XG5cbiAgQElucHV0KCkgb3Blbk9uRm9jdXMgPSB0cnVlO1xuXG4gIEBJbnB1dCgpIGhvbGlkYXlzOiBBcnJheTxDYWxlbmRhckhvbGlkYXk+ID0gW107XG5cbiAgQE91dHB1dCgpIHNlbGVjdERheTogRXZlbnRFbWl0dGVyPGFueT4gPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcblxuICBAT3V0cHV0KCkgY29tcGxldGVNYXNrOiBFdmVudEVtaXR0ZXI8YW55PiA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xuXG4gIEBWaWV3Q2hpbGQoVGxDYWxlbmRhciwge3N0YXRpYzogdHJ1ZX0pIGNhbGVuZGFyO1xuXG4gIEBWaWV3Q2hpbGQoVGxJbnB1dCwge3N0YXRpYzogdHJ1ZX0pIHRsSW5wdXQ6IFRsSW5wdXQ7XG5cbiAgQFZpZXdDaGlsZCgnY2FsZW5kYXJDb250ZW50Jywge3N0YXRpYzogdHJ1ZX0pIGNhbGVuZGFyQ29udGVudDtcblxuICBAVmlld0NoaWxkKCdhcnJvdycsIHtzdGF0aWM6IHRydWV9KSBhcnJvdztcblxuICBwdWJsaWMgaXNPcGVuID0gZmFsc2U7XG5cbiAgcHVibGljIHBvc2l0aW9uT3ZlcmxheSA9ICcnO1xuXG4gIHB1YmxpYyBkZXNjcmlwdGlvbiA9ICcnO1xuXG4gIHB1YmxpYyB0cmlnZ2VyO1xuXG4gIHB1YmxpYyBkYXRlID0gbmV3IERhdGUoKTtcblxuICBwcml2YXRlIHllYXIgPSBuZXcgRGF0ZSgpLmdldEZ1bGxZZWFyKCk7XG5cbiAgcHJpdmF0ZSBtb250aCA9IG5ldyBEYXRlKCkuZ2V0TW9udGgoKTtcblxuICBwcml2YXRlIGRheSA9IG5ldyBEYXRlKCkuZ2V0RGF0ZSgpO1xuXG4gIHByaXZhdGUgc3Vic2NyaXB0aW9uID0gbmV3IFN1YnNjcmlwdGlvbigpO1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgY2hhbmdlczogQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gICAgICAgICAgICAgIEBJbmplY3QoTE9DQUxFX0lEKSBwdWJsaWMgbG9jYWxlOiBzdHJpbmcsXG4gICAgICAgICAgICAgIEBPcHRpb25hbCgpIEBTZWxmKCkgcHVibGljIG5nQ29udHJvbDogTmdDb250cm9sKSB7XG4gICAgc3VwZXIoKTtcbiAgICB0aGlzLnNldENvbnRyb2woKTtcbiAgfVxuXG4gIGdldCBjb250cm9sKCkge1xuICAgIHJldHVybiB0aGlzLm5nQ29udHJvbC5jb250cm9sO1xuICB9XG5cbiAgc2V0Q29udHJvbCgpIHtcbiAgICBpZiAoIHRoaXMubmdDb250cm9sICkge1xuICAgICAgdGhpcy5uZ0NvbnRyb2wudmFsdWVBY2Nlc3NvciA9IHRoaXM7XG4gICAgfVxuICB9XG5cbiAgbmdPbkluaXQoKSB7XG4gICAgdGhpcy5zZXREYXRlTWFzaygpO1xuICB9XG5cbiAgbmdBZnRlckNvbnRlbnRJbml0KCkge1xuICAgIHRoaXMuZGVjb21wb3NlRGF0ZSh0aGlzLnZhbHVlKTtcbiAgICB0aGlzLmxpc3RlbkNvbnRyb2xDaGFuZ2VzKCk7XG4gIH1cblxuICBwcml2YXRlIGxpc3RlbkNvbnRyb2xDaGFuZ2VzKCkge1xuICAgIGlmICh0aGlzLmNvbnRyb2wpIHtcbiAgICAgIHRoaXMuc3Vic2NyaXB0aW9uLmFkZCh0aGlzLmNvbnRyb2wudmFsdWVDaGFuZ2VzLnN1YnNjcmliZSgoZGF0ZTogRGF0ZSkgPT4ge1xuICAgICAgICBpZiAoIXRoaXMuaXNPcGVuICYmIGRhdGUpIHtcbiAgICAgICAgICB0aGlzLmRlY29tcG9zZURhdGUoZGF0ZSk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmICggIWRhdGUgKSB7XG4gICAgICAgICAgdGhpcy5kZXNjcmlwdGlvbiA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgIH0pKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGRlY29tcG9zZURhdGUoZGF0ZSkge1xuICAgIGlmIChkYXRlICYmIHRoaXMudmFsdWUpIHtcbiAgICAgIGNvbnN0IGRhdGVTdHIgPSBuZXcgRGF0ZShkYXRlKS50b0xvY2FsZURhdGVTdHJpbmcodGhpcy5sb2NhbGUsIHt0aW1lWm9uZTogJ1VUQyd9KTtcbiAgICAgIGNvbnN0IGZvcm1hdHRlZCA9IFJldmVyc2VGb3JtYXREYXRlKHRoaXMuc3RyaW5nVW5tYXNrZWQoZGF0ZVN0ciksIHRoaXMuZm9ybWF0RGF0ZSk7XG4gICAgICB0aGlzLmRlc2NyaXB0aW9uID0gdGhpcy5nZXRGb3JtYXR0ZWREYXRlKGZvcm1hdHRlZCk7XG4gICAgICB0aGlzLnNldERhdGVPYmplY3QoZm9ybWF0dGVkKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHNldERhdGVNYXNrKCkge1xuICAgIHRoaXMudGxJbnB1dC5tYXNrID0gdGhpcy5nZXRNYXNrKCk7XG4gIH1cblxuICBwcml2YXRlIHNldERhdGVPYmplY3QoZGF0ZU9iamVjdDogRGF0ZU9qZWN0KSB7XG4gICAgdGhpcy5kYXkgPSBkYXRlT2JqZWN0LmRheTtcbiAgICB0aGlzLm1vbnRoID0gZGF0ZU9iamVjdC5tb250aCAtIDE7XG4gICAgdGhpcy55ZWFyID0gZGF0ZU9iamVjdC55ZWFyO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRNYXNrKCkge1xuICAgIGNvbnN0IGZvcm1hdCA9IHRoaXMuZm9ybWF0RGF0ZS50b0xvd2VyQ2FzZSgpO1xuICAgIGNvbnN0IGRkID0gZm9ybWF0LnJlcGxhY2UoJ2RkJywgJzAwJyk7XG4gICAgY29uc3QgbW0gPSBkZC5yZXBsYWNlKCdtbScsICcwMCcpO1xuICAgIHJldHVybiBtbS5yZXBsYWNlKCd5eXl5JywgJzAwMDAnKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0T2JqZWN0VmFsdWVzKCkge1xuICAgIHJldHVybiB7XG4gICAgICBkYXk6IHRoaXMuZGF5LFxuICAgICAgZnVsbERhdGU6IHRoaXMuZGF0ZSxcbiAgICAgIG1vbnRoOiB0aGlzLm1vbnRoLFxuICAgICAgeWVhcjogdGhpcy55ZWFyXG4gICAgfTtcbiAgfVxuXG4gIHByaXZhdGUgaGFuZGxlQXV0b0Nsb3NlKCkge1xuICAgIGlmICh0aGlzLmF1dG9DbG9zZSkge1xuICAgICAgdGhpcy5pc09wZW4gPSBmYWxzZTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGhhbmRsZU9wZW5PbkZvY3VzKCkge1xuICAgIGlmICh0aGlzLm9wZW5PbkZvY3VzKSB7XG4gICAgICB0aGlzLmlzT3BlbiA9IHRydWU7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBnZXRGb3JtYXR0ZWREYXRlKCRldmVudCkge1xuICAgIGxldCBzdHJEYXRlO1xuICAgIGNvbnN0IGRhdGUgPSB0aGlzLmZvcm1hdERhdGU7XG4gICAgc3RyRGF0ZSA9IGRhdGUucmVwbGFjZSgnZGQnLCB0aGlzLmZvcm1hdERheUFuZE1vbnRoKCRldmVudC5kYXkpKTtcbiAgICBzdHJEYXRlID0gc3RyRGF0ZS5yZXBsYWNlKCdtbScsIHRoaXMuZm9ybWF0RGF5QW5kTW9udGgoJGV2ZW50Lm1vbnRoKSk7XG4gICAgc3RyRGF0ZSA9IHN0ckRhdGUucmVwbGFjZSgneXl5eScsICRldmVudC55ZWFyKTtcbiAgICByZXR1cm4gc3RyRGF0ZTtcbiAgfVxuXG4gIHByaXZhdGUgc2V0VmFsdWUoJGV2ZW50KSB7XG4gICAgdGhpcy5kZXNjcmlwdGlvbiA9IHRoaXMuZ2V0Rm9ybWF0dGVkRGF0ZSh7Li4uJGV2ZW50LCBtb250aDogJGV2ZW50Lm1vbnRoICsgMX0pO1xuICAgIHRoaXMudmFsdWUgPSAkZXZlbnQuZnVsbERhdGUudG9JU09TdHJpbmcoKTtcbiAgfVxuXG4gIHByaXZhdGUgZm9ybWF0RGF5QW5kTW9udGgodmFsdWUpIHtcbiAgICBpZiAoU3RyaW5nKHZhbHVlKS5sZW5ndGggPT09IDEpIHtcbiAgICAgIHJldHVybiBgMCR7dmFsdWV9YDtcbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG5cbiAgaGFuZGxlRGF0ZUNoYW5nZSgpIHtcbiAgICBjb25zdCBkYXRlID0gUmV2ZXJzZUZvcm1hdERhdGUodGhpcy5kZXNjcmlwdGlvbiwgdGhpcy5mb3JtYXREYXRlKTtcbiAgICBpZiAoIWlzTmFOKGRhdGUuZGF5KSAmJiAhaXNOYU4oZGF0ZS5tb250aCkgJiYgIWlzTmFOKGRhdGUueWVhcikpIHtcbiAgICAgIHRoaXMuc2V0RGF0ZU9iamVjdChkYXRlKTtcbiAgICAgIHRoaXMuZGF0ZSA9IG5ldyBEYXRlKGRhdGUueWVhciwgZGF0ZS5tb250aCAtIDEsIGRhdGUuZGF5KTtcbiAgICAgIHRoaXMuY2hhbmdlcy5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgfVxuICB9XG5cbiAgb25CbHVyKCkge1xuICAgIHRoaXMucHJvcGFnYXRlVG91Y2hlZCgpO1xuICB9XG5cbiAgb25Db21wbGV0ZU1hc2soKSB7XG4gICAgY29uc3QgdGltZW91dCA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdGhpcy5oYW5kbGVEYXRlQ2hhbmdlKCk7XG4gICAgICBpZiAodGhpcy5pc29EYXRlKSB7XG4gICAgICAgIHRoaXMudmFsdWUgPSB0aGlzLmdldE9iamVjdFZhbHVlcygpLmZ1bGxEYXRlLnRvSVNPU3RyaW5nKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnZhbHVlID0gdGhpcy5nZXRPYmplY3RWYWx1ZXMoKS5mdWxsRGF0ZTtcbiAgICAgIH1cbiAgICAgIHRoaXMuY2hhbmdlcy5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgICB0aGlzLmNvbXBsZXRlTWFzay5lbWl0KHRoaXMuZ2V0T2JqZWN0VmFsdWVzKCkpO1xuICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xuICAgIH0sIDUwMCk7XG5cbiAgfVxuXG4gIG9uRGF0ZUlucHV0Rm9jdXMoKSB7XG4gICAgaWYgKHRoaXMudmFsdWUgJiYgIXRoaXMuaXNPcGVuKSB7XG4gICAgICBjb25zdCBpbnB1dERhdGUgPSBSZXZlcnNlRm9ybWF0RGF0ZSh0aGlzLnN0cmluZ1VubWFza2VkKHRoaXMuZGVzY3JpcHRpb24pLCB0aGlzLmZvcm1hdERhdGUpO1xuICAgICAgdGhpcy5zZXREYXRlT2JqZWN0KGlucHV0RGF0ZSk7XG4gICAgfVxuICAgIHRoaXMuaGFuZGxlT3Blbk9uRm9jdXMoKTtcbiAgfVxuXG4gIG9uU2VsZWN0RGF5KCRldmVudCkge1xuICAgIHRoaXMuc2V0RGF0ZU9iamVjdCgkZXZlbnQpO1xuICAgIHRoaXMuZGF0ZSA9ICRldmVudC5mdWxsRGF0ZTtcbiAgICB0aGlzLnNlbGVjdERheS5lbWl0KCRldmVudCk7XG4gICAgdGhpcy5zZXRWYWx1ZSgkZXZlbnQpO1xuICAgIHRoaXMuaGFuZGxlQXV0b0Nsb3NlKCk7XG4gICAgdGhpcy5jaGFuZ2VzLmRldGVjdENoYW5nZXMoKTtcbiAgfVxuXG4gIG9uUG9zaXRpb25DaGFuZ2UoJGV2ZW50OiBDb25uZWN0ZWRPdmVybGF5UG9zaXRpb25DaGFuZ2UpIHtcbiAgICB0aGlzLnBvc2l0aW9uT3ZlcmxheSA9ICRldmVudC5jb25uZWN0aW9uUGFpci5vcmlnaW5ZO1xuICB9XG5cbiAgb25CYWNrRHJvcENsaWNrKCkge1xuICAgIHRoaXMuaXNPcGVuID0gZmFsc2U7XG4gIH1cblxuICBvbkNsZWFySW5wdXQoJGV2ZW50KSB7XG4gICAgdGhpcy52YWx1ZSA9IG51bGw7XG4gICAgJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICB9XG5cbiAgaGFuZGxlQXJyb3dLZXlzKCRldmVudCkge1xuICAgIGNvbnN0IG9iamVjdCA9IHtcbiAgICAgIFtLZXlFdmVudC5BUlJPV1VQXTogKCkgPT4gdGhpcy5oYW5kbGVBcnJvd1VwKCRldmVudCksXG4gICAgICBbS2V5RXZlbnQuQVJST1dET1dOXTogKCkgPT4gdGhpcy5oYW5kbGVBcnJvd0Rvd24oJGV2ZW50KSxcbiAgICAgIFtLZXlFdmVudC5UQUJdOiAoKSA9PiB0aGlzLmhhbmRsZVRhYigpLFxuICAgICAgW0tleUV2ZW50LkVTQ0FQRV06ICgpID0+IHRoaXMuaGFuZGxlRXNjYXBlKCRldmVudCksXG4gICAgICBbS2V5RXZlbnQuQVJST1dSSUdIVF06ICgpID0+ICRldmVudC5wcmV2ZW50RGVmYXVsdCgpLFxuICAgICAgW0tleUV2ZW50LkFSUk9XTEVGVF06ICgpID0+ICRldmVudC5wcmV2ZW50RGVmYXVsdCgpLFxuICAgIH07XG4gICAgaWYgKG9iamVjdFskZXZlbnRdKSB7XG4gICAgICBvYmplY3RbJGV2ZW50XSgpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgaGFuZGxlQXJyb3dVcCgkZXZlbnQpIHtcbiAgICBpZiAodGhpcy5pc09wZW4pIHtcbiAgICAgICRldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgaGFuZGxlVGFiKCkge1xuICAgIGlmICh0aGlzLmlzT3Blbikge1xuICAgICAgdGhpcy5pc09wZW4gPSBmYWxzZTtcbiAgICAgIHRoaXMuY2hhbmdlcy5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBoYW5kbGVFc2NhcGUoJGV2ZW50KSB7XG4gICAgaWYgKHRoaXMuaXNPcGVuKSB7XG4gICAgICAkZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICRldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgIHRoaXMuaXNPcGVuID0gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBoYW5kbGVBcnJvd0Rvd24oJGV2ZW50KSB7XG4gICAgaWYgKHRoaXMuaXNPcGVuKSB7XG4gICAgICAkZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICRldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHN0cmluZ1VubWFza2VkKHZhbHVlKSB7XG4gICAgcmV0dXJuIFN0cmluZyh2YWx1ZSkucmVwbGFjZSgvKFxcfC18X3xcXCh8XFwpfDp8XFwrKS9naSwgJycpO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKSB7XG4gICAgdGhpcy5zdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgfVxuXG59XG4iLCI8dGwtaW5wdXQgI3RsaW5wdXRcbiAgICAgICAgICBbbGFiZWxdPVwibGFiZWxcIlxuICAgICAgICAgIFtsYWJlbFNpemVdPVwibGFiZWxTaXplXCJcbiAgICAgICAgICBbbmFtZV09XCJuYW1lXCJcbiAgICAgICAgICAob3ZlcmxheU9yaWdpbik9XCJ0cmlnZ2VyID0gJGV2ZW50XCJcbiAgICAgICAgICAoZm9jdXMpPVwib25EYXRlSW5wdXRGb2N1cygpXCJcbiAgICAgICAgICAoY2xpY2spPVwiaXNPcGVuID0gIWlzT3BlblwiXG4gICAgICAgICAgKGtleWRvd24pPVwiaGFuZGxlQXJyb3dLZXlzKCRldmVudClcIlxuICAgICAgICAgIChrZXlwcmVzcyk9XCJoYW5kbGVEYXRlQ2hhbmdlKClcIlxuICAgICAgICAgIChjb21wbGV0ZU1hc2spPVwib25Db21wbGV0ZU1hc2soKVwiXG4gICAgICAgICAgKGJsdXIpPVwib25CbHVyKClcIlxuICAgICAgICAgIChjbGVhcik9XCJvbkNsZWFySW5wdXQoJGV2ZW50KVwiXG4gICAgICAgICAgW2ljb25BZnRlcl09XCJpY29uQWZ0ZXJcIlxuICAgICAgICAgIGRhdGVcbiAgICAgICAgICBbY29udHJvbF09XCJjb250cm9sXCJcbiAgICAgICAgICBbZm9ybWF0RGF0ZV09XCJmb3JtYXREYXRlXCJcbiAgICAgICAgICBbdGV4dEFsaWduXT1cInRleHRBbGlnblwiXG4gICAgICAgICAgW2xhYmVsUGxhY2VtZW50XT1cImxhYmVsUGxhY2VtZW50XCJcbiAgICAgICAgICBbcmVhZG9ubHldPVwicmVhZG9ubHkgPyB0cnVlIDogbnVsbFwiXG4gICAgICAgICAgW2Rpc2FibGVkXT1cImRpc2FibGVkID8gdHJ1ZSA6IG51bGxcIlxuICAgICAgICAgIFsobmdNb2RlbCldPVwiZGVzY3JpcHRpb25cIlxuICAgICAgICAgIFtwbGFjZWhvbGRlcl09XCJwbGFjZWhvbGRlclwiXG4gICAgICAgICAgW2NsZWFyQnV0dG9uXT1cImNsZWFyQnV0dG9uXCI+XG48L3RsLWlucHV0PlxuPGlucHV0IGNsYXNzPVwiaGlkZGVuLWlucHV0XCIgbm90Zm9ybSBbdmFsdWVdPVwidmFsdWVcIj5cbjxuZy10ZW1wbGF0ZSBjZGtDb25uZWN0ZWRPdmVybGF5XG4gICAgICAgICAgICAoYmFja2Ryb3BDbGljayk9XCJvbkJhY2tEcm9wQ2xpY2soKVwiXG4gICAgICAgICAgICAocG9zaXRpb25DaGFuZ2UpPVwib25Qb3NpdGlvbkNoYW5nZSgkZXZlbnQpXCJcbiAgICAgICAgICAgIFtjZGtDb25uZWN0ZWRPdmVybGF5SGFzQmFja2Ryb3BdPVwidHJ1ZVwiXG4gICAgICAgICAgICBbY2RrQ29ubmVjdGVkT3ZlcmxheU9yaWdpbl09XCJ0cmlnZ2VyXCJcbiAgICAgICAgICAgIFtjZGtDb25uZWN0ZWRPdmVybGF5QmFja2Ryb3BDbGFzc109XCInY2RrLW92ZXJsYXktdHJhbnNwYXJlbnQtYmFja2Ryb3AnXCJcbiAgICAgICAgICAgIFtjZGtDb25uZWN0ZWRPdmVybGF5T3Blbl09XCJpc09wZW5cIj5cbiAgPHRsLWRhdGVwaWNrZXItY29udGVudFxuICAgIFtpbnB1dF09XCJ0bGlucHV0XCJcbiAgICBbZGF0ZV09XCJkYXRlXCJcbiAgICBbaG9saWRheXNdPVwiaG9saWRheXNcIlxuICAgIFtvdmVybGF5UG9zaXRpb25dPVwicG9zaXRpb25PdmVybGF5XCJcbiAgICAoc2VsZWN0RGF5Q29udGVudCk9XCJvblNlbGVjdERheSgkZXZlbnQpXCI+XG4gIDwvdGwtZGF0ZXBpY2tlci1jb250ZW50PlxuPC9uZy10ZW1wbGF0ZT5cbiJdfQ==