@pipeline-builder/api-core 4.1.1 → 4.1.3

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.
@@ -1,12 +1,35 @@
1
+ import type { Response } from 'express';
1
2
  import type { QuotaType, QuotaCheckResult } from '../types/common.js';
2
3
  import { type QuotaTier } from '../types/quota-tiers.js';
4
+ /**
5
+ * Service-principal `Authorization` header for a quota call made on behalf of
6
+ * `orgId` by the CURRENT service (`SERVICE_NAME`, the same identity the health
7
+ * router reports).
8
+ *
9
+ * The quota service's mutation endpoints (`/:orgId/increment`, `/decrement`)
10
+ * reject anything but a signed service principal or a system admin, so
11
+ * forwarding the end user's bearer token there is always a 403. Service tokens
12
+ * are also exempt from the quota service's per-IP rate limiter, so hot-path
13
+ * quota traffic from a busy pod can't exhaust that pod IP's bucket and silently
14
+ * turn enforcement off. Scoped to the target org with the lowest role (member).
15
+ */
16
+ export declare function getQuotaServiceAuthHeader(orgId: string): string;
3
17
  /**
4
18
  * Result of a synchronous quota reservation the atomic check+increment
5
19
  * variant. `exceeded: true` means the operation was rejected at the DB
6
20
  * level; the caller should return 429 without running the gated action.
7
21
  */
