@noaestudio/forms
Version:
Dynamic forms extension for Covalent
348 lines (347 loc) • 69.6 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
import * as tslib_1 from "tslib";
import { Component, forwardRef, ChangeDetectorRef } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { AbstractControlValueAccessor } from '../abstract-control-value-accesor';
import { TranslateService } from '@ngx-translate/core';
import { MatDialog } from '@angular/material';
import { moveItemInArray } from '@angular/cdk/drag-drop';
import * as lodash_ from 'lodash';
import { ErrorDialogComponent } from '../../dialogs/error-dialog/error-dialog.component';
import { ConfirmDialogComponent } from '../../dialogs/confirm-dialog/confirm-dialog.component';
var /** @type {?} */ lodash = lodash_;
export var /** @type {?} */ INPUT_INPUT_CONTROL_VALUE_ACCESSOR = {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(function () { return EditableTableComponent; }),
multi: true,
};
var EditableTableComponent = /** @class */ (function (_super) {
tslib_1.__extends(EditableTableComponent, _super);
function EditableTableComponent(translator, dialog, changeDetector) {
var _this = _super.call(this) || this;
_this.translator = translator;
_this.dialog = dialog;
_this.changeDetector = changeDetector;
/**
* Component Attributes
*/
_this.label = '';
//Elementos a devolver
_this.outputItems = [];
//Esquema
_this.schema = null;
//Puede ser draggable
_this.draggable = false;
//New Element
_this.newElement = {};
//Extras
_this.extras = null;
_this.showDelete = true;
_this.addTitle = 'Nuevo elemento';
return _this;
}
/**
* @return {?}
*/
EditableTableComponent.prototype.ngOnInit = /**
* @return {?}
*/
function () {
//Inicializamos el value si no llega nada por defecto
if (this.value == undefined) {
this.value = [];
}
//Creamos el newElement en base al esquema
for (var /** @type {?} */ i = 0; i < this.schema.length; i++) {
this.newElement[this.schema[i].name] = null;
}
//Cargamos los extras
if (this.extras) {
//Puede eliminar registros en la tabla?
if (this.extras.showDelete != undefined && this.extras.showDelete != null) {
this.showDelete = this.extras.showDelete;
}
if (this.extras.addTitle != undefined && this.extras.addTitle != null) {
this.addTitle = this.extras.addTitle;
}
}
};
/**
* @return {?}
*/
EditableTableComponent.prototype.addItem = /**
* @return {?}
*/
function () {
this.value.push(this.cloneObject(this.newElement));
this.control.setValue(this.value);
this.checkRequired();
this.checkValidators();
};
/**
* @param {?} index
* @return {?}
*/
EditableTableComponent.prototype.removeItem = /**
* @param {?} index
* @return {?}
*/
function (index) {
var _this = this;
var /** @type {?} */ deleteItem = function () {
_this.value.splice(index, 1);
_this.control.setValue(_this.value);
_this.checkRequired();
_this.checkValidators();
_this.changeDetector.detectChanges();
};
this.openConfirm().then(function (confirm) {
if (confirm) {
if (_this.extras != undefined && _this.extras != null && _this.extras.deleteAction != undefined) {
_this.extras.deleteAction(_this.value[index]).then(function (result) {
if (result) {
deleteItem();
}
}).catch(function (err) {
var /** @type {?} */ errorMessage = err.error.message;
_this.openDialog("Error", errorMessage);
});
}
else {
deleteItem();
}
}
});
};
/**
* @param {?} obj
* @return {?}
*/
EditableTableComponent.prototype.cloneObject = /**
* @param {?} obj
* @return {?}
*/
function (obj) {
var /** @type {?} */ cloneLodash = lodash.cloneDeep(obj);
return cloneLodash;
};
/**
* @param {?} $event
* @return {?}
*/
EditableTableComponent.prototype.changesOut = /**
* @param {?} $event
* @return {?}
*/
function ($event) {
this.control.setValue(this.value);
this.checkRequired();
this.checkValidators();
};
/**
* @param {?} event
* @return {?}
*/
EditableTableComponent.prototype.drop = /**
* @param {?} event
* @return {?}
*/
function (event) {
moveItemInArray(this.value, event.previousIndex, event.currentIndex);
this.control.setValue(this.value);
};
/**
* @return {?}
*/
EditableTableComponent.prototype.checkRequired = /**
* @return {?}
*/
function () {
var _this = this;
this.value.forEach(function (field) {
Object.keys(field).forEach(function (key) {
var /** @type {?} */ schema = _this.getFieldSchema(key);
if (schema != null) {
if (schema.required != undefined && schema.required && field[key] == null) {
_this.control.setErrors({ required: true });
}
}
});
});
};
/**
* @param {?} name
* @return {?}
*/
EditableTableComponent.prototype.getFieldSchema = /**
* @param {?} name
* @return {?}
*/
function (name) {
var /** @type {?} */ schema = null;
this.schema.forEach(function (item) {
if (item.name == name) {
schema = item;
}
});
return schema;
};
/**
* @return {?}
*/
EditableTableComponent.prototype.checkValidators = /**
* @return {?}
*/
function () {
if (this.extras.rowValidator) {
try {
for (var _a = tslib_1.__values(this.value), _b = _a.next(); !_b.done; _b = _a.next()) {
var item = _b.value;
var /** @type {?} */ errors = this.extras.rowValidator(item);
if (errors) {
this.control.setErrors(errors.errorList);
}
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
}
finally { if (e_1) throw e_1.error; }
}
}
var e_1, _c;
};
/**
* @param {?} item
* @param {?} field
* @return {?}
*/
EditableTableComponent.prototype.isValid = /**
* @param {?} item
* @param {?} field
* @return {?}
*/
function (item, field) {
var /** @type {?} */ valid = true;
if (this.extras.rowValidator) {
var /** @type {?} */ errors = this.extras.rowValidator(item);
if (errors) {
for (var /** @type {?} */ i = 0; i < errors.errorFields.length; i++) {
if (errors.errorFields[i].field == field) {
valid = false;
}
}
}
}
return valid;
};
/**
* @param {?} item
* @param {?} field
* @return {?}
*/
EditableTableComponent.prototype.fieldErrorMessage = /**
* @param {?} item
* @param {?} field
* @return {?}
*/
function (item, field) {
var /** @type {?} */ message = "";
if (this.extras.rowValidator) {
var /** @type {?} */ errors = this.extras.rowValidator(item);
if (errors) {
for (var /** @type {?} */ i = 0; i < errors.errorFields.length; i++) {
if (errors.errorFields[i].field == field) {
message = errors.errorFields[i].message;
}
}
}
}
return message;
};
/**
* @param {?} title
* @param {?} message
* @return {?}
*/
EditableTableComponent.prototype.openDialog = /**
* @param {?} title
* @param {?} message
* @return {?}
*/
function (title, message) {
var /** @type {?} */ data = {
title: title,
message: message
};
this.dialog.open(ErrorDialogComponent, { data: data });
};
/**
* @return {?}
*/
EditableTableComponent.prototype.openConfirm = /**
* @return {?}
*/
function () {
var /** @type {?} */ dialogRef = this.dialog.open(ConfirmDialogComponent);
return dialogRef.afterClosed().toPromise();
};
EditableTableComponent.decorators = [
{ type: Component, args: [{
providers: [INPUT_INPUT_CONTROL_VALUE_ACCESSOR],
selector: 'editable-table',
styles: ["td{padding:10px}.td-dynamic-input-wrapper{-ms-flex-direction:row;flex-direction:row;display:-ms-flexbox;display:flex;box-sizing:border-box}.td-dynamic-input-wrapper .td-dynamic-input-field{-ms-flex:1;flex:1;box-sizing:border-box}.td-dynamic-input-wrapper .ngx-editor{margin-top:10px}.label{padding:10px 0;display:inline-block;width:50%}.container{overflow:auto;border:1px solid #f3f3f3;border-radius:5px 5px 0 0}.selected-items{padding:5px;display:block;background:#f3f3f3;border-radius:0 0 5px 5px;min-height:30px}.selected-items span{background:#689f38;margin:2px;padding:5px;border-radius:5px;color:#fff;display:inline-block}.buttons{display:inline-block;width:50%;text-align:right}.buttons button{padding:0;width:30px!important;min-width:30px;border-radius:50px;height:30px}.buttons button mat-icon{position:relative!important;top:-4px!important}.main-container{border:1px solid #f3f3f3;border-radius:5px;padding:5px 10px 20px;overflow:auto}hr{display:block;height:1px;border:0;border-top:1px solid #ccc;margin:1em 0;padding:0}.dragger{text-align:center;background:#f3f3f3;height:24px;border-radius:5px;width:36px;margin:auto 8px auto auto;border:1px solid #ddd;cursor:move}.error-validate{color:#e53934;font-size:75%;top:33px;position:absolute;left:0}.error-validate.boolean{position:relative!important;top:9px;width:100%;display:inline-block}.error-validate.datetime{position:relative!important;top:9px;padding-bottom:10px;width:100%;display:inline-block}.editable-field{min-width:100%}table{width:100%;border-collapse:collapse;border-spacing:0}tr th{text-align:left}tr:nth-child(even){background:#fafafa}tr:nth-child(even) input{background:#fafafa!important}/deep/ .time-field label{display:block;color:#929292;margin-top:-12px}/deep/ .time-field input{border:0;border-bottom:1px solid #9e9f9e;font-size:14px}/deep/ .mat-datepicker-toggle button{box-shadow:0 3px 1px -2px rgba(0,0,0,.2),0 2px 2px 0 rgba(0,0,0,.14),0 1px 5px 0 rgba(0,0,0,.12);border-radius:3px!important}/deep/ .time-field{margin-bottom:4px}.details{font-size:11px;padding:5px 0}"],
template: "<div class=\"label\">{{label}}</div>\n<div class=\"main-container\">\n <table td-data-table>\n <thead>\n <tr td-data-table-column-row>\n <th td-data-table-column>\n {{addTitle}}\n </th>\n </tr>\n </thead>\n <tbody>\n <tr td-data-table-row>\n <td td-data-table-cell *ngFor=\"let item of schema; let i=index\">\n <ng-container *ngIf=\"item.type == 'string'\">\n <mat-form-field class=\"editable-field\">\n <input matInput autocomplete=\"off\" placeholder=\"{{item.label}}\" [(ngModel)]=\"newElement[item.name]\">\n </mat-form-field>\n </ng-container>\n\n <ng-container *ngIf=\"item.type == 'date'\">\n <mat-form-field class=\"editable-field\">\n <input matInput autocomplete=\"off\" [matDatepicker]=\"i\" placeholder=\"{{item.label}}\"\n [attr.id]=\"'dtPicker' + i\" [(ngModel)]=\"newElement[item.name]\">\n <mat-datepicker-toggle matSuffix [for]=\"i\"></mat-datepicker-toggle><mat-datepicker #i></mat-datepicker>\n </mat-form-field>\n </ng-container>\n\n <ng-container *ngIf=\"item.type == 'time'\">\n <div class=\"time-field\">\n <label class=\"timeLabel\">Hora</label>\n <input aria-label=\"default time\" autocomplete=\"off\" [ngxTimepicker]=\"defaultTime\" [(ngModel)]=\"newElement[item.name]\">\n <ngx-material-timepicker #defaultTime></ngx-material-timepicker>\n </div>\n </ng-container>\n\n\t\t\t\t\t<ng-container *ngIf=\"item.type == 'dateTime'\">\n <date-time-picker [min]=\"item.min\" [max]=\"item.max\" [(myModel)]=\"newElement[item.name]\"></date-time-picker>\n </ng-container>\n\n <ng-container *ngIf=\"item.type == 'number'\">\n <mat-form-field class=\"editable-field\">\n <input matInput type=\"number\" autocomplete=\"off\" placeholder=\"{{item.label}}\"\n [(ngModel)]=\"newElement[item.name]\" min=\"{{item.min}}\" max=\"{{item.max}}\">\n </mat-form-field>\n </ng-container>\n\n <ng-container *ngIf=\"item.type == 'boolean'\">\n <mat-checkbox [(ngModel)]=\"newElement[item.name]\">{{item.label}}</mat-checkbox>\n </ng-container>\n\n <ng-container *ngIf=\"item.type == 'select'\">\n <mat-form-field class=\"editable-field\">\n <mat-select placeholder=\"{{item.label}}\" [(value)]=\"newElement[item.name]\">\n <mat-option>...</mat-option>\n <mat-option value=\"{{item.value}}\" *ngFor=\"let item of item.items;\">{{item.label}}</mat-option>\n </mat-select>\n </mat-form-field>\n </ng-container>\n\n </td>\n <td>\n <button mat-button color=\"primary\" (click)=\"addItem()\">A\u00F1adir</button>\n </td>\n </tr>\n </tbody>\n </table>\n\n <hr />\n\n <table td-data-table>\n <thead>\n <tr td-data-table-column-row>\n <th td-data-table-column *ngIf=\"draggable\"></th>\n <th td-data-table-column\n *ngFor=\"let column of schema\">\n {{column.label}}\n </th>\n </tr>\n </thead>\n <tbody cdkDropList class=\"example-list\" (cdkDropListDropped)=\"drop($event)\">\n <ng-container *ngIf=\"draggable\">\n <!--DRAGGABLE: ISSUE #13893-->\n <tr td-data-table-row *ngFor=\"let row of value; let z=index\" cdkDrag>\n <td>\n <div class=\"dragger\" cdkDragHandle>\n <mat-icon>drag_handle</mat-icon>\n </div>\n </td>\n <td td-data-table-cell *ngFor=\"let attr of schema; let i=index\">\n <ng-container *ngIf=\"attr.type == 'string'\">\n <mat-form-field class=\"editable-field\">\n <input matInput placeholder=\"{{attr.label}}\" [(ngModel)]=\"row[attr.name]\" autocomplete=\"off\"\n (ngModelChange)=\"changesOut($event)\" [required]=\"attr.required\">\n <span class=\"error-validate\" *ngIf=\"!isValid(row, attr.name)\">\n {{fieldErrorMessage(row, attr.name) | translate}}\n </span>\n </mat-form-field>\n </ng-container>\n\n <ng-container *ngIf=\"attr.type == 'date'\">\n <mat-form-field class=\"editable-field\">\n <input matInput autocomplete=\"off\" [matDatepicker]=\"j\" placeholder=\"{{attr.label}}\"\n [attr.id]=\"'dtPicker' + j\" [(ngModel)]=\"row[attr.name]\" (ngModelChange)=\"changesOut($event)\" [required]=\"attr.required\">\n <mat-datepicker-toggle matSuffix [for]=\"j\"></mat-datepicker-toggle><mat-datepicker #j></mat-datepicker>\n <span class=\"error-validate\" *ngIf=\"!isValid(row, attr.name)\">\n {{fieldErrorMessage(row, attr.name) | translate}}\n </span>\n </mat-form-field>\n </ng-container>\n\n\t\t\t\t\t\t<ng-container *ngIf=\"attr.type == 'time'\">\n <div class=\"time-field\">\n <label class=\"timeLabel\">Hora</label>\n <input autocomplete=\"off\" aria-label=\"default time\" [ngxTimepicker]=\"defaultTime\"\n [value]=\"row[attr.name]\" readonly (ngModelChange)=\"changesOut($event)\">\n <ngx-material-timepicker #defaultTime></ngx-material-timepicker>\n <span class=\"error-validate\" *ngIf=\"!isValid(row, attr.name)\">\n {{fieldErrorMessage(row, attr.name) | translate}}\n </span>\n </div>\n\t </ng-container>\n\n\t\t\t\t\t\t<ng-container *ngIf=\"attr.type == 'dateTime'\">\n <date-time-picker [min]=\"attr.min\" [max]=\"attr.max\" [(myModel)]=\"newElement[attr.name]\" (myModelChange)=\"changesOut($event)\"></date-time-picker>\n <span class=\"error-validate datetime\" *ngIf=\"!isValid(row, attr.name)\">\n {{fieldErrorMessage(row, attr.name) | translate}}\n </span>\n\t </ng-container>\n\n <ng-container *ngIf=\"attr.type == 'number'\">\n <mat-form-field class=\"editable-field\">\n <input matInput type=\"number\" autocomplete=\"off\" placeholder=\"{{attr.label}}\" [(ngModel)]=\"row[attr.name]\"\n (ngModelChange)=\"changesOut($event)\" min=\"{{attr.min}}\" max=\"{{attr.max}}\" [required]=\"attr.required\">\n <span class=\"error-validate\" *ngIf=\"!isValid(row, attr.name)\">\n {{fieldErrorMessage(row, attr.name) | translate}}\n </span>\n </mat-form-field>\n </ng-container>\n\n <ng-container *ngIf=\"attr.type == 'boolean'\">\n <mat-checkbox [(ngModel)]=\"row[attr.name]\" (ngModelChange)=\"changesOut($event)\" [required]=\"attr.required\">{{attr.label}}</mat-checkbox>\n <span class=\"error-validate boolean\" *ngIf=\"!isValid(row, attr.name)\">\n {{fieldErrorMessage(row, attr.name) | translate}}\n </span>\n </ng-container>\n\n <ng-container *ngIf=\"attr.type == 'select'\">\n <mat-form-field class=\"editable-field\">\n <mat-select [(ngModel)]=\"row[attr.name]\" (ngModelChange)=\"changesOut($event)\" [required]=\"attr.required\">\n <mat-option>...</mat-option>\n <mat-option value=\"{{item.value}}\" *ngFor=\"let item of attr.items;\">{{item.label}}</mat-option>\n </mat-select>\n <span class=\"error-validate\" *ngIf=\"!isValid(row, attr.name)\">\n {{fieldErrorMessage(row, attr.name) | translate}}\n </span>\n </mat-form-field>\n </ng-container>\n\n </td>\n <td *ngIf=\"showDelete\">\n <button mat-button color=\"primary\" (click)=\"removeItem(z)\">Eliminar</button>\n </td>\n </tr>\n </ng-container>\n\n <!--NO DRAGGABLE-->\n <ng-container *ngIf=\"!draggable\">\n <tr td-data-table-row *ngFor=\"let row of value; let z=index\">\n <td td-data-table-cell *ngFor=\"let attr of schema; let i=index\">\n <ng-container *ngIf=\"attr.type == 'string'\">\n <mat-form-field class=\"editable-field\">\n <input matInput autocomplete=\"off\" placeholder=\"{{attr.label}}\" [(ngModel)]=\"row[attr.name]\" (ngModelChange)=\"changesOut($event)\">\n <span class=\"error-validate\" *ngIf=\"!isValid(row, attr.name)\">\n {{fieldErrorMessage(row, attr.name) | translate}}\n </span>\n </mat-form-field>\n </ng-container>\n\n <ng-container *ngIf=\"attr.type == 'date'\">\n <mat-form-field class=\"editable-field\">\n <input matInput autocomplete=\"off\" [matDatepicker]=\"j\" placeholder=\"{{attr.label}}\" [attr.id]=\"'dtPicker' + j\"\n [(ngModel)]=\"row[attr.name]\" (ngModelChange)=\"changesOut($event)\">\n <mat-datepicker-toggle matSuffix [for]=\"j\"></mat-datepicker-toggle><mat-datepicker #j></mat-datepicker>\n <span class=\"error-validate\" *ngIf=\"!isValid(row, attr.name)\">\n {{fieldErrorMessage(row, attr.name) | translate}}\n </span>\n </mat-form-field>\n </ng-container>\n\n <ng-container *ngIf=\"attr.type == 'time'\">\n <div class=\"time-field\">\n <label class=\"timeLabel\">Hora</label>\n <input autocomplete=\"off\" aria-label=\"default time\" [ngxTimepicker]=\"defaultTime\" [value]=\"row[attr.name]\"\n readonly (ngModelChange)=\"changesOut($event)\">\n <ngx-material-timepicker #defaultTime></ngx-material-timepicker>\n <span class=\"error-validate\" *ngIf=\"!isValid(row, attr.name)\">\n {{fieldErrorMessage(row, attr.name) | translate}}\n </span>\n </div>\n </ng-container>\n\n\t\t\t\t\t\t\t<ng-container *ngIf=\"attr.type == 'dateTime'\">\n <date-time-picker [min]=\"attr.min\" [max]=\"attr.max\" [(myModel)]=\"row[attr.name]\" (myModelChange)=\"changesOut($event)\"></date-time-picker>\n <span class=\"error-validate datetime\" *ngIf=\"!isValid(row, attr.name)\">\n {{fieldErrorMessage(row, attr.name) | translate}}\n </span>\n </ng-container>\n\n <ng-container *ngIf=\"attr.type == 'number'\">\n <mat-form-field class=\"editable-field\">\n <input matInput type=\"number\" autocomplete=\"off\" placeholder=\"{{attr.label}}\"\n [(ngModel)]=\"row[attr.name]\" (ngModelChange)=\"changesOut($event)\">\n <span class=\"error-validate\" *ngIf=\"!isValid(row, attr.name)\">\n {{fieldErrorMessage(row, attr.name) | translate}}\n </span>\n </mat-form-field>\n </ng-container>\n\n <ng-container *ngIf=\"attr.type == 'boolean'\">\n <mat-checkbox [(ngModel)]=\"row[attr.name]\" (ngModelChange)=\"changesOut($event)\">{{attr.label}}</mat-checkbox>\n <span class=\"error-validate boolean\" *ngIf=\"!isValid(row, attr.name)\">\n {{fieldErrorMessage(row, attr.name) | translate}}\n </span>\n </ng-container>\n\n <ng-container *ngIf=\"attr.type == 'select'\">\n <mat-form-field class=\"editable-field\">\n <mat-select [(ngModel)]=\"row[attr.name]\" (ngModelChange)=\"changesOut($event)\">\n <mat-option>...</mat-option>\n <mat-option value=\"{{item.value}}\" *ngFor=\"let item of attr.items;\">{{item.label}}</mat-option>\n </mat-select>\n <span class=\"error-validate\" *ngIf=\"!isValid(row, attr.name)\">\n {{fieldErrorMessage(row, attr.name) | translate}}\n </span>\n </mat-form-field>\n </ng-container>\n\n </td>\n <td *ngIf=\"showDelete\">\n <button mat-button color=\"primary\" (click)=\"removeItem(z)\">Eliminar</button>\n </td>\n </tr>\n </ng-container>\n </tbody>\n </table>\n</div>\n<div class=\"details\">\n {{extras.infoDetail}}\n</div>\n"
},] },
];
/** @nocollapse */
EditableTableComponent.ctorParameters = function () { return [
{ type: TranslateService, },
{ type: MatDialog, },
{ type: ChangeDetectorRef, },
]; };
return EditableTableComponent;
}(AbstractControlValueAccessor));
export { EditableTableComponent };
function EditableTableComponent_tsickle_Closure_declarations() {
/** @type {!Array<{type: !Function, args: (undefined|!Array<?>)}>} */
EditableTableComponent.decorators;
/**
* @nocollapse
* @type {function(): !Array<(null|{type: ?, decorators: (undefined|!Array<{type: !Function, args: (undefined|!Array<?>)}>)})>}
*/
EditableTableComponent.ctorParameters;
/** @type {?} */
EditableTableComponent.prototype.control;
/**
* Component Attributes
* @type {?}
*/
EditableTableComponent.prototype.label;
/** @type {?} */
EditableTableComponent.prototype.outputItems;
/** @type {?} */
EditableTableComponent.prototype.schema;
/** @type {?} */
EditableTableComponent.prototype.draggable;
/** @type {?} */
EditableTableComponent.prototype.newElement;
/** @type {?} */
EditableTableComponent.prototype.extras;
/** @type {?} */
EditableTableComponent.prototype.showDelete;
/** @type {?} */
EditableTableComponent.prototype.addTitle;
/** @type {?} */
EditableTableComponent.prototype.translator;
/** @type {?} */
EditableTableComponent.prototype.dialog;
/** @type {?} */
EditableTableComponent.prototype.changeDetector;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWRpdGFibGUtdGFibGUuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vQGNvdmFsZW50L2R5bmFtaWMtZm9ybXMvIiwic291cmNlcyI6WyJkeW5hbWljLWVsZW1lbnRzL2VkaXRhYmxlLXRhYmxlL2VkaXRhYmxlLXRhYmxlLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsVUFBVSxFQUFFLGlCQUFpQixFQUE2QixNQUFNLGVBQWUsQ0FBQztBQUNwRyxPQUFPLEVBQUUsaUJBQWlCLEVBQWlELE1BQU0sZ0JBQWdCLENBQUM7QUFFbEcsT0FBTyxFQUFFLDRCQUE0QixFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFJakYsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDdkQsT0FBTyxFQUFFLFNBQVMsRUFBbUIsTUFBTSxtQkFBbUIsQ0FBQztBQUkvRCxPQUFPLEVBQWMsZUFBZSxFQUFDLE1BQU0sd0JBQXdCLENBQUM7QUFFcEUsT0FBTyxLQUFLLE9BQU8sTUFBTSxRQUFRLENBQUM7QUFDbEMsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sbURBQW1ELENBQUM7QUFDekYsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sdURBQXVELENBQUM7QUFFL0YscUJBQU0sTUFBTSxHQUFHLE9BQU8sQ0FBQztBQUV2QixNQUFNLENBQUMscUJBQU0sa0NBQWtDLEdBQVE7SUFDdEQsT0FBTyxFQUFFLGlCQUFpQjtJQUMxQixXQUFXLEVBQUUsVUFBVSxDQUFDLGNBQU0sT0FBQSxzQkFBc0IsRUFBdEIsQ0FBc0IsQ0FBQztJQUNyRCxLQUFLLEVBQUUsSUFBSTtDQUNYLENBQUM7O0lBaVEwQyxrREFBNEI7SUFrQ3ZFLGdDQUFvQixVQUE0QixFQUFTLE1BQWlCLEVBQVUsY0FBaUM7UUFBckgsWUFDQyxpQkFBTyxTQUNQO1FBRm1CLGdCQUFVLEdBQVYsVUFBVSxDQUFrQjtRQUFT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QUEsQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssSUFBSSxLQUFLLENBQUMsQ0FBQyxDQUFDO3dCQUN6QyxPQUFPLEdBQUcsTUFBTSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUM7cUJBQ3hDO2lCQUNEO2FBQ0Q7U0FDRDtRQUNELE1BQU0sQ0FBQyxPQUFPLENBQUM7S0FDZjs7Ozs7O0lBRUQsMkNBQVU7Ozs7O0lBQVYsVUFBVyxLQUFhLEVBQUUsT0FBZTtRQUN4QyxxQkFBSSxJQUFJLEdBQVM7WUFDaEIsS0FBSyxFQUFFLEtBQUs7WUFDWixPQUFPLEVBQUcsT0FBTztTQUNqQixDQUFDO1FBQ0YsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsb0JBQW9CLEVBQUUsRUFBRSxJQUFJLEVBQUcsSUFBSSxFQUFFLENBQUMsQ0FBQztLQUN4RDs7OztJQUVELDRDQUFXOzs7SUFBWDtRQUNDLHFCQUFJLFNBQVMsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO1FBQ3pELE1BQU0sQ0FBQyxTQUFTLENBQUMsV0FBVyxFQUFFLENBQUMsU0FBUyxFQUFFLENBQUM7S0FDM0M7O2dCQWhjRCxTQUFTLFNBQUM7b0JBQ1YsU0FBUyxFQUFFLENBQUUsa0NBQWtDLENBQUU7b0JBQ2pELFFBQVEsRUFBRSxnQkFBZ0I7b0JBQzFCLE1BQU0sRUFBRSxDQUFDLHVnRUFBdWdFLENBQUM7b0JBQ2poRSxRQUFRLEVBQUUsK29lQXlQVjtpQkFDQTs7OztnQkFqUlEsZ0JBQWdCO2dCQUNoQixTQUFTO2dCQVJjLGlCQUFpQjs7aUNBQWpEO0VBeVI0Qyw0QkFBNEI7U0FBM0Qsc0JBQXNCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBmb3J3YXJkUmVmLCBDaGFuZ2VEZXRlY3RvclJlZiwgVmlld0VuY2Fwc3VsYXRpb24sIEluamVjdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBOR19WQUxVRV9BQ0NFU1NPUiwgQ29udHJvbFZhbHVlQWNjZXNzb3IsIEZvcm1Db250cm9sLCBWYWxpZGF0b3JzIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xyXG5cclxuaW1wb3J0IHsgQWJzdHJhY3RDb250cm9sVmFsdWVBY2Nlc3NvciB9IGZyb20gJy4uL2Fic3RyYWN0LWNvbnRyb2wtdmFsdWUtYWNjZXNvcic7XHJcbmltcG9ydCB7IE9ic2VydmFibGUgfSBmcm9tICdyeGpzJztcclxuXHJcbmltcG9ydCB7IFNlbGVjdGlvbk1vZGVsIH0gZnJvbSAnQGFuZ3VsYXIvY2RrL2NvbGxlY3Rpb25zJztcclxuaW1wb3J0IHsgVHJhbnNsYXRlU2VydmljZSB9IGZyb20gJ0BuZ3gtdHJhbnNsYXRlL2NvcmUnO1xyXG5pbXBvcnQgeyBNYXREaWFsb2csIE1BVF9ESUFMT0dfREFUQSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsJztcclxuXHJcbmltcG9ydCB7b2YgYXMgb2JzZXJ2YWJsZU9mfSBmcm9tICdyeGpzJztcclxuXHJcbmltcG9ydCB7Q2RrRHJhZ0Ryb3AsIG1vdmVJdGVtSW5BcnJheX0gZnJvbSAnQGFuZ3VsYXIvY2RrL2RyYWctZHJvcCc7XHJcblxyXG5pbXBvcnQgKiBhcyBsb2Rhc2hfIGZyb20gJ2xvZGFzaCc7XHJcbmltcG9ydCB7IEVycm9yRGlhbG9nQ29tcG9uZW50IH0gZnJvbSAnLi4vLi4vZGlhbG9ncy9lcnJvci1kaWFsb2cvZXJyb3ItZGlhbG9nLmNvbXBvbmVudCc7XHJcbmltcG9ydCB7IENvbmZpcm1EaWFsb2dDb21wb25lbnQgfSBmcm9tICcuLi8uLi9kaWFsb2dzL2NvbmZpcm0tZGlhbG9nL2NvbmZpcm0tZGlhbG9nLmNvbXBvbmVudCc7XHJcblxyXG5jb25zdCBsb2Rhc2ggPSBsb2Rhc2hfO1xyXG5cclxuZXhwb3J0IGNvbnN0IElOUFVUX0lOUFVUX0NPTlRST0xfVkFMVUVfQUNDRVNTT1I6IGFueSA9IHtcclxuXHRwcm92aWRlOiBOR19WQUxVRV9BQ0NFU1NPUixcclxuXHR1c2VFeGlzdGluZzogZm9yd2FyZFJlZigoKSA9PiBFZGl0YWJsZVRhYmxlQ29tcG9uZW50KSxcclxuXHRtdWx0aTogdHJ1ZSxcclxufTtcclxuXHJcbkBDb21wb25lbnQoe1xyXG5cdHByb3ZpZGVyczogWyBJTlBVVF9JTlBVVF9DT05UUk9MX1ZBTFVFX0FDQ0VTU09SIF0sXHJcblx0c2VsZWN0b3I6ICdlZGl0YWJsZS10YWJsZScsXHJcblx0c3R5bGVzOiBbYHRke3BhZGRpbmc6MTBweH0udGQtZHluYW1pYy1pbnB1dC13cmFwcGVyey1tcy1mbGV4LWRpcmVjdGlvbjpyb3c7ZmxleC1kaXJlY3Rpb246cm93O2Rpc3BsYXk6LW1zLWZsZXhib3g7ZGlzcGxheTpmbGV4O2JveC1zaXppbmc6Ym9yZGVyLWJveH0udGQtZHluYW1pYy1pbnB1dC13cmFwcGVyIC50ZC1keW5hbWljLWlucHV0LWZpZWxkey1tcy1mbGV4OjE7ZmxleDoxO2JveC1zaXppbmc6Ym9yZGVyLWJveH0udGQtZHluYW1pYy1pbnB1dC13cmFwcGVyIC5uZ3gtZWRpdG9ye21hcmdpbi10b3A6MTBweH0ubGFiZWx7cGFkZGluZzoxMHB4IDA7ZGlzcGxheTppbmxpbmUtYmxvY2s7d2lkdGg6NTAlfS5jb250YWluZXJ7b3ZlcmZsb3c6YXV0bztib3JkZXI6MXB4IHNvbGlkICNmM2YzZjM7Ym9yZGVyLXJhZGl1czo1cHggNXB4IDAgMH0uc2VsZWN0ZWQtaXRlbXN7cGFkZGluZzo1cHg7ZGlzcGxheTpibG9jaztiYWNrZ3JvdW5kOiNmM2YzZjM7Ym9yZGVyLXJhZGl1czowIDAgNXB4IDVweDttaW4taGVpZ2h0OjMwcHh9LnNlbGVjdGVkLWl0ZW1zIHNwYW57YmFja2dyb3VuZDojNjg5ZjM4O21hcmdpbjoycHg7cGFkZGluZzo1cHg7Ym9yZGVyLXJhZGl1czo1cHg7Y29sb3I6I2ZmZjtkaXNwbGF5OmlubGluZS1ibG9ja30uYnV0dG9uc3tkaXNwbGF5OmlubGluZS1ibG9jazt3aWR0aDo1MCU7dGV4dC1hbGlnbjpyaWdodH0uYnV0dG9ucyBidXR0b257cGFkZGluZzowO3dpZHRoOjMwcHghaW1wb3J0YW50O21pbi13aWR0aDozMHB4O2JvcmRlci1yYWRpdXM6NTBweDtoZWlnaHQ6MzBweH0uYnV0dG9ucyBidXR0b24gbWF0LWljb257cG9zaXRpb246cmVsYXRpdmUhaW1wb3J0YW50O3RvcDotNHB4IWltcG9ydGFudH0ubWFpbi1jb250YWluZXJ7Ym9yZGVyOjFweCBzb2xpZCAjZjNmM2YzO2JvcmRlci1yYWRpdXM6NXB4O3BhZGRpbmc6NXB4IDEwcHggMjBweDtvdmVyZmxvdzphdXRvfWhye2Rpc3BsYXk6YmxvY2s7aGVpZ2h0OjFweDtib3JkZXI6MDtib3JkZXItdG9wOjFweCBzb2xpZCAjY2NjO21hcmdpbjoxZW0gMDtwYWRkaW5nOjB9LmRyYWdnZXJ7dGV4dC1hbGlnbjpjZW50ZXI7YmFja2dyb3VuZDojZjNmM2YzO2hlaWdodDoyNHB4O2JvcmRlci1yYWRpdXM6NXB4O3dpZHRoOjM2cHg7bWFyZ2luOmF1dG8gOHB4IGF1dG8gYXV0bztib3JkZXI6MXB4IHNvbGlkICNkZGQ7Y3Vyc29yOm1vdmV9LmVycm9yLXZhbGlkYXRle2NvbG9yOiNlNTM5MzQ7Zm9udC1zaXplOjc1JTt0b3A6MzNweDtwb3NpdGlvbjphYnNvbHV0ZTtsZWZ0OjB9LmVycm9yLXZhbGlkYXRlLmJvb2xlYW57cG9zaXRpb246cmVsYXRpdmUhaW1wb3J0YW50O3RvcDo5cHg7d2lkdGg6MTAwJTtkaXNwbGF5OmlubGluZS1ibG9ja30uZXJyb3ItdmFsaWRhdGUuZGF0ZXRpbWV7cG9zaXRpb246cmVsYXRpdmUhaW1wb3J0YW50O3RvcDo5cHg7cGFkZGluZy1ib3R0b206MTBweDt3aWR0aDoxMDAlO2Rpc3BsYXk6aW5saW5lLWJsb2NrfS5lZGl0YWJsZS1maWVsZHttaW4td2lkdGg6MTAwJX10YWJsZXt3aWR0aDoxMDAlO2JvcmRlci1jb2xsYXBzZTpjb2xsYXBzZTtib3JkZXItc3BhY2luZzowfXRyIHRoe3RleHQtYWxpZ246bGVmdH10cjpudGgtY2hpbGQoZXZlbil7YmFja2dyb3VuZDojZmFmYWZhfXRyOm50aC1jaGlsZChldmVuKSBpbnB1dHtiYWNrZ3JvdW5kOiNmYWZhZmEhaW1wb3J0YW50fS9kZWVwLyAudGltZS1maWVsZCBsYWJlbHtkaXNwbGF5OmJsb2NrO2NvbG9yOiM5MjkyOTI7bWFyZ2luLXRvcDotMTJweH0vZGVlcC8gLnRpbWUtZmllbGQgaW5wdXR7Ym9yZGVyOjA7Ym9yZGVyLWJvdHRvbToxcHggc29saWQgIzllOWY5ZTtmb250LXNpemU6MTRweH0vZGVlcC8gLm1hdC1kYXRlcGlja2VyLXRvZ2dsZSBidXR0b257Ym94LXNoYWRvdzowIDNweCAxcHggLTJweCByZ2JhKDAsMCwwLC4yKSwwIDJweCAycHggMCByZ2JhKDAsMCwwLC4xNCksMCAxcHggNXB4IDAgcmdiYSgwLDAsMCwuMTIpO2JvcmRlci1yYWRpdXM6M3B4IWltcG9ydGFudH0vZGVlcC8gLnRpbWUtZmllbGR7bWFyZ2luLWJvdHRvbTo0cHh9LmRldGFpbHN7Zm9udC1zaXplOjExcHg7cGFkZGluZzo1cHggMH1gXSxcclxuXHR0ZW1wbGF0ZTogYDxkaXYgY2xhc3M9XCJsYWJlbFwiPnt7bGFiZWx9fTwvZGl2PlxyXG48ZGl2IGNsYXNzPVwibWFpbi1jb250YWluZXJcIj5cclxuICAgIDx0YWJsZSB0ZC1kYXRhLXRhYmxlPlxyXG4gICAgICAgIDx0aGVhZD5cclxuICAgICAgICAgICAgPHRyIHRkLWRhdGEtdGFibGUtY29sdW1uLXJvdz5cclxuICAgICAgICAgICAgICAgIDx0aCB0ZC1kYXRhLXRhYmxlLWNvbHVtbj5cclxuICAgICAgICAgICAgICAgICAgICB7e2FkZFRpdGxlfX1cclxuICAgICAgICAgICAgICAgIDwvdGg+XHJcbiAgICAgICAgICAgIDwvdHI+XHJcbiAgICAgICAgPC90aGVhZD5cclxuICAgICAgICA8dGJvZHk+XHJcbiAgICAgICAgICAgIDx0ciB0ZC1kYXRhLXRhYmxlLXJvdz5cclxuICAgICAgICAgICAgICAgIDx0ZCB0ZC1kYXRhLXRhYmxlLWNlbGwgKm5nRm9yPVwibGV0IGl0ZW0gb2Ygc2NoZW1hOyBsZXQgaT1pbmRleFwiPlxyXG4gICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJpdGVtLnR5cGUgPT0gJ3N0cmluZydcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIGNsYXNzPVwiZWRpdGFibGUtZmllbGRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCBtYXRJbnB1dCBhdXRvY29tcGxldGU9XCJvZmZcIiBwbGFjZWhvbGRlcj1cInt7aXRlbS5sYWJlbH19XCIgWyhuZ01vZGVsKV09XCJuZXdFbGVtZW50W2l0ZW0ubmFtZV1cIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIml0ZW0udHlwZSA9PSAnZGF0ZSdcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIGNsYXNzPVwiZWRpdGFibGUtZmllbGRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCBtYXRJbnB1dCBhdXRvY29tcGxldGU9XCJvZmZcIiBbbWF0RGF0ZXBpY2tlcl09XCJpXCIgcGxhY2Vob2xkZXI9XCJ7e2l0ZW0ubGFiZWx9fVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2F0dHIuaWRdPVwiJ2R0UGlja2VyJyArIGlcIiBbKG5nTW9kZWwpXT1cIm5ld0VsZW1lbnRbaXRlbS5uYW1lXVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1kYXRlcGlja2VyLXRvZ2dsZSBtYXRTdWZmaXggW2Zvcl09XCJpXCI+PC9tYXQtZGF0ZXBpY2tlci10b2dnbGU+PG1hdC1kYXRlcGlja2VyICNpPjwvbWF0LWRhdGVwaWNrZXI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcbiAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJpdGVtLnR5cGUgPT0gJ3RpbWUnXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0aW1lLWZpZWxkXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJ0aW1lTGFiZWxcIj5Ib3JhPC9sYWJlbD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCBhcmlhLWxhYmVsPVwiZGVmYXVsdCB0aW1lXCIgYXV0b2NvbXBsZXRlPVwib2ZmXCIgW25neFRpbWVwaWNrZXJdPVwiZGVmYXVsdFRpbWVcIiBbKG5nTW9kZWwpXT1cIm5ld0VsZW1lbnRbaXRlbS5uYW1lXVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5neC1tYXRlcmlhbC10aW1lcGlja2VyICNkZWZhdWx0VGltZT48L25neC1tYXRlcmlhbC10aW1lcGlja2VyPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuXHJcblx0XHRcdFx0XHQ8bmctY29udGFpbmVyICpuZ0lmPVwiaXRlbS50eXBlID09ICdkYXRlVGltZSdcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGRhdGUtdGltZS1waWNrZXIgW21pbl09XCJpdGVtLm1pblwiIFttYXhdPVwiaXRlbS5tYXhcIiBbKG15TW9kZWwpXT1cIm5ld0VsZW1lbnRbaXRlbS5uYW1lXVwiPjwvZGF0ZS10aW1lLXBpY2tlcj5cclxuICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIml0ZW0udHlwZSA9PSAnbnVtYmVyJ1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgY2xhc3M9XCJlZGl0YWJsZS1maWVsZFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IG1hdElucHV0IHR5cGU9XCJudW1iZXJcIiBhdXRvY29tcGxldGU9XCJvZmZcIiBwbGFjZWhvbGRlcj1cInt7aXRlbS5sYWJlbH19XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cIm5ld0VsZW1lbnRbaXRlbS5uYW1lXVwiIG1pbj1cInt7aXRlbS5taW59fVwiIG1heD1cInt7aXRlbS5tYXh9fVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxyXG4gICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG5cclxuICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiaXRlbS50eXBlID09ICdib29sZWFuJ1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWNoZWNrYm94IFsobmdNb2RlbCldPVwibmV3RWxlbWVudFtpdGVtLm5hbWVdXCI+e3tpdGVtLmxhYmVsfX08L21hdC1jaGVja2JveD5cclxuICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIml0ZW0udHlwZSA9PSAnc2VsZWN0J1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgY2xhc3M9XCJlZGl0YWJsZS1maWVsZFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1zZWxlY3QgcGxhY2Vob2xkZXI9XCJ7e2l0ZW0ubGFiZWx9fVwiIFsodmFsdWUpXT1cIm5ld0VsZW1lbnRbaXRlbS5uYW1lXVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtb3B0aW9uPi4uLjwvbWF0LW9wdGlvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LW9wdGlvbiB2YWx1ZT1cInt7aXRlbS52YWx1ZX19XCIgKm5nRm9yPVwibGV0IGl0ZW0gb2YgaXRlbS5pdGVtcztcIj57e2l0ZW0ubGFiZWx9fTwvbWF0LW9wdGlvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LXNlbGVjdD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuXHJcbiAgICAgICAgICAgICAgICA8L3RkPlxyXG4gICAgICAgICAgICAgICAgPHRkPlxyXG4gICAgICAgICAgICAgICAgICAgIDxidXR0b24gbWF0LWJ1dHRvbiBjb2xvcj1cInByaW1hcnlcIiAoY2xpY2spPVwiYWRkSXRlbSgpXCI+QcOxYWRpcjwvYnV0dG9uPlxyXG4gICAgICAgICAgICAgICAgPC90ZD5cclxuICAgICAgICAgICAgPC90cj5cclxuICAgICAgICA8L3Rib2R5PlxyXG4gICAgPC90YWJsZT5cclxuXHJcbiAgICA8aHIgLz5cclxuXHJcbiAgICA8dGFibGUgdGQtZGF0YS10YWJsZT5cclxuICAgICAgICA8dGhlYWQ+XHJcbiAgICAgICAgICAgIDx0ciB0ZC1kYXRhLXRhYmxlLWNvbHVtbi1yb3c+XHJcbiAgICAgICAgICAgICAgICA8dGggdGQtZGF0YS10YWJsZS1jb2x1bW4gKm5nSWY9XCJkcmFnZ2FibGVcIj48L3RoPlxyXG4gICAgICAgICAgICAgICAgPHRoIHRkLWRhdGEtdGFibGUtY29sdW1uXHJcbiAgICAgICAgICAgICAgICAgICAgKm5nRm9yPVwibGV0IGNvbHVtbiBvZiBzY2hlbWFcIj5cclxuICAgICAgICAgICAgICAgICAgICB7e2NvbHVtbi5sYWJlbH19XHJcbiAgICAgICAgICAgICAgICA8L3RoPlxyXG4gICAgICAgICAgICA8L3RyPlxyXG4gICAgICAgIDwvdGhlYWQ+XHJcbiAgICAgICAgPHRib2R5IGNka0Ryb3BMaXN0IGNsYXNzPVwiZXhhbXBsZS1saXN0XCIgKGNka0Ryb3BMaXN0RHJvcHBlZCk9XCJkcm9wKCRldmVudClcIj5cclxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImRyYWdnYWJsZVwiPlxyXG4gICAgICAgICAgICAgICAgPCEtLURSQUdHQUJMRTogSVNTVUUgIzEzODkzLS0+XHJcbiAgICAgICAgICAgICAgICA8dHIgdGQtZGF0YS10YWJsZS1yb3cgKm5nRm9yPVwibGV0IHJvdyBvZiB2YWx1ZTsgbGV0IHo9aW5kZXhcIiBjZGtEcmFnPlxyXG4gICAgICAgICAgICAgICAgICAgIDx0ZD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRyYWdnZXJcIiBjZGtEcmFnSGFuZGxlPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uPmRyYWdfaGFuZGxlPC9tYXQtaWNvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgPC90ZD5cclxuICAgICAgICAgICAgICAgICAgICA8dGQgdGQtZGF0YS10YWJsZS1jZWxsICpuZ0Zvcj1cImxldCBhdHRyIG9mIHNjaGVtYTsgbGV0IGk9aW5kZXhcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImF0dHIudHlwZSA9PSAnc3RyaW5nJ1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIGNsYXNzPVwiZWRpdGFibGUtZmllbGRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgbWF0SW5wdXQgcGxhY2Vob2xkZXI9XCJ7e2F0dHIubGFiZWx9fVwiIFsobmdNb2RlbCldPVwicm93W2F0dHIubmFtZV1cIiBhdXRvY29tcGxldGU9XCJvZmZcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJjaGFuZ2VzT3V0KCRldmVudClcIiBbcmVxdWlyZWRdPVwiYXR0ci5yZXF1aXJlZFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZXJyb3ItdmFsaWRhdGVcIiAqbmdJZj1cIiFpc1ZhbGlkKHJvdywgYXR0ci5uYW1lKVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7e2ZpZWxkRXJyb3JNZXNzYWdlKHJvdywgYXR0ci5uYW1lKSB8IHRyYW5zbGF0ZX19XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiYXR0ci50eXBlID09ICdkYXRlJ1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIGNsYXNzPVwiZWRpdGFibGUtZmllbGRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgbWF0SW5wdXQgYXV0b2NvbXBsZXRlPVwib2ZmXCIgW21hdERhdGVwaWNrZXJdPVwialwiIHBsYWNlaG9sZGVyPVwie3thdHRyLmxhYmVsfX1cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbYXR0ci5pZF09XCInZHRQaWNrZXInICsgalwiIFsobmdNb2RlbCldPVwicm93W2F0dHIubmFtZV1cIiAobmdNb2RlbENoYW5nZSk9XCJjaGFuZ2VzT3V0KCRldmVudClcIiBbcmVxdWlyZWRdPVwiYXR0ci5yZXF1aXJlZFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZGF0ZXBpY2tlci10b2dnbGUgbWF0U3VmZml4IFtmb3JdPVwialwiPjwvbWF0LWRhdGVwaWNrZXItdG9nZ2xlPjxtYXQtZGF0ZXBpY2tlciAjaj48L21hdC1kYXRlcGlja2VyPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZXJyb3ItdmFsaWRhdGVcIiAqbmdJZj1cIiFpc1ZhbGlkKHJvdywgYXR0ci5uYW1lKVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7e2ZpZWxkRXJyb3JNZXNzYWdlKHJvdywgYXR0ci5uYW1lKSB8IHRyYW5zbGF0ZX19XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcblxyXG5cdFx0XHRcdFx0XHQ8bmctY29udGFpbmVyICpuZ0lmPVwiYXR0ci50eXBlID09ICd0aW1lJ1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRpbWUtZmllbGRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJ0aW1lTGFiZWxcIj5Ib3JhPC9sYWJlbD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgYXV0b2NvbXBsZXRlPVwib2ZmXCIgYXJpYS1sYWJlbD1cImRlZmF1bHQgdGltZVwiIFtuZ3hUaW1lcGlja2VyXT1cImRlZmF1bHRUaW1lXCJ