@memberjunction/ng-flow-editor 6.1.0-edge.2 → 6.1.0-edge.3

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,6 +1,7 @@
1
1
  import { Component, Input, Output, EventEmitter, ViewChild, ViewEncapsulation, ChangeDetectionStrategy, HostListener } from '@angular/core';
2
2
  import { Subject } from 'rxjs';
3
3
  import { FFlowComponent, FCanvasComponent } from '@foblex/flow';
4
+ import { FlowBeforeContextMenuEventArgs, FlowAfterContextMenuActionEventArgs, } from '../interfaces/flow-types';
4
5
  import { FlowStateService } from '../services/flow-state.service';
5
6
  import { FlowLayoutService } from '../services/flow-layout.service';
6
7
  import { UUIDsEqual, NormalizeUUID } from '@memberjunction/global';
@@ -17,210 +18,232 @@ import * as i9 from "./flow-status-bar.component";
17
18
  const _c0 = ["fZoomRef"];
18
19
  const _c1 = ["canvasArea"];
19
20
  const _c2 = (a0, a1) => ({ x: a0, y: a1 });
21
+ const _forTrack0 = ($index, $item) => $item.ID;
20
22
  function FlowEditorComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
21
23
  const _r2 = i0.ɵɵgetCurrentView();
22
- i0.ɵɵelementStart(0, "div", 3)(1, "mj-flow-toolbar", 18);
23
- i0.ɵɵlistener("ZoomInClicked", function FlowEditorComponent_Conditional_1_Template_mj_flow_toolbar_ZoomInClicked_1_listener() { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.ZoomIn()); })("ZoomOutClicked", function FlowEditorComponent_Conditional_1_Template_mj_flow_toolbar_ZoomOutClicked_1_listener() { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.ZoomOut()); })("FitToScreenClicked", function FlowEditorComponent_Conditional_1_Template_mj_flow_toolbar_FitToScreenClicked_1_listener() { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.ZoomToFit()); })("AutoLayoutClicked", function FlowEditorComponent_Conditional_1_Template_mj_flow_toolbar_AutoLayoutClicked_1_listener() { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.AutoArrange()); })("GridToggled", function FlowEditorComponent_Conditional_1_Template_mj_flow_toolbar_GridToggled_1_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onGridToggled($event)); })("MinimapToggled", function FlowEditorComponent_Conditional_1_Template_mj_flow_toolbar_MinimapToggled_1_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onMinimapToggled($event)); })("LegendToggled", function FlowEditorComponent_Conditional_1_Template_mj_flow_toolbar_LegendToggled_1_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onLegendToggled($event)); })("PanModeToggled", function FlowEditorComponent_Conditional_1_Template_mj_flow_toolbar_PanModeToggled_1_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onPanModeToggled($event)); });
24
+ i0.ɵɵelementStart(0, "div", 3)(1, "mj-flow-toolbar", 20);
25
+ i0.ɵɵlistener("ZoomInClicked", function FlowEditorComponent_Conditional_1_Template_mj_flow_toolbar_ZoomInClicked_1_listener() { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.ZoomIn()); })("ZoomOutClicked", function FlowEditorComponent_Conditional_1_Template_mj_flow_toolbar_ZoomOutClicked_1_listener() { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.ZoomOut()); })("FitToScreenClicked", function FlowEditorComponent_Conditional_1_Template_mj_flow_toolbar_FitToScreenClicked_1_listener() { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.ZoomToFit()); })("AutoLayoutClicked", function FlowEditorComponent_Conditional_1_Template_mj_flow_toolbar_AutoLayoutClicked_1_listener() { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.AutoArrange()); })("GridToggled", function FlowEditorComponent_Conditional_1_Template_mj_flow_toolbar_GridToggled_1_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onGridToggled($event)); })("MinimapToggled", function FlowEditorComponent_Conditional_1_Template_mj_flow_toolbar_MinimapToggled_1_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onMinimapToggled($event)); })("LegendToggled", function FlowEditorComponent_Conditional_1_Template_mj_flow_toolbar_LegendToggled_1_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onLegendToggled($event)); })("PanModeToggled", function FlowEditorComponent_Conditional_1_Template_mj_flow_toolbar_PanModeToggled_1_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onPanModeToggled($event)); })("MinimizeClicked", function FlowEditorComponent_Conditional_1_Template_mj_flow_toolbar_MinimizeClicked_1_listener() { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.SetToolbarVisibility("minimized")); })("HideClicked", function FlowEditorComponent_Conditional_1_Template_mj_flow_toolbar_HideClicked_1_listener() { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.SetToolbarVisibility("hidden")); });
24
26
  i0.ɵɵelementEnd()();
25
27
  } if (rf & 2) {
26
28
  const ctx_r2 = i0.ɵɵnextContext();
29
+ i0.ɵɵattribute("data-align", ctx_r2.ToolbarAlign);
27
30
  i0.ɵɵadvance();
28
31
  i0.ɵɵproperty("ZoomLevel", ctx_r2.zoomLevel)("ShowGrid", ctx_r2.ShowGrid)("ShowMinimap", ctx_r2.ShowMinimap)("ShowLegend", ctx_r2.ShowLegend)("ReadOnly", ctx_r2.ReadOnly)("PanMode", ctx_r2.panMode);
29
32
  } }
30
- function FlowEditorComponent_Conditional_3_Template(rf, ctx) { if (rf & 1) {
33
+ function FlowEditorComponent_Conditional_2_Template(rf, ctx) { if (rf & 1) {
31
34
  const _r4 = i0.ɵɵgetCurrentView();
32
- i0.ɵɵelementStart(0, "mj-flow-palette", 19);
33
- i0.ɵɵlistener("NodeTypeActivated", function FlowEditorComponent_Conditional_3_Template_mj_flow_palette_NodeTypeActivated_0_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onPaletteNodeTypeActivated($event)); });
35
+ i0.ɵɵelementStart(0, "button", 21);
36
+ i0.ɵɵlistener("click", function FlowEditorComponent_Conditional_2_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r4); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.SetToolbarVisibility("shown")); });
37
+ i0.ɵɵelement(1, "i", 22);
38
+ i0.ɵɵelementEnd();
39
+ } if (rf & 2) {
40
+ const ctx_r2 = i0.ɵɵnextContext();
41
+ i0.ɵɵattribute("data-align", ctx_r2.ToolbarAlign);
42
+ } }
43
+ function FlowEditorComponent_Conditional_3_Template(rf, ctx) { if (rf & 1) {
44
+ const _r5 = i0.ɵɵgetCurrentView();
45
+ i0.ɵɵelementStart(0, "button", 23);
46
+ i0.ɵɵlistener("click", function FlowEditorComponent_Conditional_3_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r5); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.SetToolbarVisibility("shown")); });
47
+ i0.ɵɵelement(1, "i", 24);
48
+ i0.ɵɵelementEnd();
49
+ } if (rf & 2) {
50
+ const ctx_r2 = i0.ɵɵnextContext();
51
+ i0.ɵɵattribute("data-align", ctx_r2.ToolbarAlign);
52
+ } }
53
+ function FlowEditorComponent_Conditional_5_Template(rf, ctx) { if (rf & 1) {
54
+ const _r6 = i0.ɵɵgetCurrentView();
55
+ i0.ɵɵelementStart(0, "mj-flow-palette", 25);
56
+ i0.ɵɵlistener("NodeTypeActivated", function FlowEditorComponent_Conditional_5_Template_mj_flow_palette_NodeTypeActivated_0_listener($event) { i0.ɵɵrestoreView(_r6); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onPaletteNodeTypeActivated($event)); });
34
57
  i0.ɵɵelementEnd();
35
58
  } if (rf & 2) {
36
59
  const ctx_r2 = i0.ɵɵnextContext();
37
60
  i0.ɵɵproperty("NodeTypes", ctx_r2.NodeTypes);
38
61
  } }
