@firestitch/system 18.0.13 → 18.0.15

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.
@@ -127,11 +127,11 @@ export class SettingsComponent {
127
127
  });
128
128
  }
129
129
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: SettingsComponent, deps: [{ token: i1.FsMessage }, { token: i2.FsClipboard }, { token: i3.FsPrompt }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
130
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.7", type: SettingsComponent, selector: "fs-system-settings", inputs: { loadSettings: "loadSettings", save: "save" }, outputs: { fileRemove: "fileRemove", fileSelect: "fileSelect" }, ngImport: i0, template: "\r\n<mat-accordion>\r\n <mat-expansion-panel hideToggle *ngFor=\"let group of groups\">\r\n <mat-expansion-panel-header>\r\n <mat-panel-title>\r\n <div class=\"title-row\">\r\n <div class=\"title\">{{group || 'General'}}</div>\r\n <div class=\"actions\">\r\n <button\r\n type=\"button\"\r\n [matTooltip]=\"'Export ' + (group || 'General') + ' Settings'\"\r\n mat-icon-button\r\n (click)=\"export($event, groupedSettings[group])\">\r\n <mat-icon>cloud_download</mat-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n [matTooltip]=\"'Import ' + (group || 'General') + ' Settings'\"\r\n mat-icon-button\r\n (click)=\"import($event, group)\">\r\n <mat-icon>cloud_upload</mat-icon>\r\n </button>\r\n </div>\r\n </div>\r\n </mat-panel-title>\r\n </mat-expansion-panel-header>\r\n\r\n <div \r\n hideToggle \r\n *ngFor=\"let setting of groupedSettings[group]\" \r\n class=\"setting\"\r\n [ngClass]=\"{ 'has-instruction': !! setting.instruction }\">\r\n <mat-form-field \r\n class=\"full-width form-field-multiline-subscript\"\r\n *ngIf=\"setting.interfaceType===SettingInterfaceType.InputBox\">\r\n <mat-label>{{setting.label}}</mat-label>\r\n <input\r\n matInput\r\n [(ngModel)]=\"setting.value\"\r\n [name]=\"'setting' + setting.id\">\r\n <mat-hint>{{setting.instruction}}</mat-hint>\r\n </mat-form-field>\r\n\r\n <mat-form-field \r\n class=\"full-width form-field-multiline-subscript\" \r\n *ngIf=\"setting.interfaceType===SettingInterfaceType.Textarea\">\r\n <mat-label>{{setting.label}}</mat-label>\r\n <textarea\r\n matInput\r\n [(ngModel)]=\"setting.value\"\r\n [name]=\"'setting' + setting.id\">\r\n </textarea>\r\n <mat-hint>{{setting.instruction}}</mat-hint>\r\n </mat-form-field>\r\n\r\n <mat-form-field \r\n class=\"full-width form-field-multiline-subscript\" \r\n *ngIf=\"setting.interfaceType===SettingInterfaceType.Select || setting.interfaceType===SettingInterfaceType.SelectMultiple\">\r\n <mat-label>{{setting.label}}</mat-label>\r\n <mat-select\r\n [(ngModel)]=\"setting.value\"\r\n [multiple]=\"setting.interfaceType===SettingInterfaceType.SelectMultiple\"\r\n [name]=\"'setting' + setting.id\">\r\n <mat-option *ngFor=\"let item of setting.values | keyNameValue\" [value]=\"item.value\">\r\n {{item.name}}\r\n </mat-option>\r\n </mat-select>\r\n <mat-hint>{{setting.instruction}}</mat-hint>\r\n </mat-form-field>\r\n\r\n <mat-form-field \r\n class=\"full-width form-field-multiline-subscript\" \r\n *ngIf=\"setting.interfaceType===SettingInterfaceType.Date\">\r\n <mat-label>{{setting.label}}</mat-label>\r\n <input\r\n matInput\r\n fsDatePicker\r\n [(ngModel)]=\"setting.value\"\r\n [name]=\"'setting' + setting.id\">\r\n <mat-hint>{{setting.instruction}}</mat-hint>\r\n </mat-form-field>\r\n\r\n <mat-form-field \r\n class=\"full-width form-field-multiline-subscript\" \r\n *ngIf=\"setting.interfaceType===SettingInterfaceType.Color\">\r\n <mat-label>{{setting.label}}</mat-label>\r\n <input\r\n matInput\r\n fsColorPicker\r\n [(ngModel)]=\"setting.value\"\r\n [name]=\"'setting' + setting.id\">\r\n <mat-hint>{{setting.instruction}}</mat-hint>\r\n </mat-form-field>\r\n\r\n <mat-form-field \r\n class=\"full-width form-field-multiline-subscript\" \r\n *ngIf=\"setting.interfaceType===SettingInterfaceType.Time\">\r\n <mat-label>{{setting.label}}</mat-label>\r\n <input\r\n matInput\r\n fsTimePicker\r\n [(ngModel)]=\"setting.value\"\r\n [name]=\"'setting' + setting.id\">\r\n <mat-hint>{{setting.instruction}}</mat-hint>\r\n </mat-form-field>\r\n\r\n <fs-file-picker\r\n *ngIf=\"setting.interfaceType===SettingInterfaceType.File\"\r\n [allowRemove]=\"true\"\r\n [allowDownload]=\"true\"\r\n (select)=\"fileSelect.emit({ setting: setting, file: $event.file })\"\r\n (remove)=\"fileRemove.emit(setting)\"\r\n [url]=\"setting.value\">\r\n <div fsFileLabel>{{setting.label}}</div>\r\n <div fsFileHint>{{setting.instruction}}</div>\r\n </fs-file-picker>\r\n </div>\r\n\r\n <button mat-raised-button color=\"primary\" type=\"button\" (click)=\"saveGroup(group)\">Save</button>\r\n\r\n </mat-expansion-panel>\r\n\r\n</mat-accordion>\r\n", styles: [".mat-expansion-panel-header{font-size:19px}.full-width{width:100%}.title-row{flex-direction:row;box-sizing:border-box;display:flex;place-content:center flex-start;align-items:center;width:100%}.title-row .title{display:flex;flex:1}:host ::ng-deep .mat-expansion-panel-header-title{margin:0}:host ::ng-deep .mat-expansion-panel .actions{display:none}:host ::ng-deep .mat-expansion-panel.mat-expanded .actions{display:block}:host ::ng-deep .setting.has-instruction fs-file-picker fs-label-message{display:block;padding-bottom:1em}\n"], dependencies: [{ kind: "directive", type: i4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.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: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i6.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i6.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "directive", type: i7.MatAccordion, selector: "mat-accordion", inputs: ["hideToggle", "displayMode", "togglePosition"], exportAs: ["matAccordion"] }, { kind: "component", type: i7.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i7.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "directive", type: i7.MatExpansionPanelTitle, selector: "mat-panel-title" }, { kind: "directive", type: i8.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: i9.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i10.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i10.MatLabel, selector: "mat-label" }, { kind: "directive", type: i10.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i11.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i12.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i13.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i14.FsFilePickerComponent, selector: "fs-file-picker", inputs: ["minWidth", "minHeight", "imageWidth", "imageHeight", "imageQuality", "label", "showFilename", "allowDownload", "allowReupload", "multiple", "allowRemove", "url", "file", "accept", "disabled", "previewWidth", "previewHeight"], outputs: ["select", "remove", "download"] }, { kind: "directive", type: i14.FsFileLabelDirective, selector: "[fsFileLabel]" }, { kind: "component", type: i15.FsDatePickerComponent, selector: "[fsDatePicker]", inputs: ["minYear", "maxYear", "minDate", "maxDate", "startOfDay", "view", "format", "minutes"], outputs: ["change"] }, { kind: "component", type: i15.FsTimePickerComponent, selector: "[fsTimePicker]", inputs: ["view"] }, { kind: "component", type: i16.FsColorPickerComponent, selector: "[fsColorPicker]", inputs: ["showClear"] }, { kind: "pipe", type: i17.KeyNameValuePipe, name: "keyNameValue" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
130
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.7", type: SettingsComponent, selector: "fs-system-settings", inputs: { loadSettings: "loadSettings", save: "save" }, outputs: { fileRemove: "fileRemove", fileSelect: "fileSelect" }, ngImport: i0, template: "<mat-accordion>\r\n <mat-expansion-panel\r\n hideToggle\r\n *ngFor=\"let group of groups\">\r\n <mat-expansion-panel-header>\r\n <mat-panel-title>\r\n <div class=\"title-row\">\r\n <div class=\"title\">\r\n {{ group || 'General' }}\r\n </div>\r\n <div class=\"actions\">\r\n <button\r\n type=\"button\"\r\n [matTooltip]=\"'Export ' + (group || 'General') + ' Settings'\"\r\n mat-icon-button\r\n (click)=\"export($event, groupedSettings[group])\">\r\n <mat-icon>\r\n cloud_download\r\n </mat-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n [matTooltip]=\"'Import ' + (group || 'General') + ' Settings'\"\r\n mat-icon-button\r\n (click)=\"import($event, group)\">\r\n <mat-icon>\r\n cloud_upload\r\n </mat-icon>\r\n </button>\r\n </div>\r\n </div>\r\n </mat-panel-title>\r\n </mat-expansion-panel-header>\r\n <div\r\n hideToggle\r\n *ngFor=\"let setting of groupedSettings[group]\"\r\n class=\"setting\"\r\n [ngClass]=\"{ 'has-instruction': !! setting.instruction }\">\r\n <mat-form-field\r\n class=\"full-width form-field-multiline-subscript\"\r\n *ngIf=\"setting.interfaceType===SettingInterfaceType.InputBox\">\r\n <mat-label>\r\n {{ setting.label }}\r\n </mat-label>\r\n <input\r\n matInput\r\n [(ngModel)]=\"setting.value\"\r\n [name]=\"'setting' + setting.id\">\r\n <mat-hint>\r\n {{ setting.instruction }}\r\n </mat-hint>\r\n </mat-form-field>\r\n <mat-form-field\r\n class=\"full-width form-field-multiline-subscript\"\r\n *ngIf=\"setting.interfaceType===SettingInterfaceType.Textarea\">\r\n <mat-label>\r\n {{ setting.label }}\r\n </mat-label>\r\n <textarea\r\n matInput\r\n [(ngModel)]=\"setting.value\"\r\n [name]=\"'setting' + setting.id\">\r\n </textarea>\r\n <mat-hint>\r\n {{ setting.instruction }}\r\n </mat-hint>\r\n </mat-form-field>\r\n <mat-form-field\r\n class=\"full-width form-field-multiline-subscript\"\r\n *ngIf=\"setting.interfaceType===SettingInterfaceType.Select || setting.interfaceType===SettingInterfaceType.SelectMultiple\">\r\n <mat-label>\r\n {{ setting.label }}\r\n </mat-label>\r\n <mat-select\r\n [(ngModel)]=\"setting.value\"\r\n [multiple]=\"setting.interfaceType===SettingInterfaceType.SelectMultiple\"\r\n [name]=\"'setting' + setting.id\">\r\n <mat-option\r\n *ngFor=\"let item of setting.values | keyNameValue\"\r\n [value]=\"item.value\">\r\n {{ item.name }}\r\n </mat-option>\r\n </mat-select>\r\n <mat-hint>\r\n {{ setting.instruction }}\r\n </mat-hint>\r\n </mat-form-field>\r\n <mat-form-field\r\n class=\"full-width form-field-multiline-subscript\"\r\n *ngIf=\"setting.interfaceType===SettingInterfaceType.Date\">\r\n <mat-label>\r\n {{ setting.label }}\r\n </mat-label>\r\n <input\r\n matInput\r\n fsDatePicker\r\n [(ngModel)]=\"setting.value\"\r\n [name]=\"'setting' + setting.id\">\r\n <mat-hint>\r\n {{ setting.instruction }}\r\n </mat-hint>\r\n </mat-form-field>\r\n <mat-form-field\r\n class=\"full-width form-field-multiline-subscript\"\r\n *ngIf=\"setting.interfaceType===SettingInterfaceType.Color\">\r\n <mat-label>\r\n {{ setting.label }}\r\n </mat-label>\r\n <input\r\n matInput\r\n fsColorPicker\r\n [(ngModel)]=\"setting.value\"\r\n [name]=\"'setting' + setting.id\">\r\n <mat-hint>\r\n {{ setting.instruction }}\r\n </mat-hint>\r\n </mat-form-field>\r\n <mat-form-field\r\n class=\"full-width form-field-multiline-subscript\"\r\n *ngIf=\"setting.interfaceType===SettingInterfaceType.Time\">\r\n <mat-label>\r\n {{ setting.label }}\r\n </mat-label>\r\n <input\r\n matInput\r\n fsTimePicker\r\n [(ngModel)]=\"setting.value\"\r\n [name]=\"'setting' + setting.id\">\r\n <mat-hint>\r\n {{ setting.instruction }}\r\n </mat-hint>\r\n </mat-form-field>\r\n <fs-file-picker\r\n *ngIf=\"setting.interfaceType===SettingInterfaceType.File\"\r\n [allowRemove]=\"true\"\r\n [allowDownload]=\"true\"\r\n (select)=\"fileSelect.emit({ setting: setting, file: $event.file })\"\r\n (remove)=\"fileRemove.emit(setting)\"\r\n [url]=\"setting.value\">\r\n <div fsFileLabel>\r\n {{ setting.label }}\r\n </div>\r\n <div fsFileHint>\r\n {{ setting.instruction }}\r\n </div>\r\n </fs-file-picker>\r\n </div>\r\n <button\r\n mat-stroked-button\r\n color=\"primary\"\r\n type=\"button\"\r\n (click)=\"saveGroup(group)\">\r\n Save\r\n </button>\r\n </mat-expansion-panel>\r\n</mat-accordion>", styles: [".mat-expansion-panel-header{font-size:19px}.full-width{width:100%}.title-row{flex-direction:row;box-sizing:border-box;display:flex;place-content:center flex-start;align-items:center;width:100%}.title-row .title{display:flex;flex:1}:host ::ng-deep .mat-expansion-panel-header-title{margin:0}:host ::ng-deep .mat-expansion-panel .actions{display:none}:host ::ng-deep .mat-expansion-panel.mat-expanded .actions{display:block}:host ::ng-deep .setting.has-instruction fs-file-picker fs-label-message{display:block;padding-bottom:1em}\n"], dependencies: [{ kind: "directive", type: i4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.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: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i6.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i6.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "directive", type: i7.MatAccordion, selector: "mat-accordion", inputs: ["hideToggle", "displayMode", "togglePosition"], exportAs: ["matAccordion"] }, { kind: "component", type: i7.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i7.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "directive", type: i7.MatExpansionPanelTitle, selector: "mat-panel-title" }, { kind: "directive", type: i8.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: i9.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i10.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i10.MatLabel, selector: "mat-label" }, { kind: "directive", type: i10.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i11.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i12.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i13.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i14.FsFilePickerComponent, selector: "fs-file-picker", inputs: ["minWidth", "minHeight", "imageWidth", "imageHeight", "imageQuality", "label", "showFilename", "allowDownload", "allowReupload", "multiple", "allowRemove", "url", "file", "accept", "disabled", "previewWidth", "previewHeight"], outputs: ["select", "remove", "download"] }, { kind: "directive", type: i14.FsFileLabelDirective, selector: "[fsFileLabel]" }, { kind: "component", type: i15.FsDatePickerComponent, selector: "[fsDatePicker]", inputs: ["minYear", "maxYear", "minDate", "maxDate", "startOfDay", "view", "format", "minutes"], outputs: ["change"] }, { kind: "component", type: i15.FsTimePickerComponent, selector: "[fsTimePicker]", inputs: ["view"] }, { kind: "component", type: i16.FsColorPickerComponent, selector: "[fsColorPicker]", inputs: ["showClear"] }, { kind: "pipe", type: i17.KeyNameValuePipe, name: "keyNameValue" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
131
131
  }
132
132
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: SettingsComponent, decorators: [{
133
133
  type: Component,
134
- args: [{ selector: 'fs-system-settings', changeDetection: ChangeDetectionStrategy.OnPush, template: "\r\n<mat-accordion>\r\n <mat-expansion-panel hideToggle *ngFor=\"let group of groups\">\r\n <mat-expansion-panel-header>\r\n <mat-panel-title>\r\n <div class=\"title-row\">\r\n <div class=\"title\">{{group || 'General'}}</div>\r\n <div class=\"actions\">\r\n <button\r\n type=\"button\"\r\n [matTooltip]=\"'Export ' + (group || 'General') + ' Settings'\"\r\n mat-icon-button\r\n (click)=\"export($event, groupedSettings[group])\">\r\n <mat-icon>cloud_download</mat-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n [matTooltip]=\"'Import ' + (group || 'General') + ' Settings'\"\r\n mat-icon-button\r\n (click)=\"import($event, group)\">\r\n <mat-icon>cloud_upload</mat-icon>\r\n </button>\r\n </div>\r\n </div>\r\n </mat-panel-title>\r\n </mat-expansion-panel-header>\r\n\r\n <div \r\n hideToggle \r\n *ngFor=\"let setting of groupedSettings[group]\" \r\n class=\"setting\"\r\n [ngClass]=\"{ 'has-instruction': !! setting.instruction }\">\r\n <mat-form-field \r\n class=\"full-width form-field-multiline-subscript\"\r\n *ngIf=\"setting.interfaceType===SettingInterfaceType.InputBox\">\r\n <mat-label>{{setting.label}}</mat-label>\r\n <input\r\n matInput\r\n [(ngModel)]=\"setting.value\"\r\n [name]=\"'setting' + setting.id\">\r\n <mat-hint>{{setting.instruction}}</mat-hint>\r\n </mat-form-field>\r\n\r\n <mat-form-field \r\n class=\"full-width form-field-multiline-subscript\" \r\n *ngIf=\"setting.interfaceType===SettingInterfaceType.Textarea\">\r\n <mat-label>{{setting.label}}</mat-label>\r\n <textarea\r\n matInput\r\n [(ngModel)]=\"setting.value\"\r\n [name]=\"'setting' + setting.id\">\r\n </textarea>\r\n <mat-hint>{{setting.instruction}}</mat-hint>\r\n </mat-form-field>\r\n\r\n <mat-form-field \r\n class=\"full-width form-field-multiline-subscript\" \r\n *ngIf=\"setting.interfaceType===SettingInterfaceType.Select || setting.interfaceType===SettingInterfaceType.SelectMultiple\">\r\n <mat-label>{{setting.label}}</mat-label>\r\n <mat-select\r\n [(ngModel)]=\"setting.value\"\r\n [multiple]=\"setting.interfaceType===SettingInterfaceType.SelectMultiple\"\r\n [name]=\"'setting' + setting.id\">\r\n <mat-option *ngFor=\"let item of setting.values | keyNameValue\" [value]=\"item.value\">\r\n {{item.name}}\r\n </mat-option>\r\n </mat-select>\r\n <mat-hint>{{setting.instruction}}</mat-hint>\r\n </mat-form-field>\r\n\r\n <mat-form-field \r\n class=\"full-width form-field-multiline-subscript\" \r\n *ngIf=\"setting.interfaceType===SettingInterfaceType.Date\">\r\n <mat-label>{{setting.label}}</mat-label>\r\n <input\r\n matInput\r\n fsDatePicker\r\n [(ngModel)]=\"setting.value\"\r\n [name]=\"'setting' + setting.id\">\r\n <mat-hint>{{setting.instruction}}</mat-hint>\r\n </mat-form-field>\r\n\r\n <mat-form-field \r\n class=\"full-width form-field-multiline-subscript\" \r\n *ngIf=\"setting.interfaceType===SettingInterfaceType.Color\">\r\n <mat-label>{{setting.label}}</mat-label>\r\n <input\r\n matInput\r\n fsColorPicker\r\n [(ngModel)]=\"setting.value\"\r\n [name]=\"'setting' + setting.id\">\r\n <mat-hint>{{setting.instruction}}</mat-hint>\r\n </mat-form-field>\r\n\r\n <mat-form-field \r\n class=\"full-width form-field-multiline-subscript\" \r\n *ngIf=\"setting.interfaceType===SettingInterfaceType.Time\">\r\n <mat-label>{{setting.label}}</mat-label>\r\n <input\r\n matInput\r\n fsTimePicker\r\n [(ngModel)]=\"setting.value\"\r\n [name]=\"'setting' + setting.id\">\r\n <mat-hint>{{setting.instruction}}</mat-hint>\r\n </mat-form-field>\r\n\r\n <fs-file-picker\r\n *ngIf=\"setting.interfaceType===SettingInterfaceType.File\"\r\n [allowRemove]=\"true\"\r\n [allowDownload]=\"true\"\r\n (select)=\"fileSelect.emit({ setting: setting, file: $event.file })\"\r\n (remove)=\"fileRemove.emit(setting)\"\r\n [url]=\"setting.value\">\r\n <div fsFileLabel>{{setting.label}}</div>\r\n <div fsFileHint>{{setting.instruction}}</div>\r\n </fs-file-picker>\r\n </div>\r\n\r\n <button mat-raised-button color=\"primary\" type=\"button\" (click)=\"saveGroup(group)\">Save</button>\r\n\r\n </mat-expansion-panel>\r\n\r\n</mat-accordion>\r\n", styles: [".mat-expansion-panel-header{font-size:19px}.full-width{width:100%}.title-row{flex-direction:row;box-sizing:border-box;display:flex;place-content:center flex-start;align-items:center;width:100%}.title-row .title{display:flex;flex:1}:host ::ng-deep .mat-expansion-panel-header-title{margin:0}:host ::ng-deep .mat-expansion-panel .actions{display:none}:host ::ng-deep .mat-expansion-panel.mat-expanded .actions{display:block}:host ::ng-deep .setting.has-instruction fs-file-picker fs-label-message{display:block;padding-bottom:1em}\n"] }]
134
+ args: [{ selector: 'fs-system-settings', changeDetection: ChangeDetectionStrategy.OnPush, template: "<mat-accordion>\r\n <mat-expansion-panel\r\n hideToggle\r\n *ngFor=\"let group of groups\">\r\n <mat-expansion-panel-header>\r\n <mat-panel-title>\r\n <div class=\"title-row\">\r\n <div class=\"title\">\r\n {{ group || 'General' }}\r\n </div>\r\n <div class=\"actions\">\r\n <button\r\n type=\"button\"\r\n [matTooltip]=\"'Export ' + (group || 'General') + ' Settings'\"\r\n mat-icon-button\r\n (click)=\"export($event, groupedSettings[group])\">\r\n <mat-icon>\r\n cloud_download\r\n </mat-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n [matTooltip]=\"'Import ' + (group || 'General') + ' Settings'\"\r\n mat-icon-button\r\n (click)=\"import($event, group)\">\r\n <mat-icon>\r\n cloud_upload\r\n </mat-icon>\r\n </button>\r\n </div>\r\n </div>\r\n </mat-panel-title>\r\n </mat-expansion-panel-header>\r\n <div\r\n hideToggle\r\n *ngFor=\"let setting of groupedSettings[group]\"\r\n class=\"setting\"\r\n [ngClass]=\"{ 'has-instruction': !! setting.instruction }\">\r\n <mat-form-field\r\n class=\"full-width form-field-multiline-subscript\"\r\n *ngIf=\"setting.interfaceType===SettingInterfaceType.InputBox\">\r\n <mat-label>\r\n {{ setting.label }}\r\n </mat-label>\r\n <input\r\n matInput\r\n [(ngModel)]=\"setting.value\"\r\n [name]=\"'setting' + setting.id\">\r\n <mat-hint>\r\n {{ setting.instruction }}\r\n </mat-hint>\r\n </mat-form-field>\r\n <mat-form-field\r\n class=\"full-width form-field-multiline-subscript\"\r\n *ngIf=\"setting.interfaceType===SettingInterfaceType.Textarea\">\r\n <mat-label>\r\n {{ setting.label }}\r\n </mat-label>\r\n <textarea\r\n matInput\r\n [(ngModel)]=\"setting.value\"\r\n [name]=\"'setting' + setting.id\">\r\n </textarea>\r\n <mat-hint>\r\n {{ setting.instruction }}\r\n </mat-hint>\r\n </mat-form-field>\r\n <mat-form-field\r\n class=\"full-width form-field-multiline-subscript\"\r\n *ngIf=\"setting.interfaceType===SettingInterfaceType.Select || setting.interfaceType===SettingInterfaceType.SelectMultiple\">\r\n <mat-label>\r\n {{ setting.label }}\r\n </mat-label>\r\n <mat-select\r\n [(ngModel)]=\"setting.value\"\r\n [multiple]=\"setting.interfaceType===SettingInterfaceType.SelectMultiple\"\r\n [name]=\"'setting' + setting.id\">\r\n <mat-option\r\n *ngFor=\"let item of setting.values | keyNameValue\"\r\n [value]=\"item.value\">\r\n {{ item.name }}\r\n </mat-option>\r\n </mat-select>\r\n <mat-hint>\r\n {{ setting.instruction }}\r\n </mat-hint>\r\n </mat-form-field>\r\n <mat-form-field\r\n class=\"full-width form-field-multiline-subscript\"\r\n *ngIf=\"setting.interfaceType===SettingInterfaceType.Date\">\r\n <mat-label>\r\n {{ setting.label }}\r\n </mat-label>\r\n <input\r\n matInput\r\n fsDatePicker\r\n [(ngModel)]=\"setting.value\"\r\n [name]=\"'setting' + setting.id\">\r\n <mat-hint>\r\n {{ setting.instruction }}\r\n </mat-hint>\r\n </mat-form-field>\r\n <mat-form-field\r\n class=\"full-width form-field-multiline-subscript\"\r\n *ngIf=\"setting.interfaceType===SettingInterfaceType.Color\">\r\n <mat-label>\r\n {{ setting.label }}\r\n </mat-label>\r\n <input\r\n matInput\r\n fsColorPicker\r\n [(ngModel)]=\"setting.value\"\r\n [name]=\"'setting' + setting.id\">\r\n <mat-hint>\r\n {{ setting.instruction }}\r\n </mat-hint>\r\n </mat-form-field>\r\n <mat-form-field\r\n class=\"full-width form-field-multiline-subscript\"\r\n *ngIf=\"setting.interfaceType===SettingInterfaceType.Time\">\r\n <mat-label>\r\n {{ setting.label }}\r\n </mat-label>\r\n <input\r\n matInput\r\n fsTimePicker\r\n [(ngModel)]=\"setting.value\"\r\n [name]=\"'setting' + setting.id\">\r\n <mat-hint>\r\n {{ setting.instruction }}\r\n </mat-hint>\r\n </mat-form-field>\r\n <fs-file-picker\r\n *ngIf=\"setting.interfaceType===SettingInterfaceType.File\"\r\n [allowRemove]=\"true\"\r\n [allowDownload]=\"true\"\r\n (select)=\"fileSelect.emit({ setting: setting, file: $event.file })\"\r\n (remove)=\"fileRemove.emit(setting)\"\r\n [url]=\"setting.value\">\r\n <div fsFileLabel>\r\n {{ setting.label }}\r\n </div>\r\n <div fsFileHint>\r\n {{ setting.instruction }}\r\n </div>\r\n </fs-file-picker>\r\n </div>\r\n <button\r\n mat-stroked-button\r\n color=\"primary\"\r\n type=\"button\"\r\n (click)=\"saveGroup(group)\">\r\n Save\r\n </button>\r\n </mat-expansion-panel>\r\n</mat-accordion>", styles: [".mat-expansion-panel-header{font-size:19px}.full-width{width:100%}.title-row{flex-direction:row;box-sizing:border-box;display:flex;place-content:center flex-start;align-items:center;width:100%}.title-row .title{display:flex;flex:1}:host ::ng-deep .mat-expansion-panel-header-title{margin:0}:host ::ng-deep .mat-expansion-panel .actions{display:none}:host ::ng-deep .mat-expansion-panel.mat-expanded .actions{display:block}:host ::ng-deep .setting.has-instruction fs-file-picker fs-label-message{display:block;padding-bottom:1em}\n"] }]
135
135
  }], ctorParameters: () => [{ type: i1.FsMessage }, { type: i2.FsClipboard }, { type: i3.FsPrompt }, { type: i0.ChangeDetectorRef }], propDecorators: { loadSettings: [{
136
136
  type: Input
137
137
  }], save: [{
@@ -141,4 +141,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.7", ngImpor
141
141
  }], fileSelect: [{
142
142
  type: Output
143
143
  }] } });
144
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2V0dGluZ3MuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9tb2R1bGVzL3N5c3RlbS9jb21wb25lbnRzL3NldHRpbmdzL3NldHRpbmdzLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvbW9kdWxlcy9zeXN0ZW0vY29tcG9uZW50cy9zZXR0aW5ncy9zZXR0aW5ncy5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsaUJBQWlCLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQVUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRTNILE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUNwRCxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDekMsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ2hELE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUk5QyxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxhQUFhLENBQUM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFTbkQsTUFBTSxPQUFPLGlCQUFpQjtJQWFsQjtJQUNBO0lBQ0E7SUFDQTtJQWRNLFlBQVksQ0FBK0I7SUFDM0MsSUFBSSxDQUFnRDtJQUVuRCxVQUFVLEdBQUcsSUFBSSxZQUFZLEVBQUUsQ0FBQztJQUNoQyxVQUFVLEdBQUcsSUFBSSxZQUFZLEVBQWdDLENBQUM7SUFFeEUsZUFBZSxHQUFHLEVBQUUsQ0FBQztJQUNyQixNQUFNLEdBQUcsRUFBRSxDQUFDO0lBQ1osb0JBQW9CLEdBQUcsb0JBQW9CLENBQUM7SUFFbkQsWUFDVSxRQUFtQixFQUNuQixVQUF1QixFQUN2QixPQUFpQixFQUNqQixNQUF5QjtRQUh6QixhQUFRLEdBQVIs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QyxLQUFLLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDcEQsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBRVAsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsTUFBTSxDQUFDO2FBQ3JCLFNBQVMsQ0FBQyxHQUFHLEVBQUU7WUFDZCxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxlQUFlLENBQUMsQ0FBQztRQUN6QyxDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7dUdBcEhVLGlCQUFpQjsyRkFBakIsaUJBQWlCLG1MQ2xCOUIsNDBKQTJIQTs7MkZEekdhLGlCQUFpQjtrQkFON0IsU0FBUzsrQkFDRSxvQkFBb0IsbUJBR2IsdUJBQXVCLENBQUMsTUFBTTsrSkFJL0IsWUFBWTtzQkFBM0IsS0FBSztnQkFDVSxJQUFJO3NCQUFuQixLQUFLO2dCQUVXLFVBQVU7c0JBQTFCLE1BQU07Z0JBQ1UsVUFBVTtzQkFBMUIsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENoYW5nZURldGVjdGlvblN0cmF0ZWd5LCBDaGFuZ2VEZXRlY3RvclJlZiwgQ29tcG9uZW50LCBFdmVudEVtaXR0ZXIsIElucHV0LCBPbkluaXQsIE91dHB1dCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5cclxuaW1wb3J0IHsgRnNDbGlwYm9hcmQgfSBmcm9tICdAZmlyZXN0aXRjaC9jbGlwYm9hcmQnO1xyXG5pbXBvcnQgeyBwYXJzZSB9IGZyb20gJ0BmaXJlc3RpdGNoL2RhdGUnO1xyXG5pbXBvcnQgeyBGc01lc3NhZ2UgfSBmcm9tICdAZmlyZXN0aXRjaC9tZXNzYWdlJztcclxuaW1wb3J0IHsgRnNQcm9tcHQgfSBmcm9tICdAZmlyZXN0aXRjaC9wcm9tcHQnO1xyXG5cclxuaW1wb3J0IHsgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xyXG5cclxuaW1wb3J0IHsgU2V0dGluZ0ludGVyZmFjZVR5cGUgfSBmcm9tICcuLi8uLi9lbnVtcyc7XHJcblxyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgc2VsZWN0b3I6ICdmcy1zeXN0ZW0tc2V0dGluZ3MnLFxyXG4gIHRlbXBsYXRlVXJsOiAnLi9zZXR0aW5ncy5jb21wb25lbnQuaHRtbCcsXHJcbiAgc3R5bGVVcmxzOiBbJy4vc2V0dGluZ3MuY29tcG9uZW50LnNjc3MnXSxcclxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcclxufSlcclxuZXhwb3J0IGNsYXNzIFNldHRpbmdzQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcclxuXHJcbiAgQElucHV0KCkgcHVibGljIGxvYWRTZXR0aW5nczogKHF1ZXJ5KSA9PiBPYnNlcnZhYmxlPGFueVtdPjtcclxuICBASW5wdXQoKSBwdWJsaWMgc2F2ZTogKGRhdGE6IGFueSwgZ3JvdXA6IHN0cmluZykgPT4gT2JzZXJ2YWJsZTxhbnk+O1xyXG5cclxuICBAT3V0cHV0KCkgcHVibGljIGZpbGVSZW1vdmUgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XHJcbiAgQE91dHB1dCgpIHB1YmxpYyBmaWxlU2VsZWN0ID0gbmV3IEV2ZW50RW1pdHRlcjx7IHNldHRpbmc6IGFueSwgZmlsZTogQmxvYiB9PigpO1xyXG5cclxuICBwdWJsaWMgZ3JvdXBlZFNldHRpbmdzID0gW107XHJcbiAgcHVibGljIGdyb3VwcyA9IFtdO1xyXG4gIHB1YmxpYyBTZXR0aW5nSW50ZXJmYWNlVHlwZSA9IFNldHRpbmdJbnRlcmZhY2VUeXBlO1xyXG5cclxuICBjb25zdHJ1Y3RvcihcclxuICAgIHByaXZhdGUgX21lc3NhZ2U6IEZzTWVzc2FnZSxcclxuICAgIHByaXZhdGUgX2NsaXBib2FyZDogRnNDbGlwYm9hcmQsXHJcbiAgICBwcml2YXRlIF9wcm9tcHQ6IEZzUHJvbXB0LFxyXG4gICAgcHJpdmF0ZSBfY2RSZWY6IENoYW5nZURldGVjdG9yUmVmLFxyXG4gICkgeyB9XHJcblxyXG4gIHB1YmxpYyBuZ09uSW5pdCgpOiB2b2lkIHtcclxuICAgIHRoaXMubG9hZFNldHRpbmdzKHtcclxuICAgICAgdmlzaWJsZTogdHJ1ZSxcclxuICAgIH0pXHJcbiAgICAgIC5zdWJzY3JpYmUoKHNldHRpbmdzKSA9PiB7XHJcbiAgICAgICAgc2V0dGluZ3MgPSBzZXR0aW5nc1xyXG4gICAgICAgICAgLmZpbHRlcigoc2V0dGluZykgPT4ge1xyXG4gICAgICAgICAgICByZXR1cm4gc2V0dGluZy5pbnRlcmZhY2VUeXBlICE9PSBTZXR0aW5nSW50ZXJmYWNlVHlwZS5Ob25lO1xyXG4gICAgICAgICAgfSlcclxuICAgICAgICAgIC5tYXAoKHNldHRpbmcpID0+IHtcclxuICAgICAgICAgICAgc3dpdGNoIChzZXR0aW5nLmludGVyZmFjZVR5cGUpIHtcclxuICAgICAgICAgICAgICBjYXNlIFNldHRpbmdJbnRlcmZhY2VUeXBlLkRhdGU6XHJcbiAgICAgICAgICAgICAgY2FzZSBTZXR0aW5nSW50ZXJmYWNlVHlwZS5UaW1lOlxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgICAgLi4uc2V0dGluZyxcclxuICAgICAgICAgICAgICAgICAgdmFsdWU6IHBhcnNlKHNldHRpbmcudmFsdWUpLFxyXG4gICAgICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgICAgY2FzZSBTZXR0aW5nSW50ZXJmYWNlVHlwZS5TZWxlY3RNdWx0aXBsZTpcclxuICAgICAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICAgIC4uLnNldHRpbmcsXHJcbiAgICAgICAgICAgICAgICAgIHZhbHVlOiBBcnJheS5pc0FycmF5KHNldHRpbmcudmFsdWUpID8gc2V0dGluZy52YWx1ZSA6IFtdLFxyXG4gICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBcclxuICAgICAgICAgICAgcmV0dXJuIHNldHRpbmc7XHJcbiAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgdGhpcy5ncm91cGVkU2V0dGluZ3MgPSBzZXR0aW5ncy5yZWR1Y2UoKGFjY3VtLCBpdGVtKSA9PiB7XHJcbiAgICAgICAgICBpZihhY2N1bVtpdGVtLmdyb3VwXSA9PT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgIGFjY3VtW2l0ZW0uZ3JvdXBdID0gW107XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgICBhY2N1bVtpdGVtLmdyb3VwXS5wdXNoKGl0ZW0pO1xyXG5cclxuICAgICAgICAgIHJldHVybiBhY2N1bTtcclxuICAgICAgICB9LCB7fSk7XHJcbiAgICAgICAgXHJcbiAgICAgICAgdGhpcy5ncm91cHMgPSBPYmplY3Qua2V5cyh0aGlzLmdyb3VwZWRTZXR0aW5ncyk7XHJcbiAgICAgICAgdGhpcy5fY2RSZWYubWFya0ZvckNoZWNrKCk7XHJcbiAgICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGV4cG9ydChldmVudDogVUlFdmVudCwgc2V0dGluZ3MpOiB2b2lkIHtcclxuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xyXG4gICAgY29uc3QgZGF0YSA9IHNldHRpbmdzLm1hcCgoc2V0dGluZykgPT4ge1xyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgIG5hbWU6IHNldHRpbmcubmFtZSxcclxuICAgICAgICB2YWx1ZTogc2V0dGluZy52YWx1ZSxcclxuICAgICAgICBncm91cDogc2V0dGluZy5ncm91cCxcclxuICAgICAgfTtcclxuICAgIH0pO1xyXG5cclxuICAgIHRoaXMuX2NsaXBib2FyZC5jb3B5KEpTT04uc3RyaW5naWZ5KGRhdGEpKTtcclxuICAgIHRoaXMuX21lc3NhZ2Uuc3VjY2VzcygnQ29waWVkIHRvIGNsaXBib2FyZCcpO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGltcG9ydChldmVudDogVUlFdmVudCwgZ3JvdXApOiB2b2lkIHtcclxuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xyXG4gICAgdGhpcy5fcHJvbXB0LmlucHV0KHtcclxuICAgICAgbGFiZWw6ICdKU09OIEltcG9ydCcsXHJcbiAgICAgIHRpdGxlOiAnSW1wb3J0IFNldHRpbmdzJyxcclxuICAgICAgY29tbWl0TGFiZWw6ICdJbXBvcnQnLFxyXG4gICAgICByZXF1aXJlZDogdHJ1ZSxcclxuICAgIH0pLnN1YnNjcmliZSgodmFsdWU6IHN0cmluZykgPT4ge1xyXG4gICAgICBpZiAodmFsdWUpIHtcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgY29uc3Qgc2V0dGluZ3MgPSB0aGlzLmdyb3VwZWRTZXR0aW5nc1tncm91cF07XHJcbiAgICAgICAgICBjb25zdCBkYXRhID0gSlNPTi5wYXJzZSh2YWx1ZSk7XHJcblxyXG4gICAgICAgICAgZGF0YS5mb3JFYWNoKChpdGVtKSA9PiB7XHJcbiAgICAgICAgICAgIGNvbnN0IHNldHRpbmcgPSBzZXR0aW5ncy5maW5kKChzKSA9PiB7XHJcbiAgICAgICAgICAgICAgcmV0dXJuIGl0ZW0ubmFtZSA9PT0gcy5uYW1lO1xyXG4gICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgIGlmIChzZXR0aW5nKSB7XHJcbiAgICAgICAgICAgICAgT2JqZWN0LmFzc2lnbihzZXR0aW5nLCBpdGVtKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgdGhpcy5fY2RSZWYubWFya0ZvckNoZWNrKCk7XHJcbiAgICAgICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgdGhpcy5fbWVzc2FnZS5lcnJvcihlKTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIHNhdmVHcm91cChncm91cCk6IHZvaWQge1xyXG4gICAgY29uc3Qgc2V0dGluZ3MgPSB0aGlzLmdyb3VwZWRTZXR0aW5nc1tncm91cF07XHJcbiAgICBjb25zdCB2YWx1ZXMgPSBzZXR0aW5ncy5yZWR1Y2UoKHJlc3VsdCwgdmFsdWUpID0+IHtcclxuICAgICAgcmV0dXJuIChyZXN1bHRbdmFsdWUubmFtZV0gPSB2YWx1ZS52YWx1ZSwgcmVzdWx0KTtcclxuICAgIH0sIHt9KTtcclxuXHJcbiAgICB0aGlzLnNhdmUoZ3JvdXAsIHZhbHVlcylcclxuICAgICAgLnN1YnNjcmliZSgoKSA9PiB7XHJcbiAgICAgICAgdGhpcy5fbWVzc2FnZS5zdWNjZXNzKCdDaGFuZ2VzIFNhdmVkJyk7XHJcbiAgICAgIH0pO1xyXG4gIH1cclxufVxyXG4iLCJcclxuPG1hdC1hY2NvcmRpb24+XHJcbiAgPG1hdC1leHBhbnNpb24tcGFuZWwgaGlkZVRvZ2dsZSAqbmdGb3I9XCJsZXQgZ3JvdXAgb2YgZ3JvdXBzXCI+XHJcbiAgICA8bWF0LWV4cGFuc2lvbi1wYW5lbC1oZWFkZXI+XHJcbiAgICAgIDxtYXQtcGFuZWwtdGl0bGU+XHJcbiAgICAgICAgPGRpdiBjbGFzcz1cInRpdGxlLXJvd1wiPlxyXG4gICAgICAgICAgPGRpdiBjbGFzcz1cInRpdGxlXCI+e3tncm91cCB8fCAnR2VuZXJhbCd9fTwvZGl2PlxyXG4gICAgICAgICAgPGRpdiBjbGFzcz1cImFjdGlvbnNcIj5cclxuICAgICAgICAgICAgPGJ1dHRvblxyXG4gICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxyXG4gICAgICAgICAgICAgIFttYXRUb29sdGlwXT1cIidFeHBvcnQgJyArIChncm91cCB8fCAnR2VuZXJhbCcpICsgJyBTZXR0aW5ncydcIlxyXG4gICAgICAgICAgICAgIG1hdC1pY29uLWJ1dHRvblxyXG4gICAgICAgICAgICAgIChjbGljayk9XCJleHBvcnQoJGV2ZW50LCBncm91cGVkU2V0dGluZ3NbZ3JvdXBdKVwiPlxyXG4gICAgICAgICAgICAgIDxtYXQtaWNvbj5jbG91ZF9kb3dubG9hZDwvbWF0LWljb24+XHJcbiAgICAgICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgICAgICA8YnV0dG9uXHJcbiAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXHJcbiAgICAgICAgICAgICAgW21hdFRvb2x0aXBdPVwiJ0ltcG9ydCAnICsgKGdyb3VwIHx8ICdHZW5lcmFsJykgKyAnIFNldHRpbmdzJ1wiXHJcbiAgICAgICAgICAgICAgbWF0LWljb24tYnV0dG9uXHJcbiAgICAgICAgICAgICAgKGNsaWNrKT1cImltcG9ydCgkZXZlbnQsIGdyb3VwKVwiPlxyXG4gICAgICAgICAgICAgIDxtYXQtaWNvbj5jbG91ZF91cGxvYWQ8L21hdC1pY29uPlxyXG4gICAgICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgIDwvZGl2PlxyXG4gICAgICA8L21hdC1wYW5lbC10aXRsZT5cclxuICAgIDwvbWF0LWV4cGFuc2lvbi1wYW5lbC1oZWFkZXI+XHJcblxyXG4gICAgPGRpdiBcclxuICAgICAgICBoaWRlVG9nZ2xlIFxyXG4gICAgICAgICpuZ0Zvcj1cImxldCBzZXR0aW5nIG9mIGdyb3VwZWRTZXR0aW5nc1tncm91cF1cIiBcclxuICAgICAgICBjbGFzcz1cInNldHRpbmdcIlxyXG4gICAgICAgIFtuZ0NsYXNzXT1cInsgJ2hhcy1pbnN0cnVjdGlvbic6ICEhIHNldHRpbmcuaW5zdHJ1Y3Rpb24gfVwiPlxyXG4gICAgICA8bWF0LWZvcm0tZmllbGQgXHJcbiAgICAgICAgICBjbGFzcz1cImZ1bGwtd2lkdGggZm9ybS1maWVsZC1tdWx0aWxpbmUtc3Vic2NyaXB0XCJcclxuICAgICAgICAgICpuZ0lmPVwic2V0dGluZy5pbnRlcmZhY2VUeXBlPT09U2V0dGluZ0ludGVyZmFjZVR5cGUuSW5wdXRCb3hcIj5cclxuICAgICAgICA8bWF0LWxhYmVsPnt7c2V0dGluZy5sYWJlbH19PC9tYXQtbGFiZWw+XHJcbiAgICAgICAgPGlucHV0XHJcbiAgICAgICAgICBtYXRJbnB1dFxyXG4gICAgICAgICAgWyhuZ01vZGVsKV09XCJzZXR0aW5nLnZhbHVlXCJcclxuICAgICAgICAgIFtuYW1lXT1cIidzZXR0aW5nJyArIHNldHRpbmcuaWRcIj5cclxuICAgICAgICAgIDxtYXQtaGludD57e3NldHRpbmcuaW5zdHJ1Y3Rpb259fTwvbWF0LWhpbnQ+XHJcbiAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcblxyXG4gICAgICA8bWF0LWZvcm0tZmllbGQgXHJcbiAgICAgICAgICBjbGFzcz1cImZ1bGwtd2lkdGggZm9ybS1maWVsZC1tdWx0aWxpbmUtc3Vic2NyaXB0XCIgXHJcbiAgICAgICAgICAqbmdJZj1cInNldHRpbmcuaW50ZXJmYWNlVHlwZT09PVNldHRpbmdJbnRlcmZhY2VUeXBlLlRleHRhcmVhXCI+XHJcbiAgICAgICAgPG1hdC1sYWJlbD57e3NldHRpbmcubGFiZWx9fTwvbWF0LWxhYmVsPlxyXG4gICAgICAgIDx0ZXh0YXJlYVxyXG4gICAgICAgICAgbWF0SW5wdXRcclxuICAgICAgICAgIFsobmdNb2RlbCldPVwic2V0dGluZy52YWx1ZVwiXHJcbiAgICAgICAgICBbbmFtZV09XCInc2V0dGluZycgKyBzZXR0aW5nLmlkXCI+XHJcbiAgICAgICAgPC90ZXh0YXJlYT5cclxuICAgICAgICA8bWF0LWhpbnQ+e3tzZXR0aW5nLmluc3RydWN0aW9ufX08L21hdC1oaW50PlxyXG4gICAgICA8L21hdC1mb3JtLWZpZWxkPlxyXG5cclxuICAgICAgPG1hdC1mb3JtLWZpZWxkIFxyXG4gICAgICAgICAgY2xhc3M9XCJmdWxsLXdpZHRoIGZvcm0tZmllbGQtbXVsdGlsaW5lLXN1YnNjcmlwdFwiIFxyXG4gICAgICAgICAgKm5nSWY9XCJzZXR0aW5nLmludGVyZmFjZVR5cGU9PT1TZXR0aW5nSW50ZXJmYWNlVHlwZS5TZWxlY3QgfHwgc2V0dGluZy5pbnRlcmZhY2VUeXBlPT09U2V0dGluZ0ludGVyZmFjZVR5cGUuU2VsZWN0TXVsdGlwbGVcIj5cclxuICAgICAgICA8bWF0LWxhYmVsPnt7c2V0dGluZy5sYWJlbH19PC9tYXQtbGFiZWw+XHJcbiAgICAgICAgPG1hdC1zZWxlY3RcclxuICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJzZXR0aW5nLnZhbHVlXCJcclxuICAgICAgICAgICAgW211bHRpcGxlXT1cInNldHRpbmcuaW50ZXJmYWNlVHlwZT09PVNldHRpbmdJbnRlcmZhY2VUeXBlLlNlbGVjdE11bHRpcGxlXCJcclxuICAgICAgICAgICAgW25hbWVdPVwiJ3NldHRpbmcnICsgc2V0dGluZy5pZFwiPlxyXG4gICAgICAgICAgPG1hdC1vcHRpb24gKm5nRm9yPVwibGV0IGl0ZW0gb2Ygc2V0dGluZy52YWx1ZXMgfCBrZXlOYW1lVmFsdWVcIiBbdmFsdWVdPVwiaXRlbS52YWx1ZVwiPlxyXG4gICAgICAgICAgICB7e2l0ZW0ubmFtZX19XHJcbiAgICAgICAgICA8L21hdC1vcHRpb24+XHJcbiAgICAgICAgPC9tYXQtc2VsZWN0PlxyXG4gICAgICAgIDxtYXQtaGludD57e3NldHRpbmcuaW5zdHJ1Y3Rpb259fTwvbWF0LWhpbnQ+XHJcbiAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcblxyXG4gICAgICA8bWF0LWZvcm0tZmllbGQgXHJcbiAgICAgICAgICBjbGFzcz1cImZ1bGwtd2lkdGggZm9ybS1maWVsZC1tdWx0aWxpbmUtc3Vic2NyaXB0XCIgXHJcbiAgICAgICAgICAqbmdJZj1cInNldHRpbmcuaW50ZXJmYWNlVHlwZT09PVNldHRpbmdJbnRlcmZhY2VUeXBlLkRhdGVcIj5cclxuICAgICAgICA8bWF0LWxhYmVsPnt7c2V0dGluZy5sYWJlbH19PC9tYXQtbGFiZWw+XHJcbiAgICAgICAgPGlucHV0XHJcbiAgICAgICAgICBtYXRJbnB1dFxyXG4gICAgICAgICAgZnNEYXRlUGlja2VyXHJcbiAgICAgICAgICBbKG5nTW9kZWwpXT1cInNldHRpbmcudmFsdWVcIlxyXG4gICAgICAgICAgW25hbWVdPVwiJ3NldHRpbmcnICsgc2V0dGluZy5pZFwiPlxyXG4gICAgICAgICAgPG1hdC1oaW50Pnt7c2V0dGluZy5pbnN0cnVjdGlvbn19PC9tYXQtaGludD5cclxuICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuXHJcbiAgICAgIDxtYXQtZm9ybS1maWVsZCBcclxuICAgICAgICAgIGNsYXNzPVwiZnVsbC13aWR0aCBmb3JtLWZpZWxkLW11bHRpbGluZS1zdWJzY3JpcHRcIiBcclxuICAgICAgICAgICpuZ0lmPVwic2V0dGluZy5pbnRlcmZhY2VUeXBlPT09U2V0dGluZ0ludGVyZmFjZVR5cGUuQ29sb3JcIj5cclxuICAgICAgICA8bWF0LWxhYmVsPnt7c2V0dGluZy5sYWJlbH19PC9tYXQtbGFiZWw+XHJcbiAgICAgICAgPGlucHV0XHJcbiAgICAgICAgICBtYXRJbnB1dFxyXG4gICAgICAgICAgZnNDb2xvclBpY2tlclxyXG4gICAgICAgICAgWyhuZ01vZGVsKV09XCJzZXR0aW5nLnZhbHVlXCJcclxuICAgICAgICAgIFtuYW1lXT1cIidzZXR0aW5nJyArIHNldHRpbmcuaWRcIj5cclxuICAgICAgICAgIDxtYXQtaGludD57e3NldHRpbmcuaW5zdHJ1Y3Rpb259fTwvbWF0LWhpbnQ+XHJcbiAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcblxyXG4gICAgICA8bWF0LWZvcm0tZmllbGQgXHJcbiAgICAgICAgICBjbGFzcz1cImZ1bGwtd2lkdGggZm9ybS1maWVsZC1tdWx0aWxpbmUtc3Vic2NyaXB0XCIgXHJcbiAgICAgICAgICAqbmdJZj1cInNldHRpbmcuaW50ZXJmYWNlVHlwZT09PVNldHRpbmdJbnRlcmZhY2VUeXBlLlRpbWVcIj5cclxuICAgICAgICA8bWF0LWxhYmVsPnt7c2V0dGluZy5sYWJlbH19PC9tYXQtbGFiZWw+XHJcbiAgICAgICAgPGlucHV0XHJcbiAgICAgICAgICBtYXRJbnB1dFxyXG4gICAgICAgICAgZnNUaW1lUGlja2VyXHJcbiAgICAgICAgICBbKG5nTW9kZWwpXT1cInNldHRpbmcudmFsdWVcIlxyXG4gICAgICAgICAgW25hbWVdPVwiJ3NldHRpbmcnICsgc2V0dGluZy5pZFwiPlxyXG4gICAgICAgICAgPG1hdC1oaW50Pnt7c2V0dGluZy5pbnN0cnVjdGlvbn19PC9tYXQtaGludD5cclxuICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuXHJcbiAgICAgIDxmcy1maWxlLXBpY2tlclxyXG4gICAgICAgICAgKm5nSWY9XCJzZXR0aW5nLmludGVyZmFjZVR5cGU9PT1TZXR0aW5nSW50ZXJmYWNlVHlwZS5GaWxlXCJcclxuICAgICAgICAgIFthbGxvd1JlbW92ZV09XCJ0cnVlXCJcclxuICAgICAgICAgIFthbGxvd0Rvd25sb2FkXT1cInRydWVcIlxyXG4gICAgICAgICAgKHNlbGVjdCk9XCJmaWxlU2VsZWN0LmVtaXQoeyBzZXR0aW5nOiBzZXR0aW5nLCBmaWxlOiAkZXZlbnQuZmlsZSB9KVwiXHJcbiAgICAgICAgICAocmVtb3ZlKT1cImZpbGVSZW1vdmUuZW1pdChzZXR0aW5nKVwiXHJcbiAgICAgICAgICBbdXJsXT1cInNldHRpbmcudmFsdWVcIj5cclxuICAgICAgICA8ZGl2IGZzRmlsZUxhYmVsPnt7c2V0dGluZy5sYWJlbH19PC9kaXY+XHJcbiAgICAgICAgPGRpdiBmc0ZpbGVIaW50Pnt7c2V0dGluZy5pbnN0cnVjdGlvbn19PC9kaXY+XHJcbiAgICAgIDwvZnMtZmlsZS1waWNrZXI+XHJcbiAgICA8L2Rpdj5cclxuXHJcbiAgICA8YnV0dG9uIG1hdC1yYWlzZWQtYnV0dG9uIGNvbG9yPVwicHJpbWFyeVwiIHR5cGU9XCJidXR0b25cIiAoY2xpY2spPVwic2F2ZUdyb3VwKGdyb3VwKVwiPlNhdmU8L2J1dHRvbj5cclxuXHJcbiAgPC9tYXQtZXhwYW5zaW9uLXBhbmVsPlxyXG5cclxuPC9tYXQtYWNjb3JkaW9uPlxyXG4iXX0=
144
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2V0dGluZ3MuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9tb2R1bGVzL3N5c3RlbS9jb21wb25lbnRzL3NldHRpbmdzL3NldHRpbmdzLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvbW9kdWxlcy9zeXN0ZW0vY29tcG9uZW50cy9zZXR0aW5ncy9zZXR0aW5ncy5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsaUJBQWlCLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQVUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRTNILE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUNwRCxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDekMsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ2hELE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUk5QyxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxhQUFhLENBQUM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFTbkQsTUFBTSxPQUFPLGlCQUFpQjtJQWFsQjtJQUNBO0lBQ0E7SUFDQTtJQWRNLFlBQVksQ0FBK0I7SUFDM0MsSUFBSSxDQUFnRDtJQUVuRCxVQUFVLEdBQUcsSUFBSSxZQUFZLEVBQUUsQ0FBQztJQUNoQyxVQUFVLEdBQUcsSUFBSSxZQUFZLEVBQWdDLENBQUM7SUFFeEUsZUFBZSxHQUFHLEVBQUUsQ0FBQztJQUNyQixNQUFNLEdBQUcsRUFBRSxDQUFDO0lBQ1osb0JBQW9CLEdBQUcsb0JBQW9CLENBQUM7SUFFbkQsWUFDVSxRQUFtQixFQUNuQixVQUF1QixFQUN2QixPQUFpQixFQUNqQixNQUF5QjtRQUh6QixhQUFRLEdBQVIs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QyxLQUFLLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDcEQsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBRVAsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsTUFBTSxDQUFDO2FBQ3JCLFNBQVMsQ0FBQyxHQUFHLEVBQUU7WUFDZCxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxlQUFlLENBQUMsQ0FBQztRQUN6QyxDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7dUdBcEhVLGlCQUFpQjsyRkFBakIsaUJBQWlCLG1MQ2xCOUIsKzNLQTJKZ0I7OzJGRHpJSCxpQkFBaUI7a0JBTjdCLFNBQVM7K0JBQ0Usb0JBQW9CLG1CQUdiLHVCQUF1QixDQUFDLE1BQU07K0pBSS9CLFlBQVk7c0JBQTNCLEtBQUs7Z0JBQ1UsSUFBSTtzQkFBbkIsS0FBSztnQkFFVyxVQUFVO3NCQUExQixNQUFNO2dCQUNVLFVBQVU7c0JBQTFCLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSwgQ2hhbmdlRGV0ZWN0b3JSZWYsIENvbXBvbmVudCwgRXZlbnRFbWl0dGVyLCBJbnB1dCwgT25Jbml0LCBPdXRwdXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuXHJcbmltcG9ydCB7IEZzQ2xpcGJvYXJkIH0gZnJvbSAnQGZpcmVzdGl0Y2gvY2xpcGJvYXJkJztcclxuaW1wb3J0IHsgcGFyc2UgfSBmcm9tICdAZmlyZXN0aXRjaC9kYXRlJztcclxuaW1wb3J0IHsgRnNNZXNzYWdlIH0gZnJvbSAnQGZpcmVzdGl0Y2gvbWVzc2FnZSc7XHJcbmltcG9ydCB7IEZzUHJvbXB0IH0gZnJvbSAnQGZpcmVzdGl0Y2gvcHJvbXB0JztcclxuXHJcbmltcG9ydCB7IE9ic2VydmFibGUgfSBmcm9tICdyeGpzJztcclxuXHJcbmltcG9ydCB7IFNldHRpbmdJbnRlcmZhY2VUeXBlIH0gZnJvbSAnLi4vLi4vZW51bXMnO1xyXG5cclxuXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAnZnMtc3lzdGVtLXNldHRpbmdzJyxcclxuICB0ZW1wbGF0ZVVybDogJy4vc2V0dGluZ3MuY29tcG9uZW50Lmh0bWwnLFxyXG4gIHN0eWxlVXJsczogWycuL3NldHRpbmdzLmNvbXBvbmVudC5zY3NzJ10sXHJcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBTZXR0aW5nc0NvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XHJcblxyXG4gIEBJbnB1dCgpIHB1YmxpYyBsb2FkU2V0dGluZ3M6IChxdWVyeSkgPT4gT2JzZXJ2YWJsZTxhbnlbXT47XHJcbiAgQElucHV0KCkgcHVibGljIHNhdmU6IChkYXRhOiBhbnksIGdyb3VwOiBzdHJpbmcpID0+IE9ic2VydmFibGU8YW55PjtcclxuXHJcbiAgQE91dHB1dCgpIHB1YmxpYyBmaWxlUmVtb3ZlID0gbmV3IEV2ZW50RW1pdHRlcigpO1xyXG4gIEBPdXRwdXQoKSBwdWJsaWMgZmlsZVNlbGVjdCA9IG5ldyBFdmVudEVtaXR0ZXI8eyBzZXR0aW5nOiBhbnksIGZpbGU6IEJsb2IgfT4oKTtcclxuXHJcbiAgcHVibGljIGdyb3VwZWRTZXR0aW5ncyA9IFtdO1xyXG4gIHB1YmxpYyBncm91cHMgPSBbXTtcclxuICBwdWJsaWMgU2V0dGluZ0ludGVyZmFjZVR5cGUgPSBTZXR0aW5nSW50ZXJmYWNlVHlwZTtcclxuXHJcbiAgY29uc3RydWN0b3IoXHJcbiAgICBwcml2YXRlIF9tZXNzYWdlOiBGc01lc3NhZ2UsXHJcbiAgICBwcml2YXRlIF9jbGlwYm9hcmQ6IEZzQ2xpcGJvYXJkLFxyXG4gICAgcHJpdmF0ZSBfcHJvbXB0OiBGc1Byb21wdCxcclxuICAgIHByaXZhdGUgX2NkUmVmOiBDaGFuZ2VEZXRlY3RvclJlZixcclxuICApIHsgfVxyXG5cclxuICBwdWJsaWMgbmdPbkluaXQoKTogdm9pZCB7XHJcbiAgICB0aGlzLmxvYWRTZXR0aW5ncyh7XHJcbiAgICAgIHZpc2libGU6IHRydWUsXHJcbiAgICB9KVxyXG4gICAgICAuc3Vic2NyaWJlKChzZXR0aW5ncykgPT4ge1xyXG4gICAgICAgIHNldHRpbmdzID0gc2V0dGluZ3NcclxuICAgICAgICAgIC5maWx0ZXIoKHNldHRpbmcpID0+IHtcclxuICAgICAgICAgICAgcmV0dXJuIHNldHRpbmcuaW50ZXJmYWNlVHlwZSAhPT0gU2V0dGluZ0ludGVyZmFjZVR5cGUuTm9uZTtcclxuICAgICAgICAgIH0pXHJcbiAgICAgICAgICAubWFwKChzZXR0aW5nKSA9PiB7XHJcbiAgICAgICAgICAgIHN3aXRjaCAoc2V0dGluZy5pbnRlcmZhY2VUeXBlKSB7XHJcbiAgICAgICAgICAgICAgY2FzZSBTZXR0aW5nSW50ZXJmYWNlVHlwZS5EYXRlOlxyXG4gICAgICAgICAgICAgIGNhc2UgU2V0dGluZ0ludGVyZmFjZVR5cGUuVGltZTpcclxuICAgICAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICAgIC4uLnNldHRpbmcsXHJcbiAgICAgICAgICAgICAgICAgIHZhbHVlOiBwYXJzZShzZXR0aW5nLnZhbHVlKSxcclxuICAgICAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICAgIGNhc2UgU2V0dGluZ0ludGVyZmFjZVR5cGUuU2VsZWN0TXVsdGlwbGU6XHJcbiAgICAgICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgICAuLi5zZXR0aW5nLFxyXG4gICAgICAgICAgICAgICAgICB2YWx1ZTogQXJyYXkuaXNBcnJheShzZXR0aW5nLnZhbHVlKSA/IHNldHRpbmcudmFsdWUgOiBbXSxcclxuICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgXHJcbiAgICAgICAgICAgIHJldHVybiBzZXR0aW5nO1xyXG4gICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIHRoaXMuZ3JvdXBlZFNldHRpbmdzID0gc2V0dGluZ3MucmVkdWNlKChhY2N1bSwgaXRlbSkgPT4ge1xyXG4gICAgICAgICAgaWYoYWNjdW1baXRlbS5ncm91cF0gPT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICBhY2N1bVtpdGVtLmdyb3VwXSA9IFtdO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgYWNjdW1baXRlbS5ncm91cF0ucHVzaChpdGVtKTtcclxuXHJcbiAgICAgICAgICByZXR1cm4gYWNjdW07XHJcbiAgICAgICAgfSwge30pO1xyXG4gICAgICAgIFxyXG4gICAgICAgIHRoaXMuZ3JvdXBzID0gT2JqZWN0LmtleXModGhpcy5ncm91cGVkU2V0dGluZ3MpO1xyXG4gICAgICAgIHRoaXMuX2NkUmVmLm1hcmtGb3JDaGVjaygpO1xyXG4gICAgICB9KTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBleHBvcnQoZXZlbnQ6IFVJRXZlbnQsIHNldHRpbmdzKTogdm9pZCB7XHJcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcclxuICAgIGNvbnN0IGRhdGEgPSBzZXR0aW5ncy5tYXAoKHNldHRpbmcpID0+IHtcclxuICAgICAgcmV0dXJuIHtcclxuICAgICAgICBuYW1lOiBzZXR0aW5nLm5hbWUsXHJcbiAgICAgICAgdmFsdWU6IHNldHRpbmcudmFsdWUsXHJcbiAgICAgICAgZ3JvdXA6IHNldHRpbmcuZ3JvdXAsXHJcbiAgICAgIH07XHJcbiAgICB9KTtcclxuXHJcbiAgICB0aGlzLl9jbGlwYm9hcmQuY29weShKU09OLnN0cmluZ2lmeShkYXRhKSk7XHJcbiAgICB0aGlzLl9tZXNzYWdlLnN1Y2Nlc3MoJ0NvcGllZCB0byBjbGlwYm9hcmQnKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBpbXBvcnQoZXZlbnQ6IFVJRXZlbnQsIGdyb3VwKTogdm9pZCB7XHJcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcclxuICAgIHRoaXMuX3Byb21wdC5pbnB1dCh7XHJcbiAgICAgIGxhYmVsOiAnSlNPTiBJbXBvcnQnLFxyXG4gICAgICB0aXRsZTogJ0ltcG9ydCBTZXR0aW5ncycsXHJcbiAgICAgIGNvbW1pdExhYmVsOiAnSW1wb3J0JyxcclxuICAgICAgcmVxdWlyZWQ6IHRydWUsXHJcbiAgICB9KS5zdWJzY3JpYmUoKHZhbHVlOiBzdHJpbmcpID0+IHtcclxuICAgICAgaWYgKHZhbHVlKSB7XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgIGNvbnN0IHNldHRpbmdzID0gdGhpcy5ncm91cGVkU2V0dGluZ3NbZ3JvdXBdO1xyXG4gICAgICAgICAgY29uc3QgZGF0YSA9IEpTT04ucGFyc2UodmFsdWUpO1xyXG5cclxuICAgICAgICAgIGRhdGEuZm9yRWFjaCgoaXRlbSkgPT4ge1xyXG4gICAgICAgICAgICBjb25zdCBzZXR0aW5nID0gc2V0dGluZ3MuZmluZCgocykgPT4ge1xyXG4gICAgICAgICAgICAgIHJldHVybiBpdGVtLm5hbWUgPT09IHMubmFtZTtcclxuICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICBpZiAoc2V0dGluZykge1xyXG4gICAgICAgICAgICAgIE9iamVjdC5hc3NpZ24oc2V0dGluZywgaXRlbSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgIHRoaXMuX2NkUmVmLm1hcmtGb3JDaGVjaygpO1xyXG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcclxuICAgICAgICAgIHRoaXMuX21lc3NhZ2UuZXJyb3IoZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBzYXZlR3JvdXAoZ3JvdXApOiB2b2lkIHtcclxuICAgIGNvbnN0IHNldHRpbmdzID0gdGhpcy5ncm91cGVkU2V0dGluZ3NbZ3JvdXBdO1xyXG4gICAgY29uc3QgdmFsdWVzID0gc2V0dGluZ3MucmVkdWNlKChyZXN1bHQsIHZhbHVlKSA9PiB7XHJcbiAgICAgIHJldHVybiAocmVzdWx0W3ZhbHVlLm5hbWVdID0gdmFsdWUudmFsdWUsIHJlc3VsdCk7XHJcbiAgICB9LCB7fSk7XHJcblxyXG4gICAgdGhpcy5zYXZlKGdyb3VwLCB2YWx1ZXMpXHJcbiAgICAgIC5zdWJzY3JpYmUoKCkgPT4ge1xyXG4gICAgICAgIHRoaXMuX21lc3NhZ2Uuc3VjY2VzcygnQ2hhbmdlcyBTYXZlZCcpO1xyXG4gICAgICB9KTtcclxuICB9XHJcbn1cclxuIiwiPG1hdC1hY2NvcmRpb24+XHJcbiAgPG1hdC1leHBhbnNpb24tcGFuZWxcclxuICAgICAgaGlkZVRvZ2dsZVxyXG4gICAgICAqbmdGb3I9XCJsZXQgZ3JvdXAgb2YgZ3JvdXBzXCI+XHJcbiAgICA8bWF0LWV4cGFuc2lvbi1wYW5lbC1oZWFkZXI+XHJcbiAgICAgIDxtYXQtcGFuZWwtdGl0bGU+XHJcbiAgICAgICAgPGRpdiBjbGFzcz1cInRpdGxlLXJvd1wiPlxyXG4gICAgICAgICAgPGRpdiBjbGFzcz1cInRpdGxlXCI+XHJcbiAgICAgICAgICAgIHt7IGdyb3VwIHx8ICdHZW5lcmFsJyB9fVxyXG4gICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiYWN0aW9uc1wiPlxyXG4gICAgICAgICAgICA8YnV0dG9uXHJcbiAgICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcclxuICAgICAgICAgICAgICAgIFttYXRUb29sdGlwXT1cIidFeHBvcnQgJyArIChncm91cCB8fCAnR2VuZXJhbCcpICsgJyBTZXR0aW5ncydcIlxyXG4gICAgICAgICAgICAgICAgbWF0LWljb24tYnV0dG9uXHJcbiAgICAgICAgICAgICAgICAoY2xpY2spPVwiZXhwb3J0KCRldmVudCwgZ3JvdXBlZFNldHRpbmdzW2dyb3VwXSlcIj5cclxuICAgICAgICAgICAgICA8bWF0LWljb24+XHJcbiAgICAgICAgICAgICAgICBjbG91ZF9kb3dubG9hZFxyXG4gICAgICAgICAgICAgIDwvbWF0LWljb24+XHJcbiAgICAgICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgICAgICA8YnV0dG9uXHJcbiAgICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcclxuICAgICAgICAgICAgICAgIFttYXRUb29sdGlwXT1cIidJbXBvcnQgJyArIChncm91cCB8fCAnR2VuZXJhbCcpICsgJyBTZXR0aW5ncydcIlxyXG4gICAgICAgICAgICAgICAgbWF0LWljb24tYnV0dG9uXHJcbiAgICAgICAgICAgICAgICAoY2xpY2spPVwiaW1wb3J0KCRldmVudCwgZ3JvdXApXCI+XHJcbiAgICAgICAgICAgICAgPG1hdC1pY29uPlxyXG4gICAgICAgICAgICAgICAgY2xvdWRfdXBsb2FkXHJcbiAgICAgICAgICAgICAgPC9tYXQtaWNvbj5cclxuICAgICAgICAgICAgPC9idXR0b24+XHJcbiAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICA8L2Rpdj5cclxuICAgICAgPC9tYXQtcGFuZWwtdGl0bGU+XHJcbiAgICA8L21hdC1leHBhbnNpb24tcGFuZWwtaGVhZGVyPlxyXG4gICAgPGRpdlxyXG4gICAgICAgIGhpZGVUb2dnbGVcclxuICAgICAgICAqbmdGb3I9XCJsZXQgc2V0dGluZyBvZiBncm91cGVkU2V0dGluZ3NbZ3JvdXBdXCJcclxuICAgICAgICBjbGFzcz1cInNldHRpbmdcIlxyXG4gICAgICAgIFtuZ0NsYXNzXT1cInsgJ2hhcy1pbnN0cnVjdGlvbic6ICEhIHNldHRpbmcuaW5zdHJ1Y3Rpb24gfVwiPlxyXG4gICAgICA8bWF0LWZvcm0tZmllbGRcclxuICAgICAgICAgIGNsYXNzPVwiZnVsbC13aWR0aCBmb3JtLWZpZWxkLW11bHRpbGluZS1zdWJzY3JpcHRcIlxyXG4gICAgICAgICAgKm5nSWY9XCJzZXR0aW5nLmludGVyZmFjZVR5cGU9PT1TZXR0aW5nSW50ZXJmYWNlVHlwZS5JbnB1dEJveFwiPlxyXG4gICAgICAgIDxtYXQtbGFiZWw+XHJcbiAgICAgICAgICB7eyBzZXR0aW5nLmxhYmVsIH19XHJcbiAgICAgICAgPC9tYXQtbGFiZWw+XHJcbiAgICAgICAgPGlucHV0XHJcbiAgICAgICAgICBtYXRJbnB1dFxyXG4gICAgICAgICAgWyhuZ01vZGVsKV09XCJzZXR0aW5nLnZhbHVlXCJcclxuICAgICAgICAgIFtuYW1lXT1cIidzZXR0aW5nJyArIHNldHRpbmcuaWRcIj5cclxuICAgICAgICA8bWF0LWhpbnQ+XHJcbiAgICAgICAgICB7eyBzZXR0aW5nLmluc3RydWN0aW9uIH19XHJcbiAgICAgICAgPC9tYXQtaGludD5cclxuICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuICAgICAgPG1hdC1mb3JtLWZpZWxkXHJcbiAgICAgICAgICBjbGFzcz1cImZ1bGwtd2lkdGggZm9ybS1maWVsZC1tdWx0aWxpbmUtc3Vic2NyaXB0XCJcclxuICAgICAgICAgICpuZ0lmPVwic2V0dGluZy5pbnRlcmZhY2VUeXBlPT09U2V0dGluZ0ludGVyZmFjZVR5cGUuVGV4dGFyZWFcIj5cclxuICAgICAgICA8bWF0LWxhYmVsPlxyXG4gICAgICAgICAge3sgc2V0dGluZy5sYWJlbCB9fVxyXG4gICAgICAgIDwvbWF0LWxhYmVsPlxyXG4gICAgICAgIDx0ZXh0YXJlYVxyXG4gICAgICAgICAgbWF0SW5wdXRcclxuICAgICAgICAgIFsobmdNb2RlbCldPVwic2V0dGluZy52YWx1ZVwiXHJcbiAgICAgICAgICBbbmFtZV09XCInc2V0dGluZycgKyBzZXR0aW5nLmlkXCI+XHJcbiAgICAgICAgPC90ZXh0YXJlYT5cclxuICAgICAgICA8bWF0LWhpbnQ+XHJcbiAgICAgICAgICB7eyBzZXR0aW5nLmluc3RydWN0aW9uIH19XHJcbiAgICAgICAgPC9tYXQtaGludD5cclxuICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuICAgICAgPG1hdC1mb3JtLWZpZWxkXHJcbiAgICAgICAgICBjbGFzcz1cImZ1bGwtd2lkdGggZm9ybS1maWVsZC1tdWx0aWxpbmUtc3Vic2NyaXB0XCJcclxuICAgICAgICAgICpuZ0lmPVwic2V0dGluZy5pbnRlcmZhY2VUeXBlPT09U2V0dGluZ0ludGVyZmFjZVR5cGUuU2VsZWN0IHx8IHNldHRpbmcuaW50ZXJmYWNlVHlwZT09PVNldHRpbmdJbnRlcmZhY2VUeXBlLlNlbGVjdE11bHRpcGxlXCI+XHJcbiAgICAgICAgPG1hdC1sYWJlbD5cclxuICAgICAgICAgIHt7IHNldHRpbmcubGFiZWwgfX1cclxuICAgICAgICA8L21hdC1sYWJlbD5cclxuICAgICAgICA8bWF0LXNlbGVjdFxyXG4gICAgICAgICAgICBbKG5nTW9kZWwpXT1cInNldHRpbmcudmFsdWVcIlxyXG4gICAgICAgICAgICBbbXVsdGlwbGVdPVwic2V0dGluZy5pbnRlcmZhY2VUeXBlPT09U2V0dGluZ0ludGVyZmFjZVR5cGUuU2VsZWN0TXVsdGlwbGVcIlxyXG4gICAgICAgICAgICBbbmFtZV09XCInc2V0dGluZycgKyBzZXR0aW5nLmlkXCI+XHJcbiAgICAgICAgICA8bWF0LW9wdGlvblxyXG4gICAgICAgICAgICAgICpuZ0Zvcj1cImxldCBpdGVtIG9mIHNldHRpbmcudmFsdWVzIHwga2V5TmFtZVZhbHVlXCJcclxuICAgICAgICAgICAgICBbdmFsdWVdPVwiaXRlbS52YWx1ZVwiPlxyXG4gICAgICAgICAgICB7eyBpdGVtLm5hbWUgfX1cclxuICAgICAgICAgIDwvbWF0LW9wdGlvbj5cclxuICAgICAgICA8L21hdC1zZWxlY3Q+XHJcbiAgICAgICAgPG1hdC1oaW50PlxyXG4gICAgICAgICAge3sgc2V0dGluZy5pbnN0cnVjdGlvbiB9fVxyXG4gICAgICAgIDwvbWF0LWhpbnQ+XHJcbiAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcbiAgICAgIDxtYXQtZm9ybS1maWVsZFxyXG4gICAgICAgICAgY2xhc3M9XCJmdWxsLXdpZHRoIGZvcm0tZmllbGQtbXVsdGlsaW5lLXN1YnNjcmlwdFwiXHJcbiAgICAgICAgICAqbmdJZj1cInNldHRpbmcuaW50ZXJmYWNlVHlwZT09PVNldHRpbmdJbnRlcmZhY2VUeXBlLkRhdGVcIj5cclxuICAgICAgICA8bWF0LWxhYmVsPlxyXG4gICAgICAgICAge3sgc2V0dGluZy5sYWJlbCB9fVxyXG4gICAgICAgIDwvbWF0LWxhYmVsPlxyXG4gICAgICAgIDxpbnB1dFxyXG4gICAgICAgICAgbWF0SW5wdXRcclxuICAgICAgICAgIGZzRGF0ZVBpY2tlclxyXG4gICAgICAgICAgWyhuZ01vZGVsKV09XCJzZXR0aW5nLnZhbHVlXCJcclxuICAgICAgICAgIFtuYW1lXT1cIidzZXR0aW5nJyArIHNldHRpbmcuaWRcIj5cclxuICAgICAgICA8bWF0LWhpbnQ+XHJcbiAgICAgICAgICB7eyBzZXR0aW5nLmluc3RydWN0aW9uIH19XHJcbiAgICAgICAgPC9tYXQtaGludD5cclxuICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuICAgICAgPG1hdC1mb3JtLWZpZWxkXHJcbiAgICAgICAgICBjbGFzcz1cImZ1bGwtd2lkdGggZm9ybS1maWVsZC1tdWx0aWxpbmUtc3Vic2NyaXB0XCJcclxuICAgICAgICAgICpuZ0lmPVwic2V0dGluZy5pbnRlcmZhY2VUeXBlPT09U2V0dGluZ0ludGVyZmFjZVR5cGUuQ29sb3JcIj5cclxuICAgICAgICA8bWF0LWxhYmVsPlxyXG4gICAgICAgICAge3sgc2V0dGluZy5sYWJlbCB9fVxyXG4gICAgICAgIDwvbWF0LWxhYmVsPlxyXG4gICAgICAgIDxpbnB1dFxyXG4gICAgICAgICAgbWF0SW5wdXRcclxuICAgICAgICAgIGZzQ29sb3JQaWNrZXJcclxuICAgICAgICAgIFsobmdNb2RlbCldPVwic2V0dGluZy52YWx1ZVwiXHJcbiAgICAgICAgICBbbmFtZV09XCInc2V0dGluZycgKyBzZXR0aW5nLmlkXCI+XHJcbiAgICAgICAgPG1hdC1oaW50PlxyXG4gICAgICAgICAge3sgc2V0dGluZy5pbnN0cnVjdGlvbiB9fVxyXG4gICAgICAgIDwvbWF0LWhpbnQ+XHJcbiAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcbiAgICAgIDxtYXQtZm9ybS1maWVsZFxyXG4gICAgICAgICAgY2xhc3M9XCJmdWxsLXdpZHRoIGZvcm0tZmllbGQtbXVsdGlsaW5lLXN1YnNjcmlwdFwiXHJcbiAgICAgICAgICAqbmdJZj1cInNldHRpbmcuaW50ZXJmYWNlVHlwZT09PVNldHRpbmdJbnRlcmZhY2VUeXBlLlRpbWVcIj5cclxuICAgICAgICA8bWF0LWxhYmVsPlxyXG4gICAgICAgICAge3sgc2V0dGluZy5sYWJlbCB9fVxyXG4gICAgICAgIDwvbWF0LWxhYmVsPlxyXG4gICAgICAgIDxpbnB1dFxyXG4gICAgICAgICAgbWF0SW5wdXRcclxuICAgICAgICAgIGZzVGltZVBpY2tlclxyXG4gICAgICAgICAgWyhuZ01vZGVsKV09XCJzZXR0aW5nLnZhbHVlXCJcclxuICAgICAgICAgIFtuYW1lXT1cIidzZXR0aW5nJyArIHNldHRpbmcuaWRcIj5cclxuICAgICAgICA8bWF0LWhpbnQ+XHJcbiAgICAgICAgICB7eyBzZXR0aW5nLmluc3RydWN0aW9uIH19XHJcbiAgICAgICAgPC9tYXQtaGludD5cclxuICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuICAgICAgPGZzLWZpbGUtcGlja2VyXHJcbiAgICAgICAgICAqbmdJZj1cInNldHRpbmcuaW50ZXJmYWNlVHlwZT09PVNldHRpbmdJbnRlcmZhY2VUeXBlLkZpbGVcIlxyXG4gICAgICAgICAgW2FsbG93UmVtb3ZlXT1cInRydWVcIlxyXG4gICAgICAgICAgW2FsbG93RG93bmxvYWRdPVwidHJ1ZVwiXHJcbiAgICAgICAgICAoc2VsZWN0KT1cImZpbGVTZWxlY3QuZW1pdCh7IHNldHRpbmc6IHNldHRpbmcsIGZpbGU6ICRldmVudC5maWxlIH0pXCJcclxuICAgICAgICAgIChyZW1vdmUpPVwiZmlsZVJlbW92ZS5lbWl0KHNldHRpbmcpXCJcclxuICAgICAgICAgIFt1cmxdPVwic2V0dGluZy52YWx1ZVwiPlxyXG4gICAgICAgIDxkaXYgZnNGaWxlTGFiZWw+XHJcbiAgICAgICAgICB7eyBzZXR0aW5nLmxhYmVsIH19XHJcbiAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgPGRpdiBmc0ZpbGVIaW50PlxyXG4gICAgICAgICAge3sgc2V0dGluZy5pbnN0cnVjdGlvbiB9fVxyXG4gICAgICAgIDwvZGl2PlxyXG4gICAgICA8L2ZzLWZpbGUtcGlja2VyPlxyXG4gICAgPC9kaXY+XHJcbiAgICA8YnV0dG9uXHJcbiAgICAgICAgbWF0LXN0cm9rZWQtYnV0dG9uXHJcbiAgICAgICAgY29sb3I9XCJwcmltYXJ5XCJcclxuICAgICAgICB0eXBlPVwiYnV0dG9uXCJcclxuICAgICAgICAoY2xpY2spPVwic2F2ZUdyb3VwKGdyb3VwKVwiPlxyXG4gICAgICBTYXZlXHJcbiAgICA8L2J1dHRvbj5cclxuICA8L21hdC1leHBhbnNpb24tcGFuZWw+XHJcbjwvbWF0LWFjY29yZGlvbj4iXX0=
@@ -618,7 +618,12 @@ class CronLogsComponent {
618
618
  ...query,
619
619
  cronId: this.cron.id,
620
620
  };
621
- return this._cronData.cronLogGets(query);
621
+ return this._cronData.cronLogGets(query, {
622
+ key: null,
623
+ })
624
+ .pipe(map((data) => {
625
+ return { data: data.cronLogs, paging: data.paging };
626
+ }));
622
627
  },
623
628
  };
