UNPKG

@netgrif/components

Version:

Netgrif Application Engine frontend Angular components

32 lines 23.3 kB
import { Component, Inject, Optional } from '@angular/core'; import { DATA_FIELD_PORTAL_DATA, AbstractFileListDefaultFieldComponent } from '@netgrif/components-core'; import * as i0 from "@angular/core"; import * as i1 from "@netgrif/components-core"; import * as i2 from "@ngx-translate/core"; import * as i3 from "@angular/common"; import * as i4 from "@ngbracket/ngx-layout"; import * as i5 from "@ngbracket/ngx-layout/extended"; import * as i6 from "@angular/material/button"; import * as i7 from "@angular/material/icon"; import * as i8 from "@angular/material/form-field"; import * as i9 from "@angular/material/progress-bar"; import * as i10 from "@angular/material/tooltip"; import * as i11 from "@angular/forms"; import * as i12 from "../../required-label/required-label.component"; export class FileListDefaultFieldComponent extends AbstractFileListDefaultFieldComponent { constructor(taskResourceService, log, snackbar, translate, eventService, dataFieldPortalData) { super(taskResourceService, log, snackbar, translate, eventService, dataFieldPortalData); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FileListDefaultFieldComponent, deps: [{ token: i1.TaskResourceService }, { token: i1.LoggerService }, { token: i1.SnackBarService }, { token: i2.TranslateService }, { token: i1.EventService }, { token: DATA_FIELD_PORTAL_DATA, optional: true }], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: FileListDefaultFieldComponent, selector: "nc-file-list-default-field", usesInheritance: true, ngImport: i0, template: "<div [ngClass]=\"{'netgrif-file-padding': !(!dataField.isInvalid(formControlRef) && hasHint()) && !dataField.isInvalid(formControlRef)}\">\n <div #fileLabel class=\"file-field-label\" [ngClass]=\"{'netgrif-label-disabled': formControlRef.disabled}\">\n {{dataField.title}}\n <nc-required-label *ngIf=\"dataField.behavior.required\" [isIn]=\"!dataField.disabled\"></nc-required-label>\n </div>\n <div class=\"form-input button-icon-input full-width\" fxLayout=\"row\" fxLayoutAlign=\"start center\"\n [ngClass]=\"{'form-input-disabled': formControlRef.disabled, 'form-input-error': dataField.isInvalid(formControlRef)}\"\n [ngStyle]=\"{\n '-webkit-clip-path': getCutProperty(fileLabel),\n 'clip-path': getCutProperty(fileLabel)\n }\">\n <button mat-icon-button matPrefix\n class=\"file-button-size\"\n [disabled]=\"formControlRef.disabled\"\n color=\"primary\"\n (click)=\"chooseFile()\"\n [matTooltip]=\"'dataField.file.clickToUpload' | translate\"\n [class.do-not-click]=\"state.uploading\">\n <mat-icon>file_upload</mat-icon>\n </button>\n <span *ngIf=\"uploadedFiles.length === 0\" (click)=\"chooseFile()\" fxFlex\n [ngClass]=\"{'no-cursor': formControlRef.disabled}\"\n class=\"input-placeholder input-name-ellipsis\">{{constructDisplayName()}}</span>\n <div *ngIf=\"uploadedFiles.length !== 0\" class=\"input-name-ellipsis\" fxFlex>\n <div *ngFor=\"let name of uploadedFiles\" fxLayoutAlign=\"start center\">\n <span (click)=\"download(name)\" fxFlex\n [matTooltip]=\"'dataField.file.clickToDownload' | translate : {fileName: name}\"\n class=\"input-name-ellipsis file-list-item\">{{name}}</span>\n <button (click)=\"deleteFile(name)\" [matTooltip]=\"'dataField.file.clickToDelete' | translate\"\n mat-icon-button\n *ngIf=\"!formControlRef.disabled\">\n <mat-icon color=\"warn\">close</mat-icon>\n </button>\n </div>\n </div>\n </div>\n <mat-progress-bar *ngIf=\"state.uploading || state.downloading\" color=\"primary\" [value]=\"state.progress\"\n [mode]=\"state.uploading ? 'determinate' : 'indeterminate'\"\n class=\"margin-bottom-default\"></mat-progress-bar>\n <input type=\"file\" #fileUploadInput name=\"fileUpload\" [multiple]=\"true\"\n accept=\"{{dataField.allowTypes}}\" class=\"invisible-input\"/>\n <input type=\"text\" [formControl]=\"formControlRef\" class=\"invisible-input\">\n <mat-hint class=\"file-hint-error\" [ngClass]=\"{'mat-hint-disabled': formControlRef.disabled}\"\n *ngIf=\"!dataField.isInvalid(formControlRef) && hasHint()\">{{dataField.description}}</mat-hint>\n <mat-error class=\"file-hint-error\"\n *ngIf=\"dataField.isInvalid(formControlRef)\">{{'dataField.validations.required' | translate}}</mat-error>\n</div>\n", styles: [".invisible-input{display:none}.margin-bottom-default{margin-bottom:8px}.do-not-click:hover{cursor:not-allowed}.input-name-ellipsis{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;cursor:pointer}.input-placeholder{color:#64748b}.button-icon-input{padding:2px!important}.full-width{width:100%;min-width:100%}.form-input{background:#fff;color:#64748b;outline:none;border:1px solid #64748B;text-align:left;font-size:14px;line-height:20px;border-radius:6px;min-width:5px;box-sizing:border-box;min-height:43px}.form-input:hover{border-width:2px;padding:1px!important}.form-input-disabled{background:transparent!important;border-color:#cbd5e1!important}.form-input-disabled:hover{border-width:1px;padding:2px!important}.placeholder{color:#0000006b!important}.file-hint-error{padding:0 1em;width:unset}.no-cursor{cursor:default!important;color:#64748b}.border-default{border-width:1px;border-style:solid;border-color:#000}@media only screen and (max-width: 959.99px){.input-name-ellipsis{word-break:break-word;white-space:normal;overflow-y:auto}}.file-field-label{transform:translate(.4em,-.45em) scale(.75);transform-origin:left;color:#64748b;background:transparent;width:fit-content;padding:0 .5em;z-index:5;height:0;position:relative}.netgrif-file-padding{padding-bottom:22px;position:relative}.file-button-size{height:38px;width:38px}\n"], dependencies: [{ kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i4.DefaultLayoutDirective, selector: " [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]", inputs: ["fxLayout", "fxLayout.xs", "fxLayout.sm", "fxLayout.md", "fxLayout.lg", "fxLayout.xl", "fxLayout.lt-sm", "fxLayout.lt-md", "fxLayout.lt-lg", "fxLayout.lt-xl", "fxLayout.gt-xs", "fxLayout.gt-sm", "fxLayout.gt-md", "fxLayout.gt-lg"] }, { kind: "directive", type: i4.DefaultLayoutAlignDirective, selector: " [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]", inputs: ["fxLayoutAlign", "fxLayoutAlign.xs", "fxLayoutAlign.sm", "fxLayoutAlign.md", "fxLayoutAlign.lg", "fxLayoutAlign.xl", "fxLayoutAlign.lt-sm", "fxLayoutAlign.lt-md", "fxLayoutAlign.lt-lg", "fxLayoutAlign.lt-xl", "fxLayoutAlign.gt-xs", "fxLayoutAlign.gt-sm", "fxLayoutAlign.gt-md", "fxLayoutAlign.gt-lg"] }, { kind: "directive", type: i4.DefaultFlexDirective, selector: " [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]", inputs: ["fxFlex", "fxFlex.xs", "fxFlex.sm", "fxFlex.md", "fxFlex.lg", "fxFlex.xl", "fxFlex.lt-sm", "fxFlex.lt-md", "fxFlex.lt-lg", "fxFlex.lt-xl", "fxFlex.gt-xs", "fxFlex.gt-sm", "fxFlex.gt-md", "fxFlex.gt-lg"] }, { kind: "directive", type: i5.DefaultClassDirective, selector: " [ngClass], [ngClass.xs], [ngClass.sm], [ngClass.md], [ngClass.lg], [ngClass.xl], [ngClass.lt-sm], [ngClass.lt-md], [ngClass.lt-lg], [ngClass.lt-xl], [ngClass.gt-xs], [ngClass.gt-sm], [ngClass.gt-md], [ngClass.gt-lg]", inputs: ["ngClass", "ngClass.xs", "ngClass.sm", "ngClass.md", "ngClass.lg", "ngClass.xl", "ngClass.lt-sm", "ngClass.lt-md", "ngClass.lt-lg", "ngClass.lt-xl", "ngClass.gt-xs", "ngClass.gt-sm", "ngClass.gt-md", "ngClass.gt-lg"] }, { kind: "directive", type: i5.DefaultStyleDirective, selector: " [ngStyle], [ngStyle.xs], [ngStyle.sm], [ngStyle.md], [ngStyle.lg], [ngStyle.xl], [ngStyle.lt-sm], [ngStyle.lt-md], [ngStyle.lt-lg], [ngStyle.lt-xl], [ngStyle.gt-xs], [ngStyle.gt-sm], [ngStyle.gt-md], [ngStyle.gt-lg]", inputs: ["ngStyle", "ngStyle.xs", "ngStyle.sm", "ngStyle.md", "ngStyle.lg", "ngStyle.xl", "ngStyle.lt-sm", "ngStyle.lt-md", "ngStyle.lt-lg", "ngStyle.lt-xl", "ngStyle.gt-xs", "ngStyle.gt-sm", "ngStyle.gt-md", "ngStyle.gt-lg"] }, { kind: "component", type: i6.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: i7.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i8.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i8.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i8.MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "component", type: i9.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "directive", type: i10.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: i11.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i11.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i11.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: i12.RequiredLabelComponent, selector: "nc-required-label", inputs: ["isIn"] }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }] }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FileListDefaultFieldComponent, decorators: [{ type: Component, args: [{ selector: 'nc-file-list-default-field', template: "<div [ngClass]=\"{'netgrif-file-padding': !(!dataField.isInvalid(formControlRef) && hasHint()) && !dataField.isInvalid(formControlRef)}\">\n <div #fileLabel class=\"file-field-label\" [ngClass]=\"{'netgrif-label-disabled': formControlRef.disabled}\">\n {{dataField.title}}\n <nc-required-label *ngIf=\"dataField.behavior.required\" [isIn]=\"!dataField.disabled\"></nc-required-label>\n </div>\n <div class=\"form-input button-icon-input full-width\" fxLayout=\"row\" fxLayoutAlign=\"start center\"\n [ngClass]=\"{'form-input-disabled': formControlRef.disabled, 'form-input-error': dataField.isInvalid(formControlRef)}\"\n [ngStyle]=\"{\n '-webkit-clip-path': getCutProperty(fileLabel),\n 'clip-path': getCutProperty(fileLabel)\n }\">\n <button mat-icon-button matPrefix\n class=\"file-button-size\"\n [disabled]=\"formControlRef.disabled\"\n color=\"primary\"\n (click)=\"chooseFile()\"\n [matTooltip]=\"'dataField.file.clickToUpload' | translate\"\n [class.do-not-click]=\"state.uploading\">\n <mat-icon>file_upload</mat-icon>\n </button>\n <span *ngIf=\"uploadedFiles.length === 0\" (click)=\"chooseFile()\" fxFlex\n [ngClass]=\"{'no-cursor': formControlRef.disabled}\"\n class=\"input-placeholder input-name-ellipsis\">{{constructDisplayName()}}</span>\n <div *ngIf=\"uploadedFiles.length !== 0\" class=\"input-name-ellipsis\" fxFlex>\n <div *ngFor=\"let name of uploadedFiles\" fxLayoutAlign=\"start center\">\n <span (click)=\"download(name)\" fxFlex\n [matTooltip]=\"'dataField.file.clickToDownload' | translate : {fileName: name}\"\n class=\"input-name-ellipsis file-list-item\">{{name}}</span>\n <button (click)=\"deleteFile(name)\" [matTooltip]=\"'dataField.file.clickToDelete' | translate\"\n mat-icon-button\n *ngIf=\"!formControlRef.disabled\">\n <mat-icon color=\"warn\">close</mat-icon>\n </button>\n </div>\n </div>\n </div>\n <mat-progress-bar *ngIf=\"state.uploading || state.downloading\" color=\"primary\" [value]=\"state.progress\"\n [mode]=\"state.uploading ? 'determinate' : 'indeterminate'\"\n class=\"margin-bottom-default\"></mat-progress-bar>\n <input type=\"file\" #fileUploadInput name=\"fileUpload\" [multiple]=\"true\"\n accept=\"{{dataField.allowTypes}}\" class=\"invisible-input\"/>\n <input type=\"text\" [formControl]=\"formControlRef\" class=\"invisible-input\">\n <mat-hint class=\"file-hint-error\" [ngClass]=\"{'mat-hint-disabled': formControlRef.disabled}\"\n *ngIf=\"!dataField.isInvalid(formControlRef) && hasHint()\">{{dataField.description}}</mat-hint>\n <mat-error class=\"file-hint-error\"\n *ngIf=\"dataField.isInvalid(formControlRef)\">{{'dataField.validations.required' | translate}}</mat-error>\n</div>\n", styles: [".invisible-input{display:none}.margin-bottom-default{margin-bottom:8px}.do-not-click:hover{cursor:not-allowed}.input-name-ellipsis{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;cursor:pointer}.input-placeholder{color:#64748b}.button-icon-input{padding:2px!important}.full-width{width:100%;min-width:100%}.form-input{background:#fff;color:#64748b;outline:none;border:1px solid #64748B;text-align:left;font-size:14px;line-height:20px;border-radius:6px;min-width:5px;box-sizing:border-box;min-height:43px}.form-input:hover{border-width:2px;padding:1px!important}.form-input-disabled{background:transparent!important;border-color:#cbd5e1!important}.form-input-disabled:hover{border-width:1px;padding:2px!important}.placeholder{color:#0000006b!important}.file-hint-error{padding:0 1em;width:unset}.no-cursor{cursor:default!important;color:#64748b}.border-default{border-width:1px;border-style:solid;border-color:#000}@media only screen and (max-width: 959.99px){.input-name-ellipsis{word-break:break-word;white-space:normal;overflow-y:auto}}.file-field-label{transform:translate(.4em,-.45em) scale(.75);transform-origin:left;color:#64748b;background:transparent;width:fit-content;padding:0 .5em;z-index:5;height:0;position:relative}.netgrif-file-padding{padding-bottom:22px;position:relative}.file-button-size{height:38px;width:38px}\n"] }] }], ctorParameters: () => [{ type: i1.TaskResourceService }, { type: i1.LoggerService }, { type: i1.SnackBarService }, { type: i2.TranslateService }, { type: i1.EventService }, { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [DATA_FIELD_PORTAL_DATA] }] }] }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsZS1saXN0LWRlZmF1bHQtZmllbGQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmV0Z3JpZi1jb21wb25lbnRzL3NyYy9saWIvZGF0YS1maWVsZHMvZmlsZS1saXN0LWZpZWxkL2ZpbGUtbGlzdC1kZWZhdWx0LWZpZWxkL2ZpbGUtbGlzdC1kZWZhdWx0LWZpZWxkLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25ldGdyaWYtY29tcG9uZW50cy9zcmMvbGliL2RhdGEtZmllbGRzL2ZpbGUtbGlzdC1maWVsZC9maWxlLWxpc3QtZGVmYXVsdC1maWVsZC9maWxlLWxpc3QtZGVmYXVsdC1maWVsZC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUMsU0FBUyxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUMsTUFBTSxlQUFlLENBQUM7QUFFMUQsT0FBTyxFQUtILHNCQUFzQixFQUVQLHFDQUFxQyxFQUN2RCxNQUFNLDBCQUEwQixDQUFBOzs7Ozs7Ozs7Ozs7OztBQU9qQyxNQUFNLE9BQU8sNkJBQThCLFNBQVEscUNBQXFDO0lBRXBGLFlBQVksbUJBQXdDLEVBQ3hDLEdBQWtCLEVBQ2xCLFFBQXlCLEVBQ3pCLFNBQTJCLEVBQzNCLFlBQTBCLEVBQ2tCLG1CQUF1RDtRQUMzRyxLQUFLLENBQUMsbUJBQW1CLEVBQUUsR0FBRyxFQUFFLFFBQVEsRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLG1CQUFtQixDQUFDLENBQUM7SUFDNUYsQ0FBQzt3R0FUUSw2QkFBNkIsNktBT04sc0JBQXNCOzRGQVA3Qyw2QkFBNkIseUZDakIxQyxvbkdBK0NBOzs0RkQ5QmEsNkJBQTZCO2tCQUx6QyxTQUFTOytCQUNFLDRCQUE0Qjs7MEJBV3ZCLFFBQVE7OzBCQUFJLE1BQU07MkJBQUMsc0JBQXNCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtDb21wb25lbnQsIEluamVjdCwgT3B0aW9uYWx9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtUcmFuc2xhdGVTZXJ2aWNlfSBmcm9tIFwiQG5neC10cmFuc2xhdGUvY29yZVwiO1xuaW1wb3J0IHtcbiAgICBUYXNrUmVzb3VyY2VTZXJ2aWNlLFxuICAgIExvZ2dlclNlcnZpY2UsXG4gICAgU25hY2tCYXJTZXJ2aWNlLFxuICAgIEV2ZW50U2VydmljZSxcbiAgICBEQVRBX0ZJRUxEX1BPUlRBTF9EQVRBLFxuICAgIERhdGFGaWVsZFBvcnRhbERhdGEsXG4gICAgRmlsZUxpc3RGaWVsZCwgQWJzdHJhY3RGaWxlTGlzdERlZmF1bHRGaWVsZENvbXBvbmVudFxufSBmcm9tICdAbmV0Z3JpZi9jb21wb25lbnRzLWNvcmUnXG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ25jLWZpbGUtbGlzdC1kZWZhdWx0LWZpZWxkJyxcbiAgdGVtcGxhdGVVcmw6ICcuL2ZpbGUtbGlzdC1kZWZhdWx0LWZpZWxkLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vZmlsZS1saXN0LWRlZmF1bHQtZmllbGQuY29tcG9uZW50LnNjc3MnXVxufSlcbmV4cG9ydCBjbGFzcyBGaWxlTGlzdERlZmF1bHRGaWVsZENvbXBvbmVudCBleHRlbmRzIEFic3RyYWN0RmlsZUxpc3REZWZhdWx0RmllbGRDb21wb25lbnQge1xuXG4gICAgY29uc3RydWN0b3IodGFza1Jlc291cmNlU2VydmljZTogVGFza1Jlc291cmNlU2VydmljZSxcbiAgICAgICAgICAgICAgICBsb2c6IExvZ2dlclNlcnZpY2UsXG4gICAgICAgICAgICAgICAgc25hY2tiYXI6IFNuYWNrQmFyU2VydmljZSxcbiAgICAgICAgICAgICAgICB0cmFuc2xhdGU6IFRyYW5zbGF0ZVNlcnZpY2UsXG4gICAgICAgICAgICAgICAgZXZlbnRTZXJ2aWNlOiBFdmVudFNlcnZpY2UsXG4gICAgICAgICAgICAgICAgQE9wdGlvbmFsKCkgQEluamVjdChEQVRBX0ZJRUxEX1BPUlRBTF9EQVRBKSBkYXRhRmllbGRQb3J0YWxEYXRhOiBEYXRhRmllbGRQb3J0YWxEYXRhPEZpbGVMaXN0RmllbGQ+KSB7XG4gICAgICAgIHN1cGVyKHRhc2tSZXNvdXJjZVNlcnZpY2UsIGxvZywgc25hY2tiYXIsIHRyYW5zbGF0ZSwgZXZlbnRTZXJ2aWNlLCBkYXRhRmllbGRQb3J0YWxEYXRhKTtcbiAgICB9XG59XG4iLCI8ZGl2IFtuZ0NsYXNzXT1cInsnbmV0Z3JpZi1maWxlLXBhZGRpbmcnOiAhKCFkYXRhRmllbGQuaXNJbnZhbGlkKGZvcm1Db250cm9sUmVmKSAmJiBoYXNIaW50KCkpICYmICFkYXRhRmllbGQuaXNJbnZhbGlkKGZvcm1Db250cm9sUmVmKX1cIj5cbiAgICA8ZGl2ICNmaWxlTGFiZWwgY2xhc3M9XCJmaWxlLWZpZWxkLWxhYmVsXCIgW25nQ2xhc3NdPVwieyduZXRncmlmLWxhYmVsLWRpc2FibGVkJzogZm9ybUNvbnRyb2xSZWYuZGlzYWJsZWR9XCI+XG4gICAgICAgIHt7ZGF0YUZpZWxkLnRpdGxlfX1cbiAgICAgICAgPG5jLXJlcXVpcmVkLWxhYmVsICpuZ0lmPVwiZGF0YUZpZWxkLmJlaGF2aW9yLnJlcXVpcmVkXCIgW2lzSW5dPVwiIWRhdGFGaWVsZC5kaXNhYmxlZFwiPjwvbmMtcmVxdWlyZWQtbGFiZWw+XG4gICAgPC9kaXY+XG4gICAgPGRpdiBjbGFzcz1cImZvcm0taW5wdXQgYnV0dG9uLWljb24taW5wdXQgZnVsbC13aWR0aFwiIGZ4TGF5b3V0PVwicm93XCIgZnhMYXlvdXRBbGlnbj1cInN0YXJ0IGNlbnRlclwiXG4gICAgICAgICBbbmdDbGFzc109XCJ7J2Zvcm0taW5wdXQtZGlzYWJsZWQnOiBmb3JtQ29udHJvbFJlZi5kaXNhYmxlZCwgJ2Zvcm0taW5wdXQtZXJyb3InOiBkYXRhRmllbGQuaXNJbnZhbGlkKGZvcm1Db250cm9sUmVmKX1cIlxuICAgICAgICAgW25nU3R5bGVdPVwie1xuICAgICAgICAgICAgICAgICAgICAnLXdlYmtpdC1jbGlwLXBhdGgnOiBnZXRDdXRQcm9wZXJ0eShmaWxlTGFiZWwpLFxuICAgICAgICAgICAgICAgICAgICAnY2xpcC1wYXRoJzogZ2V0Q3V0UHJvcGVydHkoZmlsZUxhYmVsKVxuICAgICAgICAgICAgfVwiPlxuICAgICAgICA8YnV0dG9uIG1hdC1pY29uLWJ1dHRvbiBtYXRQcmVmaXhcbiAgICAgICAgICAgICAgICBjbGFzcz1cImZpbGUtYnV0dG9uLXNpemVcIlxuICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJmb3JtQ29udHJvbFJlZi5kaXNhYmxlZFwiXG4gICAgICAgICAgICAgICAgY29sb3I9XCJwcmltYXJ5XCJcbiAgICAgICAgICAgICAgICAoY2xpY2spPVwiY2hvb3NlRmlsZSgpXCJcbiAgICAgICAgICAgICAgICBbbWF0VG9vbHRpcF09XCInZGF0YUZpZWxkLmZpbGUuY2xpY2tUb1VwbG9hZCcgfCB0cmFuc2xhdGVcIlxuICAgICAgICAgICAgICAgIFtjbGFzcy5kby1ub3QtY2xpY2tdPVwic3RhdGUudXBsb2FkaW5nXCI+XG4gICAgICAgICAgICA8bWF0LWljb24+ZmlsZV91cGxvYWQ8L21hdC1pY29uPlxuICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgPHNwYW4gKm5nSWY9XCJ1cGxvYWRlZEZpbGVzLmxlbmd0aCA9PT0gMFwiIChjbGljayk9XCJjaG9vc2VGaWxlKClcIiBmeEZsZXhcbiAgICAgICAgICAgICAgW25nQ2xhc3NdPVwieyduby1jdXJzb3InOiBmb3JtQ29udHJvbFJlZi5kaXNhYmxlZH1cIlxuICAgICAgICAgICAgICBjbGFzcz1cImlucHV0LXBsYWNlaG9sZGVyIGlucHV0LW5hbWUtZWxsaXBzaXNcIj57e2NvbnN0cnVjdERpc3BsYXlOYW1lKCl9fTwvc3Bhbj5cbiAgICAgICAgPGRpdiAqbmdJZj1cInVwbG9hZGVkRmlsZXMubGVuZ3RoICE9PSAwXCIgY2xhc3M9XCJpbnB1dC1uYW1lLWVsbGlwc2lzXCIgZnhGbGV4PlxuICAgICAgICAgICAgPGRpdiAqbmdGb3I9XCJsZXQgbmFtZSBvZiB1cGxvYWRlZEZpbGVzXCIgZnhMYXlvdXRBbGlnbj1cInN0YXJ0IGNlbnRlclwiPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiAoY2xpY2spPVwiZG93bmxvYWQobmFtZSlcIiBmeEZsZXhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgW21hdFRvb2x0aXBdPVwiJ2RhdGFGaWVsZC5maWxlLmNsaWNrVG9Eb3dubG9hZCcgfCB0cmFuc2xhdGUgOiB7ZmlsZU5hbWU6IG5hbWV9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJpbnB1dC1uYW1lLWVsbGlwc2lzIGZpbGUtbGlzdC1pdGVtXCI+e3tuYW1lfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgPGJ1dHRvbiAoY2xpY2spPVwiZGVsZXRlRmlsZShuYW1lKVwiIFttYXRUb29sdGlwXT1cIidkYXRhRmllbGQuZmlsZS5jbGlja1RvRGVsZXRlJyB8IHRyYW5zbGF0ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBtYXQtaWNvbi1idXR0b25cbiAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiIWZvcm1Db250cm9sUmVmLmRpc2FibGVkXCI+XG4gICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiBjb2xvcj1cIndhcm5cIj5jbG9zZTwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gICAgPG1hdC1wcm9ncmVzcy1iYXIgKm5nSWY9XCJzdGF0ZS51cGxvYWRpbmcgfHwgc3RhdGUuZG93bmxvYWRpbmdcIiBjb2xvcj1cInByaW1hcnlcIiBbdmFsdWVdPVwic3RhdGUucHJvZ3Jlc3NcIlxuICAgICAgICAgICAgICAgICAgICAgIFttb2RlXT1cInN0YXRlLnVwbG9hZGluZyA/ICdkZXRlcm1pbmF0ZScgOiAnaW5kZXRlcm1pbmF0ZSdcIlxuICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwibWFyZ2luLWJvdHRvbS1kZWZhdWx0XCI+PC9tYXQtcHJvZ3Jlc3MtYmFyPlxuICAgIDxpbnB1dCB0eXBlPVwiZmlsZVwiICNmaWxlVXBsb2FkSW5wdXQgbmFtZT1cImZpbGVVcGxvYWRcIiBbbXVsdGlwbGVdPVwidHJ1ZVwiXG4gICAgICAgICAgIGFjY2VwdD1cInt7ZGF0YUZpZWxkLmFsbG93VHlwZXN9fVwiIGNsYXNzPVwiaW52aXNpYmxlLWlucHV0XCIvPlxuICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIFtmb3JtQ29udHJvbF09XCJmb3JtQ29udHJvbFJlZlwiIGNsYXNzPVwiaW52aXNpYmxlLWlucHV0XCI+XG4gICAgPG1hdC1oaW50IGNsYXNzPVwiZmlsZS1oaW50LWVycm9yXCIgW25nQ2xhc3NdPVwieydtYXQtaGludC1kaXNhYmxlZCc6IGZvcm1Db250cm9sUmVmLmRpc2FibGVkfVwiXG4gICAgICAgICAgICAgICpuZ0lmPVwiIWRhdGFGaWVsZC5pc0ludmFsaWQoZm9ybUNvbnRyb2xSZWYpICYmIGhhc0hpbnQoKVwiPnt7ZGF0YUZpZWxkLmRlc2NyaXB0aW9ufX08L21hdC1oaW50PlxuICAgIDxtYXQtZXJyb3IgY2xhc3M9XCJmaWxlLWhpbnQtZXJyb3JcIlxuICAgICAgICAgICAgICAgKm5nSWY9XCJkYXRhRmllbGQuaXNJbnZhbGlkKGZvcm1Db250cm9sUmVmKVwiPnt7J2RhdGFGaWVsZC52YWxpZGF0aW9ucy5yZXF1aXJlZCcgfCB0cmFuc2xhdGV9fTwvbWF0LWVycm9yPlxuPC9kaXY+XG4iXX0=