@c8y/ngx-components 1020.26.0 → 1020.26.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,7 +7,7 @@ import { ControlContainer, FormBuilder, NgForm, ReactiveFormsModule, Validators
7
7
  import { BehaviorSubject, merge, Subject } from 'rxjs';
8
8
  import { distinctUntilChanged, filter, map, shareReplay, switchMap, takeUntil, tap } from 'rxjs/operators';
9
9
  import { ImageWidgetService } from '../image-widget.service';
10
- import { AsyncPipe } from '@angular/common';
10
+ import { AsyncPipe, NgClass, NgForOf, NgIf, NgStyle } from '@angular/common';
11
11
  import * as i0 from "@angular/core";
12
12
  import * as i1 from "@angular/forms";
13
13
  import * as i2 from "@c8y/ngx-components";
@@ -125,7 +125,7 @@ export class ImageWidgetConfigComponent {
125
125
  this.styling = this.imageWidget.getStyling(config);
126
126
  }
127
127
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: ImageWidgetConfigComponent, deps: [{ token: i1.FormBuilder }, { token: i1.NgForm }, { token: i2.FilesService }, { token: i2.AlertService }, { token: i3.ImageWidgetService }, { token: i4.WidgetConfigComponent, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
128
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.9", type: ImageWidgetConfigComponent, isStandalone: true, selector: "c8y-image-widget-config", inputs: { config: "config" }, ngImport: i0, template: "<div class=\"p-l-24 p-r-24\">\n <div [formGroup]=\"formGroup\" class=\"row p-t-8\">\n <div class=\"col-md-12\">\n <c8y-form-group>\n <label>{{ 'Image' | translate }}</label>\n <c8y-drop-area\n formControlName=\"images\"\n class=\"drop-area-sm\"\n [icon]=\"'upload'\"\n [accept]=\"'image'\"\n [maxAllowedFiles]=\"1\"\n ></c8y-drop-area>\n <c8y-messages>\n <c8y-message\n name=\"maxFileSizeReached\"\n [text]=\"\n 'The maximum image size is {{ maxFileSize }} kB. The selected image has a size of {{ actualFileSize }} kB.'\n | translate\n \"\n ></c8y-message>\n <c8y-message\n name=\"wrongFileType\"\n [text]=\"'Wrong file type, select an image.' | translate\"\n ></c8y-message>\n <c8y-message name=\"maxlength\" [text]=\"'Only select one image.' | translate\"></c8y-message>\n <c8y-message name=\"required\" [text]=\"'An image is required.' | translate\"></c8y-message>\n <c8y-message name=\"minlength\" [text]=\"'An image is required.' | translate\"></c8y-message>\n </c8y-messages>\n </c8y-form-group>\n </div>\n <ng-container *ngIf=\"imageSrc$ | async as src\">\n <div class=\"col-md-6\">\n <div class=\"legend form-block\">\n {{ 'Size and alignment' | translate }}\n </div>\n <div [formGroupName]=\"'styling'\">\n <c8y-form-group>\n <label>\n {{ 'Image display' | translate }}\n </label>\n <ul class=\"list-group separator-top-bottom\">\n <li\n class=\"list-group-item d-flex a-i-center p-l-0\"\n *ngFor=\"let objectFitOption of objectFitOptions; let i = index\"\n >\n <label class=\"c8y-radio\">\n <input\n type=\"radio\"\n [id]=\"'groupradiocontentclass' + i\"\n formControlName=\"objectFit\"\n [value]=\"objectFitOption.value\"\n />\n <span></span>\n <span class=\"l-h-1\">\n {{ objectFitOption.label | translate }}\n <br />\n <small class=\"text-muted\">\n {{ objectFitOption.description | translate }}\n </small>\n </span>\n </label>\n </li>\n </ul>\n </c8y-form-group>\n <div class=\"row\">\n <div class=\"col-md-6\">\n <c8y-form-group>\n <label>{{ 'Horizontal alignment' | translate }}</label>\n <div class=\"c8y-select-wrapper\">\n <select class=\"form-control\" formControlName=\"objectPositionX\">\n <option [ngValue]=\"'left'\">\n {{ 'left`horizontal alignment`' | translate }}\n </option>\n <option [ngValue]=\"'center'\">\n {{ 'center`horizontal alignment`' | translate }}\n </option>\n <option [ngValue]=\"'right'\">\n {{ 'right`horizontal alignment`' | translate }}\n </option>\n </select>\n </div>\n </c8y-form-group>\n </div>\n <div class=\"col-md-6\">\n <c8y-form-group>\n <label>{{ 'Vertical alignment' | translate }}</label>\n <div class=\"c8y-select-wrapper\">\n <select class=\"form-control\" formControlName=\"objectPositionY\">\n <option [ngValue]=\"'top'\">\n {{ 'top`vertical alignment`' | translate }}\n </option>\n <option [ngValue]=\"'center'\">\n {{ 'center`vertical alignment`' | translate }}\n </option>\n <option [ngValue]=\"'bottom'\">\n {{ 'bottom`vertical alignment`' | translate }}\n </option>\n </select>\n </div>\n </c8y-form-group>\n </div>\n </div>\n </div>\n </div>\n <div class=\"col-md-6\">\n <div class=\"legend form-block\">{{ 'Preview' | translate }}</div>\n <div class=\"form-group\">\n <div\n class=\"border-top border-right border-bottom border-left inner-scroll\"\n style=\"height: 300px\"\n >\n <img\n [src]=\"src\"\n [ngClass]=\"styling ? 'fit-h fit-w' : 'img-responsive'\"\n [ngStyle]=\"styling\"\n />\n </div>\n </div>\n </div>\n </ng-container>\n <div class=\"col-md-12 d-flex j-c-center\" *ngIf=\"loading\">\n <c8y-loading></c8y-loading>\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.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: i1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1.RadioControlValueAccessor, selector: "input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "component", type: FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "component", type: MessagesComponent, selector: "c8y-messages", inputs: ["show", "defaults", "helpMessage"] }, { kind: "directive", type: MessageDirective, selector: "c8y-message", inputs: ["name", "text"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "component", type: DropAreaComponent, selector: "c8y-drop-area", inputs: ["formControl", "title", "message", "icon", "loadingMessage", "forceHideList", "alwaysShow", "clickToOpen", "loading", "progress", "maxAllowedFiles", "files", "maxFileSizeInMegaBytes", "accept"], outputs: ["dropped"] }], viewProviders: [{ provide: ControlContainer, useExisting: NgForm }] }); }
128
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.9", type: ImageWidgetConfigComponent, isStandalone: true, selector: "c8y-image-widget-config", inputs: { config: "config" }, ngImport: i0, template: "<div class=\"p-l-24 p-r-24\">\n <div [formGroup]=\"formGroup\" class=\"row p-t-8\">\n <div class=\"col-md-12\">\n <c8y-form-group>\n <label>{{ 'Image' | translate }}</label>\n <c8y-drop-area\n formControlName=\"images\"\n class=\"drop-area-sm\"\n [icon]=\"'upload'\"\n [accept]=\"'image'\"\n [maxAllowedFiles]=\"1\"\n ></c8y-drop-area>\n <c8y-messages>\n <c8y-message\n name=\"maxFileSizeReached\"\n [text]=\"\n 'The maximum image size is {{ maxFileSize }} kB. The selected image has a size of {{ actualFileSize }} kB.'\n | translate\n \"\n ></c8y-message>\n <c8y-message\n name=\"wrongFileType\"\n [text]=\"'Wrong file type, select an image.' | translate\"\n ></c8y-message>\n <c8y-message name=\"maxlength\" [text]=\"'Only select one image.' | translate\"></c8y-message>\n <c8y-message name=\"required\" [text]=\"'An image is required.' | translate\"></c8y-message>\n <c8y-message name=\"minlength\" [text]=\"'An image is required.' | translate\"></c8y-message>\n </c8y-messages>\n </c8y-form-group>\n </div>\n <ng-container *ngIf=\"imageSrc$ | async as src\">\n <div class=\"col-md-6\">\n <div class=\"legend form-block\">\n {{ 'Size and alignment' | translate }}\n </div>\n <div [formGroupName]=\"'styling'\">\n <c8y-form-group>\n <label>\n {{ 'Image display' | translate }}\n </label>\n <ul class=\"list-group separator-top-bottom\">\n <li\n class=\"list-group-item d-flex a-i-center p-l-0\"\n *ngFor=\"let objectFitOption of objectFitOptions; let i = index\"\n >\n <label class=\"c8y-radio\">\n <input\n type=\"radio\"\n [id]=\"'groupradiocontentclass' + i\"\n formControlName=\"objectFit\"\n [value]=\"objectFitOption.value\"\n />\n <span></span>\n <span class=\"l-h-1\">\n {{ objectFitOption.label | translate }}\n <br />\n <small class=\"text-muted\">\n {{ objectFitOption.description | translate }}\n </small>\n </span>\n </label>\n </li>\n </ul>\n </c8y-form-group>\n <div class=\"row\">\n <div class=\"col-md-6\">\n <c8y-form-group>\n <label>{{ 'Horizontal alignment' | translate }}</label>\n <div class=\"c8y-select-wrapper\">\n <select class=\"form-control\" formControlName=\"objectPositionX\">\n <option [ngValue]=\"'left'\">\n {{ 'left`horizontal alignment`' | translate }}\n </option>\n <option [ngValue]=\"'center'\">\n {{ 'center`horizontal alignment`' | translate }}\n </option>\n <option [ngValue]=\"'right'\">\n {{ 'right`horizontal alignment`' | translate }}\n </option>\n </select>\n </div>\n </c8y-form-group>\n </div>\n <div class=\"col-md-6\">\n <c8y-form-group>\n <label>{{ 'Vertical alignment' | translate }}</label>\n <div class=\"c8y-select-wrapper\">\n <select class=\"form-control\" formControlName=\"objectPositionY\">\n <option [ngValue]=\"'top'\">\n {{ 'top`vertical alignment`' | translate }}\n </option>\n <option [ngValue]=\"'center'\">\n {{ 'center`vertical alignment`' | translate }}\n </option>\n <option [ngValue]=\"'bottom'\">\n {{ 'bottom`vertical alignment`' | translate }}\n </option>\n </select>\n </div>\n </c8y-form-group>\n </div>\n </div>\n </div>\n </div>\n <div class=\"col-md-6\">\n <div class=\"legend form-block\">{{ 'Preview' | translate }}</div>\n <div class=\"form-group\">\n <div\n class=\"border-top border-right border-bottom border-left inner-scroll\"\n style=\"height: 300px\"\n >\n <img\n [src]=\"src\"\n [ngClass]=\"styling ? 'fit-h fit-w' : 'img-responsive'\"\n [ngStyle]=\"styling\"\n />\n </div>\n </div>\n </div>\n </ng-container>\n <div class=\"col-md-12 d-flex j-c-center\" *ngIf=\"loading\">\n <c8y-loading></c8y-loading>\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.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: i1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1.RadioControlValueAccessor, selector: "input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "component", type: FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "component", type: MessagesComponent, selector: "c8y-messages", inputs: ["show", "defaults", "helpMessage"] }, { kind: "directive", type: MessageDirective, selector: "c8y-message", inputs: ["name", "text"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: DropAreaComponent, selector: "c8y-drop-area", inputs: ["formControl", "title", "message", "icon", "loadingMessage", "forceHideList", "alwaysShow", "clickToOpen", "loading", "progress", "maxAllowedFiles", "files", "maxFileSizeInMegaBytes", "accept"], outputs: ["dropped"] }], viewProviders: [{ provide: ControlContainer, useExisting: NgForm }] }); }
129
129
  }
130
130
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: ImageWidgetConfigComponent, decorators: [{
131
131
  type: Component,
@@ -136,6 +136,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImpor
136
136
  MessageDirective,
137
137
  C8yTranslatePipe,
138
138
  AsyncPipe,
139
+ NgIf,
140
+ NgStyle,
141
+ NgClass,
142
+ NgForOf,
139
143
  DropAreaComponent
140
144
  ], template: "<div class=\"p-l-24 p-r-24\">\n <div [formGroup]=\"formGroup\" class=\"row p-t-8\">\n <div class=\"col-md-12\">\n <c8y-form-group>\n <label>{{ 'Image' | translate }}</label>\n <c8y-drop-area\n formControlName=\"images\"\n class=\"drop-area-sm\"\n [icon]=\"'upload'\"\n [accept]=\"'image'\"\n [maxAllowedFiles]=\"1\"\n ></c8y-drop-area>\n <c8y-messages>\n <c8y-message\n name=\"maxFileSizeReached\"\n [text]=\"\n 'The maximum image size is {{ maxFileSize }} kB. The selected image has a size of {{ actualFileSize }} kB.'\n | translate\n \"\n ></c8y-message>\n <c8y-message\n name=\"wrongFileType\"\n [text]=\"'Wrong file type, select an image.' | translate\"\n ></c8y-message>\n <c8y-message name=\"maxlength\" [text]=\"'Only select one image.' | translate\"></c8y-message>\n <c8y-message name=\"required\" [text]=\"'An image is required.' | translate\"></c8y-message>\n <c8y-message name=\"minlength\" [text]=\"'An image is required.' | translate\"></c8y-message>\n </c8y-messages>\n </c8y-form-group>\n </div>\n <ng-container *ngIf=\"imageSrc$ | async as src\">\n <div class=\"col-md-6\">\n <div class=\"legend form-block\">\n {{ 'Size and alignment' | translate }}\n </div>\n <div [formGroupName]=\"'styling'\">\n <c8y-form-group>\n <label>\n {{ 'Image display' | translate }}\n </label>\n <ul class=\"list-group separator-top-bottom\">\n <li\n class=\"list-group-item d-flex a-i-center p-l-0\"\n *ngFor=\"let objectFitOption of objectFitOptions; let i = index\"\n >\n <label class=\"c8y-radio\">\n <input\n type=\"radio\"\n [id]=\"'groupradiocontentclass' + i\"\n formControlName=\"objectFit\"\n [value]=\"objectFitOption.value\"\n />\n <span></span>\n <span class=\"l-h-1\">\n {{ objectFitOption.label | translate }}\n <br />\n <small class=\"text-muted\">\n {{ objectFitOption.description | translate }}\n </small>\n </span>\n </label>\n </li>\n </ul>\n </c8y-form-group>\n <div class=\"row\">\n <div class=\"col-md-6\">\n <c8y-form-group>\n <label>{{ 'Horizontal alignment' | translate }}</label>\n <div class=\"c8y-select-wrapper\">\n <select class=\"form-control\" formControlName=\"objectPositionX\">\n <option [ngValue]=\"'left'\">\n {{ 'left`horizontal alignment`' | translate }}\n </option>\n <option [ngValue]=\"'center'\">\n {{ 'center`horizontal alignment`' | translate }}\n </option>\n <option [ngValue]=\"'right'\">\n {{ 'right`horizontal alignment`' | translate }}\n </option>\n </select>\n </div>\n </c8y-form-group>\n </div>\n <div class=\"col-md-6\">\n <c8y-form-group>\n <label>{{ 'Vertical alignment' | translate }}</label>\n <div class=\"c8y-select-wrapper\">\n <select class=\"form-control\" formControlName=\"objectPositionY\">\n <option [ngValue]=\"'top'\">\n {{ 'top`vertical alignment`' | translate }}\n </option>\n <option [ngValue]=\"'center'\">\n {{ 'center`vertical alignment`' | translate }}\n </option>\n <option [ngValue]=\"'bottom'\">\n {{ 'bottom`vertical alignment`' | translate }}\n </option>\n </select>\n </div>\n </c8y-form-group>\n </div>\n </div>\n </div>\n </div>\n <div class=\"col-md-6\">\n <div class=\"legend form-block\">{{ 'Preview' | translate }}</div>\n <div class=\"form-group\">\n <div\n class=\"border-top border-right border-bottom border-left inner-scroll\"\n style=\"height: 300px\"\n >\n <img\n [src]=\"src\"\n [ngClass]=\"styling ? 'fit-h fit-w' : 'img-responsive'\"\n [ngStyle]=\"styling\"\n />\n </div>\n </div>\n </div>\n </ng-container>\n <div class=\"col-md-12 d-flex j-c-center\" *ngIf=\"loading\">\n <c8y-loading></c8y-loading>\n </div>\n </div>\n</div>\n" }]
141
145
  }], ctorParameters: () => [{ type: i1.FormBuilder }, { type: i1.NgForm }, { type: i2.FilesService }, { type: i2.AlertService }, { type: i3.ImageWidgetService }, { type: i4.WidgetConfigComponent, decorators: [{
@@ -143,4 +147,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImpor
143
147
  }] }], propDecorators: { config: [{
144
148
  type: Input
145
149
  }] } });