39
- function FlowEditorComponent_Conditional_7_Template(rf, ctx) { if (rf & 1) {
62
+ function FlowEditorComponent_Conditional_9_Template(rf, ctx) { if (rf & 1) {
40
63
  i0.ɵɵelementStart(0, "f-background");
41
- i0.ɵɵelement(1, "f-circle-pattern", 20);
64
+ i0.ɵɵelement(1, "f-circle-pattern", 26);
42
65
  i0.ɵɵelementEnd();
43
66
  } if (rf & 2) {
44
67
  i0.ɵɵadvance();
45
68
  i0.ɵɵproperty("color", "#94a3b8")("radius", 24);
46
69
  } }
47
- function FlowEditorComponent_Conditional_8_Template(rf, ctx) { if (rf & 1) {
48
- i0.ɵɵelement(0, "f-line-alignment", 8);
70
+ function FlowEditorComponent_Conditional_10_Template(rf, ctx) { if (rf & 1) {
71
+ i0.ɵɵelement(0, "f-line-alignment", 10);
49
72
  } if (rf & 2) {
50
73
  i0.ɵɵproperty("fAlignThreshold", 10);
51
74
  } }
52
- function FlowEditorComponent_Conditional_11_Template(rf, ctx) { if (rf & 1) {
53
- i0.ɵɵelementStart(0, "f-connection-for-create", 10);
75
+ function FlowEditorComponent_Conditional_13_Template(rf, ctx) { if (rf & 1) {
76
+ i0.ɵɵelementStart(0, "f-connection-for-create", 12);
54
77
  i0.ɵɵnamespaceSVG();
55
- i0.ɵɵelementStart(1, "svg", 21);
56
- i0.ɵɵelement(2, "path", 22);
78
+ i0.ɵɵelementStart(1, "svg", 27);
79
+ i0.ɵɵelement(2, "path", 28);
57
80
  i0.ɵɵelementEnd()();
58
81
  } if (rf & 2) {
59
82
  i0.ɵɵproperty("fRadius", 8)("fOffset", 12);
60
83
  i0.ɵɵadvance();
61
84
  i0.ɵɵproperty("refX", 9)("refY", 5)("height", 10)("width", 10);
62
85
  } }
63
- function FlowEditorComponent_For_13_Conditional_3_Conditional_1_Template(rf, ctx) { if (rf & 1) {
64
- i0.ɵɵelement(0, "i", 28);
86
+ function FlowEditorComponent_For_15_Conditional_3_Conditional_1_Template(rf, ctx) { if (rf & 1) {
87
+ i0.ɵɵelement(0, "i", 34);
65
88
  } if (rf & 2) {
66
- const conn_r6 = i0.ɵɵnextContext(2).$implicit;
67
- i0.ɵɵstyleProp("color", conn_r6.LabelIconColor || "inherit");
68
- i0.ɵɵproperty("ngClass", conn_r6.LabelIcon);
89
+ const conn_r8 = i0.ɵɵnextContext(2).$implicit;
90
+ i0.ɵɵstyleProp("color", conn_r8.LabelIconColor || "inherit");
91
+ i0.ɵɵproperty("ngClass", conn_r8.LabelIcon);
69
92
  } }
70
- function FlowEditorComponent_For_13_Conditional_3_Template(rf, ctx) { if (rf & 1) {
71
- i0.ɵɵelementStart(0, "div", 26);
72
- i0.ɵɵconditionalCreate(1, FlowEditorComponent_For_13_Conditional_3_Conditional_1_Template, 1, 3, "i", 27);
93
+ function FlowEditorComponent_For_15_Conditional_3_Template(rf, ctx) { if (rf & 1) {
94
+ i0.ɵɵelementStart(0, "div", 32);
95
+ i0.ɵɵconditionalCreate(1, FlowEditorComponent_For_15_Conditional_3_Conditional_1_Template, 1, 3, "i", 33);
73
96
  i0.ɵɵtext(2);
74
97
  i0.ɵɵelementEnd();
75
98
  } if (rf & 2) {
76
- const conn_r6 = i0.ɵɵnextContext().$implicit;
99
+ const conn_r8 = i0.ɵɵnextContext().$implicit;
77
100
  const ctx_r2 = i0.ɵɵnextContext();
78
101
  i0.ɵɵstyleProp("background-color", ctx_r2.ConnectionLabelBackground)("border-color", ctx_r2.ConnectionLabelBorderColor)("color", ctx_r2.ConnectionLabelTextColor);
79
- i0.ɵɵproperty("position", 0.5)("title", conn_r6.LabelDetail || conn_r6.Label || "");
102
+ i0.ɵɵproperty("position", 0.5)("title", conn_r8.LabelDetail || conn_r8.Label || "");
80
103
  i0.ɵɵadvance();
81
- i0.ɵɵconditional(conn_r6.LabelIcon ? 1 : -1);
104
+ i0.ɵɵconditional(conn_r8.LabelIcon ? 1 : -1);
82
105
  i0.ɵɵadvance();
83
- i0.ɵɵtextInterpolate1(" ", conn_r6.Label, " ");
106
+ i0.ɵɵtextInterpolate1(" ", conn_r8.Label, " ");
84
107
  } }
85
- function FlowEditorComponent_For_13_Template(rf, ctx) { if (rf & 1) {
86
- const _r5 = i0.ɵɵgetCurrentView();
87
- i0.ɵɵelementStart(0, "f-connection", 23);
88
- i0.ɵɵlistener("click", function FlowEditorComponent_For_13_Template_f_connection_click_0_listener($event) { const conn_r6 = i0.ɵɵrestoreView(_r5).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onConnectionClicked($event, conn_r6)); })("contextmenu", function FlowEditorComponent_For_13_Template_f_connection_contextmenu_0_listener($event) { const conn_r6 = i0.ɵɵrestoreView(_r5).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onConnectionContextMenu($event, conn_r6)); });
108
+ function FlowEditorComponent_For_15_Template(rf, ctx) { if (rf & 1) {
109
+ const _r7 = i0.ɵɵgetCurrentView();
110
+ i0.ɵɵelementStart(0, "f-connection", 29);
111
+ i0.ɵɵlistener("click", function FlowEditorComponent_For_15_Template_f_connection_click_0_listener($event) { const conn_r8 = i0.ɵɵrestoreView(_r7).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onConnectionClicked($event, conn_r8)); })("contextmenu", function FlowEditorComponent_For_15_Template_f_connection_contextmenu_0_listener($event) { const conn_r8 = i0.ɵɵrestoreView(_r7).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onConnectionContextMenu($event, conn_r8)); });
89
112
  i0.ɵɵnamespaceSVG();
90
- i0.ɵɵelementStart(1, "svg", 21);
91
- i0.ɵɵelement(2, "path", 24);
113
+ i0.ɵɵelementStart(1, "svg", 27);
114
+ i0.ɵɵelement(2, "path", 30);
92
115
  i0.ɵɵelementEnd();
93
- i0.ɵɵconditionalCreate(3, FlowEditorComponent_For_13_Conditional_3_Template, 3, 10, "div", 25);
116
+ i0.ɵɵconditionalCreate(3, FlowEditorComponent_For_15_Conditional_3_Template, 3, 10, "div", 31);
94
117
  i0.ɵɵelementEnd();
95
118
  } if (rf & 2) {
96
- const conn_r6 = ctx.$implicit;
119
+ const conn_r8 = ctx.$implicit;
97
120
  const ctx_r2 = i0.ɵɵnextContext();
98
- i0.ɵɵstyleProp("--connection-color", conn_r6.Color || "#94a3b8");
99
- i0.ɵɵclassProp("mj-flow-connection-colored", !!conn_r6.Color)("mj-flow-connection-dashed", conn_r6.Style === "dashed")("mj-flow-connection-dotted", conn_r6.Style === "dotted");
100
- i0.ɵɵproperty("fConnectionId", conn_r6.ID)("fOutputId", conn_r6.SourcePortID)("fInputId", conn_r6.TargetPortID)("fRadius", 8)("fOffset", 12)("fSelectionDisabled", false)("fReassignDisabled", ctx_r2.ReadOnly);
121
+ i0.ɵɵstyleProp("--connection-color", conn_r8.Color || "#94a3b8")("--connection-width", conn_r8.StrokeWidth || 2, "px");
122
+ i0.ɵɵclassProp("mj-flow-connection-colored", !!conn_r8.Color)("mj-flow-connection-dashed", conn_r8.Style === "dashed")("mj-flow-connection-dotted", conn_r8.Style === "dotted")("mj-flow-connection-animated", !!conn_r8.Animated);
123
+ i0.ɵɵproperty("fConnectionId", conn_r8.ID)("fOutputId", conn_r8.SourcePortID)("fInputId", conn_r8.TargetPortID)("fRadius", 8)("fOffset", 12)("fSelectionDisabled", false)("fReassignDisabled", ctx_r2.ReadOnly);
101
124
  i0.ɵɵadvance();
102
- i0.ɵɵproperty("refX", 9)("refY", 5)("height", 10)("width", 10);
125
+ i0.ɵɵproperty("refX", 9)("refY", 5)("height", conn_r8.Animated ? 16 : 10)("width", conn_r8.Animated ? 16 : 10);
103
126
  i0.ɵɵadvance();
104
- i0.ɵɵattribute("fill", conn_r6.Color || "#94a3b8");
127
+ i0.ɵɵattribute("fill", conn_r8.Color || "#94a3b8");
105
128
  i0.ɵɵadvance();
106
- i0.ɵɵconditional(conn_r6.Label ? 3 : -1);
129
+ i0.ɵɵconditional(conn_r8.Label ? 3 : -1);
107
130
  } }
108
- function FlowEditorComponent_For_15_Template(rf, ctx) { if (rf & 1) {
109
- const _r7 = i0.ɵɵgetCurrentView();
110
- i0.ɵɵelementStart(0, "mj-flow-node", 29);
111
- i0.ɵɵlistener("contextmenu", function FlowEditorComponent_For_15_Template_mj_flow_node_contextmenu_0_listener($event) { const node_r8 = i0.ɵɵrestoreView(_r7).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onNodeContextMenu($event, node_r8)); });
131
+ function FlowEditorComponent_For_17_Template(rf, ctx) { if (rf & 1) {
132
+ const _r9 = i0.ɵɵgetCurrentView();
133
+ i0.ɵɵelementStart(0, "mj-flow-node", 35);
134
+ i0.ɵɵlistener("contextmenu", function FlowEditorComponent_For_17_Template_mj_flow_node_contextmenu_0_listener($event) { const node_r10 = i0.ɵɵrestoreView(_r9).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onNodeContextMenu($event, node_r10)); });
112
135
  i0.ɵɵelementEnd();
113
136
  } if (rf & 2) {
114
- const node_r8 = ctx.$implicit;
137
+ const node_r10 = ctx.$implicit;
115
138
  const ctx_r2 = i0.ɵɵnextContext();
116
- i0.ɵɵproperty("fNodeId", node_r8.ID)("fNodePosition", i0.ɵɵpureFunction2(8, _c2, node_r8.Position.X, node_r8.Position.Y))("fNodeDraggingDisabled", ctx_r2.ReadOnly || ctx_r2.panMode || node_r8.Locked === true)("fNodeSelectionDisabled", ctx_r2.panMode)("fConnectOnNode", !ctx_r2.ReadOnly && !ctx_r2.panMode)("Node", node_r8)("TypeConfig", ctx_r2.GetTypeConfig(node_r8.Type))("ReadOnly", ctx_r2.ReadOnly);
139
+ i0.ɵɵproperty("fNodeId", node_r10.ID)("fNodePosition", i0.ɵɵpureFunction2(8, _c2, node_r10.Position.X, node_r10.Position.Y))("fNodeDraggingDisabled", ctx_r2.ReadOnly || ctx_r2.panMode || node_r10.Locked === true)("fNodeSelectionDisabled", ctx_r2.panMode)("fConnectOnNode", !ctx_r2.ReadOnly && !ctx_r2.panMode)("Node", node_r10)("TypeConfig", ctx_r2.GetTypeConfig(node_r10.Type))("ReadOnly", ctx_r2.ReadOnly);
117
140
  } }
118
- function FlowEditorComponent_Conditional_16_Template(rf, ctx) { if (rf & 1) {
141
+ function FlowEditorComponent_Conditional_18_Template(rf, ctx) { if (rf & 1) {
119
142
  i0.ɵɵelement(0, "f-selection-area");
120
143
  } }
121
- function FlowEditorComponent_Conditional_17_Template(rf, ctx) { if (rf & 1) {
122
- i0.ɵɵelementStart(0, "div", 13);
123
- i0.ɵɵelement(1, "f-minimap", 30);
144
+ function FlowEditorComponent_Conditional_19_Template(rf, ctx) { if (rf & 1) {
145
+ i0.ɵɵelementStart(0, "div", 15);
146
+ i0.ɵɵelement(1, "f-minimap", 36);
124
147
  i0.ɵɵelementEnd();
125
148
  } if (rf & 2) {
126
149
  i0.ɵɵadvance();
127
150
  i0.ɵɵproperty("fMinSize", 1500);
128
151
  } }
129
- function FlowEditorComponent_Conditional_18_Template(rf, ctx) { if (rf & 1) {
130
- i0.ɵɵelementStart(0, "div", 14)(1, "div", 31);
152
+ function FlowEditorComponent_Conditional_20_Template(rf, ctx) { if (rf & 1) {
153
+ i0.ɵɵelementStart(0, "div", 16)(1, "div", 37);
131
154
  i0.ɵɵtext(2, "Legend");
132
155
  i0.ɵɵelementEnd();
133
- i0.ɵɵelementStart(3, "div", 32)(4, "div", 33);
156
+ i0.ɵɵelementStart(3, "div", 38)(4, "div", 39);
134
157
  i0.ɵɵtext(5, "Connections");
135
158
  i0.ɵɵelementEnd();
136
- i0.ɵɵelementStart(6, "div", 34);
159
+ i0.ɵɵelementStart(6, "div", 40);
137
160
  i0.ɵɵnamespaceSVG();
138
- i0.ɵɵelementStart(7, "svg", 35);
139
- i0.ɵɵelement(8, "line", 36);
161
+ i0.ɵɵelementStart(7, "svg", 41);
162
+ i0.ɵɵelement(8, "line", 42);
140
163
  i0.ɵɵelementEnd();
141
164
  i0.ɵɵnamespaceHTML();
142
165
  i0.ɵɵelementStart(9, "span");
143
166
  i0.ɵɵtext(10, "Only exit path");
144
167
  i0.ɵɵelementEnd()();
145
- i0.ɵɵelementStart(11, "div", 34);
168
+ i0.ɵɵelementStart(11, "div", 40);
146
169
  i0.ɵɵnamespaceSVG();
147
- i0.ɵɵelementStart(12, "svg", 35);
148
- i0.ɵɵelement(13, "line", 37);
170
+ i0.ɵɵelementStart(12, "svg", 41);
171
+ i0.ɵɵelement(13, "line", 43);
149
172
  i0.ɵɵelementEnd();
150
173
  i0.ɵɵnamespaceHTML();
151
- i0.ɵɵelement(14, "i", 38);
174
+ i0.ɵɵelement(14, "i", 44);
152
175
  i0.ɵɵelementStart(15, "span");
153
176
  i0.ɵɵtext(16, "Default (fallback)");
154
177
  i0.ɵɵelementEnd()();
155
- i0.ɵɵelementStart(17, "div", 34);
178
+ i0.ɵɵelementStart(17, "div", 40);
156
179
  i0.ɵɵnamespaceSVG();
157
- i0.ɵɵelementStart(18, "svg", 35);
158
- i0.ɵɵelement(19, "line", 39);
180
+ i0.ɵɵelementStart(18, "svg", 41);
181
+ i0.ɵɵelement(19, "line", 45);
159
182
  i0.ɵɵelementEnd();
160
183
  i0.ɵɵnamespaceHTML();
161
184
  i0.ɵɵelementStart(20, "span");
162
185
  i0.ɵɵtext(21, "Conditional");
163
186
  i0.ɵɵelementEnd()();
164
- i0.ɵɵelementStart(22, "div", 34);
187
+ i0.ɵɵelementStart(22, "div", 40);
165
188
  i0.ɵɵnamespaceSVG();
166
- i0.ɵɵelementStart(23, "svg", 35);
167
- i0.ɵɵelement(24, "line", 40);
189
+ i0.ɵɵelementStart(23, "svg", 41);
190
+ i0.ɵɵelement(24, "line", 46);
168
191
  i0.ɵɵelementEnd();
169
192
  i0.ɵɵnamespaceHTML();
170
- i0.ɵɵelement(25, "i", 41);
193
+ i0.ɵɵelement(25, "i", 47);
171
194
  i0.ɵɵelementStart(26, "span");
172
195
  i0.ɵɵtext(27, "Duplicate defaults");
173
196
  i0.ɵɵelementEnd()()();
174
- i0.ɵɵelementStart(28, "div", 32)(29, "div", 33);
197
+ i0.ɵɵelementStart(28, "div", 38)(29, "div", 39);
175
198
  i0.ɵɵtext(30, "Step Types");
176
199
  i0.ɵɵelementEnd();
177
- i0.ɵɵelementStart(31, "div", 34);
178
- i0.ɵɵelement(32, "span", 42);
200
+ i0.ɵɵelementStart(31, "div", 40);
201
+ i0.ɵɵelement(32, "span", 48);
179
202
  i0.ɵɵelementStart(33, "span");
180
203
  i0.ɵɵtext(34, "Action");
181
204
  i0.ɵɵelementEnd()();
182
- i0.ɵɵelementStart(35, "div", 34);
183
- i0.ɵɵelement(36, "span", 43);
205
+ i0.ɵɵelementStart(35, "div", 40);
206
+ i0.ɵɵelement(36, "span", 49);
184
207
  i0.ɵɵelementStart(37, "span");
185
208
  i0.ɵɵtext(38, "Prompt");
186
209
  i0.ɵɵelementEnd()();
187
- i0.ɵɵelementStart(39, "div", 34);
188
- i0.ɵɵelement(40, "span", 44);
210
+ i0.ɵɵelementStart(39, "div", 40);
211
+ i0.ɵɵelement(40, "span", 50);
189
212
  i0.ɵɵelementStart(41, "span");
190
213
  i0.ɵɵtext(42, "Sub-Agent");
191
214
  i0.ɵɵelementEnd()();
192
- i0.ɵɵelementStart(43, "div", 34);
193
- i0.ɵɵelement(44, "span", 45);
215
+ i0.ɵɵelementStart(43, "div", 40);
216
+ i0.ɵɵelement(44, "span", 51);
194
217
  i0.ɵɵelementStart(45, "span");
195
218
  i0.ɵɵtext(46, "For Each");
196
219
  i0.ɵɵelementEnd()();
197
- i0.ɵɵelementStart(47, "div", 34);
198
- i0.ɵɵelement(48, "span", 46);
220
+ i0.ɵɵelementStart(47, "div", 40);
221
+ i0.ɵɵelement(48, "span", 52);
199
222
  i0.ɵɵelementStart(49, "span");
200
223
  i0.ɵɵtext(50, "While");
201
224
  i0.ɵɵelementEnd()()();
202
- i0.ɵɵelementStart(51, "div", 32)(52, "div", 33);
225
+ i0.ɵɵelementStart(51, "div", 38)(52, "div", 39);
203
226
  i0.ɵɵtext(53, "Borders");
204
227
  i0.ɵɵelementEnd();
205
- i0.ɵɵelementStart(54, "div", 34);
206
- i0.ɵɵelement(55, "span", 47);
228
+ i0.ɵɵelementStart(54, "div", 40);
229
+ i0.ɵɵelement(55, "span", 53);
207
230
  i0.ɵɵelementStart(56, "span");
208
231
  i0.ɵɵtext(57, "Start node");
209
232
  i0.ɵɵelementEnd()();
210
- i0.ɵɵelementStart(58, "div", 34);
211
- i0.ɵɵelement(59, "span", 48)(60, "i", 49);
233
+ i0.ɵɵelementStart(58, "div", 40);
234
+ i0.ɵɵelement(59, "span", 54)(60, "i", 55);
212
235
  i0.ɵɵelementStart(61, "span");
213
236
  i0.ɵɵtext(62, "Missing config");
214
237
  i0.ɵɵelementEnd()()()();
215
238
  } }
216
- function FlowEditorComponent_Conditional_19_Conditional_2_Template(rf, ctx) { if (rf & 1) {
217
- i0.ɵɵelementStart(0, "p", 51);
239
+ function FlowEditorComponent_Conditional_21_Conditional_2_Template(rf, ctx) { if (rf & 1) {
240
+ i0.ɵɵelementStart(0, "p", 57);
218
241
  i0.ɵɵtext(1, " Or use auto-layout after adding steps to arrange them automatically ");
219
242
  i0.ɵɵelementEnd();
220
243
  } }
221
- function FlowEditorComponent_Conditional_19_Template(rf, ctx) { if (rf & 1) {
222
- i0.ɵɵelementStart(0, "div", 15)(1, "mj-empty-state", 50);
223
- i0.ɵɵconditionalCreate(2, FlowEditorComponent_Conditional_19_Conditional_2_Template, 2, 0, "p", 51);
244
+ function FlowEditorComponent_Conditional_21_Template(rf, ctx) { if (rf & 1) {
245
+ i0.ɵɵelementStart(0, "div", 17)(1, "mj-empty-state", 56);
246
+ i0.ɵɵconditionalCreate(2, FlowEditorComponent_Conditional_21_Conditional_2_Template, 2, 0, "p", 57);
224
247
  i0.ɵɵelementEnd()();
225
248
  } if (rf & 2) {
226
249
  const ctx_r2 = i0.ɵɵnextContext();
@@ -229,33 +252,66 @@ function FlowEditorComponent_Conditional_19_Template(rf, ctx) { if (rf & 1) {
229
252
  i0.ɵɵadvance();
230
253
  i0.ɵɵconditional(!ctx_r2.ReadOnly ? 2 : -1);
231
254
  } }
232
- function FlowEditorComponent_Conditional_20_Template(rf, ctx) { if (rf & 1) {
233
- const _r9 = i0.ɵɵgetCurrentView();
234
- i0.ɵɵelementStart(0, "div", 52);
235
- i0.ɵɵlistener("click", function FlowEditorComponent_Conditional_20_Template_div_click_0_listener($event) { i0.ɵɵrestoreView(_r9); return i0.ɵɵresetView($event.stopPropagation()); });
236
- i0.ɵɵelementStart(1, "button", 53);
237
- i0.ɵɵlistener("click", function FlowEditorComponent_Conditional_20_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r9); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onContextMenuAction("edit")); });
238
- i0.ɵɵelement(2, "i", 54);
239
- i0.ɵɵelementStart(3, "span");
240
- i0.ɵɵtext(4);
241
- i0.ɵɵelementEnd()();
242
- i0.ɵɵelement(5, "div", 55);
243
- i0.ɵɵelementStart(6, "button", 56);
244
- i0.ɵɵlistener("click", function FlowEditorComponent_Conditional_20_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r9); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onContextMenuAction("remove")); });
245
- i0.ɵɵelement(7, "i", 57);
246
- i0.ɵɵelementStart(8, "span");
247
- i0.ɵɵtext(9);
248
- i0.ɵɵelementEnd()()();
255
+ function FlowEditorComponent_Conditional_22_For_2_Conditional_1_Template(rf, ctx) { if (rf & 1) {
256
+ i0.ɵɵelement(0, "i", 60);
257
+ } if (rf & 2) {
258
+ const item_r13 = i0.ɵɵnextContext().$implicit;
259
+ i0.ɵɵproperty("ngClass", item_r13.Icon);
260
+ } }
261
+ function FlowEditorComponent_Conditional_22_For_2_Conditional_4_Template(rf, ctx) { if (rf & 1) {
262
+ i0.ɵɵelementStart(0, "kbd", 61);
263
+ i0.ɵɵtext(1);
264
+ i0.ɵɵelementEnd();
265
+ } if (rf & 2) {
266
+ const item_r13 = i0.ɵɵnextContext().$implicit;
267
+ i0.ɵɵadvance();
268
+ i0.ɵɵtextInterpolate(item_r13.Shortcut);
269
+ } }
270
+ function FlowEditorComponent_Conditional_22_For_2_Conditional_5_Template(rf, ctx) { if (rf & 1) {
271
+ i0.ɵɵelement(0, "div", 62);
272
+ } }
273
+ function FlowEditorComponent_Conditional_22_For_2_Template(rf, ctx) { if (rf & 1) {
274
+ const _r12 = i0.ɵɵgetCurrentView();
275
+ i0.ɵɵelementStart(0, "button", 59);
276
+ i0.ɵɵlistener("click", function FlowEditorComponent_Conditional_22_For_2_Template_button_click_0_listener() { const item_r13 = i0.ɵɵrestoreView(_r12).$implicit; const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.onContextMenuAction(item_r13.ID)); });
277
+ i0.ɵɵconditionalCreate(1, FlowEditorComponent_Conditional_22_For_2_Conditional_1_Template, 1, 1, "i", 60);
278
+ i0.ɵɵelementStart(2, "span");
279
+ i0.ɵɵtext(3);
280
+ i0.ɵɵelementEnd();
281
+ i0.ɵɵconditionalCreate(4, FlowEditorComponent_Conditional_22_For_2_Conditional_4_Template, 2, 1, "kbd", 61);
282
+ i0.ɵɵelementEnd();
283
+ i0.ɵɵconditionalCreate(5, FlowEditorComponent_Conditional_22_For_2_Conditional_5_Template, 1, 0, "div", 62);
284
+ } if (rf & 2) {
285
+ const item_r13 = ctx.$implicit;
286
+ const $index_r14 = ctx.$index;
287
+ const ɵ$index_193_r15 = ctx.$index;
288
+ const ɵ$count_193_r16 = ctx.$count;
289
+ const ctx_r2 = i0.ɵɵnextContext(2);
290
+ i0.ɵɵclassProp("mj-flow-context-menu-item--danger", item_r13.Danger);
291
+ i0.ɵɵproperty("disabled", item_r13.Disabled);
292
+ i0.ɵɵadvance();
293
+ i0.ɵɵconditional(item_r13.Icon ? 1 : -1);
294
+ i0.ɵɵadvance(2);
295
+ i0.ɵɵtextInterpolate(item_r13.Label);
296
+ i0.ɵɵadvance();
297
+ i0.ɵɵconditional(item_r13.Shortcut ? 4 : -1);
298
+ i0.ɵɵadvance();
299
+ i0.ɵɵconditional(!(ɵ$index_193_r15 === ɵ$count_193_r16 - 1) && item_r13.Danger !== (ctx_r2.contextMenuItems[$index_r14 + 1] == null ? null : ctx_r2.contextMenuItems[$index_r14 + 1].Danger) ? 5 : -1);
300
+ } }
301
+ function FlowEditorComponent_Conditional_22_Template(rf, ctx) { if (rf & 1) {
302
+ const _r11 = i0.ɵɵgetCurrentView();
303
+ i0.ɵɵelementStart(0, "div", 58);
304
+ i0.ɵɵlistener("click", function FlowEditorComponent_Conditional_22_Template_div_click_0_listener($event) { i0.ɵɵrestoreView(_r11); return i0.ɵɵresetView($event.stopPropagation()); });
305
+ i0.ɵɵrepeaterCreate(1, FlowEditorComponent_Conditional_22_For_2_Template, 6, 7, null, null, _forTrack0);
306
+ i0.ɵɵelementEnd();
249
307
  } if (rf & 2) {
250
308
  const ctx_r2 = i0.ɵɵnextContext();
251
309
  i0.ɵɵstyleProp("left", ctx_r2.contextMenuX, "px")("top", ctx_r2.contextMenuY, "px");
252
- i0.ɵɵadvance(4);
253
- i0.ɵɵtextInterpolate1("Edit ", ctx_r2.contextMenuTargetType === "node" ? "Node" : "Connection");
254
- i0.ɵɵadvance(5);
255
- i0.ɵɵtextInterpolate1("Remove ", ctx_r2.contextMenuTargetType === "node" ? "Node" : "Connection");
310
+ i0.ɵɵadvance();
311
+ i0.ɵɵrepeater(ctx_r2.contextMenuItems);
256
312
  } }
257
- function FlowEditorComponent_Conditional_21_Template(rf, ctx) { if (rf & 1) {
258
- i0.ɵɵelement(0, "mj-flow-status-bar", 17);
313
+ function FlowEditorComponent_Conditional_23_Template(rf, ctx) { if (rf & 1) {
314
+ i0.ɵɵelement(0, "mj-flow-status-bar", 19);
259
315
  } if (rf & 2) {
260
316
  const ctx_r2 = i0.ɵɵnextContext();
261
317
  i0.ɵɵproperty("NodeCount", ctx_r2.Nodes.length)("ConnectionCount", ctx_r2.Connections.length)("SelectedCount", ctx_r2.selectedCount)("ZoomLevel", ctx_r2.zoomLevel);
@@ -288,7 +344,15 @@ export class FlowEditorComponent {
288
344
  ShowPalette = true;
289
345
  ShowGrid = true;
290
346
  ShowStatusBar = true;
347
+ /**
348
+ * Legacy on/off. `false` forces the toolbar fully off (no recover tab). Prefer
349
+ * `ToolbarVisibility` when the host wants shown / minimized / hidden with a way back.
350
+ */
291
351
  ShowToolbar = true;
352
+ /** Full bar, a restore chip, or a recover tab. Ignored when `ShowToolbar` is false. */
353
+ ToolbarVisibility = 'shown';
354
+ /** Left / center / right along the top of the canvas. */
355
+ ToolbarAlign = 'center';
292
356
  ShowLegend = true;
293
357
  GridSize = 20;
294
358
  AutoLayoutDirection = 'vertical';
@@ -321,9 +385,26 @@ export class FlowEditorComponent {
321
385
  ConnectionsChanged = new EventEmitter();
322
386
  NodeEditRequested = new EventEmitter();
323
387
  ConnectionEditRequested = new EventEmitter();
388
+ /** Host may replace `Items` or `Cancel` the menu. Debug attaches here — the canvas stays blind. */
389
+ BeforeContextMenu = new EventEmitter();
390
+ AfterContextMenuAction = new EventEmitter();
324
391
  GridToggled = new EventEmitter();
325
392
  MinimapToggled = new EventEmitter();
326
393
  LegendToggled = new EventEmitter();
394
+ /** The person changed shown / minimized / hidden from the canvas chrome. */
395
+ ToolbarVisibilityChanged = new EventEmitter();
396
+ /** What the template actually paints — `ShowToolbar === false` is a hard hide. */
397
+ get EffectiveToolbarVisibility() {
398
+ return this.ShowToolbar ? this.ToolbarVisibility : 'hidden';
399
+ }
400
+ SetToolbarVisibility(next) {
401
+ if (!this.ShowToolbar)
402
+ return;
403
+ if (this.ToolbarVisibility === next)
404
+ return;
405
+ this.ToolbarVisibility = next;
406
+ this.ToolbarVisibilityChanged.emit(next);
407
+ }
327
408
  // ── View Children ───────────────────────────────────────────
328
409
  fFlow;
329
410
  fCanvas;
@@ -333,6 +414,11 @@ export class FlowEditorComponent {
333
414
  zoomLevel = 100;
334
415
  canvasPosition = { x: 0, y: 0 };
335
416
  canvasScale = 1;
417
+ /** After the first auto-fit, later fLoaded events must not snap the viewport back. */
418
+ hasAutoFitted = false;
419
+ /** True once the person zooms or pans — remounts restore this viewport instead of fitting. */
420
+ viewportOwnedByUser = false;
421
+ applyingProgrammaticViewport = false;
336
422
  selectedNodeIDs = [];
337
423
  selectedConnectionIDs = [];
338
424
  panMode = false;
@@ -347,6 +433,7 @@ export class FlowEditorComponent {
347
433
  contextMenuTargetType = 'node';
348
434
  contextMenuNode = null;
349
435
  contextMenuConnection = null;
436
+ contextMenuItems = [];
350
437
  destroy$ = new Subject();
351
438
  initialized = false;
352
439
  lastConnectionClickTime = 0;
@@ -371,10 +458,14 @@ export class FlowEditorComponent {
371
458
  // ── Public Methods ──────────────────────────────────────────
372
459
  /** Fit all nodes within the viewport */
373
460
  ZoomToFit() {
461
+ this.applyingProgrammaticViewport = true;
374
462
  this.fCanvas?.fitToScreen({ x: 150, y: 150 }, true);
463
+ this.hasAutoFitted = true;
464
+ queueMicrotask(() => { this.applyingProgrammaticViewport = false; });
375
465
  }
376
466
  /** Zoom in one step */
377
467
  ZoomIn() {
468
+ this.viewportOwnedByUser = true;
378
469
  if (this.fZoom) {
379
470
  this.fZoom.zoomIn();
380
471
  }
@@ -386,6 +477,7 @@ export class FlowEditorComponent {
386
477
  }
387
478
  /** Zoom out one step */
388
479
  ZoomOut() {
480
+ this.viewportOwnedByUser = true;
389
481
  if (this.fZoom) {
390
482
  this.fZoom.zoomOut();
391
483
  }
@@ -524,15 +616,29 @@ export class FlowEditorComponent {
524
616
  // ── Foblex Event Handlers ──────────────────────────────────
525
617
  /** Called when Foblex flow finishes loading */
526
618
  onFlowLoaded() {
527
- if (this.Nodes.length > 0) {
528
- setTimeout(() => this.ZoomToFit(), 200);
619
+ if (this.Nodes.length === 0)
620
+ return;
621
+ if (this.viewportOwnedByUser || this.hasAutoFitted) {
622
+ this.restoreViewport();
623
+ return;
529
624
  }
625
+ this.hasAutoFitted = true;
626
+ setTimeout(() => this.ZoomToFit(), 200);
530
627
  }
531
628
  /** Canvas zoom/pan changed */
532
629
  onCanvasChange(event) {
533
630
  this.canvasPosition = event.position;
534
631
  this.canvasScale = event.scale;
535
632
  this.updateZoomLevel(event.scale);
633
+ if (!this.applyingProgrammaticViewport)
634
+ this.viewportOwnedByUser = true;
635
+ }
636
+ restoreViewport() {
637
+ if (!this.fCanvas)
638
+ return;
639
+ this.applyingProgrammaticViewport = true;
640
+ this.fCanvas.setScale(this.canvasScale);
641
+ queueMicrotask(() => { this.applyingProgrammaticViewport = false; });
536
642
  }
537
643
  /** User drew a new connection */
538
644
  onCreateConnection(event) {
@@ -740,11 +846,9 @@ export class FlowEditorComponent {
740
846
  }
741
847
  // ── Context Menu ───────────────────────────────────────────
742
848
  onNodeContextMenu(event, node) {
743
- if (this.ReadOnly)
744
- return;
745
849
  event.preventDefault();
746
850
  event.stopPropagation();
747
- this.showContextMenu(event, 'node', node, null);
851
+ this.openContextMenu(event, 'node', node, null);
748
852
  }
749
853
  /** Direct click on a connection — ensures ConnectionSelected fires reliably */
750
854
  onConnectionClicked(event, conn) {
@@ -758,11 +862,9 @@ export class FlowEditorComponent {
758
862
  this.cdr.detectChanges();
759
863
  }
760
864
  onConnectionContextMenu(event, conn) {
761
- if (this.ReadOnly)
762
- return;
763
865
  event.preventDefault();
764
866
  event.stopPropagation();
765
- this.showContextMenu(event, 'connection', null, conn);
867
+ this.openContextMenu(event, 'connection', null, conn);
766
868
  }
767
869
  onContextMenuAction(action) {
768
870
  // Capture the target BEFORE closing: hideContextMenu() nulls contextMenuNode and
@@ -772,7 +874,7 @@ export class FlowEditorComponent {
772
874
  const node = this.contextMenuNode;
773
875
  const connection = this.contextMenuConnection;
774
876
  this.hideContextMenu();
775
- if (action === 'edit') {
877
+ if (!this.ReadOnly && action === 'edit') {
776
878
  if (targetType === 'node' && node) {
777
879
  this.NodeEditRequested.emit(node);
778
880
  }
@@ -780,7 +882,7 @@ export class FlowEditorComponent {
780
882
  this.ConnectionEditRequested.emit(connection);
781
883
  }
782
884
  }
783
- else if (action === 'remove') {
885
+ else if (!this.ReadOnly && action === 'remove') {
784
886
  if (targetType === 'node' && node) {
785
887
  this.pushUndoState();
786
888
  this.removeNodeById(node.ID);
@@ -789,19 +891,24 @@ export class FlowEditorComponent {
789
891
  this.pushUndoState();
790
892
  this.removeConnectionById(connection.ID);
791
893
  }
792
- // pushUndoState moved inside the branches: pushing before knowing there IS a target left an
793
- // undo entry for an action that never happened, so the next Ctrl+Z did nothing visible.
794
894
  }
895
+ this.AfterContextMenuAction.emit(new FlowAfterContextMenuActionEventArgs(action, targetType, node, connection));
795
896
  }
796
897
  onDocumentClick() {
797
898
  if (this.contextMenuVisible) {
798
899
  this.hideContextMenu();
799
900
  }
800
901
  }
801
- showContextMenu(event, targetType, node, connection) {
902
+ openContextMenu(event, targetType, node, connection) {
903
+ const defaults = this.ReadOnly ? [] : defaultContextMenuItems(targetType);
904
+ const before = new FlowBeforeContextMenuEventArgs(targetType, node, connection, event, defaults);
905
+ this.BeforeContextMenu.emit(before);
906
+ if (before.Cancel || before.Items.length === 0)
907
+ return;
802
908
  this.contextMenuTargetType = targetType;
803
909
  this.contextMenuNode = node;
804
910
  this.contextMenuConnection = connection;
911
+ this.contextMenuItems = before.Items;
805
912
  this.contextMenuX = event.clientX;
806
913
  this.contextMenuY = event.clientY;
807
914
  this.contextMenuVisible = true;
@@ -985,70 +1092,70 @@ export class FlowEditorComponent {
985
1092
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.canvasArea = _t.first);
986
1093
  } }, hostBindings: function FlowEditorComponent_HostBindings(rf, ctx) { if (rf & 1) {
987
1094
  i0.ɵɵlistener("click", function FlowEditorComponent_click_HostBindingHandler() { return ctx.onDocumentClick(); }, i0.ɵɵresolveDocument)("keydown", function FlowEditorComponent_keydown_HostBindingHandler($event) { return ctx.onKeyDown($event); });
988
- } }, inputs: { Nodes: "Nodes", Connections: "Connections", NodeTypes: "NodeTypes", ReadOnly: "ReadOnly", ShowMinimap: "ShowMinimap", ShowPalette: "ShowPalette", ShowGrid: "ShowGrid", ShowStatusBar: "ShowStatusBar", ShowToolbar: "ShowToolbar", ShowLegend: "ShowLegend", GridSize: "GridSize", AutoLayoutDirection: "AutoLayoutDirection", ConnectionLabelBackground: "ConnectionLabelBackground", ConnectionLabelBorderColor: "ConnectionLabelBorderColor", ConnectionLabelTextColor: "ConnectionLabelTextColor" }, outputs: { NodeSelected: "NodeSelected", NodeAdded: "NodeAdded", NodeRemoved: "NodeRemoved", NodeMoved: "NodeMoved", ConnectionCreated: "ConnectionCreated", ConnectionRemoved: "ConnectionRemoved", ConnectionReassigned: "ConnectionReassigned", ConnectionSelected: "ConnectionSelected", SelectionChanged: "SelectionChanged", CanvasClicked: "CanvasClicked", NodesChanged: "NodesChanged", ConnectionsChanged: "ConnectionsChanged", NodeEditRequested: "NodeEditRequested", ConnectionEditRequested: "ConnectionEditRequested", GridToggled: "GridToggled", MinimapToggled: "MinimapToggled", LegendToggled: "LegendToggled" }, standalone: false, features: [i0.ɵɵProvidersFeature([FlowStateService, FlowLayoutService])], decls: 22, vars: 25, consts: [["canvasArea", ""], ["fZoomRef", "fComponent"], ["tabindex", "0", 1, "mj-flow-editor"], [1, "mj-flow-editor-toolbar-area"], [1, "mj-flow-editor-canvas-area"], [3, "NodeTypes"], [1, "mj-flow-editor-canvas"], ["fDraggable", "", 3, "fLoaded", "fCreateConnection", "fReassignConnection", "fCreateNode", "fSelectionChange", "fMoveNodes", "fDraggableDisabled", "fCanvasMoveTrigger", "vCellSize", "hCellSize", "fCellSizeWhileDragging"], [3, "fAlignThreshold"], ["fZoom", "", 3, "fCanvasChange", "fZoomMinimum", "fZoomMaximum", "fZoomStep", "position", "scale"], ["fType", "bezier", 3, "fRadius", "fOffset"], ["fType", "bezier", "fBehavior", "fixed", 3, "fConnectionId", "fOutputId", "fInputId", "fRadius", "fOffset", "fSelectionDisabled", "fReassignDisabled", "--connection-color", "mj-flow-connection-colored", "mj-flow-connection-dashed", "mj-flow-connection-dotted"], ["fNode", "", "fDragHandle", "", 3, "fNodeId", "fNodePosition", "fNodeDraggingDisabled", "fNodeSelectionDisabled", "fConnectOnNode", "Node", "TypeConfig", "ReadOnly"], ["fDragBlocker", "", 1, "mj-flow-editor-minimap"], [1, "mj-flow-editor-legend"], [1, "mj-flow-editor-empty"], [1, "mj-flow-context-menu", 3, "left", "top"], [3, "NodeCount", "ConnectionCount", "SelectedCount", "ZoomLevel"], [3, "ZoomInClicked", "ZoomOutClicked", "FitToScreenClicked", "AutoLayoutClicked", "GridToggled", "MinimapToggled", "LegendToggled", "PanModeToggled", "ZoomLevel", "ShowGrid", "ShowMinimap", "ShowLegend", "ReadOnly", "PanMode"], [3, "NodeTypeActivated", "NodeTypes"], [3, "color", "radius"], ["viewBox", "0 0 10 10", "fMarker", "", "type", "end", "orient", "auto", 3, "refX", "refY", "height", "width"], ["d", "M0 0L10 5L0 10Z", "fill", "#94a3b8"], ["fType", "bezier", "fBehavior", "fixed", 3, "click", "contextmenu", "fConnectionId", "fOutputId", "fInputId", "fRadius", "fOffset", "fSelectionDisabled", "fReassignDisabled"], ["d", "M0 0L10 5L0 10Z"], ["fConnectionContent", "", 1, "mj-flow-connection-label", 3, "position", "backgroundColor", "borderColor", "color", "title"], ["fConnectionContent", "", 1, "mj-flow-connection-label", 3, "position", "title"], [1, "fa-solid", "mj-flow-connection-label-icon", 3, "ngClass", "color"], [1, "fa-solid", "mj-flow-connection-label-icon", 3, "ngClass"], ["fNode", "", "fDragHandle", "", 3, "contextmenu", "fNodeId", "fNodePosition", "fNodeDraggingDisabled", "fNodeSelectionDisabled", "fConnectOnNode", "Node", "TypeConfig", "ReadOnly"], [3, "fMinSize"], [1, "mj-flow-editor-legend-title"], [1, "mj-flow-editor-legend-section"], [1, "mj-flow-editor-legend-heading"], [1, "mj-flow-editor-legend-item"], ["width", "28", "height", "10", 1, "mj-flow-editor-legend-line-svg"], ["x1", "0", "y1", "5", "x2", "28", "y2", "5", "stroke", "#64748b", "stroke-width", "2"], ["x1", "0", "y1", "5", "x2", "28", "y2", "5", "stroke", "#16a34a", "stroke-width", "2"], [1, "fa-solid", "fa-circle-check", 2, "color", "#16a34a", "font-size", "10px"], ["x1", "0", "y1", "5", "x2", "28", "y2", "5", "stroke", "#f59e0b", "stroke-width", "2", "stroke-dasharray", "5 3"], ["x1", "0", "y1", "5", "x2", "28", "y2", "5", "stroke", "#ef4444", "stroke-width", "2"], [1, "fa-solid", "fa-triangle-exclamation", 2, "color", "#ef4444", "font-size", "10px"], [1, "mj-flow-editor-legend-swatch", 2, "background", "#3B82F6"], [1, "mj-flow-editor-legend-swatch", 2, "background", "#8B5CF6"], [1, "mj-flow-editor-legend-swatch", 2, "background", "#10B981"], [1, "mj-flow-editor-legend-swatch", 2, "background", "#F59E0B"], [1, "mj-flow-editor-legend-swatch", 2, "background", "#F97316"], [1, "mj-flow-editor-legend-box", 2, "border-color", "#16a34a", "background", "#f0fdf4"], [1, "mj-flow-editor-legend-box", 2, "border-color", "#ef4444", "background", "#fef2f2"], [1, "fa-solid", "fa-triangle-exclamation", 2, "color", "#ea580c", "font-size", "10px"], ["Icon", "fa-solid fa-diagram-project", 3, "Title"], [1, "mj-flow-editor-empty-subtitle"], [1, "mj-flow-context-menu", 3, "click"], [1, "mj-flow-context-menu-item", 3, "click"], [1, "fa-solid", "fa-pen-to-square"], [1, "mj-flow-context-menu-divider"], [1, "mj-flow-context-menu-item", "mj-flow-context-menu-item--danger", 3, "click"], [1, "fa-solid", "fa-trash-can"]], template: function FlowEditorComponent_Template(rf, ctx) { if (rf & 1) {
1095
+ } }, inputs: { Nodes: "Nodes", Connections: "Connections", NodeTypes: "NodeTypes", ReadOnly: "ReadOnly", ShowMinimap: "ShowMinimap", ShowPalette: "ShowPalette", ShowGrid: "ShowGrid", ShowStatusBar: "ShowStatusBar", ShowToolbar: "ShowToolbar", ToolbarVisibility: "ToolbarVisibility", ToolbarAlign: "ToolbarAlign", ShowLegend: "ShowLegend", GridSize: "GridSize", AutoLayoutDirection: "AutoLayoutDirection", ConnectionLabelBackground: "ConnectionLabelBackground", ConnectionLabelBorderColor: "ConnectionLabelBorderColor", ConnectionLabelTextColor: "ConnectionLabelTextColor" }, outputs: { NodeSelected: "NodeSelected", NodeAdded: "NodeAdded", NodeRemoved: "NodeRemoved", NodeMoved: "NodeMoved", ConnectionCreated: "ConnectionCreated", ConnectionRemoved: "ConnectionRemoved", ConnectionReassigned: "ConnectionReassigned", ConnectionSelected: "ConnectionSelected", SelectionChanged: "SelectionChanged", CanvasClicked: "CanvasClicked", NodesChanged: "NodesChanged", ConnectionsChanged: "ConnectionsChanged", NodeEditRequested: "NodeEditRequested", ConnectionEditRequested: "ConnectionEditRequested", BeforeContextMenu: "BeforeContextMenu", AfterContextMenuAction: "AfterContextMenuAction", GridToggled: "GridToggled", MinimapToggled: "MinimapToggled", LegendToggled: "LegendToggled", ToolbarVisibilityChanged: "ToolbarVisibilityChanged" }, standalone: false, features: [i0.ɵɵProvidersFeature([FlowStateService, FlowLayoutService])], decls: 24, vars: 25, consts: [["canvasArea", ""], ["fZoomRef", "fComponent"], ["tabindex", "0", 1, "mj-flow-editor"], [1, "mj-flow-editor-toolbar-area"], ["type", "button", "title", "Show canvas tools", "aria-label", "Show canvas tools", 1, "mj-flow-editor-toolbar-chip"], ["type", "button", "title", "Show canvas tools", "aria-label", "Show canvas tools", 1, "mj-flow-editor-toolbar-tab"], [1, "mj-flow-editor-canvas-area"], [3, "NodeTypes"], [1, "mj-flow-editor-canvas"], ["fDraggable", "", 3, "fLoaded", "fCreateConnection", "fReassignConnection", "fCreateNode", "fSelectionChange", "fMoveNodes", "fDraggableDisabled", "fCanvasMoveTrigger", "vCellSize", "hCellSize", "fCellSizeWhileDragging"], [3, "fAlignThreshold"], ["fZoom", "", 3, "fCanvasChange", "fZoomMinimum", "fZoomMaximum", "fZoomStep", "position", "scale"], ["fType", "bezier", 3, "fRadius", "fOffset"], ["fType", "bezier", "fBehavior", "fixed", 3, "fConnectionId", "fOutputId", "fInputId", "fRadius", "fOffset", "fSelectionDisabled", "fReassignDisabled", "--connection-color", "--connection-width", "mj-flow-connection-colored", "mj-flow-connection-dashed", "mj-flow-connection-dotted", "mj-flow-connection-animated"], ["fNode", "", "fDragHandle", "", 3, "fNodeId", "fNodePosition", "fNodeDraggingDisabled", "fNodeSelectionDisabled", "fConnectOnNode", "Node", "TypeConfig", "ReadOnly"], ["fDragBlocker", "", 1, "mj-flow-editor-minimap"], [1, "mj-flow-editor-legend"], [1, "mj-flow-editor-empty"], [1, "mj-flow-context-menu", 3, "left", "top"], [3, "NodeCount", "ConnectionCount", "SelectedCount", "ZoomLevel"], [3, "ZoomInClicked", "ZoomOutClicked", "FitToScreenClicked", "AutoLayoutClicked", "GridToggled", "MinimapToggled", "LegendToggled", "PanModeToggled", "MinimizeClicked", "HideClicked", "ZoomLevel", "ShowGrid", "ShowMinimap", "ShowLegend", "ReadOnly", "PanMode"], ["type", "button", "title", "Show canvas tools", "aria-label", "Show canvas tools", 1, "mj-flow-editor-toolbar-chip", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-wrench"], ["type", "button", "title", "Show canvas tools", "aria-label", "Show canvas tools", 1, "mj-flow-editor-toolbar-tab", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-ellipsis"], [3, "NodeTypeActivated", "NodeTypes"], [3, "color", "radius"], ["viewBox", "0 0 10 10", "fMarker", "", "type", "end", "orient", "auto", 3, "refX", "refY", "height", "width"], ["d", "M0 0L10 5L0 10Z", "fill", "#94a3b8"], ["fType", "bezier", "fBehavior", "fixed", 3, "click", "contextmenu", "fConnectionId", "fOutputId", "fInputId", "fRadius", "fOffset", "fSelectionDisabled", "fReassignDisabled"], ["d", "M0 0L10 5L0 10Z"], ["fConnectionContent", "", 1, "mj-flow-connection-label", 3, "position", "backgroundColor", "borderColor", "color", "title"], ["fConnectionContent", "", 1, "mj-flow-connection-label", 3, "position", "title"], [1, "fa-solid", "mj-flow-connection-label-icon", 3, "ngClass", "color"], [1, "fa-solid", "mj-flow-connection-label-icon", 3, "ngClass"], ["fNode", "", "fDragHandle", "", 3, "contextmenu", "fNodeId", "fNodePosition", "fNodeDraggingDisabled", "fNodeSelectionDisabled", "fConnectOnNode", "Node", "TypeConfig", "ReadOnly"], [3, "fMinSize"], [1, "mj-flow-editor-legend-title"], [1, "mj-flow-editor-legend-section"], [1, "mj-flow-editor-legend-heading"], [1, "mj-flow-editor-legend-item"], ["width", "28", "height", "10", 1, "mj-flow-editor-legend-line-svg"], ["x1", "0", "y1", "5", "x2", "28", "y2", "5", "stroke", "#64748b", "stroke-width", "2"], ["x1", "0", "y1", "5", "x2", "28", "y2", "5", "stroke", "#16a34a", "stroke-width", "2"], [1, "fa-solid", "fa-circle-check", 2, "color", "#16a34a", "font-size", "10px"], ["x1", "0", "y1", "5", "x2", "28", "y2", "5", "stroke", "#f59e0b", "stroke-width", "2", "stroke-dasharray", "5 3"], ["x1", "0", "y1", "5", "x2", "28", "y2", "5", "stroke", "#ef4444", "stroke-width", "2"], [1, "fa-solid", "fa-triangle-exclamation", 2, "color", "#ef4444", "font-size", "10px"], [1, "mj-flow-editor-legend-swatch", 2, "background", "#3B82F6"], [1, "mj-flow-editor-legend-swatch", 2, "background", "#8B5CF6"], [1, "mj-flow-editor-legend-swatch", 2, "background", "#10B981"], [1, "mj-flow-editor-legend-swatch", 2, "background", "#F59E0B"], [1, "mj-flow-editor-legend-swatch", 2, "background", "#F97316"], [1, "mj-flow-editor-legend-box", 2, "border-color", "#16a34a", "background", "#f0fdf4"], [1, "mj-flow-editor-legend-box", 2, "border-color", "#ef4444", "background", "#fef2f2"], [1, "fa-solid", "fa-triangle-exclamation", 2, "color", "#ea580c", "font-size", "10px"], ["Icon", "fa-solid fa-diagram-project", 3, "Title"], [1, "mj-flow-editor-empty-subtitle"], [1, "mj-flow-context-menu", 3, "click"], ["type", "button", 1, "mj-flow-context-menu-item", 3, "click", "disabled"], [1, "fa-solid", 3, "ngClass"], [1, "mj-flow-context-menu-shortcut"], [1, "mj-flow-context-menu-divider"]], template: function FlowEditorComponent_Template(rf, ctx) { if (rf & 1) {
989
1096
  const _r1 = i0.ɵɵgetCurrentView();
990
1097
  i0.ɵɵelementStart(0, "div", 2);
991
- i0.ɵɵconditionalCreate(1, FlowEditorComponent_Conditional_1_Template, 2, 6, "div", 3);
992
- i0.ɵɵelementStart(2, "div", 4);
993
- i0.ɵɵconditionalCreate(3, FlowEditorComponent_Conditional_3_Template, 1, 1, "mj-flow-palette", 5);
994
- i0.ɵɵelementStart(4, "div", 6, 0)(6, "f-flow", 7);
995
- i0.ɵɵlistener("fLoaded", function FlowEditorComponent_Template_f_flow_fLoaded_6_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onFlowLoaded()); })("fCreateConnection", function FlowEditorComponent_Template_f_flow_fCreateConnection_6_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onCreateConnection($event)); })("fReassignConnection", function FlowEditorComponent_Template_f_flow_fReassignConnection_6_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onReassignConnection($event)); })("fCreateNode", function FlowEditorComponent_Template_f_flow_fCreateNode_6_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onCreateNode($event)); })("fSelectionChange", function FlowEditorComponent_Template_f_flow_fSelectionChange_6_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onSelectionChange($event)); })("fMoveNodes", function FlowEditorComponent_Template_f_flow_fMoveNodes_6_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onNodesMoved($event)); });
996
- i0.ɵɵconditionalCreate(7, FlowEditorComponent_Conditional_7_Template, 2, 2, "f-background");
997
- i0.ɵɵconditionalCreate(8, FlowEditorComponent_Conditional_8_Template, 1, 1, "f-line-alignment", 8);
998
- i0.ɵɵelementStart(9, "f-canvas", 9, 1);
999
- i0.ɵɵlistener("fCanvasChange", function FlowEditorComponent_Template_f_canvas_fCanvasChange_9_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onCanvasChange($event)); });
1000
- i0.ɵɵconditionalCreate(11, FlowEditorComponent_Conditional_11_Template, 3, 6, "f-connection-for-create", 10);
1001
- i0.ɵɵrepeaterCreate(12, FlowEditorComponent_For_13_Template, 4, 21, "f-connection", 11, ctx.trackConnectionById, true);
1002
- i0.ɵɵrepeaterCreate(14, FlowEditorComponent_For_15_Template, 1, 11, "mj-flow-node", 12, ctx.trackNodeById, true);
1098
+ i0.ɵɵconditionalCreate(1, FlowEditorComponent_Conditional_1_Template, 2, 7, "div", 3)(2, FlowEditorComponent_Conditional_2_Template, 2, 1, "button", 4)(3, FlowEditorComponent_Conditional_3_Template, 2, 1, "button", 5);
1099
+ i0.ɵɵelementStart(4, "div", 6);
1100
+ i0.ɵɵconditionalCreate(5, FlowEditorComponent_Conditional_5_Template, 1, 1, "mj-flow-palette", 7);
1101
+ i0.ɵɵelementStart(6, "div", 8, 0)(8, "f-flow", 9);
1102
+ i0.ɵɵlistener("fLoaded", function FlowEditorComponent_Template_f_flow_fLoaded_8_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onFlowLoaded()); })("fCreateConnection", function FlowEditorComponent_Template_f_flow_fCreateConnection_8_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onCreateConnection($event)); })("fReassignConnection", function FlowEditorComponent_Template_f_flow_fReassignConnection_8_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onReassignConnection($event)); })("fCreateNode", function FlowEditorComponent_Template_f_flow_fCreateNode_8_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onCreateNode($event)); })("fSelectionChange", function FlowEditorComponent_Template_f_flow_fSelectionChange_8_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onSelectionChange($event)); })("fMoveNodes", function FlowEditorComponent_Template_f_flow_fMoveNodes_8_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onNodesMoved($event)); });
1103
+ i0.ɵɵconditionalCreate(9, FlowEditorComponent_Conditional_9_Template, 2, 2, "f-background");
1104
+ i0.ɵɵconditionalCreate(10, FlowEditorComponent_Conditional_10_Template, 1, 1, "f-line-alignment", 10);
1105
+ i0.ɵɵelementStart(11, "f-canvas", 11, 1);
1106
+ i0.ɵɵlistener("fCanvasChange", function FlowEditorComponent_Template_f_canvas_fCanvasChange_11_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onCanvasChange($event)); });
1107
+ i0.ɵɵconditionalCreate(13, FlowEditorComponent_Conditional_13_Template, 3, 6, "f-connection-for-create", 12);
1108
+ i0.ɵɵrepeaterCreate(14, FlowEditorComponent_For_15_Template, 4, 25, "f-connection", 13, ctx.trackConnectionById, true);
1109
+ i0.ɵɵrepeaterCreate(16, FlowEditorComponent_For_17_Template, 1, 11, "mj-flow-node", 14, ctx.trackNodeById, true);
1003
1110
  i0.ɵɵelementEnd();
1004
- i0.ɵɵconditionalCreate(16, FlowEditorComponent_Conditional_16_Template, 1, 0, "f-selection-area");
1005
- i0.ɵɵconditionalCreate(17, FlowEditorComponent_Conditional_17_Template, 2, 1, "div", 13);
1111
+ i0.ɵɵconditionalCreate(18, FlowEditorComponent_Conditional_18_Template, 1, 0, "f-selection-area");
1112
+ i0.ɵɵconditionalCreate(19, FlowEditorComponent_Conditional_19_Template, 2, 1, "div", 15);
1006
1113
  i0.ɵɵelementEnd();
1007
- i0.ɵɵconditionalCreate(18, FlowEditorComponent_Conditional_18_Template, 63, 0, "div", 14);
1008
- i0.ɵɵconditionalCreate(19, FlowEditorComponent_Conditional_19_Template, 3, 2, "div", 15);
1114
+ i0.ɵɵconditionalCreate(20, FlowEditorComponent_Conditional_20_Template, 63, 0, "div", 16);
1115
+ i0.ɵɵconditionalCreate(21, FlowEditorComponent_Conditional_21_Template, 3, 2, "div", 17);
1009
1116
  i0.ɵɵelementEnd()();
1010
- i0.ɵɵconditionalCreate(20, FlowEditorComponent_Conditional_20_Template, 10, 6, "div", 16);
1011
- i0.ɵɵconditionalCreate(21, FlowEditorComponent_Conditional_21_Template, 1, 4, "mj-flow-status-bar", 17);
1117
+ i0.ɵɵconditionalCreate(22, FlowEditorComponent_Conditional_22_Template, 3, 4, "div", 18);
1118
+ i0.ɵɵconditionalCreate(23, FlowEditorComponent_Conditional_23_Template, 1, 4, "mj-flow-status-bar", 19);
1012
1119
  i0.ɵɵelementEnd();
1013
1120
  } if (rf & 2) {
1014
1121
  i0.ɵɵclassProp("mj-flow-editor--readonly", ctx.ReadOnly);
1015
1122
  i0.ɵɵadvance();
1016
- i0.ɵɵconditional(ctx.ShowToolbar ? 1 : -1);
1017
- i0.ɵɵadvance(2);
1018
- i0.ɵɵconditional(ctx.ShowPalette && !ctx.ReadOnly ? 3 : -1);
1123
+ i0.ɵɵconditional(ctx.ShowToolbar && ctx.EffectiveToolbarVisibility === "shown" ? 1 : ctx.ShowToolbar && ctx.EffectiveToolbarVisibility === "minimized" ? 2 : ctx.ShowToolbar && ctx.EffectiveToolbarVisibility === "hidden" ? 3 : -1);
1124
+ i0.ɵɵadvance(4);
1125
+ i0.ɵɵconditional(ctx.ShowPalette && !ctx.ReadOnly ? 5 : -1);
1019
1126
  i0.ɵɵadvance();
1020
1127
  i0.ɵɵclassProp("mj-flow-editor-canvas--pan-mode", ctx.panMode);
1021
1128
  i0.ɵɵadvance(2);
1022
1129
  i0.ɵɵproperty("fDraggableDisabled", false)("fCanvasMoveTrigger", ctx.canvasMoveTriggerFn)("vCellSize", ctx.GridSize)("hCellSize", ctx.GridSize)("fCellSizeWhileDragging", ctx.ShowGrid);
1023
1130
  i0.ɵɵadvance();
1024
- i0.ɵɵconditional(ctx.ShowGrid ? 7 : -1);
1131
+ i0.ɵɵconditional(ctx.ShowGrid ? 9 : -1);
1025
1132
  i0.ɵɵadvance();
1026
- i0.ɵɵconditional(!ctx.ReadOnly ? 8 : -1);
1133
+ i0.ɵɵconditional(!ctx.ReadOnly ? 10 : -1);
1027
1134
  i0.ɵɵadvance();
1028
1135
  i0.ɵɵproperty("fZoomMinimum", 0.15)("fZoomMaximum", 3)("fZoomStep", 0.1)("position", ctx.canvasPosition)("scale", ctx.canvasScale);
1029
1136
  i0.ɵɵadvance(2);
1030
- i0.ɵɵconditional(!ctx.ReadOnly ? 11 : -1);
1137
+ i0.ɵɵconditional(!ctx.ReadOnly ? 13 : -1);
1031
1138
  i0.ɵɵadvance();
1032
1139
  i0.ɵɵrepeater(ctx.Connections);
1033
1140
  i0.ɵɵadvance(2);
1034
1141
  i0.ɵɵrepeater(ctx.Nodes);
1035
1142
  i0.ɵɵadvance(2);
1036
- i0.ɵɵconditional(!ctx.ReadOnly ? 16 : -1);
1143
+ i0.ɵɵconditional(!ctx.ReadOnly ? 18 : -1);
1037
1144
  i0.ɵɵadvance();
1038
- i0.ɵɵconditional(ctx.ShowMinimap ? 17 : -1);
1145
+ i0.ɵɵconditional(ctx.ShowMinimap ? 19 : -1);
1039
1146
  i0.ɵɵadvance();
1040
- i0.ɵɵconditional(ctx.ShowLegend && ctx.Nodes.length > 0 ? 18 : -1);
1147
+ i0.ɵɵconditional(ctx.ShowLegend && ctx.Nodes.length > 0 ? 20 : -1);
1041
1148
  i0.ɵɵadvance();
1042
- i0.ɵɵconditional(ctx.Nodes.length === 0 ? 19 : -1);
1149
+ i0.ɵɵconditional(ctx.Nodes.length === 0 ? 21 : -1);
1043
1150
  i0.ɵɵadvance();
1044
- i0.ɵɵconditional(ctx.contextMenuVisible ? 20 : -1);
1151
+ i0.ɵɵconditional(ctx.contextMenuVisible ? 22 : -1);
1045
1152
  i0.ɵɵadvance();
1046
- i0.ɵɵconditional(ctx.ShowStatusBar ? 21 : -1);
1047
- } }, dependencies: [i3.NgClass, i4.FFlowComponent, i4.FCanvasComponent, i4.FBackgroundComponent, i4.FCirclePatternComponent, i4.FZoomDirective, i4.FConnectionContent, i4.FConnectionMarker, i4.FConnectionComponent, i4.FConnectionForCreateComponent, i4.FLineAlignmentComponent, i4.FMinimapComponent, i4.FNodeDirective, i4.FDragHandleDirective, i4.FSelectionAreaComponent, i4.FDragBlockerDirective, i4.FDraggableDirective, i5.MJEmptyStateComponent, i6.FlowNodeComponent, i7.FlowPaletteComponent, i8.FlowToolbarComponent, i9.FlowStatusBarComponent], styles: ["/* ============================================================\n Flow Editor \u2014 Main container styles\n ============================================================ */\n\n.mj-flow-editor {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n min-height: 400px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n overflow: hidden;\n outline: none;\n position: relative;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n}\n\n.mj-flow-editor--readonly .mj-flow-node-port {\n cursor: default;\n pointer-events: none;\n}\n\n/* \u2500\u2500 Toolbar Area \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-editor-toolbar-area {\n position: absolute;\n top: 10px;\n left: 50%;\n transform: translateX(-50%);\n z-index: 20;\n}\n\n/* \u2500\u2500 Canvas Area \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-editor-canvas-area {\n display: flex;\n flex: 1;\n overflow: hidden;\n position: relative;\n}\n\n.mj-flow-editor-canvas {\n flex: 1;\n position: relative;\n overflow: hidden;\n background: var(--mj-bg-surface);\n}\n\n.mj-flow-editor-canvas f-flow {\n width: 100%;\n height: 100%;\n}\n\n/* Pan mode \u2014 grab cursor, nodes pass through pointer events to canvas */\n.mj-flow-editor-canvas--pan-mode {\n cursor: grab;\n}\n\n.mj-flow-editor-canvas--pan-mode:active {\n cursor: grabbing;\n}\n\n.mj-flow-editor-canvas--pan-mode mj-flow-node {\n pointer-events: none;\n cursor: grab;\n}\n\n.mj-flow-editor-canvas--pan-mode f-connection {\n pointer-events: none;\n}\n\n.mj-flow-editor-canvas--pan-mode .mj-flow-connection-label {\n pointer-events: none;\n}\n\n/* \u2500\u2500 Minimap \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-editor-minimap {\n position: absolute;\n bottom: 12px;\n right: 12px;\n width: 160px;\n height: 120px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n box-shadow: var(--mj-shadow-sm);\n overflow: hidden;\n z-index: 15;\n}\n\n.mj-flow-editor-minimap f-minimap {\n width: 100%;\n height: 100%;\n}\n\n/* Foblex minimap SVG node rectangles (no default styles provided by Foblex) */\n.mj-flow-editor-minimap .f-minimap-node {\n fill: var(--mj-border-strong);\n stroke: var(--mj-text-disabled);\n stroke-width: 1;\n rx: 3;\n ry: 3;\n}\n\n.mj-flow-editor-minimap .f-minimap-node.f-selected {\n fill: color-mix(in srgb, var(--mj-brand-primary) 50%, var(--mj-bg-surface));\n stroke: var(--mj-brand-primary);\n stroke-width: 1.5;\n}\n\n.mj-flow-editor-minimap .f-minimap-group {\n fill: var(--mj-border-default);\n stroke: var(--mj-text-disabled);\n stroke-width: 0.5;\n rx: 2;\n ry: 2;\n}\n\n/* Viewport indicator rectangle */\n.mj-flow-editor-minimap .f-minimap-view {\n fill: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n stroke: var(--mj-brand-primary);\n stroke-width: 1.5;\n}\n\n/* \u2500\u2500 Empty State \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-editor-empty {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n pointer-events: none;\n z-index: 5;\n}\n\n.mj-flow-editor-empty-subtitle {\n font-size: var(--mj-text-sm);\n color: var(--mj-text-disabled);\n margin: 0;\n}\n\n/* \u2500\u2500 Connection Labels \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-connection-label {\n display: inline-flex;\n align-items: flex-start;\n gap: 5px;\n background: var(--mj-bg-surface);\n border: 1.5px solid var(--mj-border-strong);\n border-radius: 5px;\n padding: 4px 10px;\n font-size: 11px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n white-space: nowrap;\n box-shadow: var(--mj-shadow-sm);\n pointer-events: none;\n line-height: 1.4;\n text-align: center;\n}\n\n.mj-flow-connection-label-icon {\n font-size: 10px;\n flex-shrink: 0;\n margin-top: 2px;\n}\n\n/* \u2500\u2500 Foblex Overrides \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n/* Canvas \u2014 transparent so the grid pattern shows through */\nf-canvas {\n background: transparent;\n}\n\n/* Selection area */\nf-selection-area {\n --f-selection-area-background: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n --f-selection-area-border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n}\n\n/* Line alignment guides */\nf-line-alignment {\n --f-line-alignment-color: var(--mj-brand-primary);\n}\n\n/* Connection paths \u2014 default stroke color prevents invisible connections */\n.f-connection path {\n stroke: var(--mj-text-disabled);\n stroke-width: 2;\n fill: none;\n transition: stroke 0.15s ease, stroke-width 0.15s ease;\n}\n\n.f-connection:hover path {\n stroke-width: 3;\n}\n\n.f-connection.f-selected path {\n stroke: var(--mj-brand-primary);\n stroke-width: 3;\n}\n\n/* Colored connections use the --connection-color custom property,\n defaulting to neutral when no color is specified by the consumer */\n.mj-flow-connection-colored path {\n stroke: var(--connection-color, var(--mj-text-disabled));\n}\n\n.mj-flow-connection-colored.f-selected path {\n stroke: var(--connection-color, var(--mj-brand-primary));\n stroke-width: 3;\n filter: brightness(0.85);\n}\n\n/* Dashed connection style */\n.mj-flow-connection-dashed path {\n stroke-dasharray: 8 4;\n}\n\n/* Dotted connection style */\n.mj-flow-connection-dotted path {\n stroke-dasharray: 3 3;\n}\n\n/* Connection for create (dragging) */\n.f-connection-for-create path {\n stroke: var(--mj-text-disabled);\n stroke-dasharray: 6 3;\n stroke-width: 2;\n}\n\n/* \u2500\u2500 Legend \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-editor-legend {\n position: absolute;\n bottom: 12px;\n left: 12px;\n background: color-mix(in srgb, var(--mj-bg-surface) 92%, transparent);\n backdrop-filter: blur(6px);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n padding: 10px 14px;\n box-shadow: var(--mj-shadow-sm);\n z-index: 15;\n font-size: 11px;\n color: var(--mj-text-secondary);\n max-width: 200px;\n}\n\n.mj-flow-editor-legend-title {\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin-bottom: 8px;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.mj-flow-editor-legend-section {\n margin-bottom: 8px;\n}\n\n.mj-flow-editor-legend-section:last-child {\n margin-bottom: 0;\n}\n\n.mj-flow-editor-legend-heading {\n font-size: 10px;\n font-weight: 600;\n color: var(--mj-text-disabled);\n text-transform: uppercase;\n letter-spacing: 0.3px;\n margin-bottom: 4px;\n}\n\n.mj-flow-editor-legend-item {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 2px 0;\n font-size: 11px;\n color: var(--mj-text-secondary);\n}\n\n.mj-flow-editor-legend-svg,\n.mj-flow-editor-legend-line-svg {\n flex-shrink: 0;\n}\n\n.mj-flow-editor-legend-swatch {\n display: inline-block;\n width: 10px;\n height: 10px;\n border-radius: var(--mj-radius-sm);\n flex-shrink: 0;\n}\n\n.mj-flow-editor-legend-box {\n display: inline-block;\n width: 14px;\n height: 10px;\n border: 2px solid;\n border-radius: var(--mj-radius-sm);\n flex-shrink: 0;\n}\n\n/* \u2500\u2500 Context Menu \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-context-menu {\n position: fixed;\n min-width: 180px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n box-shadow: var(--mj-shadow-lg);\n padding: 4px;\n z-index: 9999;\n animation: mj-ctx-fade-in 0.1s ease-out;\n}\n\n@keyframes mj-ctx-fade-in {\n from { opacity: 0; transform: scale(0.95); }\n to { opacity: 1; transform: scale(1); }\n}\n\n.mj-flow-context-menu-item {\n display: flex;\n align-items: center;\n gap: 10px;\n width: 100%;\n padding: 8px 12px;\n border: none;\n background: none;\n font-size: var(--mj-text-sm);\n font-weight: 450;\n color: var(--mj-text-secondary);\n cursor: pointer;\n border-radius: 5px;\n text-align: left;\n transition: background-color 0.1s ease;\n}\n\n.mj-flow-context-menu-item:hover {\n background-color: var(--mj-bg-surface-sunken);\n}\n\n.mj-flow-context-menu-item i {\n width: 16px;\n text-align: center;\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n}\n\n.mj-flow-context-menu-item--danger {\n color: var(--mj-status-error);\n}\n\n.mj-flow-context-menu-item--danger:hover {\n background-color: var(--mj-status-error-subtle);\n}\n\n.mj-flow-context-menu-item--danger i {\n color: var(--mj-status-error);\n}\n\n.mj-flow-context-menu-divider {\n height: 1px;\n background: var(--mj-border-default);\n margin: 4px 8px;\n}\n\n/* \u2500\u2500 Focus Indicators (Accessibility) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-toolbar-btn:focus-visible,\n.mj-agent-editor-btn:focus-visible,\n.mj-agent-editor-view-btn:focus-visible,\n.mj-agent-props-close:focus-visible,\n.mj-agent-props-delete-btn:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n}\n\n.mj-flow-palette-item:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 1px;\n border-radius: var(--mj-radius-md);\n}\n"], encapsulation: 2 });
1153
+ i0.ɵɵconditional(ctx.ShowStatusBar ? 23 : -1);
1154
+ } }, dependencies: [i3.NgClass, i4.FFlowComponent, i4.FCanvasComponent, i4.FBackgroundComponent, i4.FCirclePatternComponent, i4.FZoomDirective, i4.FConnectionContent, i4.FConnectionMarker, i4.FConnectionComponent, i4.FConnectionForCreateComponent, i4.FLineAlignmentComponent, i4.FMinimapComponent, i4.FNodeDirective, i4.FDragHandleDirective, i4.FSelectionAreaComponent, i4.FDragBlockerDirective, i4.FDraggableDirective, i5.MJEmptyStateComponent, i6.FlowNodeComponent, i7.FlowPaletteComponent, i8.FlowToolbarComponent, i9.FlowStatusBarComponent], styles: ["/* ============================================================\n Flow Editor \u2014 Main container styles\n ============================================================ */\n\n/* The HOST is a custom element, which is `display: inline` with auto height until told otherwise.\n Without this, `.mj-flow-editor { height: 100% }` below resolved against an auto-height parent \u2014\n which means auto \u2014 so the canvas fell back to its `min-height` floor and sat at 400px no matter\n how much room its pane actually had.\n\n `height: 100%` here is safe for hosts that DON'T give it a box: it resolves to auto in that case,\n and the floor takes over exactly as before. */\n:host {\n display: block;\n height: 100%;\n min-height: 0;\n}\n\n.mj-flow-editor {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n min-height: 400px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n overflow: hidden;\n outline: none;\n position: relative;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n}\n\n.mj-flow-editor--readonly .mj-flow-node-port {\n cursor: default;\n pointer-events: none;\n}\n\n/* \u2500\u2500 Toolbar Area \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-editor-toolbar-area,\n.mj-flow-editor-toolbar-chip,\n.mj-flow-editor-toolbar-tab {\n position: absolute;\n top: 10px;\n z-index: 20;\n}\n.mj-flow-editor-toolbar-area[data-align=\"center\"],\n.mj-flow-editor-toolbar-chip[data-align=\"center\"],\n.mj-flow-editor-toolbar-tab[data-align=\"center\"] {\n left: 50%;\n transform: translateX(-50%);\n}\n.mj-flow-editor-toolbar-area[data-align=\"left\"],\n.mj-flow-editor-toolbar-chip[data-align=\"left\"],\n.mj-flow-editor-toolbar-tab[data-align=\"left\"] {\n left: 10px;\n}\n.mj-flow-editor-toolbar-area[data-align=\"right\"],\n.mj-flow-editor-toolbar-chip[data-align=\"right\"],\n.mj-flow-editor-toolbar-tab[data-align=\"right\"] {\n right: 10px;\n}\n\n.mj-flow-editor-toolbar-chip,\n.mj-flow-editor-toolbar-tab {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-elevated);\n color: var(--mj-text-secondary);\n cursor: pointer;\n}\n.mj-flow-editor-toolbar-chip:hover,\n.mj-flow-editor-toolbar-tab:hover {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface-hover);\n}\n.mj-flow-editor-toolbar-chip {\n width: 32px;\n height: 32px;\n border-radius: var(--mj-radius-md);\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06);\n}\n.mj-flow-editor-toolbar-tab {\n width: 22px;\n height: 18px;\n padding: 0;\n border-radius: var(--mj-radius-sm);\n opacity: 0.55;\n}\n.mj-flow-editor-toolbar-tab:hover { opacity: 1; }\n\n/* \u2500\u2500 Canvas Area \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-editor-canvas-area {\n display: flex;\n flex: 1;\n overflow: hidden;\n position: relative;\n}\n\n.mj-flow-editor-canvas {\n flex: 1;\n position: relative;\n overflow: hidden;\n background: var(--mj-bg-surface);\n}\n\n.mj-flow-editor-canvas f-flow {\n width: 100%;\n height: 100%;\n}\n\n/* Pan mode \u2014 grab cursor, nodes pass through pointer events to canvas */\n.mj-flow-editor-canvas--pan-mode {\n cursor: grab;\n}\n\n.mj-flow-editor-canvas--pan-mode:active {\n cursor: grabbing;\n}\n\n.mj-flow-editor-canvas--pan-mode mj-flow-node {\n pointer-events: none;\n cursor: grab;\n}\n\n.mj-flow-editor-canvas--pan-mode f-connection {\n pointer-events: none;\n}\n\n.mj-flow-editor-canvas--pan-mode .mj-flow-connection-label {\n pointer-events: none;\n}\n\n/* \u2500\u2500 Minimap \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-editor-minimap {\n position: absolute;\n bottom: 12px;\n right: 12px;\n width: 160px;\n height: 120px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n box-shadow: var(--mj-shadow-sm);\n overflow: hidden;\n z-index: 15;\n}\n\n.mj-flow-editor-minimap f-minimap {\n width: 100%;\n height: 100%;\n}\n\n/* Foblex minimap SVG node rectangles (no default styles provided by Foblex) */\n.mj-flow-editor-minimap .f-minimap-node {\n fill: var(--mj-border-strong);\n stroke: var(--mj-text-disabled);\n stroke-width: 1;\n rx: 3;\n ry: 3;\n}\n\n.mj-flow-editor-minimap .f-minimap-node.f-selected {\n fill: color-mix(in srgb, var(--mj-brand-primary) 50%, var(--mj-bg-surface));\n stroke: var(--mj-brand-primary);\n stroke-width: 1.5;\n}\n\n.mj-flow-editor-minimap .f-minimap-group {\n fill: var(--mj-border-default);\n stroke: var(--mj-text-disabled);\n stroke-width: 0.5;\n rx: 2;\n ry: 2;\n}\n\n/* Viewport indicator rectangle */\n.mj-flow-editor-minimap .f-minimap-view {\n fill: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n stroke: var(--mj-brand-primary);\n stroke-width: 1.5;\n}\n\n/* \u2500\u2500 Empty State \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-editor-empty {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n pointer-events: none;\n z-index: 5;\n}\n\n.mj-flow-editor-empty-subtitle {\n font-size: var(--mj-text-sm);\n color: var(--mj-text-disabled);\n margin: 0;\n}\n\n/* \u2500\u2500 Connection Labels \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-connection-label {\n display: inline-flex;\n align-items: flex-start;\n gap: 5px;\n background: var(--mj-bg-surface);\n border: 1.5px solid var(--mj-border-strong);\n border-radius: 5px;\n padding: 4px 10px;\n font-size: 11px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n white-space: nowrap;\n box-shadow: var(--mj-shadow-sm);\n pointer-events: none;\n line-height: 1.4;\n text-align: center;\n}\n\n.mj-flow-connection-label-icon {\n font-size: 10px;\n flex-shrink: 0;\n margin-top: 2px;\n}\n\n/* \u2500\u2500 Foblex Overrides \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n/* Canvas \u2014 transparent so the grid pattern shows through */\nf-canvas {\n background: transparent;\n}\n\n/* Selection area */\nf-selection-area {\n --f-selection-area-background: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n --f-selection-area-border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n}\n\n/* Line alignment guides */\nf-line-alignment {\n --f-line-alignment-color: var(--mj-brand-primary);\n}\n\n/* Connection paths \u2014 default stroke color prevents invisible connections */\n.f-connection path {\n stroke: var(--mj-text-disabled);\n stroke-width: var(--connection-width, 2px);\n fill: none;\n transition: stroke 0.15s ease, stroke-width 0.15s ease;\n}\n\n.f-connection:hover path {\n stroke-width: calc(var(--connection-width, 2px) + 1px);\n}\n\n.f-connection.f-selected path {\n stroke: var(--mj-brand-primary);\n stroke-width: max(3px, var(--connection-width, 2px));\n}\n\n/* Colored connections use the --connection-color custom property,\n defaulting to neutral when no color is specified by the consumer */\n.mj-flow-connection-colored path {\n stroke: var(--connection-color, var(--mj-text-disabled));\n}\n\n.mj-flow-connection-colored.f-selected path {\n stroke: var(--connection-color, var(--mj-brand-primary));\n stroke-width: max(3px, var(--connection-width, 2px));\n filter: brightness(0.85);\n}\n\n/* Dashed connection style */\n.mj-flow-connection-dashed path {\n stroke-dasharray: 8 4;\n}\n\n/* Dotted connection style */\n.mj-flow-connection-dotted path {\n stroke-dasharray: 3 3;\n}\n\n.mj-flow-connection-animated path {\n stroke-dasharray: 14 10;\n stroke-linecap: round;\n stroke-width: var(--connection-width, 4.5px);\n animation: mj-flow-dash 0.5s linear infinite;\n filter: drop-shadow(0 0 5px color-mix(in srgb, var(--connection-color, var(--mj-brand-primary)) 70%, transparent));\n}\n@keyframes mj-flow-dash {\n to { stroke-dashoffset: -24; }\n}\n\n/* Connection for create (dragging) */\n.f-connection-for-create path {\n stroke: var(--mj-text-disabled);\n stroke-dasharray: 6 3;\n stroke-width: 2;\n}\n\n/* \u2500\u2500 Legend \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-editor-legend {\n position: absolute;\n bottom: 12px;\n left: 12px;\n background: color-mix(in srgb, var(--mj-bg-surface) 92%, transparent);\n backdrop-filter: blur(6px);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n padding: 10px 14px;\n box-shadow: var(--mj-shadow-sm);\n z-index: 15;\n font-size: 11px;\n color: var(--mj-text-secondary);\n max-width: 200px;\n}\n\n.mj-flow-editor-legend-title {\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin-bottom: 8px;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.mj-flow-editor-legend-section {\n margin-bottom: 8px;\n}\n\n.mj-flow-editor-legend-section:last-child {\n margin-bottom: 0;\n}\n\n.mj-flow-editor-legend-heading {\n font-size: 10px;\n font-weight: 600;\n color: var(--mj-text-disabled);\n text-transform: uppercase;\n letter-spacing: 0.3px;\n margin-bottom: 4px;\n}\n\n.mj-flow-editor-legend-item {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 2px 0;\n font-size: 11px;\n color: var(--mj-text-secondary);\n}\n\n.mj-flow-editor-legend-svg,\n.mj-flow-editor-legend-line-svg {\n flex-shrink: 0;\n}\n\n.mj-flow-editor-legend-swatch {\n display: inline-block;\n width: 10px;\n height: 10px;\n border-radius: var(--mj-radius-sm);\n flex-shrink: 0;\n}\n\n.mj-flow-editor-legend-box {\n display: inline-block;\n width: 14px;\n height: 10px;\n border: 2px solid;\n border-radius: var(--mj-radius-sm);\n flex-shrink: 0;\n}\n\n/* \u2500\u2500 Context Menu \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-context-menu {\n position: fixed;\n min-width: 180px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n box-shadow: var(--mj-shadow-lg);\n padding: 4px;\n z-index: 9999;\n animation: mj-ctx-fade-in 0.1s ease-out;\n}\n\n@keyframes mj-ctx-fade-in {\n from { opacity: 0; transform: scale(0.95); }\n to { opacity: 1; transform: scale(1); }\n}\n\n.mj-flow-context-menu-item {\n display: flex;\n align-items: center;\n gap: 10px;\n width: 100%;\n padding: 8px 12px;\n border: none;\n background: none;\n font-size: var(--mj-text-sm);\n font-weight: 450;\n color: var(--mj-text-secondary);\n cursor: pointer;\n border-radius: 5px;\n text-align: left;\n transition: background-color 0.1s ease;\n}\n\n.mj-flow-context-menu-item:hover {\n background-color: var(--mj-bg-surface-sunken);\n}\n\n.mj-flow-context-menu-item i {\n width: 16px;\n text-align: center;\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n}\n\n.mj-flow-context-menu-shortcut {\n margin-left: auto;\n padding: 0 4px;\n border: 1px solid var(--mj-border-default);\n border-radius: 3px;\n font-size: 10px;\n font-family: inherit;\n color: var(--mj-text-muted);\n}\n\n.mj-flow-context-menu-item--danger {\n color: var(--mj-status-error);\n}\n\n.mj-flow-context-menu-item--danger:hover {\n background-color: var(--mj-status-error-subtle);\n}\n\n.mj-flow-context-menu-item--danger i {\n color: var(--mj-status-error);\n}\n\n.mj-flow-context-menu-divider {\n height: 1px;\n background: var(--mj-border-default);\n margin: 4px 8px;\n}\n\n/* \u2500\u2500 Focus Indicators (Accessibility) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-toolbar-btn:focus-visible,\n.mj-agent-editor-btn:focus-visible,\n.mj-agent-editor-view-btn:focus-visible,\n.mj-agent-props-close:focus-visible,\n.mj-agent-props-delete-btn:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n}\n\n.mj-flow-palette-item:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 1px;\n border-radius: var(--mj-radius-md);\n}\n"], encapsulation: 2 });
1048
1155
  }
