svogv
Version:
A decorator based approach for model driven forms, including an advanced DataGrid and a TreeView component.
152 lines • 21.8 kB
JavaScript
import { Component, Input, Output } from '@angular/core';
import { FormGroup } from '@angular/forms';
/**
* The Editor Widget. Creates a field with all required validators using decorators and forms service.
*/
export class EditorComponent {
constructor() {
/**
* Editor type. Default is 'text';
*/
this.type = 'text';
/**
* A character after the fields label. Default is ': ' (colon plus space);
*/
this.labelDivider = ': ';
/**
* If set to true the label and the field appears in one row.
* Otherwise the label is above the field. Default is `true`.
*/
this.inline = true;
/**
* The start value for a range field. Other field types ignore this value.
*/
this.fromValue = 0;
/**
* The end value for a range field. Other field types ignore this value.
*/
this.toValue = 100;
/**
* An optional placeholder for empty field. The default is empty (no watermark).
*/
this.waterMark = '';
/**
* Renders the field as read only.
*/
this.readonly = false;
this.params = new Array();
}
getParams(key) {
return this.first(this.params.filter((e) => e.key === key), 0);
}
first(array, n) {
if (array == null) {
return void 0;
}
if (n == null) {
return array[0];
}
if (n < 0) {
return [];
}
return array.slice(0, n);
}
ngOnInit() {
this.formGroup.valueChanges.subscribe((data) => this.onValueChanged(data));
// this is set by FormValidatorService
const editorModel = this.formGroup.__editorModel__;
// get type from form
if (editorModel) {
// get elementary types, this might get overwritten later according to decorators found
if (typeof editorModel[this.name] === 'string') {
this.type = 'text';
}
if (typeof editorModel[this.name] === 'boolean') {
this.type = 'boolean';
}
if (typeof editorModel[this.name] === 'number') {
this.type = 'number';
}
if (editorModel[this.name] instanceof Date) {
this.type = 'calendar';
}
// make an instance to read the properties
this.label = editorModel[`__displayName__${this.name}`] || this.label || this.name;
this.tooltip = editorModel[`__displayDesc__${this.name}`] || this.tooltip || this.name;
// render as range id there is a range definition
if (editorModel[`__hasRangeFrom__${this.name}`] && Number(editorModel[`__hasRangeFrom__${this.name}`])) {
this.fromValue = editorModel[`__hasRangeFrom__${this.name}`];
this.type = 'range';
}
if (editorModel[`__hasRangeTo__${this.name}`] && Number(editorModel[`__hasRangeTo__${this.name}`])) {
this.toValue = editorModel[`__hasRangeTo__${this.name}`];
this.type = 'range';
}
// placeholder
if (editorModel[`__hasWatermark__${this.name}`]) {
this.waterMark = editorModel[`__watermark__${this.name}`];
}
// templates
if (editorModel[`__hasTemplateHint__${this.name}`]) {
this.type = editorModel[`__templatehint__${this.name}`].toLowerCase();
if (editorModel[`__templatehintParams__${this.name}`]) {
this.params = editorModel[`__templatehintParams__${this.name}`];
}
}
// render hidden fields as hidden even in forms
if (editorModel[`__isHidden__${this.name}`]) {
this.type = 'hidden';
}
// check readonly
if (editorModel[`__isReadonly__${this.name}`]) {
this.readonly = !!editorModel[`__isReadonly__${this.name}`];
}
}
}
onValueChanged(data) {
// check validation on change
this.errors = new Array();
// tslint:disable-next-line:forin
for (const error in this.formGroup.controls[this.name].errors) {
this.errors.push(error);
}
}
}
EditorComponent.decorators = [
{ type: Component, args: [{
selector: 'ac-editor',
template: "<div class=\"form-group row\"\n [formGroup]=\"formGroup\"\n *ngIf=\"type != 'hidden' && formGroup\"\n [ngClass]=\"{ 'has-danger': !formGroup.controls[name].valid && formGroup.controls[name].touched }\">\n <label class=\"col-form-label col-md-3 col-sm-10\"\n [attr.for]=\"name\"\n [attr.title]=\"tooltip\" >{{ label }}{{ labelDivider }} </label>\n <div [ngClass]=\"{ 'col-md-7 col-sm-10': inline }\">\n <textarea *ngIf=\"type == 'textarea'\"\n class=\"form-control\"\n [id]=\"name\"\n [readOnly]='readonly'\n [formControlName]=\"name\"\n [attr.rows]=\"getParams('rows')\"\n [attr.cols]=\"getParams('cols')\">\n </textarea>\n <select *ngIf=\"type == 'enum' && enumValues\" class=\"form-control\" [id]=\"name\"\n [formControlName]=\"name\" [disabled]='readonly'>\n <option *ngFor=\"let option of enumValues\" [value]=\"option.key\">{{option.val}}</option>\n </select>\n <select *ngIf=\"type == 'list' && listValues\" class=\"form-control\" [id]=\"name\"\n [formControlName]=\"name\" [disabled]='readonly'>\n <option *ngFor=\"let option of listValues\" [value]=\"option.key\">{{option.val}}</option>\n </select>\n <input *ngIf=\"type == 'range'\" type=\"range\"\n class=\"form-control\"\n [placeholder]=\"waterMark\"\n [attr.minvalue]=\"fromValue\"\n [attr.maxvalue]=\"toValue\"\n [attr.min]=\"fromValue\"\n [attr.max]=\"toValue\"\n [id]=\"name\"\n [formControlName]=\"name\"\n [title]=\"tooltip\" />\n <input *ngIf=\"type == 'calendar'\" type=\"date\"\n class=\"form-control\"\n [placeholder]=\"waterMark\"\n [readOnly]='readonly'\n [id]=\"name\"\n [formControlName]=\"name\"\n [title]=\"tooltip\" />\n <input *ngIf=\"type == 'number'\" type=\"number\"\n class=\"form-control\"\n [placeholder]=\"waterMark\"\n [readOnly]='readonly'\n [id]=\"name\"\n [formControlName]=\"name\"\n [title]=\"tooltip\" />\n <input *ngIf=\"type == 'boolean'\" type=\"checkbox\"\n class=\"form-control\"\n [readOnly]='readonly'\n [id]=\"name\"\n [formControlName]=\"name\"\n [title]=\"tooltip\" />\n <label *ngIf=\"type == 'boolean'\" [attr.for]=\"name\"></label>\n <input *ngIf=\"type == 'text' || type == ''\" [placeholder]=\"waterMark\"\n [readOnly]='readonly'\n type=\"text\" class=\"form-control\" [id]=\"name\" [formControlName]=\"name\" />\n <ng-container *ngIf=\"type == 'template'\">\n <ng-content></ng-content>\n </ng-container>\n <span class=\"fa fa-warning text-danger form-control-feedback\"\n [hidden]=\"formGroup.controls[name].valid || formGroup.controls[name].pristine\"></span>\n <small class=\"text-danger\"\n [hidden]=\"formGroup.controls[name].valid || formGroup.controls[name].pristine\">\n <span *ngFor=\"let error of errors\">{{ formGroup.controls[name]['messages'][error] }}</span>\n </small>\n </div>\n</div>\n<div>\n <input *ngIf=\"type == 'hidden'\" [id]=\"name\" [formControlName]=\"name\" type=\"hidden\" />\n</div>\n",
styles: ['input[type="checkbox"] { display: none; }',
'input[type="checkbox"] + label:before { font-family: FontAwesome; }',
'input[type="checkbox"] + label:before { content: "\\f096"; }',
'input[type="checkbox"]:checked + label:before { content: "\\f046"; }',
`
input[type='checkbox'] + label {
display: inline-block;
width: 15px;
height: 20px;
margin: -1px 4px 0 0;
vertical-align: middle;
cursor: pointer;
}
`]
},] }
];
EditorComponent.ctorParameters = () => [];
EditorComponent.propDecorators = {
name: [{ type: Input }],
type: [{ type: Input }],
labelDivider: [{ type: Input }],
label: [{ type: Input }],
tooltip: [{ type: Input }],
formGroup: [{ type: Input }],
inline: [{ type: Input }],
enumValues: [{ type: Input }],
listValues: [{ type: Input }],
fromValue: [{ type: Input }],
toValue: [{ type: Input }],
waterMark: [{ type: Input }],
readonly: [{ type: Input }],
value: [{ type: Output }, { type: Input }]
};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWRpdG9yLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIuLi8uLi8uLi9wcm9qZWN0cy9zdm9ndi9zcmMvIiwic291cmNlcyI6WyJsaWIvd2lkZ2V0cy9lZGl0b3JzL2VkaXRvci9lZGl0b3IuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBVSxNQUFNLGVBQWUsQ0FBQztBQUNqRSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFM0M7O0dBRUc7QUFxQkgsTUFBTSxPQUFPLGVBQWU7SUFtRTFCO1FBOURBOztXQUVHO1FBQ2EsU0FBSSxHQUFHLE1BQU0sQ0FBQztRQUM5Qjs7V0FFRztRQUNhLGlCQUFZLEdBQUcsSUFBSSxDQUFDO1FBYXBDOzs7V0FHRztRQUNhLFdBQU0sR0FBRyxJQUFJLENBQUM7UUFVOUI7O1dBRUc7UUFDYSxjQUFTLEdBQUcsQ0FBQyxDQUFDO1FBQzlCOztXQUVHO1FBQ2EsWUFBTyxHQUFHLEdBQUcsQ0FBQztRQUM5Qjs7V0FFRztRQUNhLGNBQVMsR0FBRyxFQUFFLENBQUM7UUFDL0I7O1dBRUc7UUFDYSxhQUFRLEdBQUcsS0FBSyxDQUFDO1FBYy9CLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxLQUFLLEVBQStCLENBQUM7SUFDekQsQ0FBQztJQUVNLFNBQVMsQ0FBQyxHQUFXO1FBQzFCLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUNqRSxDQUFDO0lBRU0sS0FBSyxDQUFDLEtBQW9DLEVBQUUsQ0FBUztRQUMxRCxJQUFJLEtBQUssSUFBSSxJQUFJLEVBQUU7WUFDakIsT0FBTyxLQUFLLENBQUMsQ0FBQztTQUNmO1FBQ0QsSUFB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QUFLO29CQUlMLEtBQUs7c0JBSUwsS0FBSzt3QkFJTCxLQUFLO3FCQUtMLEtBQUs7eUJBSUwsS0FBSzt5QkFLTCxLQUFLO3dCQUlMLEtBQUs7c0JBSUwsS0FBSzt3QkFJTCxLQUFLO3VCQUlMLEtBQUs7b0JBSUwsTUFBTSxZQUNOLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIElucHV0LCBPdXRwdXQsIE9uSW5pdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRm9ybUdyb3VwIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuXG4vKipcbiAqIFRoZSBFZGl0b3IgV2lkZ2V0LiBDcmVhdGVzIGEgZmllbGQgd2l0aCBhbGwgcmVxdWlyZWQgdmFsaWRhdG9ycyB1c2luZyBkZWNvcmF0b3JzIGFuZCBmb3JtcyBzZXJ2aWNlLlxuICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdhYy1lZGl0b3InLFxuICBzdHlsZXM6IFtcbiAgICAnaW5wdXRbdHlwZT1cImNoZWNrYm94XCJdIHsgZGlzcGxheTogbm9uZTsgfScsXG4gICAgJ2lucHV0W3R5cGU9XCJjaGVja2JveFwiXSArIGxhYmVsOmJlZm9yZSB7IGZvbnQtZmFtaWx5OiBGb250QXdlc29tZTsgfScsXG4gICAgJ2lucHV0W3R5cGU9XCJjaGVja2JveFwiXSArIGxhYmVsOmJlZm9yZSB7IGNvbnRlbnQ6IFwiXFxcXGYwOTZcIjsgfScsXG4gICAgJ2lucHV0W3R5cGU9XCJjaGVja2JveFwiXTpjaGVja2VkICsgbGFiZWw6YmVmb3JlIHsgY29udGVudDogXCJcXFxcZjA0NlwiOyB9JyxcbiAgICBgXG4gICAgICBpbnB1dFt0eXBlPSdjaGVja2JveCddICsgbGFiZWwge1xuICAgICAgICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XG4gICAgICAgIHdpZHRoOiAxNXB4O1xuICAgICAgICBoZWlnaHQ6IDIwcHg7XG4gICAgICAgIG1hcmdpbjogLTFweCA0cHggMCAwO1xuICAgICAgICB2ZXJ0aWNhbC1hbGlnbjogbWlkZGxlO1xuICAgICAgICBjdXJzb3I6IHBvaW50ZXI7XG4gICAgICB9XG4gICAgYFxuICBdLFxuICB0ZW1wbGF0ZVVybDogJy4vZWRpdG9yLmNvbXBvbmVudC5odG1sJ1xufSkgLy9cbmV4cG9ydCBjbGFzcyBFZGl0b3JDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuICAvKipcbiAgICogRmllbGQgbmFtZVxuICAgKi9cbiAgQElucHV0KCkgcHVibGljIG5hbWU6IHN0cmluZztcbiAgLyoqXG4gICAqIEVkaXRvciB0eXBlLiBEZWZhdWx0IGlzICd0ZXh0JztcbiAgICovXG4gIEBJbnB1dCgpIHB1YmxpYyB0eXBlID0gJ3RleHQnO1xuICAvKipcbiAgICogQSBjaGFyYWN0ZXIgYWZ0ZXIgdGhlIGZpZWxkcyBsYWJlbC4gRGVmYXVsdCBpcyAnOiAnIChjb2xvbiBwbHVzIHNwYWNlKTtcbiAgICovXG4gIEBJbnB1dCgpIHB1YmxpYyBsYWJlbERpdmlkZXIgPSAnOiAnO1xuICAvKipcbiAgICogVGhlIGxhYmVsJ3MgbmFtZS5cbiAgICovXG4gIEBJbnB1dCgpIHB1YmxpYyBsYWJlbDogc3RyaW5nO1xuICAvKipcbiAgICogQSB0b29sdGlwXG4gICAqL1xuICBASW5wdXQoKSBwdWJsaWMgdG9vbHRpcDogc3RyaW5nO1xuICAvKipcbiAgICogVGhlIGZvcm0ncyBncm91cCBvYmplY3QuXG4gICAqL1xuICBASW5wdXQoKSBwdWJsaWMgZm9ybUdyb3VwOiBGb3JtR3JvdXA7XG4gIC8qKlxuICAgKiBJZiBzZXQgdG8gdHJ1ZSB0aGUgbGFiZWwgYW5kIHRoZSBmaWVsZCBhcHBlYXJzIGluIG9uZSByb3cuXG4gICAqIE90aGVyd2lzZSB0aGUgbGFiZWwgaXMgYWJvdmUgdGhlIGZpZWxkLiBEZWZhdWx0IGlzIGB0cnVlYC5cbiAgICovXG4gIEBJbnB1dCgpIHB1YmxpYyBpbmxpbmUgPSB0cnVlO1xuICAvKipcbiAgICogVGhlIHZhbHVlcyBvZiB0aGUgc2VsZWN0IGZpZWxkIHByb3ZpZGVkIGJ5IGFuIGVudW0uIEZvciBvdGhlciBmaWVsZHR5cGVzIGl0J3MgYmVpbmcgaWdub3JlZC5cbiAgICovXG4gIEBJbnB1dCgpIHB1YmxpYyBlbnVtVmFsdWVzOiBhbnk7XG4gIC8qKlxuICAgKiBUaGUgdmFsdWVzIG9mIHRoZSBzZWxlY3QgZmllbGQgcHJvdmlkZWQgYnkgYSBsaXN0LiBGb3Igb3RoZXIgZmllbGR0eXBlcyBpdCdzIGJlaW5nIGlnbm9yZWQuXG4gICAqIFRoZSB2YWx1ZSBzaGFsbCBiZSBhbiBBcnJheSB0aGF0IGEgYCpuZ0ZvcmAgZGlyZWN0aXZlIGNhbiBleGVjdXRlLlxuICAgKi9cbiAgQElucHV0KCkgcHVibGljIGxpc3RWYWx1ZXM6IGFueVtdO1xuICAvKipcbiAgICogVGhlIHN0YXJ0IHZhbHVlIGZvciBhIHJhbmdlIGZpZWxkLiBPdGhlciBmaWVsZCB0eXBlcyBpZ25vcmUgdGhpcyB2YWx1ZS5cbiAgICovXG4gIEBJbnB1dCgpIHB1YmxpYyBmcm9tVmFsdWUgPSAwO1xuICAvKipcbiAgICogVGhlIGVuZCB2YWx1ZSBmb3IgYSByYW5nZSBmaWVsZC4gT3RoZXIgZmllbGQgdHlwZXMgaWdub3JlIHRoaXMgdmFsdWUuXG4gICAqL1xuICBASW5wdXQoKSBwdWJsaWMgdG9WYWx1ZSA9IDEwMDtcbiAgLyoqXG4gICAqIEFuIG9wdGlvbmFsIHBsYWNlaG9sZGVyIGZvciBlbXB0eSBmaWVsZC4gVGhlIGRlZmF1bHQgaXMgZW1wdHkgKG5vIHdhdGVybWFyaykuXG4gICAqL1xuICBASW5wdXQoKSBwdWJsaWMgd2F0ZXJNYXJrID0gJyc7XG4gIC8qKlxuICAgKiBSZW5kZXJzIHRoZSBmaWVsZCBhcyByZWFkIG9ubHkuXG4gICAqL1xuICBASW5wdXQoKSBwdWJsaWMgcmVhZG9ubHkgPSBmYWxzZTtcbiAgLyoqXG4gICAqIFRoZSB2YWx1ZSBzZXQgdG8gYW5kIHJlYWQgZnJvbSB0aGUgZmllbGQuXG4gICAqL1xuICBAT3V0cHV0KClcbiAgQElucHV0KClcbiAgcHVibGljIHZhbHVlOiBhbnk7XG5cbiAgLy8gYWRkaXRpb25hbCB2YWx1ZXMgcHJvdmlkZWQgYnkgVGVtcGxhdGVIaW50IGRlY29yYXRvclxuICBwdWJsaWMgcGFyYW1zOiB7IGtleTogc3RyaW5nOyB2YWx1ZTogYW55IH1bXTtcblxuICBwdWJsaWMgZXJyb3JzOiBzdHJpbmdbXTtcblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICB0aGlzLnBhcmFtcyA9IG5ldyBBcnJheTx7IGtleTogc3RyaW5nOyB2YWx1ZTogYW55IH0+KCk7XG4gIH1cblxuICBwdWJsaWMgZ2V0UGFyYW1zKGtleTogc3RyaW5nKTogYW55IHtcbiAgICByZXR1cm4gdGhpcy5maXJzdCh0aGlzLnBhcmFtcy5maWx0ZXIoKGUpID0+IGUua2V5ID09PSBrZXkpLCAwKTtcbiAgfVxuXG4gIHB1YmxpYyBmaXJzdChhcnJheTogeyBrZXk6IHN0cmluZzsgdmFsdWU6IGFueSB9W10sIG46IG51bWJlcik6IGFueSB7XG4gICAgaWYgKGFycmF5ID09IG51bGwpIHtcbiAgICAgIHJldHVybiB2b2lkIDA7XG4gICAgfVxuICAgIGlmIChuID09IG51bGwpIHtcbiAgICAgIHJldHVybiBhcnJheVswXTtcbiAgICB9XG4gICAgaWYgKG4gPCAwKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuICAgIHJldHVybiBhcnJheS5zbGljZSgwLCBuKTtcbiAgfVxuXG4gIHB1YmxpYyBuZ09uSW5pdCgpIHtcbiAgICB0aGlzLmZvcm1Hcm91cC52YWx1ZUNoYW5nZXMuc3Vic2NyaWJlKChkYXRhKSA9PiB0aGlzLm9uVmFsdWVDaGFuZ2VkKGRhdGEpKTtcbiAgICAvLyB0aGlzIGlzIHNldCBieSBGb3JtVmFsaWRhdG9yU2VydmljZVxuICAgIGNvbnN0IGVkaXRvck1vZGVsID0gKHRoaXMuZm9ybUdyb3VwIGFzIGFueSkuX19lZGl0b3JNb2RlbF9fO1xuICAgIC8vIGdldCB0eXBlIGZyb20gZm9ybVxuICAgIGlmIChlZGl0b3JNb2RlbCkge1xuICAgICAgLy8gZ2V0IGVsZW1lbnRhcnkgdHlwZXMsIHRoaXMgbWlnaHQgZ2V0IG92ZXJ3cml0dGVuIGxhdGVyIGFjY29yZGluZyB0byBkZWNvcmF0b3JzIGZvdW5kXG4gICAgICBpZiAodHlwZW9mIGVkaXRvck1vZGVsW3RoaXMubmFtZV0gPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHRoaXMudHlwZSA9ICd0ZXh0JztcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlb2YgZWRpdG9yTW9kZWxbdGhpcy5uYW1lXSA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgIHRoaXMudHlwZSA9ICdib29sZWFuJztcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlb2YgZWRpdG9yTW9kZWxbdGhpcy5uYW1lXSA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgdGhpcy50eXBlID0gJ251bWJlcic7XG4gICAgICB9XG4gICAgICBpZiAoZWRpdG9yTW9kZWxbdGhpcy5uYW1lXSBpbnN0YW5jZW9mIERhdGUpIHtcbiAgICAgICAgdGhpcy50eXBlID0gJ2NhbGVuZGFyJztcbiAgICAgIH1cbiAgICAgIC8vIG1ha2UgYW4gaW5zdGFuY2UgdG8gcmVhZCB0aGUgcHJvcGVydGllc1xuICAgICAgdGhpcy5sYWJlbCA9IGVkaXRvck1vZGVsW2BfX2Rpc3BsYXlOYW1lX18ke3RoaXMubmFtZX1gXSB8fCB0aGlzLmxhYmVsIHx8IHRoaXMubmFtZTtcbiAgICAgIHRoaXMudG9vbHRpcCA9IGVkaXRvck1vZGVsW2BfX2Rpc3BsYXlEZXNjX18ke3RoaXMubmFtZX1gXSB8fCB0aGlzLnRvb2x0aXAgfHwgdGhpcy5uYW1lO1xuICAgICAgLy8gcmVuZGVyIGFzIHJhbmdlIGlkIHRoZXJlIGlzIGEgcmFuZ2UgZGVmaW5pdGlvblxuICAgICAgaWYgKGVkaXRvck1vZGVsW2BfX2hhc1JhbmdlRnJvbV9fJHt0aGlzLm5hbWV9YF0gJiYgTnVtYmVyKGVkaXRvck1vZGVsW2BfX2hhc1JhbmdlRnJvbV9fJHt0aGlzLm5hbWV9YF0pKSB7XG4gICAgICAgIHRoaXMuZnJvbVZhbHVlID0gZWRpdG9yTW9kZWxbYF9faGFzUmFuZ2VGcm9tX18ke3RoaXMubmFtZX1gXSBhcyBudW1iZXI7XG4gICAgICAgIHRoaXMudHlwZSA9ICdyYW5nZSc7XG4gICAgICB9XG4gICAgICBpZiAoZWRpdG9yTW9kZWxbYF9faGFzUmFuZ2VUb19fJHt0aGlzLm5hbWV9YF0gJiYgTnVtYmVyKGVkaXRvck1vZGVsW2BfX2hhc1JhbmdlVG9fXyR7dGhpcy5uYW1lfWBdKSkge1xuICAgICAgICB0aGlzLnRvVmFsdWUgPSBlZGl0b3JNb2RlbFtgX19oYXNSYW5nZVRvX18ke3RoaXMubmFtZX1gXSBhcyBudW1iZXI7XG4gICAgICAgIHRoaXMudHlwZSA9ICdyYW5nZSc7XG4gICAgICB9XG4gICAgICAvLyBwbGFjZWhvbGRlclxuICAgICAgaWYgKGVkaXRvck1vZGVsW2BfX2hhc1dhdGVybWFya19fJHt0aGlzLm5hbWV9YF0pIHtcbiAgICAgICAgdGhpcy53YXRlck1hcmsgPSBlZGl0b3JNb2RlbFtgX193YXRlcm1hcmtfXyR7dGhpcy5uYW1lfWBdO1xuICAgICAgfVxuICAgICAgLy8gdGVtcGxhdGVzXG4gICAgICBpZiAoZWRpdG9yTW9kZWxbYF9faGFzVGVtcGxhdGVIaW50X18ke3RoaXMubmFtZX1gXSkge1xuICAgICAgICB0aGlzLnR5cGUgPSAoZWRpdG9yTW9kZWxbYF9fdGVtcGxhdGVoaW50X18ke3RoaXMubmFtZX1gXSBhcyBzdHJpbmcpLnRvTG93ZXJDYXNlKCk7XG4gICAgICAgIGlmIChlZGl0b3JNb2RlbFtgX190ZW1wbGF0ZWhpbnRQYXJhbXNfXyR7dGhpcy5uYW1lfWBdKSB7XG4gICAgICAgICAgdGhpcy5wYXJhbXMgPSBlZGl0b3JNb2RlbFtgX190ZW1wbGF0ZWhpbnRQYXJhbXNfXyR7dGhpcy5uYW1lfWBdIGFzIHsga2V5OiBzdHJpbmc7IHZhbHVlOiBhbnkgfVtdO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIHJlbmRlciBoaWRkZW4gZmllbGRzIGFzIGhpZGRlbiBldmVuIGluIGZvcm1zXG4gICAgICBpZiAoZWRpdG9yTW9kZWxbYF9faXNIaWRkZW5fXyR7dGhpcy5uYW1lfWBdKSB7XG4gICAgICAgIHRoaXMudHlwZSA9ICdoaWRkZW4nO1xuICAgICAgfVxuICAgICAgLy8gY2hlY2sgcmVhZG9ubHlcbiAgICAgIGlmIChlZGl0b3JNb2RlbFtgX19pc1JlYWRvbmx5X18ke3RoaXMubmFtZX1gXSkge1xuICAgICAgICB0aGlzLnJlYWRvbmx5ID0gISFlZGl0b3JNb2RlbFtgX19pc1JlYWRvbmx5X18ke3RoaXMubmFtZX1gXTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIG9uVmFsdWVDaGFuZ2VkKGRhdGE6IGFueSkge1xuICAgIC8vIGNoZWNrIHZhbGlkYXRpb24gb24gY2hhbmdlXG4gICAgdGhpcy5lcnJvcnMgPSBuZXcgQXJyYXk8c3RyaW5nPigpO1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpmb3JpblxuICAgIGZvciAoY29uc3QgZXJyb3IgaW4gdGhpcy5mb3JtR3JvdXAuY29udHJvbHNbdGhpcy5uYW1lXS5lcnJvcnMpIHtcbiAgICAgIHRoaXMuZXJyb3JzLnB1c2goZXJyb3IpO1xuICAgIH1cbiAgfVxufVxuIl19