@myrmidon/cadmus-ui 16.0.2 → 16.1.1

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.
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { input, output, Component, signal, effect, ViewChild, Injectable, Inject, computed, inject, Injector, model } from '@angular/core';
2
+ import { inject, DestroyRef, input, output, signal, effect, ChangeDetectionStrategy, Component, Injectable, Inject, computed, Injector, model } from '@angular/core';
3
3
  import { MatButton, MatIconButton } from '@angular/material/button';
4
4
  import { MatIcon } from '@angular/material/icon';
5
5
  import { SafeHtmlPipe, ColorToContrastPipe, deepCopy } from '@myrmidon/ngx-tools';
@@ -10,7 +10,7 @@ import { FormsModule, ReactiveFormsModule, PristineChangeEvent } from '@angular/
10
10
  import { MatCheckbox } from '@angular/material/checkbox';
11
11
  import * as i2 from '@myrmidon/ngx-mat-tools';
12
12
  import { AsyncPipe } from '@angular/common';
13
- import { of, BehaviorSubject, map as map$1, Subject } from 'rxjs';
13
+ import { of, map as map$1, Subject } from 'rxjs';
14
14
  import { debounceTime, distinctUntilChanged, switchMap, map, take } from 'rxjs/operators';
15
15
  import { MatAutocomplete, MatAutocompleteTrigger } from '@angular/material/autocomplete';
16
16
  import { MatOption } from '@angular/material/core';
@@ -21,19 +21,43 @@ import { AppRepository } from '@myrmidon/cadmus-state';
21
21
  import * as i1$3 from '@myrmidon/auth-jwt-login';
22
22
 
23
23
  class CloseSaveButtonsComponent {
24
- form = input(...(ngDevMode ? [undefined, { debugName: "form" }] : []));
25
- noSave = input(...(ngDevMode ? [undefined, { debugName: "noSave" }] : []));
24
+ _statusSub;
25
+ _destroyRef = inject(DestroyRef);
26
+ form = input(...(ngDevMode ? [undefined, { debugName: "form" }] : /* istanbul ignore next */ []));
27
+ noSave = input(...(ngDevMode ? [undefined, { debugName: "noSave" }] : /* istanbul ignore next */ []));
26
28
  closeRequest = output();
29
+ /**
30
+ * Reactive invalid state: true when the current form is invalid.
31
+ * Derived from the form's statusChanges so that OnPush components
32
+ * re-render whenever validity changes without a reference change.
33
+ */
34
+ invalid = signal(false, ...(ngDevMode ? [{ debugName: "invalid" }] : /* istanbul ignore next */ []));
35
+ constructor() {
36
+ // Clean up the statusChanges subscription when the component is destroyed
37
+ this._destroyRef.onDestroy(() => this._statusSub?.unsubscribe());
38
+ // Re-subscribe whenever the form input changes
39
+ effect(() => {
40
+ this._statusSub?.unsubscribe();
41
+ const f = this.form();
42
+ if (f) {
43
+ this.invalid.set(f.invalid);
44
+ this._statusSub = f.statusChanges.subscribe(() => this.invalid.set(f.invalid));
45
+ }
46
+ else {
47
+ this.invalid.set(false);
48
+ }
49
+ });
50
+ }
27
51
  close() {
28
52
  this.closeRequest.emit();
29
53
  }
30
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: CloseSaveButtonsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
31
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.3", type: CloseSaveButtonsComponent, isStandalone: true, selector: "cadmus-close-save-buttons", inputs: { form: { classPropertyName: "form", publicName: "form", isSignal: true, isRequired: false, transformFunction: null }, noSave: { classPropertyName: "noSave", publicName: "noSave", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { closeRequest: "closeRequest" }, ngImport: i0, template: "@if (form()) {\n<div class=\"form-row\">\n <button type=\"button\" mat-flat-button class=\"mat-warn\" (click)=\"close()\">\n <mat-icon>cancel</mat-icon>\n close\n </button>\n @if (!noSave()) {\n <button\n type=\"submit\"\n [disabled]=\"form()?.invalid\"\n mat-flat-button\n class=\"mat-primary\"\n >\n <mat-icon>check_circle</mat-icon>\n save\n </button>\n }\n</div>\n}\n", styles: [".form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row *{flex:0 0 auto}\n"], dependencies: [{ kind: "component", type: MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }] });
54
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: CloseSaveButtonsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
55
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: CloseSaveButtonsComponent, isStandalone: true, selector: "cadmus-close-save-buttons", inputs: { form: { classPropertyName: "form", publicName: "form", isSignal: true, isRequired: false, transformFunction: null }, noSave: { classPropertyName: "noSave", publicName: "noSave", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { closeRequest: "closeRequest" }, ngImport: i0, template: "@if (form()) {\n <div class=\"form-row\">\n <button type=\"button\" mat-flat-button class=\"mat-warn\" (click)=\"close()\">\n <mat-icon>cancel</mat-icon>\n close\n </button>\n @if (!noSave()) {\n <button\n type=\"submit\"\n [disabled]=\"invalid()\"\n mat-flat-button\n class=\"mat-primary\"\n >\n <mat-icon>check_circle</mat-icon>\n save\n </button>\n }\n </div>\n}\n", styles: [".form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row *{flex:0 0 auto}\n"], dependencies: [{ kind: "component", type: MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
32
56
  }
33
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: CloseSaveButtonsComponent, decorators: [{
57
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: CloseSaveButtonsComponent, decorators: [{
34
58
  type: Component,
35
- args: [{ selector: 'cadmus-close-save-buttons', imports: [MatButton, MatIcon], template: "@if (form()) {\n<div class=\"form-row\">\n <button type=\"button\" mat-flat-button class=\"mat-warn\" (click)=\"close()\">\n <mat-icon>cancel</mat-icon>\n close\n </button>\n @if (!noSave()) {\n <button\n type=\"submit\"\n [disabled]=\"form()?.invalid\"\n mat-flat-button\n class=\"mat-primary\"\n >\n <mat-icon>check_circle</mat-icon>\n save\n </button>\n }\n</div>\n}\n", styles: [".form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row *{flex:0 0 auto}\n"] }]
36
- }], propDecorators: { form: [{ type: i0.Input, args: [{ isSignal: true, alias: "form", required: false }] }], noSave: [{ type: i0.Input, args: [{ isSignal: true, alias: "noSave", required: false }] }], closeRequest: [{ type: i0.Output, args: ["closeRequest"] }] } });
59
+ args: [{ selector: 'cadmus-close-save-buttons', imports: [MatButton, MatIcon], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (form()) {\n <div class=\"form-row\">\n <button type=\"button\" mat-flat-button class=\"mat-warn\" (click)=\"close()\">\n <mat-icon>cancel</mat-icon>\n close\n </button>\n @if (!noSave()) {\n <button\n type=\"submit\"\n [disabled]=\"invalid()\"\n mat-flat-button\n class=\"mat-primary\"\n >\n <mat-icon>check_circle</mat-icon>\n save\n </button>\n }\n </div>\n}\n", styles: [".form-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.form-row *{flex:0 0 auto}\n"] }]
60
+ }], ctorParameters: () => [], propDecorators: { form: [{ type: i0.Input, args: [{ isSignal: true, alias: "form", required: false }] }], noSave: [{ type: i0.Input, args: [{ isSignal: true, alias: "noSave", required: false }] }], closeRequest: [{ type: i0.Output, args: ["closeRequest"] }] } });
37
61
 
38
62
  /**
39
63
  * Decorated token-based text visualizer. This is used when editing
@@ -41,51 +65,44 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
41
65
  */
42
66
  class DecoratedTokenTextComponent {
43
67
  _textLayerService;
44
- _textElement;
45
68
  /**
46
69
  * The base text.
47
70
  */
48
- baseText = input('', ...(ngDevMode ? [{ debugName: "baseText" }] : []));
71
+ baseText = input('', ...(ngDevMode ? [{ debugName: "baseText" }] : /* istanbul ignore next */ []));
49
72
  /**
50
73
  * The token-based locations of all the fragments in the layer.
51
74
  */
52
- locations = input([], ...(ngDevMode ? [{ debugName: "locations" }] : []));
75
+ locations = input([], ...(ngDevMode ? [{ debugName: "locations" }] : /* istanbul ignore next */ []));
53
76
  /**
54
77
  * A selected token-based location.
55
78
  */
56
- selectedLocation = input(...(ngDevMode ? [undefined, { debugName: "selectedLocation" }] : []));
57
- text = signal(undefined, ...(ngDevMode ? [{ debugName: "text" }] : [])); // rendered HTML text
79
+ selectedLocation = input(...(ngDevMode ? [undefined, { debugName: "selectedLocation" }] : /* istanbul ignore next */ []));
80
+ text = signal(undefined, ...(ngDevMode ? [{ debugName: "text" }] : /* istanbul ignore next */ [])); // rendered HTML text
58
81
  constructor(_textLayerService) {
59
82
  this._textLayerService = _textLayerService;
60
83
  effect(() => {
61
84
  this.decorate(this.baseText(), this.locations(), this.selectedLocation());
62
85
  });
63
86
  }
64
- ngOnInit() {
65
- this.decorate(this.baseText(), this.locations(), this.selectedLocation());
66
- }
67
87
  decorate(text, locations, selectedLocation) {
68
88
  this.text.set(this._textLayerService.render(text, locations, selectedLocation));
69
89
  }
70
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: DecoratedTokenTextComponent, deps: [{ token: i1.TextLayerService }], target: i0.ɵɵFactoryTarget.Component });
71
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.3", type: DecoratedTokenTextComponent, isStandalone: true, selector: "cadmus-decorated-token-text", inputs: { baseText: { classPropertyName: "baseText", publicName: "baseText", isSignal: true, isRequired: false, transformFunction: null }, locations: { classPropertyName: "locations", publicName: "locations", isSignal: true, isRequired: false, transformFunction: null }, selectedLocation: { classPropertyName: "selectedLocation", publicName: "selectedLocation", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "_textElement", first: true, predicate: ["textElem"], descendants: true }], ngImport: i0, template: "<div [innerHtml]=\"text() | safeHtml : 'html'\" id=\"text\" #textElem></div>\r\n", styles: [":host ::ng-deep div#text{counter-reset:text-y-counter}:host ::ng-deep div#text p:before{content:counter(text-y-counter);counter-increment:text-y-counter;margin-right:6px;color:#a0a0a0}:host ::ng-deep span.fr{background-color:#ff0;border:1px solid silver;border-radius:6px;padding:0 4px}:host ::ng-deep span.fr-sel{background-color:orange;font-weight:700;border:1px solid #404040}\n"], dependencies: [{ kind: "pipe", type: SafeHtmlPipe, name: "safeHtml" }] });
90
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DecoratedTokenTextComponent, deps: [{ token: i1.TextLayerService }], target: i0.ɵɵFactoryTarget.Component });
91
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.4", type: DecoratedTokenTextComponent, isStandalone: true, selector: "cadmus-decorated-token-text", inputs: { baseText: { classPropertyName: "baseText", publicName: "baseText", isSignal: true, isRequired: false, transformFunction: null }, locations: { classPropertyName: "locations", publicName: "locations", isSignal: true, isRequired: false, transformFunction: null }, selectedLocation: { classPropertyName: "selectedLocation", publicName: "selectedLocation", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div [innerHtml]=\"text() | safeHtml : 'html'\" id=\"text\" #textElem></div>\r\n", styles: [":host ::ng-deep div#text{counter-reset:text-y-counter}:host ::ng-deep div#text p:before{content:counter(text-y-counter);counter-increment:text-y-counter;margin-right:6px;color:#a0a0a0}:host ::ng-deep span.fr{background-color:#ff0;border:1px solid silver;border-radius:6px;padding:0 4px}:host ::ng-deep span.fr-sel{background-color:orange;font-weight:700;border:1px solid #404040}\n"], dependencies: [{ kind: "pipe", type: SafeHtmlPipe, name: "safeHtml" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
72
92
  }
73
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: DecoratedTokenTextComponent, decorators: [{
93
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DecoratedTokenTextComponent, decorators: [{
74
94
  type: Component,
75
- args: [{ selector: 'cadmus-decorated-token-text', imports: [SafeHtmlPipe], template: "<div [innerHtml]=\"text() | safeHtml : 'html'\" id=\"text\" #textElem></div>\r\n", styles: [":host ::ng-deep div#text{counter-reset:text-y-counter}:host ::ng-deep div#text p:before{content:counter(text-y-counter);counter-increment:text-y-counter;margin-right:6px;color:#a0a0a0}:host ::ng-deep span.fr{background-color:#ff0;border:1px solid silver;border-radius:6px;padding:0 4px}:host ::ng-deep span.fr-sel{background-color:orange;font-weight:700;border:1px solid #404040}\n"] }]
76
- }], ctorParameters: () => [{ type: i1.TextLayerService }], propDecorators: { _textElement: [{
77
- type: ViewChild,
78
- args: ['textElem']
79
- }], baseText: [{ type: i0.Input, args: [{ isSignal: true, alias: "baseText", required: false }] }], locations: [{ type: i0.Input, args: [{ isSignal: true, alias: "locations", required: false }] }], selectedLocation: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedLocation", required: false }] }] } });
95
+ args: [{ selector: 'cadmus-decorated-token-text', imports: [SafeHtmlPipe], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [innerHtml]=\"text() | safeHtml : 'html'\" id=\"text\" #textElem></div>\r\n", styles: [":host ::ng-deep div#text{counter-reset:text-y-counter}:host ::ng-deep div#text p:before{content:counter(text-y-counter);counter-increment:text-y-counter;margin-right:6px;color:#a0a0a0}:host ::ng-deep span.fr{background-color:#ff0;border:1px solid silver;border-radius:6px;padding:0 4px}:host ::ng-deep span.fr-sel{background-color:orange;font-weight:700;border:1px solid #404040}\n"] }]
96
+ }], ctorParameters: () => [{ type: i1.TextLayerService }], propDecorators: { baseText: [{ type: i0.Input, args: [{ isSignal: true, alias: "baseText", required: false }] }], locations: [{ type: i0.Input, args: [{ isSignal: true, alias: "locations", required: false }] }], selectedLocation: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedLocation", required: false }] }] } });
80
97
 
81
98
  class ErrorListComponent {
82
- errors = input(...(ngDevMode ? [undefined, { debugName: "errors" }] : []));
83
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ErrorListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
84
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.3", type: ErrorListComponent, isStandalone: true, selector: "cadmus-error-list", inputs: { errors: { classPropertyName: "errors", publicName: "errors", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if (errors()?.length) {\n <ul>\n @for (error of errors(); track error) {\n <li class=\"error\">{{error}}</li>\n }\n </ul>\n}\n", styles: [".error{color:red}\n"] });
99
+ errors = input(...(ngDevMode ? [undefined, { debugName: "errors" }] : /* istanbul ignore next */ []));
100
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: ErrorListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
101
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: ErrorListComponent, isStandalone: true, selector: "cadmus-error-list", inputs: { errors: { classPropertyName: "errors", publicName: "errors", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if (errors()?.length) {\n <ul>\n @for (error of errors(); track error) {\n <li class=\"error\">{{error}}</li>\n }\n </ul>\n}\n", styles: [".error{color:var(--mat-sys-error)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
85
102
  }
86
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ErrorListComponent, decorators: [{
103
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: ErrorListComponent, decorators: [{
87
104
  type: Component,
88
- args: [{ selector: 'cadmus-error-list', template: "@if (errors()?.length) {\n <ul>\n @for (error of errors(); track error) {\n <li class=\"error\">{{error}}</li>\n }\n </ul>\n}\n", styles: [".error{color:red}\n"] }]
105
+ args: [{ selector: 'cadmus-error-list', changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (errors()?.length) {\n <ul>\n @for (error of errors(); track error) {\n <li class=\"error\">{{error}}</li>\n }\n </ul>\n}\n", styles: [".error{color:var(--mat-sys-error)}\n"] }]
89
106
  }], propDecorators: { errors: [{ type: i0.Input, args: [{ isSignal: true, alias: "errors", required: false }] }] } });
90
107
 
91
108
  /**
@@ -231,10 +248,10 @@ class ColorService {
231
248
  const rgb = this.hslToRgb(h, s, l);
232
249
  return this.rgbToString(rgb.r, rgb.g, rgb.b);
233
250
  }
234
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ColorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
235
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ColorService, providedIn: 'root' });
251
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: ColorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
252
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: ColorService, providedIn: 'root' });
236
253
  }
237
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ColorService, decorators: [{
254
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: ColorService, decorators: [{
238
255
  type: Injectable,
239
256
  args: [{
240
257
  providedIn: 'root',
@@ -245,15 +262,15 @@ class FacetBadgeComponent {
245
262
  _colorService;
246
263
  _facetColors;
247
264
  _facetTips;
248
- color = signal('transparent', ...(ngDevMode ? [{ debugName: "color" }] : []));
249
- contrastColor = signal('black', ...(ngDevMode ? [{ debugName: "contrastColor" }] : []));
250
- tip = signal(undefined, ...(ngDevMode ? [{ debugName: "tip" }] : []));
265
+ color = signal('transparent', ...(ngDevMode ? [{ debugName: "color" }] : /* istanbul ignore next */ []));
266
+ contrastColor = signal('black', ...(ngDevMode ? [{ debugName: "contrastColor" }] : /* istanbul ignore next */ []));
267
+ tip = signal(undefined, ...(ngDevMode ? [{ debugName: "tip" }] : /* istanbul ignore next */ []));
251
268
  /**
252
269
  * The facet data.
253
270
  */
254
271
  data = input({
255
272
  definitions: [],
256
- }, ...(ngDevMode ? [{ debugName: "data" }] : []));
273
+ }, ...(ngDevMode ? [{ debugName: "data" }] : /* istanbul ignore next */ []));
257
274
  constructor(_colorService) {
258
275
  this._colorService = _colorService;
259
276
  this._facetColors = {};
@@ -315,12 +332,12 @@ class FacetBadgeComponent {
315
332
  this.contrastColor.set(this._colorService.getContrastColor(this.color()));
316
333
  this.tip.set(this.getFacetTip(data?.facetId || '') ?? undefined);
317
334
  }
318
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: FacetBadgeComponent, deps: [{ token: ColorService }], target: i0.ɵɵFactoryTarget.Component });
319
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.3", type: FacetBadgeComponent, isStandalone: true, selector: "cadmus-facet-badge", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<span\r\n class=\"model-type\"\r\n [style.background-color]=\"color()\"\r\n [style.color]=\"contrastColor()\"\r\n matTooltip=\"{{ tip() }}\"\r\n >{{ data().facetId }}\r\n</span>\r\n", styles: ["span.model-type{padding:4px;border-radius:6px}\n"], dependencies: [{ kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }] });
335
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: FacetBadgeComponent, deps: [{ token: ColorService }], target: i0.ɵɵFactoryTarget.Component });
336
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.4", type: FacetBadgeComponent, isStandalone: true, selector: "cadmus-facet-badge", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<span\r\n class=\"model-type\"\r\n [style.background-color]=\"color()\"\r\n [style.color]=\"contrastColor()\"\r\n matTooltip=\"{{ tip() }}\"\r\n >{{ data().facetId }}\r\n</span>\r\n", styles: ["span.model-type{padding:4px;border-radius:6px}\n"], dependencies: [{ kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
320
337
  }
321
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: FacetBadgeComponent, decorators: [{
338
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: FacetBadgeComponent, decorators: [{
322
339
  type: Component,
323
- args: [{ selector: 'cadmus-facet-badge', imports: [MatTooltip], template: "<span\r\n class=\"model-type\"\r\n [style.background-color]=\"color()\"\r\n [style.color]=\"contrastColor()\"\r\n matTooltip=\"{{ tip() }}\"\r\n >{{ data().facetId }}\r\n</span>\r\n", styles: ["span.model-type{padding:4px;border-radius:6px}\n"] }]
340
+ args: [{ selector: 'cadmus-facet-badge', imports: [MatTooltip], changeDetection: ChangeDetectionStrategy.OnPush, template: "<span\r\n class=\"model-type\"\r\n [style.background-color]=\"color()\"\r\n [style.color]=\"contrastColor()\"\r\n matTooltip=\"{{ tip() }}\"\r\n >{{ data().facetId }}\r\n</span>\r\n", styles: ["span.model-type{padding:4px;border-radius:6px}\n"] }]
324
341
  }], ctorParameters: () => [{ type: ColorService }], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }] } });
325
342
 
326
343
  /**
@@ -328,8 +345,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
328
345
  * with the flag's color key.
329
346
  */
330
347
  class FlagsBadgeComponent {
331
- data = input(...(ngDevMode ? [undefined, { debugName: "data" }] : []));
332
- badgeFlags = signal([], ...(ngDevMode ? [{ debugName: "badgeFlags" }] : []));
348
+ data = input(...(ngDevMode ? [undefined, { debugName: "data" }] : /* istanbul ignore next */ []));
349
+ badgeFlags = signal([], ...(ngDevMode ? [{ debugName: "badgeFlags" }] : /* istanbul ignore next */ []));
333
350
  constructor() {
334
351
  effect(() => {
335
352
  this.updateBadge(this.data());
@@ -344,21 +361,21 @@ class FlagsBadgeComponent {
344
361
  return def.id & data.flags;
345
362
  }));
346
363
  }
347
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: FlagsBadgeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
348
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.3", type: FlagsBadgeComponent, isStandalone: true, selector: "cadmus-flags-badge", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div>\r\n @for (def of badgeFlags(); track def.id) {\r\n <span\r\n class=\"badge-flag\"\r\n [style.color]=\"'#' + def.colorKey\"\r\n [matTooltip]=\"def.label\"\r\n >\r\n @if (def.isAdmin) { &#x25c6; } @else { &#x2b24; }\r\n </span>\r\n }\r\n</div>\r\n", styles: ["span.badge-flag{font-size:1rem;cursor:default}\n"], dependencies: [{ kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }] });
364
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: FlagsBadgeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
365
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: FlagsBadgeComponent, isStandalone: true, selector: "cadmus-flags-badge", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div>\r\n @for (def of badgeFlags(); track def.id) {\r\n <span\r\n class=\"badge-flag\"\r\n [style.color]=\"'#' + def.colorKey\"\r\n [matTooltip]=\"def.label\"\r\n >\r\n @if (def.isAdmin) { &#x25c6; } @else { &#x2b24; }\r\n </span>\r\n }\r\n</div>\r\n", styles: ["span.badge-flag{font-size:1rem;cursor:default}\n"], dependencies: [{ kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
349
366
  }
350
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: FlagsBadgeComponent, decorators: [{
367
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: FlagsBadgeComponent, decorators: [{
351
368
  type: Component,
352
- args: [{ selector: 'cadmus-flags-badge', imports: [MatTooltip], template: "<div>\r\n @for (def of badgeFlags(); track def.id) {\r\n <span\r\n class=\"badge-flag\"\r\n [style.color]=\"'#' + def.colorKey\"\r\n [matTooltip]=\"def.label\"\r\n >\r\n @if (def.isAdmin) { &#x25c6; } @else { &#x2b24; }\r\n </span>\r\n }\r\n</div>\r\n", styles: ["span.badge-flag{font-size:1rem;cursor:default}\n"] }]
369
+ args: [{ selector: 'cadmus-flags-badge', imports: [MatTooltip], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div>\r\n @for (def of badgeFlags(); track def.id) {\r\n <span\r\n class=\"badge-flag\"\r\n [style.color]=\"'#' + def.colorKey\"\r\n [matTooltip]=\"def.label\"\r\n >\r\n @if (def.isAdmin) { &#x25c6; } @else { &#x2b24; }\r\n </span>\r\n }\r\n</div>\r\n", styles: ["span.badge-flag{font-size:1rem;cursor:default}\n"] }]
353
370
  }], ctorParameters: () => [], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }] } });
354
371
 
355
372
  class LayerHintsComponent {
356
373
  _formBuilder;
357
374
  _dialogService;
358
- hints = input([], ...(ngDevMode ? [{ debugName: "hints" }] : []));
359
- targetLocation = input(...(ngDevMode ? [undefined, { debugName: "targetLocation" }] : []));
360
- disabled = input(...(ngDevMode ? [undefined, { debugName: "disabled" }] : []));
361
- readonly = input(...(ngDevMode ? [undefined, { debugName: "readonly" }] : []));
375
+ hints = input([], ...(ngDevMode ? [{ debugName: "hints" }] : /* istanbul ignore next */ []));
376
+ targetLocation = input(...(ngDevMode ? [undefined, { debugName: "targetLocation" }] : /* istanbul ignore next */ []));
377
+ disabled = input(...(ngDevMode ? [undefined, { debugName: "disabled" }] : /* istanbul ignore next */ []));
378
+ readonly = input(...(ngDevMode ? [undefined, { debugName: "readonly" }] : /* istanbul ignore next */ []));
362
379
  requestEdit = output();
363
380
  requestDelete = output();
364
381
  requestMove = output();
@@ -395,11 +412,11 @@ class LayerHintsComponent {
395
412
  });
396
413
  }