146
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW1hZ2Utd2lkZ2V0LWNvbmZpZy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi93aWRnZXRzL2ltcGxlbWVudGF0aW9ucy9pbWFnZS9pbWFnZS13aWRnZXQtY29uZmlnL2ltYWdlLXdpZGdldC1jb25maWcuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vd2lkZ2V0cy9pbXBsZW1lbnRhdGlvbnMvaW1hZ2UvaW1hZ2Utd2lkZ2V0LWNvbmZpZy9pbWFnZS13aWRnZXQtY29uZmlnLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFxQixRQUFRLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDOUUsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sdUNBQXVDLENBQUM7QUFDOUUsT0FBTyxFQUNMLGFBQWEsRUFFYixZQUFZLEVBQ1osWUFBWSxFQUNaLE9BQU8sRUFDUCxrQkFBa0IsRUFDbEIsaUJBQWlCLEVBQ2pCLGdCQUFnQixFQUNoQixnQkFBZ0IsRUFDaEIsaUJBQWlCLEVBQ2xCLE1BQU0scUJBQXFCLENBQUM7QUFDN0IsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUNoQyxPQUFPLEVBQ0wscUJBQXFCLEVBQ3JCLDBCQUEwQixFQUkzQixNQUFNLHVCQUF1QixDQUFDO0FBQy9CLE9BQU8sRUFDTCxnQkFBZ0IsRUFDaEIsV0FBVyxFQUVYLE1BQU0sRUFDTixtQkFBbUIsRUFDbkIsVUFBVSxFQUNYLE1BQU0sZ0JBQWdCLENBQUM7QUFDeEIsT0FBTyxFQUFFLGVBQWUsRUFBYyxLQUFLLEVBQUUsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ25FLE9BQU8sRUFDTCxvQkFBb0IsRUFDcEIsTUFBTSxFQUNOLEdBQUcsRUFDSCxXQUFXLEVBQ1gsU0FBUyxFQUNULFNBQVMsRUFDVCxHQUFHLEVBQ0osTUFB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VSwwQkFBMEI7a0dBQTFCLDBCQUEwQixpSEMxRHZDLHk2SkE2SEEsMkNENUVJLG1CQUFtQix5akRBQ25CLGtCQUFrQix1SUFDbEIsaUJBQWlCLHNHQUNqQixnQkFBZ0IsNkVBQ2hCLGdCQUFnQiw2Q0FDaEIsU0FBUyw4Q0FDVCxpQkFBaUIsaVJBVEosQ0FBQyxFQUFFLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxXQUFXLEVBQUUsTUFBTSxFQUFFLENBQUM7OzJGQVl4RCwwQkFBMEI7a0JBZnRDLFNBQVM7K0JBQ0UseUJBQXlCLGlCQUVwQixDQUFDLEVBQUUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLFdBQVcsRUFBRSxNQUFNLEVBQUUsQ0FBQyxjQUN2RCxJQUFJLFdBQ1A7d0JBQ1AsbUJBQW1CO3dCQUNuQixrQkFBa0I7d0JBQ2xCLGlCQUFpQjt3QkFDakIsZ0JBQWdCO3dCQUNoQixnQkFBZ0I7d0JBQ2hCLFNBQVM7d0JBQ1QsaUJBQWlCO3FCQUNsQjs7MEJBZ0RFLFFBQVE7eUNBN0NGLE1BQU07c0JBQWQsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgSW5wdXQsIE9uRGVzdHJveSwgT25Jbml0LCBPcHRpb25hbCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgV2lkZ2V0Q29uZmlnQ29tcG9uZW50IH0gZnJvbSAnQGM4eS9uZ3gtY29tcG9uZW50cy9jb250ZXh0LWRhc2hib2FyZCc7XG5pbXBvcnQge1xuICBDOHlWYWxpZGF0b3JzLFxuICBPbkJlZm9yZVNhdmUsXG4gIEZpbGVzU2VydmljZSxcbiAgQWxlcnRTZXJ2aWNlLFxuICBnZXR0ZXh0LFxuICBGb3JtR3JvdXBDb21wb25lbnQsXG4gIE1lc3NhZ2VzQ29tcG9uZW50LFxuICBNZXNzYWdlRGlyZWN0aXZlLFxuICBDOHlUcmFuc2xhdGVQaXBlLFxuICBEcm9wQXJlYUNvbXBvbmVudFxufSBmcm9tICdAYzh5L25neC1jb21wb25lbnRzJztcbmltcG9ydCB7IGdldCB9IGZyb20gJ2xvZGFzaC1lcyc7XG5pbXBvcnQge1xuICBkZWZhdWx0T2JqZWN0Rml0VmFsdWUsXG4gIGRlZmF1bHRPYmplY3RQb3NpdGlvblZhbHVlLFxuICBJbWFnZVdpZGdldENvbmZpZyxcbiAgSW1hZ2VXaWRnZXRDb25maWdTdHlsaW5nLFxuICBJbWFnZVdpZGdldFN0eWxlXG59IGZyb20gJy4uL2ltYWdlLXdpZGdldC5tb2RlbCc7XG5pbXBvcnQge1xuICBDb250cm9sQ29udGFpbmVyLFxuICBGb3JtQnVpbGRlcixcbiAgRm9ybUdyb3VwLFxuICBOZ0Zvcm0sXG4gIFJlYWN0aXZlRm9ybXNNb2R1bGUsXG4gIFZhbGlkYXRvcnNcbn0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgQmVoYXZpb3JTdWJqZWN0LCBPYnNlcnZhYmxlLCBtZXJnZSwgU3ViamVjdCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHtcbiAgZGlzdGluY3RVbnRpbENoYW5nZWQsXG4gIGZpbHRlcixcbiAgbWFwLFxuICBzaGFyZVJlcGxheSxcbiAgc3dpdGNoTWFwLFxuICB0YWtlVW50aWwsXG4gIHRhcFxufSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBJbWFnZVdpZGdldFNlcnZpY2UgfSBmcm9tICcuLi9pbWFnZS13aWRnZXQuc2VydmljZSc7XG5pbXBvcnQgeyBBc3luY1BpcGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdjOHktaW1hZ2Utd2lkZ2V0LWNvbmZpZycsXG4gIHRlbXBsYXRlVXJsOiAnLi9pbWFnZS13aWRnZXQtY29uZmlnLmNvbXBvbmVudC5odG1sJyxcbiAgdmlld1Byb3ZpZGVyczogW3sgcHJvdmlkZTogQ29udHJvbENvbnRhaW5lciwgdXNlRXhpc3Rpbmc6IE5nRm9ybSB9XSxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW1xuICAgIFJlYWN0aXZlRm9ybXNNb2R1bGUsXG4gICAgRm9ybUdyb3VwQ29tcG9uZW50LFxuICAgIE1lc3NhZ2VzQ29tcG9uZW50LFxuICAgIE1lc3NhZ2VEaXJlY3RpdmUsXG4gICAgQzh5VHJhbnNsYXRlUGlwZSxcbiAgICBBc3luY1BpcGUsXG4gICAgRHJvcEFyZWFDb21wb25lbnRcbiAgXVxufSlcbmV4cG9ydCBjbGFzcyBJbWFnZVdpZGdldENvbmZpZ0NvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95LCBPbkJlZm9yZVNhdmUge1xuICBASW5wdXQoKSBjb25maWc6IEltYWdlV2lkZ2V0Q29uZmlnO1xuICBpbWFnZUJpbmFyeUlkJCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8c3RyaW5nPihudWxsKTtcbiAgaW1hZ2VTcmMkOiBPYnNlcnZhYmxlPHN0cmluZz47XG4gIGxvYWRpbmcgPSBmYWxzZTtcbiAgZm9ybUdyb3VwOiBGb3JtR3JvdXA7XG4gIGZpbGVGcm9tQ29uZmlnOiBGaWxlO1xuICBzdHlsaW5nOiBJbWFnZVdpZGdldFN0eWxlIHwgbnVsbDtcbiAgZGVzdHJveWVkJCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG4gIG9iamVjdEZpdE9wdGlvbnMgPSBbXG4gICAge1xuICAgICAgbGFiZWw6IGdldHRleHQoJ0NvbnRhaW5gdmVyYiwgaW1hZ2UgZml0dGluZyBvcHRpb25gJyksXG4gICAgICB2YWx1ZTogJ2NvbnRhaW4nLFxuICAgICAgZGVzY3JpcHRpb246IGdldHRleHQoXG4gICAgICAgICdUaGUgaW1hZ2UgaXMgZW50aXJlbHkgZGlzcGxheWVkIHdpdGhpbiB0aGUgd2lkZ2V0IHdoaWxlIHByZXNlcnZpbmcgdGhlIGFzcGVjdCByYXRpby4nXG4gICAgICApXG4gICAgfSxcbiAgICB7XG4gICAgICBsYWJlbDogZ2V0dGV4dCgnQ292ZXJgdmVyYiwgaW1hZ2UgZml0dGluZyBvcHRpb25gJyksXG4gICAgICB2YWx1ZTogJ2NvdmVyJyxcbiAgICAgIGRlc2NyaXB0aW9uOiBnZXR0ZXh0KFxuICAgICAgICAnVGhlIGltYWdlIGlzIHJlc2l6ZWQgdG8gZmlsbCB0aGUgd2lkZ2V0IHdoaWxlIHByZXNlcnZpbmcgdGhlIGFzcGVjdCByYXRpby4gT3ZlcmZsb3dpbmcgYXJlYXMgYXJlIGNsaXBwZWQuJ1xuICAgICAgKVxuICAgIH0sXG4gICAge1xuICAgICAgbGFiZWw6IGdldHRleHQoJ0ZpbGxgdmVyYiwgaW1hZ2UgZml0dGluZyBvcHRpb25gJyksXG4gICAgICB2YWx1ZTogJ2ZpbGwnLFxuICAgICAgZGVzY3JpcHRpb246IGdldHRleHQoXG4gICAgICAgICdUaGUgaW1hZ2UgaXMgc3RyZXRjaGVkIHRvIGZpbGwgdGhlIHdpZGdldCwgb3ZlcnJpZGluZyB0aGUgYXNwZWN0LXJhdGlvLidcbiAgICAgIClcbiAgICB9LFxuICAgIHtcbiAgICAgIGxhYmVsOiBnZXR0ZXh0KCdGdWxsIHdpZHRoYGltYWdlIGZpdHRpbmcgb3B0aW9uYCcpLFxuICAgICAgdmFsdWU6ICdmdWxsLXdpZHRoJyxcbiAgICAgIGRlc2NyaXB0aW9uOiBnZXR0ZXh0KFxuICAgICAgICBgVGhlIGltYWdlIGlzIHJlc2l6ZWQgdG8gZml0IHRoZSB3aWRnZXQncyB3aWR0aCB3aGlsZSBwcmVzZXJ2aW5nIHRoZSBhc3BlY3QgcmF0aW8uIE92ZXJmbG93aW5nIGFyZWEgaXMgc2Nyb2xsYWJsZS5gXG4gICAgICApXG4gICAgfVxuICBdO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgZm9ybUJ1aWxkZXI6IEZvcm1CdWlsZGVyLFxuICAgIHByaXZhdGUgZm9ybTogTmdGb3JtLFxuICAgIHByaXZhdGUgZmlsZVNlcnZpY2U6IEZpbGVzU2VydmljZSxcbiAgICBwcml2YXRlIGFsZXJ0OiBBbGVydFNlcnZpY2UsXG4gICAgcHJpdmF0ZSBpbWFnZVdpZGdldDogSW1hZ2VXaWRnZXRTZXJ2aWNlLFxuICAgIEBPcHRpb25hbCgpIHByaXZhdGUgd2lkZ2V0Q29uZmlnOiBXaWRnZXRDb25maWdDb21wb25lbnRcbiAgKSB7fVxuXG4gIGFzeW5jIG9uQmVmb3JlU2F2ZShjb25maWc/OiBJbWFnZVdpZGdldENvbmZpZyk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGlmICh0aGlzLmZvcm1Hcm91cC5pbnZhbGlkKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgY29uc3QgZmlsZUZyb21Gb3JtID0gdGhpcy5nZXRGaWxlRnJvbUZvcm1WYWx1ZSh0aGlzLmZvcm1Hcm91cC52YWx1ZSk7XG4gICAgaWYgKGZpbGVGcm9tRm9ybSAmJiBmaWxlRnJvbUZvcm0gIT09IHRoaXMuZmlsZUZyb21Db25maWcpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IGltYWdlQmluYXJ5SWQgPSBhd2FpdCB0aGlzLmltYWdlV2lkZ2V0LnVwbG9hZEZpbGUoZmlsZUZyb21Gb3JtLCB7XG4gICAgICAgICAgZGFzaGJvYXJkTW9JZDogdGhpcy5nZXREYXNoYm9hcmRNb0lkKCksXG4gICAgICAgICAgaXNEZXZpY2VUeXBlRGFzaGJvYXJkOiB0aGlzLndpZGdldENvbmZpZz8uaXNEZXZpY2VUeXBlRGFzaGJvYXJkXG4gICAgICAgIH0pO1xuICAgICAgICBPYmplY3QuYXNzaWduKGNvbmZpZywgeyBpbWFnZUJpbmFyeUlkIH0pO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICB0aGlzLmFsZXJ0LmRhbmdlcihnZXR0ZXh0KCdVbmFibGUgdG8gdXBsb2FkIGltYWdlLicpLCBlPy5kYXRhKTtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgICBjb25zdCBzdHlsaW5nOiBJbWFnZVdpZGdldENvbmZpZ1N0eWxpbmcgPSB0aGlzLmZvcm1Hcm91cC52YWx1ZS5zdHlsaW5nO1xuICAgIE9iamVjdC5hc3NpZ24oY29uZmlnLCB7IHN0eWxpbmcgfSk7XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIG5nT25Jbml0KCkge1xuICAgIHRoaXMuaW5pdEZvcm0oKTtcbiAgICBjb25zdCBpbWFnZUZyb21Db25maWcgPSB0aGlzLmltYWdlQmluYXJ5SWQkLnBpcGUoXG4gICAgICBmaWx0ZXIoaWQgPT4gISFpZCksXG4gICAgICBkaXN0aW5jdFVudGlsQ2hhbmdlZCgpLFxuICAgICAgdGFwKCgpID0+ICh0aGlzLmxvYWRpbmcgPSB0cnVlKSksXG4gICAgICBzd2l0Y2hNYXAoaW1hZ2VCaW5hcnlJZCA9PiB0aGlzLmltYWdlV2lkZ2V0LmdldEltYWdlRGV0YWlscyhpbWFnZUJpbmFyeUlkKSksXG4gICAgICB0YXAoZGV0YWlscyA9PiB7XG4gICAgICAgIHRoaXMubG9hZGluZyA9IGZhbHNlO1xuICAgICAgICB0aGlzLmZpbGVGcm9tQ29uZmlnID0gZGV0YWlscy5maWxlO1xuICAgICAgICBpZiAoZGV0YWlscykge1xuICAgICAgICAgIHRoaXMuZm9ybUdyb3VwLnBhdGNoVmFsdWUoeyBpbWFnZXM6IFt7IGZpbGU6IGRldGFpbHMuZmlsZSwgbmFtZTogZGV0YWlscy5maWxlLm5hbWUgfV0gfSk7XG4gICAgICAgIH1cbiAgICAgIH0pLFxuICAgICAgbWFwKGRldGFpbHMgPT4gZGV0YWlscz8uYmFzZTY0KSxcbiAgICAgIHNoYXJlUmVwbGF5KDEpXG4gICAgKTtcbiAgICBjb25zdCBzZWxlY3RlZEZpbGUgPSB0aGlzLmZvcm1Hcm91cC52YWx1ZUNoYW5nZXMucGlwZShcbiAgICAgIG1hcCh2YWx1ZSA9PiB0aGlzLmdldEZpbGVGcm9tRm9ybVZhbHVlKHZhbHVlKSksXG4gICAgICBkaXN0aW5jdFVudGlsQ2hhbmdlZCgpLFxuICAgICAgc3dpdGNoTWFwKGZpbGUgPT4gKGZpbGUgPyB0aGlzLmZpbGVTZXJ2aWNlLnRvQmFzZTY0KGZpbGUpIDogUHJvbWlzZS5yZXNvbHZlKCcnKSkpXG4gICAgKTtcbiAgICB0aGlzLmltYWdlU3JjJCA9IG1lcmdlKGltYWdlRnJvbUNvbmZpZywgc2VsZWN0ZWRGaWxlKS5waXBlKFxuICAgICAgbWFwKGJhc2U2NCA9PiAoYmFzZTY0ID8gKGJhc2U2NCBhcyBzdHJpbmcpIDogJycpKVxuICAgICk7XG4gICAgdGhpcy5pbWFnZUJpbmFyeUlkJC5uZXh0KHRoaXMuY29uZmlnPy5pbWFnZUJpbmFyeUlkKTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMuZGVzdHJveWVkJC5uZXh0KCk7XG4gICAgdGhpcy5kZXN0cm95ZWQkLmNvbXBsZXRlKCk7XG4gIH1cblxuICBwcml2YXRlIGdldERhc2hib2FyZE1vSWQoKTogc3RyaW5nIHwgbnVsbCB7XG4gICAgcmV0dXJuIGdldCh0aGlzLndpZGdldENvbmZpZywgJ21vLmlkJywgbnVsbCk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGluaXRGb3JtKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHN0eWxpbmdGb3JtR3JvdXAgPSB0aGlzLmZvcm1CdWlsZGVyLmdyb3VwKHtcbiAgICAgIG9iamVjdEZpdDogW1xuICAgICAgICAvLyBmYWxsYmFjayB0byAnZnVsbC13aWR0aCcgZm9yIG9sZCBsZWdhY3kgd2lkZ2V0cywgbmV3bHkgY3JlYXRlZCB3aWRnZXRzIHNob3VsZCB1c2UgZGVmYXVsdE9iamVjdEZpdFZhbHVlXG4gICAgICAgIHRoaXMuY29uZmlnLmltYWdlQmluYXJ5SWQgJiYgIXRoaXMuY29uZmlnLnN0eWxpbmcgPyAnZnVsbC13aWR0aCcgOiBkZWZhdWx0T2JqZWN0Rml0VmFsdWUsXG4gICAgICAgIFtWYWxpZGF0b3JzLnJlcXVpcmVkXVxuICAgICAgXSxcbiAgICAgIG9iamVjdFBvc2l0aW9uWDogW2RlZmF1bHRPYmplY3RQb3NpdGlvblZhbHVlLCBbVmFsaWRhdG9ycy5yZXF1aXJlZF1dLFxuICAgICAgb2JqZWN0UG9zaXRpb25ZOiBbZGVmYXVsdE9iamVjdFBvc2l0aW9uVmFsdWUsIFtWYWxpZGF0b3JzLnJlcXVpcmVkXV1cbiAgICB9KTtcbiAgICB0aGlzLmZvcm1Hcm91cCA9IHRoaXMuZm9ybUJ1aWxkZXIuZ3JvdXAoe1xuICAgICAgaW1hZ2VzOiBbXG4gICAgICAgIG51bGwsXG4gICAgICAgIFtcbiAgICAgICAgICBWYWxpZGF0b3JzLnJlcXVpcmVkLFxuICAgICAgICAgIFZhbGlkYXRvcnMubWluTGVuZ3RoKDEpLFxuICAgICAgICAgIFZhbGlkYXRvcnMubWF4TGVuZ3RoKDEpLFxuICAgICAgICAgIEM4eVZhbGlkYXRvcnMuZmlsZXNWYWxpZGF0b3IoeyBtYXhpbXVtRmlsZVNpemVJbktiOiAxMDAwLCB0eXBlUHJlZml4OiAnaW1hZ2UvJyB9KVxuICAgICAgICBdXG4gICAgICBdLFxuICAgICAgc3R5bGluZzogc3R5bGluZ0Zvcm1Hcm91cFxuICAgIH0pO1xuICAgIHRoaXMuZm9ybS5mb3JtLmFkZENvbnRyb2woJ2NvbmZpZycsIHRoaXMuZm9ybUdyb3VwKTtcbiAgICB0aGlzLmZvcm1Hcm91cC5wYXRjaFZhbHVlKHRoaXMuY29uZmlnKTtcbiAgICB0aGlzLmZvcm1Hcm91cC52YWx1ZUNoYW5nZXNcbiAgICAgIC5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3llZCQpKVxuICAgICAgLnN1YnNjcmliZShjaGFuZ2VzID0+IHRoaXMuc2V0U3R5bGluZyhjaGFuZ2VzKSk7XG4gIH1cblxuICBwcml2YXRlIGdldEZpbGVGcm9tRm9ybVZhbHVlKGZvcm1WYWx1ZTogYW55KTogRmlsZSB8IG51bGwge1xuICAgIGNvbnN0IGltYWdlczogYW55W10gPSBmb3JtVmFsdWU/LmltYWdlcyB8fCBbXTtcbiAgICByZXR1cm4gaW1hZ2VzWzBdPy5maWxlIHx8IG51bGw7XG4gIH1cblxuICBwcml2YXRlIHNldFN0eWxpbmcoY29uZmlnOiBJbWFnZVdpZGdldENvbmZpZyk6IHZvaWQge1xuICAgIHRoaXMuc3R5bGluZyA9IHRoaXMuaW1hZ2VXaWRnZXQuZ2V0U3R5bGluZyhjb25maWcpO1xuICB9XG59XG4iLCI8ZGl2IGNsYXNzPVwicC1sLTI0IHAtci0yNFwiPlxuICA8ZGl2IFtmb3JtR3JvdXBdPVwiZm9ybUdyb3VwXCIgY2xhc3M9XCJyb3cgcC10LThcIj5cbiAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTEyXCI+XG4gICAgICA8Yzh5LWZvcm0tZ3JvdXA+XG4gICAgICAgIDxsYWJlbD57eyAnSW1hZ2UnIHwgdHJhbnNsYXRlIH19PC9sYWJlbD5cbiAgICAgICAgPGM4eS1kcm9wLWFyZWFcbiAgICAgICAgICBmb3JtQ29udHJvbE5hbWU9XCJpbWFnZXNcIlxuICAgICAgICAgIGNsYXNzPVwiZHJvcC1hcmVhLXNtXCJcbiAgICAgICAgICBbaWNvbl09XCIndXBsb2FkJ1wiXG4gICAgICAgICAgW2FjY2VwdF09XCInaW1hZ2UnXCJcbiAgICAgICAgICBbbWF4QWxsb3dlZEZpbGVzXT1cIjFcIlxuICAgICAgICA+PC9jOHktZHJvcC1hcmVhPlxuICAgICAgICA8Yzh5LW1lc3NhZ2VzPlxuICAgICAgICAgIDxjOHktbWVzc2FnZVxuICAgICAgICAgICAgbmFtZT1cIm1heEZpbGVTaXplUmVhY2hlZFwiXG4gICAgICAgICAgICBbdGV4dF09XCJcbiAgICAgICAgICAgICAgJ1RoZSBtYXhpbXVtIGltYWdlIHNpemUgaXMge3sgbWF4RmlsZVNpemUgfX0ga0IuIFRoZSBzZWxlY3RlZCBpbWFnZSBoYXMgYSBzaXplIG9mIHt7IGFjdHVhbEZpbGVTaXplIH19IGtCLidcbiAgICAgICAgICAgICAgICB8IHRyYW5zbGF0ZVxuICAgICAgICAgICAgXCJcbiAgICAgICAgICA+PC9jOHktbWVzc2FnZT5cbiAgICAgICAgICA8Yzh5LW1lc3NhZ2VcbiAgICAgICAgICAgIG5hbWU9XCJ3cm9uZ0ZpbGVUeXBlXCJcbiAgICAgICAgICAgIFt0ZXh0XT1cIidXcm9uZyBmaWxlIHR5cGUsIHNlbGVjdCBhbiBpbWFnZS4nIHwgdHJhbnNsYXRlXCJcbiAgICAgICAgICA+PC9jOHktbWVzc2FnZT5cbiAgICAgICAgICA8Yzh5LW1lc3NhZ2UgbmFtZT1cIm1heGxlbmd0aFwiIFt0ZXh0XT1cIidPbmx5IHNlbGVjdCBvbmUgaW1hZ2UuJyB8IHRyYW5zbGF0ZVwiPjwvYzh5LW1lc3NhZ2U+XG4gICAgICAgICAgPGM4eS1tZXNzYWdlIG5hbWU9XCJyZXF1aXJlZFwiIFt0ZXh0XT1cIidBbiBpbWFnZSBpcyByZXF1aXJlZC4nIHwgdHJhbnNsYXRlXCI+PC9jOHktbWVzc2FnZT5cbiAgICAgICAgICA8Yzh5LW1lc3NhZ2UgbmFtZT1cIm1pbmxlbmd0aFwiIFt0ZXh0XT1cIidBbiBpbWFnZSBpcyByZXF1aXJlZC4nIHwgdHJhbnNsYXRlXCI+PC9jOHktbWVzc2FnZT5cbiAgICAgICAgPC9jOHktbWVzc2FnZXM+XG4gICAgICA8L2M4eS1mb3JtLWdyb3VwPlxuICAgIDwvZGl2PlxuICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJpbWFnZVNyYyQgfCBhc3luYyBhcyBzcmNcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJjb2wtbWQtNlwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwibGVnZW5kIGZvcm0tYmxvY2tcIj5cbiAgICAgICAgICB7eyAnU2l6ZSBhbmQgYWxpZ25tZW50JyB8IHRyYW5zbGF0ZSB9fVxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBbZm9ybUdyb3VwTmFtZV09XCInc3R5bGluZydcIj5cbiAgICAgICAgICA8Yzh5LWZvcm0tZ3JvdXA+XG4gICAgICAgICAgICA8bGFiZWw+XG4gICAgICAgICAgICAgIHt7ICdJbWFnZSBkaXNwbGF5JyB8IHRyYW5zbGF0ZSB9fVxuICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgIDx1bCBjbGFzcz1cImxpc3QtZ3JvdXAgc2VwYXJhdG9yLXRvcC1ib3R0b21cIj5cbiAgICAgICAgICAgICAgPGxpXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJsaXN0LWdyb3VwLWl0ZW0gZC1mbGV4IGEtaS1jZW50ZXIgcC1sLTBcIlxuICAgICAgICAgICAgICAgICpuZ0Zvcj1cImxldCBvYmplY3RGaXRPcHRpb24gb2Ygb2JqZWN0Rml0T3B0aW9uczsgbGV0IGkgPSBpbmRleFwiXG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJjOHktcmFkaW9cIj5cbiAgICAgICAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICAgICAgICB0eXBlPVwicmFkaW9cIlxuICAgICAgICAgICAgICAgICAgICBbaWRdPVwiJ2dyb3VwcmFkaW9jb250ZW50Y2xhc3MnICsgaVwiXG4gICAgICAgICAgICAgICAgICAgIGZvcm1Db250cm9sTmFtZT1cIm9iamVjdEZpdFwiXG4gICAgICAgICAgICAgICAgICAgIFt2YWx1ZV09XCJvYmplY3RGaXRPcHRpb24udmFsdWVcIlxuICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICAgIDxzcGFuPjwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibC1oLTFcIj5cbiAgICAgICAgICAgICAgICAgICAge3sgb2JqZWN0Rml0T3B0aW9uLmxhYmVsIHwgdHJhbnNsYXRlIH19XG4gICAgICAgICAgICAgICAgICAgIDxiciAvPlxuICAgICAgICAgICAgICAgICAgICA8c21hbGwgY2xhc3M9XCJ0ZXh0LW11dGVkXCI+XG4gICAgICAgICAgICAgICAgICAgICAge3sgb2JqZWN0Rml0T3B0aW9uLmRlc2NyaXB0aW9uIHwgdHJhbnNsYXRlIH19XG4gICAgICAgICAgICAgICAgICAgIDwvc21hbGw+XG4gICAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgICAgPC9saT5cbiAgICAgICAgICAgIDwvdWw+XG4gICAgICAgICAgPC9jOHktZm9ybS1ncm91cD5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwicm93XCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTZcIj5cbiAgICAgICAgICAgICAgPGM4eS1mb3JtLWdyb3VwPlxuICAgICAgICAgICAgICAgIDxsYWJlbD57eyAnSG9yaXpvbnRhbCBhbGlnbm1lbnQnIHwgdHJhbnNsYXRlIH19PC9sYWJlbD5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYzh5LXNlbGVjdC13cmFwcGVyXCI+XG4gICAgICAgICAgICAgICAgICA8c2VsZWN0IGNsYXNzPVwiZm9ybS1jb250cm9sXCIgZm9ybUNvbnRyb2xOYW1lPVwib2JqZWN0UG9zaXRpb25YXCI+XG4gICAgICAgICAgICAgICAgICAgIDxvcHRpb24gW25nVmFsdWVdPVwiJ2xlZnQnXCI+XG4gICAgICAgICAgICAgICAgICAgICAge3sgJ2xlZnRgaG9yaXpvbnRhbCBhbGlnbm1lbnRgJyB8IHRyYW5zbGF0ZSB9fVxuICAgICAgICAgICAgICAgICAgICA8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiBbbmdWYWx1ZV09XCInY2VudGVyJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgIHt7ICdjZW50ZXJgaG9yaXpvbnRhbCBhbGlnbm1lbnRgJyB8IHRyYW5zbGF0ZSB9fVxuICAgICAgICAgICAgICAgICAgICA8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiBbbmdWYWx1ZV09XCIncmlnaHQnXCI+XG4gICAgICAgICAgICAgICAgICAgICAge3sgJ3JpZ2h0YGhvcml6b250YWwgYWxpZ25tZW50YCcgfCB0cmFuc2xhdGUgfX1cbiAgICAgICAgICAgICAgICAgICAgPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICA8L3NlbGVjdD5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPC9jOHktZm9ybS1ncm91cD5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1tZC02XCI+XG4gICAgICAgICAgICAgIDxjOHktZm9ybS1ncm91cD5cbiAgICAgICAgICAgICAgICA8bGFiZWw+e3sgJ1ZlcnRpY2FsIGFsaWdubWVudCcgfCB0cmFuc2xhdGUgfX08L2xhYmVsPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjOHktc2VsZWN0LXdyYXBwZXJcIj5cbiAgICAgICAgICAgICAgICAgIDxzZWxlY3QgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIiBmb3JtQ29udHJvbE5hbWU9XCJvYmplY3RQb3NpdGlvbllcIj5cbiAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiBbbmdWYWx1ZV09XCIndG9wJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgIHt7ICd0b3BgdmVydGljYWwgYWxpZ25tZW50YCcgfCB0cmFuc2xhdGUgfX1cbiAgICAgICAgICAgICAgICAgICAgPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgIDxvcHRpb24gW25nVmFsdWVdPVwiJ2NlbnRlcidcIj5cbiAgICAgICAgICAgICAgICAgICAgICB7eyAnY2VudGVyYHZlcnRpY2FsIGFsaWdubWVudGAnIHwgdHJhbnNsYXRlIH19XG4gICAgICAgICAgICAgICAgICAgIDwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIFtuZ1ZhbHVlXT1cIidib3R0b20nXCI+XG4gICAgICAgICAgICAgICAgICAgICAge3sgJ2JvdHRvbWB2ZXJ0aWNhbCBhbGlnbm1lbnRgJyB8IHRyYW5zbGF0ZSB9fVxuICAgICAgICAgICAgICAgICAgICA8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8L2M4eS1mb3JtLWdyb3VwPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTZcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImxlZ2VuZCBmb3JtLWJsb2NrXCI+e3sgJ1ByZXZpZXcnIHwgdHJhbnNsYXRlIH19PC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwXCI+XG4gICAgICAgICAgPGRpdlxuICAgICAgICAgICAgY2xhc3M9XCJib3JkZXItdG9wIGJvcmRlci1yaWdodCBib3JkZXItYm90dG9tIGJvcmRlci1sZWZ0IGlubmVyLXNjcm9sbFwiXG4gICAgICAgICAgICBzdHlsZT1cImhlaWdodDogMzAwcHhcIlxuICAgICAgICAgID5cbiAgICAgICAgICAgIDxpbWdcbiAgICAgICAgICAgICAgW3NyY109XCJzcmNcIlxuICAgICAgICAgICAgICBbbmdDbGFzc109XCJzdHlsaW5nID8gJ2ZpdC1oIGZpdC13JyA6ICdpbWctcmVzcG9uc2l2ZSdcIlxuICAgICAgICAgICAgICBbbmdTdHlsZV09XCJzdHlsaW5nXCJcbiAgICAgICAgICAgIC8+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgPC9uZy1jb250YWluZXI+XG4gICAgPGRpdiBjbGFzcz1cImNvbC1tZC0xMiBkLWZsZXggai1jLWNlbnRlclwiICpuZ0lmPVwibG9hZGluZ1wiPlxuICAgICAgPGM4eS1sb2FkaW5nPjwvYzh5LWxvYWRpbmc+XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuPC9kaXY+XG4iXX0=
150
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW1hZ2Utd2lkZ2V0LWNvbmZpZy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi93aWRnZXRzL2ltcGxlbWVudGF0aW9ucy9pbWFnZS9pbWFnZS13aWRnZXQtY29uZmlnL2ltYWdlLXdpZGdldC1jb25maWcuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vd2lkZ2V0cy9pbXBsZW1lbnRhdGlvbnMvaW1hZ2UvaW1hZ2Utd2lkZ2V0LWNvbmZpZy9pbWFnZS13aWRnZXQtY29uZmlnLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFxQixRQUFRLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDOUUsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sdUNBQXVDLENBQUM7QUFDOUUsT0FBTyxFQUNMLGFBQWEsRUFFYixZQUFZLEVBQ1osWUFBWSxFQUNaLE9BQU8sRUFDUCxrQkFBa0IsRUFDbEIsaUJBQWlCLEVBQ2pCLGdCQUFnQixFQUNoQixnQkFBZ0IsRUFDaEIsaUJBQWlCLEVBQ2xCLE1BQU0scUJBQXFCLENBQUM7QUFDN0IsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUNoQyxPQUFPLEVBQ0wscUJBQXFCLEVBQ3JCLDBCQUEwQixFQUkzQixNQUFNLHVCQUF1QixDQUFDO0FBQy9CLE9BQU8sRUFDTCxnQkFBZ0IsRUFDaEIsV0FBVyxFQUVYLE1BQU0sRUFDTixtQkFBbUIsRUFDbkIsVUFBVSxFQUNYLE1BQU0sZ0JBQWdCLENBQUM7QUFDeEIsT0FBTyxFQUFFLGVBQWUsRUFBYyxLQUFLLEVBQUUsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ25FLE9BQU8sRUFDTCxvQkFBb0IsRUFDcEIsTUFBTSxFQUNOLEdBQUcsRUFDSCxXQUFXLEVBQ1gsU0FBUyxFQUNULFNBQVMsRUFDVCxHQUFHLEVBQ0osTUFBTSxnQkFBZ0IsQ0FBQztBQUN4QixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUM3RCxPQUFPLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxNQUFNLGlCQUFpQixDQUFDOzs7Ozs7QUFxQjdFLE1BQU0sT0FBTywwQkFBMEI7SUF3Q3JDLFlBQ1UsV0FBd0IsRUFDeEIsSUFBWSxFQUNaLFdBQXlCLEVBQ3pCLEtBQW1CLEVBQ25CLFdBQStCLEVBQ25CLFlBQW1DO1FBTC9DLGdCQUFXLEdBQVgsV0FBVyxDQUFhO1FBQ3hCLFNBQUksR0FBSixJQUFJLENBQVE7UUFDWixnQkFBVyxHQUFYLFdBQVcsQ0FBYztRQUN6QixVQUFLLEdBQUwsS0FBSyxDQUFjO1FBQ25CLGdCQUFXLEdBQVgsV0FBVyxDQUFvQjtRQUNuQixpQkFBWSxHQUFaLFlBQVksQ0FBdUI7UUE1Q3pELG1CQUFjLEdBQUcsSUFBSSxlQUFlLENBQVMsSUFBSSxDQUFDLENBQUM7UUFFbkQsWUFBTyxHQUFHLEtBQUssQ0FBQztRQUloQixlQUFVLEdBQUcsSUFBSSxPQUFPLEVBQVEsQ0FBQztRQUNqQyxxQkFBZ0IsR0FBRztZQUNqQjtnQkFDRSxLQUFLLEVBQUUsT0FBTyxDQUFDLHFDQUFxQyxDQUFDO2dCQUNyRCxLQUFLLEVBQUUsU0FBUztnQkFDaEIsV0FBVyxFQUFFLE9BQU8sQ0FDbEIsc0ZBQXNGLENBQ3ZGO2FBQ0Y7WUFDRDtnQkFDRSxLQUFLLEVBQUUsT0FBTyxDQUFDLG1DQUFtQyxDQUFDO2dCQUNuRCxLQUFLLEVBQUUsT0FBTztnQkFDZCxXQUFXLEVBQUUsT0FBTyxDQUNsQiwyR0FBMkcsQ0FDNUc7YUFDRjtZQUNEO2dCQUNFLEtBQUssRUFBRSxPQUFPLENBQUMsa0NBQWtDLENBQUM7Z0JBQ2xELEtBQUssRUFBRSxNQUFNO2dCQUNiLFdBQVcsRUFBRSxPQUFPLENBQ2xCLHlFQUF5RSxDQUMxRTthQUNGO1lBQ0Q7Z0JBQ0UsS0FBSyxFQUFFLE9BQU8sQ0FBQyxrQ0FBa0MsQ0FBQztnQkFDbEQsS0FBSyxFQUFFLFlBQVk7Z0JBQ25CLFdBQVcsRUFBRSxPQUFPLENBQ2xCLG1IQUFtSCxDQUNwSDthQUNGO1NBQ0YsQ0FBQztJQVNDLENBQUM7SUFFSixLQUFLLENBQUMsWUFBWSxDQUFDLE1BQTBCO1FBQzNDLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUMzQixPQUFPLEtBQUssQ0FBQztRQUNmLENBQUM7UUFFRCxNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsb0JBQW9CLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNyRSxJQUFJLFlBQVksSUFBSSxZQUFZLEtBQUssSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO1lBQ3pELElBQUksQ0FBQztnQkFDSCxNQUFNLGFBQWEsR0FBRyxNQUFNLElBQUksQ0FBQyxXQUFXLENBQUMsVUFBVSxDQUFDLFlBQVksRUFBRTtvQkFDcEUsYUFBYSxFQUFFLElBQUksQ0FBQyxnQkFBZ0IsRUFBRTtvQkFDdEMscUJBQXFCLEVBQUUsSUFBSSxDQUFDLFlBQVksRUFBRSxxQkFBcUI7aUJBQ2hFLENBQUMsQ0FBQztnQkFDSCxNQUFNLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxFQUFFLGFBQWEsRUFBRSxDQUFDLENBQUM7WUFDM0MsQ0FBQztZQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7Z0JBQ1gsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLHlCQUF5QixDQUFDLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDO2dCQUMvRCxPQUFPLEtBQUssQ0FBQztZQUNmLENBQUM7UUFDSCxDQUFDO1FBQ0QsTUFBTSxPQUFPLEdBQTZCLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQztRQUN2RSxNQUFNLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxFQUFFLE9BQU8sRUFBRSxDQUFDLENBQUM7UUFFbkMsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsUUFBUTtRQUNOLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUNoQixNQUFNLGVBQWUsR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksQ0FDOUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUNsQixvQkFBb0IsRUFBRSxFQUN0QixHQUFHLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxDQUFDLEVBQ2hDLFNBQVMsQ0FBQyxhQUFhLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsZUFBZSxDQUFDLGFBQWEsQ0FBQyxDQUFDLEVBQzNFLEdBQUcsQ0FBQyxPQUFPLENBQUMsRUFBRTtZQUNaLElBQUksQ0FBQyxPQUFPLEdBQUcsS0FBSyxDQUFDO1lBQ3JCLElBQUksQ0FBQyxjQUFjLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQztZQUNuQyxJQUFJLE9BQU8sRUFBRSxDQUFDO2dCQUNaLElBQUksQ0FBQyxTQUFTLENBQUMsVUFBVSxDQUFDLEVBQUUsTUFBTSxFQUFFLENBQUMsRUFBRSxJQUFJLEVBQUUsT0FBTyxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUMzRixDQUFDO1FBQ0gsQ0FBQyxDQUFDLEVBQ0YsR0FBRyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsT0FBTyxFQUFFLE1BQU0sQ0FBQyxFQUMvQixXQUFXLENBQUMsQ0FBQyxDQUFDLENBQ2YsQ0FBQztRQUNGLE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsWUFBWSxDQUFDLElBQUksQ0FDbkQsR0FBRyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLG9CQUFvQixDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQzlDLG9CQUFvQixFQUFFLEVBQ3RCLFNBQVMsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQ2xGLENBQUM7UUFDRixJQUFJLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQyxlQUFlLEVBQUUsWUFBWSxDQUFDLENBQUMsSUFBSSxDQUN4RCxHQUFHLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUUsTUFBaUIsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FDbEQsQ0FBQztRQUNGLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsYUFBYSxDQUFDLENBQUM7SUFDdkQsQ0FBQztJQUVELFdBQVc7UUFDVCxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ3ZCLElBQUksQ0FBQyxVQUFVLENBQUMsUUFBUSxFQUFFLENBQUM7SUFDN0IsQ0FBQztJQUVPLGdCQUFnQjtRQUN0QixPQUFPLEdBQUcsQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLE9BQU8sRUFBRSxJQUFJLENBQUMsQ0FBQztJQUMvQyxDQUFDO0lBRU8sS0FBSyxDQUFDLFFBQVE7UUFDcEIsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQztZQUM5QyxTQUFTLEVBQUU7Z0JBQ1QsMEdBQTBHO2dCQUMxRyxJQUFJLENBQUMsTUFBTSxDQUFDLGFBQWEsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLHFCQUFxQjtnQkFDeEYsQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDO2FBQ3RCO1lBQ0QsZUFBZSxFQUFFLENBQUMsMEJBQTBCLEVBQUUsQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDcEUsZUFBZSxFQUFFLENBQUMsMEJBQTBCLEVBQUUsQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLENBQUM7U0FDckUsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQztZQUN0QyxNQUFNLEVBQUU7Z0JBQ04sSUFBSTtnQkFDSjtvQkFDRSxVQUFVLENBQUMsUUFBUTtvQkFDbkIsVUFBVSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7b0JBQ3ZCLFVBQVUsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDO29CQUN2QixhQUFhLENBQUMsY0FBYyxDQUFDLEVBQUUsbUJBQW1CLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSxRQUFRLEVBQUUsQ0FBQztpQkFDbEY7YUFDRjtZQUNELE9BQU8sRUFBRSxnQkFBZ0I7U0FDMUIsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDcEQsSUFBSSxDQUFDLFNBQVMsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3ZDLElBQUksQ0FBQyxTQUFTLENBQUMsWUFBWTthQUN4QixJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQzthQUNoQyxTQUFTLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7SUFDcEQsQ0FBQztJQUVPLG9CQUFvQixDQUFDLFNBQWM7UUFDekMsTUFBTSxNQUFNLEdBQVUsU0FBUyxFQUFFLE1BQU0sSUFBSSxFQUFFLENBQUM7UUFDOUMsT0FBTyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsSUFBSSxJQUFJLElBQUksQ0FBQztJQUNqQyxDQUFDO0lBRU8sVUFBVSxDQUFDLE1BQXlCO1FBQzFDLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDckQsQ0FBQzs4R0FsSlUsMEJBQTBCO2tHQUExQiwwQkFBMEIsaUhDOUR2Qyx5NkpBNkhBLDJDRDVFSSxtQkFBbUIseWpEQUNuQixrQkFBa0IsdUlBQ2xCLGlCQUFpQixzR0FDakIsZ0JBQWdCLDZFQUNoQixnQkFBZ0IsNkNBQ2hCLFNBQVMsOENBQ1QsSUFBSSw2RkFDSixPQUFPLDJFQUNQLE9BQU8sb0ZBQ1AsT0FBTyxtSEFDUCxpQkFBaUIsaVJBYkosQ0FBQyxFQUFFLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxXQUFXLEVBQUUsTUFBTSxFQUFFLENBQUM7OzJGQWdCeEQsMEJBQTBCO2tCQW5CdEMsU0FBUzsrQkFDRSx5QkFBeUIsaUJBRXBCLENBQUMsRUFBRSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsV0FBVyxFQUFFLE1BQU0sRUFBRSxDQUFDLGNBQ3ZELElBQUksV0FDUDt3QkFDUCxtQkFBbUI7d0JBQ25CLGtCQUFrQjt3QkFDbEIsaUJBQWlCO3dCQUNqQixnQkFBZ0I7d0JBQ2hCLGdCQUFnQjt3QkFDaEIsU0FBUzt3QkFDVCxJQUFJO3dCQUNKLE9BQU87d0JBQ1AsT0FBTzt3QkFDUCxPQUFPO3dCQUNQLGlCQUFpQjtxQkFDbEI7OzBCQWdERSxRQUFRO3lDQTdDRixNQUFNO3NCQUFkLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIElucHV0LCBPbkRlc3Ryb3ksIE9uSW5pdCwgT3B0aW9uYWwgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFdpZGdldENvbmZpZ0NvbXBvbmVudCB9IGZyb20gJ0BjOHkvbmd4LWNvbXBvbmVudHMvY29udGV4dC1kYXNoYm9hcmQnO1xuaW1wb3J0IHtcbiAgQzh5VmFsaWRhdG9ycyxcbiAgT25CZWZvcmVTYXZlLFxuICBGaWxlc1NlcnZpY2UsXG4gIEFsZXJ0U2VydmljZSxcbiAgZ2V0dGV4dCxcbiAgRm9ybUdyb3VwQ29tcG9uZW50LFxuICBNZXNzYWdlc0NvbXBvbmVudCxcbiAgTWVzc2FnZURpcmVjdGl2ZSxcbiAgQzh5VHJhbnNsYXRlUGlwZSxcbiAgRHJvcEFyZWFDb21wb25lbnRcbn0gZnJvbSAnQGM4eS9uZ3gtY29tcG9uZW50cyc7XG5pbXBvcnQgeyBnZXQgfSBmcm9tICdsb2Rhc2gtZXMnO1xuaW1wb3J0IHtcbiAgZGVmYXVsdE9iamVjdEZpdFZhbHVlLFxuICBkZWZhdWx0T2JqZWN0UG9zaXRpb25WYWx1ZSxcbiAgSW1hZ2VXaWRnZXRDb25maWcsXG4gIEltYWdlV2lkZ2V0Q29uZmlnU3R5bGluZyxcbiAgSW1hZ2VXaWRnZXRTdHlsZVxufSBmcm9tICcuLi9pbWFnZS13aWRnZXQubW9kZWwnO1xuaW1wb3J0IHtcbiAgQ29udHJvbENvbnRhaW5lcixcbiAgRm9ybUJ1aWxkZXIsXG4gIEZvcm1Hcm91cCxcbiAgTmdGb3JtLFxuICBSZWFjdGl2ZUZvcm1zTW9kdWxlLFxuICBWYWxpZGF0b3JzXG59IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IEJlaGF2aW9yU3ViamVjdCwgT2JzZXJ2YWJsZSwgbWVyZ2UsIFN1YmplY3QgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7XG4gIGRpc3RpbmN0VW50aWxDaGFuZ2VkLFxuICBmaWx0ZXIsXG4gIG1hcCxcbiAgc2hhcmVSZXBsYXksXG4gIHN3aXRjaE1hcCxcbiAgdGFrZVVudGlsLFxuICB0YXBcbn0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgSW1hZ2VXaWRnZXRTZXJ2aWNlIH0gZnJvbSAnLi4vaW1hZ2Utd2lkZ2V0LnNlcnZpY2UnO1xuaW1wb3J0IHsgQXN5bmNQaXBlLCBOZ0NsYXNzLCBOZ0Zvck9mLCBOZ0lmLCBOZ1N0eWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnYzh5LWltYWdlLXdpZGdldC1jb25maWcnLFxuICB0ZW1wbGF0ZVVybDogJy4vaW1hZ2Utd2lkZ2V0LWNvbmZpZy5jb21wb25lbnQuaHRtbCcsXG4gIHZpZXdQcm92aWRlcnM6IFt7IHByb3ZpZGU6IENvbnRyb2xDb250YWluZXIsIHVzZUV4aXN0aW5nOiBOZ0Zvcm0gfV0sXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtcbiAgICBSZWFjdGl2ZUZvcm1zTW9kdWxlLFxuICAgIEZvcm1Hcm91cENvbXBvbmVudCxcbiAgICBNZXNzYWdlc0NvbXBvbmVudCxcbiAgICBNZXNzYWdlRGlyZWN0aXZlLFxuICAgIEM4eVRyYW5zbGF0ZVBpcGUsXG4gICAgQXN5bmNQaXBlLFxuICAgIE5nSWYsXG4gICAgTmdTdHlsZSxcbiAgICBOZ0NsYXNzLFxuICAgIE5nRm9yT2YsXG4gICAgRHJvcEFyZWFDb21wb25lbnRcbiAgXVxufSlcbmV4cG9ydCBjbGFzcyBJbWFnZVdpZGdldENvbmZpZ0NvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95LCBPbkJlZm9yZVNhdmUge1xuICBASW5wdXQoKSBjb25maWc6IEltYWdlV2lkZ2V0Q29uZmlnO1xuICBpbWFnZUJpbmFyeUlkJCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8c3RyaW5nPihudWxsKTtcbiAgaW1hZ2VTcmMkOiBPYnNlcnZhYmxlPHN0cmluZz47XG4gIGxvYWRpbmcgPSBmYWxzZTtcbiAgZm9ybUdyb3VwOiBGb3JtR3JvdXA7XG4gIGZpbGVGcm9tQ29uZmlnOiBGaWxlO1xuICBzdHlsaW5nOiBJbWFnZVdpZGdldFN0eWxlIHwgbnVsbDtcbiAgZGVzdHJveWVkJCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG4gIG9iamVjdEZpdE9wdGlvbnMgPSBbXG4gICAge1xuICAgICAgbGFiZWw6IGdldHRleHQoJ0NvbnRhaW5gdmVyYiwgaW1hZ2UgZml0dGluZyBvcHRpb25gJyksXG4gICAgICB2YWx1ZTogJ2NvbnRhaW4nLFxuICAgICAgZGVzY3JpcHRpb246IGdldHRleHQoXG4gICAgICAgICdUaGUgaW1hZ2UgaXMgZW50aXJlbHkgZGlzcGxheWVkIHdpdGhpbiB0aGUgd2lkZ2V0IHdoaWxlIHByZXNlcnZpbmcgdGhlIGFzcGVjdCByYXRpby4nXG4gICAgICApXG4gICAgfSxcbiAgICB7XG4gICAgICBsYWJlbDogZ2V0dGV4dCgnQ292ZXJgdmVyYiwgaW1hZ2UgZml0dGluZyBvcHRpb25gJyksXG4gICAgICB2YWx1ZTogJ2NvdmVyJyxcbiAgICAgIGRlc2NyaXB0aW9uOiBnZXR0ZXh0KFxuICAgICAgICAnVGhlIGltYWdlIGlzIHJlc2l6ZWQgdG8gZmlsbCB0aGUgd2lkZ2V0IHdoaWxlIHByZXNlcnZpbmcgdGhlIGFzcGVjdCByYXRpby4gT3ZlcmZsb3dpbmcgYXJlYXMgYXJlIGNsaXBwZWQuJ1xuICAgICAgKVxuICAgIH0sXG4gICAge1xuICAgICAgbGFiZWw6IGdldHRleHQoJ0ZpbGxgdmVyYiwgaW1hZ2UgZml0dGluZyBvcHRpb25gJyksXG4gICAgICB2YWx1ZTogJ2ZpbGwnLFxuICAgICAgZGVzY3JpcHRpb246IGdldHRleHQoXG4gICAgICAgICdUaGUgaW1hZ2UgaXMgc3RyZXRjaGVkIHRvIGZpbGwgdGhlIHdpZGdldCwgb3ZlcnJpZGluZyB0aGUgYXNwZWN0LXJhdGlvLidcbiAgICAgIClcbiAgICB9LFxuICAgIHtcbiAgICAgIGxhYmVsOiBnZXR0ZXh0KCdGdWxsIHdpZHRoYGltYWdlIGZpdHRpbmcgb3B0aW9uYCcpLFxuICAgICAgdmFsdWU6ICdmdWxsLXdpZHRoJyxcbiAgICAgIGRlc2NyaXB0aW9uOiBnZXR0ZXh0KFxuICAgICAgICBgVGhlIGltYWdlIGlzIHJlc2l6ZWQgdG8gZml0IHRoZSB3aWRnZXQncyB3aWR0aCB3aGlsZSBwcmVzZXJ2aW5nIHRoZSBhc3BlY3QgcmF0aW8uIE92ZXJmbG93aW5nIGFyZWEgaXMgc2Nyb2xsYWJsZS5gXG4gICAgICApXG4gICAgfVxuICBdO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgZm9ybUJ1aWxkZXI6IEZvcm1CdWlsZGVyLFxuICAgIHByaXZhdGUgZm9ybTogTmdGb3JtLFxuICAgIHByaXZhdGUgZmlsZVNlcnZpY2U6IEZpbGVzU2VydmljZSxcbiAgICBwcml2YXRlIGFsZXJ0OiBBbGVydFNlcnZpY2UsXG4gICAgcHJpdmF0ZSBpbWFnZVdpZGdldDogSW1hZ2VXaWRnZXRTZXJ2aWNlLFxuICAgIEBPcHRpb25hbCgpIHByaXZhdGUgd2lkZ2V0Q29uZmlnOiBXaWRnZXRDb25maWdDb21wb25lbnRcbiAgKSB7fVxuXG4gIGFzeW5jIG9uQmVmb3JlU2F2ZShjb25maWc/OiBJbWFnZVdpZGdldENvbmZpZyk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGlmICh0aGlzLmZvcm1Hcm91cC5pbnZhbGlkKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgY29uc3QgZmlsZUZyb21Gb3JtID0gdGhpcy5nZXRGaWxlRnJvbUZvcm1WYWx1ZSh0aGlzLmZvcm1Hcm91cC52YWx1ZSk7XG4gICAgaWYgKGZpbGVGcm9tRm9ybSAmJiBmaWxlRnJvbUZvcm0gIT09IHRoaXMuZmlsZUZyb21Db25maWcpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IGltYWdlQmluYXJ5SWQgPSBhd2FpdCB0aGlzLmltYWdlV2lkZ2V0LnVwbG9hZEZpbGUoZmlsZUZyb21Gb3JtLCB7XG4gICAgICAgICAgZGFzaGJvYXJkTW9JZDogdGhpcy5nZXREYXNoYm9hcmRNb0lkKCksXG4gICAgICAgICAgaXNEZXZpY2VUeXBlRGFzaGJvYXJkOiB0aGlzLndpZGdldENvbmZpZz8uaXNEZXZpY2VUeXBlRGFzaGJvYXJkXG4gICAgICAgIH0pO1xuICAgICAgICBPYmplY3QuYXNzaWduKGNvbmZpZywgeyBpbWFnZUJpbmFyeUlkIH0pO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICB0aGlzLmFsZXJ0LmRhbmdlcihnZXR0ZXh0KCdVbmFibGUgdG8gdXBsb2FkIGltYWdlLicpLCBlPy5kYXRhKTtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgICBjb25zdCBzdHlsaW5nOiBJbWFnZVdpZGdldENvbmZpZ1N0eWxpbmcgPSB0aGlzLmZvcm1Hcm91cC52YWx1ZS5zdHlsaW5nO1xuICAgIE9iamVjdC5hc3NpZ24oY29uZmlnLCB7IHN0eWxpbmcgfSk7XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIG5nT25Jbml0KCkge1xuICAgIHRoaXMuaW5pdEZvcm0oKTtcbiAgICBjb25zdCBpbWFnZUZyb21Db25maWcgPSB0aGlzLmltYWdlQmluYXJ5SWQkLnBpcGUoXG4gICAgICBmaWx0ZXIoaWQgPT4gISFpZCksXG4gICAgICBkaXN0aW5jdFVudGlsQ2hhbmdlZCgpLFxuICAgICAgdGFwKCgpID0+ICh0aGlzLmxvYWRpbmcgPSB0cnVlKSksXG4gICAgICBzd2l0Y2hNYXAoaW1hZ2VCaW5hcnlJZCA9PiB0aGlzLmltYWdlV2lkZ2V0LmdldEltYWdlRGV0YWlscyhpbWFnZUJpbmFyeUlkKSksXG4gICAgICB0YXAoZGV0YWlscyA9PiB7XG4gICAgICAgIHRoaXMubG9hZGluZyA9IGZhbHNlO1xuICAgICAgICB0aGlzLmZpbGVGcm9tQ29uZmlnID0gZGV0YWlscy5maWxlO1xuICAgICAgICBpZiAoZGV0YWlscykge1xuICAgICAgICAgIHRoaXMuZm9ybUdyb3VwLnBhdGNoVmFsdWUoeyBpbWFnZXM6IFt7IGZpbGU6IGRldGFpbHMuZmlsZSwgbmFtZTogZGV0YWlscy5maWxlLm5hbWUgfV0gfSk7XG4gICAgICAgIH1cbiAgICAgIH0pLFxuICAgICAgbWFwKGRldGFpbHMgPT4gZGV0YWlscz8uYmFzZTY0KSxcbiAgICAgIHNoYXJlUmVwbGF5KDEpXG4gICAgKTtcbiAgICBjb25zdCBzZWxlY3RlZEZpbGUgPSB0aGlzLmZvcm1Hcm91cC52YWx1ZUNoYW5nZXMucGlwZShcbiAgICAgIG1hcCh2YWx1ZSA9PiB0aGlzLmdldEZpbGVGcm9tRm9ybVZhbHVlKHZhbHVlKSksXG4gICAgICBkaXN0aW5jdFVudGlsQ2hhbmdlZCgpLFxuICAgICAgc3dpdGNoTWFwKGZpbGUgPT4gKGZpbGUgPyB0aGlzLmZpbGVTZXJ2aWNlLnRvQmFzZTY0KGZpbGUpIDogUHJvbWlzZS5yZXNvbHZlKCcnKSkpXG4gICAgKTtcbiAgICB0aGlzLmltYWdlU3JjJCA9IG1lcmdlKGltYWdlRnJvbUNvbmZpZywgc2VsZWN0ZWRGaWxlKS5waXBlKFxuICAgICAgbWFwKGJhc2U2NCA9PiAoYmFzZTY0ID8gKGJhc2U2NCBhcyBzdHJpbmcpIDogJycpKVxuICAgICk7XG4gICAgdGhpcy5pbWFnZUJpbmFyeUlkJC5uZXh0KHRoaXMuY29uZmlnPy5pbWFnZUJpbmFyeUlkKTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMuZGVzdHJveWVkJC5uZXh0KCk7XG4gICAgdGhpcy5kZXN0cm95ZWQkLmNvbXBsZXRlKCk7XG4gIH1cblxuICBwcml2YXRlIGdldERhc2hib2FyZE1vSWQoKTogc3RyaW5nIHwgbnVsbCB7XG4gICAgcmV0dXJuIGdldCh0aGlzLndpZGdldENvbmZpZywgJ21vLmlkJywgbnVsbCk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGluaXRGb3JtKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHN0eWxpbmdGb3JtR3JvdXAgPSB0aGlzLmZvcm1CdWlsZGVyLmdyb3VwKHtcbiAgICAgIG9iamVjdEZpdDogW1xuICAgICAgICAvLyBmYWxsYmFjayB0byAnZnVsbC13aWR0aCcgZm9yIG9sZCBsZWdhY3kgd2lkZ2V0cywgbmV3bHkgY3JlYXRlZCB3aWRnZXRzIHNob3VsZCB1c2UgZGVmYXVsdE9iamVjdEZpdFZhbHVlXG4gICAgICAgIHRoaXMuY29uZmlnLmltYWdlQmluYXJ5SWQgJiYgIXRoaXMuY29uZmlnLnN0eWxpbmcgPyAnZnVsbC13aWR0aCcgOiBkZWZhdWx0T2JqZWN0Rml0VmFsdWUsXG4gICAgICAgIFtWYWxpZGF0b3JzLnJlcXVpcmVkXVxuICAgICAgXSxcbiAgICAgIG9iamVjdFBvc2l0aW9uWDogW2RlZmF1bHRPYmplY3RQb3NpdGlvblZhbHVlLCBbVmFsaWRhdG9ycy5yZXF1aXJlZF1dLFxuICAgICAgb2JqZWN0UG9zaXRpb25ZOiBbZGVmYXVsdE9iamVjdFBvc2l0aW9uVmFsdWUsIFtWYWxpZGF0b3JzLnJlcXVpcmVkXV1cbiAgICB9KTtcbiAgICB0aGlzLmZvcm1Hcm91cCA9IHRoaXMuZm9ybUJ1aWxkZXIuZ3JvdXAoe1xuICAgICAgaW1hZ2VzOiBbXG4gICAgICAgIG51bGwsXG4gICAgICAgIFtcbiAgICAgICAgICBWYWxpZGF0b3JzLnJlcXVpcmVkLFxuICAgICAgICAgIFZhbGlkYXRvcnMubWluTGVuZ3RoKDEpLFxuICAgICAgICAgIFZhbGlkYXRvcnMubWF4TGVuZ3RoKDEpLFxuICAgICAgICAgIEM4eVZhbGlkYXRvcnMuZmlsZXNWYWxpZGF0b3IoeyBtYXhpbXVtRmlsZVNpemVJbktiOiAxMDAwLCB0eXBlUHJlZml4OiAnaW1hZ2UvJyB9KVxuICAgICAgICBdXG4gICAgICBdLFxuICAgICAgc3R5bGluZzogc3R5bGluZ0Zvcm1Hcm91cFxuICAgIH0pO1xuICAgIHRoaXMuZm9ybS5mb3JtLmFkZENvbnRyb2woJ2NvbmZpZycsIHRoaXMuZm9ybUdyb3VwKTtcbiAgICB0aGlzLmZvcm1Hcm91cC5wYXRjaFZhbHVlKHRoaXMuY29uZmlnKTtcbiAgICB0aGlzLmZvcm1Hcm91cC52YWx1ZUNoYW5nZXNcbiAgICAgIC5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3llZCQpKVxuICAgICAgLnN1YnNjcmliZShjaGFuZ2VzID0+IHRoaXMuc2V0U3R5bGluZyhjaGFuZ2VzKSk7XG4gIH1cblxuICBwcml2YXRlIGdldEZpbGVGcm9tRm9ybVZhbHVlKGZvcm1WYWx1ZTogYW55KTogRmlsZSB8IG51bGwge1xuICAgIGNvbnN0IGltYWdlczogYW55W10gPSBmb3JtVmFsdWU/LmltYWdlcyB8fCBbXTtcbiAgICByZXR1cm4gaW1hZ2VzWzBdPy5maWxlIHx8IG51bGw7XG4gIH1cblxuICBwcml2YXRlIHNldFN0eWxpbmcoY29uZmlnOiBJbWFnZVdpZGdldENvbmZpZyk6IHZvaWQge1xuICAgIHRoaXMuc3R5bGluZyA9IHRoaXMuaW1hZ2VXaWRnZXQuZ2V0U3R5bGluZyhjb25maWcpO1xuICB9XG59XG4iLCI8ZGl2IGNsYXNzPVwicC1sLTI0IHAtci0yNFwiPlxuICA8ZGl2IFtmb3JtR3JvdXBdPVwiZm9ybUdyb3VwXCIgY2xhc3M9XCJyb3cgcC10LThcIj5cbiAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTEyXCI+XG4gICAgICA8Yzh5LWZvcm0tZ3JvdXA+XG4gICAgICAgIDxsYWJlbD57eyAnSW1hZ2UnIHwgdHJhbnNsYXRlIH19PC9sYWJlbD5cbiAgICAgICAgPGM4eS1kcm9wLWFyZWFcbiAgICAgICAgICBmb3JtQ29udHJvbE5hbWU9XCJpbWFnZXNcIlxuICAgICAgICAgIGNsYXNzPVwiZHJvcC1hcmVhLXNtXCJcbiAgICAgICAgICBbaWNvbl09XCIndXBsb2FkJ1wiXG4gICAgICAgICAgW2FjY2VwdF09XCInaW1hZ2UnXCJcbiAgICAgICAgICBbbWF4QWxsb3dlZEZpbGVzXT1cIjFcIlxuICAgICAgICA+PC9jOHktZHJvcC1hcmVhPlxuICAgICAgICA8Yzh5LW1lc3NhZ2VzPlxuICAgICAgICAgIDxjOHktbWVzc2FnZVxuICAgICAgICAgICAgbmFtZT1cIm1heEZpbGVTaXplUmVhY2hlZFwiXG4gICAgICAgICAgICBbdGV4dF09XCJcbiAgICAgICAgICAgICAgJ1RoZSBtYXhpbXVtIGltYWdlIHNpemUgaXMge3sgbWF4RmlsZVNpemUgfX0ga0IuIFRoZSBzZWxlY3RlZCBpbWFnZSBoYXMgYSBzaXplIG9mIHt7IGFjdHVhbEZpbGVTaXplIH19IGtCLidcbiAgICAgICAgICAgICAgICB8IHRyYW5zbGF0ZVxuICAgICAgICAgICAgXCJcbiAgICAgICAgICA+PC9jOHktbWVzc2FnZT5cbiAgICAgICAgICA8Yzh5LW1lc3NhZ2VcbiAgICAgICAgICAgIG5hbWU9XCJ3cm9uZ0ZpbGVUeXBlXCJcbiAgICAgICAgICAgIFt0ZXh0XT1cIidXcm9uZyBmaWxlIHR5cGUsIHNlbGVjdCBhbiBpbWFnZS4nIHwgdHJhbnNsYXRlXCJcbiAgICAgICAgICA+PC9jOHktbWVzc2FnZT5cbiAgICAgICAgICA8Yzh5LW1lc3NhZ2UgbmFtZT1cIm1heGxlbmd0aFwiIFt0ZXh0XT1cIidPbmx5IHNlbGVjdCBvbmUgaW1hZ2UuJyB8IHRyYW5zbGF0ZVwiPjwvYzh5LW1lc3NhZ2U+XG4gICAgICAgICAgPGM4eS1tZXNzYWdlIG5hbWU9XCJyZXF1aXJlZFwiIFt0ZXh0XT1cIidBbiBpbWFnZSBpcyByZXF1aXJlZC4nIHwgdHJhbnNsYXRlXCI+PC9jOHktbWVzc2FnZT5cbiAgICAgICAgICA8Yzh5LW1lc3NhZ2UgbmFtZT1cIm1pbmxlbmd0aFwiIFt0ZXh0XT1cIidBbiBpbWFnZSBpcyByZXF1aXJlZC4nIHwgdHJhbnNsYXRlXCI+PC9jOHktbWVzc2FnZT5cbiAgICAgICAgPC9jOHktbWVzc2FnZXM+XG4gICAgICA8L2M4eS1mb3JtLWdyb3VwPlxuICAgIDwvZGl2PlxuICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJpbWFnZVNyYyQgfCBhc3luYyBhcyBzcmNcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJjb2wtbWQtNlwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwibGVnZW5kIGZvcm0tYmxvY2tcIj5cbiAgICAgICAgICB7eyAnU2l6ZSBhbmQgYWxpZ25tZW50JyB8IHRyYW5zbGF0ZSB9fVxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBbZm9ybUdyb3VwTmFtZV09XCInc3R5bGluZydcIj5cbiAgICAgICAgICA8Yzh5LWZvcm0tZ3JvdXA+XG4gICAgICAgICAgICA8bGFiZWw+XG4gICAgICAgICAgICAgIHt7ICdJbWFnZSBkaXNwbGF5JyB8IHRyYW5zbGF0ZSB9fVxuICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgIDx1bCBjbGFzcz1cImxpc3QtZ3JvdXAgc2VwYXJhdG9yLXRvcC1ib3R0b21cIj5cbiAgICAgICAgICAgICAgPGxpXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJsaXN0LWdyb3VwLWl0ZW0gZC1mbGV4IGEtaS1jZW50ZXIgcC1sLTBcIlxuICAgICAgICAgICAgICAgICpuZ0Zvcj1cImxldCBvYmplY3RGaXRPcHRpb24gb2Ygb2JqZWN0Rml0T3B0aW9uczsgbGV0IGkgPSBpbmRleFwiXG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJjOHktcmFkaW9cIj5cbiAgICAgICAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICAgICAgICB0eXBlPVwicmFkaW9cIlxuICAgICAgICAgICAgICAgICAgICBbaWRdPVwiJ2dyb3VwcmFkaW9jb250ZW50Y2xhc3MnICsgaVwiXG4gICAgICAgICAgICAgICAgICAgIGZvcm1Db250cm9sTmFtZT1cIm9iamVjdEZpdFwiXG4gICAgICAgICAgICAgICAgICAgIFt2YWx1ZV09XCJvYmplY3RGaXRPcHRpb24udmFsdWVcIlxuICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICAgIDxzcGFuPjwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibC1oLTFcIj5cbiAgICAgICAgICAgICAgICAgICAge3sgb2JqZWN0Rml0T3B0aW9uLmxhYmVsIHwgdHJhbnNsYXRlIH19XG4gICAgICAgICAgICAgICAgICAgIDxiciAvPlxuICAgICAgICAgICAgICAgICAgICA8c21hbGwgY2xhc3M9XCJ0ZXh0LW11dGVkXCI+XG4gICAgICAgICAgICAgICAgICAgICAge3sgb2JqZWN0Rml0T3B0aW9uLmRlc2NyaXB0aW9uIHwgdHJhbnNsYXRlIH19XG4gICAgICAgICAgICAgICAgICAgIDwvc21hbGw+XG4gICAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgICAgPC9saT5cbiAgICAgICAgICAgIDwvdWw+XG4gICAgICAgICAgPC9jOHktZm9ybS1ncm91cD5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwicm93XCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTZcIj5cbiAgICAgICAgICAgICAgPGM4eS1mb3JtLWdyb3VwPlxuICAgICAgICAgICAgICAgIDxsYWJlbD57eyAnSG9yaXpvbnRhbCBhbGlnbm1lbnQnIHwgdHJhbnNsYXRlIH19PC9sYWJlbD5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYzh5LXNlbGVjdC13cmFwcGVyXCI+XG4gICAgICAgICAgICAgICAgICA8c2VsZWN0IGNsYXNzPVwiZm9ybS1jb250cm9sXCIgZm9ybUNvbnRyb2xOYW1lPVwib2JqZWN0UG9zaXRpb25YXCI+XG4gICAgICAgICAgICAgICAgICAgIDxvcHRpb24gW25nVmFsdWVdPVwiJ2xlZnQnXCI+XG4gICAgICAgICAgICAgICAgICAgICAge3sgJ2xlZnRgaG9yaXpvbnRhbCBhbGlnbm1lbnRgJyB8IHRyYW5zbGF0ZSB9fVxuICAgICAgICAgICAgICAgICAgICA8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiBbbmdWYWx1ZV09XCInY2VudGVyJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgIHt7ICdjZW50ZXJgaG9yaXpvbnRhbCBhbGlnbm1lbnRgJyB8IHRyYW5zbGF0ZSB9fVxuICAgICAgICAgICAgICAgICAgICA8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiBbbmdWYWx1ZV09XCIncmlnaHQnXCI+XG4gICAgICAgICAgICAgICAgICAgICAge3sgJ3JpZ2h0YGhvcml6b250YWwgYWxpZ25tZW50YCcgfCB0cmFuc2xhdGUgfX1cbiAgICAgICAgICAgICAgICAgICAgPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICA8L3NlbGVjdD5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPC9jOHktZm9ybS1ncm91cD5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1tZC02XCI+XG4gICAgICAgICAgICAgIDxjOHktZm9ybS1ncm91cD5cbiAgICAgICAgICAgICAgICA8bGFiZWw+e3sgJ1ZlcnRpY2FsIGFsaWdubWVudCcgfCB0cmFuc2xhdGUgfX08L2xhYmVsPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjOHktc2VsZWN0LXdyYXBwZXJcIj5cbiAgICAgICAgICAgICAgICAgIDxzZWxlY3QgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIiBmb3JtQ29udHJvbE5hbWU9XCJvYmplY3RQb3NpdGlvbllcIj5cbiAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiBbbmdWYWx1ZV09XCIndG9wJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgIHt7ICd0b3BgdmVydGljYWwgYWxpZ25tZW50YCcgfCB0cmFuc2xhdGUgfX1cbiAgICAgICAgICAgICAgICAgICAgPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgIDxvcHRpb24gW25nVmFsdWVdPVwiJ2NlbnRlcidcIj5cbiAgICAgICAgICAgICAgICAgICAgICB7eyAnY2VudGVyYHZlcnRpY2FsIGFsaWdubWVudGAnIHwgdHJhbnNsYXRlIH19XG4gICAgICAgICAgICAgICAgICAgIDwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIFtuZ1ZhbHVlXT1cIidib3R0b20nXCI+XG4gICAgICAgICAgICAgICAgICAgICAge3sgJ2JvdHRvbWB2ZXJ0aWNhbCBhbGlnbm1lbnRgJyB8IHRyYW5zbGF0ZSB9fVxuICAgICAgICAgICAgICAgICAgICA8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8L2M4eS1mb3JtLWdyb3VwPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTZcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImxlZ2VuZCBmb3JtLWJsb2NrXCI+e3sgJ1ByZXZpZXcnIHwgdHJhbnNsYXRlIH19PC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwXCI+XG4gICAgICAgICAgPGRpdlxuICAgICAgICAgICAgY2xhc3M9XCJib3JkZXItdG9wIGJvcmRlci1yaWdodCBib3JkZXItYm90dG9tIGJvcmRlci1sZWZ0IGlubmVyLXNjcm9sbFwiXG4gICAgICAgICAgICBzdHlsZT1cImhlaWdodDogMzAwcHhcIlxuICAgICAgICAgID5cbiAgICAgICAgICAgIDxpbWdcbiAgICAgICAgICAgICAgW3NyY109XCJzcmNcIlxuICAgICAgICAgICAgICBbbmdDbGFzc109XCJzdHlsaW5nID8gJ2ZpdC1oIGZpdC13JyA6ICdpbWctcmVzcG9uc2l2ZSdcIlxuICAgICAgICAgICAgICBbbmdTdHlsZV09XCJzdHlsaW5nXCJcbiAgICAgICAgICAgIC8+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgPC9uZy1jb250YWluZXI+XG4gICAgPGRpdiBjbGFzcz1cImNvbC1tZC0xMiBkLWZsZXggai1jLWNlbnRlclwiICpuZ0lmPVwibG9hZGluZ1wiPlxuICAgICAgPGM4eS1sb2FkaW5nPjwvYzh5LWxvYWRpbmc+XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuPC9kaXY+XG4iXX0=
@@ -1,6 +1,6 @@
1
1
  import { Component, Input } from '@angular/core';