8
22
  export interface QuotaReserveResult {
23
+ /** True when the slot was NOT reserved — the gated action must not run. */
9
24
  exceeded: boolean;
25
+ /**
26
+ * Set (true) by the quota CLIENT when the reservation was denied because the
27
+ * quota service could not CONFIRM it (unreachable / timeout / circuit open /
28
+ * errored) — not because the org is over its limit. Always paired with
29
+ * `exceeded: true`. Answer with {@link sendQuotaReserveDenied}, which maps it to
30
+ * 503 instead of a misleading 429 "quota exceeded".
31
+ */
32
+ unavailable?: boolean;
10
33
  quota: {
11
34
  type: QuotaType;
12
35
  limit: number;
@@ -29,9 +52,9 @@ export interface QuotaService {
29
52
  * reserved. Use this for expensive resources where the post-hoc fire-
30
53
  * and-forget pattern allows concurrent over-spend.
31
54
  *
32
- * Fail-open semantics on transport errors: returns `exceeded: false` so
33
- * the caller can proceed and the request isn't blocked by quota-service
34
- * outages (matches `check()`).
55
+ * Fails CLOSED (`exceeded: true`) whenever the slot is not confirmed —
56
+ * unreachable, timeout, open circuit, non-ok, or a non-quota 429 — unless
57
+ * `QUOTA_RESERVE_FAIL_OPEN=true` (see the policy note at the top of this file).
35
58
  */
36
59
  reserve(orgId: string, quotaType: QuotaType, authHeader: string, amount?: number, requestId?: string): Promise<QuotaReserveResult>;
37
60
  /**
@@ -88,18 +111,20 @@ export interface QuotaServiceConfig {
88
111
  */
89
112
  export declare function createQuotaService(config?: QuotaServiceConfig): QuotaService;
90
113
  /**
91
- * Fire-and-forget quota increment with standardized error logging.
114
+ * Fire-and-forget quota METERING increment with standardized error logging.
92
115
  *
93
- * Wraps `quotaService.increment()` with a `.catch()` that logs a warning.
94
- * Eliminates the identical one-liner repeated across every read route.
116
+ * Authenticates as the calling SERVICE ({@link getQuotaServiceAuthHeader}), never
117
+ * with the end user's token: `/quotas/:orgId/increment` is service-principal /
118
+ * system-admin only, so a forwarded user JWT was always rejected (403) and the
119
+ * metered quota (e.g. `apiCalls`, and the `api_pack` bundle raising it) never
120
+ * moved.
95
121
  *
96
122
  * @param quotaService - Quota service client
97
- * @param orgId - Organization ID
123
+ * @param orgId - Organization ID whose counter is incremented
98
124
  * @param quotaType - Quota type to increment
99
- * @param authHeader - Authorization header value
100
125
  * @param logWarn - Logging function for warnings
101
126
  */
102
- export declare function incrementQuota(quotaService: QuotaService, orgId: string, quotaType: QuotaType, authHeader: string, logWarn: (message: string, data?: unknown) => void): void;
127
+ export declare function incrementQuota(quotaService: QuotaService, orgId: string, quotaType: QuotaType, logWarn: (message: string, data?: unknown) => void): void;
103
128
  /**
104
129
  * Atomic reserve helper for the "reserve + commit / rollback" pattern.
105
130
  * Use for expensive resources (pipelines, plugins, AI calls) where the
@@ -111,7 +136,7 @@ export declare function incrementQuota(quotaService: QuotaService, orgId: string
111
136
  * @example
112
137
  * ```typescript
113
138
  * const reservation = await reserveQuota(quotaService, orgId, 'pipelines', authHeader);
114
- * if (reservation.exceeded) return sendQuotaExceeded(res, 'pipelines', reservation.quota);
139
+ * if (reservation.exceeded) return sendQuotaReserveDenied(res, 'pipelines', reservation);
115
140
  * try {
116
141
  * await doExpensiveThing();
117
142
  * } catch (err) {
@@ -122,6 +147,15 @@ export declare function incrementQuota(quotaService: QuotaService, orgId: string
122
147
  * ```
123
148
  */
124
149
  export declare function reserveQuota(quotaService: QuotaService, orgId: string, quotaType: QuotaType, authHeader: string, amount?: number, requestId?: string): Promise<QuotaReserveResult>;
150
+ /**
151
+ * Answer a DENIED reservation (`reservation.exceeded === true`).
152
+ *
153
+ * - `unavailable` (the quota service couldn't confirm the slot) → **503**
154
+ * `SERVICE_UNAVAILABLE` with a short `Retry-After`: the org is not over its
155
+ * limit, so a 429 "quota exceeded" would send users to upgrade for an outage.
156
+ * - otherwise → the standard 429 `QUOTA_EXCEEDED` with the X-Quota-* headers.
157
+ */
158
+ export declare function sendQuotaReserveDenied(res: Response, quotaType: QuotaType, reservation: QuotaReserveResult): void;
125
159
  /**
126
160
  * Fire-and-forget rollback for a previously reserved quota slot.
127
161
  * Logs on failure but never throws the action that needed the rollback
@@ -1,24 +1,64 @@
1
1
  // Copyright 2026 Pipeline Builder Contributors
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
  import { createSafeClient } from './http-client.js';
4
+ import { getServiceAuthHeader } from '../middleware/auth.js';
5
+ import { ErrorCode } from '../types/error-codes.js';
4
6
  import { DEFAULT_TIER, isValidTier } from '../types/quota-tiers.js';
5
7
  import { createLogger } from '../utils/logger.js';
6
8
  import { emitCounter } from '../utils/metric-emitter.js';
7
- /** Retry options for quota calls fail fast since quota is fail-open. */
9
+ import { sendError, sendQuotaExceeded } from '../utils/response.js';
10
+ /** Retry options for quota calls — fail fast (a slow quota service must not stall the request). */
8
11
  const QUOTA_REQUEST_OPTIONS = {
9
12
  maxRateLimitRetries: 1,
10
13
  maxRetries: 1,
11
14
  };
12
15
  const logger = createLogger('quota');
13
- // `reserve` gates EXPENSIVE resources (plugin builds, pipelines). When the
14
- // quota service is reachable but returns an error (often an OVERLOADED service),
15
- // failing open would pile unmetered expensive work onto it and bypass quota
16
- // entirely — the textbook fail-open blow-up. So `reserve` fails CLOSED on an
17
- // errored response by default. Operators who prefer availability over
18
- // enforcement can opt back into fail-open with QUOTA_RESERVE_FAIL_OPEN=true.
19
- // (A genuinely UNREACHABLE service still fails open — that's a confirmed outage,
20
- // not an overload signal.)
16
+ // RESERVE FAIL MODE — explicit, single policy.
17
+ //
18
+ // `reserve` gates EXPENSIVE, billable resources (pipelines, plugin builds, AI
19
+ // calls, platform feature slots). Every quota type is a per-period FLOW counter
20
+ // with no after-the-fact reconciliation: a unit consumed while the reservation
21
+ // could not be confirmed is never counted, so fail-open lets an org consume
22
+ // unbounded unmetered units for the whole length of an incident — and an
23
+ // unconfirmed reserve (timeout, open circuit) may even have landed server-side.
24
+ // So `reserve` fails CLOSED whenever the quota service did not CONFIRM the slot:
25
+ // - unreachable / timed out / circuit breaker open (no response),
26
+ // - a reachable-but-errored response (5xx, 4xx, malformed body),
27
+ // - a 429 that is NOT a genuine QUOTA_EXCEEDED (gateway / rate limiter).
28
+ // Operators who prefer availability over enforcement opt the WHOLE set into
29
+ // fail-open with QUOTA_RESERVE_FAIL_OPEN=true. Both outcomes emit a counter
30
+ // (`quota_fail_closed_total` / `quota_fail_open_total`) tagged with the reason.
31
+ // `check` (a cheap read gate) stays fail-open; `increment` is fire-and-forget.
21
32
  const QUOTA_RESERVE_FAIL_OPEN = process.env.QUOTA_RESERVE_FAIL_OPEN === 'true';
33
+ /**
34
+ * Service-principal `Authorization` header for a quota call made on behalf of
35
+ * `orgId` by the CURRENT service (`SERVICE_NAME`, the same identity the health
36
+ * router reports).
37
+ *
38
+ * The quota service's mutation endpoints (`/:orgId/increment`, `/decrement`)
39
+ * reject anything but a signed service principal or a system admin, so
40
+ * forwarding the end user's bearer token there is always a 403. Service tokens
41
+ * are also exempt from the quota service's per-IP rate limiter, so hot-path
42
+ * quota traffic from a busy pod can't exhaust that pod IP's bucket and silently
43
+ * turn enforcement off. Scoped to the target org with the lowest role (member).
44
+ */
45
+ export function getQuotaServiceAuthHeader(orgId) {
46
+ return getServiceAuthHeader({ serviceName: process.env.SERVICE_NAME || 'api', orgId, role: 'member' });
47
+ }
48
+ /**
49
+ * Apply the explicit reserve fail-mode policy to a reservation the quota service
50
+ * did NOT confirm (see QUOTA_RESERVE_FAIL_OPEN above). Default: deny.
51
+ */
52
+ function unconfirmedReserve(orgId, quotaType, reason, statusCode) {
53
+ if (QUOTA_RESERVE_FAIL_OPEN) {
54
+ logger.warn('QUOTA_FAIL_OPEN: quota reserve not confirmed, allowing request', { orgId, quotaType, reason, statusCode });
55
+ emitCounter('quota_fail_open_total', { operation: 'reserve', reason, quotaType });
56
+ return { exceeded: false, quota: { type: quotaType, limit: -1, used: 0, remaining: -1 } };
57
+ }
58
+ logger.warn('QUOTA_FAIL_CLOSED: quota reserve not confirmed, denying request', { orgId, quotaType, reason, statusCode });
59
+ emitCounter('quota_fail_closed_total', { operation: 'reserve', reason, quotaType });
60
+ return { exceeded: true, unavailable: true, quota: { type: quotaType, limit: 0, used: 0, remaining: 0 } };
61
+ }
22
62
  /**
23
63
  * Create a fail-open quota result (allows the request).
24
64
  */
@@ -109,48 +149,23 @@ export function createQuotaService(config = {}) {
109
149
  // 200 carries `data.quota`; 429 (QUOTA_EXCEEDED) carries `details.quota`.
110
150
  // Both shapes are normalized into QuotaReserveResult.
111
151
  const response = await client.post(path, { quotaType, amount }, { headers: buildHeaders(orgId, authHeader, requestId), ...QUOTA_REQUEST_OPTIONS });
112
- if (!response) {
113
- logger.warn('QUOTA_FAIL_OPEN: Quota service unreachable on reserve, allowing request', { orgId, quotaType });
114
- emitCounter('quota_fail_open_total', { operation: 'reserve', reason: 'unreachable', quotaType });
115
- return { exceeded: false, quota: { type: quotaType, limit: -1, used: 0, remaining: -1 } };
116
- }
152
+ if (!response)
153
+ return unconfirmedReserve(orgId, quotaType, 'unreachable');
117
154
  if (response.statusCode === 429) {
118
155
  const q = response.body.details?.quota;
119
156
  // Only a GENUINE quota-exceeded 429 means "over quota". A generic 429 —
120
- // the quota service's OWN rate limiter (RATE_LIMIT_EXCEEDED) or an
121
- // intervening gateway during a spike — must NOT be surfaced as
122
- // quota-exceeded: that would falsely block legitimate work behind a
123
- // transient rate limit. Require the QUOTA_EXCEEDED error code (or the
124
- // quota payload) and otherwise fall through to the non-ok
125
- // fail-open/closed policy below (the right handling for a transient 429).
157
+ // an intervening gateway or rate limiter — did not confirm anything, so
158
+ // it goes through the same unconfirmed-reservation policy as an outage.
126
159
  if (response.body.errorCode === 'QUOTA_EXCEEDED' || q) {
127
160
  return {
128
161
  exceeded: true,
129
162
  quota: q ?? { type: quotaType, limit: 0, used: 0, remaining: 0 },
130
163
  };
131
164
  }
132
- // A non-QUOTA_EXCEEDED 429 is a TRANSIENT signal (the quota service's own
133
- // rate limiter, or a gateway during a spike) — the tenant is NOT over quota,
134
- // so fail OPEN (as for an unreachable service) rather than falsely blocking
135
- // legitimate work. Do not fall through to the fail-closed non-ok default.
136
- logger.warn('QUOTA_FAIL_OPEN: transient 429 on reserve (not quota-exceeded), allowing request', { orgId, quotaType });
137
- emitCounter('quota_fail_open_total', { operation: 'reserve', reason: 'transient-429', quotaType });
138
- return { exceeded: false, quota: { type: quotaType, limit: -1, used: 0, remaining: -1 } };
165
+ return unconfirmedReserve(orgId, quotaType, 'transient-429', response.statusCode);
139
166
  }
140
167
  if (response.statusCode !== 200 || !response.body.success) {
141
- if (QUOTA_RESERVE_FAIL_OPEN) {
142
- logger.warn('QUOTA_FAIL_OPEN: Quota reserve returned non-ok, allowing request', {
143
- orgId, quotaType, statusCode: response.statusCode,
144
- });
145
- emitCounter('quota_fail_open_total', { operation: 'reserve', reason: 'non-ok', quotaType });
146
- return { exceeded: false, quota: { type: quotaType, limit: -1, used: 0, remaining: -1 } };
147
- }
148
- // Service reachable but didn't confirm the reservation → fail CLOSED.
149
- logger.warn('QUOTA_FAIL_CLOSED: Quota reserve returned non-ok, denying request', {
150
- orgId, quotaType, statusCode: response.statusCode,
151
- });
152
- emitCounter('quota_fail_closed_total', { operation: 'reserve', reason: 'non-ok', quotaType });
153
- return { exceeded: true, quota: { type: quotaType, limit: 0, used: 0, remaining: 0 } };
168
+ return unconfirmedReserve(orgId, quotaType, 'non-ok', response.statusCode);
154
169
  }
155
170
  const q = response.body.data?.quota;
156
171
  return {
@@ -215,19 +230,21 @@ export function createQuotaService(config = {}) {
215
230
  };
216
231
  }
217
232
  /**
218
- * Fire-and-forget quota increment with standardized error logging.
233
+ * Fire-and-forget quota METERING increment with standardized error logging.
219
234
  *
220
- * Wraps `quotaService.increment()` with a `.catch()` that logs a warning.
221
- * Eliminates the identical one-liner repeated across every read route.
235
+ * Authenticates as the calling SERVICE ({@link getQuotaServiceAuthHeader}), never
236
+ * with the end user's token: `/quotas/:orgId/increment` is service-principal /
237
+ * system-admin only, so a forwarded user JWT was always rejected (403) and the
238
+ * metered quota (e.g. `apiCalls`, and the `api_pack` bundle raising it) never
239
+ * moved.
222
240
  *
223
241
  * @param quotaService - Quota service client
224
- * @param orgId - Organization ID
242
+ * @param orgId - Organization ID whose counter is incremented
225
243
  * @param quotaType - Quota type to increment
226
- * @param authHeader - Authorization header value
227
244
  * @param logWarn - Logging function for warnings
228
245
  */
229
- export function incrementQuota(quotaService, orgId, quotaType, authHeader, logWarn) {
230
- quotaService.increment(orgId, quotaType, authHeader).catch((err) => logWarn('Quota increment failed', { error: err instanceof Error ? err.message : String(err) }));
246
+ export function incrementQuota(quotaService, orgId, quotaType, logWarn) {
247
+ quotaService.increment(orgId, quotaType, getQuotaServiceAuthHeader(orgId)).catch((err) => logWarn('Quota increment failed', { error: err instanceof Error ? err.message : String(err) }));
231
248
  }
232
249
  /**
233
250
  * Atomic reserve helper for the "reserve + commit / rollback" pattern.
@@ -240,7 +257,7 @@ export function incrementQuota(quotaService, orgId, quotaType, authHeader, logWa
240
257
  * @example
241
258
  * ```typescript
242
259
  * const reservation = await reserveQuota(quotaService, orgId, 'pipelines', authHeader);
243
- * if (reservation.exceeded) return sendQuotaExceeded(res, 'pipelines', reservation.quota);
260
+ * if (reservation.exceeded) return sendQuotaReserveDenied(res, 'pipelines', reservation);
244
261
  * try {
245
262
  * await doExpensiveThing();
246
263
  * } catch (err) {
@@ -253,6 +270,25 @@ export function incrementQuota(quotaService, orgId, quotaType, authHeader, logWa
253
270
  export function reserveQuota(quotaService, orgId, quotaType, authHeader, amount = 1, requestId) {
254
271
  return quotaService.reserve(orgId, quotaType, authHeader, amount, requestId);
255
272
  }
273
+ /** Seconds a client should wait before retrying when quota couldn't be confirmed. */
274
+ const QUOTA_UNAVAILABLE_RETRY_AFTER_SECONDS = 5;
275
+ /**
276
+ * Answer a DENIED reservation (`reservation.exceeded === true`).
277
+ *
278
+ * - `unavailable` (the quota service couldn't confirm the slot) → **503**
279
+ * `SERVICE_UNAVAILABLE` with a short `Retry-After`: the org is not over its
280
+ * limit, so a 429 "quota exceeded" would send users to upgrade for an outage.
281
+ * - otherwise → the standard 429 `QUOTA_EXCEEDED` with the X-Quota-* headers.
282
+ */
283
+ export function sendQuotaReserveDenied(res, quotaType, reservation) {
284
+ if (reservation.unavailable) {
285
+ if (!res.headersSent)
286
+ res.setHeader('Retry-After', QUOTA_UNAVAILABLE_RETRY_AFTER_SECONDS);
287
+ sendError(res, 503, `Unable to confirm ${quotaType} quota right now. Please try again shortly.`, ErrorCode.SERVICE_UNAVAILABLE);
288
+ return;
289
+ }
290
+ sendQuotaExceeded(res, quotaType, reservation.quota, reservation.quota.resetAt);
291
+ }
256
292
  /**
257
293
  * Fire-and-forget rollback for a previously reserved quota slot.
258
294
  * Logs on failure but never throws the action that needed the rollback
@@ -261,4 +297,4 @@ export function reserveQuota(quotaService, orgId, quotaType, authHeader, amount
261
297
  export function decrementQuota(quotaService, orgId, quotaType, authHeader, logWarn, amount = 1, resetAtSnapshot) {
262
298
  quotaService.decrement(orgId, quotaType, authHeader, amount, resetAtSnapshot).catch((err) => logWarn('Quota rollback failed', { error: err instanceof Error ? err.message : String(err) }));
263
299
  }
264
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicXVvdGEuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2VydmljZXMvcXVvdGEudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLHNDQUFzQztBQUV0QyxPQUFPLEVBQUUsZ0JBQWdCLEVBQXVCLE1BQU0sa0JBQWtCLENBQUM7QUFFekUsT0FBTyxFQUFFLFlBQVksRUFBRSxXQUFXLEVBQWtCLE1BQU0seUJBQXlCLENBQUM7QUFDcEYsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ2xELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUV6RCx5RUFBeUU7QUFDekUsTUFBTSxxQkFBcUIsR0FBK0Q7SUFDeEYsbUJBQW1CLEVBQUUsQ0FBQztJQUN0QixVQUFVLEVBQUUsQ0FBQztDQUNkLENBQUM7QUFFRixNQUFNLE1BQU0sR0FBRyxZQUFZLENBQUMsT0FBTyxDQUFDLENBQUM7QUFFckMsMkVBQTJFO0FBQzNFLGlGQUFpRjtBQUNqRiw0RUFBNEU7QUFDNUUsNkVBQTZFO0FBQzdFLHNFQUFzRTtBQUN0RSw2RUFBNkU7QUFDN0UsaUZBQWlGO0FBQ2pGLDJCQUEyQjtBQUMzQixNQUFNLHVCQUF1QixHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsdUJBQXVCLEtBQUssTUFBTSxDQUFDO0FBdUUvRTs7R0FFRztBQUNILFNBQVMsb0JBQW9CO0lBQzNCLE9BQU87UUFDTCxPQUFPLEVBQUUsSUFBSTtRQUNiLEtBQUssRUFBRSxDQUFDLENBQUM7UUFDVCxJQUFJLEVBQUUsQ0FBQztRQUNQLFNBQVMsRUFBRSxDQUFDLENBQUM7UUFDYixPQUFPLEVBQUUsSUFBSSxJQUFJLEVBQUUsQ0FBQyxXQUFXLEVBQUU7UUFDakMsU0FBUyxFQUFFLElBQUk7UUFDZiwwRUFBMEU7UUFDMUUsa0VBQWtFO1FBQ2xFLFFBQVEsRUFBRSxJQUFJO0tBQ2YsQ0FBQztBQUNKLENBQUM7QUFFRDs7R0FF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bEIsT0FBTyxZQUFZLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxTQUFTLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxTQUFTLENBQUMsQ0FBQztBQUMvRSxDQUFDO0FBRUQ7Ozs7R0FJRztBQUNILE1BQU0sVUFBVSxjQUFjLENBQUUsWUFBMEIsRUFDeEQsS0FBYSxFQUNiLFNBQW9CLEVBQ3BCLFVBQWtCLEVBQ2xCLE9BQWtELEVBQ2xELE1BQU0sR0FBVyxDQUFDLEVBQ2xCLGVBQXdCO0lBRXhCLFlBQVksQ0FBQyxTQUFTLENBQUMsS0FBSyxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLGVBQWUsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQVksRUFBRSxFQUFFLENBQ25HLE9BQU8sQ0FBQyx1QkFBdUIsRUFBRSxFQUFFLEtBQUssRUFBRSxHQUFHLFlBQVksS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFBLENBQUMsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUM3RixDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDI2IFBpcGVsaW5lIEJ1aWxkZXIgQ29udHJpYnV0b3JzXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuXG5pbXBvcnQgeyBjcmVhdGVTYWZlQ2xpZW50LCB0eXBlIFJlcXVlc3RPcHRpb25zIH0gZnJvbSAnLi9odHRwLWNsaWVudC5qcyc7XG5pbXBvcnQgdHlwZSB7IFF1b3RhVHlwZSwgUXVvdGFDaGVja1Jlc3VsdCwgU2VydmljZUNvbmZpZyB9IGZyb20gJy4uL3R5cGVzL2NvbW1vbi5qcyc7XG5pbXBvcnQgeyBERUZBVUxUX1RJRVIsIGlzVmFsaWRUaWVyLCB0eXBlIFF1b3RhVGllciB9IGZyb20gJy4uL3R5cGVzL3F1b3RhLXRpZXJzLmpzJztcbmltcG9ydCB7IGNyZWF0ZUxvZ2dlciB9IGZyb20gJy4uL3V0aWxzL2xvZ2dlci5qcyc7XG5pbXBvcnQgeyBlbWl0Q291bnRlciB9IGZyb20gJy4uL3V0aWxzL21ldHJpYy1lbWl0dGVyLmpzJztcblxuLyoqIFJldHJ5IG9wdGlvbnMgZm9yIHF1b3RhIGNhbGxzICBmYWlsIGZhc3Qgc2luY2UgcXVvdGEgaXMgZmFpbC1vcGVuLiAqL1xuY29uc3QgUVVPVEFfUkVRVUVTVF9PUFRJT05TOiBQaWNrPFJlcXVlc3RPcHRpb25zLCAnbWF4UmF0ZUxpbWl0UmV0cmllcycgfCAnbWF4UmV0cmllcyc+ID0ge1xuICBtYXhSYXRlTGltaXRSZXRyaWVzOiAxLFxuICBtYXhSZXRyaWVzOiAxLFxufTtcblxuY29uc3QgbG9nZ2VyID0gY3JlYXRlTG9nZ2VyKCdxdW90YScpO1xuXG4vLyBgcmVzZXJ2ZWAgZ2F0ZXMgRVhQRU5TSVZFIHJlc291cmNlcyAocGx1Z2luIGJ1aWxkcywgcGlwZWxpbmVzKS4gV2hlbiB0aGVcbi8vIHF1b3RhIHNlcnZpY2UgaXMgcmVhY2hhYmxlIGJ1dCByZXR1cm5zIGFuIGVycm9yIChvZnRlbiBhbiBPVkVSTE9BREVEIHNlcnZpY2UpLFxuLy8gZmFpbGluZyBvcGVuIHdvdWxkIHBpbGUgdW5tZXRlcmVkIGV4cGVuc2l2ZSB3b3JrIG9udG8gaXQgYW5kIGJ5cGFzcyBxdW90YVxuLy8gZW50aXJlbHkg4oCUIHRoZSB0ZXh0Ym9vayBmYWlsLW9wZW4gYmxvdy11cC4gU28gYHJlc2VydmVgIGZhaWxzIENMT1NFRCBvbiBhblxuLy8gZXJyb3JlZCByZXNwb25zZSBieSBkZWZhdWx0LiBPcGVyYXRvcnMgd2hvIHByZWZlciBhdmFpbGFiaWxpdHkgb3ZlclxuLy8gZW5mb3JjZW1lbnQgY2FuIG9wdCBiYWNrIGludG8gZmFpbC1vcGVuIHdpdGggUVVPVEFfUkVTRVJWRV9GQUlMX09QRU49dHJ1ZS5cbi8vIChBIGdlbnVpbmVseSBVTlJFQUNIQUJMRSBzZXJ2aWNlIHN0aWxsIGZhaWxzIG9wZW4g4oCUIHRoYXQncyBhIGNvbmZpcm1lZCBvdXRhZ2UsXG4vLyBub3QgYW4gb3ZlcmxvYWQgc2lnbmFsLilcbmNvbnN0IFFVT1RBX1JFU0VSVkVfRkFJTF9PUEVOID0gcHJvY2Vzcy5lbnYuUVVPVEFfUkVTRVJWRV9GQUlMX09QRU4gPT09ICd0cnVlJztcblxuLyoqXG4gKiBSZXN1bHQgb2YgYSBzeW5jaHJvbm91cyBxdW90YSByZXNlcnZhdGlvbiAgdGhlIGF0b21pYyBjaGVjaytpbmNyZW1lbnRcbiAqIHZhcmlhbnQuIGBleGNlZWRlZDogdHJ1ZWAgbWVhbnMgdGhlIG9wZXJhdGlvbiB3YXMgcmVqZWN0ZWQgYXQgdGhlIERCXG4gKiBsZXZlbDsgdGhlIGNhbGxlciBzaG91bGQgcmV0dXJuIDQyOSB3aXRob3V0IHJ1bm5pbmcgdGhlIGdhdGVkIGFjdGlvbi5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBRdW90YVJlc2VydmVSZXN1bHQge1xuICBleGNlZWRlZDogYm9vbGVhbjtcbiAgcXVvdGE6IHtcbiAgICB0eXBlOiBRdW90YVR5cGU7XG4gICAgbGltaXQ6IG51bWJlcjtcbiAgICB1c2VkOiBudW1iZXI7XG4gICAgcmVtYWluaW5nOiBudW1iZXI7XG4gICAgcmVzZXRBdD86IHN0cmluZztcbiAgfTtcbn1cblxuLyoqXG4gKiBRdW90YSBzZXJ2aWNlIGNsaWVudCBpbnRlcmZhY2UuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUXVvdGFTZXJ2aWNlIHtcbiAgLyoqIENoZWNrIGlmIHF1b3RhIGlzIGF2YWlsYWJsZSAoZmFpbC1vcGVuIG9uIGVycm9yKS4gKi9cbiAgY2hlY2sob3JnSWQ6IHN0cmluZywgcXVvdGFUeXBlOiBRdW90YVR5cGUsIGF1dGhIZWFkZXI6IHN0cmluZywgcmVxdWVzdElkPzogc3RyaW5nKTogUHJvbWlzZTxRdW90YUNoZWNrUmVzdWx0PjtcbiAgLyoqIEluY3JlbWVudCBxdW90YSB1c2FnZS4gUmV0dXJucyBhIHByb21pc2Ugc28gY2FsbGVycyBjYW4gb3B0aW9uYWxseSBoYW5kbGUgZXJyb3JzLiAqL1xuICBpbmNyZW1lbnQob3JnSWQ6IHN0cmluZywgcXVvdGFUeXBlOiBRdW90YVR5cGUsIGF1dGhIZWFkZXI6IHN0cmluZywgYW1vdW50PzogbnVtYmVyLCByZXF1ZXN0SWQ/OiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+O1xuICAvKipcbiAgICogQXRvbWljIHJlc2VydmUgIHRoZSBzYW1lIGF0b21pYyBjaGVjaytpbmNyZW1lbnQgYXMgYGluY3JlbWVudGAsIGJ1dFxuICAgKiBwYXJzZXMgdGhlIHJlc3BvbnNlIHNvIGNhbGxlcnMgY2FuIHNlZSB3aGV0aGVyIHRoZSBzbG90IHdhcyBhY3R1YWxseVxuICAgKiByZXNlcnZlZC4gVXNlIHRoaXMgZm9yIGV4cGVuc2l2ZSByZXNvdXJjZXMgd2hlcmUgdGhlIHBvc3QtaG9jIGZpcmUtXG4gICAqIGFuZC1mb3JnZXQgcGF0dGVybiBhbGxvd3MgY29uY3VycmVudCBvdmVyLXNwZW5kLlxuICAgKlxuICAgKiBGYWlsLW9wZW4gc2VtYW50aWNzIG9uIHRyYW5zcG9ydCBlcnJvcnM6IHJldHVybnMgYGV4Y2VlZGVkOiBmYWxzZWAgc29cbiAgICogdGhlIGNhbGxlciBjYW4gcHJvY2VlZCBhbmQgdGhlIHJlcXVlc3QgaXNuJ3QgYmxvY2tlZCBieSBxdW90YS1zZXJ2aWNlXG4gICAqIG91dGFnZXMgKG1hdGNoZXMgYGNoZWNrKClgKS5cbiAgICovXG4gIHJlc2VydmUob3JnSWQ6IHN0cmluZywgcXVvdGFUeXBlOiBRdW90YVR5cGUsIGF1dGhIZWFkZXI6IHN0cmluZywgYW1vdW50PzogbnVtYmVyLCByZXF1ZXN0SWQ/OiBzdHJpbmcpOiBQcm9taXNlPFF1b3RhUmVzZXJ2ZVJlc3VsdD47XG4gIC8qKlxuICAgKiBSb2xsIGJhY2sgYSBwcmV2aW91c2x5IHJlc2VydmVkIHNsb3QuIEZpcmUtYW5kLWZvcmdldCDigJQgbmV2ZXIgdGhyb3dzLlxuICAgKiBQYXNzIGByZXNldEF0U25hcHNob3RgICh0aGUgYHF1b3RhLnJlc2V0QXRgIG9ic2VydmVkIHdoZW4gdGhlIHNsb3Qgd2FzXG4gICAqIHJlc2VydmVkKSB0byBtYWtlIHRoZSByb2xsYmFjayBjb25kaXRpb25hbDogaWYgdGhlIHBlcmlvZCByb2xsZWQgb3ZlclxuICAgKiBiZXR3ZWVuIHJlc2VydmUgYW5kIHJvbGxiYWNrLCB0aGUgc2VydmVyIHNraXBzIHRoZSBkZWNyZW1lbnQgc28gaXQgZG9lc24ndFxuICAgKiBzdGVhbCBjYXBhY2l0eSBmcm9tIHRoZSBuZXcgcGVyaW9kLlxuICAgKi9cbiAgZGVjcmVtZW50KG9yZ0lkOiBzdHJpbmcsIHF1b3RhVHlwZTogUXVvdGFUeXBlLCBhdXRoSGVhZGVyOiBzdHJpbmcsIGFtb3VudD86IG51bWJlciwgcmVzZXRBdFNuYXBzaG90Pzogc3RyaW5nLCByZXF1ZXN0SWQ/OiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+O1xuICAvKiogVXBkYXRlIHF1b3RhIGxpbWl0cy4gUmV0dXJucyB0cnVlIG9uIHN1Y2Nlc3MuICovXG4gIHVwZGF0ZUxpbWl0cyhvcmdJZDogc3RyaW5nLCBsaW1pdHM6IFBhcnRpYWw8UmVjb3JkPFF1b3RhVHlwZSwgbnVtYmVyPj4sIGF1dGhIZWFkZXI6IHN0cmluZywgcmVxdWVzdElkPzogc3RyaW5nKTogUHJvbWlzZTxib29sZWFuPjtcbiAgLyoqIFJlc2V0IHF1b3RhIHVzYWdlLiBSZXR1cm5zIHRydWUgb24gc3VjY2Vzcy4gKi9cbiAgcmVzZXQob3JnSWQ6IHN0cmluZywgcXVvdGFUeXBlPzogUXVvdGFUeXBlLCBhdXRoSGVhZGVyPzogc3RyaW5nLCByZXF1ZXN0SWQ/OiBzdHJpbmcpOiBQcm9taXNlPGJvb2xlYW4+O1xuICAvKipcbiAgICogR2V0IHRoZSBvcmcncyBxdW90YSBgUXVvdGFUaWVyYC4gVXNlZCBieSB0aGUgcGx1Z2luLWJ1aWxkIHF1ZXVlIHBhcnRpdGlvbmluZ1xuICAgKiB0byByb3V0ZSBhIGJ1aWxkIHRvIHRoZSByaWdodCBwZXItdGllciBxdWV1ZS4gRmFpbC1vcGVuIHJldHVybnMgYERFRkFVTFRfVElFUmBcbiAgICogKGBkZXZlbG9wZXJgIHdoZW4gYmlsbGluZyBpcyBlbmFibGVkLCBgdW5saW1pdGVkYCB3aGVuIGl0J3MgZGlzYWJsZWQpOyBhXG4gICAqIG1pc2NsYXNzaWZpZWQgb3JnIHN0aWxsIGJ1aWxkcyBvbiB0aGUgZGVmYXVsdCBxdWV1ZSwganVzdCB3aXRob3V0IHRoZVxuICAgKiB0aWVyLXNjb3BlZCBzY2hlZHVsaW5nIGJvb3N0LlxuICAgKi9cbiAgZ2V0VGllcihvcmdJZDogc3RyaW5nLCBhdXRoSGVhZGVyOiBzdHJpbmcsIHJlcXVlc3RJZD86IHN0cmluZyk6IFByb21pc2U8UXVvdGFUaWVyPjtcbn1cblxuLyoqXG4gKiBDb25maWd1cmF0aW9uIGZvciBxdW90YSBzZXJ2aWNlIGNsaWVudC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBRdW90YVNlcnZpY2VDb25maWcge1xuICAvKiogUXVvdGEgc2VydmljZSBob3N0IChkZWZhdWx0OiBlbnYgUVVPVEFfU0VSVklDRV9IT1NUIG9yICdxdW90YScpICovXG4gIGhvc3Q/OiBzdHJpbmc7XG4gIC8qKiBRdW90YSBzZXJ2aWNlIHBvcnQgKGRlZmF1bHQ6IGVudiBRVU9UQV9TRVJWSUNFX1BPUlQgb3IgMzAwMCkgKi9cbiAgcG9ydD86IG51bWJlcjtcbiAgLyoqIFJlcXVlc3QgdGltZW91dCBpbiBtaWxsaXNlY29uZHMgKGRlZmF1bHQ6IDUwMDApICovXG4gIHRpbWVvdXQ/OiBudW1iZXI7XG59XG5cbi8qKlxuICogQ3JlYXRlIGEgZmFpbC1vcGVuIHF1b3RhIHJlc3VsdCAoYWxsb3dzIHRoZSByZXF1ZXN0KS5cbiAqL1xuZnVuY3Rpb24gY3JlYXRlRmFpbE9wZW5SZXN1bHQoKTogUXVvdGFDaGVja1Jlc3VsdCB7XG4gIHJldHVybiB7XG4gICAgYWxsb3dlZDogdHJ1ZSxcbiAgICBsaW1pdDogLTEsXG4gICAgdXNlZDogMCxcbiAgICByZW1haW5pbmc6IC0xLFxuICAgIHJlc2V0QXQ6IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKSxcbiAgICB1bmxpbWl0ZWQ6IHRydWUsXG4gICAgLy8gVGFnIHRoZSBzZW50aW5lbCBzbyBmYWlsLWNsb3NlZCBjYWxsZXJzIGNhbiB0ZWxsIGFuIG91dGFnZSBhcGFydCBmcm9tIGFcbiAgICAvLyByZWFsIHVubGltaXRlZCAoLTEpIHJlYWRpbmcuIFJlYWwgcXVvdGEgcmVzdWx0cyBuZXZlciBzZXQgdGhpcy5cbiAgICBmYWlsT3BlbjogdHJ1ZSxcbiAgfTtcbn1cblxuLyoqXG4gKiBCdWlsZCBjb21tb24gcmVxdWVzdCBoZWFkZXJzIHdpdGggb3B0aW9uYWwgcmVxdWVzdCBJRCBmb3IgZGlzdHJpYnV0ZWQgdHJhY2luZy5cbiAqL1xuZnVuY3Rpb24gYnVpbGRIZWFkZXJzKG9yZ0lkOiBzdHJpbmcsIGF1dGhIZWFkZXI/OiBzdHJpbmcsIHJlcXVlc3RJZD86IHN0cmluZyk6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4ge1xuICBjb25zdCBoZWFkZXJzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0geyAneC1vcmctaWQnOiBvcmdJZCB9O1xuICBpZiAoYXV0aEhlYWRlcikgaGVhZGVycy5BdXRob3JpemF0aW9uID0gYXV0aEhlYWRlcjtcbiAgaWYgKHJlcXVlc3RJZCkgaGVhZGVyc1snWC1SZXF1ZXN0LUlkJ10gPSByZXF1ZXN0SWQ7XG4gIHJldHVybiBoZWFkZXJzO1xufVxuXG4vKipcbiAqIENyZWF0ZSBhIHF1b3RhIHNlcnZpY2UgY2xpZW50LlxuICpcbiAqIEBwYXJhbSBjb25maWcgLSBPcHRpb25hbCBzZXJ2aWNlIGNvbmZpZ3VyYXRpb25cbiAqIEByZXR1cm5zIFF1b3RhIHNlcnZpY2UgY2xpZW50XG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnN0IHF1b3RhU2VydmljZSA9IGNyZWF0ZVF1b3RhU2VydmljZSgpO1xuICpcbiAqIC8vIENoZWNrIHF1b3RhIGJlZm9yZSBwcm9jZXNzaW5nXG4gKiBjb25zdCBxdW90YSA9IGF3YWl0IHF1b3RhU2VydmljZS5jaGVjayhvcmdJZCwgJ2FwaUNhbGxzJywgYXV0aEhlYWRlcik7XG4gKiBpZiAoIXF1b3RhLmFsbG93ZWQpIHtcbiAqIHJldHVybiByZXMuc3RhdHVzKDQyOSkuanNvbih7IGVycm9yOiAnUXVvdGEgZXhjZWVkZWQnIH0pO1xuICogfVxuICpcbiAqIC8vIEluY3JlbWVudCBxdW90YSBhZnRlciBzdWNjZXNzXG4gKiBxdW90YVNlcnZpY2UuaW5jcmVtZW50KG9yZ0lkLCAnYXBpQ2FsbHMnLCBhdXRoSGVhZGVyKS5jYXRjaChlcnIgPT4gbG9nZ2VyLndhcm4oJ1F1b3RhIGluY3JlbWVudCBmYWlsZWQnLCB7IGVycm9yOiBlcnIgfSkpO1xuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVRdW90YVNlcnZpY2UoY29uZmlnOiBRdW90YVNlcnZpY2VDb25maWcgPSB7fSk6IFF1b3RhU2VydmljZSB7XG4gIGNvbnN0IHNlcnZpY2VDb25maWc6IFNlcnZpY2VDb25maWcgPSB7XG4gICAgaG9zdDogY29uZmlnLmhvc3QgPz8gcHJvY2Vzcy5lbnYuUVVPVEFfU0VSVklDRV9IT1NUID8/ICdxdW90YScsXG4gICAgcG9ydDogY29uZmlnLnBvcnQgPz8gcGFyc2VJbnQocHJvY2Vzcy5lbnYuUVVPVEFfU0VSVklDRV9QT1JUID8/ICczMDAwJywgMTApLFxuICAgIHRpbWVvdXQ6IGNvbmZpZy50aW1lb3V0ID8/IDUwMDAsXG4gIH07XG5cbiAgY29uc3QgY2xpZW50ID0gY3JlYXRlU2FmZUNsaWVudChzZXJ2aWNlQ29uZmlnKTtcblxuICByZXR1cm4ge1xuICAgIGFzeW5jIGNoZWNrKG9yZ0lkOiBzdHJpbmcsIHF1b3RhVHlwZTogUXVvdGFUeXBlLCBhdXRoSGVhZGVyOiBzdHJpbmcsIHJlcXVlc3RJZD86IHN0cmluZyk6IFByb21pc2U8UXVvdGFDaGVja1Jlc3VsdD4ge1xuICAgICAgY29uc3QgcGF0aCA9IGAvcXVvdGFzLyR7ZW5jb2RlVVJJQ29tcG9uZW50KG9yZ0lkKX0vJHtlbmNvZGVVUklDb21wb25lbnQocXVvdGFUeXBlKX1gO1xuXG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGNsaWVudC5nZXQ8e1xuICAgICAgICBzdWNjZXNzOiBib29sZWFuO1xuICAgICAgICBkYXRhPzogeyBxdW90YVR5cGU6IHN0cmluZzsgc3RhdHVzOiBRdW90YUNoZWNrUmVzdWx0IH07XG4gICAgICAgIG1lc3NhZ2U/OiBzdHJpbmc7XG4gICAgICB9PihwYXRoLCB7IGhlYWRlcnM6IGJ1aWxkSGVhZGVycyhvcmdJZCwgYXV0aEhlYWRlciwgcmVxdWVzdElkKSwgLi4uUVVPVEFfUkVRVUVTVF9PUFRJT05TIH0pO1xuXG4gICAgICBpZiAoIXJlc3BvbnNlKSB7XG4gICAgICAgIGxvZ2dlci53YXJuKCdRVU9UQV9GQUlMX09QRU46IFF1b3RhIHNlcnZpY2UgdW5yZWFjaGFibGUsIGFsbG93aW5nIHJlcXVlc3QnLCB7IG9yZ0lkLCBxdW90YVR5cGUgfSk7XG4gICAgICAgIGVtaXRDb3VudGVyKCdxdW90YV9mYWlsX29wZW5fdG90YWwnLCB7IG9wZXJhdGlvbjogJ2NoZWNrJywgcmVhc29uOiAndW5yZWFjaGFibGUnLCBxdW90YVR5cGUgfSk7XG4gICAgICAgIHJldHVybiBjcmVhdGVGYWlsT3BlblJlc3VsdCgpO1xuICAgICAgfVxuXG4gICAgICBpZiAocmVzcG9uc2Uuc3RhdHVzQ29kZSAhPT0gMjAwIHx8ICFyZXNwb25zZS5ib2R5LnN1Y2Nlc3MgfHwgIXJlc3BvbnNlLmJvZHkuZGF0YT8uc3RhdHVzKSB7XG4gICAgICAgIGxvZ2dlci53YXJuKCdRVU9UQV9GQUlMX09QRU46IFF1b3RhIGNoZWNrIHJldHVybmVkIG5vbi1vaywgYWxsb3dpbmcgcmVxdWVzdCcsIHtcbiAgICAgICAgICBvcmdJZCwgcXVvdGFUeXBlLCBzdGF0dXNDb2RlOiByZXNwb25zZS5zdGF0dXNDb2RlLCBtZXNzYWdlOiByZXNwb25zZS5ib2R5Lm1lc3NhZ2UsXG4gICAgICAgIH0pO1xuICAgICAgICBlbWl0Q291bnRlcigncXVvdGFfZmFpbF9vcGVuX3RvdGFsJywgeyBvcGVyYXRpb246ICdjaGVjaycsIHJlYXNvbjogJ25vbi1vaycsIHF1b3RhVHlwZSB9KTtcbiAgICAgICAgcmV0dXJuIGNyZWF0ZUZhaWxPcGVuUmVzdWx0KCk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiByZXNwb25zZS5ib2R5LmRhdGEuc3RhdHVzO1xuICAgIH0sXG5cbiAgICBhc3luYyBpbmNyZW1lbnQob3JnSWQ6IHN0cmluZywgcXVvdGFUeXBlOiBRdW90YVR5cGUsIGF1dGhIZWFkZXI6IHN0cmluZywgYW1vdW50OiBudW1iZXIgPSAxLCByZXF1ZXN0SWQ/OiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgIGNvbnN0IHBhdGggPSBgL3F1b3Rhcy8ke2VuY29kZVVSSUNvbXBvbmVudChvcmdJZCl9L2luY3JlbWVudGA7XG5cbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgY2xpZW50XG4gICAgICAgIC5wb3N0KHBhdGgsIHsgcXVvdGFUeXBlLCBhbW91bnQgfSwgeyBoZWFkZXJzOiBidWlsZEhlYWRlcnMob3JnSWQsIGF1dGhIZWFkZXIsIHJlcXVlc3RJZCksIC4uLlFVT1RBX1JFUVVFU1RfT1BUSU9OUyB9KTtcblxuICAgICAgaWYgKCFyZXNwb25zZSB8fCByZXNwb25zZS5zdGF0dXNDb2RlICE9PSAyMDApIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oJ0ZhaWxlZCB0byBpbmNyZW1lbnQgcXVvdGEnLCB7XG4gICAgICAgICAgb3JnSWQsIHF1b3RhVHlwZSwgYW1vdW50LCBzdGF0dXNDb2RlOiByZXNwb25zZT8uc3RhdHVzQ29kZSxcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsb2dnZXIuZGVidWcoJ1F1b3RhIGluY3JlbWVudGVkJywgeyBvcmdJZCwgcXVvdGFUeXBlLCBhbW91bnQgfSk7XG4gICAgICB9XG4gICAgfSxcblxuICAgIGFzeW5jIHJlc2VydmUob3JnSWQ6IHN0cmluZywgcXVvdGFUeXBlOiBRdW90YVR5cGUsIGF1dGhIZWFkZXI6IHN0cmluZywgYW1vdW50OiBudW1iZXIgPSAxLCByZXF1ZXN0SWQ/OiBzdHJpbmcpOiBQcm9taXNlPFF1b3RhUmVzZXJ2ZVJlc3VsdD4ge1xuICAgICAgY29uc3QgcGF0aCA9IGAvcXVvdGFzLyR7ZW5jb2RlVVJJQ29tcG9uZW50KG9yZ0lkKX0vaW5jcmVtZW50YDtcblxuICAgICAgLy8gMjAwIGNhcnJpZXMgYGRhdGEucXVvdGFgOyA0MjkgKFFVT1RBX0VYQ0VFREVEKSBjYXJyaWVzIGBkZXRhaWxzLnF1b3RhYC5cbiAgICAgIC8vIEJvdGggc2hhcGVzIGFyZSBub3JtYWxpemVkIGludG8gUXVvdGFSZXNlcnZlUmVzdWx0LlxuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBjbGllbnQucG9zdDx7XG4gICAgICAgIHN1Y2Nlc3M6IGJvb2xlYW47XG4gICAgICAgIGRhdGE/OiB7IHF1b3RhPzogUXVvdGFSZXNlcnZlUmVzdWx0WydxdW90YSddIH07XG4gICAgICAgIGRldGFpbHM/OiB7IHF1b3RhPzogUXVvdGFSZXNlcnZlUmVzdWx0WydxdW90YSddIH07XG4gICAgICAgIGVycm9yQ29kZT86IHN0cmluZztcbiAgICAgIH0+KHBhdGgsIHsgcXVvdGFUeXBlLCBhbW91bnQgfSwgeyBoZWFkZXJzOiBidWlsZEhlYWRlcnMob3JnSWQsIGF1dGhIZWFkZXIsIHJlcXVlc3RJZCksIC4uLlFVT1RBX1JFUVVFU1RfT1BUSU9OUyB9KTtcblxuICAgICAgaWYgKCFyZXNwb25zZSkge1xuICAgICAgICBsb2dnZXIud2FybignUVVPVEFfRkFJTF9PUEVOOiBRdW90YSBzZXJ2aWNlIHVucmVhY2hhYmxlIG9uIHJlc2VydmUsIGFsbG93aW5nIHJlcXVlc3QnLCB7IG9yZ0lkLCBxdW90YVR5cGUgfSk7XG4gICAgICAgIGVtaXRDb3VudGVyKCdxdW90YV9mYWlsX29wZW5fdG90YWwnLCB7IG9wZXJhdGlvbjogJ3Jlc2VydmUnLCByZWFzb246ICd1bnJlYWNoYWJsZScsIHF1b3RhVHlwZSB9KTtcbiAgICAgICAgcmV0dXJuIHsgZXhjZWVkZWQ6IGZhbHNlLCBxdW90YTogeyB0eXBlOiBxdW90YVR5cGUsIGxpbWl0OiAtMSwgdXNlZDogMCwgcmVtYWluaW5nOiAtMSB9IH07XG4gICAgICB9XG5cbiAgICAgIGlmIChyZXNwb25zZS5zdGF0dXNDb2RlID09PSA0MjkpIHtcbiAgICAgICAgY29uc3QgcSA9IHJlc3BvbnNlLmJvZHkuZGV0YWlscz8ucXVvdGE7XG4gICAgICAgIC8vIE9ubHkgYSBHRU5VSU5FIHF1b3RhLWV4Y2VlZGVkIDQyOSBtZWFucyBcIm92ZXIgcXVvdGFcIi4gQSBnZW5lcmljIDQyOSDigJRcbiAgICAgICAgLy8gdGhlIHF1b3RhIHNlcnZpY2UncyBPV04gcmF0ZSBsaW1pdGVyIChSQVRFX0xJTUlUX0VYQ0VFREVEKSBvciBhblxuICAgICAgICAvLyBpbnRlcnZlbmluZyBnYXRld2F5IGR1cmluZyBhIHNwaWtlIOKAlCBtdXN0IE5PVCBiZSBzdXJmYWNlZCBhc1xuICAgICAgICAvLyBxdW90YS1leGNlZWRlZDogdGhhdCB3b3VsZCBmYWxzZWx5IGJsb2NrIGxlZ2l0aW1hdGUgd29yayBiZWhpbmQgYVxuICAgICAgICAvLyB0cmFuc2llbnQgcmF0ZSBsaW1pdC4gUmVxdWlyZSB0aGUgUVVPVEFfRVhDRUVERUQgZXJyb3IgY29kZSAob3IgdGhlXG4gICAgICAgIC8vIHF1b3RhIHBheWxvYWQpIGFuZCBvdGhlcndpc2UgZmFsbCB0aHJvdWdoIHRvIHRoZSBub24tb2tcbiAgICAgICAgLy8gZmFpbC1vcGVuL2Nsb3NlZCBwb2xpY3kgYmVsb3cgKHRoZSByaWdodCBoYW5kbGluZyBmb3IgYSB0cmFuc2llbnQgNDI5KS5cbiAgICAgICAgaWYgKHJlc3BvbnNlLmJvZHkuZXJyb3JDb2RlID09PSAnUVVPVEFfRVhDRUVERUQnIHx8IHEpIHtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgZXhjZWVkZWQ6IHRydWUsXG4gICAgICAgICAgICBxdW90YTogcSA/PyB7IHR5cGU6IHF1b3RhVHlwZSwgbGltaXQ6IDAsIHVzZWQ6IDAsIHJlbWFpbmluZzogMCB9LFxuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgLy8gQSBub24tUVVPVEFfRVhDRUVERUQgNDI5IGlzIGEgVFJBTlNJRU5UIHNpZ25hbCAodGhlIHF1b3RhIHNlcnZpY2UncyBvd25cbiAgICAgICAgLy8gcmF0ZSBsaW1pdGVyLCBvciBhIGdhdGV3YXkgZHVyaW5nIGEgc3Bpa2UpIOKAlCB0aGUgdGVuYW50IGlzIE5PVCBvdmVyIHF1b3RhLFxuICAgICAgICAvLyBzbyBmYWlsIE9QRU4gKGFzIGZvciBhbiB1bnJlYWNoYWJsZSBzZXJ2aWNlKSByYXRoZXIgdGhhbiBmYWxzZWx5IGJsb2NraW5nXG4gICAgICAgIC8vIGxlZ2l0aW1hdGUgd29yay4gRG8gbm90IGZhbGwgdGhyb3VnaCB0byB0aGUgZmFpbC1jbG9zZWQgbm9uLW9rIGRlZmF1bHQuXG4gICAgICAgIGxvZ2dlci53YXJuKCdRVU9UQV9GQUlMX09QRU46IHRyYW5zaWVudCA0Mjkgb24gcmVzZXJ2ZSAobm90IHF1b3RhLWV4Y2VlZGVkKSwgYWxsb3dpbmcgcmVxdWVzdCcsIHsgb3JnSWQsIHF1b3RhVHlwZSB9KTtcbiAgICAgICAgZW1pdENvdW50ZXIoJ3F1b3RhX2ZhaWxfb3Blbl90b3RhbCcsIHsgb3BlcmF0aW9uOiAncmVzZXJ2ZScsIHJlYXNvbjogJ3RyYW5zaWVudC00MjknLCBxdW90YVR5cGUgfSk7XG4gICAgICAgIHJldHVybiB7IGV4Y2VlZGVkOiBmYWxzZSwgcXVvdGE6IHsgdHlwZTogcXVvdGFUeXBlLCBsaW1pdDogLTEsIHVzZWQ6IDAsIHJlbWFpbmluZzogLTEgfSB9O1xuICAgICAgfVxuXG4gICAgICBpZiAocmVzcG9uc2Uuc3RhdHVzQ29kZSAhPT0gMjAwIHx8ICFyZXNwb25zZS5ib2R5LnN1Y2Nlc3MpIHtcbiAgICAgICAgaWYgKFFVT1RBX1JFU0VSVkVfRkFJTF9PUEVOKSB7XG4gICAgICAgICAgbG9nZ2VyLndhcm4oJ1FVT1RBX0ZBSUxfT1BFTjogUXVvdGEgcmVzZXJ2ZSByZXR1cm5lZCBub24tb2ssIGFsbG93aW5nIHJlcXVlc3QnLCB7XG4gICAgICAgICAgICBvcmdJZCwgcXVvdGFUeXBlLCBzdGF0dXNDb2RlOiByZXNwb25zZS5zdGF0dXNDb2RlLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIGVtaXRDb3VudGVyKCdxdW90YV9mYWlsX29wZW5fdG90YWwnLCB7IG9wZXJhdGlvbjogJ3Jlc2VydmUnLCByZWFzb246ICdub24tb2snLCBxdW90YVR5cGUgfSk7XG4gICAgICAgICAgcmV0dXJuIHsgZXhjZWVkZWQ6IGZhbHNlLCBxdW90YTogeyB0eXBlOiBxdW90YVR5cGUsIGxpbWl0OiAtMSwgdXNlZDogMCwgcmVtYWluaW5nOiAtMSB9IH07XG4gICAgICAgIH1cbiAgICAgICAgLy8gU2VydmljZSByZWFjaGFibGUgYnV0IGRpZG4ndCBjb25maXJtIHRoZSByZXNlcnZhdGlvbiDihpIgZmFpbCBDTE9TRUQuXG4gICAgICAgIGxvZ2dlci53YXJuKCdRVU9UQV9GQUlMX0NMT1NFRDogUXVvdGEgcmVzZXJ2ZSByZXR1cm5lZCBub24tb2ssIGRlbnlpbmcgcmVxdWVzdCcsIHtcbiAgICAgICAgICBvcmdJZCwgcXVvdGFUeXBlLCBzdGF0dXNDb2RlOiByZXNwb25zZS5zdGF0dXNDb2RlLFxuICAgICAgICB9KTtcbiAgICAgICAgZW1pdENvdW50ZXIoJ3F1b3RhX2ZhaWxfY2xvc2VkX3RvdGFsJywgeyBvcGVyYXRpb246ICdyZXNlcnZlJywgcmVhc29uOiAnbm9uLW9rJywgcXVvdGFUeXBlIH0pO1xuICAgICAgICByZXR1cm4geyBleGNlZWRlZDogdHJ1ZSwgcXVvdGE6IHsgdHlwZTogcXVvdGFUeXBlLCBsaW1pdDogMCwgdXNlZDogMCwgcmVtYWluaW5nOiAwIH0gfTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgcSA9IHJlc3BvbnNlLmJvZHkuZGF0YT8ucXVvdGE7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBleGNlZWRlZDogZmFsc2UsXG4gICAgICAgIHF1b3RhOiBxID8/IHsgdHlwZTogcXVvdGFUeXBlLCBsaW1pdDogLTEsIHVzZWQ6IDAsIHJlbWFpbmluZzogLTEgfSxcbiAgICAgIH07XG4gICAgfSxcblxuICAgIGFzeW5jIGRlY3JlbWVudChvcmdJZDogc3RyaW5nLCBxdW90YVR5cGU6IFF1b3RhVHlwZSwgYXV0aEhlYWRlcjogc3RyaW5nLCBhbW91bnQ6IG51bWJlciA9IDEsIHJlc2V0QXRTbmFwc2hvdD86IHN0cmluZywgcmVxdWVzdElkPzogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICBjb25zdCBwYXRoID0gYC9xdW90YXMvJHtlbmNvZGVVUklDb21wb25lbnQob3JnSWQpfS9kZWNyZW1lbnRgO1xuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBjbGllbnRcbiAgICAgICAgLnBvc3QocGF0aCwgeyBxdW90YVR5cGUsIGFtb3VudCwgLi4uKHJlc2V0QXRTbmFwc2hvdCAmJiB7IHJlc2V0QXRTbmFwc2hvdCB9KSB9LCB7IGhlYWRlcnM6IGJ1aWxkSGVhZGVycyhvcmdJZCwgYXV0aEhlYWRlciwgcmVxdWVzdElkKSwgLi4uUVVPVEFfUkVRVUVTVF9PUFRJT05TIH0pO1xuXG4gICAgICBpZiAoIXJlc3BvbnNlIHx8IHJlc3BvbnNlLnN0YXR1c0NvZGUgIT09IDIwMCkge1xuICAgICAgICAvLyBSb2xsYmFjayBmYWlsdXJlIGlzIGxvZ2dlZCBidXQgbmV2ZXIgcHJvcGFnYXRlZCAgdGhlIGFjdGlvbidzIG93blxuICAgICAgICAvLyBmYWlsdXJlIGhhcyBhbHJlYWR5IGJlZW4gc3VyZmFjZWQgdG8gdGhlIGNhbGxlcjsgYSBzdHVjayBjb3VudGVyXG4gICAgICAgIC8vIHJlc29sdmVzIG9uIHRoZSBuZXh0IHBlcmlvZCByZXNldC5cbiAgICAgICAgbG9nZ2VyLndhcm4oJ0ZhaWxlZCB0byBkZWNyZW1lbnQgcXVvdGEgKHNsb3Qgd2lsbCByZXNldCBvbiBuZXh0IHBlcmlvZCknLCB7XG4gICAgICAgICAgb3JnSWQsIHF1b3RhVHlwZSwgYW1vdW50LCBzdGF0dXNDb2RlOiByZXNwb25zZT8uc3RhdHVzQ29kZSxcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsb2dnZXIuZGVidWcoJ1F1b3RhIGRlY3JlbWVudGVkJywgeyBvcmdJZCwgcXVvdGFUeXBlLCBhbW91bnQgfSk7XG4gICAgICB9XG4gICAgfSxcblxuICAgIGFzeW5jIHVwZGF0ZUxpbWl0cyggb3JnSWQ6IHN0cmluZyxcbiAgICAgIGxpbWl0czogUGFydGlhbDxSZWNvcmQ8UXVvdGFUeXBlLCBudW1iZXI+PixcbiAgICAgIGF1dGhIZWFkZXI6IHN0cmluZyxcbiAgICAgIHJlcXVlc3RJZD86IHN0cmluZyxcbiAgICApOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICAgIGNvbnN0IHBhdGggPSBgL3F1b3Rhcy8ke2VuY29kZVVSSUNvbXBvbmVudChvcmdJZCl9YDtcblxuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBjbGllbnQucHV0KHBhdGgsIGxpbWl0cywgeyBoZWFkZXJzOiBidWlsZEhlYWRlcnMob3JnSWQsIGF1dGhIZWFkZXIsIHJlcXVlc3RJZCkgfSk7XG5cbiAgICAgIGlmICghcmVzcG9uc2UgfHwgcmVzcG9uc2Uuc3RhdHVzQ29kZSAhPT0gMjAwKSB7XG4gICAgICAgIGxvZ2dlci53YXJuKCdGYWlsZWQgdG8gdXBkYXRlIHF1b3RhIGxpbWl0cycsIHtcbiAgICAgICAgICBvcmdJZCwgbGltaXRzLCBzdGF0dXNDb2RlOiByZXNwb25zZT8uc3RhdHVzQ29kZSxcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgbG9nZ2VyLmluZm8oJ1F1b3RhIGxpbWl0cyB1cGRhdGVkJywgeyBvcmdJZCwgbGltaXRzIH0pO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSxcblxuICAgIGFzeW5jIGdldFRpZXIob3JnSWQ6IHN0cmluZywgYXV0aEhlYWRlcjogc3RyaW5nLCByZXF1ZXN0SWQ/OiBzdHJpbmcpOiBQcm9taXNlPFF1b3RhVGllcj4ge1xuICAgICAgY29uc3QgcGF0aCA9IGAvcXVvdGFzLyR7ZW5jb2RlVVJJQ29tcG9uZW50KG9yZ0lkKX1gO1xuXG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGNsaWVudC5nZXQ8e1xuICAgICAgICBzdWNjZXNzOiBib29sZWFuO1xuICAgICAgICBkYXRhPzogeyBxdW90YT86IHsgdGllcj86IHN0cmluZyB9IH07XG4gICAgICAgIG1lc3NhZ2U/OiBzdHJpbmc7XG4gICAgICB9PihwYXRoLCB7IGhlYWRlcnM6IGJ1aWxkSGVhZGVycyhvcmdJZCwgYXV0aEhlYWRlciwgcmVxdWVzdElkKSwgLi4uUVVPVEFfUkVRVUVTVF9PUFRJT05TIH0pO1xuXG4gICAgICBpZiAoIXJlc3BvbnNlIHx8IHJlc3BvbnNlLnN0YXR1c0NvZGUgIT09IDIwMCB8fCAhcmVzcG9uc2UuYm9keS5zdWNjZXNzKSB7XG4gICAgICAgIGxvZ2dlci53YXJuKGBRVU9UQV9GQUlMX09QRU46IHRpZXIgbG9va3VwIGZhaWxlZCwgZGVmYXVsdGluZyB0byAke0RFRkFVTFRfVElFUn0gdGllcmAsIHtcbiAgICAgICAgICBvcmdJZCwgc3RhdHVzQ29kZTogcmVzcG9uc2U/LnN0YXR1c0NvZGUsIGRlZmF1bHRUaWVyOiBERUZBVUxUX1RJRVIsXG4gICAgICAgIH0pO1xuICAgICAgICBlbWl0Q291bnRlcigncXVvdGFfZmFpbF9vcGVuX3RvdGFsJywgeyBvcGVyYXRpb246ICd0aWVyJywgcmVhc29uOiByZXNwb25zZSA/ICdub24tb2snIDogJ3VucmVhY2hhYmxlJywgcXVvdGFUeXBlOiAndGllcicgfSk7XG4gICAgICAgIHJldHVybiBERUZBVUxUX1RJRVI7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHRpZXIgPSByZXNwb25zZS5ib2R5LmRhdGE/LnF1b3RhPy50aWVyO1xuICAgICAgcmV0dXJuIHRpZXIgJiYgaXNWYWxpZFRpZXIodGllcikgPyB0aWVyOiBERUZBVUxUX1RJRVI7XG4gICAgfSxcblxuICAgIGFzeW5jIHJlc2V0KG9yZ0lkOiBzdHJpbmcsIHF1b3RhVHlwZT86IFF1b3RhVHlwZSwgYXV0aEhlYWRlcj86IHN0cmluZywgcmVxdWVzdElkPzogc3RyaW5nKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgICBjb25zdCBwYXRoID0gYC9xdW90YXMvJHtlbmNvZGVVUklDb21wb25lbnQob3JnSWQpfS9yZXNldGA7XG5cbiAgICAgIGNvbnN0IGJvZHkgPSBxdW90YVR5cGUgPyB7IHF1b3RhVHlwZSB9OiB7fTtcbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgY2xpZW50LnBvc3QocGF0aCwgYm9keSwgeyBoZWFkZXJzOiBidWlsZEhlYWRlcnMob3JnSWQsIGF1dGhIZWFkZXIgPz8gJycsIHJlcXVlc3RJZCkgfSk7XG5cbiAgICAgIGlmICghcmVzcG9uc2UgfHwgcmVzcG9uc2Uuc3RhdHVzQ29kZSAhPT0gMjAwKSB7XG4gICAgICAgIGxvZ2dlci53YXJuKCdGYWlsZWQgdG8gcmVzZXQgcXVvdGEnLCB7XG4gICAgICAgICAgb3JnSWQsIHF1b3RhVHlwZSwgc3RhdHVzQ29kZTogcmVzcG9uc2U/LnN0YXR1c0NvZGUsXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIGxvZ2dlci5pbmZvKCdRdW90YSByZXNldCcsIHsgb3JnSWQsIHF1b3RhVHlwZTogcXVvdGFUeXBlID8/ICdhbGwnIH0pO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSxcbiAgfTtcbn1cblxuLyoqXG4gKiBGaXJlLWFuZC1mb3JnZXQgcXVvdGEgaW5jcmVtZW50IHdpdGggc3RhbmRhcmRpemVkIGVycm9yIGxvZ2dpbmcuXG4gKlxuICogV3JhcHMgYHF1b3RhU2VydmljZS5pbmNyZW1lbnQoKWAgd2l0aCBhIGAuY2F0Y2goKWAgdGhhdCBsb2dzIGEgd2FybmluZy5cbiAqIEVsaW1pbmF0ZXMgdGhlIGlkZW50aWNhbCBvbmUtbGluZXIgcmVwZWF0ZWQgYWNyb3NzIGV2ZXJ5IHJlYWQgcm91dGUuXG4gKlxuICogQHBhcmFtIHF1b3RhU2VydmljZSAtIFF1b3RhIHNlcnZpY2UgY2xpZW50XG4gKiBAcGFyYW0gb3JnSWQgLSBPcmdhbml6YXRpb24gSURcbiAqIEBwYXJhbSBxdW90YVR5cGUgLSBRdW90YSB0eXBlIHRvIGluY3JlbWVudFxuICogQHBhcmFtIGF1dGhIZWFkZXIgLSBBdXRob3JpemF0aW9uIGhlYWRlciB2YWx1ZVxuICogQHBhcmFtIGxvZ1dhcm4gLSBMb2dnaW5nIGZ1bmN0aW9uIGZvciB3YXJuaW5nc1xuICovXG5leHBvcnQgZnVuY3Rpb24gaW5jcmVtZW50UXVvdGEoIHF1b3RhU2VydmljZTogUXVvdGFTZXJ2aWNlLFxuICBvcmdJZDogc3RyaW5nLFxuICBxdW90YVR5cGU6IFF1b3RhVHlwZSxcbiAgYXV0aEhlYWRlcjogc3RyaW5nLFxuICBsb2dXYXJuOiAobWVzc2FnZTogc3RyaW5nLCBkYXRhPzogdW5rbm93bikgPT4gdm9pZCxcbik6IHZvaWQge1xuICBxdW90YVNlcnZpY2UuaW5jcmVtZW50KG9yZ0lkLCBxdW90YVR5cGUsIGF1dGhIZWFkZXIpLmNhdGNoKChlcnI6IHVua25vd24pID0+XG4gICAgbG9nV2FybignUXVvdGEgaW5jcmVtZW50IGZhaWxlZCcsIHsgZXJyb3I6IGVyciBpbnN0YW5jZW9mIEVycm9yID8gZXJyLm1lc3NhZ2U6IFN0cmluZyhlcnIpIH0pLFxuICApO1xufVxuXG4vKipcbiAqIEF0b21pYyByZXNlcnZlIGhlbHBlciBmb3IgdGhlIFwicmVzZXJ2ZSArIGNvbW1pdCAvIHJvbGxiYWNrXCIgcGF0dGVybi5cbiAqIFVzZSBmb3IgZXhwZW5zaXZlIHJlc291cmNlcyAocGlwZWxpbmVzLCBwbHVnaW5zLCBBSSBjYWxscykgd2hlcmUgdGhlXG4gKiBmaXJlLWFuZC1mb3JnZXQgcG9zdC1ob2MgYGluY3JlbWVudFF1b3RhYCBhbGxvd3MgY29uY3VycmVudCBvdmVyLXNwZW5kLlxuICpcbiAqIFJldHVybnMgdGhlIHN0cnVjdHVyZWQgcmVzdWx0IHNvIHRoZSBjYWxsZXIgY2FuIGRlY2lkZSB3aGV0aGVyIHRvIHJ1blxuICogdGhlIGdhdGVkIGFjdGlvbiBvciA0MjkgdGhlIGNsaWVudC5cbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgcmVzZXJ2YXRpb24gPSBhd2FpdCByZXNlcnZlUXVvdGEocXVvdGFTZXJ2aWNlLCBvcmdJZCwgJ3BpcGVsaW5lcycsIGF1dGhIZWFkZXIpO1xuICogaWYgKHJlc2VydmF0aW9uLmV4Y2VlZGVkKSByZXR1cm4gc2VuZFF1b3RhRXhjZWVkZWQocmVzLCAncGlwZWxpbmVzJywgcmVzZXJ2YXRpb24ucXVvdGEpO1xuICogdHJ5IHtcbiAqIGF3YWl0IGRvRXhwZW5zaXZlVGhpbmcoKTtcbiAqIH0gY2F0Y2ggKGVycikge1xuICogLy8gUGFzcyB0aGUgcmVzZXJ2ZWQgcmVzZXRBdCBzbyBhIHBlcmlvZCByb2xsb3ZlciBkb2Vzbid0IGdldCBkb3VibGUtY2hhcmdlZC5cbiAqIGRlY3JlbWVudFF1b3RhKHF1b3RhU2VydmljZSwgb3JnSWQsICdwaXBlbGluZXMnLCBhdXRoSGVhZGVyLCBsb2dXYXJuLCAxLCByZXNlcnZhdGlvbi5xdW90YS5yZXNldEF0KTtcbiAqIHRocm93IGVycjtcbiAqIH1cbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVzZXJ2ZVF1b3RhKCBxdW90YVNlcnZpY2U6IFF1b3RhU2VydmljZSxcbiAgb3JnSWQ6IHN0cmluZyxcbiAgcXVvdGFUeXBlOiBRdW90YVR5cGUsXG4gIGF1dGhIZWFkZXI6IHN0cmluZyxcbiAgYW1vdW50OiBudW1iZXIgPSAxLFxuICByZXF1ZXN0SWQ/OiBzdHJpbmcsXG4pOiBQcm9taXNlPFF1b3RhUmVzZXJ2ZVJlc3VsdD4ge1xuICByZXR1cm4gcXVvdGFTZXJ2aWNlLnJlc2VydmUob3JnSWQsIHF1b3RhVHlwZSwgYXV0aEhlYWRlciwgYW1vdW50LCByZXF1ZXN0SWQpO1xufVxuXG4vKipcbiAqIEZpcmUtYW5kLWZvcmdldCByb2xsYmFjayBmb3IgYSBwcmV2aW91c2x5IHJlc2VydmVkIHF1b3RhIHNsb3QuXG4gKiBMb2dzIG9uIGZhaWx1cmUgYnV0IG5ldmVyIHRocm93cyAgdGhlIGFjdGlvbiB0aGF0IG5lZWRlZCB0aGUgcm9sbGJhY2tcbiAqIGhhcyBhbHJlYWR5IGZhaWxlZCwgbm8gcG9pbnQgY29tcG91bmRpbmcgdGhlIGVycm9yLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZGVjcmVtZW50UXVvdGEoIHF1b3RhU2VydmljZTogUXVvdGFTZXJ2aWNlLFxuICBvcmdJZDogc3RyaW5nLFxuICBxdW90YVR5cGU6IFF1b3RhVHlwZSxcbiAgYXV0aEhlYWRlcjogc3RyaW5nLFxuICBsb2dXYXJuOiAobWVzc2FnZTogc3RyaW5nLCBkYXRhPzogdW5rbm93bikgPT4gdm9pZCxcbiAgYW1vdW50OiBudW1iZXIgPSAxLFxuICByZXNldEF0U25hcHNob3Q/OiBzdHJpbmcsXG4pOiB2b2lkIHtcbiAgcXVvdGFTZXJ2aWNlLmRlY3JlbWVudChvcmdJZCwgcXVvdGFUeXBlLCBhdXRoSGVhZGVyLCBhbW91bnQsIHJlc2V0QXRTbmFwc2hvdCkuY2F0Y2goKGVycjogdW5rbm93bikgPT5cbiAgICBsb2dXYXJuKCdRdW90YSByb2xsYmFjayBmYWlsZWQnLCB7IGVycm9yOiBlcnIgaW5zdGFuY2VvZiBFcnJvciA/IGVyci5tZXNzYWdlOiBTdHJpbmcoZXJyKSB9KSxcbiAgKTtcbn1cbiJdfQ==
300
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicXVvdGEuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2VydmljZXMvcXVvdGEudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLHNDQUFzQztBQUl0QyxPQUFPLEVBQUUsZ0JBQWdCLEVBQXVCLE1BQU0sa0JBQWtCLENBQUM7QUFDekUsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFFN0QsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ3BELE9BQU8sRUFBRSxZQUFZLEVBQUUsV0FBVyxFQUFrQixNQUFNLHlCQUF5QixDQUFDO0FBQ3BGLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUNsRCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDekQsT0FBTyxFQUFFLFNBQVMsRUFBRSxpQkFBaUIsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBRXBFLG1HQUFtRztBQUNuRyxNQUFNLHFCQUFxQixHQUErRDtJQUN4RixtQkFBbUIsRUFBRSxDQUFDO0lBQ3RCLFVBQVUsRUFBRSxDQUFDO0NBQ2QsQ0FBQztBQUVGLE1BQU0sTUFBTSxHQUFHLFlBQVksQ0FBQyxPQUFPLENBQUMsQ0FBQztBQUVyQywrQ0FBK0M7QUFDL0MsRUFBRTtBQUNGLDhFQUE4RTtBQUM5RSxnRkFBZ0Y7QUFDaEYsK0VBQStFO0FBQy9FLDRFQUE0RTtBQUM1RSx5RUFBeUU7QUFDekUsZ0ZBQWdGO0FBQ2hGLGlGQUFpRjtBQUNqRixvRUFBb0U7QUFDcEUsbUVBQW1FO0FBQ25FLDJFQUEyRTtBQUMzRSw0RUFBNEU7QUFDNUUsNEVBQTRFO0FBQzVFLGdGQUFnRjtBQUNoRiwrRUFBK0U7QUFDL0UsTUFBTSx1QkFBdUIsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLHVCQUF1QixLQUFLLE1BQU0sQ0FBQztBQUUvRTs7Ozs7Ozs7Ozs7R0FXRztBQUNILE1B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b250cmlidXRvcnNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5cbmltcG9ydCB0eXBlIHsgUmVzcG9uc2UgfSBmcm9tICdleHByZXNzJztcblxuaW1wb3J0IHsgY3JlYXRlU2FmZUNsaWVudCwgdHlwZSBSZXF1ZXN0T3B0aW9ucyB9IGZyb20gJy4vaHR0cC1jbGllbnQuanMnO1xuaW1wb3J0IHsgZ2V0U2VydmljZUF1dGhIZWFkZXIgfSBmcm9tICcuLi9taWRkbGV3YXJlL2F1dGguanMnO1xuaW1wb3J0IHR5cGUgeyBRdW90YVR5cGUsIFF1b3RhQ2hlY2tSZXN1bHQsIFNlcnZpY2VDb25maWcgfSBmcm9tICcuLi90eXBlcy9jb21tb24uanMnO1xuaW1wb3J0IHsgRXJyb3JDb2RlIH0gZnJvbSAnLi4vdHlwZXMvZXJyb3ItY29kZXMuanMnO1xuaW1wb3J0IHsgREVGQVVMVF9USUVSLCBpc1ZhbGlkVGllciwgdHlwZSBRdW90YVRpZXIgfSBmcm9tICcuLi90eXBlcy9xdW90YS10aWVycy5qcyc7XG5pbXBvcnQgeyBjcmVhdGVMb2dnZXIgfSBmcm9tICcuLi91dGlscy9sb2dnZXIuanMnO1xuaW1wb3J0IHsgZW1pdENvdW50ZXIgfSBmcm9tICcuLi91dGlscy9tZXRyaWMtZW1pdHRlci5qcyc7XG5pbXBvcnQgeyBzZW5kRXJyb3IsIHNlbmRRdW90YUV4Y2VlZGVkIH0gZnJvbSAnLi4vdXRpbHMvcmVzcG9uc2UuanMnO1xuXG4vKiogUmV0cnkgb3B0aW9ucyBmb3IgcXVvdGEgY2FsbHMg4oCUIGZhaWwgZmFzdCAoYSBzbG93IHF1b3RhIHNlcnZpY2UgbXVzdCBub3Qgc3RhbGwgdGhlIHJlcXVlc3QpLiAqL1xuY29uc3QgUVVPVEFfUkVRVUVTVF9PUFRJT05TOiBQaWNrPFJlcXVlc3RPcHRpb25zLCAnbWF4UmF0ZUxpbWl0UmV0cmllcycgfCAnbWF4UmV0cmllcyc+ID0ge1xuICBtYXhSYXRlTGltaXRSZXRyaWVzOiAxLFxuICBtYXhSZXRyaWVzOiAxLFxufTtcblxuY29uc3QgbG9nZ2VyID0gY3JlYXRlTG9nZ2VyKCdxdW90YScpO1xuXG4vLyBSRVNFUlZFIEZBSUwgTU9ERSDigJQgZXhwbGljaXQsIHNpbmdsZSBwb2xpY3kuXG4vL1xuLy8gYHJlc2VydmVgIGdhdGVzIEVYUEVOU0lWRSwgYmlsbGFibGUgcmVzb3VyY2VzIChwaXBlbGluZXMsIHBsdWdpbiBidWlsZHMsIEFJXG4vLyBjYWxscywgcGxhdGZvcm0gZmVhdHVyZSBzbG90cykuIEV2ZXJ5IHF1b3RhIHR5cGUgaXMgYSBwZXItcGVyaW9kIEZMT1cgY291bnRlclxuLy8gd2l0aCBubyBhZnRlci10aGUtZmFjdCByZWNvbmNpbGlhdGlvbjogYSB1bml0IGNvbnN1bWVkIHdoaWxlIHRoZSByZXNlcnZhdGlvblxuLy8gY291bGQgbm90IGJlIGNvbmZpcm1lZCBpcyBuZXZlciBjb3VudGVkLCBzbyBmYWlsLW9wZW4gbGV0cyBhbiBvcmcgY29uc3VtZVxuLy8gdW5ib3VuZGVkIHVubWV0ZXJlZCB1bml0cyBmb3IgdGhlIHdob2xlIGxlbmd0aCBvZiBhbiBpbmNpZGVudCDigJQgYW5kIGFuXG4vLyB1bmNvbmZpcm1lZCByZXNlcnZlICh0aW1lb3V0LCBvcGVuIGNpcmN1aXQpIG1heSBldmVuIGhhdmUgbGFuZGVkIHNlcnZlci1zaWRlLlxuLy8gU28gYHJlc2VydmVgIGZhaWxzIENMT1NFRCB3aGVuZXZlciB0aGUgcXVvdGEgc2VydmljZSBkaWQgbm90IENPTkZJUk0gdGhlIHNsb3Q6XG4vLyAgIC0gdW5yZWFjaGFibGUgLyB0aW1lZCBvdXQgLyBjaXJjdWl0IGJyZWFrZXIgb3BlbiAobm8gcmVzcG9uc2UpLFxuLy8gICAtIGEgcmVhY2hhYmxlLWJ1dC1lcnJvcmVkIHJlc3BvbnNlICg1eHgsIDR4eCwgbWFsZm9ybWVkIGJvZHkpLFxuLy8gICAtIGEgNDI5IHRoYXQgaXMgTk9UIGEgZ2VudWluZSBRVU9UQV9FWENFRURFRCAoZ2F0ZXdheSAvIHJhdGUgbGltaXRlcikuXG4vLyBPcGVyYXRvcnMgd2hvIHByZWZlciBhdmFpbGFiaWxpdHkgb3ZlciBlbmZvcmNlbWVudCBvcHQgdGhlIFdIT0xFIHNldCBpbnRvXG4vLyBmYWlsLW9wZW4gd2l0aCBRVU9UQV9SRVNFUlZFX0ZBSUxfT1BFTj10cnVlLiBCb3RoIG91dGNvbWVzIGVtaXQgYSBjb3VudGVyXG4vLyAoYHF1b3RhX2ZhaWxfY2xvc2VkX3RvdGFsYCAvIGBxdW90YV9mYWlsX29wZW5fdG90YWxgKSB0YWdnZWQgd2l0aCB0aGUgcmVhc29uLlxuLy8gYGNoZWNrYCAoYSBjaGVhcCByZWFkIGdhdGUpIHN0YXlzIGZhaWwtb3BlbjsgYGluY3JlbWVudGAgaXMgZmlyZS1hbmQtZm9yZ2V0LlxuY29uc3QgUVVPVEFfUkVTRVJWRV9GQUlMX09QRU4gPSBwcm9jZXNzLmVudi5RVU9UQV9SRVNFUlZFX0ZBSUxfT1BFTiA9PT0gJ3RydWUnO1xuXG4vKipcbiAqIFNlcnZpY2UtcHJpbmNpcGFsIGBBdXRob3JpemF0aW9uYCBoZWFkZXIgZm9yIGEgcXVvdGEgY2FsbCBtYWRlIG9uIGJlaGFsZiBvZlxuICogYG9yZ0lkYCBieSB0aGUgQ1VSUkVOVCBzZXJ2aWNlIChgU0VSVklDRV9OQU1FYCwgdGhlIHNhbWUgaWRlbnRpdHkgdGhlIGhlYWx0aFxuICogcm91dGVyIHJlcG9ydHMpLlxuICpcbiAqIFRoZSBxdW90YSBzZXJ2aWNlJ3MgbXV0YXRpb24gZW5kcG9pbnRzIChgLzpvcmdJZC9pbmNyZW1lbnRgLCBgL2RlY3JlbWVudGApXG4gKiByZWplY3QgYW55dGhpbmcgYnV0IGEgc2lnbmVkIHNlcnZpY2UgcHJpbmNpcGFsIG9yIGEgc3lzdGVtIGFkbWluLCBzb1xuICogZm9yd2FyZGluZyB0aGUgZW5kIHVzZXIncyBiZWFyZXIgdG9rZW4gdGhlcmUgaXMgYWx3YXlzIGEgNDAzLiBTZXJ2aWNlIHRva2Vuc1xuICogYXJlIGFsc28gZXhlbXB0IGZyb20gdGhlIHF1b3RhIHNlcnZpY2UncyBwZXItSVAgcmF0ZSBsaW1pdGVyLCBzbyBob3QtcGF0aFxuICogcXVvdGEgdHJhZmZpYyBmcm9tIGEgYnVzeSBwb2QgY2FuJ3QgZXhoYXVzdCB0aGF0IHBvZCBJUCdzIGJ1Y2tldCBhbmQgc2lsZW50bHlcbiAqIHR1cm4gZW5mb3JjZW1lbnQgb2ZmLiBTY29wZWQgdG8gdGhlIHRhcmdldCBvcmcgd2l0aCB0aGUgbG93ZXN0IHJvbGUgKG1lbWJlcikuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRRdW90YVNlcnZpY2VBdXRoSGVhZGVyKG9yZ0lkOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gZ2V0U2VydmljZUF1dGhIZWFkZXIoeyBzZXJ2aWNlTmFtZTogcHJvY2Vzcy5lbnYuU0VSVklDRV9OQU1FIHx8ICdhcGknLCBvcmdJZCwgcm9sZTogJ21lbWJlcicgfSk7XG59XG5cbi8qKlxuICogUmVzdWx0IG9mIGEgc3luY2hyb25vdXMgcXVvdGEgcmVzZXJ2YXRpb24gIHRoZSBhdG9taWMgY2hlY2sraW5jcmVtZW50XG4gKiB2YXJpYW50LiBgZXhjZWVkZWQ6IHRydWVgIG1lYW5zIHRoZSBvcGVyYXRpb24gd2FzIHJlamVjdGVkIGF0IHRoZSBEQlxuICogbGV2ZWw7IHRoZSBjYWxsZXIgc2hvdWxkIHJldHVybiA0Mjkgd2l0aG91dCBydW5uaW5nIHRoZSBnYXRlZCBhY3Rpb24uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUXVvdGFSZXNlcnZlUmVzdWx0IHtcbiAgLyoqIFRydWUgd2hlbiB0aGUgc2xvdCB3YXMgTk9UIHJlc2VydmVkIOKAlCB0aGUgZ2F0ZWQgYWN0aW9uIG11c3Qgbm90IHJ1bi4gKi9cbiAgZXhjZWVkZWQ6IGJvb2xlYW47XG4gIC8qKlxuICAgKiBTZXQgKHRydWUpIGJ5IHRoZSBxdW90YSBDTElFTlQgd2hlbiB0aGUgcmVzZXJ2YXRpb24gd2FzIGRlbmllZCBiZWNhdXNlIHRoZVxuICAgKiBxdW90YSBzZXJ2aWNlIGNvdWxkIG5vdCBDT05GSVJNIGl0ICh1bnJlYWNoYWJsZSAvIHRpbWVvdXQgLyBjaXJjdWl0IG9wZW4gL1xuICAgKiBlcnJvcmVkKSDigJQgbm90IGJlY2F1c2UgdGhlIG9yZyBpcyBvdmVyIGl0cyBsaW1pdC4gQWx3YXlzIHBhaXJlZCB3aXRoXG4gICAqIGBleGNlZWRlZDogdHJ1ZWAuIEFuc3dlciB3aXRoIHtAbGluayBzZW5kUXVvdGFSZXNlcnZlRGVuaWVkfSwgd2hpY2ggbWFwcyBpdCB0b1xuICAgKiA1MDMgaW5zdGVhZCBvZiBhIG1pc2xlYWRpbmcgNDI5IFwicXVvdGEgZXhjZWVkZWRcIi5cbiAgICovXG4gIHVuYXZhaWxhYmxlPzogYm9vbGVhbjtcbiAgcXVvdGE6IHtcbiAgICB0eXBlOiBRdW90YVR5cGU7XG4gICAgbGltaXQ6IG51bWJlcjtcbiAgICB1c2VkOiBudW1iZXI7XG4gICAgcmVtYWluaW5nOiBudW1iZXI7XG4gICAgcmVzZXRBdD86IHN0cmluZztcbiAgfTtcbn1cblxuLyoqXG4gKiBRdW90YSBzZXJ2aWNlIGNsaWVudCBpbnRlcmZhY2UuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUXVvdGFTZXJ2aWNlIHtcbiAgLyoqIENoZWNrIGlmIHF1b3RhIGlzIGF2YWlsYWJsZSAoZmFpbC1vcGVuIG9uIGVycm9yKS4gKi9cbiAgY2hlY2sob3JnSWQ6IHN0cmluZywgcXVvdGFUeXBlOiBRdW90YVR5cGUsIGF1dGhIZWFkZXI6IHN0cmluZywgcmVxdWVzdElkPzogc3RyaW5nKTogUHJvbWlzZTxRdW90YUNoZWNrUmVzdWx0PjtcbiAgLyoqIEluY3JlbWVudCBxdW90YSB1c2FnZS4gUmV0dXJucyBhIHByb21pc2Ugc28gY2FsbGVycyBjYW4gb3B0aW9uYWxseSBoYW5kbGUgZXJyb3JzLiAqL1xuICBpbmNyZW1lbnQob3JnSWQ6IHN0cmluZywgcXVvdGFUeXBlOiBRdW90YVR5cGUsIGF1dGhIZWFkZXI6IHN0cmluZywgYW1vdW50PzogbnVtYmVyLCByZXF1ZXN0SWQ/OiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+O1xuICAvKipcbiAgICogQXRvbWljIHJlc2VydmUgIHRoZSBzYW1lIGF0b21pYyBjaGVjaytpbmNyZW1lbnQgYXMgYGluY3JlbWVudGAsIGJ1dFxuICAgKiBwYXJzZXMgdGhlIHJlc3BvbnNlIHNvIGNhbGxlcnMgY2FuIHNlZSB3aGV0aGVyIHRoZSBzbG90IHdhcyBhY3R1YWxseVxuICAgKiByZXNlcnZlZC4gVXNlIHRoaXMgZm9yIGV4cGVuc2l2ZSByZXNvdXJjZXMgd2hlcmUgdGhlIHBvc3QtaG9jIGZpcmUtXG4gICAqIGFuZC1mb3JnZXQgcGF0dGVybiBhbGxvd3MgY29uY3VycmVudCBvdmVyLXNwZW5kLlxuICAgKlxuICAgKiBGYWlscyBDTE9TRUQgKGBleGNlZWRlZDogdHJ1ZWApIHdoZW5ldmVyIHRoZSBzbG90IGlzIG5vdCBjb25maXJtZWQg4oCUXG4gICAqIHVucmVhY2hhYmxlLCB0aW1lb3V0LCBvcGVuIGNpcmN1aXQsIG5vbi1vaywgb3IgYSBub24tcXVvdGEgNDI5IOKAlCB1bmxlc3NcbiAgICogYFFVT1RBX1JFU0VSVkVfRkFJTF9PUEVOPXRydWVgIChzZWUgdGhlIHBvbGljeSBub3RlIGF0IHRoZSB0b3Agb2YgdGhpcyBmaWxlKS5cbiAgICovXG4gIHJlc2VydmUob3JnSWQ6IHN0cmluZywgcXVvdGFUeXBlOiBRdW90YVR5cGUsIGF1dGhIZWFkZXI6IHN0cmluZywgYW1vdW50PzogbnVtYmVyLCByZXF1ZXN0SWQ/OiBzdHJpbmcpOiBQcm9taXNlPFF1b3RhUmVzZXJ2ZVJlc3VsdD47XG4gIC8qKlxuICAgKiBSb2xsIGJhY2sgYSBwcmV2aW91c2x5IHJlc2VydmVkIHNsb3QuIEZpcmUtYW5kLWZvcmdldCDigJQgbmV2ZXIgdGhyb3dzLlxuICAgKiBQYXNzIGByZXNldEF0U25hcHNob3RgICh0aGUgYHF1b3RhLnJlc2V0QXRgIG9ic2VydmVkIHdoZW4gdGhlIHNsb3Qgd2FzXG4gICAqIHJlc2VydmVkKSB0byBtYWtlIHRoZSByb2xsYmFjayBjb25kaXRpb25hbDogaWYgdGhlIHBlcmlvZCByb2xsZWQgb3ZlclxuICAgKiBiZXR3ZWVuIHJlc2VydmUgYW5kIHJvbGxiYWNrLCB0aGUgc2VydmVyIHNraXBzIHRoZSBkZWNyZW1lbnQgc28gaXQgZG9lc24ndFxuICAgKiBzdGVhbCBjYXBhY2l0eSBmcm9tIHRoZSBuZXcgcGVyaW9kLlxuICAgKi9cbiAgZGVjcmVtZW50KG9yZ0lkOiBzdHJpbmcsIHF1b3RhVHlwZTogUXVvdGFUeXBlLCBhdXRoSGVhZGVyOiBzdHJpbmcsIGFtb3VudD86IG51bWJlciwgcmVzZXRBdFNuYXBzaG90Pzogc3RyaW5nLCByZXF1ZXN0SWQ/OiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+O1xuICAvKiogVXBkYXRlIHF1b3RhIGxpbWl0cy4gUmV0dXJucyB0cnVlIG9uIHN1Y2Nlc3MuICovXG4gIHVwZGF0ZUxpbWl0cyhvcmdJZDogc3RyaW5nLCBsaW1pdHM6IFBhcnRpYWw8UmVjb3JkPFF1b3RhVHlwZSwgbnVtYmVyPj4sIGF1dGhIZWFkZXI6IHN0cmluZywgcmVxdWVzdElkPzogc3RyaW5nKTogUHJvbWlzZTxib29sZWFuPjtcbiAgLyoqIFJlc2V0IHF1b3RhIHVzYWdlLiBSZXR1cm5zIHRydWUgb24gc3VjY2Vzcy4gKi9cbiAgcmVzZXQob3JnSWQ6IHN0cmluZywgcXVvdGFUeXBlPzogUXVvdGFUeXBlLCBhdXRoSGVhZGVyPzogc3RyaW5nLCByZXF1ZXN0SWQ/OiBzdHJpbmcpOiBQcm9taXNlPGJvb2xlYW4+O1xuICAvKipcbiAgICogR2V0IHRoZSBvcmcncyBxdW90YSBgUXVvdGFUaWVyYC4gVXNlZCBieSB0aGUgcGx1Z2luLWJ1aWxkIHF1ZXVlIHBhcnRpdGlvbmluZ1xuICAgKiB0byByb3V0ZSBhIGJ1aWxkIHRvIHRoZSByaWdodCBwZXItdGllciBxdWV1ZS4gRmFpbC1vcGVuIHJldHVybnMgYERFRkFVTFRfVElFUmBcbiAgICogKGBkZXZlbG9wZXJgIHdoZW4gYmlsbGluZyBpcyBlbmFibGVkLCBgdW5saW1pdGVkYCB3aGVuIGl0J3MgZGlzYWJsZWQpOyBhXG4gICAqIG1pc2NsYXNzaWZpZWQgb3JnIHN0aWxsIGJ1aWxkcyBvbiB0aGUgZGVmYXVsdCBxdWV1ZSwganVzdCB3aXRob3V0IHRoZVxuICAgKiB0aWVyLXNjb3BlZCBzY2hlZHVsaW5nIGJvb3N0LlxuICAgKi9cbiAgZ2V0VGllcihvcmdJZDogc3RyaW5nLCBhdXRoSGVhZGVyOiBzdHJpbmcsIHJlcXVlc3RJZD86IHN0cmluZyk6IFByb21pc2U8UXVvdGFUaWVyPjtcbn1cblxuLyoqXG4gKiBDb25maWd1cmF0aW9uIGZvciBxdW90YSBzZXJ2aWNlIGNsaWVudC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBRdW90YVNlcnZpY2VDb25maWcge1xuICAvKiogUXVvdGEgc2VydmljZSBob3N0IChkZWZhdWx0OiBlbnYgUVVPVEFfU0VSVklDRV9IT1NUIG9yICdxdW90YScpICovXG4gIGhvc3Q/OiBzdHJpbmc7XG4gIC8qKiBRdW90YSBzZXJ2aWNlIHBvcnQgKGRlZmF1bHQ6IGVudiBRVU9UQV9TRVJWSUNFX1BPUlQgb3IgMzAwMCkgKi9cbiAgcG9ydD86IG51bWJlcjtcbiAgLyoqIFJlcXVlc3QgdGltZW91dCBpbiBtaWxsaXNlY29uZHMgKGRlZmF1bHQ6IDUwMDApICovXG4gIHRpbWVvdXQ/OiBudW1iZXI7XG59XG5cbi8qKlxuICogQXBwbHkgdGhlIGV4cGxpY2l0IHJlc2VydmUgZmFpbC1tb2RlIHBvbGljeSB0byBhIHJlc2VydmF0aW9uIHRoZSBxdW90YSBzZXJ2aWNlXG4gKiBkaWQgTk9UIGNvbmZpcm0gKHNlZSBRVU9UQV9SRVNFUlZFX0ZBSUxfT1BFTiBhYm92ZSkuIERlZmF1bHQ6IGRlbnkuXG4gKi9cbmZ1bmN0aW9uIHVuY29uZmlybWVkUmVzZXJ2ZShcbiAgb3JnSWQ6IHN0cmluZyxcbiAgcXVvdGFUeXBlOiBRdW90YVR5cGUsXG4gIHJlYXNvbjogJ3VucmVhY2hhYmxlJyB8ICd0cmFuc2llbnQtNDI5JyB8ICdub24tb2snLFxuICBzdGF0dXNDb2RlPzogbnVtYmVyLFxuKTogUXVvdGFSZXNlcnZlUmVzdWx0IHtcbiAgaWYgKFFVT1RBX1JFU0VSVkVfRkFJTF9PUEVOKSB7XG4gICAgbG9nZ2VyLndhcm4oJ1FVT1RBX0ZBSUxfT1BFTjogcXVvdGEgcmVzZXJ2ZSBub3QgY29uZmlybWVkLCBhbGxvd2luZyByZXF1ZXN0JywgeyBvcmdJZCwgcXVvdGFUeXBlLCByZWFzb24sIHN0YXR1c0NvZGUgfSk7XG4gICAgZW1pdENvdW50ZXIoJ3F1b3RhX2ZhaWxfb3Blbl90b3RhbCcsIHsgb3BlcmF0aW9uOiAncmVzZXJ2ZScsIHJlYXNvbiwgcXVvdGFUeXBlIH0pO1xuICAgIHJldHVybiB7IGV4Y2VlZGVkOiBmYWxzZSwgcXVvdGE6IHsgdHlwZTogcXVvdGFUeXBlLCBsaW1pdDogLTEsIHVzZWQ6IDAsIHJlbWFpbmluZzogLTEgfSB9O1xuICB9XG4gIGxvZ2dlci53YXJuKCdRVU9UQV9GQUlMX0NMT1NFRDogcXVvdGEgcmVzZXJ2ZSBub3QgY29uZmlybWVkLCBkZW55aW5nIHJlcXVlc3QnLCB7IG9yZ0lkLCBxdW90YVR5cGUsIHJlYXNvbiwgc3RhdHVzQ29kZSB9KTtcbiAgZW1pdENvdW50ZXIoJ3F1b3RhX2ZhaWxfY2xvc2VkX3RvdGFsJywgeyBvcGVyYXRpb246ICdyZXNlcnZlJywgcmVhc29uLCBxdW90YVR5cGUgfSk7XG4gIHJldHVybiB7IGV4Y2VlZGVkOiB0cnVlLCB1bmF2YWlsYWJsZTogdHJ1ZSwgcXVvdGE6IHsgdHlwZTogcXVvdGFUeXBlLCBsaW1pdDogMCwgdXNlZDogMCwgcmVtYWluaW5nOiAwIH0gfTtcbn1cblxuLyoqXG4gKiBDcmVhdGUgYSBmYWlsLW9wZW4gcXVvdGEgcmVzdWx0IChhbGxvd3MgdGhlIHJlcXVlc3QpLlxuICovXG5mdW5jdGlvbiBjcmVhdGVGYWlsT3BlblJlc3VsdCgpOiBRdW90YUNoZWNrUmVzdWx0IHtcbiAgcmV0dXJuIHtcbiAgICBhbGxvd2VkOiB0cnVlLFxuICAgIGxpbWl0OiAtMSxcbiAgICB1c2VkOiAwLFxuICAgIHJlbWFpbmluZzogLTEsXG4gICAgcmVzZXRBdDogbmV3IERhdGUoKS50b0lTT1N0cmluZygpLFxuICAgIHVubGltaXRlZDogdHJ1ZSxcbiAgICAvLyBUYWcgdGhlIHNlbnRpbmVsIHNvIGZhaWwtY2xvc2VkIGNhbGxlcnMgY2FuIHRlbGwgYW4gb3V0YWdlIGFwYXJ0IGZyb20gYVxuICAgIC8vIHJlYWwgdW5saW1pdGVkICgtMSkgcmVhZGluZy4gUmVhbCBxdW90YSByZXN1bHRzIG5ldmVyIHNldCB0aGlzLlxuICAgIGZhaWxPcGVuOiB0cnVlLFxuICB9O1xufVxuXG4vKipcbiAqIEJ1aWxkIGNvbW1vbiByZXF1ZXN0IGhlYWRlcnMgd2l0aCBvcHRpb25hbCByZXF1ZXN0IElEIGZvciBkaXN0cmlidXRlZCB0cmFjaW5nLlxuICovXG5mdW5jdGlvbiBidWlsZEhlYWRlcnMob3JnSWQ6IHN0cmluZywgYXV0aEhlYWRlcj86IHN0cmluZywgcmVxdWVzdElkPzogc3RyaW5nKTogUmVjb3JkPHN0cmluZywgc3RyaW5nPiB7XG4gIGNvbnN0IGhlYWRlcnM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7ICd4LW9yZy1pZCc6IG9yZ0lkIH07XG4gIGlmIChhdXRoSGVhZGVyKSBoZWFkZXJzLkF1dGhvcml6YXRpb24gPSBhdXRoSGVhZGVyO1xuICBpZiAocmVxdWVzdElkKSBoZWFkZXJzWydYLVJlcXVlc3QtSWQnXSA9IHJlcXVlc3RJZDtcbiAgcmV0dXJuIGhlYWRlcnM7XG59XG5cbi8qKlxuICogQ3JlYXRlIGEgcXVvdGEgc2VydmljZSBjbGllbnQuXG4gKlxuICogQHBhcmFtIGNvbmZpZyAtIE9wdGlvbmFsIHNlcnZpY2UgY29uZmlndXJhdGlvblxuICogQHJldHVybnMgUXVvdGEgc2VydmljZSBjbGllbnRcbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgcXVvdGFTZXJ2aWNlID0gY3JlYXRlUXVvdGFTZXJ2aWNlKCk7XG4gKlxuICogLy8gQ2hlY2sgcXVvdGEgYmVmb3JlIHByb2Nlc3NpbmdcbiAqIGNvbnN0IHF1b3RhID0gYXdhaXQgcXVvdGFTZXJ2aWNlLmNoZWNrKG9yZ0lkLCAnYXBpQ2FsbHMnLCBhdXRoSGVhZGVyKTtcbiAqIGlmICghcXVvdGEuYWxsb3dlZCkge1xuICogcmV0dXJuIHJlcy5zdGF0dXMoNDI5KS5qc29uKHsgZXJyb3I6ICdRdW90YSBleGNlZWRlZCcgfSk7XG4gKiB9XG4gKlxuICogLy8gSW5jcmVtZW50IHF1b3RhIGFmdGVyIHN1Y2Nlc3NcbiAqIHF1b3RhU2VydmljZS5pbmNyZW1lbnQob3JnSWQsICdhcGlDYWxscycsIGF1dGhIZWFkZXIpLmNhdGNoKGVyciA9PiBsb2dnZXIud2FybignUXVvdGEgaW5jcmVtZW50IGZhaWxlZCcsIHsgZXJyb3I6IGVyciB9KSk7XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVF1b3RhU2VydmljZShjb25maWc6IFF1b3RhU2VydmljZUNvbmZpZyA9IHt9KTogUXVvdGFTZXJ2aWNlIHtcbiAgY29uc3Qgc2VydmljZUNvbmZpZzogU2VydmljZUNvbmZpZyA9IHtcbiAgICBob3N0OiBjb25maWcuaG9zdCA/PyBwcm9jZXNzLmVudi5RVU9UQV9TRVJWSUNFX0hPU1QgPz8gJ3F1b3RhJyxcbiAgICBwb3J0OiBjb25maWcucG9ydCA/PyBwYXJzZUludChwcm9jZXNzLmVudi5RVU9UQV9TRVJWSUNFX1BPUlQgPz8gJzMwMDAnLCAxMCksXG4gICAgdGltZW91dDogY29uZmlnLnRpbWVvdXQgPz8gNTAwMCxcbiAgfTtcblxuICBjb25zdCBjbGllbnQgPSBjcmVhdGVTYWZlQ2xpZW50KHNlcnZpY2VDb25maWcpO1xuXG4gIHJldHVybiB7XG4gICAgYXN5bmMgY2hlY2sob3JnSWQ6IHN0cmluZywgcXVvdGFUeXBlOiBRdW90YVR5cGUsIGF1dGhIZWFkZXI6IHN0cmluZywgcmVxdWVzdElkPzogc3RyaW5nKTogUHJvbWlzZTxRdW90YUNoZWNrUmVzdWx0PiB7XG4gICAgICBjb25zdCBwYXRoID0gYC9xdW90YXMvJHtlbmNvZGVVUklDb21wb25lbnQob3JnSWQpfS8ke2VuY29kZVVSSUNvbXBvbmVudChxdW90YVR5cGUpfWA7XG5cbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgY2xpZW50LmdldDx7XG4gICAgICAgIHN1Y2Nlc3M6IGJvb2xlYW47XG4gICAgICAgIGRhdGE/OiB7IHF1b3RhVHlwZTogc3RyaW5nOyBzdGF0dXM6IFF1b3RhQ2hlY2tSZXN1bHQgfTtcbiAgICAgICAgbWVzc2FnZT86IHN0cmluZztcbiAgICAgIH0+KHBhdGgsIHsgaGVhZGVyczogYnVpbGRIZWFkZXJzKG9yZ0lkLCBhdXRoSGVhZGVyLCByZXF1ZXN0SWQpLCAuLi5RVU9UQV9SRVFVRVNUX09QVElPTlMgfSk7XG5cbiAgICAgIGlmICghcmVzcG9uc2UpIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oJ1FVT1RBX0ZBSUxfT1BFTjogUXVvdGEgc2VydmljZSB1bnJlYWNoYWJsZSwgYWxsb3dpbmcgcmVxdWVzdCcsIHsgb3JnSWQsIHF1b3RhVHlwZSB9KTtcbiAgICAgICAgZW1pdENvdW50ZXIoJ3F1b3RhX2ZhaWxfb3Blbl90b3RhbCcsIHsgb3BlcmF0aW9uOiAnY2hlY2snLCByZWFzb246ICd1bnJlYWNoYWJsZScsIHF1b3RhVHlwZSB9KTtcbiAgICAgICAgcmV0dXJuIGNyZWF0ZUZhaWxPcGVuUmVzdWx0KCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChyZXNwb25zZS5zdGF0dXNDb2RlICE9PSAyMDAgfHwgIXJlc3BvbnNlLmJvZHkuc3VjY2VzcyB8fCAhcmVzcG9uc2UuYm9keS5kYXRhPy5zdGF0dXMpIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oJ1FVT1RBX0ZBSUxfT1BFTjogUXVvdGEgY2hlY2sgcmV0dXJuZWQgbm9uLW9rLCBhbGxvd2luZyByZXF1ZXN0Jywge1xuICAgICAgICAgIG9yZ0lkLCBxdW90YVR5cGUsIHN0YXR1c0NvZGU6IHJlc3BvbnNlLnN0YXR1c0NvZGUsIG1lc3NhZ2U6IHJlc3BvbnNlLmJvZHkubWVzc2FnZSxcbiAgICAgICAgfSk7XG4gICAgICAgIGVtaXRDb3VudGVyKCdxdW90YV9mYWlsX29wZW5fdG90YWwnLCB7IG9wZXJhdGlvbjogJ2NoZWNrJywgcmVhc29uOiAnbm9uLW9rJywgcXVvdGFUeXBlIH0pO1xuICAgICAgICByZXR1cm4gY3JlYXRlRmFpbE9wZW5SZXN1bHQoKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHJlc3BvbnNlLmJvZHkuZGF0YS5zdGF0dXM7XG4gICAgfSxcblxuICAgIGFzeW5jIGluY3JlbWVudChvcmdJZDogc3RyaW5nLCBxdW90YVR5cGU6IFF1b3RhVHlwZSwgYXV0aEhlYWRlcjogc3RyaW5nLCBhbW91bnQ6IG51bWJlciA9IDEsIHJlcXVlc3RJZD86IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgY29uc3QgcGF0aCA9IGAvcXVvdGFzLyR7ZW5jb2RlVVJJQ29tcG9uZW50KG9yZ0lkKX0vaW5jcmVtZW50YDtcblxuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBjbGllbnRcbiAgICAgICAgLnBvc3QocGF0aCwgeyBxdW90YVR5cGUsIGFtb3VudCB9LCB7IGhlYWRlcnM6IGJ1aWxkSGVhZGVycyhvcmdJZCwgYXV0aEhlYWRlciwgcmVxdWVzdElkKSwgLi4uUVVPVEFfUkVRVUVTVF9PUFRJT05TIH0pO1xuXG4gICAgICBpZiAoIXJlc3BvbnNlIHx8IHJlc3BvbnNlLnN0YXR1c0NvZGUgIT09IDIwMCkge1xuICAgICAgICBsb2dnZXIud2FybignRmFpbGVkIHRvIGluY3JlbWVudCBxdW90YScsIHtcbiAgICAgICAgICBvcmdJZCwgcXVvdGFUeXBlLCBhbW91bnQsIHN0YXR1c0NvZGU6IHJlc3BvbnNlPy5zdGF0dXNDb2RlLFxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGxvZ2dlci5kZWJ1ZygnUXVvdGEgaW5jcmVtZW50ZWQnLCB7IG9yZ0lkLCBxdW90YVR5cGUsIGFtb3VudCB9KTtcbiAgICAgIH1cbiAgICB9LFxuXG4gICAgYXN5bmMgcmVzZXJ2ZShvcmdJZDogc3RyaW5nLCBxdW90YVR5cGU6IFF1b3RhVHlwZSwgYXV0aEhlYWRlcjogc3RyaW5nLCBhbW91bnQ6IG51bWJlciA9IDEsIHJlcXVlc3RJZD86IHN0cmluZyk6IFByb21pc2U8UXVvdGFSZXNlcnZlUmVzdWx0PiB7XG4gICAgICBjb25zdCBwYXRoID0gYC9xdW90YXMvJHtlbmNvZGVVUklDb21wb25lbnQob3JnSWQpfS9pbmNyZW1lbnRgO1xuXG4gICAgICAvLyAyMDAgY2FycmllcyBgZGF0YS5xdW90YWA7IDQyOSAoUVVPVEFfRVhDRUVERUQpIGNhcnJpZXMgYGRldGFpbHMucXVvdGFgLlxuICAgICAgLy8gQm90aCBzaGFwZXMgYXJlIG5vcm1hbGl6ZWQgaW50byBRdW90YVJlc2VydmVSZXN1bHQuXG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGNsaWVudC5wb3N0PHtcbiAgICAgICAgc3VjY2VzczogYm9vbGVhbjtcbiAgICAgICAgZGF0YT86IHsgcXVvdGE/OiBRdW90YVJlc2VydmVSZXN1bHRbJ3F1b3RhJ10gfTtcbiAgICAgICAgZGV0YWlscz86IHsgcXVvdGE/OiBRdW90YVJlc2VydmVSZXN1bHRbJ3F1b3RhJ10gfTtcbiAgICAgICAgZXJyb3JDb2RlPzogc3RyaW5nO1xuICAgICAgfT4ocGF0aCwgeyBxdW90YVR5cGUsIGFtb3VudCB9LCB7IGhlYWRlcnM6IGJ1aWxkSGVhZGVycyhvcmdJZCwgYXV0aEhlYWRlciwgcmVxdWVzdElkKSwgLi4uUVVPVEFfUkVRVUVTVF9PUFRJT05TIH0pO1xuXG4gICAgICBpZiAoIXJlc3BvbnNlKSByZXR1cm4gdW5jb25maXJtZWRSZXNlcnZlKG9yZ0lkLCBxdW90YVR5cGUsICd1bnJlYWNoYWJsZScpO1xuXG4gICAgICBpZiAocmVzcG9uc2Uuc3RhdHVzQ29kZSA9PT0gNDI5KSB7XG4gICAgICAgIGNvbnN0IHEgPSByZXNwb25zZS5ib2R5LmRldGFpbHM/LnF1b3RhO1xuICAgICAgICAvLyBPbmx5IGEgR0VOVUlORSBxdW90YS1leGNlZWRlZCA0MjkgbWVhbnMgXCJvdmVyIHF1b3RhXCIuIEEgZ2VuZXJpYyA0Mjkg4oCUXG4gICAgICAgIC8vIGFuIGludGVydmVuaW5nIGdhdGV3YXkgb3IgcmF0ZSBsaW1pdGVyIOKAlCBkaWQgbm90IGNvbmZpcm0gYW55dGhpbmcsIHNvXG4gICAgICAgIC8vIGl0IGdvZXMgdGhyb3VnaCB0aGUgc2FtZSB1bmNvbmZpcm1lZC1yZXNlcnZhdGlvbiBwb2xpY3kgYXMgYW4gb3V0YWdlLlxuICAgICAgICBpZiAocmVzcG9uc2UuYm9keS5lcnJvckNvZGUgPT09ICdRVU9UQV9FWENFRURFRCcgfHwgcSkge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBleGNlZWRlZDogdHJ1ZSxcbiAgICAgICAgICAgIHF1b3RhOiBxID8/IHsgdHlwZTogcXVvdGFUeXBlLCBsaW1pdDogMCwgdXNlZDogMCwgcmVtYWluaW5nOiAwIH0sXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdW5jb25maXJtZWRSZXNlcnZlKG9yZ0lkLCBxdW90YVR5cGUsICd0cmFuc2llbnQtNDI5JywgcmVzcG9uc2Uuc3RhdHVzQ29kZSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChyZXNwb25zZS5zdGF0dXNDb2RlICE9PSAyMDAgfHwgIXJlc3BvbnNlLmJvZHkuc3VjY2Vzcykge1xuICAgICAgICByZXR1cm4gdW5jb25maXJtZWRSZXNlcnZlKG9yZ0lkLCBxdW90YVR5cGUsICdub24tb2snLCByZXNwb25zZS5zdGF0dXNDb2RlKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgcSA9IHJlc3BvbnNlLmJvZHkuZGF0YT8ucXVvdGE7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBleGNlZWRlZDogZmFsc2UsXG4gICAgICAgIHF1b3RhOiBxID8/IHsgdHlwZTogcXVvdGFUeXBlLCBsaW1pdDogLTEsIHVzZWQ6IDAsIHJlbWFpbmluZzogLTEgfSxcbiAgICAgIH07XG4gICAgfSxcblxuICAgIGFzeW5jIGRlY3JlbWVudChvcmdJZDogc3RyaW5nLCBxdW90YVR5cGU6IFF1b3RhVHlwZSwgYXV0aEhlYWRlcjogc3RyaW5nLCBhbW91bnQ6IG51bWJlciA9IDEsIHJlc2V0QXRTbmFwc2hvdD86IHN0cmluZywgcmVxdWVzdElkPzogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICBjb25zdCBwYXRoID0gYC9xdW90YXMvJHtlbmNvZGVVUklDb21wb25lbnQob3JnSWQpfS9kZWNyZW1lbnRgO1xuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBjbGllbnRcbiAgICAgICAgLnBvc3QocGF0aCwgeyBxdW90YVR5cGUsIGFtb3VudCwgLi4uKHJlc2V0QXRTbmFwc2hvdCAmJiB7IHJlc2V0QXRTbmFwc2hvdCB9KSB9LCB7IGhlYWRlcnM6IGJ1aWxkSGVhZGVycyhvcmdJZCwgYXV0aEhlYWRlciwgcmVxdWVzdElkKSwgLi4uUVVPVEFfUkVRVUVTVF9PUFRJT05TIH0pO1xuXG4gICAgICBpZiAoIXJlc3BvbnNlIHx8IHJlc3BvbnNlLnN0YXR1c0NvZGUgIT09IDIwMCkge1xuICAgICAgICAvLyBSb2xsYmFjayBmYWlsdXJlIGlzIGxvZ2dlZCBidXQgbmV2ZXIgcHJvcGFnYXRlZCAgdGhlIGFjdGlvbidzIG93blxuICAgICAgICAvLyBmYWlsdXJlIGhhcyBhbHJlYWR5IGJlZW4gc3VyZmFjZWQgdG8gdGhlIGNhbGxlcjsgYSBzdHVjayBjb3VudGVyXG4gICAgICAgIC8vIHJlc29sdmVzIG9uIHRoZSBuZXh0IHBlcmlvZCByZXNldC5cbiAgICAgICAgbG9nZ2VyLndhcm4oJ0ZhaWxlZCB0byBkZWNyZW1lbnQgcXVvdGEgKHNsb3Qgd2lsbCByZXNldCBvbiBuZXh0IHBlcmlvZCknLCB7XG4gICAgICAgICAgb3JnSWQsIHF1b3RhVHlwZSwgYW1vdW50LCBzdGF0dXNDb2RlOiByZXNwb25zZT8uc3RhdHVzQ29kZSxcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsb2dnZXIuZGVidWcoJ1F1b3RhIGRlY3JlbWVudGVkJywgeyBvcmdJZCwgcXVvdGFUeXBlLCBhbW91bnQgfSk7XG4gICAgICB9XG4gICAgfSxcblxuICAgIGFzeW5jIHVwZGF0ZUxpbWl0cyggb3JnSWQ6IHN0cmluZyxcbiAgICAgIGxpbWl0czogUGFydGlhbDxSZWNvcmQ8UXVvdGFUeXBlLCBudW1iZXI+PixcbiAgICAgIGF1dGhIZWFkZXI6IHN0cmluZyxcbiAgICAgIHJlcXVlc3RJZD86IHN0cmluZyxcbiAgICApOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICAgIGNvbnN0IHBhdGggPSBgL3F1b3Rhcy8ke2VuY29kZVVSSUNvbXBvbmVudChvcmdJZCl9YDtcblxuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBjbGllbnQucHV0KHBhdGgsIGxpbWl0cywgeyBoZWFkZXJzOiBidWlsZEhlYWRlcnMob3JnSWQsIGF1dGhIZWFkZXIsIHJlcXVlc3RJZCkgfSk7XG5cbiAgICAgIGlmICghcmVzcG9uc2UgfHwgcmVzcG9uc2Uuc3RhdHVzQ29kZSAhPT0gMjAwKSB7XG4gICAgICAgIGxvZ2dlci53YXJuKCdGYWlsZWQgdG8gdXBkYXRlIHF1b3RhIGxpbWl0cycsIHtcbiAgICAgICAgICBvcmdJZCwgbGltaXRzLCBzdGF0dXNDb2RlOiByZXNwb25zZT8uc3RhdHVzQ29kZSxcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgbG9nZ2VyLmluZm8oJ1F1b3RhIGxpbWl0cyB1cGRhdGVkJywgeyBvcmdJZCwgbGltaXRzIH0pO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSxcblxuICAgIGFzeW5jIGdldFRpZXIob3JnSWQ6IHN0cmluZywgYXV0aEhlYWRlcjogc3RyaW5nLCByZXF1ZXN0SWQ/OiBzdHJpbmcpOiBQcm9taXNlPFF1b3RhVGllcj4ge1xuICAgICAgY29uc3QgcGF0aCA9IGAvcXVvdGFzLyR7ZW5jb2RlVVJJQ29tcG9uZW50KG9yZ0lkKX1gO1xuXG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGNsaWVudC5nZXQ8e1xuICAgICAgICBzdWNjZXNzOiBib29sZWFuO1xuICAgICAgICBkYXRhPzogeyBxdW90YT86IHsgdGllcj86IHN0cmluZyB9IH07XG4gICAgICAgIG1lc3NhZ2U/OiBzdHJpbmc7XG4gICAgICB9PihwYXRoLCB7IGhlYWRlcnM6IGJ1aWxkSGVhZGVycyhvcmdJZCwgYXV0aEhlYWRlciwgcmVxdWVzdElkKSwgLi4uUVVPVEFfUkVRVUVTVF9PUFRJT05TIH0pO1xuXG4gICAgICBpZiAoIXJlc3BvbnNlIHx8IHJlc3BvbnNlLnN0YXR1c0NvZGUgIT09IDIwMCB8fCAhcmVzcG9uc2UuYm9keS5zdWNjZXNzKSB7XG4gICAgICAgIGxvZ2dlci53YXJuKGBRVU9UQV9GQUlMX09QRU46IHRpZXIgbG9va3VwIGZhaWxlZCwgZGVmYXVsdGluZyB0byAke0RFRkFVTFRfVElFUn0gdGllcmAsIHtcbiAgICAgICAgICBvcmdJZCwgc3RhdHVzQ29kZTogcmVzcG9uc2U/LnN0YXR1c0NvZGUsIGRlZmF1bHRUaWVyOiBERUZBVUxUX1RJRVIsXG4gICAgICAgIH0pO1xuICAgICAgICBlbWl0Q291bnRlcigncXVvdGFfZmFpbF9vcGVuX3RvdGFsJywgeyBvcGVyYXRpb246ICd0aWVyJywgcmVhc29uOiByZXNwb25zZSA/ICdub24tb2snIDogJ3VucmVhY2hhYmxlJywgcXVvdGFUeXBlOiAndGllcicgfSk7XG4gICAgICAgIHJldHVybiBERUZBVUxUX1RJRVI7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHRpZXIgPSByZXNwb25zZS5ib2R5LmRhdGE/LnF1b3RhPy50aWVyO1xuICAgICAgcmV0dXJuIHRpZXIgJiYgaXNWYWxpZFRpZXIodGllcikgPyB0aWVyOiBERUZBVUxUX1RJRVI7XG4gICAgfSxcblxuICAgIGFzeW5jIHJlc2V0KG9yZ0lkOiBzdHJpbmcsIHF1b3RhVHlwZT86IFF1b3RhVHlwZSwgYXV0aEhlYWRlcj86IHN0cmluZywgcmVxdWVzdElkPzogc3RyaW5nKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgICBjb25zdCBwYXRoID0gYC9xdW90YXMvJHtlbmNvZGVVUklDb21wb25lbnQob3JnSWQpfS9yZXNldGA7XG5cbiAgICAgIGNvbnN0IGJvZHkgPSBxdW90YVR5cGUgPyB7IHF1b3RhVHlwZSB9OiB7fTtcbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgY2xpZW50LnBvc3QocGF0aCwgYm9keSwgeyBoZWFkZXJzOiBidWlsZEhlYWRlcnMob3JnSWQsIGF1dGhIZWFkZXIgPz8gJycsIHJlcXVlc3RJZCkgfSk7XG5cbiAgICAgIGlmICghcmVzcG9uc2UgfHwgcmVzcG9uc2Uuc3RhdHVzQ29kZSAhPT0gMjAwKSB7XG4gICAgICAgIGxvZ2dlci53YXJuKCdGYWlsZWQgdG8gcmVzZXQgcXVvdGEnLCB7XG4gICAgICAgICAgb3JnSWQsIHF1b3RhVHlwZSwgc3RhdHVzQ29kZTogcmVzcG9uc2U/LnN0YXR1c0NvZGUsXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIGxvZ2dlci5pbmZvKCdRdW90YSByZXNldCcsIHsgb3JnSWQsIHF1b3RhVHlwZTogcXVvdGFUeXBlID8/ICdhbGwnIH0pO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSxcbiAgfTtcbn1cblxuLyoqXG4gKiBGaXJlLWFuZC1mb3JnZXQgcXVvdGEgTUVURVJJTkcgaW5jcmVtZW50IHdpdGggc3RhbmRhcmRpemVkIGVycm9yIGxvZ2dpbmcuXG4gKlxuICogQXV0aGVudGljYXRlcyBhcyB0aGUgY2FsbGluZyBTRVJWSUNFICh7QGxpbmsgZ2V0UXVvdGFTZXJ2aWNlQXV0aEhlYWRlcn0pLCBuZXZlclxuICogd2l0aCB0aGUgZW5kIHVzZXIncyB0b2tlbjogYC9xdW90YXMvOm9yZ0lkL2luY3JlbWVudGAgaXMgc2VydmljZS1wcmluY2lwYWwgL1xuICogc3lzdGVtLWFkbWluIG9ubHksIHNvIGEgZm9yd2FyZGVkIHVzZXIgSldUIHdhcyBhbHdheXMgcmVqZWN0ZWQgKDQwMykgYW5kIHRoZVxuICogbWV0ZXJlZCBxdW90YSAoZS5nLiBgYXBpQ2FsbHNgLCBhbmQgdGhlIGBhcGlfcGFja2AgYnVuZGxlIHJhaXNpbmcgaXQpIG5ldmVyXG4gKiBtb3ZlZC5cbiAqXG4gKiBAcGFyYW0gcXVvdGFTZXJ2aWNlIC0gUXVvdGEgc2VydmljZSBjbGllbnRcbiAqIEBwYXJhbSBvcmdJZCAtIE9yZ2FuaXphdGlvbiBJRCB3aG9zZSBjb3VudGVyIGlzIGluY3JlbWVudGVkXG4gKiBAcGFyYW0gcXVvdGFUeXBlIC0gUXVvdGEgdHlwZSB0byBpbmNyZW1lbnRcbiAqIEBwYXJhbSBsb2dXYXJuIC0gTG9nZ2luZyBmdW5jdGlvbiBmb3Igd2FybmluZ3NcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGluY3JlbWVudFF1b3RhKCBxdW90YVNlcnZpY2U6IFF1b3RhU2VydmljZSxcbiAgb3JnSWQ6IHN0cmluZyxcbiAgcXVvdGFUeXBlOiBRdW90YVR5cGUsXG4gIGxvZ1dhcm46IChtZXNzYWdlOiBzdHJpbmcsIGRhdGE/OiB1bmtub3duKSA9PiB2b2lkLFxuKTogdm9pZCB7XG4gIHF1b3RhU2VydmljZS5pbmNyZW1lbnQob3JnSWQsIHF1b3RhVHlwZSwgZ2V0UXVvdGFTZXJ2aWNlQXV0aEhlYWRlcihvcmdJZCkpLmNhdGNoKChlcnI6IHVua25vd24pID0+XG4gICAgbG9nV2FybignUXVvdGEgaW5jcmVtZW50IGZhaWxlZCcsIHsgZXJyb3I6IGVyciBpbnN0YW5jZW9mIEVycm9yID8gZXJyLm1lc3NhZ2U6IFN0cmluZyhlcnIpIH0pLFxuICApO1xufVxuXG4vKipcbiAqIEF0b21pYyByZXNlcnZlIGhlbHBlciBmb3IgdGhlIFwicmVzZXJ2ZSArIGNvbW1pdCAvIHJvbGxiYWNrXCIgcGF0dGVybi5cbiAqIFVzZSBmb3IgZXhwZW5zaXZlIHJlc291cmNlcyAocGlwZWxpbmVzLCBwbHVnaW5zLCBBSSBjYWxscykgd2hlcmUgdGhlXG4gKiBmaXJlLWFuZC1mb3JnZXQgcG9zdC1ob2MgYGluY3JlbWVudFF1b3RhYCBhbGxvd3MgY29uY3VycmVudCBvdmVyLXNwZW5kLlxuICpcbiAqIFJldHVybnMgdGhlIHN0cnVjdHVyZWQgcmVzdWx0IHNvIHRoZSBjYWxsZXIgY2FuIGRlY2lkZSB3aGV0aGVyIHRvIHJ1blxuICogdGhlIGdhdGVkIGFjdGlvbiBvciA0MjkgdGhlIGNsaWVudC5cbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgcmVzZXJ2YXRpb24gPSBhd2FpdCByZXNlcnZlUXVvdGEocXVvdGFTZXJ2aWNlLCBvcmdJZCwgJ3BpcGVsaW5lcycsIGF1dGhIZWFkZXIpO1xuICogaWYgKHJlc2VydmF0aW9uLmV4Y2VlZGVkKSByZXR1cm4gc2VuZFF1b3RhUmVzZXJ2ZURlbmllZChyZXMsICdwaXBlbGluZXMnLCByZXNlcnZhdGlvbik7XG4gKiB0cnkge1xuICogYXdhaXQgZG9FeHBlbnNpdmVUaGluZygpO1xuICogfSBjYXRjaCAoZXJyKSB7XG4gKiAvLyBQYXNzIHRoZSByZXNlcnZlZCByZXNldEF0IHNvIGEgcGVyaW9kIHJvbGxvdmVyIGRvZXNuJ3QgZ2V0IGRvdWJsZS1jaGFyZ2VkLlxuICogZGVjcmVtZW50UXVvdGEocXVvdGFTZXJ2aWNlLCBvcmdJZCwgJ3BpcGVsaW5lcycsIGF1dGhIZWFkZXIsIGxvZ1dhcm4sIDEsIHJlc2VydmF0aW9uLnF1b3RhLnJlc2V0QXQpO1xuICogdGhyb3cgZXJyO1xuICogfVxuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNlcnZlUXVvdGEoIHF1b3RhU2VydmljZTogUXVvdGFTZXJ2aWNlLFxuICBvcmdJZDogc3RyaW5nLFxuICBxdW90YVR5cGU6IFF1b3RhVHlwZSxcbiAgYXV0aEhlYWRlcjogc3RyaW5nLFxuICBhbW91bnQ6IG51bWJlciA9IDEsXG4gIHJlcXVlc3RJZD86IHN0cmluZyxcbik6IFByb21pc2U8UXVvdGFSZXNlcnZlUmVzdWx0PiB7XG4gIHJldHVybiBxdW90YVNlcnZpY2UucmVzZXJ2ZShvcmdJZCwgcXVvdGFUeXBlLCBhdXRoSGVhZGVyLCBhbW91bnQsIHJlcXVlc3RJZCk7XG59XG5cbi8qKiBTZWNvbmRzIGEgY2xpZW50IHNob3VsZCB3YWl0IGJlZm9yZSByZXRyeWluZyB3aGVuIHF1b3RhIGNvdWxkbid0IGJlIGNvbmZpcm1lZC4gKi9cbmNvbnN0IFFVT1RBX1VOQVZBSUxBQkxFX1JFVFJZX0FGVEVSX1NFQ09ORFMgPSA1O1xuXG4vKipcbiAqIEFuc3dlciBhIERFTklFRCByZXNlcnZhdGlvbiAoYHJlc2VydmF0aW9uLmV4Y2VlZGVkID09PSB0cnVlYCkuXG4gKlxuICogLSBgdW5hdmFpbGFibGVgICh0aGUgcXVvdGEgc2VydmljZSBjb3VsZG4ndCBjb25maXJtIHRoZSBzbG90KSDihpIgKio1MDMqKlxuICogICBgU0VSVklDRV9VTkFWQUlMQUJMRWAgd2l0aCBhIHNob3J0IGBSZXRyeS1BZnRlcmA6IHRoZSBvcmcgaXMgbm90IG92ZXIgaXRzXG4gKiAgIGxpbWl0LCBzbyBhIDQyOSBcInF1b3RhIGV4Y2VlZGVkXCIgd291bGQgc2VuZCB1c2VycyB0byB1cGdyYWRlIGZvciBhbiBvdXRhZ2UuXG4gKiAtIG90aGVyd2lzZSDihpIgdGhlIHN0YW5kYXJkIDQyOSBgUVVPVEFfRVhDRUVERURgIHdpdGggdGhlIFgtUXVvdGEtKiBoZWFkZXJzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gc2VuZFF1b3RhUmVzZXJ2ZURlbmllZChyZXM6IFJlc3BvbnNlLCBxdW90YVR5cGU6IFF1b3RhVHlwZSwgcmVzZXJ2YXRpb246IFF1b3RhUmVzZXJ2ZVJlc3VsdCk6IHZvaWQge1xuICBpZiAocmVzZXJ2YXRpb24udW5hdmFpbGFibGUpIHtcbiAgICBpZiAoIXJlcy5oZWFkZXJzU2VudCkgcmVzLnNldEhlYWRlcignUmV0cnktQWZ0ZXInLCBRVU9UQV9VTkFWQUlMQUJMRV9SRVRSWV9BRlRFUl9TRUNPTkRTKTtcbiAgICBzZW5kRXJyb3IoXG4gICAgICByZXMsXG4gICAgICA1MDMsXG4gICAgICBgVW5hYmxlIHRvIGNvbmZpcm0gJHtxdW90YVR5cGV9IHF1b3RhIHJpZ2h0IG5vdy4gUGxlYXNlIHRyeSBhZ2FpbiBzaG9ydGx5LmAsXG4gICAgICBFcnJvckNvZGUuU0VSVklDRV9VTkFWQUlMQUJMRSxcbiAgICApO1xuICAgIHJldHVybjtcbiAgfVxuICBzZW5kUXVvdGFFeGNlZWRlZChyZXMsIHF1b3RhVHlwZSwgcmVzZXJ2YXRpb24ucXVvdGEsIHJlc2VydmF0aW9uLnF1b3RhLnJlc2V0QXQpO1xufVxuXG4vKipcbiAqIEZpcmUtYW5kLWZvcmdldCByb2xsYmFjayBmb3IgYSBwcmV2aW91c2x5IHJlc2VydmVkIHF1b3RhIHNsb3QuXG4gKiBMb2dzIG9uIGZhaWx1cmUgYnV0IG5ldmVyIHRocm93cyAgdGhlIGFjdGlvbiB0aGF0IG5lZWRlZCB0aGUgcm9sbGJhY2tcbiAqIGhhcyBhbHJlYWR5IGZhaWxlZCwgbm8gcG9pbnQgY29tcG91bmRpbmcgdGhlIGVycm9yLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZGVjcmVtZW50UXVvdGEoIHF1b3RhU2VydmljZTogUXVvdGFTZXJ2aWNlLFxuICBvcmdJZDogc3RyaW5nLFxuICBxdW90YVR5cGU6IFF1b3RhVHlwZSxcbiAgYXV0aEhlYWRlcjogc3RyaW5nLFxuICBsb2dXYXJuOiAobWVzc2FnZTogc3RyaW5nLCBkYXRhPzogdW5rbm93bikgPT4gdm9pZCxcbiAgYW1vdW50OiBudW1iZXIgPSAxLFxuICByZXNldEF0U25hcHNob3Q/OiBzdHJpbmcsXG4pOiB2b2lkIHtcbiAgcXVvdGFTZXJ2aWNlLmRlY3JlbWVudChvcmdJZCwgcXVvdGFUeXBlLCBhdXRoSGVhZGVyLCBhbW91bnQsIHJlc2V0QXRTbmFwc2hvdCkuY2F0Y2goKGVycjogdW5rbm93bikgPT5cbiAgICBsb2dXYXJuKCdRdW90YSByb2xsYmFjayBmYWlsZWQnLCB7IGVycm9yOiBlcnIgaW5zdGFuY2VvZiBFcnJvciA/IGVyci5tZXNzYWdlOiBTdHJpbmcoZXJyKSB9KSxcbiAgKTtcbn1cbiJdfQ==
@@ -43,7 +43,7 @@ export interface SseTicketStoreConfig {
43
43
  }
44
44
  /**
45
45
  * Build an {@link SseTicketStore} from the standard Redis env (`REDIS_URL` or
46
- * `REDIS_HOST`/`REDIS_PORT`). Uses the Redis backend when configured
46
+ * `REDIS_SENTINELS`). Uses the Redis backend when configured
47
47
  * (multi-replica safe), otherwise falls back to the in-memory single-process
48
48
  * backend. A service opts in with one boot line:
49
49
  * `const tickets = createEnvSseTicketStore({ ttlMs, maxTotal, maxPerOrg });`
@@ -113,7 +113,7 @@ function createRedisSseTicketStore(redis, config) {
113
113
  }
114
114
  /**
115
115
  * Build an {@link SseTicketStore} from the standard Redis env (`REDIS_URL` or
116
- * `REDIS_HOST`/`REDIS_PORT`). Uses the Redis backend when configured
116
+ * `REDIS_SENTINELS`). Uses the Redis backend when configured
117
117
  * (multi-replica safe), otherwise falls back to the in-memory single-process
118
118
  * backend. A service opts in with one boot line:
119
119
  * `const tickets = createEnvSseTicketStore({ ttlMs, maxTotal, maxPerOrg });`
@@ -127,4 +127,4 @@ export function createEnvSseTicketStore(config) {
127
127
  logger.info('SSE ticket store: in-memory backend (single-process fallback)');
128
128
  return createInMemorySseTicketStore(config);
129
129
  }
130
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3NlLXRpY2tldC1zdG9yZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zZXJ2aWNlcy9zc2UtdGlja2V0LXN0b3JlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUFFdEMsT0FBTyxNQUFNLE1BQU0sUUFBUSxDQUFDO0FBRTVCLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3RELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUVsRCxNQUFNLE1BQU0sR0FBRyxZQUFZLENBQUMsa0JBQWtCLENBQUMsQ0FBQztBQUVoRCxpRkFBaUY7QUFDakYsTUFBTSxpQkFBaUIsR0FBRyxTQUFTLENBQUM7QUFDcEMsTUFBTSxnQkFBZ0IsR0FBRyxVQUFVLENBQUM7QUFDcEMsTUFBTSxlQUFlLEdBQUcsaUJBQWlCLENBQUM7QUFrRDFDLFNBQVMsV0FBVztJQUNsQixPQUFPLE1BQU0sQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxDQUFDO0FBQ3RELENBQUM7QUFFRDs7OztHQUlHO0FBQ0gsU0FBUyw0QkFBNEIsQ0FBQyxNQUE0QjtJQUVoRSxNQUFNLEtBQUssR0FBRyxJQUFJLEdBQUcsRUFBaUIsQ0FBQztJQUV2QyxNQUFNLE9BQU8sR0FBRyxXQUFXLENBQUMsR0FBRyxFQUFFO1FBQy9CLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUN2QixLQUFLLE1BQU0sQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLElBQUksS0FBSztZQUFFLElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQyxTQUFTO2dCQUFFLEtBQUssQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDdkUsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNqQixPQUFPLENBQUMsS0FBSyxFQUFFLENBQUM7SUFFaEIsU0FBUyxlQUFlLENBQUMsS0FBYSxFQUFFLEdBQVc7UUFDakQsSUFBSSxLQUFLLEdBQUcsQ0FBQyxDQUFDO1FBQ2QsS0FBSyxNQUFNLENBQUMsSUFBSSxLQUFLLENBQUMsTUFBTSxFQUFFO1lBQUUsSUFBSSxDQUFDLENBQUMsS0FBSyxLQUFLLEtBQUssSUFBSSxDQUFDLENBQUMsU0FBUyxHQUFHLEdBQUc7Z0JBQUUsS0FBSyxFQUFFLENBQUM7UUFDcEYsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0lBRUQsT0FBTztRQUNMLEtBQUssQ0FBQyxLQUFLLENBQUMsS0FBYTtZQUN2QixNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7WUFDdkIsSUFBSSxLQUFLLENBQUMsSUFBSSxJQUFJLE1BQU0sQ0FBQyxRQUFRO2dCQUFFLE9BQU8sRUFBRSxFQUFFLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsQ0FBQztZQUN6RSxJQUFJLGVBQWUsQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLElBQUksTUFBTSxDQUFDLFNBQVM7Z0JBQUUsT0FBTyxFQUFFLEVBQUUsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxDQUFDO1lBQ3pGLE1BQU0sTUFBTSxHQUFHLFdBQVcsRUFBRSxDQUFDO1lBQzdCLEtBQUssQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBRSxHQUFHLEdBQUcsTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUM7WUFDNUQsT0FBTyxFQUFFLEVBQUUsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLENBQUM7UUFDOUIsQ0FBQztRQUNELEtBQUssQ0FBQyxPQUFPLENBQUMsUUFBZ0I7WUFDNUIsTUFBTSxDQUFDLEdBQUcsS0FBSyxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUM5QixLQUFLLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsbUNBQW1DO1lBQzNELElBQUksQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQyxTQUFTO2dCQUFFLE9BQU8sSUFBSSxDQUFDO1lBQ2hELE9BQU8sRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQzVCLENBQUM7UUFDRCxJQUFJLEtBQVcsYUFBYSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQztLQUN6QyxDQUFDO0FBQ0osQ0FBQztBQUVEOzs7Ozs7Ozs7Ozs7O0dBYUc7QUFDSCxTQUFTLHlCQUF5QixDQUFDLEtBQWUsRUFBRSxNQUE0QjtJQUM5RSxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQztJQUMzRCx5RUFBeUU7SUFDekUsTUFBTSxFQUFFLEdBQUcsTUFBTSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsU0FBUyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztJQUMxRCxNQUFNLFNBQVMsR0FBRyxDQUFDLENBQVMsRUFBRSxFQUFFLENBQUMsR0FBRyxFQUFFLEdBQUcsaUJBQWlCLEdBQUcsQ0FBQyxFQUFFLENBQUM7SUFDakUsTUFBTSxXQUFXLEdBQUcsQ0FBQyxDQUFTLEVBQUUsRUFBRSxDQUFDLEdBQUcsRUFBRSxHQUFHLGdCQUFnQixHQUFHLENBQUMsRUFBRSxDQUFDO0lBQ2xFLE1BQU0sYUFBYSxHQUFHLEdBQUcsRUFBRSxHQUFHLGVBQWUsRUFBRSxDQUFDO0lBRWhELDZFQUE2RTtJQUM3RSx3RUFBd0U7SUFDeEUsS0FBSyxVQUFVLFlBQVksQ0FBQyxHQUFXLEVBQUUsS0FBYTtRQUNwRCxNQUFNLENBQUMsR0FBRyxNQUFNLEtBQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDaEMsSUFBSSxDQUFDLEtBQUssQ0FBQztZQUFFLE1BQU0sS0FBSyxDQUFDLE1BQU0sQ0FBQyxHQUFHLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDN0MsT0FBTyxDQUFDLElBQUksS0FBSyxDQUFDO0lBQ3BCLENBQUM7SUFFRCxPQUFPO1FBQ0wsS0FBSyxDQUFDLEtBQUssQ0FBQyxLQUFhO1lBQ3ZCLElBQUksQ0FBQztnQkFDSCxJQUFJLENBQUMsQ0FBQyxNQUFNLFlBQVksQ0FBQyxhQUFhLEVBQUUsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO29CQUFFLE9BQU8sRUFBRSxFQUFFLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsQ0FBQztnQkFDakcsSUFBSSxDQUFDLENBQUMsTUFBTSxZQUFZLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxFQUFFLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQztvQkFBRSxPQUFPLEVBQUUsRUFBRSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLENBQUM7Z0JBQ3JHLE1BQU0sTUFBTSxHQUFHLFdBQVcsRUFBRSxDQUFDO2dCQUM3QixNQUFNLEtBQUssQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUM7Z0JBQ3hELE9BQU8sRUFBRSxFQUFFLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxDQUFDO1lBQzlCLENBQUM7WUFBQyxPQUFPLEdBQUcsRUFBRSxDQUFDO2dCQUNiLE1BQU0sQ0FBQyxJQUFJLENBQUMsdUNBQXVDLEVBQUUsRUFBRSxLQUFLLEVBQUUsR0FBRyxZQUFZLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztnQkFDbEgsT0FBTyxFQUFFLEVBQUUsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxDQUFDO1lBQ3hDLENBQUM7UUFDSCxDQUFDO1FBQ0QsS0FBSyxDQUFDLE9BQU8sQ0FBQyxRQUFnQjtZQUM1QixJQUFJLENBQUM7Z0JBQ0gsTUFBTSxLQUFLLEdBQUcsTUFBTSxLQUFLLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDO2dCQUN0RCxPQUFPLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO1lBQ2xDLENBQUM7WUFBQyxPQUFPLEdBQUcsRUFBRSxDQUFDO2dCQUNiLE1BQU0sQ0FBQyxJQUFJLENBQUMseUNBQXlDLEVBQUUsRUFBRSxLQUFLLEVBQUUsR0FBRyxZQUFZLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztnQkFDcEgsT0FBTyxJQUFJLENBQUM7WUFDZCxDQUFDO1FBQ0gsQ0FBQztRQUNELElBQUksS0FBMEUsQ0FBQztLQUNoRixDQUFDO0FBQ0osQ0FBQztBQUVEOzs7Ozs7R0FNRztBQUNILE1BQU0sVUFBVSx1QkFBdUIsQ0FBQyxNQUE0QjtJQUNsRSxNQUFNLEtBQUssR0FBRyxvQkFBb0IsQ0FBVyxZQUFZLENBQUMsQ0FBQztJQUMzRCxJQUFJLEtBQUssRUFBRSxDQUFDO1FBQ1YsTUFBTSxDQUFDLElBQUksQ0FBQyxpREFBaUQsQ0FBQyxDQUFDO1FBQy9ELE9BQU8seUJBQXlCLENBQUMsS0FBSyxFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBQ2xELENBQUM7SUFDRCxNQUFNLENBQUMsSUFBSSxDQUFDLCtEQUErRCxDQUFDLENBQUM7SUFDN0UsT0FBTyw0QkFBNEIsQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUM5QyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMjYgUGlwZWxpbmUgQnVpbGRlciBDb250cmlidXRvcnNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5cbmltcG9ydCBjcnlwdG8gZnJvbSAnY3J5cHRvJztcblxuaW1wb3J0IHsgY3JlYXRlRW52UmVkaXNDbGllbnQgfSBmcm9tICcuL2Vudi1yZWRpcy5qcyc7XG5pbXBvcnQgeyBjcmVhdGVMb2dnZXIgfSBmcm9tICcuLi91dGlscy9sb2dnZXIuanMnO1xuXG5jb25zdCBsb2dnZXIgPSBjcmVhdGVMb2dnZXIoJ3NzZS10aWNrZXQtc3RvcmUnKTtcblxuLyoqIFJlZGlzIGtleSBuYW1lc3BhY2VzLiBUaWNrZXQg4oaSIG9yZ0lkOyB3aW5kb3dlZCBpc3N1ZSBjb3VudGVycyBib3VuZCBhYnVzZS4gKi9cbmNvbnN0IFRJQ0tFVF9LRVlfUFJFRklYID0gJ3NzZTp0azonO1xuY29uc3QgT1JHX0NPVU5UX1BSRUZJWCA9ICdzc2U6dGtjOic7XG5jb25zdCBUT1RBTF9DT1VOVF9LRVkgPSAnc3NlOnRrYzpfX2FsbF9fJztcblxuLyoqIFJlc3VsdCBvZiB7QGxpbmsgU3NlVGlja2V0U3RvcmUuaXNzdWV9LiAqL1xuZXhwb3J0IHR5cGUgU3NlVGlja2V0SXNzdWVSZXN1bHQgPVxuICB8IHsgb2s6IHRydWU7IHRpY2tldDogc3RyaW5nIH1cbiAgfCB7IG9rOiBmYWxzZTsgcmVhc29uOiAndG90YWwnIHwgJ29yZycgfTtcblxuLyoqXG4gKiBTdG9yZSBmb3Igc2hvcnQtbGl2ZWQsIHNpbmdsZS11c2UgU1NFIGF1dGggdGlja2V0cy4gQSBjbGllbnQgZXhjaGFuZ2VzIGl0cyBKV1RcbiAqIGZvciBhIHRpY2tldCAoc28gdGhlIHRva2VuIG5ldmVyIGxhbmRzIGluIGFuIEV2ZW50U291cmNlIHF1ZXJ5IHN0cmluZyAvIGFjY2Vzc1xuICogbG9nKSwgdGhlbiByZWRlZW1zIGl0IG9uIHRoZSBTU0UgYEdFVGAuXG4gKlxuICogVGhlIHN0b3JlIGlzIHRoZSBtdWx0aS1yZXBsaWNhIGNvcnJlY3RuZXNzIGJvdW5kYXJ5OiBhIHRpY2tldCBtaW50ZWQgb24gcG9kIEFcbiAqIE1VU1QgYmUgcmVkZWVtYWJsZSBvbiBwb2QgQi4gVGhlIFJlZGlzIGJhY2tlbmQgbWFrZXMgdGhhdCB0cnVlOyB0aGUgaW4tbWVtb3J5XG4gKiBiYWNrZW5kIGlzIGEgc2luZ2xlLXByb2Nlc3MgZmFsbGJhY2sgZm9yIGRldiAvIHNpbmdsZS1yZXBsaWNhIGluc3RhbGxzLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFNzZVRpY2tldFN0b3JlIHtcbiAgLyoqIE1pbnQgYSB0aWNrZXQgZm9yIGBvcmdJZGAsIG9yIHJlamVjdCB3aGVuIGEgcmF0ZSB3aW5kb3cgaXMgc2F0dXJhdGVkLiAqL1xuICBpc3N1ZShvcmdJZDogc3RyaW5nKTogUHJvbWlzZTxTc2VUaWNrZXRJc3N1ZVJlc3VsdD47XG4gIC8qKiBBdG9taWNhbGx5IHJlZGVlbSBhIHRpY2tldCBleGFjdGx5IG9uY2U7IHJldHVybnMgaXRzIG9yZyBvciBudWxsIGlmIGludmFsaWQvZXhwaXJlZC9zcGVudC4gKi9cbiAgY29uc3VtZSh0aWNrZXRJZDogc3RyaW5nKTogUHJvbWlzZTx7IG9yZ0lkOiBzdHJpbmcgfSB8IG51bGw+O1xuICAvKiogUmVsZWFzZSB0aW1lcnMvcmVzb3VyY2VzLiBJbi1tZW1vcnkgY2xlYXJzIGl0cyBzd2VlcCBpbnRlcnZhbDsgUmVkaXMgaXMgYSBuby1vcC4gKi9cbiAgc3RvcCgpOiB2b2lkO1xufVxuXG4vKiogQ2FwcyArIFRUTCBmb3IgdGhlIHRpY2tldCBzdG9yZS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU3NlVGlja2V0U3RvcmVDb25maWcge1xuICAvKiogVGlja2V0IGxpZmV0aW1lIOKAlCBsb25nIGVub3VnaCBmb3IgdGhlIGNsaWVudCB0byBvcGVuIHRoZSBFdmVudFNvdXJjZS4gKi9cbiAgdHRsTXM6IG51bWJlcjtcbiAgLyoqIEhhcmQgY2FwIG9uIHRpY2tldHMgbWludGVkIHBlciBUVEwgd2luZG93IGFjcm9zcyBhbGwgb3JncyAoYWJ1c2UgYm91bmQpLiAqL1xuICBtYXhUb3RhbDogbnVtYmVyO1xuICAvKiogUGVyLW9yZyBjYXAgb24gdGlja2V0cyBtaW50ZWQgcGVyIFRUTCB3aW5kb3cgKHNpbmdsZS10ZW5hbnQgYWJ1c2UgYm91bmQpLiAqL1xuICBtYXhQZXJPcmc6IG51bWJlcjtcbiAgLyoqXG4gICAqIE9wdGlvbmFsIFJlZGlzIGtleSBuYW1lc3BhY2Ugc28gaW5kZXBlbmRlbnQgY2hhbm5lbHMgKGUuZy4gbWVzc2FnZVxuICAgKiBub3RpZmljYXRpb25zIHZzLiByZXBvcnRpbmcgZXhlY3V0aW9uLXN0YXR1cykgZG9uJ3Qgc2hhcmUgb25lIHRpY2tldFxuICAgKiBrZXlzcGFjZSDigJQgYSB0aWNrZXQgbWludGVkIGZvciBvbmUgY2hhbm5lbCBtdXN0IG5vdCBiZSByZWRlZW1hYmxlIG9uXG4gICAqIGFub3RoZXIuIE9taXQgZm9yIHRoZSBkZWZhdWx0IChzaGFyZWQpIG5hbWVzcGFjZS5cbiAgICovXG4gIGtleVByZWZpeD86IHN0cmluZztcbn1cblxuLyoqIE1pbmltYWwgaW9yZWRpcyBzdXJmYWNlIHRoaXMgc3RvcmUgbmVlZHMgKEdFVERFTCByZXF1aXJlcyBSZWRpcyDiiaUgNi4yKS4gKi9cbmludGVyZmFjZSBTc2VSZWRpcyB7XG4gIGluY3Ioa2V5OiBzdHJpbmcpOiBQcm9taXNlPG51bWJlcj47XG4gIGV4cGlyZShrZXk6IHN0cmluZywgc2Vjb25kczogbnVtYmVyKTogUHJvbWlzZTx1bmtub3duPjtcbiAgc2V0KGtleTogc3RyaW5nLCB2YWx1ZTogc3RyaW5nLCAuLi5hcmdzOiB1bmtub3duW10pOiBQcm9taXNlPHVua25vd24+O1xuICBnZXRkZWwoa2V5OiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZyB8IG51bGw+O1xufVxuXG5mdW5jdGlvbiBuZXdUaWNrZXRJZCgpOiBzdHJpbmcge1xuICByZXR1cm4gY3J5cHRvLnJhbmRvbUJ5dGVzKDI0KS50b1N0cmluZygnYmFzZTY0dXJsJyk7XG59XG5cbi8qKlxuICogSW4tbWVtb3J5IGJhY2tlbmQg4oCUIHRoZSBvcmlnaW5hbCBzaW5nbGUtcHJvY2VzcyBiZWhhdmlvdXIuIENvdW50cyBMSVZFXG4gKiAodW5leHBpcmVkKSB0aWNrZXRzIHBlciBvcmcgYW5kIGV2aWN0cyBleHBpcmVkIGVudHJpZXMgb24gYSB0aW1lci4gQ29ycmVjdFxuICogb25seSB3aXRoaW4gb25lIHByb2Nlc3MsIHNvIGl0IGlzIHRoZSBmYWxsYmFjayB1c2VkIHdoZW4gUmVkaXMgaXNuJ3QgY29uZmlndXJlZC5cbiAqL1xuZnVuY3Rpb24gY3JlYXRlSW5NZW1vcnlTc2VUaWNrZXRTdG9yZShjb25maWc6IFNzZVRpY2tldFN0b3JlQ29uZmlnKTogU3NlVGlja2V0U3RvcmUge1xuICBpbnRlcmZhY2UgRW50cnkgeyBvcmdJZDogc3RyaW5nOyBleHBpcmVzQXQ6IG51bWJlciB9XG4gIGNvbnN0IHN0b3JlID0gbmV3IE1hcDxzdHJpbmcsIEVudHJ5PigpO1xuXG4gIGNvbnN0IGNsZWFudXAgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKTtcbiAgICBmb3IgKGNvbnN0IFtpZCwgdF0gb2Ygc3RvcmUpIGlmIChub3cgPiB0LmV4cGlyZXNBdCkgc3RvcmUuZGVsZXRlKGlkKTtcbiAgfSwgY29uZmlnLnR0bE1zKTtcbiAgY2xlYW51cC51bnJlZigpO1xuXG4gIGZ1bmN0aW9uIGNvdW50TGl2ZUZvck9yZyhvcmdJZDogc3RyaW5nLCBub3c6IG51bWJlcik6IG51bWJlciB7XG4gICAgbGV0IGNvdW50ID0gMDtcbiAgICBmb3IgKGNvbnN0IHQgb2Ygc3RvcmUudmFsdWVzKCkpIGlmICh0Lm9yZ0lkID09PSBvcmdJZCAmJiB0LmV4cGlyZXNBdCA+IG5vdykgY291bnQrKztcbiAgICByZXR1cm4gY291bnQ7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIGFzeW5jIGlzc3VlKG9yZ0lkOiBzdHJpbmcpOiBQcm9taXNlPFNzZVRpY2tldElzc3VlUmVzdWx0PiB7XG4gICAgICBjb25zdCBub3cgPSBEYXRlLm5vdygpO1xuICAgICAgaWYgKHN0b3JlLnNpemUgPj0gY29uZmlnLm1heFRvdGFsKSByZXR1cm4geyBvazogZmFsc2UsIHJlYXNvbjogJ3RvdGFsJyB9O1xuICAgICAgaWYgKGNvdW50TGl2ZUZvck9yZyhvcmdJZCwgbm93KSA+PSBjb25maWcubWF4UGVyT3JnKSByZXR1cm4geyBvazogZmFsc2UsIHJlYXNvbjogJ29yZycgfTtcbiAgICAgIGNvbnN0IHRpY2tldCA9IG5ld1RpY2tldElkKCk7XG4gICAgICBzdG9yZS5zZXQodGlja2V0LCB7IG9yZ0lkLCBleHBpcmVzQXQ6IG5vdyArIGNvbmZpZy50dGxNcyB9KTtcbiAgICAgIHJldHVybiB7IG9rOiB0cnVlLCB0aWNrZXQgfTtcbiAgICB9LFxuICAgIGFzeW5jIGNvbnN1bWUodGlja2V0SWQ6IHN0cmluZyk6IFByb21pc2U8eyBvcmdJZDogc3RyaW5nIH0gfCBudWxsPiB7XG4gICAgICBjb25zdCB0ID0gc3RvcmUuZ2V0KHRpY2tldElkKTtcbiAgICAgIHN0b3JlLmRlbGV0ZSh0aWNrZXRJZCk7IC8vIHNpbmdsZS11c2Ug4oCUIGNvbnN1bWUgaW1tZWRpYXRlbHlcbiAgICAgIGlmICghdCB8fCBEYXRlLm5vdygpID4gdC5leHBpcmVzQXQpIHJldHVybiBudWxsO1xuICAgICAgcmV0dXJuIHsgb3JnSWQ6IHQub3JnSWQgfTtcbiAgICB9LFxuICAgIHN0b3AoKTogdm9pZCB7IGNsZWFySW50ZXJ2YWwoY2xlYW51cCk7IH0sXG4gIH07XG59XG5cbi8qKlxuICogUmVkaXMgYmFja2VuZCDigJQgbXVsdGktcmVwbGljYSBzYWZlLiBUaWNrZXRzIGxpdmUgdW5kZXIgYSBUVEwnZCBrZXkgc28gYW55IHBvZFxuICogY2FuIHJlZGVlbSBvbmU7IHtAbGluayBTc2VUaWNrZXRTdG9yZS5jb25zdW1lfSB1c2VzIEdFVERFTCBzbyByZWRlbXB0aW9uIGlzXG4gKiBhdG9taWMgKHR3byBwb2RzIGNhbid0IGJvdGggc3BlbmQgdGhlIHNhbWUgdGlja2V0KS4gVGhlIHBlci1vcmcgLyBnbG9iYWwgY2Fwc1xuICogYmVjb21lIHdpbmRvd2VkIHJhdGUgbGltaXRzIChtYXggbWludHMgcGVyIFRUTCB3aW5kb3cpIHZpYSBJTkNSICsgZmlyc3QtaGl0XG4gKiBFWFBJUkUg4oCUIGVxdWl2YWxlbnQgYWJ1c2UgYm91bmRpbmcgdG8gdGhlIGluLW1lbW9yeSBsaXZlLWNvdW50LCBhbmQgaXQgYWxzb1xuICogY2FwcyBjaHVybi5cbiAqXG4gKiBGYWlsLUNMT1NFRCBieSBkZXNpZ24gKHVubGlrZSB0aGUgZmFpbC1vcGVuIHRva2VuLXJldm9jYXRpb24gcmVhZGVyKTogaWYgUmVkaXNcbiAqIGVycm9ycywgYGlzc3VlYCByZXR1cm5zIGEgY2FwIHJlamVjdGlvbiBhbmQgYGNvbnN1bWVgIHJldHVybnMgbnVsbCwgc28gYSBSZWRpc1xuICogb3V0YWdlIGRlZ3JhZGVzIHRvIFwibm8gbGl2ZSBub3RpZmljYXRpb25zXCIgcmF0aGVyIHRoYW4gaGFuZGluZyBvdXQgb3JcbiAqIGFjY2VwdGluZyB1bnZhbGlkYXRlZCB0aWNrZXRzLiBTU0Ugbm90aWZpY2F0aW9ucyBhcmUgbm9uLWNyaXRpY2FsLCBzbyBmYWlsaW5nXG4gKiBjbG9zZWQgaGVyZSBjb3N0cyBvbmx5IHJlYWwtdGltZSBkZWxpdmVyeSwgbmV2ZXIgY29ycmVjdG5lc3MuXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZVJlZGlzU3NlVGlja2V0U3RvcmUocmVkaXM6IFNzZVJlZGlzLCBjb25maWc6IFNzZVRpY2tldFN0b3JlQ29uZmlnKTogU3NlVGlja2V0U3RvcmUge1xuICBjb25zdCB0dGxTZWMgPSBNYXRoLm1heCgxLCBNYXRoLmNlaWwoY29uZmlnLnR0bE1zIC8gMTAwMCkpO1xuICAvLyBQZXItY2hhbm5lbCBuYW1lc3BhY2Ugc28gdHdvIHNlcnZpY2VzJyB0aWNrZXQgc3RvcmVzIGRvbid0IHNoYXJlIGtleXMuXG4gIGNvbnN0IG5zID0gY29uZmlnLmtleVByZWZpeCA/IGAke2NvbmZpZy5rZXlQcmVmaXh9OmAgOiAnJztcbiAgY29uc3QgdGlja2V0S2V5ID0gKHQ6IHN0cmluZykgPT4gYCR7bnN9JHtUSUNLRVRfS0VZX1BSRUZJWH0ke3R9YDtcbiAgY29uc3Qgb3JnQ291bnRLZXkgPSAobzogc3RyaW5nKSA9PiBgJHtuc30ke09SR19DT1VOVF9QUkVGSVh9JHtvfWA7XG4gIGNvbnN0IHRvdGFsQ291bnRLZXkgPSBgJHtuc30ke1RPVEFMX0NPVU5UX0tFWX1gO1xuXG4gIC8vIFdpbmRvd2VkIGNvdW50ZXI6IElOQ1IsIGFuZCBvbiB0aGUgZmlyc3QgaGl0IG9mIGEgd2luZG93IHNldCB0aGUgVFRMIHNvIGl0XG4gIC8vIGF1dG8tcmVzZXRzLiBSZXR1cm5zIHRydWUgd2hpbGUgc3RpbGwgd2l0aGluIGBsaW1pdGAgZm9yIHRoaXMgd2luZG93LlxuICBhc3luYyBmdW5jdGlvbiB3aXRoaW5XaW5kb3coa2V5OiBzdHJpbmcsIGxpbWl0OiBudW1iZXIpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBjb25zdCBuID0gYXdhaXQgcmVkaXMuaW5jcihrZXkpO1xuICAgIGlmIChuID09PSAxKSBhd2FpdCByZWRpcy5leHBpcmUoa2V5LCB0dGxTZWMpO1xuICAgIHJldHVybiBuIDw9IGxpbWl0O1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBhc3luYyBpc3N1ZShvcmdJZDogc3RyaW5nKTogUHJvbWlzZTxTc2VUaWNrZXRJc3N1ZVJlc3VsdD4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgaWYgKCEoYXdhaXQgd2l0aGluV2luZG93KHRvdGFsQ291bnRLZXksIGNvbmZpZy5tYXhUb3RhbCkpKSByZXR1cm4geyBvazogZmFsc2UsIHJlYXNvbjogJ3RvdGFsJyB9O1xuICAgICAgICBpZiAoIShhd2FpdCB3aXRoaW5XaW5kb3cob3JnQ291bnRLZXkob3JnSWQpLCBjb25maWcubWF4UGVyT3JnKSkpIHJldHVybiB7IG9rOiBmYWxzZSwgcmVhc29uOiAnb3JnJyB9O1xuICAgICAgICBjb25zdCB0aWNrZXQgPSBuZXdUaWNrZXRJZCgpO1xuICAgICAgICBhd2FpdCByZWRpcy5zZXQodGlja2V0S2V5KHRpY2tldCksIG9yZ0lkLCAnRVgnLCB0dGxTZWMpO1xuICAgICAgICByZXR1cm4geyBvazogdHJ1ZSwgdGlja2V0IH07XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oJ1NTRSB0aWNrZXQgaXNzdWUgZmFpbGVkIChmYWlsLWNsb3NlZCknLCB7IGVycm9yOiBlcnIgaW5zdGFuY2VvZiBFcnJvciA/IGVyci5tZXNzYWdlIDogU3RyaW5nKGVycikgfSk7XG4gICAgICAgIHJldHVybiB7IG9rOiBmYWxzZSwgcmVhc29uOiAndG90YWwnIH07XG4gICAgICB9XG4gICAgfSxcbiAgICBhc3luYyBjb25zdW1lKHRpY2tldElkOiBzdHJpbmcpOiBQcm9taXNlPHsgb3JnSWQ6IHN0cmluZyB9IHwgbnVsbD4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3Qgb3JnSWQgPSBhd2FpdCByZWRpcy5nZXRkZWwodGlja2V0S2V5KHRpY2tldElkKSk7XG4gICAgICAgIHJldHVybiBvcmdJZCA/IHsgb3JnSWQgfSA6IG51bGw7XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oJ1NTRSB0aWNrZXQgY29uc3VtZSBmYWlsZWQgKGZhaWwtY2xvc2VkKScsIHsgZXJyb3I6IGVyciBpbnN0YW5jZW9mIEVycm9yID8gZXJyLm1lc3NhZ2UgOiBTdHJpbmcoZXJyKSB9KTtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG4gICAgfSxcbiAgICBzdG9wKCk6IHZvaWQgeyAvKiBSZWRpcyBrZXlzIGV4cGlyZSBvbiB0aGVpciBvd24gVFRMIOKAlCBub3RoaW5nIHRvIHJlbGVhc2UuICovIH0sXG4gIH07XG59XG5cbi8qKlxuICogQnVpbGQgYW4ge0BsaW5rIFNzZVRpY2tldFN0b3JlfSBmcm9tIHRoZSBzdGFuZGFyZCBSZWRpcyBlbnYgKGBSRURJU19VUkxgIG9yXG4gKiBgUkVESVNfSE9TVGAvYFJFRElTX1BPUlRgKS4gVXNlcyB0aGUgUmVkaXMgYmFja2VuZCB3aGVuIGNvbmZpZ3VyZWRcbiAqIChtdWx0aS1yZXBsaWNhIHNhZmUpLCBvdGhlcndpc2UgZmFsbHMgYmFjayB0byB0aGUgaW4tbWVtb3J5IHNpbmdsZS1wcm9jZXNzXG4gKiBiYWNrZW5kLiBBIHNlcnZpY2Ugb3B0cyBpbiB3aXRoIG9uZSBib290IGxpbmU6XG4gKiAgIGBjb25zdCB0aWNrZXRzID0gY3JlYXRlRW52U3NlVGlja2V0U3RvcmUoeyB0dGxNcywgbWF4VG90YWwsIG1heFBlck9yZyB9KTtgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVFbnZTc2VUaWNrZXRTdG9yZShjb25maWc6IFNzZVRpY2tldFN0b3JlQ29uZmlnKTogU3NlVGlja2V0U3RvcmUge1xuICBjb25zdCByZWRpcyA9IGNyZWF0ZUVudlJlZGlzQ2xpZW50PFNzZVJlZGlzPignc3NlLXRpY2tldCcpO1xuICBpZiAocmVkaXMpIHtcbiAgICBsb2dnZXIuaW5mbygnU1NFIHRpY2tldCBzdG9yZTogUmVkaXMgYmFja2VuZCAobXVsdGktcmVwbGljYSknKTtcbiAgICByZXR1cm4gY3JlYXRlUmVkaXNTc2VUaWNrZXRTdG9yZShyZWRpcywgY29uZmlnKTtcbiAgfVxuICBsb2dnZXIuaW5mbygnU1NFIHRpY2tldCBzdG9yZTogaW4tbWVtb3J5IGJhY2tlbmQgKHNpbmdsZS1wcm9jZXNzIGZhbGxiYWNrKScpO1xuICByZXR1cm4gY3JlYXRlSW5NZW1vcnlTc2VUaWNrZXRTdG9yZShjb25maWcpO1xufVxuIl19
130
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3NlLXRpY2tldC1zdG9yZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zZXJ2aWNlcy9zc2UtdGlja2V0LXN0b3JlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUFFdEMsT0FBTyxNQUFNLE1BQU0sUUFBUSxDQUFDO0FBRTVCLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3RELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUVsRCxNQUFNLE1BQU0sR0FBRyxZQUFZLENBQUMsa0JBQWtCLENBQUMsQ0FBQztBQUVoRCxpRkFBaUY7QUFDakYsTUFBTSxpQkFBaUIsR0FBRyxTQUFTLENBQUM7QUFDcEMsTUFBTSxnQkFBZ0IsR0FBRyxVQUFVLENBQUM7QUFDcEMsTUFBTSxlQUFlLEdBQUcsaUJBQWlCLENBQUM7QUFrRDFDLFNBQVMsV0FBVztJQUNsQixPQUFPLE1BQU0sQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxDQUFDO0FBQ3RELENBQUM7QUFFRDs7OztHQUlHO0FBQ0gsU0FBUyw0QkFBNEIsQ0FBQyxNQUE0QjtJQUVoRSxNQUFNLEtBQUssR0FBRyxJQUFJLEdBQUcsRUFBaUIsQ0FBQztJQUV2QyxNQUFNLE9BQU8sR0FBRyxXQUFXLENBQUMsR0FBRyxFQUFFO1FBQy9CLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUN2QixLQUFLLE1BQU0sQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLElBQUksS0FBSztZQUFFLElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQyxTQUFTO2dCQUFFLEtBQUssQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDdkUsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNqQixPQUFPLENBQUMsS0FBSyxFQUFF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QUM7Z0JBQ0gsTUFBTSxLQUFLLEdBQUcsTUFBTSxLQUFLLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDO2dCQUN0RCxPQUFPLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO1lBQ2xDLENBQUM7WUFBQyxPQUFPLEdBQUcsRUFBRSxDQUFDO2dCQUNiLE1BQU0sQ0FBQyxJQUFJLENBQUMseUNBQXlDLEVBQUUsRUFBRSxLQUFLLEVBQUUsR0FBRyxZQUFZLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztnQkFDcEgsT0FBTyxJQUFJLENBQUM7WUFDZCxDQUFDO1FBQ0gsQ0FBQztRQUNELElBQUksS0FBMEUsQ0FBQztLQUNoRixDQUFDO0FBQ0osQ0FBQztBQUVEOzs7Ozs7R0FNRztBQUNILE1BQU0sVUFBVSx1QkFBdUIsQ0FBQyxNQUE0QjtJQUNsRSxNQUFNLEtBQUssR0FBRyxvQkFBb0IsQ0FBVyxZQUFZLENBQUMsQ0FBQztJQUMzRCxJQUFJLEtBQUssRUFBRSxDQUFDO1FBQ1YsTUFBTSxDQUFDLElBQUksQ0FBQyxpREFBaUQsQ0FBQyxDQUFDO1FBQy9ELE9BQU8seUJBQXlCLENBQUMsS0FBSyxFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBQ2xELENBQUM7SUFDRCxNQUFNLENBQUMsSUFBSSxDQUFDLCtEQUErRCxDQUFDLENBQUM7SUFDN0UsT0FBTyw0QkFBNEIsQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUM5QyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMjYgUGlwZWxpbmUgQnVpbGRlciBDb250cmlidXRvcnNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5cbmltcG9ydCBjcnlwdG8gZnJvbSAnY3J5cHRvJztcblxuaW1wb3J0IHsgY3JlYXRlRW52UmVkaXNDbGllbnQgfSBmcm9tICcuL2Vudi1yZWRpcy5qcyc7XG5pbXBvcnQgeyBjcmVhdGVMb2dnZXIgfSBmcm9tICcuLi91dGlscy9sb2dnZXIuanMnO1xuXG5jb25zdCBsb2dnZXIgPSBjcmVhdGVMb2dnZXIoJ3NzZS10aWNrZXQtc3RvcmUnKTtcblxuLyoqIFJlZGlzIGtleSBuYW1lc3BhY2VzLiBUaWNrZXQg4oaSIG9yZ0lkOyB3aW5kb3dlZCBpc3N1ZSBjb3VudGVycyBib3VuZCBhYnVzZS4gKi9cbmNvbnN0IFRJQ0tFVF9LRVlfUFJFRklYID0gJ3NzZTp0azonO1xuY29uc3QgT1JHX0NPVU5UX1BSRUZJWCA9ICdzc2U6dGtjOic7XG5jb25zdCBUT1RBTF9DT1VOVF9LRVkgPSAnc3NlOnRrYzpfX2FsbF9fJztcblxuLyoqIFJlc3VsdCBvZiB7QGxpbmsgU3NlVGlja2V0U3RvcmUuaXNzdWV9LiAqL1xuZXhwb3J0IHR5cGUgU3NlVGlja2V0SXNzdWVSZXN1bHQgPVxuICB8IHsgb2s6IHRydWU7IHRpY2tldDogc3RyaW5nIH1cbiAgfCB7IG9rOiBmYWxzZTsgcmVhc29uOiAndG90YWwnIHwgJ29yZycgfTtcblxuLyoqXG4gKiBTdG9yZSBmb3Igc2hvcnQtbGl2ZWQsIHNpbmdsZS11c2UgU1NFIGF1dGggdGlja2V0cy4gQSBjbGllbnQgZXhjaGFuZ2VzIGl0cyBKV1RcbiAqIGZvciBhIHRpY2tldCAoc28gdGhlIHRva2VuIG5ldmVyIGxhbmRzIGluIGFuIEV2ZW50U291cmNlIHF1ZXJ5IHN0cmluZyAvIGFjY2Vzc1xuICogbG9nKSwgdGhlbiByZWRlZW1zIGl0IG9uIHRoZSBTU0UgYEdFVGAuXG4gKlxuICogVGhlIHN0b3JlIGlzIHRoZSBtdWx0aS1yZXBsaWNhIGNvcnJlY3RuZXNzIGJvdW5kYXJ5OiBhIHRpY2tldCBtaW50ZWQgb24gcG9kIEFcbiAqIE1VU1QgYmUgcmVkZWVtYWJsZSBvbiBwb2QgQi4gVGhlIFJlZGlzIGJhY2tlbmQgbWFrZXMgdGhhdCB0cnVlOyB0aGUgaW4tbWVtb3J5XG4gKiBiYWNrZW5kIGlzIGEgc2luZ2xlLXByb2Nlc3MgZmFsbGJhY2sgZm9yIGRldiAvIHNpbmdsZS1yZXBsaWNhIGluc3RhbGxzLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFNzZVRpY2tldFN0b3JlIHtcbiAgLyoqIE1pbnQgYSB0aWNrZXQgZm9yIGBvcmdJZGAsIG9yIHJlamVjdCB3aGVuIGEgcmF0ZSB3aW5kb3cgaXMgc2F0dXJhdGVkLiAqL1xuICBpc3N1ZShvcmdJZDogc3RyaW5nKTogUHJvbWlzZTxTc2VUaWNrZXRJc3N1ZVJlc3VsdD47XG4gIC8qKiBBdG9taWNhbGx5IHJlZGVlbSBhIHRpY2tldCBleGFjdGx5IG9uY2U7IHJldHVybnMgaXRzIG9yZyBvciBudWxsIGlmIGludmFsaWQvZXhwaXJlZC9zcGVudC4gKi9cbiAgY29uc3VtZSh0aWNrZXRJZDogc3RyaW5nKTogUHJvbWlzZTx7IG9yZ0lkOiBzdHJpbmcgfSB8IG51bGw+O1xuICAvKiogUmVsZWFzZSB0aW1lcnMvcmVzb3VyY2VzLiBJbi1tZW1vcnkgY2xlYXJzIGl0cyBzd2VlcCBpbnRlcnZhbDsgUmVkaXMgaXMgYSBuby1vcC4gKi9cbiAgc3RvcCgpOiB2b2lkO1xufVxuXG4vKiogQ2FwcyArIFRUTCBmb3IgdGhlIHRpY2tldCBzdG9yZS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU3NlVGlja2V0U3RvcmVDb25maWcge1xuICAvKiogVGlja2V0IGxpZmV0aW1lIOKAlCBsb25nIGVub3VnaCBmb3IgdGhlIGNsaWVudCB0byBvcGVuIHRoZSBFdmVudFNvdXJjZS4gKi9cbiAgdHRsTXM6IG51bWJlcjtcbiAgLyoqIEhhcmQgY2FwIG9uIHRpY2tldHMgbWludGVkIHBlciBUVEwgd2luZG93IGFjcm9zcyBhbGwgb3JncyAoYWJ1c2UgYm91bmQpLiAqL1xuICBtYXhUb3RhbDogbnVtYmVyO1xuICAvKiogUGVyLW9yZyBjYXAgb24gdGlja2V0cyBtaW50ZWQgcGVyIFRUTCB3aW5kb3cgKHNpbmdsZS10ZW5hbnQgYWJ1c2UgYm91bmQpLiAqL1xuICBtYXhQZXJPcmc6IG51bWJlcjtcbiAgLyoqXG4gICAqIE9wdGlvbmFsIFJlZGlzIGtleSBuYW1lc3BhY2Ugc28gaW5kZXBlbmRlbnQgY2hhbm5lbHMgKGUuZy4gbWVzc2FnZVxuICAgKiBub3RpZmljYXRpb25zIHZzLiByZXBvcnRpbmcgZXhlY3V0aW9uLXN0YXR1cykgZG9uJ3Qgc2hhcmUgb25lIHRpY2tldFxuICAgKiBrZXlzcGFjZSDigJQgYSB0aWNrZXQgbWludGVkIGZvciBvbmUgY2hhbm5lbCBtdXN0IG5vdCBiZSByZWRlZW1hYmxlIG9uXG4gICAqIGFub3RoZXIuIE9taXQgZm9yIHRoZSBkZWZhdWx0IChzaGFyZWQpIG5hbWVzcGFjZS5cbiAgICovXG4gIGtleVByZWZpeD86IHN0cmluZztcbn1cblxuLyoqIE1pbmltYWwgaW9yZWRpcyBzdXJmYWNlIHRoaXMgc3RvcmUgbmVlZHMgKEdFVERFTCByZXF1aXJlcyBSZWRpcyDiiaUgNi4yKS4gKi9cbmludGVyZmFjZSBTc2VSZWRpcyB7XG4gIGluY3Ioa2V5OiBzdHJpbmcpOiBQcm9taXNlPG51bWJlcj47XG4gIGV4cGlyZShrZXk6IHN0cmluZywgc2Vjb25kczogbnVtYmVyKTogUHJvbWlzZTx1bmtub3duPjtcbiAgc2V0KGtleTogc3RyaW5nLCB2YWx1ZTogc3RyaW5nLCAuLi5hcmdzOiB1bmtub3duW10pOiBQcm9taXNlPHVua25vd24+O1xuICBnZXRkZWwoa2V5OiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZyB8IG51bGw+O1xufVxuXG5mdW5jdGlvbiBuZXdUaWNrZXRJZCgpOiBzdHJpbmcge1xuICByZXR1cm4gY3J5cHRvLnJhbmRvbUJ5dGVzKDI0KS50b1N0cmluZygnYmFzZTY0dXJsJyk7XG59XG5cbi8qKlxuICogSW4tbWVtb3J5IGJhY2tlbmQg4oCUIHRoZSBvcmlnaW5hbCBzaW5nbGUtcHJvY2VzcyBiZWhhdmlvdXIuIENvdW50cyBMSVZFXG4gKiAodW5leHBpcmVkKSB0aWNrZXRzIHBlciBvcmcgYW5kIGV2aWN0cyBleHBpcmVkIGVudHJpZXMgb24gYSB0aW1lci4gQ29ycmVjdFxuICogb25seSB3aXRoaW4gb25lIHByb2Nlc3MsIHNvIGl0IGlzIHRoZSBmYWxsYmFjayB1c2VkIHdoZW4gUmVkaXMgaXNuJ3QgY29uZmlndXJlZC5cbiAqL1xuZnVuY3Rpb24gY3JlYXRlSW5NZW1vcnlTc2VUaWNrZXRTdG9yZShjb25maWc6IFNzZVRpY2tldFN0b3JlQ29uZmlnKTogU3NlVGlja2V0U3RvcmUge1xuICBpbnRlcmZhY2UgRW50cnkgeyBvcmdJZDogc3RyaW5nOyBleHBpcmVzQXQ6IG51bWJlciB9XG4gIGNvbnN0IHN0b3JlID0gbmV3IE1hcDxzdHJpbmcsIEVudHJ5PigpO1xuXG4gIGNvbnN0IGNsZWFudXAgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKTtcbiAgICBmb3IgKGNvbnN0IFtpZCwgdF0gb2Ygc3RvcmUpIGlmIChub3cgPiB0LmV4cGlyZXNBdCkgc3RvcmUuZGVsZXRlKGlkKTtcbiAgfSwgY29uZmlnLnR0bE1zKTtcbiAgY2xlYW51cC51bnJlZigpO1xuXG4gIGZ1bmN0aW9uIGNvdW50TGl2ZUZvck9yZyhvcmdJZDogc3RyaW5nLCBub3c6IG51bWJlcik6IG51bWJlciB7XG4gICAgbGV0IGNvdW50ID0gMDtcbiAgICBmb3IgKGNvbnN0IHQgb2Ygc3RvcmUudmFsdWVzKCkpIGlmICh0Lm9yZ0lkID09PSBvcmdJZCAmJiB0LmV4cGlyZXNBdCA+IG5vdykgY291bnQrKztcbiAgICByZXR1cm4gY291bnQ7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIGFzeW5jIGlzc3VlKG9yZ0lkOiBzdHJpbmcpOiBQcm9taXNlPFNzZVRpY2tldElzc3VlUmVzdWx0PiB7XG4gICAgICBjb25zdCBub3cgPSBEYXRlLm5vdygpO1xuICAgICAgaWYgKHN0b3JlLnNpemUgPj0gY29uZmlnLm1heFRvdGFsKSByZXR1cm4geyBvazogZmFsc2UsIHJlYXNvbjogJ3RvdGFsJyB9O1xuICAgICAgaWYgKGNvdW50TGl2ZUZvck9yZyhvcmdJZCwgbm93KSA+PSBjb25maWcubWF4UGVyT3JnKSByZXR1cm4geyBvazogZmFsc2UsIHJlYXNvbjogJ29yZycgfTtcbiAgICAgIGNvbnN0IHRpY2tldCA9IG5ld1RpY2tldElkKCk7XG4gICAgICBzdG9yZS5zZXQodGlja2V0LCB7IG9yZ0lkLCBleHBpcmVzQXQ6IG5vdyArIGNvbmZpZy50dGxNcyB9KTtcbiAgICAgIHJldHVybiB7IG9rOiB0cnVlLCB0aWNrZXQgfTtcbiAgICB9LFxuICAgIGFzeW5jIGNvbnN1bWUodGlja2V0SWQ6IHN0cmluZyk6IFByb21pc2U8eyBvcmdJZDogc3RyaW5nIH0gfCBudWxsPiB7XG4gICAgICBjb25zdCB0ID0gc3RvcmUuZ2V0KHRpY2tldElkKTtcbiAgICAgIHN0b3JlLmRlbGV0ZSh0aWNrZXRJZCk7IC8vIHNpbmdsZS11c2Ug4oCUIGNvbnN1bWUgaW1tZWRpYXRlbHlcbiAgICAgIGlmICghdCB8fCBEYXRlLm5vdygpID4gdC5leHBpcmVzQXQpIHJldHVybiBudWxsO1xuICAgICAgcmV0dXJuIHsgb3JnSWQ6IHQub3JnSWQgfTtcbiAgICB9LFxuICAgIHN0b3AoKTogdm9pZCB7IGNsZWFySW50ZXJ2YWwoY2xlYW51cCk7IH0sXG4gIH07XG59XG5cbi8qKlxuICogUmVkaXMgYmFja2VuZCDigJQgbXVsdGktcmVwbGljYSBzYWZlLiBUaWNrZXRzIGxpdmUgdW5kZXIgYSBUVEwnZCBrZXkgc28gYW55IHBvZFxuICogY2FuIHJlZGVlbSBvbmU7IHtAbGluayBTc2VUaWNrZXRTdG9yZS5jb25zdW1lfSB1c2VzIEdFVERFTCBzbyByZWRlbXB0aW9uIGlzXG4gKiBhdG9taWMgKHR3byBwb2RzIGNhbid0IGJvdGggc3BlbmQgdGhlIHNhbWUgdGlja2V0KS4gVGhlIHBlci1vcmcgLyBnbG9iYWwgY2Fwc1xuICogYmVjb21lIHdpbmRvd2VkIHJhdGUgbGltaXRzIChtYXggbWludHMgcGVyIFRUTCB3aW5kb3cpIHZpYSBJTkNSICsgZmlyc3QtaGl0XG4gKiBFWFBJUkUg4oCUIGVxdWl2YWxlbnQgYWJ1c2UgYm91bmRpbmcgdG8gdGhlIGluLW1lbW9yeSBsaXZlLWNvdW50LCBhbmQgaXQgYWxzb1xuICogY2FwcyBjaHVybi5cbiAqXG4gKiBGYWlsLUNMT1NFRCBieSBkZXNpZ24gKHVubGlrZSB0aGUgZmFpbC1vcGVuIHRva2VuLXJldm9jYXRpb24gcmVhZGVyKTogaWYgUmVkaXNcbiAqIGVycm9ycywgYGlzc3VlYCByZXR1cm5zIGEgY2FwIHJlamVjdGlvbiBhbmQgYGNvbnN1bWVgIHJldHVybnMgbnVsbCwgc28gYSBSZWRpc1xuICogb3V0YWdlIGRlZ3JhZGVzIHRvIFwibm8gbGl2ZSBub3RpZmljYXRpb25zXCIgcmF0aGVyIHRoYW4gaGFuZGluZyBvdXQgb3JcbiAqIGFjY2VwdGluZyB1bnZhbGlkYXRlZCB0aWNrZXRzLiBTU0Ugbm90aWZpY2F0aW9ucyBhcmUgbm9uLWNyaXRpY2FsLCBzbyBmYWlsaW5nXG4gKiBjbG9zZWQgaGVyZSBjb3N0cyBvbmx5IHJlYWwtdGltZSBkZWxpdmVyeSwgbmV2ZXIgY29ycmVjdG5lc3MuXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZVJlZGlzU3NlVGlja2V0U3RvcmUocmVkaXM6IFNzZVJlZGlzLCBjb25maWc6IFNzZVRpY2tldFN0b3JlQ29uZmlnKTogU3NlVGlja2V0U3RvcmUge1xuICBjb25zdCB0dGxTZWMgPSBNYXRoLm1heCgxLCBNYXRoLmNlaWwoY29uZmlnLnR0bE1zIC8gMTAwMCkpO1xuICAvLyBQZXItY2hhbm5lbCBuYW1lc3BhY2Ugc28gdHdvIHNlcnZpY2VzJyB0aWNrZXQgc3RvcmVzIGRvbid0IHNoYXJlIGtleXMuXG4gIGNvbnN0IG5zID0gY29uZmlnLmtleVByZWZpeCA/IGAke2NvbmZpZy5rZXlQcmVmaXh9OmAgOiAnJztcbiAgY29uc3QgdGlja2V0S2V5ID0gKHQ6IHN0cmluZykgPT4gYCR7bnN9JHtUSUNLRVRfS0VZX1BSRUZJWH0ke3R9YDtcbiAgY29uc3Qgb3JnQ291bnRLZXkgPSAobzogc3RyaW5nKSA9PiBgJHtuc30ke09SR19DT1VOVF9QUkVGSVh9JHtvfWA7XG4gIGNvbnN0IHRvdGFsQ291bnRLZXkgPSBgJHtuc30ke1RPVEFMX0NPVU5UX0tFWX1gO1xuXG4gIC8vIFdpbmRvd2VkIGNvdW50ZXI6IElOQ1IsIGFuZCBvbiB0aGUgZmlyc3QgaGl0IG9mIGEgd2luZG93IHNldCB0aGUgVFRMIHNvIGl0XG4gIC8vIGF1dG8tcmVzZXRzLiBSZXR1cm5zIHRydWUgd2hpbGUgc3RpbGwgd2l0aGluIGBsaW1pdGAgZm9yIHRoaXMgd2luZG93LlxuICBhc3luYyBmdW5jdGlvbiB3aXRoaW5XaW5kb3coa2V5OiBzdHJpbmcsIGxpbWl0OiBudW1iZXIpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBjb25zdCBuID0gYXdhaXQgcmVkaXMuaW5jcihrZXkpO1xuICAgIGlmIChuID09PSAxKSBhd2FpdCByZWRpcy5leHBpcmUoa2V5LCB0dGxTZWMpO1xuICAgIHJldHVybiBuIDw9IGxpbWl0O1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBhc3luYyBpc3N1ZShvcmdJZDogc3RyaW5nKTogUHJvbWlzZTxTc2VUaWNrZXRJc3N1ZVJlc3VsdD4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgaWYgKCEoYXdhaXQgd2l0aGluV2luZG93KHRvdGFsQ291bnRLZXksIGNvbmZpZy5tYXhUb3RhbCkpKSByZXR1cm4geyBvazogZmFsc2UsIHJlYXNvbjogJ3RvdGFsJyB9O1xuICAgICAgICBpZiAoIShhd2FpdCB3aXRoaW5XaW5kb3cob3JnQ291bnRLZXkob3JnSWQpLCBjb25maWcubWF4UGVyT3JnKSkpIHJldHVybiB7IG9rOiBmYWxzZSwgcmVhc29uOiAnb3JnJyB9O1xuICAgICAgICBjb25zdCB0aWNrZXQgPSBuZXdUaWNrZXRJZCgpO1xuICAgICAgICBhd2FpdCByZWRpcy5zZXQodGlja2V0S2V5KHRpY2tldCksIG9yZ0lkLCAnRVgnLCB0dGxTZWMpO1xuICAgICAgICByZXR1cm4geyBvazogdHJ1ZSwgdGlja2V0IH07XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oJ1NTRSB0aWNrZXQgaXNzdWUgZmFpbGVkIChmYWlsLWNsb3NlZCknLCB7IGVycm9yOiBlcnIgaW5zdGFuY2VvZiBFcnJvciA/IGVyci5tZXNzYWdlIDogU3RyaW5nKGVycikgfSk7XG4gICAgICAgIHJldHVybiB7IG9rOiBmYWxzZSwgcmVhc29uOiAndG90YWwnIH07XG4gICAgICB9XG4gICAgfSxcbiAgICBhc3luYyBjb25zdW1lKHRpY2tldElkOiBzdHJpbmcpOiBQcm9taXNlPHsgb3JnSWQ6IHN0cmluZyB9IHwgbnVsbD4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3Qgb3JnSWQgPSBhd2FpdCByZWRpcy5nZXRkZWwodGlja2V0S2V5KHRpY2tldElkKSk7XG4gICAgICAgIHJldHVybiBvcmdJZCA/IHsgb3JnSWQgfSA6IG51bGw7XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oJ1NTRSB0aWNrZXQgY29uc3VtZSBmYWlsZWQgKGZhaWwtY2xvc2VkKScsIHsgZXJyb3I6IGVyciBpbnN0YW5jZW9mIEVycm9yID8gZXJyLm1lc3NhZ2UgOiBTdHJpbmcoZXJyKSB9KTtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG4gICAgfSxcbiAgICBzdG9wKCk6IHZvaWQgeyAvKiBSZWRpcyBrZXlzIGV4cGlyZSBvbiB0aGVpciBvd24gVFRMIOKAlCBub3RoaW5nIHRvIHJlbGVhc2UuICovIH0sXG4gIH07XG59XG5cbi8qKlxuICogQnVpbGQgYW4ge0BsaW5rIFNzZVRpY2tldFN0b3JlfSBmcm9tIHRoZSBzdGFuZGFyZCBSZWRpcyBlbnYgKGBSRURJU19VUkxgIG9yXG4gKiBgUkVESVNfU0VOVElORUxTYCkuIFVzZXMgdGhlIFJlZGlzIGJhY2tlbmQgd2hlbiBjb25maWd1cmVkXG4gKiAobXVsdGktcmVwbGljYSBzYWZlKSwgb3RoZXJ3aXNlIGZhbGxzIGJhY2sgdG8gdGhlIGluLW1lbW9yeSBzaW5nbGUtcHJvY2Vzc1xuICogYmFja2VuZC4gQSBzZXJ2aWNlIG9wdHMgaW4gd2l0aCBvbmUgYm9vdCBsaW5lOlxuICogICBgY29uc3QgdGlja2V0cyA9IGNyZWF0ZUVudlNzZVRpY2tldFN0b3JlKHsgdHRsTXMsIG1heFRvdGFsLCBtYXhQZXJPcmcgfSk7YFxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlRW52U3NlVGlja2V0U3RvcmUoY29uZmlnOiBTc2VUaWNrZXRTdG9yZUNvbmZpZyk6IFNzZVRpY2tldFN0b3JlIHtcbiAgY29uc3QgcmVkaXMgPSBjcmVhdGVFbnZSZWRpc0NsaWVudDxTc2VSZWRpcz4oJ3NzZS10aWNrZXQnKTtcbiAgaWYgKHJlZGlzKSB7XG4gICAgbG9nZ2VyLmluZm8oJ1NTRSB0aWNrZXQgc3RvcmU6IFJlZGlzIGJhY2tlbmQgKG11bHRpLXJlcGxpY2EpJyk7XG4gICAgcmV0dXJuIGNyZWF0ZVJlZGlzU3NlVGlja2V0U3RvcmUocmVkaXMsIGNvbmZpZyk7XG4gIH1cbiAgbG9nZ2VyLmluZm8oJ1NTRSB0aWNrZXQgc3RvcmU6IGluLW1lbW9yeSBiYWNrZW5kIChzaW5nbGUtcHJvY2VzcyBmYWxsYmFjayknKTtcbiAgcmV0dXJuIGNyZWF0ZUluTWVtb3J5U3NlVGlja2V0U3RvcmUoY29uZmlnKTtcbn1cbiJdfQ==
@@ -10,6 +10,14 @@ import type { TokenRevocationStore } from '../middleware/auth.js';
10
10
  export declare const TOKEN_REVOCATION_KEY_PREFIX = "authrev:tv:";
11
11
  /** The revocation key for a user id. */
12
12
  export declare function tokenRevocationKey(userId: string): string;
13
+ /**
14
+ * Redis key namespace for ended IMPERSONATION sessions, by token `jti`. Same
15
+ * publish/read split as the tokenVersion keys above, and kept beside them for the
16
+ * same reason: publisher and readers must agree on this exact prefix.
17
+ */
18
+ export declare const SESSION_REVOCATION_KEY_PREFIX = "authrev:jti:";
19
+ /** The revocation key for one session's token id. */
20
+ export declare function sessionRevocationKey(jti: string): string;
13
21
  /**
14
22
  * Build a {@link TokenRevocationStore} backed by a Redis client, for a stateless
15
23
  * service to register via `setTokenRevocationStore`. Reads the current
@@ -22,7 +30,7 @@ export declare function tokenRevocationKey(userId: string): string;
22
30
  export declare function createRedisTokenRevocationStore(redis: RedisCacheClient): TokenRevocationStore;
23
31
  /**
24
32
  * Build a {@link TokenRevocationStore} backed by a Redis client that is lazily
25
- * constructed from the standard `REDIS_URL` or `REDIS_HOST`/`REDIS_PORT` env —
33
+ * constructed from the standard `REDIS_URL` or `REDIS_SENTINELS` env —
26
34
  * for a stateless service that keeps NO Redis client of its own. The client is
27
35
  * built on first `getCurrentVersion` call and memoized; `ioredis` is loaded via
28
36
  * a guarded dynamic require so merely importing this never breaks a build/test
@@ -50,3 +58,18 @@ export declare function createEnvRedisTokenRevocationStore(): TokenRevocationSto
50
58
  * @param ttlSeconds - access-token lifetime in seconds
51
59
  */
52
60
  export declare function publishTokenRevocation(redis: RedisCacheClient, userId: string, tokenVersion: number, ttlSeconds: number): Promise<void>;
61
+ /**
62
+ * Publish that one IMPERSONATION session has ended, so every stateless service
63
+ * rejects its token on the next request (platform side).
64
+ *
65
+ * Returns whether the publish landed — unlike `publishTokenRevocation`, which is
66
+ * fire-and-forget. The caller must be able to tell the person who ended the
67
+ * session that it did NOT end everywhere, rather than reporting success while
68
+ * the token still works against other services.
69
+ *
70
+ * The entry expires with the session: once the token itself can no longer be
71
+ * used, there is nothing left to revoke, so the key cleans itself up.
72
+ *
73
+ * @param ttlMs - time remaining on the session's token
74
+ */
75
+ export declare function publishSessionRevocation(redis: RedisCacheClient, jti: string, ttlMs: number): Promise<boolean>;