397
414
  emitRequestMove(hint) {
398
- if (!this.targetLocation) {
415
+ if (!this.targetLocation()) {
399
416
  return;
400
417
  }
401
418
  this._dialogService
402
- .confirm('Confirm Move', `Move fragment at ${hint.location} to ${this.targetLocation}?`)
419
+ .confirm('Confirm Move', `Move fragment at ${hint.location} to ${this.targetLocation()}?`)
403
420
  .subscribe((ok) => {
404
421
  if (ok) {
405
422
  this.requestMove.emit(hint);
@@ -424,10 +441,10 @@ class LayerHintsComponent {
424
441
  }
425
442
  });
426
443
  }
427
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: LayerHintsComponent, deps: [{ token: i1$1.FormBuilder }, { token: i2.DialogService }], target: i0.ɵɵFactoryTarget.Component });
428
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.3", type: LayerHintsComponent, isStandalone: true, selector: "cadmus-layer-hints", inputs: { hints: { classPropertyName: "hints", publicName: "hints", isSignal: true, isRequired: false, transformFunction: null }, targetLocation: { classPropertyName: "targetLocation", publicName: "targetLocation", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { requestEdit: "requestEdit", requestDelete: "requestDelete", requestMove: "requestMove", requestPatch: "requestPatch" }, ngImport: i0, template: "@if (hints().length) {\r\n<form [formGroup]=\"form\" (submit)=\"emitRequestPatch()\">\r\n <table class=\"patches\">\r\n <thead>\r\n <tr>\r\n <th></th>\r\n <th>location</th>\r\n <th>description</th>\r\n <th>patch</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @for (hint of hints(); track hint; let i = $index) {\r\n <tr>\r\n @if (!readonly()) {\r\n <td>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Edit this fragment\"\r\n [disabled]=\"disabled()\"\r\n >\r\n <mat-icon>edit</mat-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Move this fragment to {{ targetLocation() }}\"\r\n [disabled]=\"\r\n disabled() ||\r\n !targetLocation() ||\r\n targetLocation() === hint.location\r\n \"\r\n (click)=\"emitRequestMove(hint)\"\r\n >\r\n <mat-icon>arrow_forward</mat-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Delete this fragment\"\r\n [disabled]=\"disabled()\"\r\n (click)=\"emitRequestDelete(hint)\"\r\n >\r\n <mat-icon class=\"mat-warn\">delete</mat-icon>\r\n </button>\r\n </td>\r\n }\r\n <td>{{ hint.location }}</td>\r\n <td>{{ hint.description }}</td>\r\n <td>\r\n @if (hint.patchOperation) {\r\n <mat-checkbox\r\n matTooltip=\"Apply this patch\"\r\n [formControl]=\"checks.at(i)\"\r\n >\r\n {{ hint.patchOperation }}\r\n </mat-checkbox>\r\n }\r\n </td>\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n @if (targetLocation()) {\r\n <div>move target: {{ targetLocation() }}</div>\r\n }\r\n <button\r\n type=\"submit\"\r\n mat-flat-button\r\n [disabled]=\"readonly() || disabled() || form.invalid\"\r\n >\r\n apply patches\r\n </button>\r\n</form>\r\n}\r\n", styles: ["table.patches th{font-weight:400;color:#bdbdbd}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "component", type: MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }] });
444
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: LayerHintsComponent, deps: [{ token: i1$1.FormBuilder }, { token: i2.DialogService }], target: i0.ɵɵFactoryTarget.Component });
445
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: LayerHintsComponent, isStandalone: true, selector: "cadmus-layer-hints", inputs: { hints: { classPropertyName: "hints", publicName: "hints", isSignal: true, isRequired: false, transformFunction: null }, targetLocation: { classPropertyName: "targetLocation", publicName: "targetLocation", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { requestEdit: "requestEdit", requestDelete: "requestDelete", requestMove: "requestMove", requestPatch: "requestPatch" }, ngImport: i0, template: "@if (hints().length) {\r\n<form [formGroup]=\"form\" (submit)=\"emitRequestPatch()\">\r\n <table class=\"patches\">\r\n <thead>\r\n <tr>\r\n <th></th>\r\n <th>location</th>\r\n <th>description</th>\r\n <th>patch</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @for (hint of hints(); track hint; let i = $index) {\r\n <tr>\r\n @if (!readonly()) {\r\n <td>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Edit this fragment\"\r\n [disabled]=\"disabled()\"\r\n >\r\n <mat-icon>edit</mat-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Move this fragment to {{ targetLocation() }}\"\r\n [disabled]=\"\r\n disabled() ||\r\n !targetLocation() ||\r\n targetLocation() === hint.location\r\n \"\r\n (click)=\"emitRequestMove(hint)\"\r\n >\r\n <mat-icon>arrow_forward</mat-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Delete this fragment\"\r\n [disabled]=\"disabled()\"\r\n (click)=\"emitRequestDelete(hint)\"\r\n >\r\n <mat-icon class=\"mat-warn\">delete</mat-icon>\r\n </button>\r\n </td>\r\n }\r\n <td>{{ hint.location }}</td>\r\n <td>{{ hint.description }}</td>\r\n <td>\r\n @if (hint.patchOperation) {\r\n <mat-checkbox\r\n matTooltip=\"Apply this patch\"\r\n [formControl]=\"checks.at(i)\"\r\n >\r\n {{ hint.patchOperation }}\r\n </mat-checkbox>\r\n }\r\n </td>\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n @if (targetLocation()) {\r\n <div>move target: {{ targetLocation() }}</div>\r\n }\r\n <button\r\n type=\"submit\"\r\n mat-flat-button\r\n [disabled]=\"readonly() || disabled() || form.invalid\"\r\n >\r\n apply patches\r\n </button>\r\n</form>\r\n}\r\n", styles: ["table.patches th{font-weight:400;color:#bdbdbd}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "component", type: MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
429
446
  }
430
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: LayerHintsComponent, decorators: [{
447
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: LayerHintsComponent, decorators: [{
431
448
  type: Component,
432
449
  args: [{ selector: 'cadmus-layer-hints', imports: [
433
450
  FormsModule,
@@ -437,7 +454,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
437
454
  MatIcon,
438
455
  MatCheckbox,
439
456
  MatButton,
440
- ], template: "@if (hints().length) {\r\n<form [formGroup]=\"form\" (submit)=\"emitRequestPatch()\">\r\n <table class=\"patches\">\r\n <thead>\r\n <tr>\r\n <th></th>\r\n <th>location</th>\r\n <th>description</th>\r\n <th>patch</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @for (hint of hints(); track hint; let i = $index) {\r\n <tr>\r\n @if (!readonly()) {\r\n <td>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Edit this fragment\"\r\n [disabled]=\"disabled()\"\r\n >\r\n <mat-icon>edit</mat-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Move this fragment to {{ targetLocation() }}\"\r\n [disabled]=\"\r\n disabled() ||\r\n !targetLocation() ||\r\n targetLocation() === hint.location\r\n \"\r\n (click)=\"emitRequestMove(hint)\"\r\n >\r\n <mat-icon>arrow_forward</mat-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Delete this fragment\"\r\n [disabled]=\"disabled()\"\r\n (click)=\"emitRequestDelete(hint)\"\r\n >\r\n <mat-icon class=\"mat-warn\">delete</mat-icon>\r\n </button>\r\n </td>\r\n }\r\n <td>{{ hint.location }}</td>\r\n <td>{{ hint.description }}</td>\r\n <td>\r\n @if (hint.patchOperation) {\r\n <mat-checkbox\r\n matTooltip=\"Apply this patch\"\r\n [formControl]=\"checks.at(i)\"\r\n >\r\n {{ hint.patchOperation }}\r\n </mat-checkbox>\r\n }\r\n </td>\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n @if (targetLocation()) {\r\n <div>move target: {{ targetLocation() }}</div>\r\n }\r\n <button\r\n type=\"submit\"\r\n mat-flat-button\r\n [disabled]=\"readonly() || disabled() || form.invalid\"\r\n >\r\n apply patches\r\n </button>\r\n</form>\r\n}\r\n", styles: ["table.patches th{font-weight:400;color:#bdbdbd}\n"] }]
457
+ ], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (hints().length) {\r\n<form [formGroup]=\"form\" (submit)=\"emitRequestPatch()\">\r\n <table class=\"patches\">\r\n <thead>\r\n <tr>\r\n <th></th>\r\n <th>location</th>\r\n <th>description</th>\r\n <th>patch</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @for (hint of hints(); track hint; let i = $index) {\r\n <tr>\r\n @if (!readonly()) {\r\n <td>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Edit this fragment\"\r\n [disabled]=\"disabled()\"\r\n >\r\n <mat-icon>edit</mat-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Move this fragment to {{ targetLocation() }}\"\r\n [disabled]=\"\r\n disabled() ||\r\n !targetLocation() ||\r\n targetLocation() === hint.location\r\n \"\r\n (click)=\"emitRequestMove(hint)\"\r\n >\r\n <mat-icon>arrow_forward</mat-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Delete this fragment\"\r\n [disabled]=\"disabled()\"\r\n (click)=\"emitRequestDelete(hint)\"\r\n >\r\n <mat-icon class=\"mat-warn\">delete</mat-icon>\r\n </button>\r\n </td>\r\n }\r\n <td>{{ hint.location }}</td>\r\n <td>{{ hint.description }}</td>\r\n <td>\r\n @if (hint.patchOperation) {\r\n <mat-checkbox\r\n matTooltip=\"Apply this patch\"\r\n [formControl]=\"checks.at(i)\"\r\n >\r\n {{ hint.patchOperation }}\r\n </mat-checkbox>\r\n }\r\n </td>\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n @if (targetLocation()) {\r\n <div>move target: {{ targetLocation() }}</div>\r\n }\r\n <button\r\n type=\"submit\"\r\n mat-flat-button\r\n [disabled]=\"readonly() || disabled() || form.invalid\"\r\n >\r\n apply patches\r\n </button>\r\n</form>\r\n}\r\n", styles: ["table.patches th{font-weight:400;color:#bdbdbd}\n"] }]
441
458
  }], ctorParameters: () => [{ type: i1$1.FormBuilder }, { type: i2.DialogService }], propDecorators: { hints: [{ type: i0.Input, args: [{ isSignal: true, alias: "hints", required: false }] }], targetLocation: [{ type: i0.Input, args: [{ isSignal: true, alias: "targetLocation", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], requestEdit: [{ type: i0.Output, args: ["requestEdit"] }], requestDelete: [{ type: i0.Output, args: ["requestDelete"] }], requestMove: [{ type: i0.Output, args: ["requestMove"] }], requestPatch: [{ type: i0.Output, args: ["requestPatch"] }] } });
442
459
 
443
460
  /**
@@ -458,23 +475,23 @@ class LookupPinComponent {
458
475
  /**
459
476
  * The entry value initially set when the component loads.
460
477
  */
461
- initialValue = input(...(ngDevMode ? [undefined, { debugName: "initialValue" }] : []));
478
+ initialValue = input(...(ngDevMode ? [undefined, { debugName: "initialValue" }] : /* istanbul ignore next */ []));
462
479
  /**
463
480
  * The label to be displayed for this lookup.
464
481
  */
465
- label = input('', ...(ngDevMode ? [{ debugName: "label" }] : []));
482
+ label = input('', ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
466
483
  /**
467
484
  * The maximum count of lookup entries to retrieve.
468
485
  * Default is 10.
469
486
  */
470
- limit = input(10, ...(ngDevMode ? [{ debugName: "limit" }] : []));
487
+ limit = input(10, ...(ngDevMode ? [{ debugName: "limit" }] : /* istanbul ignore next */ []));
471
488
  /**
472
489
  * True to reset the lookup value after it is picked.
473
490
  * This is typically used when you use this component
474
491
  * as a pure lookup device, storing the picked value
475
492
  * elsewhere when handling its entryChange event.
476
493
  */
477
- resetOnPick = input(...(ngDevMode ? [undefined, { debugName: "resetOnPick" }] : []));
494
+ resetOnPick = input(...(ngDevMode ? [undefined, { debugName: "resetOnPick" }] : /* istanbul ignore next */ []));
478
495
  /**
479
496
  * Fired whenever an entry is picked. Usually you should
480
497
  * cast the received argument to a more specific type.
@@ -483,7 +500,7 @@ class LookupPinComponent {
483
500
  form;
484
501
  lookup;
485
502
  entries$;
486
- entry = signal(undefined, ...(ngDevMode ? [{ debugName: "entry" }] : []));
503
+ entry = signal(undefined, ...(ngDevMode ? [{ debugName: "entry" }] : /* istanbul ignore next */ []));
487
504
  constructor(formBuilder, _itemService, _lookupDefs) {
488
505
  this._itemService = _itemService;
489
506
  this._lookupDefs = _lookupDefs;
@@ -503,7 +520,7 @@ class LookupPinComponent {
503
520
  * The lookup key to be used for this component.
504
521
  * This should be a key from the injectable indexLookupDefinitions.
505
522
  */
506
- lookupKey = input(...(ngDevMode ? [undefined, { debugName: "lookupKey" }] : []));
523
+ lookupKey = input(...(ngDevMode ? [undefined, { debugName: "lookupKey" }] : /* istanbul ignore next */ []));
507
524
  ngOnInit() {
508
525
  this.entries$ = this.lookup.valueChanges.pipe(debounceTime(300), distinctUntilChanged(), switchMap((value) => {
509
526
  // if it's a string it's a filter; else it's the entry got
@@ -514,10 +531,6 @@ class LookupPinComponent {
514
531
  return of([value]);
515
532
  }
516
533
  }));
517
- // setup initial value if its name was specified
518
- if (this.initialValue()) {
519
- this.resetToInitial();
520
- }
521
534
  }
522
535
  lookupEntries(filter, limit) {
523
536
  // get the lookup definition
@@ -564,10 +577,10 @@ class LookupPinComponent {
564
577
  this.clear();
565
578
  }
566
579
  }
567
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: LookupPinComponent, deps: [{ token: i1$1.UntypedFormBuilder }, { token: i1$2.ItemService }, { token: 'indexLookupDefinitions' }], target: i0.ɵɵFactoryTarget.Component });
568
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.3", type: LookupPinComponent, isStandalone: true, selector: "cadmus-lookup-pin", inputs: { initialValue: { classPropertyName: "initialValue", publicName: "initialValue", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, limit: { classPropertyName: "limit", publicName: "limit", isSignal: true, isRequired: false, transformFunction: null }, resetOnPick: { classPropertyName: "resetOnPick", publicName: "resetOnPick", isSignal: true, isRequired: false, transformFunction: null }, lookupKey: { classPropertyName: "lookupKey", publicName: "lookupKey", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { entryChange: "entryChange" }, ngImport: i0, template: "<form [formGroup]=\"form\">\r\n <mat-autocomplete #lookupAuto=\"matAutocomplete\" [displayWith]=\"entryToName\">\r\n @for (entry of entries$ | async; track entry) {\r\n <mat-option [value]=\"entry\" (onSelectionChange)=\"pickEntry(entry)\">\r\n {{ entry?.value }}\r\n </mat-option>\r\n }\r\n </mat-autocomplete>\r\n\r\n <mat-form-field>\r\n <input\r\n matInput\r\n type=\"text\"\r\n [placeholder]=\"label()\"\r\n [formControl]=\"lookup\"\r\n [matAutocomplete]=\"lookupAuto\"\r\n />\r\n </mat-form-field>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n (click)=\"clear()\"\r\n [disabled]=\"!entry()\"\r\n matTooltip=\"Clear\"\r\n >\r\n <mat-icon class=\"mat-warn\">clear</mat-icon>\r\n </button>\r\n</form>\r\n", styles: [""], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: MatAutocomplete, selector: "mat-autocomplete", inputs: ["aria-label", "aria-labelledby", "displayWith", "autoActiveFirstOption", "autoSelectActiveOption", "requireSelection", "panelWidth", "disableRipple", "class", "hideSingleSelectionIndicator"], outputs: ["optionSelected", "opened", "closed", "optionActivated"], exportAs: ["matAutocomplete"] }, { kind: "component", type: MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "directive", type: MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", inputs: ["matAutocomplete", "matAutocompletePosition", "matAutocompleteConnectedTo", "autocomplete", "matAutocompleteDisabled"], exportAs: ["matAutocompleteTrigger"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "pipe", type: AsyncPipe, name: "async" }] });
580
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: LookupPinComponent, deps: [{ token: i1$1.UntypedFormBuilder }, { token: i1$2.ItemService }, { token: 'indexLookupDefinitions' }], target: i0.ɵɵFactoryTarget.Component });
581
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: LookupPinComponent, isStandalone: true, selector: "cadmus-lookup-pin", inputs: { initialValue: { classPropertyName: "initialValue", publicName: "initialValue", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, limit: { classPropertyName: "limit", publicName: "limit", isSignal: true, isRequired: false, transformFunction: null }, resetOnPick: { classPropertyName: "resetOnPick", publicName: "resetOnPick", isSignal: true, isRequired: false, transformFunction: null }, lookupKey: { classPropertyName: "lookupKey", publicName: "lookupKey", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { entryChange: "entryChange" }, ngImport: i0, template: "<form [formGroup]=\"form\">\r\n <mat-autocomplete #lookupAuto=\"matAutocomplete\" [displayWith]=\"entryToName\">\r\n @for (entry of entries$ | async; track entry) {\r\n <mat-option [value]=\"entry\" (onSelectionChange)=\"pickEntry(entry)\">\r\n {{ entry?.value }}\r\n </mat-option>\r\n }\r\n </mat-autocomplete>\r\n\r\n <mat-form-field>\r\n <input\r\n matInput\r\n type=\"text\"\r\n [placeholder]=\"label()\"\r\n [formControl]=\"lookup\"\r\n [matAutocomplete]=\"lookupAuto\"\r\n />\r\n </mat-form-field>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n (click)=\"clear()\"\r\n [disabled]=\"!entry()\"\r\n matTooltip=\"Clear\"\r\n >\r\n <mat-icon class=\"mat-warn\">clear</mat-icon>\r\n </button>\r\n</form>\r\n", styles: [""], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: MatAutocomplete, selector: "mat-autocomplete", inputs: ["aria-label", "aria-labelledby", "displayWith", "autoActiveFirstOption", "autoSelectActiveOption", "requireSelection", "panelWidth", "disableRipple", "class", "hideSingleSelectionIndicator"], outputs: ["optionSelected", "opened", "closed", "optionActivated"], exportAs: ["matAutocomplete"] }, { kind: "component", type: MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "directive", type: MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", inputs: ["matAutocomplete", "matAutocompletePosition", "matAutocompleteConnectedTo", "autocomplete", "matAutocompleteDisabled"], exportAs: ["matAutocompleteTrigger"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
569
582
  }
570
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: LookupPinComponent, decorators: [{
583
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: LookupPinComponent, decorators: [{
571
584
  type: Component,
572
585
  args: [{ selector: 'cadmus-lookup-pin', imports: [
573
586
  FormsModule,
@@ -581,7 +594,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
581
594
  MatTooltip,
582
595
  MatIcon,
583
596
  AsyncPipe,
584
- ], template: "<form [formGroup]=\"form\">\r\n <mat-autocomplete #lookupAuto=\"matAutocomplete\" [displayWith]=\"entryToName\">\r\n @for (entry of entries$ | async; track entry) {\r\n <mat-option [value]=\"entry\" (onSelectionChange)=\"pickEntry(entry)\">\r\n {{ entry?.value }}\r\n </mat-option>\r\n }\r\n </mat-autocomplete>\r\n\r\n <mat-form-field>\r\n <input\r\n matInput\r\n type=\"text\"\r\n [placeholder]=\"label()\"\r\n [formControl]=\"lookup\"\r\n [matAutocomplete]=\"lookupAuto\"\r\n />\r\n </mat-form-field>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n (click)=\"clear()\"\r\n [disabled]=\"!entry()\"\r\n matTooltip=\"Clear\"\r\n >\r\n <mat-icon class=\"mat-warn\">clear</mat-icon>\r\n </button>\r\n</form>\r\n" }]
597
+ ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<form [formGroup]=\"form\">\r\n <mat-autocomplete #lookupAuto=\"matAutocomplete\" [displayWith]=\"entryToName\">\r\n @for (entry of entries$ | async; track entry) {\r\n <mat-option [value]=\"entry\" (onSelectionChange)=\"pickEntry(entry)\">\r\n {{ entry?.value }}\r\n </mat-option>\r\n }\r\n </mat-autocomplete>\r\n\r\n <mat-form-field>\r\n <input\r\n matInput\r\n type=\"text\"\r\n [placeholder]=\"label()\"\r\n [formControl]=\"lookup\"\r\n [matAutocomplete]=\"lookupAuto\"\r\n />\r\n </mat-form-field>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n (click)=\"clear()\"\r\n [disabled]=\"!entry()\"\r\n matTooltip=\"Clear\"\r\n >\r\n <mat-icon class=\"mat-warn\">clear</mat-icon>\r\n </button>\r\n</form>\r\n" }]
585
598
  }], ctorParameters: () => [{ type: i1$1.UntypedFormBuilder }, { type: i1$2.ItemService }, { type: undefined, decorators: [{
586
599
  type: Inject,
587
600
  args: ['indexLookupDefinitions']
@@ -633,19 +646,19 @@ class PartBadgeComponent {
633
646
  /**
634
647
  * The badge type: 0=part and role, 1=part only, 2=role only.
635
648
  */
636
- badgeType = input(PartBadgeType.partAndRole, ...(ngDevMode ? [{ debugName: "badgeType" }] : []));
649
+ badgeType = input(PartBadgeType.partAndRole, ...(ngDevMode ? [{ debugName: "badgeType" }] : /* istanbul ignore next */ []));
637
650
  /**
638
651
  * The types thesaurus.
639
652
  */
640
- typeThesaurus = input(...(ngDevMode ? [undefined, { debugName: "typeThesaurus" }] : []));
653
+ typeThesaurus = input(...(ngDevMode ? [undefined, { debugName: "typeThesaurus" }] : /* istanbul ignore next */ []));
641
654
  /**
642
655
  * The part's facet definition.
643
656
  */
644
- facetDefinition = input(...(ngDevMode ? [undefined, { debugName: "facetDefinition" }] : []));
657
+ facetDefinition = input(...(ngDevMode ? [undefined, { debugName: "facetDefinition" }] : /* istanbul ignore next */ []));
645
658
  /**
646
659
  * The part type IDs.
647
660
  */
648
- partTypeIds = input(...(ngDevMode ? [undefined, { debugName: "partTypeIds" }] : []));
661
+ partTypeIds = input(...(ngDevMode ? [undefined, { debugName: "partTypeIds" }] : /* istanbul ignore next */ []));
649
662
  /**
650
663
  * The part type name.
651
664
  */
@@ -656,7 +669,7 @@ class PartBadgeComponent {
656
669
  return undefined;
657
670
  }
658
671
  return getPartIdName(partTypeIds.typeId, partTypeIds.roleId, typeThesaurus);
659
- }, ...(ngDevMode ? [{ debugName: "typeName" }] : []));
672
+ }, ...(ngDevMode ? [{ debugName: "typeName" }] : /* istanbul ignore next */ []));
660
673
  /**
661
674
  * The part role name.
662
675
  */
@@ -667,7 +680,7 @@ class PartBadgeComponent {
667
680
  return undefined;
668
681
  }
669
682
  return this.getRoleIdName(partTypeIds.roleId, typeThesaurus);
670
- }, ...(ngDevMode ? [{ debugName: "roleName" }] : []));
683
+ }, ...(ngDevMode ? [{ debugName: "roleName" }] : /* istanbul ignore next */ []));
671
684
  /**
672
685
  * The part badge color.
673
686
  */
@@ -678,7 +691,7 @@ class PartBadgeComponent {
678
691
  return 'transparent';
679
692
  }
680
693
  return this.getPartColor(partTypeIds.typeId, partTypeIds.roleId, facetDefinition);
681
- }, ...(ngDevMode ? [{ debugName: "color" }] : []));
694
+ }, ...(ngDevMode ? [{ debugName: "color" }] : /* istanbul ignore next */ []));
682
695
  /**
683
696
  * The part definition matching the part type ID and role ID.
684
697
  */
@@ -697,7 +710,7 @@ class PartBadgeComponent {
697
710
  }
698
711
  // Fallback to match by typeId only
699
712
  return facetDefinition.partDefinitions.find((pd) => pd.typeId === partTypeIds.typeId);
700
- }, ...(ngDevMode ? [{ debugName: "partDefinition" }] : []));
713
+ }, ...(ngDevMode ? [{ debugName: "partDefinition" }] : /* istanbul ignore next */ []));
701
714
  constructor(_facetService) {
702
715
  this._facetService = _facetService;
703
716
  }
@@ -731,12 +744,12 @@ class PartBadgeComponent {
731
744
  entry = typeThesaurus.entries?.find((e) => e.id === roleId);
732
745
  return entry ? entry.value : roleId;
733
746
  }