2
- import { DatePipe, MeasurementRealtimeService, NumberPipe } from '@c8y/ngx-components';
3
- import { AsyncPipe, NgFor, NgIf, NgStyle } from '@angular/common';
2
+ import { DatePipe, MeasurementRealtimeService } from '@c8y/ngx-components';
3
+ import { AsyncPipe, DecimalPipe, NgFor, NgIf, NgStyle } from '@angular/common';
4
4
  import { InfoGaugeCurrentMeasurementPipe } from '../current-measurement.pipe';
5
5
  import * as i0 from "@angular/core";
6
6
  export class InfoGaugeWidgetViewComponent {
@@ -20,12 +20,12 @@ export class InfoGaugeWidgetViewComponent {
20
20
  }
21
21
  }
22
22
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: InfoGaugeWidgetViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
23
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.9", type: InfoGaugeWidgetViewComponent, isStandalone: true, selector: "c8y-info-gauge-widget-view", inputs: { config: "config" }, host: { classAttribute: "d-contents" }, providers: [MeasurementRealtimeService], usesOnChanges: true, ngImport: i0, template: "<div class=\"label-value-unit-gauge\">\n <div\n class=\"gauge-legend\"\n *ngIf=\"activeDatapointLabels?.length\"\n >\n <ng-container *ngFor=\"let dp of activeDatapointLabels\">\n <ng-container *ngIf=\"dp | infoGaugeCurrentMeasurement | async as measurement\">\n <label\n class=\"text-truncate\"\n title=\"{{ dp.label }}\"\n >\n {{ dp.label }}\n </label>\n <h3\n class=\"text-truncate\"\n title=\"{{ measurement.value | number: fractionSize }} {{ dp.unit || measurement.unit }}\"\n *ngIf=\"!measurement.notFound; else notFound\"\n >\n {{ measurement.value | number: fractionSize }} {{ dp.unit || measurement.unit }}\n </h3>\n <ng-template #notFound>\n <h3>--</h3>\n </ng-template>\n <p class=\"text-muted m-b-8\">\n <small>\n <em>{{ measurement.date | c8yDate: 'short' }}</em>\n </small>\n </p>\n </ng-container>\n </ng-container>\n </div>\n\n <ng-container *ngIf=\"activeDatapointGauge\">\n <div\n class=\"gauge-svg\"\n *ngIf=\"activeDatapointGauge | infoGaugeCurrentMeasurement: true | async as measurement\"\n >\n <svg\n height=\"214px\"\n width=\"214px\"\n viewBox=\"0 0 214 214\"\n version=\"1.1\"\n xmlns=\"http://www.w3.org/2000/svg\"\n xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n >\n <desc>radial gauge</desc>\n <g\n id=\"scale\"\n stroke=\"none\"\n stroke-width=\"1\"\n fill=\"none\"\n fill-rule=\"evenodd\"\n stroke-dasharray=\"1,5\"\n >\n <circle\n id=\"Oval\"\n stroke=\"#CACECE\"\n stroke-width=\"7\"\n cx=\"107\"\n cy=\"107\"\n r=\"103\"\n ></circle>\n <rect\n id=\"mask\"\n height=\"214\"\n stroke=\"none\"\n fill-rule=\"evenodd\"\n x=\"0\"\n y=\"0\"\n width=\"214\"\n transform=\"rotate(-45 290 182)\"\n ></rect>\n </g>\n <path\n class=\"track\"\n d=\"M 107 27 a 80 80 0 1 0.1 0 Z\"\n transform=\"rotate(-135 107 107)\"\n ></path>\n <path\n class=\"track-value\"\n [ngStyle]=\"{\n stroke: measurement.color,\n 'stroke-dashoffset': -measurement.strokeDashOffset\n }\"\n d=\"M 107 27 a 80 80 0 1 0.1 0 Z\"\n transform=\"rotate(-135 107 107)\"\n ></path>\n <foreignObject\n class=\"d-flex a-i-center j-c-center\"\n height=\"100%\"\n width=\"100%\"\n requiredFeatures=\"http://www.w3.org/TR/SVG11/feature#Extensibility\"\n >\n <div\n class=\"d-flex d-col fit-h a-i-center j-c-center\"\n style=\"padding: 3rem\"\n xmlns=\"http://www.w3.org/1999/xhtml\"\n >\n <p\n class=\"text-truncate text-center\"\n title=\"{{ activeDatapointGauge.label }}\"\n >\n {{ activeDatapointGauge.label }}\n </p>\n <p\n class=\"center-value text-truncate\"\n title=\"{{ measurement.value | number: fractionSize }}\"\n *ngIf=\"!measurement.notFound; else notFoundSVG\"\n >\n {{ measurement.value | number: fractionSize }}\n </p>\n <ng-template #notFoundSVG>\n <p class=\"center-value\">--</p>\n </ng-template>\n <p class=\"center-unit strong\">{{ activeDatapointGauge.unit || measurement.unit }}</p>\n <p class=\"center-date-time\">{{ measurement.date | c8yDate: 'short' }}</p>\n </div>\n </foreignObject>\n </svg>\n </div>\n </ng-container>\n <div class=\"clearfix\"></div>\n</div>\n", dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "pipe", type: InfoGaugeCurrentMeasurementPipe, name: "infoGaugeCurrentMeasurement" }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: DatePipe, name: "c8yDate" }] }); }
23
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.9", type: InfoGaugeWidgetViewComponent, isStandalone: true, selector: "c8y-info-gauge-widget-view", inputs: { config: "config" }, host: { classAttribute: "d-contents" }, providers: [MeasurementRealtimeService], usesOnChanges: true, ngImport: i0, template: "<div class=\"label-value-unit-gauge\">\n <div\n class=\"gauge-legend\"\n *ngIf=\"activeDatapointLabels?.length\"\n >\n <ng-container *ngFor=\"let dp of activeDatapointLabels\">\n <ng-container *ngIf=\"dp | infoGaugeCurrentMeasurement | async as measurement\">\n <label\n class=\"text-truncate\"\n title=\"{{ dp.label }}\"\n >\n {{ dp.label }}\n </label>\n <h3\n class=\"text-truncate\"\n title=\"{{ measurement.value | number: fractionSize }} {{ dp.unit || measurement.unit }}\"\n *ngIf=\"!measurement.notFound; else notFound\"\n >\n {{ measurement.value | number: fractionSize }} {{ dp.unit || measurement.unit }}\n </h3>\n <ng-template #notFound>\n <h3>--</h3>\n </ng-template>\n <p class=\"text-muted m-b-8\">\n <small>\n <em>{{ measurement.date | c8yDate: 'short' }}</em>\n </small>\n </p>\n </ng-container>\n </ng-container>\n </div>\n\n <ng-container *ngIf=\"activeDatapointGauge\">\n <div\n class=\"gauge-svg\"\n *ngIf=\"activeDatapointGauge | infoGaugeCurrentMeasurement: true | async as measurement\"\n >\n <svg\n height=\"214px\"\n width=\"214px\"\n viewBox=\"0 0 214 214\"\n version=\"1.1\"\n xmlns=\"http://www.w3.org/2000/svg\"\n xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n >\n <desc>radial gauge</desc>\n <g\n id=\"scale\"\n stroke=\"none\"\n stroke-width=\"1\"\n fill=\"none\"\n fill-rule=\"evenodd\"\n stroke-dasharray=\"1,5\"\n >\n <circle\n id=\"Oval\"\n stroke=\"#CACECE\"\n stroke-width=\"7\"\n cx=\"107\"\n cy=\"107\"\n r=\"103\"\n ></circle>\n <rect\n id=\"mask\"\n height=\"214\"\n stroke=\"none\"\n fill-rule=\"evenodd\"\n x=\"0\"\n y=\"0\"\n width=\"214\"\n transform=\"rotate(-45 290 182)\"\n ></rect>\n </g>\n <path\n class=\"track\"\n d=\"M 107 27 a 80 80 0 1 0.1 0 Z\"\n transform=\"rotate(-135 107 107)\"\n ></path>\n <path\n class=\"track-value\"\n [ngStyle]=\"{\n stroke: measurement.color,\n 'stroke-dashoffset': -measurement.strokeDashOffset\n }\"\n d=\"M 107 27 a 80 80 0 1 0.1 0 Z\"\n transform=\"rotate(-135 107 107)\"\n ></path>\n <foreignObject\n class=\"d-flex a-i-center j-c-center\"\n height=\"100%\"\n width=\"100%\"\n requiredFeatures=\"http://www.w3.org/TR/SVG11/feature#Extensibility\"\n >\n <div\n class=\"d-flex d-col fit-h a-i-center j-c-center\"\n style=\"padding: 3rem\"\n xmlns=\"http://www.w3.org/1999/xhtml\"\n >\n <p\n class=\"text-truncate text-center\"\n title=\"{{ activeDatapointGauge.label }}\"\n >\n {{ activeDatapointGauge.label }}\n </p>\n <p\n class=\"center-value text-truncate\"\n title=\"{{ measurement.value | number: fractionSize }}\"\n *ngIf=\"!measurement.notFound; else notFoundSVG\"\n >\n {{ measurement.value | number: fractionSize }}\n </p>\n <ng-template #notFoundSVG>\n <p class=\"center-value\">--</p>\n </ng-template>\n <p class=\"center-unit strong\">{{ activeDatapointGauge.unit || measurement.unit }}</p>\n <p class=\"center-date-time\">{{ measurement.date | c8yDate: 'short' }}</p>\n </div>\n </foreignObject>\n </svg>\n </div>\n </ng-container>\n <div class=\"clearfix\"></div>\n</div>\n", dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "pipe", type: InfoGaugeCurrentMeasurementPipe, name: "infoGaugeCurrentMeasurement" }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: DecimalPipe, name: "number" }, { kind: "pipe", type: DatePipe, name: "c8yDate" }] }); }
24
24
  }
