@memberjunction/ng-dashboards 2.117.0 → 2.119.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/dist/Testing/components/testing-analytics.component.d.ts +56 -0
  2. package/dist/Testing/components/testing-analytics.component.d.ts.map +1 -0
  3. package/dist/Testing/components/testing-analytics.component.js +746 -0
  4. package/dist/Testing/components/testing-analytics.component.js.map +1 -0
  5. package/dist/Testing/components/testing-execution.component.d.ts +59 -0
  6. package/dist/Testing/components/testing-execution.component.d.ts.map +1 -0
  7. package/dist/Testing/components/testing-execution.component.js +647 -0
  8. package/dist/Testing/components/testing-execution.component.js.map +1 -0
  9. package/dist/Testing/components/testing-feedback.component.d.ts +55 -0
  10. package/dist/Testing/components/testing-feedback.component.d.ts.map +1 -0
  11. package/dist/Testing/components/testing-feedback.component.js +788 -0
  12. package/dist/Testing/components/testing-feedback.component.js.map +1 -0
  13. package/dist/Testing/components/testing-overview.component.d.ts +30 -0
  14. package/dist/Testing/components/testing-overview.component.d.ts.map +1 -0
  15. package/dist/Testing/components/testing-overview.component.js +341 -0
  16. package/dist/Testing/components/testing-overview.component.js.map +1 -0
  17. package/dist/Testing/components/testing-version-comparison.component.d.ts +58 -0
  18. package/dist/Testing/components/testing-version-comparison.component.d.ts.map +1 -0
  19. package/dist/Testing/components/testing-version-comparison.component.js +801 -0
  20. package/dist/Testing/components/testing-version-comparison.component.js.map +1 -0
  21. package/dist/Testing/components/widgets/oracle-breakdown-table.component.d.ts +20 -0
  22. package/dist/Testing/components/widgets/oracle-breakdown-table.component.d.ts.map +1 -0
  23. package/dist/Testing/components/widgets/oracle-breakdown-table.component.js +278 -0
  24. package/dist/Testing/components/widgets/oracle-breakdown-table.component.js.map +1 -0
  25. package/dist/Testing/components/widgets/suite-tree.component.d.ts +28 -0
  26. package/dist/Testing/components/widgets/suite-tree.component.d.ts.map +1 -0
  27. package/dist/Testing/components/widgets/suite-tree.component.js +275 -0
  28. package/dist/Testing/components/widgets/suite-tree.component.js.map +1 -0
  29. package/dist/Testing/components/widgets/test-run-detail-panel.component.d.ts +34 -0
  30. package/dist/Testing/components/widgets/test-run-detail-panel.component.d.ts.map +1 -0
  31. package/dist/Testing/components/widgets/test-run-detail-panel.component.js +371 -0
  32. package/dist/Testing/components/widgets/test-run-detail-panel.component.js.map +1 -0
  33. package/dist/Testing/services/testing-instrumentation.service.d.ts +152 -0
  34. package/dist/Testing/services/testing-instrumentation.service.d.ts.map +1 -0
  35. package/dist/Testing/services/testing-instrumentation.service.js +579 -0
  36. package/dist/Testing/services/testing-instrumentation.service.js.map +1 -0
  37. package/dist/Testing/testing-dashboard.component.d.ts +52 -0
  38. package/dist/Testing/testing-dashboard.component.d.ts.map +1 -0
  39. package/dist/Testing/testing-dashboard.component.js +271 -0
  40. package/dist/Testing/testing-dashboard.component.js.map +1 -0
  41. package/dist/module.d.ts +30 -20
  42. package/dist/module.d.ts.map +1 -1
  43. package/dist/module.js +50 -9
  44. package/dist/module.js.map +1 -1
  45. package/dist/public-api.d.ts +1 -0
  46. package/dist/public-api.d.ts.map +1 -1
  47. package/dist/public-api.js +3 -0
  48. package/dist/public-api.js.map +1 -1
  49. package/package.json +13 -10