624
629
  }
@@ -889,7 +894,10 @@ class CronsComponent {
889
894
  },
890
895
  label: 'Reset',
891
896
  show: (cron) => {
892
- return cron.state === CronState.Killing || cron.state === CronState.Running || cron.state === CronState.Failed || cron.state === CronState.Queued;
897
+ return cron.state === CronState.Killing ||
898
+ cron.state === CronState.Running ||
899
+ cron.state === CronState.Failed ||
900
+ cron.state === CronState.Queued;
893
901
  },
894
902
  },
895
903
  ];
@@ -947,12 +955,6 @@ class CronsComponent {
947
955
  query.timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
948
956
  return this._cronData.gets(query, { key: 'crons' });
949
957
  };
950
- loadCronLogs = (query) => {
951
- return this._cronData.cronLogGets(query, { key: null })
952
- .pipe(map((data) => {
953
- return { data: data.cronLogs, paging: data.paging };
954
- }));
955
- };
956
958
  bulk = (action, crons) => {
957
959
  const processes = crons
958
960
  .map((cron) => {
@@ -1101,11 +1103,11 @@ class DashboardComponent {
1101
1103
  });
1102
1104
  }
1103
1105
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: DashboardComponent, deps: [{ token: i1$3.FsMessage }, { token: i0.ChangeDetectorRef }, { token: i2$1.FsBuildService }], target: i0.ɵɵFactoryTarget.Component });
1104
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.7", type: DashboardComponent, selector: "fs-system-dashboard", inputs: { init: "init", upgrade: "upgrade", load: "load", actions: "actions" }, ngImport: i0, template: "<div *fsSkeleton=\"dashboard\">\n <div class=\"fs-row.gap-lg.wrap.align-start\">\n <div>\n <h2>Server</h2>\n\n <fs-label-field>\n <fs-label>Date/Time</fs-label>\n {{dashboard.serverTime | fsDateFormat: 'date-time'}}\n </fs-label-field>\n\n <fs-label-field>\n <fs-label>Timezone</fs-label>\n {{dashboard.serverTimezone}}\n </fs-label-field>\n\n <fs-label-field>\n <fs-label>Hostname</fs-label>\n {{dashboard.serverHostname}}\n </fs-label-field>\n\n <fs-label-field>\n <fs-label>Directory</fs-label>\n {{dashboard.appDirectory}}\n </fs-label-field>\n </div>\n\n <div>\n <h2>System</h2>\n <fs-label-field>\n <fs-label>Mode</fs-label>\n {{dashboard.appMode}}\n </fs-label-field>\n\n <fs-label-field>\n <fs-label>Notification Recipients</fs-label>\n {{dashboard.notifyRecipients.join(', ')}}\n </fs-label-field>\n </div>\n\n <div>\n <h2>Database</h2>\n\n <fs-label-field>\n <fs-label>Name</fs-label>\n {{dashboard.databaseName}}\n </fs-label-field>\n\n <fs-label-field>\n <fs-label>Date/Time</fs-label>\n {{dashboard.databaseTime | fsDateFormat: 'date-time'}}\n </fs-label-field>\n\n <fs-label-field>\n <fs-label>Timezone</fs-label>\n {{dashboard.databaseTimezone}}\n </fs-label-field>\n </div>\n\n <div *ngIf=\"build || dashboard.upgrades.length\">\n <ng-container *ngIf=\"build\">\n <h2>Build</h2>\n <fs-label-field>\n <fs-label>Version</fs-label>\n {{build.version || 'Unknown'}}\n </fs-label-field>\n\n <fs-label-field>\n <fs-label>Date</fs-label>\n {{ (build.date | fsDateFormat: 'date-time') || 'Unknown' }}\n </fs-label-field>\n </ng-container>\n\n <fs-label-field *ngIf=\"dashboard.upgrades.length\">\n <fs-label>Pending Upgrades</fs-label>\n <span class=\"attention\" [ngClass]=\"{ 'needs-attention': !!dashboard.upgrades.length }\">\n {{dashboard.upgrades.length}}\n <mat-icon\n [matTooltip]=\"dashboard.upgrades.join('\\n')\"\n matTooltipClass=\"tooltip-pending-upgrades\"\n >\n warning\n </mat-icon>\n </span>\n </fs-label-field>\n </div>\n\n <div>\n <h2>Cron</h2>\n\n <fs-label-field>\n <fs-label>Last Ran</fs-label>\n <span class=\"attention\" [ngClass]=\"{ 'needs-attention': dashboard.cronRanAttention }\">\n <span *ngIf=\"!dashboard.cronRan\">Never</span>\n <span *ngIf=\"dashboard.cronRan\">{{dashboard.cronRan | fsDateFormat: 'date-time'}}</span>\n <mat-icon>warning</mat-icon>\n </span>\n </fs-label-field>\n </div>\n </div>\n \n\n <div>\n <div class=\"actions\">\n <button mat-raised-button (click)=\"upgradeClick()\">Run Upgrades</button>\n <button mat-raised-button (click)=\"initClick()\">Init System</button>\n <button\n *ngFor=\"let action of buttonActions\"\n mat-raised-button\n (click)=\"actionClick(action)\">\n {{action.label}}\n </button>\n\n <ng-container *ngIf=\"menuActions.length\">\n <fs-menu buttonClass=\"mat-raised-button menu-button\">\n <ng-template\n *ngFor=\"let action of menuActions\"\n fs-menu-item\n (click)=\"actionClick(action)\">\n {{action.label}}\n </ng-template>\n </fs-menu>\n </ng-container>\n </div>\n </div>\n</div>\n", styles: [":host ::ng-deep .menu-button{box-shadow:none}h2{margin-top:0}.actions{display:flex;align-items:center;flex-wrap:wrap}.actions button,.actions fs-menu{margin-bottom:10px;margin-right:5px}table td{padding:3px}.attention{display:flex;align-items:center}.attention mat-icon{display:none;margin-left:2px}.attention.needs-attention{color:#c00}.attention.needs-attention mat-icon{display:inline}::ng-deep .tooltip-pending-upgrades{white-space:pre-line}@media (max-width: 1000px){:host ::ng-deep .menu-button{width:100%;border-radius:4px}}\n"], dependencies: [{ kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "directive", type: i5$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: i3$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i7$1.FsSkeletonContentDirective, selector: "[fsSkeleton]", inputs: ["fsSkeleton", "fsSkeletonPattern"] }, { kind: "component", type: i6.FsLabelComponent, selector: "fs-label" }, { kind: "component", type: i6.FsLabelFieldComponent, selector: "fs-label-field", inputs: ["appearance", "showOutline", "disabled", "focused", "hoverable", "padless"] }, { kind: "component", type: i9.FsMenuComponent, selector: "fs-menu", inputs: ["class", "buttonClass", "buttonType", "buttonColor"], outputs: ["opened", "closed"] }, { kind: "directive", type: i9.FsMenuItemDirective, selector: "fs-menu-group,[fs-menu-item]" }, { kind: "pipe", type: i4$2.FsDateFormatPipe, name: "fsDateFormat" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1106
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.7", type: DashboardComponent, selector: "fs-system-dashboard", inputs: { init: "init", upgrade: "upgrade", load: "load", actions: "actions" }, ngImport: i0, template: "<div *fsSkeleton=\"dashboard\">\n <div class=\"fs-row.gap-lg.wrap.align-start\">\n <div>\n <h2>\n Server\n </h2>\n <fs-label-field>\n <fs-label>\n Date/Time\n </fs-label>\n {{ dashboard.serverTime | fsDateFormat: 'date-time' }}\n </fs-label-field>\n <fs-label-field>\n <fs-label>\n Timezone\n </fs-label>\n {{ dashboard.serverTimezone }}\n </fs-label-field>\n <fs-label-field>\n <fs-label>\n Hostname\n </fs-label>\n {{ dashboard.serverHostname }}\n </fs-label-field>\n <fs-label-field>\n <fs-label>\n Directory\n </fs-label>\n {{ dashboard.appDirectory }}\n </fs-label-field>\n </div>\n <div>\n <h2>\n System\n </h2>\n <fs-label-field>\n <fs-label>\n Mode\n </fs-label>\n {{ dashboard.appMode }}\n </fs-label-field>\n <fs-label-field>\n <fs-label>\n Notification Recipients\n </fs-label>\n {{ dashboard.notifyRecipients.join(', ') }}\n </fs-label-field>\n </div>\n <div>\n <h2>\n Database\n </h2>\n <fs-label-field>\n <fs-label>\n Name\n </fs-label>\n {{ dashboard.databaseName }}\n </fs-label-field>\n <fs-label-field>\n <fs-label>\n Date/Time\n </fs-label>\n {{ dashboard.databaseTime | fsDateFormat: 'date-time' }}\n </fs-label-field>\n <fs-label-field>\n <fs-label>\n Timezone\n </fs-label>\n {{ dashboard.databaseTimezone }}\n </fs-label-field>\n </div>\n <div *ngIf=\"build || dashboard.upgrades.length\">\n <ng-container *ngIf=\"build\">\n <h2>\n Build\n </h2>\n <fs-label-field>\n <fs-label>\n Version\n </fs-label>\n {{ build.version || 'Unknown' }}\n </fs-label-field>\n <fs-label-field>\n <fs-label>\n Date\n </fs-label>\n {{ (build.date | fsDateFormat: 'date-time') || 'Unknown' }}\n </fs-label-field>\n </ng-container>\n <fs-label-field *ngIf=\"dashboard.upgrades.length\">\n <fs-label>\n Pending Upgrades\n </fs-label>\n <span\n class=\"attention\"\n [ngClass]=\"{ 'needs-attention': !!dashboard.upgrades.length }\">\n {{ dashboard.upgrades.length }}\n <mat-icon\n [matTooltip]=\"dashboard.upgrades.join('\\n')\"\n matTooltipClass=\"tooltip-pending-upgrades\">\n warning\n </mat-icon>\n </span>\n </fs-label-field>\n </div>\n <div>\n <h2>\n Cron\n </h2>\n <fs-label-field>\n <fs-label>\n Last Ran\n </fs-label>\n <span\n class=\"attention\"\n [ngClass]=\"{ 'needs-attention': dashboard.cronRanAttention }\">\n <span *ngIf=\"!dashboard.cronRan\">\n Never\n </span>\n <span *ngIf=\"dashboard.cronRan\">\n {{ dashboard.cronRan | fsDateFormat: 'date-time' }}\n </span>\n <mat-icon>\n warning\n </mat-icon>\n </span>\n </fs-label-field>\n </div>\n </div>\n <div>\n <div class=\"actions\">\n <button\n mat-stroked-button\n (click)=\"upgradeClick()\">\n Run Upgrades\n </button>\n <button\n mat-stroked-button\n (click)=\"initClick()\">\n Init System\n </button>\n <button\n *ngFor=\"let action of buttonActions\"\n mat-stroked-button\n (click)=\"actionClick(action)\">\n {{ action.label }}\n </button>\n <ng-container *ngIf=\"menuActions.length\">\n <fs-menu buttonClass=\"mat-stroked-button menu-button\">\n <ng-template\n *ngFor=\"let action of menuActions\"\n fs-menu-item\n (click)=\"actionClick(action)\">\n {{ action.label }}\n </ng-template>\n </fs-menu>\n </ng-container>\n </div>\n </div>\n</div>", styles: [":host ::ng-deep .menu-button{box-shadow:none}h2{margin-top:0}.actions{display:flex;align-items:center;flex-wrap:wrap}.actions button,.actions fs-menu{margin-bottom:10px;margin-right:5px}table td{padding:3px}.attention{display:flex;align-items:center}.attention mat-icon{display:none;margin-left:2px}.attention.needs-attention{color:#c00}.attention.needs-attention mat-icon{display:inline}::ng-deep .tooltip-pending-upgrades{white-space:pre-line}@media (max-width: 1000px){:host ::ng-deep .menu-button{width:100%;border-radius:4px}}\n"], dependencies: [{ kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "directive", type: i5$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: i3$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i7$1.FsSkeletonContentDirective, selector: "[fsSkeleton]", inputs: ["fsSkeleton", "fsSkeletonPattern"] }, { kind: "component", type: i6.FsLabelComponent, selector: "fs-label" }, { kind: "component", type: i6.FsLabelFieldComponent, selector: "fs-label-field", inputs: ["appearance", "showOutline", "disabled", "focused", "hoverable", "padless"] }, { kind: "component", type: i9.FsMenuComponent, selector: "fs-menu", inputs: ["class", "buttonClass", "buttonType", "buttonColor"], outputs: ["opened", "closed"] }, { kind: "directive", type: i9.FsMenuItemDirective, selector: "fs-menu-group,[fs-menu-item]" }, { kind: "pipe", type: i4$2.FsDateFormatPipe, name: "fsDateFormat" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1105
1107
  }
1106
1108
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: DashboardComponent, decorators: [{
1107
1109
  type: Component,
1108
- args: [{ selector: 'fs-system-dashboard', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div *fsSkeleton=\"dashboard\">\n <div class=\"fs-row.gap-lg.wrap.align-start\">\n <div>\n <h2>Server</h2>\n\n <fs-label-field>\n <fs-label>Date/Time</fs-label>\n {{dashboard.serverTime | fsDateFormat: 'date-time'}}\n </fs-label-field>\n\n <fs-label-field>\n <fs-label>Timezone</fs-label>\n {{dashboard.serverTimezone}}\n </fs-label-field>\n\n <fs-label-field>\n <fs-label>Hostname</fs-label>\n {{dashboard.serverHostname}}\n </fs-label-field>\n\n <fs-label-field>\n <fs-label>Directory</fs-label>\n {{dashboard.appDirectory}}\n </fs-label-field>\n </div>\n\n <div>\n <h2>System</h2>\n <fs-label-field>\n <fs-label>Mode</fs-label>\n {{dashboard.appMode}}\n </fs-label-field>\n\n <fs-label-field>\n <fs-label>Notification Recipients</fs-label>\n {{dashboard.notifyRecipients.join(', ')}}\n </fs-label-field>\n </div>\n\n <div>\n <h2>Database</h2>\n\n <fs-label-field>\n <fs-label>Name</fs-label>\n {{dashboard.databaseName}}\n </fs-label-field>\n\n <fs-label-field>\n <fs-label>Date/Time</fs-label>\n {{dashboard.databaseTime | fsDateFormat: 'date-time'}}\n </fs-label-field>\n\n <fs-label-field>\n <fs-label>Timezone</fs-label>\n {{dashboard.databaseTimezone}}\n </fs-label-field>\n </div>\n\n <div *ngIf=\"build || dashboard.upgrades.length\">\n <ng-container *ngIf=\"build\">\n <h2>Build</h2>\n <fs-label-field>\n <fs-label>Version</fs-label>\n {{build.version || 'Unknown'}}\n </fs-label-field>\n\n <fs-label-field>\n <fs-label>Date</fs-label>\n {{ (build.date | fsDateFormat: 'date-time') || 'Unknown' }}\n </fs-label-field>\n </ng-container>\n\n <fs-label-field *ngIf=\"dashboard.upgrades.length\">\n <fs-label>Pending Upgrades</fs-label>\n <span class=\"attention\" [ngClass]=\"{ 'needs-attention': !!dashboard.upgrades.length }\">\n {{dashboard.upgrades.length}}\n <mat-icon\n [matTooltip]=\"dashboard.upgrades.join('\\n')\"\n matTooltipClass=\"tooltip-pending-upgrades\"\n >\n warning\n </mat-icon>\n </span>\n </fs-label-field>\n </div>\n\n <div>\n <h2>Cron</h2>\n\n <fs-label-field>\n <fs-label>Last Ran</fs-label>\n <span class=\"attention\" [ngClass]=\"{ 'needs-attention': dashboard.cronRanAttention }\">\n <span *ngIf=\"!dashboard.cronRan\">Never</span>\n <span *ngIf=\"dashboard.cronRan\">{{dashboard.cronRan | fsDateFormat: 'date-time'}}</span>\n <mat-icon>warning</mat-icon>\n </span>\n </fs-label-field>\n </div>\n </div>\n \n\n <div>\n <div class=\"actions\">\n <button mat-raised-button (click)=\"upgradeClick()\">Run Upgrades</button>\n <button mat-raised-button (click)=\"initClick()\">Init System</button>\n <button\n *ngFor=\"let action of buttonActions\"\n mat-raised-button\n (click)=\"actionClick(action)\">\n {{action.label}}\n </button>\n\n <ng-container *ngIf=\"menuActions.length\">\n <fs-menu buttonClass=\"mat-raised-button menu-button\">\n <ng-template\n *ngFor=\"let action of menuActions\"\n fs-menu-item\n (click)=\"actionClick(action)\">\n {{action.label}}\n </ng-template>\n </fs-menu>\n </ng-container>\n </div>\n </div>\n</div>\n", styles: [":host ::ng-deep .menu-button{box-shadow:none}h2{margin-top:0}.actions{display:flex;align-items:center;flex-wrap:wrap}.actions button,.actions fs-menu{margin-bottom:10px;margin-right:5px}table td{padding:3px}.attention{display:flex;align-items:center}.attention mat-icon{display:none;margin-left:2px}.attention.needs-attention{color:#c00}.attention.needs-attention mat-icon{display:inline}::ng-deep .tooltip-pending-upgrades{white-space:pre-line}@media (max-width: 1000px){:host ::ng-deep .menu-button{width:100%;border-radius:4px}}\n"] }]
1110
+ args: [{ selector: 'fs-system-dashboard', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div *fsSkeleton=\"dashboard\">\n <div class=\"fs-row.gap-lg.wrap.align-start\">\n <div>\n <h2>\n Server\n </h2>\n <fs-label-field>\n <fs-label>\n Date/Time\n </fs-label>\n {{ dashboard.serverTime | fsDateFormat: 'date-time' }}\n </fs-label-field>\n <fs-label-field>\n <fs-label>\n Timezone\n </fs-label>\n {{ dashboard.serverTimezone }}\n </fs-label-field>\n <fs-label-field>\n <fs-label>\n Hostname\n </fs-label>\n {{ dashboard.serverHostname }}\n </fs-label-field>\n <fs-label-field>\n <fs-label>\n Directory\n </fs-label>\n {{ dashboard.appDirectory }}\n </fs-label-field>\n </div>\n <div>\n <h2>\n System\n </h2>\n <fs-label-field>\n <fs-label>\n Mode\n </fs-label>\n {{ dashboard.appMode }}\n </fs-label-field>\n <fs-label-field>\n <fs-label>\n Notification Recipients\n </fs-label>\n {{ dashboard.notifyRecipients.join(', ') }}\n </fs-label-field>\n </div>\n <div>\n <h2>\n Database\n </h2>\n <fs-label-field>\n <fs-label>\n Name\n </fs-label>\n {{ dashboard.databaseName }}\n </fs-label-field>\n <fs-label-field>\n <fs-label>\n Date/Time\n </fs-label>\n {{ dashboard.databaseTime | fsDateFormat: 'date-time' }}\n </fs-label-field>\n <fs-label-field>\n <fs-label>\n Timezone\n </fs-label>\n {{ dashboard.databaseTimezone }}\n </fs-label-field>\n </div>\n <div *ngIf=\"build || dashboard.upgrades.length\">\n <ng-container *ngIf=\"build\">\n <h2>\n Build\n </h2>\n <fs-label-field>\n <fs-label>\n Version\n </fs-label>\n {{ build.version || 'Unknown' }}\n </fs-label-field>\n <fs-label-field>\n <fs-label>\n Date\n </fs-label>\n {{ (build.date | fsDateFormat: 'date-time') || 'Unknown' }}\n </fs-label-field>\n </ng-container>\n <fs-label-field *ngIf=\"dashboard.upgrades.length\">\n <fs-label>\n Pending Upgrades\n </fs-label>\n <span\n class=\"attention\"\n [ngClass]=\"{ 'needs-attention': !!dashboard.upgrades.length }\">\n {{ dashboard.upgrades.length }}\n <mat-icon\n [matTooltip]=\"dashboard.upgrades.join('\\n')\"\n matTooltipClass=\"tooltip-pending-upgrades\">\n warning\n </mat-icon>\n </span>\n </fs-label-field>\n </div>\n <div>\n <h2>\n Cron\n </h2>\n <fs-label-field>\n <fs-label>\n Last Ran\n </fs-label>\n <span\n class=\"attention\"\n [ngClass]=\"{ 'needs-attention': dashboard.cronRanAttention }\">\n <span *ngIf=\"!dashboard.cronRan\">\n Never\n </span>\n <span *ngIf=\"dashboard.cronRan\">\n {{ dashboard.cronRan | fsDateFormat: 'date-time' }}\n </span>\n <mat-icon>\n warning\n </mat-icon>\n </span>\n </fs-label-field>\n </div>\n </div>\n <div>\n <div class=\"actions\">\n <button\n mat-stroked-button\n (click)=\"upgradeClick()\">\n Run Upgrades\n </button>\n <button\n mat-stroked-button\n (click)=\"initClick()\">\n Init System\n </button>\n <button\n *ngFor=\"let action of buttonActions\"\n mat-stroked-button\n (click)=\"actionClick(action)\">\n {{ action.label }}\n </button>\n <ng-container *ngIf=\"menuActions.length\">\n <fs-menu buttonClass=\"mat-stroked-button menu-button\">\n <ng-template\n *ngFor=\"let action of menuActions\"\n fs-menu-item\n (click)=\"actionClick(action)\">\n {{ action.label }}\n </ng-template>\n </fs-menu>\n </ng-container>\n </div>\n </div>\n</div>", styles: [":host ::ng-deep .menu-button{box-shadow:none}h2{margin-top:0}.actions{display:flex;align-items:center;flex-wrap:wrap}.actions button,.actions fs-menu{margin-bottom:10px;margin-right:5px}table td{padding:3px}.attention{display:flex;align-items:center}.attention mat-icon{display:none;margin-left:2px}.attention.needs-attention{color:#c00}.attention.needs-attention mat-icon{display:inline}::ng-deep .tooltip-pending-upgrades{white-space:pre-line}@media (max-width: 1000px){:host ::ng-deep .menu-button{width:100%;border-radius:4px}}\n"] }]
1109
1111
  }], ctorParameters: () => [{ type: i1$3.FsMessage }, { type: i0.ChangeDetectorRef }, { type: i2$1.FsBuildService }], propDecorators: { init: [{
1110
1112
  type: Input
1111
1113
  }], upgrade: [{
@@ -1624,11 +1626,11 @@ class SettingsComponent {
1624
1626
  });
1625
1627
  }
1626
1628
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: SettingsComponent, deps: [{ token: i1$3.FsMessage }, { token: i2.FsClipboard }, { token: i2$2.FsPrompt }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
1627
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.7", type: SettingsComponent, selector: "fs-system-settings", inputs: { loadSettings: "loadSettings", save: "save" }, outputs: { fileRemove: "fileRemove", fileSelect: "fileSelect" }, ngImport: i0, template: "\r\n<mat-accordion>\r\n <mat-expansion-panel hideToggle *ngFor=\"let group of groups\">\r\n <mat-expansion-panel-header>\r\n <mat-panel-title>\r\n <div class=\"title-row\">\r\n <div class=\"title\">{{group || 'General'}}</div>\r\n <div class=\"actions\">\r\n <button\r\n type=\"button\"\r\n [matTooltip]=\"'Export ' + (group || 'General') + ' Settings'\"\r\n mat-icon-button\r\n (click)=\"export($event, groupedSettings[group])\">\r\n <mat-icon>cloud_download</mat-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n [matTooltip]=\"'Import ' + (group || 'General') + ' Settings'\"\r\n mat-icon-button\r\n (click)=\"import($event, group)\">\r\n <mat-icon>cloud_upload</mat-icon>\r\n </button>\r\n </div>\r\n </div>\r\n </mat-panel-title>\r\n </mat-expansion-panel-header>\r\n\r\n <div \r\n hideToggle \r\n *ngFor=\"let setting of groupedSettings[group]\" \r\n class=\"setting\"\r\n [ngClass]=\"{ 'has-instruction': !! setting.instruction }\">\r\n <mat-form-field \r\n class=\"full-width form-field-multiline-subscript\"\r\n *ngIf=\"setting.interfaceType===SettingInterfaceType.InputBox\">\r\n <mat-label>{{setting.label}}</mat-label>\r\n <input\r\n matInput\r\n [(ngModel)]=\"setting.value\"\r\n [name]=\"'setting' + setting.id\">\r\n <mat-hint>{{setting.instruction}}</mat-hint>\r\n </mat-form-field>\r\n\r\n <mat-form-field \r\n class=\"full-width form-field-multiline-subscript\" \r\n *ngIf=\"setting.interfaceType===SettingInterfaceType.Textarea\">\r\n <mat-label>{{setting.label}}</mat-label>\r\n <textarea\r\n matInput\r\n [(ngModel)]=\"setting.value\"\r\n [name]=\"'setting' + setting.id\">\r\n </textarea>\r\n <mat-hint>{{setting.instruction}}</mat-hint>\r\n </mat-form-field>\r\n\r\n <mat-form-field \r\n class=\"full-width form-field-multiline-subscript\" \r\n *ngIf=\"setting.interfaceType===SettingInterfaceType.Select || setting.interfaceType===SettingInterfaceType.SelectMultiple\">\r\n <mat-label>{{setting.label}}</mat-label>\r\n <mat-select\r\n [(ngModel)]=\"setting.value\"\r\n [multiple]=\"setting.interfaceType===SettingInterfaceType.SelectMultiple\"\r\n [name]=\"'setting' + setting.id\">\r\n <mat-option *ngFor=\"let item of setting.values | keyNameValue\" [value]=\"item.value\">\r\n {{item.name}}\r\n </mat-option>\r\n </mat-select>\r\n <mat-hint>{{setting.instruction}}</mat-hint>\r\n </mat-form-field>\r\n\r\n <mat-form-field \r\n class=\"full-width form-field-multiline-subscript\" \r\n *ngIf=\"setting.interfaceType===SettingInterfaceType.Date\">\r\n <mat-label>{{setting.label}}</mat-label>\r\n <input\r\n matInput\r\n fsDatePicker\r\n [(ngModel)]=\"setting.value\"\r\n [name]=\"'setting' + setting.id\">\r\n <mat-hint>{{setting.instruction}}</mat-hint>\r\n </mat-form-field>\r\n\r\n <mat-form-field \r\n class=\"full-width form-field-multiline-subscript\" \r\n *ngIf=\"setting.interfaceType===SettingInterfaceType.Color\">\r\n <mat-label>{{setting.label}}</mat-label>\r\n <input\r\n matInput\r\n fsColorPicker\r\n [(ngModel)]=\"setting.value\"\r\n [name]=\"'setting' + setting.id\">\r\n <mat-hint>{{setting.instruction}}</mat-hint>\r\n </mat-form-field>\r\n\r\n <mat-form-field \r\n class=\"full-width form-field-multiline-subscript\" \r\n *ngIf=\"setting.interfaceType===SettingInterfaceType.Time\">\r\n <mat-label>{{setting.label}}</mat-label>\r\n <input\r\n matInput\r\n fsTimePicker\r\n [(ngModel)]=\"setting.value\"\r\n [name]=\"'setting' + setting.id\">\r\n <mat-hint>{{setting.instruction}}</mat-hint>\r\n </mat-form-field>\r\n\r\n <fs-file-picker\r\n *ngIf=\"setting.interfaceType===SettingInterfaceType.File\"\r\n [allowRemove]=\"true\"\r\n [allowDownload]=\"true\"\r\n (select)=\"fileSelect.emit({ setting: setting, file: $event.file })\"\r\n (remove)=\"fileRemove.emit(setting)\"\r\n [url]=\"setting.value\">\r\n <div fsFileLabel>{{setting.label}}</div>\r\n <div fsFileHint>{{setting.instruction}}</div>\r\n </fs-file-picker>\r\n </div>\r\n\r\n <button mat-raised-button color=\"primary\" type=\"button\" (click)=\"saveGroup(group)\">Save</button>\r\n\r\n </mat-expansion-panel>\r\n\r\n</mat-accordion>\r\n", styles: [".mat-expansion-panel-header{font-size:19px}.full-width{width:100%}.title-row{flex-direction:row;box-sizing:border-box;display:flex;place-content:center flex-start;align-items:center;width:100%}.title-row .title{display:flex;flex:1}:host ::ng-deep .mat-expansion-panel-header-title{margin:0}:host ::ng-deep .mat-expansion-panel .actions{display:none}:host ::ng-deep .mat-expansion-panel.mat-expanded .actions{display:block}:host ::ng-deep .setting.has-instruction fs-file-picker fs-label-message{display:block;padding-bottom:1em}\n"], dependencies: [{ kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5$2.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: i5$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i4.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i4.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "directive", type: i7$2.MatAccordion, selector: "mat-accordion", inputs: ["hideToggle", "displayMode", "togglePosition"], exportAs: ["matAccordion"] }, { kind: "component", type: i7$2.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i7$2.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "directive", type: i7$2.MatExpansionPanelTitle, selector: "mat-panel-title" }, { kind: "directive", type: i5$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: i3$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i10$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i10$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i10$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i11.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i12.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i13.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i14.FsFilePickerComponent, selector: "fs-file-picker", inputs: ["minWidth", "minHeight", "imageWidth", "imageHeight", "imageQuality", "label", "showFilename", "allowDownload", "allowReupload", "multiple", "allowRemove", "url", "file", "accept", "disabled", "previewWidth", "previewHeight"], outputs: ["select", "remove", "download"] }, { kind: "directive", type: i14.FsFileLabelDirective, selector: "[fsFileLabel]" }, { kind: "component", type: i15.FsDatePickerComponent, selector: "[fsDatePicker]", inputs: ["minYear", "maxYear", "minDate", "maxDate", "startOfDay", "view", "format", "minutes"], outputs: ["change"] }, { kind: "component", type: i15.FsTimePickerComponent, selector: "[fsTimePicker]", inputs: ["view"] }, { kind: "component", type: i16.FsColorPickerComponent, selector: "[fsColorPicker]", inputs: ["showClear"] }, { kind: "pipe", type: KeyNameValuePipe, name: "keyNameValue" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1629
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.7", type: SettingsComponent, selector: "fs-system-settings", inputs: { loadSettings: "loadSettings", save: "save" }, outputs: { fileRemove: "fileRemove", fileSelect: "fileSelect" }, ngImport: i0, template: "<mat-accordion>\r\n <mat-expansion-panel\r\n hideToggle\r\n *ngFor=\"let group of groups\">\r\n <mat-expansion-panel-header>\r\n <mat-panel-title>\r\n <div class=\"title-row\">\r\n <div class=\"title\">\r\n {{ group || 'General' }}\r\n </div>\r\n <div class=\"actions\">\r\n <button\r\n type=\"button\"\r\n [matTooltip]=\"'Export ' + (group || 'General') + ' Settings'\"\r\n mat-icon-button\r\n (click)=\"export($event, groupedSettings[group])\">\r\n <mat-icon>\r\n cloud_download\r\n </mat-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n [matTooltip]=\"'Import ' + (group || 'General') + ' Settings'\"\r\n mat-icon-button\r\n (click)=\"import($event, group)\">\r\n <mat-icon>\r\n cloud_upload\r\n </mat-icon>\r\n </button>\r\n </div>\r\n </div>\r\n </mat-panel-title>\r\n </mat-expansion-panel-header>\r\n <div\r\n hideToggle\r\n *ngFor=\"let setting of groupedSettings[group]\"\r\n class=\"setting\"\r\n [ngClass]=\"{ 'has-instruction': !! setting.instruction }\">\r\n <mat-form-field\r\n class=\"full-width form-field-multiline-subscript\"\r\n *ngIf=\"setting.interfaceType===SettingInterfaceType.InputBox\">\r\n <mat-label>\r\n {{ setting.label }}\r\n </mat-label>\r\n <input\r\n matInput\r\n [(ngModel)]=\"setting.value\"\r\n [name]=\"'setting' + setting.id\">\r\n <mat-hint>\r\n {{ setting.instruction }}\r\n </mat-hint>\r\n </mat-form-field>\r\n <mat-form-field\r\n class=\"full-width form-field-multiline-subscript\"\r\n *ngIf=\"setting.interfaceType===SettingInterfaceType.Textarea\">\r\n <mat-label>\r\n {{ setting.label }}\r\n </mat-label>\r\n <textarea\r\n matInput\r\n [(ngModel)]=\"setting.value\"\r\n [name]=\"'setting' + setting.id\">\r\n </textarea>\r\n <mat-hint>\r\n {{ setting.instruction }}\r\n </mat-hint>\r\n </mat-form-field>\r\n <mat-form-field\r\n class=\"full-width form-field-multiline-subscript\"\r\n *ngIf=\"setting.interfaceType===SettingInterfaceType.Select || setting.interfaceType===SettingInterfaceType.SelectMultiple\">\r\n <mat-label>\r\n {{ setting.label }}\r\n </mat-label>\r\n <mat-select\r\n [(ngModel)]=\"setting.value\"\r\n [multiple]=\"setting.interfaceType===SettingInterfaceType.SelectMultiple\"\r\n [name]=\"'setting' + setting.id\">\r\n <mat-option\r\n *ngFor=\"let item of setting.values | keyNameValue\"\r\n [value]=\"item.value\">\r\n {{ item.name }}\r\n </mat-option>\r\n </mat-select>\r\n <mat-hint>\r\n {{ setting.instruction }}\r\n </mat-hint>\r\n </mat-form-field>\r\n <mat-form-field\r\n class=\"full-width form-field-multiline-subscript\"\r\n *ngIf=\"setting.interfaceType===SettingInterfaceType.Date\">\r\n <mat-label>\r\n {{ setting.label }}\r\n </mat-label>\r\n <input\r\n matInput\r\n fsDatePicker\r\n [(ngModel)]=\"setting.value\"\r\n [name]=\"'setting' + setting.id\">\r\n <mat-hint>\r\n {{ setting.instruction }}\r\n </mat-hint>\r\n </mat-form-field>\r\n <mat-form-field\r\n class=\"full-width form-field-multiline-subscript\"\r\n *ngIf=\"setting.interfaceType===SettingInterfaceType.Color\">\r\n <mat-label>\r\n {{ setting.label }}\r\n </mat-label>\r\n <input\r\n matInput\r\n fsColorPicker\r\n [(ngModel)]=\"setting.value\"\r\n [name]=\"'setting' + setting.id\">\r\n <mat-hint>\r\n {{ setting.instruction }}\r\n </mat-hint>\r\n </mat-form-field>\r\n <mat-form-field\r\n class=\"full-width form-field-multiline-subscript\"\r\n *ngIf=\"setting.interfaceType===SettingInterfaceType.Time\">\r\n <mat-label>\r\n {{ setting.label }}\r\n </mat-label>\r\n <input\r\n matInput\r\n fsTimePicker\r\n [(ngModel)]=\"setting.value\"\r\n [name]=\"'setting' + setting.id\">\r\n <mat-hint>\r\n {{ setting.instruction }}\r\n </mat-hint>\r\n </mat-form-field>\r\n <fs-file-picker\r\n *ngIf=\"setting.interfaceType===SettingInterfaceType.File\"\r\n [allowRemove]=\"true\"\r\n [allowDownload]=\"true\"\r\n (select)=\"fileSelect.emit({ setting: setting, file: $event.file })\"\r\n (remove)=\"fileRemove.emit(setting)\"\r\n [url]=\"setting.value\">\r\n <div fsFileLabel>\r\n {{ setting.label }}\r\n </div>\r\n <div fsFileHint>\r\n {{ setting.instruction }}\r\n </div>\r\n </fs-file-picker>\r\n </div>\r\n <button\r\n mat-stroked-button\r\n color=\"primary\"\r\n type=\"button\"\r\n (click)=\"saveGroup(group)\">\r\n Save\r\n </button>\r\n </mat-expansion-panel>\r\n</mat-accordion>", styles: [".mat-expansion-panel-header{font-size:19px}.full-width{width:100%}.title-row{flex-direction:row;box-sizing:border-box;display:flex;place-content:center flex-start;align-items:center;width:100%}.title-row .title{display:flex;flex:1}:host ::ng-deep .mat-expansion-panel-header-title{margin:0}:host ::ng-deep .mat-expansion-panel .actions{display:none}:host ::ng-deep .mat-expansion-panel.mat-expanded .actions{display:block}:host ::ng-deep .setting.has-instruction fs-file-picker fs-label-message{display:block;padding-bottom:1em}\n"], dependencies: [{ kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5$2.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: i5$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i4.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i4.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "directive", type: i7$2.MatAccordion, selector: "mat-accordion", inputs: ["hideToggle", "displayMode", "togglePosition"], exportAs: ["matAccordion"] }, { kind: "component", type: i7$2.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i7$2.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "directive", type: i7$2.MatExpansionPanelTitle, selector: "mat-panel-title" }, { kind: "directive", type: i5$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: i3$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i10$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i10$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i10$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i11.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i12.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i13.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i14.FsFilePickerComponent, selector: "fs-file-picker", inputs: ["minWidth", "minHeight", "imageWidth", "imageHeight", "imageQuality", "label", "showFilename", "allowDownload", "allowReupload", "multiple", "allowRemove", "url", "file", "accept", "disabled", "previewWidth", "previewHeight"], outputs: ["select", "remove", "download"] }, { kind: "directive", type: i14.FsFileLabelDirective, selector: "[fsFileLabel]" }, { kind: "component", type: i15.FsDatePickerComponent, selector: "[fsDatePicker]", inputs: ["minYear", "maxYear", "minDate", "maxDate", "startOfDay", "view", "format", "minutes"], outputs: ["change"] }, { kind: "component", type: i15.FsTimePickerComponent, selector: "[fsTimePicker]", inputs: ["view"] }, { kind: "component", type: i16.FsColorPickerComponent, selector: "[fsColorPicker]", inputs: ["showClear"] }, { kind: "pipe", type: KeyNameValuePipe, name: "keyNameValue" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1628
1630
  }
1629
1631
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: SettingsComponent, decorators: [{
1630
1632
  type: Component,
1631
- args: [{ selector: 'fs-system-settings', changeDetection: ChangeDetectionStrategy.OnPush, template: "\r\n<mat-accordion>\r\n <mat-expansion-panel hideToggle *ngFor=\"let group of groups\">\r\n <mat-expansion-panel-header>\r\n <mat-panel-title>\r\n <div class=\"title-row\">\r\n <div class=\"title\">{{group || 'General'}}</div>\r\n <div class=\"actions\">\r\n <button\r\n type=\"button\"\r\n [matTooltip]=\"'Export ' + (group || 'General') + ' Settings'\"\r\n mat-icon-button\r\n (click)=\"export($event, groupedSettings[group])\">\r\n <mat-icon>cloud_download</mat-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n [matTooltip]=\"'Import ' + (group || 'General') + ' Settings'\"\r\n mat-icon-button\r\n (click)=\"import($event, group)\">\r\n <mat-icon>cloud_upload</mat-icon>\r\n </button>\r\n </div>\r\n </div>\r\n </mat-panel-title>\r\n </mat-expansion-panel-header>\r\n\r\n <div \r\n hideToggle \r\n *ngFor=\"let setting of groupedSettings[group]\" \r\n class=\"setting\"\r\n [ngClass]=\"{ 'has-instruction': !! setting.instruction }\">\r\n <mat-form-field \r\n class=\"full-width form-field-multiline-subscript\"\r\n *ngIf=\"setting.interfaceType===SettingInterfaceType.InputBox\">\r\n <mat-label>{{setting.label}}</mat-label>\r\n <input\r\n matInput\r\n [(ngModel)]=\"setting.value\"\r\n [name]=\"'setting' + setting.id\">\r\n <mat-hint>{{setting.instruction}}</mat-hint>\r\n </mat-form-field>\r\n\r\n <mat-form-field \r\n class=\"full-width form-field-multiline-subscript\" \r\n *ngIf=\"setting.interfaceType===SettingInterfaceType.Textarea\">\r\n <mat-label>{{setting.label}}</mat-label>\r\n <textarea\r\n matInput\r\n [(ngModel)]=\"setting.value\"\r\n [name]=\"'setting' + setting.id\">\r\n </textarea>\r\n <mat-hint>{{setting.instruction}}</mat-hint>\r\n </mat-form-field>\r\n\r\n <mat-form-field \r\n class=\"full-width form-field-multiline-subscript\" \r\n *ngIf=\"setting.interfaceType===SettingInterfaceType.Select || setting.interfaceType===SettingInterfaceType.SelectMultiple\">\r\n <mat-label>{{setting.label}}</mat-label>\r\n <mat-select\r\n [(ngModel)]=\"setting.value\"\r\n [multiple]=\"setting.interfaceType===SettingInterfaceType.SelectMultiple\"\r\n [name]=\"'setting' + setting.id\">\r\n <mat-option *ngFor=\"let item of setting.values | keyNameValue\" [value]=\"item.value\">\r\n {{item.name}}\r\n </mat-option>\r\n </mat-select>\r\n <mat-hint>{{setting.instruction}}</mat-hint>\r\n </mat-form-field>\r\n\r\n <mat-form-field \r\n class=\"full-width form-field-multiline-subscript\" \r\n *ngIf=\"setting.interfaceType===SettingInterfaceType.Date\">\r\n <mat-label>{{setting.label}}</mat-label>\r\n <input\r\n matInput\r\n fsDatePicker\r\n [(ngModel)]=\"setting.value\"\r\n [name]=\"'setting' + setting.id\">\r\n <mat-hint>{{setting.instruction}}</mat-hint>\r\n </mat-form-field>\r\n\r\n <mat-form-field \r\n class=\"full-width form-field-multiline-subscript\" \r\n *ngIf=\"setting.interfaceType===SettingInterfaceType.Color\">\r\n <mat-label>{{setting.label}}</mat-label>\r\n <input\r\n matInput\r\n fsColorPicker\r\n [(ngModel)]=\"setting.value\"\r\n [name]=\"'setting' + setting.id\">\r\n <mat-hint>{{setting.instruction}}</mat-hint>\r\n </mat-form-field>\r\n\r\n <mat-form-field \r\n class=\"full-width form-field-multiline-subscript\" \r\n *ngIf=\"setting.interfaceType===SettingInterfaceType.Time\">\r\n <mat-label>{{setting.label}}</mat-label>\r\n <input\r\n matInput\r\n fsTimePicker\r\n [(ngModel)]=\"setting.value\"\r\n [name]=\"'setting' + setting.id\">\r\n <mat-hint>{{setting.instruction}}</mat-hint>\r\n </mat-form-field>\r\n\r\n <fs-file-picker\r\n *ngIf=\"setting.interfaceType===SettingInterfaceType.File\"\r\n [allowRemove]=\"true\"\r\n [allowDownload]=\"true\"\r\n (select)=\"fileSelect.emit({ setting: setting, file: $event.file })\"\r\n (remove)=\"fileRemove.emit(setting)\"\r\n [url]=\"setting.value\">\r\n <div fsFileLabel>{{setting.label}}</div>\r\n <div fsFileHint>{{setting.instruction}}</div>\r\n </fs-file-picker>\r\n </div>\r\n\r\n <button mat-raised-button color=\"primary\" type=\"button\" (click)=\"saveGroup(group)\">Save</button>\r\n\r\n </mat-expansion-panel>\r\n\r\n</mat-accordion>\r\n", styles: [".mat-expansion-panel-header{font-size:19px}.full-width{width:100%}.title-row{flex-direction:row;box-sizing:border-box;display:flex;place-content:center flex-start;align-items:center;width:100%}.title-row .title{display:flex;flex:1}:host ::ng-deep .mat-expansion-panel-header-title{margin:0}:host ::ng-deep .mat-expansion-panel .actions{display:none}:host ::ng-deep .mat-expansion-panel.mat-expanded .actions{display:block}:host ::ng-deep .setting.has-instruction fs-file-picker fs-label-message{display:block;padding-bottom:1em}\n"] }]
1633
+ args: [{ selector: 'fs-system-settings', changeDetection: ChangeDetectionStrategy.OnPush, template: "<mat-accordion>\r\n <mat-expansion-panel\r\n hideToggle\r\n *ngFor=\"let group of groups\">\r\n <mat-expansion-panel-header>\r\n <mat-panel-title>\r\n <div class=\"title-row\">\r\n <div class=\"title\">\r\n {{ group || 'General' }}\r\n </div>\r\n <div class=\"actions\">\r\n <button\r\n type=\"button\"\r\n [matTooltip]=\"'Export ' + (group || 'General') + ' Settings'\"\r\n mat-icon-button\r\n (click)=\"export($event, groupedSettings[group])\">\r\n <mat-icon>\r\n cloud_download\r\n </mat-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n [matTooltip]=\"'Import ' + (group || 'General') + ' Settings'\"\r\n mat-icon-button\r\n (click)=\"import($event, group)\">\r\n <mat-icon>\r\n cloud_upload\r\n </mat-icon>\r\n </button>\r\n </div>\r\n </div>\r\n </mat-panel-title>\r\n </mat-expansion-panel-header>\r\n <div\r\n hideToggle\r\n *ngFor=\"let setting of groupedSettings[group]\"\r\n class=\"setting\"\r\n [ngClass]=\"{ 'has-instruction': !! setting.instruction }\">\r\n <mat-form-field\r\n class=\"full-width form-field-multiline-subscript\"\r\n *ngIf=\"setting.interfaceType===SettingInterfaceType.InputBox\">\r\n <mat-label>\r\n {{ setting.label }}\r\n </mat-label>\r\n <input\r\n matInput\r\n [(ngModel)]=\"setting.value\"\r\n [name]=\"'setting' + setting.id\">\r\n <mat-hint>\r\n {{ setting.instruction }}\r\n </mat-hint>\r\n </mat-form-field>\r\n <mat-form-field\r\n class=\"full-width form-field-multiline-subscript\"\r\n *ngIf=\"setting.interfaceType===SettingInterfaceType.Textarea\">\r\n <mat-label>\r\n {{ setting.label }}\r\n </mat-label>\r\n <textarea\r\n matInput\r\n [(ngModel)]=\"setting.value\"\r\n [name]=\"'setting' + setting.id\">\r\n </textarea>\r\n <mat-hint>\r\n {{ setting.instruction }}\r\n </mat-hint>\r\n </mat-form-field>\r\n <mat-form-field\r\n class=\"full-width form-field-multiline-subscript\"\r\n *ngIf=\"setting.interfaceType===SettingInterfaceType.Select || setting.interfaceType===SettingInterfaceType.SelectMultiple\">\r\n <mat-label>\r\n {{ setting.label }}\r\n </mat-label>\r\n <mat-select\r\n [(ngModel)]=\"setting.value\"\r\n [multiple]=\"setting.interfaceType===SettingInterfaceType.SelectMultiple\"\r\n [name]=\"'setting' + setting.id\">\r\n <mat-option\r\n *ngFor=\"let item of setting.values | keyNameValue\"\r\n [value]=\"item.value\">\r\n {{ item.name }}\r\n </mat-option>\r\n </mat-select>\r\n <mat-hint>\r\n {{ setting.instruction }}\r\n </mat-hint>\r\n </mat-form-field>\r\n <mat-form-field\r\n class=\"full-width form-field-multiline-subscript\"\r\n *ngIf=\"setting.interfaceType===SettingInterfaceType.Date\">\r\n <mat-label>\r\n {{ setting.label }}\r\n </mat-label>\r\n <input\r\n matInput\r\n fsDatePicker\r\n [(ngModel)]=\"setting.value\"\r\n [name]=\"'setting' + setting.id\">\r\n <mat-hint>\r\n {{ setting.instruction }}\r\n </mat-hint>\r\n </mat-form-field>\r\n <mat-form-field\r\n class=\"full-width form-field-multiline-subscript\"\r\n *ngIf=\"setting.interfaceType===SettingInterfaceType.Color\">\r\n <mat-label>\r\n {{ setting.label }}\r\n </mat-label>\r\n <input\r\n matInput\r\n fsColorPicker\r\n [(ngModel)]=\"setting.value\"\r\n [name]=\"'setting' + setting.id\">\r\n <mat-hint>\r\n {{ setting.instruction }}\r\n </mat-hint>\r\n </mat-form-field>\r\n <mat-form-field\r\n class=\"full-width form-field-multiline-subscript\"\r\n *ngIf=\"setting.interfaceType===SettingInterfaceType.Time\">\r\n <mat-label>\r\n {{ setting.label }}\r\n </mat-label>\r\n <input\r\n matInput\r\n fsTimePicker\r\n [(ngModel)]=\"setting.value\"\r\n [name]=\"'setting' + setting.id\">\r\n <mat-hint>\r\n {{ setting.instruction }}\r\n </mat-hint>\r\n </mat-form-field>\r\n <fs-file-picker\r\n *ngIf=\"setting.interfaceType===SettingInterfaceType.File\"\r\n [allowRemove]=\"true\"\r\n [allowDownload]=\"true\"\r\n (select)=\"fileSelect.emit({ setting: setting, file: $event.file })\"\r\n (remove)=\"fileRemove.emit(setting)\"\r\n [url]=\"setting.value\">\r\n <div fsFileLabel>\r\n {{ setting.label }}\r\n </div>\r\n <div fsFileHint>\r\n {{ setting.instruction }}\r\n </div>\r\n </fs-file-picker>\r\n </div>\r\n <button\r\n mat-stroked-button\r\n color=\"primary\"\r\n type=\"button\"\r\n (click)=\"saveGroup(group)\">\r\n Save\r\n </button>\r\n </mat-expansion-panel>\r\n</mat-accordion>", styles: [".mat-expansion-panel-header{font-size:19px}.full-width{width:100%}.title-row{flex-direction:row;box-sizing:border-box;display:flex;place-content:center flex-start;align-items:center;width:100%}.title-row .title{display:flex;flex:1}:host ::ng-deep .mat-expansion-panel-header-title{margin:0}:host ::ng-deep .mat-expansion-panel .actions{display:none}:host ::ng-deep .mat-expansion-panel.mat-expanded .actions{display:block}:host ::ng-deep .setting.has-instruction fs-file-picker fs-label-message{display:block;padding-bottom:1em}\n"] }]
1632
1634
  }], ctorParameters: () => [{ type: i1$3.FsMessage }, { type: i2.FsClipboard }, { type: i2$2.FsPrompt }, { type: i0.ChangeDetectorRef }], propDecorators: { loadSettings: [{
1633
1635
  type: Input
1634
1636
  }], save: [{