25
25
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: InfoGaugeWidgetViewComponent, decorators: [{
26
26
  type: Component,
27
- args: [{ selector: 'c8y-info-gauge-widget-view', host: { class: 'd-contents' }, providers: [MeasurementRealtimeService], standalone: true, imports: [NgIf, NgFor, NgStyle, InfoGaugeCurrentMeasurementPipe, AsyncPipe, NumberPipe, DatePipe], template: "<div class=\"label-value-unit-gauge\">\n <div\n class=\"gauge-legend\"\n *ngIf=\"activeDatapointLabels?.length\"\n >\n <ng-container *ngFor=\"let dp of activeDatapointLabels\">\n <ng-container *ngIf=\"dp | infoGaugeCurrentMeasurement | async as measurement\">\n <label\n class=\"text-truncate\"\n title=\"{{ dp.label }}\"\n >\n {{ dp.label }}\n </label>\n <h3\n class=\"text-truncate\"\n title=\"{{ measurement.value | number: fractionSize }} {{ dp.unit || measurement.unit }}\"\n *ngIf=\"!measurement.notFound; else notFound\"\n >\n {{ measurement.value | number: fractionSize }} {{ dp.unit || measurement.unit }}\n </h3>\n <ng-template #notFound>\n <h3>--</h3>\n </ng-template>\n <p class=\"text-muted m-b-8\">\n <small>\n <em>{{ measurement.date | c8yDate: 'short' }}</em>\n </small>\n </p>\n </ng-container>\n </ng-container>\n </div>\n\n <ng-container *ngIf=\"activeDatapointGauge\">\n <div\n class=\"gauge-svg\"\n *ngIf=\"activeDatapointGauge | infoGaugeCurrentMeasurement: true | async as measurement\"\n >\n <svg\n height=\"214px\"\n width=\"214px\"\n viewBox=\"0 0 214 214\"\n version=\"1.1\"\n xmlns=\"http://www.w3.org/2000/svg\"\n xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n >\n <desc>radial gauge</desc>\n <g\n id=\"scale\"\n stroke=\"none\"\n stroke-width=\"1\"\n fill=\"none\"\n fill-rule=\"evenodd\"\n stroke-dasharray=\"1,5\"\n >\n <circle\n id=\"Oval\"\n stroke=\"#CACECE\"\n stroke-width=\"7\"\n cx=\"107\"\n cy=\"107\"\n r=\"103\"\n ></circle>\n <rect\n id=\"mask\"\n height=\"214\"\n stroke=\"none\"\n fill-rule=\"evenodd\"\n x=\"0\"\n y=\"0\"\n width=\"214\"\n transform=\"rotate(-45 290 182)\"\n ></rect>\n </g>\n <path\n class=\"track\"\n d=\"M 107 27 a 80 80 0 1 0.1 0 Z\"\n transform=\"rotate(-135 107 107)\"\n ></path>\n <path\n class=\"track-value\"\n [ngStyle]=\"{\n stroke: measurement.color,\n 'stroke-dashoffset': -measurement.strokeDashOffset\n }\"\n d=\"M 107 27 a 80 80 0 1 0.1 0 Z\"\n transform=\"rotate(-135 107 107)\"\n ></path>\n <foreignObject\n class=\"d-flex a-i-center j-c-center\"\n height=\"100%\"\n width=\"100%\"\n requiredFeatures=\"http://www.w3.org/TR/SVG11/feature#Extensibility\"\n >\n <div\n class=\"d-flex d-col fit-h a-i-center j-c-center\"\n style=\"padding: 3rem\"\n xmlns=\"http://www.w3.org/1999/xhtml\"\n >\n <p\n class=\"text-truncate text-center\"\n title=\"{{ activeDatapointGauge.label }}\"\n >\n {{ activeDatapointGauge.label }}\n </p>\n <p\n class=\"center-value text-truncate\"\n title=\"{{ measurement.value | number: fractionSize }}\"\n *ngIf=\"!measurement.notFound; else notFoundSVG\"\n >\n {{ measurement.value | number: fractionSize }}\n </p>\n <ng-template #notFoundSVG>\n <p class=\"center-value\">--</p>\n </ng-template>\n <p class=\"center-unit strong\">{{ activeDatapointGauge.unit || measurement.unit }}</p>\n <p class=\"center-date-time\">{{ measurement.date | c8yDate: 'short' }}</p>\n </div>\n </foreignObject>\n </svg>\n </div>\n </ng-container>\n <div class=\"clearfix\"></div>\n</div>\n" }]
27
+ args: [{ selector: 'c8y-info-gauge-widget-view', host: { class: 'd-contents' }, providers: [MeasurementRealtimeService], standalone: true, imports: [NgIf, NgFor, NgStyle, InfoGaugeCurrentMeasurementPipe, AsyncPipe, DecimalPipe, DatePipe], template: "<div class=\"label-value-unit-gauge\">\n <div\n class=\"gauge-legend\"\n *ngIf=\"activeDatapointLabels?.length\"\n >\n <ng-container *ngFor=\"let dp of activeDatapointLabels\">\n <ng-container *ngIf=\"dp | infoGaugeCurrentMeasurement | async as measurement\">\n <label\n class=\"text-truncate\"\n title=\"{{ dp.label }}\"\n >\n {{ dp.label }}\n </label>\n <h3\n class=\"text-truncate\"\n title=\"{{ measurement.value | number: fractionSize }} {{ dp.unit || measurement.unit }}\"\n *ngIf=\"!measurement.notFound; else notFound\"\n >\n {{ measurement.value | number: fractionSize }} {{ dp.unit || measurement.unit }}\n </h3>\n <ng-template #notFound>\n <h3>--</h3>\n </ng-template>\n <p class=\"text-muted m-b-8\">\n <small>\n <em>{{ measurement.date | c8yDate: 'short' }}</em>\n </small>\n </p>\n </ng-container>\n </ng-container>\n </div>\n\n <ng-container *ngIf=\"activeDatapointGauge\">\n <div\n class=\"gauge-svg\"\n *ngIf=\"activeDatapointGauge | infoGaugeCurrentMeasurement: true | async as measurement\"\n >\n <svg\n height=\"214px\"\n width=\"214px\"\n viewBox=\"0 0 214 214\"\n version=\"1.1\"\n xmlns=\"http://www.w3.org/2000/svg\"\n xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n >\n <desc>radial gauge</desc>\n <g\n id=\"scale\"\n stroke=\"none\"\n stroke-width=\"1\"\n fill=\"none\"\n fill-rule=\"evenodd\"\n stroke-dasharray=\"1,5\"\n >\n <circle\n id=\"Oval\"\n stroke=\"#CACECE\"\n stroke-width=\"7\"\n cx=\"107\"\n cy=\"107\"\n r=\"103\"\n ></circle>\n <rect\n id=\"mask\"\n height=\"214\"\n stroke=\"none\"\n fill-rule=\"evenodd\"\n x=\"0\"\n y=\"0\"\n width=\"214\"\n transform=\"rotate(-45 290 182)\"\n ></rect>\n </g>\n <path\n class=\"track\"\n d=\"M 107 27 a 80 80 0 1 0.1 0 Z\"\n transform=\"rotate(-135 107 107)\"\n ></path>\n <path\n class=\"track-value\"\n [ngStyle]=\"{\n stroke: measurement.color,\n 'stroke-dashoffset': -measurement.strokeDashOffset\n }\"\n d=\"M 107 27 a 80 80 0 1 0.1 0 Z\"\n transform=\"rotate(-135 107 107)\"\n ></path>\n <foreignObject\n class=\"d-flex a-i-center j-c-center\"\n height=\"100%\"\n width=\"100%\"\n requiredFeatures=\"http://www.w3.org/TR/SVG11/feature#Extensibility\"\n >\n <div\n class=\"d-flex d-col fit-h a-i-center j-c-center\"\n style=\"padding: 3rem\"\n xmlns=\"http://www.w3.org/1999/xhtml\"\n >\n <p\n class=\"text-truncate text-center\"\n title=\"{{ activeDatapointGauge.label }}\"\n >\n {{ activeDatapointGauge.label }}\n </p>\n <p\n class=\"center-value text-truncate\"\n title=\"{{ measurement.value | number: fractionSize }}\"\n *ngIf=\"!measurement.notFound; else notFoundSVG\"\n >\n {{ measurement.value | number: fractionSize }}\n </p>\n <ng-template #notFoundSVG>\n <p class=\"center-value\">--</p>\n </ng-template>\n <p class=\"center-unit strong\">{{ activeDatapointGauge.unit || measurement.unit }}</p>\n <p class=\"center-date-time\">{{ measurement.date | c8yDate: 'short' }}</p>\n </div>\n </foreignObject>\n </svg>\n </div>\n </ng-container>\n <div class=\"clearfix\"></div>\n</div>\n" }]
28
28
  }], propDecorators: { config: [{
29
29
  type: Input
30
30
  }] } });
