@noaestudio/forms
Version:
Dynamic forms extension for Covalent
534 lines (509 loc) • 67.2 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
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';
const /** @type {?} */ lodash = lodash_;
export const /** @type {?} */ INPUT_INPUT_CONTROL_VALUE_ACCESSOR = {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => EditableTableComponent),
multi: true,
};
export class EditableTableComponent extends AbstractControlValueAccessor {
/**
* @param {?} translator
* @param {?} dialog
* @param {?} changeDetector
*/
constructor(translator, dialog, changeDetector) {
super();
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 {?}
*/
ngOnInit() {
//Inicializamos el value si no llega nada por defecto
if (this.value == undefined) {
this.value = [];
}
//Creamos el newElement en base al esquema
for (let /** @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 {?}
*/
addItem() {
this.value.push(this.cloneObject(this.newElement));
this.control.setValue(this.value);
this.checkRequired();
this.checkValidators();
}
/**
* @param {?} index
* @return {?}
*/
removeItem(index) {
let /** @type {?} */ deleteItem = () => {
this.value.splice(index, 1);
this.control.setValue(this.value);
this.checkRequired();
this.checkValidators();
this.changeDetector.detectChanges();
};
this.openConfirm().then(confirm => {
if (confirm) {
if (this.extras != undefined && this.extras != null && this.extras.deleteAction != undefined) {
this.extras.deleteAction(this.value[index]).then(result => {
if (result) {
deleteItem();
}
}).catch(err => {
let /** @type {?} */ errorMessage = err.error.message;
this.openDialog("Error", errorMessage);
});
}
else {
deleteItem();
}
}
});
}
/**
* @param {?} obj
* @return {?}
*/
cloneObject(obj) {
let /** @type {?} */ cloneLodash = lodash.cloneDeep(obj);
return cloneLodash;
}
/**
* @param {?} $event
* @return {?}
*/
changesOut($event) {
this.control.setValue(this.value);
this.checkRequired();
this.checkValidators();
}
/**
* @param {?} event
* @return {?}
*/
drop(event) {
moveItemInArray(this.value, event.previousIndex, event.currentIndex);
this.control.setValue(this.value);
}
/**
* @return {?}
*/
checkRequired() {
this.value.forEach(field => {
Object.keys(field).forEach(key => {
let /** @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 {?}
*/
getFieldSchema(name) {
let /** @type {?} */ schema = null;
this.schema.forEach(item => {
if (item.name == name) {
schema = item;
}
});
return schema;
}
/**
* @return {?}
*/
checkValidators() {
if (this.extras.rowValidator) {
for (let /** @type {?} */ item of this.value) {
let /** @type {?} */ errors = this.extras.rowValidator(item);
if (errors) {
this.control.setErrors(errors.errorList);
}
}
}
}
/**
* @param {?} item
* @param {?} field
* @return {?}
*/
isValid(item, field) {
let /** @type {?} */ valid = true;
if (this.extras.rowValidator) {
let /** @type {?} */ errors = this.extras.rowValidator(item);
if (errors) {
for (let /** @type {?} */ i = 0; i < errors.errorFields.length; i++) {
if (errors.errorFields[i].field == field) {
valid = false;
}
}
}
}
return valid;
}
/**
* @param {?} item
* @param {?} field
* @return {?}
*/
fieldErrorMessage(item, field) {
let /** @type {?} */ message = "";
if (this.extras.rowValidator) {
let /** @type {?} */ errors = this.extras.rowValidator(item);
if (errors) {
for (let /** @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 {?}
*/
openDialog(title, message) {
let /** @type {?} */ data = {
title: title,
message: message
};
this.dialog.open(ErrorDialogComponent, { data: data });
}
/**
* @return {?}
*/
openConfirm() {
let /** @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>
<div class="main-container">
<table td-data-table>
<thead>
<tr td-data-table-column-row>
<th td-data-table-column>
{{addTitle}}
</th>
</tr>
</thead>
<tbody>
<tr td-data-table-row>
<td td-data-table-cell *ngFor="let item of schema; let i=index">
<ng-container *ngIf="item.type == 'string'">
<mat-form-field class="editable-field">
<input matInput autocomplete="off" placeholder="{{item.label}}" [(ngModel)]="newElement[item.name]">
</mat-form-field>
</ng-container>
<ng-container *ngIf="item.type == 'date'">
<mat-form-field class="editable-field">
<input matInput autocomplete="off" [matDatepicker]="i" placeholder="{{item.label}}"
[attr.id]="'dtPicker' + i" [(ngModel)]="newElement[item.name]">
<mat-datepicker-toggle matSuffix [for]="i"></mat-datepicker-toggle><mat-datepicker #i></mat-datepicker>
</mat-form-field>
</ng-container>
<ng-container *ngIf="item.type == 'time'">
<div class="time-field">
<label class="timeLabel">Hora</label>
<input aria-label="default time" autocomplete="off" [ngxTimepicker]="defaultTime" [(ngModel)]="newElement[item.name]">
<ngx-material-timepicker #defaultTime></ngx-material-timepicker>
</div>
</ng-container>
<ng-container *ngIf="item.type == 'dateTime'">
<date-time-picker [min]="item.min" [max]="item.max" [(myModel)]="newElement[item.name]"></date-time-picker>
</ng-container>
<ng-container *ngIf="item.type == 'number'">
<mat-form-field class="editable-field">
<input matInput type="number" autocomplete="off" placeholder="{{item.label}}"
[(ngModel)]="newElement[item.name]" min="{{item.min}}" max="{{item.max}}">
</mat-form-field>
</ng-container>
<ng-container *ngIf="item.type == 'boolean'">
<mat-checkbox [(ngModel)]="newElement[item.name]">{{item.label}}</mat-checkbox>
</ng-container>
<ng-container *ngIf="item.type == 'select'">
<mat-form-field class="editable-field">
<mat-select placeholder="{{item.label}}" [(value)]="newElement[item.name]">
<mat-option>...</mat-option>
<mat-option value="{{item.value}}" *ngFor="let item of item.items;">{{item.label}}</mat-option>
</mat-select>
</mat-form-field>
</ng-container>
</td>
<td>
<button mat-button color="primary" (click)="addItem()">Añadir</button>
</td>
</tr>
</tbody>
</table>
<hr />
<table td-data-table>
<thead>
<tr td-data-table-column-row>
<th td-data-table-column *ngIf="draggable"></th>
<th td-data-table-column
*ngFor="let column of schema">
{{column.label}}
</th>
</tr>
</thead>
<tbody cdkDropList class="example-list" (cdkDropListDropped)="drop($event)">
<ng-container *ngIf="draggable">
<!--DRAGGABLE: ISSUE #13893-->
<tr td-data-table-row *ngFor="let row of value; let z=index" cdkDrag>
<td>
<div class="dragger" cdkDragHandle>
<mat-icon>drag_handle</mat-icon>
</div>
</td>
<td td-data-table-cell *ngFor="let attr of schema; let i=index">
<ng-container *ngIf="attr.type == 'string'">
<mat-form-field class="editable-field">
<input matInput placeholder="{{attr.label}}" [(ngModel)]="row[attr.name]" autocomplete="off"
(ngModelChange)="changesOut($event)" [required]="attr.required">
<span class="error-validate" *ngIf="!isValid(row, attr.name)">
{{fieldErrorMessage(row, attr.name) | translate}}
</span>
</mat-form-field>
</ng-container>
<ng-container *ngIf="attr.type == 'date'">
<mat-form-field class="editable-field">
<input matInput autocomplete="off" [matDatepicker]="j" placeholder="{{attr.label}}"
[attr.id]="'dtPicker' + j" [(ngModel)]="row[attr.name]" (ngModelChange)="changesOut($event)" [required]="attr.required">
<mat-datepicker-toggle matSuffix [for]="j"></mat-datepicker-toggle><mat-datepicker #j></mat-datepicker>
<span class="error-validate" *ngIf="!isValid(row, attr.name)">
{{fieldErrorMessage(row, attr.name) | translate}}
</span>
</mat-form-field>
</ng-container>
<ng-container *ngIf="attr.type == 'time'">
<div class="time-field">
<label class="timeLabel">Hora</label>
<input autocomplete="off" aria-label="default time" [ngxTimepicker]="defaultTime"
[value]="row[attr.name]" readonly (ngModelChange)="changesOut($event)">
<ngx-material-timepicker #defaultTime></ngx-material-timepicker>
<span class="error-validate" *ngIf="!isValid(row, attr.name)">
{{fieldErrorMessage(row, attr.name) | translate}}
</span>
</div>
</ng-container>
<ng-container *ngIf="attr.type == 'dateTime'">
<date-time-picker [min]="attr.min" [max]="attr.max" [(myModel)]="newElement[attr.name]" (myModelChange)="changesOut($event)"></date-time-picker>
<span class="error-validate datetime" *ngIf="!isValid(row, attr.name)">
{{fieldErrorMessage(row, attr.name) | translate}}
</span>
</ng-container>
<ng-container *ngIf="attr.type == 'number'">
<mat-form-field class="editable-field">
<input matInput type="number" autocomplete="off" placeholder="{{attr.label}}" [(ngModel)]="row[attr.name]"
(ngModelChange)="changesOut($event)" min="{{attr.min}}" max="{{attr.max}}" [required]="attr.required">
<span class="error-validate" *ngIf="!isValid(row, attr.name)">
{{fieldErrorMessage(row, attr.name) | translate}}
</span>
</mat-form-field>
</ng-container>
<ng-container *ngIf="attr.type == 'boolean'">
<mat-checkbox [(ngModel)]="row[attr.name]" (ngModelChange)="changesOut($event)" [required]="attr.required">{{attr.label}}</mat-checkbox>
<span class="error-validate boolean" *ngIf="!isValid(row, attr.name)">
{{fieldErrorMessage(row, attr.name) | translate}}
</span>
</ng-container>
<ng-container *ngIf="attr.type == 'select'">
<mat-form-field class="editable-field">
<mat-select [(ngModel)]="row[attr.name]" (ngModelChange)="changesOut($event)" [required]="attr.required">
<mat-option>...</mat-option>
<mat-option value="{{item.value}}" *ngFor="let item of attr.items;">{{item.label}}</mat-option>
</mat-select>
<span class="error-validate" *ngIf="!isValid(row, attr.name)">
{{fieldErrorMessage(row, attr.name) | translate}}
</span>
</mat-form-field>
</ng-container>
</td>
<td *ngIf="showDelete">
<button mat-button color="primary" (click)="removeItem(z)">Eliminar</button>
</td>
</tr>
</ng-container>
<!--NO DRAGGABLE-->
<ng-container *ngIf="!draggable">
<tr td-data-table-row *ngFor="let row of value; let z=index">
<td td-data-table-cell *ngFor="let attr of schema; let i=index">
<ng-container *ngIf="attr.type == 'string'">
<mat-form-field class="editable-field">
<input matInput autocomplete="off" placeholder="{{attr.label}}" [(ngModel)]="row[attr.name]" (ngModelChange)="changesOut($event)">
<span class="error-validate" *ngIf="!isValid(row, attr.name)">
{{fieldErrorMessage(row, attr.name) | translate}}
</span>
</mat-form-field>
</ng-container>
<ng-container *ngIf="attr.type == 'date'">
<mat-form-field class="editable-field">
<input matInput autocomplete="off" [matDatepicker]="j" placeholder="{{attr.label}}" [attr.id]="'dtPicker' + j"
[(ngModel)]="row[attr.name]" (ngModelChange)="changesOut($event)">
<mat-datepicker-toggle matSuffix [for]="j"></mat-datepicker-toggle><mat-datepicker #j></mat-datepicker>
<span class="error-validate" *ngIf="!isValid(row, attr.name)">
{{fieldErrorMessage(row, attr.name) | translate}}
</span>
</mat-form-field>
</ng-container>
<ng-container *ngIf="attr.type == 'time'">
<div class="time-field">
<label class="timeLabel">Hora</label>
<input autocomplete="off" aria-label="default time" [ngxTimepicker]="defaultTime" [value]="row[attr.name]"
readonly (ngModelChange)="changesOut($event)">
<ngx-material-timepicker #defaultTime></ngx-material-timepicker>
<span class="error-validate" *ngIf="!isValid(row, attr.name)">
{{fieldErrorMessage(row, attr.name) | translate}}
</span>
</div>
</ng-container>
<ng-container *ngIf="attr.type == 'dateTime'">
<date-time-picker [min]="attr.min" [max]="attr.max" [(myModel)]="row[attr.name]" (myModelChange)="changesOut($event)"></date-time-picker>
<span class="error-validate datetime" *ngIf="!isValid(row, attr.name)">
{{fieldErrorMessage(row, attr.name) | translate}}
</span>
</ng-container>
<ng-container *ngIf="attr.type == 'number'">
<mat-form-field class="editable-field">
<input matInput type="number" autocomplete="off" placeholder="{{attr.label}}"
[(ngModel)]="row[attr.name]" (ngModelChange)="changesOut($event)">
<span class="error-validate" *ngIf="!isValid(row, attr.name)">
{{fieldErrorMessage(row, attr.name) | translate}}
</span>
</mat-form-field>
</ng-container>
<ng-container *ngIf="attr.type == 'boolean'">
<mat-checkbox [(ngModel)]="row[attr.name]" (ngModelChange)="changesOut($event)">{{attr.label}}</mat-checkbox>
<span class="error-validate boolean" *ngIf="!isValid(row, attr.name)">
{{fieldErrorMessage(row, attr.name) | translate}}
</span>
</ng-container>
<ng-container *ngIf="attr.type == 'select'">
<mat-form-field class="editable-field">
<mat-select [(ngModel)]="row[attr.name]" (ngModelChange)="changesOut($event)">
<mat-option>...</mat-option>
<mat-option value="{{item.value}}" *ngFor="let item of attr.items;">{{item.label}}</mat-option>
</mat-select>
<span class="error-validate" *ngIf="!isValid(row, attr.name)">
{{fieldErrorMessage(row, attr.name) | translate}}
</span>
</mat-form-field>
</ng-container>
</td>
<td *ngIf="showDelete">
<button mat-button color="primary" (click)="removeItem(z)">Eliminar</button>
</td>
</tr>
</ng-container>
</tbody>
</table>
</div>
<div class="details">
{{extras.infoDetail}}
</div>
`
},] },
];
/** @nocollapse */
EditableTableComponent.ctorParameters = () => [
{ type: TranslateService, },
{ type: MatDialog, },
{ type: ChangeDetectorRef, },
];
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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWRpdGFibGUtdGFibGUuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vQGNvdmFsZW50L2R5bmFtaWMtZm9ybXMvIiwic291cmNlcyI6WyJkeW5hbWljLWVsZW1lbnRzL2VkaXRhYmxlLXRhYmxlL2VkaXRhYmxlLXRhYmxlLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsaUJBQWlCLEVBQTZCLE1BQU0sZUFBZSxDQUFDO0FBQ3BHLE9BQU8sRUFBRSxpQkFBaUIsRUFBaUQsTUFBTSxnQkFBZ0IsQ0FBQztBQUVsRyxPQUFPLEVBQUUsNEJBQTRCLEVBQUUsTUFBTSxtQ0FBbUMsQ0FBQztBQUlqRixPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUN2RCxPQUFPLEVBQUUsU0FBUyxFQUFtQixNQUFNLG1CQUFtQixDQUFDO0FBSS9ELE9BQU8sRUFBYyxlQUFlLEVBQUMsTUFBTSx3QkFBd0IsQ0FBQztBQUVwRSxPQUFPLEtBQUssT0FBTyxNQUFNLFFBQVEsQ0FBQztBQUNsQyxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxtREFBbUQsQ0FBQztBQUN6RixPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSx1REFBdUQsQ0FBQztBQUUvRix1QkFBTSxNQUFNLEdBQUcsT0FBTyxDQUFDO0FBRXZCLE1BQU0sQ0FBQyx1QkFBTSxrQ0FBa0MsR0FBUTtJQUN0RCxPQUFPLEVBQUUsaUJBQWlCO0lBQzFCLFdBQVcsRUFBRSxVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMsc0JBQXNCLENBQUM7SUFDckQsS0FBSyxFQUFFLElBQUk7Q0FDWCxDQUFDO0FBaVFGLE1BQU0sNkJBQThCLFNBQVEsNEJBQTRCOzs7Ozs7SUFrQ3ZFLFlBQW9CLFVBQTRCLEVBQVMsTUFBaUIsRUFBVSxjQUFpQztRQUNwSCxLQUFLLEVBQUUsQ0FBQztRQURXLGVBQVUsR0FBVixVQUFVLENB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YXJkUmVmLCBDaGFuZ2VEZXRlY3RvclJlZiwgVmlld0VuY2Fwc3VsYXRpb24sIEluamVjdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBOR19WQUxVRV9BQ0NFU1NPUiwgQ29udHJvbFZhbHVlQWNjZXNzb3IsIEZvcm1Db250cm9sLCBWYWxpZGF0b3JzIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xyXG5cclxuaW1wb3J0IHsgQWJzdHJhY3RDb250cm9sVmFsdWVBY2Nlc3NvciB9IGZyb20gJy4uL2Fic3RyYWN0LWNvbnRyb2wtdmFsdWUtYWNjZXNvcic7XHJcbmltcG9ydCB7IE9ic2VydmFibGUgfSBmcm9tICdyeGpzJztcclxuXHJcbmltcG9ydCB7IFNlbGVjdGlvbk1vZGVsIH0gZnJvbSAnQGFuZ3VsYXIvY2RrL2NvbGxlY3Rpb25zJztcclxuaW1wb3J0IHsgVHJhbnNsYXRlU2VydmljZSB9IGZyb20gJ0BuZ3gtdHJhbnNsYXRlL2NvcmUnO1xyXG5pbXBvcnQgeyBNYXREaWFsb2csIE1BVF9ESUFMT0dfREFUQSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsJztcclxuXHJcbmltcG9ydCB7b2YgYXMgb2JzZXJ2YWJsZU9mfSBmcm9tICdyeGpzJztcclxuXHJcbmltcG9ydCB7Q2RrRHJhZ0Ryb3AsIG1vdmVJdGVtSW5BcnJheX0gZnJvbSAnQGFuZ3VsYXIvY2RrL2RyYWctZHJvcCc7XHJcblxyXG5pbXBvcnQgKiBhcyBsb2Rhc2hfIGZyb20gJ2xvZGFzaCc7XHJcbmltcG9ydCB7IEVycm9yRGlhbG9nQ29tcG9uZW50IH0gZnJvbSAnLi4vLi4vZGlhbG9ncy9lcnJvci1kaWFsb2cvZXJyb3ItZGlhbG9nLmNvbXBvbmVudCc7XHJcbmltcG9ydCB7IENvbmZpcm1EaWFsb2dDb21wb25lbnQgfSBmcm9tICcuLi8uLi9kaWFsb2dzL2NvbmZpcm0tZGlhbG9nL2NvbmZpcm0tZGlhbG9nLmNvbXBvbmVudCc7XHJcblxyXG5jb25zdCBsb2Rhc2ggPSBsb2Rhc2hfO1xyXG5cclxuZXhwb3J0IGNvbnN0IElOUFVUX0lOUFVUX0NPTlRST0xfVkFMVUVfQUNDRVNTT1I6IGFueSA9IHtcclxuXHRwcm92aWRlOiBOR19WQUxVRV9BQ0NFU1NPUixcclxuXHR1c2VFeGlzdGluZzogZm9yd2FyZFJlZigoKSA9PiBFZGl0YWJsZVRhYmxlQ29tcG9uZW50KSxcclxuXHRtdWx0aTogdHJ1ZSxcclxufTtcclxuXHJcbkBDb21wb25lbnQoe1xyXG5cdHByb3ZpZGVyczogWyBJTlBVVF9JTlBVVF9DT05UUk9MX1ZBTFVFX0FDQ0VTU09SIF0sXHJcblx0c2VsZWN0b3I6ICdlZGl0YWJsZS10YWJsZScsXHJcblx0c3R5bGVzOiBbYHRke3BhZGRpbmc6MTBweH0udGQtZHluYW1pYy1pbnB1dC13cmFwcGVyey1tcy1mbGV4LWRpcmVjdGlvbjpyb3c7ZmxleC1kaXJlY3Rpb246cm93O2Rpc3BsYXk6LW1zLWZsZXhib3g7ZGlzcGxheTpmbGV4O2JveC1zaXppbmc6Ym9yZGVyLWJveH0udGQtZHluYW1pYy1pbnB1dC13cmFwcGVyIC50ZC1keW5hbWljLWlucHV0LWZpZWxkey1tcy1mbGV4OjE7ZmxleDoxO2JveC1zaXppbmc6Ym9yZGVyLWJveH0udGQtZHluYW1pYy1pbnB1dC13cmFwcGVyIC5uZ3gtZWRpdG9ye21hcmdpbi10b3A6MTBweH0ubGFiZWx7cGFkZGluZzoxMHB4IDA7ZGlzcGxheTppbmxpbmUtYmxvY2s7d2lkdGg6NTAlfS5jb250YWluZXJ7b3ZlcmZsb3c6YXV0bztib3JkZXI6MXB4IHNvbGlkICNmM2YzZjM7Ym9yZGVyLXJhZGl1czo1cHggNXB4IDAgMH0uc2VsZWN0ZWQtaXRlbXN7cGFkZGluZzo1cHg7ZGlzcGxheTpibG9jaztiYWNrZ3JvdW5kOiNmM2YzZjM7Ym9yZGVyLXJhZGl1czowIDAgNXB4IDVweDttaW4taGVpZ2h0OjMwcHh9LnNlbGVjdGVkLWl0ZW1zIHNwYW57YmFja2dyb3VuZDojNjg5ZjM4O21hcmdpbjoycHg7cGFkZGluZzo1cHg7Ym9yZGVyLXJhZGl1czo1cHg7Y29sb3I6I2ZmZjtkaXNwbGF5OmlubGluZS1ibG9ja30uYnV0dG9uc3tkaXNwbGF5OmlubGluZS1ibG9jazt3aWR0aDo1MCU7dGV4dC1hbGlnbjpyaWdodH0uYnV0dG9ucyBidXR0b257cGFkZGluZzowO3dpZHRoOjMwcHghaW1wb3J0YW50O21pbi13aWR0aDozMHB4O2JvcmRlci1yYWRpdXM6NTBweDtoZWlnaHQ6MzBweH0uYnV0dG9ucyBidXR0b24gbWF0LWljb257cG9zaXRpb246cmVsYXRpdmUhaW1wb3J0YW50O3RvcDotNHB4IWltcG9ydGFudH0ubWFpbi1jb250YWluZXJ7Ym9yZGVyOjFweCBzb2xpZCAjZjNmM2YzO2JvcmRlci1yYWRpdXM6NXB4O3BhZGRpbmc6NXB4IDEwcHggMjBweDtvdmVyZmxvdzphdXRvfWhye2Rpc3BsYXk6YmxvY2s7aGVpZ2h0OjFweDtib3JkZXI6MDtib3JkZXItdG9wOjFweCBzb2xpZCAjY2NjO21hcmdpbjoxZW0gMDtwYWRkaW5nOjB9LmRyYWdnZXJ7dGV4dC1hbGlnbjpjZW50ZXI7YmFja2dyb3VuZDojZjNmM2YzO2hlaWdodDoyNHB4O2JvcmRlci1yYWRpdXM6NXB4O3dpZHRoOjM2cHg7bWFyZ2luOmF1dG8gOHB4IGF1dG8gYXV0bztib3JkZXI6MXB4IHNvbGlkICNkZGQ7Y3Vyc29yOm1vdmV9LmVycm9yLXZhbGlkYXRle2NvbG9yOiNlNTM5MzQ7Zm9udC1zaXplOjc1JTt0b3A6MzNweDtwb3NpdGlvbjphYnNvbHV0ZTtsZWZ0OjB9LmVycm9yLXZhbGlkYXRlLmJvb2xlYW57cG9zaXRpb246cmVsYXRpdmUhaW1wb3J0YW50O3RvcDo5cHg7d2lkdGg6MTAwJTtkaXNwbGF5OmlubGluZS1ibG9ja30uZXJyb3ItdmFsaWRhdGUuZGF0ZXRpbWV7cG9zaXRpb246cmVsYXRpdmUhaW1wb3J0YW50O3RvcDo5cHg7cGFkZGluZy1ib3R0b206MTBweDt3aWR0aDoxMDAlO2Rpc3BsYXk6aW5saW5lLWJsb2NrfS5lZGl0YWJsZS1maWVsZHttaW4td2lkdGg6MTAwJX10YWJsZXt3aWR0aDoxMDAlO2JvcmRlci1jb2xsYXBzZTpjb2xsYXBzZTtib3JkZXItc3BhY2luZzowfXRyIHRoe3RleHQtYWxpZ246bGVmdH10cjpudGgtY2hpbGQoZXZlbil7YmFja2dyb3VuZDojZmFmYWZhfXRyOm50aC1jaGlsZChldmVuKSBpbnB1dHtiYWNrZ3JvdW5kOiNmYWZhZmEhaW1wb3J0YW50fS9kZWVwLyAudGltZS1maWVsZCBsYWJlbHtkaXNwbGF5OmJsb2NrO2NvbG9yOiM5MjkyOTI7bWFyZ2luLXRvcDotMTJweH0vZGVlcC8gLnRpbWUtZmllbGQgaW5wdXR7Ym9yZGVyOjA7Ym9yZGVyLWJvdHRvbToxcHggc29saWQgIzllOWY5ZTtmb250LXNpemU6MTRweH0vZGVlcC8gLm1hdC1kYXRlcGlja2VyLXRvZ2dsZSBidXR0b257Ym94LXNoYWRvdzowIDNweCAxcHggLTJweCByZ2JhKDAsMCwwLC4yKSwwIDJweCAycHggMCByZ2JhKDAsMCwwLC4xNCksMCAxcHggNXB4IDAgcmdiYSgwLDAsMCwuMTIpO2JvcmRlci1yYWRpdXM6M3B4IWltcG9ydGFudH0vZGVlcC8gLnRpbWUtZmllbGR7bWFyZ2luLWJvdHRvbTo0cHh9LmRldGFpbHN7Zm9udC1zaXplOjExcHg7cGFkZGluZzo1cHggMH1gXSxcclxuXHR0ZW1wbGF0ZTogYDxkaXYgY2xhc3M9XCJsYWJlbFwiPnt7bGFiZWx9fTwvZGl2PlxyXG48ZGl2IGNsYXNzPVwibWFpbi1jb250YWluZXJcIj5cclxuICAgIDx0YWJsZSB0ZC1kYXRhLXRhYmxlPlxyXG4gICAgICAgIDx0aGVhZD5cclxuICAgICAgICAgICAgPHRyIHRkLWRhdGEtdGFibGUtY29sdW1uLXJvdz5cclxuICAgICAgICAgICAgICAgIDx0aCB0ZC1kYXRhLXRhYmxlLWNvbHVtbj5cclxuICAgICAgICAgICAgICAgICAgICB7e2FkZFRpdGxlfX1cclxuICAgICAgICAgICAgICAgIDwvdGg+XHJcbiAgICAgICAgICAgIDwvdHI+XHJcbiAgICAgICAgPC90aGVhZD5cclxuICAgICAgICA8dGJvZHk+XHJcbiAgICAgICAgICAgIDx0ciB0ZC1kYXRhLXRhYmxlLXJvdz5cclxuICAgICAgICAgICAgICAgIDx0ZCB0ZC1kYXRhLXRhYmxlLWNlbGwgKm5nRm9yPVwibGV0IGl0ZW0gb2Ygc2NoZW1hOyBsZXQgaT1pbmRleFwiPlxyXG4gICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJpdGVtLnR5cGUgPT0gJ3N0cmluZydcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIGNsYXNzPVwiZWRpdGFibGUtZmllbGRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCBtYXRJbnB1dCBhdXRvY29tcGxldGU9XCJvZmZcIiBwbGFjZWhvbGRlcj1cInt7aXRlbS5sYWJlbH19XCIgWyhuZ01vZGVsKV09XCJuZXdFbGVtZW50W2l0ZW0ubmFtZV1cIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIml0ZW0udHlwZSA9PSAnZGF0ZSdcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIGNsYXNzPVwiZWRpdGFibGUtZmllbGRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCBtYXRJbnB1dCBhdXRvY29tcGxldGU9XCJvZmZcIiBbbWF0RGF0ZXBpY2tlcl09XCJpXCIgcGxhY2Vob2xkZXI9XCJ7e2l0ZW0ubGFiZWx9fVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2F0dHIuaWRdPVwiJ2R0UGlja2VyJyArIGlcIiBbKG5nTW9kZWwpXT1cIm5ld0VsZW1lbnRbaXRlbS5uYW1lXVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1kYXRlcGlja2VyLXRvZ2dsZSBtYXRTdWZmaXggW2Zvcl09XCJpXCI+PC9tYXQtZGF0ZXBpY2tlci10b2dnbGU+PG1hdC1kYXRlcGlja2VyICNpPjwvbWF0LWRhdGVwaWNrZXI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcbiAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJpdGVtLnR5cGUgPT0gJ3RpbWUnXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0aW1lLWZpZWxkXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJ0aW1lTGFiZWxcIj5Ib3JhPC9sYWJlbD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCBhcmlhLWxhYmVsPVwiZGVmYXVsdCB0aW1lXCIgYXV0b2NvbXBsZXRlPVwib2ZmXCIgW25neFRpbWVwaWNrZXJdPVwiZGVmYXVsdFRpbWVcIiBbKG5nTW9kZWwpXT1cIm5ld0VsZW1lbnRbaXRlbS5uYW1lXVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5neC1tYXRlcmlhbC10aW1lcGlja2VyICNkZWZhdWx0VGltZT48L25neC1tYXRlcmlhbC10aW1lcGlja2VyPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuXHJcblx0XHRcdFx0XHQ8bmctY29udGFpbmVyICpuZ0lmPVwiaXRlbS50eXBlID09ICdkYXRlVGltZSdcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGRhdGUtdGltZS1waWNrZXIgW21pbl09XCJpdGVtLm1pblwiIFttYXhdPVwiaXRlbS5tYXhcIiBbKG15TW9kZWwpXT1cIm5ld0VsZW1lbnRbaXRlbS5uYW1lXVwiPjwvZGF0ZS10aW1lLXBpY2tlcj5cclxuICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIml0ZW0udHlwZSA9PSAnbnVtYmVyJ1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgY2xhc3M9XCJlZGl0YWJsZS1maWVsZFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IG1hdElucHV0IHR5cGU9XCJudW1iZXJcIiBhdXRvY29tcGxldGU9XCJvZmZcIiBwbGFjZWhvbGRlcj1cInt7aXRlbS5sYWJlbH19XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cIm5ld0VsZW1lbnRbaXRlbS5uYW1lXVwiIG1pbj1cInt7aXRlbS5taW59fVwiIG1heD1cInt7aXRlbS5tYXh9fVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxyXG4gICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG5cclxuICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiaXRlbS50eXBlID09ICdib29sZWFuJ1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWNoZWNrYm94IFsobmdNb2RlbCldPVwibmV3RWxlbWVudFtpdGVtLm5hbWVdXCI+e3tpdGVtLmxhYmVsfX08L21hdC1jaGVja2JveD5cclxuICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIml0ZW0udHlwZSA9PSAnc2VsZWN0J1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgY2xhc3M9XCJlZGl0YWJsZS1maWVsZFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1zZWxlY3QgcGxhY2Vob2xkZXI9XCJ7e2l0ZW0ubGFiZWx9fVwiIFsodmFsdWUpXT1cIm5ld0VsZW1lbnRbaXRlbS5uYW1lXVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtb3B0aW9uPi4uLjwvbWF0LW9wdGlvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LW9wdGlvbiB2YWx1ZT1cInt7aXRlbS52YWx1ZX19XCIgKm5nRm9yPVwibGV0IGl0ZW0gb2YgaXRlbS5pdGVtcztcIj57e2l0ZW0ubGFiZWx9fTwvbWF0LW9wdGlvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LXNlbGVjdD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuXHJcbiAgICAgICAgICAgICAgICA8L3RkPlxyXG4gICAgICAgICAgICAgICAgPHRkPlxyXG4gICAgICAgICAgICAgICAgICAgIDxidXR0b24gbWF0LWJ1dHRvbiBjb2xvcj1cInByaW1hcnlcIiAoY2xpY2spPVwiYWRkSXRlbSgpXCI+QcOxYWRpcjwvYnV0dG9uPlxyXG4gICAgICAgICAgICAgICAgPC90ZD5cclxuICAgICAgICAgICAgPC90cj5cclxuICAgICAgICA8L3Rib2R5PlxyXG4gICAgPC90YWJsZT5cclxuXHJcbiAgICA8aHIgLz5cclxuXHJcbiAgICA8dGFibGUgdGQtZGF0YS10YWJsZT5cclxuICAgICAgICA8dGhlYWQ+XHJcbiAgICAgICAgICAgIDx0ciB0ZC1kYXRhLXRhYmxlLWNvbHVtbi1yb3c+XHJcbiAgICAgICAgICAgICAgICA8dGggdGQtZGF0YS10YWJsZS1jb2x1bW4gKm5nSWY9XCJkcmFnZ2FibGVcIj48L3RoPlxyXG4gICAgICAgICAgICAgICAgPHRoIHRkLWRhdGEtdGFibGUtY29sdW1uXHJcbiAgICAgICAgICAgICAgICAgICAgKm5nRm9yPVwibGV0IGNvbHVtbiBvZiBzY2hlbWFcIj5cclxuICAgICAgICAgICAgICAgICAgICB7e2NvbHVtbi5sYWJlbH19XHJcbiAgICAgICAgICAgICAgICA8L3RoPlxyXG4gICAgICAgICAgICA8L3RyPlxyXG4gICAgICAgIDwvdGhlYWQ+XHJcbiAgICAgICAgPHRib2R5IGNka0Ryb3BMaXN0IGNsYXNzPVwiZXhhbXBsZS1saXN0XCIgKGNka0Ryb3BMaXN0RHJvcHBlZCk9XCJkcm9wKCRldmVudClcIj5cclxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImRyYWdnYWJsZVwiPlxyXG4gICAgICAgICAgICAgICAgPCEtLURSQUdHQUJMRTogSVNTVUUgIzEzODkzLS0+XHJcbiAgICAgICAgICAgICAgICA8dHIgdGQtZGF0YS10YWJsZS1yb3cgKm5nRm9yPVwibGV0IHJvdyBvZiB2YWx1ZTsgbGV0IHo9aW5kZXhcIiBjZGtEcmFnPlxyXG4gICAgICAgICAgICAgICAgICAgIDx0ZD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRyYWdnZXJcIiBjZGtEcmFnSGFuZGxlPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uPmRyYWdfaGFuZGxlPC9tYXQtaWNvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgPC90ZD5cclxuICAgICAgICAgICAgICAgICAgICA8dGQgdGQtZGF0YS10YWJsZS1jZWxsICpuZ0Zvcj1cImxldCBhdHRyIG9mIHNjaGVtYTsgbGV0IGk9aW5kZXhcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImF0dHIudHlwZSA9PSAnc3RyaW5nJ1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIGNsYXNzPVwiZWRpdGFibGUtZmllbGRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgbWF0SW5wdXQgcGxhY2Vob2xkZXI9XCJ7e2F0dHIubGFiZWx9fVwiIFsobmdNb2RlbCldPVwicm93W2F0dHIubmFtZV1cIiBhdXRvY29tcGxldGU9XCJvZmZcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJjaGFuZ2VzT3V0KCRldmVudClcIiBbcmVxdWlyZWRdPVwiYXR0ci5yZXF1aXJlZFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZXJyb3ItdmFsaWRhdGVcIiAqbmdJZj1cIiFpc1ZhbGlkKHJvdywgYXR0ci5uYW1lKVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7e2ZpZWxkRXJyb3JNZXNzYWdlKHJvdywgYXR0ci5uYW1lKSB8IHRyYW5zbGF0ZX19XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiYXR0ci50eXBlID09ICdkYXRlJ1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIGNsYXNzPVwiZWRpdGFibGUtZmllbGRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgbWF0SW5wdXQgYXV0b2NvbXBsZXRlPVwib2ZmXCIgW21hdERhdGVwaWNrZXJdPVwialwiIHBsYWNlaG9sZGVyPVwie3thdHRyLmxhYmVsfX1cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbYXR0ci5pZF09XCInZHRQaWNrZXInICsgalwiIFsobmdNb2RlbCldPVwicm93W2F0dHIubmFtZV1cIiAobmdNb2RlbENoYW5nZSk9XCJjaGFuZ2VzT3V0KCRldmVudClcIiBbcmVxdWlyZWRdPVwiYXR0ci5yZXF1aXJlZFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZGF0ZXBpY2tlci10b2dnbGUgbWF0U3VmZml4IFtmb3JdPVwialwiPjwvbWF0LWRhdGVwaWNrZXItdG9nZ2xlPjxtYXQtZGF0ZXBpY2tlciAjaj48L21hdC1kYXRlcGlja2VyPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZXJyb3ItdmFsaWRhdGVcIiAqbmdJZj1cIiFpc1ZhbGlkKHJvdywgYXR0ci5uYW1lKVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7e2ZpZWxkRXJyb3JNZXNzYWdlKHJvdywgYXR0ci5uYW1lKSB8IHRyYW5zbGF0ZX19XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcblxyXG5cdFx0XHRcdFx0XHQ8bmctY29udGFpbmVyICpuZ0lmPVwiYXR0ci50eXBlID09ICd0aW1lJ1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRpbWUtZmllbGRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJ0aW1lTGFiZWxcIj5Ib3JhPC9sYWJlbD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgYXV0b2NvbXBsZXRlPVwib2ZmXCIgYXJpYS1sYWJlbD1cImRlZmF1bHQgdGltZVwiIFtuZ3hUaW1lcGlja2VyXT1cImRlZmF1bHRUaW1lXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3ZhbHVlXT1cInJvd1thdHRyLm5hbWVdXCIgcmVhZG9ubHkgKG5nTW9kZWxDaGFuZ2UpPVwiY2hhbmdlc091dCgkZXZlbnQpXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5neC1tYXRlcmlhbC10aW1lcGlja2VyICNkZWZhdWx0VGltZT48L25neC1tYXRlcmlhbC10aW1lcGlja2VyPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZXJyb3ItdmFsaWRhdGVcIiAqbmdJZj1cIiFpc1ZhbGlkKHJvdywgYXR0ci5uYW1lKVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7e2ZpZWxkRXJyb3JNZXNzYWdlKHJvdywgYXR0ci5uYW1lKSB8IHRyYW5zbGF0ZX19XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcblx0ICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuXHJcblx0XHRcdFx0XHRcdDxuZy1jb250YWluZXIgKm5nSWY9XCJhdHRyLnR5cGUgPT0gJ2RhdGVUaW1lJ1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRhdGUtdGltZS1waWNrZXIgW21pbl09XCJhdHRyLm1pblwiIFttYXhdPVwiYXR0ci5tYXhcIiBbKG15TW9kZWwpXT1cIm5ld0VsZW1lbnRbYXR0ci5uYW1lXVwiIChteU1vZGVsQ2hhbmdlKT1cImNoYW5nZXNPdXQoJGV2ZW50KVwiPjwvZGF0ZS10aW1lLXBpY2tlcj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZXJyb3ItdmFsaWRhdGUgZGF0ZXRpbWVcIiAqbmdJZj1cIiFpc1ZhbGlkKHJvdywgYXR0ci5uYW1lKVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7ZmllbGRFcnJvck1lc3NhZ2Uocm93LCBhdHRyLm5hbWUpIHwgdHJhbnNsYXRlfX1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cclxuXHQgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImF0dHIudHlwZSA9PSAnbnVtYmVyJ1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIGNsYXNzPVwiZWRpdGFibGUtZmllbGRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgbWF0SW5wdXQgdHlwZT1cIm51bWJlclwiIGF1dG9jb21wbGV0ZT1cIm9mZlwiIHBsYWNlaG9sZGVyPVwie3thdHRyLmxhYmVsfX1cIiBbKG5nTW9kZWwpXT1cInJvd1thdHRyLm5hbWVdXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwiY2hhbmdlc091dCgkZXZlbnQpXCIgbWluPVwie3thdHRyLm1pbn19XCIgbWF4PVwie3thdHRyLm1heH19XCIgW3JlcXVpcmVkXT1cImF0dHIucmVxdWlyZWRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImVycm9yLXZhbGlkYXRlXCIgKm5nSWY9XCIhaXNWYWxpZChyb3csIGF0dHIubmFtZSlcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3tmaWVsZEVycm9yTWVzc2FnZShyb3csIGF0dHIubmFtZSkgfCB0cmFuc2xhdGV9fVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+