@memberjunction/ng-core-entity-forms 5.33.0 → 5.34.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. package/dist/lib/custom/AIAgents/ai-agent-form.component.d.ts +30 -0
  2. package/dist/lib/custom/AIAgents/ai-agent-form.component.d.ts.map +1 -1
  3. package/dist/lib/custom/AIAgents/ai-agent-form.component.js +944 -645
  4. package/dist/lib/custom/AIAgents/ai-agent-form.component.js.map +1 -1
  5. package/dist/lib/custom/SearchScopes/searchscope-form.component.d.ts +137 -0
  6. package/dist/lib/custom/SearchScopes/searchscope-form.component.d.ts.map +1 -0
  7. package/dist/lib/custom/SearchScopes/searchscope-form.component.js +888 -0
  8. package/dist/lib/custom/SearchScopes/searchscope-form.component.js.map +1 -0
  9. package/dist/lib/custom/SearchScopes/searchscopeprovider-form.component.d.ts +66 -0
  10. package/dist/lib/custom/SearchScopes/searchscopeprovider-form.component.d.ts.map +1 -0
  11. package/dist/lib/custom/SearchScopes/searchscopeprovider-form.component.js +253 -0
  12. package/dist/lib/custom/SearchScopes/searchscopeprovider-form.component.js.map +1 -0
  13. package/dist/lib/custom/Tests/test-rubric-form.component.js +2 -2
  14. package/dist/lib/custom/Tests/test-rubric-form.component.js.map +1 -1
  15. package/dist/lib/custom/Tests/test-suite-form.component.js +2 -2
  16. package/dist/lib/custom/Tests/test-suite-form.component.js.map +1 -1
  17. package/dist/lib/custom/custom-forms.module.d.ts +28 -25
  18. package/dist/lib/custom/custom-forms.module.d.ts.map +1 -1
  19. package/dist/lib/custom/custom-forms.module.js +18 -4
  20. package/dist/lib/custom/custom-forms.module.js.map +1 -1
  21. package/dist/lib/custom/shared/entity-selector-dialog.component.js +2 -2
  22. package/dist/lib/custom/shared/entity-selector-dialog.component.js.map +1 -1
  23. package/dist/lib/generated/Entities/MJAIAgent/mjaiagent.form.component.d.ts.map +1 -1
  24. package/dist/lib/generated/Entities/MJAIAgent/mjaiagent.form.component.js +111 -79
  25. package/dist/lib/generated/Entities/MJAIAgent/mjaiagent.form.component.js.map +1 -1
  26. package/dist/lib/generated/Entities/MJAIAgentSearchScope/mjaiagentsearchscope.form.component.d.ts +10 -0
  27. package/dist/lib/generated/Entities/MJAIAgentSearchScope/mjaiagentsearchscope.form.component.d.ts.map +1 -0
  28. package/dist/lib/generated/Entities/MJAIAgentSearchScope/mjaiagentsearchscope.form.component.js +93 -0
  29. package/dist/lib/generated/Entities/MJAIAgentSearchScope/mjaiagentsearchscope.form.component.js.map +1 -0
  30. package/dist/lib/generated/Entities/MJAIResultCache/mjairesultcache.form.component.js +2 -2
  31. package/dist/lib/generated/Entities/MJAIResultCache/mjairesultcache.form.component.js.map +1 -1
  32. package/dist/lib/generated/Entities/MJEntity/mjentity.form.component.d.ts.map +1 -1
  33. package/dist/lib/generated/Entities/MJEntity/mjentity.form.component.js +89 -71
  34. package/dist/lib/generated/Entities/MJEntity/mjentity.form.component.js.map +1 -1
  35. package/dist/lib/generated/Entities/MJEntityField/mjentityfield.form.component.js +23 -21
  36. package/dist/lib/generated/Entities/MJEntityField/mjentityfield.form.component.js.map +1 -1
  37. package/dist/lib/generated/Entities/MJFileStorageAccount/mjfilestorageaccount.form.component.d.ts.map +1 -1
  38. package/dist/lib/generated/Entities/MJFileStorageAccount/mjfilestorageaccount.form.component.js +33 -15
  39. package/dist/lib/generated/Entities/MJFileStorageAccount/mjfilestorageaccount.form.component.js.map +1 -1
  40. package/dist/lib/generated/Entities/MJRole/mjrole.form.component.d.ts.map +1 -1
  41. package/dist/lib/generated/Entities/MJRole/mjrole.form.component.js +31 -13
  42. package/dist/lib/generated/Entities/MJRole/mjrole.form.component.js.map +1 -1
  43. package/dist/lib/generated/Entities/MJSearchExecutionLog/mjsearchexecutionlog.form.component.d.ts +10 -0
  44. package/dist/lib/generated/Entities/MJSearchExecutionLog/mjsearchexecutionlog.form.component.d.ts.map +1 -0
  45. package/dist/lib/generated/Entities/MJSearchExecutionLog/mjsearchexecutionlog.form.component.js +91 -0
  46. package/dist/lib/generated/Entities/MJSearchExecutionLog/mjsearchexecutionlog.form.component.js.map +1 -0
  47. package/dist/lib/generated/Entities/MJSearchProvider/mjsearchprovider.form.component.d.ts.map +1 -1
  48. package/dist/lib/generated/Entities/MJSearchProvider/mjsearchprovider.form.component.js +23 -5
  49. package/dist/lib/generated/Entities/MJSearchProvider/mjsearchprovider.form.component.js.map +1 -1
  50. package/dist/lib/generated/Entities/MJSearchScope/mjsearchscope.form.component.d.ts +10 -0
  51. package/dist/lib/generated/Entities/MJSearchScope/mjsearchscope.form.component.d.ts.map +1 -0
  52. package/dist/lib/generated/Entities/MJSearchScope/mjsearchscope.form.component.js +243 -0
  53. package/dist/lib/generated/Entities/MJSearchScope/mjsearchscope.form.component.js.map +1 -0
  54. package/dist/lib/generated/Entities/MJSearchScopeEntity/mjsearchscopeentity.form.component.d.ts +10 -0
  55. package/dist/lib/generated/Entities/MJSearchScopeEntity/mjsearchscopeentity.form.component.d.ts.map +1 -0
  56. package/dist/lib/generated/Entities/MJSearchScopeEntity/mjsearchscopeentity.form.component.js +71 -0
  57. package/dist/lib/generated/Entities/MJSearchScopeEntity/mjsearchscopeentity.form.component.js.map +1 -0
  58. package/dist/lib/generated/Entities/MJSearchScopeExternalIndex/mjsearchscopeexternalindex.form.component.d.ts +10 -0
  59. package/dist/lib/generated/Entities/MJSearchScopeExternalIndex/mjsearchscopeexternalindex.form.component.d.ts.map +1 -0
  60. package/dist/lib/generated/Entities/MJSearchScopeExternalIndex/mjsearchscopeexternalindex.form.component.js +75 -0
  61. package/dist/lib/generated/Entities/MJSearchScopeExternalIndex/mjsearchscopeexternalindex.form.component.js.map +1 -0
  62. package/dist/lib/generated/Entities/MJSearchScopePermission/mjsearchscopepermission.form.component.d.ts +10 -0
  63. package/dist/lib/generated/Entities/MJSearchScopePermission/mjsearchscopepermission.form.component.d.ts.map +1 -0
  64. package/dist/lib/generated/Entities/MJSearchScopePermission/mjsearchscopepermission.form.component.js +65 -0
  65. package/dist/lib/generated/Entities/MJSearchScopePermission/mjsearchscopepermission.form.component.js.map +1 -0
  66. package/dist/lib/generated/Entities/MJSearchScopeProvider/mjsearchscopeprovider.form.component.d.ts +10 -0
  67. package/dist/lib/generated/Entities/MJSearchScopeProvider/mjsearchscopeprovider.form.component.d.ts.map +1 -0
  68. package/dist/lib/generated/Entities/MJSearchScopeProvider/mjsearchscopeprovider.form.component.js +75 -0
  69. package/dist/lib/generated/Entities/MJSearchScopeProvider/mjsearchscopeprovider.form.component.js.map +1 -0
  70. package/dist/lib/generated/Entities/MJSearchScopeStorageAccount/mjsearchscopestorageaccount.form.component.d.ts +10 -0
  71. package/dist/lib/generated/Entities/MJSearchScopeStorageAccount/mjsearchscopestorageaccount.form.component.d.ts.map +1 -0
  72. package/dist/lib/generated/Entities/MJSearchScopeStorageAccount/mjsearchscopestorageaccount.form.component.js +63 -0
  73. package/dist/lib/generated/Entities/MJSearchScopeStorageAccount/mjsearchscopestorageaccount.form.component.js.map +1 -0
  74. package/dist/lib/generated/Entities/MJSearchScopeTestQuery/mjsearchscopetestquery.form.component.d.ts +10 -0
  75. package/dist/lib/generated/Entities/MJSearchScopeTestQuery/mjsearchscopetestquery.form.component.d.ts.map +1 -0
  76. package/dist/lib/generated/Entities/MJSearchScopeTestQuery/mjsearchscopetestquery.form.component.js +75 -0
  77. package/dist/lib/generated/Entities/MJSearchScopeTestQuery/mjsearchscopetestquery.form.component.js.map +1 -0
  78. package/dist/lib/generated/Entities/MJTag/mjtag.form.component.js +9 -9
  79. package/dist/lib/generated/Entities/MJTag/mjtag.form.component.js.map +1 -1
  80. package/dist/lib/generated/Entities/MJTemplate/mjtemplate.form.component.d.ts.map +1 -1
  81. package/dist/lib/generated/Entities/MJTemplate/mjtemplate.form.component.js +46 -10
  82. package/dist/lib/generated/Entities/MJTemplate/mjtemplate.form.component.js.map +1 -1
  83. package/dist/lib/generated/Entities/MJUser/mjuser.form.component.d.ts.map +1 -1
  84. package/dist/lib/generated/Entities/MJUser/mjuser.form.component.js +223 -169
  85. package/dist/lib/generated/Entities/MJUser/mjuser.form.component.js.map +1 -1
  86. package/dist/lib/generated/Entities/MJVectorIndex/mjvectorindex.form.component.d.ts.map +1 -1
  87. package/dist/lib/generated/Entities/MJVectorIndex/mjvectorindex.form.component.js +32 -14
  88. package/dist/lib/generated/Entities/MJVectorIndex/mjvectorindex.form.component.js.map +1 -1
  89. package/dist/lib/generated/generated-forms.module.d.ts +312 -298
  90. package/dist/lib/generated/generated-forms.module.d.ts.map +1 -1
  91. package/dist/lib/generated/generated-forms.module.js +168 -111
  92. package/dist/lib/generated/generated-forms.module.js.map +1 -1
  93. package/package.json +36 -35