31
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5mby1nYXVnZS13aWRnZXQtdmlldy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi93aWRnZXRzL2ltcGxlbWVudGF0aW9ucy9pbmZvLWdhdWdlL2luZm8tZ2F1Z2Utd2lkZ2V0LXZpZXcvaW5mby1nYXVnZS13aWRnZXQtdmlldy5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi93aWRnZXRzL2ltcGxlbWVudGF0aW9ucy9pbmZvLWdhdWdlL2luZm8tZ2F1Z2Utd2lkZ2V0LXZpZXcvaW5mby1nYXVnZS13aWRnZXQtdmlldy5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFhLEtBQUssRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUU1RCxPQUFPLEVBQUUsUUFBUSxFQUFFLDBCQUEwQixFQUFFLFVBQVUsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ3ZGLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNsRSxPQUFPLEVBQUUsK0JBQStCLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQzs7QUFVOUUsTUFBTSxPQUFPLDRCQUE0QjtJQVJ6QztRQWNFLDBCQUFxQixHQUFHLEVBQUUsQ0FBQztRQUUzQixpQkFBWSxHQUFHLE9BQU8sQ0FBQztLQWV4QjtJQWJDLFdBQVc7UUFDVCxJQUFJLElBQUksQ0FBQyxNQUFNLEVBQUUsZ0JBQWdCLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLGdCQUFnQixDQUFDLEVBQUUsQ0FBQztZQUNsRixJQUFJLENBQUMscUJBQXFCLEdBQUcsSUFBSSxDQUFDLE1BQU0sRUFBRSxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDdkYsQ0FBQztRQUVELElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRSxlQUFlLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLGVBQWUsQ0FBQyxFQUFFLENBQUM7WUFDaEYsSUFBSSxDQUFDLG9CQUFvQixHQUFHLElBQUksQ0FBQyxNQUFNLEVBQUUsZUFBZSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUNuRixDQUFDO1FBRUQsSUFBSSxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsWUFBWSxLQUFLLFFBQVEsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsRUFBRSxDQUFDO1lBQzVGLElBQUksQ0FBQyxZQUFZLEdBQUcsS0FBSyxJQUFJLENBQUMsTUFBTSxDQUFDLFlBQVksSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLFlBQVksRUFBRSxDQUFDO1FBQ2xGLENBQUM7SUFDSCxDQUFDOzhHQXRCVSw0QkFBNEI7a0dBQTVCLDRCQUE0QiwrSUFKNUIsQ0FBQywwQkFBMEIsQ0FBQywrQ0NWekMsdzRIQTJIQSw0Q0QvR1ksSUFBSSw2RkFBRSxLQUFLLG1IQUFFLE9BQU8sc0VBQUUsK0JBQStCLCtEQUFFLFNBQVMseUNBQWMsUUFBUTs7MkZBRXJGLDRCQUE0QjtrQkFSeEMsU0FBUzsrQkFDRSw0QkFBNEIsUUFFaEMsRUFBRSxLQUFLLEVBQUUsWUFBWSxFQUFFLGFBQ2xCLENBQUMsMEJBQTBCLENBQUMsY0FDM0IsSUFBSSxXQUNQLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsK0JBQStCLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBRSxRQUFRLENBQUM7OEJBR3hGLE1BQU07c0JBQWQsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgT25DaGFuZ2VzLCBJbnB1dCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHR5cGUgeyBLUElEZXRhaWxzIH0gZnJvbSAnQGM4eS9uZ3gtY29tcG9uZW50cy9kYXRhcG9pbnQtc2VsZWN0b3InO1xuaW1wb3J0IHsgRGF0ZVBpcGUsIE1lYXN1cmVtZW50UmVhbHRpbWVTZXJ2aWNlLCBOdW1iZXJQaXBlIH0gZnJvbSAnQGM4eS9uZ3gtY29tcG9uZW50cyc7XG5pbXBvcnQgeyBBc3luY1BpcGUsIE5nRm9yLCBOZ0lmLCBOZ1N0eWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IEluZm9HYXVnZUN1cnJlbnRNZWFzdXJlbWVudFBpcGUgfSBmcm9tICcuLi9jdXJyZW50LW1lYXN1cmVtZW50LnBpcGUnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdjOHktaW5mby1nYXVnZS13aWRnZXQtdmlldycsXG4gIHRlbXBsYXRlVXJsOiAnLi9pbmZvLWdhdWdlLXdpZGdldC12aWV3LmNvbXBvbmVudC5odG1sJyxcbiAgaG9zdDogeyBjbGFzczogJ2QtY29udGVudHMnIH0sXG4gIHByb3ZpZGVyczogW01lYXN1cmVtZW50UmVhbHRpbWVTZXJ2aWNlXSxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW05nSWYsIE5nRm9yLCBOZ1N0eWxlLCBJbmZvR2F1Z2VDdXJyZW50TWVhc3VyZW1lbnRQaXBlLCBBc3luY1BpcGUsIE51bWJlclBpcGUsIERhdGVQaXBlXVxufSlcbmV4cG9ydCBjbGFzcyBJbmZvR2F1Z2VXaWRnZXRWaWV3Q29tcG9uZW50IGltcGxlbWVudHMgT25DaGFuZ2VzIHtcbiAgQElucHV0KCkgY29uZmlnOiB7XG4gICAgZGF0YXBvaW50c0xhYmVscz86IEtQSURldGFpbHNbXTtcbiAgICBkYXRhcG9pbnRzR2F1Z2U6IEtQSURldGFpbHNbXTtcbiAgICBmcmFjdGlvblNpemU6IG51bWJlcjtcbiAgfTtcbiAgYWN0aXZlRGF0YXBvaW50TGFiZWxzID0gW107XG4gIGFjdGl2ZURhdGFwb2ludEdhdWdlOiBLUElEZXRhaWxzO1xuICBmcmFjdGlvblNpemUgPSAnMS4xLTEnO1xuXG4gIG5nT25DaGFuZ2VzKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmNvbmZpZz8uZGF0YXBvaW50c0xhYmVscyAmJiBBcnJheS5pc0FycmF5KHRoaXMuY29uZmlnPy5kYXRhcG9pbnRzTGFiZWxzKSkge1xuICAgICAgdGhpcy5hY3RpdmVEYXRhcG9pbnRMYWJlbHMgPSB0aGlzLmNvbmZpZz8uZGF0YXBvaW50c0xhYmVscy5maWx0ZXIoZHAgPT4gZHAuX19hY3RpdmUpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmNvbmZpZz8uZGF0YXBvaW50c0dhdWdlICYmIEFycmF5LmlzQXJyYXkodGhpcy5jb25maWc/LmRhdGFwb2ludHNHYXVnZSkpIHtcbiAgICAgIHRoaXMuYWN0aXZlRGF0YXBvaW50R2F1Z2UgPSB0aGlzLmNvbmZpZz8uZGF0YXBvaW50c0dhdWdlLmZpbmQoZHAgPT4gZHAuX19hY3RpdmUpO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgdGhpcy5jb25maWcuZnJhY3Rpb25TaXplID09PSAnbnVtYmVyJyAmJiAhTnVtYmVyLmlzTmFOKHRoaXMuY29uZmlnLmZyYWN0aW9uU2l6ZSkpIHtcbiAgICAgIHRoaXMuZnJhY3Rpb25TaXplID0gYDEuJHt0aGlzLmNvbmZpZy5mcmFjdGlvblNpemV9LSR7dGhpcy5jb25maWcuZnJhY3Rpb25TaXplfWA7XG4gICAgfVxuICB9XG59XG4iLCI8ZGl2IGNsYXNzPVwibGFiZWwtdmFsdWUtdW5pdC1nYXVnZVwiPlxuICA8ZGl2XG4gICAgY2xhc3M9XCJnYXVnZS1sZWdlbmRcIlxuICAgICpuZ0lmPVwiYWN0aXZlRGF0YXBvaW50TGFiZWxzPy5sZW5ndGhcIlxuICA+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgZHAgb2YgYWN0aXZlRGF0YXBvaW50TGFiZWxzXCI+XG4gICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiZHAgfCBpbmZvR2F1Z2VDdXJyZW50TWVhc3VyZW1lbnQgfCBhc3luYyBhcyBtZWFzdXJlbWVudFwiPlxuICAgICAgICA8bGFiZWxcbiAgICAgICAgICBjbGFzcz1cInRleHQtdHJ1bmNhdGVcIlxuICAgICAgICAgIHRpdGxlPVwie3sgZHAubGFiZWwgfX1cIlxuICAgICAgICA+XG4gICAgICAgICAge3sgZHAubGFiZWwgfX1cbiAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgPGgzXG4gICAgICAgICAgY2xhc3M9XCJ0ZXh0LXRydW5jYXRlXCJcbiAgICAgICAgICB0aXRsZT1cInt7IG1lYXN1cmVtZW50LnZhbHVlIHwgbnVtYmVyOiBmcmFjdGlvblNpemUgfX0ge3sgZHAudW5pdCB8fCBtZWFzdXJlbWVudC51bml0IH19XCJcbiAgICAgICAgICAqbmdJZj1cIiFtZWFzdXJlbWVudC5ub3RGb3VuZDsgZWxzZSBub3RGb3VuZFwiXG4gICAgICAgID5cbiAgICAgICAgICB7eyBtZWFzdXJlbWVudC52YWx1ZSB8IG51bWJlcjogZnJhY3Rpb25TaXplIH19IHt7IGRwLnVuaXQgfHwgbWVhc3VyZW1lbnQudW5pdCB9fVxuICAgICAgICA8L2gzPlxuICAgICAgICA8bmctdGVtcGxhdGUgI25vdEZvdW5kPlxuICAgICAgICAgIDxoMz4tLTwvaDM+XG4gICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgIDxwIGNsYXNzPVwidGV4dC1tdXRlZCBtLWItOFwiPlxuICAgICAgICAgIDxzbWFsbD5cbiAgICAgICAgICAgIDxlbT57eyBtZWFzdXJlbWVudC5kYXRlIHwgYzh5RGF0ZTogJ3Nob3J0JyB9fTwvZW0+XG4gICAgICAgICAgPC9zbWFsbD5cbiAgICAgICAgPC9wPlxuICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgPC9uZy1jb250YWluZXI+XG4gIDwvZGl2PlxuXG4gIDxuZy1jb250YWluZXIgKm5nSWY9XCJhY3RpdmVEYXRhcG9pbnRHYXVnZVwiPlxuICAgIDxkaXZcbiAgICAgIGNsYXNzPVwiZ2F1Z2Utc3ZnXCJcbiAgICAgICpuZ0lmPVwiYWN0aXZlRGF0YXBvaW50R2F1Z2UgfCBpbmZvR2F1Z2VDdXJyZW50TWVhc3VyZW1lbnQ6IHRydWUgfCBhc3luYyBhcyBtZWFzdXJlbWVudFwiXG4gICAgPlxuICAgICAgPHN2Z1xuICAgICAgICBoZWlnaHQ9XCIyMTRweFwiXG4gICAgICAgIHdpZHRoPVwiMjE0cHhcIlxuICAgICAgICB2aWV3Qm94PVwiMCAwIDIxNCAyMTRcIlxuICAgICAgICB2ZXJzaW9uPVwiMS4xXCJcbiAgICAgICAgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiXG4gICAgICAgIHhtbG5zOnhsaW5rPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGlua1wiXG4gICAgICA+XG4gICAgICAgIDxkZXNjPnJhZGlhbCBnYXVnZTwvZGVzYz5cbiAgICAgICAgPGdcbiAgICAgICAgICBpZD1cInNjYWxlXCJcbiAgICAgICAgICBzdHJva2U9XCJub25lXCJcbiAgICAgICAgICBzdHJva2Utd2lkdGg9XCIxXCJcbiAgICAgICAgICBmaWxsPVwibm9uZVwiXG4gICAgICAgICAgZmlsbC1ydWxlPVwiZXZlbm9kZFwiXG4gICAgICAgICAgc3Ryb2tlLWRhc2hhcnJheT1cIjEsNVwiXG4gICAgICAgID5cbiAgICAgICAgICA8Y2lyY2xlXG4gICAgICAgICAgICBpZD1cIk92YWxcIlxuICAgICAgICAgICAgc3Ryb2tlPVwiI0NBQ0VDRVwiXG4gICAgICAgICAgICBzdHJva2Utd2lkdGg9XCI3XCJcbiAgICAgICAgICAgIGN4PVwiMTA3XCJcbiAgICAgICAgICAgIGN5PVwiMTA3XCJcbiAgICAgICAgICAgIHI9XCIxMDNcIlxuICAgICAgICAgID48L2NpcmNsZT5cbiAgICAgICAgICA8cmVjdFxuICAgICAgICAgICAgaWQ9XCJtYXNrXCJcbiAgICAgICAgICAgIGhlaWdodD1cIjIxNFwiXG4gICAgICAgICAgICBzdHJva2U9XCJub25lXCJcbiAgICAgICAgICAgIGZpbGwtcnVsZT1cImV2ZW5vZGRcIlxuICAgICAgICAgICAgeD1cIjBcIlxuICAgICAgICAgICAgeT1cIjBcIlxuICAgICAgICAgICAgd2lkdGg9XCIyMTRcIlxuICAgICAgICAgICAgdHJhbnNmb3JtPVwicm90YXRlKC00NSAyOTAgMTgyKVwiXG4gICAgICAgICAgPjwvcmVjdD5cbiAgICAgICAgPC9nPlxuICAgICAgICA8cGF0aFxuICAgICAgICAgIGNsYXNzPVwidHJhY2tcIlxuICAgICAgICAgIGQ9XCJNIDEwNyAyNyBhIDgwIDgwIDAgMSAwLjEgMCBaXCJcbiAgICAgICAgICB0cmFuc2Zvcm09XCJyb3RhdGUoLTEzNSAxMDcgMTA3KVwiXG4gICAgICAgID48L3BhdGg+XG4gICAgICAgIDxwYXRoXG4gICAgICAgICAgY2xhc3M9XCJ0cmFjay12YWx1ZVwiXG4gICAgICAgICAgW25nU3R5bGVdPVwie1xuICAgICAgICAgICAgc3Ryb2tlOiBtZWFzdXJlbWVudC5jb2xvcixcbiAgICAgICAgICAgICdzdHJva2UtZGFzaG9mZnNldCc6IC1tZWFzdXJlbWVudC5zdHJva2VEYXNoT2Zmc2V0XG4gICAgICAgICAgfVwiXG4gICAgICAgICAgZD1cIk0gMTA3IDI3IGEgODAgODAgMCAxIDAuMSAwIFpcIlxuICAgICAgICAgIHRyYW5zZm9ybT1cInJvdGF0ZSgtMTM1IDEwNyAxMDcpXCJcbiAgICAgICAgPjwvcGF0aD5cbiAgICAgICAgPGZvcmVpZ25PYmplY3RcbiAgICAgICAgICBjbGFzcz1cImQtZmxleCBhLWktY2VudGVyIGotYy1jZW50ZXJcIlxuICAgICAgICAgIGhlaWdodD1cIjEwMCVcIlxuICAgICAgICAgIHdpZHRoPVwiMTAwJVwiXG4gICAgICAgICAgcmVxdWlyZWRGZWF0dXJlcz1cImh0dHA6Ly93d3cudzMub3JnL1RSL1NWRzExL2ZlYXR1cmUjRXh0ZW5zaWJpbGl0eVwiXG4gICAgICAgID5cbiAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICBjbGFzcz1cImQtZmxleCBkLWNvbCBmaXQtaCBhLWktY2VudGVyIGotYy1jZW50ZXJcIlxuICAgICAgICAgICAgc3R5bGU9XCJwYWRkaW5nOiAzcmVtXCJcbiAgICAgICAgICAgIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbFwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPHBcbiAgICAgICAgICAgICAgY2xhc3M9XCJ0ZXh0LXRydW5jYXRlIHRleHQtY2VudGVyXCJcbiAgICAgICAgICAgICAgdGl0bGU9XCJ7eyBhY3RpdmVEYXRhcG9pbnRHYXVnZS5sYWJlbCB9fVwiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIHt7IGFjdGl2ZURhdGFwb2ludEdhdWdlLmxhYmVsIH19XG4gICAgICAgICAgICA8L3A+XG4gICAgICAgICAgICA8cFxuICAgICAgICAgICAgICBjbGFzcz1cImNlbnRlci12YWx1ZSB0ZXh0LXRydW5jYXRlXCJcbiAgICAgICAgICAgICAgdGl0bGU9XCJ7eyBtZWFzdXJlbWVudC52YWx1ZSB8IG51bWJlcjogZnJhY3Rpb25TaXplIH19XCJcbiAgICAgICAgICAgICAgKm5nSWY9XCIhbWVhc3VyZW1lbnQubm90Rm91bmQ7IGVsc2Ugbm90Rm91bmRTVkdcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICB7eyBtZWFzdXJlbWVudC52YWx1ZSB8IG51bWJlcjogZnJhY3Rpb25TaXplIH19XG4gICAgICAgICAgICA8L3A+XG4gICAgICAgICAgICA8bmctdGVtcGxhdGUgI25vdEZvdW5kU1ZHPlxuICAgICAgICAgICAgICA8cCBjbGFzcz1cImNlbnRlci12YWx1ZVwiPi0tPC9wPlxuICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgIDxwIGNsYXNzPVwiY2VudGVyLXVuaXQgc3Ryb25nXCI+e3sgYWN0aXZlRGF0YXBvaW50R2F1Z2UudW5pdCB8fCBtZWFzdXJlbWVudC51bml0IH19PC9wPlxuICAgICAgICAgICAgPHAgY2xhc3M9XCJjZW50ZXItZGF0ZS10aW1lXCI+e3sgbWVhc3VyZW1lbnQuZGF0ZSB8IGM4eURhdGU6ICdzaG9ydCcgfX08L3A+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZm9yZWlnbk9iamVjdD5cbiAgICAgIDwvc3ZnPlxuICAgIDwvZGl2PlxuICA8L25nLWNvbnRhaW5lcj5cbiAgPGRpdiBjbGFzcz1cImNsZWFyZml4XCI+PC9kaXY+XG48L2Rpdj5cbiJdfQ==
31
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5mby1nYXVnZS13aWRnZXQtdmlldy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi93aWRnZXRzL2ltcGxlbWVudGF0aW9ucy9pbmZvLWdhdWdlL2luZm8tZ2F1Z2Utd2lkZ2V0LXZpZXcvaW5mby1nYXVnZS13aWRnZXQtdmlldy5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi93aWRnZXRzL2ltcGxlbWVudGF0aW9ucy9pbmZvLWdhdWdlL2luZm8tZ2F1Z2Utd2lkZ2V0LXZpZXcvaW5mby1nYXVnZS13aWRnZXQtdmlldy5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFhLEtBQUssRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUU1RCxPQUFPLEVBQUUsUUFBUSxFQUFFLDBCQUEwQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDM0UsT0FBTyxFQUFFLFNBQVMsRUFBRSxXQUFXLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvRSxPQUFPLEVBQUUsK0JBQStCLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQzs7QUFVOUUsTUFBTSxPQUFPLDRCQUE0QjtJQVJ6QztRQWNFLDBCQUFxQixHQUFHLEVBQUUsQ0FBQztRQUUzQixpQkFBWSxHQUFHLE9BQU8sQ0FBQztLQWV4QjtJQWJDLFdBQVc7UUFDVCxJQUFJLElBQUksQ0FBQyxNQUFNLEVBQUUsZ0JBQWdCLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLGdCQUFnQixDQUFDLEVBQUUsQ0FBQztZQUNsRixJQUFJLENBQUMscUJBQXFCLEdBQUcsSUFBSSxDQUFDLE1BQU0sRUFBRSxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDdkYsQ0FBQztRQUVELElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRSxlQUFlLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLGVBQWUsQ0FBQyxFQUFFLENBQUM7WUFDaEYsSUFBSSxDQUFDLG9CQUFvQixHQUFHLElBQUksQ0FBQyxNQUFNLEVBQUUsZUFBZSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUNuRixDQUFDO1FBRUQsSUFBSSxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsWUFBWSxLQUFLLFFBQVEsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsRUFBRSxDQUFDO1lBQzVGLElBQUksQ0FBQyxZQUFZLEdBQUcsS0FBSyxJQUFJLENBQUMsTUFBTSxDQUFDLFlBQVksSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLFlBQVksRUFBRSxDQUFDO1FBQ2xGLENBQUM7SUFDSCxDQUFDOzhHQXRCVSw0QkFBNEI7a0dBQTVCLDRCQUE0QiwrSUFKNUIsQ0FBQywwQkFBMEIsQ0FBQywrQ0NWekMsdzRIQTJIQSw0Q0QvR1ksSUFBSSw2RkFBRSxLQUFLLG1IQUFFLE9BQU8sc0VBQUUsK0JBQStCLCtEQUFFLFNBQVMseUNBQUUsV0FBVywwQ0FBRSxRQUFROzsyRkFFdEYsNEJBQTRCO2tCQVJ4QyxTQUFTOytCQUNFLDRCQUE0QixRQUVoQyxFQUFFLEtBQUssRUFBRSxZQUFZLEVBQUUsYUFDbEIsQ0FBQywwQkFBMEIsQ0FBQyxjQUMzQixJQUFJLFdBQ1AsQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSwrQkFBK0IsRUFBRSxTQUFTLEVBQUUsV0FBVyxFQUFFLFFBQVEsQ0FBQzs4QkFHekYsTUFBTTtzQkFBZCxLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBPbkNoYW5nZXMsIElucHV0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgdHlwZSB7IEtQSURldGFpbHMgfSBmcm9tICdAYzh5L25neC1jb21wb25lbnRzL2RhdGFwb2ludC1zZWxlY3Rvcic7XG5pbXBvcnQgeyBEYXRlUGlwZSwgTWVhc3VyZW1lbnRSZWFsdGltZVNlcnZpY2UgfSBmcm9tICdAYzh5L25neC1jb21wb25lbnRzJztcbmltcG9ydCB7IEFzeW5jUGlwZSwgRGVjaW1hbFBpcGUsIE5nRm9yLCBOZ0lmLCBOZ1N0eWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IEluZm9HYXVnZUN1cnJlbnRNZWFzdXJlbWVudFBpcGUgfSBmcm9tICcuLi9jdXJyZW50LW1lYXN1cmVtZW50LnBpcGUnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdjOHktaW5mby1nYXVnZS13aWRnZXQtdmlldycsXG4gIHRlbXBsYXRlVXJsOiAnLi9pbmZvLWdhdWdlLXdpZGdldC12aWV3LmNvbXBvbmVudC5odG1sJyxcbiAgaG9zdDogeyBjbGFzczogJ2QtY29udGVudHMnIH0sXG4gIHByb3ZpZGVyczogW01lYXN1cmVtZW50UmVhbHRpbWVTZXJ2aWNlXSxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW05nSWYsIE5nRm9yLCBOZ1N0eWxlLCBJbmZvR2F1Z2VDdXJyZW50TWVhc3VyZW1lbnRQaXBlLCBBc3luY1BpcGUsIERlY2ltYWxQaXBlLCBEYXRlUGlwZV1cbn0pXG5leHBvcnQgY2xhc3MgSW5mb0dhdWdlV2lkZ2V0Vmlld0NvbXBvbmVudCBpbXBsZW1lbnRzIE9uQ2hhbmdlcyB7XG4gIEBJbnB1dCgpIGNvbmZpZzoge1xuICAgIGRhdGFwb2ludHNMYWJlbHM/OiBLUElEZXRhaWxzW107XG4gICAgZGF0YXBvaW50c0dhdWdlOiBLUElEZXRhaWxzW107XG4gICAgZnJhY3Rpb25TaXplOiBudW1iZXI7XG4gIH07XG4gIGFjdGl2ZURhdGFwb2ludExhYmVscyA9IFtdO1xuICBhY3RpdmVEYXRhcG9pbnRHYXVnZTogS1BJRGV0YWlscztcbiAgZnJhY3Rpb25TaXplID0gJzEuMS0xJztcblxuICBuZ09uQ2hhbmdlcygpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5jb25maWc/LmRhdGFwb2ludHNMYWJlbHMgJiYgQXJyYXkuaXNBcnJheSh0aGlzLmNvbmZpZz8uZGF0YXBvaW50c0xhYmVscykpIHtcbiAgICAgIHRoaXMuYWN0aXZlRGF0YXBvaW50TGFiZWxzID0gdGhpcy5jb25maWc/LmRhdGFwb2ludHNMYWJlbHMuZmlsdGVyKGRwID0+IGRwLl9fYWN0aXZlKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5jb25maWc/LmRhdGFwb2ludHNHYXVnZSAmJiBBcnJheS5pc0FycmF5KHRoaXMuY29uZmlnPy5kYXRhcG9pbnRzR2F1Z2UpKSB7XG4gICAgICB0aGlzLmFjdGl2ZURhdGFwb2ludEdhdWdlID0gdGhpcy5jb25maWc/LmRhdGFwb2ludHNHYXVnZS5maW5kKGRwID0+IGRwLl9fYWN0aXZlKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIHRoaXMuY29uZmlnLmZyYWN0aW9uU2l6ZSA9PT0gJ251bWJlcicgJiYgIU51bWJlci5pc05hTih0aGlzLmNvbmZpZy5mcmFjdGlvblNpemUpKSB7XG4gICAgICB0aGlzLmZyYWN0aW9uU2l6ZSA9IGAxLiR7dGhpcy5jb25maWcuZnJhY3Rpb25TaXplfS0ke3RoaXMuY29uZmlnLmZyYWN0aW9uU2l6ZX1gO1xuICAgIH1cbiAgfVxufVxuIiwiPGRpdiBjbGFzcz1cImxhYmVsLXZhbHVlLXVuaXQtZ2F1Z2VcIj5cbiAgPGRpdlxuICAgIGNsYXNzPVwiZ2F1Z2UtbGVnZW5kXCJcbiAgICAqbmdJZj1cImFjdGl2ZURhdGFwb2ludExhYmVscz8ubGVuZ3RoXCJcbiAgPlxuICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGRwIG9mIGFjdGl2ZURhdGFwb2ludExhYmVsc1wiPlxuICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImRwIHwgaW5mb0dhdWdlQ3VycmVudE1lYXN1cmVtZW50IHwgYXN5bmMgYXMgbWVhc3VyZW1lbnRcIj5cbiAgICAgICAgPGxhYmVsXG4gICAgICAgICAgY2xhc3M9XCJ0ZXh0LXRydW5jYXRlXCJcbiAgICAgICAgICB0aXRsZT1cInt7IGRwLmxhYmVsIH19XCJcbiAgICAgICAgPlxuICAgICAgICAgIHt7IGRwLmxhYmVsIH19XG4gICAgICAgIDwvbGFiZWw+XG4gICAgICAgIDxoM1xuICAgICAgICAgIGNsYXNzPVwidGV4dC10cnVuY2F0ZVwiXG4gICAgICAgICAgdGl0bGU9XCJ7eyBtZWFzdXJlbWVudC52YWx1ZSB8IG51bWJlcjogZnJhY3Rpb25TaXplIH19IHt7IGRwLnVuaXQgfHwgbWVhc3VyZW1lbnQudW5pdCB9fVwiXG4gICAgICAgICAgKm5nSWY9XCIhbWVhc3VyZW1lbnQubm90Rm91bmQ7IGVsc2Ugbm90Rm91bmRcIlxuICAgICAgICA+XG4gICAgICAgICAge3sgbWVhc3VyZW1lbnQudmFsdWUgfCBudW1iZXI6IGZyYWN0aW9uU2l6ZSB9fSB7eyBkcC51bml0IHx8IG1lYXN1cmVtZW50LnVuaXQgfX1cbiAgICAgICAgPC9oMz5cbiAgICAgICAgPG5nLXRlbXBsYXRlICNub3RGb3VuZD5cbiAgICAgICAgICA8aDM+LS08L2gzPlxuICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICA8cCBjbGFzcz1cInRleHQtbXV0ZWQgbS1iLThcIj5cbiAgICAgICAgICA8c21hbGw+XG4gICAgICAgICAgICA8ZW0+e3sgbWVhc3VyZW1lbnQuZGF0ZSB8IGM4eURhdGU6ICdzaG9ydCcgfX08L2VtPlxuICAgICAgICAgIDwvc21hbGw+XG4gICAgICAgIDwvcD5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuICAgIDwvbmctY29udGFpbmVyPlxuICA8L2Rpdj5cblxuICA8bmctY29udGFpbmVyICpuZ0lmPVwiYWN0aXZlRGF0YXBvaW50R2F1Z2VcIj5cbiAgICA8ZGl2XG4gICAgICBjbGFzcz1cImdhdWdlLXN2Z1wiXG4gICAgICAqbmdJZj1cImFjdGl2ZURhdGFwb2ludEdhdWdlIHwgaW5mb0dhdWdlQ3VycmVudE1lYXN1cmVtZW50OiB0cnVlIHwgYXN5bmMgYXMgbWVhc3VyZW1lbnRcIlxuICAgID5cbiAgICAgIDxzdmdcbiAgICAgICAgaGVpZ2h0PVwiMjE0cHhcIlxuICAgICAgICB3aWR0aD1cIjIxNHB4XCJcbiAgICAgICAgdmlld0JveD1cIjAgMCAyMTQgMjE0XCJcbiAgICAgICAgdmVyc2lvbj1cIjEuMVwiXG4gICAgICAgIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIlxuICAgICAgICB4bWxuczp4bGluaz1cImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmtcIlxuICAgICAgPlxuICAgICAgICA8ZGVzYz5yYWRpYWwgZ2F1Z2U8L2Rlc2M+XG4gICAgICAgIDxnXG4gICAgICAgICAgaWQ9XCJzY2FsZVwiXG4gICAgICAgICAgc3Ryb2tlPVwibm9uZVwiXG4gICAgICAgICAgc3Ryb2tlLXdpZHRoPVwiMVwiXG4gICAgICAgICAgZmlsbD1cIm5vbmVcIlxuICAgICAgICAgIGZpbGwtcnVsZT1cImV2ZW5vZGRcIlxuICAgICAgICAgIHN0cm9rZS1kYXNoYXJyYXk9XCIxLDVcIlxuICAgICAgICA+XG4gICAgICAgICAgPGNpcmNsZVxuICAgICAgICAgICAgaWQ9XCJPdmFsXCJcbiAgICAgICAgICAgIHN0cm9rZT1cIiNDQUNFQ0VcIlxuICAgICAgICAgICAgc3Ryb2tlLXdpZHRoPVwiN1wiXG4gICAgICAgICAgICBjeD1cIjEwN1wiXG4gICAgICAgICAgICBjeT1cIjEwN1wiXG4gICAgICAgICAgICByPVwiMTAzXCJcbiAgICAgICAgICA+PC9jaXJjbGU+XG4gICAgICAgICAgPHJlY3RcbiAgICAgICAgICAgIGlkPVwibWFza1wiXG4gICAgICAgICAgICBoZWlnaHQ9XCIyMTRcIlxuICAgICAgICAgICAgc3Ryb2tlPVwibm9uZVwiXG4gICAgICAgICAgICBmaWxsLXJ1bGU9XCJldmVub2RkXCJcbiAgICAgICAgICAgIHg9XCIwXCJcbiAgICAgICAgICAgIHk9XCIwXCJcbiAgICAgICAgICAgIHdpZHRoPVwiMjE0XCJcbiAgICAgICAgICAgIHRyYW5zZm9ybT1cInJvdGF0ZSgtNDUgMjkwIDE4MilcIlxuICAgICAgICAgID48L3JlY3Q+XG4gICAgICAgIDwvZz5cbiAgICAgICAgPHBhdGhcbiAgICAgICAgICBjbGFzcz1cInRyYWNrXCJcbiAgICAgICAgICBkPVwiTSAxMDcgMjcgYSA4MCA4MCAwIDEgMC4xIDAgWlwiXG4gICAgICAgICAgdHJhbnNmb3JtPVwicm90YXRlKC0xMzUgMTA3IDEwNylcIlxuICAgICAgICA+PC9wYXRoPlxuICAgICAgICA8cGF0aFxuICAgICAgICAgIGNsYXNzPVwidHJhY2stdmFsdWVcIlxuICAgICAgICAgIFtuZ1N0eWxlXT1cIntcbiAgICAgICAgICAgIHN0cm9rZTogbWVhc3VyZW1lbnQuY29sb3IsXG4gICAgICAgICAgICAnc3Ryb2tlLWRhc2hvZmZzZXQnOiAtbWVhc3VyZW1lbnQuc3Ryb2tlRGFzaE9mZnNldFxuICAgICAgICAgIH1cIlxuICAgICAgICAgIGQ9XCJNIDEwNyAyNyBhIDgwIDgwIDAgMSAwLjEgMCBaXCJcbiAgICAgICAgICB0cmFuc2Zvcm09XCJyb3RhdGUoLTEzNSAxMDcgMTA3KVwiXG4gICAgICAgID48L3BhdGg+XG4gICAgICAgIDxmb3JlaWduT2JqZWN0XG4gICAgICAgICAgY2xhc3M9XCJkLWZsZXggYS1pLWNlbnRlciBqLWMtY2VudGVyXCJcbiAgICAgICAgICBoZWlnaHQ9XCIxMDAlXCJcbiAgICAgICAgICB3aWR0aD1cIjEwMCVcIlxuICAgICAgICAgIHJlcXVpcmVkRmVhdHVyZXM9XCJodHRwOi8vd3d3LnczLm9yZy9UUi9TVkcxMS9mZWF0dXJlI0V4dGVuc2liaWxpdHlcIlxuICAgICAgICA+XG4gICAgICAgICAgPGRpdlxuICAgICAgICAgICAgY2xhc3M9XCJkLWZsZXggZC1jb2wgZml0LWggYS1pLWNlbnRlciBqLWMtY2VudGVyXCJcbiAgICAgICAgICAgIHN0eWxlPVwicGFkZGluZzogM3JlbVwiXG4gICAgICAgICAgICB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWxcIlxuICAgICAgICAgID5cbiAgICAgICAgICAgIDxwXG4gICAgICAgICAgICAgIGNsYXNzPVwidGV4dC10cnVuY2F0ZSB0ZXh0LWNlbnRlclwiXG4gICAgICAgICAgICAgIHRpdGxlPVwie3sgYWN0aXZlRGF0YXBvaW50R2F1Z2UubGFiZWwgfX1cIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICB7eyBhY3RpdmVEYXRhcG9pbnRHYXVnZS5sYWJlbCB9fVxuICAgICAgICAgICAgPC9wPlxuICAgICAgICAgICAgPHBcbiAgICAgICAgICAgICAgY2xhc3M9XCJjZW50ZXItdmFsdWUgdGV4dC10cnVuY2F0ZVwiXG4gICAgICAgICAgICAgIHRpdGxlPVwie3sgbWVhc3VyZW1lbnQudmFsdWUgfCBudW1iZXI6IGZyYWN0aW9uU2l6ZSB9fVwiXG4gICAgICAgICAgICAgICpuZ0lmPVwiIW1lYXN1cmVtZW50Lm5vdEZvdW5kOyBlbHNlIG5vdEZvdW5kU1ZHXCJcbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAge3sgbWVhc3VyZW1lbnQudmFsdWUgfCBudW1iZXI6IGZyYWN0aW9uU2l6ZSB9fVxuICAgICAgICAgICAgPC9wPlxuICAgICAgICAgICAgPG5nLXRlbXBsYXRlICNub3RGb3VuZFNWRz5cbiAgICAgICAgICAgICAgPHAgY2xhc3M9XCJjZW50ZXItdmFsdWVcIj4tLTwvcD5cbiAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICA8cCBjbGFzcz1cImNlbnRlci11bml0IHN0cm9uZ1wiPnt7IGFjdGl2ZURhdGFwb2ludEdhdWdlLnVuaXQgfHwgbWVhc3VyZW1lbnQudW5pdCB9fTwvcD5cbiAgICAgICAgICAgIDxwIGNsYXNzPVwiY2VudGVyLWRhdGUtdGltZVwiPnt7IG1lYXN1cmVtZW50LmRhdGUgfCBjOHlEYXRlOiAnc2hvcnQnIH19PC9wPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2ZvcmVpZ25PYmplY3Q+XG4gICAgICA8L3N2Zz5cbiAgICA8L2Rpdj5cbiAgPC9uZy1jb250YWluZXI+XG4gIDxkaXYgY2xhc3M9XCJjbGVhcmZpeFwiPjwvZGl2PlxuPC9kaXY+XG4iXX0=
@@ -6,7 +6,7 @@ import * as i1 from '@c8y/client';
6
6
  import * as i2 from '@c8y/ngx-components';
