@pipeline-builder/api-core 3.4.126 → 4.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/lib/constants/ai-providers.d.ts +18 -0
- package/lib/constants/ai-providers.js +51 -1
- package/lib/helpers/access-helpers.d.ts +52 -11
- package/lib/helpers/access-helpers.js +63 -18
- package/lib/helpers/restore-helpers.d.ts +8 -5
- package/lib/helpers/restore-helpers.js +12 -10
- package/lib/index.d.ts +1 -1
- package/lib/index.js +2 -2
- package/lib/middleware/auth.d.ts +11 -13
- package/lib/middleware/auth.js +61 -21
- package/lib/openapi/routes/ask-routes.d.ts +7 -0
- package/lib/openapi/routes/ask-routes.js +62 -0
- package/lib/openapi/routes/image-registry-routes.d.ts +7 -0
- package/lib/openapi/routes/image-registry-routes.js +98 -0
- package/lib/openapi/routes/index.js +8 -1
- package/lib/openapi/routes/pipeline-routes.js +10 -1
- package/lib/openapi/routes/pipeline-template-routes.js +8 -6
- package/lib/openapi/schema-registry.js +4 -4
- package/lib/services/circuit-breaker.d.ts +45 -0
- package/lib/services/circuit-breaker.js +138 -0
- package/lib/services/durable-event-bus.d.ts +96 -0
- package/lib/services/durable-event-bus.js +204 -0
- package/lib/services/http-client.js +42 -2
- package/lib/services/index.d.ts +2 -0
- package/lib/services/index.js +3 -1
- package/lib/services/quota.js +8 -1
- package/lib/services/remote-audit-client.d.ts +1 -1
- package/lib/services/remote-audit-client.js +7 -1
- package/lib/services/sse-ticket-store.d.ts +7 -0
- package/lib/services/sse-ticket-store.js +10 -5
- package/lib/services/token-revocation.js +10 -1
- package/lib/types/index.d.ts +1 -0
- package/lib/types/index.js +2 -1
- package/lib/types/permissions.d.ts +1 -1
- package/lib/types/permissions.js +6 -3
- package/lib/types/pipeline.d.ts +0 -11
- package/lib/types/pipeline.js +1 -11
- package/lib/types/visibility.d.ts +20 -0
- package/lib/types/visibility.js +22 -0
- package/lib/utils/audit.js +1 -1
- package/lib/utils/response.js +6 -3
- package/lib/validation/ai-schemas.d.ts +2 -1
- package/lib/validation/ai-schemas.js +3 -3
- package/lib/validation/common-schemas.d.ts +8 -6
- package/lib/validation/common-schemas.js +8 -7
- package/lib/validation/message-schemas.d.ts +2 -1
- package/lib/validation/pipeline-schemas.d.ts +6 -3
- package/lib/validation/pipeline-schemas.js +4 -4
- package/lib/validation/pipeline-template-schemas.d.ts +9 -6
- package/lib/validation/pipeline-template-schemas.js +5 -4
- package/lib/validation/plugin-schemas.d.ts +8 -4
- package/lib/validation/plugin-schemas.js +5 -5
- package/package.json +1 -1
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Durable, at-least-once event backbone (Redis Streams).
|
|
3
|
+
*
|
|
4
|
+
* The platform's cross-service signalling today is point-to-point HTTP plus
|
|
5
|
+
* polling reconcilers plus an IN-PROCESS best-effort emitter ({@link entityEvents}).
|
|
6
|
+
* There is no durable bus, so a signal produced on one pod is either delivered
|
|
7
|
+
* synchronously over HTTP (coupling + retry-storm risk) or lost if the consumer
|
|
8
|
+
* is momentarily down (the reconcilers exist to paper over exactly that).
|
|
9
|
+
*
|
|
10
|
+
* This is that missing bus, as a reusable primitive:
|
|
11
|
+
* - **publish(topic, payload)** → `XADD` onto a bounded (`MAXLEN ~`) per-topic
|
|
12
|
+
* stream. Durable across restarts, shared by all replicas.
|
|
13
|
+
* - **subscribe({topic, group, consumer, handler})** → a `XREADGROUP` consumer.
|
|
14
|
+
* Consumer GROUPS give at-least-once: each group gets every message once, a
|
|
15
|
+
* message stays pending until the handler `XACK`s it, and `XAUTOCLAIM`
|
|
16
|
+
* reclaims messages stranded by a crashed consumer. Multiple groups on one
|
|
17
|
+
* topic = independent fan-out (e.g. quota-sync AND audit both react).
|
|
18
|
+
*
|
|
19
|
+
* FAIL-SAFE + OPT-IN, exactly like the audit spool: {@link createEnvRedisDurableEventBus}
|
|
20
|
+
* returns `null` when Redis isn't configured, so a service without it simply
|
|
21
|
+
* doesn't use the bus (keeps today's behavior). A publish failure is dropped-with-
|
|
22
|
+
* -metric, never thrown; a handler throw leaves the message un-acked for redelivery.
|
|
23
|
+
*
|
|
24
|
+
* Migrating a specific reconciler (e.g. billing→quota entitlement sync) onto this
|
|
25
|
+
* is deliberately follow-on work — this lands the backbone + an additive entity-
|
|
26
|
+
* event bridge; the reconcilers stay as the belt-and-suspenders backstop until a
|
|
27
|
+
* flow is fully cut over.
|
|
28
|
+
*/
|
|
29
|
+
import type { EntityEventSubscriber } from './entity-events.js';
|
|
30
|
+
/** A delivered event: its stream id, topic, and decoded payload. */
|
|
31
|
+
export interface EventEnvelope<T = unknown> {
|
|
32
|
+
/** Redis Stream entry id (`<ms>-<seq>`) — also the idempotency handle. */
|
|
33
|
+
id: string;
|
|
34
|
+
topic: string;
|
|
35
|
+
payload: T;
|
|
36
|
+
}
|
|
37
|
+
export interface SubscribeOptions<T = unknown> {
|
|
38
|
+
/** Topic (stream) to consume. */
|
|
39
|
+
topic: string;
|
|
40
|
+
/** Consumer group — one delivery per group; distinct groups fan out. */
|
|
41
|
+
group: string;
|
|
42
|
+
/** This consumer's id within the group (e.g. `${service}-${pid}`). */
|
|
43
|
+
consumer: string;
|
|
44
|
+
/** Async handler. Resolves ⇒ the message is acked; throws ⇒ left pending for redelivery. */
|
|
45
|
+
handler: (env: EventEnvelope<T>) => Promise<void>;
|
|
46
|
+
/** Max messages per read (default 16). */
|
|
47
|
+
batchSize?: number;
|
|
48
|
+
/** XREADGROUP block time in ms (default 5000). */
|
|
49
|
+
blockMs?: number;
|
|
50
|
+
/** A pending message idle this long (ms) is reclaimed from a dead consumer (default 60000). */
|
|
51
|
+
minIdleMs?: number;
|
|
52
|
+
}
|
|
53
|
+
export interface EventSubscription {
|
|
54
|
+
/** Stop the consumer loop. Resolves once the in-flight read returns. */
|
|
55
|
+
stop(): Promise<void>;
|
|
56
|
+
}
|
|
57
|
+
export interface DurableEventBus {
|
|
58
|
+
/** Publish a payload to a topic. Returns the stream id, or null on failure (dropped, never throws). */
|
|
59
|
+
publish<T>(topic: string, payload: T): Promise<string | null>;
|
|
60
|
+
/** Start a consumer-group reader for a topic. Fire-and-forget loop; call `stop()` to end it. */
|
|
61
|
+
subscribe<T>(opts: SubscribeOptions<T>): EventSubscription;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* The subset of ioredis' Stream API the bus uses. Kept minimal so a test can
|
|
65
|
+
* supply an in-memory fake and so merely importing this never hard-depends on
|
|
66
|
+
* ioredis (constructed via the shared env helper).
|
|
67
|
+
*/
|
|
68
|
+
export interface RedisStreamClient {
|
|
69
|
+
xadd(key: string, ...args: (string | number)[]): Promise<string | null>;
|
|
70
|
+
xgroup(...args: (string | number)[]): Promise<unknown>;
|
|
71
|
+
xreadgroup(...args: (string | number)[]): Promise<unknown>;
|
|
72
|
+
xack(key: string, group: string, ...ids: string[]): Promise<number>;
|
|
73
|
+
xautoclaim(...args: (string | number)[]): Promise<unknown>;
|
|
74
|
+
}
|
|
75
|
+
/** Build a durable event bus over a Redis Streams client. */
|
|
76
|
+
export declare function createRedisDurableEventBus(redis: RedisStreamClient, opts?: {
|
|
77
|
+
maxLen?: number;
|
|
78
|
+
}): DurableEventBus;
|
|
79
|
+
/**
|
|
80
|
+
* Build a durable event bus from the ambient Redis env via the shared
|
|
81
|
+
* `createEnvRedisClient`. Returns `null` when Redis is not configured — the
|
|
82
|
+
* caller then runs without a bus (today's HTTP/reconciler behavior), never
|
|
83
|
+
* crashing. Opt in with a single boot line where a service wants durable events.
|
|
84
|
+
*/
|
|
85
|
+
export declare function createEnvRedisDurableEventBus(opts?: {
|
|
86
|
+
maxLen?: number;
|
|
87
|
+
}): DurableEventBus | null;
|
|
88
|
+
/** Topic the entity-event bridge publishes to. */
|
|
89
|
+
export declare const ENTITY_EVENT_TOPIC = "entity-events";
|
|
90
|
+
/**
|
|
91
|
+
* An {@link EntityEventSubscriber} that forwards each entity event to the durable
|
|
92
|
+
* bus. `bus.publish` is fail-safe (drops-with-metric, never throws), matching the
|
|
93
|
+
* emitter's fire-and-forget contract. Note `EntityEvent.timestamp` (a Date)
|
|
94
|
+
* serializes to an ISO string on the wire — a consumer re-hydrates as needed.
|
|
95
|
+
*/
|
|
96
|
+
export declare function createEntityEventBusPublisher(bus: DurableEventBus): EntityEventSubscriber;
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
// Copyright 2026 Pipeline Builder Contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
import { createEnvRedisClient } from './env-redis.js';
|
|
4
|
+
import { createLogger } from '../utils/logger.js';
|
|
5
|
+
import { emitCounter } from '../utils/metric-emitter.js';
|
|
6
|
+
const logger = createLogger('durable-event-bus');
|
|
7
|
+
const DEFAULT_MAXLEN = 10_000;
|
|
8
|
+
const DEFAULT_BATCH = 16;
|
|
9
|
+
const DEFAULT_BLOCK_MS = 5_000;
|
|
10
|
+
const DEFAULT_MIN_IDLE_MS = 60_000;
|
|
11
|
+
function errMsg(err) {
|
|
12
|
+
return err instanceof Error ? err.message : String(err);
|
|
13
|
+
}
|
|
14
|
+
function streamKey(topic) {
|
|
15
|
+
return `evt:${topic}`;
|
|
16
|
+
}
|
|
17
|
+
/** True when the error is Redis' "group already exists" (idempotent create). */
|
|
18
|
+
function isBusyGroup(err) {
|
|
19
|
+
return errMsg(err).includes('BUSYGROUP');
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Parse the nested array shape XREADGROUP / XAUTOCLAIM return into flat envelopes.
|
|
23
|
+
* XREADGROUP: `[[streamKey, [[id, [f, v, ...]], ...]]]`.
|
|
24
|
+
* XAUTOCLAIM: `[nextCursor, [[id, [f, v, ...]], ...], deletedIds]`.
|
|
25
|
+
* We store the JSON payload under a single field `d`.
|
|
26
|
+
*/
|
|
27
|
+
function parseEntries(topic, entries) {
|
|
28
|
+
const out = [];
|
|
29
|
+
if (!Array.isArray(entries))
|
|
30
|
+
return out;
|
|
31
|
+
for (const entry of entries) {
|
|
32
|
+
if (!Array.isArray(entry) || entry.length < 2)
|
|
33
|
+
continue;
|
|
34
|
+
const id = String(entry[0]);
|
|
35
|
+
const fields = entry[1];
|
|
36
|
+
if (!Array.isArray(fields))
|
|
37
|
+
continue;
|
|
38
|
+
// fields is [name, value, name, value, ...]; find 'd'.
|
|
39
|
+
let raw;
|
|
40
|
+
for (let i = 0; i + 1 < fields.length; i += 2) {
|
|
41
|
+
if (String(fields[i]) === 'd') {
|
|
42
|
+
raw = String(fields[i + 1]);
|
|
43
|
+
break;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
// A missing `d` field (an entry not written by publish()) OR a corrupt JSON
|
|
47
|
+
// payload both yield an undefined-payload envelope so `deliver()` ACKs it —
|
|
48
|
+
// a poison message must never wedge the group by staying perpetually pending.
|
|
49
|
+
if (raw === undefined) {
|
|
50
|
+
out.push({ id, topic, payload: undefined });
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
try {
|
|
54
|
+
out.push({ id, topic, payload: JSON.parse(raw) });
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
out.push({ id, topic, payload: undefined });
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return out;
|
|
61
|
+
}
|
|
62
|
+
/** Build a durable event bus over a Redis Streams client. */
|
|
63
|
+
export function createRedisDurableEventBus(redis, opts = {}) {
|
|
64
|
+
const maxLen = Math.max(1, opts.maxLen ?? DEFAULT_MAXLEN);
|
|
65
|
+
return {
|
|
66
|
+
async publish(topic, payload) {
|
|
67
|
+
const key = streamKey(topic);
|
|
68
|
+
try {
|
|
69
|
+
// MAXLEN ~ <n> bounds the stream approximately (cheap); `*` = server id.
|
|
70
|
+
const id = await redis.xadd(key, 'MAXLEN', '~', maxLen, '*', 'd', JSON.stringify(payload));
|
|
71
|
+
emitCounter('event_bus_published_total', { topic });
|
|
72
|
+
return id;
|
|
73
|
+
}
|
|
74
|
+
catch (err) {
|
|
75
|
+
emitCounter('event_bus_publish_failed_total', { topic });
|
|
76
|
+
logger.warn('Event bus publish failed (event dropped)', { topic, error: errMsg(err) });
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
subscribe(subOpts) {
|
|
81
|
+
const { topic, group, consumer, handler } = subOpts;
|
|
82
|
+
const key = streamKey(topic);
|
|
83
|
+
const batch = Math.max(1, subOpts.batchSize ?? DEFAULT_BATCH);
|
|
84
|
+
const blockMs = Math.max(0, subOpts.blockMs ?? DEFAULT_BLOCK_MS);
|
|
85
|
+
const minIdle = Math.max(0, subOpts.minIdleMs ?? DEFAULT_MIN_IDLE_MS);
|
|
86
|
+
let stopped = false;
|
|
87
|
+
let started = false;
|
|
88
|
+
const deliver = async (envs) => {
|
|
89
|
+
for (const env of envs) {
|
|
90
|
+
try {
|
|
91
|
+
if (env.payload !== undefined)
|
|
92
|
+
await handler(env);
|
|
93
|
+
// Ack on success OR on an undefined (corrupt) payload — a poison
|
|
94
|
+
// message must not block the group forever.
|
|
95
|
+
await redis.xack(key, group, env.id);
|
|
96
|
+
emitCounter('event_bus_delivered_total', { topic, group });
|
|
97
|
+
}
|
|
98
|
+
catch (err) {
|
|
99
|
+
// Leave it pending (no XACK) — XAUTOCLAIM redelivers it after minIdle.
|
|
100
|
+
emitCounter('event_bus_handler_failed_total', { topic, group });
|
|
101
|
+
logger.warn('Event handler failed; leaving message pending for redelivery', {
|
|
102
|
+
topic, group, id: env.id, error: errMsg(err),
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
const ensureGroup = async () => {
|
|
108
|
+
try {
|
|
109
|
+
// MKSTREAM so the stream need not exist yet; '$' = only new messages.
|
|
110
|
+
await redis.xgroup('CREATE', key, group, '$', 'MKSTREAM');
|
|
111
|
+
}
|
|
112
|
+
catch (err) {
|
|
113
|
+
if (!isBusyGroup(err)) {
|
|
114
|
+
logger.warn('Event bus group create failed', { topic, group, error: errMsg(err) });
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
const loop = async () => {
|
|
119
|
+
await ensureGroup();
|
|
120
|
+
while (!stopped) {
|
|
121
|
+
try {
|
|
122
|
+
// 1) Reclaim messages stranded by a crashed consumer in this group.
|
|
123
|
+
const claimed = await redis.xautoclaim(key, group, consumer, minIdle, '0', 'COUNT', batch);
|
|
124
|
+
// XAUTOCLAIM reply: [nextCursor, entries, deletedIds]
|
|
125
|
+
if (Array.isArray(claimed) && claimed.length >= 2) {
|
|
126
|
+
await deliver(parseEntries(topic, claimed[1]));
|
|
127
|
+
}
|
|
128
|
+
if (stopped)
|
|
129
|
+
break;
|
|
130
|
+
// 2) Read new, never-delivered messages for this group ('>').
|
|
131
|
+
const res = await redis.xreadgroup('GROUP', group, consumer, 'COUNT', batch, 'BLOCK', blockMs, 'STREAMS', key, '>');
|
|
132
|
+
// XREADGROUP reply: [[streamKey, entries]] | null (on block timeout)
|
|
133
|
+
if (Array.isArray(res) && res.length > 0 && Array.isArray(res[0]) && res[0].length >= 2) {
|
|
134
|
+
await deliver(parseEntries(topic, res[0][1]));
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
catch (err) {
|
|
138
|
+
if (stopped)
|
|
139
|
+
break;
|
|
140
|
+
logger.warn('Event bus consumer loop error; backing off', { topic, group, error: errMsg(err) });
|
|
141
|
+
// Back off so a persistent Redis error doesn't hot-spin.
|
|
142
|
+
await new Promise((r) => setTimeout(r, 1000));
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
let loopPromise = Promise.resolve();
|
|
147
|
+
if (!started) {
|
|
148
|
+
started = true;
|
|
149
|
+
loopPromise = loop();
|
|
150
|
+
logger.info('Event bus consumer started', { topic, group, consumer });
|
|
151
|
+
}
|
|
152
|
+
return {
|
|
153
|
+
async stop() {
|
|
154
|
+
stopped = true;
|
|
155
|
+
// Await the in-flight read/handler so a caller (e.g. a service shutting
|
|
156
|
+
// down its DB) doesn't race a message still being processed. Bounded by
|
|
157
|
+
// the XREADGROUP BLOCK window. Never rejects — the loop swallows errors.
|
|
158
|
+
await loopPromise.catch(() => undefined);
|
|
159
|
+
},
|
|
160
|
+
};
|
|
161
|
+
},
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Build a durable event bus from the ambient Redis env via the shared
|
|
166
|
+
* `createEnvRedisClient`. Returns `null` when Redis is not configured — the
|
|
167
|
+
* caller then runs without a bus (today's HTTP/reconciler behavior), never
|
|
168
|
+
* crashing. Opt in with a single boot line where a service wants durable events.
|
|
169
|
+
*/
|
|
170
|
+
export function createEnvRedisDurableEventBus(opts = {}) {
|
|
171
|
+
const inst = createEnvRedisClient('event-bus');
|
|
172
|
+
if (!inst)
|
|
173
|
+
return null;
|
|
174
|
+
logger.info('Redis durable event bus initialized');
|
|
175
|
+
return createRedisDurableEventBus(inst, opts);
|
|
176
|
+
}
|
|
177
|
+
// ---------------------------------------------------------------------------
|
|
178
|
+
// Entity-event bridge (additive, opt-in)
|
|
179
|
+
//
|
|
180
|
+
// Lets a service give its in-process {@link entityEvents} emitter a DURABLE,
|
|
181
|
+
// cross-pod delivery leg WITHOUT changing existing behavior: register the
|
|
182
|
+
// returned subscriber and every entity mutation is ALSO published to the bus.
|
|
183
|
+
// A consumer elsewhere (`bus.subscribe`) then reacts at-least-once across pods
|
|
184
|
+
// and restarts. The in-process subscribers keep firing exactly as before, so
|
|
185
|
+
// this is purely additive — no double-processing unless a service intentionally
|
|
186
|
+
// runs a bus consumer for the same reaction. Kept here (not in entity-events.ts)
|
|
187
|
+
// so that module stays infrastructure-free per its own contract.
|
|
188
|
+
// ---------------------------------------------------------------------------
|
|
189
|
+
/** Topic the entity-event bridge publishes to. */
|
|
190
|
+
export const ENTITY_EVENT_TOPIC = 'entity-events';
|
|
191
|
+
/**
|
|
192
|
+
* An {@link EntityEventSubscriber} that forwards each entity event to the durable
|
|
193
|
+
* bus. `bus.publish` is fail-safe (drops-with-metric, never throws), matching the
|
|
194
|
+
* emitter's fire-and-forget contract. Note `EntityEvent.timestamp` (a Date)
|
|
195
|
+
* serializes to an ISO string on the wire — a consumer re-hydrates as needed.
|
|
196
|
+
*/
|
|
197
|
+
export function createEntityEventBusPublisher(bus) {
|
|
198
|
+
return {
|
|
199
|
+
async onEntityEvent(event) {
|
|
200
|
+
await bus.publish(ENTITY_EVENT_TOPIC, event);
|
|
201
|
+
},
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHVyYWJsZS1ldmVudC1idXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2VydmljZXMvZHVyYWJsZS1ldmVudC1idXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLHNDQUFzQztBQWdDdEMsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDdEQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ2xELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUV6RCxNQUFNLE1BQU0sR0FBRyxZQUFZLENBQUMsbUJBQW1CLENBQUMsQ0FBQztBQW9EakQsTUFBTSxjQUFjLEdBQUcsTUFBTSxDQUFDO0FBQzlCLE1BQU0sYUFBYSxHQUFHLEVBQUUsQ0FBQztBQUN6QixNQUFNLGdCQUFnQixHQUFHLEtBQUssQ0FBQztBQUMvQixNQUFNLG1CQUFtQixHQUFHLE1BQU0sQ0FBQztBQUVuQyxTQUFTLE1BQU0sQ0FBQyxHQUFZO0lBQzFCLE9BQU8sR0FBRyxZQUFZLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQzFELENBQUM7QUFFRCxTQUFTLFNBQVMsQ0FBQyxLQUFhO0lBQzlCLE9BQU8sT0FBTyxLQUFLLEVBQUUsQ0FBQztBQUN4QixDQUFDO0FBRUQsZ0ZBQWdGO0FBQ2hGLFNBQVMsV0FBVyxDQUFDLEdBQVk7SUFDL0IsT0FBTyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxDQUFDO0FBQzNDLENBQUM7QUFFRDs7Ozs7R0FLRztBQUNILFNBQVMsWUFBWSxDQUFJLEtBQWEsRUFBRSxPQUFnQjtJQUN0RCxNQUFNLEdBQUcsR0FBdUIsRUFBRSxDQUFDO0lBQ25DLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLE9B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QUMsTUFBTSxrQkFBa0IsR0FBRyxlQUFlLENBQUM7QUFFbEQ7Ozs7O0dBS0c7QUFDSCxNQUFNLFVBQVUsNkJBQTZCLENBQUMsR0FBb0I7SUFDaEUsT0FBTztRQUNMLEtBQUssQ0FBQyxhQUFhLENBQUMsS0FBa0I7WUFDcEMsTUFBTSxHQUFHLENBQUMsT0FBTyxDQUFDLGtCQUFrQixFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQy9DLENBQUM7S0FDRixDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDI2IFBpcGVsaW5lIEJ1aWxkZXIgQ29udHJpYnV0b3JzXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuXG4vKipcbiAqIER1cmFibGUsIGF0LWxlYXN0LW9uY2UgZXZlbnQgYmFja2JvbmUgKFJlZGlzIFN0cmVhbXMpLlxuICpcbiAqIFRoZSBwbGF0Zm9ybSdzIGNyb3NzLXNlcnZpY2Ugc2lnbmFsbGluZyB0b2RheSBpcyBwb2ludC10by1wb2ludCBIVFRQIHBsdXNcbiAqIHBvbGxpbmcgcmVjb25jaWxlcnMgcGx1cyBhbiBJTi1QUk9DRVNTIGJlc3QtZWZmb3J0IGVtaXR0ZXIgKHtAbGluayBlbnRpdHlFdmVudHN9KS5cbiAqIFRoZXJlIGlzIG5vIGR1cmFibGUgYnVzLCBzbyBhIHNpZ25hbCBwcm9kdWNlZCBvbiBvbmUgcG9kIGlzIGVpdGhlciBkZWxpdmVyZWRcbiAqIHN5bmNocm9ub3VzbHkgb3ZlciBIVFRQIChjb3VwbGluZyArIHJldHJ5LXN0b3JtIHJpc2spIG9yIGxvc3QgaWYgdGhlIGNvbnN1bWVyXG4gKiBpcyBtb21lbnRhcmlseSBkb3duICh0aGUgcmVjb25jaWxlcnMgZXhpc3QgdG8gcGFwZXIgb3ZlciBleGFjdGx5IHRoYXQpLlxuICpcbiAqIFRoaXMgaXMgdGhhdCBtaXNzaW5nIGJ1cywgYXMgYSByZXVzYWJsZSBwcmltaXRpdmU6XG4gKiAgLSAqKnB1Ymxpc2godG9waWMsIHBheWxvYWQpKiog4oaSIGBYQUREYCBvbnRvIGEgYm91bmRlZCAoYE1BWExFTiB+YCkgcGVyLXRvcGljXG4gKiAgICBzdHJlYW0uIER1cmFibGUgYWNyb3NzIHJlc3RhcnRzLCBzaGFyZWQgYnkgYWxsIHJlcGxpY2FzLlxuICogIC0gKipzdWJzY3JpYmUoe3RvcGljLCBncm91cCwgY29uc3VtZXIsIGhhbmRsZXJ9KSoqIOKGkiBhIGBYUkVBREdST1VQYCBjb25zdW1lci5cbiAqICAgIENvbnN1bWVyIEdST1VQUyBnaXZlIGF0LWxlYXN0LW9uY2U6IGVhY2ggZ3JvdXAgZ2V0cyBldmVyeSBtZXNzYWdlIG9uY2UsIGFcbiAqICAgIG1lc3NhZ2Ugc3RheXMgcGVuZGluZyB1bnRpbCB0aGUgaGFuZGxlciBgWEFDS2BzIGl0LCBhbmQgYFhBVVRPQ0xBSU1gXG4gKiAgICByZWNsYWltcyBtZXNzYWdlcyBzdHJhbmRlZCBieSBhIGNyYXNoZWQgY29uc3VtZXIuIE11bHRpcGxlIGdyb3VwcyBvbiBvbmVcbiAqICAgIHRvcGljID0gaW5kZXBlbmRlbnQgZmFuLW91dCAoZS5nLiBxdW90YS1zeW5jIEFORCBhdWRpdCBib3RoIHJlYWN0KS5cbiAqXG4gKiBGQUlMLVNBRkUgKyBPUFQtSU4sIGV4YWN0bHkgbGlrZSB0aGUgYXVkaXQgc3Bvb2w6IHtAbGluayBjcmVhdGVFbnZSZWRpc0R1cmFibGVFdmVudEJ1c31cbiAqIHJldHVybnMgYG51bGxgIHdoZW4gUmVkaXMgaXNuJ3QgY29uZmlndXJlZCwgc28gYSBzZXJ2aWNlIHdpdGhvdXQgaXQgc2ltcGx5XG4gKiBkb2Vzbid0IHVzZSB0aGUgYnVzIChrZWVwcyB0b2RheSdzIGJlaGF2aW9yKS4gQSBwdWJsaXNoIGZhaWx1cmUgaXMgZHJvcHBlZC13aXRoLVxuICogLW1ldHJpYywgbmV2ZXIgdGhyb3duOyBhIGhhbmRsZXIgdGhyb3cgbGVhdmVzIHRoZSBtZXNzYWdlIHVuLWFja2VkIGZvciByZWRlbGl2ZXJ5LlxuICpcbiAqIE1pZ3JhdGluZyBhIHNwZWNpZmljIHJlY29uY2lsZXIgKGUuZy4gYmlsbGluZ+KGknF1b3RhIGVudGl0bGVtZW50IHN5bmMpIG9udG8gdGhpc1xuICogaXMgZGVsaWJlcmF0ZWx5IGZvbGxvdy1vbiB3b3JrIOKAlCB0aGlzIGxhbmRzIHRoZSBiYWNrYm9uZSArIGFuIGFkZGl0aXZlIGVudGl0eS1cbiAqIGV2ZW50IGJyaWRnZTsgdGhlIHJlY29uY2lsZXJzIHN0YXkgYXMgdGhlIGJlbHQtYW5kLXN1c3BlbmRlcnMgYmFja3N0b3AgdW50aWwgYVxuICogZmxvdyBpcyBmdWxseSBjdXQgb3Zlci5cbiAqL1xuXG5pbXBvcnQgdHlwZSB7IEVudGl0eUV2ZW50LCBFbnRpdHlFdmVudFN1YnNjcmliZXIgfSBmcm9tICcuL2VudGl0eS1ldmVudHMuanMnO1xuaW1wb3J0IHsgY3JlYXRlRW52UmVkaXNDbGllbnQgfSBmcm9tICcuL2Vudi1yZWRpcy5qcyc7XG5pbXBvcnQgeyBjcmVhdGVMb2dnZXIgfSBmcm9tICcuLi91dGlscy9sb2dnZXIuanMnO1xuaW1wb3J0IHsgZW1pdENvdW50ZXIgfSBmcm9tICcuLi91dGlscy9tZXRyaWMtZW1pdHRlci5qcyc7XG5cbmNvbnN0IGxvZ2dlciA9IGNyZWF0ZUxvZ2dlcignZHVyYWJsZS1ldmVudC1idXMnKTtcblxuLyoqIEEgZGVsaXZlcmVkIGV2ZW50OiBpdHMgc3RyZWFtIGlkLCB0b3BpYywgYW5kIGRlY29kZWQgcGF5bG9hZC4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRXZlbnRFbnZlbG9wZTxUID0gdW5rbm93bj4ge1xuICAvKiogUmVkaXMgU3RyZWFtIGVudHJ5IGlkIChgPG1zPi08c2VxPmApIOKAlCBhbHNvIHRoZSBpZGVtcG90ZW5jeSBoYW5kbGUuICovXG4gIGlkOiBzdHJpbmc7XG4gIHRvcGljOiBzdHJpbmc7XG4gIHBheWxvYWQ6IFQ7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgU3Vic2NyaWJlT3B0aW9uczxUID0gdW5rbm93bj4ge1xuICAvKiogVG9waWMgKHN0cmVhbSkgdG8gY29uc3VtZS4gKi9cbiAgdG9waWM6IHN0cmluZztcbiAgLyoqIENvbnN1bWVyIGdyb3VwIOKAlCBvbmUgZGVsaXZlcnkgcGVyIGdyb3VwOyBkaXN0aW5jdCBncm91cHMgZmFuIG91dC4gKi9cbiAgZ3JvdXA6IHN0cmluZztcbiAgLyoqIFRoaXMgY29uc3VtZXIncyBpZCB3aXRoaW4gdGhlIGdyb3VwIChlLmcuIGAke3NlcnZpY2V9LSR7cGlkfWApLiAqL1xuICBjb25zdW1lcjogc3RyaW5nO1xuICAvKiogQXN5bmMgaGFuZGxlci4gUmVzb2x2ZXMg4oeSIHRoZSBtZXNzYWdlIGlzIGFja2VkOyB0aHJvd3Mg4oeSIGxlZnQgcGVuZGluZyBmb3IgcmVkZWxpdmVyeS4gKi9cbiAgaGFuZGxlcjogKGVudjogRXZlbnRFbnZlbG9wZTxUPikgPT4gUHJvbWlzZTx2b2lkPjtcbiAgLyoqIE1heCBtZXNzYWdlcyBwZXIgcmVhZCAoZGVmYXVsdCAxNikuICovXG4gIGJhdGNoU2l6ZT86IG51bWJlcjtcbiAgLyoqIFhSRUFER1JPVVAgYmxvY2sgdGltZSBpbiBtcyAoZGVmYXVsdCA1MDAwKS4gKi9cbiAgYmxvY2tNcz86IG51bWJlcjtcbiAgLyoqIEEgcGVuZGluZyBtZXNzYWdlIGlkbGUgdGhpcyBsb25nIChtcykgaXMgcmVjbGFpbWVkIGZyb20gYSBkZWFkIGNvbnN1bWVyIChkZWZhdWx0IDYwMDAwKS4gKi9cbiAgbWluSWRsZU1zPzogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEV2ZW50U3Vic2NyaXB0aW9uIHtcbiAgLyoqIFN0b3AgdGhlIGNvbnN1bWVyIGxvb3AuIFJlc29sdmVzIG9uY2UgdGhlIGluLWZsaWdodCByZWFkIHJldHVybnMuICovXG4gIHN0b3AoKTogUHJvbWlzZTx2b2lkPjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBEdXJhYmxlRXZlbnRCdXMge1xuICAvKiogUHVibGlzaCBhIHBheWxvYWQgdG8gYSB0b3BpYy4gUmV0dXJucyB0aGUgc3RyZWFtIGlkLCBvciBudWxsIG9uIGZhaWx1cmUgKGRyb3BwZWQsIG5ldmVyIHRocm93cykuICovXG4gIHB1Ymxpc2g8VD4odG9waWM6IHN0cmluZywgcGF5bG9hZDogVCk6IFByb21pc2U8c3RyaW5nIHwgbnVsbD47XG4gIC8qKiBTdGFydCBhIGNvbnN1bWVyLWdyb3VwIHJlYWRlciBmb3IgYSB0b3BpYy4gRmlyZS1hbmQtZm9yZ2V0IGxvb3A7IGNhbGwgYHN0b3AoKWAgdG8gZW5kIGl0LiAqL1xuICBzdWJzY3JpYmU8VD4ob3B0czogU3Vic2NyaWJlT3B0aW9uczxUPik6IEV2ZW50U3Vic2NyaXB0aW9uO1xufVxuXG4vKipcbiAqIFRoZSBzdWJzZXQgb2YgaW9yZWRpcycgU3RyZWFtIEFQSSB0aGUgYnVzIHVzZXMuIEtlcHQgbWluaW1hbCBzbyBhIHRlc3QgY2FuXG4gKiBzdXBwbHkgYW4gaW4tbWVtb3J5IGZha2UgYW5kIHNvIG1lcmVseSBpbXBvcnRpbmcgdGhpcyBuZXZlciBoYXJkLWRlcGVuZHMgb25cbiAqIGlvcmVkaXMgKGNvbnN0cnVjdGVkIHZpYSB0aGUgc2hhcmVkIGVudiBoZWxwZXIpLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFJlZGlzU3RyZWFtQ2xpZW50IHtcbiAgeGFkZChrZXk6IHN0cmluZywgLi4uYXJnczogKHN0cmluZyB8IG51bWJlcilbXSk6IFByb21pc2U8c3RyaW5nIHwgbnVsbD47XG4gIHhncm91cCguLi5hcmdzOiAoc3RyaW5nIHwgbnVtYmVyKVtdKTogUHJvbWlzZTx1bmtub3duPjtcbiAgeHJlYWRncm91cCguLi5hcmdzOiAoc3RyaW5nIHwgbnVtYmVyKVtdKTogUHJvbWlzZTx1bmtub3duPjtcbiAgeGFjayhrZXk6IHN0cmluZywgZ3JvdXA6IHN0cmluZywgLi4uaWRzOiBzdHJpbmdbXSk6IFByb21pc2U8bnVtYmVyPjtcbiAgeGF1dG9jbGFpbSguLi5hcmdzOiAoc3RyaW5nIHwgbnVtYmVyKVtdKTogUHJvbWlzZTx1bmtub3duPjtcbn1cblxuY29uc3QgREVGQVVMVF9NQVhMRU4gPSAxMF8wMDA7XG5jb25zdCBERUZBVUxUX0JBVENIID0gMTY7XG5jb25zdCBERUZBVUxUX0JMT0NLX01TID0gNV8wMDA7XG5jb25zdCBERUZBVUxUX01JTl9JRExFX01TID0gNjBfMDAwO1xuXG5mdW5jdGlvbiBlcnJNc2coZXJyOiB1bmtub3duKTogc3RyaW5nIHtcbiAgcmV0dXJuIGVyciBpbnN0YW5jZW9mIEVycm9yID8gZXJyLm1lc3NhZ2UgOiBTdHJpbmcoZXJyKTtcbn1cblxuZnVuY3Rpb24gc3RyZWFtS2V5KHRvcGljOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gYGV2dDoke3RvcGljfWA7XG59XG5cbi8qKiBUcnVlIHdoZW4gdGhlIGVycm9yIGlzIFJlZGlzJyBcImdyb3VwIGFscmVhZHkgZXhpc3RzXCIgKGlkZW1wb3RlbnQgY3JlYXRlKS4gKi9cbmZ1bmN0aW9uIGlzQnVzeUdyb3VwKGVycjogdW5rbm93bik6IGJvb2xlYW4ge1xuICByZXR1cm4gZXJyTXNnKGVycikuaW5jbHVkZXMoJ0JVU1lHUk9VUCcpO1xufVxuXG4vKipcbiAqIFBhcnNlIHRoZSBuZXN0ZWQgYXJyYXkgc2hhcGUgWFJFQURHUk9VUCAvIFhBVVRPQ0xBSU0gcmV0dXJuIGludG8gZmxhdCBlbnZlbG9wZXMuXG4gKiBYUkVBREdST1VQOiBgW1tzdHJlYW1LZXksIFtbaWQsIFtmLCB2LCAuLi5dXSwgLi4uXV1dYC5cbiAqIFhBVVRPQ0xBSU06IGBbbmV4dEN1cnNvciwgW1tpZCwgW2YsIHYsIC4uLl1dLCAuLi5dLCBkZWxldGVkSWRzXWAuXG4gKiBXZSBzdG9yZSB0aGUgSlNPTiBwYXlsb2FkIHVuZGVyIGEgc2luZ2xlIGZpZWxkIGBkYC5cbiAqL1xuZnVuY3Rpb24gcGFyc2VFbnRyaWVzPFQ+KHRvcGljOiBzdHJpbmcsIGVudHJpZXM6IHVua25vd24pOiBFdmVudEVudmVsb3BlPFQ+W10ge1xuICBjb25zdCBvdXQ6IEV2ZW50RW52ZWxvcGU8VD5bXSA9IFtdO1xuICBpZiAoIUFycmF5LmlzQXJyYXkoZW50cmllcykpIHJldHVybiBvdXQ7XG4gIGZvciAoY29uc3QgZW50cnkgb2YgZW50cmllcykge1xuICAgIGlmICghQXJyYXkuaXNBcnJheShlbnRyeSkgfHwgZW50cnkubGVuZ3RoIDwgMikgY29udGludWU7XG4gICAgY29uc3QgaWQgPSBTdHJpbmcoZW50cnlbMF0pO1xuICAgIGNvbnN0IGZpZWxkcyA9IGVudHJ5WzFdO1xuICAgIGlmICghQXJyYXkuaXNBcnJheShmaWVsZHMpKSBjb250aW51ZTtcbiAgICAvLyBmaWVsZHMgaXMgW25hbWUsIHZhbHVlLCBuYW1lLCB2YWx1ZSwgLi4uXTsgZmluZCAnZCcuXG4gICAgbGV0IHJhdzogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAgIGZvciAobGV0IGkgPSAwOyBpICsgMSA8IGZpZWxkcy5sZW5ndGg7IGkgKz0gMikge1xuICAgICAgaWYgKFN0cmluZyhmaWVsZHNbaV0pID09PSAnZCcpIHsgcmF3ID0gU3RyaW5nKGZpZWxkc1tpICsgMV0pOyBicmVhazsgfVxuICAgIH1cbiAgICAvLyBBIG1pc3NpbmcgYGRgIGZpZWxkIChhbiBlbnRyeSBub3Qgd3JpdHRlbiBieSBwdWJsaXNoKCkpIE9SIGEgY29ycnVwdCBKU09OXG4gICAgLy8gcGF5bG9hZCBib3RoIHlpZWxkIGFuIHVuZGVmaW5lZC1wYXlsb2FkIGVudmVsb3BlIHNvIGBkZWxpdmVyKClgIEFDS3MgaXQg4oCUXG4gICAgLy8gYSBwb2lzb24gbWVzc2FnZSBtdXN0IG5ldmVyIHdlZGdlIHRoZSBncm91cCBieSBzdGF5aW5nIHBlcnBldHVhbGx5IHBlbmRpbmcuXG4gICAgaWYgKHJhdyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBvdXQucHVzaCh7IGlkLCB0b3BpYywgcGF5bG9hZDogdW5kZWZpbmVkIGFzIHVua25vd24gYXMgVCB9KTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgb3V0LnB1c2goeyBpZCwgdG9waWMsIHBheWxvYWQ6IEpTT04ucGFyc2UocmF3KSBhcyBUIH0pO1xuICAgIH0gY2F0Y2gge1xuICAgICAgb3V0LnB1c2goeyBpZCwgdG9waWMsIHBheWxvYWQ6IHVuZGVmaW5lZCBhcyB1bmtub3duIGFzIFQgfSk7XG4gICAgfVxuICB9XG4gIHJldHVybiBvdXQ7XG59XG5cbi8qKiBCdWlsZCBhIGR1cmFibGUgZXZlbnQgYnVzIG92ZXIgYSBSZWRpcyBTdHJlYW1zIGNsaWVudC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVSZWRpc0R1cmFibGVFdmVudEJ1cyhcbiAgcmVkaXM6IFJlZGlzU3RyZWFtQ2xpZW50LFxuICBvcHRzOiB7IG1heExlbj86IG51bWJlciB9ID0ge30sXG4pOiBEdXJhYmxlRXZlbnRCdXMge1xuICBjb25zdCBtYXhMZW4gPSBNYXRoLm1heCgxLCBvcHRzLm1heExlbiA/PyBERUZBVUxUX01BWExFTik7XG5cbiAgcmV0dXJuIHtcbiAgICBhc3luYyBwdWJsaXNoPFQ+KHRvcGljOiBzdHJpbmcsIHBheWxvYWQ6IFQpOiBQcm9taXNlPHN0cmluZyB8IG51bGw+IHtcbiAgICAgIGNvbnN0IGtleSA9IHN0cmVhbUtleSh0b3BpYyk7XG4gICAgICB0cnkge1xuICAgICAgICAvLyBNQVhMRU4gfiA8bj4gYm91bmRzIHRoZSBzdHJlYW0gYXBwcm94aW1hdGVseSAoY2hlYXApOyBgKmAgPSBzZXJ2ZXIgaWQuXG4gICAgICAgIGNvbnN0IGlkID0gYXdhaXQgcmVkaXMueGFkZChrZXksICdNQVhMRU4nLCAnficsIG1heExlbiwgJyonLCAnZCcsIEpTT04uc3RyaW5naWZ5KHBheWxvYWQpKTtcbiAgICAgICAgZW1pdENvdW50ZXIoJ2V2ZW50X2J1c19wdWJsaXNoZWRfdG90YWwnLCB7IHRvcGljIH0pO1xuICAgICAgICByZXR1cm4gaWQ7XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgZW1pdENvdW50ZXIoJ2V2ZW50X2J1c19wdWJsaXNoX2ZhaWxlZF90b3RhbCcsIHsgdG9waWMgfSk7XG4gICAgICAgIGxvZ2dlci53YXJuKCdFdmVudCBidXMgcHVibGlzaCBmYWlsZWQgKGV2ZW50IGRyb3BwZWQpJywgeyB0b3BpYywgZXJyb3I6IGVyck1zZyhlcnIpIH0pO1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICB9LFxuXG4gICAgc3Vic2NyaWJlPFQ+KHN1Yk9wdHM6IFN1YnNjcmliZU9wdGlvbnM8VD4pOiBFdmVudFN1YnNjcmlwdGlvbiB7XG4gICAgICBjb25zdCB7IHRvcGljLCBncm91cCwgY29uc3VtZXIsIGhhbmRsZXIgfSA9IHN1Yk9wdHM7XG4gICAgICBjb25zdCBrZXkgPSBzdHJlYW1LZXkodG9waWMpO1xuICAgICAgY29uc3QgYmF0Y2ggPSBNYXRoLm1heCgxLCBzdWJPcHRzLmJhdGNoU2l6ZSA/PyBERUZBVUxUX0JBVENIKTtcbiAgICAgIGNvbnN0IGJsb2NrTXMgPSBNYXRoLm1heCgwLCBzdWJPcHRzLmJsb2NrTXMgPz8gREVGQVVMVF9CTE9DS19NUyk7XG4gICAgICBjb25zdCBtaW5JZGxlID0gTWF0aC5tYXgoMCwgc3ViT3B0cy5taW5JZGxlTXMgPz8gREVGQVVMVF9NSU5fSURMRV9NUyk7XG5cbiAgICAgIGxldCBzdG9wcGVkID0gZmFsc2U7XG4gICAgICBsZXQgc3RhcnRlZCA9IGZhbHNlO1xuXG4gICAgICBjb25zdCBkZWxpdmVyID0gYXN5bmMgKGVudnM6IEV2ZW50RW52ZWxvcGU8VD5bXSk6IFByb21pc2U8dm9pZD4gPT4ge1xuICAgICAgICBmb3IgKGNvbnN0IGVudiBvZiBlbnZzKSB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGlmIChlbnYucGF5bG9hZCAhPT0gdW5kZWZpbmVkKSBhd2FpdCBoYW5kbGVyKGVudik7XG4gICAgICAgICAgICAvLyBBY2sgb24gc3VjY2VzcyBPUiBvbiBhbiB1bmRlZmluZWQgKGNvcnJ1cHQpIHBheWxvYWQg4oCUIGEgcG9pc29uXG4gICAgICAgICAgICAvLyBtZXNzYWdlIG11c3Qgbm90IGJsb2NrIHRoZSBncm91cCBmb3JldmVyLlxuICAgICAgICAgICAgYXdhaXQgcmVkaXMueGFjayhrZXksIGdyb3VwLCBlbnYuaWQpO1xuICAgICAgICAgICAgZW1pdENvdW50ZXIoJ2V2ZW50X2J1c19kZWxpdmVyZWRfdG90YWwnLCB7IHRvcGljLCBncm91cCB9KTtcbiAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgIC8vIExlYXZlIGl0IHBlbmRpbmcgKG5vIFhBQ0spIOKAlCBYQVVUT0NMQUlNIHJlZGVsaXZlcnMgaXQgYWZ0ZXIgbWluSWRsZS5cbiAgICAgICAgICAgIGVtaXRDb3VudGVyKCdldmVudF9idXNfaGFuZGxlcl9mYWlsZWRfdG90YWwnLCB7IHRvcGljLCBncm91cCB9KTtcbiAgICAgICAgICAgIGxvZ2dlci53YXJuKCdFdmVudCBoYW5kbGVyIGZhaWxlZDsgbGVhdmluZyBtZXNzYWdlIHBlbmRpbmcgZm9yIHJlZGVsaXZlcnknLCB7XG4gICAgICAgICAgICAgIHRvcGljLCBncm91cCwgaWQ6IGVudi5pZCwgZXJyb3I6IGVyck1zZyhlcnIpLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9O1xuXG4gICAgICBjb25zdCBlbnN1cmVHcm91cCA9IGFzeW5jICgpOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAvLyBNS1NUUkVBTSBzbyB0aGUgc3RyZWFtIG5lZWQgbm90IGV4aXN0IHlldDsgJyQnID0gb25seSBuZXcgbWVzc2FnZXMuXG4gICAgICAgICAgYXdhaXQgcmVkaXMueGdyb3VwKCdDUkVBVEUnLCBrZXksIGdyb3VwLCAnJCcsICdNS1NUUkVBTScpO1xuICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICBpZiAoIWlzQnVzeUdyb3VwKGVycikpIHtcbiAgICAgICAgICAgIGxvZ2dlci53YXJuKCdFdmVudCBidXMgZ3JvdXAgY3JlYXRlIGZhaWxlZCcsIHsgdG9waWMsIGdyb3VwLCBlcnJvcjogZXJyTXNnKGVycikgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9O1xuXG4gICAgICBjb25zdCBsb29wID0gYXN5bmMgKCk6IFByb21pc2U8dm9pZD4gPT4ge1xuICAgICAgICBhd2FpdCBlbnN1cmVHcm91cCgpO1xuICAgICAgICB3aGlsZSAoIXN0b3BwZWQpIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgLy8gMSkgUmVjbGFpbSBtZXNzYWdlcyBzdHJhbmRlZCBieSBhIGNyYXNoZWQgY29uc3VtZXIgaW4gdGhpcyBncm91cC5cbiAgICAgICAgICAgIGNvbnN0IGNsYWltZWQgPSBhd2FpdCByZWRpcy54YXV0b2NsYWltKGtleSwgZ3JvdXAsIGNvbnN1bWVyLCBtaW5JZGxlLCAnMCcsICdDT1VOVCcsIGJhdGNoKTtcbiAgICAgICAgICAgIC8vIFhBVVRPQ0xBSU0gcmVwbHk6IFtuZXh0Q3Vyc29yLCBlbnRyaWVzLCBkZWxldGVkSWRzXVxuICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoY2xhaW1lZCkgJiYgY2xhaW1lZC5sZW5ndGggPj0gMikge1xuICAgICAgICAgICAgICBhd2FpdCBkZWxpdmVyKHBhcnNlRW50cmllczxUPih0b3BpYywgY2xhaW1lZFsxXSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHN0b3BwZWQpIGJyZWFrO1xuXG4gICAgICAgICAgICAvLyAyKSBSZWFkIG5ldywgbmV2ZXItZGVsaXZlcmVkIG1lc3NhZ2VzIGZvciB0aGlzIGdyb3VwICgnPicpLlxuICAgICAgICAgICAgY29uc3QgcmVzID0gYXdhaXQgcmVkaXMueHJlYWRncm91cChcbiAgICAgICAgICAgICAgJ0dST1VQJywgZ3JvdXAsIGNvbnN1bWVyLCAnQ09VTlQnLCBiYXRjaCwgJ0JMT0NLJywgYmxvY2tNcywgJ1NUUkVBTVMnLCBrZXksICc+JyxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICAvLyBYUkVBREdST1VQIHJlcGx5OiBbW3N0cmVhbUtleSwgZW50cmllc11dIHwgbnVsbCAob24gYmxvY2sgdGltZW91dClcbiAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KHJlcykgJiYgcmVzLmxlbmd0aCA+IDAgJiYgQXJyYXkuaXNBcnJheShyZXNbMF0pICYmIHJlc1swXS5sZW5ndGggPj0gMikge1xuICAgICAgICAgICAgICBhd2FpdCBkZWxpdmVyKHBhcnNlRW50cmllczxUPih0b3BpYywgcmVzWzBdWzFdKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICBpZiAoc3RvcHBlZCkgYnJlYWs7XG4gICAgICAgICAgICBsb2dnZXIud2FybignRXZlbnQgYnVzIGNvbnN1bWVyIGxvb3AgZXJyb3I7IGJhY2tpbmcgb2ZmJywgeyB0b3BpYywgZ3JvdXAsIGVycm9yOiBlcnJNc2coZXJyKSB9KTtcbiAgICAgICAgICAgIC8vIEJhY2sgb2ZmIHNvIGEgcGVyc2lzdGVudCBSZWRpcyBlcnJvciBkb2Vzbid0IGhvdC1zcGluLlxuICAgICAgICAgICAgYXdhaXQgbmV3IFByb21pc2UoKHIpID0+IHNldFRpbWVvdXQociwgMTAwMCkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfTtcblxuICAgICAgbGV0IGxvb3BQcm9taXNlID0gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgICBpZiAoIXN0YXJ0ZWQpIHtcbiAgICAgICAgc3RhcnRlZCA9IHRydWU7XG4gICAgICAgIGxvb3BQcm9taXNlID0gbG9vcCgpO1xuICAgICAgICBsb2dnZXIuaW5mbygnRXZlbnQgYnVzIGNvbnN1bWVyIHN0YXJ0ZWQnLCB7IHRvcGljLCBncm91cCwgY29uc3VtZXIgfSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIGFzeW5jIHN0b3AoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgICAgc3RvcHBlZCA9IHRydWU7XG4gICAgICAgICAgLy8gQXdhaXQgdGhlIGluLWZsaWdodCByZWFkL2hhbmRsZXIgc28gYSBjYWxsZXIgKGUuZy4gYSBzZXJ2aWNlIHNodXR0aW5nXG4gICAgICAgICAgLy8gZG93biBpdHMgREIpIGRvZXNuJ3QgcmFjZSBhIG1lc3NhZ2Ugc3RpbGwgYmVpbmcgcHJvY2Vzc2VkLiBCb3VuZGVkIGJ5XG4gICAgICAgICAgLy8gdGhlIFhSRUFER1JPVVAgQkxPQ0sgd2luZG93LiBOZXZlciByZWplY3RzIOKAlCB0aGUgbG9vcCBzd2FsbG93cyBlcnJvcnMuXG4gICAgICAgICAgYXdhaXQgbG9vcFByb21pc2UuY2F0Y2goKCkgPT4gdW5kZWZpbmVkKTtcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgfSxcbiAgfTtcbn1cblxuLyoqXG4gKiBCdWlsZCBhIGR1cmFibGUgZXZlbnQgYnVzIGZyb20gdGhlIGFtYmllbnQgUmVkaXMgZW52IHZpYSB0aGUgc2hhcmVkXG4gKiBgY3JlYXRlRW52UmVkaXNDbGllbnRgLiBSZXR1cm5zIGBudWxsYCB3aGVuIFJlZGlzIGlzIG5vdCBjb25maWd1cmVkIOKAlCB0aGVcbiAqIGNhbGxlciB0aGVuIHJ1bnMgd2l0aG91dCBhIGJ1cyAodG9kYXkncyBIVFRQL3JlY29uY2lsZXIgYmVoYXZpb3IpLCBuZXZlclxuICogY3Jhc2hpbmcuIE9wdCBpbiB3aXRoIGEgc2luZ2xlIGJvb3QgbGluZSB3aGVyZSBhIHNlcnZpY2Ugd2FudHMgZHVyYWJsZSBldmVudHMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVFbnZSZWRpc0R1cmFibGVFdmVudEJ1cyhvcHRzOiB7IG1heExlbj86IG51bWJlciB9ID0ge30pOiBEdXJhYmxlRXZlbnRCdXMgfCBudWxsIHtcbiAgY29uc3QgaW5zdCA9IGNyZWF0ZUVudlJlZGlzQ2xpZW50PFJlZGlzU3RyZWFtQ2xpZW50PignZXZlbnQtYnVzJyk7XG4gIGlmICghaW5zdCkgcmV0dXJuIG51bGw7XG4gIGxvZ2dlci5pbmZvKCdSZWRpcyBkdXJhYmxlIGV2ZW50IGJ1cyBpbml0aWFsaXplZCcpO1xuICByZXR1cm4gY3JlYXRlUmVkaXNEdXJhYmxlRXZlbnRCdXMoaW5zdCwgb3B0cyk7XG59XG5cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gRW50aXR5LWV2ZW50IGJyaWRnZSAoYWRkaXRpdmUsIG9wdC1pbilcbi8vXG4vLyBMZXRzIGEgc2VydmljZSBnaXZlIGl0cyBpbi1wcm9jZXNzIHtAbGluayBlbnRpdHlFdmVudHN9IGVtaXR0ZXIgYSBEVVJBQkxFLFxuLy8gY3Jvc3MtcG9kIGRlbGl2ZXJ5IGxlZyBXSVRIT1VUIGNoYW5naW5nIGV4aXN0aW5nIGJlaGF2aW9yOiByZWdpc3RlciB0aGVcbi8vIHJldHVybmVkIHN1YnNjcmliZXIgYW5kIGV2ZXJ5IGVudGl0eSBtdXRhdGlvbiBpcyBBTFNPIHB1Ymxpc2hlZCB0byB0aGUgYnVzLlxuLy8gQSBjb25zdW1lciBlbHNld2hlcmUgKGBidXMuc3Vic2NyaWJlYCkgdGhlbiByZWFjdHMgYXQtbGVhc3Qtb25jZSBhY3Jvc3MgcG9kc1xuLy8gYW5kIHJlc3RhcnRzLiBUaGUgaW4tcHJvY2VzcyBzdWJzY3JpYmVycyBrZWVwIGZpcmluZyBleGFjdGx5IGFzIGJlZm9yZSwgc29cbi8vIHRoaXMgaXMgcHVyZWx5IGFkZGl0aXZlIOKAlCBubyBkb3VibGUtcHJvY2Vzc2luZyB1bmxlc3MgYSBzZXJ2aWNlIGludGVudGlvbmFsbHlcbi8vIHJ1bnMgYSBidXMgY29uc3VtZXIgZm9yIHRoZSBzYW1lIHJlYWN0aW9uLiBLZXB0IGhlcmUgKG5vdCBpbiBlbnRpdHktZXZlbnRzLnRzKVxuLy8gc28gdGhhdCBtb2R1bGUgc3RheXMgaW5mcmFzdHJ1Y3R1cmUtZnJlZSBwZXIgaXRzIG93biBjb250cmFjdC5cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4vKiogVG9waWMgdGhlIGVudGl0eS1ldmVudCBicmlkZ2UgcHVibGlzaGVzIHRvLiAqL1xuZXhwb3J0IGNvbnN0IEVOVElUWV9FVkVOVF9UT1BJQyA9ICdlbnRpdHktZXZlbnRzJztcblxuLyoqXG4gKiBBbiB7QGxpbmsgRW50aXR5RXZlbnRTdWJzY3JpYmVyfSB0aGF0IGZvcndhcmRzIGVhY2ggZW50aXR5IGV2ZW50IHRvIHRoZSBkdXJhYmxlXG4gKiBidXMuIGBidXMucHVibGlzaGAgaXMgZmFpbC1zYWZlIChkcm9wcy13aXRoLW1ldHJpYywgbmV2ZXIgdGhyb3dzKSwgbWF0Y2hpbmcgdGhlXG4gKiBlbWl0dGVyJ3MgZmlyZS1hbmQtZm9yZ2V0IGNvbnRyYWN0LiBOb3RlIGBFbnRpdHlFdmVudC50aW1lc3RhbXBgIChhIERhdGUpXG4gKiBzZXJpYWxpemVzIHRvIGFuIElTTyBzdHJpbmcgb24gdGhlIHdpcmUg4oCUIGEgY29uc3VtZXIgcmUtaHlkcmF0ZXMgYXMgbmVlZGVkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlRW50aXR5RXZlbnRCdXNQdWJsaXNoZXIoYnVzOiBEdXJhYmxlRXZlbnRCdXMpOiBFbnRpdHlFdmVudFN1YnNjcmliZXIge1xuICByZXR1cm4ge1xuICAgIGFzeW5jIG9uRW50aXR5RXZlbnQoZXZlbnQ6IEVudGl0eUV2ZW50KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICBhd2FpdCBidXMucHVibGlzaChFTlRJVFlfRVZFTlRfVE9QSUMsIGV2ZW50KTtcbiAgICB9LFxuICB9O1xufVxuIl19
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
// Copyright 2026 Pipeline Builder Contributors
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
import * as http from 'http';
|
|
4
|
+
import { getCircuitBreaker, CircuitOpenError } from './circuit-breaker.js';
|
|
4
5
|
import { DEFAULT_MAX_RETRIES, DEFAULT_RETRY_DELAY_MS, DEFAULT_MAX_RATE_LIMIT_RETRIES, getRetryDecision, getErrorRetryDecision, } from './retry-strategy.js';
|
|
5
6
|
import { HttpStatus } from '../constants/http-status.js';
|
|
6
7
|
import { createLogger } from '../utils/logger.js';
|
|
8
|
+
import { emitCounter } from '../utils/metric-emitter.js';
|
|
7
9
|
const logger = createLogger('http-client');
|
|
8
10
|
/**
|
|
9
11
|
* Default request timeout in milliseconds (env: `HTTP_CLIENT_TIMEOUT`).
|
|
@@ -91,6 +93,13 @@ export class InternalHttpClient {
|
|
|
91
93
|
* - All delays include ±25% jitter to prevent thundering herd.
|
|
92
94
|
*/
|
|
93
95
|
async requestWithRetry(method, path, body, options) {
|
|
96
|
+
// A malformed path is a CLIENT bug, not a downstream fault — reject it up
|
|
97
|
+
// front so it never burns retries or feeds the circuit breaker (which would
|
|
98
|
+
// otherwise shed traffic to a perfectly healthy downstream). request() keeps
|
|
99
|
+
// the same guard as defence-in-depth.
|
|
100
|
+
if (path.includes('://') || path.startsWith('//') || /[\r\n\0]/.test(path)) {
|
|
101
|
+
throw new Error(`Invalid request path: ${path}`);
|
|
102
|
+
}
|
|
94
103
|
const retryConfig = {
|
|
95
104
|
maxRetries: options?.maxRetries ?? DEFAULT_MAX_RETRIES,
|
|
96
105
|
maxRateLimitRetries: options?.maxRateLimitRetries ?? DEFAULT_MAX_RATE_LIMIT_RETRIES,
|
|
@@ -106,6 +115,17 @@ export class InternalHttpClient {
|
|
|
106
115
|
const retrySafe = IDEMPOTENT_METHODS.has(method.toUpperCase()) ||
|
|
107
116
|
options?.idempotent === true ||
|
|
108
117
|
!!(options?.headers && (options.headers['Idempotency-Key'] || options.headers['idempotency-key']));
|
|
118
|
+
// Per-target circuit breaker + S2S request metrics. `target` is the shared
|
|
119
|
+
// breaker/metric key so one bad downstream trips once (not once-per-client)
|
|
120
|
+
// and dashboards can see S2S health per callee.
|
|
121
|
+
const target = `${this.config.host}:${this.config.port}`;
|
|
122
|
+
const breaker = getCircuitBreaker(target);
|
|
123
|
+
if (!breaker.allowRequest()) {
|
|
124
|
+
// Fast-fail without touching the network — this is the load-shedding that
|
|
125
|
+
// prevents a downstream brownout from cascading via retry storms.
|
|
126
|
+
emitCounter('s2s_requests_total', { target, method, outcome: 'circuit_open' });
|
|
127
|
+
throw new CircuitOpenError(target);
|
|
128
|
+
}
|
|
109
129
|
let lastError;
|
|
110
130
|
for (let attempt = 0; attempt <= totalMaxAttempts; attempt++) {
|
|
111
131
|
try {
|
|
@@ -115,9 +135,22 @@ export class InternalHttpClient {
|
|
|
115
135
|
// 5xx/gateway error is only retried when the request is retry-safe.
|
|
116
136
|
if (decision.shouldRetry && (response.statusCode === 429 || retrySafe)) {
|
|
117
137
|
logger.debug(decision.reason + ', retrying', { method, path, attempt: attempt + 1, delayMs: decision.delayMs });
|
|
138
|
+
emitCounter('s2s_request_retries_total', { target, method });
|
|
118
139
|
await this.sleep(decision.delayMs);
|
|
119
140
|
continue;
|
|
120
141
|
}
|
|
142
|
+
// Terminal response. A 5xx is a downstream fault (feeds the breaker); a
|
|
143
|
+
// 429 is backpressure, not a fault — the service answered, so it counts
|
|
144
|
+
// as success for breaker purposes (never trip the breaker on rate limits).
|
|
145
|
+
const isServerFault = response.statusCode >= 500 && response.statusCode <= 599;
|
|
146
|
+
if (isServerFault) {
|
|
147
|
+
breaker.recordFailure();
|
|
148
|
+
emitCounter('s2s_requests_total', { target, method, outcome: 'server_error' });
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
breaker.recordSuccess();
|
|
152
|
+
emitCounter('s2s_requests_total', { target, method, outcome: 'success' });
|
|
153
|
+
}
|
|
121
154
|
return response;
|
|
122
155
|
}
|
|
123
156
|
catch (error) {
|
|
@@ -125,13 +158,20 @@ export class InternalHttpClient {
|
|
|
125
158
|
const decision = getErrorRetryDecision(attempt, retryConfig);
|
|
126
159
|
if (decision.shouldRetry && retrySafe) {
|
|
127
160
|
logger.debug('Retrying after error', { method, path, error: lastError.message, attempt: attempt + 1 });
|
|
161
|
+
emitCounter('s2s_request_retries_total', { target, method });
|
|
128
162
|
await this.sleep(decision.delayMs);
|
|
129
163
|
continue;
|
|
130
164
|
}
|
|
131
|
-
// Not retrying (non-idempotent, or attempts exhausted) —
|
|
165
|
+
// Not retrying (non-idempotent, or attempts exhausted) — a connection
|
|
166
|
+
// error/timeout is a downstream fault: feed the breaker and fail now.
|
|
167
|
+
breaker.recordFailure();
|
|
168
|
+
emitCounter('s2s_requests_total', { target, method, outcome: 'error' });
|
|
132
169
|
throw lastError;
|
|
133
170
|
}
|
|
134
171
|
}
|
|
172
|
+
// Loop exhausted without returning (all attempts retried then ran out).
|
|
173
|
+
breaker.recordFailure();
|
|
174
|
+
emitCounter('s2s_requests_total', { target, method, outcome: 'error' });
|
|
135
175
|
throw lastError;
|
|
136
176
|
}
|
|
137
177
|
sleep(ms) {
|
|
@@ -292,4 +332,4 @@ export function createSafeClient(config, options) {
|
|
|
292
332
|
},
|
|
293
333
|
};
|
|
294
334
|
}
|
|
295
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaHR0cC1jbGllbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2VydmljZXMvaHR0cC1jbGllbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLHNDQUFzQztBQUV0QyxPQUFPLEtBQUssSUFBSSxNQUFNLE1BQU0sQ0FBQztBQUM3QixPQUFPLEVBQ0wsbUJBQW1CLEVBQ25CLHNCQUFzQixFQUN0Qiw4QkFBOEIsRUFDOUIsZ0JBQWdCLEVBQ2hCLHFCQUFxQixHQUV0QixNQUFNLHFCQUFxQixDQUFDO0FBQzdCLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUV6RCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFFbEQsTUFBTSxNQUFNLEdBQUcsWUFBWSxDQUFDLGFBQWEsQ0FBQyxDQUFDO0FBRTNDOztHQUVHO0FBQ0gsTUFBTSxlQUFlLEdBQUcsUUFBUSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsbUJBQW1CLElBQUksTUFBTSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0FBRWhGOzs7Ozs7R0FNRztBQUNILE1BQU0sbUJBQW1CLEdBQUcsUUFBUSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsdUJBQXVCLElBQUksSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0FBRXRGLDJFQUEyRTtBQUMzRSxrRUFBa0U7QUFDbEUsTUFBTSxrQkFBa0IsR0FBRyxJQUFJLEdBQUcsQ0FBQyxDQUFDLEtBQUssRUFBRSxNQUFNLEVBQUUsU0FBUyxDQUFDLENBQUMsQ0FBQztBQW9FL0QsTUFBTSxPQUFPLGtCQUFrQjtJQUNyQixNQUFNLENBQTBCO0lBQ2hDLEtBQUssQ0FBYTtJQUMxQixtRkFBbUY7SUFDbEUsU0FBUyxDQUFVO0lBRXBDOzs7OztPQUtHO0lBQ0gsWUFBWSxNQUFxQixFQUFFLE9BQTJCO1FBQzVELElBQUksQ0FBQyxNQUFNLEdBQUc7WUFDWixJQUFJLEVBQUUsTUFBTSxDQUFDLElBQUk7WUFDakIsSUFBSSxFQUFFLE1BQU0sQ0FBQyxJQUFJO1lBQ2pCLE9BQU8sRUFBRSxNQUFNLENBQUMsT0FBTyxJQUFJLGVBQWU7U0FDM0MsQ0FBQztRQUNGLElBQUksT0FBTyxFQUFFLEtBQUssRUFBRSxDQUFDO1lBQ25CLDZFQUE2RTtZQUM3RSxJQUFJLENBQUMsS0FBSyxHQUFHLE9BQU8sQ0FBQyxLQUFLLENBQUM7WUFDM0IsSUFBSSxDQUFDLFNBQVMsR0FBRyxLQUFLLENBQUM7UUFDekIsQ0FBQzthQUFNLENBQUM7WUFDTix3RUFBd0U7WUFDeEUsSUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSxPQUFPLEVBQUUsVUFBVSxJQUFJLG1CQUFtQixFQUFFLENBQUMsQ0FBQztZQUN6RyxJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQztRQUN4QixDQUFDO0lBQ0gsQ0FBQztJQUVEOzs7O09BSUc7SUFDSCxPQUFPO1FBQ0wsSUFBSSxJQUFJLENBQUMsU0FBUztZQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFLENBQUM7SUFDM0MsQ0FBQztJQUVEOztPQUVHO0lBQ0gsS0FBSyxDQUFDLEdBQUcsQ0FBYyxJQUFZLEVBQUUsT0FBd0I7UUFDM0QsT0FBTyxJQUFJLENBQUMsZ0JBQWdCLENBQUksS0FBSyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDbkUsQ0FBQztJQUVEOztPQUVHO0lBQ0gsS0FBSyxDQUFDLElBQUksQ0FDUixJQUFZLEVBQ1osSUFBYyxFQUNkLE9BQXdCO1FBRXhCLE9BQU8sSUFBSSxDQUFDLGdCQUFnQixDQUFJLE1BQU0sRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBQy9ELENBQUM7SUFFRDs7T0FFRztJQUNILEtBQUssQ0FBQyxHQUFHLENBQ1AsSUFBWSxFQUNaLElBQWMsRUFDZCxPQUF3QjtRQUV4QixPQUFPLElBQUksQ0FBQyxnQkFBZ0IsQ0FBSSxLQUFLLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxPQUFPLENBQUMsQ0FBQztJQUM5RCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxLQUFLLENBQUMsTUFBTSxDQUFjLElBQVksRUFBRSxPQUF3QjtRQUM5RCxPQUFPLElBQUksQ0FBQyxnQkFBZ0IsQ0FBSSxRQUFRLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxPQUFPLENBQUMsQ0FBQztJQUN0RSxDQUFDO0lBRUQ7Ozs7Ozs7O09BUUc7SUFDSyxLQUFLLENBQUMsZ0JBQWdCLENBQzVCLE1BQWMsRUFDZCxJQUFZLEVBQ1osSUFBYyxFQUNkLE9BQXdCO1FBRXhCLE1BQU0sV0FBVyxHQUFnQjtZQUMvQixVQUFVLEVBQUUsT0FBTyxFQUFFLFVBQVUsSUFBSSxtQkFBbUI7WUFDdEQsbUJBQW1CLEVBQUUsT0FBTyxFQUFFLG1CQUFtQixJQUFJLDhCQUE4QjtZQUNuRixZQUFZLEVBQUUsT0FBTyxFQUFFLFlBQVksSUFBSSxzQkFBc0I7U0FDOUQsQ0FBQztRQUNGLE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxXQUFXLENBQUMsVUFBVSxFQUFFLFdBQVcsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO1FBRTNGLDRFQUE0RTtRQUM1RSw0RUFBNEU7UUFDNUUseUVBQXlFO1FBQ3pFLDZFQUE2RTtRQUM3RSw0RUFBNEU7UUFDNUUsOEVBQThFO1FBQzlFLE1BQU0sU0FBUyxHQUNiLGtCQUFrQixDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDNUMsT0FBTyxFQUFFLFVBQVUsS0FBSyxJQUFJO1lBQzVCLENBQUMsQ0FBQyxDQUFDLE9BQU8sRUFBRSxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLGlCQUFpQixDQUFDLElBQUksT0FBTyxDQUFDLE9BQU8sQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUVyRyxJQUFJLFNBQTRCLENBQUM7UUFFakMsS0FBSyxJQUFJLE9BQU8sR0FBRyxDQUFDLEVBQUUsT0FBTyxJQUFJLGdCQUFnQixFQUFFLE9BQU8sRUFBRSxFQUFFLENBQUM7WUFDN0QsSUFBSSxDQUFDO2dCQUNILE1BQU0sUUFBUSxHQUFHLE1BQU0sSUFBSSxDQUFDLE9BQU8sQ0FBSSxNQUFNLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxPQUFPLENBQUMsQ0FBQztnQkFFcEUsTUFBTSxRQUFRLEdBQUcsZ0JBQWdCLENBQUMsUUFBUSxDQUFDLFVBQVUsRUFBRSxRQUFRLENBQUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxXQUFXLENBQUMsQ0FBQztnQkFDL0Ysd0VBQXdFO2dCQUN4RSxvRUFBb0U7Z0JBQ3BFLElBQUksUUFBUSxDQUFDLFdBQVcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxVQUFVLEtBQUssR0FBRyxJQUFJLFNBQVMsQ0FBQyxFQUFFLENBQUM7b0JBQ3ZFLE1BQU0sQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLE1BQU0sR0FBRyxZQUFZLEVBQUUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxPQUFPLEdBQUcsQ0FBQyxFQUFFLE9BQU8sRUFBRSxRQUFRLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztvQkFDaEgsTUFBTSxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQztvQkFDbkMsU0FBUztnQkFDWCxDQUFDO2dCQUVELE9BQU8sUUFBUSxDQUFDO1lBQ2xCLENBQUM7WUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO2dCQUNmLFNBQVMsR0FBRyxLQUFLLFlBQVksS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLElBQUksS0FBSyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO2dCQUV0RSxNQUFNLFFBQVEsR0FBRyxxQkFBcUIsQ0FBQyxPQUFPLEVBQUUsV0FBVyxDQUFDLENBQUM7Z0JBQzdELElBQUksUUFBUSxDQUFDLFdBQVcsSUFBSSxTQUFTLEVBQUUsQ0FBQztvQkFDdEMsTUFBTSxDQUFDLEtBQUssQ0FBQyxzQkFBc0IsRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLFNBQVMsQ0FBQyxPQUFPLEVBQUUsT0FBTyxFQUFFLE9BQU8sR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDO29CQUN2RyxNQUFNLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDO29CQUNuQyxTQUFTO2dCQUNYLENBQUM7Z0JBQ0QsbUVBQW1FO2dCQUNuRSxNQUFNLFNBQVMsQ0FBQztZQUNsQixDQUFDO1FBQ0gsQ0FBQztRQUVELE1BQU0sU0FBVSxDQUFDO0lBQ25CLENBQUM7SUFFTyxLQUFLLENBQUMsRUFBVTtRQUN0QixPQUFPLElBQUksT0FBTyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsVUFBVSxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ3pELENBQUM7SUFFRDs7T0FFRztJQUNLLE9BQU8sQ0FDYixNQUFjLEVBQ2QsSUFBWSxFQUNaLElBQWMsRUFDZCxPQUF3QjtRQUV4QixPQUFPLElBQUksT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxFQUFFO1lBQ3JDLHFGQUFxRjtZQUNyRixNQUFNLE9BQU8sR0FBRyxJQUFJLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7WUFFdEUsTUFBTSxPQUFPLEdBQTZCO2dCQUN4QyxjQUFjLEVBQUUsa0JBQWtCO2dCQUNsQyxHQUFHLE9BQU8sRUFBRSxPQUFPO2FBQ3BCLENBQUM7WUFFRiwrQ0FBK0M7WUFDL0MsSUFBSSxPQUFPLEVBQUUsU0FBUyxFQUFFLENBQUM7Z0JBQ3ZCLE9BQU8sQ0FBQyxjQUFjLENBQUMsR0FBRyxPQUFPLENBQUMsU0FBUyxDQUFDO1lBQzlDLENBQUM7WUFFRCxJQUFJLE9BQU8sRUFBRSxDQUFDO2dCQUNaLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDekQsQ0FBQztZQUVELGtFQUFrRTtZQUNsRSxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsSUFBSSxVQUFVLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7Z0JBQzNFLE1BQU0sSUFBSSxLQUFLLENBQUMseUJBQXlCLElBQUksRUFBRSxDQUFDLENBQUM7WUFDbkQsQ0FBQztZQUVELE1BQU0sY0FBYyxHQUF3QjtnQkFDMUMsUUFBUSxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSTtnQkFDMUIsSUFBSSxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSTtnQkFDdEIsSUFBSSxFQUFFLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxJQUFJLEVBQUU7Z0JBQzlDLE1BQU07Z0JBQ04sT0FBTztnQkFDUCxPQUFPLEVBQUUsT0FBTyxFQUFFLE9BQU8sSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU87Z0JBQ2hELEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSzthQUNsQixDQUFDO1lBRUYsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxjQUFjLEVBQUUsQ0FBQyxHQUFHLEVBQUUsRUFBRTtnQkFDL0MsSUFBSSxJQUFJLEdBQUcsRUFBRSxDQUFDO2dCQUVkLEdBQUcsQ0FBQyxFQUFFLENBQUMsTUFBTSxFQUFFLENBQUMsS0FBSyxFQUFFLEVBQUU7b0JBQ3ZCLElBQUksSUFBSSxLQUFLLENBQUM7Z0JBQ2hCLENBQUMsQ0FBQyxDQUFDO2dCQUVILEdBQUcsQ0FBQyxFQUFFLENBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRTtvQkFDakIsSUFBSSxDQUFDO3dCQUNILE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO3dCQUNoRCxPQUFPLENBQUM7NEJBQ04sVUFBVSxFQUFFLEdBQUcsQ0FBQyxVQUFVLElBQUksVUFBVSxDQUFDLHFCQUFxQjs0QkFDOUQsSUFBSSxFQUFFLFVBQWU7NEJBQ3JCLE9BQU8sRUFBRSxHQUFHLENBQUMsT0FBTzt5QkFDckIsQ0FBQyxDQUFDO29CQUNMLENBQUM7b0JBQUMsT0FBTyxVQUFVLEVBQUUsQ0FBQzt3QkFDcEIsTUFBTSxDQUFDLElBQUksQ0FBQywrQkFBK0IsRUFBRTs0QkFDM0MsSUFBSSxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSTs0QkFDdEIsSUFBSTs0QkFDSixLQUFLLEVBQUUsVUFBVSxZQUFZLEtBQUssQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQzt5QkFDN0UsQ0FBQyxDQUFDO3dCQUNILE9BQU8sQ0FBQzs0QkFDTixVQUFVLEVBQUUsR0FBRyxDQUFDLFVBQVUsSUFBSSxVQUFVLENBQUMscUJBQXFCOzRCQUM5RCxJQUFJLEVBQUUsRUFBTzs0QkFDYixPQUFPLEVBQUUsR0FBRyxDQUFDLE9BQU87eUJBQ3JCLENBQUMsQ0FBQztvQkFDTCxDQUFDO2dCQUNILENBQUMsQ0FBQyxDQUFDO1lBQ0wsQ0FBQyxDQUFDLENBQUM7WUFFSCxHQUFHLENBQUMsRUFBRSxDQUFDLE9BQU8sRUFBRSxDQUFDLEtBQUssRUFBRSxFQUFFO2dCQUN4Qix1RUFBdUU7Z0JBQ3ZFLHFFQUFxRTtnQkFDckUsNENBQTRDO2dCQUM1QyxNQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsT0FBTyxJQUFLLEtBQStCLENBQUMsSUFBSSxJQUFJLEtBQUssQ0FBQyxJQUFJLENBQUM7Z0JBQ3BGLE1BQU0sQ0FBQyxLQUFLLENBQUMscUJBQXFCLEVBQUU7b0JBQ2xDLElBQUksRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUk7b0JBQ3RCLElBQUksRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUk7b0JBQ3RCLElBQUk7b0JBQ0osTUFBTTtvQkFDTixLQUFLLEVBQUUsTUFBTTtpQkFDZCxDQUFDLENBQUM7Z0JBQ0gsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ2hCLENBQUMsQ0FBQyxDQUFDO1lBRUgsR0FBRyxDQUFDLEVBQUUsQ0FBQyxTQUFTLEVBQUUsR0FBRyxFQUFFO2dCQUNyQixHQUFHLENBQUMsT0FBTyxFQUFFLENBQUM7Z0JBQ2QsTUFBTSxLQUFLLEdBQUcsSUFBSSxLQUFLLENBQUMseUJBQXlCLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxJQUFJLENBQUMsQ0FBQztnQkFDMUUsTUFBTSxDQUFDLElBQUksQ0FBQyxzQkFBc0IsRUFBRTtvQkFDbEMsSUFBSSxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSTtvQkFDdEIsSUFBSTtvQkFDSixPQUFPLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPO2lCQUM3QixDQUFDLENBQUM7Z0JBQ0gsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ2hCLENBQUMsQ0FBQyxDQUFDO1lBRUgsSUFBSSxPQUFPLEVBQUUsQ0FBQztnQkFDWixHQUFHLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQ3JCLENBQUM7WUFFRCxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUM7UUFDWixDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7Q0FDRjtBQUVEOzs7Ozs7R0FNRztBQUNILE1BQU0sVUFBVSxnQkFBZ0IsQ0FBQyxNQUFxQixFQUFFLE9BQTJCO0lBQ2pGLE1BQU0sTUFBTSxHQUFHLElBQUksa0JBQWtCLENBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBRXZELE9BQU87UUFDTCxpRkFBaUY7UUFDakYsT0FBTztZQUNMLE1BQU0sQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUNuQixDQUFDO1FBRUQ7O1dBRUc7UUFDSCxLQUFLLENBQUMsR0FBRyxDQUFJLElBQVksRUFBRSxPQUF3QjtZQUNqRCxJQUFJLENBQUM7Z0JBQ0gsT0FBTyxNQUFNLE1BQU0sQ0FBQyxHQUFHLENBQUksSUFBSSxFQUFFLE9BQU8sQ0FBQyxDQUFDO1lBQzVDLENBQUM7WUFBQyxPQUFPLEdBQUcsRUFBRSxDQUFDO2dCQUNiLE1BQU0sQ0FBQyxLQUFLLENBQUMsaUNBQWlDLEVBQUUsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLEdBQUcsWUFBWSxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUM7Z0JBQ25ILE9BQU8sSUFBSSxDQUFDO1lBQ2QsQ0FBQztRQUNILENBQUM7UUFFRDs7V0FFRztRQUNILEtBQUssQ0FBQyxJQUFJLENBQ1IsSUFBWSxFQUNaLElBQWMsRUFDZCxPQUF3QjtZQUV4QixJQUFJLENBQUM7Z0JBQ0gsT0FBTyxNQUFNLE1BQU0sQ0FBQyxJQUFJLENBQUksSUFBSSxFQUFFLElBQUksRUFBRSxPQUFPLENBQUMsQ0FBQztZQUNuRCxDQUFDO1lBQUMsT0FBTyxHQUFHLEVBQUUsQ0FBQztnQkFDYixNQUFNLENBQUMsS0FBSyxDQUFDLGtDQUFrQyxFQUFFLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxHQUFHLFlBQVksS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDO2dCQUNwSCxPQUFPLElBQUksQ0FBQztZQUNkLENBQUM7UUFDSCxDQUFDO1FBRUQ7O1dBRUc7UUFDSCxLQUFLLENBQUMsR0FBRyxDQUNQLElBQVksRUFDWixJQUFjLEVBQ2QsT0FBd0I7WUFFeEIsSUFBSSxDQUFDO2dCQUNILE9BQU8sTUFBTSxNQUFNLENBQUMsR0FBRyxDQUFJLElBQUksRUFBRSxJQUFJLEVBQUUsT0FBTyxDQUFDLENBQUM7WUFDbEQsQ0FBQztZQUFDLE9BQU8sR0FBRyxFQUFFLENBQUM7Z0JBQ2IsTUFBTSxDQUFDLEtBQUssQ0FBQyxpQ0FBaUMsRUFBRSxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsR0FBRyxZQUFZLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztnQkFDbkgsT0FBTyxJQUFJLENBQUM7WUFDZCxDQUFDO1FBQ0gsQ0FBQztRQUVEOzs7V0FHRztRQUNILEtBQUssQ0FBQyxNQUFNLENBQ1YsSUFBWSxFQUNaLE9BQXdCO1lBRXhCLElBQUksQ0FBQztnQkFDSCxPQUFPLE1BQU0sTUFBTSxDQUFDLE1BQU0sQ0FBSSxJQUFJLEVBQUUsT0FBTyxDQUFDLENBQUM7WUFDL0MsQ0FBQztZQUFDLE9BQU8sR0FBRyxFQUFFLENBQUM7Z0JBQ2IsTUFBTSxDQUFDLEtBQUssQ0FBQyxvQ0FBb0MsRUFBRSxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsR0FBRyxZQUFZLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztnQkFDdEgsT0FBTyxJQUFJLENBQUM7WUFDZCxDQUFDO1FBQ0gsQ0FBQztLQUNGLENBQUM7QUFDSixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMjYgUGlwZWxpbmUgQnVpbGRlciBDb250cmlidXRvcnNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5cbmltcG9ydCAqIGFzIGh0dHAgZnJvbSAnaHR0cCc7XG5pbXBvcnQge1xuICBERUZBVUxUX01BWF9SRVRSSUVTLFxuICBERUZBVUxUX1JFVFJZX0RFTEFZX01TLFxuICBERUZBVUxUX01BWF9SQVRFX0xJTUlUX1JFVFJJRVMsXG4gIGdldFJldHJ5RGVjaXNpb24sXG4gIGdldEVycm9yUmV0cnlEZWNpc2lvbixcbiAgdHlwZSBSZXRyeUNvbmZpZyxcbn0gZnJvbSAnLi9yZXRyeS1zdHJhdGVneS5qcyc7XG5pbXBvcnQgeyBIdHRwU3RhdHVzIH0gZnJvbSAnLi4vY29uc3RhbnRzL2h0dHAtc3RhdHVzLmpzJztcbmltcG9ydCB0eXBlIHsgU2VydmljZUNvbmZpZyB9IGZyb20gJy4uL3R5cGVzL2NvbW1vbi5qcyc7XG5pbXBvcnQgeyBjcmVhdGVMb2dnZXIgfSBmcm9tICcuLi91dGlscy9sb2dnZXIuanMnO1xuXG5jb25zdCBsb2dnZXIgPSBjcmVhdGVMb2dnZXIoJ2h0dHAtY2xpZW50Jyk7XG5cbi8qKlxuICogRGVmYXVsdCByZXF1ZXN0IHRpbWVvdXQgaW4gbWlsbGlzZWNvbmRzIChlbnY6IGBIVFRQX0NMSUVOVF9USU1FT1VUYCkuXG4gKi9cbmNvbnN0IERFRkFVTFRfVElNRU9VVCA9IHBhcnNlSW50KHByb2Nlc3MuZW52LkhUVFBfQ0xJRU5UX1RJTUVPVVQgfHwgJzUwMDAnLCAxMCk7XG5cbi8qKlxuICogRGVmYXVsdCBjYXAgb24gY29uY3VycmVudCBrZWVwLWFsaXZlIHNvY2tldHMgcGVyIGNsaWVudCBhZ2VudFxuICogKGVudjogYEhUVFBfQ0xJRU5UX01BWF9TT0NLRVRTYCkuIE5vZGUncyBkZWZhdWx0IGlzIGBJbmZpbml0eWAsIHdoaWNoIGxldHMgYVxuICogYnVyc3Qgb2YgY29uY3VycmVudCBjYWxscyBvcGVuIHVuYm91bmRlZCBzb2NrZXRzIGFnYWluc3QgYSBkb3duc3RyZWFtIHNlcnZpY2VcbiAqIChmZCBleGhhdXN0aW9uICsgY29ubmVjdGlvbi1zdG9ybSBvbiB0aGUgY2FsbGVlKS4gNjQgaXMgYW1wbGUgZm9yXG4gKiBzZXJ2aWNlLXRvLXNlcnZpY2UgZmFuLW91dCB3aGlsZSBzdGF5aW5nIGJvdW5kZWQuXG4gKi9cbmNvbnN0IERFRkFVTFRfTUFYX1NPQ0tFVFMgPSBwYXJzZUludChwcm9jZXNzLmVudi5IVFRQX0NMSUVOVF9NQVhfU09DS0VUUyB8fCAnNjQnLCAxMCk7XG5cbi8vIEhUVFAgbWV0aG9kcyB0aGF0IGFyZSBpZGVtcG90ZW50IGJ5IGRlZmluaXRpb24g4oCUIHNhZmUgdG8gYXV0by1yZXRyeSBvbiBhXG4vLyA1eHgvY29ubmVjdGlvbi90aW1lb3V0IHdpdGhvdXQgcmlza2luZyBhIGR1cGxpY2F0ZSBzaWRlIGVmZmVjdC5cbmNvbnN0IElERU1QT1RFTlRfTUVUSE9EUyA9IG5ldyBTZXQoWydHRVQnLCAnSEVBRCcsICdPUFRJT05TJ10pO1xuXG4vKipcbiAqIEhUVFAgcmVxdWVzdCBvcHRpb25zLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFJlcXVlc3RPcHRpb25zIHtcbiAgLyoqIFJlcXVlc3QgaGVhZGVycyAqL1xuICBoZWFkZXJzPzogUmVjb3JkPHN0cmluZywgc3RyaW5nPjtcbiAgLyoqIFJlcXVlc3QgdGltZW91dCBpbiBtaWxsaXNlY29uZHMgKi9cbiAgdGltZW91dD86IG51bWJlcjtcbiAgLyoqIE1heGltdW0gcmV0cnkgYXR0ZW1wdHMgZm9yIHRyYW5zaWVudCBmYWlsdXJlcyAoZGVmYXVsdDogMikgKi9cbiAgbWF4UmV0cmllcz86IG51bWJlcjtcbiAgLyoqIEJhc2UgZGVsYXkgYmV0d2VlbiByZXRyaWVzIGluIG1zIOKAlCBkb3VibGVzIGVhY2ggYXR0ZW1wdCAoZGVmYXVsdDogMjAwKSAqL1xuICByZXRyeURlbGF5TXM/OiBudW1iZXI7XG4gIC8qKiBNYXhpbXVtIHJldHJ5IGF0dGVtcHRzIHNwZWNpZmljYWxseSBmb3IgNDI5IHJhdGUgbGltaXRpbmcgKGRlZmF1bHQ6IDQpICovXG4gIG1heFJhdGVMaW1pdFJldHJpZXM/OiBudW1iZXI7XG4gIC8qKiBPcHRpb25hbCByZXF1ZXN0IElEIGZvciBkaXN0cmlidXRlZCB0cmFjaW5nIChhZGRlZCBhcyBYLVJlcXVlc3QtSWQgaGVhZGVyKSAqL1xuICByZXF1ZXN0SWQ/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBUcmVhdCB0aGlzIHJlcXVlc3QgYXMgc2FmZSB0byBhdXRvLXJldHJ5IG9uIDV4eC9jb25uZWN0aW9uL3RpbWVvdXQgZXZlblxuICAgKiB0aG91Z2ggdGhlIG1ldGhvZCBpcyBub24taWRlbXBvdGVudCAoZS5nLiB0aGUgZW5kcG9pbnQgaXMgaWRlbXBvdGVudCBieSBhblxuICAgKiBJZGVtcG90ZW5jeS1LZXksIG9yIHRoZSBvcGVyYXRpb24gaXMgbmF0dXJhbGx5IGlkZW1wb3RlbnQpLiBEZWZhdWx0IGZhbHNlOlxuICAgKiBub24taWRlbXBvdGVudCBtZXRob2RzIGFyZSBOT1QgcmV0cmllZCBvbiB0aG9zZSBmYWlsdXJlcywgb25seSBvbiA0MjkuXG4gICAqL1xuICBpZGVtcG90ZW50PzogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBIVFRQIGNsaWVudCByZXNwb25zZSB3cmFwcGVyLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEh0dHBDbGllbnRSZXNwb25zZTxUID0gdW5rbm93bj4ge1xuICAvKiogSFRUUCBzdGF0dXMgY29kZSAqL1xuICBzdGF0dXNDb2RlOiBudW1iZXI7XG4gIC8qKiBSZXNwb25zZSBib2R5IChwYXJzZWQgSlNPTikgKi9cbiAgYm9keTogVDtcbiAgLyoqIFJlc3BvbnNlIGhlYWRlcnMgKi9cbiAgaGVhZGVyczogaHR0cC5JbmNvbWluZ0h0dHBIZWFkZXJzO1xufVxuXG4vKipcbiAqIEludGVybmFsIEhUVFAgY2xpZW50IGZvciBzZXJ2aWNlLXRvLXNlcnZpY2UgY29tbXVuaWNhdGlvbi5cbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgY2xpZW50ID0gbmV3IEludGVybmFsSHR0cENsaWVudCh7XG4gKiAgIGhvc3Q6ICdxdW90YScsXG4gKiAgIHBvcnQ6IDMwMDAsXG4gKiAgIHRpbWVvdXQ6IDUwMDAsXG4gKiB9KTtcbiAqXG4gKiBjb25zdCByZXNwb25zZSA9IGF3YWl0IGNsaWVudC5nZXQoJy9vcmcxMjMvYXBpQ2FsbHMnKTtcbiAqIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGNsaWVudC5wb3N0KCcvb3JnMTIzL2luY3JlbWVudCcsIHsgcXVvdGFUeXBlOiAnYXBpQ2FsbHMnIH0pO1xuICogYGBgXG4gKi9cbi8qKlxuICogT3B0aW9ucyBjb250cm9sbGluZyB0aGUgY2xpZW50J3MgY29ubmVjdGlvbiBwb29sLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEh0dHBDbGllbnRPcHRpb25zIHtcbiAgLyoqXG4gICAqIEEgc2hhcmVkIGBodHRwLkFnZW50YCB0byByZXVzZSBhY3Jvc3MgY2xpZW50cyAocG9vbHMgc29ja2V0cyB0byB0aGUgc2FtZVxuICAgKiBob3N0KS4gV2hlbiBzdXBwbGllZCwgdGhlIGNsaWVudCBkb2VzIE5PVCBvd24gaXQg4oCUIHtAbGluayBJbnRlcm5hbEh0dHBDbGllbnQuZGVzdHJveX1cbiAgICogbGVhdmVzIGEgYm9ycm93ZWQgYWdlbnQgdW50b3VjaGVkIHNvIG90aGVyIGNsaWVudHMga2VlcCB3b3JraW5nLlxuICAgKi9cbiAgYWdlbnQ/OiBodHRwLkFnZW50O1xuICAvKiogQ2FwIG9uIGNvbmN1cnJlbnQga2VlcC1hbGl2ZSBzb2NrZXRzIHdoZW4gbWludGluZyBhbiBhZ2VudCAoZGVmYXVsdCA2NCkuICovXG4gIG1heFNvY2tldHM/OiBudW1iZXI7XG59XG5cbmV4cG9ydCBjbGFzcyBJbnRlcm5hbEh0dHBDbGllbnQge1xuICBwcml2YXRlIGNvbmZpZzogUmVxdWlyZWQ8U2VydmljZUNvbmZpZz47XG4gIHByaXZhdGUgYWdlbnQ6IGh0dHAuQWdlbnQ7XG4gIC8qKiBUcnVlIG9ubHkgd2hlbiB0aGlzIGNsaWVudCBNSU5URUQgaXRzIGFnZW50IChzbyBkZXN0cm95KCkgbWF5IHRlYXIgaXQgZG93bikuICovXG4gIHByaXZhdGUgcmVhZG9ubHkgb3duc0FnZW50OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBuZXcgSFRUUCBjbGllbnQgaW5zdGFuY2UuXG4gICAqXG4gICAqIEBwYXJhbSBjb25maWcgLSBTZXJ2aWNlIGNvbmZpZ3VyYXRpb25cbiAgICogQHBhcmFtIG9wdGlvbnMgLSBPcHRpb25hbCBjb25uZWN0aW9uLXBvb2wgY29udHJvbHMgKHNoYXJlZCBhZ2VudCAvIHNvY2tldCBjYXApXG4gICAqL1xuICBjb25zdHJ1Y3Rvcihjb25maWc6IFNlcnZpY2VDb25maWcsIG9wdGlvbnM/OiBIdHRwQ2xpZW50T3B0aW9ucykge1xuICAgIHRoaXMuY29uZmlnID0ge1xuICAgICAgaG9zdDogY29uZmlnLmhvc3QsXG4gICAgICBwb3J0OiBjb25maWcucG9ydCxcbiAgICAgIHRpbWVvdXQ6IGNvbmZpZy50aW1lb3V0ID8/IERFRkFVTFRfVElNRU9VVCxcbiAgICB9O1xuICAgIGlmIChvcHRpb25zPy5hZ2VudCkge1xuICAgICAgLy8gQm9ycm93ZWQsIGNhbGxlci1vd25lZCBhZ2VudCDigJQgcG9vbGVkIGFjcm9zcyBjbGllbnRzLCBub3Qgb3VycyB0byBkZXN0cm95LlxuICAgICAgdGhpcy5hZ2VudCA9IG9wdGlvbnMuYWdlbnQ7XG4gICAgICB0aGlzLm93bnNBZ2VudCA9IGZhbHNlO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBPd24gYSBrZWVwLWFsaXZlIGFnZW50IHdpdGggYSBCT1VOREVEIHNvY2tldCBwb29sIChubyBtb3JlIEluZmluaXR5KS5cbiAgICAgIHRoaXMuYWdlbnQgPSBuZXcgaHR0cC5BZ2VudCh7IGtlZXBBbGl2ZTogdHJ1ZSwgbWF4U29ja2V0czogb3B0aW9ucz8ubWF4U29ja2V0cyA/PyBERUZBVUxUX01BWF9TT0NLRVRTIH0pO1xuICAgICAgdGhpcy5vd25zQWdlbnQgPSB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZWxlYXNlIHRoZSBrZWVwLWFsaXZlIHNvY2tldCBwb29sLiBJZGVtcG90ZW50IGFuZCBzYWZlIHRvIGNhbGwgb24gc2h1dGRvd24uXG4gICAqIEEgYm9ycm93ZWQgKGNhbGxlci1zdXBwbGllZCkgYWdlbnQgaXMgbGVmdCBpbnRhY3Qg4oCUIG9ubHkgYW4gYWdlbnQgdGhpcyBjbGllbnRcbiAgICogY3JlYXRlZCBpcyBkZXN0cm95ZWQsIHNvIHRlYXJpbmcgZG93biBvbmUgY2xpZW50IGNhbid0IHNldmVyIGFub3RoZXIncyBwb29sLlxuICAgKi9cbiAgZGVzdHJveSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5vd25zQWdlbnQpIHRoaXMuYWdlbnQuZGVzdHJveSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIE1ha2UgYSBHRVQgcmVxdWVzdC5cbiAgICovXG4gIGFzeW5jIGdldDxUID0gdW5rbm93bj4ocGF0aDogc3RyaW5nLCBvcHRpb25zPzogUmVxdWVzdE9wdGlvbnMpOiBQcm9taXNlPEh0dHBDbGllbnRSZXNwb25zZTxUPj4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3RXaXRoUmV0cnk8VD4oJ0dFVCcsIHBhdGgsIHVuZGVmaW5lZCwgb3B0aW9ucyk7XG4gIH1cblxuICAvKipcbiAgICogTWFrZSBhIFBPU1QgcmVxdWVzdC5cbiAgICovXG4gIGFzeW5jIHBvc3Q8VCA9IHVua25vd24+KFxuICAgIHBhdGg6IHN0cmluZyxcbiAgICBib2R5PzogdW5rbm93bixcbiAgICBvcHRpb25zPzogUmVxdWVzdE9wdGlvbnMsXG4gICk6IFByb21pc2U8SHR0cENsaWVudFJlc3BvbnNlPFQ+PiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdFdpdGhSZXRyeTxUPignUE9TVCcsIHBhdGgsIGJvZHksIG9wdGlvbnMpO1xuICB9XG5cbiAgLyoqXG4gICAqIE1ha2UgYSBQVVQgcmVxdWVzdC5cbiAgICovXG4gIGFzeW5jIHB1dDxUID0gdW5rbm93bj4oXG4gICAgcGF0aDogc3RyaW5nLFxuICAgIGJvZHk/OiB1bmtub3duLFxuICAgIG9wdGlvbnM/OiBSZXF1ZXN0T3B0aW9ucyxcbiAgKTogUHJvbWlzZTxIdHRwQ2xpZW50UmVzcG9uc2U8VD4+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0V2l0aFJldHJ5PFQ+KCdQVVQnLCBwYXRoLCBib2R5LCBvcHRpb25zKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNYWtlIGEgREVMRVRFIHJlcXVlc3QuXG4gICAqL1xuICBhc3luYyBkZWxldGU8VCA9IHVua25vd24+KHBhdGg6IHN0cmluZywgb3B0aW9ucz86IFJlcXVlc3RPcHRpb25zKTogUHJvbWlzZTxIdHRwQ2xpZW50UmVzcG9uc2U8VD4+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0V2l0aFJldHJ5PFQ+KCdERUxFVEUnLCBwYXRoLCB1bmRlZmluZWQsIG9wdGlvbnMpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlcXVlc3Qgd2l0aCByZXRyeSBsb2dpYyBmb3IgdHJhbnNpZW50IGZhaWx1cmVzLlxuICAgKlxuICAgKiAtIDQyOSAocmF0ZSBsaW1pdCk6IHJlc3BlY3RzIGBSZXRyeS1BZnRlcmAgaGVhZGVyLCB1c2VzIGxvbmdlciBiYXNlIGRlbGF5ICg0eCksXG4gICAqICAgcmV0cmllcyB1cCB0byBgbWF4UmF0ZUxpbWl0UmV0cmllc2AgdGltZXMgKGRlZmF1bHQgNCkuXG4gICAqIC0gNTAyLzUwMy81MDQgKHNlcnZlciBlcnJvcnMpOiBzdGFuZGFyZCBleHBvbmVudGlhbCBiYWNrb2ZmLCB1cCB0byBgbWF4UmV0cmllc2AgKGRlZmF1bHQgMikuXG4gICAqIC0gQ29ubmVjdGlvbiBlcnJvcnMgLyB0aW1lb3V0czogcmV0cmllcyB1cCB0byBgbWF4UmV0cmllc2AuXG4gICAqIC0gQWxsIGRlbGF5cyBpbmNsdWRlIMKxMjUlIGppdHRlciB0byBwcmV2ZW50IHRodW5kZXJpbmcgaGVyZC5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgcmVxdWVzdFdpdGhSZXRyeTxUPihcbiAgICBtZXRob2Q6IHN0cmluZyxcbiAgICBwYXRoOiBzdHJpbmcsXG4gICAgYm9keT86IHVua25vd24sXG4gICAgb3B0aW9ucz86IFJlcXVlc3RPcHRpb25zLFxuICApOiBQcm9taXNlPEh0dHBDbGllbnRSZXNwb25zZTxUPj4ge1xuICAgIGNvbnN0IHJldHJ5Q29uZmlnOiBSZXRyeUNvbmZpZyA9IHtcbiAgICAgIG1heFJldHJpZXM6IG9wdGlvbnM/Lm1heFJldHJpZXMgPz8gREVGQVVMVF9NQVhfUkVUUklFUyxcbiAgICAgIG1heFJhdGVMaW1pdFJldHJpZXM6IG9wdGlvbnM/Lm1heFJhdGVMaW1pdFJldHJpZXMgPz8gREVGQVVMVF9NQVhfUkFURV9MSU1JVF9SRVRSSUVTLFxuICAgICAgcmV0cnlEZWxheU1zOiBvcHRpb25zPy5yZXRyeURlbGF5TXMgPz8gREVGQVVMVF9SRVRSWV9ERUxBWV9NUyxcbiAgICB9O1xuICAgIGNvbnN0IHRvdGFsTWF4QXR0ZW1wdHMgPSBNYXRoLm1heChyZXRyeUNvbmZpZy5tYXhSZXRyaWVzLCByZXRyeUNvbmZpZy5tYXhSYXRlTGltaXRSZXRyaWVzKTtcblxuICAgIC8vIFdoZXRoZXIgaXQncyBzYWZlIHRvIGF1dG8tcmV0cnkgdGhpcyByZXF1ZXN0IG9uIGEgNXh4L2Nvbm5lY3Rpb24vdGltZW91dC5cbiAgICAvLyBBIHRpbWVkLW91dCBQT1NUIG1heSBoYXZlIGFscmVhZHkgYmVlbiBwcm9jZXNzZWQgc2VydmVyLXNpZGUsIHNvIHJldHJ5aW5nXG4gICAgLy8gYSBub24taWRlbXBvdGVudCByZXF1ZXN0IHJpc2tzIGEgRFVQTElDQVRFIHNpZGUgZWZmZWN0IChkb3VibGUtY2hhcmdlLFxuICAgIC8vIGRvdWJsZS1jcmVhdGUpLiBPbmx5IEdFVC9IRUFEL09QVElPTlMsIGFuIGV4cGxpY2l0IGBpZGVtcG90ZW50YCBvcHQtaW4sIG9yXG4gICAgLy8gYSByZXF1ZXN0IGNhcnJ5aW5nIGFuIElkZW1wb3RlbmN5LUtleSBhcmUgYXV0by1yZXRyaWVkIG9uIHRob3NlIGZhaWx1cmVzLlxuICAgIC8vICg0MjkgaXMgYWx3YXlzIHJldHJpZWQg4oCUIHNlZSBiZWxvdyDigJQgc2luY2UgaXQgd2FzIHJlamVjdGVkLCBub3QgcHJvY2Vzc2VkLilcbiAgICBjb25zdCByZXRyeVNhZmUgPVxuICAgICAgSURFTVBPVEVOVF9NRVRIT0RTLmhhcyhtZXRob2QudG9VcHBlckNhc2UoKSkgfHxcbiAgICAgIG9wdGlvbnM/LmlkZW1wb3RlbnQgPT09IHRydWUgfHxcbiAgICAgICEhKG9wdGlvbnM/LmhlYWRlcnMgJiYgKG9wdGlvbnMuaGVhZGVyc1snSWRlbXBvdGVuY3ktS2V5J10gfHwgb3B0aW9ucy5oZWFkZXJzWydpZGVtcG90ZW5jeS1rZXknXSkpO1xuXG4gICAgbGV0IGxhc3RFcnJvcjogRXJyb3IgfCB1bmRlZmluZWQ7XG5cbiAgICBmb3IgKGxldCBhdHRlbXB0ID0gMDsgYXR0ZW1wdCA8PSB0b3RhbE1heEF0dGVtcHRzOyBhdHRlbXB0KyspIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy5yZXF1ZXN0PFQ+KG1ldGhvZCwgcGF0aCwgYm9keSwgb3B0aW9ucyk7XG5cbiAgICAgICAgY29uc3QgZGVjaXNpb24gPSBnZXRSZXRyeURlY2lzaW9uKHJlc3BvbnNlLnN0YXR1c0NvZGUsIHJlc3BvbnNlLmhlYWRlcnMsIGF0dGVtcHQsIHJldHJ5Q29uZmlnKTtcbiAgICAgICAgLy8gNDI5IGlzIHNhZmUgdG8gcmV0cnkgZm9yIEFOWSBtZXRob2QgKHJhdGUtbGltaXRlZCDihpIgbm90IHByb2Nlc3NlZCk7IGFcbiAgICAgICAgLy8gNXh4L2dhdGV3YXkgZXJyb3IgaXMgb25seSByZXRyaWVkIHdoZW4gdGhlIHJlcXVlc3QgaXMgcmV0cnktc2FmZS5cbiAgICAgICAgaWYgKGRlY2lzaW9uLnNob3VsZFJldHJ5ICYmIChyZXNwb25zZS5zdGF0dXNDb2RlID09PSA0MjkgfHwgcmV0cnlTYWZlKSkge1xuICAgICAgICAgIGxvZ2dlci5kZWJ1ZyhkZWNpc2lvbi5yZWFzb24gKyAnLCByZXRyeWluZycsIHsgbWV0aG9kLCBwYXRoLCBhdHRlbXB0OiBhdHRlbXB0ICsgMSwgZGVsYXlNczogZGVjaXNpb24uZGVsYXlNcyB9KTtcbiAgICAgICAgICBhd2FpdCB0aGlzLnNsZWVwKGRlY2lzaW9uLmRlbGF5TXMpO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgbGFzdEVycm9yID0gZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yIDogbmV3IEVycm9yKFN0cmluZyhlcnJvcikpO1xuXG4gICAgICAgIGNvbnN0IGRlY2lzaW9uID0gZ2V0RXJyb3JSZXRyeURlY2lzaW9uKGF0dGVtcHQsIHJldHJ5Q29uZmlnKTtcbiAgICAgICAgaWYgKGRlY2lzaW9uLnNob3VsZFJldHJ5ICYmIHJldHJ5U2FmZSkge1xuICAgICAgICAgIGxvZ2dlci5kZWJ1ZygnUmV0cnlpbmcgYWZ0ZXIgZXJyb3InLCB7IG1ldGhvZCwgcGF0aCwgZXJyb3I6IGxhc3RFcnJvci5tZXNzYWdlLCBhdHRlbXB0OiBhdHRlbXB0ICsgMSB9KTtcbiAgICAgICAgICBhd2FpdCB0aGlzLnNsZWVwKGRlY2lzaW9uLmRlbGF5TXMpO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIC8vIE5vdCByZXRyeWluZyAobm9uLWlkZW1wb3RlbnQsIG9yIGF0dGVtcHRzIGV4aGF1c3RlZCkg4oCUIGZhaWwgbm93LlxuICAgICAgICB0aHJvdyBsYXN0RXJyb3I7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhyb3cgbGFzdEVycm9yITtcbiAgfVxuXG4gIHByaXZhdGUgc2xlZXAobXM6IG51bWJlcik6IFByb21pc2U8dm9pZD4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHNldFRpbWVvdXQocmVzb2x2ZSwgbXMpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBJbnRlcm5hbCByZXF1ZXN0IG1ldGhvZC5cbiAgICovXG4gIHByaXZhdGUgcmVxdWVzdDxUPihcbiAgICBtZXRob2Q6IHN0cmluZyxcbiAgICBwYXRoOiBzdHJpbmcsXG4gICAgYm9keT86IHVua25vd24sXG4gICAgb3B0aW9ucz86IFJlcXVlc3RPcHRpb25zLFxuICApOiBQcm9taXNlPEh0dHBDbGllbnRSZXNwb25zZTxUPj4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAvLyBTZXJpYWxpemUgd2hlbiBib2R5IGlzIGRlZmluZWQgKGluY2x1ZGluZyAwL2ZhbHNlLycnIHdoaWNoIGFyZSB2YWxpZCBKU09OIHZhbHVlcykuXG4gICAgICBjb25zdCBib2R5U3RyID0gYm9keSAhPT0gdW5kZWZpbmVkID8gSlNPTi5zdHJpbmdpZnkoYm9keSkgOiB1bmRlZmluZWQ7XG5cbiAgICAgIGNvbnN0IGhlYWRlcnM6IGh0dHAuT3V0Z29pbmdIdHRwSGVhZGVycyA9IHtcbiAgICAgICAgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgICAgLi4ub3B0aW9ucz8uaGVhZGVycyxcbiAgICAgIH07XG5cbiAgICAgIC8vIFByb3BhZ2F0ZSByZXF1ZXN0IElEIGZvciBkaXN0cmlidXRlZCB0cmFjaW5nXG4gICAgICBpZiAob3B0aW9ucz8ucmVxdWVzdElkKSB7XG4gICAgICAgIGhlYWRlcnNbJ1gtUmVxdWVzdC1JZCddID0gb3B0aW9ucy5yZXF1ZXN0SWQ7XG4gICAgICB9XG5cbiAgICAgIGlmIChib2R5U3RyKSB7XG4gICAgICAgIGhlYWRlcnNbJ0NvbnRlbnQtTGVuZ3RoJ10gPSBCdWZmZXIuYnl0ZUxlbmd0aChib2R5U3RyKTtcbiAgICAgIH1cblxuICAgICAgLy8gVmFsaWRhdGUgcGF0aCB0byBwcmV2ZW50IHByb3RvY29sIGluamVjdGlvbiAvIHJlcXVlc3Qgc211Z2dsaW5nXG4gICAgICBpZiAocGF0aC5pbmNsdWRlcygnOi8vJykgfHwgcGF0aC5zdGFydHNXaXRoKCcvLycpIHx8IC9bXFxyXFxuXFwwXS8udGVzdChwYXRoKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgcmVxdWVzdCBwYXRoOiAke3BhdGh9YCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHJlcXVlc3RPcHRpb25zOiBodHRwLlJlcXVlc3RPcHRpb25zID0ge1xuICAgICAgICBob3N0bmFtZTogdGhpcy5jb25maWcuaG9zdCxcbiAgICAgICAgcG9ydDogdGhpcy5jb25maWcucG9ydCxcbiAgICAgICAgcGF0aDogcGF0aC5zdGFydHNXaXRoKCcvJykgPyBwYXRoIDogYC8ke3BhdGh9YCxcbiAgICAgICAgbWV0aG9kLFxuICAgICAgICBoZWFkZXJzLFxuICAgICAgICB0aW1lb3V0OiBvcHRpb25zPy50aW1lb3V0ID8/IHRoaXMuY29uZmlnLnRpbWVvdXQsXG4gICAgICAgIGFnZW50OiB0aGlzLmFnZW50LFxuICAgICAgfTtcblxuICAgICAgY29uc3QgcmVxID0gaHR0cC5yZXF1ZXN0KHJlcXVlc3RPcHRpb25zLCAocmVzKSA9PiB7XG4gICAgICAgIGxldCBkYXRhID0gJyc7XG5cbiAgICAgICAgcmVzLm9uKCdkYXRhJywgKGNodW5rKSA9PiB7XG4gICAgICAgICAgZGF0YSArPSBjaHVuaztcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmVzLm9uKCdlbmQnLCAoKSA9PiB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IHBhcnNlZEJvZHkgPSBkYXRhID8gSlNPTi5wYXJzZShkYXRhKSA6IHt9O1xuICAgICAgICAgICAgcmVzb2x2ZSh7XG4gICAgICAgICAgICAgIHN0YXR1c0NvZGU6IHJlcy5zdGF0dXNDb2RlIHx8IEh0dHBTdGF0dXMuSU5URVJOQUxfU0VSVkVSX0VSUk9SLFxuICAgICAgICAgICAgICBib2R5OiBwYXJzZWRCb2R5IGFzIFQsXG4gICAgICAgICAgICAgIGhlYWRlcnM6IHJlcy5oZWFkZXJzLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSBjYXRjaCAocGFyc2VFcnJvcikge1xuICAgICAgICAgICAgbG9nZ2VyLndhcm4oJ0ZhaWxlZCB0byBwYXJzZSByZXNwb25zZSBib2R5Jywge1xuICAgICAgICAgICAgICBob3N0OiB0aGlzLmNvbmZpZy5ob3N0LFxuICAgICAgICAgICAgICBwYXRoLFxuICAgICAgICAgICAgICBlcnJvcjogcGFyc2VFcnJvciBpbnN0YW5jZW9mIEVycm9yID8gcGFyc2VFcnJvci5tZXNzYWdlIDogU3RyaW5nKHBhcnNlRXJyb3IpLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXNvbHZlKHtcbiAgICAgICAgICAgICAgc3RhdHVzQ29kZTogcmVzLnN0YXR1c0NvZGUgfHwgSHR0cFN0YXR1cy5JTlRFUk5BTF9TRVJWRVJfRVJST1IsXG4gICAgICAgICAgICAgIGJvZHk6IHt9IGFzIFQsXG4gICAgICAgICAgICAgIGhlYWRlcnM6IHJlcy5oZWFkZXJzLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICByZXEub24oJ2Vycm9yJywgKGVycm9yKSA9PiB7XG4gICAgICAgIC8vIE5vZGUgZHVhbC1zdGFjayBjb25uZWN0IGZhaWx1cmVzIGFyZSBhbiBBZ2dyZWdhdGVFcnJvciB3aXRoIGFuIGVtcHR5XG4gICAgICAgIC8vIGAubWVzc2FnZWA7IHRoZSBjYXVzZSBpcyBpbiBgLmNvZGVgIChFQ09OTlJFRlVTRUQvRVRJTUVET1VUKS4gRmFsbFxuICAgICAgICAvLyBiYWNrIHNvIHRoZSBsb2cgaXNuJ3QgYSBibGFuayBgZXJyb3I6XCJcImAuXG4gICAgICAgIGNvbnN0IGRldGFpbCA9IGVycm9yLm1lc3NhZ2UgfHwgKGVycm9yIGFzIE5vZGVKUy5FcnJub0V4Y2VwdGlvbikuY29kZSB8fCBlcnJvci5uYW1lO1xuICAgICAgICBsb2dnZXIuZXJyb3IoJ0hUVFAgcmVxdWVzdCBmYWlsZWQnLCB7XG4gICAgICAgICAgaG9zdDogdGhpcy5jb25maWcuaG9zdCxcbiAgICAgICAgICBwb3J0OiB0aGlzLmNvbmZpZy5wb3J0LFxuICAgICAgICAgIHBhdGgsXG4gICAgICAgICAgbWV0aG9kLFxuICAgICAgICAgIGVycm9yOiBkZXRhaWwsXG4gICAgICAgIH0pO1xuICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgfSk7XG5cbiAgICAgIHJlcS5vbigndGltZW91dCcsICgpID0+IHtcbiAgICAgICAgcmVxLmRlc3Ryb3koKTtcbiAgICAgICAgY29uc3QgZXJyb3IgPSBuZXcgRXJyb3IoYFJlcXVlc3QgdGltZW91dCBhZnRlciAke3RoaXMuY29uZmlnLnRpbWVvdXR9bXNgKTtcbiAgICAgICAgbG9nZ2VyLndhcm4oJ0hUVFAgcmVxdWVzdCB0aW1lb3V0Jywge1xuICAgICAgICAgIGhvc3Q6IHRoaXMuY29uZmlnLmhvc3QsXG4gICAgICAgICAgcGF0aCxcbiAgICAgICAgICB0aW1lb3V0OiB0aGlzLmNvbmZpZy50aW1lb3V0LFxuICAgICAgICB9KTtcbiAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgIH0pO1xuXG4gICAgICBpZiAoYm9keVN0cikge1xuICAgICAgICByZXEud3JpdGUoYm9keVN0cik7XG4gICAgICB9XG5cbiAgICAgIHJlcS5lbmQoKTtcbiAgICB9KTtcbiAgfVxufVxuXG4vKipcbiAqIENyZWF0ZSBhbiBIVFRQIGNsaWVudCB3aXRoIGVycm9yIGhhbmRsaW5nIHRoYXQgcmV0dXJucyBudWxsIG9uIGZhaWx1cmUuXG4gKiBVc2VmdWwgZm9yIGZhaWwtb3BlbiBzY2VuYXJpb3MuXG4gKlxuICogQHBhcmFtIGNvbmZpZyAtIFNlcnZpY2UgY29uZmlndXJhdGlvblxuICogQHJldHVybnMgQ2xpZW50IHdyYXBwZXIgd2l0aCBzYWZlIG1ldGhvZHNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVNhZmVDbGllbnQoY29uZmlnOiBTZXJ2aWNlQ29uZmlnLCBvcHRpb25zPzogSHR0cENsaWVudE9wdGlvbnMpIHtcbiAgY29uc3QgY2xpZW50ID0gbmV3IEludGVybmFsSHR0cENsaWVudChjb25maWcsIG9wdGlvbnMpO1xuXG4gIHJldHVybiB7XG4gICAgLyoqIFJlbGVhc2UgdGhlIHVuZGVybHlpbmcga2VlcC1hbGl2ZSBzb2NrZXQgcG9vbCAobm8tb3Agb24gYSBib3Jyb3dlZCBhZ2VudCkuICovXG4gICAgZGVzdHJveSgpOiB2b2lkIHtcbiAgICAgIGNsaWVudC5kZXN0cm95KCk7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFNhZmUgR0VUIHJlcXVlc3QgLSByZXR1cm5zIG51bGwgb24gZXJyb3IuXG4gICAgICovXG4gICAgYXN5bmMgZ2V0PFQ+KHBhdGg6IHN0cmluZywgb3B0aW9ucz86IFJlcXVlc3RPcHRpb25zKTogUHJvbWlzZTxIdHRwQ2xpZW50UmVzcG9uc2U8VD4gfCBudWxsPiB7XG4gICAgICB0cnkge1xuICAgICAgICByZXR1cm4gYXdhaXQgY2xpZW50LmdldDxUPihwYXRoLCBvcHRpb25zKTtcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBsb2dnZXIuZGVidWcoJ1NhZmUgR0VUIGZhaWxlZCwgcmV0dXJuaW5nIG51bGwnLCB7IHBhdGgsIGVycm9yOiBlcnIgaW5zdGFuY2VvZiBFcnJvciA/IGVyci5tZXNzYWdlIDogU3RyaW5nKGVycikgfSk7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBTYWZlIFBPU1QgcmVxdWVzdCAtIHJldHVybnMgbnVsbCBvbiBlcnJvci5cbiAgICAgKi9cbiAgICBhc3luYyBwb3N0PFQ+KFxuICAgICAgcGF0aDogc3RyaW5nLFxuICAgICAgYm9keT86IHVua25vd24sXG4gICAgICBvcHRpb25zPzogUmVxdWVzdE9wdGlvbnMsXG4gICAgKTogUHJvbWlzZTxIdHRwQ2xpZW50UmVzcG9uc2U8VD4gfCBudWxsPiB7XG4gICAgICB0cnkge1xuICAgICAgICByZXR1cm4gYXdhaXQgY2xpZW50LnBvc3Q8VD4ocGF0aCwgYm9keSwgb3B0aW9ucyk7XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgbG9nZ2VyLmRlYnVnKCdTYWZlIFBPU1QgZmFpbGVkLCByZXR1cm5pbmcgbnVsbCcsIHsgcGF0aCwgZXJyb3I6IGVyciBpbnN0YW5jZW9mIEVycm9yID8gZXJyLm1lc3NhZ2UgOiBTdHJpbmcoZXJyKSB9KTtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFNhZmUgUFVUIHJlcXVlc3QgLSByZXR1cm5zIG51bGwgb24gZXJyb3IuXG4gICAgICovXG4gICAgYXN5bmMgcHV0PFQ+KFxuICAgICAgcGF0aDogc3RyaW5nLFxuICAgICAgYm9keT86IHVua25vd24sXG4gICAgICBvcHRpb25zPzogUmVxdWVzdE9wdGlvbnMsXG4gICAgKTogUHJvbWlzZTxIdHRwQ2xpZW50UmVzcG9uc2U8VD4gfCBudWxsPiB7XG4gICAgICB0cnkge1xuICAgICAgICByZXR1cm4gYXdhaXQgY2xpZW50LnB1dDxUPihwYXRoLCBib2R5LCBvcHRpb25zKTtcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBsb2dnZXIuZGVidWcoJ1NhZmUgUFVUIGZhaWxlZCwgcmV0dXJuaW5nIG51bGwnLCB7IHBhdGgsIGVycm9yOiBlcnIgaW5zdGFuY2VvZiBFcnJvciA/IGVyci5tZXNzYWdlIDogU3RyaW5nKGVycikgfSk7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBTYWZlIERFTEVURSByZXF1ZXN0IC0gcmV0dXJucyBudWxsIG9uIGVycm9yLiBVc2VkIGJ5IGRlc3RydWN0aXZlXG4gICAgICogY3Jvc3Mtc2VydmljZSBvcGVyYXRpb25zIChlLmcuIG9yZy1jYXNjYWRlIGRlbGV0ZSBpbiBwbGF0Zm9ybSkuXG4gICAgICovXG4gICAgYXN5bmMgZGVsZXRlPFQ+KFxuICAgICAgcGF0aDogc3RyaW5nLFxuICAgICAgb3B0aW9ucz86IFJlcXVlc3RPcHRpb25zLFxuICAgICk6IFByb21pc2U8SHR0cENsaWVudFJlc3BvbnNlPFQ+IHwgbnVsbD4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IGNsaWVudC5kZWxldGU8VD4ocGF0aCwgb3B0aW9ucyk7XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgbG9nZ2VyLmRlYnVnKCdTYWZlIERFTEVURSBmYWlsZWQsIHJldHVybmluZyBudWxsJywgeyBwYXRoLCBlcnJvcjogZXJyIGluc3RhbmNlb2YgRXJyb3IgPyBlcnIubWVzc2FnZSA6IFN0cmluZyhlcnIpIH0pO1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICB9LFxuICB9O1xufVxuIl19
|
|
335
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaHR0cC1jbGllbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2VydmljZXMvaHR0cC1jbGllbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLHNDQUFzQztBQUV0QyxPQUFPLEtBQUssSUFBSSxNQUFNLE1BQU0sQ0FBQztBQUM3QixPQUFPLEVBQUUsaUJBQWlCLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUMzRSxPQUFPLEVBQ0wsbUJBQW1CLEVBQ25CLHNCQUFzQixFQUN0Qiw4QkFBOEIsRUFDOUIsZ0JBQWdCLEVBQ2hCLHFCQUFxQixHQUV0QixNQUFNLHFCQUFxQixDQUFDO0FBQzdCLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUV6RCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDbEQsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBRXpELE1BQU0sTUFBTSxHQUFHLFlBQVksQ0FBQyxhQUFhLENBQUMsQ0FBQztBQUUzQzs7R0FFRztBQUNILE1BQU0sZUFBZSxHQUFHLFFBQVEsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLG1CQUFtQixJQUFJLE1BQU0sRUFBRSxFQUFFLENBQUMsQ0FBQztBQUVoRjs7Ozs7O0dBTUc7QUFDSCxNQUFNLG1CQUFtQixHQUFHLFFBQVEsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLHVCQUF1QixJQUFJLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQztBQUV0RiwyRUFBMkU7QUFDM0Usa0VBQWtFO0FBQ2xFLE1BQU0sa0JBQWtCLEdBQUcsSUFBSSxHQUFHLENBQUMsQ0FBQyxLQUFLLEVBQUUsTUFBTSxFQUFFLFNBQVMsQ0FBQyxDQUFDLENBQUM7QUFvRS9ELE1BQU0sT0FBTyxrQkFBa0I7SUFDckIsTUFBTSxDQUEwQjtJQUNoQyxLQUFLLENBQWE7SUFDMUIsbUZBQW1GO0lBQ2xFLFNBQVMsQ0FBVTtJQUVwQzs7Ozs7T0FLRztJQUNILFlBQVksTUFBcUIsRUFBRSxPQUEyQjtRQUM1RCxJQUFJLENBQUMsTUFBTSxHQUFHO1lBQ1osSUFBSSxFQUFFLE1BQU0sQ0FBQyxJQUFJO1lBQ2pCLElBQUksRUFBRSxNQUFNLENBQUMsSUFBSTtZQUNqQixPQUFPLEVBQUUsTUFBTSxDQUFDLE9BQU8sSUFBSSxlQUFlO1NBQzNDLENBQUM7UUFDRixJQUFJLE9BQU8sRUFBRSxLQUFLLEVBQUUsQ0FBQztZQUNuQiw2RUFBNkU7WUFDN0UsSUFBSSxDQUFDLEtBQUssR0FBRyxPQUFPLENBQUMsS0FBSyxDQUFDO1lBQzNCLElBQUksQ0FBQyxTQUFTLEdBQUcsS0FBSyxDQUFDO1FBQ3pCLENBQUM7YUFBTSxDQUFDO1lBQ04sd0VBQXdFO1lBQ3hFLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUUsT0FBTyxFQUFFLFVBQVUsSUFBSSxtQkFBbUIsRUFBRSxDQUFDLENBQUM7WUFDekcsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUM7UUFDeEIsQ0FBQztJQUNILENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsT0FBTztRQUNMLElBQUksSUFBSSxDQUFDLFNBQVM7WUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRSxDQUFDO0lBQzNDLENBQUM7SUFFRDs7T0FFRztJQUNILEtBQUssQ0FBQyxHQUFHLENBQWMsSUFBWSxFQUFFLE9BQXdCO1FBQzNELE9BQU8sSUFBSSxDQUFDLGdCQUFnQixDQUFJLEtBQUssRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBQ25FLENBQUM7SUFFRDs7T0FFRztJQUNILEtBQUssQ0FBQyxJQUFJLENBQ1IsSUFBWSxFQUNaLElBQWMsRUFDZCxPQUF3QjtRQUV4QixPQUFPLElBQUksQ0FBQyxnQkFBZ0IsQ0FBSSxNQUFNLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxPQUFPLENBQUMsQ0FBQztJQUMvRCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxLQUFLLENBQUMsR0FBRyxDQUNQLElBQVksRUFDWixJQUFjLEVBQ2QsT0FBd0I7UUFFeEIsT0FBTyxJQUFJLENBQUMsZ0JBQWdCLENBQUksS0FBSyxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDOUQsQ0FBQztJQUVEOztPQUVHO0lBQ0gsS0FBSyxDQUFDLE1BQU0sQ0FBYyxJQUFZLEVBQUUsT0FBd0I7UUFDOUQsT0FBTyxJQUFJLENBQUMsZ0JBQWdCLENBQUksUUFBUSxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDdEUsQ0FBQztJQUVEOzs7Ozs7OztPQVFHO0lBQ0ssS0FBSyxDQUFDLGdCQUFnQixDQUM1QixNQUFjLEVBQ2QsSUFBWSxFQUNaLElBQWMsRUFDZCxPQUF3QjtRQUV4QiwwRUFBMEU7UUFDMUUsNEVBQTRFO1FBQzVFLDZFQUE2RTtRQUM3RSxzQ0FBc0M7UUFDdEMsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLElBQUksVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO1lBQzNFLE1BQU0sSUFBSSxLQUFLLENBQUMseUJBQXlCLElBQUksRUFBRSxDQUFDLENBQUM7UUFDbkQsQ0FBQztRQUVELE1BQU0sV0FBVyxHQUFnQjtZQUMvQixVQUFVLEVBQUUsT0FBTyxFQUFFLFVBQVUsSUFBSSxtQkFBbUI7WUFDdEQsbUJBQW1CLEVBQUUsT0FBTyxFQUFFLG1CQUFtQixJQUFJLDhCQUE4QjtZQUNuRixZQUFZLEVBQUUsT0FBTyxFQUFFLFlBQVksSUFBSSxzQkFBc0I7U0FDOUQsQ0FBQztRQUNGLE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxXQUFXLENBQUMsVUFBVSxFQUFFLFdBQVcsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO1FBRTNGLDRFQUE0RTtRQUM1RSw0RUFBNEU7UUFDNUUseUVBQXlFO1FBQ3pFLDZFQUE2RTtRQUM3RSw0RUFBNEU7UUFDNUUsOEVBQThFO1FBQzlFLE1BQU0sU0FBUyxHQUNiLGtCQUFrQixDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDNUMsT0FBTyxFQUFFLFVBQVUsS0FBSyxJQUFJO1lBQzVCLENBQUMsQ0FBQyxDQUFDLE9BQU8sRUFBRSxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLGlCQUFpQixDQUFDLElBQUksT0FBTyxDQUFDLE9BQU8sQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUVyRywyRUFBMkU7UUFDM0UsNEVBQTRFO1FBQzVFLGdEQUFnRDtRQUNoRCxNQUFNLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDekQsTUFBTSxPQUFPLEdBQUcsaUJBQWlCLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDMUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLEVBQUUsRUFBRSxDQUFDO1lBQzVCLDBFQUEwRTtZQUMxRSxrRUFBa0U7WUFDbEUsV0FBVyxDQUFDLG9CQUFvQixFQUFFLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsY0FBYyxFQUFFLENBQUMsQ0FBQztZQUMvRSxNQUFNLElBQUksZ0JBQWdCLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDckMsQ0FBQztRQUVELElBQUksU0FBNEIsQ0FBQztRQUVqQyxLQUFLLElBQUksT0FBTyxHQUFHLENBQUMsRUFBRSxPQUFPLElBQUksZ0JBQWdCLEVBQUUsT0FBTyxFQUFFLEVBQUUsQ0FBQztZQUM3RCxJQUFJLENBQUM7Z0JBQ0gsTUFBTSxRQUFRLEdBQUcsTUFBTSxJQUFJLENBQUMsT0FBTyxDQUFJLE1BQU0sRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLE9BQU8sQ0FBQyxDQUFDO2dCQUVwRSxNQUFNLFFBQVEsR0FBRyxnQkFBZ0IsQ0FBQyxRQUFRLENBQUMsVUFBVSxFQUFFLFFBQVEsQ0FBQyxPQUFPLEVBQUUsT0FBTyxFQUFFLFdBQVcsQ0FBQyxDQUFDO2dCQUMvRix3RUFBd0U7Z0JBQ3hFLG9FQUFvRTtnQkFDcEUsSUFBSSxRQUFRLENBQUMsV0FBVyxJQUFJLENBQUMsUUFBUSxDQUFDLFVBQVUsS0FBSyxHQUFHLElBQUksU0FBUyxDQUFDLEVBQUUsQ0FBQztvQkFDdkUsTUFBTSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsTUFBTSxHQUFHLFlBQVksRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLE9BQU8sR0FBRyxDQUFDLEVBQUUsT0FBTyxFQUFFLFFBQVEsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDO29CQUNoSCxXQUFXLENBQUMsMkJBQTJCLEVBQUUsRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQztvQkFDN0QsTUFBTSxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQztvQkFDbkMsU0FBUztnQkFDWCxDQUFDO2dCQUVELHdFQUF3RTtnQkFDeEUsd0VBQXdFO2dCQUN4RSwyRUFBMkU7Z0JBQzNFLE1BQU0sYUFBYSxHQUFHLFFBQVEsQ0FBQyxVQUFVLElBQUksR0FBRyxJQUFJLFFBQVEsQ0FBQyxVQUFVLElBQUksR0FBRyxDQUFDO2dCQUMvRSxJQUFJLGFBQWEsRUFBRSxDQUFDO29CQUNsQixPQUFPLENBQUMsYUFBYSxFQUFFLENBQUM7b0JBQ3hCLFdBQVcsQ0FBQyxvQkFBb0IsRUFBRSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLGNBQWMsRUFBRSxDQUFDLENBQUM7Z0JBQ2pGLENBQUM7cUJBQU0sQ0FBQztvQkFDTixPQUFPLENBQUMsYUFBYSxFQUFFLENBQUM7b0JBQ3hCLFdBQVcsQ0FBQyxvQkFBb0IsRUFBRSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxDQUFDLENBQUM7Z0JBQzVFLENBQUM7Z0JBQ0QsT0FBTyxRQUFRLENBQUM7WUFDbEIsQ0FBQztZQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7Z0JBQ2YsU0FBUyxHQUFHLEtBQUssWUFBWSxLQUFLLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxLQUFLLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7Z0JBRXRFLE1BQU0sUUFBUSxHQUFHLHFCQUFxQixDQUFDLE9BQU8sRUFBRSxXQUFXLENBQUMsQ0FBQztnQkFDN0QsSUFBSSxRQUFRLENBQUMsV0FBVyxJQUFJLFNBQVMsRUFBRSxDQUFDO29CQUN0QyxNQUFNLENBQUMsS0FBSyxDQUFDLHNCQUFzQixFQUFFLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsU0FBUyxDQUFDLE9BQU8sRUFBRSxPQUFPLEVBQUUsT0FBTyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUM7b0JBQ3ZHLFdBQVcsQ0FBQywyQkFBMkIsRUFBRSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDO29CQUM3RCxNQUFNLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDO29CQUNuQyxTQUFTO2dCQUNYLENBQUM7Z0JBQ0Qsc0VBQXNFO2dCQUN0RSxzRUFBc0U7Z0JBQ3RFLE9BQU8sQ0FBQyxhQUFhLEVBQUUsQ0FBQztnQkFDeEIsV0FBVyxDQUFDLG9CQUFvQixFQUFFLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FBQztnQkFDeEUsTUFBTSxTQUFTLENBQUM7WUFDbEIsQ0FBQztRQUNILENBQUM7UUFFRCx3RUFBd0U7UUFDeEUsT0FBTyxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBQ3hCLFdBQVcsQ0FBQyxvQkFBb0IsRUFBRSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxDQUFDLENBQUM7UUFDeEUsTUFBTSxTQUFVLENBQUM7SUFDbkIsQ0FBQztJQUVPLEtBQUssQ0FBQyxFQUFVO1FBQ3RCLE9BQU8sSUFBSSxPQUFPLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDekQsQ0FBQztJQUVEOztPQUVHO0lBQ0ssT0FBTyxDQUNiLE1BQWMsRUFDZCxJQUFZLEVBQ1osSUFBYyxFQUNkLE9BQXdCO1FBRXhCLE9BQU8sSUFBSSxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLEVBQUU7WUFDckMscUZBQXFGO1lBQ3JGLE1BQU0sT0FBTyxHQUFHLElBQUksS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztZQUV0RSxNQUFNLE9BQU8sR0FBNkI7Z0JBQ3hDLGNBQWMsRUFBRSxrQkFBa0I7Z0JBQ2xDLEdBQUcsT0FBTyxFQUFFLE9BQU87YUFDcEIsQ0FBQztZQUVGLCtDQUErQztZQUMvQyxJQUFJLE9BQU8sRUFBRSxTQUFTLEVBQUUsQ0FBQztnQkFDdkIsT0FBTyxDQUFDLGNBQWMsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxTQUFTLENBQUM7WUFDOUMsQ0FBQztZQUVELElBQUksT0FBTyxFQUFFLENBQUM7Z0JBQ1osT0FBTyxDQUFDLGdCQUFnQixDQUFDLEdBQUcsTUFBTSxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUN6RCxDQUFDO1lBRUQsa0VBQWtFO1lBQ2xFLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLFVBQVUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztnQkFDM0UsTUFBTSxJQUFJLEtBQUssQ0FBQyx5QkFBeUIsSUFBSSxFQUFFLENBQUMsQ0FBQztZQUNuRCxDQUFDO1lBRUQsTUFBTSxjQUFjLEdBQXdCO2dCQUMxQyxRQUFRLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJO2dCQUMxQixJQUFJLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJO2dCQUN0QixJQUFJLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLElBQUksRUFBRTtnQkFDOUMsTUFBTTtnQkFDTixPQUFPO2dCQUNQLE9BQU8sRUFBRSxPQUFPLEVBQUUsT0FBTyxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTztnQkFDaEQsS0FBSyxFQUFFLElBQUksQ0FBQyxLQUFLO2FBQ2xCLENBQUM7WUFFRixNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLGNBQWMsRUFBRSxDQUFDLEdBQUcsRUFBRSxFQUFFO2dCQUMvQyxJQUFJLElBQUksR0FBRyxFQUFFLENBQUM7Z0JBRWQsR0FBRyxDQUFDLEVBQUUsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxLQUFLLEVBQUUsRUFBRTtvQkFDdkIsSUFBSSxJQUFJLEtBQUssQ0FBQztnQkFDaEIsQ0FBQyxDQUFDLENBQUM7Z0JBRUgsR0FBRyxDQUFDLEVBQUUsQ0FBQyxLQUFLLEVBQUUsR0FBRyxFQUFFO29CQUNqQixJQUFJLENBQUM7d0JBQ0gsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7d0JBQ2hELE9BQU8sQ0FBQzs0QkFDTixVQUFVLEVBQUUsR0FBRyxDQUFDLFVBQVUsSUFBSSxVQUFVLENBQUMscUJBQXFCOzRCQUM5RCxJQUFJLEVBQUUsVUFBZTs0QkFDckIsT0FBTyxFQUFFLEdBQUcsQ0FBQyxPQUFPO3lCQUNyQixDQUFDLENBQUM7b0JBQ0wsQ0FBQztvQkFBQyxPQUFPLFVBQVUsRUFBRSxDQUFDO3dCQUNwQixNQUFNLENBQUMsSUFBSSxDQUFDLCtCQUErQixFQUFFOzRCQUMzQyxJQUFJLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJOzRCQUN0QixJQUFJOzRCQUNKLEtBQUssRUFBRSxVQUFVLFlBQVksS0FBSyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDO3lCQUM3RSxDQUFDLENBQUM7d0JBQ0gsT0FBTyxDQUFDOzRCQUNOLFVBQVUsRUFBRSxHQUFHLENBQUMsVUFBVSxJQUFJLFVBQVUsQ0FBQyxxQkFBcUI7NEJBQzlELElBQUksRUFBRSxFQUFPOzRCQUNiLE9BQU8sRUFBRSxHQUFHLENBQUMsT0FBTzt5QkFDckIsQ0FBQyxDQUFDO29CQUNMLENBQUM7Z0JBQ0gsQ0FBQyxDQUFDLENBQUM7WUFDTCxDQUFDLENBQUMsQ0FBQztZQUVILEdBQUcsQ0FBQyxFQUFFLENBQUMsT0FBTyxFQUFFLENBQUMsS0FBSyxFQUFFLEVBQUU7Z0JBQ3hCLHVFQUF1RTtnQkFDdkUscUVBQXFFO2dCQUNyRSw0Q0FBNEM7Z0JBQzVDLE1BQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxPQUFPLElBQUssS0FBK0IsQ0FBQyxJQUFJLElBQUksS0FBSyxDQUFDLElBQUksQ0FBQztnQkFDcEYsTUFBTSxDQUFDLEtBQUssQ0FBQyxxQkFBcUIsRUFBRTtvQkFDbEMsSUFBSSxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSTtvQkFDdEIsSUFBSSxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSTtvQkFDdEIsSUFBSTtvQkFDSixNQUFNO29CQUNOLEtBQUssRUFBRSxNQUFNO2lCQUNkLENBQUMsQ0FBQztnQkFDSCxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDaEIsQ0FBQyxDQUFDLENBQUM7WUFFSCxHQUFHLENBQUMsRUFBRSxDQUFDLFNBQVMsRUFBRSxHQUFHLEVBQUU7Z0JBQ3JCLEdBQUcsQ0FBQyxPQUFPLEVBQUUsQ0FBQztnQkFDZCxNQUFNLEtBQUssR0FBRyxJQUFJLEtBQUssQ0FBQyx5QkFBeUIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLElBQUksQ0FBQyxDQUFDO2dCQUMxRSxNQUFNLENBQUMsSUFBSSxDQUFDLHNCQUFzQixFQUFFO29CQUNsQyxJQUFJLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJO29CQUN0QixJQUFJO29CQUNKLE9BQU8sRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU87aUJBQzdCLENBQUMsQ0FBQztnQkFDSCxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDaEIsQ0FBQyxDQUFDLENBQUM7WUFFSCxJQUFJLE9BQU8sRUFBRSxDQUFDO2dCQUNaLEdBQUcsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDckIsQ0FBQztZQUVELEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUNaLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztDQUNGO0FBRUQ7Ozs7OztHQU1HO0FBQ0gsTUFBTSxVQUFVLGdCQUFnQixDQUFDLE1BQXFCLEVBQUUsT0FBMkI7SUFDakYsTUFBTSxNQUFNLEdBQUcsSUFBSSxrQkFBa0IsQ0FBQyxNQUFNLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFFdkQsT0FBTztRQUNMLGlGQUFpRjtRQUNqRixPQUFPO1lBQ0wsTUFBTSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ25CLENBQUM7UUFFRDs7V0FFRztRQUNILEtBQUssQ0FBQyxHQUFHLENBQUksSUFBWSxFQUFFLE9BQXdCO1lBQ2pELElBQUksQ0FBQztnQkFDSCxPQUFPLE1BQU0sTUFBTSxDQUFDLEdBQUcsQ0FBSSxJQUFJLEVBQUUsT0FBTyxDQUFDLENBQUM7WUFDNUMsQ0FBQztZQUFDLE9BQU8sR0FBRyxFQUFFLENBQUM7Z0JBQ2IsTUFBTSxDQUFDLEtBQUssQ0FBQyxpQ0FBaUMsRUFBRSxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsR0FBRyxZQUFZLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztnQkFDbkgsT0FBTyxJQUFJLENBQUM7WUFDZCxDQUFDO1FBQ0gsQ0FBQztRQUVEOztXQUVHO1FBQ0gsS0FBSyxDQUFDLElBQUksQ0FDUixJQUFZLEVBQ1osSUFBYyxFQUNkLE9BQXdCO1lBRXhCLElBQUksQ0FBQztnQkFDSCxPQUFPLE1BQU0sTUFBTSxDQUFDLElBQUksQ0FBSSxJQUFJLEVBQUUsSUFBSSxFQUFFLE9BQU8sQ0FBQyxDQUFDO1lBQ25ELENBQUM7WUFBQyxPQUFPLEdBQUcsRUFBRSxDQUFDO2dCQUNiLE1BQU0sQ0FBQyxLQUFLLENBQUMsa0NBQWtDLEVBQUUsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLEdBQUcsWUFBWSxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUM7Z0JBQ3BILE9BQU8sSUFBSSxDQUFDO1lBQ2QsQ0FBQztRQUNILENBQUM7UUFFRDs7V0FFRztRQUNILEtBQUssQ0FBQyxHQUFHLENBQ1AsSUFBWSxFQUNaLElBQWMsRUFDZCxPQUF3QjtZQUV4QixJQUFJLENBQUM7Z0JBQ0gsT0FBTyxNQUFNLE1BQU0sQ0FBQyxHQUFHLENBQUksSUFBSSxFQUFFLElBQUksRUFBRSxPQUFPLENBQUMsQ0FBQztZQUNsRCxDQUFDO1lBQUMsT0FBTyxHQUFHLEVBQUUsQ0FBQztnQkFDYixNQUFNLENBQUMsS0FBSyxDQUFDLGlDQUFpQyxFQUFFLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxHQUFHLFlBQVksS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDO2dCQUNuSCxPQUFPLElBQUksQ0FBQztZQUNkLENBQUM7UUFDSCxDQUFDO1FBRUQ7OztXQUdHO1FBQ0gsS0FBSyxDQUFDLE1BQU0sQ0FDVixJQUFZLEVBQ1osT0FBd0I7WUFFeEIsSUFBSSxDQUFDO2dCQUNILE9BQU8sTUFBTSxNQUFNLENBQUMsTUFBTSxDQUFJLElBQUksRUFBRSxPQUFPLENBQUMsQ0FBQztZQUMvQyxDQUFDO1lBQUMsT0FBTyxHQUFHLEVBQUUsQ0FBQztnQkFDYixNQUFNLENBQUMsS0FBSyxDQUFDLG9DQUFvQyxFQUFFLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxHQUFHLFlBQVksS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDO2dCQUN0SCxPQUFPLElBQUksQ0FBQztZQUNkLENBQUM7UUFDSCxDQUFDO0tBQ0YsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuaW1wb3J0ICogYXMgaHR0cCBmcm9tICdodHRwJztcbmltcG9ydCB7IGdldENpcmN1aXRCcmVha2VyLCBDaXJjdWl0T3BlbkVycm9yIH0gZnJvbSAnLi9jaXJjdWl0LWJyZWFrZXIuanMnO1xuaW1wb3J0IHtcbiAgREVGQVVMVF9NQVhfUkVUUklFUyxcbiAgREVGQVVMVF9SRVRSWV9ERUxBWV9NUyxcbiAgREVGQVVMVF9NQVhfUkFURV9MSU1JVF9SRVRSSUVTLFxuICBnZXRSZXRyeURlY2lzaW9uLFxuICBnZXRFcnJvclJldHJ5RGVjaXNpb24sXG4gIHR5cGUgUmV0cnlDb25maWcsXG59IGZyb20gJy4vcmV0cnktc3RyYXRlZ3kuanMnO1xuaW1wb3J0IHsgSHR0cFN0YXR1cyB9IGZyb20gJy4uL2NvbnN0YW50cy9odHRwLXN0YXR1cy5qcyc7XG5pbXBvcnQgdHlwZSB7IFNlcnZpY2VDb25maWcgfSBmcm9tICcuLi90eXBlcy9jb21tb24uanMnO1xuaW1wb3J0IHsgY3JlYXRlTG9nZ2VyIH0gZnJvbSAnLi4vdXRpbHMvbG9nZ2VyLmpzJztcbmltcG9ydCB7IGVtaXRDb3VudGVyIH0gZnJvbSAnLi4vdXRpbHMvbWV0cmljLWVtaXR0ZXIuanMnO1xuXG5jb25zdCBsb2dnZXIgPSBjcmVhdGVMb2dnZXIoJ2h0dHAtY2xpZW50Jyk7XG5cbi8qKlxuICogRGVmYXVsdCByZXF1ZXN0IHRpbWVvdXQgaW4gbWlsbGlzZWNvbmRzIChlbnY6IGBIVFRQX0NMSUVOVF9USU1FT1VUYCkuXG4gKi9cbmNvbnN0IERFRkFVTFRfVElNRU9VVCA9IHBhcnNlSW50KHByb2Nlc3MuZW52LkhUVFBfQ0xJRU5UX1RJTUVPVVQgfHwgJzUwMDAnLCAxMCk7XG5cbi8qKlxuICogRGVmYXVsdCBjYXAgb24gY29uY3VycmVudCBrZWVwLWFsaXZlIHNvY2tldHMgcGVyIGNsaWVudCBhZ2VudFxuICogKGVudjogYEhUVFBfQ0xJRU5UX01BWF9TT0NLRVRTYCkuIE5vZGUncyBkZWZhdWx0IGlzIGBJbmZpbml0eWAsIHdoaWNoIGxldHMgYVxuICogYnVyc3Qgb2YgY29uY3VycmVudCBjYWxscyBvcGVuIHVuYm91bmRlZCBzb2NrZXRzIGFnYWluc3QgYSBkb3duc3RyZWFtIHNlcnZpY2VcbiAqIChmZCBleGhhdXN0aW9uICsgY29ubmVjdGlvbi1zdG9ybSBvbiB0aGUgY2FsbGVlKS4gNjQgaXMgYW1wbGUgZm9yXG4gKiBzZXJ2aWNlLXRvLXNlcnZpY2UgZmFuLW91dCB3aGlsZSBzdGF5aW5nIGJvdW5kZWQuXG4gKi9cbmNvbnN0IERFRkFVTFRfTUFYX1NPQ0tFVFMgPSBwYXJzZUludChwcm9jZXNzLmVudi5IVFRQX0NMSUVOVF9NQVhfU09DS0VUUyB8fCAnNjQnLCAxMCk7XG5cbi8vIEhUVFAgbWV0aG9kcyB0aGF0IGFyZSBpZGVtcG90ZW50IGJ5IGRlZmluaXRpb24g4oCUIHNhZmUgdG8gYXV0by1yZXRyeSBvbiBhXG4vLyA1eHgvY29ubmVjdGlvbi90aW1lb3V0IHdpdGhvdXQgcmlza2luZyBhIGR1cGxpY2F0ZSBzaWRlIGVmZmVjdC5cbmNvbnN0IElERU1QT1RFTlRfTUVUSE9EUyA9IG5ldyBTZXQoWydHRVQnLCAnSEVBRCcsICdPUFRJT05TJ10pO1xuXG4vKipcbiAqIEhUVFAgcmVxdWVzdCBvcHRpb25zLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFJlcXVlc3RPcHRpb25zIHtcbiAgLyoqIFJlcXVlc3QgaGVhZGVycyAqL1xuICBoZWFkZXJzPzogUmVjb3JkPHN0cmluZywgc3RyaW5nPjtcbiAgLyoqIFJlcXVlc3QgdGltZW91dCBpbiBtaWxsaXNlY29uZHMgKi9cbiAgdGltZW91dD86IG51bWJlcjtcbiAgLyoqIE1heGltdW0gcmV0cnkgYXR0ZW1wdHMgZm9yIHRyYW5zaWVudCBmYWlsdXJlcyAoZGVmYXVsdDogMikgKi9cbiAgbWF4UmV0cmllcz86IG51bWJlcjtcbiAgLyoqIEJhc2UgZGVsYXkgYmV0d2VlbiByZXRyaWVzIGluIG1zIOKAlCBkb3VibGVzIGVhY2ggYXR0ZW1wdCAoZGVmYXVsdDogMjAwKSAqL1xuICByZXRyeURlbGF5TXM/OiBudW1iZXI7XG4gIC8qKiBNYXhpbXVtIHJldHJ5IGF0dGVtcHRzIHNwZWNpZmljYWxseSBmb3IgNDI5IHJhdGUgbGltaXRpbmcgKGRlZmF1bHQ6IDQpICovXG4gIG1heFJhdGVMaW1pdFJldHJpZXM/OiBudW1iZXI7XG4gIC8qKiBPcHRpb25hbCByZXF1ZXN0IElEIGZvciBkaXN0cmlidXRlZCB0cmFjaW5nIChhZGRlZCBhcyBYLVJlcXVlc3QtSWQgaGVhZGVyKSAqL1xuICByZXF1ZXN0SWQ/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBUcmVhdCB0aGlzIHJlcXVlc3QgYXMgc2FmZSB0byBhdXRvLXJldHJ5IG9uIDV4eC9jb25uZWN0aW9uL3RpbWVvdXQgZXZlblxuICAgKiB0aG91Z2ggdGhlIG1ldGhvZCBpcyBub24taWRlbXBvdGVudCAoZS5nLiB0aGUgZW5kcG9pbnQgaXMgaWRlbXBvdGVudCBieSBhblxuICAgKiBJZGVtcG90ZW5jeS1LZXksIG9yIHRoZSBvcGVyYXRpb24gaXMgbmF0dXJhbGx5IGlkZW1wb3RlbnQpLiBEZWZhdWx0IGZhbHNlOlxuICAgKiBub24taWRlbXBvdGVudCBtZXRob2RzIGFyZSBOT1QgcmV0cmllZCBvbiB0aG9zZSBmYWlsdXJlcywgb25seSBvbiA0MjkuXG4gICAqL1xuICBpZGVtcG90ZW50PzogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBIVFRQIGNsaWVudCByZXNwb25zZSB3cmFwcGVyLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEh0dHBDbGllbnRSZXNwb25zZTxUID0gdW5rbm93bj4ge1xuICAvKiogSFRUUCBzdGF0dXMgY29kZSAqL1xuICBzdGF0dXNDb2RlOiBudW1iZXI7XG4gIC8qKiBSZXNwb25zZSBib2R5IChwYXJzZWQgSlNPTikgKi9cbiAgYm9keTogVDtcbiAgLyoqIFJlc3BvbnNlIGhlYWRlcnMgKi9cbiAgaGVhZGVyczogaHR0cC5JbmNvbWluZ0h0dHBIZWFkZXJzO1xufVxuXG4vKipcbiAqIEludGVybmFsIEhUVFAgY2xpZW50IGZvciBzZXJ2aWNlLXRvLXNlcnZpY2UgY29tbXVuaWNhdGlvbi5cbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgY2xpZW50ID0gbmV3IEludGVybmFsSHR0cENsaWVudCh7XG4gKiAgIGhvc3Q6ICdxdW90YScsXG4gKiAgIHBvcnQ6IDMwMDAsXG4gKiAgIHRpbWVvdXQ6IDUwMDAsXG4gKiB9KTtcbiAqXG4gKiBjb25zdCByZXNwb25zZSA9IGF3YWl0IGNsaWVudC5nZXQoJy9vcmcxMjMvYXBpQ2FsbHMnKTtcbiAqIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGNsaWVudC5wb3N0KCcvb3JnMTIzL2luY3JlbWVudCcsIHsgcXVvdGFUeXBlOiAnYXBpQ2FsbHMnIH0pO1xuICogYGBgXG4gKi9cbi8qKlxuICogT3B0aW9ucyBjb250cm9sbGluZyB0aGUgY2xpZW50J3MgY29ubmVjdGlvbiBwb29sLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEh0dHBDbGllbnRPcHRpb25zIHtcbiAgLyoqXG4gICAqIEEgc2hhcmVkIGBodHRwLkFnZW50YCB0byByZXVzZSBhY3Jvc3MgY2xpZW50cyAocG9vbHMgc29ja2V0cyB0byB0aGUgc2FtZVxuICAgKiBob3N0KS4gV2hlbiBzdXBwbGllZCwgdGhlIGNsaWVudCBkb2VzIE5PVCBvd24gaXQg4oCUIHtAbGluayBJbnRlcm5hbEh0dHBDbGllbnQuZGVzdHJveX1cbiAgICogbGVhdmVzIGEgYm9ycm93ZWQgYWdlbnQgdW50b3VjaGVkIHNvIG90aGVyIGNsaWVudHMga2VlcCB3b3JraW5nLlxuICAgKi9cbiAgYWdlbnQ/OiBodHRwLkFnZW50O1xuICAvKiogQ2FwIG9uIGNvbmN1cnJlbnQga2VlcC1hbGl2ZSBzb2NrZXRzIHdoZW4gbWludGluZyBhbiBhZ2VudCAoZGVmYXVsdCA2NCkuICovXG4gIG1heFNvY2tldHM/OiBudW1iZXI7XG59XG5cbmV4cG9ydCBjbGFzcyBJbnRlcm5hbEh0dHBDbGllbnQge1xuICBwcml2YXRlIGNvbmZpZzogUmVxdWlyZWQ8U2VydmljZUNvbmZpZz47XG4gIHByaXZhdGUgYWdlbnQ6IGh0dHAuQWdlbnQ7XG4gIC8qKiBUcnVlIG9ubHkgd2hlbiB0aGlzIGNsaWVudCBNSU5URUQgaXRzIGFnZW50IChzbyBkZXN0cm95KCkgbWF5IHRlYXIgaXQgZG93bikuICovXG4gIHByaXZhdGUgcmVhZG9ubHkgb3duc0FnZW50OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBuZXcgSFRUUCBjbGllbnQgaW5zdGFuY2UuXG4gICAqXG4gICAqIEBwYXJhbSBjb25maWcgLSBTZXJ2aWNlIGNvbmZpZ3VyYXRpb25cbiAgICogQHBhcmFtIG9wdGlvbnMgLSBPcHRpb25hbCBjb25uZWN0aW9uLXBvb2wgY29udHJvbHMgKHNoYXJlZCBhZ2VudCAvIHNvY2tldCBjYXApXG4gICAqL1xuICBjb25zdHJ1Y3Rvcihjb25maWc6IFNlcnZpY2VDb25maWcsIG9wdGlvbnM/OiBIdHRwQ2xpZW50T3B0aW9ucykge1xuICAgIHRoaXMuY29uZmlnID0ge1xuICAgICAgaG9zdDogY29uZmlnLmhvc3QsXG4gICAgICBwb3J0OiBjb25maWcucG9ydCxcbiAgICAgIHRpbWVvdXQ6IGNvbmZpZy50aW1lb3V0ID8/IERFRkFVTFRfVElNRU9VVCxcbiAgICB9O1xuICAgIGlmIChvcHRpb25zPy5hZ2VudCkge1xuICAgICAgLy8gQm9ycm93ZWQsIGNhbGxlci1vd25lZCBhZ2VudCDigJQgcG9vbGVkIGFjcm9zcyBjbGllbnRzLCBub3Qgb3VycyB0byBkZXN0cm95LlxuICAgICAgdGhpcy5hZ2VudCA9IG9wdGlvbnMuYWdlbnQ7XG4gICAgICB0aGlzLm93bnNBZ2VudCA9IGZhbHNlO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBPd24gYSBrZWVwLWFsaXZlIGFnZW50IHdpdGggYSBCT1VOREVEIHNvY2tldCBwb29sIChubyBtb3JlIEluZmluaXR5KS5cbiAgICAgIHRoaXMuYWdlbnQgPSBuZXcgaHR0cC5BZ2VudCh7IGtlZXBBbGl2ZTogdHJ1ZSwgbWF4U29ja2V0czogb3B0aW9ucz8ubWF4U29ja2V0cyA/PyBERUZBVUxUX01BWF9TT0NLRVRTIH0pO1xuICAgICAgdGhpcy5vd25zQWdlbnQgPSB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZWxlYXNlIHRoZSBrZWVwLWFsaXZlIHNvY2tldCBwb29sLiBJZGVtcG90ZW50IGFuZCBzYWZlIHRvIGNhbGwgb24gc2h1dGRvd24uXG4gICAqIEEgYm9ycm93ZWQgKGNhbGxlci1zdXBwbGllZCkgYWdlbnQgaXMgbGVmdCBpbnRhY3Qg4oCUIG9ubHkgYW4gYWdlbnQgdGhpcyBjbGllbnRcbiAgICogY3JlYXRlZCBpcyBkZXN0cm95ZWQsIHNvIHRlYXJpbmcgZG93biBvbmUgY2xpZW50IGNhbid0IHNldmVyIGFub3RoZXIncyBwb29sLlxuICAgKi9cbiAgZGVzdHJveSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5vd25zQWdlbnQpIHRoaXMuYWdlbnQuZGVzdHJveSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIE1ha2UgYSBHRVQgcmVxdWVzdC5cbiAgICovXG4gIGFzeW5jIGdldDxUID0gdW5rbm93bj4ocGF0aDogc3RyaW5nLCBvcHRpb25zPzogUmVxdWVzdE9wdGlvbnMpOiBQcm9taXNlPEh0dHBDbGllbnRSZXNwb25zZTxUPj4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3RXaXRoUmV0cnk8VD4oJ0dFVCcsIHBhdGgsIHVuZGVmaW5lZCwgb3B0aW9ucyk7XG4gIH1cblxuICAvKipcbiAgICogTWFrZSBhIFBPU1QgcmVxdWVzdC5cbiAgICovXG4gIGFzeW5jIHBvc3Q8VCA9IHVua25vd24+KFxuICAgIHBhdGg6IHN0cmluZyxcbiAgICBib2R5PzogdW5rbm93bixcbiAgICBvcHRpb25zPzogUmVxdWVzdE9wdGlvbnMsXG4gICk6IFByb21pc2U8SHR0cENsaWVudFJlc3BvbnNlPFQ+PiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdFdpdGhSZXRyeTxUPignUE9TVCcsIHBhdGgsIGJvZHksIG9wdGlvbnMpO1xuICB9XG5cbiAgLyoqXG4gICAqIE1ha2UgYSBQVVQgcmVxdWVzdC5cbiAgICovXG4gIGFzeW5jIHB1dDxUID0gdW5rbm93bj4oXG4gICAgcGF0aDogc3RyaW5nLFxuICAgIGJvZHk/OiB1bmtub3duLFxuICAgIG9wdGlvbnM/OiBSZXF1ZXN0T3B0aW9ucyxcbiAgKTogUHJvbWlzZTxIdHRwQ2xpZW50UmVzcG9uc2U8VD4+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0V2l0aFJldHJ5PFQ+KCdQVVQnLCBwYXRoLCBib2R5LCBvcHRpb25zKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNYWtlIGEgREVMRVRFIHJlcXVlc3QuXG4gICAqL1xuICBhc3luYyBkZWxldGU8VCA9IHVua25vd24+KHBhdGg6IHN0cmluZywgb3B0aW9ucz86IFJlcXVlc3RPcHRpb25zKTogUHJvbWlzZTxIdHRwQ2xpZW50UmVzcG9uc2U8VD4+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0V2l0aFJldHJ5PFQ+KCdERUxFVEUnLCBwYXRoLCB1bmRlZmluZWQsIG9wdGlvbnMpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlcXVlc3Qgd2l0aCByZXRyeSBsb2dpYyBmb3IgdHJhbnNpZW50IGZhaWx1cmVzLlxuICAgKlxuICAgKiAtIDQyOSAocmF0ZSBsaW1pdCk6IHJlc3BlY3RzIGBSZXRyeS1BZnRlcmAgaGVhZGVyLCB1c2VzIGxvbmdlciBiYXNlIGRlbGF5ICg0eCksXG4gICAqICAgcmV0cmllcyB1cCB0byBgbWF4UmF0ZUxpbWl0UmV0cmllc2AgdGltZXMgKGRlZmF1bHQgNCkuXG4gICAqIC0gNTAyLzUwMy81MDQgKHNlcnZlciBlcnJvcnMpOiBzdGFuZGFyZCBleHBvbmVudGlhbCBiYWNrb2ZmLCB1cCB0byBgbWF4UmV0cmllc2AgKGRlZmF1bHQgMikuXG4gICAqIC0gQ29ubmVjdGlvbiBlcnJvcnMgLyB0aW1lb3V0czogcmV0cmllcyB1cCB0byBgbWF4UmV0cmllc2AuXG4gICAqIC0gQWxsIGRlbGF5cyBpbmNsdWRlIMKxMjUlIGppdHRlciB0byBwcmV2ZW50IHRodW5kZXJpbmcgaGVyZC5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgcmVxdWVzdFdpdGhSZXRyeTxUPihcbiAgICBtZXRob2Q6IHN0cmluZyxcbiAgICBwYXRoOiBzdHJpbmcsXG4gICAgYm9keT86IHVua25vd24sXG4gICAgb3B0aW9ucz86IFJlcXVlc3RPcHRpb25zLFxuICApOiBQcm9taXNlPEh0dHBDbGllbnRSZXNwb25zZTxUPj4ge1xuICAgIC8vIEEgbWFsZm9ybWVkIHBhdGggaXMgYSBDTElFTlQgYnVnLCBub3QgYSBkb3duc3RyZWFtIGZhdWx0IOKAlCByZWplY3QgaXQgdXBcbiAgICAvLyBmcm9udCBzbyBpdCBuZXZlciBidXJucyByZXRyaWVzIG9yIGZlZWRzIHRoZSBjaXJjdWl0IGJyZWFrZXIgKHdoaWNoIHdvdWxkXG4gICAgLy8gb3RoZXJ3aXNlIHNoZWQgdHJhZmZpYyB0byBhIHBlcmZlY3RseSBoZWFsdGh5IGRvd25zdHJlYW0pLiByZXF1ZXN0KCkga2VlcHNcbiAgICAvLyB0aGUgc2FtZSBndWFyZCBhcyBkZWZlbmNlLWluLWRlcHRoLlxuICAgIGlmIChwYXRoLmluY2x1ZGVzKCc6Ly8nKSB8fCBwYXRoLnN0YXJ0c1dpdGgoJy8vJykgfHwgL1tcXHJcXG5cXDBdLy50ZXN0KHBhdGgpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgcmVxdWVzdCBwYXRoOiAke3BhdGh9YCk7XG4gICAgfVxuXG4gICAgY29uc3QgcmV0cnlDb25maWc6IFJldHJ5Q29uZmlnID0ge1xuICAgICAgbWF4UmV0cmllczogb3B0aW9ucz8ubWF4UmV0cmllcyA/PyBERUZBVUxUX01BWF9SRVRSSUVTLFxuICAgICAgbWF4UmF0ZUxpbWl0UmV0cmllczogb3B0aW9ucz8ubWF4UmF0ZUxpbWl0UmV0cmllcyA/PyBERUZBVUxUX01BWF9SQVRFX0xJTUlUX1JFVFJJRVMsXG4gICAgICByZXRyeURlbGF5TXM6IG9wdGlvbnM/LnJldHJ5RGVsYXlNcyA/PyBERUZBVUxUX1JFVFJZX0RFTEFZX01TLFxuICAgIH07XG4gICAgY29uc3QgdG90YWxNYXhBdHRlbXB0cyA9IE1hdGgubWF4KHJldHJ5Q29uZmlnLm1heFJldHJpZXMsIHJldHJ5Q29uZmlnLm1heFJhdGVMaW1pdFJldHJpZXMpO1xuXG4gICAgLy8gV2hldGhlciBpdCdzIHNhZmUgdG8gYXV0by1yZXRyeSB0aGlzIHJlcXVlc3Qgb24gYSA1eHgvY29ubmVjdGlvbi90aW1lb3V0LlxuICAgIC8vIEEgdGltZWQtb3V0IFBPU1QgbWF5IGhhdmUgYWxyZWFkeSBiZWVuIHByb2Nlc3NlZCBzZXJ2ZXItc2lkZSwgc28gcmV0cnlpbmdcbiAgICAvLyBhIG5vbi1pZGVtcG90ZW50IHJlcXVlc3Qgcmlza3MgYSBEVVBMSUNBVEUgc2lkZSBlZmZlY3QgKGRvdWJsZS1jaGFyZ2UsXG4gICAgLy8gZG91YmxlLWNyZWF0ZSkuIE9ubHkgR0VUL0hFQUQvT1BUSU9OUywgYW4gZXhwbGljaXQgYGlkZW1wb3RlbnRgIG9wdC1pbiwgb3JcbiAgICAvLyBhIHJlcXVlc3QgY2FycnlpbmcgYW4gSWRlbXBvdGVuY3ktS2V5IGFyZSBhdXRvLXJldHJpZWQgb24gdGhvc2UgZmFpbHVyZXMuXG4gICAgLy8gKDQyOSBpcyBhbHdheXMgcmV0cmllZCDigJQgc2VlIGJlbG93IOKAlCBzaW5jZSBpdCB3YXMgcmVqZWN0ZWQsIG5vdCBwcm9jZXNzZWQuKVxuICAgIGNvbnN0IHJldHJ5U2FmZSA9XG4gICAgICBJREVNUE9URU5UX01FVEhPRFMuaGFzKG1ldGhvZC50b1VwcGVyQ2FzZSgpKSB8fFxuICAgICAgb3B0aW9ucz8uaWRlbXBvdGVudCA9PT0gdHJ1ZSB8fFxuICAgICAgISEob3B0aW9ucz8uaGVhZGVycyAmJiAob3B0aW9ucy5oZWFkZXJzWydJZGVtcG90ZW5jeS1LZXknXSB8fCBvcHRpb25zLmhlYWRlcnNbJ2lkZW1wb3RlbmN5LWtleSddKSk7XG5cbiAgICAvLyBQZXItdGFyZ2V0IGNpcmN1aXQgYnJlYWtlciArIFMyUyByZXF1ZXN0IG1ldHJpY3MuIGB0YXJnZXRgIGlzIHRoZSBzaGFyZWRcbiAgICAvLyBicmVha2VyL21ldHJpYyBrZXkgc28gb25lIGJhZCBkb3duc3RyZWFtIHRyaXBzIG9uY2UgKG5vdCBvbmNlLXBlci1jbGllbnQpXG4gICAgLy8gYW5kIGRhc2hib2FyZHMgY2FuIHNlZSBTMlMgaGVhbHRoIHBlciBjYWxsZWUuXG4gICAgY29uc3QgdGFyZ2V0ID0gYCR7dGhpcy5jb25maWcuaG9zdH06JHt0aGlzLmNvbmZpZy5wb3J0fWA7XG4gICAgY29uc3QgYnJlYWtlciA9IGdldENpcmN1aXRCcmVha2VyKHRhcmdldCk7XG4gICAgaWYgKCFicmVha2VyLmFsbG93UmVxdWVzdCgpKSB7XG4gICAgICAvLyBGYXN0LWZhaWwgd2l0aG91dCB0b3VjaGluZyB0aGUgbmV0d29yayDigJQgdGhpcyBpcyB0aGUgbG9hZC1zaGVkZGluZyB0aGF0XG4gICAgICAvLyBwcmV2ZW50cyBhIGRvd25zdHJlYW0gYnJvd25vdXQgZnJvbSBjYXNjYWRpbmcgdmlhIHJldHJ5IHN0b3Jtcy5cbiAgICAgIGVtaXRDb3VudGVyKCdzMnNfcmVxdWVzdHNfdG90YWwnLCB7IHRhcmdldCwgbWV0aG9kLCBvdXRjb21lOiAnY2lyY3VpdF9vcGVuJyB9KTtcbiAgICAgIHRocm93IG5ldyBDaXJjdWl0T3BlbkVycm9yKHRhcmdldCk7XG4gICAgfVxuXG4gICAgbGV0IGxhc3RFcnJvcjogRXJyb3IgfCB1bmRlZmluZWQ7XG5cbiAgICBmb3IgKGxldCBhdHRlbXB0ID0gMDsgYXR0ZW1wdCA8PSB0b3RhbE1heEF0dGVtcHRzOyBhdHRlbXB0KyspIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy5yZXF1ZXN0PFQ+KG1ldGhvZCwgcGF0aCwgYm9keSwgb3B0aW9ucyk7XG5cbiAgICAgICAgY29uc3QgZGVjaXNpb24gPSBnZXRSZXRyeURlY2lzaW9uKHJlc3BvbnNlLnN0YXR1c0NvZGUsIHJlc3BvbnNlLmhlYWRlcnMsIGF0dGVtcHQsIHJldHJ5Q29uZmlnKTtcbiAgICAgICAgLy8gNDI5IGlzIHNhZmUgdG8gcmV0cnkgZm9yIEFOWSBtZXRob2QgKHJhdGUtbGltaXRlZCDihpIgbm90IHByb2Nlc3NlZCk7IGFcbiAgICAgICAgLy8gNXh4L2dhdGV3YXkgZXJyb3IgaXMgb25seSByZXRyaWVkIHdoZW4gdGhlIHJlcXVlc3QgaXMgcmV0cnktc2FmZS5cbiAgICAgICAgaWYgKGRlY2lzaW9uLnNob3VsZFJldHJ5ICYmIChyZXNwb25zZS5zdGF0dXNDb2RlID09PSA0MjkgfHwgcmV0cnlTYWZlKSkge1xuICAgICAgICAgIGxvZ2dlci5kZWJ1ZyhkZWNpc2lvbi5yZWFzb24gKyAnLCByZXRyeWluZycsIHsgbWV0aG9kLCBwYXRoLCBhdHRlbXB0OiBhdHRlbXB0ICsgMSwgZGVsYXlNczogZGVjaXNpb24uZGVsYXlNcyB9KTtcbiAgICAgICAgICBlbWl0Q291bnRlcignczJzX3JlcXVlc3RfcmV0cmllc190b3RhbCcsIHsgdGFyZ2V0LCBtZXRob2QgfSk7XG4gICAgICAgICAgYXdhaXQgdGhpcy5zbGVlcChkZWNpc2lvbi5kZWxheU1zKTtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFRlcm1pbmFsIHJlc3BvbnNlLiBBIDV4eCBpcyBhIGRvd25zdHJlYW0gZmF1bHQgKGZlZWRzIHRoZSBicmVha2VyKTsgYVxuICAgICAgICAvLyA0MjkgaXMgYmFja3ByZXNzdXJlLCBub3QgYSBmYXVsdCDigJQgdGhlIHNlcnZpY2UgYW5zd2VyZWQsIHNvIGl0IGNvdW50c1xuICAgICAgICAvLyBhcyBzdWNjZXNzIGZvciBicmVha2VyIHB1cnBvc2VzIChuZXZlciB0cmlwIHRoZSBicmVha2VyIG9uIHJhdGUgbGltaXRzKS5cbiAgICAgICAgY29uc3QgaXNTZXJ2ZXJGYXVsdCA9IHJlc3BvbnNlLnN0YXR1c0NvZGUgPj0gNTAwICYmIHJlc3BvbnNlLnN0YXR1c0NvZGUgPD0gNTk5O1xuICAgICAgICBpZiAoaXNTZXJ2ZXJGYXVsdCkge1xuICAgICAgICAgIGJyZWFrZXIucmVjb3JkRmFpbHVyZSgpO1xuICAgICAgICAgIGVtaXRDb3VudGVyKCdzMnNfcmVxdWVzdHNfdG90YWwnLCB7IHRhcmdldCwgbWV0aG9kLCBvdXRjb21lOiAnc2VydmVyX2Vycm9yJyB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBicmVha2VyLnJlY29yZFN1Y2Nlc3MoKTtcbiAgICAgICAgICBlbWl0Q291bnRlcignczJzX3JlcXVlc3RzX3RvdGFsJywgeyB0YXJnZXQsIG1ldGhvZCwgb3V0Y29tZTogJ3N1Y2Nlc3MnIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXNwb25zZTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGxhc3RFcnJvciA9IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvciA6IG5ldyBFcnJvcihTdHJpbmcoZXJyb3IpKTtcblxuICAgICAgICBjb25zdCBkZWNpc2lvbiA9IGdldEVycm9yUmV0cnlEZWNpc2lvbihhdHRlbXB0LCByZXRyeUNvbmZpZyk7XG4gICAgICAgIGlmIChkZWNpc2lvbi5zaG91bGRSZXRyeSAmJiByZXRyeVNhZmUpIHtcbiAgICAgICAgICBsb2dnZXIuZGVidWcoJ1JldHJ5aW5nIGFmdGVyIGVycm9yJywgeyBtZXRob2QsIHBhdGgsIGVycm9yOiBsYXN0RXJyb3IubWVzc2FnZSwgYXR0ZW1wdDogYXR0ZW1wdCArIDEgfSk7XG4gICAgICAgICAgZW1pdENvdW50ZXIoJ3Myc19yZXF1ZXN0X3JldHJpZXNfdG90YWwnLCB7IHRhcmdldCwgbWV0aG9kIH0pO1xuICAgICAgICAgIGF3YWl0IHRoaXMuc2xlZXAoZGVjaXNpb24uZGVsYXlNcyk7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgLy8gTm90IHJldHJ5aW5nIChub24taWRlbXBvdGVudCwgb3IgYXR0ZW1wdHMgZXhoYXVzdGVkKSDigJQgYSBjb25uZWN0aW9uXG4gICAgICAgIC8vIGVycm9yL3RpbWVvdXQgaXMgYSBkb3duc3RyZWFtIGZhdWx0OiBmZWVkIHRoZSBicmVha2VyIGFuZCBmYWlsIG5vdy5cbiAgICAgICAgYnJlYWtlci5yZWNvcmRGYWlsdXJlKCk7XG4gICAgICAgIGVtaXRDb3VudGVyKCdzMnNfcmVxdWVzdHNfdG90YWwnLCB7IHRhcmdldCwgbWV0aG9kLCBvdXRjb21lOiAnZXJyb3InIH0pO1xuICAgICAgICB0aHJvdyBsYXN0RXJyb3I7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gTG9vcCBleGhhdXN0ZWQgd2l0aG91dCByZXR1cm5pbmcgKGFsbCBhdHRlbXB0cyByZXRyaWVkIHRoZW4gcmFuIG91dCkuXG4gICAgYnJlYWtlci5yZWNvcmRGYWlsdXJlKCk7XG4gICAgZW1pdENvdW50ZXIoJ3Myc19yZXF1ZXN0c190b3RhbCcsIHsgdGFyZ2V0LCBtZXRob2QsIG91dGNvbWU6ICdlcnJvcicgfSk7XG4gICAgdGhyb3cgbGFzdEVycm9yITtcbiAgfVxuXG4gIHByaXZhdGUgc2xlZXAobXM6IG51bWJlcik6IFByb21pc2U8dm9pZD4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHNldFRpbWVvdXQocmVzb2x2ZSwgbXMpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBJbnRlcm5hbCByZXF1ZXN0IG1ldGhvZC5cbiAgICovXG4gIHByaXZhdGUgcmVxdWVzdDxUPihcbiAgICBtZXRob2Q6IHN0cmluZyxcbiAgICBwYXRoOiBzdHJpbmcsXG4gICAgYm9keT86IHVua25vd24sXG4gICAgb3B0aW9ucz86IFJlcXVlc3RPcHRpb25zLFxuICApOiBQcm9taXNlPEh0dHBDbGllbnRSZXNwb25zZTxUPj4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAvLyBTZXJpYWxpemUgd2hlbiBib2R5IGlzIGRlZmluZWQgKGluY2x1ZGluZyAwL2ZhbHNlLycnIHdoaWNoIGFyZSB2YWxpZCBKU09OIHZhbHVlcykuXG4gICAgICBjb25zdCBib2R5U3RyID0gYm9keSAhPT0gdW5kZWZpbmVkID8gSlNPTi5zdHJpbmdpZnkoYm9keSkgOiB1bmRlZmluZWQ7XG5cbiAgICAgIGNvbnN0IGhlYWRlcnM6IGh0dHAuT3V0Z29pbmdIdHRwSGVhZGVycyA9IHtcbiAgICAgICAgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgICAgLi4ub3B0aW9ucz8uaGVhZGVycyxcbiAgICAgIH07XG5cbiAgICAgIC8vIFByb3BhZ2F0ZSByZXF1ZXN0IElEIGZvciBkaXN0cmlidXRlZCB0cmFjaW5nXG4gICAgICBpZiAob3B0aW9ucz8ucmVxdWVzdElkKSB7XG4gICAgICAgIGhlYWRlcnNbJ1gtUmVxdWVzdC1JZCddID0gb3B0aW9ucy5yZXF1ZXN0SWQ7XG4gICAgICB9XG5cbiAgICAgIGlmIChib2R5U3RyKSB7XG4gICAgICAgIGhlYWRlcnNbJ0NvbnRlbnQtTGVuZ3RoJ10gPSBCdWZmZXIuYnl0ZUxlbmd0aChib2R5U3RyKTtcbiAgICAgIH1cblxuICAgICAgLy8gVmFsaWRhdGUgcGF0aCB0byBwcmV2ZW50IHByb3RvY29sIGluamVjdGlvbiAvIHJlcXVlc3Qgc211Z2dsaW5nXG4gICAgICBpZiAocGF0aC5pbmNsdWRlcygnOi8vJykgfHwgcGF0aC5zdGFydHNXaXRoKCcvLycpIHx8IC9bXFxyXFxuXFwwXS8udGVzdChwYXRoKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgcmVxdWVzdCBwYXRoOiAke3BhdGh9YCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHJlcXVlc3RPcHRpb25zOiBodHRwLlJlcXVlc3RPcHRpb25zID0ge1xuICAgICAgICBob3N0bmFtZTogdGhpcy5jb25maWcuaG9zdCxcbiAgICAgICAgcG9ydDogdGhpcy5jb25maWcucG9ydCxcbiAgICAgICAgcGF0aDogcGF0aC5zdGFydHNXaXRoKCcvJykgPyBwYXRoIDogYC8ke3BhdGh9YCxcbiAgICAgICAgbWV0aG9kLFxuICAgICAgICBoZWFkZXJzLFxuICAgICAgICB0aW1lb3V0OiBvcHRpb25zPy50aW1lb3V0ID8/IHRoaXMuY29uZmlnLnRpbWVvdXQsXG4gICAgICAgIGFnZW50OiB0aGlzLmFnZW50LFxuICAgICAgfTtcblxuICAgICAgY29uc3QgcmVxID0gaHR0cC5yZXF1ZXN0KHJlcXVlc3RPcHRpb25zLCAocmVzKSA9PiB7XG4gICAgICAgIGxldCBkYXRhID0gJyc7XG5cbiAgICAgICAgcmVzLm9uKCdkYXRhJywgKGNodW5rKSA9PiB7XG4gICAgICAgICAgZGF0YSArPSBjaHVuaztcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmVzLm9uKCdlbmQnLCAoKSA9PiB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IHBhcnNlZEJvZHkgPSBkYXRhID8gSlNPTi5wYXJzZShkYXRhKSA6IHt9O1xuICAgICAgICAgICAgcmVzb2x2ZSh7XG4gICAgICAgICAgICAgIHN0YXR1c0NvZGU6IHJlcy5zdGF0dXNDb2RlIHx8IEh0dHBTdGF0dXMuSU5URVJOQUxfU0VSVkVSX0VSUk9SLFxuICAgICAgICAgICAgICBib2R5OiBwYXJzZWRCb2R5IGFzIFQsXG4gICAgICAgICAgICAgIGhlYWRlcnM6IHJlcy5oZWFkZXJzLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSBjYXRjaCAocGFyc2VFcnJvcikge1xuICAgICAgICAgICAgbG9nZ2VyLndhcm4oJ0ZhaWxlZCB0byBwYXJzZSByZXNwb25zZSBib2R5Jywge1xuICAgICAgICAgICAgICBob3N0OiB0aGlzLmNvbmZpZy5ob3N0LFxuICAgICAgICAgICAgICBwYXRoLFxuICAgICAgICAgICAgICBlcnJvcjogcGFyc2VFcnJvciBpbnN0YW5jZW9mIEVycm9yID8gcGFyc2VFcnJvci5tZXNzYWdlIDogU3RyaW5nKHBhcnNlRXJyb3IpLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXNvbHZlKHtcbiAgICAgICAgICAgICAgc3RhdHVzQ29kZTogcmVzLnN0YXR1c0NvZGUgfHwgSHR0cFN0YXR1cy5JTlRFUk5BTF9TRVJWRVJfRVJST1IsXG4gICAgICAgICAgICAgIGJvZHk6IHt9IGFzIFQsXG4gICAgICAgICAgICAgIGhlYWRlcnM6IHJlcy5oZWFkZXJzLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICByZXEub24oJ2Vycm9yJywgKGVycm9yKSA9PiB7XG4gICAgICAgIC8vIE5vZGUgZHVhbC1zdGFjayBjb25uZWN0IGZhaWx1cmVzIGFyZSBhbiBBZ2dyZWdhdGVFcnJvciB3aXRoIGFuIGVtcHR5XG4gICAgICAgIC8vIGAubWVzc2FnZWA7IHRoZSBjYXVzZSBpcyBpbiBgLmNvZGVgIChFQ09OTlJFRlVTRUQvRVRJTUVET1VUKS4gRmFsbFxuICAgICAgICAvLyBiYWNrIHNvIHRoZSBsb2cgaXNuJ3QgYSBibGFuayBgZXJyb3I6XCJcImAuXG4gICAgICAgIGNvbnN0IGRldGFpbCA9IGVycm9yLm1lc3NhZ2UgfHwgKGVycm9yIGFzIE5vZGVKUy5FcnJub0V4Y2VwdGlvbikuY29kZSB8fCBlcnJvci5uYW1lO1xuICAgICAgICBsb2dnZXIuZXJyb3IoJ0hUVFAgcmVxdWVzdCBmYWlsZWQnLCB7XG4gICAgICAgICAgaG9zdDogdGhpcy5jb25maWcuaG9zdCxcbiAgICAgICAgICBwb3J0OiB0aGlzLmNvbmZpZy5wb3J0LFxuICAgICAgICAgIHBhdGgsXG4gICAgICAgICAgbWV0aG9kLFxuICAgICAgICAgIGVycm9yOiBkZXRhaWwsXG4gICAgICAgIH0pO1xuICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgfSk7XG5cbiAgICAgIHJlcS5vbigndGltZW91dCcsICgpID0+IHtcbiAgICAgICAgcmVxLmRlc3Ryb3koKTtcbiAgICAgICAgY29uc3QgZXJyb3IgPSBuZXcgRXJyb3IoYFJlcXVlc3QgdGltZW91dCBhZnRlciAke3RoaXMuY29uZmlnLnRpbWVvdXR9bXNgKTtcbiAgICAgICAgbG9nZ2VyLndhcm4oJ0hUVFAgcmVxdWVzdCB0aW1lb3V0Jywge1xuICAgICAgICAgIGhvc3Q6IHRoaXMuY29uZmlnLmhvc3QsXG4gICAgICAgICAgcGF0aCxcbiAgICAgICAgICB0aW1lb3V0OiB0aGlzLmNvbmZpZy50aW1lb3V0LFxuICAgICAgICB9KTtcbiAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgIH0pO1xuXG4gICAgICBpZiAoYm9keVN0cikge1xuICAgICAgICByZXEud3JpdGUoYm9keVN0cik7XG4gICAgICB9XG5cbiAgICAgIHJlcS5lbmQoKTtcbiAgICB9KTtcbiAgfVxufVxuXG4vKipcbiAqIENyZWF0ZSBhbiBIVFRQIGNsaWVudCB3aXRoIGVycm9yIGhhbmRsaW5nIHRoYXQgcmV0dXJucyBudWxsIG9uIGZhaWx1cmUuXG4gKiBVc2VmdWwgZm9yIGZhaWwtb3BlbiBzY2VuYXJpb3MuXG4gKlxuICogQHBhcmFtIGNvbmZpZyAtIFNlcnZpY2UgY29uZmlndXJhdGlvblxuICogQHJldHVybnMgQ2xpZW50IHdyYXBwZXIgd2l0aCBzYWZlIG1ldGhvZHNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVNhZmVDbGllbnQoY29uZmlnOiBTZXJ2aWNlQ29uZmlnLCBvcHRpb25zPzogSHR0cENsaWVudE9wdGlvbnMpIHtcbiAgY29uc3QgY2xpZW50ID0gbmV3IEludGVybmFsSHR0cENsaWVudChjb25maWcsIG9wdGlvbnMpO1xuXG4gIHJldHVybiB7XG4gICAgLyoqIFJlbGVhc2UgdGhlIHVuZGVybHlpbmcga2VlcC1hbGl2ZSBzb2NrZXQgcG9vbCAobm8tb3Agb24gYSBib3Jyb3dlZCBhZ2VudCkuICovXG4gICAgZGVzdHJveSgpOiB2b2lkIHtcbiAgICAgIGNsaWVudC5kZXN0cm95KCk7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFNhZmUgR0VUIHJlcXVlc3QgLSByZXR1cm5zIG51bGwgb24gZXJyb3IuXG4gICAgICovXG4gICAgYXN5bmMgZ2V0PFQ+KHBhdGg6IHN0cmluZywgb3B0aW9ucz86IFJlcXVlc3RPcHRpb25zKTogUHJvbWlzZTxIdHRwQ2xpZW50UmVzcG9uc2U8VD4gfCBudWxsPiB7XG4gICAgICB0cnkge1xuICAgICAgICByZXR1cm4gYXdhaXQgY2xpZW50LmdldDxUPihwYXRoLCBvcHRpb25zKTtcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBsb2dnZXIuZGVidWcoJ1NhZmUgR0VUIGZhaWxlZCwgcmV0dXJuaW5nIG51bGwnLCB7IHBhdGgsIGVycm9yOiBlcnIgaW5zdGFuY2VvZiBFcnJvciA/IGVyci5tZXNzYWdlIDogU3RyaW5nKGVycikgfSk7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBTYWZlIFBPU1QgcmVxdWVzdCAtIHJldHVybnMgbnVsbCBvbiBlcnJvci5cbiAgICAgKi9cbiAgICBhc3luYyBwb3N0PFQ+KFxuICAgICAgcGF0aDogc3RyaW5nLFxuICAgICAgYm9keT86IHVua25vd24sXG4gICAgICBvcHRpb25zPzogUmVxdWVzdE9wdGlvbnMsXG4gICAgKTogUHJvbWlzZTxIdHRwQ2xpZW50UmVzcG9uc2U8VD4gfCBudWxsPiB7XG4gICAgICB0cnkge1xuICAgICAgICByZXR1cm4gYXdhaXQgY2xpZW50LnBvc3Q8VD4ocGF0aCwgYm9keSwgb3B0aW9ucyk7XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgbG9nZ2VyLmRlYnVnKCdTYWZlIFBPU1QgZmFpbGVkLCByZXR1cm5pbmcgbnVsbCcsIHsgcGF0aCwgZXJyb3I6IGVyciBpbnN0YW5jZW9mIEVycm9yID8gZXJyLm1lc3NhZ2UgOiBTdHJpbmcoZXJyKSB9KTtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFNhZmUgUFVUIHJlcXVlc3QgLSByZXR1cm5zIG51bGwgb24gZXJyb3IuXG4gICAgICovXG4gICAgYXN5bmMgcHV0PFQ+KFxuICAgICAgcGF0aDogc3RyaW5nLFxuICAgICAgYm9keT86IHVua25vd24sXG4gICAgICBvcHRpb25zPzogUmVxdWVzdE9wdGlvbnMsXG4gICAgKTogUHJvbWlzZTxIdHRwQ2xpZW50UmVzcG9uc2U8VD4gfCBudWxsPiB7XG4gICAgICB0cnkge1xuICAgICAgICByZXR1cm4gYXdhaXQgY2xpZW50LnB1dDxUPihwYXRoLCBib2R5LCBvcHRpb25zKTtcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBsb2dnZXIuZGVidWcoJ1NhZmUgUFVUIGZhaWxlZCwgcmV0dXJuaW5nIG51bGwnLCB7IHBhdGgsIGVycm9yOiBlcnIgaW5zdGFuY2VvZiBFcnJvciA/IGVyci5tZXNzYWdlIDogU3RyaW5nKGVycikgfSk7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBTYWZlIERFTEVURSByZXF1ZXN0IC0gcmV0dXJucyBudWxsIG9uIGVycm9yLiBVc2VkIGJ5IGRlc3RydWN0aXZlXG4gICAgICogY3Jvc3Mtc2VydmljZSBvcGVyYXRpb25zIChlLmcuIG9yZy1jYXNjYWRlIGRlbGV0ZSBpbiBwbGF0Zm9ybSkuXG4gICAgICovXG4gICAgYXN5bmMgZGVsZXRlPFQ+KFxuICAgICAgcGF0aDogc3RyaW5nLFxuICAgICAgb3B0aW9ucz86IFJlcXVlc3RPcHRpb25zLFxuICAgICk6IFByb21pc2U8SHR0cENsaWVudFJlc3BvbnNlPFQ+IHwgbnVsbD4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IGNsaWVudC5kZWxldGU8VD4ocGF0aCwgb3B0aW9ucyk7XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgbG9nZ2VyLmRlYnVnKCdTYWZlIERFTEVURSBmYWlsZWQsIHJldHVybmluZyBudWxsJywgeyBwYXRoLCBlcnJvcjogZXJyIGluc3RhbmNlb2YgRXJyb3IgPyBlcnIubWVzc2FnZSA6IFN0cmluZyhlcnIpIH0pO1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICB9LFxuICB9O1xufVxuIl19
|
package/lib/services/index.d.ts
CHANGED
|
@@ -5,6 +5,8 @@ export * from './compliance-client.js';
|
|
|
5
5
|
export * from './compliance-event-subscriber.js';
|
|
6
6
|
export * from './entity-events.js';
|
|
7
7
|
export * from './http-client.js';
|
|
8
|
+
export * from './circuit-breaker.js';
|
|
9
|
+
export * from './durable-event-bus.js';
|
|
8
10
|
export { DEFAULT_MAX_RETRIES, DEFAULT_RETRY_DELAY_MS, DEFAULT_MAX_RATE_LIMIT_RETRIES, calculateBackoff, getRetryDecision, getErrorRetryDecision, } from './retry-strategy.js';
|
|
9
11
|
export type { RetryConfig, RetryDecision } from './retry-strategy.js';
|
|
10
12
|
export * from './quota.js';
|