1049
1156
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(FlowEditorComponent, [{
1050
1157
  type: Component,
1051
- args: [{ standalone: false, selector: 'mj-flow-editor', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.Default, providers: [FlowStateService, FlowLayoutService], template: "<div class=\"mj-flow-editor\" [class.mj-flow-editor--readonly]=\"ReadOnly\" tabindex=\"0\">\n\n <!-- Canvas Toolbar -->\n @if (ShowToolbar) {\n <div class=\"mj-flow-editor-toolbar-area\">\n <mj-flow-toolbar\n [ZoomLevel]=\"zoomLevel\"\n [ShowGrid]=\"ShowGrid\"\n [ShowMinimap]=\"ShowMinimap\"\n [ShowLegend]=\"ShowLegend\"\n [ReadOnly]=\"ReadOnly\"\n [PanMode]=\"panMode\"\n (ZoomInClicked)=\"ZoomIn()\"\n (ZoomOutClicked)=\"ZoomOut()\"\n (FitToScreenClicked)=\"ZoomToFit()\"\n (AutoLayoutClicked)=\"AutoArrange()\"\n (GridToggled)=\"onGridToggled($event)\"\n (MinimapToggled)=\"onMinimapToggled($event)\"\n (LegendToggled)=\"onLegendToggled($event)\"\n (PanModeToggled)=\"onPanModeToggled($event)\">\n </mj-flow-toolbar>\n </div>\n }\n\n <!-- Main Canvas Area -->\n <div class=\"mj-flow-editor-canvas-area\">\n\n <!-- Palette Sidebar -->\n @if (ShowPalette && !ReadOnly) {\n <mj-flow-palette\n [NodeTypes]=\"NodeTypes\"\n (NodeTypeActivated)=\"onPaletteNodeTypeActivated($event)\">\n </mj-flow-palette>\n }\n\n <!-- Foblex Canvas -->\n <div class=\"mj-flow-editor-canvas\" #canvasArea\n [class.mj-flow-editor-canvas--pan-mode]=\"panMode\">\n <f-flow fDraggable\n [fDraggableDisabled]=\"false\"\n [fCanvasMoveTrigger]=\"canvasMoveTriggerFn\"\n [vCellSize]=\"GridSize\"\n [hCellSize]=\"GridSize\"\n [fCellSizeWhileDragging]=\"ShowGrid\"\n (fLoaded)=\"onFlowLoaded()\"\n (fCreateConnection)=\"onCreateConnection($event)\"\n (fReassignConnection)=\"onReassignConnection($event)\"\n (fCreateNode)=\"onCreateNode($event)\"\n (fSelectionChange)=\"onSelectionChange($event)\"\n (fMoveNodes)=\"onNodesMoved($event)\">\n\n <!-- Background grid \u2014 MUST be direct child of f-flow (Foblex content projection requires it) -->\n @if (ShowGrid) {\n <f-background>\n <f-circle-pattern [color]=\"'#94a3b8'\" [radius]=\"24\"></f-circle-pattern>\n </f-background>\n }\n\n <!-- Alignment snap lines \u2014 direct child of f-flow -->\n @if (!ReadOnly) {\n <f-line-alignment [fAlignThreshold]=\"10\"></f-line-alignment>\n }\n\n <f-canvas fZoom #fZoomRef=\"fComponent\"\n [fZoomMinimum]=\"0.15\"\n [fZoomMaximum]=\"3\"\n [fZoomStep]=\"0.1\"\n [position]=\"canvasPosition\"\n [scale]=\"canvasScale\"\n (fCanvasChange)=\"onCanvasChange($event)\">\n\n <!-- Interactive connection drawing -->\n @if (!ReadOnly) {\n <f-connection-for-create\n fType=\"bezier\"\n [fRadius]=\"8\"\n [fOffset]=\"12\">\n <svg viewBox=\"0 0 10 10\" fMarker type=\"end\"\n orient=\"auto\" [refX]=\"9\" [refY]=\"5\" [height]=\"10\" [width]=\"10\">\n <path d=\"M0 0L10 5L0 10Z\" fill=\"#94a3b8\"/>\n </svg>\n </f-connection-for-create>\n }\n\n <!-- Connections -->\n @for (conn of Connections; track trackConnectionById($index, conn)) {\n <f-connection\n [fConnectionId]=\"conn.ID\"\n [fOutputId]=\"conn.SourcePortID\"\n [fInputId]=\"conn.TargetPortID\"\n fType=\"bezier\"\n fBehavior=\"fixed\"\n [fRadius]=\"8\"\n [fOffset]=\"12\"\n [fSelectionDisabled]=\"false\"\n [fReassignDisabled]=\"ReadOnly\"\n [style.--connection-color]=\"conn.Color || '#94a3b8'\"\n [class.mj-flow-connection-colored]=\"!!conn.Color\"\n [class.mj-flow-connection-dashed]=\"conn.Style === 'dashed'\"\n [class.mj-flow-connection-dotted]=\"conn.Style === 'dotted'\"\n (click)=\"onConnectionClicked($event, conn)\"\n (contextmenu)=\"onConnectionContextMenu($event, conn)\">\n <!-- Arrow marker -->\n <svg viewBox=\"0 0 10 10\" fMarker type=\"end\"\n orient=\"auto\" [refX]=\"9\" [refY]=\"5\" [height]=\"10\" [width]=\"10\">\n <path d=\"M0 0L10 5L0 10Z\" [attr.fill]=\"conn.Color || '#94a3b8'\"/>\n </svg>\n <!-- Connection label -->\n @if (conn.Label) {\n <div fConnectionContent [position]=\"0.5\"\n class=\"mj-flow-connection-label\"\n [style.backgroundColor]=\"ConnectionLabelBackground\"\n [style.borderColor]=\"ConnectionLabelBorderColor\"\n [style.color]=\"ConnectionLabelTextColor\"\n [title]=\"conn.LabelDetail || conn.Label || ''\">\n @if (conn.LabelIcon) {\n <i\n class=\"fa-solid mj-flow-connection-label-icon\"\n [ngClass]=\"conn.LabelIcon\"\n [style.color]=\"conn.LabelIconColor || 'inherit'\"></i>\n }\n {{ conn.Label }}\n </div>\n }\n </f-connection>\n }\n\n <!-- Nodes -->\n @for (node of Nodes; track trackNodeById($index, node)) {\n <mj-flow-node\n fNode\n fDragHandle\n [fNodeId]=\"node.ID\"\n [fNodePosition]=\"{ x: node.Position.X, y: node.Position.Y }\"\n [fNodeDraggingDisabled]=\"ReadOnly || panMode || node.Locked === true\"\n [fNodeSelectionDisabled]=\"panMode\"\n [fConnectOnNode]=\"!ReadOnly && !panMode\"\n [Node]=\"node\"\n [TypeConfig]=\"GetTypeConfig(node.Type)\"\n [ReadOnly]=\"ReadOnly\"\n (contextmenu)=\"onNodeContextMenu($event, node)\">\n </mj-flow-node>\n }\n\n </f-canvas>\n\n <!-- Rubber-band selection \u2014 direct child of f-flow -->\n @if (!ReadOnly) {\n <f-selection-area></f-selection-area>\n }\n\n <!-- Minimap -->\n @if (ShowMinimap) {\n <div class=\"mj-flow-editor-minimap\" fDragBlocker>\n <f-minimap [fMinSize]=\"1500\"></f-minimap>\n </div>\n }\n </f-flow>\n\n <!-- Legend -->\n @if (ShowLegend && Nodes.length > 0) {\n <div class=\"mj-flow-editor-legend\">\n <div class=\"mj-flow-editor-legend-title\">Legend</div>\n <div class=\"mj-flow-editor-legend-section\">\n <div class=\"mj-flow-editor-legend-heading\">Connections</div>\n <div class=\"mj-flow-editor-legend-item\">\n <svg class=\"mj-flow-editor-legend-line-svg\" width=\"28\" height=\"10\"><line x1=\"0\" y1=\"5\" x2=\"28\" y2=\"5\" stroke=\"#64748b\" stroke-width=\"2\"/></svg>\n <span>Only exit path</span>\n </div>\n <div class=\"mj-flow-editor-legend-item\">\n <svg class=\"mj-flow-editor-legend-line-svg\" width=\"28\" height=\"10\"><line x1=\"0\" y1=\"5\" x2=\"28\" y2=\"5\" stroke=\"#16a34a\" stroke-width=\"2\"/></svg>\n <i class=\"fa-solid fa-circle-check\" style=\"color:#16a34a;font-size:10px;\"></i>\n <span>Default (fallback)</span>\n </div>\n <div class=\"mj-flow-editor-legend-item\">\n <svg class=\"mj-flow-editor-legend-line-svg\" width=\"28\" height=\"10\"><line x1=\"0\" y1=\"5\" x2=\"28\" y2=\"5\" stroke=\"#f59e0b\" stroke-width=\"2\" stroke-dasharray=\"5 3\"/></svg>\n <span>Conditional</span>\n </div>\n <div class=\"mj-flow-editor-legend-item\">\n <svg class=\"mj-flow-editor-legend-line-svg\" width=\"28\" height=\"10\"><line x1=\"0\" y1=\"5\" x2=\"28\" y2=\"5\" stroke=\"#ef4444\" stroke-width=\"2\"/></svg>\n <i class=\"fa-solid fa-triangle-exclamation\" style=\"color:#ef4444;font-size:10px;\"></i>\n <span>Duplicate defaults</span>\n </div>\n </div>\n <div class=\"mj-flow-editor-legend-section\">\n <div class=\"mj-flow-editor-legend-heading\">Step Types</div>\n <div class=\"mj-flow-editor-legend-item\">\n <span class=\"mj-flow-editor-legend-swatch\" style=\"background:#3B82F6\"></span>\n <span>Action</span>\n </div>\n <div class=\"mj-flow-editor-legend-item\">\n <span class=\"mj-flow-editor-legend-swatch\" style=\"background:#8B5CF6\"></span>\n <span>Prompt</span>\n </div>\n <div class=\"mj-flow-editor-legend-item\">\n <span class=\"mj-flow-editor-legend-swatch\" style=\"background:#10B981\"></span>\n <span>Sub-Agent</span>\n </div>\n <div class=\"mj-flow-editor-legend-item\">\n <span class=\"mj-flow-editor-legend-swatch\" style=\"background:#F59E0B\"></span>\n <span>For Each</span>\n </div>\n <div class=\"mj-flow-editor-legend-item\">\n <span class=\"mj-flow-editor-legend-swatch\" style=\"background:#F97316\"></span>\n <span>While</span>\n </div>\n </div>\n <div class=\"mj-flow-editor-legend-section\">\n <div class=\"mj-flow-editor-legend-heading\">Borders</div>\n <div class=\"mj-flow-editor-legend-item\">\n <span class=\"mj-flow-editor-legend-box\" style=\"border-color:#16a34a;background:#f0fdf4;\"></span>\n <span>Start node</span>\n </div>\n <div class=\"mj-flow-editor-legend-item\">\n <span class=\"mj-flow-editor-legend-box\" style=\"border-color:#ef4444;background:#fef2f2;\"></span>\n <i class=\"fa-solid fa-triangle-exclamation\" style=\"color:#ea580c;font-size:10px;\"></i>\n <span>Missing config</span>\n </div>\n </div>\n </div>\n }\n\n <!-- Empty state overlay -->\n @if (Nodes.length === 0) {\n <div class=\"mj-flow-editor-empty\">\n <mj-empty-state\n Icon=\"fa-solid fa-diagram-project\"\n [Title]=\"EmptyStateTitle\">\n @if (!ReadOnly) {\n <p class=\"mj-flow-editor-empty-subtitle\">\n Or use auto-layout after adding steps to arrange them automatically\n </p>\n }\n </mj-empty-state>\n </div>\n }\n </div>\n </div>\n\n <!-- Context Menu -->\n @if (contextMenuVisible) {\n <div\n class=\"mj-flow-context-menu\"\n [style.left.px]=\"contextMenuX\"\n [style.top.px]=\"contextMenuY\"\n (click)=\"$event.stopPropagation()\">\n <button class=\"mj-flow-context-menu-item\" (click)=\"onContextMenuAction('edit')\">\n <i class=\"fa-solid fa-pen-to-square\"></i>\n <span>Edit {{ contextMenuTargetType === 'node' ? 'Node' : 'Connection' }}</span>\n </button>\n <div class=\"mj-flow-context-menu-divider\"></div>\n <button class=\"mj-flow-context-menu-item mj-flow-context-menu-item--danger\" (click)=\"onContextMenuAction('remove')\">\n <i class=\"fa-solid fa-trash-can\"></i>\n <span>Remove {{ contextMenuTargetType === 'node' ? 'Node' : 'Connection' }}</span>\n </button>\n </div>\n }\n\n <!-- Status Bar -->\n @if (ShowStatusBar) {\n <mj-flow-status-bar\n [NodeCount]=\"Nodes.length\"\n [ConnectionCount]=\"Connections.length\"\n [SelectedCount]=\"selectedCount\"\n [ZoomLevel]=\"zoomLevel\">\n </mj-flow-status-bar>\n }\n</div>\n", styles: ["/* ============================================================\n Flow Editor \u2014 Main container styles\n ============================================================ */\n\n.mj-flow-editor {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n min-height: 400px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n overflow: hidden;\n outline: none;\n position: relative;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n}\n\n.mj-flow-editor--readonly .mj-flow-node-port {\n cursor: default;\n pointer-events: none;\n}\n\n/* \u2500\u2500 Toolbar Area \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-editor-toolbar-area {\n position: absolute;\n top: 10px;\n left: 50%;\n transform: translateX(-50%);\n z-index: 20;\n}\n\n/* \u2500\u2500 Canvas Area \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-editor-canvas-area {\n display: flex;\n flex: 1;\n overflow: hidden;\n position: relative;\n}\n\n.mj-flow-editor-canvas {\n flex: 1;\n position: relative;\n overflow: hidden;\n background: var(--mj-bg-surface);\n}\n\n.mj-flow-editor-canvas f-flow {\n width: 100%;\n height: 100%;\n}\n\n/* Pan mode \u2014 grab cursor, nodes pass through pointer events to canvas */\n.mj-flow-editor-canvas--pan-mode {\n cursor: grab;\n}\n\n.mj-flow-editor-canvas--pan-mode:active {\n cursor: grabbing;\n}\n\n.mj-flow-editor-canvas--pan-mode mj-flow-node {\n pointer-events: none;\n cursor: grab;\n}\n\n.mj-flow-editor-canvas--pan-mode f-connection {\n pointer-events: none;\n}\n\n.mj-flow-editor-canvas--pan-mode .mj-flow-connection-label {\n pointer-events: none;\n}\n\n/* \u2500\u2500 Minimap \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-editor-minimap {\n position: absolute;\n bottom: 12px;\n right: 12px;\n width: 160px;\n height: 120px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n box-shadow: var(--mj-shadow-sm);\n overflow: hidden;\n z-index: 15;\n}\n\n.mj-flow-editor-minimap f-minimap {\n width: 100%;\n height: 100%;\n}\n\n/* Foblex minimap SVG node rectangles (no default styles provided by Foblex) */\n.mj-flow-editor-minimap .f-minimap-node {\n fill: var(--mj-border-strong);\n stroke: var(--mj-text-disabled);\n stroke-width: 1;\n rx: 3;\n ry: 3;\n}\n\n.mj-flow-editor-minimap .f-minimap-node.f-selected {\n fill: color-mix(in srgb, var(--mj-brand-primary) 50%, var(--mj-bg-surface));\n stroke: var(--mj-brand-primary);\n stroke-width: 1.5;\n}\n\n.mj-flow-editor-minimap .f-minimap-group {\n fill: var(--mj-border-default);\n stroke: var(--mj-text-disabled);\n stroke-width: 0.5;\n rx: 2;\n ry: 2;\n}\n\n/* Viewport indicator rectangle */\n.mj-flow-editor-minimap .f-minimap-view {\n fill: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n stroke: var(--mj-brand-primary);\n stroke-width: 1.5;\n}\n\n/* \u2500\u2500 Empty State \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-editor-empty {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n pointer-events: none;\n z-index: 5;\n}\n\n.mj-flow-editor-empty-subtitle {\n font-size: var(--mj-text-sm);\n color: var(--mj-text-disabled);\n margin: 0;\n}\n\n/* \u2500\u2500 Connection Labels \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-connection-label {\n display: inline-flex;\n align-items: flex-start;\n gap: 5px;\n background: var(--mj-bg-surface);\n border: 1.5px solid var(--mj-border-strong);\n border-radius: 5px;\n padding: 4px 10px;\n font-size: 11px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n white-space: nowrap;\n box-shadow: var(--mj-shadow-sm);\n pointer-events: none;\n line-height: 1.4;\n text-align: center;\n}\n\n.mj-flow-connection-label-icon {\n font-size: 10px;\n flex-shrink: 0;\n margin-top: 2px;\n}\n\n/* \u2500\u2500 Foblex Overrides \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n/* Canvas \u2014 transparent so the grid pattern shows through */\nf-canvas {\n background: transparent;\n}\n\n/* Selection area */\nf-selection-area {\n --f-selection-area-background: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n --f-selection-area-border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n}\n\n/* Line alignment guides */\nf-line-alignment {\n --f-line-alignment-color: var(--mj-brand-primary);\n}\n\n/* Connection paths \u2014 default stroke color prevents invisible connections */\n.f-connection path {\n stroke: var(--mj-text-disabled);\n stroke-width: 2;\n fill: none;\n transition: stroke 0.15s ease, stroke-width 0.15s ease;\n}\n\n.f-connection:hover path {\n stroke-width: 3;\n}\n\n.f-connection.f-selected path {\n stroke: var(--mj-brand-primary);\n stroke-width: 3;\n}\n\n/* Colored connections use the --connection-color custom property,\n defaulting to neutral when no color is specified by the consumer */\n.mj-flow-connection-colored path {\n stroke: var(--connection-color, var(--mj-text-disabled));\n}\n\n.mj-flow-connection-colored.f-selected path {\n stroke: var(--connection-color, var(--mj-brand-primary));\n stroke-width: 3;\n filter: brightness(0.85);\n}\n\n/* Dashed connection style */\n.mj-flow-connection-dashed path {\n stroke-dasharray: 8 4;\n}\n\n/* Dotted connection style */\n.mj-flow-connection-dotted path {\n stroke-dasharray: 3 3;\n}\n\n/* Connection for create (dragging) */\n.f-connection-for-create path {\n stroke: var(--mj-text-disabled);\n stroke-dasharray: 6 3;\n stroke-width: 2;\n}\n\n/* \u2500\u2500 Legend \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-editor-legend {\n position: absolute;\n bottom: 12px;\n left: 12px;\n background: color-mix(in srgb, var(--mj-bg-surface) 92%, transparent);\n backdrop-filter: blur(6px);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n padding: 10px 14px;\n box-shadow: var(--mj-shadow-sm);\n z-index: 15;\n font-size: 11px;\n color: var(--mj-text-secondary);\n max-width: 200px;\n}\n\n.mj-flow-editor-legend-title {\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin-bottom: 8px;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.mj-flow-editor-legend-section {\n margin-bottom: 8px;\n}\n\n.mj-flow-editor-legend-section:last-child {\n margin-bottom: 0;\n}\n\n.mj-flow-editor-legend-heading {\n font-size: 10px;\n font-weight: 600;\n color: var(--mj-text-disabled);\n text-transform: uppercase;\n letter-spacing: 0.3px;\n margin-bottom: 4px;\n}\n\n.mj-flow-editor-legend-item {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 2px 0;\n font-size: 11px;\n color: var(--mj-text-secondary);\n}\n\n.mj-flow-editor-legend-svg,\n.mj-flow-editor-legend-line-svg {\n flex-shrink: 0;\n}\n\n.mj-flow-editor-legend-swatch {\n display: inline-block;\n width: 10px;\n height: 10px;\n border-radius: var(--mj-radius-sm);\n flex-shrink: 0;\n}\n\n.mj-flow-editor-legend-box {\n display: inline-block;\n width: 14px;\n height: 10px;\n border: 2px solid;\n border-radius: var(--mj-radius-sm);\n flex-shrink: 0;\n}\n\n/* \u2500\u2500 Context Menu \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-context-menu {\n position: fixed;\n min-width: 180px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n box-shadow: var(--mj-shadow-lg);\n padding: 4px;\n z-index: 9999;\n animation: mj-ctx-fade-in 0.1s ease-out;\n}\n\n@keyframes mj-ctx-fade-in {\n from { opacity: 0; transform: scale(0.95); }\n to { opacity: 1; transform: scale(1); }\n}\n\n.mj-flow-context-menu-item {\n display: flex;\n align-items: center;\n gap: 10px;\n width: 100%;\n padding: 8px 12px;\n border: none;\n background: none;\n font-size: var(--mj-text-sm);\n font-weight: 450;\n color: var(--mj-text-secondary);\n cursor: pointer;\n border-radius: 5px;\n text-align: left;\n transition: background-color 0.1s ease;\n}\n\n.mj-flow-context-menu-item:hover {\n background-color: var(--mj-bg-surface-sunken);\n}\n\n.mj-flow-context-menu-item i {\n width: 16px;\n text-align: center;\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n}\n\n.mj-flow-context-menu-item--danger {\n color: var(--mj-status-error);\n}\n\n.mj-flow-context-menu-item--danger:hover {\n background-color: var(--mj-status-error-subtle);\n}\n\n.mj-flow-context-menu-item--danger i {\n color: var(--mj-status-error);\n}\n\n.mj-flow-context-menu-divider {\n height: 1px;\n background: var(--mj-border-default);\n margin: 4px 8px;\n}\n\n/* \u2500\u2500 Focus Indicators (Accessibility) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-toolbar-btn:focus-visible,\n.mj-agent-editor-btn:focus-visible,\n.mj-agent-editor-view-btn:focus-visible,\n.mj-agent-props-close:focus-visible,\n.mj-agent-props-delete-btn:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n}\n\n.mj-flow-palette-item:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 1px;\n border-radius: var(--mj-radius-md);\n}\n"] }]
1158
+ args: [{ standalone: false, selector: 'mj-flow-editor', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.Default, providers: [FlowStateService, FlowLayoutService], template: "<div class=\"mj-flow-editor\" [class.mj-flow-editor--readonly]=\"ReadOnly\" tabindex=\"0\">\n\n <!-- Canvas Toolbar \u2014 shown / minimized / hidden (recover tab). Align is left/center/right. -->\n @if (ShowToolbar && EffectiveToolbarVisibility === 'shown') {\n <div class=\"mj-flow-editor-toolbar-area\" [attr.data-align]=\"ToolbarAlign\">\n <mj-flow-toolbar\n [ZoomLevel]=\"zoomLevel\"\n [ShowGrid]=\"ShowGrid\"\n [ShowMinimap]=\"ShowMinimap\"\n [ShowLegend]=\"ShowLegend\"\n [ReadOnly]=\"ReadOnly\"\n [PanMode]=\"panMode\"\n (ZoomInClicked)=\"ZoomIn()\"\n (ZoomOutClicked)=\"ZoomOut()\"\n (FitToScreenClicked)=\"ZoomToFit()\"\n (AutoLayoutClicked)=\"AutoArrange()\"\n (GridToggled)=\"onGridToggled($event)\"\n (MinimapToggled)=\"onMinimapToggled($event)\"\n (LegendToggled)=\"onLegendToggled($event)\"\n (PanModeToggled)=\"onPanModeToggled($event)\"\n (MinimizeClicked)=\"SetToolbarVisibility('minimized')\"\n (HideClicked)=\"SetToolbarVisibility('hidden')\">\n </mj-flow-toolbar>\n </div>\n } @else if (ShowToolbar && EffectiveToolbarVisibility === 'minimized') {\n <button type=\"button\" class=\"mj-flow-editor-toolbar-chip\" [attr.data-align]=\"ToolbarAlign\"\n (click)=\"SetToolbarVisibility('shown')\"\n title=\"Show canvas tools\" aria-label=\"Show canvas tools\">\n <i class=\"fa-solid fa-wrench\" aria-hidden=\"true\"></i>\n </button>\n } @else if (ShowToolbar && EffectiveToolbarVisibility === 'hidden') {\n <button type=\"button\" class=\"mj-flow-editor-toolbar-tab\" [attr.data-align]=\"ToolbarAlign\"\n (click)=\"SetToolbarVisibility('shown')\"\n title=\"Show canvas tools\" aria-label=\"Show canvas tools\">\n <i class=\"fa-solid fa-ellipsis\" aria-hidden=\"true\"></i>\n </button>\n }\n\n <!-- Main Canvas Area -->\n <div class=\"mj-flow-editor-canvas-area\">\n\n <!-- Palette Sidebar -->\n @if (ShowPalette && !ReadOnly) {\n <mj-flow-palette\n [NodeTypes]=\"NodeTypes\"\n (NodeTypeActivated)=\"onPaletteNodeTypeActivated($event)\">\n </mj-flow-palette>\n }\n\n <!-- Foblex Canvas -->\n <div class=\"mj-flow-editor-canvas\" #canvasArea\n [class.mj-flow-editor-canvas--pan-mode]=\"panMode\">\n <f-flow fDraggable\n [fDraggableDisabled]=\"false\"\n [fCanvasMoveTrigger]=\"canvasMoveTriggerFn\"\n [vCellSize]=\"GridSize\"\n [hCellSize]=\"GridSize\"\n [fCellSizeWhileDragging]=\"ShowGrid\"\n (fLoaded)=\"onFlowLoaded()\"\n (fCreateConnection)=\"onCreateConnection($event)\"\n (fReassignConnection)=\"onReassignConnection($event)\"\n (fCreateNode)=\"onCreateNode($event)\"\n (fSelectionChange)=\"onSelectionChange($event)\"\n (fMoveNodes)=\"onNodesMoved($event)\">\n\n <!-- Background grid \u2014 MUST be direct child of f-flow (Foblex content projection requires it) -->\n @if (ShowGrid) {\n <f-background>\n <f-circle-pattern [color]=\"'#94a3b8'\" [radius]=\"24\"></f-circle-pattern>\n </f-background>\n }\n\n <!-- Alignment snap lines \u2014 direct child of f-flow -->\n @if (!ReadOnly) {\n <f-line-alignment [fAlignThreshold]=\"10\"></f-line-alignment>\n }\n\n <f-canvas fZoom #fZoomRef=\"fComponent\"\n [fZoomMinimum]=\"0.15\"\n [fZoomMaximum]=\"3\"\n [fZoomStep]=\"0.1\"\n [position]=\"canvasPosition\"\n [scale]=\"canvasScale\"\n (fCanvasChange)=\"onCanvasChange($event)\">\n\n <!-- Interactive connection drawing -->\n @if (!ReadOnly) {\n <f-connection-for-create\n fType=\"bezier\"\n [fRadius]=\"8\"\n [fOffset]=\"12\">\n <svg viewBox=\"0 0 10 10\" fMarker type=\"end\"\n orient=\"auto\" [refX]=\"9\" [refY]=\"5\" [height]=\"10\" [width]=\"10\">\n <path d=\"M0 0L10 5L0 10Z\" fill=\"#94a3b8\"/>\n </svg>\n </f-connection-for-create>\n }\n\n <!-- Connections -->\n @for (conn of Connections; track trackConnectionById($index, conn)) {\n <f-connection\n [fConnectionId]=\"conn.ID\"\n [fOutputId]=\"conn.SourcePortID\"\n [fInputId]=\"conn.TargetPortID\"\n fType=\"bezier\"\n fBehavior=\"fixed\"\n [fRadius]=\"8\"\n [fOffset]=\"12\"\n [fSelectionDisabled]=\"false\"\n [fReassignDisabled]=\"ReadOnly\"\n [style.--connection-color]=\"conn.Color || '#94a3b8'\"\n [style.--connection-width.px]=\"conn.StrokeWidth || 2\"\n [class.mj-flow-connection-colored]=\"!!conn.Color\"\n [class.mj-flow-connection-dashed]=\"conn.Style === 'dashed'\"\n [class.mj-flow-connection-dotted]=\"conn.Style === 'dotted'\"\n [class.mj-flow-connection-animated]=\"!!conn.Animated\"\n (click)=\"onConnectionClicked($event, conn)\"\n (contextmenu)=\"onConnectionContextMenu($event, conn)\">\n <!-- Arrow marker -->\n <svg viewBox=\"0 0 10 10\" fMarker type=\"end\"\n orient=\"auto\" [refX]=\"9\" [refY]=\"5\"\n [height]=\"conn.Animated ? 16 : 10\"\n [width]=\"conn.Animated ? 16 : 10\">\n <path d=\"M0 0L10 5L0 10Z\" [attr.fill]=\"conn.Color || '#94a3b8'\"/>\n </svg>\n <!-- Connection label -->\n @if (conn.Label) {\n <div fConnectionContent [position]=\"0.5\"\n class=\"mj-flow-connection-label\"\n [style.backgroundColor]=\"ConnectionLabelBackground\"\n [style.borderColor]=\"ConnectionLabelBorderColor\"\n [style.color]=\"ConnectionLabelTextColor\"\n [title]=\"conn.LabelDetail || conn.Label || ''\">\n @if (conn.LabelIcon) {\n <i\n class=\"fa-solid mj-flow-connection-label-icon\"\n [ngClass]=\"conn.LabelIcon\"\n [style.color]=\"conn.LabelIconColor || 'inherit'\"></i>\n }\n {{ conn.Label }}\n </div>\n }\n </f-connection>\n }\n\n <!-- Nodes -->\n @for (node of Nodes; track trackNodeById($index, node)) {\n <mj-flow-node\n fNode\n fDragHandle\n [fNodeId]=\"node.ID\"\n [fNodePosition]=\"{ x: node.Position.X, y: node.Position.Y }\"\n [fNodeDraggingDisabled]=\"ReadOnly || panMode || node.Locked === true\"\n [fNodeSelectionDisabled]=\"panMode\"\n [fConnectOnNode]=\"!ReadOnly && !panMode\"\n [Node]=\"node\"\n [TypeConfig]=\"GetTypeConfig(node.Type)\"\n [ReadOnly]=\"ReadOnly\"\n (contextmenu)=\"onNodeContextMenu($event, node)\">\n </mj-flow-node>\n }\n\n </f-canvas>\n\n <!-- Rubber-band selection \u2014 direct child of f-flow -->\n @if (!ReadOnly) {\n <f-selection-area></f-selection-area>\n }\n\n <!-- Minimap -->\n @if (ShowMinimap) {\n <div class=\"mj-flow-editor-minimap\" fDragBlocker>\n <f-minimap [fMinSize]=\"1500\"></f-minimap>\n </div>\n }\n </f-flow>\n\n <!-- Legend -->\n @if (ShowLegend && Nodes.length > 0) {\n <div class=\"mj-flow-editor-legend\">\n <div class=\"mj-flow-editor-legend-title\">Legend</div>\n <div class=\"mj-flow-editor-legend-section\">\n <div class=\"mj-flow-editor-legend-heading\">Connections</div>\n <div class=\"mj-flow-editor-legend-item\">\n <svg class=\"mj-flow-editor-legend-line-svg\" width=\"28\" height=\"10\"><line x1=\"0\" y1=\"5\" x2=\"28\" y2=\"5\" stroke=\"#64748b\" stroke-width=\"2\"/></svg>\n <span>Only exit path</span>\n </div>\n <div class=\"mj-flow-editor-legend-item\">\n <svg class=\"mj-flow-editor-legend-line-svg\" width=\"28\" height=\"10\"><line x1=\"0\" y1=\"5\" x2=\"28\" y2=\"5\" stroke=\"#16a34a\" stroke-width=\"2\"/></svg>\n <i class=\"fa-solid fa-circle-check\" style=\"color:#16a34a;font-size:10px;\"></i>\n <span>Default (fallback)</span>\n </div>\n <div class=\"mj-flow-editor-legend-item\">\n <svg class=\"mj-flow-editor-legend-line-svg\" width=\"28\" height=\"10\"><line x1=\"0\" y1=\"5\" x2=\"28\" y2=\"5\" stroke=\"#f59e0b\" stroke-width=\"2\" stroke-dasharray=\"5 3\"/></svg>\n <span>Conditional</span>\n </div>\n <div class=\"mj-flow-editor-legend-item\">\n <svg class=\"mj-flow-editor-legend-line-svg\" width=\"28\" height=\"10\"><line x1=\"0\" y1=\"5\" x2=\"28\" y2=\"5\" stroke=\"#ef4444\" stroke-width=\"2\"/></svg>\n <i class=\"fa-solid fa-triangle-exclamation\" style=\"color:#ef4444;font-size:10px;\"></i>\n <span>Duplicate defaults</span>\n </div>\n </div>\n <div class=\"mj-flow-editor-legend-section\">\n <div class=\"mj-flow-editor-legend-heading\">Step Types</div>\n <div class=\"mj-flow-editor-legend-item\">\n <span class=\"mj-flow-editor-legend-swatch\" style=\"background:#3B82F6\"></span>\n <span>Action</span>\n </div>\n <div class=\"mj-flow-editor-legend-item\">\n <span class=\"mj-flow-editor-legend-swatch\" style=\"background:#8B5CF6\"></span>\n <span>Prompt</span>\n </div>\n <div class=\"mj-flow-editor-legend-item\">\n <span class=\"mj-flow-editor-legend-swatch\" style=\"background:#10B981\"></span>\n <span>Sub-Agent</span>\n </div>\n <div class=\"mj-flow-editor-legend-item\">\n <span class=\"mj-flow-editor-legend-swatch\" style=\"background:#F59E0B\"></span>\n <span>For Each</span>\n </div>\n <div class=\"mj-flow-editor-legend-item\">\n <span class=\"mj-flow-editor-legend-swatch\" style=\"background:#F97316\"></span>\n <span>While</span>\n </div>\n </div>\n <div class=\"mj-flow-editor-legend-section\">\n <div class=\"mj-flow-editor-legend-heading\">Borders</div>\n <div class=\"mj-flow-editor-legend-item\">\n <span class=\"mj-flow-editor-legend-box\" style=\"border-color:#16a34a;background:#f0fdf4;\"></span>\n <span>Start node</span>\n </div>\n <div class=\"mj-flow-editor-legend-item\">\n <span class=\"mj-flow-editor-legend-box\" style=\"border-color:#ef4444;background:#fef2f2;\"></span>\n <i class=\"fa-solid fa-triangle-exclamation\" style=\"color:#ea580c;font-size:10px;\"></i>\n <span>Missing config</span>\n </div>\n </div>\n </div>\n }\n\n <!-- Empty state overlay -->\n @if (Nodes.length === 0) {\n <div class=\"mj-flow-editor-empty\">\n <mj-empty-state\n Icon=\"fa-solid fa-diagram-project\"\n [Title]=\"EmptyStateTitle\">\n @if (!ReadOnly) {\n <p class=\"mj-flow-editor-empty-subtitle\">\n Or use auto-layout after adding steps to arrange them automatically\n </p>\n }\n </mj-empty-state>\n </div>\n }\n </div>\n </div>\n\n <!-- Context Menu -->\n @if (contextMenuVisible) {\n <div\n class=\"mj-flow-context-menu\"\n [style.left.px]=\"contextMenuX\"\n [style.top.px]=\"contextMenuY\"\n (click)=\"$event.stopPropagation()\">\n @for (item of contextMenuItems; track item.ID; let last = $last) {\n <button type=\"button\" class=\"mj-flow-context-menu-item\"\n [class.mj-flow-context-menu-item--danger]=\"item.Danger\"\n [disabled]=\"item.Disabled\"\n (click)=\"onContextMenuAction(item.ID)\">\n @if (item.Icon) {\n <i class=\"fa-solid\" [ngClass]=\"item.Icon\"></i>\n }\n <span>{{ item.Label }}</span>\n @if (item.Shortcut) {\n <kbd class=\"mj-flow-context-menu-shortcut\">{{ item.Shortcut }}</kbd>\n }\n </button>\n @if (!last && item.Danger !== contextMenuItems[$index + 1]?.Danger) {\n <div class=\"mj-flow-context-menu-divider\"></div>\n }\n }\n </div>\n }\n\n <!-- Status Bar -->\n @if (ShowStatusBar) {\n <mj-flow-status-bar\n [NodeCount]=\"Nodes.length\"\n [ConnectionCount]=\"Connections.length\"\n [SelectedCount]=\"selectedCount\"\n [ZoomLevel]=\"zoomLevel\">\n </mj-flow-status-bar>\n }\n</div>\n", styles: ["/* ============================================================\n Flow Editor \u2014 Main container styles\n ============================================================ */\n\n/* The HOST is a custom element, which is `display: inline` with auto height until told otherwise.\n Without this, `.mj-flow-editor { height: 100% }` below resolved against an auto-height parent \u2014\n which means auto \u2014 so the canvas fell back to its `min-height` floor and sat at 400px no matter\n how much room its pane actually had.\n\n `height: 100%` here is safe for hosts that DON'T give it a box: it resolves to auto in that case,\n and the floor takes over exactly as before. */\n:host {\n display: block;\n height: 100%;\n min-height: 0;\n}\n\n.mj-flow-editor {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n min-height: 400px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n overflow: hidden;\n outline: none;\n position: relative;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n}\n\n.mj-flow-editor--readonly .mj-flow-node-port {\n cursor: default;\n pointer-events: none;\n}\n\n/* \u2500\u2500 Toolbar Area \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-editor-toolbar-area,\n.mj-flow-editor-toolbar-chip,\n.mj-flow-editor-toolbar-tab {\n position: absolute;\n top: 10px;\n z-index: 20;\n}\n.mj-flow-editor-toolbar-area[data-align=\"center\"],\n.mj-flow-editor-toolbar-chip[data-align=\"center\"],\n.mj-flow-editor-toolbar-tab[data-align=\"center\"] {\n left: 50%;\n transform: translateX(-50%);\n}\n.mj-flow-editor-toolbar-area[data-align=\"left\"],\n.mj-flow-editor-toolbar-chip[data-align=\"left\"],\n.mj-flow-editor-toolbar-tab[data-align=\"left\"] {\n left: 10px;\n}\n.mj-flow-editor-toolbar-area[data-align=\"right\"],\n.mj-flow-editor-toolbar-chip[data-align=\"right\"],\n.mj-flow-editor-toolbar-tab[data-align=\"right\"] {\n right: 10px;\n}\n\n.mj-flow-editor-toolbar-chip,\n.mj-flow-editor-toolbar-tab {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-elevated);\n color: var(--mj-text-secondary);\n cursor: pointer;\n}\n.mj-flow-editor-toolbar-chip:hover,\n.mj-flow-editor-toolbar-tab:hover {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface-hover);\n}\n.mj-flow-editor-toolbar-chip {\n width: 32px;\n height: 32px;\n border-radius: var(--mj-radius-md);\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06);\n}\n.mj-flow-editor-toolbar-tab {\n width: 22px;\n height: 18px;\n padding: 0;\n border-radius: var(--mj-radius-sm);\n opacity: 0.55;\n}\n.mj-flow-editor-toolbar-tab:hover { opacity: 1; }\n\n/* \u2500\u2500 Canvas Area \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-editor-canvas-area {\n display: flex;\n flex: 1;\n overflow: hidden;\n position: relative;\n}\n\n.mj-flow-editor-canvas {\n flex: 1;\n position: relative;\n overflow: hidden;\n background: var(--mj-bg-surface);\n}\n\n.mj-flow-editor-canvas f-flow {\n width: 100%;\n height: 100%;\n}\n\n/* Pan mode \u2014 grab cursor, nodes pass through pointer events to canvas */\n.mj-flow-editor-canvas--pan-mode {\n cursor: grab;\n}\n\n.mj-flow-editor-canvas--pan-mode:active {\n cursor: grabbing;\n}\n\n.mj-flow-editor-canvas--pan-mode mj-flow-node {\n pointer-events: none;\n cursor: grab;\n}\n\n.mj-flow-editor-canvas--pan-mode f-connection {\n pointer-events: none;\n}\n\n.mj-flow-editor-canvas--pan-mode .mj-flow-connection-label {\n pointer-events: none;\n}\n\n/* \u2500\u2500 Minimap \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-editor-minimap {\n position: absolute;\n bottom: 12px;\n right: 12px;\n width: 160px;\n height: 120px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n box-shadow: var(--mj-shadow-sm);\n overflow: hidden;\n z-index: 15;\n}\n\n.mj-flow-editor-minimap f-minimap {\n width: 100%;\n height: 100%;\n}\n\n/* Foblex minimap SVG node rectangles (no default styles provided by Foblex) */\n.mj-flow-editor-minimap .f-minimap-node {\n fill: var(--mj-border-strong);\n stroke: var(--mj-text-disabled);\n stroke-width: 1;\n rx: 3;\n ry: 3;\n}\n\n.mj-flow-editor-minimap .f-minimap-node.f-selected {\n fill: color-mix(in srgb, var(--mj-brand-primary) 50%, var(--mj-bg-surface));\n stroke: var(--mj-brand-primary);\n stroke-width: 1.5;\n}\n\n.mj-flow-editor-minimap .f-minimap-group {\n fill: var(--mj-border-default);\n stroke: var(--mj-text-disabled);\n stroke-width: 0.5;\n rx: 2;\n ry: 2;\n}\n\n/* Viewport indicator rectangle */\n.mj-flow-editor-minimap .f-minimap-view {\n fill: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n stroke: var(--mj-brand-primary);\n stroke-width: 1.5;\n}\n\n/* \u2500\u2500 Empty State \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-editor-empty {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n pointer-events: none;\n z-index: 5;\n}\n\n.mj-flow-editor-empty-subtitle {\n font-size: var(--mj-text-sm);\n color: var(--mj-text-disabled);\n margin: 0;\n}\n\n/* \u2500\u2500 Connection Labels \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-connection-label {\n display: inline-flex;\n align-items: flex-start;\n gap: 5px;\n background: var(--mj-bg-surface);\n border: 1.5px solid var(--mj-border-strong);\n border-radius: 5px;\n padding: 4px 10px;\n font-size: 11px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n white-space: nowrap;\n box-shadow: var(--mj-shadow-sm);\n pointer-events: none;\n line-height: 1.4;\n text-align: center;\n}\n\n.mj-flow-connection-label-icon {\n font-size: 10px;\n flex-shrink: 0;\n margin-top: 2px;\n}\n\n/* \u2500\u2500 Foblex Overrides \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n/* Canvas \u2014 transparent so the grid pattern shows through */\nf-canvas {\n background: transparent;\n}\n\n/* Selection area */\nf-selection-area {\n --f-selection-area-background: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n --f-selection-area-border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n}\n\n/* Line alignment guides */\nf-line-alignment {\n --f-line-alignment-color: var(--mj-brand-primary);\n}\n\n/* Connection paths \u2014 default stroke color prevents invisible connections */\n.f-connection path {\n stroke: var(--mj-text-disabled);\n stroke-width: var(--connection-width, 2px);\n fill: none;\n transition: stroke 0.15s ease, stroke-width 0.15s ease;\n}\n\n.f-connection:hover path {\n stroke-width: calc(var(--connection-width, 2px) + 1px);\n}\n\n.f-connection.f-selected path {\n stroke: var(--mj-brand-primary);\n stroke-width: max(3px, var(--connection-width, 2px));\n}\n\n/* Colored connections use the --connection-color custom property,\n defaulting to neutral when no color is specified by the consumer */\n.mj-flow-connection-colored path {\n stroke: var(--connection-color, var(--mj-text-disabled));\n}\n\n.mj-flow-connection-colored.f-selected path {\n stroke: var(--connection-color, var(--mj-brand-primary));\n stroke-width: max(3px, var(--connection-width, 2px));\n filter: brightness(0.85);\n}\n\n/* Dashed connection style */\n.mj-flow-connection-dashed path {\n stroke-dasharray: 8 4;\n}\n\n/* Dotted connection style */\n.mj-flow-connection-dotted path {\n stroke-dasharray: 3 3;\n}\n\n.mj-flow-connection-animated path {\n stroke-dasharray: 14 10;\n stroke-linecap: round;\n stroke-width: var(--connection-width, 4.5px);\n animation: mj-flow-dash 0.5s linear infinite;\n filter: drop-shadow(0 0 5px color-mix(in srgb, var(--connection-color, var(--mj-brand-primary)) 70%, transparent));\n}\n@keyframes mj-flow-dash {\n to { stroke-dashoffset: -24; }\n}\n\n/* Connection for create (dragging) */\n.f-connection-for-create path {\n stroke: var(--mj-text-disabled);\n stroke-dasharray: 6 3;\n stroke-width: 2;\n}\n\n/* \u2500\u2500 Legend \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-editor-legend {\n position: absolute;\n bottom: 12px;\n left: 12px;\n background: color-mix(in srgb, var(--mj-bg-surface) 92%, transparent);\n backdrop-filter: blur(6px);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n padding: 10px 14px;\n box-shadow: var(--mj-shadow-sm);\n z-index: 15;\n font-size: 11px;\n color: var(--mj-text-secondary);\n max-width: 200px;\n}\n\n.mj-flow-editor-legend-title {\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin-bottom: 8px;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.mj-flow-editor-legend-section {\n margin-bottom: 8px;\n}\n\n.mj-flow-editor-legend-section:last-child {\n margin-bottom: 0;\n}\n\n.mj-flow-editor-legend-heading {\n font-size: 10px;\n font-weight: 600;\n color: var(--mj-text-disabled);\n text-transform: uppercase;\n letter-spacing: 0.3px;\n margin-bottom: 4px;\n}\n\n.mj-flow-editor-legend-item {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 2px 0;\n font-size: 11px;\n color: var(--mj-text-secondary);\n}\n\n.mj-flow-editor-legend-svg,\n.mj-flow-editor-legend-line-svg {\n flex-shrink: 0;\n}\n\n.mj-flow-editor-legend-swatch {\n display: inline-block;\n width: 10px;\n height: 10px;\n border-radius: var(--mj-radius-sm);\n flex-shrink: 0;\n}\n\n.mj-flow-editor-legend-box {\n display: inline-block;\n width: 14px;\n height: 10px;\n border: 2px solid;\n border-radius: var(--mj-radius-sm);\n flex-shrink: 0;\n}\n\n/* \u2500\u2500 Context Menu \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-context-menu {\n position: fixed;\n min-width: 180px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n box-shadow: var(--mj-shadow-lg);\n padding: 4px;\n z-index: 9999;\n animation: mj-ctx-fade-in 0.1s ease-out;\n}\n\n@keyframes mj-ctx-fade-in {\n from { opacity: 0; transform: scale(0.95); }\n to { opacity: 1; transform: scale(1); }\n}\n\n.mj-flow-context-menu-item {\n display: flex;\n align-items: center;\n gap: 10px;\n width: 100%;\n padding: 8px 12px;\n border: none;\n background: none;\n font-size: var(--mj-text-sm);\n font-weight: 450;\n color: var(--mj-text-secondary);\n cursor: pointer;\n border-radius: 5px;\n text-align: left;\n transition: background-color 0.1s ease;\n}\n\n.mj-flow-context-menu-item:hover {\n background-color: var(--mj-bg-surface-sunken);\n}\n\n.mj-flow-context-menu-item i {\n width: 16px;\n text-align: center;\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n}\n\n.mj-flow-context-menu-shortcut {\n margin-left: auto;\n padding: 0 4px;\n border: 1px solid var(--mj-border-default);\n border-radius: 3px;\n font-size: 10px;\n font-family: inherit;\n color: var(--mj-text-muted);\n}\n\n.mj-flow-context-menu-item--danger {\n color: var(--mj-status-error);\n}\n\n.mj-flow-context-menu-item--danger:hover {\n background-color: var(--mj-status-error-subtle);\n}\n\n.mj-flow-context-menu-item--danger i {\n color: var(--mj-status-error);\n}\n\n.mj-flow-context-menu-divider {\n height: 1px;\n background: var(--mj-border-default);\n margin: 4px 8px;\n}\n\n/* \u2500\u2500 Focus Indicators (Accessibility) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.mj-flow-toolbar-btn:focus-visible,\n.mj-agent-editor-btn:focus-visible,\n.mj-agent-editor-view-btn:focus-visible,\n.mj-agent-props-close:focus-visible,\n.mj-agent-props-delete-btn:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n}\n\n.mj-flow-palette-item:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 1px;\n border-radius: var(--mj-radius-md);\n}\n"] }]
1052
1159
  }], () => [{ type: i0.ChangeDetectorRef }, { type: i1.FlowStateService }, { type: i2.FlowLayoutService }], { Nodes: [{
1053
1160
  type: Input
1054
1161
  }], Connections: [{
@@ -1067,6 +1174,10 @@ export class FlowEditorComponent {
1067
1174
  type: Input
1068
1175
  }], ShowToolbar: [{
1069
1176
  type: Input
1177
+ }], ToolbarVisibility: [{
1178
+ type: Input
1179
+ }], ToolbarAlign: [{
1180
+ type: Input
1070
1181
  }], ShowLegend: [{
1071
1182
  type: Input
1072
1183
  }], GridSize: [{
@@ -1107,12 +1218,18 @@ export class FlowEditorComponent {
1107
1218
  type: Output
1108
1219
  }], ConnectionEditRequested: [{
1109
1220
  type: Output
1221
+ }], BeforeContextMenu: [{
1222
+ type: Output
1223
+ }], AfterContextMenuAction: [{
1224
+ type: Output
1110
1225
  }], GridToggled: [{
1111
1226
  type: Output
1112
1227
  }], MinimapToggled: [{
1113
1228
  type: Output
1114
1229
  }], LegendToggled: [{
1115
1230
  type: Output
1231
+ }], ToolbarVisibilityChanged: [{
1232
+ type: Output
1116
1233
  }], fFlow: [{
1117
1234
  type: ViewChild,
1118
1235
  args: [FFlowComponent]
@@ -1132,5 +1249,12 @@ export class FlowEditorComponent {
1132
1249
  type: HostListener,
1133
1250
  args: ['keydown', ['$event']]
1134
1251
  }] }); })();
1135
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(FlowEditorComponent, { className: "FlowEditorComponent", filePath: "src/lib/components/flow-editor.component.ts", lineNumber: 44 }); })();
1252
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(FlowEditorComponent, { className: "FlowEditorComponent", filePath: "src/lib/components/flow-editor.component.ts", lineNumber: 46 }); })();
1253
+ function defaultContextMenuItems(target) {
1254
+ const noun = target === 'node' ? 'Node' : 'Connection';
1255
+ return [
1256
+ { ID: 'edit', Label: `Edit ${noun}`, Icon: 'fa-pen-to-square' },
1257
+ { ID: 'remove', Label: `Remove ${noun}`, Icon: 'fa-trash-can', Danger: true },
1258
+ ];
1259
+ }
1136
1260
  //# sourceMappingURL=flow-editor.component.js.map