7
7
  import { gettext, LoadingComponent, EmptyStateComponent, C8yValidators, FormGroupComponent, MessagesComponent, MessageDirective, C8yTranslatePipe, DropAreaComponent } from '@c8y/ngx-components';
8
8
  import * as i3 from '@ngx-translate/core';
9
- import { NgIf, NgClass, AsyncPipe, NgStyle } from '@angular/common';
9
+ import { NgIf, NgClass, AsyncPipe, NgStyle, NgForOf } from '@angular/common';
10
10
  import * as i4 from '@c8y/ngx-components/context-dashboard';
11
11
  import { get } from 'lodash-es';
12
12
  import * as i1$1 from '@angular/forms';
@@ -211,7 +211,7 @@ class ImageWidgetConfigComponent {
211
211
  this.styling = this.imageWidget.getStyling(config);
212
212
  }
213
213
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: ImageWidgetConfigComponent, deps: [{ token: i1$1.FormBuilder }, { token: i1$1.NgForm }, { token: i2.FilesService }, { token: i2.AlertService }, { token: ImageWidgetService }, { token: i4.WidgetConfigComponent, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
214
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.9", type: ImageWidgetConfigComponent, isStandalone: true, selector: "c8y-image-widget-config", inputs: { config: "config" }, ngImport: i0, template: "<div class=\"p-l-24 p-r-24\">\n <div [formGroup]=\"formGroup\" class=\"row p-t-8\">\n <div class=\"col-md-12\">\n <c8y-form-group>\n <label>{{ 'Image' | translate }}</label>\n <c8y-drop-area\n formControlName=\"images\"\n class=\"drop-area-sm\"\n [icon]=\"'upload'\"\n [accept]=\"'image'\"\n [maxAllowedFiles]=\"1\"\n ></c8y-drop-area>\n <c8y-messages>\n <c8y-message\n name=\"maxFileSizeReached\"\n [text]=\"\n 'The maximum image size is {{ maxFileSize }} kB. The selected image has a size of {{ actualFileSize }} kB.'\n | translate\n \"\n ></c8y-message>\n <c8y-message\n name=\"wrongFileType\"\n [text]=\"'Wrong file type, select an image.' | translate\"\n ></c8y-message>\n <c8y-message name=\"maxlength\" [text]=\"'Only select one image.' | translate\"></c8y-message>\n <c8y-message name=\"required\" [text]=\"'An image is required.' | translate\"></c8y-message>\n <c8y-message name=\"minlength\" [text]=\"'An image is required.' | translate\"></c8y-message>\n </c8y-messages>\n </c8y-form-group>\n </div>\n <ng-container *ngIf=\"imageSrc$ | async as src\">\n <div class=\"col-md-6\">\n <div class=\"legend form-block\">\n {{ 'Size and alignment' | translate }}\n </div>\n <div [formGroupName]=\"'styling'\">\n <c8y-form-group>\n <label>\n {{ 'Image display' | translate }}\n </label>\n <ul class=\"list-group separator-top-bottom\">\n <li\n class=\"list-group-item d-flex a-i-center p-l-0\"\n *ngFor=\"let objectFitOption of objectFitOptions; let i = index\"\n >\n <label class=\"c8y-radio\">\n <input\n type=\"radio\"\n [id]=\"'groupradiocontentclass' + i\"\n formControlName=\"objectFit\"\n [value]=\"objectFitOption.value\"\n />\n <span></span>\n <span class=\"l-h-1\">\n {{ objectFitOption.label | translate }}\n <br />\n <small class=\"text-muted\">\n {{ objectFitOption.description | translate }}\n </small>\n </span>\n </label>\n </li>\n </ul>\n </c8y-form-group>\n <div class=\"row\">\n <div class=\"col-md-6\">\n <c8y-form-group>\n <label>{{ 'Horizontal alignment' | translate }}</label>\n <div class=\"c8y-select-wrapper\">\n <select class=\"form-control\" formControlName=\"objectPositionX\">\n <option [ngValue]=\"'left'\">\n {{ 'left`horizontal alignment`' | translate }}\n </option>\n <option [ngValue]=\"'center'\">\n {{ 'center`horizontal alignment`' | translate }}\n </option>\n <option [ngValue]=\"'right'\">\n {{ 'right`horizontal alignment`' | translate }}\n </option>\n </select>\n </div>\n </c8y-form-group>\n </div>\n <div class=\"col-md-6\">\n <c8y-form-group>\n <label>{{ 'Vertical alignment' | translate }}</label>\n <div class=\"c8y-select-wrapper\">\n <select class=\"form-control\" formControlName=\"objectPositionY\">\n <option [ngValue]=\"'top'\">\n {{ 'top`vertical alignment`' | translate }}\n </option>\n <option [ngValue]=\"'center'\">\n {{ 'center`vertical alignment`' | translate }}\n </option>\n <option [ngValue]=\"'bottom'\">\n {{ 'bottom`vertical alignment`' | translate }}\n </option>\n </select>\n </div>\n </c8y-form-group>\n </div>\n </div>\n </div>\n </div>\n <div class=\"col-md-6\">\n <div class=\"legend form-block\">{{ 'Preview' | translate }}</div>\n <div class=\"form-group\">\n <div\n class=\"border-top border-right border-bottom border-left inner-scroll\"\n style=\"height: 300px\"\n >\n <img\n [src]=\"src\"\n [ngClass]=\"styling ? 'fit-h fit-w' : 'img-responsive'\"\n [ngStyle]=\"styling\"\n />\n </div>\n </div>\n </div>\n </ng-container>\n <div class=\"col-md-12 d-flex j-c-center\" *ngIf=\"loading\">\n <c8y-loading></c8y-loading>\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$1.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: i1$1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1$1.RadioControlValueAccessor, selector: "input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1$1.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "component", type: FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "component", type: MessagesComponent, selector: "c8y-messages", inputs: ["show", "defaults", "helpMessage"] }, { kind: "directive", type: MessageDirective, selector: "c8y-message", inputs: ["name", "text"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "component", type: DropAreaComponent, selector: "c8y-drop-area", inputs: ["formControl", "title", "message", "icon", "loadingMessage", "forceHideList", "alwaysShow", "clickToOpen", "loading", "progress", "maxAllowedFiles", "files", "maxFileSizeInMegaBytes", "accept"], outputs: ["dropped"] }], viewProviders: [{ provide: ControlContainer, useExisting: NgForm }] }); }
214
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.9", type: ImageWidgetConfigComponent, isStandalone: true, selector: "c8y-image-widget-config", inputs: { config: "config" }, ngImport: i0, template: "<div class=\"p-l-24 p-r-24\">\n <div [formGroup]=\"formGroup\" class=\"row p-t-8\">\n <div class=\"col-md-12\">\n <c8y-form-group>\n <label>{{ 'Image' | translate }}</label>\n <c8y-drop-area\n formControlName=\"images\"\n class=\"drop-area-sm\"\n [icon]=\"'upload'\"\n [accept]=\"'image'\"\n [maxAllowedFiles]=\"1\"\n ></c8y-drop-area>\n <c8y-messages>\n <c8y-message\n name=\"maxFileSizeReached\"\n [text]=\"\n 'The maximum image size is {{ maxFileSize }} kB. The selected image has a size of {{ actualFileSize }} kB.'\n | translate\n \"\n ></c8y-message>\n <c8y-message\n name=\"wrongFileType\"\n [text]=\"'Wrong file type, select an image.' | translate\"\n ></c8y-message>\n <c8y-message name=\"maxlength\" [text]=\"'Only select one image.' | translate\"></c8y-message>\n <c8y-message name=\"required\" [text]=\"'An image is required.' | translate\"></c8y-message>\n <c8y-message name=\"minlength\" [text]=\"'An image is required.' | translate\"></c8y-message>\n </c8y-messages>\n </c8y-form-group>\n </div>\n <ng-container *ngIf=\"imageSrc$ | async as src\">\n <div class=\"col-md-6\">\n <div class=\"legend form-block\">\n {{ 'Size and alignment' | translate }}\n </div>\n <div [formGroupName]=\"'styling'\">\n <c8y-form-group>\n <label>\n {{ 'Image display' | translate }}\n </label>\n <ul class=\"list-group separator-top-bottom\">\n <li\n class=\"list-group-item d-flex a-i-center p-l-0\"\n *ngFor=\"let objectFitOption of objectFitOptions; let i = index\"\n >\n <label class=\"c8y-radio\">\n <input\n type=\"radio\"\n [id]=\"'groupradiocontentclass' + i\"\n formControlName=\"objectFit\"\n [value]=\"objectFitOption.value\"\n />\n <span></span>\n <span class=\"l-h-1\">\n {{ objectFitOption.label | translate }}\n <br />\n <small class=\"text-muted\">\n {{ objectFitOption.description | translate }}\n </small>\n </span>\n </label>\n </li>\n </ul>\n </c8y-form-group>\n <div class=\"row\">\n <div class=\"col-md-6\">\n <c8y-form-group>\n <label>{{ 'Horizontal alignment' | translate }}</label>\n <div class=\"c8y-select-wrapper\">\n <select class=\"form-control\" formControlName=\"objectPositionX\">\n <option [ngValue]=\"'left'\">\n {{ 'left`horizontal alignment`' | translate }}\n </option>\n <option [ngValue]=\"'center'\">\n {{ 'center`horizontal alignment`' | translate }}\n </option>\n <option [ngValue]=\"'right'\">\n {{ 'right`horizontal alignment`' | translate }}\n </option>\n </select>\n </div>\n </c8y-form-group>\n </div>\n <div class=\"col-md-6\">\n <c8y-form-group>\n <label>{{ 'Vertical alignment' | translate }}</label>\n <div class=\"c8y-select-wrapper\">\n <select class=\"form-control\" formControlName=\"objectPositionY\">\n <option [ngValue]=\"'top'\">\n {{ 'top`vertical alignment`' | translate }}\n </option>\n <option [ngValue]=\"'center'\">\n {{ 'center`vertical alignment`' | translate }}\n </option>\n <option [ngValue]=\"'bottom'\">\n {{ 'bottom`vertical alignment`' | translate }}\n </option>\n </select>\n </div>\n </c8y-form-group>\n </div>\n </div>\n </div>\n </div>\n <div class=\"col-md-6\">\n <div class=\"legend form-block\">{{ 'Preview' | translate }}</div>\n <div class=\"form-group\">\n <div\n class=\"border-top border-right border-bottom border-left inner-scroll\"\n style=\"height: 300px\"\n >\n <img\n [src]=\"src\"\n [ngClass]=\"styling ? 'fit-h fit-w' : 'img-responsive'\"\n [ngStyle]=\"styling\"\n />\n </div>\n </div>\n </div>\n </ng-container>\n <div class=\"col-md-12 d-flex j-c-center\" *ngIf=\"loading\">\n <c8y-loading></c8y-loading>\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$1.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: i1$1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1$1.RadioControlValueAccessor, selector: "input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1$1.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "component", type: FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "component", type: MessagesComponent, selector: "c8y-messages", inputs: ["show", "defaults", "helpMessage"] }, { kind: "directive", type: MessageDirective, selector: "c8y-message", inputs: ["name", "text"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: DropAreaComponent, selector: "c8y-drop-area", inputs: ["formControl", "title", "message", "icon", "loadingMessage", "forceHideList", "alwaysShow", "clickToOpen", "loading", "progress", "maxAllowedFiles", "files", "maxFileSizeInMegaBytes", "accept"], outputs: ["dropped"] }], viewProviders: [{ provide: ControlContainer, useExisting: NgForm }] }); }
215
215
  }
