@pipeline-builder/api-core 5.2.2 → 5.2.4
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/lib/constants/ai-providers.d.ts +3 -22
- package/lib/constants/ai-providers.js +6 -56
- package/lib/errors/app-errors.d.ts +14 -0
- package/lib/errors/app-errors.js +21 -1
- package/lib/helpers/index.d.ts +1 -0
- package/lib/helpers/index.js +2 -1
- package/lib/helpers/sse-helpers.d.ts +33 -3
- package/lib/helpers/sse-helpers.js +91 -19
- package/lib/helpers/support-calendar.d.ts +69 -0
- package/lib/helpers/support-calendar.js +179 -0
- package/lib/middleware/auth.js +6 -3
- package/lib/middleware/deferred-quota-check.d.ts +5 -0
- package/lib/middleware/deferred-quota-check.js +33 -0
- package/lib/middleware/ecosystem-guard.d.ts +3 -3
- package/lib/middleware/ecosystem-guard.js +5 -5
- package/lib/middleware/index.d.ts +5 -2
- package/lib/middleware/index.js +6 -3
- package/lib/middleware/on-behalf.d.ts +37 -0
- package/lib/middleware/on-behalf.js +143 -0
- package/lib/middleware/permission-gates.d.ts +11 -0
- package/lib/middleware/permission-gates.js +7 -1
- package/lib/middleware/quota-exempt-routes.d.ts +36 -0
- package/lib/middleware/quota-exempt-routes.js +47 -0
- package/lib/middleware/route-table.d.ts +104 -0
- package/lib/middleware/route-table.js +72 -2
- package/lib/middleware/service-tokens.d.ts +8 -0
- package/lib/middleware/service-tokens.js +5 -3
- package/lib/middleware/step-up.js +11 -1
- package/lib/services/ai-call-weight.d.ts +24 -0
- package/lib/services/ai-call-weight.js +77 -0
- package/lib/services/alert-delivery.d.ts +99 -0
- package/lib/services/alert-delivery.js +132 -0
- package/lib/services/audit-context.d.ts +105 -0
- package/lib/services/audit-context.js +134 -0
- package/lib/services/index.d.ts +10 -2
- package/lib/services/index.js +10 -2
- package/lib/services/org-ai-client.d.ts +61 -0
- package/lib/services/org-ai-client.js +112 -0
- package/lib/services/pagerduty-inbound.d.ts +101 -0
- package/lib/services/pagerduty-inbound.js +195 -0
- package/lib/services/pagerduty.d.ts +109 -0
- package/lib/services/pagerduty.js +186 -0
- package/lib/services/quota-increment-batcher.d.ts +81 -0
- package/lib/services/quota-increment-batcher.js +166 -0
- package/lib/services/quota.d.ts +158 -14
- package/lib/services/quota.js +252 -22
- package/lib/services/remote-audit-client.d.ts +44 -1
- package/lib/services/remote-audit-client.js +106 -20
- package/lib/services/version-vuln-policy.d.ts +174 -0
- package/lib/services/version-vuln-policy.js +242 -0
- package/lib/types/ai-catalog.d.ts +63 -0
- package/lib/types/ai-catalog.js +82 -0
- package/lib/types/ask-proposals.js +6 -6
- package/lib/types/build-catalog.d.ts +154 -0
- package/lib/types/build-catalog.js +158 -0
- package/lib/types/common.d.ts +37 -3
- package/lib/types/common.js +20 -2
- package/lib/types/ecosystem-notifications.d.ts +5 -5
- package/lib/types/ecosystem-notifications.js +9 -3
- package/lib/types/error-codes.d.ts +13 -6
- package/lib/types/error-codes.js +18 -8
- package/lib/types/feature-flags.d.ts +71 -1
- package/lib/types/feature-flags.js +131 -11
- package/lib/types/index.d.ts +6 -4
- package/lib/types/index.js +12 -5
- package/lib/types/metadata-keys.d.ts +6 -0
- package/lib/types/metadata-keys.js +4 -1
- package/lib/types/permissions.d.ts +351 -3
- package/lib/types/permissions.js +610 -21
- package/lib/types/pipeline.d.ts +39 -0
- package/lib/types/pipeline.js +57 -1
- package/lib/types/plugin-health.d.ts +0 -2
- package/lib/types/plugin-health.js +1 -11
- package/lib/types/plugin-scan.d.ts +192 -42
- package/lib/types/plugin-scan.js +159 -43
- package/lib/types/quota-catalog.d.ts +247 -0
- package/lib/types/quota-catalog.js +122 -0
- package/lib/types/quota-tiers.d.ts +150 -0
- package/lib/types/quota-tiers.js +167 -2
- package/lib/types/remote-audit-actions.d.ts +1 -1
- package/lib/types/remote-audit-actions.js +217 -4
- package/lib/types/wire-vocabulary.js +8 -1
- package/lib/utils/index.d.ts +1 -1
- package/lib/utils/index.js +2 -2
- package/lib/utils/response.d.ts +35 -2
- package/lib/utils/response.js +42 -3
- package/lib/validation/ai-schemas.d.ts +27 -0
- package/lib/validation/ai-schemas.js +31 -5
- package/lib/validation/plugin-schemas.d.ts +15 -0
- package/lib/validation/plugin-schemas.js +28 -1
- package/package.json +31 -2
|
@@ -4,7 +4,20 @@ export interface RemoteAuditEvent {
|
|
|
4
4
|
action: RemoteAuditAction;
|
|
5
5
|
actorId: string;
|
|
6
6
|
actorEmail?: string;
|
|
7
|
-
|
|
7
|
+
/**
|
|
8
|
+
* The org the event is recorded FOR — REQUIRED. The platform ingest binds every
|
|
9
|
+
* event to the service token's org, and the client mints that token with this
|
|
10
|
+
* value, so an org-less event can never be stored (it used to be refused 403
|
|
11
|
+
* "no org claim" and then wedge the spool). System work with no tenant passes
|
|
12
|
+
* `SYSTEM_ORG_ID` explicitly — e.g. a registry GC sweep.
|
|
13
|
+
*/
|
|
14
|
+
orgId: string;
|
|
15
|
+
/**
|
|
16
|
+
* The org the action touched, when it is NOT `orgId` (the system org acting on
|
|
17
|
+
* a publisher's plugin, a superadmin purging a tenant's pipeline). Accepted
|
|
18
|
+
* cross-org only from a system-org token, or when the inbound principal was a
|
|
19
|
+
* superadmin / system-org member (see `auditCrossOrg` in the ingest).
|
|
20
|
+
*/
|
|
8
21
|
affectedOrgId?: string;
|
|
9
22
|
targetType?: string;
|
|
10
23
|
targetId?: string;
|
|
@@ -28,8 +41,38 @@ export interface RemoteAuditEvent {
|
|
|
28
41
|
* copy so a live attempt and its later re-delivery collapse to ONE stored row.
|
|
29
42
|
*/
|
|
30
43
|
idempotencyKey?: string;
|
|
44
|
+
/**
|
|
45
|
+
* Correlation context. Normally left unset: `record()` fills each from the
|
|
46
|
+
* ambient audit context (see `runWithAuditContext`) — the inbound request's id,
|
|
47
|
+
* trace id, client ip and user agent. Set one only to override it.
|
|
48
|
+
*
|
|
49
|
+
* An ANONYMOUS actor never inherits the client ip / user agent from context:
|
|
50
|
+
* those rows are the public, unauthenticated surfaces (plugin submissions,
|
|
51
|
+
* report verify/unsubscribe) whose callers deliberately record only a HASHED
|
|
52
|
+
* ip/address — stamping the raw ip beside it would undo that. Pass `ip` /
|
|
53
|
+
* `userAgent` explicitly if an anonymous row genuinely needs them.
|
|
54
|
+
*/
|
|
55
|
+
requestId?: string;
|
|
56
|
+
traceId?: string;
|
|
57
|
+
ip?: string;
|
|
58
|
+
userAgent?: string;
|
|
59
|
+
/**
|
|
60
|
+
* Free-form event detail. Keep it free of secrets/tokens, PII and AWS account
|
|
61
|
+
* ids. The keys `_auth` and `_context` are RESERVED: `record()` replaces them
|
|
62
|
+
* with the verified credential block and the correlation/job ids from the
|
|
63
|
+
* ambient audit context, whatever the call site passed.
|
|
64
|
+
*/
|
|
31
65
|
details?: Record<string, unknown>;
|
|
32
66
|
}
|
|
67
|
+
/**
|
|
68
|
+
* The event as it goes over the wire and into the spool: the call-site event
|
|
69
|
+
* plus what `record()` stamps from the ambient audit context. `impersonatorId` is
|
|
70
|
+
* NOT a call-site field — it comes only from the inbound request's verified
|
|
71
|
+
* token, so no route can attribute an action to an impersonator by passing one.
|
|
72
|
+
*/
|
|
73
|
+
export interface RemoteAuditWireEvent extends RemoteAuditEvent {
|
|
74
|
+
impersonatorId?: string;
|
|
75
|
+
}
|
|
33
76
|
/**
|
|
34
77
|
* Client for POSTing audit events to the platform's `/audit-events` ingest
|
|
35
78
|
* endpoint. Mints a fresh service token per call (5 min TTL) there's no
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
// Copyright 2026 Pipeline Builder Contributors
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
import { randomUUID } from 'crypto';
|
|
4
|
+
import { auditAuthBlock, currentAuditContext } from './audit-context.js';
|
|
4
5
|
import { auditSpoolKey, createEnvRedisAuditSpool } from './audit-spool.js';
|
|
5
6
|
import { createSafeClient } from './http-client.js';
|
|
6
7
|
import { setAuthzDenialAuditor } from '../middleware/permission-gates.js';
|
|
7
8
|
import { getServiceAuthHeader } from '../middleware/service-tokens.js';
|
|
9
|
+
import { SYSTEM_ORG_ID } from '../middleware/system-org.js';
|
|
8
10
|
import {} from '../types/remote-audit-actions.js';
|
|
11
|
+
import { ANONYMOUS_ACTOR_ID } from '../utils/identity.js';
|
|
9
12
|
import { createLogger } from '../utils/logger.js';
|
|
10
13
|
import { emitCounter } from '../utils/metric-emitter.js';
|
|
11
14
|
import { errorMessage } from '../utils/response.js';
|
|
@@ -24,6 +27,49 @@ const AUDIT_REQUEST_OPTIONS = {
|
|
|
24
27
|
maxRateLimitRetries: 2,
|
|
25
28
|
maxRetries: 2,
|
|
26
29
|
};
|
|
30
|
+
/** `details` keys only `record()` may write (see {@link RemoteAuditEvent.details}). */
|
|
31
|
+
const RESERVED_DETAIL_KEYS = ['_auth', '_context'];
|
|
32
|
+
/**
|
|
33
|
+
* Stamp an event with the ambient audit context at the moment it is RECORDED.
|
|
34
|
+
* Persisted on the event, so a spooled re-delivery carries the original
|
|
35
|
+
* request's context rather than whatever is ambient when the drain runs.
|
|
36
|
+
*/
|
|
37
|
+
function stampAuditContext(event) {
|
|
38
|
+
const ctx = currentAuditContext();
|
|
39
|
+
const principal = ctx?.principal?.();
|
|
40
|
+
const auth = auditAuthBlock(principal);
|
|
41
|
+
const context = { ...ctx?.correlation, ...ctx?.job };
|
|
42
|
+
const anonymous = event.actorId === ANONYMOUS_ACTOR_ID;
|
|
43
|
+
const details = { ...event.details };
|
|
44
|
+
for (const key of RESERVED_DETAIL_KEYS)
|
|
45
|
+
delete details[key];
|
|
46
|
+
if (auth)
|
|
47
|
+
details._auth = auth;
|
|
48
|
+
if (Object.keys(context).length > 0)
|
|
49
|
+
details._context = context;
|
|
50
|
+
return {
|
|
51
|
+
...event,
|
|
52
|
+
requestId: event.requestId ?? ctx?.requestId,
|
|
53
|
+
traceId: event.traceId ?? ctx?.traceId,
|
|
54
|
+
ip: event.ip ?? (anonymous ? undefined : ctx?.ip),
|
|
55
|
+
userAgent: event.userAgent ?? (anonymous ? undefined : ctx?.userAgent),
|
|
56
|
+
...(principal?.impersonatorId ? { impersonatorId: principal.impersonatorId } : {}),
|
|
57
|
+
...(Object.keys(details).length > 0 ? { details } : { details: undefined }),
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Whether this event may name an `affectedOrgId` outside its own org. Derived
|
|
62
|
+
* ONLY from the stamped `_auth` block (the verified inbound principal), which
|
|
63
|
+
* `record()` always overwrites — a call site cannot grant it.
|
|
64
|
+
*/
|
|
65
|
+
function crossOrgAuthorized(event) {
|
|
66
|
+
if (!event.affectedOrgId || event.affectedOrgId === event.orgId)
|
|
67
|
+
return false;
|
|
68
|
+
const auth = event.details?._auth;
|
|
69
|
+
return auth?.superAdmin === true || auth?.systemOrg === true;
|
|
70
|
+
}
|
|
71
|
+
/** 4xx statuses that are transient, not a verdict on the event. */
|
|
72
|
+
const RETRYABLE_4XX = new Set([408, 429]);
|
|
27
73
|
/**
|
|
28
74
|
* Construct a remote-audit client targeted at the platform service.
|
|
29
75
|
*
|
|
@@ -75,23 +121,49 @@ export function createRemoteAuditClient(config = {}) {
|
|
|
75
121
|
// the rejection would go unhandled and crash-loop the pod on its first
|
|
76
122
|
// audited write. Inside, a key problem is just an undeliverable event:
|
|
77
123
|
// spooled, or dropped and metered.
|
|
78
|
-
const authHeader = getServiceAuthHeader({
|
|
124
|
+
const authHeader = getServiceAuthHeader({
|
|
125
|
+
serviceName,
|
|
126
|
+
orgId: event.orgId,
|
|
127
|
+
role: 'member',
|
|
128
|
+
...(crossOrgAuthorized(event) ? { auditCrossOrg: true } : {}),
|
|
129
|
+
});
|
|
79
130
|
const headers = {
|
|
80
131
|
'Authorization': authHeader,
|
|
81
132
|
'Idempotency-Key': event.idempotencyKey ?? randomUUID(),
|
|
82
133
|
};
|
|
83
134
|
const response = await client.post('/audit/events', event, { headers, ...AUDIT_REQUEST_OPTIONS });
|
|
84
|
-
const
|
|
85
|
-
if (
|
|
86
|
-
|
|
135
|
+
const status = response?.statusCode;
|
|
136
|
+
if (status !== undefined && status >= 200 && status < 300)
|
|
137
|
+
return { kind: 'delivered' };
|
|
138
|
+
if (status !== undefined && status >= 400 && status < 500 && !RETRYABLE_4XX.has(status)) {
|
|
139
|
+
return { kind: 'rejected', status };
|
|
87
140
|
}
|
|
88
|
-
|
|
141
|
+
logger.warn('Remote audit ingest non-ok', { action: event.action, statusCode: status });
|
|
142
|
+
return { kind: 'retry' };
|
|
89
143
|
}
|
|
90
144
|
catch (err) {
|
|
91
145
|
logger.warn('Remote audit ingest threw', { action: event.action, error: errorMessage(err) });
|
|
92
|
-
return
|
|
146
|
+
return { kind: 'retry' };
|
|
93
147
|
}
|
|
94
148
|
}
|
|
149
|
+
/**
|
|
150
|
+
* A permanently refused event is DROPPED — loudly. Spooling it would put it at
|
|
151
|
+
* the head of the queue forever (the drain stops at the first failure), so one
|
|
152
|
+
* malformed event would silently stall every later event this service emits.
|
|
153
|
+
* `AuditEventsRejected` pages on the counter.
|
|
154
|
+
*/
|
|
155
|
+
function reportRejected(event, serviceName, status) {
|
|
156
|
+
emitCounter('audit_events_rejected_total', { service: serviceName, status: String(status) });
|
|
157
|
+
logger.error('Remote audit event REJECTED by ingest (dropped, not retried)', {
|
|
158
|
+
action: event.action,
|
|
159
|
+
statusCode: status,
|
|
160
|
+
orgId: event.orgId,
|
|
161
|
+
affectedOrgId: event.affectedOrgId,
|
|
162
|
+
targetType: event.targetType,
|
|
163
|
+
targetId: event.targetId,
|
|
164
|
+
requestId: event.requestId,
|
|
165
|
+
});
|
|
166
|
+
}
|
|
95
167
|
// Serialize spool drains so a periodic tick and an on-success drain can't both
|
|
96
168
|
// pull the same batch. Stops early the moment a re-delivery fails (platform
|
|
97
169
|
// still down) so we don't hammer it or churn the buffer.
|
|
@@ -105,7 +177,9 @@ export function createRemoteAuditClient(config = {}) {
|
|
|
105
177
|
const batch = await spool.take(drainBatchSize);
|
|
106
178
|
if (batch.length === 0)
|
|
107
179
|
return;
|
|
108
|
-
|
|
180
|
+
// `settled` = delivered OR permanently rejected: either way it leaves the
|
|
181
|
+
// spool. Only a retryable failure stops the sweep and goes back.
|
|
182
|
+
const settled = [];
|
|
109
183
|
const failed = [];
|
|
110
184
|
let platformDown = false;
|
|
111
185
|
for (const entry of batch) {
|
|
@@ -113,21 +187,25 @@ export function createRemoteAuditClient(config = {}) {
|
|
|
113
187
|
failed.push(entry);
|
|
114
188
|
continue;
|
|
115
189
|
}
|
|
116
|
-
const
|
|
117
|
-
if (
|
|
118
|
-
|
|
190
|
+
const result = await deliver(entry.event, entry.serviceName);
|
|
191
|
+
if (result.kind === 'delivered') {
|
|
192
|
+
settled.push(entry);
|
|
119
193
|
emitCounter('audit_spool_redelivered_total', { service: entry.serviceName });
|
|
120
194
|
}
|
|
195
|
+
else if (result.kind === 'rejected') {
|
|
196
|
+
settled.push(entry);
|
|
197
|
+
reportRejected(entry.event, entry.serviceName, result.status);
|
|
198
|
+
}
|
|
121
199
|
else {
|
|
122
200
|
platformDown = true;
|
|
123
201
|
failed.push(entry);
|
|
124
202
|
}
|
|
125
203
|
}
|
|
126
|
-
// Acknowledge the
|
|
204
|
+
// Acknowledge the settled entries so they clear the in-progress list; the
|
|
127
205
|
// reliable take() moved the whole batch there, so unacked survivors are
|
|
128
206
|
// reclaimed by recover() after a crash rather than being silently lost.
|
|
129
|
-
if (
|
|
130
|
-
await spool.ack(
|
|
207
|
+
if (settled.length > 0)
|
|
208
|
+
await spool.ack(settled);
|
|
131
209
|
if (failed.length > 0) {
|
|
132
210
|
await spool.requeue(failed);
|
|
133
211
|
return; // still down — try again on the next tick
|
|
@@ -156,19 +234,23 @@ export function createRemoteAuditClient(config = {}) {
|
|
|
156
234
|
}
|
|
157
235
|
return {
|
|
158
236
|
record(event, serviceName) {
|
|
159
|
-
// Stamp
|
|
160
|
-
//
|
|
237
|
+
// Stamp the ambient request/job context and when the action actually
|
|
238
|
+
// occurred (all survive spool delay), and pin a stable idempotency key so a
|
|
239
|
+
// live attempt and its spooled retry dedup.
|
|
161
240
|
const stamped = {
|
|
162
|
-
...event,
|
|
241
|
+
...stampAuditContext(event),
|
|
163
242
|
occurredAt: event.occurredAt ?? new Date().toISOString(),
|
|
164
243
|
idempotencyKey: event.idempotencyKey ?? randomUUID(),
|
|
165
244
|
};
|
|
166
|
-
void deliver(stamped, serviceName).then((
|
|
167
|
-
if (
|
|
245
|
+
void deliver(stamped, serviceName).then((result) => {
|
|
246
|
+
if (result.kind === 'delivered') {
|
|
168
247
|
emitCounter('audit_emitted_total', { service: serviceName, outcome: stamped.outcome ?? 'success' });
|
|
169
248
|
if (spool)
|
|
170
249
|
void drain(); // platform is reachable — flush any backlog
|
|
171
250
|
}
|
|
251
|
+
else if (result.kind === 'rejected') {
|
|
252
|
+
reportRejected(stamped, serviceName, result.status);
|
|
253
|
+
}
|
|
172
254
|
else if (spool) {
|
|
173
255
|
void spool.enqueue({ event: stamped, serviceName });
|
|
174
256
|
}
|
|
@@ -208,11 +290,15 @@ export function createRemoteAuditClient(config = {}) {
|
|
|
208
290
|
* a RemoteAuditClient.
|
|
209
291
|
*/
|
|
210
292
|
export function wireAuthzDenialAuditor(serviceName, getClient) {
|
|
293
|
+
// Request context (ip / user agent / request id / credential / impersonator)
|
|
294
|
+
// is stamped by `record()` from the ambient audit context — the denial fires
|
|
295
|
+
// inside the request's scope. An unauthenticated denial has no org: it is
|
|
296
|
+
// recorded on the system org's chain rather than refused for lacking one.
|
|
211
297
|
setAuthzDenialAuditor((info) => getClient().record({
|
|
212
298
|
action: 'authz.denied',
|
|
213
299
|
actorId: info.actorId ?? 'anonymous',
|
|
214
300
|
actorEmail: info.actorEmail,
|
|
215
|
-
orgId: info.orgId,
|
|
301
|
+
orgId: info.orgId ?? SYSTEM_ORG_ID,
|
|
216
302
|
outcome: 'failure',
|
|
217
303
|
details: { method: info.method, path: info.path, required: info.required },
|
|
218
304
|
}, serviceName));
|
|
@@ -272,4 +358,4 @@ export function recordAudit(event) {
|
|
|
272
358
|
const { client, serviceName } = boundAudit();
|
|
273
359
|
client.record(event, serviceName);
|
|
274
360
|
}
|
|
275
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVtb3RlLWF1ZGl0LWNsaWVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zZXJ2aWNlcy9yZW1vdGUtYXVkaXQtY2xpZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUFFdEMsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLFFBQVEsQ0FBQztBQUNwQyxPQUFPLEVBQUUsYUFBYSxFQUFFLHdCQUF3QixFQUF5QyxNQUFNLGtCQUFrQixDQUFDO0FBQ2xILE9BQU8sRUFBRSxnQkFBZ0IsRUFBdUIsTUFBTSxrQkFBa0IsQ0FBQztBQUN6RSxPQUFPLEVBQUUscUJBQXFCLEVBQXdCLE1BQU0sbUNBQW1DLENBQUM7QUFDaEcsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFFdkUsT0FBTyxFQUEwQixNQUFNLGtDQUFrQyxDQUFDO0FBQzFFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUNsRCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDekQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ3BELE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUUvRCxNQUFNLE1BQU0sR0FBRyxZQUFZLENBQUMsY0FBYyxDQUFDLENBQUM7QUFFNUM7Ozs7Ozs7O0dBUUc7QUFDSCxNQUFNLHFCQUFxQixHQUErRDtJQUN4RixtQkFBbUIsRUFBRSxDQUFDO0lBQ3RCLFVBQVUsRUFBRSxDQUFDO0NBQ2QsQ0FBQztBQTBFRjs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQW1CRztBQUNILE1BQU0sVUFBVSx1QkFBdUIsQ0FBQyxNQUFNLEdBQTRCLEVBQUU7SUFDMUUsTUFBTSxhQUFhLEdBQWtCO1FBQ25DLElBQUksRUFBRSxNQUFNLENBQUMsSUFBSSxJQUFJLGVBQWUsQ0FBQyxVQUFVLENBQUMsQ0FB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QyxLQUF1QjtJQUNqRCxNQUFNLEVBQUUsTUFBTSxFQUFFLFdBQVcsRUFBRSxHQUFHLFVBQVUsRUFBRSxDQUFDO0lBQzdDLE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFLFdBQVcsQ0FBQyxDQUFDO0FBQ3BDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuaW1wb3J0IHsgcmFuZG9tVVVJRCB9IGZyb20gJ2NyeXB0byc7XG5pbXBvcnQgeyBhdWRpdFNwb29sS2V5LCBjcmVhdGVFbnZSZWRpc0F1ZGl0U3Bvb2wsIHR5cGUgQXVkaXRTcG9vbCwgdHlwZSBBdWRpdFNwb29sRW50cnkgfSBmcm9tICcuL2F1ZGl0LXNwb29sLmpzJztcbmltcG9ydCB7IGNyZWF0ZVNhZmVDbGllbnQsIHR5cGUgUmVxdWVzdE9wdGlvbnMgfSBmcm9tICcuL2h0dHAtY2xpZW50LmpzJztcbmltcG9ydCB7IHNldEF1dGh6RGVuaWFsQXVkaXRvciwgdHlwZSBBdXRoekRlbmlhbEluZm8gfSBmcm9tICcuLi9taWRkbGV3YXJlL3Blcm1pc3Npb24tZ2F0ZXMuanMnO1xuaW1wb3J0IHsgZ2V0U2VydmljZUF1dGhIZWFkZXIgfSBmcm9tICcuLi9taWRkbGV3YXJlL3NlcnZpY2UtdG9rZW5zLmpzJztcbmltcG9ydCB0eXBlIHsgU2VydmljZUNvbmZpZyB9IGZyb20gJy4uL3R5cGVzL2NvbW1vbi5qcyc7XG5pbXBvcnQgeyB0eXBlIFJlbW90ZUF1ZGl0QWN0aW9uIH0gZnJvbSAnLi4vdHlwZXMvcmVtb3RlLWF1ZGl0LWFjdGlvbnMuanMnO1xuaW1wb3J0IHsgY3JlYXRlTG9nZ2VyIH0gZnJvbSAnLi4vdXRpbHMvbG9nZ2VyLmpzJztcbmltcG9ydCB7IGVtaXRDb3VudGVyIH0gZnJvbSAnLi4vdXRpbHMvbWV0cmljLWVtaXR0ZXIuanMnO1xuaW1wb3J0IHsgZXJyb3JNZXNzYWdlIH0gZnJvbSAnLi4vdXRpbHMvcmVzcG9uc2UuanMnO1xuaW1wb3J0IHsgc2VydmljZUVuZHBvaW50IH0gZnJvbSAnLi4vdXRpbHMvc2VydmljZS1yZWdpc3RyeS5qcyc7XG5cbmNvbnN0IGxvZ2dlciA9IGNyZWF0ZUxvZ2dlcigncmVtb3RlLWF1ZGl0Jyk7XG5cbi8qKlxuICogQXVkaXQgaW5nZXN0IGlzIGJlc3QtZWZmb3J0IGFuZCBNVVNUIE5PVCBibG9jayB0aGUgY2FsbGVyLCBidXQgYSB0cmFuc2llbnRcbiAqIGZhaWx1cmUgKDQyOSAvIDV4eCAvIGNvbm5lY3Rpb24gcmVzZXQgLyB0aW1lb3V0KSBzaG91bGQgbm90IHNpbGVudGx5IGRyb3AgdGhlXG4gKiByb3cgb24gdGhlIGZpcnN0IGF0dGVtcHQuIEVhY2ggZW1pc3Npb24gY2FycmllcyBhIHN0YWJsZSBwZXItZXZlbnRcbiAqIGBJZGVtcG90ZW5jeS1LZXlgIChzZWUgYHJlY29yZGApLCBzbyB0aGUgaHR0cC1jbGllbnQgdHJlYXRzIHRoZSBQT1NUIGFzXG4gKiByZXRyeS1zYWZlIGFuZCB0aGUgcGxhdGZvcm0gY2FuIGRlZHVwIGEgcmV0cmllZCBkZWxpdmVyeSBpbnN0ZWFkIG9mIHdyaXRpbmcgYVxuICogZHVwbGljYXRlIHJvdy4gQnVkZ2V0IGlzIGtlcHQgc21hbGwgc28gYSBoYXJkLWRvd24gcGxhdGZvcm0gY2FuJ3QgYmFjayB0aGVcbiAqIHdvcmtlciB1cCBmb3IgbG9uZzogYmFzZSBkZWxheSDDlygyIHJldHJpZXMpICsgYSBjb3VwbGUgb2YgNDI5IGJhY2tvZmZzLlxuICovXG5jb25zdCBBVURJVF9SRVFVRVNUX09QVElPTlM6IFBpY2s8UmVxdWVzdE9wdGlvbnMsICdtYXhSYXRlTGltaXRSZXRyaWVzJyB8ICdtYXhSZXRyaWVzJz4gPSB7XG4gIG1heFJhdGVMaW1pdFJldHJpZXM6IDIsXG4gIG1heFJldHJpZXM6IDIsXG59O1xuXG5leHBvcnQgaW50ZXJmYWNlIFJlbW90ZUF1ZGl0RXZlbnQge1xuICBhY3Rpb246IFJlbW90ZUF1ZGl0QWN0aW9uO1xuICBhY3RvcklkOiBzdHJpbmc7XG4gIGFjdG9yRW1haWw/OiBzdHJpbmc7XG4gIG9yZ0lkPzogc3RyaW5nO1xuICBhZmZlY3RlZE9yZ0lkPzogc3RyaW5nO1xuICB0YXJnZXRUeXBlPzogc3RyaW5nO1xuICB0YXJnZXRJZD86IHN0cmluZztcbiAgLyoqXG4gICAqIERpZCB0aGUgYXVkaXRlZCBhY3Rpb24gc3VjY2VlZCBvciBmYWlsPyBEZWZhdWx0cyB0byAnc3VjY2Vzcycgd2hlbiBvbWl0dGVkXG4gICAqICh0aGUgcGxhdGZvcm0gaW5nZXN0IGFwcGxpZXMgdGhlIHNhbWUgZGVmYXVsdCkuIERlbmllZC1hdXRoeiBldmVudHMgc2V0XG4gICAqICdmYWlsdXJlJyBzbyBhIHJldmlld2VyIGNhbiBmaWx0ZXIgYXR0ZW1wdHMgZnJvbSBjb21wbGV0ZWQgYWN0aW9ucy5cbiAgICovXG4gIG91dGNvbWU/OiAnc3VjY2VzcycgfCAnZmFpbHVyZSc7XG4gIC8qKlxuICAgKiBXaGVuIHRoZSBhdWRpdGVkIGFjdGlvbiBhY3R1YWxseSBPQ0NVUlJFRCAoSVNPLTg2MDEpLCBzdGFtcGVkIGF0IGVtaXNzaW9uLlxuICAgKiBUaGUgcGxhdGZvcm0gc3RvcmVzIHRoaXMgZm9yIHJldmlld2VyczsgaXQgaXMgTk9UIHRoZSBjaGFpbi1vcmRlcmluZyBmaWVsZFxuICAgKiAodGhlIHRhbXBlci1ldmlkZW50IGNoYWluIG9yZGVycyBieSBpbmdlc3QvYGNyZWF0ZWRBdGApLiBJdCBtYXR0ZXJzIGZvclxuICAgKiBTUE9PTEVEIGV2ZW50czogb25lIGJ1ZmZlcmVkIGR1cmluZyBhIHBsYXRmb3JtIG91dGFnZSBpcyByZS1kZWxpdmVyZWQg4oCUIGFuZFxuICAgKiBzbyBjaGFpbmVkIOKAlCBsYXRlciwgYnV0IGBvY2N1cnJlZEF0YCBwcmVzZXJ2ZXMgd2hlbiBpdCByZWFsbHkgaGFwcGVuZWQuXG4gICAqL1xuICBvY2N1cnJlZEF0Pzogc3RyaW5nO1xuICAvKipcbiAgICogU3RhYmxlIHBlci1lbWlzc2lvbiBkZWR1cCBrZXkgKGFsc28gc2VudCBhcyB0aGUgYElkZW1wb3RlbmN5LUtleWAgaGVhZGVyIHRoZVxuICAgKiBwbGF0Zm9ybSBpbmdlc3QgZGVkdXBzIG9uKS4gU3RhbXBlZCBieSBgcmVjb3JkKClgIGFuZCBjYXJyaWVkIG9uIHRoZSBzcG9vbGVkXG4gICAqIGNvcHkgc28gYSBsaXZlIGF0dGVtcHQgYW5kIGl0cyBsYXRlciByZS1kZWxpdmVyeSBjb2xsYXBzZSB0byBPTkUgc3RvcmVkIHJvdy5cbiAgICovXG4gIGlkZW1wb3RlbmN5S2V5Pzogc3RyaW5nO1xuICBkZXRhaWxzPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG59XG5cbi8qKlxuICogQ2xpZW50IGZvciBQT1NUaW5nIGF1ZGl0IGV2ZW50cyB0byB0aGUgcGxhdGZvcm0ncyBgL2F1ZGl0LWV2ZW50c2AgaW5nZXN0XG4gKiBlbmRwb2ludC4gTWludHMgYSBmcmVzaCBzZXJ2aWNlIHRva2VuIHBlciBjYWxsICg1IG1pbiBUVEwpICB0aGVyZSdzIG5vXG4gKiBtZWFuaW5nZnVsIGNhY2hpbmcgYmVuZWZpdCB3aGVuIGVtaXNzaW9ucyBhcmUgc3BhcnNlLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFJlbW90ZUF1ZGl0Q2xpZW50IHtcbiAgLyoqXG4gICAqIEZpcmUtYW5kLWZvcmdldCBhdWRpdCBlbWlzc2lvbi4gRmFpbHVyZXMgYXJlIGxvZ2dlZCBhdCB3YXJuIGxldmVsIGJ1dFxuICAgKiBuZXZlciB0aHJvd24gIHRoZSBvcmlnaW5hdGluZyBhY3Rpb24gKGUuZy4gYSBwbHVnaW4gYnVpbGQpIGhhcyBpdHNcbiAgICogb3duIHN1Y2Nlc3MvZmFpbHVyZSBwYXRoIHRoYXQgc2hvdWxkbid0IGdldCBwb2xsdXRlZCBieSBhIGZsYWt5IGF1ZGl0XG4gICAqIGRvd25zdHJlYW0uIFdoZW4gYSB7QGxpbmsgQXVkaXRTcG9vbH0gaXMgY29uZmlndXJlZCwgYW4gZW1pc3Npb24gdGhhdFxuICAgKiBleGhhdXN0cyBpdHMgbGl2ZSByZXRyaWVzIGlzIGJ1ZmZlcmVkIGFuZCByZS1kZWxpdmVyZWQgbGF0ZXIgaW5zdGVhZCBvZlxuICAgKiBiZWluZyBkcm9wcGVkLlxuICAgKi9cbiAgcmVjb3JkKGV2ZW50OiBSZW1vdGVBdWRpdEV2ZW50LCBzZXJ2aWNlTmFtZTogc3RyaW5nKTogdm9pZDtcbiAgLyoqIFN0b3AgdGhlIGJhY2tncm91bmQgc3Bvb2wtZHJhaW4gdGltZXIgKGlmIGFueSkuIFNhZmUgdG8gY2FsbCByZXBlYXRlZGx5LiAqL1xuICBjbG9zZSgpOiB2b2lkO1xufVxuXG4vKipcbiAqIENvbmZpZ3VyYXRpb24gZm9yIHRoZSByZW1vdGUgYXVkaXQgY2xpZW50LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFJlbW90ZUF1ZGl0Q2xpZW50Q29uZmlnIHtcbiAgLyoqIFBsYXRmb3JtIHNlcnZpY2UgaG9zdCAoZGVmYXVsdDogZW52IFBMQVRGT1JNX1NFUlZJQ0VfSE9TVCBvciAncGxhdGZvcm0nKSAqL1xuICBob3N0Pzogc3RyaW5nO1xuICAvKiogUGxhdGZvcm0gc2VydmljZSBwb3J0IChkZWZhdWx0OiBlbnYgUExBVEZPUk1fU0VSVklDRV9QT1JUIG9yIDMwMDApICovXG4gIHBvcnQ/OiBudW1iZXI7XG4gIC8qKiBSZXF1ZXN0IHRpbWVvdXQgbXMgKGRlZmF1bHQgMzAwMCAgYXVkaXQgc2hvdWxkbid0IGJsb2NrIHRoZSB3b3JrZXIpLiAqL1xuICB0aW1lb3V0PzogbnVtYmVyO1xuICAvKipcbiAgICogT3B0aW9uYWwgZHVyYWJsZSBidWZmZXIuIFdoZW4gc2V0LCBhbiBlbWlzc2lvbiB0aGF0IGV4aGF1c3RzIGl0cyBsaXZlIHJldHJ5XG4gICAqIGJ1ZGdldCAoc3VzdGFpbmVkIHBsYXRmb3JtIG91dGFnZSkgaXMgc3Bvb2xlZCBhbmQgcmUtZGVsaXZlcmVkIOKAlCBvbiB0aGUgbmV4dFxuICAgKiBzdWNjZXNzZnVsIGVtaXNzaW9uIGFuZCBvbiBhIHBlcmlvZGljIHRpbWVyIOKAlCBpbnN0ZWFkIG9mIGJlaW5nIGxvc3QuXG4gICAqL1xuICBzcG9vbD86IEF1ZGl0U3Bvb2w7XG4gIC8qKiBTcG9vbC1kcmFpbiBpbnRlcnZhbCBtcyAoZGVmYXVsdCAzMF8wMDApLiBPbmx5IHVzZWQgd2hlbiBgc3Bvb2xgIGlzIHNldC4gKi9cbiAgZHJhaW5JbnRlcnZhbE1zPzogbnVtYmVyO1xuICAvKiogTWF4IGVudHJpZXMgZHJhaW5lZCBwZXIgc3dlZXAgKGRlZmF1bHQgMTAwKS4gKi9cbiAgZHJhaW5CYXRjaFNpemU/OiBudW1iZXI7XG59XG5cbi8qKlxuICogQ29uc3RydWN0IGEgcmVtb3RlLWF1ZGl0IGNsaWVudCB0YXJnZXRlZCBhdCB0aGUgcGxhdGZvcm0gc2VydmljZS5cbiAqXG4gKiBVc2VkIGJ5IGFwaS9wbHVnaW4ncyBidWlsZCB3b3JrZXIgdG8gcHVzaCBgcGx1Z2luLmJ1aWxkLipgIGV2ZW50cyBpbnRvXG4gKiB0aGUgcGxhdGZvcm0ncyBNb25nb0RCIGBhdWRpdF9ldmVudHNgIGNvbGxlY3Rpb24uIE90aGVyIHNlcnZpY2VzXG4gKiB3aXRoIHdvcmtlci1zdHlsZSBlbWl0dGVycyBjYW4gdXNlIHRoZSBzYW1lIGNsaWVudC5cbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgYXVkaXRDbGllbnQgPSBjcmVhdGVSZW1vdGVBdWRpdENsaWVudCgpO1xuICogYXVkaXRDbGllbnQucmVjb3JkKHtcbiAqIGFjdGlvbjogJ3BsdWdpbi5idWlsZC5jb21wbGV0ZWQnLFxuICogYWN0b3JJZDogJ3VzZXItMTIzJyxcbiAqIG9yZ0lkOiAnb3JnLWFjbWUnLFxuICogdGFyZ2V0VHlwZTogJ3BsdWdpbicsXG4gKiB0YXJnZXRJZDogJ3BsdWdpbi1hYmMnLFxuICogZGV0YWlsczogeyBuYW1lOiAnbXktcGx1Z2luJywgdmVyc2lvbjogJzEuMC4wJyB9LFxuICogfSwgJ3BsdWdpbicpO1xuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVSZW1vdGVBdWRpdENsaWVudChjb25maWc6IFJlbW90ZUF1ZGl0Q2xpZW50Q29uZmlnID0ge30pOiBSZW1vdGVBdWRpdENsaWVudCB7XG4gIGNvbnN0IHNlcnZpY2VDb25maWc6IFNlcnZpY2VDb25maWcgPSB7XG4gICAgaG9zdDogY29uZmlnLmhvc3QgPz8gc2VydmljZUVuZHBvaW50KCdwbGF0Zm9ybScpLmhvc3QsXG4gICAgcG9ydDogY29uZmlnLnBvcnQgPz8gc2VydmljZUVuZHBvaW50KCdwbGF0Zm9ybScpLnBvcnQsXG4gICAgdGltZW91dDogY29uZmlnLnRpbWVvdXQgPz8gMzAwMCxcbiAgfTtcbiAgLy8gSXRzIG93biBicmVha2VyIHJvdXRlIGNsYXNzOiBhdWRpdCBpbmdlc3QgZmFpbGluZyAoNXh4IHdoaWxlIHBsYXRmb3JtJ3NcbiAgLy8gYXVkaXQgc3RvcmUgaXMgZGVncmFkZWQpIG11c3Qgbm90IG9wZW4gdGhlIGJyZWFrZXIgdGhhdCBwbGF0Zm9ybSdzIEpXS1MgYW5kXG4gIC8vIGtleS1leGNoYW5nZSBjYWxscyByaWRlIG9uIOKAlCB0aGF0IHdvdWxkIHR1cm4gYW4gYXVkaXQgYnJvd25vdXQgaW50byBhbiBhdXRoXG4gIC8vIG91dGFnZSBpbiBldmVyeSBzZXJ2aWNlLlxuICBjb25zdCBjbGllbnQgPSBjcmVhdGVTYWZlQ2xpZW50KHNlcnZpY2VDb25maWcsIHsgYnJlYWtlckNsYXNzOiAnYXVkaXQnIH0pO1xuICBjb25zdCBzcG9vbCA9IGNvbmZpZy5zcG9vbDtcbiAgY29uc3QgZHJhaW5CYXRjaFNpemUgPSBjb25maWcuZHJhaW5CYXRjaFNpemUgPz8gMTAwO1xuXG4gIC8qKlxuICAgKiBBdHRlbXB0IE9ORSBsaXZlIGRlbGl2ZXJ5LiBSZXNvbHZlcyBgdHJ1ZWAgb24gYSAyeHggYWNjZXB0LCBgZmFsc2VgIG9uIGFueVxuICAgKiBub24tMnh4IC8gdGhyb3duIGVycm9yICh0aGUgaHR0cC1jbGllbnQgaGFzIGFscmVhZHkgYXBwbGllZCB0aGUgcmV0cnlcbiAgICogYnVkZ2V0KS4gQSBzdGFibGUgcGVyLWVtaXNzaW9uIGBJZGVtcG90ZW5jeS1LZXlgIG1ha2VzIHRoaXMgbm9uLWlkZW1wb3RlbnRcbiAgICogUE9TVCByZXRyeS1zYWZlIGFuZCBsZXRzIHRoZSBwbGF0Zm9ybSBpbmdlc3QgZGVkdXAgYSByZS1kZWxpdmVyZWQgZXZlbnRcbiAgICogaW5zdGVhZCBvZiB3cml0aW5nIGEgZHVwbGljYXRlIGF1ZGl0IHJvdyAoYW5kIGR1cGxpY2F0ZSBjaGFpbiBsaW5rKS5cbiAgICogYElkZW1wb3RlbmN5LUtleWAgaXMgZGVyaXZlZCBmcm9tIHRoZSBldmVudCBzbyBhIFNQT09MRUQgcmUtZGVsaXZlcnkgcmV1c2VzXG4gICAqIHRoZSBzYW1lIGtleSBhcyBpdHMgb3JpZ2luYWwgbGl2ZSBhdHRlbXB0IOKAlCB0aGUgdHdvIGNvbGxhcHNlIHRvIG9uZSByb3cuXG4gICAqL1xuICBhc3luYyBmdW5jdGlvbiBkZWxpdmVyKGV2ZW50OiBSZW1vdGVBdWRpdEV2ZW50LCBzZXJ2aWNlTmFtZTogc3RyaW5nKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgdHJ5IHtcbiAgICAgIC8vIE1pbnRpbmcgdGhlIHRva2VuIGlzIElOU0lERSB0aGUgdHJ5IG9uIHB1cnBvc2UuIEl0IGNhbiB0aHJvdyDigJQgdGhlXG4gICAgICAvLyBzaWduaW5nIGtleSB1bnJlYWRhYmxlLCBub3QgYW4gRUMgUC0yNTYga2V5LCBvciBgU0VSVklDRV9OQU1FYCBub3RcbiAgICAgIC8vIG1hdGNoaW5nIHRoaXMgY2xpZW50J3MgbmFtZS4gT3V0c2lkZSB0aGUgYHRyeWAsIGBkZWxpdmVyYCB3b3VsZCByZWplY3RcbiAgICAgIC8vIGluc3RlYWQgb2YgcmVzb2x2aW5nIGBmYWxzZWA7IGByZWNvcmRgIGZpcmVzIGl0IHdpdGggYSBiYXJlIGAudGhlbmAsIHNvXG4gICAgICAvLyB0aGUgcmVqZWN0aW9uIHdvdWxkIGdvIHVuaGFuZGxlZCBhbmQgY3Jhc2gtbG9vcCB0aGUgcG9kIG9uIGl0cyBmaXJzdFxuICAgICAgLy8gYXVkaXRlZCB3cml0ZS4gSW5zaWRlLCBhIGtleSBwcm9ibGVtIGlzIGp1c3QgYW4gdW5kZWxpdmVyYWJsZSBldmVudDpcbiAgICAgIC8vIHNwb29sZWQsIG9yIGRyb3BwZWQgYW5kIG1ldGVyZWQuXG4gICAgICBjb25zdCBhdXRoSGVhZGVyID0gZ2V0U2VydmljZUF1dGhIZWFkZXIoeyBzZXJ2aWNlTmFtZSwgb3JnSWQ6IGV2ZW50Lm9yZ0lkLCByb2xlOiAnbWVtYmVyJyB9KTtcbiAgICAgIGNvbnN0IGhlYWRlcnM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7XG4gICAgICAgICdBdXRob3JpemF0aW9uJzogYXV0aEhlYWRlcixcbiAgICAgICAgJ0lkZW1wb3RlbmN5LUtleSc6IGV2ZW50LmlkZW1wb3RlbmN5S2V5ID8/IHJhbmRvbVVVSUQoKSxcbiAgICAgIH07XG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGNsaWVudC5wb3N0KCcvYXVkaXQvZXZlbnRzJywgZXZlbnQsIHsgaGVhZGVycywgLi4uQVVESVRfUkVRVUVTVF9PUFRJT05TIH0pO1xuICAgICAgY29uc3Qgb2sgPSAhIXJlc3BvbnNlICYmIHJlc3BvbnNlLnN0YXR1c0NvZGUgPj0gMjAwICYmIHJlc3BvbnNlLnN0YXR1c0NvZGUgPCAzMDA7XG4gICAgICBpZiAoIW9rKSB7XG4gICAgICAgIGxvZ2dlci53YXJuKCdSZW1vdGUgYXVkaXQgaW5nZXN0IG5vbi1vaycsIHsgYWN0aW9uOiBldmVudC5hY3Rpb24sIHN0YXR1c0NvZGU6IHJlc3BvbnNlPy5zdGF0dXNDb2RlIH0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG9rO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgbG9nZ2VyLndhcm4oJ1JlbW90ZSBhdWRpdCBpbmdlc3QgdGhyZXcnLCB7IGFjdGlvbjogZXZlbnQuYWN0aW9uLCBlcnJvcjogZXJyb3JNZXNzYWdlKGVycikgfSk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgLy8gU2VyaWFsaXplIHNwb29sIGRyYWlucyBzbyBhIHBlcmlvZGljIHRpY2sgYW5kIGFuIG9uLXN1Y2Nlc3MgZHJhaW4gY2FuJ3QgYm90aFxuICAvLyBwdWxsIHRoZSBzYW1lIGJhdGNoLiBTdG9wcyBlYXJseSB0aGUgbW9tZW50IGEgcmUtZGVsaXZlcnkgZmFpbHMgKHBsYXRmb3JtXG4gIC8vIHN0aWxsIGRvd24pIHNvIHdlIGRvbid0IGhhbW1lciBpdCBvciBjaHVybiB0aGUgYnVmZmVyLlxuICBsZXQgZHJhaW5pbmcgPSBmYWxzZTtcbiAgYXN5bmMgZnVuY3Rpb24gZHJhaW4oKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKCFzcG9vbCB8fCBkcmFpbmluZykgcmV0dXJuO1xuICAgIGRyYWluaW5nID0gdHJ1ZTtcbiAgICB0cnkge1xuICAgICAgZm9yICg7Oykge1xuICAgICAgICBjb25zdCBiYXRjaCA9IGF3YWl0IHNwb29sLnRha2UoZHJhaW5CYXRjaFNpemUpO1xuICAgICAgICBpZiAoYmF0Y2gubGVuZ3RoID09PSAwKSByZXR1cm47XG4gICAgICAgIGNvbnN0IGRlbGl2ZXJlZDogQXVkaXRTcG9vbEVudHJ5W10gPSBbXTtcbiAgICAgICAgY29uc3QgZmFpbGVkOiBBdWRpdFNwb29sRW50cnlbXSA9IFtdO1xuICAgICAgICBsZXQgcGxhdGZvcm1Eb3duID0gZmFsc2U7XG4gICAgICAgIGZvciAoY29uc3QgZW50cnkgb2YgYmF0Y2gpIHtcbiAgICAgICAgICBpZiAocGxhdGZvcm1Eb3duKSB7IGZhaWxlZC5wdXNoKGVudHJ5KTsgY29udGludWU7IH1cbiAgICAgICAgICBjb25zdCBvayA9IGF3YWl0IGRlbGl2ZXIoZW50cnkuZXZlbnQsIGVudHJ5LnNlcnZpY2VOYW1lKTtcbiAgICAgICAgICBpZiAob2spIHtcbiAgICAgICAgICAgIGRlbGl2ZXJlZC5wdXNoKGVudHJ5KTtcbiAgICAgICAgICAgIGVtaXRDb3VudGVyKCdhdWRpdF9zcG9vbF9yZWRlbGl2ZXJlZF90b3RhbCcsIHsgc2VydmljZTogZW50cnkuc2VydmljZU5hbWUgfSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHBsYXRmb3JtRG93biA9IHRydWU7XG4gICAgICAgICAgICBmYWlsZWQucHVzaChlbnRyeSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIEFja25vd2xlZGdlIHRoZSBkZWxpdmVyZWQgcHJlZml4IHNvIGl0IGNsZWFycyB0aGUgaW4tcHJvZ3Jlc3MgbGlzdDsgdGhlXG4gICAgICAgIC8vIHJlbGlhYmxlIHRha2UoKSBtb3ZlZCB0aGUgd2hvbGUgYmF0Y2ggdGhlcmUsIHNvIHVuYWNrZWQgc3Vydml2b3JzIGFyZVxuICAgICAgICAvLyByZWNsYWltZWQgYnkgcmVjb3ZlcigpIGFmdGVyIGEgY3Jhc2ggcmF0aGVyIHRoYW4gYmVpbmcgc2lsZW50bHkgbG9zdC5cbiAgICAgICAgaWYgKGRlbGl2ZXJlZC5sZW5ndGggPiAwKSBhd2FpdCBzcG9vbC5hY2soZGVsaXZlcmVkKTtcbiAgICAgICAgaWYgKGZhaWxlZC5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgYXdhaXQgc3Bvb2wucmVxdWV1ZShmYWlsZWQpO1xuICAgICAgICAgIHJldHVybjsgLy8gc3RpbGwgZG93biDigJQgdHJ5IGFnYWluIG9uIHRoZSBuZXh0IHRpY2tcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgbG9nZ2VyLndhcm4oJ0F1ZGl0IHNwb29sIGRyYWluIGZhaWxlZCcsIHsgZXJyb3I6IGVycm9yTWVzc2FnZShlcnIpIH0pO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBkcmFpbmluZyA9IGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIGxldCBkcmFpblRpbWVyOiBSZXR1cm5UeXBlPHR5cGVvZiBzZXRJbnRlcnZhbD4gfCB1bmRlZmluZWQ7XG4gIGlmIChzcG9vbCkge1xuICAgIC8vIFJlY2xhaW0gYW55IGJhdGNoIHN0cmFuZGVkIG9uIHRoZSBpbi1wcm9ncmVzcyBsaXN0IGJ5IGEgcHJpb3IgY3Jhc2gsIHRoZW5cbiAgICAvLyBhdHRlbXB0IHRvIGZsdXNoIGl0LiBCb3RoIGFyZSBiZXN0LWVmZm9ydCAodGhlIHNwb29sIHN3YWxsb3dzIGl0cyBlcnJvcnMpLlxuICAgIHZvaWQgc3Bvb2wucmVjb3ZlcigpLnRoZW4oKCkgPT4gZHJhaW4oKSk7XG4gICAgLy8gRXZlcnkgdGljazogaGVhcnRiZWF0IChzbyBwZWVycyBuZXZlciByZWNsYWltIGEgYmF0Y2ggdGhpcyBwb2QgaXMgc3RpbGxcbiAgICAvLyBkZWxpdmVyaW5nIOKAlCBldmVuIG1pZC1kcmFpbiksIHJlY2xhaW0gYmF0Y2hlcyBvZiBwb2RzIHRoYXQgZGllZCwgZHJhaW4uXG4gICAgZHJhaW5UaW1lciA9IHNldEludGVydmFsKCgpID0+IHtcbiAgICAgIHZvaWQgc3Bvb2wuaGVhcnRiZWF0KCkudGhlbigoKSA9PiBzcG9vbC5yZWNvdmVyKCkpLnRoZW4oKCkgPT4gZHJhaW4oKSk7XG4gICAgfSwgY29uZmlnLmRyYWluSW50ZXJ2YWxNcyA/PyAzMF8wMDApO1xuICAgIC8vIERvbid0IGxldCB0aGUgZHJhaW4gdGltZXIga2VlcCB0aGUgcHJvY2VzcyBhbGl2ZSBvbiBzaHV0ZG93bi5cbiAgICAoZHJhaW5UaW1lciBhcyB1bmtub3duIGFzIHsgdW5yZWY/OiAoKSA9PiB2b2lkIH0pLnVucmVmPy4oKTtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgcmVjb3JkKGV2ZW50LCBzZXJ2aWNlTmFtZSkge1xuICAgICAgLy8gU3RhbXAgd2hlbiB0aGUgYWN0aW9uIGFjdHVhbGx5IG9jY3VycmVkIChzdXJ2aXZlcyBzcG9vbCBkZWxheSkgYW5kIHBpbiBhXG4gICAgICAvLyBzdGFibGUgaWRlbXBvdGVuY3kga2V5IHNvIGEgbGl2ZSBhdHRlbXB0IGFuZCBpdHMgc3Bvb2xlZCByZXRyeSBkZWR1cC5cbiAgICAgIGNvbnN0IHN0YW1wZWQ6IFJlbW90ZUF1ZGl0RXZlbnQgPSB7XG4gICAgICAgIC4uLmV2ZW50LFxuICAgICAgICBvY2N1cnJlZEF0OiBldmVudC5vY2N1cnJlZEF0ID8/IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKSxcbiAgICAgICAgaWRlbXBvdGVuY3lLZXk6IGV2ZW50LmlkZW1wb3RlbmN5S2V5ID8/IHJhbmRvbVVVSUQoKSxcbiAgICAgIH07XG4gICAgICB2b2lkIGRlbGl2ZXIoc3RhbXBlZCwgc2VydmljZU5hbWUpLnRoZW4oKG9rKSA9PiB7XG4gICAgICAgIGlmIChvaykge1xuICAgICAgICAgIGVtaXRDb3VudGVyKCdhdWRpdF9lbWl0dGVkX3RvdGFsJywgeyBzZXJ2aWNlOiBzZXJ2aWNlTmFtZSwgb3V0Y29tZTogc3RhbXBlZC5vdXRjb21lID8/ICdzdWNjZXNzJyB9KTtcbiAgICAgICAgICBpZiAoc3Bvb2wpIHZvaWQgZHJhaW4oKTsgLy8gcGxhdGZvcm0gaXMgcmVhY2hhYmxlIOKAlCBmbHVzaCBhbnkgYmFja2xvZ1xuICAgICAgICB9IGVsc2UgaWYgKHNwb29sKSB7XG4gICAgICAgICAgdm9pZCBzcG9vbC5lbnF1ZXVlKHsgZXZlbnQ6IHN0YW1wZWQsIHNlcnZpY2VOYW1lIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGVtaXRDb3VudGVyKCdhdWRpdF9kcm9wcGVkX3RvdGFsJywgeyBzZXJ2aWNlOiBzZXJ2aWNlTmFtZSB9KTtcbiAgICAgICAgfVxuICAgICAgfSkuY2F0Y2goKGVycikgPT4ge1xuICAgICAgICAvLyBCZWx0IGFuZCBicmFjZXMuIGBkZWxpdmVyYCBuZXZlciByZWplY3RzLCBidXQgYW55dGhpbmcgdGhhdCB0aHJvd3NcbiAgICAgICAgLy8gaW4gdGhlIGNvbnRpbnVhdGlvbiB3b3VsZCBvdGhlcndpc2UgYmVjb21lIGFuIHVuaGFuZGxlZCByZWplY3Rpb24g4oCUXG4gICAgICAgIC8vIGFuZCBpbiB0aGlzIHByb2Nlc3MgdGhhdCBpcyBhIGNyYXNoLCBub3QgYSBsb2cgbGluZS4gQW4gYXVkaXQgZXZlbnRcbiAgICAgICAgLy8gbXVzdCBuZXZlciB0YWtlIHRoZSBzZXJ2aWNlIGRvd24uXG4gICAgICAgIGVtaXRDb3VudGVyKCdhdWRpdF9kcm9wcGVkX3RvdGFsJywgeyBzZXJ2aWNlOiBzZXJ2aWNlTmFtZSB9KTtcbiAgICAgICAgbG9nZ2VyLmVycm9yKCdSZW1vdGUgYXVkaXQgcmVjb3JkIGZhaWxlZCB1bmV4cGVjdGVkbHknLCB7IGFjdGlvbjogc3RhbXBlZC5hY3Rpb24sIGVycm9yOiBlcnJvck1lc3NhZ2UoZXJyKSB9KTtcbiAgICAgIH0pO1xuICAgIH0sXG4gICAgY2xvc2UoKSB7XG4gICAgICBpZiAoZHJhaW5UaW1lcikgeyBjbGVhckludGVydmFsKGRyYWluVGltZXIpOyBkcmFpblRpbWVyID0gdW5kZWZpbmVkOyB9XG4gICAgfSxcbiAgfTtcbn1cblxuLyoqXG4gKiBSZWdpc3RlciB0aGUgc3RhbmRhcmQgYGF1dGh6LmRlbmllZGAgc2luayB1c2VkIGJ5IGV2ZXJ5IHJlbW90ZS1hdWRpdCBzZXJ2aWNlXG4gKiAocGlwZWxpbmUsIHBsdWdpbiwgY29tcGxpYW5jZSwgcXVvdGEsIG1lc3NhZ2UsIGJpbGxpbmcsIHJlcG9ydGluZywg4oCmKS5cbiAqXG4gKiBUaGUgc2hhcmVkIGByZXF1aXJlQXV0aGAgZ2F0ZSBmb3J3YXJkcyBlYWNoIERFTklFRCBzdGF0ZS1jaGFuZ2luZyByZXF1ZXN0IHRvXG4gKiB0aGUgYXVkaXRvciBzZXQgdmlhIHtAbGluayBzZXRBdXRoekRlbmlhbEF1ZGl0b3J9OyB0aGlzIHdpcmVzIHRoYXQgaG9vayB0byB0aGVcbiAqIHNlcnZpY2UncyB7QGxpbmsgUmVtb3RlQXVkaXRDbGllbnR9LCBmb3J3YXJkaW5nIGEgYGZhaWx1cmVgLW91dGNvbWVcbiAqIGBhdXRoei5kZW5pZWRgIGV2ZW50IHNvIHByb2JpbmcgLyBwcml2aWxlZ2UtZXNjYWxhdGlvbiBhdHRlbXB0cyBsZWF2ZSBhIHRyYWlsLlxuICogRW1pc3Npb24gaXMgZmlyZS1hbmQtZm9yZ2V0ICh0aGUgY2xpZW50IG5ldmVyIHRocm93cykuIGBnZXRDbGllbnRgIGlzIGEgZ2V0dGVyXG4gKiBzbyB0aGUgY2xpZW50IHN0YXlzIGxhemlseSBjb25zdHJ1Y3RlZCAoc2VydmljZXMgbWVtb2l6ZSBpdCBvbiBmaXJzdCB1c2UpLlxuICpcbiAqIFBsYXRmb3JtIGlzIGludGVudGlvbmFsbHkgTk9UIGEgY2FsbGVyIOKAlCBpdCBpcyB0aGUgYXVkaXQgYXV0aG9yaXR5IGFuZCB3cml0ZXNcbiAqIGBhdXRoei5kZW5pZWRgIHN0cmFpZ2h0IHRvIGl0cyBsb2NhbCBzdG9yZSAod2l0aCBgYWZmZWN0ZWRPcmdJZGApLCBub3QgdGhyb3VnaFxuICogYSBSZW1vdGVBdWRpdENsaWVudC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHdpcmVBdXRoekRlbmlhbEF1ZGl0b3Ioc2VydmljZU5hbWU6IHN0cmluZywgZ2V0Q2xpZW50OiAoKSA9PiBSZW1vdGVBdWRpdENsaWVudCk6IHZvaWQge1xuICBzZXRBdXRoekRlbmlhbEF1ZGl0b3IoKGluZm86IEF1dGh6RGVuaWFsSW5mbykgPT4gZ2V0Q2xpZW50KCkucmVjb3JkKHtcbiAgICBhY3Rpb246ICdhdXRoei5kZW5pZWQnLFxuICAgIGFjdG9ySWQ6IGluZm8uYWN0b3JJZCA/PyAnYW5vbnltb3VzJyxcbiAgICBhY3RvckVtYWlsOiBpbmZvLmFjdG9yRW1haWwsXG4gICAgb3JnSWQ6IGluZm8ub3JnSWQsXG4gICAgb3V0Y29tZTogJ2ZhaWx1cmUnLFxuICAgIGRldGFpbHM6IHsgbWV0aG9kOiBpbmZvLm1ldGhvZCwgcGF0aDogaW5mby5wYXRoLCByZXF1aXJlZDogaW5mby5yZXF1aXJlZCB9LFxuICB9LCBzZXJ2aWNlTmFtZSkpO1xufVxuXG4vKipcbiAqIFRoZSBwcm9jZXNzLXdpZGUgcmVtb3RlLWF1ZGl0IGJpbmRpbmc6IHdoaWNoIHNlcnZpY2UgdGhpcyBwcm9jZXNzIGlzLCBhbmQgdGhlXG4gKiAobGF6aWx5IGJ1aWx0KSBjbGllbnQgaXRzIGV2ZW50cyBnbyB0aHJvdWdoLiBCb3VuZCBPTkNFIGF0IGJvb3QgYnlcbiAqIGB3aXJlU2VydmljZVNlY3VyaXR5KHNlcnZpY2VOYW1lKWAg4oCUIGV2ZXJ5IHN0YXRlbGVzcyBzZXJ2aWNlIGNhbGxzIGl0IOKAlCBzbyB0aGVcbiAqIHNlcnZpY2UgaWRlbnRpdHkgaXMgbmV2ZXIgcmVwZWF0ZWQgYXQgYSBjYWxsIHNpdGUgYW5kIGNhbiBuZXZlciBkcmlmdC5cbiAqL1xuaW50ZXJmYWNlIEF1ZGl0QmluZGluZyB7XG4gIHNlcnZpY2VOYW1lOiBzdHJpbmc7XG4gIGNsaWVudDogUmVtb3RlQXVkaXRDbGllbnQgfCBudWxsO1xufVxuXG5sZXQgYXVkaXRCaW5kaW5nOiBBdWRpdEJpbmRpbmcgfCBudWxsID0gbnVsbDtcblxuLyoqXG4gKiBCaW5kIHRoaXMgcHJvY2VzcydzIHNlcnZpY2UgaWRlbnRpdHkgZm9yIHtAbGluayByZWNvcmRBdWRpdH0uIENhbGxlZCBieVxuICogYHdpcmVTZXJ2aWNlU2VjdXJpdHlgOyB0ZXN0cyBnbyB0aHJvdWdoIGBiaW5kVGVzdEF1ZGl0U2VydmljZWBcbiAqIChgQHBpcGVsaW5lLWJ1aWxkZXIvYXBpLWNvcmUvdGVzdGluZ2ApLCB3aGljaCBwYXNzZXMgYSBzcHkgYGNsaWVudGAuXG4gKlxuICogV2l0aG91dCBgY2xpZW50YCwgdGhlIHJlYWwgb25lIGlzIGJ1aWx0IGxhemlseSBvbiBmaXJzdCBlbWlzc2lvbjogYVxuICogUmVtb3RlQXVkaXRDbGllbnQgd2lyZWQgdG8gdGhlIGR1cmFibGUgZW52LVJlZGlzIHNwb29sIChudWxsIOKGkiBubyBzcG9vbCkuXG4gKiBMYXp5IG9uIHB1cnBvc2Ug4oCUIGJ1aWxkaW5nIGl0IGF0IGJvb3Qgd291bGQgZm9yY2UgdGhlIHNwb29sJ3MgUmVkaXMgY29ubmVjdGlvblxuICogd2hlcmV2ZXIgdGhlIHNlcnZpY2UgbW9kdWxlIGlzIG1lcmVseSBpbXBvcnRlZC4gUmViaW5kaW5nIGNsb3NlcyB0aGUgcHJldmlvdXNcbiAqIGNsaWVudCdzIHNwb29sLWRyYWluIHRpbWVyLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYmluZEF1ZGl0U2VydmljZShzZXJ2aWNlTmFtZTogc3RyaW5nLCBjbGllbnQ/OiBSZW1vdGVBdWRpdENsaWVudCk6IHZvaWQge1xuICBhdWRpdEJpbmRpbmc/LmNsaWVudD8uY2xvc2UoKTtcbiAgYXVkaXRCaW5kaW5nID0geyBzZXJ2aWNlTmFtZSwgY2xpZW50OiBjbGllbnQgPz8gbnVsbCB9O1xufVxuXG4vKiogRHJvcCB0aGUgYmluZGluZyAodGVzdHMgb25seSDigJQgcmV0dXJucyB0aGUgcHJvY2VzcyB0byB0aGUgdW5ib3VuZCBzdGF0ZSkuICovXG5leHBvcnQgZnVuY3Rpb24gdW5iaW5kQXVkaXRTZXJ2aWNlKCk6IHZvaWQge1xuICBhdWRpdEJpbmRpbmc/LmNsaWVudD8uY2xvc2UoKTtcbiAgYXVkaXRCaW5kaW5nID0gbnVsbDtcbn1cblxuZnVuY3Rpb24gYm91bmRBdWRpdCgpOiBBdWRpdEJpbmRpbmcgJiB7IGNsaWVudDogUmVtb3RlQXVkaXRDbGllbnQgfSB7XG4gIGlmICghYXVkaXRCaW5kaW5nKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdhdWRpdCBub3QgaW5pdGlhbGlzZWQ6IGNhbGwgd2lyZVNlcnZpY2VTZWN1cml0eShzZXJ2aWNlTmFtZSkgYXQgYm9vdCBiZWZvcmUgcmVjb3JkQXVkaXQoKScpO1xuICB9XG4gIGF1ZGl0QmluZGluZy5jbGllbnQgPz89IGNyZWF0ZVJlbW90ZUF1ZGl0Q2xpZW50KHtcbiAgICBzcG9vbDogY3JlYXRlRW52UmVkaXNBdWRpdFNwb29sKHsga2V5OiBhdWRpdFNwb29sS2V5KGF1ZGl0QmluZGluZy5zZXJ2aWNlTmFtZSkgfSkgPz8gdW5kZWZpbmVkLFxuICB9KTtcbiAgcmV0dXJuIGF1ZGl0QmluZGluZyBhcyBBdWRpdEJpbmRpbmcgJiB7IGNsaWVudDogUmVtb3RlQXVkaXRDbGllbnQgfTtcbn1cblxuLyoqXG4gKiBUaGUgYm91bmQgc2VydmljZSdzIFJlbW90ZUF1ZGl0Q2xpZW50LiBUaHJvd3MgXCJhdWRpdCBub3QgaW5pdGlhbGlzZWRcIiBiZWZvcmVcbiAqIGB3aXJlU2VydmljZVNlY3VyaXR5YCBoYXMgcnVuLiBJbnRlcm5hbDogY2FsbGVycyBlbWl0IHRocm91Z2hcbiAqIHtAbGluayByZWNvcmRBdWRpdH07IGB3aXJlU2VydmljZVNlY3VyaXR5YCBoYW5kcyB0aGlzIGdldHRlciB0byB0aGVcbiAqIGBhdXRoei5kZW5pZWRgIHNpbmsuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRCb3VuZEF1ZGl0Q2xpZW50KCk6IFJlbW90ZUF1ZGl0Q2xpZW50IHtcbiAgcmV0dXJuIGJvdW5kQXVkaXQoKS5jbGllbnQ7XG59XG5cbi8qKlxuICogUmVjb3JkIGFuIGV2ZW50IGluIHRoZSBkdXJhYmxlLCBoYXNoLWNoYWluZWQgY2VudHJhbCBhdWRpdCB0cmFpbCAocGxhdGZvcm0nc1xuICogYFBPU1QgL2F1ZGl0L2V2ZW50c2AgaW5nZXN0KSwgYXR0cmlidXRlZCB0byB0aGUgc2VydmljZSBib3VuZCBhdCBib290LlxuICpcbiAqIEZJUkUtQU5ELUZPUkdFVDogZGVsaXZlcnkgbmV2ZXIgYmxvY2tzIG9yIHRocm93cyDigJQgZW1pdCBvbmx5IEFGVEVSIHRoZVxuICogbXV0YXRpb24gc3VjY2VlZHMsIGFuZCBrZWVwIGBkZXRhaWxzYCBmcmVlIG9mIHNlY3JldHMvdG9rZW5zLCBQSUkgYW5kIEFXU1xuICogYWNjb3VudCBpZHMuIFRoZSBPTkUgdGhpbmcgdGhhdCB0aHJvd3MgaXMgY2FsbGluZyBpdCBiZWZvcmVcbiAqIGB3aXJlU2VydmljZVNlY3VyaXR5KHNlcnZpY2VOYW1lKWAgaGFzIGJvdW5kIHRoZSBzZXJ2aWNlOiB0aGF0IGlzIGEgd2lyaW5nXG4gKiBidWcsIGFuZCBmYWlsaW5nIGxvdWRseSBiZWF0cyBzaWxlbnRseSBhdHRyaWJ1dGluZyB0aGUgZXZlbnQgdG8gbm9ib2R5LlxuICpcbiAqIChUaGUgd2luc3Rvbi9Mb2tpIGxvZyBsaW5lIGlzIGEgZGlmZmVyZW50IHNpbms6IGBsb2dBdWRpdEV2ZW50YC4pXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWNvcmRBdWRpdChldmVudDogUmVtb3RlQXVkaXRFdmVudCk6IHZvaWQge1xuICBjb25zdCB7IGNsaWVudCwgc2VydmljZU5hbWUgfSA9IGJvdW5kQXVkaXQoKTtcbiAgY2xpZW50LnJlY29yZChldmVudCwgc2VydmljZU5hbWUpO1xufVxuIl19
|
|
361
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVtb3RlLWF1ZGl0LWNsaWVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zZXJ2aWNlcy9yZW1vdGUtYXVkaXQtY2xpZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUFFdEMsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLFFBQVEsQ0FBQztBQUNwQyxPQUFPLEVBQUUsY0FBYyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDekUsT0FBTyxFQUFFLGFBQWEsRUFBRSx3QkFBd0IsRUFBeUMsTUFBTSxrQkFBa0IsQ0FBQztBQUNsSCxPQUFPLEVBQUUsZ0JBQWdCLEVBQXVCLE1BQU0sa0JBQWtCLENBQUM7QUFDekUsT0FBTyxFQUFFLHFCQUFxQixFQUF3QixNQUFNLG1DQUFtQyxDQUFDO0FBQ2hHLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQ3ZFLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUU1RCxPQUFPLEVBQTBCLE1BQU0sa0NBQWtDLENBQUM7QUFDMUUsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDMUQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ2xELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUN6RCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDcEQsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBRS9ELE1BQU0sTUFBTSxHQUFHLFlBQVksQ0FBQyxjQUFjLENBQUMsQ0FBQztBQUU1Qzs7Ozs7Ozs7R0FRRztBQUNILE1BQU0scUJBQXFCLEdBQStEO0lBQ3hGLG1CQUFtQixFQUFFLENBQUM7SUFDdEIsVUFBVSxFQUFFLENBQUM7Q0FDZCxDQUFDO0FBNkVGLHVGQUF1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SyxFQUFFLHdCQUF3QixDQUFDLEVBQUUsR0FBRyxFQUFFLGFBQWEsQ0FBQyxZQUFZLENBQUMsV0FBVyxDQUFDLEVBQUUsQ0FBQyxJQUFJLFNBQVM7S0FDL0YsQ0FBQyxDQUFDO0lBQ0gsT0FBTyxZQUE0RCxDQUFDO0FBQ3RFLENBQUM7QUFFRDs7Ozs7R0FLRztBQUNILE1BQU0sVUFBVSxtQkFBbUI7SUFDakMsT0FBTyxVQUFVLEVBQUUsQ0FBQyxNQUFNLENBQUM7QUFDN0IsQ0FBQztBQUVEOzs7Ozs7Ozs7OztHQVdHO0FBQ0gsTUFBTSxVQUFVLFdBQVcsQ0FBQyxLQUF1QjtJQUNqRCxNQUFNLEVBQUUsTUFBTSxFQUFFLFdBQVcsRUFBRSxHQUFHLFVBQVUsRUFBRSxDQUFDO0lBQzdDLE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFLFdBQVcsQ0FBQyxDQUFDO0FBQ3BDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuaW1wb3J0IHsgcmFuZG9tVVVJRCB9IGZyb20gJ2NyeXB0byc7XG5pbXBvcnQgeyBhdWRpdEF1dGhCbG9jaywgY3VycmVudEF1ZGl0Q29udGV4dCB9IGZyb20gJy4vYXVkaXQtY29udGV4dC5qcyc7XG5pbXBvcnQgeyBhdWRpdFNwb29sS2V5LCBjcmVhdGVFbnZSZWRpc0F1ZGl0U3Bvb2wsIHR5cGUgQXVkaXRTcG9vbCwgdHlwZSBBdWRpdFNwb29sRW50cnkgfSBmcm9tICcuL2F1ZGl0LXNwb29sLmpzJztcbmltcG9ydCB7IGNyZWF0ZVNhZmVDbGllbnQsIHR5cGUgUmVxdWVzdE9wdGlvbnMgfSBmcm9tICcuL2h0dHAtY2xpZW50LmpzJztcbmltcG9ydCB7IHNldEF1dGh6RGVuaWFsQXVkaXRvciwgdHlwZSBBdXRoekRlbmlhbEluZm8gfSBmcm9tICcuLi9taWRkbGV3YXJlL3Blcm1pc3Npb24tZ2F0ZXMuanMnO1xuaW1wb3J0IHsgZ2V0U2VydmljZUF1dGhIZWFkZXIgfSBmcm9tICcuLi9taWRkbGV3YXJlL3NlcnZpY2UtdG9rZW5zLmpzJztcbmltcG9ydCB7IFNZU1RFTV9PUkdfSUQgfSBmcm9tICcuLi9taWRkbGV3YXJlL3N5c3RlbS1vcmcuanMnO1xuaW1wb3J0IHR5cGUgeyBTZXJ2aWNlQ29uZmlnIH0gZnJvbSAnLi4vdHlwZXMvY29tbW9uLmpzJztcbmltcG9ydCB7IHR5cGUgUmVtb3RlQXVkaXRBY3Rpb24gfSBmcm9tICcuLi90eXBlcy9yZW1vdGUtYXVkaXQtYWN0aW9ucy5qcyc7XG5pbXBvcnQgeyBBTk9OWU1PVVNfQUNUT1JfSUQgfSBmcm9tICcuLi91dGlscy9pZGVudGl0eS5qcyc7XG5pbXBvcnQgeyBjcmVhdGVMb2dnZXIgfSBmcm9tICcuLi91dGlscy9sb2dnZXIuanMnO1xuaW1wb3J0IHsgZW1pdENvdW50ZXIgfSBmcm9tICcuLi91dGlscy9tZXRyaWMtZW1pdHRlci5qcyc7XG5pbXBvcnQgeyBlcnJvck1lc3NhZ2UgfSBmcm9tICcuLi91dGlscy9yZXNwb25zZS5qcyc7XG5pbXBvcnQgeyBzZXJ2aWNlRW5kcG9pbnQgfSBmcm9tICcuLi91dGlscy9zZXJ2aWNlLXJlZ2lzdHJ5LmpzJztcblxuY29uc3QgbG9nZ2VyID0gY3JlYXRlTG9nZ2VyKCdyZW1vdGUtYXVkaXQnKTtcblxuLyoqXG4gKiBBdWRpdCBpbmdlc3QgaXMgYmVzdC1lZmZvcnQgYW5kIE1VU1QgTk9UIGJsb2NrIHRoZSBjYWxsZXIsIGJ1dCBhIHRyYW5zaWVudFxuICogZmFpbHVyZSAoNDI5IC8gNXh4IC8gY29ubmVjdGlvbiByZXNldCAvIHRpbWVvdXQpIHNob3VsZCBub3Qgc2lsZW50bHkgZHJvcCB0aGVcbiAqIHJvdyBvbiB0aGUgZmlyc3QgYXR0ZW1wdC4gRWFjaCBlbWlzc2lvbiBjYXJyaWVzIGEgc3RhYmxlIHBlci1ldmVudFxuICogYElkZW1wb3RlbmN5LUtleWAgKHNlZSBgcmVjb3JkYCksIHNvIHRoZSBodHRwLWNsaWVudCB0cmVhdHMgdGhlIFBPU1QgYXNcbiAqIHJldHJ5LXNhZmUgYW5kIHRoZSBwbGF0Zm9ybSBjYW4gZGVkdXAgYSByZXRyaWVkIGRlbGl2ZXJ5IGluc3RlYWQgb2Ygd3JpdGluZyBhXG4gKiBkdXBsaWNhdGUgcm93LiBCdWRnZXQgaXMga2VwdCBzbWFsbCBzbyBhIGhhcmQtZG93biBwbGF0Zm9ybSBjYW4ndCBiYWNrIHRoZVxuICogd29ya2VyIHVwIGZvciBsb25nOiBiYXNlIGRlbGF5IMOXKDIgcmV0cmllcykgKyBhIGNvdXBsZSBvZiA0MjkgYmFja29mZnMuXG4gKi9cbmNvbnN0IEFVRElUX1JFUVVFU1RfT1BUSU9OUzogUGljazxSZXF1ZXN0T3B0aW9ucywgJ21heFJhdGVMaW1pdFJldHJpZXMnIHwgJ21heFJldHJpZXMnPiA9IHtcbiAgbWF4UmF0ZUxpbWl0UmV0cmllczogMixcbiAgbWF4UmV0cmllczogMixcbn07XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVtb3RlQXVkaXRFdmVudCB7XG4gIGFjdGlvbjogUmVtb3RlQXVkaXRBY3Rpb247XG4gIGFjdG9ySWQ6IHN0cmluZztcbiAgYWN0b3JFbWFpbD86IHN0cmluZztcbiAgLyoqXG4gICAqIFRoZSBvcmcgdGhlIGV2ZW50IGlzIHJlY29yZGVkIEZPUiDigJQgUkVRVUlSRUQuIFRoZSBwbGF0Zm9ybSBpbmdlc3QgYmluZHMgZXZlcnlcbiAgICogZXZlbnQgdG8gdGhlIHNlcnZpY2UgdG9rZW4ncyBvcmcsIGFuZCB0aGUgY2xpZW50IG1pbnRzIHRoYXQgdG9rZW4gd2l0aCB0aGlzXG4gICAqIHZhbHVlLCBzbyBhbiBvcmctbGVzcyBldmVudCBjYW4gbmV2ZXIgYmUgc3RvcmVkIChpdCB1c2VkIHRvIGJlIHJlZnVzZWQgNDAzXG4gICAqIFwibm8gb3JnIGNsYWltXCIgYW5kIHRoZW4gd2VkZ2UgdGhlIHNwb29sKS4gU3lzdGVtIHdvcmsgd2l0aCBubyB0ZW5hbnQgcGFzc2VzXG4gICAqIGBTWVNURU1fT1JHX0lEYCBleHBsaWNpdGx5IOKAlCBlLmcuIGEgcmVnaXN0cnkgR0Mgc3dlZXAuXG4gICAqL1xuICBvcmdJZDogc3RyaW5nO1xuICAvKipcbiAgICogVGhlIG9yZyB0aGUgYWN0aW9uIHRvdWNoZWQsIHdoZW4gaXQgaXMgTk9UIGBvcmdJZGAgKHRoZSBzeXN0ZW0gb3JnIGFjdGluZyBvblxuICAgKiBhIHB1Ymxpc2hlcidzIHBsdWdpbiwgYSBzdXBlcmFkbWluIHB1cmdpbmcgYSB0ZW5hbnQncyBwaXBlbGluZSkuIEFjY2VwdGVkXG4gICAqIGNyb3NzLW9yZyBvbmx5IGZyb20gYSBzeXN0ZW0tb3JnIHRva2VuLCBvciB3aGVuIHRoZSBpbmJvdW5kIHByaW5jaXBhbCB3YXMgYVxuICAgKiBzdXBlcmFkbWluIC8gc3lzdGVtLW9yZyBtZW1iZXIgKHNlZSBgYXVkaXRDcm9zc09yZ2AgaW4gdGhlIGluZ2VzdCkuXG4gICAqL1xuICBhZmZlY3RlZE9yZ0lkPzogc3RyaW5nO1xuICB0YXJnZXRUeXBlPzogc3RyaW5nO1xuICB0YXJnZXRJZD86IHN0cmluZztcbiAgLyoqXG4gICAqIERpZCB0aGUgYXVkaXRlZCBhY3Rpb24gc3VjY2VlZCBvciBmYWlsPyBEZWZhdWx0cyB0byAnc3VjY2Vzcycgd2hlbiBvbWl0dGVkXG4gICAqICh0aGUgcGxhdGZvcm0gaW5nZXN0IGFwcGxpZXMgdGhlIHNhbWUgZGVmYXVsdCkuIERlbmllZC1hdXRoeiBldmVudHMgc2V0XG4gICAqICdmYWlsdXJlJyBzbyBhIHJldmlld2VyIGNhbiBmaWx0ZXIgYXR0ZW1wdHMgZnJvbSBjb21wbGV0ZWQgYWN0aW9ucy5cbiAgICovXG4gIG91dGNvbWU/OiAnc3VjY2VzcycgfCAnZmFpbHVyZSc7XG4gIC8qKlxuICAgKiBXaGVuIHRoZSBhdWRpdGVkIGFjdGlvbiBhY3R1YWxseSBPQ0NVUlJFRCAoSVNPLTg2MDEpLCBzdGFtcGVkIGF0IGVtaXNzaW9uLlxuICAgKiBUaGUgcGxhdGZvcm0gc3RvcmVzIHRoaXMgZm9yIHJldmlld2VyczsgaXQgaXMgTk9UIHRoZSBjaGFpbi1vcmRlcmluZyBmaWVsZFxuICAgKiAodGhlIHRhbXBlci1ldmlkZW50IGNoYWluIG9yZGVycyBieSBpbmdlc3QvYGNyZWF0ZWRBdGApLiBJdCBtYXR0ZXJzIGZvclxuICAgKiBTUE9PTEVEIGV2ZW50czogb25lIGJ1ZmZlcmVkIGR1cmluZyBhIHBsYXRmb3JtIG91dGFnZSBpcyByZS1kZWxpdmVyZWQg4oCUIGFuZFxuICAgKiBzbyBjaGFpbmVkIOKAlCBsYXRlciwgYnV0IGBvY2N1cnJlZEF0YCBwcmVzZXJ2ZXMgd2hlbiBpdCByZWFsbHkgaGFwcGVuZWQuXG4gICAqL1xuICBvY2N1cnJlZEF0Pzogc3RyaW5nO1xuICAvKipcbiAgICogU3RhYmxlIHBlci1lbWlzc2lvbiBkZWR1cCBrZXkgKGFsc28gc2VudCBhcyB0aGUgYElkZW1wb3RlbmN5LUtleWAgaGVhZGVyIHRoZVxuICAgKiBwbGF0Zm9ybSBpbmdlc3QgZGVkdXBzIG9uKS4gU3RhbXBlZCBieSBgcmVjb3JkKClgIGFuZCBjYXJyaWVkIG9uIHRoZSBzcG9vbGVkXG4gICAqIGNvcHkgc28gYSBsaXZlIGF0dGVtcHQgYW5kIGl0cyBsYXRlciByZS1kZWxpdmVyeSBjb2xsYXBzZSB0byBPTkUgc3RvcmVkIHJvdy5cbiAgICovXG4gIGlkZW1wb3RlbmN5S2V5Pzogc3RyaW5nO1xuICAvKipcbiAgICogQ29ycmVsYXRpb24gY29udGV4dC4gTm9ybWFsbHkgbGVmdCB1bnNldDogYHJlY29yZCgpYCBmaWxscyBlYWNoIGZyb20gdGhlXG4gICAqIGFtYmllbnQgYXVkaXQgY29udGV4dCAoc2VlIGBydW5XaXRoQXVkaXRDb250ZXh0YCkg4oCUIHRoZSBpbmJvdW5kIHJlcXVlc3QncyBpZCxcbiAgICogdHJhY2UgaWQsIGNsaWVudCBpcCBhbmQgdXNlciBhZ2VudC4gU2V0IG9uZSBvbmx5IHRvIG92ZXJyaWRlIGl0LlxuICAgKlxuICAgKiBBbiBBTk9OWU1PVVMgYWN0b3IgbmV2ZXIgaW5oZXJpdHMgdGhlIGNsaWVudCBpcCAvIHVzZXIgYWdlbnQgZnJvbSBjb250ZXh0OlxuICAgKiB0aG9zZSByb3dzIGFyZSB0aGUgcHVibGljLCB1bmF1dGhlbnRpY2F0ZWQgc3VyZmFjZXMgKHBsdWdpbiBzdWJtaXNzaW9ucyxcbiAgICogcmVwb3J0IHZlcmlmeS91bnN1YnNjcmliZSkgd2hvc2UgY2FsbGVycyBkZWxpYmVyYXRlbHkgcmVjb3JkIG9ubHkgYSBIQVNIRURcbiAgICogaXAvYWRkcmVzcyDigJQgc3RhbXBpbmcgdGhlIHJhdyBpcCBiZXNpZGUgaXQgd291bGQgdW5kbyB0aGF0LiBQYXNzIGBpcGAgL1xuICAgKiBgdXNlckFnZW50YCBleHBsaWNpdGx5IGlmIGFuIGFub255bW91cyByb3cgZ2VudWluZWx5IG5lZWRzIHRoZW0uXG4gICAqL1xuICByZXF1ZXN0SWQ/OiBzdHJpbmc7XG4gIHRyYWNlSWQ/OiBzdHJpbmc7XG4gIGlwPzogc3RyaW5nO1xuICB1c2VyQWdlbnQ/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBGcmVlLWZvcm0gZXZlbnQgZGV0YWlsLiBLZWVwIGl0IGZyZWUgb2Ygc2VjcmV0cy90b2tlbnMsIFBJSSBhbmQgQVdTIGFjY291bnRcbiAgICogaWRzLiBUaGUga2V5cyBgX2F1dGhgIGFuZCBgX2NvbnRleHRgIGFyZSBSRVNFUlZFRDogYHJlY29yZCgpYCByZXBsYWNlcyB0aGVtXG4gICAqIHdpdGggdGhlIHZlcmlmaWVkIGNyZWRlbnRpYWwgYmxvY2sgYW5kIHRoZSBjb3JyZWxhdGlvbi9qb2IgaWRzIGZyb20gdGhlXG4gICAqIGFtYmllbnQgYXVkaXQgY29udGV4dCwgd2hhdGV2ZXIgdGhlIGNhbGwgc2l0ZSBwYXNzZWQuXG4gICAqL1xuICBkZXRhaWxzPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG59XG5cbi8qKlxuICogVGhlIGV2ZW50IGFzIGl0IGdvZXMgb3ZlciB0aGUgd2lyZSBhbmQgaW50byB0aGUgc3Bvb2w6IHRoZSBjYWxsLXNpdGUgZXZlbnRcbiAqIHBsdXMgd2hhdCBgcmVjb3JkKClgIHN0YW1wcyBmcm9tIHRoZSBhbWJpZW50IGF1ZGl0IGNvbnRleHQuIGBpbXBlcnNvbmF0b3JJZGAgaXNcbiAqIE5PVCBhIGNhbGwtc2l0ZSBmaWVsZCDigJQgaXQgY29tZXMgb25seSBmcm9tIHRoZSBpbmJvdW5kIHJlcXVlc3QncyB2ZXJpZmllZFxuICogdG9rZW4sIHNvIG5vIHJvdXRlIGNhbiBhdHRyaWJ1dGUgYW4gYWN0aW9uIHRvIGFuIGltcGVyc29uYXRvciBieSBwYXNzaW5nIG9uZS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBSZW1vdGVBdWRpdFdpcmVFdmVudCBleHRlbmRzIFJlbW90ZUF1ZGl0RXZlbnQge1xuICBpbXBlcnNvbmF0b3JJZD86IHN0cmluZztcbn1cblxuLyoqIGBkZXRhaWxzYCBrZXlzIG9ubHkgYHJlY29yZCgpYCBtYXkgd3JpdGUgKHNlZSB7QGxpbmsgUmVtb3RlQXVkaXRFdmVudC5kZXRhaWxzfSkuICovXG5jb25zdCBSRVNFUlZFRF9ERVRBSUxfS0VZUyA9IFsnX2F1dGgnLCAnX2NvbnRleHQnXSBhcyBjb25zdDtcblxuLyoqXG4gKiBTdGFtcCBhbiBldmVudCB3aXRoIHRoZSBhbWJpZW50IGF1ZGl0IGNvbnRleHQgYXQgdGhlIG1vbWVudCBpdCBpcyBSRUNPUkRFRC5cbiAqIFBlcnNpc3RlZCBvbiB0aGUgZXZlbnQsIHNvIGEgc3Bvb2xlZCByZS1kZWxpdmVyeSBjYXJyaWVzIHRoZSBvcmlnaW5hbFxuICogcmVxdWVzdCdzIGNvbnRleHQgcmF0aGVyIHRoYW4gd2hhdGV2ZXIgaXMgYW1iaWVudCB3aGVuIHRoZSBkcmFpbiBydW5zLlxuICovXG5mdW5jdGlvbiBzdGFtcEF1ZGl0Q29udGV4dChldmVudDogUmVtb3RlQXVkaXRFdmVudCk6IFJlbW90ZUF1ZGl0V2lyZUV2ZW50IHtcbiAgY29uc3QgY3R4ID0gY3VycmVudEF1ZGl0Q29udGV4dCgpO1xuICBjb25zdCBwcmluY2lwYWwgPSBjdHg/LnByaW5jaXBhbD8uKCk7XG4gIGNvbnN0IGF1dGggPSBhdWRpdEF1dGhCbG9jayhwcmluY2lwYWwpO1xuICBjb25zdCBjb250ZXh0ID0geyAuLi5jdHg/LmNvcnJlbGF0aW9uLCAuLi5jdHg/LmpvYiB9O1xuICBjb25zdCBhbm9ueW1vdXMgPSBldmVudC5hY3RvcklkID09PSBBTk9OWU1PVVNfQUNUT1JfSUQ7XG4gIGNvbnN0IGRldGFpbHM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+ID0geyAuLi5ldmVudC5kZXRhaWxzIH07XG4gIGZvciAoY29uc3Qga2V5IG9mIFJFU0VSVkVEX0RFVEFJTF9LRVlTKSBkZWxldGUgZGV0YWlsc1trZXldO1xuICBpZiAoYXV0aCkgZGV0YWlscy5fYXV0aCA9IGF1dGg7XG4gIGlmIChPYmplY3Qua2V5cyhjb250ZXh0KS5sZW5ndGggPiAwKSBkZXRhaWxzLl9jb250ZXh0ID0gY29udGV4dDtcbiAgcmV0dXJuIHtcbiAgICAuLi5ldmVudCxcbiAgICByZXF1ZXN0SWQ6IGV2ZW50LnJlcXVlc3RJZCA/PyBjdHg/LnJlcXVlc3RJZCxcbiAgICB0cmFjZUlkOiBldmVudC50cmFjZUlkID8/IGN0eD8udHJhY2VJZCxcbiAgICBpcDogZXZlbnQuaXAgPz8gKGFub255bW91cyA/IHVuZGVmaW5lZCA6IGN0eD8uaXApLFxuICAgIHVzZXJBZ2VudDogZXZlbnQudXNlckFnZW50ID8/IChhbm9ueW1vdXMgPyB1bmRlZmluZWQgOiBjdHg/LnVzZXJBZ2VudCksXG4gICAgLi4uKHByaW5jaXBhbD8uaW1wZXJzb25hdG9ySWQgPyB7IGltcGVyc29uYXRvcklkOiBwcmluY2lwYWwuaW1wZXJzb25hdG9ySWQgfSA6IHt9KSxcbiAgICAuLi4oT2JqZWN0LmtleXMoZGV0YWlscykubGVuZ3RoID4gMCA/IHsgZGV0YWlscyB9IDogeyBkZXRhaWxzOiB1bmRlZmluZWQgfSksXG4gIH07XG59XG5cbi8qKlxuICogV2hldGhlciB0aGlzIGV2ZW50IG1heSBuYW1lIGFuIGBhZmZlY3RlZE9yZ0lkYCBvdXRzaWRlIGl0cyBvd24gb3JnLiBEZXJpdmVkXG4gKiBPTkxZIGZyb20gdGhlIHN0YW1wZWQgYF9hdXRoYCBibG9jayAodGhlIHZlcmlmaWVkIGluYm91bmQgcHJpbmNpcGFsKSwgd2hpY2hcbiAqIGByZWNvcmQoKWAgYWx3YXlzIG92ZXJ3cml0ZXMg4oCUIGEgY2FsbCBzaXRlIGNhbm5vdCBncmFudCBpdC5cbiAqL1xuZnVuY3Rpb24gY3Jvc3NPcmdBdXRob3JpemVkKGV2ZW50OiBSZW1vdGVBdWRpdFdpcmVFdmVudCk6IGJvb2xlYW4ge1xuICBpZiAoIWV2ZW50LmFmZmVjdGVkT3JnSWQgfHwgZXZlbnQuYWZmZWN0ZWRPcmdJZCA9PT0gZXZlbnQub3JnSWQpIHJldHVybiBmYWxzZTtcbiAgY29uc3QgYXV0aCA9IGV2ZW50LmRldGFpbHM/Ll9hdXRoIGFzIHsgc3VwZXJBZG1pbj86IGJvb2xlYW47IHN5c3RlbU9yZz86IGJvb2xlYW4gfSB8IHVuZGVmaW5lZDtcbiAgcmV0dXJuIGF1dGg/LnN1cGVyQWRtaW4gPT09IHRydWUgfHwgYXV0aD8uc3lzdGVtT3JnID09PSB0cnVlO1xufVxuXG4vKipcbiAqIFJlc3VsdCBvZiBvbmUgZGVsaXZlcnkgYXR0ZW1wdC4gYHJlamVjdGVkYCBpcyBhIFBFUk1BTkVOVCByZWZ1c2FsIChhIDR4eCBvdGhlclxuICogdGhhbiA0MDgvNDI5KTogdGhlIHBsYXRmb3JtIHdpbGwgbmV2ZXIgYWNjZXB0IHRoaXMgZXZlbnQsIHNvIHJldHJ5aW5nIGl0IG9ubHlcbiAqIHdlZGdlcyB0aGUgc3Bvb2wgYmVoaW5kIGl0LlxuICovXG50eXBlIERlbGl2ZXJ5UmVzdWx0ID0geyBraW5kOiAnZGVsaXZlcmVkJyB9IHwgeyBraW5kOiAncmV0cnknIH0gfCB7IGtpbmQ6ICdyZWplY3RlZCc7IHN0YXR1czogbnVtYmVyIH07XG5cbi8qKiA0eHggc3RhdHVzZXMgdGhhdCBhcmUgdHJhbnNpZW50LCBub3QgYSB2ZXJkaWN0IG9uIHRoZSBldmVudC4gKi9cbmNvbnN0IFJFVFJZQUJMRV80WFggPSBuZXcgU2V0KFs0MDgsIDQyOV0pO1xuXG4vKipcbiAqIENsaWVudCBmb3IgUE9TVGluZyBhdWRpdCBldmVudHMgdG8gdGhlIHBsYXRmb3JtJ3MgYC9hdWRpdC1ldmVudHNgIGluZ2VzdFxuICogZW5kcG9pbnQuIE1pbnRzIGEgZnJlc2ggc2VydmljZSB0b2tlbiBwZXIgY2FsbCAoNSBtaW4gVFRMKSAgdGhlcmUncyBub1xuICogbWVhbmluZ2Z1bCBjYWNoaW5nIGJlbmVmaXQgd2hlbiBlbWlzc2lvbnMgYXJlIHNwYXJzZS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBSZW1vdGVBdWRpdENsaWVudCB7XG4gIC8qKlxuICAgKiBGaXJlLWFuZC1mb3JnZXQgYXVkaXQgZW1pc3Npb24uIEZhaWx1cmVzIGFyZSBsb2dnZWQgYXQgd2FybiBsZXZlbCBidXRcbiAgICogbmV2ZXIgdGhyb3duICB0aGUgb3JpZ2luYXRpbmcgYWN0aW9uIChlLmcuIGEgcGx1Z2luIGJ1aWxkKSBoYXMgaXRzXG4gICAqIG93biBzdWNjZXNzL2ZhaWx1cmUgcGF0aCB0aGF0IHNob3VsZG4ndCBnZXQgcG9sbHV0ZWQgYnkgYSBmbGFreSBhdWRpdFxuICAgKiBkb3duc3RyZWFtLiBXaGVuIGEge0BsaW5rIEF1ZGl0U3Bvb2x9IGlzIGNvbmZpZ3VyZWQsIGFuIGVtaXNzaW9uIHRoYXRcbiAgICogZXhoYXVzdHMgaXRzIGxpdmUgcmV0cmllcyBpcyBidWZmZXJlZCBhbmQgcmUtZGVsaXZlcmVkIGxhdGVyIGluc3RlYWQgb2ZcbiAgICogYmVpbmcgZHJvcHBlZC5cbiAgICovXG4gIHJlY29yZChldmVudDogUmVtb3RlQXVkaXRFdmVudCwgc2VydmljZU5hbWU6IHN0cmluZyk6IHZvaWQ7XG4gIC8qKiBTdG9wIHRoZSBiYWNrZ3JvdW5kIHNwb29sLWRyYWluIHRpbWVyIChpZiBhbnkpLiBTYWZlIHRvIGNhbGwgcmVwZWF0ZWRseS4gKi9cbiAgY2xvc2UoKTogdm9pZDtcbn1cblxuLyoqXG4gKiBDb25maWd1cmF0aW9uIGZvciB0aGUgcmVtb3RlIGF1ZGl0IGNsaWVudC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBSZW1vdGVBdWRpdENsaWVudENvbmZpZyB7XG4gIC8qKiBQbGF0Zm9ybSBzZXJ2aWNlIGhvc3QgKGRlZmF1bHQ6IGVudiBQTEFURk9STV9TRVJWSUNFX0hPU1Qgb3IgJ3BsYXRmb3JtJykgKi9cbiAgaG9zdD86IHN0cmluZztcbiAgLyoqIFBsYXRmb3JtIHNlcnZpY2UgcG9ydCAoZGVmYXVsdDogZW52IFBMQVRGT1JNX1NFUlZJQ0VfUE9SVCBvciAzMDAwKSAqL1xuICBwb3J0PzogbnVtYmVyO1xuICAvKiogUmVxdWVzdCB0aW1lb3V0IG1zIChkZWZhdWx0IDMwMDAgIGF1ZGl0IHNob3VsZG4ndCBibG9jayB0aGUgd29ya2VyKS4gKi9cbiAgdGltZW91dD86IG51bWJlcjtcbiAgLyoqXG4gICAqIE9wdGlvbmFsIGR1cmFibGUgYnVmZmVyLiBXaGVuIHNldCwgYW4gZW1pc3Npb24gdGhhdCBleGhhdXN0cyBpdHMgbGl2ZSByZXRyeVxuICAgKiBidWRnZXQgKHN1c3RhaW5lZCBwbGF0Zm9ybSBvdXRhZ2UpIGlzIHNwb29sZWQgYW5kIHJlLWRlbGl2ZXJlZCDigJQgb24gdGhlIG5leHRcbiAgICogc3VjY2Vzc2Z1bCBlbWlzc2lvbiBhbmQgb24gYSBwZXJpb2RpYyB0aW1lciDigJQgaW5zdGVhZCBvZiBiZWluZyBsb3N0LlxuICAgKi9cbiAgc3Bvb2w/OiBBdWRpdFNwb29sO1xuICAvKiogU3Bvb2wtZHJhaW4gaW50ZXJ2YWwgbXMgKGRlZmF1bHQgMzBfMDAwKS4gT25seSB1c2VkIHdoZW4gYHNwb29sYCBpcyBzZXQuICovXG4gIGRyYWluSW50ZXJ2YWxNcz86IG51bWJlcjtcbiAgLyoqIE1heCBlbnRyaWVzIGRyYWluZWQgcGVyIHN3ZWVwIChkZWZhdWx0IDEwMCkuICovXG4gIGRyYWluQmF0Y2hTaXplPzogbnVtYmVyO1xufVxuXG4vKipcbiAqIENvbnN0cnVjdCBhIHJlbW90ZS1hdWRpdCBjbGllbnQgdGFyZ2V0ZWQgYXQgdGhlIHBsYXRmb3JtIHNlcnZpY2UuXG4gKlxuICogVXNlZCBieSBhcGkvcGx1Z2luJ3MgYnVpbGQgd29ya2VyIHRvIHB1c2ggYHBsdWdpbi5idWlsZC4qYCBldmVudHMgaW50b1xuICogdGhlIHBsYXRmb3JtJ3MgTW9uZ29EQiBgYXVkaXRfZXZlbnRzYCBjb2xsZWN0aW9uLiBPdGhlciBzZXJ2aWNlc1xuICogd2l0aCB3b3JrZXItc3R5bGUgZW1pdHRlcnMgY2FuIHVzZSB0aGUgc2FtZSBjbGllbnQuXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnN0IGF1ZGl0Q2xpZW50ID0gY3JlYXRlUmVtb3RlQXVkaXRDbGllbnQoKTtcbiAqIGF1ZGl0Q2xpZW50LnJlY29yZCh7XG4gKiBhY3Rpb246ICdwbHVnaW4uYnVpbGQuY29tcGxldGVkJyxcbiAqIGFjdG9ySWQ6ICd1c2VyLTEyMycsXG4gKiBvcmdJZDogJ29yZy1hY21lJyxcbiAqIHRhcmdldFR5cGU6ICdwbHVnaW4nLFxuICogdGFyZ2V0SWQ6ICdwbHVnaW4tYWJjJyxcbiAqIGRldGFpbHM6IHsgbmFtZTogJ215LXBsdWdpbicsIHZlcnNpb246ICcxLjAuMCcgfSxcbiAqIH0sICdwbHVnaW4nKTtcbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlUmVtb3RlQXVkaXRDbGllbnQoY29uZmlnOiBSZW1vdGVBdWRpdENsaWVudENvbmZpZyA9IHt9KTogUmVtb3RlQXVkaXRDbGllbnQge1xuICBjb25zdCBzZXJ2aWNlQ29uZmlnOiBTZXJ2aWNlQ29uZmlnID0ge1xuICAgIGhvc3Q6IGNvbmZpZy5ob3N0ID8/IHNlcnZpY2VFbmRwb2ludCgncGxhdGZvcm0nKS5ob3N0LFxuICAgIHBvcnQ6IGNvbmZpZy5wb3J0ID8/IHNlcnZpY2VFbmRwb2ludCgncGxhdGZvcm0nKS5wb3J0LFxuICAgIHRpbWVvdXQ6IGNvbmZpZy50aW1lb3V0ID8/IDMwMDAsXG4gIH07XG4gIC8vIEl0cyBvd24gYnJlYWtlciByb3V0ZSBjbGFzczogYXVkaXQgaW5nZXN0IGZhaWxpbmcgKDV4eCB3aGlsZSBwbGF0Zm9ybSdzXG4gIC8vIGF1ZGl0IHN0b3JlIGlzIGRlZ3JhZGVkKSBtdXN0IG5vdCBvcGVuIHRoZSBicmVha2VyIHRoYXQgcGxhdGZvcm0ncyBKV0tTIGFuZFxuICAvLyBrZXktZXhjaGFuZ2UgY2FsbHMgcmlkZSBvbiDigJQgdGhhdCB3b3VsZCB0dXJuIGFuIGF1ZGl0IGJyb3dub3V0IGludG8gYW4gYXV0aFxuICAvLyBvdXRhZ2UgaW4gZXZlcnkgc2VydmljZS5cbiAgY29uc3QgY2xpZW50ID0gY3JlYXRlU2FmZUNsaWVudChzZXJ2aWNlQ29uZmlnLCB7IGJyZWFrZXJDbGFzczogJ2F1ZGl0JyB9KTtcbiAgY29uc3Qgc3Bvb2wgPSBjb25maWcuc3Bvb2w7XG4gIGNvbnN0IGRyYWluQmF0Y2hTaXplID0gY29uZmlnLmRyYWluQmF0Y2hTaXplID8/IDEwMDtcblxuICAvKipcbiAgICogQXR0ZW1wdCBPTkUgbGl2ZSBkZWxpdmVyeS4gUmVzb2x2ZXMgYHRydWVgIG9uIGEgMnh4IGFjY2VwdCwgYGZhbHNlYCBvbiBhbnlcbiAgICogbm9uLTJ4eCAvIHRocm93biBlcnJvciAodGhlIGh0dHAtY2xpZW50IGhhcyBhbHJlYWR5IGFwcGxpZWQgdGhlIHJldHJ5XG4gICAqIGJ1ZGdldCkuIEEgc3RhYmxlIHBlci1lbWlzc2lvbiBgSWRlbXBvdGVuY3ktS2V5YCBtYWtlcyB0aGlzIG5vbi1pZGVtcG90ZW50XG4gICAqIFBPU1QgcmV0cnktc2FmZSBhbmQgbGV0cyB0aGUgcGxhdGZvcm0gaW5nZXN0IGRlZHVwIGEgcmUtZGVsaXZlcmVkIGV2ZW50XG4gICAqIGluc3RlYWQgb2Ygd3JpdGluZyBhIGR1cGxpY2F0ZSBhdWRpdCByb3cgKGFuZCBkdXBsaWNhdGUgY2hhaW4gbGluaykuXG4gICAqIGBJZGVtcG90ZW5jeS1LZXlgIGlzIGRlcml2ZWQgZnJvbSB0aGUgZXZlbnQgc28gYSBTUE9PTEVEIHJlLWRlbGl2ZXJ5IHJldXNlc1xuICAgKiB0aGUgc2FtZSBrZXkgYXMgaXRzIG9yaWdpbmFsIGxpdmUgYXR0ZW1wdCDigJQgdGhlIHR3byBjb2xsYXBzZSB0byBvbmUgcm93LlxuICAgKi9cbiAgYXN5bmMgZnVuY3Rpb24gZGVsaXZlcihldmVudDogUmVtb3RlQXVkaXRXaXJlRXZlbnQsIHNlcnZpY2VOYW1lOiBzdHJpbmcpOiBQcm9taXNlPERlbGl2ZXJ5UmVzdWx0PiB7XG4gICAgdHJ5IHtcbiAgICAgIC8vIE1pbnRpbmcgdGhlIHRva2VuIGlzIElOU0lERSB0aGUgdHJ5IG9uIHB1cnBvc2UuIEl0IGNhbiB0aHJvdyDigJQgdGhlXG4gICAgICAvLyBzaWduaW5nIGtleSB1bnJlYWRhYmxlLCBub3QgYW4gRUMgUC0yNTYga2V5LCBvciBgU0VSVklDRV9OQU1FYCBub3RcbiAgICAgIC8vIG1hdGNoaW5nIHRoaXMgY2xpZW50J3MgbmFtZS4gT3V0c2lkZSB0aGUgYHRyeWAsIGBkZWxpdmVyYCB3b3VsZCByZWplY3RcbiAgICAgIC8vIGluc3RlYWQgb2YgcmVzb2x2aW5nIGBmYWxzZWA7IGByZWNvcmRgIGZpcmVzIGl0IHdpdGggYSBiYXJlIGAudGhlbmAsIHNvXG4gICAgICAvLyB0aGUgcmVqZWN0aW9uIHdvdWxkIGdvIHVuaGFuZGxlZCBhbmQgY3Jhc2gtbG9vcCB0aGUgcG9kIG9uIGl0cyBmaXJzdFxuICAgICAgLy8gYXVkaXRlZCB3cml0ZS4gSW5zaWRlLCBhIGtleSBwcm9ibGVtIGlzIGp1c3QgYW4gdW5kZWxpdmVyYWJsZSBldmVudDpcbiAgICAgIC8vIHNwb29sZWQsIG9yIGRyb3BwZWQgYW5kIG1ldGVyZWQuXG4gICAgICBjb25zdCBhdXRoSGVhZGVyID0gZ2V0U2VydmljZUF1dGhIZWFkZXIoe1xuICAgICAgICBzZXJ2aWNlTmFtZSxcbiAgICAgICAgb3JnSWQ6IGV2ZW50Lm9yZ0lkLFxuICAgICAgICByb2xlOiAnbWVtYmVyJyxcbiAgICAgICAgLi4uKGNyb3NzT3JnQXV0aG9yaXplZChldmVudCkgPyB7IGF1ZGl0Q3Jvc3NPcmc6IHRydWUgfSA6IHt9KSxcbiAgICAgIH0pO1xuICAgICAgY29uc3QgaGVhZGVyczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHtcbiAgICAgICAgJ0F1dGhvcml6YXRpb24nOiBhdXRoSGVhZGVyLFxuICAgICAgICAnSWRlbXBvdGVuY3ktS2V5JzogZXZlbnQuaWRlbXBvdGVuY3lLZXkgPz8gcmFuZG9tVVVJRCgpLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgY2xpZW50LnBvc3QoJy9hdWRpdC9ldmVudHMnLCBldmVudCwgeyBoZWFkZXJzLCAuLi5BVURJVF9SRVFVRVNUX09QVElPTlMgfSk7XG4gICAgICBjb25zdCBzdGF0dXMgPSByZXNwb25zZT8uc3RhdHVzQ29kZTtcbiAgICAgIGlmIChzdGF0dXMgIT09IHVuZGVmaW5lZCAmJiBzdGF0dXMgPj0gMjAwICYmIHN0YXR1cyA8IDMwMCkgcmV0dXJuIHsga2luZDogJ2RlbGl2ZXJlZCcgfTtcbiAgICAgIGlmIChzdGF0dXMgIT09IHVuZGVmaW5lZCAmJiBzdGF0dXMgPj0gNDAwICYmIHN0YXR1cyA8IDUwMCAmJiAhUkVUUllBQkxFXzRYWC5oYXMoc3RhdHVzKSkge1xuICAgICAgICByZXR1cm4geyBraW5kOiAncmVqZWN0ZWQnLCBzdGF0dXMgfTtcbiAgICAgIH1cbiAgICAgIGxvZ2dlci53YXJuKCdSZW1vdGUgYXVkaXQgaW5nZXN0IG5vbi1vaycsIHsgYWN0aW9uOiBldmVudC5hY3Rpb24sIHN0YXR1c0NvZGU6IHN0YXR1cyB9KTtcbiAgICAgIHJldHVybiB7IGtpbmQ6ICdyZXRyeScgfTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIGxvZ2dlci53YXJuKCdSZW1vdGUgYXVkaXQgaW5nZXN0IHRocmV3JywgeyBhY3Rpb246IGV2ZW50LmFjdGlvbiwgZXJyb3I6IGVycm9yTWVzc2FnZShlcnIpIH0pO1xuICAgICAgcmV0dXJuIHsga2luZDogJ3JldHJ5JyB9O1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBBIHBlcm1hbmVudGx5IHJlZnVzZWQgZXZlbnQgaXMgRFJPUFBFRCDigJQgbG91ZGx5LiBTcG9vbGluZyBpdCB3b3VsZCBwdXQgaXQgYXRcbiAgICogdGhlIGhlYWQgb2YgdGhlIHF1ZXVlIGZvcmV2ZXIgKHRoZSBkcmFpbiBzdG9wcyBhdCB0aGUgZmlyc3QgZmFpbHVyZSksIHNvIG9uZVxuICAgKiBtYWxmb3JtZWQgZXZlbnQgd291bGQgc2lsZW50bHkgc3RhbGwgZXZlcnkgbGF0ZXIgZXZlbnQgdGhpcyBzZXJ2aWNlIGVtaXRzLlxuICAgKiBgQXVkaXRFdmVudHNSZWplY3RlZGAgcGFnZXMgb24gdGhlIGNvdW50ZXIuXG4gICAqL1xuICBmdW5jdGlvbiByZXBvcnRSZWplY3RlZChldmVudDogUmVtb3RlQXVkaXRXaXJlRXZlbnQsIHNlcnZpY2VOYW1lOiBzdHJpbmcsIHN0YXR1czogbnVtYmVyKTogdm9pZCB7XG4gICAgZW1pdENvdW50ZXIoJ2F1ZGl0X2V2ZW50c19yZWplY3RlZF90b3RhbCcsIHsgc2VydmljZTogc2VydmljZU5hbWUsIHN0YXR1czogU3RyaW5nKHN0YXR1cykgfSk7XG4gICAgbG9nZ2VyLmVycm9yKCdSZW1vdGUgYXVkaXQgZXZlbnQgUkVKRUNURUQgYnkgaW5nZXN0IChkcm9wcGVkLCBub3QgcmV0cmllZCknLCB7XG4gICAgICBhY3Rpb246IGV2ZW50LmFjdGlvbixcbiAgICAgIHN0YXR1c0NvZGU6IHN0YXR1cyxcbiAgICAgIG9yZ0lkOiBldmVudC5vcmdJZCxcbiAgICAgIGFmZmVjdGVkT3JnSWQ6IGV2ZW50LmFmZmVjdGVkT3JnSWQsXG4gICAgICB0YXJnZXRUeXBlOiBldmVudC50YXJnZXRUeXBlLFxuICAgICAgdGFyZ2V0SWQ6IGV2ZW50LnRhcmdldElkLFxuICAgICAgcmVxdWVzdElkOiBldmVudC5yZXF1ZXN0SWQsXG4gICAgfSk7XG4gIH1cblxuICAvLyBTZXJpYWxpemUgc3Bvb2wgZHJhaW5zIHNvIGEgcGVyaW9kaWMgdGljayBhbmQgYW4gb24tc3VjY2VzcyBkcmFpbiBjYW4ndCBib3RoXG4gIC8vIHB1bGwgdGhlIHNhbWUgYmF0Y2guIFN0b3BzIGVhcmx5IHRoZSBtb21lbnQgYSByZS1kZWxpdmVyeSBmYWlscyAocGxhdGZvcm1cbiAgLy8gc3RpbGwgZG93bikgc28gd2UgZG9uJ3QgaGFtbWVyIGl0IG9yIGNodXJuIHRoZSBidWZmZXIuXG4gIGxldCBkcmFpbmluZyA9IGZhbHNlO1xuICBhc3luYyBmdW5jdGlvbiBkcmFpbigpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAoIXNwb29sIHx8IGRyYWluaW5nKSByZXR1cm47XG4gICAgZHJhaW5pbmcgPSB0cnVlO1xuICAgIHRyeSB7XG4gICAgICBmb3IgKDs7KSB7XG4gICAgICAgIGNvbnN0IGJhdGNoID0gYXdhaXQgc3Bvb2wudGFrZShkcmFpbkJhdGNoU2l6ZSk7XG4gICAgICAgIGlmIChiYXRjaC5sZW5ndGggPT09IDApIHJldHVybjtcbiAgICAgICAgLy8gYHNldHRsZWRgID0gZGVsaXZlcmVkIE9SIHBlcm1hbmVudGx5IHJlamVjdGVkOiBlaXRoZXIgd2F5IGl0IGxlYXZlcyB0aGVcbiAgICAgICAgLy8gc3Bvb2wuIE9ubHkgYSByZXRyeWFibGUgZmFpbHVyZSBzdG9wcyB0aGUgc3dlZXAgYW5kIGdvZXMgYmFjay5cbiAgICAgICAgY29uc3Qgc2V0dGxlZDogQXVkaXRTcG9vbEVudHJ5W10gPSBbXTtcbiAgICAgICAgY29uc3QgZmFpbGVkOiBBdWRpdFNwb29sRW50cnlbXSA9IFtdO1xuICAgICAgICBsZXQgcGxhdGZvcm1Eb3duID0gZmFsc2U7XG4gICAgICAgIGZvciAoY29uc3QgZW50cnkgb2YgYmF0Y2gpIHtcbiAgICAgICAgICBpZiAocGxhdGZvcm1Eb3duKSB7IGZhaWxlZC5wdXNoKGVudHJ5KTsgY29udGludWU7IH1cbiAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBkZWxpdmVyKGVudHJ5LmV2ZW50LCBlbnRyeS5zZXJ2aWNlTmFtZSk7XG4gICAgICAgICAgaWYgKHJlc3VsdC5raW5kID09PSAnZGVsaXZlcmVkJykge1xuICAgICAgICAgICAgc2V0dGxlZC5wdXNoKGVudHJ5KTtcbiAgICAgICAgICAgIGVtaXRDb3VudGVyKCdhdWRpdF9zcG9vbF9yZWRlbGl2ZXJlZF90b3RhbCcsIHsgc2VydmljZTogZW50cnkuc2VydmljZU5hbWUgfSk7XG4gICAgICAgICAgfSBlbHNlIGlmIChyZXN1bHQua2luZCA9PT0gJ3JlamVjdGVkJykge1xuICAgICAgICAgICAgc2V0dGxlZC5wdXNoKGVudHJ5KTtcbiAgICAgICAgICAgIHJlcG9ydFJlamVjdGVkKGVudHJ5LmV2ZW50LCBlbnRyeS5zZXJ2aWNlTmFtZSwgcmVzdWx0LnN0YXR1cyk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHBsYXRmb3JtRG93biA9IHRydWU7XG4gICAgICAgICAgICBmYWlsZWQucHVzaChlbnRyeSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIEFja25vd2xlZGdlIHRoZSBzZXR0bGVkIGVudHJpZXMgc28gdGhleSBjbGVhciB0aGUgaW4tcHJvZ3Jlc3MgbGlzdDsgdGhlXG4gICAgICAgIC8vIHJlbGlhYmxlIHRha2UoKSBtb3ZlZCB0aGUgd2hvbGUgYmF0Y2ggdGhlcmUsIHNvIHVuYWNrZWQgc3Vydml2b3JzIGFyZVxuICAgICAgICAvLyByZWNsYWltZWQgYnkgcmVjb3ZlcigpIGFmdGVyIGEgY3Jhc2ggcmF0aGVyIHRoYW4gYmVpbmcgc2lsZW50bHkgbG9zdC5cbiAgICAgICAgaWYgKHNldHRsZWQubGVuZ3RoID4gMCkgYXdhaXQgc3Bvb2wuYWNrKHNldHRsZWQpO1xuICAgICAgICBpZiAoZmFpbGVkLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICBhd2FpdCBzcG9vbC5yZXF1ZXVlKGZhaWxlZCk7XG4gICAgICAgICAgcmV0dXJuOyAvLyBzdGlsbCBkb3duIOKAlCB0cnkgYWdhaW4gb24gdGhlIG5leHQgdGlja1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBsb2dnZXIud2FybignQXVkaXQgc3Bvb2wgZHJhaW4gZmFpbGVkJywgeyBlcnJvcjogZXJyb3JNZXNzYWdlKGVycikgfSk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGRyYWluaW5nID0gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgbGV0IGRyYWluVGltZXI6IFJldHVyblR5cGU8dHlwZW9mIHNldEludGVydmFsPiB8IHVuZGVmaW5lZDtcbiAgaWYgKHNwb29sKSB7XG4gICAgLy8gUmVjbGFpbSBhbnkgYmF0Y2ggc3RyYW5kZWQgb24gdGhlIGluLXByb2dyZXNzIGxpc3QgYnkgYSBwcmlvciBjcmFzaCwgdGhlblxuICAgIC8vIGF0dGVtcHQgdG8gZmx1c2ggaXQuIEJvdGggYXJlIGJlc3QtZWZmb3J0ICh0aGUgc3Bvb2wgc3dhbGxvd3MgaXRzIGVycm9ycykuXG4gICAgdm9pZCBzcG9vbC5yZWNvdmVyKCkudGhlbigoKSA9PiBkcmFpbigpKTtcbiAgICAvLyBFdmVyeSB0aWNrOiBoZWFydGJlYXQgKHNvIHBlZXJzIG5ldmVyIHJlY2xhaW0gYSBiYXRjaCB0aGlzIHBvZCBpcyBzdGlsbFxuICAgIC8vIGRlbGl2ZXJpbmcg4oCUIGV2ZW4gbWlkLWRyYWluKSwgcmVjbGFpbSBiYXRjaGVzIG9mIHBvZHMgdGhhdCBkaWVkLCBkcmFpbi5cbiAgICBkcmFpblRpbWVyID0gc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICAgICAgdm9pZCBzcG9vbC5oZWFydGJlYXQoKS50aGVuKCgpID0+IHNwb29sLnJlY292ZXIoKSkudGhlbigoKSA9PiBkcmFpbigpKTtcbiAgICB9LCBjb25maWcuZHJhaW5JbnRlcnZhbE1zID8/IDMwXzAwMCk7XG4gICAgLy8gRG9uJ3QgbGV0IHRoZSBkcmFpbiB0aW1lciBrZWVwIHRoZSBwcm9jZXNzIGFsaXZlIG9uIHNodXRkb3duLlxuICAgIChkcmFpblRpbWVyIGFzIHVua25vd24gYXMgeyB1bnJlZj86ICgpID0+IHZvaWQgfSkudW5yZWY/LigpO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICByZWNvcmQoZXZlbnQsIHNlcnZpY2VOYW1lKSB7XG4gICAgICAvLyBTdGFtcCB0aGUgYW1iaWVudCByZXF1ZXN0L2pvYiBjb250ZXh0IGFuZCB3aGVuIHRoZSBhY3Rpb24gYWN0dWFsbHlcbiAgICAgIC8vIG9jY3VycmVkIChhbGwgc3Vydml2ZSBzcG9vbCBkZWxheSksIGFuZCBwaW4gYSBzdGFibGUgaWRlbXBvdGVuY3kga2V5IHNvIGFcbiAgICAgIC8vIGxpdmUgYXR0ZW1wdCBhbmQgaXRzIHNwb29sZWQgcmV0cnkgZGVkdXAuXG4gICAgICBjb25zdCBzdGFtcGVkOiBSZW1vdGVBdWRpdFdpcmVFdmVudCA9IHtcbiAgICAgICAgLi4uc3RhbXBBdWRpdENvbnRleHQoZXZlbnQpLFxuICAgICAgICBvY2N1cnJlZEF0OiBldmVudC5vY2N1cnJlZEF0ID8/IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKSxcbiAgICAgICAgaWRlbXBvdGVuY3lLZXk6IGV2ZW50LmlkZW1wb3RlbmN5S2V5ID8/IHJhbmRvbVVVSUQoKSxcbiAgICAgIH07XG4gICAgICB2b2lkIGRlbGl2ZXIoc3RhbXBlZCwgc2VydmljZU5hbWUpLnRoZW4oKHJlc3VsdCkgPT4ge1xuICAgICAgICBpZiAocmVzdWx0LmtpbmQgPT09ICdkZWxpdmVyZWQnKSB7XG4gICAgICAgICAgZW1pdENvdW50ZXIoJ2F1ZGl0X2VtaXR0ZWRfdG90YWwnLCB7IHNlcnZpY2U6IHNlcnZpY2VOYW1lLCBvdXRjb21lOiBzdGFtcGVkLm91dGNvbWUgPz8gJ3N1Y2Nlc3MnIH0pO1xuICAgICAgICAgIGlmIChzcG9vbCkgdm9pZCBkcmFpbigpOyAvLyBwbGF0Zm9ybSBpcyByZWFjaGFibGUg4oCUIGZsdXNoIGFueSBiYWNrbG9nXG4gICAgICAgIH0gZWxzZSBpZiAocmVzdWx0LmtpbmQgPT09ICdyZWplY3RlZCcpIHtcbiAgICAgICAgICByZXBvcnRSZWplY3RlZChzdGFtcGVkLCBzZXJ2aWNlTmFtZSwgcmVzdWx0LnN0YXR1cyk7XG4gICAgICAgIH0gZWxzZSBpZiAoc3Bvb2wpIHtcbiAgICAgICAgICB2b2lkIHNwb29sLmVucXVldWUoeyBldmVudDogc3RhbXBlZCwgc2VydmljZU5hbWUgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZW1pdENvdW50ZXIoJ2F1ZGl0X2Ryb3BwZWRfdG90YWwnLCB7IHNlcnZpY2U6IHNlcnZpY2VOYW1lIH0pO1xuICAgICAgICB9XG4gICAgICB9KS5jYXRjaCgoZXJyKSA9PiB7XG4gICAgICAgIC8vIEJlbHQgYW5kIGJyYWNlcy4gYGRlbGl2ZXJgIG5ldmVyIHJlamVjdHMsIGJ1dCBhbnl0aGluZyB0aGF0IHRocm93c1xuICAgICAgICAvLyBpbiB0aGUgY29udGludWF0aW9uIHdvdWxkIG90aGVyd2lzZSBiZWNvbWUgYW4gdW5oYW5kbGVkIHJlamVjdGlvbiDigJRcbiAgICAgICAgLy8gYW5kIGluIHRoaXMgcHJvY2VzcyB0aGF0IGlzIGEgY3Jhc2gsIG5vdCBhIGxvZyBsaW5lLiBBbiBhdWRpdCBldmVudFxuICAgICAgICAvLyBtdXN0IG5ldmVyIHRha2UgdGhlIHNlcnZpY2UgZG93bi5cbiAgICAgICAgZW1pdENvdW50ZXIoJ2F1ZGl0X2Ryb3BwZWRfdG90YWwnLCB7IHNlcnZpY2U6IHNlcnZpY2VOYW1lIH0pO1xuICAgICAgICBsb2dnZXIuZXJyb3IoJ1JlbW90ZSBhdWRpdCByZWNvcmQgZmFpbGVkIHVuZXhwZWN0ZWRseScsIHsgYWN0aW9uOiBzdGFtcGVkLmFjdGlvbiwgZXJyb3I6IGVycm9yTWVzc2FnZShlcnIpIH0pO1xuICAgICAgfSk7XG4gICAgfSxcbiAgICBjbG9zZSgpIHtcbiAgICAgIGlmIChkcmFpblRpbWVyKSB7IGNsZWFySW50ZXJ2YWwoZHJhaW5UaW1lcik7IGRyYWluVGltZXIgPSB1bmRlZmluZWQ7IH1cbiAgICB9LFxuICB9O1xufVxuXG4vKipcbiAqIFJlZ2lzdGVyIHRoZSBzdGFuZGFyZCBgYXV0aHouZGVuaWVkYCBzaW5rIHVzZWQgYnkgZXZlcnkgcmVtb3RlLWF1ZGl0IHNlcnZpY2VcbiAqIChwaXBlbGluZSwgcGx1Z2luLCBjb21wbGlhbmNlLCBxdW90YSwgbWVzc2FnZSwgYmlsbGluZywgcmVwb3J0aW5nLCDigKYpLlxuICpcbiAqIFRoZSBzaGFyZWQgYHJlcXVpcmVBdXRoYCBnYXRlIGZvcndhcmRzIGVhY2ggREVOSUVEIHN0YXRlLWNoYW5naW5nIHJlcXVlc3QgdG9cbiAqIHRoZSBhdWRpdG9yIHNldCB2aWEge0BsaW5rIHNldEF1dGh6RGVuaWFsQXVkaXRvcn07IHRoaXMgd2lyZXMgdGhhdCBob29rIHRvIHRoZVxuICogc2VydmljZSdzIHtAbGluayBSZW1vdGVBdWRpdENsaWVudH0sIGZvcndhcmRpbmcgYSBgZmFpbHVyZWAtb3V0Y29tZVxuICogYGF1dGh6LmRlbmllZGAgZXZlbnQgc28gcHJvYmluZyAvIHByaXZpbGVnZS1lc2NhbGF0aW9uIGF0dGVtcHRzIGxlYXZlIGEgdHJhaWwuXG4gKiBFbWlzc2lvbiBpcyBmaXJlLWFuZC1mb3JnZXQgKHRoZSBjbGllbnQgbmV2ZXIgdGhyb3dzKS4gYGdldENsaWVudGAgaXMgYSBnZXR0ZXJcbiAqIHNvIHRoZSBjbGllbnQgc3RheXMgbGF6aWx5IGNvbnN0cnVjdGVkIChzZXJ2aWNlcyBtZW1vaXplIGl0IG9uIGZpcnN0IHVzZSkuXG4gKlxuICogUGxhdGZvcm0gaXMgaW50ZW50aW9uYWxseSBOT1QgYSBjYWxsZXIg4oCUIGl0IGlzIHRoZSBhdWRpdCBhdXRob3JpdHkgYW5kIHdyaXRlc1xuICogYGF1dGh6LmRlbmllZGAgc3RyYWlnaHQgdG8gaXRzIGxvY2FsIHN0b3JlICh3aXRoIGBhZmZlY3RlZE9yZ0lkYCksIG5vdCB0aHJvdWdoXG4gKiBhIFJlbW90ZUF1ZGl0Q2xpZW50LlxuICovXG5leHBvcnQgZnVuY3Rpb24gd2lyZUF1dGh6RGVuaWFsQXVkaXRvcihzZXJ2aWNlTmFtZTogc3RyaW5nLCBnZXRDbGllbnQ6ICgpID0+IFJlbW90ZUF1ZGl0Q2xpZW50KTogdm9pZCB7XG4gIC8vIFJlcXVlc3QgY29udGV4dCAoaXAgLyB1c2VyIGFnZW50IC8gcmVxdWVzdCBpZCAvIGNyZWRlbnRpYWwgLyBpbXBlcnNvbmF0b3IpXG4gIC8vIGlzIHN0YW1wZWQgYnkgYHJlY29yZCgpYCBmcm9tIHRoZSBhbWJpZW50IGF1ZGl0IGNvbnRleHQg4oCUIHRoZSBkZW5pYWwgZmlyZXNcbiAgLy8gaW5zaWRlIHRoZSByZXF1ZXN0J3Mgc2NvcGUuIEFuIHVuYXV0aGVudGljYXRlZCBkZW5pYWwgaGFzIG5vIG9yZzogaXQgaXNcbiAgLy8gcmVjb3JkZWQgb24gdGhlIHN5c3RlbSBvcmcncyBjaGFpbiByYXRoZXIgdGhhbiByZWZ1c2VkIGZvciBsYWNraW5nIG9uZS5cbiAgc2V0QXV0aHpEZW5pYWxBdWRpdG9yKChpbmZvOiBBdXRoekRlbmlhbEluZm8pID0+IGdldENsaWVudCgpLnJlY29yZCh7XG4gICAgYWN0aW9uOiAnYXV0aHouZGVuaWVkJyxcbiAgICBhY3RvcklkOiBpbmZvLmFjdG9ySWQgPz8gJ2Fub255bW91cycsXG4gICAgYWN0b3JFbWFpbDogaW5mby5hY3RvckVtYWlsLFxuICAgIG9yZ0lkOiBpbmZvLm9yZ0lkID8/IFNZU1RFTV9PUkdfSUQsXG4gICAgb3V0Y29tZTogJ2ZhaWx1cmUnLFxuICAgIGRldGFpbHM6IHsgbWV0aG9kOiBpbmZvLm1ldGhvZCwgcGF0aDogaW5mby5wYXRoLCByZXF1aXJlZDogaW5mby5yZXF1aXJlZCB9LFxuICB9LCBzZXJ2aWNlTmFtZSkpO1xufVxuXG4vKipcbiAqIFRoZSBwcm9jZXNzLXdpZGUgcmVtb3RlLWF1ZGl0IGJpbmRpbmc6IHdoaWNoIHNlcnZpY2UgdGhpcyBwcm9jZXNzIGlzLCBhbmQgdGhlXG4gKiAobGF6aWx5IGJ1aWx0KSBjbGllbnQgaXRzIGV2ZW50cyBnbyB0aHJvdWdoLiBCb3VuZCBPTkNFIGF0IGJvb3QgYnlcbiAqIGB3aXJlU2VydmljZVNlY3VyaXR5KHNlcnZpY2VOYW1lKWAg4oCUIGV2ZXJ5IHN0YXRlbGVzcyBzZXJ2aWNlIGNhbGxzIGl0IOKAlCBzbyB0aGVcbiAqIHNlcnZpY2UgaWRlbnRpdHkgaXMgbmV2ZXIgcmVwZWF0ZWQgYXQgYSBjYWxsIHNpdGUgYW5kIGNhbiBuZXZlciBkcmlmdC5cbiAqL1xuaW50ZXJmYWNlIEF1ZGl0QmluZGluZyB7XG4gIHNlcnZpY2VOYW1lOiBzdHJpbmc7XG4gIGNsaWVudDogUmVtb3RlQXVkaXRDbGllbnQgfCBudWxsO1xufVxuXG5sZXQgYXVkaXRCaW5kaW5nOiBBdWRpdEJpbmRpbmcgfCBudWxsID0gbnVsbDtcblxuLyoqXG4gKiBCaW5kIHRoaXMgcHJvY2VzcydzIHNlcnZpY2UgaWRlbnRpdHkgZm9yIHtAbGluayByZWNvcmRBdWRpdH0uIENhbGxlZCBieVxuICogYHdpcmVTZXJ2aWNlU2VjdXJpdHlgOyB0ZXN0cyBnbyB0aHJvdWdoIGBiaW5kVGVzdEF1ZGl0U2VydmljZWBcbiAqIChgQHBpcGVsaW5lLWJ1aWxkZXIvYXBpLWNvcmUvdGVzdGluZ2ApLCB3aGljaCBwYXNzZXMgYSBzcHkgYGNsaWVudGAuXG4gKlxuICogV2l0aG91dCBgY2xpZW50YCwgdGhlIHJlYWwgb25lIGlzIGJ1aWx0IGxhemlseSBvbiBmaXJzdCBlbWlzc2lvbjogYVxuICogUmVtb3RlQXVkaXRDbGllbnQgd2lyZWQgdG8gdGhlIGR1cmFibGUgZW52LVJlZGlzIHNwb29sIChudWxsIOKGkiBubyBzcG9vbCkuXG4gKiBMYXp5IG9uIHB1cnBvc2Ug4oCUIGJ1aWxkaW5nIGl0IGF0IGJvb3Qgd291bGQgZm9yY2UgdGhlIHNwb29sJ3MgUmVkaXMgY29ubmVjdGlvblxuICogd2hlcmV2ZXIgdGhlIHNlcnZpY2UgbW9kdWxlIGlzIG1lcmVseSBpbXBvcnRlZC4gUmViaW5kaW5nIGNsb3NlcyB0aGUgcHJldmlvdXNcbiAqIGNsaWVudCdzIHNwb29sLWRyYWluIHRpbWVyLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYmluZEF1ZGl0U2VydmljZShzZXJ2aWNlTmFtZTogc3RyaW5nLCBjbGllbnQ/OiBSZW1vdGVBdWRpdENsaWVudCk6IHZvaWQge1xuICBhdWRpdEJpbmRpbmc/LmNsaWVudD8uY2xvc2UoKTtcbiAgYXVkaXRCaW5kaW5nID0geyBzZXJ2aWNlTmFtZSwgY2xpZW50OiBjbGllbnQgPz8gbnVsbCB9O1xufVxuXG4vKiogRHJvcCB0aGUgYmluZGluZyAodGVzdHMgb25seSDigJQgcmV0dXJucyB0aGUgcHJvY2VzcyB0byB0aGUgdW5ib3VuZCBzdGF0ZSkuICovXG5leHBvcnQgZnVuY3Rpb24gdW5iaW5kQXVkaXRTZXJ2aWNlKCk6IHZvaWQge1xuICBhdWRpdEJpbmRpbmc/LmNsaWVudD8uY2xvc2UoKTtcbiAgYXVkaXRCaW5kaW5nID0gbnVsbDtcbn1cblxuZnVuY3Rpb24gYm91bmRBdWRpdCgpOiBBdWRpdEJpbmRpbmcgJiB7IGNsaWVudDogUmVtb3RlQXVkaXRDbGllbnQgfSB7XG4gIGlmICghYXVkaXRCaW5kaW5nKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdhdWRpdCBub3QgaW5pdGlhbGlzZWQ6IGNhbGwgd2lyZVNlcnZpY2VTZWN1cml0eShzZXJ2aWNlTmFtZSkgYXQgYm9vdCBiZWZvcmUgcmVjb3JkQXVkaXQoKScpO1xuICB9XG4gIGF1ZGl0QmluZGluZy5jbGllbnQgPz89IGNyZWF0ZVJlbW90ZUF1ZGl0Q2xpZW50KHtcbiAgICBzcG9vbDogY3JlYXRlRW52UmVkaXNBdWRpdFNwb29sKHsga2V5OiBhdWRpdFNwb29sS2V5KGF1ZGl0QmluZGluZy5zZXJ2aWNlTmFtZSkgfSkgPz8gdW5kZWZpbmVkLFxuICB9KTtcbiAgcmV0dXJuIGF1ZGl0QmluZGluZyBhcyBBdWRpdEJpbmRpbmcgJiB7IGNsaWVudDogUmVtb3RlQXVkaXRDbGllbnQgfTtcbn1cblxuLyoqXG4gKiBUaGUgYm91bmQgc2VydmljZSdzIFJlbW90ZUF1ZGl0Q2xpZW50LiBUaHJvd3MgXCJhdWRpdCBub3QgaW5pdGlhbGlzZWRcIiBiZWZvcmVcbiAqIGB3aXJlU2VydmljZVNlY3VyaXR5YCBoYXMgcnVuLiBJbnRlcm5hbDogY2FsbGVycyBlbWl0IHRocm91Z2hcbiAqIHtAbGluayByZWNvcmRBdWRpdH07IGB3aXJlU2VydmljZVNlY3VyaXR5YCBoYW5kcyB0aGlzIGdldHRlciB0byB0aGVcbiAqIGBhdXRoei5kZW5pZWRgIHNpbmsuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRCb3VuZEF1ZGl0Q2xpZW50KCk6IFJlbW90ZUF1ZGl0Q2xpZW50IHtcbiAgcmV0dXJuIGJvdW5kQXVkaXQoKS5jbGllbnQ7XG59XG5cbi8qKlxuICogUmVjb3JkIGFuIGV2ZW50IGluIHRoZSBkdXJhYmxlLCBoYXNoLWNoYWluZWQgY2VudHJhbCBhdWRpdCB0cmFpbCAocGxhdGZvcm0nc1xuICogYFBPU1QgL2F1ZGl0L2V2ZW50c2AgaW5nZXN0KSwgYXR0cmlidXRlZCB0byB0aGUgc2VydmljZSBib3VuZCBhdCBib290LlxuICpcbiAqIEZJUkUtQU5ELUZPUkdFVDogZGVsaXZlcnkgbmV2ZXIgYmxvY2tzIG9yIHRocm93cyDigJQgZW1pdCBvbmx5IEFGVEVSIHRoZVxuICogbXV0YXRpb24gc3VjY2VlZHMsIGFuZCBrZWVwIGBkZXRhaWxzYCBmcmVlIG9mIHNlY3JldHMvdG9rZW5zLCBQSUkgYW5kIEFXU1xuICogYWNjb3VudCBpZHMuIFRoZSBPTkUgdGhpbmcgdGhhdCB0aHJvd3MgaXMgY2FsbGluZyBpdCBiZWZvcmVcbiAqIGB3aXJlU2VydmljZVNlY3VyaXR5KHNlcnZpY2VOYW1lKWAgaGFzIGJvdW5kIHRoZSBzZXJ2aWNlOiB0aGF0IGlzIGEgd2lyaW5nXG4gKiBidWcsIGFuZCBmYWlsaW5nIGxvdWRseSBiZWF0cyBzaWxlbnRseSBhdHRyaWJ1dGluZyB0aGUgZXZlbnQgdG8gbm9ib2R5LlxuICpcbiAqIChUaGUgd2luc3Rvbi9Mb2tpIGxvZyBsaW5lIGlzIGEgZGlmZmVyZW50IHNpbms6IGBsb2dBdWRpdEV2ZW50YC4pXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWNvcmRBdWRpdChldmVudDogUmVtb3RlQXVkaXRFdmVudCk6IHZvaWQge1xuICBjb25zdCB7IGNsaWVudCwgc2VydmljZU5hbWUgfSA9IGJvdW5kQXVkaXQoKTtcbiAgY2xpZW50LnJlY29yZChldmVudCwgc2VydmljZU5hbWUpO1xufVxuIl19
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* THE vulnerability assessment of one resolved plugin version, for one org (and,
|
|
3
|
+
* optionally, one pipeline's risk acceptance). One function, three callers:
|
|
4
|
+
* `/plugins/lookup` (what synth pins), `/plugins/runtime-check` (what a running
|
|
5
|
+
* pipeline is about to execute) and the pipeline service's save-time contract
|
|
6
|
+
* check. Three copies of these rules drifted once already.
|
|
7
|
+
*
|
|
8
|
+
* Vulnerability state NEVER refuses a pipeline — not its save, its synth, its
|
|
9
|
+
* deploy or its run. What it produces is SEVERITY-GRADED warnings (and, from the
|
|
10
|
+
* callers, notifications to the pipeline's owners). The grades:
|
|
11
|
+
*
|
|
12
|
+
* critical — a finding on the CISA Known Exploited Vulnerabilities list
|
|
13
|
+
* error — the version is FLAGGED (gated Criticals over the platform floor),
|
|
14
|
+
* it has fixable Critical findings, or an org compliance rule on the
|
|
15
|
+
* vulnerability attributes is in BLOCK mode and fails
|
|
16
|
+
* warning — fixable High findings over the org's `warnFixableHigh`, a version
|
|
17
|
+
* never scanned, a scan older than `PLUGIN_SCAN_STALE_HOURS`, or a
|
|
18
|
+
* compliance rule in WARN mode
|
|
19
|
+
* info — what a reader may want to know but need not act on
|
|
20
|
+
*
|
|
21
|
+
* A PIPELINE's active risk acceptance (`plugin_vuln_exposure`, triaged `accepted`
|
|
22
|
+
* with a reason and an expiry) downgrades the warnings about the findings it
|
|
23
|
+
* ACCEPTED to `info` ("accepted until …") — never one about a finding that
|
|
24
|
+
* appeared since, never a KEV one unless the acceptance said `kev: true`, and
|
|
25
|
+
* never the scan-freshness or compliance warnings (neither is about a finding).
|
|
26
|
+
*/
|
|
27
|
+
import { createComplianceClient } from './compliance-client.js';
|
|
28
|
+
import { type PluginScanFinding, type PluginScanFlag } from '../types/plugin-scan.js';
|
|
29
|
+
import { type PluginImageRow } from '../utils/plugin-compliance.js';
|
|
30
|
+
/** How loud a warning is, quietest first. */
|
|
31
|
+
export declare const VULN_SEVERITIES: readonly ['info', 'warning', 'error', 'critical'];
|
|
32
|
+
export type VulnSeverity = typeof VULN_SEVERITIES[number];
|
|
33
|
+
/** The louder of two severities. */
|
|
34
|
+
export declare function maxSeverity(a: VulnSeverity, b: VulnSeverity): VulnSeverity;
|
|
35
|
+
/** Whether `s` is at least `floor`. */
|
|
36
|
+
export declare function severityAtLeast(s: VulnSeverity, floor: VulnSeverity): boolean;
|
|
37
|
+
/** `PLUGIN_SCAN_STALE_HOURS` (default 72): a scan older than this is stale. */
|
|
38
|
+
export declare function scanStaleHours(): number;
|
|
39
|
+
/** The scan-related fields of a resolved record (an org row or a listed record). */
|
|
40
|
+
export interface ScannedRecord extends PluginImageRow {
|
|
41
|
+
name: string;
|
|
42
|
+
version: string;
|
|
43
|
+
scannedAt?: Date | string | null;
|
|
44
|
+
scanSummary?: unknown;
|
|
45
|
+
scanFlaggedAt?: Date | string | null;
|
|
46
|
+
scanFlag?: unknown;
|
|
47
|
+
vulnHighFixable?: unknown;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* When the version was last scanned: the later of the build-time `scannedAt` and
|
|
51
|
+
* the nightly rescan's `scan_summary.scannedAt`. Null = never.
|
|
52
|
+
*/
|
|
53
|
+
export declare function lastScannedAt(record: Pick<ScannedRecord, 'scannedAt' | 'scanSummary'>): Date | null;
|
|
54
|
+
/** Freshness of a version's scan: `none` (no image to scan), `unscanned`, `stale` or `fresh`. */
|
|
55
|
+
export declare function scanFreshness(record: ScannedRecord, now?: Date): {
|
|
56
|
+
state: 'none' | 'unscanned' | 'stale' | 'fresh';
|
|
57
|
+
scannedAt: Date | null;
|
|
58
|
+
};
|
|
59
|
+
/** One severity-graded vulnerability warning. */
|
|
60
|
+
export type VulnWarning = {
|
|
61
|
+
code: 'VULN_KEV' | 'VULN_FLAGGED' | 'VULN_CRITICAL_FIXABLE' | 'VULN_HIGH_FIXABLE';
|
|
62
|
+
severity: VulnSeverity;
|
|
63
|
+
message: string;
|
|
64
|
+
findings: PluginScanFinding[];
|
|
65
|
+
suggestedVersion?: string;
|
|
66
|
+
/** `VULN_FLAGGED` carries the flag's counts (the shape the rescan-flag warning always had). */
|
|
67
|
+
plugin?: string;
|
|
68
|
+
version?: string;
|
|
69
|
+
/** The flag's gated count (findings at or above its `failOn`). */
|
|
70
|
+
gated?: number;
|
|
71
|
+
high?: number;
|
|
72
|
+
} | {
|
|
73
|
+
code: 'VULN_ACCEPTED';
|
|
74
|
+
severity: 'info';
|
|
75
|
+
message: string;
|
|
76
|
+
findings: string[];
|
|
77
|
+
acceptedUntil: string | null;
|
|
78
|
+
kev: boolean;
|
|
79
|
+
covers: string;
|
|
80
|
+
} | {
|
|
81
|
+
code: 'UNSCANNED';
|
|
82
|
+
severity: VulnSeverity;
|
|
83
|
+
message: string;
|
|
84
|
+
} | {
|
|
85
|
+
code: 'SCAN_STALE';
|
|
86
|
+
severity: VulnSeverity;
|
|
87
|
+
message: string;
|
|
88
|
+
scannedAt: string;
|
|
89
|
+
staleAfterHours: number;
|
|
90
|
+
} | {
|
|
91
|
+
code: 'COMPLIANCE_VULN_RULE';
|
|
92
|
+
severity: VulnSeverity;
|
|
93
|
+
message: string;
|
|
94
|
+
ruleId: string;
|
|
95
|
+
ruleName: string;
|
|
96
|
+
field: string;
|
|
97
|
+
mode: 'block' | 'warn';
|
|
98
|
+
} | {
|
|
99
|
+
code: 'COMPLIANCE_UNAVAILABLE';
|
|
100
|
+
severity: VulnSeverity;
|
|
101
|
+
message: string;
|
|
102
|
+
};
|
|
103
|
+
/** `UNSCANNED` / `SCAN_STALE` for a resolved version (empty for a fresh scan or an image-less plugin). */
|
|
104
|
+
export declare function scanWarnings(record: ScannedRecord, now?: Date): VulnWarning[];
|
|
105
|
+
/** The vulnerability fields of an org's consumption policy (pipeline-data's `ConsumptionPolicy` satisfies it). */
|
|
106
|
+
export interface VulnConsumptionPolicy {
|
|
107
|
+
/** Fixable High findings above this many raise a `warning`; null = never (they stay `info`). */
|
|
108
|
+
warnFixableHigh: number | null;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* A pipeline's ACTIVE risk acceptance of one version / image: the finding keys
|
|
112
|
+
* ({@link scanFindingKey}) it accepted, whether it accepted KEV findings, and
|
|
113
|
+
* until when. Built by pipeline-data from `plugin_vuln_exposure`.
|
|
114
|
+
*/
|
|
115
|
+
export interface VulnAcceptance {
|
|
116
|
+
findingKeys: readonly string[];
|
|
117
|
+
kev: boolean;
|
|
118
|
+
acceptedUntil: Date | string | null;
|
|
119
|
+
}
|
|
120
|
+
/** What a version's stored scan says, normalized from `scan_summary` (for its image) and `scan_flag`. */
|
|
121
|
+
export interface VersionScanFacts {
|
|
122
|
+
flagged: boolean;
|
|
123
|
+
flag: PluginScanFlag | null;
|
|
124
|
+
/** Fixable Critical / High findings (null = not known). */
|
|
125
|
+
criticalFixable: number | null;
|
|
126
|
+
highFixable: number | null;
|
|
127
|
+
/** Totals including unfixable findings (null = not known). */
|
|
128
|
+
critical: number | null;
|
|
129
|
+
high: number | null;
|
|
130
|
+
/** KEV-listed Critical + High findings. */
|
|
131
|
+
kev: number;
|
|
132
|
+
/** Every Critical/High finding the scan itemized (the summary's list, else the flag's). */
|
|
133
|
+
findings: PluginScanFinding[];
|
|
134
|
+
/** The summary cut its findings list — a subset check over it cannot be trusted. */
|
|
135
|
+
truncated: boolean;
|
|
136
|
+
scannedAt: Date | null;
|
|
137
|
+
}
|
|
138
|
+
/** The normalized scan facts of a resolved record. A summary describing another image is ignored. */
|
|
139
|
+
export declare function versionScanFacts(record: ScannedRecord): VersionScanFacts;
|
|
140
|
+
/** Input to {@link assessVersionVulns}. */
|
|
141
|
+
export interface VersionVulnInput {
|
|
142
|
+
orgId: string;
|
|
143
|
+
record: ScannedRecord;
|
|
144
|
+
policy: VulnConsumptionPolicy;
|
|
145
|
+
/** The pipeline's active acceptance of this version / image, when the caller has a pipeline. */
|
|
146
|
+
acceptance?: VulnAcceptance | null;
|
|
147
|
+
/** The newest unflagged version the owner can move to, named on the finding warnings. */
|
|
148
|
+
suggestedVersion?: string | null;
|
|
149
|
+
/** Run the org's compliance rules (a network call). Default true. */
|
|
150
|
+
compliance?: boolean;
|
|
151
|
+
now?: Date;
|
|
152
|
+
}
|
|
153
|
+
/** The assessment: every warning, the loudest severity, and which accepted findings it downgraded. */
|
|
154
|
+
export interface VersionVulnAssessment {
|
|
155
|
+
/** `null` when there is nothing to say. */
|
|
156
|
+
severity: VulnSeverity | null;
|
|
157
|
+
warnings: VulnWarning[];
|
|
158
|
+
/** Finding keys an acceptance downgraded (empty = no acceptance applied). */
|
|
159
|
+
acceptedFindings: string[];
|
|
160
|
+
facts: VersionScanFacts;
|
|
161
|
+
}
|
|
162
|
+
/** The loudest severity of `warnings`, or null for none. */
|
|
163
|
+
export declare function severityOf(warnings: ReadonlyArray<{
|
|
164
|
+
severity?: VulnSeverity;
|
|
165
|
+
}>): VulnSeverity | null;
|
|
166
|
+
/**
|
|
167
|
+
* The assessment of one resolved version (see the module doc). Never throws and
|
|
168
|
+
* never refuses: a compliance outage adds an `info` `COMPLIANCE_UNAVAILABLE`.
|
|
169
|
+
*/
|
|
170
|
+
export declare function assessVersionVulns(input: VersionVulnInput): Promise<VersionVulnAssessment>;
|
|
171
|
+
type ComplianceClient = Pick<ReturnType<typeof createComplianceClient>, 'dryRunPlugin'>;
|
|
172
|
+
/** Test hook: replace the compliance client the assessment's compliance layer calls. */
|
|
173
|
+
export declare function setVulnPolicyComplianceClientForTests(client: ComplianceClient | null): void;
|
|
174
|
+
export {};
|