@memberjunction/ng-core-entity-forms 6.2.0-edge.1 → 6.2.0-edge.2

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 (161) hide show
  1. package/dist/lib/custom/AIAgents/agent-form-tabs.d.ts +1 -0
  2. package/dist/lib/custom/AIAgents/agent-form-tabs.d.ts.map +1 -1
  3. package/dist/lib/custom/AIAgents/agent-form-tabs.js +2 -0
  4. package/dist/lib/custom/AIAgents/agent-form-tabs.js.map +1 -1
  5. package/dist/lib/custom/AIAgents/ai-agent-form.component.js +528 -521
  6. package/dist/lib/custom/AIAgents/ai-agent-form.component.js.map +1 -1
  7. package/dist/lib/custom/AIPrompts/ai-prompt-form.component.d.ts.map +1 -1
  8. package/dist/lib/custom/AIPrompts/ai-prompt-form.component.js +10 -16
  9. package/dist/lib/custom/AIPrompts/ai-prompt-form.component.js.map +1 -1
  10. package/dist/lib/custom/AIPrompts/pending-records.d.ts +11 -0
  11. package/dist/lib/custom/AIPrompts/pending-records.d.ts.map +1 -0
  12. package/dist/lib/custom/AIPrompts/pending-records.js +21 -0
  13. package/dist/lib/custom/AIPrompts/pending-records.js.map +1 -0
  14. package/dist/lib/custom/Entities/entity-form.component.d.ts +8 -1
  15. package/dist/lib/custom/Entities/entity-form.component.d.ts.map +1 -1
  16. package/dist/lib/custom/Entities/entity-form.component.js +240 -147
  17. package/dist/lib/custom/Entities/entity-form.component.js.map +1 -1
  18. package/dist/lib/custom/RecordProcesses/record-process-form.component.d.ts +19 -0
  19. package/dist/lib/custom/RecordProcesses/record-process-form.component.d.ts.map +1 -1
  20. package/dist/lib/custom/RecordProcesses/record-process-form.component.js +50 -8
  21. package/dist/lib/custom/RecordProcesses/record-process-form.component.js.map +1 -1
  22. package/dist/lib/custom/Rubrics/evaluation-form.component.d.ts +37 -0
  23. package/dist/lib/custom/Rubrics/evaluation-form.component.d.ts.map +1 -0
  24. package/dist/lib/custom/Rubrics/evaluation-form.component.js +399 -0
  25. package/dist/lib/custom/Rubrics/evaluation-form.component.js.map +1 -0
  26. package/dist/lib/custom/Rubrics/record-forms.component.d.ts +69 -0
  27. package/dist/lib/custom/Rubrics/record-forms.component.d.ts.map +1 -0
  28. package/dist/lib/custom/Rubrics/record-forms.component.js +587 -0
  29. package/dist/lib/custom/Rubrics/record-forms.component.js.map +1 -0
  30. package/dist/lib/custom/Rubrics/rubric-form.component.d.ts +67 -0
  31. package/dist/lib/custom/Rubrics/rubric-form.component.d.ts.map +1 -0
  32. package/dist/lib/custom/Rubrics/rubric-form.component.js +534 -0
  33. package/dist/lib/custom/Rubrics/rubric-form.component.js.map +1 -0
  34. package/dist/lib/custom/Rubrics/rubric-form.panels.d.ts +25 -0
  35. package/dist/lib/custom/Rubrics/rubric-form.panels.d.ts.map +1 -0
  36. package/dist/lib/custom/Rubrics/rubric-form.panels.js +299 -0
  37. package/dist/lib/custom/Rubrics/rubric-form.panels.js.map +1 -0
  38. package/dist/lib/custom/Rubrics/scale-form.component.d.ts +31 -0
  39. package/dist/lib/custom/Rubrics/scale-form.component.d.ts.map +1 -0
  40. package/dist/lib/custom/Rubrics/scale-form.component.js +395 -0
  41. package/dist/lib/custom/Rubrics/scale-form.component.js.map +1 -0
  42. package/dist/lib/custom/Templates/templates-form.component.d.ts +13 -4
  43. package/dist/lib/custom/Templates/templates-form.component.d.ts.map +1 -1
  44. package/dist/lib/custom/Templates/templates-form.component.js +110 -113
  45. package/dist/lib/custom/Templates/templates-form.component.js.map +1 -1
  46. package/dist/lib/custom/Tests/test-form.component.d.ts +6 -0
  47. package/dist/lib/custom/Tests/test-form.component.d.ts.map +1 -1
  48. package/dist/lib/custom/Tests/test-form.component.js +402 -361
  49. package/dist/lib/custom/Tests/test-form.component.js.map +1 -1
  50. package/dist/lib/custom/Tests/test-suite-form.component.d.ts +5 -0
  51. package/dist/lib/custom/Tests/test-suite-form.component.d.ts.map +1 -1
  52. package/dist/lib/custom/Tests/test-suite-form.component.js +704 -664
  53. package/dist/lib/custom/Tests/test-suite-form.component.js.map +1 -1
  54. package/dist/lib/custom/Users/user-overview.panel.js +1 -1
  55. package/dist/lib/custom/Users/user-overview.panel.js.map +1 -1
  56. package/dist/lib/custom/custom-forms.module.d.ts +56 -48
  57. package/dist/lib/custom/custom-forms.module.d.ts.map +1 -1
  58. package/dist/lib/custom/custom-forms.module.js +60 -0
  59. package/dist/lib/custom/custom-forms.module.js.map +1 -1
  60. package/dist/lib/generated/Entities/MJAIAgent/mjaiagent.form.component.d.ts.map +1 -1
  61. package/dist/lib/generated/Entities/MJAIAgent/mjaiagent.form.component.js +61 -43
  62. package/dist/lib/generated/Entities/MJAIAgent/mjaiagent.form.component.js.map +1 -1
  63. package/dist/lib/generated/Entities/MJAIAgentRubric/mjaiagentrubric.form.component.d.ts +10 -0
  64. package/dist/lib/generated/Entities/MJAIAgentRubric/mjaiagentrubric.form.component.d.ts.map +1 -0
  65. package/dist/lib/generated/Entities/MJAIAgentRubric/mjaiagentrubric.form.component.js +74 -0
  66. package/dist/lib/generated/Entities/MJAIAgentRubric/mjaiagentrubric.form.component.js.map +1 -0
  67. package/dist/lib/generated/Entities/MJAIAgentRun/mjaiagentrun.form.component.d.ts.map +1 -1
  68. package/dist/lib/generated/Entities/MJAIAgentRun/mjaiagentrun.form.component.js +37 -19
  69. package/dist/lib/generated/Entities/MJAIAgentRun/mjaiagentrun.form.component.js.map +1 -1
  70. package/dist/lib/generated/Entities/MJAIPromptRun/mjaipromptrun.form.component.d.ts.map +1 -1
  71. package/dist/lib/generated/Entities/MJAIPromptRun/mjaipromptrun.form.component.js +31 -13
  72. package/dist/lib/generated/Entities/MJAIPromptRun/mjaipromptrun.form.component.js.map +1 -1
  73. package/dist/lib/generated/Entities/MJEntity/mjentity.form.component.d.ts.map +1 -1
  74. package/dist/lib/generated/Entities/MJEntity/mjentity.form.component.js +156 -84
  75. package/dist/lib/generated/Entities/MJEntity/mjentity.form.component.js.map +1 -1
  76. package/dist/lib/generated/Entities/MJFeaturePipelineType/mjfeaturepipelinetype.form.component.d.ts +10 -0
  77. package/dist/lib/generated/Entities/MJFeaturePipelineType/mjfeaturepipelinetype.form.component.d.ts.map +1 -0
  78. package/dist/lib/generated/Entities/MJFeaturePipelineType/mjfeaturepipelinetype.form.component.js +62 -0
  79. package/dist/lib/generated/Entities/MJFeaturePipelineType/mjfeaturepipelinetype.form.component.js.map +1 -0
  80. package/dist/lib/generated/Entities/MJProcessRun/mjprocessrun.form.component.d.ts.map +1 -1
  81. package/dist/lib/generated/Entities/MJProcessRun/mjprocessrun.form.component.js +24 -6
  82. package/dist/lib/generated/Entities/MJProcessRun/mjprocessrun.form.component.js.map +1 -1
  83. package/dist/lib/generated/Entities/MJRecordChange/mjrecordchange.form.component.d.ts.map +1 -1
  84. package/dist/lib/generated/Entities/MJRecordChange/mjrecordchange.form.component.js +24 -16
  85. package/dist/lib/generated/Entities/MJRecordChange/mjrecordchange.form.component.js.map +1 -1
  86. package/dist/lib/generated/Entities/MJRecordCloneLog/mjrecordclonelog.form.component.d.ts +10 -0
  87. package/dist/lib/generated/Entities/MJRecordCloneLog/mjrecordclonelog.form.component.d.ts.map +1 -0
  88. package/dist/lib/generated/Entities/MJRecordCloneLog/mjrecordclonelog.form.component.js +107 -0
  89. package/dist/lib/generated/Entities/MJRecordCloneLog/mjrecordclonelog.form.component.js.map +1 -0
  90. package/dist/lib/generated/Entities/MJRecordCloneLogItem/mjrecordclonelogitem.form.component.d.ts +10 -0
  91. package/dist/lib/generated/Entities/MJRecordCloneLogItem/mjrecordclonelogitem.form.component.d.ts.map +1 -0
  92. package/dist/lib/generated/Entities/MJRecordCloneLogItem/mjrecordclonelogitem.form.component.js +74 -0
  93. package/dist/lib/generated/Entities/MJRecordCloneLogItem/mjrecordclonelogitem.form.component.js.map +1 -0
  94. package/dist/lib/generated/Entities/MJRubric/mjrubric.form.component.d.ts +10 -0
  95. package/dist/lib/generated/Entities/MJRubric/mjrubric.form.component.d.ts.map +1 -0
  96. package/dist/lib/generated/Entities/MJRubric/mjrubric.form.component.js +135 -0
  97. package/dist/lib/generated/Entities/MJRubric/mjrubric.form.component.js.map +1 -0
  98. package/dist/lib/generated/Entities/MJRubricBand/mjrubricband.form.component.d.ts +10 -0
  99. package/dist/lib/generated/Entities/MJRubricBand/mjrubricband.form.component.d.ts.map +1 -0
  100. package/dist/lib/generated/Entities/MJRubricBand/mjrubricband.form.component.js +87 -0
  101. package/dist/lib/generated/Entities/MJRubricBand/mjrubricband.form.component.js.map +1 -0
  102. package/dist/lib/generated/Entities/MJRubricCategory/mjrubriccategory.form.component.d.ts +10 -0
  103. package/dist/lib/generated/Entities/MJRubricCategory/mjrubriccategory.form.component.d.ts.map +1 -0
  104. package/dist/lib/generated/Entities/MJRubricCategory/mjrubriccategory.form.component.js +107 -0
  105. package/dist/lib/generated/Entities/MJRubricCategory/mjrubriccategory.form.component.js.map +1 -0
  106. package/dist/lib/generated/Entities/MJRubricCriterion/mjrubriccriterion.form.component.d.ts +10 -0
  107. package/dist/lib/generated/Entities/MJRubricCriterion/mjrubriccriterion.form.component.d.ts.map +1 -0
  108. package/dist/lib/generated/Entities/MJRubricCriterion/mjrubriccriterion.form.component.js +155 -0
  109. package/dist/lib/generated/Entities/MJRubricCriterion/mjrubriccriterion.form.component.js.map +1 -0
  110. package/dist/lib/generated/Entities/MJRubricCriterionLevel/mjrubriccriterionlevel.form.component.d.ts +10 -0
  111. package/dist/lib/generated/Entities/MJRubricCriterionLevel/mjrubriccriterionlevel.form.component.d.ts.map +1 -0
  112. package/dist/lib/generated/Entities/MJRubricCriterionLevel/mjrubriccriterionlevel.form.component.js +62 -0
  113. package/dist/lib/generated/Entities/MJRubricCriterionLevel/mjrubriccriterionlevel.form.component.js.map +1 -0
  114. package/dist/lib/generated/Entities/MJRubricEvaluation/mjrubricevaluation.form.component.d.ts +10 -0
  115. package/dist/lib/generated/Entities/MJRubricEvaluation/mjrubricevaluation.form.component.d.ts.map +1 -0
  116. package/dist/lib/generated/Entities/MJRubricEvaluation/mjrubricevaluation.form.component.js +183 -0
  117. package/dist/lib/generated/Entities/MJRubricEvaluation/mjrubricevaluation.form.component.js.map +1 -0
  118. package/dist/lib/generated/Entities/MJRubricEvaluationScore/mjrubricevaluationscore.form.component.d.ts +10 -0
  119. package/dist/lib/generated/Entities/MJRubricEvaluationScore/mjrubricevaluationscore.form.component.d.ts.map +1 -0
  120. package/dist/lib/generated/Entities/MJRubricEvaluationScore/mjrubricevaluationscore.form.component.js +120 -0
  121. package/dist/lib/generated/Entities/MJRubricEvaluationScore/mjrubricevaluationscore.form.component.js.map +1 -0
  122. package/dist/lib/generated/Entities/MJRubricScale/mjrubricscale.form.component.d.ts +10 -0
  123. package/dist/lib/generated/Entities/MJRubricScale/mjrubricscale.form.component.d.ts.map +1 -0
  124. package/dist/lib/generated/Entities/MJRubricScale/mjrubricscale.form.component.js +107 -0
  125. package/dist/lib/generated/Entities/MJRubricScale/mjrubricscale.form.component.js.map +1 -0
  126. package/dist/lib/generated/Entities/MJRubricScaleLevel/mjrubricscalelevel.form.component.d.ts +10 -0
  127. package/dist/lib/generated/Entities/MJRubricScaleLevel/mjrubricscalelevel.form.component.d.ts.map +1 -0
  128. package/dist/lib/generated/Entities/MJRubricScaleLevel/mjrubricscalelevel.form.component.js +103 -0
  129. package/dist/lib/generated/Entities/MJRubricScaleLevel/mjrubricscalelevel.form.component.js.map +1 -0
  130. package/dist/lib/generated/Entities/MJRubricVersion/mjrubricversion.form.component.d.ts +10 -0
  131. package/dist/lib/generated/Entities/MJRubricVersion/mjrubricversion.form.component.d.ts.map +1 -0
  132. package/dist/lib/generated/Entities/MJRubricVersion/mjrubricversion.form.component.js +171 -0
  133. package/dist/lib/generated/Entities/MJRubricVersion/mjrubricversion.form.component.js.map +1 -0
  134. package/dist/lib/generated/Entities/MJTest/mjtest.form.component.d.ts.map +1 -1
  135. package/dist/lib/generated/Entities/MJTest/mjtest.form.component.js +24 -16
  136. package/dist/lib/generated/Entities/MJTest/mjtest.form.component.js.map +1 -1
  137. package/dist/lib/generated/Entities/MJTestSuite/mjtestsuite.form.component.js +27 -25
  138. package/dist/lib/generated/Entities/MJTestSuite/mjtestsuite.form.component.js.map +1 -1
  139. package/dist/lib/generated/Entities/MJTestSuiteRun/mjtestsuiterun.form.component.d.ts.map +1 -1
  140. package/dist/lib/generated/Entities/MJTestSuiteRun/mjtestsuiterun.form.component.js +19 -11
  141. package/dist/lib/generated/Entities/MJTestSuiteRun/mjtestsuiterun.form.component.js.map +1 -1
  142. package/dist/lib/generated/Entities/MJUser/mjuser.form.component.d.ts.map +1 -1
  143. package/dist/lib/generated/Entities/MJUser/mjuser.form.component.js +172 -118
  144. package/dist/lib/generated/Entities/MJUser/mjuser.form.component.js.map +1 -1
  145. package/dist/lib/generated/generated-forms.module.d.ts +436 -422
  146. package/dist/lib/generated/generated-forms.module.d.ts.map +1 -1
  147. package/dist/lib/generated/generated-forms.module.js +44 -2
  148. package/dist/lib/generated/generated-forms.module.js.map +1 -1
  149. package/dist/lib/panels/record-clone/entity-clone-config-editor.component.d.ts +116 -0
  150. package/dist/lib/panels/record-clone/entity-clone-config-editor.component.d.ts.map +1 -0
  151. package/dist/lib/panels/record-clone/entity-clone-config-editor.component.js +820 -0
  152. package/dist/lib/panels/record-clone/entity-clone-config-editor.component.js.map +1 -0
  153. package/dist/lib/shared/components/template-editor.component.d.ts +25 -1
  154. package/dist/lib/shared/components/template-editor.component.d.ts.map +1 -1
  155. package/dist/lib/shared/components/template-editor.component.js +67 -3
  156. package/dist/lib/shared/components/template-editor.component.js.map +1 -1
  157. package/dist/public-api.d.ts +5 -0
  158. package/dist/public-api.d.ts.map +1 -1
  159. package/dist/public-api.js +5 -0
  160. package/dist/public-api.js.map +1 -1
  161. package/package.json +47 -43
@@ -17,7 +17,7 @@ import { SharedService, NavigationService } from '@memberjunction/ng-shared';
17
17
  import { ApplicationManager } from '@memberjunction/ng-base-application';
18
18
  import { MJConfirmService } from '@memberjunction/ng-ui-components';
19
19
  import { MJTestSuiteFormComponent } from '../../generated/Entities/MJTestSuite/mjtestsuite.form.component';
20
- import { TestingDialogService, TagsHelper, EvaluationPreferencesService } from '@memberjunction/ng-testing';
20
+ import { TestingDialogService, TagsHelper, EvaluationPreferencesService, RubricPickerOptions } from '@memberjunction/ng-testing';
21
21
  import * as i0 from "@angular/core";
22
22
  import * as i1 from "@angular/common";
23
23
  import * as i2 from "@angular/forms";
@@ -34,7 +34,8 @@ const _c5 = (a0, a1, a2) => ({ "high": a0, "medium": a1, "low": a2 });
34
34
  const _c6 = (a0, a1) => ({ "positive": a0, "negative": a1 });
35
35
  const _c7 = (a0, a1, a2) => ({ "fa-arrow-down": a0, "fa-arrow-up": a1, "fa-minus": a2 });
36
36
  const _c8 = (a0, a1) => ({ "improved": a0, "regressed": a1 });
37
- const _forTrack0 = ($index, $item) => $item.ID;
37
+ const _forTrack0 = ($index, $item) => $item.id;
38
+ const _forTrack1 = ($index, $item) => $item.ID;
38
39
  function MJTestSuiteFormComponentExtended_Conditional_21_Template(rf, ctx) { if (rf & 1) {
39
40
  i0.ɵɵelementStart(0, "span", 16);
40
41
  i0.ɵɵtext(1, "\u25CF");
@@ -98,25 +99,35 @@ function MJTestSuiteFormComponentExtended_Conditional_60_For_33_Template(rf, ctx
98
99
  i0.ɵɵtext(1);
99
100
  i0.ɵɵelementEnd();
100
101
  } if (rf & 2) {
101
- const s_r4 = ctx.$implicit;
102
- i0.ɵɵproperty("ngValue", s_r4.ID);
102
+ const rubric_r4 = ctx.$implicit;
103
+ i0.ɵɵproperty("ngValue", rubric_r4.id);
103
104
  i0.ɵɵadvance();
104
- i0.ɵɵtextInterpolate(s_r4.Name);
105
+ i0.ɵɵtextInterpolate(rubric_r4.name);
105
106
  } }
106
- function MJTestSuiteFormComponentExtended_Conditional_60_For_39_Template(rf, ctx) { if (rf & 1) {
107
- const _r6 = i0.ɵɵgetCurrentView();
108
- i0.ɵɵelementStart(0, "span", 78);
107
+ function MJTestSuiteFormComponentExtended_Conditional_60_For_41_Template(rf, ctx) { if (rf & 1) {
108
+ i0.ɵɵelementStart(0, "option", 73);
109
+ i0.ɵɵtext(1);
110
+ i0.ɵɵelementEnd();
111
+ } if (rf & 2) {
112
+ const s_r5 = ctx.$implicit;
113
+ i0.ɵɵproperty("ngValue", s_r5.ID);
114
+ i0.ɵɵadvance();
115
+ i0.ɵɵtextInterpolate(s_r5.Name);
116
+ } }
117
+ function MJTestSuiteFormComponentExtended_Conditional_60_For_47_Template(rf, ctx) { if (rf & 1) {
118
+ const _r7 = i0.ɵɵgetCurrentView();
119
+ i0.ɵɵelementStart(0, "span", 80);
109
120
  i0.ɵɵtext(1);
110
- i0.ɵɵelementStart(2, "button", 90);
111
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_60_For_39_Template_button_click_2_listener($event) { const tag_r7 = i0.ɵɵrestoreView(_r6).$implicit; const ctx_r0 = i0.ɵɵnextContext(2); ctx_r0.removeTag(tag_r7); return i0.ɵɵresetView($event.stopPropagation()); });
112
- i0.ɵɵelement(3, "i", 91);
121
+ i0.ɵɵelementStart(2, "button", 92);
122
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_60_For_47_Template_button_click_2_listener($event) { const tag_r8 = i0.ɵɵrestoreView(_r7).$implicit; const ctx_r0 = i0.ɵɵnextContext(2); ctx_r0.removeTag(tag_r8); return i0.ɵɵresetView($event.stopPropagation()); });
123
+ i0.ɵɵelement(3, "i", 93);
113
124
  i0.ɵɵelementEnd()();
114
125
  } if (rf & 2) {
115
- const tag_r7 = ctx.$implicit;
126
+ const tag_r8 = ctx.$implicit;
116
127
  i0.ɵɵadvance();
117
- i0.ɵɵtextInterpolate1(" ", tag_r7, " ");
128
+ i0.ɵɵtextInterpolate1(" ", tag_r8, " ");
118
129
  i0.ɵɵadvance();
119
- i0.ɵɵattribute("aria-label", "Remove tag " + tag_r7);
130
+ i0.ɵɵattribute("aria-label", "Remove tag " + tag_r8);
120
131
  } }
121
132
  function MJTestSuiteFormComponentExtended_Conditional_60_Template(rf, ctx) { if (rf & 1) {
122
133
  const _r2 = i0.ɵɵgetCurrentView();
@@ -149,60 +160,70 @@ function MJTestSuiteFormComponentExtended_Conditional_60_Template(rf, ctx) { if
149
160
  i0.ɵɵrepeaterCreate(24, MJTestSuiteFormComponentExtended_Conditional_60_For_25_Template, 2, 2, "option", 73, i0.ɵɵrepeaterTrackByIdentity);
150
161
  i0.ɵɵelementEnd()()();
151
162
  i0.ɵɵelementStart(26, "div", 69)(27, "label", 74);
152
- i0.ɵɵtext(28, "Parent Suite");
163
+ i0.ɵɵtext(28, "Rubric");
153
164
  i0.ɵɵelementEnd();
154
165
  i0.ɵɵelementStart(29, "select", 75);
155
- i0.ɵɵlistener("ngModelChange", function MJTestSuiteFormComponentExtended_Conditional_60_Template_select_ngModelChange_29_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.record.ParentID = $event || null); });
166
+ i0.ɵɵlistener("ngModelChange", function MJTestSuiteFormComponentExtended_Conditional_60_Template_select_ngModelChange_29_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.record.RubricID = $event || null); });
156
167
  i0.ɵɵelementStart(30, "option", 73);
157
- i0.ɵɵtext(31, "\u2014 None (top-level) \u2014");
168
+ i0.ɵɵtext(31, "\u2014 None \u2014");
158
169
  i0.ɵɵelementEnd();
159
170
  i0.ɵɵrepeaterCreate(32, MJTestSuiteFormComponentExtended_Conditional_60_For_33_Template, 2, 2, "option", 73, _forTrack0);
160
171
  i0.ɵɵelementEnd()();
161
- i0.ɵɵelementStart(34, "div", 63)(35, "label", 76);
162
- i0.ɵɵtext(36, "Tags");
163
- i0.ɵɵelementEnd();
164
- i0.ɵɵelementStart(37, "div", 77);
165
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_60_Template_div_click_37_listener() { i0.ɵɵrestoreView(_r2); const tagInput_r5 = i0.ɵɵreference(41); return i0.ɵɵresetView(tagInput_r5.focus()); });
166
- i0.ɵɵrepeaterCreate(38, MJTestSuiteFormComponentExtended_Conditional_60_For_39_Template, 4, 2, "span", 78, i0.ɵɵrepeaterTrackByIdentity);
167
- i0.ɵɵelementStart(40, "input", 79, 0);
168
- i0.ɵɵtwoWayListener("ngModelChange", function MJTestSuiteFormComponentExtended_Conditional_60_Template_input_ngModelChange_40_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r0.tagDraft, $event) || (ctx_r0.tagDraft = $event); return i0.ɵɵresetView($event); });
169
- i0.ɵɵlistener("keydown", function MJTestSuiteFormComponentExtended_Conditional_60_Template_input_keydown_40_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onTagInputKeydown($event)); })("blur", function MJTestSuiteFormComponentExtended_Conditional_60_Template_input_blur_40_listener() { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.addTagFromDraft()); });
172
+ i0.ɵɵelementStart(34, "div", 69)(35, "label", 76);
173
+ i0.ɵɵtext(36, "Parent Suite");
174
+ i0.ɵɵelementEnd();
175
+ i0.ɵɵelementStart(37, "select", 77);
176
+ i0.ɵɵlistener("ngModelChange", function MJTestSuiteFormComponentExtended_Conditional_60_Template_select_ngModelChange_37_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.record.ParentID = $event || null); });
177
+ i0.ɵɵelementStart(38, "option", 73);
178
+ i0.ɵɵtext(39, "\u2014 None (top-level) \u2014");
179
+ i0.ɵɵelementEnd();
180
+ i0.ɵɵrepeaterCreate(40, MJTestSuiteFormComponentExtended_Conditional_60_For_41_Template, 2, 2, "option", 73, _forTrack1);
181
+ i0.ɵɵelementEnd()();
182
+ i0.ɵɵelementStart(42, "div", 63)(43, "label", 78);
183
+ i0.ɵɵtext(44, "Tags");
184
+ i0.ɵɵelementEnd();
185
+ i0.ɵɵelementStart(45, "div", 79);
186
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_60_Template_div_click_45_listener() { i0.ɵɵrestoreView(_r2); const tagInput_r6 = i0.ɵɵreference(49); return i0.ɵɵresetView(tagInput_r6.focus()); });
187
+ i0.ɵɵrepeaterCreate(46, MJTestSuiteFormComponentExtended_Conditional_60_For_47_Template, 4, 2, "span", 80, i0.ɵɵrepeaterTrackByIdentity);
188
+ i0.ɵɵelementStart(48, "input", 81, 0);
189
+ i0.ɵɵtwoWayListener("ngModelChange", function MJTestSuiteFormComponentExtended_Conditional_60_Template_input_ngModelChange_48_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r0.tagDraft, $event) || (ctx_r0.tagDraft = $event); return i0.ɵɵresetView($event); });
190
+ i0.ɵɵlistener("keydown", function MJTestSuiteFormComponentExtended_Conditional_60_Template_input_keydown_48_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onTagInputKeydown($event)); })("blur", function MJTestSuiteFormComponentExtended_Conditional_60_Template_input_blur_48_listener() { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.addTagFromDraft()); });
170
191
  i0.ɵɵelementEnd()();
171
- i0.ɵɵelementStart(42, "span", 80);
172
- i0.ɵɵtext(43, "Press Enter or comma to add a tag. Backspace on empty input removes the last tag.");
192
+ i0.ɵɵelementStart(50, "span", 82);
193
+ i0.ɵɵtext(51, "Press Enter or comma to add a tag. Backspace on empty input removes the last tag.");
173
194
  i0.ɵɵelementEnd()()()();
174
- i0.ɵɵelementStart(44, "section", 58)(45, "header", 59)(46, "h3");
175
- i0.ɵɵelement(47, "i", 81);
176
- i0.ɵɵtext(48, " Execution Settings");
195
+ i0.ɵɵelementStart(52, "section", 58)(53, "header", 59)(54, "h3");
196
+ i0.ɵɵelement(55, "i", 83);
197
+ i0.ɵɵtext(56, " Execution Settings");
177
198
  i0.ɵɵelementEnd()();
178
- i0.ɵɵelementStart(49, "div", 62)(50, "div", 69)(51, "label", 82);
179
- i0.ɵɵtext(52, "Max Execution Time (ms)");
199
+ i0.ɵɵelementStart(57, "div", 62)(58, "div", 69)(59, "label", 84);
200
+ i0.ɵɵtext(60, "Max Execution Time (ms)");
180
201
  i0.ɵɵelementEnd();
181
- i0.ɵɵelementStart(53, "input", 83);
182
- i0.ɵɵlistener("ngModelChange", function MJTestSuiteFormComponentExtended_Conditional_60_Template_input_ngModelChange_53_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.record.MaxExecutionTimeMS = $event === "" || $event === null ? null : +$event); });
202
+ i0.ɵɵelementStart(61, "input", 85);
203
+ i0.ɵɵlistener("ngModelChange", function MJTestSuiteFormComponentExtended_Conditional_60_Template_input_ngModelChange_61_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.record.MaxExecutionTimeMS = $event === "" || $event === null ? null : +$event); });
183
204
  i0.ɵɵelementEnd();
184
- i0.ɵɵelementStart(54, "span", 80);
185
- i0.ɵɵtext(55);
205
+ i0.ɵɵelementStart(62, "span", 82);
206
+ i0.ɵɵtext(63);
186
207
  i0.ɵɵelementEnd()()()();
187
- i0.ɵɵelementStart(56, "section", 84)(57, "div", 85)(58, "div", 86)(59, "div", 87);
188
- i0.ɵɵtext(60, "Created");
208
+ i0.ɵɵelementStart(64, "section", 86)(65, "div", 87)(66, "div", 88)(67, "div", 89);
209
+ i0.ɵɵtext(68, "Created");
189
210
  i0.ɵɵelementEnd();
190
- i0.ɵɵelementStart(61, "div", 88);
191
- i0.ɵɵtext(62);
192
- i0.ɵɵpipe(63, "date");
211
+ i0.ɵɵelementStart(69, "div", 90);
212
+ i0.ɵɵtext(70);
213
+ i0.ɵɵpipe(71, "date");
193
214
  i0.ɵɵelementEnd()();
194
- i0.ɵɵelementStart(64, "div", 86)(65, "div", 87);
195
- i0.ɵɵtext(66, "Last updated");
215
+ i0.ɵɵelementStart(72, "div", 88)(73, "div", 89);
216
+ i0.ɵɵtext(74, "Last updated");
196
217
  i0.ɵɵelementEnd();
197
- i0.ɵɵelementStart(67, "div", 88);
198
- i0.ɵɵtext(68);
199
- i0.ɵɵpipe(69, "date");
218
+ i0.ɵɵelementStart(75, "div", 90);
219
+ i0.ɵɵtext(76);
220
+ i0.ɵɵpipe(77, "date");
200
221
  i0.ɵɵelementEnd()();
201
- i0.ɵɵelementStart(70, "div", 86)(71, "div", 87);
202
- i0.ɵɵtext(72, "Suite ID");
222
+ i0.ɵɵelementStart(78, "div", 88)(79, "div", 89);
223
+ i0.ɵɵtext(80, "Suite ID");
203
224
  i0.ɵɵelementEnd();
204
- i0.ɵɵelementStart(73, "div", 89);
205
- i0.ɵɵtext(74);
225
+ i0.ɵɵelementStart(81, "div", 91);
226
+ i0.ɵɵtext(82);
206
227
  i0.ɵɵelementEnd()()()()();
207
228
  } if (rf & 2) {
208
229
  const ctx_r0 = i0.ɵɵnextContext();
@@ -215,6 +236,12 @@ function MJTestSuiteFormComponentExtended_Conditional_60_Template(rf, ctx) { if
215
236
  i0.ɵɵadvance();
216
237
  i0.ɵɵrepeater(ctx_r0.statusOptions);
217
238
  i0.ɵɵadvance(5);
239
+ i0.ɵɵproperty("ngModel", ctx_r0.record.RubricID);
240
+ i0.ɵɵadvance();
241
+ i0.ɵɵproperty("ngValue", null);
242
+ i0.ɵɵadvance(2);
243
+ i0.ɵɵrepeater(ctx_r0.RubricOptions);
244
+ i0.ɵɵadvance(5);
218
245
  i0.ɵɵproperty("ngModel", ctx_r0.record.ParentID);
219
246
  i0.ɵɵadvance();
220
247
  i0.ɵɵproperty("ngValue", null);
@@ -230,14 +257,14 @@ function MJTestSuiteFormComponentExtended_Conditional_60_Template(rf, ctx) { if
230
257
  i0.ɵɵadvance(2);
231
258
  i0.ɵɵtextInterpolate1("Default timeout for tests in this suite. Currently: ", ctx_r0.formatTimeout(ctx_r0.record.MaxExecutionTimeMS));
232
259
  i0.ɵɵadvance(7);
233
- i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(63, 12, ctx_r0.record.__mj_CreatedAt, "medium"));
260
+ i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(71, 14, ctx_r0.record.__mj_CreatedAt, "medium"));
234
261
  i0.ɵɵadvance(6);
235
- i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(69, 15, ctx_r0.record.__mj_UpdatedAt, "medium"));
262
+ i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(77, 17, ctx_r0.record.__mj_UpdatedAt, "medium"));
236
263
  i0.ɵɵadvance(6);
237
264
  i0.ɵɵtextInterpolate(ctx_r0.record.ID);
238
265
  } }
239
266
  function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_5_Template(rf, ctx) { if (rf & 1) {
240
- i0.ɵɵelementStart(0, "span", 94);
267
+ i0.ɵɵelementStart(0, "span", 96);
241
268
  i0.ɵɵtext(1);
242
269
  i0.ɵɵelementEnd();
243
270
  } if (rf & 2) {
@@ -246,15 +273,15 @@ function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_5_Template(
246
273
  i0.ɵɵtextInterpolate(ctx_r0.suiteTests.length);
247
274
  } }
248
275
  function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_12_For_3_Template(rf, ctx) { if (rf & 1) {
249
- i0.ɵɵelementStart(0, "div", 103);
250
- i0.ɵɵelement(1, "div", 104)(2, "div", 105);
251
- i0.ɵɵelementStart(3, "div", 106);
252
- i0.ɵɵelement(4, "div", 107)(5, "div", 108);
276
+ i0.ɵɵelementStart(0, "div", 105);
277
+ i0.ɵɵelement(1, "div", 106)(2, "div", 107);
278
+ i0.ɵɵelementStart(3, "div", 108);
279
+ i0.ɵɵelement(4, "div", 109)(5, "div", 110);
253
280
  i0.ɵɵelementEnd()();
254
281
  } }
255
282
  function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_12_Template(rf, ctx) { if (rf & 1) {
256
- i0.ɵɵelementStart(0, "div", 99)(1, "div", 102);
257
- i0.ɵɵrepeaterCreate(2, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_12_For_3_Template, 6, 0, "div", 103, i0.ɵɵrepeaterTrackByIdentity);
283
+ i0.ɵɵelementStart(0, "div", 101)(1, "div", 104);
284
+ i0.ɵɵrepeaterCreate(2, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_12_For_3_Template, 6, 0, "div", 105, i0.ɵɵrepeaterTrackByIdentity);
258
285
  i0.ɵɵelementEnd()();
259
286
  } if (rf & 2) {
260
287
  i0.ɵɵadvance(2);
@@ -262,33 +289,33 @@ function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_12_Template
262
289
  } }
263
290
  function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Conditional_11_Template(rf, ctx) { if (rf & 1) {
264
291
  i0.ɵɵelementStart(0, "span");
265
- i0.ɵɵelement(1, "i", 119);
292
+ i0.ɵɵelement(1, "i", 121);
266
293
  i0.ɵɵtext(2);
267
294
  i0.ɵɵelementEnd();
268
295
  } if (rf & 2) {
269
- const test_r11 = i0.ɵɵnextContext().$implicit;
296
+ const test_r12 = i0.ɵɵnextContext().$implicit;
270
297
  i0.ɵɵadvance(2);
271
- i0.ɵɵtextInterpolate1(" ", test_r11.Status);
298
+ i0.ɵɵtextInterpolate1(" ", test_r12.Status);
272
299
  } }
273
300
  function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Conditional_12_Conditional_4_Template(rf, ctx) { if (rf & 1) {
274
- i0.ɵɵelement(0, "i", 123);
301
+ i0.ɵɵelement(0, "i", 125);
275
302
  } }
276
303
  function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Conditional_12_Conditional_5_Template(rf, ctx) { if (rf & 1) {
277
304
  i0.ɵɵtext(0, " Remove ");
278
305
  } }
279
306
  function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Conditional_12_Template(rf, ctx) { if (rf & 1) {
280
- const _r12 = i0.ɵɵgetCurrentView();
281
- i0.ɵɵelementStart(0, "div", 120);
307
+ const _r13 = i0.ɵɵgetCurrentView();
308
+ i0.ɵɵelementStart(0, "div", 122);
282
309
  i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Conditional_12_Template_div_click_0_listener($event) { return $event.stopPropagation(); });
283
- i0.ɵɵelementStart(1, "span", 121);
310
+ i0.ɵɵelementStart(1, "span", 123);
284
311
  i0.ɵɵtext(2, "Remove from suite?");
285
312
  i0.ɵɵelementEnd();
286
- i0.ɵɵelementStart(3, "button", 122);
287
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Conditional_12_Template_button_click_3_listener($event) { i0.ɵɵrestoreView(_r12); const test_r11 = i0.ɵɵnextContext().$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.confirmRemoveTest(test_r11, $event)); });
288
- i0.ɵɵconditionalCreate(4, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Conditional_12_Conditional_4_Template, 1, 0, "i", 123)(5, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Conditional_12_Conditional_5_Template, 1, 0);
313
+ i0.ɵɵelementStart(3, "button", 124);
314
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Conditional_12_Template_button_click_3_listener($event) { i0.ɵɵrestoreView(_r13); const test_r12 = i0.ɵɵnextContext().$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.confirmRemoveTest(test_r12, $event)); });
315
+ i0.ɵɵconditionalCreate(4, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Conditional_12_Conditional_4_Template, 1, 0, "i", 125)(5, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Conditional_12_Conditional_5_Template, 1, 0);
289
316
  i0.ɵɵelementEnd();
290
- i0.ɵɵelementStart(6, "button", 124);
291
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Conditional_12_Template_button_click_6_listener($event) { i0.ɵɵrestoreView(_r12); const ctx_r0 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r0.cancelRemoveTest($event)); });
317
+ i0.ɵɵelementStart(6, "button", 126);
318
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Conditional_12_Template_button_click_6_listener($event) { i0.ɵɵrestoreView(_r13); const ctx_r0 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r0.cancelRemoveTest($event)); });
292
319
  i0.ɵɵtext(7, " Cancel ");
293
320
  i0.ɵɵelementEnd()();
294
321
  } if (rf & 2) {
@@ -301,54 +328,54 @@ function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Co
301
328
  i0.ɵɵproperty("disabled", ctx_r0.isRemovingTest);
302
329
  } }
303
330
  function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Conditional_13_Template(rf, ctx) { if (rf & 1) {
304
- const _r13 = i0.ɵɵgetCurrentView();
305
- i0.ɵɵelementStart(0, "button", 125);
306
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Conditional_13_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(_r13); const test_r11 = i0.ɵɵnextContext().$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.requestRemoveTest(test_r11, $event)); });
307
- i0.ɵɵelement(1, "i", 91);
331
+ const _r14 = i0.ɵɵgetCurrentView();
332
+ i0.ɵɵelementStart(0, "button", 127);
333
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Conditional_13_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(_r14); const test_r12 = i0.ɵɵnextContext().$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.requestRemoveTest(test_r12, $event)); });
334
+ i0.ɵɵelement(1, "i", 93);
308
335
  i0.ɵɵelementEnd();
309
- i0.ɵɵelementStart(2, "i", 126);
310
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Conditional_13_Template_i_click_2_listener() { i0.ɵɵrestoreView(_r13); const test_r11 = i0.ɵɵnextContext().$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.openTest(test_r11.TestID)); });
336
+ i0.ɵɵelementStart(2, "i", 128);
337
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Conditional_13_Template_i_click_2_listener() { i0.ɵɵrestoreView(_r14); const test_r12 = i0.ɵɵnextContext().$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.openTest(test_r12.TestID)); });
311
338
  i0.ɵɵelementEnd();
312
339
  } }
313
340
  function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Template(rf, ctx) { if (rf & 1) {
314
- const _r10 = i0.ɵɵgetCurrentView();
315
- i0.ɵɵelementStart(0, "div", 110)(1, "span", 111);
316
- i0.ɵɵelement(2, "i", 112);
341
+ const _r11 = i0.ɵɵgetCurrentView();
342
+ i0.ɵɵelementStart(0, "div", 112)(1, "span", 113);
343
+ i0.ɵɵelement(2, "i", 114);
317
344
  i0.ɵɵelementEnd();
318
- i0.ɵɵelementStart(3, "div", 113);
345
+ i0.ɵɵelementStart(3, "div", 115);
319
346
  i0.ɵɵtext(4);
320
347
  i0.ɵɵelementEnd();
321
- i0.ɵɵelementStart(5, "div", 114);
348
+ i0.ɵɵelementStart(5, "div", 116);
322
349
  i0.ɵɵelement(6, "i", 33);
323
350
  i0.ɵɵelementEnd();
324
- i0.ɵɵelementStart(7, "div", 115);
325
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Template_div_click_7_listener() { const test_r11 = i0.ɵɵrestoreView(_r10).$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.openTest(test_r11.TestID)); });
326
- i0.ɵɵelementStart(8, "div", 116);
351
+ i0.ɵɵelementStart(7, "div", 117);
352
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Template_div_click_7_listener() { const test_r12 = i0.ɵɵrestoreView(_r11).$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.openTest(test_r12.TestID)); });
353
+ i0.ɵɵelementStart(8, "div", 118);
327
354
  i0.ɵɵtext(9);
328
355
  i0.ɵɵelementEnd();
329
- i0.ɵɵelementStart(10, "div", 117);
356
+ i0.ɵɵelementStart(10, "div", 119);
330
357
  i0.ɵɵconditionalCreate(11, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Conditional_11_Template, 3, 1, "span");
331
358
  i0.ɵɵelementEnd()();
332
- i0.ɵɵconditionalCreate(12, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Conditional_12_Template, 8, 3, "div", 118)(13, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Conditional_13_Template, 3, 0);
359
+ i0.ɵɵconditionalCreate(12, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Conditional_12_Template, 8, 3, "div", 120)(13, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Conditional_13_Template, 3, 0);
333
360
  i0.ɵɵelementEnd();
334
361
  } if (rf & 2) {
335
- const test_r11 = ctx.$implicit;
362
+ const test_r12 = ctx.$implicit;
336
363
  const ctx_r0 = i0.ɵɵnextContext(3);
337
364
  i0.ɵɵproperty("cdkDragDisabled", ctx_r0.isReorderingTests || ctx_r0.isRemovingTest);
338
365
  i0.ɵɵadvance(4);
339
- i0.ɵɵtextInterpolate(test_r11.Sequence);
366
+ i0.ɵɵtextInterpolate(test_r12.Sequence);
340
367
  i0.ɵɵadvance(5);
341
- i0.ɵɵtextInterpolate(test_r11.Test);
368
+ i0.ɵɵtextInterpolate(test_r12.Test);
342
369
  i0.ɵɵadvance(2);
343
- i0.ɵɵconditional(test_r11.Status ? 11 : -1);
370
+ i0.ɵɵconditional(test_r12.Status ? 11 : -1);
344
371
  i0.ɵɵadvance();
345
- i0.ɵɵconditional(ctx_r0.confirmingRemoveSuiteTestId === test_r11.ID ? 12 : 13);
372
+ i0.ɵɵconditional(ctx_r0.confirmingRemoveSuiteTestId === test_r12.ID ? 12 : 13);
346
373
  } }
347
374
  function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_Template(rf, ctx) { if (rf & 1) {
348
- const _r9 = i0.ɵɵgetCurrentView();
349
- i0.ɵɵelementStart(0, "div", 109);
350
- i0.ɵɵlistener("cdkDropListDropped", function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_Template_div_cdkDropListDropped_0_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.onTestDrop($event)); });
351
- i0.ɵɵrepeaterCreate(1, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Template, 14, 5, "div", 110, _forTrack0);
375
+ const _r10 = i0.ɵɵgetCurrentView();
376
+ i0.ɵɵelementStart(0, "div", 111);
377
+ i0.ɵɵlistener("cdkDropListDropped", function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_Template_div_cdkDropListDropped_0_listener($event) { i0.ɵɵrestoreView(_r10); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.onTestDrop($event)); });
378
+ i0.ɵɵrepeaterCreate(1, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Template, 14, 5, "div", 112, _forTrack1);
352
379
  i0.ɵɵelementEnd();
353
380
  } if (rf & 2) {
354
381
  const ctx_r0 = i0.ɵɵnextContext(2);
@@ -356,28 +383,28 @@ function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_Template
356
383
  i0.ɵɵrepeater(ctx_r0.suiteTests);
357
384
  } }
358
385
  function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_14_Template(rf, ctx) { if (rf & 1) {
359
- const _r14 = i0.ɵɵgetCurrentView();
360
- i0.ɵɵelementStart(0, "mj-empty-state", 127);
361
- i0.ɵɵlistener("Action", function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_14_Template_mj_empty_state_Action_0_listener() { i0.ɵɵrestoreView(_r14); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.openAddTestsDialog()); });
386
+ const _r15 = i0.ɵɵgetCurrentView();
387
+ i0.ɵɵelementStart(0, "mj-empty-state", 129);
388
+ i0.ɵɵlistener("Action", function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_14_Template_mj_empty_state_Action_0_listener() { i0.ɵɵrestoreView(_r15); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.openAddTestsDialog()); });
362
389
  i0.ɵɵelementEnd();
363
390
  } }
364
391
  function MJTestSuiteFormComponentExtended_Conditional_61_Template(rf, ctx) { if (rf & 1) {
365
- const _r8 = i0.ɵɵgetCurrentView();
366
- i0.ɵɵelementStart(0, "div", 40)(1, "div", 92)(2, "div", 93)(3, "strong");
392
+ const _r9 = i0.ɵɵgetCurrentView();
393
+ i0.ɵɵelementStart(0, "div", 40)(1, "div", 94)(2, "div", 95)(3, "strong");
367
394
  i0.ɵɵtext(4, "Suite tests");
368
395
  i0.ɵɵelementEnd();
369
- i0.ɵɵconditionalCreate(5, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_5_Template, 2, 1, "span", 94);
370
- i0.ɵɵelementStart(6, "span", 95);
396
+ i0.ɵɵconditionalCreate(5, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_5_Template, 2, 1, "span", 96);
397
+ i0.ɵɵelementStart(6, "span", 97);
371
398
  i0.ɵɵtext(7, "Drag to reorder \u00B7 Hover a row to remove");
372
399
  i0.ɵɵelementEnd()();
373
- i0.ɵɵelementStart(8, "div", 96)(9, "button", 97);
374
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_61_Template_button_click_9_listener() { i0.ɵɵrestoreView(_r8); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.openAddTestsDialog()); });
375
- i0.ɵɵelement(10, "i", 98);
400
+ i0.ɵɵelementStart(8, "div", 98)(9, "button", 99);
401
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_61_Template_button_click_9_listener() { i0.ɵɵrestoreView(_r9); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.openAddTestsDialog()); });
402
+ i0.ɵɵelement(10, "i", 100);
376
403
  i0.ɵɵtext(11, " Add tests ");
377
404
  i0.ɵɵelementEnd()()();
378
- i0.ɵɵconditionalCreate(12, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_12_Template, 4, 1, "div", 99);
379
- i0.ɵɵconditionalCreate(13, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_Template, 3, 0, "div", 100);
380
- i0.ɵɵconditionalCreate(14, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_14_Template, 1, 0, "mj-empty-state", 101);
405
+ i0.ɵɵconditionalCreate(12, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_12_Template, 4, 1, "div", 101);
406
+ i0.ɵɵconditionalCreate(13, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_Template, 3, 0, "div", 102);
407
+ i0.ɵɵconditionalCreate(14, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_14_Template, 1, 0, "mj-empty-state", 103);
381
408
  i0.ɵɵelementEnd();
382
409
  } if (rf & 2) {
383
410
  const ctx_r0 = i0.ɵɵnextContext();
@@ -393,15 +420,15 @@ function MJTestSuiteFormComponentExtended_Conditional_61_Template(rf, ctx) { if
393
420
  i0.ɵɵconditional(ctx_r0.testsLoaded && !ctx_r0.loadingTests && ctx_r0.suiteTests.length === 0 ? 14 : -1);
394
421
  } }
395
422
  function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_1_For_3_Template(rf, ctx) { if (rf & 1) {
396
- i0.ɵɵelementStart(0, "div", 103);
397
- i0.ɵɵelement(1, "div", 105);
398
- i0.ɵɵelementStart(2, "div", 106);
399
- i0.ɵɵelement(3, "div", 107)(4, "div", 108);
423
+ i0.ɵɵelementStart(0, "div", 105);
424
+ i0.ɵɵelement(1, "div", 107);
425
+ i0.ɵɵelementStart(2, "div", 108);
426
+ i0.ɵɵelement(3, "div", 109)(4, "div", 110);
400
427
  i0.ɵɵelementEnd()();
401
428
  } }
402
429
  function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_1_Template(rf, ctx) { if (rf & 1) {
403
- i0.ɵɵelementStart(0, "div", 99)(1, "div", 102);
404
- i0.ɵɵrepeaterCreate(2, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_1_For_3_Template, 5, 0, "div", 103, i0.ɵɵrepeaterTrackByIdentity);
430
+ i0.ɵɵelementStart(0, "div", 101)(1, "div", 104);
431
+ i0.ɵɵrepeaterCreate(2, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_1_For_3_Template, 5, 0, "div", 105, i0.ɵɵrepeaterTrackByIdentity);
405
432
  i0.ɵɵelementEnd()();
406
433
  } if (rf & 2) {
407
434
  i0.ɵɵadvance(2);
@@ -409,121 +436,121 @@ function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_1_Template(
409
436
  } }
410
437
  function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_2_For_2_Conditional_13_Template(rf, ctx) { if (rf & 1) {
411
438
  i0.ɵɵelementStart(0, "span");
412
- i0.ɵɵelement(1, "i", 146);
439
+ i0.ɵɵelement(1, "i", 148);
413
440
  i0.ɵɵtext(2);
414
441
  i0.ɵɵelementEnd();
415
442
  } if (rf & 2) {
416
- const run_r16 = i0.ɵɵnextContext().$implicit;
443
+ const run_r17 = i0.ɵɵnextContext().$implicit;
417
444
  const ctx_r0 = i0.ɵɵnextContext(3);
418
445
  i0.ɵɵadvance(2);
419
- i0.ɵɵtextInterpolate3(" ", run_r16.PassedTests, "/", run_r16.TotalTests, " (", ctx_r0.getPassRate(run_r16).toFixed(0), "%) ");
446
+ i0.ɵɵtextInterpolate3(" ", run_r17.PassedTests, "/", run_r17.TotalTests, " (", ctx_r0.getPassRate(run_r17).toFixed(0), "%) ");
420
447
  } }
421
448
  function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_2_For_2_Conditional_15_Template(rf, ctx) { if (rf & 1) {
422
- i0.ɵɵelementStart(0, "span", 147);
423
- i0.ɵɵelement(1, "i", 133);
449
+ i0.ɵɵelementStart(0, "span", 149);
450
+ i0.ɵɵelement(1, "i", 135);
424
451
  i0.ɵɵelementEnd();
425
452
  } if (rf & 2) {
426
- const run_r16 = i0.ɵɵnextContext().$implicit;
427
- i0.ɵɵclassMap("status-" + run_r16.Status.toLowerCase());
453
+ const run_r17 = i0.ɵɵnextContext().$implicit;
454
+ i0.ɵɵclassMap("status-" + run_r17.Status.toLowerCase());
428
455
  i0.ɵɵadvance();
429
- i0.ɵɵclassProp("fa-circle-check", run_r16.Status === "Completed")("fa-circle-xmark", run_r16.Status === "Failed")("fa-spinner", run_r16.Status === "Running")("fa-clock", run_r16.Status === "Pending")("fa-ban", run_r16.Status === "Cancelled");
456
+ i0.ɵɵclassProp("fa-circle-check", run_r17.Status === "Completed")("fa-circle-xmark", run_r17.Status === "Failed")("fa-spinner", run_r17.Status === "Running")("fa-clock", run_r17.Status === "Pending")("fa-ban", run_r17.Status === "Cancelled");
430
457
  } }
431
458
  function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_2_For_2_Conditional_16_Template(rf, ctx) { if (rf & 1) {
432
- i0.ɵɵelementStart(0, "span", 142);
433
- i0.ɵɵelement(1, "i", 148);
434
- i0.ɵɵelementStart(2, "span", 149);
435
- i0.ɵɵelement(3, "i", 150);
459
+ i0.ɵɵelementStart(0, "span", 144);
460
+ i0.ɵɵelement(1, "i", 150);
461
+ i0.ɵɵelementStart(2, "span", 151);
462
+ i0.ɵɵelement(3, "i", 152);
436
463
  i0.ɵɵelementEnd()();
437
464
  } }
438
465
  function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_2_For_2_Conditional_17_Template(rf, ctx) { if (rf & 1) {
439
- i0.ɵɵelementStart(0, "span", 151);
440
- i0.ɵɵelement(1, "i", 152);
466
+ i0.ɵɵelementStart(0, "span", 153);
467
+ i0.ɵɵelement(1, "i", 154);
441
468
  i0.ɵɵelementStart(2, "span");
442
469
  i0.ɵɵtext(3);
443
470
  i0.ɵɵelementEnd()();
444
471
  } if (rf & 2) {
445
- const run_r16 = i0.ɵɵnextContext().$implicit;
472
+ const run_r17 = i0.ɵɵnextContext().$implicit;
446
473
  const ctx_r0 = i0.ɵɵnextContext(3);
447
- i0.ɵɵclassProp("high", ctx_r0.getPassRate(run_r16) >= 80)("medium", ctx_r0.getPassRate(run_r16) >= 50 && ctx_r0.getPassRate(run_r16) < 80)("low", ctx_r0.getPassRate(run_r16) < 50);
474
+ i0.ɵɵclassProp("high", ctx_r0.getPassRate(run_r17) >= 80)("medium", ctx_r0.getPassRate(run_r17) >= 50 && ctx_r0.getPassRate(run_r17) < 80)("low", ctx_r0.getPassRate(run_r17) < 50);
448
475
  i0.ɵɵadvance(3);
449
- i0.ɵɵtextInterpolate1("", ctx_r0.getPassRate(run_r16).toFixed(0), "%");
476
+ i0.ɵɵtextInterpolate1("", ctx_r0.getPassRate(run_r17).toFixed(0), "%");
450
477
  } }
451
478
  function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_2_For_2_Conditional_18_For_2_Template(rf, ctx) { if (rf & 1) {
452
- i0.ɵɵelementStart(0, "span", 153);
479
+ i0.ɵɵelementStart(0, "span", 155);
453
480
  i0.ɵɵtext(1);
454
481
  i0.ɵɵelementEnd();
455
482
  } if (rf & 2) {
456
- const tag_r17 = ctx.$implicit;
483
+ const tag_r18 = ctx.$implicit;
457
484
  i0.ɵɵadvance();
458
- i0.ɵɵtextInterpolate(tag_r17);
485
+ i0.ɵɵtextInterpolate(tag_r18);
459
486
  } }
460
487
  function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_2_For_2_Conditional_18_Template(rf, ctx) { if (rf & 1) {
461
- i0.ɵɵelementStart(0, "div", 144);
462
- i0.ɵɵrepeaterCreate(1, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_2_For_2_Conditional_18_For_2_Template, 2, 1, "span", 153, i0.ɵɵrepeaterTrackByIdentity);
488
+ i0.ɵɵelementStart(0, "div", 146);
489
+ i0.ɵɵrepeaterCreate(1, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_2_For_2_Conditional_18_For_2_Template, 2, 1, "span", 155, i0.ɵɵrepeaterTrackByIdentity);
463
490
  i0.ɵɵelementEnd();
464
491
  } if (rf & 2) {
465
- const run_r16 = i0.ɵɵnextContext().$implicit;
492
+ const run_r17 = i0.ɵɵnextContext().$implicit;
466
493
  const ctx_r0 = i0.ɵɵnextContext(3);
467
494
  i0.ɵɵadvance();
468
- i0.ɵɵrepeater(ctx_r0.getRunTags(run_r16));
495
+ i0.ɵɵrepeater(ctx_r0.getRunTags(run_r17));
469
496
  } }
470
497
  function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_2_For_2_Template(rf, ctx) { if (rf & 1) {
471
- const _r15 = i0.ɵɵgetCurrentView();
472
- i0.ɵɵelementStart(0, "div", 131);
473
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_2_For_2_Template_div_click_0_listener() { const run_r16 = i0.ɵɵrestoreView(_r15).$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.openSuiteRun(run_r16.ID)); });
474
- i0.ɵɵelementStart(1, "div", 132);
475
- i0.ɵɵelement(2, "i", 133);
498
+ const _r16 = i0.ɵɵgetCurrentView();
499
+ i0.ɵɵelementStart(0, "div", 133);
500
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_2_For_2_Template_div_click_0_listener() { const run_r17 = i0.ɵɵrestoreView(_r16).$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.openSuiteRun(run_r17.ID)); });
501
+ i0.ɵɵelementStart(1, "div", 134);
502
+ i0.ɵɵelement(2, "i", 135);
476
503
  i0.ɵɵelementEnd();
477
- i0.ɵɵelementStart(3, "div", 134)(4, "div", 135)(5, "span", 136);
504
+ i0.ɵɵelementStart(3, "div", 136)(4, "div", 137)(5, "span", 138);
478
505
  i0.ɵɵtext(6);
479
506
  i0.ɵɵelementEnd();
480
- i0.ɵɵelementStart(7, "span", 137);
507
+ i0.ɵɵelementStart(7, "span", 139);
481
508
  i0.ɵɵtext(8);
482
509
  i0.ɵɵelementEnd()();
483
- i0.ɵɵelementStart(9, "div", 138)(10, "span");
484
- i0.ɵɵelement(11, "i", 139);
510
+ i0.ɵɵelementStart(9, "div", 140)(10, "span");
511
+ i0.ɵɵelement(11, "i", 141);
485
512
  i0.ɵɵtext(12);
486
513
  i0.ɵɵelementEnd();
487
514
  i0.ɵɵconditionalCreate(13, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_2_For_2_Conditional_13_Template, 3, 3, "span");
488
515
  i0.ɵɵelementEnd();
489
- i0.ɵɵelementStart(14, "div", 140);
490
- i0.ɵɵconditionalCreate(15, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_2_For_2_Conditional_15_Template, 2, 12, "span", 141);
491
- i0.ɵɵconditionalCreate(16, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_2_For_2_Conditional_16_Template, 4, 0, "span", 142);
492
- i0.ɵɵconditionalCreate(17, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_2_For_2_Conditional_17_Template, 4, 7, "span", 143);
516
+ i0.ɵɵelementStart(14, "div", 142);
517
+ i0.ɵɵconditionalCreate(15, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_2_For_2_Conditional_15_Template, 2, 12, "span", 143);
518
+ i0.ɵɵconditionalCreate(16, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_2_For_2_Conditional_16_Template, 4, 0, "span", 144);
519
+ i0.ɵɵconditionalCreate(17, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_2_For_2_Conditional_17_Template, 4, 7, "span", 145);
493
520
  i0.ɵɵelementEnd();
494
- i0.ɵɵconditionalCreate(18, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_2_For_2_Conditional_18_Template, 3, 0, "div", 144);
521
+ i0.ɵɵconditionalCreate(18, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_2_For_2_Conditional_18_Template, 3, 0, "div", 146);
495
522
  i0.ɵɵelementEnd();
496
- i0.ɵɵelement(19, "i", 145);
523
+ i0.ɵɵelement(19, "i", 147);
497
524
  i0.ɵɵelementEnd();
498
525
  } if (rf & 2) {
499
- const run_r16 = ctx.$implicit;
526
+ const run_r17 = ctx.$implicit;
500
527
  const ctx_r0 = i0.ɵɵnextContext(3);
501
528
  i0.ɵɵadvance();
502
- i0.ɵɵstyleProp("background-color", ctx_r0.getRunStatusColor(run_r16.Status));
529
+ i0.ɵɵstyleProp("background-color", ctx_r0.getRunStatusColor(run_r17.Status));
503
530
  i0.ɵɵadvance();
504
- i0.ɵɵclassProp("fa-check", run_r16.Status === "Completed")("fa-times", run_r16.Status === "Failed")("fa-spinner", run_r16.Status === "Running")("fa-clock", run_r16.Status === "Pending")("fa-ban", run_r16.Status === "Cancelled");
531
+ i0.ɵɵclassProp("fa-check", run_r17.Status === "Completed")("fa-times", run_r17.Status === "Failed")("fa-spinner", run_r17.Status === "Running")("fa-clock", run_r17.Status === "Pending")("fa-ban", run_r17.Status === "Cancelled");
505
532
  i0.ɵɵadvance(4);
506
- i0.ɵɵtextInterpolate1("Run #", run_r16.ID.substring(0, 8));
533
+ i0.ɵɵtextInterpolate1("Run #", run_r17.ID.substring(0, 8));
507
534
  i0.ɵɵadvance();
508
- i0.ɵɵstyleProp("color", ctx_r0.getRunStatusColor(run_r16.Status));
535
+ i0.ɵɵstyleProp("color", ctx_r0.getRunStatusColor(run_r17.Status));
509
536
  i0.ɵɵadvance();
510
- i0.ɵɵtextInterpolate(run_r16.Status);
537
+ i0.ɵɵtextInterpolate(run_r17.Status);
511
538
  i0.ɵɵadvance(4);
512
- i0.ɵɵtextInterpolate1(" ", ctx_r0.getRelativeTime(run_r16.StartedAt));
539
+ i0.ɵɵtextInterpolate1(" ", ctx_r0.getRelativeTime(run_r17.StartedAt));
513
540
  i0.ɵɵadvance();
514
- i0.ɵɵconditional(run_r16.TotalTests ? 13 : -1);
541
+ i0.ɵɵconditional(run_r17.TotalTests ? 13 : -1);
515
542
  i0.ɵɵadvance(2);
516
543
  i0.ɵɵconditional(ctx_r0.evalPreferences.showExecution ? 15 : -1);
517
544
  i0.ɵɵadvance();
518
545
  i0.ɵɵconditional(ctx_r0.evalPreferences.showHuman ? 16 : -1);
519
546
  i0.ɵɵadvance();
520
- i0.ɵɵconditional(ctx_r0.evalPreferences.showAuto && run_r16.TotalTests ? 17 : -1);
547
+ i0.ɵɵconditional(ctx_r0.evalPreferences.showAuto && run_r17.TotalTests ? 17 : -1);
521
548
  i0.ɵɵadvance();
522
- i0.ɵɵconditional(ctx_r0.getRunTags(run_r16).length > 0 ? 18 : -1);
549
+ i0.ɵɵconditional(ctx_r0.getRunTags(run_r17).length > 0 ? 18 : -1);
523
550
  } }
524
551
  function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_2_Template(rf, ctx) { if (rf & 1) {
525
- i0.ɵɵelementStart(0, "div", 128);
526
- i0.ɵɵrepeaterCreate(1, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_2_For_2_Template, 20, 22, "div", 130, i0.ɵɵrepeaterTrackByIdentity);
552
+ i0.ɵɵelementStart(0, "div", 130);
553
+ i0.ɵɵrepeaterCreate(1, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_2_For_2_Template, 20, 22, "div", 132, i0.ɵɵrepeaterTrackByIdentity);
527
554
  i0.ɵɵelementEnd();
528
555
  } if (rf & 2) {
529
556
  const ctx_r0 = i0.ɵɵnextContext(2);
@@ -531,16 +558,16 @@ function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_2_Template(
531
558
  i0.ɵɵrepeater(ctx_r0.suiteRuns);
532
559
  } }
533
560
  function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_3_Template(rf, ctx) { if (rf & 1) {
534
- const _r18 = i0.ɵɵgetCurrentView();
535
- i0.ɵɵelementStart(0, "mj-empty-state", 154);
536
- i0.ɵɵlistener("Action", function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_3_Template_mj_empty_state_Action_0_listener() { i0.ɵɵrestoreView(_r18); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.runSuite()); });
561
+ const _r19 = i0.ɵɵgetCurrentView();
562
+ i0.ɵɵelementStart(0, "mj-empty-state", 156);
563
+ i0.ɵɵlistener("Action", function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_3_Template_mj_empty_state_Action_0_listener() { i0.ɵɵrestoreView(_r19); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.runSuite()); });
537
564
  i0.ɵɵelementEnd();
538
565
  } }
539
566
  function MJTestSuiteFormComponentExtended_Conditional_62_Template(rf, ctx) { if (rf & 1) {
540
567
  i0.ɵɵelementStart(0, "div", 41);
541
- i0.ɵɵconditionalCreate(1, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_1_Template, 4, 1, "div", 99);
542
- i0.ɵɵconditionalCreate(2, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_2_Template, 3, 0, "div", 128);
543
- i0.ɵɵconditionalCreate(3, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_3_Template, 1, 0, "mj-empty-state", 129);
568
+ i0.ɵɵconditionalCreate(1, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_1_Template, 4, 1, "div", 101);
569
+ i0.ɵɵconditionalCreate(2, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_2_Template, 3, 0, "div", 130);
570
+ i0.ɵɵconditionalCreate(3, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_3_Template, 1, 0, "mj-empty-state", 131);
544
571
  i0.ɵɵelementEnd();
545
572
  } if (rf & 2) {
546
573
  const ctx_r0 = i0.ɵɵnextContext();
@@ -552,8 +579,8 @@ function MJTestSuiteFormComponentExtended_Conditional_62_Template(rf, ctx) { if
552
579
  i0.ɵɵconditional(ctx_r0.runsLoaded && !ctx_r0.loadingRuns && ctx_r0.suiteRuns.length === 0 ? 3 : -1);
553
580
  } }
554
581
  function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_1_Template(rf, ctx) { if (rf & 1) {
555
- i0.ɵɵelementStart(0, "div", 99);
556
- i0.ɵɵelement(1, "mj-loading", 156);
582
+ i0.ɵɵelementStart(0, "div", 101);
583
+ i0.ɵɵelement(1, "mj-loading", 158);
557
584
  i0.ɵɵelementEnd();
558
585
  } }
559
586
  function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_template_15_Conditional_2_Conditional_2_Template(rf, ctx) { if (rf & 1) {
@@ -566,7 +593,7 @@ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_templa
566
593
  i0.ɵɵtextInterpolate1(" \u00B7 ", ctx_r0.selectedTags.length, " tags");
567
594
  } }
568
595
  function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_template_15_Conditional_2_Template(rf, ctx) { if (rf & 1) {
569
- i0.ɵɵelementStart(0, "span", 167);
596
+ i0.ɵɵelementStart(0, "span", 169);
570
597
  i0.ɵɵtext(1);
571
598
  i0.ɵɵconditionalCreate(2, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_template_15_Conditional_2_Conditional_2_Template, 2, 1, "span");
572
599
  i0.ɵɵelementEnd();
@@ -578,16 +605,16 @@ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_templa
578
605
  i0.ɵɵconditional(ctx_r0.selectedTags.length > 0 ? 2 : -1);
579
606
  } }
580
607
  function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_template_15_Template(rf, ctx) { if (rf & 1) {
581
- i0.ɵɵelement(0, "i", 166);
608
+ i0.ɵɵelement(0, "i", 168);
582
609
  i0.ɵɵtext(1, " Filters ");
583
- i0.ɵɵconditionalCreate(2, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_template_15_Conditional_2_Template, 3, 2, "span", 167);
610
+ i0.ɵɵconditionalCreate(2, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_template_15_Conditional_2_Template, 3, 2, "span", 169);
584
611
  } if (rf & 2) {
585
612
  const ctx_r0 = i0.ɵɵnextContext(3);
586
613
  i0.ɵɵadvance(2);
587
614
  i0.ɵɵconditional(ctx_r0.filtersCollapsed ? 2 : -1);
588
615
  } }
589
616
  function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_template_16_Conditional_13_Conditional_3_Template(rf, ctx) { if (rf & 1) {
590
- i0.ɵɵelementStart(0, "span", 172);
617
+ i0.ɵɵelementStart(0, "span", 174);
591
618
  i0.ɵɵtext(1);
592
619
  i0.ɵɵelementEnd();
593
620
  } if (rf & 2) {
@@ -596,36 +623,36 @@ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_templa
596
623
  i0.ɵɵtextInterpolate1("(", ctx_r0.selectedTags.length, " selected)");
597
624
  } }
598
625
  function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_template_16_Conditional_13_For_9_Conditional_1_Template(rf, ctx) { if (rf & 1) {
599
- i0.ɵɵelement(0, "i", 177);
626
+ i0.ɵɵelement(0, "i", 179);
600
627
  } }
601
628
  function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_template_16_Conditional_13_For_9_Template(rf, ctx) { if (rf & 1) {
602
- const _r22 = i0.ɵɵgetCurrentView();
603
- i0.ɵɵelementStart(0, "button", 176);
604
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_template_16_Conditional_13_For_9_Template_button_click_0_listener() { const tag_r23 = i0.ɵɵrestoreView(_r22).$implicit; const ctx_r0 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r0.toggleTagFilter(tag_r23)); });
605
- i0.ɵɵconditionalCreate(1, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_template_16_Conditional_13_For_9_Conditional_1_Template, 1, 0, "i", 177);
629
+ const _r23 = i0.ɵɵgetCurrentView();
630
+ i0.ɵɵelementStart(0, "button", 178);
631
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_template_16_Conditional_13_For_9_Template_button_click_0_listener() { const tag_r24 = i0.ɵɵrestoreView(_r23).$implicit; const ctx_r0 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r0.toggleTagFilter(tag_r24)); });
632
+ i0.ɵɵconditionalCreate(1, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_template_16_Conditional_13_For_9_Conditional_1_Template, 1, 0, "i", 179);
606
633
  i0.ɵɵtext(2);
607
634
  i0.ɵɵelementEnd();
608
635
  } if (rf & 2) {
609
- const tag_r23 = ctx.$implicit;
636
+ const tag_r24 = ctx.$implicit;
610
637
  const ctx_r0 = i0.ɵɵnextContext(5);
611
- i0.ɵɵclassProp("active", ctx_r0.isTagSelected(tag_r23));
638
+ i0.ɵɵclassProp("active", ctx_r0.isTagSelected(tag_r24));
612
639
  i0.ɵɵadvance();
613
- i0.ɵɵconditional(ctx_r0.isTagSelected(tag_r23) ? 1 : -1);
640
+ i0.ɵɵconditional(ctx_r0.isTagSelected(tag_r24) ? 1 : -1);
614
641
  i0.ɵɵadvance();
615
- i0.ɵɵtextInterpolate1(" ", tag_r23, " ");
642
+ i0.ɵɵtextInterpolate1(" ", tag_r24, " ");
616
643
  } }
617
644
  function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_template_16_Conditional_13_Template(rf, ctx) { if (rf & 1) {
618
- const _r21 = i0.ɵɵgetCurrentView();
619
- i0.ɵɵelementStart(0, "div", 169)(1, "label");
645
+ const _r22 = i0.ɵɵgetCurrentView();
646
+ i0.ɵɵelementStart(0, "div", 171)(1, "label");
620
647
  i0.ɵɵtext(2, "Filter by Tag ");
621
- i0.ɵɵconditionalCreate(3, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_template_16_Conditional_13_Conditional_3_Template, 2, 1, "span", 172);
648
+ i0.ɵɵconditionalCreate(3, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_template_16_Conditional_13_Conditional_3_Template, 2, 1, "span", 174);
622
649
  i0.ɵɵelementEnd();
623
- i0.ɵɵelementStart(4, "div", 173)(5, "button", 174);
624
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_template_16_Conditional_13_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r21); const ctx_r0 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r0.toggleTagFilter(null)); });
650
+ i0.ɵɵelementStart(4, "div", 175)(5, "button", 176);
651
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_template_16_Conditional_13_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r22); const ctx_r0 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r0.toggleTagFilter(null)); });
625
652
  i0.ɵɵelement(6, "i", 11);
626
653
  i0.ɵɵtext(7, " All Tags ");
627
654
  i0.ɵɵelementEnd();
628
- i0.ɵɵrepeaterCreate(8, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_template_16_Conditional_13_For_9_Template, 3, 4, "button", 175, i0.ɵɵrepeaterTrackByIdentity);
655
+ i0.ɵɵrepeaterCreate(8, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_template_16_Conditional_13_For_9_Template, 3, 4, "button", 177, i0.ɵɵrepeaterTrackByIdentity);
629
656
  i0.ɵɵelementEnd()();
630
657
  } if (rf & 2) {
631
658
  const ctx_r0 = i0.ɵɵnextContext(4);
@@ -637,27 +664,27 @@ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_templa
637
664
  i0.ɵɵrepeater(ctx_r0.uniqueTags);
638
665
  } }
639
666
  function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_template_16_Template(rf, ctx) { if (rf & 1) {
640
- const _r20 = i0.ɵɵgetCurrentView();
641
- i0.ɵɵelementStart(0, "div", 168)(1, "div", 169)(2, "label");
667
+ const _r21 = i0.ɵɵgetCurrentView();
668
+ i0.ɵɵelementStart(0, "div", 170)(1, "div", 171)(2, "label");
642
669
  i0.ɵɵtext(3, "Time Range");
643
670
  i0.ɵɵelementEnd();
644
- i0.ɵɵelementStart(4, "div", 170)(5, "button", 171);
645
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_template_16_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r20); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.setTimeRange("7d")); });
671
+ i0.ɵɵelementStart(4, "div", 172)(5, "button", 173);
672
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_template_16_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r21); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.setTimeRange("7d")); });
646
673
  i0.ɵɵtext(6, "7 Days");
647
674
  i0.ɵɵelementEnd();
648
- i0.ɵɵelementStart(7, "button", 171);
649
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_template_16_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r20); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.setTimeRange("30d")); });
675
+ i0.ɵɵelementStart(7, "button", 173);
676
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_template_16_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r21); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.setTimeRange("30d")); });
650
677
  i0.ɵɵtext(8, "30 Days");
651
678
  i0.ɵɵelementEnd();
652
- i0.ɵɵelementStart(9, "button", 171);
653
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_template_16_Template_button_click_9_listener() { i0.ɵɵrestoreView(_r20); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.setTimeRange("90d")); });
679
+ i0.ɵɵelementStart(9, "button", 173);
680
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_template_16_Template_button_click_9_listener() { i0.ɵɵrestoreView(_r21); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.setTimeRange("90d")); });
654
681
  i0.ɵɵtext(10, "90 Days");
655
682
  i0.ɵɵelementEnd();
656
- i0.ɵɵelementStart(11, "button", 171);
657
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_template_16_Template_button_click_11_listener() { i0.ɵɵrestoreView(_r20); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.setTimeRange("all")); });
683
+ i0.ɵɵelementStart(11, "button", 173);
684
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_template_16_Template_button_click_11_listener() { i0.ɵɵrestoreView(_r21); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.setTimeRange("all")); });
658
685
  i0.ɵɵtext(12, "All Time");
659
686
  i0.ɵɵelementEnd()()();
660
- i0.ɵɵconditionalCreate(13, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_template_16_Conditional_13_Template, 10, 3, "div", 169);
687
+ i0.ɵɵconditionalCreate(13, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_template_16_Conditional_13_Template, 10, 3, "div", 171);
661
688
  i0.ɵɵelementEnd();
662
689
  } if (rf & 2) {
663
690
  const ctx_r0 = i0.ɵɵnextContext(3);
@@ -673,36 +700,36 @@ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_templa
673
700
  i0.ɵɵconditional(ctx_r0.uniqueTags.length > 0 ? 13 : -1);
674
701
  } }
675
702
  function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_17_For_60_For_21_Template(rf, ctx) { if (rf & 1) {
676
- i0.ɵɵelementStart(0, "span", 201);
703
+ i0.ɵɵelementStart(0, "span", 203);
677
704
  i0.ɵɵtext(1);
678
705
  i0.ɵɵelementEnd();
679
706
  } if (rf & 2) {
680
- const tag_r26 = ctx.$implicit;
707
+ const tag_r27 = ctx.$implicit;
681
708
  i0.ɵɵadvance();
682
- i0.ɵɵtextInterpolate(tag_r26);
709
+ i0.ɵɵtextInterpolate(tag_r27);
683
710
  } }
684
711
  function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_17_For_60_Conditional_22_Template(rf, ctx) { if (rf & 1) {
685
- i0.ɵɵelementStart(0, "span", 202);
712
+ i0.ɵɵelementStart(0, "span", 204);
686
713
  i0.ɵɵtext(1);
687
714
  i0.ɵɵelementEnd();
688
715
  } if (rf & 2) {
689
- const dp_r25 = i0.ɵɵnextContext().$implicit;
716
+ const dp_r26 = i0.ɵɵnextContext().$implicit;
690
717
  i0.ɵɵadvance();
691
- i0.ɵɵtextInterpolate1("+", dp_r25.tags.length - 2);
718
+ i0.ɵɵtextInterpolate1("+", dp_r26.tags.length - 2);
692
719
  } }
693
720
  function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_17_For_60_Template(rf, ctx) { if (rf & 1) {
694
- const _r24 = i0.ɵɵgetCurrentView();
695
- i0.ɵɵelementStart(0, "tr", 196);
696
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_17_For_60_Template_tr_click_0_listener() { const dp_r25 = i0.ɵɵrestoreView(_r24).$implicit; const ctx_r0 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r0.openSuiteRun(dp_r25.runId)); });
721
+ const _r25 = i0.ɵɵgetCurrentView();
722
+ i0.ɵɵelementStart(0, "tr", 198);
723
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_17_For_60_Template_tr_click_0_listener() { const dp_r26 = i0.ɵɵrestoreView(_r25).$implicit; const ctx_r0 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r0.openSuiteRun(dp_r26.runId)); });
697
724
  i0.ɵɵelementStart(1, "td");
698
725
  i0.ɵɵtext(2);
699
726
  i0.ɵɵpipe(3, "date");
700
727
  i0.ɵɵelementEnd();
701
- i0.ɵɵelementStart(4, "td")(5, "span", 197);
728
+ i0.ɵɵelementStart(4, "td")(5, "span", 199);
702
729
  i0.ɵɵtext(6);
703
730
  i0.ɵɵelementEnd()();
704
- i0.ɵɵelementStart(7, "td")(8, "div", 198);
705
- i0.ɵɵelement(9, "div", 199);
731
+ i0.ɵɵelementStart(7, "td")(8, "div", 200);
732
+ i0.ɵɵelement(9, "div", 201);
706
733
  i0.ɵɵelementStart(10, "span");
707
734
  i0.ɵɵtext(11);
708
735
  i0.ɵɵelementEnd()()();
@@ -715,84 +742,84 @@ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Condition
715
742
  i0.ɵɵelementStart(16, "td");
716
743
  i0.ɵɵtext(17);
717
744
  i0.ɵɵelementEnd();
718
- i0.ɵɵelementStart(18, "td")(19, "div", 200);
719
- i0.ɵɵrepeaterCreate(20, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_17_For_60_For_21_Template, 2, 1, "span", 201, i0.ɵɵrepeaterTrackByIdentity);
720
- i0.ɵɵconditionalCreate(22, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_17_For_60_Conditional_22_Template, 2, 1, "span", 202);
745
+ i0.ɵɵelementStart(18, "td")(19, "div", 202);
746
+ i0.ɵɵrepeaterCreate(20, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_17_For_60_For_21_Template, 2, 1, "span", 203, i0.ɵɵrepeaterTrackByIdentity);
747
+ i0.ɵɵconditionalCreate(22, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_17_For_60_Conditional_22_Template, 2, 1, "span", 204);
721
748
  i0.ɵɵelementEnd()()();
722
749
  } if (rf & 2) {
723
- const dp_r25 = ctx.$implicit;
750
+ const dp_r26 = ctx.$implicit;
724
751
  const ctx_r0 = i0.ɵɵnextContext(4);
725
752
  i0.ɵɵadvance(2);
726
- i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(3, 12, dp_r25.date, "short"));
753
+ i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(3, 12, dp_r26.date, "short"));
727
754
  i0.ɵɵadvance(3);
728
- i0.ɵɵproperty("ngClass", "status-" + dp_r25.status.toLowerCase());
755
+ i0.ɵɵproperty("ngClass", "status-" + dp_r26.status.toLowerCase());
729
756
  i0.ɵɵadvance();
730
- i0.ɵɵtextInterpolate(dp_r25.status);
757
+ i0.ɵɵtextInterpolate(dp_r26.status);
731
758
  i0.ɵɵadvance(3);
732
- i0.ɵɵstyleProp("width", dp_r25.passRate, "%");
733
- i0.ɵɵproperty("ngClass", i0.ɵɵpureFunction3(15, _c5, dp_r25.passRate >= 80, dp_r25.passRate >= 50 && dp_r25.passRate < 80, dp_r25.passRate < 50));
759
+ i0.ɵɵstyleProp("width", dp_r26.passRate, "%");
760
+ i0.ɵɵproperty("ngClass", i0.ɵɵpureFunction3(15, _c5, dp_r26.passRate >= 80, dp_r26.passRate >= 50 && dp_r26.passRate < 80, dp_r26.passRate < 50));
734
761
  i0.ɵɵadvance(2);
735
- i0.ɵɵtextInterpolate1("", dp_r25.passRate.toFixed(0), "%");
762
+ i0.ɵɵtextInterpolate1("", dp_r26.passRate.toFixed(0), "%");
736
763
  i0.ɵɵadvance(2);
737
- i0.ɵɵtextInterpolate2("", dp_r25.passedTests, "/", dp_r25.totalTests);
764
+ i0.ɵɵtextInterpolate2("", dp_r26.passedTests, "/", dp_r26.totalTests);
738
765
  i0.ɵɵadvance(2);
739
- i0.ɵɵtextInterpolate(ctx_r0.formatDuration(dp_r25.duration));
766
+ i0.ɵɵtextInterpolate(ctx_r0.formatDuration(dp_r26.duration));
740
767
  i0.ɵɵadvance(2);
741
- i0.ɵɵtextInterpolate(ctx_r0.formatCost(dp_r25.cost));
768
+ i0.ɵɵtextInterpolate(ctx_r0.formatCost(dp_r26.cost));
742
769
  i0.ɵɵadvance(3);
743
- i0.ɵɵrepeater(dp_r25.tags.slice(0, 2));
770
+ i0.ɵɵrepeater(dp_r26.tags.slice(0, 2));
744
771
  i0.ɵɵadvance(2);
745
- i0.ɵɵconditional(dp_r25.tags.length > 2 ? 22 : -1);
772
+ i0.ɵɵconditional(dp_r26.tags.length > 2 ? 22 : -1);
746
773
  } }
747
774
  function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_17_Conditional_61_Template(rf, ctx) { if (rf & 1) {
748
- i0.ɵɵelement(0, "mj-empty-state", 195);
775
+ i0.ɵɵelement(0, "mj-empty-state", 197);
749
776
  } }
750
777
  function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_17_Template(rf, ctx) { if (rf & 1) {
751
- i0.ɵɵelementStart(0, "div", 178)(1, "div", 179)(2, "div", 180);
752
- i0.ɵɵelement(3, "i", 181);
778
+ i0.ɵɵelementStart(0, "div", 180)(1, "div", 181)(2, "div", 182);
779
+ i0.ɵɵelement(3, "i", 183);
753
780
  i0.ɵɵelementEnd();
754
- i0.ɵɵelementStart(4, "div", 182)(5, "div", 183);
781
+ i0.ɵɵelementStart(4, "div", 184)(5, "div", 185);
755
782
  i0.ɵɵtext(6);
756
783
  i0.ɵɵelementEnd();
757
- i0.ɵɵelementStart(7, "div", 184);
784
+ i0.ɵɵelementStart(7, "div", 186);
758
785
  i0.ɵɵtext(8, "Total Runs");
759
786
  i0.ɵɵelementEnd()()();
760
- i0.ɵɵelementStart(9, "div", 179)(10, "div", 185);
761
- i0.ɵɵelement(11, "i", 146);
787
+ i0.ɵɵelementStart(9, "div", 181)(10, "div", 187);
788
+ i0.ɵɵelement(11, "i", 148);
762
789
  i0.ɵɵelementEnd();
763
- i0.ɵɵelementStart(12, "div", 182)(13, "div", 183);
790
+ i0.ɵɵelementStart(12, "div", 184)(13, "div", 185);
764
791
  i0.ɵɵtext(14);
765
792
  i0.ɵɵelementEnd();
766
- i0.ɵɵelementStart(15, "div", 184);
793
+ i0.ɵɵelementStart(15, "div", 186);
767
794
  i0.ɵɵtext(16, "Avg Pass Rate");
768
795
  i0.ɵɵelementEnd();
769
- i0.ɵɵelementStart(17, "div", 186);
796
+ i0.ɵɵelementStart(17, "div", 188);
770
797
  i0.ɵɵelement(18, "i", 19);
771
798
  i0.ɵɵtext(19);
772
799
  i0.ɵɵelementEnd()()();
773
- i0.ɵɵelementStart(20, "div", 179)(21, "div", 187);
774
- i0.ɵɵelement(22, "i", 150);
800
+ i0.ɵɵelementStart(20, "div", 181)(21, "div", 189);
801
+ i0.ɵɵelement(22, "i", 152);
775
802
  i0.ɵɵelementEnd();
776
- i0.ɵɵelementStart(23, "div", 182)(24, "div", 183);
803
+ i0.ɵɵelementStart(23, "div", 184)(24, "div", 185);
777
804
  i0.ɵɵtext(25);
778
805
  i0.ɵɵelementEnd();
779
- i0.ɵɵelementStart(26, "div", 184);
806
+ i0.ɵɵelementStart(26, "div", 186);
780
807
  i0.ɵɵtext(27, "Avg Duration");
781
808
  i0.ɵɵelementEnd()()();
782
- i0.ɵɵelementStart(28, "div", 179)(29, "div", 188);
783
- i0.ɵɵelement(30, "i", 189);
809
+ i0.ɵɵelementStart(28, "div", 181)(29, "div", 190);
810
+ i0.ɵɵelement(30, "i", 191);
784
811
  i0.ɵɵelementEnd();
785
- i0.ɵɵelementStart(31, "div", 182)(32, "div", 183);
812
+ i0.ɵɵelementStart(31, "div", 184)(32, "div", 185);
786
813
  i0.ɵɵtext(33);
787
814
  i0.ɵɵelementEnd();
788
- i0.ɵɵelementStart(34, "div", 184);
815
+ i0.ɵɵelementStart(34, "div", 186);
789
816
  i0.ɵɵtext(35, "Total Cost");
790
817
  i0.ɵɵelementEnd()()()();
791
- i0.ɵɵelementStart(36, "div", 190)(37, "h3");
792
- i0.ɵɵelement(38, "i", 191);
818
+ i0.ɵɵelementStart(36, "div", 192)(37, "h3");
819
+ i0.ɵɵelement(38, "i", 193);
793
820
  i0.ɵɵtext(39, " Run History");
794
821
  i0.ɵɵelementEnd();
795
- i0.ɵɵelementStart(40, "div", 192)(41, "table", 193)(42, "thead")(43, "tr")(44, "th");
822
+ i0.ɵɵelementStart(40, "div", 194)(41, "table", 195)(42, "thead")(43, "tr")(44, "th");
796
823
  i0.ɵɵtext(45, "Date");
797
824
  i0.ɵɵelementEnd();
798
825
  i0.ɵɵelementStart(46, "th");
@@ -814,9 +841,9 @@ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Condition
814
841
  i0.ɵɵtext(57, "Tags");
815
842
  i0.ɵɵelementEnd()()();
816
843
  i0.ɵɵelementStart(58, "tbody");
817
- i0.ɵɵrepeaterCreate(59, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_17_For_60_Template, 23, 19, "tr", 194, i0.ɵɵrepeaterTrackByIdentity);
844
+ i0.ɵɵrepeaterCreate(59, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_17_For_60_Template, 23, 19, "tr", 196, i0.ɵɵrepeaterTrackByIdentity);
818
845
  i0.ɵɵelementEnd()()();
819
- i0.ɵɵconditionalCreate(61, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_17_Conditional_61_Template, 1, 0, "mj-empty-state", 195);
846
+ i0.ɵɵconditionalCreate(61, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_17_Conditional_61_Template, 1, 0, "mj-empty-state", 197);
820
847
  i0.ɵɵelementEnd();
821
848
  } if (rf & 2) {
822
849
  const ctx_r0 = i0.ɵɵnextContext(3);
@@ -840,259 +867,259 @@ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Condition
840
867
  i0.ɵɵconditional(ctx_r0.getFilteredAnalyticsData().length === 0 ? 61 : -1);
841
868
  } }
842
869
  function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_0_Template(rf, ctx) { if (rf & 1) {
843
- i0.ɵɵelementStart(0, "div", 99);
844
- i0.ɵɵelement(1, "mj-loading", 205);
870
+ i0.ɵɵelementStart(0, "div", 101);
871
+ i0.ɵɵelement(1, "mj-loading", 207);
845
872
  i0.ɵɵelementEnd();
846
873
  } }
847
874
  function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_Conditional_9_Template(rf, ctx) { if (rf & 1) {
848
- const _r28 = i0.ɵɵgetCurrentView();
849
- i0.ɵɵelementStart(0, "button", 227);
850
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_Conditional_9_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r28); const ctx_r0 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r0.clearMatrixFilter()); });
851
- i0.ɵɵelement(1, "i", 91);
875
+ const _r29 = i0.ɵɵgetCurrentView();
876
+ i0.ɵɵelementStart(0, "button", 229);
877
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_Conditional_9_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r29); const ctx_r0 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r0.clearMatrixFilter()); });
878
+ i0.ɵɵelement(1, "i", 93);
852
879
  i0.ɵɵelementEnd();
853
880
  } }
854
881
  function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_26_Conditional_3_For_2_Template(rf, ctx) { if (rf & 1) {
855
- i0.ɵɵelementStart(0, "span", 233);
882
+ i0.ɵɵelementStart(0, "span", 235);
856
883
  i0.ɵɵtext(1);
857
884
  i0.ɵɵelementEnd();
858
885
  } if (rf & 2) {
859
- const tag_r31 = ctx.$implicit;
886
+ const tag_r32 = ctx.$implicit;
860
887
  i0.ɵɵadvance();
861
- i0.ɵɵtextInterpolate(tag_r31);
888
+ i0.ɵɵtextInterpolate(tag_r32);
862
889
  } }
863
890
  function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_26_Conditional_3_Conditional_3_Template(rf, ctx) { if (rf & 1) {
864
- i0.ɵɵelementStart(0, "span", 234);
891
+ i0.ɵɵelementStart(0, "span", 236);
865
892
  i0.ɵɵtext(1);
866
893
  i0.ɵɵelementEnd();
867
894
  } if (rf & 2) {
868
- const run_r30 = i0.ɵɵnextContext(2).$implicit;
895
+ const run_r31 = i0.ɵɵnextContext(2).$implicit;
869
896
  i0.ɵɵadvance();
870
- i0.ɵɵtextInterpolate1("+", run_r30.tags.length - 2);
897
+ i0.ɵɵtextInterpolate1("+", run_r31.tags.length - 2);
871
898
  } }
872
899
  function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_26_Conditional_3_Template(rf, ctx) { if (rf & 1) {
873
- i0.ɵɵelementStart(0, "div", 230);
874
- i0.ɵɵrepeaterCreate(1, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_26_Conditional_3_For_2_Template, 2, 1, "span", 233, i0.ɵɵrepeaterTrackByIdentity);
875
- i0.ɵɵconditionalCreate(3, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_26_Conditional_3_Conditional_3_Template, 2, 1, "span", 234);
900
+ i0.ɵɵelementStart(0, "div", 232);
901
+ i0.ɵɵrepeaterCreate(1, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_26_Conditional_3_For_2_Template, 2, 1, "span", 235, i0.ɵɵrepeaterTrackByIdentity);
902
+ i0.ɵɵconditionalCreate(3, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_26_Conditional_3_Conditional_3_Template, 2, 1, "span", 236);
876
903
  i0.ɵɵelementEnd();
877
904
  } if (rf & 2) {
878
- const run_r30 = i0.ɵɵnextContext().$implicit;
905
+ const run_r31 = i0.ɵɵnextContext().$implicit;
879
906
  i0.ɵɵadvance();
880
- i0.ɵɵrepeater(run_r30.tags.slice(0, 2));
907
+ i0.ɵɵrepeater(run_r31.tags.slice(0, 2));
881
908
  i0.ɵɵadvance(2);
882
- i0.ɵɵconditional(run_r30.tags.length > 2 ? 3 : -1);
909
+ i0.ɵɵconditional(run_r31.tags.length > 2 ? 3 : -1);
883
910
  } }
884
911
  function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_26_Template(rf, ctx) { if (rf & 1) {
885
- const _r29 = i0.ɵɵgetCurrentView();
886
- i0.ɵɵelementStart(0, "th", 228);
912
+ const _r30 = i0.ɵɵgetCurrentView();
913
+ i0.ɵɵelementStart(0, "th", 230);
887
914
  i0.ɵɵpipe(1, "date");
888
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_26_Template_th_click_0_listener() { const run_r30 = i0.ɵɵrestoreView(_r29).$implicit; const ctx_r0 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r0.openSuiteRun(run_r30.runId)); });
889
- i0.ɵɵelementStart(2, "div", 229);
890
- i0.ɵɵconditionalCreate(3, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_26_Conditional_3_Template, 4, 1, "div", 230);
891
- i0.ɵɵelementStart(4, "div", 231);
915
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_26_Template_th_click_0_listener() { const run_r31 = i0.ɵɵrestoreView(_r30).$implicit; const ctx_r0 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r0.openSuiteRun(run_r31.runId)); });
916
+ i0.ɵɵelementStart(2, "div", 231);
917
+ i0.ɵɵconditionalCreate(3, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_26_Conditional_3_Template, 4, 1, "div", 232);
918
+ i0.ɵɵelementStart(4, "div", 233);
892
919
  i0.ɵɵtext(5);
893
920
  i0.ɵɵelementEnd();
894
- i0.ɵɵelementStart(6, "div", 232);
921
+ i0.ɵɵelementStart(6, "div", 234);
895
922
  i0.ɵɵtext(7);
896
923
  i0.ɵɵelementEnd()()();
897
924
  } if (rf & 2) {
898
- const run_r30 = ctx.$implicit;
925
+ const run_r31 = ctx.$implicit;
899
926
  const ctx_r0 = i0.ɵɵnextContext(5);
900
- i0.ɵɵproperty("title", "Click to view suite run - " + i0.ɵɵpipeBind2(1, 5, run_r30.date, "medium"));
927
+ i0.ɵɵproperty("title", "Click to view suite run - " + i0.ɵɵpipeBind2(1, 5, run_r31.date, "medium"));
901
928
  i0.ɵɵadvance(3);
902
- i0.ɵɵconditional(run_r30.tags.length > 0 ? 3 : -1);
929
+ i0.ɵɵconditional(run_r31.tags.length > 0 ? 3 : -1);
903
930
  i0.ɵɵadvance(2);
904
- i0.ɵɵtextInterpolate(ctx_r0.getRelativeTime(run_r30.date));
931
+ i0.ɵɵtextInterpolate(ctx_r0.getRelativeTime(run_r31.date));
905
932
  i0.ɵɵadvance();
906
- i0.ɵɵproperty("ngClass", i0.ɵɵpureFunction3(8, _c5, run_r30.passRate >= 80, run_r30.passRate >= 50 && run_r30.passRate < 80, run_r30.passRate < 50));
933
+ i0.ɵɵproperty("ngClass", i0.ɵɵpureFunction3(8, _c5, run_r31.passRate >= 80, run_r31.passRate >= 50 && run_r31.passRate < 80, run_r31.passRate < 50));
907
934
  i0.ɵɵadvance();
908
- i0.ɵɵtextInterpolate1(" ", run_r30.passRate.toFixed(0), "% ");
935
+ i0.ɵɵtextInterpolate1(" ", run_r31.passRate.toFixed(0), "% ");
909
936
  } }
910
937
  function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_30_For_7_Conditional_1_Conditional_1_Template(rf, ctx) { if (rf & 1) {
911
- i0.ɵɵelementStart(0, "span", 248);
912
- i0.ɵɵelement(1, "i", 133);
938
+ i0.ɵɵelementStart(0, "span", 250);
939
+ i0.ɵɵelement(1, "i", 135);
913
940
  i0.ɵɵelementEnd();
914
941
  } if (rf & 2) {
915
- const result_r36 = i0.ɵɵnextContext();
942
+ const result_r37 = i0.ɵɵnextContext();
916
943
  const ctx_r0 = i0.ɵɵnextContext(7);
917
- i0.ɵɵclassProp("cell-skipped-status", result_r36.status === "Skipped" || result_r36.status === "Pending");
918
- i0.ɵɵproperty("ngClass", "status-" + result_r36.status.toLowerCase())("title", ctx_r0.getStatusTooltip(result_r36.status));
944
+ i0.ɵɵclassProp("cell-skipped-status", result_r37.status === "Skipped" || result_r37.status === "Pending");
945
+ i0.ɵɵproperty("ngClass", "status-" + result_r37.status.toLowerCase())("title", ctx_r0.getStatusTooltip(result_r37.status));
919
946
  i0.ɵɵadvance();
920
- i0.ɵɵclassProp("fa-check", result_r36.status === "Passed")("fa-times", result_r36.status === "Failed")("fa-exclamation", result_r36.status === "Error")("fa-hourglass-end", result_r36.status === "Timeout")("fa-forward", result_r36.status === "Skipped")("fa-spinner", result_r36.status === "Running")("fa-clock", result_r36.status === "Pending");
947
+ i0.ɵɵclassProp("fa-check", result_r37.status === "Passed")("fa-times", result_r37.status === "Failed")("fa-exclamation", result_r37.status === "Error")("fa-hourglass-end", result_r37.status === "Timeout")("fa-forward", result_r37.status === "Skipped")("fa-spinner", result_r37.status === "Running")("fa-clock", result_r37.status === "Pending");
921
948
  } }
922
949
  function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_30_For_7_Conditional_1_Conditional_2_Template(rf, ctx) { if (rf & 1) {
923
- i0.ɵɵelementStart(0, "span", 244);
924
- i0.ɵɵelement(1, "i", 249);
950
+ i0.ɵɵelementStart(0, "span", 246);
951
+ i0.ɵɵelement(1, "i", 251);
925
952
  i0.ɵɵelementEnd();
926
953
  } }
927
954
  function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_30_For_7_Conditional_1_Conditional_3_Template(rf, ctx) { if (rf & 1) {
928
- i0.ɵɵelementStart(0, "span", 250);
929
- i0.ɵɵelement(1, "i", 148);
930
- i0.ɵɵelementStart(2, "span", 251);
955
+ i0.ɵɵelementStart(0, "span", 252);
956
+ i0.ɵɵelement(1, "i", 150);
957
+ i0.ɵɵelementStart(2, "span", 253);
931
958
  i0.ɵɵtext(3);
932
959
  i0.ɵɵelementEnd()();
933
960
  } if (rf & 2) {
934
- const result_r36 = i0.ɵɵnextContext();
961
+ const result_r37 = i0.ɵɵnextContext();
935
962
  const ctx_r0 = i0.ɵɵnextContext(7);
936
- i0.ɵɵclassProp("rating-low", result_r36.humanRating <= 4)("rating-medium", result_r36.humanRating >= 5 && result_r36.humanRating <= 6)("rating-good", result_r36.humanRating >= 7 && result_r36.humanRating <= 8)("rating-excellent", result_r36.humanRating >= 9);
937
- i0.ɵɵproperty("title", ctx_r0.getHumanTooltip(result_r36.humanRating, result_r36.humanComments));
963
+ i0.ɵɵclassProp("rating-low", result_r37.humanRating <= 4)("rating-medium", result_r37.humanRating >= 5 && result_r37.humanRating <= 6)("rating-good", result_r37.humanRating >= 7 && result_r37.humanRating <= 8)("rating-excellent", result_r37.humanRating >= 9);
964
+ i0.ɵɵproperty("title", ctx_r0.getHumanTooltip(result_r37.humanRating, result_r37.humanComments));
938
965
  i0.ɵɵadvance(3);
939
- i0.ɵɵtextInterpolate(result_r36.humanRating);
966
+ i0.ɵɵtextInterpolate(result_r37.humanRating);
940
967
  } }
941
968
  function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_30_For_7_Conditional_1_Conditional_4_Template(rf, ctx) { if (rf & 1) {
942
- i0.ɵɵelementStart(0, "span", 252);
943
- i0.ɵɵelement(1, "i", 152);
944
- i0.ɵɵelementStart(2, "span", 253);
969
+ i0.ɵɵelementStart(0, "span", 254);
970
+ i0.ɵɵelement(1, "i", 154);
971
+ i0.ɵɵelementStart(2, "span", 255);
945
972
  i0.ɵɵtext(3);
946
973
  i0.ɵɵelementEnd()();
947
974
  } if (rf & 2) {
948
- const result_r36 = i0.ɵɵnextContext();
949
- i0.ɵɵclassProp("score-low", result_r36.score < 0.5)("score-medium", result_r36.score >= 0.5 && result_r36.score < 0.7)("score-good", result_r36.score >= 0.7 && result_r36.score < 0.85)("score-excellent", result_r36.score >= 0.85);
950
- i0.ɵɵproperty("title", "Auto Score: " + (result_r36.score * 100).toFixed(0) + "% automated evaluation");
975
+ const result_r37 = i0.ɵɵnextContext();
976
+ i0.ɵɵclassProp("score-low", result_r37.score < 0.5)("score-medium", result_r37.score >= 0.5 && result_r37.score < 0.7)("score-good", result_r37.score >= 0.7 && result_r37.score < 0.85)("score-excellent", result_r37.score >= 0.85);
977
+ i0.ɵɵproperty("title", "Auto Score: " + (result_r37.score * 100).toFixed(0) + "% automated evaluation");
951
978
  i0.ɵɵadvance(3);
952
- i0.ɵɵtextInterpolate((result_r36.score * 100).toFixed(0));
979
+ i0.ɵɵtextInterpolate((result_r37.score * 100).toFixed(0));
953
980
  } }
954
981
  function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_30_For_7_Conditional_1_Conditional_5_Template(rf, ctx) { if (rf & 1) {
955
- i0.ɵɵelementStart(0, "span", 247);
956
- i0.ɵɵelement(1, "i", 152);
982
+ i0.ɵɵelementStart(0, "span", 249);
983
+ i0.ɵɵelement(1, "i", 154);
957
984
  i0.ɵɵelementEnd();
958
985
  } }
959
986
  function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_30_For_7_Conditional_1_Template(rf, ctx) { if (rf & 1) {
960
- i0.ɵɵelementStart(0, "div", 241);
961
- i0.ɵɵconditionalCreate(1, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_30_For_7_Conditional_1_Conditional_1_Template, 2, 18, "span", 243);
962
- i0.ɵɵconditionalCreate(2, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_30_For_7_Conditional_1_Conditional_2_Template, 2, 0, "span", 244);
963
- i0.ɵɵconditionalCreate(3, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_30_For_7_Conditional_1_Conditional_3_Template, 4, 10, "span", 245);
964
- i0.ɵɵconditionalCreate(4, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_30_For_7_Conditional_1_Conditional_4_Template, 4, 10, "span", 246);
965
- i0.ɵɵconditionalCreate(5, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_30_For_7_Conditional_1_Conditional_5_Template, 2, 0, "span", 247);
987
+ i0.ɵɵelementStart(0, "div", 243);
988
+ i0.ɵɵconditionalCreate(1, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_30_For_7_Conditional_1_Conditional_1_Template, 2, 18, "span", 245);
989
+ i0.ɵɵconditionalCreate(2, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_30_For_7_Conditional_1_Conditional_2_Template, 2, 0, "span", 246);
990
+ i0.ɵɵconditionalCreate(3, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_30_For_7_Conditional_1_Conditional_3_Template, 4, 10, "span", 247);
991
+ i0.ɵɵconditionalCreate(4, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_30_For_7_Conditional_1_Conditional_4_Template, 4, 10, "span", 248);
992
+ i0.ɵɵconditionalCreate(5, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_30_For_7_Conditional_1_Conditional_5_Template, 2, 0, "span", 249);
966
993
  i0.ɵɵelementEnd();
967
994
  } if (rf & 2) {
968
- const result_r36 = ctx;
995
+ const result_r37 = ctx;
969
996
  const ctx_r0 = i0.ɵɵnextContext(7);
970
997
  i0.ɵɵadvance();
971
998
  i0.ɵɵconditional(ctx_r0.evalPreferences.showExecution ? 1 : -1);
972
999
  i0.ɵɵadvance();
973
- i0.ɵɵconditional(ctx_r0.evalPreferences.showHuman && !result_r36.humanRating ? 2 : -1);
1000
+ i0.ɵɵconditional(ctx_r0.evalPreferences.showHuman && !result_r37.humanRating ? 2 : -1);
974
1001
  i0.ɵɵadvance();
975
- i0.ɵɵconditional(ctx_r0.evalPreferences.showHuman && result_r36.humanRating ? 3 : -1);
1002
+ i0.ɵɵconditional(ctx_r0.evalPreferences.showHuman && result_r37.humanRating ? 3 : -1);
976
1003
  i0.ɵɵadvance();
977
- i0.ɵɵconditional(ctx_r0.evalPreferences.showAuto && result_r36.score != null ? 4 : -1);
1004
+ i0.ɵɵconditional(ctx_r0.evalPreferences.showAuto && result_r37.score != null ? 4 : -1);
978
1005
  i0.ɵɵadvance();
979
- i0.ɵɵconditional(ctx_r0.evalPreferences.showAuto && result_r36.score == null ? 5 : -1);
1006
+ i0.ɵɵconditional(ctx_r0.evalPreferences.showAuto && result_r37.score == null ? 5 : -1);
980
1007
  } }
981
1008
  function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_30_For_7_Conditional_2_Template(rf, ctx) { if (rf & 1) {
982
- i0.ɵɵelementStart(0, "span", 242);
983
- i0.ɵɵelement(1, "i", 254);
1009
+ i0.ɵɵelementStart(0, "span", 244);
1010
+ i0.ɵɵelement(1, "i", 256);
984
1011
  i0.ɵɵelementEnd();
985
1012
  } }
986
1013
  function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_30_For_7_Template(rf, ctx) { if (rf & 1) {
987
- const _r34 = i0.ɵɵgetCurrentView();
988
- i0.ɵɵelementStart(0, "td", 240);
989
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_30_For_7_Template_td_click_0_listener($event) { const run_r35 = i0.ɵɵrestoreView(_r34).$implicit; const test_r33 = i0.ɵɵnextContext().$implicit; const ctx_r0 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r0.onMatrixCellClick(ctx_r0.getTestResultForRun(run_r35.runId, test_r33.testId), $event)); });
990
- i0.ɵɵconditionalCreate(1, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_30_For_7_Conditional_1_Template, 6, 5, "div", 241);
991
- i0.ɵɵconditionalCreate(2, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_30_For_7_Conditional_2_Template, 2, 0, "span", 242);
1014
+ const _r35 = i0.ɵɵgetCurrentView();
1015
+ i0.ɵɵelementStart(0, "td", 242);
1016
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_30_For_7_Template_td_click_0_listener($event) { const run_r36 = i0.ɵɵrestoreView(_r35).$implicit; const test_r34 = i0.ɵɵnextContext().$implicit; const ctx_r0 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r0.onMatrixCellClick(ctx_r0.getTestResultForRun(run_r36.runId, test_r34.testId), $event)); });
1017
+ i0.ɵɵconditionalCreate(1, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_30_For_7_Conditional_1_Template, 6, 5, "div", 243);
1018
+ i0.ɵɵconditionalCreate(2, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_30_For_7_Conditional_2_Template, 2, 0, "span", 244);
992
1019
  i0.ɵɵelementEnd();
993
1020
  } if (rf & 2) {
994
1021
  let tmp_27_0;
995
1022
  let tmp_28_0;
996
- const run_r35 = ctx.$implicit;
997
- const test_r33 = i0.ɵɵnextContext().$implicit;
1023
+ const run_r36 = ctx.$implicit;
1024
+ const test_r34 = i0.ɵɵnextContext().$implicit;
998
1025
  const ctx_r0 = i0.ɵɵnextContext(5);
999
- i0.ɵɵclassProp("clickable", ctx_r0.getTestResultForRun(run_r35.runId, test_r33.testId))("cell-not-run", !ctx_r0.getTestResultForRun(run_r35.runId, test_r33.testId));
1000
- i0.ɵɵproperty("ngClass", ctx_r0.getMatrixCellClass(ctx_r0.getTestResultForRun(run_r35.runId, test_r33.testId)))("title", ((tmp_27_0 = ctx_r0.getTestResultForRun(run_r35.runId, test_r33.testId)) == null ? null : tmp_27_0.status) + " - Click to view test run" || "Not Run");
1026
+ i0.ɵɵclassProp("clickable", ctx_r0.getTestResultForRun(run_r36.runId, test_r34.testId))("cell-not-run", !ctx_r0.getTestResultForRun(run_r36.runId, test_r34.testId));
1027
+ i0.ɵɵproperty("ngClass", ctx_r0.getMatrixCellClass(ctx_r0.getTestResultForRun(run_r36.runId, test_r34.testId)))("title", ((tmp_27_0 = ctx_r0.getTestResultForRun(run_r36.runId, test_r34.testId)) == null ? null : tmp_27_0.status) + " - Click to view test run" || "Not Run");
1001
1028
  i0.ɵɵadvance();
1002
- i0.ɵɵconditional((tmp_28_0 = ctx_r0.getTestResultForRun(run_r35.runId, test_r33.testId)) ? 1 : -1, tmp_28_0);
1029
+ i0.ɵɵconditional((tmp_28_0 = ctx_r0.getTestResultForRun(run_r36.runId, test_r34.testId)) ? 1 : -1, tmp_28_0);
1003
1030
  i0.ɵɵadvance();
1004
- i0.ɵɵconditional(!ctx_r0.getTestResultForRun(run_r35.runId, test_r33.testId) ? 2 : -1);
1031
+ i0.ɵɵconditional(!ctx_r0.getTestResultForRun(run_r36.runId, test_r34.testId) ? 2 : -1);
1005
1032
  } }
1006
1033
  function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_30_Template(rf, ctx) { if (rf & 1) {
1007
- const _r32 = i0.ɵɵgetCurrentView();
1008
- i0.ɵɵelementStart(0, "tr", 235);
1009
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_30_Template_tr_click_0_listener() { const test_r33 = i0.ɵɵrestoreView(_r32).$implicit; const ctx_r0 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r0.selectMatrixRow(test_r33.testId)); });
1010
- i0.ɵɵelementStart(1, "td", 236);
1034
+ const _r33 = i0.ɵɵgetCurrentView();
1035
+ i0.ɵɵelementStart(0, "tr", 237);
1036
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_30_Template_tr_click_0_listener() { const test_r34 = i0.ɵɵrestoreView(_r33).$implicit; const ctx_r0 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r0.selectMatrixRow(test_r34.testId)); });
1037
+ i0.ɵɵelementStart(1, "td", 238);
1011
1038
  i0.ɵɵtext(2);
1012
1039
  i0.ɵɵelementEnd();
1013
- i0.ɵɵelementStart(3, "td", 237)(4, "span", 238);
1040
+ i0.ɵɵelementStart(3, "td", 239)(4, "span", 240);
1014
1041
  i0.ɵɵtext(5);
1015
1042
  i0.ɵɵelementEnd()();
1016
- i0.ɵɵrepeaterCreate(6, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_30_For_7_Template, 3, 8, "td", 239, i0.ɵɵrepeaterTrackByIdentity);
1017
- i0.ɵɵelement(8, "td", 226);
1043
+ i0.ɵɵrepeaterCreate(6, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_30_For_7_Template, 3, 8, "td", 241, i0.ɵɵrepeaterTrackByIdentity);
1044
+ i0.ɵɵelement(8, "td", 228);
1018
1045
  i0.ɵɵelementEnd();
1019
1046
  } if (rf & 2) {
1020
- const test_r33 = ctx.$implicit;
1047
+ const test_r34 = ctx.$implicit;
1021
1048
  const ctx_r0 = i0.ɵɵnextContext(5);
1022
- i0.ɵɵclassProp("row-selected", ctx_r0.selectedMatrixTestId === test_r33.testId);
1049
+ i0.ɵɵclassProp("row-selected", ctx_r0.selectedMatrixTestId === test_r34.testId);
1023
1050
  i0.ɵɵadvance(2);
1024
- i0.ɵɵtextInterpolate(test_r33.sequence);
1051
+ i0.ɵɵtextInterpolate(test_r34.sequence);
1025
1052
  i0.ɵɵadvance(2);
1026
- i0.ɵɵproperty("title", test_r33.testName);
1053
+ i0.ɵɵproperty("title", test_r34.testName);
1027
1054
  i0.ɵɵadvance();
1028
- i0.ɵɵtextInterpolate(test_r33.testName);
1055
+ i0.ɵɵtextInterpolate(test_r34.testName);
1029
1056
  i0.ɵɵadvance();
1030
1057
  i0.ɵɵrepeater(ctx_r0.matrixData);
1031
1058
  } }
1032
1059
  function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_38_Conditional_2_Template(rf, ctx) { if (rf & 1) {
1033
- i0.ɵɵelementStart(0, "span", 256)(1, "span", 259);
1060
+ i0.ɵɵelementStart(0, "span", 258)(1, "span", 261);
1034
1061
  i0.ɵɵtext(2);
1035
1062
  i0.ɵɵelementEnd()();
1036
1063
  } if (rf & 2) {
1037
- const run_r37 = i0.ɵɵnextContext().$implicit;
1064
+ const run_r38 = i0.ɵɵnextContext().$implicit;
1038
1065
  const ctx_r0 = i0.ɵɵnextContext(5);
1039
1066
  i0.ɵɵadvance(2);
1040
- i0.ɵɵtextInterpolate2("", ctx_r0.getRunPassedCount(run_r37), "/", ctx_r0.getRunTotalCount(run_r37));
1067
+ i0.ɵɵtextInterpolate2("", ctx_r0.getRunPassedCount(run_r38), "/", ctx_r0.getRunTotalCount(run_r38));
1041
1068
  } }
1042
1069
  function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_38_Conditional_3_Conditional_1_Template(rf, ctx) { if (rf & 1) {
1043
- i0.ɵɵelementStart(0, "span", 260);
1070
+ i0.ɵɵelementStart(0, "span", 262);
1044
1071
  i0.ɵɵtext(1);
1045
1072
  i0.ɵɵelementEnd();
1046
1073
  } if (rf & 2) {
1047
1074
  let tmp_16_0;
1048
- const run_r37 = i0.ɵɵnextContext(2).$implicit;
1075
+ const run_r38 = i0.ɵɵnextContext(2).$implicit;
1049
1076
  const ctx_r0 = i0.ɵɵnextContext(5);
1050
1077
  i0.ɵɵadvance();
1051
- i0.ɵɵtextInterpolate((tmp_16_0 = ctx_r0.getRunHumanAvg(run_r37)) == null ? null : tmp_16_0.toFixed(1));
1078
+ i0.ɵɵtextInterpolate((tmp_16_0 = ctx_r0.getRunHumanAvg(run_r38)) == null ? null : tmp_16_0.toFixed(1));
1052
1079
  } }
1053
1080
  function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_38_Conditional_3_Template(rf, ctx) { if (rf & 1) {
1054
- i0.ɵɵelementStart(0, "span", 257);
1055
- i0.ɵɵconditionalCreate(1, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_38_Conditional_3_Conditional_1_Template, 2, 1, "span", 260);
1056
- i0.ɵɵelementStart(2, "span", 261);
1081
+ i0.ɵɵelementStart(0, "span", 259);
1082
+ i0.ɵɵconditionalCreate(1, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_38_Conditional_3_Conditional_1_Template, 2, 1, "span", 262);
1083
+ i0.ɵɵelementStart(2, "span", 263);
1057
1084
  i0.ɵɵtext(3);
1058
1085
  i0.ɵɵelementEnd()();
1059
1086
  } if (rf & 2) {
1060
- const run_r37 = i0.ɵɵnextContext().$implicit;
1087
+ const run_r38 = i0.ɵɵnextContext().$implicit;
1061
1088
  const ctx_r0 = i0.ɵɵnextContext(5);
1062
1089
  i0.ɵɵadvance();
1063
- i0.ɵɵconditional(ctx_r0.getRunHumanAvg(run_r37) != null ? 1 : -1);
1090
+ i0.ɵɵconditional(ctx_r0.getRunHumanAvg(run_r38) != null ? 1 : -1);
1064
1091
  i0.ɵɵadvance(2);
1065
- i0.ɵɵtextInterpolate1("(", ctx_r0.getRunHumanCount(run_r37), ")");
1092
+ i0.ɵɵtextInterpolate1("(", ctx_r0.getRunHumanCount(run_r38), ")");
1066
1093
  } }
1067
1094
  function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_38_Conditional_4_Conditional_1_Template(rf, ctx) { if (rf & 1) {
1068
- i0.ɵɵelementStart(0, "span", 260);
1095
+ i0.ɵɵelementStart(0, "span", 262);
1069
1096
  i0.ɵɵtext(1);
1070
1097
  i0.ɵɵelementEnd();
1071
1098
  } if (rf & 2) {
1072
- const run_r37 = i0.ɵɵnextContext(2).$implicit;
1099
+ const run_r38 = i0.ɵɵnextContext(2).$implicit;
1073
1100
  const ctx_r0 = i0.ɵɵnextContext(5);
1074
1101
  i0.ɵɵadvance();
1075
- i0.ɵɵtextInterpolate1("", (ctx_r0.getRunAutoAvg(run_r37) * 100).toFixed(0), "%");
1102
+ i0.ɵɵtextInterpolate1("", (ctx_r0.getRunAutoAvg(run_r38) * 100).toFixed(0), "%");
1076
1103
  } }
1077
1104
  function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_38_Conditional_4_Template(rf, ctx) { if (rf & 1) {
1078
- i0.ɵɵelementStart(0, "span", 258);
1079
- i0.ɵɵconditionalCreate(1, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_38_Conditional_4_Conditional_1_Template, 2, 1, "span", 260);
1080
- i0.ɵɵelementStart(2, "span", 261);
1105
+ i0.ɵɵelementStart(0, "span", 260);
1106
+ i0.ɵɵconditionalCreate(1, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_38_Conditional_4_Conditional_1_Template, 2, 1, "span", 262);
1107
+ i0.ɵɵelementStart(2, "span", 263);
1081
1108
  i0.ɵɵtext(3);
1082
1109
  i0.ɵɵelementEnd()();
1083
1110
  } if (rf & 2) {
1084
- const run_r37 = i0.ɵɵnextContext().$implicit;
1111
+ const run_r38 = i0.ɵɵnextContext().$implicit;
1085
1112
  const ctx_r0 = i0.ɵɵnextContext(5);
1086
1113
  i0.ɵɵadvance();
1087
- i0.ɵɵconditional(ctx_r0.getRunAutoAvg(run_r37) != null ? 1 : -1);
1114
+ i0.ɵɵconditional(ctx_r0.getRunAutoAvg(run_r38) != null ? 1 : -1);
1088
1115
  i0.ɵɵadvance(2);
1089
- i0.ɵɵtextInterpolate1("(", ctx_r0.getRunAutoCount(run_r37), ")");
1116
+ i0.ɵɵtextInterpolate1("(", ctx_r0.getRunAutoCount(run_r38), ")");
1090
1117
  } }
1091
1118
  function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_38_Template(rf, ctx) { if (rf & 1) {
1092
- i0.ɵɵelementStart(0, "td", 225)(1, "div", 255);
1093
- i0.ɵɵconditionalCreate(2, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_38_Conditional_2_Template, 3, 2, "span", 256);
1094
- i0.ɵɵconditionalCreate(3, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_38_Conditional_3_Template, 4, 2, "span", 257);
1095
- i0.ɵɵconditionalCreate(4, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_38_Conditional_4_Template, 4, 2, "span", 258);
1119
+ i0.ɵɵelementStart(0, "td", 227)(1, "div", 257);
1120
+ i0.ɵɵconditionalCreate(2, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_38_Conditional_2_Template, 3, 2, "span", 258);
1121
+ i0.ɵɵconditionalCreate(3, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_38_Conditional_3_Template, 4, 2, "span", 259);
1122
+ i0.ɵɵconditionalCreate(4, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_38_Conditional_4_Template, 4, 2, "span", 260);
1096
1123
  i0.ɵɵelementEnd()();
1097
1124
  } if (rf & 2) {
1098
1125
  const ctx_r0 = i0.ɵɵnextContext(5);
@@ -1104,49 +1131,49 @@ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Condition
1104
1131
  i0.ɵɵconditional(ctx_r0.evalPreferences.showAuto ? 4 : -1);
1105
1132
  } }
1106
1133
  function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_Template(rf, ctx) { if (rf & 1) {
1107
- const _r27 = i0.ɵɵgetCurrentView();
1108
- i0.ɵɵelementStart(0, "div", 203)(1, "div", 206)(2, "h3");
1109
- i0.ɵɵelement(3, "i", 161);
1134
+ const _r28 = i0.ɵɵgetCurrentView();
1135
+ i0.ɵɵelementStart(0, "div", 205)(1, "div", 208)(2, "h3");
1136
+ i0.ɵɵelement(3, "i", 163);
1110
1137
  i0.ɵɵtext(4, " Test Results Matrix");
1111
1138
  i0.ɵɵelementEnd();
1112
- i0.ɵɵelementStart(5, "div", 207)(6, "div", 208);
1113
- i0.ɵɵelement(7, "i", 209);
1114
- i0.ɵɵelementStart(8, "input", 210);
1115
- i0.ɵɵlistener("input", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_Template_input_input_8_listener($event) { i0.ɵɵrestoreView(_r27); const ctx_r0 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r0.onMatrixFilterInput($event)); });
1139
+ i0.ɵɵelementStart(5, "div", 209)(6, "div", 210);
1140
+ i0.ɵɵelement(7, "i", 211);
1141
+ i0.ɵɵelementStart(8, "input", 212);
1142
+ i0.ɵɵlistener("input", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_Template_input_input_8_listener($event) { i0.ɵɵrestoreView(_r28); const ctx_r0 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r0.onMatrixFilterInput($event)); });
1116
1143
  i0.ɵɵelementEnd();
1117
- i0.ɵɵconditionalCreate(9, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_Conditional_9_Template, 2, 0, "button", 211);
1144
+ i0.ɵɵconditionalCreate(9, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_Conditional_9_Template, 2, 0, "button", 213);
1118
1145
  i0.ɵɵelementEnd();
1119
- i0.ɵɵelementStart(10, "span", 212);
1146
+ i0.ɵɵelementStart(10, "span", 214);
1120
1147
  i0.ɵɵtext(11);
1121
1148
  i0.ɵɵelementEnd();
1122
- i0.ɵɵelementStart(12, "button", 213);
1123
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_Template_button_click_12_listener() { i0.ɵɵrestoreView(_r27); const ctx_r0 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r0.exportMatrixToCSV()); });
1124
- i0.ɵɵelement(13, "i", 214);
1149
+ i0.ɵɵelementStart(12, "button", 215);
1150
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_Template_button_click_12_listener() { i0.ɵɵrestoreView(_r28); const ctx_r0 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r0.exportMatrixToCSV()); });
1151
+ i0.ɵɵelement(13, "i", 216);
1125
1152
  i0.ɵɵtext(14, " Export ");
1126
1153
  i0.ɵɵelementEnd()()();
1127
- i0.ɵɵelementStart(15, "div", 215)(16, "table", 216)(17, "thead")(18, "tr")(19, "th", 217);
1128
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_Template_th_click_19_listener() { i0.ɵɵrestoreView(_r27); const ctx_r0 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r0.toggleMatrixSort("sequence")); });
1154
+ i0.ɵɵelementStart(15, "div", 217)(16, "table", 218)(17, "thead")(18, "tr")(19, "th", 219);
1155
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_Template_th_click_19_listener() { i0.ɵɵrestoreView(_r28); const ctx_r0 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r0.toggleMatrixSort("sequence")); });
1129
1156
  i0.ɵɵtext(20, " # ");
1130
1157
  i0.ɵɵelement(21, "i", 19);
1131
1158
  i0.ɵɵelementEnd();
1132
- i0.ɵɵelementStart(22, "th", 218);
1133
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_Template_th_click_22_listener() { i0.ɵɵrestoreView(_r27); const ctx_r0 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r0.toggleMatrixSort("name")); });
1159
+ i0.ɵɵelementStart(22, "th", 220);
1160
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_Template_th_click_22_listener() { i0.ɵɵrestoreView(_r28); const ctx_r0 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r0.toggleMatrixSort("name")); });
1134
1161
  i0.ɵɵtext(23, " Test ");
1135
1162
  i0.ɵɵelement(24, "i", 19);
1136
1163
  i0.ɵɵelementEnd();
1137
- i0.ɵɵrepeaterCreate(25, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_26_Template, 8, 12, "th", 219, i0.ɵɵrepeaterTrackByIdentity);
1138
- i0.ɵɵelement(27, "th", 220);
1164
+ i0.ɵɵrepeaterCreate(25, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_26_Template, 8, 12, "th", 221, i0.ɵɵrepeaterTrackByIdentity);
1165
+ i0.ɵɵelement(27, "th", 222);
1139
1166
  i0.ɵɵelementEnd()();
1140
1167
  i0.ɵɵelementStart(28, "tbody");
1141
- i0.ɵɵrepeaterCreate(29, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_30_Template, 9, 5, "tr", 221, i0.ɵɵrepeaterTrackByIdentity);
1168
+ i0.ɵɵrepeaterCreate(29, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_30_Template, 9, 5, "tr", 223, i0.ɵɵrepeaterTrackByIdentity);
1142
1169
  i0.ɵɵelementEnd();
1143
- i0.ɵɵelementStart(31, "tfoot")(32, "tr", 222);
1144
- i0.ɵɵelement(33, "td", 223);
1145
- i0.ɵɵelementStart(34, "td", 224)(35, "strong");
1170
+ i0.ɵɵelementStart(31, "tfoot")(32, "tr", 224);
1171
+ i0.ɵɵelement(33, "td", 225);
1172
+ i0.ɵɵelementStart(34, "td", 226)(35, "strong");
1146
1173
  i0.ɵɵtext(36, "Totals");
1147
1174
  i0.ɵɵelementEnd()();
1148
- i0.ɵɵrepeaterCreate(37, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_38_Template, 5, 3, "td", 225, i0.ɵɵrepeaterTrackByIdentity);
1149
- i0.ɵɵelement(39, "td", 226);
1175
+ i0.ɵɵrepeaterCreate(37, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_For_38_Template, 5, 3, "td", 227, i0.ɵɵrepeaterTrackByIdentity);
1176
+ i0.ɵɵelement(39, "td", 228);
1150
1177
  i0.ɵɵelementEnd()()()()();
1151
1178
  } if (rf & 2) {
1152
1179
  const ctx_r0 = i0.ɵɵnextContext(4);
@@ -1170,12 +1197,12 @@ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Condition
1170
1197
  i0.ɵɵrepeater(ctx_r0.matrixData);
1171
1198
  } }
1172
1199
  function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_2_Template(rf, ctx) { if (rf & 1) {
1173
- i0.ɵɵelement(0, "mj-empty-state", 204);
1200
+ i0.ɵɵelement(0, "mj-empty-state", 206);
1174
1201
  } }
1175
1202
  function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Template(rf, ctx) { if (rf & 1) {
1176
- i0.ɵɵconditionalCreate(0, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_0_Template, 2, 0, "div", 99);
1177
- i0.ɵɵconditionalCreate(1, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_Template, 40, 7, "div", 203);
1178
- i0.ɵɵconditionalCreate(2, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_2_Template, 1, 0, "mj-empty-state", 204);
1203
+ i0.ɵɵconditionalCreate(0, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_0_Template, 2, 0, "div", 101);
1204
+ i0.ɵɵconditionalCreate(1, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_1_Template, 40, 7, "div", 205);
1205
+ i0.ɵɵconditionalCreate(2, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Conditional_2_Template, 1, 0, "mj-empty-state", 206);
1179
1206
  } if (rf & 2) {
1180
1207
  const ctx_r0 = i0.ɵɵnextContext(3);
1181
1208
  i0.ɵɵconditional(ctx_r0.loadingMatrix ? 0 : -1);
@@ -1185,36 +1212,36 @@ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Condition
1185
1212
  i0.ɵɵconditional(!ctx_r0.loadingMatrix && ctx_r0.matrixLoaded && ctx_r0.matrixData.length === 0 ? 2 : -1);
1186
1213
  } }
1187
1214
  function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_19_Conditional_0_Template(rf, ctx) { if (rf & 1) {
1188
- i0.ɵɵelementStart(0, "div", 99);
1189
- i0.ɵɵelement(1, "mj-loading", 264);
1215
+ i0.ɵɵelementStart(0, "div", 101);
1216
+ i0.ɵɵelement(1, "mj-loading", 266);
1190
1217
  i0.ɵɵelementEnd();
1191
1218
  } }
1192
1219
  function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_19_Conditional_1_Template(rf, ctx) { if (rf & 1) {
1193
- i0.ɵɵelementStart(0, "div", 262)(1, "div", 265)(2, "h3");
1194
- i0.ɵɵelement(3, "i", 162);
1220
+ i0.ɵɵelementStart(0, "div", 264)(1, "div", 267)(2, "h3");
1221
+ i0.ɵɵelement(3, "i", 164);
1195
1222
  i0.ɵɵtext(4, " Test Results Flow");
1196
1223
  i0.ɵɵelementEnd();
1197
- i0.ɵɵelementStart(5, "div", 266)(6, "span", 267);
1198
- i0.ɵɵelement(7, "i", 177);
1224
+ i0.ɵɵelementStart(5, "div", 268)(6, "span", 269);
1225
+ i0.ɵɵelement(7, "i", 179);
1199
1226
  i0.ɵɵtext(8, " Passed");
1200
1227
  i0.ɵɵelementEnd();
1201
- i0.ɵɵelementStart(9, "span", 268);
1202
- i0.ɵɵelement(10, "i", 91);
1228
+ i0.ɵɵelementStart(9, "span", 270);
1229
+ i0.ɵɵelement(10, "i", 93);
1203
1230
  i0.ɵɵtext(11, " Failed");
1204
1231
  i0.ɵɵelementEnd();
1205
- i0.ɵɵelementStart(12, "span", 269);
1206
- i0.ɵɵelement(13, "i", 270);
1232
+ i0.ɵɵelementStart(12, "span", 271);
1233
+ i0.ɵɵelement(13, "i", 272);
1207
1234
  i0.ɵɵtext(14, " Error");
1208
1235
  i0.ɵɵelementEnd();
1209
- i0.ɵɵelementStart(15, "span", 271);
1210
- i0.ɵɵelement(16, "i", 272);
1236
+ i0.ɵɵelementStart(15, "span", 273);
1237
+ i0.ɵɵelement(16, "i", 274);
1211
1238
  i0.ɵɵtext(17, " Skipped");
1212
1239
  i0.ɵɵelementEnd()()();
1213
- i0.ɵɵelementStart(18, "div", 273);
1214
- i0.ɵɵelement(19, "div", 274, 1);
1240
+ i0.ɵɵelementStart(18, "div", 275);
1241
+ i0.ɵɵelement(19, "div", 276, 1);
1215
1242
  i0.ɵɵelementEnd();
1216
- i0.ɵɵelementStart(21, "div", 275);
1217
- i0.ɵɵelement(22, "i", 119);
1243
+ i0.ɵɵelementStart(21, "div", 277);
1244
+ i0.ɵɵelement(22, "i", 121);
1218
1245
  i0.ɵɵtext(23);
1219
1246
  i0.ɵɵelementEnd()();
1220
1247
  } if (rf & 2) {
@@ -1223,12 +1250,12 @@ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Condition
1223
1250
  i0.ɵɵtextInterpolate1(" Interactive visualization showing test results across ", ctx_r0.matrixData.length, " runs. Hover over elements for details, click nodes to navigate. ");
1224
1251
  } }
1225
1252
  function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_19_Conditional_2_Template(rf, ctx) { if (rf & 1) {
1226
- i0.ɵɵelement(0, "mj-empty-state", 263);
1253
+ i0.ɵɵelement(0, "mj-empty-state", 265);
1227
1254
  } }
1228
1255
  function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_19_Template(rf, ctx) { if (rf & 1) {
1229
- i0.ɵɵconditionalCreate(0, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_19_Conditional_0_Template, 2, 0, "div", 99);
1230
- i0.ɵɵconditionalCreate(1, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_19_Conditional_1_Template, 24, 1, "div", 262);
1231
- i0.ɵɵconditionalCreate(2, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_19_Conditional_2_Template, 1, 0, "mj-empty-state", 263);
1256
+ i0.ɵɵconditionalCreate(0, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_19_Conditional_0_Template, 2, 0, "div", 101);
1257
+ i0.ɵɵconditionalCreate(1, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_19_Conditional_1_Template, 24, 1, "div", 264);
1258
+ i0.ɵɵconditionalCreate(2, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_19_Conditional_2_Template, 1, 0, "mj-empty-state", 265);
1232
1259
  } if (rf & 2) {
1233
1260
  const ctx_r0 = i0.ɵɵnextContext(3);
1234
1261
  i0.ɵɵconditional(ctx_r0.loadingMatrix ? 0 : -1);
@@ -1238,28 +1265,28 @@ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Condition
1238
1265
  i0.ɵɵconditional(!ctx_r0.loadingMatrix && ctx_r0.matrixLoaded && ctx_r0.matrixData.length === 0 ? 2 : -1);
1239
1266
  } }
1240
1267
  function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Template(rf, ctx) { if (rf & 1) {
1241
- const _r19 = i0.ɵɵgetCurrentView();
1242
- i0.ɵɵelementStart(0, "div", 157)(1, "div", 158)(2, "button", 159);
1243
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Template_button_click_2_listener() { i0.ɵɵrestoreView(_r19); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.setAnalyticsView("summary")); });
1244
- i0.ɵɵelement(3, "i", 160);
1268
+ const _r20 = i0.ɵɵgetCurrentView();
1269
+ i0.ɵɵelementStart(0, "div", 159)(1, "div", 160)(2, "button", 161);
1270
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Template_button_click_2_listener() { i0.ɵɵrestoreView(_r20); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.setAnalyticsView("summary")); });
1271
+ i0.ɵɵelement(3, "i", 162);
1245
1272
  i0.ɵɵelementStart(4, "span");
1246
1273
  i0.ɵɵtext(5, "Summary");
1247
1274
  i0.ɵɵelementEnd()();
1248
- i0.ɵɵelementStart(6, "button", 159);
1249
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r19); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.setAnalyticsView("matrix")); });
1250
- i0.ɵɵelement(7, "i", 161);
1275
+ i0.ɵɵelementStart(6, "button", 161);
1276
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r20); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.setAnalyticsView("matrix")); });
1277
+ i0.ɵɵelement(7, "i", 163);
1251
1278
  i0.ɵɵelementStart(8, "span");
1252
1279
  i0.ɵɵtext(9, "Matrix");
1253
1280
  i0.ɵɵelementEnd()();
1254
- i0.ɵɵelementStart(10, "button", 159);
1255
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Template_button_click_10_listener() { i0.ɵɵrestoreView(_r19); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.setAnalyticsView("chart")); });
1256
- i0.ɵɵelement(11, "i", 162);
1281
+ i0.ɵɵelementStart(10, "button", 161);
1282
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Template_button_click_10_listener() { i0.ɵɵrestoreView(_r20); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.setAnalyticsView("chart")); });
1283
+ i0.ɵɵelement(11, "i", 164);
1257
1284
  i0.ɵɵelementStart(12, "span");
1258
1285
  i0.ɵɵtext(13, "Chart");
1259
1286
  i0.ɵɵelementEnd()()()();
1260
- i0.ɵɵelementStart(14, "mj-accordion-panel", 163);
1261
- i0.ɵɵlistener("ExpandedChange", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Template_mj_accordion_panel_ExpandedChange_14_listener($event) { i0.ɵɵrestoreView(_r19); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.onFiltersExpandedChange($event)); });
1262
- i0.ɵɵtemplate(15, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_template_15_Template, 3, 1, "ng-template", 164)(16, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_template_16_Template, 14, 9, "ng-template", 165);
1287
+ i0.ɵɵelementStart(14, "mj-accordion-panel", 165);
1288
+ i0.ɵɵlistener("ExpandedChange", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Template_mj_accordion_panel_ExpandedChange_14_listener($event) { i0.ɵɵrestoreView(_r20); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.onFiltersExpandedChange($event)); });
1289
+ i0.ɵɵtemplate(15, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_template_15_Template, 3, 1, "ng-template", 166)(16, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_ng_template_16_Template, 14, 9, "ng-template", 167);
1263
1290
  i0.ɵɵelementEnd();
1264
1291
  i0.ɵɵconditionalCreate(17, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_17_Template, 62, 15);
1265
1292
  i0.ɵɵconditionalCreate(18, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_18_Template, 3, 3);
@@ -1282,16 +1309,16 @@ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Template(
1282
1309
  i0.ɵɵconditional(ctx_r0.analyticsView === "chart" ? 19 : -1);
1283
1310
  } }
1284
1311
  function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_3_Template(rf, ctx) { if (rf & 1) {
1285
- const _r38 = i0.ɵɵgetCurrentView();
1286
- i0.ɵɵelementStart(0, "mj-empty-state", 276);
1287
- i0.ɵɵlistener("Action", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_3_Template_mj_empty_state_Action_0_listener() { i0.ɵɵrestoreView(_r38); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.runSuite()); });
1312
+ const _r39 = i0.ɵɵgetCurrentView();
1313
+ i0.ɵɵelementStart(0, "mj-empty-state", 278);
1314
+ i0.ɵɵlistener("Action", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_3_Template_mj_empty_state_Action_0_listener() { i0.ɵɵrestoreView(_r39); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.runSuite()); });
1288
1315
  i0.ɵɵelementEnd();
1289
1316
  } }
1290
1317
  function MJTestSuiteFormComponentExtended_Conditional_63_Template(rf, ctx) { if (rf & 1) {
1291
1318
  i0.ɵɵelementStart(0, "div", 42);
1292
- i0.ɵɵconditionalCreate(1, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_1_Template, 2, 0, "div", 99);
1319
+ i0.ɵɵconditionalCreate(1, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_1_Template, 2, 0, "div", 101);
1293
1320
  i0.ɵɵconditionalCreate(2, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Template, 20, 11);
1294
- i0.ɵɵconditionalCreate(3, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_3_Template, 1, 0, "mj-empty-state", 155);
1321
+ i0.ɵɵconditionalCreate(3, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_3_Template, 1, 0, "mj-empty-state", 157);
1295
1322
  i0.ɵɵelementEnd();
1296
1323
  } if (rf & 2) {
1297
1324
  const ctx_r0 = i0.ɵɵnextContext();
@@ -1303,54 +1330,54 @@ function MJTestSuiteFormComponentExtended_Conditional_63_Template(rf, ctx) { if
1303
1330
  i0.ɵɵconditional(!ctx_r0.loadingAnalytics && ctx_r0.analyticsLoaded && ctx_r0.analyticsData.length === 0 ? 3 : -1);
1304
1331
  } }
1305
1332
  function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_5_For_2_Conditional_8_For_2_Template(rf, ctx) { if (rf & 1) {
1306
- i0.ɵɵelementStart(0, "span", 293);
1333
+ i0.ɵɵelementStart(0, "span", 295);
1307
1334
  i0.ɵɵtext(1);
1308
1335
  i0.ɵɵelementEnd();
1309
1336
  } if (rf & 2) {
1310
- const tag_r41 = ctx.$implicit;
1337
+ const tag_r42 = ctx.$implicit;
1311
1338
  i0.ɵɵadvance();
1312
- i0.ɵɵtextInterpolate(tag_r41);
1339
+ i0.ɵɵtextInterpolate(tag_r42);
1313
1340
  } }
1314
1341
  function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_5_For_2_Conditional_8_Template(rf, ctx) { if (rf & 1) {
1315
- i0.ɵɵelementStart(0, "div", 292);
1316
- i0.ɵɵrepeaterCreate(1, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_5_For_2_Conditional_8_For_2_Template, 2, 1, "span", 293, i0.ɵɵrepeaterTrackByIdentity);
1342
+ i0.ɵɵelementStart(0, "div", 294);
1343
+ i0.ɵɵrepeaterCreate(1, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_5_For_2_Conditional_8_For_2_Template, 2, 1, "span", 295, i0.ɵɵrepeaterTrackByIdentity);
1317
1344
  i0.ɵɵelementEnd();
1318
1345
  } if (rf & 2) {
1319
- const run_r40 = i0.ɵɵnextContext().$implicit;
1346
+ const run_r41 = i0.ɵɵnextContext().$implicit;
1320
1347
  const ctx_r0 = i0.ɵɵnextContext(3);
1321
1348
  i0.ɵɵadvance();
1322
- i0.ɵɵrepeater(ctx_r0.getRunTags(run_r40).slice(0, 2));
1349
+ i0.ɵɵrepeater(ctx_r0.getRunTags(run_r41).slice(0, 2));
1323
1350
  } }
1324
1351
  function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_5_For_2_Template(rf, ctx) { if (rf & 1) {
1325
- const _r39 = i0.ɵɵgetCurrentView();
1326
- i0.ɵɵelementStart(0, "div", 287);
1327
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_5_For_2_Template_div_click_0_listener() { const run_r40 = i0.ɵɵrestoreView(_r39).$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.selectCompareRunA(run_r40)); });
1328
- i0.ɵɵelement(1, "div", 288);
1329
- i0.ɵɵelementStart(2, "div", 289)(3, "div", 290);
1352
+ const _r40 = i0.ɵɵgetCurrentView();
1353
+ i0.ɵɵelementStart(0, "div", 289);
1354
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_5_For_2_Template_div_click_0_listener() { const run_r41 = i0.ɵɵrestoreView(_r40).$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.selectCompareRunA(run_r41)); });
1355
+ i0.ɵɵelement(1, "div", 290);
1356
+ i0.ɵɵelementStart(2, "div", 291)(3, "div", 292);
1330
1357
  i0.ɵɵtext(4);
1331
1358
  i0.ɵɵpipe(5, "date");
1332
1359
  i0.ɵɵelementEnd();
1333
- i0.ɵɵelementStart(6, "div", 291);
1360
+ i0.ɵɵelementStart(6, "div", 293);
1334
1361
  i0.ɵɵtext(7);
1335
1362
  i0.ɵɵelementEnd()();
1336
- i0.ɵɵconditionalCreate(8, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_5_For_2_Conditional_8_Template, 3, 0, "div", 292);
1363
+ i0.ɵɵconditionalCreate(8, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_5_For_2_Conditional_8_Template, 3, 0, "div", 294);
1337
1364
  i0.ɵɵelementEnd();
1338
1365
  } if (rf & 2) {
1339
- const run_r40 = ctx.$implicit;
1366
+ const run_r41 = ctx.$implicit;
1340
1367
  const ctx_r0 = i0.ɵɵnextContext(3);
1341
- i0.ɵɵclassProp("selected", ctx_r0.IsCompareRunA(run_r40));
1368
+ i0.ɵɵclassProp("selected", ctx_r0.IsCompareRunA(run_r41));
1342
1369
  i0.ɵɵadvance();
1343
- i0.ɵɵstyleProp("background-color", ctx_r0.getRunStatusColor(run_r40.Status));
1370
+ i0.ɵɵstyleProp("background-color", ctx_r0.getRunStatusColor(run_r41.Status));
1344
1371
  i0.ɵɵadvance(3);
1345
- i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(5, 7, run_r40.StartedAt, "short"));
1372
+ i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(5, 7, run_r41.StartedAt, "short"));
1346
1373
  i0.ɵɵadvance(3);
1347
- i0.ɵɵtextInterpolate1("", ctx_r0.getPassRate(run_r40).toFixed(0), "% pass");
1374
+ i0.ɵɵtextInterpolate1("", ctx_r0.getPassRate(run_r41).toFixed(0), "% pass");
1348
1375
  i0.ɵɵadvance();
1349
- i0.ɵɵconditional(ctx_r0.getRunTags(run_r40).length > 0 ? 8 : -1);
1376
+ i0.ɵɵconditional(ctx_r0.getRunTags(run_r41).length > 0 ? 8 : -1);
1350
1377
  } }
1351
1378
  function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_5_Template(rf, ctx) { if (rf & 1) {
1352
- i0.ɵɵelementStart(0, "div", 279);
1353
- i0.ɵɵrepeaterCreate(1, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_5_For_2_Template, 9, 10, "div", 286, i0.ɵɵrepeaterTrackByIdentity);
1379
+ i0.ɵɵelementStart(0, "div", 281);
1380
+ i0.ɵɵrepeaterCreate(1, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_5_For_2_Template, 9, 10, "div", 288, i0.ɵɵrepeaterTrackByIdentity);
1354
1381
  i0.ɵɵelementEnd();
1355
1382
  } if (rf & 2) {
1356
1383
  const ctx_r0 = i0.ɵɵnextContext(2);
@@ -1358,19 +1385,19 @@ function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_5_Template(
1358
1385
  i0.ɵɵrepeater(ctx_r0.suiteRuns);
1359
1386
  } }
1360
1387
  function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_6_Template(rf, ctx) { if (rf & 1) {
1361
- const _r42 = i0.ɵɵgetCurrentView();
1362
- i0.ɵɵelementStart(0, "div", 280)(1, "div", 294)(2, "span", 295);
1388
+ const _r43 = i0.ɵɵgetCurrentView();
1389
+ i0.ɵɵelementStart(0, "div", 282)(1, "div", 296)(2, "span", 297);
1363
1390
  i0.ɵɵtext(3, "Selected:");
1364
1391
  i0.ɵɵelementEnd();
1365
- i0.ɵɵelementStart(4, "button", 296);
1366
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_6_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r42); const ctx_r0 = i0.ɵɵnextContext(2); ctx_r0.compareRunA = null; return i0.ɵɵresetView(ctx_r0.compareResults = []); });
1392
+ i0.ɵɵelementStart(4, "button", 298);
1393
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_6_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r43); const ctx_r0 = i0.ɵɵnextContext(2); ctx_r0.compareRunA = null; return i0.ɵɵresetView(ctx_r0.compareResults = []); });
1367
1394
  i0.ɵɵtext(5, "Clear");
1368
1395
  i0.ɵɵelementEnd()();
1369
- i0.ɵɵelementStart(6, "div", 297)(7, "span");
1396
+ i0.ɵɵelementStart(6, "div", 299)(7, "span");
1370
1397
  i0.ɵɵtext(8);
1371
1398
  i0.ɵɵpipe(9, "date");
1372
1399
  i0.ɵɵelementEnd();
1373
- i0.ɵɵelementStart(10, "span", 298);
1400
+ i0.ɵɵelementStart(10, "span", 300);
1374
1401
  i0.ɵɵtext(11);
1375
1402
  i0.ɵɵelementEnd()()();
1376
1403
  } if (rf & 2) {
@@ -1381,54 +1408,54 @@ function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_6_Template(
1381
1408
  i0.ɵɵtextInterpolate1("", ctx_r0.getPassRate(ctx_r0.compareRunA).toFixed(1), "%");
1382
1409
  } }
1383
1410
  function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_12_For_2_Conditional_8_For_2_Template(rf, ctx) { if (rf & 1) {
1384
- i0.ɵɵelementStart(0, "span", 293);
1411
+ i0.ɵɵelementStart(0, "span", 295);
1385
1412
  i0.ɵɵtext(1);
1386
1413
  i0.ɵɵelementEnd();
1387
1414
  } if (rf & 2) {
1388
- const tag_r45 = ctx.$implicit;
1415
+ const tag_r46 = ctx.$implicit;
1389
1416
  i0.ɵɵadvance();
1390
- i0.ɵɵtextInterpolate(tag_r45);
1417
+ i0.ɵɵtextInterpolate(tag_r46);
1391
1418
  } }
1392
1419
  function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_12_For_2_Conditional_8_Template(rf, ctx) { if (rf & 1) {
1393
- i0.ɵɵelementStart(0, "div", 292);
1394
- i0.ɵɵrepeaterCreate(1, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_12_For_2_Conditional_8_For_2_Template, 2, 1, "span", 293, i0.ɵɵrepeaterTrackByIdentity);
1420
+ i0.ɵɵelementStart(0, "div", 294);
1421
+ i0.ɵɵrepeaterCreate(1, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_12_For_2_Conditional_8_For_2_Template, 2, 1, "span", 295, i0.ɵɵrepeaterTrackByIdentity);
1395
1422
  i0.ɵɵelementEnd();
1396
1423
  } if (rf & 2) {
1397
- const run_r44 = i0.ɵɵnextContext().$implicit;
1424
+ const run_r45 = i0.ɵɵnextContext().$implicit;
1398
1425
  const ctx_r0 = i0.ɵɵnextContext(3);
1399
1426
  i0.ɵɵadvance();
1400
- i0.ɵɵrepeater(ctx_r0.getRunTags(run_r44).slice(0, 2));
1427
+ i0.ɵɵrepeater(ctx_r0.getRunTags(run_r45).slice(0, 2));
1401
1428
  } }
1402
1429
  function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_12_For_2_Template(rf, ctx) { if (rf & 1) {
1403
- const _r43 = i0.ɵɵgetCurrentView();
1404
- i0.ɵɵelementStart(0, "div", 287);
1405
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_12_For_2_Template_div_click_0_listener() { const run_r44 = i0.ɵɵrestoreView(_r43).$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(!ctx_r0.IsCompareRunA(run_r44) && ctx_r0.selectCompareRunB(run_r44)); });
1406
- i0.ɵɵelement(1, "div", 288);
1407
- i0.ɵɵelementStart(2, "div", 289)(3, "div", 290);
1430
+ const _r44 = i0.ɵɵgetCurrentView();
1431
+ i0.ɵɵelementStart(0, "div", 289);
1432
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_12_For_2_Template_div_click_0_listener() { const run_r45 = i0.ɵɵrestoreView(_r44).$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(!ctx_r0.IsCompareRunA(run_r45) && ctx_r0.selectCompareRunB(run_r45)); });
1433
+ i0.ɵɵelement(1, "div", 290);
1434
+ i0.ɵɵelementStart(2, "div", 291)(3, "div", 292);
1408
1435
  i0.ɵɵtext(4);
1409
1436
  i0.ɵɵpipe(5, "date");
1410
1437
  i0.ɵɵelementEnd();
1411
- i0.ɵɵelementStart(6, "div", 291);
1438
+ i0.ɵɵelementStart(6, "div", 293);
1412
1439
  i0.ɵɵtext(7);
1413
1440
  i0.ɵɵelementEnd()();
1414
- i0.ɵɵconditionalCreate(8, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_12_For_2_Conditional_8_Template, 3, 0, "div", 292);
1441
+ i0.ɵɵconditionalCreate(8, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_12_For_2_Conditional_8_Template, 3, 0, "div", 294);
1415
1442
  i0.ɵɵelementEnd();
1416
1443
  } if (rf & 2) {
1417
- const run_r44 = ctx.$implicit;
1444
+ const run_r45 = ctx.$implicit;
1418
1445
  const ctx_r0 = i0.ɵɵnextContext(3);
1419
- i0.ɵɵclassProp("selected", ctx_r0.IsCompareRunB(run_r44))("disabled", ctx_r0.IsCompareRunA(run_r44));
1446
+ i0.ɵɵclassProp("selected", ctx_r0.IsCompareRunB(run_r45))("disabled", ctx_r0.IsCompareRunA(run_r45));
1420
1447
  i0.ɵɵadvance();
1421
- i0.ɵɵstyleProp("background-color", ctx_r0.getRunStatusColor(run_r44.Status));
1448
+ i0.ɵɵstyleProp("background-color", ctx_r0.getRunStatusColor(run_r45.Status));
1422
1449
  i0.ɵɵadvance(3);
1423
- i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(5, 9, run_r44.StartedAt, "short"));
1450
+ i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(5, 9, run_r45.StartedAt, "short"));
1424
1451
  i0.ɵɵadvance(3);
1425
- i0.ɵɵtextInterpolate1("", ctx_r0.getPassRate(run_r44).toFixed(0), "% pass");
1452
+ i0.ɵɵtextInterpolate1("", ctx_r0.getPassRate(run_r45).toFixed(0), "% pass");
1426
1453
  i0.ɵɵadvance();
1427
- i0.ɵɵconditional(ctx_r0.getRunTags(run_r44).length > 0 ? 8 : -1);
1454
+ i0.ɵɵconditional(ctx_r0.getRunTags(run_r45).length > 0 ? 8 : -1);
1428
1455
  } }
1429
1456
  function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_12_Template(rf, ctx) { if (rf & 1) {
1430
- i0.ɵɵelementStart(0, "div", 279);
1431
- i0.ɵɵrepeaterCreate(1, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_12_For_2_Template, 9, 12, "div", 299, i0.ɵɵrepeaterTrackByIdentity);
1457
+ i0.ɵɵelementStart(0, "div", 281);
1458
+ i0.ɵɵrepeaterCreate(1, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_12_For_2_Template, 9, 12, "div", 301, i0.ɵɵrepeaterTrackByIdentity);
1432
1459
  i0.ɵɵelementEnd();
1433
1460
  } if (rf & 2) {
1434
1461
  const ctx_r0 = i0.ɵɵnextContext(2);
@@ -1436,19 +1463,19 @@ function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_12_Template
1436
1463
  i0.ɵɵrepeater(ctx_r0.suiteRuns);
1437
1464
  } }
1438
1465
  function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_13_Template(rf, ctx) { if (rf & 1) {
1439
- const _r46 = i0.ɵɵgetCurrentView();
1440
- i0.ɵɵelementStart(0, "div", 280)(1, "div", 294)(2, "span", 295);
1466
+ const _r47 = i0.ɵɵgetCurrentView();
1467
+ i0.ɵɵelementStart(0, "div", 282)(1, "div", 296)(2, "span", 297);
1441
1468
  i0.ɵɵtext(3, "Selected:");
1442
1469
  i0.ɵɵelementEnd();
1443
- i0.ɵɵelementStart(4, "button", 296);
1444
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_13_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r46); const ctx_r0 = i0.ɵɵnextContext(2); ctx_r0.compareRunB = null; return i0.ɵɵresetView(ctx_r0.compareResults = []); });
1470
+ i0.ɵɵelementStart(4, "button", 298);
1471
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_13_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r47); const ctx_r0 = i0.ɵɵnextContext(2); ctx_r0.compareRunB = null; return i0.ɵɵresetView(ctx_r0.compareResults = []); });
1445
1472
  i0.ɵɵtext(5, "Clear");
1446
1473
  i0.ɵɵelementEnd()();
1447
- i0.ɵɵelementStart(6, "div", 297)(7, "span");
1474
+ i0.ɵɵelementStart(6, "div", 299)(7, "span");
1448
1475
  i0.ɵɵtext(8);
1449
1476
  i0.ɵɵpipe(9, "date");
1450
1477
  i0.ɵɵelementEnd();
1451
- i0.ɵɵelementStart(10, "span", 298);
1478
+ i0.ɵɵelementStart(10, "span", 300);
1452
1479
  i0.ɵɵtext(11);
1453
1480
  i0.ɵɵelementEnd()()();
1454
1481
  } if (rf & 2) {
@@ -1459,167 +1486,167 @@ function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_13_Template
1459
1486
  i0.ɵɵtextInterpolate1("", ctx_r0.getPassRate(ctx_r0.compareRunB).toFixed(1), "%");
1460
1487
  } }
1461
1488
  function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_4_Template(rf, ctx) { if (rf & 1) {
1462
- i0.ɵɵelementStart(0, "span", 197);
1489
+ i0.ɵɵelementStart(0, "span", 199);
1463
1490
  i0.ɵɵtext(1);
1464
1491
  i0.ɵɵelementEnd();
1465
1492
  } if (rf & 2) {
1466
- const result_r47 = i0.ɵɵnextContext().$implicit;
1467
- i0.ɵɵproperty("ngClass", "status-" + result_r47.runA.status.toLowerCase());
1493
+ const result_r48 = i0.ɵɵnextContext().$implicit;
1494
+ i0.ɵɵproperty("ngClass", "status-" + result_r48.runA.status.toLowerCase());
1468
1495
  i0.ɵɵadvance();
1469
- i0.ɵɵtextInterpolate(result_r47.runA.status);
1496
+ i0.ɵɵtextInterpolate(result_r48.runA.status);
1470
1497
  } }
1471
1498
  function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_5_Template(rf, ctx) { if (rf & 1) {
1472
- i0.ɵɵelementStart(0, "span", 312);
1499
+ i0.ɵɵelementStart(0, "span", 314);
1473
1500
  i0.ɵɵtext(1, "N/A");
1474
1501
  i0.ɵɵelementEnd();
1475
1502
  } }
1476
1503
  function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_7_Template(rf, ctx) { if (rf & 1) {
1477
- i0.ɵɵelementStart(0, "span", 197);
1504
+ i0.ɵɵelementStart(0, "span", 199);
1478
1505
  i0.ɵɵtext(1);
1479
1506
  i0.ɵɵelementEnd();
1480
1507
  } if (rf & 2) {
1481
- const result_r47 = i0.ɵɵnextContext().$implicit;
1482
- i0.ɵɵproperty("ngClass", "status-" + result_r47.runB.status.toLowerCase());
1508
+ const result_r48 = i0.ɵɵnextContext().$implicit;
1509
+ i0.ɵɵproperty("ngClass", "status-" + result_r48.runB.status.toLowerCase());
1483
1510
  i0.ɵɵadvance();
1484
- i0.ɵɵtextInterpolate(result_r47.runB.status);
1511
+ i0.ɵɵtextInterpolate(result_r48.runB.status);
1485
1512
  } }
1486
1513
  function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_8_Template(rf, ctx) { if (rf & 1) {
1487
- i0.ɵɵelementStart(0, "span", 312);
1514
+ i0.ɵɵelementStart(0, "span", 314);
1488
1515
  i0.ɵɵtext(1, "N/A");
1489
1516
  i0.ɵɵelementEnd();
1490
1517
  } }
1491
1518
  function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_10_Template(rf, ctx) { if (rf & 1) {
1492
- i0.ɵɵelementStart(0, "span", 311);
1519
+ i0.ɵɵelementStart(0, "span", 313);
1493
1520
  i0.ɵɵtext(1);
1494
1521
  i0.ɵɵelementEnd();
1495
1522
  } if (rf & 2) {
1496
- const result_r47 = i0.ɵɵnextContext().$implicit;
1497
- i0.ɵɵproperty("ngClass", i0.ɵɵpureFunction2(3, _c6, result_r47.scoreDiff > 0, result_r47.scoreDiff < 0));
1523
+ const result_r48 = i0.ɵɵnextContext().$implicit;
1524
+ i0.ɵɵproperty("ngClass", i0.ɵɵpureFunction2(3, _c6, result_r48.scoreDiff > 0, result_r48.scoreDiff < 0));
1498
1525
  i0.ɵɵadvance();
1499
- i0.ɵɵtextInterpolate2(" ", result_r47.scoreDiff > 0 ? "+" : "", "", (result_r47.scoreDiff * 100).toFixed(1), "% ");
1526
+ i0.ɵɵtextInterpolate2(" ", result_r48.scoreDiff > 0 ? "+" : "", "", (result_r48.scoreDiff * 100).toFixed(1), "% ");
1500
1527
  } }
1501
1528
  function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_11_Template(rf, ctx) { if (rf & 1) {
1502
- i0.ɵɵelementStart(0, "span", 313);
1529
+ i0.ɵɵelementStart(0, "span", 315);
1503
1530
  i0.ɵɵtext(1, "-");
1504
1531
  i0.ɵɵelementEnd();
1505
1532
  } }
1506
1533
  function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_13_Template(rf, ctx) { if (rf & 1) {
1507
- i0.ɵɵelementStart(0, "span", 311);
1534
+ i0.ɵɵelementStart(0, "span", 313);
1508
1535
  i0.ɵɵtext(1);
1509
1536
  i0.ɵɵelementEnd();
1510
1537
  } if (rf & 2) {
1511
- const result_r47 = i0.ɵɵnextContext().$implicit;
1512
- i0.ɵɵproperty("ngClass", i0.ɵɵpureFunction2(3, _c6, result_r47.durationDiff < 0, result_r47.durationDiff > 0));
1538
+ const result_r48 = i0.ɵɵnextContext().$implicit;
1539
+ i0.ɵɵproperty("ngClass", i0.ɵɵpureFunction2(3, _c6, result_r48.durationDiff < 0, result_r48.durationDiff > 0));
1513
1540
  i0.ɵɵadvance();
1514
- i0.ɵɵtextInterpolate2(" ", result_r47.durationDiff > 0 ? "+" : "", "", result_r47.durationDiff.toFixed(1), "s ");
1541
+ i0.ɵɵtextInterpolate2(" ", result_r48.durationDiff > 0 ? "+" : "", "", result_r48.durationDiff.toFixed(1), "s ");
1515
1542
  } }
1516
1543
  function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_14_Template(rf, ctx) { if (rf & 1) {
1517
- i0.ɵɵelementStart(0, "span", 313);
1544
+ i0.ɵɵelementStart(0, "span", 315);
1518
1545
  i0.ɵɵtext(1, "-");
1519
1546
  i0.ɵɵelementEnd();
1520
1547
  } }
1521
1548
  function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_16_Template(rf, ctx) { if (rf & 1) {
1522
- i0.ɵɵelementStart(0, "span", 314);
1523
- i0.ɵɵelement(1, "i", 317);
1549
+ i0.ɵɵelementStart(0, "span", 316);
1550
+ i0.ɵɵelement(1, "i", 319);
1524
1551
  i0.ɵɵtext(2, " Fixed ");
1525
1552
  i0.ɵɵelementEnd();
1526
1553
  } }
1527
1554
  function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_17_Template(rf, ctx) { if (rf & 1) {
1528
- i0.ɵɵelementStart(0, "span", 315);
1529
- i0.ɵɵelement(1, "i", 318);
1555
+ i0.ɵɵelementStart(0, "span", 317);
1556
+ i0.ɵɵelement(1, "i", 320);
1530
1557
  i0.ɵɵtext(2, " Broke ");
1531
1558
  i0.ɵɵelementEnd();
1532
1559
  } }
1533
1560
  function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_18_Template(rf, ctx) { if (rf & 1) {
1534
- i0.ɵɵelementStart(0, "span", 316);
1535
- i0.ɵɵelement(1, "i", 254);
1561
+ i0.ɵɵelementStart(0, "span", 318);
1562
+ i0.ɵɵelement(1, "i", 256);
1536
1563
  i0.ɵɵelementEnd();
1537
1564
  } }
1538
1565
  function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Template(rf, ctx) { if (rf & 1) {
1539
- i0.ɵɵelementStart(0, "tr", 311)(1, "td", 237);
1566
+ i0.ɵɵelementStart(0, "tr", 313)(1, "td", 239);
1540
1567
  i0.ɵɵtext(2);
1541
1568
  i0.ɵɵelementEnd();
1542
1569
  i0.ɵɵelementStart(3, "td");
1543
- i0.ɵɵconditionalCreate(4, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_4_Template, 2, 2, "span", 197);
1544
- i0.ɵɵconditionalCreate(5, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_5_Template, 2, 0, "span", 312);
1570
+ i0.ɵɵconditionalCreate(4, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_4_Template, 2, 2, "span", 199);
1571
+ i0.ɵɵconditionalCreate(5, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_5_Template, 2, 0, "span", 314);
1545
1572
  i0.ɵɵelementEnd();
1546
1573
  i0.ɵɵelementStart(6, "td");
1547
- i0.ɵɵconditionalCreate(7, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_7_Template, 2, 2, "span", 197);
1548
- i0.ɵɵconditionalCreate(8, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_8_Template, 2, 0, "span", 312);
1574
+ i0.ɵɵconditionalCreate(7, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_7_Template, 2, 2, "span", 199);
1575
+ i0.ɵɵconditionalCreate(8, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_8_Template, 2, 0, "span", 314);
1549
1576
  i0.ɵɵelementEnd();
1550
1577
  i0.ɵɵelementStart(9, "td");
1551
- i0.ɵɵconditionalCreate(10, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_10_Template, 2, 6, "span", 311);
1552
- i0.ɵɵconditionalCreate(11, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_11_Template, 2, 0, "span", 313);
1578
+ i0.ɵɵconditionalCreate(10, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_10_Template, 2, 6, "span", 313);
1579
+ i0.ɵɵconditionalCreate(11, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_11_Template, 2, 0, "span", 315);
1553
1580
  i0.ɵɵelementEnd();
1554
1581
  i0.ɵɵelementStart(12, "td");
1555
- i0.ɵɵconditionalCreate(13, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_13_Template, 2, 6, "span", 311);
1556
- i0.ɵɵconditionalCreate(14, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_14_Template, 2, 0, "span", 313);
1582
+ i0.ɵɵconditionalCreate(13, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_13_Template, 2, 6, "span", 313);
1583
+ i0.ɵɵconditionalCreate(14, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_14_Template, 2, 0, "span", 315);
1557
1584
  i0.ɵɵelementEnd();
1558
1585
  i0.ɵɵelementStart(15, "td");
1559
- i0.ɵɵconditionalCreate(16, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_16_Template, 3, 0, "span", 314);
1560
- i0.ɵɵconditionalCreate(17, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_17_Template, 3, 0, "span", 315);
1561
- i0.ɵɵconditionalCreate(18, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_18_Template, 2, 0, "span", 316);
1586
+ i0.ɵɵconditionalCreate(16, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_16_Template, 3, 0, "span", 316);
1587
+ i0.ɵɵconditionalCreate(17, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_17_Template, 3, 0, "span", 317);
1588
+ i0.ɵɵconditionalCreate(18, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_18_Template, 2, 0, "span", 318);
1562
1589
  i0.ɵɵelementEnd()();
1563
1590
  } if (rf & 2) {
1564
- const result_r47 = ctx.$implicit;
1565
- i0.ɵɵproperty("ngClass", i0.ɵɵpureFunction2(13, _c8, result_r47.runA && result_r47.runB && result_r47.runA.status !== "Passed" && result_r47.runB.status === "Passed", result_r47.runA && result_r47.runB && result_r47.runA.status === "Passed" && result_r47.runB.status !== "Passed"));
1591
+ const result_r48 = ctx.$implicit;
1592
+ i0.ɵɵproperty("ngClass", i0.ɵɵpureFunction2(13, _c8, result_r48.runA && result_r48.runB && result_r48.runA.status !== "Passed" && result_r48.runB.status === "Passed", result_r48.runA && result_r48.runB && result_r48.runA.status === "Passed" && result_r48.runB.status !== "Passed"));
1566
1593
  i0.ɵɵadvance(2);
1567
- i0.ɵɵtextInterpolate(result_r47.testName);
1594
+ i0.ɵɵtextInterpolate(result_r48.testName);
1568
1595
  i0.ɵɵadvance(2);
1569
- i0.ɵɵconditional(result_r47.runA ? 4 : -1);
1596
+ i0.ɵɵconditional(result_r48.runA ? 4 : -1);
1570
1597
  i0.ɵɵadvance();
1571
- i0.ɵɵconditional(!result_r47.runA ? 5 : -1);
1598
+ i0.ɵɵconditional(!result_r48.runA ? 5 : -1);
1572
1599
  i0.ɵɵadvance(2);
1573
- i0.ɵɵconditional(result_r47.runB ? 7 : -1);
1600
+ i0.ɵɵconditional(result_r48.runB ? 7 : -1);
1574
1601
  i0.ɵɵadvance();
1575
- i0.ɵɵconditional(!result_r47.runB ? 8 : -1);
1602
+ i0.ɵɵconditional(!result_r48.runB ? 8 : -1);
1576
1603
  i0.ɵɵadvance(2);
1577
- i0.ɵɵconditional(result_r47.scoreDiff != null ? 10 : -1);
1604
+ i0.ɵɵconditional(result_r48.scoreDiff != null ? 10 : -1);
1578
1605
  i0.ɵɵadvance();
1579
- i0.ɵɵconditional(result_r47.scoreDiff == null ? 11 : -1);
1606
+ i0.ɵɵconditional(result_r48.scoreDiff == null ? 11 : -1);
1580
1607
  i0.ɵɵadvance(2);
1581
- i0.ɵɵconditional(result_r47.durationDiff != null ? 13 : -1);
1608
+ i0.ɵɵconditional(result_r48.durationDiff != null ? 13 : -1);
1582
1609
  i0.ɵɵadvance();
1583
- i0.ɵɵconditional(result_r47.durationDiff == null ? 14 : -1);
1610
+ i0.ɵɵconditional(result_r48.durationDiff == null ? 14 : -1);
1584
1611
  i0.ɵɵadvance(2);
1585
- i0.ɵɵconditional(result_r47.runA && result_r47.runB && result_r47.runA.status !== "Passed" && result_r47.runB.status === "Passed" ? 16 : -1);
1612
+ i0.ɵɵconditional(result_r48.runA && result_r48.runB && result_r48.runA.status !== "Passed" && result_r48.runB.status === "Passed" ? 16 : -1);
1586
1613
  i0.ɵɵadvance();
1587
- i0.ɵɵconditional(result_r47.runA && result_r47.runB && result_r47.runA.status === "Passed" && result_r47.runB.status !== "Passed" ? 17 : -1);
1614
+ i0.ɵɵconditional(result_r48.runA && result_r48.runB && result_r48.runA.status === "Passed" && result_r48.runB.status !== "Passed" ? 17 : -1);
1588
1615
  i0.ɵɵadvance();
1589
- i0.ɵɵconditional(!result_r47.statusChanged ? 18 : -1);
1616
+ i0.ɵɵconditional(!result_r48.statusChanged ? 18 : -1);
1590
1617
  } }
1591
1618
  function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_Template(rf, ctx) { if (rf & 1) {
1592
- i0.ɵɵelementStart(0, "div", 283)(1, "div", 300)(2, "div", 301)(3, "div", 302);
1619
+ i0.ɵɵelementStart(0, "div", 285)(1, "div", 302)(2, "div", 303)(3, "div", 304);
1593
1620
  i0.ɵɵtext(4, "Pass Rate Change");
1594
1621
  i0.ɵɵelementEnd();
1595
- i0.ɵɵelementStart(5, "div", 303);
1622
+ i0.ɵɵelementStart(5, "div", 305);
1596
1623
  i0.ɵɵelement(6, "i", 19);
1597
1624
  i0.ɵɵtext(7);
1598
1625
  i0.ɵɵelementEnd()();
1599
- i0.ɵɵelementStart(8, "div", 301)(9, "div", 302);
1626
+ i0.ɵɵelementStart(8, "div", 303)(9, "div", 304);
1600
1627
  i0.ɵɵtext(10, "Duration Change");
1601
1628
  i0.ɵɵelementEnd();
1602
- i0.ɵɵelementStart(11, "div", 303);
1629
+ i0.ɵɵelementStart(11, "div", 305);
1603
1630
  i0.ɵɵelement(12, "i", 19);
1604
1631
  i0.ɵɵtext(13);
1605
1632
  i0.ɵɵelementEnd()();
1606
- i0.ɵɵelementStart(14, "div", 304)(15, "div", 302);
1633
+ i0.ɵɵelementStart(14, "div", 306)(15, "div", 304);
1607
1634
  i0.ɵɵtext(16, "Improved");
1608
1635
  i0.ɵɵelementEnd();
1609
- i0.ɵɵelementStart(17, "div", 305);
1636
+ i0.ɵɵelementStart(17, "div", 307);
1610
1637
  i0.ɵɵtext(18);
1611
1638
  i0.ɵɵelementEnd()();
1612
- i0.ɵɵelementStart(19, "div", 306)(20, "div", 302);
1639
+ i0.ɵɵelementStart(19, "div", 308)(20, "div", 304);
1613
1640
  i0.ɵɵtext(21, "Regressed");
1614
1641
  i0.ɵɵelementEnd();
1615
- i0.ɵɵelementStart(22, "div", 305);
1642
+ i0.ɵɵelementStart(22, "div", 307);
1616
1643
  i0.ɵɵtext(23);
1617
1644
  i0.ɵɵelementEnd()()();
1618
- i0.ɵɵelementStart(24, "div", 307)(25, "h3");
1619
- i0.ɵɵelement(26, "i", 308);
1645
+ i0.ɵɵelementStart(24, "div", 309)(25, "h3");
1646
+ i0.ɵɵelement(26, "i", 310);
1620
1647
  i0.ɵɵtext(27, " Test-by-Test Comparison");
1621
1648
  i0.ɵɵelementEnd();
1622
- i0.ɵɵelementStart(28, "div", 309)(29, "table", 310)(30, "thead")(31, "tr")(32, "th");
1649
+ i0.ɵɵelementStart(28, "div", 311)(29, "table", 312)(30, "thead")(31, "tr")(32, "th");
1623
1650
  i0.ɵɵtext(33, "Test");
1624
1651
  i0.ɵɵelementEnd();
1625
1652
  i0.ɵɵelementStart(34, "th");
@@ -1638,7 +1665,7 @@ function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_Template
1638
1665
  i0.ɵɵtext(43, "Change");
1639
1666
  i0.ɵɵelementEnd()()();
1640
1667
  i0.ɵɵelementStart(44, "tbody");
1641
- i0.ɵɵrepeaterCreate(45, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Template, 19, 16, "tr", 311, i0.ɵɵrepeaterTrackByIdentity);
1668
+ i0.ɵɵrepeaterCreate(45, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Template, 19, 16, "tr", 313, i0.ɵɵrepeaterTrackByIdentity);
1642
1669
  i0.ɵɵelementEnd()()()()();
1643
1670
  } if (rf & 2) {
1644
1671
  let tmp_4_0;
@@ -1663,39 +1690,39 @@ function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_Template
1663
1690
  i0.ɵɵrepeater(ctx_r0.compareResults);
1664
1691
  } }
1665
1692
  function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_15_Template(rf, ctx) { if (rf & 1) {
1666
- i0.ɵɵelementStart(0, "div", 99);
1667
- i0.ɵɵelement(1, "mj-loading", 319);
1693
+ i0.ɵɵelementStart(0, "div", 101);
1694
+ i0.ɵɵelement(1, "mj-loading", 321);
1668
1695
  i0.ɵɵelementEnd();
1669
1696
  } }
1670
1697
  function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_16_Template(rf, ctx) { if (rf & 1) {
1671
- i0.ɵɵelement(0, "mj-empty-state", 284);
1698
+ i0.ɵɵelement(0, "mj-empty-state", 286);
1672
1699
  } }
1673
1700
  function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_17_Template(rf, ctx) { if (rf & 1) {
1674
- const _r48 = i0.ɵɵgetCurrentView();
1675
- i0.ɵɵelementStart(0, "mj-empty-state", 320);
1676
- i0.ɵɵlistener("Action", function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_17_Template_mj_empty_state_Action_0_listener() { i0.ɵɵrestoreView(_r48); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.runSuite()); });
1701
+ const _r49 = i0.ɵɵgetCurrentView();
1702
+ i0.ɵɵelementStart(0, "mj-empty-state", 322);
1703
+ i0.ɵɵlistener("Action", function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_17_Template_mj_empty_state_Action_0_listener() { i0.ɵɵrestoreView(_r49); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.runSuite()); });
1677
1704
  i0.ɵɵelementEnd();
1678
1705
  } }
1679
1706
  function MJTestSuiteFormComponentExtended_Conditional_64_Template(rf, ctx) { if (rf & 1) {
1680
- i0.ɵɵelementStart(0, "div", 43)(1, "div", 277)(2, "div", 278)(3, "h4");
1707
+ i0.ɵɵelementStart(0, "div", 43)(1, "div", 279)(2, "div", 280)(3, "h4");
1681
1708
  i0.ɵɵtext(4, "Run A (Baseline)");
1682
1709
  i0.ɵɵelementEnd();
1683
- i0.ɵɵconditionalCreate(5, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_5_Template, 3, 0, "div", 279);
1684
- i0.ɵɵconditionalCreate(6, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_6_Template, 12, 5, "div", 280);
1710
+ i0.ɵɵconditionalCreate(5, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_5_Template, 3, 0, "div", 281);
1711
+ i0.ɵɵconditionalCreate(6, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_6_Template, 12, 5, "div", 282);
1685
1712
  i0.ɵɵelementEnd();
1686
- i0.ɵɵelementStart(7, "div", 281);
1687
- i0.ɵɵelement(8, "i", 282);
1713
+ i0.ɵɵelementStart(7, "div", 283);
1714
+ i0.ɵɵelement(8, "i", 284);
1688
1715
  i0.ɵɵelementEnd();
1689
- i0.ɵɵelementStart(9, "div", 278)(10, "h4");
1716
+ i0.ɵɵelementStart(9, "div", 280)(10, "h4");
1690
1717
  i0.ɵɵtext(11, "Run B (Compare)");
1691
1718
  i0.ɵɵelementEnd();
1692
- i0.ɵɵconditionalCreate(12, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_12_Template, 3, 0, "div", 279);
1693
- i0.ɵɵconditionalCreate(13, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_13_Template, 12, 5, "div", 280);
1719
+ i0.ɵɵconditionalCreate(12, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_12_Template, 3, 0, "div", 281);
1720
+ i0.ɵɵconditionalCreate(13, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_13_Template, 12, 5, "div", 282);
1694
1721
  i0.ɵɵelementEnd()();
1695
- i0.ɵɵconditionalCreate(14, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_Template, 47, 23, "div", 283);
1696
- i0.ɵɵconditionalCreate(15, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_15_Template, 2, 0, "div", 99);
1697
- i0.ɵɵconditionalCreate(16, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_16_Template, 1, 0, "mj-empty-state", 284);
1698
- i0.ɵɵconditionalCreate(17, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_17_Template, 1, 0, "mj-empty-state", 285);
1722
+ i0.ɵɵconditionalCreate(14, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_Template, 47, 23, "div", 285);
1723
+ i0.ɵɵconditionalCreate(15, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_15_Template, 2, 0, "div", 101);
1724
+ i0.ɵɵconditionalCreate(16, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_16_Template, 1, 0, "mj-empty-state", 286);
1725
+ i0.ɵɵconditionalCreate(17, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_17_Template, 1, 0, "mj-empty-state", 287);
1699
1726
  i0.ɵɵelementEnd();
1700
1727
  } if (rf & 2) {
1701
1728
  const ctx_r0 = i0.ɵɵnextContext();
@@ -1717,45 +1744,45 @@ function MJTestSuiteFormComponentExtended_Conditional_64_Template(rf, ctx) { if
1717
1744
  i0.ɵɵconditional(ctx_r0.runsLoaded && ctx_r0.suiteRuns.length < 2 ? 17 : -1);
1718
1745
  } }
1719
1746
  function MJTestSuiteFormComponentExtended_Conditional_67_Template(rf, ctx) { if (rf & 1) {
1720
- const _r49 = i0.ɵɵgetCurrentView();
1721
- i0.ɵɵelementStart(0, "div", 46)(1, "div", 321);
1747
+ const _r50 = i0.ɵɵgetCurrentView();
1748
+ i0.ɵɵelementStart(0, "div", 46)(1, "div", 323);
1722
1749
  i0.ɵɵelement(2, "i", 45);
1723
1750
  i0.ɵɵtext(3, " Shortcuts ");
1724
- i0.ɵɵelementStart(4, "button", 322);
1725
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_67_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r49); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.toggleShortcuts()); });
1726
- i0.ɵɵelement(5, "i", 91);
1751
+ i0.ɵɵelementStart(4, "button", 324);
1752
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_67_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r50); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.toggleShortcuts()); });
1753
+ i0.ɵɵelement(5, "i", 93);
1727
1754
  i0.ɵɵelementEnd()();
1728
- i0.ɵɵelementStart(6, "div", 323)(7, "div", 324)(8, "span");
1755
+ i0.ɵɵelementStart(6, "div", 325)(7, "div", 326)(8, "span");
1729
1756
  i0.ɵɵtext(9, "Save changes");
1730
1757
  i0.ɵɵelementEnd();
1731
- i0.ɵɵelementStart(10, "span", 325)(11, "kbd");
1758
+ i0.ɵɵelementStart(10, "span", 327)(11, "kbd");
1732
1759
  i0.ɵɵtext(12, "Cmd");
1733
1760
  i0.ɵɵelementEnd();
1734
1761
  i0.ɵɵelementStart(13, "kbd");
1735
1762
  i0.ɵɵtext(14, "S");
1736
1763
  i0.ɵɵelementEnd()()();
1737
- i0.ɵɵelementStart(15, "div", 324)(16, "span");
1764
+ i0.ɵɵelementStart(15, "div", 326)(16, "span");
1738
1765
  i0.ɵɵtext(17, "Refresh");
1739
1766
  i0.ɵɵelementEnd();
1740
- i0.ɵɵelementStart(18, "span", 325)(19, "kbd");
1767
+ i0.ɵɵelementStart(18, "span", 327)(19, "kbd");
1741
1768
  i0.ɵɵtext(20, "Cmd");
1742
1769
  i0.ɵɵelementEnd();
1743
1770
  i0.ɵɵelementStart(21, "kbd");
1744
1771
  i0.ɵɵtext(22, "R");
1745
1772
  i0.ɵɵelementEnd()()();
1746
- i0.ɵɵelementStart(23, "div", 324)(24, "span");
1773
+ i0.ɵɵelementStart(23, "div", 326)(24, "span");
1747
1774
  i0.ɵɵtext(25, "Run Suite");
1748
1775
  i0.ɵɵelementEnd();
1749
- i0.ɵɵelementStart(26, "span", 325)(27, "kbd");
1776
+ i0.ɵɵelementStart(26, "span", 327)(27, "kbd");
1750
1777
  i0.ɵɵtext(28, "Cmd");
1751
1778
  i0.ɵɵelementEnd();
1752
1779
  i0.ɵɵelementStart(29, "kbd");
1753
1780
  i0.ɵɵtext(30, "Enter");
1754
1781
  i0.ɵɵelementEnd()()();
1755
- i0.ɵɵelementStart(31, "div", 324)(32, "span");
1782
+ i0.ɵɵelementStart(31, "div", 326)(32, "span");
1756
1783
  i0.ɵɵtext(33, "Switch Tabs");
1757
1784
  i0.ɵɵelementEnd();
1758
- i0.ɵɵelementStart(34, "span", 325)(35, "kbd");
1785
+ i0.ɵɵelementStart(34, "span", 327)(35, "kbd");
1759
1786
  i0.ɵɵtext(36, "1");
1760
1787
  i0.ɵɵelementEnd();
1761
1788
  i0.ɵɵtext(37, "-");
@@ -1764,11 +1791,11 @@ function MJTestSuiteFormComponentExtended_Conditional_67_Template(rf, ctx) { if
1764
1791
  i0.ɵɵelementEnd()()()()();
1765
1792
  } }
1766
1793
  function MJTestSuiteFormComponentExtended_Conditional_68_Template(rf, ctx) { if (rf & 1) {
1767
- const _r50 = i0.ɵɵgetCurrentView();
1768
- i0.ɵɵelementStart(0, "mj-slide-panel", 326);
1769
- i0.ɵɵlistener("Closed", function MJTestSuiteFormComponentExtended_Conditional_68_Template_mj_slide_panel_Closed_0_listener() { i0.ɵɵrestoreView(_r50); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnPanelClosed()); });
1770
- i0.ɵɵelementStart(1, "app-test-run-dialog", 327);
1771
- i0.ɵɵlistener("PanelClose", function MJTestSuiteFormComponentExtended_Conditional_68_Template_app_test_run_dialog_PanelClose_1_listener() { i0.ɵɵrestoreView(_r50); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnPanelClosed()); });
1794
+ const _r51 = i0.ɵɵgetCurrentView();
1795
+ i0.ɵɵelementStart(0, "mj-slide-panel", 328);
1796
+ i0.ɵɵlistener("Closed", function MJTestSuiteFormComponentExtended_Conditional_68_Template_mj_slide_panel_Closed_0_listener() { i0.ɵɵrestoreView(_r51); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnPanelClosed()); });
1797
+ i0.ɵɵelementStart(1, "app-test-run-dialog", 329);
1798
+ i0.ɵɵlistener("PanelClose", function MJTestSuiteFormComponentExtended_Conditional_68_Template_app_test_run_dialog_PanelClose_1_listener() { i0.ɵɵrestoreView(_r51); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnPanelClosed()); });
1772
1799
  i0.ɵɵelementEnd()();
1773
1800
  } if (rf & 2) {
1774
1801
  const ctx_r0 = i0.ɵɵnextContext();
@@ -1777,10 +1804,10 @@ function MJTestSuiteFormComponentExtended_Conditional_68_Template(rf, ctx) { if
1777
1804
  i0.ɵɵproperty("PanelMode", true)("selectedTestId", (ctx_r0.testingDialogService.PanelOptions == null ? null : ctx_r0.testingDialogService.PanelOptions.testId) ?? null)("selectedSuiteId", (ctx_r0.testingDialogService.PanelOptions == null ? null : ctx_r0.testingDialogService.PanelOptions.suiteId) ?? null)("runMode", (ctx_r0.testingDialogService.PanelOptions == null ? null : ctx_r0.testingDialogService.PanelOptions.mode) ?? "suite");
1778
1805
  } }
1779
1806
  function MJTestSuiteFormComponentExtended_Conditional_69_Conditional_12_Template(rf, ctx) { if (rf & 1) {
1780
- const _r52 = i0.ɵɵgetCurrentView();
1781
- i0.ɵɵelementStart(0, "button", 348);
1782
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_69_Conditional_12_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r52); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.addTestsSearch = ""); });
1783
- i0.ɵɵelement(1, "i", 91);
1807
+ const _r53 = i0.ɵɵgetCurrentView();
1808
+ i0.ɵɵelementStart(0, "button", 350);
1809
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_69_Conditional_12_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r53); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.addTestsSearch = ""); });
1810
+ i0.ɵɵelement(1, "i", 93);
1784
1811
  i0.ɵɵelementEnd();
1785
1812
  } }
1786
1813
  function MJTestSuiteFormComponentExtended_Conditional_69_Conditional_15_Template(rf, ctx) { if (rf & 1) {
@@ -1800,84 +1827,84 @@ function MJTestSuiteFormComponentExtended_Conditional_69_Conditional_16_Template
1800
1827
  i0.ɵɵtextInterpolate2(" ", ctx_r0.filteredAvailableTests.length, " test", ctx_r0.filteredAvailableTests.length === 1 ? "" : "s", " available ");
1801
1828
  } }
1802
1829
  function MJTestSuiteFormComponentExtended_Conditional_69_Conditional_23_Template(rf, ctx) { if (rf & 1) {
1803
- i0.ɵɵelementStart(0, "div", 343);
1804
- i0.ɵɵelement(1, "mj-loading", 349);
1830
+ i0.ɵɵelementStart(0, "div", 345);
1831
+ i0.ɵɵelement(1, "mj-loading", 351);
1805
1832
  i0.ɵɵelementEnd();
1806
1833
  } }
1807
1834
  function MJTestSuiteFormComponentExtended_Conditional_69_Conditional_24_Conditional_0_Template(rf, ctx) { if (rf & 1) {
1808
- i0.ɵɵelement(0, "mj-empty-state", 350);
1835
+ i0.ɵɵelement(0, "mj-empty-state", 352);
1809
1836
  } }
1810
1837
  function MJTestSuiteFormComponentExtended_Conditional_69_Conditional_24_Conditional_1_Template(rf, ctx) { if (rf & 1) {
1811
- i0.ɵɵelement(0, "mj-empty-state", 351);
1838
+ i0.ɵɵelement(0, "mj-empty-state", 353);
1812
1839
  } if (rf & 2) {
1813
1840
  const ctx_r0 = i0.ɵɵnextContext(3);
1814
1841
  i0.ɵɵproperty("Message", ctx_r0.AddTestsNoMatchMessage);
1815
1842
  } }
1816
1843
  function MJTestSuiteFormComponentExtended_Conditional_69_Conditional_24_Template(rf, ctx) { if (rf & 1) {
1817
- i0.ɵɵconditionalCreate(0, MJTestSuiteFormComponentExtended_Conditional_69_Conditional_24_Conditional_0_Template, 1, 0, "mj-empty-state", 350)(1, MJTestSuiteFormComponentExtended_Conditional_69_Conditional_24_Conditional_1_Template, 1, 1, "mj-empty-state", 351);
1844
+ i0.ɵɵconditionalCreate(0, MJTestSuiteFormComponentExtended_Conditional_69_Conditional_24_Conditional_0_Template, 1, 0, "mj-empty-state", 352)(1, MJTestSuiteFormComponentExtended_Conditional_69_Conditional_24_Conditional_1_Template, 1, 1, "mj-empty-state", 353);
1818
1845
  } if (rf & 2) {
1819
1846
  const ctx_r0 = i0.ɵɵnextContext(2);
1820
1847
  i0.ɵɵconditional(ctx_r0.availableTests.length === 0 ? 0 : 1);
1821
1848
  } }
1822
1849
  function MJTestSuiteFormComponentExtended_Conditional_69_Conditional_25_For_2_Conditional_2_Template(rf, ctx) { if (rf & 1) {
1823
- i0.ɵɵelement(0, "i", 177);
1850
+ i0.ɵɵelement(0, "i", 179);
1824
1851
  } }
1825
1852
  function MJTestSuiteFormComponentExtended_Conditional_69_Conditional_25_For_2_Conditional_6_Template(rf, ctx) { if (rf & 1) {
1826
- i0.ɵɵelementStart(0, "div", 357);
1853
+ i0.ɵɵelementStart(0, "div", 359);
1827
1854
  i0.ɵɵtext(1);
1828
1855
  i0.ɵɵelementEnd();
1829
1856
  } if (rf & 2) {
1830
- const t_r54 = i0.ɵɵnextContext().$implicit;
1857
+ const t_r55 = i0.ɵɵnextContext().$implicit;
1831
1858
  i0.ɵɵadvance();
1832
- i0.ɵɵtextInterpolate(t_r54.Description);
1859
+ i0.ɵɵtextInterpolate(t_r55.Description);
1833
1860
  } }
1834
1861
  function MJTestSuiteFormComponentExtended_Conditional_69_Conditional_25_For_2_Conditional_8_Template(rf, ctx) { if (rf & 1) {
1835
- i0.ɵɵelementStart(0, "span", 359);
1862
+ i0.ɵɵelementStart(0, "span", 361);
1836
1863
  i0.ɵɵtext(1);
1837
1864
  i0.ɵɵelementEnd();
1838
1865
  } if (rf & 2) {
1839
- const t_r54 = i0.ɵɵnextContext().$implicit;
1866
+ const t_r55 = i0.ɵɵnextContext().$implicit;
1840
1867
  i0.ɵɵadvance();
1841
- i0.ɵɵtextInterpolate(t_r54.Type);
1868
+ i0.ɵɵtextInterpolate(t_r55.Type);
1842
1869
  } }
1843
1870
  function MJTestSuiteFormComponentExtended_Conditional_69_Conditional_25_For_2_Template(rf, ctx) { if (rf & 1) {
1844
- const _r53 = i0.ɵɵgetCurrentView();
1845
- i0.ɵɵelementStart(0, "li", 353);
1846
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_69_Conditional_25_For_2_Template_li_click_0_listener() { const t_r54 = i0.ɵɵrestoreView(_r53).$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.toggleAddSelection(t_r54.ID)); });
1847
- i0.ɵɵelementStart(1, "span", 354);
1848
- i0.ɵɵconditionalCreate(2, MJTestSuiteFormComponentExtended_Conditional_69_Conditional_25_For_2_Conditional_2_Template, 1, 0, "i", 177);
1871
+ const _r54 = i0.ɵɵgetCurrentView();
1872
+ i0.ɵɵelementStart(0, "li", 355);
1873
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_69_Conditional_25_For_2_Template_li_click_0_listener() { const t_r55 = i0.ɵɵrestoreView(_r54).$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.toggleAddSelection(t_r55.ID)); });
1874
+ i0.ɵɵelementStart(1, "span", 356);
1875
+ i0.ɵɵconditionalCreate(2, MJTestSuiteFormComponentExtended_Conditional_69_Conditional_25_For_2_Conditional_2_Template, 1, 0, "i", 179);
1849
1876
  i0.ɵɵelementEnd();
1850
- i0.ɵɵelementStart(3, "div", 355)(4, "div", 356);
1877
+ i0.ɵɵelementStart(3, "div", 357)(4, "div", 358);
1851
1878
  i0.ɵɵtext(5);
1852
1879
  i0.ɵɵelementEnd();
1853
- i0.ɵɵconditionalCreate(6, MJTestSuiteFormComponentExtended_Conditional_69_Conditional_25_For_2_Conditional_6_Template, 2, 1, "div", 357);
1880
+ i0.ɵɵconditionalCreate(6, MJTestSuiteFormComponentExtended_Conditional_69_Conditional_25_For_2_Conditional_6_Template, 2, 1, "div", 359);
1854
1881
  i0.ɵɵelementEnd();
1855
- i0.ɵɵelementStart(7, "div", 358);
1856
- i0.ɵɵconditionalCreate(8, MJTestSuiteFormComponentExtended_Conditional_69_Conditional_25_For_2_Conditional_8_Template, 2, 1, "span", 359);
1857
- i0.ɵɵelementStart(9, "span", 360);
1882
+ i0.ɵɵelementStart(7, "div", 360);
1883
+ i0.ɵɵconditionalCreate(8, MJTestSuiteFormComponentExtended_Conditional_69_Conditional_25_For_2_Conditional_8_Template, 2, 1, "span", 361);
1884
+ i0.ɵɵelementStart(9, "span", 362);
1858
1885
  i0.ɵɵtext(10);
1859
1886
  i0.ɵɵelementEnd()()();
1860
1887
  } if (rf & 2) {
1861
- const t_r54 = ctx.$implicit;
1888
+ const t_r55 = ctx.$implicit;
1862
1889
  const ctx_r0 = i0.ɵɵnextContext(3);
1863
- i0.ɵɵclassProp("picker-row--selected", ctx_r0.isAddSelected(t_r54.ID));
1864
- i0.ɵɵattribute("aria-checked", ctx_r0.isAddSelected(t_r54.ID));
1890
+ i0.ɵɵclassProp("picker-row--selected", ctx_r0.isAddSelected(t_r55.ID));
1891
+ i0.ɵɵattribute("aria-checked", ctx_r0.isAddSelected(t_r55.ID));
1865
1892
  i0.ɵɵadvance(2);
1866
- i0.ɵɵconditional(ctx_r0.isAddSelected(t_r54.ID) ? 2 : -1);
1893
+ i0.ɵɵconditional(ctx_r0.isAddSelected(t_r55.ID) ? 2 : -1);
1867
1894
  i0.ɵɵadvance(3);
1868
- i0.ɵɵtextInterpolate(t_r54.Name);
1895
+ i0.ɵɵtextInterpolate(t_r55.Name);
1869
1896
  i0.ɵɵadvance();
1870
- i0.ɵɵconditional(t_r54.Description ? 6 : -1);
1897
+ i0.ɵɵconditional(t_r55.Description ? 6 : -1);
1871
1898
  i0.ɵɵadvance(2);
1872
- i0.ɵɵconditional(t_r54.Type ? 8 : -1);
1899
+ i0.ɵɵconditional(t_r55.Type ? 8 : -1);
1873
1900
  i0.ɵɵadvance();
1874
- i0.ɵɵattribute("data-status", t_r54.Status == null ? null : t_r54.Status.toLowerCase());
1901
+ i0.ɵɵattribute("data-status", t_r55.Status == null ? null : t_r55.Status.toLowerCase());
1875
1902
  i0.ɵɵadvance();
1876
- i0.ɵɵtextInterpolate(t_r54.Status);
1903
+ i0.ɵɵtextInterpolate(t_r55.Status);
1877
1904
  } }
1878
1905
  function MJTestSuiteFormComponentExtended_Conditional_69_Conditional_25_Template(rf, ctx) { if (rf & 1) {
1879
- i0.ɵɵelementStart(0, "ul", 344);
1880
- i0.ɵɵrepeaterCreate(1, MJTestSuiteFormComponentExtended_Conditional_69_Conditional_25_For_2_Template, 11, 9, "li", 352, _forTrack0);
1906
+ i0.ɵɵelementStart(0, "ul", 346);
1907
+ i0.ɵɵrepeaterCreate(1, MJTestSuiteFormComponentExtended_Conditional_69_Conditional_25_For_2_Template, 11, 9, "li", 354, _forTrack1);
1881
1908
  i0.ɵɵelementEnd();
1882
1909
  } if (rf & 2) {
1883
1910
  const ctx_r0 = i0.ɵɵnextContext(2);
@@ -1885,7 +1912,7 @@ function MJTestSuiteFormComponentExtended_Conditional_69_Conditional_25_Template
1885
1912
  i0.ɵɵrepeater(ctx_r0.filteredAvailableTests);
1886
1913
  } }
1887
1914
  function MJTestSuiteFormComponentExtended_Conditional_69_Conditional_28_Template(rf, ctx) { if (rf & 1) {
1888
- i0.ɵɵelement(0, "i", 123);
1915
+ i0.ɵɵelement(0, "i", 125);
1889
1916
  i0.ɵɵtext(1, " Adding\u2026 ");
1890
1917
  } }
1891
1918
  function MJTestSuiteFormComponentExtended_Conditional_69_Conditional_29_Conditional_1_Template(rf, ctx) { if (rf & 1) {
@@ -1901,7 +1928,7 @@ function MJTestSuiteFormComponentExtended_Conditional_69_Conditional_29_Conditio
1901
1928
  i0.ɵɵtextInterpolate1(" Add ", ctx_r0.selectedTestIdsToAdd.size, " tests ");
1902
1929
  } }
1903
1930
  function MJTestSuiteFormComponentExtended_Conditional_69_Conditional_29_Template(rf, ctx) { if (rf & 1) {
1904
- i0.ɵɵelement(0, "i", 177);
1931
+ i0.ɵɵelement(0, "i", 179);
1905
1932
  i0.ɵɵconditionalCreate(1, MJTestSuiteFormComponentExtended_Conditional_69_Conditional_29_Conditional_1_Template, 1, 0)(2, MJTestSuiteFormComponentExtended_Conditional_69_Conditional_29_Conditional_2_Template, 1, 0)(3, MJTestSuiteFormComponentExtended_Conditional_69_Conditional_29_Conditional_3_Template, 1, 1);
1906
1933
  } if (rf & 2) {
1907
1934
  const ctx_r0 = i0.ɵɵnextContext(2);
@@ -1909,47 +1936,47 @@ function MJTestSuiteFormComponentExtended_Conditional_69_Conditional_29_Template
1909
1936
  i0.ɵɵconditional(ctx_r0.selectedTestIdsToAdd.size === 0 ? 1 : ctx_r0.selectedTestIdsToAdd.size === 1 ? 2 : 3);
1910
1937
  } }
1911
1938
  function MJTestSuiteFormComponentExtended_Conditional_69_Template(rf, ctx) { if (rf & 1) {
1912
- const _r51 = i0.ɵɵgetCurrentView();
1913
- i0.ɵɵelementStart(0, "div", 328);
1914
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_69_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r51); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.closeAddTestsDialog()); });
1939
+ const _r52 = i0.ɵɵgetCurrentView();
1940
+ i0.ɵɵelementStart(0, "div", 330);
1941
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_69_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r52); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.closeAddTestsDialog()); });
1915
1942
  i0.ɵɵelementEnd();
1916
- i0.ɵɵelementStart(1, "div", 329);
1943
+ i0.ɵɵelementStart(1, "div", 331);
1917
1944
  i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_69_Template_div_click_1_listener($event) { return $event.stopPropagation(); });
1918
- i0.ɵɵelementStart(2, "div", 330)(3, "h2", 331);
1919
- i0.ɵɵelement(4, "i", 332);
1945
+ i0.ɵɵelementStart(2, "div", 332)(3, "h2", 333);
1946
+ i0.ɵɵelement(4, "i", 334);
1920
1947
  i0.ɵɵtext(5, " Add tests to suite ");
1921
1948
  i0.ɵɵelementEnd();
1922
- i0.ɵɵelementStart(6, "button", 333);
1923
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_69_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r51); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.closeAddTestsDialog()); });
1924
- i0.ɵɵelement(7, "i", 91);
1949
+ i0.ɵɵelementStart(6, "button", 335);
1950
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_69_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r52); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.closeAddTestsDialog()); });
1951
+ i0.ɵɵelement(7, "i", 93);
1925
1952
  i0.ɵɵelementEnd()();
1926
- i0.ɵɵelementStart(8, "div", 334);
1927
- i0.ɵɵelement(9, "i", 335);
1928
- i0.ɵɵelementStart(10, "input", 336, 2);
1929
- i0.ɵɵtwoWayListener("ngModelChange", function MJTestSuiteFormComponentExtended_Conditional_69_Template_input_ngModelChange_10_listener($event) { i0.ɵɵrestoreView(_r51); const ctx_r0 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r0.addTestsSearch, $event) || (ctx_r0.addTestsSearch = $event); return i0.ɵɵresetView($event); });
1953
+ i0.ɵɵelementStart(8, "div", 336);
1954
+ i0.ɵɵelement(9, "i", 337);
1955
+ i0.ɵɵelementStart(10, "input", 338, 2);
1956
+ i0.ɵɵtwoWayListener("ngModelChange", function MJTestSuiteFormComponentExtended_Conditional_69_Template_input_ngModelChange_10_listener($event) { i0.ɵɵrestoreView(_r52); const ctx_r0 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r0.addTestsSearch, $event) || (ctx_r0.addTestsSearch = $event); return i0.ɵɵresetView($event); });
1930
1957
  i0.ɵɵelementEnd();
1931
- i0.ɵɵconditionalCreate(12, MJTestSuiteFormComponentExtended_Conditional_69_Conditional_12_Template, 2, 0, "button", 337);
1958
+ i0.ɵɵconditionalCreate(12, MJTestSuiteFormComponentExtended_Conditional_69_Conditional_12_Template, 2, 0, "button", 339);
1932
1959
  i0.ɵɵelementEnd();
1933
- i0.ɵɵelementStart(13, "div", 338)(14, "span", 339);
1960
+ i0.ɵɵelementStart(13, "div", 340)(14, "span", 341);
1934
1961
  i0.ɵɵconditionalCreate(15, MJTestSuiteFormComponentExtended_Conditional_69_Conditional_15_Template, 3, 1)(16, MJTestSuiteFormComponentExtended_Conditional_69_Conditional_16_Template, 1, 2);
1935
1962
  i0.ɵɵelementEnd();
1936
- i0.ɵɵelementStart(17, "div", 340)(18, "button", 341);
1937
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_69_Template_button_click_18_listener() { i0.ɵɵrestoreView(_r51); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.selectAllFiltered()); });
1963
+ i0.ɵɵelementStart(17, "div", 342)(18, "button", 343);
1964
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_69_Template_button_click_18_listener() { i0.ɵɵrestoreView(_r52); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.selectAllFiltered()); });
1938
1965
  i0.ɵɵtext(19, " Select all ");
1939
1966
  i0.ɵɵelementEnd();
1940
- i0.ɵɵelementStart(20, "button", 341);
1941
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_69_Template_button_click_20_listener() { i0.ɵɵrestoreView(_r51); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.clearAddSelection()); });
1967
+ i0.ɵɵelementStart(20, "button", 343);
1968
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_69_Template_button_click_20_listener() { i0.ɵɵrestoreView(_r52); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.clearAddSelection()); });
1942
1969
  i0.ɵɵtext(21, " Clear ");
1943
1970
  i0.ɵɵelementEnd()()();
1944
- i0.ɵɵelementStart(22, "div", 342);
1945
- i0.ɵɵconditionalCreate(23, MJTestSuiteFormComponentExtended_Conditional_69_Conditional_23_Template, 2, 0, "div", 343)(24, MJTestSuiteFormComponentExtended_Conditional_69_Conditional_24_Template, 2, 1)(25, MJTestSuiteFormComponentExtended_Conditional_69_Conditional_25_Template, 3, 0, "ul", 344);
1971
+ i0.ɵɵelementStart(22, "div", 344);
1972
+ i0.ɵɵconditionalCreate(23, MJTestSuiteFormComponentExtended_Conditional_69_Conditional_23_Template, 2, 0, "div", 345)(24, MJTestSuiteFormComponentExtended_Conditional_69_Conditional_24_Template, 2, 1)(25, MJTestSuiteFormComponentExtended_Conditional_69_Conditional_25_Template, 3, 0, "ul", 346);
1946
1973
  i0.ɵɵelementEnd();
1947
- i0.ɵɵelementStart(26, "div", 345)(27, "button", 346);
1948
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_69_Template_button_click_27_listener() { i0.ɵɵrestoreView(_r51); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.confirmAddTests()); });
1974
+ i0.ɵɵelementStart(26, "div", 347)(27, "button", 348);
1975
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_69_Template_button_click_27_listener() { i0.ɵɵrestoreView(_r52); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.confirmAddTests()); });
1949
1976
  i0.ɵɵconditionalCreate(28, MJTestSuiteFormComponentExtended_Conditional_69_Conditional_28_Template, 2, 0)(29, MJTestSuiteFormComponentExtended_Conditional_69_Conditional_29_Template, 4, 1);
1950
1977
  i0.ɵɵelementEnd();
1951
- i0.ɵɵelementStart(30, "button", 347);
1952
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_69_Template_button_click_30_listener() { i0.ɵɵrestoreView(_r51); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.closeAddTestsDialog()); });
1978
+ i0.ɵɵelementStart(30, "button", 349);
1979
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_69_Template_button_click_30_listener() { i0.ɵɵrestoreView(_r52); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.closeAddTestsDialog()); });
1953
1980
  i0.ɵɵtext(31, " Cancel ");
1954
1981
  i0.ɵɵelementEnd()()();
1955
1982
  } if (rf & 2) {
@@ -1988,13 +2015,13 @@ function MJTestSuiteFormComponentExtended_Conditional_79_Template(rf, ctx) { if
1988
2015
  i0.ɵɵtextInterpolate1(" ", ctx_r0.dirtyFieldNames.length, " fields edited ");
1989
2016
  } }
1990
2017
  function MJTestSuiteFormComponentExtended_Conditional_82_Template(rf, ctx) { if (rf & 1) {
1991
- i0.ɵɵelement(0, "i", 123);
2018
+ i0.ɵɵelement(0, "i", 125);
1992
2019
  i0.ɵɵtext(1, " Saving\u2026 ");
1993
2020
  } }
1994
2021
  function MJTestSuiteFormComponentExtended_Conditional_83_Template(rf, ctx) { if (rf & 1) {
1995
- i0.ɵɵelement(0, "i", 177);
2022
+ i0.ɵɵelement(0, "i", 179);
1996
2023
  i0.ɵɵtext(1, " Save changes ");
1997
- i0.ɵɵelementStart(2, "span", 361)(3, "kbd");
2024
+ i0.ɵɵelementStart(2, "span", 363)(3, "kbd");
1998
2025
  i0.ɵɵtext(4, "\u2318");
1999
2026
  i0.ɵɵelementEnd();
2000
2027
  i0.ɵɵelementStart(5, "kbd");
@@ -2057,6 +2084,7 @@ let MJTestSuiteFormComponentExtended = class MJTestSuiteFormComponentExtended ex
2057
2084
  // Edit state
2058
2085
  this.IsSaving = false;
2059
2086
  this.ParentSuiteOptions = [];
2087
+ this.RubricOptions = [];
2060
2088
  this.TagDraft = '';
2061
2089
  this.StatusOptions = ['Active', 'Pending', 'Disabled'];
2062
2090
  // Add Tests picker state
@@ -2457,6 +2485,7 @@ let MJTestSuiteFormComponentExtended = class MJTestSuiteFormComponentExtended ex
2457
2485
  this.loadShortcutsSetting();
2458
2486
  // Fire-and-forget: parent suite list for the edit form
2459
2487
  this.loadParentSuiteOptions();
2488
+ void this.loadRubricOptions();
2460
2489
  // Subscribe to evaluation preferences
2461
2490
  this.evalPrefsService.preferences$
2462
2491
  .pipe(takeUntil(this.destroy$))
@@ -4391,6 +4420,17 @@ let MJTestSuiteFormComponentExtended = class MJTestSuiteFormComponentExtended ex
4391
4420
  * Load all suites for the Parent Suite dropdown. Excludes the current
4392
4421
  * suite (a suite cannot be its own parent).
4393
4422
  */
4423
+ async loadRubricOptions() {
4424
+ try {
4425
+ const rv = RunView.FromMetadataProvider(this.ProviderToUse);
4426
+ const result = await rv.RunView({ EntityName: 'MJ: Rubrics', ExtraFilter: `Status='Active'`, OrderBy: 'Name', ResultType: 'simple', MaxRows: 500 });
4427
+ this.RubricOptions = RubricPickerOptions((result.Results ?? []));
4428
+ this.cdr.markForCheck();
4429
+ }
4430
+ catch (error) {
4431
+ console.warn('Failed to load rubric options:', error);
4432
+ }
4433
+ }
4394
4434
  async loadParentSuiteOptions() {
4395
4435
  try {
4396
4436
  const rv = RunView.FromMetadataProvider(this.ProviderToUse);
@@ -4795,7 +4835,7 @@ let MJTestSuiteFormComponentExtended = class MJTestSuiteFormComponentExtended ex
4795
4835
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.ChartContainer = _t.first);
4796
4836
  } }, hostBindings: function MJTestSuiteFormComponentExtended_HostBindings(rf, ctx) { if (rf & 1) {
4797
4837
  i0.ɵɵlistener("keydown", function MJTestSuiteFormComponentExtended_keydown_HostBindingHandler($event) { return ctx.handleKeyboardShortcut($event); }, i0.ɵɵresolveDocument)("beforeunload", function MJTestSuiteFormComponentExtended_beforeunload_HostBindingHandler($event) { return ctx.handleBeforeUnload($event); }, i0.ɵɵresolveWindow);
4798
- } }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 87, vars: 51, consts: [["tagInput", ""], ["chartContainer", ""], ["pickerSearch", ""], [1, "test-suite-form"], [1, "suite-header"], ["aria-label", "Breadcrumb", 1, "breadcrumb"], ["href", "javascript:void(0)", 3, "click"], [1, "fas", "fa-vial"], [1, "breadcrumb-text"], [1, "current"], [1, "fas", "fa-chevron-right", "separator"], [1, "fas", "fa-layer-group"], [1, "header-content"], [1, "header-left"], [1, "suite-icon"], [1, "suite-info"], ["title", "You have unsaved changes", "aria-label", "Unsaved changes", 1, "dirty-indicator"], [1, "suite-meta"], [1, "status-badge", 3, "ngClass"], [1, "fas", 3, "ngClass"], [1, "test-count"], ["title", "You have unsaved changes", 1, "unsaved-pill"], [1, "header-actions"], ["mjButton", "", "title", "Export to CSV", 3, "click"], [1, "fas", "fa-file-excel"], ["mjButton", "", "variant", "primary", 3, "click"], [1, "fas", "fa-play"], ["mjButton", "", 3, "click", "disabled"], [1, "suite-description"], [1, "tabs-container"], ["role", "tablist", 1, "tabs"], ["role", "tab", 1, "tab", 3, "click"], [1, "fas", "fa-th-large"], [1, "fas", "fa-flask"], [1, "tab-badge"], [1, "fas", "fa-history"], [1, "fas", "fa-chart-line"], [1, "fas", "fa-balance-scale"], [1, "tab-content"], [1, "overview-tab"], [1, "tests-tab"], [1, "runs-tab"], [1, "analytics-tab"], [1, "compare-tab"], [1, "shortcuts-toggle", 3, "click", "title"], [1, "fas", "fa-keyboard"], [1, "keyboard-shortcuts"], ["Mode", "slide", 3, "Title", "Resizable"], ["role", "region", "aria-label", "Unsaved changes", 1, "save-bar"], [1, "save-bar-message"], ["aria-hidden", "true", 1, "save-bar-dot"], [1, "save-bar-text"], [1, "save-bar-fields"], [1, "save-bar-actions"], ["type", "button", "title", "Save changes (\u2318S)", 1, "save-bar-btn", "save-bar-btn--primary", 3, "click", "disabled"], ["type", "button", "title", "Discard changes", 1, "save-bar-btn", "save-bar-btn--ghost", 3, "click", "disabled"], [1, "fas", "fa-undo"], [1, "fas", "fa-circle"], [1, "edit-section"], [1, "edit-section-header"], [1, "fas", "fa-pen-to-square"], [1, "edit-section-sub"], [1, "edit-grid"], [1, "edit-field", "edit-field--full"], ["for", "suite-name"], [1, "required"], ["id", "suite-name", "type", "text", "placeholder", "e.g., Core Agent Test Suite", 1, "config-input", 3, "ngModelChange", "ngModel"], ["for", "suite-description"], ["id", "suite-description", "rows", "3", "placeholder", "What does this suite cover?", 1, "config-input", "config-textarea", 3, "ngModelChange", "ngModel"], [1, "edit-field"], ["for", "suite-status"], [1, "select-wrapper"], ["id", "suite-status", 1, "config-input", 3, "ngModelChange", "ngModel"], [3, "ngValue"], ["for", "suite-parent"], ["id", "suite-parent", 1, "config-input", 3, "ngModelChange", "ngModel"], ["for", "suite-tags"], [1, "tag-editor", 3, "click"], [1, "tag-chip-editable"], ["id", "suite-tags", "type", "text", 1, "tag-input-inline", 3, "ngModelChange", "keydown", "blur", "placeholder", "ngModel"], [1, "config-hint"], [1, "fas", "fa-cogs"], ["for", "suite-timeout"], ["id", "suite-timeout", "type", "number", "placeholder", "Default: 300000 (5 min)", 1, "config-input", 3, "ngModelChange", "ngModel"], [1, "meta-section"], [1, "meta-grid"], [1, "meta-item"], [1, "meta-label"], [1, "meta-value"], [1, "meta-value", "meta-mono"], ["type", "button", 1, "tag-remove", 3, "click"], [1, "fas", "fa-times"], [1, "tests-actionbar"], [1, "tests-actionbar-text"], [1, "tests-actionbar-count"], [1, "tests-actionbar-hint"], [1, "tests-actionbar-actions"], ["mjButton", "", "variant", "primary", 3, "click", "disabled"], [1, "fas", "fa-plus"], [1, "loading-state"], ["cdkDropList", "", 1, "tests-list"], ["Icon", "fa-solid fa-flask", "Title", "No Tests in Suite", "Message", "Add tests to this suite to start running them together.", "ActionText", "Add tests", "ActionIcon", "fa-solid fa-plus"], [1, "skeleton-list"], [1, "skeleton-card"], [1, "skeleton-sequence"], [1, "skeleton-icon"], [1, "skeleton-content"], [1, "skeleton-line", "wide"], [1, "skeleton-line", "narrow"], ["cdkDropList", "", 1, "tests-list", 3, "cdkDropListDropped"], ["cdkDrag", "", 1, "test-item", 3, "cdkDragDisabled"], ["cdkDragHandle", "", "title", "Drag to reorder", "aria-label", "Drag to reorder", 1, "test-drag-handle"], [1, "fas", "fa-grip-vertical"], [1, "test-sequence"], [1, "test-icon"], [1, "test-content", 3, "click"], [1, "test-name"], [1, "test-status"], [1, "test-remove-confirm"], [1, "fas", "fa-info-circle"], [1, "test-remove-confirm", 3, "click"], [1, "test-remove-confirm-text"], ["type", "button", 1, "test-remove-confirm-btn", "test-remove-confirm-btn--danger", 3, "click", "disabled"], [1, "fas", "fa-spinner", "fa-spin"], ["type", "button", 1, "test-remove-confirm-btn", "test-remove-confirm-btn--ghost", 3, "click", "disabled"], ["type", "button", "title", "Remove from suite", "aria-label", "Remove from suite", 1, "test-remove-btn", 3, "click"], [1, "fas", "fa-chevron-right", "test-chevron", 3, "click"], ["Icon", "fa-solid fa-flask", "Title", "No Tests in Suite", "Message", "Add tests to this suite to start running them together.", "ActionText", "Add tests", "ActionIcon", "fa-solid fa-plus", 3, "Action"], [1, "runs-list"], ["Icon", "fa-solid fa-circle-play", "Title", "No Suite Runs Yet", "Message", "Run this suite to see execution history and results here.", "ActionText", "Run Suite Now", "ActionIcon", "fa-solid fa-play"], [1, "run-item"], [1, "run-item", 3, "click"], [1, "run-icon"], [1, "fas"], [1, "run-content"], [1, "run-header"], [1, "run-id"], [1, "run-status"], [1, "run-meta"], [1, "fas", "fa-calendar"], [1, "run-eval-metrics"], [1, "eval-metric", "status", 3, "class"], ["title", "Human evaluation", 1, "eval-metric", "human"], ["title", "Auto score (pass rate)", 1, "eval-metric", "auto", 3, "high", "medium", "low"], [1, "run-tags"], [1, "fas", "fa-chevron-right"], [1, "fas", "fa-check-circle"], [1, "eval-metric", "status"], [1, "fas", "fa-user"], [1, "eval-pending"], [1, "fas", "fa-clock"], ["title", "Auto score (pass rate)", 1, "eval-metric", "auto"], [1, "fas", "fa-robot"], [1, "tag-chip"], ["Icon", "fa-solid fa-circle-play", "Title", "No Suite Runs Yet", "Message", "Run this suite to see execution history and results here.", "ActionText", "Run Suite Now", "ActionIcon", "fa-solid fa-play", 3, "Action"], ["Icon", "fa-solid fa-chart-line", "Title", "No Analytics Data", "Message", "Run this suite to start collecting analytics data.", "ActionText", "Run Suite Now", "ActionIcon", "fa-solid fa-play"], ["text", "Loading analytics data..."], [1, "analytics-subnav"], [1, "subnav-tabs"], [1, "subnav-tab", 3, "click"], [1, "fas", "fa-chart-bar"], [1, "fas", "fa-th"], [1, "fas", "fa-project-diagram"], ["Size", "sm", 3, "ExpandedChange", "FlushBody", "Expanded"], ["mjAccordionTitle", ""], ["mjAccordionBody", ""], [1, "fas", "fa-filter", 2, "color", "var(--test-primary)"], [1, "mj-accordion-badge", "mj-accordion-badge--right", "mj-accordion-badge--muted"], [1, "filters-content"], [1, "filter-group"], [1, "filter-buttons"], [1, "filter-btn", 3, "click"], [1, "filter-hint"], [1, "filter-buttons", "tag-filters"], [1, "filter-btn", "tag-btn", "all-tags-btn", 3, "click"], [1, "filter-btn", "tag-btn", 3, "active"], [1, "filter-btn", "tag-btn", 3, "click"], [1, "fas", "fa-check"], [1, "analytics-kpis"], [1, "kpi-card"], [1, "kpi-icon"], [1, "fas", "fa-play-circle"], [1, "kpi-content"], [1, "kpi-value"], [1, "kpi-label"], [1, "kpi-icon", "success"], [1, "kpi-trend", 3, "ngClass"], [1, "kpi-icon", "info"], [1, "kpi-icon", "warning"], [1, "fas", "fa-dollar-sign"], [1, "analytics-table-section"], [1, "fas", "fa-table"], [1, "analytics-table-wrapper"], [1, "analytics-table"], [1, "clickable-row"], ["Variant", "no-results", "Size", "compact", "Title", "No runs match the current filters."], [1, "clickable-row", 3, "click"], [1, "status-chip", 3, "ngClass"], [1, "pass-rate-cell"], [1, "pass-rate-bar", 3, "ngClass"], [1, "tag-cell"], [1, "tag-chip-table"], [1, "tag-more"], [1, "matrix-section"], ["Variant", "no-results", "Icon", "fa-solid fa-table-cells", "Title", "No Matrix Data", "Message", "No suite runs match the current filters."], ["text", "Loading test matrix..."], [1, "matrix-header"], [1, "matrix-header-right"], [1, "matrix-filter-input"], [1, "fas", "fa-search"], ["type", "text", "placeholder", "Filter tests...", 1, "filter-input", 3, "input", "value"], ["title", "Clear filter", 1, "clear-filter-btn"], [1, "matrix-run-count"], ["mjButton", "", "title", "Export matrix to CSV", 3, "click", "disabled"], [1, "fas", "fa-download"], [1, "matrix-scroll-container"], [1, "test-matrix"], ["title", "Sort by sequence", 1, "seq-header", 3, "click"], ["title", "Sort by name", 1, "test-name-header", 3, "click"], [1, "run-header", 3, "title"], [1, "spacer-header"], [3, "row-selected"], [1, "totals-row"], [1, "seq-cell", "totals-label"], [1, "test-name-cell", "totals-label"], [1, "result-cell", "totals-cell"], [1, "spacer-cell"], ["title", "Clear filter", 1, "clear-filter-btn", 3, "click"], [1, "run-header", 3, "click", "title"], [1, "run-header-content"], [1, "run-tags-header"], [1, "run-date"], [1, "run-pass-rate", 3, "ngClass"], [1, "tag-chip-header"], [1, "tag-more-header"], [3, "click"], [1, "seq-cell"], [1, "test-name-cell"], [1, "test-name", 3, "title"], [1, "result-cell", 3, "ngClass", "clickable", "cell-not-run", "title"], [1, "result-cell", 3, "click", "ngClass", "title"], [1, "cell-eval-stack"], [1, "cell-not-run-indicator"], [1, "cell-status", 3, "ngClass", "cell-skipped-status", "title"], ["title", "Human Review: No rating submitted yet", 1, "cell-human", "no-feedback"], [1, "cell-human", "has-feedback", 3, "rating-low", "rating-medium", "rating-good", "rating-excellent", "title"], [1, "cell-auto", "has-score", 3, "score-low", "score-medium", "score-good", "score-excellent", "title"], ["title", "Auto Score: No automated score available", 1, "cell-auto", "no-score"], [1, "cell-status", 3, "ngClass", "title"], [1, "fas", "fa-user-slash"], [1, "cell-human", "has-feedback", 3, "title"], [1, "rating-value"], [1, "cell-auto", "has-score", 3, "title"], [1, "score-value"], [1, "fas", "fa-minus"], [1, "cell-eval-stack", "totals-stack"], [1, "totals-status"], [1, "totals-human"], [1, "totals-auto"], [1, "pass-count"], [1, "avg-label"], [1, "count-label"], [1, "chart-section"], ["Variant", "no-results", "Icon", "fa-solid fa-diagram-project", "Title", "No Chart Data", "Message", "No suite runs match the current filters."], ["text", "Loading chart data..."], [1, "chart-header"], [1, "chart-legend"], [1, "legend-item", "chart-passed"], [1, "legend-item", "chart-failed"], [1, "legend-item", "chart-error"], [1, "fas", "fa-exclamation"], [1, "legend-item", "chart-skipped"], [1, "fas", "fa-forward"], [1, "chart-container"], [1, "d3-chart"], [1, "chart-info"], ["Icon", "fa-solid fa-chart-line", "Title", "No Analytics Data", "Message", "Run this suite to start collecting analytics data.", "ActionText", "Run Suite Now", "ActionIcon", "fa-solid fa-play", 3, "Action"], [1, "compare-selection"], [1, "compare-run-selector"], [1, "run-selector-list"], [1, "selected-run-preview"], [1, "compare-vs"], [1, "fas", "fa-exchange-alt"], [1, "compare-results"], ["Icon", "fa-solid fa-scale-balanced", "Title", "Select Two Runs to Compare", "Message", "Choose a baseline run (A) and a comparison run (B) from the lists above to see a detailed side-by-side comparison."], ["Icon", "fa-solid fa-scale-balanced", "Title", "Not Enough Runs to Compare", "Message", "You need at least 2 suite runs to use the comparison feature.", "ActionText", "Run Suite Now", "ActionIcon", "fa-solid fa-play"], [1, "run-selector-item", 3, "selected"], [1, "run-selector-item", 3, "click"], [1, "selector-status"], [1, "selector-content"], [1, "selector-date"], [1, "selector-rate"], [1, "selector-tags"], [1, "tag-mini"], [1, "preview-header"], [1, "preview-label"], [1, "clear-btn", 3, "click"], [1, "preview-details"], [1, "preview-rate"], [1, "run-selector-item", 3, "selected", "disabled"], [1, "compare-summary"], [1, "compare-summary-card"], [1, "summary-label"], [1, "summary-value", 3, "ngClass"], [1, "compare-summary-card", "improved"], [1, "summary-value"], [1, "compare-summary-card", "regressed"], [1, "compare-table-section"], [1, "fas", "fa-list"], [1, "compare-table-wrapper"], [1, "compare-table"], [3, "ngClass"], [1, "status-chip", "status-missing"], [1, "muted"], [1, "change-indicator", "improved"], [1, "change-indicator", "regressed"], [1, "change-indicator", "unchanged"], [1, "fas", "fa-arrow-up"], [1, "fas", "fa-arrow-down"], ["text", "Loading comparison data..."], ["Icon", "fa-solid fa-scale-balanced", "Title", "Not Enough Runs to Compare", "Message", "You need at least 2 suite runs to use the comparison feature.", "ActionText", "Run Suite Now", "ActionIcon", "fa-solid fa-play", 3, "Action"], [1, "shortcuts-header"], ["title", "Hide shortcuts", 1, "shortcuts-close", 3, "click"], [1, "shortcut-list"], [1, "shortcut-item"], [1, "shortcut-keys"], ["Mode", "slide", 3, "Closed", "Title", "Resizable"], [3, "PanelClose", "PanelMode", "selectedTestId", "selectedSuiteId", "runMode"], [1, "picker-backdrop", 3, "click"], ["role", "dialog", "aria-modal", "true", "aria-labelledby", "add-tests-dialog-title", 1, "picker-dialog", 3, "click"], [1, "picker-header"], ["id", "add-tests-dialog-title", 1, "picker-title"], [1, "fas", "fa-plus-circle"], ["type", "button", "aria-label", "Close", 1, "picker-close", 3, "click", "disabled"], [1, "picker-search"], [1, "fas", "fa-search", "picker-search-icon"], ["type", "text", "placeholder", "Search tests by name, description, or type...", "autofocus", "", 1, "picker-search-input", 3, "ngModelChange", "ngModel"], ["type", "button", "aria-label", "Clear search", 1, "picker-search-clear"], [1, "picker-toolbar"], [1, "picker-toolbar-status"], [1, "picker-toolbar-actions"], ["type", "button", 1, "picker-link-btn", 3, "click", "disabled"], [1, "picker-body"], [1, "picker-loading"], [1, "picker-list"], [1, "picker-footer"], ["type", "button", 1, "picker-btn", "picker-btn--primary", 3, "click", "disabled"], ["type", "button", 1, "picker-btn", "picker-btn--ghost", 3, "click", "disabled"], ["type", "button", "aria-label", "Clear search", 1, "picker-search-clear", 3, "click"], ["text", "Loading tests..."], ["Variant", "success", "Size", "compact", "Title", "Everything's already in the suite", "Message", "This suite contains every available test. Create a new test first to add more."], ["Variant", "no-results", "Size", "compact", "Title", "No matches", 3, "Message"], ["role", "checkbox", "tabindex", "0", 1, "picker-row", 3, "picker-row--selected"], ["role", "checkbox", "tabindex", "0", 1, "picker-row", 3, "click"], [1, "picker-check"], [1, "picker-row-main"], [1, "picker-row-name"], [1, "picker-row-desc"], [1, "picker-row-meta"], [1, "picker-row-pill"], [1, "picker-row-pill", "picker-row-pill--status"], [1, "save-bar-kbd"]], template: function MJTestSuiteFormComponentExtended_Template(rf, ctx) { if (rf & 1) {
4838
+ } }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 87, vars: 51, consts: [["tagInput", ""], ["chartContainer", ""], ["pickerSearch", ""], [1, "test-suite-form"], [1, "suite-header"], ["aria-label", "Breadcrumb", 1, "breadcrumb"], ["href", "javascript:void(0)", 3, "click"], [1, "fas", "fa-vial"], [1, "breadcrumb-text"], [1, "current"], [1, "fas", "fa-chevron-right", "separator"], [1, "fas", "fa-layer-group"], [1, "header-content"], [1, "header-left"], [1, "suite-icon"], [1, "suite-info"], ["title", "You have unsaved changes", "aria-label", "Unsaved changes", 1, "dirty-indicator"], [1, "suite-meta"], [1, "status-badge", 3, "ngClass"], [1, "fas", 3, "ngClass"], [1, "test-count"], ["title", "You have unsaved changes", 1, "unsaved-pill"], [1, "header-actions"], ["mjButton", "", "title", "Export to CSV", 3, "click"], [1, "fas", "fa-file-excel"], ["mjButton", "", "variant", "primary", 3, "click"], [1, "fas", "fa-play"], ["mjButton", "", 3, "click", "disabled"], [1, "suite-description"], [1, "tabs-container"], ["role", "tablist", 1, "tabs"], ["role", "tab", 1, "tab", 3, "click"], [1, "fas", "fa-th-large"], [1, "fas", "fa-flask"], [1, "tab-badge"], [1, "fas", "fa-history"], [1, "fas", "fa-chart-line"], [1, "fas", "fa-balance-scale"], [1, "tab-content"], [1, "overview-tab"], [1, "tests-tab"], [1, "runs-tab"], [1, "analytics-tab"], [1, "compare-tab"], [1, "shortcuts-toggle", 3, "click", "title"], [1, "fas", "fa-keyboard"], [1, "keyboard-shortcuts"], ["Mode", "slide", 3, "Title", "Resizable"], ["role", "region", "aria-label", "Unsaved changes", 1, "save-bar"], [1, "save-bar-message"], ["aria-hidden", "true", 1, "save-bar-dot"], [1, "save-bar-text"], [1, "save-bar-fields"], [1, "save-bar-actions"], ["type", "button", "title", "Save changes (\u2318S)", 1, "save-bar-btn", "save-bar-btn--primary", 3, "click", "disabled"], ["type", "button", "title", "Discard changes", 1, "save-bar-btn", "save-bar-btn--ghost", 3, "click", "disabled"], [1, "fas", "fa-undo"], [1, "fas", "fa-circle"], [1, "edit-section"], [1, "edit-section-header"], [1, "fas", "fa-pen-to-square"], [1, "edit-section-sub"], [1, "edit-grid"], [1, "edit-field", "edit-field--full"], ["for", "suite-name"], [1, "required"], ["id", "suite-name", "type", "text", "placeholder", "e.g., Core Agent Test Suite", 1, "config-input", 3, "ngModelChange", "ngModel"], ["for", "suite-description"], ["id", "suite-description", "rows", "3", "placeholder", "What does this suite cover?", 1, "config-input", "config-textarea", 3, "ngModelChange", "ngModel"], [1, "edit-field"], ["for", "suite-status"], [1, "select-wrapper"], ["id", "suite-status", 1, "config-input", 3, "ngModelChange", "ngModel"], [3, "ngValue"], ["for", "suite-rubric"], ["id", "suite-rubric", 1, "config-input", 3, "ngModelChange", "ngModel"], ["for", "suite-parent"], ["id", "suite-parent", 1, "config-input", 3, "ngModelChange", "ngModel"], ["for", "suite-tags"], [1, "tag-editor", 3, "click"], [1, "tag-chip-editable"], ["id", "suite-tags", "type", "text", 1, "tag-input-inline", 3, "ngModelChange", "keydown", "blur", "placeholder", "ngModel"], [1, "config-hint"], [1, "fas", "fa-cogs"], ["for", "suite-timeout"], ["id", "suite-timeout", "type", "number", "placeholder", "Default: 300000 (5 min)", 1, "config-input", 3, "ngModelChange", "ngModel"], [1, "meta-section"], [1, "meta-grid"], [1, "meta-item"], [1, "meta-label"], [1, "meta-value"], [1, "meta-value", "meta-mono"], ["type", "button", 1, "tag-remove", 3, "click"], [1, "fas", "fa-times"], [1, "tests-actionbar"], [1, "tests-actionbar-text"], [1, "tests-actionbar-count"], [1, "tests-actionbar-hint"], [1, "tests-actionbar-actions"], ["mjButton", "", "variant", "primary", 3, "click", "disabled"], [1, "fas", "fa-plus"], [1, "loading-state"], ["cdkDropList", "", 1, "tests-list"], ["Icon", "fa-solid fa-flask", "Title", "No Tests in Suite", "Message", "Add tests to this suite to start running them together.", "ActionText", "Add tests", "ActionIcon", "fa-solid fa-plus"], [1, "skeleton-list"], [1, "skeleton-card"], [1, "skeleton-sequence"], [1, "skeleton-icon"], [1, "skeleton-content"], [1, "skeleton-line", "wide"], [1, "skeleton-line", "narrow"], ["cdkDropList", "", 1, "tests-list", 3, "cdkDropListDropped"], ["cdkDrag", "", 1, "test-item", 3, "cdkDragDisabled"], ["cdkDragHandle", "", "title", "Drag to reorder", "aria-label", "Drag to reorder", 1, "test-drag-handle"], [1, "fas", "fa-grip-vertical"], [1, "test-sequence"], [1, "test-icon"], [1, "test-content", 3, "click"], [1, "test-name"], [1, "test-status"], [1, "test-remove-confirm"], [1, "fas", "fa-info-circle"], [1, "test-remove-confirm", 3, "click"], [1, "test-remove-confirm-text"], ["type", "button", 1, "test-remove-confirm-btn", "test-remove-confirm-btn--danger", 3, "click", "disabled"], [1, "fas", "fa-spinner", "fa-spin"], ["type", "button", 1, "test-remove-confirm-btn", "test-remove-confirm-btn--ghost", 3, "click", "disabled"], ["type", "button", "title", "Remove from suite", "aria-label", "Remove from suite", 1, "test-remove-btn", 3, "click"], [1, "fas", "fa-chevron-right", "test-chevron", 3, "click"], ["Icon", "fa-solid fa-flask", "Title", "No Tests in Suite", "Message", "Add tests to this suite to start running them together.", "ActionText", "Add tests", "ActionIcon", "fa-solid fa-plus", 3, "Action"], [1, "runs-list"], ["Icon", "fa-solid fa-circle-play", "Title", "No Suite Runs Yet", "Message", "Run this suite to see execution history and results here.", "ActionText", "Run Suite Now", "ActionIcon", "fa-solid fa-play"], [1, "run-item"], [1, "run-item", 3, "click"], [1, "run-icon"], [1, "fas"], [1, "run-content"], [1, "run-header"], [1, "run-id"], [1, "run-status"], [1, "run-meta"], [1, "fas", "fa-calendar"], [1, "run-eval-metrics"], [1, "eval-metric", "status", 3, "class"], ["title", "Human evaluation", 1, "eval-metric", "human"], ["title", "Auto score (pass rate)", 1, "eval-metric", "auto", 3, "high", "medium", "low"], [1, "run-tags"], [1, "fas", "fa-chevron-right"], [1, "fas", "fa-check-circle"], [1, "eval-metric", "status"], [1, "fas", "fa-user"], [1, "eval-pending"], [1, "fas", "fa-clock"], ["title", "Auto score (pass rate)", 1, "eval-metric", "auto"], [1, "fas", "fa-robot"], [1, "tag-chip"], ["Icon", "fa-solid fa-circle-play", "Title", "No Suite Runs Yet", "Message", "Run this suite to see execution history and results here.", "ActionText", "Run Suite Now", "ActionIcon", "fa-solid fa-play", 3, "Action"], ["Icon", "fa-solid fa-chart-line", "Title", "No Analytics Data", "Message", "Run this suite to start collecting analytics data.", "ActionText", "Run Suite Now", "ActionIcon", "fa-solid fa-play"], ["text", "Loading analytics data..."], [1, "analytics-subnav"], [1, "subnav-tabs"], [1, "subnav-tab", 3, "click"], [1, "fas", "fa-chart-bar"], [1, "fas", "fa-th"], [1, "fas", "fa-project-diagram"], ["Size", "sm", 3, "ExpandedChange", "FlushBody", "Expanded"], ["mjAccordionTitle", ""], ["mjAccordionBody", ""], [1, "fas", "fa-filter", 2, "color", "var(--test-primary)"], [1, "mj-accordion-badge", "mj-accordion-badge--right", "mj-accordion-badge--muted"], [1, "filters-content"], [1, "filter-group"], [1, "filter-buttons"], [1, "filter-btn", 3, "click"], [1, "filter-hint"], [1, "filter-buttons", "tag-filters"], [1, "filter-btn", "tag-btn", "all-tags-btn", 3, "click"], [1, "filter-btn", "tag-btn", 3, "active"], [1, "filter-btn", "tag-btn", 3, "click"], [1, "fas", "fa-check"], [1, "analytics-kpis"], [1, "kpi-card"], [1, "kpi-icon"], [1, "fas", "fa-play-circle"], [1, "kpi-content"], [1, "kpi-value"], [1, "kpi-label"], [1, "kpi-icon", "success"], [1, "kpi-trend", 3, "ngClass"], [1, "kpi-icon", "info"], [1, "kpi-icon", "warning"], [1, "fas", "fa-dollar-sign"], [1, "analytics-table-section"], [1, "fas", "fa-table"], [1, "analytics-table-wrapper"], [1, "analytics-table"], [1, "clickable-row"], ["Variant", "no-results", "Size", "compact", "Title", "No runs match the current filters."], [1, "clickable-row", 3, "click"], [1, "status-chip", 3, "ngClass"], [1, "pass-rate-cell"], [1, "pass-rate-bar", 3, "ngClass"], [1, "tag-cell"], [1, "tag-chip-table"], [1, "tag-more"], [1, "matrix-section"], ["Variant", "no-results", "Icon", "fa-solid fa-table-cells", "Title", "No Matrix Data", "Message", "No suite runs match the current filters."], ["text", "Loading test matrix..."], [1, "matrix-header"], [1, "matrix-header-right"], [1, "matrix-filter-input"], [1, "fas", "fa-search"], ["type", "text", "placeholder", "Filter tests...", 1, "filter-input", 3, "input", "value"], ["title", "Clear filter", 1, "clear-filter-btn"], [1, "matrix-run-count"], ["mjButton", "", "title", "Export matrix to CSV", 3, "click", "disabled"], [1, "fas", "fa-download"], [1, "matrix-scroll-container"], [1, "test-matrix"], ["title", "Sort by sequence", 1, "seq-header", 3, "click"], ["title", "Sort by name", 1, "test-name-header", 3, "click"], [1, "run-header", 3, "title"], [1, "spacer-header"], [3, "row-selected"], [1, "totals-row"], [1, "seq-cell", "totals-label"], [1, "test-name-cell", "totals-label"], [1, "result-cell", "totals-cell"], [1, "spacer-cell"], ["title", "Clear filter", 1, "clear-filter-btn", 3, "click"], [1, "run-header", 3, "click", "title"], [1, "run-header-content"], [1, "run-tags-header"], [1, "run-date"], [1, "run-pass-rate", 3, "ngClass"], [1, "tag-chip-header"], [1, "tag-more-header"], [3, "click"], [1, "seq-cell"], [1, "test-name-cell"], [1, "test-name", 3, "title"], [1, "result-cell", 3, "ngClass", "clickable", "cell-not-run", "title"], [1, "result-cell", 3, "click", "ngClass", "title"], [1, "cell-eval-stack"], [1, "cell-not-run-indicator"], [1, "cell-status", 3, "ngClass", "cell-skipped-status", "title"], ["title", "Human Review: No rating submitted yet", 1, "cell-human", "no-feedback"], [1, "cell-human", "has-feedback", 3, "rating-low", "rating-medium", "rating-good", "rating-excellent", "title"], [1, "cell-auto", "has-score", 3, "score-low", "score-medium", "score-good", "score-excellent", "title"], ["title", "Auto Score: No automated score available", 1, "cell-auto", "no-score"], [1, "cell-status", 3, "ngClass", "title"], [1, "fas", "fa-user-slash"], [1, "cell-human", "has-feedback", 3, "title"], [1, "rating-value"], [1, "cell-auto", "has-score", 3, "title"], [1, "score-value"], [1, "fas", "fa-minus"], [1, "cell-eval-stack", "totals-stack"], [1, "totals-status"], [1, "totals-human"], [1, "totals-auto"], [1, "pass-count"], [1, "avg-label"], [1, "count-label"], [1, "chart-section"], ["Variant", "no-results", "Icon", "fa-solid fa-diagram-project", "Title", "No Chart Data", "Message", "No suite runs match the current filters."], ["text", "Loading chart data..."], [1, "chart-header"], [1, "chart-legend"], [1, "legend-item", "chart-passed"], [1, "legend-item", "chart-failed"], [1, "legend-item", "chart-error"], [1, "fas", "fa-exclamation"], [1, "legend-item", "chart-skipped"], [1, "fas", "fa-forward"], [1, "chart-container"], [1, "d3-chart"], [1, "chart-info"], ["Icon", "fa-solid fa-chart-line", "Title", "No Analytics Data", "Message", "Run this suite to start collecting analytics data.", "ActionText", "Run Suite Now", "ActionIcon", "fa-solid fa-play", 3, "Action"], [1, "compare-selection"], [1, "compare-run-selector"], [1, "run-selector-list"], [1, "selected-run-preview"], [1, "compare-vs"], [1, "fas", "fa-exchange-alt"], [1, "compare-results"], ["Icon", "fa-solid fa-scale-balanced", "Title", "Select Two Runs to Compare", "Message", "Choose a baseline run (A) and a comparison run (B) from the lists above to see a detailed side-by-side comparison."], ["Icon", "fa-solid fa-scale-balanced", "Title", "Not Enough Runs to Compare", "Message", "You need at least 2 suite runs to use the comparison feature.", "ActionText", "Run Suite Now", "ActionIcon", "fa-solid fa-play"], [1, "run-selector-item", 3, "selected"], [1, "run-selector-item", 3, "click"], [1, "selector-status"], [1, "selector-content"], [1, "selector-date"], [1, "selector-rate"], [1, "selector-tags"], [1, "tag-mini"], [1, "preview-header"], [1, "preview-label"], [1, "clear-btn", 3, "click"], [1, "preview-details"], [1, "preview-rate"], [1, "run-selector-item", 3, "selected", "disabled"], [1, "compare-summary"], [1, "compare-summary-card"], [1, "summary-label"], [1, "summary-value", 3, "ngClass"], [1, "compare-summary-card", "improved"], [1, "summary-value"], [1, "compare-summary-card", "regressed"], [1, "compare-table-section"], [1, "fas", "fa-list"], [1, "compare-table-wrapper"], [1, "compare-table"], [3, "ngClass"], [1, "status-chip", "status-missing"], [1, "muted"], [1, "change-indicator", "improved"], [1, "change-indicator", "regressed"], [1, "change-indicator", "unchanged"], [1, "fas", "fa-arrow-up"], [1, "fas", "fa-arrow-down"], ["text", "Loading comparison data..."], ["Icon", "fa-solid fa-scale-balanced", "Title", "Not Enough Runs to Compare", "Message", "You need at least 2 suite runs to use the comparison feature.", "ActionText", "Run Suite Now", "ActionIcon", "fa-solid fa-play", 3, "Action"], [1, "shortcuts-header"], ["title", "Hide shortcuts", 1, "shortcuts-close", 3, "click"], [1, "shortcut-list"], [1, "shortcut-item"], [1, "shortcut-keys"], ["Mode", "slide", 3, "Closed", "Title", "Resizable"], [3, "PanelClose", "PanelMode", "selectedTestId", "selectedSuiteId", "runMode"], [1, "picker-backdrop", 3, "click"], ["role", "dialog", "aria-modal", "true", "aria-labelledby", "add-tests-dialog-title", 1, "picker-dialog", 3, "click"], [1, "picker-header"], ["id", "add-tests-dialog-title", 1, "picker-title"], [1, "fas", "fa-plus-circle"], ["type", "button", "aria-label", "Close", 1, "picker-close", 3, "click", "disabled"], [1, "picker-search"], [1, "fas", "fa-search", "picker-search-icon"], ["type", "text", "placeholder", "Search tests by name, description, or type...", "autofocus", "", 1, "picker-search-input", 3, "ngModelChange", "ngModel"], ["type", "button", "aria-label", "Clear search", 1, "picker-search-clear"], [1, "picker-toolbar"], [1, "picker-toolbar-status"], [1, "picker-toolbar-actions"], ["type", "button", 1, "picker-link-btn", 3, "click", "disabled"], [1, "picker-body"], [1, "picker-loading"], [1, "picker-list"], [1, "picker-footer"], ["type", "button", 1, "picker-btn", "picker-btn--primary", 3, "click", "disabled"], ["type", "button", 1, "picker-btn", "picker-btn--ghost", 3, "click", "disabled"], ["type", "button", "aria-label", "Clear search", 1, "picker-search-clear", 3, "click"], ["text", "Loading tests..."], ["Variant", "success", "Size", "compact", "Title", "Everything's already in the suite", "Message", "This suite contains every available test. Create a new test first to add more."], ["Variant", "no-results", "Size", "compact", "Title", "No matches", 3, "Message"], ["role", "checkbox", "tabindex", "0", 1, "picker-row", 3, "picker-row--selected"], ["role", "checkbox", "tabindex", "0", 1, "picker-row", 3, "click"], [1, "picker-check"], [1, "picker-row-main"], [1, "picker-row-name"], [1, "picker-row-desc"], [1, "picker-row-meta"], [1, "picker-row-pill"], [1, "picker-row-pill", "picker-row-pill--status"], [1, "save-bar-kbd"]], template: function MJTestSuiteFormComponentExtended_Template(rf, ctx) { if (rf & 1) {
4799
4839
  i0.ɵɵelementStart(0, "div", 3)(1, "div", 4)(2, "nav", 5)(3, "ol")(4, "li")(5, "a", 6);
4800
4840
  i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Template_a_click_5_listener() { return ctx.navigateToTestingDashboard(); });
4801
4841
  i0.ɵɵelement(6, "i", 7);
@@ -4868,7 +4908,7 @@ let MJTestSuiteFormComponentExtended = class MJTestSuiteFormComponentExtended ex
4868
4908
  i0.ɵɵtext(58, " Compare ");
4869
4909
  i0.ɵɵelementEnd()()();
4870
4910
  i0.ɵɵelementStart(59, "div", 38);
4871
- i0.ɵɵconditionalCreate(60, MJTestSuiteFormComponentExtended_Conditional_60_Template, 75, 18, "div", 39);
4911
+ i0.ɵɵconditionalCreate(60, MJTestSuiteFormComponentExtended_Conditional_60_Template, 83, 20, "div", 39);
4872
4912
  i0.ɵɵconditionalCreate(61, MJTestSuiteFormComponentExtended_Conditional_61_Template, 15, 5, "div", 40);
4873
4913
  i0.ɵɵconditionalCreate(62, MJTestSuiteFormComponentExtended_Conditional_62_Template, 4, 3, "div", 41);
4874
4914
  i0.ɵɵconditionalCreate(63, MJTestSuiteFormComponentExtended_Conditional_63_Template, 4, 3, "div", 42);
@@ -4986,7 +5026,7 @@ MJTestSuiteFormComponentExtended = __decorate([
4986
5026
  export { MJTestSuiteFormComponentExtended };
4987
5027
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MJTestSuiteFormComponentExtended, [{
4988
5028
  type: Component,
4989
- args: [{ standalone: false, selector: 'mj-test-suite-form', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"test-suite-form\">\n <!-- Header Section -->\n <div class=\"suite-header\">\n <!-- Breadcrumb Navigation -->\n <nav class=\"breadcrumb\" aria-label=\"Breadcrumb\">\n <ol>\n <li>\n <a href=\"javascript:void(0)\" (click)=\"navigateToTestingDashboard()\">\n <i class=\"fas fa-vial\"></i>\n <span class=\"breadcrumb-text\">Testing</span>\n </a>\n </li>\n <li class=\"current\">\n <i class=\"fas fa-chevron-right separator\"></i>\n <i class=\"fas fa-layer-group\"></i>\n <span>{{ record.Name }}</span>\n </li>\n </ol>\n </nav>\n\n <div class=\"header-content\">\n <div class=\"header-left\">\n <div class=\"suite-icon\" [style.background-color]=\"getStatusColor()\">\n <i class=\"fas fa-layer-group\"></i>\n </div>\n <div class=\"suite-info\">\n <h1>\n {{ record.Name }}\n @if (isDirty) {\n <span class=\"dirty-indicator\" title=\"You have unsaved changes\" aria-label=\"Unsaved changes\">\u25CF</span>\n }\n </h1>\n <div class=\"suite-meta\">\n <span class=\"status-badge\" [ngClass]=\"getStatusClass()\">\n <i class=\"fas\" [ngClass]=\"record.Status === 'Active' ? 'fa-circle-check' : 'fa-circle-pause'\"></i>\n {{ record.Status }}\n </span>\n @if (testsLoaded) {\n <span class=\"test-count\">\n <i class=\"fas fa-flask\"></i>\n {{ suiteTests.length }} tests\n </span>\n }\n @if (isDirty) {\n <span class=\"unsaved-pill\" title=\"You have unsaved changes\">\n <i class=\"fas fa-circle\"></i> Unsaved\n </span>\n }\n </div>\n </div>\n </div>\n <div class=\"header-actions\">\n <app-evaluation-mode-toggle></app-evaluation-mode-toggle>\n <button mjButton (click)=\"exportToExcel()\" title=\"Export to CSV\">\n <i class=\"fas fa-file-excel\"></i> Export\n </button>\n <button mjButton (click)=\"runSuite()\" variant=\"primary\">\n <i class=\"fas fa-play\"></i> Run Suite\n </button>\n <button mjButton (click)=\"refresh()\" [disabled]=\"isRefreshing\">\n <i class=\"fas\" [ngClass]=\"isRefreshing ? 'fa-sync fa-spin' : 'fa-sync'\"></i>\n {{ isRefreshing ? 'Refreshing...' : 'Refresh' }}\n </button>\n </div>\n </div>\n @if (record.Description) {\n <div class=\"suite-description\">\n <p>{{ record.Description }}</p>\n </div>\n }\n </div>\n\n <!-- Tabs -->\n <div class=\"tabs-container\">\n <div class=\"tabs\" role=\"tablist\">\n <button class=\"tab\"\n [class.active]=\"activeTab === 'overview'\"\n (click)=\"changeTab('overview')\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'overview'\">\n <i class=\"fas fa-th-large\"></i> Overview\n </button>\n <button class=\"tab\"\n [class.active]=\"activeTab === 'tests'\"\n (click)=\"changeTab('tests')\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'tests'\">\n <i class=\"fas fa-flask\"></i> Tests\n @if (testsLoaded) {\n <span class=\"tab-badge\">{{ suiteTests.length }}</span>\n }\n </button>\n <button class=\"tab\"\n [class.active]=\"activeTab === 'runs'\"\n (click)=\"changeTab('runs')\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'runs'\">\n <i class=\"fas fa-history\"></i> Runs\n @if (runsLoaded) {\n <span class=\"tab-badge\">{{ suiteRuns.length }}</span>\n }\n </button>\n <button class=\"tab\"\n [class.active]=\"activeTab === 'analytics'\"\n (click)=\"changeTab('analytics')\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'analytics'\">\n <i class=\"fas fa-chart-line\"></i> Analytics\n </button>\n <button class=\"tab\"\n [class.active]=\"activeTab === 'compare'\"\n (click)=\"changeTab('compare')\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'compare'\">\n <i class=\"fas fa-balance-scale\"></i> Compare\n </button>\n </div>\n </div>\n\n <!-- Tab Content -->\n <div class=\"tab-content\" [class.has-savebar]=\"isDirty\">\n <!-- Overview Tab -->\n @if (activeTab === 'overview') {\n <div class=\"overview-tab\">\n <!-- Editable Details -->\n <section class=\"edit-section\">\n <header class=\"edit-section-header\">\n <h3><i class=\"fas fa-pen-to-square\"></i> Details</h3>\n <p class=\"edit-section-sub\">Edit any field \u2014 changes are saved with the bar at the bottom.</p>\n </header>\n <div class=\"edit-grid\">\n <div class=\"edit-field edit-field--full\">\n <label for=\"suite-name\">Name <span class=\"required\">*</span></label>\n <input\n id=\"suite-name\"\n type=\"text\"\n class=\"config-input\"\n placeholder=\"e.g., Core Agent Test Suite\"\n [(ngModel)]=\"record.Name\"\n />\n </div>\n\n <div class=\"edit-field edit-field--full\">\n <label for=\"suite-description\">Description</label>\n <textarea\n id=\"suite-description\"\n class=\"config-input config-textarea\"\n rows=\"3\"\n placeholder=\"What does this suite cover?\"\n [ngModel]=\"record.Description\"\n (ngModelChange)=\"record.Description = $event || null\"\n ></textarea>\n </div>\n\n <div class=\"edit-field\">\n <label for=\"suite-status\">Status</label>\n <div class=\"select-wrapper\">\n <select\n id=\"suite-status\"\n class=\"config-input\"\n [(ngModel)]=\"record.Status\"\n >\n @for (opt of statusOptions; track opt) {\n <option [ngValue]=\"opt\">{{ opt }}</option>\n }\n </select>\n </div>\n </div>\n\n <div class=\"edit-field\">\n <label for=\"suite-parent\">Parent Suite</label>\n <select\n id=\"suite-parent\"\n class=\"config-input\"\n [ngModel]=\"record.ParentID\"\n (ngModelChange)=\"record.ParentID = $event || null\"\n >\n <option [ngValue]=\"null\">\u2014 None (top-level) \u2014</option>\n @for (s of parentSuiteOptions; track s.ID) {\n <option [ngValue]=\"s.ID\">{{ s.Name }}</option>\n }\n </select>\n </div>\n\n <div class=\"edit-field edit-field--full\">\n <label for=\"suite-tags\">Tags</label>\n <div class=\"tag-editor\" (click)=\"tagInput.focus()\">\n @for (tag of tags; track tag) {\n <span class=\"tag-chip-editable\">\n {{ tag }}\n <button type=\"button\" class=\"tag-remove\" (click)=\"removeTag(tag); $event.stopPropagation()\" [attr.aria-label]=\"'Remove tag ' + tag\">\n <i class=\"fas fa-times\"></i>\n </button>\n </span>\n }\n <input\n #tagInput\n id=\"suite-tags\"\n type=\"text\"\n class=\"tag-input-inline\"\n [placeholder]=\"tags.length === 0 ? 'Add tags, press Enter or comma...' : ''\"\n [(ngModel)]=\"tagDraft\"\n (keydown)=\"onTagInputKeydown($event)\"\n (blur)=\"addTagFromDraft()\"\n />\n </div>\n <span class=\"config-hint\">Press Enter or comma to add a tag. Backspace on empty input removes the last tag.</span>\n </div>\n </div>\n </section>\n\n <!-- Execution Settings -->\n <section class=\"edit-section\">\n <header class=\"edit-section-header\">\n <h3><i class=\"fas fa-cogs\"></i> Execution Settings</h3>\n </header>\n <div class=\"edit-grid\">\n <div class=\"edit-field\">\n <label for=\"suite-timeout\">Max Execution Time (ms)</label>\n <input\n id=\"suite-timeout\"\n type=\"number\"\n class=\"config-input\"\n placeholder=\"Default: 300000 (5 min)\"\n [ngModel]=\"record.MaxExecutionTimeMS\"\n (ngModelChange)=\"record.MaxExecutionTimeMS = $event === '' || $event === null ? null : +$event\"\n />\n <span class=\"config-hint\">Default timeout for tests in this suite. Currently: {{ formatTimeout(record.MaxExecutionTimeMS) }}</span>\n </div>\n </div>\n </section>\n\n <!-- Metadata (read-only) -->\n <section class=\"meta-section\">\n <div class=\"meta-grid\">\n <div class=\"meta-item\">\n <div class=\"meta-label\">Created</div>\n <div class=\"meta-value\">{{ record.__mj_CreatedAt | date:'medium' }}</div>\n </div>\n <div class=\"meta-item\">\n <div class=\"meta-label\">Last updated</div>\n <div class=\"meta-value\">{{ record.__mj_UpdatedAt | date:'medium' }}</div>\n </div>\n <div class=\"meta-item\">\n <div class=\"meta-label\">Suite ID</div>\n <div class=\"meta-value meta-mono\">{{ record.ID }}</div>\n </div>\n </div>\n </section>\n </div>\n }\n\n <!-- Tests Tab -->\n @if (activeTab === 'tests') {\n <div class=\"tests-tab\">\n <!-- Header: action bar -->\n <div class=\"tests-actionbar\">\n <div class=\"tests-actionbar-text\">\n <strong>Suite tests</strong>\n @if (testsLoaded) {\n <span class=\"tests-actionbar-count\">{{ suiteTests.length }}</span>\n }\n <span class=\"tests-actionbar-hint\">Drag to reorder \u00B7 Hover a row to remove</span>\n </div>\n <div class=\"tests-actionbar-actions\">\n <button mjButton variant=\"primary\" (click)=\"openAddTestsDialog()\" [disabled]=\"isReorderingTests\">\n <i class=\"fas fa-plus\"></i> Add tests\n </button>\n </div>\n </div>\n\n <!-- Loading State -->\n @if (loadingTests) {\n <div class=\"loading-state\">\n <div class=\"skeleton-list\">\n @for (i of [1,2,3,4,5]; track i) {\n <div class=\"skeleton-card\">\n <div class=\"skeleton-sequence\"></div>\n <div class=\"skeleton-icon\"></div>\n <div class=\"skeleton-content\">\n <div class=\"skeleton-line wide\"></div>\n <div class=\"skeleton-line narrow\"></div>\n </div>\n </div>\n }\n </div>\n </div>\n }\n <!-- Tests List -->\n @if (!loadingTests && suiteTests.length > 0) {\n <div class=\"tests-list\" cdkDropList (cdkDropListDropped)=\"onTestDrop($event)\">\n @for (test of suiteTests; track test.ID) {\n <div class=\"test-item\" cdkDrag [cdkDragDisabled]=\"isReorderingTests || isRemovingTest\">\n <span class=\"test-drag-handle\" cdkDragHandle title=\"Drag to reorder\" aria-label=\"Drag to reorder\">\n <i class=\"fas fa-grip-vertical\"></i>\n </span>\n <div class=\"test-sequence\">{{ test.Sequence }}</div>\n <div class=\"test-icon\"><i class=\"fas fa-flask\"></i></div>\n <div class=\"test-content\" (click)=\"openTest(test.TestID)\">\n <div class=\"test-name\">{{ test.Test }}</div>\n <div class=\"test-status\">\n @if (test.Status) {\n <span><i class=\"fas fa-info-circle\"></i> {{ test.Status }}</span>\n }\n </div>\n </div>\n <!-- Inline remove confirm OR hover-reveal X -->\n @if (confirmingRemoveSuiteTestId === test.ID) {\n <div class=\"test-remove-confirm\" (click)=\"$event.stopPropagation()\">\n <span class=\"test-remove-confirm-text\">Remove from suite?</span>\n <button\n type=\"button\"\n class=\"test-remove-confirm-btn test-remove-confirm-btn--danger\"\n (click)=\"confirmRemoveTest(test, $event)\"\n [disabled]=\"isRemovingTest\"\n >\n @if (isRemovingTest) {\n <i class=\"fas fa-spinner fa-spin\"></i>\n } @else {\n Remove\n }\n </button>\n <button\n type=\"button\"\n class=\"test-remove-confirm-btn test-remove-confirm-btn--ghost\"\n (click)=\"cancelRemoveTest($event)\"\n [disabled]=\"isRemovingTest\"\n >\n Cancel\n </button>\n </div>\n } @else {\n <button\n type=\"button\"\n class=\"test-remove-btn\"\n title=\"Remove from suite\"\n aria-label=\"Remove from suite\"\n (click)=\"requestRemoveTest(test, $event)\"\n >\n <i class=\"fas fa-times\"></i>\n </button>\n <i class=\"fas fa-chevron-right test-chevron\" (click)=\"openTest(test.TestID)\"></i>\n }\n </div>\n }\n </div>\n }\n <!-- Empty State -->\n @if (testsLoaded && !loadingTests && suiteTests.length === 0) {\n <mj-empty-state\n Icon=\"fa-solid fa-flask\"\n Title=\"No Tests in Suite\"\n Message=\"Add tests to this suite to start running them together.\"\n ActionText=\"Add tests\"\n ActionIcon=\"fa-solid fa-plus\"\n (Action)=\"openAddTestsDialog()\" />\n }\n </div>\n }\n\n <!-- Runs Tab -->\n @if (activeTab === 'runs') {\n <div class=\"runs-tab\">\n <!-- Loading State -->\n @if (loadingRuns) {\n <div class=\"loading-state\">\n <div class=\"skeleton-list\">\n @for (i of [1,2,3]; track i) {\n <div class=\"skeleton-card\">\n <div class=\"skeleton-icon\"></div>\n <div class=\"skeleton-content\">\n <div class=\"skeleton-line wide\"></div>\n <div class=\"skeleton-line narrow\"></div>\n </div>\n </div>\n }\n </div>\n </div>\n }\n <!-- Runs List -->\n @if (!loadingRuns && suiteRuns.length > 0) {\n <div class=\"runs-list\">\n @for (run of suiteRuns; track run) {\n <div class=\"run-item\" (click)=\"openSuiteRun(run.ID)\">\n <div class=\"run-icon\" [style.background-color]=\"getRunStatusColor(run.Status)\">\n <i class=\"fas\"\n [class.fa-check]=\"run.Status === 'Completed'\"\n [class.fa-times]=\"run.Status === 'Failed'\"\n [class.fa-spinner]=\"run.Status === 'Running'\"\n [class.fa-clock]=\"run.Status === 'Pending'\"\n [class.fa-ban]=\"run.Status === 'Cancelled'\"></i>\n </div>\n <div class=\"run-content\">\n <div class=\"run-header\">\n <span class=\"run-id\">Run #{{ run.ID.substring(0, 8) }}</span>\n <span class=\"run-status\" [style.color]=\"getRunStatusColor(run.Status)\">{{ run.Status }}</span>\n </div>\n <div class=\"run-meta\">\n <span><i class=\"fas fa-calendar\"></i> {{ getRelativeTime(run.StartedAt) }}</span>\n @if (run.TotalTests) {\n <span>\n <i class=\"fas fa-check-circle\"></i> {{ run.PassedTests }}/{{ run.TotalTests }}\n ({{ getPassRate(run).toFixed(0) }}%)\n </span>\n }\n </div>\n <!-- Evaluation metrics row -->\n <div class=\"run-eval-metrics\">\n <!-- Status badge -->\n @if (evalPreferences.showExecution) {\n <span class=\"eval-metric status\" [class]=\"'status-' + run.Status.toLowerCase()\">\n <i class=\"fas\"\n [class.fa-circle-check]=\"run.Status === 'Completed'\"\n [class.fa-circle-xmark]=\"run.Status === 'Failed'\"\n [class.fa-spinner]=\"run.Status === 'Running'\"\n [class.fa-clock]=\"run.Status === 'Pending'\"\n [class.fa-ban]=\"run.Status === 'Cancelled'\"></i>\n </span>\n }\n <!-- Human score (placeholder - need avg from suite run) -->\n @if (evalPreferences.showHuman) {\n <span class=\"eval-metric human\" title=\"Human evaluation\">\n <i class=\"fas fa-user\"></i>\n <span class=\"eval-pending\"><i class=\"fas fa-clock\"></i></span>\n </span>\n }\n <!-- Auto score (pass rate as proxy) -->\n @if (evalPreferences.showAuto && run.TotalTests) {\n <span class=\"eval-metric auto\"\n [class.high]=\"getPassRate(run) >= 80\"\n [class.medium]=\"getPassRate(run) >= 50 && getPassRate(run) < 80\"\n [class.low]=\"getPassRate(run) < 50\"\n title=\"Auto score (pass rate)\">\n <i class=\"fas fa-robot\"></i>\n <span>{{ getPassRate(run).toFixed(0) }}%</span>\n </span>\n }\n </div>\n <!-- Tags display -->\n @if (getRunTags(run).length > 0) {\n <div class=\"run-tags\">\n @for (tag of getRunTags(run); track tag) {\n <span class=\"tag-chip\">{{ tag }}</span>\n }\n </div>\n }\n </div>\n <i class=\"fas fa-chevron-right\"></i>\n </div>\n }\n </div>\n }\n <!-- Empty State -->\n @if (runsLoaded && !loadingRuns && suiteRuns.length === 0) {\n <mj-empty-state\n Icon=\"fa-solid fa-circle-play\"\n Title=\"No Suite Runs Yet\"\n Message=\"Run this suite to see execution history and results here.\"\n ActionText=\"Run Suite Now\"\n ActionIcon=\"fa-solid fa-play\"\n (Action)=\"runSuite()\" />\n }\n </div>\n }\n\n <!-- Analytics Tab -->\n @if (activeTab === 'analytics') {\n <div class=\"analytics-tab\">\n <!-- Loading State -->\n @if (loadingAnalytics) {\n <div class=\"loading-state\">\n <mj-loading text=\"Loading analytics data...\"></mj-loading>\n </div>\n }\n @if (!loadingAnalytics && analyticsLoaded) {\n <!-- View Toggle Sub-nav -->\n <div class=\"analytics-subnav\">\n <div class=\"subnav-tabs\">\n <button class=\"subnav-tab\"\n [class.active]=\"analyticsView === 'summary'\"\n (click)=\"setAnalyticsView('summary')\">\n <i class=\"fas fa-chart-bar\"></i>\n <span>Summary</span>\n </button>\n <button class=\"subnav-tab\"\n [class.active]=\"analyticsView === 'matrix'\"\n (click)=\"setAnalyticsView('matrix')\">\n <i class=\"fas fa-th\"></i>\n <span>Matrix</span>\n </button>\n <button class=\"subnav-tab\"\n [class.active]=\"analyticsView === 'chart'\"\n (click)=\"setAnalyticsView('chart')\">\n <i class=\"fas fa-project-diagram\"></i>\n <span>Chart</span>\n </button>\n </div>\n </div>\n <!-- Collapsible Filters (shared by both views) -->\n <mj-accordion-panel Size=\"sm\" [FlushBody]=\"true\"\n [Expanded]=\"!filtersCollapsed\" (ExpandedChange)=\"onFiltersExpandedChange($event)\">\n <ng-template mjAccordionTitle>\n <i class=\"fas fa-filter\" style=\"color: var(--test-primary);\"></i>\n Filters\n @if (filtersCollapsed) {\n <span class=\"mj-accordion-badge mj-accordion-badge--right mj-accordion-badge--muted\">\n {{ analyticsTimeRange === 'all' ? 'All Time' : analyticsTimeRange }}\n @if (selectedTags.length > 0) {\n <span> \u00B7 {{ selectedTags.length }} tags</span>\n }\n </span>\n }\n </ng-template>\n <ng-template mjAccordionBody>\n <div class=\"filters-content\">\n <div class=\"filter-group\">\n <label>Time Range</label>\n <div class=\"filter-buttons\">\n <button class=\"filter-btn\" [class.active]=\"analyticsTimeRange === '7d'\" (click)=\"setTimeRange('7d')\">7 Days</button>\n <button class=\"filter-btn\" [class.active]=\"analyticsTimeRange === '30d'\" (click)=\"setTimeRange('30d')\">30 Days</button>\n <button class=\"filter-btn\" [class.active]=\"analyticsTimeRange === '90d'\" (click)=\"setTimeRange('90d')\">90 Days</button>\n <button class=\"filter-btn\" [class.active]=\"analyticsTimeRange === 'all'\" (click)=\"setTimeRange('all')\">All Time</button>\n </div>\n </div>\n @if (uniqueTags.length > 0) {\n <div class=\"filter-group\">\n <label>Filter by Tag @if (selectedTags.length > 0) {\n <span class=\"filter-hint\">({{ selectedTags.length }} selected)</span>\n }</label>\n <div class=\"filter-buttons tag-filters\">\n <button class=\"filter-btn tag-btn all-tags-btn\"\n [class.active]=\"selectedTags.length === 0\"\n (click)=\"toggleTagFilter(null)\">\n <i class=\"fas fa-layer-group\"></i> All Tags\n </button>\n @for (tag of uniqueTags; track tag) {\n <button class=\"filter-btn tag-btn\"\n [class.active]=\"isTagSelected(tag)\"\n (click)=\"toggleTagFilter(tag)\">\n @if (isTagSelected(tag)) {\n <i class=\"fas fa-check\"></i>\n }\n {{ tag }}\n </button>\n }\n </div>\n </div>\n }\n </div>\n </ng-template>\n </mj-accordion-panel>\n <!-- Summary View -->\n @if (analyticsView === 'summary') {\n <!-- KPI Cards -->\n <div class=\"analytics-kpis\">\n <div class=\"kpi-card\">\n <div class=\"kpi-icon\"><i class=\"fas fa-play-circle\"></i></div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{ getTotalRuns() }}</div>\n <div class=\"kpi-label\">Total Runs</div>\n </div>\n </div>\n <div class=\"kpi-card\">\n <div class=\"kpi-icon success\"><i class=\"fas fa-check-circle\"></i></div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{ getAveragePassRate().toFixed(1) }}%</div>\n <div class=\"kpi-label\">Avg Pass Rate</div>\n <div class=\"kpi-trend\" [ngClass]=\"{'trend-up': getPassRateTrend().direction === 'up', 'trend-down': getPassRateTrend().direction === 'down'}\">\n <i class=\"fas\" [ngClass]=\"{'fa-arrow-up': getPassRateTrend().direction === 'up', 'fa-arrow-down': getPassRateTrend().direction === 'down', 'fa-minus': getPassRateTrend().direction === 'stable'}\"></i>\n {{ getPassRateTrend().value.toFixed(1) }}%\n </div>\n </div>\n </div>\n <div class=\"kpi-card\">\n <div class=\"kpi-icon info\"><i class=\"fas fa-clock\"></i></div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{ formatDuration(getAverageDuration()) }}</div>\n <div class=\"kpi-label\">Avg Duration</div>\n </div>\n </div>\n <div class=\"kpi-card\">\n <div class=\"kpi-icon warning\"><i class=\"fas fa-dollar-sign\"></i></div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{ formatCost(getTotalCost()) }}</div>\n <div class=\"kpi-label\">Total Cost</div>\n </div>\n </div>\n </div>\n <!-- Runs Table -->\n <div class=\"analytics-table-section\">\n <h3><i class=\"fas fa-table\"></i> Run History</h3>\n <div class=\"analytics-table-wrapper\">\n <table class=\"analytics-table\">\n <thead>\n <tr>\n <th>Date</th>\n <th>Status</th>\n <th>Pass Rate</th>\n <th>Tests</th>\n <th>Duration</th>\n <th>Cost</th>\n <th>Tags</th>\n </tr>\n </thead>\n <tbody>\n @for (dp of getFilteredAnalyticsData(); track dp) {\n <tr (click)=\"openSuiteRun(dp.runId)\" class=\"clickable-row\">\n <td>{{ dp.date | date:'short' }}</td>\n <td>\n <span class=\"status-chip\" [ngClass]=\"'status-' + dp.status.toLowerCase()\">{{ dp.status }}</span>\n </td>\n <td>\n <div class=\"pass-rate-cell\">\n <div class=\"pass-rate-bar\" [style.width.%]=\"dp.passRate\" [ngClass]=\"{'high': dp.passRate >= 80, 'medium': dp.passRate >= 50 && dp.passRate < 80, 'low': dp.passRate < 50}\"></div>\n <span>{{ dp.passRate.toFixed(0) }}%</span>\n </div>\n </td>\n <td>{{ dp.passedTests }}/{{ dp.totalTests }}</td>\n <td>{{ formatDuration(dp.duration) }}</td>\n <td>{{ formatCost(dp.cost) }}</td>\n <td>\n <div class=\"tag-cell\">\n @for (tag of dp.tags.slice(0, 2); track tag) {\n <span class=\"tag-chip-table\">{{ tag }}</span>\n }\n @if (dp.tags.length > 2) {\n <span class=\"tag-more\">+{{ dp.tags.length - 2 }}</span>\n }\n </div>\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n @if (getFilteredAnalyticsData().length === 0) {\n <mj-empty-state\n Variant=\"no-results\"\n Size=\"compact\"\n Title=\"No runs match the current filters.\" />\n }\n </div>\n }\n <!-- Matrix View -->\n @if (analyticsView === 'matrix') {\n <!-- Loading Matrix -->\n @if (loadingMatrix) {\n <div class=\"loading-state\">\n <mj-loading text=\"Loading test matrix...\"></mj-loading>\n </div>\n }\n <!-- Matrix Content -->\n @if (!loadingMatrix && matrixLoaded && matrixData.length > 0) {\n <div class=\"matrix-section\">\n <div class=\"matrix-header\">\n <h3><i class=\"fas fa-th\"></i> Test Results Matrix</h3>\n <div class=\"matrix-header-right\">\n <div class=\"matrix-filter-input\">\n <i class=\"fas fa-search\"></i>\n <input type=\"text\"\n placeholder=\"Filter tests...\"\n [value]=\"matrixTestFilter\"\n (input)=\"onMatrixFilterInput($event)\"\n class=\"filter-input\">\n @if (matrixTestFilter) {\n <button class=\"clear-filter-btn\" (click)=\"clearMatrixFilter()\" title=\"Clear filter\">\n <i class=\"fas fa-times\"></i>\n </button>\n }\n </div>\n <span class=\"matrix-run-count\">{{ matrixData.length }} runs \u00B7 {{ getUniqueTestsFromMatrix().length }} tests</span>\n <button mjButton (click)=\"exportMatrixToCSV()\" [disabled]=\"matrixData.length === 0\" title=\"Export matrix to CSV\">\n <i class=\"fas fa-download\"></i> Export\n </button>\n </div>\n </div>\n <div class=\"matrix-scroll-container\">\n <table class=\"test-matrix\">\n <thead>\n <tr>\n <th class=\"seq-header\" (click)=\"toggleMatrixSort('sequence')\" title=\"Sort by sequence\">\n #\n <i class=\"fas\" [ngClass]=\"matrixSortBy === 'sequence' ? (matrixSortAsc ? 'fa-sort-up' : 'fa-sort-down') : 'fa-sort'\"></i>\n </th>\n <th class=\"test-name-header\" (click)=\"toggleMatrixSort('name')\" title=\"Sort by name\">\n Test\n <i class=\"fas\" [ngClass]=\"matrixSortBy === 'name' ? (matrixSortAsc ? 'fa-sort-up' : 'fa-sort-down') : 'fa-sort'\"></i>\n </th>\n @for (run of matrixData; track run) {\n <th class=\"run-header\" (click)=\"openSuiteRun(run.runId)\" [title]=\"'Click to view suite run - ' + (run.date | date:'medium')\">\n <div class=\"run-header-content\">\n @if (run.tags.length > 0) {\n <div class=\"run-tags-header\">\n @for (tag of run.tags.slice(0, 2); track tag) {\n <span class=\"tag-chip-header\">{{ tag }}</span>\n }\n @if (run.tags.length > 2) {\n <span class=\"tag-more-header\">+{{ run.tags.length - 2 }}</span>\n }\n </div>\n }\n <div class=\"run-date\">{{ getRelativeTime(run.date) }}</div>\n <div class=\"run-pass-rate\" [ngClass]=\"{'high': run.passRate >= 80, 'medium': run.passRate >= 50 && run.passRate < 80, 'low': run.passRate < 50}\">\n {{ run.passRate.toFixed(0) }}%\n </div>\n </div>\n </th>\n }\n <th class=\"spacer-header\"></th>\n </tr>\n </thead>\n <tbody>\n @for (test of getUniqueTestsFromMatrix(); track test) {\n <tr\n [class.row-selected]=\"selectedMatrixTestId === test.testId\"\n (click)=\"selectMatrixRow(test.testId)\">\n <td class=\"seq-cell\">{{ test.sequence }}</td>\n <td class=\"test-name-cell\">\n <span class=\"test-name\" [title]=\"test.testName\">{{ test.testName }}</span>\n </td>\n @for (run of matrixData; track run) {\n <td class=\"result-cell\"\n [ngClass]=\"getMatrixCellClass(getTestResultForRun(run.runId, test.testId))\"\n [class.clickable]=\"getTestResultForRun(run.runId, test.testId)\"\n [class.cell-not-run]=\"!getTestResultForRun(run.runId, test.testId)\"\n [title]=\"getTestResultForRun(run.runId, test.testId)?.status + ' - Click to view test run' || 'Not Run'\"\n (click)=\"onMatrixCellClick(getTestResultForRun(run.runId, test.testId), $event)\">\n @if (getTestResultForRun(run.runId, test.testId); as result) {\n <div class=\"cell-eval-stack\">\n <!-- Status indicator -->\n @if (evalPreferences.showExecution) {\n <span class=\"cell-status\"\n [ngClass]=\"'status-' + result.status.toLowerCase()\"\n [class.cell-skipped-status]=\"result.status === 'Skipped' || result.status === 'Pending'\"\n [title]=\"getStatusTooltip(result.status)\">\n <i class=\"fas\"\n [class.fa-check]=\"result.status === 'Passed'\"\n [class.fa-times]=\"result.status === 'Failed'\"\n [class.fa-exclamation]=\"result.status === 'Error'\"\n [class.fa-hourglass-end]=\"result.status === 'Timeout'\"\n [class.fa-forward]=\"result.status === 'Skipped'\"\n [class.fa-spinner]=\"result.status === 'Running'\"\n [class.fa-clock]=\"result.status === 'Pending'\"></i>\n </span>\n }\n <!-- Human score - slashed icon if no feedback, colored by rating if has feedback -->\n @if (evalPreferences.showHuman && !result.humanRating) {\n <span class=\"cell-human no-feedback\"\n title=\"Human Review: No rating submitted yet\">\n <i class=\"fas fa-user-slash\"></i>\n </span>\n }\n @if (evalPreferences.showHuman && result.humanRating) {\n <span class=\"cell-human has-feedback\"\n [class.rating-low]=\"result.humanRating <= 4\"\n [class.rating-medium]=\"result.humanRating >= 5 && result.humanRating <= 6\"\n [class.rating-good]=\"result.humanRating >= 7 && result.humanRating <= 8\"\n [class.rating-excellent]=\"result.humanRating >= 9\"\n [title]=\"getHumanTooltip(result.humanRating, result.humanComments)\">\n <i class=\"fas fa-user\"></i>\n <span class=\"rating-value\">{{ result.humanRating }}</span>\n </span>\n }\n <!-- Auto score - colored by percentage -->\n @if (evalPreferences.showAuto && result.score != null) {\n <span class=\"cell-auto has-score\"\n [class.score-low]=\"result.score < 0.5\"\n [class.score-medium]=\"result.score >= 0.5 && result.score < 0.7\"\n [class.score-good]=\"result.score >= 0.7 && result.score < 0.85\"\n [class.score-excellent]=\"result.score >= 0.85\"\n [title]=\"'Auto Score: ' + (result.score * 100).toFixed(0) + '% automated evaluation'\">\n <i class=\"fas fa-robot\"></i>\n <span class=\"score-value\">{{ (result.score * 100).toFixed(0) }}</span>\n </span>\n }\n @if (evalPreferences.showAuto && result.score == null) {\n <span class=\"cell-auto no-score\"\n title=\"Auto Score: No automated score available\">\n <i class=\"fas fa-robot\"></i>\n </span>\n }\n </div>\n }\n @if (!getTestResultForRun(run.runId, test.testId)) {\n <span class=\"cell-not-run-indicator\">\n <i class=\"fas fa-minus\"></i>\n </span>\n }\n </td>\n }\n <td class=\"spacer-cell\"></td>\n </tr>\n }\n </tbody>\n <!-- Footer row with totals -->\n <tfoot>\n <tr class=\"totals-row\">\n <td class=\"seq-cell totals-label\"></td>\n <td class=\"test-name-cell totals-label\">\n <strong>Totals</strong>\n </td>\n @for (run of matrixData; track run) {\n <td class=\"result-cell totals-cell\">\n <div class=\"cell-eval-stack totals-stack\">\n <!-- Status totals -->\n @if (evalPreferences.showExecution) {\n <span class=\"totals-status\">\n <span class=\"pass-count\">{{ getRunPassedCount(run) }}/{{ getRunTotalCount(run) }}</span>\n </span>\n }\n <!-- Human totals -->\n @if (evalPreferences.showHuman) {\n <span class=\"totals-human\">\n @if (getRunHumanAvg(run) != null) {\n <span class=\"avg-label\">{{ getRunHumanAvg(run)?.toFixed(1) }}</span>\n }\n <span class=\"count-label\">({{ getRunHumanCount(run) }})</span>\n </span>\n }\n <!-- Auto totals -->\n @if (evalPreferences.showAuto) {\n <span class=\"totals-auto\">\n @if (getRunAutoAvg(run) != null) {\n <span class=\"avg-label\">{{ (getRunAutoAvg(run)! * 100).toFixed(0) }}%</span>\n }\n <span class=\"count-label\">({{ getRunAutoCount(run) }})</span>\n </span>\n }\n </div>\n </td>\n }\n <td class=\"spacer-cell\"></td>\n </tr>\n </tfoot>\n </table>\n </div>\n </div>\n }\n <!-- Empty Matrix State -->\n @if (!loadingMatrix && matrixLoaded && matrixData.length === 0) {\n <mj-empty-state\n Variant=\"no-results\"\n Icon=\"fa-solid fa-table-cells\"\n Title=\"No Matrix Data\"\n Message=\"No suite runs match the current filters.\" />\n }\n }\n <!-- Chart View -->\n @if (analyticsView === 'chart') {\n <!-- Loading Chart -->\n @if (loadingMatrix) {\n <div class=\"loading-state\">\n <mj-loading text=\"Loading chart data...\"></mj-loading>\n </div>\n }\n <!-- Chart Content -->\n @if (!loadingMatrix && matrixLoaded && matrixData.length > 0) {\n <div class=\"chart-section\">\n <div class=\"chart-header\">\n <h3><i class=\"fas fa-project-diagram\"></i> Test Results Flow</h3>\n <div class=\"chart-legend\">\n <span class=\"legend-item chart-passed\"><i class=\"fas fa-check\"></i> Passed</span>\n <span class=\"legend-item chart-failed\"><i class=\"fas fa-times\"></i> Failed</span>\n <span class=\"legend-item chart-error\"><i class=\"fas fa-exclamation\"></i> Error</span>\n <span class=\"legend-item chart-skipped\"><i class=\"fas fa-forward\"></i> Skipped</span>\n </div>\n </div>\n <div class=\"chart-container\">\n <div #chartContainer class=\"d3-chart\"></div>\n </div>\n <div class=\"chart-info\">\n <i class=\"fas fa-info-circle\"></i>\n Interactive visualization showing test results across {{ matrixData.length }} runs.\n Hover over elements for details, click nodes to navigate.\n </div>\n </div>\n }\n <!-- Empty Chart State -->\n @if (!loadingMatrix && matrixLoaded && matrixData.length === 0) {\n <mj-empty-state\n Variant=\"no-results\"\n Icon=\"fa-solid fa-diagram-project\"\n Title=\"No Chart Data\"\n Message=\"No suite runs match the current filters.\" />\n }\n }\n }\n <!-- Empty State -->\n @if (!loadingAnalytics && analyticsLoaded && analyticsData.length === 0) {\n <mj-empty-state\n Icon=\"fa-solid fa-chart-line\"\n Title=\"No Analytics Data\"\n Message=\"Run this suite to start collecting analytics data.\"\n ActionText=\"Run Suite Now\"\n ActionIcon=\"fa-solid fa-play\"\n (Action)=\"runSuite()\" />\n }\n </div>\n }\n\n <!-- Compare Tab -->\n @if (activeTab === 'compare') {\n <div class=\"compare-tab\">\n <!-- Run Selection -->\n <div class=\"compare-selection\">\n <div class=\"compare-run-selector\">\n <h4>Run A (Baseline)</h4>\n @if (!loadingRuns && suiteRuns.length > 0) {\n <div class=\"run-selector-list\">\n @for (run of suiteRuns; track run) {\n <div class=\"run-selector-item\"\n [class.selected]=\"IsCompareRunA(run)\"\n (click)=\"selectCompareRunA(run)\">\n <div class=\"selector-status\" [style.background-color]=\"getRunStatusColor(run.Status)\"></div>\n <div class=\"selector-content\">\n <div class=\"selector-date\">{{ run.StartedAt | date:'short' }}</div>\n <div class=\"selector-rate\">{{ getPassRate(run).toFixed(0) }}% pass</div>\n </div>\n @if (getRunTags(run).length > 0) {\n <div class=\"selector-tags\">\n @for (tag of getRunTags(run).slice(0, 2); track tag) {\n <span class=\"tag-mini\">{{ tag }}</span>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n @if (compareRunA) {\n <div class=\"selected-run-preview\">\n <div class=\"preview-header\">\n <span class=\"preview-label\">Selected:</span>\n <button class=\"clear-btn\" (click)=\"compareRunA = null; compareResults = []\">Clear</button>\n </div>\n <div class=\"preview-details\">\n <span>{{ compareRunA.StartedAt | date:'medium' }}</span>\n <span class=\"preview-rate\">{{ getPassRate(compareRunA).toFixed(1) }}%</span>\n </div>\n </div>\n }\n </div>\n <div class=\"compare-vs\"><i class=\"fas fa-exchange-alt\"></i></div>\n <div class=\"compare-run-selector\">\n <h4>Run B (Compare)</h4>\n @if (!loadingRuns && suiteRuns.length > 0) {\n <div class=\"run-selector-list\">\n @for (run of suiteRuns; track run) {\n <div class=\"run-selector-item\"\n [class.selected]=\"IsCompareRunB(run)\"\n [class.disabled]=\"IsCompareRunA(run)\"\n (click)=\"!IsCompareRunA(run) && selectCompareRunB(run)\">\n <div class=\"selector-status\" [style.background-color]=\"getRunStatusColor(run.Status)\"></div>\n <div class=\"selector-content\">\n <div class=\"selector-date\">{{ run.StartedAt | date:'short' }}</div>\n <div class=\"selector-rate\">{{ getPassRate(run).toFixed(0) }}% pass</div>\n </div>\n @if (getRunTags(run).length > 0) {\n <div class=\"selector-tags\">\n @for (tag of getRunTags(run).slice(0, 2); track tag) {\n <span class=\"tag-mini\">{{ tag }}</span>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n @if (compareRunB) {\n <div class=\"selected-run-preview\">\n <div class=\"preview-header\">\n <span class=\"preview-label\">Selected:</span>\n <button class=\"clear-btn\" (click)=\"compareRunB = null; compareResults = []\">Clear</button>\n </div>\n <div class=\"preview-details\">\n <span>{{ compareRunB.StartedAt | date:'medium' }}</span>\n <span class=\"preview-rate\">{{ getPassRate(compareRunB).toFixed(1) }}%</span>\n </div>\n </div>\n }\n </div>\n </div>\n <!-- Comparison Results -->\n @if (compareRunA && compareRunB && !loadingCompare) {\n <div class=\"compare-results\">\n <!-- Summary Cards -->\n <div class=\"compare-summary\">\n <div class=\"compare-summary-card\">\n <div class=\"summary-label\">Pass Rate Change</div>\n <div class=\"summary-value\" [ngClass]=\"{'positive': getComparePassRateDiff()! > 0, 'negative': getComparePassRateDiff()! < 0}\">\n <i class=\"fas\" [ngClass]=\"{'fa-arrow-up': getComparePassRateDiff()! > 0, 'fa-arrow-down': getComparePassRateDiff()! < 0, 'fa-minus': getComparePassRateDiff() === 0}\"></i>\n {{ getComparePassRateDiff()! > 0 ? '+' : '' }}{{ getComparePassRateDiff()?.toFixed(1) }}%\n </div>\n </div>\n <div class=\"compare-summary-card\">\n <div class=\"summary-label\">Duration Change</div>\n <div class=\"summary-value\" [ngClass]=\"{'positive': getCompareDurationDiff()! < 0, 'negative': getCompareDurationDiff()! > 0}\">\n <i class=\"fas\" [ngClass]=\"{'fa-arrow-down': getCompareDurationDiff()! < 0, 'fa-arrow-up': getCompareDurationDiff()! > 0, 'fa-minus': getCompareDurationDiff() === 0}\"></i>\n {{ formatDuration(getAbsCompareDurationDiff()) }}\n </div>\n </div>\n <div class=\"compare-summary-card improved\">\n <div class=\"summary-label\">Improved</div>\n <div class=\"summary-value\">{{ getCompareImprovedCount() }}</div>\n </div>\n <div class=\"compare-summary-card regressed\">\n <div class=\"summary-label\">Regressed</div>\n <div class=\"summary-value\">{{ getCompareRegressedCount() }}</div>\n </div>\n </div>\n <!-- Detailed Comparison Table -->\n <div class=\"compare-table-section\">\n <h3><i class=\"fas fa-list\"></i> Test-by-Test Comparison</h3>\n <div class=\"compare-table-wrapper\">\n <table class=\"compare-table\">\n <thead>\n <tr>\n <th>Test</th>\n <th>Run A Status</th>\n <th>Run B Status</th>\n <th>Score Diff</th>\n <th>Duration Diff</th>\n <th>Change</th>\n </tr>\n </thead>\n <tbody>\n @for (result of compareResults; track result) {\n <tr [ngClass]=\"{'improved': result.runA && result.runB && result.runA.status !== 'Passed' && result.runB.status === 'Passed', 'regressed': result.runA && result.runB && result.runA.status === 'Passed' && result.runB.status !== 'Passed'}\">\n <td class=\"test-name-cell\">{{ result.testName }}</td>\n <td>\n @if (result.runA) {\n <span class=\"status-chip\" [ngClass]=\"'status-' + result.runA.status.toLowerCase()\">{{ result.runA.status }}</span>\n }\n @if (!result.runA) {\n <span class=\"status-chip status-missing\">N/A</span>\n }\n </td>\n <td>\n @if (result.runB) {\n <span class=\"status-chip\" [ngClass]=\"'status-' + result.runB.status.toLowerCase()\">{{ result.runB.status }}</span>\n }\n @if (!result.runB) {\n <span class=\"status-chip status-missing\">N/A</span>\n }\n </td>\n <td>\n @if (result.scoreDiff != null) {\n <span [ngClass]=\"{'positive': result.scoreDiff > 0, 'negative': result.scoreDiff < 0}\">\n {{ result.scoreDiff > 0 ? '+' : '' }}{{ (result.scoreDiff * 100).toFixed(1) }}%\n </span>\n }\n @if (result.scoreDiff == null) {\n <span class=\"muted\">-</span>\n }\n </td>\n <td>\n @if (result.durationDiff != null) {\n <span [ngClass]=\"{'positive': result.durationDiff < 0, 'negative': result.durationDiff > 0}\">\n {{ result.durationDiff > 0 ? '+' : '' }}{{ result.durationDiff.toFixed(1) }}s\n </span>\n }\n @if (result.durationDiff == null) {\n <span class=\"muted\">-</span>\n }\n </td>\n <td>\n @if (result.runA && result.runB && result.runA.status !== 'Passed' && result.runB.status === 'Passed') {\n <span class=\"change-indicator improved\">\n <i class=\"fas fa-arrow-up\"></i> Fixed\n </span>\n }\n @if (result.runA && result.runB && result.runA.status === 'Passed' && result.runB.status !== 'Passed') {\n <span class=\"change-indicator regressed\">\n <i class=\"fas fa-arrow-down\"></i> Broke\n </span>\n }\n @if (!result.statusChanged) {\n <span class=\"change-indicator unchanged\">\n <i class=\"fas fa-minus\"></i>\n </span>\n }\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n </div>\n </div>\n }\n <!-- Loading State for Compare -->\n @if (loadingCompare) {\n <div class=\"loading-state\">\n <mj-loading text=\"Loading comparison data...\"></mj-loading>\n </div>\n }\n <!-- Empty State -->\n @if (!compareRunA || !compareRunB) {\n <mj-empty-state\n Icon=\"fa-solid fa-scale-balanced\"\n Title=\"Select Two Runs to Compare\"\n Message=\"Choose a baseline run (A) and a comparison run (B) from the lists above to see a detailed side-by-side comparison.\" />\n }\n <!-- No Runs State -->\n @if (runsLoaded && suiteRuns.length < 2) {\n <mj-empty-state\n Icon=\"fa-solid fa-scale-balanced\"\n Title=\"Not Enough Runs to Compare\"\n Message=\"You need at least 2 suite runs to use the comparison feature.\"\n ActionText=\"Run Suite Now\"\n ActionIcon=\"fa-solid fa-play\"\n (Action)=\"runSuite()\" />\n }\n </div>\n }\n </div>\n\n <!-- Keyboard Shortcuts Toggle Button -->\n <button class=\"shortcuts-toggle\" (click)=\"toggleShortcuts()\" [title]=\"showShortcuts ? 'Hide keyboard shortcuts' : 'Show keyboard shortcuts'\">\n <i class=\"fas fa-keyboard\"></i>\n </button>\n\n <!-- Keyboard Shortcuts Hint (Desktop Only) -->\n @if (showShortcuts) {\n <div class=\"keyboard-shortcuts\">\n <div class=\"shortcuts-header\">\n <i class=\"fas fa-keyboard\"></i>\n Shortcuts\n <button class=\"shortcuts-close\" (click)=\"toggleShortcuts()\" title=\"Hide shortcuts\">\n <i class=\"fas fa-times\"></i>\n </button>\n </div>\n <div class=\"shortcut-list\">\n <div class=\"shortcut-item\">\n <span>Save changes</span>\n <span class=\"shortcut-keys\"><kbd>Cmd</kbd><kbd>S</kbd></span>\n </div>\n <div class=\"shortcut-item\">\n <span>Refresh</span>\n <span class=\"shortcut-keys\"><kbd>Cmd</kbd><kbd>R</kbd></span>\n </div>\n <div class=\"shortcut-item\">\n <span>Run Suite</span>\n <span class=\"shortcut-keys\"><kbd>Cmd</kbd><kbd>Enter</kbd></span>\n </div>\n <div class=\"shortcut-item\">\n <span>Switch Tabs</span>\n <span class=\"shortcut-keys\"><kbd>1</kbd>-<kbd>5</kbd></span>\n </div>\n </div>\n </div>\n }\n\n <!-- Slide Panel for Suite Execution -->\n @if (testingDialogService.IsPanelOpen) {\n <mj-slide-panel\n Mode=\"slide\"\n [Title]=\"testingDialogService.PanelOptions?.suiteId ? 'Suite Execution' : 'Run Suite'\"\n [Resizable]=\"true\"\n (Closed)=\"OnPanelClosed()\">\n <app-test-run-dialog\n [PanelMode]=\"true\"\n [selectedTestId]=\"testingDialogService.PanelOptions?.testId ?? null\"\n [selectedSuiteId]=\"testingDialogService.PanelOptions?.suiteId ?? null\"\n [runMode]=\"testingDialogService.PanelOptions?.mode ?? 'suite'\"\n (PanelClose)=\"OnPanelClosed()\">\n </app-test-run-dialog>\n </mj-slide-panel>\n }\n\n <!-- Add Tests Picker Dialog -->\n @if (showAddTestsDialog) {\n <div class=\"picker-backdrop\" (click)=\"closeAddTestsDialog()\"></div>\n <div class=\"picker-dialog\" role=\"dialog\" aria-modal=\"true\" aria-labelledby=\"add-tests-dialog-title\" (click)=\"$event.stopPropagation()\">\n <div class=\"picker-header\">\n <h2 id=\"add-tests-dialog-title\" class=\"picker-title\">\n <i class=\"fas fa-plus-circle\"></i> Add tests to suite\n </h2>\n <button type=\"button\" class=\"picker-close\" (click)=\"closeAddTestsDialog()\" [disabled]=\"isAddingTests\" aria-label=\"Close\">\n <i class=\"fas fa-times\"></i>\n </button>\n </div>\n\n <div class=\"picker-search\">\n <i class=\"fas fa-search picker-search-icon\"></i>\n <input\n #pickerSearch\n type=\"text\"\n class=\"picker-search-input\"\n placeholder=\"Search tests by name, description, or type...\"\n [(ngModel)]=\"addTestsSearch\"\n autofocus\n />\n @if (addTestsSearch) {\n <button type=\"button\" class=\"picker-search-clear\" (click)=\"addTestsSearch = ''\" aria-label=\"Clear search\">\n <i class=\"fas fa-times\"></i>\n </button>\n }\n </div>\n\n <div class=\"picker-toolbar\">\n <span class=\"picker-toolbar-status\">\n @if (selectedTestIdsToAdd.size > 0) {\n <strong>{{ selectedTestIdsToAdd.size }}</strong> selected\n } @else if (!loadingAvailableTests) {\n {{ filteredAvailableTests.length }} test{{ filteredAvailableTests.length === 1 ? '' : 's' }} available\n }\n </span>\n <div class=\"picker-toolbar-actions\">\n <button type=\"button\" class=\"picker-link-btn\" (click)=\"selectAllFiltered()\" [disabled]=\"loadingAvailableTests || filteredAvailableTests.length === 0\">\n Select all\n </button>\n <button type=\"button\" class=\"picker-link-btn\" (click)=\"clearAddSelection()\" [disabled]=\"selectedTestIdsToAdd.size === 0\">\n Clear\n </button>\n </div>\n </div>\n\n <div class=\"picker-body\">\n @if (loadingAvailableTests) {\n <div class=\"picker-loading\">\n <mj-loading text=\"Loading tests...\"></mj-loading>\n </div>\n } @else if (filteredAvailableTests.length === 0) {\n @if (availableTests.length === 0) {\n <mj-empty-state\n Variant=\"success\"\n Size=\"compact\"\n Title=\"Everything's already in the suite\"\n Message=\"This suite contains every available test. Create a new test first to add more.\" />\n } @else {\n <mj-empty-state\n Variant=\"no-results\"\n Size=\"compact\"\n Title=\"No matches\"\n [Message]=\"AddTestsNoMatchMessage\" />\n }\n } @else {\n <ul class=\"picker-list\">\n @for (t of filteredAvailableTests; track t.ID) {\n <li\n class=\"picker-row\"\n [class.picker-row--selected]=\"isAddSelected(t.ID)\"\n (click)=\"toggleAddSelection(t.ID)\"\n role=\"checkbox\"\n [attr.aria-checked]=\"isAddSelected(t.ID)\"\n tabindex=\"0\"\n >\n <span class=\"picker-check\">\n @if (isAddSelected(t.ID)) {\n <i class=\"fas fa-check\"></i>\n }\n </span>\n <div class=\"picker-row-main\">\n <div class=\"picker-row-name\">{{ t.Name }}</div>\n @if (t.Description) {\n <div class=\"picker-row-desc\">{{ t.Description }}</div>\n }\n </div>\n <div class=\"picker-row-meta\">\n @if (t.Type) {\n <span class=\"picker-row-pill\">{{ t.Type }}</span>\n }\n <span class=\"picker-row-pill picker-row-pill--status\" [attr.data-status]=\"t.Status?.toLowerCase()\">{{ t.Status }}</span>\n </div>\n </li>\n }\n </ul>\n }\n </div>\n\n <div class=\"picker-footer\">\n <button\n type=\"button\"\n class=\"picker-btn picker-btn--primary\"\n (click)=\"confirmAddTests()\"\n [disabled]=\"selectedTestIdsToAdd.size === 0 || isAddingTests\"\n >\n @if (isAddingTests) {\n <i class=\"fas fa-spinner fa-spin\"></i> Adding\u2026\n } @else {\n <i class=\"fas fa-check\"></i>\n @if (selectedTestIdsToAdd.size === 0) {\n Add tests\n } @else if (selectedTestIdsToAdd.size === 1) {\n Add 1 test\n } @else {\n Add {{ selectedTestIdsToAdd.size }} tests\n }\n }\n </button>\n <button\n type=\"button\"\n class=\"picker-btn picker-btn--ghost\"\n (click)=\"closeAddTestsDialog()\"\n [disabled]=\"isAddingTests\"\n >\n Cancel\n </button>\n </div>\n </div>\n }\n\n <!-- Sticky Save Bar \u2014 always in the DOM so CSS transitions can fire reliably.\n Visibility is controlled by the .save-bar--visible class, driven by isDirty. -->\n <div\n class=\"save-bar\"\n [class.save-bar--visible]=\"isDirty\"\n [attr.aria-hidden]=\"!isDirty\"\n role=\"region\"\n aria-label=\"Unsaved changes\"\n >\n <div class=\"save-bar-message\">\n <span class=\"save-bar-dot\" aria-hidden=\"true\">\u25CF</span>\n <span class=\"save-bar-text\">\n <strong>Unsaved changes</strong>\n <span class=\"save-bar-fields\">\n @if (dirtyFieldNames.length === 1) {\n {{ dirtyFieldNames[0] }} edited\n } @else if (dirtyFieldNames.length > 1) {\n {{ dirtyFieldNames.length }} fields edited\n }\n </span>\n </span>\n </div>\n <div class=\"save-bar-actions\">\n <button\n type=\"button\"\n class=\"save-bar-btn save-bar-btn--primary\"\n (click)=\"saveChanges()\"\n [disabled]=\"isSaving || !isDirty\"\n [attr.tabindex]=\"isDirty ? 0 : -1\"\n title=\"Save changes (\u2318S)\"\n >\n @if (isSaving) {\n <i class=\"fas fa-spinner fa-spin\"></i> Saving\u2026\n } @else {\n <i class=\"fas fa-check\"></i> Save changes\n <span class=\"save-bar-kbd\"><kbd>\u2318</kbd><kbd>S</kbd></span>\n }\n </button>\n <button\n type=\"button\"\n class=\"save-bar-btn save-bar-btn--ghost\"\n (click)=\"discardChanges()\"\n [disabled]=\"isSaving || !isDirty\"\n [attr.tabindex]=\"isDirty ? 0 : -1\"\n title=\"Discard changes\"\n >\n <i class=\"fas fa-undo\"></i> Discard\n </button>\n </div>\n </div>\n</div>\n", styles: ["/* ===========================\n Test Suite Form - World-Class UX\n =========================== */\n\n/* CSS Custom Properties for Theming - using :host for Angular encapsulation */\n:host {\n --test-primary: var(--mj-brand-primary);\n --test-primary-light: var(--mj-brand-primary);\n --test-success: var(--mj-status-success);\n --test-error: var(--mj-status-error);\n --test-warning: var(--mj-status-warning);\n --test-disabled: var(--mj-text-muted);\n --test-bg: var(--mj-bg-surface-card);\n --test-surface: var(--mj-bg-surface);\n --test-border: var(--mj-border-default);\n --test-text: var(--mj-text-primary);\n --test-text-secondary: var(--mj-text-secondary);\n --test-text-muted: var(--mj-text-disabled);\n --test-radius-sm: 6px;\n --test-radius-md: 10px;\n --test-radius-lg: 16px;\n --test-shadow-sm: var(--mj-shadow-sm);\n --test-shadow-md: var(--mj-shadow-md);\n --test-shadow-lg: var(--mj-shadow-lg);\n --test-transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n display: block;\n height: 100%;\n}\n\n.test-suite-form {\n position: relative;\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--test-bg);\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n}\n\n/* Breadcrumb */\n.breadcrumb {\n margin-bottom: 16px;\n}\n\n.breadcrumb ol {\n display: flex;\n align-items: center;\n gap: 4px;\n list-style: none;\n margin: 0;\n padding: 0;\n font-size: 13px;\n}\n\n.breadcrumb li {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.breadcrumb a {\n color: var(--test-primary);\n text-decoration: none;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 8px;\n border-radius: 6px;\n transition: background 0.15s;\n}\n\n.breadcrumb a:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n text-decoration: none;\n}\n\n.breadcrumb .separator {\n font-size: 10px;\n color: var(--test-text-muted);\n margin: 0 4px;\n}\n\n.breadcrumb .current {\n color: var(--test-text-secondary);\n font-weight: 500;\n}\n\n.breadcrumb-text {\n max-width: 200px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n/* Header */\n.suite-header {\n background: var(--test-surface);\n border-bottom: 1px solid var(--test-border);\n padding: 20px;\n}\n\n.header-content {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 16px;\n gap: 16px;\n}\n\n.header-left {\n display: flex;\n gap: 16px;\n flex: 1;\n min-width: 0;\n}\n\n.suite-icon {\n width: 56px;\n height: 56px;\n border-radius: var(--test-radius-md);\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-inverse);\n font-size: 24px;\n flex-shrink: 0;\n box-shadow: var(--test-shadow-md);\n transition: var(--test-transition);\n}\n\n.suite-icon:hover { transform: scale(1.05); }\n\n.suite-info { flex: 1; min-width: 0; }\n\n.suite-info h1 {\n margin: 0 0 8px 0;\n font-size: clamp(18px, 4vw, 24px);\n font-weight: 700;\n color: var(--test-text);\n word-wrap: break-word;\n}\n\n.suite-meta {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-wrap: wrap;\n}\n\n.status-badge {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n border-radius: 20px;\n color: var(--mj-text-inverse);\n font-size: 12px;\n font-weight: 600;\n text-transform: uppercase;\n}\n\n.status-badge.status-active { background: var(--test-success); }\n.status-badge.status-disabled { background: var(--test-disabled); }\n.status-badge.status-pending { background: var(--test-warning); }\n\n.status-badge-inline {\n display: inline-flex;\n padding: 2px 10px;\n border-radius: 10px;\n color: var(--mj-text-inverse);\n font-size: 11px;\n font-weight: 600;\n}\n\n.status-badge-inline.status-active { background: var(--test-success); }\n.status-badge-inline.status-disabled { background: var(--test-disabled); }\n.status-badge-inline.status-pending { background: var(--test-warning); }\n\n.test-count {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-size: 14px;\n color: var(--test-text-secondary);\n padding: 4px 10px;\n background: var(--test-bg);\n border-radius: var(--test-radius-sm);\n}\n\n.header-actions {\n display: flex;\n gap: 8px;\n flex-shrink: 0;\n}\n\n.suite-description {\n padding: 16px;\n background: var(--mj-bg-surface-card);\n border-radius: var(--test-radius-md);\n border: 1px solid var(--test-border);\n}\n\n.suite-description p {\n margin: 0;\n color: var(--test-text-secondary);\n line-height: 1.6;\n font-size: 14px;\n}\n\n/* Tabs */\n.tabs-container {\n background: var(--test-surface);\n border-bottom: 1px solid var(--test-border);\n position: sticky;\n top: 0;\n z-index: 10;\n}\n\n.tabs {\n display: flex;\n padding: 0 20px;\n overflow-x: auto;\n scrollbar-width: none;\n}\n\n.tabs::-webkit-scrollbar { display: none; }\n\n.tab {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 14px 18px;\n border: none;\n background: transparent;\n border-bottom: 3px solid transparent;\n color: var(--test-text-secondary);\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: var(--test-transition);\n white-space: nowrap;\n}\n\n.tab:hover {\n color: var(--test-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.tab.active {\n color: var(--test-primary);\n border-bottom-color: var(--test-primary);\n font-weight: 600;\n}\n\n.tab-badge {\n background: var(--test-border);\n color: var(--test-text-secondary);\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n}\n\n.tab.active .tab-badge {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n color: var(--test-primary);\n}\n\n.tab-shortcut {\n font-size: 10px;\n color: var(--test-text-muted);\n background: var(--test-bg);\n padding: 2px 6px;\n border-radius: 4px;\n font-weight: 600;\n}\n\n/* Tab Content */\n.tab-content {\n flex: 1;\n overflow-y: auto;\n padding: 20px;\n}\n\n/* Overview Tab */\n.overview-tab {\n display: flex;\n flex-direction: column;\n gap: 20px;\n animation: fadeIn 0.3s ease-out;\n}\n\n@keyframes fadeIn {\n from { opacity: 0; transform: translateY(10px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n.info-section, .config-section {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.info-section h3, .config-section h3 {\n margin: 0 0 20px 0;\n font-size: 18px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.info-section h3 i, .config-section h3 i {\n color: var(--test-primary);\n}\n\n.info-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: 16px;\n}\n\n.info-item {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.info-label {\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n}\n\n.info-value {\n font-size: 14px;\n color: var(--test-text);\n font-weight: 500;\n}\n\n.config-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));\n gap: 20px;\n}\n\n.config-item {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.config-item label {\n font-size: 12px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n}\n\n.config-input {\n padding: 10px 14px;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n font-size: 14px;\n transition: var(--test-transition);\n}\n\n.config-input:focus {\n outline: none;\n border-color: var(--test-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.config-hint {\n font-size: 11px;\n color: var(--test-text-muted);\n}\n\n/* Tests Tab */\n.tests-tab, .runs-tab {\n animation: fadeIn 0.3s ease-out;\n}\n\n.loading-state { padding: 0; }\n\n.skeleton-list {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.skeleton-card {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 16px;\n background: var(--test-surface);\n border-radius: var(--test-radius-md);\n border: 1px solid var(--test-border);\n}\n\n.skeleton-sequence {\n width: 32px;\n height: 32px;\n border-radius: 50%;\n background: linear-gradient(90deg, var(--mj-border-default) 25%, var(--mj-bg-surface-sunken) 50%, var(--mj-border-default) 75%);\n background-size: 200% 100%;\n animation: shimmer 1.5s infinite;\n}\n\n.skeleton-icon {\n width: 40px;\n height: 40px;\n border-radius: var(--test-radius-md);\n background: linear-gradient(90deg, var(--mj-border-default) 25%, var(--mj-bg-surface-sunken) 50%, var(--mj-border-default) 75%);\n background-size: 200% 100%;\n animation: shimmer 1.5s infinite;\n}\n\n.skeleton-content {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.skeleton-line {\n height: 14px;\n border-radius: 4px;\n background: linear-gradient(90deg, var(--mj-border-default) 25%, var(--mj-bg-surface-sunken) 50%, var(--mj-border-default) 75%);\n background-size: 200% 100%;\n animation: shimmer 1.5s infinite;\n}\n\n.skeleton-line.wide { width: 70%; }\n.skeleton-line.narrow { width: 40%; }\n\n@keyframes shimmer {\n 0% { background-position: 200% 0; }\n 100% { background-position: -200% 0; }\n}\n\n.tests-list, .runs-list {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.test-item, .run-item {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 16px;\n background: var(--test-surface);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.test-item:hover, .run-item:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n border-color: var(--test-primary-light);\n transform: translateX(4px);\n}\n\n.test-sequence {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--test-bg);\n border-radius: 50%;\n font-size: 14px;\n font-weight: 700;\n color: var(--test-text-secondary);\n flex-shrink: 0;\n}\n\n.test-icon, .run-icon {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: var(--test-radius-md);\n color: var(--mj-text-inverse);\n font-size: 18px;\n flex-shrink: 0;\n box-shadow: var(--test-shadow-sm);\n}\n\n.test-icon {\n background: var(--test-primary);\n}\n\n.test-content, .run-content { flex: 1; min-width: 0; }\n\n.test-name, .run-header {\n font-size: 14px;\n font-weight: 600;\n color: var(--test-text);\n margin-bottom: 4px;\n}\n\n.run-header {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.run-id { font-weight: 600; }\n\n.run-status {\n font-size: 12px;\n font-weight: 700;\n text-transform: uppercase;\n}\n\n.test-status, .run-meta {\n display: flex;\n gap: 12px;\n font-size: 12px;\n color: var(--test-text-secondary);\n}\n\n.test-status span, .run-meta span {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n}\n\n.test-item > i, .run-item > i {\n color: var(--test-text-muted);\n font-size: 14px;\n transition: var(--test-transition);\n}\n\n.test-item:hover > i, .run-item:hover > i {\n color: var(--test-primary);\n transform: translateX(2px);\n}\n\n/* Keyboard Shortcuts */\n/* Keyboard shortcuts toggle button - visible when shortcuts are hidden */\n.shortcuts-toggle {\n position: fixed;\n bottom: 20px;\n right: 20px;\n width: 36px;\n height: 36px;\n border-radius: 50%;\n background: var(--test-surface);\n border: 1px solid var(--test-border);\n box-shadow: var(--test-shadow-md);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--test-text-secondary);\n font-size: 14px;\n z-index: 99;\n transition: var(--test-transition);\n opacity: 0.7;\n}\n\n.shortcuts-toggle:hover {\n opacity: 1;\n transform: scale(1.1);\n color: var(--test-primary);\n border-color: var(--test-primary);\n}\n\n.keyboard-shortcuts {\n position: fixed;\n bottom: 20px;\n right: 20px;\n background: var(--test-surface);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n padding: 12px 16px;\n box-shadow: var(--test-shadow-lg);\n font-size: 12px;\n z-index: 100;\n max-width: 260px;\n}\n\n.shortcuts-header {\n display: flex;\n align-items: center;\n gap: 6px;\n margin-bottom: 10px;\n padding-bottom: 8px;\n border-bottom: 1px solid var(--test-border);\n font-weight: 600;\n color: var(--test-text);\n}\n\n.shortcuts-close {\n margin-left: auto;\n background: none;\n border: none;\n cursor: pointer;\n color: var(--test-text-muted);\n font-size: 12px;\n padding: 2px 4px;\n border-radius: 4px;\n transition: var(--test-transition);\n}\n\n.shortcuts-close:hover {\n color: var(--test-text);\n background: var(--test-border);\n}\n\n.shortcut-list {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.shortcut-item {\n display: flex;\n justify-content: space-between;\n align-items: center;\n color: var(--test-text-secondary);\n}\n\n.shortcut-keys {\n display: flex;\n gap: 4px;\n}\n\n.shortcut-keys kbd {\n background: var(--test-bg);\n border: 1px solid var(--test-border);\n border-radius: 4px;\n padding: 2px 6px;\n font-size: 11px;\n color: var(--test-text);\n}\n\n/* Responsive */\n@media (max-width: 1024px) {\n .keyboard-shortcuts, .shortcuts-toggle { display: none; }\n}\n\n@media (max-width: 768px) {\n .suite-header { padding: 16px; }\n\n .header-content {\n flex-direction: column;\n gap: 16px;\n }\n\n .header-actions {\n width: 100%;\n justify-content: stretch;\n }\n\n .header-actions button { flex: 1; }\n\n .tab-shortcut { display: none; }\n\n .info-grid { grid-template-columns: 1fr; }\n\n .test-item, .run-item { padding: 14px; }\n}\n\n@media (max-width: 480px) {\n .suite-icon {\n width: 40px;\n height: 40px;\n font-size: 18px;\n }\n\n .suite-info h1 { font-size: 16px; }\n\n .tab-badge { display: none; }\n\n .test-sequence { display: none; }\n}\n\n@media (hover: none) and (pointer: coarse) {\n .test-item:active, .run-item:active {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n transform: scale(0.98);\n }\n\n .tab { min-height: 48px; }\n .test-item, .run-item { min-height: 64px; }\n}\n\n@media (prefers-reduced-motion: reduce) {\n *, *::before, *::after {\n animation-duration: 0.01ms !important;\n transition-duration: 0.01ms !important;\n }\n}\n\n@media print {\n .header-actions, .tabs-container, .keyboard-shortcuts {\n display: none !important;\n }\n}\n\n/* ===========================\n Tags UI\n =========================== */\n.run-tags {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n margin-top: 8px;\n}\n\n.tag-chip {\n display: inline-flex;\n align-items: center;\n padding: 3px 10px;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n border-radius: 12px;\n font-size: 11px;\n font-weight: 500;\n color: var(--mj-brand-primary-hover);\n}\n\n.tag-mini {\n display: inline-flex;\n align-items: center;\n padding: 2px 6px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 4px;\n font-size: 10px;\n font-weight: 500;\n color: var(--mj-text-muted);\n}\n\n.tag-more {\n font-size: 10px;\n color: var(--mj-text-disabled);\n font-weight: 500;\n}\n\n/* Evaluation metrics row for Runs list */\n.run-eval-metrics {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-top: 8px;\n}\n\n.eval-metric {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 3px 8px;\n border-radius: 6px;\n font-size: 11px;\n font-weight: 500;\n}\n\n.eval-metric.status {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n}\n\n.eval-metric.status.status-completed {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.eval-metric.status.status-failed {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.eval-metric.status.status-running {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary-hover);\n}\n\n.eval-metric.status.status-pending {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.eval-metric.human {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n border: 1px solid var(--mj-status-warning);\n color: var(--mj-status-warning);\n}\n\n.eval-metric.human .eval-pending {\n font-size: 9px;\n color: var(--mj-status-warning);\n}\n\n.eval-metric.auto {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n color: var(--mj-brand-primary-hover);\n}\n\n.eval-metric.auto.high {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-success) 30%, transparent);\n color: var(--mj-status-success);\n}\n\n.eval-metric.auto.medium {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-warning) 30%, transparent);\n color: var(--mj-status-warning);\n}\n\n.eval-metric.auto.low {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-error) 30%, transparent);\n color: var(--mj-status-error);\n}\n\n.tag-cell {\n display: flex;\n align-items: center;\n gap: 4px;\n flex-wrap: wrap;\n}\n\n.tag-chip-table {\n display: inline-block;\n padding: 3px 8px;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n color: var(--mj-brand-primary-hover);\n border-radius: 10px;\n font-size: 10px;\n font-weight: 600;\n white-space: nowrap;\n max-width: 80px;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n/* ===========================\n Analytics Tab\n =========================== */\n.analytics-tab {\n animation: fadeIn 0.3s ease-out;\n}\n\n/* Collapsible filters */\n/* Filters disclosure migrated to <mj-accordion-panel>. The bespoke\n .analytics-filters wrapper card chrome, the .filters-header bar (+ hover),\n and the .filters-header > i chevron are now owned by the accordion and were\n removed. The title-slot layout (.filters-title flex row) and font are now\n provided by the accordion title + Size=\"sm\"; the collapsed summary uses the\n shared .mj-accordion-badge (--muted --right). Only the body content\n (.filters-content) styling is kept below. */\n\n.filters-content {\n display: flex;\n flex-direction: column;\n gap: 16px;\n padding: 12px 16px 16px 16px;\n border-top: 1px solid var(--test-border);\n}\n\n.filter-group {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.filter-group label {\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n}\n\n.filter-buttons {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n}\n\n.filter-btn {\n padding: 8px 16px;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n background: var(--test-surface);\n color: var(--test-text-secondary);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.filter-btn:hover {\n border-color: var(--test-primary);\n color: var(--test-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.filter-btn.active {\n background: var(--test-primary);\n border-color: var(--test-primary);\n color: var(--mj-text-inverse);\n}\n\n.filter-btn.tag-btn {\n padding: 6px 12px;\n font-size: 12px;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n}\n\n.filter-btn.tag-btn i.fa-check {\n font-size: 10px;\n}\n\n.filter-btn.tag-btn.all-tags-btn {\n font-weight: 600;\n}\n\n.filter-btn.tag-btn.all-tags-btn i {\n font-size: 11px;\n}\n\n.filter-hint {\n font-weight: 400;\n font-size: 10px;\n color: var(--test-primary);\n text-transform: none;\n letter-spacing: normal;\n}\n\n.tag-filters {\n max-height: 120px;\n overflow-y: auto;\n}\n\n/* KPI Cards */\n.analytics-kpis {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: 16px;\n margin-bottom: 24px;\n}\n\n.kpi-card {\n display: flex;\n align-items: center;\n gap: 16px;\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 20px;\n box-shadow: var(--test-shadow-sm);\n transition: var(--test-transition);\n}\n\n.kpi-card:hover {\n transform: translateY(-2px);\n box-shadow: var(--test-shadow-md);\n}\n\n.kpi-icon {\n width: 48px;\n height: 48px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n border-radius: var(--test-radius-md);\n color: var(--test-primary);\n font-size: 20px;\n}\n\n.kpi-icon.success {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--test-success);\n}\n\n.kpi-icon.info {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.kpi-icon.warning {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--test-warning);\n}\n\n.kpi-content {\n flex: 1;\n min-width: 0;\n}\n\n.kpi-value {\n font-size: 24px;\n font-weight: 700;\n color: var(--test-text);\n line-height: 1.2;\n}\n\n.kpi-label {\n font-size: 12px;\n color: var(--test-text-secondary);\n margin-top: 2px;\n}\n\n.kpi-trend {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n font-size: 12px;\n font-weight: 600;\n margin-top: 4px;\n padding: 2px 8px;\n border-radius: 10px;\n background: var(--mj-bg-surface-sunken);\n color: var(--test-text-secondary);\n}\n\n.kpi-trend.trend-up {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--test-success);\n}\n\n.kpi-trend.trend-down {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--test-error);\n}\n\n/* Analytics Table */\n.analytics-table-section {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.analytics-table-section h3 {\n margin: 0 0 16px 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.analytics-table-section h3 i {\n color: var(--test-primary);\n}\n\n.analytics-table-wrapper {\n overflow-x: auto;\n margin: 0 -24px;\n padding: 0 24px;\n}\n\n.analytics-table {\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n}\n\n.analytics-table th {\n text-align: left;\n padding: 12px 16px;\n background: var(--mj-bg-surface-card);\n border-bottom: 2px solid var(--test-border);\n font-weight: 600;\n color: var(--test-text-secondary);\n text-transform: uppercase;\n font-size: 11px;\n letter-spacing: 0.5px;\n white-space: nowrap;\n}\n\n.analytics-table td {\n padding: 14px 16px;\n border-bottom: 1px solid var(--test-border);\n color: var(--test-text);\n}\n\n.analytics-table tbody tr.clickable-row {\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.analytics-table tbody tr.clickable-row:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.status-chip {\n display: inline-flex;\n align-items: center;\n padding: 4px 10px;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n}\n\n.status-chip.status-completed { background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface)); color: var(--test-success); }\n.status-chip.status-passed { background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface)); color: var(--test-success); }\n.status-chip.status-failed { background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface)); color: var(--test-error); }\n.status-chip.status-error { background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface)); color: var(--test-warning); }\n.status-chip.status-running { background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface)); color: var(--test-primary); }\n.status-chip.status-pending { background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface)); color: var(--mj-brand-primary); }\n.status-chip.status-cancelled { background: var(--mj-bg-surface-sunken); color: var(--test-disabled); }\n.status-chip.status-missing { background: var(--mj-bg-surface-sunken); color: var(--test-text-muted); }\n.status-chip.status-timeout { background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface)); color: var(--test-warning); }\n.status-chip.status-skipped { background: var(--mj-bg-surface-sunken); color: var(--test-disabled); }\n\n.pass-rate-cell {\n display: flex;\n align-items: center;\n gap: 8px;\n min-width: 100px;\n}\n\n.pass-rate-bar {\n height: 6px;\n border-radius: 3px;\n background: var(--test-success);\n transition: width 0.3s ease;\n max-width: 60px;\n}\n\n.pass-rate-bar.medium { background: var(--test-warning); }\n.pass-rate-bar.low { background: var(--test-error); }\n\n/* Analytics Sub-navigation */\n.analytics-subnav {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 8px;\n margin-bottom: 20px;\n box-shadow: var(--test-shadow-sm);\n display: inline-flex;\n}\n\n.subnav-tabs {\n display: flex;\n gap: 4px;\n background: var(--test-bg);\n border-radius: var(--test-radius-md);\n padding: 4px;\n}\n\n.subnav-tab {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 20px;\n border: none;\n border-radius: var(--test-radius-sm);\n background: transparent;\n color: var(--test-text-secondary);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.subnav-tab:hover {\n color: var(--test-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.subnav-tab.active {\n background: var(--test-surface);\n color: var(--test-primary);\n box-shadow: var(--test-shadow-sm);\n}\n\n.subnav-tab i {\n font-size: 14px;\n}\n\n/* Matrix View */\n.matrix-section {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 16px;\n box-shadow: var(--test-shadow-sm);\n display: flex;\n flex-direction: column;\n max-height: calc(100vh - 280px);\n min-height: 300px;\n}\n\n.matrix-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n flex-wrap: wrap;\n gap: 12px;\n margin-bottom: 12px;\n padding-bottom: 12px;\n border-bottom: 1px solid var(--test-border);\n flex-shrink: 0;\n}\n\n.matrix-header-right {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.matrix-header h3 {\n display: flex;\n align-items: center;\n gap: 10px;\n margin: 0;\n font-size: 15px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.matrix-header h3 i {\n color: var(--test-primary);\n}\n\n.matrix-run-count {\n font-size: 12px;\n color: var(--test-text-muted);\n font-weight: 500;\n}\n\n/* Matrix filter input */\n.matrix-filter-input {\n display: flex;\n align-items: center;\n gap: 8px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--test-border);\n border-radius: 6px;\n padding: 4px 10px;\n min-width: 180px;\n}\n\n.matrix-filter-input i.fa-search {\n color: var(--mj-text-disabled);\n font-size: 12px;\n}\n\n.matrix-filter-input .filter-input {\n border: none;\n background: transparent;\n outline: none;\n font-size: 12px;\n color: var(--test-text);\n width: 100%;\n}\n\n.matrix-filter-input .filter-input::placeholder {\n color: var(--mj-text-disabled);\n}\n\n.clear-filter-btn {\n border: none;\n background: none;\n padding: 2px 4px;\n cursor: pointer;\n color: var(--mj-text-disabled);\n font-size: 10px;\n border-radius: 3px;\n transition: all 0.15s ease;\n}\n\n.clear-filter-btn:hover {\n background: var(--mj-border-default);\n color: var(--mj-text-muted);\n}\n\n/* Scrollable matrix container with fixed height */\n.matrix-scroll-container {\n flex: 1;\n overflow: auto;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n}\n\n.test-matrix {\n display: table;\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n}\n\n.test-matrix thead {\n display: table-header-group;\n}\n\n.test-matrix thead tr {\n display: table-row;\n}\n\n.test-matrix tbody {\n display: table-row-group;\n}\n\n.test-matrix tbody tr {\n display: table-row;\n cursor: pointer;\n transition: background-color 0.15s ease;\n}\n\n.test-matrix tbody tr:hover {\n background-color: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.test-matrix tbody tr.row-selected {\n background-color: color-mix(in srgb, var(--mj-brand-primary) 12%, transparent) !important;\n}\n\n.test-matrix tbody tr.row-selected td {\n border-top: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n border-bottom: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n}\n\n.test-matrix tbody tr.row-selected .seq-cell,\n.test-matrix tbody tr.row-selected .test-name-cell {\n background-color: color-mix(in srgb, var(--mj-brand-primary) 12%, transparent) !important;\n}\n\n.test-matrix tfoot {\n display: table-footer-group;\n}\n\n.test-matrix th,\n.test-matrix td {\n display: table-cell;\n border: 1px solid var(--test-border);\n padding: 8px 12px;\n text-align: center;\n vertical-align: middle;\n}\n\n.test-matrix th {\n background: var(--test-bg);\n font-weight: 600;\n font-size: 11px;\n color: var(--test-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n position: sticky;\n top: 0;\n z-index: 10;\n border-bottom: 3px solid var(--mj-text-secondary) !important;\n}\n\n/* Sequence column - shared styles */\n.test-matrix .seq-header,\n.test-matrix .seq-cell {\n width: 36px;\n min-width: 36px;\n max-width: 36px;\n text-align: center;\n position: sticky;\n left: 0;\n font-size: 11px;\n color: var(--mj-text-muted);\n border-right: 1px solid var(--test-border);\n padding: 6px 4px !important;\n}\n\n/* Seq header - sticky top AND left, highest z-index */\n.test-matrix .seq-header {\n cursor: pointer;\n font-weight: 600;\n background: var(--test-bg);\n z-index: 12; /* Higher than other headers */\n top: 0;\n}\n\n/* Seq body cells - sticky left only, lower z-index */\n.test-matrix .seq-cell {\n background: var(--test-surface);\n z-index: 2;\n}\n\n.test-matrix .seq-header i {\n font-size: 9px;\n margin-left: 2px;\n opacity: 0.6;\n}\n\n.test-matrix .seq-header:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.test-matrix .test-name-header {\n text-align: left;\n min-width: 150px;\n max-width: 500px;\n width: auto;\n position: sticky;\n left: 36px;\n background: var(--test-bg);\n z-index: 11;\n border-right: 2px solid var(--test-border);\n cursor: pointer;\n}\n\n.test-matrix .test-name-header i {\n font-size: 9px;\n margin-left: 4px;\n opacity: 0.6;\n}\n\n.test-matrix .test-name-header:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.test-matrix .run-header {\n min-width: 120px;\n width: 120px;\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n/* Spacer column absorbs extra width */\n.test-matrix .spacer-header,\n.test-matrix .spacer-cell {\n width: 100%;\n min-width: 20px;\n background: var(--test-bg);\n border: none;\n}\n\n.test-matrix .spacer-cell {\n background: var(--test-surface);\n}\n\n.test-matrix .run-header:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.run-header-content {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 4px;\n}\n\n.run-date {\n font-size: 12px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.run-pass-rate {\n font-size: 11px;\n font-weight: 700;\n padding: 2px 8px;\n border-radius: 10px;\n}\n\n.run-pass-rate.high {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--test-success);\n}\n\n.run-pass-rate.medium {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--test-warning);\n}\n\n.run-pass-rate.low {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--test-error);\n}\n\n.run-tags {\n display: flex;\n gap: 4px;\n}\n\n.tag-tiny {\n font-size: 9px;\n padding: 2px 6px;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--test-primary);\n border-radius: 8px;\n white-space: nowrap;\n max-width: 60px;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n/* Matrix column header tags - emphasized */\n.run-tags-header {\n display: flex;\n flex-wrap: wrap;\n gap: 3px;\n justify-content: center;\n margin-bottom: 4px;\n}\n\n.tag-chip-header {\n display: inline-block;\n padding: 3px 8px;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n color: var(--mj-brand-primary-hover);\n border-radius: 10px;\n font-size: 10px;\n font-weight: 600;\n white-space: nowrap;\n max-width: 70px;\n overflow: hidden;\n text-overflow: ellipsis;\n text-transform: none;\n letter-spacing: normal;\n}\n\n.tag-more-header {\n font-size: 9px;\n color: var(--test-text-secondary);\n padding: 2px 4px;\n}\n\n.test-matrix .test-name-cell {\n text-align: left;\n min-width: 150px;\n max-width: 500px;\n width: auto;\n position: sticky;\n left: 36px;\n background: var(--test-surface);\n z-index: 2;\n border-right: 2px solid var(--test-border);\n padding: 6px 10px !important;\n}\n\n.test-name {\n display: block;\n white-space: nowrap;\n font-weight: 500;\n color: var(--test-text);\n font-size: 12px;\n}\n\n.result-cell {\n position: relative;\n min-width: 120px;\n width: 120px;\n transition: var(--test-transition);\n}\n\n.result-cell.clickable {\n cursor: pointer;\n}\n\n.result-cell.clickable:hover {\n transform: scale(1.1);\n box-shadow: var(--mj-shadow-md);\n z-index: 5;\n}\n\n.result-cell i {\n font-size: 14px;\n}\n\n/* Completed cells have neutral white background - pills tell the story */\n.result-cell.cell-passed,\n.result-cell.cell-failed,\n.result-cell.cell-error,\n.result-cell.cell-timeout,\n.result-cell.cell-running,\n.result-cell.cell-pending {\n background: var(--mj-bg-surface);\n color: var(--test-text);\n}\n\n/* Skipped/not-run cells get hatched background */\n.result-cell.cell-skipped {\n background: repeating-linear-gradient(\n 45deg,\n var(--mj-bg-surface-card),\n var(--mj-bg-surface-card) 4px,\n var(--mj-border-default) 4px,\n var(--mj-border-default) 8px\n );\n color: var(--test-disabled);\n}\n\n.result-cell.cell-none {\n background: var(--mj-bg-surface-card);\n color: var(--test-text-muted);\n}\n\n.cell-score {\n display: block;\n font-size: 10px;\n font-weight: 600;\n margin-top: 2px;\n}\n\n/* Matrix cell evaluation stack - shows multiple eval types horizontally */\n.cell-eval-stack {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n flex-wrap: nowrap;\n}\n\n.result-cell.multi-eval {\n min-width: 120px;\n width: auto;\n}\n\n/* Add timeout status icon */\n.cell-status.status-timeout {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.cell-status {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n border-radius: 50%;\n font-size: 11px;\n}\n\n.cell-status.status-passed {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.cell-status.status-failed {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.cell-status.status-error {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.cell-status.status-skipped {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n}\n\n.cell-status.status-running {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary-hover);\n}\n\n.cell-status.status-pending {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.cell-human {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n border-radius: 50%;\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n font-size: 10px;\n}\n\n.cell-auto {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n padding: 2px 6px;\n border-radius: 4px;\n font-size: 10px;\n font-weight: 600;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary-hover);\n}\n\n.cell-auto.high {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.cell-auto.medium {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.cell-auto.low {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.cell-none-indicator {\n color: var(--test-text-muted);\n opacity: 0.5;\n}\n\n.matrix-info {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 12px;\n color: var(--test-text-muted);\n padding: 12px;\n background: var(--test-bg);\n border-radius: var(--test-radius-sm);\n}\n\n.matrix-info i {\n color: var(--test-primary);\n}\n\n/* ===========================\n Chart View\n =========================== */\n.chart-section {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.chart-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n flex-wrap: wrap;\n gap: 16px;\n margin-bottom: 20px;\n padding-bottom: 16px;\n border-bottom: 1px solid var(--test-border);\n}\n\n.chart-header h3 {\n display: flex;\n align-items: center;\n gap: 10px;\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.chart-header h3 i {\n color: var(--test-primary);\n}\n\n.chart-legend {\n display: flex;\n gap: 16px;\n flex-wrap: wrap;\n}\n\n.chart-legend .legend-item {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n font-weight: 500;\n padding: 4px 10px;\n border-radius: 12px;\n}\n\n.chart-legend .legend-item.chart-passed {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--test-success);\n}\n\n.chart-legend .legend-item.chart-failed {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--test-error);\n}\n\n.chart-legend .legend-item.chart-error {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--test-warning);\n}\n\n.chart-legend .legend-item.chart-skipped {\n background: var(--mj-bg-surface-sunken);\n color: var(--test-disabled);\n}\n\n.chart-container {\n min-height: 500px;\n position: relative;\n overflow: hidden;\n background: var(--mj-bg-surface-card);\n border-radius: var(--test-radius-md);\n border: 1px solid var(--test-border);\n}\n\n.d3-chart {\n width: 100%;\n height: 500px;\n}\n\n.d3-chart svg {\n width: 100%;\n height: 100%;\n}\n\n/* D3 Chart Node Styles */\n.d3-chart .node {\n cursor: pointer;\n transition: transform 0.2s ease;\n}\n\n.d3-chart .node:hover {\n transform: scale(1.05);\n}\n\n.d3-chart .node-label {\n font-size: 11px;\n font-weight: 500;\n fill: var(--test-text);\n pointer-events: none;\n}\n\n.d3-chart .link {\n fill: none;\n stroke-opacity: 0.4;\n transition: stroke-opacity 0.2s ease;\n}\n\n.d3-chart .link:hover {\n stroke-opacity: 0.8;\n}\n\n.d3-chart .tooltip {\n position: absolute;\n padding: 10px 14px;\n background: var(--mj-bg-overlay);\n color: var(--mj-text-inverse);\n border-radius: 8px;\n font-size: 12px;\n pointer-events: none;\n z-index: 100;\n box-shadow: var(--mj-shadow-lg);\n max-width: 250px;\n}\n\n.d3-chart .tooltip-title {\n font-weight: 600;\n margin-bottom: 4px;\n}\n\n.d3-chart .tooltip-value {\n opacity: 0.8;\n}\n\n.chart-info {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 12px;\n color: var(--test-text-muted);\n padding: 12px;\n background: var(--test-bg);\n border-radius: var(--test-radius-sm);\n margin-top: 16px;\n}\n\n.chart-info i {\n color: var(--test-primary);\n}\n\n/* ===========================\n Compare Tab\n =========================== */\n.compare-tab {\n animation: fadeIn 0.3s ease-out;\n}\n\n.compare-selection {\n display: grid;\n grid-template-columns: 1fr auto 1fr;\n gap: 24px;\n align-items: flex-start;\n margin-bottom: 24px;\n}\n\n.compare-run-selector {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 20px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.compare-run-selector h4 {\n margin: 0 0 16px 0;\n font-size: 14px;\n font-weight: 600;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.run-selector-list {\n max-height: 200px;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n gap: 8px;\n margin-bottom: 12px;\n}\n\n.run-selector-item {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 12px;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.run-selector-item:hover {\n border-color: var(--test-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.run-selector-item.selected {\n border-color: var(--test-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n}\n\n.run-selector-item.disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.selector-status {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n flex-shrink: 0;\n}\n\n.selector-content {\n flex: 1;\n min-width: 0;\n}\n\n.selector-date {\n font-size: 12px;\n font-weight: 500;\n color: var(--test-text);\n}\n\n.selector-rate {\n font-size: 11px;\n color: var(--test-text-secondary);\n}\n\n.selector-tags {\n display: flex;\n gap: 4px;\n flex-wrap: wrap;\n}\n\n.selected-run-preview {\n padding: 12px;\n background: var(--mj-bg-surface-card);\n border-radius: var(--test-radius-sm);\n border: 1px solid var(--test-border);\n}\n\n.preview-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 8px;\n}\n\n.preview-label {\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n color: var(--test-text-muted);\n}\n\n.clear-btn {\n padding: 4px 8px;\n border: none;\n background: transparent;\n color: var(--test-error);\n font-size: 11px;\n font-weight: 500;\n cursor: pointer;\n}\n\n.clear-btn:hover { text-decoration: underline; }\n\n.preview-details {\n display: flex;\n justify-content: space-between;\n font-size: 12px;\n color: var(--test-text);\n}\n\n.preview-rate {\n font-weight: 600;\n color: var(--test-success);\n}\n\n.compare-vs {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n background: var(--test-bg);\n border-radius: 50%;\n color: var(--test-text-muted);\n font-size: 16px;\n align-self: center;\n margin-top: 60px;\n}\n\n/* Compare Results */\n.compare-results {\n animation: fadeIn 0.3s ease-out;\n}\n\n.compare-summary {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));\n gap: 16px;\n margin-bottom: 24px;\n}\n\n.compare-summary-card {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 20px;\n box-shadow: var(--test-shadow-sm);\n text-align: center;\n}\n\n.compare-summary-card .summary-label {\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n color: var(--test-text-muted);\n margin-bottom: 8px;\n}\n\n.compare-summary-card .summary-value {\n font-size: 24px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n}\n\n.compare-summary-card .summary-value.positive { color: var(--test-success); }\n.compare-summary-card .summary-value.negative { color: var(--test-error); }\n\n.compare-summary-card.improved {\n border-left: 4px solid var(--test-success);\n}\n\n.compare-summary-card.improved .summary-value { color: var(--test-success); }\n\n.compare-summary-card.regressed {\n border-left: 4px solid var(--test-error);\n}\n\n.compare-summary-card.regressed .summary-value { color: var(--test-error); }\n\n/* Compare Table */\n.compare-table-section {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.compare-table-section h3 {\n margin: 0 0 16px 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.compare-table-section h3 i {\n color: var(--test-primary);\n}\n\n.compare-table-wrapper {\n overflow-x: auto;\n}\n\n.compare-table {\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n}\n\n.compare-table th {\n text-align: left;\n padding: 12px 16px;\n background: var(--mj-bg-surface-card);\n border-bottom: 2px solid var(--test-border);\n font-weight: 600;\n color: var(--test-text-secondary);\n text-transform: uppercase;\n font-size: 11px;\n letter-spacing: 0.5px;\n white-space: nowrap;\n}\n\n.compare-table td {\n padding: 14px 16px;\n border-bottom: 1px solid var(--test-border);\n color: var(--test-text);\n}\n\n.compare-table tbody tr.improved {\n background: color-mix(in srgb, var(--mj-status-success) 5%, transparent);\n}\n\n.compare-table tbody tr.regressed {\n background: color-mix(in srgb, var(--mj-status-error) 5%, transparent);\n}\n\n.test-name-cell {\n font-weight: 500;\n max-width: 200px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.positive { color: var(--test-success); }\n.negative { color: var(--test-error); }\n.muted { color: var(--test-text-muted); }\n\n.change-indicator {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 4px 8px;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n}\n\n.change-indicator.improved {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--test-success);\n}\n\n.change-indicator.regressed {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--test-error);\n}\n\n.change-indicator.unchanged {\n background: var(--mj-bg-surface-sunken);\n color: var(--test-text-muted);\n}\n\n/* ===========================\n Responsive Analytics/Compare\n =========================== */\n@media (max-width: 1024px) {\n .compare-selection {\n grid-template-columns: 1fr;\n gap: 16px;\n }\n\n .compare-vs {\n margin: 0;\n align-self: center;\n justify-self: center;\n }\n\n .analytics-kpis {\n grid-template-columns: repeat(2, 1fr);\n }\n}\n\n@media (max-width: 768px) {\n .filter-buttons {\n flex-direction: column;\n }\n\n .filter-btn {\n width: 100%;\n text-align: center;\n }\n\n .analytics-kpis {\n grid-template-columns: 1fr;\n }\n\n .kpi-card {\n padding: 16px;\n }\n\n .kpi-value {\n font-size: 20px;\n }\n\n .compare-summary {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .analytics-table-wrapper,\n .compare-table-wrapper {\n margin: 0 -20px;\n padding: 0 20px;\n }\n\n .run-selector-list {\n max-height: 150px;\n }\n}\n\n@media (max-width: 480px) {\n .compare-summary {\n grid-template-columns: 1fr;\n }\n\n .compare-summary-card .summary-value {\n font-size: 20px;\n }\n\n .analytics-table th,\n .analytics-table td,\n .compare-table th,\n .compare-table td {\n padding: 10px 12px;\n font-size: 12px;\n }\n}\n\n/* ===========================\n Matrix Evaluation Indicators\n =========================== */\n\n/* Human Feedback Indicators */\n.cell-human {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 3px;\n min-width: 22px;\n height: 22px;\n border-radius: 50%;\n font-size: 10px;\n}\n\n.cell-human.no-feedback {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-disabled);\n}\n\n.cell-human.no-feedback i {\n font-size: 11px;\n}\n\n.cell-human.has-feedback {\n padding: 0 6px;\n border-radius: 12px;\n min-width: 36px;\n}\n\n.cell-human.has-feedback i {\n font-size: 9px;\n}\n\n.cell-human.has-feedback .rating-value {\n font-weight: 700;\n font-size: 11px;\n}\n\n/* Human rating color coding: red \u22644, yellow 5-6, light-green 7-8, green 9-10 */\n.cell-human.rating-low {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.cell-human.rating-medium {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.cell-human.rating-good {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.cell-human.rating-excellent {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n/* Auto Score Indicators */\n.cell-auto {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 3px;\n min-width: 22px;\n height: 22px;\n border-radius: 50%;\n font-size: 10px;\n}\n\n.cell-auto.no-score {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-disabled);\n}\n\n.cell-auto.no-score i {\n font-size: 11px;\n}\n\n.cell-auto.has-score {\n padding: 0 6px;\n border-radius: 12px;\n min-width: 36px;\n}\n\n.cell-auto.has-score i {\n font-size: 9px;\n}\n\n.cell-auto.has-score .score-value {\n font-weight: 700;\n font-size: 10px;\n}\n\n/* Auto score color coding (0-100%): red <50, yellow 50-69, light-green 70-84, green 85+ */\n.cell-auto.score-low {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.cell-auto.score-medium {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.cell-auto.score-good {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.cell-auto.score-excellent {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n/* Status indicators in matrix cells */\n.cell-status {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n border-radius: 50%;\n font-size: 11px;\n}\n\n.cell-status.status-passed {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.cell-status.status-failed {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.cell-status.status-error {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.cell-status.status-timeout {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.cell-status.status-skipped,\n.cell-status.status-pending {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n}\n\n.cell-status.status-running {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n/* Not-run / Skipped cells with hatch pattern */\n.result-cell.cell-not-run {\n background: repeating-linear-gradient(\n 45deg,\n var(--mj-bg-surface-card),\n var(--mj-bg-surface-card) 4px,\n var(--mj-border-default) 4px,\n var(--mj-border-default) 8px\n );\n color: var(--mj-text-disabled);\n}\n\n.result-cell.cell-not-run .cell-eval-stack {\n opacity: 0.6;\n}\n\n.cell-not-run-indicator {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n color: var(--mj-text-disabled);\n font-size: 11px;\n}\n\n/* ===========================\n Matrix Totals Footer Row\n =========================== */\n.test-matrix tfoot {\n position: sticky;\n bottom: 0;\n z-index: 2;\n}\n\n.totals-row {\n background: var(--mj-bg-surface-sunken);\n border-top: 2px solid var(--test-border);\n}\n\n.totals-row td {\n padding: 10px 12px;\n font-weight: 600;\n}\n\n.totals-row .totals-label {\n background: var(--mj-bg-surface-sunken);\n font-size: 12px;\n color: var(--test-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.totals-row .totals-cell {\n background: var(--mj-bg-surface-sunken);\n}\n\n.totals-stack {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 4px;\n}\n\n.totals-status,\n.totals-human,\n.totals-auto {\n display: flex;\n align-items: center;\n gap: 4px;\n font-size: 11px;\n padding: 2px 8px;\n border-radius: 10px;\n white-space: nowrap;\n}\n\n.totals-status {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.totals-status .pass-count {\n font-weight: 700;\n}\n\n.totals-human {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.totals-human .avg-label {\n font-weight: 700;\n}\n\n.totals-human .count-label {\n font-size: 10px;\n opacity: 0.8;\n}\n\n.totals-auto {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary-hover);\n}\n\n.totals-auto .avg-label {\n font-weight: 700;\n}\n\n.totals-auto .count-label {\n font-size: 10px;\n opacity: 0.8;\n}\n\n/* ===========================\n Editable Overview Form\n =========================== */\n\n.edit-section {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.edit-section-header {\n margin: 0 0 18px 0;\n}\n\n.edit-section-header h3 {\n margin: 0 0 4px 0;\n font-size: 18px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.edit-section-header h3 i {\n color: var(--test-primary);\n}\n\n.edit-section-sub {\n margin: 0;\n font-size: 12px;\n color: var(--test-text-muted);\n}\n\n.edit-grid {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: 18px;\n}\n\n@media (max-width: 720px) {\n .edit-grid {\n grid-template-columns: 1fr;\n }\n}\n\n.edit-field {\n display: flex;\n flex-direction: column;\n gap: 6px;\n min-width: 0;\n}\n\n.edit-field--full {\n grid-column: 1 / -1;\n}\n\n.edit-field label {\n font-size: 12px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n}\n\n.edit-field .required {\n color: var(--mj-status-error);\n margin-left: 2px;\n}\n\n.config-textarea {\n resize: vertical;\n min-height: 72px;\n font-family: inherit;\n line-height: 1.5;\n}\n\n.select-wrapper {\n position: relative;\n}\n\n.select-wrapper select.config-input {\n padding-right: 36px;\n appearance: none;\n background-color: var(--test-surface);\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='%2364748b' d='M1.41 0L6 4.59 10.59 0 12 1.41l-6 6-6-6z'/%3E%3C/svg%3E\");\n background-repeat: no-repeat;\n background-position: right 14px center;\n background-size: 10px 7px;\n}\n\n/* Tag editor (chips + inline input) */\n.tag-editor {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n padding: 8px 10px;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n background: var(--test-surface);\n transition: var(--test-transition);\n cursor: text;\n min-height: 42px;\n align-items: center;\n}\n\n.tag-editor:focus-within {\n border-color: var(--test-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.tag-chip-editable {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 3px 4px 3px 10px;\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary-hover);\n border-radius: 999px;\n font-size: 12px;\n font-weight: 600;\n line-height: 1;\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 25%, transparent);\n}\n\n.tag-chip-editable .tag-remove {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 18px;\n height: 18px;\n border-radius: 50%;\n border: none;\n background: transparent;\n color: var(--mj-brand-primary);\n cursor: pointer;\n font-size: 10px;\n transition: background 0.15s;\n}\n\n.tag-chip-editable .tag-remove:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 25%, transparent);\n color: var(--mj-brand-primary-hover);\n}\n\n.tag-input-inline {\n flex: 1;\n min-width: 140px;\n border: none;\n background: transparent;\n outline: none;\n font-size: 13px;\n color: var(--test-text);\n padding: 4px 2px;\n}\n\n.tag-input-inline::placeholder {\n color: var(--test-text-muted);\n}\n\n/* Read-only metadata section */\n.meta-section {\n background: var(--mj-bg-surface-sunken);\n border-radius: var(--test-radius-md);\n padding: 14px 18px;\n border: 1px solid var(--test-border);\n}\n\n.meta-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));\n gap: 14px;\n}\n\n.meta-item {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n}\n\n.meta-label {\n font-size: 10px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n}\n\n.meta-value {\n font-size: 12px;\n color: var(--test-text-secondary);\n font-weight: 500;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.meta-mono {\n font-family: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, monospace;\n font-size: 11px;\n}\n\n/* Dirty indicator next to the title */\n.dirty-indicator {\n display: inline-block;\n margin-left: 8px;\n font-size: 14px;\n color: var(--mj-status-warning);\n line-height: 1;\n animation: pulseDot 1.8s ease-in-out infinite;\n vertical-align: middle;\n}\n\n@keyframes pulseDot {\n 0%, 100% { opacity: 1; transform: scale(1); }\n 50% { opacity: 0.5; transform: scale(0.85); }\n}\n\n.unsaved-pill {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning-text, var(--mj-status-warning));\n border: 1px solid color-mix(in srgb, var(--mj-status-warning) 30%, transparent);\n border-radius: 999px;\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.4px;\n}\n\n.unsaved-pill i {\n font-size: 6px;\n animation: pulseDot 1.8s ease-in-out infinite;\n}\n\n/* Pad the bottom of the tab content when the save bar is visible\n so the bar doesn't cover the last form field. */\n.tab-content.has-savebar {\n padding-bottom: 84px;\n}\n\n/* ===========================\n Sticky Save Bar\n =========================== */\n\n.save-bar {\n position: absolute;\n left: 16px;\n right: 96px; /* leaves room for the bottom-right chat launcher */\n bottom: 16px;\n z-index: 50;\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 16px;\n padding: 12px 16px 12px 20px;\n background: var(--mj-bg-surface-elevated, var(--test-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-warning) 25%, var(--test-border));\n border-radius: 14px;\n box-shadow: 0 12px 32px color-mix(in srgb, var(--mj-status-warning) 10%, rgba(0, 0, 0, 0.18));\n backdrop-filter: blur(8px);\n /* Hidden / off-screen state by default. The .save-bar--visible class\n animates it up into view. Using `transition` (not `animation`)\n guarantees the change runs every time isDirty toggles. */\n opacity: 0;\n transform: translateY(calc(100% + 32px));\n pointer-events: none;\n transition:\n transform 420ms cubic-bezier(0.16, 1, 0.3, 1),\n opacity 260ms cubic-bezier(0.16, 1, 0.3, 1);\n will-change: transform, opacity;\n}\n\n.save-bar--visible {\n opacity: 1;\n transform: translateY(0);\n pointer-events: auto;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .save-bar {\n transition: opacity 180ms ease-out;\n transform: none;\n }\n .save-bar--visible {\n transform: none;\n }\n}\n\n.save-bar-message {\n display: flex;\n align-items: center;\n gap: 12px;\n min-width: 0;\n}\n\n.save-bar-dot {\n color: var(--mj-status-warning);\n font-size: 12px;\n line-height: 1;\n animation: pulseDot 1.8s ease-in-out infinite;\n}\n\n.save-bar-text {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n}\n\n.save-bar-text strong {\n font-size: 14px;\n color: var(--test-text);\n font-weight: 700;\n}\n\n.save-bar-fields {\n font-size: 12px;\n color: var(--test-text-muted);\n}\n\n.save-bar-actions {\n display: flex;\n align-items: center;\n gap: 8px;\n flex-shrink: 0;\n}\n\n.save-bar-btn {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 9px 16px;\n font-size: 13px;\n font-weight: 600;\n border-radius: 8px;\n border: 1px solid transparent;\n cursor: pointer;\n transition: var(--test-transition);\n font-family: inherit;\n}\n\n.save-bar-btn:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.save-bar-btn--primary {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse, white);\n border-color: var(--mj-brand-primary);\n box-shadow: 0 2px 8px color-mix(in srgb, var(--mj-brand-primary) 35%, transparent);\n}\n\n.save-bar-btn--primary:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover, var(--mj-brand-primary));\n transform: translateY(-1px);\n box-shadow: 0 4px 12px color-mix(in srgb, var(--mj-brand-primary) 45%, transparent);\n}\n\n.save-bar-btn--primary:active:not(:disabled) {\n transform: translateY(0);\n}\n\n.save-bar-btn--ghost {\n background: transparent;\n color: var(--test-text-secondary);\n border-color: var(--test-border);\n}\n\n.save-bar-btn--ghost:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover, var(--mj-bg-surface-card));\n color: var(--test-text);\n border-color: var(--test-text-muted);\n}\n\n.save-bar-kbd {\n display: inline-flex;\n gap: 3px;\n margin-left: 6px;\n opacity: 0.85;\n}\n\n.save-bar-kbd kbd {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 18px;\n height: 18px;\n padding: 0 4px;\n font-size: 10px;\n font-weight: 600;\n font-family: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, monospace;\n background: color-mix(in srgb, white 18%, transparent);\n border: 1px solid color-mix(in srgb, white 35%, transparent);\n border-radius: 4px;\n color: inherit;\n}\n\n@media (max-width: 640px) {\n .save-bar {\n left: 8px;\n right: 8px;\n bottom: 88px; /* push above the chat launcher on small screens */\n flex-direction: column;\n align-items: stretch;\n padding: 12px;\n }\n .save-bar-actions {\n justify-content: space-between;\n }\n .save-bar-kbd {\n display: none;\n }\n}\n\n/* ===========================\n Tests Tab \u2014 Action Bar + Drag/Remove\n =========================== */\n\n.tests-actionbar {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n padding: 12px 16px;\n margin-bottom: 16px;\n background: var(--test-surface);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n}\n\n.tests-actionbar-text {\n display: flex;\n align-items: center;\n gap: 10px;\n flex-wrap: wrap;\n min-width: 0;\n}\n\n.tests-actionbar-text strong {\n font-size: 14px;\n color: var(--test-text);\n font-weight: 700;\n}\n\n.tests-actionbar-count {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 22px;\n height: 22px;\n padding: 0 8px;\n border-radius: 999px;\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary-hover);\n font-size: 12px;\n font-weight: 700;\n}\n\n.tests-actionbar-hint {\n font-size: 12px;\n color: var(--test-text-muted);\n}\n\n.tests-actionbar-actions {\n display: flex;\n gap: 8px;\n flex-shrink: 0;\n}\n\n/* Override the default test-item hover translate so drag transforms don't fight it. */\n.tests-list[cdk-drop-list] .test-item:hover,\n.tests-list .test-item.cdk-drag:hover {\n transform: none;\n}\n\n/* The whole row is draggable. .test-content keeps the click-to-open behavior. */\n.test-item.cdk-drag {\n position: relative;\n}\n\n.test-item .test-content {\n cursor: pointer;\n}\n\n/* Drag handle */\n.test-drag-handle {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 28px;\n border-radius: 4px;\n color: var(--test-text-muted);\n cursor: grab;\n flex-shrink: 0;\n transition: background 0.15s, color 0.15s;\n user-select: none;\n}\n\n.test-drag-handle:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n color: var(--test-primary);\n}\n\n.test-drag-handle:active,\n.cdk-drag-preview .test-drag-handle {\n cursor: grabbing;\n}\n\n/* Remove (X) button \u2014 hover-revealed */\n.test-remove-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border-radius: 50%;\n border: none;\n background: transparent;\n color: var(--test-text-muted);\n cursor: pointer;\n flex-shrink: 0;\n opacity: 0;\n transition: opacity 0.15s, background 0.15s, color 0.15s;\n}\n\n.test-item:hover .test-remove-btn,\n.test-remove-btn:focus-visible {\n opacity: 1;\n}\n\n.test-remove-btn:hover {\n background: color-mix(in srgb, var(--mj-status-error) 12%, transparent);\n color: var(--mj-status-error);\n}\n\n.test-chevron {\n cursor: pointer;\n}\n\n/* Inline remove-confirm */\n.test-remove-confirm {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 4px 8px 4px 12px;\n border-radius: 999px;\n background: color-mix(in srgb, var(--mj-status-error) 8%, var(--test-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-error) 30%, transparent);\n flex-shrink: 0;\n}\n\n.test-remove-confirm-text {\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-status-error-text, var(--mj-status-error));\n}\n\n.test-remove-confirm-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n padding: 4px 10px;\n border-radius: 6px;\n border: 1px solid transparent;\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n font-family: inherit;\n transition: var(--test-transition);\n}\n\n.test-remove-confirm-btn:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.test-remove-confirm-btn--danger {\n background: var(--mj-status-error);\n color: var(--mj-text-inverse, white);\n}\n\n.test-remove-confirm-btn--danger:hover:not(:disabled) {\n background: color-mix(in srgb, var(--mj-status-error) 88%, black);\n}\n\n.test-remove-confirm-btn--ghost {\n background: transparent;\n color: var(--test-text-secondary);\n border-color: var(--test-border);\n}\n\n.test-remove-confirm-btn--ghost:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover, var(--mj-bg-surface-card));\n color: var(--test-text);\n}\n\n/* CDK drag-drop visuals */\n.cdk-drag-preview {\n box-shadow: 0 12px 32px rgba(0, 0, 0, 0.25);\n border-radius: var(--test-radius-md);\n background: var(--test-surface);\n opacity: 0.95;\n}\n\n.cdk-drag-placeholder {\n opacity: 0;\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n border: 2px dashed var(--test-primary);\n border-radius: var(--test-radius-md);\n}\n\n.cdk-drag-placeholder * {\n visibility: hidden;\n}\n\n.cdk-drag-animating {\n transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);\n}\n\n.tests-list.cdk-drop-list-dragging .test-item:not(.cdk-drag-placeholder) {\n transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);\n}\n\n/* ===========================\n Add Tests Picker Dialog\n =========================== */\n\n.picker-backdrop {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.45);\n z-index: 200;\n animation: pickerFadeIn 180ms ease-out;\n backdrop-filter: blur(2px);\n}\n\n@keyframes pickerFadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n.picker-dialog {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: min(720px, calc(100vw - 32px));\n max-height: min(80vh, 720px);\n z-index: 201;\n display: flex;\n flex-direction: column;\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n box-shadow: 0 24px 64px rgba(0, 0, 0, 0.28);\n animation: pickerSlideUp 220ms cubic-bezier(0.16, 1, 0.3, 1);\n overflow: hidden;\n}\n\n@keyframes pickerSlideUp {\n from {\n opacity: 0;\n transform: translate(-50%, calc(-50% + 16px));\n }\n to {\n opacity: 1;\n transform: translate(-50%, -50%);\n }\n}\n\n.picker-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 18px 20px;\n border-bottom: 1px solid var(--test-border);\n}\n\n.picker-title {\n margin: 0;\n font-size: 16px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.picker-title i {\n color: var(--test-primary);\n}\n\n.picker-close {\n width: 32px;\n height: 32px;\n border-radius: 8px;\n border: none;\n background: transparent;\n color: var(--test-text-muted);\n cursor: pointer;\n font-size: 14px;\n transition: background 0.15s, color 0.15s;\n}\n\n.picker-close:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover, var(--mj-bg-surface-card));\n color: var(--test-text);\n}\n\n.picker-close:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.picker-search {\n position: relative;\n padding: 14px 20px 0 20px;\n}\n\n.picker-search-icon {\n position: absolute;\n top: 50%;\n left: 32px;\n transform: translateY(-30%);\n color: var(--test-text-muted);\n font-size: 13px;\n pointer-events: none;\n}\n\n.picker-search-input {\n width: 100%;\n padding: 10px 36px 10px 36px;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n background: var(--test-surface);\n font-size: 14px;\n color: var(--test-text);\n font-family: inherit;\n transition: var(--test-transition);\n}\n\n.picker-search-input:focus {\n outline: none;\n border-color: var(--test-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.picker-search-clear {\n position: absolute;\n top: 50%;\n right: 32px;\n transform: translateY(-30%);\n width: 22px;\n height: 22px;\n border-radius: 50%;\n border: none;\n background: transparent;\n color: var(--test-text-muted);\n cursor: pointer;\n font-size: 11px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n}\n\n.picker-search-clear:hover {\n background: var(--mj-bg-surface-hover, var(--mj-bg-surface-card));\n color: var(--test-text);\n}\n\n.picker-toolbar {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 10px 20px;\n border-bottom: 1px solid var(--test-border);\n}\n\n.picker-toolbar-status {\n font-size: 12px;\n color: var(--test-text-secondary);\n}\n\n.picker-toolbar-status strong {\n color: var(--mj-brand-primary-hover);\n font-weight: 700;\n}\n\n.picker-toolbar-actions {\n display: flex;\n gap: 14px;\n}\n\n.picker-link-btn {\n border: none;\n background: transparent;\n color: var(--test-primary);\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n padding: 0;\n font-family: inherit;\n}\n\n.picker-link-btn:hover:not(:disabled) {\n text-decoration: underline;\n}\n\n.picker-link-btn:disabled {\n color: var(--test-text-muted);\n cursor: not-allowed;\n}\n\n.picker-body {\n flex: 1;\n overflow-y: auto;\n padding: 8px 12px;\n min-height: 200px;\n}\n\n.picker-loading {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 40px;\n}\n\n.picker-list {\n list-style: none;\n padding: 0;\n margin: 0;\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.picker-row {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 12px;\n border-radius: 8px;\n cursor: pointer;\n transition: background 0.12s, border-color 0.12s;\n border: 1px solid transparent;\n}\n\n.picker-row:hover {\n background: var(--mj-bg-surface-hover, var(--mj-bg-surface-card));\n}\n\n.picker-row:focus-visible {\n outline: none;\n border-color: var(--test-primary);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.picker-row--selected {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--test-surface));\n border-color: color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n}\n\n.picker-row--selected:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--test-surface));\n}\n\n.picker-check {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 20px;\n height: 20px;\n border-radius: 5px;\n border: 1.5px solid var(--test-border);\n background: var(--test-surface);\n color: var(--mj-text-inverse, white);\n font-size: 11px;\n flex-shrink: 0;\n transition: background 0.12s, border-color 0.12s;\n}\n\n.picker-row--selected .picker-check {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n}\n\n.picker-row-main {\n flex: 1;\n min-width: 0;\n}\n\n.picker-row-name {\n font-size: 13px;\n font-weight: 600;\n color: var(--test-text);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.picker-row-desc {\n font-size: 12px;\n color: var(--test-text-muted);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n margin-top: 2px;\n}\n\n.picker-row-meta {\n display: flex;\n align-items: center;\n gap: 6px;\n flex-shrink: 0;\n}\n\n.picker-row-pill {\n display: inline-flex;\n align-items: center;\n padding: 2px 8px;\n border-radius: 999px;\n font-size: 10px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.3px;\n background: var(--mj-bg-surface-sunken, var(--test-bg));\n color: var(--test-text-secondary);\n border: 1px solid var(--test-border);\n}\n\n.picker-row-pill--status[data-status=\"active\"] {\n background: color-mix(in srgb, var(--mj-status-success) 12%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n border-color: color-mix(in srgb, var(--mj-status-success) 30%, transparent);\n}\n\n.picker-row-pill--status[data-status=\"disabled\"] {\n background: var(--mj-bg-surface-sunken, var(--test-bg));\n color: var(--test-text-muted);\n}\n\n.picker-row-pill--status[data-status=\"pending\"] {\n background: color-mix(in srgb, var(--mj-status-warning) 12%, var(--mj-bg-surface));\n color: var(--mj-status-warning-text, var(--mj-status-warning));\n border-color: color-mix(in srgb, var(--mj-status-warning) 30%, transparent);\n}\n\n.picker-footer {\n display: flex;\n gap: 8px;\n padding: 14px 20px;\n border-top: 1px solid var(--test-border);\n background: var(--mj-bg-surface-sunken, var(--test-bg));\n}\n\n.picker-btn {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 9px 16px;\n font-size: 13px;\n font-weight: 600;\n border-radius: 8px;\n border: 1px solid transparent;\n cursor: pointer;\n font-family: inherit;\n transition: var(--test-transition);\n}\n\n.picker-btn:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.picker-btn--primary {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse, white);\n border-color: var(--mj-brand-primary);\n}\n\n.picker-btn--primary:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover, var(--mj-brand-primary));\n}\n\n.picker-btn--ghost {\n background: transparent;\n color: var(--test-text-secondary);\n border-color: var(--test-border);\n}\n\n.picker-btn--ghost:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover, var(--mj-bg-surface-card));\n color: var(--test-text);\n}\n\n@media (max-width: 640px) {\n .picker-dialog {\n width: calc(100vw - 16px);\n max-height: calc(100vh - 32px);\n }\n .tests-actionbar {\n flex-direction: column;\n align-items: stretch;\n }\n .tests-actionbar-actions {\n justify-content: flex-end;\n }\n .test-remove-btn {\n opacity: 1; /* always visible on touch */\n }\n}\n\n"] }]
5029
+ args: [{ standalone: false, selector: 'mj-test-suite-form', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"test-suite-form\">\n <!-- Header Section -->\n <div class=\"suite-header\">\n <!-- Breadcrumb Navigation -->\n <nav class=\"breadcrumb\" aria-label=\"Breadcrumb\">\n <ol>\n <li>\n <a href=\"javascript:void(0)\" (click)=\"navigateToTestingDashboard()\">\n <i class=\"fas fa-vial\"></i>\n <span class=\"breadcrumb-text\">Testing</span>\n </a>\n </li>\n <li class=\"current\">\n <i class=\"fas fa-chevron-right separator\"></i>\n <i class=\"fas fa-layer-group\"></i>\n <span>{{ record.Name }}</span>\n </li>\n </ol>\n </nav>\n\n <div class=\"header-content\">\n <div class=\"header-left\">\n <div class=\"suite-icon\" [style.background-color]=\"getStatusColor()\">\n <i class=\"fas fa-layer-group\"></i>\n </div>\n <div class=\"suite-info\">\n <h1>\n {{ record.Name }}\n @if (isDirty) {\n <span class=\"dirty-indicator\" title=\"You have unsaved changes\" aria-label=\"Unsaved changes\">\u25CF</span>\n }\n </h1>\n <div class=\"suite-meta\">\n <span class=\"status-badge\" [ngClass]=\"getStatusClass()\">\n <i class=\"fas\" [ngClass]=\"record.Status === 'Active' ? 'fa-circle-check' : 'fa-circle-pause'\"></i>\n {{ record.Status }}\n </span>\n @if (testsLoaded) {\n <span class=\"test-count\">\n <i class=\"fas fa-flask\"></i>\n {{ suiteTests.length }} tests\n </span>\n }\n @if (isDirty) {\n <span class=\"unsaved-pill\" title=\"You have unsaved changes\">\n <i class=\"fas fa-circle\"></i> Unsaved\n </span>\n }\n </div>\n </div>\n </div>\n <div class=\"header-actions\">\n <app-evaluation-mode-toggle></app-evaluation-mode-toggle>\n <button mjButton (click)=\"exportToExcel()\" title=\"Export to CSV\">\n <i class=\"fas fa-file-excel\"></i> Export\n </button>\n <button mjButton (click)=\"runSuite()\" variant=\"primary\">\n <i class=\"fas fa-play\"></i> Run Suite\n </button>\n <button mjButton (click)=\"refresh()\" [disabled]=\"isRefreshing\">\n <i class=\"fas\" [ngClass]=\"isRefreshing ? 'fa-sync fa-spin' : 'fa-sync'\"></i>\n {{ isRefreshing ? 'Refreshing...' : 'Refresh' }}\n </button>\n </div>\n </div>\n @if (record.Description) {\n <div class=\"suite-description\">\n <p>{{ record.Description }}</p>\n </div>\n }\n </div>\n\n <!-- Tabs -->\n <div class=\"tabs-container\">\n <div class=\"tabs\" role=\"tablist\">\n <button class=\"tab\"\n [class.active]=\"activeTab === 'overview'\"\n (click)=\"changeTab('overview')\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'overview'\">\n <i class=\"fas fa-th-large\"></i> Overview\n </button>\n <button class=\"tab\"\n [class.active]=\"activeTab === 'tests'\"\n (click)=\"changeTab('tests')\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'tests'\">\n <i class=\"fas fa-flask\"></i> Tests\n @if (testsLoaded) {\n <span class=\"tab-badge\">{{ suiteTests.length }}</span>\n }\n </button>\n <button class=\"tab\"\n [class.active]=\"activeTab === 'runs'\"\n (click)=\"changeTab('runs')\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'runs'\">\n <i class=\"fas fa-history\"></i> Runs\n @if (runsLoaded) {\n <span class=\"tab-badge\">{{ suiteRuns.length }}</span>\n }\n </button>\n <button class=\"tab\"\n [class.active]=\"activeTab === 'analytics'\"\n (click)=\"changeTab('analytics')\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'analytics'\">\n <i class=\"fas fa-chart-line\"></i> Analytics\n </button>\n <button class=\"tab\"\n [class.active]=\"activeTab === 'compare'\"\n (click)=\"changeTab('compare')\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'compare'\">\n <i class=\"fas fa-balance-scale\"></i> Compare\n </button>\n </div>\n </div>\n\n <!-- Tab Content -->\n <div class=\"tab-content\" [class.has-savebar]=\"isDirty\">\n <!-- Overview Tab -->\n @if (activeTab === 'overview') {\n <div class=\"overview-tab\">\n <!-- Editable Details -->\n <section class=\"edit-section\">\n <header class=\"edit-section-header\">\n <h3><i class=\"fas fa-pen-to-square\"></i> Details</h3>\n <p class=\"edit-section-sub\">Edit any field \u2014 changes are saved with the bar at the bottom.</p>\n </header>\n <div class=\"edit-grid\">\n <div class=\"edit-field edit-field--full\">\n <label for=\"suite-name\">Name <span class=\"required\">*</span></label>\n <input\n id=\"suite-name\"\n type=\"text\"\n class=\"config-input\"\n placeholder=\"e.g., Core Agent Test Suite\"\n [(ngModel)]=\"record.Name\"\n />\n </div>\n\n <div class=\"edit-field edit-field--full\">\n <label for=\"suite-description\">Description</label>\n <textarea\n id=\"suite-description\"\n class=\"config-input config-textarea\"\n rows=\"3\"\n placeholder=\"What does this suite cover?\"\n [ngModel]=\"record.Description\"\n (ngModelChange)=\"record.Description = $event || null\"\n ></textarea>\n </div>\n\n <div class=\"edit-field\">\n <label for=\"suite-status\">Status</label>\n <div class=\"select-wrapper\">\n <select\n id=\"suite-status\"\n class=\"config-input\"\n [(ngModel)]=\"record.Status\"\n >\n @for (opt of statusOptions; track opt) {\n <option [ngValue]=\"opt\">{{ opt }}</option>\n }\n </select>\n </div>\n </div>\n\n <div class=\"edit-field\">\n <label for=\"suite-rubric\">Rubric</label>\n <select\n id=\"suite-rubric\"\n class=\"config-input\"\n [ngModel]=\"record.RubricID\"\n (ngModelChange)=\"record.RubricID = $event || null\"\n >\n <option [ngValue]=\"null\">\u2014 None \u2014</option>\n @for (rubric of RubricOptions; track rubric.id) {\n <option [ngValue]=\"rubric.id\">{{ rubric.name }}</option>\n }\n </select>\n </div>\n\n <div class=\"edit-field\">\n <label for=\"suite-parent\">Parent Suite</label>\n <select\n id=\"suite-parent\"\n class=\"config-input\"\n [ngModel]=\"record.ParentID\"\n (ngModelChange)=\"record.ParentID = $event || null\"\n >\n <option [ngValue]=\"null\">\u2014 None (top-level) \u2014</option>\n @for (s of parentSuiteOptions; track s.ID) {\n <option [ngValue]=\"s.ID\">{{ s.Name }}</option>\n }\n </select>\n </div>\n\n <div class=\"edit-field edit-field--full\">\n <label for=\"suite-tags\">Tags</label>\n <div class=\"tag-editor\" (click)=\"tagInput.focus()\">\n @for (tag of tags; track tag) {\n <span class=\"tag-chip-editable\">\n {{ tag }}\n <button type=\"button\" class=\"tag-remove\" (click)=\"removeTag(tag); $event.stopPropagation()\" [attr.aria-label]=\"'Remove tag ' + tag\">\n <i class=\"fas fa-times\"></i>\n </button>\n </span>\n }\n <input\n #tagInput\n id=\"suite-tags\"\n type=\"text\"\n class=\"tag-input-inline\"\n [placeholder]=\"tags.length === 0 ? 'Add tags, press Enter or comma...' : ''\"\n [(ngModel)]=\"tagDraft\"\n (keydown)=\"onTagInputKeydown($event)\"\n (blur)=\"addTagFromDraft()\"\n />\n </div>\n <span class=\"config-hint\">Press Enter or comma to add a tag. Backspace on empty input removes the last tag.</span>\n </div>\n </div>\n </section>\n\n <!-- Execution Settings -->\n <section class=\"edit-section\">\n <header class=\"edit-section-header\">\n <h3><i class=\"fas fa-cogs\"></i> Execution Settings</h3>\n </header>\n <div class=\"edit-grid\">\n <div class=\"edit-field\">\n <label for=\"suite-timeout\">Max Execution Time (ms)</label>\n <input\n id=\"suite-timeout\"\n type=\"number\"\n class=\"config-input\"\n placeholder=\"Default: 300000 (5 min)\"\n [ngModel]=\"record.MaxExecutionTimeMS\"\n (ngModelChange)=\"record.MaxExecutionTimeMS = $event === '' || $event === null ? null : +$event\"\n />\n <span class=\"config-hint\">Default timeout for tests in this suite. Currently: {{ formatTimeout(record.MaxExecutionTimeMS) }}</span>\n </div>\n </div>\n </section>\n\n <!-- Metadata (read-only) -->\n <section class=\"meta-section\">\n <div class=\"meta-grid\">\n <div class=\"meta-item\">\n <div class=\"meta-label\">Created</div>\n <div class=\"meta-value\">{{ record.__mj_CreatedAt | date:'medium' }}</div>\n </div>\n <div class=\"meta-item\">\n <div class=\"meta-label\">Last updated</div>\n <div class=\"meta-value\">{{ record.__mj_UpdatedAt | date:'medium' }}</div>\n </div>\n <div class=\"meta-item\">\n <div class=\"meta-label\">Suite ID</div>\n <div class=\"meta-value meta-mono\">{{ record.ID }}</div>\n </div>\n </div>\n </section>\n </div>\n }\n\n <!-- Tests Tab -->\n @if (activeTab === 'tests') {\n <div class=\"tests-tab\">\n <!-- Header: action bar -->\n <div class=\"tests-actionbar\">\n <div class=\"tests-actionbar-text\">\n <strong>Suite tests</strong>\n @if (testsLoaded) {\n <span class=\"tests-actionbar-count\">{{ suiteTests.length }}</span>\n }\n <span class=\"tests-actionbar-hint\">Drag to reorder \u00B7 Hover a row to remove</span>\n </div>\n <div class=\"tests-actionbar-actions\">\n <button mjButton variant=\"primary\" (click)=\"openAddTestsDialog()\" [disabled]=\"isReorderingTests\">\n <i class=\"fas fa-plus\"></i> Add tests\n </button>\n </div>\n </div>\n\n <!-- Loading State -->\n @if (loadingTests) {\n <div class=\"loading-state\">\n <div class=\"skeleton-list\">\n @for (i of [1,2,3,4,5]; track i) {\n <div class=\"skeleton-card\">\n <div class=\"skeleton-sequence\"></div>\n <div class=\"skeleton-icon\"></div>\n <div class=\"skeleton-content\">\n <div class=\"skeleton-line wide\"></div>\n <div class=\"skeleton-line narrow\"></div>\n </div>\n </div>\n }\n </div>\n </div>\n }\n <!-- Tests List -->\n @if (!loadingTests && suiteTests.length > 0) {\n <div class=\"tests-list\" cdkDropList (cdkDropListDropped)=\"onTestDrop($event)\">\n @for (test of suiteTests; track test.ID) {\n <div class=\"test-item\" cdkDrag [cdkDragDisabled]=\"isReorderingTests || isRemovingTest\">\n <span class=\"test-drag-handle\" cdkDragHandle title=\"Drag to reorder\" aria-label=\"Drag to reorder\">\n <i class=\"fas fa-grip-vertical\"></i>\n </span>\n <div class=\"test-sequence\">{{ test.Sequence }}</div>\n <div class=\"test-icon\"><i class=\"fas fa-flask\"></i></div>\n <div class=\"test-content\" (click)=\"openTest(test.TestID)\">\n <div class=\"test-name\">{{ test.Test }}</div>\n <div class=\"test-status\">\n @if (test.Status) {\n <span><i class=\"fas fa-info-circle\"></i> {{ test.Status }}</span>\n }\n </div>\n </div>\n <!-- Inline remove confirm OR hover-reveal X -->\n @if (confirmingRemoveSuiteTestId === test.ID) {\n <div class=\"test-remove-confirm\" (click)=\"$event.stopPropagation()\">\n <span class=\"test-remove-confirm-text\">Remove from suite?</span>\n <button\n type=\"button\"\n class=\"test-remove-confirm-btn test-remove-confirm-btn--danger\"\n (click)=\"confirmRemoveTest(test, $event)\"\n [disabled]=\"isRemovingTest\"\n >\n @if (isRemovingTest) {\n <i class=\"fas fa-spinner fa-spin\"></i>\n } @else {\n Remove\n }\n </button>\n <button\n type=\"button\"\n class=\"test-remove-confirm-btn test-remove-confirm-btn--ghost\"\n (click)=\"cancelRemoveTest($event)\"\n [disabled]=\"isRemovingTest\"\n >\n Cancel\n </button>\n </div>\n } @else {\n <button\n type=\"button\"\n class=\"test-remove-btn\"\n title=\"Remove from suite\"\n aria-label=\"Remove from suite\"\n (click)=\"requestRemoveTest(test, $event)\"\n >\n <i class=\"fas fa-times\"></i>\n </button>\n <i class=\"fas fa-chevron-right test-chevron\" (click)=\"openTest(test.TestID)\"></i>\n }\n </div>\n }\n </div>\n }\n <!-- Empty State -->\n @if (testsLoaded && !loadingTests && suiteTests.length === 0) {\n <mj-empty-state\n Icon=\"fa-solid fa-flask\"\n Title=\"No Tests in Suite\"\n Message=\"Add tests to this suite to start running them together.\"\n ActionText=\"Add tests\"\n ActionIcon=\"fa-solid fa-plus\"\n (Action)=\"openAddTestsDialog()\" />\n }\n </div>\n }\n\n <!-- Runs Tab -->\n @if (activeTab === 'runs') {\n <div class=\"runs-tab\">\n <!-- Loading State -->\n @if (loadingRuns) {\n <div class=\"loading-state\">\n <div class=\"skeleton-list\">\n @for (i of [1,2,3]; track i) {\n <div class=\"skeleton-card\">\n <div class=\"skeleton-icon\"></div>\n <div class=\"skeleton-content\">\n <div class=\"skeleton-line wide\"></div>\n <div class=\"skeleton-line narrow\"></div>\n </div>\n </div>\n }\n </div>\n </div>\n }\n <!-- Runs List -->\n @if (!loadingRuns && suiteRuns.length > 0) {\n <div class=\"runs-list\">\n @for (run of suiteRuns; track run) {\n <div class=\"run-item\" (click)=\"openSuiteRun(run.ID)\">\n <div class=\"run-icon\" [style.background-color]=\"getRunStatusColor(run.Status)\">\n <i class=\"fas\"\n [class.fa-check]=\"run.Status === 'Completed'\"\n [class.fa-times]=\"run.Status === 'Failed'\"\n [class.fa-spinner]=\"run.Status === 'Running'\"\n [class.fa-clock]=\"run.Status === 'Pending'\"\n [class.fa-ban]=\"run.Status === 'Cancelled'\"></i>\n </div>\n <div class=\"run-content\">\n <div class=\"run-header\">\n <span class=\"run-id\">Run #{{ run.ID.substring(0, 8) }}</span>\n <span class=\"run-status\" [style.color]=\"getRunStatusColor(run.Status)\">{{ run.Status }}</span>\n </div>\n <div class=\"run-meta\">\n <span><i class=\"fas fa-calendar\"></i> {{ getRelativeTime(run.StartedAt) }}</span>\n @if (run.TotalTests) {\n <span>\n <i class=\"fas fa-check-circle\"></i> {{ run.PassedTests }}/{{ run.TotalTests }}\n ({{ getPassRate(run).toFixed(0) }}%)\n </span>\n }\n </div>\n <!-- Evaluation metrics row -->\n <div class=\"run-eval-metrics\">\n <!-- Status badge -->\n @if (evalPreferences.showExecution) {\n <span class=\"eval-metric status\" [class]=\"'status-' + run.Status.toLowerCase()\">\n <i class=\"fas\"\n [class.fa-circle-check]=\"run.Status === 'Completed'\"\n [class.fa-circle-xmark]=\"run.Status === 'Failed'\"\n [class.fa-spinner]=\"run.Status === 'Running'\"\n [class.fa-clock]=\"run.Status === 'Pending'\"\n [class.fa-ban]=\"run.Status === 'Cancelled'\"></i>\n </span>\n }\n <!-- Human score (placeholder - need avg from suite run) -->\n @if (evalPreferences.showHuman) {\n <span class=\"eval-metric human\" title=\"Human evaluation\">\n <i class=\"fas fa-user\"></i>\n <span class=\"eval-pending\"><i class=\"fas fa-clock\"></i></span>\n </span>\n }\n <!-- Auto score (pass rate as proxy) -->\n @if (evalPreferences.showAuto && run.TotalTests) {\n <span class=\"eval-metric auto\"\n [class.high]=\"getPassRate(run) >= 80\"\n [class.medium]=\"getPassRate(run) >= 50 && getPassRate(run) < 80\"\n [class.low]=\"getPassRate(run) < 50\"\n title=\"Auto score (pass rate)\">\n <i class=\"fas fa-robot\"></i>\n <span>{{ getPassRate(run).toFixed(0) }}%</span>\n </span>\n }\n </div>\n <!-- Tags display -->\n @if (getRunTags(run).length > 0) {\n <div class=\"run-tags\">\n @for (tag of getRunTags(run); track tag) {\n <span class=\"tag-chip\">{{ tag }}</span>\n }\n </div>\n }\n </div>\n <i class=\"fas fa-chevron-right\"></i>\n </div>\n }\n </div>\n }\n <!-- Empty State -->\n @if (runsLoaded && !loadingRuns && suiteRuns.length === 0) {\n <mj-empty-state\n Icon=\"fa-solid fa-circle-play\"\n Title=\"No Suite Runs Yet\"\n Message=\"Run this suite to see execution history and results here.\"\n ActionText=\"Run Suite Now\"\n ActionIcon=\"fa-solid fa-play\"\n (Action)=\"runSuite()\" />\n }\n </div>\n }\n\n <!-- Analytics Tab -->\n @if (activeTab === 'analytics') {\n <div class=\"analytics-tab\">\n <!-- Loading State -->\n @if (loadingAnalytics) {\n <div class=\"loading-state\">\n <mj-loading text=\"Loading analytics data...\"></mj-loading>\n </div>\n }\n @if (!loadingAnalytics && analyticsLoaded) {\n <!-- View Toggle Sub-nav -->\n <div class=\"analytics-subnav\">\n <div class=\"subnav-tabs\">\n <button class=\"subnav-tab\"\n [class.active]=\"analyticsView === 'summary'\"\n (click)=\"setAnalyticsView('summary')\">\n <i class=\"fas fa-chart-bar\"></i>\n <span>Summary</span>\n </button>\n <button class=\"subnav-tab\"\n [class.active]=\"analyticsView === 'matrix'\"\n (click)=\"setAnalyticsView('matrix')\">\n <i class=\"fas fa-th\"></i>\n <span>Matrix</span>\n </button>\n <button class=\"subnav-tab\"\n [class.active]=\"analyticsView === 'chart'\"\n (click)=\"setAnalyticsView('chart')\">\n <i class=\"fas fa-project-diagram\"></i>\n <span>Chart</span>\n </button>\n </div>\n </div>\n <!-- Collapsible Filters (shared by both views) -->\n <mj-accordion-panel Size=\"sm\" [FlushBody]=\"true\"\n [Expanded]=\"!filtersCollapsed\" (ExpandedChange)=\"onFiltersExpandedChange($event)\">\n <ng-template mjAccordionTitle>\n <i class=\"fas fa-filter\" style=\"color: var(--test-primary);\"></i>\n Filters\n @if (filtersCollapsed) {\n <span class=\"mj-accordion-badge mj-accordion-badge--right mj-accordion-badge--muted\">\n {{ analyticsTimeRange === 'all' ? 'All Time' : analyticsTimeRange }}\n @if (selectedTags.length > 0) {\n <span> \u00B7 {{ selectedTags.length }} tags</span>\n }\n </span>\n }\n </ng-template>\n <ng-template mjAccordionBody>\n <div class=\"filters-content\">\n <div class=\"filter-group\">\n <label>Time Range</label>\n <div class=\"filter-buttons\">\n <button class=\"filter-btn\" [class.active]=\"analyticsTimeRange === '7d'\" (click)=\"setTimeRange('7d')\">7 Days</button>\n <button class=\"filter-btn\" [class.active]=\"analyticsTimeRange === '30d'\" (click)=\"setTimeRange('30d')\">30 Days</button>\n <button class=\"filter-btn\" [class.active]=\"analyticsTimeRange === '90d'\" (click)=\"setTimeRange('90d')\">90 Days</button>\n <button class=\"filter-btn\" [class.active]=\"analyticsTimeRange === 'all'\" (click)=\"setTimeRange('all')\">All Time</button>\n </div>\n </div>\n @if (uniqueTags.length > 0) {\n <div class=\"filter-group\">\n <label>Filter by Tag @if (selectedTags.length > 0) {\n <span class=\"filter-hint\">({{ selectedTags.length }} selected)</span>\n }</label>\n <div class=\"filter-buttons tag-filters\">\n <button class=\"filter-btn tag-btn all-tags-btn\"\n [class.active]=\"selectedTags.length === 0\"\n (click)=\"toggleTagFilter(null)\">\n <i class=\"fas fa-layer-group\"></i> All Tags\n </button>\n @for (tag of uniqueTags; track tag) {\n <button class=\"filter-btn tag-btn\"\n [class.active]=\"isTagSelected(tag)\"\n (click)=\"toggleTagFilter(tag)\">\n @if (isTagSelected(tag)) {\n <i class=\"fas fa-check\"></i>\n }\n {{ tag }}\n </button>\n }\n </div>\n </div>\n }\n </div>\n </ng-template>\n </mj-accordion-panel>\n <!-- Summary View -->\n @if (analyticsView === 'summary') {\n <!-- KPI Cards -->\n <div class=\"analytics-kpis\">\n <div class=\"kpi-card\">\n <div class=\"kpi-icon\"><i class=\"fas fa-play-circle\"></i></div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{ getTotalRuns() }}</div>\n <div class=\"kpi-label\">Total Runs</div>\n </div>\n </div>\n <div class=\"kpi-card\">\n <div class=\"kpi-icon success\"><i class=\"fas fa-check-circle\"></i></div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{ getAveragePassRate().toFixed(1) }}%</div>\n <div class=\"kpi-label\">Avg Pass Rate</div>\n <div class=\"kpi-trend\" [ngClass]=\"{'trend-up': getPassRateTrend().direction === 'up', 'trend-down': getPassRateTrend().direction === 'down'}\">\n <i class=\"fas\" [ngClass]=\"{'fa-arrow-up': getPassRateTrend().direction === 'up', 'fa-arrow-down': getPassRateTrend().direction === 'down', 'fa-minus': getPassRateTrend().direction === 'stable'}\"></i>\n {{ getPassRateTrend().value.toFixed(1) }}%\n </div>\n </div>\n </div>\n <div class=\"kpi-card\">\n <div class=\"kpi-icon info\"><i class=\"fas fa-clock\"></i></div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{ formatDuration(getAverageDuration()) }}</div>\n <div class=\"kpi-label\">Avg Duration</div>\n </div>\n </div>\n <div class=\"kpi-card\">\n <div class=\"kpi-icon warning\"><i class=\"fas fa-dollar-sign\"></i></div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{ formatCost(getTotalCost()) }}</div>\n <div class=\"kpi-label\">Total Cost</div>\n </div>\n </div>\n </div>\n <!-- Runs Table -->\n <div class=\"analytics-table-section\">\n <h3><i class=\"fas fa-table\"></i> Run History</h3>\n <div class=\"analytics-table-wrapper\">\n <table class=\"analytics-table\">\n <thead>\n <tr>\n <th>Date</th>\n <th>Status</th>\n <th>Pass Rate</th>\n <th>Tests</th>\n <th>Duration</th>\n <th>Cost</th>\n <th>Tags</th>\n </tr>\n </thead>\n <tbody>\n @for (dp of getFilteredAnalyticsData(); track dp) {\n <tr (click)=\"openSuiteRun(dp.runId)\" class=\"clickable-row\">\n <td>{{ dp.date | date:'short' }}</td>\n <td>\n <span class=\"status-chip\" [ngClass]=\"'status-' + dp.status.toLowerCase()\">{{ dp.status }}</span>\n </td>\n <td>\n <div class=\"pass-rate-cell\">\n <div class=\"pass-rate-bar\" [style.width.%]=\"dp.passRate\" [ngClass]=\"{'high': dp.passRate >= 80, 'medium': dp.passRate >= 50 && dp.passRate < 80, 'low': dp.passRate < 50}\"></div>\n <span>{{ dp.passRate.toFixed(0) }}%</span>\n </div>\n </td>\n <td>{{ dp.passedTests }}/{{ dp.totalTests }}</td>\n <td>{{ formatDuration(dp.duration) }}</td>\n <td>{{ formatCost(dp.cost) }}</td>\n <td>\n <div class=\"tag-cell\">\n @for (tag of dp.tags.slice(0, 2); track tag) {\n <span class=\"tag-chip-table\">{{ tag }}</span>\n }\n @if (dp.tags.length > 2) {\n <span class=\"tag-more\">+{{ dp.tags.length - 2 }}</span>\n }\n </div>\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n @if (getFilteredAnalyticsData().length === 0) {\n <mj-empty-state\n Variant=\"no-results\"\n Size=\"compact\"\n Title=\"No runs match the current filters.\" />\n }\n </div>\n }\n <!-- Matrix View -->\n @if (analyticsView === 'matrix') {\n <!-- Loading Matrix -->\n @if (loadingMatrix) {\n <div class=\"loading-state\">\n <mj-loading text=\"Loading test matrix...\"></mj-loading>\n </div>\n }\n <!-- Matrix Content -->\n @if (!loadingMatrix && matrixLoaded && matrixData.length > 0) {\n <div class=\"matrix-section\">\n <div class=\"matrix-header\">\n <h3><i class=\"fas fa-th\"></i> Test Results Matrix</h3>\n <div class=\"matrix-header-right\">\n <div class=\"matrix-filter-input\">\n <i class=\"fas fa-search\"></i>\n <input type=\"text\"\n placeholder=\"Filter tests...\"\n [value]=\"matrixTestFilter\"\n (input)=\"onMatrixFilterInput($event)\"\n class=\"filter-input\">\n @if (matrixTestFilter) {\n <button class=\"clear-filter-btn\" (click)=\"clearMatrixFilter()\" title=\"Clear filter\">\n <i class=\"fas fa-times\"></i>\n </button>\n }\n </div>\n <span class=\"matrix-run-count\">{{ matrixData.length }} runs \u00B7 {{ getUniqueTestsFromMatrix().length }} tests</span>\n <button mjButton (click)=\"exportMatrixToCSV()\" [disabled]=\"matrixData.length === 0\" title=\"Export matrix to CSV\">\n <i class=\"fas fa-download\"></i> Export\n </button>\n </div>\n </div>\n <div class=\"matrix-scroll-container\">\n <table class=\"test-matrix\">\n <thead>\n <tr>\n <th class=\"seq-header\" (click)=\"toggleMatrixSort('sequence')\" title=\"Sort by sequence\">\n #\n <i class=\"fas\" [ngClass]=\"matrixSortBy === 'sequence' ? (matrixSortAsc ? 'fa-sort-up' : 'fa-sort-down') : 'fa-sort'\"></i>\n </th>\n <th class=\"test-name-header\" (click)=\"toggleMatrixSort('name')\" title=\"Sort by name\">\n Test\n <i class=\"fas\" [ngClass]=\"matrixSortBy === 'name' ? (matrixSortAsc ? 'fa-sort-up' : 'fa-sort-down') : 'fa-sort'\"></i>\n </th>\n @for (run of matrixData; track run) {\n <th class=\"run-header\" (click)=\"openSuiteRun(run.runId)\" [title]=\"'Click to view suite run - ' + (run.date | date:'medium')\">\n <div class=\"run-header-content\">\n @if (run.tags.length > 0) {\n <div class=\"run-tags-header\">\n @for (tag of run.tags.slice(0, 2); track tag) {\n <span class=\"tag-chip-header\">{{ tag }}</span>\n }\n @if (run.tags.length > 2) {\n <span class=\"tag-more-header\">+{{ run.tags.length - 2 }}</span>\n }\n </div>\n }\n <div class=\"run-date\">{{ getRelativeTime(run.date) }}</div>\n <div class=\"run-pass-rate\" [ngClass]=\"{'high': run.passRate >= 80, 'medium': run.passRate >= 50 && run.passRate < 80, 'low': run.passRate < 50}\">\n {{ run.passRate.toFixed(0) }}%\n </div>\n </div>\n </th>\n }\n <th class=\"spacer-header\"></th>\n </tr>\n </thead>\n <tbody>\n @for (test of getUniqueTestsFromMatrix(); track test) {\n <tr\n [class.row-selected]=\"selectedMatrixTestId === test.testId\"\n (click)=\"selectMatrixRow(test.testId)\">\n <td class=\"seq-cell\">{{ test.sequence }}</td>\n <td class=\"test-name-cell\">\n <span class=\"test-name\" [title]=\"test.testName\">{{ test.testName }}</span>\n </td>\n @for (run of matrixData; track run) {\n <td class=\"result-cell\"\n [ngClass]=\"getMatrixCellClass(getTestResultForRun(run.runId, test.testId))\"\n [class.clickable]=\"getTestResultForRun(run.runId, test.testId)\"\n [class.cell-not-run]=\"!getTestResultForRun(run.runId, test.testId)\"\n [title]=\"getTestResultForRun(run.runId, test.testId)?.status + ' - Click to view test run' || 'Not Run'\"\n (click)=\"onMatrixCellClick(getTestResultForRun(run.runId, test.testId), $event)\">\n @if (getTestResultForRun(run.runId, test.testId); as result) {\n <div class=\"cell-eval-stack\">\n <!-- Status indicator -->\n @if (evalPreferences.showExecution) {\n <span class=\"cell-status\"\n [ngClass]=\"'status-' + result.status.toLowerCase()\"\n [class.cell-skipped-status]=\"result.status === 'Skipped' || result.status === 'Pending'\"\n [title]=\"getStatusTooltip(result.status)\">\n <i class=\"fas\"\n [class.fa-check]=\"result.status === 'Passed'\"\n [class.fa-times]=\"result.status === 'Failed'\"\n [class.fa-exclamation]=\"result.status === 'Error'\"\n [class.fa-hourglass-end]=\"result.status === 'Timeout'\"\n [class.fa-forward]=\"result.status === 'Skipped'\"\n [class.fa-spinner]=\"result.status === 'Running'\"\n [class.fa-clock]=\"result.status === 'Pending'\"></i>\n </span>\n }\n <!-- Human score - slashed icon if no feedback, colored by rating if has feedback -->\n @if (evalPreferences.showHuman && !result.humanRating) {\n <span class=\"cell-human no-feedback\"\n title=\"Human Review: No rating submitted yet\">\n <i class=\"fas fa-user-slash\"></i>\n </span>\n }\n @if (evalPreferences.showHuman && result.humanRating) {\n <span class=\"cell-human has-feedback\"\n [class.rating-low]=\"result.humanRating <= 4\"\n [class.rating-medium]=\"result.humanRating >= 5 && result.humanRating <= 6\"\n [class.rating-good]=\"result.humanRating >= 7 && result.humanRating <= 8\"\n [class.rating-excellent]=\"result.humanRating >= 9\"\n [title]=\"getHumanTooltip(result.humanRating, result.humanComments)\">\n <i class=\"fas fa-user\"></i>\n <span class=\"rating-value\">{{ result.humanRating }}</span>\n </span>\n }\n <!-- Auto score - colored by percentage -->\n @if (evalPreferences.showAuto && result.score != null) {\n <span class=\"cell-auto has-score\"\n [class.score-low]=\"result.score < 0.5\"\n [class.score-medium]=\"result.score >= 0.5 && result.score < 0.7\"\n [class.score-good]=\"result.score >= 0.7 && result.score < 0.85\"\n [class.score-excellent]=\"result.score >= 0.85\"\n [title]=\"'Auto Score: ' + (result.score * 100).toFixed(0) + '% automated evaluation'\">\n <i class=\"fas fa-robot\"></i>\n <span class=\"score-value\">{{ (result.score * 100).toFixed(0) }}</span>\n </span>\n }\n @if (evalPreferences.showAuto && result.score == null) {\n <span class=\"cell-auto no-score\"\n title=\"Auto Score: No automated score available\">\n <i class=\"fas fa-robot\"></i>\n </span>\n }\n </div>\n }\n @if (!getTestResultForRun(run.runId, test.testId)) {\n <span class=\"cell-not-run-indicator\">\n <i class=\"fas fa-minus\"></i>\n </span>\n }\n </td>\n }\n <td class=\"spacer-cell\"></td>\n </tr>\n }\n </tbody>\n <!-- Footer row with totals -->\n <tfoot>\n <tr class=\"totals-row\">\n <td class=\"seq-cell totals-label\"></td>\n <td class=\"test-name-cell totals-label\">\n <strong>Totals</strong>\n </td>\n @for (run of matrixData; track run) {\n <td class=\"result-cell totals-cell\">\n <div class=\"cell-eval-stack totals-stack\">\n <!-- Status totals -->\n @if (evalPreferences.showExecution) {\n <span class=\"totals-status\">\n <span class=\"pass-count\">{{ getRunPassedCount(run) }}/{{ getRunTotalCount(run) }}</span>\n </span>\n }\n <!-- Human totals -->\n @if (evalPreferences.showHuman) {\n <span class=\"totals-human\">\n @if (getRunHumanAvg(run) != null) {\n <span class=\"avg-label\">{{ getRunHumanAvg(run)?.toFixed(1) }}</span>\n }\n <span class=\"count-label\">({{ getRunHumanCount(run) }})</span>\n </span>\n }\n <!-- Auto totals -->\n @if (evalPreferences.showAuto) {\n <span class=\"totals-auto\">\n @if (getRunAutoAvg(run) != null) {\n <span class=\"avg-label\">{{ (getRunAutoAvg(run)! * 100).toFixed(0) }}%</span>\n }\n <span class=\"count-label\">({{ getRunAutoCount(run) }})</span>\n </span>\n }\n </div>\n </td>\n }\n <td class=\"spacer-cell\"></td>\n </tr>\n </tfoot>\n </table>\n </div>\n </div>\n }\n <!-- Empty Matrix State -->\n @if (!loadingMatrix && matrixLoaded && matrixData.length === 0) {\n <mj-empty-state\n Variant=\"no-results\"\n Icon=\"fa-solid fa-table-cells\"\n Title=\"No Matrix Data\"\n Message=\"No suite runs match the current filters.\" />\n }\n }\n <!-- Chart View -->\n @if (analyticsView === 'chart') {\n <!-- Loading Chart -->\n @if (loadingMatrix) {\n <div class=\"loading-state\">\n <mj-loading text=\"Loading chart data...\"></mj-loading>\n </div>\n }\n <!-- Chart Content -->\n @if (!loadingMatrix && matrixLoaded && matrixData.length > 0) {\n <div class=\"chart-section\">\n <div class=\"chart-header\">\n <h3><i class=\"fas fa-project-diagram\"></i> Test Results Flow</h3>\n <div class=\"chart-legend\">\n <span class=\"legend-item chart-passed\"><i class=\"fas fa-check\"></i> Passed</span>\n <span class=\"legend-item chart-failed\"><i class=\"fas fa-times\"></i> Failed</span>\n <span class=\"legend-item chart-error\"><i class=\"fas fa-exclamation\"></i> Error</span>\n <span class=\"legend-item chart-skipped\"><i class=\"fas fa-forward\"></i> Skipped</span>\n </div>\n </div>\n <div class=\"chart-container\">\n <div #chartContainer class=\"d3-chart\"></div>\n </div>\n <div class=\"chart-info\">\n <i class=\"fas fa-info-circle\"></i>\n Interactive visualization showing test results across {{ matrixData.length }} runs.\n Hover over elements for details, click nodes to navigate.\n </div>\n </div>\n }\n <!-- Empty Chart State -->\n @if (!loadingMatrix && matrixLoaded && matrixData.length === 0) {\n <mj-empty-state\n Variant=\"no-results\"\n Icon=\"fa-solid fa-diagram-project\"\n Title=\"No Chart Data\"\n Message=\"No suite runs match the current filters.\" />\n }\n }\n }\n <!-- Empty State -->\n @if (!loadingAnalytics && analyticsLoaded && analyticsData.length === 0) {\n <mj-empty-state\n Icon=\"fa-solid fa-chart-line\"\n Title=\"No Analytics Data\"\n Message=\"Run this suite to start collecting analytics data.\"\n ActionText=\"Run Suite Now\"\n ActionIcon=\"fa-solid fa-play\"\n (Action)=\"runSuite()\" />\n }\n </div>\n }\n\n <!-- Compare Tab -->\n @if (activeTab === 'compare') {\n <div class=\"compare-tab\">\n <!-- Run Selection -->\n <div class=\"compare-selection\">\n <div class=\"compare-run-selector\">\n <h4>Run A (Baseline)</h4>\n @if (!loadingRuns && suiteRuns.length > 0) {\n <div class=\"run-selector-list\">\n @for (run of suiteRuns; track run) {\n <div class=\"run-selector-item\"\n [class.selected]=\"IsCompareRunA(run)\"\n (click)=\"selectCompareRunA(run)\">\n <div class=\"selector-status\" [style.background-color]=\"getRunStatusColor(run.Status)\"></div>\n <div class=\"selector-content\">\n <div class=\"selector-date\">{{ run.StartedAt | date:'short' }}</div>\n <div class=\"selector-rate\">{{ getPassRate(run).toFixed(0) }}% pass</div>\n </div>\n @if (getRunTags(run).length > 0) {\n <div class=\"selector-tags\">\n @for (tag of getRunTags(run).slice(0, 2); track tag) {\n <span class=\"tag-mini\">{{ tag }}</span>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n @if (compareRunA) {\n <div class=\"selected-run-preview\">\n <div class=\"preview-header\">\n <span class=\"preview-label\">Selected:</span>\n <button class=\"clear-btn\" (click)=\"compareRunA = null; compareResults = []\">Clear</button>\n </div>\n <div class=\"preview-details\">\n <span>{{ compareRunA.StartedAt | date:'medium' }}</span>\n <span class=\"preview-rate\">{{ getPassRate(compareRunA).toFixed(1) }}%</span>\n </div>\n </div>\n }\n </div>\n <div class=\"compare-vs\"><i class=\"fas fa-exchange-alt\"></i></div>\n <div class=\"compare-run-selector\">\n <h4>Run B (Compare)</h4>\n @if (!loadingRuns && suiteRuns.length > 0) {\n <div class=\"run-selector-list\">\n @for (run of suiteRuns; track run) {\n <div class=\"run-selector-item\"\n [class.selected]=\"IsCompareRunB(run)\"\n [class.disabled]=\"IsCompareRunA(run)\"\n (click)=\"!IsCompareRunA(run) && selectCompareRunB(run)\">\n <div class=\"selector-status\" [style.background-color]=\"getRunStatusColor(run.Status)\"></div>\n <div class=\"selector-content\">\n <div class=\"selector-date\">{{ run.StartedAt | date:'short' }}</div>\n <div class=\"selector-rate\">{{ getPassRate(run).toFixed(0) }}% pass</div>\n </div>\n @if (getRunTags(run).length > 0) {\n <div class=\"selector-tags\">\n @for (tag of getRunTags(run).slice(0, 2); track tag) {\n <span class=\"tag-mini\">{{ tag }}</span>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n @if (compareRunB) {\n <div class=\"selected-run-preview\">\n <div class=\"preview-header\">\n <span class=\"preview-label\">Selected:</span>\n <button class=\"clear-btn\" (click)=\"compareRunB = null; compareResults = []\">Clear</button>\n </div>\n <div class=\"preview-details\">\n <span>{{ compareRunB.StartedAt | date:'medium' }}</span>\n <span class=\"preview-rate\">{{ getPassRate(compareRunB).toFixed(1) }}%</span>\n </div>\n </div>\n }\n </div>\n </div>\n <!-- Comparison Results -->\n @if (compareRunA && compareRunB && !loadingCompare) {\n <div class=\"compare-results\">\n <!-- Summary Cards -->\n <div class=\"compare-summary\">\n <div class=\"compare-summary-card\">\n <div class=\"summary-label\">Pass Rate Change</div>\n <div class=\"summary-value\" [ngClass]=\"{'positive': getComparePassRateDiff()! > 0, 'negative': getComparePassRateDiff()! < 0}\">\n <i class=\"fas\" [ngClass]=\"{'fa-arrow-up': getComparePassRateDiff()! > 0, 'fa-arrow-down': getComparePassRateDiff()! < 0, 'fa-minus': getComparePassRateDiff() === 0}\"></i>\n {{ getComparePassRateDiff()! > 0 ? '+' : '' }}{{ getComparePassRateDiff()?.toFixed(1) }}%\n </div>\n </div>\n <div class=\"compare-summary-card\">\n <div class=\"summary-label\">Duration Change</div>\n <div class=\"summary-value\" [ngClass]=\"{'positive': getCompareDurationDiff()! < 0, 'negative': getCompareDurationDiff()! > 0}\">\n <i class=\"fas\" [ngClass]=\"{'fa-arrow-down': getCompareDurationDiff()! < 0, 'fa-arrow-up': getCompareDurationDiff()! > 0, 'fa-minus': getCompareDurationDiff() === 0}\"></i>\n {{ formatDuration(getAbsCompareDurationDiff()) }}\n </div>\n </div>\n <div class=\"compare-summary-card improved\">\n <div class=\"summary-label\">Improved</div>\n <div class=\"summary-value\">{{ getCompareImprovedCount() }}</div>\n </div>\n <div class=\"compare-summary-card regressed\">\n <div class=\"summary-label\">Regressed</div>\n <div class=\"summary-value\">{{ getCompareRegressedCount() }}</div>\n </div>\n </div>\n <!-- Detailed Comparison Table -->\n <div class=\"compare-table-section\">\n <h3><i class=\"fas fa-list\"></i> Test-by-Test Comparison</h3>\n <div class=\"compare-table-wrapper\">\n <table class=\"compare-table\">\n <thead>\n <tr>\n <th>Test</th>\n <th>Run A Status</th>\n <th>Run B Status</th>\n <th>Score Diff</th>\n <th>Duration Diff</th>\n <th>Change</th>\n </tr>\n </thead>\n <tbody>\n @for (result of compareResults; track result) {\n <tr [ngClass]=\"{'improved': result.runA && result.runB && result.runA.status !== 'Passed' && result.runB.status === 'Passed', 'regressed': result.runA && result.runB && result.runA.status === 'Passed' && result.runB.status !== 'Passed'}\">\n <td class=\"test-name-cell\">{{ result.testName }}</td>\n <td>\n @if (result.runA) {\n <span class=\"status-chip\" [ngClass]=\"'status-' + result.runA.status.toLowerCase()\">{{ result.runA.status }}</span>\n }\n @if (!result.runA) {\n <span class=\"status-chip status-missing\">N/A</span>\n }\n </td>\n <td>\n @if (result.runB) {\n <span class=\"status-chip\" [ngClass]=\"'status-' + result.runB.status.toLowerCase()\">{{ result.runB.status }}</span>\n }\n @if (!result.runB) {\n <span class=\"status-chip status-missing\">N/A</span>\n }\n </td>\n <td>\n @if (result.scoreDiff != null) {\n <span [ngClass]=\"{'positive': result.scoreDiff > 0, 'negative': result.scoreDiff < 0}\">\n {{ result.scoreDiff > 0 ? '+' : '' }}{{ (result.scoreDiff * 100).toFixed(1) }}%\n </span>\n }\n @if (result.scoreDiff == null) {\n <span class=\"muted\">-</span>\n }\n </td>\n <td>\n @if (result.durationDiff != null) {\n <span [ngClass]=\"{'positive': result.durationDiff < 0, 'negative': result.durationDiff > 0}\">\n {{ result.durationDiff > 0 ? '+' : '' }}{{ result.durationDiff.toFixed(1) }}s\n </span>\n }\n @if (result.durationDiff == null) {\n <span class=\"muted\">-</span>\n }\n </td>\n <td>\n @if (result.runA && result.runB && result.runA.status !== 'Passed' && result.runB.status === 'Passed') {\n <span class=\"change-indicator improved\">\n <i class=\"fas fa-arrow-up\"></i> Fixed\n </span>\n }\n @if (result.runA && result.runB && result.runA.status === 'Passed' && result.runB.status !== 'Passed') {\n <span class=\"change-indicator regressed\">\n <i class=\"fas fa-arrow-down\"></i> Broke\n </span>\n }\n @if (!result.statusChanged) {\n <span class=\"change-indicator unchanged\">\n <i class=\"fas fa-minus\"></i>\n </span>\n }\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n </div>\n </div>\n }\n <!-- Loading State for Compare -->\n @if (loadingCompare) {\n <div class=\"loading-state\">\n <mj-loading text=\"Loading comparison data...\"></mj-loading>\n </div>\n }\n <!-- Empty State -->\n @if (!compareRunA || !compareRunB) {\n <mj-empty-state\n Icon=\"fa-solid fa-scale-balanced\"\n Title=\"Select Two Runs to Compare\"\n Message=\"Choose a baseline run (A) and a comparison run (B) from the lists above to see a detailed side-by-side comparison.\" />\n }\n <!-- No Runs State -->\n @if (runsLoaded && suiteRuns.length < 2) {\n <mj-empty-state\n Icon=\"fa-solid fa-scale-balanced\"\n Title=\"Not Enough Runs to Compare\"\n Message=\"You need at least 2 suite runs to use the comparison feature.\"\n ActionText=\"Run Suite Now\"\n ActionIcon=\"fa-solid fa-play\"\n (Action)=\"runSuite()\" />\n }\n </div>\n }\n </div>\n\n <!-- Keyboard Shortcuts Toggle Button -->\n <button class=\"shortcuts-toggle\" (click)=\"toggleShortcuts()\" [title]=\"showShortcuts ? 'Hide keyboard shortcuts' : 'Show keyboard shortcuts'\">\n <i class=\"fas fa-keyboard\"></i>\n </button>\n\n <!-- Keyboard Shortcuts Hint (Desktop Only) -->\n @if (showShortcuts) {\n <div class=\"keyboard-shortcuts\">\n <div class=\"shortcuts-header\">\n <i class=\"fas fa-keyboard\"></i>\n Shortcuts\n <button class=\"shortcuts-close\" (click)=\"toggleShortcuts()\" title=\"Hide shortcuts\">\n <i class=\"fas fa-times\"></i>\n </button>\n </div>\n <div class=\"shortcut-list\">\n <div class=\"shortcut-item\">\n <span>Save changes</span>\n <span class=\"shortcut-keys\"><kbd>Cmd</kbd><kbd>S</kbd></span>\n </div>\n <div class=\"shortcut-item\">\n <span>Refresh</span>\n <span class=\"shortcut-keys\"><kbd>Cmd</kbd><kbd>R</kbd></span>\n </div>\n <div class=\"shortcut-item\">\n <span>Run Suite</span>\n <span class=\"shortcut-keys\"><kbd>Cmd</kbd><kbd>Enter</kbd></span>\n </div>\n <div class=\"shortcut-item\">\n <span>Switch Tabs</span>\n <span class=\"shortcut-keys\"><kbd>1</kbd>-<kbd>5</kbd></span>\n </div>\n </div>\n </div>\n }\n\n <!-- Slide Panel for Suite Execution -->\n @if (testingDialogService.IsPanelOpen) {\n <mj-slide-panel\n Mode=\"slide\"\n [Title]=\"testingDialogService.PanelOptions?.suiteId ? 'Suite Execution' : 'Run Suite'\"\n [Resizable]=\"true\"\n (Closed)=\"OnPanelClosed()\">\n <app-test-run-dialog\n [PanelMode]=\"true\"\n [selectedTestId]=\"testingDialogService.PanelOptions?.testId ?? null\"\n [selectedSuiteId]=\"testingDialogService.PanelOptions?.suiteId ?? null\"\n [runMode]=\"testingDialogService.PanelOptions?.mode ?? 'suite'\"\n (PanelClose)=\"OnPanelClosed()\">\n </app-test-run-dialog>\n </mj-slide-panel>\n }\n\n <!-- Add Tests Picker Dialog -->\n @if (showAddTestsDialog) {\n <div class=\"picker-backdrop\" (click)=\"closeAddTestsDialog()\"></div>\n <div class=\"picker-dialog\" role=\"dialog\" aria-modal=\"true\" aria-labelledby=\"add-tests-dialog-title\" (click)=\"$event.stopPropagation()\">\n <div class=\"picker-header\">\n <h2 id=\"add-tests-dialog-title\" class=\"picker-title\">\n <i class=\"fas fa-plus-circle\"></i> Add tests to suite\n </h2>\n <button type=\"button\" class=\"picker-close\" (click)=\"closeAddTestsDialog()\" [disabled]=\"isAddingTests\" aria-label=\"Close\">\n <i class=\"fas fa-times\"></i>\n </button>\n </div>\n\n <div class=\"picker-search\">\n <i class=\"fas fa-search picker-search-icon\"></i>\n <input\n #pickerSearch\n type=\"text\"\n class=\"picker-search-input\"\n placeholder=\"Search tests by name, description, or type...\"\n [(ngModel)]=\"addTestsSearch\"\n autofocus\n />\n @if (addTestsSearch) {\n <button type=\"button\" class=\"picker-search-clear\" (click)=\"addTestsSearch = ''\" aria-label=\"Clear search\">\n <i class=\"fas fa-times\"></i>\n </button>\n }\n </div>\n\n <div class=\"picker-toolbar\">\n <span class=\"picker-toolbar-status\">\n @if (selectedTestIdsToAdd.size > 0) {\n <strong>{{ selectedTestIdsToAdd.size }}</strong> selected\n } @else if (!loadingAvailableTests) {\n {{ filteredAvailableTests.length }} test{{ filteredAvailableTests.length === 1 ? '' : 's' }} available\n }\n </span>\n <div class=\"picker-toolbar-actions\">\n <button type=\"button\" class=\"picker-link-btn\" (click)=\"selectAllFiltered()\" [disabled]=\"loadingAvailableTests || filteredAvailableTests.length === 0\">\n Select all\n </button>\n <button type=\"button\" class=\"picker-link-btn\" (click)=\"clearAddSelection()\" [disabled]=\"selectedTestIdsToAdd.size === 0\">\n Clear\n </button>\n </div>\n </div>\n\n <div class=\"picker-body\">\n @if (loadingAvailableTests) {\n <div class=\"picker-loading\">\n <mj-loading text=\"Loading tests...\"></mj-loading>\n </div>\n } @else if (filteredAvailableTests.length === 0) {\n @if (availableTests.length === 0) {\n <mj-empty-state\n Variant=\"success\"\n Size=\"compact\"\n Title=\"Everything's already in the suite\"\n Message=\"This suite contains every available test. Create a new test first to add more.\" />\n } @else {\n <mj-empty-state\n Variant=\"no-results\"\n Size=\"compact\"\n Title=\"No matches\"\n [Message]=\"AddTestsNoMatchMessage\" />\n }\n } @else {\n <ul class=\"picker-list\">\n @for (t of filteredAvailableTests; track t.ID) {\n <li\n class=\"picker-row\"\n [class.picker-row--selected]=\"isAddSelected(t.ID)\"\n (click)=\"toggleAddSelection(t.ID)\"\n role=\"checkbox\"\n [attr.aria-checked]=\"isAddSelected(t.ID)\"\n tabindex=\"0\"\n >\n <span class=\"picker-check\">\n @if (isAddSelected(t.ID)) {\n <i class=\"fas fa-check\"></i>\n }\n </span>\n <div class=\"picker-row-main\">\n <div class=\"picker-row-name\">{{ t.Name }}</div>\n @if (t.Description) {\n <div class=\"picker-row-desc\">{{ t.Description }}</div>\n }\n </div>\n <div class=\"picker-row-meta\">\n @if (t.Type) {\n <span class=\"picker-row-pill\">{{ t.Type }}</span>\n }\n <span class=\"picker-row-pill picker-row-pill--status\" [attr.data-status]=\"t.Status?.toLowerCase()\">{{ t.Status }}</span>\n </div>\n </li>\n }\n </ul>\n }\n </div>\n\n <div class=\"picker-footer\">\n <button\n type=\"button\"\n class=\"picker-btn picker-btn--primary\"\n (click)=\"confirmAddTests()\"\n [disabled]=\"selectedTestIdsToAdd.size === 0 || isAddingTests\"\n >\n @if (isAddingTests) {\n <i class=\"fas fa-spinner fa-spin\"></i> Adding\u2026\n } @else {\n <i class=\"fas fa-check\"></i>\n @if (selectedTestIdsToAdd.size === 0) {\n Add tests\n } @else if (selectedTestIdsToAdd.size === 1) {\n Add 1 test\n } @else {\n Add {{ selectedTestIdsToAdd.size }} tests\n }\n }\n </button>\n <button\n type=\"button\"\n class=\"picker-btn picker-btn--ghost\"\n (click)=\"closeAddTestsDialog()\"\n [disabled]=\"isAddingTests\"\n >\n Cancel\n </button>\n </div>\n </div>\n }\n\n <!-- Sticky Save Bar \u2014 always in the DOM so CSS transitions can fire reliably.\n Visibility is controlled by the .save-bar--visible class, driven by isDirty. -->\n <div\n class=\"save-bar\"\n [class.save-bar--visible]=\"isDirty\"\n [attr.aria-hidden]=\"!isDirty\"\n role=\"region\"\n aria-label=\"Unsaved changes\"\n >\n <div class=\"save-bar-message\">\n <span class=\"save-bar-dot\" aria-hidden=\"true\">\u25CF</span>\n <span class=\"save-bar-text\">\n <strong>Unsaved changes</strong>\n <span class=\"save-bar-fields\">\n @if (dirtyFieldNames.length === 1) {\n {{ dirtyFieldNames[0] }} edited\n } @else if (dirtyFieldNames.length > 1) {\n {{ dirtyFieldNames.length }} fields edited\n }\n </span>\n </span>\n </div>\n <div class=\"save-bar-actions\">\n <button\n type=\"button\"\n class=\"save-bar-btn save-bar-btn--primary\"\n (click)=\"saveChanges()\"\n [disabled]=\"isSaving || !isDirty\"\n [attr.tabindex]=\"isDirty ? 0 : -1\"\n title=\"Save changes (\u2318S)\"\n >\n @if (isSaving) {\n <i class=\"fas fa-spinner fa-spin\"></i> Saving\u2026\n } @else {\n <i class=\"fas fa-check\"></i> Save changes\n <span class=\"save-bar-kbd\"><kbd>\u2318</kbd><kbd>S</kbd></span>\n }\n </button>\n <button\n type=\"button\"\n class=\"save-bar-btn save-bar-btn--ghost\"\n (click)=\"discardChanges()\"\n [disabled]=\"isSaving || !isDirty\"\n [attr.tabindex]=\"isDirty ? 0 : -1\"\n title=\"Discard changes\"\n >\n <i class=\"fas fa-undo\"></i> Discard\n </button>\n </div>\n </div>\n</div>\n", styles: ["/* ===========================\n Test Suite Form - World-Class UX\n =========================== */\n\n/* CSS Custom Properties for Theming - using :host for Angular encapsulation */\n:host {\n --test-primary: var(--mj-brand-primary);\n --test-primary-light: var(--mj-brand-primary);\n --test-success: var(--mj-status-success);\n --test-error: var(--mj-status-error);\n --test-warning: var(--mj-status-warning);\n --test-disabled: var(--mj-text-muted);\n --test-bg: var(--mj-bg-surface-card);\n --test-surface: var(--mj-bg-surface);\n --test-border: var(--mj-border-default);\n --test-text: var(--mj-text-primary);\n --test-text-secondary: var(--mj-text-secondary);\n --test-text-muted: var(--mj-text-disabled);\n --test-radius-sm: 6px;\n --test-radius-md: 10px;\n --test-radius-lg: 16px;\n --test-shadow-sm: var(--mj-shadow-sm);\n --test-shadow-md: var(--mj-shadow-md);\n --test-shadow-lg: var(--mj-shadow-lg);\n --test-transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n display: block;\n height: 100%;\n}\n\n.test-suite-form {\n position: relative;\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--test-bg);\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n}\n\n/* Breadcrumb */\n.breadcrumb {\n margin-bottom: 16px;\n}\n\n.breadcrumb ol {\n display: flex;\n align-items: center;\n gap: 4px;\n list-style: none;\n margin: 0;\n padding: 0;\n font-size: 13px;\n}\n\n.breadcrumb li {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.breadcrumb a {\n color: var(--test-primary);\n text-decoration: none;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 8px;\n border-radius: 6px;\n transition: background 0.15s;\n}\n\n.breadcrumb a:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n text-decoration: none;\n}\n\n.breadcrumb .separator {\n font-size: 10px;\n color: var(--test-text-muted);\n margin: 0 4px;\n}\n\n.breadcrumb .current {\n color: var(--test-text-secondary);\n font-weight: 500;\n}\n\n.breadcrumb-text {\n max-width: 200px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n/* Header */\n.suite-header {\n background: var(--test-surface);\n border-bottom: 1px solid var(--test-border);\n padding: 20px;\n}\n\n.header-content {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 16px;\n gap: 16px;\n}\n\n.header-left {\n display: flex;\n gap: 16px;\n flex: 1;\n min-width: 0;\n}\n\n.suite-icon {\n width: 56px;\n height: 56px;\n border-radius: var(--test-radius-md);\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-inverse);\n font-size: 24px;\n flex-shrink: 0;\n box-shadow: var(--test-shadow-md);\n transition: var(--test-transition);\n}\n\n.suite-icon:hover { transform: scale(1.05); }\n\n.suite-info { flex: 1; min-width: 0; }\n\n.suite-info h1 {\n margin: 0 0 8px 0;\n font-size: clamp(18px, 4vw, 24px);\n font-weight: 700;\n color: var(--test-text);\n word-wrap: break-word;\n}\n\n.suite-meta {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-wrap: wrap;\n}\n\n.status-badge {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n border-radius: 20px;\n color: var(--mj-text-inverse);\n font-size: 12px;\n font-weight: 600;\n text-transform: uppercase;\n}\n\n.status-badge.status-active { background: var(--test-success); }\n.status-badge.status-disabled { background: var(--test-disabled); }\n.status-badge.status-pending { background: var(--test-warning); }\n\n.status-badge-inline {\n display: inline-flex;\n padding: 2px 10px;\n border-radius: 10px;\n color: var(--mj-text-inverse);\n font-size: 11px;\n font-weight: 600;\n}\n\n.status-badge-inline.status-active { background: var(--test-success); }\n.status-badge-inline.status-disabled { background: var(--test-disabled); }\n.status-badge-inline.status-pending { background: var(--test-warning); }\n\n.test-count {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-size: 14px;\n color: var(--test-text-secondary);\n padding: 4px 10px;\n background: var(--test-bg);\n border-radius: var(--test-radius-sm);\n}\n\n.header-actions {\n display: flex;\n gap: 8px;\n flex-shrink: 0;\n}\n\n.suite-description {\n padding: 16px;\n background: var(--mj-bg-surface-card);\n border-radius: var(--test-radius-md);\n border: 1px solid var(--test-border);\n}\n\n.suite-description p {\n margin: 0;\n color: var(--test-text-secondary);\n line-height: 1.6;\n font-size: 14px;\n}\n\n/* Tabs */\n.tabs-container {\n background: var(--test-surface);\n border-bottom: 1px solid var(--test-border);\n position: sticky;\n top: 0;\n z-index: 10;\n}\n\n.tabs {\n display: flex;\n padding: 0 20px;\n overflow-x: auto;\n scrollbar-width: none;\n}\n\n.tabs::-webkit-scrollbar { display: none; }\n\n.tab {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 14px 18px;\n border: none;\n background: transparent;\n border-bottom: 3px solid transparent;\n color: var(--test-text-secondary);\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: var(--test-transition);\n white-space: nowrap;\n}\n\n.tab:hover {\n color: var(--test-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.tab.active {\n color: var(--test-primary);\n border-bottom-color: var(--test-primary);\n font-weight: 600;\n}\n\n.tab-badge {\n background: var(--test-border);\n color: var(--test-text-secondary);\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n}\n\n.tab.active .tab-badge {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n color: var(--test-primary);\n}\n\n.tab-shortcut {\n font-size: 10px;\n color: var(--test-text-muted);\n background: var(--test-bg);\n padding: 2px 6px;\n border-radius: 4px;\n font-weight: 600;\n}\n\n/* Tab Content */\n.tab-content {\n flex: 1;\n overflow-y: auto;\n padding: 20px;\n}\n\n/* Overview Tab */\n.overview-tab {\n display: flex;\n flex-direction: column;\n gap: 20px;\n animation: fadeIn 0.3s ease-out;\n}\n\n@keyframes fadeIn {\n from { opacity: 0; transform: translateY(10px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n.info-section, .config-section {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.info-section h3, .config-section h3 {\n margin: 0 0 20px 0;\n font-size: 18px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.info-section h3 i, .config-section h3 i {\n color: var(--test-primary);\n}\n\n.info-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: 16px;\n}\n\n.info-item {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.info-label {\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n}\n\n.info-value {\n font-size: 14px;\n color: var(--test-text);\n font-weight: 500;\n}\n\n.config-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));\n gap: 20px;\n}\n\n.config-item {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.config-item label {\n font-size: 12px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n}\n\n.config-input {\n padding: 10px 14px;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n font-size: 14px;\n transition: var(--test-transition);\n}\n\n.config-input:focus {\n outline: none;\n border-color: var(--test-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.config-hint {\n font-size: 11px;\n color: var(--test-text-muted);\n}\n\n/* Tests Tab */\n.tests-tab, .runs-tab {\n animation: fadeIn 0.3s ease-out;\n}\n\n.loading-state { padding: 0; }\n\n.skeleton-list {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.skeleton-card {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 16px;\n background: var(--test-surface);\n border-radius: var(--test-radius-md);\n border: 1px solid var(--test-border);\n}\n\n.skeleton-sequence {\n width: 32px;\n height: 32px;\n border-radius: 50%;\n background: linear-gradient(90deg, var(--mj-border-default) 25%, var(--mj-bg-surface-sunken) 50%, var(--mj-border-default) 75%);\n background-size: 200% 100%;\n animation: shimmer 1.5s infinite;\n}\n\n.skeleton-icon {\n width: 40px;\n height: 40px;\n border-radius: var(--test-radius-md);\n background: linear-gradient(90deg, var(--mj-border-default) 25%, var(--mj-bg-surface-sunken) 50%, var(--mj-border-default) 75%);\n background-size: 200% 100%;\n animation: shimmer 1.5s infinite;\n}\n\n.skeleton-content {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.skeleton-line {\n height: 14px;\n border-radius: 4px;\n background: linear-gradient(90deg, var(--mj-border-default) 25%, var(--mj-bg-surface-sunken) 50%, var(--mj-border-default) 75%);\n background-size: 200% 100%;\n animation: shimmer 1.5s infinite;\n}\n\n.skeleton-line.wide { width: 70%; }\n.skeleton-line.narrow { width: 40%; }\n\n@keyframes shimmer {\n 0% { background-position: 200% 0; }\n 100% { background-position: -200% 0; }\n}\n\n.tests-list, .runs-list {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.test-item, .run-item {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 16px;\n background: var(--test-surface);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.test-item:hover, .run-item:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n border-color: var(--test-primary-light);\n transform: translateX(4px);\n}\n\n.test-sequence {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--test-bg);\n border-radius: 50%;\n font-size: 14px;\n font-weight: 700;\n color: var(--test-text-secondary);\n flex-shrink: 0;\n}\n\n.test-icon, .run-icon {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: var(--test-radius-md);\n color: var(--mj-text-inverse);\n font-size: 18px;\n flex-shrink: 0;\n box-shadow: var(--test-shadow-sm);\n}\n\n.test-icon {\n background: var(--test-primary);\n}\n\n.test-content, .run-content { flex: 1; min-width: 0; }\n\n.test-name, .run-header {\n font-size: 14px;\n font-weight: 600;\n color: var(--test-text);\n margin-bottom: 4px;\n}\n\n.run-header {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.run-id { font-weight: 600; }\n\n.run-status {\n font-size: 12px;\n font-weight: 700;\n text-transform: uppercase;\n}\n\n.test-status, .run-meta {\n display: flex;\n gap: 12px;\n font-size: 12px;\n color: var(--test-text-secondary);\n}\n\n.test-status span, .run-meta span {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n}\n\n.test-item > i, .run-item > i {\n color: var(--test-text-muted);\n font-size: 14px;\n transition: var(--test-transition);\n}\n\n.test-item:hover > i, .run-item:hover > i {\n color: var(--test-primary);\n transform: translateX(2px);\n}\n\n/* Keyboard Shortcuts */\n/* Keyboard shortcuts toggle button - visible when shortcuts are hidden */\n.shortcuts-toggle {\n position: fixed;\n bottom: 20px;\n right: 20px;\n width: 36px;\n height: 36px;\n border-radius: 50%;\n background: var(--test-surface);\n border: 1px solid var(--test-border);\n box-shadow: var(--test-shadow-md);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--test-text-secondary);\n font-size: 14px;\n z-index: 99;\n transition: var(--test-transition);\n opacity: 0.7;\n}\n\n.shortcuts-toggle:hover {\n opacity: 1;\n transform: scale(1.1);\n color: var(--test-primary);\n border-color: var(--test-primary);\n}\n\n.keyboard-shortcuts {\n position: fixed;\n bottom: 20px;\n right: 20px;\n background: var(--test-surface);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n padding: 12px 16px;\n box-shadow: var(--test-shadow-lg);\n font-size: 12px;\n z-index: 100;\n max-width: 260px;\n}\n\n.shortcuts-header {\n display: flex;\n align-items: center;\n gap: 6px;\n margin-bottom: 10px;\n padding-bottom: 8px;\n border-bottom: 1px solid var(--test-border);\n font-weight: 600;\n color: var(--test-text);\n}\n\n.shortcuts-close {\n margin-left: auto;\n background: none;\n border: none;\n cursor: pointer;\n color: var(--test-text-muted);\n font-size: 12px;\n padding: 2px 4px;\n border-radius: 4px;\n transition: var(--test-transition);\n}\n\n.shortcuts-close:hover {\n color: var(--test-text);\n background: var(--test-border);\n}\n\n.shortcut-list {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.shortcut-item {\n display: flex;\n justify-content: space-between;\n align-items: center;\n color: var(--test-text-secondary);\n}\n\n.shortcut-keys {\n display: flex;\n gap: 4px;\n}\n\n.shortcut-keys kbd {\n background: var(--test-bg);\n border: 1px solid var(--test-border);\n border-radius: 4px;\n padding: 2px 6px;\n font-size: 11px;\n color: var(--test-text);\n}\n\n/* Responsive */\n@media (max-width: 1024px) {\n .keyboard-shortcuts, .shortcuts-toggle { display: none; }\n}\n\n@media (max-width: 768px) {\n .suite-header { padding: 16px; }\n\n .header-content {\n flex-direction: column;\n gap: 16px;\n }\n\n .header-actions {\n width: 100%;\n justify-content: stretch;\n }\n\n .header-actions button { flex: 1; }\n\n .tab-shortcut { display: none; }\n\n .info-grid { grid-template-columns: 1fr; }\n\n .test-item, .run-item { padding: 14px; }\n}\n\n@media (max-width: 480px) {\n .suite-icon {\n width: 40px;\n height: 40px;\n font-size: 18px;\n }\n\n .suite-info h1 { font-size: 16px; }\n\n .tab-badge { display: none; }\n\n .test-sequence { display: none; }\n}\n\n@media (hover: none) and (pointer: coarse) {\n .test-item:active, .run-item:active {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n transform: scale(0.98);\n }\n\n .tab { min-height: 48px; }\n .test-item, .run-item { min-height: 64px; }\n}\n\n@media (prefers-reduced-motion: reduce) {\n *, *::before, *::after {\n animation-duration: 0.01ms !important;\n transition-duration: 0.01ms !important;\n }\n}\n\n@media print {\n .header-actions, .tabs-container, .keyboard-shortcuts {\n display: none !important;\n }\n}\n\n/* ===========================\n Tags UI\n =========================== */\n.run-tags {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n margin-top: 8px;\n}\n\n.tag-chip {\n display: inline-flex;\n align-items: center;\n padding: 3px 10px;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n border-radius: 12px;\n font-size: 11px;\n font-weight: 500;\n color: var(--mj-brand-primary-hover);\n}\n\n.tag-mini {\n display: inline-flex;\n align-items: center;\n padding: 2px 6px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 4px;\n font-size: 10px;\n font-weight: 500;\n color: var(--mj-text-muted);\n}\n\n.tag-more {\n font-size: 10px;\n color: var(--mj-text-disabled);\n font-weight: 500;\n}\n\n/* Evaluation metrics row for Runs list */\n.run-eval-metrics {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-top: 8px;\n}\n\n.eval-metric {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 3px 8px;\n border-radius: 6px;\n font-size: 11px;\n font-weight: 500;\n}\n\n.eval-metric.status {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n}\n\n.eval-metric.status.status-completed {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.eval-metric.status.status-failed {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.eval-metric.status.status-running {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary-hover);\n}\n\n.eval-metric.status.status-pending {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.eval-metric.human {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n border: 1px solid var(--mj-status-warning);\n color: var(--mj-status-warning);\n}\n\n.eval-metric.human .eval-pending {\n font-size: 9px;\n color: var(--mj-status-warning);\n}\n\n.eval-metric.auto {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n color: var(--mj-brand-primary-hover);\n}\n\n.eval-metric.auto.high {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-success) 30%, transparent);\n color: var(--mj-status-success);\n}\n\n.eval-metric.auto.medium {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-warning) 30%, transparent);\n color: var(--mj-status-warning);\n}\n\n.eval-metric.auto.low {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-error) 30%, transparent);\n color: var(--mj-status-error);\n}\n\n.tag-cell {\n display: flex;\n align-items: center;\n gap: 4px;\n flex-wrap: wrap;\n}\n\n.tag-chip-table {\n display: inline-block;\n padding: 3px 8px;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n color: var(--mj-brand-primary-hover);\n border-radius: 10px;\n font-size: 10px;\n font-weight: 600;\n white-space: nowrap;\n max-width: 80px;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n/* ===========================\n Analytics Tab\n =========================== */\n.analytics-tab {\n animation: fadeIn 0.3s ease-out;\n}\n\n/* Collapsible filters */\n/* Filters disclosure migrated to <mj-accordion-panel>. The bespoke\n .analytics-filters wrapper card chrome, the .filters-header bar (+ hover),\n and the .filters-header > i chevron are now owned by the accordion and were\n removed. The title-slot layout (.filters-title flex row) and font are now\n provided by the accordion title + Size=\"sm\"; the collapsed summary uses the\n shared .mj-accordion-badge (--muted --right). Only the body content\n (.filters-content) styling is kept below. */\n\n.filters-content {\n display: flex;\n flex-direction: column;\n gap: 16px;\n padding: 12px 16px 16px 16px;\n border-top: 1px solid var(--test-border);\n}\n\n.filter-group {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.filter-group label {\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n}\n\n.filter-buttons {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n}\n\n.filter-btn {\n padding: 8px 16px;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n background: var(--test-surface);\n color: var(--test-text-secondary);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.filter-btn:hover {\n border-color: var(--test-primary);\n color: var(--test-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.filter-btn.active {\n background: var(--test-primary);\n border-color: var(--test-primary);\n color: var(--mj-text-inverse);\n}\n\n.filter-btn.tag-btn {\n padding: 6px 12px;\n font-size: 12px;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n}\n\n.filter-btn.tag-btn i.fa-check {\n font-size: 10px;\n}\n\n.filter-btn.tag-btn.all-tags-btn {\n font-weight: 600;\n}\n\n.filter-btn.tag-btn.all-tags-btn i {\n font-size: 11px;\n}\n\n.filter-hint {\n font-weight: 400;\n font-size: 10px;\n color: var(--test-primary);\n text-transform: none;\n letter-spacing: normal;\n}\n\n.tag-filters {\n max-height: 120px;\n overflow-y: auto;\n}\n\n/* KPI Cards */\n.analytics-kpis {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: 16px;\n margin-bottom: 24px;\n}\n\n.kpi-card {\n display: flex;\n align-items: center;\n gap: 16px;\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 20px;\n box-shadow: var(--test-shadow-sm);\n transition: var(--test-transition);\n}\n\n.kpi-card:hover {\n transform: translateY(-2px);\n box-shadow: var(--test-shadow-md);\n}\n\n.kpi-icon {\n width: 48px;\n height: 48px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n border-radius: var(--test-radius-md);\n color: var(--test-primary);\n font-size: 20px;\n}\n\n.kpi-icon.success {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--test-success);\n}\n\n.kpi-icon.info {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.kpi-icon.warning {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--test-warning);\n}\n\n.kpi-content {\n flex: 1;\n min-width: 0;\n}\n\n.kpi-value {\n font-size: 24px;\n font-weight: 700;\n color: var(--test-text);\n line-height: 1.2;\n}\n\n.kpi-label {\n font-size: 12px;\n color: var(--test-text-secondary);\n margin-top: 2px;\n}\n\n.kpi-trend {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n font-size: 12px;\n font-weight: 600;\n margin-top: 4px;\n padding: 2px 8px;\n border-radius: 10px;\n background: var(--mj-bg-surface-sunken);\n color: var(--test-text-secondary);\n}\n\n.kpi-trend.trend-up {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--test-success);\n}\n\n.kpi-trend.trend-down {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--test-error);\n}\n\n/* Analytics Table */\n.analytics-table-section {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.analytics-table-section h3 {\n margin: 0 0 16px 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.analytics-table-section h3 i {\n color: var(--test-primary);\n}\n\n.analytics-table-wrapper {\n overflow-x: auto;\n margin: 0 -24px;\n padding: 0 24px;\n}\n\n.analytics-table {\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n}\n\n.analytics-table th {\n text-align: left;\n padding: 12px 16px;\n background: var(--mj-bg-surface-card);\n border-bottom: 2px solid var(--test-border);\n font-weight: 600;\n color: var(--test-text-secondary);\n text-transform: uppercase;\n font-size: 11px;\n letter-spacing: 0.5px;\n white-space: nowrap;\n}\n\n.analytics-table td {\n padding: 14px 16px;\n border-bottom: 1px solid var(--test-border);\n color: var(--test-text);\n}\n\n.analytics-table tbody tr.clickable-row {\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.analytics-table tbody tr.clickable-row:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.status-chip {\n display: inline-flex;\n align-items: center;\n padding: 4px 10px;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n}\n\n.status-chip.status-completed { background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface)); color: var(--test-success); }\n.status-chip.status-passed { background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface)); color: var(--test-success); }\n.status-chip.status-failed { background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface)); color: var(--test-error); }\n.status-chip.status-error { background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface)); color: var(--test-warning); }\n.status-chip.status-running { background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface)); color: var(--test-primary); }\n.status-chip.status-pending { background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface)); color: var(--mj-brand-primary); }\n.status-chip.status-cancelled { background: var(--mj-bg-surface-sunken); color: var(--test-disabled); }\n.status-chip.status-missing { background: var(--mj-bg-surface-sunken); color: var(--test-text-muted); }\n.status-chip.status-timeout { background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface)); color: var(--test-warning); }\n.status-chip.status-skipped { background: var(--mj-bg-surface-sunken); color: var(--test-disabled); }\n\n.pass-rate-cell {\n display: flex;\n align-items: center;\n gap: 8px;\n min-width: 100px;\n}\n\n.pass-rate-bar {\n height: 6px;\n border-radius: 3px;\n background: var(--test-success);\n transition: width 0.3s ease;\n max-width: 60px;\n}\n\n.pass-rate-bar.medium { background: var(--test-warning); }\n.pass-rate-bar.low { background: var(--test-error); }\n\n/* Analytics Sub-navigation */\n.analytics-subnav {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 8px;\n margin-bottom: 20px;\n box-shadow: var(--test-shadow-sm);\n display: inline-flex;\n}\n\n.subnav-tabs {\n display: flex;\n gap: 4px;\n background: var(--test-bg);\n border-radius: var(--test-radius-md);\n padding: 4px;\n}\n\n.subnav-tab {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 20px;\n border: none;\n border-radius: var(--test-radius-sm);\n background: transparent;\n color: var(--test-text-secondary);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.subnav-tab:hover {\n color: var(--test-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.subnav-tab.active {\n background: var(--test-surface);\n color: var(--test-primary);\n box-shadow: var(--test-shadow-sm);\n}\n\n.subnav-tab i {\n font-size: 14px;\n}\n\n/* Matrix View */\n.matrix-section {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 16px;\n box-shadow: var(--test-shadow-sm);\n display: flex;\n flex-direction: column;\n max-height: calc(100vh - 280px);\n min-height: 300px;\n}\n\n.matrix-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n flex-wrap: wrap;\n gap: 12px;\n margin-bottom: 12px;\n padding-bottom: 12px;\n border-bottom: 1px solid var(--test-border);\n flex-shrink: 0;\n}\n\n.matrix-header-right {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.matrix-header h3 {\n display: flex;\n align-items: center;\n gap: 10px;\n margin: 0;\n font-size: 15px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.matrix-header h3 i {\n color: var(--test-primary);\n}\n\n.matrix-run-count {\n font-size: 12px;\n color: var(--test-text-muted);\n font-weight: 500;\n}\n\n/* Matrix filter input */\n.matrix-filter-input {\n display: flex;\n align-items: center;\n gap: 8px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--test-border);\n border-radius: 6px;\n padding: 4px 10px;\n min-width: 180px;\n}\n\n.matrix-filter-input i.fa-search {\n color: var(--mj-text-disabled);\n font-size: 12px;\n}\n\n.matrix-filter-input .filter-input {\n border: none;\n background: transparent;\n outline: none;\n font-size: 12px;\n color: var(--test-text);\n width: 100%;\n}\n\n.matrix-filter-input .filter-input::placeholder {\n color: var(--mj-text-disabled);\n}\n\n.clear-filter-btn {\n border: none;\n background: none;\n padding: 2px 4px;\n cursor: pointer;\n color: var(--mj-text-disabled);\n font-size: 10px;\n border-radius: 3px;\n transition: all 0.15s ease;\n}\n\n.clear-filter-btn:hover {\n background: var(--mj-border-default);\n color: var(--mj-text-muted);\n}\n\n/* Scrollable matrix container with fixed height */\n.matrix-scroll-container {\n flex: 1;\n overflow: auto;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n}\n\n.test-matrix {\n display: table;\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n}\n\n.test-matrix thead {\n display: table-header-group;\n}\n\n.test-matrix thead tr {\n display: table-row;\n}\n\n.test-matrix tbody {\n display: table-row-group;\n}\n\n.test-matrix tbody tr {\n display: table-row;\n cursor: pointer;\n transition: background-color 0.15s ease;\n}\n\n.test-matrix tbody tr:hover {\n background-color: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.test-matrix tbody tr.row-selected {\n background-color: color-mix(in srgb, var(--mj-brand-primary) 12%, transparent) !important;\n}\n\n.test-matrix tbody tr.row-selected td {\n border-top: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n border-bottom: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n}\n\n.test-matrix tbody tr.row-selected .seq-cell,\n.test-matrix tbody tr.row-selected .test-name-cell {\n background-color: color-mix(in srgb, var(--mj-brand-primary) 12%, transparent) !important;\n}\n\n.test-matrix tfoot {\n display: table-footer-group;\n}\n\n.test-matrix th,\n.test-matrix td {\n display: table-cell;\n border: 1px solid var(--test-border);\n padding: 8px 12px;\n text-align: center;\n vertical-align: middle;\n}\n\n.test-matrix th {\n background: var(--test-bg);\n font-weight: 600;\n font-size: 11px;\n color: var(--test-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n position: sticky;\n top: 0;\n z-index: 10;\n border-bottom: 3px solid var(--mj-text-secondary) !important;\n}\n\n/* Sequence column - shared styles */\n.test-matrix .seq-header,\n.test-matrix .seq-cell {\n width: 36px;\n min-width: 36px;\n max-width: 36px;\n text-align: center;\n position: sticky;\n left: 0;\n font-size: 11px;\n color: var(--mj-text-muted);\n border-right: 1px solid var(--test-border);\n padding: 6px 4px !important;\n}\n\n/* Seq header - sticky top AND left, highest z-index */\n.test-matrix .seq-header {\n cursor: pointer;\n font-weight: 600;\n background: var(--test-bg);\n z-index: 12; /* Higher than other headers */\n top: 0;\n}\n\n/* Seq body cells - sticky left only, lower z-index */\n.test-matrix .seq-cell {\n background: var(--test-surface);\n z-index: 2;\n}\n\n.test-matrix .seq-header i {\n font-size: 9px;\n margin-left: 2px;\n opacity: 0.6;\n}\n\n.test-matrix .seq-header:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.test-matrix .test-name-header {\n text-align: left;\n min-width: 150px;\n max-width: 500px;\n width: auto;\n position: sticky;\n left: 36px;\n background: var(--test-bg);\n z-index: 11;\n border-right: 2px solid var(--test-border);\n cursor: pointer;\n}\n\n.test-matrix .test-name-header i {\n font-size: 9px;\n margin-left: 4px;\n opacity: 0.6;\n}\n\n.test-matrix .test-name-header:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.test-matrix .run-header {\n min-width: 120px;\n width: 120px;\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n/* Spacer column absorbs extra width */\n.test-matrix .spacer-header,\n.test-matrix .spacer-cell {\n width: 100%;\n min-width: 20px;\n background: var(--test-bg);\n border: none;\n}\n\n.test-matrix .spacer-cell {\n background: var(--test-surface);\n}\n\n.test-matrix .run-header:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.run-header-content {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 4px;\n}\n\n.run-date {\n font-size: 12px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.run-pass-rate {\n font-size: 11px;\n font-weight: 700;\n padding: 2px 8px;\n border-radius: 10px;\n}\n\n.run-pass-rate.high {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--test-success);\n}\n\n.run-pass-rate.medium {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--test-warning);\n}\n\n.run-pass-rate.low {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--test-error);\n}\n\n.run-tags {\n display: flex;\n gap: 4px;\n}\n\n.tag-tiny {\n font-size: 9px;\n padding: 2px 6px;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--test-primary);\n border-radius: 8px;\n white-space: nowrap;\n max-width: 60px;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n/* Matrix column header tags - emphasized */\n.run-tags-header {\n display: flex;\n flex-wrap: wrap;\n gap: 3px;\n justify-content: center;\n margin-bottom: 4px;\n}\n\n.tag-chip-header {\n display: inline-block;\n padding: 3px 8px;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n color: var(--mj-brand-primary-hover);\n border-radius: 10px;\n font-size: 10px;\n font-weight: 600;\n white-space: nowrap;\n max-width: 70px;\n overflow: hidden;\n text-overflow: ellipsis;\n text-transform: none;\n letter-spacing: normal;\n}\n\n.tag-more-header {\n font-size: 9px;\n color: var(--test-text-secondary);\n padding: 2px 4px;\n}\n\n.test-matrix .test-name-cell {\n text-align: left;\n min-width: 150px;\n max-width: 500px;\n width: auto;\n position: sticky;\n left: 36px;\n background: var(--test-surface);\n z-index: 2;\n border-right: 2px solid var(--test-border);\n padding: 6px 10px !important;\n}\n\n.test-name {\n display: block;\n white-space: nowrap;\n font-weight: 500;\n color: var(--test-text);\n font-size: 12px;\n}\n\n.result-cell {\n position: relative;\n min-width: 120px;\n width: 120px;\n transition: var(--test-transition);\n}\n\n.result-cell.clickable {\n cursor: pointer;\n}\n\n.result-cell.clickable:hover {\n transform: scale(1.1);\n box-shadow: var(--mj-shadow-md);\n z-index: 5;\n}\n\n.result-cell i {\n font-size: 14px;\n}\n\n/* Completed cells have neutral white background - pills tell the story */\n.result-cell.cell-passed,\n.result-cell.cell-failed,\n.result-cell.cell-error,\n.result-cell.cell-timeout,\n.result-cell.cell-running,\n.result-cell.cell-pending {\n background: var(--mj-bg-surface);\n color: var(--test-text);\n}\n\n/* Skipped/not-run cells get hatched background */\n.result-cell.cell-skipped {\n background: repeating-linear-gradient(\n 45deg,\n var(--mj-bg-surface-card),\n var(--mj-bg-surface-card) 4px,\n var(--mj-border-default) 4px,\n var(--mj-border-default) 8px\n );\n color: var(--test-disabled);\n}\n\n.result-cell.cell-none {\n background: var(--mj-bg-surface-card);\n color: var(--test-text-muted);\n}\n\n.cell-score {\n display: block;\n font-size: 10px;\n font-weight: 600;\n margin-top: 2px;\n}\n\n/* Matrix cell evaluation stack - shows multiple eval types horizontally */\n.cell-eval-stack {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n flex-wrap: nowrap;\n}\n\n.result-cell.multi-eval {\n min-width: 120px;\n width: auto;\n}\n\n/* Add timeout status icon */\n.cell-status.status-timeout {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.cell-status {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n border-radius: 50%;\n font-size: 11px;\n}\n\n.cell-status.status-passed {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.cell-status.status-failed {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.cell-status.status-error {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.cell-status.status-skipped {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n}\n\n.cell-status.status-running {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary-hover);\n}\n\n.cell-status.status-pending {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.cell-human {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n border-radius: 50%;\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n font-size: 10px;\n}\n\n.cell-auto {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n padding: 2px 6px;\n border-radius: 4px;\n font-size: 10px;\n font-weight: 600;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary-hover);\n}\n\n.cell-auto.high {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.cell-auto.medium {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.cell-auto.low {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.cell-none-indicator {\n color: var(--test-text-muted);\n opacity: 0.5;\n}\n\n.matrix-info {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 12px;\n color: var(--test-text-muted);\n padding: 12px;\n background: var(--test-bg);\n border-radius: var(--test-radius-sm);\n}\n\n.matrix-info i {\n color: var(--test-primary);\n}\n\n/* ===========================\n Chart View\n =========================== */\n.chart-section {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.chart-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n flex-wrap: wrap;\n gap: 16px;\n margin-bottom: 20px;\n padding-bottom: 16px;\n border-bottom: 1px solid var(--test-border);\n}\n\n.chart-header h3 {\n display: flex;\n align-items: center;\n gap: 10px;\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.chart-header h3 i {\n color: var(--test-primary);\n}\n\n.chart-legend {\n display: flex;\n gap: 16px;\n flex-wrap: wrap;\n}\n\n.chart-legend .legend-item {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n font-weight: 500;\n padding: 4px 10px;\n border-radius: 12px;\n}\n\n.chart-legend .legend-item.chart-passed {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--test-success);\n}\n\n.chart-legend .legend-item.chart-failed {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--test-error);\n}\n\n.chart-legend .legend-item.chart-error {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--test-warning);\n}\n\n.chart-legend .legend-item.chart-skipped {\n background: var(--mj-bg-surface-sunken);\n color: var(--test-disabled);\n}\n\n.chart-container {\n min-height: 500px;\n position: relative;\n overflow: hidden;\n background: var(--mj-bg-surface-card);\n border-radius: var(--test-radius-md);\n border: 1px solid var(--test-border);\n}\n\n.d3-chart {\n width: 100%;\n height: 500px;\n}\n\n.d3-chart svg {\n width: 100%;\n height: 100%;\n}\n\n/* D3 Chart Node Styles */\n.d3-chart .node {\n cursor: pointer;\n transition: transform 0.2s ease;\n}\n\n.d3-chart .node:hover {\n transform: scale(1.05);\n}\n\n.d3-chart .node-label {\n font-size: 11px;\n font-weight: 500;\n fill: var(--test-text);\n pointer-events: none;\n}\n\n.d3-chart .link {\n fill: none;\n stroke-opacity: 0.4;\n transition: stroke-opacity 0.2s ease;\n}\n\n.d3-chart .link:hover {\n stroke-opacity: 0.8;\n}\n\n.d3-chart .tooltip {\n position: absolute;\n padding: 10px 14px;\n background: var(--mj-bg-overlay);\n color: var(--mj-text-inverse);\n border-radius: 8px;\n font-size: 12px;\n pointer-events: none;\n z-index: 100;\n box-shadow: var(--mj-shadow-lg);\n max-width: 250px;\n}\n\n.d3-chart .tooltip-title {\n font-weight: 600;\n margin-bottom: 4px;\n}\n\n.d3-chart .tooltip-value {\n opacity: 0.8;\n}\n\n.chart-info {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 12px;\n color: var(--test-text-muted);\n padding: 12px;\n background: var(--test-bg);\n border-radius: var(--test-radius-sm);\n margin-top: 16px;\n}\n\n.chart-info i {\n color: var(--test-primary);\n}\n\n/* ===========================\n Compare Tab\n =========================== */\n.compare-tab {\n animation: fadeIn 0.3s ease-out;\n}\n\n.compare-selection {\n display: grid;\n grid-template-columns: 1fr auto 1fr;\n gap: 24px;\n align-items: flex-start;\n margin-bottom: 24px;\n}\n\n.compare-run-selector {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 20px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.compare-run-selector h4 {\n margin: 0 0 16px 0;\n font-size: 14px;\n font-weight: 600;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.run-selector-list {\n max-height: 200px;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n gap: 8px;\n margin-bottom: 12px;\n}\n\n.run-selector-item {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 12px;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.run-selector-item:hover {\n border-color: var(--test-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.run-selector-item.selected {\n border-color: var(--test-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n}\n\n.run-selector-item.disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.selector-status {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n flex-shrink: 0;\n}\n\n.selector-content {\n flex: 1;\n min-width: 0;\n}\n\n.selector-date {\n font-size: 12px;\n font-weight: 500;\n color: var(--test-text);\n}\n\n.selector-rate {\n font-size: 11px;\n color: var(--test-text-secondary);\n}\n\n.selector-tags {\n display: flex;\n gap: 4px;\n flex-wrap: wrap;\n}\n\n.selected-run-preview {\n padding: 12px;\n background: var(--mj-bg-surface-card);\n border-radius: var(--test-radius-sm);\n border: 1px solid var(--test-border);\n}\n\n.preview-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 8px;\n}\n\n.preview-label {\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n color: var(--test-text-muted);\n}\n\n.clear-btn {\n padding: 4px 8px;\n border: none;\n background: transparent;\n color: var(--test-error);\n font-size: 11px;\n font-weight: 500;\n cursor: pointer;\n}\n\n.clear-btn:hover { text-decoration: underline; }\n\n.preview-details {\n display: flex;\n justify-content: space-between;\n font-size: 12px;\n color: var(--test-text);\n}\n\n.preview-rate {\n font-weight: 600;\n color: var(--test-success);\n}\n\n.compare-vs {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n background: var(--test-bg);\n border-radius: 50%;\n color: var(--test-text-muted);\n font-size: 16px;\n align-self: center;\n margin-top: 60px;\n}\n\n/* Compare Results */\n.compare-results {\n animation: fadeIn 0.3s ease-out;\n}\n\n.compare-summary {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));\n gap: 16px;\n margin-bottom: 24px;\n}\n\n.compare-summary-card {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 20px;\n box-shadow: var(--test-shadow-sm);\n text-align: center;\n}\n\n.compare-summary-card .summary-label {\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n color: var(--test-text-muted);\n margin-bottom: 8px;\n}\n\n.compare-summary-card .summary-value {\n font-size: 24px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n}\n\n.compare-summary-card .summary-value.positive { color: var(--test-success); }\n.compare-summary-card .summary-value.negative { color: var(--test-error); }\n\n.compare-summary-card.improved {\n border-left: 4px solid var(--test-success);\n}\n\n.compare-summary-card.improved .summary-value { color: var(--test-success); }\n\n.compare-summary-card.regressed {\n border-left: 4px solid var(--test-error);\n}\n\n.compare-summary-card.regressed .summary-value { color: var(--test-error); }\n\n/* Compare Table */\n.compare-table-section {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.compare-table-section h3 {\n margin: 0 0 16px 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.compare-table-section h3 i {\n color: var(--test-primary);\n}\n\n.compare-table-wrapper {\n overflow-x: auto;\n}\n\n.compare-table {\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n}\n\n.compare-table th {\n text-align: left;\n padding: 12px 16px;\n background: var(--mj-bg-surface-card);\n border-bottom: 2px solid var(--test-border);\n font-weight: 600;\n color: var(--test-text-secondary);\n text-transform: uppercase;\n font-size: 11px;\n letter-spacing: 0.5px;\n white-space: nowrap;\n}\n\n.compare-table td {\n padding: 14px 16px;\n border-bottom: 1px solid var(--test-border);\n color: var(--test-text);\n}\n\n.compare-table tbody tr.improved {\n background: color-mix(in srgb, var(--mj-status-success) 5%, transparent);\n}\n\n.compare-table tbody tr.regressed {\n background: color-mix(in srgb, var(--mj-status-error) 5%, transparent);\n}\n\n.test-name-cell {\n font-weight: 500;\n max-width: 200px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.positive { color: var(--test-success); }\n.negative { color: var(--test-error); }\n.muted { color: var(--test-text-muted); }\n\n.change-indicator {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 4px 8px;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n}\n\n.change-indicator.improved {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--test-success);\n}\n\n.change-indicator.regressed {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--test-error);\n}\n\n.change-indicator.unchanged {\n background: var(--mj-bg-surface-sunken);\n color: var(--test-text-muted);\n}\n\n/* ===========================\n Responsive Analytics/Compare\n =========================== */\n@media (max-width: 1024px) {\n .compare-selection {\n grid-template-columns: 1fr;\n gap: 16px;\n }\n\n .compare-vs {\n margin: 0;\n align-self: center;\n justify-self: center;\n }\n\n .analytics-kpis {\n grid-template-columns: repeat(2, 1fr);\n }\n}\n\n@media (max-width: 768px) {\n .filter-buttons {\n flex-direction: column;\n }\n\n .filter-btn {\n width: 100%;\n text-align: center;\n }\n\n .analytics-kpis {\n grid-template-columns: 1fr;\n }\n\n .kpi-card {\n padding: 16px;\n }\n\n .kpi-value {\n font-size: 20px;\n }\n\n .compare-summary {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .analytics-table-wrapper,\n .compare-table-wrapper {\n margin: 0 -20px;\n padding: 0 20px;\n }\n\n .run-selector-list {\n max-height: 150px;\n }\n}\n\n@media (max-width: 480px) {\n .compare-summary {\n grid-template-columns: 1fr;\n }\n\n .compare-summary-card .summary-value {\n font-size: 20px;\n }\n\n .analytics-table th,\n .analytics-table td,\n .compare-table th,\n .compare-table td {\n padding: 10px 12px;\n font-size: 12px;\n }\n}\n\n/* ===========================\n Matrix Evaluation Indicators\n =========================== */\n\n/* Human Feedback Indicators */\n.cell-human {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 3px;\n min-width: 22px;\n height: 22px;\n border-radius: 50%;\n font-size: 10px;\n}\n\n.cell-human.no-feedback {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-disabled);\n}\n\n.cell-human.no-feedback i {\n font-size: 11px;\n}\n\n.cell-human.has-feedback {\n padding: 0 6px;\n border-radius: 12px;\n min-width: 36px;\n}\n\n.cell-human.has-feedback i {\n font-size: 9px;\n}\n\n.cell-human.has-feedback .rating-value {\n font-weight: 700;\n font-size: 11px;\n}\n\n/* Human rating color coding: red \u22644, yellow 5-6, light-green 7-8, green 9-10 */\n.cell-human.rating-low {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.cell-human.rating-medium {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.cell-human.rating-good {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.cell-human.rating-excellent {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n/* Auto Score Indicators */\n.cell-auto {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 3px;\n min-width: 22px;\n height: 22px;\n border-radius: 50%;\n font-size: 10px;\n}\n\n.cell-auto.no-score {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-disabled);\n}\n\n.cell-auto.no-score i {\n font-size: 11px;\n}\n\n.cell-auto.has-score {\n padding: 0 6px;\n border-radius: 12px;\n min-width: 36px;\n}\n\n.cell-auto.has-score i {\n font-size: 9px;\n}\n\n.cell-auto.has-score .score-value {\n font-weight: 700;\n font-size: 10px;\n}\n\n/* Auto score color coding (0-100%): red <50, yellow 50-69, light-green 70-84, green 85+ */\n.cell-auto.score-low {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.cell-auto.score-medium {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.cell-auto.score-good {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.cell-auto.score-excellent {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n/* Status indicators in matrix cells */\n.cell-status {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n border-radius: 50%;\n font-size: 11px;\n}\n\n.cell-status.status-passed {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.cell-status.status-failed {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.cell-status.status-error {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.cell-status.status-timeout {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.cell-status.status-skipped,\n.cell-status.status-pending {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n}\n\n.cell-status.status-running {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n/* Not-run / Skipped cells with hatch pattern */\n.result-cell.cell-not-run {\n background: repeating-linear-gradient(\n 45deg,\n var(--mj-bg-surface-card),\n var(--mj-bg-surface-card) 4px,\n var(--mj-border-default) 4px,\n var(--mj-border-default) 8px\n );\n color: var(--mj-text-disabled);\n}\n\n.result-cell.cell-not-run .cell-eval-stack {\n opacity: 0.6;\n}\n\n.cell-not-run-indicator {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n color: var(--mj-text-disabled);\n font-size: 11px;\n}\n\n/* ===========================\n Matrix Totals Footer Row\n =========================== */\n.test-matrix tfoot {\n position: sticky;\n bottom: 0;\n z-index: 2;\n}\n\n.totals-row {\n background: var(--mj-bg-surface-sunken);\n border-top: 2px solid var(--test-border);\n}\n\n.totals-row td {\n padding: 10px 12px;\n font-weight: 600;\n}\n\n.totals-row .totals-label {\n background: var(--mj-bg-surface-sunken);\n font-size: 12px;\n color: var(--test-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.totals-row .totals-cell {\n background: var(--mj-bg-surface-sunken);\n}\n\n.totals-stack {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 4px;\n}\n\n.totals-status,\n.totals-human,\n.totals-auto {\n display: flex;\n align-items: center;\n gap: 4px;\n font-size: 11px;\n padding: 2px 8px;\n border-radius: 10px;\n white-space: nowrap;\n}\n\n.totals-status {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.totals-status .pass-count {\n font-weight: 700;\n}\n\n.totals-human {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.totals-human .avg-label {\n font-weight: 700;\n}\n\n.totals-human .count-label {\n font-size: 10px;\n opacity: 0.8;\n}\n\n.totals-auto {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary-hover);\n}\n\n.totals-auto .avg-label {\n font-weight: 700;\n}\n\n.totals-auto .count-label {\n font-size: 10px;\n opacity: 0.8;\n}\n\n/* ===========================\n Editable Overview Form\n =========================== */\n\n.edit-section {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.edit-section-header {\n margin: 0 0 18px 0;\n}\n\n.edit-section-header h3 {\n margin: 0 0 4px 0;\n font-size: 18px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.edit-section-header h3 i {\n color: var(--test-primary);\n}\n\n.edit-section-sub {\n margin: 0;\n font-size: 12px;\n color: var(--test-text-muted);\n}\n\n.edit-grid {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: 18px;\n}\n\n@media (max-width: 720px) {\n .edit-grid {\n grid-template-columns: 1fr;\n }\n}\n\n.edit-field {\n display: flex;\n flex-direction: column;\n gap: 6px;\n min-width: 0;\n}\n\n.edit-field--full {\n grid-column: 1 / -1;\n}\n\n.edit-field label {\n font-size: 12px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n}\n\n.edit-field .required {\n color: var(--mj-status-error);\n margin-left: 2px;\n}\n\n.config-textarea {\n resize: vertical;\n min-height: 72px;\n font-family: inherit;\n line-height: 1.5;\n}\n\n.select-wrapper {\n position: relative;\n}\n\n.select-wrapper select.config-input {\n padding-right: 36px;\n appearance: none;\n background-color: var(--test-surface);\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='%2364748b' d='M1.41 0L6 4.59 10.59 0 12 1.41l-6 6-6-6z'/%3E%3C/svg%3E\");\n background-repeat: no-repeat;\n background-position: right 14px center;\n background-size: 10px 7px;\n}\n\n/* Tag editor (chips + inline input) */\n.tag-editor {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n padding: 8px 10px;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n background: var(--test-surface);\n transition: var(--test-transition);\n cursor: text;\n min-height: 42px;\n align-items: center;\n}\n\n.tag-editor:focus-within {\n border-color: var(--test-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.tag-chip-editable {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 3px 4px 3px 10px;\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary-hover);\n border-radius: 999px;\n font-size: 12px;\n font-weight: 600;\n line-height: 1;\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 25%, transparent);\n}\n\n.tag-chip-editable .tag-remove {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 18px;\n height: 18px;\n border-radius: 50%;\n border: none;\n background: transparent;\n color: var(--mj-brand-primary);\n cursor: pointer;\n font-size: 10px;\n transition: background 0.15s;\n}\n\n.tag-chip-editable .tag-remove:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 25%, transparent);\n color: var(--mj-brand-primary-hover);\n}\n\n.tag-input-inline {\n flex: 1;\n min-width: 140px;\n border: none;\n background: transparent;\n outline: none;\n font-size: 13px;\n color: var(--test-text);\n padding: 4px 2px;\n}\n\n.tag-input-inline::placeholder {\n color: var(--test-text-muted);\n}\n\n/* Read-only metadata section */\n.meta-section {\n background: var(--mj-bg-surface-sunken);\n border-radius: var(--test-radius-md);\n padding: 14px 18px;\n border: 1px solid var(--test-border);\n}\n\n.meta-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));\n gap: 14px;\n}\n\n.meta-item {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n}\n\n.meta-label {\n font-size: 10px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n}\n\n.meta-value {\n font-size: 12px;\n color: var(--test-text-secondary);\n font-weight: 500;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.meta-mono {\n font-family: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, monospace;\n font-size: 11px;\n}\n\n/* Dirty indicator next to the title */\n.dirty-indicator {\n display: inline-block;\n margin-left: 8px;\n font-size: 14px;\n color: var(--mj-status-warning);\n line-height: 1;\n animation: pulseDot 1.8s ease-in-out infinite;\n vertical-align: middle;\n}\n\n@keyframes pulseDot {\n 0%, 100% { opacity: 1; transform: scale(1); }\n 50% { opacity: 0.5; transform: scale(0.85); }\n}\n\n.unsaved-pill {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning-text, var(--mj-status-warning));\n border: 1px solid color-mix(in srgb, var(--mj-status-warning) 30%, transparent);\n border-radius: 999px;\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.4px;\n}\n\n.unsaved-pill i {\n font-size: 6px;\n animation: pulseDot 1.8s ease-in-out infinite;\n}\n\n/* Pad the bottom of the tab content when the save bar is visible\n so the bar doesn't cover the last form field. */\n.tab-content.has-savebar {\n padding-bottom: 84px;\n}\n\n/* ===========================\n Sticky Save Bar\n =========================== */\n\n.save-bar {\n position: absolute;\n left: 16px;\n right: 96px; /* leaves room for the bottom-right chat launcher */\n bottom: 16px;\n z-index: 50;\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 16px;\n padding: 12px 16px 12px 20px;\n background: var(--mj-bg-surface-elevated, var(--test-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-warning) 25%, var(--test-border));\n border-radius: 14px;\n box-shadow: 0 12px 32px color-mix(in srgb, var(--mj-status-warning) 10%, rgba(0, 0, 0, 0.18));\n backdrop-filter: blur(8px);\n /* Hidden / off-screen state by default. The .save-bar--visible class\n animates it up into view. Using `transition` (not `animation`)\n guarantees the change runs every time isDirty toggles. */\n opacity: 0;\n transform: translateY(calc(100% + 32px));\n pointer-events: none;\n transition:\n transform 420ms cubic-bezier(0.16, 1, 0.3, 1),\n opacity 260ms cubic-bezier(0.16, 1, 0.3, 1);\n will-change: transform, opacity;\n}\n\n.save-bar--visible {\n opacity: 1;\n transform: translateY(0);\n pointer-events: auto;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .save-bar {\n transition: opacity 180ms ease-out;\n transform: none;\n }\n .save-bar--visible {\n transform: none;\n }\n}\n\n.save-bar-message {\n display: flex;\n align-items: center;\n gap: 12px;\n min-width: 0;\n}\n\n.save-bar-dot {\n color: var(--mj-status-warning);\n font-size: 12px;\n line-height: 1;\n animation: pulseDot 1.8s ease-in-out infinite;\n}\n\n.save-bar-text {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n}\n\n.save-bar-text strong {\n font-size: 14px;\n color: var(--test-text);\n font-weight: 700;\n}\n\n.save-bar-fields {\n font-size: 12px;\n color: var(--test-text-muted);\n}\n\n.save-bar-actions {\n display: flex;\n align-items: center;\n gap: 8px;\n flex-shrink: 0;\n}\n\n.save-bar-btn {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 9px 16px;\n font-size: 13px;\n font-weight: 600;\n border-radius: 8px;\n border: 1px solid transparent;\n cursor: pointer;\n transition: var(--test-transition);\n font-family: inherit;\n}\n\n.save-bar-btn:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.save-bar-btn--primary {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse, white);\n border-color: var(--mj-brand-primary);\n box-shadow: 0 2px 8px color-mix(in srgb, var(--mj-brand-primary) 35%, transparent);\n}\n\n.save-bar-btn--primary:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover, var(--mj-brand-primary));\n transform: translateY(-1px);\n box-shadow: 0 4px 12px color-mix(in srgb, var(--mj-brand-primary) 45%, transparent);\n}\n\n.save-bar-btn--primary:active:not(:disabled) {\n transform: translateY(0);\n}\n\n.save-bar-btn--ghost {\n background: transparent;\n color: var(--test-text-secondary);\n border-color: var(--test-border);\n}\n\n.save-bar-btn--ghost:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover, var(--mj-bg-surface-card));\n color: var(--test-text);\n border-color: var(--test-text-muted);\n}\n\n.save-bar-kbd {\n display: inline-flex;\n gap: 3px;\n margin-left: 6px;\n opacity: 0.85;\n}\n\n.save-bar-kbd kbd {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 18px;\n height: 18px;\n padding: 0 4px;\n font-size: 10px;\n font-weight: 600;\n font-family: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, monospace;\n background: color-mix(in srgb, white 18%, transparent);\n border: 1px solid color-mix(in srgb, white 35%, transparent);\n border-radius: 4px;\n color: inherit;\n}\n\n@media (max-width: 640px) {\n .save-bar {\n left: 8px;\n right: 8px;\n bottom: 88px; /* push above the chat launcher on small screens */\n flex-direction: column;\n align-items: stretch;\n padding: 12px;\n }\n .save-bar-actions {\n justify-content: space-between;\n }\n .save-bar-kbd {\n display: none;\n }\n}\n\n/* ===========================\n Tests Tab \u2014 Action Bar + Drag/Remove\n =========================== */\n\n.tests-actionbar {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n padding: 12px 16px;\n margin-bottom: 16px;\n background: var(--test-surface);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n}\n\n.tests-actionbar-text {\n display: flex;\n align-items: center;\n gap: 10px;\n flex-wrap: wrap;\n min-width: 0;\n}\n\n.tests-actionbar-text strong {\n font-size: 14px;\n color: var(--test-text);\n font-weight: 700;\n}\n\n.tests-actionbar-count {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 22px;\n height: 22px;\n padding: 0 8px;\n border-radius: 999px;\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary-hover);\n font-size: 12px;\n font-weight: 700;\n}\n\n.tests-actionbar-hint {\n font-size: 12px;\n color: var(--test-text-muted);\n}\n\n.tests-actionbar-actions {\n display: flex;\n gap: 8px;\n flex-shrink: 0;\n}\n\n/* Override the default test-item hover translate so drag transforms don't fight it. */\n.tests-list[cdk-drop-list] .test-item:hover,\n.tests-list .test-item.cdk-drag:hover {\n transform: none;\n}\n\n/* The whole row is draggable. .test-content keeps the click-to-open behavior. */\n.test-item.cdk-drag {\n position: relative;\n}\n\n.test-item .test-content {\n cursor: pointer;\n}\n\n/* Drag handle */\n.test-drag-handle {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 28px;\n border-radius: 4px;\n color: var(--test-text-muted);\n cursor: grab;\n flex-shrink: 0;\n transition: background 0.15s, color 0.15s;\n user-select: none;\n}\n\n.test-drag-handle:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n color: var(--test-primary);\n}\n\n.test-drag-handle:active,\n.cdk-drag-preview .test-drag-handle {\n cursor: grabbing;\n}\n\n/* Remove (X) button \u2014 hover-revealed */\n.test-remove-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border-radius: 50%;\n border: none;\n background: transparent;\n color: var(--test-text-muted);\n cursor: pointer;\n flex-shrink: 0;\n opacity: 0;\n transition: opacity 0.15s, background 0.15s, color 0.15s;\n}\n\n.test-item:hover .test-remove-btn,\n.test-remove-btn:focus-visible {\n opacity: 1;\n}\n\n.test-remove-btn:hover {\n background: color-mix(in srgb, var(--mj-status-error) 12%, transparent);\n color: var(--mj-status-error);\n}\n\n.test-chevron {\n cursor: pointer;\n}\n\n/* Inline remove-confirm */\n.test-remove-confirm {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 4px 8px 4px 12px;\n border-radius: 999px;\n background: color-mix(in srgb, var(--mj-status-error) 8%, var(--test-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-error) 30%, transparent);\n flex-shrink: 0;\n}\n\n.test-remove-confirm-text {\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-status-error-text, var(--mj-status-error));\n}\n\n.test-remove-confirm-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n padding: 4px 10px;\n border-radius: 6px;\n border: 1px solid transparent;\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n font-family: inherit;\n transition: var(--test-transition);\n}\n\n.test-remove-confirm-btn:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.test-remove-confirm-btn--danger {\n background: var(--mj-status-error);\n color: var(--mj-text-inverse, white);\n}\n\n.test-remove-confirm-btn--danger:hover:not(:disabled) {\n background: color-mix(in srgb, var(--mj-status-error) 88%, black);\n}\n\n.test-remove-confirm-btn--ghost {\n background: transparent;\n color: var(--test-text-secondary);\n border-color: var(--test-border);\n}\n\n.test-remove-confirm-btn--ghost:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover, var(--mj-bg-surface-card));\n color: var(--test-text);\n}\n\n/* CDK drag-drop visuals */\n.cdk-drag-preview {\n box-shadow: 0 12px 32px rgba(0, 0, 0, 0.25);\n border-radius: var(--test-radius-md);\n background: var(--test-surface);\n opacity: 0.95;\n}\n\n.cdk-drag-placeholder {\n opacity: 0;\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n border: 2px dashed var(--test-primary);\n border-radius: var(--test-radius-md);\n}\n\n.cdk-drag-placeholder * {\n visibility: hidden;\n}\n\n.cdk-drag-animating {\n transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);\n}\n\n.tests-list.cdk-drop-list-dragging .test-item:not(.cdk-drag-placeholder) {\n transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);\n}\n\n/* ===========================\n Add Tests Picker Dialog\n =========================== */\n\n.picker-backdrop {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.45);\n z-index: 200;\n animation: pickerFadeIn 180ms ease-out;\n backdrop-filter: blur(2px);\n}\n\n@keyframes pickerFadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n.picker-dialog {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: min(720px, calc(100vw - 32px));\n max-height: min(80vh, 720px);\n z-index: 201;\n display: flex;\n flex-direction: column;\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n box-shadow: 0 24px 64px rgba(0, 0, 0, 0.28);\n animation: pickerSlideUp 220ms cubic-bezier(0.16, 1, 0.3, 1);\n overflow: hidden;\n}\n\n@keyframes pickerSlideUp {\n from {\n opacity: 0;\n transform: translate(-50%, calc(-50% + 16px));\n }\n to {\n opacity: 1;\n transform: translate(-50%, -50%);\n }\n}\n\n.picker-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 18px 20px;\n border-bottom: 1px solid var(--test-border);\n}\n\n.picker-title {\n margin: 0;\n font-size: 16px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.picker-title i {\n color: var(--test-primary);\n}\n\n.picker-close {\n width: 32px;\n height: 32px;\n border-radius: 8px;\n border: none;\n background: transparent;\n color: var(--test-text-muted);\n cursor: pointer;\n font-size: 14px;\n transition: background 0.15s, color 0.15s;\n}\n\n.picker-close:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover, var(--mj-bg-surface-card));\n color: var(--test-text);\n}\n\n.picker-close:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.picker-search {\n position: relative;\n padding: 14px 20px 0 20px;\n}\n\n.picker-search-icon {\n position: absolute;\n top: 50%;\n left: 32px;\n transform: translateY(-30%);\n color: var(--test-text-muted);\n font-size: 13px;\n pointer-events: none;\n}\n\n.picker-search-input {\n width: 100%;\n padding: 10px 36px 10px 36px;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n background: var(--test-surface);\n font-size: 14px;\n color: var(--test-text);\n font-family: inherit;\n transition: var(--test-transition);\n}\n\n.picker-search-input:focus {\n outline: none;\n border-color: var(--test-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.picker-search-clear {\n position: absolute;\n top: 50%;\n right: 32px;\n transform: translateY(-30%);\n width: 22px;\n height: 22px;\n border-radius: 50%;\n border: none;\n background: transparent;\n color: var(--test-text-muted);\n cursor: pointer;\n font-size: 11px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n}\n\n.picker-search-clear:hover {\n background: var(--mj-bg-surface-hover, var(--mj-bg-surface-card));\n color: var(--test-text);\n}\n\n.picker-toolbar {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 10px 20px;\n border-bottom: 1px solid var(--test-border);\n}\n\n.picker-toolbar-status {\n font-size: 12px;\n color: var(--test-text-secondary);\n}\n\n.picker-toolbar-status strong {\n color: var(--mj-brand-primary-hover);\n font-weight: 700;\n}\n\n.picker-toolbar-actions {\n display: flex;\n gap: 14px;\n}\n\n.picker-link-btn {\n border: none;\n background: transparent;\n color: var(--test-primary);\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n padding: 0;\n font-family: inherit;\n}\n\n.picker-link-btn:hover:not(:disabled) {\n text-decoration: underline;\n}\n\n.picker-link-btn:disabled {\n color: var(--test-text-muted);\n cursor: not-allowed;\n}\n\n.picker-body {\n flex: 1;\n overflow-y: auto;\n padding: 8px 12px;\n min-height: 200px;\n}\n\n.picker-loading {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 40px;\n}\n\n.picker-list {\n list-style: none;\n padding: 0;\n margin: 0;\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.picker-row {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 12px;\n border-radius: 8px;\n cursor: pointer;\n transition: background 0.12s, border-color 0.12s;\n border: 1px solid transparent;\n}\n\n.picker-row:hover {\n background: var(--mj-bg-surface-hover, var(--mj-bg-surface-card));\n}\n\n.picker-row:focus-visible {\n outline: none;\n border-color: var(--test-primary);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.picker-row--selected {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--test-surface));\n border-color: color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n}\n\n.picker-row--selected:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--test-surface));\n}\n\n.picker-check {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 20px;\n height: 20px;\n border-radius: 5px;\n border: 1.5px solid var(--test-border);\n background: var(--test-surface);\n color: var(--mj-text-inverse, white);\n font-size: 11px;\n flex-shrink: 0;\n transition: background 0.12s, border-color 0.12s;\n}\n\n.picker-row--selected .picker-check {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n}\n\n.picker-row-main {\n flex: 1;\n min-width: 0;\n}\n\n.picker-row-name {\n font-size: 13px;\n font-weight: 600;\n color: var(--test-text);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.picker-row-desc {\n font-size: 12px;\n color: var(--test-text-muted);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n margin-top: 2px;\n}\n\n.picker-row-meta {\n display: flex;\n align-items: center;\n gap: 6px;\n flex-shrink: 0;\n}\n\n.picker-row-pill {\n display: inline-flex;\n align-items: center;\n padding: 2px 8px;\n border-radius: 999px;\n font-size: 10px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.3px;\n background: var(--mj-bg-surface-sunken, var(--test-bg));\n color: var(--test-text-secondary);\n border: 1px solid var(--test-border);\n}\n\n.picker-row-pill--status[data-status=\"active\"] {\n background: color-mix(in srgb, var(--mj-status-success) 12%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n border-color: color-mix(in srgb, var(--mj-status-success) 30%, transparent);\n}\n\n.picker-row-pill--status[data-status=\"disabled\"] {\n background: var(--mj-bg-surface-sunken, var(--test-bg));\n color: var(--test-text-muted);\n}\n\n.picker-row-pill--status[data-status=\"pending\"] {\n background: color-mix(in srgb, var(--mj-status-warning) 12%, var(--mj-bg-surface));\n color: var(--mj-status-warning-text, var(--mj-status-warning));\n border-color: color-mix(in srgb, var(--mj-status-warning) 30%, transparent);\n}\n\n.picker-footer {\n display: flex;\n gap: 8px;\n padding: 14px 20px;\n border-top: 1px solid var(--test-border);\n background: var(--mj-bg-surface-sunken, var(--test-bg));\n}\n\n.picker-btn {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 9px 16px;\n font-size: 13px;\n font-weight: 600;\n border-radius: 8px;\n border: 1px solid transparent;\n cursor: pointer;\n font-family: inherit;\n transition: var(--test-transition);\n}\n\n.picker-btn:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.picker-btn--primary {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse, white);\n border-color: var(--mj-brand-primary);\n}\n\n.picker-btn--primary:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover, var(--mj-brand-primary));\n}\n\n.picker-btn--ghost {\n background: transparent;\n color: var(--test-text-secondary);\n border-color: var(--test-border);\n}\n\n.picker-btn--ghost:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover, var(--mj-bg-surface-card));\n color: var(--test-text);\n}\n\n@media (max-width: 640px) {\n .picker-dialog {\n width: calc(100vw - 16px);\n max-height: calc(100vh - 32px);\n }\n .tests-actionbar {\n flex-direction: column;\n align-items: stretch;\n }\n .tests-actionbar-actions {\n justify-content: flex-end;\n }\n .test-remove-btn {\n opacity: 1; /* always visible on touch */\n }\n}\n\n"] }]
4990
5030
  }], null, { ChartContainer: [{
4991
5031
  type: ViewChild,
4992
5032
  args: ['chartContainer']
@@ -4997,5 +5037,5 @@ export { MJTestSuiteFormComponentExtended };
4997
5037
  type: HostListener,
4998
5038
  args: ['window:beforeunload', ['$event']]
4999
5039
  }] }); })();
5000
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MJTestSuiteFormComponentExtended, { className: "MJTestSuiteFormComponentExtended", filePath: "src/lib/custom/Tests/test-suite-form.component.ts", lineNumber: 33 }); })();
5040
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MJTestSuiteFormComponentExtended, { className: "MJTestSuiteFormComponentExtended", filePath: "src/lib/custom/Tests/test-suite-form.component.ts", lineNumber: 34 }); })();
5001
5041
  //# sourceMappingURL=test-suite-form.component.js.map