@memberjunction/ng-artifacts 6.1.0-edge.4 → 6.1.0-edge.6

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.
Files changed (44) hide show
  1. package/dist/lib/components/artifact-version-download.d.ts +31 -0
  2. package/dist/lib/components/artifact-version-download.d.ts.map +1 -0
  3. package/dist/lib/components/artifact-version-download.js +60 -0
  4. package/dist/lib/components/artifact-version-download.js.map +1 -0
  5. package/dist/lib/components/artifact-version-history.component.d.ts.map +1 -1
  6. package/dist/lib/components/artifact-version-history.component.js +5 -3
  7. package/dist/lib/components/artifact-version-history.component.js.map +1 -1
  8. package/dist/lib/components/artifact-viewer-panel.component.d.ts +30 -1
  9. package/dist/lib/components/artifact-viewer-panel.component.d.ts.map +1 -1
  10. package/dist/lib/components/artifact-viewer-panel.component.js +283 -89
  11. package/dist/lib/components/artifact-viewer-panel.component.js.map +1 -1
  12. package/dist/lib/components/file-artifact-toolbar.component.js +1 -1
  13. package/dist/lib/components/plugins/component-artifact-viewer.component.js +2 -2
  14. package/dist/lib/components/plugins/component-artifact-viewer.component.js.map +1 -1
  15. package/dist/lib/components/plugins/component-feedback-panel/component-feedback-panel.component.js +1 -1
  16. package/dist/lib/components/plugins/data-artifact-viewer.component.d.ts.map +1 -1
  17. package/dist/lib/components/plugins/data-artifact-viewer.component.js +6 -8
  18. package/dist/lib/components/plugins/data-artifact-viewer.component.js.map +1 -1
  19. package/dist/lib/components/plugins/data-requirements-viewer/data-requirements-viewer.component.js +1 -1
  20. package/dist/lib/components/plugins/docx-artifact-viewer.component.js +1 -1
  21. package/dist/lib/components/plugins/image-artifact-viewer.component.js +1 -1
  22. package/dist/lib/components/plugins/json-artifact-viewer.component.d.ts +8 -0
  23. package/dist/lib/components/plugins/json-artifact-viewer.component.d.ts.map +1 -1
  24. package/dist/lib/components/plugins/json-artifact-viewer.component.js +45 -14
  25. package/dist/lib/components/plugins/json-artifact-viewer.component.js.map +1 -1
  26. package/dist/lib/components/plugins/ml-experiment-results-viewer.component.js +1 -1
  27. package/dist/lib/components/plugins/pdf-artifact-viewer.component.js +1 -1
  28. package/dist/lib/components/plugins/save-query-dialog.component.js +7 -7
  29. package/dist/lib/components/plugins/save-query-dialog.component.js.map +1 -1
  30. package/dist/lib/components/previews/audio-artifact-preview.component.d.ts.map +1 -1
  31. package/dist/lib/components/previews/audio-artifact-preview.component.js +15 -9
  32. package/dist/lib/components/previews/audio-artifact-preview.component.js.map +1 -1
  33. package/dist/lib/components/previews/base-artifact-preview.component.d.ts +13 -0
  34. package/dist/lib/components/previews/base-artifact-preview.component.d.ts.map +1 -1
  35. package/dist/lib/components/previews/base-artifact-preview.component.js +20 -0
  36. package/dist/lib/components/previews/base-artifact-preview.component.js.map +1 -1
  37. package/dist/lib/components/previews/image-artifact-preview.component.d.ts +13 -0
  38. package/dist/lib/components/previews/image-artifact-preview.component.d.ts.map +1 -1
  39. package/dist/lib/components/previews/image-artifact-preview.component.js +55 -19
  40. package/dist/lib/components/previews/image-artifact-preview.component.js.map +1 -1
  41. package/dist/lib/components/previews/video-artifact-preview.component.d.ts.map +1 -1
  42. package/dist/lib/components/previews/video-artifact-preview.component.js +15 -9
  43. package/dist/lib/components/previews/video-artifact-preview.component.js.map +1 -1
  44. package/package.json +29 -29
@@ -12,11 +12,12 @@ import * as i0 from "@angular/core";
12
12
  import * as i1 from "@memberjunction/ng-notifications";
13
13
  import * as i2 from "@angular/platform-browser";
14
14
  import * as i3 from "../services/artifact-icon.service";
15
- import * as i4 from "@angular/common";
16
- import * as i5 from "@memberjunction/ng-markdown";
17
- import * as i6 from "@memberjunction/ng-code-editor";
18
- import * as i7 from "@memberjunction/ng-ui-components";
19
- import * as i8 from "./artifact-type-plugin-viewer.component";
15
+ import * as i4 from "../services/artifact-file.service";
16
+ import * as i5 from "@angular/common";
17
+ import * as i6 from "@memberjunction/ng-markdown";
18
+ import * as i7 from "@memberjunction/ng-code-editor";
19
+ import * as i8 from "@memberjunction/ng-ui-components";
20
+ import * as i9 from "./artifact-type-plugin-viewer.component";
20
21
  const _forTrack0 = ($index, $item) => $item.ID;
21
22
  const _forTrack1 = ($index, $item) => $item.id;
22
23
  function ArtifactViewerPanelComponent_Conditional_1_Conditional_5_Template(rf, ctx) { if (rf & 1) {
@@ -38,9 +39,9 @@ function ArtifactViewerPanelComponent_Conditional_1_Conditional_12_For_2_Conditi
38
39
  i0.ɵɵelement(0, "i", 28);
39
40
  } }
40
41
  function ArtifactViewerPanelComponent_Conditional_1_Conditional_12_For_2_Template(rf, ctx) { if (rf & 1) {
41
- const _r4 = i0.ɵɵgetCurrentView();
42
+ const _r3 = i0.ɵɵgetCurrentView();
42
43
  i0.ɵɵelementStart(0, "div", 25);
43
- i0.ɵɵlistener("click", function ArtifactViewerPanelComponent_Conditional_1_Conditional_12_For_2_Template_div_click_0_listener($event) { const version_r5 = i0.ɵɵrestoreView(_r4).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); ctx_r1.selectVersion(version_r5); return i0.ɵɵresetView($event.stopPropagation()); });
44
+ i0.ɵɵlistener("click", function ArtifactViewerPanelComponent_Conditional_1_Conditional_12_For_2_Template_div_click_0_listener($event) { const version_r4 = i0.ɵɵrestoreView(_r3).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); ctx_r1.selectVersion(version_r4); return i0.ɵɵresetView($event.stopPropagation()); });
44
45
  i0.ɵɵelementStart(1, "span", 26);
45
46
  i0.ɵɵtext(2);
46
47
  i0.ɵɵelementEnd();
@@ -51,20 +52,19 @@ function ArtifactViewerPanelComponent_Conditional_1_Conditional_12_For_2_Templat
51
52
  i0.ɵɵconditionalCreate(6, ArtifactViewerPanelComponent_Conditional_1_Conditional_12_For_2_Conditional_6_Template, 1, 0, "i", 28);
52
53
  i0.ɵɵelementEnd();
53
54
  } if (rf & 2) {
54
- const version_r5 = ctx.$implicit;
55
+ const version_r4 = ctx.$implicit;
55
56
  const ctx_r1 = i0.ɵɵnextContext(3);
56
- i0.ɵɵclassProp("selected", version_r5.VersionNumber === ctx_r1.selectedVersionNumber);
57
+ i0.ɵɵclassProp("selected", version_r4.VersionNumber === ctx_r1.selectedVersionNumber);
57
58
  i0.ɵɵadvance(2);
58
- i0.ɵɵtextInterpolate1("v", version_r5.VersionNumber);
59
+ i0.ɵɵtextInterpolate1("v", version_r4.VersionNumber);
59
60
  i0.ɵɵadvance(2);
60
- i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(5, 5, version_r5.__mj_CreatedAt, "short"));
61
+ i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(5, 5, version_r4.__mj_CreatedAt, "short"));
61
62
  i0.ɵɵadvance(2);
62
- i0.ɵɵconditional(version_r5.VersionNumber === ctx_r1.selectedVersionNumber ? 6 : -1);
63
+ i0.ɵɵconditional(version_r4.VersionNumber === ctx_r1.selectedVersionNumber ? 6 : -1);
63
64
  } }
64
65
  function ArtifactViewerPanelComponent_Conditional_1_Conditional_12_Template(rf, ctx) { if (rf & 1) {
65
- const _r3 = i0.ɵɵgetCurrentView();
66
66
  i0.ɵɵelementStart(0, "div", 23);
67
- i0.ɵɵlistener("click", function ArtifactViewerPanelComponent_Conditional_1_Conditional_12_Template_div_click_0_listener($event) { i0.ɵɵrestoreView(_r3); return i0.ɵɵresetView($event.stopPropagation()); });
67
+ i0.ɵɵlistener("click", function ArtifactViewerPanelComponent_Conditional_1_Conditional_12_Template_div_click_0_listener($event) { return $event.stopPropagation(); });
68
68
  i0.ɵɵrepeaterCreate(1, ArtifactViewerPanelComponent_Conditional_1_Conditional_12_For_2_Template, 7, 8, "div", 24, _forTrack0);
69
69
  i0.ɵɵelementEnd();
70
70
  } if (rf & 2) {
@@ -73,16 +73,16 @@ function ArtifactViewerPanelComponent_Conditional_1_Conditional_12_Template(rf,
73
73
  i0.ɵɵrepeater(ctx_r1.allVersions);
74
74
  } }
75
75
  function ArtifactViewerPanelComponent_Conditional_1_Conditional_13_Template(rf, ctx) { if (rf & 1) {
76
- const _r6 = i0.ɵɵgetCurrentView();
76
+ const _r5 = i0.ɵɵgetCurrentView();
77
77
  i0.ɵɵelementStart(0, "button", 29);
78
- i0.ɵɵlistener("click", function ArtifactViewerPanelComponent_Conditional_1_Conditional_13_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.pluginViewer == null ? null : ctx_r1.pluginViewer.AskUserForFeedback()); });
78
+ i0.ɵɵlistener("click", function ArtifactViewerPanelComponent_Conditional_1_Conditional_13_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.pluginViewer == null ? null : ctx_r1.pluginViewer.AskUserForFeedback()); });
79
79
  i0.ɵɵelement(1, "i", 30);
80
80
  i0.ɵɵelementEnd();
81
81
  } }
82
82
  function ArtifactViewerPanelComponent_Conditional_1_Conditional_14_Template(rf, ctx) { if (rf & 1) {
83
- const _r7 = i0.ɵɵgetCurrentView();
83
+ const _r6 = i0.ɵɵgetCurrentView();
84
84
  i0.ɵɵelementStart(0, "button", 31);
85
- i0.ɵɵlistener("click", function ArtifactViewerPanelComponent_Conditional_1_Conditional_14_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.onSaveToLibrary()); });
85
+ i0.ɵɵlistener("click", function ArtifactViewerPanelComponent_Conditional_1_Conditional_14_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.onSaveToLibrary()); });
86
86
  i0.ɵɵelement(1, "i");
87
87
  i0.ɵɵelementEnd();
88
88
  } if (rf & 2) {
@@ -93,16 +93,16 @@ function ArtifactViewerPanelComponent_Conditional_1_Conditional_14_Template(rf,
93
93
  i0.ɵɵclassMap(ctx_r1.isInCollection ? "fas fa-bookmark" : "far fa-bookmark");
94
94
  } }
95
95
  function ArtifactViewerPanelComponent_Conditional_1_Conditional_15_Template(rf, ctx) { if (rf & 1) {
96
- const _r8 = i0.ɵɵgetCurrentView();
96
+ const _r7 = i0.ɵɵgetCurrentView();
97
97
  i0.ɵɵelementStart(0, "button", 32);
98
- i0.ɵɵlistener("click", function ArtifactViewerPanelComponent_Conditional_1_Conditional_15_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r8); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.onShare()); });
98
+ i0.ɵɵlistener("click", function ArtifactViewerPanelComponent_Conditional_1_Conditional_15_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.onShare()); });
99
99
  i0.ɵɵelement(1, "i", 33);
100
100
  i0.ɵɵelementEnd();
101
101
  } }
102
102
  function ArtifactViewerPanelComponent_Conditional_1_Conditional_18_Template(rf, ctx) { if (rf & 1) {
103
- const _r9 = i0.ɵɵgetCurrentView();
103
+ const _r8 = i0.ɵɵgetCurrentView();
104
104
  i0.ɵɵelementStart(0, "button", 34);
105
- i0.ɵɵlistener("click", function ArtifactViewerPanelComponent_Conditional_1_Conditional_18_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.onMaximizeToggle()); });
105
+ i0.ɵɵlistener("click", function ArtifactViewerPanelComponent_Conditional_1_Conditional_18_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r8); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.onMaximizeToggle()); });
106
106
  i0.ɵɵelement(1, "i", 7);
107
107
  i0.ɵɵelementEnd();
108
108
  } if (rf & 2) {
@@ -112,9 +112,9 @@ function ArtifactViewerPanelComponent_Conditional_1_Conditional_18_Template(rf,
112
112
  i0.ɵɵproperty("ngClass", ctx_r1.isMaximized ? "fa-compress-arrows-alt" : "fa-arrows-left-right");
113
113
  } }
114
114
  function ArtifactViewerPanelComponent_Conditional_1_Conditional_19_Template(rf, ctx) { if (rf & 1) {
115
- const _r10 = i0.ɵɵgetCurrentView();
115
+ const _r9 = i0.ɵɵgetCurrentView();
116
116
  i0.ɵɵelementStart(0, "button", 35);
117
- i0.ɵɵlistener("click", function ArtifactViewerPanelComponent_Conditional_1_Conditional_19_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.onClose()); });
117
+ i0.ɵɵlistener("click", function ArtifactViewerPanelComponent_Conditional_1_Conditional_19_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.onClose()); });
118
118
  i0.ɵɵelement(1, "i", 36);
119
119
  i0.ɵɵelementEnd();
120
120
  } }
@@ -188,25 +188,25 @@ function ArtifactViewerPanelComponent_Conditional_4_Template(rf, ctx) { if (rf &
188
188
  function ArtifactViewerPanelComponent_Conditional_5_Conditional_1_For_2_Conditional_1_Template(rf, ctx) { if (rf & 1) {
189
189
  i0.ɵɵelement(0, "i");
190
190
  } if (rf & 2) {
191
- const tab_r12 = i0.ɵɵnextContext().$implicit;
191
+ const tab_r11 = i0.ɵɵnextContext().$implicit;
192
192
  const ctx_r1 = i0.ɵɵnextContext(3);
193
- i0.ɵɵclassMap(ctx_r1.GetTabIcon(tab_r12));
193
+ i0.ɵɵclassMap(ctx_r1.GetTabIcon(tab_r11));
194
194
  } }
195
195
  function ArtifactViewerPanelComponent_Conditional_5_Conditional_1_For_2_Template(rf, ctx) { if (rf & 1) {
196
- const _r11 = i0.ɵɵgetCurrentView();
196
+ const _r10 = i0.ɵɵgetCurrentView();
197
197
  i0.ɵɵelementStart(0, "button", 52);
198
- i0.ɵɵlistener("click", function ArtifactViewerPanelComponent_Conditional_5_Conditional_1_For_2_Template_button_click_0_listener() { const tab_r12 = i0.ɵɵrestoreView(_r11).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.SetActiveTab(tab_r12)); });
198
+ i0.ɵɵlistener("click", function ArtifactViewerPanelComponent_Conditional_5_Conditional_1_For_2_Template_button_click_0_listener() { const tab_r11 = i0.ɵɵrestoreView(_r10).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.SetActiveTab(tab_r11)); });
199
199
  i0.ɵɵconditionalCreate(1, ArtifactViewerPanelComponent_Conditional_5_Conditional_1_For_2_Conditional_1_Template, 1, 2, "i", 53);
200
200
  i0.ɵɵtext(2);
201
201
  i0.ɵɵelementEnd();
202
202
  } if (rf & 2) {
203
- const tab_r12 = ctx.$implicit;
203
+ const tab_r11 = ctx.$implicit;
204
204
  const ctx_r1 = i0.ɵɵnextContext(3);
205
- i0.ɵɵclassProp("active", ctx_r1.activeTab === tab_r12.toLowerCase());
205
+ i0.ɵɵclassProp("active", ctx_r1.activeTab === tab_r11.toLowerCase());
206
206
  i0.ɵɵadvance();
207
- i0.ɵɵconditional(ctx_r1.GetTabIcon(tab_r12) ? 1 : -1);
207
+ i0.ɵɵconditional(ctx_r1.GetTabIcon(tab_r11) ? 1 : -1);
208
208
  i0.ɵɵadvance();
209
- i0.ɵɵtextInterpolate1(" ", tab_r12, " ");
209
+ i0.ɵɵtextInterpolate1(" ", tab_r11, " ");
210
210
  } }
211
211
  function ArtifactViewerPanelComponent_Conditional_5_Conditional_1_Template(rf, ctx) { if (rf & 1) {
212
212
  i0.ɵɵelementStart(0, "div", 39);
@@ -218,9 +218,9 @@ function ArtifactViewerPanelComponent_Conditional_5_Conditional_1_Template(rf, c
218
218
  i0.ɵɵrepeater(ctx_r1.allTabs);
219
219
  } }
220
220
  function ArtifactViewerPanelComponent_Conditional_5_Conditional_3_Template(rf, ctx) { if (rf & 1) {
221
- const _r13 = i0.ɵɵgetCurrentView();
221
+ const _r12 = i0.ɵɵgetCurrentView();
222
222
  i0.ɵɵelementStart(0, "div", 54)(1, "mj-artifact-type-plugin-viewer", 55);
223
- i0.ɵɵlistener("openEntityRecord", function ArtifactViewerPanelComponent_Conditional_5_Conditional_3_Template_mj_artifact_type_plugin_viewer_openEntityRecord_1_listener($event) { i0.ɵɵrestoreView(_r13); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.onOpenEntityRecord($event)); })("navigationRequest", function ArtifactViewerPanelComponent_Conditional_5_Conditional_3_Template_mj_artifact_type_plugin_viewer_navigationRequest_1_listener($event) { i0.ɵɵrestoreView(_r13); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.onNavigationRequest($event)); })("pluginLoaded", function ArtifactViewerPanelComponent_Conditional_5_Conditional_3_Template_mj_artifact_type_plugin_viewer_pluginLoaded_1_listener() { i0.ɵɵrestoreView(_r13); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.onPluginLoaded()); })("tabsChanged", function ArtifactViewerPanelComponent_Conditional_5_Conditional_3_Template_mj_artifact_type_plugin_viewer_tabsChanged_1_listener() { i0.ɵɵrestoreView(_r13); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.onTabsChanged()); })("applyFormRequested", function ArtifactViewerPanelComponent_Conditional_5_Conditional_3_Template_mj_artifact_type_plugin_viewer_applyFormRequested_1_listener($event) { i0.ɵɵrestoreView(_r13); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.applyFormRequested.emit($event)); });
223
+ i0.ɵɵlistener("openEntityRecord", function ArtifactViewerPanelComponent_Conditional_5_Conditional_3_Template_mj_artifact_type_plugin_viewer_openEntityRecord_1_listener($event) { i0.ɵɵrestoreView(_r12); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.onOpenEntityRecord($event)); })("navigationRequest", function ArtifactViewerPanelComponent_Conditional_5_Conditional_3_Template_mj_artifact_type_plugin_viewer_navigationRequest_1_listener($event) { i0.ɵɵrestoreView(_r12); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.onNavigationRequest($event)); })("pluginLoaded", function ArtifactViewerPanelComponent_Conditional_5_Conditional_3_Template_mj_artifact_type_plugin_viewer_pluginLoaded_1_listener() { i0.ɵɵrestoreView(_r12); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.onPluginLoaded()); })("tabsChanged", function ArtifactViewerPanelComponent_Conditional_5_Conditional_3_Template_mj_artifact_type_plugin_viewer_tabsChanged_1_listener() { i0.ɵɵrestoreView(_r12); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.onTabsChanged()); })("applyFormRequested", function ArtifactViewerPanelComponent_Conditional_5_Conditional_3_Template_mj_artifact_type_plugin_viewer_applyFormRequested_1_listener($event) { i0.ɵɵrestoreView(_r12); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.applyFormRequested.emit($event)); });
224
224
  i0.ɵɵelementEnd()();
225
225
  } if (rf & 2) {
226
226
  const ctx_r1 = i0.ɵɵnextContext(2);
@@ -229,8 +229,8 @@ function ArtifactViewerPanelComponent_Conditional_5_Conditional_3_Template(rf, c
229
229
  i0.ɵɵproperty("artifactVersion", ctx_r1.artifactVersion)("artifactTypeName", ctx_r1.artifactTypeName)("contentType", ctx_r1.contentType)("readonly", true);
230
230
  } }
231
231
  function ArtifactViewerPanelComponent_Conditional_5_Conditional_4_Conditional_1_Conditional_7_Template(rf, ctx) { if (rf & 1) {
232
- i0.ɵɵelementStart(0, "div", 61);
233
- i0.ɵɵelement(1, "mj-markdown", 63);
232
+ i0.ɵɵelementStart(0, "div", 62);
233
+ i0.ɵɵelement(1, "mj-markdown", 64);
234
234
  i0.ɵɵelementEnd();
235
235
  } if (rf & 2) {
236
236
  const ctx_r1 = i0.ɵɵnextContext(4);
@@ -238,37 +238,95 @@ function ArtifactViewerPanelComponent_Conditional_5_Conditional_4_Conditional_1_
238
238
  i0.ɵɵproperty("data", ctx_r1.displayMarkdown)("enableCollapsibleHeadings", true)("enableLineNumbers", true)("enableSmartypants", true)("enableHtml", true);
239
239
  } }