216
216
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: ImageWidgetConfigComponent, decorators: [{
217
217
  type: Component,
@@ -222,6 +222,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImpor
222
222
  MessageDirective,
223
223
  C8yTranslatePipe,
224
224
  AsyncPipe,
225
+ NgIf,
226
+ NgStyle,
227
+ NgClass,
228
+ NgForOf,
225
229
  DropAreaComponent
226
230
  ], template: "<div class=\"p-l-24 p-r-24\">\n <div [formGroup]=\"formGroup\" class=\"row p-t-8\">\n <div class=\"col-md-12\">\n <c8y-form-group>\n <label>{{ 'Image' | translate }}</label>\n <c8y-drop-area\n formControlName=\"images\"\n class=\"drop-area-sm\"\n [icon]=\"'upload'\"\n [accept]=\"'image'\"\n [maxAllowedFiles]=\"1\"\n ></c8y-drop-area>\n <c8y-messages>\n <c8y-message\n name=\"maxFileSizeReached\"\n [text]=\"\n 'The maximum image size is {{ maxFileSize }} kB. The selected image has a size of {{ actualFileSize }} kB.'\n | translate\n \"\n ></c8y-message>\n <c8y-message\n name=\"wrongFileType\"\n [text]=\"'Wrong file type, select an image.' | translate\"\n ></c8y-message>\n <c8y-message name=\"maxlength\" [text]=\"'Only select one image.' | translate\"></c8y-message>\n <c8y-message name=\"required\" [text]=\"'An image is required.' | translate\"></c8y-message>\n <c8y-message name=\"minlength\" [text]=\"'An image is required.' | translate\"></c8y-message>\n </c8y-messages>\n </c8y-form-group>\n </div>\n <ng-container *ngIf=\"imageSrc$ | async as src\">\n <div class=\"col-md-6\">\n <div class=\"legend form-block\">\n {{ 'Size and alignment' | translate }}\n </div>\n <div [formGroupName]=\"'styling'\">\n <c8y-form-group>\n <label>\n {{ 'Image display' | translate }}\n </label>\n <ul class=\"list-group separator-top-bottom\">\n <li\n class=\"list-group-item d-flex a-i-center p-l-0\"\n *ngFor=\"let objectFitOption of objectFitOptions; let i = index\"\n >\n <label class=\"c8y-radio\">\n <input\n type=\"radio\"\n [id]=\"'groupradiocontentclass' + i\"\n formControlName=\"objectFit\"\n [value]=\"objectFitOption.value\"\n />\n <span></span>\n <span class=\"l-h-1\">\n {{ objectFitOption.label | translate }}\n <br />\n <small class=\"text-muted\">\n {{ objectFitOption.description | translate }}\n </small>\n </span>\n </label>\n </li>\n </ul>\n </c8y-form-group>\n <div class=\"row\">\n <div class=\"col-md-6\">\n <c8y-form-group>\n <label>{{ 'Horizontal alignment' | translate }}</label>\n <div class=\"c8y-select-wrapper\">\n <select class=\"form-control\" formControlName=\"objectPositionX\">\n <option [ngValue]=\"'left'\">\n {{ 'left`horizontal alignment`' | translate }}\n </option>\n <option [ngValue]=\"'center'\">\n {{ 'center`horizontal alignment`' | translate }}\n </option>\n <option [ngValue]=\"'right'\">\n {{ 'right`horizontal alignment`' | translate }}\n </option>\n </select>\n </div>\n </c8y-form-group>\n </div>\n <div class=\"col-md-6\">\n <c8y-form-group>\n <label>{{ 'Vertical alignment' | translate }}</label>\n <div class=\"c8y-select-wrapper\">\n <select class=\"form-control\" formControlName=\"objectPositionY\">\n <option [ngValue]=\"'top'\">\n {{ 'top`vertical alignment`' | translate }}\n </option>\n <option [ngValue]=\"'center'\">\n {{ 'center`vertical alignment`' | translate }}\n </option>\n <option [ngValue]=\"'bottom'\">\n {{ 'bottom`vertical alignment`' | translate }}\n </option>\n </select>\n </div>\n </c8y-form-group>\n </div>\n </div>\n </div>\n </div>\n <div class=\"col-md-6\">\n <div class=\"legend form-block\">{{ 'Preview' | translate }}</div>\n <div class=\"form-group\">\n <div\n class=\"border-top border-right border-bottom border-left inner-scroll\"\n style=\"height: 300px\"\n >\n <img\n [src]=\"src\"\n [ngClass]=\"styling ? 'fit-h fit-w' : 'img-responsive'\"\n [ngStyle]=\"styling\"\n />\n </div>\n </div>\n </div>\n </ng-container>\n <div class=\"col-md-12 d-flex j-c-center\" *ngIf=\"loading\">\n <c8y-loading></c8y-loading>\n </div>\n </div>\n</div>\n" }]
