@thinkhive/sdk 3.1.0 → 3.3.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/README.md +279 -128
- package/dist/api/apiKeys.d.ts +252 -0
- package/dist/api/apiKeys.js +298 -0
- package/dist/api/business-metrics.d.ts +188 -0
- package/dist/api/business-metrics.js +213 -0
- package/dist/api/conversation-eval.d.ts +200 -0
- package/dist/api/conversation-eval.js +235 -0
- package/dist/api/deterministic-graders.d.ts +205 -0
- package/dist/api/deterministic-graders.js +191 -0
- package/dist/api/eval-health.d.ts +250 -0
- package/dist/api/eval-health.js +224 -0
- package/dist/api/human-review.d.ts +275 -0
- package/dist/api/human-review.js +236 -0
- package/dist/api/nondeterminism.d.ts +300 -0
- package/dist/api/nondeterminism.js +250 -0
- package/dist/api/quality-metrics.d.ts +303 -0
- package/dist/api/quality-metrics.js +198 -0
- package/dist/api/roi-analytics.d.ts +263 -0
- package/dist/api/roi-analytics.js +204 -0
- package/dist/api/transcript-patterns.d.ts +204 -0
- package/dist/api/transcript-patterns.js +227 -0
- package/dist/core/client.d.ts +82 -8
- package/dist/core/client.js +223 -32
- package/dist/core/config.d.ts +1 -1
- package/dist/core/config.js +2 -2
- package/dist/core/types.d.ts +27 -2
- package/dist/core/types.js +1 -1
- package/dist/index.d.ts +415 -62
- package/dist/index.js +253 -37
- package/package.json +8 -4
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ThinkHive SDK v3.0 - Evaluation Health API
|
|
3
|
+
*
|
|
4
|
+
* API for eval saturation monitoring, regression detection, and health reports
|
|
5
|
+
*/
|
|
6
|
+
export type SaturationType = 'ceiling' | 'floor' | 'healthy';
|
|
7
|
+
export type HealthStatus = 'healthy' | 'warning' | 'critical';
|
|
8
|
+
export type RegressionSeverity = 'minor' | 'moderate' | 'severe';
|
|
9
|
+
export interface EvalHealthSnapshot {
|
|
10
|
+
id: string;
|
|
11
|
+
companyId: string;
|
|
12
|
+
agentId: string;
|
|
13
|
+
criterionId?: string;
|
|
14
|
+
snapshotDate: string;
|
|
15
|
+
passRate?: string;
|
|
16
|
+
evalCount?: number;
|
|
17
|
+
meanScore?: string;
|
|
18
|
+
saturationType?: SaturationType;
|
|
19
|
+
daysAtSaturation?: number;
|
|
20
|
+
trendDirection?: string;
|
|
21
|
+
trendStrength?: string;
|
|
22
|
+
healthStatus?: HealthStatus;
|
|
23
|
+
healthScore?: string;
|
|
24
|
+
createdAt: string;
|
|
25
|
+
}
|
|
26
|
+
export interface EvalRegression {
|
|
27
|
+
id: string;
|
|
28
|
+
companyId: string;
|
|
29
|
+
agentId: string;
|
|
30
|
+
criterionId?: string;
|
|
31
|
+
severity: RegressionSeverity;
|
|
32
|
+
baselinePassRate: string;
|
|
33
|
+
currentPassRate: string;
|
|
34
|
+
delta: string;
|
|
35
|
+
deltaPercent?: string;
|
|
36
|
+
baselinePeriodStart: string;
|
|
37
|
+
baselinePeriodEnd: string;
|
|
38
|
+
currentPeriodStart: string;
|
|
39
|
+
currentPeriodEnd: string;
|
|
40
|
+
baselineEvalCount?: number;
|
|
41
|
+
currentEvalCount?: number;
|
|
42
|
+
suspectedCauses?: unknown[];
|
|
43
|
+
isSignificant?: boolean;
|
|
44
|
+
isResolved: boolean;
|
|
45
|
+
isAcknowledged: boolean;
|
|
46
|
+
resolvedAt?: string;
|
|
47
|
+
resolvedBy?: string;
|
|
48
|
+
resolutionType?: string;
|
|
49
|
+
resolutionNotes?: string;
|
|
50
|
+
acknowledgedAt?: string;
|
|
51
|
+
acknowledgedBy?: string;
|
|
52
|
+
detectedAt: string;
|
|
53
|
+
createdAt: string;
|
|
54
|
+
}
|
|
55
|
+
export interface HealthReport {
|
|
56
|
+
agentId: string;
|
|
57
|
+
generatedAt: string;
|
|
58
|
+
overallHealth: HealthStatus;
|
|
59
|
+
overallScore: number;
|
|
60
|
+
passRate: number;
|
|
61
|
+
evalCount: number;
|
|
62
|
+
saturationStatus: {
|
|
63
|
+
type: SaturationType;
|
|
64
|
+
daysAtSaturation: number;
|
|
65
|
+
recommendation: string;
|
|
66
|
+
};
|
|
67
|
+
regressionCount: number;
|
|
68
|
+
activeRegressions: EvalRegression[];
|
|
69
|
+
trend: {
|
|
70
|
+
direction: 'improving' | 'stable' | 'declining';
|
|
71
|
+
strength: number;
|
|
72
|
+
description: string;
|
|
73
|
+
};
|
|
74
|
+
recommendations: string[];
|
|
75
|
+
}
|
|
76
|
+
export interface CreateSnapshotOptions {
|
|
77
|
+
agentId: string;
|
|
78
|
+
criterionId?: string;
|
|
79
|
+
snapshotDate: string;
|
|
80
|
+
passRate?: string;
|
|
81
|
+
evalCount?: number;
|
|
82
|
+
meanScore?: string;
|
|
83
|
+
saturationType?: SaturationType;
|
|
84
|
+
daysAtSaturation?: number;
|
|
85
|
+
trendDirection?: string;
|
|
86
|
+
trendStrength?: string;
|
|
87
|
+
healthStatus?: HealthStatus;
|
|
88
|
+
healthScore?: string;
|
|
89
|
+
}
|
|
90
|
+
export interface CreateRegressionOptions {
|
|
91
|
+
agentId: string;
|
|
92
|
+
criterionId?: string;
|
|
93
|
+
severity: RegressionSeverity;
|
|
94
|
+
baselinePassRate: string;
|
|
95
|
+
currentPassRate: string;
|
|
96
|
+
delta: string;
|
|
97
|
+
deltaPercent?: string;
|
|
98
|
+
baselinePeriodStart: string;
|
|
99
|
+
baselinePeriodEnd: string;
|
|
100
|
+
currentPeriodStart: string;
|
|
101
|
+
currentPeriodEnd: string;
|
|
102
|
+
baselineEvalCount?: number;
|
|
103
|
+
currentEvalCount?: number;
|
|
104
|
+
suspectedCauses?: unknown[];
|
|
105
|
+
isSignificant?: boolean;
|
|
106
|
+
detectedAt?: string;
|
|
107
|
+
}
|
|
108
|
+
export interface ResolveRegressionOptions {
|
|
109
|
+
resolutionType: string;
|
|
110
|
+
notes?: string;
|
|
111
|
+
}
|
|
112
|
+
export interface GetSnapshotsOptions {
|
|
113
|
+
agentId: string;
|
|
114
|
+
criterionId?: string;
|
|
115
|
+
startDate?: string;
|
|
116
|
+
endDate?: string;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Evaluation Health API client for monitoring eval quality and detecting regressions
|
|
120
|
+
*/
|
|
121
|
+
export declare const evalHealth: {
|
|
122
|
+
/**
|
|
123
|
+
* Get comprehensive health report for an agent
|
|
124
|
+
*
|
|
125
|
+
* @example
|
|
126
|
+
* ```typescript
|
|
127
|
+
* const report = await evalHealth.getReport('agent_123');
|
|
128
|
+
* console.log(`Overall health: ${report.overallHealth}`);
|
|
129
|
+
* console.log(`Active regressions: ${report.regressionCount}`);
|
|
130
|
+
* ```
|
|
131
|
+
*/
|
|
132
|
+
getReport(agentId: string): Promise<HealthReport>;
|
|
133
|
+
/**
|
|
134
|
+
* Get historical health snapshots
|
|
135
|
+
*
|
|
136
|
+
* @example
|
|
137
|
+
* ```typescript
|
|
138
|
+
* const snapshots = await evalHealth.getSnapshots({
|
|
139
|
+
* agentId: 'agent_123',
|
|
140
|
+
* startDate: '2024-01-01T00:00:00Z',
|
|
141
|
+
* endDate: '2024-01-31T23:59:59Z',
|
|
142
|
+
* });
|
|
143
|
+
* ```
|
|
144
|
+
*/
|
|
145
|
+
getSnapshots(options: GetSnapshotsOptions): Promise<EvalHealthSnapshot[]>;
|
|
146
|
+
/**
|
|
147
|
+
* Get latest health snapshot
|
|
148
|
+
*
|
|
149
|
+
* @example
|
|
150
|
+
* ```typescript
|
|
151
|
+
* const snapshot = await evalHealth.getLatestSnapshot('agent_123');
|
|
152
|
+
* ```
|
|
153
|
+
*/
|
|
154
|
+
getLatestSnapshot(agentId: string, criterionId?: string): Promise<EvalHealthSnapshot | null>;
|
|
155
|
+
/**
|
|
156
|
+
* Record a health snapshot
|
|
157
|
+
*
|
|
158
|
+
* @example
|
|
159
|
+
* ```typescript
|
|
160
|
+
* const snapshot = await evalHealth.recordSnapshot({
|
|
161
|
+
* agentId: 'agent_123',
|
|
162
|
+
* snapshotDate: new Date().toISOString(),
|
|
163
|
+
* passRate: '0.85',
|
|
164
|
+
* evalCount: 150,
|
|
165
|
+
* healthStatus: 'healthy',
|
|
166
|
+
* });
|
|
167
|
+
* ```
|
|
168
|
+
*/
|
|
169
|
+
recordSnapshot(options: CreateSnapshotOptions): Promise<EvalHealthSnapshot>;
|
|
170
|
+
/**
|
|
171
|
+
* Get unresolved regressions for an agent
|
|
172
|
+
*
|
|
173
|
+
* @example
|
|
174
|
+
* ```typescript
|
|
175
|
+
* const regressions = await evalHealth.getRegressions('agent_123');
|
|
176
|
+
* for (const regression of regressions) {
|
|
177
|
+
* console.log(`${regression.severity}: ${regression.delta}% drop`);
|
|
178
|
+
* }
|
|
179
|
+
* ```
|
|
180
|
+
*/
|
|
181
|
+
getRegressions(agentId: string): Promise<EvalRegression[]>;
|
|
182
|
+
/**
|
|
183
|
+
* Record a new regression
|
|
184
|
+
*
|
|
185
|
+
* @example
|
|
186
|
+
* ```typescript
|
|
187
|
+
* const regression = await evalHealth.recordRegression({
|
|
188
|
+
* agentId: 'agent_123',
|
|
189
|
+
* severity: 'moderate',
|
|
190
|
+
* baselinePassRate: '0.92',
|
|
191
|
+
* currentPassRate: '0.78',
|
|
192
|
+
* delta: '-0.14',
|
|
193
|
+
* baselinePeriodStart: '2024-01-01T00:00:00Z',
|
|
194
|
+
* baselinePeriodEnd: '2024-01-15T23:59:59Z',
|
|
195
|
+
* currentPeriodStart: '2024-01-16T00:00:00Z',
|
|
196
|
+
* currentPeriodEnd: '2024-01-31T23:59:59Z',
|
|
197
|
+
* });
|
|
198
|
+
* ```
|
|
199
|
+
*/
|
|
200
|
+
recordRegression(options: CreateRegressionOptions): Promise<EvalRegression>;
|
|
201
|
+
/**
|
|
202
|
+
* Resolve a regression
|
|
203
|
+
*
|
|
204
|
+
* @example
|
|
205
|
+
* ```typescript
|
|
206
|
+
* await evalHealth.resolveRegression('regression_123', {
|
|
207
|
+
* resolutionType: 'fixed',
|
|
208
|
+
* notes: 'Updated prompt template to address quality issues',
|
|
209
|
+
* });
|
|
210
|
+
* ```
|
|
211
|
+
*/
|
|
212
|
+
resolveRegression(regressionId: string, options: ResolveRegressionOptions): Promise<void>;
|
|
213
|
+
/**
|
|
214
|
+
* Acknowledge a regression
|
|
215
|
+
*
|
|
216
|
+
* @example
|
|
217
|
+
* ```typescript
|
|
218
|
+
* await evalHealth.acknowledgeRegression('regression_123');
|
|
219
|
+
* ```
|
|
220
|
+
*/
|
|
221
|
+
acknowledgeRegression(regressionId: string): Promise<void>;
|
|
222
|
+
};
|
|
223
|
+
/**
|
|
224
|
+
* Check if health status indicates an issue
|
|
225
|
+
*
|
|
226
|
+
* @param status - Health status to check
|
|
227
|
+
* @returns Whether the status indicates a problem
|
|
228
|
+
*/
|
|
229
|
+
export declare function hasHealthIssue(status: HealthStatus): boolean;
|
|
230
|
+
/**
|
|
231
|
+
* Get severity level as numeric value for sorting
|
|
232
|
+
*
|
|
233
|
+
* @param severity - Regression severity
|
|
234
|
+
* @returns Numeric severity (1-3, higher is worse)
|
|
235
|
+
*/
|
|
236
|
+
export declare function getSeverityLevel(severity: RegressionSeverity): number;
|
|
237
|
+
/**
|
|
238
|
+
* Check if evaluation is saturated
|
|
239
|
+
*
|
|
240
|
+
* @param snapshot - Health snapshot to check
|
|
241
|
+
* @returns Whether evaluation is at ceiling or floor
|
|
242
|
+
*/
|
|
243
|
+
export declare function isSaturated(snapshot: EvalHealthSnapshot): boolean;
|
|
244
|
+
/**
|
|
245
|
+
* Get recommendation for saturation type
|
|
246
|
+
*
|
|
247
|
+
* @param saturationType - Type of saturation
|
|
248
|
+
* @returns Recommendation string
|
|
249
|
+
*/
|
|
250
|
+
export declare function getSaturationRecommendation(saturationType: SaturationType): string;
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* ThinkHive SDK v3.0 - Evaluation Health API
|
|
4
|
+
*
|
|
5
|
+
* API for eval saturation monitoring, regression detection, and health reports
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.evalHealth = void 0;
|
|
9
|
+
exports.hasHealthIssue = hasHealthIssue;
|
|
10
|
+
exports.getSeverityLevel = getSeverityLevel;
|
|
11
|
+
exports.isSaturated = isSaturated;
|
|
12
|
+
exports.getSaturationRecommendation = getSaturationRecommendation;
|
|
13
|
+
const client_1 = require("../core/client");
|
|
14
|
+
// ============================================================================
|
|
15
|
+
// EVAL HEALTH API CLIENT
|
|
16
|
+
// ============================================================================
|
|
17
|
+
/**
|
|
18
|
+
* Evaluation Health API client for monitoring eval quality and detecting regressions
|
|
19
|
+
*/
|
|
20
|
+
exports.evalHealth = {
|
|
21
|
+
/**
|
|
22
|
+
* Get comprehensive health report for an agent
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```typescript
|
|
26
|
+
* const report = await evalHealth.getReport('agent_123');
|
|
27
|
+
* console.log(`Overall health: ${report.overallHealth}`);
|
|
28
|
+
* console.log(`Active regressions: ${report.regressionCount}`);
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
async getReport(agentId) {
|
|
32
|
+
return (0, client_1.apiRequestWithData)(`/eval-health/report?agentId=${agentId}`, { apiVersion: 'v1' });
|
|
33
|
+
},
|
|
34
|
+
// ---------------------------------------------------------------------------
|
|
35
|
+
// SNAPSHOTS
|
|
36
|
+
// ---------------------------------------------------------------------------
|
|
37
|
+
/**
|
|
38
|
+
* Get historical health snapshots
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```typescript
|
|
42
|
+
* const snapshots = await evalHealth.getSnapshots({
|
|
43
|
+
* agentId: 'agent_123',
|
|
44
|
+
* startDate: '2024-01-01T00:00:00Z',
|
|
45
|
+
* endDate: '2024-01-31T23:59:59Z',
|
|
46
|
+
* });
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
async getSnapshots(options) {
|
|
50
|
+
const params = new URLSearchParams();
|
|
51
|
+
params.set('agentId', options.agentId);
|
|
52
|
+
if (options.criterionId)
|
|
53
|
+
params.set('criterionId', options.criterionId);
|
|
54
|
+
if (options.startDate)
|
|
55
|
+
params.set('startDate', options.startDate);
|
|
56
|
+
if (options.endDate)
|
|
57
|
+
params.set('endDate', options.endDate);
|
|
58
|
+
return (0, client_1.apiRequestWithData)(`/eval-health/snapshots?${params.toString()}`, { apiVersion: 'v1' });
|
|
59
|
+
},
|
|
60
|
+
/**
|
|
61
|
+
* Get latest health snapshot
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```typescript
|
|
65
|
+
* const snapshot = await evalHealth.getLatestSnapshot('agent_123');
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
68
|
+
async getLatestSnapshot(agentId, criterionId) {
|
|
69
|
+
const params = new URLSearchParams();
|
|
70
|
+
params.set('agentId', agentId);
|
|
71
|
+
if (criterionId)
|
|
72
|
+
params.set('criterionId', criterionId);
|
|
73
|
+
return (0, client_1.apiRequestWithData)(`/eval-health/snapshots/latest?${params.toString()}`, { apiVersion: 'v1' });
|
|
74
|
+
},
|
|
75
|
+
/**
|
|
76
|
+
* Record a health snapshot
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
* ```typescript
|
|
80
|
+
* const snapshot = await evalHealth.recordSnapshot({
|
|
81
|
+
* agentId: 'agent_123',
|
|
82
|
+
* snapshotDate: new Date().toISOString(),
|
|
83
|
+
* passRate: '0.85',
|
|
84
|
+
* evalCount: 150,
|
|
85
|
+
* healthStatus: 'healthy',
|
|
86
|
+
* });
|
|
87
|
+
* ```
|
|
88
|
+
*/
|
|
89
|
+
async recordSnapshot(options) {
|
|
90
|
+
return (0, client_1.apiRequestWithData)('/eval-health/snapshots', {
|
|
91
|
+
method: 'POST',
|
|
92
|
+
body: options,
|
|
93
|
+
apiVersion: 'v1',
|
|
94
|
+
});
|
|
95
|
+
},
|
|
96
|
+
// ---------------------------------------------------------------------------
|
|
97
|
+
// REGRESSIONS
|
|
98
|
+
// ---------------------------------------------------------------------------
|
|
99
|
+
/**
|
|
100
|
+
* Get unresolved regressions for an agent
|
|
101
|
+
*
|
|
102
|
+
* @example
|
|
103
|
+
* ```typescript
|
|
104
|
+
* const regressions = await evalHealth.getRegressions('agent_123');
|
|
105
|
+
* for (const regression of regressions) {
|
|
106
|
+
* console.log(`${regression.severity}: ${regression.delta}% drop`);
|
|
107
|
+
* }
|
|
108
|
+
* ```
|
|
109
|
+
*/
|
|
110
|
+
async getRegressions(agentId) {
|
|
111
|
+
return (0, client_1.apiRequestWithData)(`/eval-health/regressions?agentId=${agentId}`, { apiVersion: 'v1' });
|
|
112
|
+
},
|
|
113
|
+
/**
|
|
114
|
+
* Record a new regression
|
|
115
|
+
*
|
|
116
|
+
* @example
|
|
117
|
+
* ```typescript
|
|
118
|
+
* const regression = await evalHealth.recordRegression({
|
|
119
|
+
* agentId: 'agent_123',
|
|
120
|
+
* severity: 'moderate',
|
|
121
|
+
* baselinePassRate: '0.92',
|
|
122
|
+
* currentPassRate: '0.78',
|
|
123
|
+
* delta: '-0.14',
|
|
124
|
+
* baselinePeriodStart: '2024-01-01T00:00:00Z',
|
|
125
|
+
* baselinePeriodEnd: '2024-01-15T23:59:59Z',
|
|
126
|
+
* currentPeriodStart: '2024-01-16T00:00:00Z',
|
|
127
|
+
* currentPeriodEnd: '2024-01-31T23:59:59Z',
|
|
128
|
+
* });
|
|
129
|
+
* ```
|
|
130
|
+
*/
|
|
131
|
+
async recordRegression(options) {
|
|
132
|
+
return (0, client_1.apiRequestWithData)('/eval-health/regressions', {
|
|
133
|
+
method: 'POST',
|
|
134
|
+
body: options,
|
|
135
|
+
apiVersion: 'v1',
|
|
136
|
+
});
|
|
137
|
+
},
|
|
138
|
+
/**
|
|
139
|
+
* Resolve a regression
|
|
140
|
+
*
|
|
141
|
+
* @example
|
|
142
|
+
* ```typescript
|
|
143
|
+
* await evalHealth.resolveRegression('regression_123', {
|
|
144
|
+
* resolutionType: 'fixed',
|
|
145
|
+
* notes: 'Updated prompt template to address quality issues',
|
|
146
|
+
* });
|
|
147
|
+
* ```
|
|
148
|
+
*/
|
|
149
|
+
async resolveRegression(regressionId, options) {
|
|
150
|
+
await (0, client_1.apiRequest)(`/eval-health/regressions/${regressionId}/resolve`, {
|
|
151
|
+
method: 'POST',
|
|
152
|
+
body: options,
|
|
153
|
+
apiVersion: 'v1',
|
|
154
|
+
});
|
|
155
|
+
},
|
|
156
|
+
/**
|
|
157
|
+
* Acknowledge a regression
|
|
158
|
+
*
|
|
159
|
+
* @example
|
|
160
|
+
* ```typescript
|
|
161
|
+
* await evalHealth.acknowledgeRegression('regression_123');
|
|
162
|
+
* ```
|
|
163
|
+
*/
|
|
164
|
+
async acknowledgeRegression(regressionId) {
|
|
165
|
+
await (0, client_1.apiRequest)(`/eval-health/regressions/${regressionId}/acknowledge`, {
|
|
166
|
+
method: 'POST',
|
|
167
|
+
apiVersion: 'v1',
|
|
168
|
+
});
|
|
169
|
+
},
|
|
170
|
+
};
|
|
171
|
+
// ============================================================================
|
|
172
|
+
// HELPER FUNCTIONS
|
|
173
|
+
// ============================================================================
|
|
174
|
+
/**
|
|
175
|
+
* Check if health status indicates an issue
|
|
176
|
+
*
|
|
177
|
+
* @param status - Health status to check
|
|
178
|
+
* @returns Whether the status indicates a problem
|
|
179
|
+
*/
|
|
180
|
+
function hasHealthIssue(status) {
|
|
181
|
+
return status === 'warning' || status === 'critical';
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Get severity level as numeric value for sorting
|
|
185
|
+
*
|
|
186
|
+
* @param severity - Regression severity
|
|
187
|
+
* @returns Numeric severity (1-3, higher is worse)
|
|
188
|
+
*/
|
|
189
|
+
function getSeverityLevel(severity) {
|
|
190
|
+
switch (severity) {
|
|
191
|
+
case 'minor': return 1;
|
|
192
|
+
case 'moderate': return 2;
|
|
193
|
+
case 'severe': return 3;
|
|
194
|
+
default: return 0;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Check if evaluation is saturated
|
|
199
|
+
*
|
|
200
|
+
* @param snapshot - Health snapshot to check
|
|
201
|
+
* @returns Whether evaluation is at ceiling or floor
|
|
202
|
+
*/
|
|
203
|
+
function isSaturated(snapshot) {
|
|
204
|
+
return snapshot.saturationType === 'ceiling' || snapshot.saturationType === 'floor';
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Get recommendation for saturation type
|
|
208
|
+
*
|
|
209
|
+
* @param saturationType - Type of saturation
|
|
210
|
+
* @returns Recommendation string
|
|
211
|
+
*/
|
|
212
|
+
function getSaturationRecommendation(saturationType) {
|
|
213
|
+
switch (saturationType) {
|
|
214
|
+
case 'ceiling':
|
|
215
|
+
return 'Evaluation criteria may be too lenient. Consider adding stricter checks or more challenging test cases.';
|
|
216
|
+
case 'floor':
|
|
217
|
+
return 'Evaluation criteria may be too strict. Consider relaxing thresholds or reviewing criteria for accuracy.';
|
|
218
|
+
case 'healthy':
|
|
219
|
+
return 'Evaluation is operating within healthy parameters.';
|
|
220
|
+
default:
|
|
221
|
+
return 'Unable to determine saturation status.';
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXZhbC1oZWFsdGguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXBpL2V2YWwtaGVhbHRoLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7OztHQUlHOzs7QUE0VEgsd0NBRUM7QUFRRCw0Q0FPQztBQVFELGtDQUVDO0FBUUQsa0VBV0M7QUF4V0QsMkNBQWdFO0FBOEhoRSwrRUFBK0U7QUFDL0UseUJBQXlCO0FBQ3pCLCtFQUErRTtBQUUvRTs7R0FFRztBQUNVLFFBQUEsVUFBVSxHQUFHO0lBQ3hCOzs7Ozs7Ozs7T0FTRztJQUNILEtBQUssQ0FBQyxTQUFTLENBQUMsT0FBZTtRQUM3QixPQUFPLElBQUEsMkJBQWtCLEVBQ3ZCLCtCQUErQixPQUFPLEVBQUUsRUFDeEMsRUFBRSxVQUFVLEVBQUUsSUFBSSxFQUFFLENBQ3JCLENBQUM7SUFDSixDQUFDO0lBRUQsOEVBQThFO0lBQzlFLFlBQVk7SUFDWiw4RUFBOEU7SUFFOUU7Ozs7Ozs7Ozs7O09BV0c7SUFDSCxLQUFLLENBQUMsWUFBWSxDQUFDLE9BQTRCO1FBQzdDLE1BQU0sTUFBTSxHQUFHLElBQUksZUFBZSxFQUFFLENBQUM7UUFDckMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxTQUFTLEVBQUUsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ3ZDLElBQUksT0FBTyxDQUFDLFdBQVc7WUFBRSxNQUFNLENBQUMsR0FBRyxDQUFDLGFBQWEsRUFBRSxPQUFPLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDeEUsSUFBSSxPQUFPLENBQUMsU0FBUztZQUFFLE1BQU0sQ0FBQyxHQUFHLENBQUMsV0FBVyxFQUFFLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNsRSxJQUFJLE9BQU8sQ0FBQyxPQUFPO1lBQUUsTUFBTSxDQUFDLEdBQUcsQ0FBQyxTQUFTLEVBQUUsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBRTVELE9BQU8sSUFBQSwyQkFBa0IsRUFDdkIsMEJBQTBCLE1BQU0s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LFFBQVEsQ0FBQyxjQUFjLEtBQUssT0FBTyxDQUFDO0FBQ3RGLENBQUM7QUFFRDs7Ozs7R0FLRztBQUNILFNBQWdCLDJCQUEyQixDQUFDLGNBQThCO0lBQ3hFLFFBQVEsY0FBYyxFQUFFLENBQUM7UUFDdkIsS0FBSyxTQUFTO1lBQ1osT0FBTyx5R0FBeUcsQ0FBQztRQUNuSCxLQUFLLE9BQU87WUFDVixPQUFPLHlHQUF5RyxDQUFDO1FBQ25ILEtBQUssU0FBUztZQUNaLE9BQU8sb0RBQW9ELENBQUM7UUFDOUQ7WUFDRSxPQUFPLHdDQUF3QyxDQUFDO0lBQ3BELENBQUM7QUFDSCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBUaGlua0hpdmUgU0RLIHYzLjAgLSBFdmFsdWF0aW9uIEhlYWx0aCBBUElcbiAqXG4gKiBBUEkgZm9yIGV2YWwgc2F0dXJhdGlvbiBtb25pdG9yaW5nLCByZWdyZXNzaW9uIGRldGVjdGlvbiwgYW5kIGhlYWx0aCByZXBvcnRzXG4gKi9cblxuaW1wb3J0IHsgYXBpUmVxdWVzdCwgYXBpUmVxdWVzdFdpdGhEYXRhIH0gZnJvbSAnLi4vY29yZS9jbGllbnQnO1xuXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vLyBUWVBFU1xuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG5leHBvcnQgdHlwZSBTYXR1cmF0aW9uVHlwZSA9ICdjZWlsaW5nJyB8ICdmbG9vcicgfCAnaGVhbHRoeSc7XG5leHBvcnQgdHlwZSBIZWFsdGhTdGF0dXMgPSAnaGVhbHRoeScgfCAnd2FybmluZycgfCAnY3JpdGljYWwnO1xuZXhwb3J0IHR5cGUgUmVncmVzc2lvblNldmVyaXR5ID0gJ21pbm9yJyB8ICdtb2RlcmF0ZScgfCAnc2V2ZXJlJztcblxuZXhwb3J0IGludGVyZmFjZSBFdmFsSGVhbHRoU25hcHNob3Qge1xuICBpZDogc3RyaW5nO1xuICBjb21wYW55SWQ6IHN0cmluZztcbiAgYWdlbnRJZDogc3RyaW5nO1xuICBjcml0ZXJpb25JZD86IHN0cmluZztcbiAgc25hcHNob3REYXRlOiBzdHJpbmc7XG4gIHBhc3NSYXRlPzogc3RyaW5nO1xuICBldmFsQ291bnQ/OiBudW1iZXI7XG4gIG1lYW5TY29yZT86IHN0cmluZztcbiAgc2F0dXJhdGlvblR5cGU/OiBTYXR1cmF0aW9uVHlwZTtcbiAgZGF5c0F0U2F0dXJhdGlvbj86IG51bWJlcjtcbiAgdHJlbmREaXJlY3Rpb24/OiBzdHJpbmc7XG4gIHRyZW5kU3RyZW5ndGg/OiBzdHJpbmc7XG4gIGhlYWx0aFN0YXR1cz86IEhlYWx0aFN0YXR1cztcbiAgaGVhbHRoU2NvcmU/OiBzdHJpbmc7XG4gIGNyZWF0ZWRBdDogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEV2YWxSZWdyZXNzaW9uIHtcbiAgaWQ6IHN0cmluZztcbiAgY29tcGFueUlkOiBzdHJpbmc7XG4gIGFnZW50SWQ6IHN0cmluZztcbiAgY3JpdGVyaW9uSWQ/OiBzdHJpbmc7XG4gIHNldmVyaXR5OiBSZWdyZXNzaW9uU2V2ZXJpdHk7XG4gIGJhc2VsaW5lUGFzc1JhdGU6IHN0cmluZztcbiAgY3VycmVudFBhc3NSYXRlOiBzdHJpbmc7XG4gIGRlbHRhOiBzdHJpbmc7XG4gIGRlbHRhUGVyY2VudD86IHN0cmluZztcbiAgYmFzZWxpbmVQZXJpb2RTdGFydDogc3RyaW5nO1xuICBiYXNlbGluZVBlcmlvZEVuZDogc3RyaW5nO1xuICBjdXJyZW50UGVyaW9kU3RhcnQ6IHN0cmluZztcbiAgY3VycmVudFBlcmlvZEVuZDogc3RyaW5nO1xuICBiYXNlbGluZUV2YWxDb3VudD86IG51bWJlcjtcbiAgY3VycmVudEV2YWxDb3VudD86IG51bWJlcjtcbiAgc3VzcGVjdGVkQ2F1c2VzPzogdW5rbm93bltdO1xuICBpc1NpZ25pZmljYW50PzogYm9vbGVhbjtcbiAgaXNSZXNvbHZlZDogYm9vbGVhbjtcbiAgaXNBY2tub3dsZWRnZWQ6IGJvb2xlYW47XG4gIHJlc29sdmVkQXQ/OiBzdHJpbmc7XG4gIHJlc29sdmVkQnk/OiBzdHJpbmc7XG4gIHJlc29sdXRpb25UeXBlPzogc3RyaW5nO1xuICByZXNvbHV0aW9uTm90ZXM/OiBzdHJpbmc7XG4gIGFja25vd2xlZGdlZEF0Pzogc3RyaW5nO1xuICBhY2tub3dsZWRnZWRCeT86IHN0cmluZztcbiAgZGV0ZWN0ZWRBdDogc3RyaW5nO1xuICBjcmVhdGVkQXQ6IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBIZWFsdGhSZXBvcnQge1xuICBhZ2VudElkOiBzdHJpbmc7XG4gIGdlbmVyYXRlZEF0OiBzdHJpbmc7XG4gIG92ZXJhbGxIZWFsdGg6IEhlYWx0aFN0YXR1cztcbiAgb3ZlcmFsbFNjb3JlOiBudW1iZXI7XG4gIHBhc3NSYXRlOiBudW1iZXI7XG4gIGV2YWxDb3VudDogbnVtYmVyO1xuICBzYXR1cmF0aW9uU3RhdHVzOiB7XG4gICAgdHlwZTogU2F0dXJhdGlvblR5cGU7XG4gICAgZGF5c0F0U2F0dXJhdGlvbjogbnVtYmVyO1xuICAgIHJlY29tbWVuZGF0aW9uOiBzdHJpbmc7XG4gIH07XG4gIHJlZ3Jlc3Npb25Db3VudDogbnVtYmVyO1xuICBhY3RpdmVSZWdyZXNzaW9uczogRXZhbFJlZ3Jlc3Npb25bXTtcbiAgdHJlbmQ6IHtcbiAgICBkaXJlY3Rpb246ICdpbXByb3ZpbmcnIHwgJ3N0YWJsZScgfCAnZGVjbGluaW5nJztcbiAgICBzdHJlbmd0aDogbnVtYmVyO1xuICAgIGRlc2NyaXB0aW9uOiBzdHJpbmc7XG4gIH07XG4gIHJlY29tbWVuZGF0aW9uczogc3RyaW5nW107XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ3JlYXRlU25hcHNob3RPcHRpb25zIHtcbiAgYWdlbnRJZDogc3RyaW5nO1xuICBjcml0ZXJpb25JZD86IHN0cmluZztcbiAgc25hcHNob3REYXRlOiBzdHJpbmc7XG4gIHBhc3NSYXRlPzogc3RyaW5nO1xuICBldmFsQ291bnQ/OiBudW1iZXI7XG4gIG1lYW5TY29yZT86IHN0cmluZztcbiAgc2F0dXJhdGlvblR5cGU/OiBTYXR1cmF0aW9uVHlwZTtcbiAgZGF5c0F0U2F0dXJhdGlvbj86IG51bWJlcjtcbiAgdHJlbmREaXJlY3Rpb24/OiBzdHJpbmc7XG4gIHRyZW5kU3RyZW5ndGg/OiBzdHJpbmc7XG4gIGhlYWx0aFN0YXR1cz86IEhlYWx0aFN0YXR1cztcbiAgaGVhbHRoU2NvcmU/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ3JlYXRlUmVncmVzc2lvbk9wdGlvbnMge1xuICBhZ2VudElkOiBzdHJpbmc7XG4gIGNyaXRlcmlvbklkPzogc3RyaW5nO1xuICBzZXZlcml0eTogUmVncmVzc2lvblNldmVyaXR5O1xuICBiYXNlbGluZVBhc3NSYXRlOiBzdHJpbmc7XG4gIGN1cnJlbnRQYXNzUmF0ZTogc3RyaW5nO1xuICBkZWx0YTogc3RyaW5nO1xuICBkZWx0YVBlcmNlbnQ/OiBzdHJpbmc7XG4gIGJhc2VsaW5lUGVyaW9kU3RhcnQ6IHN0cmluZztcbiAgYmFzZWxpbmVQZXJpb2RFbmQ6IHN0cmluZztcbiAgY3VycmVudFBlcmlvZFN0YXJ0OiBzdHJpbmc7XG4gIGN1cnJlbnRQZXJpb2RFbmQ6IHN0cmluZztcbiAgYmFzZWxpbmVFdmFsQ291bnQ/OiBudW1iZXI7XG4gIGN1cnJlbnRFdmFsQ291bnQ/OiBudW1iZXI7XG4gIHN1c3BlY3RlZENhdXNlcz86IHVua25vd25bXTtcbiAgaXNTaWduaWZpY2FudD86IGJvb2xlYW47XG4gIGRldGVjdGVkQXQ/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVzb2x2ZVJlZ3Jlc3Npb25PcHRpb25zIHtcbiAgcmVzb2x1dGlvblR5cGU6IHN0cmluZztcbiAgbm90ZXM/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgR2V0U25hcHNob3RzT3B0aW9ucyB7XG4gIGFnZW50SWQ6IHN0cmluZztcbiAgY3JpdGVyaW9uSWQ/OiBzdHJpbmc7XG4gIHN0YXJ0RGF0ZT86IHN0cmluZztcbiAgZW5kRGF0ZT86IHN0cmluZztcbn1cblxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy8gRVZBTCBIRUFMVEggQVBJIENMSUVOVFxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4vKipcbiAqIEV2YWx1YXRpb24gSGVhbHRoIEFQSSBjbGllbnQgZm9yIG1vbml0b3JpbmcgZXZhbCBxdWFsaXR5IGFuZCBkZXRlY3RpbmcgcmVncmVzc2lvbnNcbiAqL1xuZXhwb3J0IGNvbnN0IGV2YWxIZWFsdGggPSB7XG4gIC8qKlxuICAgKiBHZXQgY29tcHJlaGVuc2l2ZSBoZWFsdGggcmVwb3J0IGZvciBhbiBhZ2VudFxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiBgYGB0eXBlc2NyaXB0XG4gICAqIGNvbnN0IHJlcG9ydCA9IGF3YWl0IGV2YWxIZWFsdGguZ2V0UmVwb3J0KCdhZ2VudF8xMjMnKTtcbiAgICogY29uc29sZS5sb2coYE92ZXJhbGwgaGVhbHRoOiAke3JlcG9ydC5vdmVyYWxsSGVhbHRofWApO1xuICAgKiBjb25zb2xlLmxvZyhgQWN0aXZlIHJlZ3Jlc3Npb25zOiAke3JlcG9ydC5yZWdyZXNzaW9uQ291bnR9YCk7XG4gICAqIGBgYFxuICAgKi9cbiAgYXN5bmMgZ2V0UmVwb3J0KGFnZW50SWQ6IHN0cmluZyk6IFByb21pc2U8SGVhbHRoUmVwb3J0PiB7XG4gICAgcmV0dXJuIGFwaVJlcXVlc3RXaXRoRGF0YTxIZWFsdGhSZXBvcnQ+KFxuICAgICAgYC9ldmFsLWhlYWx0aC9yZXBvcnQ/YWdlbnRJZD0ke2FnZW50SWR9YCxcbiAgICAgIHsgYXBpVmVyc2lvbjogJ3YxJyB9XG4gICAgKTtcbiAgfSxcblxuICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgLy8gU05BUFNIT1RTXG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4gIC8qKlxuICAgKiBHZXQgaGlzdG9yaWNhbCBoZWFsdGggc25hcHNob3RzXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIGBgYHR5cGVzY3JpcHRcbiAgICogY29uc3Qgc25hcHNob3RzID0gYXdhaXQgZXZhbEhlYWx0aC5nZXRTbmFwc2hvdHMoe1xuICAgKiAgIGFnZW50SWQ6ICdhZ2VudF8xMjMnLFxuICAgKiAgIHN0YXJ0RGF0ZTogJzIwMjQtMDEtMDFUMDA6MDA6MDBaJyxcbiAgICogICBlbmREYXRlOiAnMjAyNC0wMS0zMVQyMzo1OTo1OVonLFxuICAgKiB9KTtcbiAgICogYGBgXG4gICAqL1xuICBhc3luYyBnZXRTbmFwc2hvdHMob3B0aW9uczogR2V0U25hcHNob3RzT3B0aW9ucyk6IFByb21pc2U8RXZhbEhlYWx0aFNuYXBzaG90W10+IHtcbiAgICBjb25zdCBwYXJhbXMgPSBuZXcgVVJMU2VhcmNoUGFyYW1zKCk7XG4gICAgcGFyYW1zLnNldCgnYWdlbnRJZCcsIG9wdGlvbnMuYWdlbnRJZCk7XG4gICAgaWYgKG9wdGlvbnMuY3JpdGVyaW9uSWQpIHBhcmFtcy5zZXQoJ2NyaXRlcmlvbklkJywgb3B0aW9ucy5jcml0ZXJpb25JZCk7XG4gICAgaWYgKG9wdGlvbnMuc3RhcnREYXRlKSBwYXJhbXMuc2V0KCdzdGFydERhdGUnLCBvcHRpb25zLnN0YXJ0RGF0ZSk7XG4gICAgaWYgKG9wdGlvbnMuZW5kRGF0ZSkgcGFyYW1zLnNldCgnZW5kRGF0ZScsIG9wdGlvbnMuZW5kRGF0ZSk7XG5cbiAgICByZXR1cm4gYXBpUmVxdWVzdFdpdGhEYXRhPEV2YWxIZWFsdGhTbmFwc2hvdFtdPihcbiAgICAgIGAvZXZhbC1oZWFsdGgvc25hcHNob3RzPyR7cGFyYW1zLnRvU3RyaW5nKCl9YCxcbiAgICAgIHsgYXBpVmVyc2lvbjogJ3YxJyB9XG4gICAgKTtcbiAgfSxcblxuICAvKipcbiAgICogR2V0IGxhdGVzdCBoZWFsdGggc25hcHNob3RcbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogYGBgdHlwZXNjcmlwdFxuICAgKiBjb25zdCBzbmFwc2hvdCA9IGF3YWl0IGV2YWxIZWFsdGguZ2V0TGF0ZXN0U25hcHNob3QoJ2FnZW50XzEyMycpO1xuICAgKiBgYGBcbiAgICovXG4gIGFzeW5jIGdldExhdGVzdFNuYXBzaG90KGFnZW50SWQ6IHN0cmluZywgY3JpdGVyaW9uSWQ/OiBzdHJpbmcpOiBQcm9taXNlPEV2YWxIZWFsdGhTbmFwc2hvdCB8IG51bGw+IHtcbiAgICBjb25zdCBwYXJhbXMgPSBuZXcgVVJMU2VhcmNoUGFyYW1zKCk7XG4gICAgcGFyYW1zLnNldCgnYWdlbnRJZCcsIGFnZW50SWQpO1xuICAgIGlmIChjcml0ZXJpb25JZCkgcGFyYW1zLnNldCgnY3JpdGVyaW9uSWQnLCBjcml0ZXJpb25JZCk7XG5cbiAgICByZXR1cm4gYXBpUmVxdWVzdFdpdGhEYXRhPEV2YWxIZWFsdGhTbmFwc2hvdCB8IG51bGw+KFxuICAgICAgYC9ldmFsLWhlYWx0aC9zbmFwc2hvdHMvbGF0ZXN0PyR7cGFyYW1zLnRvU3RyaW5nKCl9YCxcbiAgICAgIHsgYXBpVmVyc2lvbjogJ3YxJyB9XG4gICAgKTtcbiAgfSxcblxuICAvKipcbiAgICogUmVjb3JkIGEgaGVhbHRoIHNuYXBzaG90XG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIGBgYHR5cGVzY3JpcHRcbiAgICogY29uc3Qgc25hcHNob3QgPSBhd2FpdCBldmFsSGVhbHRoLnJlY29yZFNuYXBzaG90KHtcbiAgICogICBhZ2VudElkOiAnYWdlbnRfMTIzJyxcbiAgICogICBzbmFwc2hvdERhdGU6IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKSxcbiAgICogICBwYXNzUmF0ZTogJzAuODUnLFxuICAgKiAgIGV2YWxDb3VudDogMTUwLFxuICAgKiAgIGhlYWx0aFN0YXR1czogJ2hlYWx0aHknLFxuICAgKiB9KTtcbiAgICogYGBgXG4gICAqL1xuICBhc3luYyByZWNvcmRTbmFwc2hvdChvcHRpb25zOiBDcmVhdGVTbmFwc2hvdE9wdGlvbnMpOiBQcm9taXNlPEV2YWxIZWFsdGhTbmFwc2hvdD4ge1xuICAgIHJldHVybiBhcGlSZXF1ZXN0V2l0aERhdGE8RXZhbEhlYWx0aFNuYXBzaG90PignL2V2YWwtaGVhbHRoL3NuYXBzaG90cycsIHtcbiAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgYm9keTogb3B0aW9ucyxcbiAgICAgIGFwaVZlcnNpb246ICd2MScsXG4gICAgfSk7XG4gIH0sXG5cbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gIC8vIFJFR1JFU1NJT05TXG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4gIC8qKlxuICAgKiBHZXQgdW5yZXNvbHZlZCByZWdyZXNzaW9ucyBmb3IgYW4gYWdlbnRcbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogYGBgdHlwZXNjcmlwdFxuICAgKiBjb25zdCByZWdyZXNzaW9ucyA9IGF3YWl0IGV2YWxIZWFsdGguZ2V0UmVncmVzc2lvbnMoJ2FnZW50XzEyMycpO1xuICAgKiBmb3IgKGNvbnN0IHJlZ3Jlc3Npb24gb2YgcmVncmVzc2lvbnMpIHtcbiAgICogICBjb25zb2xlLmxvZyhgJHtyZWdyZXNzaW9uLnNldmVyaXR5fTogJHtyZWdyZXNzaW9uLmRlbHRhfSUgZHJvcGApO1xuICAgKiB9XG4gICAqIGBgYFxuICAgKi9cbiAgYXN5bmMgZ2V0UmVncmVzc2lvbnMoYWdlbnRJZDogc3RyaW5nKTogUHJvbWlzZTxFdmFsUmVncmVzc2lvbltdPiB7XG4gICAgcmV0dXJuIGFwaVJlcXVlc3RXaXRoRGF0YTxFdmFsUmVncmVzc2lvbltdPihcbiAgICAgIGAvZXZhbC1oZWFsdGgvcmVncmVzc2lvbnM/YWdlbnRJZD0ke2FnZW50SWR9YCxcbiAgICAgIHsgYXBpVmVyc2lvbjogJ3YxJyB9XG4gICAgKTtcbiAgfSxcblxuICAvKipcbiAgICogUmVjb3JkIGEgbmV3IHJlZ3Jlc3Npb25cbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogYGBgdHlwZXNjcmlwdFxuICAgKiBjb25zdCByZWdyZXNzaW9uID0gYXdhaXQgZXZhbEhlYWx0aC5yZWNvcmRSZWdyZXNzaW9uKHtcbiAgICogICBhZ2VudElkOiAnYWdlbnRfMTIzJyxcbiAgICogICBzZXZlcml0eTogJ21vZGVyYXRlJyxcbiAgICogICBiYXNlbGluZVBhc3NSYXRlOiAnMC45MicsXG4gICAqICAgY3VycmVudFBhc3NSYXRlOiAnMC43OCcsXG4gICAqICAgZGVsdGE6ICctMC4xNCcsXG4gICAqICAgYmFzZWxpbmVQZXJpb2RTdGFydDogJzIwMjQtMDEtMDFUMDA6MDA6MDBaJyxcbiAgICogICBiYXNlbGluZVBlcmlvZEVuZDogJzIwMjQtMDEtMTVUMjM6NTk6NTlaJyxcbiAgICogICBjdXJyZW50UGVyaW9kU3RhcnQ6ICcyMDI0LTAxLTE2VDAwOjAwOjAwWicsXG4gICAqICAgY3VycmVudFBlcmlvZEVuZDogJzIwMjQtMDEtMzFUMjM6NTk6NTlaJyxcbiAgICogfSk7XG4gICAqIGBgYFxuICAgKi9cbiAgYXN5bmMgcmVjb3JkUmVncmVzc2lvbihvcHRpb25zOiBDcmVhdGVSZWdyZXNzaW9uT3B0aW9ucyk6IFByb21pc2U8RXZhbFJlZ3Jlc3Npb24+IHtcbiAgICByZXR1cm4gYXBpUmVxdWVzdFdpdGhEYXRhPEV2YWxSZWdyZXNzaW9uPignL2V2YWwtaGVhbHRoL3JlZ3Jlc3Npb25zJywge1xuICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICBib2R5OiBvcHRpb25zLFxuICAgICAgYXBpVmVyc2lvbjogJ3YxJyxcbiAgICB9KTtcbiAgfSxcblxuICAvKipcbiAgICogUmVzb2x2ZSBhIHJlZ3Jlc3Npb25cbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogYGBgdHlwZXNjcmlwdFxuICAgKiBhd2FpdCBldmFsSGVhbHRoLnJlc29sdmVSZWdyZXNzaW9uKCdyZWdyZXNzaW9uXzEyMycsIHtcbiAgICogICByZXNvbHV0aW9uVHlwZTogJ2ZpeGVkJyxcbiAgICogICBub3RlczogJ1VwZGF0ZWQgcHJvbXB0IHRlbXBsYXRlIHRvIGFkZHJlc3MgcXVhbGl0eSBpc3N1ZXMnLFxuICAgKiB9KTtcbiAgICogYGBgXG4gICAqL1xuICBhc3luYyByZXNvbHZlUmVncmVzc2lvbihyZWdyZXNzaW9uSWQ6IHN0cmluZywgb3B0aW9uczogUmVzb2x2ZVJlZ3Jlc3Npb25PcHRpb25zKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgYXBpUmVxdWVzdChgL2V2YWwtaGVhbHRoL3JlZ3Jlc3Npb25zLyR7cmVncmVzc2lvbklkfS9yZXNvbHZlYCwge1xuICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICBib2R5OiBvcHRpb25zLFxuICAgICAgYXBpVmVyc2lvbjogJ3YxJyxcbiAgICB9KTtcbiAgfSxcblxuICAvKipcbiAgICogQWNrbm93bGVkZ2UgYSByZWdyZXNzaW9uXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIGBgYHR5cGVzY3JpcHRcbiAgICogYXdhaXQgZXZhbEhlYWx0aC5hY2tub3dsZWRnZVJlZ3Jlc3Npb24oJ3JlZ3Jlc3Npb25fMTIzJyk7XG4gICAqIGBgYFxuICAgKi9cbiAgYXN5bmMgYWNrbm93bGVkZ2VSZWdyZXNzaW9uKHJlZ3Jlc3Npb25JZDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgYXBpUmVxdWVzdChgL2V2YWwtaGVhbHRoL3JlZ3Jlc3Npb25zLyR7cmVncmVzc2lvbklkfS9hY2tub3dsZWRnZWAsIHtcbiAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgYXBpVmVyc2lvbjogJ3YxJyxcbiAgICB9KTtcbiAgfSxcbn07XG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIEhFTFBFUiBGVU5DVElPTlNcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuLyoqXG4gKiBDaGVjayBpZiBoZWFsdGggc3RhdHVzIGluZGljYXRlcyBhbiBpc3N1ZVxuICpcbiAqIEBwYXJhbSBzdGF0dXMgLSBIZWFsdGggc3RhdHVzIHRvIGNoZWNrXG4gKiBAcmV0dXJucyBXaGV0aGVyIHRoZSBzdGF0dXMgaW5kaWNhdGVzIGEgcHJvYmxlbVxuICovXG5leHBvcnQgZnVuY3Rpb24gaGFzSGVhbHRoSXNzdWUoc3RhdHVzOiBIZWFsdGhTdGF0dXMpOiBib29sZWFuIHtcbiAgcmV0dXJuIHN0YXR1cyA9PT0gJ3dhcm5pbmcnIHx8IHN0YXR1cyA9PT0gJ2NyaXRpY2FsJztcbn1cblxuLyoqXG4gKiBHZXQgc2V2ZXJpdHkgbGV2ZWwgYXMgbnVtZXJpYyB2YWx1ZSBmb3Igc29ydGluZ1xuICpcbiAqIEBwYXJhbSBzZXZlcml0eSAtIFJlZ3Jlc3Npb24gc2V2ZXJpdHlcbiAqIEByZXR1cm5zIE51bWVyaWMgc2V2ZXJpdHkgKDEtMywgaGlnaGVyIGlzIHdvcnNlKVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0U2V2ZXJpdHlMZXZlbChzZXZlcml0eTogUmVncmVzc2lvblNldmVyaXR5KTogbnVtYmVyIHtcbiAgc3dpdGNoIChzZXZlcml0eSkge1xuICAgIGNhc2UgJ21pbm9yJzogcmV0dXJuIDE7XG4gICAgY2FzZSAnbW9kZXJhdGUnOiByZXR1cm4gMjtcbiAgICBjYXNlICdzZXZlcmUnOiByZXR1cm4gMztcbiAgICBkZWZhdWx0OiByZXR1cm4gMDtcbiAgfVxufVxuXG4vKipcbiAqIENoZWNrIGlmIGV2YWx1YXRpb24gaXMgc2F0dXJhdGVkXG4gKlxuICogQHBhcmFtIHNuYXBzaG90IC0gSGVhbHRoIHNuYXBzaG90IHRvIGNoZWNrXG4gKiBAcmV0dXJucyBXaGV0aGVyIGV2YWx1YXRpb24gaXMgYXQgY2VpbGluZyBvciBmbG9vclxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNTYXR1cmF0ZWQoc25hcHNob3Q6IEV2YWxIZWFsdGhTbmFwc2hvdCk6IGJvb2xlYW4ge1xuICByZXR1cm4gc25hcHNob3Quc2F0dXJhdGlvblR5cGUgPT09ICdjZWlsaW5nJyB8fCBzbmFwc2hvdC5zYXR1cmF0aW9uVHlwZSA9PT0gJ2Zsb29yJztcbn1cblxuLyoqXG4gKiBHZXQgcmVjb21tZW5kYXRpb24gZm9yIHNhdHVyYXRpb24gdHlwZVxuICpcbiAqIEBwYXJhbSBzYXR1cmF0aW9uVHlwZSAtIFR5cGUgb2Ygc2F0dXJhdGlvblxuICogQHJldHVybnMgUmVjb21tZW5kYXRpb24gc3RyaW5nXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRTYXR1cmF0aW9uUmVjb21tZW5kYXRpb24oc2F0dXJhdGlvblR5cGU6IFNhdHVyYXRpb25UeXBlKTogc3RyaW5nIHtcbiAgc3dpdGNoIChzYXR1cmF0aW9uVHlwZSkge1xuICAgIGNhc2UgJ2NlaWxpbmcnOlxuICAgICAgcmV0dXJuICdFdmFsdWF0aW9uIGNyaXRlcmlhIG1heSBiZSB0b28gbGVuaWVudC4gQ29uc2lkZXIgYWRkaW5nIHN0cmljdGVyIGNoZWNrcyBvciBtb3JlIGNoYWxsZW5naW5nIHRlc3QgY2FzZXMuJztcbiAgICBjYXNlICdmbG9vcic6XG4gICAgICByZXR1cm4gJ0V2YWx1YXRpb24gY3JpdGVyaWEgbWF5IGJlIHRvbyBzdHJpY3QuIENvbnNpZGVyIHJlbGF4aW5nIHRocmVzaG9sZHMgb3IgcmV2aWV3aW5nIGNyaXRlcmlhIGZvciBhY2N1cmFjeS4nO1xuICAgIGNhc2UgJ2hlYWx0aHknOlxuICAgICAgcmV0dXJuICdFdmFsdWF0aW9uIGlzIG9wZXJhdGluZyB3aXRoaW4gaGVhbHRoeSBwYXJhbWV0ZXJzLic7XG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiAnVW5hYmxlIHRvIGRldGVybWluZSBzYXR1cmF0aW9uIHN0YXR1cy4nO1xuICB9XG59XG4iXX0=
|