734
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: PartBadgeComponent, deps: [{ token: i1$2.FacetService }], target: i0.ɵɵFactoryTarget.Component });
735
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.3", type: PartBadgeComponent, isStandalone: true, selector: "cadmus-part-badge", inputs: { badgeType: { classPropertyName: "badgeType", publicName: "badgeType", isSignal: true, isRequired: false, transformFunction: null }, typeThesaurus: { classPropertyName: "typeThesaurus", publicName: "typeThesaurus", isSignal: true, isRequired: false, transformFunction: null }, facetDefinition: { classPropertyName: "facetDefinition", publicName: "facetDefinition", isSignal: true, isRequired: false, transformFunction: null }, partTypeIds: { classPropertyName: "partTypeIds", publicName: "partTypeIds", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if (badgeType() !== 2) {\r\n<span\r\n class=\"part-badge\"\r\n [style.background-color]=\"color()\"\r\n [style.color]=\"color() | colorToContrast\"\r\n [matTooltip]=\"partDefinition()?.description\"\r\n>\r\n {{ typeName() }}\r\n</span>\r\n} @if (badgeType() !== 1 && roleName()) {\r\n<span class=\"role-badge\">\r\n {{ roleName() }}\r\n</span>\r\n}\r\n", styles: [".part-badge{padding:4px;border-radius:6px}.role-badge{padding:4px;border:1px solid silver;border-radius:6px}\n"], dependencies: [{ kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "pipe", type: ColorToContrastPipe, name: "colorToContrast" }] });
747
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: PartBadgeComponent, deps: [{ token: i1$2.FacetService }], target: i0.ɵɵFactoryTarget.Component });
748
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: PartBadgeComponent, isStandalone: true, selector: "cadmus-part-badge", inputs: { badgeType: { classPropertyName: "badgeType", publicName: "badgeType", isSignal: true, isRequired: false, transformFunction: null }, typeThesaurus: { classPropertyName: "typeThesaurus", publicName: "typeThesaurus", isSignal: true, isRequired: false, transformFunction: null }, facetDefinition: { classPropertyName: "facetDefinition", publicName: "facetDefinition", isSignal: true, isRequired: false, transformFunction: null }, partTypeIds: { classPropertyName: "partTypeIds", publicName: "partTypeIds", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if (badgeType() !== 2) {\r\n<span\r\n class=\"part-badge\"\r\n [style.background-color]=\"color()\"\r\n [style.color]=\"color() | colorToContrast\"\r\n [matTooltip]=\"partDefinition()?.description\"\r\n>\r\n {{ typeName() }}\r\n</span>\r\n} @if (badgeType() !== 1 && roleName()) {\r\n<span class=\"role-badge\">\r\n {{ roleName() }}\r\n</span>\r\n}\r\n", styles: [".part-badge{padding:4px;border-radius:6px}.role-badge{padding:4px;border:1px solid var(--mat-sys-on-surface-variant);border-radius:6px}\n"], dependencies: [{ kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "pipe", type: ColorToContrastPipe, name: "colorToContrast" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
736
749
  }
737
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: PartBadgeComponent, decorators: [{
750
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: PartBadgeComponent, decorators: [{
738
751
  type: Component,
739
- args: [{ selector: 'cadmus-part-badge', imports: [MatTooltip, ColorToContrastPipe], template: "@if (badgeType() !== 2) {\r\n<span\r\n class=\"part-badge\"\r\n [style.background-color]=\"color()\"\r\n [style.color]=\"color() | colorToContrast\"\r\n [matTooltip]=\"partDefinition()?.description\"\r\n>\r\n {{ typeName() }}\r\n</span>\r\n} @if (badgeType() !== 1 && roleName()) {\r\n<span class=\"role-badge\">\r\n {{ roleName() }}\r\n</span>\r\n}\r\n", styles: [".part-badge{padding:4px;border-radius:6px}.role-badge{padding:4px;border:1px solid silver;border-radius:6px}\n"] }]
752
+ args: [{ selector: 'cadmus-part-badge', imports: [MatTooltip, ColorToContrastPipe], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (badgeType() !== 2) {\r\n<span\r\n class=\"part-badge\"\r\n [style.background-color]=\"color()\"\r\n [style.color]=\"color() | colorToContrast\"\r\n [matTooltip]=\"partDefinition()?.description\"\r\n>\r\n {{ typeName() }}\r\n</span>\r\n} @if (badgeType() !== 1 && roleName()) {\r\n<span class=\"role-badge\">\r\n {{ roleName() }}\r\n</span>\r\n}\r\n", styles: [".part-badge{padding:4px;border-radius:6px}.role-badge{padding:4px;border:1px solid var(--mat-sys-on-surface-variant);border-radius:6px}\n"] }]
740
753
  }], ctorParameters: () => [{ type: i1$2.FacetService }], propDecorators: { badgeType: [{ type: i0.Input, args: [{ isSignal: true, alias: "badgeType", required: false }] }], typeThesaurus: [{ type: i0.Input, args: [{ isSignal: true, alias: "typeThesaurus", required: false }] }], facetDefinition: [{ type: i0.Input, args: [{ isSignal: true, alias: "facetDefinition", required: false }] }], partTypeIds: [{ type: i0.Input, args: [{ isSignal: true, alias: "partTypeIds", required: false }] }] } });
741
754
 
742
755
  /**
@@ -765,21 +778,21 @@ class ModelEditorComponentBase {
765
778
  */
766
779
  userLevel;
767
780
  /**
768
- * An observable with the current dirty state of the editor.
781
+ * A signal with the current dirty state of the editor.
769
782
  */
770
- isDirty$;
783
+ isDirty = signal(false, ...(ngDevMode ? [{ debugName: "isDirty" }] : /* istanbul ignore next */ []));
771
784
  /**
772
785
  * The identity of the edited model.
773
786
  */
774
- identity = input(...(ngDevMode ? [undefined, { debugName: "identity" }] : []));
787
+ identity = input(...(ngDevMode ? [undefined, { debugName: "identity" }] : /* istanbul ignore next */ []));
775
788
  /**
776
789
  * The data being edited.
777
790
  */
778
- data = model(...(ngDevMode ? [undefined, { debugName: "data" }] : []));
791
+ data = model(...(ngDevMode ? [undefined, { debugName: "data" }] : /* istanbul ignore next */ []));
779
792
  /**
780
793
  * True to disable the editor.
781
794
  */
782
- disabled = input(...(ngDevMode ? [undefined, { debugName: "disabled" }] : []));
795
+ disabled = input(...(ngDevMode ? [undefined, { debugName: "disabled" }] : /* istanbul ignore next */ []));
783
796
  /**
784
797
  * Event emitted when the dirty state has changed.
785
798
  * This event just reflects changes in isDirty$, and is a facility
@@ -811,7 +824,7 @@ class ModelEditorComponentBase {
811
824
  }
812
825
  return getPartIdName(identity.typeId, identity.roleId, this._appRepository?.getTypeThesaurus(), true // no fallback so that the part template can use its default name
813
826
  );
814
- }, ...(ngDevMode ? [{ debugName: "modelName" }] : []));
827
+ }, ...(ngDevMode ? [{ debugName: "modelName" }] : /* istanbul ignore next */ []));
815
828
  /**
816
829
  * Create a new instance of the editor.
817
830
  *
@@ -823,7 +836,6 @@ class ModelEditorComponentBase {
823
836
  this.formBuilder = formBuilder;
824
837
  this.form = formBuilder.group({});
825
838
  this.userLevel = 0;
826
- this.isDirty$ = new BehaviorSubject(false);
827
839
  this._appRepository = inject(AppRepository);
828
840
  effect(() => {
829
841
  this.disableForm(this.disabled());
@@ -882,9 +894,8 @@ class ModelEditorComponentBase {
882
894
  // dirty check on form
883
895
  this._mebSubs.push(this.form.events.subscribe((e) => {
884
896
  if (e instanceof PristineChangeEvent) {
885
- console.log('dirty change: ', !e.pristine);
886
- this.isDirty$.next(!e.pristine);
887
- this.dirtyChange.emit(this.isDirty$.value);
897
+ this.isDirty.set(!e.pristine);
898
+ this.dirtyChange.emit(!e.pristine);
888
899
  }
889
900
  }));
890
901
  // auth service
@@ -995,10 +1006,10 @@ class ModelEditorComponentBase {
995
1006
  // the form is no more dirty
996
1007
  this.form.markAsPristine();
997
1008
  }
998
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ModelEditorComponentBase, deps: [{ token: i1$3.AuthJwtService }, { token: i1$1.FormBuilder }], target: i0.ɵɵFactoryTarget.Component });
999
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.3", type: ModelEditorComponentBase, isStandalone: false, selector: "ng-component", inputs: { identity: { classPropertyName: "identity", publicName: "identity", isSignal: true, isRequired: false, transformFunction: null }, data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { data: "dataChange", dirtyChange: "dirtyChange", editorClose: "editorClose" }, ngImport: i0, template: '', isInline: true });
1009
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: ModelEditorComponentBase, deps: [{ token: i1$3.AuthJwtService }, { token: i1$1.FormBuilder }], target: i0.ɵɵFactoryTarget.Component });
1010
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.4", type: ModelEditorComponentBase, isStandalone: false, selector: "ng-component", inputs: { identity: { classPropertyName: "identity", publicName: "identity", isSignal: true, isRequired: false, transformFunction: null }, data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { data: "dataChange", dirtyChange: "dirtyChange", editorClose: "editorClose" }, ngImport: i0, template: '', isInline: true });
1000
1011
  }
1001
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ModelEditorComponentBase, decorators: [{
1012
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: ModelEditorComponentBase, decorators: [{
1002
1013
  type: Component,
1003
1014
  args: [{
1004
1015
  template: '',
@@ -1086,10 +1097,10 @@ class UserRefLookupService {
1086
1097
  getName(item) {
1087
1098
  return item?.user?.userName;
1088
1099
  }
1089
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: UserRefLookupService, deps: [{ token: i1$2.UserService }], target: i0.ɵɵFactoryTarget.Injectable });
1090
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: UserRefLookupService, providedIn: 'root' });
1100
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: UserRefLookupService, deps: [{ token: i1$2.UserService }], target: i0.ɵɵFactoryTarget.Injectable });
1101
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: UserRefLookupService, providedIn: 'root' });
1091
1102
  }
1092
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: UserRefLookupService, decorators: [{
1103
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: UserRefLookupService, decorators: [{
1093
1104
  type: Injectable,
1094
1105
  args: [{
1095
1106
  providedIn: 'root',
@@ -1 +1 @@
1
- {"version":3,"file":"myrmidon-cadmus-ui.mjs","sources":["../../../../projects/myrmidon/cadmus-ui/src/lib/components/close-save-buttons/close-save-buttons.component.ts","../../../../projects/myrmidon/cadmus-ui/src/lib/components/close-save-buttons/close-save-buttons.component.html","../../../../projects/myrmidon/cadmus-ui/src/lib/components/decorated-token-text/decorated-token-text.component.ts","../../../../projects/myrmidon/cadmus-ui/src/lib/components/decorated-token-text/decorated-token-text.component.html","../../../../projects/myrmidon/cadmus-ui/src/lib/components/error-list/error-list.component.ts","../../../../projects/myrmidon/cadmus-ui/src/lib/components/error-list/error-list.component.html","../../../../projects/myrmidon/cadmus-ui/src/lib/services/color.service.ts","../../../../projects/myrmidon/cadmus-ui/src/lib/components/facet-badge/facet-badge.component.ts","../../../../projects/myrmidon/cadmus-ui/src/lib/components/facet-badge/facet-badge.component.html","../../../../projects/myrmidon/cadmus-ui/src/lib/components/flags-badge/flags-badge.component.ts","../../../../projects/myrmidon/cadmus-ui/src/lib/components/flags-badge/flags-badge.component.html","../../../../projects/myrmidon/cadmus-ui/src/lib/components/layer-hints/layer-hints.component.ts","../../../../projects/myrmidon/cadmus-ui/src/lib/components/layer-hints/layer-hints.component.html","../../../../projects/myrmidon/cadmus-ui/src/lib/components/lookup-pin/lookup-pin.component.ts","../../../../projects/myrmidon/cadmus-ui/src/lib/components/lookup-pin/lookup-pin.component.html","../../../../projects/myrmidon/cadmus-ui/src/lib/components/part-badge/part-badge.component.ts","../../../../projects/myrmidon/cadmus-ui/src/lib/components/part-badge/part-badge.component.html","../../../../projects/myrmidon/cadmus-ui/src/lib/components/model-editor-component-base.ts","../../../../projects/myrmidon/cadmus-ui/src/lib/validators/custom-validators.ts","../../../../projects/myrmidon/cadmus-ui/src/lib/validators/json-validators.ts","../../../../projects/myrmidon/cadmus-ui/src/lib/services/user-ref-lookup.service.ts","../../../../projects/myrmidon/cadmus-ui/src/lib/utils.ts","../../../../projects/myrmidon/cadmus-ui/src/public-api.ts","../../../../projects/myrmidon/cadmus-ui/src/myrmidon-cadmus-ui.ts"],"sourcesContent":["import { Component, input, output } from '@angular/core';\r\nimport { FormGroup, UntypedFormGroup } from '@angular/forms';\r\n\r\nimport { MatButton } from '@angular/material/button';\r\nimport { MatIcon } from '@angular/material/icon';\r\n\r\n@Component({\r\n selector: 'cadmus-close-save-buttons',\r\n templateUrl: './close-save-buttons.component.html',\r\n styleUrls: ['./close-save-buttons.component.css'],\r\n imports: [MatButton, MatIcon],\r\n})\r\nexport class CloseSaveButtonsComponent {\r\n public readonly form = input<FormGroup | UntypedFormGroup>();\r\n\r\n public readonly noSave = input<boolean>();\r\n\r\n public readonly closeRequest = output();\r\n\r\n public close(): void {\r\n this.closeRequest.emit();\r\n }\r\n}\r\n","@if (form()) {\n<div class=\"form-row\">\n <button type=\"button\" mat-flat-button class=\"mat-warn\" (click)=\"close()\">\n <mat-icon>cancel</mat-icon>\n close\n </button>\n @if (!noSave()) {\n <button\n type=\"submit\"\n [disabled]=\"form()?.invalid\"\n mat-flat-button\n class=\"mat-primary\"\n >\n <mat-icon>check_circle</mat-icon>\n save\n </button>\n }\n</div>\n}\n","import {\r\n Component,\r\n OnInit,\r\n ViewChild,\r\n ElementRef,\r\n input,\r\n effect,\r\n signal,\r\n} from '@angular/core';\r\n\r\nimport { SafeHtmlPipe } from '@myrmidon/ngx-tools';\r\n\r\nimport { TokenLocation, TextLayerService } from '@myrmidon/cadmus-core';\r\n\r\n/**\r\n * Decorated token-based text visualizer. This is used when editing\r\n * token-based text layers.\r\n */\r\n@Component({\r\n selector: 'cadmus-decorated-token-text',\r\n templateUrl: './decorated-token-text.component.html',\r\n styleUrls: ['./decorated-token-text.component.css'],\r\n imports: [SafeHtmlPipe],\r\n})\r\nexport class DecoratedTokenTextComponent implements OnInit {\r\n @ViewChild('textElem') _textElement?: ElementRef;\r\n\r\n /**\r\n * The base text.\r\n */\r\n public readonly baseText = input<string>('');\r\n\r\n /**\r\n * The token-based locations of all the fragments in the layer.\r\n */\r\n public readonly locations = input<TokenLocation[]>([]);\r\n\r\n /**\r\n * A selected token-based location.\r\n */\r\n public readonly selectedLocation = input<TokenLocation>();\r\n\r\n public readonly text = signal<string | undefined>(undefined); // rendered HTML text\r\n\r\n constructor(private _textLayerService: TextLayerService) {\r\n effect(() => {\r\n this.decorate(this.baseText(), this.locations(), this.selectedLocation());\r\n });\r\n }\r\n\r\n public ngOnInit(): void {\r\n this.decorate(this.baseText(), this.locations(), this.selectedLocation());\r\n }\r\n\r\n private decorate(\r\n text: string,\r\n locations: TokenLocation[],\r\n selectedLocation?: TokenLocation\r\n ): void {\r\n this.text.set(\r\n this._textLayerService.render(text, locations, selectedLocation)\r\n );\r\n }\r\n}\r\n","<div [innerHtml]=\"text() | safeHtml : 'html'\" id=\"text\" #textElem></div>\r\n","import { Component, input } from '@angular/core';\r\n\r\n@Component({\r\n selector: 'cadmus-error-list',\r\n templateUrl: './error-list.component.html',\r\n styleUrls: ['./error-list.component.css'],\r\n})\r\nexport class ErrorListComponent {\r\n public readonly errors = input<string[]>();\r\n}\r\n","@if (errors()?.length) {\n <ul>\n @for (error of errors(); track error) {\n <li class=\"error\">{{error}}</li>\n }\n </ul>\n}\n","import { Injectable } from '@angular/core';\r\n\r\n/**\r\n * Colors helper service.\r\n */\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class ColorService {\r\n /**\r\n * Get the R,G,B components of the color expressed by the specified\r\n * RGB string (3 or 6 digits format).\r\n *\r\n * @param rgb The RGB color string (3 or 6 digits).\r\n * @returns An array where [0]=R, [1]=G, [2]=B, or null if invalid\r\n * input string.\r\n */\r\n public getRgb(rgb: string): number[] | null {\r\n if (!rgb) {\r\n return null;\r\n }\r\n\r\n // RGB\r\n let m = rgb.match(/^#?([0-9a-f]{3})$/i);\r\n if (m && m[1]) {\r\n // in 3-characters format, each value is multiplied by 0x11 to give an\r\n // even scale from 0x00 to 0xff\r\n return [\r\n parseInt(m[1].charAt(0), 16) * 0x11,\r\n parseInt(m[1].charAt(1), 16) * 0x11,\r\n parseInt(m[1].charAt(2), 16) * 0x11,\r\n ];\r\n }\r\n // RRGGBB\r\n m = rgb.match(/^#?([0-9a-f]{6})$/i);\r\n if (m && m[1]) {\r\n return [\r\n parseInt(m[1].substring(0, 2), 16),\r\n parseInt(m[1].substring(2, 4), 16),\r\n parseInt(m[1].substring(4, 6), 16),\r\n ];\r\n }\r\n return null;\r\n }\r\n\r\n /**\r\n * Get black or white according to which of them has the maximum contrast\r\n * against the specified color.\r\n *\r\n * @param rgb The RGB color string.\r\n * @returns Black or white. If rgb is invalid, always black.\r\n */\r\n public getContrastColor(rgb: string): string {\r\n // https://stackoverflow.com/questions/3942878/how-to-decide-font-color-in-white-or-black-depending-on-background-color\r\n const values = this.getRgb(rgb);\r\n if (!values) {\r\n return 'black';\r\n }\r\n return values[0] * 0.299 + values[1] * 0.587 + values[2] * 0.114 > 186\r\n ? 'black'\r\n : 'white';\r\n }\r\n\r\n /**\r\n * Convert HSL to RGB.\r\n *\r\n * @param h Hue\r\n * @param s Saturation\r\n * @param l Lightness\r\n * @returns Object with r, g, b values.\r\n */\r\n public hslToRgb(\r\n h: number,\r\n s: number,\r\n l: number\r\n ): { r: number; g: number; b: number } {\r\n // https://css-tricks.com/converting-color-spaces-in-javascript/\r\n // must be fractions of 1\r\n s /= 100;\r\n l /= 100;\r\n\r\n let c = (1 - Math.abs(2 * l - 1)) * s,\r\n x = c * (1 - Math.abs(((h / 60) % 2) - 1)),\r\n m = l - c / 2,\r\n r = 0,\r\n g = 0,\r\n b = 0;\r\n if (0 <= h && h < 60) {\r\n r = c;\r\n g = x;\r\n b = 0;\r\n } else if (60 <= h && h < 120) {\r\n r = x;\r\n g = c;\r\n b = 0;\r\n } else if (120 <= h && h < 180) {\r\n r = 0;\r\n g = c;\r\n b = x;\r\n } else if (180 <= h && h < 240) {\r\n r = 0;\r\n g = x;\r\n b = c;\r\n } else if (240 <= h && h < 300) {\r\n r = x;\r\n g = 0;\r\n b = c;\r\n } else if (300 <= h && h < 360) {\r\n r = c;\r\n g = 0;\r\n b = x;\r\n }\r\n r = Math.round((r + m) * 255);\r\n g = Math.round((g + m) * 255);\r\n b = Math.round((b + m) * 255);\r\n\r\n return { r: r, g: g, b: b };\r\n }\r\n\r\n public rgbToString(r: number, g: number, b: number): string {\r\n let rd = r.toString(16);\r\n if (rd.length === 1) {\r\n rd = '0' + rd;\r\n }\r\n let gd = g.toString(16);\r\n if (gd.length === 1) {\r\n gd = '0' + gd;\r\n }\r\n let bd = b.toString(16);\r\n if (bd.length === 1) {\r\n bd = '0' + bd;\r\n }\r\n return rd + gd + bd;\r\n }\r\n\r\n /**\r\n * Get the next color from a palette generated to include\r\n * the specified count of colors.\r\n *\r\n * @param index The index of the next color in the palette.\r\n * @param count The total count of colors in the palette.\r\n * @param blueBoost True to adjust colors for the eye's lack of sensitivity to blue.\r\n * @returns The RRGGBB values string.\r\n */\r\n public nextPaletteColor(\r\n index: number,\r\n count: number,\r\n blueBoost = true\r\n ): string {\r\n // https://stackoverflow.com/questions/43193341/how-to-generate-random-pastel-or-brighter-color-in-javascript\r\n const h = Math.floor((index / count) * 341); // between 0 and 340\r\n let s = 100;\r\n let l = 50;\r\n\r\n if (blueBoost && h > 215 && h < 265) {\r\n const gain = 20;\r\n let blueness = 1 - Math.abs(h - 240) / 25;\r\n let change = Math.floor(gain * blueness);\r\n l += change;\r\n s -= change;\r\n }\r\n const rgb = this.hslToRgb(h, s, l);\r\n return this.rgbToString(rgb.r, rgb.g, rgb.b);\r\n }\r\n}\r\n","import { Component, effect, input, Input, signal } from '@angular/core';\r\nimport { FacetDefinition } from '@myrmidon/cadmus-core';\r\n\r\nimport { MatTooltip } from '@angular/material/tooltip';\r\n\r\nimport { ColorService } from '../../services/color.service';\r\n\r\nexport interface FacetBadgeData {\r\n definitions: FacetDefinition[];\r\n facetId?: string;\r\n}\r\n\r\n@Component({\r\n selector: 'cadmus-facet-badge',\r\n templateUrl: './facet-badge.component.html',\r\n styleUrls: ['./facet-badge.component.css'],\r\n imports: [MatTooltip],\r\n})\r\nexport class FacetBadgeComponent {\r\n private _facetColors: { [key: string]: string };\r\n private _facetTips: { [key: string]: string };\r\n\r\n public readonly color = signal<string>('transparent');\r\n public readonly contrastColor = signal<string>('black');\r\n public readonly tip = signal<string | undefined>(undefined);\r\n\r\n /**\r\n * The facet data.\r\n */\r\n public readonly data = input<FacetBadgeData>({\r\n definitions: [],\r\n });\r\n\r\n constructor(private _colorService: ColorService) {\r\n this._facetColors = {};\r\n this._facetTips = {};\r\n\r\n effect(() => {\r\n this.updateBadge(this.data());\r\n });\r\n }\r\n\r\n private getFacetColor(facetId: string): string {\r\n if (this._facetColors[facetId]) {\r\n return this._facetColors[facetId];\r\n }\r\n if (!this.data().definitions?.length) {\r\n return 'transparent';\r\n }\r\n\r\n const facet = this.data().definitions.find((f) => {\r\n return f.id === facetId;\r\n });\r\n if (facet?.colorKey) {\r\n this._facetColors[facetId] = '#' + facet.colorKey;\r\n } else {\r\n this._facetColors[facetId] = 'transparent';\r\n }\r\n return this._facetColors[facetId];\r\n }\r\n\r\n private getFacetTip(facetId: string): string | null {\r\n if (this._facetTips[facetId]) {\r\n return this._facetTips[facetId];\r\n }\r\n\r\n if (!this.data().definitions?.length) {\r\n return null;\r\n }\r\n\r\n const facet = this.data().definitions.find((f) => {\r\n return f.id === facetId;\r\n });\r\n if (!facet) {\r\n this._facetTips[facetId] = facetId;\r\n } else {\r\n const sb: string[] = [];\r\n for (let i = 0; i < facet.partDefinitions.length; i++) {\r\n if (i > 0) {\r\n sb.push(', ');\r\n }\r\n sb.push(facet.partDefinitions[i].name);\r\n if (facet.partDefinitions[i].isRequired) {\r\n sb.push('*');\r\n }\r\n }\r\n this._facetTips[facetId] = sb.join('');\r\n }\r\n return this._facetTips[facetId];\r\n }\r\n\r\n private updateBadge(data?: FacetBadgeData) {\r\n this._facetColors = {};\r\n this._facetTips = {};\r\n this.color.set(this.getFacetColor(data?.facetId || ''));\r\n this.contrastColor.set(this._colorService.getContrastColor(this.color()));\r\n this.tip.set(this.getFacetTip(data?.facetId || '') ?? undefined);\r\n }\r\n}\r\n","<span\r\n class=\"model-type\"\r\n [style.background-color]=\"color()\"\r\n [style.color]=\"contrastColor()\"\r\n matTooltip=\"{{ tip() }}\"\r\n >{{ data().facetId }}\r\n</span>\r\n","import { Component, effect, input, Input, signal } from '@angular/core';\r\n\r\nimport { MatTooltip } from '@angular/material/tooltip';\r\n\r\nimport { FlagDefinition } from '@myrmidon/cadmus-core';\r\n\r\n/**\r\n * Data for FlagsBadgeComponent, including flags and their definitions.\r\n */\r\nexport interface FlagsBadgeData {\r\n definitions: FlagDefinition[];\r\n flags: number;\r\n}\r\n\r\n/**\r\n * Badge with item's flags. Each flag is represented by a circle filled\r\n * with the flag's color key.\r\n */\r\n@Component({\r\n selector: 'cadmus-flags-badge',\r\n templateUrl: './flags-badge.component.html',\r\n styleUrls: ['./flags-badge.component.css'],\r\n imports: [MatTooltip],\r\n})\r\nexport class FlagsBadgeComponent {\r\n public readonly data = input<FlagsBadgeData>();\r\n\r\n public readonly badgeFlags = signal<FlagDefinition[]>([]);\r\n\r\n constructor() {\r\n effect(() => {\r\n this.updateBadge(this.data());\r\n });\r\n }\r\n\r\n private updateBadge(data?: FlagsBadgeData) {\r\n if (!data) {\r\n return;\r\n }\r\n this.badgeFlags.set(\r\n data.definitions.filter((def) => {\r\n // tslint:disable-next-line: no-bitwise\r\n return def.id & data!.flags;\r\n })\r\n );\r\n }\r\n}\r\n","<div>\r\n @for (def of badgeFlags(); track def.id) {\r\n <span\r\n class=\"badge-flag\"\r\n [style.color]=\"'#' + def.colorKey\"\r\n [matTooltip]=\"def.label\"\r\n >\r\n @if (def.isAdmin) { &#x25c6; } @else { &#x2b24; }\r\n </span>\r\n }\r\n</div>\r\n","import { Component, output, input, effect } from '@angular/core';\r\nimport {\r\n FormGroup,\r\n FormArray,\r\n FormBuilder,\r\n FormsModule,\r\n ReactiveFormsModule,\r\n FormControl,\r\n} from '@angular/forms';\r\n\r\nimport { MatIconButton, MatButton } from '@angular/material/button';\r\nimport { MatTooltip } from '@angular/material/tooltip';\r\nimport { MatIcon } from '@angular/material/icon';\r\nimport { MatCheckbox } from '@angular/material/checkbox';\r\n\r\nimport { DialogService } from '@myrmidon/ngx-mat-tools';\r\n\r\nimport { LayerHint } from '@myrmidon/cadmus-core';\r\n\r\n@Component({\r\n selector: 'cadmus-layer-hints',\r\n templateUrl: './layer-hints.component.html',\r\n styleUrls: ['./layer-hints.component.css'],\r\n imports: [\r\n FormsModule,\r\n ReactiveFormsModule,\r\n MatIconButton,\r\n MatTooltip,\r\n MatIcon,\r\n MatCheckbox,\r\n MatButton,\r\n ],\r\n})\r\nexport class LayerHintsComponent {\r\n public readonly hints = input<LayerHint[]>([]);\r\n\r\n public readonly targetLocation = input<string>();\r\n public readonly disabled = input<boolean>();\r\n public readonly readonly = input<boolean>();\r\n\r\n public readonly requestEdit = output<LayerHint>();\r\n public readonly requestDelete = output<LayerHint>();\r\n public readonly requestMove = output<LayerHint>();\r\n public readonly requestPatch = output<string[]>();\r\n\r\n public form: FormGroup;\r\n public checks: FormArray<FormControl<boolean>>;\r\n\r\n constructor(\r\n private _formBuilder: FormBuilder,\r\n private _dialogService: DialogService\r\n ) {\r\n this.checks = _formBuilder.array<FormControl<boolean>>([]);\r\n this.form = _formBuilder.group({\r\n checks: this.checks,\r\n });\r\n\r\n effect(() => {\r\n this.updateChecks(this.hints());\r\n });\r\n }\r\n\r\n private updateChecks(hints: LayerHint[]) {\r\n this.checks.clear();\r\n for (let i = 0; i < hints.length; i++) {\r\n this.checks.push(this._formBuilder.control(false, { nonNullable: true }));\r\n }\r\n }\r\n\r\n public emitRequestEdit(hint: LayerHint) {\r\n this.requestEdit.emit(hint);\r\n }\r\n\r\n public emitRequestDelete(hint: LayerHint) {\r\n this._dialogService\r\n .confirm('Confirm Deletion', `Delete fragment at \"${hint.location}\"?`)\r\n .subscribe((ok: boolean) => {\r\n if (ok) {\r\n this.requestDelete.emit(hint);\r\n }\r\n });\r\n }\r\n\r\n public emitRequestMove(hint: LayerHint) {\r\n if (!this.targetLocation) {\r\n return;\r\n }\r\n this._dialogService\r\n .confirm(\r\n 'Confirm Move',\r\n `Move fragment at ${hint.location} to ${this.targetLocation}?`\r\n )\r\n .subscribe((ok: boolean) => {\r\n if (ok) {\r\n this.requestMove.emit(hint);\r\n }\r\n });\r\n }\r\n\r\n public emitRequestPatch() {\r\n if (this.form.invalid) {\r\n return;\r\n }\r\n this._dialogService\r\n .confirm('Confirm Patch', `Patch the selected fragments?`)\r\n .subscribe((ok: boolean) => {\r\n if (ok) {\r\n const patches: string[] = [];\r\n for (let i = 0; i < this.checks.length; i++) {\r\n if (this.checks.at(i).value) {\r\n patches.push(this.hints()[i].patchOperation!);\r\n }\r\n }\r\n this.requestPatch.emit(patches);\r\n }\r\n });\r\n }\r\n}\r\n","@if (hints().length) {\r\n<form [formGroup]=\"form\" (submit)=\"emitRequestPatch()\">\r\n <table class=\"patches\">\r\n <thead>\r\n <tr>\r\n <th></th>\r\n <th>location</th>\r\n <th>description</th>\r\n <th>patch</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @for (hint of hints(); track hint; let i = $index) {\r\n <tr>\r\n @if (!readonly()) {\r\n <td>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Edit this fragment\"\r\n [disabled]=\"disabled()\"\r\n >\r\n <mat-icon>edit</mat-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Move this fragment to {{ targetLocation() }}\"\r\n [disabled]=\"\r\n disabled() ||\r\n !targetLocation() ||\r\n targetLocation() === hint.location\r\n \"\r\n (click)=\"emitRequestMove(hint)\"\r\n >\r\n <mat-icon>arrow_forward</mat-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Delete this fragment\"\r\n [disabled]=\"disabled()\"\r\n (click)=\"emitRequestDelete(hint)\"\r\n >\r\n <mat-icon class=\"mat-warn\">delete</mat-icon>\r\n </button>\r\n </td>\r\n }\r\n <td>{{ hint.location }}</td>\r\n <td>{{ hint.description }}</td>\r\n <td>\r\n @if (hint.patchOperation) {\r\n <mat-checkbox\r\n matTooltip=\"Apply this patch\"\r\n [formControl]=\"checks.at(i)\"\r\n >\r\n {{ hint.patchOperation }}\r\n </mat-checkbox>\r\n }\r\n </td>\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n @if (targetLocation()) {\r\n <div>move target: {{ targetLocation() }}</div>\r\n }\r\n <button\r\n type=\"submit\"\r\n mat-flat-button\r\n [disabled]=\"readonly() || disabled() || form.invalid\"\r\n >\r\n apply patches\r\n </button>\r\n</form>\r\n}\r\n","import {\r\n Component,\r\n effect,\r\n Inject,\r\n input,\r\n OnInit,\r\n output,\r\n signal,\r\n} from '@angular/core';\r\nimport { AsyncPipe } from '@angular/common';\r\nimport {\r\n UntypedFormBuilder,\r\n UntypedFormControl,\r\n UntypedFormGroup,\r\n FormsModule,\r\n ReactiveFormsModule,\r\n} from '@angular/forms';\r\nimport { Observable, of } from 'rxjs';\r\nimport {\r\n debounceTime,\r\n distinctUntilChanged,\r\n map,\r\n switchMap,\r\n take,\r\n} from 'rxjs/operators';\r\n\r\nimport {\r\n MatAutocomplete,\r\n MatAutocompleteTrigger,\r\n} from '@angular/material/autocomplete';\r\nimport { MatOption } from '@angular/material/core';\r\nimport { MatFormField } from '@angular/material/form-field';\r\nimport { MatInput } from '@angular/material/input';\r\nimport { MatIconButton } from '@angular/material/button';\r\nimport { MatTooltip } from '@angular/material/tooltip';\r\nimport { MatIcon } from '@angular/material/icon';\r\n\r\nimport { DataPage, ErrorWrapper } from '@myrmidon/ngx-tools';\r\n\r\nimport { DataPinInfo, IndexLookupDefinitions } from '@myrmidon/cadmus-core';\r\nimport { ItemService } from '@myrmidon/cadmus-api';\r\n\r\n/**\r\n * Generic data pin lookup component. This allows users typing a part\r\n * of a pin's value, and get the full pin. For instance, if you have\r\n * a lookup set of colors and type \"gr\", you might get the pins\r\n * corresponding to \"green\" (e.g. id=color, value=green), \"gray\", etc.\r\n * Usage: add a FormControl to hold a DataPinInfo value; in the HTML\r\n * template set the component's lookupKey, label, initialValue, and\r\n * entryChange handler. The initialValue, if any, should be the initial\r\n * DataPinInfo value.\r\n * If you are using this component as a pure lookup device, don't set\r\n * the initialValue and set resetOnPick=true.\r\n */\r\n@Component({\r\n selector: 'cadmus-lookup-pin',\r\n templateUrl: './lookup-pin.component.html',\r\n styleUrls: ['./lookup-pin.component.css'],\r\n imports: [\r\n FormsModule,\r\n ReactiveFormsModule,\r\n MatAutocomplete,\r\n MatOption,\r\n MatFormField,\r\n MatInput,\r\n MatAutocompleteTrigger,\r\n MatIconButton,\r\n MatTooltip,\r\n MatIcon,\r\n AsyncPipe,\r\n ],\r\n})\r\nexport class LookupPinComponent implements OnInit {\r\n /**\r\n * The entry value initially set when the component loads.\r\n */\r\n public readonly initialValue = input<string>();\r\n\r\n /**\r\n * The label to be displayed for this lookup.\r\n */\r\n public readonly label = input<string>('');\r\n\r\n /**\r\n * The maximum count of lookup entries to retrieve.\r\n * Default is 10.\r\n */\r\n public readonly limit = input<number>(10);\r\n\r\n /**\r\n * True to reset the lookup value after it is picked.\r\n * This is typically used when you use this component\r\n * as a pure lookup device, storing the picked value\r\n * elsewhere when handling its entryChange event.\r\n */\r\n public readonly resetOnPick = input<boolean>();\r\n\r\n /**\r\n * Fired whenever an entry is picked. Usually you should\r\n * cast the received argument to a more specific type.\r\n */\r\n public readonly entryChange = output<DataPinInfo | null>();\r\n\r\n public form: UntypedFormGroup;\r\n public lookup: UntypedFormControl;\r\n public entries$: Observable<DataPinInfo[]> | undefined;\r\n\r\n public readonly entry = signal<DataPinInfo | undefined>(undefined);\r\n\r\n constructor(\r\n formBuilder: UntypedFormBuilder,\r\n private _itemService: ItemService,\r\n @Inject('indexLookupDefinitions')\r\n private _lookupDefs: IndexLookupDefinitions\r\n ) {\r\n // form\r\n this.lookup = formBuilder.control(null);\r\n this.form = formBuilder.group({\r\n lookup: this.lookup,\r\n });\r\n\r\n effect(() => {\r\n console.log('lookup pin initial value', this.initialValue());\r\n if (this.lookup) {\r\n this.resetToInitial();\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * The lookup key to be used for this component.\r\n * This should be a key from the injectable indexLookupDefinitions.\r\n */\r\n public readonly lookupKey = input<string>();\r\n\r\n public ngOnInit(): void {\r\n this.entries$ = this.lookup.valueChanges.pipe(\r\n debounceTime(300),\r\n distinctUntilChanged(),\r\n switchMap((value: DataPinInfo | string) => {\r\n // if it's a string it's a filter; else it's the entry got\r\n if (typeof value === 'string') {\r\n return this.lookupEntries(value, this.limit());\r\n } else {\r\n return of([value]);\r\n }\r\n })\r\n );\r\n // setup initial value if its name was specified\r\n if (this.initialValue()) {\r\n this.resetToInitial();\r\n }\r\n }\r\n\r\n private lookupEntries(\r\n filter: string,\r\n limit: number\r\n ): Observable<DataPinInfo[]> {\r\n // get the lookup definition\r\n if (!this.lookupKey() || !filter) {\r\n return of([]);\r\n }\r\n const ld = this._lookupDefs[this.lookupKey()!];\r\n if (!ld) {\r\n return of([]);\r\n }\r\n\r\n // build query\r\n const query = ld.roleId\r\n ? `[partTypeId=${ld.typeId}] AND [roleId=${ld.roleId}] AND [name=${ld.name}] AND [value^=${filter}]`\r\n : `[partTypeId=${ld.typeId}] AND [name=${ld.name}] AND [value^=${filter}]`;\r\n\r\n // search\r\n return this._itemService.searchPins(query, 1, limit).pipe(\r\n map((w: ErrorWrapper<DataPage<DataPinInfo>>) => {\r\n if (w.error) {\r\n return [];\r\n } else {\r\n return w.value?.items || [];\r\n }\r\n })\r\n );\r\n }\r\n\r\n private resetToInitial(): void {\r\n this.lookupEntries(this.initialValue() || '', 1)\r\n .pipe(take(1))\r\n .subscribe((entries) => {\r\n this.lookup.setValue(entries.length ? entries[0] : undefined);\r\n });\r\n }\r\n\r\n public clear(): void {\r\n this.entry.set(undefined);\r\n this.lookup.setValue(null);\r\n this.entryChange.emit(null);\r\n }\r\n\r\n public entryToName(entry: DataPinInfo): string {\r\n return entry?.value;\r\n }\r\n\r\n public pickEntry(entry: DataPinInfo): void {\r\n this.entry.set(entry);\r\n this.entryChange.emit(entry);\r\n if (this.resetOnPick()) {\r\n this.clear();\r\n }\r\n }\r\n}\r\n","<form [formGroup]=\"form\">\r\n <mat-autocomplete #lookupAuto=\"matAutocomplete\" [displayWith]=\"entryToName\">\r\n @for (entry of entries$ | async; track entry) {\r\n <mat-option [value]=\"entry\" (onSelectionChange)=\"pickEntry(entry)\">\r\n {{ entry?.value }}\r\n </mat-option>\r\n }\r\n </mat-autocomplete>\r\n\r\n <mat-form-field>\r\n <input\r\n matInput\r\n type=\"text\"\r\n [placeholder]=\"label()\"\r\n [formControl]=\"lookup\"\r\n [matAutocomplete]=\"lookupAuto\"\r\n />\r\n </mat-form-field>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n (click)=\"clear()\"\r\n [disabled]=\"!entry()\"\r\n matTooltip=\"Clear\"\r\n >\r\n <mat-icon class=\"mat-warn\">clear</mat-icon>\r\n </button>\r\n</form>\r\n","import { Component, input, computed } from '@angular/core';\r\n\r\nimport {\r\n Thesaurus,\r\n FacetDefinition,\r\n PartTypeIds,\r\n ThesaurusEntry,\r\n} from '@myrmidon/cadmus-core';\r\nimport { FacetService } from '@myrmidon/cadmus-api';\r\nimport { MatTooltip } from '@angular/material/tooltip';\r\n\r\nimport { ColorToContrastPipe } from '@myrmidon/ngx-tools';\r\n\r\nexport enum PartBadgeType {\r\n partAndRole = 0,\r\n partOnly = 1,\r\n roleOnly = 2,\r\n}\r\n\r\n/**\r\n * Function used to get the part's human-friendly name from its ID and role ID.\r\n * This assumes that thesaurus entries with role ID specified have form\r\n * partId:roleId.\r\n * @param typeId The part type ID.\r\n * @param roleId The optional role ID.\r\n * @param typeThesaurus The types thesaurus.\r\n * @param noFallback If true, and no thesaurus is provided, return undefined\r\n * rather than the type and role IDs.\r\n * @returns The name.\r\n */\r\nexport function getPartIdName(\r\n typeId: string,\r\n roleId?: string | null,\r\n typeThesaurus?: Thesaurus,\r\n noFallback = false\r\n): string | undefined {\r\n if (!typeThesaurus) {\r\n if (noFallback) {\r\n return undefined;\r\n }\r\n return roleId ? `${typeId} ${roleId}` : typeId;\r\n }\r\n let entry: ThesaurusEntry | undefined;\r\n\r\n // first find partId:roleId if any\r\n if (roleId) {\r\n const suffixedId = `${typeId}:${roleId}`;\r\n entry = typeThesaurus.entries?.find((e) => e.id === suffixedId);\r\n if (entry) {\r\n return entry.value;\r\n }\r\n }\r\n // else find partId alone\r\n entry = typeThesaurus.entries?.find((e) => e.id === typeId);\r\n\r\n return entry ? entry.value : typeId;\r\n}\r\n\r\n/**\r\n * Part badge component. This component displays a badge with the\r\n * part's type name and role name, if any, and a background color.\r\n */\r\n@Component({\r\n selector: 'cadmus-part-badge',\r\n imports: [MatTooltip, ColorToContrastPipe],\r\n templateUrl: './part-badge.component.html',\r\n styleUrls: ['./part-badge.component.css'],\r\n})\r\nexport class PartBadgeComponent {\r\n /**\r\n * The badge type: 0=part and role, 1=part only, 2=role only.\r\n */\r\n public readonly badgeType = input<PartBadgeType>(PartBadgeType.partAndRole);\r\n\r\n /**\r\n * The types thesaurus.\r\n */\r\n public readonly typeThesaurus = input<Thesaurus>();\r\n\r\n /**\r\n * The part's facet definition.\r\n */\r\n public readonly facetDefinition = input<FacetDefinition>();\r\n\r\n /**\r\n * The part type IDs.\r\n */\r\n public readonly partTypeIds = input<PartTypeIds>();\r\n\r\n /**\r\n * The part type name.\r\n */\r\n public readonly typeName = computed(() => {\r\n const partTypeIds = this.partTypeIds();\r\n const typeThesaurus = this.typeThesaurus();\r\n\r\n if (!partTypeIds) {\r\n return undefined;\r\n }\r\n\r\n return getPartIdName(partTypeIds.typeId, partTypeIds.roleId, typeThesaurus);\r\n });\r\n\r\n /**\r\n * The part role name.\r\n */\r\n public readonly roleName = computed(() => {\r\n const partTypeIds = this.partTypeIds();\r\n const typeThesaurus = this.typeThesaurus();\r\n\r\n if (!partTypeIds) {\r\n return undefined;\r\n }\r\n\r\n return this.getRoleIdName(partTypeIds.roleId, typeThesaurus);\r\n });\r\n\r\n /**\r\n * The part badge color.\r\n */\r\n public readonly color = computed(() => {\r\n const partTypeIds = this.partTypeIds();\r\n const facetDefinition = this.facetDefinition();\r\n\r\n if (!partTypeIds) {\r\n return 'transparent';\r\n }\r\n\r\n return this.getPartColor(\r\n partTypeIds.typeId,\r\n partTypeIds.roleId,\r\n facetDefinition\r\n );\r\n });\r\n\r\n /**\r\n * The part definition matching the part type ID and role ID.\r\n */\r\n public readonly partDefinition = computed(() => {\r\n const partTypeIds = this.partTypeIds();\r\n const facetDefinition = this.facetDefinition();\r\n\r\n if (!partTypeIds || !facetDefinition?.partDefinitions) {\r\n return undefined;\r\n }\r\n\r\n // First try to find exact match with typeId:roleId\r\n if (partTypeIds.roleId) {\r\n const exactMatch = facetDefinition.partDefinitions.find(\r\n (pd) => pd.typeId === `${partTypeIds.typeId}:${partTypeIds.roleId}`\r\n );\r\n if (exactMatch) {\r\n return exactMatch;\r\n }\r\n }\r\n\r\n // Fallback to match by typeId only\r\n return facetDefinition.partDefinitions.find(\r\n (pd) => pd.typeId === partTypeIds.typeId\r\n );\r\n });\r\n\r\n constructor(private _facetService: FacetService) {}\r\n\r\n private getPartColor(\r\n typeId: string,\r\n roleId?: string,\r\n facetDefinition?: FacetDefinition\r\n ): string {\r\n if (!facetDefinition) {\r\n return 'transparent';\r\n }\r\n return this._facetService.getPartColor(typeId, roleId, facetDefinition);\r\n }\r\n\r\n /**\r\n * Get the role's human-friendly name from its ID.\r\n * @param roleId The role ID.\r\n * @param typeThesaurus The types thesaurus.\r\n * @returns The name or undefined.\r\n */\r\n private getRoleIdName(\r\n roleId?: string,\r\n typeThesaurus?: Thesaurus\r\n ): string | undefined {\r\n if (!roleId || !typeThesaurus) {\r\n return roleId;\r\n }\r\n let entry: ThesaurusEntry | undefined;\r\n\r\n // first find full roleId with optional suffix\r\n entry = typeThesaurus.entries?.find((e) => e.id === roleId);\r\n if (entry) {\r\n return entry.value;\r\n }\r\n\r\n // else strip :suffix if any and find\r\n const i = roleId.lastIndexOf(':');\r\n if (i > -1) {\r\n roleId = roleId.substring(0, i);\r\n }\r\n entry = typeThesaurus.entries?.find((e) => e.id === roleId);\r\n return entry ? entry.value : roleId;\r\n }\r\n}\r\n","@if (badgeType() !== 2) {\r\n<span\r\n class=\"part-badge\"\r\n [style.background-color]=\"color()\"\r\n [style.color]=\"color() | colorToContrast\"\r\n [matTooltip]=\"partDefinition()?.description\"\r\n>\r\n {{ typeName() }}\r\n</span>\r\n} @if (badgeType() !== 1 && roleName()) {\r\n<span class=\"role-badge\">\r\n {{ roleName() }}\r\n</span>\r\n}\r\n","import {\r\n Component,\r\n Injector,\r\n OnDestroy,\r\n OnInit,\r\n output,\r\n input,\r\n effect,\r\n model,\r\n computed,\r\n inject,\r\n} from '@angular/core';\r\nimport {\r\n FormBuilder,\r\n FormGroup,\r\n PristineChangeEvent,\r\n UntypedFormGroup,\r\n} from '@angular/forms';\r\nimport { BehaviorSubject, Subscription } from 'rxjs';\r\n\r\nimport { deepCopy } from '@myrmidon/ngx-tools';\r\nimport { AuthJwtService, User } from '@myrmidon/auth-jwt-login';\r\nimport { AppRepository } from '@myrmidon/cadmus-state';\r\n\r\nimport {\r\n EditedObject,\r\n Fragment,\r\n FragmentIdentity,\r\n Part,\r\n PartIdentity,\r\n} from '@myrmidon/cadmus-core';\r\nimport { getPartIdName } from './part-badge/part-badge.component';\r\n\r\n/**\r\n * Base class for part/fragment editors dumb components.\r\n * The model type is the templated argument T.\r\n *\r\n * When deriving from this editor, be sure to call super.ngOnInit()\r\n * from the derived editor's ngOnInit handler.\r\n */\r\n@Component({\r\n template: '',\r\n standalone: false,\r\n})\r\nexport abstract class ModelEditorComponentBase<T extends Part | Fragment>\r\n implements OnInit, OnDestroy\r\n{\r\n private readonly _mebSubs: Subscription[] = [];\r\n private readonly _injector = inject(Injector);\r\n protected readonly _appRepository?: AppRepository;\r\n\r\n /**\r\n * The root form of the editor.\r\n */\r\n public form: FormGroup | UntypedFormGroup;\r\n\r\n /**\r\n * The current user.\r\n */\r\n public user?: User;\r\n\r\n /**\r\n * The user authorization level (0-4).\r\n */\r\n public userLevel: number;\r\n\r\n /**\r\n * An observable with the current dirty state of the editor.\r\n */\r\n public isDirty$: BehaviorSubject<boolean>;\r\n\r\n /**\r\n * The identity of the edited model.\r\n */\r\n public readonly identity = input<PartIdentity | FragmentIdentity>();\r\n\r\n /**\r\n * The data being edited.\r\n */\r\n public readonly data = model<EditedObject<T>>();\r\n\r\n /**\r\n * True to disable the editor.\r\n */\r\n public readonly disabled = input<boolean>();\r\n\r\n /**\r\n * Event emitted when the dirty state has changed.\r\n * This event just reflects changes in isDirty$, and is a facility\r\n * for propagating it to the parent's component.\r\n */\r\n public readonly dirtyChange = output<boolean>();\r\n\r\n /**\r\n * Emitted when the user requests to close the editor.\r\n */\r\n public readonly editorClose = output();\r\n\r\n /**\r\n * The human-friendly model name. This is computed from the model's\r\n * type ID and role ID, if any, using the types thesaurus set provided\r\n * by the app repository.\r\n */\r\n public readonly modelName = computed<string | undefined>(() => {\r\n const identity = this.identity();\r\n // layers have no identity but have a layerPart\r\n if (!identity) {\r\n const layerPart = this.data()?.layerPart;\r\n if (layerPart) {\r\n return getPartIdName(\r\n layerPart.typeId,\r\n layerPart.roleId,\r\n this._appRepository?.getTypeThesaurus(),\r\n true // no fallback so that the part template can use its default name\r\n );\r\n }\r\n return undefined;\r\n }\r\n if (!identity) {\r\n return undefined;\r\n }\r\n return getPartIdName(\r\n identity.typeId,\r\n identity.roleId,\r\n this._appRepository?.getTypeThesaurus(),\r\n true // no fallback so that the part template can use its default name\r\n );\r\n });\r\n\r\n /**\r\n * Create a new instance of the editor.\r\n *\r\n * @param authService The authentication service.\r\n * @param formBuilder Form builder.\r\n */\r\n constructor(\r\n protected authService: AuthJwtService,\r\n protected formBuilder: FormBuilder\r\n ) {\r\n this.form = formBuilder.group({});\r\n this.userLevel = 0;\r\n this.isDirty$ = new BehaviorSubject<boolean>(false);\r\n this._appRepository = inject(AppRepository);\r\n\r\n effect(() => {\r\n this.disableForm(this.disabled());\r\n });\r\n effect(() => {\r\n this.onDataSet(this.data());\r\n });\r\n effect(() => {\r\n this.onIdentitySet(this.identity());\r\n });\r\n }\r\n\r\n private disableForm(disabled?: boolean) {\r\n if (disabled) {\r\n this.form.disable();\r\n } else {\r\n this.form.enable();\r\n }\r\n }\r\n\r\n private onIdentitySet(identity?: PartIdentity | FragmentIdentity) {\r\n if (identity?.partId) {\r\n const part = this.data()?.value as Part;\r\n if (part && !part.id) {\r\n console.log('part identity set', identity.partId);\r\n part.id = identity.partId;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Initialize automatic settings loading for this editor. Call this from\r\n * the derived class constructor to opt into settings loading. When\r\n * identity becomes available, settings are fetched using the specified\r\n * type ID and the role ID from identity.\r\n *\r\n * @param typeId The part/fragment type ID for settings lookup.\r\n * @param callback Called when settings are loaded (or with undefined\r\n * if not found or on error).\r\n */\r\n protected initSettings<S>(\r\n typeId: string,\r\n callback: (settings: S | undefined) => void\r\n ): void {\r\n effect(\r\n () => {\r\n const identity = this.identity();\r\n if (!identity || !this._appRepository) return;\r\n this._appRepository\r\n .getSettingFor<S>(typeId, identity.roleId || undefined)\r\n .then((settings) => callback(settings))\r\n .catch((err) => {\r\n console.warn(`Failed to load settings for ${typeId}:`, err);\r\n callback(undefined);\r\n });\r\n },\r\n { injector: this._injector }\r\n );\r\n }\r\n\r\n public ngOnInit(): void {\r\n // form\r\n this.form = this.buildForm(this.formBuilder);\r\n\r\n // dirty check on form\r\n this._mebSubs.push(\r\n this.form.events.subscribe((e) => {\r\n if (e instanceof PristineChangeEvent) {\r\n console.log('dirty change: ', !e.pristine);\r\n this.isDirty$.next(!e.pristine);\r\n this.dirtyChange.emit(this.isDirty$.value);\r\n }\r\n })\r\n );\r\n\r\n // auth service\r\n this.userLevel = this.getCurrentUserLevel();\r\n this._mebSubs.push(\r\n this.authService.currentUser$.subscribe((user: User | null) => {\r\n this.updateUserProperties(user);\r\n })\r\n );\r\n }\r\n\r\n public ngOnDestroy(): void {\r\n this._mebSubs.forEach((s) => s.unsubscribe());\r\n }\r\n\r\n /**\r\n * Implement in the derived class to build the root form of this editor.\r\n * The form built will then be attached to the dirty check mechanism\r\n * provided by this base class.\r\n *\r\n * @param formBuilder The form builder.\r\n */\r\n protected abstract buildForm(\r\n formBuilder: FormBuilder\r\n ): FormGroup | UntypedFormGroup;\r\n\r\n /**\r\n * Get the authorization level of the current user if any.\r\n * @returns 4-1 for admin, editor, operator, visitor; else 0.\r\n */\r\n private getCurrentUserLevel(): number {\r\n const user = this.authService.currentUserValue;\r\n if (!user || !user.roles) {\r\n return 0;\r\n }\r\n if (user.roles.indexOf('admin') > -1) {\r\n return 4;\r\n }\r\n if (user.roles.indexOf('editor') > -1) {\r\n return 3;\r\n }\r\n if (user.roles.indexOf('operator') > -1) {\r\n return 2;\r\n }\r\n if (user.roles.indexOf('visitor') > -1) {\r\n return 1;\r\n }\r\n return 0;\r\n }\r\n\r\n private updateUserProperties(user: User | null): void {\r\n if (!user) {\r\n this.user = undefined;\r\n this.userLevel = 0;\r\n } else {\r\n this.user = user;\r\n this.userLevel = this.getCurrentUserLevel();\r\n }\r\n }\r\n\r\n /**\r\n * Update the data value property and emit the corresponding\r\n * modelChange event.\r\n *\r\n * @param value The value.\r\n */\r\n protected updateValue(value: T): void {\r\n this.data.set({ ...(this.data() || { thesauri: {} }), value: value });\r\n }\r\n\r\n /**\r\n * Invoked whenever the model property is set (=data comes from input model\r\n * property), unless setting it via updateModel. Implement to update the form\r\n * controls to reflect the new model data.\r\n *\r\n * @param data The data set, or undefined.\r\n */\r\n protected abstract onDataSet(data?: EditedObject<T>): void;\r\n\r\n /**\r\n * Get a new object from the edited part if any, else as a new part.\r\n *\r\n * @param typeId The part's type ID. This is a constant received\r\n * from the implementor.\r\n * @returns Part object.\r\n */\r\n protected getEditedPart(typeId: string): Part {\r\n const part = deepCopy(this.data()?.value) as Part | null;\r\n return (\r\n part || {\r\n itemId: this.identity()!.itemId || '',\r\n id: '',\r\n typeId: typeId,\r\n roleId: this.identity()!.roleId || undefined,\r\n timeCreated: new Date(),\r\n creatorId: '',\r\n timeModified: new Date(),\r\n userId: '',\r\n }\r\n );\r\n }\r\n\r\n /**\r\n * Get a new object from the edited fragment if any, else a new fragment.\r\n *\r\n * @returns Fragment object.\r\n */\r\n protected getEditedFragment(): Fragment {\r\n const fr = deepCopy(this.data()?.value) as Fragment | null;\r\n return (\r\n fr || {\r\n location: (this.identity() as FragmentIdentity).loc,\r\n }\r\n );\r\n }\r\n\r\n /**\r\n * Implement in derived classes to get the data from form's controls.\r\n * This is used when saving.\r\n */\r\n protected abstract getValue(): T;\r\n\r\n /**\r\n * True if this editor has the thesaurus having the specified key in the\r\n * loaded thesauri set.\r\n */\r\n protected hasThesaurus(key: string): boolean {\r\n return this.data()?.thesauri && this.data()!.thesauri[key] ? true : false;\r\n }\r\n\r\n /**\r\n * Emit a request to close the editor.\r\n */\r\n public close(): void {\r\n this.editorClose.emit();\r\n }\r\n\r\n /**\r\n * Save the edited data if valid.\r\n */\r\n public save(): void {\r\n if (this.form.invalid) {\r\n console.warn('Save invoked with invalid form');\r\n return;\r\n }\r\n const value = this.getValue();\r\n this.updateValue(value);\r\n // the form is no more dirty\r\n this.form.markAsPristine();\r\n }\r\n}\r\n","import {\r\n AbstractControl,\r\n ValidatorFn,\r\n ValidationErrors,\r\n FormGroup,\r\n UntypedFormGroup,\r\n} from '@angular/forms';\r\n\r\n// https://www.tektutorialshub.com/angular/custom-validator-with-parameters-in-angular/\r\n\r\n/**\r\n * General-purpose custom validators.\r\n */\r\n// https://github.com/angular/angular/issues/18867#issuecomment-357484102\r\n// @dynamic\r\nexport class CustomValidators {\r\n /**\r\n * Validates a FormGroup or FormArray control checking if the count of their\r\n * controls with a true value is equal to or greater than the specified\r\n * number.\r\n *\r\n * @param min The minimum number of checked controls.\r\n */\r\n public static minChecked(min = 1): ValidatorFn {\r\n return (control: AbstractControl): ValidationErrors | null => {\r\n // https://trungk18.com/experience/angular-form-array-validate-at-least-one-checkbox-was-selected/\r\n let checked = 0;\r\n\r\n const group = (control as FormGroup) || (control as UntypedFormGroup);\r\n Object.keys(group.controls).forEach((key) => {\r\n const ctl = group.controls[key];\r\n if (ctl.value === true) {\r\n checked++;\r\n }\r\n });\r\n\r\n if (checked < min) {\r\n return {\r\n minChecked: true,\r\n };\r\n }\r\n return null;\r\n };\r\n }\r\n}\r\n","import { AbstractControl } from '@angular/forms';\r\n\r\n/**\r\n * Simple JSON validator.\r\n */\r\nexport class JsonValidators {\r\n public static json(\r\n control: AbstractControl\r\n ): { [key: string]: boolean } | null {\r\n if (!control.value) {\r\n // we allow empty code\r\n return null;\r\n }\r\n try {\r\n JSON.parse(control.value);\r\n } catch (e) {\r\n return { json: true };\r\n }\r\n return null;\r\n }\r\n}\r\n","import { Injectable } from '@angular/core';\nimport { map, Observable } from 'rxjs';\n\nimport { DataPage } from '@myrmidon/ngx-tools';\n\nimport { UserService } from '@myrmidon/cadmus-api';\nimport {\n RefLookupFilter,\n RefLookupService,\n} from '@myrmidon/cadmus-refs-lookup';\n\nexport interface UserWithRoles {\n user: {\n id: string;\n firstName: string;\n lastName: string;\n userName: string;\n email: string;\n };\n roles: string[];\n}\n\n/**\n * Service for users lookup.\n */\n@Injectable({\n providedIn: 'root',\n})\nexport class UserRefLookupService implements RefLookupService {\n public readonly id = 'user';\n\n constructor(private _userService: UserService) {}\n\n public lookup(\n filter: RefLookupFilter,\n options?: any,\n ): Observable<UserWithRoles[]> {\n return this._userService\n .getUsers(\n {\n name: filter.text,\n },\n 1,\n filter.limit,\n )\n .pipe(\n map((page: DataPage<UserWithRoles>) => {\n return page.items;\n }),\n );\n }\n\n public getById(id: string): Observable<UserWithRoles | undefined> {\n return this._userService\n .getUser(id)\n .pipe(map((user) => user as UserWithRoles | undefined));\n }\n\n public getName(item: UserWithRoles): string {\n return item?.user?.userName;\n }\n}\n","// https://github.com/angular/angular/issues/10887\r\n\r\nimport { AbstractControl } from '@angular/forms';\r\nimport { Observable, Subject } from 'rxjs';\r\n\r\n/**\r\n * Extract arguments of function\r\n */\r\nexport type ArgumentsType<F> = F extends (...args: infer A) => any ? A : never;\r\n\r\n/**\r\n * Creates an object like O. Optionally provide minimum set of properties P\r\n * which the objects must share to conform.\r\n */\r\ntype ObjectLike<O extends object, P extends keyof O = keyof O> = Pick<O, P>;\r\n\r\n/**\r\n * Extract a touched changed observable from an abstract control.\r\n * Use in component code like:\r\n * this.touchedChanges$ = extractTouchedChanges(this.form);\r\n *\r\n * @param control AbstractControl-like object with markAsTouched method.\r\n */\r\nexport const extractTouchedChanges = (\r\n control: ObjectLike<AbstractControl, 'markAsTouched' | 'markAsUntouched'>\r\n): Observable<boolean> => {\r\n const prevMarkAsTouched = control.markAsTouched;\r\n const prevMarkAsUntouched = control.markAsUntouched;\r\n\r\n const touchedChanges$ = new Subject<boolean>();\r\n\r\n function nextMarkAsTouched(\r\n ...args: ArgumentsType<AbstractControl['markAsTouched']>\r\n ): void {\r\n touchedChanges$.next(true);\r\n prevMarkAsTouched.bind(control)(...args);\r\n }\r\n\r\n function nextMarkAsUntouched(\r\n ...args: ArgumentsType<AbstractControl['markAsUntouched']>\r\n ): void {\r\n touchedChanges$.next(false);\r\n prevMarkAsUntouched.bind(control)(...args);\r\n }\r\n\r\n control.markAsTouched = nextMarkAsTouched;\r\n control.markAsUntouched = nextMarkAsUntouched;\r\n\r\n return touchedChanges$;\r\n};\r\n\r\n/**\r\n * Extract a pristine changed observable from an abstract control.\r\n * Use in component code like:\r\n * this.pristineChanges$ = extractPristineChanges(this.form);\r\n *\r\n * @param control AbstractControl-like object with markAsPristine and markAsDirty\r\n * methods.\r\n */\r\nexport const extractPristineChanges = (\r\n control: ObjectLike<AbstractControl, 'markAsPristine' | 'markAsDirty'>\r\n): Observable<boolean> => {\r\n const prevMarkAsPristine = control.markAsPristine;\r\n const prevMarkAsDirty = control.markAsDirty;\r\n\r\n const pristineChanges$ = new Subject<boolean>();\r\n\r\n function nextMarkAsPristine(\r\n ...args: ArgumentsType<AbstractControl['markAsPristine']>\r\n ): void {\r\n pristineChanges$.next(true);\r\n prevMarkAsPristine.bind(control)(...args);\r\n }\r\n\r\n function nextMarkAsDirty(\r\n ...args: ArgumentsType<AbstractControl['markAsDirty']>\r\n ): void {\r\n pristineChanges$.next(false);\r\n prevMarkAsDirty.bind(control)(...args);\r\n }\r\n\r\n control.markAsPristine = nextMarkAsPristine;\r\n control.markAsDirty = nextMarkAsDirty;\r\n\r\n return pristineChanges$;\r\n};\r\n","/*\r\n * Public API Surface of cadmus-ui\r\n */\r\n\r\nexport * from './lib/components/close-save-buttons/close-save-buttons.component';\r\nexport * from './lib/components/decorated-token-text/decorated-token-text.component';\r\nexport * from './lib/components/error-list/error-list.component';\r\nexport * from './lib/components/facet-badge/facet-badge.component';\r\nexport * from './lib/components/flags-badge/flags-badge.component';\r\nexport * from './lib/components/layer-hints/layer-hints.component';\r\nexport * from './lib/components/lookup-pin/lookup-pin.component';\r\nexport * from './lib/components/part-badge/part-badge.component';\r\n\r\nexport * from './lib/components/model-editor-component-base';\r\n\r\nexport * from './lib/services/color.service';\r\n\r\nexport * from './lib/validators/custom-validators';\r\nexport * from './lib/validators/json-validators';\r\n\r\nexport * from './lib/services/user-ref-lookup.service';\r\n\r\nexport * from './lib/utils';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i1.ColorService","i1","i2","map"],"mappings":"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"}
1
+ {"version":3,"file":"myrmidon-cadmus-ui.mjs","sources":["../../../../projects/myrmidon/cadmus-ui/src/lib/components/close-save-buttons/close-save-buttons.component.ts","../../../../projects/myrmidon/cadmus-ui/src/lib/components/close-save-buttons/close-save-buttons.component.html","../../../../projects/myrmidon/cadmus-ui/src/lib/components/decorated-token-text/decorated-token-text.component.ts","../../../../projects/myrmidon/cadmus-ui/src/lib/components/decorated-token-text/decorated-token-text.component.html","../../../../projects/myrmidon/cadmus-ui/src/lib/components/error-list/error-list.component.ts","../../../../projects/myrmidon/cadmus-ui/src/lib/components/error-list/error-list.component.html","../../../../projects/myrmidon/cadmus-ui/src/lib/services/color.service.ts","../../../../projects/myrmidon/cadmus-ui/src/lib/components/facet-badge/facet-badge.component.ts","../../../../projects/myrmidon/cadmus-ui/src/lib/components/facet-badge/facet-badge.component.html","../../../../projects/myrmidon/cadmus-ui/src/lib/components/flags-badge/flags-badge.component.ts","../../../../projects/myrmidon/cadmus-ui/src/lib/components/flags-badge/flags-badge.component.html","../../../../projects/myrmidon/cadmus-ui/src/lib/components/layer-hints/layer-hints.component.ts","../../../../projects/myrmidon/cadmus-ui/src/lib/components/layer-hints/layer-hints.component.html","../../../../projects/myrmidon/cadmus-ui/src/lib/components/lookup-pin/lookup-pin.component.ts","../../../../projects/myrmidon/cadmus-ui/src/lib/components/lookup-pin/lookup-pin.component.html","../../../../projects/myrmidon/cadmus-ui/src/lib/components/part-badge/part-badge.component.ts","../../../../projects/myrmidon/cadmus-ui/src/lib/components/part-badge/part-badge.component.html","../../../../projects/myrmidon/cadmus-ui/src/lib/components/model-editor-component-base.ts","../../../../projects/myrmidon/cadmus-ui/src/lib/validators/custom-validators.ts","../../../../projects/myrmidon/cadmus-ui/src/lib/validators/json-validators.ts","../../../../projects/myrmidon/cadmus-ui/src/lib/services/user-ref-lookup.service.ts","../../../../projects/myrmidon/cadmus-ui/src/lib/utils.ts","../../../../projects/myrmidon/cadmus-ui/src/public-api.ts","../../../../projects/myrmidon/cadmus-ui/src/myrmidon-cadmus-ui.ts"],"sourcesContent":["import {\r\n ChangeDetectionStrategy,\r\n Component,\r\n DestroyRef,\r\n effect,\r\n inject,\r\n input,\r\n output,\r\n signal,\r\n} from '@angular/core';\r\nimport { FormGroup, UntypedFormGroup } from '@angular/forms';\r\nimport { Subscription } from 'rxjs';\r\n\r\nimport { MatButton } from '@angular/material/button';\r\nimport { MatIcon } from '@angular/material/icon';\r\n\r\n@Component({\r\n selector: 'cadmus-close-save-buttons',\r\n templateUrl: './close-save-buttons.component.html',\r\n styleUrls: ['./close-save-buttons.component.css'],\r\n imports: [MatButton, MatIcon],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n})\r\nexport class CloseSaveButtonsComponent {\r\n private _statusSub?: Subscription;\r\n private readonly _destroyRef = inject(DestroyRef);\r\n\r\n public readonly form = input<FormGroup | UntypedFormGroup>();\r\n public readonly noSave = input<boolean>();\r\n public readonly closeRequest = output();\r\n\r\n /**\r\n * Reactive invalid state: true when the current form is invalid.\r\n * Derived from the form's statusChanges so that OnPush components\r\n * re-render whenever validity changes without a reference change.\r\n */\r\n public readonly invalid = signal<boolean>(false);\r\n\r\n constructor() {\r\n // Clean up the statusChanges subscription when the component is destroyed\r\n this._destroyRef.onDestroy(() => this._statusSub?.unsubscribe());\r\n\r\n // Re-subscribe whenever the form input changes\r\n effect(() => {\r\n this._statusSub?.unsubscribe();\r\n const f = this.form();\r\n if (f) {\r\n this.invalid.set(f.invalid);\r\n this._statusSub = f.statusChanges.subscribe(() =>\r\n this.invalid.set(f.invalid),\r\n );\r\n } else {\r\n this.invalid.set(false);\r\n }\r\n });\r\n }\r\n\r\n public close(): void {\r\n this.closeRequest.emit();\r\n }\r\n}\r\n","@if (form()) {\n <div class=\"form-row\">\n <button type=\"button\" mat-flat-button class=\"mat-warn\" (click)=\"close()\">\n <mat-icon>cancel</mat-icon>\n close\n </button>\n @if (!noSave()) {\n <button\n type=\"submit\"\n [disabled]=\"invalid()\"\n mat-flat-button\n class=\"mat-primary\"\n >\n <mat-icon>check_circle</mat-icon>\n save\n </button>\n }\n </div>\n}\n","import {\r\n ChangeDetectionStrategy,\r\n Component,\r\n effect,\r\n input,\r\n signal,\r\n} from '@angular/core';\r\n\r\nimport { SafeHtmlPipe } from '@myrmidon/ngx-tools';\r\n\r\nimport { TokenLocation, TextLayerService } from '@myrmidon/cadmus-core';\r\n\r\n/**\r\n * Decorated token-based text visualizer. This is used when editing\r\n * token-based text layers.\r\n */\r\n@Component({\r\n selector: 'cadmus-decorated-token-text',\r\n templateUrl: './decorated-token-text.component.html',\r\n styleUrls: ['./decorated-token-text.component.css'],\r\n imports: [SafeHtmlPipe],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n})\r\nexport class DecoratedTokenTextComponent {\r\n /**\r\n * The base text.\r\n */\r\n public readonly baseText = input<string>('');\r\n\r\n /**\r\n * The token-based locations of all the fragments in the layer.\r\n */\r\n public readonly locations = input<TokenLocation[]>([]);\r\n\r\n /**\r\n * A selected token-based location.\r\n */\r\n public readonly selectedLocation = input<TokenLocation>();\r\n\r\n public readonly text = signal<string | undefined>(undefined); // rendered HTML text\r\n\r\n constructor(private _textLayerService: TextLayerService) {\r\n effect(() => {\r\n this.decorate(this.baseText(), this.locations(), this.selectedLocation());\r\n });\r\n }\r\n\r\n private decorate(\r\n text: string,\r\n locations: TokenLocation[],\r\n selectedLocation?: TokenLocation\r\n ): void {\r\n this.text.set(\r\n this._textLayerService.render(text, locations, selectedLocation)\r\n );\r\n }\r\n}\r\n","<div [innerHtml]=\"text() | safeHtml : 'html'\" id=\"text\" #textElem></div>\r\n","import { ChangeDetectionStrategy, Component, input } from '@angular/core';\r\n\r\n@Component({\r\n selector: 'cadmus-error-list',\r\n templateUrl: './error-list.component.html',\r\n styleUrls: ['./error-list.component.css'],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n})\r\nexport class ErrorListComponent {\r\n public readonly errors = input<string[]>();\r\n}\r\n","@if (errors()?.length) {\n <ul>\n @for (error of errors(); track error) {\n <li class=\"error\">{{error}}</li>\n }\n </ul>\n}\n","import { Injectable } from '@angular/core';\r\n\r\n/**\r\n * Colors helper service.\r\n */\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class ColorService {\r\n /**\r\n * Get the R,G,B components of the color expressed by the specified\r\n * RGB string (3 or 6 digits format).\r\n *\r\n * @param rgb The RGB color string (3 or 6 digits).\r\n * @returns An array where [0]=R, [1]=G, [2]=B, or null if invalid\r\n * input string.\r\n */\r\n public getRgb(rgb: string): number[] | null {\r\n if (!rgb) {\r\n return null;\r\n }\r\n\r\n // RGB\r\n let m = rgb.match(/^#?([0-9a-f]{3})$/i);\r\n if (m && m[1]) {\r\n // in 3-characters format, each value is multiplied by 0x11 to give an\r\n // even scale from 0x00 to 0xff\r\n return [\r\n parseInt(m[1].charAt(0), 16) * 0x11,\r\n parseInt(m[1].charAt(1), 16) * 0x11,\r\n parseInt(m[1].charAt(2), 16) * 0x11,\r\n ];\r\n }\r\n // RRGGBB\r\n m = rgb.match(/^#?([0-9a-f]{6})$/i);\r\n if (m && m[1]) {\r\n return [\r\n parseInt(m[1].substring(0, 2), 16),\r\n parseInt(m[1].substring(2, 4), 16),\r\n parseInt(m[1].substring(4, 6), 16),\r\n ];\r\n }\r\n return null;\r\n }\r\n\r\n /**\r\n * Get black or white according to which of them has the maximum contrast\r\n * against the specified color.\r\n *\r\n * @param rgb The RGB color string.\r\n * @returns Black or white. If rgb is invalid, always black.\r\n */\r\n public getContrastColor(rgb: string): string {\r\n // https://stackoverflow.com/questions/3942878/how-to-decide-font-color-in-white-or-black-depending-on-background-color\r\n const values = this.getRgb(rgb);\r\n if (!values) {\r\n return 'black';\r\n }\r\n return values[0] * 0.299 + values[1] * 0.587 + values[2] * 0.114 > 186\r\n ? 'black'\r\n : 'white';\r\n }\r\n\r\n /**\r\n * Convert HSL to RGB.\r\n *\r\n * @param h Hue\r\n * @param s Saturation\r\n * @param l Lightness\r\n * @returns Object with r, g, b values.\r\n */\r\n public hslToRgb(\r\n h: number,\r\n s: number,\r\n l: number\r\n ): { r: number; g: number; b: number } {\r\n // https://css-tricks.com/converting-color-spaces-in-javascript/\r\n // must be fractions of 1\r\n s /= 100;\r\n l /= 100;\r\n\r\n let c = (1 - Math.abs(2 * l - 1)) * s,\r\n x = c * (1 - Math.abs(((h / 60) % 2) - 1)),\r\n m = l - c / 2,\r\n r = 0,\r\n g = 0,\r\n b = 0;\r\n if (0 <= h && h < 60) {\r\n r = c;\r\n g = x;\r\n b = 0;\r\n } else if (60 <= h && h < 120) {\r\n r = x;\r\n g = c;\r\n b = 0;\r\n } else if (120 <= h && h < 180) {\r\n r = 0;\r\n g = c;\r\n b = x;\r\n } else if (180 <= h && h < 240) {\r\n r = 0;\r\n g = x;\r\n b = c;\r\n } else if (240 <= h && h < 300) {\r\n r = x;\r\n g = 0;\r\n b = c;\r\n } else if (300 <= h && h < 360) {\r\n r = c;\r\n g = 0;\r\n b = x;\r\n }\r\n r = Math.round((r + m) * 255);\r\n g = Math.round((g + m) * 255);\r\n b = Math.round((b + m) * 255);\r\n\r\n return { r: r, g: g, b: b };\r\n }\r\n\r\n public rgbToString(r: number, g: number, b: number): string {\r\n let rd = r.toString(16);\r\n if (rd.length === 1) {\r\n rd = '0' + rd;\r\n }\r\n let gd = g.toString(16);\r\n if (gd.length === 1) {\r\n gd = '0' + gd;\r\n }\r\n let bd = b.toString(16);\r\n if (bd.length === 1) {\r\n bd = '0' + bd;\r\n }\r\n return rd + gd + bd;\r\n }\r\n\r\n /**\r\n * Get the next color from a palette generated to include\r\n * the specified count of colors.\r\n *\r\n * @param index The index of the next color in the palette.\r\n * @param count The total count of colors in the palette.\r\n * @param blueBoost True to adjust colors for the eye's lack of sensitivity to blue.\r\n * @returns The RRGGBB values string.\r\n */\r\n public nextPaletteColor(\r\n index: number,\r\n count: number,\r\n blueBoost = true\r\n ): string {\r\n // https://stackoverflow.com/questions/43193341/how-to-generate-random-pastel-or-brighter-color-in-javascript\r\n const h = Math.floor((index / count) * 341); // between 0 and 340\r\n let s = 100;\r\n let l = 50;\r\n\r\n if (blueBoost && h > 215 && h < 265) {\r\n const gain = 20;\r\n let blueness = 1 - Math.abs(h - 240) / 25;\r\n let change = Math.floor(gain * blueness);\r\n l += change;\r\n s -= change;\r\n }\r\n const rgb = this.hslToRgb(h, s, l);\r\n return this.rgbToString(rgb.r, rgb.g, rgb.b);\r\n }\r\n}\r\n","import { ChangeDetectionStrategy, Component, effect, input, signal } from '@angular/core';\r\nimport { FacetDefinition } from '@myrmidon/cadmus-core';\r\n\r\nimport { MatTooltip } from '@angular/material/tooltip';\r\n\r\nimport { ColorService } from '../../services/color.service';\r\n\r\nexport interface FacetBadgeData {\r\n definitions: FacetDefinition[];\r\n facetId?: string;\r\n}\r\n\r\n@Component({\r\n selector: 'cadmus-facet-badge',\r\n templateUrl: './facet-badge.component.html',\r\n styleUrls: ['./facet-badge.component.css'],\r\n imports: [MatTooltip],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n})\r\nexport class FacetBadgeComponent {\r\n private _facetColors: { [key: string]: string };\r\n private _facetTips: { [key: string]: string };\r\n\r\n public readonly color = signal<string>('transparent');\r\n public readonly contrastColor = signal<string>('black');\r\n public readonly tip = signal<string | undefined>(undefined);\r\n\r\n /**\r\n * The facet data.\r\n */\r\n public readonly data = input<FacetBadgeData>({\r\n definitions: [],\r\n });\r\n\r\n constructor(private _colorService: ColorService) {\r\n this._facetColors = {};\r\n this._facetTips = {};\r\n\r\n effect(() => {\r\n this.updateBadge(this.data());\r\n });\r\n }\r\n\r\n private getFacetColor(facetId: string): string {\r\n if (this._facetColors[facetId]) {\r\n return this._facetColors[facetId];\r\n }\r\n if (!this.data().definitions?.length) {\r\n return 'transparent';\r\n }\r\n\r\n const facet = this.data().definitions.find((f) => {\r\n return f.id === facetId;\r\n });\r\n if (facet?.colorKey) {\r\n this._facetColors[facetId] = '#' + facet.colorKey;\r\n } else {\r\n this._facetColors[facetId] = 'transparent';\r\n }\r\n return this._facetColors[facetId];\r\n }\r\n\r\n private getFacetTip(facetId: string): string | null {\r\n if (this._facetTips[facetId]) {\r\n return this._facetTips[facetId];\r\n }\r\n\r\n if (!this.data().definitions?.length) {\r\n return null;\r\n }\r\n\r\n const facet = this.data().definitions.find((f) => {\r\n return f.id === facetId;\r\n });\r\n if (!facet) {\r\n this._facetTips[facetId] = facetId;\r\n } else {\r\n const sb: string[] = [];\r\n for (let i = 0; i < facet.partDefinitions.length; i++) {\r\n if (i > 0) {\r\n sb.push(', ');\r\n }\r\n sb.push(facet.partDefinitions[i].name);\r\n if (facet.partDefinitions[i].isRequired) {\r\n sb.push('*');\r\n }\r\n }\r\n this._facetTips[facetId] = sb.join('');\r\n }\r\n return this._facetTips[facetId];\r\n }\r\n\r\n private updateBadge(data?: FacetBadgeData) {\r\n this._facetColors = {};\r\n this._facetTips = {};\r\n this.color.set(this.getFacetColor(data?.facetId || ''));\r\n this.contrastColor.set(this._colorService.getContrastColor(this.color()));\r\n this.tip.set(this.getFacetTip(data?.facetId || '') ?? undefined);\r\n }\r\n}\r\n","<span\r\n class=\"model-type\"\r\n [style.background-color]=\"color()\"\r\n [style.color]=\"contrastColor()\"\r\n matTooltip=\"{{ tip() }}\"\r\n >{{ data().facetId }}\r\n</span>\r\n","import { ChangeDetectionStrategy, Component, effect, input, signal } from '@angular/core';\r\n\r\nimport { MatTooltip } from '@angular/material/tooltip';\r\n\r\nimport { FlagDefinition } from '@myrmidon/cadmus-core';\r\n\r\n/**\r\n * Data for FlagsBadgeComponent, including flags and their definitions.\r\n */\r\nexport interface FlagsBadgeData {\r\n definitions: FlagDefinition[];\r\n flags: number;\r\n}\r\n\r\n/**\r\n * Badge with item's flags. Each flag is represented by a circle filled\r\n * with the flag's color key.\r\n */\r\n@Component({\r\n selector: 'cadmus-flags-badge',\r\n templateUrl: './flags-badge.component.html',\r\n styleUrls: ['./flags-badge.component.css'],\r\n imports: [MatTooltip],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n})\r\nexport class FlagsBadgeComponent {\r\n public readonly data = input<FlagsBadgeData>();\r\n\r\n public readonly badgeFlags = signal<FlagDefinition[]>([]);\r\n\r\n constructor() {\r\n effect(() => {\r\n this.updateBadge(this.data());\r\n });\r\n }\r\n\r\n private updateBadge(data?: FlagsBadgeData) {\r\n if (!data) {\r\n return;\r\n }\r\n this.badgeFlags.set(\r\n data.definitions.filter((def) => {\r\n // tslint:disable-next-line: no-bitwise\r\n return def.id & data!.flags;\r\n })\r\n );\r\n }\r\n}\r\n","<div>\r\n @for (def of badgeFlags(); track def.id) {\r\n <span\r\n class=\"badge-flag\"\r\n [style.color]=\"'#' + def.colorKey\"\r\n [matTooltip]=\"def.label\"\r\n >\r\n @if (def.isAdmin) { &#x25c6; } @else { &#x2b24; }\r\n </span>\r\n }\r\n</div>\r\n","import { ChangeDetectionStrategy, Component, output, input, effect } from '@angular/core';\r\nimport {\r\n FormGroup,\r\n FormArray,\r\n FormBuilder,\r\n FormsModule,\r\n ReactiveFormsModule,\r\n FormControl,\r\n} from '@angular/forms';\r\n\r\nimport { MatIconButton, MatButton } from '@angular/material/button';\r\nimport { MatTooltip } from '@angular/material/tooltip';\r\nimport { MatIcon } from '@angular/material/icon';\r\nimport { MatCheckbox } from '@angular/material/checkbox';\r\n\r\nimport { DialogService } from '@myrmidon/ngx-mat-tools';\r\n\r\nimport { LayerHint } from '@myrmidon/cadmus-core';\r\n\r\n@Component({\r\n selector: 'cadmus-layer-hints',\r\n templateUrl: './layer-hints.component.html',\r\n styleUrls: ['./layer-hints.component.css'],\r\n imports: [\r\n FormsModule,\r\n ReactiveFormsModule,\r\n MatIconButton,\r\n MatTooltip,\r\n MatIcon,\r\n MatCheckbox,\r\n MatButton,\r\n ],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n})\r\nexport class LayerHintsComponent {\r\n public readonly hints = input<LayerHint[]>([]);\r\n\r\n public readonly targetLocation = input<string>();\r\n public readonly disabled = input<boolean>();\r\n public readonly readonly = input<boolean>();\r\n\r\n public readonly requestEdit = output<LayerHint>();\r\n public readonly requestDelete = output<LayerHint>();\r\n public readonly requestMove = output<LayerHint>();\r\n public readonly requestPatch = output<string[]>();\r\n\r\n public form: FormGroup;\r\n public checks: FormArray<FormControl<boolean>>;\r\n\r\n constructor(\r\n private _formBuilder: FormBuilder,\r\n private _dialogService: DialogService\r\n ) {\r\n this.checks = _formBuilder.array<FormControl<boolean>>([]);\r\n this.form = _formBuilder.group({\r\n checks: this.checks,\r\n });\r\n\r\n effect(() => {\r\n this.updateChecks(this.hints());\r\n });\r\n }\r\n\r\n private updateChecks(hints: LayerHint[]) {\r\n this.checks.clear();\r\n for (let i = 0; i < hints.length; i++) {\r\n this.checks.push(this._formBuilder.control(false, { nonNullable: true }));\r\n }\r\n }\r\n\r\n public emitRequestEdit(hint: LayerHint) {\r\n this.requestEdit.emit(hint);\r\n }\r\n\r\n public emitRequestDelete(hint: LayerHint) {\r\n this._dialogService\r\n .confirm('Confirm Deletion', `Delete fragment at \"${hint.location}\"?`)\r\n .subscribe((ok: boolean) => {\r\n if (ok) {\r\n this.requestDelete.emit(hint);\r\n }\r\n });\r\n }\r\n\r\n public emitRequestMove(hint: LayerHint) {\r\n if (!this.targetLocation()) {\r\n return;\r\n }\r\n this._dialogService\r\n .confirm(\r\n 'Confirm Move',\r\n `Move fragment at ${hint.location} to ${this.targetLocation()}?`\r\n )\r\n .subscribe((ok: boolean) => {\r\n if (ok) {\r\n this.requestMove.emit(hint);\r\n }\r\n });\r\n }\r\n\r\n public emitRequestPatch() {\r\n if (this.form.invalid) {\r\n return;\r\n }\r\n this._dialogService\r\n .confirm('Confirm Patch', `Patch the selected fragments?`)\r\n .subscribe((ok: boolean) => {\r\n if (ok) {\r\n const patches: string[] = [];\r\n for (let i = 0; i < this.checks.length; i++) {\r\n if (this.checks.at(i).value) {\r\n patches.push(this.hints()[i].patchOperation!);\r\n }\r\n }\r\n this.requestPatch.emit(patches);\r\n }\r\n });\r\n }\r\n}\r\n","@if (hints().length) {\r\n<form [formGroup]=\"form\" (submit)=\"emitRequestPatch()\">\r\n <table class=\"patches\">\r\n <thead>\r\n <tr>\r\n <th></th>\r\n <th>location</th>\r\n <th>description</th>\r\n <th>patch</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @for (hint of hints(); track hint; let i = $index) {\r\n <tr>\r\n @if (!readonly()) {\r\n <td>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Edit this fragment\"\r\n [disabled]=\"disabled()\"\r\n >\r\n <mat-icon>edit</mat-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Move this fragment to {{ targetLocation() }}\"\r\n [disabled]=\"\r\n disabled() ||\r\n !targetLocation() ||\r\n targetLocation() === hint.location\r\n \"\r\n (click)=\"emitRequestMove(hint)\"\r\n >\r\n <mat-icon>arrow_forward</mat-icon>\r\n </button>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n matTooltip=\"Delete this fragment\"\r\n [disabled]=\"disabled()\"\r\n (click)=\"emitRequestDelete(hint)\"\r\n >\r\n <mat-icon class=\"mat-warn\">delete</mat-icon>\r\n </button>\r\n </td>\r\n }\r\n <td>{{ hint.location }}</td>\r\n <td>{{ hint.description }}</td>\r\n <td>\r\n @if (hint.patchOperation) {\r\n <mat-checkbox\r\n matTooltip=\"Apply this patch\"\r\n [formControl]=\"checks.at(i)\"\r\n >\r\n {{ hint.patchOperation }}\r\n </mat-checkbox>\r\n }\r\n </td>\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n @if (targetLocation()) {\r\n <div>move target: {{ targetLocation() }}</div>\r\n }\r\n <button\r\n type=\"submit\"\r\n mat-flat-button\r\n [disabled]=\"readonly() || disabled() || form.invalid\"\r\n >\r\n apply patches\r\n </button>\r\n</form>\r\n}\r\n","import {\r\n ChangeDetectionStrategy,\r\n Component,\r\n effect,\r\n Inject,\r\n input,\r\n OnInit,\r\n output,\r\n signal,\r\n} from '@angular/core';\r\nimport { AsyncPipe } from '@angular/common';\r\nimport {\r\n UntypedFormBuilder,\r\n UntypedFormControl,\r\n UntypedFormGroup,\r\n FormsModule,\r\n ReactiveFormsModule,\r\n} from '@angular/forms';\r\nimport { Observable, of } from 'rxjs';\r\nimport {\r\n debounceTime,\r\n distinctUntilChanged,\r\n map,\r\n switchMap,\r\n take,\r\n} from 'rxjs/operators';\r\n\r\nimport {\r\n MatAutocomplete,\r\n MatAutocompleteTrigger,\r\n} from '@angular/material/autocomplete';\r\nimport { MatOption } from '@angular/material/core';\r\nimport { MatFormField } from '@angular/material/form-field';\r\nimport { MatInput } from '@angular/material/input';\r\nimport { MatIconButton } from '@angular/material/button';\r\nimport { MatTooltip } from '@angular/material/tooltip';\r\nimport { MatIcon } from '@angular/material/icon';\r\n\r\nimport { DataPage, ErrorWrapper } from '@myrmidon/ngx-tools';\r\n\r\nimport { DataPinInfo, IndexLookupDefinitions } from '@myrmidon/cadmus-core';\r\nimport { ItemService } from '@myrmidon/cadmus-api';\r\n\r\n/**\r\n * Generic data pin lookup component. This allows users typing a part\r\n * of a pin's value, and get the full pin. For instance, if you have\r\n * a lookup set of colors and type \"gr\", you might get the pins\r\n * corresponding to \"green\" (e.g. id=color, value=green), \"gray\", etc.\r\n * Usage: add a FormControl to hold a DataPinInfo value; in the HTML\r\n * template set the component's lookupKey, label, initialValue, and\r\n * entryChange handler. The initialValue, if any, should be the initial\r\n * DataPinInfo value.\r\n * If you are using this component as a pure lookup device, don't set\r\n * the initialValue and set resetOnPick=true.\r\n */\r\n@Component({\r\n selector: 'cadmus-lookup-pin',\r\n templateUrl: './lookup-pin.component.html',\r\n styleUrls: ['./lookup-pin.component.css'],\r\n imports: [\r\n FormsModule,\r\n ReactiveFormsModule,\r\n MatAutocomplete,\r\n MatOption,\r\n MatFormField,\r\n MatInput,\r\n MatAutocompleteTrigger,\r\n MatIconButton,\r\n MatTooltip,\r\n MatIcon,\r\n AsyncPipe,\r\n ],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n})\r\nexport class LookupPinComponent implements OnInit {\r\n /**\r\n * The entry value initially set when the component loads.\r\n */\r\n public readonly initialValue = input<string>();\r\n\r\n /**\r\n * The label to be displayed for this lookup.\r\n */\r\n public readonly label = input<string>('');\r\n\r\n /**\r\n * The maximum count of lookup entries to retrieve.\r\n * Default is 10.\r\n */\r\n public readonly limit = input<number>(10);\r\n\r\n /**\r\n * True to reset the lookup value after it is picked.\r\n * This is typically used when you use this component\r\n * as a pure lookup device, storing the picked value\r\n * elsewhere when handling its entryChange event.\r\n */\r\n public readonly resetOnPick = input<boolean>();\r\n\r\n /**\r\n * Fired whenever an entry is picked. Usually you should\r\n * cast the received argument to a more specific type.\r\n */\r\n public readonly entryChange = output<DataPinInfo | null>();\r\n\r\n public form: UntypedFormGroup;\r\n public lookup: UntypedFormControl;\r\n public entries$: Observable<DataPinInfo[]> | undefined;\r\n\r\n public readonly entry = signal<DataPinInfo | undefined>(undefined);\r\n\r\n constructor(\r\n formBuilder: UntypedFormBuilder,\r\n private _itemService: ItemService,\r\n @Inject('indexLookupDefinitions')\r\n private _lookupDefs: IndexLookupDefinitions\r\n ) {\r\n // form\r\n this.lookup = formBuilder.control(null);\r\n this.form = formBuilder.group({\r\n lookup: this.lookup,\r\n });\r\n\r\n effect(() => {\r\n console.log('lookup pin initial value', this.initialValue());\r\n if (this.lookup) {\r\n this.resetToInitial();\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * The lookup key to be used for this component.\r\n * This should be a key from the injectable indexLookupDefinitions.\r\n */\r\n public readonly lookupKey = input<string>();\r\n\r\n public ngOnInit(): void {\r\n this.entries$ = this.lookup.valueChanges.pipe(\r\n debounceTime(300),\r\n distinctUntilChanged(),\r\n switchMap((value: DataPinInfo | string) => {\r\n // if it's a string it's a filter; else it's the entry got\r\n if (typeof value === 'string') {\r\n return this.lookupEntries(value, this.limit());\r\n } else {\r\n return of([value]);\r\n }\r\n })\r\n );\r\n }\r\n\r\n private lookupEntries(\r\n filter: string,\r\n limit: number\r\n ): Observable<DataPinInfo[]> {\r\n // get the lookup definition\r\n if (!this.lookupKey() || !filter) {\r\n return of([]);\r\n }\r\n const ld = this._lookupDefs[this.lookupKey()!];\r\n if (!ld) {\r\n return of([]);\r\n }\r\n\r\n // build query\r\n const query = ld.roleId\r\n ? `[partTypeId=${ld.typeId}] AND [roleId=${ld.roleId}] AND [name=${ld.name}] AND [value^=${filter}]`\r\n : `[partTypeId=${ld.typeId}] AND [name=${ld.name}] AND [value^=${filter}]`;\r\n\r\n // search\r\n return this._itemService.searchPins(query, 1, limit).pipe(\r\n map((w: ErrorWrapper<DataPage<DataPinInfo>>) => {\r\n if (w.error) {\r\n return [];\r\n } else {\r\n return w.value?.items || [];\r\n }\r\n })\r\n );\r\n }\r\n\r\n private resetToInitial(): void {\r\n this.lookupEntries(this.initialValue() || '', 1)\r\n .pipe(take(1))\r\n .subscribe((entries) => {\r\n this.lookup.setValue(entries.length ? entries[0] : undefined);\r\n });\r\n }\r\n\r\n public clear(): void {\r\n this.entry.set(undefined);\r\n this.lookup.setValue(null);\r\n this.entryChange.emit(null);\r\n }\r\n\r\n public entryToName(entry: DataPinInfo): string {\r\n return entry?.value;\r\n }\r\n\r\n public pickEntry(entry: DataPinInfo): void {\r\n this.entry.set(entry);\r\n this.entryChange.emit(entry);\r\n if (this.resetOnPick()) {\r\n this.clear();\r\n }\r\n }\r\n}\r\n","<form [formGroup]=\"form\">\r\n <mat-autocomplete #lookupAuto=\"matAutocomplete\" [displayWith]=\"entryToName\">\r\n @for (entry of entries$ | async; track entry) {\r\n <mat-option [value]=\"entry\" (onSelectionChange)=\"pickEntry(entry)\">\r\n {{ entry?.value }}\r\n </mat-option>\r\n }\r\n </mat-autocomplete>\r\n\r\n <mat-form-field>\r\n <input\r\n matInput\r\n type=\"text\"\r\n [placeholder]=\"label()\"\r\n [formControl]=\"lookup\"\r\n [matAutocomplete]=\"lookupAuto\"\r\n />\r\n </mat-form-field>\r\n <button\r\n type=\"button\"\r\n mat-icon-button\r\n (click)=\"clear()\"\r\n [disabled]=\"!entry()\"\r\n matTooltip=\"Clear\"\r\n >\r\n <mat-icon class=\"mat-warn\">clear</mat-icon>\r\n </button>\r\n</form>\r\n","import { ChangeDetectionStrategy, Component, input, computed } from '@angular/core';\r\n\r\nimport {\r\n Thesaurus,\r\n FacetDefinition,\r\n PartTypeIds,\r\n ThesaurusEntry,\r\n} from '@myrmidon/cadmus-core';\r\nimport { FacetService } from '@myrmidon/cadmus-api';\r\nimport { MatTooltip } from '@angular/material/tooltip';\r\n\r\nimport { ColorToContrastPipe } from '@myrmidon/ngx-tools';\r\n\r\nexport enum PartBadgeType {\r\n partAndRole = 0,\r\n partOnly = 1,\r\n roleOnly = 2,\r\n}\r\n\r\n/**\r\n * Function used to get the part's human-friendly name from its ID and role ID.\r\n * This assumes that thesaurus entries with role ID specified have form\r\n * partId:roleId.\r\n * @param typeId The part type ID.\r\n * @param roleId The optional role ID.\r\n * @param typeThesaurus The types thesaurus.\r\n * @param noFallback If true, and no thesaurus is provided, return undefined\r\n * rather than the type and role IDs.\r\n * @returns The name.\r\n */\r\nexport function getPartIdName(\r\n typeId: string,\r\n roleId?: string | null,\r\n typeThesaurus?: Thesaurus,\r\n noFallback = false\r\n): string | undefined {\r\n if (!typeThesaurus) {\r\n if (noFallback) {\r\n return undefined;\r\n }\r\n return roleId ? `${typeId} ${roleId}` : typeId;\r\n }\r\n let entry: ThesaurusEntry | undefined;\r\n\r\n // first find partId:roleId if any\r\n if (roleId) {\r\n const suffixedId = `${typeId}:${roleId}`;\r\n entry = typeThesaurus.entries?.find((e) => e.id === suffixedId);\r\n if (entry) {\r\n return entry.value;\r\n }\r\n }\r\n // else find partId alone\r\n entry = typeThesaurus.entries?.find((e) => e.id === typeId);\r\n\r\n return entry ? entry.value : typeId;\r\n}\r\n\r\n/**\r\n * Part badge component. This component displays a badge with the\r\n * part's type name and role name, if any, and a background color.\r\n */\r\n@Component({\r\n selector: 'cadmus-part-badge',\r\n imports: [MatTooltip, ColorToContrastPipe],\r\n templateUrl: './part-badge.component.html',\r\n styleUrls: ['./part-badge.component.css'],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n})\r\nexport class PartBadgeComponent {\r\n /**\r\n * The badge type: 0=part and role, 1=part only, 2=role only.\r\n */\r\n public readonly badgeType = input<PartBadgeType>(PartBadgeType.partAndRole);\r\n\r\n /**\r\n * The types thesaurus.\r\n */\r\n public readonly typeThesaurus = input<Thesaurus>();\r\n\r\n /**\r\n * The part's facet definition.\r\n */\r\n public readonly facetDefinition = input<FacetDefinition>();\r\n\r\n /**\r\n * The part type IDs.\r\n */\r\n public readonly partTypeIds = input<PartTypeIds>();\r\n\r\n /**\r\n * The part type name.\r\n */\r\n public readonly typeName = computed(() => {\r\n const partTypeIds = this.partTypeIds();\r\n const typeThesaurus = this.typeThesaurus();\r\n\r\n if (!partTypeIds) {\r\n return undefined;\r\n }\r\n\r\n return getPartIdName(partTypeIds.typeId, partTypeIds.roleId, typeThesaurus);\r\n });\r\n\r\n /**\r\n * The part role name.\r\n */\r\n public readonly roleName = computed(() => {\r\n const partTypeIds = this.partTypeIds();\r\n const typeThesaurus = this.typeThesaurus();\r\n\r\n if (!partTypeIds) {\r\n return undefined;\r\n }\r\n\r\n return this.getRoleIdName(partTypeIds.roleId, typeThesaurus);\r\n });\r\n\r\n /**\r\n * The part badge color.\r\n */\r\n public readonly color = computed(() => {\r\n const partTypeIds = this.partTypeIds();\r\n const facetDefinition = this.facetDefinition();\r\n\r\n if (!partTypeIds) {\r\n return 'transparent';\r\n }\r\n\r\n return this.getPartColor(\r\n partTypeIds.typeId,\r\n partTypeIds.roleId,\r\n facetDefinition\r\n );\r\n });\r\n\r\n /**\r\n * The part definition matching the part type ID and role ID.\r\n */\r\n public readonly partDefinition = computed(() => {\r\n const partTypeIds = this.partTypeIds();\r\n const facetDefinition = this.facetDefinition();\r\n\r\n if (!partTypeIds || !facetDefinition?.partDefinitions) {\r\n return undefined;\r\n }\r\n\r\n // First try to find exact match with typeId:roleId\r\n if (partTypeIds.roleId) {\r\n const exactMatch = facetDefinition.partDefinitions.find(\r\n (pd) => pd.typeId === `${partTypeIds.typeId}:${partTypeIds.roleId}`\r\n );\r\n if (exactMatch) {\r\n return exactMatch;\r\n }\r\n }\r\n\r\n // Fallback to match by typeId only\r\n return facetDefinition.partDefinitions.find(\r\n (pd) => pd.typeId === partTypeIds.typeId\r\n );\r\n });\r\n\r\n constructor(private _facetService: FacetService) {}\r\n\r\n private getPartColor(\r\n typeId: string,\r\n roleId?: string,\r\n facetDefinition?: FacetDefinition\r\n ): string {\r\n if (!facetDefinition) {\r\n return 'transparent';\r\n }\r\n return this._facetService.getPartColor(typeId, roleId, facetDefinition);\r\n }\r\n\r\n /**\r\n * Get the role's human-friendly name from its ID.\r\n * @param roleId The role ID.\r\n * @param typeThesaurus The types thesaurus.\r\n * @returns The name or undefined.\r\n */\r\n private getRoleIdName(\r\n roleId?: string,\r\n typeThesaurus?: Thesaurus\r\n ): string | undefined {\r\n if (!roleId || !typeThesaurus) {\r\n return roleId;\r\n }\r\n let entry: ThesaurusEntry | undefined;\r\n\r\n // first find full roleId with optional suffix\r\n entry = typeThesaurus.entries?.find((e) => e.id === roleId);\r\n if (entry) {\r\n return entry.value;\r\n }\r\n\r\n // else strip :suffix if any and find\r\n const i = roleId.lastIndexOf(':');\r\n if (i > -1) {\r\n roleId = roleId.substring(0, i);\r\n }\r\n entry = typeThesaurus.entries?.find((e) => e.id === roleId);\r\n return entry ? entry.value : roleId;\r\n }\r\n}\r\n","@if (badgeType() !== 2) {\r\n<span\r\n class=\"part-badge\"\r\n [style.background-color]=\"color()\"\r\n [style.color]=\"color() | colorToContrast\"\r\n [matTooltip]=\"partDefinition()?.description\"\r\n>\r\n {{ typeName() }}\r\n</span>\r\n} @if (badgeType() !== 1 && roleName()) {\r\n<span class=\"role-badge\">\r\n {{ roleName() }}\r\n</span>\r\n}\r\n","import {\r\n Component,\r\n Injector,\r\n OnDestroy,\r\n OnInit,\r\n output,\r\n input,\r\n effect,\r\n model,\r\n computed,\r\n inject,\r\n signal,\r\n} from '@angular/core';\r\nimport {\r\n FormBuilder,\r\n FormGroup,\r\n PristineChangeEvent,\r\n UntypedFormGroup,\r\n} from '@angular/forms';\r\nimport { Subscription } from 'rxjs';\r\n\r\nimport { deepCopy } from '@myrmidon/ngx-tools';\r\nimport { AuthJwtService, User } from '@myrmidon/auth-jwt-login';\r\nimport { AppRepository } from '@myrmidon/cadmus-state';\r\n\r\nimport {\r\n EditedObject,\r\n Fragment,\r\n FragmentIdentity,\r\n Part,\r\n PartIdentity,\r\n} from '@myrmidon/cadmus-core';\r\nimport { getPartIdName } from './part-badge/part-badge.component';\r\n\r\n/**\r\n * Base class for part/fragment editors dumb components.\r\n * The model type is the templated argument T.\r\n *\r\n * When deriving from this editor, be sure to call super.ngOnInit()\r\n * from the derived editor's ngOnInit handler.\r\n */\r\n@Component({\r\n template: '',\r\n standalone: false,\r\n})\r\nexport abstract class ModelEditorComponentBase<T extends Part | Fragment>\r\n implements OnInit, OnDestroy\r\n{\r\n private readonly _mebSubs: Subscription[] = [];\r\n private readonly _injector = inject(Injector);\r\n protected readonly _appRepository?: AppRepository;\r\n\r\n /**\r\n * The root form of the editor.\r\n */\r\n public form: FormGroup | UntypedFormGroup;\r\n\r\n /**\r\n * The current user.\r\n */\r\n public user?: User;\r\n\r\n /**\r\n * The user authorization level (0-4).\r\n */\r\n public userLevel: number;\r\n\r\n /**\r\n * A signal with the current dirty state of the editor.\r\n */\r\n public readonly isDirty = signal<boolean>(false);\r\n\r\n /**\r\n * The identity of the edited model.\r\n */\r\n public readonly identity = input<PartIdentity | FragmentIdentity>();\r\n\r\n /**\r\n * The data being edited.\r\n */\r\n public readonly data = model<EditedObject<T>>();\r\n\r\n /**\r\n * True to disable the editor.\r\n */\r\n public readonly disabled = input<boolean>();\r\n\r\n /**\r\n * Event emitted when the dirty state has changed.\r\n * This event just reflects changes in isDirty$, and is a facility\r\n * for propagating it to the parent's component.\r\n */\r\n public readonly dirtyChange = output<boolean>();\r\n\r\n /**\r\n * Emitted when the user requests to close the editor.\r\n */\r\n public readonly editorClose = output();\r\n\r\n /**\r\n * The human-friendly model name. This is computed from the model's\r\n * type ID and role ID, if any, using the types thesaurus set provided\r\n * by the app repository.\r\n */\r\n public readonly modelName = computed<string | undefined>(() => {\r\n const identity = this.identity();\r\n // layers have no identity but have a layerPart\r\n if (!identity) {\r\n const layerPart = this.data()?.layerPart;\r\n if (layerPart) {\r\n return getPartIdName(\r\n layerPart.typeId,\r\n layerPart.roleId,\r\n this._appRepository?.getTypeThesaurus(),\r\n true // no fallback so that the part template can use its default name\r\n );\r\n }\r\n return undefined;\r\n }\r\n if (!identity) {\r\n return undefined;\r\n }\r\n return getPartIdName(\r\n identity.typeId,\r\n identity.roleId,\r\n this._appRepository?.getTypeThesaurus(),\r\n true // no fallback so that the part template can use its default name\r\n );\r\n });\r\n\r\n /**\r\n * Create a new instance of the editor.\r\n *\r\n * @param authService The authentication service.\r\n * @param formBuilder Form builder.\r\n */\r\n constructor(\r\n protected authService: AuthJwtService,\r\n protected formBuilder: FormBuilder\r\n ) {\r\n this.form = formBuilder.group({});\r\n this.userLevel = 0;\r\n this._appRepository = inject(AppRepository);\r\n\r\n effect(() => {\r\n this.disableForm(this.disabled());\r\n });\r\n effect(() => {\r\n this.onDataSet(this.data());\r\n });\r\n effect(() => {\r\n this.onIdentitySet(this.identity());\r\n });\r\n }\r\n\r\n private disableForm(disabled?: boolean) {\r\n if (disabled) {\r\n this.form.disable();\r\n } else {\r\n this.form.enable();\r\n }\r\n }\r\n\r\n private onIdentitySet(identity?: PartIdentity | FragmentIdentity) {\r\n if (identity?.partId) {\r\n const part = this.data()?.value as Part;\r\n if (part && !part.id) {\r\n console.log('part identity set', identity.partId);\r\n part.id = identity.partId;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Initialize automatic settings loading for this editor. Call this from\r\n * the derived class constructor to opt into settings loading. When\r\n * identity becomes available, settings are fetched using the specified\r\n * type ID and the role ID from identity.\r\n *\r\n * @param typeId The part/fragment type ID for settings lookup.\r\n * @param callback Called when settings are loaded (or with undefined\r\n * if not found or on error).\r\n */\r\n protected initSettings<S>(\r\n typeId: string,\r\n callback: (settings: S | undefined) => void\r\n ): void {\r\n effect(\r\n () => {\r\n const identity = this.identity();\r\n if (!identity || !this._appRepository) return;\r\n this._appRepository\r\n .getSettingFor<S>(typeId, identity.roleId || undefined)\r\n .then((settings) => callback(settings))\r\n .catch((err) => {\r\n console.warn(`Failed to load settings for ${typeId}:`, err);\r\n callback(undefined);\r\n });\r\n },\r\n { injector: this._injector }\r\n );\r\n }\r\n\r\n public ngOnInit(): void {\r\n // form\r\n this.form = this.buildForm(this.formBuilder);\r\n\r\n // dirty check on form\r\n this._mebSubs.push(\r\n this.form.events.subscribe((e) => {\r\n if (e instanceof PristineChangeEvent) {\r\n this.isDirty.set(!e.pristine);\r\n this.dirtyChange.emit(!e.pristine);\r\n }\r\n })\r\n );\r\n\r\n // auth service\r\n this.userLevel = this.getCurrentUserLevel();\r\n this._mebSubs.push(\r\n this.authService.currentUser$.subscribe((user: User | null) => {\r\n this.updateUserProperties(user);\r\n })\r\n );\r\n }\r\n\r\n public ngOnDestroy(): void {\r\n this._mebSubs.forEach((s) => s.unsubscribe());\r\n }\r\n\r\n /**\r\n * Implement in the derived class to build the root form of this editor.\r\n * The form built will then be attached to the dirty check mechanism\r\n * provided by this base class.\r\n *\r\n * @param formBuilder The form builder.\r\n */\r\n protected abstract buildForm(\r\n formBuilder: FormBuilder\r\n ): FormGroup | UntypedFormGroup;\r\n\r\n /**\r\n * Get the authorization level of the current user if any.\r\n * @returns 4-1 for admin, editor, operator, visitor; else 0.\r\n */\r\n private getCurrentUserLevel(): number {\r\n const user = this.authService.currentUserValue;\r\n if (!user || !user.roles) {\r\n return 0;\r\n }\r\n if (user.roles.indexOf('admin') > -1) {\r\n return 4;\r\n }\r\n if (user.roles.indexOf('editor') > -1) {\r\n return 3;\r\n }\r\n if (user.roles.indexOf('operator') > -1) {\r\n return 2;\r\n }\r\n if (user.roles.indexOf('visitor') > -1) {\r\n return 1;\r\n }\r\n return 0;\r\n }\r\n\r\n private updateUserProperties(user: User | null): void {\r\n if (!user) {\r\n this.user = undefined;\r\n this.userLevel = 0;\r\n } else {\r\n this.user = user;\r\n this.userLevel = this.getCurrentUserLevel();\r\n }\r\n }\r\n\r\n /**\r\n * Update the data value property and emit the corresponding\r\n * modelChange event.\r\n *\r\n * @param value The value.\r\n */\r\n protected updateValue(value: T): void {\r\n this.data.set({ ...(this.data() || { thesauri: {} }), value: value });\r\n }\r\n\r\n /**\r\n * Invoked whenever the model property is set (=data comes from input model\r\n * property), unless setting it via updateModel. Implement to update the form\r\n * controls to reflect the new model data.\r\n *\r\n * @param data The data set, or undefined.\r\n */\r\n protected abstract onDataSet(data?: EditedObject<T>): void;\r\n\r\n /**\r\n * Get a new object from the edited part if any, else as a new part.\r\n *\r\n * @param typeId The part's type ID. This is a constant received\r\n * from the implementor.\r\n * @returns Part object.\r\n */\r\n protected getEditedPart(typeId: string): Part {\r\n const part = deepCopy(this.data()?.value) as Part | null;\r\n return (\r\n part || {\r\n itemId: this.identity()!.itemId || '',\r\n id: '',\r\n typeId: typeId,\r\n roleId: this.identity()!.roleId || undefined,\r\n timeCreated: new Date(),\r\n creatorId: '',\r\n timeModified: new Date(),\r\n userId: '',\r\n }\r\n );\r\n }\r\n\r\n /**\r\n * Get a new object from the edited fragment if any, else a new fragment.\r\n *\r\n * @returns Fragment object.\r\n */\r\n protected getEditedFragment(): Fragment {\r\n const fr = deepCopy(this.data()?.value) as Fragment | null;\r\n return (\r\n fr || {\r\n location: (this.identity() as FragmentIdentity).loc,\r\n }\r\n );\r\n }\r\n\r\n /**\r\n * Implement in derived classes to get the data from form's controls.\r\n * This is used when saving.\r\n */\r\n protected abstract getValue(): T;\r\n\r\n /**\r\n * True if this editor has the thesaurus having the specified key in the\r\n * loaded thesauri set.\r\n */\r\n protected hasThesaurus(key: string): boolean {\r\n return this.data()?.thesauri && this.data()!.thesauri[key] ? true : false;\r\n }\r\n\r\n /**\r\n * Emit a request to close the editor.\r\n */\r\n public close(): void {\r\n this.editorClose.emit();\r\n }\r\n\r\n /**\r\n * Save the edited data if valid.\r\n */\r\n public save(): void {\r\n if (this.form.invalid) {\r\n console.warn('Save invoked with invalid form');\r\n return;\r\n }\r\n const value = this.getValue();\r\n this.updateValue(value);\r\n // the form is no more dirty\r\n this.form.markAsPristine();\r\n }\r\n}\r\n","import {\r\n AbstractControl,\r\n ValidatorFn,\r\n ValidationErrors,\r\n FormGroup,\r\n UntypedFormGroup,\r\n} from '@angular/forms';\r\n\r\n// https://www.tektutorialshub.com/angular/custom-validator-with-parameters-in-angular/\r\n\r\n/**\r\n * General-purpose custom validators.\r\n */\r\n// https://github.com/angular/angular/issues/18867#issuecomment-357484102\r\n// @dynamic\r\nexport class CustomValidators {\r\n /**\r\n * Validates a FormGroup or FormArray control checking if the count of their\r\n * controls with a true value is equal to or greater than the specified\r\n * number.\r\n *\r\n * @param min The minimum number of checked controls.\r\n */\r\n public static minChecked(min = 1): ValidatorFn {\r\n return (control: AbstractControl): ValidationErrors | null => {\r\n // https://trungk18.com/experience/angular-form-array-validate-at-least-one-checkbox-was-selected/\r\n let checked = 0;\r\n\r\n const group = (control as FormGroup) || (control as UntypedFormGroup);\r\n Object.keys(group.controls).forEach((key) => {\r\n const ctl = group.controls[key];\r\n if (ctl.value === true) {\r\n checked++;\r\n }\r\n });\r\n\r\n if (checked < min) {\r\n return {\r\n minChecked: true,\r\n };\r\n }\r\n return null;\r\n };\r\n }\r\n}\r\n","import { AbstractControl } from '@angular/forms';\r\n\r\n/**\r\n * Simple JSON validator.\r\n */\r\nexport class JsonValidators {\r\n public static json(\r\n control: AbstractControl\r\n ): { [key: string]: boolean } | null {\r\n if (!control.value) {\r\n // we allow empty code\r\n return null;\r\n }\r\n try {\r\n JSON.parse(control.value);\r\n } catch (e) {\r\n return { json: true };\r\n }\r\n return null;\r\n }\r\n}\r\n","import { Injectable } from '@angular/core';\nimport { map, Observable } from 'rxjs';\n\nimport { DataPage } from '@myrmidon/ngx-tools';\n\nimport { UserService } from '@myrmidon/cadmus-api';\nimport {\n RefLookupFilter,\n RefLookupService,\n} from '@myrmidon/cadmus-refs-lookup';\n\nexport interface UserWithRoles {\n user: {\n id: string;\n firstName: string;\n lastName: string;\n userName: string;\n email: string;\n };\n roles: string[];\n}\n\n/**\n * Service for users lookup.\n */\n@Injectable({\n providedIn: 'root',\n})\nexport class UserRefLookupService implements RefLookupService {\n public readonly id = 'user';\n\n constructor(private _userService: UserService) {}\n\n public lookup(\n filter: RefLookupFilter,\n options?: any,\n ): Observable<UserWithRoles[]> {\n return this._userService\n .getUsers(\n {\n name: filter.text,\n },\n 1,\n filter.limit,\n )\n .pipe(\n map((page: DataPage<UserWithRoles>) => {\n return page.items;\n }),\n );\n }\n\n public getById(id: string): Observable<UserWithRoles | undefined> {\n return this._userService\n .getUser(id)\n .pipe(map((user) => user as UserWithRoles | undefined));\n }\n\n public getName(item: UserWithRoles): string {\n return item?.user?.userName;\n }\n}\n","// https://github.com/angular/angular/issues/10887\r\n\r\nimport { AbstractControl } from '@angular/forms';\r\nimport { Observable, Subject } from 'rxjs';\r\n\r\n/**\r\n * Extract arguments of function\r\n */\r\nexport type ArgumentsType<F> = F extends (...args: infer A) => any ? A : never;\r\n\r\n/**\r\n * Creates an object like O. Optionally provide minimum set of properties P\r\n * which the objects must share to conform.\r\n */\r\ntype ObjectLike<O extends object, P extends keyof O = keyof O> = Pick<O, P>;\r\n\r\n/**\r\n * Extract a touched changed observable from an abstract control.\r\n * Use in component code like:\r\n * this.touchedChanges$ = extractTouchedChanges(this.form);\r\n *\r\n * @param control AbstractControl-like object with markAsTouched method.\r\n */\r\nexport const extractTouchedChanges = (\r\n control: ObjectLike<AbstractControl, 'markAsTouched' | 'markAsUntouched'>\r\n): Observable<boolean> => {\r\n const prevMarkAsTouched = control.markAsTouched;\r\n const prevMarkAsUntouched = control.markAsUntouched;\r\n\r\n const touchedChanges$ = new Subject<boolean>();\r\n\r\n function nextMarkAsTouched(\r\n ...args: ArgumentsType<AbstractControl['markAsTouched']>\r\n ): void {\r\n touchedChanges$.next(true);\r\n prevMarkAsTouched.bind(control)(...args);\r\n }\r\n\r\n function nextMarkAsUntouched(\r\n ...args: ArgumentsType<AbstractControl['markAsUntouched']>\r\n ): void {\r\n touchedChanges$.next(false);\r\n prevMarkAsUntouched.bind(control)(...args);\r\n }\r\n\r\n control.markAsTouched = nextMarkAsTouched;\r\n control.markAsUntouched = nextMarkAsUntouched;\r\n\r\n return touchedChanges$;\r\n};\r\n\r\n/**\r\n * Extract a pristine changed observable from an abstract control.\r\n * Use in component code like:\r\n * this.pristineChanges$ = extractPristineChanges(this.form);\r\n *\r\n * @param control AbstractControl-like object with markAsPristine and markAsDirty\r\n * methods.\r\n */\r\nexport const extractPristineChanges = (\r\n control: ObjectLike<AbstractControl, 'markAsPristine' | 'markAsDirty'>\r\n): Observable<boolean> => {\r\n const prevMarkAsPristine = control.markAsPristine;\r\n const prevMarkAsDirty = control.markAsDirty;\r\n\r\n const pristineChanges$ = new Subject<boolean>();\r\n\r\n function nextMarkAsPristine(\r\n ...args: ArgumentsType<AbstractControl['markAsPristine']>\r\n ): void {\r\n pristineChanges$.next(true);\r\n prevMarkAsPristine.bind(control)(...args);\r\n }\r\n\r\n function nextMarkAsDirty(\r\n ...args: ArgumentsType<AbstractControl['markAsDirty']>\r\n ): void {\r\n pristineChanges$.next(false);\r\n prevMarkAsDirty.bind(control)(...args);\r\n }\r\n\r\n control.markAsPristine = nextMarkAsPristine;\r\n control.markAsDirty = nextMarkAsDirty;\r\n\r\n return pristineChanges$;\r\n};\r\n","/*\r\n * Public API Surface of cadmus-ui\r\n */\r\n\r\nexport * from './lib/components/close-save-buttons/close-save-buttons.component';\r\nexport * from './lib/components/decorated-token-text/decorated-token-text.component';\r\nexport * from './lib/components/error-list/error-list.component';\r\nexport * from './lib/components/facet-badge/facet-badge.component';\r\nexport * from './lib/components/flags-badge/flags-badge.component';\r\nexport * from './lib/components/layer-hints/layer-hints.component';\r\nexport * from './lib/components/lookup-pin/lookup-pin.component';\r\nexport * from './lib/components/part-badge/part-badge.component';\r\n\r\nexport * from './lib/components/model-editor-component-base';\r\n\r\nexport * from './lib/services/color.service';\r\n\r\nexport * from './lib/validators/custom-validators';\r\nexport * from './lib/validators/json-validators';\r\n\r\nexport * from './lib/services/user-ref-lookup.service';\r\n\r\nexport * from './lib/utils';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i1.ColorService","i1","i2","map"],"mappings":";;;;;;;;;;;;;;;;;;;;;;MAuBa,yBAAyB,CAAA;AAC5B,IAAA,UAAU;AACD,IAAA,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC;IAEjC,IAAI,GAAG,KAAK,CAAA,IAAA,SAAA,GAAA,CAAA,SAAA,EAAA,EAAA,SAAA,EAAA,MAAA,EAAA,CAAA,8BAAA,EAAA,CAAA,CAAgC;IAC5C,MAAM,GAAG,KAAK,CAAA,IAAA,SAAA,GAAA,CAAA,SAAA,EAAA,EAAA,SAAA,EAAA,QAAA,EAAA,CAAA,8BAAA,EAAA,CAAA,CAAW;IACzB,YAAY,GAAG,MAAM,EAAE;AAEvC;;;;AAIG;AACa,IAAA,OAAO,GAAG,MAAM,CAAU,KAAK,8EAAC;AAEhD,IAAA,WAAA,GAAA;;AAEE,QAAA,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,MAAM,IAAI,CAAC,UAAU,EAAE,WAAW,EAAE,CAAC;;QAGhE,MAAM,CAAC,MAAK;AACV,YAAA,IAAI,CAAC,UAAU,EAAE,WAAW,EAAE;AAC9B,YAAA,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE;YACrB,IAAI,CAAC,EAAE;gBACL,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC;gBAC3B,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC,aAAa,CAAC,SAAS,CAAC,MAC1C,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAC5B;YACH;iBAAO;AACL,gBAAA,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC;YACzB;AACF,QAAA,CAAC,CAAC;IACJ;IAEO,KAAK,GAAA;AACV,QAAA,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE;IAC1B;uGApCW,yBAAyB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAzB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,yBAAyB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,2BAAA,EAAA,MAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,MAAA,EAAA,EAAA,iBAAA,EAAA,QAAA,EAAA,UAAA,EAAA,QAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,YAAA,EAAA,cAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,ECvBtC,kcAmBA,EAAA,MAAA,EAAA,CAAA,+FAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EDCY,SAAS,yUAAE,OAAO,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,QAAA,EAAA,SAAA,EAAA,SAAA,EAAA,UAAA,CAAA,EAAA,QAAA,EAAA,CAAA,SAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;2FAGjB,yBAAyB,EAAA,UAAA,EAAA,CAAA;kBAPrC,SAAS;+BACE,2BAA2B,EAAA,OAAA,EAG5B,CAAC,SAAS,EAAE,OAAO,CAAC,EAAA,eAAA,EACZ,uBAAuB,CAAC,MAAM,EAAA,QAAA,EAAA,kcAAA,EAAA,MAAA,EAAA,CAAA,+FAAA,CAAA,EAAA;;;AETjD;;;AAGG;MAQU,2BAA2B,CAAA;AAkBlB,IAAA,iBAAA;AAjBpB;;AAEG;AACa,IAAA,QAAQ,GAAG,KAAK,CAAS,EAAE,+EAAC;AAE5C;;AAEG;AACa,IAAA,SAAS,GAAG,KAAK,CAAkB,EAAE,gFAAC;AAEtD;;AAEG;IACa,gBAAgB,GAAG,KAAK,CAAA,IAAA,SAAA,GAAA,CAAA,SAAA,EAAA,EAAA,SAAA,EAAA,kBAAA,EAAA,CAAA,8BAAA,EAAA,CAAA,CAAiB;AAEzC,IAAA,IAAI,GAAG,MAAM,CAAqB,SAAS,EAAA,IAAA,SAAA,GAAA,CAAA,EAAA,SAAA,EAAA,MAAA,EAAA,CAAA,8BAAA,EAAA,CAAA,CAAC,CAAC;AAE7D,IAAA,WAAA,CAAoB,iBAAmC,EAAA;QAAnC,IAAA,CAAA,iBAAiB,GAAjB,iBAAiB;QACnC,MAAM,CAAC,MAAK;AACV,YAAA,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,IAAI,CAAC,SAAS,EAAE,EAAE,IAAI,CAAC,gBAAgB,EAAE,CAAC;AAC3E,QAAA,CAAC,CAAC;IACJ;AAEQ,IAAA,QAAQ,CACd,IAAY,EACZ,SAA0B,EAC1B,gBAAgC,EAAA;AAEhC,QAAA,IAAI,CAAC,IAAI,CAAC,GAAG,CACX,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,IAAI,EAAE,SAAS,EAAE,gBAAgB,CAAC,CACjE;IACH;uGAhCW,2BAA2B,EAAA,IAAA,EAAA,CAAA,EAAA,KAAA,EAAA,EAAA,CAAA,gBAAA,EAAA,CAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAA3B,2BAA2B,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,6BAAA,EAAA,MAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,SAAA,EAAA,EAAA,iBAAA,EAAA,WAAA,EAAA,UAAA,EAAA,WAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,gBAAA,EAAA,EAAA,iBAAA,EAAA,kBAAA,EAAA,UAAA,EAAA,kBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,ECvBxC,kFACA,EAAA,MAAA,EAAA,CAAA,+XAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,MAAA,EAAA,IAAA,EDmBY,YAAY,EAAA,IAAA,EAAA,UAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;2FAGX,2BAA2B,EAAA,UAAA,EAAA,CAAA;kBAPvC,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,6BAA6B,WAG9B,CAAC,YAAY,CAAC,EAAA,eAAA,EACN,uBAAuB,CAAC,MAAM,EAAA,QAAA,EAAA,kFAAA,EAAA,MAAA,EAAA,CAAA,+XAAA,CAAA,EAAA;;;MEbpC,kBAAkB,CAAA;IACb,MAAM,GAAG,KAAK,CAAA,IAAA,SAAA,GAAA,CAAA,SAAA,EAAA,EAAA,SAAA,EAAA,QAAA,EAAA,CAAA,8BAAA,EAAA,CAAA,CAAY;uGAD/B,kBAAkB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAlB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,kBAAkB,oNCR/B,8IAOA,EAAA,MAAA,EAAA,CAAA,sCAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;2FDCa,kBAAkB,EAAA,UAAA,EAAA,CAAA;kBAN9B,SAAS;+BACE,mBAAmB,EAAA,eAAA,EAGZ,uBAAuB,CAAC,MAAM,EAAA,QAAA,EAAA,8IAAA,EAAA,MAAA,EAAA,CAAA,sCAAA,CAAA,EAAA;;;AEJjD;;AAEG;MAIU,YAAY,CAAA;AACvB;;;;;;;AAOG;AACI,IAAA,MAAM,CAAC,GAAW,EAAA;QACvB,IAAI,CAAC,GAAG,EAAE;AACR,YAAA,OAAO,IAAI;QACb;;QAGA,IAAI,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,oBAAoB,CAAC;AACvC,QAAA,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE;;;YAGb,OAAO;AACL,gBAAA,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,IAAI;AACnC,gBAAA,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,IAAI;AACnC,gBAAA,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,IAAI;aACpC;QACH;;AAEA,QAAA,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,oBAAoB,CAAC;AACnC,QAAA,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE;YACb,OAAO;AACL,gBAAA,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC;AAClC,gBAAA,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC;AAClC,gBAAA,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC;aACnC;QACH;AACA,QAAA,OAAO,IAAI;IACb;AAEA;;;;;;AAMG;AACI,IAAA,gBAAgB,CAAC,GAAW,EAAA;;QAEjC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC;QAC/B,IAAI,CAAC,MAAM,EAAE;AACX,YAAA,OAAO,OAAO;QAChB;QACA,OAAO,MAAM,CAAC,CAAC,CAAC,GAAG,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,KAAK,GAAG;AACjE,cAAE;cACA,OAAO;IACb;AAEA;;;;;;;AAOG;AACI,IAAA,QAAQ,CACb,CAAS,EACT,CAAS,EACT,CAAS,EAAA;;;QAIT,CAAC,IAAI,GAAG;QACR,CAAC,IAAI,GAAG;AAER,QAAA,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EACnC,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAC1C,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,EACb,CAAC,GAAG,CAAC,EACL,CAAC,GAAG,CAAC,EACL,CAAC,GAAG,CAAC;QACP,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE;YACpB,CAAC,GAAG,CAAC;YACL,CAAC,GAAG,CAAC;YACL,CAAC,GAAG,CAAC;QACP;aAAO,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,EAAE;YAC7B,CAAC,GAAG,CAAC;YACL,CAAC,GAAG,CAAC;YACL,CAAC,GAAG,CAAC;QACP;aAAO,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,EAAE;YAC9B,CAAC,GAAG,CAAC;YACL,CAAC,GAAG,CAAC;YACL,CAAC,GAAG,CAAC;QACP;aAAO,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,EAAE;YAC9B,CAAC,GAAG,CAAC;YACL,CAAC,GAAG,CAAC;YACL,CAAC,GAAG,CAAC;QACP;aAAO,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,EAAE;YAC9B,CAAC,GAAG,CAAC;YACL,CAAC,GAAG,CAAC;YACL,CAAC,GAAG,CAAC;QACP;aAAO,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,EAAE;YAC9B,CAAC,GAAG,CAAC;YACL,CAAC,GAAG,CAAC;YACL,CAAC,GAAG,CAAC;QACP;AACA,QAAA,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC;AAC7B,QAAA,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC;AAC7B,QAAA,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC;AAE7B,QAAA,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE;IAC7B;AAEO,IAAA,WAAW,CAAC,CAAS,EAAE,CAAS,EAAE,CAAS,EAAA;QAChD,IAAI,EAAE,GAAG,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC;AACvB,QAAA,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE;AACnB,YAAA,EAAE,GAAG,GAAG,GAAG,EAAE;QACf;QACA,IAAI,EAAE,GAAG,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC;AACvB,QAAA,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE;AACnB,YAAA,EAAE,GAAG,GAAG,GAAG,EAAE;QACf;QACA,IAAI,EAAE,GAAG,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC;AACvB,QAAA,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE;AACnB,YAAA,EAAE,GAAG,GAAG,GAAG,EAAE;QACf;AACA,QAAA,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE;IACrB;AAEA;;;;;;;;AAQG;AACI,IAAA,gBAAgB,CACrB,KAAa,EACb,KAAa,EACb,SAAS,GAAG,IAAI,EAAA;;AAGhB,QAAA,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG,KAAK,IAAI,GAAG,CAAC,CAAC;QAC5C,IAAI,CAAC,GAAG,GAAG;QACX,IAAI,CAAC,GAAG,EAAE;QAEV,IAAI,SAAS,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,EAAE;YACnC,MAAM,IAAI,GAAG,EAAE;AACf,YAAA,IAAI,QAAQ,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,EAAE;YACzC,IAAI,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,QAAQ,CAAC;YACxC,CAAC,IAAI,MAAM;YACX,CAAC,IAAI,MAAM;QACb;AACA,QAAA,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;AAClC,QAAA,OAAO,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;IAC9C;uGA3JW,YAAY,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AAAZ,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,YAAY,cAFX,MAAM,EAAA,CAAA;;2FAEP,YAAY,EAAA,UAAA,EAAA,CAAA;kBAHxB,UAAU;AAAC,YAAA,IAAA,EAAA,CAAA;AACV,oBAAA,UAAU,EAAE,MAAM;AACnB,iBAAA;;;MCYY,mBAAmB,CAAA;AAeV,IAAA,aAAA;AAdZ,IAAA,YAAY;AACZ,IAAA,UAAU;AAEF,IAAA,KAAK,GAAG,MAAM,CAAS,aAAa,4EAAC;AACrC,IAAA,aAAa,GAAG,MAAM,CAAS,OAAO,oFAAC;AACvC,IAAA,GAAG,GAAG,MAAM,CAAqB,SAAS,0EAAC;AAE3D;;AAEG;IACa,IAAI,GAAG,KAAK,CAAiB;AAC3C,QAAA,WAAW,EAAE,EAAE;AAChB,KAAA,EAAA,IAAA,SAAA,GAAA,CAAA,EAAA,SAAA,EAAA,MAAA,EAAA,CAAA,8BAAA,EAAA,CAAA,CAAC;AAEF,IAAA,WAAA,CAAoB,aAA2B,EAAA;QAA3B,IAAA,CAAA,aAAa,GAAb,aAAa;AAC/B,QAAA,IAAI,CAAC,YAAY,GAAG,EAAE;AACtB,QAAA,IAAI,CAAC,UAAU,GAAG,EAAE;QAEpB,MAAM,CAAC,MAAK;YACV,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;AAC/B,QAAA,CAAC,CAAC;IACJ;AAEQ,IAAA,aAAa,CAAC,OAAe,EAAA;AACnC,QAAA,IAAI,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE;AAC9B,YAAA,OAAO,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC;QACnC;QACA,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE;AACpC,YAAA,OAAO,aAAa;QACtB;AAEA,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,KAAI;AAC/C,YAAA,OAAO,CAAC,CAAC,EAAE,KAAK,OAAO;AACzB,QAAA,CAAC,CAAC;AACF,QAAA,IAAI,KAAK,EAAE,QAAQ,EAAE;YACnB,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,GAAG,GAAG,GAAG,KAAK,CAAC,QAAQ;QACnD;aAAO;AACL,YAAA,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,GAAG,aAAa;QAC5C;AACA,QAAA,OAAO,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC;IACnC;AAEQ,IAAA,WAAW,CAAC,OAAe,EAAA;AACjC,QAAA,IAAI,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE;AAC5B,YAAA,OAAO,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;QACjC;QAEA,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE;AACpC,YAAA,OAAO,IAAI;QACb;AAEA,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,KAAI;AAC/C,YAAA,OAAO,CAAC,CAAC,EAAE,KAAK,OAAO;AACzB,QAAA,CAAC,CAAC;QACF,IAAI,CAAC,KAAK,EAAE;AACV,YAAA,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,OAAO;QACpC;aAAO;YACL,MAAM,EAAE,GAAa,EAAE;AACvB,YAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,eAAe,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;AACrD,gBAAA,IAAI,CAAC,GAAG,CAAC,EAAE;AACT,oBAAA,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC;gBACf;AACA,gBAAA,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;gBACtC,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE;AACvC,oBAAA,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC;gBACd;YACF;AACA,YAAA,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACxC;AACA,QAAA,OAAO,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;IACjC;AAEQ,IAAA,WAAW,CAAC,IAAqB,EAAA;AACvC,QAAA,IAAI,CAAC,YAAY,GAAG,EAAE;AACtB,QAAA,IAAI,CAAC,UAAU,GAAG,EAAE;AACpB,QAAA,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,OAAO,IAAI,EAAE,CAAC,CAAC;AACvD,QAAA,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,gBAAgB,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;AACzE,QAAA,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,OAAO,IAAI,EAAE,CAAC,IAAI,SAAS,CAAC;IAClE;uGA/EW,mBAAmB,EAAA,IAAA,EAAA,CAAA,EAAA,KAAA,EAAAA,YAAA,EAAA,CAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAnB,mBAAmB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,oBAAA,EAAA,MAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,ECnBhC,4LAOA,EAAA,MAAA,EAAA,CAAA,kDAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EDSY,UAAU,EAAA,QAAA,EAAA,cAAA,EAAA,MAAA,EAAA,CAAA,oBAAA,EAAA,4BAAA,EAAA,oBAAA,EAAA,qBAAA,EAAA,qBAAA,EAAA,yBAAA,EAAA,YAAA,EAAA,iBAAA,CAAA,EAAA,QAAA,EAAA,CAAA,YAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;2FAGT,mBAAmB,EAAA,UAAA,EAAA,CAAA;kBAP/B,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,oBAAoB,WAGrB,CAAC,UAAU,CAAC,EAAA,eAAA,EACJ,uBAAuB,CAAC,MAAM,EAAA,QAAA,EAAA,4LAAA,EAAA,MAAA,EAAA,CAAA,kDAAA,CAAA,EAAA;;;AEHjD;;;AAGG;MAQU,mBAAmB,CAAA;IACd,IAAI,GAAG,KAAK,CAAA,IAAA,SAAA,GAAA,CAAA,SAAA,EAAA,EAAA,SAAA,EAAA,MAAA,EAAA,CAAA,8BAAA,EAAA,CAAA,CAAkB;AAE9B,IAAA,UAAU,GAAG,MAAM,CAAmB,EAAE,iFAAC;AAEzD,IAAA,WAAA,GAAA;QACE,MAAM,CAAC,MAAK;YACV,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;AAC/B,QAAA,CAAC,CAAC;IACJ;AAEQ,IAAA,WAAW,CAAC,IAAqB,EAAA;QACvC,IAAI,CAAC,IAAI,EAAE;YACT;QACF;AACA,QAAA,IAAI,CAAC,UAAU,CAAC,GAAG,CACjB,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,GAAG,KAAI;;AAE9B,YAAA,OAAO,GAAG,CAAC,EAAE,GAAG,IAAK,CAAC,KAAK;QAC7B,CAAC,CAAC,CACH;IACH;uGArBW,mBAAmB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAnB,mBAAmB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,oBAAA,EAAA,MAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,ECzBhC,8QAWA,EAAA,MAAA,EAAA,CAAA,kDAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EDWY,UAAU,EAAA,QAAA,EAAA,cAAA,EAAA,MAAA,EAAA,CAAA,oBAAA,EAAA,4BAAA,EAAA,oBAAA,EAAA,qBAAA,EAAA,qBAAA,EAAA,yBAAA,EAAA,YAAA,EAAA,iBAAA,CAAA,EAAA,QAAA,EAAA,CAAA,YAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;2FAGT,mBAAmB,EAAA,UAAA,EAAA,CAAA;kBAP/B,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,oBAAoB,WAGrB,CAAC,UAAU,CAAC,EAAA,eAAA,EACJ,uBAAuB,CAAC,MAAM,EAAA,QAAA,EAAA,8QAAA,EAAA,MAAA,EAAA,CAAA,kDAAA,CAAA,EAAA;;;MEWpC,mBAAmB,CAAA;AAgBpB,IAAA,YAAA;AACA,IAAA,cAAA;AAhBM,IAAA,KAAK,GAAG,KAAK,CAAc,EAAE,4EAAC;IAE9B,cAAc,GAAG,KAAK,CAAA,IAAA,SAAA,GAAA,CAAA,SAAA,EAAA,EAAA,SAAA,EAAA,gBAAA,EAAA,CAAA,8BAAA,EAAA,CAAA,CAAU;IAChC,QAAQ,GAAG,KAAK,CAAA,IAAA,SAAA,GAAA,CAAA,SAAA,EAAA,EAAA,SAAA,EAAA,UAAA,EAAA,CAAA,8BAAA,EAAA,CAAA,CAAW;IAC3B,QAAQ,GAAG,KAAK,CAAA,IAAA,SAAA,GAAA,CAAA,SAAA,EAAA,EAAA,SAAA,EAAA,UAAA,EAAA,CAAA,8BAAA,EAAA,CAAA,CAAW;IAE3B,WAAW,GAAG,MAAM,EAAa;IACjC,aAAa,GAAG,MAAM,EAAa;IACnC,WAAW,GAAG,MAAM,EAAa;IACjC,YAAY,GAAG,MAAM,EAAY;AAE1C,IAAA,IAAI;AACJ,IAAA,MAAM;IAEb,WAAA,CACU,YAAyB,EACzB,cAA6B,EAAA;QAD7B,IAAA,CAAA,YAAY,GAAZ,YAAY;QACZ,IAAA,CAAA,cAAc,GAAd,cAAc;QAEtB,IAAI,CAAC,MAAM,GAAG,YAAY,CAAC,KAAK,CAAuB,EAAE,CAAC;AAC1D,QAAA,IAAI,CAAC,IAAI,GAAG,YAAY,CAAC,KAAK,CAAC;YAC7B,MAAM,EAAE,IAAI,CAAC,MAAM;AACpB,SAAA,CAAC;QAEF,MAAM,CAAC,MAAK;YACV,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;AACjC,QAAA,CAAC,CAAC;IACJ;AAEQ,IAAA,YAAY,CAAC,KAAkB,EAAA;AACrC,QAAA,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE;AACnB,QAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;YACrC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3E;IACF;AAEO,IAAA,eAAe,CAAC,IAAe,EAAA;AACpC,QAAA,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC;IAC7B;AAEO,IAAA,iBAAiB,CAAC,IAAe,EAAA;AACtC,QAAA,IAAI,CAAC;aACF,OAAO,CAAC,kBAAkB,EAAE,CAAA,oBAAA,EAAuB,IAAI,CAAC,QAAQ,IAAI;AACpE,aAAA,SAAS,CAAC,CAAC,EAAW,KAAI;YACzB,IAAI,EAAE,EAAE;AACN,gBAAA,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC;YAC/B;AACF,QAAA,CAAC,CAAC;IACN;AAEO,IAAA,eAAe,CAAC,IAAe,EAAA;AACpC,QAAA,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE;YAC1B;QACF;AACA,QAAA,IAAI,CAAC;AACF,aAAA,OAAO,CACN,cAAc,EACd,CAAA,iBAAA,EAAoB,IAAI,CAAC,QAAQ,CAAA,IAAA,EAAO,IAAI,CAAC,cAAc,EAAE,GAAG;AAEjE,aAAA,SAAS,CAAC,CAAC,EAAW,KAAI;YACzB,IAAI,EAAE,EAAE;AACN,gBAAA,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC;YAC7B;AACF,QAAA,CAAC,CAAC;IACN;IAEO,gBAAgB,GAAA;AACrB,QAAA,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;YACrB;QACF;AACA,QAAA,IAAI,CAAC;AACF,aAAA,OAAO,CAAC,eAAe,EAAE,CAAA,6BAAA,CAA+B;AACxD,aAAA,SAAS,CAAC,CAAC,EAAW,KAAI;YACzB,IAAI,EAAE,EAAE;gBACN,MAAM,OAAO,GAAa,EAAE;AAC5B,gBAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;oBAC3C,IAAI,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE;AAC3B,wBAAA,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,cAAe,CAAC;oBAC/C;gBACF;AACA,gBAAA,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC;YACjC;AACF,QAAA,CAAC,CAAC;IACN;uGAnFW,mBAAmB,EAAA,IAAA,EAAA,CAAA,EAAA,KAAA,EAAAC,IAAA,CAAA,WAAA,EAAA,EAAA,EAAA,KAAA,EAAA,EAAA,CAAA,aAAA,EAAA,CAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAnB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,mBAAmB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,oBAAA,EAAA,MAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,cAAA,EAAA,EAAA,iBAAA,EAAA,gBAAA,EAAA,UAAA,EAAA,gBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,WAAA,EAAA,aAAA,EAAA,aAAA,EAAA,eAAA,EAAA,WAAA,EAAA,aAAA,EAAA,YAAA,EAAA,cAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EClChC,0pEA4EA,EAAA,MAAA,EAAA,CAAA,mDAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EDpDI,WAAW,6ZACX,mBAAmB,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,oBAAA,EAAA,QAAA,EAAA,eAAA,EAAA,MAAA,EAAA,CAAA,aAAA,EAAA,UAAA,EAAA,SAAA,CAAA,EAAA,OAAA,EAAA,CAAA,eAAA,CAAA,EAAA,QAAA,EAAA,CAAA,QAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,kBAAA,EAAA,QAAA,EAAA,aAAA,EAAA,MAAA,EAAA,CAAA,WAAA,CAAA,EAAA,OAAA,EAAA,CAAA,UAAA,CAAA,EAAA,QAAA,EAAA,CAAA,QAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACnB,aAAa,EAAA,QAAA,EAAA,sFAAA,EAAA,QAAA,EAAA,CAAA,WAAA,EAAA,WAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACb,UAAU,EAAA,QAAA,EAAA,cAAA,EAAA,MAAA,EAAA,CAAA,oBAAA,EAAA,4BAAA,EAAA,oBAAA,EAAA,qBAAA,EAAA,qBAAA,EAAA,yBAAA,EAAA,YAAA,EAAA,iBAAA,CAAA,EAAA,QAAA,EAAA,CAAA,YAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACV,OAAO,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,QAAA,EAAA,SAAA,EAAA,SAAA,EAAA,UAAA,CAAA,EAAA,QAAA,EAAA,CAAA,SAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACP,WAAW,uYACX,SAAS,EAAA,QAAA,EAAA,iOAAA,EAAA,MAAA,EAAA,CAAA,WAAA,CAAA,EAAA,QAAA,EAAA,CAAA,WAAA,EAAA,WAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;2FAIA,mBAAmB,EAAA,UAAA,EAAA,CAAA;kBAf/B,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,oBAAoB,EAAA,OAAA,EAGrB;wBACP,WAAW;wBACX,mBAAmB;wBACnB,aAAa;wBACb,UAAU;wBACV,OAAO;wBACP,WAAW;wBACX,SAAS;qBACV,EAAA,eAAA,EACgB,uBAAuB,CAAC,MAAM,EAAA,QAAA,EAAA,0pEAAA,EAAA,MAAA,EAAA,CAAA,mDAAA,CAAA,EAAA;;;AEWjD;;;;;;;;;;;AAWG;MAoBU,kBAAkB,CAAA;AAuCnB,IAAA,YAAA;AAEA,IAAA,WAAA;AAxCV;;AAEG;IACa,YAAY,GAAG,KAAK,CAAA,IAAA,SAAA,GAAA,CAAA,SAAA,EAAA,EAAA,SAAA,EAAA,cAAA,EAAA,CAAA,8BAAA,EAAA,CAAA,CAAU;AAE9C;;AAEG;AACa,IAAA,KAAK,GAAG,KAAK,CAAS,EAAE,4EAAC;AAEzC;;;AAGG;AACa,IAAA,KAAK,GAAG,KAAK,CAAS,EAAE,4EAAC;AAEzC;;;;;AAKG;IACa,WAAW,GAAG,KAAK,CAAA,IAAA,SAAA,GAAA,CAAA,SAAA,EAAA,EAAA,SAAA,EAAA,aAAA,EAAA,CAAA,8BAAA,EAAA,CAAA,CAAW;AAE9C;;;AAGG;IACa,WAAW,GAAG,MAAM,EAAsB;AAEnD,IAAA,IAAI;AACJ,IAAA,MAAM;AACN,IAAA,QAAQ;AAEC,IAAA,KAAK,GAAG,MAAM,CAA0B,SAAS,4EAAC;AAElE,IAAA,WAAA,CACE,WAA+B,EACvB,YAAyB,EAEzB,WAAmC,EAAA;QAFnC,IAAA,CAAA,YAAY,GAAZ,YAAY;QAEZ,IAAA,CAAA,WAAW,GAAX,WAAW;;QAGnB,IAAI,CAAC,MAAM,GAAG,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC;AACvC,QAAA,IAAI,CAAC,IAAI,GAAG,WAAW,CAAC,KAAK,CAAC;YAC5B,MAAM,EAAE,IAAI,CAAC,MAAM;AACpB,SAAA,CAAC;QAEF,MAAM,CAAC,MAAK;YACV,OAAO,CAAC,GAAG,CAAC,0BAA0B,EAAE,IAAI,CAAC,YAAY,EAAE,CAAC;AAC5D,YAAA,IAAI,IAAI,CAAC,MAAM,EAAE;gBACf,IAAI,CAAC,cAAc,EAAE;YACvB;AACF,QAAA,CAAC,CAAC;IACJ;AAEA;;;AAGG;IACa,SAAS,GAAG,KAAK,CAAA,IAAA,SAAA,GAAA,CAAA,SAAA,EAAA,EAAA,SAAA,EAAA,WAAA,EAAA,CAAA,8BAAA,EAAA,CAAA,CAAU;IAEpC,QAAQ,GAAA;QACb,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAC3C,YAAY,CAAC,GAAG,CAAC,EACjB,oBAAoB,EAAE,EACtB,SAAS,CAAC,CAAC,KAA2B,KAAI;;AAExC,YAAA,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE;gBAC7B,OAAO,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;YAChD;iBAAO;AACL,gBAAA,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC;YACpB;QACF,CAAC,CAAC,CACH;IACH;IAEQ,aAAa,CACnB,MAAc,EACd,KAAa,EAAA;;QAGb,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,MAAM,EAAE;AAChC,YAAA,OAAO,EAAE,CAAC,EAAE,CAAC;QACf;QACA,MAAM,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,EAAG,CAAC;QAC9C,IAAI,CAAC,EAAE,EAAE;AACP,YAAA,OAAO,EAAE,CAAC,EAAE,CAAC;QACf;;AAGA,QAAA,MAAM,KAAK,GAAG,EAAE,CAAC;AACf,cAAE,CAAA,YAAA,EAAe,EAAE,CAAC,MAAM,CAAA,cAAA,EAAiB,EAAE,CAAC,MAAM,eAAe,EAAE,CAAC,IAAI,CAAA,cAAA,EAAiB,MAAM,CAAA,CAAA;AACjG,cAAE,CAAA,YAAA,EAAe,EAAE,CAAC,MAAM,CAAA,YAAA,EAAe,EAAE,CAAC,IAAI,CAAA,cAAA,EAAiB,MAAM,CAAA,CAAA,CAAG;;QAG5E,OAAO,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC,IAAI,CACvD,GAAG,CAAC,CAAC,CAAsC,KAAI;AAC7C,YAAA,IAAI,CAAC,CAAC,KAAK,EAAE;AACX,gBAAA,OAAO,EAAE;YACX;iBAAO;AACL,gBAAA,OAAO,CAAC,CAAC,KAAK,EAAE,KAAK,IAAI,EAAE;YAC7B;QACF,CAAC,CAAC,CACH;IACH;IAEQ,cAAc,GAAA;QACpB,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,EAAE,EAAE,CAAC;AAC5C,aAAA,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;AACZ,aAAA,SAAS,CAAC,CAAC,OAAO,KAAI;YACrB,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;AAC/D,QAAA,CAAC,CAAC;IACN;IAEO,KAAK,GAAA;AACV,QAAA,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC;AACzB,QAAA,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;AAC1B,QAAA,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC;IAC7B;AAEO,IAAA,WAAW,CAAC,KAAkB,EAAA;QACnC,OAAO,KAAK,EAAE,KAAK;IACrB;AAEO,IAAA,SAAS,CAAC,KAAkB,EAAA;AACjC,QAAA,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC;AACrB,QAAA,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC;AAC5B,QAAA,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE;YACtB,IAAI,CAAC,KAAK,EAAE;QACd;IACF;AApIW,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,kBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,kBAAkB,mFAwCnB,wBAAwB,EAAA,CAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAxCvB,kBAAkB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,mBAAA,EAAA,MAAA,EAAA,EAAA,YAAA,EAAA,EAAA,iBAAA,EAAA,cAAA,EAAA,UAAA,EAAA,cAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,WAAA,EAAA,EAAA,iBAAA,EAAA,aAAA,EAAA,UAAA,EAAA,aAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,SAAA,EAAA,EAAA,iBAAA,EAAA,WAAA,EAAA,UAAA,EAAA,WAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,WAAA,EAAA,aAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EC1E/B,wxBA4BA,EAAA,MAAA,EAAA,CAAA,EAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EDgCI,WAAW,+qBACX,mBAAmB,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,oBAAA,EAAA,QAAA,EAAA,eAAA,EAAA,MAAA,EAAA,CAAA,aAAA,EAAA,UAAA,EAAA,SAAA,CAAA,EAAA,OAAA,EAAA,CAAA,eAAA,CAAA,EAAA,QAAA,EAAA,CAAA,QAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,kBAAA,EAAA,QAAA,EAAA,aAAA,EAAA,MAAA,EAAA,CAAA,WAAA,CAAA,EAAA,OAAA,EAAA,CAAA,UAAA,CAAA,EAAA,QAAA,EAAA,CAAA,QAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACnB,eAAe,EAAA,QAAA,EAAA,kBAAA,EAAA,MAAA,EAAA,CAAA,YAAA,EAAA,iBAAA,EAAA,aAAA,EAAA,uBAAA,EAAA,wBAAA,EAAA,kBAAA,EAAA,YAAA,EAAA,eAAA,EAAA,OAAA,EAAA,8BAAA,CAAA,EAAA,OAAA,EAAA,CAAA,gBAAA,EAAA,QAAA,EAAA,QAAA,EAAA,iBAAA,CAAA,EAAA,QAAA,EAAA,CAAA,iBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACf,SAAS,EAAA,QAAA,EAAA,YAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,IAAA,EAAA,UAAA,CAAA,EAAA,OAAA,EAAA,CAAA,mBAAA,CAAA,EAAA,QAAA,EAAA,CAAA,WAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACT,YAAY,EAAA,QAAA,EAAA,gBAAA,EAAA,MAAA,EAAA,CAAA,oBAAA,EAAA,OAAA,EAAA,YAAA,EAAA,YAAA,EAAA,iBAAA,EAAA,WAAA,CAAA,EAAA,QAAA,EAAA,CAAA,cAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACZ,QAAQ,EAAA,QAAA,EAAA,yHAAA,EAAA,MAAA,EAAA,CAAA,UAAA,EAAA,IAAA,EAAA,aAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,mBAAA,EAAA,kBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,qBAAA,CAAA,EAAA,QAAA,EAAA,CAAA,UAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACR,sBAAsB,EAAA,QAAA,EAAA,mDAAA,EAAA,MAAA,EAAA,CAAA,iBAAA,EAAA,yBAAA,EAAA,4BAAA,EAAA,cAAA,EAAA,yBAAA,CAAA,EAAA,QAAA,EAAA,CAAA,wBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACtB,aAAa,uKACb,UAAU,EAAA,QAAA,EAAA,cAAA,EAAA,MAAA,EAAA,CAAA,oBAAA,EAAA,4BAAA,EAAA,oBAAA,EAAA,qBAAA,EAAA,qBAAA,EAAA,yBAAA,EAAA,YAAA,EAAA,iBAAA,CAAA,EAAA,QAAA,EAAA,CAAA,YAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACV,OAAO,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,QAAA,EAAA,SAAA,EAAA,SAAA,EAAA,UAAA,CAAA,EAAA,QAAA,EAAA,CAAA,SAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,MAAA,EAAA,IAAA,EACP,SAAS,EAAA,IAAA,EAAA,OAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;2FAIA,kBAAkB,EAAA,UAAA,EAAA,CAAA;kBAnB9B,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,mBAAmB,EAAA,OAAA,EAGpB;wBACP,WAAW;wBACX,mBAAmB;wBACnB,eAAe;wBACf,SAAS;wBACT,YAAY;wBACZ,QAAQ;wBACR,sBAAsB;wBACtB,aAAa;wBACb,UAAU;wBACV,OAAO;wBACP,SAAS;qBACV,EAAA,eAAA,EACgB,uBAAuB,CAAC,MAAM,EAAA,QAAA,EAAA,wxBAAA,EAAA;;0BA0C5C,MAAM;2BAAC,wBAAwB;;;IErGxB;AAAZ,CAAA,UAAY,aAAa,EAAA;AACvB,IAAA,aAAA,CAAA,aAAA,CAAA,aAAA,CAAA,GAAA,CAAA,CAAA,GAAA,aAAe;AACf,IAAA,aAAA,CAAA,aAAA,CAAA,UAAA,CAAA,GAAA,CAAA,CAAA,GAAA,UAAY;AACZ,IAAA,aAAA,CAAA,aAAA,CAAA,UAAA,CAAA,GAAA,CAAA,CAAA,GAAA,UAAY;AACd,CAAC,EAJW,aAAa,KAAb,aAAa,GAAA,EAAA,CAAA,CAAA;AAMzB;;;;;;;;;;AAUG;AACG,SAAU,aAAa,CAC3B,MAAc,EACd,MAAsB,EACtB,aAAyB,EACzB,UAAU,GAAG,KAAK,EAAA;IAElB,IAAI,CAAC,aAAa,EAAE;QAClB,IAAI,UAAU,EAAE;AACd,YAAA,OAAO,SAAS;QAClB;AACA,QAAA,OAAO,MAAM,GAAG,CAAA,EAAG,MAAM,CAAA,CAAA,EAAI,MAAM,CAAA,CAAE,GAAG,MAAM;IAChD;AACA,IAAA,IAAI,KAAiC;;IAGrC,IAAI,MAAM,EAAE;AACV,QAAA,MAAM,UAAU,GAAG,CAAA,EAAG,MAAM,CAAA,CAAA,EAAI,MAAM,EAAE;AACxC,QAAA,KAAK,GAAG,aAAa,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,UAAU,CAAC;QAC/D,IAAI,KAAK,EAAE;YACT,OAAO,KAAK,CAAC,KAAK;QACpB;IACF;;AAEA,IAAA,KAAK,GAAG,aAAa,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC;IAE3D,OAAO,KAAK,GAAG,KAAK,CAAC,KAAK,GAAG,MAAM;AACrC;AAEA;;;AAGG;MAQU,kBAAkB,CAAA;AA8FT,IAAA,aAAA;AA7FpB;;AAEG;AACa,IAAA,SAAS,GAAG,KAAK,CAAgB,aAAa,CAAC,WAAW,gFAAC;AAE3E;;AAEG;IACa,aAAa,GAAG,KAAK,CAAA,IAAA,SAAA,GAAA,CAAA,SAAA,EAAA,EAAA,SAAA,EAAA,eAAA,EAAA,CAAA,8BAAA,EAAA,CAAA,CAAa;AAElD;;AAEG;IACa,eAAe,GAAG,KAAK,CAAA,IAAA,SAAA,GAAA,CAAA,SAAA,EAAA,EAAA,SAAA,EAAA,iBAAA,EAAA,CAAA,8BAAA,EAAA,CAAA,CAAmB;AAE1D;;AAEG;IACa,WAAW,GAAG,KAAK,CAAA,IAAA,SAAA,GAAA,CAAA,SAAA,EAAA,EAAA,SAAA,EAAA,aAAA,EAAA,CAAA,8BAAA,EAAA,CAAA,CAAe;AAElD;;AAEG;AACa,IAAA,QAAQ,GAAG,QAAQ,CAAC,MAAK;AACvC,QAAA,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,EAAE;AACtC,QAAA,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,EAAE;QAE1C,IAAI,CAAC,WAAW,EAAE;AAChB,YAAA,OAAO,SAAS;QAClB;AAEA,QAAA,OAAO,aAAa,CAAC,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,aAAa,CAAC;AAC7E,IAAA,CAAC,+EAAC;AAEF;;AAEG;AACa,IAAA,QAAQ,GAAG,QAAQ,CAAC,MAAK;AACvC,QAAA,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,EAAE;AACtC,QAAA,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,EAAE;QAE1C,IAAI,CAAC,WAAW,EAAE;AAChB,YAAA,OAAO,SAAS;QAClB;QAEA,OAAO,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,MAAM,EAAE,aAAa,CAAC;AAC9D,IAAA,CAAC,+EAAC;AAEF;;AAEG;AACa,IAAA,KAAK,GAAG,QAAQ,CAAC,MAAK;AACpC,QAAA,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,EAAE;AACtC,QAAA,MAAM,eAAe,GAAG,IAAI,CAAC,eAAe,EAAE;QAE9C,IAAI,CAAC,WAAW,EAAE;AAChB,YAAA,OAAO,aAAa;QACtB;AAEA,QAAA,OAAO,IAAI,CAAC,YAAY,CACtB,WAAW,CAAC,MAAM,EAClB,WAAW,CAAC,MAAM,EAClB,eAAe,CAChB;AACH,IAAA,CAAC,4EAAC;AAEF;;AAEG;AACa,IAAA,cAAc,GAAG,QAAQ,CAAC,MAAK;AAC7C,QAAA,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,EAAE;AACtC,QAAA,MAAM,eAAe,GAAG,IAAI,CAAC,eAAe,EAAE;QAE9C,IAAI,CAAC,WAAW,IAAI,CAAC,eAAe,EAAE,eAAe,EAAE;AACrD,YAAA,OAAO,SAAS;QAClB;;AAGA,QAAA,IAAI,WAAW,CAAC,MAAM,EAAE;YACtB,MAAM,UAAU,GAAG,eAAe,CAAC,eAAe,CAAC,IAAI,CACrD,CAAC,EAAE,KAAK,EAAE,CAAC,MAAM,KAAK,CAAA,EAAG,WAAW,CAAC,MAAM,CAAA,CAAA,EAAI,WAAW,CAAC,MAAM,CAAA,CAAE,CACpE;YACD,IAAI,UAAU,EAAE;AACd,gBAAA,OAAO,UAAU;YACnB;QACF;;AAGA,QAAA,OAAO,eAAe,CAAC,eAAe,CAAC,IAAI,CACzC,CAAC,EAAE,KAAK,EAAE,CAAC,MAAM,KAAK,WAAW,CAAC,MAAM,CACzC;AACH,IAAA,CAAC,qFAAC;AAEF,IAAA,WAAA,CAAoB,aAA2B,EAAA;QAA3B,IAAA,CAAA,aAAa,GAAb,aAAa;IAAiB;AAE1C,IAAA,YAAY,CAClB,MAAc,EACd,MAAe,EACf,eAAiC,EAAA;QAEjC,IAAI,CAAC,eAAe,EAAE;AACpB,YAAA,OAAO,aAAa;QACtB;AACA,QAAA,OAAO,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,eAAe,CAAC;IACzE;AAEA;;;;;AAKG;IACK,aAAa,CACnB,MAAe,EACf,aAAyB,EAAA;AAEzB,QAAA,IAAI,CAAC,MAAM,IAAI,CAAC,aAAa,EAAE;AAC7B,YAAA,OAAO,MAAM;QACf;AACA,QAAA,IAAI,KAAiC;;AAGrC,QAAA,KAAK,GAAG,aAAa,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC;QAC3D,IAAI,KAAK,EAAE;YACT,OAAO,KAAK,CAAC,KAAK;QACpB;;QAGA,MAAM,CAAC,GAAG,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC;AACjC,QAAA,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE;YACV,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC;QACjC;AACA,QAAA,KAAK,GAAG,aAAa,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC;QAC3D,OAAO,KAAK,GAAG,KAAK,CAAC,KAAK,GAAG,MAAM;IACrC;uGAvIW,kBAAkB,EAAA,IAAA,EAAA,CAAA,EAAA,KAAA,EAAAA,IAAA,CAAA,YAAA,EAAA,CAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAlB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,kBAAkB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,mBAAA,EAAA,MAAA,EAAA,EAAA,SAAA,EAAA,EAAA,iBAAA,EAAA,WAAA,EAAA,UAAA,EAAA,WAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,aAAA,EAAA,EAAA,iBAAA,EAAA,eAAA,EAAA,UAAA,EAAA,eAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,eAAA,EAAA,EAAA,iBAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,iBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,WAAA,EAAA,EAAA,iBAAA,EAAA,aAAA,EAAA,UAAA,EAAA,aAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,ECrE/B,yWAcA,EAAA,MAAA,EAAA,CAAA,2IAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EDkDY,UAAU,4QAAE,mBAAmB,EAAA,IAAA,EAAA,iBAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;2FAK9B,kBAAkB,EAAA,UAAA,EAAA,CAAA;kBAP9B,SAAS;+BACE,mBAAmB,EAAA,OAAA,EACpB,CAAC,UAAU,EAAE,mBAAmB,CAAC,EAAA,eAAA,EAGzB,uBAAuB,CAAC,MAAM,EAAA,QAAA,EAAA,yWAAA,EAAA,MAAA,EAAA,CAAA,2IAAA,CAAA,EAAA;;;AEjCjD;;;;;;AAMG;MAKmB,wBAAwB,CAAA;AA4FhC,IAAA,WAAA;AACA,IAAA,WAAA;IA1FK,QAAQ,GAAmB,EAAE;AAC7B,IAAA,SAAS,GAAG,MAAM,CAAC,QAAQ,CAAC;AAC1B,IAAA,cAAc;AAEjC;;AAEG;AACI,IAAA,IAAI;AAEX;;AAEG;AACI,IAAA,IAAI;AAEX;;AAEG;AACI,IAAA,SAAS;AAEhB;;AAEG;AACa,IAAA,OAAO,GAAG,MAAM,CAAU,KAAK,8EAAC;AAEhD;;AAEG;IACa,QAAQ,GAAG,KAAK,CAAA,IAAA,SAAA,GAAA,CAAA,SAAA,EAAA,EAAA,SAAA,EAAA,UAAA,EAAA,CAAA,8BAAA,EAAA,CAAA,CAAmC;AAEnE;;AAEG;IACa,IAAI,GAAG,KAAK,CAAA,IAAA,SAAA,GAAA,CAAA,SAAA,EAAA,EAAA,SAAA,EAAA,MAAA,EAAA,CAAA,8BAAA,EAAA,CAAA,CAAmB;AAE/C;;AAEG;IACa,QAAQ,GAAG,KAAK,CAAA,IAAA,SAAA,GAAA,CAAA,SAAA,EAAA,EAAA,SAAA,EAAA,UAAA,EAAA,CAAA,8BAAA,EAAA,CAAA,CAAW;AAE3C;;;;AAIG;IACa,WAAW,GAAG,MAAM,EAAW;AAE/C;;AAEG;IACa,WAAW,GAAG,MAAM,EAAE;AAEtC;;;;AAIG;AACa,IAAA,SAAS,GAAG,QAAQ,CAAqB,MAAK;AAC5D,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE;;QAEhC,IAAI,CAAC,QAAQ,EAAE;YACb,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,EAAE,EAAE,SAAS;YACxC,IAAI,SAAS,EAAE;AACb,gBAAA,OAAO,aAAa,CAClB,SAAS,CAAC,MAAM,EAChB,SAAS,CAAC,MAAM,EAChB,IAAI,CAAC,cAAc,EAAE,gBAAgB,EAAE,EACvC,IAAI;iBACL;YACH;AACA,YAAA,OAAO,SAAS;QAClB;QACA,IAAI,CAAC,QAAQ,EAAE;AACb,YAAA,OAAO,SAAS;QAClB;AACA,QAAA,OAAO,aAAa,CAClB,QAAQ,CAAC,MAAM,EACf,QAAQ,CAAC,MAAM,EACf,IAAI,CAAC,cAAc,EAAE,gBAAgB,EAAE,EACvC,IAAI;SACL;AACH,IAAA,CAAC,gFAAC;AAEF;;;;;AAKG;IACH,WAAA,CACY,WAA2B,EAC3B,WAAwB,EAAA;QADxB,IAAA,CAAA,WAAW,GAAX,WAAW;QACX,IAAA,CAAA,WAAW,GAAX,WAAW;QAErB,IAAI,CAAC,IAAI,GAAG,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC;AACjC,QAAA,IAAI,CAAC,SAAS,GAAG,CAAC;AAClB,QAAA,IAAI,CAAC,cAAc,GAAG,MAAM,CAAC,aAAa,CAAC;QAE3C,MAAM,CAAC,MAAK;YACV,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;AACnC,QAAA,CAAC,CAAC;QACF,MAAM,CAAC,MAAK;YACV,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;AAC7B,QAAA,CAAC,CAAC;QACF,MAAM,CAAC,MAAK;YACV,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;AACrC,QAAA,CAAC,CAAC;IACJ;AAEQ,IAAA,WAAW,CAAC,QAAkB,EAAA;QACpC,IAAI,QAAQ,EAAE;AACZ,YAAA,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;QACrB;aAAO;AACL,YAAA,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;QACpB;IACF;AAEQ,IAAA,aAAa,CAAC,QAA0C,EAAA;AAC9D,QAAA,IAAI,QAAQ,EAAE,MAAM,EAAE;YACpB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,EAAE,KAAa;AACvC,YAAA,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE;gBACpB,OAAO,CAAC,GAAG,CAAC,mBAAmB,EAAE,QAAQ,CAAC,MAAM,CAAC;AACjD,gBAAA,IAAI,CAAC,EAAE,GAAG,QAAQ,CAAC,MAAM;YAC3B;QACF;IACF;AAEA;;;;;;;;;AASG;IACO,YAAY,CACpB,MAAc,EACd,QAA2C,EAAA;QAE3C,MAAM,CACJ,MAAK;AACH,YAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE;AAChC,YAAA,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,cAAc;gBAAE;AACvC,YAAA,IAAI,CAAC;iBACF,aAAa,CAAI,MAAM,EAAE,QAAQ,CAAC,MAAM,IAAI,SAAS;iBACrD,IAAI,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,QAAQ,CAAC;AACrC,iBAAA,KAAK,CAAC,CAAC,GAAG,KAAI;gBACb,OAAO,CAAC,IAAI,CAAC,CAAA,4BAAA,EAA+B,MAAM,CAAA,CAAA,CAAG,EAAE,GAAG,CAAC;gBAC3D,QAAQ,CAAC,SAAS,CAAC;AACrB,YAAA,CAAC,CAAC;QACN,CAAC,EACD,EAAE,QAAQ,EAAE,IAAI,CAAC,SAAS,EAAE,CAC7B;IACH;IAEO,QAAQ,GAAA;;QAEb,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC;;AAG5C,QAAA,IAAI,CAAC,QAAQ,CAAC,IAAI,CAChB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,KAAI;AAC/B,YAAA,IAAI,CAAC,YAAY,mBAAmB,EAAE;gBACpC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;gBAC7B,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;YACpC;QACF,CAAC,CAAC,CACH;;AAGD,QAAA,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,mBAAmB,EAAE;AAC3C,QAAA,IAAI,CAAC,QAAQ,CAAC,IAAI,CAChB,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,IAAiB,KAAI;AAC5D,YAAA,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC;QACjC,CAAC,CAAC,CACH;IACH;IAEO,WAAW,GAAA;AAChB,QAAA,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC;IAC/C;AAaA;;;AAGG;IACK,mBAAmB,GAAA;AACzB,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,gBAAgB;QAC9C,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE;AACxB,YAAA,OAAO,CAAC;QACV;AACA,QAAA,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE;AACpC,YAAA,OAAO,CAAC;QACV;AACA,QAAA,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE;AACrC,YAAA,OAAO,CAAC;QACV;AACA,QAAA,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,EAAE;AACvC,YAAA,OAAO,CAAC;QACV;AACA,QAAA,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,EAAE;AACtC,YAAA,OAAO,CAAC;QACV;AACA,QAAA,OAAO,CAAC;IACV;AAEQ,IAAA,oBAAoB,CAAC,IAAiB,EAAA;QAC5C,IAAI,CAAC,IAAI,EAAE;AACT,YAAA,IAAI,CAAC,IAAI,GAAG,SAAS;AACrB,YAAA,IAAI,CAAC,SAAS,GAAG,CAAC;QACpB;aAAO;AACL,YAAA,IAAI,CAAC,IAAI,GAAG,IAAI;AAChB,YAAA,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,mBAAmB,EAAE;QAC7C;IACF;AAEA;;;;;AAKG;AACO,IAAA,WAAW,CAAC,KAAQ,EAAA;QAC5B,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,IAAI,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;IACvE;AAWA;;;;;;AAMG;AACO,IAAA,aAAa,CAAC,MAAc,EAAA;QACpC,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,KAAK,CAAgB;QACxD,QACE,IAAI,IAAI;YACN,MAAM,EAAE,IAAI,CAAC,QAAQ,EAAG,CAAC,MAAM,IAAI,EAAE;AACrC,YAAA,EAAE,EAAE,EAAE;AACN,YAAA,MAAM,EAAE,MAAM;YACd,MAAM,EAAE,IAAI,CAAC,QAAQ,EAAG,CAAC,MAAM,IAAI,SAAS;YAC5C,WAAW,EAAE,IAAI,IAAI,EAAE;AACvB,YAAA,SAAS,EAAE,EAAE;YACb,YAAY,EAAE,IAAI,IAAI,EAAE;AACxB,YAAA,MAAM,EAAE,EAAE;AACX,SAAA;IAEL;AAEA;;;;AAIG;IACO,iBAAiB,GAAA;QACzB,MAAM,EAAE,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,KAAK,CAAoB;QAC1D,QACE,EAAE,IAAI;AACJ,YAAA,QAAQ,EAAG,IAAI,CAAC,QAAQ,EAAuB,CAAC,GAAG;AACpD,SAAA;IAEL;AAQA;;;AAGG;AACO,IAAA,YAAY,CAAC,GAAW,EAAA;QAChC,OAAO,IAAI,CAAC,IAAI,EAAE,EAAE,QAAQ,IAAI,IAAI,CAAC,IAAI,EAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,IAAI,GAAG,KAAK;IAC3E;AAEA;;AAEG;IACI,KAAK,GAAA;AACV,QAAA,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE;IACzB;AAEA;;AAEG;IACI,IAAI,GAAA;AACT,QAAA,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;AACrB,YAAA,OAAO,CAAC,IAAI,CAAC,gCAAgC,CAAC;YAC9C;QACF;AACA,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE;AAC7B,QAAA,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC;;AAEvB,QAAA,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE;IAC5B;uGA/ToB,wBAAwB,EAAA,IAAA,EAAA,CAAA,EAAA,KAAA,EAAAA,IAAA,CAAA,cAAA,EAAA,EAAA,EAAA,KAAA,EAAAC,IAAA,CAAA,WAAA,EAAA,CAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAxB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,wBAAwB,qiBAHlC,EAAE,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA;;2FAGQ,wBAAwB,EAAA,UAAA,EAAA,CAAA;kBAJ7C,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,EAAE;AACZ,oBAAA,UAAU,EAAE,KAAK;AAClB,iBAAA;;;ACpCD;AAEA;;AAEG;AACH;AACA;MACa,gBAAgB,CAAA;AAC3B;;;;;;AAMG;AACI,IAAA,OAAO,UAAU,CAAC,GAAG,GAAG,CAAC,EAAA;QAC9B,OAAO,CAAC,OAAwB,KAA6B;;YAE3D,IAAI,OAAO,GAAG,CAAC;AAEf,YAAA,MAAM,KAAK,GAAI,OAAqB,IAAK,OAA4B;AACrE,YAAA,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,KAAI;gBAC1C,MAAM,GAAG,GAAG,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC;AAC/B,gBAAA,IAAI,GAAG,CAAC,KAAK,KAAK,IAAI,EAAE;AACtB,oBAAA,OAAO,EAAE;gBACX;AACF,YAAA,CAAC,CAAC;AAEF,YAAA,IAAI,OAAO,GAAG,GAAG,EAAE;gBACjB,OAAO;AACL,oBAAA,UAAU,EAAE,IAAI;iBACjB;YACH;AACA,YAAA,OAAO,IAAI;AACb,QAAA,CAAC;IACH;AACD;;AC1CD;;AAEG;MACU,cAAc,CAAA;IAClB,OAAO,IAAI,CAChB,OAAwB,EAAA;AAExB,QAAA,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE;;AAElB,YAAA,OAAO,IAAI;QACb;AACA,QAAA,IAAI;AACF,YAAA,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAC3B;QAAE,OAAO,CAAC,EAAE;AACV,YAAA,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE;QACvB;AACA,QAAA,OAAO,IAAI;IACb;AACD;;ACED;;AAEG;MAIU,oBAAoB,CAAA;AAGX,IAAA,YAAA;IAFJ,EAAE,GAAG,MAAM;AAE3B,IAAA,WAAA,CAAoB,YAAyB,EAAA;QAAzB,IAAA,CAAA,YAAY,GAAZ,YAAY;IAAgB;IAEzC,MAAM,CACX,MAAuB,EACvB,OAAa,EAAA;QAEb,OAAO,IAAI,CAAC;AACT,aAAA,QAAQ,CACP;YACE,IAAI,EAAE,MAAM,CAAC,IAAI;AAClB,SAAA,EACD,CAAC,EACD,MAAM,CAAC,KAAK;AAEb,aAAA,IAAI,CACHC,KAAG,CAAC,CAAC,IAA6B,KAAI;YACpC,OAAO,IAAI,CAAC,KAAK;QACnB,CAAC,CAAC,CACH;IACL;AAEO,IAAA,OAAO,CAAC,EAAU,EAAA;QACvB,OAAO,IAAI,CAAC;aACT,OAAO,CAAC,EAAE;aACV,IAAI,CAACA,KAAG,CAAC,CAAC,IAAI,KAAK,IAAiC,CAAC,CAAC;IAC3D;AAEO,IAAA,OAAO,CAAC,IAAmB,EAAA;AAChC,QAAA,OAAO,IAAI,EAAE,IAAI,EAAE,QAAQ;IAC7B;uGAhCW,oBAAoB,EAAA,IAAA,EAAA,CAAA,EAAA,KAAA,EAAAF,IAAA,CAAA,WAAA,EAAA,CAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AAApB,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,oBAAoB,cAFnB,MAAM,EAAA,CAAA;;2FAEP,oBAAoB,EAAA,UAAA,EAAA,CAAA;kBAHhC,UAAU;AAAC,YAAA,IAAA,EAAA,CAAA;AACV,oBAAA,UAAU,EAAE,MAAM;AACnB,iBAAA;;;AC3BD;AAgBA;;;;;;AAMG;AACI,MAAM,qBAAqB,GAAG,CACnC,OAAyE,KAClD;AACvB,IAAA,MAAM,iBAAiB,GAAG,OAAO,CAAC,aAAa;AAC/C,IAAA,MAAM,mBAAmB,GAAG,OAAO,CAAC,eAAe;AAEnD,IAAA,MAAM,eAAe,GAAG,IAAI,OAAO,EAAW;IAE9C,SAAS,iBAAiB,CACxB,GAAG,IAAqD,EAAA;AAExD,QAAA,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC;QAC1B,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;IAC1C;IAEA,SAAS,mBAAmB,CAC1B,GAAG,IAAuD,EAAA;AAE1D,QAAA,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC;QAC3B,mBAAmB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;IAC5C;AAEA,IAAA,OAAO,CAAC,aAAa,GAAG,iBAAiB;AACzC,IAAA,OAAO,CAAC,eAAe,GAAG,mBAAmB;AAE7C,IAAA,OAAO,eAAe;AACxB;AAEA;;;;;;;AAOG;AACI,MAAM,sBAAsB,GAAG,CACpC,OAAsE,KAC/C;AACvB,IAAA,MAAM,kBAAkB,GAAG,OAAO,CAAC,cAAc;AACjD,IAAA,MAAM,eAAe,GAAG,OAAO,CAAC,WAAW;AAE3C,IAAA,MAAM,gBAAgB,GAAG,IAAI,OAAO,EAAW;IAE/C,SAAS,kBAAkB,CACzB,GAAG,IAAsD,EAAA;AAEzD,QAAA,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC;QAC3B,kBAAkB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;IAC3C;IAEA,SAAS,eAAe,CACtB,GAAG,IAAmD,EAAA;AAEtD,QAAA,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC;QAC5B,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;IACxC;AAEA,IAAA,OAAO,CAAC,cAAc,GAAG,kBAAkB;AAC3C,IAAA,OAAO,CAAC,WAAW,GAAG,eAAe;AAErC,IAAA,OAAO,gBAAgB;AACzB;;ACrFA;;AAEG;;ACFH;;AAEG;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@myrmidon/cadmus-ui",
3
- "version": "16.0.2",
3
+ "version": "16.1.1",
4
4
  "description": "Cadmus - general UI components.",
5
5
  "keywords": [
6
6
  "Cadmus"
@@ -18,7 +18,7 @@
18
18
  "@angular/core": "^20.0.0 || ^21.0.0",
19
19
  "@angular/material": "^20.0.0 || ^21.0.0",
20
20
  "@myrmidon/ngx-tools": "^2.0.2",
21
- "@myrmidon/cadmus-refs-lookup": "^10.0.8",
21
+ "@myrmidon/cadmus-refs-lookup": "^10.0.9",
22
22
  "@myrmidon/cadmus-core": "^12.0.3"
23
23
  },
24
24
  "dependencies": {
@@ -1,19 +1,28 @@
1
1
  import * as _angular_core from '@angular/core';
2
- import { OnInit, ElementRef, OnDestroy } from '@angular/core';
2
+ import { OnInit, OnDestroy } from '@angular/core';
3
3
  import { FormGroup, UntypedFormGroup, FormArray, FormControl, FormBuilder, UntypedFormControl, UntypedFormBuilder, ValidatorFn, AbstractControl } from '@angular/forms';
4
4
  import * as _myrmidon_cadmus_core from '@myrmidon/cadmus-core';
5
5
  import { TokenLocation, TextLayerService, FacetDefinition, FlagDefinition, LayerHint, DataPinInfo, IndexLookupDefinitions, Thesaurus, PartTypeIds, Part, Fragment, PartIdentity, FragmentIdentity, EditedObject } from '@myrmidon/cadmus-core';
6
6
  import { DialogService } from '@myrmidon/ngx-mat-tools';
7
- import { Observable, BehaviorSubject } from 'rxjs';
7
+ import { Observable } from 'rxjs';
8
8
  import { ItemService, FacetService, UserService } from '@myrmidon/cadmus-api';
9
9
  import { AuthJwtService, User } from '@myrmidon/auth-jwt-login';
10
10
  import { AppRepository } from '@myrmidon/cadmus-state';
11
11
  import { RefLookupService, RefLookupFilter } from '@myrmidon/cadmus-refs-lookup';
12
12
 
13
13
  declare class CloseSaveButtonsComponent {
14
+ private _statusSub?;
15
+ private readonly _destroyRef;
14
16
  readonly form: _angular_core.InputSignal<FormGroup<any> | UntypedFormGroup | undefined>;
15
17
  readonly noSave: _angular_core.InputSignal<boolean | undefined>;
16
18
  readonly closeRequest: _angular_core.OutputEmitterRef<void>;
19
+ /**
20
+ * Reactive invalid state: true when the current form is invalid.
21
+ * Derived from the form's statusChanges so that OnPush components
22
+ * re-render whenever validity changes without a reference change.
23
+ */
24
+ readonly invalid: _angular_core.WritableSignal<boolean>;
25
+ constructor();
17
26
  close(): void;
18
27
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<CloseSaveButtonsComponent, never>;
19
28
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<CloseSaveButtonsComponent, "cadmus-close-save-buttons", never, { "form": { "alias": "form"; "required": false; "isSignal": true; }; "noSave": { "alias": "noSave"; "required": false; "isSignal": true; }; }, { "closeRequest": "closeRequest"; }, never, never, true, never>;
@@ -23,9 +32,8 @@ declare class CloseSaveButtonsComponent {
23
32
  * Decorated token-based text visualizer. This is used when editing
24
33
  * token-based text layers.
25
34
  */
26
- declare class DecoratedTokenTextComponent implements OnInit {
35
+ declare class DecoratedTokenTextComponent {
27
36
  private _textLayerService;
28
- _textElement?: ElementRef;
29
37
  /**
30
38
  * The base text.
31
39
  */
@@ -40,7 +48,6 @@ declare class DecoratedTokenTextComponent implements OnInit {
40
48
  readonly selectedLocation: _angular_core.InputSignal<TokenLocation | undefined>;
41
49
  readonly text: _angular_core.WritableSignal<string | undefined>;
42
50
  constructor(_textLayerService: TextLayerService);
43
- ngOnInit(): void;
44
51
  private decorate;
45
52
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<DecoratedTokenTextComponent, never>;
46
53
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<DecoratedTokenTextComponent, "cadmus-decorated-token-text", never, { "baseText": { "alias": "baseText"; "required": false; "isSignal": true; }; "locations": { "alias": "locations"; "required": false; "isSignal": true; }; "selectedLocation": { "alias": "selectedLocation"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
@@ -321,9 +328,9 @@ declare abstract class ModelEditorComponentBase<T extends Part | Fragment> imple
321
328
  */
322
329
  userLevel: number;
323
330
  /**
324
- * An observable with the current dirty state of the editor.
331
+ * A signal with the current dirty state of the editor.
325
332
  */
326
- isDirty$: BehaviorSubject<boolean>;
333
+ readonly isDirty: _angular_core.WritableSignal<boolean>;
327
334
  /**
328
335
  * The identity of the edited model.
329
336
  */