240
240
  function ArtifactViewerPanelComponent_Conditional_5_Conditional_4_Conditional_1_Conditional_8_Template(rf, ctx) { if (rf & 1) {
241
- i0.ɵɵelement(0, "div", 62);
241
+ i0.ɵɵelement(0, "div", 63);
242
242
  } if (rf & 2) {
243
243
  const ctx_r1 = i0.ɵɵnextContext(4);
244
244
  i0.ɵɵproperty("innerHTML", ctx_r1.displayHtml, i0.ɵɵsanitizeHtml);
245
245
  } }
246
246
  function ArtifactViewerPanelComponent_Conditional_5_Conditional_4_Conditional_1_Template(rf, ctx) { if (rf & 1) {
247
- const _r14 = i0.ɵɵgetCurrentView();
248
- i0.ɵɵelementStart(0, "div", 56)(1, "button", 57);
249
- i0.ɵɵlistener("click", function ArtifactViewerPanelComponent_Conditional_5_Conditional_4_Conditional_1_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r14); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.onPrintDisplayContent()); });
250
- i0.ɵɵelement(2, "i", 58);
247
+ const _r13 = i0.ɵɵgetCurrentView();
248
+ i0.ɵɵelementStart(0, "div", 57)(1, "button", 58);
249
+ i0.ɵɵlistener("click", function ArtifactViewerPanelComponent_Conditional_5_Conditional_4_Conditional_1_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r13); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.onPrintDisplayContent()); });
250
+ i0.ɵɵelement(2, "i", 59);
251
251
  i0.ɵɵtext(3, " Print ");
252
252
  i0.ɵɵelementEnd();
253
- i0.ɵɵelementStart(4, "button", 59);
254
- i0.ɵɵlistener("click", function ArtifactViewerPanelComponent_Conditional_5_Conditional_4_Conditional_1_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r14); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.onCopyDisplayContent()); });
255
- i0.ɵɵelement(5, "i", 60);
253
+ i0.ɵɵelementStart(4, "button", 60);
254
+ i0.ɵɵlistener("click", function ArtifactViewerPanelComponent_Conditional_5_Conditional_4_Conditional_1_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r13); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.onCopyDisplayContent()); });
255
+ i0.ɵɵelement(5, "i", 61);
256
256
  i0.ɵɵtext(6, " Copy ");
257
257
  i0.ɵɵelementEnd()();
258
- i0.ɵɵconditionalCreate(7, ArtifactViewerPanelComponent_Conditional_5_Conditional_4_Conditional_1_Conditional_7_Template, 2, 5, "div", 61)(8, ArtifactViewerPanelComponent_Conditional_5_Conditional_4_Conditional_1_Conditional_8_Template, 1, 1, "div", 62);
258
+ i0.ɵɵconditionalCreate(7, ArtifactViewerPanelComponent_Conditional_5_Conditional_4_Conditional_1_Conditional_7_Template, 2, 5, "div", 62)(8, ArtifactViewerPanelComponent_Conditional_5_Conditional_4_Conditional_1_Conditional_8_Template, 1, 1, "div", 63);
259
259
  } if (rf & 2) {
260
260
  const ctx_r1 = i0.ɵɵnextContext(3);
261
261
  i0.ɵɵadvance(7);
262
262
  i0.ɵɵconditional(ctx_r1.displayMarkdown ? 7 : ctx_r1.displayHtml ? 8 : -1);
263
263
  } }
264
+ function ArtifactViewerPanelComponent_Conditional_5_Conditional_4_Conditional_2_Conditional_8_Template(rf, ctx) { if (rf & 1) {
265
+ i0.ɵɵtext(0);
266
+ } if (rf & 2) {
267
+ const ctx_r1 = i0.ɵɵnextContext(4);
268
+ i0.ɵɵtextInterpolate1(" \u00B7 ", ctx_r1.fallbackSize);
269
+ } }
270
+ function ArtifactViewerPanelComponent_Conditional_5_Conditional_4_Conditional_2_Conditional_12_Conditional_2_Template(rf, ctx) { if (rf & 1) {
271
+ i0.ɵɵelementStart(0, "div", 69);
272
+ i0.ɵɵtext(1, "Showing the first part only \u2014 download the file for all of it.");
273
+ i0.ɵɵelementEnd();
274
+ } }
275
+ function ArtifactViewerPanelComponent_Conditional_5_Conditional_4_Conditional_2_Conditional_12_Template(rf, ctx) { if (rf & 1) {
276
+ i0.ɵɵelementStart(0, "pre", 72);
277
+ i0.ɵɵtext(1);
278
+ i0.ɵɵelementEnd();
279
+ i0.ɵɵconditionalCreate(2, ArtifactViewerPanelComponent_Conditional_5_Conditional_4_Conditional_2_Conditional_12_Conditional_2_Template, 2, 0, "div", 69);
280
+ } if (rf & 2) {
281
+ const ctx_r1 = i0.ɵɵnextContext(4);
282
+ i0.ɵɵadvance();
283
+ i0.ɵɵtextInterpolate(ctx_r1.fallbackText);
284
+ i0.ɵɵadvance();
285
+ i0.ɵɵconditional(ctx_r1.fallbackTextTruncated ? 2 : -1);
286
+ } }
287
+ function ArtifactViewerPanelComponent_Conditional_5_Conditional_4_Conditional_2_Template(rf, ctx) { if (rf & 1) {
288
+ const _r14 = i0.ɵɵgetCurrentView();
289
+ i0.ɵɵelementStart(0, "div", 56)(1, "div", 65);
290
+ i0.ɵɵelement(2, "i", 66);
291
+ i0.ɵɵelementStart(3, "div", 67)(4, "div", 68);
292
+ i0.ɵɵtext(5);
293
+ i0.ɵɵelementEnd();
294
+ i0.ɵɵelementStart(6, "div", 69);
295
+ i0.ɵɵtext(7);
296
+ i0.ɵɵconditionalCreate(8, ArtifactViewerPanelComponent_Conditional_5_Conditional_4_Conditional_2_Conditional_8_Template, 1, 1);
297
+ i0.ɵɵelementEnd()();
298
+ i0.ɵɵelementStart(9, "button", 70);
299
+ i0.ɵɵlistener("click", function ArtifactViewerPanelComponent_Conditional_5_Conditional_4_Conditional_2_Template_button_click_9_listener() { i0.ɵɵrestoreView(_r14); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.downloadArtifactFile()); });
300
+ i0.ɵɵelement(10, "i", 71);
301
+ i0.ɵɵtext(11);
302
+ i0.ɵɵelementEnd()();
303
+ i0.ɵɵconditionalCreate(12, ArtifactViewerPanelComponent_Conditional_5_Conditional_4_Conditional_2_Conditional_12_Template, 3, 2);
304
+ i0.ɵɵelementEnd();
305
+ } if (rf & 2) {
306
+ const ctx_r1 = i0.ɵɵnextContext(3);
307
+ i0.ɵɵadvance(2);
308
+ i0.ɵɵproperty("ngClass", ctx_r1.artifactIcon);
309
+ i0.ɵɵadvance(3);
310
+ i0.ɵɵtextInterpolate(ctx_r1.fallbackFileName);
311
+ i0.ɵɵadvance(2);
312
+ i0.ɵɵtextInterpolate((ctx_r1.artifactVersion == null ? null : ctx_r1.artifactVersion.MimeType) || ctx_r1.artifact.Type);
313
+ i0.ɵɵadvance();
314
+ i0.ɵɵconditional(ctx_r1.fallbackSize ? 8 : -1);
315
+ i0.ɵɵadvance();
316
+ i0.ɵɵproperty("disabled", ctx_r1.fallbackBusy);
317
+ i0.ɵɵadvance(2);
318
+ i0.ɵɵtextInterpolate1(" ", ctx_r1.fallbackBusy ? "Preparing\u2026" : "Download", " ");
319
+ i0.ɵɵadvance();
320
+ i0.ɵɵconditional(ctx_r1.fallbackText !== null ? 12 : -1);
321
+ } }
264
322
  function ArtifactViewerPanelComponent_Conditional_5_Conditional_4_Template(rf, ctx) { if (rf & 1) {
265
323
  i0.ɵɵelementStart(0, "div", 42);
266
- i0.ɵɵconditionalCreate(1, ArtifactViewerPanelComponent_Conditional_5_Conditional_4_Conditional_1_Template, 9, 1);
324
+ i0.ɵɵconditionalCreate(1, ArtifactViewerPanelComponent_Conditional_5_Conditional_4_Conditional_1_Template, 9, 1)(2, ArtifactViewerPanelComponent_Conditional_5_Conditional_4_Conditional_2_Template, 13, 7, "div", 56);
267
325
  i0.ɵɵelementEnd();
268
326
  } if (rf & 2) {
269
327
  const ctx_r1 = i0.ɵɵnextContext(2);
270
328
  i0.ɵɵadvance();
271
- i0.ɵɵconditional(ctx_r1.displayMarkdown || ctx_r1.displayHtml ? 1 : -1);
329
+ i0.ɵɵconditional(ctx_r1.displayMarkdown || ctx_r1.displayHtml ? 1 : ctx_r1.showFileFallback ? 2 : -1);
272
330
  } }
273
331
  function ArtifactViewerPanelComponent_Conditional_5_Conditional_29_Template(rf, ctx) { if (rf & 1) {
274
332
  i0.ɵɵelementStart(0, "div", 46)(1, "label");
@@ -304,15 +362,15 @@ function ArtifactViewerPanelComponent_Conditional_5_Conditional_31_For_5_Conditi
304
362
  i0.ɵɵtextInterpolate(attr_r15.Value);
305
363
  } }
306
364
  function ArtifactViewerPanelComponent_Conditional_5_Conditional_31_For_5_Conditional_4_Template(rf, ctx) { if (rf & 1) {
307
- i0.ɵɵelementStart(0, "span", 66);
365
+ i0.ɵɵelementStart(0, "span", 75);
308
366
  i0.ɵɵtext(1, "Empty");
309
367
  i0.ɵɵelementEnd();
310
368
  } }
311
369
  function ArtifactViewerPanelComponent_Conditional_5_Conditional_31_For_5_Template(rf, ctx) { if (rf & 1) {
312
- i0.ɵɵelementStart(0, "div", 65)(1, "label");
370
+ i0.ɵɵelementStart(0, "div", 74)(1, "label");
313
371
  i0.ɵɵtext(2);
314
372
  i0.ɵɵelementEnd();
315
- i0.ɵɵconditionalCreate(3, ArtifactViewerPanelComponent_Conditional_5_Conditional_31_For_5_Conditional_3_Template, 2, 1, "span")(4, ArtifactViewerPanelComponent_Conditional_5_Conditional_31_For_5_Conditional_4_Template, 2, 0, "span", 66);
373
+ i0.ɵɵconditionalCreate(3, ArtifactViewerPanelComponent_Conditional_5_Conditional_31_For_5_Conditional_3_Template, 2, 1, "span")(4, ArtifactViewerPanelComponent_Conditional_5_Conditional_31_For_5_Conditional_4_Template, 2, 0, "span", 75);
316
374
  i0.ɵɵelementEnd();
317
375
  } if (rf & 2) {
318
376
  const attr_r15 = ctx.$implicit;
@@ -325,8 +383,8 @@ function ArtifactViewerPanelComponent_Conditional_5_Conditional_31_Template(rf,
325
383
  i0.ɵɵelementStart(0, "div", 47)(1, "h4");
326
384
  i0.ɵɵtext(2, "Version Attributes");
327
385
  i0.ɵɵelementEnd();
328
- i0.ɵɵelementStart(3, "div", 64);
329
- i0.ɵɵrepeaterCreate(4, ArtifactViewerPanelComponent_Conditional_5_Conditional_31_For_5_Template, 5, 2, "div", 65, _forTrack0);
386
+ i0.ɵɵelementStart(3, "div", 73);
387
+ i0.ɵɵrepeaterCreate(4, ArtifactViewerPanelComponent_Conditional_5_Conditional_31_For_5_Template, 5, 2, "div", 74, _forTrack0);
330
388
  i0.ɵɵelementEnd()();
331
389
  } if (rf & 2) {
332
390
  const ctx_r1 = i0.ɵɵnextContext(2);
@@ -334,26 +392,26 @@ function ArtifactViewerPanelComponent_Conditional_5_Conditional_31_Template(rf,
334
392
  i0.ɵɵrepeater(ctx_r1.filteredAttributes);
335
393
  } }
336
394
  function ArtifactViewerPanelComponent_Conditional_5_Conditional_33_For_2_Conditional_2_Template(rf, ctx) { if (rf & 1) {
337
- i0.ɵɵelement(0, "i", 70);
395
+ i0.ɵɵelement(0, "i", 79);
338
396
  } }
339
397
  function ArtifactViewerPanelComponent_Conditional_5_Conditional_33_For_2_Conditional_3_Template(rf, ctx) { if (rf & 1) {
340
- i0.ɵɵelement(0, "i", 71);
398
+ i0.ɵɵelement(0, "i", 80);
341
399
  } }
342
400
  function ArtifactViewerPanelComponent_Conditional_5_Conditional_33_For_2_Template(rf, ctx) { if (rf & 1) {
343
401
  const _r16 = i0.ɵɵgetCurrentView();
344
- i0.ɵɵelementStart(0, "div", 68);
402
+ i0.ɵɵelementStart(0, "div", 77);
345
403
  i0.ɵɵlistener("click", function ArtifactViewerPanelComponent_Conditional_5_Conditional_33_For_2_Template_div_click_0_listener() { const link_r17 = i0.ɵɵrestoreView(_r16).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(link_r17.hasAccess ? ctx_r1.onNavigateToLink(link_r17) : null); });
346
- i0.ɵɵelementStart(1, "div", 69);
347
- i0.ɵɵconditionalCreate(2, ArtifactViewerPanelComponent_Conditional_5_Conditional_33_For_2_Conditional_2_Template, 1, 0, "i", 70)(3, ArtifactViewerPanelComponent_Conditional_5_Conditional_33_For_2_Conditional_3_Template, 1, 0, "i", 71);
404
+ i0.ɵɵelementStart(1, "div", 78);
405
+ i0.ɵɵconditionalCreate(2, ArtifactViewerPanelComponent_Conditional_5_Conditional_33_For_2_Conditional_2_Template, 1, 0, "i", 79)(3, ArtifactViewerPanelComponent_Conditional_5_Conditional_33_For_2_Conditional_3_Template, 1, 0, "i", 80);
348
406
  i0.ɵɵelementEnd();
349
- i0.ɵɵelementStart(4, "div", 72)(5, "div", 73);
407
+ i0.ɵɵelementStart(4, "div", 81)(5, "div", 82);
350
408
  i0.ɵɵtext(6);
351
409
  i0.ɵɵelementEnd();
352
- i0.ɵɵelementStart(7, "div", 74);
410
+ i0.ɵɵelementStart(7, "div", 83);
353
411
  i0.ɵɵtext(8);
354
412
  i0.ɵɵelementEnd()();
355
- i0.ɵɵelementStart(9, "div", 75);
356
- i0.ɵɵelement(10, "i", 76);
413
+ i0.ɵɵelementStart(9, "div", 84);
414
+ i0.ɵɵelement(10, "i", 85);
357
415
  i0.ɵɵelementEnd()();
358
416
  } if (rf & 2) {
359
417
  const link_r17 = ctx.$implicit;
@@ -368,7 +426,7 @@ function ArtifactViewerPanelComponent_Conditional_5_Conditional_33_For_2_Templat
368
426
  } }
369
427
  function ArtifactViewerPanelComponent_Conditional_5_Conditional_33_Template(rf, ctx) { if (rf & 1) {
370
428
  i0.ɵɵelementStart(0, "div", 49);
371
- i0.ɵɵrepeaterCreate(1, ArtifactViewerPanelComponent_Conditional_5_Conditional_33_For_2_Template, 11, 8, "div", 67, _forTrack1);
429
+ i0.ɵɵrepeaterCreate(1, ArtifactViewerPanelComponent_Conditional_5_Conditional_33_For_2_Template, 11, 8, "div", 76, _forTrack1);
372
430
  i0.ɵɵelementEnd();
373
431
  } if (rf & 2) {
374
432
  const ctx_r1 = i0.ɵɵnextContext(2);
@@ -382,8 +440,8 @@ function ArtifactViewerPanelComponent_Conditional_5_Conditional_35_Conditional_0
382
440
  i0.ɵɵelementContainer(0);
383
441
  } }
384
442
  function ArtifactViewerPanelComponent_Conditional_5_Conditional_35_Conditional_0_Template(rf, ctx) { if (rf & 1) {
385
- i0.ɵɵelementStart(0, "div", 77);
386
- i0.ɵɵtemplate(1, ArtifactViewerPanelComponent_Conditional_5_Conditional_35_Conditional_0_ng_container_1_Template, 1, 0, "ng-container", 78);
443
+ i0.ɵɵelementStart(0, "div", 86);
444
+ i0.ɵɵtemplate(1, ArtifactViewerPanelComponent_Conditional_5_Conditional_35_Conditional_0_ng_container_1_Template, 1, 0, "ng-container", 87);
387
445
  i0.ɵɵelementEnd();
388
446
  } if (rf & 2) {
389
447
  const ctx_r1 = i0.ɵɵnextContext(3);
@@ -391,8 +449,8 @@ function ArtifactViewerPanelComponent_Conditional_5_Conditional_35_Conditional_0
391
449
  i0.ɵɵproperty("ngComponentOutlet", ctx)("ngComponentOutletInputs", ctx_r1.GetComponentInputs(ctx_r1.activeTab));
392
450
  } }
393
451
  function ArtifactViewerPanelComponent_Conditional_5_Conditional_35_Conditional_1_Conditional_0_Case_1_Template(rf, ctx) { if (rf & 1) {
394
- i0.ɵɵelementStart(0, "div", 80);
395
- i0.ɵɵelement(1, "mj-markdown", 63);
452
+ i0.ɵɵelementStart(0, "div", 89);
453
+ i0.ɵɵelement(1, "mj-markdown", 64);
396
454
  i0.ɵɵelementEnd();
397
455
  } if (rf & 2) {
398
456
  const tabData_r18 = i0.ɵɵnextContext();
@@ -401,13 +459,13 @@ function ArtifactViewerPanelComponent_Conditional_5_Conditional_35_Conditional_1
401
459
  } }
402
460
  function ArtifactViewerPanelComponent_Conditional_5_Conditional_35_Conditional_1_Conditional_0_Case_2_Template(rf, ctx) { if (rf & 1) {
403
461
  const _r19 = i0.ɵɵgetCurrentView();
404
- i0.ɵɵelementStart(0, "div", 81)(1, "div", 85)(2, "button", 86);
462
+ i0.ɵɵelementStart(0, "div", 90)(1, "div", 94)(2, "button", 95);
405
463
  i0.ɵɵlistener("click", function ArtifactViewerPanelComponent_Conditional_5_Conditional_35_Conditional_1_Conditional_0_Case_2_Template_button_click_2_listener() { i0.ɵɵrestoreView(_r19); const ctx_r1 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r1.onCopyToClipboard()); });
406
- i0.ɵɵelement(3, "i", 60);
464
+ i0.ɵɵelement(3, "i", 61);
407
465
  i0.ɵɵtext(4, " Copy ");
408
466
  i0.ɵɵelementEnd()();
409
- i0.ɵɵelementStart(5, "div", 87);
410
- i0.ɵɵelement(6, "mj-code-editor", 88);
467
+ i0.ɵɵelementStart(5, "div", 96);
468
+ i0.ɵɵelement(6, "mj-code-editor", 97);
411
469
  i0.ɵɵelementEnd()();
412
470
  } if (rf & 2) {
413
471
  const tabData_r18 = i0.ɵɵnextContext();
@@ -416,13 +474,13 @@ function ArtifactViewerPanelComponent_Conditional_5_Conditional_35_Conditional_1
416
474
  } }
417
475
  function ArtifactViewerPanelComponent_Conditional_5_Conditional_35_Conditional_1_Conditional_0_Case_3_Template(rf, ctx) { if (rf & 1) {
418
476
  const _r20 = i0.ɵɵgetCurrentView();
419
- i0.ɵɵelementStart(0, "div", 82)(1, "div", 89)(2, "button", 90);
477
+ i0.ɵɵelementStart(0, "div", 91)(1, "div", 98)(2, "button", 99);
420
478
  i0.ɵɵlistener("click", function ArtifactViewerPanelComponent_Conditional_5_Conditional_35_Conditional_1_Conditional_0_Case_3_Template_button_click_2_listener() { i0.ɵɵrestoreView(_r20); const ctx_r1 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r1.onCopyToClipboard()); });
421
- i0.ɵɵelement(3, "i", 60);
479
+ i0.ɵɵelement(3, "i", 61);
422
480
  i0.ɵɵtext(4, " Copy ");
423
481
  i0.ɵɵelementEnd()();
424
- i0.ɵɵelementStart(5, "div", 91);
425
- i0.ɵɵelement(6, "mj-code-editor", 88);
482
+ i0.ɵɵelementStart(5, "div", 100);
483
+ i0.ɵɵelement(6, "mj-code-editor", 97);
426
484
  i0.ɵɵelementEnd()();
427
485
  } if (rf & 2) {
428
486
  const tabData_r18 = i0.ɵɵnextContext();
@@ -430,13 +488,13 @@ function ArtifactViewerPanelComponent_Conditional_5_Conditional_35_Conditional_1
430
488
  i0.ɵɵproperty("value", tabData_r18.content)("language", tabData_r18.language || "typescript")("readonly", true)("lineWrapping", true);
431
489
  } }
