@workflow/core 5.0.0-beta.43 → 5.0.0-beta.44
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/capabilities.d.ts +4 -4
- package/dist/capabilities.js +5 -5
- package/dist/capture-stack.d.ts +1 -1
- package/dist/capture-stack.js +2 -2
- package/dist/class-serialization.d.ts +8 -8
- package/dist/class-serialization.js +9 -9
- package/dist/classify-error.js +5 -5
- package/dist/context-violation-error.d.ts +5 -5
- package/dist/context-violation-error.d.ts.map +1 -1
- package/dist/context-violation-error.js +5 -5
- package/dist/create-hook.d.ts +2 -2
- package/dist/create-hook.js +1 -1
- package/dist/define-hook.js +2 -2
- package/dist/describe-error.d.ts +7 -7
- package/dist/describe-error.js +8 -8
- package/dist/encryption.d.ts +5 -5
- package/dist/encryption.js +7 -7
- package/dist/events-consumer.d.ts +19 -7
- package/dist/events-consumer.d.ts.map +1 -1
- package/dist/events-consumer.js +33 -12
- package/dist/flushable-stream.d.ts +4 -4
- package/dist/flushable-stream.js +12 -12
- package/dist/global.d.ts +1 -1
- package/dist/global.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -2
- package/dist/log-format.d.ts +2 -2
- package/dist/log-format.js +5 -5
- package/dist/logger.js +4 -4
- package/dist/private.d.ts +21 -65
- package/dist/private.d.ts.map +1 -1
- package/dist/private.js +160 -38
- package/dist/replay-payload-cache.d.ts +1 -1
- package/dist/replay-payload-cache.js +4 -4
- package/dist/runtime/compute-instance.d.ts +4 -3
- package/dist/runtime/compute-instance.d.ts.map +1 -1
- package/dist/runtime/compute-instance.js +5 -4
- package/dist/runtime/constants.d.ts +24 -24
- package/dist/runtime/constants.d.ts.map +1 -1
- package/dist/runtime/constants.js +49 -43
- package/dist/runtime/count-step-started-events.d.ts +7 -7
- package/dist/runtime/count-step-started-events.js +4 -4
- package/dist/runtime/deployment-guard.d.ts +7 -7
- package/dist/runtime/deployment-guard.js +8 -8
- package/dist/runtime/get-port-lazy.d.ts +2 -2
- package/dist/runtime/get-port-lazy.d.ts.map +1 -1
- package/dist/runtime/get-port-lazy.js +37 -30
- package/dist/runtime/get-world-lazy.d.ts +2 -2
- package/dist/runtime/get-world-lazy.js +3 -3
- package/dist/runtime/helpers.d.ts +18 -18
- package/dist/runtime/helpers.js +27 -27
- package/dist/runtime/quickjs-entrypoint.d.ts +21 -10
- package/dist/runtime/quickjs-entrypoint.d.ts.map +1 -1
- package/dist/runtime/quickjs-entrypoint.js +199 -81
- package/dist/runtime/quickjs-runtime.d.ts +31 -15
- package/dist/runtime/quickjs-runtime.d.ts.map +1 -1
- package/dist/runtime/quickjs-runtime.js +126 -77
- package/dist/runtime/quickjs-serde.d.ts +10 -10
- package/dist/runtime/quickjs-serde.js +20 -20
- package/dist/runtime/replay-budget.d.ts +4 -4
- package/dist/runtime/replay-budget.js +5 -5
- package/dist/runtime/replay-recovery-reporter.d.ts +1 -1
- package/dist/runtime/replay-recovery-reporter.js +2 -2
- package/dist/runtime/resume-hook.d.ts +2 -2
- package/dist/runtime/resume-hook.js +27 -27
- package/dist/runtime/resume-latency.d.ts +25 -25
- package/dist/runtime/resume-latency.d.ts.map +1 -1
- package/dist/runtime/resume-latency.js +4 -4
- package/dist/runtime/run-id-time.d.ts +2 -2
- package/dist/runtime/run-id-time.js +5 -5
- package/dist/runtime/run.d.ts +21 -4
- package/dist/runtime/run.d.ts.map +1 -1
- package/dist/runtime/run.js +104 -10
- package/dist/runtime/runs.d.ts +4 -4
- package/dist/runtime/runs.js +2 -2
- package/dist/runtime/start.d.ts +3 -3
- package/dist/runtime/start.d.ts.map +1 -1
- package/dist/runtime/start.js +27 -23
- package/dist/runtime/step-executor.d.ts +14 -14
- package/dist/runtime/step-executor.d.ts.map +1 -1
- package/dist/runtime/step-executor.js +54 -39
- package/dist/runtime/step-latency.d.ts +14 -14
- package/dist/runtime/step-latency.js +11 -11
- package/dist/runtime/step-ownership.d.ts +6 -6
- package/dist/runtime/step-ownership.js +8 -8
- package/dist/runtime/step-single-flight.d.ts +1 -1
- package/dist/runtime/step-single-flight.d.ts.map +1 -1
- package/dist/runtime/step-single-flight.js +17 -11
- package/dist/runtime/suspension-handler.d.ts +29 -17
- package/dist/runtime/suspension-handler.d.ts.map +1 -1
- package/dist/runtime/suspension-handler.js +206 -71
- package/dist/runtime/unserializable-step.d.ts +34 -0
- package/dist/runtime/unserializable-step.d.ts.map +1 -0
- package/dist/runtime/unserializable-step.js +52 -0
- package/dist/runtime/vm-mode.d.ts +1 -1
- package/dist/runtime/vm-mode.js +2 -2
- package/dist/runtime/wait-continuation.d.ts +31 -9
- package/dist/runtime/wait-continuation.d.ts.map +1 -1
- package/dist/runtime/wait-continuation.js +44 -13
- package/dist/runtime/wait-until.d.ts +1 -1
- package/dist/runtime/wait-until.js +2 -2
- package/dist/runtime/world-compatibility.d.ts +20 -9
- package/dist/runtime/world-compatibility.d.ts.map +1 -1
- package/dist/runtime/world-compatibility.js +24 -13
- package/dist/runtime/world-init.d.ts +5 -5
- package/dist/runtime/world-init.js +6 -6
- package/dist/runtime/world.d.ts.map +1 -1
- package/dist/runtime/world.js +13 -3
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +300 -206
- package/dist/sealed-box.d.ts +7 -7
- package/dist/sealed-box.js +15 -15
- package/dist/serialization/client.js +2 -2
- package/dist/serialization/codec-devalue-vm.d.ts +1 -1
- package/dist/serialization/codec-devalue-vm.js +4 -4
- package/dist/serialization/codec-devalue.d.ts +1 -1
- package/dist/serialization/codec-devalue.js +2 -2
- package/dist/serialization/codec.d.ts +4 -4
- package/dist/serialization/codec.js +2 -2
- package/dist/serialization/compression.d.ts +12 -11
- package/dist/serialization/compression.d.ts.map +1 -1
- package/dist/serialization/compression.js +16 -15
- package/dist/serialization/encryption.d.ts +7 -7
- package/dist/serialization/encryption.d.ts.map +1 -1
- package/dist/serialization/encryption.js +8 -8
- package/dist/serialization/errors.js +2 -2
- package/dist/serialization/format.d.ts +6 -6
- package/dist/serialization/format.js +7 -7
- package/dist/serialization/hardened.d.ts +18 -18
- package/dist/serialization/hardened.d.ts.map +1 -1
- package/dist/serialization/hardened.js +41 -32
- package/dist/serialization/index.d.ts +1 -1
- package/dist/serialization/index.js +2 -2
- package/dist/serialization/reducers/class-vm.d.ts +1 -1
- package/dist/serialization/reducers/class-vm.js +2 -2
- package/dist/serialization/reducers/class.js +2 -2
- package/dist/serialization/reducers/common-vm.js +12 -12
- package/dist/serialization/reducers/common.js +12 -12
- package/dist/serialization/reducers/step-function-vm.d.ts +1 -1
- package/dist/serialization/reducers/step-function-vm.js +2 -2
- package/dist/serialization/reducers/step-function.js +2 -2
- package/dist/serialization/step.js +2 -2
- package/dist/serialization/types.d.ts +5 -5
- package/dist/serialization/types.js +2 -2
- package/dist/serialization/workflow-vm.d.ts +1 -1
- package/dist/serialization/workflow-vm.d.ts.map +1 -1
- package/dist/serialization/workflow-vm.js +13 -10
- package/dist/serialization-format.d.ts +11 -11
- package/dist/serialization-format.d.ts.map +1 -1
- package/dist/serialization-format.js +29 -23
- package/dist/serialization.d.ts +10 -10
- package/dist/serialization.js +98 -98
- package/dist/set-attributes.js +2 -2
- package/dist/source-map.d.ts +1 -1
- package/dist/source-map.d.ts.map +1 -1
- package/dist/source-map.js +18 -12
- package/dist/step/context-storage.d.ts +5 -5
- package/dist/step/context-storage.js +1 -1
- package/dist/step/writable-stream.d.ts +3 -3
- package/dist/step/writable-stream.js +7 -7
- package/dist/step.js +12 -12
- package/dist/symbols.d.ts +2 -2
- package/dist/symbols.js +3 -3
- package/dist/telemetry/semantic-conventions.d.ts +21 -13
- package/dist/telemetry/semantic-conventions.d.ts.map +1 -1
- package/dist/telemetry/semantic-conventions.js +21 -15
- package/dist/telemetry.d.ts +3 -3
- package/dist/telemetry.d.ts.map +1 -1
- package/dist/telemetry.js +19 -10
- package/dist/test-support/orchestrator-context.d.ts.map +1 -1
- package/dist/test-support/orchestrator-context.js +12 -2
- package/dist/version.d.ts +1 -1
- package/dist/version.js +2 -2
- package/dist/vm/index.js +4 -4
- package/dist/vm/script-cache.d.ts.map +1 -1
- package/dist/vm/script-cache.js +23 -17
- package/dist/vm/uint8array-base64.js +1 -1
- package/dist/workflow/abort-controller.d.ts +1 -1
- package/dist/workflow/abort-controller.js +12 -12
- package/dist/workflow/create-hook.js +2 -2
- package/dist/workflow/get-workflow-metadata.js +2 -2
- package/dist/workflow/hook.js +16 -16
- package/dist/workflow/set-attributes.d.ts +1 -1
- package/dist/workflow/set-attributes.js +2 -2
- package/dist/workflow/sleep.js +2 -2
- package/dist/workflow/world-init-stub.d.ts +1 -1
- package/dist/workflow/world-init-stub.js +2 -2
- package/dist/workflow.d.ts +2 -2
- package/dist/workflow.js +21 -7
- package/docs/api-reference/create-hook.mdx +15 -15
- package/docs/api-reference/create-webhook.mdx +15 -15
- package/docs/api-reference/define-hook.mdx +10 -10
- package/docs/api-reference/fatal-error.mdx +2 -2
- package/docs/api-reference/fetch.mdx +7 -7
- package/docs/api-reference/get-step-metadata.mdx +2 -2
- package/docs/api-reference/get-workflow-metadata.mdx +3 -3
- package/docs/api-reference/get-writable.mdx +7 -7
- package/docs/api-reference/index.mdx +1 -1
- package/docs/api-reference/retryable-error.mdx +1 -1
- package/docs/api-reference/set-attributes.mdx +2 -2
- package/docs/api-reference/sleep.mdx +3 -3
- package/docs/foundations/cancellation.mdx +31 -31
- package/docs/foundations/errors-and-retries.mdx +42 -11
- package/docs/foundations/hooks.mdx +35 -35
- package/docs/foundations/idempotency.mdx +9 -9
- package/docs/foundations/serialization.mdx +21 -22
- package/docs/foundations/starting-workflows.mdx +36 -37
- package/docs/foundations/streaming.mdx +46 -41
- package/docs/foundations/versioning.mdx +3 -3
- package/docs/foundations/workflows-and-steps.mdx +9 -9
- package/docs/how-it-works/cancellation.mdx +62 -62
- package/docs/how-it-works/code-transform.mdx +66 -54
- package/docs/how-it-works/encryption.mdx +25 -21
- package/docs/how-it-works/event-sourcing.mdx +53 -35
- package/docs/how-it-works/framework-integrations.mdx +12 -12
- package/docs/how-it-works/understanding-directives.mdx +21 -21
- package/package.json +7 -7
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { globalSingleton } from '@workflow/utils';
|
|
1
2
|
import { envNumber } from '@workflow/world';
|
|
2
3
|
import { runtimeLogger } from '../logger.js';
|
|
3
4
|
// Maximum number of queue delivery attempts before the handler gives up and
|
|
@@ -9,15 +10,15 @@ import { runtimeLogger } from '../logger.js';
|
|
|
9
10
|
// `retry-after` the handler returns (see world-vercel
|
|
10
11
|
// `getHandlerErrorRetryAfterSeconds`) fed through VQS `calculateBackoffDelay`.
|
|
11
12
|
// VQS uses our value for the first 32 attempts (clamped to [5s, 900s]) then
|
|
12
|
-
// applies its own exponential growth
|
|
13
|
+
// applies its own exponential growth, every hop hard-capped at the SQS limit
|
|
13
14
|
// of 900s. With the backoff ramping toward that 900s ceiling (reached by
|
|
14
15
|
// ~delivery 11), 48 attempts span roughly 9–10 hours of wall-clock (~35,000s),
|
|
15
16
|
// comfortably under the 24-hour message-visibility limit so the failure path
|
|
16
17
|
// runs before the message expires. (A flatter, low-capped backoff exhausts the
|
|
17
18
|
// budget in only a few hours, failing otherwise-healthy runs during a transient
|
|
18
19
|
// backend outage; conversely, spanning the full 24h window would require a
|
|
19
|
-
// substantially higher cap here, not a higher per-hop ceiling
|
|
20
|
-
// every hop at 900s.)
|
|
20
|
+
// substantially higher cap here, not a higher per-hop ceiling, since VQS
|
|
21
|
+
// clamps every hop at 900s.)
|
|
21
22
|
export const MAX_QUEUE_DELIVERIES = 48;
|
|
22
23
|
/**
|
|
23
24
|
* Effective max queue deliveries. Override via `WORKFLOW_MAX_QUEUE_DELIVERIES`.
|
|
@@ -37,7 +38,7 @@ export function getMaxQueueDeliveries() {
|
|
|
37
38
|
/**
|
|
38
39
|
* Default maximum time allowed for the *replay* portion of a single workflow
|
|
39
40
|
* handler invocation (in ms). This budget only covers deterministic-replay
|
|
40
|
-
* and workflow-VM execution between step boundaries
|
|
41
|
+
* and workflow-VM execution between step boundaries. Inline step bodies
|
|
41
42
|
* (`"use step"` functions invoked via `executeStep`) do NOT count against
|
|
42
43
|
* it. Step bodies are bounded separately by the platform's function
|
|
43
44
|
* `maxDuration` (e.g. 800s on Vercel Pro Fluid) and `NO_INLINE_REPLAY_AFTER_MS`.
|
|
@@ -48,7 +49,7 @@ export function getMaxQueueDeliveries() {
|
|
|
48
49
|
* `RUN_ERROR_CODES.REPLAY_TIMEOUT`.
|
|
49
50
|
*
|
|
50
51
|
* Note that on Vercel Hobby (standard functions), the platform `maxDuration`
|
|
51
|
-
* is 60s
|
|
52
|
+
* is 60s, well below this budget, so the platform SIGTERM will fire first
|
|
52
53
|
* and the queue will re-deliver until the visibility window expires. With
|
|
53
54
|
* Fluid Compute on Hobby the per-function ceiling rises to 300s, still
|
|
54
55
|
* under the default budget.
|
|
@@ -67,11 +68,19 @@ export const MIN_REPLAY_TIMEOUT_MS = 30_000;
|
|
|
67
68
|
export const MAX_REPLAY_TIMEOUT_MS = 780_000;
|
|
68
69
|
// Track which raw env var values we've already warned about so the warning
|
|
69
70
|
// log only fires once per process (the function may be called many times).
|
|
70
|
-
|
|
71
|
+
//
|
|
72
|
+
// On `globalThis` rather than at module scope so "once per process" survives
|
|
73
|
+
// bundling: this package is compiled into the host application's server build
|
|
74
|
+
// once per bundler layer, and per-copy sets warn once per layer instead.
|
|
75
|
+
const warned = globalSingleton('@workflow/core//envWarnings', 1, () => ({
|
|
76
|
+
replayTimeoutValues: new Set(),
|
|
77
|
+
maxInlineStepsValues: new Set(),
|
|
78
|
+
maxEventsValues: new Set(),
|
|
79
|
+
}));
|
|
71
80
|
function warnOnce(raw, message, data) {
|
|
72
|
-
if (
|
|
81
|
+
if (warned.replayTimeoutValues.has(raw))
|
|
73
82
|
return;
|
|
74
|
-
|
|
83
|
+
warned.replayTimeoutValues.add(raw);
|
|
75
84
|
runtimeLogger.warn(message, data);
|
|
76
85
|
}
|
|
77
86
|
/**
|
|
@@ -79,7 +88,7 @@ function warnOnce(raw, message, data) {
|
|
|
79
88
|
*
|
|
80
89
|
* Reads `process.env.WORKFLOW_REPLAY_TIMEOUT_MS` lazily so tests and
|
|
81
90
|
* deployments can override per invocation. Invalid / out-of-range values
|
|
82
|
-
* fall back to a safe value (no throw
|
|
91
|
+
* fall back to a safe value (no throw: the env var is an escape hatch,
|
|
83
92
|
* not a hard requirement) and emit a one-time warning so misconfiguration
|
|
84
93
|
* is observable.
|
|
85
94
|
*/
|
|
@@ -111,13 +120,13 @@ export function getReplayTimeoutMs() {
|
|
|
111
120
|
return parsed;
|
|
112
121
|
}
|
|
113
122
|
/**
|
|
114
|
-
* Reset the warn-once cache. Test-only
|
|
123
|
+
* Reset the warn-once cache. Test-only: exported so unit tests can
|
|
115
124
|
* exercise the warn path repeatedly without sharing state.
|
|
116
125
|
*
|
|
117
126
|
* @internal
|
|
118
127
|
*/
|
|
119
128
|
export function _resetReplayTimeoutWarnCacheForTests() {
|
|
120
|
-
|
|
129
|
+
warned.replayTimeoutValues.clear();
|
|
121
130
|
}
|
|
122
131
|
// Number of queue delivery attempts to allow before permanently failing a run
|
|
123
132
|
// due to a replay timeout. On attempts 1 through this value, the timeout
|
|
@@ -134,8 +143,8 @@ export function getReplayTimeoutMaxRetries() {
|
|
|
134
143
|
/**
|
|
135
144
|
* Default maximum number of steps the owned-inline path runs inline (in
|
|
136
145
|
* parallel) per suspension. The rest are queued to background handlers. Each
|
|
137
|
-
* inline step is created lazily
|
|
138
|
-
* `step_started` that `executeStep` sends
|
|
146
|
+
* inline step is created lazily (its `step_created` is folded into the
|
|
147
|
+
* `step_started` that `executeStep` sends), so inlining N steps saves N queue
|
|
139
148
|
* round-trips for a `Promise.all`-style fan-out. `1` reproduces the
|
|
140
149
|
* single-inline-step behavior exactly (useful kill-switch).
|
|
141
150
|
*
|
|
@@ -150,14 +159,12 @@ export const MIN_MAX_INLINE_STEPS = 1;
|
|
|
150
159
|
* within one function invocation, so this caps memory/CPU fan-out per handler.
|
|
151
160
|
*/
|
|
152
161
|
export const MAX_MAX_INLINE_STEPS = 16;
|
|
153
|
-
// Warn-once cache for WORKFLOW_MAX_INLINE_STEPS, keyed by raw env value.
|
|
154
|
-
const warnedMaxInlineStepsValues = new Set();
|
|
155
162
|
/**
|
|
156
163
|
* Resolve the effective max number of inline steps for the current process.
|
|
157
164
|
*
|
|
158
165
|
* Reads `process.env.WORKFLOW_MAX_INLINE_STEPS` lazily so tests and
|
|
159
166
|
* deployments can override per invocation. Invalid / out-of-range values fall
|
|
160
|
-
* back to a safe value (no throw
|
|
167
|
+
* back to a safe value (no throw: the env var is an escape hatch) and emit a
|
|
161
168
|
* one-time warning so misconfiguration is observable.
|
|
162
169
|
*/
|
|
163
170
|
export function getMaxInlineSteps() {
|
|
@@ -166,8 +173,8 @@ export function getMaxInlineSteps() {
|
|
|
166
173
|
return MAX_INLINE_STEPS;
|
|
167
174
|
const parsed = Number(raw);
|
|
168
175
|
if (!Number.isInteger(parsed) || parsed <= 0) {
|
|
169
|
-
if (!
|
|
170
|
-
|
|
176
|
+
if (!warned.maxInlineStepsValues.has(raw)) {
|
|
177
|
+
warned.maxInlineStepsValues.add(raw);
|
|
171
178
|
runtimeLogger.warn('Ignoring WORKFLOW_MAX_INLINE_STEPS: not a positive integer; using default', { raw, defaultValue: MAX_INLINE_STEPS });
|
|
172
179
|
}
|
|
173
180
|
return MAX_INLINE_STEPS;
|
|
@@ -175,8 +182,8 @@ export function getMaxInlineSteps() {
|
|
|
175
182
|
if (parsed < MIN_MAX_INLINE_STEPS)
|
|
176
183
|
return MIN_MAX_INLINE_STEPS;
|
|
177
184
|
if (parsed > MAX_MAX_INLINE_STEPS) {
|
|
178
|
-
if (!
|
|
179
|
-
|
|
185
|
+
if (!warned.maxInlineStepsValues.has(raw)) {
|
|
186
|
+
warned.maxInlineStepsValues.add(raw);
|
|
180
187
|
runtimeLogger.warn('WORKFLOW_MAX_INLINE_STEPS above maximum; clamped', {
|
|
181
188
|
raw,
|
|
182
189
|
clampedValue: MAX_MAX_INLINE_STEPS,
|
|
@@ -214,7 +221,7 @@ export const MAX_RESILIENT_STEP_INPUT_BYTES = 128 * 1024;
|
|
|
214
221
|
* **Off by default.** Enable via `WORKFLOW_RESILIENT_STEP_DISPATCH=1`.
|
|
215
222
|
*
|
|
216
223
|
* The queue publish races the create's verdict, and a create can come back
|
|
217
|
-
* refused
|
|
224
|
+
* refused: as a duplicate this replay should stop pursuing, or as a stale
|
|
218
225
|
* write on a World that refuses rather than reports. Either way the message
|
|
219
226
|
* carrying the payload is already out, so the consumer can materialize a step
|
|
220
227
|
* whose create was refused, and nothing orders the verdict before the
|
|
@@ -231,11 +238,11 @@ export function isResilientStepDispatchEnabled() {
|
|
|
231
238
|
* instead of one write per event. Only engages when the World implements the
|
|
232
239
|
* optional `events.createBatch` AND the run is on slot identity
|
|
233
240
|
* (specVersion >= 6) AND the suspension carries no attribute/hook writes and
|
|
234
|
-
* no resilient step dispatch
|
|
241
|
+
* no resilient step dispatch. Everything else keeps the single-event path
|
|
235
242
|
* byte-for-byte.
|
|
236
243
|
*
|
|
237
244
|
* Reads `process.env.WORKFLOW_BATCH_TRANSITIONS` lazily. Default **ON**;
|
|
238
|
-
* disabled only by an explicit `'0'` / `'false'` (case-insensitive)
|
|
245
|
+
* disabled only by an explicit `'0'` / `'false'` (case-insensitive), the
|
|
239
246
|
* operator escape hatch that restores the exact prior one-write-per-event
|
|
240
247
|
* path, mirroring `WORKFLOW_TURBO`'s kill-switch shape.
|
|
241
248
|
*/
|
|
@@ -250,13 +257,12 @@ export function isBatchTransitionsEnabled() {
|
|
|
250
257
|
* Mirrors the server's transaction budgets with a comfortable margin: each
|
|
251
258
|
* fan-out event costs 2 transaction items server-side (entity + event row)
|
|
252
259
|
* against the 100-item DynamoDB cap, and inline payloads count against a
|
|
253
|
-
* 768 KB byte budget
|
|
254
|
-
* than this
|
|
260
|
+
* 768 KB byte budget, so 32 events stays well under both, and a fan-out larger
|
|
261
|
+
* than this commits in successive batches (split batches lose
|
|
255
262
|
* cross-batch atomicity, which is exactly today's per-event-write crash
|
|
256
|
-
* surface
|
|
263
|
+
* surface, and every batch still converges on retry via per-event 409s).
|
|
257
264
|
*/
|
|
258
265
|
export const MAX_BATCH_FANOUT_EVENTS = 32;
|
|
259
|
-
const warnedMaxEventsValues = new Set();
|
|
260
266
|
/**
|
|
261
267
|
* Optional client-side override for the server-supplied per-run event ceiling.
|
|
262
268
|
* When set to a positive integer, the runtime clamps the server's limit *down*
|
|
@@ -265,7 +271,7 @@ const warnedMaxEventsValues = new Set();
|
|
|
265
271
|
*
|
|
266
272
|
* Reads `process.env.WORKFLOW_MAX_EVENTS_OVERRIDE` lazily so tests and
|
|
267
273
|
* deployments can override per invocation. Invalid values fall back to unset
|
|
268
|
-
* (no throw
|
|
274
|
+
* (no throw: the env var is an escape hatch) and emit a one-time warning.
|
|
269
275
|
*/
|
|
270
276
|
export function getMaxEventsOverride() {
|
|
271
277
|
const raw = process.env.WORKFLOW_MAX_EVENTS_OVERRIDE;
|
|
@@ -273,8 +279,8 @@ export function getMaxEventsOverride() {
|
|
|
273
279
|
return undefined;
|
|
274
280
|
const parsed = Number(raw);
|
|
275
281
|
if (!Number.isInteger(parsed) || parsed <= 0) {
|
|
276
|
-
if (!
|
|
277
|
-
|
|
282
|
+
if (!warned.maxEventsValues.has(raw)) {
|
|
283
|
+
warned.maxEventsValues.add(raw);
|
|
278
284
|
runtimeLogger.warn('Ignoring WORKFLOW_MAX_EVENTS_OVERRIDE: not a positive integer; using server limit', { raw });
|
|
279
285
|
}
|
|
280
286
|
return undefined;
|
|
@@ -288,7 +294,7 @@ export function getMaxEventsOverride() {
|
|
|
288
294
|
* `step_started` only before the terminal write.
|
|
289
295
|
*
|
|
290
296
|
* This can run a step body more than once when handlers race for the same
|
|
291
|
-
* step's create-claim
|
|
297
|
+
* step's create-claim: both run the body before one wins. That is unsafe for
|
|
292
298
|
* steps with non-idempotent side effects; in particular, two concurrent runs
|
|
293
299
|
* of a step that writes to the workflow stream (e.g. an AI agent streaming
|
|
294
300
|
* tokens) can interleave and corrupt the stream data. So the optimization is
|
|
@@ -323,7 +329,7 @@ export function isOptimisticInlineStartExplicitlyDisabled() {
|
|
|
323
329
|
* the first invocation* of a run (detected by the entrypoint via `runInput`
|
|
324
330
|
* presence + `metadata.attempt === 1`): it backgrounds the `run_started` event
|
|
325
331
|
* creation, skips the initial event-log load (nothing has been written yet),
|
|
326
|
-
* and forces optimistic inline step start for that invocation
|
|
332
|
+
* and forces optimistic inline step start for that invocation, independent of
|
|
327
333
|
* `WORKFLOW_OPTIMISTIC_INLINE_START`.
|
|
328
334
|
*
|
|
329
335
|
* Forcing optimistic start is safe here because the first delivery has no
|
|
@@ -346,7 +352,7 @@ export function isTurboEnabled() {
|
|
|
346
352
|
* enabled (default ON). When on, the engine hydrates a VM with the
|
|
347
353
|
* workflow bundle once per function instance, snapshots it, and starts
|
|
348
354
|
* every invocation by restoring the snapshot instead of re-evaluating
|
|
349
|
-
* the bundle
|
|
355
|
+
* the bundle, skipping the dominant share of VM startup (measured
|
|
350
356
|
* ~77ms → ~3ms to first suspension for a 1.3MB bundle). Bundles whose
|
|
351
357
|
* module scope consumes randomness, reads the clock, or replaces a
|
|
352
358
|
* serialization intrinsic are detected at hydrate time and
|
|
@@ -381,12 +387,12 @@ export function isVmRetentionEnabled() {
|
|
|
381
387
|
* Whether inline step ownership is enabled (default ON). When on, the lazy
|
|
382
388
|
* `step_started` that creates an inline step records the owning queue
|
|
383
389
|
* message ID, and wake replays that observe an actively-owned step enqueue a
|
|
384
|
-
* *delayed backstop* message instead of immediately requeueing it
|
|
390
|
+
* *delayed backstop* message instead of immediately requeueing it, fixing
|
|
385
391
|
* duplicate inline step execution when a hook/wait wakes a run mid-step
|
|
386
392
|
* (vercel/workflow#2780).
|
|
387
393
|
*
|
|
388
394
|
* `WORKFLOW_INLINE_OWNERSHIP=0` (or `false`) is the kill switch: dispatch
|
|
389
|
-
* reverts to the unconditional immediate requeue. Stamping is unaffected
|
|
395
|
+
* reverts to the unconditional immediate requeue. Stamping is unaffected:
|
|
390
396
|
* the recorded ownerMessageId is inert data when the switch is off.
|
|
391
397
|
*/
|
|
392
398
|
export function isInlineOwnershipEnabled() {
|
|
@@ -403,16 +409,16 @@ export function isInlineOwnershipEnabled() {
|
|
|
403
409
|
* immediately; past it, they enqueue immediately (today's behavior).
|
|
404
410
|
*
|
|
405
411
|
* Why a fixed 860 and not a value derived from the function's `maxDuration`:
|
|
406
|
-
* neither runtime nor build time can see the resolved value
|
|
412
|
+
* neither runtime nor build time can see the resolved value: builders emit
|
|
407
413
|
* `maxDuration: 'max'`, which the platform resolves per-plan at deploy, and
|
|
408
414
|
* no env var or request-context deadline API exposes the result. The bound
|
|
409
415
|
* comes from a platform rule instead: durations above 800s require explicit
|
|
410
416
|
* per-function numeric config, so a builder-emitted `'max'` resolves to at
|
|
411
|
-
* most 800s
|
|
417
|
+
* most 800s, and 860s therefore dominates any workflow route's invocation
|
|
412
418
|
* lifetime plus scheduling slack. Revisit when that ceiling moves (the
|
|
413
419
|
* 30-minute duration beta becoming reachable via `'max'` would invalidate
|
|
414
420
|
* the bound). Worlds without an invocation kill bound (world-local,
|
|
415
|
-
* self-hosted) get no death proof from any constant
|
|
421
|
+
* self-hosted) get no death proof from any constant. There the in-process
|
|
416
422
|
* single-flight layer (step-single-flight.ts) is what makes a backstop
|
|
417
423
|
* firing mid-step harmless.
|
|
418
424
|
*
|
|
@@ -425,13 +431,13 @@ export function isInlineOwnershipEnabled() {
|
|
|
425
431
|
export const INLINE_OWNERSHIP_LEASE_SECONDS = 860;
|
|
426
432
|
/**
|
|
427
433
|
* Upper bound for the lease env override. 900s is the queue's maximum
|
|
428
|
-
* per-message delay (SQS cap)
|
|
434
|
+
* per-message delay (SQS cap). A longer lease would need delay chaining
|
|
429
435
|
* like long waits use; clamp instead so one delayed message always suffices.
|
|
430
436
|
*/
|
|
431
437
|
export const MAX_INLINE_OWNERSHIP_LEASE_SECONDS = 900;
|
|
432
438
|
/**
|
|
433
439
|
* Effective inline-ownership lease. Override via
|
|
434
|
-
* `WORKFLOW_INLINE_OWNERSHIP_LEASE_SECONDS
|
|
440
|
+
* `WORKFLOW_INLINE_OWNERSHIP_LEASE_SECONDS`, e.g. raise it on self-hosted
|
|
435
441
|
* multi-instance worlds with long-running steps to widen the window in which
|
|
436
442
|
* a live owner is protected from a concurrent backstop execution.
|
|
437
443
|
*/
|
|
@@ -466,9 +472,9 @@ export function getPreconditionMaxInProcessRestarts() {
|
|
|
466
472
|
// The in-process budget above is per-invocation, and a re-invocation that
|
|
467
473
|
// enqueues a fresh message also restarts the queue's delivery count, so without
|
|
468
474
|
// a counter carried on the message a permanently fenced run has no run-level
|
|
469
|
-
// bound at all. It can stay fenced without any permanent fault
|
|
475
|
+
// bound at all. It can stay fenced without any permanent fault (a full reload
|
|
470
476
|
// is not atomic across pages, so a busy run can acquire a new hole on every
|
|
471
|
-
// reload
|
|
477
|
+
// reload), so the chain is counted and the run fails once this many
|
|
472
478
|
// re-invocations have been spent on stale-snapshot rejections.
|
|
473
479
|
export const PRECONDITION_MAX_REINVOCATIONS = 5;
|
|
474
480
|
/**
|
|
@@ -502,4 +508,4 @@ export const DEPLOYMENT_MISMATCH_MAX_RETRIES = 3;
|
|
|
502
508
|
export function getDeploymentMismatchMaxRetries() {
|
|
503
509
|
return envNumber('WORKFLOW_DEPLOYMENT_MISMATCH_MAX_RETRIES', DEPLOYMENT_MISMATCH_MAX_RETRIES, { integer: true, min: 0 });
|
|
504
510
|
}
|
|
505
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uc3RhbnRzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3J1bnRpbWUvY29uc3RhbnRzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUM1QyxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBRTdDLDRFQUE0RTtBQUM1RSw0RUFBNEU7QUFDNUUseUVBQXlFO0FBQ3pFLG9EQUFvRDtBQUNwRCxFQUFFO0FBQ0YsK0VBQStFO0FBQy9FLHNEQUFzRDtBQUN0RCwrRUFBK0U7QUFDL0UsNEVBQTRFO0FBQzVFLDhFQUE4RTtBQUM5RSx5RUFBeUU7QUFDekUsK0VBQStFO0FBQy9FLDZFQUE2RTtBQUM3RSwrRUFBK0U7QUFDL0UsZ0ZBQWdGO0FBQ2hGLDJFQUEyRTtBQUMzRSwyRUFBMkU7QUFDM0Usc0JBQXNCO0FBQ3RCLE1BQU0sQ0FBQyxNQUFNLG9CQUFvQixHQUFHLEVBQUUsQ0FBQztBQUV2Qzs7R0FFRztBQUNILE1BQU0sVUFBVSxxQkFBcUI7SUFDbkMsd0VBQXdFO0lBQ3hFLDBFQUEwRTtJQUMxRSw4RUFBOEU7SUFDOUUseUVBQXlFO0lBQ3pFLDRFQUE0RTtJQUM1RSxPQUFPLFNBQVMsQ0FBQywrQkFBK0IsRUFBRSxvQkFBb0IsRUFBRTtRQUN0RSxPQUFPLEVBQUUsSUFBSTtRQUNiLEdBQUcsRUFBRSxDQUFDO1FBQ04sR0FBRyxFQUFFLG9CQUFvQjtLQUMxQixDQUFDLENBQUM7QUFDTCxDQUFDO0FBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXFCRztBQUNILE1BQU0sQ0FBQyxNQUFNLGlCQUFpQixHQUFHLE9BQU8sQ0FBQztBQUV6QywyREFBMkQ7QUFDM0QsTUFBTSxDQUFDLE1BQU0scUJBQXFCLEdBQUcsTUFBTSxDQUFDO0FBRTVDOzs7O0dBSUc7QUFDSCxNQUFNLENBQUMsTUFBTSxxQkFBcUIsR0FBRyxPQUFPLENBQUM7QUFFN0MsMkVBQTJFO0FBQzNFLDJFQUEyRTtBQUMzRSxNQUFNLHlCQUF5QixHQUFHLElBQUksR0FBRyxFQUFVLENBQUM7QUFFcEQsU0FBUyxRQUFRLENBQ2YsR0FBVyxFQUNYLE9BQWUsRUFDZixJQUE2QjtJQUU3QixJQUFJLHlCQUF5QixDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUM7UUFBRSxPQUFPO0lBQy9DLHlCQUF5QixDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUNuQyxhQUFhLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsQ0FBQztBQUNwQyxDQUFDO0FBRUQ7Ozs7Ozs7O0dBUUc7QUFDSCxNQUFNLFVBQVUsa0JBQWtCO0lBQ2hDLE1BQU0sR0FBRyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsMEJBQTBCLENBQUM7SUFDbkQsSUFBSSxDQUFDLEdBQUc7UUFBRSxPQUFPLGlCQUFpQixDQUFDO0lBQ25DLE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUMzQixJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsSUFBSSxNQUFNLElBQUksQ0FBQyxFQUFFLENBQUM7UUFDNUMsUUFBUSxDQUNOLEdBQUcsRUFDSCxrRkFBa0YsRUFDbEYsRUFBRSxHQUFHLEVBQUUsU0FBUyxFQUFFLGlCQUFpQixFQUFFLENBQ3RDLENBQUM7UUFDRixPQUFPLGlCQUFpQixDQUFDO0lBQzNCLENBQUM7SUFDRCxJQUFJLE1BQU0sR0FBRyxxQkFBcUIsRUFBRSxDQUFDO1FBQ25DLFFBQVEsQ0FBQyxHQUFHLEVBQUUsbURBQW1ELEVBQUU7WUFDakUsR0FBRztZQUNILFNBQVMsRUFBRSxxQkFBcUI7WUFDaEMsS0FBSyxFQUFFLHFCQUFxQjtTQUM3QixDQUFDLENBQUM7UUFDSCxPQUFPLHFCQUFxQixDQUFDO0lBQy9CLENBQUM7SUFDRCxJQUFJLE1BQU0sR0FBRyxxQkFBcUIsRUFBRSxDQUFDO1FBQ25DLFFBQVEsQ0FBQyxHQUFHLEVBQUUsbURBQW1ELEVBQUU7WUFDakUsR0FBRztZQUNILFNBQVMsRUFBRSxxQkFBcUI7WUFDaEMsS0FBSyxFQUFFLHFCQUFxQjtTQUM3QixDQUFDLENBQUM7UUFDSCxPQUFPLHFCQUFxQixDQUFDO0lBQy9CLENBQUM7SUFDRCxPQUFPLE1BQU0sQ0FBQztBQUNoQixDQUFDO0FBRUQ7Ozs7O0dBS0c7QUFDSCxNQUFNLFVBQVUsb0NBQW9DO0lBQ2xELHlCQUF5QixDQUFDLEtBQUssRUFBRSxDQUFDO0FBQ3BDLENBQUM7QUFFRCw4RUFBOEU7QUFDOUUseUVBQXlFO0FBQ3pFLCtFQUErRTtBQUMvRSxtREFBbUQ7QUFDbkQsTUFBTSxDQUFDLE1BQU0sMEJBQTBCLEdBQUcsQ0FBQyxDQUFDO0FBRTVDOzs7R0FHRztBQUNILE1BQU0sVUFBVSwwQkFBMEI7SUFDeEMsT0FBTyxTQUFTLENBQ2QscUNBQXFDLEVBQ3JDLDBCQUEwQixFQUMxQixFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsQ0FDbEIsQ0FBQztBQUNKLENBQUM7QUFFRDs7Ozs7Ozs7OztHQVVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sZ0JBQWdCLEdBQUcsQ0FBQyxDQUFDO0FBRWxDLDhFQUE4RTtBQUM5RSxNQUFNLENBQUMsTUFBTSxvQkFBb0IsR0FBRyxDQUFDLENBQUM7QUFFdEM7OztHQUdHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sb0JBQW9CLEdBQUcsRUFBRSxDQUFDO0FBRXZDLHlFQUF5RTtBQUN6RSxNQUFNLDBCQUEwQixHQUFHLElBQUksR0FBRyxFQUFVLENBQUM7QUFFckQ7Ozs7Ozs7R0FPRztBQUNILE1BQU0sVUFBVSxpQkFBaUI7SUFDL0IsTUFBTSxHQUFHLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyx5QkFBeUIsQ0FBQztJQUNsRCxJQUFJLENBQUMsR0FBRztRQUFFLE9BQU8sZ0JBQWdCLENBQUM7SUFDbEMsTUFBTSxNQUFNLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQzNCLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxJQUFJLE1BQU0sSUFBSSxDQUFDLEVBQUUsQ0FBQztRQUM3QyxJQUFJLENBQUMsMEJBQTBCLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDekMsMEJBQTBCLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ3BDLGFBQWEsQ0FBQyxJQUFJLENBQ2hCLDJFQUEyRSxFQUMzRSxFQUFFLEdBQUcsRUFBRSxZQUFZLEVBQUUsZ0JBQWdCLEVBQUUsQ0FDeEMsQ0FBQztRQUNKLENBQUM7UUFDRCxPQUFPLGdCQUFnQixDQUFDO0lBQzFCLENBQUM7SUFDRCxJQUFJLE1BQU0sR0FBRyxvQkFBb0I7UUFBRSxPQUFPLG9CQUFvQixDQUFDO0lBQy9ELElBQUksTUFBTSxHQUFHLG9CQUFvQixFQUFFLENBQUM7UUFDbEMsSUFBSSxDQUFDLDBCQUEwQixDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQ3pDLDBCQUEwQixDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUNwQyxhQUFhLENBQUMsSUFBSSxDQUFDLGtEQUFrRCxFQUFFO2dCQUNyRSxHQUFHO2dCQUNILFlBQVksRUFBRSxvQkFBb0I7Z0JBQ2xDLFFBQVEsRUFBRSxvQkFBb0I7YUFDL0IsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztRQUNELE9BQU8sb0JBQW9CLENBQUM7SUFDOUIsQ0FBQztJQUNELE9BQU8sTUFBTSxDQUFDO0FBQ2hCLENBQUM7QUFFRDs7Ozs7Ozs7Ozs7Ozs7R0FjRztBQUNILE1BQU0sQ0FBQyxNQUFNLDhCQUE4QixHQUFHLEdBQUcsR0FBRyxJQUFJLENBQUM7QUFFekQ7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBaUJHO0FBQ0gsTUFBTSxVQUFVLDhCQUE4QjtJQUM1QyxPQUFPLE9BQU8sQ0FBQyxHQUFHLENBQUMsZ0NBQWdDLEtBQUssR0FBRyxDQUFDO0FBQzlELENBQUM7QUFFRDs7Ozs7Ozs7Ozs7Ozs7R0FjRztBQUNILE1BQU0sVUFBVSx5QkFBeUI7SUFDdkMsTUFBTSxHQUFHLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQywwQkFBMEIsQ0FBQztJQUNuRCxJQUFJLEdBQUcsS0FBSyxTQUFTLElBQUksR0FBRyxLQUFLLEVBQUU7UUFBRSxPQUFPLElBQUksQ0FBQztJQUNqRCxPQUFPLENBQUMsQ0FBQyxHQUFHLEtBQUssR0FBRyxJQUFJLEdBQUcsQ0FBQyxXQUFXLEVBQUUsS0FBSyxPQUFPLENBQUMsQ0FBQztBQUN6RCxDQUFDO0FBRUQ7Ozs7Ozs7OztHQVNHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sdUJBQXVCLEdBQUcsRUFBRSxDQUFDO0FBRTFDLE1BQU0scUJBQXFCLEdBQUcsSUFBSSxHQUFHLEVBQVUsQ0FBQztBQUVoRDs7Ozs7Ozs7O0dBU0c7QUFDSCxNQUFNLFVBQVUsb0JBQW9CO0lBQ2xDLE1BQU0sR0FBRyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsNEJBQTRCLENBQUM7SUFDckQsSUFBSSxDQUFDLEdBQUc7UUFBRSxPQUFPLFNBQVMsQ0FBQztJQUMzQixNQUFNLE1BQU0sR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDM0IsSUFBSSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLElBQUksTUFBTSxJQUFJLENBQUMsRUFBRSxDQUFDO1FBQzdDLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUNwQyxxQkFBcUIsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDL0IsYUFBYSxDQUFDLElBQUksQ0FDaEIsbUZBQW1GLEVBQ25GLEVBQUUsR0FBRyxFQUFFLENBQ1IsQ0FBQztRQUNKLENBQUM7UUFDRCxPQUFPLFNBQVMsQ0FBQztJQUNuQixDQUFDO0lBQ0QsT0FBTyxNQUFNLENBQUM7QUFDaEIsQ0FBQztBQUVEOzs7Ozs7Ozs7Ozs7Ozs7R0FlRztBQUNILE1BQU0sVUFBVSw4QkFBOEI7SUFDNUMsTUFBTSxHQUFHLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxnQ0FBZ0MsQ0FBQztJQUN6RCxJQUFJLEdBQUcsS0FBSyxTQUFTLElBQUksR0FBRyxLQUFLLEVBQUU7UUFBRSxPQUFPLEtBQUssQ0FBQztJQUNsRCxPQUFPLEdBQUcsS0FBSyxHQUFHLElBQUksR0FBRyxDQUFDLFdBQVcsRUFBRSxLQUFLLE1BQU0sQ0FBQztBQUNyRCxDQUFDO0FBRUQ7Ozs7Ozs7O0dBUUc7QUFDSCxNQUFNLFVBQVUseUNBQXlDO0lBQ3ZELE1BQU0sR0FBRyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsZ0NBQWdDLENBQUM7SUFDekQsSUFBSSxHQUFHLEtBQUssU0FBUyxJQUFJLEdBQUcsS0FBSyxFQUFFO1FBQUUsT0FBTyxLQUFLLENBQUM7SUFDbEQsT0FBTyxHQUFHLEtBQUssR0FBRyxJQUFJLEdBQUcsQ0FBQyxXQUFXLEVBQUUsS0FBSyxPQUFPLENBQUM7QUFDdEQsQ0FBQztBQUVEOzs7Ozs7Ozs7Ozs7Ozs7O0dBZ0JHO0FBQ0gsTUFBTSxVQUFVLGNBQWM7SUFDNUIsTUFBTSxHQUFHLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxjQUFjLENBQUM7SUFDdkMsSUFBSSxHQUFHLEtBQUssU0FBUyxJQUFJLEdBQUcsS0FBSyxFQUFFO1FBQUUsT0FBTyxJQUFJLENBQUM7SUFDakQsT0FBTyxDQUFDLENBQUMsR0FBRyxLQUFLLEdBQUcsSUFBSSxHQUFHLENBQUMsV0FBVyxFQUFFLEtBQUssT0FBTyxDQUFDLENBQUM7QUFDekQsQ0FBQztBQUVEOzs7Ozs7Ozs7Ozs7R0FZRztBQUNILE1BQU0sVUFBVSxnQ0FBZ0M7SUFDOUMsTUFBTSxHQUFHLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxrQ0FBa0MsQ0FBQztJQUMzRCxJQUFJLEdBQUcsS0FBSyxTQUFTLElBQUksR0FBRyxLQUFLLEVBQUU7UUFBRSxPQUFPLElBQUksQ0FBQztJQUNqRCxPQUFPLENBQUMsQ0FBQyxHQUFHLEtBQUssR0FBRyxJQUFJLEdBQUcsQ0FBQyxXQUFXLEVBQUUsS0FBSyxPQUFPLENBQUMsQ0FBQztBQUN6RCxDQUFDO0FBRUQ7Ozs7Ozs7Ozs7R0FVRztBQUNILE1BQU0sVUFBVSxvQkFBb0I7SUFDbEMsTUFBTSxHQUFHLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxvQkFBb0IsQ0FBQztJQUM3QyxJQUFJLEdBQUcsS0FBSyxTQUFTLElBQUksR0FBRyxLQUFLLEVBQUU7UUFBRSxPQUFPLElBQUksQ0FBQztJQUNqRCxPQUFPLENBQUMsQ0FBQyxHQUFHLEtBQUssR0FBRyxJQUFJLEdBQUcsQ0FBQyxXQUFXLEVBQUUsS0FBSyxPQUFPLENBQUMsQ0FBQztBQUN6RCxDQUFDO0FBRUQ7Ozs7Ozs7Ozs7O0dBV0c7QUFDSCxNQUFNLFVBQVUsd0JBQXdCO0lBQ3RDLE1BQU0sR0FBRyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMseUJBQXlCLENBQUM7SUFDbEQsSUFBSSxHQUFHLEtBQUssU0FBUyxJQUFJLEdBQUcsS0FBSyxFQUFFO1FBQUUsT0FBTyxJQUFJLENBQUM7SUFDakQsT0FBTyxDQUFDLENBQUMsR0FBRyxLQUFLLEdBQUcsSUFBSSxHQUFHLENBQUMsV0FBVyxFQUFFLEtBQUssT0FBTyxDQUFDLENBQUM7QUFDekQsQ0FBQztBQUVEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQTBCRztBQUNILE1BQU0sQ0FBQyxNQUFNLDhCQUE4QixHQUFHLEdBQUcsQ0FBQztBQUVsRDs7OztHQUlHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sa0NBQWtDLEdBQUcsR0FBRyxDQUFDO0FBRXREOzs7OztHQUtHO0FBQ0gsTUFBTSxVQUFVLDhCQUE4QjtJQUM1QyxPQUFPLFNBQVMsQ0FDZCx5Q0FBeUMsRUFDekMsOEJBQThCLEVBQzlCLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxrQ0FBa0MsRUFBRSxDQUNuRSxDQUFDO0FBQ0osQ0FBQztBQUVELDJFQUEyRTtBQUMzRSwyRUFBMkU7QUFDM0UscUVBQXFFO0FBQ3JFLE1BQU0sQ0FBQyxNQUFNLDZCQUE2QixHQUFHLENBQUMsQ0FBQztBQUUvQzs7O0dBR0c7QUFDSCxNQUFNLFVBQVUsNkJBQTZCO0lBQzNDLE9BQU8sU0FBUyxDQUNkLHdDQUF3QyxFQUN4Qyw2QkFBNkIsRUFDN0IsRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLENBQ2xCLENBQUM7QUFDSixDQUFDO0FBRUQsK0VBQStFO0FBQy9FLDJFQUEyRTtBQUMzRSwyRUFBMkU7QUFDM0UsZ0ZBQWdGO0FBQ2hGLGdGQUFnRjtBQUNoRix1Q0FBdUM7QUFDdkMsTUFBTSxDQUFDLE1BQU0sbUNBQW1DLEdBQUcsQ0FBQyxDQUFDO0FBRXJEOzs7R0FHRztBQUNILE1BQU0sVUFBVSxtQ0FBbUM7SUFDakQsT0FBTyxTQUFTLENBQ2QsOENBQThDLEVBQzlDLG1DQUFtQyxFQUNuQyxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsQ0FDbEIsQ0FBQztBQUNKLENBQUM7QUFFRCwwRUFBMEU7QUFDMUUsZ0ZBQWdGO0FBQ2hGLDZFQUE2RTtBQUM3RSwrRUFBK0U7QUFDL0UsNEVBQTRFO0FBQzVFLG9FQUFvRTtBQUNwRSwrREFBK0Q7QUFDL0QsTUFBTSxDQUFDLE1BQU0sOEJBQThCLEdBQUcsQ0FBQyxDQUFDO0FBRWhEOzs7R0FHRztBQUNILE1BQU0sVUFBVSwrQkFBK0I7SUFDN0MsT0FBTyxTQUFTLENBQ2QseUNBQXlDLEVBQ3pDLDhCQUE4QixFQUM5QixFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsQ0FDbEIsQ0FBQztBQUNKLENBQUM7QUFFRCw2RUFBNkU7QUFDN0UsNEVBQTRFO0FBQzVFLCtFQUErRTtBQUMvRSwyRUFBMkU7QUFDM0UsTUFBTSxDQUFDLE1BQU0sbUNBQW1DLEdBQUcsQ0FBQyxDQUFDO0FBRXJEOzs7R0FHRztBQUNILE1BQU0sVUFBVSxtQ0FBbUM7SUFDakQsT0FBTyxTQUFTLENBQ2QsOENBQThDLEVBQzlDLG1DQUFtQyxFQUNuQyxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsQ0FDbEIsQ0FBQztBQUNKLENBQUM7QUFFRCw4RUFBOEU7QUFDOUUsK0VBQStFO0FBQy9FLDREQUE0RDtBQUM1RCxNQUFNLENBQUMsTUFBTSwrQkFBK0IsR0FBRyxDQUFDLENBQUM7QUFFakQ7Ozs7R0FJRztBQUNILE1BQU0sVUFBVSwrQkFBK0I7SUFDN0MsT0FBTyxTQUFTLENBQ2QsMENBQTBDLEVBQzFDLCtCQUErQixFQUMvQixFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUMxQixDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGVudk51bWJlciB9IGZyb20gJ0B3b3JrZmxvdy93b3JsZCc7XG5pbXBvcnQgeyBydW50aW1lTG9nZ2VyIH0gZnJvbSAnLi4vbG9nZ2VyLmpzJztcblxuLy8gTWF4aW11bSBudW1iZXIgb2YgcXVldWUgZGVsaXZlcnkgYXR0ZW1wdHMgYmVmb3JlIHRoZSBoYW5kbGVyIGdpdmVzIHVwIGFuZFxuLy8gZ3JhY2VmdWxseSBmYWlscyB0aGUgcnVuL3N0ZXAuIFRoaXMgbXVzdCBiZSBib3VuZGVkIHVuZGVyIHRoZSBWUVMgbWVzc2FnZVxuLy8gbWF4IHZpc2liaWxpdHkgd2luZG93ICgyNCBob3Vycykgc28gdGhhdCBvdXIgaGFuZGxlci1zaWRlIGZhaWx1cmUgcGF0aFxuLy8gcmVsaWFibHkgZXhlY3V0ZXMgYmVmb3JlIFZRUyBleHBpcmVzIHRoZSBtZXNzYWdlLlxuLy9cbi8vIFRoZSBlZmZlY3RpdmUgd2FsbC1jbG9jayBzdXJ2aXZhbCBkZXBlbmRzIG9uIHRoZSBwZXItcmVkZWxpdmVyeSBiYWNrb2ZmOiB0aGVcbi8vIGByZXRyeS1hZnRlcmAgdGhlIGhhbmRsZXIgcmV0dXJucyAoc2VlIHdvcmxkLXZlcmNlbFxuLy8gYGdldEhhbmRsZXJFcnJvclJldHJ5QWZ0ZXJTZWNvbmRzYCkgZmVkIHRocm91Z2ggVlFTIGBjYWxjdWxhdGVCYWNrb2ZmRGVsYXlgLlxuLy8gVlFTIHVzZXMgb3VyIHZhbHVlIGZvciB0aGUgZmlyc3QgMzIgYXR0ZW1wdHMgKGNsYW1wZWQgdG8gWzVzLCA5MDBzXSkgdGhlblxuLy8gYXBwbGllcyBpdHMgb3duIGV4cG9uZW50aWFsIGdyb3d0aCDigJQgZXZlcnkgaG9wIGhhcmQtY2FwcGVkIGF0IHRoZSBTUVMgbGltaXRcbi8vIG9mIDkwMHMuIFdpdGggdGhlIGJhY2tvZmYgcmFtcGluZyB0b3dhcmQgdGhhdCA5MDBzIGNlaWxpbmcgKHJlYWNoZWQgYnlcbi8vIH5kZWxpdmVyeSAxMSksIDQ4IGF0dGVtcHRzIHNwYW4gcm91Z2hseSA54oCTMTAgaG91cnMgb2Ygd2FsbC1jbG9jayAofjM1LDAwMHMpLFxuLy8gY29tZm9ydGFibHkgdW5kZXIgdGhlIDI0LWhvdXIgbWVzc2FnZS12aXNpYmlsaXR5IGxpbWl0IHNvIHRoZSBmYWlsdXJlIHBhdGhcbi8vIHJ1bnMgYmVmb3JlIHRoZSBtZXNzYWdlIGV4cGlyZXMuIChBIGZsYXR0ZXIsIGxvdy1jYXBwZWQgYmFja29mZiBleGhhdXN0cyB0aGVcbi8vIGJ1ZGdldCBpbiBvbmx5IGEgZmV3IGhvdXJzLCBmYWlsaW5nIG90aGVyd2lzZS1oZWFsdGh5IHJ1bnMgZHVyaW5nIGEgdHJhbnNpZW50XG4vLyBiYWNrZW5kIG91dGFnZTsgY29udmVyc2VseSwgc3Bhbm5pbmcgdGhlIGZ1bGwgMjRoIHdpbmRvdyB3b3VsZCByZXF1aXJlIGFcbi8vIHN1YnN0YW50aWFsbHkgaGlnaGVyIGNhcCBoZXJlLCBub3QgYSBoaWdoZXIgcGVyLWhvcCBjZWlsaW5nIOKAlCBWUVMgY2xhbXBzXG4vLyBldmVyeSBob3AgYXQgOTAwcy4pXG5leHBvcnQgY29uc3QgTUFYX1FVRVVFX0RFTElWRVJJRVMgPSA0ODtcblxuLyoqXG4gKiBFZmZlY3RpdmUgbWF4IHF1ZXVlIGRlbGl2ZXJpZXMuIE92ZXJyaWRlIHZpYSBgV09SS0ZMT1dfTUFYX1FVRVVFX0RFTElWRVJJRVNgLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0TWF4UXVldWVEZWxpdmVyaWVzKCk6IG51bWJlciB7XG4gIC8vIE9ubHkgZXZlciBsb3dlciB0aGUgZGVsaXZlcnkgYnVkZ2V0LiBUaGUgZGVmYXVsdCBpcyBjYWxpYnJhdGVkIHNvIHRoZVxuICAvLyBoYW5kbGVyLXNpZGUgZmFpbHVyZSBwYXRoIHJ1bnMgYmVmb3JlIFZRUyBtZXNzYWdlLXJldGVudGlvbiBleHBpcnkgKHNlZVxuICAvLyBNQVhfUVVFVUVfREVMSVZFUklFUyBhYm92ZSk7IGEgaGlnaGVyIHZhbHVlIHdvdWxkIGJ5cGFzcyB0aGF0IGludmFyaWFudCBhbmRcbiAgLy8gbGV0IGEgYmFkIGRlcGxveW1lbnQgcmVkZWxpdmVyIHVudGlsIHF1ZXVlIGV4cGlyeSBpbnN0ZWFkIG9mIHJlY29yZGluZ1xuICAvLyBydW5fZmFpbC4gYG1heGAgY2xhbXBzIGEgdG9vLWhpZ2ggb3ZlcnJpZGUgYmFjayBkb3duIHRvIHRoZSBzYWZlIGRlZmF1bHQuXG4gIHJldHVybiBlbnZOdW1iZXIoJ1dPUktGTE9XX01BWF9RVUVVRV9ERUxJVkVSSUVTJywgTUFYX1FVRVVFX0RFTElWRVJJRVMsIHtcbiAgICBpbnRlZ2VyOiB0cnVlLFxuICAgIG1pbjogMSxcbiAgICBtYXg6IE1BWF9RVUVVRV9ERUxJVkVSSUVTLFxuICB9KTtcbn1cblxuLyoqXG4gKiBEZWZhdWx0IG1heGltdW0gdGltZSBhbGxvd2VkIGZvciB0aGUgKnJlcGxheSogcG9ydGlvbiBvZiBhIHNpbmdsZSB3b3JrZmxvd1xuICogaGFuZGxlciBpbnZvY2F0aW9uIChpbiBtcykuIFRoaXMgYnVkZ2V0IG9ubHkgY292ZXJzIGRldGVybWluaXN0aWMtcmVwbGF5XG4gKiBhbmQgd29ya2Zsb3ctVk0gZXhlY3V0aW9uIGJldHdlZW4gc3RlcCBib3VuZGFyaWVzIOKAlCBpbmxpbmUgc3RlcCBib2RpZXNcbiAqIChgXCJ1c2Ugc3RlcFwiYCBmdW5jdGlvbnMgaW52b2tlZCB2aWEgYGV4ZWN1dGVTdGVwYCkgZG8gTk9UIGNvdW50IGFnYWluc3RcbiAqIGl0LiBTdGVwIGJvZGllcyBhcmUgYm91bmRlZCBzZXBhcmF0ZWx5IGJ5IHRoZSBwbGF0Zm9ybSdzIGZ1bmN0aW9uXG4gKiBgbWF4RHVyYXRpb25gIChlLmcuIDgwMHMgb24gVmVyY2VsIFBybyBGbHVpZCkgYW5kIGBOT19JTkxJTkVfUkVQTEFZX0FGVEVSX01TYC5cbiAqXG4gKiBJZiB0aGUgbm9uLXN0ZXAgKFwicmVwbGF5XCIpIHRpbWUgd2l0aGluIGEgc2luZ2xlIGludm9jYXRpb24gZXhjZWVkcyB0aGlzXG4gKiBidWRnZXQsIHRoZSBoYW5kbGVyIHJlamVjdHMgc28gdGhlIHF1ZXVlIGNhbiByZXRyeS4gQWZ0ZXJcbiAqIGBSRVBMQVlfVElNRU9VVF9NQVhfUkVUUklFU2AgZXhoYXVzdGVkIGF0dGVtcHRzIHRoZSBydW4gaXMgZmFpbGVkIHdpdGhcbiAqIGBSVU5fRVJST1JfQ09ERVMuUkVQTEFZX1RJTUVPVVRgLlxuICpcbiAqIE5vdGUgdGhhdCBvbiBWZXJjZWwgSG9iYnkgKHN0YW5kYXJkIGZ1bmN0aW9ucyksIHRoZSBwbGF0Zm9ybSBgbWF4RHVyYXRpb25gXG4gKiBpcyA2MHMg4oCUIHdlbGwgYmVsb3cgdGhpcyBidWRnZXQsIHNvIHRoZSBwbGF0Zm9ybSBTSUdURVJNIHdpbGwgZmlyZSBmaXJzdFxuICogYW5kIHRoZSBxdWV1ZSB3aWxsIHJlLWRlbGl2ZXIgdW50aWwgdGhlIHZpc2liaWxpdHkgd2luZG93IGV4cGlyZXMuIFdpdGhcbiAqIEZsdWlkIENvbXB1dGUgb24gSG9iYnkgdGhlIHBlci1mdW5jdGlvbiBjZWlsaW5nIHJpc2VzIHRvIDMwMHMsIHN0aWxsXG4gKiB1bmRlciB0aGUgZGVmYXVsdCBidWRnZXQuXG4gKlxuICogT3ZlcnJpZGUgdmlhIHRoZSBgV09SS0ZMT1dfUkVQTEFZX1RJTUVPVVRfTVNgIGVudiB2YXIgKGNsYW1wZWQgdG9cbiAqIGBNSU5fUkVQTEFZX1RJTUVPVVRfTVNgLi5gTUFYX1JFUExBWV9USU1FT1VUX01TYCkuXG4gKi9cbmV4cG9ydCBjb25zdCBSRVBMQVlfVElNRU9VVF9NUyA9IDI0MF8wMDA7XG5cbi8qKiBMb3dlciBib3VuZCBmb3IgdGhlIHJlcGxheS10aW1lb3V0IGVudiB2YXIgb3ZlcnJpZGUuICovXG5leHBvcnQgY29uc3QgTUlOX1JFUExBWV9USU1FT1VUX01TID0gMzBfMDAwO1xuXG4vKipcbiAqIFVwcGVyIGJvdW5kIGZvciB0aGUgcmVwbGF5LXRpbWVvdXQgZW52IHZhciBvdmVycmlkZS4gNzgwcyBsZWF2ZXMg4omlMjBzIG9mXG4gKiBoZWFkcm9vbSB1bmRlciBWZXJjZWwgUHJvIEZsdWlkJ3MgODAwcyBmdW5jdGlvbiBjZWlsaW5nIHNvIHRoZSBoYW5kbGVyXG4gKiBjYW4gd3JpdGUgYHJ1bl9mYWlsZWRgIGJlZm9yZSBTSUdURVJNLlxuICovXG5leHBvcnQgY29uc3QgTUFYX1JFUExBWV9USU1FT1VUX01TID0gNzgwXzAwMDtcblxuLy8gVHJhY2sgd2hpY2ggcmF3IGVudiB2YXIgdmFsdWVzIHdlJ3ZlIGFscmVhZHkgd2FybmVkIGFib3V0IHNvIHRoZSB3YXJuaW5nXG4vLyBsb2cgb25seSBmaXJlcyBvbmNlIHBlciBwcm9jZXNzICh0aGUgZnVuY3Rpb24gbWF5IGJlIGNhbGxlZCBtYW55IHRpbWVzKS5cbmNvbnN0IHdhcm5lZFJlcGxheVRpbWVvdXRWYWx1ZXMgPSBuZXcgU2V0PHN0cmluZz4oKTtcblxuZnVuY3Rpb24gd2Fybk9uY2UoXG4gIHJhdzogc3RyaW5nLFxuICBtZXNzYWdlOiBzdHJpbmcsXG4gIGRhdGE6IFJlY29yZDxzdHJpbmcsIHVua25vd24+XG4pOiB2b2lkIHtcbiAgaWYgKHdhcm5lZFJlcGxheVRpbWVvdXRWYWx1ZXMuaGFzKHJhdykpIHJldHVybjtcbiAgd2FybmVkUmVwbGF5VGltZW91dFZhbHVlcy5hZGQocmF3KTtcbiAgcnVudGltZUxvZ2dlci53YXJuKG1lc3NhZ2UsIGRhdGEpO1xufVxuXG4vKipcbiAqIFJlc29sdmUgdGhlIGVmZmVjdGl2ZSByZXBsYXktdGltZW91dCBidWRnZXQgZm9yIHRoZSBjdXJyZW50IHByb2Nlc3MuXG4gKlxuICogUmVhZHMgYHByb2Nlc3MuZW52LldPUktGTE9XX1JFUExBWV9USU1FT1VUX01TYCBsYXppbHkgc28gdGVzdHMgYW5kXG4gKiBkZXBsb3ltZW50cyBjYW4gb3ZlcnJpZGUgcGVyIGludm9jYXRpb24uIEludmFsaWQgLyBvdXQtb2YtcmFuZ2UgdmFsdWVzXG4gKiBmYWxsIGJhY2sgdG8gYSBzYWZlIHZhbHVlIChubyB0aHJvdyDigJQgdGhlIGVudiB2YXIgaXMgYW4gZXNjYXBlIGhhdGNoLFxuICogbm90IGEgaGFyZCByZXF1aXJlbWVudCkgYW5kIGVtaXQgYSBvbmUtdGltZSB3YXJuaW5nIHNvIG1pc2NvbmZpZ3VyYXRpb25cbiAqIGlzIG9ic2VydmFibGUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRSZXBsYXlUaW1lb3V0TXMoKTogbnVtYmVyIHtcbiAgY29uc3QgcmF3ID0gcHJvY2Vzcy5lbnYuV09SS0ZMT1dfUkVQTEFZX1RJTUVPVVRfTVM7XG4gIGlmICghcmF3KSByZXR1cm4gUkVQTEFZX1RJTUVPVVRfTVM7XG4gIGNvbnN0IHBhcnNlZCA9IE51bWJlcihyYXcpO1xuICBpZiAoIU51bWJlci5pc0Zpbml0ZShwYXJzZWQpIHx8IHBhcnNlZCA8PSAwKSB7XG4gICAgd2Fybk9uY2UoXG4gICAgICByYXcsXG4gICAgICAnSWdub3JpbmcgV09SS0ZMT1dfUkVQTEFZX1RJTUVPVVRfTVM6IG5vdCBhIHBvc2l0aXZlIGZpbml0ZSBudW1iZXI7IHVzaW5nIGRlZmF1bHQnLFxuICAgICAgeyByYXcsIGRlZmF1bHRNczogUkVQTEFZX1RJTUVPVVRfTVMgfVxuICAgICk7XG4gICAgcmV0dXJuIFJFUExBWV9USU1FT1VUX01TO1xuICB9XG4gIGlmIChwYXJzZWQgPCBNSU5fUkVQTEFZX1RJTUVPVVRfTVMpIHtcbiAgICB3YXJuT25jZShyYXcsICdXT1JLRkxPV19SRVBMQVlfVElNRU9VVF9NUyBiZWxvdyBtaW5pbXVtOyBjbGFtcGVkJywge1xuICAgICAgcmF3LFxuICAgICAgY2xhbXBlZE1zOiBNSU5fUkVQTEFZX1RJTUVPVVRfTVMsXG4gICAgICBtaW5NczogTUlOX1JFUExBWV9USU1FT1VUX01TLFxuICAgIH0pO1xuICAgIHJldHVybiBNSU5fUkVQTEFZX1RJTUVPVVRfTVM7XG4gIH1cbiAgaWYgKHBhcnNlZCA+IE1BWF9SRVBMQVlfVElNRU9VVF9NUykge1xuICAgIHdhcm5PbmNlKHJhdywgJ1dPUktGTE9XX1JFUExBWV9USU1FT1VUX01TIGFib3ZlIG1heGltdW07IGNsYW1wZWQnLCB7XG4gICAgICByYXcsXG4gICAgICBjbGFtcGVkTXM6IE1BWF9SRVBMQVlfVElNRU9VVF9NUyxcbiAgICAgIG1heE1zOiBNQVhfUkVQTEFZX1RJTUVPVVRfTVMsXG4gICAgfSk7XG4gICAgcmV0dXJuIE1BWF9SRVBMQVlfVElNRU9VVF9NUztcbiAgfVxuICByZXR1cm4gcGFyc2VkO1xufVxuXG4vKipcbiAqIFJlc2V0IHRoZSB3YXJuLW9uY2UgY2FjaGUuIFRlc3Qtb25seSDigJQgZXhwb3J0ZWQgc28gdW5pdCB0ZXN0cyBjYW5cbiAqIGV4ZXJjaXNlIHRoZSB3YXJuIHBhdGggcmVwZWF0ZWRseSB3aXRob3V0IHNoYXJpbmcgc3RhdGUuXG4gKlxuICogQGludGVybmFsXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBfcmVzZXRSZXBsYXlUaW1lb3V0V2FybkNhY2hlRm9yVGVzdHMoKTogdm9pZCB7XG4gIHdhcm5lZFJlcGxheVRpbWVvdXRWYWx1ZXMuY2xlYXIoKTtcbn1cblxuLy8gTnVtYmVyIG9mIHF1ZXVlIGRlbGl2ZXJ5IGF0dGVtcHRzIHRvIGFsbG93IGJlZm9yZSBwZXJtYW5lbnRseSBmYWlsaW5nIGEgcnVuXG4vLyBkdWUgdG8gYSByZXBsYXkgdGltZW91dC4gT24gYXR0ZW1wdHMgMSB0aHJvdWdoIHRoaXMgdmFsdWUsIHRoZSB0aW1lb3V0XG4vLyBoYW5kbGVyIHJlamVjdHMgd2l0aG91dCB3cml0aW5nIHJ1bl9mYWlsZWQgc28gdGhlIHF1ZXVlIHJldHJpZXMgdGhlIG1lc3NhZ2UuXG4vLyBPbiB0aGUgbmV4dCBhdHRlbXB0IHRoZSBydW4gaXMgbWFya2VkIGFzIGZhaWxlZC5cbmV4cG9ydCBjb25zdCBSRVBMQVlfVElNRU9VVF9NQVhfUkVUUklFUyA9IDM7XG5cbi8qKlxuICogRWZmZWN0aXZlIHJlcGxheS10aW1lb3V0IHJldHJ5IGJ1ZGdldC4gT3ZlcnJpZGUgdmlhXG4gKiBgV09SS0ZMT1dfUkVQTEFZX1RJTUVPVVRfTUFYX1JFVFJJRVNgLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0UmVwbGF5VGltZW91dE1heFJldHJpZXMoKTogbnVtYmVyIHtcbiAgcmV0dXJuIGVudk51bWJlcihcbiAgICAnV09SS0ZMT1dfUkVQTEFZX1RJTUVPVVRfTUFYX1JFVFJJRVMnLFxuICAgIFJFUExBWV9USU1FT1VUX01BWF9SRVRSSUVTLFxuICAgIHsgaW50ZWdlcjogdHJ1ZSB9XG4gICk7XG59XG5cbi8qKlxuICogRGVmYXVsdCBtYXhpbXVtIG51bWJlciBvZiBzdGVwcyB0aGUgb3duZWQtaW5saW5lIHBhdGggcnVucyBpbmxpbmUgKGluXG4gKiBwYXJhbGxlbCkgcGVyIHN1c3BlbnNpb24uIFRoZSByZXN0IGFyZSBxdWV1ZWQgdG8gYmFja2dyb3VuZCBoYW5kbGVycy4gRWFjaFxuICogaW5saW5lIHN0ZXAgaXMgY3JlYXRlZCBsYXppbHkg4oCUIGl0cyBgc3RlcF9jcmVhdGVkYCBpcyBmb2xkZWQgaW50byB0aGVcbiAqIGBzdGVwX3N0YXJ0ZWRgIHRoYXQgYGV4ZWN1dGVTdGVwYCBzZW5kcyDigJQgc28gaW5saW5pbmcgTiBzdGVwcyBzYXZlcyBOIHF1ZXVlXG4gKiByb3VuZC10cmlwcyBmb3IgYSBgUHJvbWlzZS5hbGxgLXN0eWxlIGZhbi1vdXQuIGAxYCByZXByb2R1Y2VzIHRoZVxuICogc2luZ2xlLWlubGluZS1zdGVwIGJlaGF2aW9yIGV4YWN0bHkgKHVzZWZ1bCBraWxsLXN3aXRjaCkuXG4gKlxuICogT3ZlcnJpZGUgdmlhIGBXT1JLRkxPV19NQVhfSU5MSU5FX1NURVBTYCAoY2xhbXBlZCB0b1xuICogYE1JTl9NQVhfSU5MSU5FX1NURVBTYC4uYE1BWF9NQVhfSU5MSU5FX1NURVBTYCkuXG4gKi9cbmV4cG9ydCBjb25zdCBNQVhfSU5MSU5FX1NURVBTID0gMztcblxuLyoqIExvd2VyIGJvdW5kIGZvciB0aGUgaW5saW5lLXN0ZXBzIGVudiBvdmVycmlkZSAoMSA9IHNpbmdsZSBpbmxpbmUgc3RlcCkuICovXG5leHBvcnQgY29uc3QgTUlOX01BWF9JTkxJTkVfU1RFUFMgPSAxO1xuXG4vKipcbiAqIFVwcGVyIGJvdW5kIGZvciB0aGUgaW5saW5lLXN0ZXBzIGVudiBvdmVycmlkZS4gSW5saW5lIGJvZGllcyBydW4gaW4gcGFyYWxsZWxcbiAqIHdpdGhpbiBvbmUgZnVuY3Rpb24gaW52b2NhdGlvbiwgc28gdGhpcyBjYXBzIG1lbW9yeS9DUFUgZmFuLW91dCBwZXIgaGFuZGxlci5cbiAqL1xuZXhwb3J0IGNvbnN0IE1BWF9NQVhfSU5MSU5FX1NURVBTID0gMTY7XG5cbi8vIFdhcm4tb25jZSBjYWNoZSBmb3IgV09SS0ZMT1dfTUFYX0lOTElORV9TVEVQUywga2V5ZWQgYnkgcmF3IGVudiB2YWx1ZS5cbmNvbnN0IHdhcm5lZE1heElubGluZVN0ZXBzVmFsdWVzID0gbmV3IFNldDxzdHJpbmc+KCk7XG5cbi8qKlxuICogUmVzb2x2ZSB0aGUgZWZmZWN0aXZlIG1heCBudW1iZXIgb2YgaW5saW5lIHN0ZXBzIGZvciB0aGUgY3VycmVudCBwcm9jZXNzLlxuICpcbiAqIFJlYWRzIGBwcm9jZXNzLmVudi5XT1JLRkxPV19NQVhfSU5MSU5FX1NURVBTYCBsYXppbHkgc28gdGVzdHMgYW5kXG4gKiBkZXBsb3ltZW50cyBjYW4gb3ZlcnJpZGUgcGVyIGludm9jYXRpb24uIEludmFsaWQgLyBvdXQtb2YtcmFuZ2UgdmFsdWVzIGZhbGxcbiAqIGJhY2sgdG8gYSBzYWZlIHZhbHVlIChubyB0aHJvdyDigJQgdGhlIGVudiB2YXIgaXMgYW4gZXNjYXBlIGhhdGNoKSBhbmQgZW1pdCBhXG4gKiBvbmUtdGltZSB3YXJuaW5nIHNvIG1pc2NvbmZpZ3VyYXRpb24gaXMgb2JzZXJ2YWJsZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldE1heElubGluZVN0ZXBzKCk6IG51bWJlciB7XG4gIGNvbnN0IHJhdyA9IHByb2Nlc3MuZW52LldPUktGTE9XX01BWF9JTkxJTkVfU1RFUFM7XG4gIGlmICghcmF3KSByZXR1cm4gTUFYX0lOTElORV9TVEVQUztcbiAgY29uc3QgcGFyc2VkID0gTnVtYmVyKHJhdyk7XG4gIGlmICghTnVtYmVyLmlzSW50ZWdlcihwYXJzZWQpIHx8IHBhcnNlZCA8PSAwKSB7XG4gICAgaWYgKCF3YXJuZWRNYXhJbmxpbmVTdGVwc1ZhbHVlcy5oYXMocmF3KSkge1xuICAgICAgd2FybmVkTWF4SW5saW5lU3RlcHNWYWx1ZXMuYWRkKHJhdyk7XG4gICAgICBydW50aW1lTG9nZ2VyLndhcm4oXG4gICAgICAgICdJZ25vcmluZyBXT1JLRkxPV19NQVhfSU5MSU5FX1NURVBTOiBub3QgYSBwb3NpdGl2ZSBpbnRlZ2VyOyB1c2luZyBkZWZhdWx0JyxcbiAgICAgICAgeyByYXcsIGRlZmF1bHRWYWx1ZTogTUFYX0lOTElORV9TVEVQUyB9XG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gTUFYX0lOTElORV9TVEVQUztcbiAgfVxuICBpZiAocGFyc2VkIDwgTUlOX01BWF9JTkxJTkVfU1RFUFMpIHJldHVybiBNSU5fTUFYX0lOTElORV9TVEVQUztcbiAgaWYgKHBhcnNlZCA+IE1BWF9NQVhfSU5MSU5FX1NURVBTKSB7XG4gICAgaWYgKCF3YXJuZWRNYXhJbmxpbmVTdGVwc1ZhbHVlcy5oYXMocmF3KSkge1xuICAgICAgd2FybmVkTWF4SW5saW5lU3RlcHNWYWx1ZXMuYWRkKHJhdyk7XG4gICAgICBydW50aW1lTG9nZ2VyLndhcm4oJ1dPUktGTE9XX01BWF9JTkxJTkVfU1RFUFMgYWJvdmUgbWF4aW11bTsgY2xhbXBlZCcsIHtcbiAgICAgICAgcmF3LFxuICAgICAgICBjbGFtcGVkVmFsdWU6IE1BWF9NQVhfSU5MSU5FX1NURVBTLFxuICAgICAgICBtYXhWYWx1ZTogTUFYX01BWF9JTkxJTkVfU1RFUFMsXG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIE1BWF9NQVhfSU5MSU5FX1NURVBTO1xuICB9XG4gIHJldHVybiBwYXJzZWQ7XG59XG5cbi8qKlxuICogVXBwZXIgYm91bmQgb24gdGhlIHNlcmlhbGl6ZWQgc3RlcCBpbnB1dCB0aGF0IHJlc2lsaWVudCBzdGVwIGRpc3BhdGNoIHdpbGxcbiAqIGlubGluZSBpbnRvIHRoZSBxdWV1ZSBtZXNzYWdlJ3MgYHN0ZXBJbnB1dGAuXG4gKlxuICogVmVyY2VsIFF1ZXVlcyBoYXMgbm8gaGFyZCBtZXNzYWdlLXNpemUgY2FwIChib2RpZXMgYWJvdmUgaXRzIH4yNTYgS0JcbiAqIGlubGluZSB0aHJlc2hvbGQgdHJhbnNwYXJlbnRseSBzcGlsbCB0byBTMy1iYWNrZWQgc3RvcmFnZSksIHNvIHRoaXMgYm91bmRcbiAqIGlzIGEgY29zdC9sYXRlbmN5IGNob2ljZSwgbm90IGEgcmVqZWN0aW9uIGd1YXJkOiB0aGUgbWVzc2FnZSBhbHNvIGNhcnJpZXNcbiAqIHRoZSBydW5JZCwgc3RlcElkLCBzdGVwTmFtZSwgYW5kIHRyYWNlIGNhcnJpZXIgYWxvbmdzaWRlIENCT1IgZnJhbWluZ1xuICogb3ZlcmhlYWQsIGFuZCBzdGF5aW5nIHVuZGVyIHRoZSBxdWV1ZSdzIGlubGluZSB0aHJlc2hvbGQga2VlcHMgc3RlcFxuICogbWVzc2FnZXMgb24gaXRzIGZhc3QgaW5saW5lIHBhdGggaW5zdGVhZCBvZiBwYXlpbmcgYW4gUzMgc3RvcmUrZmV0Y2hcbiAqIGRvdWJsZS1ob3AgZm9yIGJ5dGVzIHRoYXQgYWxyZWFkeSBsaXZlIGluIHRoZSBldmVudCBsb2cuIEFib3ZlIHRoaXMgc2l6ZVxuICogdGhlIGRpc3BhdGNoIGZhbGxzIGJhY2sgdG8gdGhlIHNlcXVlbnRpYWwgcGF0aCAoYHN0ZXBfY3JlYXRlZGAgd3JpdGUsIHRoZW5cbiAqIGEgcGF5bG9hZC1sZXNzIHF1ZXVlIG1lc3NhZ2UpLiBNYXRjaGVzIGBNQVhfSU5MSU5FX1JFU1VNRV9QQVlMT0FEX0JZVEVTYFxuICogb24gdGhlIHJlc2lsaWVudCBob29rIHJlc3VtZSBwYXRoLlxuICovXG5leHBvcnQgY29uc3QgTUFYX1JFU0lMSUVOVF9TVEVQX0lOUFVUX0JZVEVTID0gMTI4ICogMTAyNDtcblxuLyoqXG4gKiBXaGV0aGVyIHJlc2lsaWVudCBzdGVwIGRpc3BhdGNoIGlzIGVuYWJsZWQ6IHRoZSBzdXNwZW5zaW9uIGhhbmRsZXJcbiAqIHBhcmFsbGVsaXplcyBlYWNoIG5ld2x5IGNyZWF0ZWQgc3RlcCdzIGBzdGVwX2NyZWF0ZWRgIGV2ZW50IHdyaXRlIHdpdGggaXRzXG4gKiBzdGVwLWV4ZWN1dGlvbiBxdWV1ZSBwdWJsaXNoLCBjYXJyeWluZyB0aGUgc2VyaWFsaXplZCBzdGVwIGlucHV0IGluIHRoZVxuICogcXVldWUgbWVzc2FnZSAoYHN0ZXBJbnB1dGApIHNvIHRoZSBjb25zdW1lciBjYW4gaWRlbXBvdGVudGx5IHJlLWVuc3VyZSB0aGVcbiAqIGV2ZW50IGlmIHRoZSBkaXJlY3Qgd3JpdGUgZmFpbGVkIHRyYW5zaWVudGx5LiBNaXJyb3JzIHRoZSByZXNpbGllbnQgc3RhcnRcbiAqIChgcnVuSW5wdXRgKSBhbmQgcmVzaWxpZW50IGhvb2sgcmVzdW1lIChgaG9va0lucHV0YCkgcGF0dGVybnMuXG4gKlxuICogKipPZmYgYnkgZGVmYXVsdC4qKiBFbmFibGUgdmlhIGBXT1JLRkxPV19SRVNJTElFTlRfU1RFUF9ESVNQQVRDSD0xYC5cbiAqXG4gKiBUaGUgcXVldWUgcHVibGlzaCByYWNlcyB0aGUgY3JlYXRlJ3MgdmVyZGljdCwgYW5kIGEgY3JlYXRlIGNhbiBjb21lIGJhY2tcbiAqIHJlZnVzZWQg4oCUIGFzIGEgZHVwbGljYXRlIHRoaXMgcmVwbGF5IHNob3VsZCBzdG9wIHB1cnN1aW5nLCBvciBhcyBhIHN0YWxlXG4gKiB3cml0ZSBvbiBhIFdvcmxkIHRoYXQgcmVmdXNlcyByYXRoZXIgdGhhbiByZXBvcnRzLiBFaXRoZXIgd2F5IHRoZSBtZXNzYWdlXG4gKiBjYXJyeWluZyB0aGUgcGF5bG9hZCBpcyBhbHJlYWR5IG91dCwgc28gdGhlIGNvbnN1bWVyIGNhbiBtYXRlcmlhbGl6ZSBhIHN0ZXBcbiAqIHdob3NlIGNyZWF0ZSB3YXMgcmVmdXNlZCwgYW5kIG5vdGhpbmcgb3JkZXJzIHRoZSB2ZXJkaWN0IGJlZm9yZSB0aGVcbiAqIGNvbnN1bWVyJ3MgcmVkZWxpdmVyeSByZS1lbnN1cmUuIEVuYWJsaW5nIHRoaXMgdHJhZGVzIHRoYXQgd2luZG93IGZvciB0aGVcbiAqIGxhdGVuY3kgdGhlIHBhcmFsbGVsIHB1Ymxpc2ggc2F2ZXMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1Jlc2lsaWVudFN0ZXBEaXNwYXRjaEVuYWJsZWQoKTogYm9vbGVhbiB7XG4gIHJldHVybiBwcm9jZXNzLmVudi5XT1JLRkxPV19SRVNJTElFTlRfU1RFUF9ESVNQQVRDSCA9PT0gJzEnO1xufVxuXG4vKipcbiAqIFdoZXRoZXIgYmF0Y2hlZCBldmVudCB0cmFuc2l0aW9ucyBhcmUgZW5hYmxlZDogdGhlIHN1c3BlbnNpb24gaGFuZGxlciBmb2xkc1xuICogYSBjbGVhbiBmYW4tb3V0J3MgYHN0ZXBfY3JlYXRlZGAgKyBgd2FpdF9jcmVhdGVkYCB3cml0ZXMgaW50byBvbmVcbiAqIGB3b3JsZC5ldmVudHMuY3JlYXRlQmF0Y2hgIGNhbGwgKG9uZSBkdXJhYmxlIHdyaXRlLCBwZXItZXZlbnQgb3V0Y29tZXMpXG4gKiBpbnN0ZWFkIG9mIG9uZSB3cml0ZSBwZXIgZXZlbnQuIE9ubHkgZW5nYWdlcyB3aGVuIHRoZSBXb3JsZCBpbXBsZW1lbnRzIHRoZVxuICogb3B0aW9uYWwgYGV2ZW50cy5jcmVhdGVCYXRjaGAgQU5EIHRoZSBydW4gaXMgb24gc2xvdCBpZGVudGl0eVxuICogKHNwZWNWZXJzaW9uID49IDYpIEFORCB0aGUgc3VzcGVuc2lvbiBjYXJyaWVzIG5vIGF0dHJpYnV0ZS9ob29rIHdyaXRlcyBhbmRcbiAqIG5vIHJlc2lsaWVudCBzdGVwIGRpc3BhdGNoIOKAlCBldmVyeXRoaW5nIGVsc2Uga2VlcHMgdGhlIHNpbmdsZS1ldmVudCBwYXRoXG4gKiBieXRlLWZvci1ieXRlLlxuICpcbiAqIFJlYWRzIGBwcm9jZXNzLmVudi5XT1JLRkxPV19CQVRDSF9UUkFOU0lUSU9OU2AgbGF6aWx5LiBEZWZhdWx0ICoqT04qKjtcbiAqIGRpc2FibGVkIG9ubHkgYnkgYW4gZXhwbGljaXQgYCcwJ2AgLyBgJ2ZhbHNlJ2AgKGNhc2UtaW5zZW5zaXRpdmUpIOKAlCB0aGVcbiAqIG9wZXJhdG9yIGVzY2FwZSBoYXRjaCB0aGF0IHJlc3RvcmVzIHRoZSBleGFjdCBwcmlvciBvbmUtd3JpdGUtcGVyLWV2ZW50XG4gKiBwYXRoLCBtaXJyb3JpbmcgYFdPUktGTE9XX1RVUkJPYCdzIGtpbGwtc3dpdGNoIHNoYXBlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNCYXRjaFRyYW5zaXRpb25zRW5hYmxlZCgpOiBib29sZWFuIHtcbiAgY29uc3QgcmF3ID0gcHJvY2Vzcy5lbnYuV09SS0ZMT1dfQkFUQ0hfVFJBTlNJVElPTlM7XG4gIGlmIChyYXcgPT09IHVuZGVmaW5lZCB8fCByYXcgPT09ICcnKSByZXR1cm4gdHJ1ZTtcbiAgcmV0dXJuICEocmF3ID09PSAnMCcgfHwgcmF3LnRvTG93ZXJDYXNlKCkgPT09ICdmYWxzZScpO1xufVxuXG4vKipcbiAqIENlaWxpbmcgb24gZXZlbnRzIHBlciBgY3JlYXRlQmF0Y2hgIGNhbGwgZnJvbSB0aGUgYmF0Y2hlZCBmYW4tb3V0IGZvbGQuXG4gKiBNaXJyb3JzIHRoZSBzZXJ2ZXIncyB0cmFuc2FjdGlvbiBidWRnZXRzIHdpdGggYSBjb21mb3J0YWJsZSBtYXJnaW46IGVhY2hcbiAqIGZhbi1vdXQgZXZlbnQgY29zdHMgMiB0cmFuc2FjdGlvbiBpdGVtcyBzZXJ2ZXItc2lkZSAoZW50aXR5ICsgZXZlbnQgcm93KVxuICogYWdhaW5zdCB0aGUgMTAwLWl0ZW0gRHluYW1vREIgY2FwLCBhbmQgaW5saW5lIHBheWxvYWRzIGNvdW50IGFnYWluc3QgYVxuICogNzY4IEtCIGJ5dGUgYnVkZ2V0IOKAlCAzMiBldmVudHMgc3RheXMgd2VsbCB1bmRlciBib3RoLCBhbmQgYSBmYW4tb3V0IGxhcmdlclxuICogdGhhbiB0aGlzIHNpbXBseSBjb21taXRzIGluIHN1Y2Nlc3NpdmUgYmF0Y2hlcyAoc3BsaXQgYmF0Y2hlcyBsb3NlXG4gKiBjcm9zcy1iYXRjaCBhdG9taWNpdHksIHdoaWNoIGlzIGV4YWN0bHkgdG9kYXkncyBwZXItZXZlbnQtd3JpdGUgY3Jhc2hcbiAqIHN1cmZhY2Ug4oCUIGV2ZXJ5IGJhdGNoIHN0aWxsIGNvbnZlcmdlcyBvbiByZXRyeSB2aWEgcGVyLWV2ZW50IDQwOXMpLlxuICovXG5leHBvcnQgY29uc3QgTUFYX0JBVENIX0ZBTk9VVF9FVkVOVFMgPSAzMjtcblxuY29uc3Qgd2FybmVkTWF4RXZlbnRzVmFsdWVzID0gbmV3IFNldDxzdHJpbmc+KCk7XG5cbi8qKlxuICogT3B0aW9uYWwgY2xpZW50LXNpZGUgb3ZlcnJpZGUgZm9yIHRoZSBzZXJ2ZXItc3VwcGxpZWQgcGVyLXJ1biBldmVudCBjZWlsaW5nLlxuICogV2hlbiBzZXQgdG8gYSBwb3NpdGl2ZSBpbnRlZ2VyLCB0aGUgcnVudGltZSBjbGFtcHMgdGhlIHNlcnZlcidzIGxpbWl0ICpkb3duKlxuICogdG8gdGhpcyB2YWx1ZSAobmV2ZXIgcmFpc2VzIGl0KSBzbyBlbmZvcmNlbWVudCBjYW4gYmUgZXhlcmNpc2VkIHdpdGhvdXQgYVxuICogc2VydmVyLXNpZGUgY2hhbmdlLiBgdW5kZWZpbmVkYCAodW5zZXQpIOKHkiB1c2UgdGhlIHNlcnZlciB2YWx1ZSBhcy1pcy5cbiAqXG4gKiBSZWFkcyBgcHJvY2Vzcy5lbnYuV09SS0ZMT1dfTUFYX0VWRU5UU19PVkVSUklERWAgbGF6aWx5IHNvIHRlc3RzIGFuZFxuICogZGVwbG95bWVudHMgY2FuIG92ZXJyaWRlIHBlciBpbnZvY2F0aW9uLiBJbnZhbGlkIHZhbHVlcyBmYWxsIGJhY2sgdG8gdW5zZXRcbiAqIChubyB0aHJvdyDigJQgdGhlIGVudiB2YXIgaXMgYW4gZXNjYXBlIGhhdGNoKSBhbmQgZW1pdCBhIG9uZS10aW1lIHdhcm5pbmcuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRNYXhFdmVudHNPdmVycmlkZSgpOiBudW1iZXIgfCB1bmRlZmluZWQge1xuICBjb25zdCByYXcgPSBwcm9jZXNzLmVudi5XT1JLRkxPV19NQVhfRVZFTlRTX09WRVJSSURFO1xuICBpZiAoIXJhdykgcmV0dXJuIHVuZGVmaW5lZDtcbiAgY29uc3QgcGFyc2VkID0gTnVtYmVyKHJhdyk7XG4gIGlmICghTnVtYmVyLmlzSW50ZWdlcihwYXJzZWQpIHx8IHBhcnNlZCA8PSAwKSB7XG4gICAgaWYgKCF3YXJuZWRNYXhFdmVudHNWYWx1ZXMuaGFzKHJhdykpIHtcbiAgICAgIHdhcm5lZE1heEV2ZW50c1ZhbHVlcy5hZGQocmF3KTtcbiAgICAgIHJ1bnRpbWVMb2dnZXIud2FybihcbiAgICAgICAgJ0lnbm9yaW5nIFdPUktGTE9XX01BWF9FVkVOVFNfT1ZFUlJJREU6IG5vdCBhIHBvc2l0aXZlIGludGVnZXI7IHVzaW5nIHNlcnZlciBsaW1pdCcsXG4gICAgICAgIHsgcmF3IH1cbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbiAgcmV0dXJuIHBhcnNlZDtcbn1cblxuLyoqXG4gKiBXaGV0aGVyIG9wdGltaXN0aWMgaW5saW5lIHN0ZXAgc3RhcnQgaXMgZW5hYmxlZC4gV2hlbiBvbiwgdGhlIG93bmVkLWlubGluZVxuICogcGF0aCBiZWdpbnMgcnVubmluZyBhIGJyYW5kLW5ldyBzdGVwJ3MgYm9keSAqYmVmb3JlKiBpdHMgbGF6eSBgc3RlcF9zdGFydGVkYFxuICogbmV0d29yayBjYWxsIHJlc29sdmVzICh0aGUgaW5wdXQgaXMgYWxyZWFkeSBrbm93biBsb2NhbGx5KSwgYXdhaXRpbmcgdGhlXG4gKiBgc3RlcF9zdGFydGVkYCBvbmx5IGJlZm9yZSB0aGUgdGVybWluYWwgd3JpdGUuXG4gKlxuICogVGhpcyBjYW4gcnVuIGEgc3RlcCBib2R5IG1vcmUgdGhhbiBvbmNlIHdoZW4gaGFuZGxlcnMgcmFjZSBmb3IgdGhlIHNhbWVcbiAqIHN0ZXAncyBjcmVhdGUtY2xhaW0g4oCUIGJvdGggcnVuIHRoZSBib2R5IGJlZm9yZSBvbmUgd2lucy4gVGhhdCBpcyB1bnNhZmUgZm9yXG4gKiBzdGVwcyB3aXRoIG5vbi1pZGVtcG90ZW50IHNpZGUgZWZmZWN0czsgaW4gcGFydGljdWxhciwgdHdvIGNvbmN1cnJlbnQgcnVuc1xuICogb2YgYSBzdGVwIHRoYXQgd3JpdGVzIHRvIHRoZSB3b3JrZmxvdyBzdHJlYW0gKGUuZy4gYW4gQUkgYWdlbnQgc3RyZWFtaW5nXG4gKiB0b2tlbnMpIGNhbiBpbnRlcmxlYXZlIGFuZCBjb3JydXB0IHRoZSBzdHJlYW0gZGF0YS4gU28gdGhlIG9wdGltaXphdGlvbiBpc1xuICogKipvZmYgYnkgZGVmYXVsdCoqIGFuZCBtdXN0IGJlIGV4cGxpY2l0bHkgb3B0ZWQgaW50byBwZXIgZGVwbG95bWVudC5cbiAqXG4gKiBSZWFkcyBgcHJvY2Vzcy5lbnYuV09SS0ZMT1dfT1BUSU1JU1RJQ19JTkxJTkVfU1RBUlRgIGxhemlseS4gRGVmYXVsdCBPRkY7XG4gKiBlbmFibGVkIG9ubHkgYnkgYW4gZXhwbGljaXQgYCcxJ2AgLyBgJ3RydWUnYC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzT3B0aW1pc3RpY0lubGluZVN0YXJ0RW5hYmxlZCgpOiBib29sZWFuIHtcbiAgY29uc3QgcmF3ID0gcHJvY2Vzcy5lbnYuV09SS0ZMT1dfT1BUSU1JU1RJQ19JTkxJTkVfU1RBUlQ7XG4gIGlmIChyYXcgPT09IHVuZGVmaW5lZCB8fCByYXcgPT09ICcnKSByZXR1cm4gZmFsc2U7XG4gIHJldHVybiByYXcgPT09ICcxJyB8fCByYXcudG9Mb3dlckNhc2UoKSA9PT0gJ3RydWUnO1xufVxuXG4vKipcbiAqIFdoZXRoZXIgYW4gb3BlcmF0b3IgaGFzICoqZXhwbGljaXRseSBkaXNhYmxlZCoqIG9wdGltaXN0aWMgaW5saW5lIHN0YXJ0IHZpYVxuICogYFdPUktGTE9XX09QVElNSVNUSUNfSU5MSU5FX1NUQVJUPTBgIC8gYD1mYWxzZWAuIERpc3RpbmN0IGZyb20gXCJ1bnNldFwiOiB1bnNldFxuICogbGVhdmVzIHRoZSBvcHRpbWl6YXRpb24gb2ZmIGJ5IGRlZmF1bHQgYnV0IGxldHMgdHVyYm8gZm9yY2UgaXQgb247IGFuIGV4cGxpY2l0XG4gKiBgMGAvYGZhbHNlYCBpcyBhbiBvcGVyYXRvciBvcHQtb3V0IHRoYXQgdHVyYm8gbXVzdCBob25vciAodHVyYm8ncyBmb3JjZWRcbiAqIG9wdGltaXN0aWMgc3RhcnQgc3RpbGwgcnVucyBhIHN0ZXAgYm9keSBiZWZvcmUgYHN0ZXBfc3RhcnRlZGAvYHJ1bl9zdGFydGVkYCBpc1xuICogY29uZmlybWVkLCB0aGUgcHJvcGVydHkgc3VjaCBhbiBvcGVyYXRvciBpcyBvcHRpbmcgb3V0IG9mKSwgc29cbiAqIGBmb3JjZU9wdGltaXN0aWNTdGFydGAgZGVmZXJzIHRvIHRoaXMuIFJlYWRzIHRoZSBlbnYgdmFyIGxhemlseS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzT3B0aW1pc3RpY0lubGluZVN0YXJ0RXhwbGljaXRseURpc2FibGVkKCk6IGJvb2xlYW4ge1xuICBjb25zdCByYXcgPSBwcm9jZXNzLmVudi5XT1JLRkxPV19PUFRJTUlTVElDX0lOTElORV9TVEFSVDtcbiAgaWYgKHJhdyA9PT0gdW5kZWZpbmVkIHx8IHJhdyA9PT0gJycpIHJldHVybiBmYWxzZTtcbiAgcmV0dXJuIHJhdyA9PT0gJzAnIHx8IHJhdy50b0xvd2VyQ2FzZSgpID09PSAnZmFsc2UnO1xufVxuXG4vKipcbiAqIFdoZXRoZXIgXCJ0dXJibyBtb2RlXCIgaXMgZW5hYmxlZC4gVHVyYm8gbW9kZSBmYXN0LXBhdGhzIHRoZSAqZmlyc3QgZGVsaXZlcnkgb2ZcbiAqIHRoZSBmaXJzdCBpbnZvY2F0aW9uKiBvZiBhIHJ1biAoZGV0ZWN0ZWQgYnkgdGhlIGVudHJ5cG9pbnQgdmlhIGBydW5JbnB1dGBcbiAqIHByZXNlbmNlICsgYG1ldGFkYXRhLmF0dGVtcHQgPT09IDFgKTogaXQgYmFja2dyb3VuZHMgdGhlIGBydW5fc3RhcnRlZGAgZXZlbnRcbiAqIGNyZWF0aW9uLCBza2lwcyB0aGUgaW5pdGlhbCBldmVudC1sb2cgbG9hZCAobm90aGluZyBoYXMgYmVlbiB3cml0dGVuIHlldCksXG4gKiBhbmQgZm9yY2VzIG9wdGltaXN0aWMgaW5saW5lIHN0ZXAgc3RhcnQgZm9yIHRoYXQgaW52b2NhdGlvbiDigJQgaW5kZXBlbmRlbnQgb2ZcbiAqIGBXT1JLRkxPV19PUFRJTUlTVElDX0lOTElORV9TVEFSVGAuXG4gKlxuICogRm9yY2luZyBvcHRpbWlzdGljIHN0YXJ0IGlzIHNhZmUgaGVyZSBiZWNhdXNlIHRoZSBmaXJzdCBkZWxpdmVyeSBoYXMgbm9cbiAqIGNvbmN1cnJlbnQgcGVlciBoYW5kbGVyIHRvIHJhY2UgdGhlIHN0ZXAgY3JlYXRlLWNsYWltLCBzbyBhIHN0ZXAgYm9keSBydW5zXG4gKiBleGFjdGx5IG9uY2UuIFRoYXQgc2luZ2xlLWhhbmRsZXIgZ3VhcmFudGVlIGVuZHMgYXMgc29vbiBhcyB0aGUgcnVuIGNyZWF0ZXMgYVxuICogaG9vayBvciB3YWl0ICh3aGljaCBpbnRyb2R1Y2UgcmVzdW1lL3BhcmFsbGVsIGludm9jYXRpb25zKSwgc28gdGhlIHJ1bnRpbWVcbiAqIGV4aXRzIHR1cmJvIGF0IHRoYXQgcG9pbnQuXG4gKlxuICogUmVhZHMgYHByb2Nlc3MuZW52LldPUktGTE9XX1RVUkJPYCBsYXppbHkuIERlZmF1bHQgKipPTioqOyBkaXNhYmxlZCBvbmx5IGJ5IGFuXG4gKiBleHBsaWNpdCBgJzAnYCAvIGAnZmFsc2UnYCAoY2FzZS1pbnNlbnNpdGl2ZSkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1R1cmJvRW5hYmxlZCgpOiBib29sZWFuIHtcbiAgY29uc3QgcmF3ID0gcHJvY2Vzcy5lbnYuV09SS0ZMT1dfVFVSQk87XG4gIGlmIChyYXcgPT09IHVuZGVmaW5lZCB8fCByYXcgPT09ICcnKSByZXR1cm4gdHJ1ZTtcbiAgcmV0dXJuICEocmF3ID09PSAnMCcgfHwgcmF3LnRvTG93ZXJDYXNlKCkgPT09ICdmYWxzZScpO1xufVxuXG4vKipcbiAqIFdoZXRoZXIgdGhlIFF1aWNrSlMgZW5naW5lJ3MgYmFzZWxpbmUtc25hcHNob3Qgc3RhcnR1cCBvcHRpbWl6YXRpb24gaXNcbiAqIGVuYWJsZWQgKGRlZmF1bHQgT04pLiBXaGVuIG9uLCB0aGUgZW5naW5lIGh5ZHJhdGVzIGEgVk0gd2l0aCB0aGVcbiAqIHdvcmtmbG93IGJ1bmRsZSBvbmNlIHBlciBmdW5jdGlvbiBpbnN0YW5jZSwgc25hcHNob3RzIGl0LCBhbmQgc3RhcnRzXG4gKiBldmVyeSBpbnZvY2F0aW9uIGJ5IHJlc3RvcmluZyB0aGUgc25hcHNob3QgaW5zdGVhZCBvZiByZS1ldmFsdWF0aW5nXG4gKiB0aGUgYnVuZGxlIOKAlCBza2lwcGluZyB0aGUgZG9taW5hbnQgc2hhcmUgb2YgVk0gc3RhcnR1cCAobWVhc3VyZWRcbiAqIH43N21zIOKGkiB+M21zIHRvIGZpcnN0IHN1c3BlbnNpb24gZm9yIGEgMS4zTUIgYnVuZGxlKS4gQnVuZGxlcyB3aG9zZVxuICogbW9kdWxlIHNjb3BlIGNvbnN1bWVzIHJhbmRvbW5lc3MsIHJlYWRzIHRoZSBjbG9jaywgb3IgcmVwbGFjZXMgYVxuICogc2VyaWFsaXphdGlvbiBpbnRyaW5zaWMgYXJlIGRldGVjdGVkIGF0IGh5ZHJhdGUgdGltZSBhbmRcbiAqIGF1dG9tYXRpY2FsbHkgZmFsbCBiYWNrIHRvIHBlci1pbnZvY2F0aW9uIGZyZXNoIGV2YWx1YXRpb24gKHNlZVxuICogcHJlcGFyZUJhc2VsaW5lU25hcHNob3QpLiBTZXQgV09SS0ZMT1dfUVVJQ0tKU19CQVNFTElORV9TTkFQU0hPVD0wIHRvXG4gKiBkaXNhYmxlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNRdWlja0pTQmFzZWxpbmVTbmFwc2hvdEVuYWJsZWQoKTogYm9vbGVhbiB7XG4gIGNvbnN0IHJhdyA9IHByb2Nlc3MuZW52LldPUktGTE9XX1FVSUNLSlNfQkFTRUxJTkVfU05BUFNIT1Q7XG4gIGlmIChyYXcgPT09IHVuZGVmaW5lZCB8fCByYXcgPT09ICcnKSByZXR1cm4gdHJ1ZTtcbiAgcmV0dXJuICEocmF3ID09PSAnMCcgfHwgcmF3LnRvTG93ZXJDYXNlKCkgPT09ICdmYWxzZScpO1xufVxuXG4vKipcbiAqIFdoZXRoZXIgdGhlIGlubGluZSBsb29wIHJldGFpbnMgYSBzdXNwZW5kZWQgd29ya2Zsb3cgVk0gYWNyb3NzIGlubGluZSBzdGVwc1xuICogd2l0aGluIG9uZSBpbnZvY2F0aW9uIChkZWZhdWx0IE9OKS4gV2hlbiBvbiwgYSBzdGVwLW9ubHkgc3VzcGVuc2lvbiBrZWVwc1xuICogdGhlIGxpdmUgVk0sIGV2ZW50IGNvbnN1bWVyLCBhbmQgaHlkcmF0ZWQgc3RhdGUgYWxpdmUsIGFuZCB0aGUgbmV4dCBsb29wXG4gKiBpdGVyYXRpb24gYXBwZW5kcyBvbmx5IHRoZSBuZXdseSBkdXJhYmxlIGV2ZW50cyBpbnN0ZWFkIG9mIHJlYnVpbGRpbmcgdGhlXG4gKiBgdm0uQ29udGV4dGAgYW5kIHJlcGxheWluZyB0aGUgd2hvbGUgZXZlbnQgbG9nLiBOb24tc3RlcCBzdXNwZW5zaW9ucyBhbmRcbiAqIHJlcGxheSBkaXZlcmdlbmNlIGFsd2F5cyBmYWxsIGJhY2sgdG8gdGhlIG9yZGluYXJ5IGR1cmFibGUgcmVwbGF5IHBhdGguXG4gKlxuICogYFdPUktGTE9XX1JFVEFJTkVEX1ZNPTBgIChvciBgZmFsc2VgKSBpcyB0aGUga2lsbCBzd2l0Y2g6IGV2ZXJ5IGl0ZXJhdGlvblxuICogcmVwbGF5cyBmcm9tIHNjcmF0Y2ggaW4gYSBmcmVzaCBWTSwgbWF0Y2hpbmcgdGhlIHByZS1yZXRlbnRpb24gYmVoYXZpb3IuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1ZtUmV0ZW50aW9uRW5hYmxlZCgpOiBib29sZWFuIHtcbiAgY29uc3QgcmF3ID0gcHJvY2Vzcy5lbnYuV09SS0ZMT1dfUkVUQUlORURfVk07XG4gIGlmIChyYXcgPT09IHVuZGVmaW5lZCB8fCByYXcgPT09ICcnKSByZXR1cm4gdHJ1ZTtcbiAgcmV0dXJuICEocmF3ID09PSAnMCcgfHwgcmF3LnRvTG93ZXJDYXNlKCkgPT09ICdmYWxzZScpO1xufVxuXG4vKipcbiAqIFdoZXRoZXIgaW5saW5lIHN0ZXAgb3duZXJzaGlwIGlzIGVuYWJsZWQgKGRlZmF1bHQgT04pLiBXaGVuIG9uLCB0aGUgbGF6eVxuICogYHN0ZXBfc3RhcnRlZGAgdGhhdCBjcmVhdGVzIGFuIGlubGluZSBzdGVwIHJlY29yZHMgdGhlIG93bmluZyBxdWV1ZVxuICogbWVzc2FnZSBJRCwgYW5kIHdha2UgcmVwbGF5cyB0aGF0IG9ic2VydmUgYW4gYWN0aXZlbHktb3duZWQgc3RlcCBlbnF1ZXVlIGFcbiAqICpkZWxheWVkIGJhY2tzdG9wKiBtZXNzYWdlIGluc3RlYWQgb2YgaW1tZWRpYXRlbHkgcmVxdWV1ZWluZyBpdCDigJQgZml4aW5nXG4gKiBkdXBsaWNhdGUgaW5saW5lIHN0ZXAgZXhlY3V0aW9uIHdoZW4gYSBob29rL3dhaXQgd2FrZXMgYSBydW4gbWlkLXN0ZXBcbiAqICh2ZXJjZWwvd29ya2Zsb3cjMjc4MCkuXG4gKlxuICogYFdPUktGTE9XX0lOTElORV9PV05FUlNISVA9MGAgKG9yIGBmYWxzZWApIGlzIHRoZSBraWxsIHN3aXRjaDogZGlzcGF0Y2hcbiAqIHJldmVydHMgdG8gdGhlIHVuY29uZGl0aW9uYWwgaW1tZWRpYXRlIHJlcXVldWUuIFN0YW1waW5nIGlzIHVuYWZmZWN0ZWQg4oCUXG4gKiB0aGUgcmVjb3JkZWQgb3duZXJNZXNzYWdlSWQgaXMgaW5lcnQgZGF0YSB3aGVuIHRoZSBzd2l0Y2ggaXMgb2ZmLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNJbmxpbmVPd25lcnNoaXBFbmFibGVkKCk6IGJvb2xlYW4ge1xuICBjb25zdCByYXcgPSBwcm9jZXNzLmVudi5XT1JLRkxPV19JTkxJTkVfT1dORVJTSElQO1xuICBpZiAocmF3ID09PSB1bmRlZmluZWQgfHwgcmF3ID09PSAnJykgcmV0dXJuIHRydWU7XG4gIHJldHVybiAhKHJhdyA9PT0gJzAnIHx8IHJhdy50b0xvd2VyQ2FzZSgpID09PSAnZmFsc2UnKTtcbn1cblxuLyoqXG4gKiBEZWZhdWx0IGlubGluZS1vd25lcnNoaXAgbGVhc2UsIGluIHNlY29uZHM6IGhvdyBsb25nIGFmdGVyIGEgc3RlcCdzIGxhdGVzdFxuICogKHN0YW1wZWQpIGBzdGVwX3N0YXJ0ZWRgIGEgbm9uLW93bmVyIGludm9jYXRpb24gYXNzdW1lcyB0aGUgb3duaW5nXG4gKiBpbnZvY2F0aW9uIG1heSBzdGlsbCBiZSBhbGl2ZS4gV2l0aGluIHRoZSBsZWFzZSwgd2FrZSByZXBsYXlzIGVucXVldWUgdGhlXG4gKiBzdGVwJ3MgYmFja3N0b3AgbWVzc2FnZSB3aXRoIGBkZWxheVNlY29uZHMgPSBsZWFzZSByZW1haW5pbmdgIGluc3RlYWQgb2ZcbiAqIGltbWVkaWF0ZWx5OyBwYXN0IGl0LCB0aGV5IGVucXVldWUgaW1tZWRpYXRlbHkgKHRvZGF5J3MgYmVoYXZpb3IpLlxuICpcbiAqIFdoeSBhIGZpeGVkIDg2MCBhbmQgbm90IGEgdmFsdWUgZGVyaXZlZCBmcm9tIHRoZSBmdW5jdGlvbidzIGBtYXhEdXJhdGlvbmA6XG4gKiBuZWl0aGVyIHJ1bnRpbWUgbm9yIGJ1aWxkIHRpbWUgY2FuIHNlZSB0aGUgcmVzb2x2ZWQgdmFsdWUg4oCUIGJ1aWxkZXJzIGVtaXRcbiAqIGBtYXhEdXJhdGlvbjogJ21heCdgLCB3aGljaCB0aGUgcGxhdGZvcm0gcmVzb2x2ZXMgcGVyLXBsYW4gYXQgZGVwbG95LCBhbmRcbiAqIG5vIGVudiB2YXIgb3IgcmVxdWVzdC1jb250ZXh0IGRlYWRsaW5lIEFQSSBleHBvc2VzIHRoZSByZXN1bHQuIFRoZSBib3VuZFxuICogY29tZXMgZnJvbSBhIHBsYXRmb3JtIHJ1bGUgaW5zdGVhZDogZHVyYXRpb25zIGFib3ZlIDgwMHMgcmVxdWlyZSBleHBsaWNpdFxuICogcGVyLWZ1bmN0aW9uIG51bWVyaWMgY29uZmlnLCBzbyBhIGJ1aWxkZXItZW1pdHRlZCBgJ21heCdgIHJlc29sdmVzIHRvIGF0XG4gKiBtb3N0IDgwMHMg4oCUIDg2MHMgdGhlcmVmb3JlIGRvbWluYXRlcyBhbnkgd29ya2Zsb3cgcm91dGUncyBpbnZvY2F0aW9uXG4gKiBsaWZldGltZSBwbHVzIHNjaGVkdWxpbmcgc2xhY2suIFJldmlzaXQgd2hlbiB0aGF0IGNlaWxpbmcgbW92ZXMgKHRoZVxuICogMzAtbWludXRlIGR1cmF0aW9uIGJldGEgYmVjb21pbmcgcmVhY2hhYmxlIHZpYSBgJ21heCdgIHdvdWxkIGludmFsaWRhdGVcbiAqIHRoZSBib3VuZCkuIFdvcmxkcyB3aXRob3V0IGFuIGludm9jYXRpb24ga2lsbCBib3VuZCAod29ybGQtbG9jYWwsXG4gKiBzZWxmLWhvc3RlZCkgZ2V0IG5vIGRlYXRoIHByb29mIGZyb20gYW55IGNvbnN0YW50IOKAlCB0aGVyZSB0aGUgaW4tcHJvY2Vzc1xuICogc2luZ2xlLWZsaWdodCBsYXllciAoc3RlcC1zaW5nbGUtZmxpZ2h0LnRzKSBpcyB3aGF0IG1ha2VzIGEgYmFja3N0b3BcbiAqIGZpcmluZyBtaWQtc3RlcCBoYXJtbGVzcy5cbiAqXG4gKiA4NjAgYWxzbyBzdGF5cyB1bmRlciB0aGUgcXVldWUncyA5MDBzIG1heGltdW0gZGVsYXkgKFNRUyBjYXApLCBzbyBhXG4gKiBiYWNrc3RvcCdzIGZ1bGwgbGVhc2UgcmVtYWluZGVyIGFsd2F5cyBmaXRzIGluIGEgc2luZ2xlIGRlbGF5ZWQgbWVzc2FnZS5cbiAqXG4gKiBPdmVycmlkZSB2aWEgYFdPUktGTE9XX0lOTElORV9PV05FUlNISVBfTEVBU0VfU0VDT05EU2AgKGNsYW1wZWQgdG9cbiAqIDEuLmBNQVhfSU5MSU5FX09XTkVSU0hJUF9MRUFTRV9TRUNPTkRTYCkuXG4gKi9cbmV4cG9ydCBjb25zdCBJTkxJTkVfT1dORVJTSElQX0xFQVNFX1NFQ09ORFMgPSA4NjA7XG5cbi8qKlxuICogVXBwZXIgYm91bmQgZm9yIHRoZSBsZWFzZSBlbnYgb3ZlcnJpZGUuIDkwMHMgaXMgdGhlIHF1ZXVlJ3MgbWF4aW11bVxuICogcGVyLW1lc3NhZ2UgZGVsYXkgKFNRUyBjYXApIOKAlCBhIGxvbmdlciBsZWFzZSB3b3VsZCBuZWVkIGRlbGF5IGNoYWluaW5nXG4gKiBsaWtlIGxvbmcgd2FpdHMgdXNlOyBjbGFtcCBpbnN0ZWFkIHNvIG9uZSBkZWxheWVkIG1lc3NhZ2UgYWx3YXlzIHN1ZmZpY2VzLlxuICovXG5leHBvcnQgY29uc3QgTUFYX0lOTElORV9PV05FUlNISVBfTEVBU0VfU0VDT05EUyA9IDkwMDtcblxuLyoqXG4gKiBFZmZlY3RpdmUgaW5saW5lLW93bmVyc2hpcCBsZWFzZS4gT3ZlcnJpZGUgdmlhXG4gKiBgV09SS0ZMT1dfSU5MSU5FX09XTkVSU0hJUF9MRUFTRV9TRUNPTkRTYCDigJQgZS5nLiByYWlzZSBpdCBvbiBzZWxmLWhvc3RlZFxuICogbXVsdGktaW5zdGFuY2Ugd29ybGRzIHdpdGggbG9uZy1ydW5uaW5nIHN0ZXBzIHRvIHdpZGVuIHRoZSB3aW5kb3cgaW4gd2hpY2hcbiAqIGEgbGl2ZSBvd25lciBpcyBwcm90ZWN0ZWQgZnJvbSBhIGNvbmN1cnJlbnQgYmFja3N0b3AgZXhlY3V0aW9uLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0SW5saW5lT3duZXJzaGlwTGVhc2VTZWNvbmRzKCk6IG51bWJlciB7XG4gIHJldHVybiBlbnZOdW1iZXIoXG4gICAgJ1dPUktGTE9XX0lOTElORV9PV05FUlNISVBfTEVBU0VfU0VDT05EUycsXG4gICAgSU5MSU5FX09XTkVSU0hJUF9MRUFTRV9TRUNPTkRTLFxuICAgIHsgaW50ZWdlcjogdHJ1ZSwgbWluOiAxLCBtYXg6IE1BWF9JTkxJTkVfT1dORVJTSElQX0xFQVNFX1NFQ09ORFMgfVxuICApO1xufVxuXG4vLyBBIHJlcGxheS1jb25zdW1lciBtaXNtYXRjaCBjYW4gYmUgY2F1c2VkIGJ5IGEgdHJhbnNpZW50IGRpdmVyZ2VudCByZXBsYXlcbi8vIHJhdGhlciB0aGFuIGFuIGludmFsaWQgcGVyc2lzdGVkIGhpc3RvcnkuIFF1ZXVlIGJvdW5kZWQgcmVjb3ZlcnkgcmVwbGF5c1xuLy8gYmVmb3JlIHJlY29yZGluZyB0ZXJtaW5hbCBjb3JydXB0aW9uIGZvciBhIHJ1biB0aGF0IGNhbm5vdCByZXBsYXkuXG5leHBvcnQgY29uc3QgUkVQTEFZX0RJVkVSR0VOQ0VfTUFYX1JFVFJJRVMgPSAzO1xuXG4vKipcbiAqIEVmZmVjdGl2ZSByZXBsYXktZGl2ZXJnZW5jZSByZWNvdmVyeSBidWRnZXQuIE92ZXJyaWRlIHZpYVxuICogYFdPUktGTE9XX1JFUExBWV9ESVZFUkdFTkNFX01BWF9SRVRSSUVTYC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFJlcGxheURpdmVyZ2VuY2VNYXhSZXRyaWVzKCk6IG51bWJlciB7XG4gIHJldHVybiBlbnZOdW1iZXIoXG4gICAgJ1dPUktGTE9XX1JFUExBWV9ESVZFUkdFTkNFX01BWF9SRVRSSUVTJyxcbiAgICBSRVBMQVlfRElWRVJHRU5DRV9NQVhfUkVUUklFUyxcbiAgICB7IGludGVnZXI6IHRydWUgfVxuICApO1xufVxuXG4vLyBBIHN0YWxlLXNuYXBzaG90IHJlamVjdGlvbiAoNDEyKSBtZWFucyB0aGUgcmVwbGF5J3MgZXZlbnQgbG9nIHdhcyBtaXNzaW5nIGFuXG4vLyBldmVudCB0aGUgV29ybGQgaGFkIGFscmVhZHkgcmVjb3JkZWQsIHNvIHRoZSByZXBsYXkgaXMgcmUtZGVyaXZlZCBmcm9tIGFcbi8vIGNvcnJlY3RlZCBsb2cgaW5zaWRlIHRoZSBzYW1lIGludm9jYXRpb24uIEJvdW5kZWQgYmVjYXVzZSBhIHBlcnNpc3RlbnRseVxuLy8gcmVqZWN0ZWQgd3JpdGUgc2hvdWxkIGVzY2FsYXRlIHJhdGhlciB0aGFuIHNwaW46IGFmdGVyIHRoaXMgbWFueSByZXN0YXJ0cyB0aGVcbi8vIHJ1biBpcyByZS1pbnZva2VkIChhIG5ldyBpbnZvY2F0aW9uLCBwb3NzaWJseSBpbiBhIGRpZmZlcmVudCByZWdpb24pLCBhbmQgdGhlXG4vLyBydW4tbGV2ZWwgYnVkZ2V0IGJlbG93IHRoZW4gYXBwbGllcy5cbmV4cG9ydCBjb25zdCBQUkVDT05ESVRJT05fTUFYX0lOUFJPQ0VTU19SRVNUQVJUUyA9IDM7XG5cbi8qKlxuICogRWZmZWN0aXZlIGluLXByb2Nlc3MgcmVwbGF5LXJlc3RhcnQgYnVkZ2V0IGZvciBzdGFsZS1zbmFwc2hvdCByZWplY3Rpb25zLlxuICogT3ZlcnJpZGUgdmlhIGBXT1JLRkxPV19QUkVDT05ESVRJT05fTUFYX0lOUFJPQ0VTU19SRVNUQVJUU2AuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRQcmVjb25kaXRpb25NYXhJblByb2Nlc3NSZXN0YXJ0cygpOiBudW1iZXIge1xuICByZXR1cm4gZW52TnVtYmVyKFxuICAgICdXT1JLRkxPV19QUkVDT05ESVRJT05fTUFYX0lOUFJPQ0VTU19SRVNUQVJUUycsXG4gICAgUFJFQ09ORElUSU9OX01BWF9JTlBST0NFU1NfUkVTVEFSVFMsXG4gICAgeyBpbnRlZ2VyOiB0cnVlIH1cbiAgKTtcbn1cblxuLy8gVGhlIGluLXByb2Nlc3MgYnVkZ2V0IGFib3ZlIGlzIHBlci1pbnZvY2F0aW9uLCBhbmQgYSByZS1pbnZvY2F0aW9uIHRoYXRcbi8vIGVucXVldWVzIGEgZnJlc2ggbWVzc2FnZSBhbHNvIHJlc3RhcnRzIHRoZSBxdWV1ZSdzIGRlbGl2ZXJ5IGNvdW50LCBzbyB3aXRob3V0XG4vLyBhIGNvdW50ZXIgY2FycmllZCBvbiB0aGUgbWVzc2FnZSBhIHBlcm1hbmVudGx5IGZlbmNlZCBydW4gaGFzIG5vIHJ1bi1sZXZlbFxuLy8gYm91bmQgYXQgYWxsLiBJdCBjYW4gc3RheSBmZW5jZWQgd2l0aG91dCBhbnkgcGVybWFuZW50IGZhdWx0IOKAlCBhIGZ1bGwgcmVsb2FkXG4vLyBpcyBub3QgYXRvbWljIGFjcm9zcyBwYWdlcywgc28gYSBidXN5IHJ1biBjYW4gYWNxdWlyZSBhIG5ldyBob2xlIG9uIGV2ZXJ5XG4vLyByZWxvYWQg4oCUIHNvIHRoZSBjaGFpbiBpcyBjb3VudGVkIGFuZCB0aGUgcnVuIGZhaWxzIG9uY2UgdGhpcyBtYW55XG4vLyByZS1pbnZvY2F0aW9ucyBoYXZlIGJlZW4gc3BlbnQgb24gc3RhbGUtc25hcHNob3QgcmVqZWN0aW9ucy5cbmV4cG9ydCBjb25zdCBQUkVDT05ESVRJT05fTUFYX1JFSU5WT0NBVElPTlMgPSA1O1xuXG4vKipcbiAqIEVmZmVjdGl2ZSBwZXItcnVuIGJ1ZGdldCBmb3IgcmUtaW52b2NhdGlvbnMgY2F1c2VkIGJ5IHN0YWxlLXNuYXBzaG90XG4gKiByZWplY3Rpb25zLiBPdmVycmlkZSB2aWEgYFdPUktGTE9XX1BSRUNPTkRJVElPTl9NQVhfUkVJTlZPQ0FUSU9OU2AuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRQcmVjb25kaXRpb25NYXhSZWludm9jYXRpb25zKCk6IG51bWJlciB7XG4gIHJldHVybiBlbnZOdW1iZXIoXG4gICAgJ1dPUktGTE9XX1BSRUNPTkRJVElPTl9NQVhfUkVJTlZPQ0FUSU9OUycsXG4gICAgUFJFQ09ORElUSU9OX01BWF9SRUlOVk9DQVRJT05TLFxuICAgIHsgaW50ZWdlcjogdHJ1ZSB9XG4gICk7XG59XG5cbi8vIEJhY2tvZmYgYmVmb3JlIGEgcHJlY29uZGl0aW9uIHJlLWludm9jYXRpb24uIFVubGlrZSB0aGUgaW4tcHJvY2VzcyByZXN0YXJ0XG4vLyAod2hlcmUgdGhlIHBvaW50IGlzIHRvIHJlLXJlYWQgaW1tZWRpYXRlbHkpLCBhIHJlLWludm9jYXRpb24gb25seSBoYXBwZW5zXG4vLyBhZnRlciB0aGUgaW4tcHJvY2VzcyBidWRnZXQgZmFpbGVkIHRvIGNhdGNoIHVwLCBzbyB0aGUgbG9nIGlzIGJlaW5nIGV4dGVuZGVkXG4vLyBmYXN0ZXIgdGhhbiB0aGlzIHJlcGxheSBjYW4gZm9sbG93IGl0LiBXYWl0aW5nIGxldHMgdGhlIHdyaXRlcnMgcXVpZXNjZS5cbmV4cG9ydCBjb25zdCBQUkVDT05ESVRJT05fUkVJTlZPS0VfREVMQVlfU0VDT05EUyA9IDI7XG5cbi8qKlxuICogRWZmZWN0aXZlIGRlbGF5IGJlZm9yZSBhIHByZWNvbmRpdGlvbiByZS1pbnZvY2F0aW9uLiBPdmVycmlkZSB2aWFcbiAqIGBXT1JLRkxPV19QUkVDT05ESVRJT05fUkVJTlZPS0VfREVMQVlfU0VDT05EU2AuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRQcmVjb25kaXRpb25SZWludm9rZURlbGF5U2Vjb25kcygpOiBudW1iZXIge1xuICByZXR1cm4gZW52TnVtYmVyKFxuICAgICdXT1JLRkxPV19QUkVDT05ESVRJT05fUkVJTlZPS0VfREVMQVlfU0VDT05EUycsXG4gICAgUFJFQ09ORElUSU9OX1JFSU5WT0tFX0RFTEFZX1NFQ09ORFMsXG4gICAgeyBpbnRlZ2VyOiB0cnVlIH1cbiAgKTtcbn1cblxuLy8gQSBkZWxpdmVyeSByZWFjaGluZyBhIGRlcGxveW1lbnQgdGhlIHJ1biBpcyBub3QgcGlubmVkIHRvIGlzIG5vdCB0cmVhdGVkIGFzXG4vLyBwZXJtYW5lbnQuIFJlLXJvdXRlIHRoZSBtZXNzYWdlIGF0IHRoZSBydW4ncyBvd24gZGVwbG95bWVudCBhIGJvdW5kZWQgbnVtYmVyXG4vLyBvZiB0aW1lcyBiZWZvcmUgZmFpbGluZyB0aGUgcnVuIHdpdGggREVQTE9ZTUVOVF9NSVNNQVRDSC5cbmV4cG9ydCBjb25zdCBERVBMT1lNRU5UX01JU01BVENIX01BWF9SRVRSSUVTID0gMztcblxuLyoqXG4gKiBFZmZlY3RpdmUgZGVwbG95bWVudC1taXNtYXRjaCByZS1yb3V0ZSBidWRnZXQuIE92ZXJyaWRlIHZpYVxuICogYFdPUktGTE9XX0RFUExPWU1FTlRfTUlTTUFUQ0hfTUFYX1JFVFJJRVNgOyBgMGAgZmFpbHMgdGhlIHJ1biBvbiB0aGUgZmlyc3RcbiAqIG1pc3JvdXRlZCBkZWxpdmVyeSBpbnN0ZWFkIG9mIGF0dGVtcHRpbmcgcmVjb3ZlcnkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXREZXBsb3ltZW50TWlzbWF0Y2hNYXhSZXRyaWVzKCk6IG51bWJlciB7XG4gIHJldHVybiBlbnZOdW1iZXIoXG4gICAgJ1dPUktGTE9XX0RFUExPWU1FTlRfTUlTTUFUQ0hfTUFYX1JFVFJJRVMnLFxuICAgIERFUExPWU1FTlRfTUlTTUFUQ0hfTUFYX1JFVFJJRVMsXG4gICAgeyBpbnRlZ2VyOiB0cnVlLCBtaW46IDAgfVxuICApO1xufVxuIl19
|
|
511
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uc3RhbnRzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3J1bnRpbWUvY29uc3RhbnRzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNsRCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDNUMsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUU3Qyw0RUFBNEU7QUFDNUUsNEVBQTRFO0FBQzVFLHlFQUF5RTtBQUN6RSxvREFBb0Q7QUFDcEQsRUFBRTtBQUNGLCtFQUErRTtBQUMvRSxzREFBc0Q7QUFDdEQsK0VBQStFO0FBQy9FLDRFQUE0RTtBQUM1RSw2RUFBNkU7QUFDN0UseUVBQXlFO0FBQ3pFLCtFQUErRTtBQUMvRSw2RUFBNkU7QUFDN0UsK0VBQStFO0FBQy9FLGdGQUFnRjtBQUNoRiwyRUFBMkU7QUFDM0UseUVBQXlFO0FBQ3pFLDZCQUE2QjtBQUM3QixNQUFNLENBQUMsTUFBTSxvQkFBb0IsR0FBRyxFQUFFLENBQUM7QUFFdkM7O0dBRUc7QUFDSCxNQUFNLFVBQVUscUJBQXFCO0lBQ25DLHdFQUF3RTtJQUN4RSwwRUFBMEU7SUFDMUUsOEVBQThFO0lBQzlFLHlFQUF5RTtJQUN6RSw0RUFBNEU7SUFDNUUsT0FBTyxTQUFTLENBQUMsK0JBQStCLEVBQUUsb0JBQW9CLEVBQUU7UUFDdEUsT0FBTyxFQUFFLElBQUk7UUFDYixHQUFHLEVBQUUsQ0FBQztRQUNOLEdBQUcsRUFBRSxvQkFBb0I7S0FDMUIsQ0FBQyxDQUFDO0FBQ0wsQ0FBQztBQUVEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FxQkc7QUFDSCxNQUFNLENBQUMsTUFBTSxpQkFBaUIsR0FBRyxPQUFPLENBQUM7QUFFekMsMkRBQTJEO0FBQzNELE1BQU0sQ0FBQyxNQUFNLHFCQUFxQixHQUFHLE1BQU0sQ0FBQztBQUU1Qzs7OztHQUlHO0FBQ0gs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QUMsQ0FBQztBQUVyRDs7O0dBR0c7QUFDSCxNQUFNLFVBQVUsbUNBQW1DO0lBQ2pELE9BQU8sU0FBUyxDQUNkLDhDQUE4QyxFQUM5QyxtQ0FBbUMsRUFDbkMsRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLENBQ2xCLENBQUM7QUFDSixDQUFDO0FBRUQsOEVBQThFO0FBQzlFLCtFQUErRTtBQUMvRSw0REFBNEQ7QUFDNUQsTUFBTSxDQUFDLE1BQU0sK0JBQStCLEdBQUcsQ0FBQyxDQUFDO0FBRWpEOzs7O0dBSUc7QUFDSCxNQUFNLFVBQVUsK0JBQStCO0lBQzdDLE9BQU8sU0FBUyxDQUNkLDBDQUEwQyxFQUMxQywrQkFBK0IsRUFDL0IsRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLEdBQUcsRUFBRSxDQUFDLEVBQUUsQ0FDMUIsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBnbG9iYWxTaW5nbGV0b24gfSBmcm9tICdAd29ya2Zsb3cvdXRpbHMnO1xuaW1wb3J0IHsgZW52TnVtYmVyIH0gZnJvbSAnQHdvcmtmbG93L3dvcmxkJztcbmltcG9ydCB7IHJ1bnRpbWVMb2dnZXIgfSBmcm9tICcuLi9sb2dnZXIuanMnO1xuXG4vLyBNYXhpbXVtIG51bWJlciBvZiBxdWV1ZSBkZWxpdmVyeSBhdHRlbXB0cyBiZWZvcmUgdGhlIGhhbmRsZXIgZ2l2ZXMgdXAgYW5kXG4vLyBncmFjZWZ1bGx5IGZhaWxzIHRoZSBydW4vc3RlcC4gVGhpcyBtdXN0IGJlIGJvdW5kZWQgdW5kZXIgdGhlIFZRUyBtZXNzYWdlXG4vLyBtYXggdmlzaWJpbGl0eSB3aW5kb3cgKDI0IGhvdXJzKSBzbyB0aGF0IG91ciBoYW5kbGVyLXNpZGUgZmFpbHVyZSBwYXRoXG4vLyByZWxpYWJseSBleGVjdXRlcyBiZWZvcmUgVlFTIGV4cGlyZXMgdGhlIG1lc3NhZ2UuXG4vL1xuLy8gVGhlIGVmZmVjdGl2ZSB3YWxsLWNsb2NrIHN1cnZpdmFsIGRlcGVuZHMgb24gdGhlIHBlci1yZWRlbGl2ZXJ5IGJhY2tvZmY6IHRoZVxuLy8gYHJldHJ5LWFmdGVyYCB0aGUgaGFuZGxlciByZXR1cm5zIChzZWUgd29ybGQtdmVyY2VsXG4vLyBgZ2V0SGFuZGxlckVycm9yUmV0cnlBZnRlclNlY29uZHNgKSBmZWQgdGhyb3VnaCBWUVMgYGNhbGN1bGF0ZUJhY2tvZmZEZWxheWAuXG4vLyBWUVMgdXNlcyBvdXIgdmFsdWUgZm9yIHRoZSBmaXJzdCAzMiBhdHRlbXB0cyAoY2xhbXBlZCB0byBbNXMsIDkwMHNdKSB0aGVuXG4vLyBhcHBsaWVzIGl0cyBvd24gZXhwb25lbnRpYWwgZ3Jvd3RoLCBldmVyeSBob3AgaGFyZC1jYXBwZWQgYXQgdGhlIFNRUyBsaW1pdFxuLy8gb2YgOTAwcy4gV2l0aCB0aGUgYmFja29mZiByYW1waW5nIHRvd2FyZCB0aGF0IDkwMHMgY2VpbGluZyAocmVhY2hlZCBieVxuLy8gfmRlbGl2ZXJ5IDExKSwgNDggYXR0ZW1wdHMgc3BhbiByb3VnaGx5IDnigJMxMCBob3VycyBvZiB3YWxsLWNsb2NrICh+MzUsMDAwcyksXG4vLyBjb21mb3J0YWJseSB1bmRlciB0aGUgMjQtaG91ciBtZXNzYWdlLXZpc2liaWxpdHkgbGltaXQgc28gdGhlIGZhaWx1cmUgcGF0aFxuLy8gcnVucyBiZWZvcmUgdGhlIG1lc3NhZ2UgZXhwaXJlcy4gKEEgZmxhdHRlciwgbG93LWNhcHBlZCBiYWNrb2ZmIGV4aGF1c3RzIHRoZVxuLy8gYnVkZ2V0IGluIG9ubHkgYSBmZXcgaG91cnMsIGZhaWxpbmcgb3RoZXJ3aXNlLWhlYWx0aHkgcnVucyBkdXJpbmcgYSB0cmFuc2llbnRcbi8vIGJhY2tlbmQgb3V0YWdlOyBjb252ZXJzZWx5LCBzcGFubmluZyB0aGUgZnVsbCAyNGggd2luZG93IHdvdWxkIHJlcXVpcmUgYVxuLy8gc3Vic3RhbnRpYWxseSBoaWdoZXIgY2FwIGhlcmUsIG5vdCBhIGhpZ2hlciBwZXItaG9wIGNlaWxpbmcsIHNpbmNlIFZRU1xuLy8gY2xhbXBzIGV2ZXJ5IGhvcCBhdCA5MDBzLilcbmV4cG9ydCBjb25zdCBNQVhfUVVFVUVfREVMSVZFUklFUyA9IDQ4O1xuXG4vKipcbiAqIEVmZmVjdGl2ZSBtYXggcXVldWUgZGVsaXZlcmllcy4gT3ZlcnJpZGUgdmlhIGBXT1JLRkxPV19NQVhfUVVFVUVfREVMSVZFUklFU2AuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRNYXhRdWV1ZURlbGl2ZXJpZXMoKTogbnVtYmVyIHtcbiAgLy8gT25seSBldmVyIGxvd2VyIHRoZSBkZWxpdmVyeSBidWRnZXQuIFRoZSBkZWZhdWx0IGlzIGNhbGlicmF0ZWQgc28gdGhlXG4gIC8vIGhhbmRsZXItc2lkZSBmYWlsdXJlIHBhdGggcnVucyBiZWZvcmUgVlFTIG1lc3NhZ2UtcmV0ZW50aW9uIGV4cGlyeSAoc2VlXG4gIC8vIE1BWF9RVUVVRV9ERUxJVkVSSUVTIGFib3ZlKTsgYSBoaWdoZXIgdmFsdWUgd291bGQgYnlwYXNzIHRoYXQgaW52YXJpYW50IGFuZFxuICAvLyBsZXQgYSBiYWQgZGVwbG95bWVudCByZWRlbGl2ZXIgdW50aWwgcXVldWUgZXhwaXJ5IGluc3RlYWQgb2YgcmVjb3JkaW5nXG4gIC8vIHJ1bl9mYWlsLiBgbWF4YCBjbGFtcHMgYSB0b28taGlnaCBvdmVycmlkZSBiYWNrIGRvd24gdG8gdGhlIHNhZmUgZGVmYXVsdC5cbiAgcmV0dXJuIGVudk51bWJlcignV09SS0ZMT1dfTUFYX1FVRVVFX0RFTElWRVJJRVMnLCBNQVhfUVVFVUVfREVMSVZFUklFUywge1xuICAgIGludGVnZXI6IHRydWUsXG4gICAgbWluOiAxLFxuICAgIG1heDogTUFYX1FVRVVFX0RFTElWRVJJRVMsXG4gIH0pO1xufVxuXG4vKipcbiAqIERlZmF1bHQgbWF4aW11bSB0aW1lIGFsbG93ZWQgZm9yIHRoZSAqcmVwbGF5KiBwb3J0aW9uIG9mIGEgc2luZ2xlIHdvcmtmbG93XG4gKiBoYW5kbGVyIGludm9jYXRpb24gKGluIG1zKS4gVGhpcyBidWRnZXQgb25seSBjb3ZlcnMgZGV0ZXJtaW5pc3RpYy1yZXBsYXlcbiAqIGFuZCB3b3JrZmxvdy1WTSBleGVjdXRpb24gYmV0d2VlbiBzdGVwIGJvdW5kYXJpZXMuIElubGluZSBzdGVwIGJvZGllc1xuICogKGBcInVzZSBzdGVwXCJgIGZ1bmN0aW9ucyBpbnZva2VkIHZpYSBgZXhlY3V0ZVN0ZXBgKSBkbyBOT1QgY291bnQgYWdhaW5zdFxuICogaXQuIFN0ZXAgYm9kaWVzIGFyZSBib3VuZGVkIHNlcGFyYXRlbHkgYnkgdGhlIHBsYXRmb3JtJ3MgZnVuY3Rpb25cbiAqIGBtYXhEdXJhdGlvbmAgKGUuZy4gODAwcyBvbiBWZXJjZWwgUHJvIEZsdWlkKSBhbmQgYE5PX0lOTElORV9SRVBMQVlfQUZURVJfTVNgLlxuICpcbiAqIElmIHRoZSBub24tc3RlcCAoXCJyZXBsYXlcIikgdGltZSB3aXRoaW4gYSBzaW5nbGUgaW52b2NhdGlvbiBleGNlZWRzIHRoaXNcbiAqIGJ1ZGdldCwgdGhlIGhhbmRsZXIgcmVqZWN0cyBzbyB0aGUgcXVldWUgY2FuIHJldHJ5LiBBZnRlclxuICogYFJFUExBWV9USU1FT1VUX01BWF9SRVRSSUVTYCBleGhhdXN0ZWQgYXR0ZW1wdHMgdGhlIHJ1biBpcyBmYWlsZWQgd2l0aFxuICogYFJVTl9FUlJPUl9DT0RFUy5SRVBMQVlfVElNRU9VVGAuXG4gKlxuICogTm90ZSB0aGF0IG9uIFZlcmNlbCBIb2JieSAoc3RhbmRhcmQgZnVuY3Rpb25zKSwgdGhlIHBsYXRmb3JtIGBtYXhEdXJhdGlvbmBcbiAqIGlzIDYwcywgd2VsbCBiZWxvdyB0aGlzIGJ1ZGdldCwgc28gdGhlIHBsYXRmb3JtIFNJR1RFUk0gd2lsbCBmaXJlIGZpcnN0XG4gKiBhbmQgdGhlIHF1ZXVlIHdpbGwgcmUtZGVsaXZlciB1bnRpbCB0aGUgdmlzaWJpbGl0eSB3aW5kb3cgZXhwaXJlcy4gV2l0aFxuICogRmx1aWQgQ29tcHV0ZSBvbiBIb2JieSB0aGUgcGVyLWZ1bmN0aW9uIGNlaWxpbmcgcmlzZXMgdG8gMzAwcywgc3RpbGxcbiAqIHVuZGVyIHRoZSBkZWZhdWx0IGJ1ZGdldC5cbiAqXG4gKiBPdmVycmlkZSB2aWEgdGhlIGBXT1JLRkxPV19SRVBMQVlfVElNRU9VVF9NU2AgZW52IHZhciAoY2xhbXBlZCB0b1xuICogYE1JTl9SRVBMQVlfVElNRU9VVF9NU2AuLmBNQVhfUkVQTEFZX1RJTUVPVVRfTVNgKS5cbiAqL1xuZXhwb3J0IGNvbnN0IFJFUExBWV9USU1FT1VUX01TID0gMjQwXzAwMDtcblxuLyoqIExvd2VyIGJvdW5kIGZvciB0aGUgcmVwbGF5LXRpbWVvdXQgZW52IHZhciBvdmVycmlkZS4gKi9cbmV4cG9ydCBjb25zdCBNSU5fUkVQTEFZX1RJTUVPVVRfTVMgPSAzMF8wMDA7XG5cbi8qKlxuICogVXBwZXIgYm91bmQgZm9yIHRoZSByZXBsYXktdGltZW91dCBlbnYgdmFyIG92ZXJyaWRlLiA3ODBzIGxlYXZlcyDiiaUyMHMgb2ZcbiAqIGhlYWRyb29tIHVuZGVyIFZlcmNlbCBQcm8gRmx1aWQncyA4MDBzIGZ1bmN0aW9uIGNlaWxpbmcgc28gdGhlIGhhbmRsZXJcbiAqIGNhbiB3cml0ZSBgcnVuX2ZhaWxlZGAgYmVmb3JlIFNJR1RFUk0uXG4gKi9cbmV4cG9ydCBjb25zdCBNQVhfUkVQTEFZX1RJTUVPVVRfTVMgPSA3ODBfMDAwO1xuXG4vLyBUcmFjayB3aGljaCByYXcgZW52IHZhciB2YWx1ZXMgd2UndmUgYWxyZWFkeSB3YXJuZWQgYWJvdXQgc28gdGhlIHdhcm5pbmdcbi8vIGxvZyBvbmx5IGZpcmVzIG9uY2UgcGVyIHByb2Nlc3MgKHRoZSBmdW5jdGlvbiBtYXkgYmUgY2FsbGVkIG1hbnkgdGltZXMpLlxuLy9cbi8vIE9uIGBnbG9iYWxUaGlzYCByYXRoZXIgdGhhbiBhdCBtb2R1bGUgc2NvcGUgc28gXCJvbmNlIHBlciBwcm9jZXNzXCIgc3Vydml2ZXNcbi8vIGJ1bmRsaW5nOiB0aGlzIHBhY2thZ2UgaXMgY29tcGlsZWQgaW50byB0aGUgaG9zdCBhcHBsaWNhdGlvbidzIHNlcnZlciBidWlsZFxuLy8gb25jZSBwZXIgYnVuZGxlciBsYXllciwgYW5kIHBlci1jb3B5IHNldHMgd2FybiBvbmNlIHBlciBsYXllciBpbnN0ZWFkLlxuY29uc3Qgd2FybmVkID0gZ2xvYmFsU2luZ2xldG9uKCdAd29ya2Zsb3cvY29yZS8vZW52V2FybmluZ3MnLCAxLCAoKSA9PiAoe1xuICByZXBsYXlUaW1lb3V0VmFsdWVzOiBuZXcgU2V0PHN0cmluZz4oKSxcbiAgbWF4SW5saW5lU3RlcHNWYWx1ZXM6IG5ldyBTZXQ8c3RyaW5nPigpLFxuICBtYXhFdmVudHNWYWx1ZXM6IG5ldyBTZXQ8c3RyaW5nPigpLFxufSkpO1xuXG5mdW5jdGlvbiB3YXJuT25jZShcbiAgcmF3OiBzdHJpbmcsXG4gIG1lc3NhZ2U6IHN0cmluZyxcbiAgZGF0YTogUmVjb3JkPHN0cmluZywgdW5rbm93bj5cbik6IHZvaWQge1xuICBpZiAod2FybmVkLnJlcGxheVRpbWVvdXRWYWx1ZXMuaGFzKHJhdykpIHJldHVybjtcbiAgd2FybmVkLnJlcGxheVRpbWVvdXRWYWx1ZXMuYWRkKHJhdyk7XG4gIHJ1bnRpbWVMb2dnZXIud2FybihtZXNzYWdlLCBkYXRhKTtcbn1cblxuLyoqXG4gKiBSZXNvbHZlIHRoZSBlZmZlY3RpdmUgcmVwbGF5LXRpbWVvdXQgYnVkZ2V0IGZvciB0aGUgY3VycmVudCBwcm9jZXNzLlxuICpcbiAqIFJlYWRzIGBwcm9jZXNzLmVudi5XT1JLRkxPV19SRVBMQVlfVElNRU9VVF9NU2AgbGF6aWx5IHNvIHRlc3RzIGFuZFxuICogZGVwbG95bWVudHMgY2FuIG92ZXJyaWRlIHBlciBpbnZvY2F0aW9uLiBJbnZhbGlkIC8gb3V0LW9mLXJhbmdlIHZhbHVlc1xuICogZmFsbCBiYWNrIHRvIGEgc2FmZSB2YWx1ZSAobm8gdGhyb3c6IHRoZSBlbnYgdmFyIGlzIGFuIGVzY2FwZSBoYXRjaCxcbiAqIG5vdCBhIGhhcmQgcmVxdWlyZW1lbnQpIGFuZCBlbWl0IGEgb25lLXRpbWUgd2FybmluZyBzbyBtaXNjb25maWd1cmF0aW9uXG4gKiBpcyBvYnNlcnZhYmxlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0UmVwbGF5VGltZW91dE1zKCk6IG51bWJlciB7XG4gIGNvbnN0IHJhdyA9IHByb2Nlc3MuZW52LldPUktGTE9XX1JFUExBWV9USU1FT1VUX01TO1xuICBpZiAoIXJhdykgcmV0dXJuIFJFUExBWV9USU1FT1VUX01TO1xuICBjb25zdCBwYXJzZWQgPSBOdW1iZXIocmF3KTtcbiAgaWYgKCFOdW1iZXIuaXNGaW5pdGUocGFyc2VkKSB8fCBwYXJzZWQgPD0gMCkge1xuICAgIHdhcm5PbmNlKFxuICAgICAgcmF3LFxuICAgICAgJ0lnbm9yaW5nIFdPUktGTE9XX1JFUExBWV9USU1FT1VUX01TOiBub3QgYSBwb3NpdGl2ZSBmaW5pdGUgbnVtYmVyOyB1c2luZyBkZWZhdWx0JyxcbiAgICAgIHsgcmF3LCBkZWZhdWx0TXM6IFJFUExBWV9USU1FT1VUX01TIH1cbiAgICApO1xuICAgIHJldHVybiBSRVBMQVlfVElNRU9VVF9NUztcbiAgfVxuICBpZiAocGFyc2VkIDwgTUlOX1JFUExBWV9USU1FT1VUX01TKSB7XG4gICAgd2Fybk9uY2UocmF3LCAnV09SS0ZMT1dfUkVQTEFZX1RJTUVPVVRfTVMgYmVsb3cgbWluaW11bTsgY2xhbXBlZCcsIHtcbiAgICAgIHJhdyxcbiAgICAgIGNsYW1wZWRNczogTUlOX1JFUExBWV9USU1FT1VUX01TLFxuICAgICAgbWluTXM6IE1JTl9SRVBMQVlfVElNRU9VVF9NUyxcbiAgICB9KTtcbiAgICByZXR1cm4gTUlOX1JFUExBWV9USU1FT1VUX01TO1xuICB9XG4gIGlmIChwYXJzZWQgPiBNQVhfUkVQTEFZX1RJTUVPVVRfTVMpIHtcbiAgICB3YXJuT25jZShyYXcsICdXT1JLRkxPV19SRVBMQVlfVElNRU9VVF9NUyBhYm92ZSBtYXhpbXVtOyBjbGFtcGVkJywge1xuICAgICAgcmF3LFxuICAgICAgY2xhbXBlZE1zOiBNQVhfUkVQTEFZX1RJTUVPVVRfTVMsXG4gICAgICBtYXhNczogTUFYX1JFUExBWV9USU1FT1VUX01TLFxuICAgIH0pO1xuICAgIHJldHVybiBNQVhfUkVQTEFZX1RJTUVPVVRfTVM7XG4gIH1cbiAgcmV0dXJuIHBhcnNlZDtcbn1cblxuLyoqXG4gKiBSZXNldCB0aGUgd2Fybi1vbmNlIGNhY2hlLiBUZXN0LW9ubHk6IGV4cG9ydGVkIHNvIHVuaXQgdGVzdHMgY2FuXG4gKiBleGVyY2lzZSB0aGUgd2FybiBwYXRoIHJlcGVhdGVkbHkgd2l0aG91dCBzaGFyaW5nIHN0YXRlLlxuICpcbiAqIEBpbnRlcm5hbFxuICovXG5leHBvcnQgZnVuY3Rpb24gX3Jlc2V0UmVwbGF5VGltZW91dFdhcm5DYWNoZUZvclRlc3RzKCk6IHZvaWQge1xuICB3YXJuZWQucmVwbGF5VGltZW91dFZhbHVlcy5jbGVhcigpO1xufVxuXG4vLyBOdW1iZXIgb2YgcXVldWUgZGVsaXZlcnkgYXR0ZW1wdHMgdG8gYWxsb3cgYmVmb3JlIHBlcm1hbmVudGx5IGZhaWxpbmcgYSBydW5cbi8vIGR1ZSB0byBhIHJlcGxheSB0aW1lb3V0LiBPbiBhdHRlbXB0cyAxIHRocm91Z2ggdGhpcyB2YWx1ZSwgdGhlIHRpbWVvdXRcbi8vIGhhbmRsZXIgcmVqZWN0cyB3aXRob3V0IHdyaXRpbmcgcnVuX2ZhaWxlZCBzbyB0aGUgcXVldWUgcmV0cmllcyB0aGUgbWVzc2FnZS5cbi8vIE9uIHRoZSBuZXh0IGF0dGVtcHQgdGhlIHJ1biBpcyBtYXJrZWQgYXMgZmFpbGVkLlxuZXhwb3J0IGNvbnN0IFJFUExBWV9USU1FT1VUX01BWF9SRVRSSUVTID0gMztcblxuLyoqXG4gKiBFZmZlY3RpdmUgcmVwbGF5LXRpbWVvdXQgcmV0cnkgYnVkZ2V0LiBPdmVycmlkZSB2aWFcbiAqIGBXT1JLRkxPV19SRVBMQVlfVElNRU9VVF9NQVhfUkVUUklFU2AuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRSZXBsYXlUaW1lb3V0TWF4UmV0cmllcygpOiBudW1iZXIge1xuICByZXR1cm4gZW52TnVtYmVyKFxuICAgICdXT1JLRkxPV19SRVBMQVlfVElNRU9VVF9NQVhfUkVUUklFUycsXG4gICAgUkVQTEFZX1RJTUVPVVRfTUFYX1JFVFJJRVMsXG4gICAgeyBpbnRlZ2VyOiB0cnVlIH1cbiAgKTtcbn1cblxuLyoqXG4gKiBEZWZhdWx0IG1heGltdW0gbnVtYmVyIG9mIHN0ZXBzIHRoZSBvd25lZC1pbmxpbmUgcGF0aCBydW5zIGlubGluZSAoaW5cbiAqIHBhcmFsbGVsKSBwZXIgc3VzcGVuc2lvbi4gVGhlIHJlc3QgYXJlIHF1ZXVlZCB0byBiYWNrZ3JvdW5kIGhhbmRsZXJzLiBFYWNoXG4gKiBpbmxpbmUgc3RlcCBpcyBjcmVhdGVkIGxhemlseSAoaXRzIGBzdGVwX2NyZWF0ZWRgIGlzIGZvbGRlZCBpbnRvIHRoZVxuICogYHN0ZXBfc3RhcnRlZGAgdGhhdCBgZXhlY3V0ZVN0ZXBgIHNlbmRzKSwgc28gaW5saW5pbmcgTiBzdGVwcyBzYXZlcyBOIHF1ZXVlXG4gKiByb3VuZC10cmlwcyBmb3IgYSBgUHJvbWlzZS5hbGxgLXN0eWxlIGZhbi1vdXQuIGAxYCByZXByb2R1Y2VzIHRoZVxuICogc2luZ2xlLWlubGluZS1zdGVwIGJlaGF2aW9yIGV4YWN0bHkgKHVzZWZ1bCBraWxsLXN3aXRjaCkuXG4gKlxuICogT3ZlcnJpZGUgdmlhIGBXT1JLRkxPV19NQVhfSU5MSU5FX1NURVBTYCAoY2xhbXBlZCB0b1xuICogYE1JTl9NQVhfSU5MSU5FX1NURVBTYC4uYE1BWF9NQVhfSU5MSU5FX1NURVBTYCkuXG4gKi9cbmV4cG9ydCBjb25zdCBNQVhfSU5MSU5FX1NURVBTID0gMztcblxuLyoqIExvd2VyIGJvdW5kIGZvciB0aGUgaW5saW5lLXN0ZXBzIGVudiBvdmVycmlkZSAoMSA9IHNpbmdsZSBpbmxpbmUgc3RlcCkuICovXG5leHBvcnQgY29uc3QgTUlOX01BWF9JTkxJTkVfU1RFUFMgPSAxO1xuXG4vKipcbiAqIFVwcGVyIGJvdW5kIGZvciB0aGUgaW5saW5lLXN0ZXBzIGVudiBvdmVycmlkZS4gSW5saW5lIGJvZGllcyBydW4gaW4gcGFyYWxsZWxcbiAqIHdpdGhpbiBvbmUgZnVuY3Rpb24gaW52b2NhdGlvbiwgc28gdGhpcyBjYXBzIG1lbW9yeS9DUFUgZmFuLW91dCBwZXIgaGFuZGxlci5cbiAqL1xuZXhwb3J0IGNvbnN0IE1BWF9NQVhfSU5MSU5FX1NURVBTID0gMTY7XG5cbi8qKlxuICogUmVzb2x2ZSB0aGUgZWZmZWN0aXZlIG1heCBudW1iZXIgb2YgaW5saW5lIHN0ZXBzIGZvciB0aGUgY3VycmVudCBwcm9jZXNzLlxuICpcbiAqIFJlYWRzIGBwcm9jZXNzLmVudi5XT1JLRkxPV19NQVhfSU5MSU5FX1NURVBTYCBsYXppbHkgc28gdGVzdHMgYW5kXG4gKiBkZXBsb3ltZW50cyBjYW4gb3ZlcnJpZGUgcGVyIGludm9jYXRpb24uIEludmFsaWQgLyBvdXQtb2YtcmFuZ2UgdmFsdWVzIGZhbGxcbiAqIGJhY2sgdG8gYSBzYWZlIHZhbHVlIChubyB0aHJvdzogdGhlIGVudiB2YXIgaXMgYW4gZXNjYXBlIGhhdGNoKSBhbmQgZW1pdCBhXG4gKiBvbmUtdGltZSB3YXJuaW5nIHNvIG1pc2NvbmZpZ3VyYXRpb24gaXMgb2JzZXJ2YWJsZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldE1heElubGluZVN0ZXBzKCk6IG51bWJlciB7XG4gIGNvbnN0IHJhdyA9IHByb2Nlc3MuZW52LldPUktGTE9XX01BWF9JTkxJTkVfU1RFUFM7XG4gIGlmICghcmF3KSByZXR1cm4gTUFYX0lOTElORV9TVEVQUztcbiAgY29uc3QgcGFyc2VkID0gTnVtYmVyKHJhdyk7XG4gIGlmICghTnVtYmVyLmlzSW50ZWdlcihwYXJzZWQpIHx8IHBhcnNlZCA8PSAwKSB7XG4gICAgaWYgKCF3YXJuZWQubWF4SW5saW5lU3RlcHNWYWx1ZXMuaGFzKHJhdykpIHtcbiAgICAgIHdhcm5lZC5tYXhJbmxpbmVTdGVwc1ZhbHVlcy5hZGQocmF3KTtcbiAgICAgIHJ1bnRpbWVMb2dnZXIud2FybihcbiAgICAgICAgJ0lnbm9yaW5nIFdPUktGTE9XX01BWF9JTkxJTkVfU1RFUFM6IG5vdCBhIHBvc2l0aXZlIGludGVnZXI7IHVzaW5nIGRlZmF1bHQnLFxuICAgICAgICB7IHJhdywgZGVmYXVsdFZhbHVlOiBNQVhfSU5MSU5FX1NURVBTIH1cbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiBNQVhfSU5MSU5FX1NURVBTO1xuICB9XG4gIGlmIChwYXJzZWQgPCBNSU5fTUFYX0lOTElORV9TVEVQUykgcmV0dXJuIE1JTl9NQVhfSU5MSU5FX1NURVBTO1xuICBpZiAocGFyc2VkID4gTUFYX01BWF9JTkxJTkVfU1RFUFMpIHtcbiAgICBpZiAoIXdhcm5lZC5tYXhJbmxpbmVTdGVwc1ZhbHVlcy5oYXMocmF3KSkge1xuICAgICAgd2FybmVkLm1heElubGluZVN0ZXBzVmFsdWVzLmFkZChyYXcpO1xuICAgICAgcnVudGltZUxvZ2dlci53YXJuKCdXT1JLRkxPV19NQVhfSU5MSU5FX1NURVBTIGFib3ZlIG1heGltdW07IGNsYW1wZWQnLCB7XG4gICAgICAgIHJhdyxcbiAgICAgICAgY2xhbXBlZFZhbHVlOiBNQVhfTUFYX0lOTElORV9TVEVQUyxcbiAgICAgICAgbWF4VmFsdWU6IE1BWF9NQVhfSU5MSU5FX1NURVBTLFxuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiBNQVhfTUFYX0lOTElORV9TVEVQUztcbiAgfVxuICByZXR1cm4gcGFyc2VkO1xufVxuXG4vKipcbiAqIFVwcGVyIGJvdW5kIG9uIHRoZSBzZXJpYWxpemVkIHN0ZXAgaW5wdXQgdGhhdCByZXNpbGllbnQgc3RlcCBkaXNwYXRjaCB3aWxsXG4gKiBpbmxpbmUgaW50byB0aGUgcXVldWUgbWVzc2FnZSdzIGBzdGVwSW5wdXRgLlxuICpcbiAqIFZlcmNlbCBRdWV1ZXMgaGFzIG5vIGhhcmQgbWVzc2FnZS1zaXplIGNhcCAoYm9kaWVzIGFib3ZlIGl0cyB+MjU2IEtCXG4gKiBpbmxpbmUgdGhyZXNob2xkIHRyYW5zcGFyZW50bHkgc3BpbGwgdG8gUzMtYmFja2VkIHN0b3JhZ2UpLCBzbyB0aGlzIGJvdW5kXG4gKiBpcyBhIGNvc3QvbGF0ZW5jeSBjaG9pY2UsIG5vdCBhIHJlamVjdGlvbiBndWFyZDogdGhlIG1lc3NhZ2UgYWxzbyBjYXJyaWVzXG4gKiB0aGUgcnVuSWQsIHN0ZXBJZCwgc3RlcE5hbWUsIGFuZCB0cmFjZSBjYXJyaWVyIGFsb25nc2lkZSBDQk9SIGZyYW1pbmdcbiAqIG92ZXJoZWFkLCBhbmQgc3RheWluZyB1bmRlciB0aGUgcXVldWUncyBpbmxpbmUgdGhyZXNob2xkIGtlZXBzIHN0ZXBcbiAqIG1lc3NhZ2VzIG9uIGl0cyBmYXN0IGlubGluZSBwYXRoIGluc3RlYWQgb2YgcGF5aW5nIGFuIFMzIHN0b3JlK2ZldGNoXG4gKiBkb3VibGUtaG9wIGZvciBieXRlcyB0aGF0IGFscmVhZHkgbGl2ZSBpbiB0aGUgZXZlbnQgbG9nLiBBYm92ZSB0aGlzIHNpemVcbiAqIHRoZSBkaXNwYXRjaCBmYWxscyBiYWNrIHRvIHRoZSBzZXF1ZW50aWFsIHBhdGggKGBzdGVwX2NyZWF0ZWRgIHdyaXRlLCB0aGVuXG4gKiBhIHBheWxvYWQtbGVzcyBxdWV1ZSBtZXNzYWdlKS4gTWF0Y2hlcyBgTUFYX0lOTElORV9SRVNVTUVfUEFZTE9BRF9CWVRFU2BcbiAqIG9uIHRoZSByZXNpbGllbnQgaG9vayByZXN1bWUgcGF0aC5cbiAqL1xuZXhwb3J0IGNvbnN0IE1BWF9SRVNJTElFTlRfU1RFUF9JTlBVVF9CWVRFUyA9IDEyOCAqIDEwMjQ7XG5cbi8qKlxuICogV2hldGhlciByZXNpbGllbnQgc3RlcCBkaXNwYXRjaCBpcyBlbmFibGVkOiB0aGUgc3VzcGVuc2lvbiBoYW5kbGVyXG4gKiBwYXJhbGxlbGl6ZXMgZWFjaCBuZXdseSBjcmVhdGVkIHN0ZXAncyBgc3RlcF9jcmVhdGVkYCBldmVudCB3cml0ZSB3aXRoIGl0c1xuICogc3RlcC1leGVjdXRpb24gcXVldWUgcHVibGlzaCwgY2FycnlpbmcgdGhlIHNlcmlhbGl6ZWQgc3RlcCBpbnB1dCBpbiB0aGVcbiAqIHF1ZXVlIG1lc3NhZ2UgKGBzdGVwSW5wdXRgKSBzbyB0aGUgY29uc3VtZXIgY2FuIGlkZW1wb3RlbnRseSByZS1lbnN1cmUgdGhlXG4gKiBldmVudCBpZiB0aGUgZGlyZWN0IHdyaXRlIGZhaWxlZCB0cmFuc2llbnRseS4gTWlycm9ycyB0aGUgcmVzaWxpZW50IHN0YXJ0XG4gKiAoYHJ1bklucHV0YCkgYW5kIHJlc2lsaWVudCBob29rIHJlc3VtZSAoYGhvb2tJbnB1dGApIHBhdHRlcm5zLlxuICpcbiAqICoqT2ZmIGJ5IGRlZmF1bHQuKiogRW5hYmxlIHZpYSBgV09SS0ZMT1dfUkVTSUxJRU5UX1NURVBfRElTUEFUQ0g9MWAuXG4gKlxuICogVGhlIHF1ZXVlIHB1Ymxpc2ggcmFjZXMgdGhlIGNyZWF0ZSdzIHZlcmRpY3QsIGFuZCBhIGNyZWF0ZSBjYW4gY29tZSBiYWNrXG4gKiByZWZ1c2VkOiBhcyBhIGR1cGxpY2F0ZSB0aGlzIHJlcGxheSBzaG91bGQgc3RvcCBwdXJzdWluZywgb3IgYXMgYSBzdGFsZVxuICogd3JpdGUgb24gYSBXb3JsZCB0aGF0IHJlZnVzZXMgcmF0aGVyIHRoYW4gcmVwb3J0cy4gRWl0aGVyIHdheSB0aGUgbWVzc2FnZVxuICogY2FycnlpbmcgdGhlIHBheWxvYWQgaXMgYWxyZWFkeSBvdXQsIHNvIHRoZSBjb25zdW1lciBjYW4gbWF0ZXJpYWxpemUgYSBzdGVwXG4gKiB3aG9zZSBjcmVhdGUgd2FzIHJlZnVzZWQsIGFuZCBub3RoaW5nIG9yZGVycyB0aGUgdmVyZGljdCBiZWZvcmUgdGhlXG4gKiBjb25zdW1lcidzIHJlZGVsaXZlcnkgcmUtZW5zdXJlLiBFbmFibGluZyB0aGlzIHRyYWRlcyB0aGF0IHdpbmRvdyBmb3IgdGhlXG4gKiBsYXRlbmN5IHRoZSBwYXJhbGxlbCBwdWJsaXNoIHNhdmVzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNSZXNpbGllbnRTdGVwRGlzcGF0Y2hFbmFibGVkKCk6IGJvb2xlYW4ge1xuICByZXR1cm4gcHJvY2Vzcy5lbnYuV09SS0ZMT1dfUkVTSUxJRU5UX1NURVBfRElTUEFUQ0ggPT09ICcxJztcbn1cblxuLyoqXG4gKiBXaGV0aGVyIGJhdGNoZWQgZXZlbnQgdHJhbnNpdGlvbnMgYXJlIGVuYWJsZWQ6IHRoZSBzdXNwZW5zaW9uIGhhbmRsZXIgZm9sZHNcbiAqIGEgY2xlYW4gZmFuLW91dCdzIGBzdGVwX2NyZWF0ZWRgICsgYHdhaXRfY3JlYXRlZGAgd3JpdGVzIGludG8gb25lXG4gKiBgd29ybGQuZXZlbnRzLmNyZWF0ZUJhdGNoYCBjYWxsIChvbmUgZHVyYWJsZSB3cml0ZSwgcGVyLWV2ZW50IG91dGNvbWVzKVxuICogaW5zdGVhZCBvZiBvbmUgd3JpdGUgcGVyIGV2ZW50LiBPbmx5IGVuZ2FnZXMgd2hlbiB0aGUgV29ybGQgaW1wbGVtZW50cyB0aGVcbiAqIG9wdGlvbmFsIGBldmVudHMuY3JlYXRlQmF0Y2hgIEFORCB0aGUgcnVuIGlzIG9uIHNsb3QgaWRlbnRpdHlcbiAqIChzcGVjVmVyc2lvbiA+PSA2KSBBTkQgdGhlIHN1c3BlbnNpb24gY2FycmllcyBubyBhdHRyaWJ1dGUvaG9vayB3cml0ZXMgYW5kXG4gKiBubyByZXNpbGllbnQgc3RlcCBkaXNwYXRjaC4gRXZlcnl0aGluZyBlbHNlIGtlZXBzIHRoZSBzaW5nbGUtZXZlbnQgcGF0aFxuICogYnl0ZS1mb3ItYnl0ZS5cbiAqXG4gKiBSZWFkcyBgcHJvY2Vzcy5lbnYuV09SS0ZMT1dfQkFUQ0hfVFJBTlNJVElPTlNgIGxhemlseS4gRGVmYXVsdCAqKk9OKio7XG4gKiBkaXNhYmxlZCBvbmx5IGJ5IGFuIGV4cGxpY2l0IGAnMCdgIC8gYCdmYWxzZSdgIChjYXNlLWluc2Vuc2l0aXZlKSwgdGhlXG4gKiBvcGVyYXRvciBlc2NhcGUgaGF0Y2ggdGhhdCByZXN0b3JlcyB0aGUgZXhhY3QgcHJpb3Igb25lLXdyaXRlLXBlci1ldmVudFxuICogcGF0aCwgbWlycm9yaW5nIGBXT1JLRkxPV19UVVJCT2AncyBraWxsLXN3aXRjaCBzaGFwZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzQmF0Y2hUcmFuc2l0aW9uc0VuYWJsZWQoKTogYm9vbGVhbiB7XG4gIGNvbnN0IHJhdyA9IHByb2Nlc3MuZW52LldPUktGTE9XX0JBVENIX1RSQU5TSVRJT05TO1xuICBpZiAocmF3ID09PSB1bmRlZmluZWQgfHwgcmF3ID09PSAnJykgcmV0dXJuIHRydWU7XG4gIHJldHVybiAhKHJhdyA9PT0gJzAnIHx8IHJhdy50b0xvd2VyQ2FzZSgpID09PSAnZmFsc2UnKTtcbn1cblxuLyoqXG4gKiBDZWlsaW5nIG9uIGV2ZW50cyBwZXIgYGNyZWF0ZUJhdGNoYCBjYWxsIGZyb20gdGhlIGJhdGNoZWQgZmFuLW91dCBmb2xkLlxuICogTWlycm9ycyB0aGUgc2VydmVyJ3MgdHJhbnNhY3Rpb24gYnVkZ2V0cyB3aXRoIGEgY29tZm9ydGFibGUgbWFyZ2luOiBlYWNoXG4gKiBmYW4tb3V0IGV2ZW50IGNvc3RzIDIgdHJhbnNhY3Rpb24gaXRlbXMgc2VydmVyLXNpZGUgKGVudGl0eSArIGV2ZW50IHJvdylcbiAqIGFnYWluc3QgdGhlIDEwMC1pdGVtIER5bmFtb0RCIGNhcCwgYW5kIGlubGluZSBwYXlsb2FkcyBjb3VudCBhZ2FpbnN0IGFcbiAqIDc2OCBLQiBieXRlIGJ1ZGdldCwgc28gMzIgZXZlbnRzIHN0YXlzIHdlbGwgdW5kZXIgYm90aCwgYW5kIGEgZmFuLW91dCBsYXJnZXJcbiAqIHRoYW4gdGhpcyBjb21taXRzIGluIHN1Y2Nlc3NpdmUgYmF0Y2hlcyAoc3BsaXQgYmF0Y2hlcyBsb3NlXG4gKiBjcm9zcy1iYXRjaCBhdG9taWNpdHksIHdoaWNoIGlzIGV4YWN0bHkgdG9kYXkncyBwZXItZXZlbnQtd3JpdGUgY3Jhc2hcbiAqIHN1cmZhY2UsIGFuZCBldmVyeSBiYXRjaCBzdGlsbCBjb252ZXJnZXMgb24gcmV0cnkgdmlhIHBlci1ldmVudCA0MDlzKS5cbiAqL1xuZXhwb3J0IGNvbnN0IE1BWF9CQVRDSF9GQU5PVVRfRVZFTlRTID0gMzI7XG5cbi8qKlxuICogT3B0aW9uYWwgY2xpZW50LXNpZGUgb3ZlcnJpZGUgZm9yIHRoZSBzZXJ2ZXItc3VwcGxpZWQgcGVyLXJ1biBldmVudCBjZWlsaW5nLlxuICogV2hlbiBzZXQgdG8gYSBwb3NpdGl2ZSBpbnRlZ2VyLCB0aGUgcnVudGltZSBjbGFtcHMgdGhlIHNlcnZlcidzIGxpbWl0ICpkb3duKlxuICogdG8gdGhpcyB2YWx1ZSAobmV2ZXIgcmFpc2VzIGl0KSBzbyBlbmZvcmNlbWVudCBjYW4gYmUgZXhlcmNpc2VkIHdpdGhvdXQgYVxuICogc2VydmVyLXNpZGUgY2hhbmdlLiBgdW5kZWZpbmVkYCAodW5zZXQpIOKHkiB1c2UgdGhlIHNlcnZlciB2YWx1ZSBhcy1pcy5cbiAqXG4gKiBSZWFkcyBgcHJvY2Vzcy5lbnYuV09SS0ZMT1dfTUFYX0VWRU5UU19PVkVSUklERWAgbGF6aWx5IHNvIHRlc3RzIGFuZFxuICogZGVwbG95bWVudHMgY2FuIG92ZXJyaWRlIHBlciBpbnZvY2F0aW9uLiBJbnZhbGlkIHZhbHVlcyBmYWxsIGJhY2sgdG8gdW5zZXRcbiAqIChubyB0aHJvdzogdGhlIGVudiB2YXIgaXMgYW4gZXNjYXBlIGhhdGNoKSBhbmQgZW1pdCBhIG9uZS10aW1lIHdhcm5pbmcuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRNYXhFdmVudHNPdmVycmlkZSgpOiBudW1iZXIgfCB1bmRlZmluZWQge1xuICBjb25zdCByYXcgPSBwcm9jZXNzLmVudi5XT1JLRkxPV19NQVhfRVZFTlRTX09WRVJSSURFO1xuICBpZiAoIXJhdykgcmV0dXJuIHVuZGVmaW5lZDtcbiAgY29uc3QgcGFyc2VkID0gTnVtYmVyKHJhdyk7XG4gIGlmICghTnVtYmVyLmlzSW50ZWdlcihwYXJzZWQpIHx8IHBhcnNlZCA8PSAwKSB7XG4gICAgaWYgKCF3YXJuZWQubWF4RXZlbnRzVmFsdWVzLmhhcyhyYXcpKSB7XG4gICAgICB3YXJuZWQubWF4RXZlbnRzVmFsdWVzLmFkZChyYXcpO1xuICAgICAgcnVudGltZUxvZ2dlci53YXJuKFxuICAgICAgICAnSWdub3JpbmcgV09SS0ZMT1dfTUFYX0VWRU5UU19PVkVSUklERTogbm90IGEgcG9zaXRpdmUgaW50ZWdlcjsgdXNpbmcgc2VydmVyIGxpbWl0JyxcbiAgICAgICAgeyByYXcgfVxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICByZXR1cm4gcGFyc2VkO1xufVxuXG4vKipcbiAqIFdoZXRoZXIgb3B0aW1pc3RpYyBpbmxpbmUgc3RlcCBzdGFydCBpcyBlbmFibGVkLiBXaGVuIG9uLCB0aGUgb3duZWQtaW5saW5lXG4gKiBwYXRoIGJlZ2lucyBydW5uaW5nIGEgYnJhbmQtbmV3IHN0ZXAncyBib2R5ICpiZWZvcmUqIGl0cyBsYXp5IGBzdGVwX3N0YXJ0ZWRgXG4gKiBuZXR3b3JrIGNhbGwgcmVzb2x2ZXMgKHRoZSBpbnB1dCBpcyBhbHJlYWR5IGtub3duIGxvY2FsbHkpLCBhd2FpdGluZyB0aGVcbiAqIGBzdGVwX3N0YXJ0ZWRgIG9ubHkgYmVmb3JlIHRoZSB0ZXJtaW5hbCB3cml0ZS5cbiAqXG4gKiBUaGlzIGNhbiBydW4gYSBzdGVwIGJvZHkgbW9yZSB0aGFuIG9uY2Ugd2hlbiBoYW5kbGVycyByYWNlIGZvciB0aGUgc2FtZVxuICogc3RlcCdzIGNyZWF0ZS1jbGFpbTogYm90aCBydW4gdGhlIGJvZHkgYmVmb3JlIG9uZSB3aW5zLiBUaGF0IGlzIHVuc2FmZSBmb3JcbiAqIHN0ZXBzIHdpdGggbm9uLWlkZW1wb3RlbnQgc2lkZSBlZmZlY3RzOyBpbiBwYXJ0aWN1bGFyLCB0d28gY29uY3VycmVudCBydW5zXG4gKiBvZiBhIHN0ZXAgdGhhdCB3cml0ZXMgdG8gdGhlIHdvcmtmbG93IHN0cmVhbSAoZS5nLiBhbiBBSSBhZ2VudCBzdHJlYW1pbmdcbiAqIHRva2VucykgY2FuIGludGVybGVhdmUgYW5kIGNvcnJ1cHQgdGhlIHN0cmVhbSBkYXRhLiBTbyB0aGUgb3B0aW1pemF0aW9uIGlzXG4gKiAqKm9mZiBieSBkZWZhdWx0KiogYW5kIG11c3QgYmUgZXhwbGljaXRseSBvcHRlZCBpbnRvIHBlciBkZXBsb3ltZW50LlxuICpcbiAqIFJlYWRzIGBwcm9jZXNzLmVudi5XT1JLRkxPV19PUFRJTUlTVElDX0lOTElORV9TVEFSVGAgbGF6aWx5LiBEZWZhdWx0IE9GRjtcbiAqIGVuYWJsZWQgb25seSBieSBhbiBleHBsaWNpdCBgJzEnYCAvIGAndHJ1ZSdgLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNPcHRpbWlzdGljSW5saW5lU3RhcnRFbmFibGVkKCk6IGJvb2xlYW4ge1xuICBjb25zdCByYXcgPSBwcm9jZXNzLmVudi5XT1JLRkxPV19PUFRJTUlTVElDX0lOTElORV9TVEFSVDtcbiAgaWYgKHJhdyA9PT0gdW5kZWZpbmVkIHx8IHJhdyA9PT0gJycpIHJldHVybiBmYWxzZTtcbiAgcmV0dXJuIHJhdyA9PT0gJzEnIHx8IHJhdy50b0xvd2VyQ2FzZSgpID09PSAndHJ1ZSc7XG59XG5cbi8qKlxuICogV2hldGhlciBhbiBvcGVyYXRvciBoYXMgKipleHBsaWNpdGx5IGRpc2FibGVkKiogb3B0aW1pc3RpYyBpbmxpbmUgc3RhcnQgdmlhXG4gKiBgV09SS0ZMT1dfT1BUSU1JU1RJQ19JTkxJTkVfU1RBUlQ9MGAgLyBgPWZhbHNlYC4gRGlzdGluY3QgZnJvbSBcInVuc2V0XCI6IHVuc2V0XG4gKiBsZWF2ZXMgdGhlIG9wdGltaXphdGlvbiBvZmYgYnkgZGVmYXVsdCBidXQgbGV0cyB0dXJibyBmb3JjZSBpdCBvbjsgYW4gZXhwbGljaXRcbiAqIGAwYC9gZmFsc2VgIGlzIGFuIG9wZXJhdG9yIG9wdC1vdXQgdGhhdCB0dXJibyBtdXN0IGhvbm9yICh0dXJibydzIGZvcmNlZFxuICogb3B0aW1pc3RpYyBzdGFydCBzdGlsbCBydW5zIGEgc3RlcCBib2R5IGJlZm9yZSBgc3RlcF9zdGFydGVkYC9gcnVuX3N0YXJ0ZWRgIGlzXG4gKiBjb25maXJtZWQsIHRoZSBwcm9wZXJ0eSBzdWNoIGFuIG9wZXJhdG9yIGlzIG9wdGluZyBvdXQgb2YpLCBzb1xuICogYGZvcmNlT3B0aW1pc3RpY1N0YXJ0YCBkZWZlcnMgdG8gdGhpcy4gUmVhZHMgdGhlIGVudiB2YXIgbGF6aWx5LlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNPcHRpbWlzdGljSW5saW5lU3RhcnRFeHBsaWNpdGx5RGlzYWJsZWQoKTogYm9vbGVhbiB7XG4gIGNvbnN0IHJhdyA9IHByb2Nlc3MuZW52LldPUktGTE9XX09QVElNSVNUSUNfSU5MSU5FX1NUQVJUO1xuICBpZiAocmF3ID09PSB1bmRlZmluZWQgfHwgcmF3ID09PSAnJykgcmV0dXJuIGZhbHNlO1xuICByZXR1cm4gcmF3ID09PSAnMCcgfHwgcmF3LnRvTG93ZXJDYXNlKCkgPT09ICdmYWxzZSc7XG59XG5cbi8qKlxuICogV2hldGhlciBcInR1cmJvIG1vZGVcIiBpcyBlbmFibGVkLiBUdXJibyBtb2RlIGZhc3QtcGF0aHMgdGhlICpmaXJzdCBkZWxpdmVyeSBvZlxuICogdGhlIGZpcnN0IGludm9jYXRpb24qIG9mIGEgcnVuIChkZXRlY3RlZCBieSB0aGUgZW50cnlwb2ludCB2aWEgYHJ1bklucHV0YFxuICogcHJlc2VuY2UgKyBgbWV0YWRhdGEuYXR0ZW1wdCA9PT0gMWApOiBpdCBiYWNrZ3JvdW5kcyB0aGUgYHJ1bl9zdGFydGVkYCBldmVudFxuICogY3JlYXRpb24sIHNraXBzIHRoZSBpbml0aWFsIGV2ZW50LWxvZyBsb2FkIChub3RoaW5nIGhhcyBiZWVuIHdyaXR0ZW4geWV0KSxcbiAqIGFuZCBmb3JjZXMgb3B0aW1pc3RpYyBpbmxpbmUgc3RlcCBzdGFydCBmb3IgdGhhdCBpbnZvY2F0aW9uLCBpbmRlcGVuZGVudCBvZlxuICogYFdPUktGTE9XX09QVElNSVNUSUNfSU5MSU5FX1NUQVJUYC5cbiAqXG4gKiBGb3JjaW5nIG9wdGltaXN0aWMgc3RhcnQgaXMgc2FmZSBoZXJlIGJlY2F1c2UgdGhlIGZpcnN0IGRlbGl2ZXJ5IGhhcyBub1xuICogY29uY3VycmVudCBwZWVyIGhhbmRsZXIgdG8gcmFjZSB0aGUgc3RlcCBjcmVhdGUtY2xhaW0sIHNvIGEgc3RlcCBib2R5IHJ1bnNcbiAqIGV4YWN0bHkgb25jZS4gVGhhdCBzaW5nbGUtaGFuZGxlciBndWFyYW50ZWUgZW5kcyBhcyBzb29uIGFzIHRoZSBydW4gY3JlYXRlcyBhXG4gKiBob29rIG9yIHdhaXQgKHdoaWNoIGludHJvZHVjZSByZXN1bWUvcGFyYWxsZWwgaW52b2NhdGlvbnMpLCBzbyB0aGUgcnVudGltZVxuICogZXhpdHMgdHVyYm8gYXQgdGhhdCBwb2ludC5cbiAqXG4gKiBSZWFkcyBgcHJvY2Vzcy5lbnYuV09SS0ZMT1dfVFVSQk9gIGxhemlseS4gRGVmYXVsdCAqKk9OKio7IGRpc2FibGVkIG9ubHkgYnkgYW5cbiAqIGV4cGxpY2l0IGAnMCdgIC8gYCdmYWxzZSdgIChjYXNlLWluc2Vuc2l0aXZlKS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzVHVyYm9FbmFibGVkKCk6IGJvb2xlYW4ge1xuICBjb25zdCByYXcgPSBwcm9jZXNzLmVudi5XT1JLRkxPV19UVVJCTztcbiAgaWYgKHJhdyA9PT0gdW5kZWZpbmVkIHx8IHJhdyA9PT0gJycpIHJldHVybiB0cnVlO1xuICByZXR1cm4gIShyYXcgPT09ICcwJyB8fCByYXcudG9Mb3dlckNhc2UoKSA9PT0gJ2ZhbHNlJyk7XG59XG5cbi8qKlxuICogV2hldGhlciB0aGUgUXVpY2tKUyBlbmdpbmUncyBiYXNlbGluZS1zbmFwc2hvdCBzdGFydHVwIG9wdGltaXphdGlvbiBpc1xuICogZW5hYmxlZCAoZGVmYXVsdCBPTikuIFdoZW4gb24sIHRoZSBlbmdpbmUgaHlkcmF0ZXMgYSBWTSB3aXRoIHRoZVxuICogd29ya2Zsb3cgYnVuZGxlIG9uY2UgcGVyIGZ1bmN0aW9uIGluc3RhbmNlLCBzbmFwc2hvdHMgaXQsIGFuZCBzdGFydHNcbiAqIGV2ZXJ5IGludm9jYXRpb24gYnkgcmVzdG9yaW5nIHRoZSBzbmFwc2hvdCBpbnN0ZWFkIG9mIHJlLWV2YWx1YXRpbmdcbiAqIHRoZSBidW5kbGUsIHNraXBwaW5nIHRoZSBkb21pbmFudCBzaGFyZSBvZiBWTSBzdGFydHVwIChtZWFzdXJlZFxuICogfjc3bXMg4oaSIH4zbXMgdG8gZmlyc3Qgc3VzcGVuc2lvbiBmb3IgYSAxLjNNQiBidW5kbGUpLiBCdW5kbGVzIHdob3NlXG4gKiBtb2R1bGUgc2NvcGUgY29uc3VtZXMgcmFuZG9tbmVzcywgcmVhZHMgdGhlIGNsb2NrLCBvciByZXBsYWNlcyBhXG4gKiBzZXJpYWxpemF0aW9uIGludHJpbnNpYyBhcmUgZGV0ZWN0ZWQgYXQgaHlkcmF0ZSB0aW1lIGFuZFxuICogYXV0b21hdGljYWxseSBmYWxsIGJhY2sgdG8gcGVyLWludm9jYXRpb24gZnJlc2ggZXZhbHVhdGlvbiAoc2VlXG4gKiBwcmVwYXJlQmFzZWxpbmVTbmFwc2hvdCkuIFNldCBXT1JLRkxPV19RVUlDS0pTX0JBU0VMSU5FX1NOQVBTSE9UPTAgdG9cbiAqIGRpc2FibGUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1F1aWNrSlNCYXNlbGluZVNuYXBzaG90RW5hYmxlZCgpOiBib29sZWFuIHtcbiAgY29uc3QgcmF3ID0gcHJvY2Vzcy5lbnYuV09SS0ZMT1dfUVVJQ0tKU19CQVNFTElORV9TTkFQU0hPVDtcbiAgaWYgKHJhdyA9PT0gdW5kZWZpbmVkIHx8IHJhdyA9PT0gJycpIHJldHVybiB0cnVlO1xuICByZXR1cm4gIShyYXcgPT09ICcwJyB8fCByYXcudG9Mb3dlckNhc2UoKSA9PT0gJ2ZhbHNlJyk7XG59XG5cbi8qKlxuICogV2hldGhlciB0aGUgaW5saW5lIGxvb3AgcmV0YWlucyBhIHN1c3BlbmRlZCB3b3JrZmxvdyBWTSBhY3Jvc3MgaW5saW5lIHN0ZXBzXG4gKiB3aXRoaW4gb25lIGludm9jYXRpb24gKGRlZmF1bHQgT04pLiBXaGVuIG9uLCBhIHN0ZXAtb25seSBzdXNwZW5zaW9uIGtlZXBzXG4gKiB0aGUgbGl2ZSBWTSwgZXZlbnQgY29uc3VtZXIsIGFuZCBoeWRyYXRlZCBzdGF0ZSBhbGl2ZSwgYW5kIHRoZSBuZXh0IGxvb3BcbiAqIGl0ZXJhdGlvbiBhcHBlbmRzIG9ubHkgdGhlIG5ld2x5IGR1cmFibGUgZXZlbnRzIGluc3RlYWQgb2YgcmVidWlsZGluZyB0aGVcbiAqIGB2bS5Db250ZXh0YCBhbmQgcmVwbGF5aW5nIHRoZSB3aG9sZSBldmVudCBsb2cuIE5vbi1zdGVwIHN1c3BlbnNpb25zIGFuZFxuICogcmVwbGF5IGRpdmVyZ2VuY2UgYWx3YXlzIGZhbGwgYmFjayB0byB0aGUgb3JkaW5hcnkgZHVyYWJsZSByZXBsYXkgcGF0aC5cbiAqXG4gKiBgV09SS0ZMT1dfUkVUQUlORURfVk09MGAgKG9yIGBmYWxzZWApIGlzIHRoZSBraWxsIHN3aXRjaDogZXZlcnkgaXRlcmF0aW9uXG4gKiByZXBsYXlzIGZyb20gc2NyYXRjaCBpbiBhIGZyZXNoIFZNLCBtYXRjaGluZyB0aGUgcHJlLXJldGVudGlvbiBiZWhhdmlvci5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzVm1SZXRlbnRpb25FbmFibGVkKCk6IGJvb2xlYW4ge1xuICBjb25zdCByYXcgPSBwcm9jZXNzLmVudi5XT1JLRkxPV19SRVRBSU5FRF9WTTtcbiAgaWYgKHJhdyA9PT0gdW5kZWZpbmVkIHx8IHJhdyA9PT0gJycpIHJldHVybiB0cnVlO1xuICByZXR1cm4gIShyYXcgPT09ICcwJyB8fCByYXcudG9Mb3dlckNhc2UoKSA9PT0gJ2ZhbHNlJyk7XG59XG5cbi8qKlxuICogV2hldGhlciBpbmxpbmUgc3RlcCBvd25lcnNoaXAgaXMgZW5hYmxlZCAoZGVmYXVsdCBPTikuIFdoZW4gb24sIHRoZSBsYXp5XG4gKiBgc3RlcF9zdGFydGVkYCB0aGF0IGNyZWF0ZXMgYW4gaW5saW5lIHN0ZXAgcmVjb3JkcyB0aGUgb3duaW5nIHF1ZXVlXG4gKiBtZXNzYWdlIElELCBhbmQgd2FrZSByZXBsYXlzIHRoYXQgb2JzZXJ2ZSBhbiBhY3RpdmVseS1vd25lZCBzdGVwIGVucXVldWUgYVxuICogKmRlbGF5ZWQgYmFja3N0b3AqIG1lc3NhZ2UgaW5zdGVhZCBvZiBpbW1lZGlhdGVseSByZXF1ZXVlaW5nIGl0LCBmaXhpbmdcbiAqIGR1cGxpY2F0ZSBpbmxpbmUgc3RlcCBleGVjdXRpb24gd2hlbiBhIGhvb2svd2FpdCB3YWtlcyBhIHJ1biBtaWQtc3RlcFxuICogKHZlcmNlbC93b3JrZmxvdyMyNzgwKS5cbiAqXG4gKiBgV09SS0ZMT1dfSU5MSU5FX09XTkVSU0hJUD0wYCAob3IgYGZhbHNlYCkgaXMgdGhlIGtpbGwgc3dpdGNoOiBkaXNwYXRjaFxuICogcmV2ZXJ0cyB0byB0aGUgdW5jb25kaXRpb25hbCBpbW1lZGlhdGUgcmVxdWV1ZS4gU3RhbXBpbmcgaXMgdW5hZmZlY3RlZDpcbiAqIHRoZSByZWNvcmRlZCBvd25lck1lc3NhZ2VJZCBpcyBpbmVydCBkYXRhIHdoZW4gdGhlIHN3aXRjaCBpcyBvZmYuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0lubGluZU93bmVyc2hpcEVuYWJsZWQoKTogYm9vbGVhbiB7XG4gIGNvbnN0IHJhdyA9IHByb2Nlc3MuZW52LldPUktGTE9XX0lOTElORV9PV05FUlNISVA7XG4gIGlmIChyYXcgPT09IHVuZGVmaW5lZCB8fCByYXcgPT09ICcnKSByZXR1cm4gdHJ1ZTtcbiAgcmV0dXJuICEocmF3ID09PSAnMCcgfHwgcmF3LnRvTG93ZXJDYXNlKCkgPT09ICdmYWxzZScpO1xufVxuXG4vKipcbiAqIERlZmF1bHQgaW5saW5lLW93bmVyc2hpcCBsZWFzZSwgaW4gc2Vjb25kczogaG93IGxvbmcgYWZ0ZXIgYSBzdGVwJ3MgbGF0ZXN0XG4gKiAoc3RhbXBlZCkgYHN0ZXBfc3RhcnRlZGAgYSBub24tb3duZXIgaW52b2NhdGlvbiBhc3N1bWVzIHRoZSBvd25pbmdcbiAqIGludm9jYXRpb24gbWF5IHN0aWxsIGJlIGFsaXZlLiBXaXRoaW4gdGhlIGxlYXNlLCB3YWtlIHJlcGxheXMgZW5xdWV1ZSB0aGVcbiAqIHN0ZXAncyBiYWNrc3RvcCBtZXNzYWdlIHdpdGggYGRlbGF5U2Vjb25kcyA9IGxlYXNlIHJlbWFpbmluZ2AgaW5zdGVhZCBvZlxuICogaW1tZWRpYXRlbHk7IHBhc3QgaXQsIHRoZXkgZW5xdWV1ZSBpbW1lZGlhdGVseSAodG9kYXkncyBiZWhhdmlvcikuXG4gKlxuICogV2h5IGEgZml4ZWQgODYwIGFuZCBub3QgYSB2YWx1ZSBkZXJpdmVkIGZyb20gdGhlIGZ1bmN0aW9uJ3MgYG1heER1cmF0aW9uYDpcbiAqIG5laXRoZXIgcnVudGltZSBub3IgYnVpbGQgdGltZSBjYW4gc2VlIHRoZSByZXNvbHZlZCB2YWx1ZTogYnVpbGRlcnMgZW1pdFxuICogYG1heER1cmF0aW9uOiAnbWF4J2AsIHdoaWNoIHRoZSBwbGF0Zm9ybSByZXNvbHZlcyBwZXItcGxhbiBhdCBkZXBsb3ksIGFuZFxuICogbm8gZW52IHZhciBvciByZXF1ZXN0LWNvbnRleHQgZGVhZGxpbmUgQVBJIGV4cG9zZXMgdGhlIHJlc3VsdC4gVGhlIGJvdW5kXG4gKiBjb21lcyBmcm9tIGEgcGxhdGZvcm0gcnVsZSBpbnN0ZWFkOiBkdXJhdGlvbnMgYWJvdmUgODAwcyByZXF1aXJlIGV4cGxpY2l0XG4gKiBwZXItZnVuY3Rpb24gbnVtZXJpYyBjb25maWcsIHNvIGEgYnVpbGRlci1lbWl0dGVkIGAnbWF4J2AgcmVzb2x2ZXMgdG8gYXRcbiAqIG1vc3QgODAwcywgYW5kIDg2MHMgdGhlcmVmb3JlIGRvbWluYXRlcyBhbnkgd29ya2Zsb3cgcm91dGUncyBpbnZvY2F0aW9uXG4gKiBsaWZldGltZSBwbHVzIHNjaGVkdWxpbmcgc2xhY2suIFJldmlzaXQgd2hlbiB0aGF0IGNlaWxpbmcgbW92ZXMgKHRoZVxuICogMzAtbWludXRlIGR1cmF0aW9uIGJldGEgYmVjb21pbmcgcmVhY2hhYmxlIHZpYSBgJ21heCdgIHdvdWxkIGludmFsaWRhdGVcbiAqIHRoZSBib3VuZCkuIFdvcmxkcyB3aXRob3V0IGFuIGludm9jYXRpb24ga2lsbCBib3VuZCAod29ybGQtbG9jYWwsXG4gKiBzZWxmLWhvc3RlZCkgZ2V0IG5vIGRlYXRoIHByb29mIGZyb20gYW55IGNvbnN0YW50LiBUaGVyZSB0aGUgaW4tcHJvY2Vzc1xuICogc2luZ2xlLWZsaWdodCBsYXllciAoc3RlcC1zaW5nbGUtZmxpZ2h0LnRzKSBpcyB3aGF0IG1ha2VzIGEgYmFja3N0b3BcbiAqIGZpcmluZyBtaWQtc3RlcCBoYXJtbGVzcy5cbiAqXG4gKiA4NjAgYWxzbyBzdGF5cyB1bmRlciB0aGUgcXVldWUncyA5MDBzIG1heGltdW0gZGVsYXkgKFNRUyBjYXApLCBzbyBhXG4gKiBiYWNrc3RvcCdzIGZ1bGwgbGVhc2UgcmVtYWluZGVyIGFsd2F5cyBmaXRzIGluIGEgc2luZ2xlIGRlbGF5ZWQgbWVzc2FnZS5cbiAqXG4gKiBPdmVycmlkZSB2aWEgYFdPUktGTE9XX0lOTElORV9PV05FUlNISVBfTEVBU0VfU0VDT05EU2AgKGNsYW1wZWQgdG9cbiAqIDEuLmBNQVhfSU5MSU5FX09XTkVSU0hJUF9MRUFTRV9TRUNPTkRTYCkuXG4gKi9cbmV4cG9ydCBjb25zdCBJTkxJTkVfT1dORVJTSElQX0xFQVNFX1NFQ09ORFMgPSA4NjA7XG5cbi8qKlxuICogVXBwZXIgYm91bmQgZm9yIHRoZSBsZWFzZSBlbnYgb3ZlcnJpZGUuIDkwMHMgaXMgdGhlIHF1ZXVlJ3MgbWF4aW11bVxuICogcGVyLW1lc3NhZ2UgZGVsYXkgKFNRUyBjYXApLiBBIGxvbmdlciBsZWFzZSB3b3VsZCBuZWVkIGRlbGF5IGNoYWluaW5nXG4gKiBsaWtlIGxvbmcgd2FpdHMgdXNlOyBjbGFtcCBpbnN0ZWFkIHNvIG9uZSBkZWxheWVkIG1lc3NhZ2UgYWx3YXlzIHN1ZmZpY2VzLlxuICovXG5leHBvcnQgY29uc3QgTUFYX0lOTElORV9PV05FUlNISVBfTEVBU0VfU0VDT05EUyA9IDkwMDtcblxuLyoqXG4gKiBFZmZlY3RpdmUgaW5saW5lLW93bmVyc2hpcCBsZWFzZS4gT3ZlcnJpZGUgdmlhXG4gKiBgV09SS0ZMT1dfSU5MSU5FX09XTkVSU0hJUF9MRUFTRV9TRUNPTkRTYCwgZS5nLiByYWlzZSBpdCBvbiBzZWxmLWhvc3RlZFxuICogbXVsdGktaW5zdGFuY2Ugd29ybGRzIHdpdGggbG9uZy1ydW5uaW5nIHN0ZXBzIHRvIHdpZGVuIHRoZSB3aW5kb3cgaW4gd2hpY2hcbiAqIGEgbGl2ZSBvd25lciBpcyBwcm90ZWN0ZWQgZnJvbSBhIGNvbmN1cnJlbnQgYmFja3N0b3AgZXhlY3V0aW9uLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0SW5saW5lT3duZXJzaGlwTGVhc2VTZWNvbmRzKCk6IG51bWJlciB7XG4gIHJldHVybiBlbnZOdW1iZXIoXG4gICAgJ1dPUktGTE9XX0lOTElORV9PV05FUlNISVBfTEVBU0VfU0VDT05EUycsXG4gICAgSU5MSU5FX09XTkVSU0hJUF9MRUFTRV9TRUNPTkRTLFxuICAgIHsgaW50ZWdlcjogdHJ1ZSwgbWluOiAxLCBtYXg6IE1BWF9JTkxJTkVfT1dORVJTSElQX0xFQVNFX1NFQ09ORFMgfVxuICApO1xufVxuXG4vLyBBIHJlcGxheS1jb25zdW1lciBtaXNtYXRjaCBjYW4gYmUgY2F1c2VkIGJ5IGEgdHJhbnNpZW50IGRpdmVyZ2VudCByZXBsYXlcbi8vIHJhdGhlciB0aGFuIGFuIGludmFsaWQgcGVyc2lzdGVkIGhpc3RvcnkuIFF1ZXVlIGJvdW5kZWQgcmVjb3ZlcnkgcmVwbGF5c1xuLy8gYmVmb3JlIHJlY29yZGluZyB0ZXJtaW5hbCBjb3JydXB0aW9uIGZvciBhIHJ1biB0aGF0IGNhbm5vdCByZXBsYXkuXG5leHBvcnQgY29uc3QgUkVQTEFZX0RJVkVSR0VOQ0VfTUFYX1JFVFJJRVMgPSAzO1xuXG4vKipcbiAqIEVmZmVjdGl2ZSByZXBsYXktZGl2ZXJnZW5jZSByZWNvdmVyeSBidWRnZXQuIE92ZXJyaWRlIHZpYVxuICogYFdPUktGTE9XX1JFUExBWV9ESVZFUkdFTkNFX01BWF9SRVRSSUVTYC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFJlcGxheURpdmVyZ2VuY2VNYXhSZXRyaWVzKCk6IG51bWJlciB7XG4gIHJldHVybiBlbnZOdW1iZXIoXG4gICAgJ1dPUktGTE9XX1JFUExBWV9ESVZFUkdFTkNFX01BWF9SRVRSSUVTJyxcbiAgICBSRVBMQVlfRElWRVJHRU5DRV9NQVhfUkVUUklFUyxcbiAgICB7IGludGVnZXI6IHRydWUgfVxuICApO1xufVxuXG4vLyBBIHN0YWxlLXNuYXBzaG90IHJlamVjdGlvbiAoNDEyKSBtZWFucyB0aGUgcmVwbGF5J3MgZXZlbnQgbG9nIHdhcyBtaXNzaW5nIGFuXG4vLyBldmVudCB0aGUgV29ybGQgaGFkIGFscmVhZHkgcmVjb3JkZWQsIHNvIHRoZSByZXBsYXkgaXMgcmUtZGVyaXZlZCBmcm9tIGFcbi8vIGNvcnJlY3RlZCBsb2cgaW5zaWRlIHRoZSBzYW1lIGludm9jYXRpb24uIEJvdW5kZWQgYmVjYXVzZSBhIHBlcnNpc3RlbnRseVxuLy8gcmVqZWN0ZWQgd3JpdGUgc2hvdWxkIGVzY2FsYXRlIHJhdGhlciB0aGFuIHNwaW46IGFmdGVyIHRoaXMgbWFueSByZXN0YXJ0cyB0aGVcbi8vIHJ1biBpcyByZS1pbnZva2VkIChhIG5ldyBpbnZvY2F0aW9uLCBwb3NzaWJseSBpbiBhIGRpZmZlcmVudCByZWdpb24pLCBhbmQgdGhlXG4vLyBydW4tbGV2ZWwgYnVkZ2V0IGJlbG93IHRoZW4gYXBwbGllcy5cbmV4cG9ydCBjb25zdCBQUkVDT05ESVRJT05fTUFYX0lOUFJPQ0VTU19SRVNUQVJUUyA9IDM7XG5cbi8qKlxuICogRWZmZWN0aXZlIGluLXByb2Nlc3MgcmVwbGF5LXJlc3RhcnQgYnVkZ2V0IGZvciBzdGFsZS1zbmFwc2hvdCByZWplY3Rpb25zLlxuICogT3ZlcnJpZGUgdmlhIGBXT1JLRkxPV19QUkVDT05ESVRJT05fTUFYX0lOUFJPQ0VTU19SRVNUQVJUU2AuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRQcmVjb25kaXRpb25NYXhJblByb2Nlc3NSZXN0YXJ0cygpOiBudW1iZXIge1xuICByZXR1cm4gZW52TnVtYmVyKFxuICAgICdXT1JLRkxPV19QUkVDT05ESVRJT05fTUFYX0lOUFJPQ0VTU19SRVNUQVJUUycsXG4gICAgUFJFQ09ORElUSU9OX01BWF9JTlBST0NFU1NfUkVTVEFSVFMsXG4gICAgeyBpbnRlZ2VyOiB0cnVlIH1cbiAgKTtcbn1cblxuLy8gVGhlIGluLXByb2Nlc3MgYnVkZ2V0IGFib3ZlIGlzIHBlci1pbnZvY2F0aW9uLCBhbmQgYSByZS1pbnZvY2F0aW9uIHRoYXRcbi8vIGVucXVldWVzIGEgZnJlc2ggbWVzc2FnZSBhbHNvIHJlc3RhcnRzIHRoZSBxdWV1ZSdzIGRlbGl2ZXJ5IGNvdW50LCBzbyB3aXRob3V0XG4vLyBhIGNvdW50ZXIgY2FycmllZCBvbiB0aGUgbWVzc2FnZSBhIHBlcm1hbmVudGx5IGZlbmNlZCBydW4gaGFzIG5vIHJ1bi1sZXZlbFxuLy8gYm91bmQgYXQgYWxsLiBJdCBjYW4gc3RheSBmZW5jZWQgd2l0aG91dCBhbnkgcGVybWFuZW50IGZhdWx0IChhIGZ1bGwgcmVsb2FkXG4vLyBpcyBub3QgYXRvbWljIGFjcm9zcyBwYWdlcywgc28gYSBidXN5IHJ1biBjYW4gYWNxdWlyZSBhIG5ldyBob2xlIG9uIGV2ZXJ5XG4vLyByZWxvYWQpLCBzbyB0aGUgY2hhaW4gaXMgY291bnRlZCBhbmQgdGhlIHJ1biBmYWlscyBvbmNlIHRoaXMgbWFueVxuLy8gcmUtaW52b2NhdGlvbnMgaGF2ZSBiZWVuIHNwZW50IG9uIHN0YWxlLXNuYXBzaG90IHJlamVjdGlvbnMuXG5leHBvcnQgY29uc3QgUFJFQ09ORElUSU9OX01BWF9SRUlOVk9DQVRJT05TID0gNTtcblxuLyoqXG4gKiBFZmZlY3RpdmUgcGVyLXJ1biBidWRnZXQgZm9yIHJlLWludm9jYXRpb25zIGNhdXNlZCBieSBzdGFsZS1zbmFwc2hvdFxuICogcmVqZWN0aW9ucy4gT3ZlcnJpZGUgdmlhIGBXT1JLRkxPV19QUkVDT05ESVRJT05fTUFYX1JFSU5WT0NBVElPTlNgLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0UHJlY29uZGl0aW9uTWF4UmVpbnZvY2F0aW9ucygpOiBudW1iZXIge1xuICByZXR1cm4gZW52TnVtYmVyKFxuICAgICdXT1JLRkxPV19QUkVDT05ESVRJT05fTUFYX1JFSU5WT0NBVElPTlMnLFxuICAgIFBSRUNPTkRJVElPTl9NQVhfUkVJTlZPQ0FUSU9OUyxcbiAgICB7IGludGVnZXI6IHRydWUgfVxuICApO1xufVxuXG4vLyBCYWNrb2ZmIGJlZm9yZSBhIHByZWNvbmRpdGlvbiByZS1pbnZvY2F0aW9uLiBVbmxpa2UgdGhlIGluLXByb2Nlc3MgcmVzdGFydFxuLy8gKHdoZXJlIHRoZSBwb2ludCBpcyB0byByZS1yZWFkIGltbWVkaWF0ZWx5KSwgYSByZS1pbnZvY2F0aW9uIG9ubHkgaGFwcGVuc1xuLy8gYWZ0ZXIgdGhlIGluLXByb2Nlc3MgYnVkZ2V0IGZhaWxlZCB0byBjYXRjaCB1cCwgc28gdGhlIGxvZyBpcyBiZWluZyBleHRlbmRlZFxuLy8gZmFzdGVyIHRoYW4gdGhpcyByZXBsYXkgY2FuIGZvbGxvdyBpdC4gV2FpdGluZyBsZXRzIHRoZSB3cml0ZXJzIHF1aWVzY2UuXG5leHBvcnQgY29uc3QgUFJFQ09ORElUSU9OX1JFSU5WT0tFX0RFTEFZX1NFQ09ORFMgPSAyO1xuXG4vKipcbiAqIEVmZmVjdGl2ZSBkZWxheSBiZWZvcmUgYSBwcmVjb25kaXRpb24gcmUtaW52b2NhdGlvbi4gT3ZlcnJpZGUgdmlhXG4gKiBgV09SS0ZMT1dfUFJFQ09ORElUSU9OX1JFSU5WT0tFX0RFTEFZX1NFQ09ORFNgLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0UHJlY29uZGl0aW9uUmVpbnZva2VEZWxheVNlY29uZHMoKTogbnVtYmVyIHtcbiAgcmV0dXJuIGVudk51bWJlcihcbiAgICAnV09SS0ZMT1dfUFJFQ09ORElUSU9OX1JFSU5WT0tFX0RFTEFZX1NFQ09ORFMnLFxuICAgIFBSRUNPTkRJVElPTl9SRUlOVk9LRV9ERUxBWV9TRUNPTkRTLFxuICAgIHsgaW50ZWdlcjogdHJ1ZSB9XG4gICk7XG59XG5cbi8vIEEgZGVsaXZlcnkgcmVhY2hpbmcgYSBkZXBsb3ltZW50IHRoZSBydW4gaXMgbm90IHBpbm5lZCB0byBpcyBub3QgdHJlYXRlZCBhc1xuLy8gcGVybWFuZW50LiBSZS1yb3V0ZSB0aGUgbWVzc2FnZSBhdCB0aGUgcnVuJ3Mgb3duIGRlcGxveW1lbnQgYSBib3VuZGVkIG51bWJlclxuLy8gb2YgdGltZXMgYmVmb3JlIGZhaWxpbmcgdGhlIHJ1biB3aXRoIERFUExPWU1FTlRfTUlTTUFUQ0guXG5leHBvcnQgY29uc3QgREVQTE9ZTUVOVF9NSVNNQVRDSF9NQVhfUkVUUklFUyA9IDM7XG5cbi8qKlxuICogRWZmZWN0aXZlIGRlcGxveW1lbnQtbWlzbWF0Y2ggcmUtcm91dGUgYnVkZ2V0LiBPdmVycmlkZSB2aWFcbiAqIGBXT1JLRkxPV19ERVBMT1lNRU5UX01JU01BVENIX01BWF9SRVRSSUVTYDsgYDBgIGZhaWxzIHRoZSBydW4gb24gdGhlIGZpcnN0XG4gKiBtaXNyb3V0ZWQgZGVsaXZlcnkgaW5zdGVhZCBvZiBhdHRlbXB0aW5nIHJlY292ZXJ5LlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0RGVwbG95bWVudE1pc21hdGNoTWF4UmV0cmllcygpOiBudW1iZXIge1xuICByZXR1cm4gZW52TnVtYmVyKFxuICAgICdXT1JLRkxPV19ERVBMT1lNRU5UX01JU01BVENIX01BWF9SRVRSSUVTJyxcbiAgICBERVBMT1lNRU5UX01JU01BVENIX01BWF9SRVRSSUVTLFxuICAgIHsgaW50ZWdlcjogdHJ1ZSwgbWluOiAwIH1cbiAgKTtcbn1cbiJdfQ==
|
|
@@ -2,16 +2,16 @@ import type { Event } from '@workflow/world';
|
|
|
2
2
|
/**
|
|
3
3
|
* Scope for {@link countStepStartedEvents}:
|
|
4
4
|
* - `{ type: 'ownedBy', messageId }` counts only starts whose
|
|
5
|
-
* `eventData.ownerMessageId` matches
|
|
5
|
+
* `eventData.ownerMessageId` matches, i.e. attempts performed by that
|
|
6
6
|
* owning queue message (inline lazy starts and owned-recovery re-stamps).
|
|
7
7
|
* - `{ type: 'totalAttempts' }` estimates the step's genuine attempt total
|
|
8
|
-
* across its whole lifecycle: unstamped (bare) starts
|
|
9
|
-
* queue-dispatched background deliveries write
|
|
8
|
+
* across its whole lifecycle: unstamped (bare) starts, which only real
|
|
9
|
+
* queue-dispatched background deliveries write, plus the starts of the
|
|
10
10
|
* single most-started owner. A genuine lifecycle has at most one inline
|
|
11
11
|
* owner phase (ownership is claimed atomically at step creation and
|
|
12
12
|
* lapses permanently at `step_retrying` or on any bare start), so taking
|
|
13
13
|
* the max over owners counts that phase's real attempts while invocations
|
|
14
|
-
* racing on the same batch
|
|
14
|
+
* racing on the same batch, which stamp their own one-off message IDs,
|
|
15
15
|
* contribute at most their single largest count instead of accumulating.
|
|
16
16
|
*/
|
|
17
17
|
export type StepStartScope = {
|
|
@@ -29,7 +29,7 @@ export type StepStartScope = {
|
|
|
29
29
|
* Concurrent invocations racing on the same pending batch (stale replays,
|
|
30
30
|
* wake replays, a step message dispatched by a replay that lost the
|
|
31
31
|
* create-claim race, ...) can each write a `step_started` for the same
|
|
32
|
-
* logical attempt
|
|
32
|
+
* logical attempt. Worlds without an atomic start guard (world-local) let
|
|
33
33
|
* all of them through. Counting those duplicates as "attempts" made the
|
|
34
34
|
* maxRetries ceiling fire on healthy runs and fail them with a false
|
|
35
35
|
* "exceeded max retries" (see workflow#3069).
|
|
@@ -37,11 +37,11 @@ export type StepStartScope = {
|
|
|
37
37
|
* Callers therefore scope the count to the starts their ceiling is actually
|
|
38
38
|
* about via `scope`:
|
|
39
39
|
* - the inline owned-recovery ceiling counts only THIS message's starts
|
|
40
|
-
* (`ownedBy`)
|
|
40
|
+
* (`ownedBy`): each real (re)delivery of the owning message stamps its
|
|
41
41
|
* `ownerMessageId` on the start it writes, while racing invocations stamp
|
|
42
42
|
* their own IDs (or none), so they no longer inflate the count;
|
|
43
43
|
* - the background-step ceiling counts the lifecycle attempt total
|
|
44
|
-
* (`totalAttempts`: bare starts plus the largest single owner's starts)
|
|
44
|
+
* (`totalAttempts`: bare starts plus the largest single owner's starts),
|
|
45
45
|
* so a step that exhausted part of its budget under inline ownership
|
|
46
46
|
* before transitioning to queued/bare retries still trips the combined
|
|
47
47
|
* ceiling, while racers' one-off stamped duplicates don't accumulate, and
|
|
@@ -13,7 +13,7 @@ const ownerOf = (e) => 'eventData' in e &&
|
|
|
13
13
|
* Concurrent invocations racing on the same pending batch (stale replays,
|
|
14
14
|
* wake replays, a step message dispatched by a replay that lost the
|
|
15
15
|
* create-claim race, ...) can each write a `step_started` for the same
|
|
16
|
-
* logical attempt
|
|
16
|
+
* logical attempt. Worlds without an atomic start guard (world-local) let
|
|
17
17
|
* all of them through. Counting those duplicates as "attempts" made the
|
|
18
18
|
* maxRetries ceiling fire on healthy runs and fail them with a false
|
|
19
19
|
* "exceeded max retries" (see workflow#3069).
|
|
@@ -21,11 +21,11 @@ const ownerOf = (e) => 'eventData' in e &&
|
|
|
21
21
|
* Callers therefore scope the count to the starts their ceiling is actually
|
|
22
22
|
* about via `scope`:
|
|
23
23
|
* - the inline owned-recovery ceiling counts only THIS message's starts
|
|
24
|
-
* (`ownedBy`)
|
|
24
|
+
* (`ownedBy`): each real (re)delivery of the owning message stamps its
|
|
25
25
|
* `ownerMessageId` on the start it writes, while racing invocations stamp
|
|
26
26
|
* their own IDs (or none), so they no longer inflate the count;
|
|
27
27
|
* - the background-step ceiling counts the lifecycle attempt total
|
|
28
|
-
* (`totalAttempts`: bare starts plus the largest single owner's starts)
|
|
28
|
+
* (`totalAttempts`: bare starts plus the largest single owner's starts),
|
|
29
29
|
* so a step that exhausted part of its budget under inline ownership
|
|
30
30
|
* before transitioning to queued/bare retries still trips the combined
|
|
31
31
|
* ceiling, while racers' one-off stamped duplicates don't accumulate, and
|
|
@@ -69,4 +69,4 @@ export function countStepStartedEvents(events, stepId, scope) {
|
|
|
69
69
|
}
|
|
70
70
|
return bare + maxOwner;
|
|
71
71
|
}
|
|
72
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
72
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY291bnQtc3RlcC1zdGFydGVkLWV2ZW50cy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9ydW50aW1lL2NvdW50LXN0ZXAtc3RhcnRlZC1ldmVudHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBcUJBLE1BQU0sT0FBTyxHQUFHLENBQUMsQ0FBUSxFQUFzQixFQUFFLENBQy9DLFdBQVcsSUFBSSxDQUFDO0lBQ2hCLENBQUMsQ0FBQyxTQUFTO0lBQ1gsZ0JBQWdCLElBQUksQ0FBQyxDQUFDLFNBQVM7SUFDL0IsT0FBTyxDQUFDLENBQUMsU0FBUyxDQUFDLGNBQWMsS0FBSyxRQUFRO0lBQzVDLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLGNBQWM7SUFDNUIsQ0FBQyxDQUFDLFNBQVMsQ0FBQztBQUVoQjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBMkJHO0FBQ0gsTUFBTSxVQUFVLHNCQUFzQixDQUNwQyxNQUFrQyxFQUNsQyxNQUFjLEVBQ2QsS0FBc0I7SUFFdEIsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ1osT0FBTyxDQUFDLENBQUM7SUFDWCxDQUFDO0lBQ0QsSUFBSSxJQUFJLEdBQUcsQ0FBQyxDQUFDO0lBQ2IsTUFBTSxPQUFPLEdBQUcsSUFBSSxHQUFHLEVBQWtCLENBQUM7SUFDMUMsS0FBSyxNQUFNLENBQUMsSUFBSSxNQUFNLEVBQUUsQ0FBQztRQUN2QixJQUFJLENBQUMsQ0FBQyxTQUFTLEtBQUssY0FBYyxJQUFJLENBQUMsQ0FBQyxhQUFhLEtBQUssTUFBTSxFQUFFLENBQUM7WUFDakUsU0FBUztRQUNYLENBQUM7UUFDRCxNQUFNLEtBQUssR0FBRyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDekIsSUFBSSxLQUFLLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDeEIsSUFBSSxFQUFFLENBQUM7UUFDVCxDQUFDO2FBQU0sQ0FBQztZQUNOLE9BQU8sQ0FBQyxHQUFHLENBQUMsS0FBSyxFQUFFLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUNwRCxDQUFDO0lBQ0gsQ0FBQztJQUNELElBQUksS0FBSyxLQUFLLFNBQVMsRUFBRSxDQUFDO1FBQ3hCLElBQUksS0FBSyxHQUFHLElBQUksQ0FBQztRQUNqQixLQUFLLE1BQU0sS0FBSyxJQUFJLE9BQU8sQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDO1lBQ3JDLEtBQUssSUFBSSxLQUFLLENBQUM7UUFDakIsQ0FBQztRQUNELE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztJQUNELElBQUksS0FBSyxDQUFDLElBQUksS0FBSyxTQUFTLEVBQUUsQ0FBQztRQUM3QixPQUFPLE9BQU8sQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUMzQyxDQUFDO0lBQ0QsZ0JBQWdCO0lBQ2hCLElBQUksUUFBUSxHQUFHLENBQUMsQ0FBQztJQUNqQixLQUFLLE1BQU0sS0FBSyxJQUFJLE9BQU8sQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDO1FBQ3JDLElBQUksS0FBSyxHQUFHLFFBQVEsRUFBRSxDQUFDO1lBQ3JCLFFBQVEsR0FBRyxLQUFLLENBQUM7UUFDbkIsQ0FBQztJQUNILENBQUM7SUFDRCxPQUFPLElBQUksR0FBRyxRQUFRLENBQUM7QUFDekIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgRXZlbnQgfSBmcm9tICdAd29ya2Zsb3cvd29ybGQnO1xuXG4vKipcbiAqIFNjb3BlIGZvciB7QGxpbmsgY291bnRTdGVwU3RhcnRlZEV2ZW50c306XG4gKiAtIGB7IHR5cGU6ICdvd25lZEJ5JywgbWVzc2FnZUlkIH1gIGNvdW50cyBvbmx5IHN0YXJ0cyB3aG9zZVxuICogICBgZXZlbnREYXRhLm93bmVyTWVzc2FnZUlkYCBtYXRjaGVzLCBpLmUuIGF0dGVtcHRzIHBlcmZvcm1lZCBieSB0aGF0XG4gKiAgIG93bmluZyBxdWV1ZSBtZXNzYWdlIChpbmxpbmUgbGF6eSBzdGFydHMgYW5kIG93bmVkLXJlY292ZXJ5IHJlLXN0YW1wcykuXG4gKiAtIGB7IHR5cGU6ICd0b3RhbEF0dGVtcHRzJyB9YCBlc3RpbWF0ZXMgdGhlIHN0ZXAncyBnZW51aW5lIGF0dGVtcHQgdG90YWxcbiAqICAgYWNyb3NzIGl0cyB3aG9sZSBsaWZlY3ljbGU6IHVuc3RhbXBlZCAoYmFyZSkgc3RhcnRzLCB3aGljaCBvbmx5IHJlYWxcbiAqICAgcXVldWUtZGlzcGF0Y2hlZCBiYWNrZ3JvdW5kIGRlbGl2ZXJpZXMgd3JpdGUsIHBsdXMgdGhlIHN0YXJ0cyBvZiB0aGVcbiAqICAgc2luZ2xlIG1vc3Qtc3RhcnRlZCBvd25lci4gQSBnZW51aW5lIGxpZmVjeWNsZSBoYXMgYXQgbW9zdCBvbmUgaW5saW5lXG4gKiAgIG93bmVyIHBoYXNlIChvd25lcnNoaXAgaXMgY2xhaW1lZCBhdG9taWNhbGx5IGF0IHN0ZXAgY3JlYXRpb24gYW5kXG4gKiAgIGxhcHNlcyBwZXJtYW5lbnRseSBhdCBgc3RlcF9yZXRyeWluZ2Agb3Igb24gYW55IGJhcmUgc3RhcnQpLCBzbyB0YWtpbmdcbiAqICAgdGhlIG1heCBvdmVyIG93bmVycyBjb3VudHMgdGhhdCBwaGFzZSdzIHJlYWwgYXR0ZW1wdHMgd2hpbGUgaW52b2NhdGlvbnNcbiAqICAgcmFjaW5nIG9uIHRoZSBzYW1lIGJhdGNoLCB3aGljaCBzdGFtcCB0aGVpciBvd24gb25lLW9mZiBtZXNzYWdlIElEcyxcbiAqICAgY29udHJpYnV0ZSBhdCBtb3N0IHRoZWlyIHNpbmdsZSBsYXJnZXN0IGNvdW50IGluc3RlYWQgb2YgYWNjdW11bGF0aW5nLlxuICovXG5leHBvcnQgdHlwZSBTdGVwU3RhcnRTY29wZSA9XG4gIHwgeyB0eXBlOiAnb3duZWRCeSc7IG1lc3NhZ2VJZDogc3RyaW5nIH1cbiAgfCB7IHR5cGU6ICd0b3RhbEF0dGVtcHRzJyB9O1xuXG5jb25zdCBvd25lck9mID0gKGU6IEV2ZW50KTogc3RyaW5nIHwgdW5kZWZpbmVkID0+XG4gICdldmVudERhdGEnIGluIGUgJiZcbiAgZS5ldmVudERhdGEgJiZcbiAgJ293bmVyTWVzc2FnZUlkJyBpbiBlLmV2ZW50RGF0YSAmJlxuICB0eXBlb2YgZS5ldmVudERhdGEub3duZXJNZXNzYWdlSWQgPT09ICdzdHJpbmcnXG4gICAgPyBlLmV2ZW50RGF0YS5vd25lck1lc3NhZ2VJZFxuICAgIDogdW5kZWZpbmVkO1xuXG4vKipcbiAqIE51bWJlciBvZiBgc3RlcF9zdGFydGVkYCBldmVudHMgYWxyZWFkeSByZWNvcmRlZCBmb3IgYSBzdGVwLCB1c2VkIGFzIHRoZVxuICogYXV0aG9yaXRhdGl2ZSBhdHRlbXB0IGNvdW50IGZvciB0aGUgbWF4UmV0cmllcyBjZWlsaW5nICh0aGUgb25seSBib3VuZCBmb3JcbiAqIHN0ZXBzIHRoYXQgdGltZSBvdXQgd2l0aG91dCB3cml0aW5nIGEgYHN0ZXBfZmFpbGVkYCkuXG4gKlxuICogSU1QT1JUQU5UOiB0aGUgcmF3ICh1bnNjb3BlZCkgY291bnQgaXMgTk9UIGEgcmVsaWFibGUgYXR0ZW1wdCBudW1iZXIuXG4gKiBDb25jdXJyZW50IGludm9jYXRpb25zIHJhY2luZyBvbiB0aGUgc2FtZSBwZW5kaW5nIGJhdGNoIChzdGFsZSByZXBsYXlzLFxuICogd2FrZSByZXBsYXlzLCBhIHN0ZXAgbWVzc2FnZSBkaXNwYXRjaGVkIGJ5IGEgcmVwbGF5IHRoYXQgbG9zdCB0aGVcbiAqIGNyZWF0ZS1jbGFpbSByYWNlLCAuLi4pIGNhbiBlYWNoIHdyaXRlIGEgYHN0ZXBfc3RhcnRlZGAgZm9yIHRoZSBzYW1lXG4gKiBsb2dpY2FsIGF0dGVtcHQuIFdvcmxkcyB3aXRob3V0IGFuIGF0b21pYyBzdGFydCBndWFyZCAod29ybGQtbG9jYWwpIGxldFxuICogYWxsIG9mIHRoZW0gdGhyb3VnaC4gQ291bnRpbmcgdGhvc2UgZHVwbGljYXRlcyBhcyBcImF0dGVtcHRzXCIgbWFkZSB0aGVcbiAqIG1heFJldHJpZXMgY2VpbGluZyBmaXJlIG9uIGhlYWx0aHkgcnVucyBhbmQgZmFpbCB0aGVtIHdpdGggYSBmYWxzZVxuICogXCJleGNlZWRlZCBtYXggcmV0cmllc1wiIChzZWUgd29ya2Zsb3cjMzA2OSkuXG4gKlxuICogQ2FsbGVycyB0aGVyZWZvcmUgc2NvcGUgdGhlIGNvdW50IHRvIHRoZSBzdGFydHMgdGhlaXIgY2VpbGluZyBpcyBhY3R1YWxseVxuICogYWJvdXQgdmlhIGBzY29wZWA6XG4gKiAtIHRoZSBpbmxpbmUgb3duZWQtcmVjb3ZlcnkgY2VpbGluZyBjb3VudHMgb25seSBUSElTIG1lc3NhZ2UncyBzdGFydHNcbiAqICAgKGBvd25lZEJ5YCk6IGVhY2ggcmVhbCAocmUpZGVsaXZlcnkgb2YgdGhlIG93bmluZyBtZXNzYWdlIHN0YW1wcyBpdHNcbiAqICAgYG93bmVyTWVzc2FnZUlkYCBvbiB0aGUgc3RhcnQgaXQgd3JpdGVzLCB3aGlsZSByYWNpbmcgaW52b2NhdGlvbnMgc3RhbXBcbiAqICAgdGhlaXIgb3duIElEcyAob3Igbm9uZSksIHNvIHRoZXkgbm8gbG9uZ2VyIGluZmxhdGUgdGhlIGNvdW50O1xuICogLSB0aGUgYmFja2dyb3VuZC1zdGVwIGNlaWxpbmcgY291bnRzIHRoZSBsaWZlY3ljbGUgYXR0ZW1wdCB0b3RhbFxuICogICAoYHRvdGFsQXR0ZW1wdHNgOiBiYXJlIHN0YXJ0cyBwbHVzIHRoZSBsYXJnZXN0IHNpbmdsZSBvd25lcidzIHN0YXJ0cyksXG4gKiAgIHNvIGEgc3RlcCB0aGF0IGV4aGF1c3RlZCBwYXJ0IG9mIGl0cyBidWRnZXQgdW5kZXIgaW5saW5lIG93bmVyc2hpcFxuICogICBiZWZvcmUgdHJhbnNpdGlvbmluZyB0byBxdWV1ZWQvYmFyZSByZXRyaWVzIHN0aWxsIHRyaXBzIHRoZSBjb21iaW5lZFxuICogICBjZWlsaW5nLCB3aGlsZSByYWNlcnMnIG9uZS1vZmYgc3RhbXBlZCBkdXBsaWNhdGVzIGRvbid0IGFjY3VtdWxhdGUsIGFuZFxuICogICB0aHJvdHRsZS90b28tZWFybHkgcmVkZWxpdmVyaWVzICh3aGljaCB3cml0ZSBubyBzdGFydCBhdCBhbGwpIHN0YXlcbiAqICAgZXhjbHVkZWQgYXMgYmVmb3JlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY291bnRTdGVwU3RhcnRlZEV2ZW50cyhcbiAgZXZlbnRzOiBFdmVudFtdIHwgbnVsbCB8IHVuZGVmaW5lZCxcbiAgc3RlcElkOiBzdHJpbmcsXG4gIHNjb3BlPzogU3RlcFN0YXJ0U2NvcGVcbik6IG51bWJlciB7XG4gIGlmICghZXZlbnRzKSB7XG4gICAgcmV0dXJuIDA7XG4gIH1cbiAgbGV0IGJhcmUgPSAwO1xuICBjb25zdCBieU93bmVyID0gbmV3IE1hcDxzdHJpbmcsIG51bWJlcj4oKTtcbiAgZm9yIChjb25zdCBlIG9mIGV2ZW50cykge1xuICAgIGlmIChlLmV2ZW50VHlwZSAhPT0gJ3N0ZXBfc3RhcnRlZCcgfHwgZS5jb3JyZWxhdGlvbklkICE9PSBzdGVwSWQpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICBjb25zdCBvd25lciA9IG93bmVyT2YoZSk7XG4gICAgaWYgKG93bmVyID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGJhcmUrKztcbiAgICB9IGVsc2Uge1xuICAgICAgYnlPd25lci5zZXQob3duZXIsIChieU93bmVyLmdldChvd25lcikgPz8gMCkgKyAxKTtcbiAgICB9XG4gIH1cbiAgaWYgKHNjb3BlID09PSB1bmRlZmluZWQpIHtcbiAgICBsZXQgdG90YWwgPSBiYXJlO1xuICAgIGZvciAoY29uc3QgY291bnQgb2YgYnlPd25lci52YWx1ZXMoKSkge1xuICAgICAgdG90YWwgKz0gY291bnQ7XG4gICAgfVxuICAgIHJldHVybiB0b3RhbDtcbiAgfVxuICBpZiAoc2NvcGUudHlwZSA9PT0gJ293bmVkQnknKSB7XG4gICAgcmV0dXJuIGJ5T3duZXIuZ2V0KHNjb3BlLm1lc3NhZ2VJZCkgPz8gMDtcbiAgfVxuICAvLyB0b3RhbEF0dGVtcHRzXG4gIGxldCBtYXhPd25lciA9IDA7XG4gIGZvciAoY29uc3QgY291bnQgb2YgYnlPd25lci52YWx1ZXMoKSkge1xuICAgIGlmIChjb3VudCA+IG1heE93bmVyKSB7XG4gICAgICBtYXhPd25lciA9IGNvdW50O1xuICAgIH1cbiAgfVxuICByZXR1cm4gYmFyZSArIG1heE93bmVyO1xufVxuIl19
|