@myrmidon/gve-core 5.0.3 → 6.0.0

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.
@@ -2,180 +2,139 @@ import { MatDialogConfig, MatDialogRef, MatDialog } from '@angular/material/dial
2
2
  import * as _angular_core from '@angular/core';
3
3
  import { OnInit, OnDestroy, ElementRef, AfterViewInit } from '@angular/core';
4
4
  import { FormControl, FormGroup, FormBuilder } from '@angular/forms';
5
- import { GveAnimationTimeline, GveAnimationTween, TweenType, CharNode, Feature, CharChainOperation, OperationFeature, LabeledId, FeatureSetPolicy, SnapshotBase, OperationSource, OperationType, SnapshotViewComponent, Snapshot, SnapshotViewData, GveVisualEvent, SnapshotViewRenderEvent } from '@myrmidon/gve-snapshot-view';
6
5
  import { DialogService } from '@myrmidon/ngx-mat-tools';
7
6
  import { HttpClient } from '@angular/common/http';
8
7
  import { Observable } from 'rxjs';
9
8
  import { ErrorService, EnvService } from '@myrmidon/ngx-tools';
10
9
  import { Clipboard } from '@angular/cdk/clipboard';
11
10
  import { MatSnackBar } from '@angular/material/snack-bar';
11
+ import { GveSnapshotRendition, GveRenditionSettings } from '@myrmidon/gve-snapshot-rendition';
12
12
 
13
13
  /**
14
- * API call result wrapper.
14
+ * A labeled ID. This can be used when a feature is from a closed set,
15
+ * and you want to provide localized or human-readable labels for the
16
+ * possible values.
15
17
  */