432
490
  function ArtifactViewerPanelComponent_Conditional_5_Conditional_35_Conditional_1_Conditional_0_Case_4_Template(rf, ctx) { if (rf & 1) {
433
- i0.ɵɵelement(0, "div", 83);
491
+ i0.ɵɵelement(0, "div", 92);
434
492
  } if (rf & 2) {
435
493
  const tabData_r18 = i0.ɵɵnextContext();
436
494
  i0.ɵɵproperty("innerHTML", tabData_r18.content, i0.ɵɵsanitizeHtml);
437
495
  } }
438
496
  function ArtifactViewerPanelComponent_Conditional_5_Conditional_35_Conditional_1_Conditional_0_Case_5_Template(rf, ctx) { if (rf & 1) {
439
- i0.ɵɵelementStart(0, "pre", 84);
497
+ i0.ɵɵelementStart(0, "pre", 93);
440
498
  i0.ɵɵtext(1);
441
499
  i0.ɵɵelementEnd();
442
500
  } if (rf & 2) {
@@ -445,8 +503,8 @@ function ArtifactViewerPanelComponent_Conditional_5_Conditional_35_Conditional_1
445
503
  i0.ɵɵtextInterpolate(tabData_r18.content);
446
504
  } }
447
505
  function ArtifactViewerPanelComponent_Conditional_5_Conditional_35_Conditional_1_Conditional_0_Template(rf, ctx) { if (rf & 1) {
448
- i0.ɵɵelementStart(0, "div", 79);
449
- i0.ɵɵconditionalCreate(1, ArtifactViewerPanelComponent_Conditional_5_Conditional_35_Conditional_1_Conditional_0_Case_1_Template, 2, 5, "div", 80)(2, ArtifactViewerPanelComponent_Conditional_5_Conditional_35_Conditional_1_Conditional_0_Case_2_Template, 7, 4, "div", 81)(3, ArtifactViewerPanelComponent_Conditional_5_Conditional_35_Conditional_1_Conditional_0_Case_3_Template, 7, 4, "div", 82)(4, ArtifactViewerPanelComponent_Conditional_5_Conditional_35_Conditional_1_Conditional_0_Case_4_Template, 1, 1, "div", 83)(5, ArtifactViewerPanelComponent_Conditional_5_Conditional_35_Conditional_1_Conditional_0_Case_5_Template, 2, 1, "pre", 84);
506
+ i0.ɵɵelementStart(0, "div", 88);
507
+ i0.ɵɵconditionalCreate(1, ArtifactViewerPanelComponent_Conditional_5_Conditional_35_Conditional_1_Conditional_0_Case_1_Template, 2, 5, "div", 89)(2, ArtifactViewerPanelComponent_Conditional_5_Conditional_35_Conditional_1_Conditional_0_Case_2_Template, 7, 4, "div", 90)(3, ArtifactViewerPanelComponent_Conditional_5_Conditional_35_Conditional_1_Conditional_0_Case_3_Template, 7, 4, "div", 91)(4, ArtifactViewerPanelComponent_Conditional_5_Conditional_35_Conditional_1_Conditional_0_Case_4_Template, 1, 1, "div", 92)(5, ArtifactViewerPanelComponent_Conditional_5_Conditional_35_Conditional_1_Conditional_0_Case_5_Template, 2, 1, "pre", 93);
450
508
  i0.ɵɵelementEnd();
451
509
  } if (rf & 2) {
452
510
  let tmp_5_0;
@@ -454,14 +512,14 @@ function ArtifactViewerPanelComponent_Conditional_5_Conditional_35_Conditional_1
454
512
  i0.ɵɵconditional((tmp_5_0 = ctx.type) === "markdown" ? 1 : tmp_5_0 === "json" ? 2 : tmp_5_0 === "code" ? 3 : tmp_5_0 === "html" ? 4 : tmp_5_0 === "plaintext" ? 5 : -1);
455
513
  } }
456
514
  function ArtifactViewerPanelComponent_Conditional_5_Conditional_35_Conditional_1_Template(rf, ctx) { if (rf & 1) {
457
- i0.ɵɵconditionalCreate(0, ArtifactViewerPanelComponent_Conditional_5_Conditional_35_Conditional_1_Conditional_0_Template, 6, 1, "div", 79);
515
+ i0.ɵɵconditionalCreate(0, ArtifactViewerPanelComponent_Conditional_5_Conditional_35_Conditional_1_Conditional_0_Template, 6, 1, "div", 88);
458
516
  } if (rf & 2) {
459
517
  let tmp_3_0;
460
518
  const ctx_r1 = i0.ɵɵnextContext(3);
461
519
  i0.ɵɵconditional((tmp_3_0 = ctx_r1.GetTabContent(ctx_r1.activeTab)) ? 0 : -1, tmp_3_0);
462
520
  } }
