@netgrif/components
Version:
Netgrif Application Engine frontend Angular components
52 lines • 31.3 kB
JavaScript
import { Component, Inject, Optional } from '@angular/core';
import { DATA_FIELD_PORTAL_DATA, AbstractFileDefaultFieldComponent } from "@netgrif/components-core";
import { PreviewDialogComponent } from "../preview-dialog/preview-dialog.component";
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/platform-browser";
import * as i4 from "@angular/material/dialog";
import * as i5 from "@angular/common";
import * as i6 from "@ngbracket/ngx-layout";
import * as i7 from "@ngbracket/ngx-layout/extended";
import * as i8 from "@angular/material/button";
import * as i9 from "@angular/material/icon";
import * as i10 from "@angular/material/form-field";
import * as i11 from "@angular/material/progress-bar";
import * as i12 from "@angular/material/progress-spinner";
import * as i13 from "@angular/material/tooltip";
import * as i14 from "@angular/forms";
import * as i15 from "angular-resize-event";
import * as i16 from "../../required-label/required-label.component";
export class FileDefaultFieldComponent extends AbstractFileDefaultFieldComponent {
_sanitizer;
dialog;
constructor(taskResourceService, log, snackbar, translate, eventService, _sanitizer, dialog, dataFieldPortalData) {
super(taskResourceService, log, snackbar, translate, eventService, _sanitizer, dataFieldPortalData);
this._sanitizer = _sanitizer;
this.dialog = dialog;
}
showPreviewDialog() {
super.showPreviewDialog();
this.dialog.open(PreviewDialogComponent, {
data: {
dataField: this.dataField,
imagePreview: this.previewSource,
imageFull: this.fullSource,
extension: this.previewExtension
}
});
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FileDefaultFieldComponent, deps: [{ token: i1.TaskResourceService }, { token: i1.LoggerService }, { token: i1.SnackBarService }, { token: i2.TranslateService }, { token: i1.EventService }, { token: i3.DomSanitizer }, { token: i4.MatDialog }, { token: DATA_FIELD_PORTAL_DATA, optional: true }], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: FileDefaultFieldComponent, selector: "nc-file-default-field", usesInheritance: true, ngImport: i0, template: "<div fxLayoutAlign=\"center center\" fxLayout=\"row\">\n <div fxFlex=\"{{!isFilePreview ? '100' : '75'}}\" [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 [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 (click)=\"isEmpty() ? chooseFile() : download()\" fxFlex\n [matTooltip]=\"isEmpty() ? '' : ('dataField.file.clickToDownload' | translate : {fileName: constructDisplayName()})\"\n class=\"input-name-ellipsis\"\n [ngClass]=\"{'input-placeholder': isEmpty(), 'no-cursor': isEmpty() && formControlRef.disabled}\">{{constructDisplayName()}}</span>\n <button (click)=\"showPreviewDialog()\" [matTooltip]=\"'dataField.file.clickToDelete' | translate\" mat-icon-button\n *ngIf=\"isFilePreviewButton && !isEmpty() && isDisplayable\">\n <mat-icon color=\"primary\">search</mat-icon>\n </button>\n <button (click)=\"deleteFile()\" [matTooltip]=\"'dataField.file.clickToDelete' | translate\" mat-icon-button\n *ngIf=\"!isEmpty() && !formControlRef.disabled\">\n <mat-icon color=\"warn\">close</mat-icon>\n </button>\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]=\"false\"\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 <div *ngIf=\"isFilePreview\" fxFlex=\"5\"></div>\n <div *ngIf=\"isFilePreview\" fxFlex=\"20\" fxLayout=\"row\" fxLayoutAlign=\"center center\" #imageDiv\n (resized)=\"changeMaxWidth($event)\">\n <img *ngIf=\"previewSource !== undefined && !state.downloading && isDisplayable\" class=\"image-preview\" #imageEl\n [ngStyle]=\"!isBorderLGBTQ() && !isBorderDefault() && {\n 'border-width': getPreviewBorderWidth(),\n 'border-style': getPreviewBorderStyle(),\n 'border-color': getPreviewBorderColor()\n }\"\n [ngClass]=\"{'border-LGBTQ': isBorderLGBTQ(), 'border-default': isBorderDefault()}\"\n [src]=\"previewSource\" alt=\"Image preview\" (click)=\"showPreviewDialog()\"/>\n <mat-spinner *ngIf=\"previewSource === undefined && !!state.downloading && isDisplayable\"\n [diameter]=\"26\"></mat-spinner>\n </div>\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;height:43px}.form-input:hover{border-width:2px;padding-left:1px!important;padding-right:1px!important}.form-input-disabled,.form-input-disabled:focus-within{background:transparent!important;border-color:#cbd5e1!important}.form-input-disabled:hover,.form-input-disabled:focus-within{border-width:1px!important;padding:2px!important}.file-hint-error{padding:0 1em;width:unset}.image-preview{width:auto;height:auto;cursor:pointer}.no-cursor{cursor:default!important;color:#64748b}.border-LGBTQ{border:5px solid transparent;border-image:linear-gradient(to bottom right,#b827fc,#2c90fc,#b8fd33,#fec837,#fd1892);border-image-slice:1;animation:rainbow 10s infinite}@keyframes rainbow{0%{border-image:linear-gradient(to bottom right,#b827fc,#2c90fc,#b8fd33,#fec837,#fd1892);border-image-slice:1}20%{border-image:linear-gradient(to bottom right,#2c90fc,#b8fd33,#fec837,#fd1892,#b827fc);border-image-slice:1}40%{border-image:linear-gradient(to bottom right,#b8fd33,#fec837,#fd1892,#b827fc,#2c90fc);border-image-slice:1}60%{border-image:linear-gradient(to bottom right,#fec837,#fd1892,#b827fc,#2c90fc,#b8fd33);border-image-slice:1}80%{border-image:linear-gradient(to bottom right,#fd1892,#b827fc,#2c90fc,#b8fd33,#fec837);border-image-slice:1}to{border-image:linear-gradient(to bottom right,#b827fc,#2c90fc,#b8fd33,#fec837,#fd1892);border-image-slice:1}}.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;max-height:40px}}.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}\n"], dependencies: [{ kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i6.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: i6.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: i6.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: i7.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: i7.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: i8.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: i9.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i10.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i10.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i10.MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "component", type: i11.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "component", type: i12.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "directive", type: i13.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: i14.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: i14.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i14.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i15.ResizedDirective, selector: "[resized]", outputs: ["resized"] }, { kind: "component", type: i16.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: FileDefaultFieldComponent, decorators: [{
type: Component,
args: [{ selector: 'nc-file-default-field', template: "<div fxLayoutAlign=\"center center\" fxLayout=\"row\">\n <div fxFlex=\"{{!isFilePreview ? '100' : '75'}}\" [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 [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 (click)=\"isEmpty() ? chooseFile() : download()\" fxFlex\n [matTooltip]=\"isEmpty() ? '' : ('dataField.file.clickToDownload' | translate : {fileName: constructDisplayName()})\"\n class=\"input-name-ellipsis\"\n [ngClass]=\"{'input-placeholder': isEmpty(), 'no-cursor': isEmpty() && formControlRef.disabled}\">{{constructDisplayName()}}</span>\n <button (click)=\"showPreviewDialog()\" [matTooltip]=\"'dataField.file.clickToDelete' | translate\" mat-icon-button\n *ngIf=\"isFilePreviewButton && !isEmpty() && isDisplayable\">\n <mat-icon color=\"primary\">search</mat-icon>\n </button>\n <button (click)=\"deleteFile()\" [matTooltip]=\"'dataField.file.clickToDelete' | translate\" mat-icon-button\n *ngIf=\"!isEmpty() && !formControlRef.disabled\">\n <mat-icon color=\"warn\">close</mat-icon>\n </button>\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]=\"false\"\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 <div *ngIf=\"isFilePreview\" fxFlex=\"5\"></div>\n <div *ngIf=\"isFilePreview\" fxFlex=\"20\" fxLayout=\"row\" fxLayoutAlign=\"center center\" #imageDiv\n (resized)=\"changeMaxWidth($event)\">\n <img *ngIf=\"previewSource !== undefined && !state.downloading && isDisplayable\" class=\"image-preview\" #imageEl\n [ngStyle]=\"!isBorderLGBTQ() && !isBorderDefault() && {\n 'border-width': getPreviewBorderWidth(),\n 'border-style': getPreviewBorderStyle(),\n 'border-color': getPreviewBorderColor()\n }\"\n [ngClass]=\"{'border-LGBTQ': isBorderLGBTQ(), 'border-default': isBorderDefault()}\"\n [src]=\"previewSource\" alt=\"Image preview\" (click)=\"showPreviewDialog()\"/>\n <mat-spinner *ngIf=\"previewSource === undefined && !!state.downloading && isDisplayable\"\n [diameter]=\"26\"></mat-spinner>\n </div>\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;height:43px}.form-input:hover{border-width:2px;padding-left:1px!important;padding-right:1px!important}.form-input-disabled,.form-input-disabled:focus-within{background:transparent!important;border-color:#cbd5e1!important}.form-input-disabled:hover,.form-input-disabled:focus-within{border-width:1px!important;padding:2px!important}.file-hint-error{padding:0 1em;width:unset}.image-preview{width:auto;height:auto;cursor:pointer}.no-cursor{cursor:default!important;color:#64748b}.border-LGBTQ{border:5px solid transparent;border-image:linear-gradient(to bottom right,#b827fc,#2c90fc,#b8fd33,#fec837,#fd1892);border-image-slice:1;animation:rainbow 10s infinite}@keyframes rainbow{0%{border-image:linear-gradient(to bottom right,#b827fc,#2c90fc,#b8fd33,#fec837,#fd1892);border-image-slice:1}20%{border-image:linear-gradient(to bottom right,#2c90fc,#b8fd33,#fec837,#fd1892,#b827fc);border-image-slice:1}40%{border-image:linear-gradient(to bottom right,#b8fd33,#fec837,#fd1892,#b827fc,#2c90fc);border-image-slice:1}60%{border-image:linear-gradient(to bottom right,#fec837,#fd1892,#b827fc,#2c90fc,#b8fd33);border-image-slice:1}80%{border-image:linear-gradient(to bottom right,#fd1892,#b827fc,#2c90fc,#b8fd33,#fec837);border-image-slice:1}to{border-image:linear-gradient(to bottom right,#b827fc,#2c90fc,#b8fd33,#fec837,#fd1892);border-image-slice:1}}.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;max-height:40px}}.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}\n"] }]
}], ctorParameters: () => [{ type: i1.TaskResourceService }, { type: i1.LoggerService }, { type: i1.SnackBarService }, { type: i2.TranslateService }, { type: i1.EventService }, { type: i3.DomSanitizer }, { type: i4.MatDialog }, { type: undefined, decorators: [{
type: Optional
}, {
type: Inject,
args: [DATA_FIELD_PORTAL_DATA]
}] }] });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsZS1kZWZhdWx0LWZpZWxkLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25ldGdyaWYtY29tcG9uZW50cy9zcmMvbGliL2RhdGEtZmllbGRzL2ZpbGUtZmllbGQvZmlsZS1kZWZhdWx0LWZpZWxkL2ZpbGUtZGVmYXVsdC1maWVsZC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZXRncmlmLWNvbXBvbmVudHMvc3JjL2xpYi9kYXRhLWZpZWxkcy9maWxlLWZpZWxkL2ZpbGUtZGVmYXVsdC1maWVsZC9maWxlLWRlZmF1bHQtZmllbGQuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFDLFNBQVMsRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFDLE1BQU0sZUFBZSxDQUFDO0FBQzFELE9BQU8sRUFDSCxzQkFBc0IsRUFLdEIsaUNBQWlDLEVBQ3BDLE1BQU0sMEJBQTBCLENBQUM7QUFJbEMsT0FBTyxFQUFDLHNCQUFzQixFQUFDLE1BQU0sNENBQTRDLENBQUM7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQU9sRixNQUFNLE9BQU8seUJBQTBCLFNBQVEsaUNBQWlDO0lBT3REO0lBQ0E7SUFOdEIsWUFBWSxtQkFBd0MsRUFDeEMsR0FBa0IsRUFDbEIsUUFBeUIsRUFDekIsU0FBMkIsRUFDM0IsWUFBMEIsRUFDaEIsVUFBd0IsRUFDeEIsTUFBaUIsRUFDaUIsbUJBQW1EO1FBQ3ZHLEtBQUssQ0FBQyxtQkFBbUIsRUFBRSxHQUFHLEVBQUUsUUFBUSxFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsVUFBVSxFQUFFLG1CQUFtQixDQUFDLENBQUM7UUFIbEYsZUFBVSxHQUFWLFVBQVUsQ0FBYztRQUN4QixXQUFNLEdBQU4sTUFBTSxDQUFXO0lBR3ZDLENBQUM7SUFFTSxpQkFBaUI7UUFDcEIsS0FBSyxDQUFDLGlCQUFpQixFQUFFLENBQUM7UUFDMUIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsc0JBQXNCLEVBQUU7WUFDckMsSUFBSSxFQUFFO2dCQUNGLFNBQVMsRUFBRSxJQUFJLENBQUMsU0FBUztnQkFDekIsWUFBWSxFQUFFLElBQUksQ0FBQyxhQUFhO2dCQUNoQyxTQUFTLEVBQUUsSUFBSSxDQUFDLFVBQVU7Z0JBQzFCLFNBQVMsRUFBRSxJQUFJLENBQUMsZ0JBQWdCO2FBQ25DO1NBQ0osQ0FBQyxDQUFDO0lBQ1AsQ0FBQzt3R0F2QlEseUJBQXlCLGtPQVNGLHNCQUFzQjs0RkFUN0MseUJBQXlCLG9GQ25CdEMseXNJQTJEQTs7NEZEeENhLHlCQUF5QjtrQkFMckMsU0FBUzsrQkFDRSx1QkFBdUI7OzBCQWFsQixRQUFROzswQkFBSSxNQUFNOzJCQUFDLHNCQUFzQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7Q29tcG9uZW50LCBJbmplY3QsIE9wdGlvbmFsfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7XG4gICAgREFUQV9GSUVMRF9QT1JUQUxfREFUQSwgRGF0YUZpZWxkUG9ydGFsRGF0YSxcbiAgICBFdmVudFNlcnZpY2UsIEZpbGVGaWVsZCxcbiAgICBMb2dnZXJTZXJ2aWNlLFxuICAgIFNuYWNrQmFyU2VydmljZSxcbiAgICBUYXNrUmVzb3VyY2VTZXJ2aWNlLFxuICAgIEFic3RyYWN0RmlsZURlZmF1bHRGaWVsZENvbXBvbmVudFxufSBmcm9tIFwiQG5ldGdyaWYvY29tcG9uZW50cy1jb3JlXCI7XG5pbXBvcnQge1RyYW5zbGF0ZVNlcnZpY2V9IGZyb20gXCJAbmd4LXRyYW5zbGF0ZS9jb3JlXCI7XG5pbXBvcnQge0RvbVNhbml0aXplcn0gZnJvbSBcIkBhbmd1bGFyL3BsYXRmb3JtLWJyb3dzZXJcIjtcbmltcG9ydCB7TWF0RGlhbG9nfSBmcm9tIFwiQGFuZ3VsYXIvbWF0ZXJpYWwvZGlhbG9nXCI7XG5pbXBvcnQge1ByZXZpZXdEaWFsb2dDb21wb25lbnR9IGZyb20gXCIuLi9wcmV2aWV3LWRpYWxvZy9wcmV2aWV3LWRpYWxvZy5jb21wb25lbnRcIjtcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnbmMtZmlsZS1kZWZhdWx0LWZpZWxkJyxcbiAgdGVtcGxhdGVVcmw6ICcuL2ZpbGUtZGVmYXVsdC1maWVsZC5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL2ZpbGUtZGVmYXVsdC1maWVsZC5jb21wb25lbnQuc2NzcyddXG59KVxuZXhwb3J0IGNsYXNzIEZpbGVEZWZhdWx0RmllbGRDb21wb25lbnQgZXh0ZW5kcyBBYnN0cmFjdEZpbGVEZWZhdWx0RmllbGRDb21wb25lbnR7XG5cbiAgICBjb25zdHJ1Y3Rvcih0YXNrUmVzb3VyY2VTZXJ2aWNlOiBUYXNrUmVzb3VyY2VTZXJ2aWNlLFxuICAgICAgICAgICAgICAgIGxvZzogTG9nZ2VyU2VydmljZSxcbiAgICAgICAgICAgICAgICBzbmFja2JhcjogU25hY2tCYXJTZXJ2aWNlLFxuICAgICAgICAgICAgICAgIHRyYW5zbGF0ZTogVHJhbnNsYXRlU2VydmljZSxcbiAgICAgICAgICAgICAgICBldmVudFNlcnZpY2U6IEV2ZW50U2VydmljZSxcbiAgICAgICAgICAgICAgICBwcm90ZWN0ZWQgX3Nhbml0aXplcjogRG9tU2FuaXRpemVyLFxuICAgICAgICAgICAgICAgIHByb3RlY3RlZCBkaWFsb2c6IE1hdERpYWxvZyxcbiAgICAgICAgICAgICAgICBAT3B0aW9uYWwoKSBASW5qZWN0KERBVEFfRklFTERfUE9SVEFMX0RBVEEpIGRhdGFGaWVsZFBvcnRhbERhdGE6IERhdGFGaWVsZFBvcnRhbERhdGE8RmlsZUZpZWxkPikge1xuICAgICAgICBzdXBlcih0YXNrUmVzb3VyY2VTZXJ2aWNlLCBsb2csIHNuYWNrYmFyLCB0cmFuc2xhdGUsIGV2ZW50U2VydmljZSwgX3Nhbml0aXplciwgZGF0YUZpZWxkUG9ydGFsRGF0YSk7XG4gICAgfVxuXG4gICAgcHVibGljIHNob3dQcmV2aWV3RGlhbG9nKCkge1xuICAgICAgICBzdXBlci5zaG93UHJldmlld0RpYWxvZygpO1xuICAgICAgICB0aGlzLmRpYWxvZy5vcGVuKFByZXZpZXdEaWFsb2dDb21wb25lbnQsIHtcbiAgICAgICAgICAgIGRhdGE6IHtcbiAgICAgICAgICAgICAgICBkYXRhRmllbGQ6IHRoaXMuZGF0YUZpZWxkLFxuICAgICAgICAgICAgICAgIGltYWdlUHJldmlldzogdGhpcy5wcmV2aWV3U291cmNlLFxuICAgICAgICAgICAgICAgIGltYWdlRnVsbDogdGhpcy5mdWxsU291cmNlLFxuICAgICAgICAgICAgICAgIGV4dGVuc2lvbjogdGhpcy5wcmV2aWV3RXh0ZW5zaW9uXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxufVxuIiwiPGRpdiBmeExheW91dEFsaWduPVwiY2VudGVyIGNlbnRlclwiIGZ4TGF5b3V0PVwicm93XCI+XG4gICAgPGRpdiBmeEZsZXg9XCJ7eyFpc0ZpbGVQcmV2aWV3ID8gJzEwMCcgOiAnNzUnfX1cIiBbbmdDbGFzc109XCJ7J25ldGdyaWYtZmlsZS1wYWRkaW5nJzogISghZGF0YUZpZWxkLmlzSW52YWxpZChmb3JtQ29udHJvbFJlZikgJiYgaGFzSGludCgpKSAmJiAhZGF0YUZpZWxkLmlzSW52YWxpZChmb3JtQ29udHJvbFJlZil9XCI+XG4gICAgICAgIDxkaXYgI2ZpbGVMYWJlbCBjbGFzcz1cImZpbGUtZmllbGQtbGFiZWxcIiBbbmdDbGFzc109XCJ7J25ldGdyaWYtbGFiZWwtZGlzYWJsZWQnOiBmb3JtQ29udHJvbFJlZi5kaXNhYmxlZH1cIj5cbiAgICAgICAgICAgIHt7ZGF0YUZpZWxkLnRpdGxlfX1cbiAgICAgICAgICAgIDxuYy1yZXF1aXJlZC1sYWJlbCAqbmdJZj1cImRhdGFGaWVsZC5iZWhhdmlvci5yZXF1aXJlZFwiIFtpc0luXT1cIiFkYXRhRmllbGQuZGlzYWJsZWRcIj48L25jLXJlcXVpcmVkLWxhYmVsPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0taW5wdXQgYnV0dG9uLWljb24taW5wdXQgZnVsbC13aWR0aFwiIGZ4TGF5b3V0PVwicm93XCIgZnhMYXlvdXRBbGlnbj1cInN0YXJ0IGNlbnRlclwiXG4gICAgICAgICAgICAgW25nQ2xhc3NdPVwieydmb3JtLWlucHV0LWRpc2FibGVkJzogZm9ybUNvbnRyb2xSZWYuZGlzYWJsZWQsICdmb3JtLWlucHV0LWVycm9yJzogZGF0YUZpZWxkLmlzSW52YWxpZChmb3JtQ29udHJvbFJlZil9XCJcbiAgICAgICAgICAgICBbbmdTdHlsZV09XCJ7XG4gICAgICAgICAgICAgICAgICAgICctd2Via2l0LWNsaXAtcGF0aCc6IGdldEN1dFByb3BlcnR5KGZpbGVMYWJlbCksXG4gICAgICAgICAgICAgICAgICAgICdjbGlwLXBhdGgnOiBnZXRDdXRQcm9wZXJ0eShmaWxlTGFiZWwpXG4gICAgICAgICAgICB9XCI+XG4gICAgICAgICAgICA8YnV0dG9uIG1hdC1pY29uLWJ1dHRvbiBtYXRQcmVmaXhcbiAgICAgICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cImZvcm1Db250cm9sUmVmLmRpc2FibGVkXCJcbiAgICAgICAgICAgICAgICAgICAgY29sb3I9XCJwcmltYXJ5XCJcbiAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cImNob29zZUZpbGUoKVwiXG4gICAgICAgICAgICAgICAgICAgIFttYXRUb29sdGlwXT1cIidkYXRhRmllbGQuZmlsZS5jbGlja1RvVXBsb2FkJyB8IHRyYW5zbGF0ZVwiXG4gICAgICAgICAgICAgICAgICAgIFtjbGFzcy5kby1ub3QtY2xpY2tdPVwic3RhdGUudXBsb2FkaW5nXCI+XG4gICAgICAgICAgICAgICAgPG1hdC1pY29uPmZpbGVfdXBsb2FkPC9tYXQtaWNvbj5cbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgPHNwYW4gKGNsaWNrKT1cImlzRW1wdHkoKSA/IGNob29zZUZpbGUoKSA6IGRvd25sb2FkKClcIiBmeEZsZXhcbiAgICAgICAgICAgICAgICAgIFttYXRUb29sdGlwXT1cImlzRW1wdHkoKSA/ICcnIDogKCdkYXRhRmllbGQuZmlsZS5jbGlja1RvRG93bmxvYWQnIHwgdHJhbnNsYXRlIDoge2ZpbGVOYW1lOiBjb25zdHJ1Y3REaXNwbGF5TmFtZSgpfSlcIlxuICAgICAgICAgICAgICAgICAgY2xhc3M9XCJpbnB1dC1uYW1lLWVsbGlwc2lzXCJcbiAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cInsnaW5wdXQtcGxhY2Vob2xkZXInOiBpc0VtcHR5KCksICduby1jdXJzb3InOiBpc0VtcHR5KCkgJiYgZm9ybUNvbnRyb2xSZWYuZGlzYWJsZWR9XCI+e3tjb25zdHJ1Y3REaXNwbGF5TmFtZSgpfX08L3NwYW4+XG4gICAgICAgICAgICA8YnV0dG9uIChjbGljayk9XCJzaG93UHJldmlld0RpYWxvZygpXCIgW21hdFRvb2x0aXBdPVwiJ2RhdGFGaWVsZC5maWxlLmNsaWNrVG9EZWxldGUnIHwgdHJhbnNsYXRlXCIgbWF0LWljb24tYnV0dG9uXG4gICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiaXNGaWxlUHJldmlld0J1dHRvbiAmJiAhaXNFbXB0eSgpICYmIGlzRGlzcGxheWFibGVcIj5cbiAgICAgICAgICAgICAgICA8bWF0LWljb24gY29sb3I9XCJwcmltYXJ5XCI+c2VhcmNoPC9tYXQtaWNvbj5cbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgPGJ1dHRvbiAoY2xpY2spPVwiZGVsZXRlRmlsZSgpXCIgW21hdFRvb2x0aXBdPVwiJ2RhdGFGaWVsZC5maWxlLmNsaWNrVG9EZWxldGUnIHwgdHJhbnNsYXRlXCIgbWF0LWljb24tYnV0dG9uXG4gICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiIWlzRW1wdHkoKSAmJiAhZm9ybUNvbnRyb2xSZWYuZGlzYWJsZWRcIj5cbiAgICAgICAgICAgICAgICA8bWF0LWljb24gY29sb3I9XCJ3YXJuXCI+Y2xvc2U8L21hdC1pY29uPlxuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8bWF0LXByb2dyZXNzLWJhciAqbmdJZj1cInN0YXRlLnVwbG9hZGluZyB8fCBzdGF0ZS5kb3dubG9hZGluZ1wiIGNvbG9yPVwicHJpbWFyeVwiIFt2YWx1ZV09XCJzdGF0ZS5wcm9ncmVzc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFttb2RlXT1cInN0YXRlLnVwbG9hZGluZyA/ICdkZXRlcm1pbmF0ZScgOiAnaW5kZXRlcm1pbmF0ZSdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cIm1hcmdpbi1ib3R0b20tZGVmYXVsdFwiPjwvbWF0LXByb2dyZXNzLWJhcj5cbiAgICAgICAgPGlucHV0IHR5cGU9XCJmaWxlXCIgI2ZpbGVVcGxvYWRJbnB1dCBuYW1lPVwiZmlsZVVwbG9hZFwiIFttdWx0aXBsZV09XCJmYWxzZVwiXG4gICAgICAgICAgICAgICBhY2NlcHQ9XCJ7e2RhdGFGaWVsZC5hbGxvd1R5cGVzfX1cIiBjbGFzcz1cImludmlzaWJsZS1pbnB1dFwiPlxuICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBbZm9ybUNvbnRyb2xdPVwiZm9ybUNvbnRyb2xSZWZcIiBjbGFzcz1cImludmlzaWJsZS1pbnB1dFwiPlxuICAgICAgICA8bWF0LWhpbnQgY2xhc3M9XCJmaWxlLWhpbnQtZXJyb3JcIiBbbmdDbGFzc109XCJ7J21hdC1oaW50LWRpc2FibGVkJzogZm9ybUNvbnRyb2xSZWYuZGlzYWJsZWR9XCJcbiAgICAgICAgICAgICAgICAgICpuZ0lmPVwiIWRhdGFGaWVsZC5pc0ludmFsaWQoZm9ybUNvbnRyb2xSZWYpICYmIGhhc0hpbnQoKVwiPnt7ZGF0YUZpZWxkLmRlc2NyaXB0aW9ufX08L21hdC1oaW50PlxuICAgICAgICA8bWF0LWVycm9yIGNsYXNzPVwiZmlsZS1oaW50LWVycm9yXCJcbiAgICAgICAgICAgICAgICAgICAqbmdJZj1cImRhdGFGaWVsZC5pc0ludmFsaWQoZm9ybUNvbnRyb2xSZWYpXCI+e3snZGF0YUZpZWxkLnZhbGlkYXRpb25zLnJlcXVpcmVkJyB8IHRyYW5zbGF0ZX19PC9tYXQtZXJyb3I+XG4gICAgPC9kaXY+XG4gICAgPGRpdiAqbmdJZj1cImlzRmlsZVByZXZpZXdcIiBmeEZsZXg9XCI1XCI+PC9kaXY+XG4gICAgPGRpdiAqbmdJZj1cImlzRmlsZVByZXZpZXdcIiBmeEZsZXg9XCIyMFwiIGZ4TGF5b3V0PVwicm93XCIgZnhMYXlvdXRBbGlnbj1cImNlbnRlciBjZW50ZXJcIiAjaW1hZ2VEaXZcbiAgICAgICAgIChyZXNpemVkKT1cImNoYW5nZU1heFdpZHRoKCRldmVudClcIj5cbiAgICAgICAgPGltZyAqbmdJZj1cInByZXZpZXdTb3VyY2UgIT09IHVuZGVmaW5lZCAmJiAhc3RhdGUuZG93bmxvYWRpbmcgJiYgaXNEaXNwbGF5YWJsZVwiIGNsYXNzPVwiaW1hZ2UtcHJldmlld1wiICNpbWFnZUVsXG4gICAgICAgICAgICAgW25nU3R5bGVdPVwiIWlzQm9yZGVyTEdCVFEoKSAmJiAhaXNCb3JkZXJEZWZhdWx0KCkgJiYge1xuICAgICAgICAgICAgICAgICAgICAnYm9yZGVyLXdpZHRoJzogZ2V0UHJldmlld0JvcmRlcldpZHRoKCksXG4gICAgICAgICAgICAgICAgICAgICdib3JkZXItc3R5bGUnOiBnZXRQcmV2aWV3Qm9yZGVyU3R5bGUoKSxcbiAgICAgICAgICAgICAgICAgICAgJ2JvcmRlci1jb2xvcic6IGdldFByZXZpZXdCb3JkZXJDb2xvcigpXG4gICAgICAgICAgICAgICAgIH1cIlxuICAgICAgICAgICAgIFtuZ0NsYXNzXT1cInsnYm9yZGVyLUxHQlRRJzogaXNCb3JkZXJMR0JUUSgpLCAnYm9yZGVyLWRlZmF1bHQnOiBpc0JvcmRlckRlZmF1bHQoKX1cIlxuICAgICAgICAgICAgIFtzcmNdPVwicHJldmlld1NvdXJjZVwiIGFsdD1cIkltYWdlIHByZXZpZXdcIiAoY2xpY2spPVwic2hvd1ByZXZpZXdEaWFsb2coKVwiLz5cbiAgICAgICAgPG1hdC1zcGlubmVyICpuZ0lmPVwicHJldmlld1NvdXJjZSA9PT0gdW5kZWZpbmVkICYmICEhc3RhdGUuZG93bmxvYWRpbmcgJiYgaXNEaXNwbGF5YWJsZVwiXG4gICAgICAgICAgICAgICAgICAgICBbZGlhbWV0ZXJdPVwiMjZcIj48L21hdC1zcGlubmVyPlxuICAgIDwvZGl2PlxuPC9kaXY+XG4iXX0=