@@ -0,0 +1,888 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var MJSearchScopeFormComponentExtended_1;
8
+ /**
9
+ * Custom SearchScope form (P2D.7 Angular half).
10
+ *
11
+ * Adds a "Reranker" custom section that:
12
+ * - Renders a dropdown of registered rerankers — currently a hardcoded list
13
+ * mirroring `BaseReRanker.GetAvailableRerankers()` server-side, with each
14
+ * option's HasCost flag surfaced inline so authors can see at a glance
15
+ * which options will incur API spend.
16
+ * - Reads / writes the current selection from `record.ScopeConfig` JSON's
17
+ * `reRanker.driverClass` key — same path the SearchEngine reads at runtime.
18
+ *
19
+ * **Discovery follow-up:** the canonical source of available rerankers is
20
+ * `BaseReRanker.GetAvailableRerankers()` in `@memberjunction/search-engine`,
21
+ * but that's a Node-only package and can't be imported in the browser.
22
+ * A small GraphQL query (e.g. `AvailableRerankers`) on MJServer that calls
23
+ * the helper server-side would let this dropdown auto-discover any
24
+ * third-party reranker registered with ClassFactory. Tracked as a follow-up
25
+ * — for now the hardcoded list covers the 5 rerankers shipped in Phase 2D.
26
+ *
27
+ * The CodeGen-generated `RerankerBudgetCents` numeric input is already on
28
+ * the form (in the "Details" section); we don't need to recreate it.
29
+ * The dropdown above + budget input below give scope authors the full
30
+ * Phase 2D configuration surface.
31
+ */
32
+ import { Component } from '@angular/core';
33
+ import { LogError, RunView } from '@memberjunction/core';
34
+ import { RegisterClass } from '@memberjunction/global';
35
+ import { BaseFormComponent } from '@memberjunction/ng-base-forms';
36
+ import { SearchService } from '@memberjunction/ng-search';
37
+ import { MJSearchScopeFormComponent } from '../../generated/Entities/MJSearchScope/mjsearchscope.form.component';
38
+ import * as i0 from "@angular/core";
39
+ import * as i1 from "@angular/forms";
40
+ import * as i2 from "@memberjunction/ng-base-forms";
41
+ import * as i3 from "@angular/common";
42
+ const _forTrack0 = ($index, $item) => $item.Key;
43
+ const _forTrack1 = ($index, $item) => $item.DriverClass;
44
+ const _forTrack2 = ($index, $item) => $item.Name;
45
+ const _forTrack3 = ($index, $item) => $item.ID;
46
+ function MJSearchScopeFormComponentExtended_For_20_Template(rf, ctx) { if (rf & 1) {
47
+ const _r1 = i0.ɵɵgetCurrentView();
48
+ i0.ɵɵelementStart(0, "div", 19)(1, "span", 54);
49
+ i0.ɵɵtext(2);
50
+ i0.ɵɵelementEnd();
51
+ i0.ɵɵelementStart(3, "input", 55);
52
+ i0.ɵɵlistener("change", function MJSearchScopeFormComponentExtended_For_20_Template_input_change_3_listener($event) { const row_r2 = i0.ɵɵrestoreView(_r1).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OnFusionWeightChanged(row_r2, $event.target.valueAsNumber)); });
53
+ i0.ɵɵelementEnd();
54
+ i0.ɵɵelementStart(4, "span", 56);
55
+ i0.ɵɵtext(5);
56
+ i0.ɵɵpipe(6, "number");
57
+ i0.ɵɵelementEnd()();
58
+ } if (rf & 2) {
59
+ const row_r2 = ctx.$implicit;
60
+ const ctx_r2 = i0.ɵɵnextContext();
61
+ i0.ɵɵadvance(2);
62
+ i0.ɵɵtextInterpolate(row_r2.Label);
63
+ i0.ɵɵadvance();
64
+ i0.ɵɵproperty("disabled", !ctx_r2.EditMode)("value", row_r2.Weight);
65
+ i0.ɵɵadvance(2);
66
+ i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(6, 4, row_r2.Weight, "1.1-1"));
67
+ } }
68
+ function MJSearchScopeFormComponentExtended_For_34_Template(rf, ctx) { if (rf & 1) {
69
+ i0.ɵɵelementStart(0, "option", 26);
70
+ i0.ɵɵtext(1);
71
+ i0.ɵɵelementEnd();
72
+ } if (rf & 2) {
73
+ const option_r4 = ctx.$implicit;
74
+ i0.ɵɵproperty("value", option_r4.DriverClass);
75
+ i0.ɵɵadvance();
76
+ i0.ɵɵtextInterpolate2(" ", option_r4.Name, "", option_r4.HasCost ? " \u2014 paid" : " \u2014 free", " ");
77
+ } }
78
+ function MJSearchScopeFormComponentExtended_Conditional_35_Template(rf, ctx) { if (rf & 1) {
79
+ i0.ɵɵelementStart(0, "p", 27);
80
+ i0.ɵɵelement(1, "i", 57);
81
+ i0.ɵɵtext(2, " This reranker incurs API cost per search. Set ");
82
+ i0.ɵɵelementStart(3, "strong");
83
+ i0.ɵɵtext(4, "RerankerBudgetCents");
84
+ i0.ɵɵelementEnd();
85
+ i0.ɵɵtext(5, " below to cap spend per invocation. ");
86
+ i0.ɵɵelementEnd();
87
+ } }
88
+ function MJSearchScopeFormComponentExtended_Conditional_44_Template(rf, ctx) { if (rf & 1) {
89
+ i0.ɵɵelement(0, "i", 58);
90
+ i0.ɵɵelementStart(1, "span");
91
+ i0.ɵɵtext(2, "Exporting\u2026");
92
+ i0.ɵɵelementEnd();
93
+ } }
94
+ function MJSearchScopeFormComponentExtended_Conditional_45_Template(rf, ctx) { if (rf & 1) {
95
+ i0.ɵɵelement(0, "i", 59);
96
+ i0.ɵɵelementStart(1, "span");
97
+ i0.ɵɵtext(2, "Export tuning data (CSV)");
98
+ i0.ɵɵelementEnd();
99
+ } }
100
+ function MJSearchScopeFormComponentExtended_Conditional_52_Template(rf, ctx) { if (rf & 1) {
101
+ const _r5 = i0.ɵɵgetCurrentView();
102
+ i0.ɵɵelementStart(0, "button", 60);
103
+ i0.ɵɵlistener("click", function MJSearchScopeFormComponentExtended_Conditional_52_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r5); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.RunPreview()); });
104
+ i0.ɵɵelement(1, "i", 61);
105
+ i0.ɵɵtext(2, " Run ");
106
+ i0.ɵɵelementEnd();
107
+ } if (rf & 2) {
108
+ const ctx_r2 = i0.ɵɵnextContext();
109
+ i0.ɵɵproperty("disabled", !(ctx_r2.record == null ? null : ctx_r2.record.ID) || !ctx_r2.PreviewQuery.trim());
110
+ } }
111
+ function MJSearchScopeFormComponentExtended_Conditional_53_Template(rf, ctx) { if (rf & 1) {
112
+ const _r6 = i0.ɵɵgetCurrentView();
113
+ i0.ɵɵelementStart(0, "button", 62);
114
+ i0.ɵɵlistener("click", function MJSearchScopeFormComponentExtended_Conditional_53_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r6); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.CancelPreview()); });
115
+ i0.ɵɵelement(1, "i", 63);
116
+ i0.ɵɵtext(2, " Cancel ");
117
+ i0.ɵɵelementEnd();
118
+ } }
119
+ function MJSearchScopeFormComponentExtended_Conditional_54_Template(rf, ctx) { if (rf & 1) {
120
+ i0.ɵɵelementStart(0, "p", 39);
121
+ i0.ɵɵelement(1, "i", 64);
122
+ i0.ɵɵtext(2);
123
+ i0.ɵɵelementEnd();
124
+ } if (rf & 2) {
125
+ const ctx_r2 = i0.ɵɵnextContext();
126
+ i0.ɵɵadvance(2);
127
+ i0.ɵɵtextInterpolate1(" ", ctx_r2.PreviewError, " ");
128
+ } }
129
+ function MJSearchScopeFormComponentExtended_Conditional_55_Conditional_1_Template(rf, ctx) { if (rf & 1) {
130
+ i0.ɵɵelementStart(0, "span", 65);
131
+ i0.ɵɵelement(1, "i", 67);
132
+ i0.ɵɵtext(2, " Streaming\u2026 ");
133
+ i0.ɵɵelementEnd();
134
+ } }
135
+ function MJSearchScopeFormComponentExtended_Conditional_55_For_3_Template(rf, ctx) { if (rf & 1) {
136
+ i0.ɵɵelementStart(0, "span", 66);
137
+ i0.ɵɵelement(1, "i", 68);
138
+ i0.ɵɵelementStart(2, "strong");
139
+ i0.ɵɵtext(3);
140
+ i0.ɵɵelementEnd();
141
+ i0.ɵɵelementStart(4, "span", 69);
142
+ i0.ɵɵtext(5);
143
+ i0.ɵɵelementEnd();
144
+ i0.ɵɵelementStart(6, "span", 70);
145
+ i0.ɵɵtext(7);
146
+ i0.ɵɵelementEnd()();
147
+ } if (rf & 2) {
148
+ const p_r7 = ctx.$implicit;
149
+ i0.ɵɵadvance(3);
150
+ i0.ɵɵtextInterpolate(p_r7.Name);
151
+ i0.ɵɵadvance(2);
152
+ i0.ɵɵtextInterpolate(p_r7.Count);
153
+ i0.ɵɵadvance(2);
154
+ i0.ɵɵtextInterpolate1("", p_r7.ElapsedMs, "ms");
155
+ } }
156
+ function MJSearchScopeFormComponentExtended_Conditional_55_Template(rf, ctx) { if (rf & 1) {
157
+ i0.ɵɵelementStart(0, "div", 40);
158
+ i0.ɵɵconditionalCreate(1, MJSearchScopeFormComponentExtended_Conditional_55_Conditional_1_Template, 3, 0, "span", 65);
159
+ i0.ɵɵrepeaterCreate(2, MJSearchScopeFormComponentExtended_Conditional_55_For_3_Template, 8, 3, "span", 66, _forTrack2);
160
+ i0.ɵɵelementEnd();
161
+ } if (rf & 2) {
162
+ const ctx_r2 = i0.ɵɵnextContext();
163
+ i0.ɵɵadvance();
164
+ i0.ɵɵconditional(ctx_r2.PreviewIsRunning && ctx_r2.PreviewProviders.length === 0 ? 1 : -1);
165
+ i0.ɵɵadvance();
166
+ i0.ɵɵrepeater(ctx_r2.PreviewProviders);
167
+ } }
168
+ function MJSearchScopeFormComponentExtended_Conditional_56_Conditional_3_Template(rf, ctx) { if (rf & 1) {
169
+ i0.ɵɵtext(0);
170
+ } if (rf & 2) {
171
+ const ctx_r2 = i0.ɵɵnextContext(2);
172
+ i0.ɵɵtextInterpolate1(" in ", ctx_r2.PreviewElapsedMs, "ms ");
173
+ } }
174
+ function MJSearchScopeFormComponentExtended_Conditional_56_Conditional_4_Template(rf, ctx) { if (rf & 1) {
175
+ i0.ɵɵelementStart(0, "span", 74);
176
+ i0.ɵɵtext(1);
177
+ i0.ɵɵelementEnd();
178
+ } if (rf & 2) {
179
+ const ctx_r2 = i0.ɵɵnextContext(2);
180
+ i0.ɵɵclassProp("live-preview-similarity-low", ctx_r2.LastRunSimilarityPercent < 70);
181
+ i0.ɵɵadvance();
182
+ i0.ɵɵtextInterpolate1(" \u00B7 ", ctx_r2.LastRunSimilarityPercent, "% similar to last run ");
183
+ } }
184
+ function MJSearchScopeFormComponentExtended_Conditional_56_For_6_Conditional_0_Template(rf, ctx) { if (rf & 1) {
185
+ i0.ɵɵelementStart(0, "div", 75)(1, "span", 76);
186
+ i0.ɵɵtext(2);
187
+ i0.ɵɵpipe(3, "number");
188
+ i0.ɵɵelementEnd();
189
+ i0.ɵɵelementStart(4, "span", 77);
190
+ i0.ɵɵtext(5);
191
+ i0.ɵɵelementEnd();
192
+ i0.ɵɵelementStart(6, "span", 78);
193
+ i0.ɵɵtext(7);
194
+ i0.ɵɵelementEnd()();
195
+ } if (rf & 2) {
196
+ const r_r8 = i0.ɵɵnextContext().$implicit;
197
+ i0.ɵɵadvance(2);
198
+ i0.ɵɵtextInterpolate1("", i0.ɵɵpipeBind2(3, 3, r_r8.Score * 100, "1.0-0"), "%");
199
+ i0.ɵɵadvance(3);
200
+ i0.ɵɵtextInterpolate(r_r8.Title);
201
+ i0.ɵɵadvance(2);
202
+ i0.ɵɵtextInterpolate(r_r8.EntityName);
203
+ } }
204
+ function MJSearchScopeFormComponentExtended_Conditional_56_For_6_Template(rf, ctx) { if (rf & 1) {
205
+ i0.ɵɵconditionalCreate(0, MJSearchScopeFormComponentExtended_Conditional_56_For_6_Conditional_0_Template, 8, 6, "div", 75);
206
+ } if (rf & 2) {
207
+ const ɵ$index_173_r9 = ctx.$index;
208
+ i0.ɵɵconditional(ɵ$index_173_r9 < 10 ? 0 : -1);
209
+ } }
210
+ function MJSearchScopeFormComponentExtended_Conditional_56_Conditional_7_Template(rf, ctx) { if (rf & 1) {
211
+ i0.ɵɵelementStart(0, "p", 73);
212
+ i0.ɵɵtext(1);
213
+ i0.ɵɵelementEnd();
214
+ } if (rf & 2) {
215
+ const ctx_r2 = i0.ɵɵnextContext(2);
216
+ i0.ɵɵadvance();
217
+ i0.ɵɵtextInterpolate1("\u2026and ", ctx_r2.PreviewResults.length - 10, " more (preview shows top 10).");
218
+ } }
219
+ function MJSearchScopeFormComponentExtended_Conditional_56_Template(rf, ctx) { if (rf & 1) {
220
+ i0.ɵɵelementStart(0, "div", 41)(1, "div", 71);
221
+ i0.ɵɵtext(2);
222
+ i0.ɵɵconditionalCreate(3, MJSearchScopeFormComponentExtended_Conditional_56_Conditional_3_Template, 1, 1);
223
+ i0.ɵɵconditionalCreate(4, MJSearchScopeFormComponentExtended_Conditional_56_Conditional_4_Template, 2, 3, "span", 72);
224
+ i0.ɵɵelementEnd();
225
+ i0.ɵɵrepeaterCreate(5, MJSearchScopeFormComponentExtended_Conditional_56_For_6_Template, 1, 1, null, null, _forTrack3);
226
+ i0.ɵɵconditionalCreate(7, MJSearchScopeFormComponentExtended_Conditional_56_Conditional_7_Template, 2, 1, "p", 73);
227
+ i0.ɵɵelementEnd();
228
+ } if (rf & 2) {
229
+ const ctx_r2 = i0.ɵɵnextContext();
230
+ i0.ɵɵadvance(2);
231
+ i0.ɵɵtextInterpolate1(" ", ctx_r2.PreviewResults.length, " result(s) ");
232
+ i0.ɵɵadvance();
233
+ i0.ɵɵconditional(ctx_r2.PreviewElapsedMs !== null ? 3 : -1);
234
+ i0.ɵɵadvance();
235
+ i0.ɵɵconditional(ctx_r2.LastRunSimilarityPercent !== null ? 4 : -1);
236
+ i0.ɵɵadvance();
237
+ i0.ɵɵrepeater(ctx_r2.PreviewResults);
238
+ i0.ɵɵadvance(2);
239
+ i0.ɵɵconditional(ctx_r2.PreviewResults.length > 10 ? 7 : -1);
240
+ } }
241
+ function MJSearchScopeFormComponentExtended_Conditional_62_Template(rf, ctx) { if (rf & 1) {
242
+ const _r10 = i0.ɵɵgetCurrentView();
243
+ i0.ɵɵelementStart(0, "div")(1, "mj-explorer-entity-data-grid", 79);
244
+ i0.ɵɵlistener("Navigate", function MJSearchScopeFormComponentExtended_Conditional_62_Template_mj_explorer_entity_data_grid_Navigate_1_listener($event) { i0.ɵɵrestoreView(_r10); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OnFormNavigate($event)); })("AfterDataLoad", function MJSearchScopeFormComponentExtended_Conditional_62_Template_mj_explorer_entity_data_grid_AfterDataLoad_1_listener($event) { i0.ɵɵrestoreView(_r10); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.SetSectionRowCount("mJSearchScopeTestQueries", $event.totalRowCount)); });
245
+ i0.ɵɵelementEnd()();
246
+ } if (rf & 2) {
247
+ const ctx_r2 = i0.ɵɵnextContext();
248
+ i0.ɵɵadvance();
249
+ i0.ɵɵproperty("Params", ctx_r2.BuildRelationshipViewParamsByEntityName("MJ: Search Scope Test Queries", "SearchScopeID"))("NewRecordValues", ctx_r2.NewRecordValues("MJ: Search Scope Test Queries"))("AllowLoad", ctx_r2.IsSectionExpanded("mJSearchScopeTestQueries"))("ShowToolbar", true);
250
+ } }
251
+ function MJSearchScopeFormComponentExtended_Conditional_64_Template(rf, ctx) { if (rf & 1) {
252
+ const _r11 = i0.ɵɵgetCurrentView();
253
+ i0.ɵɵelementStart(0, "div")(1, "mj-explorer-entity-data-grid", 79);
254
+ i0.ɵɵlistener("Navigate", function MJSearchScopeFormComponentExtended_Conditional_64_Template_mj_explorer_entity_data_grid_Navigate_1_listener($event) { i0.ɵɵrestoreView(_r11); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OnFormNavigate($event)); })("AfterDataLoad", function MJSearchScopeFormComponentExtended_Conditional_64_Template_mj_explorer_entity_data_grid_AfterDataLoad_1_listener($event) { i0.ɵɵrestoreView(_r11); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.SetSectionRowCount("mJSearchScopeStorageAccounts", $event.totalRowCount)); });
255
+ i0.ɵɵelementEnd()();
256
+ } if (rf & 2) {
257
+ const ctx_r2 = i0.ɵɵnextContext();
258
+ i0.ɵɵadvance();
259
+ i0.ɵɵproperty("Params", ctx_r2.BuildRelationshipViewParamsByEntityName("MJ: Search Scope Storage Accounts", "SearchScopeID"))("NewRecordValues", ctx_r2.NewRecordValues("MJ: Search Scope Storage Accounts"))("AllowLoad", ctx_r2.IsSectionExpanded("mJSearchScopeStorageAccounts"))("ShowToolbar", true);
260
+ } }
261
+ function MJSearchScopeFormComponentExtended_Conditional_66_Template(rf, ctx) { if (rf & 1) {
262
+ const _r12 = i0.ɵɵgetCurrentView();
263
+ i0.ɵɵelementStart(0, "div")(1, "mj-explorer-entity-data-grid", 79);
264
+ i0.ɵɵlistener("Navigate", function MJSearchScopeFormComponentExtended_Conditional_66_Template_mj_explorer_entity_data_grid_Navigate_1_listener($event) { i0.ɵɵrestoreView(_r12); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OnFormNavigate($event)); })("AfterDataLoad", function MJSearchScopeFormComponentExtended_Conditional_66_Template_mj_explorer_entity_data_grid_AfterDataLoad_1_listener($event) { i0.ɵɵrestoreView(_r12); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.SetSectionRowCount("mJSearchScopeEntities", $event.totalRowCount)); });
265
+ i0.ɵɵelementEnd()();
266
+ } if (rf & 2) {
267
+ const ctx_r2 = i0.ɵɵnextContext();
268
+ i0.ɵɵadvance();
269
+ i0.ɵɵproperty("Params", ctx_r2.BuildRelationshipViewParamsByEntityName("MJ: Search Scope Entities", "SearchScopeID"))("NewRecordValues", ctx_r2.NewRecordValues("MJ: Search Scope Entities"))("AllowLoad", ctx_r2.IsSectionExpanded("mJSearchScopeEntities"))("ShowToolbar", true);
270
+ } }
271
+ function MJSearchScopeFormComponentExtended_Conditional_68_Template(rf, ctx) { if (rf & 1) {
272
+ const _r13 = i0.ɵɵgetCurrentView();
273
+ i0.ɵɵelementStart(0, "div")(1, "mj-explorer-entity-data-grid", 79);
274
+ i0.ɵɵlistener("Navigate", function MJSearchScopeFormComponentExtended_Conditional_68_Template_mj_explorer_entity_data_grid_Navigate_1_listener($event) { i0.ɵɵrestoreView(_r13); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OnFormNavigate($event)); })("AfterDataLoad", function MJSearchScopeFormComponentExtended_Conditional_68_Template_mj_explorer_entity_data_grid_AfterDataLoad_1_listener($event) { i0.ɵɵrestoreView(_r13); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.SetSectionRowCount("mJSearchScopeExternalIndexes", $event.totalRowCount)); });
275
+ i0.ɵɵelementEnd()();
276
+ } if (rf & 2) {
277
+ const ctx_r2 = i0.ɵɵnextContext();
278
+ i0.ɵɵadvance();
279
+ i0.ɵɵproperty("Params", ctx_r2.BuildRelationshipViewParamsByEntityName("MJ: Search Scope External Indexes", "SearchScopeID"))("NewRecordValues", ctx_r2.NewRecordValues("MJ: Search Scope External Indexes"))("AllowLoad", ctx_r2.IsSectionExpanded("mJSearchScopeExternalIndexes"))("ShowToolbar", true);
280
+ } }
281
+ function MJSearchScopeFormComponentExtended_Conditional_70_Template(rf, ctx) { if (rf & 1) {
282
+ const _r14 = i0.ɵɵgetCurrentView();
283
+ i0.ɵɵelementStart(0, "div")(1, "mj-explorer-entity-data-grid", 79);
284
+ i0.ɵɵlistener("Navigate", function MJSearchScopeFormComponentExtended_Conditional_70_Template_mj_explorer_entity_data_grid_Navigate_1_listener($event) { i0.ɵɵrestoreView(_r14); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OnFormNavigate($event)); })("AfterDataLoad", function MJSearchScopeFormComponentExtended_Conditional_70_Template_mj_explorer_entity_data_grid_AfterDataLoad_1_listener($event) { i0.ɵɵrestoreView(_r14); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.SetSectionRowCount("mJSearchScopeProviders", $event.totalRowCount)); });
285
+ i0.ɵɵelementEnd()();
286
+ } if (rf & 2) {
287
+ const ctx_r2 = i0.ɵɵnextContext();
288
+ i0.ɵɵadvance();
289
+ i0.ɵɵproperty("Params", ctx_r2.BuildRelationshipViewParamsByEntityName("MJ: Search Scope Providers", "SearchScopeID"))("NewRecordValues", ctx_r2.NewRecordValues("MJ: Search Scope Providers"))("AllowLoad", ctx_r2.IsSectionExpanded("mJSearchScopeProviders"))("ShowToolbar", true);
290
+ } }
291
+ function MJSearchScopeFormComponentExtended_Conditional_72_Template(rf, ctx) { if (rf & 1) {
292
+ const _r15 = i0.ɵɵgetCurrentView();
293
+ i0.ɵɵelementStart(0, "div")(1, "mj-explorer-entity-data-grid", 79);
294
+ i0.ɵɵlistener("Navigate", function MJSearchScopeFormComponentExtended_Conditional_72_Template_mj_explorer_entity_data_grid_Navigate_1_listener($event) { i0.ɵɵrestoreView(_r15); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OnFormNavigate($event)); })("AfterDataLoad", function MJSearchScopeFormComponentExtended_Conditional_72_Template_mj_explorer_entity_data_grid_AfterDataLoad_1_listener($event) { i0.ɵɵrestoreView(_r15); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.SetSectionRowCount("mJAIAgentSearchScopes", $event.totalRowCount)); });
295
+ i0.ɵɵelementEnd()();
296
+ } if (rf & 2) {
297
+ const ctx_r2 = i0.ɵɵnextContext();
298
+ i0.ɵɵadvance();
299
+ i0.ɵɵproperty("Params", ctx_r2.BuildRelationshipViewParamsByEntityName("MJ: AI Agent Search Scopes", "SearchScopeID"))("NewRecordValues", ctx_r2.NewRecordValues("MJ: AI Agent Search Scopes"))("AllowLoad", ctx_r2.IsSectionExpanded("mJAIAgentSearchScopes"))("ShowToolbar", true);
300
+ } }
301
+ function MJSearchScopeFormComponentExtended_Conditional_74_Template(rf, ctx) { if (rf & 1) {
302
+ const _r16 = i0.ɵɵgetCurrentView();
303
+ i0.ɵɵelementStart(0, "div")(1, "mj-explorer-entity-data-grid", 79);
304
+ i0.ɵɵlistener("Navigate", function MJSearchScopeFormComponentExtended_Conditional_74_Template_mj_explorer_entity_data_grid_Navigate_1_listener($event) { i0.ɵɵrestoreView(_r16); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OnFormNavigate($event)); })("AfterDataLoad", function MJSearchScopeFormComponentExtended_Conditional_74_Template_mj_explorer_entity_data_grid_AfterDataLoad_1_listener($event) { i0.ɵɵrestoreView(_r16); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.SetSectionRowCount("mJSearchScopePermissions", $event.totalRowCount)); });
305
+ i0.ɵɵelementEnd()();
306
+ } if (rf & 2) {
307
+ const ctx_r2 = i0.ɵɵnextContext();
308
+ i0.ɵɵadvance();
309
+ i0.ɵɵproperty("Params", ctx_r2.BuildRelationshipViewParamsByEntityName("MJ: Search Scope Permissions", "SearchScopeID"))("NewRecordValues", ctx_r2.NewRecordValues("MJ: Search Scope Permissions"))("AllowLoad", ctx_r2.IsSectionExpanded("mJSearchScopePermissions"))("ShowToolbar", true);
310
+ } }
311
+ function MJSearchScopeFormComponentExtended_Conditional_76_Template(rf, ctx) { if (rf & 1) {
312
+ const _r17 = i0.ɵɵgetCurrentView();
313
+ i0.ɵɵelementStart(0, "div")(1, "mj-explorer-entity-data-grid", 79);
314
+ i0.ɵɵlistener("Navigate", function MJSearchScopeFormComponentExtended_Conditional_76_Template_mj_explorer_entity_data_grid_Navigate_1_listener($event) { i0.ɵɵrestoreView(_r17); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OnFormNavigate($event)); })("AfterDataLoad", function MJSearchScopeFormComponentExtended_Conditional_76_Template_mj_explorer_entity_data_grid_AfterDataLoad_1_listener($event) { i0.ɵɵrestoreView(_r17); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.SetSectionRowCount("mJSearchExecutionLogs", $event.totalRowCount)); });
315
+ i0.ɵɵelementEnd()();
316
+ } if (rf & 2) {
317
+ const ctx_r2 = i0.ɵɵnextContext();
318
+ i0.ɵɵadvance();
319
+ i0.ɵɵproperty("Params", ctx_r2.BuildRelationshipViewParamsByEntityName("MJ: Search Execution Logs", "SearchScopeID"))("NewRecordValues", ctx_r2.NewRecordValues("MJ: Search Execution Logs"))("AllowLoad", ctx_r2.IsSectionExpanded("mJSearchExecutionLogs"))("ShowToolbar", false);
320
+ } }
321
+ /**
322
+ * Built-in source types the SearchEngine ships. New 3rd-party provider
323
+ * SourceTypes (e.g. external clusters) won't appear here unless the scope
324
+ * author adds them via the JSON Scope Config block — by design, since the
325
+ * fusion-weights UI is for the four canonical built-ins.
326
+ */
327
+ const BUILT_IN_SOURCE_TYPES = ['vector', 'fulltext', 'entity', 'storage'];
328
+ /**
329
+ * Hardcoded list mirroring the rerankers `@memberjunction/search-engine`
330
+ * registers with ClassFactory. Update when adding a new built-in reranker
331
+ * or when the GraphQL discovery query lands.
332
+ */
333
+ const BUILT_IN_RERANKERS = [
334
+ { DriverClass: 'NoopReRanker', Name: 'NoopReRanker (pass-through)', HasCost: false },
335
+ { DriverClass: 'CohereReRanker', Name: 'Cohere (rerank-v3.5)', HasCost: true },
336
+ { DriverClass: 'VoyageReRanker', Name: 'Voyage (rerank-2)', HasCost: true },
337
+ { DriverClass: 'OpenAIReRanker', Name: 'OpenAI (gpt-4o-mini judge)', HasCost: true },
338
+ { DriverClass: 'BGEReRanker', Name: 'BGE (local, free)', HasCost: false },
339
+ ];
340
+ let MJSearchScopeFormComponentExtended = class MJSearchScopeFormComponentExtended extends MJSearchScopeFormComponent {
341
+ constructor() {
342
+ super(...arguments);
343
+ this.AvailableRerankers = BUILT_IN_RERANKERS;
344
+ /** Live-preview state (P4.1). */
345
+ this.PreviewQuery = '';
346
+ this.PreviewIsRunning = false;
347
+ this.PreviewResults = [];
348
+ this.PreviewProviders = [];
349
+ this.PreviewElapsedMs = null;
350
+ this.PreviewError = null;
351
+ this.previewSubscription = null;
352
+ this.searchService = new SearchService();
353
+ /**
354
+ * P4.3 — A/B comparison via Kendall-tau between consecutive preview runs.
355
+ * After RunPreview completes, the previous run's RecordIDs are diffed
356
+ * against the current run and the rank-correlation similarity is shown
357
+ * inline ("82% similar to last run"). Authors use this to immediately
358
+ * see how much a reranker swap or fusion-weight tweak shifted the ranking.
359
+ */
360
+ this.PreviousRunRecordIDs = [];
361
+ this.LastRunSimilarityPercent = null;
362
+ /**
363
+ * Whether the CSV export is currently running. Drives the button's disabled
364
+ * state + spinner.
365
+ */
366
+ this.IsExportingTuningCsv = false;
367
+ /**
368
+ * P4.2 — fusion weight sliders for each canonical SearchEngine source type.
369
+ * Backed by `SearchScope.ScopeConfig.fusionWeights` JSON (the runtime path
370
+ * — see plans/search-scopes-rag-plus/RAG_plan.md §8 Multi-Scope RRF Fusion). Plan task originally
371
+ * proposed `SearchScopeProvider.Weight` but that column doesn't exist in
372
+ * Phase 1; the JSON path is the actual contract the SearchEngine reads.
373
+ */
374
+ this._fusionWeights = null;
375
+ }
376
+ static { MJSearchScopeFormComponentExtended_1 = this; }
377
+ ngOnDestroy() {
378
+ this.previewSubscription?.unsubscribe();
379
+ this.previewSubscription = null;
380
+ }
381
+ /**
382
+ * P4.1 — run a streaming preview against this scope. Uses the same
383
+ * SearchService.StreamSearch path the production search UI uses, scoped
384
+ * to just this scope's ID. Renders progressively as each provider
385
+ * reports back so authors can see chip-by-chip what each tuning change
386
+ * actually affects.
387
+ */
388
+ RunPreview() {
389
+ if (!this.record?.ID || this.PreviewIsRunning)
390
+ return;
391
+ const query = this.PreviewQuery.trim();
392
+ if (!query)
393
+ return;
394
+ // Tear down any previous run before starting a new one.
395
+ this.previewSubscription?.unsubscribe();
396
+ this.PreviewIsRunning = true;
397
+ this.PreviewResults = [];
398
+ this.PreviewProviders = [];
399
+ this.PreviewElapsedMs = null;
400
+ this.PreviewError = null;
401
+ this.previewSubscription = this.searchService.StreamSearch({
402
+ Query: query,
403
+ MaxResults: 25,
404
+ ActiveFilters: {},
405
+ IncludeSources: ['vector', 'fulltext', 'entity', 'storage'],
406
+ ScopeIDs: [this.record.ID],
407
+ }).subscribe({
408
+ next: (event) => {
409
+ if (event.Phase === 'provider' && event.ProviderName) {
410
+ this.PreviewProviders = [
411
+ ...this.PreviewProviders,
412
+ {
413
+ Name: event.ProviderName,
414
+ Count: event.Results?.length ?? 0,
415
+ ElapsedMs: event.ElapsedMs ?? 0,
416
+ State: 'Completed',
417
+ },
418
+ ];
419
+ if (event.Results) {
420
+ this.PreviewResults = [...this.PreviewResults, ...event.Results].sort((a, b) => b.Score - a.Score);
421
+ }
422
+ }
423
+ else if (event.Phase === 'final' && event.Results) {
424
+ this.PreviewResults = [...event.Results].sort((a, b) => b.Score - a.Score);
425
+ this.PreviewElapsedMs = event.ElapsedMs ?? null;
426
+ }
427
+ },
428
+ error: (err) => {
429
+ this.PreviewError = err.message ?? String(err);
430
+ this.PreviewIsRunning = false;
431
+ },
432
+ complete: () => {
433
+ this.PreviewIsRunning = false;
434
+ // Compute Kendall-tau against the prior run, then capture this
435
+ // run's order as the next baseline.
436
+ const currentIDs = this.PreviewResults.map(r => r.RecordID);
437
+ if (this.PreviousRunRecordIDs.length > 0 && currentIDs.length > 0) {
438
+ const tau = MJSearchScopeFormComponentExtended_1.kendallTauOnSharedItems(this.PreviousRunRecordIDs, currentIDs);
439
+ if (tau !== null) {
440
+ // Map [-1, 1] tau onto a [0, 100] "% similar" gauge so non-stats
441
+ // authors can read it. -1 (reverse) = 0%, 0 (uncorrelated) = 50%,
442
+ // +1 (identical) = 100%.
443
+ this.LastRunSimilarityPercent = Math.round((tau + 1) * 50);
444
+ }
445
+ }
446
+ this.PreviousRunRecordIDs = currentIDs;
447
+ },
448
+ });
449
+ }
450
+ CancelPreview() {
451
+ this.previewSubscription?.unsubscribe();
452
+ this.previewSubscription = null;
453
+ this.PreviewIsRunning = false;
454
+ }
455
+ /**
456
+ * Compute Kendall-tau rank correlation on the items present in both lists.
457
+ * Items only in one list are ignored (partial-overlap handling). Returns
458
+ * null when the shared overlap is too small (< 2 items) to be meaningful.
459
+ *
460
+ * Tau formula: (concordant - discordant) / (N * (N-1) / 2)
461
+ * where concordant = pairs ranked in the same order in both lists,
462
+ * discordant = pairs ranked in opposite order, N = shared item count.
463
+ */
464
+ static kendallTauOnSharedItems(listA, listB) {
465
+ const rankA = new Map(listA.map((id, i) => [id, i]));
466
+ const rankB = new Map(listB.map((id, i) => [id, i]));
467
+ const shared = listA.filter(id => rankB.has(id));
468
+ const n = shared.length;
469
+ if (n < 2)
470
+ return null;
471
+ let concordant = 0;
472
+ let discordant = 0;
473
+ for (let i = 0; i < n; i++) {
474
+ for (let j = i + 1; j < n; j++) {
475
+ const a = (rankA.get(shared[i]) - rankA.get(shared[j]));
476
+ const b = (rankB.get(shared[i]) - rankB.get(shared[j]));
477
+ const product = a * b;
478
+ if (product > 0)
479
+ concordant++;
480
+ else if (product < 0)
481
+ discordant++;
482
+ // Ties (product === 0) ignored — items at same rank
483
+ }
484
+ }
485
+ const totalPairs = (n * (n - 1)) / 2;
486
+ if (totalPairs === 0)
487
+ return null;
488
+ return (concordant - discordant) / totalPairs;
489
+ }
490
+ /**
491
+ * Override the section list to include the new "Reranker" section before
492
+ * "Details". The generated `initSections()` doesn't know about our custom
493
+ * section so we replace the list. Order matches the template's render order.
494
+ */
495
+ async ngOnInit() {
496
+ await super.ngOnInit();
497
+ this.initSections([
498
+ { sectionKey: 'scopeDefinition', sectionName: 'Scope Definition', isExpanded: true },
499
+ { sectionKey: 'scopeConfiguration', sectionName: 'Scope Configuration', isExpanded: true },
500
+ { sectionKey: 'accessControl', sectionName: 'Access Control', isExpanded: false },
501
+ { sectionKey: 'lifecycleManagement', sectionName: 'Lifecycle Management', isExpanded: false },
502
+ { sectionKey: 'technicalConfiguration', sectionName: 'Technical Configuration', isExpanded: false },
503
+ { sectionKey: 'fusionWeights', sectionName: 'Fusion Weights', isExpanded: false },
504
+ { sectionKey: 'reranker', sectionName: 'Reranker', isExpanded: false },
505
+ { sectionKey: 'livePreview', sectionName: 'Live Preview', isExpanded: false },
506
+ { sectionKey: 'details', sectionName: 'Details', isExpanded: false },
507
+ { sectionKey: 'systemMetadata', sectionName: 'System Metadata', isExpanded: false },
508
+ { sectionKey: 'mJSearchScopeTestQueries', sectionName: 'Search Scope Test Queries', isExpanded: false },
509
+ { sectionKey: 'mJSearchScopeStorageAccounts', sectionName: 'Search Scope Storage Accounts', isExpanded: false },
510
+ { sectionKey: 'mJSearchScopeEntities', sectionName: 'Search Scope Entities', isExpanded: false },
511
+ { sectionKey: 'mJSearchScopeExternalIndexes', sectionName: 'Search Scope External Indexes', isExpanded: false },
512
+ { sectionKey: 'mJSearchScopeProviders', sectionName: 'Search Scope Providers', isExpanded: false },
513
+ { sectionKey: 'mJAIAgentSearchScopes', sectionName: 'AI Agent Search Scopes', isExpanded: false },
514
+ { sectionKey: 'mJSearchScopePermissions', sectionName: 'Search Scope Permissions', isExpanded: false },
515
+ ]);
516
+ }
517
+ /**
518
+ * Currently-selected reranker driver class, parsed from `record.ScopeConfig`.
519
+ * Empty string means "no reranker explicitly chosen" — runtime defaults
520
+ * to NoopReRanker. Stored as `ScopeConfig.reRanker.driverClass`.
521
+ */
522
+ get SelectedRerankerDriverClass() {
523
+ const cfg = this.parseScopeConfig();
524
+ return cfg?.['reRanker']?.driverClass ?? '';
525
+ }
526
+ set SelectedRerankerDriverClass(value) {
527
+ const cfg = this.parseScopeConfig() ?? {};
528
+ const reRanker = cfg['reRanker'] ?? {};
529
+ if (value && value.trim().length > 0) {
530
+ reRanker['driverClass'] = value;
531
+ }
532
+ else {
533
+ delete reRanker['driverClass'];
534
+ }
535
+ cfg['reRanker'] = reRanker;
536
+ this.record.ScopeConfig = JSON.stringify(cfg, null, 2);
537
+ }
538
+ /**
539
+ * Whether the currently-selected reranker incurs API cost — used to render
540
+ * an inline cost-warning indicator next to the dropdown.
541
+ */
542
+ get SelectedRerankerHasCost() {
543
+ const driver = this.SelectedRerankerDriverClass;
544
+ return BUILT_IN_RERANKERS.find(r => r.DriverClass === driver)?.HasCost ?? false;
545
+ }
546
+ get FusionWeights() {
547
+ if (!this._fusionWeights) {
548
+ const cfg = this.parseScopeConfig();
549
+ const stored = cfg?.['fusionWeights'] ?? {};
550
+ this._fusionWeights = BUILT_IN_SOURCE_TYPES.map(key => {
551
+ const value = stored[key];
552
+ const weight = typeof value === 'number' && Number.isFinite(value) ? value : 1;
553
+ return { Key: key, Label: key, Weight: weight };
554
+ });
555
+ }
556
+ return this._fusionWeights;
557
+ }
558
+ /**
559
+ * Persist a fusion weight change back to `ScopeConfig.fusionWeights`. The
560
+ * caller is the slider's `(change)` event so writes happen only on
561
+ * slide-end, not on every drag tick.
562
+ */
563
+ OnFusionWeightChanged(row, raw) {
564
+ const value = typeof raw === 'number' ? raw : Number(raw);
565
+ if (!Number.isFinite(value))
566
+ return;
567
+ row.Weight = value;
568
+ const cfg = this.parseScopeConfig() ?? {};
569
+ const weights = cfg['fusionWeights'] ?? {};
570
+ if (Math.abs(value - 1) < 0.001) {
571
+ // Default value — drop the explicit override so future engine-default
572
+ // changes flow through naturally.
573
+ delete weights[row.Key];
574
+ }
575
+ else {
576
+ weights[row.Key] = +value.toFixed(2);
577
+ }
578
+ if (Object.keys(weights).length > 0) {
579
+ cfg['fusionWeights'] = weights;
580
+ }
581
+ else {
582
+ delete cfg['fusionWeights'];
583
+ }
584
+ this.record.ScopeConfig = JSON.stringify(cfg, null, 2);
585
+ }
586
+ /**
587
+ * P3.4 — export the last 500 SearchExecutionLog rows for this scope as CSV.
588
+ * Used by scope authors for offline tuning analysis (open in a spreadsheet,
589
+ * pivot by reranker / status / latency, etc.). Filtered to this scope's ID
590
+ * so multi-tenant deployments don't leak other scopes' query history.
591
+ */
592
+ async ExportTuningCsv() {
593
+ if (!this.record?.ID || this.IsExportingTuningCsv)
594
+ return;
595
+ this.IsExportingTuningCsv = true;
596
+ try {
597
+ const rv = new RunView();
598
+ const result = await rv.RunView({
599
+ EntityName: 'MJ: Search Execution Logs',
600
+ // Constrain to the columns the CSV writer actually emits — avoids
601
+ // pulling the wider entity (per Section 6.8).
602
+ Fields: [
603
+ '__mj_CreatedAt', 'Status', 'Query', 'ResultCount', 'TotalDurationMs',
604
+ 'RerankerName', 'RerankerCostCents', 'FailureReason', 'UserID', 'AIAgentID',
605
+ ],
606
+ ExtraFilter: `SearchScopeID='${this.record.ID.replace(/'/g, "''")}'`,
607
+ OrderBy: '__mj_CreatedAt DESC',
608
+ MaxRows: 500,
609
+ ResultType: 'simple',
610
+ });
611
+ if (!result.Success) {
612
+ LogError(`SearchScope CSV export failed: ${result.ErrorMessage ?? 'unknown error'}`);
613
+ return;
614
+ }
615
+ const rows = (result.Results ?? []);
616
+ this.downloadCsv(rows);
617
+ }
618
+ finally {
619
+ this.IsExportingTuningCsv = false;
620
+ }
621
+ }
622
+ downloadCsv(rows) {
623
+ const headers = [
624
+ 'CreatedAt', 'Status', 'Query', 'ResultCount', 'TotalDurationMs',
625
+ 'RerankerName', 'RerankerCostCents', 'FailureReason', 'UserID', 'AIAgentID',
626
+ ];
627
+ const lines = [headers.join(',')];
628
+ for (const r of rows) {
629
+ const cells = [
630
+ this.escapeCsv(String(r.__mj_CreatedAt ?? '')),
631
+ this.escapeCsv(String(r.Status ?? '')),
632
+ this.escapeCsv(String(r.Query ?? '')),
633
+ String(r.ResultCount ?? 0),
634
+ String(r.TotalDurationMs ?? 0),
635
+ this.escapeCsv(String(r.RerankerName ?? '')),
636
+ String(r.RerankerCostCents ?? ''),
637
+ this.escapeCsv(String(r.FailureReason ?? '')),
638
+ String(r.UserID ?? ''),
639
+ String(r.AIAgentID ?? ''),
640
+ ];
641
+ lines.push(cells.join(','));
642
+ }
643
+ const blob = new Blob([lines.join('\n')], { type: 'text/csv;charset=utf-8;' });
644
+ const url = URL.createObjectURL(blob);
645
+ const link = document.createElement('a');
646
+ link.setAttribute('href', url);
647
+ const name = (this.record?.Name ?? 'scope').replace(/[^\w\-]+/g, '_');
648
+ link.setAttribute('download', `searchscope-tuning-${name}-${new Date().toISOString().split('T')[0]}.csv`);
649
+ link.style.visibility = 'hidden';
650
+ document.body.appendChild(link);
651
+ link.click();
652
+ document.body.removeChild(link);
653
+ URL.revokeObjectURL(url);
654
+ }
655
+ escapeCsv(value) {
656
+ if (value == null)
657
+ return '';
658
+ // Quote when the value contains a comma, quote, newline, or starts with
659
+ // formula-injection characters. Inside a quoted value, escape inner
660
+ // quotes by doubling.
661
+ if (/[",\n\r]/.test(value) || /^[=+\-@]/.test(value)) {
662
+ return `"${value.replace(/"/g, '""')}"`;
663
+ }
664
+ return value;
665
+ }
666
+ parseScopeConfig() {
667
+ if (!this.record?.ScopeConfig)
668
+ return null;
669
+ try {
670
+ const parsed = JSON.parse(this.record.ScopeConfig);
671
+ return (parsed && typeof parsed === 'object') ? parsed : null;
672
+ }
673
+ catch {
674
+ return null;
675
+ }
676
+ }
677
+ static { this.ɵfac = /*@__PURE__*/ (() => { let ɵMJSearchScopeFormComponentExtended_BaseFactory; return function MJSearchScopeFormComponentExtended_Factory(__ngFactoryType__) { return (ɵMJSearchScopeFormComponentExtended_BaseFactory || (ɵMJSearchScopeFormComponentExtended_BaseFactory = i0.ɵɵgetInheritedFactory(MJSearchScopeFormComponentExtended)))(__ngFactoryType__ || MJSearchScopeFormComponentExtended); }; })(); }
678
+ static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: MJSearchScopeFormComponentExtended, selectors: [["mj-searchscope-form-extended"]], standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 77, vars: 129, consts: [[3, "Navigate", "DeleteRequested", "FavoriteToggled", "HistoryRequested", "ListManagementRequested", "Record", "FormComponent"], ["SectionKey", "scopeDefinition", "SectionName", "Scope Definition", "Icon", "fa fa-info-circle", 3, "Form", "FormContext"], ["FieldName", "Name", "Type", "textbox", 3, "Record", "ShowLabel", "EditMode", "FormContext"], ["FieldName", "Description", "Type", "textarea", 3, "Record", "ShowLabel", "EditMode", "FormContext"], ["FieldName", "Icon", "Type", "textbox", 3, "Record", "ShowLabel", "EditMode", "FormContext"], ["SectionKey", "scopeConfiguration", "SectionName", "Scope Configuration", "Icon", "fa fa-sliders-h", 3, "Form", "FormContext"], ["FieldName", "IsGlobal", "Type", "checkbox", 3, "Record", "ShowLabel", "EditMode", "FormContext"], ["FieldName", "IsDefault", "Type", "checkbox", 3, "Record", "ShowLabel", "EditMode", "FormContext"], ["SectionKey", "accessControl", "SectionName", "Access Control", "Icon", "fa fa-lock", 3, "Form", "FormContext"], ["FieldName", "OwnerUserID", "Type", "textbox", "LinkType", "Record", 3, "Record", "ShowLabel", "EditMode", "FormContext"], ["SectionKey", "lifecycleManagement", "SectionName", "Lifecycle Management", "Icon", "fa fa-clock", 3, "Form", "FormContext"], ["FieldName", "Status", "Type", "select", 3, "Record", "ShowLabel", "EditMode", "FormContext"], ["FieldName", "StartAt", "Type", "datepicker", 3, "Record", "ShowLabel", "EditMode", "FormContext"], ["FieldName", "EndAt", "Type", "datepicker", 3, "Record", "ShowLabel", "EditMode", "FormContext"], ["SectionKey", "technicalConfiguration", "SectionName", "Technical Configuration", "Icon", "fa fa-code", 3, "Form", "FormContext"], ["FieldName", "ScopeConfig", "Type", "code", 3, "Record", "ShowLabel", "EditMode", "FormContext"], ["FieldName", "SearchContextConfig", "Type", "code", 3, "Record", "ShowLabel", "EditMode", "FormContext"], ["SectionKey", "fusionWeights", "SectionName", "Fusion Weights", "Icon", "fa fa-sliders-h", 3, "Form", "FormContext"], [1, "fusion-weights"], [1, "fusion-weight-row"], [1, "fusion-weights-help"], ["SectionKey", "reranker", "SectionName", "Reranker", "Icon", "fa fa-sort-amount-down", 3, "Form", "FormContext"], [1, "reranker-config"], [1, "reranker-config-label"], [1, "mj-input", "reranker-driver-select", 3, "ngModelChange", "disabled", "ngModel"], ["value", ""], [3, "value"], [1, "reranker-cost-hint"], [1, "reranker-help-hint"], ["FieldName", "RerankerBudgetCents", "Type", "number", 3, "Record", "ShowLabel", "EditMode", "FormContext"], [1, "reranker-export-row"], ["type", "button", 1, "reranker-export-btn", 3, "click", "disabled"], [1, "reranker-export-hint"], ["SectionKey", "livePreview", "SectionName", "Live Preview", "Icon", "fa fa-flask", 3, "Form", "FormContext"], [1, "live-preview"], [1, "live-preview-input-row"], ["type", "text", "placeholder", "Type a sample query and press Run\u2026", 1, "mj-input", "live-preview-input", 3, "input", "keydown.enter", "disabled", "value"], ["type", "button", 1, "live-preview-btn", 3, "disabled"], ["type", "button", 1, "live-preview-btn", "live-preview-btn-cancel"], [1, "live-preview-error"], [1, "live-preview-chips"], [1, "live-preview-results"], ["SectionKey", "details", "SectionName", "Details", "Icon", "fa fa-align-left", 3, "Form", "FormContext"], ["SectionKey", "systemMetadata", "SectionName", "System Metadata", "Icon", "fa fa-cog", 3, "Form", "FormContext"], ["FieldName", "__mj_CreatedAt", "Type", "textbox", 3, "Record", "ShowLabel", "EditMode", "FormContext"], ["FieldName", "__mj_UpdatedAt", "Type", "textbox", 3, "Record", "ShowLabel", "EditMode", "FormContext"], ["SectionKey", "mJSearchScopeTestQueries", "SectionName", "Search Scope Test Queries", "Icon", "fa fa-table", "Variant", "related-entity", 3, "Form", "FormContext", "BadgeCount", "DefaultExpanded"], ["SectionKey", "mJSearchScopeStorageAccounts", "SectionName", "Search Scope Storage Accounts", "Icon", "fa fa-folder-open", "Variant", "related-entity", 3, "Form", "FormContext", "BadgeCount", "DefaultExpanded"], ["SectionKey", "mJSearchScopeEntities", "SectionName", "Search Scope Entities", "Icon", "fa fa-search", "Variant", "related-entity", 3, "Form", "FormContext", "BadgeCount", "DefaultExpanded"], ["SectionKey", "mJSearchScopeExternalIndexes", "SectionName", "Search Scope External Indexes", "Icon", "fa fa-search-plus", "Variant", "related-entity", 3, "Form", "FormContext", "BadgeCount", "DefaultExpanded"], ["SectionKey", "mJSearchScopeProviders", "SectionName", "Search Scope Providers", "Icon", "fa fa-search-plus", "Variant", "related-entity", 3, "Form", "FormContext", "BadgeCount", "DefaultExpanded"], ["SectionKey", "mJAIAgentSearchScopes", "SectionName", "AI Agent Search Scopes", "Icon", "fa fa-search-plus", "Variant", "related-entity", 3, "Form", "FormContext", "BadgeCount", "DefaultExpanded"], ["SectionKey", "mJSearchScopePermissions", "SectionName", "Search Scope Permissions", "Icon", "fa fa-table", "Variant", "related-entity", 3, "Form", "FormContext", "BadgeCount", "DefaultExpanded"], ["SectionKey", "mJSearchExecutionLogs", "SectionName", "Search Execution Logs", "Icon", "fa fa-table", "Variant", "related-entity", 3, "Form", "FormContext", "BadgeCount", "DefaultExpanded"], [1, "fusion-weight-label"], ["type", "range", "min", "0", "max", "5", "step", "0.1", 1, "fusion-weight-slider", 3, "change", "disabled", "value"], [1, "fusion-weight-value"], [1, "fa-solid", "fa-triangle-exclamation"], [1, "fa-solid", "fa-spinner", "fa-spin"], [1, "fa-solid", "fa-download"], ["type", "button", 1, "live-preview-btn", 3, "click", "disabled"], [1, "fa-solid", "fa-play"], ["type", "button", 1, "live-preview-btn", "live-preview-btn-cancel", 3, "click"], [1, "fa-solid", "fa-stop"], [1, "fa-solid", "fa-circle-exclamation"], [1, "live-preview-chip", "live-preview-chip-pending"], [1, "live-preview-chip", "live-preview-chip-completed"], [1, "fa-solid", "fa-circle-notch", "fa-spin"], [1, "fa-solid", "fa-check"], [1, "live-preview-chip-count"], [1, "live-preview-chip-time"], [1, "live-preview-results-header"], ["title", "Kendall-tau rank correlation against the previous run, mapped to [0%, 100%].", 1, "live-preview-similarity", 3, "live-preview-similarity-low"], [1, "live-preview-truncated"], ["title", "Kendall-tau rank correlation against the previous run, mapped to [0%, 100%].", 1, "live-preview-similarity"], [1, "live-preview-result"], [1, "live-preview-result-score"], [1, "live-preview-result-title"], [1, "live-preview-result-entity"], [3, "Navigate", "AfterDataLoad", "Params", "NewRecordValues", "AllowLoad", "ShowToolbar"]], template: function MJSearchScopeFormComponentExtended_Template(rf, ctx) { if (rf & 1) {
679
+ i0.ɵɵelementStart(0, "mj-record-form-container", 0);
680
+ i0.ɵɵlistener("Navigate", function MJSearchScopeFormComponentExtended_Template_mj_record_form_container_Navigate_0_listener($event) { return ctx.OnFormNavigate($event); })("DeleteRequested", function MJSearchScopeFormComponentExtended_Template_mj_record_form_container_DeleteRequested_0_listener() { return ctx.OnDeleteRequested(); })("FavoriteToggled", function MJSearchScopeFormComponentExtended_Template_mj_record_form_container_FavoriteToggled_0_listener() { return ctx.OnFavoriteToggled(); })("HistoryRequested", function MJSearchScopeFormComponentExtended_Template_mj_record_form_container_HistoryRequested_0_listener() { return ctx.OnHistoryRequested(); })("ListManagementRequested", function MJSearchScopeFormComponentExtended_Template_mj_record_form_container_ListManagementRequested_0_listener() { return ctx.OnListManagementRequested(); });
681
+ i0.ɵɵelementStart(1, "mj-collapsible-panel", 1);
682
+ i0.ɵɵelement(2, "mj-form-field", 2)(3, "mj-form-field", 3)(4, "mj-form-field", 4);
683
+ i0.ɵɵelementEnd();
684
+ i0.ɵɵelementStart(5, "mj-collapsible-panel", 5);
685
+ i0.ɵɵelement(6, "mj-form-field", 6)(7, "mj-form-field", 7);
686
+ i0.ɵɵelementEnd();
687
+ i0.ɵɵelementStart(8, "mj-collapsible-panel", 8);
688
+ i0.ɵɵelement(9, "mj-form-field", 9);
689
+ i0.ɵɵelementEnd();
690
+ i0.ɵɵelementStart(10, "mj-collapsible-panel", 10);
691
+ i0.ɵɵelement(11, "mj-form-field", 11)(12, "mj-form-field", 12)(13, "mj-form-field", 13);
692
+ i0.ɵɵelementEnd();
693
+ i0.ɵɵelementStart(14, "mj-collapsible-panel", 14);
694
+ i0.ɵɵelement(15, "mj-form-field", 15)(16, "mj-form-field", 16);
695
+ i0.ɵɵelementEnd();
696
+ i0.ɵɵelementStart(17, "mj-collapsible-panel", 17)(18, "div", 18);
697
+ i0.ɵɵrepeaterCreate(19, MJSearchScopeFormComponentExtended_For_20_Template, 7, 7, "div", 19, _forTrack0);
698
+ i0.ɵɵelementStart(21, "p", 20);
699
+ i0.ɵɵtext(22, " Drag a slider to update ");
700
+ i0.ɵɵelementStart(23, "code");
701
+ i0.ɵɵtext(24, "ScopeConfig.fusionWeights");
702
+ i0.ɵɵelementEnd();
703
+ i0.ɵɵtext(25, ". Default 1.0 means \"use engine default\"; values are persisted on form save. ");
704
+ i0.ɵɵelementEnd()()();
705
+ i0.ɵɵelementStart(26, "mj-collapsible-panel", 21)(27, "div", 22)(28, "label", 23);
706
+ i0.ɵɵtext(29, "Reranker driver class");
707
+ i0.ɵɵelementEnd();
708
+ i0.ɵɵelementStart(30, "select", 24);
709
+ i0.ɵɵlistener("ngModelChange", function MJSearchScopeFormComponentExtended_Template_select_ngModelChange_30_listener($event) { return ctx.SelectedRerankerDriverClass = $event; });
710
+ i0.ɵɵelementStart(31, "option", 25);
711
+ i0.ɵɵtext(32, "\u2014 None (use NoopReRanker) \u2014");
712
+ i0.ɵɵelementEnd();
713
+ i0.ɵɵrepeaterCreate(33, MJSearchScopeFormComponentExtended_For_34_Template, 2, 3, "option", 26, _forTrack1);
714
+ i0.ɵɵelementEnd();
715
+ i0.ɵɵconditionalCreate(35, MJSearchScopeFormComponentExtended_Conditional_35_Template, 6, 0, "p", 27);
716
+ i0.ɵɵelementStart(36, "p", 28);
717
+ i0.ɵɵtext(37, " Stored on ");
718
+ i0.ɵɵelementStart(38, "code");
719
+ i0.ɵɵtext(39, "ScopeConfig.reRanker.driverClass");
720
+ i0.ɵɵelementEnd();
721
+ i0.ɵɵtext(40, " \u2014 the SearchEngine reads this at runtime. Leave blank to use the pass-through default. ");
722
+ i0.ɵɵelementEnd();
723
+ i0.ɵɵelement(41, "mj-form-field", 29);
724
+ i0.ɵɵelementStart(42, "div", 30)(43, "button", 31);
725
+ i0.ɵɵlistener("click", function MJSearchScopeFormComponentExtended_Template_button_click_43_listener() { return ctx.ExportTuningCsv(); });
726
+ i0.ɵɵconditionalCreate(44, MJSearchScopeFormComponentExtended_Conditional_44_Template, 3, 0)(45, MJSearchScopeFormComponentExtended_Conditional_45_Template, 3, 0);
727
+ i0.ɵɵelementEnd();
728
+ i0.ɵɵelementStart(46, "span", 32);
729
+ i0.ɵɵtext(47, "Last 500 search invocations against this scope.");
730
+ i0.ɵɵelementEnd()()()();
731
+ i0.ɵɵelementStart(48, "mj-collapsible-panel", 33)(49, "div", 34)(50, "div", 35)(51, "input", 36);
732
+ i0.ɵɵlistener("input", function MJSearchScopeFormComponentExtended_Template_input_input_51_listener($event) { return ctx.PreviewQuery = $event.target.value; })("keydown.enter", function MJSearchScopeFormComponentExtended_Template_input_keydown_enter_51_listener() { return ctx.RunPreview(); });
733
+ i0.ɵɵelementEnd();
734
+ i0.ɵɵconditionalCreate(52, MJSearchScopeFormComponentExtended_Conditional_52_Template, 3, 1, "button", 37)(53, MJSearchScopeFormComponentExtended_Conditional_53_Template, 3, 0, "button", 38);
735
+ i0.ɵɵelementEnd();
736
+ i0.ɵɵconditionalCreate(54, MJSearchScopeFormComponentExtended_Conditional_54_Template, 3, 1, "p", 39);
737
+ i0.ɵɵconditionalCreate(55, MJSearchScopeFormComponentExtended_Conditional_55_Template, 4, 1, "div", 40);
738
+ i0.ɵɵconditionalCreate(56, MJSearchScopeFormComponentExtended_Conditional_56_Template, 8, 4, "div", 41);
739
+ i0.ɵɵelementEnd()();
740
+ i0.ɵɵelement(57, "mj-collapsible-panel", 42);
741
+ i0.ɵɵelementStart(58, "mj-collapsible-panel", 43);
742
+ i0.ɵɵelement(59, "mj-form-field", 44)(60, "mj-form-field", 45);
743
+ i0.ɵɵelementEnd();
744
+ i0.ɵɵelementStart(61, "mj-collapsible-panel", 46);
745
+ i0.ɵɵconditionalCreate(62, MJSearchScopeFormComponentExtended_Conditional_62_Template, 2, 4, "div");
746
+ i0.ɵɵelementEnd();
747
+ i0.ɵɵelementStart(63, "mj-collapsible-panel", 47);
748
+ i0.ɵɵconditionalCreate(64, MJSearchScopeFormComponentExtended_Conditional_64_Template, 2, 4, "div");
749
+ i0.ɵɵelementEnd();
750
+ i0.ɵɵelementStart(65, "mj-collapsible-panel", 48);
751
+ i0.ɵɵconditionalCreate(66, MJSearchScopeFormComponentExtended_Conditional_66_Template, 2, 4, "div");
752
+ i0.ɵɵelementEnd();
753
+ i0.ɵɵelementStart(67, "mj-collapsible-panel", 49);
754
+ i0.ɵɵconditionalCreate(68, MJSearchScopeFormComponentExtended_Conditional_68_Template, 2, 4, "div");
755
+ i0.ɵɵelementEnd();
756
+ i0.ɵɵelementStart(69, "mj-collapsible-panel", 50);
757
+ i0.ɵɵconditionalCreate(70, MJSearchScopeFormComponentExtended_Conditional_70_Template, 2, 4, "div");
758
+ i0.ɵɵelementEnd();
759
+ i0.ɵɵelementStart(71, "mj-collapsible-panel", 51);
760
+ i0.ɵɵconditionalCreate(72, MJSearchScopeFormComponentExtended_Conditional_72_Template, 2, 4, "div");
761
+ i0.ɵɵelementEnd();
762
+ i0.ɵɵelementStart(73, "mj-collapsible-panel", 52);
763
+ i0.ɵɵconditionalCreate(74, MJSearchScopeFormComponentExtended_Conditional_74_Template, 2, 4, "div");
764
+ i0.ɵɵelementEnd();
765
+ i0.ɵɵelementStart(75, "mj-collapsible-panel", 53);
766
+ i0.ɵɵconditionalCreate(76, MJSearchScopeFormComponentExtended_Conditional_76_Template, 2, 4, "div");
767
+ i0.ɵɵelementEnd()();
768
+ } if (rf & 2) {
769
+ i0.ɵɵproperty("Record", ctx.record)("FormComponent", ctx);
770
+ i0.ɵɵadvance();
771
+ i0.ɵɵproperty("Form", ctx)("FormContext", ctx.formContext);
772
+ i0.ɵɵadvance();
773
+ i0.ɵɵproperty("Record", ctx.record)("ShowLabel", true)("EditMode", ctx.EditMode)("FormContext", ctx.formContext);
774
+ i0.ɵɵadvance();
775
+ i0.ɵɵproperty("Record", ctx.record)("ShowLabel", true)("EditMode", ctx.EditMode)("FormContext", ctx.formContext);
776
+ i0.ɵɵadvance();
777
+ i0.ɵɵproperty("Record", ctx.record)("ShowLabel", true)("EditMode", ctx.EditMode)("FormContext", ctx.formContext);
778
+ i0.ɵɵadvance();
779
+ i0.ɵɵproperty("Form", ctx)("FormContext", ctx.formContext);
780
+ i0.ɵɵadvance();
781
+ i0.ɵɵproperty("Record", ctx.record)("ShowLabel", true)("EditMode", ctx.EditMode)("FormContext", ctx.formContext);
782
+ i0.ɵɵadvance();
783
+ i0.ɵɵproperty("Record", ctx.record)("ShowLabel", true)("EditMode", ctx.EditMode)("FormContext", ctx.formContext);
784
+ i0.ɵɵadvance();
785
+ i0.ɵɵproperty("Form", ctx)("FormContext", ctx.formContext);
786
+ i0.ɵɵadvance();
787
+ i0.ɵɵproperty("Record", ctx.record)("ShowLabel", false)("EditMode", ctx.EditMode)("FormContext", ctx.formContext);
788
+ i0.ɵɵadvance();
789
+ i0.ɵɵproperty("Form", ctx)("FormContext", ctx.formContext);
790
+ i0.ɵɵadvance();
791
+ i0.ɵɵproperty("Record", ctx.record)("ShowLabel", true)("EditMode", ctx.EditMode)("FormContext", ctx.formContext);
792
+ i0.ɵɵadvance();
793
+ i0.ɵɵproperty("Record", ctx.record)("ShowLabel", true)("EditMode", ctx.EditMode)("FormContext", ctx.formContext);
794
+ i0.ɵɵadvance();
795
+ i0.ɵɵproperty("Record", ctx.record)("ShowLabel", true)("EditMode", ctx.EditMode)("FormContext", ctx.formContext);
796
+ i0.ɵɵadvance();
797
+ i0.ɵɵproperty("Form", ctx)("FormContext", ctx.formContext);
798
+ i0.ɵɵadvance();
799
+ i0.ɵɵproperty("Record", ctx.record)("ShowLabel", true)("EditMode", ctx.EditMode)("FormContext", ctx.formContext);
800
+ i0.ɵɵadvance();
801
+ i0.ɵɵproperty("Record", ctx.record)("ShowLabel", true)("EditMode", ctx.EditMode)("FormContext", ctx.formContext);
802
+ i0.ɵɵadvance();
803
+ i0.ɵɵproperty("Form", ctx)("FormContext", ctx.formContext);
804
+ i0.ɵɵadvance(2);
805
+ i0.ɵɵrepeater(ctx.FusionWeights);
806
+ i0.ɵɵadvance(7);
807
+ i0.ɵɵproperty("Form", ctx)("FormContext", ctx.formContext);
808
+ i0.ɵɵadvance(4);
809
+ i0.ɵɵproperty("disabled", !ctx.EditMode)("ngModel", ctx.SelectedRerankerDriverClass);
810
+ i0.ɵɵadvance(3);
811
+ i0.ɵɵrepeater(ctx.AvailableRerankers);
812
+ i0.ɵɵadvance(2);
813
+ i0.ɵɵconditional(ctx.SelectedRerankerHasCost ? 35 : -1);
814
+ i0.ɵɵadvance(6);
815
+ i0.ɵɵproperty("Record", ctx.record)("ShowLabel", true)("EditMode", ctx.EditMode)("FormContext", ctx.formContext);
816
+ i0.ɵɵadvance(2);
817
+ i0.ɵɵproperty("disabled", !(ctx.record == null ? null : ctx.record.ID) || ctx.IsExportingTuningCsv);
818
+ i0.ɵɵadvance();
819
+ i0.ɵɵconditional(ctx.IsExportingTuningCsv ? 44 : 45);
820
+ i0.ɵɵadvance(4);
821
+ i0.ɵɵproperty("Form", ctx)("FormContext", ctx.formContext);
822
+ i0.ɵɵadvance(3);
823
+ i0.ɵɵproperty("disabled", !(ctx.record == null ? null : ctx.record.ID) || ctx.PreviewIsRunning)("value", ctx.PreviewQuery);
824
+ i0.ɵɵadvance();
825
+ i0.ɵɵconditional(!ctx.PreviewIsRunning ? 52 : 53);
826
+ i0.ɵɵadvance(2);
827
+ i0.ɵɵconditional(ctx.PreviewError ? 54 : -1);
828
+ i0.ɵɵadvance();
829
+ i0.ɵɵconditional(ctx.PreviewIsRunning || ctx.PreviewProviders.length > 0 ? 55 : -1);
830
+ i0.ɵɵadvance();
831
+ i0.ɵɵconditional(ctx.PreviewResults.length > 0 ? 56 : -1);
832
+ i0.ɵɵadvance();
833
+ i0.ɵɵproperty("Form", ctx)("FormContext", ctx.formContext);
834
+ i0.ɵɵadvance();
835
+ i0.ɵɵproperty("Form", ctx)("FormContext", ctx.formContext);
836
+ i0.ɵɵadvance();
837
+ i0.ɵɵproperty("Record", ctx.record)("ShowLabel", true)("EditMode", ctx.EditMode)("FormContext", ctx.formContext);
838
+ i0.ɵɵadvance();
839
+ i0.ɵɵproperty("Record", ctx.record)("ShowLabel", true)("EditMode", ctx.EditMode)("FormContext", ctx.formContext);
840
+ i0.ɵɵadvance();
841
+ i0.ɵɵproperty("Form", ctx)("FormContext", ctx.formContext)("BadgeCount", ctx.GetSectionRowCount("mJSearchScopeTestQueries"))("DefaultExpanded", false);
842
+ i0.ɵɵadvance();
843
+ i0.ɵɵconditional(ctx.record.IsSaved ? 62 : -1);
844
+ i0.ɵɵadvance();
845
+ i0.ɵɵproperty("Form", ctx)("FormContext", ctx.formContext)("BadgeCount", ctx.GetSectionRowCount("mJSearchScopeStorageAccounts"))("DefaultExpanded", false);
846
+ i0.ɵɵadvance();
847
+ i0.ɵɵconditional(ctx.record.IsSaved ? 64 : -1);
848
+ i0.ɵɵadvance();
849
+ i0.ɵɵproperty("Form", ctx)("FormContext", ctx.formContext)("BadgeCount", ctx.GetSectionRowCount("mJSearchScopeEntities"))("DefaultExpanded", false);
850
+ i0.ɵɵadvance();
851
+ i0.ɵɵconditional(ctx.record.IsSaved ? 66 : -1);
852
+ i0.ɵɵadvance();
853
+ i0.ɵɵproperty("Form", ctx)("FormContext", ctx.formContext)("BadgeCount", ctx.GetSectionRowCount("mJSearchScopeExternalIndexes"))("DefaultExpanded", false);
854
+ i0.ɵɵadvance();
855
+ i0.ɵɵconditional(ctx.record.IsSaved ? 68 : -1);
856
+ i0.ɵɵadvance();
857
+ i0.ɵɵproperty("Form", ctx)("FormContext", ctx.formContext)("BadgeCount", ctx.GetSectionRowCount("mJSearchScopeProviders"))("DefaultExpanded", false);
858
+ i0.ɵɵadvance();
859
+ i0.ɵɵconditional(ctx.record.IsSaved ? 70 : -1);
860
+ i0.ɵɵadvance();
861
+ i0.ɵɵproperty("Form", ctx)("FormContext", ctx.formContext)("BadgeCount", ctx.GetSectionRowCount("mJAIAgentSearchScopes"))("DefaultExpanded", false);
862
+ i0.ɵɵadvance();
863
+ i0.ɵɵconditional(ctx.record.IsSaved ? 72 : -1);
864
+ i0.ɵɵadvance();
865
+ i0.ɵɵproperty("Form", ctx)("FormContext", ctx.formContext)("BadgeCount", ctx.GetSectionRowCount("mJSearchScopePermissions"))("DefaultExpanded", false);
866
+ i0.ɵɵadvance();
867
+ i0.ɵɵconditional(ctx.record.IsSaved ? 74 : -1);
868
+ i0.ɵɵadvance();
869
+ i0.ɵɵproperty("Form", ctx)("FormContext", ctx.formContext)("BadgeCount", ctx.GetSectionRowCount("mJSearchExecutionLogs"))("DefaultExpanded", false);
870
+ i0.ɵɵadvance();
871
+ i0.ɵɵconditional(ctx.record.IsSaved ? 76 : -1);
872
+ } }, dependencies: [i1.NgSelectOption, i1.ɵNgSelectMultipleOption, i1.SelectControlValueAccessor, i1.NgControlStatus, i1.NgModel, i2.MjFormFieldComponent, i2.MjCollapsiblePanelComponent, i2.MjRecordFormContainerComponent, i2.ExplorerEntityDataGridComponent, i3.DecimalPipe], styles: [".reranker-config[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 0.6rem;\n padding: 0.5rem 0;\n}\n\n.reranker-config-label[_ngcontent-%COMP%] {\n font-weight: 500;\n color: var(--mj-text-primary);\n font-size: 0.85rem;\n}\n\n.reranker-driver-select[_ngcontent-%COMP%] {\n max-width: 480px;\n}\n\n.reranker-cost-hint[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 10%, var(--mj-bg-surface));\n border: 1px solid var(--mj-status-warning-border);\n color: var(--mj-status-warning-text);\n border-radius: 4px;\n padding: 0.5rem 0.75rem;\n font-size: 0.8rem;\n margin: 0;\n display: flex;\n align-items: center;\n gap: 0.5rem;\n}\n\n.reranker-cost-hint[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-warning);\n}\n\n.reranker-help-hint[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-size: 0.78rem;\n margin: 0;\n line-height: 1.4;\n}\n\n.reranker-help-hint[_ngcontent-%COMP%] code[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n padding: 0.1rem 0.3rem;\n border-radius: 3px;\n font-size: 0.74rem;\n}\n\n.reranker-export-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.6rem;\n margin-top: 0.4rem;\n padding-top: 0.6rem;\n border-top: 1px solid var(--mj-border-subtle);\n}\n\n.reranker-export-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 0.4rem;\n padding: 0.35rem 0.8rem;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n border-radius: 4px;\n cursor: pointer;\n font-size: 0.8rem;\n}\n\n.reranker-export-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n.reranker-export-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.reranker-export-hint[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-size: 0.74rem;\n}\n\n.fusion-weights[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n padding: 0.4rem 0;\n}\n\n.fusion-weights-load-btn[_ngcontent-%COMP%] {\n align-self: flex-start;\n display: inline-flex;\n align-items: center;\n gap: 0.4rem;\n padding: 0.35rem 0.8rem;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n border-radius: 4px;\n cursor: pointer;\n font-size: 0.8rem;\n}\n\n.fusion-weights-load-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.fusion-weights-empty[_ngcontent-%COMP%], \n.fusion-weights-help[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-size: 0.78rem;\n margin: 0;\n line-height: 1.4;\n}\n\n.fusion-weights-help[_ngcontent-%COMP%] code[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n padding: 0.1rem 0.3rem;\n border-radius: 3px;\n font-size: 0.74rem;\n}\n\n.fusion-weight-row[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 160px 1fr 56px 16px;\n align-items: center;\n gap: 0.6rem;\n padding: 0.35rem 0;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.fusion-weight-row[_ngcontent-%COMP%]:last-of-type {\n border-bottom: none;\n}\n\n.fusion-weight-label[_ngcontent-%COMP%] {\n font-size: 0.85rem;\n color: var(--mj-text-primary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.fusion-weight-slider[_ngcontent-%COMP%] {\n width: 100%;\n}\n\n.fusion-weight-value[_ngcontent-%COMP%] {\n font-variant-numeric: tabular-nums;\n text-align: right;\n color: var(--mj-text-secondary);\n font-size: 0.82rem;\n}\n\n.fusion-weight-spinner[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n}\n\n.live-preview[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 0.6rem;\n padding: 0.4rem 0;\n}\n\n.live-preview-input-row[_ngcontent-%COMP%] {\n display: flex;\n gap: 0.5rem;\n align-items: center;\n}\n\n.live-preview-input[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.live-preview-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n padding: 0.4rem 0.9rem;\n border: 1px solid var(--mj-brand-primary);\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border-radius: 4px;\n cursor: pointer;\n font-size: 0.82rem;\n white-space: nowrap;\n}\n\n.live-preview-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.live-preview-btn-cancel[_ngcontent-%COMP%] {\n background: var(--mj-status-error);\n border-color: var(--mj-status-error);\n}\n\n.live-preview-error[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n border: 1px solid var(--mj-status-error-border);\n color: var(--mj-status-error-text);\n padding: 0.5rem 0.75rem;\n border-radius: 4px;\n font-size: 0.82rem;\n margin: 0;\n}\n\n.live-preview-chips[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 0.4rem;\n}\n\n.live-preview-chip[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n padding: 0.2rem 0.55rem;\n border-radius: 9999px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 0.74rem;\n}\n\n.live-preview-chip-pending[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n}\n\n.live-preview-chip-completed[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 10%, var(--mj-bg-surface));\n border-color: var(--mj-status-success-border);\n color: var(--mj-status-success-text);\n}\n\n.live-preview-chip-count[_ngcontent-%COMP%] { opacity: 0.7; }\n.live-preview-chip-time[_ngcontent-%COMP%] { opacity: 0.6; font-size: 0.7rem; }\n\n.live-preview-results[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 0.25rem;\n padding-top: 0.5rem;\n border-top: 1px solid var(--mj-border-subtle);\n}\n\n.live-preview-results-header[_ngcontent-%COMP%] {\n font-size: 0.78rem;\n color: var(--mj-text-muted);\n}\n\n.live-preview-result[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 50px 1fr 180px;\n gap: 0.6rem;\n padding: 0.3rem 0;\n border-bottom: 1px solid var(--mj-border-subtle);\n font-size: 0.82rem;\n}\n\n.live-preview-result[_ngcontent-%COMP%]:last-child {\n border-bottom: none;\n}\n\n.live-preview-result-score[_ngcontent-%COMP%] {\n font-variant-numeric: tabular-nums;\n color: var(--mj-text-secondary);\n}\n\n.live-preview-result-title[_ngcontent-%COMP%] {\n color: var(--mj-text-primary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.live-preview-result-entity[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-size: 0.76rem;\n text-align: right;\n}\n\n.live-preview-truncated[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-size: 0.76rem;\n margin: 0.3rem 0 0;\n}\n\n.live-preview-similarity[_ngcontent-%COMP%] {\n color: var(--mj-status-success-text);\n font-weight: 500;\n}\n\n.live-preview-similarity-low[_ngcontent-%COMP%] {\n color: var(--mj-status-warning-text);\n}"] }); }
873
+ };
874
+ MJSearchScopeFormComponentExtended = MJSearchScopeFormComponentExtended_1 = __decorate([
875
+ RegisterClass(BaseFormComponent, 'MJ: Search Scopes')
876
+ ], MJSearchScopeFormComponentExtended);
877
+ export { MJSearchScopeFormComponentExtended };
878
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MJSearchScopeFormComponentExtended, [{
879
+ type: Component,
880
+ args: [{ standalone: false, selector: 'mj-searchscope-form-extended', template: "<mj-record-form-container [Record]=\"record\" [FormComponent]=\"this\"\n (Navigate)=\"OnFormNavigate($event)\"\n (DeleteRequested)=\"OnDeleteRequested()\"\n (FavoriteToggled)=\"OnFavoriteToggled()\"\n (HistoryRequested)=\"OnHistoryRequested()\"\n (ListManagementRequested)=\"OnListManagementRequested()\">\n\n <!-- ========================================\n FIELD PANELS\n ======================================== -->\n <!-- Scope Definition Section -->\n <mj-collapsible-panel\n SectionKey=\"scopeDefinition\"\n SectionName=\"Scope Definition\"\n Icon=\"fa fa-info-circle\"\n [Form]=\"this\"\n [FormContext]=\"formContext\">\n <mj-form-field \n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"Name\"\n Type=\"textbox\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n ></mj-form-field>\n <mj-form-field \n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"Description\"\n Type=\"textarea\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n ></mj-form-field>\n <mj-form-field \n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"Icon\"\n Type=\"textbox\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n ></mj-form-field>\n\n </mj-collapsible-panel>\n\n <!-- Scope Configuration Section -->\n <mj-collapsible-panel\n SectionKey=\"scopeConfiguration\"\n SectionName=\"Scope Configuration\"\n Icon=\"fa fa-sliders-h\"\n [Form]=\"this\"\n [FormContext]=\"formContext\">\n <mj-form-field \n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"IsGlobal\"\n Type=\"checkbox\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n ></mj-form-field>\n <mj-form-field \n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"IsDefault\"\n Type=\"checkbox\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n ></mj-form-field>\n\n </mj-collapsible-panel>\n\n <!-- Access Control Section -->\n <mj-collapsible-panel\n SectionKey=\"accessControl\"\n SectionName=\"Access Control\"\n Icon=\"fa fa-lock\"\n [Form]=\"this\"\n [FormContext]=\"formContext\">\n <mj-form-field \n [Record]=\"record\"\n [ShowLabel]=\"false\"\n FieldName=\"OwnerUserID\"\n Type=\"textbox\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n LinkType=\"Record\"\n ></mj-form-field>\n\n </mj-collapsible-panel>\n\n <!-- Lifecycle Management Section -->\n <mj-collapsible-panel\n SectionKey=\"lifecycleManagement\"\n SectionName=\"Lifecycle Management\"\n Icon=\"fa fa-clock\"\n [Form]=\"this\"\n [FormContext]=\"formContext\">\n <mj-form-field \n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"Status\"\n Type=\"select\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n ></mj-form-field>\n <mj-form-field \n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"StartAt\"\n Type=\"datepicker\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n ></mj-form-field>\n <mj-form-field \n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"EndAt\"\n Type=\"datepicker\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n ></mj-form-field>\n\n </mj-collapsible-panel>\n\n <!-- Technical Configuration Section -->\n <mj-collapsible-panel\n SectionKey=\"technicalConfiguration\"\n SectionName=\"Technical Configuration\"\n Icon=\"fa fa-code\"\n [Form]=\"this\"\n [FormContext]=\"formContext\">\n <mj-form-field \n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"ScopeConfig\"\n Type=\"code\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n ></mj-form-field>\n <mj-form-field \n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"SearchContextConfig\"\n Type=\"code\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n ></mj-form-field>\n\n </mj-collapsible-panel>\n\n <!-- Fusion Weights Section (custom \u2014 P4.2).\n Sliders for each canonical SearchEngine source type, backed by\n SearchScope.ScopeConfig.fusionWeights JSON. Weights >1 amplify a\n provider's contribution; weights <1 dampen it. Default 1 = engine\n default (no override). Plan-doc estimated SearchScopeProvider.Weight\n but that column doesn't exist; the JSON path is the actual contract\n the SearchEngine reads. -->\n <mj-collapsible-panel\n SectionKey=\"fusionWeights\"\n SectionName=\"Fusion Weights\"\n Icon=\"fa fa-sliders-h\"\n [Form]=\"this\"\n [FormContext]=\"formContext\">\n <div class=\"fusion-weights\">\n @for (row of FusionWeights; track row.Key) {\n <div class=\"fusion-weight-row\">\n <span class=\"fusion-weight-label\">{{ row.Label }}</span>\n <input\n class=\"fusion-weight-slider\"\n type=\"range\"\n min=\"0\"\n max=\"5\"\n step=\"0.1\"\n [disabled]=\"!EditMode\"\n [value]=\"row.Weight\"\n (change)=\"OnFusionWeightChanged(row, $any($event.target).valueAsNumber)\" />\n <span class=\"fusion-weight-value\">{{ row.Weight | number:'1.1-1' }}</span>\n </div>\n }\n <p class=\"fusion-weights-help\">\n Drag a slider to update <code>ScopeConfig.fusionWeights</code>. Default 1.0 means \"use engine default\";\n values are persisted on form save.\n </p>\n </div>\n </mj-collapsible-panel>\n\n <!-- Reranker Section (custom \u2014 P2D.7 Angular half).\n Dropdown writes the choice into ScopeConfig JSON's reRanker.driverClass \u2014\n the same path SearchEngine reads at runtime via pickReRankerConfig().\n RerankerBudgetCents is rendered here too so the cost-cap input lives\n right next to the cost-incurring choice. -->\n <mj-collapsible-panel\n SectionKey=\"reranker\"\n SectionName=\"Reranker\"\n Icon=\"fa fa-sort-amount-down\"\n [Form]=\"this\"\n [FormContext]=\"formContext\">\n <div class=\"reranker-config\">\n <label class=\"reranker-config-label\">Reranker driver class</label>\n <select\n class=\"mj-input reranker-driver-select\"\n [disabled]=\"!EditMode\"\n [ngModel]=\"SelectedRerankerDriverClass\"\n (ngModelChange)=\"SelectedRerankerDriverClass = $event\">\n <option value=\"\">\u2014 None (use NoopReRanker) \u2014</option>\n @for (option of AvailableRerankers; track option.DriverClass) {\n <option [value]=\"option.DriverClass\">\n {{ option.Name }}{{ option.HasCost ? ' \u2014 paid' : ' \u2014 free' }}\n </option>\n }\n </select>\n @if (SelectedRerankerHasCost) {\n <p class=\"reranker-cost-hint\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n This reranker incurs API cost per search. Set\n <strong>RerankerBudgetCents</strong> below to cap spend per invocation.\n </p>\n }\n <p class=\"reranker-help-hint\">\n Stored on <code>ScopeConfig.reRanker.driverClass</code> \u2014 the SearchEngine reads this at runtime.\n Leave blank to use the pass-through default.\n </p>\n\n <mj-form-field\n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"RerankerBudgetCents\"\n Type=\"number\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n ></mj-form-field>\n\n <!-- P3.4 \u2014 per-scope tuning CSV export.\n Pulls the last 500 rows from MJ: Search Execution Logs filtered\n to this scope's ID and downloads as CSV for offline analysis. -->\n <div class=\"reranker-export-row\">\n <button class=\"reranker-export-btn\"\n type=\"button\"\n [disabled]=\"!record?.ID || IsExportingTuningCsv\"\n (click)=\"ExportTuningCsv()\">\n @if (IsExportingTuningCsv) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n <span>Exporting\u2026</span>\n } @else {\n <i class=\"fa-solid fa-download\"></i>\n <span>Export tuning data (CSV)</span>\n }\n </button>\n <span class=\"reranker-export-hint\">Last 500 search invocations against this scope.</span>\n </div>\n </div>\n </mj-collapsible-panel>\n\n <!-- Live Preview Section (custom \u2014 P4.1).\n Streaming search against this scope, rendered with chip-strip + result\n list so authors can see how each tuning change (reranker, fusion\n weights, scope template) affects the actual ranked output. -->\n <mj-collapsible-panel\n SectionKey=\"livePreview\"\n SectionName=\"Live Preview\"\n Icon=\"fa fa-flask\"\n [Form]=\"this\"\n [FormContext]=\"formContext\">\n <div class=\"live-preview\">\n <div class=\"live-preview-input-row\">\n <input\n class=\"mj-input live-preview-input\"\n type=\"text\"\n placeholder=\"Type a sample query and press Run\u2026\"\n [disabled]=\"!record?.ID || PreviewIsRunning\"\n [value]=\"PreviewQuery\"\n (input)=\"PreviewQuery = $any($event.target).value\"\n (keydown.enter)=\"RunPreview()\" />\n @if (!PreviewIsRunning) {\n <button class=\"live-preview-btn\"\n type=\"button\"\n [disabled]=\"!record?.ID || !PreviewQuery.trim()\"\n (click)=\"RunPreview()\">\n <i class=\"fa-solid fa-play\"></i> Run\n </button>\n } @else {\n <button class=\"live-preview-btn live-preview-btn-cancel\"\n type=\"button\"\n (click)=\"CancelPreview()\">\n <i class=\"fa-solid fa-stop\"></i> Cancel\n </button>\n }\n </div>\n\n @if (PreviewError) {\n <p class=\"live-preview-error\">\n <i class=\"fa-solid fa-circle-exclamation\"></i> {{ PreviewError }}\n </p>\n }\n\n @if (PreviewIsRunning || PreviewProviders.length > 0) {\n <div class=\"live-preview-chips\">\n @if (PreviewIsRunning && PreviewProviders.length === 0) {\n <span class=\"live-preview-chip live-preview-chip-pending\">\n <i class=\"fa-solid fa-circle-notch fa-spin\"></i> Streaming\u2026\n </span>\n }\n @for (p of PreviewProviders; track p.Name) {\n <span class=\"live-preview-chip live-preview-chip-completed\">\n <i class=\"fa-solid fa-check\"></i>\n <strong>{{ p.Name }}</strong>\n <span class=\"live-preview-chip-count\">{{ p.Count }}</span>\n <span class=\"live-preview-chip-time\">{{ p.ElapsedMs }}ms</span>\n </span>\n }\n </div>\n }\n\n @if (PreviewResults.length > 0) {\n <div class=\"live-preview-results\">\n <div class=\"live-preview-results-header\">\n {{ PreviewResults.length }} result(s)\n @if (PreviewElapsedMs !== null) { in {{ PreviewElapsedMs }}ms }\n @if (LastRunSimilarityPercent !== null) {\n <span class=\"live-preview-similarity\"\n [class.live-preview-similarity-low]=\"LastRunSimilarityPercent < 70\"\n title=\"Kendall-tau rank correlation against the previous run, mapped to [0%, 100%].\">\n \u00B7 {{ LastRunSimilarityPercent }}% similar to last run\n </span>\n }\n </div>\n @for (r of PreviewResults; track r.ID; let i = $index) {\n @if (i < 10) {\n <div class=\"live-preview-result\">\n <span class=\"live-preview-result-score\">{{ (r.Score * 100) | number:'1.0-0' }}%</span>\n <span class=\"live-preview-result-title\">{{ r.Title }}</span>\n <span class=\"live-preview-result-entity\">{{ r.EntityName }}</span>\n </div>\n }\n }\n @if (PreviewResults.length > 10) {\n <p class=\"live-preview-truncated\">\u2026and {{ PreviewResults.length - 10 }} more (preview shows top 10).</p>\n }\n </div>\n }\n </div>\n </mj-collapsible-panel>\n\n <!-- Details Section (kept empty \u2014 RerankerBudgetCents now lives in the\n Reranker section above where it semantically belongs) -->\n <mj-collapsible-panel\n SectionKey=\"details\"\n SectionName=\"Details\"\n Icon=\"fa fa-align-left\"\n [Form]=\"this\"\n [FormContext]=\"formContext\">\n </mj-collapsible-panel>\n\n <!-- System Metadata Section -->\n <mj-collapsible-panel\n SectionKey=\"systemMetadata\"\n SectionName=\"System Metadata\"\n Icon=\"fa fa-cog\"\n [Form]=\"this\"\n [FormContext]=\"formContext\">\n <mj-form-field \n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"__mj_CreatedAt\"\n Type=\"textbox\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n ></mj-form-field>\n <mj-form-field \n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"__mj_UpdatedAt\"\n Type=\"textbox\"\n [EditMode]=\"EditMode\"\n [FormContext]=\"formContext\"\n ></mj-form-field>\n\n </mj-collapsible-panel>\n\n <!-- ========================================\n RELATED ENTITY PANELS\n ======================================== -->\n\n <!-- Search Scope Test Queries Section (P4.4) \u2014 canonical test queries for\n offline tuning. Authors save representative queries here, re-run them\n after a config change, and compare results. -->\n <mj-collapsible-panel\n SectionKey=\"mJSearchScopeTestQueries\"\n SectionName=\"Search Scope Test Queries\"\n Icon=\"fa fa-table\"\n Variant=\"related-entity\"\n [Form]=\"this\"\n [FormContext]=\"formContext\"\n [BadgeCount]=\"GetSectionRowCount('mJSearchScopeTestQueries')\"\n [DefaultExpanded]=\"false\">\n @if (record.IsSaved) {\n <div>\n <mj-explorer-entity-data-grid\n [Params]=\"BuildRelationshipViewParamsByEntityName('MJ: Search Scope Test Queries','SearchScopeID')\"\n [NewRecordValues]=\"NewRecordValues('MJ: Search Scope Test Queries')\"\n [AllowLoad]=\"IsSectionExpanded('mJSearchScopeTestQueries')\"\n [ShowToolbar]=\"true\"\n (Navigate)=\"OnFormNavigate($event)\"\n (AfterDataLoad)=\"SetSectionRowCount('mJSearchScopeTestQueries', $event.totalRowCount)\"\n >\n </mj-explorer-entity-data-grid>\n </div>\n }\n </mj-collapsible-panel>\n\n <!-- Search Scope Storage Accounts Section -->\n <mj-collapsible-panel\n SectionKey=\"mJSearchScopeStorageAccounts\"\n SectionName=\"Search Scope Storage Accounts\"\n Icon=\"fa fa-folder-open\"\n Variant=\"related-entity\"\n [Form]=\"this\"\n [FormContext]=\"formContext\"\n [BadgeCount]=\"GetSectionRowCount('mJSearchScopeStorageAccounts')\"\n [DefaultExpanded]=\"false\">\n @if (record.IsSaved) {\n <div>\n <mj-explorer-entity-data-grid\n [Params]=\"BuildRelationshipViewParamsByEntityName('MJ: Search Scope Storage Accounts','SearchScopeID')\"\n [NewRecordValues]=\"NewRecordValues('MJ: Search Scope Storage Accounts')\"\n [AllowLoad]=\"IsSectionExpanded('mJSearchScopeStorageAccounts')\"\n [ShowToolbar]=\"true\"\n (Navigate)=\"OnFormNavigate($event)\"\n (AfterDataLoad)=\"SetSectionRowCount('mJSearchScopeStorageAccounts', $event.totalRowCount)\"\n >\n </mj-explorer-entity-data-grid>\n </div>\n }\n </mj-collapsible-panel>\n\n <!-- Search Scope Entities Section -->\n <mj-collapsible-panel\n SectionKey=\"mJSearchScopeEntities\"\n SectionName=\"Search Scope Entities\"\n Icon=\"fa fa-search\"\n Variant=\"related-entity\"\n [Form]=\"this\"\n [FormContext]=\"formContext\"\n [BadgeCount]=\"GetSectionRowCount('mJSearchScopeEntities')\"\n [DefaultExpanded]=\"false\">\n @if (record.IsSaved) {\n <div>\n <mj-explorer-entity-data-grid\n [Params]=\"BuildRelationshipViewParamsByEntityName('MJ: Search Scope Entities','SearchScopeID')\"\n [NewRecordValues]=\"NewRecordValues('MJ: Search Scope Entities')\"\n [AllowLoad]=\"IsSectionExpanded('mJSearchScopeEntities')\"\n [ShowToolbar]=\"true\"\n (Navigate)=\"OnFormNavigate($event)\"\n (AfterDataLoad)=\"SetSectionRowCount('mJSearchScopeEntities', $event.totalRowCount)\"\n >\n </mj-explorer-entity-data-grid>\n </div>\n }\n </mj-collapsible-panel>\n\n <!-- Search Scope External Indexes Section -->\n <mj-collapsible-panel\n SectionKey=\"mJSearchScopeExternalIndexes\"\n SectionName=\"Search Scope External Indexes\"\n Icon=\"fa fa-search-plus\"\n Variant=\"related-entity\"\n [Form]=\"this\"\n [FormContext]=\"formContext\"\n [BadgeCount]=\"GetSectionRowCount('mJSearchScopeExternalIndexes')\"\n [DefaultExpanded]=\"false\">\n @if (record.IsSaved) {\n <div>\n <mj-explorer-entity-data-grid\n [Params]=\"BuildRelationshipViewParamsByEntityName('MJ: Search Scope External Indexes','SearchScopeID')\"\n [NewRecordValues]=\"NewRecordValues('MJ: Search Scope External Indexes')\"\n [AllowLoad]=\"IsSectionExpanded('mJSearchScopeExternalIndexes')\"\n [ShowToolbar]=\"true\"\n (Navigate)=\"OnFormNavigate($event)\"\n (AfterDataLoad)=\"SetSectionRowCount('mJSearchScopeExternalIndexes', $event.totalRowCount)\"\n >\n </mj-explorer-entity-data-grid>\n </div>\n }\n </mj-collapsible-panel>\n\n <!-- Search Scope Providers Section -->\n <mj-collapsible-panel\n SectionKey=\"mJSearchScopeProviders\"\n SectionName=\"Search Scope Providers\"\n Icon=\"fa fa-search-plus\"\n Variant=\"related-entity\"\n [Form]=\"this\"\n [FormContext]=\"formContext\"\n [BadgeCount]=\"GetSectionRowCount('mJSearchScopeProviders')\"\n [DefaultExpanded]=\"false\">\n @if (record.IsSaved) {\n <div>\n <mj-explorer-entity-data-grid\n [Params]=\"BuildRelationshipViewParamsByEntityName('MJ: Search Scope Providers','SearchScopeID')\"\n [NewRecordValues]=\"NewRecordValues('MJ: Search Scope Providers')\"\n [AllowLoad]=\"IsSectionExpanded('mJSearchScopeProviders')\"\n [ShowToolbar]=\"true\"\n (Navigate)=\"OnFormNavigate($event)\"\n (AfterDataLoad)=\"SetSectionRowCount('mJSearchScopeProviders', $event.totalRowCount)\"\n >\n </mj-explorer-entity-data-grid>\n </div>\n }\n </mj-collapsible-panel>\n\n <!-- AI Agent Search Scopes Section -->\n <mj-collapsible-panel\n SectionKey=\"mJAIAgentSearchScopes\"\n SectionName=\"AI Agent Search Scopes\"\n Icon=\"fa fa-search-plus\"\n Variant=\"related-entity\"\n [Form]=\"this\"\n [FormContext]=\"formContext\"\n [BadgeCount]=\"GetSectionRowCount('mJAIAgentSearchScopes')\"\n [DefaultExpanded]=\"false\">\n @if (record.IsSaved) {\n <div>\n <mj-explorer-entity-data-grid\n [Params]=\"BuildRelationshipViewParamsByEntityName('MJ: AI Agent Search Scopes','SearchScopeID')\"\n [NewRecordValues]=\"NewRecordValues('MJ: AI Agent Search Scopes')\"\n [AllowLoad]=\"IsSectionExpanded('mJAIAgentSearchScopes')\"\n [ShowToolbar]=\"true\"\n (Navigate)=\"OnFormNavigate($event)\"\n (AfterDataLoad)=\"SetSectionRowCount('mJAIAgentSearchScopes', $event.totalRowCount)\"\n >\n </mj-explorer-entity-data-grid>\n </div>\n }\n </mj-collapsible-panel>\n\n <!-- Search Scope Permissions Section -->\n <mj-collapsible-panel\n SectionKey=\"mJSearchScopePermissions\"\n SectionName=\"Search Scope Permissions\"\n Icon=\"fa fa-table\"\n Variant=\"related-entity\"\n [Form]=\"this\"\n [FormContext]=\"formContext\"\n [BadgeCount]=\"GetSectionRowCount('mJSearchScopePermissions')\"\n [DefaultExpanded]=\"false\">\n @if (record.IsSaved) {\n <div>\n <mj-explorer-entity-data-grid\n [Params]=\"BuildRelationshipViewParamsByEntityName('MJ: Search Scope Permissions','SearchScopeID')\"\n [NewRecordValues]=\"NewRecordValues('MJ: Search Scope Permissions')\"\n [AllowLoad]=\"IsSectionExpanded('mJSearchScopePermissions')\"\n [ShowToolbar]=\"true\"\n (Navigate)=\"OnFormNavigate($event)\"\n (AfterDataLoad)=\"SetSectionRowCount('mJSearchScopePermissions', $event.totalRowCount)\"\n >\n </mj-explorer-entity-data-grid>\n </div>\n }\n </mj-collapsible-panel>\n\n <!-- Search Execution Logs Section -->\n <mj-collapsible-panel\n SectionKey=\"mJSearchExecutionLogs\"\n SectionName=\"Search Execution Logs\"\n Icon=\"fa fa-table\"\n Variant=\"related-entity\"\n [Form]=\"this\"\n [FormContext]=\"formContext\"\n [BadgeCount]=\"GetSectionRowCount('mJSearchExecutionLogs')\"\n [DefaultExpanded]=\"false\">\n @if (record.IsSaved) {\n <div>\n <mj-explorer-entity-data-grid\n [Params]=\"BuildRelationshipViewParamsByEntityName('MJ: Search Execution Logs','SearchScopeID')\"\n [NewRecordValues]=\"NewRecordValues('MJ: Search Execution Logs')\"\n [AllowLoad]=\"IsSectionExpanded('mJSearchExecutionLogs')\"\n [ShowToolbar]=\"false\"\n (Navigate)=\"OnFormNavigate($event)\"\n (AfterDataLoad)=\"SetSectionRowCount('mJSearchExecutionLogs', $event.totalRowCount)\"\n >\n </mj-explorer-entity-data-grid>\n </div>\n }\n </mj-collapsible-panel>\n</mj-record-form-container>\n ", styles: [".reranker-config {\n display: flex;\n flex-direction: column;\n gap: 0.6rem;\n padding: 0.5rem 0;\n}\n\n.reranker-config-label {\n font-weight: 500;\n color: var(--mj-text-primary);\n font-size: 0.85rem;\n}\n\n.reranker-driver-select {\n max-width: 480px;\n}\n\n.reranker-cost-hint {\n background: color-mix(in srgb, var(--mj-status-warning) 10%, var(--mj-bg-surface));\n border: 1px solid var(--mj-status-warning-border);\n color: var(--mj-status-warning-text);\n border-radius: 4px;\n padding: 0.5rem 0.75rem;\n font-size: 0.8rem;\n margin: 0;\n display: flex;\n align-items: center;\n gap: 0.5rem;\n}\n\n.reranker-cost-hint i {\n color: var(--mj-status-warning);\n}\n\n.reranker-help-hint {\n color: var(--mj-text-muted);\n font-size: 0.78rem;\n margin: 0;\n line-height: 1.4;\n}\n\n.reranker-help-hint code {\n background: var(--mj-bg-surface-sunken);\n padding: 0.1rem 0.3rem;\n border-radius: 3px;\n font-size: 0.74rem;\n}\n\n.reranker-export-row {\n display: flex;\n align-items: center;\n gap: 0.6rem;\n margin-top: 0.4rem;\n padding-top: 0.6rem;\n border-top: 1px solid var(--mj-border-subtle);\n}\n\n.reranker-export-btn {\n display: inline-flex;\n align-items: center;\n gap: 0.4rem;\n padding: 0.35rem 0.8rem;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n border-radius: 4px;\n cursor: pointer;\n font-size: 0.8rem;\n}\n\n.reranker-export-btn:hover:not(:disabled) {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n.reranker-export-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.reranker-export-hint {\n color: var(--mj-text-muted);\n font-size: 0.74rem;\n}\n\n.fusion-weights {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n padding: 0.4rem 0;\n}\n\n.fusion-weights-load-btn {\n align-self: flex-start;\n display: inline-flex;\n align-items: center;\n gap: 0.4rem;\n padding: 0.35rem 0.8rem;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n border-radius: 4px;\n cursor: pointer;\n font-size: 0.8rem;\n}\n\n.fusion-weights-load-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.fusion-weights-empty,\n.fusion-weights-help {\n color: var(--mj-text-muted);\n font-size: 0.78rem;\n margin: 0;\n line-height: 1.4;\n}\n\n.fusion-weights-help code {\n background: var(--mj-bg-surface-sunken);\n padding: 0.1rem 0.3rem;\n border-radius: 3px;\n font-size: 0.74rem;\n}\n\n.fusion-weight-row {\n display: grid;\n grid-template-columns: 160px 1fr 56px 16px;\n align-items: center;\n gap: 0.6rem;\n padding: 0.35rem 0;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.fusion-weight-row:last-of-type {\n border-bottom: none;\n}\n\n.fusion-weight-label {\n font-size: 0.85rem;\n color: var(--mj-text-primary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.fusion-weight-slider {\n width: 100%;\n}\n\n.fusion-weight-value {\n font-variant-numeric: tabular-nums;\n text-align: right;\n color: var(--mj-text-secondary);\n font-size: 0.82rem;\n}\n\n.fusion-weight-spinner {\n color: var(--mj-text-muted);\n}\n\n.live-preview {\n display: flex;\n flex-direction: column;\n gap: 0.6rem;\n padding: 0.4rem 0;\n}\n\n.live-preview-input-row {\n display: flex;\n gap: 0.5rem;\n align-items: center;\n}\n\n.live-preview-input {\n flex: 1;\n min-width: 0;\n}\n\n.live-preview-btn {\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n padding: 0.4rem 0.9rem;\n border: 1px solid var(--mj-brand-primary);\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border-radius: 4px;\n cursor: pointer;\n font-size: 0.82rem;\n white-space: nowrap;\n}\n\n.live-preview-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.live-preview-btn-cancel {\n background: var(--mj-status-error);\n border-color: var(--mj-status-error);\n}\n\n.live-preview-error {\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n border: 1px solid var(--mj-status-error-border);\n color: var(--mj-status-error-text);\n padding: 0.5rem 0.75rem;\n border-radius: 4px;\n font-size: 0.82rem;\n margin: 0;\n}\n\n.live-preview-chips {\n display: flex;\n flex-wrap: wrap;\n gap: 0.4rem;\n}\n\n.live-preview-chip {\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n padding: 0.2rem 0.55rem;\n border-radius: 9999px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 0.74rem;\n}\n\n.live-preview-chip-pending {\n color: var(--mj-text-muted);\n}\n\n.live-preview-chip-completed {\n background: color-mix(in srgb, var(--mj-status-success) 10%, var(--mj-bg-surface));\n border-color: var(--mj-status-success-border);\n color: var(--mj-status-success-text);\n}\n\n.live-preview-chip-count { opacity: 0.7; }\n.live-preview-chip-time { opacity: 0.6; font-size: 0.7rem; }\n\n.live-preview-results {\n display: flex;\n flex-direction: column;\n gap: 0.25rem;\n padding-top: 0.5rem;\n border-top: 1px solid var(--mj-border-subtle);\n}\n\n.live-preview-results-header {\n font-size: 0.78rem;\n color: var(--mj-text-muted);\n}\n\n.live-preview-result {\n display: grid;\n grid-template-columns: 50px 1fr 180px;\n gap: 0.6rem;\n padding: 0.3rem 0;\n border-bottom: 1px solid var(--mj-border-subtle);\n font-size: 0.82rem;\n}\n\n.live-preview-result:last-child {\n border-bottom: none;\n}\n\n.live-preview-result-score {\n font-variant-numeric: tabular-nums;\n color: var(--mj-text-secondary);\n}\n\n.live-preview-result-title {\n color: var(--mj-text-primary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.live-preview-result-entity {\n color: var(--mj-text-muted);\n font-size: 0.76rem;\n text-align: right;\n}\n\n.live-preview-truncated {\n color: var(--mj-text-muted);\n font-size: 0.76rem;\n margin: 0.3rem 0 0;\n}\n\n.live-preview-similarity {\n color: var(--mj-status-success-text);\n font-weight: 500;\n}\n\n.live-preview-similarity-low {\n color: var(--mj-status-warning-text);\n}\n"] }]
881
+ }], null, null); })();
882
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MJSearchScopeFormComponentExtended, { className: "MJSearchScopeFormComponentExtended", filePath: "src/lib/custom/SearchScopes/searchscope-form.component.ts", lineNumber: 77 }); })();
883
+ export function LoadMJSearchScopeFormComponentExtended() {
884
+ // Tree-shake prevention; called from custom-forms.module's LoadCoreCustomForms()
885
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
886
+ const _ref = MJSearchScopeFormComponentExtended;
887
+ }
888
+ //# sourceMappingURL=searchscope-form.component.js.map