463
521
  function ArtifactViewerPanelComponent_Conditional_5_Conditional_35_Template(rf, ctx) { if (rf & 1) {
464
- i0.ɵɵconditionalCreate(0, ArtifactViewerPanelComponent_Conditional_5_Conditional_35_Conditional_0_Template, 2, 2, "div", 77)(1, ArtifactViewerPanelComponent_Conditional_5_Conditional_35_Conditional_1_Template, 1, 1);
522
+ i0.ɵɵconditionalCreate(0, ArtifactViewerPanelComponent_Conditional_5_Conditional_35_Conditional_0_Template, 2, 2, "div", 86)(1, ArtifactViewerPanelComponent_Conditional_5_Conditional_35_Conditional_1_Template, 1, 1);
465
523
  } if (rf & 2) {
466
524
  let tmp_2_0;
467
525
  const ctx_r1 = i0.ɵɵnextContext(2);
@@ -472,7 +530,7 @@ function ArtifactViewerPanelComponent_Conditional_5_Template(rf, ctx) { if (rf &
472
530
  i0.ɵɵconditionalCreate(1, ArtifactViewerPanelComponent_Conditional_5_Conditional_1_Template, 3, 0, "div", 39);
473
531
  i0.ɵɵelementStart(2, "div", 40);
474
532
  i0.ɵɵconditionalCreate(3, ArtifactViewerPanelComponent_Conditional_5_Conditional_3_Template, 2, 6, "div", 41);
475
- i0.ɵɵconditionalCreate(4, ArtifactViewerPanelComponent_Conditional_5_Conditional_4_Template, 2, 1, "div", 42);
533
+ i0.ɵɵconditionalCreate(4, ArtifactViewerPanelComponent_Conditional_5_Conditional_4_Template, 3, 1, "div", 42);
476
534
  i0.ɵɵelementStart(5, "div", 43)(6, "div", 44)(7, "div", 45)(8, "label");
477
535
  i0.ɵɵtext(9, "Type");
478
536
  i0.ɵɵelementEnd();
@@ -546,6 +604,7 @@ export class ArtifactViewerPanelComponent extends BaseAngularComponent {
546
604
  notificationService;
547
605
  sanitizer;
548
606
  artifactIconService;
607
+ artifactFileService;
549
608
  artifactId;
550
609
  currentUser;
551
610
  environmentId;
@@ -593,6 +652,17 @@ export class ArtifactViewerPanelComponent extends BaseAngularComponent {
593
652
  activeTab = 'display'; // Changed to string to support dynamic tabs
594
653
  displayMarkdown = null;
595
654
  displayHtml = null;
655
+ /**
656
+ * The no-plugin fallback. An artifact type with no viewer plugin (CSV today) used to render an empty
657
+ * pane: the display tab only knew the extracted markdown/HTML attributes, and a file-backed version
658
+ * has no inline Content to show. Now such an artifact gets a file card with a Download action, and
659
+ * text-like content (text/*, JSON, CSV) is fetched and shown as plain text — capped, so a large file
660
+ * is downloaded rather than rendered.
661
+ */
662
+ fallbackText = null;
663
+ fallbackTextTruncated = false;
664
+ fallbackBusy = false;
665
+ static FALLBACK_TEXT_MAX_CHARS = 200_000;
596
666
  versionAttributes = [];
597
667
  artifactTypeDriverClass = null;
598
668
  /** Populated from ArtifactType.ContentCategory. Used to suppress the JSON tab for
@@ -711,19 +781,23 @@ export class ArtifactViewerPanelComponent extends BaseAngularComponent {
711
781
  : tabDef.componentInputs || {};
712
782
  }
713
783
  recentAccessService;
714
- constructor(cdr, notificationService, sanitizer, artifactIconService) {
784
+ constructor(cdr, notificationService, sanitizer, artifactIconService, artifactFileService) {
715
785
  super();
716
786
  this.cdr = cdr;
717
787
  this.notificationService = notificationService;
718
788
  this.sanitizer = sanitizer;
719
789
  this.artifactIconService = artifactIconService;
790
+ this.artifactFileService = artifactFileService;
720
791
  this.recentAccessService = new RecentAccessService();
721
792
  }
722
793
  async ngOnInit() {
723
794
  // Subscribe to refresh trigger for dynamic version changes
724
795
  if (this.refreshTrigger) {
725
796
  this.refreshTrigger.pipe(takeUntil(this.destroy$)).subscribe(async (data) => {
726
- if (data.artifactId === this.artifactId) {
797
+ // UUIDsEqual, not ===: SQL Server hands back upper-case UUIDs and PostgreSQL lower-case, so
798
+ // a raw comparison silently drops a legitimate refresh whenever the emitting side and this
799
+ // input picked up the id from differently-cased sources.
800
+ if (UUIDsEqual(data.artifactId, this.artifactId)) {
727
801
  // Reload all versions to get any new ones
728
802
  await this.loadArtifact(data.versionNumber);
729
803
  }
@@ -749,6 +823,14 @@ export class ArtifactViewerPanelComponent extends BaseAngularComponent {
749
823
  // Reload artifact when artifactId changes
750
824
  if (changes['artifactId'] && !changes['artifactId'].firstChange) {
751
825
  await this.loadArtifact(this.versionNumber);
826
+ // `loadArtifact` already honored the (possibly also-changed) versionNumber, so the branch
827
+ // below has nothing left to do. Angular delivers both inputs in ONE SimpleChanges when a
828
+ // caller switches artifact and version together, and these are two independent `if`s: the
829
+ // version branch used to find the version `loadArtifact` had just loaded sitting in the
830
+ // freshly populated `allVersions` and load its content, attributes, collections and links a
831
+ // second time — roughly six redundant round trips per open, including a second full content
832
+ // download, none of them cancellable by a later load.
833
+ return;
752
834
  }
753
835
  // Switch to new version when versionNumber changes (but artifactId stays the same)
754
836
  if (changes['versionNumber'] && !changes['versionNumber'].firstChange) {
@@ -794,6 +876,8 @@ export class ArtifactViewerPanelComponent extends BaseAngularComponent {
794
876
  this.jsonContent = '';
795
877
  this.displayMarkdown = null;
796
878
  this.displayHtml = null;
879
+ this.fallbackText = null;
880
+ this.fallbackTextTruncated = false;
797
881
  this.artifactCollections = [];
798
882
  this.currentVersionCollections = [];
799
883
  this.primaryCollection = null;
@@ -995,6 +1079,7 @@ export class ArtifactViewerPanelComponent extends BaseAngularComponent {
995
1079
  // Set active tab to the first available tab
996
1080
  this.setActiveTabToFirstAvailable();
997
1081
  }
1082
+ await this.prepareNoPluginFallback(isCurrentLoad);
998
1083
  }
999
1084
  catch (err) {
1000
1085
  if (!isCurrentLoad()) {
@@ -1031,6 +1116,115 @@ export class ArtifactViewerPanelComponent extends BaseAngularComponent {
1031
1116
  const pluginHasContent = this.pluginViewer?.pluginInstance?.hasDisplayContent ?? false;
1032
1117
  return pluginHasContent || !!this.displayMarkdown || !!this.displayHtml;
1033
1118
  }
1119
+ /** True when the display tab has nothing better than the file card to show. */
1120
+ get showFileFallback() {
1121
+ return !this.hasPlugin && !!this.artifactVersion && !this.displayMarkdown && !this.displayHtml;
1122
+ }
1123
+ /** The file name shown on the fallback card. */
1124
+ get fallbackFileName() {
1125
+ return this.artifactVersion?.FileName || this.artifact?.Name || 'file';
1126
+ }
1127
+ /** Human file size for the fallback card, when the version knows it. */
1128
+ get fallbackSize() {
1129
+ const content = this.artifactVersion?.Content;
1130
+ if (this.artifactVersion?.ContentMode === 'Text' && content?.startsWith('data:')) {
1131
+ const b64 = content.slice(content.indexOf(',') + 1);
1132
+ return this.formatBytes(Math.floor((b64.length * 3) / 4));
1133
+ }
1134
+ return null;
1135
+ }
1136
+ /** Text-like MIME types are shown inline on the fallback card; everything else is download-only. */
1137
+ isTextLike(mime) {
1138
+ const m = (mime ?? '').toLowerCase();
1139
+ return m.startsWith('text/') || m === 'application/json' || m === 'application/xml' || m === 'application/csv';
1140
+ }
1141
+ /**
1142
+ * Fetch text-like content for the no-plugin fallback. File-backed: MJ's pre-authenticated URL;
1143
+ * inline: the data URL. Silent on failure — the Download action still works.
1144
+ */
1145
+ async prepareNoPluginFallback(isCurrentLoad) {
1146
+ this.fallbackText = null;
1147
+ this.fallbackTextTruncated = false;
1148
+ const version = this.artifactVersion;
1149
+ if (!this.showFileFallback || !version || !this.isTextLike(version.MimeType))
1150
+ return;
1151
+ try {
1152
+ let text = null;
1153
+ if (version.ContentMode === 'File') {
1154
+ const url = await this.artifactFileService.getDownloadUrl(version.ID);
1155
+ const res = await fetch(url);
1156
+ if (res.ok)
1157
+ text = await res.text();
1158
+ }
1159
+ else if (version.Content?.startsWith('data:')) {
1160
+ text = new TextDecoder().decode(this.artifactFileService.dataUrlToArrayBuffer(version.Content));
1161
+ }
1162
+ else if (typeof version.Content === 'string') {
1163
+ text = version.Content;
1164
+ }
1165
+ if (!isCurrentLoad() || text == null)
1166
+ return;
1167
+ if (text.length > ArtifactViewerPanelComponent.FALLBACK_TEXT_MAX_CHARS) {
1168
+ text = text.slice(0, ArtifactViewerPanelComponent.FALLBACK_TEXT_MAX_CHARS);
1169
+ this.fallbackTextTruncated = true;
1170
+ }
1171
+ this.fallbackText = text;
1172
+ this.cdr.markForCheck();
1173
+ }
1174
+ catch (err) {
1175
+ LogError(`Artifact viewer: could not load text for the no-plugin fallback: ${err instanceof Error ? err.message : String(err)}`);
1176
+ }
1177
+ }
1178
+ /** Download the artifact's file: file-backed via MJ's URL (fetched to a blob so the browser saves it), inline via the data URL. */
1179
+ async downloadArtifactFile() {
1180
+ const version = this.artifactVersion;
1181
+ if (!version || this.fallbackBusy)
1182
+ return;
1183
+ this.fallbackBusy = true;
1184
+ try {
1185
+ let objectUrl = null;
1186
+ if (version.ContentMode === 'File') {
1187
+ const url = await this.artifactFileService.getDownloadUrl(version.ID);
1188
+ try {
1189
+ const res = await fetch(url);
1190
+ if (!res.ok)
1191
+ throw new Error(`HTTP ${res.status}`);
1192
+ objectUrl = URL.createObjectURL(await res.blob());
1193
+ }
1194
+ catch {
1195
+ window.open(url, '_blank', 'noopener'); // storage refused the cross-origin fetch — let the browser handle it
1196
+ return;
1197
+ }
1198
+ }
1199
+ else if (version.Content?.startsWith('data:')) {
1200
+ objectUrl = this.artifactFileService.dataUrlToObjectUrl(version.Content, version.MimeType || 'application/octet-stream');
1201
+ }
1202
+ else if (typeof version.Content === 'string') {
1203
+ objectUrl = URL.createObjectURL(new Blob([version.Content], { type: version.MimeType || 'text/plain' }));
1204
+ }
1205
+ if (!objectUrl)
1206
+ return;
1207
+ const a = document.createElement('a');
1208
+ a.href = objectUrl;
1209
+ a.download = this.fallbackFileName;
1210
+ a.rel = 'noopener';
1211
+ document.body.appendChild(a);
1212
+ a.click();
1213
+ a.remove();
1214
+ setTimeout(() => URL.revokeObjectURL(objectUrl), 60_000);
1215
+ }
1216
+ finally {
1217
+ this.fallbackBusy = false;
1218
+ this.cdr.markForCheck();
1219
+ }
1220
+ }
1221
+ formatBytes(n) {
1222
+ if (n < 1024)
1223
+ return `${n} B`;
1224
+ if (n < 1024 * 1024)
1225
+ return `${(n / 1024).toFixed(1)} KB`;
1226
+ return `${(n / (1024 * 1024)).toFixed(1)} MB`;
1227
+ }
1034
1228
  get hasPlugin() {
1035
1229
  // Check if the artifact type has a DriverClass configured
1036
1230
  // If DriverClass is set, we have a plugin available
@@ -1758,13 +1952,13 @@ export class ArtifactViewerPanelComponent extends BaseAngularComponent {
1758
1952
  GetCurrentStateSnapshot() {
1759
1953
  return this.pluginViewer?.pluginInstance?.GetCurrentStateSnapshot() ?? null;
1760
1954
  }
1761
- static ɵfac = function ArtifactViewerPanelComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || ArtifactViewerPanelComponent)(i0.ɵɵdirectiveInject(i0.ChangeDetectorRef), i0.ɵɵdirectiveInject(i1.MJNotificationService), i0.ɵɵdirectiveInject(i2.DomSanitizer), i0.ɵɵdirectiveInject(i3.ArtifactIconService)); };
1955
+ static ɵfac = function ArtifactViewerPanelComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || ArtifactViewerPanelComponent)(i0.ɵɵdirectiveInject(i0.ChangeDetectorRef), i0.ɵɵdirectiveInject(i1.MJNotificationService), i0.ɵɵdirectiveInject(i2.DomSanitizer), i0.ɵɵdirectiveInject(i3.ArtifactIconService), i0.ɵɵdirectiveInject(i4.ArtifactFileService)); };
1762
1956
  static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ArtifactViewerPanelComponent, selectors: [["mj-artifact-viewer-panel"]], viewQuery: function ArtifactViewerPanelComponent_Query(rf, ctx) { if (rf & 1) {
1763
1957
  i0.ɵɵviewQuery(ArtifactTypePluginViewerComponent, 5);
1764
1958
  } if (rf & 2) {
1765
1959
  let _t;
1766
1960
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.pluginViewer = _t.first);
1767
- } }, inputs: { artifactId: "artifactId", currentUser: "currentUser", environmentId: "environmentId", versionNumber: "versionNumber", showSaveToCollection: "showSaveToCollection", showHeader: "showHeader", showTabs: "showTabs", showCloseButton: "showCloseButton", showMaximizeButton: "showMaximizeButton", refreshTrigger: "refreshTrigger", viewContext: "viewContext", contextCollectionId: "contextCollectionId", canShare: "canShare", canEdit: "canEdit", isMaximized: "isMaximized" }, outputs: { closed: "closed", saveToCollectionRequested: "saveToCollectionRequested", navigateToLink: "navigateToLink", shareRequested: "shareRequested", maximizeToggled: "maximizeToggled", openEntityRecord: "openEntityRecord", navigationRequest: "navigationRequest", analyzeRequested: "analyzeRequested", applyFormRequested: "applyFormRequested" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature, i0.ɵɵNgOnChangesFeature], decls: 6, vars: 6, consts: [[1, "artifact-viewer-panel"], [1, "panel-header"], [1, "panel-content"], [1, "loading-state"], ["Variant", "error", "Icon", "fa-solid fa-triangle-exclamation", "Title", "Couldn't load artifact", "Size", "compact", 3, "Message"], [1, "artifact-content-wrapper", 3, "no-tabs"], [1, "panel-header-left"], [1, "fas", 3, "ngClass"], [1, "header-description"], [1, "panel-header-right"], [1, "version-selector", 3, "click"], [1, "fas", "fa-history"], [1, "version-label"], [1, "fas", "fa-chevron-down", "dropdown-icon", 3, "open"], [1, "version-dropdown"], ["title", "Inspect & rate components", 1, "feedback-btn"], [1, "save-to-collection-btn", 3, "in-collection", "title"], ["title", "Share", 1, "share-btn"], ["title", "Analyze this artifact with AI", 1, "analyze-btn", 3, "click"], [1, "fas", "fa-magnifying-glass-chart"], [1, "maximize-btn", 3, "title"], ["title", "Close", 1, "close-btn"], [1, "fas", "fa-chevron-down", "dropdown-icon"], [1, "version-dropdown", 3, "click"], [1, "version-option", 3, "selected"], [1, "version-option", 3, "click"], [1, "version-number"], [1, "version-date"], [1, "fas", "fa-check"], ["title", "Inspect & rate components", 1, "feedback-btn", 3, "click"], [1, "fas", "fa-star-half-stroke"], [1, "save-to-collection-btn", 3, "click", "title"], ["title", "Share", 1, "share-btn", 3, "click"], [1, "fas", "fa-share-nodes"], [1, "maximize-btn", 3, "click", "title"], ["title", "Close", 1, "close-btn", 3, "click"], [1, "fas", "fa-times"], [1, "fas", "fa-spinner", "fa-spin"], [1, "artifact-content-wrapper"], [1, "tab-navigation"], [1, "tab-content"], [1, "plugin-container", 3, "plugin-hidden"], [1, "display-content"], [1, "details-content"], [1, "artifact-meta"], [1, "meta-item"], [1, "meta-item", "full-width"], [1, "attributes-section"], [1, "links-container"], [1, "links-section"], ["Icon", "fa-solid fa-link", "Title", "No links available", "Size", "compact"], [1, "tab-btn", 3, "active"], [1, "tab-btn", 3, "click"], [3, "class"], [1, "plugin-container"], [3, "openEntityRecord", "navigationRequest", "pluginLoaded", "tabsChanged", "applyFormRequested", "artifactVersion", "artifactTypeName", "contentType", "readonly"], [1, "display-toolbar"], ["title", "Print", 1, "btn-icon", 3, "click"], [1, "fas", "fa-print"], ["title", "Copy Content", 1, "btn-icon", 3, "click"], [1, "fas", "fa-copy"], [1, "markdown-content"], [1, "html-content", 3, "innerHTML"], [3, "data", "enableCollapsibleHeadings", "enableLineNumbers", "enableSmartypants", "enableHtml"], [1, "attributes-list"], [1, "attribute-item"], [1, "attribute-empty-pill"], [1, "link-item", 3, "disabled", "clickable", "title"], [1, "link-item", 3, "click", "title"], [1, "link-icon"], [1, "fas", "fa-comments"], [1, "fas", "fa-folder"], [1, "link-content"], [1, "link-name"], [1, "link-type"], [1, "link-actions"], [1, "fas", "fa-arrow-right"], [1, "component-tab-content"], [4, "ngComponentOutlet", "ngComponentOutletInputs"], [1, "dynamic-tab-content"], [1, "markdown-viewer"], [1, "json-viewer"], [1, "code-viewer"], [1, "html-viewer", 3, "innerHTML"], [1, "plaintext-viewer"], [1, "json-toolbar"], ["title", "Copy JSON", 1, "btn-icon", 3, "click"], [1, "json-editor-container"], [2, "width", "100%", "height", "100%", 3, "value", "language", "readonly", "lineWrapping"], [1, "code-toolbar"], ["title", "Copy Code", 1, "btn-icon", 3, "click"], [1, "code-editor-container"]], template: function ArtifactViewerPanelComponent_Template(rf, ctx) { if (rf & 1) {
1961
+ } }, inputs: { artifactId: "artifactId", currentUser: "currentUser", environmentId: "environmentId", versionNumber: "versionNumber", showSaveToCollection: "showSaveToCollection", showHeader: "showHeader", showTabs: "showTabs", showCloseButton: "showCloseButton", showMaximizeButton: "showMaximizeButton", refreshTrigger: "refreshTrigger", viewContext: "viewContext", contextCollectionId: "contextCollectionId", canShare: "canShare", canEdit: "canEdit", isMaximized: "isMaximized" }, outputs: { closed: "closed", saveToCollectionRequested: "saveToCollectionRequested", navigateToLink: "navigateToLink", shareRequested: "shareRequested", maximizeToggled: "maximizeToggled", openEntityRecord: "openEntityRecord", navigationRequest: "navigationRequest", analyzeRequested: "analyzeRequested", applyFormRequested: "applyFormRequested" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature, i0.ɵɵNgOnChangesFeature], decls: 6, vars: 6, consts: [[1, "artifact-viewer-panel"], [1, "panel-header"], [1, "panel-content"], [1, "loading-state"], ["Variant", "error", "Icon", "fa-solid fa-triangle-exclamation", "Title", "Couldn't load artifact", "Size", "compact", 3, "Message"], [1, "artifact-content-wrapper", 3, "no-tabs"], [1, "panel-header-left"], [1, "fas", 3, "ngClass"], [1, "header-description"], [1, "panel-header-right"], [1, "version-selector", 3, "click"], [1, "fas", "fa-history"], [1, "version-label"], [1, "fas", "fa-chevron-down", "dropdown-icon", 3, "open"], [1, "version-dropdown"], ["title", "Inspect & rate components", 1, "feedback-btn"], [1, "save-to-collection-btn", 3, "in-collection", "title"], ["title", "Share", 1, "share-btn"], ["title", "Analyze this artifact with AI", 1, "analyze-btn", 3, "click"], [1, "fas", "fa-magnifying-glass-chart"], [1, "maximize-btn", 3, "title"], ["title", "Close", 1, "close-btn"], [1, "fas", "fa-chevron-down", "dropdown-icon"], [1, "version-dropdown", 3, "click"], [1, "version-option", 3, "selected"], [1, "version-option", 3, "click"], [1, "version-number"], [1, "version-date"], [1, "fas", "fa-check"], ["title", "Inspect & rate components", 1, "feedback-btn", 3, "click"], [1, "fas", "fa-star-half-stroke"], [1, "save-to-collection-btn", 3, "click", "title"], ["title", "Share", 1, "share-btn", 3, "click"], [1, "fas", "fa-share-nodes"], [1, "maximize-btn", 3, "click", "title"], ["title", "Close", 1, "close-btn", 3, "click"], [1, "fas", "fa-times"], [1, "fas", "fa-spinner", "fa-spin"], [1, "artifact-content-wrapper"], [1, "tab-navigation"], [1, "tab-content"], [1, "plugin-container", 3, "plugin-hidden"], [1, "display-content"], [1, "details-content"], [1, "artifact-meta"], [1, "meta-item"], [1, "meta-item", "full-width"], [1, "attributes-section"], [1, "links-container"], [1, "links-section"], ["Icon", "fa-solid fa-link", "Title", "No links available", "Size", "compact"], [1, "tab-btn", 3, "active"], [1, "tab-btn", 3, "click"], [3, "class"], [1, "plugin-container"], [3, "openEntityRecord", "navigationRequest", "pluginLoaded", "tabsChanged", "applyFormRequested", "artifactVersion", "artifactTypeName", "contentType", "readonly"], ["data-testid", "file-fallback", 1, "file-fallback"], [1, "display-toolbar"], ["title", "Print", 1, "btn-icon", 3, "click"], [1, "fas", "fa-print"], ["title", "Copy Content", 1, "btn-icon", 3, "click"], [1, "fas", "fa-copy"], [1, "markdown-content"], [1, "html-content", 3, "innerHTML"], [3, "data", "enableCollapsibleHeadings", "enableLineNumbers", "enableSmartypants", "enableHtml"], [1, "file-fallback-card"], ["aria-hidden", "true", 1, "fas", 3, "ngClass"], [1, "file-fallback-meta"], [1, "file-fallback-name"], [1, "file-fallback-sub"], ["type", "button", "title", "Download", 1, "btn-icon", "btn-primary", 3, "click", "disabled"], [1, "fas", "fa-download"], [1, "plaintext-viewer", "file-fallback-text"], [1, "attributes-list"], [1, "attribute-item"], [1, "attribute-empty-pill"], [1, "link-item", 3, "disabled", "clickable", "title"], [1, "link-item", 3, "click", "title"], [1, "link-icon"], [1, "fas", "fa-comments"], [1, "fas", "fa-folder"], [1, "link-content"], [1, "link-name"], [1, "link-type"], [1, "link-actions"], [1, "fas", "fa-arrow-right"], [1, "component-tab-content"], [4, "ngComponentOutlet", "ngComponentOutletInputs"], [1, "dynamic-tab-content"], [1, "markdown-viewer"], [1, "json-viewer"], [1, "code-viewer"], [1, "html-viewer", 3, "innerHTML"], [1, "plaintext-viewer"], [1, "json-toolbar"], ["title", "Copy JSON", 1, "btn-icon", 3, "click"], [1, "json-editor-container"], [2, "width", "100%", "height", "100%", 3, "value", "language", "readonly", "lineWrapping"], [1, "code-toolbar"], ["title", "Copy Code", 1, "btn-icon", 3, "click"], [1, "code-editor-container"]], template: function ArtifactViewerPanelComponent_Template(rf, ctx) { if (rf & 1) {
1768
1962
  i0.ɵɵelementStart(0, "div", 0);
1769
1963
  i0.ɵɵconditionalCreate(1, ArtifactViewerPanelComponent_Conditional_1_Template, 20, 13, "div", 1);
1770
1964
  i0.ɵɵelementStart(2, "div", 2);
@@ -1782,12 +1976,12 @@ export class ArtifactViewerPanelComponent extends BaseAngularComponent {
1782
1976
  i0.ɵɵconditional(ctx.error ? 4 : -1);
1783
1977
  i0.ɵɵadvance();
1784
1978
  i0.ɵɵconditional(!ctx.isLoading && !ctx.error && ctx.artifact ? 5 : -1);
1785
- } }, dependencies: [i4.NgClass, i4.NgComponentOutlet, i5.MarkdownComponent, i6.CodeEditorComponent, i7.MJEmptyStateComponent, i8.ArtifactTypePluginViewerComponent, i4.DatePipe], styles: [".artifact-viewer-panel[_ngcontent-%COMP%] {\n width: 100%;\n height: 100%;\n background: var(--mj-bg-surface);\n border-left: 1px solid var(--mj-border-default);\n display: flex;\n flex-direction: column;\n overflow: hidden;\n box-sizing: border-box;\n}\n\n.panel-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n padding: 12px 16px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n flex-shrink: 0;\n width: 100%;\n box-sizing: border-box;\n}\n\n.panel-header-left[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n margin-right: 16px;\n}\n\n.panel-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 14px;\n font-weight: 600;\n display: flex;\n align-items: flex-start;\n gap: 8px;\n word-wrap: break-word;\n overflow-wrap: break-word;\n}\n\n.panel-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n flex-shrink: 0;\n margin-top: 2px;\n}\n\n.header-description[_ngcontent-%COMP%] {\n margin: 4px 0 0 0;\n font-size: 12px;\n color: var(--mj-text-muted);\n font-weight: normal;\n word-wrap: break-word;\n overflow-wrap: break-word;\n}\n\n.panel-header-right[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-shrink: 0;\n}\n\n.version-selector[_ngcontent-%COMP%] {\n position: relative;\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 12px;\n font-size: 12px;\n color: var(--mj-text-muted);\n font-weight: 500;\n transition: all 0.2s;\n}\n\n.version-selector.clickable[_ngcontent-%COMP%] {\n cursor: pointer;\n}\n\n.version-selector.clickable[_ngcontent-%COMP%]:hover {\n background: var(--mj-border-default);\n}\n\n.version-selector[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 11px;\n}\n\n.version-selector[_ngcontent-%COMP%] .dropdown-icon[_ngcontent-%COMP%] {\n margin-left: 2px;\n transition: transform 0.2s;\n}\n\n.version-selector[_ngcontent-%COMP%] .dropdown-icon.open[_ngcontent-%COMP%] {\n transform: rotate(180deg);\n}\n\n.version-label[_ngcontent-%COMP%] {\n font-family: monospace;\n}\n\n.version-dropdown[_ngcontent-%COMP%] {\n position: absolute;\n top: calc(100% + 4px);\n right: 0;\n min-width: 200px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n box-shadow: var(--mj-shadow-md);\n z-index: 1000;\n overflow: hidden;\n}\n\n.version-option[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 12px;\n cursor: pointer;\n transition: background 0.15s;\n font-size: 13px;\n}\n\n.version-option[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.version-option.selected[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.version-option[_ngcontent-%COMP%] .version-number[_ngcontent-%COMP%] {\n font-family: monospace;\n font-weight: 600;\n min-width: 35px;\n}\n\n.version-option[_ngcontent-%COMP%] .version-date[_ngcontent-%COMP%] {\n flex: 1;\n color: var(--mj-text-muted);\n font-size: 12px;\n}\n\n.version-option[_ngcontent-%COMP%] i.fa-check[_ngcontent-%COMP%] {\n color: var(--mj-status-success);\n margin-left: auto;\n}\n\n.feedback-btn[_ngcontent-%COMP%] {\n background: none;\n border: none;\n cursor: pointer;\n color: var(--mj-text-disabled);\n padding: 6px;\n border-radius: 4px;\n transition: all 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n}\n\n.feedback-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-brand-primary);\n}\n\n.feedback-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.save-to-collection-btn[_ngcontent-%COMP%] {\n background: none;\n border: none;\n cursor: pointer;\n color: var(--mj-text-disabled);\n padding: 6px;\n border-radius: 4px;\n transition: all 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n}\n\n.save-to-collection-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n}\n\n.save-to-collection-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.save-to-collection-btn.in-collection[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.save-to-collection-btn.in-collection[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.share-btn[_ngcontent-%COMP%] {\n background: none;\n border: none;\n cursor: pointer;\n color: var(--mj-text-disabled);\n padding: 6px;\n border-radius: 4px;\n transition: all 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n}\n\n.share-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-brand-primary);\n}\n\n.share-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.analyze-btn[_ngcontent-%COMP%] {\n background: none;\n border: none;\n cursor: pointer;\n color: var(--mj-text-disabled);\n padding: 6px;\n border-radius: 4px;\n transition: all 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.analyze-btn[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.analyze-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.maximize-btn[_ngcontent-%COMP%] {\n background: none;\n border: none;\n cursor: pointer;\n color: var(--mj-text-muted);\n padding: 6px;\n border-radius: 4px;\n transition: all 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n}\n\n.maximize-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n}\n\n.maximize-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.close-btn[_ngcontent-%COMP%] {\n background: none;\n border: none;\n cursor: pointer;\n color: var(--mj-text-muted);\n padding: 6px;\n border-radius: 4px;\n transition: all 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n}\n\n.close-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n}\n\n.close-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.panel-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow: hidden;\n min-height: 0;\n display: flex;\n flex-direction: column;\n width: 100%;\n box-sizing: border-box;\n}\n\n.artifact-content-wrapper[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n min-height: 0;\n width: 100%;\n box-sizing: border-box;\n}\n\n.loading-state[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 12px;\n padding: 40px 20px;\n color: var(--mj-text-muted);\n}\n\n.loading-state[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 24px;\n}\n\n.artifact-meta[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));\n gap: 16px;\n margin-bottom: 16px;\n padding: 16px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 8px;\n flex-shrink: 0;\n}\n\n.meta-item[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.meta-item[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.meta-item[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--mj-text-primary);\n}\n\n.artifact-description[_ngcontent-%COMP%] {\n padding: 12px;\n margin-bottom: 16px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-left: 3px solid var(--mj-brand-primary);\n border-radius: 4px;\n color: var(--mj-brand-primary);\n font-size: 14px;\n flex-shrink: 0;\n}\n\n.json-viewer[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n overflow: hidden;\n min-height: 0;\n}\n\n.json-editor-container[_ngcontent-%COMP%] {\n flex: 1;\n overflow: hidden;\n min-height: 0;\n}\n\n.json-toolbar[_ngcontent-%COMP%] {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n padding: 8px 12px;\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.btn-icon[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong);\n border-radius: 4px;\n padding: 6px 12px;\n cursor: pointer;\n color: var(--mj-text-secondary);\n font-size: 14px;\n transition: all 0.2s;\n}\n\n.btn-icon[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-text-disabled);\n}\n\n.btn-icon.btn-primary[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.btn-icon.btn-primary[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary-hover);\n border-color: var(--mj-brand-primary-hover);\n}\n\n.btn-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n\n\n.modal-overlay[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: var(--mj-bg-overlay);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 10000;\n}\n\n.modal-content[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: var(--mj-shadow-lg);\n max-width: 500px;\n width: 90%;\n max-height: 90vh;\n display: flex;\n flex-direction: column;\n}\n\n.modal-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.modal-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.modal-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-warning);\n}\n\n.modal-body[_ngcontent-%COMP%] {\n padding: 20px;\n overflow-y: auto;\n}\n\n.modal-footer[_ngcontent-%COMP%] {\n display: flex;\n justify-content: flex-end;\n gap: 12px;\n padding: 16px 20px;\n border-top: 1px solid var(--mj-border-default);\n}\n\n.form-section[_ngcontent-%COMP%] {\n margin-bottom: 20px;\n}\n\n.form-section[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n display: block;\n margin-bottom: 8px;\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n}\n\n.form-select[_ngcontent-%COMP%], \n.form-input[_ngcontent-%COMP%] {\n width: 100%;\n padding: 10px 12px;\n border: 1px solid var(--mj-border-strong);\n border-radius: 6px;\n font-size: 14px;\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n transition: border-color 0.2s;\n}\n\n.form-select[_ngcontent-%COMP%]:focus, \n.form-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.divider[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n margin: 24px 0;\n color: var(--mj-text-disabled);\n font-size: 12px;\n font-weight: 500;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.divider[_ngcontent-%COMP%]::before, \n.divider[_ngcontent-%COMP%]::after {\n content: '';\n flex: 1;\n height: 1px;\n background: var(--mj-border-default);\n}\n\n.divider[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n padding: 0 12px;\n}\n\n.create-collection-row[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n}\n\n.create-collection-row[_ngcontent-%COMP%] .form-input[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n.btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 16px;\n border: none;\n border-radius: 6px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s;\n white-space: nowrap;\n}\n\n.btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.btn-primary[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.btn-primary[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n}\n\n.btn-secondary[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong);\n color: var(--mj-text-secondary);\n}\n\n.btn-secondary[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-bg-surface-sunken);\n}\n\n\n\n.tab-navigation[_ngcontent-%COMP%] {\n display: flex;\n gap: 0;\n border-bottom: 2px solid var(--mj-border-default);\n padding: 0 16px;\n background: var(--mj-bg-surface);\n}\n\n.tab-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 12px 20px;\n background: transparent;\n border: none;\n border-bottom: 2px solid transparent;\n margin-bottom: -2px;\n color: var(--mj-text-muted);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 150ms ease;\n}\n\n.tab-btn[_ngcontent-%COMP%]:hover {\n color: var(--mj-brand-primary);\n background: var(--mj-bg-surface-sunken);\n}\n\n.tab-btn.active[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n border-bottom-color: var(--mj-brand-primary);\n}\n\n.tab-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n\n\n.tab-content[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow: auto;\n width: 100%;\n box-sizing: border-box;\n margin-bottom: 5px;\n min-width: 0;\n min-height: 0;\n}\n\n\n\n.plugin-container[_ngcontent-%COMP%] {\n width: 100%;\n height: 100%;\n min-height: 0;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n.plugin-container.plugin-hidden[_ngcontent-%COMP%], \n.tab-hidden[_ngcontent-%COMP%] {\n display: none;\n}\n\n\n\n.plugin-container[_ngcontent-%COMP%] mj-artifact-type-plugin-viewer[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n flex: 1;\n min-height: 0;\n width: 100%;\n}\n\n.display-content[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n position: relative;\n width: 100%;\n box-sizing: border-box;\n overflow: hidden;\n min-height: 0;\n min-width: 0;\n padding: 7px;\n}\n\n.display-toolbar[_ngcontent-%COMP%] {\n position: absolute;\n top: 12px;\n right: 12px;\n display: flex;\n gap: 8px;\n z-index: 10;\n}\n\n.markdown-content[_ngcontent-%COMP%], \n.html-content[_ngcontent-%COMP%] {\n flex: 1;\n font-size: 14px;\n line-height: 1.6;\n width: 100%;\n padding: 20px 10px 5px 20px; \n\n box-sizing: border-box;\n overflow: auto;\n min-height: 0;\n}\n\n.details-content[_ngcontent-%COMP%] {\n padding: 20px;\n width: 100%;\n box-sizing: border-box;\n}\n\n.details-content[_ngcontent-%COMP%] .artifact-meta[_ngcontent-%COMP%] {\n margin-bottom: 0;\n padding: 20px;\n}\n\n.details-content[_ngcontent-%COMP%] .meta-item.full-width[_ngcontent-%COMP%] {\n grid-column: 1 / -1;\n}\n\n.attributes-section[_ngcontent-%COMP%] {\n margin-top: 24px;\n padding: 24px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 8px;\n}\n\n.attributes-section[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] {\n margin: 0 0 16px 0;\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.attributes-list[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));\n gap: 16px;\n}\n\n.attribute-item[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n padding: 12px;\n background: var(--mj-bg-surface);\n border-radius: 6px;\n border: 1px solid var(--mj-border-default);\n}\n\n.attribute-item[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.attribute-item[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-size: 13px;\n color: var(--mj-text-primary);\n word-break: break-word;\n}\n\n.attribute-empty-pill[_ngcontent-%COMP%] {\n display: inline-block;\n padding: 2px 8px;\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-disabled);\n font-size: 11px;\n font-weight: 500;\n border-radius: 4px;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n\n\n.links-container[_ngcontent-%COMP%] {\n padding: 20px;\n}\n\n.links-section[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.link-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n transition: all 0.15s;\n}\n\n.link-item.clickable[_ngcontent-%COMP%] {\n cursor: pointer;\n}\n\n.link-item.clickable[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n box-shadow: var(--mj-shadow-sm);\n background: var(--mj-bg-surface-sunken);\n}\n\n.link-item.disabled[_ngcontent-%COMP%] {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.link-item[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n box-shadow: var(--mj-shadow-sm);\n}\n\n.link-icon[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--mj-bg-surface);\n border-radius: 8px;\n flex-shrink: 0;\n}\n\n.link-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 18px;\n color: var(--mj-brand-primary);\n}\n\n.link-content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.link-name[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.link-type[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-muted);\n margin-top: 2px;\n}\n\n.link-actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 24px;\n height: 24px;\n flex-shrink: 0;\n}\n\n.link-actions[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--mj-text-muted);\n transition: all 0.15s;\n}\n\n.link-item.clickable[_ngcontent-%COMP%]:hover .link-actions[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n transform: translateX(2px);\n}\n\n\n\n.dynamic-tab-content[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n padding: 16px;\n}\n\n\n\n.component-tab-content[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow: auto;\n padding: 16px;\n}\n\n.markdown-viewer[_ngcontent-%COMP%] {\n flex: 1;\n overflow: auto;\n padding: 20px;\n background: var(--mj-bg-surface);\n line-height: 1.6;\n}\n\n.markdown-viewer[_ngcontent-%COMP%] h1[_ngcontent-%COMP%], .markdown-viewer[_ngcontent-%COMP%] h2[_ngcontent-%COMP%], .markdown-viewer[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin-top: 24px;\n margin-bottom: 12px;\n font-weight: 600;\n}\n\n.markdown-viewer[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] { font-size: 24px; }\n.markdown-viewer[_ngcontent-%COMP%] h2[_ngcontent-%COMP%] { font-size: 20px; }\n.markdown-viewer[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] { font-size: 18px; }\n\n.markdown-viewer[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin-bottom: 12px;\n}\n\n.markdown-viewer[_ngcontent-%COMP%] ul[_ngcontent-%COMP%], .markdown-viewer[_ngcontent-%COMP%] ol[_ngcontent-%COMP%] {\n margin-bottom: 12px;\n padding-left: 24px;\n}\n\n.markdown-viewer[_ngcontent-%COMP%] code[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n padding: 2px 6px;\n border-radius: 3px;\n font-family: 'Courier New', monospace;\n font-size: 13px;\n}\n\n.markdown-viewer[_ngcontent-%COMP%] pre[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n padding: 12px;\n border-radius: 6px;\n overflow-x: auto;\n margin-bottom: 12px;\n}\n\n.markdown-viewer[_ngcontent-%COMP%] pre[_ngcontent-%COMP%] code[_ngcontent-%COMP%] {\n background: none;\n padding: 0;\n}\n\n.code-viewer[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n overflow: hidden;\n min-height: 0;\n}\n\n.code-toolbar[_ngcontent-%COMP%] {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n padding: 8px 12px;\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.code-editor-container[_ngcontent-%COMP%] {\n flex: 1;\n overflow: hidden;\n min-height: 0;\n}\n\n.plaintext-viewer[_ngcontent-%COMP%] {\n flex: 1;\n overflow: auto;\n padding: 12px;\n background: var(--mj-bg-surface-sunken);\n font-family: 'Courier New', monospace;\n font-size: 13px;\n white-space: pre-wrap;\n}\n\n.html-viewer[_ngcontent-%COMP%] {\n flex: 1;\n overflow: auto;\n padding: 20px;\n background: var(--mj-bg-surface);\n}\n\n\n\n@media (max-width: 768px) {\n \n\n .artifact-viewer-panel[_ngcontent-%COMP%] {\n border-top: 3px solid var(--mj-brand-primary);\n position: relative;\n }\n\n \n\n .artifact-viewer-panel[_ngcontent-%COMP%]::before {\n content: '';\n position: absolute;\n top: -8px;\n left: 0;\n right: 0;\n height: 8px;\n background: var(--mj-brand-secondary);\n }\n\n .tab-navigation[_ngcontent-%COMP%] {\n padding: 0 8px;\n overflow-x: auto;\n overflow-y: hidden;\n -webkit-overflow-scrolling: touch;\n scrollbar-width: none;\n }\n\n .tab-navigation[_ngcontent-%COMP%]::-webkit-scrollbar {\n display: none;\n }\n\n .tab-btn[_ngcontent-%COMP%] {\n padding: 10px 12px;\n font-size: 12px;\n white-space: nowrap;\n flex-shrink: 0;\n }\n\n .tab-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 13px;\n }\n\n .panel-header[_ngcontent-%COMP%] {\n padding: 12px;\n }\n\n .dynamic-tab-content[_ngcontent-%COMP%] {\n padding: 12px;\n }\n\n .markdown-viewer[_ngcontent-%COMP%] {\n padding: 12px;\n }\n}\n\n\n\n@media (max-width: 480px) {\n .tab-navigation[_ngcontent-%COMP%] {\n padding: 0 4px;\n }\n\n .tab-btn[_ngcontent-%COMP%] {\n padding: 8px 10px;\n font-size: 11px;\n gap: 4px;\n }\n\n .tab-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n }\n\n .panel-header[_ngcontent-%COMP%] {\n padding: 8px;\n }\n\n .dynamic-tab-content[_ngcontent-%COMP%] {\n padding: 8px;\n }\n\n .markdown-viewer[_ngcontent-%COMP%] {\n padding: 8px;\n }\n}"] });
1979
+ } }, dependencies: [i5.NgClass, i5.NgComponentOutlet, i6.MarkdownComponent, i7.CodeEditorComponent, i8.MJEmptyStateComponent, i9.ArtifactTypePluginViewerComponent, i5.DatePipe], styles: [".artifact-viewer-panel[_ngcontent-%COMP%] {\n width: 100%;\n height: 100%;\n background: var(--mj-bg-surface);\n border-left: 1px solid var(--mj-border-default);\n display: flex;\n flex-direction: column;\n overflow: hidden;\n box-sizing: border-box;\n}\n\n.panel-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n padding: 12px 16px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n flex-shrink: 0;\n width: 100%;\n box-sizing: border-box;\n}\n\n.panel-header-left[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n margin-right: 16px;\n}\n\n.panel-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 14px;\n font-weight: 600;\n display: flex;\n align-items: flex-start;\n gap: 8px;\n word-wrap: break-word;\n overflow-wrap: break-word;\n}\n\n.panel-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n flex-shrink: 0;\n margin-top: 2px;\n}\n\n.header-description[_ngcontent-%COMP%] {\n margin: 4px 0 0 0;\n font-size: 12px;\n color: var(--mj-text-muted);\n font-weight: normal;\n word-wrap: break-word;\n overflow-wrap: break-word;\n}\n\n.panel-header-right[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-shrink: 0;\n}\n\n.version-selector[_ngcontent-%COMP%] {\n position: relative;\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 12px;\n font-size: 12px;\n color: var(--mj-text-muted);\n font-weight: 500;\n transition: all 0.2s;\n}\n\n.version-selector.clickable[_ngcontent-%COMP%] {\n cursor: pointer;\n}\n\n.version-selector.clickable[_ngcontent-%COMP%]:hover {\n background: var(--mj-border-default);\n}\n\n.version-selector[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 11px;\n}\n\n.version-selector[_ngcontent-%COMP%] .dropdown-icon[_ngcontent-%COMP%] {\n margin-left: 2px;\n transition: transform 0.2s;\n}\n\n.version-selector[_ngcontent-%COMP%] .dropdown-icon.open[_ngcontent-%COMP%] {\n transform: rotate(180deg);\n}\n\n.version-label[_ngcontent-%COMP%] {\n font-family: monospace;\n}\n\n.version-dropdown[_ngcontent-%COMP%] {\n position: absolute;\n top: calc(100% + 4px);\n right: 0;\n min-width: 200px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n box-shadow: var(--mj-shadow-md);\n z-index: 1000;\n overflow: hidden;\n}\n\n.version-option[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 12px;\n cursor: pointer;\n transition: background 0.15s;\n font-size: 13px;\n}\n\n.version-option[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.version-option.selected[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.version-option[_ngcontent-%COMP%] .version-number[_ngcontent-%COMP%] {\n font-family: monospace;\n font-weight: 600;\n min-width: 35px;\n}\n\n.version-option[_ngcontent-%COMP%] .version-date[_ngcontent-%COMP%] {\n flex: 1;\n color: var(--mj-text-muted);\n font-size: 12px;\n}\n\n.version-option[_ngcontent-%COMP%] i.fa-check[_ngcontent-%COMP%] {\n color: var(--mj-status-success);\n margin-left: auto;\n}\n\n.feedback-btn[_ngcontent-%COMP%] {\n background: none;\n border: none;\n cursor: pointer;\n color: var(--mj-text-disabled);\n padding: 6px;\n border-radius: 4px;\n transition: all 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n}\n\n.feedback-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-brand-primary);\n}\n\n.feedback-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.save-to-collection-btn[_ngcontent-%COMP%] {\n background: none;\n border: none;\n cursor: pointer;\n color: var(--mj-text-disabled);\n padding: 6px;\n border-radius: 4px;\n transition: all 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n}\n\n.save-to-collection-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n}\n\n.save-to-collection-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.save-to-collection-btn.in-collection[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.save-to-collection-btn.in-collection[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.share-btn[_ngcontent-%COMP%] {\n background: none;\n border: none;\n cursor: pointer;\n color: var(--mj-text-disabled);\n padding: 6px;\n border-radius: 4px;\n transition: all 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n}\n\n.share-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-brand-primary);\n}\n\n.share-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.analyze-btn[_ngcontent-%COMP%] {\n background: none;\n border: none;\n cursor: pointer;\n color: var(--mj-text-disabled);\n padding: 6px;\n border-radius: 4px;\n transition: all 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.analyze-btn[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.analyze-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.maximize-btn[_ngcontent-%COMP%] {\n background: none;\n border: none;\n cursor: pointer;\n color: var(--mj-text-muted);\n padding: 6px;\n border-radius: 4px;\n transition: all 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n}\n\n.maximize-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n}\n\n.maximize-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.close-btn[_ngcontent-%COMP%] {\n background: none;\n border: none;\n cursor: pointer;\n color: var(--mj-text-muted);\n padding: 6px;\n border-radius: 4px;\n transition: all 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n}\n\n.close-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n}\n\n.close-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.panel-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow: hidden;\n min-height: 0;\n display: flex;\n flex-direction: column;\n width: 100%;\n box-sizing: border-box;\n}\n\n.artifact-content-wrapper[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n min-height: 0;\n width: 100%;\n box-sizing: border-box;\n}\n\n.loading-state[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 12px;\n padding: 40px 20px;\n color: var(--mj-text-muted);\n}\n\n.loading-state[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 24px;\n}\n\n.artifact-meta[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));\n gap: 16px;\n margin-bottom: 16px;\n padding: 16px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 8px;\n flex-shrink: 0;\n}\n\n.meta-item[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.meta-item[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.meta-item[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--mj-text-primary);\n}\n\n.artifact-description[_ngcontent-%COMP%] {\n padding: 12px;\n margin-bottom: 16px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-left: 3px solid var(--mj-brand-primary);\n border-radius: 4px;\n color: var(--mj-brand-primary);\n font-size: 14px;\n flex-shrink: 0;\n}\n\n.json-viewer[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n overflow: hidden;\n min-height: 0;\n}\n\n.json-editor-container[_ngcontent-%COMP%] {\n flex: 1;\n overflow: hidden;\n min-height: 0;\n}\n\n.json-toolbar[_ngcontent-%COMP%] {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n padding: 8px 12px;\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.btn-icon[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong);\n border-radius: 4px;\n padding: 6px 12px;\n cursor: pointer;\n color: var(--mj-text-secondary);\n font-size: 14px;\n transition: all 0.2s;\n}\n\n.btn-icon[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-text-disabled);\n}\n\n.btn-icon.btn-primary[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.btn-icon.btn-primary[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary-hover);\n border-color: var(--mj-brand-primary-hover);\n}\n\n.btn-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n\n.modal-overlay[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: var(--mj-bg-overlay);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 10000;\n}\n\n.modal-content[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: var(--mj-shadow-lg);\n max-width: 500px;\n width: 90%;\n max-height: 90vh;\n display: flex;\n flex-direction: column;\n}\n\n.modal-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.modal-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.modal-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-warning);\n}\n\n.modal-body[_ngcontent-%COMP%] {\n padding: 20px;\n overflow-y: auto;\n}\n\n.modal-footer[_ngcontent-%COMP%] {\n display: flex;\n justify-content: flex-end;\n gap: 12px;\n padding: 16px 20px;\n border-top: 1px solid var(--mj-border-default);\n}\n\n.form-section[_ngcontent-%COMP%] {\n margin-bottom: 20px;\n}\n\n.form-section[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n display: block;\n margin-bottom: 8px;\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n}\n\n.form-select[_ngcontent-%COMP%], \n.form-input[_ngcontent-%COMP%] {\n width: 100%;\n padding: 10px 12px;\n border: 1px solid var(--mj-border-strong);\n border-radius: 6px;\n font-size: 14px;\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n transition: border-color 0.2s;\n}\n\n.form-select[_ngcontent-%COMP%]:focus, \n.form-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.divider[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n margin: 24px 0;\n color: var(--mj-text-disabled);\n font-size: 12px;\n font-weight: 500;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.divider[_ngcontent-%COMP%]::before, \n.divider[_ngcontent-%COMP%]::after {\n content: '';\n flex: 1;\n height: 1px;\n background: var(--mj-border-default);\n}\n\n.divider[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n padding: 0 12px;\n}\n\n.create-collection-row[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n}\n\n.create-collection-row[_ngcontent-%COMP%] .form-input[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n.btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 16px;\n border: none;\n border-radius: 6px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s;\n white-space: nowrap;\n}\n\n.btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.btn-primary[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.btn-primary[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n}\n\n.btn-secondary[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong);\n color: var(--mj-text-secondary);\n}\n\n.btn-secondary[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-bg-surface-sunken);\n}\n\n\n.tab-navigation[_ngcontent-%COMP%] {\n display: flex;\n gap: 0;\n border-bottom: 2px solid var(--mj-border-default);\n padding: 0 16px;\n background: var(--mj-bg-surface);\n}\n\n.tab-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 12px 20px;\n background: transparent;\n border: none;\n border-bottom: 2px solid transparent;\n margin-bottom: -2px;\n color: var(--mj-text-muted);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 150ms ease;\n}\n\n.tab-btn[_ngcontent-%COMP%]:hover {\n color: var(--mj-brand-primary);\n background: var(--mj-bg-surface-sunken);\n}\n\n.tab-btn.active[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n border-bottom-color: var(--mj-brand-primary);\n}\n\n.tab-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n\n.tab-content[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow: auto;\n width: 100%;\n box-sizing: border-box;\n margin-bottom: 5px;\n min-width: 0;\n min-height: 0;\n}\n\n\n.plugin-container[_ngcontent-%COMP%] {\n width: 100%;\n height: 100%;\n min-height: 0;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n.plugin-container.plugin-hidden[_ngcontent-%COMP%], \n.tab-hidden[_ngcontent-%COMP%] {\n display: none;\n}\n\n\n.plugin-container[_ngcontent-%COMP%] mj-artifact-type-plugin-viewer[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n flex: 1;\n min-height: 0;\n width: 100%;\n}\n\n.display-content[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n position: relative;\n width: 100%;\n box-sizing: border-box;\n overflow: hidden;\n min-height: 0;\n min-width: 0;\n padding: 7px;\n}\n\n.display-toolbar[_ngcontent-%COMP%] {\n position: absolute;\n top: 12px;\n right: 12px;\n display: flex;\n gap: 8px;\n z-index: 10;\n}\n\n.markdown-content[_ngcontent-%COMP%], \n.html-content[_ngcontent-%COMP%] {\n flex: 1;\n font-size: 14px;\n line-height: 1.6;\n width: 100%;\n padding: 20px 10px 5px 20px; \n box-sizing: border-box;\n overflow: auto;\n min-height: 0;\n}\n\n.details-content[_ngcontent-%COMP%] {\n padding: 20px;\n width: 100%;\n box-sizing: border-box;\n}\n\n.details-content[_ngcontent-%COMP%] .artifact-meta[_ngcontent-%COMP%] {\n margin-bottom: 0;\n padding: 20px;\n}\n\n.details-content[_ngcontent-%COMP%] .meta-item.full-width[_ngcontent-%COMP%] {\n grid-column: 1 / -1;\n}\n\n.attributes-section[_ngcontent-%COMP%] {\n margin-top: 24px;\n padding: 24px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 8px;\n}\n\n.attributes-section[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] {\n margin: 0 0 16px 0;\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.attributes-list[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));\n gap: 16px;\n}\n\n.attribute-item[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n padding: 12px;\n background: var(--mj-bg-surface);\n border-radius: 6px;\n border: 1px solid var(--mj-border-default);\n}\n\n.attribute-item[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.attribute-item[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-size: 13px;\n color: var(--mj-text-primary);\n word-break: break-word;\n}\n\n.attribute-empty-pill[_ngcontent-%COMP%] {\n display: inline-block;\n padding: 2px 8px;\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-disabled);\n font-size: 11px;\n font-weight: 500;\n border-radius: 4px;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n\n.links-container[_ngcontent-%COMP%] {\n padding: 20px;\n}\n\n.links-section[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.link-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n transition: all 0.15s;\n}\n\n.link-item.clickable[_ngcontent-%COMP%] {\n cursor: pointer;\n}\n\n.link-item.clickable[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n box-shadow: var(--mj-shadow-sm);\n background: var(--mj-bg-surface-sunken);\n}\n\n.link-item.disabled[_ngcontent-%COMP%] {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.link-item[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n box-shadow: var(--mj-shadow-sm);\n}\n\n.link-icon[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--mj-bg-surface);\n border-radius: 8px;\n flex-shrink: 0;\n}\n\n.link-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 18px;\n color: var(--mj-brand-primary);\n}\n\n.link-content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.link-name[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.link-type[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-muted);\n margin-top: 2px;\n}\n\n.link-actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 24px;\n height: 24px;\n flex-shrink: 0;\n}\n\n.link-actions[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--mj-text-muted);\n transition: all 0.15s;\n}\n\n.link-item.clickable[_ngcontent-%COMP%]:hover .link-actions[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n transform: translateX(2px);\n}\n\n\n.dynamic-tab-content[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n padding: 16px;\n}\n\n\n.component-tab-content[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow: auto;\n padding: 16px;\n}\n\n.markdown-viewer[_ngcontent-%COMP%] {\n flex: 1;\n overflow: auto;\n padding: 20px;\n background: var(--mj-bg-surface);\n line-height: 1.6;\n}\n\n.markdown-viewer[_ngcontent-%COMP%] h1[_ngcontent-%COMP%], .markdown-viewer[_ngcontent-%COMP%] h2[_ngcontent-%COMP%], .markdown-viewer[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin-top: 24px;\n margin-bottom: 12px;\n font-weight: 600;\n}\n\n.markdown-viewer[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] { font-size: 24px; }\n.markdown-viewer[_ngcontent-%COMP%] h2[_ngcontent-%COMP%] { font-size: 20px; }\n.markdown-viewer[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] { font-size: 18px; }\n\n.markdown-viewer[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin-bottom: 12px;\n}\n\n.markdown-viewer[_ngcontent-%COMP%] ul[_ngcontent-%COMP%], .markdown-viewer[_ngcontent-%COMP%] ol[_ngcontent-%COMP%] {\n margin-bottom: 12px;\n padding-left: 24px;\n}\n\n.markdown-viewer[_ngcontent-%COMP%] code[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n padding: 2px 6px;\n border-radius: 3px;\n font-family: 'Courier New', monospace;\n font-size: 13px;\n}\n\n.markdown-viewer[_ngcontent-%COMP%] pre[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n padding: 12px;\n border-radius: 6px;\n overflow-x: auto;\n margin-bottom: 12px;\n}\n\n.markdown-viewer[_ngcontent-%COMP%] pre[_ngcontent-%COMP%] code[_ngcontent-%COMP%] {\n background: none;\n padding: 0;\n}\n\n.code-viewer[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n overflow: hidden;\n min-height: 0;\n}\n\n.code-toolbar[_ngcontent-%COMP%] {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n padding: 8px 12px;\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.code-editor-container[_ngcontent-%COMP%] {\n flex: 1;\n overflow: hidden;\n min-height: 0;\n}\n\n.plaintext-viewer[_ngcontent-%COMP%] {\n flex: 1;\n overflow: auto;\n padding: 12px;\n background: var(--mj-bg-surface-sunken);\n font-family: 'Courier New', monospace;\n font-size: 13px;\n white-space: pre-wrap;\n}\n\n.html-viewer[_ngcontent-%COMP%] {\n flex: 1;\n overflow: auto;\n padding: 20px;\n background: var(--mj-bg-surface);\n}\n\n\n@media (max-width: 768px) {\n \n .artifact-viewer-panel[_ngcontent-%COMP%] {\n border-top: 3px solid var(--mj-brand-primary);\n position: relative;\n }\n\n \n .artifact-viewer-panel[_ngcontent-%COMP%]::before {\n content: '';\n position: absolute;\n top: -8px;\n left: 0;\n right: 0;\n height: 8px;\n background: var(--mj-brand-secondary);\n }\n\n .tab-navigation[_ngcontent-%COMP%] {\n padding: 0 8px;\n overflow-x: auto;\n overflow-y: hidden;\n -webkit-overflow-scrolling: touch;\n scrollbar-width: none;\n }\n\n .tab-navigation[_ngcontent-%COMP%]::-webkit-scrollbar {\n display: none;\n }\n\n .tab-btn[_ngcontent-%COMP%] {\n padding: 10px 12px;\n font-size: 12px;\n white-space: nowrap;\n flex-shrink: 0;\n }\n\n .tab-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 13px;\n }\n\n .panel-header[_ngcontent-%COMP%] {\n padding: 12px;\n }\n\n .dynamic-tab-content[_ngcontent-%COMP%] {\n padding: 12px;\n }\n\n .markdown-viewer[_ngcontent-%COMP%] {\n padding: 12px;\n }\n}\n\n\n@media (max-width: 480px) {\n .tab-navigation[_ngcontent-%COMP%] {\n padding: 0 4px;\n }\n\n .tab-btn[_ngcontent-%COMP%] {\n padding: 8px 10px;\n font-size: 11px;\n gap: 4px;\n }\n\n .tab-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n }\n\n .panel-header[_ngcontent-%COMP%] {\n padding: 8px;\n }\n\n .dynamic-tab-content[_ngcontent-%COMP%] {\n padding: 8px;\n }\n\n .markdown-viewer[_ngcontent-%COMP%] {\n padding: 8px;\n }\n}\n\n\n.file-fallback[_ngcontent-%COMP%] { display: flex; flex-direction: column; gap: var(--mj-space-3, 12px); padding: var(--mj-space-4, 16px); }\n.file-fallback-card[_ngcontent-%COMP%] {\n display: flex; align-items: center; gap: var(--mj-space-3, 12px);\n padding: var(--mj-space-3, 12px) var(--mj-space-4, 16px);\n border: 1px solid var(--mj-border-default); border-radius: var(--mj-radius-md, 8px);\n background: var(--mj-bg-surface-card, var(--mj-bg-surface));\n}\n.file-fallback-card[_ngcontent-%COMP%] > i[_ngcontent-%COMP%] { font-size: 1.5rem; color: var(--mj-brand-primary); }\n.file-fallback-meta[_ngcontent-%COMP%] { flex: 1; min-width: 0; }\n.file-fallback-name[_ngcontent-%COMP%] { font-weight: var(--mj-font-semibold, 600); color: var(--mj-text-primary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n.file-fallback-sub[_ngcontent-%COMP%] { font-size: var(--mj-text-sm, 0.85rem); color: var(--mj-text-muted); }\n.file-fallback-text[_ngcontent-%COMP%] { max-height: 60vh; overflow: auto; margin: 0; }"] });
1786
1980
  }
