@memberjunction/ng-dashboards 6.1.2 → 6.2.0-edge.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.
- package/dist/AI/components/vectors/vector-management-resource.component.d.ts +6 -1
- package/dist/AI/components/vectors/vector-management-resource.component.d.ts.map +1 -1
- package/dist/AI/components/vectors/vector-management-resource.component.js +99 -45
- package/dist/AI/components/vectors/vector-management-resource.component.js.map +1 -1
- package/dist/DataExplorer/components/navigation-panel/navigation-panel.component.d.ts +4 -0
- package/dist/DataExplorer/components/navigation-panel/navigation-panel.component.d.ts.map +1 -1
- package/dist/DataExplorer/components/navigation-panel/navigation-panel.component.js +16 -6
- package/dist/DataExplorer/components/navigation-panel/navigation-panel.component.js.map +1 -1
- package/dist/DataExplorer/data-explorer-dashboard.component.d.ts +4 -0
- package/dist/DataExplorer/data-explorer-dashboard.component.d.ts.map +1 -1
- package/dist/DataExplorer/data-explorer-dashboard.component.js +14 -4
- package/dist/DataExplorer/data-explorer-dashboard.component.js.map +1 -1
- package/dist/DataExplorer/services/explorer-state.service.js +2 -2
- package/dist/DataExplorer/services/explorer-state.service.js.map +1 -1
- package/dist/DevTools/graphql-console.component.d.ts.map +1 -1
- package/dist/DevTools/graphql-console.component.js +2 -0
- package/dist/DevTools/graphql-console.component.js.map +1 -1
- package/dist/Integration/components/connections/connections.component.d.ts.map +1 -1
- package/dist/Integration/components/connections/connections.component.js +2 -0
- package/dist/Integration/components/connections/connections.component.js.map +1 -1
- package/dist/KnowledgeHub/components/feature-pipelines/feature-pipelines-resource.component.d.ts +4 -12
- package/dist/KnowledgeHub/components/feature-pipelines/feature-pipelines-resource.component.d.ts.map +1 -1
- package/dist/KnowledgeHub/components/feature-pipelines/feature-pipelines-resource.component.js +39 -78
- package/dist/KnowledgeHub/components/feature-pipelines/feature-pipelines-resource.component.js.map +1 -1
- package/dist/Lists/components/lists-browse-resource.component.d.ts +3 -0
- package/dist/Lists/components/lists-browse-resource.component.d.ts.map +1 -1
- package/dist/Lists/components/lists-browse-resource.component.js +7 -6
- package/dist/Lists/components/lists-browse-resource.component.js.map +1 -1
- package/dist/Lists/components/lists-my-lists-resource.component.d.ts +3 -0
- package/dist/Lists/components/lists-my-lists-resource.component.d.ts.map +1 -1
- package/dist/Lists/components/lists-my-lists-resource.component.js +7 -6
- package/dist/Lists/components/lists-my-lists-resource.component.js.map +1 -1
- package/dist/PredictiveStudio/at-risk.view-models.d.ts +41 -3
- package/dist/PredictiveStudio/at-risk.view-models.d.ts.map +1 -1
- package/dist/PredictiveStudio/at-risk.view-models.js +99 -6
- package/dist/PredictiveStudio/at-risk.view-models.js.map +1 -1
- package/dist/PredictiveStudio/components/ps-catalog.component.d.ts +4 -1
- package/dist/PredictiveStudio/components/ps-catalog.component.d.ts.map +1 -1
- package/dist/PredictiveStudio/components/ps-catalog.component.js +61 -37
- package/dist/PredictiveStudio/components/ps-catalog.component.js.map +1 -1
- package/dist/PredictiveStudio/components/ps-experiments.component.d.ts +12 -0
- package/dist/PredictiveStudio/components/ps-experiments.component.d.ts.map +1 -1
- package/dist/PredictiveStudio/components/ps-experiments.component.js +426 -184
- package/dist/PredictiveStudio/components/ps-experiments.component.js.map +1 -1
- package/dist/PredictiveStudio/components/ps-pipeline-wizard.component.d.ts +84 -0
- package/dist/PredictiveStudio/components/ps-pipeline-wizard.component.d.ts.map +1 -0
- package/dist/PredictiveStudio/components/ps-pipeline-wizard.component.js +1397 -0
- package/dist/PredictiveStudio/components/ps-pipeline-wizard.component.js.map +1 -0
- package/dist/PredictiveStudio/components/ps-pipelines.component.d.ts +66 -34
- package/dist/PredictiveStudio/components/ps-pipelines.component.d.ts.map +1 -1
- package/dist/PredictiveStudio/components/ps-pipelines.component.js +2456 -743
- package/dist/PredictiveStudio/components/ps-pipelines.component.js.map +1 -1
- package/dist/PredictiveStudio/components/ps-predictions-grid.component.d.ts +194 -0
- package/dist/PredictiveStudio/components/ps-predictions-grid.component.d.ts.map +1 -0
- package/dist/PredictiveStudio/components/ps-predictions-grid.component.js +1902 -0
- package/dist/PredictiveStudio/components/ps-predictions-grid.component.js.map +1 -0
- package/dist/PredictiveStudio/components/ps-production.component.d.ts +17 -1
- package/dist/PredictiveStudio/components/ps-production.component.d.ts.map +1 -1
- package/dist/PredictiveStudio/components/ps-production.component.js +653 -372
- package/dist/PredictiveStudio/components/ps-production.component.js.map +1 -1
- package/dist/PredictiveStudio/components/ps-registry.component.d.ts +21 -61
- package/dist/PredictiveStudio/components/ps-registry.component.d.ts.map +1 -1
- package/dist/PredictiveStudio/components/ps-registry.component.js +214 -681
- package/dist/PredictiveStudio/components/ps-registry.component.js.map +1 -1
- package/dist/PredictiveStudio/components/ps-run-experiment-modal.component.d.ts +49 -0
- package/dist/PredictiveStudio/components/ps-run-experiment-modal.component.d.ts.map +1 -0
- package/dist/PredictiveStudio/components/ps-run-experiment-modal.component.js +658 -0
- package/dist/PredictiveStudio/components/ps-run-experiment-modal.component.js.map +1 -0
- package/dist/PredictiveStudio/predictive-studio-score-history.service.d.ts +42 -0
- package/dist/PredictiveStudio/predictive-studio-score-history.service.d.ts.map +1 -0
- package/dist/PredictiveStudio/predictive-studio-score-history.service.js +90 -0
- package/dist/PredictiveStudio/predictive-studio-score-history.service.js.map +1 -0
- package/dist/PredictiveStudio/predictive-studio.view-models.d.ts +14 -2
- package/dist/PredictiveStudio/predictive-studio.view-models.d.ts.map +1 -1
- package/dist/PredictiveStudio/predictive-studio.view-models.js +41 -5
- package/dist/PredictiveStudio/predictive-studio.view-models.js.map +1 -1
- package/dist/PredictiveStudio/resources/ps-models-resource.component.d.ts +9 -1
- package/dist/PredictiveStudio/resources/ps-models-resource.component.d.ts.map +1 -1
- package/dist/PredictiveStudio/resources/ps-models-resource.component.js +178 -65
- package/dist/PredictiveStudio/resources/ps-models-resource.component.js.map +1 -1
- package/dist/PredictiveStudio/resources/ps-predictions-resource.component.d.ts +9 -1
- package/dist/PredictiveStudio/resources/ps-predictions-resource.component.d.ts.map +1 -1
- package/dist/PredictiveStudio/resources/ps-predictions-resource.component.js +307 -369
- package/dist/PredictiveStudio/resources/ps-predictions-resource.component.js.map +1 -1
- package/dist/PredictiveStudio/resources/ps-resource-base.js +1 -1
- package/dist/PredictiveStudio/resources/ps-resource-base.js.map +1 -1
- package/dist/PredictiveStudio/resources/ps-studio-resource.component.d.ts +17 -1
- package/dist/PredictiveStudio/resources/ps-studio-resource.component.d.ts.map +1 -1
- package/dist/PredictiveStudio/resources/ps-studio-resource.component.js +309 -138
- package/dist/PredictiveStudio/resources/ps-studio-resource.component.js.map +1 -1
- package/dist/VersionHistory/components/graph-resource.component.d.ts +1 -0
- package/dist/VersionHistory/components/graph-resource.component.d.ts.map +1 -1
- package/dist/VersionHistory/components/graph-resource.component.js +6 -5
- package/dist/VersionHistory/components/graph-resource.component.js.map +1 -1
- package/dist/predictive-studio-dashboards.module.d.ts +10 -8
- package/dist/predictive-studio-dashboards.module.d.ts.map +1 -1
- package/dist/predictive-studio-dashboards.module.js +13 -3
- package/dist/predictive-studio-dashboards.module.js.map +1 -1
- package/package.json +64 -63
|
@@ -0,0 +1,1397 @@
|
|
|
1
|
+
import { ChangeDetectorRef, Component, EventEmitter, Input, Output, ViewEncapsulation, inject, } from '@angular/core';
|
|
2
|
+
import { CommonModule } from '@angular/common';
|
|
3
|
+
import { FormsModule } from '@angular/forms';
|
|
4
|
+
import { UUIDsEqual } from '@memberjunction/global';
|
|
5
|
+
import { MJButtonDirective } from '@memberjunction/ng-ui-components';
|
|
6
|
+
import { MJNotificationService } from '@memberjunction/ng-notifications';
|
|
7
|
+
import { Metadata } from '@memberjunction/core';
|
|
8
|
+
import { DOMINANCE_THRESHOLD_DEFAULT, } from '@memberjunction/predictive-studio-core';
|
|
9
|
+
import * as i0 from "@angular/core";
|
|
10
|
+
import * as i1 from "@angular/forms";
|
|
11
|
+
import * as i2 from "@angular/common";
|
|
12
|
+
const _forTrack0 = ($index, $item) => $item.ID;
|
|
13
|
+
const _forTrack1 = ($index, $item) => $item.Name;
|
|
14
|
+
const _forTrack2 = ($index, $item) => $item.field.Name;
|
|
15
|
+
function PSPipelineWizardComponent_Conditional_37_For_21_Template(rf, ctx) { if (rf & 1) {
|
|
16
|
+
i0.ɵɵelementStart(0, "option", 33);
|
|
17
|
+
i0.ɵɵtext(1);
|
|
18
|
+
i0.ɵɵelementEnd();
|
|
19
|
+
} if (rf & 2) {
|
|
20
|
+
const ent_r3 = ctx.$implicit;
|
|
21
|
+
i0.ɵɵproperty("value", ent_r3.ID);
|
|
22
|
+
i0.ɵɵadvance();
|
|
23
|
+
i0.ɵɵtextInterpolate2("", ent_r3.Name, " (", ent_r3.BaseView || ent_r3.BaseTable, ")");
|
|
24
|
+
} }
|
|
25
|
+
function PSPipelineWizardComponent_Conditional_37_For_31_Template(rf, ctx) { if (rf & 1) {
|
|
26
|
+
i0.ɵɵelementStart(0, "option", 33);
|
|
27
|
+
i0.ɵɵtext(1);
|
|
28
|
+
i0.ɵɵelementEnd();
|
|
29
|
+
} if (rf & 2) {
|
|
30
|
+
const f_r4 = ctx.$implicit;
|
|
31
|
+
i0.ɵɵproperty("value", f_r4.Name);
|
|
32
|
+
i0.ɵɵadvance();
|
|
33
|
+
i0.ɵɵtextInterpolate2("", f_r4.Name, " (", f_r4.Type, ")");
|
|
34
|
+
} }
|
|
35
|
+
function PSPipelineWizardComponent_Conditional_37_For_46_Template(rf, ctx) { if (rf & 1) {
|
|
36
|
+
i0.ɵɵelementStart(0, "option", 33);
|
|
37
|
+
i0.ɵɵtext(1);
|
|
38
|
+
i0.ɵɵelementEnd();
|
|
39
|
+
} if (rf & 2) {
|
|
40
|
+
const m_r5 = ctx.$implicit;
|
|
41
|
+
i0.ɵɵproperty("value", m_r5);
|
|
42
|
+
i0.ɵɵadvance();
|
|
43
|
+
i0.ɵɵtextInterpolate(m_r5);
|
|
44
|
+
} }
|
|
45
|
+
function PSPipelineWizardComponent_Conditional_37_Conditional_64_For_7_Template(rf, ctx) { if (rf & 1) {
|
|
46
|
+
i0.ɵɵelementStart(0, "option", 33);
|
|
47
|
+
i0.ɵɵtext(1);
|
|
48
|
+
i0.ɵɵelementEnd();
|
|
49
|
+
} if (rf & 2) {
|
|
50
|
+
const f_r7 = ctx.$implicit;
|
|
51
|
+
i0.ɵɵproperty("value", f_r7.Name);
|
|
52
|
+
i0.ɵɵadvance();
|
|
53
|
+
i0.ɵɵtextInterpolate(f_r7.Name);
|
|
54
|
+
} }
|
|
55
|
+
function PSPipelineWizardComponent_Conditional_37_Conditional_64_Template(rf, ctx) { if (rf & 1) {
|
|
56
|
+
const _r6 = i0.ɵɵgetCurrentView();
|
|
57
|
+
i0.ɵɵelementStart(0, "div", 23)(1, "label");
|
|
58
|
+
i0.ɵɵtext(2, "Decision Date Field");
|
|
59
|
+
i0.ɵɵelementEnd();
|
|
60
|
+
i0.ɵɵelementStart(3, "select", 46);
|
|
61
|
+
i0.ɵɵtwoWayListener("ngModelChange", function PSPipelineWizardComponent_Conditional_37_Conditional_64_Template_select_ngModelChange_3_listener($event) { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r1.asOfColumn, $event) || (ctx_r1.asOfColumn = $event); return i0.ɵɵresetView($event); });
|
|
62
|
+
i0.ɵɵelementStart(4, "option", 33);
|
|
63
|
+
i0.ɵɵtext(5, "-- Select Date Field --");
|
|
64
|
+
i0.ɵɵelementEnd();
|
|
65
|
+
i0.ɵɵrepeaterCreate(6, PSPipelineWizardComponent_Conditional_37_Conditional_64_For_7_Template, 2, 2, "option", 33, _forTrack1);
|
|
66
|
+
i0.ɵɵelementEnd()();
|
|
67
|
+
} if (rf & 2) {
|
|
68
|
+
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
69
|
+
i0.ɵɵadvance(3);
|
|
70
|
+
i0.ɵɵtwoWayProperty("ngModel", ctx_r1.asOfColumn);
|
|
71
|
+
i0.ɵɵadvance();
|
|
72
|
+
i0.ɵɵproperty("value", "");
|
|
73
|
+
i0.ɵɵadvance(2);
|
|
74
|
+
i0.ɵɵrepeater(ctx_r1.dateFields);
|
|
75
|
+
} }
|
|
76
|
+
function PSPipelineWizardComponent_Conditional_37_Conditional_65_Template(rf, ctx) { if (rf & 1) {
|
|
77
|
+
const _r8 = i0.ɵɵgetCurrentView();
|
|
78
|
+
i0.ɵɵelementStart(0, "div", 23)(1, "label");
|
|
79
|
+
i0.ɵɵtext(2, "Offset Days before Outcome");
|
|
80
|
+
i0.ɵɵelementEnd();
|
|
81
|
+
i0.ɵɵelementStart(3, "input", 50);
|
|
82
|
+
i0.ɵɵtwoWayListener("ngModelChange", function PSPipelineWizardComponent_Conditional_37_Conditional_65_Template_input_ngModelChange_3_listener($event) { i0.ɵɵrestoreView(_r8); const ctx_r1 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r1.asOfOffsetDays, $event) || (ctx_r1.asOfOffsetDays = $event); return i0.ɵɵresetView($event); });
|
|
83
|
+
i0.ɵɵelementEnd()();
|
|
84
|
+
} if (rf & 2) {
|
|
85
|
+
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
86
|
+
i0.ɵɵadvance(3);
|
|
87
|
+
i0.ɵɵtwoWayProperty("ngModel", ctx_r1.asOfOffsetDays);
|
|
88
|
+
} }
|
|
89
|
+
function PSPipelineWizardComponent_Conditional_37_Template(rf, ctx) { if (rf & 1) {
|
|
90
|
+
const _r1 = i0.ɵɵgetCurrentView();
|
|
91
|
+
i0.ɵɵelementStart(0, "div", 14)(1, "div", 23)(2, "label", 24);
|
|
92
|
+
i0.ɵɵtext(3, "Pipeline Name ");
|
|
93
|
+
i0.ɵɵelementStart(4, "span", 25);
|
|
94
|
+
i0.ɵɵtext(5, "*");
|
|
95
|
+
i0.ɵɵelementEnd()();
|
|
96
|
+
i0.ɵɵelementStart(6, "input", 26);
|
|
97
|
+
i0.ɵɵtwoWayListener("ngModelChange", function PSPipelineWizardComponent_Conditional_37_Template_input_ngModelChange_6_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.pipelineName, $event) || (ctx_r1.pipelineName = $event); return i0.ɵɵresetView($event); });
|
|
98
|
+
i0.ɵɵelementEnd()();
|
|
99
|
+
i0.ɵɵelementStart(7, "div", 23)(8, "label", 27);
|
|
100
|
+
i0.ɵɵtext(9, "Description");
|
|
101
|
+
i0.ɵɵelementEnd();
|
|
102
|
+
i0.ɵɵelementStart(10, "textarea", 28);
|
|
103
|
+
i0.ɵɵtwoWayListener("ngModelChange", function PSPipelineWizardComponent_Conditional_37_Template_textarea_ngModelChange_10_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.pipelineDescription, $event) || (ctx_r1.pipelineDescription = $event); return i0.ɵɵresetView($event); });
|
|
104
|
+
i0.ɵɵelementEnd()();
|
|
105
|
+
i0.ɵɵelementStart(11, "div", 29)(12, "div", 23)(13, "label", 30);
|
|
106
|
+
i0.ɵɵtext(14, "Target Entity ");
|
|
107
|
+
i0.ɵɵelementStart(15, "span", 25);
|
|
108
|
+
i0.ɵɵtext(16, "*");
|
|
109
|
+
i0.ɵɵelementEnd()();
|
|
110
|
+
i0.ɵɵelementStart(17, "select", 31);
|
|
111
|
+
i0.ɵɵlistener("ngModelChange", function PSPipelineWizardComponent_Conditional_37_Template_select_ngModelChange_17_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onEntitySelected($event)); });
|
|
112
|
+
i0.ɵɵelementStart(18, "option", 32);
|
|
113
|
+
i0.ɵɵtext(19, "-- Select Entity --");
|
|
114
|
+
i0.ɵɵelementEnd();
|
|
115
|
+
i0.ɵɵrepeaterCreate(20, PSPipelineWizardComponent_Conditional_37_For_21_Template, 2, 3, "option", 33, _forTrack0);
|
|
116
|
+
i0.ɵɵelementEnd()();
|
|
117
|
+
i0.ɵɵelementStart(22, "div", 23)(23, "label", 34);
|
|
118
|
+
i0.ɵɵtext(24, "Target Variable (Label Column) ");
|
|
119
|
+
i0.ɵɵelementStart(25, "span", 25);
|
|
120
|
+
i0.ɵɵtext(26, "*");
|
|
121
|
+
i0.ɵɵelementEnd()();
|
|
122
|
+
i0.ɵɵelementStart(27, "select", 35);
|
|
123
|
+
i0.ɵɵtwoWayListener("ngModelChange", function PSPipelineWizardComponent_Conditional_37_Template_select_ngModelChange_27_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.targetVariable, $event) || (ctx_r1.targetVariable = $event); return i0.ɵɵresetView($event); });
|
|
124
|
+
i0.ɵɵelementStart(28, "option", 32);
|
|
125
|
+
i0.ɵɵtext(29, "-- Select Label Field --");
|
|
126
|
+
i0.ɵɵelementEnd();
|
|
127
|
+
i0.ɵɵrepeaterCreate(30, PSPipelineWizardComponent_Conditional_37_For_31_Template, 2, 3, "option", 33, _forTrack1);
|
|
128
|
+
i0.ɵɵelementEnd()()();
|
|
129
|
+
i0.ɵɵelementStart(32, "div", 29)(33, "div", 23)(34, "label", 36);
|
|
130
|
+
i0.ɵɵtext(35, "Problem Type");
|
|
131
|
+
i0.ɵɵelementEnd();
|
|
132
|
+
i0.ɵɵelementStart(36, "select", 37);
|
|
133
|
+
i0.ɵɵtwoWayListener("ngModelChange", function PSPipelineWizardComponent_Conditional_37_Template_select_ngModelChange_36_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.problemType, $event) || (ctx_r1.problemType = $event); return i0.ɵɵresetView($event); });
|
|
134
|
+
i0.ɵɵlistener("ngModelChange", function PSPipelineWizardComponent_Conditional_37_Template_select_ngModelChange_36_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onProblemTypeChange()); });
|
|
135
|
+
i0.ɵɵelementStart(37, "option", 38);
|
|
136
|
+
i0.ɵɵtext(38, "Classification (Predict Categorical / Binary Outcome)");
|
|
137
|
+
i0.ɵɵelementEnd();
|
|
138
|
+
i0.ɵɵelementStart(39, "option", 39);
|
|
139
|
+
i0.ɵɵtext(40, "Regression (Predict Numeric Continuous Value)");
|
|
140
|
+
i0.ɵɵelementEnd()()();
|
|
141
|
+
i0.ɵɵelementStart(41, "div", 23)(42, "label", 40);
|
|
142
|
+
i0.ɵɵtext(43, "Primary Evaluation Metric");
|
|
143
|
+
i0.ɵɵelementEnd();
|
|
144
|
+
i0.ɵɵelementStart(44, "select", 41);
|
|
145
|
+
i0.ɵɵtwoWayListener("ngModelChange", function PSPipelineWizardComponent_Conditional_37_Template_select_ngModelChange_44_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.evaluationMetric, $event) || (ctx_r1.evaluationMetric = $event); return i0.ɵɵresetView($event); });
|
|
146
|
+
i0.ɵɵrepeaterCreate(45, PSPipelineWizardComponent_Conditional_37_For_46_Template, 2, 2, "option", 33, i0.ɵɵrepeaterTrackByIdentity);
|
|
147
|
+
i0.ɵɵelementEnd()()();
|
|
148
|
+
i0.ɵɵelementStart(47, "div", 42)(48, "div", 43);
|
|
149
|
+
i0.ɵɵelement(49, "i", 44);
|
|
150
|
+
i0.ɵɵelementStart(50, "h4");
|
|
151
|
+
i0.ɵɵtext(51, "Point-in-Time Cutoff (Temporal Leakage Guard)");
|
|
152
|
+
i0.ɵɵelementEnd()();
|
|
153
|
+
i0.ɵɵelementStart(52, "div", 45)(53, "div", 29)(54, "div", 23)(55, "label");
|
|
154
|
+
i0.ɵɵtext(56, "Cutoff Mode");
|
|
155
|
+
i0.ɵɵelementEnd();
|
|
156
|
+
i0.ɵɵelementStart(57, "select", 46);
|
|
157
|
+
i0.ɵɵtwoWayListener("ngModelChange", function PSPipelineWizardComponent_Conditional_37_Template_select_ngModelChange_57_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.asOfMode, $event) || (ctx_r1.asOfMode = $event); return i0.ɵɵresetView($event); });
|
|
158
|
+
i0.ɵɵelementStart(58, "option", 47);
|
|
159
|
+
i0.ɵɵtext(59, "None (Static Cross-Sectional Data)");
|
|
160
|
+
i0.ɵɵelementEnd();
|
|
161
|
+
i0.ɵɵelementStart(60, "option", 48);
|
|
162
|
+
i0.ɵɵtext(61, "Date Column on Entity");
|
|
163
|
+
i0.ɵɵelementEnd();
|
|
164
|
+
i0.ɵɵelementStart(62, "option", 49);
|
|
165
|
+
i0.ɵɵtext(63, "Relative Days Offset before Event");
|
|
166
|
+
i0.ɵɵelementEnd()()();
|
|
167
|
+
i0.ɵɵconditionalCreate(64, PSPipelineWizardComponent_Conditional_37_Conditional_64_Template, 8, 2, "div", 23);
|
|
168
|
+
i0.ɵɵconditionalCreate(65, PSPipelineWizardComponent_Conditional_37_Conditional_65_Template, 4, 1, "div", 23);
|
|
169
|
+
i0.ɵɵelementEnd()()()();
|
|
170
|
+
} if (rf & 2) {
|
|
171
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
172
|
+
i0.ɵɵadvance(6);
|
|
173
|
+
i0.ɵɵtwoWayProperty("ngModel", ctx_r1.pipelineName);
|
|
174
|
+
i0.ɵɵadvance(4);
|
|
175
|
+
i0.ɵɵtwoWayProperty("ngModel", ctx_r1.pipelineDescription);
|
|
176
|
+
i0.ɵɵadvance(7);
|
|
177
|
+
i0.ɵɵproperty("ngModel", ctx_r1.selectedEntityId);
|
|
178
|
+
i0.ɵɵadvance();
|
|
179
|
+
i0.ɵɵproperty("value", "");
|
|
180
|
+
i0.ɵɵadvance(2);
|
|
181
|
+
i0.ɵɵrepeater(ctx_r1.availableEntities);
|
|
182
|
+
i0.ɵɵadvance(7);
|
|
183
|
+
i0.ɵɵtwoWayProperty("ngModel", ctx_r1.targetVariable);
|
|
184
|
+
i0.ɵɵproperty("disabled", !ctx_r1.selectedEntity);
|
|
185
|
+
i0.ɵɵadvance();
|
|
186
|
+
i0.ɵɵproperty("value", "");
|
|
187
|
+
i0.ɵɵadvance(2);
|
|
188
|
+
i0.ɵɵrepeater(ctx_r1.availableFields);
|
|
189
|
+
i0.ɵɵadvance(6);
|
|
190
|
+
i0.ɵɵtwoWayProperty("ngModel", ctx_r1.problemType);
|
|
191
|
+
i0.ɵɵadvance(8);
|
|
192
|
+
i0.ɵɵtwoWayProperty("ngModel", ctx_r1.evaluationMetric);
|
|
193
|
+
i0.ɵɵadvance();
|
|
194
|
+
i0.ɵɵrepeater(ctx_r1.availableMetrics);
|
|
195
|
+
i0.ɵɵadvance(12);
|
|
196
|
+
i0.ɵɵtwoWayProperty("ngModel", ctx_r1.asOfMode);
|
|
197
|
+
i0.ɵɵadvance(7);
|
|
198
|
+
i0.ɵɵconditional(ctx_r1.asOfMode === "column" ? 64 : -1);
|
|
199
|
+
i0.ɵɵadvance();
|
|
200
|
+
i0.ɵɵconditional(ctx_r1.asOfMode === "offset" ? 65 : -1);
|
|
201
|
+
} }
|
|
202
|
+
function PSPipelineWizardComponent_Conditional_38_For_39_Conditional_6_Template(rf, ctx) { if (rf & 1) {
|
|
203
|
+
i0.ɵɵelementStart(0, "span", 68);
|
|
204
|
+
i0.ɵɵtext(1, "Target Label");
|
|
205
|
+
i0.ɵɵelementEnd();
|
|
206
|
+
} }
|
|
207
|
+
function PSPipelineWizardComponent_Conditional_38_For_39_Conditional_13_Template(rf, ctx) { if (rf & 1) {
|
|
208
|
+
const _r12 = i0.ɵɵgetCurrentView();
|
|
209
|
+
i0.ɵɵelementStart(0, "button", 71);
|
|
210
|
+
i0.ɵɵlistener("click", function PSPipelineWizardComponent_Conditional_38_For_39_Conditional_13_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r12); const item_r11 = i0.ɵɵnextContext().$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.toggleDenyList(item_r11)); });
|
|
211
|
+
i0.ɵɵelement(1, "i", 72);
|
|
212
|
+
i0.ɵɵtext(2);
|
|
213
|
+
i0.ɵɵelementEnd();
|
|
214
|
+
} if (rf & 2) {
|
|
215
|
+
const item_r11 = i0.ɵɵnextContext().$implicit;
|
|
216
|
+
i0.ɵɵclassProp("denied", item_r11.isDenyList);
|
|
217
|
+
i0.ɵɵadvance();
|
|
218
|
+
i0.ɵɵclassProp("fa-shield-halved", item_r11.isDenyList)("fa-shield", !item_r11.isDenyList);
|
|
219
|
+
i0.ɵɵadvance();
|
|
220
|
+
i0.ɵɵtextInterpolate1(" ", item_r11.isDenyList ? "Denied" : "Allow", " ");
|
|
221
|
+
} }
|
|
222
|
+
function PSPipelineWizardComponent_Conditional_38_For_39_Template(rf, ctx) { if (rf & 1) {
|
|
223
|
+
const _r10 = i0.ɵɵgetCurrentView();
|
|
224
|
+
i0.ɵɵelementStart(0, "tr")(1, "td")(2, "input", 67);
|
|
225
|
+
i0.ɵɵtwoWayListener("ngModelChange", function PSPipelineWizardComponent_Conditional_38_For_39_Template_input_ngModelChange_2_listener($event) { const item_r11 = i0.ɵɵrestoreView(_r10).$implicit; i0.ɵɵtwoWayBindingSet(item_r11.selected, $event) || (item_r11.selected = $event); return i0.ɵɵresetView($event); });
|
|
226
|
+
i0.ɵɵelementEnd()();
|
|
227
|
+
i0.ɵɵelementStart(3, "td")(4, "strong");
|
|
228
|
+
i0.ɵɵtext(5);
|
|
229
|
+
i0.ɵɵelementEnd();
|
|
230
|
+
i0.ɵɵconditionalCreate(6, PSPipelineWizardComponent_Conditional_38_For_39_Conditional_6_Template, 2, 0, "span", 68);
|
|
231
|
+
i0.ɵɵelementEnd();
|
|
232
|
+
i0.ɵɵelementStart(7, "td")(8, "code");
|
|
233
|
+
i0.ɵɵtext(9);
|
|
234
|
+
i0.ɵɵelementEnd()();
|
|
235
|
+
i0.ɵɵelementStart(10, "td");
|
|
236
|
+
i0.ɵɵtext(11);
|
|
237
|
+
i0.ɵɵelementEnd();
|
|
238
|
+
i0.ɵɵelementStart(12, "td", 69);
|
|
239
|
+
i0.ɵɵconditionalCreate(13, PSPipelineWizardComponent_Conditional_38_For_39_Conditional_13_Template, 3, 7, "button", 70);
|
|
240
|
+
i0.ɵɵelementEnd()();
|
|
241
|
+
} if (rf & 2) {
|
|
242
|
+
const item_r11 = ctx.$implicit;
|
|
243
|
+
i0.ɵɵclassProp("target-row", item_r11.isTarget)("deny-row", item_r11.isDenyList);
|
|
244
|
+
i0.ɵɵadvance(2);
|
|
245
|
+
i0.ɵɵtwoWayProperty("ngModel", item_r11.selected);
|
|
246
|
+
i0.ɵɵproperty("disabled", item_r11.isTarget || item_r11.isDenyList);
|
|
247
|
+
i0.ɵɵadvance(3);
|
|
248
|
+
i0.ɵɵtextInterpolate(item_r11.field.Name);
|
|
249
|
+
i0.ɵɵadvance();
|
|
250
|
+
i0.ɵɵconditional(item_r11.isTarget ? 6 : -1);
|
|
251
|
+
i0.ɵɵadvance(3);
|
|
252
|
+
i0.ɵɵtextInterpolate(item_r11.field.Type);
|
|
253
|
+
i0.ɵɵadvance(2);
|
|
254
|
+
i0.ɵɵtextInterpolate(item_r11.field.AllowsNull ? "Yes" : "No");
|
|
255
|
+
i0.ɵɵadvance(2);
|
|
256
|
+
i0.ɵɵconditional(!item_r11.isTarget ? 13 : -1);
|
|
257
|
+
} }
|
|
258
|
+
function PSPipelineWizardComponent_Conditional_38_Template(rf, ctx) { if (rf & 1) {
|
|
259
|
+
const _r9 = i0.ɵɵgetCurrentView();
|
|
260
|
+
i0.ɵɵelementStart(0, "div", 15)(1, "div", 51)(2, "div", 52);
|
|
261
|
+
i0.ɵɵelement(3, "i", 53);
|
|
262
|
+
i0.ɵɵelementStart(4, "input", 54);
|
|
263
|
+
i0.ɵɵtwoWayListener("ngModelChange", function PSPipelineWizardComponent_Conditional_38_Template_input_ngModelChange_4_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.fieldSearchFilter, $event) || (ctx_r1.fieldSearchFilter = $event); return i0.ɵɵresetView($event); });
|
|
264
|
+
i0.ɵɵelementEnd()();
|
|
265
|
+
i0.ɵɵelementStart(5, "div", 55)(6, "button", 19);
|
|
266
|
+
i0.ɵɵlistener("click", function PSPipelineWizardComponent_Conditional_38_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.selectAllFields(true)); });
|
|
267
|
+
i0.ɵɵtext(7, "Select All");
|
|
268
|
+
i0.ɵɵelementEnd();
|
|
269
|
+
i0.ɵɵelementStart(8, "button", 19);
|
|
270
|
+
i0.ɵɵlistener("click", function PSPipelineWizardComponent_Conditional_38_Template_button_click_8_listener() { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.selectAllFields(false)); });
|
|
271
|
+
i0.ɵɵtext(9, "Deselect All");
|
|
272
|
+
i0.ɵɵelementEnd();
|
|
273
|
+
i0.ɵɵelementStart(10, "button", 19);
|
|
274
|
+
i0.ɵɵlistener("click", function PSPipelineWizardComponent_Conditional_38_Template_button_click_10_listener() { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.excludeAuditFields()); });
|
|
275
|
+
i0.ɵɵtext(11, "Exclude IDs & Timestamps");
|
|
276
|
+
i0.ɵɵelementEnd()()();
|
|
277
|
+
i0.ɵɵelementStart(12, "div", 56)(13, "span");
|
|
278
|
+
i0.ɵɵtext(14, "Selected: ");
|
|
279
|
+
i0.ɵɵelementStart(15, "strong");
|
|
280
|
+
i0.ɵɵtext(16);
|
|
281
|
+
i0.ɵɵelementEnd();
|
|
282
|
+
i0.ɵɵtext(17, " features");
|
|
283
|
+
i0.ɵɵelementEnd();
|
|
284
|
+
i0.ɵɵelementStart(18, "span");
|
|
285
|
+
i0.ɵɵtext(19, "Leakage Deny-List: ");
|
|
286
|
+
i0.ɵɵelementStart(20, "strong", 57);
|
|
287
|
+
i0.ɵɵtext(21);
|
|
288
|
+
i0.ɵɵelementEnd();
|
|
289
|
+
i0.ɵɵtext(22, " excluded fields");
|
|
290
|
+
i0.ɵɵelementEnd()();
|
|
291
|
+
i0.ɵɵelementStart(23, "div", 58)(24, "table", 59)(25, "thead")(26, "tr")(27, "th", 60);
|
|
292
|
+
i0.ɵɵtext(28, "Use");
|
|
293
|
+
i0.ɵɵelementEnd();
|
|
294
|
+
i0.ɵɵelementStart(29, "th");
|
|
295
|
+
i0.ɵɵtext(30, "Field Name");
|
|
296
|
+
i0.ɵɵelementEnd();
|
|
297
|
+
i0.ɵɵelementStart(31, "th");
|
|
298
|
+
i0.ɵɵtext(32, "Data Type");
|
|
299
|
+
i0.ɵɵelementEnd();
|
|
300
|
+
i0.ɵɵelementStart(33, "th");
|
|
301
|
+
i0.ɵɵtext(34, "Nullable");
|
|
302
|
+
i0.ɵɵelementEnd();
|
|
303
|
+
i0.ɵɵelementStart(35, "th", 61);
|
|
304
|
+
i0.ɵɵtext(36, "Leakage Guard");
|
|
305
|
+
i0.ɵɵelementEnd()()();
|
|
306
|
+
i0.ɵɵelementStart(37, "tbody");
|
|
307
|
+
i0.ɵɵrepeaterCreate(38, PSPipelineWizardComponent_Conditional_38_For_39_Template, 14, 11, "tr", 62, _forTrack2);
|
|
308
|
+
i0.ɵɵelementEnd()()();
|
|
309
|
+
i0.ɵɵelementStart(40, "div", 63)(41, "label");
|
|
310
|
+
i0.ɵɵtext(42, "Single-Feature Dominance Threshold: ");
|
|
311
|
+
i0.ɵɵelementStart(43, "strong");
|
|
312
|
+
i0.ɵɵtext(44);
|
|
313
|
+
i0.ɵɵpipe(45, "percent");
|
|
314
|
+
i0.ɵɵelementEnd()();
|
|
315
|
+
i0.ɵɵelementStart(46, "div", 64)(47, "input", 65);
|
|
316
|
+
i0.ɵɵtwoWayListener("ngModelChange", function PSPipelineWizardComponent_Conditional_38_Template_input_ngModelChange_47_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.dominanceThreshold, $event) || (ctx_r1.dominanceThreshold = $event); return i0.ɵɵresetView($event); });
|
|
317
|
+
i0.ɵɵelementEnd();
|
|
318
|
+
i0.ɵɵelementStart(48, "span", 66);
|
|
319
|
+
i0.ɵɵtext(49);
|
|
320
|
+
i0.ɵɵpipe(50, "percent");
|
|
321
|
+
i0.ɵɵelementEnd()()()();
|
|
322
|
+
} if (rf & 2) {
|
|
323
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
324
|
+
i0.ɵɵadvance(4);
|
|
325
|
+
i0.ɵɵtwoWayProperty("ngModel", ctx_r1.fieldSearchFilter);
|
|
326
|
+
i0.ɵɵadvance(12);
|
|
327
|
+
i0.ɵɵtextInterpolate(ctx_r1.selectedFeaturesCount);
|
|
328
|
+
i0.ɵɵadvance(5);
|
|
329
|
+
i0.ɵɵtextInterpolate(ctx_r1.denyListCount);
|
|
330
|
+
i0.ɵɵadvance(17);
|
|
331
|
+
i0.ɵɵrepeater(ctx_r1.filteredFieldItems);
|
|
332
|
+
i0.ɵɵadvance(6);
|
|
333
|
+
i0.ɵɵtextInterpolate(i0.ɵɵpipeBind1(45, 6, ctx_r1.dominanceThreshold));
|
|
334
|
+
i0.ɵɵadvance(3);
|
|
335
|
+
i0.ɵɵtwoWayProperty("ngModel", ctx_r1.dominanceThreshold);
|
|
336
|
+
i0.ɵɵadvance(2);
|
|
337
|
+
i0.ɵɵtextInterpolate1("Warns and holds model if any single feature accounts for > ", i0.ɵɵpipeBind1(50, 8, ctx_r1.dominanceThreshold), " of total importance.");
|
|
338
|
+
} }
|
|
339
|
+
function PSPipelineWizardComponent_Conditional_39_Template(rf, ctx) { if (rf & 1) {
|
|
340
|
+
const _r13 = i0.ɵɵgetCurrentView();
|
|
341
|
+
i0.ɵɵelementStart(0, "div", 16)(1, "div", 73)(2, "div", 74);
|
|
342
|
+
i0.ɵɵelement(3, "i", 75);
|
|
343
|
+
i0.ɵɵelementEnd();
|
|
344
|
+
i0.ɵɵelementStart(4, "div", 76)(5, "h4");
|
|
345
|
+
i0.ɵɵtext(6, "Categorical Encoding");
|
|
346
|
+
i0.ɵɵelementEnd();
|
|
347
|
+
i0.ɵɵelementStart(7, "p", 77);
|
|
348
|
+
i0.ɵɵtext(8, "Converts text and discrete categoricals into numerical representations.");
|
|
349
|
+
i0.ɵɵelementEnd();
|
|
350
|
+
i0.ɵɵelementStart(9, "select", 46);
|
|
351
|
+
i0.ɵɵtwoWayListener("ngModelChange", function PSPipelineWizardComponent_Conditional_39_Template_select_ngModelChange_9_listener($event) { i0.ɵɵrestoreView(_r13); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.categoricalEncoding, $event) || (ctx_r1.categoricalEncoding = $event); return i0.ɵɵresetView($event); });
|
|
352
|
+
i0.ɵɵelementStart(10, "option", 78);
|
|
353
|
+
i0.ɵɵtext(11, "One-Hot Encoding (Recommended for cardinality < 50)");
|
|
354
|
+
i0.ɵɵelementEnd();
|
|
355
|
+
i0.ɵɵelementStart(12, "option", 47);
|
|
356
|
+
i0.ɵɵtext(13, "Pass-Through / Native Algorithm Handling");
|
|
357
|
+
i0.ɵɵelementEnd()()()();
|
|
358
|
+
i0.ɵɵelementStart(14, "div", 73)(15, "div", 74);
|
|
359
|
+
i0.ɵɵelement(16, "i", 79);
|
|
360
|
+
i0.ɵɵelementEnd();
|
|
361
|
+
i0.ɵɵelementStart(17, "div", 76)(18, "h4");
|
|
362
|
+
i0.ɵɵtext(19, "Missing Value Imputation");
|
|
363
|
+
i0.ɵɵelementEnd();
|
|
364
|
+
i0.ɵɵelementStart(20, "p", 77);
|
|
365
|
+
i0.ɵɵtext(21, "Strategy for filling null or missing entries in training matrices.");
|
|
366
|
+
i0.ɵɵelementEnd();
|
|
367
|
+
i0.ɵɵelementStart(22, "select", 46);
|
|
368
|
+
i0.ɵɵtwoWayListener("ngModelChange", function PSPipelineWizardComponent_Conditional_39_Template_select_ngModelChange_22_listener($event) { i0.ɵɵrestoreView(_r13); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.imputeStrategy, $event) || (ctx_r1.imputeStrategy = $event); return i0.ɵɵresetView($event); });
|
|
369
|
+
i0.ɵɵelementStart(23, "option", 80);
|
|
370
|
+
i0.ɵɵtext(24, "Median (Robust against numeric outliers)");
|
|
371
|
+
i0.ɵɵelementEnd();
|
|
372
|
+
i0.ɵɵelementStart(25, "option", 81);
|
|
373
|
+
i0.ɵɵtext(26, "Mean (Standard arithmetic average)");
|
|
374
|
+
i0.ɵɵelementEnd();
|
|
375
|
+
i0.ɵɵelementStart(27, "option", 82);
|
|
376
|
+
i0.ɵɵtext(28, "Mode (Most frequent category)");
|
|
377
|
+
i0.ɵɵelementEnd();
|
|
378
|
+
i0.ɵɵelementStart(29, "option", 83);
|
|
379
|
+
i0.ɵɵtext(30, "Constant (Zero / Missing category token)");
|
|
380
|
+
i0.ɵɵelementEnd()()()();
|
|
381
|
+
i0.ɵɵelementStart(31, "div", 73)(32, "div", 74);
|
|
382
|
+
i0.ɵɵelement(33, "i", 84);
|
|
383
|
+
i0.ɵɵelementEnd();
|
|
384
|
+
i0.ɵɵelementStart(34, "div", 76)(35, "h4");
|
|
385
|
+
i0.ɵɵtext(36, "Numeric Standardization");
|
|
386
|
+
i0.ɵɵelementEnd();
|
|
387
|
+
i0.ɵɵelementStart(37, "p", 77);
|
|
388
|
+
i0.ɵɵtext(38, "Scales numeric features to prevent large magnitudes from dominating.");
|
|
389
|
+
i0.ɵɵelementEnd();
|
|
390
|
+
i0.ɵɵelementStart(39, "select", 46);
|
|
391
|
+
i0.ɵɵtwoWayListener("ngModelChange", function PSPipelineWizardComponent_Conditional_39_Template_select_ngModelChange_39_listener($event) { i0.ɵɵrestoreView(_r13); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.standardizeStrategy, $event) || (ctx_r1.standardizeStrategy = $event); return i0.ɵɵresetView($event); });
|
|
392
|
+
i0.ɵɵelementStart(40, "option", 85);
|
|
393
|
+
i0.ɵɵtext(41, "Standard Scaling (Z-score: mean 0, variance 1)");
|
|
394
|
+
i0.ɵɵelementEnd();
|
|
395
|
+
i0.ɵɵelementStart(42, "option", 86);
|
|
396
|
+
i0.ɵɵtext(43, "Min-Max Scaling (Bounding values to [0, 1])");
|
|
397
|
+
i0.ɵɵelementEnd();
|
|
398
|
+
i0.ɵɵelementStart(44, "option", 47);
|
|
399
|
+
i0.ɵɵtext(45, "None (Native tree-based scaling)");
|
|
400
|
+
i0.ɵɵelementEnd()()()()();
|
|
401
|
+
} if (rf & 2) {
|
|
402
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
403
|
+
i0.ɵɵadvance(9);
|
|
404
|
+
i0.ɵɵtwoWayProperty("ngModel", ctx_r1.categoricalEncoding);
|
|
405
|
+
i0.ɵɵadvance(13);
|
|
406
|
+
i0.ɵɵtwoWayProperty("ngModel", ctx_r1.imputeStrategy);
|
|
407
|
+
i0.ɵɵadvance(17);
|
|
408
|
+
i0.ɵɵtwoWayProperty("ngModel", ctx_r1.standardizeStrategy);
|
|
409
|
+
} }
|
|
410
|
+
function PSPipelineWizardComponent_Conditional_40_For_8_Template(rf, ctx) { if (rf & 1) {
|
|
411
|
+
i0.ɵɵelementStart(0, "option", 33);
|
|
412
|
+
i0.ɵɵtext(1);
|
|
413
|
+
i0.ɵɵelementEnd();
|
|
414
|
+
} if (rf & 2) {
|
|
415
|
+
const a_r15 = ctx.$implicit;
|
|
416
|
+
i0.ɵɵproperty("value", a_r15.ID);
|
|
417
|
+
i0.ɵɵadvance();
|
|
418
|
+
i0.ɵɵtextInterpolate2("", a_r15.Name, " (", a_r15.DriverClass, ")");
|
|
419
|
+
} }
|
|
420
|
+
function PSPipelineWizardComponent_Conditional_40_Conditional_43_Template(rf, ctx) { if (rf & 1) {
|
|
421
|
+
const _r16 = i0.ɵɵgetCurrentView();
|
|
422
|
+
i0.ɵɵelementStart(0, "div", 23)(1, "label");
|
|
423
|
+
i0.ɵɵtext(2, "Test Holdout Percentage: ");
|
|
424
|
+
i0.ɵɵelementStart(3, "strong");
|
|
425
|
+
i0.ɵɵtext(4);
|
|
426
|
+
i0.ɵɵpipe(5, "percent");
|
|
427
|
+
i0.ɵɵelementEnd()();
|
|
428
|
+
i0.ɵɵelementStart(6, "input", 99);
|
|
429
|
+
i0.ɵɵtwoWayListener("ngModelChange", function PSPipelineWizardComponent_Conditional_40_Conditional_43_Template_input_ngModelChange_6_listener($event) { i0.ɵɵrestoreView(_r16); const ctx_r1 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r1.testSplitRatio, $event) || (ctx_r1.testSplitRatio = $event); return i0.ɵɵresetView($event); });
|
|
430
|
+
i0.ɵɵelementEnd()();
|
|
431
|
+
} if (rf & 2) {
|
|
432
|
+
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
433
|
+
i0.ɵɵadvance(4);
|
|
434
|
+
i0.ɵɵtextInterpolate(i0.ɵɵpipeBind1(5, 2, ctx_r1.testSplitRatio));
|
|
435
|
+
i0.ɵɵadvance(2);
|
|
436
|
+
i0.ɵɵtwoWayProperty("ngModel", ctx_r1.testSplitRatio);
|
|
437
|
+
} }
|
|
438
|
+
function PSPipelineWizardComponent_Conditional_40_Conditional_44_Template(rf, ctx) { if (rf & 1) {
|
|
439
|
+
const _r17 = i0.ɵɵgetCurrentView();
|
|
440
|
+
i0.ɵɵelementStart(0, "div", 23)(1, "label");
|
|
441
|
+
i0.ɵɵtext(2, "Number of Folds (K)");
|
|
442
|
+
i0.ɵɵelementEnd();
|
|
443
|
+
i0.ɵɵelementStart(3, "input", 100);
|
|
444
|
+
i0.ɵɵtwoWayListener("ngModelChange", function PSPipelineWizardComponent_Conditional_40_Conditional_44_Template_input_ngModelChange_3_listener($event) { i0.ɵɵrestoreView(_r17); const ctx_r1 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r1.kFolds, $event) || (ctx_r1.kFolds = $event); return i0.ɵɵresetView($event); });
|
|
445
|
+
i0.ɵɵelementEnd()();
|
|
446
|
+
} if (rf & 2) {
|
|
447
|
+
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
448
|
+
i0.ɵɵadvance(3);
|
|
449
|
+
i0.ɵɵtwoWayProperty("ngModel", ctx_r1.kFolds);
|
|
450
|
+
} }
|
|
451
|
+
function PSPipelineWizardComponent_Conditional_40_Template(rf, ctx) { if (rf & 1) {
|
|
452
|
+
const _r14 = i0.ɵɵgetCurrentView();
|
|
453
|
+
i0.ɵɵelementStart(0, "div", 17)(1, "div", 23)(2, "label", 87);
|
|
454
|
+
i0.ɵɵtext(3, "Algorithm ");
|
|
455
|
+
i0.ɵɵelementStart(4, "span", 25);
|
|
456
|
+
i0.ɵɵtext(5, "*");
|
|
457
|
+
i0.ɵɵelementEnd()();
|
|
458
|
+
i0.ɵɵelementStart(6, "select", 88);
|
|
459
|
+
i0.ɵɵlistener("ngModelChange", function PSPipelineWizardComponent_Conditional_40_Template_select_ngModelChange_6_listener($event) { i0.ɵɵrestoreView(_r14); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onAlgorithmSelected($event)); });
|
|
460
|
+
i0.ɵɵrepeaterCreate(7, PSPipelineWizardComponent_Conditional_40_For_8_Template, 2, 3, "option", 33, _forTrack0);
|
|
461
|
+
i0.ɵɵelementEnd()();
|
|
462
|
+
i0.ɵɵelementStart(9, "div", 89)(10, "div", 43);
|
|
463
|
+
i0.ɵɵelement(11, "i", 90);
|
|
464
|
+
i0.ɵɵelementStart(12, "h4");
|
|
465
|
+
i0.ɵɵtext(13, "Algorithm Hyperparameters");
|
|
466
|
+
i0.ɵɵelementEnd()();
|
|
467
|
+
i0.ɵɵelementStart(14, "div", 45)(15, "div", 91)(16, "div", 23)(17, "label");
|
|
468
|
+
i0.ɵɵtext(18, "Estimators (Trees)");
|
|
469
|
+
i0.ɵɵelementEnd();
|
|
470
|
+
i0.ɵɵelementStart(19, "input", 92);
|
|
471
|
+
i0.ɵɵtwoWayListener("ngModelChange", function PSPipelineWizardComponent_Conditional_40_Template_input_ngModelChange_19_listener($event) { i0.ɵɵrestoreView(_r14); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.hyperparamEstimators, $event) || (ctx_r1.hyperparamEstimators = $event); return i0.ɵɵresetView($event); });
|
|
472
|
+
i0.ɵɵelementEnd()();
|
|
473
|
+
i0.ɵɵelementStart(20, "div", 23)(21, "label");
|
|
474
|
+
i0.ɵɵtext(22, "Max Depth");
|
|
475
|
+
i0.ɵɵelementEnd();
|
|
476
|
+
i0.ɵɵelementStart(23, "input", 93);
|
|
477
|
+
i0.ɵɵtwoWayListener("ngModelChange", function PSPipelineWizardComponent_Conditional_40_Template_input_ngModelChange_23_listener($event) { i0.ɵɵrestoreView(_r14); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.hyperparamMaxDepth, $event) || (ctx_r1.hyperparamMaxDepth = $event); return i0.ɵɵresetView($event); });
|
|
478
|
+
i0.ɵɵelementEnd()();
|
|
479
|
+
i0.ɵɵelementStart(24, "div", 23)(25, "label");
|
|
480
|
+
i0.ɵɵtext(26, "Learning Rate");
|
|
481
|
+
i0.ɵɵelementEnd();
|
|
482
|
+
i0.ɵɵelementStart(27, "input", 94);
|
|
483
|
+
i0.ɵɵtwoWayListener("ngModelChange", function PSPipelineWizardComponent_Conditional_40_Template_input_ngModelChange_27_listener($event) { i0.ɵɵrestoreView(_r14); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.hyperparamLearningRate, $event) || (ctx_r1.hyperparamLearningRate = $event); return i0.ɵɵresetView($event); });
|
|
484
|
+
i0.ɵɵelementEnd()()()()();
|
|
485
|
+
i0.ɵɵelementStart(28, "div", 95)(29, "div", 43);
|
|
486
|
+
i0.ɵɵelement(30, "i", 96);
|
|
487
|
+
i0.ɵɵelementStart(31, "h4");
|
|
488
|
+
i0.ɵɵtext(32, "Validation Strategy");
|
|
489
|
+
i0.ɵɵelementEnd()();
|
|
490
|
+
i0.ɵɵelementStart(33, "div", 45)(34, "div", 29)(35, "div", 23)(36, "label");
|
|
491
|
+
i0.ɵɵtext(37, "Strategy");
|
|
492
|
+
i0.ɵɵelementEnd();
|
|
493
|
+
i0.ɵɵelementStart(38, "select", 46);
|
|
494
|
+
i0.ɵɵtwoWayListener("ngModelChange", function PSPipelineWizardComponent_Conditional_40_Template_select_ngModelChange_38_listener($event) { i0.ɵɵrestoreView(_r14); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.validationStrategyType, $event) || (ctx_r1.validationStrategyType = $event); return i0.ɵɵresetView($event); });
|
|
495
|
+
i0.ɵɵelementStart(39, "option", 97);
|
|
496
|
+
i0.ɵɵtext(40, "Train / Test Split");
|
|
497
|
+
i0.ɵɵelementEnd();
|
|
498
|
+
i0.ɵɵelementStart(41, "option", 98);
|
|
499
|
+
i0.ɵɵtext(42, "K-Fold Cross-Validation");
|
|
500
|
+
i0.ɵɵelementEnd()()();
|
|
501
|
+
i0.ɵɵconditionalCreate(43, PSPipelineWizardComponent_Conditional_40_Conditional_43_Template, 7, 4, "div", 23)(44, PSPipelineWizardComponent_Conditional_40_Conditional_44_Template, 4, 1, "div", 23);
|
|
502
|
+
i0.ɵɵelementEnd()()()();
|
|
503
|
+
} if (rf & 2) {
|
|
504
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
505
|
+
i0.ɵɵadvance(6);
|
|
506
|
+
i0.ɵɵproperty("ngModel", ctx_r1.selectedAlgorithmId);
|
|
507
|
+
i0.ɵɵadvance();
|
|
508
|
+
i0.ɵɵrepeater(ctx_r1.availableAlgorithms);
|
|
509
|
+
i0.ɵɵadvance(12);
|
|
510
|
+
i0.ɵɵtwoWayProperty("ngModel", ctx_r1.hyperparamEstimators);
|
|
511
|
+
i0.ɵɵadvance(4);
|
|
512
|
+
i0.ɵɵtwoWayProperty("ngModel", ctx_r1.hyperparamMaxDepth);
|
|
513
|
+
i0.ɵɵadvance(4);
|
|
514
|
+
i0.ɵɵtwoWayProperty("ngModel", ctx_r1.hyperparamLearningRate);
|
|
515
|
+
i0.ɵɵadvance(11);
|
|
516
|
+
i0.ɵɵtwoWayProperty("ngModel", ctx_r1.validationStrategyType);
|
|
517
|
+
i0.ɵɵadvance(5);
|
|
518
|
+
i0.ɵɵconditional(ctx_r1.validationStrategyType === "train_test_split" ? 43 : 44);
|
|
519
|
+
} }
|
|
520
|
+
function PSPipelineWizardComponent_Conditional_45_Template(rf, ctx) { if (rf & 1) {
|
|
521
|
+
const _r18 = i0.ɵɵgetCurrentView();
|
|
522
|
+
i0.ɵɵelementStart(0, "button", 19);
|
|
523
|
+
i0.ɵɵlistener("click", function PSPipelineWizardComponent_Conditional_45_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r18); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.prevStep()); });
|
|
524
|
+
i0.ɵɵelement(1, "i", 101);
|
|
525
|
+
i0.ɵɵtext(2, " Back ");
|
|
526
|
+
i0.ɵɵelementEnd();
|
|
527
|
+
} }
|
|
528
|
+
function PSPipelineWizardComponent_Conditional_46_Template(rf, ctx) { if (rf & 1) {
|
|
529
|
+
const _r19 = i0.ɵɵgetCurrentView();
|
|
530
|
+
i0.ɵɵelementStart(0, "button", 102);
|
|
531
|
+
i0.ɵɵlistener("click", function PSPipelineWizardComponent_Conditional_46_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r19); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.nextStep()); });
|
|
532
|
+
i0.ɵɵtext(1, " Next ");
|
|
533
|
+
i0.ɵɵelement(2, "i", 103);
|
|
534
|
+
i0.ɵɵelementEnd();
|
|
535
|
+
} if (rf & 2) {
|
|
536
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
537
|
+
i0.ɵɵproperty("disabled", !ctx_r1.canProceed());
|
|
538
|
+
} }
|
|
539
|
+
function PSPipelineWizardComponent_Conditional_47_Template(rf, ctx) { if (rf & 1) {
|
|
540
|
+
const _r20 = i0.ɵɵgetCurrentView();
|
|
541
|
+
i0.ɵɵelementStart(0, "button", 104);
|
|
542
|
+
i0.ɵɵlistener("click", function PSPipelineWizardComponent_Conditional_47_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r20); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.saveDraft()); });
|
|
543
|
+
i0.ɵɵelement(1, "i", 105);
|
|
544
|
+
i0.ɵɵtext(2, " Save Draft ");
|
|
545
|
+
i0.ɵɵelementEnd();
|
|
546
|
+
i0.ɵɵelementStart(3, "button", 102);
|
|
547
|
+
i0.ɵɵlistener("click", function PSPipelineWizardComponent_Conditional_47_Template_button_click_3_listener() { i0.ɵɵrestoreView(_r20); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.saveAndTrain()); });
|
|
548
|
+
i0.ɵɵelement(4, "i", 106);
|
|
549
|
+
i0.ɵɵtext(5, " Save & Train Now ");
|
|
550
|
+
i0.ɵɵelementEnd();
|
|
551
|
+
} if (rf & 2) {
|
|
552
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
553
|
+
i0.ɵɵproperty("disabled", ctx_r1.busy || !ctx_r1.canSave());
|
|
554
|
+
i0.ɵɵadvance(3);
|
|
555
|
+
i0.ɵɵproperty("disabled", ctx_r1.busy || !ctx_r1.canSave());
|
|
556
|
+
} }
|
|
557
|
+
export class PSPipelineWizardComponent {
|
|
558
|
+
provider = null;
|
|
559
|
+
currentUser = null;
|
|
560
|
+
engine = null;
|
|
561
|
+
initialAlgorithmName;
|
|
562
|
+
initialAlgorithmId;
|
|
563
|
+
cloneFromPipeline;
|
|
564
|
+
set cloneFrom(p) {
|
|
565
|
+
this.cloneFromPipeline = p ?? undefined;
|
|
566
|
+
}
|
|
567
|
+
closed = new EventEmitter();
|
|
568
|
+
saved = new EventEmitter();
|
|
569
|
+
trainRequested = new EventEmitter();
|
|
570
|
+
cdr = inject(ChangeDetectorRef);
|
|
571
|
+
notifications = inject(MJNotificationService);
|
|
572
|
+
currentStep = 'goal';
|
|
573
|
+
busy = false;
|
|
574
|
+
isEditing = false;
|
|
575
|
+
// Step 1: Goal & Target
|
|
576
|
+
pipelineName = '';
|
|
577
|
+
pipelineDescription = '';
|
|
578
|
+
selectedEntityId = '';
|
|
579
|
+
targetVariable = '';
|
|
580
|
+
problemType = 'classification';
|
|
581
|
+
evaluationMetric = 'AUC';
|
|
582
|
+
asOfMode = 'none';
|
|
583
|
+
asOfColumn = '';
|
|
584
|
+
asOfOffsetDays = 30;
|
|
585
|
+
// Step 2: Features
|
|
586
|
+
fieldItems = [];
|
|
587
|
+
fieldSearchFilter = '';
|
|
588
|
+
dominanceThreshold = DOMINANCE_THRESHOLD_DEFAULT;
|
|
589
|
+
// Step 3: Preprocessing
|
|
590
|
+
categoricalEncoding = 'onehot';
|
|
591
|
+
imputeStrategy = 'median';
|
|
592
|
+
standardizeStrategy = 'standard';
|
|
593
|
+
// Step 4: Algorithm & Validation
|
|
594
|
+
selectedAlgorithmId = '';
|
|
595
|
+
hyperparamEstimators = 100;
|
|
596
|
+
hyperparamMaxDepth = 6;
|
|
597
|
+
hyperparamLearningRate = 0.1;
|
|
598
|
+
validationStrategyType = 'train_test_split';
|
|
599
|
+
testSplitRatio = 0.2;
|
|
600
|
+
kFolds = 5;
|
|
601
|
+
ngOnInit() {
|
|
602
|
+
this.initFromDefaults();
|
|
603
|
+
}
|
|
604
|
+
get availableEntities() {
|
|
605
|
+
if (!this.provider)
|
|
606
|
+
return [];
|
|
607
|
+
return this.provider.Entities.filter((e) => !e.VirtualEntity && e.AllowUserSearchAPI)
|
|
608
|
+
.sort((a, b) => a.Name.localeCompare(b.Name));
|
|
609
|
+
}
|
|
610
|
+
get selectedEntity() {
|
|
611
|
+
if (!this.selectedEntityId || !this.provider)
|
|
612
|
+
return null;
|
|
613
|
+
return this.provider.Entities.find((e) => UUIDsEqual(e.ID, this.selectedEntityId)) ?? null;
|
|
614
|
+
}
|
|
615
|
+
get availableFields() {
|
|
616
|
+
return this.selectedEntity?.Fields ?? [];
|
|
617
|
+
}
|
|
618
|
+
get dateFields() {
|
|
619
|
+
return this.availableFields.filter((f) => f.Type?.toLowerCase().includes('date') || f.Type?.toLowerCase().includes('time'));
|
|
620
|
+
}
|
|
621
|
+
get availableMetrics() {
|
|
622
|
+
if (this.problemType === 'classification') {
|
|
623
|
+
return ['AUC', 'Accuracy', 'F1', 'Log Loss', 'Precision', 'Recall'];
|
|
624
|
+
}
|
|
625
|
+
return ['RMSE', 'MAE', 'R2', 'MSE'];
|
|
626
|
+
}
|
|
627
|
+
get availableAlgorithms() {
|
|
628
|
+
return this.engine?.Algorithms ?? [];
|
|
629
|
+
}
|
|
630
|
+
get filteredFieldItems() {
|
|
631
|
+
const q = this.fieldSearchFilter.trim().toLowerCase();
|
|
632
|
+
if (!q)
|
|
633
|
+
return this.fieldItems;
|
|
634
|
+
return this.fieldItems.filter((item) => item.field.Name.toLowerCase().includes(q) || item.field.Type?.toLowerCase().includes(q));
|
|
635
|
+
}
|
|
636
|
+
get selectedFeaturesCount() {
|
|
637
|
+
return this.fieldItems.filter((i) => i.selected && !i.isDenyList && !i.isTarget).length;
|
|
638
|
+
}
|
|
639
|
+
get denyListCount() {
|
|
640
|
+
return this.fieldItems.filter((i) => i.isDenyList).length;
|
|
641
|
+
}
|
|
642
|
+
onEntitySelected(entityId) {
|
|
643
|
+
this.selectedEntityId = entityId;
|
|
644
|
+
this.targetVariable = '';
|
|
645
|
+
this.populateFieldItems();
|
|
646
|
+
this.cdr.detectChanges();
|
|
647
|
+
}
|
|
648
|
+
onProblemTypeChange() {
|
|
649
|
+
this.evaluationMetric = this.problemType === 'classification' ? 'AUC' : 'RMSE';
|
|
650
|
+
this.cdr.detectChanges();
|
|
651
|
+
}
|
|
652
|
+
onAlgorithmSelected(algoId) {
|
|
653
|
+
this.selectedAlgorithmId = algoId;
|
|
654
|
+
this.cdr.detectChanges();
|
|
655
|
+
}
|
|
656
|
+
toggleDenyList(item) {
|
|
657
|
+
item.isDenyList = !item.isDenyList;
|
|
658
|
+
if (item.isDenyList) {
|
|
659
|
+
item.selected = false;
|
|
660
|
+
}
|
|
661
|
+
this.cdr.detectChanges();
|
|
662
|
+
}
|
|
663
|
+
selectAllFields(val) {
|
|
664
|
+
for (const item of this.fieldItems) {
|
|
665
|
+
if (!item.isTarget && !item.isDenyList) {
|
|
666
|
+
item.selected = val;
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
this.cdr.detectChanges();
|
|
670
|
+
}
|
|
671
|
+
excludeAuditFields() {
|
|
672
|
+
for (const item of this.fieldItems) {
|
|
673
|
+
const name = item.field.Name.toLowerCase();
|
|
674
|
+
if (name === 'id' ||
|
|
675
|
+
name.startsWith('__mj') ||
|
|
676
|
+
name.includes('created') ||
|
|
677
|
+
name.includes('updated') ||
|
|
678
|
+
name.includes('password')) {
|
|
679
|
+
item.selected = false;
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
this.cdr.detectChanges();
|
|
683
|
+
}
|
|
684
|
+
isStepDone(step) {
|
|
685
|
+
switch (step) {
|
|
686
|
+
case 'goal':
|
|
687
|
+
return Boolean(this.pipelineName.trim() && this.selectedEntityId && this.targetVariable);
|
|
688
|
+
case 'features':
|
|
689
|
+
return this.selectedFeaturesCount > 0;
|
|
690
|
+
case 'preprocessing':
|
|
691
|
+
return true;
|
|
692
|
+
case 'algorithm':
|
|
693
|
+
return Boolean(this.selectedAlgorithmId);
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
canProceed() {
|
|
697
|
+
return this.isStepDone(this.currentStep);
|
|
698
|
+
}
|
|
699
|
+
canSave() {
|
|
700
|
+
return (Boolean(this.pipelineName.trim()) &&
|
|
701
|
+
Boolean(this.selectedEntityId) &&
|
|
702
|
+
Boolean(this.targetVariable) &&
|
|
703
|
+
Boolean(this.selectedAlgorithmId) &&
|
|
704
|
+
this.selectedFeaturesCount > 0);
|
|
705
|
+
}
|
|
706
|
+
goToStep(step) {
|
|
707
|
+
this.currentStep = step;
|
|
708
|
+
this.cdr.detectChanges();
|
|
709
|
+
}
|
|
710
|
+
nextStep() {
|
|
711
|
+
if (this.currentStep === 'goal')
|
|
712
|
+
this.currentStep = 'features';
|
|
713
|
+
else if (this.currentStep === 'features')
|
|
714
|
+
this.currentStep = 'preprocessing';
|
|
715
|
+
else if (this.currentStep === 'preprocessing')
|
|
716
|
+
this.currentStep = 'algorithm';
|
|
717
|
+
this.cdr.detectChanges();
|
|
718
|
+
}
|
|
719
|
+
prevStep() {
|
|
720
|
+
if (this.currentStep === 'algorithm')
|
|
721
|
+
this.currentStep = 'preprocessing';
|
|
722
|
+
else if (this.currentStep === 'preprocessing')
|
|
723
|
+
this.currentStep = 'features';
|
|
724
|
+
else if (this.currentStep === 'features')
|
|
725
|
+
this.currentStep = 'goal';
|
|
726
|
+
this.cdr.detectChanges();
|
|
727
|
+
}
|
|
728
|
+
cancel() {
|
|
729
|
+
this.closed.emit();
|
|
730
|
+
}
|
|
731
|
+
onBackdropClick(event) {
|
|
732
|
+
if (event.target.classList.contains('ps-modal-backdrop')) {
|
|
733
|
+
this.cancel();
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
async saveDraft() {
|
|
737
|
+
return this.persistPipeline(false);
|
|
738
|
+
}
|
|
739
|
+
async saveAndTrain() {
|
|
740
|
+
const pipeline = await this.persistPipeline(true);
|
|
741
|
+
if (!pipeline)
|
|
742
|
+
return;
|
|
743
|
+
this.trainRequested.emit(pipeline);
|
|
744
|
+
}
|
|
745
|
+
async persistPipeline(andTrain) {
|
|
746
|
+
if (!this.canSave()) {
|
|
747
|
+
this.notifications.CreateSimpleNotification('Please complete required fields before saving.', 'warning', 3000);
|
|
748
|
+
return null;
|
|
749
|
+
}
|
|
750
|
+
this.busy = true;
|
|
751
|
+
this.cdr.detectChanges();
|
|
752
|
+
try {
|
|
753
|
+
const prov = this.provider ?? Metadata.Provider;
|
|
754
|
+
const p = await prov.GetEntityObject('MJ: ML Training Pipelines', this.currentUser ?? undefined);
|
|
755
|
+
p.NewRecord();
|
|
756
|
+
p.Name = this.pipelineName.trim();
|
|
757
|
+
p.Description = this.pipelineDescription.trim();
|
|
758
|
+
p.Version = 1;
|
|
759
|
+
p.Status = 'Draft';
|
|
760
|
+
p.TargetEntityID = this.selectedEntityId;
|
|
761
|
+
p.TargetVariable = this.targetVariable;
|
|
762
|
+
p.ProblemType = this.problemType;
|
|
763
|
+
p.AlgorithmID = this.selectedAlgorithmId;
|
|
764
|
+
// Source Bindings
|
|
765
|
+
const sourceBindings = [
|
|
766
|
+
{
|
|
767
|
+
Kind: 'Entity',
|
|
768
|
+
Ref: this.selectedEntity?.Name ?? this.selectedEntityId,
|
|
769
|
+
Alias: 'src_primary',
|
|
770
|
+
},
|
|
771
|
+
];
|
|
772
|
+
p.SourceBindings = JSON.stringify(sourceBindings);
|
|
773
|
+
// Feature Steps
|
|
774
|
+
const selectedColumns = this.fieldItems
|
|
775
|
+
.filter((i) => i.selected && !i.isDenyList && !i.isTarget)
|
|
776
|
+
.map((i) => i.field.Name);
|
|
777
|
+
const steps = [
|
|
778
|
+
{
|
|
779
|
+
Id: 'step_select',
|
|
780
|
+
Kind: 'select',
|
|
781
|
+
Label: 'Select Features',
|
|
782
|
+
Inputs: ['src_primary'],
|
|
783
|
+
Columns: selectedColumns,
|
|
784
|
+
},
|
|
785
|
+
];
|
|
786
|
+
if (this.categoricalEncoding === 'onehot') {
|
|
787
|
+
const catCols = this.fieldItems
|
|
788
|
+
.filter((i) => i.selected && !i.isDenyList && !i.isTarget)
|
|
789
|
+
.filter((i) => {
|
|
790
|
+
const t = i.field.Type?.toLowerCase() ?? '';
|
|
791
|
+
return t.includes('char') || t.includes('text') || t.includes('string');
|
|
792
|
+
})
|
|
793
|
+
.map((i) => i.field.Name);
|
|
794
|
+
for (const c of catCols) {
|
|
795
|
+
steps.push({
|
|
796
|
+
Id: `step_onehot_${c}`,
|
|
797
|
+
Kind: 'onehot',
|
|
798
|
+
Label: `One-Hot ${c}`,
|
|
799
|
+
Inputs: ['step_select'],
|
|
800
|
+
Column: c,
|
|
801
|
+
});
|
|
802
|
+
}
|
|
803
|
+
}
|
|
804
|
+
if (this.standardizeStrategy !== 'none') {
|
|
805
|
+
const numCols = this.fieldItems
|
|
806
|
+
.filter((i) => i.selected && !i.isDenyList && !i.isTarget)
|
|
807
|
+
.filter((i) => {
|
|
808
|
+
const t = i.field.Type?.toLowerCase() ?? '';
|
|
809
|
+
return (t.includes('int') ||
|
|
810
|
+
t.includes('decimal') ||
|
|
811
|
+
t.includes('float') ||
|
|
812
|
+
t.includes('money') ||
|
|
813
|
+
t.includes('numeric'));
|
|
814
|
+
})
|
|
815
|
+
.map((i) => i.field.Name);
|
|
816
|
+
if (numCols.length > 0) {
|
|
817
|
+
steps.push({
|
|
818
|
+
Id: 'step_standardize',
|
|
819
|
+
Kind: 'standardize',
|
|
820
|
+
Label: 'Standardize Numerics',
|
|
821
|
+
Inputs: ['step_select'],
|
|
822
|
+
Columns: numCols,
|
|
823
|
+
});
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
p.FeatureSteps = JSON.stringify({ Steps: steps });
|
|
827
|
+
// As-Of Strategy
|
|
828
|
+
const asOf = {
|
|
829
|
+
Mode: this.asOfMode,
|
|
830
|
+
...(this.asOfMode === 'column' ? { Column: this.asOfColumn } : {}),
|
|
831
|
+
...(this.asOfMode === 'offset' ? { OffsetDays: this.asOfOffsetDays } : {}),
|
|
832
|
+
};
|
|
833
|
+
p.AsOfStrategy = JSON.stringify(asOf);
|
|
834
|
+
// Leakage Guard
|
|
835
|
+
const denyList = this.fieldItems.filter((i) => i.isDenyList).map((i) => i.field.Name);
|
|
836
|
+
const leakageGuard = {
|
|
837
|
+
DenyFields: denyList,
|
|
838
|
+
SingleFeatureDominanceThreshold: this.dominanceThreshold,
|
|
839
|
+
};
|
|
840
|
+
p.LeakageGuard = JSON.stringify(leakageGuard);
|
|
841
|
+
// Validation Strategy
|
|
842
|
+
const valStrategy = {
|
|
843
|
+
Strategy: this.validationStrategyType,
|
|
844
|
+
LockedHoldoutFraction: 0.15,
|
|
845
|
+
...(this.validationStrategyType === 'train_test_split' ? { TestSize: this.testSplitRatio } : {}),
|
|
846
|
+
...(this.validationStrategyType === 'kfold' ? { K: this.kFolds } : {}),
|
|
847
|
+
};
|
|
848
|
+
p.ValidationStrategy = JSON.stringify(valStrategy);
|
|
849
|
+
if (!(await p.Save())) {
|
|
850
|
+
throw new Error(p.LatestResult?.CompleteMessage ?? 'Failed to save pipeline record.');
|
|
851
|
+
}
|
|
852
|
+
this.notifications.CreateSimpleNotification(`Training pipeline '${p.Name}' saved successfully.`, 'success', 3000);
|
|
853
|
+
this.saved.emit(p);
|
|
854
|
+
return p;
|
|
855
|
+
}
|
|
856
|
+
catch (err) {
|
|
857
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
858
|
+
this.notifications.CreateSimpleNotification(`Error saving pipeline: ${msg}`, 'error', 5000);
|
|
859
|
+
return null;
|
|
860
|
+
}
|
|
861
|
+
finally {
|
|
862
|
+
this.busy = false;
|
|
863
|
+
this.cdr.detectChanges();
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
initFromDefaults() {
|
|
867
|
+
// If initial algorithm requested (e.g. from Catalog)
|
|
868
|
+
if (this.initialAlgorithmId) {
|
|
869
|
+
this.selectedAlgorithmId = this.initialAlgorithmId;
|
|
870
|
+
}
|
|
871
|
+
else if (this.initialAlgorithmName && (this.engine?.Algorithms.length ?? 0) > 0) {
|
|
872
|
+
const match = this.engine.Algorithms.find((a) => a.Name.toLowerCase() === this.initialAlgorithmName.toLowerCase() ||
|
|
873
|
+
a.DriverClass?.toLowerCase() === this.initialAlgorithmName.toLowerCase());
|
|
874
|
+
if (match)
|
|
875
|
+
this.selectedAlgorithmId = match.ID;
|
|
876
|
+
}
|
|
877
|
+
else if ((this.engine?.Algorithms.length ?? 0) > 0) {
|
|
878
|
+
this.selectedAlgorithmId = this.engine.Algorithms[0].ID;
|
|
879
|
+
}
|
|
880
|
+
// If cloning from existing pipeline
|
|
881
|
+
if (this.cloneFromPipeline) {
|
|
882
|
+
const cp = this.cloneFromPipeline;
|
|
883
|
+
this.isEditing = false; // clone creates new
|
|
884
|
+
this.pipelineName = `${cp.Name} (Copy)`;
|
|
885
|
+
this.pipelineDescription = cp.Description || '';
|
|
886
|
+
this.selectedEntityId = cp.TargetEntityID;
|
|
887
|
+
this.targetVariable = cp.TargetVariable;
|
|
888
|
+
this.problemType = cp.ProblemType || 'classification';
|
|
889
|
+
if (cp.AlgorithmID)
|
|
890
|
+
this.selectedAlgorithmId = cp.AlgorithmID;
|
|
891
|
+
this.populateFieldItems();
|
|
892
|
+
// Read leakage guard
|
|
893
|
+
try {
|
|
894
|
+
if (cp.LeakageGuard) {
|
|
895
|
+
const lg = JSON.parse(cp.LeakageGuard);
|
|
896
|
+
const deny = (lg['DenyFields'] ?? lg['DenyList']);
|
|
897
|
+
if (Array.isArray(deny)) {
|
|
898
|
+
const denySet = new Set(deny.map((d) => d.toLowerCase()));
|
|
899
|
+
for (const item of this.fieldItems) {
|
|
900
|
+
if (denySet.has(item.field.Name.toLowerCase())) {
|
|
901
|
+
item.isDenyList = true;
|
|
902
|
+
item.selected = false;
|
|
903
|
+
}
|
|
904
|
+
}
|
|
905
|
+
}
|
|
906
|
+
if (typeof lg['SingleFeatureDominanceThreshold'] === 'number') {
|
|
907
|
+
this.dominanceThreshold = lg['SingleFeatureDominanceThreshold'];
|
|
908
|
+
}
|
|
909
|
+
}
|
|
910
|
+
}
|
|
911
|
+
catch {
|
|
912
|
+
// Ignore
|
|
913
|
+
}
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
populateFieldItems() {
|
|
917
|
+
if (!this.selectedEntity) {
|
|
918
|
+
this.fieldItems = [];
|
|
919
|
+
return;
|
|
920
|
+
}
|
|
921
|
+
const targetLower = (this.targetVariable || '').toLowerCase();
|
|
922
|
+
this.fieldItems = this.selectedEntity.Fields.map((f) => {
|
|
923
|
+
const nameLower = f.Name.toLowerCase();
|
|
924
|
+
const isTarget = Boolean(targetLower && nameLower === targetLower);
|
|
925
|
+
const isSystem = nameLower === 'id' ||
|
|
926
|
+
nameLower.startsWith('__mj') ||
|
|
927
|
+
nameLower.includes('created') ||
|
|
928
|
+
nameLower.includes('updated');
|
|
929
|
+
return {
|
|
930
|
+
field: f,
|
|
931
|
+
selected: !isTarget && !isSystem,
|
|
932
|
+
isDenyList: false,
|
|
933
|
+
isTarget,
|
|
934
|
+
};
|
|
935
|
+
});
|
|
936
|
+
}
|
|
937
|
+
static ɵfac = function PSPipelineWizardComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || PSPipelineWizardComponent)(); };
|
|
938
|
+
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: PSPipelineWizardComponent, selectors: [["ps-pipeline-wizard"]], inputs: { provider: "provider", currentUser: "currentUser", engine: "engine", initialAlgorithmName: "initialAlgorithmName", initialAlgorithmId: "initialAlgorithmId", cloneFromPipeline: "cloneFromPipeline", cloneFrom: "cloneFrom" }, outputs: { closed: "closed", saved: "saved", trainRequested: "trainRequested" }, decls: 48, vars: 23, consts: [[1, "ps-modal-backdrop", 3, "click"], ["role", "dialog", "aria-modal", "true", "data-testid", "ps-pipeline-wizard", 1, "ps-modal-dialog", "ps-wizard-dialog"], [1, "ps-wizard-header"], [1, "ps-wizard-header-title"], [1, "fa-solid", "fa-wand-magic-sparkles"], [1, "ps-wizard-subtitle"], ["aria-label", "Close wizard", 1, "ps-wizard-close", 3, "click"], [1, "fa-solid", "fa-xmark"], [1, "ps-wizard-stepper"], [1, "ps-step-tab", 3, "click"], [1, "step-num"], [1, "step-label"], [1, "step-line"], [1, "ps-wizard-body"], ["data-testid", "ps-wizard-step-goal", 1, "ps-step-content"], ["data-testid", "ps-wizard-step-features", 1, "ps-step-content"], ["data-testid", "ps-wizard-step-preprocessing", 1, "ps-step-content"], ["data-testid", "ps-wizard-step-algorithm", 1, "ps-step-content"], [1, "ps-wizard-footer"], ["mjButton", "", "variant", "secondary", "size", "sm", 3, "click"], [1, "ps-spacer"], ["mjButton", "", "variant", "secondary", "size", "sm"], ["mjButton", "", "variant", "primary", "size", "sm", 3, "disabled"], [1, "ps-field"], ["for", "pipeline-name"], [1, "req"], ["id", "pipeline-name", "type", "text", "placeholder", "e.g. Member Renewal Risk v1", 1, "mj-input", 3, "ngModelChange", "ngModel"], ["for", "pipeline-desc"], ["id", "pipeline-desc", "rows", "2", "placeholder", "Predicts whether active members will renew before their period ends.", 1, "mj-textarea", 3, "ngModelChange", "ngModel"], [1, "ps-grid-2"], ["for", "target-entity"], ["id", "target-entity", 1, "mj-input", 3, "ngModelChange", "ngModel"], ["disabled", "", 3, "value"], [3, "value"], ["for", "target-variable"], ["id", "target-variable", 1, "mj-input", 3, "ngModelChange", "ngModel", "disabled"], ["for", "problem-type"], ["id", "problem-type", 1, "mj-input", 3, "ngModelChange", "ngModel"], ["value", "classification"], ["value", "regression"], ["for", "eval-metric"], ["id", "eval-metric", 1, "mj-input", 3, "ngModelChange", "ngModel"], [1, "ps-card", "as-of-box"], [1, "ps-card-head"], [1, "fa-solid", "fa-clock-rotate-left"], [1, "ps-card-body"], [1, "mj-input", 3, "ngModelChange", "ngModel"], ["value", "none"], ["value", "column"], ["value", "offset"], ["type", "number", "min", "1", 1, "mj-input", 3, "ngModelChange", "ngModel"], [1, "feat-toolbar"], [1, "feat-search"], [1, "fa-solid", "fa-magnifying-glass"], ["type", "text", "placeholder", "Filter fields by name or type\u2026", 1, "mj-input", 3, "ngModelChange", "ngModel"], [1, "feat-actions"], [1, "feat-stats"], [1, "text-danger"], [1, "feat-table-wrap"], [1, "ps-table", "feat-table"], [2, "width", "40px"], [2, "width", "140px", "text-align", "center"], [3, "target-row", "deny-row"], [1, "ps-field", 2, "margin-top", "14px"], [1, "slider-row"], ["type", "range", "min", "0.5", "max", "0.99", "step", "0.01", 3, "ngModelChange", "ngModel"], [1, "ps-muted", "ps-small"], ["type", "checkbox", 3, "ngModelChange", "ngModel", "disabled"], [1, "ps-badge", "info", 2, "margin-left", "6px"], [2, "text-align", "center"], ["title", "Add to leakage deny-list", 1, "ps-deny-toggle", 3, "denied"], ["title", "Add to leakage deny-list", 1, "ps-deny-toggle", 3, "click"], [1, "fa-solid"], [1, "recipe-card"], [1, "recipe-icon"], [1, "fa-solid", "fa-table-cells"], [1, "recipe-details"], [1, "ps-small", "ps-muted"], ["value", "onehot"], [1, "fa-solid", "fa-fill-drip"], ["value", "median"], ["value", "mean"], ["value", "mode"], ["value", "constant"], [1, "fa-solid", "fa-ruler-combined"], ["value", "standard"], ["value", "minmax"], ["for", "algorithm-select"], ["id", "algorithm-select", 1, "mj-input", 3, "ngModelChange", "ngModel"], [1, "ps-card", 2, "margin", "12px 0"], [1, "fa-solid", "fa-sliders"], [1, "ps-grid-3"], ["type", "number", "min", "10", "max", "1000", "step", "10", 1, "mj-input", 3, "ngModelChange", "ngModel"], ["type", "number", "min", "1", "max", "20", 1, "mj-input", 3, "ngModelChange", "ngModel"], ["type", "number", "min", "0.001", "max", "1", "step", "0.01", 1, "mj-input", 3, "ngModelChange", "ngModel"], [1, "ps-card"], [1, "fa-solid", "fa-scissors"], ["value", "train_test_split"], ["value", "kfold"], ["type", "range", "min", "0.1", "max", "0.4", "step", "0.05", 3, "ngModelChange", "ngModel"], ["type", "number", "min", "2", "max", "10", 1, "mj-input", 3, "ngModelChange", "ngModel"], [1, "fa-solid", "fa-arrow-left"], ["mjButton", "", "variant", "primary", "size", "sm", 3, "click", "disabled"], [1, "fa-solid", "fa-arrow-right"], ["mjButton", "", "variant", "secondary", "size", "sm", 3, "click", "disabled"], [1, "fa-solid", "fa-floppy-disk"], [1, "fa-solid", "fa-play"]], template: function PSPipelineWizardComponent_Template(rf, ctx) { if (rf & 1) {
|
|
939
|
+
i0.ɵɵelementStart(0, "div", 0);
|
|
940
|
+
i0.ɵɵlistener("click", function PSPipelineWizardComponent_Template_div_click_0_listener($event) { return ctx.onBackdropClick($event); });
|
|
941
|
+
i0.ɵɵelementStart(1, "div", 1)(2, "div", 2)(3, "div", 3);
|
|
942
|
+
i0.ɵɵelement(4, "i", 4);
|
|
943
|
+
i0.ɵɵelementStart(5, "div")(6, "h2");
|
|
944
|
+
i0.ɵɵtext(7);
|
|
945
|
+
i0.ɵɵelementEnd();
|
|
946
|
+
i0.ɵɵelementStart(8, "span", 5);
|
|
947
|
+
i0.ɵɵtext(9, "Step-by-step pipeline configuration with leakage guard");
|
|
948
|
+
i0.ɵɵelementEnd()()();
|
|
949
|
+
i0.ɵɵelementStart(10, "button", 6);
|
|
950
|
+
i0.ɵɵlistener("click", function PSPipelineWizardComponent_Template_button_click_10_listener() { return ctx.cancel(); });
|
|
951
|
+
i0.ɵɵelement(11, "i", 7);
|
|
952
|
+
i0.ɵɵelementEnd()();
|
|
953
|
+
i0.ɵɵelementStart(12, "div", 8)(13, "button", 9);
|
|
954
|
+
i0.ɵɵlistener("click", function PSPipelineWizardComponent_Template_button_click_13_listener() { return ctx.goToStep("goal"); });
|
|
955
|
+
i0.ɵɵelementStart(14, "span", 10);
|
|
956
|
+
i0.ɵɵtext(15, "1");
|
|
957
|
+
i0.ɵɵelementEnd();
|
|
958
|
+
i0.ɵɵelementStart(16, "span", 11);
|
|
959
|
+
i0.ɵɵtext(17, "Goal & Target");
|
|
960
|
+
i0.ɵɵelementEnd()();
|
|
961
|
+
i0.ɵɵelement(18, "div", 12);
|
|
962
|
+
i0.ɵɵelementStart(19, "button", 9);
|
|
963
|
+
i0.ɵɵlistener("click", function PSPipelineWizardComponent_Template_button_click_19_listener() { return ctx.goToStep("features"); });
|
|
964
|
+
i0.ɵɵelementStart(20, "span", 10);
|
|
965
|
+
i0.ɵɵtext(21, "2");
|
|
966
|
+
i0.ɵɵelementEnd();
|
|
967
|
+
i0.ɵɵelementStart(22, "span", 11);
|
|
968
|
+
i0.ɵɵtext(23, "Features & Leakage");
|
|
969
|
+
i0.ɵɵelementEnd()();
|
|
970
|
+
i0.ɵɵelement(24, "div", 12);
|
|
971
|
+
i0.ɵɵelementStart(25, "button", 9);
|
|
972
|
+
i0.ɵɵlistener("click", function PSPipelineWizardComponent_Template_button_click_25_listener() { return ctx.goToStep("preprocessing"); });
|
|
973
|
+
i0.ɵɵelementStart(26, "span", 10);
|
|
974
|
+
i0.ɵɵtext(27, "3");
|
|
975
|
+
i0.ɵɵelementEnd();
|
|
976
|
+
i0.ɵɵelementStart(28, "span", 11);
|
|
977
|
+
i0.ɵɵtext(29, "Preprocessing");
|
|
978
|
+
i0.ɵɵelementEnd()();
|
|
979
|
+
i0.ɵɵelement(30, "div", 12);
|
|
980
|
+
i0.ɵɵelementStart(31, "button", 9);
|
|
981
|
+
i0.ɵɵlistener("click", function PSPipelineWizardComponent_Template_button_click_31_listener() { return ctx.goToStep("algorithm"); });
|
|
982
|
+
i0.ɵɵelementStart(32, "span", 10);
|
|
983
|
+
i0.ɵɵtext(33, "4");
|
|
984
|
+
i0.ɵɵelementEnd();
|
|
985
|
+
i0.ɵɵelementStart(34, "span", 11);
|
|
986
|
+
i0.ɵɵtext(35, "Algorithm & Split");
|
|
987
|
+
i0.ɵɵelementEnd()()();
|
|
988
|
+
i0.ɵɵelementStart(36, "div", 13);
|
|
989
|
+
i0.ɵɵconditionalCreate(37, PSPipelineWizardComponent_Conditional_37_Template, 66, 12, "div", 14);
|
|
990
|
+
i0.ɵɵconditionalCreate(38, PSPipelineWizardComponent_Conditional_38_Template, 51, 10, "div", 15);
|
|
991
|
+
i0.ɵɵconditionalCreate(39, PSPipelineWizardComponent_Conditional_39_Template, 46, 3, "div", 16);
|
|
992
|
+
i0.ɵɵconditionalCreate(40, PSPipelineWizardComponent_Conditional_40_Template, 45, 6, "div", 17);
|
|
993
|
+
i0.ɵɵelementEnd();
|
|
994
|
+
i0.ɵɵelementStart(41, "div", 18)(42, "button", 19);
|
|
995
|
+
i0.ɵɵlistener("click", function PSPipelineWizardComponent_Template_button_click_42_listener() { return ctx.cancel(); });
|
|
996
|
+
i0.ɵɵtext(43, "Cancel");
|
|
997
|
+
i0.ɵɵelementEnd();
|
|
998
|
+
i0.ɵɵelement(44, "span", 20);
|
|
999
|
+
i0.ɵɵconditionalCreate(45, PSPipelineWizardComponent_Conditional_45_Template, 3, 0, "button", 21);
|
|
1000
|
+
i0.ɵɵconditionalCreate(46, PSPipelineWizardComponent_Conditional_46_Template, 3, 1, "button", 22)(47, PSPipelineWizardComponent_Conditional_47_Template, 6, 2);
|
|
1001
|
+
i0.ɵɵelementEnd()()();
|
|
1002
|
+
} if (rf & 2) {
|
|
1003
|
+
i0.ɵɵadvance(7);
|
|
1004
|
+
i0.ɵɵtextInterpolate(ctx.isEditing ? "Edit Training Pipeline" : "New ML Training Pipeline");
|
|
1005
|
+
i0.ɵɵadvance(6);
|
|
1006
|
+
i0.ɵɵclassProp("active", ctx.currentStep === "goal")("done", ctx.isStepDone("goal"));
|
|
1007
|
+
i0.ɵɵadvance(6);
|
|
1008
|
+
i0.ɵɵclassProp("active", ctx.currentStep === "features")("done", ctx.isStepDone("features"));
|
|
1009
|
+
i0.ɵɵadvance(6);
|
|
1010
|
+
i0.ɵɵclassProp("active", ctx.currentStep === "preprocessing")("done", ctx.isStepDone("preprocessing"));
|
|
1011
|
+
i0.ɵɵadvance(6);
|
|
1012
|
+
i0.ɵɵclassProp("active", ctx.currentStep === "algorithm")("done", ctx.isStepDone("algorithm"));
|
|
1013
|
+
i0.ɵɵadvance(6);
|
|
1014
|
+
i0.ɵɵconditional(ctx.currentStep === "goal" ? 37 : -1);
|
|
1015
|
+
i0.ɵɵadvance();
|
|
1016
|
+
i0.ɵɵconditional(ctx.currentStep === "features" ? 38 : -1);
|
|
1017
|
+
i0.ɵɵadvance();
|
|
1018
|
+
i0.ɵɵconditional(ctx.currentStep === "preprocessing" ? 39 : -1);
|
|
1019
|
+
i0.ɵɵadvance();
|
|
1020
|
+
i0.ɵɵconditional(ctx.currentStep === "algorithm" ? 40 : -1);
|
|
1021
|
+
i0.ɵɵadvance(5);
|
|
1022
|
+
i0.ɵɵconditional(ctx.currentStep !== "goal" ? 45 : -1);
|
|
1023
|
+
i0.ɵɵadvance();
|
|
1024
|
+
i0.ɵɵconditional(ctx.currentStep !== "algorithm" ? 46 : 47);
|
|
1025
|
+
} }, dependencies: [CommonModule, FormsModule, i1.NgSelectOption, i1.ɵNgSelectMultipleOption, i1.DefaultValueAccessor, i1.NumberValueAccessor, i1.RangeValueAccessor, i1.CheckboxControlValueAccessor, i1.SelectControlValueAccessor, i1.NgControlStatus, i1.MinValidator, i1.MaxValidator, i1.NgModel, MJButtonDirective, i2.PercentPipe], styles: ["/* ============================================================================\n Predictive Studio \u2014 shared panel styles (design-token compliant)\n Maps the mockup design system onto MemberJunction semantic --mj-* tokens.\n Loaded by every PS panel component (styleUrls) under ViewEncapsulation.None,\n so the class names are global within the PS dashboard subtree.\n No hardcoded colors except the intentional categorical node/algorithm palette\n (declared once as --ps-* custom props below) which must stay distinct across\n light/dark to remain readable as diagram accents.\n ============================================================================ */\n\n/* Categorical accents for DAG node types + algorithm chips. These are\n data-visualization colors that must remain distinct regardless of theme\n (allowed exception #3 in the design-token rules). */\n.ps-panel {\n --ps-node-source: #6b7280;\n --ps-node-feature: #2050c8;\n --ps-node-embedding: #7b3ff0;\n --ps-node-target: #1f9d57;\n --ps-node-algorithm: #d98213;\n /* budget-gauge categorical accents (reuse the node palette so light/dark stay distinct) */\n --ps-gauge-cost: var(--ps-node-algorithm);\n --ps-gauge-iterations: var(--ps-node-feature);\n}\n\n.ps-panel {\n display: block;\n height: 100%;\n}\n\n/* ---- generic layout helpers ---- */\n.ps-row { display: flex; gap: 16px; }\n.ps-col { display: flex; flex-direction: column; gap: 16px; }\n.ps-wrap { flex-wrap: wrap; }\n.ps-spacer { flex: 1; }\n.ps-muted { color: var(--mj-text-muted); }\n.ps-small { font-size: 12.5px; }\n.ps-mono { font-family: ui-monospace, 'SF Mono', Menlo, Consolas, monospace; font-size: 12.5px; }\n.ps-section-title {\n font-size: 12px; text-transform: uppercase; letter-spacing: .06em;\n color: var(--mj-text-muted); margin: 4px 0 2px; font-weight: 700;\n}\n\n/* ---- cards ---- */\n.ps-card {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n overflow: hidden;\n}\n.ps-card-head {\n display: flex; align-items: center; gap: 10px;\n padding: 14px 16px; border-bottom: 1px solid var(--mj-border-subtle);\n}\n.ps-card-head h3 { font-size: 14.5px; margin: 0; font-weight: 650; color: var(--mj-text-primary); }\n.ps-card-body { padding: 16px; }\n\n/* ---- KPI tiles ---- */\n.ps-kpi {\n background: var(--mj-bg-surface); border: 1px solid var(--mj-border-default);\n border-radius: 8px; padding: 16px 18px;\n}\n.ps-kpi .label { font-size: 12px; color: var(--mj-text-muted); font-weight: 600; }\n.ps-kpi .val { font-size: 26px; font-weight: 720; letter-spacing: -.02em; margin-top: 2px; color: var(--mj-text-primary); }\n\n/* ---- badges ---- */\n.ps-badge {\n display: inline-flex; align-items: center; gap: 5px;\n padding: 2px 9px; border-radius: 999px; font-size: 11.5px; font-weight: 650; line-height: 1.7;\n}\n.ps-badge.gray { background: var(--mj-bg-surface-sunken); color: var(--mj-text-secondary); }\n.ps-badge.blue { background: var(--mj-status-info-bg); color: var(--mj-status-info-text); }\n.ps-badge.green { background: var(--mj-status-success-bg); color: var(--mj-status-success-text); }\n.ps-badge.amber { background: var(--mj-status-warning-bg); color: var(--mj-status-warning-text); }\n.ps-badge.red { background: var(--mj-status-error-bg); color: var(--mj-status-error-text); }\n.ps-dot { width: 7px; height: 7px; border-radius: 50%; display: inline-block; }\n\n/* recommendation-level chips (the ranking matrix payoff) */\n.ps-lvl {\n display: inline-flex; align-items: center; justify-content: center;\n min-width: 92px; padding: 4px 10px; border-radius: 7px;\n font-weight: 650; font-size: 11.5px; color: var(--mj-text-inverse);\n}\n.ps-lvl-Primary { background: var(--mj-status-success); }\n.ps-lvl-Strong { background: var(--mj-status-info); }\n.ps-lvl-Viable { background: var(--mj-status-warning); }\n.ps-lvl-Weak { background: var(--mj-text-disabled); }\n.ps-lvl-NotRecommended { background: var(--mj-bg-surface-sunken); color: var(--mj-text-muted); }\n\n/* ---- tags ---- */\n.ps-tag {\n display: inline-block; padding: 2px 8px; border-radius: 6px;\n background: var(--mj-bg-surface-sunken); color: var(--mj-text-secondary);\n font-size: 11.5px; font-weight: 600;\n}\n.ps-tag.muted { opacity: .6; }\n.ps-divider { height: 1px; background: var(--mj-border-subtle); margin: 8px 0; }\n\n/* ---- tables ---- */\n.ps-table { width: 100%; border-collapse: collapse; font-size: 13px; }\n.ps-table th {\n text-align: left; font-size: 11.5px; text-transform: uppercase; letter-spacing: .04em;\n color: var(--mj-text-muted); font-weight: 700; padding: 9px 12px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n.ps-table td { padding: 11px 12px; border-bottom: 1px solid var(--mj-border-subtle); color: var(--mj-text-primary); }\n.ps-table tr:hover td { background: var(--mj-bg-surface-hover); }\n.ps-table .num { text-align: right; font-variant-numeric: tabular-nums; }\n\n.ps-rank {\n width: 22px; height: 22px; border-radius: 6px; background: var(--mj-bg-surface-sunken);\n display: inline-grid; place-items: center; font-weight: 700; font-size: 11.5px; color: var(--mj-text-secondary);\n}\n.ps-rank.gold { background: var(--mj-status-warning-bg); color: var(--mj-status-warning-text); }\n\n/* ---- progress bars ---- */\n.ps-bar { height: 8px; border-radius: 999px; background: var(--mj-bg-surface-sunken); overflow: hidden; }\n.ps-bar > span { display: block; height: 100%; border-radius: 999px; background: var(--mj-brand-primary); }\n.ps-bar.warn > span { background: var(--mj-status-warning); }\n.ps-bar.run > span { background: var(--mj-brand-primary); }\n\n.ps-fbar { display: grid; grid-template-columns: minmax(150px, 1.3fr) 2fr 56px; align-items: center; gap: 14px; padding: 8px 0; }\n.ps-fbar + .ps-fbar { border-top: 1px solid var(--mj-border-subtle); }\n.ps-fbar .track { height: 10px; border-radius: var(--mj-radius-full); background: var(--mj-bg-surface-sunken); overflow: hidden; }\n.ps-fbar .track > span { display: block; height: 100%; border-radius: var(--mj-radius-full); background: var(--mj-brand-primary); }\n.ps-fbar .track > span.warn { background: var(--mj-status-warning); }\n.ps-fbar .name { color: var(--mj-text-primary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n.ps-fbar > .ps-mono { text-align: right; color: var(--mj-text-secondary); font-variant-numeric: tabular-nums; }\n\n/* gauge */\n.ps-gauge {\n position: relative; width: 64px; height: 64px; border-radius: 50%; flex: 0 0 auto;\n background: conic-gradient(var(--ps-gauge-color, var(--mj-brand-primary)) calc(var(--ps-p, 40) * 1%), var(--mj-bg-surface-sunken) 0);\n display: grid; place-items: center;\n}\n.ps-gauge::after { content: ''; position: absolute; inset: 9px; background: var(--mj-bg-surface); border-radius: 50%; }\n.ps-gauge .g-val { position: relative; font-weight: 720; font-size: 14px; color: var(--mj-text-primary); }\n\n/* warning / info callouts */\n.ps-callout { display: flex; gap: 11px; padding: 12px 14px; border-radius: 10px; border: 1px solid; }\n.ps-callout.warn { background: var(--mj-status-warning-bg); border-color: var(--mj-status-warning-border); color: var(--mj-status-warning-text); }\n.ps-callout.info { background: var(--mj-status-info-bg); border-color: var(--mj-status-info-border); color: var(--mj-status-info-text); }\n.ps-callout.success { background: var(--mj-status-success-bg); border-color: var(--mj-status-success-border); color: var(--mj-status-success-text); }\n.ps-callout i { font-size: 16px; margin-top: 1px; }\n\n/* lifecycle stepper */\n.ps-stepper { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }\n.ps-step { display: flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 600; color: var(--mj-text-muted); }\n.ps-step .pip {\n width: 22px; height: 22px; border-radius: 50%; border: 2px solid var(--mj-border-strong);\n display: grid; place-items: center; font-size: 11px;\n}\n.ps-step.done { color: var(--mj-status-success-text); }\n.ps-step.done .pip { background: var(--mj-status-success); border-color: var(--mj-status-success); color: var(--mj-text-inverse); }\n.ps-step.curr { color: var(--mj-brand-primary); }\n.ps-step.curr .pip { border-color: var(--mj-brand-primary); color: var(--mj-brand-primary); }\n.ps-step .ln { width: 26px; height: 2px; background: var(--mj-border-strong); }\n\n/* ---- DAG flow canvas ---- */\n.ps-flow {\n position: relative;\n background:\n linear-gradient(var(--mj-border-subtle) 1px, transparent 1px) 0 0 / 22px 22px,\n linear-gradient(90deg, var(--mj-border-subtle) 1px, transparent 1px) 0 0 / 22px 22px,\n var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default); border-radius: 10px;\n min-height: 620px; overflow: hidden;\n}\n.ps-node {\n position: absolute; width: 190px; background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong); border-left-width: 3px; border-radius: 8px;\n cursor: pointer;\n}\n.ps-node .nh {\n display: flex; align-items: center; gap: 8px; padding: 9px 11px;\n border-bottom: 1px solid var(--mj-border-subtle); font-weight: 650; font-size: 12.5px; color: var(--mj-text-primary);\n}\n.ps-node .nh i.tile {\n width: 24px; height: 24px; border-radius: 6px; display: grid; place-items: center;\n color: var(--mj-text-inverse); font-size: 12px; flex: 0 0 auto;\n}\n.ps-node .nh .ps-tag { margin-left: auto; }\n.ps-node .nb { padding: 9px 11px; font-size: 12px; color: var(--mj-text-secondary); }\n.ps-node .nb-row { display: flex; justify-content: space-between; gap: 8px; padding: 2px 0; }\n.ps-node .nb-row .k { color: var(--mj-text-muted); }\n.ps-node.src { border-left-color: var(--ps-node-source); }\n.ps-node.src .nh i.tile { background: var(--ps-node-source); }\n.ps-node.feat { border-left-color: var(--ps-node-feature); }\n.ps-node.feat .nh i.tile { background: var(--ps-node-feature); }\n.ps-node.emb { border-left-color: var(--ps-node-embedding); }\n.ps-node.emb .nh i.tile { background: var(--ps-node-embedding); }\n.ps-node.target { border-left-color: var(--ps-node-target); }\n.ps-node.target .nh i.tile { background: var(--ps-node-target); }\n.ps-node.algo { border-left-color: var(--ps-node-algorithm); }\n.ps-node.algo .nh i.tile { background: var(--ps-node-algorithm); }\n.ps-node.output { border-left-color: var(--mj-status-success); }\n.ps-node.output .nh i.tile { background: var(--mj-status-success); }\n.ps-node.selected {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 18%, transparent);\n}\n.ps-node .port {\n position: absolute; width: 11px; height: 11px; border-radius: 50%;\n background: var(--mj-bg-surface); border: 2px solid var(--mj-brand-primary);\n top: 50%; transform: translateY(-50%);\n}\n.ps-node .port.in { left: -6px; }\n.ps-node .port.out { right: -6px; }\nsvg.ps-edges { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }\nsvg.ps-edges path { stroke: color-mix(in srgb, var(--mj-brand-primary) 45%, transparent); stroke-width: 2; fill: none; }\n\n/* palette chips */\n.ps-pchip {\n display: inline-flex; align-items: center; gap: 7px; padding: 6px 11px; border-radius: 8px;\n border: 1px dashed var(--mj-border-strong); background: var(--mj-bg-surface);\n font-size: 12.5px; font-weight: 600; color: var(--mj-text-secondary); cursor: grab;\n}\n.ps-pchip i { font-size: 12px; color: var(--mj-text-inverse); width: 20px; height: 20px; border-radius: 5px; display: grid; place-items: center; }\n.ps-pchip.s i { background: var(--ps-node-source); }\n.ps-pchip.f i { background: var(--ps-node-feature); }\n.ps-pchip.e i { background: var(--ps-node-embedding); }\n.ps-pchip.t i { background: var(--ps-node-target); }\n.ps-pchip.a i { background: var(--ps-node-algorithm); }\n\n/* segmented control */\n.ps-seg { display: inline-flex; border: 1px solid var(--mj-border-default); border-radius: 8px; overflow: hidden; }\n.ps-seg button {\n border: none; background: var(--mj-bg-surface); color: var(--mj-text-secondary);\n padding: 6px 12px; font-size: 12.5px; font-weight: 600; cursor: pointer;\n border-right: 1px solid var(--mj-border-default);\n}\n.ps-seg button:last-child { border-right: none; }\n.ps-seg button.on { background: var(--mj-brand-primary); color: var(--mj-text-inverse); }\n\n/* field control */\n.ps-field { margin-bottom: 14px; }\n.ps-field > label {\n display: block; font-size: 11px; text-transform: uppercase; letter-spacing: .04em;\n color: var(--mj-text-muted); font-weight: 700; margin-bottom: 6px;\n}\n.ps-input {\n width: 100%; padding: 8px 10px; border: 1px solid var(--mj-border-default);\n border-radius: 6px; font-size: 13px; background: var(--mj-bg-surface); color: var(--mj-text-primary);\n box-sizing: border-box;\n}\n.ps-input:focus { outline: none; border-color: var(--mj-brand-primary); box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 12%, transparent); }\n\n/* loading container */\n.ps-loading { display: flex; align-items: center; justify-content: center; padding: 60px 0; }\n\n/* ---- empty / prompt states ---- */\n.ps-empty {\n display: flex; flex-direction: column; align-items: center; justify-content: center;\n text-align: center; gap: 10px; padding: 56px 24px; color: var(--mj-text-muted);\n}\n.ps-empty .ps-empty-ico {\n width: 60px; height: 60px; border-radius: 16px; display: grid; place-items: center;\n background: var(--mj-bg-surface-sunken); color: var(--mj-text-disabled); font-size: 24px;\n}\n.ps-empty h3 { margin: 4px 0 0; font-size: 16px; font-weight: 650; color: var(--mj-text-secondary); }\n.ps-empty p { margin: 0; max-width: 420px; font-size: 13px; line-height: 1.5; }\n\n/* ---- confirm modal ---- */\n.ps-modal-backdrop {\n position: fixed; inset: 0; z-index: 1000;\n background: var(--mj-bg-overlay);\n display: flex; align-items: center; justify-content: center; padding: 24px;\n}\n.ps-modal {\n width: 100%; max-width: 480px; background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default); border-radius: 14px;\n box-shadow: var(--mj-shadow-lg, var(--mj-shadow-sm)); overflow: hidden;\n}\n.ps-modal-head {\n display: flex; align-items: center; gap: 12px; padding: 18px 20px;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n.ps-modal-head .ico {\n width: 38px; height: 38px; border-radius: 10px; display: grid; place-items: center;\n font-size: 16px; flex: 0 0 auto;\n background: var(--mj-status-info-bg); color: var(--mj-status-info-text);\n}\n.ps-modal-head.warn .ico { background: var(--mj-status-warning-bg); color: var(--mj-status-warning-text); }\n.ps-modal-head.danger .ico { background: var(--mj-status-error-bg); color: var(--mj-status-error-text); }\n.ps-modal-head h3 { margin: 0; font-size: 15.5px; font-weight: 650; color: var(--mj-text-primary); }\n.ps-modal-body { padding: 18px 20px; font-size: 13.5px; line-height: 1.55; color: var(--mj-text-secondary); }\n.ps-modal-body .ps-field { margin-top: 14px; margin-bottom: 0; }\n.ps-modal-foot {\n display: flex; align-items: center; gap: 10px; padding: 14px 20px;\n border-top: 1px solid var(--mj-border-subtle); background: var(--mj-bg-surface-card);\n}\n.ps-modal-foot .ps-spacer { flex: 1; }\n", ".ps-modal-backdrop {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.55);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 9999;\n backdrop-filter: blur(2px);\n}\n\n.ps-wizard-dialog {\n width: 920px;\n max-width: 95vw;\n max-height: 90vh;\n background: var(--mj-bg-surface-card);\n border-radius: var(--mj-radius-xl, 12px);\n border: 1px solid var(--mj-border-default);\n box-shadow: var(--mj-shadow-2xl);\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n.ps-wizard-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n}\n\n.ps-wizard-header-title {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.ps-wizard-header-title i {\n font-size: 24px;\n color: var(--mj-brand-primary);\n}\n\n.ps-wizard-header-title h2 {\n margin: 0;\n font-size: 1.15rem;\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.ps-wizard-subtitle {\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n}\n\n.ps-wizard-close {\n background: transparent;\n border: none;\n cursor: pointer;\n padding: 6px 8px;\n border-radius: 6px;\n color: var(--mj-text-muted);\n}\n\n.ps-wizard-close:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n.ps-wizard-stepper {\n display: flex;\n align-items: center;\n padding: 12px 20px;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n gap: 8px;\n}\n\n.ps-step-tab {\n display: flex;\n align-items: center;\n gap: 8px;\n background: transparent;\n border: none;\n cursor: pointer;\n padding: 6px 12px;\n border-radius: var(--mj-radius-md);\n color: var(--mj-text-muted);\n font-size: var(--mj-text-sm);\n font-weight: 500;\n transition: all 0.15s;\n}\n\n.ps-step-tab .step-num {\n width: 22px;\n height: 22px;\n border-radius: 50%;\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-muted);\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 11px;\n font-weight: 700;\n}\n\n.ps-step-tab.active {\n color: var(--mj-brand-primary);\n font-weight: 600;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.ps-step-tab.active .step-num {\n background: var(--mj-brand-primary);\n color: white;\n}\n\n.ps-step-tab.done .step-num {\n background: var(--mj-status-success-bg, #e6f4ea);\n color: var(--mj-status-success, #137333);\n}\n\n.step-line {\n flex: 1;\n height: 2px;\n background: var(--mj-border-default);\n}\n\n.ps-wizard-body {\n flex: 1;\n min-height: 0;\n overflow-y: auto;\n padding: 20px;\n}\n\n.ps-step-content {\n display: flex;\n flex-direction: column;\n gap: 14px;\n}\n\n.ps-grid-2 {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 14px;\n}\n\n.ps-grid-3 {\n display: grid;\n grid-template-columns: 1fr 1fr 1fr;\n gap: 14px;\n}\n\n.ps-field {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.ps-field label {\n font-size: var(--mj-text-xs);\n font-weight: 600;\n color: var(--mj-text-secondary);\n}\n\n.ps-field label .req {\n color: var(--mj-status-error, #d93025);\n}\n\n.as-of-box {\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n margin-top: 6px;\n}\n\n.feat-toolbar {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n}\n\n.feat-search {\n position: relative;\n flex: 1;\n}\n\n.feat-search i {\n position: absolute;\n left: 10px;\n top: 50%;\n transform: translateY(-50%);\n color: var(--mj-text-muted);\n}\n\n.feat-search input {\n padding-left: 32px;\n width: 100%;\n}\n\n.feat-actions {\n display: flex;\n gap: 6px;\n}\n\n.feat-stats {\n display: flex;\n gap: 18px;\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n padding: 4px 2px;\n}\n\n.feat-table-wrap {\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n max-height: 320px;\n overflow-y: auto;\n}\n\n.feat-table {\n width: 100%;\n border-collapse: collapse;\n font-size: var(--mj-text-sm);\n}\n\n.feat-table th {\n position: sticky;\n top: 0;\n background: var(--mj-bg-surface);\n z-index: 1;\n padding: 8px 12px;\n text-align: left;\n border-bottom: 1px solid var(--mj-border-default);\n font-size: var(--mj-text-xs);\n font-weight: 700;\n color: var(--mj-text-muted);\n}\n\n.feat-table td {\n padding: 8px 12px;\n border-bottom: 1px solid var(--mj-border-default);\n color: var(--mj-text-primary);\n}\n\n.feat-table tr:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.feat-table tr.deny-row {\n background: color-mix(in srgb, var(--mj-status-error) 6%, transparent);\n text-decoration: line-through;\n color: var(--mj-text-muted);\n}\n\n.feat-table tr.target-row {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n}\n\n.ps-deny-toggle {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 3px 8px;\n font-size: 11px;\n border-radius: 4px;\n border: 1px solid var(--mj-border-default);\n background: transparent;\n cursor: pointer;\n color: var(--mj-text-secondary);\n}\n\n.ps-deny-toggle.denied {\n background: var(--mj-status-error-bg, #fce8e6);\n border-color: var(--mj-status-error-border, #fad2cf);\n color: var(--mj-status-error, #c5221f);\n font-weight: 600;\n}\n\n.slider-row {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.slider-row input[type=\"range\"] {\n width: 100%;\n}\n\n.recipe-card {\n display: flex;\n gap: 14px;\n padding: 14px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n}\n\n.recipe-icon {\n width: 42px;\n height: 42px;\n border-radius: var(--mj-radius-md);\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, transparent);\n color: var(--mj-brand-primary);\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 18px;\n flex: none;\n}\n\n.recipe-details {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.recipe-details h4 {\n margin: 0;\n font-size: var(--mj-text-sm);\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.ps-wizard-footer {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 14px 20px;\n border-top: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n}\n"], encapsulation: 2 });
|
|
1026
|
+
}
|
|
1027
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(PSPipelineWizardComponent, [{
|
|
1028
|
+
type: Component,
|
|
1029
|
+
args: [{ standalone: true, selector: 'ps-pipeline-wizard', imports: [CommonModule, FormsModule, MJButtonDirective], encapsulation: ViewEncapsulation.None, template: `
|
|
1030
|
+
<div class="ps-modal-backdrop" (click)="onBackdropClick($event)">
|
|
1031
|
+
<div class="ps-modal-dialog ps-wizard-dialog" role="dialog" aria-modal="true" data-testid="ps-pipeline-wizard">
|
|
1032
|
+
<!-- Header -->
|
|
1033
|
+
<div class="ps-wizard-header">
|
|
1034
|
+
<div class="ps-wizard-header-title">
|
|
1035
|
+
<i class="fa-solid fa-wand-magic-sparkles"></i>
|
|
1036
|
+
<div>
|
|
1037
|
+
<h2>{{ isEditing ? 'Edit Training Pipeline' : 'New ML Training Pipeline' }}</h2>
|
|
1038
|
+
<span class="ps-wizard-subtitle">Step-by-step pipeline configuration with leakage guard</span>
|
|
1039
|
+
</div>
|
|
1040
|
+
</div>
|
|
1041
|
+
<button class="ps-wizard-close" (click)="cancel()" aria-label="Close wizard">
|
|
1042
|
+
<i class="fa-solid fa-xmark"></i>
|
|
1043
|
+
</button>
|
|
1044
|
+
</div>
|
|
1045
|
+
|
|
1046
|
+
<!-- Step Indicator Strip -->
|
|
1047
|
+
<div class="ps-wizard-stepper">
|
|
1048
|
+
<button class="ps-step-tab" [class.active]="currentStep === 'goal'" [class.done]="isStepDone('goal')" (click)="goToStep('goal')">
|
|
1049
|
+
<span class="step-num">1</span>
|
|
1050
|
+
<span class="step-label">Goal & Target</span>
|
|
1051
|
+
</button>
|
|
1052
|
+
<div class="step-line"></div>
|
|
1053
|
+
<button class="ps-step-tab" [class.active]="currentStep === 'features'" [class.done]="isStepDone('features')" (click)="goToStep('features')">
|
|
1054
|
+
<span class="step-num">2</span>
|
|
1055
|
+
<span class="step-label">Features & Leakage</span>
|
|
1056
|
+
</button>
|
|
1057
|
+
<div class="step-line"></div>
|
|
1058
|
+
<button class="ps-step-tab" [class.active]="currentStep === 'preprocessing'" [class.done]="isStepDone('preprocessing')" (click)="goToStep('preprocessing')">
|
|
1059
|
+
<span class="step-num">3</span>
|
|
1060
|
+
<span class="step-label">Preprocessing</span>
|
|
1061
|
+
</button>
|
|
1062
|
+
<div class="step-line"></div>
|
|
1063
|
+
<button class="ps-step-tab" [class.active]="currentStep === 'algorithm'" [class.done]="isStepDone('algorithm')" (click)="goToStep('algorithm')">
|
|
1064
|
+
<span class="step-num">4</span>
|
|
1065
|
+
<span class="step-label">Algorithm & Split</span>
|
|
1066
|
+
</button>
|
|
1067
|
+
</div>
|
|
1068
|
+
|
|
1069
|
+
<!-- Step Content Area -->
|
|
1070
|
+
<div class="ps-wizard-body">
|
|
1071
|
+
<!-- Step 1: Goal & Target -->
|
|
1072
|
+
@if (currentStep === 'goal') {
|
|
1073
|
+
<div class="ps-step-content" data-testid="ps-wizard-step-goal">
|
|
1074
|
+
<div class="ps-field">
|
|
1075
|
+
<label for="pipeline-name">Pipeline Name <span class="req">*</span></label>
|
|
1076
|
+
<input id="pipeline-name" class="mj-input" type="text" [(ngModel)]="pipelineName" placeholder="e.g. Member Renewal Risk v1" />
|
|
1077
|
+
</div>
|
|
1078
|
+
|
|
1079
|
+
<div class="ps-field">
|
|
1080
|
+
<label for="pipeline-desc">Description</label>
|
|
1081
|
+
<textarea id="pipeline-desc" class="mj-textarea" rows="2" [(ngModel)]="pipelineDescription" placeholder="Predicts whether active members will renew before their period ends."></textarea>
|
|
1082
|
+
</div>
|
|
1083
|
+
|
|
1084
|
+
<div class="ps-grid-2">
|
|
1085
|
+
<div class="ps-field">
|
|
1086
|
+
<label for="target-entity">Target Entity <span class="req">*</span></label>
|
|
1087
|
+
<select id="target-entity" class="mj-input" [ngModel]="selectedEntityId" (ngModelChange)="onEntitySelected($event)">
|
|
1088
|
+
<option [value]="''" disabled>-- Select Entity --</option>
|
|
1089
|
+
@for (ent of availableEntities; track ent.ID) {
|
|
1090
|
+
<option [value]="ent.ID">{{ ent.Name }} ({{ ent.BaseView || ent.BaseTable }})</option>
|
|
1091
|
+
}
|
|
1092
|
+
</select>
|
|
1093
|
+
</div>
|
|
1094
|
+
|
|
1095
|
+
<div class="ps-field">
|
|
1096
|
+
<label for="target-variable">Target Variable (Label Column) <span class="req">*</span></label>
|
|
1097
|
+
<select id="target-variable" class="mj-input" [(ngModel)]="targetVariable" [disabled]="!selectedEntity">
|
|
1098
|
+
<option [value]="''" disabled>-- Select Label Field --</option>
|
|
1099
|
+
@for (f of availableFields; track f.Name) {
|
|
1100
|
+
<option [value]="f.Name">{{ f.Name }} ({{ f.Type }})</option>
|
|
1101
|
+
}
|
|
1102
|
+
</select>
|
|
1103
|
+
</div>
|
|
1104
|
+
</div>
|
|
1105
|
+
|
|
1106
|
+
<div class="ps-grid-2">
|
|
1107
|
+
<div class="ps-field">
|
|
1108
|
+
<label for="problem-type">Problem Type</label>
|
|
1109
|
+
<select id="problem-type" class="mj-input" [(ngModel)]="problemType" (ngModelChange)="onProblemTypeChange()">
|
|
1110
|
+
<option value="classification">Classification (Predict Categorical / Binary Outcome)</option>
|
|
1111
|
+
<option value="regression">Regression (Predict Numeric Continuous Value)</option>
|
|
1112
|
+
</select>
|
|
1113
|
+
</div>
|
|
1114
|
+
|
|
1115
|
+
<div class="ps-field">
|
|
1116
|
+
<label for="eval-metric">Primary Evaluation Metric</label>
|
|
1117
|
+
<select id="eval-metric" class="mj-input" [(ngModel)]="evaluationMetric">
|
|
1118
|
+
@for (m of availableMetrics; track m) {
|
|
1119
|
+
<option [value]="m">{{ m }}</option>
|
|
1120
|
+
}
|
|
1121
|
+
</select>
|
|
1122
|
+
</div>
|
|
1123
|
+
</div>
|
|
1124
|
+
|
|
1125
|
+
<div class="ps-card as-of-box">
|
|
1126
|
+
<div class="ps-card-head">
|
|
1127
|
+
<i class="fa-solid fa-clock-rotate-left"></i>
|
|
1128
|
+
<h4>Point-in-Time Cutoff (Temporal Leakage Guard)</h4>
|
|
1129
|
+
</div>
|
|
1130
|
+
<div class="ps-card-body">
|
|
1131
|
+
<div class="ps-grid-2">
|
|
1132
|
+
<div class="ps-field">
|
|
1133
|
+
<label>Cutoff Mode</label>
|
|
1134
|
+
<select class="mj-input" [(ngModel)]="asOfMode">
|
|
1135
|
+
<option value="none">None (Static Cross-Sectional Data)</option>
|
|
1136
|
+
<option value="column">Date Column on Entity</option>
|
|
1137
|
+
<option value="offset">Relative Days Offset before Event</option>
|
|
1138
|
+
</select>
|
|
1139
|
+
</div>
|
|
1140
|
+
|
|
1141
|
+
@if (asOfMode === 'column') {
|
|
1142
|
+
<div class="ps-field">
|
|
1143
|
+
<label>Decision Date Field</label>
|
|
1144
|
+
<select class="mj-input" [(ngModel)]="asOfColumn">
|
|
1145
|
+
<option [value]="''">-- Select Date Field --</option>
|
|
1146
|
+
@for (f of dateFields; track f.Name) {
|
|
1147
|
+
<option [value]="f.Name">{{ f.Name }}</option>
|
|
1148
|
+
}
|
|
1149
|
+
</select>
|
|
1150
|
+
</div>
|
|
1151
|
+
}
|
|
1152
|
+
|
|
1153
|
+
@if (asOfMode === 'offset') {
|
|
1154
|
+
<div class="ps-field">
|
|
1155
|
+
<label>Offset Days before Outcome</label>
|
|
1156
|
+
<input class="mj-input" type="number" min="1" [(ngModel)]="asOfOffsetDays" />
|
|
1157
|
+
</div>
|
|
1158
|
+
}
|
|
1159
|
+
</div>
|
|
1160
|
+
</div>
|
|
1161
|
+
</div>
|
|
1162
|
+
</div>
|
|
1163
|
+
}
|
|
1164
|
+
|
|
1165
|
+
<!-- Step 2: Feature Selection & Leakage Guard -->
|
|
1166
|
+
@if (currentStep === 'features') {
|
|
1167
|
+
<div class="ps-step-content" data-testid="ps-wizard-step-features">
|
|
1168
|
+
<div class="feat-toolbar">
|
|
1169
|
+
<div class="feat-search">
|
|
1170
|
+
<i class="fa-solid fa-magnifying-glass"></i>
|
|
1171
|
+
<input class="mj-input" type="text" [(ngModel)]="fieldSearchFilter" placeholder="Filter fields by name or type…" />
|
|
1172
|
+
</div>
|
|
1173
|
+
<div class="feat-actions">
|
|
1174
|
+
<button mjButton variant="secondary" size="sm" (click)="selectAllFields(true)">Select All</button>
|
|
1175
|
+
<button mjButton variant="secondary" size="sm" (click)="selectAllFields(false)">Deselect All</button>
|
|
1176
|
+
<button mjButton variant="secondary" size="sm" (click)="excludeAuditFields()">Exclude IDs & Timestamps</button>
|
|
1177
|
+
</div>
|
|
1178
|
+
</div>
|
|
1179
|
+
|
|
1180
|
+
<div class="feat-stats">
|
|
1181
|
+
<span>Selected: <strong>{{ selectedFeaturesCount }}</strong> features</span>
|
|
1182
|
+
<span>Leakage Deny-List: <strong class="text-danger">{{ denyListCount }}</strong> excluded fields</span>
|
|
1183
|
+
</div>
|
|
1184
|
+
|
|
1185
|
+
<div class="feat-table-wrap">
|
|
1186
|
+
<table class="ps-table feat-table">
|
|
1187
|
+
<thead>
|
|
1188
|
+
<tr>
|
|
1189
|
+
<th style="width: 40px;">Use</th>
|
|
1190
|
+
<th>Field Name</th>
|
|
1191
|
+
<th>Data Type</th>
|
|
1192
|
+
<th>Nullable</th>
|
|
1193
|
+
<th style="width: 140px; text-align: center;">Leakage Guard</th>
|
|
1194
|
+
</tr>
|
|
1195
|
+
</thead>
|
|
1196
|
+
<tbody>
|
|
1197
|
+
@for (item of filteredFieldItems; track item.field.Name) {
|
|
1198
|
+
<tr [class.target-row]="item.isTarget" [class.deny-row]="item.isDenyList">
|
|
1199
|
+
<td>
|
|
1200
|
+
<input type="checkbox" [(ngModel)]="item.selected" [disabled]="item.isTarget || item.isDenyList" />
|
|
1201
|
+
</td>
|
|
1202
|
+
<td>
|
|
1203
|
+
<strong>{{ item.field.Name }}</strong>
|
|
1204
|
+
@if (item.isTarget) {
|
|
1205
|
+
<span class="ps-badge info" style="margin-left: 6px;">Target Label</span>
|
|
1206
|
+
}
|
|
1207
|
+
</td>
|
|
1208
|
+
<td><code>{{ item.field.Type }}</code></td>
|
|
1209
|
+
<td>{{ item.field.AllowsNull ? 'Yes' : 'No' }}</td>
|
|
1210
|
+
<td style="text-align: center;">
|
|
1211
|
+
@if (!item.isTarget) {
|
|
1212
|
+
<button class="ps-deny-toggle" [class.denied]="item.isDenyList" (click)="toggleDenyList(item)" title="Add to leakage deny-list">
|
|
1213
|
+
<i class="fa-solid" [class.fa-shield-halved]="item.isDenyList" [class.fa-shield]="!item.isDenyList"></i>
|
|
1214
|
+
{{ item.isDenyList ? 'Denied' : 'Allow' }}
|
|
1215
|
+
</button>
|
|
1216
|
+
}
|
|
1217
|
+
</td>
|
|
1218
|
+
</tr>
|
|
1219
|
+
}
|
|
1220
|
+
</tbody>
|
|
1221
|
+
</table>
|
|
1222
|
+
</div>
|
|
1223
|
+
|
|
1224
|
+
<div class="ps-field" style="margin-top: 14px;">
|
|
1225
|
+
<label>Single-Feature Dominance Threshold: <strong>{{ dominanceThreshold | percent }}</strong></label>
|
|
1226
|
+
<div class="slider-row">
|
|
1227
|
+
<input type="range" min="0.5" max="0.99" step="0.01" [(ngModel)]="dominanceThreshold" />
|
|
1228
|
+
<span class="ps-muted ps-small">Warns and holds model if any single feature accounts for > {{ dominanceThreshold | percent }} of total importance.</span>
|
|
1229
|
+
</div>
|
|
1230
|
+
</div>
|
|
1231
|
+
</div>
|
|
1232
|
+
}
|
|
1233
|
+
|
|
1234
|
+
<!-- Step 3: Preprocessing Recipe -->
|
|
1235
|
+
@if (currentStep === 'preprocessing') {
|
|
1236
|
+
<div class="ps-step-content" data-testid="ps-wizard-step-preprocessing">
|
|
1237
|
+
<div class="recipe-card">
|
|
1238
|
+
<div class="recipe-icon"><i class="fa-solid fa-table-cells"></i></div>
|
|
1239
|
+
<div class="recipe-details">
|
|
1240
|
+
<h4>Categorical Encoding</h4>
|
|
1241
|
+
<p class="ps-small ps-muted">Converts text and discrete categoricals into numerical representations.</p>
|
|
1242
|
+
<select class="mj-input" [(ngModel)]="categoricalEncoding">
|
|
1243
|
+
<option value="onehot">One-Hot Encoding (Recommended for cardinality < 50)</option>
|
|
1244
|
+
<option value="none">Pass-Through / Native Algorithm Handling</option>
|
|
1245
|
+
</select>
|
|
1246
|
+
</div>
|
|
1247
|
+
</div>
|
|
1248
|
+
|
|
1249
|
+
<div class="recipe-card">
|
|
1250
|
+
<div class="recipe-icon"><i class="fa-solid fa-fill-drip"></i></div>
|
|
1251
|
+
<div class="recipe-details">
|
|
1252
|
+
<h4>Missing Value Imputation</h4>
|
|
1253
|
+
<p class="ps-small ps-muted">Strategy for filling null or missing entries in training matrices.</p>
|
|
1254
|
+
<select class="mj-input" [(ngModel)]="imputeStrategy">
|
|
1255
|
+
<option value="median">Median (Robust against numeric outliers)</option>
|
|
1256
|
+
<option value="mean">Mean (Standard arithmetic average)</option>
|
|
1257
|
+
<option value="mode">Mode (Most frequent category)</option>
|
|
1258
|
+
<option value="constant">Constant (Zero / Missing category token)</option>
|
|
1259
|
+
</select>
|
|
1260
|
+
</div>
|
|
1261
|
+
</div>
|
|
1262
|
+
|
|
1263
|
+
<div class="recipe-card">
|
|
1264
|
+
<div class="recipe-icon"><i class="fa-solid fa-ruler-combined"></i></div>
|
|
1265
|
+
<div class="recipe-details">
|
|
1266
|
+
<h4>Numeric Standardization</h4>
|
|
1267
|
+
<p class="ps-small ps-muted">Scales numeric features to prevent large magnitudes from dominating.</p>
|
|
1268
|
+
<select class="mj-input" [(ngModel)]="standardizeStrategy">
|
|
1269
|
+
<option value="standard">Standard Scaling (Z-score: mean 0, variance 1)</option>
|
|
1270
|
+
<option value="minmax">Min-Max Scaling (Bounding values to [0, 1])</option>
|
|
1271
|
+
<option value="none">None (Native tree-based scaling)</option>
|
|
1272
|
+
</select>
|
|
1273
|
+
</div>
|
|
1274
|
+
</div>
|
|
1275
|
+
</div>
|
|
1276
|
+
}
|
|
1277
|
+
|
|
1278
|
+
<!-- Step 4: Algorithm & Validation Split -->
|
|
1279
|
+
@if (currentStep === 'algorithm') {
|
|
1280
|
+
<div class="ps-step-content" data-testid="ps-wizard-step-algorithm">
|
|
1281
|
+
<div class="ps-field">
|
|
1282
|
+
<label for="algorithm-select">Algorithm <span class="req">*</span></label>
|
|
1283
|
+
<select id="algorithm-select" class="mj-input" [ngModel]="selectedAlgorithmId" (ngModelChange)="onAlgorithmSelected($event)">
|
|
1284
|
+
@for (a of availableAlgorithms; track a.ID) {
|
|
1285
|
+
<option [value]="a.ID">{{ a.Name }} ({{ a.DriverClass }})</option>
|
|
1286
|
+
}
|
|
1287
|
+
</select>
|
|
1288
|
+
</div>
|
|
1289
|
+
|
|
1290
|
+
<!-- Hyperparameter controls -->
|
|
1291
|
+
<div class="ps-card" style="margin: 12px 0;">
|
|
1292
|
+
<div class="ps-card-head">
|
|
1293
|
+
<i class="fa-solid fa-sliders"></i>
|
|
1294
|
+
<h4>Algorithm Hyperparameters</h4>
|
|
1295
|
+
</div>
|
|
1296
|
+
<div class="ps-card-body">
|
|
1297
|
+
<div class="ps-grid-3">
|
|
1298
|
+
<div class="ps-field">
|
|
1299
|
+
<label>Estimators (Trees)</label>
|
|
1300
|
+
<input class="mj-input" type="number" min="10" max="1000" step="10" [(ngModel)]="hyperparamEstimators" />
|
|
1301
|
+
</div>
|
|
1302
|
+
<div class="ps-field">
|
|
1303
|
+
<label>Max Depth</label>
|
|
1304
|
+
<input class="mj-input" type="number" min="1" max="20" [(ngModel)]="hyperparamMaxDepth" />
|
|
1305
|
+
</div>
|
|
1306
|
+
<div class="ps-field">
|
|
1307
|
+
<label>Learning Rate</label>
|
|
1308
|
+
<input class="mj-input" type="number" min="0.001" max="1" step="0.01" [(ngModel)]="hyperparamLearningRate" />
|
|
1309
|
+
</div>
|
|
1310
|
+
</div>
|
|
1311
|
+
</div>
|
|
1312
|
+
</div>
|
|
1313
|
+
|
|
1314
|
+
<!-- Validation strategy -->
|
|
1315
|
+
<div class="ps-card">
|
|
1316
|
+
<div class="ps-card-head">
|
|
1317
|
+
<i class="fa-solid fa-scissors"></i>
|
|
1318
|
+
<h4>Validation Strategy</h4>
|
|
1319
|
+
</div>
|
|
1320
|
+
<div class="ps-card-body">
|
|
1321
|
+
<div class="ps-grid-2">
|
|
1322
|
+
<div class="ps-field">
|
|
1323
|
+
<label>Strategy</label>
|
|
1324
|
+
<select class="mj-input" [(ngModel)]="validationStrategyType">
|
|
1325
|
+
<option value="train_test_split">Train / Test Split</option>
|
|
1326
|
+
<option value="kfold">K-Fold Cross-Validation</option>
|
|
1327
|
+
</select>
|
|
1328
|
+
</div>
|
|
1329
|
+
|
|
1330
|
+
@if (validationStrategyType === 'train_test_split') {
|
|
1331
|
+
<div class="ps-field">
|
|
1332
|
+
<label>Test Holdout Percentage: <strong>{{ testSplitRatio | percent }}</strong></label>
|
|
1333
|
+
<input type="range" min="0.1" max="0.4" step="0.05" [(ngModel)]="testSplitRatio" />
|
|
1334
|
+
</div>
|
|
1335
|
+
} @else {
|
|
1336
|
+
<div class="ps-field">
|
|
1337
|
+
<label>Number of Folds (K)</label>
|
|
1338
|
+
<input class="mj-input" type="number" min="2" max="10" [(ngModel)]="kFolds" />
|
|
1339
|
+
</div>
|
|
1340
|
+
}
|
|
1341
|
+
</div>
|
|
1342
|
+
</div>
|
|
1343
|
+
</div>
|
|
1344
|
+
</div>
|
|
1345
|
+
}
|
|
1346
|
+
</div>
|
|
1347
|
+
|
|
1348
|
+
<!-- Footer Actions -->
|
|
1349
|
+
<div class="ps-wizard-footer">
|
|
1350
|
+
<button mjButton variant="secondary" size="sm" (click)="cancel()">Cancel</button>
|
|
1351
|
+
<span class="ps-spacer"></span>
|
|
1352
|
+
|
|
1353
|
+
@if (currentStep !== 'goal') {
|
|
1354
|
+
<button mjButton variant="secondary" size="sm" (click)="prevStep()">
|
|
1355
|
+
<i class="fa-solid fa-arrow-left"></i> Back
|
|
1356
|
+
</button>
|
|
1357
|
+
}
|
|
1358
|
+
|
|
1359
|
+
@if (currentStep !== 'algorithm') {
|
|
1360
|
+
<button mjButton variant="primary" size="sm" (click)="nextStep()" [disabled]="!canProceed()">
|
|
1361
|
+
Next <i class="fa-solid fa-arrow-right"></i>
|
|
1362
|
+
</button>
|
|
1363
|
+
} @else {
|
|
1364
|
+
<button mjButton variant="secondary" size="sm" (click)="saveDraft()" [disabled]="busy || !canSave()">
|
|
1365
|
+
<i class="fa-solid fa-floppy-disk"></i> Save Draft
|
|
1366
|
+
</button>
|
|
1367
|
+
<button mjButton variant="primary" size="sm" (click)="saveAndTrain()" [disabled]="busy || !canSave()">
|
|
1368
|
+
<i class="fa-solid fa-play"></i> Save & Train Now
|
|
1369
|
+
</button>
|
|
1370
|
+
}
|
|
1371
|
+
</div>
|
|
1372
|
+
</div>
|
|
1373
|
+
</div>
|
|
1374
|
+
`, styles: ["/* ============================================================================\n Predictive Studio \u2014 shared panel styles (design-token compliant)\n Maps the mockup design system onto MemberJunction semantic --mj-* tokens.\n Loaded by every PS panel component (styleUrls) under ViewEncapsulation.None,\n so the class names are global within the PS dashboard subtree.\n No hardcoded colors except the intentional categorical node/algorithm palette\n (declared once as --ps-* custom props below) which must stay distinct across\n light/dark to remain readable as diagram accents.\n ============================================================================ */\n\n/* Categorical accents for DAG node types + algorithm chips. These are\n data-visualization colors that must remain distinct regardless of theme\n (allowed exception #3 in the design-token rules). */\n.ps-panel {\n --ps-node-source: #6b7280;\n --ps-node-feature: #2050c8;\n --ps-node-embedding: #7b3ff0;\n --ps-node-target: #1f9d57;\n --ps-node-algorithm: #d98213;\n /* budget-gauge categorical accents (reuse the node palette so light/dark stay distinct) */\n --ps-gauge-cost: var(--ps-node-algorithm);\n --ps-gauge-iterations: var(--ps-node-feature);\n}\n\n.ps-panel {\n display: block;\n height: 100%;\n}\n\n/* ---- generic layout helpers ---- */\n.ps-row { display: flex; gap: 16px; }\n.ps-col { display: flex; flex-direction: column; gap: 16px; }\n.ps-wrap { flex-wrap: wrap; }\n.ps-spacer { flex: 1; }\n.ps-muted { color: var(--mj-text-muted); }\n.ps-small { font-size: 12.5px; }\n.ps-mono { font-family: ui-monospace, 'SF Mono', Menlo, Consolas, monospace; font-size: 12.5px; }\n.ps-section-title {\n font-size: 12px; text-transform: uppercase; letter-spacing: .06em;\n color: var(--mj-text-muted); margin: 4px 0 2px; font-weight: 700;\n}\n\n/* ---- cards ---- */\n.ps-card {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n overflow: hidden;\n}\n.ps-card-head {\n display: flex; align-items: center; gap: 10px;\n padding: 14px 16px; border-bottom: 1px solid var(--mj-border-subtle);\n}\n.ps-card-head h3 { font-size: 14.5px; margin: 0; font-weight: 650; color: var(--mj-text-primary); }\n.ps-card-body { padding: 16px; }\n\n/* ---- KPI tiles ---- */\n.ps-kpi {\n background: var(--mj-bg-surface); border: 1px solid var(--mj-border-default);\n border-radius: 8px; padding: 16px 18px;\n}\n.ps-kpi .label { font-size: 12px; color: var(--mj-text-muted); font-weight: 600; }\n.ps-kpi .val { font-size: 26px; font-weight: 720; letter-spacing: -.02em; margin-top: 2px; color: var(--mj-text-primary); }\n\n/* ---- badges ---- */\n.ps-badge {\n display: inline-flex; align-items: center; gap: 5px;\n padding: 2px 9px; border-radius: 999px; font-size: 11.5px; font-weight: 650; line-height: 1.7;\n}\n.ps-badge.gray { background: var(--mj-bg-surface-sunken); color: var(--mj-text-secondary); }\n.ps-badge.blue { background: var(--mj-status-info-bg); color: var(--mj-status-info-text); }\n.ps-badge.green { background: var(--mj-status-success-bg); color: var(--mj-status-success-text); }\n.ps-badge.amber { background: var(--mj-status-warning-bg); color: var(--mj-status-warning-text); }\n.ps-badge.red { background: var(--mj-status-error-bg); color: var(--mj-status-error-text); }\n.ps-dot { width: 7px; height: 7px; border-radius: 50%; display: inline-block; }\n\n/* recommendation-level chips (the ranking matrix payoff) */\n.ps-lvl {\n display: inline-flex; align-items: center; justify-content: center;\n min-width: 92px; padding: 4px 10px; border-radius: 7px;\n font-weight: 650; font-size: 11.5px; color: var(--mj-text-inverse);\n}\n.ps-lvl-Primary { background: var(--mj-status-success); }\n.ps-lvl-Strong { background: var(--mj-status-info); }\n.ps-lvl-Viable { background: var(--mj-status-warning); }\n.ps-lvl-Weak { background: var(--mj-text-disabled); }\n.ps-lvl-NotRecommended { background: var(--mj-bg-surface-sunken); color: var(--mj-text-muted); }\n\n/* ---- tags ---- */\n.ps-tag {\n display: inline-block; padding: 2px 8px; border-radius: 6px;\n background: var(--mj-bg-surface-sunken); color: var(--mj-text-secondary);\n font-size: 11.5px; font-weight: 600;\n}\n.ps-tag.muted { opacity: .6; }\n.ps-divider { height: 1px; background: var(--mj-border-subtle); margin: 8px 0; }\n\n/* ---- tables ---- */\n.ps-table { width: 100%; border-collapse: collapse; font-size: 13px; }\n.ps-table th {\n text-align: left; font-size: 11.5px; text-transform: uppercase; letter-spacing: .04em;\n color: var(--mj-text-muted); font-weight: 700; padding: 9px 12px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n.ps-table td { padding: 11px 12px; border-bottom: 1px solid var(--mj-border-subtle); color: var(--mj-text-primary); }\n.ps-table tr:hover td { background: var(--mj-bg-surface-hover); }\n.ps-table .num { text-align: right; font-variant-numeric: tabular-nums; }\n\n.ps-rank {\n width: 22px; height: 22px; border-radius: 6px; background: var(--mj-bg-surface-sunken);\n display: inline-grid; place-items: center; font-weight: 700; font-size: 11.5px; color: var(--mj-text-secondary);\n}\n.ps-rank.gold { background: var(--mj-status-warning-bg); color: var(--mj-status-warning-text); }\n\n/* ---- progress bars ---- */\n.ps-bar { height: 8px; border-radius: 999px; background: var(--mj-bg-surface-sunken); overflow: hidden; }\n.ps-bar > span { display: block; height: 100%; border-radius: 999px; background: var(--mj-brand-primary); }\n.ps-bar.warn > span { background: var(--mj-status-warning); }\n.ps-bar.run > span { background: var(--mj-brand-primary); }\n\n.ps-fbar { display: grid; grid-template-columns: minmax(150px, 1.3fr) 2fr 56px; align-items: center; gap: 14px; padding: 8px 0; }\n.ps-fbar + .ps-fbar { border-top: 1px solid var(--mj-border-subtle); }\n.ps-fbar .track { height: 10px; border-radius: var(--mj-radius-full); background: var(--mj-bg-surface-sunken); overflow: hidden; }\n.ps-fbar .track > span { display: block; height: 100%; border-radius: var(--mj-radius-full); background: var(--mj-brand-primary); }\n.ps-fbar .track > span.warn { background: var(--mj-status-warning); }\n.ps-fbar .name { color: var(--mj-text-primary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n.ps-fbar > .ps-mono { text-align: right; color: var(--mj-text-secondary); font-variant-numeric: tabular-nums; }\n\n/* gauge */\n.ps-gauge {\n position: relative; width: 64px; height: 64px; border-radius: 50%; flex: 0 0 auto;\n background: conic-gradient(var(--ps-gauge-color, var(--mj-brand-primary)) calc(var(--ps-p, 40) * 1%), var(--mj-bg-surface-sunken) 0);\n display: grid; place-items: center;\n}\n.ps-gauge::after { content: ''; position: absolute; inset: 9px; background: var(--mj-bg-surface); border-radius: 50%; }\n.ps-gauge .g-val { position: relative; font-weight: 720; font-size: 14px; color: var(--mj-text-primary); }\n\n/* warning / info callouts */\n.ps-callout { display: flex; gap: 11px; padding: 12px 14px; border-radius: 10px; border: 1px solid; }\n.ps-callout.warn { background: var(--mj-status-warning-bg); border-color: var(--mj-status-warning-border); color: var(--mj-status-warning-text); }\n.ps-callout.info { background: var(--mj-status-info-bg); border-color: var(--mj-status-info-border); color: var(--mj-status-info-text); }\n.ps-callout.success { background: var(--mj-status-success-bg); border-color: var(--mj-status-success-border); color: var(--mj-status-success-text); }\n.ps-callout i { font-size: 16px; margin-top: 1px; }\n\n/* lifecycle stepper */\n.ps-stepper { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }\n.ps-step { display: flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 600; color: var(--mj-text-muted); }\n.ps-step .pip {\n width: 22px; height: 22px; border-radius: 50%; border: 2px solid var(--mj-border-strong);\n display: grid; place-items: center; font-size: 11px;\n}\n.ps-step.done { color: var(--mj-status-success-text); }\n.ps-step.done .pip { background: var(--mj-status-success); border-color: var(--mj-status-success); color: var(--mj-text-inverse); }\n.ps-step.curr { color: var(--mj-brand-primary); }\n.ps-step.curr .pip { border-color: var(--mj-brand-primary); color: var(--mj-brand-primary); }\n.ps-step .ln { width: 26px; height: 2px; background: var(--mj-border-strong); }\n\n/* ---- DAG flow canvas ---- */\n.ps-flow {\n position: relative;\n background:\n linear-gradient(var(--mj-border-subtle) 1px, transparent 1px) 0 0 / 22px 22px,\n linear-gradient(90deg, var(--mj-border-subtle) 1px, transparent 1px) 0 0 / 22px 22px,\n var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default); border-radius: 10px;\n min-height: 620px; overflow: hidden;\n}\n.ps-node {\n position: absolute; width: 190px; background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong); border-left-width: 3px; border-radius: 8px;\n cursor: pointer;\n}\n.ps-node .nh {\n display: flex; align-items: center; gap: 8px; padding: 9px 11px;\n border-bottom: 1px solid var(--mj-border-subtle); font-weight: 650; font-size: 12.5px; color: var(--mj-text-primary);\n}\n.ps-node .nh i.tile {\n width: 24px; height: 24px; border-radius: 6px; display: grid; place-items: center;\n color: var(--mj-text-inverse); font-size: 12px; flex: 0 0 auto;\n}\n.ps-node .nh .ps-tag { margin-left: auto; }\n.ps-node .nb { padding: 9px 11px; font-size: 12px; color: var(--mj-text-secondary); }\n.ps-node .nb-row { display: flex; justify-content: space-between; gap: 8px; padding: 2px 0; }\n.ps-node .nb-row .k { color: var(--mj-text-muted); }\n.ps-node.src { border-left-color: var(--ps-node-source); }\n.ps-node.src .nh i.tile { background: var(--ps-node-source); }\n.ps-node.feat { border-left-color: var(--ps-node-feature); }\n.ps-node.feat .nh i.tile { background: var(--ps-node-feature); }\n.ps-node.emb { border-left-color: var(--ps-node-embedding); }\n.ps-node.emb .nh i.tile { background: var(--ps-node-embedding); }\n.ps-node.target { border-left-color: var(--ps-node-target); }\n.ps-node.target .nh i.tile { background: var(--ps-node-target); }\n.ps-node.algo { border-left-color: var(--ps-node-algorithm); }\n.ps-node.algo .nh i.tile { background: var(--ps-node-algorithm); }\n.ps-node.output { border-left-color: var(--mj-status-success); }\n.ps-node.output .nh i.tile { background: var(--mj-status-success); }\n.ps-node.selected {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 18%, transparent);\n}\n.ps-node .port {\n position: absolute; width: 11px; height: 11px; border-radius: 50%;\n background: var(--mj-bg-surface); border: 2px solid var(--mj-brand-primary);\n top: 50%; transform: translateY(-50%);\n}\n.ps-node .port.in { left: -6px; }\n.ps-node .port.out { right: -6px; }\nsvg.ps-edges { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }\nsvg.ps-edges path { stroke: color-mix(in srgb, var(--mj-brand-primary) 45%, transparent); stroke-width: 2; fill: none; }\n\n/* palette chips */\n.ps-pchip {\n display: inline-flex; align-items: center; gap: 7px; padding: 6px 11px; border-radius: 8px;\n border: 1px dashed var(--mj-border-strong); background: var(--mj-bg-surface);\n font-size: 12.5px; font-weight: 600; color: var(--mj-text-secondary); cursor: grab;\n}\n.ps-pchip i { font-size: 12px; color: var(--mj-text-inverse); width: 20px; height: 20px; border-radius: 5px; display: grid; place-items: center; }\n.ps-pchip.s i { background: var(--ps-node-source); }\n.ps-pchip.f i { background: var(--ps-node-feature); }\n.ps-pchip.e i { background: var(--ps-node-embedding); }\n.ps-pchip.t i { background: var(--ps-node-target); }\n.ps-pchip.a i { background: var(--ps-node-algorithm); }\n\n/* segmented control */\n.ps-seg { display: inline-flex; border: 1px solid var(--mj-border-default); border-radius: 8px; overflow: hidden; }\n.ps-seg button {\n border: none; background: var(--mj-bg-surface); color: var(--mj-text-secondary);\n padding: 6px 12px; font-size: 12.5px; font-weight: 600; cursor: pointer;\n border-right: 1px solid var(--mj-border-default);\n}\n.ps-seg button:last-child { border-right: none; }\n.ps-seg button.on { background: var(--mj-brand-primary); color: var(--mj-text-inverse); }\n\n/* field control */\n.ps-field { margin-bottom: 14px; }\n.ps-field > label {\n display: block; font-size: 11px; text-transform: uppercase; letter-spacing: .04em;\n color: var(--mj-text-muted); font-weight: 700; margin-bottom: 6px;\n}\n.ps-input {\n width: 100%; padding: 8px 10px; border: 1px solid var(--mj-border-default);\n border-radius: 6px; font-size: 13px; background: var(--mj-bg-surface); color: var(--mj-text-primary);\n box-sizing: border-box;\n}\n.ps-input:focus { outline: none; border-color: var(--mj-brand-primary); box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 12%, transparent); }\n\n/* loading container */\n.ps-loading { display: flex; align-items: center; justify-content: center; padding: 60px 0; }\n\n/* ---- empty / prompt states ---- */\n.ps-empty {\n display: flex; flex-direction: column; align-items: center; justify-content: center;\n text-align: center; gap: 10px; padding: 56px 24px; color: var(--mj-text-muted);\n}\n.ps-empty .ps-empty-ico {\n width: 60px; height: 60px; border-radius: 16px; display: grid; place-items: center;\n background: var(--mj-bg-surface-sunken); color: var(--mj-text-disabled); font-size: 24px;\n}\n.ps-empty h3 { margin: 4px 0 0; font-size: 16px; font-weight: 650; color: var(--mj-text-secondary); }\n.ps-empty p { margin: 0; max-width: 420px; font-size: 13px; line-height: 1.5; }\n\n/* ---- confirm modal ---- */\n.ps-modal-backdrop {\n position: fixed; inset: 0; z-index: 1000;\n background: var(--mj-bg-overlay);\n display: flex; align-items: center; justify-content: center; padding: 24px;\n}\n.ps-modal {\n width: 100%; max-width: 480px; background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default); border-radius: 14px;\n box-shadow: var(--mj-shadow-lg, var(--mj-shadow-sm)); overflow: hidden;\n}\n.ps-modal-head {\n display: flex; align-items: center; gap: 12px; padding: 18px 20px;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n.ps-modal-head .ico {\n width: 38px; height: 38px; border-radius: 10px; display: grid; place-items: center;\n font-size: 16px; flex: 0 0 auto;\n background: var(--mj-status-info-bg); color: var(--mj-status-info-text);\n}\n.ps-modal-head.warn .ico { background: var(--mj-status-warning-bg); color: var(--mj-status-warning-text); }\n.ps-modal-head.danger .ico { background: var(--mj-status-error-bg); color: var(--mj-status-error-text); }\n.ps-modal-head h3 { margin: 0; font-size: 15.5px; font-weight: 650; color: var(--mj-text-primary); }\n.ps-modal-body { padding: 18px 20px; font-size: 13.5px; line-height: 1.55; color: var(--mj-text-secondary); }\n.ps-modal-body .ps-field { margin-top: 14px; margin-bottom: 0; }\n.ps-modal-foot {\n display: flex; align-items: center; gap: 10px; padding: 14px 20px;\n border-top: 1px solid var(--mj-border-subtle); background: var(--mj-bg-surface-card);\n}\n.ps-modal-foot .ps-spacer { flex: 1; }\n", ".ps-modal-backdrop {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.55);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 9999;\n backdrop-filter: blur(2px);\n}\n\n.ps-wizard-dialog {\n width: 920px;\n max-width: 95vw;\n max-height: 90vh;\n background: var(--mj-bg-surface-card);\n border-radius: var(--mj-radius-xl, 12px);\n border: 1px solid var(--mj-border-default);\n box-shadow: var(--mj-shadow-2xl);\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n.ps-wizard-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n}\n\n.ps-wizard-header-title {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.ps-wizard-header-title i {\n font-size: 24px;\n color: var(--mj-brand-primary);\n}\n\n.ps-wizard-header-title h2 {\n margin: 0;\n font-size: 1.15rem;\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.ps-wizard-subtitle {\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n}\n\n.ps-wizard-close {\n background: transparent;\n border: none;\n cursor: pointer;\n padding: 6px 8px;\n border-radius: 6px;\n color: var(--mj-text-muted);\n}\n\n.ps-wizard-close:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n.ps-wizard-stepper {\n display: flex;\n align-items: center;\n padding: 12px 20px;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n gap: 8px;\n}\n\n.ps-step-tab {\n display: flex;\n align-items: center;\n gap: 8px;\n background: transparent;\n border: none;\n cursor: pointer;\n padding: 6px 12px;\n border-radius: var(--mj-radius-md);\n color: var(--mj-text-muted);\n font-size: var(--mj-text-sm);\n font-weight: 500;\n transition: all 0.15s;\n}\n\n.ps-step-tab .step-num {\n width: 22px;\n height: 22px;\n border-radius: 50%;\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-muted);\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 11px;\n font-weight: 700;\n}\n\n.ps-step-tab.active {\n color: var(--mj-brand-primary);\n font-weight: 600;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.ps-step-tab.active .step-num {\n background: var(--mj-brand-primary);\n color: white;\n}\n\n.ps-step-tab.done .step-num {\n background: var(--mj-status-success-bg, #e6f4ea);\n color: var(--mj-status-success, #137333);\n}\n\n.step-line {\n flex: 1;\n height: 2px;\n background: var(--mj-border-default);\n}\n\n.ps-wizard-body {\n flex: 1;\n min-height: 0;\n overflow-y: auto;\n padding: 20px;\n}\n\n.ps-step-content {\n display: flex;\n flex-direction: column;\n gap: 14px;\n}\n\n.ps-grid-2 {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 14px;\n}\n\n.ps-grid-3 {\n display: grid;\n grid-template-columns: 1fr 1fr 1fr;\n gap: 14px;\n}\n\n.ps-field {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.ps-field label {\n font-size: var(--mj-text-xs);\n font-weight: 600;\n color: var(--mj-text-secondary);\n}\n\n.ps-field label .req {\n color: var(--mj-status-error, #d93025);\n}\n\n.as-of-box {\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n margin-top: 6px;\n}\n\n.feat-toolbar {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n}\n\n.feat-search {\n position: relative;\n flex: 1;\n}\n\n.feat-search i {\n position: absolute;\n left: 10px;\n top: 50%;\n transform: translateY(-50%);\n color: var(--mj-text-muted);\n}\n\n.feat-search input {\n padding-left: 32px;\n width: 100%;\n}\n\n.feat-actions {\n display: flex;\n gap: 6px;\n}\n\n.feat-stats {\n display: flex;\n gap: 18px;\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n padding: 4px 2px;\n}\n\n.feat-table-wrap {\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n max-height: 320px;\n overflow-y: auto;\n}\n\n.feat-table {\n width: 100%;\n border-collapse: collapse;\n font-size: var(--mj-text-sm);\n}\n\n.feat-table th {\n position: sticky;\n top: 0;\n background: var(--mj-bg-surface);\n z-index: 1;\n padding: 8px 12px;\n text-align: left;\n border-bottom: 1px solid var(--mj-border-default);\n font-size: var(--mj-text-xs);\n font-weight: 700;\n color: var(--mj-text-muted);\n}\n\n.feat-table td {\n padding: 8px 12px;\n border-bottom: 1px solid var(--mj-border-default);\n color: var(--mj-text-primary);\n}\n\n.feat-table tr:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.feat-table tr.deny-row {\n background: color-mix(in srgb, var(--mj-status-error) 6%, transparent);\n text-decoration: line-through;\n color: var(--mj-text-muted);\n}\n\n.feat-table tr.target-row {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n}\n\n.ps-deny-toggle {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 3px 8px;\n font-size: 11px;\n border-radius: 4px;\n border: 1px solid var(--mj-border-default);\n background: transparent;\n cursor: pointer;\n color: var(--mj-text-secondary);\n}\n\n.ps-deny-toggle.denied {\n background: var(--mj-status-error-bg, #fce8e6);\n border-color: var(--mj-status-error-border, #fad2cf);\n color: var(--mj-status-error, #c5221f);\n font-weight: 600;\n}\n\n.slider-row {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.slider-row input[type=\"range\"] {\n width: 100%;\n}\n\n.recipe-card {\n display: flex;\n gap: 14px;\n padding: 14px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n}\n\n.recipe-icon {\n width: 42px;\n height: 42px;\n border-radius: var(--mj-radius-md);\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, transparent);\n color: var(--mj-brand-primary);\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 18px;\n flex: none;\n}\n\n.recipe-details {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.recipe-details h4 {\n margin: 0;\n font-size: var(--mj-text-sm);\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.ps-wizard-footer {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 14px 20px;\n border-top: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n}\n"] }]
|
|
1375
|
+
}], null, { provider: [{
|
|
1376
|
+
type: Input
|
|
1377
|
+
}], currentUser: [{
|
|
1378
|
+
type: Input
|
|
1379
|
+
}], engine: [{
|
|
1380
|
+
type: Input
|
|
1381
|
+
}], initialAlgorithmName: [{
|
|
1382
|
+
type: Input
|
|
1383
|
+
}], initialAlgorithmId: [{
|
|
1384
|
+
type: Input
|
|
1385
|
+
}], cloneFromPipeline: [{
|
|
1386
|
+
type: Input
|
|
1387
|
+
}], cloneFrom: [{
|
|
1388
|
+
type: Input
|
|
1389
|
+
}], closed: [{
|
|
1390
|
+
type: Output
|
|
1391
|
+
}], saved: [{
|
|
1392
|
+
type: Output
|
|
1393
|
+
}], trainRequested: [{
|
|
1394
|
+
type: Output
|
|
1395
|
+
}] }); })();
|
|
1396
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(PSPipelineWizardComponent, { className: "PSPipelineWizardComponent", filePath: "src/PredictiveStudio/components/ps-pipeline-wizard.component.ts", lineNumber: 395 }); })();
|
|
1397
|
+
//# sourceMappingURL=ps-pipeline-wizard.component.js.map
|