@@ -0,0 +1,801 @@
1
+ import { Component, Input, Output, EventEmitter, ChangeDetectionStrategy } from '@angular/core';
2
+ import { Subject, combineLatest, of } from 'rxjs';
3
+ import { takeUntil, map, shareReplay, switchMap } from 'rxjs/operators';
4
+ import * as i0 from "@angular/core";
5
+ import * as i1 from "../services/testing-instrumentation.service";
6
+ import * as i2 from "@angular/forms";
7
+ import * as i3 from "@angular/common";
8
+ const _forTrack0 = ($index, $item) => $item.version;
9
+ const _forTrack1 = ($index, $item) => $item.testName;
10
+ const _c0 = () => [];
11
+ function TestingVersionComparisonComponent_For_18_Template(rf, ctx) { if (rf & 1) {
12
+ i0.ɵɵelementStart(0, "option", 11);
13
+ i0.ɵɵtext(1);
14
+ i0.ɵɵelementEnd();
15
+ } if (rf & 2) {
16
+ const version_r1 = ctx.$implicit;
17
+ i0.ɵɵproperty("value", version_r1.version);
18
+ i0.ɵɵadvance();
19
+ i0.ɵɵtextInterpolate2("", version_r1.version, " (", version_r1.totalTests, " tests)");
20
+ } }
21
+ function TestingVersionComparisonComponent_For_29_Template(rf, ctx) { if (rf & 1) {
22
+ i0.ɵɵelementStart(0, "option", 11);
23
+ i0.ɵɵtext(1);
24
+ i0.ɵɵelementEnd();
25
+ } if (rf & 2) {
26
+ const version_r2 = ctx.$implicit;
27
+ i0.ɵɵproperty("value", version_r2.version);
28
+ i0.ɵɵadvance();
29
+ i0.ɵɵtextInterpolate2("", version_r2.version, " (", version_r2.totalTests, " tests)");
30
+ } }
31
+ function TestingVersionComparisonComponent_Conditional_31_For_69_Conditional_26_Template(rf, ctx) { if (rf & 1) {
32
+ i0.ɵɵelementStart(0, "span", 58);
33
+ i0.ɵɵelement(1, "i", 61);
34
+ i0.ɵɵtext(2, " Regression ");
35
+ i0.ɵɵelementEnd();
36
+ } }
37
+ function TestingVersionComparisonComponent_Conditional_31_For_69_Conditional_27_Template(rf, ctx) { if (rf & 1) {
38
+ i0.ɵɵelementStart(0, "span", 59);
39
+ i0.ɵɵelement(1, "i", 62);
40
+ i0.ɵɵtext(2, " Improved ");
41
+ i0.ɵɵelementEnd();
42
+ } }
43
+ function TestingVersionComparisonComponent_Conditional_31_For_69_Conditional_28_Template(rf, ctx) { if (rf & 1) {
44
+ i0.ɵɵelementStart(0, "span", 60);
45
+ i0.ɵɵelement(1, "i", 63);
46
+ i0.ɵɵtext(2, " Unchanged ");
47
+ i0.ɵɵelementEnd();
48
+ } }
49
+ function TestingVersionComparisonComponent_Conditional_31_For_69_Template(rf, ctx) { if (rf & 1) {
50
+ i0.ɵɵelementStart(0, "div", 49)(1, "div", 50)(2, "span", 51);
51
+ i0.ɵɵtext(3);
52
+ i0.ɵɵelementEnd()();
53
+ i0.ɵɵelementStart(4, "div", 52)(5, "div", 53)(6, "span", 48);
54
+ i0.ɵɵtext(7);
55
+ i0.ɵɵelementEnd();
56
+ i0.ɵɵelementStart(8, "span", 54);
57
+ i0.ɵɵtext(9);
58
+ i0.ɵɵelementEnd()()();
59
+ i0.ɵɵelementStart(10, "div", 52)(11, "div", 53)(12, "span", 48);
60
+ i0.ɵɵtext(13);
61
+ i0.ɵɵelementEnd();
62
+ i0.ɵɵelementStart(14, "span", 54);
63
+ i0.ɵɵtext(15);
64
+ i0.ɵɵelementEnd()()();
65
+ i0.ɵɵelementStart(16, "div", 55)(17, "span", 56);
66
+ i0.ɵɵtext(18);
67
+ i0.ɵɵelementEnd()();
68
+ i0.ɵɵelementStart(19, "div", 55)(20, "span", 56);
69
+ i0.ɵɵtext(21);
70
+ i0.ɵɵelementEnd()();
71
+ i0.ɵɵelementStart(22, "div", 55)(23, "span", 56);
72
+ i0.ɵɵtext(24);
73
+ i0.ɵɵelementEnd()();
74
+ i0.ɵɵelementStart(25, "div", 57);
75
+ i0.ɵɵtemplate(26, TestingVersionComparisonComponent_Conditional_31_For_69_Conditional_26_Template, 3, 0, "span", 58)(27, TestingVersionComparisonComponent_Conditional_31_For_69_Conditional_27_Template, 3, 0, "span", 59)(28, TestingVersionComparisonComponent_Conditional_31_For_69_Conditional_28_Template, 3, 0, "span", 60);
76
+ i0.ɵɵelementEnd()();
77
+ } if (rf & 2) {
78
+ const comparison_r5 = ctx.$implicit;
79
+ i0.ɵɵclassProp("regression", comparison_r5.regression)("improvement", comparison_r5.improvement);
80
+ i0.ɵɵadvance(3);
81
+ i0.ɵɵtextInterpolate(comparison_r5.testName);
82
+ i0.ɵɵadvance(4);
83
+ i0.ɵɵtextInterpolate(comparison_r5.versionA.avgScore.toFixed(4));
84
+ i0.ɵɵadvance(2);
85
+ i0.ɵɵtextInterpolate2("", comparison_r5.versionA.passRate.toFixed(0), "% pass \u2022 ", comparison_r5.versionA.runCount, " runs");
86
+ i0.ɵɵadvance(4);
87
+ i0.ɵɵtextInterpolate(comparison_r5.versionB.avgScore.toFixed(4));
88
+ i0.ɵɵadvance(2);
89
+ i0.ɵɵtextInterpolate2("", comparison_r5.versionB.passRate.toFixed(0), "% pass \u2022 ", comparison_r5.versionB.runCount, " runs");
90
+ i0.ɵɵadvance(2);
91
+ i0.ɵɵclassProp("positive", comparison_r5.scoreDelta > 0)("negative", comparison_r5.scoreDelta < 0);
92
+ i0.ɵɵadvance();
93
+ i0.ɵɵtextInterpolate2(" ", comparison_r5.scoreDelta > 0 ? "+" : "", "", (comparison_r5.scoreDelta * 100).toFixed(1), "% ");
94
+ i0.ɵɵadvance(2);
95
+ i0.ɵɵclassProp("positive", comparison_r5.costDelta < 0)("negative", comparison_r5.costDelta > 0);
96
+ i0.ɵɵadvance();
97
+ i0.ɵɵtextInterpolate2(" ", comparison_r5.costDelta > 0 ? "+" : "", "", (comparison_r5.costDelta * 100).toFixed(1), "% ");
98
+ i0.ɵɵadvance(2);
99
+ i0.ɵɵclassProp("positive", comparison_r5.durationDelta < 0)("negative", comparison_r5.durationDelta > 0);
100
+ i0.ɵɵadvance();
101
+ i0.ɵɵtextInterpolate2(" ", comparison_r5.durationDelta > 0 ? "+" : "", "", (comparison_r5.durationDelta * 100).toFixed(1), "% ");
102
+ i0.ɵɵadvance(2);
103
+ i0.ɵɵconditional(comparison_r5.regression ? 26 : comparison_r5.improvement ? 27 : 28);
104
+ } }
105
+ function TestingVersionComparisonComponent_Conditional_31_ForEmpty_70_Template(rf, ctx) { if (rf & 1) {
106
+ i0.ɵɵelementStart(0, "div", 42);
107
+ i0.ɵɵelement(1, "i", 64);
108
+ i0.ɵɵelementStart(2, "p");
109
+ i0.ɵɵtext(3, "No test data available for comparison");
110
+ i0.ɵɵelementEnd()();
111
+ } }
112
+ function TestingVersionComparisonComponent_Conditional_31_Template(rf, ctx) { if (rf & 1) {
113
+ const _r3 = i0.ɵɵgetCurrentView();
114
+ i0.ɵɵelementStart(0, "div", 15)(1, "div", 16)(2, "div", 17);
115
+ i0.ɵɵelement(3, "i", 18);
116
+ i0.ɵɵelementEnd();
117
+ i0.ɵɵelementStart(4, "div", 19)(5, "div", 20);
118
+ i0.ɵɵtext(6);
119
+ i0.ɵɵpipe(7, "async");
120
+ i0.ɵɵelementEnd();
121
+ i0.ɵɵelementStart(8, "div", 21);
122
+ i0.ɵɵtext(9, "Regressions Detected");
123
+ i0.ɵɵelementEnd()()();
124
+ i0.ɵɵelementStart(10, "div", 16)(11, "div", 22);
125
+ i0.ɵɵelement(12, "i", 23);
126
+ i0.ɵɵelementEnd();
127
+ i0.ɵɵelementStart(13, "div", 19)(14, "div", 20);
128
+ i0.ɵɵtext(15);
129
+ i0.ɵɵpipe(16, "async");
130
+ i0.ɵɵelementEnd();
131
+ i0.ɵɵelementStart(17, "div", 21);
132
+ i0.ɵɵtext(18, "Improvements");
133
+ i0.ɵɵelementEnd()()();
134
+ i0.ɵɵelementStart(19, "div", 16)(20, "div", 24);
135
+ i0.ɵɵelement(21, "i", 25);
136
+ i0.ɵɵelementEnd();
137
+ i0.ɵɵelementStart(22, "div", 19)(23, "div", 20);
138
+ i0.ɵɵtext(24);
139
+ i0.ɵɵpipe(25, "async");
140
+ i0.ɵɵelementEnd();
141
+ i0.ɵɵelementStart(26, "div", 21);
142
+ i0.ɵɵtext(27, "Unchanged");
143
+ i0.ɵɵelementEnd()()();
144
+ i0.ɵɵelementStart(28, "div", 16)(29, "div", 26);
145
+ i0.ɵɵelement(30, "i", 27);
146
+ i0.ɵɵelementEnd();
147
+ i0.ɵɵelementStart(31, "div", 19)(32, "div", 20);
148
+ i0.ɵɵtext(33);
149
+ i0.ɵɵpipe(34, "async");
150
+ i0.ɵɵpipe(35, "number");
151
+ i0.ɵɵelementEnd();
152
+ i0.ɵɵelementStart(36, "div", 21);
153
+ i0.ɵɵtext(37, "Cost Change");
154
+ i0.ɵɵelementEnd()()()();
155
+ i0.ɵɵelementStart(38, "div", 28)(39, "button", 29);
156
+ i0.ɵɵlistener("click", function TestingVersionComparisonComponent_Conditional_31_Template_button_click_39_listener() { i0.ɵɵrestoreView(_r3); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.setFilter("all")); });
157
+ i0.ɵɵelement(40, "i", 30);
158
+ i0.ɵɵtext(41, " All Tests ");
159
+ i0.ɵɵelementEnd();
160
+ i0.ɵɵelementStart(42, "button", 31);
161
+ i0.ɵɵlistener("click", function TestingVersionComparisonComponent_Conditional_31_Template_button_click_42_listener() { i0.ɵɵrestoreView(_r3); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.setFilter("regressions")); });
162
+ i0.ɵɵelement(43, "i", 18);
163
+ i0.ɵɵtext(44, " Regressions Only ");
164
+ i0.ɵɵelementEnd();
165
+ i0.ɵɵelementStart(45, "button", 32);
166
+ i0.ɵɵlistener("click", function TestingVersionComparisonComponent_Conditional_31_Template_button_click_45_listener() { i0.ɵɵrestoreView(_r3); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.setFilter("improvements")); });
167
+ i0.ɵɵelement(46, "i", 23);
168
+ i0.ɵɵtext(47, " Improvements Only ");
169
+ i0.ɵɵelementEnd();
170
+ i0.ɵɵelementStart(48, "button", 33);
171
+ i0.ɵɵlistener("click", function TestingVersionComparisonComponent_Conditional_31_Template_button_click_48_listener() { i0.ɵɵrestoreView(_r3); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.setFilter("unchanged")); });
172
+ i0.ɵɵelement(49, "i", 25);
173
+ i0.ɵɵtext(50, " Unchanged ");
174
+ i0.ɵɵelementEnd()();
175
+ i0.ɵɵelementStart(51, "div", 34)(52, "div", 35)(53, "div", 36)(54, "div", 37);
176
+ i0.ɵɵtext(55, "Test Name");
177
+ i0.ɵɵelementEnd();
178
+ i0.ɵɵelementStart(56, "div", 38);
179
+ i0.ɵɵtext(57);
180
+ i0.ɵɵelementEnd();
181
+ i0.ɵɵelementStart(58, "div", 38);
182
+ i0.ɵɵtext(59);
183
+ i0.ɵɵelementEnd();
184
+ i0.ɵɵelementStart(60, "div", 39);
185
+ i0.ɵɵtext(61, "Score \u0394");
186
+ i0.ɵɵelementEnd();
187
+ i0.ɵɵelementStart(62, "div", 39);
188
+ i0.ɵɵtext(63, "Cost \u0394");
189
+ i0.ɵɵelementEnd();
190
+ i0.ɵɵelementStart(64, "div", 39);
191
+ i0.ɵɵtext(65, "Duration \u0394");
192
+ i0.ɵɵelementEnd();
193
+ i0.ɵɵelementStart(66, "div", 40);
194
+ i0.ɵɵtext(67, "Status");
195
+ i0.ɵɵelementEnd()();
196
+ i0.ɵɵrepeaterCreate(68, TestingVersionComparisonComponent_Conditional_31_For_69_Template, 29, 30, "div", 41, _forTrack1, false, TestingVersionComparisonComponent_Conditional_31_ForEmpty_70_Template, 4, 0, "div", 42);
197
+ i0.ɵɵpipe(71, "async");
198
+ i0.ɵɵelementEnd()();
199
+ i0.ɵɵelementStart(72, "div", 43)(73, "div", 44)(74, "h3");
200
+ i0.ɵɵtext(75);
201
+ i0.ɵɵelementEnd();
202
+ i0.ɵɵelementStart(76, "div", 45)(77, "div", 46)(78, "span", 47);
203
+ i0.ɵɵtext(79, "Avg Score");
204
+ i0.ɵɵelementEnd();
205
+ i0.ɵɵelementStart(80, "span", 48);
206
+ i0.ɵɵtext(81);
207
+ i0.ɵɵpipe(82, "async");
208
+ i0.ɵɵelementEnd()();
209
+ i0.ɵɵelementStart(83, "div", 46)(84, "span", 47);
210
+ i0.ɵɵtext(85, "Pass Rate");
211
+ i0.ɵɵelementEnd();
212
+ i0.ɵɵelementStart(86, "span", 48);
213
+ i0.ɵɵtext(87);
214
+ i0.ɵɵpipe(88, "async");
215
+ i0.ɵɵelementEnd()();
216
+ i0.ɵɵelementStart(89, "div", 46)(90, "span", 47);
217
+ i0.ɵɵtext(91, "Total Cost");
218
+ i0.ɵɵelementEnd();
219
+ i0.ɵɵelementStart(92, "span", 48);
220
+ i0.ɵɵtext(93);
221
+ i0.ɵɵpipe(94, "async");
222
+ i0.ɵɵelementEnd()();
223
+ i0.ɵɵelementStart(95, "div", 46)(96, "span", 47);
224
+ i0.ɵɵtext(97, "Avg Duration");
225
+ i0.ɵɵelementEnd();
226
+ i0.ɵɵelementStart(98, "span", 48);
227
+ i0.ɵɵtext(99);
228
+ i0.ɵɵpipe(100, "async");
229
+ i0.ɵɵelementEnd()()()();
230
+ i0.ɵɵelementStart(101, "div", 44)(102, "h3");
231
+ i0.ɵɵtext(103);
232
+ i0.ɵɵelementEnd();
233
+ i0.ɵɵelementStart(104, "div", 45)(105, "div", 46)(106, "span", 47);
234
+ i0.ɵɵtext(107, "Avg Score");
235
+ i0.ɵɵelementEnd();
236
+ i0.ɵɵelementStart(108, "span", 48);
237
+ i0.ɵɵtext(109);
238
+ i0.ɵɵpipe(110, "async");
239
+ i0.ɵɵelementEnd()();
240
+ i0.ɵɵelementStart(111, "div", 46)(112, "span", 47);
241
+ i0.ɵɵtext(113, "Pass Rate");
242
+ i0.ɵɵelementEnd();
243
+ i0.ɵɵelementStart(114, "span", 48);
244
+ i0.ɵɵtext(115);
245
+ i0.ɵɵpipe(116, "async");
246
+ i0.ɵɵelementEnd()();
247
+ i0.ɵɵelementStart(117, "div", 46)(118, "span", 47);
248
+ i0.ɵɵtext(119, "Total Cost");
249
+ i0.ɵɵelementEnd();
250
+ i0.ɵɵelementStart(120, "span", 48);
251
+ i0.ɵɵtext(121);
252
+ i0.ɵɵpipe(122, "async");
253
+ i0.ɵɵelementEnd()();
254
+ i0.ɵɵelementStart(123, "div", 46)(124, "span", 47);
255
+ i0.ɵɵtext(125, "Avg Duration");
256
+ i0.ɵɵelementEnd();
257
+ i0.ɵɵelementStart(126, "span", 48);
258
+ i0.ɵɵtext(127);
259
+ i0.ɵɵpipe(128, "async");
260
+ i0.ɵɵelementEnd()()()()();
261
+ } if (rf & 2) {
262
+ let tmp_11_0;
263
+ let tmp_13_0;
264
+ let tmp_14_0;
265
+ let tmp_15_0;
266
+ let tmp_16_0;
267
+ let tmp_18_0;
268
+ let tmp_19_0;
269
+ let tmp_20_0;
270
+ let tmp_21_0;
271
+ const ctx_r3 = i0.ɵɵnextContext();
272
+ i0.ɵɵadvance(6);
273
+ i0.ɵɵtextInterpolate(i0.ɵɵpipeBind1(7, 25, ctx_r3.regressionCount$) || 0);
274
+ i0.ɵɵadvance(9);
275
+ i0.ɵɵtextInterpolate(i0.ɵɵpipeBind1(16, 27, ctx_r3.improvementCount$) || 0);
276
+ i0.ɵɵadvance(9);
277
+ i0.ɵɵtextInterpolate(i0.ɵɵpipeBind1(25, 29, ctx_r3.unchangedCount$) || 0);
278
+ i0.ɵɵadvance(9);
279
+ i0.ɵɵtextInterpolate1("", i0.ɵɵpipeBind2(35, 33, i0.ɵɵpipeBind1(34, 31, ctx_r3.totalCostDelta$) || 0, "1.2-2"), "%");
280
+ i0.ɵɵadvance(6);
281
+ i0.ɵɵclassProp("active", ctx_r3.filter === "all");
282
+ i0.ɵɵadvance(3);
283
+ i0.ɵɵclassProp("active", ctx_r3.filter === "regressions");
284
+ i0.ɵɵadvance(3);
285
+ i0.ɵɵclassProp("active", ctx_r3.filter === "improvements");
286
+ i0.ɵɵadvance(3);
287
+ i0.ɵɵclassProp("active", ctx_r3.filter === "unchanged");
288
+ i0.ɵɵadvance(9);
289
+ i0.ɵɵtextInterpolate(ctx_r3.versionA);
290
+ i0.ɵɵadvance(2);
291
+ i0.ɵɵtextInterpolate(ctx_r3.versionB);
292
+ i0.ɵɵadvance(9);
293
+ i0.ɵɵrepeater((tmp_11_0 = i0.ɵɵpipeBind1(71, 36, ctx_r3.filteredComparisons$)) !== null && tmp_11_0 !== undefined ? tmp_11_0 : i0.ɵɵpureFunction0(54, _c0));
294
+ i0.ɵɵadvance(7);
295
+ i0.ɵɵtextInterpolate1("", ctx_r3.versionA, " Metrics");
296
+ i0.ɵɵadvance(6);
297
+ i0.ɵɵtextInterpolate(((tmp_13_0 = i0.ɵɵpipeBind1(82, 38, ctx_r3.versionAMetrics$)) == null ? null : tmp_13_0.averageScore.toFixed(4)) || "0.0000");
298
+ i0.ɵɵadvance(6);
299
+ i0.ɵɵtextInterpolate1("", ((tmp_14_0 = i0.ɵɵpipeBind1(88, 40, ctx_r3.versionAMetrics$)) == null ? null : tmp_14_0.passRate.toFixed(1)) || "0.0", "%");
300
+ i0.ɵɵadvance(6);
301
+ i0.ɵɵtextInterpolate1("$", ((tmp_15_0 = i0.ɵɵpipeBind1(94, 42, ctx_r3.versionAMetrics$)) == null ? null : tmp_15_0.totalCost.toFixed(2)) || "0.00", "");
302
+ i0.ɵɵadvance(6);
303
+ i0.ɵɵtextInterpolate(ctx_r3.formatDuration(((tmp_16_0 = i0.ɵɵpipeBind1(100, 44, ctx_r3.versionAMetrics$)) == null ? null : tmp_16_0.avgDuration) || 0));
304
+ i0.ɵɵadvance(4);
305
+ i0.ɵɵtextInterpolate1("", ctx_r3.versionB, " Metrics");
306
+ i0.ɵɵadvance(6);
307
+ i0.ɵɵtextInterpolate(((tmp_18_0 = i0.ɵɵpipeBind1(110, 46, ctx_r3.versionBMetrics$)) == null ? null : tmp_18_0.averageScore.toFixed(4)) || "0.0000");
308
+ i0.ɵɵadvance(6);
309
+ i0.ɵɵtextInterpolate1("", ((tmp_19_0 = i0.ɵɵpipeBind1(116, 48, ctx_r3.versionBMetrics$)) == null ? null : tmp_19_0.passRate.toFixed(1)) || "0.0", "%");
310
+ i0.ɵɵadvance(6);
311
+ i0.ɵɵtextInterpolate1("$", ((tmp_20_0 = i0.ɵɵpipeBind1(122, 50, ctx_r3.versionBMetrics$)) == null ? null : tmp_20_0.totalCost.toFixed(2)) || "0.00", "");
312
+ i0.ɵɵadvance(6);
313
+ i0.ɵɵtextInterpolate(ctx_r3.formatDuration(((tmp_21_0 = i0.ɵɵpipeBind1(128, 52, ctx_r3.versionBMetrics$)) == null ? null : tmp_21_0.avgDuration) || 0));
314
+ } }
315
+ function TestingVersionComparisonComponent_Conditional_32_Template(rf, ctx) { if (rf & 1) {
316
+ i0.ɵɵelementStart(0, "div", 14);
317
+ i0.ɵɵelement(1, "i", 3);
318
+ i0.ɵɵelementStart(2, "h3");
319
+ i0.ɵɵtext(3, "Select Two Versions to Compare");
320
+ i0.ɵɵelementEnd();
321
+ i0.ɵɵelementStart(4, "p");
322
+ i0.ɵɵtext(5, "Choose a baseline version and a comparison version from the dropdowns above to analyze changes and detect regressions.");
323
+ i0.ɵɵelementEnd()();
324
+ } }
325
+ export class TestingVersionComparisonComponent {
326
+ instrumentationService;
327
+ cdr;
328
+ initialState;
329
+ stateChange = new EventEmitter();
330
+ destroy$ = new Subject();
331
+ versionA = '';
332
+ versionB = '';
333
+ filter = 'all';
334
+ versions$;
335
+ comparisons$;
336
+ filteredComparisons$;
337
+ regressionCount$;
338
+ improvementCount$;
339
+ unchangedCount$;
340
+ totalCostDelta$;
341
+ versionAMetrics$;
342
+ versionBMetrics$;
343
+ constructor(instrumentationService, cdr) {
344
+ this.instrumentationService = instrumentationService;
345
+ this.cdr = cdr;
346
+ }
347
+ ngOnInit() {
348
+ this.setupObservables();
349
+ if (this.initialState) {
350
+ this.versionA = this.initialState.versionA || '';
351
+ this.versionB = this.initialState.versionB || '';
352
+ this.filter = this.initialState.filter || 'all';
353
+ }
354
+ }
355
+ ngOnDestroy() {
356
+ this.destroy$.next();
357
+ this.destroy$.complete();
358
+ }
359
+ setupObservables() {
360
+ // Load version metrics from the service method
361
+ this.versions$ = of(this.instrumentationService.getVersionMetrics()).pipe(switchMap(promise => promise), shareReplay(1), takeUntil(this.destroy$));
362
+ this.comparisons$ = combineLatest([
363
+ this.instrumentationService.testRuns$
364
+ ]).pipe(map(() => this.generateComparisons()), takeUntil(this.destroy$));
365
+ this.filteredComparisons$ = this.comparisons$.pipe(map(comparisons => this.filterComparisons(comparisons)));
366
+ this.regressionCount$ = this.comparisons$.pipe(map(comparisons => comparisons.filter(c => c.regression).length));
367
+ this.improvementCount$ = this.comparisons$.pipe(map(comparisons => comparisons.filter(c => c.improvement).length));
368
+ this.unchangedCount$ = this.comparisons$.pipe(map(comparisons => comparisons.filter(c => !c.regression && !c.improvement).length));
369
+ this.totalCostDelta$ = this.comparisons$.pipe(map(comparisons => {
370
+ if (comparisons.length === 0)
371
+ return 0;
372
+ const avgDelta = comparisons.reduce((sum, c) => sum + c.costDelta, 0) / comparisons.length;
373
+ return avgDelta * 100;
374
+ }));
375
+ this.versionAMetrics$ = this.instrumentationService.testRuns$.pipe(map(runs => this.calculateVersionMetrics(this.versionA, runs)));
376
+ this.versionBMetrics$ = this.instrumentationService.testRuns$.pipe(map(runs => this.calculateVersionMetrics(this.versionB, runs)));
377
+ }
378
+ generateComparisons() {
379
+ if (!this.versionA || !this.versionB)
380
+ return [];
381
+ const runsA = this.getRunsForVersion(this.versionA);
382
+ const runsB = this.getRunsForVersion(this.versionB);
383
+ const testNames = new Set([
384
+ ...runsA.map(r => r.testName),
385
+ ...runsB.map(r => r.testName)
386
+ ]);
387
+ return Array.from(testNames).map(testName => {
388
+ const testRunsA = runsA.filter(r => r.testName === testName);
389
+ const testRunsB = runsB.filter(r => r.testName === testName);
390
+ const versionAData = this.aggregateTestData(testRunsA);
391
+ const versionBData = this.aggregateTestData(testRunsB);
392
+ const scoreDelta = versionBData.avgScore - versionAData.avgScore;
393
+ const costDelta = versionBData.avgCost === 0 ? 0 : (versionBData.avgCost - versionAData.avgCost) / versionAData.avgCost;
394
+ const durationDelta = versionBData.avgDuration === 0 ? 0 : (versionBData.avgDuration - versionAData.avgDuration) / versionAData.avgDuration;
395
+ return {
396
+ testName,
397
+ versionA: versionAData,
398
+ versionB: versionBData,
399
+ regression: scoreDelta < -0.05 || (versionBData.passRate - versionAData.passRate) < -5,
400
+ improvement: scoreDelta > 0.05 || (versionBData.passRate - versionAData.passRate) > 5,
401
+ scoreDelta,
402
+ costDelta,
403
+ durationDelta
404
+ };
405
+ }).sort((a, b) => {
406
+ if (a.regression && !b.regression)
407
+ return -1;
408
+ if (!a.regression && b.regression)
409
+ return 1;
410
+ return Math.abs(b.scoreDelta) - Math.abs(a.scoreDelta);
411
+ });
412
+ }
413
+ getRunsForVersion(version) {
414
+ return [];
415
+ }
416
+ aggregateTestData(runs) {
417
+ if (runs.length === 0) {
418
+ return {
419
+ avgScore: 0,
420
+ avgCost: 0,
421
+ avgDuration: 0,
422
+ passRate: 0,
423
+ runCount: 0
424
+ };
425
+ }
426
+ const passed = runs.filter(r => r.status === 'Passed').length;
427
+ return {
428
+ avgScore: runs.reduce((sum, r) => sum + r.score, 0) / runs.length,
429
+ avgCost: runs.reduce((sum, r) => sum + r.cost, 0) / runs.length,
430
+ avgDuration: runs.reduce((sum, r) => sum + r.duration, 0) / runs.length,
431
+ passRate: (passed / runs.length) * 100,
432
+ runCount: runs.length
433
+ };
434
+ }
435
+ filterComparisons(comparisons) {
436
+ if (this.filter === 'all')
437
+ return comparisons;
438
+ if (this.filter === 'regressions')
439
+ return comparisons.filter(c => c.regression);
440
+ if (this.filter === 'improvements')
441
+ return comparisons.filter(c => c.improvement);
442
+ if (this.filter === 'unchanged')
443
+ return comparisons.filter(c => !c.regression && !c.improvement);
444
+ return comparisons;
445
+ }
446
+ calculateVersionMetrics(version, allRuns) {
447
+ const runs = allRuns.filter(r => r.testName === version);
448
+ if (runs.length === 0) {
449
+ return {
450
+ averageScore: 0,
451
+ passRate: 0,
452
+ totalCost: 0,
453
+ avgDuration: 0
454
+ };
455
+ }
456
+ const passed = runs.filter(r => r.status === 'Passed').length;
457
+ return {
458
+ averageScore: runs.reduce((sum, r) => sum + r.score, 0) / runs.length,
459
+ passRate: (passed / runs.length) * 100,
460
+ totalCost: runs.reduce((sum, r) => sum + r.cost, 0),
461
+ avgDuration: runs.reduce((sum, r) => sum + r.duration, 0) / runs.length
462
+ };
463
+ }
464
+ onVersionChange() {
465
+ this.emitStateChange();
466
+ this.cdr.markForCheck();
467
+ }
468
+ setFilter(filter) {
469
+ this.filter = filter;
470
+ this.emitStateChange();
471
+ this.cdr.markForCheck();
472
+ }
473
+ refresh() {
474
+ this.instrumentationService.refresh();
475
+ }
476
+ formatDuration(milliseconds) {
477
+ if (milliseconds < 1000)
478
+ return `${milliseconds}ms`;
479
+ const seconds = Math.floor(milliseconds / 1000);
480
+ const minutes = Math.floor(seconds / 60);
481
+ if (minutes > 0)
482
+ return `${minutes}m ${seconds % 60}s`;
483
+ return `${seconds}s`;
484
+ }
485
+ emitStateChange() {
486
+ this.stateChange.emit({
487
+ versionA: this.versionA,
488
+ versionB: this.versionB,
489
+ filter: this.filter
490
+ });
491
+ }
492
+ static ɵfac = function TestingVersionComparisonComponent_Factory(t) { return new (t || TestingVersionComparisonComponent)(i0.ɵɵdirectiveInject(i1.TestingInstrumentationService), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef)); };
493
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: TestingVersionComparisonComponent, selectors: [["app-testing-version-comparison"]], inputs: { initialState: "initialState" }, outputs: { stateChange: "stateChange" }, decls: 33, vars: 9, consts: [[1, "testing-version-comparison"], [1, "version-header"], [1, "header-left"], [1, "fa-solid", "fa-code-compare"], [1, "header-actions"], [1, "action-btn", 3, "click"], [1, "fa-solid", "fa-refresh"], [1, "version-selector"], [1, "selector-group"], [1, "version-select", 3, "ngModelChange", "change", "ngModel"], ["value", ""], [3, "value"], [1, "selector-icon"], [1, "fa-solid", "fa-arrows-left-right"], [1, "empty-state"], [1, "comparison-summary"], [1, "summary-card"], [1, "card-icon", "regression"], [1, "fa-solid", "fa-arrow-trend-down"], [1, "card-content"], [1, "card-value"], [1, "card-label"], [1, "card-icon", "improvement"], [1, "fa-solid", "fa-arrow-trend-up"], [1, "card-icon", "neutral"], [1, "fa-solid", "fa-minus"], [1, "card-icon", "cost"], [1, "fa-solid", "fa-dollar-sign"], [1, "comparison-filters"], [1, "filter-btn", 3, "click"], [1, "fa-solid", "fa-list"], [1, "filter-btn", "regression", 3, "click"], [1, "filter-btn", "improvement", 3, "click"], [1, "filter-btn", "neutral", 3, "click"], [1, "comparison-content"], [1, "comparison-table"], [1, "table-header"], [1, "header-cell", "test-name"], [1, "header-cell", "version-data"], [1, "header-cell", "delta"], [1, "header-cell", "status"], [1, "table-row", 3, "regression", "improvement"], [1, "no-data"], [1, "metrics-overview"], [1, "overview-section"], [1, "metrics-grid"], [1, "metric-item"], [1, "metric-label"], [1, "metric-value"], [1, "table-row"], [1, "cell", "test-name"], [1, "test-name-text"], [1, "cell", "version-data"], [1, "version-metrics"], [1, "metric-meta"], [1, "cell", "delta"], [1, "delta-value"], [1, "cell", "status"], [1, "status-badge", "regression"], [1, "status-badge", "improvement"], [1, "status-badge", "neutral"], [1, "fa-solid", "fa-exclamation-triangle"], [1, "fa-solid", "fa-check-circle"], [1, "fa-solid", "fa-minus-circle"], [1, "fa-solid", "fa-chart-simple"]], template: function TestingVersionComparisonComponent_Template(rf, ctx) { if (rf & 1) {
494
+ i0.ɵɵelementStart(0, "div", 0)(1, "div", 1)(2, "div", 2)(3, "h2");
495
+ i0.ɵɵelement(4, "i", 3);
496
+ i0.ɵɵtext(5, " Version Comparison ");
497
+ i0.ɵɵelementEnd()();
498
+ i0.ɵɵelementStart(6, "div", 4)(7, "button", 5);
499
+ i0.ɵɵlistener("click", function TestingVersionComparisonComponent_Template_button_click_7_listener() { return ctx.refresh(); });
500
+ i0.ɵɵelement(8, "i", 6);
501
+ i0.ɵɵtext(9, " Refresh ");
502
+ i0.ɵɵelementEnd()()();
503
+ i0.ɵɵelementStart(10, "div", 7)(11, "div", 8)(12, "label");
504
+ i0.ɵɵtext(13, "Version A (Baseline)");
505
+ i0.ɵɵelementEnd();
506
+ i0.ɵɵelementStart(14, "select", 9);
507
+ i0.ɵɵtwoWayListener("ngModelChange", function TestingVersionComparisonComponent_Template_select_ngModelChange_14_listener($event) { i0.ɵɵtwoWayBindingSet(ctx.versionA, $event) || (ctx.versionA = $event); return $event; });
508
+ i0.ɵɵlistener("change", function TestingVersionComparisonComponent_Template_select_change_14_listener() { return ctx.onVersionChange(); });
509
+ i0.ɵɵelementStart(15, "option", 10);
510
+ i0.ɵɵtext(16, "Select Version...");
511
+ i0.ɵɵelementEnd();
512
+ i0.ɵɵrepeaterCreate(17, TestingVersionComparisonComponent_For_18_Template, 2, 3, "option", 11, _forTrack0);
513
+ i0.ɵɵpipe(19, "async");
514
+ i0.ɵɵelementEnd()();
515
+ i0.ɵɵelementStart(20, "div", 12);
516
+ i0.ɵɵelement(21, "i", 13);
517
+ i0.ɵɵelementEnd();
518
+ i0.ɵɵelementStart(22, "div", 8)(23, "label");
519
+ i0.ɵɵtext(24, "Version B (Comparison)");
520
+ i0.ɵɵelementEnd();
521
+ i0.ɵɵelementStart(25, "select", 9);
522
+ i0.ɵɵtwoWayListener("ngModelChange", function TestingVersionComparisonComponent_Template_select_ngModelChange_25_listener($event) { i0.ɵɵtwoWayBindingSet(ctx.versionB, $event) || (ctx.versionB = $event); return $event; });
523
+ i0.ɵɵlistener("change", function TestingVersionComparisonComponent_Template_select_change_25_listener() { return ctx.onVersionChange(); });
524
+ i0.ɵɵelementStart(26, "option", 10);
525
+ i0.ɵɵtext(27, "Select Version...");
526
+ i0.ɵɵelementEnd();
527
+ i0.ɵɵrepeaterCreate(28, TestingVersionComparisonComponent_For_29_Template, 2, 3, "option", 11, _forTrack0);
528
+ i0.ɵɵpipe(30, "async");
529
+ i0.ɵɵelementEnd()()();
530
+ i0.ɵɵtemplate(31, TestingVersionComparisonComponent_Conditional_31_Template, 129, 55)(32, TestingVersionComparisonComponent_Conditional_32_Template, 6, 0, "div", 14);
531
+ i0.ɵɵelementEnd();
532
+ } if (rf & 2) {
533
+ let tmp_1_0;
534
+ let tmp_3_0;
535
+ i0.ɵɵadvance(14);
536
+ i0.ɵɵtwoWayProperty("ngModel", ctx.versionA);
537
+ i0.ɵɵadvance(3);
538
+ i0.ɵɵrepeater((tmp_1_0 = i0.ɵɵpipeBind1(19, 3, ctx.versions$)) !== null && tmp_1_0 !== undefined ? tmp_1_0 : i0.ɵɵpureFunction0(7, _c0));
539
+ i0.ɵɵadvance(8);
540
+ i0.ɵɵtwoWayProperty("ngModel", ctx.versionB);
541
+ i0.ɵɵadvance(3);
542
+ i0.ɵɵrepeater((tmp_3_0 = i0.ɵɵpipeBind1(30, 5, ctx.versions$)) !== null && tmp_3_0 !== undefined ? tmp_3_0 : i0.ɵɵpureFunction0(8, _c0));
543
+ i0.ɵɵadvance(3);
544
+ i0.ɵɵconditional(ctx.versionA && ctx.versionB ? 31 : 32);
545
+ } }, dependencies: [i2.NgSelectOption, i2.ɵNgSelectMultipleOption, i2.SelectControlValueAccessor, i2.NgControlStatus, i2.NgModel, i3.AsyncPipe, i3.DecimalPipe], styles: [".testing-version-comparison[_ngcontent-%COMP%] {\n padding: 20px;\n height: 100%;\n overflow-y: auto;\n background: #f8f9fa;\n }\n\n .version-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 24px;\n background: white;\n padding: 20px;\n border-radius: 8px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);\n }\n\n .header-left[_ngcontent-%COMP%] h2[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 20px;\n font-weight: 600;\n color: #333;\n display: flex;\n align-items: center;\n gap: 12px;\n }\n\n .header-left[_ngcontent-%COMP%] h2[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #2196f3;\n }\n\n .action-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n border: 1px solid #ddd;\n border-radius: 4px;\n background: white;\n color: #666;\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s ease;\n }\n\n .action-btn[_ngcontent-%COMP%]:hover {\n background: #f5f5f5;\n }\n\n .version-selector[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 1fr auto 1fr;\n gap: 20px;\n align-items: center;\n background: white;\n padding: 20px;\n border-radius: 8px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);\n margin-bottom: 24px;\n }\n\n .selector-group[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n }\n\n .selector-group[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 600;\n color: #666;\n text-transform: uppercase;\n }\n\n .version-select[_ngcontent-%COMP%] {\n padding: 10px 14px;\n border: 2px solid #ddd;\n border-radius: 6px;\n font-size: 14px;\n background: white;\n cursor: pointer;\n transition: border-color 0.2s ease;\n }\n\n .version-select[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: #2196f3;\n }\n\n .selector-icon[_ngcontent-%COMP%] {\n font-size: 24px;\n color: #2196f3;\n text-align: center;\n }\n\n .comparison-summary[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: 16px;\n margin-bottom: 24px;\n }\n\n .summary-card[_ngcontent-%COMP%] {\n background: white;\n padding: 20px;\n border-radius: 8px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);\n display: flex;\n align-items: center;\n gap: 16px;\n }\n\n .card-icon[_ngcontent-%COMP%] {\n width: 56px;\n height: 56px;\n border-radius: 12px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 24px;\n color: white;\n }\n\n .card-icon.regression[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #f44336 0%, #d32f2f 100%);\n }\n\n .card-icon.improvement[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #4caf50 0%, #388e3c 100%);\n }\n\n .card-icon.neutral[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #9e9e9e 0%, #757575 100%);\n }\n\n .card-icon.cost[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #ff9800 0%, #f57c00 100%);\n }\n\n .card-content[_ngcontent-%COMP%] {\n flex: 1;\n }\n\n .card-value[_ngcontent-%COMP%] {\n font-size: 28px;\n font-weight: 700;\n color: #333;\n line-height: 1;\n margin-bottom: 6px;\n }\n\n .card-label[_ngcontent-%COMP%] {\n font-size: 11px;\n color: #666;\n font-weight: 600;\n text-transform: uppercase;\n }\n\n .comparison-filters[_ngcontent-%COMP%] {\n display: flex;\n gap: 12px;\n margin-bottom: 20px;\n background: white;\n padding: 16px;\n border-radius: 8px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);\n }\n\n .filter-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 16px;\n border: 2px solid #e0e0e0;\n border-radius: 6px;\n background: white;\n color: #666;\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s ease;\n }\n\n .filter-btn[_ngcontent-%COMP%]:hover {\n background: #f5f5f5;\n border-color: #bdbdbd;\n }\n\n .filter-btn.active[_ngcontent-%COMP%] {\n background: #2196f3;\n border-color: #2196f3;\n color: white;\n }\n\n .filter-btn.regression.active[_ngcontent-%COMP%] {\n background: #f44336;\n border-color: #f44336;\n }\n\n .filter-btn.improvement.active[_ngcontent-%COMP%] {\n background: #4caf50;\n border-color: #4caf50;\n }\n\n .filter-btn.neutral.active[_ngcontent-%COMP%] {\n background: #9e9e9e;\n border-color: #9e9e9e;\n }\n\n .comparison-content[_ngcontent-%COMP%] {\n background: white;\n border-radius: 8px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);\n overflow: hidden;\n margin-bottom: 24px;\n }\n\n .comparison-table[_ngcontent-%COMP%] {\n overflow-x: auto;\n }\n\n .table-header[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 2fr 1.5fr 1.5fr 100px 100px 100px 140px;\n gap: 16px;\n padding: 16px;\n background: #f8f9fa;\n border-bottom: 2px solid #e0e0e0;\n font-size: 11px;\n font-weight: 600;\n color: #666;\n text-transform: uppercase;\n }\n\n .table-row[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 2fr 1.5fr 1.5fr 100px 100px 100px 140px;\n gap: 16px;\n padding: 16px;\n border-bottom: 1px solid #f0f0f0;\n transition: background 0.2s ease;\n }\n\n .table-row[_ngcontent-%COMP%]:hover {\n background: #f8f9fa;\n }\n\n .table-row.regression[_ngcontent-%COMP%] {\n border-left: 4px solid #f44336;\n }\n\n .table-row.improvement[_ngcontent-%COMP%] {\n border-left: 4px solid #4caf50;\n }\n\n .cell[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n font-size: 13px;\n color: #333;\n }\n\n .cell.test-name[_ngcontent-%COMP%] {\n font-weight: 500;\n }\n\n .version-metrics[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 4px;\n }\n\n .metric-value[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: #333;\n }\n\n .metric-meta[_ngcontent-%COMP%] {\n font-size: 11px;\n color: #666;\n }\n\n .delta-value[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 600;\n padding: 4px 8px;\n border-radius: 4px;\n }\n\n .delta-value.positive[_ngcontent-%COMP%] {\n background: #e8f5e9;\n color: #4caf50;\n }\n\n .delta-value.negative[_ngcontent-%COMP%] {\n background: #ffebee;\n color: #f44336;\n }\n\n .status-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 600;\n }\n\n .status-badge.regression[_ngcontent-%COMP%] {\n background: #ffebee;\n color: #f44336;\n }\n\n .status-badge.improvement[_ngcontent-%COMP%] {\n background: #e8f5e9;\n color: #4caf50;\n }\n\n .status-badge.neutral[_ngcontent-%COMP%] {\n background: #f5f5f5;\n color: #9e9e9e;\n }\n\n .metrics-overview[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 20px;\n }\n\n .overview-section[_ngcontent-%COMP%] {\n background: white;\n padding: 20px;\n border-radius: 8px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);\n }\n\n .overview-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 16px 0;\n font-size: 16px;\n font-weight: 600;\n color: #333;\n padding-bottom: 12px;\n border-bottom: 2px solid #f0f0f0;\n }\n\n .metrics-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 16px;\n }\n\n .metric-item[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n padding: 12px;\n background: #f8f9fa;\n border-radius: 6px;\n }\n\n .metric-label[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 600;\n color: #666;\n text-transform: uppercase;\n }\n\n .metric-value[_ngcontent-%COMP%] {\n font-size: 18px;\n font-weight: 700;\n color: #333;\n }\n\n .empty-state[_ngcontent-%COMP%], \n .no-data[_ngcontent-%COMP%] {\n padding: 80px 20px;\n text-align: center;\n color: #999;\n }\n\n .empty-state[_ngcontent-%COMP%] i[_ngcontent-%COMP%], \n .no-data[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 64px;\n margin-bottom: 20px;\n opacity: 0.3;\n color: #2196f3;\n }\n\n .empty-state[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n font-size: 20px;\n color: #666;\n margin: 0 0 12px 0;\n }\n\n .empty-state[_ngcontent-%COMP%] p[_ngcontent-%COMP%], \n .no-data[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n font-size: 14px;\n margin: 0;\n max-width: 500px;\n margin: 0 auto;\n line-height: 1.6;\n }\n\n @media (max-width: 1200px) {\n .metrics-overview[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n\n .version-selector[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n\n .selector-icon[_ngcontent-%COMP%] {\n transform: rotate(90deg);\n }\n }"], changeDetection: 0 });
546
+ }
547
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(TestingVersionComparisonComponent, [{
548
+ type: Component,
549
+ args: [{ selector: 'app-testing-version-comparison', changeDetection: ChangeDetectionStrategy.OnPush, template: `
550
+ <div class="testing-version-comparison">
551
+ <div class="version-header">
552
+ <div class="header-left">
553
+ <h2>
554
+ <i class="fa-solid fa-code-compare"></i>
555
+ Version Comparison
556
+ </h2>
557
+ </div>
558
+ <div class="header-actions">
559
+ <button class="action-btn" (click)="refresh()">
560
+ <i class="fa-solid fa-refresh"></i>
561
+ Refresh
562
+ </button>
563
+ </div>
564
+ </div>
565
+
566
+ <!-- Version Selector -->
567
+ <div class="version-selector">
568
+ <div class="selector-group">
569
+ <label>Version A (Baseline)</label>
570
+ <select [(ngModel)]="versionA" (change)="onVersionChange()" class="version-select">
571
+ <option value="">Select Version...</option>
572
+ @for (version of (versions$ | async) ?? []; track version.version) {
573
+ <option [value]="version.version">{{ version.version }} ({{ version.totalTests }} tests)</option>
574
+ }
575
+ </select>
576
+ </div>
577
+ <div class="selector-icon">
578
+ <i class="fa-solid fa-arrows-left-right"></i>
579
+ </div>
580
+ <div class="selector-group">
581
+ <label>Version B (Comparison)</label>
582
+ <select [(ngModel)]="versionB" (change)="onVersionChange()" class="version-select">
583
+ <option value="">Select Version...</option>
584
+ @for (version of (versions$ | async) ?? []; track version.version) {
585
+ <option [value]="version.version">{{ version.version }} ({{ version.totalTests }} tests)</option>
586
+ }
587
+ </select>
588
+ </div>
589
+ </div>
590
+
591
+ @if (versionA && versionB) {
592
+ <!-- Summary Cards -->
593
+ <div class="comparison-summary">
594
+ <div class="summary-card">
595
+ <div class="card-icon regression">
596
+ <i class="fa-solid fa-arrow-trend-down"></i>
597
+ </div>
598
+ <div class="card-content">
599
+ <div class="card-value">{{ (regressionCount$ | async) || 0 }}</div>
600
+ <div class="card-label">Regressions Detected</div>
601
+ </div>
602
+ </div>
603
+ <div class="summary-card">
604
+ <div class="card-icon improvement">
605
+ <i class="fa-solid fa-arrow-trend-up"></i>
606
+ </div>
607
+ <div class="card-content">
608
+ <div class="card-value">{{ (improvementCount$ | async) || 0 }}</div>
609
+ <div class="card-label">Improvements</div>
610
+ </div>
611
+ </div>
612
+ <div class="summary-card">
613
+ <div class="card-icon neutral">
614
+ <i class="fa-solid fa-minus"></i>
615
+ </div>
616
+ <div class="card-content">
617
+ <div class="card-value">{{ (unchangedCount$ | async) || 0 }}</div>
618
+ <div class="card-label">Unchanged</div>
619
+ </div>
620
+ </div>
621
+ <div class="summary-card">
622
+ <div class="card-icon cost">
623
+ <i class="fa-solid fa-dollar-sign"></i>
624
+ </div>
625
+ <div class="card-content">
626
+ <div class="card-value">{{ (totalCostDelta$ | async) || 0 | number:'1.2-2' }}%</div>
627
+ <div class="card-label">Cost Change</div>
628
+ </div>
629
+ </div>
630
+ </div>
631
+
632
+ <!-- Filters -->
633
+ <div class="comparison-filters">
634
+ <button
635
+ class="filter-btn"
636
+ [class.active]="filter === 'all'"
637
+ (click)="setFilter('all')"
638
+ >
639
+ <i class="fa-solid fa-list"></i>
640
+ All Tests
641
+ </button>
642
+ <button
643
+ class="filter-btn regression"
644
+ [class.active]="filter === 'regressions'"
645
+ (click)="setFilter('regressions')"
646
+ >
647
+ <i class="fa-solid fa-arrow-trend-down"></i>
648
+ Regressions Only
649
+ </button>
650
+ <button
651
+ class="filter-btn improvement"
652
+ [class.active]="filter === 'improvements'"
653
+ (click)="setFilter('improvements')"
654
+ >
655
+ <i class="fa-solid fa-arrow-trend-up"></i>
656
+ Improvements Only
657
+ </button>
658
+ <button
659
+ class="filter-btn neutral"
660
+ [class.active]="filter === 'unchanged'"
661
+ (click)="setFilter('unchanged')"
662
+ >
663
+ <i class="fa-solid fa-minus"></i>
664
+ Unchanged
665
+ </button>
666
+ </div>
667
+
668
+ <!-- Comparison Table -->
669
+ <div class="comparison-content">
670
+ <div class="comparison-table">
671
+ <div class="table-header">
672
+ <div class="header-cell test-name">Test Name</div>
673
+ <div class="header-cell version-data">{{ versionA }}</div>
674
+ <div class="header-cell version-data">{{ versionB }}</div>
675
+ <div class="header-cell delta">Score Δ</div>
676
+ <div class="header-cell delta">Cost Δ</div>
677
+ <div class="header-cell delta">Duration Δ</div>
678
+ <div class="header-cell status">Status</div>
679
+ </div>
680
+
681
+ @for (comparison of (filteredComparisons$ | async) ?? []; track comparison.testName) {
682
+ <div class="table-row" [class.regression]="comparison.regression" [class.improvement]="comparison.improvement">
683
+ <div class="cell test-name">
684
+ <span class="test-name-text">{{ comparison.testName }}</span>
685
+ </div>
686
+ <div class="cell version-data">
687
+ <div class="version-metrics">
688
+ <span class="metric-value">{{ comparison.versionA.avgScore.toFixed(4) }}</span>
689
+ <span class="metric-meta">{{ comparison.versionA.passRate.toFixed(0) }}% pass • {{ comparison.versionA.runCount }} runs</span>
690
+ </div>
691
+ </div>
692
+ <div class="cell version-data">
693
+ <div class="version-metrics">
694
+ <span class="metric-value">{{ comparison.versionB.avgScore.toFixed(4) }}</span>
695
+ <span class="metric-meta">{{ comparison.versionB.passRate.toFixed(0) }}% pass • {{ comparison.versionB.runCount }} runs</span>
696
+ </div>
697
+ </div>
698
+ <div class="cell delta">
699
+ <span class="delta-value" [class.positive]="comparison.scoreDelta > 0" [class.negative]="comparison.scoreDelta < 0">
700
+ {{ comparison.scoreDelta > 0 ? '+' : '' }}{{ (comparison.scoreDelta * 100).toFixed(1) }}%
701
+ </span>
702
+ </div>
703
+ <div class="cell delta">
704
+ <span class="delta-value" [class.positive]="comparison.costDelta < 0" [class.negative]="comparison.costDelta > 0">
705
+ {{ comparison.costDelta > 0 ? '+' : '' }}{{ (comparison.costDelta * 100).toFixed(1) }}%
706
+ </span>
707
+ </div>
708
+ <div class="cell delta">
709
+ <span class="delta-value" [class.positive]="comparison.durationDelta < 0" [class.negative]="comparison.durationDelta > 0">
710
+ {{ comparison.durationDelta > 0 ? '+' : '' }}{{ (comparison.durationDelta * 100).toFixed(1) }}%
711
+ </span>
712
+ </div>
713
+ <div class="cell status">
714
+ @if (comparison.regression) {
715
+ <span class="status-badge regression">
716
+ <i class="fa-solid fa-exclamation-triangle"></i>
717
+ Regression
718
+ </span>
719
+ } @else if (comparison.improvement) {
720
+ <span class="status-badge improvement">
721
+ <i class="fa-solid fa-check-circle"></i>
722
+ Improved
723
+ </span>
724
+ } @else {
725
+ <span class="status-badge neutral">
726
+ <i class="fa-solid fa-minus-circle"></i>
727
+ Unchanged
728
+ </span>
729
+ }
730
+ </div>
731
+ </div>
732
+ } @empty {
733
+ <div class="no-data">
734
+ <i class="fa-solid fa-chart-simple"></i>
735
+ <p>No test data available for comparison</p>
736
+ </div>
737
+ }
738
+ </div>
739
+ </div>
740
+
741
+ <!-- Version Metrics Overview -->
742
+ <div class="metrics-overview">
743
+ <div class="overview-section">
744
+ <h3>{{ versionA }} Metrics</h3>
745
+ <div class="metrics-grid">
746
+ <div class="metric-item">
747
+ <span class="metric-label">Avg Score</span>
748
+ <span class="metric-value">{{ (versionAMetrics$ | async)?.averageScore.toFixed(4) || '0.0000' }}</span>
749
+ </div>
750
+ <div class="metric-item">
751
+ <span class="metric-label">Pass Rate</span>
752
+ <span class="metric-value">{{ (versionAMetrics$ | async)?.passRate.toFixed(1) || '0.0' }}%</span>
753
+ </div>
754
+ <div class="metric-item">
755
+ <span class="metric-label">Total Cost</span>
756
+ <span class="metric-value">\${{ (versionAMetrics$ | async)?.totalCost.toFixed(2) || '0.00' }}</span>
757
+ </div>
758
+ <div class="metric-item">
759
+ <span class="metric-label">Avg Duration</span>
760
+ <span class="metric-value">{{ formatDuration((versionAMetrics$ | async)?.avgDuration || 0) }}</span>
761
+ </div>
762
+ </div>
763
+ </div>
764
+ <div class="overview-section">
765
+ <h3>{{ versionB }} Metrics</h3>
766
+ <div class="metrics-grid">
767
+ <div class="metric-item">
768
+ <span class="metric-label">Avg Score</span>
769
+ <span class="metric-value">{{ (versionBMetrics$ | async)?.averageScore.toFixed(4) || '0.0000' }}</span>
770
+ </div>
771
+ <div class="metric-item">
772
+ <span class="metric-label">Pass Rate</span>
773
+ <span class="metric-value">{{ (versionBMetrics$ | async)?.passRate.toFixed(1) || '0.0' }}%</span>
774
+ </div>
775
+ <div class="metric-item">
776
+ <span class="metric-label">Total Cost</span>
777
+ <span class="metric-value">\${{ (versionBMetrics$ | async)?.totalCost.toFixed(2) || '0.00' }}</span>
778
+ </div>
779
+ <div class="metric-item">
780
+ <span class="metric-label">Avg Duration</span>
781
+ <span class="metric-value">{{ formatDuration((versionBMetrics$ | async)?.avgDuration || 0) }}</span>
782
+ </div>
783
+ </div>
784
+ </div>
785
+ </div>
786
+ } @else {
787
+ <div class="empty-state">
788
+ <i class="fa-solid fa-code-compare"></i>
789
+ <h3>Select Two Versions to Compare</h3>
790
+ <p>Choose a baseline version and a comparison version from the dropdowns above to analyze changes and detect regressions.</p>
791
+ </div>
792
+ }
793
+ </div>
794
+ `, styles: ["\n .testing-version-comparison {\n padding: 20px;\n height: 100%;\n overflow-y: auto;\n background: #f8f9fa;\n }\n\n .version-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 24px;\n background: white;\n padding: 20px;\n border-radius: 8px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);\n }\n\n .header-left h2 {\n margin: 0;\n font-size: 20px;\n font-weight: 600;\n color: #333;\n display: flex;\n align-items: center;\n gap: 12px;\n }\n\n .header-left h2 i {\n color: #2196f3;\n }\n\n .action-btn {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n border: 1px solid #ddd;\n border-radius: 4px;\n background: white;\n color: #666;\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s ease;\n }\n\n .action-btn:hover {\n background: #f5f5f5;\n }\n\n .version-selector {\n display: grid;\n grid-template-columns: 1fr auto 1fr;\n gap: 20px;\n align-items: center;\n background: white;\n padding: 20px;\n border-radius: 8px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);\n margin-bottom: 24px;\n }\n\n .selector-group {\n display: flex;\n flex-direction: column;\n gap: 8px;\n }\n\n .selector-group label {\n font-size: 12px;\n font-weight: 600;\n color: #666;\n text-transform: uppercase;\n }\n\n .version-select {\n padding: 10px 14px;\n border: 2px solid #ddd;\n border-radius: 6px;\n font-size: 14px;\n background: white;\n cursor: pointer;\n transition: border-color 0.2s ease;\n }\n\n .version-select:focus {\n outline: none;\n border-color: #2196f3;\n }\n\n .selector-icon {\n font-size: 24px;\n color: #2196f3;\n text-align: center;\n }\n\n .comparison-summary {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: 16px;\n margin-bottom: 24px;\n }\n\n .summary-card {\n background: white;\n padding: 20px;\n border-radius: 8px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);\n display: flex;\n align-items: center;\n gap: 16px;\n }\n\n .card-icon {\n width: 56px;\n height: 56px;\n border-radius: 12px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 24px;\n color: white;\n }\n\n .card-icon.regression {\n background: linear-gradient(135deg, #f44336 0%, #d32f2f 100%);\n }\n\n .card-icon.improvement {\n background: linear-gradient(135deg, #4caf50 0%, #388e3c 100%);\n }\n\n .card-icon.neutral {\n background: linear-gradient(135deg, #9e9e9e 0%, #757575 100%);\n }\n\n .card-icon.cost {\n background: linear-gradient(135deg, #ff9800 0%, #f57c00 100%);\n }\n\n .card-content {\n flex: 1;\n }\n\n .card-value {\n font-size: 28px;\n font-weight: 700;\n color: #333;\n line-height: 1;\n margin-bottom: 6px;\n }\n\n .card-label {\n font-size: 11px;\n color: #666;\n font-weight: 600;\n text-transform: uppercase;\n }\n\n .comparison-filters {\n display: flex;\n gap: 12px;\n margin-bottom: 20px;\n background: white;\n padding: 16px;\n border-radius: 8px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);\n }\n\n .filter-btn {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 16px;\n border: 2px solid #e0e0e0;\n border-radius: 6px;\n background: white;\n color: #666;\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s ease;\n }\n\n .filter-btn:hover {\n background: #f5f5f5;\n border-color: #bdbdbd;\n }\n\n .filter-btn.active {\n background: #2196f3;\n border-color: #2196f3;\n color: white;\n }\n\n .filter-btn.regression.active {\n background: #f44336;\n border-color: #f44336;\n }\n\n .filter-btn.improvement.active {\n background: #4caf50;\n border-color: #4caf50;\n }\n\n .filter-btn.neutral.active {\n background: #9e9e9e;\n border-color: #9e9e9e;\n }\n\n .comparison-content {\n background: white;\n border-radius: 8px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);\n overflow: hidden;\n margin-bottom: 24px;\n }\n\n .comparison-table {\n overflow-x: auto;\n }\n\n .table-header {\n display: grid;\n grid-template-columns: 2fr 1.5fr 1.5fr 100px 100px 100px 140px;\n gap: 16px;\n padding: 16px;\n background: #f8f9fa;\n border-bottom: 2px solid #e0e0e0;\n font-size: 11px;\n font-weight: 600;\n color: #666;\n text-transform: uppercase;\n }\n\n .table-row {\n display: grid;\n grid-template-columns: 2fr 1.5fr 1.5fr 100px 100px 100px 140px;\n gap: 16px;\n padding: 16px;\n border-bottom: 1px solid #f0f0f0;\n transition: background 0.2s ease;\n }\n\n .table-row:hover {\n background: #f8f9fa;\n }\n\n .table-row.regression {\n border-left: 4px solid #f44336;\n }\n\n .table-row.improvement {\n border-left: 4px solid #4caf50;\n }\n\n .cell {\n display: flex;\n align-items: center;\n font-size: 13px;\n color: #333;\n }\n\n .cell.test-name {\n font-weight: 500;\n }\n\n .version-metrics {\n display: flex;\n flex-direction: column;\n gap: 4px;\n }\n\n .metric-value {\n font-size: 14px;\n font-weight: 600;\n color: #333;\n }\n\n .metric-meta {\n font-size: 11px;\n color: #666;\n }\n\n .delta-value {\n font-size: 13px;\n font-weight: 600;\n padding: 4px 8px;\n border-radius: 4px;\n }\n\n .delta-value.positive {\n background: #e8f5e9;\n color: #4caf50;\n }\n\n .delta-value.negative {\n background: #ffebee;\n color: #f44336;\n }\n\n .status-badge {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 600;\n }\n\n .status-badge.regression {\n background: #ffebee;\n color: #f44336;\n }\n\n .status-badge.improvement {\n background: #e8f5e9;\n color: #4caf50;\n }\n\n .status-badge.neutral {\n background: #f5f5f5;\n color: #9e9e9e;\n }\n\n .metrics-overview {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 20px;\n }\n\n .overview-section {\n background: white;\n padding: 20px;\n border-radius: 8px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);\n }\n\n .overview-section h3 {\n margin: 0 0 16px 0;\n font-size: 16px;\n font-weight: 600;\n color: #333;\n padding-bottom: 12px;\n border-bottom: 2px solid #f0f0f0;\n }\n\n .metrics-grid {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 16px;\n }\n\n .metric-item {\n display: flex;\n flex-direction: column;\n gap: 6px;\n padding: 12px;\n background: #f8f9fa;\n border-radius: 6px;\n }\n\n .metric-label {\n font-size: 11px;\n font-weight: 600;\n color: #666;\n text-transform: uppercase;\n }\n\n .metric-value {\n font-size: 18px;\n font-weight: 700;\n color: #333;\n }\n\n .empty-state,\n .no-data {\n padding: 80px 20px;\n text-align: center;\n color: #999;\n }\n\n .empty-state i,\n .no-data i {\n font-size: 64px;\n margin-bottom: 20px;\n opacity: 0.3;\n color: #2196f3;\n }\n\n .empty-state h3 {\n font-size: 20px;\n color: #666;\n margin: 0 0 12px 0;\n }\n\n .empty-state p,\n .no-data p {\n font-size: 14px;\n margin: 0;\n max-width: 500px;\n margin: 0 auto;\n line-height: 1.6;\n }\n\n @media (max-width: 1200px) {\n .metrics-overview {\n grid-template-columns: 1fr;\n }\n\n .version-selector {\n grid-template-columns: 1fr;\n }\n\n .selector-icon {\n transform: rotate(90deg);\n }\n }\n "] }]
795
+ }], () => [{ type: i1.TestingInstrumentationService }, { type: i0.ChangeDetectorRef }], { initialState: [{
796
+ type: Input
797
+ }], stateChange: [{
798
+ type: Output
799
+ }] }); })();
800
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(TestingVersionComparisonComponent, { className: "TestingVersionComparisonComponent", filePath: "src/Testing/components/testing-version-comparison.component.ts", lineNumber: 697 }); })();
801
+ //# sourceMappingURL=testing-version-comparison.component.js.map