227
231
  }], ctorParameters: () => [{ type: i1$1.FormBuilder }, { type: i1$1.NgForm }, { type: i2.FilesService }, { type: i2.AlertService }, { type: ImageWidgetService }, { type: i4.WidgetConfigComponent, decorators: [{
@@ -1 +1 @@
1
- {"version":3,"file":"c8y-ngx-components-widgets-implementations-image.mjs","sources":["../../widgets/implementations/image/image-widget.model.ts","../../widgets/implementations/image/image-widget.service.ts","../../widgets/implementations/image/image-widget-view/image-widget-view.component.ts","../../widgets/implementations/image/image-widget-view/image-widget-view.component.html","../../widgets/implementations/image/image-widget-config/image-widget-config.component.ts","../../widgets/implementations/image/image-widget-config/image-widget-config.component.html","../../widgets/implementations/image/image-widget.module.ts","../../widgets/implementations/image/c8y-ngx-components-widgets-implementations-image.ts"],"sourcesContent":["export interface ImageWidgetConfig {\n imageBinaryId: string;\n styling?: ImageWidgetConfigStyling;\n}\n\nexport interface ImageWidgetConfigStyling {\n objectFit: string;\n objectPositionX: string;\n objectPositionY: string;\n}\n\nexport interface ImageWidgetStyle {\n [key: string]: string;\n}\n\nexport const defaultObjectFitValue = 'contain';\nexport const defaultObjectPositionValue = 'center';\n","import { Injectable } from '@angular/core';\nimport { IManagedObject } from '@c8y/client';\nimport { InventoryBinaryService } from '@c8y/client';\nimport { IManagedObjectBinary, InventoryService } from '@c8y/client';\nimport { AlertService, FilesService, gettext } from '@c8y/ngx-components';\nimport { TranslateService } from '@ngx-translate/core';\nimport {\n defaultObjectPositionValue,\n ImageWidgetConfig,\n ImageWidgetStyle\n} from './image-widget.model';\n\n@Injectable({ providedIn: 'root' })\nexport class ImageWidgetService {\n constructor(\n private inventory: InventoryService,\n private fileService: FilesService,\n private alert: AlertService,\n private translate: TranslateService,\n private binary: InventoryBinaryService\n ) {}\n\n async getImageDetails(imageBinaryId: string | null): Promise<{ file: File; base64: string }> {\n if (!imageBinaryId) {\n return null;\n }\n\n try {\n const { data: imageBinaryMo } = await this.inventory.detail(imageBinaryId);\n const file = await this.fileService.getFile(imageBinaryMo as IManagedObjectBinary);\n const base64 = await this.fileService.toBase64(file);\n return {\n file,\n base64: base64 as string\n };\n } catch (e) {\n const text = this.translate.instant(\n gettext('Unable to retrieve image with id: {{ imageBinaryId }}'),\n { imageBinaryId }\n );\n this.alert.danger(text, e?.data);\n }\n\n return null;\n }\n\n async uploadFile(\n file: File,\n options: {\n dashboardMoId?: string;\n isDeviceTypeDashboard?: boolean;\n } = {}\n ): Promise<string> {\n const hash = await this.fileService.getHashSumOfFile(file);\n const fileDetails = { c8y_SHA256: hash };\n const globalImage = !options?.dashboardMoId || options?.isDeviceTypeDashboard;\n const partialBinaryMo: Partial<IManagedObject> = !globalImage\n ? { ...fileDetails }\n : { ...fileDetails, c8y_Global: {} };\n const { data: mo } = await this.binary.create(file, partialBinaryMo);\n if (options?.dashboardMoId) {\n await this.inventory.childAdditionsAdd(mo, options?.dashboardMoId);\n }\n return mo.id;\n }\n\n getStyling(config: ImageWidgetConfig): ImageWidgetStyle | null {\n if (!config.styling?.objectFit || config.styling?.objectFit === 'full-width') {\n return null;\n }\n return {\n 'object-fit': config.styling.objectFit,\n 'object-position': `${config.styling?.objectPositionX || defaultObjectPositionValue} ${\n config.styling?.objectPositionY || defaultObjectPositionValue\n }`\n };\n }\n}\n","import { Component, Input, OnChanges, SimpleChanges } from '@angular/core';\nimport { BehaviorSubject, Observable } from 'rxjs';\nimport { distinctUntilChanged, shareReplay, switchMap, tap } from 'rxjs/operators';\nimport { ImageWidgetConfig, ImageWidgetStyle } from '../image-widget.model';\nimport { ImageWidgetService } from '../image-widget.service';\nimport { EmptyStateComponent, LoadingComponent } from '@c8y/ngx-components';\nimport { AsyncPipe, NgClass, NgIf, NgStyle } from '@angular/common';\n\n@Component({\n selector: 'c8y-image-widget-view',\n templateUrl: './image-widget-view.component.html',\n standalone: true,\n imports: [NgIf, NgClass, AsyncPipe, NgStyle, LoadingComponent, EmptyStateComponent]\n})\nexport class ImageWidgetViewComponent implements OnChanges {\n @Input() config: ImageWidgetConfig;\n imageBinaryId$ = new BehaviorSubject<string>(null);\n imageDetails$: Observable<{\n file: File;\n base64: string;\n }>;\n styling: ImageWidgetStyle | null;\n loading = true;\n\n constructor(private imageWidget: ImageWidgetService) {\n this.imageDetails$ = this.imageBinaryId$.pipe(\n distinctUntilChanged(),\n tap(() => (this.loading = true)),\n switchMap(imageBinaryId => this.imageWidget.getImageDetails(imageBinaryId)),\n tap(() => (this.loading = false)),\n shareReplay(1)\n );\n }\n\n ngOnChanges(changes: SimpleChanges): void {\n if (changes.config) {\n const value = changes.config.currentValue as ImageWidgetConfig;\n this.imageBinaryId$.next(value.imageBinaryId);\n this.setStyling(value);\n }\n }\n\n private setStyling(config: ImageWidgetConfig): void {\n this.styling = this.imageWidget.getStyling(config);\n }\n}\n","<ng-container *ngIf=\"imageDetails$ | async as details; else empty\">\n <img\n [src]=\"details.base64\"\n [title]=\"details.file.name\"\n [ngClass]=\"styling ? 'fit-h fit-w' : 'img-responsive'\"\n [ngStyle]=\"styling\"\n />\n</ng-container>\n\n<ng-template #empty>\n <div class=\"d-flex fit-h fit-w j-c-center a-i-center\" *ngIf=\"!loading\">\n <c8y-ui-empty-state\n class=\"fit-w\"\n [icon]=\"'no-image'\"\n [title]=\"'No image to display.' | translate\"\n [subtitle]=\"'Upload an image.' | translate\"\n [horizontal]=\"true\"\n ></c8y-ui-empty-state>\n </div>\n</ng-template>\n<div class=\"d-flex fit-h fit-w j-c-center a-i-center\" *ngIf=\"loading\">\n <c8y-loading></c8y-loading>\n</div>\n","import { Component, Input, OnDestroy, OnInit, Optional } from '@angular/core';\nimport { WidgetConfigComponent } from '@c8y/ngx-components/context-dashboard';\nimport {\n C8yValidators,\n OnBeforeSave,\n FilesService,\n AlertService,\n gettext,\n FormGroupComponent,\n MessagesComponent,\n MessageDirective,\n C8yTranslatePipe,\n DropAreaComponent\n} from '@c8y/ngx-components';\nimport { get } from 'lodash-es';\nimport {\n defaultObjectFitValue,\n defaultObjectPositionValue,\n ImageWidgetConfig,\n ImageWidgetConfigStyling,\n ImageWidgetStyle\n} from '../image-widget.model';\nimport {\n ControlContainer,\n FormBuilder,\n FormGroup,\n NgForm,\n ReactiveFormsModule,\n Validators\n} from '@angular/forms';\nimport { BehaviorSubject, Observable, merge, Subject } from 'rxjs';\nimport {\n distinctUntilChanged,\n filter,\n map,\n shareReplay,\n switchMap,\n takeUntil,\n tap\n} from 'rxjs/operators';\nimport { ImageWidgetService } from '../image-widget.service';\nimport { AsyncPipe } from '@angular/common';\n\n@Component({\n selector: 'c8y-image-widget-config',\n templateUrl: './image-widget-config.component.html',\n viewProviders: [{ provide: ControlContainer, useExisting: NgForm }],\n standalone: true,\n imports: [\n ReactiveFormsModule,\n FormGroupComponent,\n MessagesComponent,\n MessageDirective,\n C8yTranslatePipe,\n AsyncPipe,\n DropAreaComponent\n ]\n})\nexport class ImageWidgetConfigComponent implements OnInit, OnDestroy, OnBeforeSave {\n @Input() config: ImageWidgetConfig;\n imageBinaryId$ = new BehaviorSubject<string>(null);\n imageSrc$: Observable<string>;\n loading = false;\n formGroup: FormGroup;\n fileFromConfig: File;\n styling: ImageWidgetStyle | null;\n destroyed$ = new Subject<void>();\n objectFitOptions = [\n {\n label: gettext('Contain`verb, image fitting option`'),\n value: 'contain',\n description: gettext(\n 'The image is entirely displayed within the widget while preserving the aspect ratio.'\n )\n },\n {\n label: gettext('Cover`verb, image fitting option`'),\n value: 'cover',\n description: gettext(\n 'The image is resized to fill the widget while preserving the aspect ratio. Overflowing areas are clipped.'\n )\n },\n {\n label: gettext('Fill`verb, image fitting option`'),\n value: 'fill',\n description: gettext(\n 'The image is stretched to fill the widget, overriding the aspect-ratio.'\n )\n },\n {\n label: gettext('Full width`image fitting option`'),\n value: 'full-width',\n description: gettext(\n `The image is resized to fit the widget's width while preserving the aspect ratio. Overflowing area is scrollable.`\n )\n }\n ];\n\n constructor(\n private formBuilder: FormBuilder,\n private form: NgForm,\n private fileService: FilesService,\n private alert: AlertService,\n private imageWidget: ImageWidgetService,\n @Optional() private widgetConfig: WidgetConfigComponent\n ) {}\n\n async onBeforeSave(config?: ImageWidgetConfig): Promise<boolean> {\n if (this.formGroup.invalid) {\n return false;\n }\n\n const fileFromForm = this.getFileFromFormValue(this.formGroup.value);\n if (fileFromForm && fileFromForm !== this.fileFromConfig) {\n try {\n const imageBinaryId = await this.imageWidget.uploadFile(fileFromForm, {\n dashboardMoId: this.getDashboardMoId(),\n isDeviceTypeDashboard: this.widgetConfig?.isDeviceTypeDashboard\n });\n Object.assign(config, { imageBinaryId });\n } catch (e) {\n this.alert.danger(gettext('Unable to upload image.'), e?.data);\n return false;\n }\n }\n const styling: ImageWidgetConfigStyling = this.formGroup.value.styling;\n Object.assign(config, { styling });\n\n return true;\n }\n\n ngOnInit() {\n this.initForm();\n const imageFromConfig = this.imageBinaryId$.pipe(\n filter(id => !!id),\n distinctUntilChanged(),\n tap(() => (this.loading = true)),\n switchMap(imageBinaryId => this.imageWidget.getImageDetails(imageBinaryId)),\n tap(details => {\n this.loading = false;\n this.fileFromConfig = details.file;\n if (details) {\n this.formGroup.patchValue({ images: [{ file: details.file, name: details.file.name }] });\n }\n }),\n map(details => details?.base64),\n shareReplay(1)\n );\n const selectedFile = this.formGroup.valueChanges.pipe(\n map(value => this.getFileFromFormValue(value)),\n distinctUntilChanged(),\n switchMap(file => (file ? this.fileService.toBase64(file) : Promise.resolve('')))\n );\n this.imageSrc$ = merge(imageFromConfig, selectedFile).pipe(\n map(base64 => (base64 ? (base64 as string) : ''))\n );\n this.imageBinaryId$.next(this.config?.imageBinaryId);\n }\n\n ngOnDestroy(): void {\n this.destroyed$.next();\n this.destroyed$.complete();\n }\n\n private getDashboardMoId(): string | null {\n return get(this.widgetConfig, 'mo.id', null);\n }\n\n private async initForm(): Promise<void> {\n const stylingFormGroup = this.formBuilder.group({\n objectFit: [\n // fallback to 'full-width' for old legacy widgets, newly created widgets should use defaultObjectFitValue\n this.config.imageBinaryId && !this.config.styling ? 'full-width' : defaultObjectFitValue,\n [Validators.required]\n ],\n objectPositionX: [defaultObjectPositionValue, [Validators.required]],\n objectPositionY: [defaultObjectPositionValue, [Validators.required]]\n });\n this.formGroup = this.formBuilder.group({\n images: [\n null,\n [\n Validators.required,\n Validators.minLength(1),\n Validators.maxLength(1),\n C8yValidators.filesValidator({ maximumFileSizeInKb: 1000, typePrefix: 'image/' })\n ]\n ],\n styling: stylingFormGroup\n });\n this.form.form.addControl('config', this.formGroup);\n this.formGroup.patchValue(this.config);\n this.formGroup.valueChanges\n .pipe(takeUntil(this.destroyed$))\n .subscribe(changes => this.setStyling(changes));\n }\n\n private getFileFromFormValue(formValue: any): File | null {\n const images: any[] = formValue?.images || [];\n return images[0]?.file || null;\n }\n\n private setStyling(config: ImageWidgetConfig): void {\n this.styling = this.imageWidget.getStyling(config);\n }\n}\n","<div class=\"p-l-24 p-r-24\">\n <div [formGroup]=\"formGroup\" class=\"row p-t-8\">\n <div class=\"col-md-12\">\n <c8y-form-group>\n <label>{{ 'Image' | translate }}</label>\n <c8y-drop-area\n formControlName=\"images\"\n class=\"drop-area-sm\"\n [icon]=\"'upload'\"\n [accept]=\"'image'\"\n [maxAllowedFiles]=\"1\"\n ></c8y-drop-area>\n <c8y-messages>\n <c8y-message\n name=\"maxFileSizeReached\"\n [text]=\"\n 'The maximum image size is {{ maxFileSize }} kB. The selected image has a size of {{ actualFileSize }} kB.'\n | translate\n \"\n ></c8y-message>\n <c8y-message\n name=\"wrongFileType\"\n [text]=\"'Wrong file type, select an image.' | translate\"\n ></c8y-message>\n <c8y-message name=\"maxlength\" [text]=\"'Only select one image.' | translate\"></c8y-message>\n <c8y-message name=\"required\" [text]=\"'An image is required.' | translate\"></c8y-message>\n <c8y-message name=\"minlength\" [text]=\"'An image is required.' | translate\"></c8y-message>\n </c8y-messages>\n </c8y-form-group>\n </div>\n <ng-container *ngIf=\"imageSrc$ | async as src\">\n <div class=\"col-md-6\">\n <div class=\"legend form-block\">\n {{ 'Size and alignment' | translate }}\n </div>\n <div [formGroupName]=\"'styling'\">\n <c8y-form-group>\n <label>\n {{ 'Image display' | translate }}\n </label>\n <ul class=\"list-group separator-top-bottom\">\n <li\n class=\"list-group-item d-flex a-i-center p-l-0\"\n *ngFor=\"let objectFitOption of objectFitOptions; let i = index\"\n >\n <label class=\"c8y-radio\">\n <input\n type=\"radio\"\n [id]=\"'groupradiocontentclass' + i\"\n formControlName=\"objectFit\"\n [value]=\"objectFitOption.value\"\n />\n <span></span>\n <span class=\"l-h-1\">\n {{ objectFitOption.label | translate }}\n <br />\n <small class=\"text-muted\">\n {{ objectFitOption.description | translate }}\n </small>\n </span>\n </label>\n </li>\n </ul>\n </c8y-form-group>\n <div class=\"row\">\n <div class=\"col-md-6\">\n <c8y-form-group>\n <label>{{ 'Horizontal alignment' | translate }}</label>\n <div class=\"c8y-select-wrapper\">\n <select class=\"form-control\" formControlName=\"objectPositionX\">\n <option [ngValue]=\"'left'\">\n {{ 'left`horizontal alignment`' | translate }}\n </option>\n <option [ngValue]=\"'center'\">\n {{ 'center`horizontal alignment`' | translate }}\n </option>\n <option [ngValue]=\"'right'\">\n {{ 'right`horizontal alignment`' | translate }}\n </option>\n </select>\n </div>\n </c8y-form-group>\n </div>\n <div class=\"col-md-6\">\n <c8y-form-group>\n <label>{{ 'Vertical alignment' | translate }}</label>\n <div class=\"c8y-select-wrapper\">\n <select class=\"form-control\" formControlName=\"objectPositionY\">\n <option [ngValue]=\"'top'\">\n {{ 'top`vertical alignment`' | translate }}\n </option>\n <option [ngValue]=\"'center'\">\n {{ 'center`vertical alignment`' | translate }}\n </option>\n <option [ngValue]=\"'bottom'\">\n {{ 'bottom`vertical alignment`' | translate }}\n </option>\n </select>\n </div>\n </c8y-form-group>\n </div>\n </div>\n </div>\n </div>\n <div class=\"col-md-6\">\n <div class=\"legend form-block\">{{ 'Preview' | translate }}</div>\n <div class=\"form-group\">\n <div\n class=\"border-top border-right border-bottom border-left inner-scroll\"\n style=\"height: 300px\"\n >\n <img\n [src]=\"src\"\n [ngClass]=\"styling ? 'fit-h fit-w' : 'img-responsive'\"\n [ngStyle]=\"styling\"\n />\n </div>\n </div>\n </div>\n </ng-container>\n <div class=\"col-md-12 d-flex j-c-center\" *ngIf=\"loading\">\n <c8y-loading></c8y-loading>\n </div>\n </div>\n</div>\n","import { NgModule } from '@angular/core';\nimport { ImageWidgetViewComponent } from './image-widget-view/image-widget-view.component';\nimport { ImageWidgetConfigComponent } from './image-widget-config/image-widget-config.component';\n\n/**\n * @deprecated\n */\n@NgModule({\n imports: [ImageWidgetViewComponent, ImageWidgetConfigComponent]\n})\nexport class ImageWidgetModule {}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["i1.ImageWidgetService","i1","i3.ImageWidgetService"],"mappings":"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"}
1
+ {"version":3,"file":"c8y-ngx-components-widgets-implementations-image.mjs","sources":["../../widgets/implementations/image/image-widget.model.ts","../../widgets/implementations/image/image-widget.service.ts","../../widgets/implementations/image/image-widget-view/image-widget-view.component.ts","../../widgets/implementations/image/image-widget-view/image-widget-view.component.html","../../widgets/implementations/image/image-widget-config/image-widget-config.component.ts","../../widgets/implementations/image/image-widget-config/image-widget-config.component.html","../../widgets/implementations/image/image-widget.module.ts","../../widgets/implementations/image/c8y-ngx-components-widgets-implementations-image.ts"],"sourcesContent":["export interface ImageWidgetConfig {\n imageBinaryId: string;\n styling?: ImageWidgetConfigStyling;\n}\n\nexport interface ImageWidgetConfigStyling {\n objectFit: string;\n objectPositionX: string;\n objectPositionY: string;\n}\n\nexport interface ImageWidgetStyle {\n [key: string]: string;\n}\n\nexport const defaultObjectFitValue = 'contain';\nexport const defaultObjectPositionValue = 'center';\n","import { Injectable } from '@angular/core';\nimport { IManagedObject } from '@c8y/client';\nimport { InventoryBinaryService } from '@c8y/client';\nimport { IManagedObjectBinary, InventoryService } from '@c8y/client';\nimport { AlertService, FilesService, gettext } from '@c8y/ngx-components';\nimport { TranslateService } from '@ngx-translate/core';\nimport {\n defaultObjectPositionValue,\n ImageWidgetConfig,\n ImageWidgetStyle\n} from './image-widget.model';\n\n@Injectable({ providedIn: 'root' })\nexport class ImageWidgetService {\n constructor(\n private inventory: InventoryService,\n private fileService: FilesService,\n private alert: AlertService,\n private translate: TranslateService,\n private binary: InventoryBinaryService\n ) {}\n\n async getImageDetails(imageBinaryId: string | null): Promise<{ file: File; base64: string }> {\n if (!imageBinaryId) {\n return null;\n }\n\n try {\n const { data: imageBinaryMo } = await this.inventory.detail(imageBinaryId);\n const file = await this.fileService.getFile(imageBinaryMo as IManagedObjectBinary);\n const base64 = await this.fileService.toBase64(file);\n return {\n file,\n base64: base64 as string\n };\n } catch (e) {\n const text = this.translate.instant(\n gettext('Unable to retrieve image with id: {{ imageBinaryId }}'),\n { imageBinaryId }\n );\n this.alert.danger(text, e?.data);\n }\n\n return null;\n }\n\n async uploadFile(\n file: File,\n options: {\n dashboardMoId?: string;\n isDeviceTypeDashboard?: boolean;\n } = {}\n ): Promise<string> {\n const hash = await this.fileService.getHashSumOfFile(file);\n const fileDetails = { c8y_SHA256: hash };\n const globalImage = !options?.dashboardMoId || options?.isDeviceTypeDashboard;\n const partialBinaryMo: Partial<IManagedObject> = !globalImage\n ? { ...fileDetails }\n : { ...fileDetails, c8y_Global: {} };\n const { data: mo } = await this.binary.create(file, partialBinaryMo);\n if (options?.dashboardMoId) {\n await this.inventory.childAdditionsAdd(mo, options?.dashboardMoId);\n }\n return mo.id;\n }\n\n getStyling(config: ImageWidgetConfig): ImageWidgetStyle | null {\n if (!config.styling?.objectFit || config.styling?.objectFit === 'full-width') {\n return null;\n }\n return {\n 'object-fit': config.styling.objectFit,\n 'object-position': `${config.styling?.objectPositionX || defaultObjectPositionValue} ${\n config.styling?.objectPositionY || defaultObjectPositionValue\n }`\n };\n }\n}\n","import { Component, Input, OnChanges, SimpleChanges } from '@angular/core';\nimport { BehaviorSubject, Observable } from 'rxjs';\nimport { distinctUntilChanged, shareReplay, switchMap, tap } from 'rxjs/operators';\nimport { ImageWidgetConfig, ImageWidgetStyle } from '../image-widget.model';\nimport { ImageWidgetService } from '../image-widget.service';\nimport { EmptyStateComponent, LoadingComponent } from '@c8y/ngx-components';\nimport { AsyncPipe, NgClass, NgIf, NgStyle } from '@angular/common';\n\n@Component({\n selector: 'c8y-image-widget-view',\n templateUrl: './image-widget-view.component.html',\n standalone: true,\n imports: [NgIf, NgClass, AsyncPipe, NgStyle, LoadingComponent, EmptyStateComponent]\n})\nexport class ImageWidgetViewComponent implements OnChanges {\n @Input() config: ImageWidgetConfig;\n imageBinaryId$ = new BehaviorSubject<string>(null);\n imageDetails$: Observable<{\n file: File;\n base64: string;\n }>;\n styling: ImageWidgetStyle | null;\n loading = true;\n\n constructor(private imageWidget: ImageWidgetService) {\n this.imageDetails$ = this.imageBinaryId$.pipe(\n distinctUntilChanged(),\n tap(() => (this.loading = true)),\n switchMap(imageBinaryId => this.imageWidget.getImageDetails(imageBinaryId)),\n tap(() => (this.loading = false)),\n shareReplay(1)\n );\n }\n\n ngOnChanges(changes: SimpleChanges): void {\n if (changes.config) {\n const value = changes.config.currentValue as ImageWidgetConfig;\n this.imageBinaryId$.next(value.imageBinaryId);\n this.setStyling(value);\n }\n }\n\n private setStyling(config: ImageWidgetConfig): void {\n this.styling = this.imageWidget.getStyling(config);\n }\n}\n","<ng-container *ngIf=\"imageDetails$ | async as details; else empty\">\n <img\n [src]=\"details.base64\"\n [title]=\"details.file.name\"\n [ngClass]=\"styling ? 'fit-h fit-w' : 'img-responsive'\"\n [ngStyle]=\"styling\"\n />\n</ng-container>\n\n<ng-template #empty>\n <div class=\"d-flex fit-h fit-w j-c-center a-i-center\" *ngIf=\"!loading\">\n <c8y-ui-empty-state\n class=\"fit-w\"\n [icon]=\"'no-image'\"\n [title]=\"'No image to display.' | translate\"\n [subtitle]=\"'Upload an image.' | translate\"\n [horizontal]=\"true\"\n ></c8y-ui-empty-state>\n </div>\n</ng-template>\n<div class=\"d-flex fit-h fit-w j-c-center a-i-center\" *ngIf=\"loading\">\n <c8y-loading></c8y-loading>\n</div>\n","import { Component, Input, OnDestroy, OnInit, Optional } from '@angular/core';\nimport { WidgetConfigComponent } from '@c8y/ngx-components/context-dashboard';\nimport {\n C8yValidators,\n OnBeforeSave,\n FilesService,\n AlertService,\n gettext,\n FormGroupComponent,\n MessagesComponent,\n MessageDirective,\n C8yTranslatePipe,\n DropAreaComponent\n} from '@c8y/ngx-components';\nimport { get } from 'lodash-es';\nimport {\n defaultObjectFitValue,\n defaultObjectPositionValue,\n ImageWidgetConfig,\n ImageWidgetConfigStyling,\n ImageWidgetStyle\n} from '../image-widget.model';\nimport {\n ControlContainer,\n FormBuilder,\n FormGroup,\n NgForm,\n ReactiveFormsModule,\n Validators\n} from '@angular/forms';\nimport { BehaviorSubject, Observable, merge, Subject } from 'rxjs';\nimport {\n distinctUntilChanged,\n filter,\n map,\n shareReplay,\n switchMap,\n takeUntil,\n tap\n} from 'rxjs/operators';\nimport { ImageWidgetService } from '../image-widget.service';\nimport { AsyncPipe, NgClass, NgForOf, NgIf, NgStyle } from '@angular/common';\n\n@Component({\n selector: 'c8y-image-widget-config',\n templateUrl: './image-widget-config.component.html',\n viewProviders: [{ provide: ControlContainer, useExisting: NgForm }],\n standalone: true,\n imports: [\n ReactiveFormsModule,\n FormGroupComponent,\n MessagesComponent,\n MessageDirective,\n C8yTranslatePipe,\n AsyncPipe,\n NgIf,\n NgStyle,\n NgClass,\n NgForOf,\n DropAreaComponent\n ]\n})\nexport class ImageWidgetConfigComponent implements OnInit, OnDestroy, OnBeforeSave {\n @Input() config: ImageWidgetConfig;\n imageBinaryId$ = new BehaviorSubject<string>(null);\n imageSrc$: Observable<string>;\n loading = false;\n formGroup: FormGroup;\n fileFromConfig: File;\n styling: ImageWidgetStyle | null;\n destroyed$ = new Subject<void>();\n objectFitOptions = [\n {\n label: gettext('Contain`verb, image fitting option`'),\n value: 'contain',\n description: gettext(\n 'The image is entirely displayed within the widget while preserving the aspect ratio.'\n )\n },\n {\n label: gettext('Cover`verb, image fitting option`'),\n value: 'cover',\n description: gettext(\n 'The image is resized to fill the widget while preserving the aspect ratio. Overflowing areas are clipped.'\n )\n },\n {\n label: gettext('Fill`verb, image fitting option`'),\n value: 'fill',\n description: gettext(\n 'The image is stretched to fill the widget, overriding the aspect-ratio.'\n )\n },\n {\n label: gettext('Full width`image fitting option`'),\n value: 'full-width',\n description: gettext(\n `The image is resized to fit the widget's width while preserving the aspect ratio. Overflowing area is scrollable.`\n )\n }\n ];\n\n constructor(\n private formBuilder: FormBuilder,\n private form: NgForm,\n private fileService: FilesService,\n private alert: AlertService,\n private imageWidget: ImageWidgetService,\n @Optional() private widgetConfig: WidgetConfigComponent\n ) {}\n\n async onBeforeSave(config?: ImageWidgetConfig): Promise<boolean> {\n if (this.formGroup.invalid) {\n return false;\n }\n\n const fileFromForm = this.getFileFromFormValue(this.formGroup.value);\n if (fileFromForm && fileFromForm !== this.fileFromConfig) {\n try {\n const imageBinaryId = await this.imageWidget.uploadFile(fileFromForm, {\n dashboardMoId: this.getDashboardMoId(),\n isDeviceTypeDashboard: this.widgetConfig?.isDeviceTypeDashboard\n });\n Object.assign(config, { imageBinaryId });\n } catch (e) {\n this.alert.danger(gettext('Unable to upload image.'), e?.data);\n return false;\n }\n }\n const styling: ImageWidgetConfigStyling = this.formGroup.value.styling;\n Object.assign(config, { styling });\n\n return true;\n }\n\n ngOnInit() {\n this.initForm();\n const imageFromConfig = this.imageBinaryId$.pipe(\n filter(id => !!id),\n distinctUntilChanged(),\n tap(() => (this.loading = true)),\n switchMap(imageBinaryId => this.imageWidget.getImageDetails(imageBinaryId)),\n tap(details => {\n this.loading = false;\n this.fileFromConfig = details.file;\n if (details) {\n this.formGroup.patchValue({ images: [{ file: details.file, name: details.file.name }] });\n }\n }),\n map(details => details?.base64),\n shareReplay(1)\n );\n const selectedFile = this.formGroup.valueChanges.pipe(\n map(value => this.getFileFromFormValue(value)),\n distinctUntilChanged(),\n switchMap(file => (file ? this.fileService.toBase64(file) : Promise.resolve('')))\n );\n this.imageSrc$ = merge(imageFromConfig, selectedFile).pipe(\n map(base64 => (base64 ? (base64 as string) : ''))\n );\n this.imageBinaryId$.next(this.config?.imageBinaryId);\n }\n\n ngOnDestroy(): void {\n this.destroyed$.next();\n this.destroyed$.complete();\n }\n\n private getDashboardMoId(): string | null {\n return get(this.widgetConfig, 'mo.id', null);\n }\n\n private async initForm(): Promise<void> {\n const stylingFormGroup = this.formBuilder.group({\n objectFit: [\n // fallback to 'full-width' for old legacy widgets, newly created widgets should use defaultObjectFitValue\n this.config.imageBinaryId && !this.config.styling ? 'full-width' : defaultObjectFitValue,\n [Validators.required]\n ],\n objectPositionX: [defaultObjectPositionValue, [Validators.required]],\n objectPositionY: [defaultObjectPositionValue, [Validators.required]]\n });\n this.formGroup = this.formBuilder.group({\n images: [\n null,\n [\n Validators.required,\n Validators.minLength(1),\n Validators.maxLength(1),\n C8yValidators.filesValidator({ maximumFileSizeInKb: 1000, typePrefix: 'image/' })\n ]\n ],\n styling: stylingFormGroup\n });\n this.form.form.addControl('config', this.formGroup);\n this.formGroup.patchValue(this.config);\n this.formGroup.valueChanges\n .pipe(takeUntil(this.destroyed$))\n .subscribe(changes => this.setStyling(changes));\n }\n\n private getFileFromFormValue(formValue: any): File | null {\n const images: any[] = formValue?.images || [];\n return images[0]?.file || null;\n }\n\n private setStyling(config: ImageWidgetConfig): void {\n this.styling = this.imageWidget.getStyling(config);\n }\n}\n","<div class=\"p-l-24 p-r-24\">\n <div [formGroup]=\"formGroup\" class=\"row p-t-8\">\n <div class=\"col-md-12\">\n <c8y-form-group>\n <label>{{ 'Image' | translate }}</label>\n <c8y-drop-area\n formControlName=\"images\"\n class=\"drop-area-sm\"\n [icon]=\"'upload'\"\n [accept]=\"'image'\"\n [maxAllowedFiles]=\"1\"\n ></c8y-drop-area>\n <c8y-messages>\n <c8y-message\n name=\"maxFileSizeReached\"\n [text]=\"\n 'The maximum image size is {{ maxFileSize }} kB. The selected image has a size of {{ actualFileSize }} kB.'\n | translate\n \"\n ></c8y-message>\n <c8y-message\n name=\"wrongFileType\"\n [text]=\"'Wrong file type, select an image.' | translate\"\n ></c8y-message>\n <c8y-message name=\"maxlength\" [text]=\"'Only select one image.' | translate\"></c8y-message>\n <c8y-message name=\"required\" [text]=\"'An image is required.' | translate\"></c8y-message>\n <c8y-message name=\"minlength\" [text]=\"'An image is required.' | translate\"></c8y-message>\n </c8y-messages>\n </c8y-form-group>\n </div>\n <ng-container *ngIf=\"imageSrc$ | async as src\">\n <div class=\"col-md-6\">\n <div class=\"legend form-block\">\n {{ 'Size and alignment' | translate }}\n </div>\n <div [formGroupName]=\"'styling'\">\n <c8y-form-group>\n <label>\n {{ 'Image display' | translate }}\n </label>\n <ul class=\"list-group separator-top-bottom\">\n <li\n class=\"list-group-item d-flex a-i-center p-l-0\"\n *ngFor=\"let objectFitOption of objectFitOptions; let i = index\"\n >\n <label class=\"c8y-radio\">\n <input\n type=\"radio\"\n [id]=\"'groupradiocontentclass' + i\"\n formControlName=\"objectFit\"\n [value]=\"objectFitOption.value\"\n />\n <span></span>\n <span class=\"l-h-1\">\n {{ objectFitOption.label | translate }}\n <br />\n <small class=\"text-muted\">\n {{ objectFitOption.description | translate }}\n </small>\n </span>\n </label>\n </li>\n </ul>\n </c8y-form-group>\n <div class=\"row\">\n <div class=\"col-md-6\">\n <c8y-form-group>\n <label>{{ 'Horizontal alignment' | translate }}</label>\n <div class=\"c8y-select-wrapper\">\n <select class=\"form-control\" formControlName=\"objectPositionX\">\n <option [ngValue]=\"'left'\">\n {{ 'left`horizontal alignment`' | translate }}\n </option>\n <option [ngValue]=\"'center'\">\n {{ 'center`horizontal alignment`' | translate }}\n </option>\n <option [ngValue]=\"'right'\">\n {{ 'right`horizontal alignment`' | translate }}\n </option>\n </select>\n </div>\n </c8y-form-group>\n </div>\n <div class=\"col-md-6\">\n <c8y-form-group>\n <label>{{ 'Vertical alignment' | translate }}</label>\n <div class=\"c8y-select-wrapper\">\n <select class=\"form-control\" formControlName=\"objectPositionY\">\n <option [ngValue]=\"'top'\">\n {{ 'top`vertical alignment`' | translate }}\n </option>\n <option [ngValue]=\"'center'\">\n {{ 'center`vertical alignment`' | translate }}\n </option>\n <option [ngValue]=\"'bottom'\">\n {{ 'bottom`vertical alignment`' | translate }}\n </option>\n </select>\n </div>\n </c8y-form-group>\n </div>\n </div>\n </div>\n </div>\n <div class=\"col-md-6\">\n <div class=\"legend form-block\">{{ 'Preview' | translate }}</div>\n <div class=\"form-group\">\n <div\n class=\"border-top border-right border-bottom border-left inner-scroll\"\n style=\"height: 300px\"\n >\n <img\n [src]=\"src\"\n [ngClass]=\"styling ? 'fit-h fit-w' : 'img-responsive'\"\n [ngStyle]=\"styling\"\n />\n </div>\n </div>\n </div>\n </ng-container>\n <div class=\"col-md-12 d-flex j-c-center\" *ngIf=\"loading\">\n <c8y-loading></c8y-loading>\n </div>\n </div>\n</div>\n","import { NgModule } from '@angular/core';\nimport { ImageWidgetViewComponent } from './image-widget-view/image-widget-view.component';\nimport { ImageWidgetConfigComponent } from './image-widget-config/image-widget-config.component';\n\n/**\n * @deprecated\n */\n@NgModule({\n imports: [ImageWidgetViewComponent, ImageWidgetConfigComponent]\n})\nexport class ImageWidgetModule {}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["i1.ImageWidgetService","i1","i3.ImageWidgetService"],"mappings":"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"}