16
- interface ResultWrapper<T> {
17
- result?: T;
18
- error?: string;
18
+ interface LabeledId {
19
+ id: string;
20
+ label: string;
19
21
  }
20
22
  /**
21
- * PayloadMatDialogConfig is a MatDialogConfig with a payload, used
22
- * to pass data of type T to a dialog.
23
+ * A generic tree node.
23
24
  */
24
- interface PayloadMatDialogConfig<T> extends MatDialogConfig {
25
+ interface TreeNode<T> {
26
+ label: string;
25
27
  payload?: T;
28
+ parent?: TreeNode<T>;
29
+ children?: TreeNode<T>[];
30
+ isExpanded?: boolean;
26
31
  }
27
-
28
32
  /**
29
- * 🔑 `gve-animation-timeline`
30
- *
31
- * A component to edit an animation timeline.
32
- * Used by the `gve-animation-timeline-set` component.
33
- *
34
- * - ▶️ `timeline` (`GveAnimationTimeline`): the animation timeline to edit.
35
- * - ▶️ `elementIds` (`string[]`): the IDs of the elements that can be selected
36
- * by the tween.
37
- * - ▶️ `tags` (`string[]`): the tags that can be used by the timeline.
38
- * - 🔥 `timelineChange` (`GveAnimationTimeline`): emitted when the timeline
39
- * is changed.
40
- * - 🔥 `timelineCancel` (`void`): emitted when the timeline editing is canceled.
33
+ * Generic name=value feature.
41
34
  */
42
- declare class AnimationTimelineComponent {
43
- /**
44
- * The animation timeline to edit.
45
- */
46
- readonly timeline: _angular_core.ModelSignal<GveAnimationTimeline | undefined>;
47
- /**
48
- * The IDs of the elements that can be selected by the tween.
49
- * This list is used to allow the user to select an element from a dropdown.
50
- */
51
- readonly elementIds: _angular_core.InputSignal<string[] | undefined>;
52
- /**
53
- * The tags that can be used by the timeline.
54
- */
55
- readonly tags: _angular_core.InputSignal<string[]>;
56
- /**
57
- * Emitted when the timeline is changed.
58
- */
59
- readonly timelineChange: _angular_core.OutputEmitterRef<GveAnimationTimeline>;
60
- /**
61
- * Emitted when the timeline editing is canceled.
62
- */
63
- readonly timelineCancel: _angular_core.OutputEmitterRef<void>;
64
- readonly editedTweenIndex: _angular_core.WritableSignal<number>;
65
- readonly editedTween: _angular_core.WritableSignal<GveAnimationTween | undefined>;
66
- tag: FormControl<string>;
67
- tweens: FormControl<GveAnimationTween[]>;
68
- vars: FormControl<string | null>;
69
- form: FormGroup;
70
- constructor(formBuilder: FormBuilder);
71
- private jsonValidator;
72
- private updateForm;
73
- addTween(): void;
74
- editTween(index: number): void;
75
- deleteTween(index: number): void;
76
- closeTween(): void;
77
- saveTween(tween?: GveAnimationTween): void;
78
- moveTweenUp(index: number): void;
79
- moveTweenDown(index: number): void;
80
- private getTimeline;
81
- close(): void;
82
- save(): void;
83
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<AnimationTimelineComponent, never>;
84
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<AnimationTimelineComponent, "gve-animation-timeline", never, { "timeline": { "alias": "timeline"; "required": false; "isSignal": true; }; "elementIds": { "alias": "elementIds"; "required": false; "isSignal": true; }; "tags": { "alias": "tags"; "required": false; "isSignal": true; }; }, { "timeline": "timelineChange"; "timelineChange": "timelineChange"; "timelineCancel": "timelineCancel"; }, never, never, true, never>;
35
+ interface Feature {
36
+ name: string;
37
+ value: string;
38
+ setPolicy: FeatureSetPolicy;
85
39
  }
86
-
87
40
  /**
88
- * 🔑 `gve-animation-timeline-set`
89
- *
90
- * A component to edit a set of animation timelines.
91
- * Used by the `gve-snapshot-editor` component.
92
- *
93
- * - ▶️ `timelines` (`GveAnimationTimeline[]`): the animation timelines to edit.
94
- * - ▶️ `elementIds` (`string[]`): the IDs of the elements that can be selected by the tween.
95
- * - ▶️ `tags` (`string[]`): the tags that can be used by the timeline.
96
- * - 🔥 `timelinesChange` (`GveAnimationTimeline[]`): emitted when the timelines are changed.
97
- * - 🔥 `timelinesCancel` (`void`): emitted when the timeline editing is canceled.
41
+ * Operation feature set policy.
98
42
  */
99
- declare class AnimationTimelineSetComponent {
100
- private _dialogService;
101
- /**
102
- * The animation timelines to edit.
103
- */
104
- readonly timelines: _angular_core.ModelSignal<GveAnimationTimeline[]>;
105
- /**
106
- * The IDs of the elements that can be selected by the tween.
107
- * This list is used to allow the user to select an element from a dropdown.
108
- */
109
- readonly elementIds: _angular_core.InputSignal<string[] | undefined>;
110
- /**
111
- * The tags that can be used by the timeline.
112
- */
113
- readonly tags: _angular_core.InputSignal<string[]>;
114
- /**
115
- * Emitted when the timeline editing is canceled.
116
- */
117
- readonly timelinesCancel: _angular_core.OutputEmitterRef<void>;
118
- readonly editedTimeline: _angular_core.WritableSignal<GveAnimationTimeline | undefined>;
119
- readonly editedIndex: _angular_core.WritableSignal<number>;
120
- constructor(_dialogService: DialogService);
121
- closeTimeline(): void;
122
- newTimeline(): void;
123
- editTimeline(index: number): void;
124
- onTimelineChange(timeline: GveAnimationTimeline): void;
125
- deleteTimeline(index: number): void;
126
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<AnimationTimelineSetComponent, never>;
127
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<AnimationTimelineSetComponent, "gve-animation-timeline-set", never, { "timelines": { "alias": "timelines"; "required": false; "isSignal": true; }; "elementIds": { "alias": "elementIds"; "required": false; "isSignal": true; }; "tags": { "alias": "tags"; "required": false; "isSignal": true; }; }, { "timelines": "timelinesChange"; "timelinesCancel": "timelinesCancel"; }, never, never, true, never>;
43
+ declare enum FeatureSetPolicy {
44
+ multiple = 0,
45
+ single = 1,
46
+ singleFirst = 2
128
47
  }
129
-
130
48
  /**
131
- * 🔑 `gve-animation-tween`
132
- *
133
- * A component to edit an animation tween.
134
- * Used by the `gve-animation-timeline` component.
135
- *
136
- * - ▶️ `tween` (`GveAnimationTween`): the tween to edit.
137
- * - ▶️ `elementIds` (`string[]`): the IDs of the elements that can be selected by the tween.
138
- * - 🔥 `tweenChange` (`GveAnimationTween`): emitted when the tween is changed.
139
- * - 🔥 `tweenCancel` (`void`): emitted when the user cancels the edit.
49
+ * Operation feature.
140
50
  */
141
- declare class AnimationTweenComponent implements OnInit, OnDestroy {
142
- private _sub?;
143
- /**
144
- * The tween to edit.
145
- */
146
- readonly tween: _angular_core.ModelSignal<GveAnimationTween | undefined>;
147
- /**
148
- * The IDs of the elements that can be selected by the tween.
149
- * This list is used to allow the user to select an element from a dropdown.
150
- */
151
- readonly elementIds: _angular_core.InputSignal<string[] | undefined>;
152
- /**
153
- * Emitted when the user cancels the edit.
154
- */
155
- readonly tweenCancel: _angular_core.OutputEmitterRef<void>;
156
- readonly types: string[];
157
- label: FormControl<string>;
158
- note: FormControl<string | null>;
159
- type: FormControl<TweenType>;
160
- selector: FormControl<string>;
161
- vars: FormControl<string>;
162
- vars2: FormControl<string | null>;
163
- position: FormControl<string | null>;
164
- form: FormGroup;
165
- elementId: FormControl<string | null>;
166
- constructor(formBuilder: FormBuilder);
167
- ngOnInit(): void;
168
- ngOnDestroy(): void;
169
- onVarsChange(vars: string): void;
170
- onVars2Change(vars: string): void;
171
- close(): void;
172
- private jsonValidator;
173
- private updateForm;
174
- private getTween;
175
- openUrl(url: string): void;
176
- save(): void;
177
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<AnimationTweenComponent, never>;
178
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<AnimationTweenComponent, "gve-animation-tween", never, { "tween": { "alias": "tween"; "required": false; "isSignal": true; }; "elementIds": { "alias": "elementIds"; "required": false; "isSignal": true; }; }, { "tween": "tweenChange"; "tweenCancel": "tweenCancel"; }, never, never, true, never>;
51
+ interface OperationFeature extends Feature {
52
+ isNegated?: boolean;
53
+ isGlobal?: boolean;
54
+ isShortLived?: boolean;
55
+ }
56
+ /**
57
+ * Source about a text variant. This is typically used when
58
+ * variants come from different witnesses.
59
+ */
60
+ interface OperationSource {
61
+ id: string;
62
+ type: string;
63
+ rank?: number;
64
+ note?: string;
65
+ }
66
+ /**
67
+ * Generic metadata about a text variant generation operation.
68
+ */
69
+ interface OperationMetadata {
70
+ type: OperationType;
71
+ id: string;
72
+ rank?: number;
73
+ groupId?: string;
74
+ features?: OperationFeature[];
75
+ sources?: OperationSource[];
76
+ }
77
+ /**
78
+ * Type of a text operation.
79
+ */
80
+ declare enum OperationType {
81
+ replace = 0,
82
+ delete = 1,
83
+ addBefore = 2,
84
+ addAfter = 3,
85
+ moveBefore = 4,
86
+ moveAfter = 5,
87
+ swap = 6,
88
+ annotate = 7
89
+ }
90
+ /**
91
+ * Metadata of a char-based chain operation.
92
+ */
93
+ interface CharChainOperation extends OperationMetadata {
94
+ at: number;
95
+ atAsIndex?: boolean;
96
+ to?: number;
97
+ toAsIndex?: boolean;
98
+ inputTag?: string;
99
+ outputTag?: string;
100
+ run: number;
101
+ toRun?: number;
102
+ value?: string;
103
+ noTraceFeautures?: boolean;
104
+ dsl?: string;
105
+ }
106
+ /**
107
+ * A single character node in an operation execution result.
108
+ */
109
+ interface CharNode {
110
+ id: number;
111
+ index: number;
112
+ label: string;
113
+ data: string;
114
+ sourceTag?: string;
115
+ features?: Feature[];
116
+ }
117
+ /**
118
+ * A text snapshot, including the base text and the operations that
119
+ * have been applied to it.
120
+ */
121
+ interface Snapshot {
122
+ text: string | CharNode[];
123
+ operations: CharChainOperation[];
124
+ }
125
+ /**
126
+ * API call result wrapper.
127
+ */
128
+ interface ResultWrapper<T> {
129
+ result?: T;
130
+ error?: string;
131
+ }
132
+ /**
133
+ * PayloadMatDialogConfig is a MatDialogConfig with a payload, used
134
+ * to pass data of type T to a dialog.
135
+ */
136
+ interface PayloadMatDialogConfig<T> extends MatDialogConfig {
137
+ payload?: T;
179
138
  }
180
139
 
181
140
  /**
@@ -225,7 +184,7 @@ declare class BaseTextCharComponent {
225
184
  /**
226
185
  * A range in the base text.
227
186
  */
228
- interface VarBaseTextRange {
187
+ interface BaseTextRange {
229
188
  at: number;
230
189
  run: number;
231
190
  }
@@ -233,7 +192,9 @@ interface VarBaseTextRange {
233
192
  * 🔑 `gve-base-text-view`
234
193
  *
235
194
  * A component to display a selectable base text. Its input is either a string or an
236
- * array of `CharNode`'s.
195
+ * array of `CharNode`'s. The base text is the starting text in a set of transformations,
196
+ * and is represented as a sequence of characters with optional metadata.
197
+ * This component allows users to view and select characters or ranges of characters.
237
198
  * Used by the chain result view component and the base text editor component.
238
199
  *
239
200
  * - ▶️ `defaultColor` (`string`): the default color for the text.
@@ -247,10 +208,15 @@ interface VarBaseTextRange {
247
208
  * to each line.
248
209
  * - ▶️ `text` (`string` | `CharNode[]`): the text to display.
249
210
  * - 🔥 `charPick` (`BaseTextCharEvent`): emitted when a character is picked.
250
- * - 🔥 `rangePick` (`VarBaseTextRange`): emitted when a range is picked.
211
+ * - 🔥 `rangePick` (`BaseTextRange`): emitted when a range is picked.
251
212
  */
252
- declare class BaseTextViewComponent {
213
+ declare class BaseTextViewComponent implements OnInit {
214
+ private readonly _destroyRef;
215
+ private readonly _clipboard;
216
+ private readonly _snackBar;
217
+ private readonly _searchSubject;
253
218
  private _lastSelectedPosition?;
219
+ private _selectionAnchor?;
254
220
  /**
255
221
  * The default color for the text.
256
222
  */
@@ -263,10 +229,22 @@ declare class BaseTextViewComponent {
263
229
  * The color for the selected text.
264
230
  */
265
231
  readonly selectionColor: _angular_core.InputSignal<string>;
232
+ /**
233
+ * The color for search match highlights.
234
+ */
235
+ readonly searchHighlightColor: _angular_core.InputSignal<string>;
266
236
  /**
267
237
  * True if line numbers should be displayed next to each line.
268
238
  */
269
239
  readonly hasLineNumber: _angular_core.InputSignal<boolean>;
240
+ /**
241
+ * The search query entered in the toolbar.
242
+ */
243
+ readonly searchQuery: _angular_core.WritableSignal<string>;
244
+ /**
245
+ * The positions of search matches (start and length pairs).
246
+ */
247
+ private readonly searchMatches;
270
248
  /**
271
249
  * The text to display.
272
250
  */
@@ -290,7 +268,7 @@ declare class BaseTextViewComponent {
290
268
  * The range is defined by the starting character and the number of characters.
291
269
  * The range is inclusive.
292
270
  */
293
- readonly rangePick: _angular_core.OutputEmitterRef<VarBaseTextRange>;
271
+ readonly rangePick: _angular_core.OutputEmitterRef<BaseTextRange>;
294
272
  /**
295
273
  * The base characters organized by lines, computed from text input.
296
274
  */
@@ -300,10 +278,12 @@ declare class BaseTextViewComponent {
300
278
  */
301
279
  private readonly selectedRange;
302
280
  /**
303
- * The lines with selection state applied, computed from base lines and selection.
281
+ * The lines with selection or search highlight state applied.
282
+ * Search highlights take priority over selection when present.
304
283
  */
305
284
  readonly lines: _angular_core.Signal<BaseTextChar[][]>;
306
285
  constructor();
286
+ ngOnInit(): void;
307
287
  private buildLines;
308
288
  onCharPick(event: BaseTextCharEvent): void;
309
289
  /**
@@ -316,8 +296,55 @@ declare class BaseTextViewComponent {
316
296
  * Returns the ID or -1 if position is out of bounds.
317
297
  */
318
298
  private getCharIdAtPosition;
299
+ /**
300
+ * Handle search input changes and trigger debounced search.
301
+ */
302
+ onSearchInput(query: string): void;
303
+ /**
304
+ * Perform the actual search and update match positions.
305
+ */
306
+ private performSearch;
307
+ /**
308
+ * Clear the search query and remove search highlights.
309
+ */
310
+ clearSearch(): void;
311
+ /**
312
+ * Get the total number of characters in the text.
313
+ */
314
+ private getTotalCharCount;
315
+ /**
316
+ * Get the character at a specific position.
317
+ */
318
+ private getCharAtPosition;
319
+ /**
320
+ * Handle keyboard events for arrow key navigation.
321
+ * - Left/Right: Move single selection to previous/next character
322
+ * - Shift+Left/Right: Extend selection range
323
+ */
324
+ onKeyDown(event: KeyboardEvent): void;
325
+ /**
326
+ * Copy the currently selected text to the clipboard.
327
+ */
328
+ copySelection(): void;
329
+ /**
330
+ * Copy the currently selected range coordinates to the clipboard.
331
+ * Format: "ID" for single character, "IDxCOUNT" for range.
332
+ */
333
+ copyCoordinates(): void;
334
+ /**
335
+ * Check if there is an active selection.
336
+ */
337
+ readonly hasSelection: _angular_core.Signal<boolean>;
338
+ /**
339
+ * Get the total count of matched characters.
340
+ */
341
+ readonly matchCount: _angular_core.Signal<number>;
342
+ /**
343
+ * Check if a search is active (query is not empty).
344
+ */
345
+ readonly isSearchActive: _angular_core.Signal<boolean>;
319
346
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<BaseTextViewComponent, never>;
320
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<BaseTextViewComponent, "gve-base-text-view", never, { "defaultColor": { "alias": "defaultColor"; "required": false; "isSignal": true; }; "defaultBorderColor": { "alias": "defaultBorderColor"; "required": false; "isSignal": true; }; "selectionColor": { "alias": "selectionColor"; "required": false; "isSignal": true; }; "hasLineNumber": { "alias": "hasLineNumber"; "required": false; "isSignal": true; }; "text": { "alias": "text"; "required": false; "isSignal": true; }; "colorCallback": { "alias": "colorCallback"; "required": false; "isSignal": true; }; "borderColorCallback": { "alias": "borderColorCallback"; "required": false; "isSignal": true; }; }, { "charPick": "charPick"; "rangePick": "rangePick"; }, never, never, true, never>;
347
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<BaseTextViewComponent, "gve-base-text-view", never, { "defaultColor": { "alias": "defaultColor"; "required": false; "isSignal": true; }; "defaultBorderColor": { "alias": "defaultBorderColor"; "required": false; "isSignal": true; }; "selectionColor": { "alias": "selectionColor"; "required": false; "isSignal": true; }; "searchHighlightColor": { "alias": "searchHighlightColor"; "required": false; "isSignal": true; }; "hasLineNumber": { "alias": "hasLineNumber"; "required": false; "isSignal": true; }; "text": { "alias": "text"; "required": false; "isSignal": true; }; "colorCallback": { "alias": "colorCallback"; "required": false; "isSignal": true; }; "borderColorCallback": { "alias": "borderColorCallback"; "required": false; "isSignal": true; }; }, { "charPick": "charPick"; "rangePick": "rangePick"; }, never, never, true, never>;
321
348
  }
322
349
 
323
350
  /**
@@ -337,24 +364,29 @@ declare class BaseTextEditorComponent {
337
364
  * objects.
338
365
  */
339
366
  readonly text: _angular_core.InputSignalWithTransform<CharNode[] | undefined, string | CharNode[] | undefined>;
367
+ /**
368
+ * The IDs of the features that are multi-valued. If a feature being
369
+ * edited is in this list, the feature editor will allow adding multiple
370
+ * values to it. Passed down to feature editors.
371
+ */
372
+ readonly multiValuedFeatureIds: _angular_core.InputSignal<string[] | undefined>;
340
373
  /**
341
374
  * Emitted for the edited text as an array of `CharNode`'s whenever it changes.
342
375
  */
343
376
  readonly textChange: _angular_core.OutputEmitterRef<CharNode[]>;
344
377
  readonly selectedChar: _angular_core.WritableSignal<CharNode | undefined>;
345
378
  readonly selectedCharLabel: _angular_core.WritableSignal<string | undefined>;
346
- readonly textRange: _angular_core.WritableSignal<VarBaseTextRange | undefined>;
379
+ readonly textRange: _angular_core.WritableSignal<BaseTextRange | undefined>;
347
380
  userText: FormControl<string>;
348
381
  form: FormGroup;
349
382
  constructor(formBuilder: FormBuilder, _dialogService: DialogService);
350
383
  private resetSelectedChar;
351
384
  onSelectedChar(event: BaseTextCharEvent): void;
352
385
  onFeaturesChange(features: Feature[]): void;
353
- onRangePick(range: VarBaseTextRange): void;
354
- patchTextFromUser(): void;
386
+ onRangePick(range: BaseTextRange): void;
355
387
  setTextFromUser(): void;
356
388
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<BaseTextEditorComponent, never>;
357
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<BaseTextEditorComponent, "gve-base-text-editor", never, { "text": { "alias": "text"; "required": true; "isSignal": true; }; }, { "textChange": "textChange"; }, never, never, true, never>;
389
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<BaseTextEditorComponent, "gve-base-text-editor", never, { "text": { "alias": "text"; "required": true; "isSignal": true; }; "multiValuedFeatureIds": { "alias": "multiValuedFeatureIds"; "required": false; "isSignal": true; }; }, { "textChange": "textChange"; }, never, never, true, never>;
358
390
  }
359
391
 
360
392
  /**
@@ -399,6 +431,12 @@ interface ChainOperationContextStep {
399
431
  * Result of execution of a char-based chain.
400
432
  */
401
433
  interface CharChainResult {
434
+ /**
435
+ * The base text, as an array of character nodes or string.
436
+ * This is not returned by the API, but can be supplied
437
+ * by the caller for rendering purposes.
438
+ */
439
+ text?: CharNode[] | string;
402
440
  /**
403
441
  * The execution steps of the chain.
404
442
  */
@@ -629,7 +667,7 @@ declare class SettingsService {
629
667
  /**
630
668
  * Features map. This is used for features from closed sets,
631
669
  * and lists the possible values for each feature.
632
- * The key is the feature name, and the value is an array of
670
+ * The key is the feature name's ID, and the value is an array of
633
671
  * labeled IDs representing the allowed values for that feature.
634
672
  */
635
673
  interface FeatureMap {
@@ -651,6 +689,11 @@ interface FeatureMap {
651
689
  * - ▶️ `featValues` (`FeatureMap`): the feature values map. When
652
690
  * specified and the user selects a feature name present in the map keys,
653
691
  * the corresponding values will be used to populate the value selection.
692
+ * - ▶️ `multiValuedFeatureIds` (`string[]`): the IDs of the features that are
693
+ * multi-valued. Used to determine if the current feature being edited should
694
+ * display multi-value controls.
695
+ * - ▶️ `isVar`: true if the feature is a variant operation feature, which
696
+ * has additional properties like negation, global, and short-lived.
654
697
  * - 🔥 `featureChange` (`Feature`): emitted when feature has changed.
655
698
  * - 🔥 `featureCancel`: emitted when the user cancels the feature editing.
656
699
  */
@@ -678,13 +721,20 @@ declare class FeatureEditorComponent implements OnInit, OnDestroy {
678
721
  * additional properties like negation, global, and short-lived.
679
722
  */
680
723
  readonly isVar: _angular_core.InputSignal<boolean>;
724
+ /**
725
+ * The IDs of the features that are multi-valued. Used to determine
726
+ * if the current feature being edited should display multi-value controls.
727
+ */
728
+ readonly multiValuedFeatureIds: _angular_core.InputSignal<string[] | undefined>;
681
729
  /**
682
730
  * Event emitted when the user cancels the feature editing.
683
731
  */
684
732
  readonly featureCancel: _angular_core.OutputEmitterRef<void>;
685
733
  readonly nameIds: _angular_core.WritableSignal<LabeledId[] | undefined>;
734
+ readonly isMultiValued: _angular_core.WritableSignal<boolean>;
686
735
  name: FormControl<string>;
687
736
  value: FormControl<string>;
737
+ selectedValue: FormControl<string>;
688
738
  setPolicy: FormControl<FeatureSetPolicy>;
689
739
  isNegated: FormControl<boolean>;
690
740
  isGlobal: FormControl<boolean>;
@@ -695,10 +745,11 @@ declare class FeatureEditorComponent implements OnInit, OnDestroy {
695
745
  ngOnDestroy(): void;
696
746
  private getLabeledIdsFor;
697
747
  private updateForm;
748
+ addValueToComposite(): void;
698
749
  cancel(): void;
699
750
  save(): void;
700
751
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<FeatureEditorComponent, never>;
701
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<FeatureEditorComponent, "gve-feature-editor", never, { "featNames": { "alias": "featNames"; "required": false; "isSignal": true; }; "featValues": { "alias": "featValues"; "required": false; "isSignal": true; }; "feature": { "alias": "feature"; "required": false; "isSignal": true; }; "isVar": { "alias": "isVar"; "required": false; "isSignal": true; }; }, { "feature": "featureChange"; "featureCancel": "featureCancel"; }, never, never, true, never>;
752
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<FeatureEditorComponent, "gve-feature-editor", never, { "featNames": { "alias": "featNames"; "required": false; "isSignal": true; }; "featValues": { "alias": "featValues"; "required": false; "isSignal": true; }; "feature": { "alias": "feature"; "required": false; "isSignal": true; }; "isVar": { "alias": "isVar"; "required": false; "isSignal": true; }; "multiValuedFeatureIds": { "alias": "multiValuedFeatureIds"; "required": false; "isSignal": true; }; }, { "feature": "featureChange"; "featureCancel": "featureCancel"; }, never, never, true, never>;
702
753
  }
703
754
 
704
755
  /**
@@ -723,7 +774,7 @@ interface FeatureDefinitions {
723
774
  * A component for editing a variant generation operation.
724
775
  * Used by the `gve-snapshot-editor` component.
725
776
  * - ▶️ `operation` (`CharChainOperation`): the operation to edit.
726
- * - ▶️ `snapshot` (`SnapshotBase`): the snapshot the operation refers to.
777
+ * - ▶️ `snapshot` (`Snapshot`): the snapshot the operation refers to.
727
778
  * - ▶️ `hidePreview` (`boolean`): whether to hide the preview request button.
728
779
  * - 🔥 `operationChange` (`CharChainOperation`): emitted when the operation
729
780
  * is changed.
@@ -771,11 +822,8 @@ declare class ChainOperationEditorComponent implements OnInit, OnDestroy {
771
822
  private _clipboard;
772
823
  private _settings;
773
824
  private _dialogService;
774
- private readonly _disposables;
775
825
  private readonly _subs;
776
826
  private readonly _nanoid;
777
- private _editorModel?;
778
- private _editor?;
779
827
  /**
780
828
  * The operation to edit.
781
829
  */
@@ -783,7 +831,7 @@ declare class ChainOperationEditorComponent implements OnInit, OnDestroy {
783
831
  /**
784
832
  * The snapshot the operation refers to.
785
833
  */
786
- readonly snapshot: _angular_core.InputSignal<SnapshotBase | undefined>;
834
+ readonly snapshot: _angular_core.InputSignal<Snapshot | undefined>;
787
835
  /**
788
836
  * Whether to hide the preview request button.
789
837
  */
@@ -793,17 +841,15 @@ declare class ChainOperationEditorComponent implements OnInit, OnDestroy {
793
841
  */
794
842
  readonly featureDefs: _angular_core.InputSignal<FeatureDefinitions | undefined>;
795
843
  /**
796
- * Definitions for element features, including names and values.
797
- */
798
- readonly elementFeatureDefs: _angular_core.InputSignal<FeatureDefinitions | undefined>;
799
- /**
800
- * Definitions for diplomatic features, including names and values.
844
+ * Set when the edited operation's text range is to be patched.
801
845
  */
802
- readonly diplomaticFeatureDefs: _angular_core.InputSignal<FeatureDefinitions | undefined>;
846
+ readonly rangePatch: _angular_core.InputSignal<BaseTextRange | undefined>;
803
847
  /**
804
- * Set when the edited operation's text range is to be patched.
848
+ * The IDs of the features that are multi-valued. If a feature being
849
+ * edited is in this list, the feature editor will allow adding multiple
850
+ * values to it. Passed down to feature editors.
805
851
  */
806
- readonly rangePatch: _angular_core.InputSignal<VarBaseTextRange | undefined>;
852
+ readonly multiValuedFeatureIds: _angular_core.InputSignal<string[] | undefined>;
807
853
  /**
808
854
  * Emitted when the operation is changed.
809
855
  */
@@ -849,24 +895,12 @@ declare class ChainOperationEditorComponent implements OnInit, OnDestroy {
849
895
  ngOnDestroy(): void;
850
896
  private toggleLfEscape;
851
897
  private hasTextChanges;
852
- onCreateEditor(editor: monaco.editor.IEditor): void;
853
898
  onFeaturesChange(features: OperationFeature[]): void;
854
899
  onDpFeaturesChange(features: Feature[]): void;
855
900
  addSource(): void;
856
901
  editSource(index: number): void;
857
902
  closeSource(): void;
858
903
  onSourceChange(source: OperationSource): void;
859
- saveSvg(): void;
860
- openSvgEditor(): void;
861
- loadSvg(): void;
862
- setSvgFromClipboard(): void;
863
- private parseSvg;
864
- removeDecimals(): void;
865
- wrapInGroup(): void;
866
- onTabIndexChange(index: number): void;
867
- editElementFeatures(element: SVGElement): void;
868
- deleteElementFeatures(element: SVGElement): void;
869
- onElementFeaturesChange(features: Feature[]): void;
870
904
  private updateArgsUI;
871
905
  private updateForm;
872
906
  cancel(): void;
@@ -874,7 +908,7 @@ declare class ChainOperationEditorComponent implements OnInit, OnDestroy {
874
908
  requestPreview(): void;
875
909
  save(): void;
876
910
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<ChainOperationEditorComponent, never>;
877
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<ChainOperationEditorComponent, "gve-chain-operation-editor", never, { "operation": { "alias": "operation"; "required": false; "isSignal": true; }; "snapshot": { "alias": "snapshot"; "required": false; "isSignal": true; }; "hidePreview": { "alias": "hidePreview"; "required": false; "isSignal": true; }; "featureDefs": { "alias": "featureDefs"; "required": false; "isSignal": true; }; "elementFeatureDefs": { "alias": "elementFeatureDefs"; "required": false; "isSignal": true; }; "diplomaticFeatureDefs": { "alias": "diplomaticFeatureDefs"; "required": false; "isSignal": true; }; "rangePatch": { "alias": "rangePatch"; "required": false; "isSignal": true; }; }, { "operation": "operationChange"; "operationChange": "operationChange"; "operationPreview": "operationPreview"; "operationCancel": "operationCancel"; }, never, never, true, never>;
911
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<ChainOperationEditorComponent, "gve-chain-operation-editor", never, { "operation": { "alias": "operation"; "required": false; "isSignal": true; }; "snapshot": { "alias": "snapshot"; "required": false; "isSignal": true; }; "hidePreview": { "alias": "hidePreview"; "required": false; "isSignal": true; }; "featureDefs": { "alias": "featureDefs"; "required": false; "isSignal": true; }; "rangePatch": { "alias": "rangePatch"; "required": false; "isSignal": true; }; "multiValuedFeatureIds": { "alias": "multiValuedFeatureIds"; "required": false; "isSignal": true; }; }, { "operation": "operationChange"; "operationChange": "operationChange"; "operationPreview": "operationPreview"; "operationCancel": "operationCancel"; }, never, never, true, never>;
878
912
  }
879
913
 
880
914
  /**
@@ -912,7 +946,7 @@ declare class ChainResultViewComponent implements OnInit, OnDestroy, AfterViewIn
912
946
  readonly step: _angular_core.WritableSignal<ChainOperationContextStep | undefined>;
913
947
  readonly selection: _angular_core.WritableSignal<string | undefined>;
914
948
  readonly selectionFeatures: _angular_core.WritableSignal<OperationFeature[]>;
915
- readonly selectionRange: _angular_core.WritableSignal<VarBaseTextRange | undefined>;
949
+ readonly selectionRange: _angular_core.WritableSignal<BaseTextRange | undefined>;
916
950
  /**
917
951
  * True to disable range picking. For instance the snapshot editor,
918
952
  * which uses rangePick to set the edited operation's range, disables
@@ -922,7 +956,7 @@ declare class ChainResultViewComponent implements OnInit, OnDestroy, AfterViewIn
922
956
  /**
923
957
  * Emitted when a range is picked.
924
958
  */
925
- readonly rangePick: _angular_core.OutputEmitterRef<VarBaseTextRange>;
959
+ readonly rangePick: _angular_core.OutputEmitterRef<BaseTextRange>;
926
960
  versionTag: FormControl<string | null>;
927
961
  tag: FormControl<string | null>;
928
962
  constructor(formBuilder: FormBuilder);
@@ -938,67 +972,13 @@ declare class ChainResultViewComponent implements OnInit, OnDestroy, AfterViewIn
938
972
  private getNodeFeatures;
939
973
  private findNode;
940
974
  onTextCharPick(event: BaseTextCharEvent): void;
941
- onTextRangePick(range: VarBaseTextRange): void;
975
+ onTextRangePick(range: BaseTextRange): void;
942
976
  onStepChange(step?: ChainOperationContextStep): void;
943
977
  pickRange(): void;
944
978
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<ChainResultViewComponent, never>;
945
979
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<ChainResultViewComponent, "gve-chain-result-view", never, { "result": { "alias": "result"; "required": false; "isSignal": true; }; "initialStepIndex": { "alias": "initialStepIndex"; "required": false; "isSignal": true; }; "disabledRangePick": { "alias": "disabledRangePick"; "required": false; "isSignal": true; }; }, { "stepPick": "stepPick"; "rangePick": "rangePick"; }, never, never, true, never>;
946
980
  }
947
981
 
948
- type GraphvizRankdir = 'TB' | 'LR' | 'BT' | 'RL';
949
- declare class GveGraphvizService {
950
- private hashString;
951
- private hslToRgb;
952
- private getColorForTag;
953
- private getExcludedNodeIds;
954
- /**
955
- * Represent the received chain as a Graphviz digraph.
956
- *
957
- * @param chain The source chain if any.
958
- * @param tags The tags to show. When set, only the links with these tags are shown.
959
- * @param rankdir The rank direction.
960
- * @returns Graphviz representation of the chain.
961
- */
962
- generateGraph(chain?: CharChain, tags?: string[], rankdir?: GraphvizRankdir): string;
963
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<GveGraphvizService, never>;
964
- static ɵprov: _angular_core.ɵɵInjectableDeclaration<GveGraphvizService>;
965
- }
966
-
967
- declare class ChainViewComponent implements OnDestroy {
968
- private _graphviz;
969
- private _settings;
970
- private _clipboard;
971
- private _snackbar;
972
- private readonly _sub?;
973
- /**
974
- * The chain to display.
975
- */
976
- readonly chain: _angular_core.InputSignal<CharChain | undefined>;
977
- /**
978
- * The direction of the graph.
979
- */
980
- readonly direction: _angular_core.InputSignal<GraphvizRankdir>;
981
- /**
982
- * All the distinct tags in the chain.
983
- */
984
- readonly tags: _angular_core.Signal<string[]>;
985
- /**
986
- * The tags to show, or empty to show all of them.
987
- */
988
- readonly selectedTags: _angular_core.ModelSignal<string[]>;
989
- /**
990
- * The Graphviz representation of the chain.
991
- */
992
- readonly graph: _angular_core.Signal<string>;
993
- userTags: FormControl<string[]>;
994
- constructor(_graphviz: GveGraphvizService, _settings: SettingsService, _clipboard: Clipboard, _snackbar: MatSnackBar);
995
- ngOnDestroy(): void;
996
- copyGraph(): void;
997
- openExternalEditor(): void;
998
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<ChainViewComponent, never>;
999
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<ChainViewComponent, "gve-chain-view", never, { "chain": { "alias": "chain"; "required": false; "isSignal": true; }; "direction": { "alias": "direction"; "required": false; "isSignal": true; }; "selectedTags": { "alias": "selectedTags"; "required": false; "isSignal": true; }; }, { "selectedTags": "selectedTagsChange"; }, never, never, true, never>;
1000
- }
1001
-
1002
982
  /**
1003
983
  * 🔑 `gve-feature-set-editor`
1004
984
  *
@@ -1017,6 +997,9 @@ declare class ChainViewComponent implements OnDestroy {
1017
997
  * it is always invisible; otherwise, it gets visible when the number of features
1018
998
  * is equal to or greater than the threshold. Default is 5.
1019
999
  * - ▶️ `features` (`Feature[]`): the features to edit.
1000
+ * - ▶️ `multiValuedFeatureIds` (`string[]`): the IDs of the features that are
1001
+ * multi-valued. If a feature being edited is in this list, the feature editor
1002
+ * will allow adding multiple values to it.
1020
1003
  * - ▶️ `isVar`: true if the feature is a variant operation feature, which
1021
1004
  * has additional properties like negation, global, and short-lived.
1022
1005
  * - 🔥 `featuresChange` (`Feature[]`): emitted when features have changed.
@@ -1047,13 +1030,19 @@ declare class FeatureSetEditorComponent implements OnInit, OnDestroy {
1047
1030
  * is greater than or equal to the threshold. Default is 5.
1048
1031
  */
1049
1032
  readonly filterThreshold: _angular_core.InputSignal<number>;
1033
+ /**
1034
+ * The IDs of the features that are multi-valued. If a feature being
1035
+ * edited is in this list, the feature editor will allow adding multiple
1036
+ * values to it.
1037
+ */
1038
+ readonly multiValuedFeatureIds: _angular_core.InputSignal<string[] | undefined>;
1050
1039
  /**
1051
1040
  * The features to edit.
1052
1041
  */
1053
- readonly features: _angular_core.ModelSignal<Feature[] | OperationFeature[]>;
1042
+ readonly features: _angular_core.ModelSignal<OperationFeature[] | Feature[]>;
1054
1043
  readonly editedFeature: _angular_core.WritableSignal<Feature | OperationFeature | undefined>;
1055
1044
  readonly editedFeatureIndex: _angular_core.WritableSignal<number>;
1056
- filteredFeatures: _angular_core.WritableSignal<Feature[] | OperationFeature[]>;
1045
+ filteredFeatures: _angular_core.WritableSignal<OperationFeature[] | Feature[]>;
1057
1046
  filter: FormControl<string | null>;
1058
1047
  constructor(formBuilder: FormBuilder);
1059
1048
  private applyFeatureFilter;
@@ -1062,10 +1051,11 @@ declare class FeatureSetEditorComponent implements OnInit, OnDestroy {
1062
1051
  addFeature(): void;
1063
1052
  editFeature(feature: Feature | OperationFeature): void;
1064
1053
  deleteFeature(feature: Feature | OperationFeature): void;
1054
+ isFeatureMultiValued(feature?: Feature | OperationFeature): boolean;
1065
1055
  onFeatureChange(feature?: Feature | OperationFeature): void;
1066
1056
  onFeatureCancel(): void;
1067
1057
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<FeatureSetEditorComponent, never>;
1068
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<FeatureSetEditorComponent, "gve-feature-set-editor", never, { "isVar": { "alias": "isVar"; "required": false; "isSignal": true; }; "featNames": { "alias": "featNames"; "required": false; "isSignal": true; }; "featValues": { "alias": "featValues"; "required": false; "isSignal": true; }; "filterThreshold": { "alias": "filterThreshold"; "required": false; "isSignal": true; }; "features": { "alias": "features"; "required": false; "isSignal": true; }; }, { "features": "featuresChange"; }, never, never, true, never>;
1058
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<FeatureSetEditorComponent, "gve-feature-set-editor", never, { "isVar": { "alias": "isVar"; "required": false; "isSignal": true; }; "featNames": { "alias": "featNames"; "required": false; "isSignal": true; }; "featValues": { "alias": "featValues"; "required": false; "isSignal": true; }; "filterThreshold": { "alias": "filterThreshold"; "required": false; "isSignal": true; }; "multiValuedFeatureIds": { "alias": "multiValuedFeatureIds"; "required": false; "isSignal": true; }; "features": { "alias": "features"; "required": false; "isSignal": true; }; }, { "features": "featuresChange"; }, never, never, true, never>;
1069
1059
  }
1070
1060
 
1071
1061
  /**
@@ -1090,7 +1080,7 @@ declare class FeatureSetViewComponent {
1090
1080
  /**
1091
1081
  * The features.
1092
1082
  */
1093
- readonly features: _angular_core.InputSignal<Feature[] | OperationFeature[]>;
1083
+ readonly features: _angular_core.InputSignal<OperationFeature[] | Feature[]>;
1094
1084
  /**
1095
1085
  * The list of feature names to display in the name selection.
1096
1086
  * This is used when you have a closed list of features.
@@ -1109,7 +1099,7 @@ declare class FeatureSetViewComponent {
1109
1099
  * is greater than the threshold. Default is 5.
1110
1100
  */
1111
1101
  readonly filterThreshold: _angular_core.InputSignal<number>;
1112
- readonly filteredFeatures: _angular_core.WritableSignal<Feature[] | OperationFeature[]>;
1102
+ readonly filteredFeatures: _angular_core.WritableSignal<OperationFeature[] | Feature[]>;
1113
1103
  filter: FormControl<string | null>;
1114
1104
  constructor(formBuilder: FormBuilder);
1115
1105
  private applyFeatureFilter;
@@ -1119,45 +1109,6 @@ declare class FeatureSetViewComponent {
1119
1109
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<FeatureSetViewComponent, "gve-feature-set-view", never, { "features": { "alias": "features"; "required": false; "isSignal": true; }; "featNames": { "alias": "featNames"; "required": false; "isSignal": true; }; "featValues": { "alias": "featValues"; "required": false; "isSignal": true; }; "filterThreshold": { "alias": "filterThreshold"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
1120
1110
  }
1121
1111
 
1122
- /**
1123
- * 🔑 `gve-ln-heights-editor`
1124
- *
1125
- * A component to edit line heights.
1126
- * Used by the `gve-snapshot-editor` component.
1127
- *
1128
- * - ▶️ `lineCount` (`number`): the number of lines.
1129
- * - ▶️ `heights` (`Record<number, number>`): the line heights.
1130
- * - 🔥 `heightsChange` (`EventEmitter<Record<number, number>>`): the event
1131
- * emitted when the heights change.
1132
- */
1133
- declare class LnHeightsEditorComponent implements OnInit, OnDestroy {
1134
- private _subs?;
1135
- private _heights?;
1136
- lineNumber: FormControl<number>;
1137
- height: FormControl<number>;
1138
- /**
1139
- * The total number of lines in the text.
1140
- */
1141
- readonly lineCount: _angular_core.InputSignal<number>;
1142
- /**
1143
- * The heights map of the lines. Each key is a line number and the value is
1144
- * the height of the line.
1145
- */
1146
- readonly heights: _angular_core.InputSignal<Record<number, number> | undefined>;
1147
- /**
1148
- * The event emitted when the heights change.
1149
- */
1150
- readonly heightsChange: _angular_core.OutputEmitterRef<Record<number, number> | undefined>;
1151
- readonly lineNumbers: _angular_core.Signal<number[]>;
1152
- constructor(formBuilder: FormBuilder);
1153
- private pruneHeights;
1154
- ngOnInit(): void;
1155
- ngOnDestroy(): void;
1156
- reset(): void;
1157
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<LnHeightsEditorComponent, never>;
1158
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<LnHeightsEditorComponent, "gve-ln-heights-editor", never, { "lineCount": { "alias": "lineCount"; "required": false; "isSignal": true; }; "heights": { "alias": "heights"; "required": false; "isSignal": true; }; }, { "heightsChange": "heightsChange"; }, never, never, true, never>;
1159
- }
1160
-
1161
1112
  /**
1162
1113
  * 🔑 `gve-operation-source-editor`
1163
1114
  *
@@ -1222,13 +1173,14 @@ declare class SnapshotEditorComponent {
1222
1173
  private _dialogService;
1223
1174
  private _snackbar;
1224
1175
  private readonly _nanoid;
1225
- private _renderer?;
1226
1176
  private _previewing?;
1227
- private _transparentIds?;
1228
1177
  private _stepPickFrozen?;
1229
- private _handlingOver?;
1230
- private _lastOverId?;
1231
- snapshotView?: ElementRef<SnapshotViewComponent>;
1178
+ /**
1179
+ * Reference to the snapshot rendition web component.
1180
+ * Using viewChild signal to handle conditionally rendered element -
1181
+ * the element only exists when result() is truthy.
1182
+ */
1183
+ readonly renditionRef: _angular_core.Signal<ElementRef<GveSnapshotRendition> | undefined>;
1232
1184
  /**
1233
1185
  * The snapshot to edit.
1234
1186
  */
@@ -1255,49 +1207,32 @@ declare class SnapshotEditorComponent {
1255
1207
  */
1256
1208
  readonly featureDefs: _angular_core.InputSignal<FeatureDefinitions | undefined>;
1257
1209
  /**
1258
- * Definitions for element features, including names and values.
1210
+ * The IDs of the features that are multi-valued. If a feature being
1211
+ * edited is in this list, the feature editor will allow adding multiple
1212
+ * values to it. Passed down to feature editors.
1259
1213
  */
1260
- readonly elementFeatureDefs: _angular_core.InputSignal<FeatureDefinitions | undefined>;
1214
+ readonly multiValuedFeatureIds: _angular_core.InputSignal<string[] | undefined>;
1261
1215
  /**
1262
- * Definitions for diplomatic features, including names and values.
1216
+ * Settings for rendering the snapshot. These are passed to the snapshot rendition
1217
+ * component.
1263
1218
  */
1264
- readonly diplomaticFeatureDefs: _angular_core.InputSignal<FeatureDefinitions | undefined>;
1219
+ readonly renditionSettings: _angular_core.InputSignal<GveRenditionSettings>;
1265
1220
  /**
1266
1221
  * Emitted when the user cancels the snapshot editing.
1267
1222
  */
1268
1223
  readonly snapshotCancel: _angular_core.OutputEmitterRef<void>;
1269
- width: FormControl<number>;
1270
- height: FormControl<number>;
1271
- style: FormControl<string | null>;
1272
1224
  baseText: FormControl<CharNode[]>;
1273
- offsetX: FormControl<number>;
1274
- offsetY: FormControl<number>;
1275
- lineHeightOffset: FormControl<number>;
1276
- lnHeights: FormControl<Record<number, number> | null>;
1277
- charSpacingOffset: FormControl<number>;
1278
- spcWidthOffset: FormControl<number>;
1279
- textStyle: FormControl<string | null>;
1280
1225
  operations: FormControl<CharChainOperation[]>;
1281
- opStyle: FormControl<string | null>;
1282
1226
  form: FormGroup;
1283
- imageUrl: FormControl<string | null>;
1284
- imageOpacity: FormControl<number>;
1285
- imageX: FormControl<number>;
1286
- imageY: FormControl<number>;
1287
- imageWidth: FormControl<number>;
1288
- imageHeight: FormControl<number>;
1289
- defs: FormControl<string | null>;
1290
- timelines: FormControl<GveAnimationTimeline[]>;
1291
1227
  readonly showChain: FormControl<boolean>;
1292
1228
  readonly featDetails: FormControl<boolean>;
1229
+ readonly autoRun: FormControl<boolean>;
1293
1230
  readonly chain: _angular_core.WritableSignal<CharChain | undefined>;
1294
- readonly opTags: _angular_core.WritableSignal<string[]>;
1295
- readonly opElementIds: _angular_core.WritableSignal<string[]>;
1296
- readonly textRange: _angular_core.WritableSignal<VarBaseTextRange | undefined>;
1231
+ readonly textRange: _angular_core.WritableSignal<BaseTextRange | undefined>;
1297
1232
  readonly lineCount: _angular_core.WritableSignal<number>;
1298
1233
  readonly editedOp: _angular_core.WritableSignal<CharChainOperation | undefined>;
1299
1234
  readonly editedOpIndex: _angular_core.WritableSignal<number>;
1300
- readonly editedOpRangePatch: _angular_core.WritableSignal<VarBaseTextRange | undefined>;
1235
+ readonly editedOpRangePatch: _angular_core.WritableSignal<BaseTextRange | undefined>;
1301
1236
  readonly busy: _angular_core.WritableSignal<boolean>;
1302
1237
  readonly opTypeMap: {
1303
1238
  0: string;
@@ -1309,14 +1244,23 @@ declare class SnapshotEditorComponent {
1309
1244
  6: string;
1310
1245
  7: string;
1311
1246
  };
1312
- viewTitle: string;
1313
- viewData?: SnapshotViewData;
1314
- visualInfo?: string;
1315
- rulers: boolean;
1316
- result?: CharChainResult;
1317
- resultOperationId?: string;
1318
- initialStepIndex: number;
1247
+ readonly result: _angular_core.WritableSignal<CharChainResult | undefined>;
1248
+ readonly resultOperationId: _angular_core.WritableSignal<string | undefined>;
1249
+ readonly initialStepIndex: _angular_core.WritableSignal<number>;
1319
1250
  constructor(formBuilder: FormBuilder, _api: GveApiService, _dialog: MatDialog, _dialogService: DialogService, _snackbar: MatSnackBar);
1251
+ /**
1252
+ * Initialize rendition settings and event listeners when the element becomes available.
1253
+ * Called via effect since the element is conditionally rendered.
1254
+ */
1255
+ private initRendition;
1256
+ /**
1257
+ * Apply settings to the rendition component.
1258
+ */
1259
+ private applyRenditionSettings;
1260
+ /**
1261
+ * Update the snapshot rendition component with the current result data.
1262
+ */
1263
+ private updateRendition;
1320
1264
  /**
1321
1265
  * Set the view data for the snapshot view.
1322
1266
  *
@@ -1337,13 +1281,7 @@ declare class SnapshotEditorComponent {
1337
1281
  * @param range The picked range.
1338
1282
  * @param applyToOp True to also apply the picked range to the edited operation.
1339
1283
  */
1340
- onRangePick(range?: VarBaseTextRange, applyToOp?: boolean): void;
1341
- /**
1342
- * Update the lists of operation output tags and element IDs by collecting
1343
- * all the operation tags and the IDs of the elements in their diplomatic.g
1344
- * SVG code if any.
1345
- */
1346
- private updateOpLists;
1284
+ onRangePick(range?: BaseTextRange, applyToOp?: boolean): void;
1347
1285
  /**
1348
1286
  * Edit a new operation.
1349
1287
  */
@@ -1374,6 +1312,23 @@ declare class SnapshotEditorComponent {
1374
1312
  * @param index The index of the operation to delete.
1375
1313
  */
1376
1314
  deleteOperation(index: number): void;
1315
+ /**
1316
+ * Duplicate the operation at the specified index, inserting the copy
1317
+ * immediately after the original.
1318
+ * @param index The index of the operation to duplicate.
1319
+ */
1320
+ duplicateOperation(index: number): void;
1321
+ /**
1322
+ * Move the operation at the specified index up by one position.
1323
+ * @param index The index of the operation to move up.
1324
+ */
1325
+ moveOperationUp(index: number): void;
1326
+ /**
1327
+ * Move the operation at the specified index down by one position.
1328
+ * @param index The index of the operation to move down.
1329
+ */
1330
+ moveOperationDown(index: number): void;
1331
+ copyOperationsJson(): void;
1377
1332
  /**
1378
1333
  * Parse the operations from their text and append them to the current
1379
1334
  * snapshot operations.
@@ -1446,50 +1401,16 @@ declare class SnapshotEditorComponent {
1446
1401
  * @param operation The operation being previewed.
1447
1402
  */
1448
1403
  onOperationPreview(operation: CharChainOperation): void;
1449
- private playTimeline;
1450
1404
  /**
1451
1405
  * Handle the event fired by the chain result view to pick a step.
1452
1406
  *
1453
1407
  * @param step The step to pick.
1454
1408
  */
1455
1409
  onStepPick(step: ChainOperationContextStep): void;
1456
- /**
1457
- * Handle the event fired by a visual in the snapshot view.
1458
- *
1459
- * @param event The event.
1460
- */
1461
- onVisualEvent(event: CustomEvent<GveVisualEvent>): void;
1462
- /**
1463
- * Handle the change of line heights by updating the form control.
1464
- *
1465
- * @param heights The line heights.
1466
- */
1467
- onHeightsChange(heights: Record<number, number> | undefined): void;
1468
- /**
1469
- * Handle the change of timelines by updating the form control.
1470
- *
1471
- * @param timelines The timelines.
1472
- */
1473
- onTimelinesChange(timelines?: GveAnimationTimeline[] | null): void;
1474
1410
  /**
1475
1411
  * Emit the cancel event for this snapshot edit.
1476
1412
  */
1477
1413
  close(): void;
1478
- /**
1479
- * Handle the render event from the snapshot view to get a reference
1480
- * to the renderer.
1481
- *
1482
- * @param event The rendition event.
1483
- */
1484
- onSnapshotRender(event: CustomEvent<SnapshotViewRenderEvent>): void;
1485
- onImageLoad(imageElement: HTMLImageElement): void;
1486
- onImageOpacityChange(value: number): void;
1487
- resetImgMetadata(): void;
1488
- /**
1489
- * Toggle rulers in the snapshot view.
1490
- */
1491
- toggleRulers(): void;
1492
- private defaultCharDecorator;
1493
1414
  /**
1494
1415
  * Get a snapshot from the form data.
1495
1416
  *
@@ -1502,7 +1423,7 @@ declare class SnapshotEditorComponent {
1502
1423
  */
1503
1424
  save(): void;
1504
1425
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<SnapshotEditorComponent, never>;
1505
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<SnapshotEditorComponent, "gve-snapshot-editor", never, { "snapshot": { "alias": "snapshot"; "required": false; "isSignal": true; }; "batchOps": { "alias": "batchOps"; "required": false; "isSignal": true; }; "noSave": { "alias": "noSave"; "required": false; "isSignal": true; }; "debug": { "alias": "debug"; "required": false; "isSignal": true; }; "noDecoration": { "alias": "noDecoration"; "required": false; "isSignal": true; }; "featureDefs": { "alias": "featureDefs"; "required": false; "isSignal": true; }; "elementFeatureDefs": { "alias": "elementFeatureDefs"; "required": false; "isSignal": true; }; "diplomaticFeatureDefs": { "alias": "diplomaticFeatureDefs"; "required": false; "isSignal": true; }; }, { "snapshot": "snapshotChange"; "snapshotCancel": "snapshotCancel"; }, never, never, true, never>;
1426
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<SnapshotEditorComponent, "gve-snapshot-editor", never, { "snapshot": { "alias": "snapshot"; "required": false; "isSignal": true; }; "batchOps": { "alias": "batchOps"; "required": false; "isSignal": true; }; "noSave": { "alias": "noSave"; "required": false; "isSignal": true; }; "debug": { "alias": "debug"; "required": false; "isSignal": true; }; "noDecoration": { "alias": "noDecoration"; "required": false; "isSignal": true; }; "featureDefs": { "alias": "featureDefs"; "required": false; "isSignal": true; }; "multiValuedFeatureIds": { "alias": "multiValuedFeatureIds"; "required": false; "isSignal": true; }; "renditionSettings": { "alias": "renditionSettings"; "required": false; "isSignal": true; }; }, { "snapshot": "snapshotChange"; "snapshotCancel": "snapshotCancel"; }, never, never, true, never>;
1506
1427
  }
1507
1428
 
1508
1429
  /**
@@ -1515,6 +1436,7 @@ declare class SnapshotEditorComponent {
1515
1436
  * - 🔥 `textChange` (`CharNode[]`): event emitted when text changes.
1516
1437
  */
1517
1438
  declare class SnapshotTextEditorComponent implements OnInit {
1439
+ private _snackbar;
1518
1440
  dialogRef?: MatDialogRef<SnapshotTextEditorComponent> | undefined;
1519
1441
  data?: PayloadMatDialogConfig<{
1520
1442
  text?: CharNode[];
@@ -1522,14 +1444,15 @@ declare class SnapshotTextEditorComponent implements OnInit {
1522
1444
  userText: FormControl<string>;
1523
1445
  form: FormGroup;
1524
1446
  readonly text: _angular_core.ModelSignal<CharNode[]>;
1525
- constructor(formBuilder: FormBuilder, dialogRef?: MatDialogRef<SnapshotTextEditorComponent> | undefined, data?: PayloadMatDialogConfig<{
1447
+ constructor(formBuilder: FormBuilder, _snackbar: MatSnackBar, dialogRef?: MatDialogRef<SnapshotTextEditorComponent> | undefined, data?: PayloadMatDialogConfig<{
1526
1448
  text?: CharNode[];
1527
1449
  }> | undefined);
1528
1450
  private updateUserText;
1529
1451
  ngOnInit(): void;
1530
1452
  close(): void;
1453
+ copyToClipboard(): void;
1531
1454
  save(): void;
1532
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<SnapshotTextEditorComponent, [null, { optional: true; }, { optional: true; }]>;
1455
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<SnapshotTextEditorComponent, [null, null, { optional: true; }, { optional: true; }]>;
1533
1456
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<SnapshotTextEditorComponent, "gve-snapshot-text-editor", never, { "text": { "alias": "text"; "required": false; "isSignal": true; }; }, { "text": "textChange"; }, never, never, true, never>;
1534
1457
  }
1535
1458
 
@@ -1579,5 +1502,45 @@ declare class StepsMapComponent implements AfterViewInit {
1579
1502
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<StepsMapComponent, "gve-steps-map", never, { "steps": { "alias": "steps"; "required": false; "isSignal": true; }; "selectedStep": { "alias": "selectedStep"; "required": false; "isSignal": true; }; "textFontSize": { "alias": "textFontSize"; "required": false; "isSignal": true; }; }, { "selectedStep": "selectedStepChange"; }, never, never, true, never>;
1580
1503
  }
1581
1504
 
1582
- export { AnimationTimelineComponent, AnimationTimelineSetComponent, AnimationTweenComponent, BaseTextCharComponent, BaseTextEditorComponent, BaseTextViewComponent, BatchOperationEditorComponent, ChainOperationEditorComponent, ChainResultViewComponent, ChainViewComponent, FeatureEditorComponent, FeatureSetEditorComponent, FeatureSetViewComponent, GveApiService, GveGraphvizService, LnHeightsEditorComponent, OperationSourceEditorComponent, SettingsService, SnapshotEditorComponent, SnapshotTextEditorComponent, StepsMapComponent };
1583
- export type { BaseTextChar, BaseTextCharEvent, ChainOperationContextStep, ChainOperationTags, CharChain, CharChainLink, CharChainNode, CharChainResult, FeatureDefinitions, FeatureMap, GraphvizRankdir, PayloadMatDialogConfig, ResultWrapper, VarBaseTextRange };
1505
+ /**
1506
+ * Service for base text operations.
1507
+ */
1508
+ declare class GveBaseTextService {
1509
+ private static readonly _asciiTable;
1510
+ /**
1511
+ * Translate an ASCII special character to a printable character.
1512
+ *
1513
+ * @param c The character to translate.
1514
+ * @returns The translated character.
1515
+ */
1516
+ static translateSpecialChar(c: string): string;
1517
+ /**
1518
+ * Convert a string to the character nodes of a base text.
1519
+ *
1520
+ * @param text The text to convert to base characters.
1521
+ * @returns Character nodes for the given text.
1522
+ */
1523
+ static stringToBaseChars(text?: string): CharNode[];
1524
+ }
1525
+
1526
+ type GraphvizRankdir = 'TB' | 'LR' | 'BT' | 'RL';
1527
+ declare class GveGraphvizService {
1528
+ private hashString;
1529
+ private hslToRgb;
1530
+ private getColorForTag;
1531
+ private getExcludedNodeIds;
1532
+ /**
1533
+ * Represent the received chain as a Graphviz digraph.
1534
+ *
1535
+ * @param chain The source chain if any.
1536
+ * @param tags The tags to show. When set, only the links with these tags are shown.
1537
+ * @param rankdir The rank direction.
1538
+ * @returns Graphviz representation of the chain.
1539
+ */
1540
+ generateGraph(chain?: CharChain, tags?: string[], rankdir?: GraphvizRankdir): string;
1541
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<GveGraphvizService, never>;
1542
+ static ɵprov: _angular_core.ɵɵInjectableDeclaration<GveGraphvizService>;
1543
+ }
1544
+
1545
+ export { BaseTextCharComponent, BaseTextEditorComponent, BaseTextViewComponent, BatchOperationEditorComponent, ChainOperationEditorComponent, ChainResultViewComponent, FeatureEditorComponent, FeatureSetEditorComponent, FeatureSetPolicy, FeatureSetViewComponent, GveApiService, GveBaseTextService, GveGraphvizService, OperationSourceEditorComponent, OperationType, SettingsService, SnapshotEditorComponent, SnapshotTextEditorComponent, StepsMapComponent };
1546
+ export type { BaseTextChar, BaseTextCharEvent, BaseTextRange, ChainOperationContextStep, ChainOperationTags, CharChain, CharChainLink, CharChainNode, CharChainOperation, CharChainResult, CharNode, Feature, FeatureDefinitions, FeatureMap, GraphvizRankdir, LabeledId, OperationFeature, OperationMetadata, OperationSource, PayloadMatDialogConfig, ResultWrapper, Snapshot, TreeNode };