dynamic-display-shared
Version:
A library for dynamic view
83 lines • 17.4 kB
JavaScript
import { COMMA, ENTER } from '@angular/cdk/keycodes';
import { Component, ElementRef, HostListener, Input } from '@angular/core';
import { FormControl, NG_VALUE_ACCESSOR } from '@angular/forms';
import * as i0 from "@angular/core";
import * as i1 from "@angular/common";
import * as i2 from "@angular/forms";
import * as i3 from "@angular/material/button";
import * as i4 from "@angular/material/icon";
import * as i5 from "@angular/material/form-field";
import * as i6 from "@angular/material/chips";
// https://netbasal.com/how-to-implement-file-uploading-in-angular-reactive-forms-89a3fffa1a03
export class FileUploadComponent {
constructor(host) {
this.host = host;
this.files = null;
this.filesNames = [];
this.separatorKeysCodes = [ENTER, COMMA];
}
emitFiles(event) {
// const file = event && event.item(0);
// this.onChange(file);
// this.file = file;
if (event) {
this.files = event;
this.filesNames = [];
for (let index = 0; index < this.files.length; index++) {
this.filesNames.push(this.files.item(index).name);
}
}
this.onChange(this.files);
}
ngOnInit() {
if (this.existsFile) {
this.filesNames.push(this.existsFile);
}
this.fileInputControl = new FormControl('', this.control.validator, this.control.asyncValidator);
this.fileRequired = this.control.hasError('required');
this.fileInputControl.markAllAsTouched();
}
writeValue(value) {
// clear file input
this.host.nativeElement.value = '';
this.files = null;
}
registerOnChange(fn) {
this.onChange = fn;
}
registerOnTouched(fn) {
}
removeFile(fileName) {
this.writeValue(null);
}
}
FileUploadComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.4", ngImport: i0, type: FileUploadComponent, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
FileUploadComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.0.4", type: FileUploadComponent, selector: "app-file-upload", inputs: { placeholder: "placeholder", explanation: "explanation", existsFile: "existsFile", control: "control" }, host: { listeners: { "change": "emitFiles($event.target.files)" } }, providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: FileUploadComponent,
multi: true
}
], ngImport: i0, template: "<mat-form-field class=\"upload-file-area\" [hintLabel]=\"explanation\">\r\n <mat-chip-list [formControl]=\"fileInputControl\" #chipListFile>\r\n <mat-chip *ngFor=\"let fileName of filesNames\" [removable]=\"true\" (removed)=\"removeFile(fileName)\">\r\n {{fileName}}\r\n <!-- <mat-icon matChipRemove>cancel</mat-icon> -->\r\n </mat-chip>\r\n <!-- <mat-chip *ngFor=\"let file of fileInput.files\" [removable]=\"true\" (removed)=\"removeFile(file.name)\">\r\n {{file.name}}\r\n <mat-icon matChipRemove>cancel</mat-icon>\r\n </mat-chip> -->\r\n <input disabled [placeholder]=\"placeholder\" [matChipInputFor]=\"chipListFile\"\r\n [matChipInputSeparatorKeyCodes]=\"separatorKeysCodes\" [matChipInputAddOnBlur]=\"true\" >\r\n <!-- (matChipInputTokenEnd)=\"addMultiParameter($event,parameter.metadata.id)\"> -->\r\n\r\n <!-- <mat-hint *ngIf=\"parameter.isExplanationDisplayed\" align=\"start\">{{parameter.metadata.explanation}}</mat-hint>-->\r\n <button mat-icon-button matSuffix (click)=\"fileInput.click()\">\r\n <mat-icon color=\"primary\">attach_file</mat-icon>\r\n </button>\r\n </mat-chip-list>\r\n\r\n <input hidden #fileInput type=\"file\" accept=\".pdf,.dwg,.shp\">\r\n</mat-form-field>\r\n<!-- <span *ngIf=\"fileRequired\" style=\"color: red;font-size: small;\" >\u05DE\u05E1\u05DE\u05DA \u05D6\u05D4 \u05D4\u05D9\u05E0\u05D5 \u05D7\u05D5\u05D1\u05D4</span> -->\r\n\r\n\r\n<!--<div>\r\n <span>{{placeholder}}</span>\r\n <span>{{file ? file.name : 'or drag and drop file here' }}</span>\r\n <input class=\"file-input\" type=\"file\">\r\n</div>\r\n <app-progress [progress]=\"progress\"></app-progress> -->\r\n", styles: [".upload-file-area{width:70%}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: i3.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i5.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i5.MatSuffix, selector: "[matSuffix]" }, { kind: "component", type: i6.MatChipList, selector: "mat-chip-list", inputs: ["role", "aria-describedby", "errorStateMatcher", "multiple", "compareWith", "value", "required", "placeholder", "disabled", "aria-orientation", "selectable", "tabIndex"], outputs: ["change", "valueChange"], exportAs: ["matChipList"] }, { kind: "directive", type: i6.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["color", "disableRipple", "tabIndex", "role", "selected", "value", "selectable", "disabled", "removable"], outputs: ["selectionChange", "destroyed", "removed"], exportAs: ["matChip"] }, { kind: "directive", type: i6.MatChipInput, selector: "input[matChipInputFor]", inputs: ["matChipInputFor", "matChipInputAddOnBlur", "matChipInputSeparatorKeyCodes", "placeholder", "id", "disabled"], outputs: ["matChipInputTokenEnd"], exportAs: ["matChipInput", "matChipInputFor"] }] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.4", ngImport: i0, type: FileUploadComponent, decorators: [{
type: Component,
args: [{ selector: 'app-file-upload', providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: FileUploadComponent,
multi: true
}
], template: "<mat-form-field class=\"upload-file-area\" [hintLabel]=\"explanation\">\r\n <mat-chip-list [formControl]=\"fileInputControl\" #chipListFile>\r\n <mat-chip *ngFor=\"let fileName of filesNames\" [removable]=\"true\" (removed)=\"removeFile(fileName)\">\r\n {{fileName}}\r\n <!-- <mat-icon matChipRemove>cancel</mat-icon> -->\r\n </mat-chip>\r\n <!-- <mat-chip *ngFor=\"let file of fileInput.files\" [removable]=\"true\" (removed)=\"removeFile(file.name)\">\r\n {{file.name}}\r\n <mat-icon matChipRemove>cancel</mat-icon>\r\n </mat-chip> -->\r\n <input disabled [placeholder]=\"placeholder\" [matChipInputFor]=\"chipListFile\"\r\n [matChipInputSeparatorKeyCodes]=\"separatorKeysCodes\" [matChipInputAddOnBlur]=\"true\" >\r\n <!-- (matChipInputTokenEnd)=\"addMultiParameter($event,parameter.metadata.id)\"> -->\r\n\r\n <!-- <mat-hint *ngIf=\"parameter.isExplanationDisplayed\" align=\"start\">{{parameter.metadata.explanation}}</mat-hint>-->\r\n <button mat-icon-button matSuffix (click)=\"fileInput.click()\">\r\n <mat-icon color=\"primary\">attach_file</mat-icon>\r\n </button>\r\n </mat-chip-list>\r\n\r\n <input hidden #fileInput type=\"file\" accept=\".pdf,.dwg,.shp\">\r\n</mat-form-field>\r\n<!-- <span *ngIf=\"fileRequired\" style=\"color: red;font-size: small;\" >\u05DE\u05E1\u05DE\u05DA \u05D6\u05D4 \u05D4\u05D9\u05E0\u05D5 \u05D7\u05D5\u05D1\u05D4</span> -->\r\n\r\n\r\n<!--<div>\r\n <span>{{placeholder}}</span>\r\n <span>{{file ? file.name : 'or drag and drop file here' }}</span>\r\n <input class=\"file-input\" type=\"file\">\r\n</div>\r\n <app-progress [progress]=\"progress\"></app-progress> -->\r\n", styles: [".upload-file-area{width:70%}\n"] }]
}], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { placeholder: [{
type: Input
}], explanation: [{
type: Input
}], existsFile: [{
type: Input
}], control: [{
type: Input
}], emitFiles: [{
type: HostListener,
args: ['change', ['$event.target.files']]
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsZS11cGxvYWQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvZHluYW1pYy1kaXNwbGF5LXNoYXJlZC9zcmMvbGliL3NoYXJlZC9jb21wb25lbnRzL2ZpbGUtdXBsb2FkL2ZpbGUtdXBsb2FkLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2R5bmFtaWMtZGlzcGxheS1zaGFyZWQvc3JjL2xpYi9zaGFyZWQvY29tcG9uZW50cy9maWxlLXVwbG9hZC9maWxlLXVwbG9hZC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQ3JELE9BQU8sRUFBRSxTQUFTLEVBQUUsVUFBVSxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQVUsTUFBTSxlQUFlLENBQUM7QUFDbkYsT0FBTyxFQUF3QixXQUFXLEVBQWEsaUJBQWlCLEVBQWMsTUFBTSxnQkFBZ0IsQ0FBQzs7Ozs7Ozs7QUFDN0csOEZBQThGO0FBYzlGLE1BQU0sT0FBTyxtQkFBbUI7SUFnQzlCLFlBQW9CLElBQWtDO1FBQWxDLFNBQUksR0FBSixJQUFJLENBQThCO1FBckI5QyxVQUFLLEdBQW9CLElBQUksQ0FBQztRQUN0QyxlQUFVLEdBQWEsRUFBRSxDQUFDO1FBSWpCLHVCQUFrQixHQUFhLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBaUJ2RCxDQUFDO0lBZmdELFNBQVMsQ0FBQyxLQUFlO1FBQ3hFLHVDQUF1QztRQUN2Qyx1QkFBdUI7UUFDdkIsb0JBQW9CO1FBQ3BCLElBQUksS0FBSyxFQUFFO1lBQ1QsSUFBSSxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUM7WUFDbkIsSUFBSSxDQUFDLFVBQVUsR0FBRyxFQUFFLENBQUM7WUFDckIsS0FBSyxJQUFJLEtBQUssR0FBRyxDQUFDLEVBQUUsS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFLEtBQUssRUFBRSxFQUFFO2dCQUN0RCxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQzthQUNwRDtTQUNGO1FBQ0QsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDNUIsQ0FBQztJQUlELFFBQVE7UUFDTixJQUFJLElBQUksQ0FBQyxVQUFVLEVBQUU7WUFDbkIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1NBQ3ZDO1FBQ0QsSUFBSSxDQUFDLGdCQUFnQixHQUFHLElBQUksV0FBVyxDQUFDLEVBQUUsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBQ2pHLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDdEQsSUFBSSxDQUFDLGdCQUFnQixDQUFDLGdCQUFnQixFQUFFLENBQUM7SUFDM0MsQ0FBQztJQUVELFVBQVUsQ0FBQyxLQUFXO1FBQ3BCLG1CQUFtQjtRQUNuQixJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxLQUFLLEdBQUcsRUFBRSxDQUFDO1FBQ25DLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDO0lBQ3BCLENBQUM7SUFFRCxnQkFBZ0IsQ0FBQyxFQUFZO1FBQzNCLElBQUksQ0FBQyxRQUFRLEdBQUcsRUFBRSxDQUFDO0lBQ3JCLENBQUM7SUFFRCxpQkFBaUIsQ0FBQyxFQUFZO0lBQzlCLENBQUM7SUFDRCxVQUFVLENBQUMsUUFBZ0I7UUFDekIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUN4QixDQUFDOztnSEF6RFUsbUJBQW1CO29HQUFuQixtQkFBbUIsaU9BUm5CO1FBQ1Q7WUFDRSxPQUFPLEVBQUUsaUJBQWlCO1lBQzFCLFdBQVcsRUFBRSxtQkFBbUI7WUFDaEMsS0FBSyxFQUFFLElBQUk7U0FDWjtLQUNGLDBCQ2ZILGtwREErQkE7MkZEZGEsbUJBQW1CO2tCQVovQixTQUFTOytCQUNFLGlCQUFpQixhQUdoQjt3QkFDVDs0QkFDRSxPQUFPLEVBQUUsaUJBQWlCOzRCQUMxQixXQUFXLHFCQUFxQjs0QkFDaEMsS0FBSyxFQUFFLElBQUk7eUJBQ1o7cUJBQ0Y7aUdBS0QsV0FBVztzQkFEVixLQUFLO2dCQUdOLFdBQVc7c0JBRFYsS0FBSztnQkFHTixVQUFVO3NCQURULEtBQUs7Z0JBR04sT0FBTztzQkFETixLQUFLO2dCQVUyQyxTQUFTO3NCQUF6RCxZQUFZO3VCQUFDLFFBQVEsRUFBRSxDQUFDLHFCQUFxQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ09NTUEsIEVOVEVSIH0gZnJvbSAnQGFuZ3VsYXIvY2RrL2tleWNvZGVzJztcclxuaW1wb3J0IHsgQ29tcG9uZW50LCBFbGVtZW50UmVmLCBIb3N0TGlzdGVuZXIsIElucHV0LCBPbkluaXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgQ29udHJvbFZhbHVlQWNjZXNzb3IsIEZvcm1Db250cm9sLCBGb3JtR3JvdXAsIE5HX1ZBTFVFX0FDQ0VTU09SLCBWYWxpZGF0b3JzIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xyXG4vLyBodHRwczovL25ldGJhc2FsLmNvbS9ob3ctdG8taW1wbGVtZW50LWZpbGUtdXBsb2FkaW5nLWluLWFuZ3VsYXItcmVhY3RpdmUtZm9ybXMtODlhM2ZmZmExYTAzXHJcblxyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ2FwcC1maWxlLXVwbG9hZCcsXHJcbiAgdGVtcGxhdGVVcmw6ICcuL2ZpbGUtdXBsb2FkLmNvbXBvbmVudC5odG1sJyxcclxuICBzdHlsZVVybHM6IFsnLi9maWxlLXVwbG9hZC5jb21wb25lbnQuY3NzJ10sXHJcbiAgcHJvdmlkZXJzOiBbXHJcbiAgICB7XHJcbiAgICAgIHByb3ZpZGU6IE5HX1ZBTFVFX0FDQ0VTU09SLFxyXG4gICAgICB1c2VFeGlzdGluZzogRmlsZVVwbG9hZENvbXBvbmVudCxcclxuICAgICAgbXVsdGk6IHRydWVcclxuICAgIH1cclxuICBdXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBGaWxlVXBsb2FkQ29tcG9uZW50IGltcGxlbWVudHMgQ29udHJvbFZhbHVlQWNjZXNzb3IsIE9uSW5pdCB7XHJcbiAgLy8gQElucHV0KCkgcHJvZ3Jlc3M7XHJcbiAgQElucHV0KClcclxuICBwbGFjZWhvbGRlciE6IHN0cmluZztcclxuICBASW5wdXQoKVxyXG4gIGV4cGxhbmF0aW9uITogc3RyaW5nO1xyXG4gIEBJbnB1dCgpXHJcbiAgZXhpc3RzRmlsZSE6IHN0cmluZztcclxuICBASW5wdXQoKVxyXG4gIGNvbnRyb2whOiBGb3JtQ29udHJvbDtcclxuICBvbkNoYW5nZSE6IEZ1bmN0aW9uO1xyXG4gIHByaXZhdGUgZmlsZXM6IEZpbGVMaXN0IHwgbnVsbCA9IG51bGw7XHJcbiAgZmlsZXNOYW1lczogc3RyaW5nW10gPSBbXTtcclxuICBmaWxlUmVxdWlyZWQ6IGFueTtcclxuICBmaWxlSW5wdXRDb250cm9sITogRm9ybUNvbnRyb2w7XHJcbiAgZmlsZUZvcm1Hcm91cCE6IEZvcm1Hcm91cDtcclxuICByZWFkb25seSBzZXBhcmF0b3JLZXlzQ29kZXM6IG51bWJlcltdID0gW0VOVEVSLCBDT01NQV07XHJcblxyXG4gIEBIb3N0TGlzdGVuZXIoJ2NoYW5nZScsIFsnJGV2ZW50LnRhcmdldC5maWxlcyddKSBlbWl0RmlsZXMoZXZlbnQ6IEZpbGVMaXN0KSB7XHJcbiAgICAvLyBjb25zdCBmaWxlID0gZXZlbnQgJiYgZXZlbnQuaXRlbSgwKTtcclxuICAgIC8vIHRoaXMub25DaGFuZ2UoZmlsZSk7XHJcbiAgICAvLyB0aGlzLmZpbGUgPSBmaWxlO1xyXG4gICAgaWYgKGV2ZW50KSB7XHJcbiAgICAgIHRoaXMuZmlsZXMgPSBldmVudDtcclxuICAgICAgdGhpcy5maWxlc05hbWVzID0gW107XHJcbiAgICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCB0aGlzLmZpbGVzLmxlbmd0aDsgaW5kZXgrKykge1xyXG4gICAgICAgIHRoaXMuZmlsZXNOYW1lcy5wdXNoKHRoaXMuZmlsZXMuaXRlbShpbmRleCkhLm5hbWUpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICB0aGlzLm9uQ2hhbmdlKHRoaXMuZmlsZXMpO1xyXG4gIH1cclxuXHJcbiAgY29uc3RydWN0b3IocHJpdmF0ZSBob3N0OiBFbGVtZW50UmVmPEhUTUxJbnB1dEVsZW1lbnQ+KSB7XHJcbiAgfVxyXG4gIG5nT25Jbml0KCk6IHZvaWQge1xyXG4gICAgaWYgKHRoaXMuZXhpc3RzRmlsZSkge1xyXG4gICAgICB0aGlzLmZpbGVzTmFtZXMucHVzaCh0aGlzLmV4aXN0c0ZpbGUpO1xyXG4gICAgfVxyXG4gICAgdGhpcy5maWxlSW5wdXRDb250cm9sID0gbmV3IEZvcm1Db250cm9sKCcnLCB0aGlzLmNvbnRyb2wudmFsaWRhdG9yLCB0aGlzLmNvbnRyb2wuYXN5bmNWYWxpZGF0b3IpO1xyXG4gICAgdGhpcy5maWxlUmVxdWlyZWQgPSB0aGlzLmNvbnRyb2wuaGFzRXJyb3IoJ3JlcXVpcmVkJyk7XHJcbiAgICB0aGlzLmZpbGVJbnB1dENvbnRyb2wubWFya0FsbEFzVG91Y2hlZCgpO1xyXG4gIH1cclxuXHJcbiAgd3JpdGVWYWx1ZSh2YWx1ZTogbnVsbCkge1xyXG4gICAgLy8gY2xlYXIgZmlsZSBpbnB1dFxyXG4gICAgdGhpcy5ob3N0Lm5hdGl2ZUVsZW1lbnQudmFsdWUgPSAnJztcclxuICAgIHRoaXMuZmlsZXMgPSBudWxsO1xyXG4gIH1cclxuXHJcbiAgcmVnaXN0ZXJPbkNoYW5nZShmbjogRnVuY3Rpb24pIHtcclxuICAgIHRoaXMub25DaGFuZ2UgPSBmbjtcclxuICB9XHJcblxyXG4gIHJlZ2lzdGVyT25Ub3VjaGVkKGZuOiBGdW5jdGlvbikge1xyXG4gIH1cclxuICByZW1vdmVGaWxlKGZpbGVOYW1lOiBzdHJpbmcpIHtcclxuICAgIHRoaXMud3JpdGVWYWx1ZShudWxsKTtcclxuICB9XHJcbn1cclxuIiwiPG1hdC1mb3JtLWZpZWxkIGNsYXNzPVwidXBsb2FkLWZpbGUtYXJlYVwiIFtoaW50TGFiZWxdPVwiZXhwbGFuYXRpb25cIj5cclxuICA8bWF0LWNoaXAtbGlzdCBbZm9ybUNvbnRyb2xdPVwiZmlsZUlucHV0Q29udHJvbFwiICNjaGlwTGlzdEZpbGU+XHJcbiAgICA8bWF0LWNoaXAgKm5nRm9yPVwibGV0IGZpbGVOYW1lIG9mIGZpbGVzTmFtZXNcIiBbcmVtb3ZhYmxlXT1cInRydWVcIiAocmVtb3ZlZCk9XCJyZW1vdmVGaWxlKGZpbGVOYW1lKVwiPlxyXG4gICAgICB7e2ZpbGVOYW1lfX1cclxuICAgICAgPCEtLSA8bWF0LWljb24gbWF0Q2hpcFJlbW92ZT5jYW5jZWw8L21hdC1pY29uPiAtLT5cclxuICAgIDwvbWF0LWNoaXA+XHJcbiAgPCEtLSA8bWF0LWNoaXAgKm5nRm9yPVwibGV0IGZpbGUgb2YgZmlsZUlucHV0LmZpbGVzXCIgW3JlbW92YWJsZV09XCJ0cnVlXCIgKHJlbW92ZWQpPVwicmVtb3ZlRmlsZShmaWxlLm5hbWUpXCI+XHJcbiAgICAgIHt7ZmlsZS5uYW1lfX1cclxuICAgICAgPG1hdC1pY29uIG1hdENoaXBSZW1vdmU+Y2FuY2VsPC9tYXQtaWNvbj5cclxuICAgIDwvbWF0LWNoaXA+IC0tPlxyXG4gICAgICA8aW5wdXQgZGlzYWJsZWQgW3BsYWNlaG9sZGVyXT1cInBsYWNlaG9sZGVyXCIgW21hdENoaXBJbnB1dEZvcl09XCJjaGlwTGlzdEZpbGVcIlxyXG4gICAgICAgIFttYXRDaGlwSW5wdXRTZXBhcmF0b3JLZXlDb2Rlc109XCJzZXBhcmF0b3JLZXlzQ29kZXNcIiBbbWF0Q2hpcElucHV0QWRkT25CbHVyXT1cInRydWVcIiA+XHJcbiAgICAgIDwhLS0gKG1hdENoaXBJbnB1dFRva2VuRW5kKT1cImFkZE11bHRpUGFyYW1ldGVyKCRldmVudCxwYXJhbWV0ZXIubWV0YWRhdGEuaWQpXCI+IC0tPlxyXG5cclxuICAgICAgPCEtLSA8bWF0LWhpbnQgKm5nSWY9XCJwYXJhbWV0ZXIuaXNFeHBsYW5hdGlvbkRpc3BsYXllZFwiIGFsaWduPVwic3RhcnRcIj57e3BhcmFtZXRlci5tZXRhZGF0YS5leHBsYW5hdGlvbn19PC9tYXQtaGludD4tLT5cclxuICA8YnV0dG9uIG1hdC1pY29uLWJ1dHRvbiBtYXRTdWZmaXggKGNsaWNrKT1cImZpbGVJbnB1dC5jbGljaygpXCI+XHJcbiAgICAgIDxtYXQtaWNvbiBjb2xvcj1cInByaW1hcnlcIj5hdHRhY2hfZmlsZTwvbWF0LWljb24+XHJcbiAgICA8L2J1dHRvbj5cclxuICA8L21hdC1jaGlwLWxpc3Q+XHJcblxyXG4gIDxpbnB1dCBoaWRkZW4gI2ZpbGVJbnB1dCB0eXBlPVwiZmlsZVwiIGFjY2VwdD1cIi5wZGYsLmR3Zywuc2hwXCI+XHJcbjwvbWF0LWZvcm0tZmllbGQ+XHJcbjwhLS0gPHNwYW4gKm5nSWY9XCJmaWxlUmVxdWlyZWRcIiBzdHlsZT1cImNvbG9yOiByZWQ7Zm9udC1zaXplOiBzbWFsbDtcIiA+157Xodee15og15bXlCDXlNeZ16DXlSDXl9eV15HXlDwvc3Bhbj4gLS0+XHJcblxyXG5cclxuPCEtLTxkaXY+XHJcbiAgPHNwYW4+e3twbGFjZWhvbGRlcn19PC9zcGFuPlxyXG4gIDxzcGFuPnt7ZmlsZSA/IGZpbGUubmFtZSA6ICdvciBkcmFnIGFuZCBkcm9wIGZpbGUgaGVyZScgfX08L3NwYW4+XHJcbiAgPGlucHV0IGNsYXNzPVwiZmlsZS1pbnB1dFwiIHR5cGU9XCJmaWxlXCI+XHJcbjwvZGl2PlxyXG4gPGFwcC1wcm9ncmVzcyBbcHJvZ3Jlc3NdPVwicHJvZ3Jlc3NcIj48L2FwcC1wcm9ncmVzcz4gLS0+XHJcbiJdfQ==