1787
1981
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ArtifactViewerPanelComponent, [{
1788
1982
  type: Component,
1789
- args: [{ standalone: false, selector: 'mj-artifact-viewer-panel', template: "<div class=\"artifact-viewer-panel\" [class.no-header]=\"!showHeader\">\n @if (showHeader) {\n <div class=\"panel-header\">\n <div class=\"panel-header-left\">\n <h3>\n <i class=\"fas\" [ngClass]=\"artifactIcon\"></i>\n {{ displayName }}\n </h3>\n @if (displayDescription) {\n <p class=\"header-description\">{{ displayDescription }}</p>\n }\n </div>\n <div class=\"panel-header-right\">\n <div class=\"version-selector\"\n [class.clickable]=\"allVersions.length > 1 && viewContext !== 'collection'\"\n (click)=\"viewContext !== 'collection' && toggleVersionDropdown()\">\n <i class=\"fas fa-history\"></i>\n <span class=\"version-label\">v{{ selectedVersionNumber }}</span>\n @if (allVersions.length > 1 && viewContext !== 'collection') {\n <i class=\"fas fa-chevron-down dropdown-icon\" [class.open]=\"showVersionDropdown\"></i>\n }\n @if (showVersionDropdown) {\n <div class=\"version-dropdown\" (click)=\"$event.stopPropagation()\">\n @for (version of allVersions; track version.ID) {\n <div class=\"version-option\"\n [class.selected]=\"version.VersionNumber === selectedVersionNumber\"\n (click)=\"selectVersion(version); $event.stopPropagation()\">\n <span class=\"version-number\">v{{ version.VersionNumber }}</span>\n <span class=\"version-date\">{{ version.__mj_CreatedAt | date:'short' }}</span>\n @if (version.VersionNumber === selectedVersionNumber) {\n <i class=\"fas fa-check\"></i>\n }\n </div>\n }\n </div>\n }\n </div>\n @if (pluginViewer?.SupportsFeedback) {\n <button class=\"feedback-btn\"\n (click)=\"pluginViewer?.AskUserForFeedback()\"\n title=\"Inspect & rate components\">\n <i class=\"fas fa-star-half-stroke\"></i>\n </button>\n }\n @if (showSaveToCollection) {\n <button class=\"save-to-collection-btn\"\n [class.in-collection]=\"isInCollection\"\n (click)=\"onSaveToLibrary()\"\n [title]=\"isInCollection ? 'Current version saved to ' + currentVersionCollections.length + ' collection(s)' : 'Save to Collection'\">\n <i [class]=\"isInCollection ? 'fas fa-bookmark' : 'far fa-bookmark'\"></i>\n </button>\n }\n @if (canShare) {\n <button class=\"share-btn\"\n (click)=\"onShare()\"\n title=\"Share\">\n <i class=\"fas fa-share-nodes\"></i>\n </button>\n }\n <button class=\"analyze-btn\"\n (click)=\"OnAnalyze()\"\n title=\"Analyze this artifact with AI\">\n <i class=\"fas fa-magnifying-glass-chart\"></i>\n </button>\n @if (showMaximizeButton) {\n <button class=\"maximize-btn\"\n (click)=\"onMaximizeToggle()\"\n [title]=\"isMaximized ? 'Restore Width' : 'Maximize Width'\">\n <i class=\"fas\" [ngClass]=\"isMaximized ? 'fa-compress-arrows-alt' : 'fa-arrows-left-right'\"></i>\n </button>\n }\n @if (showCloseButton) {\n <button class=\"close-btn\" (click)=\"onClose()\" title=\"Close\">\n <i class=\"fas fa-times\"></i>\n </button>\n }\n </div>\n </div>\n }\n\n <div class=\"panel-content\">\n @if (isLoading) {\n <div class=\"loading-state\">\n <i class=\"fas fa-spinner fa-spin\"></i>\n <span>Loading artifact...</span>\n </div>\n }\n\n @if (error) {\n <mj-empty-state\n Variant=\"error\"\n Icon=\"fa-solid fa-triangle-exclamation\"\n Title=\"Couldn't load artifact\"\n [Message]=\"error\"\n Size=\"compact\" />\n }\n\n @if (!isLoading && !error && artifact) {\n <div class=\"artifact-content-wrapper\" [class.no-tabs]=\"!showTabs\">\n <!-- Tab Navigation (Dynamic) - Hidden when showTabs is false -->\n @if (showTabs) {\n <div class=\"tab-navigation\">\n @for (tab of allTabs; track tab) {\n <button class=\"tab-btn\"\n [class.active]=\"activeTab === tab.toLowerCase()\"\n (click)=\"SetActiveTab(tab)\">\n @if (GetTabIcon(tab)) {\n <i [class]=\"GetTabIcon(tab)!\"></i>\n }\n {{ tab }}\n </button>\n }\n </div>\n }\n\n <!-- Tab Content (Dynamic) -->\n <div class=\"tab-content\">\n <!-- Plugin Viewer - Created once, kept alive, shown/hidden with CSS -->\n @if (hasPlugin && artifactVersion && artifactTypeName) {\n <div class=\"plugin-container\" [class.plugin-hidden]=\"activeTab !== 'display'\">\n <mj-artifact-type-plugin-viewer\n [artifactVersion]=\"artifactVersion\"\n [artifactTypeName]=\"artifactTypeName\"\n [contentType]=\"contentType\"\n [readonly]=\"true\"\n (openEntityRecord)=\"onOpenEntityRecord($event)\"\n (navigationRequest)=\"onNavigationRequest($event)\"\n (pluginLoaded)=\"onPluginLoaded()\"\n (tabsChanged)=\"onTabsChanged()\"\n (applyFormRequested)=\"applyFormRequested.emit($event)\">\n </mj-artifact-type-plugin-viewer>\n </div>\n }\n\n <!-- Display Tab - Fallback content when no plugin -->\n @if (activeTab === 'display' && (!hasPlugin || !artifactVersion)) {\n <div class=\"display-content\">\n @if (displayMarkdown || displayHtml) {\n <!-- Fallback to extracted markdown/HTML attributes -->\n <div class=\"display-toolbar\">\n <button class=\"btn-icon\" title=\"Print\" (click)=\"onPrintDisplayContent()\">\n <i class=\"fas fa-print\"></i> Print\n </button>\n <button class=\"btn-icon\" title=\"Copy Content\" (click)=\"onCopyDisplayContent()\">\n <i class=\"fas fa-copy\"></i> Copy\n </button>\n </div>\n @if (displayMarkdown) {\n <div class=\"markdown-content\">\n <mj-markdown [data]=\"displayMarkdown\"\n [enableCollapsibleHeadings]=\"true\"\n [enableLineNumbers]=\"true\"\n [enableSmartypants]=\"true\"\n [enableHtml]=\"true\"></mj-markdown>\n </div>\n } @else if (displayHtml) {\n <div class=\"html-content\" [innerHTML]=\"displayHtml\"></div>\n }\n }\n </div>\n }\n\n <!-- Details Tab - Artifact metadata (always in DOM, hidden with CSS) -->\n <div class=\"details-content\" [class.tab-hidden]=\"activeTab !== 'details'\">\n <div class=\"artifact-meta\">\n <div class=\"meta-item\">\n <label>Type</label>\n <span>{{ artifact.Type }}</span>\n </div>\n <div class=\"meta-item\">\n <label>Version</label>\n <span>{{ artifactVersion?.VersionNumber || 1 }}</span>\n </div>\n <div class=\"meta-item\">\n <label>Created</label>\n <span>{{ artifact.__mj_CreatedAt | date:'short' }}</span>\n </div>\n <div class=\"meta-item\">\n <label>Updated</label>\n <span>{{ artifactVersion?.__mj_UpdatedAt | date:'short' }}</span>\n </div>\n @if (artifact.Description) {\n <div class=\"meta-item full-width\">\n <label>Artifact Description</label>\n <span>{{ artifact.Description }}</span>\n </div>\n }\n @if (artifactVersion?.Description && artifact.Description && artifactVersion?.Description !== artifact.Description) {\n <div class=\"meta-item full-width\">\n <label>Version Description</label>\n <span>{{ artifactVersion?.Description }}</span>\n </div>\n }\n </div>\n\n <!-- Version Attributes -->\n @if (filteredAttributes.length > 0) {\n <div class=\"attributes-section\">\n <h4>Version Attributes</h4>\n <div class=\"attributes-list\">\n @for (attr of filteredAttributes; track attr.ID) {\n <div class=\"attribute-item\">\n <label>{{ attr.Name }}</label>\n @if (attr.Value) {\n <span>{{ attr.Value }}</span>\n } @else {\n <span class=\"attribute-empty-pill\">Empty</span>\n }\n </div>\n }\n </div>\n </div>\n }\n </div>\n\n <!-- Links Tab - Conversations and Collections (always in DOM, hidden with CSS) -->\n <div class=\"links-container\" [class.tab-hidden]=\"activeTab !== 'links'\">\n @if (linksToShow.length > 0) {\n <div class=\"links-section\">\n @for (link of linksToShow; track link.id) {\n <div class=\"link-item\"\n [class.disabled]=\"!link.hasAccess\"\n [class.clickable]=\"link.hasAccess\"\n (click)=\"link.hasAccess ? onNavigateToLink(link) : null\"\n [title]=\"link.hasAccess ? 'Click to open' : 'No access'\">\n <div class=\"link-icon\">\n @if (link.type === 'conversation') {\n <i class=\"fas fa-comments\"></i>\n } @else {\n <i class=\"fas fa-folder\"></i>\n }\n </div>\n <div class=\"link-content\">\n <div class=\"link-name\">{{ link.name }}</div>\n <div class=\"link-type\">{{ link.type === 'conversation' ? 'Conversation' : 'Collection' }}</div>\n </div>\n <div class=\"link-actions\">\n <i class=\"fas fa-arrow-right\"></i>\n </div>\n </div>\n }\n </div>\n } @else {\n <mj-empty-state\n Icon=\"fa-solid fa-link\"\n Title=\"No links available\"\n Size=\"compact\" />\n }\n </div>\n\n <!-- Dynamic Plugin Tabs and Base Tabs (JSON, etc.) -->\n @if (activeTab !== 'display' && activeTab !== 'details' && activeTab !== 'links') {\n <!-- Check if this is a component tab -->\n @if (GetComponentTabType(activeTab); as componentType) {\n <div class=\"component-tab-content\">\n <ng-container *ngComponentOutlet=\"componentType; inputs: GetComponentInputs(activeTab)\"></ng-container>\n </div>\n } @else {\n @if (GetTabContent(activeTab); as tabData) {\n <div class=\"dynamic-tab-content\">\n @switch (tabData.type) {\n @case ('markdown') {\n <div class=\"markdown-viewer\">\n <mj-markdown [data]=\"tabData.content\"\n [enableCollapsibleHeadings]=\"true\"\n [enableLineNumbers]=\"true\"\n [enableSmartypants]=\"true\"\n [enableHtml]=\"true\"></mj-markdown>\n </div>\n }\n @case ('json') {\n <div class=\"json-viewer\">\n <div class=\"json-toolbar\">\n <button class=\"btn-icon\" title=\"Copy JSON\" (click)=\"onCopyToClipboard()\">\n <i class=\"fas fa-copy\"></i> Copy\n </button>\n </div>\n <div class=\"json-editor-container\">\n <mj-code-editor\n [value]=\"tabData.content\"\n [language]=\"'json'\"\n [readonly]=\"true\"\n [lineWrapping]=\"true\"\n style=\"width: 100%; height: 100%;\">\n </mj-code-editor>\n </div>\n </div>\n }\n @case ('code') {\n <div class=\"code-viewer\">\n <div class=\"code-toolbar\">\n <button class=\"btn-icon\" title=\"Copy Code\" (click)=\"onCopyToClipboard()\">\n <i class=\"fas fa-copy\"></i> Copy\n </button>\n </div>\n <div class=\"code-editor-container\">\n <mj-code-editor\n [value]=\"tabData.content\"\n [language]=\"tabData.language || 'typescript'\"\n [readonly]=\"true\"\n [lineWrapping]=\"true\"\n style=\"width: 100%; height: 100%;\">\n </mj-code-editor>\n </div>\n </div>\n }\n @case ('html') {\n <div class=\"html-viewer\" [innerHTML]=\"tabData.content\"></div>\n }\n @case ('plaintext') {\n <pre class=\"plaintext-viewer\">{{ tabData.content }}</pre>\n }\n }\n </div>\n }\n }\n }\n </div>\n </div>\n }\n </div>\n</div>\n\n", styles: [".artifact-viewer-panel {\n width: 100%;\n height: 100%;\n background: var(--mj-bg-surface);\n border-left: 1px solid var(--mj-border-default);\n display: flex;\n flex-direction: column;\n overflow: hidden;\n box-sizing: border-box;\n}\n\n.panel-header {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n padding: 12px 16px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n flex-shrink: 0;\n width: 100%;\n box-sizing: border-box;\n}\n\n.panel-header-left {\n flex: 1;\n min-width: 0;\n margin-right: 16px;\n}\n\n.panel-header h3 {\n margin: 0;\n font-size: 14px;\n font-weight: 600;\n display: flex;\n align-items: flex-start;\n gap: 8px;\n word-wrap: break-word;\n overflow-wrap: break-word;\n}\n\n.panel-header h3 i {\n color: var(--mj-brand-primary);\n flex-shrink: 0;\n margin-top: 2px;\n}\n\n.header-description {\n margin: 4px 0 0 0;\n font-size: 12px;\n color: var(--mj-text-muted);\n font-weight: normal;\n word-wrap: break-word;\n overflow-wrap: break-word;\n}\n\n.panel-header-right {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-shrink: 0;\n}\n\n.version-selector {\n position: relative;\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 12px;\n font-size: 12px;\n color: var(--mj-text-muted);\n font-weight: 500;\n transition: all 0.2s;\n}\n\n.version-selector.clickable {\n cursor: pointer;\n}\n\n.version-selector.clickable:hover {\n background: var(--mj-border-default);\n}\n\n.version-selector i {\n font-size: 11px;\n}\n\n.version-selector .dropdown-icon {\n margin-left: 2px;\n transition: transform 0.2s;\n}\n\n.version-selector .dropdown-icon.open {\n transform: rotate(180deg);\n}\n\n.version-label {\n font-family: monospace;\n}\n\n.version-dropdown {\n position: absolute;\n top: calc(100% + 4px);\n right: 0;\n min-width: 200px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n box-shadow: var(--mj-shadow-md);\n z-index: 1000;\n overflow: hidden;\n}\n\n.version-option {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 12px;\n cursor: pointer;\n transition: background 0.15s;\n font-size: 13px;\n}\n\n.version-option:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.version-option.selected {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.version-option .version-number {\n font-family: monospace;\n font-weight: 600;\n min-width: 35px;\n}\n\n.version-option .version-date {\n flex: 1;\n color: var(--mj-text-muted);\n font-size: 12px;\n}\n\n.version-option i.fa-check {\n color: var(--mj-status-success);\n margin-left: auto;\n}\n\n.feedback-btn {\n background: none;\n border: none;\n cursor: pointer;\n color: var(--mj-text-disabled);\n padding: 6px;\n border-radius: 4px;\n transition: all 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n}\n\n.feedback-btn:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-brand-primary);\n}\n\n.feedback-btn i {\n font-size: 14px;\n}\n\n.save-to-collection-btn {\n background: none;\n border: none;\n cursor: pointer;\n color: var(--mj-text-disabled);\n padding: 6px;\n border-radius: 4px;\n transition: all 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n}\n\n.save-to-collection-btn:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n}\n\n.save-to-collection-btn i {\n font-size: 14px;\n}\n\n.save-to-collection-btn.in-collection {\n color: var(--mj-brand-primary);\n}\n\n.save-to-collection-btn.in-collection:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.share-btn {\n background: none;\n border: none;\n cursor: pointer;\n color: var(--mj-text-disabled);\n padding: 6px;\n border-radius: 4px;\n transition: all 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n}\n\n.share-btn:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-brand-primary);\n}\n\n.share-btn i {\n font-size: 14px;\n}\n\n.analyze-btn {\n background: none;\n border: none;\n cursor: pointer;\n color: var(--mj-text-disabled);\n padding: 6px;\n border-radius: 4px;\n transition: all 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.analyze-btn:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.analyze-btn i {\n font-size: 14px;\n}\n\n.maximize-btn {\n background: none;\n border: none;\n cursor: pointer;\n color: var(--mj-text-muted);\n padding: 6px;\n border-radius: 4px;\n transition: all 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n}\n\n.maximize-btn:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n}\n\n.maximize-btn i {\n font-size: 14px;\n}\n\n.close-btn {\n background: none;\n border: none;\n cursor: pointer;\n color: var(--mj-text-muted);\n padding: 6px;\n border-radius: 4px;\n transition: all 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n}\n\n.close-btn:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n}\n\n.close-btn i {\n font-size: 14px;\n}\n\n.panel-content {\n flex: 1;\n overflow: hidden;\n min-height: 0;\n display: flex;\n flex-direction: column;\n width: 100%;\n box-sizing: border-box;\n}\n\n.artifact-content-wrapper {\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n min-height: 0;\n width: 100%;\n box-sizing: border-box;\n}\n\n.loading-state {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 12px;\n padding: 40px 20px;\n color: var(--mj-text-muted);\n}\n\n.loading-state i {\n font-size: 24px;\n}\n\n.artifact-meta {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));\n gap: 16px;\n margin-bottom: 16px;\n padding: 16px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 8px;\n flex-shrink: 0;\n}\n\n.meta-item {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.meta-item label {\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.meta-item span {\n font-size: 14px;\n color: var(--mj-text-primary);\n}\n\n.artifact-description {\n padding: 12px;\n margin-bottom: 16px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-left: 3px solid var(--mj-brand-primary);\n border-radius: 4px;\n color: var(--mj-brand-primary);\n font-size: 14px;\n flex-shrink: 0;\n}\n\n.json-viewer {\n flex: 1;\n display: flex;\n flex-direction: column;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n overflow: hidden;\n min-height: 0;\n}\n\n.json-editor-container {\n flex: 1;\n overflow: hidden;\n min-height: 0;\n}\n\n.json-toolbar {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n padding: 8px 12px;\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.btn-icon {\n display: flex;\n align-items: center;\n gap: 6px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong);\n border-radius: 4px;\n padding: 6px 12px;\n cursor: pointer;\n color: var(--mj-text-secondary);\n font-size: 14px;\n transition: all 0.2s;\n}\n\n.btn-icon:hover {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-text-disabled);\n}\n\n.btn-icon.btn-primary {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.btn-icon.btn-primary:hover {\n background: var(--mj-brand-primary-hover);\n border-color: var(--mj-brand-primary-hover);\n}\n\n.btn-icon i {\n font-size: 14px;\n}\n\n/* Library Dialog Styles */\n.modal-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: var(--mj-bg-overlay);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 10000;\n}\n\n.modal-content {\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: var(--mj-shadow-lg);\n max-width: 500px;\n width: 90%;\n max-height: 90vh;\n display: flex;\n flex-direction: column;\n}\n\n.modal-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.modal-header h3 {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.modal-header h3 i {\n color: var(--mj-status-warning);\n}\n\n.modal-body {\n padding: 20px;\n overflow-y: auto;\n}\n\n.modal-footer {\n display: flex;\n justify-content: flex-end;\n gap: 12px;\n padding: 16px 20px;\n border-top: 1px solid var(--mj-border-default);\n}\n\n.form-section {\n margin-bottom: 20px;\n}\n\n.form-section label {\n display: block;\n margin-bottom: 8px;\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n}\n\n.form-select,\n.form-input {\n width: 100%;\n padding: 10px 12px;\n border: 1px solid var(--mj-border-strong);\n border-radius: 6px;\n font-size: 14px;\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n transition: border-color 0.2s;\n}\n\n.form-select:focus,\n.form-input:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.divider {\n display: flex;\n align-items: center;\n margin: 24px 0;\n color: var(--mj-text-disabled);\n font-size: 12px;\n font-weight: 500;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.divider::before,\n.divider::after {\n content: '';\n flex: 1;\n height: 1px;\n background: var(--mj-border-default);\n}\n\n.divider span {\n padding: 0 12px;\n}\n\n.create-collection-row {\n display: flex;\n gap: 8px;\n}\n\n.create-collection-row .form-input {\n flex: 1;\n}\n\n.btn {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 16px;\n border: none;\n border-radius: 6px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s;\n white-space: nowrap;\n}\n\n.btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.btn-primary {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.btn-primary:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n}\n\n.btn-secondary {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong);\n color: var(--mj-text-secondary);\n}\n\n.btn-secondary:hover:not(:disabled) {\n background: var(--mj-bg-surface-sunken);\n}\n\n/* Tab Navigation */\n.tab-navigation {\n display: flex;\n gap: 0;\n border-bottom: 2px solid var(--mj-border-default);\n padding: 0 16px;\n background: var(--mj-bg-surface);\n}\n\n.tab-btn {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 12px 20px;\n background: transparent;\n border: none;\n border-bottom: 2px solid transparent;\n margin-bottom: -2px;\n color: var(--mj-text-muted);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 150ms ease;\n}\n\n.tab-btn:hover {\n color: var(--mj-brand-primary);\n background: var(--mj-bg-surface-sunken);\n}\n\n.tab-btn.active {\n color: var(--mj-brand-primary);\n border-bottom-color: var(--mj-brand-primary);\n}\n\n.tab-btn i {\n font-size: 14px;\n}\n\n/* Tab Content */\n.tab-content {\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow: auto;\n width: 100%;\n box-sizing: border-box;\n margin-bottom: 5px;\n min-width: 0;\n min-height: 0;\n}\n\n/* Plugin Container */\n.plugin-container {\n width: 100%;\n height: 100%;\n min-height: 0;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n.plugin-container.plugin-hidden,\n.tab-hidden {\n display: none;\n}\n\n/* Ensure artifact viewer component takes full height */\n.plugin-container mj-artifact-type-plugin-viewer {\n display: flex;\n flex-direction: column;\n flex: 1;\n min-height: 0;\n width: 100%;\n}\n\n.display-content {\n flex: 1;\n display: flex;\n flex-direction: column;\n position: relative;\n width: 100%;\n box-sizing: border-box;\n overflow: hidden;\n min-height: 0;\n min-width: 0;\n padding: 7px;\n}\n\n.display-toolbar {\n position: absolute;\n top: 12px;\n right: 12px;\n display: flex;\n gap: 8px;\n z-index: 10;\n}\n\n.markdown-content,\n.html-content {\n flex: 1;\n font-size: 14px;\n line-height: 1.6;\n width: 100%;\n padding: 20px 10px 5px 20px; /* top right bottom left */\n box-sizing: border-box;\n overflow: auto;\n min-height: 0;\n}\n\n.details-content {\n padding: 20px;\n width: 100%;\n box-sizing: border-box;\n}\n\n.details-content .artifact-meta {\n margin-bottom: 0;\n padding: 20px;\n}\n\n.details-content .meta-item.full-width {\n grid-column: 1 / -1;\n}\n\n.attributes-section {\n margin-top: 24px;\n padding: 24px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 8px;\n}\n\n.attributes-section h4 {\n margin: 0 0 16px 0;\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.attributes-list {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));\n gap: 16px;\n}\n\n.attribute-item {\n display: flex;\n flex-direction: column;\n gap: 6px;\n padding: 12px;\n background: var(--mj-bg-surface);\n border-radius: 6px;\n border: 1px solid var(--mj-border-default);\n}\n\n.attribute-item label {\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.attribute-item span {\n font-size: 13px;\n color: var(--mj-text-primary);\n word-break: break-word;\n}\n\n.attribute-empty-pill {\n display: inline-block;\n padding: 2px 8px;\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-disabled);\n font-size: 11px;\n font-weight: 500;\n border-radius: 4px;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n/* Links Tab */\n.links-container {\n padding: 20px;\n}\n\n.links-section {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.link-item {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n transition: all 0.15s;\n}\n\n.link-item.clickable {\n cursor: pointer;\n}\n\n.link-item.clickable:hover {\n border-color: var(--mj-brand-primary);\n box-shadow: var(--mj-shadow-sm);\n background: var(--mj-bg-surface-sunken);\n}\n\n.link-item.disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.link-item:hover {\n border-color: var(--mj-brand-primary);\n box-shadow: var(--mj-shadow-sm);\n}\n\n.link-icon {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--mj-bg-surface);\n border-radius: 8px;\n flex-shrink: 0;\n}\n\n.link-icon i {\n font-size: 18px;\n color: var(--mj-brand-primary);\n}\n\n.link-content {\n flex: 1;\n min-width: 0;\n}\n\n.link-name {\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.link-type {\n font-size: 12px;\n color: var(--mj-text-muted);\n margin-top: 2px;\n}\n\n.link-actions {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 24px;\n height: 24px;\n flex-shrink: 0;\n}\n\n.link-actions i {\n font-size: 14px;\n color: var(--mj-text-muted);\n transition: all 0.15s;\n}\n\n.link-item.clickable:hover .link-actions i {\n color: var(--mj-brand-primary);\n transform: translateX(2px);\n}\n\n/* Dynamic Tab Content Styles */\n.dynamic-tab-content {\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n padding: 16px;\n}\n\n/* Custom component tab content */\n.component-tab-content {\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow: auto;\n padding: 16px;\n}\n\n.markdown-viewer {\n flex: 1;\n overflow: auto;\n padding: 20px;\n background: var(--mj-bg-surface);\n line-height: 1.6;\n}\n\n.markdown-viewer h1, .markdown-viewer h2, .markdown-viewer h3 {\n margin-top: 24px;\n margin-bottom: 12px;\n font-weight: 600;\n}\n\n.markdown-viewer h1 { font-size: 24px; }\n.markdown-viewer h2 { font-size: 20px; }\n.markdown-viewer h3 { font-size: 18px; }\n\n.markdown-viewer p {\n margin-bottom: 12px;\n}\n\n.markdown-viewer ul, .markdown-viewer ol {\n margin-bottom: 12px;\n padding-left: 24px;\n}\n\n.markdown-viewer code {\n background: var(--mj-bg-surface-sunken);\n padding: 2px 6px;\n border-radius: 3px;\n font-family: 'Courier New', monospace;\n font-size: 13px;\n}\n\n.markdown-viewer pre {\n background: var(--mj-bg-surface-sunken);\n padding: 12px;\n border-radius: 6px;\n overflow-x: auto;\n margin-bottom: 12px;\n}\n\n.markdown-viewer pre code {\n background: none;\n padding: 0;\n}\n\n.code-viewer {\n flex: 1;\n display: flex;\n flex-direction: column;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n overflow: hidden;\n min-height: 0;\n}\n\n.code-toolbar {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n padding: 8px 12px;\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.code-editor-container {\n flex: 1;\n overflow: hidden;\n min-height: 0;\n}\n\n.plaintext-viewer {\n flex: 1;\n overflow: auto;\n padding: 12px;\n background: var(--mj-bg-surface-sunken);\n font-family: 'Courier New', monospace;\n font-size: 13px;\n white-space: pre-wrap;\n}\n\n.html-viewer {\n flex: 1;\n overflow: auto;\n padding: 20px;\n background: var(--mj-bg-surface);\n}\n\n/* Mobile adjustments: 481px - 768px */\n@media (max-width: 768px) {\n /* Add top border with slight visual separation from top nav */\n .artifact-viewer-panel {\n border-top: 3px solid var(--mj-brand-primary);\n position: relative;\n }\n\n /* Create a small dark strip above the blue border to separate from top nav */\n .artifact-viewer-panel::before {\n content: '';\n position: absolute;\n top: -8px;\n left: 0;\n right: 0;\n height: 8px;\n background: var(--mj-brand-secondary);\n }\n\n .tab-navigation {\n padding: 0 8px;\n overflow-x: auto;\n overflow-y: hidden;\n -webkit-overflow-scrolling: touch;\n scrollbar-width: none;\n }\n\n .tab-navigation::-webkit-scrollbar {\n display: none;\n }\n\n .tab-btn {\n padding: 10px 12px;\n font-size: 12px;\n white-space: nowrap;\n flex-shrink: 0;\n }\n\n .tab-btn i {\n font-size: 13px;\n }\n\n .panel-header {\n padding: 12px;\n }\n\n .dynamic-tab-content {\n padding: 12px;\n }\n\n .markdown-viewer {\n padding: 12px;\n }\n}\n\n/* Small Phone adjustments: <= 480px */\n@media (max-width: 480px) {\n .tab-navigation {\n padding: 0 4px;\n }\n\n .tab-btn {\n padding: 8px 10px;\n font-size: 11px;\n gap: 4px;\n }\n\n .tab-btn i {\n font-size: 12px;\n }\n\n .panel-header {\n padding: 8px;\n }\n\n .dynamic-tab-content {\n padding: 8px;\n }\n\n .markdown-viewer {\n padding: 8px;\n }\n}\n"] }]
1790
- }], () => [{ type: i0.ChangeDetectorRef }, { type: i1.MJNotificationService }, { type: i2.DomSanitizer }, { type: i3.ArtifactIconService }], { artifactId: [{
1983
+ args: [{ standalone: false, selector: 'mj-artifact-viewer-panel', template: "<div class=\"artifact-viewer-panel\" [class.no-header]=\"!showHeader\">\n @if (showHeader) {\n <div class=\"panel-header\">\n <div class=\"panel-header-left\">\n <h3>\n <i class=\"fas\" [ngClass]=\"artifactIcon\"></i>\n {{ displayName }}\n </h3>\n @if (displayDescription) {\n <p class=\"header-description\">{{ displayDescription }}</p>\n }\n </div>\n <div class=\"panel-header-right\">\n <div class=\"version-selector\"\n [class.clickable]=\"allVersions.length > 1 && viewContext !== 'collection'\"\n (click)=\"viewContext !== 'collection' && toggleVersionDropdown()\">\n <i class=\"fas fa-history\"></i>\n <span class=\"version-label\">v{{ selectedVersionNumber }}</span>\n @if (allVersions.length > 1 && viewContext !== 'collection') {\n <i class=\"fas fa-chevron-down dropdown-icon\" [class.open]=\"showVersionDropdown\"></i>\n }\n @if (showVersionDropdown) {\n <div class=\"version-dropdown\" (click)=\"$event.stopPropagation()\">\n @for (version of allVersions; track version.ID) {\n <div class=\"version-option\"\n [class.selected]=\"version.VersionNumber === selectedVersionNumber\"\n (click)=\"selectVersion(version); $event.stopPropagation()\">\n <span class=\"version-number\">v{{ version.VersionNumber }}</span>\n <span class=\"version-date\">{{ version.__mj_CreatedAt | date:'short' }}</span>\n @if (version.VersionNumber === selectedVersionNumber) {\n <i class=\"fas fa-check\"></i>\n }\n </div>\n }\n </div>\n }\n </div>\n @if (pluginViewer?.SupportsFeedback) {\n <button class=\"feedback-btn\"\n (click)=\"pluginViewer?.AskUserForFeedback()\"\n title=\"Inspect & rate components\">\n <i class=\"fas fa-star-half-stroke\"></i>\n </button>\n }\n @if (showSaveToCollection) {\n <button class=\"save-to-collection-btn\"\n [class.in-collection]=\"isInCollection\"\n (click)=\"onSaveToLibrary()\"\n [title]=\"isInCollection ? 'Current version saved to ' + currentVersionCollections.length + ' collection(s)' : 'Save to Collection'\">\n <i [class]=\"isInCollection ? 'fas fa-bookmark' : 'far fa-bookmark'\"></i>\n </button>\n }\n @if (canShare) {\n <button class=\"share-btn\"\n (click)=\"onShare()\"\n title=\"Share\">\n <i class=\"fas fa-share-nodes\"></i>\n </button>\n }\n <button class=\"analyze-btn\"\n (click)=\"OnAnalyze()\"\n title=\"Analyze this artifact with AI\">\n <i class=\"fas fa-magnifying-glass-chart\"></i>\n </button>\n @if (showMaximizeButton) {\n <button class=\"maximize-btn\"\n (click)=\"onMaximizeToggle()\"\n [title]=\"isMaximized ? 'Restore Width' : 'Maximize Width'\">\n <i class=\"fas\" [ngClass]=\"isMaximized ? 'fa-compress-arrows-alt' : 'fa-arrows-left-right'\"></i>\n </button>\n }\n @if (showCloseButton) {\n <button class=\"close-btn\" (click)=\"onClose()\" title=\"Close\">\n <i class=\"fas fa-times\"></i>\n </button>\n }\n </div>\n </div>\n }\n\n <div class=\"panel-content\">\n @if (isLoading) {\n <div class=\"loading-state\">\n <i class=\"fas fa-spinner fa-spin\"></i>\n <span>Loading artifact...</span>\n </div>\n }\n\n @if (error) {\n <mj-empty-state\n Variant=\"error\"\n Icon=\"fa-solid fa-triangle-exclamation\"\n Title=\"Couldn't load artifact\"\n [Message]=\"error\"\n Size=\"compact\" />\n }\n\n @if (!isLoading && !error && artifact) {\n <div class=\"artifact-content-wrapper\" [class.no-tabs]=\"!showTabs\">\n <!-- Tab Navigation (Dynamic) - Hidden when showTabs is false -->\n @if (showTabs) {\n <div class=\"tab-navigation\">\n @for (tab of allTabs; track tab) {\n <button class=\"tab-btn\"\n [class.active]=\"activeTab === tab.toLowerCase()\"\n (click)=\"SetActiveTab(tab)\">\n @if (GetTabIcon(tab)) {\n <i [class]=\"GetTabIcon(tab)!\"></i>\n }\n {{ tab }}\n </button>\n }\n </div>\n }\n\n <!-- Tab Content (Dynamic) -->\n <div class=\"tab-content\">\n <!-- Plugin Viewer - Created once, kept alive, shown/hidden with CSS -->\n @if (hasPlugin && artifactVersion && artifactTypeName) {\n <div class=\"plugin-container\" [class.plugin-hidden]=\"activeTab !== 'display'\">\n <mj-artifact-type-plugin-viewer\n [artifactVersion]=\"artifactVersion\"\n [artifactTypeName]=\"artifactTypeName\"\n [contentType]=\"contentType\"\n [readonly]=\"true\"\n (openEntityRecord)=\"onOpenEntityRecord($event)\"\n (navigationRequest)=\"onNavigationRequest($event)\"\n (pluginLoaded)=\"onPluginLoaded()\"\n (tabsChanged)=\"onTabsChanged()\"\n (applyFormRequested)=\"applyFormRequested.emit($event)\">\n </mj-artifact-type-plugin-viewer>\n </div>\n }\n\n <!-- Display Tab - Fallback content when no plugin -->\n @if (activeTab === 'display' && (!hasPlugin || !artifactVersion)) {\n <div class=\"display-content\">\n @if (displayMarkdown || displayHtml) {\n <!-- Fallback to extracted markdown/HTML attributes -->\n <div class=\"display-toolbar\">\n <button class=\"btn-icon\" title=\"Print\" (click)=\"onPrintDisplayContent()\">\n <i class=\"fas fa-print\"></i> Print\n </button>\n <button class=\"btn-icon\" title=\"Copy Content\" (click)=\"onCopyDisplayContent()\">\n <i class=\"fas fa-copy\"></i> Copy\n </button>\n </div>\n @if (displayMarkdown) {\n <div class=\"markdown-content\">\n <mj-markdown [data]=\"displayMarkdown\"\n [enableCollapsibleHeadings]=\"true\"\n [enableLineNumbers]=\"true\"\n [enableSmartypants]=\"true\"\n [enableHtml]=\"true\"></mj-markdown>\n </div>\n } @else if (displayHtml) {\n <div class=\"html-content\" [innerHTML]=\"displayHtml\"></div>\n }\n } @else if (showFileFallback) {\n <!-- No viewer plugin for this type: a file card with a real Download, plus the text for text-like content -->\n <div class=\"file-fallback\" data-testid=\"file-fallback\">\n <div class=\"file-fallback-card\">\n <i class=\"fas\" [ngClass]=\"artifactIcon\" aria-hidden=\"true\"></i>\n <div class=\"file-fallback-meta\">\n <div class=\"file-fallback-name\">{{ fallbackFileName }}</div>\n <div class=\"file-fallback-sub\">{{ artifactVersion?.MimeType || artifact.Type }}@if (fallbackSize) { \u00B7 {{ fallbackSize }}}</div>\n </div>\n <button class=\"btn-icon btn-primary\" type=\"button\" (click)=\"downloadArtifactFile()\" [disabled]=\"fallbackBusy\" title=\"Download\">\n <i class=\"fas fa-download\"></i> {{ fallbackBusy ? 'Preparing\u2026' : 'Download' }}\n </button>\n </div>\n @if (fallbackText !== null) {\n <pre class=\"plaintext-viewer file-fallback-text\">{{ fallbackText }}</pre>\n @if (fallbackTextTruncated) {\n <div class=\"file-fallback-sub\">Showing the first part only \u2014 download the file for all of it.</div>\n }\n }\n </div>\n }\n </div>\n }\n\n <!-- Details Tab - Artifact metadata (always in DOM, hidden with CSS) -->\n <div class=\"details-content\" [class.tab-hidden]=\"activeTab !== 'details'\">\n <div class=\"artifact-meta\">\n <div class=\"meta-item\">\n <label>Type</label>\n <span>{{ artifact.Type }}</span>\n </div>\n <div class=\"meta-item\">\n <label>Version</label>\n <span>{{ artifactVersion?.VersionNumber || 1 }}</span>\n </div>\n <div class=\"meta-item\">\n <label>Created</label>\n <span>{{ artifact.__mj_CreatedAt | date:'short' }}</span>\n </div>\n <div class=\"meta-item\">\n <label>Updated</label>\n <span>{{ artifactVersion?.__mj_UpdatedAt | date:'short' }}</span>\n </div>\n @if (artifact.Description) {\n <div class=\"meta-item full-width\">\n <label>Artifact Description</label>\n <span>{{ artifact.Description }}</span>\n </div>\n }\n @if (artifactVersion?.Description && artifact.Description && artifactVersion?.Description !== artifact.Description) {\n <div class=\"meta-item full-width\">\n <label>Version Description</label>\n <span>{{ artifactVersion?.Description }}</span>\n </div>\n }\n </div>\n\n <!-- Version Attributes -->\n @if (filteredAttributes.length > 0) {\n <div class=\"attributes-section\">\n <h4>Version Attributes</h4>\n <div class=\"attributes-list\">\n @for (attr of filteredAttributes; track attr.ID) {\n <div class=\"attribute-item\">\n <label>{{ attr.Name }}</label>\n @if (attr.Value) {\n <span>{{ attr.Value }}</span>\n } @else {\n <span class=\"attribute-empty-pill\">Empty</span>\n }\n </div>\n }\n </div>\n </div>\n }\n </div>\n\n <!-- Links Tab - Conversations and Collections (always in DOM, hidden with CSS) -->\n <div class=\"links-container\" [class.tab-hidden]=\"activeTab !== 'links'\">\n @if (linksToShow.length > 0) {\n <div class=\"links-section\">\n @for (link of linksToShow; track link.id) {\n <div class=\"link-item\"\n [class.disabled]=\"!link.hasAccess\"\n [class.clickable]=\"link.hasAccess\"\n (click)=\"link.hasAccess ? onNavigateToLink(link) : null\"\n [title]=\"link.hasAccess ? 'Click to open' : 'No access'\">\n <div class=\"link-icon\">\n @if (link.type === 'conversation') {\n <i class=\"fas fa-comments\"></i>\n } @else {\n <i class=\"fas fa-folder\"></i>\n }\n </div>\n <div class=\"link-content\">\n <div class=\"link-name\">{{ link.name }}</div>\n <div class=\"link-type\">{{ link.type === 'conversation' ? 'Conversation' : 'Collection' }}</div>\n </div>\n <div class=\"link-actions\">\n <i class=\"fas fa-arrow-right\"></i>\n </div>\n </div>\n }\n </div>\n } @else {\n <mj-empty-state\n Icon=\"fa-solid fa-link\"\n Title=\"No links available\"\n Size=\"compact\" />\n }\n </div>\n\n <!-- Dynamic Plugin Tabs and Base Tabs (JSON, etc.) -->\n @if (activeTab !== 'display' && activeTab !== 'details' && activeTab !== 'links') {\n <!-- Check if this is a component tab -->\n @if (GetComponentTabType(activeTab); as componentType) {\n <div class=\"component-tab-content\">\n <ng-container *ngComponentOutlet=\"componentType; inputs: GetComponentInputs(activeTab)\"></ng-container>\n </div>\n } @else {\n @if (GetTabContent(activeTab); as tabData) {\n <div class=\"dynamic-tab-content\">\n @switch (tabData.type) {\n @case ('markdown') {\n <div class=\"markdown-viewer\">\n <mj-markdown [data]=\"tabData.content\"\n [enableCollapsibleHeadings]=\"true\"\n [enableLineNumbers]=\"true\"\n [enableSmartypants]=\"true\"\n [enableHtml]=\"true\"></mj-markdown>\n </div>\n }\n @case ('json') {\n <div class=\"json-viewer\">\n <div class=\"json-toolbar\">\n <button class=\"btn-icon\" title=\"Copy JSON\" (click)=\"onCopyToClipboard()\">\n <i class=\"fas fa-copy\"></i> Copy\n </button>\n </div>\n <div class=\"json-editor-container\">\n <mj-code-editor\n [value]=\"tabData.content\"\n [language]=\"'json'\"\n [readonly]=\"true\"\n [lineWrapping]=\"true\"\n style=\"width: 100%; height: 100%;\">\n </mj-code-editor>\n </div>\n </div>\n }\n @case ('code') {\n <div class=\"code-viewer\">\n <div class=\"code-toolbar\">\n <button class=\"btn-icon\" title=\"Copy Code\" (click)=\"onCopyToClipboard()\">\n <i class=\"fas fa-copy\"></i> Copy\n </button>\n </div>\n <div class=\"code-editor-container\">\n <mj-code-editor\n [value]=\"tabData.content\"\n [language]=\"tabData.language || 'typescript'\"\n [readonly]=\"true\"\n [lineWrapping]=\"true\"\n style=\"width: 100%; height: 100%;\">\n </mj-code-editor>\n </div>\n </div>\n }\n @case ('html') {\n <div class=\"html-viewer\" [innerHTML]=\"tabData.content\"></div>\n }\n @case ('plaintext') {\n <pre class=\"plaintext-viewer\">{{ tabData.content }}</pre>\n }\n }\n </div>\n }\n }\n }\n </div>\n </div>\n }\n </div>\n</div>\n\n", styles: [".artifact-viewer-panel {\n width: 100%;\n height: 100%;\n background: var(--mj-bg-surface);\n border-left: 1px solid var(--mj-border-default);\n display: flex;\n flex-direction: column;\n overflow: hidden;\n box-sizing: border-box;\n}\n\n.panel-header {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n padding: 12px 16px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n flex-shrink: 0;\n width: 100%;\n box-sizing: border-box;\n}\n\n.panel-header-left {\n flex: 1;\n min-width: 0;\n margin-right: 16px;\n}\n\n.panel-header h3 {\n margin: 0;\n font-size: 14px;\n font-weight: 600;\n display: flex;\n align-items: flex-start;\n gap: 8px;\n word-wrap: break-word;\n overflow-wrap: break-word;\n}\n\n.panel-header h3 i {\n color: var(--mj-brand-primary);\n flex-shrink: 0;\n margin-top: 2px;\n}\n\n.header-description {\n margin: 4px 0 0 0;\n font-size: 12px;\n color: var(--mj-text-muted);\n font-weight: normal;\n word-wrap: break-word;\n overflow-wrap: break-word;\n}\n\n.panel-header-right {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-shrink: 0;\n}\n\n.version-selector {\n position: relative;\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 12px;\n font-size: 12px;\n color: var(--mj-text-muted);\n font-weight: 500;\n transition: all 0.2s;\n}\n\n.version-selector.clickable {\n cursor: pointer;\n}\n\n.version-selector.clickable:hover {\n background: var(--mj-border-default);\n}\n\n.version-selector i {\n font-size: 11px;\n}\n\n.version-selector .dropdown-icon {\n margin-left: 2px;\n transition: transform 0.2s;\n}\n\n.version-selector .dropdown-icon.open {\n transform: rotate(180deg);\n}\n\n.version-label {\n font-family: monospace;\n}\n\n.version-dropdown {\n position: absolute;\n top: calc(100% + 4px);\n right: 0;\n min-width: 200px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n box-shadow: var(--mj-shadow-md);\n z-index: 1000;\n overflow: hidden;\n}\n\n.version-option {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 12px;\n cursor: pointer;\n transition: background 0.15s;\n font-size: 13px;\n}\n\n.version-option:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.version-option.selected {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.version-option .version-number {\n font-family: monospace;\n font-weight: 600;\n min-width: 35px;\n}\n\n.version-option .version-date {\n flex: 1;\n color: var(--mj-text-muted);\n font-size: 12px;\n}\n\n.version-option i.fa-check {\n color: var(--mj-status-success);\n margin-left: auto;\n}\n\n.feedback-btn {\n background: none;\n border: none;\n cursor: pointer;\n color: var(--mj-text-disabled);\n padding: 6px;\n border-radius: 4px;\n transition: all 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n}\n\n.feedback-btn:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-brand-primary);\n}\n\n.feedback-btn i {\n font-size: 14px;\n}\n\n.save-to-collection-btn {\n background: none;\n border: none;\n cursor: pointer;\n color: var(--mj-text-disabled);\n padding: 6px;\n border-radius: 4px;\n transition: all 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n}\n\n.save-to-collection-btn:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n}\n\n.save-to-collection-btn i {\n font-size: 14px;\n}\n\n.save-to-collection-btn.in-collection {\n color: var(--mj-brand-primary);\n}\n\n.save-to-collection-btn.in-collection:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.share-btn {\n background: none;\n border: none;\n cursor: pointer;\n color: var(--mj-text-disabled);\n padding: 6px;\n border-radius: 4px;\n transition: all 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n}\n\n.share-btn:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-brand-primary);\n}\n\n.share-btn i {\n font-size: 14px;\n}\n\n.analyze-btn {\n background: none;\n border: none;\n cursor: pointer;\n color: var(--mj-text-disabled);\n padding: 6px;\n border-radius: 4px;\n transition: all 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.analyze-btn:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.analyze-btn i {\n font-size: 14px;\n}\n\n.maximize-btn {\n background: none;\n border: none;\n cursor: pointer;\n color: var(--mj-text-muted);\n padding: 6px;\n border-radius: 4px;\n transition: all 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n}\n\n.maximize-btn:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n}\n\n.maximize-btn i {\n font-size: 14px;\n}\n\n.close-btn {\n background: none;\n border: none;\n cursor: pointer;\n color: var(--mj-text-muted);\n padding: 6px;\n border-radius: 4px;\n transition: all 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n}\n\n.close-btn:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n}\n\n.close-btn i {\n font-size: 14px;\n}\n\n.panel-content {\n flex: 1;\n overflow: hidden;\n min-height: 0;\n display: flex;\n flex-direction: column;\n width: 100%;\n box-sizing: border-box;\n}\n\n.artifact-content-wrapper {\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n min-height: 0;\n width: 100%;\n box-sizing: border-box;\n}\n\n.loading-state {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 12px;\n padding: 40px 20px;\n color: var(--mj-text-muted);\n}\n\n.loading-state i {\n font-size: 24px;\n}\n\n.artifact-meta {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));\n gap: 16px;\n margin-bottom: 16px;\n padding: 16px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 8px;\n flex-shrink: 0;\n}\n\n.meta-item {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.meta-item label {\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.meta-item span {\n font-size: 14px;\n color: var(--mj-text-primary);\n}\n\n.artifact-description {\n padding: 12px;\n margin-bottom: 16px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-left: 3px solid var(--mj-brand-primary);\n border-radius: 4px;\n color: var(--mj-brand-primary);\n font-size: 14px;\n flex-shrink: 0;\n}\n\n.json-viewer {\n flex: 1;\n display: flex;\n flex-direction: column;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n overflow: hidden;\n min-height: 0;\n}\n\n.json-editor-container {\n flex: 1;\n overflow: hidden;\n min-height: 0;\n}\n\n.json-toolbar {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n padding: 8px 12px;\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.btn-icon {\n display: flex;\n align-items: center;\n gap: 6px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong);\n border-radius: 4px;\n padding: 6px 12px;\n cursor: pointer;\n color: var(--mj-text-secondary);\n font-size: 14px;\n transition: all 0.2s;\n}\n\n.btn-icon:hover {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-text-disabled);\n}\n\n.btn-icon.btn-primary {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.btn-icon.btn-primary:hover {\n background: var(--mj-brand-primary-hover);\n border-color: var(--mj-brand-primary-hover);\n}\n\n.btn-icon i {\n font-size: 14px;\n}\n\n/* Library Dialog Styles */\n.modal-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: var(--mj-bg-overlay);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 10000;\n}\n\n.modal-content {\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: var(--mj-shadow-lg);\n max-width: 500px;\n width: 90%;\n max-height: 90vh;\n display: flex;\n flex-direction: column;\n}\n\n.modal-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.modal-header h3 {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.modal-header h3 i {\n color: var(--mj-status-warning);\n}\n\n.modal-body {\n padding: 20px;\n overflow-y: auto;\n}\n\n.modal-footer {\n display: flex;\n justify-content: flex-end;\n gap: 12px;\n padding: 16px 20px;\n border-top: 1px solid var(--mj-border-default);\n}\n\n.form-section {\n margin-bottom: 20px;\n}\n\n.form-section label {\n display: block;\n margin-bottom: 8px;\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n}\n\n.form-select,\n.form-input {\n width: 100%;\n padding: 10px 12px;\n border: 1px solid var(--mj-border-strong);\n border-radius: 6px;\n font-size: 14px;\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n transition: border-color 0.2s;\n}\n\n.form-select:focus,\n.form-input:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.divider {\n display: flex;\n align-items: center;\n margin: 24px 0;\n color: var(--mj-text-disabled);\n font-size: 12px;\n font-weight: 500;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.divider::before,\n.divider::after {\n content: '';\n flex: 1;\n height: 1px;\n background: var(--mj-border-default);\n}\n\n.divider span {\n padding: 0 12px;\n}\n\n.create-collection-row {\n display: flex;\n gap: 8px;\n}\n\n.create-collection-row .form-input {\n flex: 1;\n}\n\n.btn {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 16px;\n border: none;\n border-radius: 6px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s;\n white-space: nowrap;\n}\n\n.btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.btn-primary {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.btn-primary:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n}\n\n.btn-secondary {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong);\n color: var(--mj-text-secondary);\n}\n\n.btn-secondary:hover:not(:disabled) {\n background: var(--mj-bg-surface-sunken);\n}\n\n/* Tab Navigation */\n.tab-navigation {\n display: flex;\n gap: 0;\n border-bottom: 2px solid var(--mj-border-default);\n padding: 0 16px;\n background: var(--mj-bg-surface);\n}\n\n.tab-btn {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 12px 20px;\n background: transparent;\n border: none;\n border-bottom: 2px solid transparent;\n margin-bottom: -2px;\n color: var(--mj-text-muted);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 150ms ease;\n}\n\n.tab-btn:hover {\n color: var(--mj-brand-primary);\n background: var(--mj-bg-surface-sunken);\n}\n\n.tab-btn.active {\n color: var(--mj-brand-primary);\n border-bottom-color: var(--mj-brand-primary);\n}\n\n.tab-btn i {\n font-size: 14px;\n}\n\n/* Tab Content */\n.tab-content {\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow: auto;\n width: 100%;\n box-sizing: border-box;\n margin-bottom: 5px;\n min-width: 0;\n min-height: 0;\n}\n\n/* Plugin Container */\n.plugin-container {\n width: 100%;\n height: 100%;\n min-height: 0;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n.plugin-container.plugin-hidden,\n.tab-hidden {\n display: none;\n}\n\n/* Ensure artifact viewer component takes full height */\n.plugin-container mj-artifact-type-plugin-viewer {\n display: flex;\n flex-direction: column;\n flex: 1;\n min-height: 0;\n width: 100%;\n}\n\n.display-content {\n flex: 1;\n display: flex;\n flex-direction: column;\n position: relative;\n width: 100%;\n box-sizing: border-box;\n overflow: hidden;\n min-height: 0;\n min-width: 0;\n padding: 7px;\n}\n\n.display-toolbar {\n position: absolute;\n top: 12px;\n right: 12px;\n display: flex;\n gap: 8px;\n z-index: 10;\n}\n\n.markdown-content,\n.html-content {\n flex: 1;\n font-size: 14px;\n line-height: 1.6;\n width: 100%;\n padding: 20px 10px 5px 20px; /* top right bottom left */\n box-sizing: border-box;\n overflow: auto;\n min-height: 0;\n}\n\n.details-content {\n padding: 20px;\n width: 100%;\n box-sizing: border-box;\n}\n\n.details-content .artifact-meta {\n margin-bottom: 0;\n padding: 20px;\n}\n\n.details-content .meta-item.full-width {\n grid-column: 1 / -1;\n}\n\n.attributes-section {\n margin-top: 24px;\n padding: 24px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 8px;\n}\n\n.attributes-section h4 {\n margin: 0 0 16px 0;\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.attributes-list {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));\n gap: 16px;\n}\n\n.attribute-item {\n display: flex;\n flex-direction: column;\n gap: 6px;\n padding: 12px;\n background: var(--mj-bg-surface);\n border-radius: 6px;\n border: 1px solid var(--mj-border-default);\n}\n\n.attribute-item label {\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.attribute-item span {\n font-size: 13px;\n color: var(--mj-text-primary);\n word-break: break-word;\n}\n\n.attribute-empty-pill {\n display: inline-block;\n padding: 2px 8px;\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-disabled);\n font-size: 11px;\n font-weight: 500;\n border-radius: 4px;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n/* Links Tab */\n.links-container {\n padding: 20px;\n}\n\n.links-section {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.link-item {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n transition: all 0.15s;\n}\n\n.link-item.clickable {\n cursor: pointer;\n}\n\n.link-item.clickable:hover {\n border-color: var(--mj-brand-primary);\n box-shadow: var(--mj-shadow-sm);\n background: var(--mj-bg-surface-sunken);\n}\n\n.link-item.disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.link-item:hover {\n border-color: var(--mj-brand-primary);\n box-shadow: var(--mj-shadow-sm);\n}\n\n.link-icon {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--mj-bg-surface);\n border-radius: 8px;\n flex-shrink: 0;\n}\n\n.link-icon i {\n font-size: 18px;\n color: var(--mj-brand-primary);\n}\n\n.link-content {\n flex: 1;\n min-width: 0;\n}\n\n.link-name {\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.link-type {\n font-size: 12px;\n color: var(--mj-text-muted);\n margin-top: 2px;\n}\n\n.link-actions {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 24px;\n height: 24px;\n flex-shrink: 0;\n}\n\n.link-actions i {\n font-size: 14px;\n color: var(--mj-text-muted);\n transition: all 0.15s;\n}\n\n.link-item.clickable:hover .link-actions i {\n color: var(--mj-brand-primary);\n transform: translateX(2px);\n}\n\n/* Dynamic Tab Content Styles */\n.dynamic-tab-content {\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n padding: 16px;\n}\n\n/* Custom component tab content */\n.component-tab-content {\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow: auto;\n padding: 16px;\n}\n\n.markdown-viewer {\n flex: 1;\n overflow: auto;\n padding: 20px;\n background: var(--mj-bg-surface);\n line-height: 1.6;\n}\n\n.markdown-viewer h1, .markdown-viewer h2, .markdown-viewer h3 {\n margin-top: 24px;\n margin-bottom: 12px;\n font-weight: 600;\n}\n\n.markdown-viewer h1 { font-size: 24px; }\n.markdown-viewer h2 { font-size: 20px; }\n.markdown-viewer h3 { font-size: 18px; }\n\n.markdown-viewer p {\n margin-bottom: 12px;\n}\n\n.markdown-viewer ul, .markdown-viewer ol {\n margin-bottom: 12px;\n padding-left: 24px;\n}\n\n.markdown-viewer code {\n background: var(--mj-bg-surface-sunken);\n padding: 2px 6px;\n border-radius: 3px;\n font-family: 'Courier New', monospace;\n font-size: 13px;\n}\n\n.markdown-viewer pre {\n background: var(--mj-bg-surface-sunken);\n padding: 12px;\n border-radius: 6px;\n overflow-x: auto;\n margin-bottom: 12px;\n}\n\n.markdown-viewer pre code {\n background: none;\n padding: 0;\n}\n\n.code-viewer {\n flex: 1;\n display: flex;\n flex-direction: column;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n overflow: hidden;\n min-height: 0;\n}\n\n.code-toolbar {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n padding: 8px 12px;\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.code-editor-container {\n flex: 1;\n overflow: hidden;\n min-height: 0;\n}\n\n.plaintext-viewer {\n flex: 1;\n overflow: auto;\n padding: 12px;\n background: var(--mj-bg-surface-sunken);\n font-family: 'Courier New', monospace;\n font-size: 13px;\n white-space: pre-wrap;\n}\n\n.html-viewer {\n flex: 1;\n overflow: auto;\n padding: 20px;\n background: var(--mj-bg-surface);\n}\n\n/* Mobile adjustments: 481px - 768px */\n@media (max-width: 768px) {\n /* Add top border with slight visual separation from top nav */\n .artifact-viewer-panel {\n border-top: 3px solid var(--mj-brand-primary);\n position: relative;\n }\n\n /* Create a small dark strip above the blue border to separate from top nav */\n .artifact-viewer-panel::before {\n content: '';\n position: absolute;\n top: -8px;\n left: 0;\n right: 0;\n height: 8px;\n background: var(--mj-brand-secondary);\n }\n\n .tab-navigation {\n padding: 0 8px;\n overflow-x: auto;\n overflow-y: hidden;\n -webkit-overflow-scrolling: touch;\n scrollbar-width: none;\n }\n\n .tab-navigation::-webkit-scrollbar {\n display: none;\n }\n\n .tab-btn {\n padding: 10px 12px;\n font-size: 12px;\n white-space: nowrap;\n flex-shrink: 0;\n }\n\n .tab-btn i {\n font-size: 13px;\n }\n\n .panel-header {\n padding: 12px;\n }\n\n .dynamic-tab-content {\n padding: 12px;\n }\n\n .markdown-viewer {\n padding: 12px;\n }\n}\n\n/* Small Phone adjustments: <= 480px */\n@media (max-width: 480px) {\n .tab-navigation {\n padding: 0 4px;\n }\n\n .tab-btn {\n padding: 8px 10px;\n font-size: 11px;\n gap: 4px;\n }\n\n .tab-btn i {\n font-size: 12px;\n }\n\n .panel-header {\n padding: 8px;\n }\n\n .dynamic-tab-content {\n padding: 8px;\n }\n\n .markdown-viewer {\n padding: 8px;\n }\n}\n\n/* No-plugin fallback: a file card with a download action, text underneath when it is text-like */\n.file-fallback { display: flex; flex-direction: column; gap: var(--mj-space-3, 12px); padding: var(--mj-space-4, 16px); }\n.file-fallback-card {\n display: flex; align-items: center; gap: var(--mj-space-3, 12px);\n padding: var(--mj-space-3, 12px) var(--mj-space-4, 16px);\n border: 1px solid var(--mj-border-default); border-radius: var(--mj-radius-md, 8px);\n background: var(--mj-bg-surface-card, var(--mj-bg-surface));\n}\n.file-fallback-card > i { font-size: 1.5rem; color: var(--mj-brand-primary); }\n.file-fallback-meta { flex: 1; min-width: 0; }\n.file-fallback-name { font-weight: var(--mj-font-semibold, 600); color: var(--mj-text-primary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n.file-fallback-sub { font-size: var(--mj-text-sm, 0.85rem); color: var(--mj-text-muted); }\n.file-fallback-text { max-height: 60vh; overflow: auto; margin: 0; }\n"] }]
1984
+ }], () => [{ type: i0.ChangeDetectorRef }, { type: i1.MJNotificationService }, { type: i2.DomSanitizer }, { type: i3.ArtifactIconService }, { type: i4.ArtifactFileService }], { artifactId: [{
1791
1985
  type: Input
1792
1986
  }], currentUser: [{
1793
1987
  type: Input
@@ -1839,5 +2033,5 @@ export class ArtifactViewerPanelComponent extends BaseAngularComponent {
1839
2033
  type: ViewChild,
1840
2034
  args: [ArtifactTypePluginViewerComponent]
1841
2035
  }] }); })();
1842
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ArtifactViewerPanelComponent, { className: "ArtifactViewerPanelComponent", filePath: "src/lib/components/artifact-viewer-panel.component.ts", lineNumber: 21 }); })();
2036
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ArtifactViewerPanelComponent, { className: "ArtifactViewerPanelComponent", filePath: "src/lib/components/artifact-viewer-panel.component.ts", lineNumber: 22 }); })();
1843
2037
  //# sourceMappingURL=artifact-viewer-panel.component.js.map