@workflow/core 5.0.0-beta.43 → 5.0.0-beta.46

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.
Files changed (228) hide show
  1. package/dist/attribute-changes.d.ts +3 -5
  2. package/dist/attribute-changes.d.ts.map +1 -1
  3. package/dist/attribute-changes.js +2 -2
  4. package/dist/capabilities.d.ts +6 -6
  5. package/dist/capabilities.js +8 -8
  6. package/dist/capture-stack.d.ts +1 -1
  7. package/dist/capture-stack.js +2 -2
  8. package/dist/class-serialization.d.ts +8 -8
  9. package/dist/class-serialization.js +9 -9
  10. package/dist/classify-error.js +5 -5
  11. package/dist/context-violation-error.d.ts +5 -5
  12. package/dist/context-violation-error.d.ts.map +1 -1
  13. package/dist/context-violation-error.js +5 -5
  14. package/dist/create-hook.d.ts +2 -2
  15. package/dist/create-hook.js +1 -1
  16. package/dist/define-hook.js +2 -2
  17. package/dist/describe-error.d.ts +7 -7
  18. package/dist/describe-error.js +8 -8
  19. package/dist/encryption.d.ts +5 -5
  20. package/dist/encryption.js +7 -7
  21. package/dist/events-consumer.d.ts +20 -8
  22. package/dist/events-consumer.d.ts.map +1 -1
  23. package/dist/events-consumer.js +34 -12
  24. package/dist/flushable-stream.d.ts +4 -4
  25. package/dist/flushable-stream.js +13 -13
  26. package/dist/global.d.ts +4 -2
  27. package/dist/global.d.ts.map +1 -1
  28. package/dist/global.js +8 -5
  29. package/dist/index.d.ts +1 -1
  30. package/dist/index.js +2 -2
  31. package/dist/log-format.d.ts +2 -2
  32. package/dist/log-format.js +5 -5
  33. package/dist/logger.js +4 -4
  34. package/dist/private.d.ts +29 -71
  35. package/dist/private.d.ts.map +1 -1
  36. package/dist/private.js +170 -38
  37. package/dist/replay-payload-cache.d.ts +1 -1
  38. package/dist/replay-payload-cache.js +4 -4
  39. package/dist/runtime/compute-instance.d.ts +4 -3
  40. package/dist/runtime/compute-instance.d.ts.map +1 -1
  41. package/dist/runtime/compute-instance.js +5 -4
  42. package/dist/runtime/constants.d.ts +24 -24
  43. package/dist/runtime/constants.d.ts.map +1 -1
  44. package/dist/runtime/constants.js +49 -43
  45. package/dist/runtime/count-step-started-events.d.ts +7 -7
  46. package/dist/runtime/count-step-started-events.js +4 -4
  47. package/dist/runtime/deployment-guard.d.ts +7 -7
  48. package/dist/runtime/deployment-guard.js +8 -8
  49. package/dist/runtime/get-port-lazy.d.ts +2 -2
  50. package/dist/runtime/get-port-lazy.d.ts.map +1 -1
  51. package/dist/runtime/get-port-lazy.js +37 -30
  52. package/dist/runtime/get-world-lazy.d.ts +2 -2
  53. package/dist/runtime/get-world-lazy.js +3 -3
  54. package/dist/runtime/helpers.d.ts +21 -21
  55. package/dist/runtime/helpers.js +27 -27
  56. package/dist/runtime/quickjs-entrypoint.d.ts +21 -10
  57. package/dist/runtime/quickjs-entrypoint.d.ts.map +1 -1
  58. package/dist/runtime/quickjs-entrypoint.js +206 -81
  59. package/dist/runtime/quickjs-runtime.d.ts +31 -15
  60. package/dist/runtime/quickjs-runtime.d.ts.map +1 -1
  61. package/dist/runtime/quickjs-runtime.js +132 -77
  62. package/dist/runtime/quickjs-serde.d.ts +10 -10
  63. package/dist/runtime/quickjs-serde.js +20 -20
  64. package/dist/runtime/replay-budget.d.ts +4 -4
  65. package/dist/runtime/replay-budget.js +5 -5
  66. package/dist/runtime/replay-recovery-reporter.d.ts +1 -1
  67. package/dist/runtime/replay-recovery-reporter.js +2 -2
  68. package/dist/runtime/resume-hook.d.ts +27 -12
  69. package/dist/runtime/resume-hook.d.ts.map +1 -1
  70. package/dist/runtime/resume-hook.js +200 -200
  71. package/dist/runtime/resume-latency.d.ts +40 -30
  72. package/dist/runtime/resume-latency.d.ts.map +1 -1
  73. package/dist/runtime/resume-latency.js +7 -5
  74. package/dist/runtime/run-id-time.d.ts +2 -2
  75. package/dist/runtime/run-id-time.js +5 -5
  76. package/dist/runtime/run.d.ts +22 -5
  77. package/dist/runtime/run.d.ts.map +1 -1
  78. package/dist/runtime/run.js +106 -11
  79. package/dist/runtime/runs.d.ts +4 -4
  80. package/dist/runtime/runs.js +2 -2
  81. package/dist/runtime/start.d.ts +3 -3
  82. package/dist/runtime/start.d.ts.map +1 -1
  83. package/dist/runtime/start.js +29 -25
  84. package/dist/runtime/step-executor.d.ts +14 -14
  85. package/dist/runtime/step-executor.d.ts.map +1 -1
  86. package/dist/runtime/step-executor.js +54 -39
  87. package/dist/runtime/step-latency.d.ts +42 -25
  88. package/dist/runtime/step-latency.d.ts.map +1 -1
  89. package/dist/runtime/step-latency.js +29 -23
  90. package/dist/runtime/step-ownership.d.ts +6 -6
  91. package/dist/runtime/step-ownership.js +8 -8
  92. package/dist/runtime/step-single-flight.d.ts +1 -1
  93. package/dist/runtime/step-single-flight.d.ts.map +1 -1
  94. package/dist/runtime/step-single-flight.js +17 -11
  95. package/dist/runtime/suspension-handler.d.ts +38 -24
  96. package/dist/runtime/suspension-handler.d.ts.map +1 -1
  97. package/dist/runtime/suspension-handler.js +238 -103
  98. package/dist/runtime/unserializable-step.d.ts +34 -0
  99. package/dist/runtime/unserializable-step.d.ts.map +1 -0
  100. package/dist/runtime/unserializable-step.js +52 -0
  101. package/dist/runtime/vm-mode.d.ts +1 -1
  102. package/dist/runtime/vm-mode.js +2 -2
  103. package/dist/runtime/wait-continuation.d.ts +31 -9
  104. package/dist/runtime/wait-continuation.d.ts.map +1 -1
  105. package/dist/runtime/wait-continuation.js +44 -13
  106. package/dist/runtime/wait-until.d.ts +1 -1
  107. package/dist/runtime/wait-until.js +2 -2
  108. package/dist/runtime/world-compatibility.d.ts +20 -9
  109. package/dist/runtime/world-compatibility.d.ts.map +1 -1
  110. package/dist/runtime/world-compatibility.js +24 -13
  111. package/dist/runtime/world-init.d.ts +5 -5
  112. package/dist/runtime/world-init.js +6 -6
  113. package/dist/runtime/world.d.ts.map +1 -1
  114. package/dist/runtime/world.js +13 -3
  115. package/dist/runtime.d.ts.map +1 -1
  116. package/dist/runtime.js +427 -266
  117. package/dist/sealed-box.d.ts +7 -7
  118. package/dist/sealed-box.js +15 -15
  119. package/dist/serialization/client.js +2 -2
  120. package/dist/serialization/codec-devalue-vm.d.ts +1 -1
  121. package/dist/serialization/codec-devalue-vm.js +4 -4
  122. package/dist/serialization/codec-devalue.d.ts +1 -1
  123. package/dist/serialization/codec-devalue.js +2 -2
  124. package/dist/serialization/codec.d.ts +4 -4
  125. package/dist/serialization/codec.js +2 -2
  126. package/dist/serialization/compression.d.ts +12 -11
  127. package/dist/serialization/compression.d.ts.map +1 -1
  128. package/dist/serialization/compression.js +16 -15
  129. package/dist/serialization/encryption.d.ts +7 -7
  130. package/dist/serialization/encryption.d.ts.map +1 -1
  131. package/dist/serialization/encryption.js +8 -8
  132. package/dist/serialization/errors.js +2 -2
  133. package/dist/serialization/format.d.ts +6 -6
  134. package/dist/serialization/format.js +7 -7
  135. package/dist/serialization/hardened.d.ts +23 -22
  136. package/dist/serialization/hardened.d.ts.map +1 -1
  137. package/dist/serialization/hardened.js +47 -32
  138. package/dist/serialization/index.d.ts +1 -1
  139. package/dist/serialization/index.js +2 -2
  140. package/dist/serialization/reducers/class-vm.d.ts +1 -1
  141. package/dist/serialization/reducers/class-vm.js +2 -2
  142. package/dist/serialization/reducers/class.js +2 -2
  143. package/dist/serialization/reducers/common-vm.js +12 -12
  144. package/dist/serialization/reducers/common.js +12 -12
  145. package/dist/serialization/reducers/step-function-vm.d.ts +1 -1
  146. package/dist/serialization/reducers/step-function-vm.js +2 -2
  147. package/dist/serialization/reducers/step-function.js +2 -2
  148. package/dist/serialization/step.js +2 -2
  149. package/dist/serialization/types.d.ts +5 -5
  150. package/dist/serialization/types.js +2 -2
  151. package/dist/serialization/workflow-vm.d.ts +1 -1
  152. package/dist/serialization/workflow-vm.d.ts.map +1 -1
  153. package/dist/serialization/workflow-vm.js +13 -10
  154. package/dist/serialization-format.d.ts +11 -11
  155. package/dist/serialization-format.d.ts.map +1 -1
  156. package/dist/serialization-format.js +30 -24
  157. package/dist/serialization.d.ts +15 -16
  158. package/dist/serialization.d.ts.map +1 -1
  159. package/dist/serialization.js +116 -109
  160. package/dist/set-attributes.js +2 -2
  161. package/dist/source-map.d.ts +1 -1
  162. package/dist/source-map.d.ts.map +1 -1
  163. package/dist/source-map.js +18 -12
  164. package/dist/step/context-storage.d.ts +5 -5
  165. package/dist/step/context-storage.js +1 -1
  166. package/dist/step/writable-stream.d.ts +3 -3
  167. package/dist/step/writable-stream.js +7 -7
  168. package/dist/step.d.ts.map +1 -1
  169. package/dist/step.js +14 -22
  170. package/dist/symbols.d.ts +2 -2
  171. package/dist/symbols.js +3 -3
  172. package/dist/telemetry/semantic-conventions.d.ts +34 -17
  173. package/dist/telemetry/semantic-conventions.d.ts.map +1 -1
  174. package/dist/telemetry/semantic-conventions.js +32 -17
  175. package/dist/telemetry.d.ts +3 -3
  176. package/dist/telemetry.d.ts.map +1 -1
  177. package/dist/telemetry.js +19 -10
  178. package/dist/test-support/orchestrator-context.d.ts.map +1 -1
  179. package/dist/test-support/orchestrator-context.js +12 -2
  180. package/dist/version.d.ts +1 -1
  181. package/dist/version.js +2 -2
  182. package/dist/vm/index.js +4 -4
  183. package/dist/vm/script-cache.d.ts.map +1 -1
  184. package/dist/vm/script-cache.js +23 -17
  185. package/dist/vm/uint8array-base64.js +1 -1
  186. package/dist/workflow/abort-controller.d.ts +1 -1
  187. package/dist/workflow/abort-controller.js +12 -12
  188. package/dist/workflow/attribute-dispatcher.d.ts.map +1 -1
  189. package/dist/workflow/attribute-dispatcher.js +3 -6
  190. package/dist/workflow/create-hook.js +2 -2
  191. package/dist/workflow/get-workflow-metadata.js +2 -2
  192. package/dist/workflow/hook.d.ts.map +1 -1
  193. package/dist/workflow/hook.js +21 -30
  194. package/dist/workflow/set-attributes.d.ts +1 -1
  195. package/dist/workflow/set-attributes.js +2 -2
  196. package/dist/workflow/sleep.js +2 -2
  197. package/dist/workflow/world-init-stub.d.ts +1 -1
  198. package/dist/workflow/world-init-stub.js +2 -2
  199. package/dist/workflow.d.ts +2 -2
  200. package/dist/workflow.js +26 -13
  201. package/docs/api-reference/create-hook.mdx +15 -15
  202. package/docs/api-reference/create-webhook.mdx +15 -15
  203. package/docs/api-reference/define-hook.mdx +10 -10
  204. package/docs/api-reference/fatal-error.mdx +2 -2
  205. package/docs/api-reference/fetch.mdx +7 -7
  206. package/docs/api-reference/get-step-metadata.mdx +2 -2
  207. package/docs/api-reference/get-workflow-metadata.mdx +3 -3
  208. package/docs/api-reference/get-writable.mdx +7 -7
  209. package/docs/api-reference/index.mdx +1 -1
  210. package/docs/api-reference/retryable-error.mdx +1 -1
  211. package/docs/api-reference/set-attributes.mdx +2 -2
  212. package/docs/api-reference/sleep.mdx +3 -3
  213. package/docs/foundations/cancellation.mdx +31 -31
  214. package/docs/foundations/errors-and-retries.mdx +42 -11
  215. package/docs/foundations/hooks.mdx +35 -35
  216. package/docs/foundations/idempotency.mdx +9 -9
  217. package/docs/foundations/serialization.mdx +21 -22
  218. package/docs/foundations/starting-workflows.mdx +36 -37
  219. package/docs/foundations/streaming.mdx +46 -41
  220. package/docs/foundations/versioning.mdx +3 -3
  221. package/docs/foundations/workflows-and-steps.mdx +9 -9
  222. package/docs/how-it-works/cancellation.mdx +62 -62
  223. package/docs/how-it-works/code-transform.mdx +66 -54
  224. package/docs/how-it-works/encryption.mdx +25 -21
  225. package/docs/how-it-works/event-sourcing.mdx +53 -35
  226. package/docs/how-it-works/framework-integrations.mdx +12 -12
  227. package/docs/how-it-works/understanding-directives.mdx +21 -21
  228. package/package.json +7 -7
package/dist/private.js CHANGED
@@ -2,6 +2,7 @@
2
2
  * Utils used by the bundler when transforming code
3
3
  */
4
4
  import { withResolvers } from '@workflow/utils';
5
+ import { WorkflowSuspension } from './global.js';
5
6
  const RegisteredStepsKey = Symbol.for('@workflow/core//registeredSteps');
6
7
  const globalSymbols = globalThis;
7
8
  // biome-ignore lint/suspicious/noAssignInExpressions: /
@@ -91,20 +92,20 @@ export function getStepFunction(stepId) {
91
92
  * blocks on a peer it does not need to:
92
93
  *
93
94
  * - a hook defers behind earlier HOOKS, WAITS and STEPS;
94
- * - a wait defers behind earlier HOOKS and STEPS not earlier waits, since a
95
- * wait never needs to queue behind another wait;
95
+ * - a wait defers behind earlier HOOKS and STEPS (not earlier waits, since a
96
+ * wait never needs to queue behind another wait);
96
97
  * - a step defers behind earlier WAITS, HOOKS and STEPS.
97
98
  *
98
99
  * The step-behind-step edge is not redundant with the serial `promiseQueue`.
99
100
  * The queue fixes the order in which step results are HYDRATED, but a step no
100
- * longer resolves inside its queue slot it captures the outcome there and
101
+ * longer resolves inside its queue slot: it captures the outcome there and
101
102
  * resolves from a detached continuation once its barrier clears. Two steps
102
103
  * agree on that continuation's ordering only while they defer behind the same
103
104
  * set, which holds when they are consumed in the same drain window but not
104
105
  * across windows: a step consumed later can miss a wait/hook barrier that an
105
106
  * earlier step is still parked on, because the barrier retired in between. The
106
107
  * earlier step is then waiting out the macrotask yield below while the later
107
- * one resolves on microtasks, and overtakes it — see
108
+ * one resolves on microtasks, and overtakes it. See
108
109
  * `delivery-barrier-coverage.test.ts`. Deferring behind earlier steps
109
110
  * closes that window structurally: the earlier step's barrier is still
110
111
  * registered precisely because it has not delivered yet.
@@ -127,19 +128,24 @@ const DEFER_BEHIND = {
127
128
  * Those two MUST agree exactly, and the doc block on
128
129
  * {@link awaitEarlierDeliveries} stakes deadlock-freedom on it, so the
129
130
  * condition lives here rather than being spelled out twice.
131
+ *
132
+ * One deliberate exception: the log-order-draws turnstile in
133
+ * {@link quiesceEarlierCascades} waits on ANY lower armed entry, a strictly
134
+ * wider relation than this one. Why that width cannot deadlock the
135
+ * safety-net dispenser is argued at the turnstile itself.
130
136
  */
131
137
  function gatesOn(kind, index, otherIndex, other) {
132
138
  if (otherIndex >= index || !DEFER_BEHIND[kind].includes(other.kind)) {
133
139
  return false;
134
140
  }
135
141
  // A step skips an UNARMED earlier entry (an unclaimed buffered hook
136
- // payload) see the asymmetry described on `awaitEarlierDeliveries`. The
142
+ // payload). See the asymmetry described on `awaitEarlierDeliveries`. The
137
143
  // skip is direct, never transitive: armed entries are still gated on, even
138
144
  // when they are themselves parked behind such a payload.
139
145
  return !(kind === 'step' && !other.armed);
140
146
  }
141
147
  /**
142
- * Whether `entry` will resolve on its own it is armed, and every earlier
148
+ * Whether `entry` will resolve on its own: it is armed, and every earlier
143
149
  * delivery it actually gates on ({@link gatesOn}) will likewise resolve on its
144
150
  * own.
145
151
  *
@@ -155,7 +161,7 @@ function gatesOn(kind, index, otherIndex, other) {
155
161
  *
156
162
  * Recursion terminates because every edge points to a strictly smaller index.
157
163
  * `memo` keeps the walk linear in registry size, and the registry is not small
158
- * by construction `EventsConsumer` drains consecutively consumable events
164
+ * by construction: `EventsConsumer` drains consecutively consumable events
159
165
  * synchronously while barriers only retire on microtask-driven deliveries, so
160
166
  * a fan-out of `Promise.race([hook, sleep])` branches accumulates one barrier
161
167
  * per branch per kind. The memo MUST be per-call: `armed` mutates between
@@ -163,7 +169,7 @@ function gatesOn(kind, index, otherIndex, other) {
163
169
  *
164
170
  * The memo is an optimization, not a correctness requirement. It once was one:
165
171
  * `awaitEarlierDeliveries` used to run this walk for every earlier entry of a
166
- * step delivery, with no early exit, which unmemoized is T(n) = Σ T(j)
172
+ * step delivery, with no early exit, which unmemoized is T(n) = Σ T(j),
167
173
  * measured at 4.3e8 recursive calls (84s) for 40 alternating armed hook/wait
168
174
  * barriers. That call site is gone; a step now tests `armed` directly. The one
169
175
  * surviving caller, {@link hasParkedCommittedDelivery}, cannot reach that
@@ -203,8 +209,8 @@ function computeResolvesOnItsOwn(barriers, index, entry, memo) {
203
209
  * earlier in the log than `eventIndex` and that a delivery of `kind` defers
204
210
  * behind (see {@link DEFER_BEHIND}), so that this resolution is handed to the
205
211
  * workflow only after all relevant earlier-in-log deliveries have been. This
206
- * is what keeps a `Promise.race` or the ULID a follow-up `useStep` draws on
207
- * a concurrent branch deterministic and aligned with the committed event
212
+ * is what keeps a `Promise.race` (or the ULID a follow-up `useStep` draws on
213
+ * a concurrent branch) deterministic and aligned with the committed event
208
214
  * log, independent of microtask-hop counts, hydration time, or race-argument
209
215
  * order. When this delivery does have to wait, it also yields a macrotask
210
216
  * afterwards so the earlier delivery's consumer can run to its own next
@@ -217,10 +223,10 @@ function computeResolvesOnItsOwn(barriers, index, entry, memo) {
217
223
  * One asymmetry: a STEP result skips any earlier delivery that is UNARMED,
218
224
  * i.e. a buffered hook payload no consumer has claimed. Such a payload is
219
225
  * delivered only when the workflow next reads the hook, and reaching that read
220
- * very commonly requires the step result itself (`await stepX()` before the
226
+ * often requires the step result itself (`await stepX()` before the
221
227
  * read). Gating the step on it would stall the workflow until the barrier's
222
228
  * idle safety net fires, which then releases every delivery queued behind that
223
- * payload at once losing exactly the race this ordering exists to protect.
229
+ * payload at once, losing exactly the race this ordering exists to protect.
224
230
  * Waits and hooks keep gating on unclaimed payloads: for them, waiting for the
225
231
  * claim IS the ordering guarantee (a `wait_completed` must not preempt a
226
232
  * payload the log ordered first).
@@ -231,7 +237,7 @@ function computeResolvesOnItsOwn(barriers, index, entry, memo) {
231
237
  * there is: a workflow that creates a hook it does not read on this branch,
232
238
  * races `step` against `sleep`, and has the log say the sleep won. The step
233
239
  * would then overtake the wait, both branches would swap the correlation ids
234
- * they draw next, and replay would diverge — see
240
+ * they draw next, and replay would diverge. See
235
241
  * `step-delivery-ordering.test.ts`. Waiting instead is safe because the
236
242
  * payload's own idle safety net retires it and the whole chain then delivers
237
243
  * in log order; {@link hasParkedCommittedDelivery} deliberately reports such a
@@ -242,19 +248,120 @@ function computeResolvesOnItsOwn(barriers, index, entry, memo) {
242
248
  * structural: safety-net retirements go through one per-context dispenser that
243
249
  * only ever retires the lowest-index entry at delivery idle, and every
244
250
  * retirement that wakes a chain flips {@link hasParkedCommittedDelivery} back
245
- * to true, re-blocking the dispenser until the chain has drained — see
251
+ * to true, re-blocking the dispenser until the chain has drained. See
246
252
  * {@link ensureBarrierSafetyNet}. (This used to rest on the FIFO of one idle
247
253
  * poll per barrier, which held for a single parked segment but decayed to
248
- * timing noise with several the release order, and therefore the ULIDs
254
+ * timing noise with several: the release order, and therefore the ULIDs
249
255
  * drawn by the woken branches, then depended on how much log the replay had
250
256
  * loaded. storm-log-replay.test.ts replays a production log corrupted exactly
251
257
  * that way.)
252
258
  */
259
+ /**
260
+ * Whether correlation-id draw order is pinned to event-log order. Default ON:
261
+ * only the literal string `WORKFLOW_LOG_ORDER_DRAWS=0` opts out. `=false`,
262
+ * `=off`, and every other value keep it enabled. Read per call so tests can
263
+ * flip it.
264
+ *
265
+ * Off, a delivery that had to defer yields ONE macrotask after its
266
+ * predecessors resolve. This is enough for short consumers, but a woken branch
267
+ * whose path to its next draw crosses more hops (a `Promise.race` resolution, a
268
+ * user-level semaphore, an async-iterator read) can still be overtaken by a
269
+ * later-in-log delivery's shorter cascade, so the run's draw order, including
270
+ * its correlation ids, depends on how much log this replay loaded.
271
+ * On, the yield becomes a fixpoint: the delivery resolves only once every
272
+ * earlier cascade has quiesced, making the draw sequence a pure function of
273
+ * the dense log, stable under prefix extension, and concurrent writers'
274
+ * duplicate creates identical (deduped) instead of colliding.
275
+ */
276
+ function isLogOrderDrawsEnabled() {
277
+ return process.env.WORKFLOW_LOG_ORDER_DRAWS !== '0';
278
+ }
279
+ /**
280
+ * One quiescence turn: lets the entire pending microtask queue drain, then
281
+ * yields to the event loop once. `setImmediate` (check phase) is used where
282
+ * available because Node clamps `setTimeout(0)` to ~1ms while `setImmediate`
283
+ * costs ~20µs. Every branch-deciding delivery pays this turn at least
284
+ * once, so on a sequential replay the clamp is the whole cost. Timers still
285
+ * run between consecutive turns (the loop re-enters the event loop each
286
+ * iteration, passing through the timers phase), so chains parked on the
287
+ * safety-net dispenser's `setTimeout` cadence are not starved.
288
+ */
289
+ function quiescenceTurn(delayMs) {
290
+ if (delayMs === 0 && typeof setImmediate === 'function') {
291
+ return new Promise((resolve) => setImmediate(resolve));
292
+ }
293
+ return new Promise((resolve) => setTimeout(resolve, delayMs));
294
+ }
295
+ /**
296
+ * Waits until the workflow can make no further progress without another
297
+ * delivery: repeated (promise-queue drain + event-loop turn)s until a full
298
+ * turn passes with no new ULID draws and no hydration in flight.
299
+ *
300
+ * Termination: each extra iteration requires a new ULID draw or a hydration
301
+ * started in the previous turn. `mintCount` counts EVERY draw from the run's
302
+ * sequence, including correlation ids and serialization-driven draws (stream
303
+ * ids minted through the `STABLE_ULID` global while dehydrating). This is
304
+ * conservative in the safe direction: serialization draws only extend the
305
+ * wait, and both body progress and the serialization work one cascade can
306
+ * schedule are finite between deliveries, so the fixpoint is reached. The
307
+ * loop holds this delivery's own barrier registered (its `markDelivered` has
308
+ * not run), so `isDeliveryIdle` stays false and no suspension can preempt the
309
+ * cascade being waited out.
310
+ *
311
+ * A rejected `promiseQueue` settles immediately and forever, so looping at
312
+ * the normal cadence on a failed run would degenerate into a busy loop (the
313
+ * same hazard {@link ensureBarrierSafetyNet} documents). Iterations that
314
+ * observe the queue rejected back off to a 50ms tick instead.
315
+ */
316
+ async function quiesceEarlierCascades(ctx, eventIndex) {
317
+ for (;;) {
318
+ const mintsBefore = ctx.mintCount ?? 0;
319
+ const pendingBefore = ctx.pendingDeliveries;
320
+ // Settled or rejected, the queue snapshot only orders us behind work
321
+ // already chained; a rejection is the run failing elsewhere.
322
+ const queueRejected = await ctx.promiseQueue.then(() => false, () => true);
323
+ await quiescenceTurn(queueRejected ? 50 : 0);
324
+ if ((ctx.mintCount ?? 0) !== mintsBefore ||
325
+ pendingBefore !== 0 ||
326
+ ctx.pendingDeliveries !== 0) {
327
+ continue;
328
+ }
329
+ // Quiet is not enough on its own: several delivery chains can be sitting
330
+ // in this loop at once, and letting the first quiet observation resolve
331
+ // would break the tie by timer arrival. This mode removes that arrival-order
332
+ // dependence. A lower-index ARMED barrier is a delivery committed to
333
+ // happening that has not happened yet, so this one keeps waiting. Unarmed
334
+ // entries (buffered payloads nobody has claimed) do not block, exactly as
335
+ // in `gatesOn`: their handover is claim-driven, which is body-position
336
+ // determined and therefore already a function of the prefix.
337
+ //
338
+ // This is deliberately a WIDER waits-for relation than `gatesOn` (which,
339
+ // e.g., excludes wait→wait): under log-order draws EVERY branch-deciding
340
+ // delivery must resolve in log order, kinds included. The width is safe
341
+ // against the dispenser deadlock that `resolvesOnItsOwn` guards, because
342
+ // the one edge the wider relation adds (waiting on an armed entry that
343
+ // gatesOn does not model) always bottoms out at the same unarmed payload:
344
+ // a lower armed WAIT is non-self-resolving only when it is (transitively)
345
+ // parked behind an unclaimed buffered payload, and a wait gates on every
346
+ // lower hook and step directly, so the spinner here also gates on that
347
+ // payload through `gatesOn` and is itself reported non-self-resolving.
348
+ // The dispenser therefore stays unblocked and retires the chain head; see
349
+ // the parked-chain test in delivery-barrier-coverage.test.ts.
350
+ let lowerArmed = false;
351
+ for (const [index, entry] of ctx.pendingDeliveryBarriers ?? []) {
352
+ if (index < eventIndex && entry.armed) {
353
+ lowerArmed = true;
354
+ break;
355
+ }
356
+ }
357
+ if (!lowerArmed) {
358
+ return;
359
+ }
360
+ }
361
+ }
253
362
  export async function awaitEarlierDeliveries(ctx, eventIndex, kind) {
254
363
  // Defensive: tolerate contexts that predate this field (test harnesses).
255
- if (eventIndex === undefined ||
256
- !ctx.pendingDeliveryBarriers ||
257
- ctx.pendingDeliveryBarriers.size === 0) {
364
+ if (eventIndex === undefined || !ctx.pendingDeliveryBarriers) {
258
365
  return;
259
366
  }
260
367
  const barriers = ctx.pendingDeliveryBarriers;
@@ -267,9 +374,22 @@ export async function awaitEarlierDeliveries(ctx, eventIndex, kind) {
267
374
  }
268
375
  if (earlier.length > 0) {
269
376
  await Promise.all(earlier);
377
+ }
378
+ if (isLogOrderDrawsEnabled()) {
379
+ // Unconditional, not just when a barrier was still registered: an earlier
380
+ // delivery's barrier deregisters when its resolve() runs, but the branch
381
+ // it woke may still be hops away from its next draw. A later delivery
382
+ // consumed after that deregistration sees an empty gate set, and without
383
+ // this it would resolve mid-cascade and overtake the draw. This is the exact
384
+ // arrival-order dependence this mode exists to remove. Costs one quiet
385
+ // macrotask turn when nothing is in flight.
386
+ await quiesceEarlierCascades(ctx, eventIndex);
387
+ return;
388
+ }
389
+ if (earlier.length > 0) {
270
390
  // An earlier delivery being "delivered" only means its `resolve()` ran.
271
391
  // The branch it woke may need an arbitrary number of further microtask
272
- // hops before it reaches its next `useStep` call and draws a ULID a
392
+ // hops before it reaches its next `useStep` call and draws a ULID: a
273
393
  // `for await` over a hook, for instance, resumes the generator, settles
274
394
  // the promise from `next()`, and only then runs the loop body. Resolving
275
395
  // this delivery on a microtask would let it overtake that branch and
@@ -297,12 +417,12 @@ export async function awaitEarlierDeliveries(ctx, eventIndex, kind) {
297
417
  * suspending and never observes it), the barrier auto-resolves at idle.
298
418
  *
299
419
  * INVARIANT required of every call site: a barrier that is ever `armed` must
300
- * be paired with a delivery chain that runs unconditionally attached when
420
+ * be paired with a delivery chain that runs unconditionally, attached when
301
421
  * the event is consumed (waits, step results, waiting-consumer hook payloads,
302
422
  * aborts), or by the `claim()` whose invocation is what arms it (buffered
303
423
  * hook payloads). The idle check ({@link scheduleWhenIdle}) refuses to
304
424
  * observe idle while an armed, self-resolving barrier is undelivered, and the
305
- * safety net below is itself idle-gated so an armed barrier with no
425
+ * safety net below is itself idle-gated, so an armed barrier with no
306
426
  * unconditional chain would livelock every idle check in the run, including
307
427
  * its own retirement.
308
428
  */
@@ -336,7 +456,7 @@ export function registerDeliveryBarrier(ctx, eventIndex, kind, options = {}) {
336
456
  // it is retired at idle so a later delivery gated on it cannot deadlock and
337
457
  // the registry cannot leak an entry per abandoned delivery. Retirement goes
338
458
  // through the context's single ordered dispenser rather than a per-barrier
339
- // idle poll see {@link ensureBarrierSafetyNet} for why the ORDER of these
459
+ // idle poll. See {@link ensureBarrierSafetyNet} for why the ORDER of these
340
460
  // retirements is load-bearing.
341
461
  ensureBarrierSafetyNet(ctx);
342
462
  return {
@@ -351,6 +471,9 @@ export function registerDeliveryBarrier(ctx, eventIndex, kind, options = {}) {
351
471
  * so the context interface (constructed literally by many test harnesses)
352
472
  * needs no new field; entries drop with the context.
353
473
  */
474
+ // per-copy-ok: keyed on the orchestrator context object, and a context is armed
475
+ // and observed by the same copy that created it. Entries can never be looked up
476
+ // from another copy because that copy has no reference to the key.
354
477
  const activeBarrierSafetyNets = new WeakSet();
355
478
  /**
356
479
  * The barrier registry's safety net: ONE idle-gated dispenser per context that
@@ -360,13 +483,13 @@ const activeBarrierSafetyNets = new WeakSet();
360
483
  *
361
484
  * Why one ordered dispenser and not a poll per barrier (which is what this
362
485
  * replaced): the order of safety-net retirements decides the delivery order of
363
- * every chain parked behind an unclaimed buffered hook payload a hook the
486
+ * every chain parked behind an unclaimed buffered hook payload: a hook the
364
487
  * workflow never reads (a fire-and-forget `createHook`) parks every later
365
488
  * armed wait/hook behind a barrier that only this net can retire. Per-barrier
366
489
  * polls fire in whatever order their re-arm cycles land, and each re-arm
367
490
  * attaches to a `promiseQueue` that grows between checks, so with several
368
491
  * parked segments the release order decays to timing noise. Draws (`useStep`
369
- * correlation ids) then depend on which segment happened to release first
492
+ * correlation ids) then depend on which segment happened to release first:
370
493
  * concretely, on how MUCH log the replay loaded, since that decides what is in
371
494
  * the registry. That is the mechanism behind slot-mode CORRUPTED_EVENT_LOG on
372
495
  * storm-shaped runs (see storm-log-replay.test.ts, built from a production
@@ -376,12 +499,12 @@ const activeBarrierSafetyNets = new WeakSet();
376
499
  * Retiring lowest-first is not merely tidy, it is the only order that cannot
377
500
  * invert the log: every gate points from a higher index to a strictly lower
378
501
  * one, so at delivery idle the lowest undelivered entry gates on nothing
379
- * still registered it is the head of every parked chain (in practice, the
502
+ * still registered: it is the head of every parked chain (in practice, the
380
503
  * unclaimed payload itself). Releasing it lets the chain above deliver
381
504
  * through the ordinary barrier order; anything the release wakes flips
382
505
  * {@link hasParkedCommittedDelivery} back to true, which re-blocks this
383
506
  * dispenser until the chain has fully drained. A higher entry must never be
384
- * retired while a lower one is registered that is exactly the inversion
507
+ * retired while a lower one is registered, which is exactly the inversion
385
508
  * described on {@link awaitEarlierDeliveries}.
386
509
  *
387
510
  * The dispenser goes dormant when the registry empties and is re-armed by the
@@ -418,16 +541,16 @@ function ensureBarrierSafetyNet(ctx) {
418
541
  return;
419
542
  }
420
543
  // Idle with entries left: nothing remaining delivers on its own, so
421
- // release parked chains from the head lowest index first, one at a
544
+ // release parked chains from the head: lowest index first, one at a
422
545
  // time, re-reading idle between retirements. A retirement that wakes a
423
546
  // chain flips {@link hasParkedCommittedDelivery} synchronously (it is
424
547
  // computed from the registry this loop just mutated), which stops the
425
548
  // sweep so the chain delivers before anything above it is released. A
426
549
  // retirement that wakes nothing (a stale payload no delivery gates on)
427
550
  // keeps the sweep going, so a backlog of those drains in ONE idle
428
- // observation pacing them one per timer tick would hold consumed-but-
429
- // undelivered events hostage long enough to trip the events consumer's
430
- // unconsumed-event deadline and fail healthy replays.
551
+ // observation, since pacing them one per timer tick would hold
552
+ // consumed-but-undelivered events hostage long enough to trip the events
553
+ // consumer's unconsumed-event deadline and fail healthy replays.
431
554
  while (barriers.size > 0 && canRetireAbandonedBarriers(ctx)) {
432
555
  let lowestIndex;
433
556
  let lowestEntry;
@@ -456,19 +579,19 @@ function canRetireAbandonedBarriers(ctx) {
456
579
  /**
457
580
  * Whether some registered branch-deciding delivery is going to reach the
458
581
  * workflow without any further help (it is armed and not transitively parked
459
- * behind an unclaimed buffered payload see {@link resolvesOnItsOwn}) but
582
+ * behind an unclaimed buffered payload, see {@link resolvesOnItsOwn}) but
460
583
  * has not been handed over yet.
461
584
  *
462
585
  * This is the delivery state `pendingDeliveries` cannot see. That counter
463
586
  * covers the hydration window inside a serial `promiseQueue` slot and is
464
587
  * released there, while the delivery's `resolve()` runs later, from a
465
- * detached continuation behind {@link awaitEarlierDeliveries} including its
588
+ * detached continuation behind {@link awaitEarlierDeliveries}, including its
466
589
  * macrotask yield whenever the delivery had to defer. Replaying a batch of N
467
590
  * parallel step results consumed in one drain window leaves N-1 of them
468
591
  * parked on that yield with `pendingDeliveries` already at 0. An idle check
469
592
  * armed during the same window (a pending `sleep()` arms one on every replay)
470
593
  * could then observe "idle" mid-deferral and raise a `WorkflowSuspension`
471
- * BEFORE the workflow's own continuations ran a suspension carrying none of
594
+ * BEFORE the workflow's own continuations ran: a suspension carrying none of
472
595
  * the follow-up work the batch was about to create, which the runtime
473
596
  * dutifully schedules as nothing, leaving the run dormant until an unrelated
474
597
  * timer fires (vercel/workflow#3183).
@@ -477,7 +600,7 @@ function canRetireAbandonedBarriers(ctx) {
477
600
  * accuracy but for termination: an unclaimed buffered hook payload is retired
478
601
  * BY the idle safety net in {@link registerDeliveryBarrier}, so counting it
479
602
  * here would gate its own retirement. That reasoning extends to whatever is
480
- * parked behind such a payload a wait, and a step gating on that wait for
603
+ * parked behind such a payload (a wait, and a step gating on that wait) for
481
604
  * the same reason: the whole chain moves only once the net fires, and it
482
605
  * cannot fire while the chain is counted. Self-resolving deliveries always
483
606
  * deliver from their own chains (see the INVARIANT on
@@ -489,7 +612,7 @@ export function hasParkedCommittedDelivery(ctx) {
489
612
  if (!barriers || barriers.size === 0) {
490
613
  return false;
491
614
  }
492
- // Shared across this call only see `resolvesOnItsOwn`.
615
+ // Shared across this call only. See `resolvesOnItsOwn`.
493
616
  const selfResolving = new Map();
494
617
  for (const [index, entry] of barriers) {
495
618
  if (resolvesOnItsOwn(barriers, index, entry, selfResolving)) {
@@ -504,7 +627,7 @@ export function hasParkedCommittedDelivery(ctx) {
504
627
  * "In flight" is two distinct windows, each with its own guard:
505
628
  * `pendingDeliveries > 0` covers hydration inside the serial queue slots, and
506
629
  * {@link hasParkedCommittedDelivery} covers the detached gap between a slot
507
- * releasing that counter and the delivery's `resolve()` actually running
630
+ * releasing that counter and the delivery's `resolve()` actually running,
508
631
  * deliberately outside `pendingDeliveries` (see step.ts), and invisible to it.
509
632
  *
510
633
  * Anything that decides a replay is over, or that a replay went wrong, has to
@@ -517,7 +640,7 @@ export function hasParkedCommittedDelivery(ctx) {
517
640
  * entry is parked behind an unclaimed buffered payload. Those entries only
518
641
  * move when the safety-net dispenser retires them (lowest-first, see
519
642
  * {@link ensureBarrierSafetyNet}), and the deliveries they release are real
520
- * workflow reactions a suspension raised before they run would be computed
643
+ * workflow reactions: a suspension raised before they run would be computed
521
644
  * from a VM that has not seen them, scheduling none of their follow-up work
522
645
  * and leaving the run dormant (the vercel/workflow#3183 shape). The dispenser
523
646
  * itself is gated on {@link canRetireAbandonedBarriers}, the weaker predicate
@@ -566,4 +689,13 @@ export function scheduleWhenIdle(ctx, fn) {
566
689
  };
567
690
  setTimeout(check, 0);
568
691
  }
569
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJpdmF0ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9wcml2YXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBRUgsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBZ0JoRCxNQUFNLGtCQUFrQixHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsaUNBQWlDLENBQUMsQ0FBQztBQUV6RSxNQUFNLGFBQWEsR0FFZixVQUFVLENBQUM7QUFFZix3REFBd0Q7QUFDeEQsTUFBTSxlQUFlLEdBQUcsQ0FBQyxhQUFhLENBQUMsa0JBQWtCLENBQUMsS0FBSyxJQUFJLEdBQUcsRUFHbkUsQ0FBQyxDQUFDO0FBRUwsTUFBTSwyQkFBMkIsR0FBRyxJQUFJLEdBQUcsQ0FBQztJQUMxQyxpQ0FBaUM7SUFDakMseUJBQXlCO0lBQ3pCLHlCQUF5QjtDQUMxQixDQUFDLENBQUM7QUFFSCxTQUFTLHdCQUF3QixDQUFDLE1BQWM7SUFDOUMsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNqQyxJQUFJLEtBQUssQ0FBQyxNQUFNLEtBQUssQ0FBQyxJQUFJLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxNQUFNLEVBQUUsQ0FBQztRQUM5QyxPQUFPLEVBQUUsQ0FBQztJQUNaLENBQUM7SUFFRCxNQUFNLFVBQVUsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDNUIsTUFBTSxNQUFNLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3hCLE1BQU0saUJBQWlCLEdBQUcsSUFBSSxHQUFHLEVBQVUsQ0FBQztJQUU1QyxNQUFNLFFBQVEsR0FBRyxDQUFDLGVBQXVCLEVBQUUsRUFBRTtRQUMzQyxJQUFJLGVBQWUsS0FBSyxVQUFVLEVBQUUsQ0FBQztZQUNuQyxpQkFBaUIsQ0FBQyxHQUFHLENBQUMsZUFBZSxDQUFDLENBQUM7UUFDekMsQ0FBQztJQUNILENB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RCxPQUFPLEtBQUssQ0FBQztBQUNmLENBQUM7QUFFRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0EwQkc7QUFDSCxNQUFNLFVBQVUsY0FBYyxDQUFDLEdBQWdDO0lBQzdELE9BQU8sQ0FDTCxHQUFHLENBQUMsaUJBQWlCLEtBQUssQ0FBQztRQUMzQixDQUFDLENBQUMsR0FBRyxDQUFDLHVCQUF1QixJQUFJLEdBQUcsQ0FBQyx1QkFBdUIsQ0FBQyxJQUFJLEtBQUssQ0FBQyxDQUFDLENBQ3pFLENBQUM7QUFDSixDQUFDO0FBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBb0JHO0FBQ0gsTUFBTSxVQUFVLGdCQUFnQixDQUM5QixHQUFnQyxFQUNoQyxFQUFjO0lBRWQsTUFBTSxLQUFLLEdBQUcsR0FBRyxFQUFFO1FBQ2pCLElBQUksQ0FBQyxjQUFjLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUN6Qix1RUFBdUU7WUFDdkUscUVBQXFFO1lBQ3JFLHFFQUFxRTtZQUNyRSxHQUFHLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUU7Z0JBQ3pCLFVBQVUsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDdkIsQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDO2FBQU0sQ0FBQztZQUNOLEVBQUUsRUFBRSxDQUFDO1FBQ1AsQ0FBQztJQUNILENBQUMsQ0FBQztJQUNGLFVBQVUsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDdkIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogVXRpbHMgdXNlZCBieSB0aGUgYnVuZGxlciB3aGVuIHRyYW5zZm9ybWluZyBjb2RlXG4gKi9cblxuaW1wb3J0IHsgd2l0aFJlc29sdmVycyB9IGZyb20gJ0B3b3JrZmxvdy91dGlscyc7XG5pbXBvcnQgdHlwZSB7IFdvcmxkQ2FwYWJpbGl0aWVzIH0gZnJvbSAnQHdvcmtmbG93L3dvcmxkJztcbmltcG9ydCB0eXBlIHsgRXZlbnRzQ29uc3VtZXIgfSBmcm9tICcuL2V2ZW50cy1jb25zdW1lci5qcyc7XG5pbXBvcnQgdHlwZSB7IFF1ZXVlSXRlbSB9IGZyb20gJy4vZ2xvYmFsLmpzJztcbmltcG9ydCB0eXBlIHsgUmVwbGF5UGF5bG9hZENhY2hlIH0gZnJvbSAnLi9yZXBsYXktcGF5bG9hZC1jYWNoZS5qcyc7XG5pbXBvcnQgdHlwZSB7IFNlcmlhbGl6YWJsZSB9IGZyb20gJy4vc2NoZW1hcy5qcyc7XG5pbXBvcnQgdHlwZSB7IFBheWxvYWRLZXkgfSBmcm9tICcuL3NlcmlhbGl6YXRpb24vZW5jcnlwdGlvbi5qcyc7XG5cbmV4cG9ydCB0eXBlIFN0ZXBGdW5jdGlvbjxcbiAgQXJncyBleHRlbmRzIFNlcmlhbGl6YWJsZVtdID0gYW55W10sXG4gIFJlc3VsdCBleHRlbmRzIFNlcmlhbGl6YWJsZSB8IHVua25vd24gPSB1bmtub3duLFxuPiA9ICgoLi4uYXJnczogQXJncykgPT4gUHJvbWlzZTxSZXN1bHQ+KSAmIHtcbiAgbWF4UmV0cmllcz86IG51bWJlcjtcbiAgc3RlcElkPzogc3RyaW5nO1xufTtcblxuY29uc3QgUmVnaXN0ZXJlZFN0ZXBzS2V5ID0gU3ltYm9sLmZvcignQHdvcmtmbG93L2NvcmUvL3JlZ2lzdGVyZWRTdGVwcycpO1xuXG5jb25zdCBnbG9iYWxTeW1ib2xzOiB0eXBlb2YgZ2xvYmFsVGhpcyAmIHtcbiAgW1JlZ2lzdGVyZWRTdGVwc0tleV0/OiBNYXA8c3RyaW5nLCBTdGVwRnVuY3Rpb24+O1xufSA9IGdsb2JhbFRoaXM7XG5cbi8vIGJpb21lLWlnbm9yZSBsaW50L3N1c3BpY2lvdXMvbm9Bc3NpZ25JbkV4cHJlc3Npb25zOiAvXG5jb25zdCByZWdpc3RlcmVkU3RlcHMgPSAoZ2xvYmFsU3ltYm9sc1tSZWdpc3RlcmVkU3RlcHNLZXldID8/PSBuZXcgTWFwPFxuICBzdHJpbmcsXG4gIFN0ZXBGdW5jdGlvblxuPigpKTtcblxuY29uc3QgQlVJTFRJTl9SRVNQT05TRV9TVEVQX05BTUVTID0gbmV3IFNldChbXG4gICdfX2J1aWx0aW5fcmVzcG9uc2VfYXJyYXlfYnVmZmVyJyxcbiAgJ19fYnVpbHRpbl9yZXNwb25zZV9qc29uJyxcbiAgJ19fYnVpbHRpbl9yZXNwb25zZV90ZXh0Jyxcbl0pO1xuXG5mdW5jdGlvbiBnZXRTdGVwSWRBbGlhc0NhbmRpZGF0ZXMoc3RlcElkOiBzdHJpbmcpOiBzdHJpbmdbXSB7XG4gIGNvbnN0IHBhcnRzID0gc3RlcElkLnNwbGl0KCcvLycpO1xuICBpZiAocGFydHMubGVuZ3RoICE9PSAzIHx8IHBhcnRzWzBdICE9PSAnc3RlcCcpIHtcbiAgICByZXR1cm4gW107XG4gIH1cblxuICBjb25zdCBtb2R1bGVQYXRoID0gcGFydHNbMV07XG4gIGNvbnN0IGZuTmFtZSA9IHBhcnRzWzJdO1xuICBjb25zdCBtb2R1bGVQYXRoQWxpYXNlcyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuXG4gIGNvbnN0IGFkZEFsaWFzID0gKGFsaWFzTW9kdWxlUGF0aDogc3RyaW5nKSA9PiB7XG4gICAgaWYgKGFsaWFzTW9kdWxlUGF0aCAhPT0gbW9kdWxlUGF0aCkge1xuICAgICAgbW9kdWxlUGF0aEFsaWFzZXMuYWRkKGFsaWFzTW9kdWxlUGF0aCk7XG4gICAgfVxuICB9O1xuXG4gIGlmIChtb2R1bGVQYXRoLnN0YXJ0c1dpdGgoJy4vd29ya2Zsb3dzLycpKSB7XG4gICAgY29uc3Qgd29ya2Zsb3dSZWxhdGl2ZVBhdGggPSBtb2R1bGVQYXRoLnNsaWNlKCcuLycubGVuZ3RoKTtcbiAgICBhZGRBbGlhcyhgLi9leGFtcGxlLyR7d29ya2Zsb3dSZWxhdGl2ZVBhdGh9YCk7XG4gICAgYWRkQWxpYXMoYC4vc3JjLyR7d29ya2Zsb3dSZWxhdGl2ZVBhdGh9YCk7XG4gIH0gZWxzZSBpZiAobW9kdWxlUGF0aC5zdGFydHNXaXRoKCcuL2V4YW1wbGUvd29ya2Zsb3dzLycpKSB7XG4gICAgY29uc3Qgd29ya2Zsb3dSZWxhdGl2ZVBhdGggPSBtb2R1bGVQYXRoLnNsaWNlKCcuL2V4YW1wbGUvJy5sZW5ndGgpO1xuICAgIGFkZEFsaWFzKGAuLyR7d29ya2Zsb3dSZWxhdGl2ZVBhdGh9YCk7XG4gICAgYWRkQWxpYXMoYC4vc3JjLyR7d29ya2Zsb3dSZWxhdGl2ZVBhdGh9YCk7XG4gIH0gZWxzZSBpZiAobW9kdWxlUGF0aC5zdGFydHNXaXRoKCcuL3NyYy93b3JrZmxvd3MvJykpIHtcbiAgICBjb25zdCB3b3JrZmxvd1JlbGF0aXZlUGF0aCA9IG1vZHVsZVBhdGguc2xpY2UoJy4vc3JjLycubGVuZ3RoKTtcbiAgICBhZGRBbGlhcyhgLi8ke3dvcmtmbG93UmVsYXRpdmVQYXRofWApO1xuICAgIGFkZEFsaWFzKGAuL2V4YW1wbGUvJHt3b3JrZmxvd1JlbGF0aXZlUGF0aH1gKTtcbiAgfVxuXG4gIHJldHVybiBBcnJheS5mcm9tKFxuICAgIG1vZHVsZVBhdGhBbGlhc2VzLFxuICAgIChhbGlhc01vZHVsZVBhdGgpID0+IGBzdGVwLy8ke2FsaWFzTW9kdWxlUGF0aH0vLyR7Zm5OYW1lfWBcbiAgKTtcbn1cblxuZnVuY3Rpb24gZ2V0QnVpbHRpblJlc3BvbnNlU3RlcEFsaWFzKHN0ZXBJZDogc3RyaW5nKTogU3RlcEZ1bmN0aW9uIHwgdW5kZWZpbmVkIHtcbiAgaWYgKCFCVUlMVElOX1JFU1BPTlNFX1NURVBfTkFNRVMuaGFzKHN0ZXBJZCkpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgZm9yIChjb25zdCBbcmVnaXN0ZXJlZFN0ZXBJZCwgc3RlcEZuXSBvZiByZWdpc3RlcmVkU3RlcHMuZW50cmllcygpKSB7XG4gICAgaWYgKHJlZ2lzdGVyZWRTdGVwSWQuZW5kc1dpdGgoYC8vJHtzdGVwSWR9YCkpIHtcbiAgICAgIHJldHVybiBzdGVwRm47XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBSZWdpc3RlciBhIHN0ZXAgZnVuY3Rpb24gdG8gYmUgc2VydmVkIGluIHRoZSBzZXJ2ZXIgYnVuZGxlLlxuICogQWxzbyBzZXRzIHRoZSBzdGVwSWQgcHJvcGVydHkgb24gdGhlIGZ1bmN0aW9uIGZvciBzZXJpYWxpemF0aW9uIHN1cHBvcnQuXG4gKlxuICogTm90ZTogVGhlIFNXQyBjb21waWxlciBwbHVnaW4gbm8gbG9uZ2VyIGdlbmVyYXRlcyBjYWxscyB0byB0aGlzIGZ1bmN0aW9uLlxuICogU3RlcCByZWdpc3RyYXRpb24gaXMgbm93IGlubGluZWQgYXMgYSBzZWxmLWNvbnRhaW5lZCBJSUZFIHRoYXQgd3JpdGVzXG4gKiBkaXJlY3RseSB0byB0aGUgZ2xvYmFsIE1hcCBhdCBTeW1ib2wuZm9yKFwiQHdvcmtmbG93L2NvcmUvL3JlZ2lzdGVyZWRTdGVwc1wiKS5cbiAqIFRoaXMgZnVuY3Rpb24gaXMga2VwdCBmb3IgaW50ZXJuYWwvdGVzdCB1c2Ugb25seS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlZ2lzdGVyU3RlcEZ1bmN0aW9uKHN0ZXBJZDogc3RyaW5nLCBzdGVwRm46IFN0ZXBGdW5jdGlvbikge1xuICByZWdpc3RlcmVkU3RlcHMuc2V0KHN0ZXBJZCwgc3RlcEZuKTtcbiAgc3RlcEZuLnN0ZXBJZCA9IHN0ZXBJZDtcbn1cblxuLyoqXG4gKiBGaW5kIGEgcmVnaXN0ZXJlZCBzdGVwIGZ1bmN0aW9uIGJ5IG5hbWVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFN0ZXBGdW5jdGlvbihzdGVwSWQ6IHN0cmluZyk6IFN0ZXBGdW5jdGlvbiB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IGRpcmVjdE1hdGNoID0gcmVnaXN0ZXJlZFN0ZXBzLmdldChzdGVwSWQpO1xuICBpZiAoZGlyZWN0TWF0Y2gpIHtcbiAgICByZXR1cm4gZGlyZWN0TWF0Y2g7XG4gIH1cblxuICAvLyBTdXBwb3J0IGVxdWl2YWxlbnQgd29ya2Zsb3cgcGF0aCBhbGlhc2VzIGluIG1peGVkIHN5bWxpbmsgZW52aXJvbm1lbnRzLlxuICBmb3IgKGNvbnN0IGFsaWFzU3RlcElkIG9mIGdldFN0ZXBJZEFsaWFzQ2FuZGlkYXRlcyhzdGVwSWQpKSB7XG4gICAgY29uc3QgYWxpYXNNYXRjaCA9IHJlZ2lzdGVyZWRTdGVwcy5nZXQoYWxpYXNTdGVwSWQpO1xuICAgIGlmIChhbGlhc01hdGNoKSB7XG4gICAgICByZXR1cm4gYWxpYXNNYXRjaDtcbiAgICB9XG4gIH1cblxuICBjb25zdCBidWlsdGluQWxpYXNNYXRjaCA9IGdldEJ1aWx0aW5SZXNwb25zZVN0ZXBBbGlhcyhzdGVwSWQpO1xuICBpZiAoYnVpbHRpbkFsaWFzTWF0Y2gpIHtcbiAgICByZXR1cm4gYnVpbHRpbkFsaWFzTWF0Y2g7XG4gIH1cblxuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG4vLyBOb3RlOiBfX3ByaXZhdGVfZ2V0Q2xvc3VyZVZhcnMgaXMgbm8gbG9uZ2VyIHJlLWV4cG9ydGVkIGhlcmUuXG4vLyBUaGUgU1dDIGNvbXBpbGVyIHBsdWdpbiBub3cgaW5saW5lcyBjbG9zdXJlIHZhcmlhYmxlIGFjY2VzcyBhcyBhXG4vLyBzZWxmLWNvbnRhaW5lZCBJSUZFIHRoYXQgcmVhZHMgZGlyZWN0bHkgZnJvbSB0aGUgZ2xvYmFsIEFzeW5jTG9jYWxTdG9yYWdlXG4vLyBhdCBTeW1ib2wuZm9yKFwiV09SS0ZMT1dfU1RFUF9DT05URVhUX1NUT1JBR0VcIikuXG5cbmV4cG9ydCBpbnRlcmZhY2UgV29ya2Zsb3dPcmNoZXN0cmF0b3JDb250ZXh0IHtcbiAgcnVuSWQ6IHN0cmluZztcbiAgZW5jcnlwdGlvbktleTogUGF5bG9hZEtleSB8IHVuZGVmaW5lZDtcbiAgd29ybGRDYXBhYmlsaXRpZXM/OiBXb3JsZENhcGFiaWxpdGllcztcbiAgZ2xvYmFsVGhpczogdHlwZW9mIGdsb2JhbFRoaXM7XG4gIC8qKlxuICAgKiBJbmNyZW1lbnRzIHdoZW4gYSBzdXNwZW5zaW9uIGlzIGFjY2VwdGVkIGFuZCBvbiBldmVyeSByZXRhaW5lZC1zZXNzaW9uXG4gICAqIHJlc3VtZS4gU1RFUCBzdXNwZW5zaW9uIHNpZ25hbHMgY2FwdHVyZSBpdCB3aGVuIHNjaGVkdWxlZCBhbmQgbm8tb3AgaWZcbiAgICogaXQgbW92ZWQgKHNlZSBzdGVwLnRzKSDigJQgdGhpcyBkcm9wcyBzYW1lLWJvdW5kYXJ5IHNpYmxpbmcgc2lnbmFscyBhbmRcbiAgICogdGltZXJzIHF1ZXVlZCBhdCBib3VuZGFyeSBOIHRoYXQgd291bGQgZmlyZSBhZnRlciB0aGUgc2Vzc2lvbiByZXN1bWVkXG4gICAqIGludG8gYm91bmRhcnkgTisxLiBTbGVlcC9ob29rL2F0dHJpYnV0ZSBzaWduYWxzIGFyZSBpbnRlbnRpb25hbGx5XG4gICAqIHVuZ3VhcmRlZDogdGhlaXIgcHJlc2VuY2UgbWFrZXMgdGhlIGJvdW5kYXJ5IHVucmV0YWluYWJsZSwgc28gYSBsYXRlXG4gICAqIHNpZ25hbCBjb3JyZWN0bHkgZGVtb3RlcyB0aGUgc2Vzc2lvbiAod29ya2Zsb3cudHMgYG9uV29ya2Zsb3dFcnJvcmApLlxuICAgKi9cbiAgc3VzcGVuc2lvbkdlbmVyYXRpb246IG51bWJlcjtcbiAgZXZlbnRzQ29uc3VtZXI6IEV2ZW50c0NvbnN1bWVyO1xuICAvKipcbiAgICogTWFwIG9mIHBlbmRpbmcgaW52b2NhdGlvbnMga2V5ZWQgYnkgY29ycmVsYXRpb25JZC5cbiAgICogVXNpbmcgTWFwIGluc3RlYWQgb2YgQXJyYXkgZm9yIE8oMSkgbG9va3VwL2RlbGV0ZSBvcGVyYXRpb25zLlxuICAgKi9cbiAgaW52b2NhdGlvbnNRdWV1ZTogTWFwPHN0cmluZywgUXVldWVJdGVtPjtcbiAgb25Xb3JrZmxvd0Vycm9yOiAoZXJyb3I6IEVycm9yKSA9PiB2b2lkO1xuICAvKipcbiAgICogTWludHMgdGhlIFVMSUQgYm9keSBvZiBhIGNvcnJlbGF0aW9uIGlkLiBFdmVyeSBlbnRpdHkgYSByZXBsYXkgY3JlYXRlc1xuICAgKiBkcmF3cyBmcm9tIHRoaXMgb25lIG1vbm90b25pYyBzZXF1ZW5jZSwgc28gYW4gaWQgaXMgYW4gb3JkaW5hbCBvdmVyIHRoZVxuICAgKiB3aG9sZSBydW4gYW5kIGJvdGggcmVwbGF5cyBvZiBhIHJ1biBtdXN0IGRyYXcgaW4gdGhlIHNhbWUgb3JkZXIuXG4gICAqL1xuICBnZW5lcmF0ZVVsaWQ6ICgpID0+IHN0cmluZztcbiAgZ2VuZXJhdGVOYW5vaWQ6ICgpID0+IHN0cmluZztcbiAgLyoqXG4gICAqIFNlcXVlbnRpYWwgcHJvbWlzZSBxdWV1ZSB0aGF0IGVuc3VyZXMgYWxsIGV2ZW50LWRyaXZlbiBwcm9taXNlIHJlc29sdXRpb25zXG4gICAqIChzdGVwIHJlc3VsdHMsIGhvb2sgcGF5bG9hZHMsIGZhaWx1cmVzLCBzdXNwZW5zaW9ucykgaGFwcGVuIGluIGV2ZW50IGxvZ1xuICAgKiBvcmRlci4gRXZlcnkgcmVzb2x2ZSwgcmVqZWN0LCBvciB3b3JrZmxvdyBlcnJvciBpcyBjaGFpbmVkIHRocm91Z2ggdGhpc1xuICAgKiBxdWV1ZSBzbyB0aGF0IGV2ZW4gaWYgaW5kaXZpZHVhbCBvcGVyYXRpb25zIHRha2UgdmFyaWFibGUgdGltZSAoZS5nLixcbiAgICogYXN5bmMgZGVjcnlwdGlvbiksIHByb21pc2VzIHJlc29sdmUgZGV0ZXJtaW5pc3RpY2FsbHkuXG4gICAqL1xuICBwcm9taXNlUXVldWU6IFByb21pc2U8dm9pZD47XG4gIC8qKlxuICAgKiBDb3VudGVyIG9mIGluLWZsaWdodCBhc3luYyBkYXRhIGRlbGl2ZXJ5IG9wZXJhdGlvbnMgKHN0ZXAgcmVzdWx0XG4gICAqIGh5ZHJhdGlvbiwgaG9vayBwYXlsb2FkIGh5ZHJhdGlvbiwgYWJvcnQgc2lnbmFsIGh5ZHJhdGlvbikuIFN1c3BlbnNpb25zXG4gICAqIG11c3Qgd2FpdCBmb3IgdGhpcyB0byByZWFjaCAwIGJlZm9yZSBmaXJpbmcsIHRvIGF2b2lkIHByZWVtcHRpbmcgZGF0YVxuICAgKiBkZWxpdmVyeSDigJQgZS5nLiBkZWh5ZHJhdGluZyBhIHN0ZXAncyBhcmd1bWVudHMgd2hpbGUgYW4gYWJvcnQgdGhhdCBzaG91bGRcbiAgICogYmUgcmVmbGVjdGVkIGluIHRob3NlIGFyZ3VtZW50cyBpcyBzdGlsbCBoeWRyYXRpbmcgaXRzIHJlYXNvbi5cbiAgICovXG4gIHBlbmRpbmdEZWxpdmVyaWVzOiBudW1iZXI7XG4gIC8qKlxuICAgKiBPcmRlcmVkIHJlZ2lzdHJ5IG9mIGluLWZsaWdodCBcImJyYW5jaC1kZWNpZGluZ1wiIGRlbGl2ZXJpZXMg4oCUIHRoZVxuICAgKiByZXNvbHV0aW9ucyBhIHdvcmtmbG93IHR5cGljYWxseSBgUHJvbWlzZS5yYWNlYHMgb24sIG9yIGF3YWl0cyBmcm9tXG4gICAqIGluZGVwZW5kZW50IGNvbmN1cnJlbnQgYnJhbmNoZXM6IGhvb2sgcGF5bG9hZHMgKGBob29rX3JlY2VpdmVkYCksIHdhaXRcbiAgICogY29tcGxldGlvbnMgKGB3YWl0X2NvbXBsZXRlZGApLCBhbmQgc3RlcCByZXN1bHRzIChgc3RlcF9jb21wbGV0ZWRgIC9cbiAgICogYHN0ZXBfZmFpbGVkYCkuIEtleWVkIGJ5IHRoZSBkZWxpdmVyeSdzIHBvc2l0aW9uIChpbmRleCkgaW4gdGhlIGNvbnN1bWVkXG4gICAqIGV2ZW50IGxvZy5cbiAgICpcbiAgICogVGhlIHByb2JsZW06IGVhY2ggb2YgdGhlc2UgcmVzb2x1dGlvbnMgcmVhY2hlcyB3b3JrZmxvdyBjb2RlIGFmdGVyIGFcbiAgICogZGlmZmVyZW50LCB3b3JrbG9hZC1kZXBlbmRlbnQgbnVtYmVyIG9mIG1pY3JvdGFzayBob3BzLiBBIGJ1ZmZlcmVkIGhvb2tcbiAgICogcGF5bG9hZCBpcyBvYnNlcnZlZCB2aWEgdGhlIGFzeW5jIGhvb2sgaXRlcmF0b3IgKGB5aWVsZCBhd2FpdCB0aGlzYCksXG4gICAqIGNvc3RpbmcgZXh0cmEgaG9wczsgYSBgd2FpdF9jb21wbGV0ZWRgIHJlc29sdmVzIHdpdGggZmV3ZXIsIGFuZCBhIHJldXNlZFxuICAgKiBzbGVlcCBjYW4gcmVzb2x2ZSBpbiBhbiBlbnRpcmVseSBlYXJsaWVyIGxvb3AgaXRlcmF0aW9uOyBhIHN0ZXAgcmVzdWx0IGlzXG4gICAqIGdhdGVkIG9uIGh5ZHJhdGlvbiB3aG9zZSBjb3N0IHZhcmllcyBiZXR3ZWVuIHJlcGxheXMgb2YgdGhlIFNBTUVcbiAgICogaW52b2NhdGlvbiDigJQgdGhlIGZpcnN0IHJlcGxheSBwYXlzIHRoZSBmdWxsIGRlY3J5cHQvZGVjb21wcmVzcy9yZXZpdmUsXG4gICAqIHdoaWxlIGxhdGVyIHJlcGxheXMgc2hhcmluZyB0aGUgaW52b2NhdGlvbidzIGBSZXBsYXlQYXlsb2FkQ2FjaGVgXG4gICAqIG1lbW8taGl0IHNtYWxsIHByaW1pdGl2ZSByZXN1bHRzIGFuZCByZXNvbHZlIGluIG9uZSBvciB0d28gaG9wcy4gRWl0aGVyXG4gICAqIHdheSwgdGhlIHJlc29sdXRpb24gdGhhdCB0aGUgY29tbWl0dGVkIGV2ZW50IGxvZyBvcmRlcmVkIGZpcnN0IGNhbiBsb3NlIGFcbiAgICogYFByb21pc2UucmFjZWAgKG9yIGEgYHVzZVN0ZXBgIFVMSUQgYWxsb2NhdGlvbikgdG8gYSBmYXN0ZXItIG9yXG4gICAqIGFscmVhZHktcmVzb2x2ZWQgY29tcGV0aXRvciwgZGl2ZXJnaW5nIGZyb20gdGhlIGxvZyBhbmQgc3VyZmFjaW5nIGFzXG4gICAqIGBDb3JydXB0ZWRFdmVudExvZ0Vycm9yYC5cbiAgICpcbiAgICogVGhlIGZpeCBpcyBhIHN0cmljdCwgZGV0ZXJtaW5pc3RpYyBkZWxpdmVyeSBvcmRlciBhbmNob3JlZCBvblxuICAgKiBldmVudC1sb2cgcG9zaXRpb246IGEgZGVsaXZlcnkgZG9lcyBub3QgcmVzb2x2ZSB0byB0aGUgd29ya2Zsb3cgdW50aWxcbiAgICogZXZlcnkgcmVsZXZhbnQgZWFybGllci1pbi1sb2cgZGVsaXZlcnkgaGFzIGJlZW4gZGVsaXZlcmVkLiBCZWNhdXNlIHRoZVxuICAgKiBnYXRlIGlzIFwidGhlIGVhcmxpZXIgZGVsaXZlcnkgcmVzb2x2ZWRcIiwgbm90IFwid29uIGEgdGltaW5nIHJhY2VcIiwgdGhlXG4gICAqIG91dGNvbWUgaXMgaW5kZXBlbmRlbnQgb2YgbWljcm90YXNrIGhvcHMsIGh5ZHJhdGlvbi9kZWNyeXB0aW9uIHRpbWUsXG4gICAqIGFuZCBgUHJvbWlzZS5yYWNlYCBhcmd1bWVudCBvcmRlci4gV2hpY2ggZWFybGllciBraW5kcyBhIGRlbGl2ZXJ5IGRlZmVyc1xuICAgKiBiZWhpbmQgaXMgc3BlbGxlZCBvdXQgb24ge0BsaW5rIGF3YWl0RWFybGllckRlbGl2ZXJpZXN9LlxuICAgKlxuICAgKiBJbmRleCBpcyB1c2VkIHJhdGhlciB0aGFuIHRoZSBgZXZlbnRJZGAgc3RyaW5nIGJlY2F1c2UgYGV2ZW50SWRgIGlzIGFuXG4gICAqIG9wYXF1ZSwgd29ybGQtYXNzaWduZWQgdmFsdWUgbm90IGd1YXJhbnRlZWQgdG8gc29ydCBpbiBjcmVhdGlvbiBvcmRlclxuICAgKiAob25seSB0aGUgYnVuZGxlZCBVTElEIHdvcmxkcyBoYXBwZW4gdG8pLlxuICAgKlxuICAgKiBPcHRpb25hbCBzbyBvbGRlci9vdXQtb2YtdHJlZSBjb250ZXh0cyAoYW5kIGxpZ2h0d2VpZ2h0IHRlc3QgaGFybmVzc2VzKVxuICAgKiB0aGF0IGRvIG5vdCBpbml0aWFsaXplIGl0IGRlZ3JhZGUgZ3JhY2VmdWxseSB0byB0aGUgcHJldmlvdXMgYmVoYXZpb3IuXG4gICAqL1xuICBwZW5kaW5nRGVsaXZlcnlCYXJyaWVycz86IE1hcDxudW1iZXIsIERlbGl2ZXJ5QmFycmllckVudHJ5PjtcbiAgLyoqXG4gICAqIEludm9jYXRpb24tc2NvcGVkIGNhY2hlIG9mIHByZXBhcmVkIHNlcmlhbGl6ZWQgcGF5bG9hZHMgYW5kIGltbXV0YWJsZSBmaW5hbFxuICAgKiB2YWx1ZXMuIFByZXBhcmVkIGJ5dGVzIHN1cnZpdmUgZnJlc2ggcmVwbGF5IFZNczsgb2JqZWN0IGdyYXBocyBkbyBub3QuXG4gICAqL1xuICByZXBsYXlQYXlsb2FkQ2FjaGU6IFJlcGxheVBheWxvYWRDYWNoZTtcbn1cblxuLyoqIFRoZSBraW5kIG9mIGJyYW5jaC1kZWNpZGluZyBkZWxpdmVyeSBhIGJhcnJpZXIgcmVwcmVzZW50cy4gKi9cbmV4cG9ydCB0eXBlIERlbGl2ZXJ5S2luZCA9ICdob29rJyB8ICd3YWl0JyB8ICdzdGVwJztcblxuaW50ZXJmYWNlIERlbGl2ZXJ5QmFycmllckVudHJ5IHtcbiAga2luZDogRGVsaXZlcnlLaW5kO1xuICAvKiogUmVzb2x2ZXMgb25jZSB0aGlzIGRlbGl2ZXJ5IGhhcyByZXNvbHZlZCB0byB0aGUgd29ya2Zsb3cuICovXG4gIGRlbGl2ZXJlZDogUHJvbWlzZTx2b2lkPjtcbiAgLyoqXG4gICAqIFdoZXRoZXIgdGhpcyBkZWxpdmVyeSBpcyBjb21taXR0ZWQgdG8gcmVhY2hpbmcgdGhlIHdvcmtmbG93IHdpdGhvdXQgYW55XG4gICAqIGZ1cnRoZXIgYWN0aW9uIGJ5IHdvcmtmbG93IGNvZGUuIFRydWUgZm9yIHdhaXQgY29tcGxldGlvbnMgYW5kIHN0ZXBcbiAgICogcmVzdWx0cywgd2hpY2ggYWx3YXlzIHJlc29sdmUgZnJvbSB0aGVpciBvd24gY2hhaW4sIGFuZCBmb3IgYSBob29rIHBheWxvYWRcbiAgICogdGhhdCBhbHJlYWR5IGhhZCBhIHdhaXRpbmcgY29uc3VtZXIgd2hlbiBpdCB3YXMgY29uc3VtZWQuXG4gICAqXG4gICAqIEZhbHNlIGZvciBhIEJVRkZFUkVEIGhvb2sgcGF5bG9hZCBubyBjb25zdW1lciBoYXMgY2xhaW1lZCB5ZXQ6IGl0IGlzXG4gICAqIGRlbGl2ZXJlZCBieSBgY2xhaW0oKWAsIGkuZS4gd2hlbmV2ZXIgdGhlIHdvcmtmbG93IG5leHQgcmVhZHMgdGhlIGhvb2sg4oCUXG4gICAqIHdoaWNoIG1heSBiZSBjYXVzYWxseSAqYWZ0ZXIqIGEgbGF0ZXItaW4tbG9nIGRlbGl2ZXJ5LiBgYXJtKClgIGZsaXBzIGl0XG4gICAqIG9uY2UgYSBjb25zdW1lciB0YWtlcyB0aGUgcGF5bG9hZC5cbiAgICovXG4gIGFybWVkOiBib29sZWFuO1xuICAvKipcbiAgICogUmV0aXJlIHRoaXMgZW50cnk6IHJlc29sdmUgYGRlbGl2ZXJlZGAgYW5kIHJlbW92ZSBpdCBmcm9tIHRoZSByZWdpc3RyeSxcbiAgICogZXhhY3RseSBhcyBgbWFya0RlbGl2ZXJlZGAgd291bGQuIENhbGxlZCBvbmx5IGJ5IHRoZSBjb250ZXh0J3Mgc2FmZXR5LW5ldFxuICAgKiBkaXNwZW5zZXIgKHtAbGluayBlbnN1cmVCYXJyaWVyU2FmZXR5TmV0fSksIGFuZCBvbmx5IG9uIHRoZSBsb3dlc3QtaW5kZXhcbiAgICogZW50cnkgYXQgZGVsaXZlcnkgaWRsZS4gSWRlbXBvdGVudC5cbiAgICovXG4gIHJldGlyZTogKCkgPT4gdm9pZDtcbn1cblxuLyoqXG4gKiBXaGljaCBlYXJsaWVyIGtpbmRzIGVhY2ggZGVsaXZlcnkga2luZCBkZWZlcnMgYmVoaW5kLiBDaG9zZW4gc28gdGhhdCBubyBraW5kXG4gKiBibG9ja3Mgb24gYSBwZWVyIGl0IGRvZXMgbm90IG5lZWQgdG86XG4gKlxuICogIC0gYSBob29rIGRlZmVycyBiZWhpbmQgZWFybGllciBIT09LUywgV0FJVFMgYW5kIFNURVBTO1xuICogIC0gYSB3YWl0IGRlZmVycyBiZWhpbmQgZWFybGllciBIT09LUyBhbmQgU1RFUFMg4oCUIG5vdCBlYXJsaWVyIHdhaXRzLCBzaW5jZSBhXG4gKiAgICB3YWl0IG5ldmVyIG5lZWRzIHRvIHF1ZXVlIGJlaGluZCBhbm90aGVyIHdhaXQ7XG4gKiAgLSBhIHN0ZXAgZGVmZXJzIGJlaGluZCBlYXJsaWVyIFdBSVRTLCBIT09LUyBhbmQgU1RFUFMuXG4gKlxuICogVGhlIHN0ZXAtYmVoaW5kLXN0ZXAgZWRnZSBpcyBub3QgcmVkdW5kYW50IHdpdGggdGhlIHNlcmlhbCBgcHJvbWlzZVF1ZXVlYC5cbiAqIFRoZSBxdWV1ZSBmaXhlcyB0aGUgb3JkZXIgaW4gd2hpY2ggc3RlcCByZXN1bHRzIGFyZSBIWURSQVRFRCwgYnV0IGEgc3RlcCBub1xuICogbG9uZ2VyIHJlc29sdmVzIGluc2lkZSBpdHMgcXVldWUgc2xvdCDigJQgaXQgY2FwdHVyZXMgdGhlIG91dGNvbWUgdGhlcmUgYW5kXG4gKiByZXNvbHZlcyBmcm9tIGEgZGV0YWNoZWQgY29udGludWF0aW9uIG9uY2UgaXRzIGJhcnJpZXIgY2xlYXJzLiBUd28gc3RlcHNcbiAqIGFncmVlIG9uIHRoYXQgY29udGludWF0aW9uJ3Mgb3JkZXJpbmcgb25seSB3aGlsZSB0aGV5IGRlZmVyIGJlaGluZCB0aGUgc2FtZVxuICogc2V0LCB3aGljaCBob2xkcyB3aGVuIHRoZXkgYXJlIGNvbnN1bWVkIGluIHRoZSBzYW1lIGRyYWluIHdpbmRvdyBidXQgbm90XG4gKiBhY3Jvc3Mgd2luZG93czogYSBzdGVwIGNvbnN1bWVkIGxhdGVyIGNhbiBtaXNzIGEgd2FpdC9ob29rIGJhcnJpZXIgdGhhdCBhblxuICogZWFybGllciBzdGVwIGlzIHN0aWxsIHBhcmtlZCBvbiwgYmVjYXVzZSB0aGUgYmFycmllciByZXRpcmVkIGluIGJldHdlZW4uIFRoZVxuICogZWFybGllciBzdGVwIGlzIHRoZW4gd2FpdGluZyBvdXQgdGhlIG1hY3JvdGFzayB5aWVsZCBiZWxvdyB3aGlsZSB0aGUgbGF0ZXJcbiAqIG9uZSByZXNvbHZlcyBvbiBtaWNyb3Rhc2tzLCBhbmQgb3ZlcnRha2VzIGl0IOKAlCBzZWVcbiAqIGBkZWxpdmVyeS1iYXJyaWVyLWNvdmVyYWdlLnRlc3QudHNgLiBEZWZlcnJpbmcgYmVoaW5kIGVhcmxpZXIgc3RlcHNcbiAqIGNsb3NlcyB0aGF0IHdpbmRvdyBzdHJ1Y3R1cmFsbHk6IHRoZSBlYXJsaWVyIHN0ZXAncyBiYXJyaWVyIGlzIHN0aWxsXG4gKiByZWdpc3RlcmVkIHByZWNpc2VseSBiZWNhdXNlIGl0IGhhcyBub3QgZGVsaXZlcmVkIHlldC5cbiAqXG4gKiBFdmVyeSBlZGdlIHBvaW50cyBmcm9tIGEgbGF0ZXIgbG9nIGluZGV4IHRvIGEgc3RyaWN0bHkgZWFybGllciBvbmUsIHNvIHRoZVxuICogd2FpdC1mb3IgZ3JhcGggY2FuIG5ldmVyIGNvbnRhaW4gYSBjeWNsZS5cbiAqL1xuY29uc3QgREVGRVJfQkVISU5EOiBSZWNvcmQ8RGVsaXZlcnlLaW5kLCByZWFkb25seSBEZWxpdmVyeUtpbmRbXT4gPSB7XG4gIGhvb2s6IFsnaG9vaycsICd3YWl0JywgJ3N0ZXAnXSxcbiAgd2FpdDogWydob29rJywgJ3N0ZXAnXSxcbiAgc3RlcDogWyd3YWl0JywgJ2hvb2snLCAnc3RlcCddLFxufTtcblxuLyoqXG4gKiBXaGV0aGVyIGEgZGVsaXZlcnkgb2YgYGtpbmRgIGF0IGxvZyBpbmRleCBgaW5kZXhgIGdhdGVzIG9uIHRoZSBlYXJsaWVyXG4gKiByZWdpc3RyeSBlbnRyeSBgb3RoZXJgIChhdCBgb3RoZXJJbmRleGApLlxuICpcbiAqIFNpbmdsZSBzb3VyY2Ugb2YgdHJ1dGggZm9yIHRoYXQgcXVlc3Rpb24sIGNhbGxlZCBieSBib3RoXG4gKiB7QGxpbmsgYXdhaXRFYXJsaWVyRGVsaXZlcmllc30gKHdoaWNoIGF3YWl0cyB3aGF0IGl0IGdhdGVzIG9uKSBhbmRcbiAqIHtAbGluayBjb21wdXRlUmVzb2x2ZXNPbkl0c093bn0gKHdoaWNoIHJlY3Vyc2VzIGludG8gd2hhdCBpdCBnYXRlcyBvbikuXG4gKiBUaG9zZSB0d28gTVVTVCBhZ3JlZSBleGFjdGx5LCBhbmQgdGhlIGRvYyBibG9jayBvblxuICoge0BsaW5rIGF3YWl0RWFybGllckRlbGl2ZXJpZXN9IHN0YWtlcyBkZWFkbG9jay1mcmVlZG9tIG9uIGl0LCBzbyB0aGVcbiAqIGNvbmRpdGlvbiBsaXZlcyBoZXJlIHJhdGhlciB0aGFuIGJlaW5nIHNwZWxsZWQgb3V0IHR3aWNlLlxuICovXG5mdW5jdGlvbiBnYXRlc09uKFxuICBraW5kOiBEZWxpdmVyeUtpbmQsXG4gIGluZGV4OiBudW1iZXIsXG4gIG90aGVySW5kZXg6IG51bWJlcixcbiAgb3RoZXI6IERlbGl2ZXJ5QmFycmllckVudHJ5XG4pOiBib29sZWFuIHtcbiAgaWYgKG90aGVySW5kZXggPj0gaW5kZXggfHwgIURFRkVSX0JFSElORFtraW5kXS5pbmNsdWRlcyhvdGhlci5raW5kKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICAvLyBBIHN0ZXAgc2tpcHMgYW4gVU5BUk1FRCBlYXJsaWVyIGVudHJ5IChhbiB1bmNsYWltZWQgYnVmZmVyZWQgaG9va1xuICAvLyBwYXlsb2FkKSDigJQgc2VlIHRoZSBhc3ltbWV0cnkgZGVzY3JpYmVkIG9uIGBhd2FpdEVhcmxpZXJEZWxpdmVyaWVzYC4gVGhlXG4gIC8vIHNraXAgaXMgZGlyZWN0LCBuZXZlciB0cmFuc2l0aXZlOiBhcm1lZCBlbnRyaWVzIGFyZSBzdGlsbCBnYXRlZCBvbiwgZXZlblxuICAvLyB3aGVuIHRoZXkgYXJlIHRoZW1zZWx2ZXMgcGFya2VkIGJlaGluZCBzdWNoIGEgcGF5bG9hZC5cbiAgcmV0dXJuICEoa2luZCA9PT0gJ3N0ZXAnICYmICFvdGhlci5hcm1lZCk7XG59XG5cbi8qKlxuICogV2hldGhlciBgZW50cnlgIHdpbGwgcmVzb2x2ZSBvbiBpdHMgb3duIOKAlCBpdCBpcyBhcm1lZCwgYW5kIGV2ZXJ5IGVhcmxpZXJcbiAqIGRlbGl2ZXJ5IGl0IGFjdHVhbGx5IGdhdGVzIG9uICh7QGxpbmsgZ2F0ZXNPbn0pIHdpbGwgbGlrZXdpc2UgcmVzb2x2ZSBvbiBpdHNcbiAqIG93bi5cbiAqXG4gKiBBIHN0ZXAgZG9lcyBub3QgZ2F0ZSBvbiBhbiB1bmNsYWltZWQgYnVmZmVyZWQgcGF5bG9hZCwgc28gc3VjaCBhIHBheWxvYWRcbiAqIGNhbm5vdCBrZWVwIGl0IGZyb20gcmVzb2x2aW5nLiBBIHN0ZXAgRE9FUyBnYXRlIG9uIGVhcmxpZXIgYXJtZWQgd2FpdHMgYW5kXG4gKiBob29rcywgc28gb25lIHBhcmtlZCBiZWhpbmQgYW4gdW5jbGFpbWVkIHBheWxvYWQgbWFrZXMgdGhlIHN0ZXBcbiAqIG5vbi1zZWxmLXJlc29sdmluZyBpbiB0dXJuLiBEaXNhZ3JlZWluZyB3aXRoIHtAbGluayBhd2FpdEVhcmxpZXJEZWxpdmVyaWVzfVxuICogaGVyZSB3b3VsZCBub3QgYmUgYSBjb3NtZXRpYyBwcm9ibGVtOiB0aGlzIHByZWRpY2F0ZSBpcyB3aGF0XG4gKiB7QGxpbmsgaGFzUGFya2VkQ29tbWl0dGVkRGVsaXZlcnl9IHVzZXMgdG8gZGVjaWRlIHdoZXRoZXIgaWRsZSBpcyByZWFjaGFibGUsXG4gKiBhbmQgYW4gZW50cnkgcmVwb3J0ZWQgc2VsZi1yZXNvbHZpbmcgd2hpbGUgaXQgaXMgaW4gZmFjdCBwYXJrZWQgYmVoaW5kIGFcbiAqIHBheWxvYWQgdGhhdCBvbmx5IHRoZSBpZGxlIHNhZmV0eSBuZXQgY2FuIHJldGlyZSB3b3VsZCBnYXRlIGl0cyBvd25cbiAqIHJldGlyZW1lbnQuXG4gKlxuICogUmVjdXJzaW9uIHRlcm1pbmF0ZXMgYmVjYXVzZSBldmVyeSBlZGdlIHBvaW50cyB0byBhIHN0cmljdGx5IHNtYWxsZXIgaW5kZXguXG4gKiBgbWVtb2Aga2VlcHMgdGhlIHdhbGsgbGluZWFyIGluIHJlZ2lzdHJ5IHNpemUsIGFuZCB0aGUgcmVnaXN0cnkgaXMgbm90IHNtYWxsXG4gKiBieSBjb25zdHJ1Y3Rpb24g4oCUIGBFdmVudHNDb25zdW1lcmAgZHJhaW5zIGNvbnNlY3V0aXZlbHkgY29uc3VtYWJsZSBldmVudHNcbiAqIHN5bmNocm9ub3VzbHkgd2hpbGUgYmFycmllcnMgb25seSByZXRpcmUgb24gbWljcm90YXNrLWRyaXZlbiBkZWxpdmVyaWVzLCBzb1xuICogYSBmYW4tb3V0IG9mIGBQcm9taXNlLnJhY2UoW2hvb2ssIHNsZWVwXSlgIGJyYW5jaGVzIGFjY3VtdWxhdGVzIG9uZSBiYXJyaWVyXG4gKiBwZXIgYnJhbmNoIHBlciBraW5kLiBUaGUgbWVtbyBNVVNUIGJlIHBlci1jYWxsOiBgYXJtZWRgIG11dGF0ZXMgYmV0d2VlblxuICogY2FsbHMgYXMgYnVmZmVyZWQgcGF5bG9hZHMgYXJlIGNsYWltZWQuXG4gKlxuICogVGhlIG1lbW8gaXMgYW4gb3B0aW1pemF0aW9uLCBub3QgYSBjb3JyZWN0bmVzcyByZXF1aXJlbWVudC4gSXQgb25jZSB3YXMgb25lOlxuICogYGF3YWl0RWFybGllckRlbGl2ZXJpZXNgIHVzZWQgdG8gcnVuIHRoaXMgd2FsayBmb3IgZXZlcnkgZWFybGllciBlbnRyeSBvZiBhXG4gKiBzdGVwIGRlbGl2ZXJ5LCB3aXRoIG5vIGVhcmx5IGV4aXQsIHdoaWNoIHVubWVtb2l6ZWQgaXMgVChuKSA9IM6jIFQoaikg4oCUXG4gKiBtZWFzdXJlZCBhdCA0LjNlOCByZWN1cnNpdmUgY2FsbHMgKDg0cykgZm9yIDQwIGFsdGVybmF0aW5nIGFybWVkIGhvb2svd2FpdFxuICogYmFycmllcnMuIFRoYXQgY2FsbCBzaXRlIGlzIGdvbmU7IGEgc3RlcCBub3cgdGVzdHMgYGFybWVkYCBkaXJlY3RseS4gVGhlIG9uZVxuICogc3Vydml2aW5nIGNhbGxlciwge0BsaW5rIGhhc1BhcmtlZENvbW1pdHRlZERlbGl2ZXJ5fSwgY2Fubm90IHJlYWNoIHRoYXRcbiAqIHNoYXBlOiBpdCByZXR1cm5zIGF0IHRoZSBGSVJTVCBzZWxmLXJlc29sdmluZyBlbnRyeSwgc28gaXQgb25seSBldmVyXG4gKiBhZHZhbmNlcyBwYXN0IGVudHJpZXMgdGhhdCBhcmUgbm9uLXNlbGYtcmVzb2x2aW5nLCBhbmQgdGhvc2Ugc2hvcnQtY2lyY3VpdFxuICogb24gdGhlaXIgZmlyc3QgZmFsc2UgY2hpbGQuIEV2ZXJ5IGVudHJ5IGl0IGV2YWx1YXRlcyB0aGVyZWZvcmUgaGFzXG4gKiBhbGwtZmFsc2UgcHJlZGVjZXNzb3JzIGFuZCByZXR1cm5zIGFmdGVyIG9uZSBjaGlsZCwgZGVnZW5lcmF0aW5nIHRoZSB3YWxrIHRvXG4gKiBhIGNoYWluIChtZWFzdXJlZDogOTggY2FsbHMgdW5tZW1vaXplZCBmb3IgdGhlIHdvcnN0IDQwLWJhcnJpZXIgc2hhcGUsIDFcbiAqIGNhbGwgZm9yIHRoZSByZWdpc3RyeSBhYm92ZSkuIERvIG5vdCByZXN0b3JlIGFuIGV4cG9uZW50aWFsIGNsYWltIGhlcmVcbiAqIHdpdGhvdXQgcmVzdG9yaW5nIGEgY2FsbGVyIHRoYXQgY2FuIHByb2R1Y2UgaXQuXG4gKi9cbmZ1bmN0aW9uIHJlc29sdmVzT25JdHNPd24oXG4gIGJhcnJpZXJzOiBNYXA8bnVtYmVyLCBEZWxpdmVyeUJhcnJpZXJFbnRyeT4sXG4gIGluZGV4OiBudW1iZXIsXG4gIGVudHJ5OiBEZWxpdmVyeUJhcnJpZXJFbnRyeSxcbiAgbWVtbzogTWFwPG51bWJlciwgYm9vbGVhbj5cbik6IGJvb2xlYW4ge1xuICBjb25zdCBjYWNoZWQgPSBtZW1vLmdldChpbmRleCk7XG4gIGlmIChjYWNoZWQgIT09IHVuZGVmaW5lZCkge1xuICAgIHJldHVybiBjYWNoZWQ7XG4gIH1cbiAgY29uc3QgcmVzdWx0ID0gY29tcHV0ZVJlc29sdmVzT25JdHNPd24oYmFycmllcnMsIGluZGV4LCBlbnRyeSwgbWVtbyk7XG4gIG1lbW8uc2V0KGluZGV4LCByZXN1bHQpO1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG5mdW5jdGlvbiBjb21wdXRlUmVzb2x2ZXNPbkl0c093bihcbiAgYmFycmllcnM6IE1hcDxudW1iZXIsIERlbGl2ZXJ5QmFycmllckVudHJ5PixcbiAgaW5kZXg6IG51bWJlcixcbiAgZW50cnk6IERlbGl2ZXJ5QmFycmllckVudHJ5LFxuICBtZW1vOiBNYXA8bnVtYmVyLCBib29sZWFuPlxuKTogYm9vbGVhbiB7XG4gIGlmICghZW50cnkuYXJtZWQpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgZm9yIChjb25zdCBbb3RoZXJJbmRleCwgb3RoZXJdIG9mIGJhcnJpZXJzKSB7XG4gICAgaWYgKCFnYXRlc09uKGVudHJ5LmtpbmQsIGluZGV4LCBvdGhlckluZGV4LCBvdGhlcikpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICBpZiAoIXJlc29sdmVzT25JdHNPd24oYmFycmllcnMsIG90aGVySW5kZXgsIG90aGVyLCBtZW1vKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn1cblxuLyoqXG4gKiBBd2FpdHMsIGluIHN0cmljdCBldmVudC1sb2cgb3JkZXIsIGV2ZXJ5IHN0aWxsLXJlZ2lzdGVyZWQgZGVsaXZlcnkgdGhhdCBpc1xuICogZWFybGllciBpbiB0aGUgbG9nIHRoYW4gYGV2ZW50SW5kZXhgIGFuZCB0aGF0IGEgZGVsaXZlcnkgb2YgYGtpbmRgIGRlZmVyc1xuICogYmVoaW5kIChzZWUge0BsaW5rIERFRkVSX0JFSElORH0pLCBzbyB0aGF0IHRoaXMgcmVzb2x1dGlvbiBpcyBoYW5kZWQgdG8gdGhlXG4gKiB3b3JrZmxvdyBvbmx5IGFmdGVyIGFsbCByZWxldmFudCBlYXJsaWVyLWluLWxvZyBkZWxpdmVyaWVzIGhhdmUgYmVlbi4gVGhpc1xuICogaXMgd2hhdCBrZWVwcyBhIGBQcm9taXNlLnJhY2VgIOKAlCBvciB0aGUgVUxJRCBhIGZvbGxvdy11cCBgdXNlU3RlcGAgZHJhd3Mgb25cbiAqIGEgY29uY3VycmVudCBicmFuY2gg4oCUIGRldGVybWluaXN0aWMgYW5kIGFsaWduZWQgd2l0aCB0aGUgY29tbWl0dGVkIGV2ZW50XG4gKiBsb2csIGluZGVwZW5kZW50IG9mIG1pY3JvdGFzay1ob3AgY291bnRzLCBoeWRyYXRpb24gdGltZSwgb3IgcmFjZS1hcmd1bWVudFxuICogb3JkZXIuIFdoZW4gdGhpcyBkZWxpdmVyeSBkb2VzIGhhdmUgdG8gd2FpdCwgaXQgYWxzbyB5aWVsZHMgYSBtYWNyb3Rhc2tcbiAqIGFmdGVyd2FyZHMgc28gdGhlIGVhcmxpZXIgZGVsaXZlcnkncyBjb25zdW1lciBjYW4gcnVuIHRvIGl0cyBvd24gbmV4dFxuICogc3VzcGVuc2lvbiBwb2ludCBmaXJzdDsgc2VlIHRoZSBjb21tZW50IGF0IHRoYXQgYGF3YWl0YCBmb3Igd2h5IG9yZGVyaW5nIHRoZVxuICogYHJlc29sdmUoKWAgY2FsbHMgYWxvbmUgaXMgbm90IGVub3VnaC5cbiAqXG4gKiBXaGF0IGNvdW50cyBhcyBcImRlZmVycyBiZWhpbmRcIiBpcyB7QGxpbmsgZ2F0ZXNPbn0sIHNoYXJlZCB3aXRoXG4gKiB7QGxpbmsgY29tcHV0ZVJlc29sdmVzT25JdHNPd259IHNvIHRoZSB0d28gY2Fubm90IGRyaWZ0LlxuICpcbiAqIE9uZSBhc3ltbWV0cnk6IGEgU1RFUCByZXN1bHQgc2tpcHMgYW55IGVhcmxpZXIgZGVsaXZlcnkgdGhhdCBpcyBVTkFSTUVELFxuICogaS5lLiBhIGJ1ZmZlcmVkIGhvb2sgcGF5bG9hZCBubyBjb25zdW1lciBoYXMgY2xhaW1lZC4gU3VjaCBhIHBheWxvYWQgaXNcbiAqIGRlbGl2ZXJlZCBvbmx5IHdoZW4gdGhlIHdvcmtmbG93IG5leHQgcmVhZHMgdGhlIGhvb2ssIGFuZCByZWFjaGluZyB0aGF0IHJlYWRcbiAqIHZlcnkgY29tbW9ubHkgcmVxdWlyZXMgdGhlIHN0ZXAgcmVzdWx0IGl0c2VsZiAoYGF3YWl0IHN0ZXBYKClgIGJlZm9yZSB0aGVcbiAqIHJlYWQpLiBHYXRpbmcgdGhlIHN0ZXAgb24gaXQgd291bGQgc3RhbGwgdGhlIHdvcmtmbG93IHVudGlsIHRoZSBiYXJyaWVyJ3NcbiAqIGlkbGUgc2FmZXR5IG5ldCBmaXJlcywgd2hpY2ggdGhlbiByZWxlYXNlcyBldmVyeSBkZWxpdmVyeSBxdWV1ZWQgYmVoaW5kIHRoYXRcbiAqIHBheWxvYWQgYXQgb25jZSDigJQgbG9zaW5nIGV4YWN0bHkgdGhlIHJhY2UgdGhpcyBvcmRlcmluZyBleGlzdHMgdG8gcHJvdGVjdC5cbiAqIFdhaXRzIGFuZCBob29rcyBrZWVwIGdhdGluZyBvbiB1bmNsYWltZWQgcGF5bG9hZHM6IGZvciB0aGVtLCB3YWl0aW5nIGZvciB0aGVcbiAqIGNsYWltIElTIHRoZSBvcmRlcmluZyBndWFyYW50ZWUgKGEgYHdhaXRfY29tcGxldGVkYCBtdXN0IG5vdCBwcmVlbXB0IGFcbiAqIHBheWxvYWQgdGhlIGxvZyBvcmRlcmVkIGZpcnN0KS5cbiAqXG4gKiBUaGUgc2tpcCBpcyBkaXJlY3QsIG5ldmVyIHRyYW5zaXRpdmUuIEEgc3RlcCBzdGlsbCBnYXRlcyBvbiBhbiBlYXJsaWVyIEFSTUVEXG4gKiB3YWl0IG9yIGhvb2ssIGluY2x1ZGluZyBvbmUgdGhhdCBpcyBpdHNlbGYgcGFya2VkIGJlaGluZCBhbiB1bmNsYWltZWRcbiAqIHBheWxvYWQuIFNraXBwaW5nIHRob3NlIHRvbyB3b3VsZCBpbnZlcnQgbG9nIG9yZGVyIGZvciB0aGUgY29tbW9uZXN0IHNoYXBlXG4gKiB0aGVyZSBpczogYSB3b3JrZmxvdyB0aGF0IGNyZWF0ZXMgYSBob29rIGl0IGRvZXMgbm90IHJlYWQgb24gdGhpcyBicmFuY2gsXG4gKiByYWNlcyBgc3RlcGAgYWdhaW5zdCBgc2xlZXBgLCBhbmQgaGFzIHRoZSBsb2cgc2F5IHRoZSBzbGVlcCB3b24uIFRoZSBzdGVwXG4gKiB3b3VsZCB0aGVuIG92ZXJ0YWtlIHRoZSB3YWl0LCBib3RoIGJyYW5jaGVzIHdvdWxkIHN3YXAgdGhlIGNvcnJlbGF0aW9uIGlkc1xuICogdGhleSBkcmF3IG5leHQsIGFuZCByZXBsYXkgd291bGQgZGl2ZXJnZSDigJQgc2VlXG4gKiBgc3RlcC1kZWxpdmVyeS1vcmRlcmluZy50ZXN0LnRzYC4gV2FpdGluZyBpbnN0ZWFkIGlzIHNhZmUgYmVjYXVzZSB0aGVcbiAqIHBheWxvYWQncyBvd24gaWRsZSBzYWZldHkgbmV0IHJldGlyZXMgaXQgYW5kIHRoZSB3aG9sZSBjaGFpbiB0aGVuIGRlbGl2ZXJzXG4gKiBpbiBsb2cgb3JkZXI7IHtAbGluayBoYXNQYXJrZWRDb21taXR0ZWREZWxpdmVyeX0gZGVsaWJlcmF0ZWx5IHJlcG9ydHMgc3VjaCBhXG4gKiBzdGVwIGFzIG5vdCBzZWxmLXJlc29sdmluZyBzbyB0aGF0IGlkbGUgc3RheXMgcmVhY2hhYmxlLlxuICpcbiAqIFwiVGhlIHdob2xlIGNoYWluIHRoZW4gZGVsaXZlcnMgaW4gbG9nIG9yZGVyXCIgcmVzdHMgb24gdGhlIFBBWUxPQUQncyBiYXJyaWVyXG4gKiBiZWluZyByZXRpcmVkIGJlZm9yZSB0aGF0IG9mIGFueXRoaW5nIHBhcmtlZCBiZWhpbmQgaXQuIFRoYXQgb3JkZXIgaXNcbiAqIHN0cnVjdHVyYWw6IHNhZmV0eS1uZXQgcmV0aXJlbWVudHMgZ28gdGhyb3VnaCBvbmUgcGVyLWNvbnRleHQgZGlzcGVuc2VyIHRoYXRcbiAqIG9ubHkgZXZlciByZXRpcmVzIHRoZSBsb3dlc3QtaW5kZXggZW50cnkgYXQgZGVsaXZlcnkgaWRsZSwgYW5kIGV2ZXJ5XG4gKiByZXRpcmVtZW50IHRoYXQgd2FrZXMgYSBjaGFpbiBmbGlwcyB7QGxpbmsgaGFzUGFya2VkQ29tbWl0dGVkRGVsaXZlcnl9IGJhY2tcbiAqIHRvIHRydWUsIHJlLWJsb2NraW5nIHRoZSBkaXNwZW5zZXIgdW50aWwgdGhlIGNoYWluIGhhcyBkcmFpbmVkIOKAlCBzZWVcbiAqIHtAbGluayBlbnN1cmVCYXJyaWVyU2FmZXR5TmV0fS4gKFRoaXMgdXNlZCB0byByZXN0IG9uIHRoZSBGSUZPIG9mIG9uZSBpZGxlXG4gKiBwb2xsIHBlciBiYXJyaWVyLCB3aGljaCBoZWxkIGZvciBhIHNpbmdsZSBwYXJrZWQgc2VnbWVudCBidXQgZGVjYXllZCB0b1xuICogdGltaW5nIG5vaXNlIHdpdGggc2V2ZXJhbCDigJQgdGhlIHJlbGVhc2Ugb3JkZXIsIGFuZCB0aGVyZWZvcmUgdGhlIFVMSURzXG4gKiBkcmF3biBieSB0aGUgd29rZW4gYnJhbmNoZXMsIHRoZW4gZGVwZW5kZWQgb24gaG93IG11Y2ggbG9nIHRoZSByZXBsYXkgaGFkXG4gKiBsb2FkZWQuIHN0b3JtLWxvZy1yZXBsYXkudGVzdC50cyByZXBsYXlzIGEgcHJvZHVjdGlvbiBsb2cgY29ycnVwdGVkIGV4YWN0bHlcbiAqIHRoYXQgd2F5LilcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGF3YWl0RWFybGllckRlbGl2ZXJpZXMoXG4gIGN0eDogV29ya2Zsb3dPcmNoZXN0cmF0b3JDb250ZXh0LFxuICBldmVudEluZGV4OiBudW1iZXIgfCB1bmRlZmluZWQsXG4gIGtpbmQ6IERlbGl2ZXJ5S2luZFxuKTogUHJvbWlzZTx2b2lkPiB7XG4gIC8vIERlZmVuc2l2ZTogdG9sZXJhdGUgY29udGV4dHMgdGhhdCBwcmVkYXRlIHRoaXMgZmllbGQgKHRlc3QgaGFybmVzc2VzKS5cbiAgaWYgKFxuICAgIGV2ZW50SW5kZXggPT09IHVuZGVmaW5lZCB8fFxuICAgICFjdHgucGVuZGluZ0RlbGl2ZXJ5QmFycmllcnMgfHxcbiAgICBjdHgucGVuZGluZ0RlbGl2ZXJ5QmFycmllcnMuc2l6ZSA9PT0gMFxuICApIHtcbiAgICByZXR1cm47XG4gIH1cbiAgY29uc3QgYmFycmllcnMgPSBjdHgucGVuZGluZ0RlbGl2ZXJ5QmFycmllcnM7XG4gIGNvbnN0IGVhcmxpZXI6IFByb21pc2U8dm9pZD5bXSA9IFtdO1xuICBmb3IgKGNvbnN0IFtpbmRleCwgZW50cnldIG9mIGJhcnJpZXJzKSB7XG4gICAgaWYgKCFnYXRlc09uKGtpbmQsIGV2ZW50SW5kZXgsIGluZGV4LCBlbnRyeSkpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICBlYXJsaWVyLnB1c2goZW50cnkuZGVsaXZlcmVkKTtcbiAgfVxuICBpZiAoZWFybGllci5sZW5ndGggPiAwKSB7XG4gICAgYXdhaXQgUHJvbWlzZS5hbGwoZWFybGllcik7XG4gICAgLy8gQW4gZWFybGllciBkZWxpdmVyeSBiZWluZyBcImRlbGl2ZXJlZFwiIG9ubHkgbWVhbnMgaXRzIGByZXNvbHZlKClgIHJhbi5cbiAgICAvLyBUaGUgYnJhbmNoIGl0IHdva2UgbWF5IG5lZWQgYW4gYXJiaXRyYXJ5IG51bWJlciBvZiBmdXJ0aGVyIG1pY3JvdGFza1xuICAgIC8vIGhvcHMgYmVmb3JlIGl0IHJlYWNoZXMgaXRzIG5leHQgYHVzZVN0ZXBgIGNhbGwgYW5kIGRyYXdzIGEgVUxJRCDigJQgYVxuICAgIC8vIGBmb3IgYXdhaXRgIG92ZXIgYSBob29rLCBmb3IgaW5zdGFuY2UsIHJlc3VtZXMgdGhlIGdlbmVyYXRvciwgc2V0dGxlc1xuICAgIC8vIHRoZSBwcm9taXNlIGZyb20gYG5leHQoKWAsIGFuZCBvbmx5IHRoZW4gcnVucyB0aGUgbG9vcCBib2R5LiBSZXNvbHZpbmdcbiAgICAvLyB0aGlzIGRlbGl2ZXJ5IG9uIGEgbWljcm90YXNrIHdvdWxkIGxldCBpdCBvdmVydGFrZSB0aGF0IGJyYW5jaCBhbmRcbiAgICAvLyByZW9yZGVyIHRoZSBVTElEIGFsbG9jYXRpb24gYW55d2F5LCB0dXJuaW5nIHRoZSBndWFyYW50ZWUgYmVsb3cgaW50byBhXG4gICAgLy8gaG9wLWNvdW50IHJhY2UgdGhhdCBob2xkcyBvbmx5IGZvciB0aGUgc2hvcnRlc3QgY29uc3VtZXJzLlxuICAgIC8vXG4gICAgLy8gWWllbGRpbmcgYSBtYWNyb3Rhc2sgbGV0cyB0aGUgZWFybGllciBicmFuY2gncyBlbnRpcmUgbWljcm90YXNrIGNoYWluXG4gICAgLy8gZHJhaW4gZmlyc3QsIHdoYXRldmVyIGl0cyBsZW5ndGgsIHNvIGxvZyBvcmRlciBzdXJ2aXZlcyByZWdhcmRsZXNzIG9mXG4gICAgLy8gaG93IHRoZSB3b3JrZmxvdyBjb25zdW1lcyB0aGUgZWFybGllciBkZWxpdmVyeS4gT25seSBkZWxpdmVyaWVzIHRoYXRcbiAgICAvLyBhY3R1YWxseSBoYWQgdG8gZGVmZXIgcGF5IHRoaXMsIHNvIHRoZSBjb21tb24gc2luZ2xlLWRlbGl2ZXJ5IGRyYWluIGlzXG4gICAgLy8gdW5hZmZlY3RlZC5cbiAgICBhd2FpdCBuZXcgUHJvbWlzZTx2b2lkPigocmVzb2x2ZSkgPT4gc2V0VGltZW91dChyZXNvbHZlLCAwKSk7XG4gIH1cbn1cblxuLyoqIEhhbmRsZSBmb3IgYSByZWdpc3RlcmVkIGJyYW5jaC1kZWNpZGluZyBkZWxpdmVyeSBiYXJyaWVyLiAqL1xuZXhwb3J0IGludGVyZmFjZSBEZWxpdmVyeUJhcnJpZXIge1xuICAvKipcbiAgICogTWFyayB0aGlzIGRlbGl2ZXJ5IGFzIGRlbGl2ZXJlZCB0byB0aGUgd29ya2Zsb3cuIFJlc29sdmVzIGl0c1xuICAgKiBgZGVsaXZlcmVkYCBwcm9taXNlIHNvIGFueSBsYXRlci1pbi1sb2cgZGVsaXZlcnkgZ2F0ZWQgb24gaXQgKHZpYVxuICAgKiB7QGxpbmsgYXdhaXRFYXJsaWVyRGVsaXZlcmllc30pIG1heSBwcm9jZWVkLCBhbmQgcmVtb3ZlcyBpdCBmcm9tIHRoZVxuICAgKiByZWdpc3RyeS4gSWRlbXBvdGVudC5cbiAgICovXG4gIG1hcmtEZWxpdmVyZWQ6ICgpID0+IHZvaWQ7XG4gIC8qKlxuICAgKiBNYXJrIHRoaXMgZGVsaXZlcnkgYXMgY29tbWl0dGVkIHRvIGhhcHBlbmluZywgZm9yIGEgYmFycmllciByZWdpc3RlcmVkXG4gICAqIHVuYXJtZWQgKGEgYnVmZmVyZWQgaG9vayBwYXlsb2FkKSBvbmNlIGEgY29uc3VtZXIgaGFzIGNsYWltZWQgaXQuIEZyb21cbiAgICogdGhlbiBvbiBhIGxhdGVyIHN0ZXAgcmVzdWx0IG1heSBiZSBvcmRlcmVkIGJlaGluZCBpdC4gSWRlbXBvdGVudC5cbiAgICovXG4gIGFybTogKCkgPT4gdm9pZDtcbn1cblxuLyoqXG4gKiBSZWdpc3RlciBhIGJyYW5jaC1kZWNpZGluZyBkZWxpdmVyeSBhdCBpdHMgZXZlbnQtbG9nIGluZGV4IHNvIHRoYXQgbGF0ZXJcbiAqIGRlbGl2ZXJpZXMgY2FuIGJlIG9yZGVyZWQgc3RyaWN0bHkgYWZ0ZXIgaXQuIFJldHVybnMgYW4gaW5lcnQgaGFuZGxlIHdoZW5cbiAqIGBwZW5kaW5nRGVsaXZlcnlCYXJyaWVyc2AgaXMgbm90IGluaXRpYWxpemVkLlxuICpcbiAqIFBhc3MgYGFybWVkOiBmYWxzZWAgZm9yIGEgZGVsaXZlcnkgd2hvc2UgcmVzb2x1dGlvbiB3YWl0cyBvbiB3b3JrZmxvdyBjb2RlXG4gKiBhc2tpbmcgZm9yIGl0IChhIGJ1ZmZlcmVkIGhvb2sgcGF5bG9hZCk7IGNhbGwgYGFybSgpYCB3aGVuIGl0IGRvZXMuXG4gKlxuICogVG8gZ3VhcmFudGVlIGEgbGF0ZXIgZGVsaXZlcnkgZ2F0ZWQgb24gdGhpcyBvbmUgY2FuIG5ldmVyIGhhbmcgd2hlbiB0aGlzXG4gKiBkZWxpdmVyeSBpcyBhYmFuZG9uZWQgKHRoZSB3b3JrZmxvdyB0b29rIGEgZGlmZmVyZW50IGJyYW5jaCBvciBpc1xuICogc3VzcGVuZGluZyBhbmQgbmV2ZXIgb2JzZXJ2ZXMgaXQpLCB0aGUgYmFycmllciBhdXRvLXJlc29sdmVzIGF0IGlkbGUuXG4gKlxuICogSU5WQVJJQU5UIHJlcXVpcmVkIG9mIGV2ZXJ5IGNhbGwgc2l0ZTogYSBiYXJyaWVyIHRoYXQgaXMgZXZlciBgYXJtZWRgIG11c3RcbiAqIGJlIHBhaXJlZCB3aXRoIGEgZGVsaXZlcnkgY2hhaW4gdGhhdCBydW5zIHVuY29uZGl0aW9uYWxseSDigJQgYXR0YWNoZWQgd2hlblxuICogdGhlIGV2ZW50IGlzIGNvbnN1bWVkICh3YWl0cywgc3RlcCByZXN1bHRzLCB3YWl0aW5nLWNvbnN1bWVyIGhvb2sgcGF5bG9hZHMsXG4gKiBhYm9ydHMpLCBvciBieSB0aGUgYGNsYWltKClgIHdob3NlIGludm9jYXRpb24gaXMgd2hhdCBhcm1zIGl0IChidWZmZXJlZFxuICogaG9vayBwYXlsb2FkcykuIFRoZSBpZGxlIGNoZWNrICh7QGxpbmsgc2NoZWR1bGVXaGVuSWRsZX0pIHJlZnVzZXMgdG9cbiAqIG9ic2VydmUgaWRsZSB3aGlsZSBhbiBhcm1lZCwgc2VsZi1yZXNvbHZpbmcgYmFycmllciBpcyB1bmRlbGl2ZXJlZCwgYW5kIHRoZVxuICogc2FmZXR5IG5ldCBiZWxvdyBpcyBpdHNlbGYgaWRsZS1nYXRlZCDigJQgc28gYW4gYXJtZWQgYmFycmllciB3aXRoIG5vXG4gKiB1bmNvbmRpdGlvbmFsIGNoYWluIHdvdWxkIGxpdmVsb2NrIGV2ZXJ5IGlkbGUgY2hlY2sgaW4gdGhlIHJ1biwgaW5jbHVkaW5nXG4gKiBpdHMgb3duIHJldGlyZW1lbnQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWdpc3RlckRlbGl2ZXJ5QmFycmllcihcbiAgY3R4OiBXb3JrZmxvd09yY2hlc3RyYXRvckNvbnRleHQsXG4gIGV2ZW50SW5kZXg6IG51bWJlciB8IHVuZGVmaW5lZCxcbiAga2luZDogRGVsaXZlcnlLaW5kLFxuICBvcHRpb25zOiB7IGFybWVkPzogYm9vbGVhbiB9ID0ge31cbik6IERlbGl2ZXJ5QmFycmllciB7XG4gIGNvbnN0IGJhcnJpZXJzID0gY3R4LnBlbmRpbmdEZWxpdmVyeUJhcnJpZXJzO1xuICBpZiAoIWJhcnJpZXJzIHx8IGV2ZW50SW5kZXggPT09IHVuZGVmaW5lZCkge1xuICAgIHJldHVybiB7IG1hcmtEZWxpdmVyZWQ6ICgpID0+IHt9LCBhcm06ICgpID0+IHt9IH07XG4gIH1cblxuICBsZXQgZG9uZSA9IGZhbHNlO1xuICBjb25zdCB7IHByb21pc2UsIHJlc29sdmUgfSA9IHdpdGhSZXNvbHZlcnM8dm9pZD4oKTtcblxuICBjb25zdCBmaW5pc2ggPSAoKSA9PiB7XG4gICAgaWYgKGRvbmUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgZG9uZSA9IHRydWU7XG4gICAgaWYgKGJhcnJpZXJzLmdldChldmVudEluZGV4KSA9PT0gZW50cnkpIHtcbiAgICAgIGJhcnJpZXJzLmRlbGV0ZShldmVudEluZGV4KTtcbiAgICB9XG4gICAgcmVzb2x2ZSgpO1xuICB9O1xuXG4gIGNvbnN0IGVudHJ5OiBEZWxpdmVyeUJhcnJpZXJFbnRyeSA9IHtcbiAgICBraW5kLFxuICAgIGRlbGl2ZXJlZDogcHJvbWlzZSxcbiAgICBhcm1lZDogb3B0aW9ucy5hcm1lZCA/PyB0cnVlLFxuICAgIHJldGlyZTogZmluaXNoLFxuICB9O1xuICBiYXJyaWVycy5zZXQoZXZlbnRJbmRleCwgZW50cnkpO1xuXG4gIC8vIFNhZmV0eSBuZXQ6IGlmIHRoaXMgZGVsaXZlcnkgaXMgbmV2ZXIgZGVsaXZlcmVkIHRvIHRoZSB3b3JrZmxvdyAoaXRzXG4gIC8vIGJyYW5jaCB3YXMgbm90IHRha2VuIC8gdGhlIHJ1biBpcyBzdXNwZW5kaW5nLCBvciBhIGJ1ZmZlcmVkIGhvb2sgcGF5bG9hZFxuICAvLyBpcyBvbmx5IGNsYWltZWQgYWZ0ZXIgYSBsYXRlciBkZWxpdmVyeSB0aGUgd29ya2Zsb3cgaXMgc3RpbGwgd2FpdGluZyBvbiksXG4gIC8vIGl0IGlzIHJldGlyZWQgYXQgaWRsZSBzbyBhIGxhdGVyIGRlbGl2ZXJ5IGdhdGVkIG9uIGl0IGNhbm5vdCBkZWFkbG9jayBhbmRcbiAgLy8gdGhlIHJlZ2lzdHJ5IGNhbm5vdCBsZWFrIGFuIGVudHJ5IHBlciBhYmFuZG9uZWQgZGVsaXZlcnkuIFJldGlyZW1lbnQgZ29lc1xuICAvLyB0aHJvdWdoIHRoZSBjb250ZXh0J3Mgc2luZ2xlIG9yZGVyZWQgZGlzcGVuc2VyIHJhdGhlciB0aGFuIGEgcGVyLWJhcnJpZXJcbiAgLy8gaWRsZSBwb2xsIOKAlCBzZWUge0BsaW5rIGVuc3VyZUJhcnJpZXJTYWZldHlOZXR9IGZvciB3aHkgdGhlIE9SREVSIG9mIHRoZXNlXG4gIC8vIHJldGlyZW1lbnRzIGlzIGxvYWQtYmVhcmluZy5cbiAgZW5zdXJlQmFycmllclNhZmV0eU5ldChjdHgpO1xuXG4gIHJldHVybiB7XG4gICAgbWFya0RlbGl2ZXJlZDogZmluaXNoLFxuICAgIGFybTogKCkgPT4ge1xuICAgICAgZW50cnkuYXJtZWQgPSB0cnVlO1xuICAgIH0sXG4gIH07XG59XG5cbi8qKlxuICogQ29udGV4dHMgd2hvc2UgYmFycmllciBzYWZldHktbmV0IGRpc3BlbnNlciBpcyBjdXJyZW50bHkgYXJtZWQuIE1vZHVsZS1sZXZlbFxuICogc28gdGhlIGNvbnRleHQgaW50ZXJmYWNlIChjb25zdHJ1Y3RlZCBsaXRlcmFsbHkgYnkgbWFueSB0ZXN0IGhhcm5lc3NlcylcbiAqIG5lZWRzIG5vIG5ldyBmaWVsZDsgZW50cmllcyBkcm9wIHdpdGggdGhlIGNvbnRleHQuXG4gKi9cbmNvbnN0IGFjdGl2ZUJhcnJpZXJTYWZldHlOZXRzID0gbmV3IFdlYWtTZXQ8V29ya2Zsb3dPcmNoZXN0cmF0b3JDb250ZXh0PigpO1xuXG4vKipcbiAqIFRoZSBiYXJyaWVyIHJlZ2lzdHJ5J3Mgc2FmZXR5IG5ldDogT05FIGlkbGUtZ2F0ZWQgZGlzcGVuc2VyIHBlciBjb250ZXh0IHRoYXRcbiAqIHJldGlyZXMsIGF0IGVhY2ggb2JzZXJ2YXRpb24gb2YgZGVsaXZlcnkgaWRsZSwgb25seSB0aGUgTE9XRVNULWluZGV4IGVudHJ5XG4gKiBzdGlsbCByZWdpc3RlcmVkLCB0aGVuIHlpZWxkcyBzbyB0aGUgY2hhaW4gaXQgcmVsZWFzZWQgY2FuIHJ1biBiZWZvcmUgdGhlXG4gKiBuZXh0IHJldGlyZW1lbnQgaXMgY29uc2lkZXJlZC5cbiAqXG4gKiBXaHkgb25lIG9yZGVyZWQgZGlzcGVuc2VyIGFuZCBub3QgYSBwb2xsIHBlciBiYXJyaWVyICh3aGljaCBpcyB3aGF0IHRoaXNcbiAqIHJlcGxhY2VkKTogdGhlIG9yZGVyIG9mIHNhZmV0eS1uZXQgcmV0aXJlbWVudHMgZGVjaWRlcyB0aGUgZGVsaXZlcnkgb3JkZXIgb2ZcbiAqIGV2ZXJ5IGNoYWluIHBhcmtlZCBiZWhpbmQgYW4gdW5jbGFpbWVkIGJ1ZmZlcmVkIGhvb2sgcGF5bG9hZCDigJQgYSBob29rIHRoZVxuICogd29ya2Zsb3cgbmV2ZXIgcmVhZHMgKGEgZmlyZS1hbmQtZm9yZ2V0IGBjcmVhdGVIb29rYCkgcGFya3MgZXZlcnkgbGF0ZXJcbiAqIGFybWVkIHdhaXQvaG9vayBiZWhpbmQgYSBiYXJyaWVyIHRoYXQgb25seSB0aGlzIG5ldCBjYW4gcmV0aXJlLiBQZXItYmFycmllclxuICogcG9sbHMgZmlyZSBpbiB3aGF0ZXZlciBvcmRlciB0aGVpciByZS1hcm0gY3ljbGVzIGxhbmQsIGFuZCBlYWNoIHJlLWFybVxuICogYXR0YWNoZXMgdG8gYSBgcHJvbWlzZVF1ZXVlYCB0aGF0IGdyb3dzIGJldHdlZW4gY2hlY2tzLCBzbyB3aXRoIHNldmVyYWxcbiAqIHBhcmtlZCBzZWdtZW50cyB0aGUgcmVsZWFzZSBvcmRlciBkZWNheXMgdG8gdGltaW5nIG5vaXNlLiBEcmF3cyAoYHVzZVN0ZXBgXG4gKiBjb3JyZWxhdGlvbiBpZHMpIHRoZW4gZGVwZW5kIG9uIHdoaWNoIHNlZ21lbnQgaGFwcGVuZWQgdG8gcmVsZWFzZSBmaXJzdCDigJRcbiAqIGNvbmNyZXRlbHksIG9uIGhvdyBNVUNIIGxvZyB0aGUgcmVwbGF5IGxvYWRlZCwgc2luY2UgdGhhdCBkZWNpZGVzIHdoYXQgaXMgaW5cbiAqIHRoZSByZWdpc3RyeS4gVGhhdCBpcyB0aGUgbWVjaGFuaXNtIGJlaGluZCBzbG90LW1vZGUgQ09SUlVQVEVEX0VWRU5UX0xPRyBvblxuICogc3Rvcm0tc2hhcGVkIHJ1bnMgKHNlZSBzdG9ybS1sb2ctcmVwbGF5LnRlc3QudHMsIGJ1aWx0IGZyb20gYSBwcm9kdWN0aW9uXG4gKiBsb2cpOiB0d28gcmVwbGF5cyBvZiB0aGUgc2FtZSBydW4gaG9sZGluZyBkaWZmZXJlbnQtbGVuZ3RoIHByZWZpeGVzIGJvdW5kXG4gKiB0aGUgc2FtZSBjb3JyZWxhdGlvbiBvcmRpbmFsIHRvIGRpZmZlcmVudCBzdGVwcy5cbiAqXG4gKiBSZXRpcmluZyBsb3dlc3QtZmlyc3QgaXMgbm90IG1lcmVseSB0aWR5LCBpdCBpcyB0aGUgb25seSBvcmRlciB0aGF0IGNhbm5vdFxuICogaW52ZXJ0IHRoZSBsb2c6IGV2ZXJ5IGdhdGUgcG9pbnRzIGZyb20gYSBoaWdoZXIgaW5kZXggdG8gYSBzdHJpY3RseSBsb3dlclxuICogb25lLCBzbyBhdCBkZWxpdmVyeSBpZGxlIHRoZSBsb3dlc3QgdW5kZWxpdmVyZWQgZW50cnkgZ2F0ZXMgb24gbm90aGluZ1xuICogc3RpbGwgcmVnaXN0ZXJlZCDigJQgaXQgaXMgdGhlIGhlYWQgb2YgZXZlcnkgcGFya2VkIGNoYWluIChpbiBwcmFjdGljZSwgdGhlXG4gKiB1bmNsYWltZWQgcGF5bG9hZCBpdHNlbGYpLiBSZWxlYXNpbmcgaXQgbGV0cyB0aGUgY2hhaW4gYWJvdmUgZGVsaXZlclxuICogdGhyb3VnaCB0aGUgb3JkaW5hcnkgYmFycmllciBvcmRlcjsgYW55dGhpbmcgdGhlIHJlbGVhc2Ugd2FrZXMgZmxpcHNcbiAqIHtAbGluayBoYXNQYXJrZWRDb21taXR0ZWREZWxpdmVyeX0gYmFjayB0byB0cnVlLCB3aGljaCByZS1ibG9ja3MgdGhpc1xuICogZGlzcGVuc2VyIHVudGlsIHRoZSBjaGFpbiBoYXMgZnVsbHkgZHJhaW5lZC4gQSBoaWdoZXIgZW50cnkgbXVzdCBuZXZlciBiZVxuICogcmV0aXJlZCB3aGlsZSBhIGxvd2VyIG9uZSBpcyByZWdpc3RlcmVkIOKAlCB0aGF0IGlzIGV4YWN0bHkgdGhlIGludmVyc2lvblxuICogZGVzY3JpYmVkIG9uIHtAbGluayBhd2FpdEVhcmxpZXJEZWxpdmVyaWVzfS5cbiAqXG4gKiBUaGUgZGlzcGVuc2VyIGdvZXMgZG9ybWFudCB3aGVuIHRoZSByZWdpc3RyeSBlbXB0aWVzIGFuZCBpcyByZS1hcm1lZCBieSB0aGVcbiAqIG5leHQgcmVnaXN0cmF0aW9uLCBzbyBhbiBpZGxlIGNvbnRleHQgaG9sZHMgbm8gbGl2ZSB0aW1lci5cbiAqL1xuZnVuY3Rpb24gZW5zdXJlQmFycmllclNhZmV0eU5ldChjdHg6IFdvcmtmbG93T3JjaGVzdHJhdG9yQ29udGV4dCk6IHZvaWQge1xuICBjb25zdCBiYXJyaWVycyA9IGN0eC5wZW5kaW5nRGVsaXZlcnlCYXJyaWVycztcbiAgaWYgKCFiYXJyaWVycyB8fCBhY3RpdmVCYXJyaWVyU2FmZXR5TmV0cy5oYXMoY3R4KSkge1xuICAgIHJldHVybjtcbiAgfVxuICBhY3RpdmVCYXJyaWVyU2FmZXR5TmV0cy5hZGQoY3R4KTtcbiAgY29uc3QgcmVhcm0gPSAoKSA9PiB7XG4gICAgc2V0VGltZW91dChjaGVjaywgMCk7XG4gIH07XG4gIC8vIEEgcmVqZWN0ZWQgcHJvbWlzZVF1ZXVlIHNldHRsZXMgaW1tZWRpYXRlbHkgYW5kIGZvcmV2ZXIsIHNvIHJlLWFybWluZ1xuICAvLyB0aHJvdWdoIGl0IGF0IHRoZSBub3JtYWwgY2FkZW5jZSB3b3VsZCBkZWdlbmVyYXRlIGludG8gYSBidXN5IGxvb3Agb24gYW5cbiAgLy8gYWJhbmRvbmVkIGNvbnRleHQuIEJhY2sgb2ZmIGluc3RlYWQ6IGNvcnJlY3RuZXNzIG9ubHkgbmVlZHMgdGhlIGRpc3BlbnNlclxuICAvLyB0byBzdGlsbCBleGlzdCwgc2luY2UgdGhlIHJlZ2lzdHJ5IGdhdGVzIHN1c3BlbnNpb24gdmlhIGlzRGVsaXZlcnlJZGxlXG4gIC8vIGFuZCBhIGRlYWQgZGlzcGVuc2VyIHdvdWxkIHdlZGdlIHRoZSBydW4uXG4gIGNvbnN0IHJlYXJtQWZ0ZXJSZWplY3Rpb24gPSAoKSA9PiB7XG4gICAgc2V0VGltZW91dChjaGVjaywgNTApO1xuICB9O1xuICBjb25zdCBjaGVjayA9ICgpID0+IHtcbiAgICBpZiAoYmFycmllcnMuc2l6ZSA9PT0gMCkge1xuICAgICAgLy8gRG9ybWFudC4gVGhlIG5leHQgcmVnaXN0ZXJEZWxpdmVyeUJhcnJpZXIgcmUtYXJtcy5cbiAgICAgIGFjdGl2ZUJhcnJpZXJTYWZldHlOZXRzLmRlbGV0ZShjdHgpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoIWNhblJldGlyZUFiYW5kb25lZEJhcnJpZXJzKGN0eCkpIHtcbiAgICAgIC8vIEEgZGVsaXZlcnkgaXMgaHlkcmF0aW5nIG9yIGNvbW1pdHRlZC1idXQtcGFya2VkIG9uIGl0cyBkZWZlcnJhbDsgbGV0XG4gICAgICAvLyB0aGUgcXVldWUgZHJhaW4gYW5kIHJlLWNoZWNrIGEgdGljayBsYXRlciAoc2FtZSBjYWRlbmNlIGFzXG4gICAgICAvLyBzY2hlZHVsZVdoZW5JZGxlKS5cbiAgICAgIGN0eC5wcm9taXNlUXVldWUudGhlbihyZWFybSwgcmVhcm1BZnRlclJlamVjdGlvbik7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIC8vIElkbGUgd2l0aCBlbnRyaWVzIGxlZnQ6IG5vdGhpbmcgcmVtYWluaW5nIGRlbGl2ZXJzIG9uIGl0cyBvd24sIHNvXG4gICAgLy8gcmVsZWFzZSBwYXJrZWQgY2hhaW5zIGZyb20gdGhlIGhlYWQg4oCUIGxvd2VzdCBpbmRleCBmaXJzdCwgb25lIGF0IGFcbiAgICAvLyB0aW1lLCByZS1yZWFkaW5nIGlkbGUgYmV0d2VlbiByZXRpcmVtZW50cy4gQSByZXRpcmVtZW50IHRoYXQgd2FrZXMgYVxuICAgIC8vIGNoYWluIGZsaXBzIHtAbGluayBoYXNQYXJrZWRDb21taXR0ZWREZWxpdmVyeX0gc3luY2hyb25vdXNseSAoaXQgaXNcbiAgICAvLyBjb21wdXRlZCBmcm9tIHRoZSByZWdpc3RyeSB0aGlzIGxvb3AganVzdCBtdXRhdGVkKSwgd2hpY2ggc3RvcHMgdGhlXG4gICAgLy8gc3dlZXAgc28gdGhlIGNoYWluIGRlbGl2ZXJzIGJlZm9yZSBhbnl0aGluZyBhYm92ZSBpdCBpcyByZWxlYXNlZC4gQVxuICAgIC8vIHJldGlyZW1lbnQgdGhhdCB3YWtlcyBub3RoaW5nIChhIHN0YWxlIHBheWxvYWQgbm8gZGVsaXZlcnkgZ2F0ZXMgb24pXG4gICAgLy8ga2VlcHMgdGhlIHN3ZWVwIGdvaW5nLCBzbyBhIGJhY2tsb2cgb2YgdGhvc2UgZHJhaW5zIGluIE9ORSBpZGxlXG4gICAgLy8gb2JzZXJ2YXRpb24g4oCUIHBhY2luZyB0aGVtIG9uZSBwZXIgdGltZXIgdGljayB3b3VsZCBob2xkIGNvbnN1bWVkLWJ1dC1cbiAgICAvLyB1bmRlbGl2ZXJlZCBldmVudHMgaG9zdGFnZSBsb25nIGVub3VnaCB0byB0cmlwIHRoZSBldmVudHMgY29uc3VtZXInc1xuICAgIC8vIHVuY29uc3VtZWQtZXZlbnQgZGVhZGxpbmUgYW5kIGZhaWwgaGVhbHRoeSByZXBsYXlzLlxuICAgIHdoaWxlIChiYXJyaWVycy5zaXplID4gMCAmJiBjYW5SZXRpcmVBYmFuZG9uZWRCYXJyaWVycyhjdHgpKSB7XG4gICAgICBsZXQgbG93ZXN0SW5kZXg6IG51bWJlciB8IHVuZGVmaW5lZDtcbiAgICAgIGxldCBsb3dlc3RFbnRyeTogRGVsaXZlcnlCYXJyaWVyRW50cnkgfCB1bmRlZmluZWQ7XG4gICAgICBmb3IgKGNvbnN0IFtpbmRleCwgZW50cnldIG9mIGJhcnJpZXJzKSB7XG4gICAgICAgIGlmIChsb3dlc3RJbmRleCA9PT0gdW5kZWZpbmVkIHx8IGluZGV4IDwgbG93ZXN0SW5kZXgpIHtcbiAgICAgICAgICBsb3dlc3RJbmRleCA9IGluZGV4O1xuICAgICAgICAgIGxvd2VzdEVudHJ5ID0gZW50cnk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGxvd2VzdEVudHJ5Py5yZXRpcmUoKTtcbiAgICB9XG4gICAgc2V0VGltZW91dChjaGVjaywgMCk7XG4gIH07XG4gIHNldFRpbWVvdXQoY2hlY2ssIDApO1xufVxuXG4vKipcbiAqIFdoZXRoZXIgdGhlIHNhZmV0eS1uZXQgZGlzcGVuc2VyIG1heSByZXRpcmUgYWJhbmRvbmVkIGJhcnJpZXJzIHJpZ2h0IG5vdzpcbiAqIG5vIGh5ZHJhdGlvbiBpbiBmbGlnaHQgYW5kIG5vIGNvbW1pdHRlZCBkZWxpdmVyeSBzdGlsbCB3b3JraW5nIHRocm91Z2ggaXRzXG4gKiBkZXRhY2hlZCBkZWZlcnJhbC4gVGhpcyBpcyBkZWxpYmVyYXRlbHkgV0VBS0VSIHRoYW4ge0BsaW5rIGlzRGVsaXZlcnlJZGxlfTpcbiAqIHRoZSBkaXNwZW5zZXIgaXMgd2hhdCBlbXB0aWVzIHRoZSByZWdpc3RyeSwgc28gZ2F0aW5nIGl0IG9uIHJlZ2lzdHJ5XG4gKiBlbXB0aW5lc3Mgd291bGQgZ2F0ZSBpdHMgb3duIHdvcmsuXG4gKi9cbmZ1bmN0aW9uIGNhblJldGlyZUFiYW5kb25lZEJhcnJpZXJzKGN0eDogV29ya2Zsb3dPcmNoZXN0cmF0b3JDb250ZXh0KTogYm9vbGVhbiB7XG4gIHJldHVybiBjdHgucGVuZGluZ0RlbGl2ZXJpZXMgPT09IDAgJiYgIWhhc1BhcmtlZENvbW1pdHRlZERlbGl2ZXJ5KGN0eCk7XG59XG5cbi8qKlxuICogV2hldGhlciBzb21lIHJlZ2lzdGVyZWQgYnJhbmNoLWRlY2lkaW5nIGRlbGl2ZXJ5IGlzIGdvaW5nIHRvIHJlYWNoIHRoZVxuICogd29ya2Zsb3cgd2l0aG91dCBhbnkgZnVydGhlciBoZWxwIChpdCBpcyBhcm1lZCBhbmQgbm90IHRyYW5zaXRpdmVseSBwYXJrZWRcbiAqIGJlaGluZCBhbiB1bmNsYWltZWQgYnVmZmVyZWQgcGF5bG9hZCDigJQgc2VlIHtAbGluayByZXNvbHZlc09uSXRzT3dufSkgYnV0XG4gKiBoYXMgbm90IGJlZW4gaGFuZGVkIG92ZXIgeWV0LlxuICpcbiAqIFRoaXMgaXMgdGhlIGRlbGl2ZXJ5IHN0YXRlIGBwZW5kaW5nRGVsaXZlcmllc2AgY2Fubm90IHNlZS4gVGhhdCBjb3VudGVyXG4gKiBjb3ZlcnMgdGhlIGh5ZHJhdGlvbiB3aW5kb3cgaW5zaWRlIGEgc2VyaWFsIGBwcm9taXNlUXVldWVgIHNsb3QgYW5kIGlzXG4gKiByZWxlYXNlZCB0aGVyZSwgd2hpbGUgdGhlIGRlbGl2ZXJ5J3MgYHJlc29sdmUoKWAgcnVucyBsYXRlciwgZnJvbSBhXG4gKiBkZXRhY2hlZCBjb250aW51YXRpb24gYmVoaW5kIHtAbGluayBhd2FpdEVhcmxpZXJEZWxpdmVyaWVzfSDigJQgaW5jbHVkaW5nIGl0c1xuICogbWFjcm90YXNrIHlpZWxkIHdoZW5ldmVyIHRoZSBkZWxpdmVyeSBoYWQgdG8gZGVmZXIuIFJlcGxheWluZyBhIGJhdGNoIG9mIE5cbiAqIHBhcmFsbGVsIHN0ZXAgcmVzdWx0cyBjb25zdW1lZCBpbiBvbmUgZHJhaW4gd2luZG93IGxlYXZlcyBOLTEgb2YgdGhlbVxuICogcGFya2VkIG9uIHRoYXQgeWllbGQgd2l0aCBgcGVuZGluZ0RlbGl2ZXJpZXNgIGFscmVhZHkgYXQgMC4gQW4gaWRsZSBjaGVja1xuICogYXJtZWQgZHVyaW5nIHRoZSBzYW1lIHdpbmRvdyAoYSBwZW5kaW5nIGBzbGVlcCgpYCBhcm1zIG9uZSBvbiBldmVyeSByZXBsYXkpXG4gKiBjb3VsZCB0aGVuIG9ic2VydmUgXCJpZGxlXCIgbWlkLWRlZmVycmFsIGFuZCByYWlzZSBhIGBXb3JrZmxvd1N1c3BlbnNpb25gXG4gKiBCRUZPUkUgdGhlIHdvcmtmbG93J3Mgb3duIGNvbnRpbnVhdGlvbnMgcmFuIOKAlCBhIHN1c3BlbnNpb24gY2Fycnlpbmcgbm9uZSBvZlxuICogdGhlIGZvbGxvdy11cCB3b3JrIHRoZSBiYXRjaCB3YXMgYWJvdXQgdG8gY3JlYXRlLCB3aGljaCB0aGUgcnVudGltZVxuICogZHV0aWZ1bGx5IHNjaGVkdWxlcyBhcyBub3RoaW5nLCBsZWF2aW5nIHRoZSBydW4gZG9ybWFudCB1bnRpbCBhbiB1bnJlbGF0ZWRcbiAqIHRpbWVyIGZpcmVzICh2ZXJjZWwvd29ya2Zsb3cjMzE4MykuXG4gKlxuICogRGVsaXZlcmllcyB0aGF0IGRvIE5PVCByZXNvbHZlIG9uIHRoZWlyIG93biBtdXN0IGJlIGV4Y2x1ZGVkLCBub3QgZm9yXG4gKiBhY2N1cmFjeSBidXQgZm9yIHRlcm1pbmF0aW9uOiBhbiB1bmNsYWltZWQgYnVmZmVyZWQgaG9vayBwYXlsb2FkIGlzIHJldGlyZWRcbiAqIEJZIHRoZSBpZGxlIHNhZmV0eSBuZXQgaW4ge0BsaW5rIHJlZ2lzdGVyRGVsaXZlcnlCYXJyaWVyfSwgc28gY291bnRpbmcgaXRcbiAqIGhlcmUgd291bGQgZ2F0ZSBpdHMgb3duIHJldGlyZW1lbnQuIFRoYXQgcmVhc29uaW5nIGV4dGVuZHMgdG8gd2hhdGV2ZXIgaXNcbiAqIHBhcmtlZCBiZWhpbmQgc3VjaCBhIHBheWxvYWQg4oCUIGEgd2FpdCwgYW5kIGEgc3RlcCBnYXRpbmcgb24gdGhhdCB3YWl0IOKAlCBmb3JcbiAqIHRoZSBzYW1lIHJlYXNvbjogdGhlIHdob2xlIGNoYWluIG1vdmVzIG9ubHkgb25jZSB0aGUgbmV0IGZpcmVzLCBhbmQgaXRcbiAqIGNhbm5vdCBmaXJlIHdoaWxlIHRoZSBjaGFpbiBpcyBjb3VudGVkLiBTZWxmLXJlc29sdmluZyBkZWxpdmVyaWVzIGFsd2F5c1xuICogZGVsaXZlciBmcm9tIHRoZWlyIG93biBjaGFpbnMgKHNlZSB0aGUgSU5WQVJJQU5UIG9uXG4gKiB7QGxpbmsgcmVnaXN0ZXJEZWxpdmVyeUJhcnJpZXJ9KSBhbmQgbmV2ZXIgbmVlZCB0aGF0IG5ldCwgc28gd2FpdGluZyBvblxuICogdGhlbSBpcyBkZWFkbG9jay1mcmVlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaGFzUGFya2VkQ29tbWl0dGVkRGVsaXZlcnkoXG4gIGN0eDogV29ya2Zsb3dPcmNoZXN0cmF0b3JDb250ZXh0XG4pOiBib29sZWFuIHtcbiAgY29uc3QgYmFycmllcnMgPSBjdHgucGVuZGluZ0RlbGl2ZXJ5QmFycmllcnM7XG4gIGlmICghYmFycmllcnMgfHwgYmFycmllcnMuc2l6ZSA9PT0gMCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICAvLyBTaGFyZWQgYWNyb3NzIHRoaXMgY2FsbCBvbmx5IOKAlCBzZWUgYHJlc29sdmVzT25JdHNPd25gLlxuICBjb25zdCBzZWxmUmVzb2x2aW5nID0gbmV3IE1hcDxudW1iZXIsIGJvb2xlYW4+KCk7XG4gIGZvciAoY29uc3QgW2luZGV4LCBlbnRyeV0gb2YgYmFycmllcnMpIHtcbiAgICBpZiAocmVzb2x2ZXNPbkl0c093bihiYXJyaWVycywgaW5kZXgsIGVudHJ5LCBzZWxmUmVzb2x2aW5nKSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9XG4gIHJldHVybiBmYWxzZTtcbn1cblxuLyoqXG4gKiBXaGV0aGVyIG5vIGRhdGEgZGVsaXZlcnkgKHN0ZXAgcmVzdWx0LCBob29rIHBheWxvYWQpIGlzIGluIGZsaWdodCByaWdodCBub3cuXG4gKlxuICogXCJJbiBmbGlnaHRcIiBpcyB0d28gZGlzdGluY3Qgd2luZG93cywgZWFjaCB3aXRoIGl0cyBvd24gZ3VhcmQ6XG4gKiBgcGVuZGluZ0RlbGl2ZXJpZXMgPiAwYCBjb3ZlcnMgaHlkcmF0aW9uIGluc2lkZSB0aGUgc2VyaWFsIHF1ZXVlIHNsb3RzLCBhbmRcbiAqIHtAbGluayBoYXNQYXJrZWRDb21taXR0ZWREZWxpdmVyeX0gY292ZXJzIHRoZSBkZXRhY2hlZCBnYXAgYmV0d2VlbiBhIHNsb3RcbiAqIHJlbGVhc2luZyB0aGF0IGNvdW50ZXIgYW5kIHRoZSBkZWxpdmVyeSdzIGByZXNvbHZlKClgIGFjdHVhbGx5IHJ1bm5pbmcg4oCUXG4gKiBkZWxpYmVyYXRlbHkgb3V0c2lkZSBgcGVuZGluZ0RlbGl2ZXJpZXNgIChzZWUgc3RlcC50cyksIGFuZCBpbnZpc2libGUgdG8gaXQuXG4gKlxuICogQW55dGhpbmcgdGhhdCBkZWNpZGVzIGEgcmVwbGF5IGlzIG92ZXIsIG9yIHRoYXQgYSByZXBsYXkgd2VudCB3cm9uZywgaGFzIHRvXG4gKiBjb25zdWx0IHRoaXMgZmlyc3Q6IHdoaWxlIGl0IGlzIGZhbHNlIHRoZSB3b3JrZmxvdyBWTSBpcyBtaWQtcmVhY3Rpb24sIHNvXG4gKiB3aGF0IGl0IGhhcyBhbmQgaGFzIG5vdCBkb25lIHlldCBzYXlzIG5vdGhpbmcgYWJvdXQgdGhlIHJ1bi4gVHdvIGNhbGxlcnNcbiAqIHJlYWQgaXQsIGZvciB0aGUgdHdvIHN1Y2ggZGVjaXNpb25zOiB7QGxpbmsgc2NoZWR1bGVXaGVuSWRsZX0gZm9yIHRoZVxuICogc3VzcGVuc2lvbiwgYW5kIHRoZSBldmVudHMgY29uc3VtZXIncyB1bmNvbnN1bWVkLWV2ZW50IGNoZWNrIGZvciBkaXZlcmdlbmNlLlxuICpcbiAqIEEgbm9uLWVtcHR5IGJhcnJpZXIgcmVnaXN0cnkgY291bnRzIGFzIGluIGZsaWdodCwgZXZlbiB3aGVuIGV2ZXJ5IHJlbWFpbmluZ1xuICogZW50cnkgaXMgcGFya2VkIGJlaGluZCBhbiB1bmNsYWltZWQgYnVmZmVyZWQgcGF5bG9hZC4gVGhvc2UgZW50cmllcyBvbmx5XG4gKiBtb3ZlIHdoZW4gdGhlIHNhZmV0eS1uZXQgZGlzcGVuc2VyIHJldGlyZXMgdGhlbSAobG93ZXN0LWZpcnN0LCBzZWVcbiAqIHtAbGluayBlbnN1cmVCYXJyaWVyU2FmZXR5TmV0fSksIGFuZCB0aGUgZGVsaXZlcmllcyB0aGV5IHJlbGVhc2UgYXJlIHJlYWxcbiAqIHdvcmtmbG93IHJlYWN0aW9ucyDigJQgYSBzdXNwZW5zaW9uIHJhaXNlZCBiZWZvcmUgdGhleSBydW4gd291bGQgYmUgY29tcHV0ZWRcbiAqIGZyb20gYSBWTSB0aGF0IGhhcyBub3Qgc2VlbiB0aGVtLCBzY2hlZHVsaW5nIG5vbmUgb2YgdGhlaXIgZm9sbG93LXVwIHdvcmtcbiAqIGFuZCBsZWF2aW5nIHRoZSBydW4gZG9ybWFudCAodGhlIHZlcmNlbC93b3JrZmxvdyMzMTgzIHNoYXBlKS4gVGhlIGRpc3BlbnNlclxuICogaXRzZWxmIGlzIGdhdGVkIG9uIHtAbGluayBjYW5SZXRpcmVBYmFuZG9uZWRCYXJyaWVyc30sIHRoZSB3ZWFrZXIgcHJlZGljYXRlXG4gKiB3aXRob3V0IHRoZSByZWdpc3RyeSB0ZXJtLCBwcmVjaXNlbHkgc28gaXQgY2FuIGRvIHRoZSBkcmFpbmluZyB0aGF0IHRoaXNcbiAqIHByZWRpY2F0ZSB3YWl0cyBmb3I7IHJlZ2lzdHJ5IHNpemUgc3RyaWN0bHkgZGVjcmVhc2VzIGF0IGVhY2ggcmV0aXJlbWVudCxcbiAqIHNvIGlkbGUgaXMgYWx3YXlzIHJlYWNoZWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0RlbGl2ZXJ5SWRsZShjdHg6IFdvcmtmbG93T3JjaGVzdHJhdG9yQ29udGV4dCk6IGJvb2xlYW4ge1xuICByZXR1cm4gKFxuICAgIGN0eC5wZW5kaW5nRGVsaXZlcmllcyA9PT0gMCAmJlxuICAgICghY3R4LnBlbmRpbmdEZWxpdmVyeUJhcnJpZXJzIHx8IGN0eC5wZW5kaW5nRGVsaXZlcnlCYXJyaWVycy5zaXplID09PSAwKVxuICApO1xufVxuXG4vKipcbiAqIFNjaGVkdWxlIGEgY2FsbGJhY2sgdG8gZmlyZSBvbmx5IGFmdGVyIGFsbCBwZW5kaW5nIGRhdGEgZGVsaXZlcmllc1xuICogKHN0ZXAgcmVzdWx0cywgaG9vayBwYXlsb2FkcykgYW5kIGFzeW5jIGRlc2VyaWFsaXphdGlvbiBoYXZlIGNvbXBsZXRlZC5cbiAqIFVzZXMgYSBwb2xsaW5nIGxvb3A6IHNldFRpbWVvdXQoMCkg4oaSIGNoZWNrIHBlbmRpbmdEZWxpdmVyaWVzIGFuZCB0aGVcbiAqIGJhcnJpZXIgcmVnaXN0cnkg4oaSIGlmIGFueXRoaW5nIGlzIHN0aWxsIGluIGZsaWdodCwgd2FpdCBmb3IgcHJvbWlzZVF1ZXVlIOKGklxuICogcmVwZWF0LiBUaGlzIGhhbmRsZXMgdGhlIG11bHRpLXJvdW5kIGRlbGl2ZXJ5IHBhdHRlcm4gd2hlcmUgZWFjaCBob29rXG4gKiBwYXlsb2FkIGRlbGl2ZXJ5IGN5Y2xlIGFwcGVuZHMgbmV3IGFzeW5jIHdvcmsgdG8gdGhlIHByb21pc2VRdWV1ZS4gV2hhdFxuICogY291bnRzIGFzIGluIGZsaWdodCBpcyB7QGxpbmsgaXNEZWxpdmVyeUlkbGV9LlxuICpcbiAqIFRoZSBpbml0aWFsIGBzZXRUaW1lb3V0KDApYCBtYWNyb3Rhc2sgaXMgbG9hZC1iZWFyaW5nIGFuZCBtdXN0IE5PVCBiZVxuICogZG93bmdyYWRlZCB0byBhIG1pY3JvdGFzayAoYHF1ZXVlTWljcm90YXNrYC9gUHJvbWlzZS5yZXNvbHZlKCkudGhlbmApLlxuICogYHBlbmRpbmdEZWxpdmVyaWVzYCBvbmx5IGd1YXJkcyB0aGUgaG9zdC1zaWRlIGh5ZHJhdGlvbiB3aW5kb3c7IGJldHdlZW4gYVxuICogZGVsaXZlcnkncyBgcmVzb2x2ZSgpYCBhbmQgdGhlIHdvcmtmbG93IFZNIGJvZHkgcnVubmluZyBpdHMgY29udGludWF0aW9uIHRvXG4gKiByZWdpc3RlciB0aGUgbmV4dCBzdWJzY3JpYmVyLCBgcGVuZGluZ0RlbGl2ZXJpZXNgIGlzIGFscmVhZHkgMCBldmVuIHRob3VnaFxuICogdGhlIFZNIGlzIG1pZC1yZWFjdGlvbi4gTm9kZSBkb2VzIG5vdCBndWFyYW50ZWUgYSBtaWNyb3Rhc2sgc2NoZWR1bGVkIGluXG4gKiB0aGUgaG9zdCBjb250ZXh0IHNldHRsZXMgYWZ0ZXIgdGhlIGNyb3NzLVZNIHByb21pc2UgY2hhaW4gKHJlc29sdmUgaW4gaG9zdFxuICog4oaSIHdvcmtmbG93IGNvZGUgaW4gVk0g4oaSIHN1YnNjcmliZSBiYWNrIGluIGhvc3QpOyB0aGUgbWFjcm90YXNrIGJvdW5kYXJ5XG4gKiBnaXZlcyB0aGF0IGNoYWluIHRpbWUgdG8gcnVuLCBzbyB0aGUgc3VzcGVuc2lvbiBkb2VzIG5vdCBwcmVlbXB0IGEgc2libGluZ1xuICogZGVsaXZlcnkgc3RpbGwgaW4gZmxpZ2h0LiBFbXBpcmljYWxseSwgcmVwbGFjaW5nIGl0IHdpdGggYHF1ZXVlTWljcm90YXNrYFxuICogYnJlYWtzIGhvb2svc2xlZXAgYFByb21pc2UucmFjZWAgb3JkZXJpbmcgKENvcnJ1cHRlZEV2ZW50TG9nRXJyb3IpLlxuICovXG5leHBvcnQgZnVuY3Rpb24gc2NoZWR1bGVXaGVuSWRsZShcbiAgY3R4OiBXb3JrZmxvd09yY2hlc3RyYXRvckNvbnRleHQsXG4gIGZuOiAoKSA9PiB2b2lkXG4pOiB2b2lkIHtcbiAgY29uc3QgY2hlY2sgPSAoKSA9PiB7XG4gICAgaWYgKCFpc0RlbGl2ZXJ5SWRsZShjdHgpKSB7XG4gICAgICAvLyBBIGRlbGl2ZXJ5IGlzIHN0aWxsIGh5ZHJhdGluZywgb3IgaXMgY29tbWl0dGVkIGJ1dCBwYXJrZWQgYmVoaW5kIGl0c1xuICAgICAgLy8gZGVmZXJyYWwgKHdob3NlIHJlc29sdmUgcnVucyBvbiBhIGRldGFjaGVkIHRpbWVyLCBub3QgdGhpcyBxdWV1ZSkuXG4gICAgICAvLyBFaXRoZXIgd2F5OiBsZXQgdGhlIHF1ZXVlIGRyYWluLCB0aGVuIHJlLWNoZWNrIGEgdGltZXIgdGljayBsYXRlci5cbiAgICAgIGN0eC5wcm9taXNlUXVldWUudGhlbigoKSA9PiB7XG4gICAgICAgIHNldFRpbWVvdXQoY2hlY2ssIDApO1xuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGZuKCk7XG4gICAgfVxuICB9O1xuICBzZXRUaW1lb3V0KGNoZWNrLCAwKTtcbn1cbiJdfQ==
692
+ /** Schedule a generation-guarded suspension after deliveries settle. */
693
+ export function scheduleWorkflowSuspension(ctx) {
694
+ const generation = ctx.suspensionGeneration;
695
+ scheduleWhenIdle(ctx, () => {
696
+ if (generation !== ctx.suspensionGeneration)
697
+ return;
698
+ ctx.onWorkflowError(new WorkflowSuspension(ctx.invocationsQueue, ctx.globalThis));
699
+ });
700
+ }
701
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJpdmF0ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9wcml2YXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBRUgsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBR2hELE9BQU8sRUFBa0Isa0JBQWtCLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFhakUsTUFBTSxrQkFBa0IsR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLGlDQUFpQyxDQUFDLENBQUM7QUFFekUsTUFBTSxhQUFhLEdBRWYsVUFBVSxDQUFDO0FBRWYsd0RBQXdEO0FBQ3hELE1BQU0sZUFBZSxHQUFHLENBQUMsYUFBYSxDQUFDLGtCQUFrQixDQUFDLEtBQUssSUFBSSxHQUFHLEVBR25FLENBQUMsQ0FBQztBQUVMLE1BQU0sMkJBQTJCLEdBQUcsSUFBSSxHQUFHLENBQUM7SUFDMUMsaUNBQWlDO0lBQ2pDLHlCQUF5QjtJQUN6Qix5QkFBeUI7Q0FDMUIsQ0FBQyxDQUFDO0FBRUgsU0FBUyx3QkFBd0IsQ0FBQyxNQUFjO0lBQzlDLE1BQU0sS0FBSyxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDakMsSUFBSSxLQUFLLENBQUMsTUFBTSxLQUFLLENBQUMsSUFBSSxLQUFLLENBQUMsQ0FBQyxDQUFDLEtBQUssTUFBTSxFQUFFLENBQUM7UUFDOUMsT0FBTyxFQUFFLENBQUM7SUFDWixDQUFDO0lBRUQsTUFBTSxVQUFVLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzVCLE1BQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUN4QixNQUFNLGlCQUFpQixHQUFHLElBQUksR0FBRyxFQUFVLENBQUM7SUFFNUMsTUFBTSxRQUFRLEdBQUcsQ0FBQyxlQUF1QixFQUFFLEVBQUU7UUFDM0MsSUFBSSxlQUFlLEtBQUssVUFBVSxFQUFFLENBQUM7WUFDbkMsaUJBQWlCLENBQUMs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QUcsQ0FBQyxVQUFVLENBQUMsQ0FDN0QsQ0FBQztJQUNKLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogVXRpbHMgdXNlZCBieSB0aGUgYnVuZGxlciB3aGVuIHRyYW5zZm9ybWluZyBjb2RlXG4gKi9cblxuaW1wb3J0IHsgd2l0aFJlc29sdmVycyB9IGZyb20gJ0B3b3JrZmxvdy91dGlscyc7XG5pbXBvcnQgdHlwZSB7IFdvcmxkQ2FwYWJpbGl0aWVzIH0gZnJvbSAnQHdvcmtmbG93L3dvcmxkJztcbmltcG9ydCB0eXBlIHsgRXZlbnRzQ29uc3VtZXIgfSBmcm9tICcuL2V2ZW50cy1jb25zdW1lci5qcyc7XG5pbXBvcnQgeyB0eXBlIFF1ZXVlSXRlbSwgV29ya2Zsb3dTdXNwZW5zaW9uIH0gZnJvbSAnLi9nbG9iYWwuanMnO1xuaW1wb3J0IHR5cGUgeyBSZXBsYXlQYXlsb2FkQ2FjaGUgfSBmcm9tICcuL3JlcGxheS1wYXlsb2FkLWNhY2hlLmpzJztcbmltcG9ydCB0eXBlIHsgU2VyaWFsaXphYmxlIH0gZnJvbSAnLi9zY2hlbWFzLmpzJztcbmltcG9ydCB0eXBlIHsgUGF5bG9hZEtleSB9IGZyb20gJy4vc2VyaWFsaXphdGlvbi9lbmNyeXB0aW9uLmpzJztcblxuZXhwb3J0IHR5cGUgU3RlcEZ1bmN0aW9uPFxuICBBcmdzIGV4dGVuZHMgU2VyaWFsaXphYmxlW10gPSBhbnlbXSxcbiAgUmVzdWx0IGV4dGVuZHMgU2VyaWFsaXphYmxlIHwgdW5rbm93biA9IHVua25vd24sXG4+ID0gKCguLi5hcmdzOiBBcmdzKSA9PiBQcm9taXNlPFJlc3VsdD4pICYge1xuICBtYXhSZXRyaWVzPzogbnVtYmVyO1xuICBzdGVwSWQ/OiBzdHJpbmc7XG59O1xuXG5jb25zdCBSZWdpc3RlcmVkU3RlcHNLZXkgPSBTeW1ib2wuZm9yKCdAd29ya2Zsb3cvY29yZS8vcmVnaXN0ZXJlZFN0ZXBzJyk7XG5cbmNvbnN0IGdsb2JhbFN5bWJvbHM6IHR5cGVvZiBnbG9iYWxUaGlzICYge1xuICBbUmVnaXN0ZXJlZFN0ZXBzS2V5XT86IE1hcDxzdHJpbmcsIFN0ZXBGdW5jdGlvbj47XG59ID0gZ2xvYmFsVGhpcztcblxuLy8gYmlvbWUtaWdub3JlIGxpbnQvc3VzcGljaW91cy9ub0Fzc2lnbkluRXhwcmVzc2lvbnM6IC9cbmNvbnN0IHJlZ2lzdGVyZWRTdGVwcyA9IChnbG9iYWxTeW1ib2xzW1JlZ2lzdGVyZWRTdGVwc0tleV0gPz89IG5ldyBNYXA8XG4gIHN0cmluZyxcbiAgU3RlcEZ1bmN0aW9uXG4+KCkpO1xuXG5jb25zdCBCVUlMVElOX1JFU1BPTlNFX1NURVBfTkFNRVMgPSBuZXcgU2V0KFtcbiAgJ19fYnVpbHRpbl9yZXNwb25zZV9hcnJheV9idWZmZXInLFxuICAnX19idWlsdGluX3Jlc3BvbnNlX2pzb24nLFxuICAnX19idWlsdGluX3Jlc3BvbnNlX3RleHQnLFxuXSk7XG5cbmZ1bmN0aW9uIGdldFN0ZXBJZEFsaWFzQ2FuZGlkYXRlcyhzdGVwSWQ6IHN0cmluZyk6IHN0cmluZ1tdIHtcbiAgY29uc3QgcGFydHMgPSBzdGVwSWQuc3BsaXQoJy8vJyk7XG4gIGlmIChwYXJ0cy5sZW5ndGggIT09IDMgfHwgcGFydHNbMF0gIT09ICdzdGVwJykge1xuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIGNvbnN0IG1vZHVsZVBhdGggPSBwYXJ0c1sxXTtcbiAgY29uc3QgZm5OYW1lID0gcGFydHNbMl07XG4gIGNvbnN0IG1vZHVsZVBhdGhBbGlhc2VzID0gbmV3IFNldDxzdHJpbmc+KCk7XG5cbiAgY29uc3QgYWRkQWxpYXMgPSAoYWxpYXNNb2R1bGVQYXRoOiBzdHJpbmcpID0+IHtcbiAgICBpZiAoYWxpYXNNb2R1bGVQYXRoICE9PSBtb2R1bGVQYXRoKSB7XG4gICAgICBtb2R1bGVQYXRoQWxpYXNlcy5hZGQoYWxpYXNNb2R1bGVQYXRoKTtcbiAgICB9XG4gIH07XG5cbiAgaWYgKG1vZHVsZVBhdGguc3RhcnRzV2l0aCgnLi93b3JrZmxvd3MvJykpIHtcbiAgICBjb25zdCB3b3JrZmxvd1JlbGF0aXZlUGF0aCA9IG1vZHVsZVBhdGguc2xpY2UoJy4vJy5sZW5ndGgpO1xuICAgIGFkZEFsaWFzKGAuL2V4YW1wbGUvJHt3b3JrZmxvd1JlbGF0aXZlUGF0aH1gKTtcbiAgICBhZGRBbGlhcyhgLi9zcmMvJHt3b3JrZmxvd1JlbGF0aXZlUGF0aH1gKTtcbiAgfSBlbHNlIGlmIChtb2R1bGVQYXRoLnN0YXJ0c1dpdGgoJy4vZXhhbXBsZS93b3JrZmxvd3MvJykpIHtcbiAgICBjb25zdCB3b3JrZmxvd1JlbGF0aXZlUGF0aCA9IG1vZHVsZVBhdGguc2xpY2UoJy4vZXhhbXBsZS8nLmxlbmd0aCk7XG4gICAgYWRkQWxpYXMoYC4vJHt3b3JrZmxvd1JlbGF0aXZlUGF0aH1gKTtcbiAgICBhZGRBbGlhcyhgLi9zcmMvJHt3b3JrZmxvd1JlbGF0aXZlUGF0aH1gKTtcbiAgfSBlbHNlIGlmIChtb2R1bGVQYXRoLnN0YXJ0c1dpdGgoJy4vc3JjL3dvcmtmbG93cy8nKSkge1xuICAgIGNvbnN0IHdvcmtmbG93UmVsYXRpdmVQYXRoID0gbW9kdWxlUGF0aC5zbGljZSgnLi9zcmMvJy5sZW5ndGgpO1xuICAgIGFkZEFsaWFzKGAuLyR7d29ya2Zsb3dSZWxhdGl2ZVBhdGh9YCk7XG4gICAgYWRkQWxpYXMoYC4vZXhhbXBsZS8ke3dvcmtmbG93UmVsYXRpdmVQYXRofWApO1xuICB9XG5cbiAgcmV0dXJuIEFycmF5LmZyb20oXG4gICAgbW9kdWxlUGF0aEFsaWFzZXMsXG4gICAgKGFsaWFzTW9kdWxlUGF0aCkgPT4gYHN0ZXAvLyR7YWxpYXNNb2R1bGVQYXRofS8vJHtmbk5hbWV9YFxuICApO1xufVxuXG5mdW5jdGlvbiBnZXRCdWlsdGluUmVzcG9uc2VTdGVwQWxpYXMoc3RlcElkOiBzdHJpbmcpOiBTdGVwRnVuY3Rpb24gfCB1bmRlZmluZWQge1xuICBpZiAoIUJVSUxUSU5fUkVTUE9OU0VfU1RFUF9OQU1FUy5oYXMoc3RlcElkKSkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICBmb3IgKGNvbnN0IFtyZWdpc3RlcmVkU3RlcElkLCBzdGVwRm5dIG9mIHJlZ2lzdGVyZWRTdGVwcy5lbnRyaWVzKCkpIHtcbiAgICBpZiAocmVnaXN0ZXJlZFN0ZXBJZC5lbmRzV2l0aChgLy8ke3N0ZXBJZH1gKSkge1xuICAgICAgcmV0dXJuIHN0ZXBGbjtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIFJlZ2lzdGVyIGEgc3RlcCBmdW5jdGlvbiB0byBiZSBzZXJ2ZWQgaW4gdGhlIHNlcnZlciBidW5kbGUuXG4gKiBBbHNvIHNldHMgdGhlIHN0ZXBJZCBwcm9wZXJ0eSBvbiB0aGUgZnVuY3Rpb24gZm9yIHNlcmlhbGl6YXRpb24gc3VwcG9ydC5cbiAqXG4gKiBOb3RlOiBUaGUgU1dDIGNvbXBpbGVyIHBsdWdpbiBubyBsb25nZXIgZ2VuZXJhdGVzIGNhbGxzIHRvIHRoaXMgZnVuY3Rpb24uXG4gKiBTdGVwIHJlZ2lzdHJhdGlvbiBpcyBub3cgaW5saW5lZCBhcyBhIHNlbGYtY29udGFpbmVkIElJRkUgdGhhdCB3cml0ZXNcbiAqIGRpcmVjdGx5IHRvIHRoZSBnbG9iYWwgTWFwIGF0IFN5bWJvbC5mb3IoXCJAd29ya2Zsb3cvY29yZS8vcmVnaXN0ZXJlZFN0ZXBzXCIpLlxuICogVGhpcyBmdW5jdGlvbiBpcyBrZXB0IGZvciBpbnRlcm5hbC90ZXN0IHVzZSBvbmx5LlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVnaXN0ZXJTdGVwRnVuY3Rpb24oc3RlcElkOiBzdHJpbmcsIHN0ZXBGbjogU3RlcEZ1bmN0aW9uKSB7XG4gIHJlZ2lzdGVyZWRTdGVwcy5zZXQoc3RlcElkLCBzdGVwRm4pO1xuICBzdGVwRm4uc3RlcElkID0gc3RlcElkO1xufVxuXG4vKipcbiAqIEZpbmQgYSByZWdpc3RlcmVkIHN0ZXAgZnVuY3Rpb24gYnkgbmFtZVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0U3RlcEZ1bmN0aW9uKHN0ZXBJZDogc3RyaW5nKTogU3RlcEZ1bmN0aW9uIHwgdW5kZWZpbmVkIHtcbiAgY29uc3QgZGlyZWN0TWF0Y2ggPSByZWdpc3RlcmVkU3RlcHMuZ2V0KHN0ZXBJZCk7XG4gIGlmIChkaXJlY3RNYXRjaCkge1xuICAgIHJldHVybiBkaXJlY3RNYXRjaDtcbiAgfVxuXG4gIC8vIFN1cHBvcnQgZXF1aXZhbGVudCB3b3JrZmxvdyBwYXRoIGFsaWFzZXMgaW4gbWl4ZWQgc3ltbGluayBlbnZpcm9ubWVudHMuXG4gIGZvciAoY29uc3QgYWxpYXNTdGVwSWQgb2YgZ2V0U3RlcElkQWxpYXNDYW5kaWRhdGVzKHN0ZXBJZCkpIHtcbiAgICBjb25zdCBhbGlhc01hdGNoID0gcmVnaXN0ZXJlZFN0ZXBzLmdldChhbGlhc1N0ZXBJZCk7XG4gICAgaWYgKGFsaWFzTWF0Y2gpIHtcbiAgICAgIHJldHVybiBhbGlhc01hdGNoO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IGJ1aWx0aW5BbGlhc01hdGNoID0gZ2V0QnVpbHRpblJlc3BvbnNlU3RlcEFsaWFzKHN0ZXBJZCk7XG4gIGlmIChidWlsdGluQWxpYXNNYXRjaCkge1xuICAgIHJldHVybiBidWlsdGluQWxpYXNNYXRjaDtcbiAgfVxuXG4gIHJldHVybiB1bmRlZmluZWQ7XG59XG5cbi8vIE5vdGU6IF9fcHJpdmF0ZV9nZXRDbG9zdXJlVmFycyBpcyBubyBsb25nZXIgcmUtZXhwb3J0ZWQgaGVyZS5cbi8vIFRoZSBTV0MgY29tcGlsZXIgcGx1Z2luIG5vdyBpbmxpbmVzIGNsb3N1cmUgdmFyaWFibGUgYWNjZXNzIGFzIGFcbi8vIHNlbGYtY29udGFpbmVkIElJRkUgdGhhdCByZWFkcyBkaXJlY3RseSBmcm9tIHRoZSBnbG9iYWwgQXN5bmNMb2NhbFN0b3JhZ2Vcbi8vIGF0IFN5bWJvbC5mb3IoXCJXT1JLRkxPV19TVEVQX0NPTlRFWFRfU1RPUkFHRVwiKS5cblxuZXhwb3J0IGludGVyZmFjZSBXb3JrZmxvd09yY2hlc3RyYXRvckNvbnRleHQge1xuICBydW5JZDogc3RyaW5nO1xuICBlbmNyeXB0aW9uS2V5OiBQYXlsb2FkS2V5IHwgdW5kZWZpbmVkO1xuICB3b3JsZENhcGFiaWxpdGllcz86IFdvcmxkQ2FwYWJpbGl0aWVzO1xuICBnbG9iYWxUaGlzOiB0eXBlb2YgZ2xvYmFsVGhpcztcbiAgLyoqXG4gICAqIEluY3JlbWVudHMgd2hlbiBhIHN1c3BlbnNpb24gaXMgYWNjZXB0ZWQgYW5kIG9uIGV2ZXJ5IHJldGFpbmVkLXNlc3Npb25cbiAgICogcmVzdW1lLiBTdGVwLCBob29rLCBhbmQgYXR0cmlidXRlIHN1c3BlbnNpb24gc2lnbmFscyBjYXB0dXJlIGl0IHdoZW5cbiAgICogc2NoZWR1bGVkIGFuZCBuby1vcCBpZiBpdCBtb3ZlZCwgd2hpY2ggZHJvcHMgc2FtZS1ib3VuZGFyeSBzaWJsaW5nIHNpZ25hbHNcbiAgICogYW5kIHRpbWVycyBxdWV1ZWQgYXQgYm91bmRhcnkgTiB0aGF0IHdvdWxkIGZpcmUgYWZ0ZXIgdGhlIHNlc3Npb24gcmVzdW1lZFxuICAgKiBpbnRvIGJvdW5kYXJ5IE4rMS4gU2xlZXAgc2lnbmFscyBhcmUgaW50ZW50aW9uYWxseSB1bmd1YXJkZWQ6IHRoZWlyXG4gICAqIHByZXNlbmNlIG1ha2VzIHRoZSBib3VuZGFyeSB1bnJldGFpbmFibGUsIHNvIGEgbGF0ZSBzaWduYWwgY29ycmVjdGx5XG4gICAqIGRlbW90ZXMgdGhlIHNlc3Npb24gKHdvcmtmbG93LnRzIGBvbldvcmtmbG93RXJyb3JgKS5cbiAgICovXG4gIHN1c3BlbnNpb25HZW5lcmF0aW9uOiBudW1iZXI7XG4gIGV2ZW50c0NvbnN1bWVyOiBFdmVudHNDb25zdW1lcjtcbiAgLyoqXG4gICAqIE1hcCBvZiBwZW5kaW5nIGludm9jYXRpb25zIGtleWVkIGJ5IGNvcnJlbGF0aW9uSWQuXG4gICAqIFVzaW5nIE1hcCBpbnN0ZWFkIG9mIEFycmF5IGZvciBPKDEpIGxvb2t1cC9kZWxldGUgb3BlcmF0aW9ucy5cbiAgICovXG4gIGludm9jYXRpb25zUXVldWU6IE1hcDxzdHJpbmcsIFF1ZXVlSXRlbT47XG4gIG9uV29ya2Zsb3dFcnJvcjogKGVycm9yOiBFcnJvcikgPT4gdm9pZDtcbiAgLyoqXG4gICAqIE1pbnRzIHRoZSBVTElEIGJvZHkgb2YgYSBjb3JyZWxhdGlvbiBpZC4gRXZlcnkgZW50aXR5IGEgcmVwbGF5IGNyZWF0ZXNcbiAgICogZHJhd3MgZnJvbSB0aGlzIG9uZSBtb25vdG9uaWMgc2VxdWVuY2UsIHNvIGFuIGlkIGlzIGFuIG9yZGluYWwgb3ZlciB0aGVcbiAgICogd2hvbGUgcnVuIGFuZCBib3RoIHJlcGxheXMgb2YgYSBydW4gbXVzdCBkcmF3IGluIHRoZSBzYW1lIG9yZGVyLlxuICAgKi9cbiAgZ2VuZXJhdGVVbGlkOiAoKSA9PiBzdHJpbmc7XG4gIC8qKlxuICAgKiBNb25vdG9uZSBjb3VudCBvZiBjb3JyZWxhdGlvbi1pZCBkcmF3cyB0aGlzIHJlcGxheSBoYXMgbWFkZS4gUHJvZ3Jlc3NcbiAgICogbWV0cmljIGZvciB7QGxpbmsgcXVpZXNjZUVhcmxpZXJDYXNjYWRlc306IGEgbWFjcm90YXNrIHR1cm4gaW4gd2hpY2ggaXRcbiAgICogZG9lcyBub3QgbW92ZSAoYW5kIG5vIGh5ZHJhdGlvbiBpcyBpbiBmbGlnaHQpIG1lYW5zIGV2ZXJ5IHdva2VuIGJyYW5jaCBoYXNcbiAgICogcnVuIGFzIGZhciBhcyBpdCBjYW4gd2l0aG91dCBhbm90aGVyIGRlbGl2ZXJ5LiBPcHRpb25hbCBzbyBsaWdodHdlaWdodFxuICAgKiB0ZXN0IGNvbnRleHRzIGRlZ3JhZGUgdG8gdGhlIHNpbmdsZS15aWVsZCBiZWhhdmlvci5cbiAgICovXG4gIHJlYWRvbmx5IG1pbnRDb3VudD86IG51bWJlcjtcbiAgZ2VuZXJhdGVOYW5vaWQ6ICgpID0+IHN0cmluZztcbiAgLyoqXG4gICAqIFNlcXVlbnRpYWwgcHJvbWlzZSBxdWV1ZSB0aGF0IGVuc3VyZXMgYWxsIGV2ZW50LWRyaXZlbiBwcm9taXNlIHJlc29sdXRpb25zXG4gICAqIChzdGVwIHJlc3VsdHMsIGhvb2sgcGF5bG9hZHMsIGZhaWx1cmVzLCBzdXNwZW5zaW9ucykgaGFwcGVuIGluIGV2ZW50IGxvZ1xuICAgKiBvcmRlci4gRXZlcnkgcmVzb2x2ZSwgcmVqZWN0LCBvciB3b3JrZmxvdyBlcnJvciBpcyBjaGFpbmVkIHRocm91Z2ggdGhpc1xuICAgKiBxdWV1ZSBzbyB0aGF0IGV2ZW4gaWYgaW5kaXZpZHVhbCBvcGVyYXRpb25zIHRha2UgdmFyaWFibGUgdGltZSAoZS5nLixcbiAgICogYXN5bmMgZGVjcnlwdGlvbiksIHByb21pc2VzIHJlc29sdmUgZGV0ZXJtaW5pc3RpY2FsbHkuXG4gICAqL1xuICBwcm9taXNlUXVldWU6IFByb21pc2U8dm9pZD47XG4gIC8qKlxuICAgKiBDb3VudGVyIG9mIGluLWZsaWdodCBhc3luYyBkYXRhIGRlbGl2ZXJ5IG9wZXJhdGlvbnMgKHN0ZXAgcmVzdWx0XG4gICAqIGh5ZHJhdGlvbiwgaG9vayBwYXlsb2FkIGh5ZHJhdGlvbiwgYWJvcnQgc2lnbmFsIGh5ZHJhdGlvbikuIFN1c3BlbnNpb25zXG4gICAqIG11c3Qgd2FpdCBmb3IgdGhpcyB0byByZWFjaCAwIGJlZm9yZSBmaXJpbmcsIHRvIGF2b2lkIHByZWVtcHRpbmcgZGF0YVxuICAgKiBkZWxpdmVyeSwgZS5nLiBkZWh5ZHJhdGluZyBhIHN0ZXAncyBhcmd1bWVudHMgd2hpbGUgYW4gYWJvcnQgdGhhdCBzaG91bGRcbiAgICogYmUgcmVmbGVjdGVkIGluIHRob3NlIGFyZ3VtZW50cyBpcyBzdGlsbCBoeWRyYXRpbmcgaXRzIHJlYXNvbi5cbiAgICovXG4gIHBlbmRpbmdEZWxpdmVyaWVzOiBudW1iZXI7XG4gIC8qKlxuICAgKiBPcmRlcmVkIHJlZ2lzdHJ5IG9mIGluLWZsaWdodCBcImJyYW5jaC1kZWNpZGluZ1wiIGRlbGl2ZXJpZXM6IHRoZVxuICAgKiByZXNvbHV0aW9ucyBhIHdvcmtmbG93IHR5cGljYWxseSBgUHJvbWlzZS5yYWNlYHMgb24sIG9yIGF3YWl0cyBmcm9tXG4gICAqIGluZGVwZW5kZW50IGNvbmN1cnJlbnQgYnJhbmNoZXM6IGhvb2sgcGF5bG9hZHMgKGBob29rX3JlY2VpdmVkYCksIHdhaXRcbiAgICogY29tcGxldGlvbnMgKGB3YWl0X2NvbXBsZXRlZGApLCBhbmQgc3RlcCByZXN1bHRzIChgc3RlcF9jb21wbGV0ZWRgIC9cbiAgICogYHN0ZXBfZmFpbGVkYCkuIEtleWVkIGJ5IHRoZSBkZWxpdmVyeSdzIHBvc2l0aW9uIChpbmRleCkgaW4gdGhlIGNvbnN1bWVkXG4gICAqIGV2ZW50IGxvZy5cbiAgICpcbiAgICogVGhlIHByb2JsZW06IGVhY2ggb2YgdGhlc2UgcmVzb2x1dGlvbnMgcmVhY2hlcyB3b3JrZmxvdyBjb2RlIGFmdGVyIGFcbiAgICogZGlmZmVyZW50LCB3b3JrbG9hZC1kZXBlbmRlbnQgbnVtYmVyIG9mIG1pY3JvdGFzayBob3BzLiBBIGJ1ZmZlcmVkIGhvb2tcbiAgICogcGF5bG9hZCBpcyBvYnNlcnZlZCB2aWEgdGhlIGFzeW5jIGhvb2sgaXRlcmF0b3IgKGB5aWVsZCBhd2FpdCB0aGlzYCksXG4gICAqIGNvc3RpbmcgZXh0cmEgaG9wczsgYSBgd2FpdF9jb21wbGV0ZWRgIHJlc29sdmVzIHdpdGggZmV3ZXIsIGFuZCBhIHJldXNlZFxuICAgKiBzbGVlcCBjYW4gcmVzb2x2ZSBpbiBhbiBlbnRpcmVseSBlYXJsaWVyIGxvb3AgaXRlcmF0aW9uOyBhIHN0ZXAgcmVzdWx0IGlzXG4gICAqIGdhdGVkIG9uIGh5ZHJhdGlvbiB3aG9zZSBjb3N0IHZhcmllcyBiZXR3ZWVuIHJlcGxheXMgb2YgdGhlIFNBTUVcbiAgICogaW52b2NhdGlvbjogdGhlIGZpcnN0IHJlcGxheSBwYXlzIHRoZSBmdWxsIGRlY3J5cHQvZGVjb21wcmVzcy9yZXZpdmUsXG4gICAqIHdoaWxlIGxhdGVyIHJlcGxheXMgc2hhcmluZyB0aGUgaW52b2NhdGlvbidzIGBSZXBsYXlQYXlsb2FkQ2FjaGVgXG4gICAqIG1lbW8taGl0IHNtYWxsIHByaW1pdGl2ZSByZXN1bHRzIGFuZCByZXNvbHZlIGluIG9uZSBvciB0d28gaG9wcy4gRWl0aGVyXG4gICAqIHdheSwgdGhlIHJlc29sdXRpb24gdGhhdCB0aGUgY29tbWl0dGVkIGV2ZW50IGxvZyBvcmRlcmVkIGZpcnN0IGNhbiBsb3NlIGFcbiAgICogYFByb21pc2UucmFjZWAgKG9yIGEgYHVzZVN0ZXBgIFVMSUQgYWxsb2NhdGlvbikgdG8gYSBmYXN0ZXItIG9yXG4gICAqIGFscmVhZHktcmVzb2x2ZWQgY29tcGV0aXRvciwgZGl2ZXJnaW5nIGZyb20gdGhlIGxvZyBhbmQgc3VyZmFjaW5nIGFzXG4gICAqIGBDb3JydXB0ZWRFdmVudExvZ0Vycm9yYC5cbiAgICpcbiAgICogVGhlIGZpeCBpcyBhIHN0cmljdCwgZGV0ZXJtaW5pc3RpYyBkZWxpdmVyeSBvcmRlciBhbmNob3JlZCBvblxuICAgKiBldmVudC1sb2cgcG9zaXRpb246IGEgZGVsaXZlcnkgZG9lcyBub3QgcmVzb2x2ZSB0byB0aGUgd29ya2Zsb3cgdW50aWxcbiAgICogZXZlcnkgcmVsZXZhbnQgZWFybGllci1pbi1sb2cgZGVsaXZlcnkgaGFzIGJlZW4gZGVsaXZlcmVkLiBCZWNhdXNlIHRoZVxuICAgKiBnYXRlIGlzIFwidGhlIGVhcmxpZXIgZGVsaXZlcnkgcmVzb2x2ZWRcIiwgbm90IFwid29uIGEgdGltaW5nIHJhY2VcIiwgdGhlXG4gICAqIG91dGNvbWUgaXMgaW5kZXBlbmRlbnQgb2YgbWljcm90YXNrIGhvcHMsIGh5ZHJhdGlvbi9kZWNyeXB0aW9uIHRpbWUsXG4gICAqIGFuZCBgUHJvbWlzZS5yYWNlYCBhcmd1bWVudCBvcmRlci4gV2hpY2ggZWFybGllciBraW5kcyBhIGRlbGl2ZXJ5IGRlZmVyc1xuICAgKiBiZWhpbmQgaXMgc3BlbGxlZCBvdXQgb24ge0BsaW5rIGF3YWl0RWFybGllckRlbGl2ZXJpZXN9LlxuICAgKlxuICAgKiBJbmRleCBpcyB1c2VkIHJhdGhlciB0aGFuIHRoZSBgZXZlbnRJZGAgc3RyaW5nIGJlY2F1c2UgYGV2ZW50SWRgIGlzIGFuXG4gICAqIG9wYXF1ZSwgd29ybGQtYXNzaWduZWQgdmFsdWUgbm90IGd1YXJhbnRlZWQgdG8gc29ydCBpbiBjcmVhdGlvbiBvcmRlclxuICAgKiAob25seSB0aGUgYnVuZGxlZCBVTElEIHdvcmxkcyBoYXBwZW4gdG8pLlxuICAgKlxuICAgKiBPcHRpb25hbCBzbyBvbGRlci9vdXQtb2YtdHJlZSBjb250ZXh0cyAoYW5kIGxpZ2h0d2VpZ2h0IHRlc3QgaGFybmVzc2VzKVxuICAgKiB0aGF0IGRvIG5vdCBpbml0aWFsaXplIGl0IGRlZ3JhZGUgZ3JhY2VmdWxseSB0byB0aGUgcHJldmlvdXMgYmVoYXZpb3IuXG4gICAqL1xuICBwZW5kaW5nRGVsaXZlcnlCYXJyaWVycz86IE1hcDxudW1iZXIsIERlbGl2ZXJ5QmFycmllckVudHJ5PjtcbiAgLyoqXG4gICAqIEludm9jYXRpb24tc2NvcGVkIGNhY2hlIG9mIHByZXBhcmVkIHNlcmlhbGl6ZWQgcGF5bG9hZHMgYW5kIGltbXV0YWJsZSBmaW5hbFxuICAgKiB2YWx1ZXMuIFByZXBhcmVkIGJ5dGVzIHN1cnZpdmUgZnJlc2ggcmVwbGF5IFZNczsgb2JqZWN0IGdyYXBocyBkbyBub3QuXG4gICAqL1xuICByZXBsYXlQYXlsb2FkQ2FjaGU6IFJlcGxheVBheWxvYWRDYWNoZTtcbn1cblxuLyoqIFRoZSBraW5kIG9mIGJyYW5jaC1kZWNpZGluZyBkZWxpdmVyeSBhIGJhcnJpZXIgcmVwcmVzZW50cy4gKi9cbmV4cG9ydCB0eXBlIERlbGl2ZXJ5S2luZCA9ICdob29rJyB8ICd3YWl0JyB8ICdzdGVwJztcblxuaW50ZXJmYWNlIERlbGl2ZXJ5QmFycmllckVudHJ5IHtcbiAga2luZDogRGVsaXZlcnlLaW5kO1xuICAvKiogUmVzb2x2ZXMgb25jZSB0aGlzIGRlbGl2ZXJ5IGhhcyByZXNvbHZlZCB0byB0aGUgd29ya2Zsb3cuICovXG4gIGRlbGl2ZXJlZDogUHJvbWlzZTx2b2lkPjtcbiAgLyoqXG4gICAqIFdoZXRoZXIgdGhpcyBkZWxpdmVyeSBpcyBjb21taXR0ZWQgdG8gcmVhY2hpbmcgdGhlIHdvcmtmbG93IHdpdGhvdXQgYW55XG4gICAqIGZ1cnRoZXIgYWN0aW9uIGJ5IHdvcmtmbG93IGNvZGUuIFRydWUgZm9yIHdhaXQgY29tcGxldGlvbnMgYW5kIHN0ZXBcbiAgICogcmVzdWx0cywgd2hpY2ggYWx3YXlzIHJlc29sdmUgZnJvbSB0aGVpciBvd24gY2hhaW4sIGFuZCBmb3IgYSBob29rIHBheWxvYWRcbiAgICogdGhhdCBhbHJlYWR5IGhhZCBhIHdhaXRpbmcgY29uc3VtZXIgd2hlbiBpdCB3YXMgY29uc3VtZWQuXG4gICAqXG4gICAqIEZhbHNlIGZvciBhIEJVRkZFUkVEIGhvb2sgcGF5bG9hZCBubyBjb25zdW1lciBoYXMgY2xhaW1lZCB5ZXQ6IGl0IGlzXG4gICAqIGRlbGl2ZXJlZCBieSBgY2xhaW0oKWAsIGkuZS4gd2hlbmV2ZXIgdGhlIHdvcmtmbG93IG5leHQgcmVhZHMgdGhlIGhvb2ssXG4gICAqIHdoaWNoIG1heSBiZSBjYXVzYWxseSAqYWZ0ZXIqIGEgbGF0ZXItaW4tbG9nIGRlbGl2ZXJ5LiBgYXJtKClgIGZsaXBzIGl0XG4gICAqIG9uY2UgYSBjb25zdW1lciB0YWtlcyB0aGUgcGF5bG9hZC5cbiAgICovXG4gIGFybWVkOiBib29sZWFuO1xuICAvKipcbiAgICogUmV0aXJlIHRoaXMgZW50cnk6IHJlc29sdmUgYGRlbGl2ZXJlZGAgYW5kIHJlbW92ZSBpdCBmcm9tIHRoZSByZWdpc3RyeSxcbiAgICogZXhhY3RseSBhcyBgbWFya0RlbGl2ZXJlZGAgd291bGQuIENhbGxlZCBvbmx5IGJ5IHRoZSBjb250ZXh0J3Mgc2FmZXR5LW5ldFxuICAgKiBkaXNwZW5zZXIgKHtAbGluayBlbnN1cmVCYXJyaWVyU2FmZXR5TmV0fSksIGFuZCBvbmx5IG9uIHRoZSBsb3dlc3QtaW5kZXhcbiAgICogZW50cnkgYXQgZGVsaXZlcnkgaWRsZS4gSWRlbXBvdGVudC5cbiAgICovXG4gIHJldGlyZTogKCkgPT4gdm9pZDtcbn1cblxuLyoqXG4gKiBXaGljaCBlYXJsaWVyIGtpbmRzIGVhY2ggZGVsaXZlcnkga2luZCBkZWZlcnMgYmVoaW5kLiBDaG9zZW4gc28gdGhhdCBubyBraW5kXG4gKiBibG9ja3Mgb24gYSBwZWVyIGl0IGRvZXMgbm90IG5lZWQgdG86XG4gKlxuICogIC0gYSBob29rIGRlZmVycyBiZWhpbmQgZWFybGllciBIT09LUywgV0FJVFMgYW5kIFNURVBTO1xuICogIC0gYSB3YWl0IGRlZmVycyBiZWhpbmQgZWFybGllciBIT09LUyBhbmQgU1RFUFMgKG5vdCBlYXJsaWVyIHdhaXRzLCBzaW5jZSBhXG4gKiAgICB3YWl0IG5ldmVyIG5lZWRzIHRvIHF1ZXVlIGJlaGluZCBhbm90aGVyIHdhaXQpO1xuICogIC0gYSBzdGVwIGRlZmVycyBiZWhpbmQgZWFybGllciBXQUlUUywgSE9PS1MgYW5kIFNURVBTLlxuICpcbiAqIFRoZSBzdGVwLWJlaGluZC1zdGVwIGVkZ2UgaXMgbm90IHJlZHVuZGFudCB3aXRoIHRoZSBzZXJpYWwgYHByb21pc2VRdWV1ZWAuXG4gKiBUaGUgcXVldWUgZml4ZXMgdGhlIG9yZGVyIGluIHdoaWNoIHN0ZXAgcmVzdWx0cyBhcmUgSFlEUkFURUQsIGJ1dCBhIHN0ZXAgbm9cbiAqIGxvbmdlciByZXNvbHZlcyBpbnNpZGUgaXRzIHF1ZXVlIHNsb3Q6IGl0IGNhcHR1cmVzIHRoZSBvdXRjb21lIHRoZXJlIGFuZFxuICogcmVzb2x2ZXMgZnJvbSBhIGRldGFjaGVkIGNvbnRpbnVhdGlvbiBvbmNlIGl0cyBiYXJyaWVyIGNsZWFycy4gVHdvIHN0ZXBzXG4gKiBhZ3JlZSBvbiB0aGF0IGNvbnRpbnVhdGlvbidzIG9yZGVyaW5nIG9ubHkgd2hpbGUgdGhleSBkZWZlciBiZWhpbmQgdGhlIHNhbWVcbiAqIHNldCwgd2hpY2ggaG9sZHMgd2hlbiB0aGV5IGFyZSBjb25zdW1lZCBpbiB0aGUgc2FtZSBkcmFpbiB3aW5kb3cgYnV0IG5vdFxuICogYWNyb3NzIHdpbmRvd3M6IGEgc3RlcCBjb25zdW1lZCBsYXRlciBjYW4gbWlzcyBhIHdhaXQvaG9vayBiYXJyaWVyIHRoYXQgYW5cbiAqIGVhcmxpZXIgc3RlcCBpcyBzdGlsbCBwYXJrZWQgb24sIGJlY2F1c2UgdGhlIGJhcnJpZXIgcmV0aXJlZCBpbiBiZXR3ZWVuLiBUaGVcbiAqIGVhcmxpZXIgc3RlcCBpcyB0aGVuIHdhaXRpbmcgb3V0IHRoZSBtYWNyb3Rhc2sgeWllbGQgYmVsb3cgd2hpbGUgdGhlIGxhdGVyXG4gKiBvbmUgcmVzb2x2ZXMgb24gbWljcm90YXNrcywgYW5kIG92ZXJ0YWtlcyBpdC4gU2VlXG4gKiBgZGVsaXZlcnktYmFycmllci1jb3ZlcmFnZS50ZXN0LnRzYC4gRGVmZXJyaW5nIGJlaGluZCBlYXJsaWVyIHN0ZXBzXG4gKiBjbG9zZXMgdGhhdCB3aW5kb3cgc3RydWN0dXJhbGx5OiB0aGUgZWFybGllciBzdGVwJ3MgYmFycmllciBpcyBzdGlsbFxuICogcmVnaXN0ZXJlZCBwcmVjaXNlbHkgYmVjYXVzZSBpdCBoYXMgbm90IGRlbGl2ZXJlZCB5ZXQuXG4gKlxuICogRXZlcnkgZWRnZSBwb2ludHMgZnJvbSBhIGxhdGVyIGxvZyBpbmRleCB0byBhIHN0cmljdGx5IGVhcmxpZXIgb25lLCBzbyB0aGVcbiAqIHdhaXQtZm9yIGdyYXBoIGNhbiBuZXZlciBjb250YWluIGEgY3ljbGUuXG4gKi9cbmNvbnN0IERFRkVSX0JFSElORDogUmVjb3JkPERlbGl2ZXJ5S2luZCwgcmVhZG9ubHkgRGVsaXZlcnlLaW5kW10+ID0ge1xuICBob29rOiBbJ2hvb2snLCAnd2FpdCcsICdzdGVwJ10sXG4gIHdhaXQ6IFsnaG9vaycsICdzdGVwJ10sXG4gIHN0ZXA6IFsnd2FpdCcsICdob29rJywgJ3N0ZXAnXSxcbn07XG5cbi8qKlxuICogV2hldGhlciBhIGRlbGl2ZXJ5IG9mIGBraW5kYCBhdCBsb2cgaW5kZXggYGluZGV4YCBnYXRlcyBvbiB0aGUgZWFybGllclxuICogcmVnaXN0cnkgZW50cnkgYG90aGVyYCAoYXQgYG90aGVySW5kZXhgKS5cbiAqXG4gKiBTaW5nbGUgc291cmNlIG9mIHRydXRoIGZvciB0aGF0IHF1ZXN0aW9uLCBjYWxsZWQgYnkgYm90aFxuICoge0BsaW5rIGF3YWl0RWFybGllckRlbGl2ZXJpZXN9ICh3aGljaCBhd2FpdHMgd2hhdCBpdCBnYXRlcyBvbikgYW5kXG4gKiB7QGxpbmsgY29tcHV0ZVJlc29sdmVzT25JdHNPd259ICh3aGljaCByZWN1cnNlcyBpbnRvIHdoYXQgaXQgZ2F0ZXMgb24pLlxuICogVGhvc2UgdHdvIE1VU1QgYWdyZWUgZXhhY3RseSwgYW5kIHRoZSBkb2MgYmxvY2sgb25cbiAqIHtAbGluayBhd2FpdEVhcmxpZXJEZWxpdmVyaWVzfSBzdGFrZXMgZGVhZGxvY2stZnJlZWRvbSBvbiBpdCwgc28gdGhlXG4gKiBjb25kaXRpb24gbGl2ZXMgaGVyZSByYXRoZXIgdGhhbiBiZWluZyBzcGVsbGVkIG91dCB0d2ljZS5cbiAqXG4gKiBPbmUgZGVsaWJlcmF0ZSBleGNlcHRpb246IHRoZSBsb2ctb3JkZXItZHJhd3MgdHVybnN0aWxlIGluXG4gKiB7QGxpbmsgcXVpZXNjZUVhcmxpZXJDYXNjYWRlc30gd2FpdHMgb24gQU5ZIGxvd2VyIGFybWVkIGVudHJ5LCBhIHN0cmljdGx5XG4gKiB3aWRlciByZWxhdGlvbiB0aGFuIHRoaXMgb25lLiBXaHkgdGhhdCB3aWR0aCBjYW5ub3QgZGVhZGxvY2sgdGhlXG4gKiBzYWZldHktbmV0IGRpc3BlbnNlciBpcyBhcmd1ZWQgYXQgdGhlIHR1cm5zdGlsZSBpdHNlbGYuXG4gKi9cbmZ1bmN0aW9uIGdhdGVzT24oXG4gIGtpbmQ6IERlbGl2ZXJ5S2luZCxcbiAgaW5kZXg6IG51bWJlcixcbiAgb3RoZXJJbmRleDogbnVtYmVyLFxuICBvdGhlcjogRGVsaXZlcnlCYXJyaWVyRW50cnlcbik6IGJvb2xlYW4ge1xuICBpZiAob3RoZXJJbmRleCA+PSBpbmRleCB8fCAhREVGRVJfQkVISU5EW2tpbmRdLmluY2x1ZGVzKG90aGVyLmtpbmQpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIC8vIEEgc3RlcCBza2lwcyBhbiBVTkFSTUVEIGVhcmxpZXIgZW50cnkgKGFuIHVuY2xhaW1lZCBidWZmZXJlZCBob29rXG4gIC8vIHBheWxvYWQpLiBTZWUgdGhlIGFzeW1tZXRyeSBkZXNjcmliZWQgb24gYGF3YWl0RWFybGllckRlbGl2ZXJpZXNgLiBUaGVcbiAgLy8gc2tpcCBpcyBkaXJlY3QsIG5ldmVyIHRyYW5zaXRpdmU6IGFybWVkIGVudHJpZXMgYXJlIHN0aWxsIGdhdGVkIG9uLCBldmVuXG4gIC8vIHdoZW4gdGhleSBhcmUgdGhlbXNlbHZlcyBwYXJrZWQgYmVoaW5kIHN1Y2ggYSBwYXlsb2FkLlxuICByZXR1cm4gIShraW5kID09PSAnc3RlcCcgJiYgIW90aGVyLmFybWVkKTtcbn1cblxuLyoqXG4gKiBXaGV0aGVyIGBlbnRyeWAgd2lsbCByZXNvbHZlIG9uIGl0cyBvd246IGl0IGlzIGFybWVkLCBhbmQgZXZlcnkgZWFybGllclxuICogZGVsaXZlcnkgaXQgYWN0dWFsbHkgZ2F0ZXMgb24gKHtAbGluayBnYXRlc09ufSkgd2lsbCBsaWtld2lzZSByZXNvbHZlIG9uIGl0c1xuICogb3duLlxuICpcbiAqIEEgc3RlcCBkb2VzIG5vdCBnYXRlIG9uIGFuIHVuY2xhaW1lZCBidWZmZXJlZCBwYXlsb2FkLCBzbyBzdWNoIGEgcGF5bG9hZFxuICogY2Fubm90IGtlZXAgaXQgZnJvbSByZXNvbHZpbmcuIEEgc3RlcCBET0VTIGdhdGUgb24gZWFybGllciBhcm1lZCB3YWl0cyBhbmRcbiAqIGhvb2tzLCBzbyBvbmUgcGFya2VkIGJlaGluZCBhbiB1bmNsYWltZWQgcGF5bG9hZCBtYWtlcyB0aGUgc3RlcFxuICogbm9uLXNlbGYtcmVzb2x2aW5nIGluIHR1cm4uIERpc2FncmVlaW5nIHdpdGgge0BsaW5rIGF3YWl0RWFybGllckRlbGl2ZXJpZXN9XG4gKiBoZXJlIHdvdWxkIG5vdCBiZSBhIGNvc21ldGljIHByb2JsZW06IHRoaXMgcHJlZGljYXRlIGlzIHdoYXRcbiAqIHtAbGluayBoYXNQYXJrZWRDb21taXR0ZWREZWxpdmVyeX0gdXNlcyB0byBkZWNpZGUgd2hldGhlciBpZGxlIGlzIHJlYWNoYWJsZSxcbiAqIGFuZCBhbiBlbnRyeSByZXBvcnRlZCBzZWxmLXJlc29sdmluZyB3aGlsZSBpdCBpcyBpbiBmYWN0IHBhcmtlZCBiZWhpbmQgYVxuICogcGF5bG9hZCB0aGF0IG9ubHkgdGhlIGlkbGUgc2FmZXR5IG5ldCBjYW4gcmV0aXJlIHdvdWxkIGdhdGUgaXRzIG93blxuICogcmV0aXJlbWVudC5cbiAqXG4gKiBSZWN1cnNpb24gdGVybWluYXRlcyBiZWNhdXNlIGV2ZXJ5IGVkZ2UgcG9pbnRzIHRvIGEgc3RyaWN0bHkgc21hbGxlciBpbmRleC5cbiAqIGBtZW1vYCBrZWVwcyB0aGUgd2FsayBsaW5lYXIgaW4gcmVnaXN0cnkgc2l6ZSwgYW5kIHRoZSByZWdpc3RyeSBpcyBub3Qgc21hbGxcbiAqIGJ5IGNvbnN0cnVjdGlvbjogYEV2ZW50c0NvbnN1bWVyYCBkcmFpbnMgY29uc2VjdXRpdmVseSBjb25zdW1hYmxlIGV2ZW50c1xuICogc3luY2hyb25vdXNseSB3aGlsZSBiYXJyaWVycyBvbmx5IHJldGlyZSBvbiBtaWNyb3Rhc2stZHJpdmVuIGRlbGl2ZXJpZXMsIHNvXG4gKiBhIGZhbi1vdXQgb2YgYFByb21pc2UucmFjZShbaG9vaywgc2xlZXBdKWAgYnJhbmNoZXMgYWNjdW11bGF0ZXMgb25lIGJhcnJpZXJcbiAqIHBlciBicmFuY2ggcGVyIGtpbmQuIFRoZSBtZW1vIE1VU1QgYmUgcGVyLWNhbGw6IGBhcm1lZGAgbXV0YXRlcyBiZXR3ZWVuXG4gKiBjYWxscyBhcyBidWZmZXJlZCBwYXlsb2FkcyBhcmUgY2xhaW1lZC5cbiAqXG4gKiBUaGUgbWVtbyBpcyBhbiBvcHRpbWl6YXRpb24sIG5vdCBhIGNvcnJlY3RuZXNzIHJlcXVpcmVtZW50LiBJdCBvbmNlIHdhcyBvbmU6XG4gKiBgYXdhaXRFYXJsaWVyRGVsaXZlcmllc2AgdXNlZCB0byBydW4gdGhpcyB3YWxrIGZvciBldmVyeSBlYXJsaWVyIGVudHJ5IG9mIGFcbiAqIHN0ZXAgZGVsaXZlcnksIHdpdGggbm8gZWFybHkgZXhpdCwgd2hpY2ggdW5tZW1vaXplZCBpcyBUKG4pID0gzqMgVChqKSxcbiAqIG1lYXN1cmVkIGF0IDQuM2U4IHJlY3Vyc2l2ZSBjYWxscyAoODRzKSBmb3IgNDAgYWx0ZXJuYXRpbmcgYXJtZWQgaG9vay93YWl0XG4gKiBiYXJyaWVycy4gVGhhdCBjYWxsIHNpdGUgaXMgZ29uZTsgYSBzdGVwIG5vdyB0ZXN0cyBgYXJtZWRgIGRpcmVjdGx5LiBUaGUgb25lXG4gKiBzdXJ2aXZpbmcgY2FsbGVyLCB7QGxpbmsgaGFzUGFya2VkQ29tbWl0dGVkRGVsaXZlcnl9LCBjYW5ub3QgcmVhY2ggdGhhdFxuICogc2hhcGU6IGl0IHJldHVybnMgYXQgdGhlIEZJUlNUIHNlbGYtcmVzb2x2aW5nIGVudHJ5LCBzbyBpdCBvbmx5IGV2ZXJcbiAqIGFkdmFuY2VzIHBhc3QgZW50cmllcyB0aGF0IGFyZSBub24tc2VsZi1yZXNvbHZpbmcsIGFuZCB0aG9zZSBzaG9ydC1jaXJjdWl0XG4gKiBvbiB0aGVpciBmaXJzdCBmYWxzZSBjaGlsZC4gRXZlcnkgZW50cnkgaXQgZXZhbHVhdGVzIHRoZXJlZm9yZSBoYXNcbiAqIGFsbC1mYWxzZSBwcmVkZWNlc3NvcnMgYW5kIHJldHVybnMgYWZ0ZXIgb25lIGNoaWxkLCBkZWdlbmVyYXRpbmcgdGhlIHdhbGsgdG9cbiAqIGEgY2hhaW4gKG1lYXN1cmVkOiA5OCBjYWxscyB1bm1lbW9pemVkIGZvciB0aGUgd29yc3QgNDAtYmFycmllciBzaGFwZSwgMVxuICogY2FsbCBmb3IgdGhlIHJlZ2lzdHJ5IGFib3ZlKS4gRG8gbm90IHJlc3RvcmUgYW4gZXhwb25lbnRpYWwgY2xhaW0gaGVyZVxuICogd2l0aG91dCByZXN0b3JpbmcgYSBjYWxsZXIgdGhhdCBjYW4gcHJvZHVjZSBpdC5cbiAqL1xuZnVuY3Rpb24gcmVzb2x2ZXNPbkl0c093bihcbiAgYmFycmllcnM6IE1hcDxudW1iZXIsIERlbGl2ZXJ5QmFycmllckVudHJ5PixcbiAgaW5kZXg6IG51bWJlcixcbiAgZW50cnk6IERlbGl2ZXJ5QmFycmllckVudHJ5LFxuICBtZW1vOiBNYXA8bnVtYmVyLCBib29sZWFuPlxuKTogYm9vbGVhbiB7XG4gIGNvbnN0IGNhY2hlZCA9IG1lbW8uZ2V0KGluZGV4KTtcbiAgaWYgKGNhY2hlZCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIGNhY2hlZDtcbiAgfVxuICBjb25zdCByZXN1bHQgPSBjb21wdXRlUmVzb2x2ZXNPbkl0c093bihiYXJyaWVycywgaW5kZXgsIGVudHJ5LCBtZW1vKTtcbiAgbWVtby5zZXQoaW5kZXgsIHJlc3VsdCk7XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbmZ1bmN0aW9uIGNvbXB1dGVSZXNvbHZlc09uSXRzT3duKFxuICBiYXJyaWVyczogTWFwPG51bWJlciwgRGVsaXZlcnlCYXJyaWVyRW50cnk+LFxuICBpbmRleDogbnVtYmVyLFxuICBlbnRyeTogRGVsaXZlcnlCYXJyaWVyRW50cnksXG4gIG1lbW86IE1hcDxudW1iZXIsIGJvb2xlYW4+XG4pOiBib29sZWFuIHtcbiAgaWYgKCFlbnRyeS5hcm1lZCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBmb3IgKGNvbnN0IFtvdGhlckluZGV4LCBvdGhlcl0gb2YgYmFycmllcnMpIHtcbiAgICBpZiAoIWdhdGVzT24oZW50cnkua2luZCwgaW5kZXgsIG90aGVySW5kZXgsIG90aGVyKSkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGlmICghcmVzb2x2ZXNPbkl0c093bihiYXJyaWVycywgb3RoZXJJbmRleCwgb3RoZXIsIG1lbW8pKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG4gIHJldHVybiB0cnVlO1xufVxuXG4vKipcbiAqIEF3YWl0cywgaW4gc3RyaWN0IGV2ZW50LWxvZyBvcmRlciwgZXZlcnkgc3RpbGwtcmVnaXN0ZXJlZCBkZWxpdmVyeSB0aGF0IGlzXG4gKiBlYXJsaWVyIGluIHRoZSBsb2cgdGhhbiBgZXZlbnRJbmRleGAgYW5kIHRoYXQgYSBkZWxpdmVyeSBvZiBga2luZGAgZGVmZXJzXG4gKiBiZWhpbmQgKHNlZSB7QGxpbmsgREVGRVJfQkVISU5EfSksIHNvIHRoYXQgdGhpcyByZXNvbHV0aW9uIGlzIGhhbmRlZCB0byB0aGVcbiAqIHdvcmtmbG93IG9ubHkgYWZ0ZXIgYWxsIHJlbGV2YW50IGVhcmxpZXItaW4tbG9nIGRlbGl2ZXJpZXMgaGF2ZSBiZWVuLiBUaGlzXG4gKiBpcyB3aGF0IGtlZXBzIGEgYFByb21pc2UucmFjZWAgKG9yIHRoZSBVTElEIGEgZm9sbG93LXVwIGB1c2VTdGVwYCBkcmF3cyBvblxuICogYSBjb25jdXJyZW50IGJyYW5jaCkgZGV0ZXJtaW5pc3RpYyBhbmQgYWxpZ25lZCB3aXRoIHRoZSBjb21taXR0ZWQgZXZlbnRcbiAqIGxvZywgaW5kZXBlbmRlbnQgb2YgbWljcm90YXNrLWhvcCBjb3VudHMsIGh5ZHJhdGlvbiB0aW1lLCBvciByYWNlLWFyZ3VtZW50XG4gKiBvcmRlci4gV2hlbiB0aGlzIGRlbGl2ZXJ5IGRvZXMgaGF2ZSB0byB3YWl0LCBpdCBhbHNvIHlpZWxkcyBhIG1hY3JvdGFza1xuICogYWZ0ZXJ3YXJkcyBzbyB0aGUgZWFybGllciBkZWxpdmVyeSdzIGNvbnN1bWVyIGNhbiBydW4gdG8gaXRzIG93biBuZXh0XG4gKiBzdXNwZW5zaW9uIHBvaW50IGZpcnN0OyBzZWUgdGhlIGNvbW1lbnQgYXQgdGhhdCBgYXdhaXRgIGZvciB3aHkgb3JkZXJpbmcgdGhlXG4gKiBgcmVzb2x2ZSgpYCBjYWxscyBhbG9uZSBpcyBub3QgZW5vdWdoLlxuICpcbiAqIFdoYXQgY291bnRzIGFzIFwiZGVmZXJzIGJlaGluZFwiIGlzIHtAbGluayBnYXRlc09ufSwgc2hhcmVkIHdpdGhcbiAqIHtAbGluayBjb21wdXRlUmVzb2x2ZXNPbkl0c093bn0gc28gdGhlIHR3byBjYW5ub3QgZHJpZnQuXG4gKlxuICogT25lIGFzeW1tZXRyeTogYSBTVEVQIHJlc3VsdCBza2lwcyBhbnkgZWFybGllciBkZWxpdmVyeSB0aGF0IGlzIFVOQVJNRUQsXG4gKiBpLmUuIGEgYnVmZmVyZWQgaG9vayBwYXlsb2FkIG5vIGNvbnN1bWVyIGhhcyBjbGFpbWVkLiBTdWNoIGEgcGF5bG9hZCBpc1xuICogZGVsaXZlcmVkIG9ubHkgd2hlbiB0aGUgd29ya2Zsb3cgbmV4dCByZWFkcyB0aGUgaG9vaywgYW5kIHJlYWNoaW5nIHRoYXQgcmVhZFxuICogb2Z0ZW4gcmVxdWlyZXMgdGhlIHN0ZXAgcmVzdWx0IGl0c2VsZiAoYGF3YWl0IHN0ZXBYKClgIGJlZm9yZSB0aGVcbiAqIHJlYWQpLiBHYXRpbmcgdGhlIHN0ZXAgb24gaXQgd291bGQgc3RhbGwgdGhlIHdvcmtmbG93IHVudGlsIHRoZSBiYXJyaWVyJ3NcbiAqIGlkbGUgc2FmZXR5IG5ldCBmaXJlcywgd2hpY2ggdGhlbiByZWxlYXNlcyBldmVyeSBkZWxpdmVyeSBxdWV1ZWQgYmVoaW5kIHRoYXRcbiAqIHBheWxvYWQgYXQgb25jZSwgbG9zaW5nIGV4YWN0bHkgdGhlIHJhY2UgdGhpcyBvcmRlcmluZyBleGlzdHMgdG8gcHJvdGVjdC5cbiAqIFdhaXRzIGFuZCBob29rcyBrZWVwIGdhdGluZyBvbiB1bmNsYWltZWQgcGF5bG9hZHM6IGZvciB0aGVtLCB3YWl0aW5nIGZvciB0aGVcbiAqIGNsYWltIElTIHRoZSBvcmRlcmluZyBndWFyYW50ZWUgKGEgYHdhaXRfY29tcGxldGVkYCBtdXN0IG5vdCBwcmVlbXB0IGFcbiAqIHBheWxvYWQgdGhlIGxvZyBvcmRlcmVkIGZpcnN0KS5cbiAqXG4gKiBUaGUgc2tpcCBpcyBkaXJlY3QsIG5ldmVyIHRyYW5zaXRpdmUuIEEgc3RlcCBzdGlsbCBnYXRlcyBvbiBhbiBlYXJsaWVyIEFSTUVEXG4gKiB3YWl0IG9yIGhvb2ssIGluY2x1ZGluZyBvbmUgdGhhdCBpcyBpdHNlbGYgcGFya2VkIGJlaGluZCBhbiB1bmNsYWltZWRcbiAqIHBheWxvYWQuIFNraXBwaW5nIHRob3NlIHRvbyB3b3VsZCBpbnZlcnQgbG9nIG9yZGVyIGZvciB0aGUgY29tbW9uZXN0IHNoYXBlXG4gKiB0aGVyZSBpczogYSB3b3JrZmxvdyB0aGF0IGNyZWF0ZXMgYSBob29rIGl0IGRvZXMgbm90IHJlYWQgb24gdGhpcyBicmFuY2gsXG4gKiByYWNlcyBgc3RlcGAgYWdhaW5zdCBgc2xlZXBgLCBhbmQgaGFzIHRoZSBsb2cgc2F5IHRoZSBzbGVlcCB3b24uIFRoZSBzdGVwXG4gKiB3b3VsZCB0aGVuIG92ZXJ0YWtlIHRoZSB3YWl0LCBib3RoIGJyYW5jaGVzIHdvdWxkIHN3YXAgdGhlIGNvcnJlbGF0aW9uIGlkc1xuICogdGhleSBkcmF3IG5leHQsIGFuZCByZXBsYXkgd291bGQgZGl2ZXJnZS4gU2VlXG4gKiBgc3RlcC1kZWxpdmVyeS1vcmRlcmluZy50ZXN0LnRzYC4gV2FpdGluZyBpbnN0ZWFkIGlzIHNhZmUgYmVjYXVzZSB0aGVcbiAqIHBheWxvYWQncyBvd24gaWRsZSBzYWZldHkgbmV0IHJldGlyZXMgaXQgYW5kIHRoZSB3aG9sZSBjaGFpbiB0aGVuIGRlbGl2ZXJzXG4gKiBpbiBsb2cgb3JkZXI7IHtAbGluayBoYXNQYXJrZWRDb21taXR0ZWREZWxpdmVyeX0gZGVsaWJlcmF0ZWx5IHJlcG9ydHMgc3VjaCBhXG4gKiBzdGVwIGFzIG5vdCBzZWxmLXJlc29sdmluZyBzbyB0aGF0IGlkbGUgc3RheXMgcmVhY2hhYmxlLlxuICpcbiAqIFwiVGhlIHdob2xlIGNoYWluIHRoZW4gZGVsaXZlcnMgaW4gbG9nIG9yZGVyXCIgcmVzdHMgb24gdGhlIFBBWUxPQUQncyBiYXJyaWVyXG4gKiBiZWluZyByZXRpcmVkIGJlZm9yZSB0aGF0IG9mIGFueXRoaW5nIHBhcmtlZCBiZWhpbmQgaXQuIFRoYXQgb3JkZXIgaXNcbiAqIHN0cnVjdHVyYWw6IHNhZmV0eS1uZXQgcmV0aXJlbWVudHMgZ28gdGhyb3VnaCBvbmUgcGVyLWNvbnRleHQgZGlzcGVuc2VyIHRoYXRcbiAqIG9ubHkgZXZlciByZXRpcmVzIHRoZSBsb3dlc3QtaW5kZXggZW50cnkgYXQgZGVsaXZlcnkgaWRsZSwgYW5kIGV2ZXJ5XG4gKiByZXRpcmVtZW50IHRoYXQgd2FrZXMgYSBjaGFpbiBmbGlwcyB7QGxpbmsgaGFzUGFya2VkQ29tbWl0dGVkRGVsaXZlcnl9IGJhY2tcbiAqIHRvIHRydWUsIHJlLWJsb2NraW5nIHRoZSBkaXNwZW5zZXIgdW50aWwgdGhlIGNoYWluIGhhcyBkcmFpbmVkLiBTZWVcbiAqIHtAbGluayBlbnN1cmVCYXJyaWVyU2FmZXR5TmV0fS4gKFRoaXMgdXNlZCB0byByZXN0IG9uIHRoZSBGSUZPIG9mIG9uZSBpZGxlXG4gKiBwb2xsIHBlciBiYXJyaWVyLCB3aGljaCBoZWxkIGZvciBhIHNpbmdsZSBwYXJrZWQgc2VnbWVudCBidXQgZGVjYXllZCB0b1xuICogdGltaW5nIG5vaXNlIHdpdGggc2V2ZXJhbDogdGhlIHJlbGVhc2Ugb3JkZXIsIGFuZCB0aGVyZWZvcmUgdGhlIFVMSURzXG4gKiBkcmF3biBieSB0aGUgd29rZW4gYnJhbmNoZXMsIHRoZW4gZGVwZW5kZWQgb24gaG93IG11Y2ggbG9nIHRoZSByZXBsYXkgaGFkXG4gKiBsb2FkZWQuIHN0b3JtLWxvZy1yZXBsYXkudGVzdC50cyByZXBsYXlzIGEgcHJvZHVjdGlvbiBsb2cgY29ycnVwdGVkIGV4YWN0bHlcbiAqIHRoYXQgd2F5LilcbiAqL1xuLyoqXG4gKiBXaGV0aGVyIGNvcnJlbGF0aW9uLWlkIGRyYXcgb3JkZXIgaXMgcGlubmVkIHRvIGV2ZW50LWxvZyBvcmRlci4gRGVmYXVsdCBPTjpcbiAqIG9ubHkgdGhlIGxpdGVyYWwgc3RyaW5nIGBXT1JLRkxPV19MT0dfT1JERVJfRFJBV1M9MGAgb3B0cyBvdXQuIGA9ZmFsc2VgLFxuICogYD1vZmZgLCBhbmQgZXZlcnkgb3RoZXIgdmFsdWUga2VlcCBpdCBlbmFibGVkLiBSZWFkIHBlciBjYWxsIHNvIHRlc3RzIGNhblxuICogZmxpcCBpdC5cbiAqXG4gKiBPZmYsIGEgZGVsaXZlcnkgdGhhdCBoYWQgdG8gZGVmZXIgeWllbGRzIE9ORSBtYWNyb3Rhc2sgYWZ0ZXIgaXRzXG4gKiBwcmVkZWNlc3NvcnMgcmVzb2x2ZS4gVGhpcyBpcyBlbm91Z2ggZm9yIHNob3J0IGNvbnN1bWVycywgYnV0IGEgd29rZW4gYnJhbmNoXG4gKiB3aG9zZSBwYXRoIHRvIGl0cyBuZXh0IGRyYXcgY3Jvc3NlcyBtb3JlIGhvcHMgKGEgYFByb21pc2UucmFjZWAgcmVzb2x1dGlvbiwgYVxuICogdXNlci1sZXZlbCBzZW1hcGhvcmUsIGFuIGFzeW5jLWl0ZXJhdG9yIHJlYWQpIGNhbiBzdGlsbCBiZSBvdmVydGFrZW4gYnkgYVxuICogbGF0ZXItaW4tbG9nIGRlbGl2ZXJ5J3Mgc2hvcnRlciBjYXNjYWRlLCBzbyB0aGUgcnVuJ3MgZHJhdyBvcmRlciwgaW5jbHVkaW5nXG4gKiBpdHMgY29ycmVsYXRpb24gaWRzLCBkZXBlbmRzIG9uIGhvdyBtdWNoIGxvZyB0aGlzIHJlcGxheSBsb2FkZWQuXG4gKiBPbiwgdGhlIHlpZWxkIGJlY29tZXMgYSBmaXhwb2ludDogdGhlIGRlbGl2ZXJ5IHJlc29sdmVzIG9ubHkgb25jZSBldmVyeVxuICogZWFybGllciBjYXNjYWRlIGhhcyBxdWllc2NlZCwgbWFraW5nIHRoZSBkcmF3IHNlcXVlbmNlIGEgcHVyZSBmdW5jdGlvbiBvZlxuICogdGhlIGRlbnNlIGxvZywgc3RhYmxlIHVuZGVyIHByZWZpeCBleHRlbnNpb24sIGFuZCBjb25jdXJyZW50IHdyaXRlcnMnXG4gKiBkdXBsaWNhdGUgY3JlYXRlcyBpZGVudGljYWwgKGRlZHVwZWQpIGluc3RlYWQgb2YgY29sbGlkaW5nLlxuICovXG5mdW5jdGlvbiBpc0xvZ09yZGVyRHJhd3NFbmFibGVkKCk6IGJvb2xlYW4ge1xuICByZXR1cm4gcHJvY2Vzcy5lbnYuV09SS0ZMT1dfTE9HX09SREVSX0RSQVdTICE9PSAnMCc7XG59XG5cbi8qKlxuICogT25lIHF1aWVzY2VuY2UgdHVybjogbGV0cyB0aGUgZW50aXJlIHBlbmRpbmcgbWljcm90YXNrIHF1ZXVlIGRyYWluLCB0aGVuXG4gKiB5aWVsZHMgdG8gdGhlIGV2ZW50IGxvb3Agb25jZS4gYHNldEltbWVkaWF0ZWAgKGNoZWNrIHBoYXNlKSBpcyB1c2VkIHdoZXJlXG4gKiBhdmFpbGFibGUgYmVjYXVzZSBOb2RlIGNsYW1wcyBgc2V0VGltZW91dCgwKWAgdG8gfjFtcyB3aGlsZSBgc2V0SW1tZWRpYXRlYFxuICogY29zdHMgfjIwwrVzLiBFdmVyeSBicmFuY2gtZGVjaWRpbmcgZGVsaXZlcnkgcGF5cyB0aGlzIHR1cm4gYXQgbGVhc3RcbiAqIG9uY2UsIHNvIG9uIGEgc2VxdWVudGlhbCByZXBsYXkgdGhlIGNsYW1wIGlzIHRoZSB3aG9sZSBjb3N0LiBUaW1lcnMgc3RpbGxcbiAqIHJ1biBiZXR3ZWVuIGNvbnNlY3V0aXZlIHR1cm5zICh0aGUgbG9vcCByZS1lbnRlcnMgdGhlIGV2ZW50IGxvb3AgZWFjaFxuICogaXRlcmF0aW9uLCBwYXNzaW5nIHRocm91Z2ggdGhlIHRpbWVycyBwaGFzZSksIHNvIGNoYWlucyBwYXJrZWQgb24gdGhlXG4gKiBzYWZldHktbmV0IGRpc3BlbnNlcidzIGBzZXRUaW1lb3V0YCBjYWRlbmNlIGFyZSBub3Qgc3RhcnZlZC5cbiAqL1xuZnVuY3Rpb24gcXVpZXNjZW5jZVR1cm4oZGVsYXlNczogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiB7XG4gIGlmIChkZWxheU1zID09PSAwICYmIHR5cGVvZiBzZXRJbW1lZGlhdGUgPT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gbmV3IFByb21pc2U8dm9pZD4oKHJlc29sdmUpID0+IHNldEltbWVkaWF0ZShyZXNvbHZlKSk7XG4gIH1cbiAgcmV0dXJuIG5ldyBQcm9taXNlPHZvaWQ+KChyZXNvbHZlKSA9PiBzZXRUaW1lb3V0KHJlc29sdmUsIGRlbGF5TXMpKTtcbn1cblxuLyoqXG4gKiBXYWl0cyB1bnRpbCB0aGUgd29ya2Zsb3cgY2FuIG1ha2Ugbm8gZnVydGhlciBwcm9ncmVzcyB3aXRob3V0IGFub3RoZXJcbiAqIGRlbGl2ZXJ5OiByZXBlYXRlZCAocHJvbWlzZS1xdWV1ZSBkcmFpbiArIGV2ZW50LWxvb3AgdHVybilzIHVudGlsIGEgZnVsbFxuICogdHVybiBwYXNzZXMgd2l0aCBubyBuZXcgVUxJRCBkcmF3cyBhbmQgbm8gaHlkcmF0aW9uIGluIGZsaWdodC5cbiAqXG4gKiBUZXJtaW5hdGlvbjogZWFjaCBleHRyYSBpdGVyYXRpb24gcmVxdWlyZXMgYSBuZXcgVUxJRCBkcmF3IG9yIGEgaHlkcmF0aW9uXG4gKiBzdGFydGVkIGluIHRoZSBwcmV2aW91cyB0dXJuLiBgbWludENvdW50YCBjb3VudHMgRVZFUlkgZHJhdyBmcm9tIHRoZSBydW4nc1xuICogc2VxdWVuY2UsIGluY2x1ZGluZyBjb3JyZWxhdGlvbiBpZHMgYW5kIHNlcmlhbGl6YXRpb24tZHJpdmVuIGRyYXdzIChzdHJlYW1cbiAqIGlkcyBtaW50ZWQgdGhyb3VnaCB0aGUgYFNUQUJMRV9VTElEYCBnbG9iYWwgd2hpbGUgZGVoeWRyYXRpbmcpLiBUaGlzIGlzXG4gKiBjb25zZXJ2YXRpdmUgaW4gdGhlIHNhZmUgZGlyZWN0aW9uOiBzZXJpYWxpemF0aW9uIGRyYXdzIG9ubHkgZXh0ZW5kIHRoZVxuICogd2FpdCwgYW5kIGJvdGggYm9keSBwcm9ncmVzcyBhbmQgdGhlIHNlcmlhbGl6YXRpb24gd29yayBvbmUgY2FzY2FkZSBjYW5cbiAqIHNjaGVkdWxlIGFyZSBmaW5pdGUgYmV0d2VlbiBkZWxpdmVyaWVzLCBzbyB0aGUgZml4cG9pbnQgaXMgcmVhY2hlZC4gVGhlXG4gKiBsb29wIGhvbGRzIHRoaXMgZGVsaXZlcnkncyBvd24gYmFycmllciByZWdpc3RlcmVkIChpdHMgYG1hcmtEZWxpdmVyZWRgIGhhc1xuICogbm90IHJ1biksIHNvIGBpc0RlbGl2ZXJ5SWRsZWAgc3RheXMgZmFsc2UgYW5kIG5vIHN1c3BlbnNpb24gY2FuIHByZWVtcHQgdGhlXG4gKiBjYXNjYWRlIGJlaW5nIHdhaXRlZCBvdXQuXG4gKlxuICogQSByZWplY3RlZCBgcHJvbWlzZVF1ZXVlYCBzZXR0bGVzIGltbWVkaWF0ZWx5IGFuZCBmb3JldmVyLCBzbyBsb29waW5nIGF0XG4gKiB0aGUgbm9ybWFsIGNhZGVuY2Ugb24gYSBmYWlsZWQgcnVuIHdvdWxkIGRlZ2VuZXJhdGUgaW50byBhIGJ1c3kgbG9vcCAodGhlXG4gKiBzYW1lIGhhemFyZCB7QGxpbmsgZW5zdXJlQmFycmllclNhZmV0eU5ldH0gZG9jdW1lbnRzKS4gSXRlcmF0aW9ucyB0aGF0XG4gKiBvYnNlcnZlIHRoZSBxdWV1ZSByZWplY3RlZCBiYWNrIG9mZiB0byBhIDUwbXMgdGljayBpbnN0ZWFkLlxuICovXG5hc3luYyBmdW5jdGlvbiBxdWllc2NlRWFybGllckNhc2NhZGVzKFxuICBjdHg6IFdvcmtmbG93T3JjaGVzdHJhdG9yQ29udGV4dCxcbiAgZXZlbnRJbmRleDogbnVtYmVyXG4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgZm9yICg7Oykge1xuICAgIGNvbnN0IG1pbnRzQmVmb3JlID0gY3R4Lm1pbnRDb3VudCA/PyAwO1xuICAgIGNvbnN0IHBlbmRpbmdCZWZvcmUgPSBjdHgucGVuZGluZ0RlbGl2ZXJpZXM7XG4gICAgLy8gU2V0dGxlZCBvciByZWplY3RlZCwgdGhlIHF1ZXVlIHNuYXBzaG90IG9ubHkgb3JkZXJzIHVzIGJlaGluZCB3b3JrXG4gICAgLy8gYWxyZWFkeSBjaGFpbmVkOyBhIHJlamVjdGlvbiBpcyB0aGUgcnVuIGZhaWxpbmcgZWxzZXdoZXJlLlxuICAgIGNvbnN0IHF1ZXVlUmVqZWN0ZWQgPSBhd2FpdCBjdHgucHJvbWlzZVF1ZXVlLnRoZW4oXG4gICAgICAoKSA9PiBmYWxzZSxcbiAgICAgICgpID0+IHRydWVcbiAgICApO1xuICAgIGF3YWl0IHF1aWVzY2VuY2VUdXJuKHF1ZXVlUmVqZWN0ZWQgPyA1MCA6IDApO1xuICAgIGlmIChcbiAgICAgIChjdHgubWludENvdW50ID8/IDApICE9PSBtaW50c0JlZm9yZSB8fFxuICAgICAgcGVuZGluZ0JlZm9yZSAhPT0gMCB8fFxuICAgICAgY3R4LnBlbmRpbmdEZWxpdmVyaWVzICE9PSAwXG4gICAgKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgLy8gUXVpZXQgaXMgbm90IGVub3VnaCBvbiBpdHMgb3duOiBzZXZlcmFsIGRlbGl2ZXJ5IGNoYWlucyBjYW4gYmUgc2l0dGluZ1xuICAgIC8vIGluIHRoaXMgbG9vcCBhdCBvbmNlLCBhbmQgbGV0dGluZyB0aGUgZmlyc3QgcXVpZXQgb2JzZXJ2YXRpb24gcmVzb2x2ZVxuICAgIC8vIHdvdWxkIGJyZWFrIHRoZSB0aWUgYnkgdGltZXIgYXJyaXZhbC4gVGhpcyBtb2RlIHJlbW92ZXMgdGhhdCBhcnJpdmFsLW9yZGVyXG4gICAgLy8gZGVwZW5kZW5jZS4gQSBsb3dlci1pbmRleCBBUk1FRCBiYXJyaWVyIGlzIGEgZGVsaXZlcnkgY29tbWl0dGVkIHRvXG4gICAgLy8gaGFwcGVuaW5nIHRoYXQgaGFzIG5vdCBoYXBwZW5lZCB5ZXQsIHNvIHRoaXMgb25lIGtlZXBzIHdhaXRpbmcuIFVuYXJtZWRcbiAgICAvLyBlbnRyaWVzIChidWZmZXJlZCBwYXlsb2FkcyBub2JvZHkgaGFzIGNsYWltZWQpIGRvIG5vdCBibG9jaywgZXhhY3RseSBhc1xuICAgIC8vIGluIGBnYXRlc09uYDogdGhlaXIgaGFuZG92ZXIgaXMgY2xhaW0tZHJpdmVuLCB3aGljaCBpcyBib2R5LXBvc2l0aW9uXG4gICAgLy8gZGV0ZXJtaW5lZCBhbmQgdGhlcmVmb3JlIGFscmVhZHkgYSBmdW5jdGlvbiBvZiB0aGUgcHJlZml4LlxuICAgIC8vXG4gICAgLy8gVGhpcyBpcyBkZWxpYmVyYXRlbHkgYSBXSURFUiB3YWl0cy1mb3IgcmVsYXRpb24gdGhhbiBgZ2F0ZXNPbmAgKHdoaWNoLFxuICAgIC8vIGUuZy4sIGV4Y2x1ZGVzIHdhaXTihpJ3YWl0KTogdW5kZXIgbG9nLW9yZGVyIGRyYXdzIEVWRVJZIGJyYW5jaC1kZWNpZGluZ1xuICAgIC8vIGRlbGl2ZXJ5IG11c3QgcmVzb2x2ZSBpbiBsb2cgb3JkZXIsIGtpbmRzIGluY2x1ZGVkLiBUaGUgd2lkdGggaXMgc2FmZVxuICAgIC8vIGFnYWluc3QgdGhlIGRpc3BlbnNlciBkZWFkbG9jayB0aGF0IGByZXNvbHZlc09uSXRzT3duYCBndWFyZHMsIGJlY2F1c2VcbiAgICAvLyB0aGUgb25lIGVkZ2UgdGhlIHdpZGVyIHJlbGF0aW9uIGFkZHMgKHdhaXRpbmcgb24gYW4gYXJtZWQgZW50cnkgdGhhdFxuICAgIC8vIGdhdGVzT24gZG9lcyBub3QgbW9kZWwpIGFsd2F5cyBib3R0b21zIG91dCBhdCB0aGUgc2FtZSB1bmFybWVkIHBheWxvYWQ6XG4gICAgLy8gYSBsb3dlciBhcm1lZCBXQUlUIGlzIG5vbi1zZWxmLXJlc29sdmluZyBvbmx5IHdoZW4gaXQgaXMgKHRyYW5zaXRpdmVseSlcbiAgICAvLyBwYXJrZWQgYmVoaW5kIGFuIHVuY2xhaW1lZCBidWZmZXJlZCBwYXlsb2FkLCBhbmQgYSB3YWl0IGdhdGVzIG9uIGV2ZXJ5XG4gICAgLy8gbG93ZXIgaG9vayBhbmQgc3RlcCBkaXJlY3RseSwgc28gdGhlIHNwaW5uZXIgaGVyZSBhbHNvIGdhdGVzIG9uIHRoYXRcbiAgICAvLyBwYXlsb2FkIHRocm91Z2ggYGdhdGVzT25gIGFuZCBpcyBpdHNlbGYgcmVwb3J0ZWQgbm9uLXNlbGYtcmVzb2x2aW5nLlxuICAgIC8vIFRoZSBkaXNwZW5zZXIgdGhlcmVmb3JlIHN0YXlzIHVuYmxvY2tlZCBhbmQgcmV0aXJlcyB0aGUgY2hhaW4gaGVhZDsgc2VlXG4gICAgLy8gdGhlIHBhcmtlZC1jaGFpbiB0ZXN0IGluIGRlbGl2ZXJ5LWJhcnJpZXItY292ZXJhZ2UudGVzdC50cy5cbiAgICBsZXQgbG93ZXJBcm1lZCA9IGZhbHNlO1xuICAgIGZvciAoY29uc3QgW2luZGV4LCBlbnRyeV0gb2YgY3R4LnBlbmRpbmdEZWxpdmVyeUJhcnJpZXJzID8/IFtdKSB7XG4gICAgICBpZiAoaW5kZXggPCBldmVudEluZGV4ICYmIGVudHJ5LmFybWVkKSB7XG4gICAgICAgIGxvd2VyQXJtZWQgPSB0cnVlO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKCFsb3dlckFybWVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBhd2FpdEVhcmxpZXJEZWxpdmVyaWVzKFxuICBjdHg6IFdvcmtmbG93T3JjaGVzdHJhdG9yQ29udGV4dCxcbiAgZXZlbnRJbmRleDogbnVtYmVyIHwgdW5kZWZpbmVkLFxuICBraW5kOiBEZWxpdmVyeUtpbmRcbik6IFByb21pc2U8dm9pZD4ge1xuICAvLyBEZWZlbnNpdmU6IHRvbGVyYXRlIGNvbnRleHRzIHRoYXQgcHJlZGF0ZSB0aGlzIGZpZWxkICh0ZXN0IGhhcm5lc3NlcykuXG4gIGlmIChldmVudEluZGV4ID09PSB1bmRlZmluZWQgfHwgIWN0eC5wZW5kaW5nRGVsaXZlcnlCYXJyaWVycykge1xuICAgIHJldHVybjtcbiAgfVxuICBjb25zdCBiYXJyaWVycyA9IGN0eC5wZW5kaW5nRGVsaXZlcnlCYXJyaWVycztcbiAgY29uc3QgZWFybGllcjogUHJvbWlzZTx2b2lkPltdID0gW107XG4gIGZvciAoY29uc3QgW2luZGV4LCBlbnRyeV0gb2YgYmFycmllcnMpIHtcbiAgICBpZiAoIWdhdGVzT24oa2luZCwgZXZlbnRJbmRleCwgaW5kZXgsIGVudHJ5KSkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGVhcmxpZXIucHVzaChlbnRyeS5kZWxpdmVyZWQpO1xuICB9XG4gIGlmIChlYXJsaWVyLmxlbmd0aCA+IDApIHtcbiAgICBhd2FpdCBQcm9taXNlLmFsbChlYXJsaWVyKTtcbiAgfVxuICBpZiAoaXNMb2dPcmRlckRyYXdzRW5hYmxlZCgpKSB7XG4gICAgLy8gVW5jb25kaXRpb25hbCwgbm90IGp1c3Qgd2hlbiBhIGJhcnJpZXIgd2FzIHN0aWxsIHJlZ2lzdGVyZWQ6IGFuIGVhcmxpZXJcbiAgICAvLyBkZWxpdmVyeSdzIGJhcnJpZXIgZGVyZWdpc3RlcnMgd2hlbiBpdHMgcmVzb2x2ZSgpIHJ1bnMsIGJ1dCB0aGUgYnJhbmNoXG4gICAgLy8gaXQgd29rZSBtYXkgc3RpbGwgYmUgaG9wcyBhd2F5IGZyb20gaXRzIG5leHQgZHJhdy4gQSBsYXRlciBkZWxpdmVyeVxuICAgIC8vIGNvbnN1bWVkIGFmdGVyIHRoYXQgZGVyZWdpc3RyYXRpb24gc2VlcyBhbiBlbXB0eSBnYXRlIHNldCwgYW5kIHdpdGhvdXRcbiAgICAvLyB0aGlzIGl0IHdvdWxkIHJlc29sdmUgbWlkLWNhc2NhZGUgYW5kIG92ZXJ0YWtlIHRoZSBkcmF3LiBUaGlzIGlzIHRoZSBleGFjdFxuICAgIC8vIGFycml2YWwtb3JkZXIgZGVwZW5kZW5jZSB0aGlzIG1vZGUgZXhpc3RzIHRvIHJlbW92ZS4gQ29zdHMgb25lIHF1aWV0XG4gICAgLy8gbWFjcm90YXNrIHR1cm4gd2hlbiBub3RoaW5nIGlzIGluIGZsaWdodC5cbiAgICBhd2FpdCBxdWllc2NlRWFybGllckNhc2NhZGVzKGN0eCwgZXZlbnRJbmRleCk7XG4gICAgcmV0dXJuO1xuICB9XG4gIGlmIChlYXJsaWVyLmxlbmd0aCA+IDApIHtcbiAgICAvLyBBbiBlYXJsaWVyIGRlbGl2ZXJ5IGJlaW5nIFwiZGVsaXZlcmVkXCIgb25seSBtZWFucyBpdHMgYHJlc29sdmUoKWAgcmFuLlxuICAgIC8vIFRoZSBicmFuY2ggaXQgd29rZSBtYXkgbmVlZCBhbiBhcmJpdHJhcnkgbnVtYmVyIG9mIGZ1cnRoZXIgbWljcm90YXNrXG4gICAgLy8gaG9wcyBiZWZvcmUgaXQgcmVhY2hlcyBpdHMgbmV4dCBgdXNlU3RlcGAgY2FsbCBhbmQgZHJhd3MgYSBVTElEOiBhXG4gICAgLy8gYGZvciBhd2FpdGAgb3ZlciBhIGhvb2ssIGZvciBpbnN0YW5jZSwgcmVzdW1lcyB0aGUgZ2VuZXJhdG9yLCBzZXR0bGVzXG4gICAgLy8gdGhlIHByb21pc2UgZnJvbSBgbmV4dCgpYCwgYW5kIG9ubHkgdGhlbiBydW5zIHRoZSBsb29wIGJvZHkuIFJlc29sdmluZ1xuICAgIC8vIHRoaXMgZGVsaXZlcnkgb24gYSBtaWNyb3Rhc2sgd291bGQgbGV0IGl0IG92ZXJ0YWtlIHRoYXQgYnJhbmNoIGFuZFxuICAgIC8vIHJlb3JkZXIgdGhlIFVMSUQgYWxsb2NhdGlvbiBhbnl3YXksIHR1cm5pbmcgdGhlIGd1YXJhbnRlZSBiZWxvdyBpbnRvIGFcbiAgICAvLyBob3AtY291bnQgcmFjZSB0aGF0IGhvbGRzIG9ubHkgZm9yIHRoZSBzaG9ydGVzdCBjb25zdW1lcnMuXG4gICAgLy9cbiAgICAvLyBZaWVsZGluZyBhIG1hY3JvdGFzayBsZXRzIHRoZSBlYXJsaWVyIGJyYW5jaCdzIGVudGlyZSBtaWNyb3Rhc2sgY2hhaW5cbiAgICAvLyBkcmFpbiBmaXJzdCwgd2hhdGV2ZXIgaXRzIGxlbmd0aCwgc28gbG9nIG9yZGVyIHN1cnZpdmVzIHJlZ2FyZGxlc3Mgb2ZcbiAgICAvLyBob3cgdGhlIHdvcmtmbG93IGNvbnN1bWVzIHRoZSBlYXJsaWVyIGRlbGl2ZXJ5LiBPbmx5IGRlbGl2ZXJpZXMgdGhhdFxuICAgIC8vIGFjdHVhbGx5IGhhZCB0byBkZWZlciBwYXkgdGhpcywgc28gdGhlIGNvbW1vbiBzaW5nbGUtZGVsaXZlcnkgZHJhaW4gaXNcbiAgICAvLyB1bmFmZmVjdGVkLlxuICAgIGF3YWl0IG5ldyBQcm9taXNlPHZvaWQ+KChyZXNvbHZlKSA9PiBzZXRUaW1lb3V0KHJlc29sdmUsIDApKTtcbiAgfVxufVxuXG4vKiogSGFuZGxlIGZvciBhIHJlZ2lzdGVyZWQgYnJhbmNoLWRlY2lkaW5nIGRlbGl2ZXJ5IGJhcnJpZXIuICovXG5leHBvcnQgaW50ZXJmYWNlIERlbGl2ZXJ5QmFycmllciB7XG4gIC8qKlxuICAgKiBNYXJrIHRoaXMgZGVsaXZlcnkgYXMgZGVsaXZlcmVkIHRvIHRoZSB3b3JrZmxvdy4gUmVzb2x2ZXMgaXRzXG4gICAqIGBkZWxpdmVyZWRgIHByb21pc2Ugc28gYW55IGxhdGVyLWluLWxvZyBkZWxpdmVyeSBnYXRlZCBvbiBpdCAodmlhXG4gICAqIHtAbGluayBhd2FpdEVhcmxpZXJEZWxpdmVyaWVzfSkgbWF5IHByb2NlZWQsIGFuZCByZW1vdmVzIGl0IGZyb20gdGhlXG4gICAqIHJlZ2lzdHJ5LiBJZGVtcG90ZW50LlxuICAgKi9cbiAgbWFya0RlbGl2ZXJlZDogKCkgPT4gdm9pZDtcbiAgLyoqXG4gICAqIE1hcmsgdGhpcyBkZWxpdmVyeSBhcyBjb21taXR0ZWQgdG8gaGFwcGVuaW5nLCBmb3IgYSBiYXJyaWVyIHJlZ2lzdGVyZWRcbiAgICogdW5hcm1lZCAoYSBidWZmZXJlZCBob29rIHBheWxvYWQpIG9uY2UgYSBjb25zdW1lciBoYXMgY2xhaW1lZCBpdC4gRnJvbVxuICAgKiB0aGVuIG9uIGEgbGF0ZXIgc3RlcCByZXN1bHQgbWF5IGJlIG9yZGVyZWQgYmVoaW5kIGl0LiBJZGVtcG90ZW50LlxuICAgKi9cbiAgYXJtOiAoKSA9PiB2b2lkO1xufVxuXG4vKipcbiAqIFJlZ2lzdGVyIGEgYnJhbmNoLWRlY2lkaW5nIGRlbGl2ZXJ5IGF0IGl0cyBldmVudC1sb2cgaW5kZXggc28gdGhhdCBsYXRlclxuICogZGVsaXZlcmllcyBjYW4gYmUgb3JkZXJlZCBzdHJpY3RseSBhZnRlciBpdC4gUmV0dXJucyBhbiBpbmVydCBoYW5kbGUgd2hlblxuICogYHBlbmRpbmdEZWxpdmVyeUJhcnJpZXJzYCBpcyBub3QgaW5pdGlhbGl6ZWQuXG4gKlxuICogUGFzcyBgYXJtZWQ6IGZhbHNlYCBmb3IgYSBkZWxpdmVyeSB3aG9zZSByZXNvbHV0aW9uIHdhaXRzIG9uIHdvcmtmbG93IGNvZGVcbiAqIGFza2luZyBmb3IgaXQgKGEgYnVmZmVyZWQgaG9vayBwYXlsb2FkKTsgY2FsbCBgYXJtKClgIHdoZW4gaXQgZG9lcy5cbiAqXG4gKiBUbyBndWFyYW50ZWUgYSBsYXRlciBkZWxpdmVyeSBnYXRlZCBvbiB0aGlzIG9uZSBjYW4gbmV2ZXIgaGFuZyB3aGVuIHRoaXNcbiAqIGRlbGl2ZXJ5IGlzIGFiYW5kb25lZCAodGhlIHdvcmtmbG93IHRvb2sgYSBkaWZmZXJlbnQgYnJhbmNoIG9yIGlzXG4gKiBzdXNwZW5kaW5nIGFuZCBuZXZlciBvYnNlcnZlcyBpdCksIHRoZSBiYXJyaWVyIGF1dG8tcmVzb2x2ZXMgYXQgaWRsZS5cbiAqXG4gKiBJTlZBUklBTlQgcmVxdWlyZWQgb2YgZXZlcnkgY2FsbCBzaXRlOiBhIGJhcnJpZXIgdGhhdCBpcyBldmVyIGBhcm1lZGAgbXVzdFxuICogYmUgcGFpcmVkIHdpdGggYSBkZWxpdmVyeSBjaGFpbiB0aGF0IHJ1bnMgdW5jb25kaXRpb25hbGx5LCBhdHRhY2hlZCB3aGVuXG4gKiB0aGUgZXZlbnQgaXMgY29uc3VtZWQgKHdhaXRzLCBzdGVwIHJlc3VsdHMsIHdhaXRpbmctY29uc3VtZXIgaG9vayBwYXlsb2FkcyxcbiAqIGFib3J0cyksIG9yIGJ5IHRoZSBgY2xhaW0oKWAgd2hvc2UgaW52b2NhdGlvbiBpcyB3aGF0IGFybXMgaXQgKGJ1ZmZlcmVkXG4gKiBob29rIHBheWxvYWRzKS4gVGhlIGlkbGUgY2hlY2sgKHtAbGluayBzY2hlZHVsZVdoZW5JZGxlfSkgcmVmdXNlcyB0b1xuICogb2JzZXJ2ZSBpZGxlIHdoaWxlIGFuIGFybWVkLCBzZWxmLXJlc29sdmluZyBiYXJyaWVyIGlzIHVuZGVsaXZlcmVkLCBhbmQgdGhlXG4gKiBzYWZldHkgbmV0IGJlbG93IGlzIGl0c2VsZiBpZGxlLWdhdGVkLCBzbyBhbiBhcm1lZCBiYXJyaWVyIHdpdGggbm9cbiAqIHVuY29uZGl0aW9uYWwgY2hhaW4gd291bGQgbGl2ZWxvY2sgZXZlcnkgaWRsZSBjaGVjayBpbiB0aGUgcnVuLCBpbmNsdWRpbmdcbiAqIGl0cyBvd24gcmV0aXJlbWVudC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlZ2lzdGVyRGVsaXZlcnlCYXJyaWVyKFxuICBjdHg6IFdvcmtmbG93T3JjaGVzdHJhdG9yQ29udGV4dCxcbiAgZXZlbnRJbmRleDogbnVtYmVyIHwgdW5kZWZpbmVkLFxuICBraW5kOiBEZWxpdmVyeUtpbmQsXG4gIG9wdGlvbnM6IHsgYXJtZWQ/OiBib29sZWFuIH0gPSB7fVxuKTogRGVsaXZlcnlCYXJyaWVyIHtcbiAgY29uc3QgYmFycmllcnMgPSBjdHgucGVuZGluZ0RlbGl2ZXJ5QmFycmllcnM7XG4gIGlmICghYmFycmllcnMgfHwgZXZlbnRJbmRleCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIHsgbWFya0RlbGl2ZXJlZDogKCkgPT4ge30sIGFybTogKCkgPT4ge30gfTtcbiAgfVxuXG4gIGxldCBkb25lID0gZmFsc2U7XG4gIGNvbnN0IHsgcHJvbWlzZSwgcmVzb2x2ZSB9ID0gd2l0aFJlc29sdmVyczx2b2lkPigpO1xuXG4gIGNvbnN0IGZpbmlzaCA9ICgpID0+IHtcbiAgICBpZiAoZG9uZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBkb25lID0gdHJ1ZTtcbiAgICBpZiAoYmFycmllcnMuZ2V0KGV2ZW50SW5kZXgpID09PSBlbnRyeSkge1xuICAgICAgYmFycmllcnMuZGVsZXRlKGV2ZW50SW5kZXgpO1xuICAgIH1cbiAgICByZXNvbHZlKCk7XG4gIH07XG5cbiAgY29uc3QgZW50cnk6IERlbGl2ZXJ5QmFycmllckVudHJ5ID0ge1xuICAgIGtpbmQsXG4gICAgZGVsaXZlcmVkOiBwcm9taXNlLFxuICAgIGFybWVkOiBvcHRpb25zLmFybWVkID8/IHRydWUsXG4gICAgcmV0aXJlOiBmaW5pc2gsXG4gIH07XG4gIGJhcnJpZXJzLnNldChldmVudEluZGV4LCBlbnRyeSk7XG5cbiAgLy8gU2FmZXR5IG5ldDogaWYgdGhpcyBkZWxpdmVyeSBpcyBuZXZlciBkZWxpdmVyZWQgdG8gdGhlIHdvcmtmbG93IChpdHNcbiAgLy8gYnJhbmNoIHdhcyBub3QgdGFrZW4gLyB0aGUgcnVuIGlzIHN1c3BlbmRpbmcsIG9yIGEgYnVmZmVyZWQgaG9vayBwYXlsb2FkXG4gIC8vIGlzIG9ubHkgY2xhaW1lZCBhZnRlciBhIGxhdGVyIGRlbGl2ZXJ5IHRoZSB3b3JrZmxvdyBpcyBzdGlsbCB3YWl0aW5nIG9uKSxcbiAgLy8gaXQgaXMgcmV0aXJlZCBhdCBpZGxlIHNvIGEgbGF0ZXIgZGVsaXZlcnkgZ2F0ZWQgb24gaXQgY2Fubm90IGRlYWRsb2NrIGFuZFxuICAvLyB0aGUgcmVnaXN0cnkgY2Fubm90IGxlYWsgYW4gZW50cnkgcGVyIGFiYW5kb25lZCBkZWxpdmVyeS4gUmV0aXJlbWVudCBnb2VzXG4gIC8vIHRocm91Z2ggdGhlIGNvbnRleHQncyBzaW5nbGUgb3JkZXJlZCBkaXNwZW5zZXIgcmF0aGVyIHRoYW4gYSBwZXItYmFycmllclxuICAvLyBpZGxlIHBvbGwuIFNlZSB7QGxpbmsgZW5zdXJlQmFycmllclNhZmV0eU5ldH0gZm9yIHdoeSB0aGUgT1JERVIgb2YgdGhlc2VcbiAgLy8gcmV0aXJlbWVudHMgaXMgbG9hZC1iZWFyaW5nLlxuICBlbnN1cmVCYXJyaWVyU2FmZXR5TmV0KGN0eCk7XG5cbiAgcmV0dXJuIHtcbiAgICBtYXJrRGVsaXZlcmVkOiBmaW5pc2gsXG4gICAgYXJtOiAoKSA9PiB7XG4gICAgICBlbnRyeS5hcm1lZCA9IHRydWU7XG4gICAgfSxcbiAgfTtcbn1cblxuLyoqXG4gKiBDb250ZXh0cyB3aG9zZSBiYXJyaWVyIHNhZmV0eS1uZXQgZGlzcGVuc2VyIGlzIGN1cnJlbnRseSBhcm1lZC4gTW9kdWxlLWxldmVsXG4gKiBzbyB0aGUgY29udGV4dCBpbnRlcmZhY2UgKGNvbnN0cnVjdGVkIGxpdGVyYWxseSBieSBtYW55IHRlc3QgaGFybmVzc2VzKVxuICogbmVlZHMgbm8gbmV3IGZpZWxkOyBlbnRyaWVzIGRyb3Agd2l0aCB0aGUgY29udGV4dC5cbiAqL1xuLy8gcGVyLWNvcHktb2s6IGtleWVkIG9uIHRoZSBvcmNoZXN0cmF0b3IgY29udGV4dCBvYmplY3QsIGFuZCBhIGNvbnRleHQgaXMgYXJtZWRcbi8vIGFuZCBvYnNlcnZlZCBieSB0aGUgc2FtZSBjb3B5IHRoYXQgY3JlYXRlZCBpdC4gRW50cmllcyBjYW4gbmV2ZXIgYmUgbG9va2VkIHVwXG4vLyBmcm9tIGFub3RoZXIgY29weSBiZWNhdXNlIHRoYXQgY29weSBoYXMgbm8gcmVmZXJlbmNlIHRvIHRoZSBrZXkuXG5jb25zdCBhY3RpdmVCYXJyaWVyU2FmZXR5TmV0cyA9IG5ldyBXZWFrU2V0PFdvcmtmbG93T3JjaGVzdHJhdG9yQ29udGV4dD4oKTtcblxuLyoqXG4gKiBUaGUgYmFycmllciByZWdpc3RyeSdzIHNhZmV0eSBuZXQ6IE9ORSBpZGxlLWdhdGVkIGRpc3BlbnNlciBwZXIgY29udGV4dCB0aGF0XG4gKiByZXRpcmVzLCBhdCBlYWNoIG9ic2VydmF0aW9uIG9mIGRlbGl2ZXJ5IGlkbGUsIG9ubHkgdGhlIExPV0VTVC1pbmRleCBlbnRyeVxuICogc3RpbGwgcmVnaXN0ZXJlZCwgdGhlbiB5aWVsZHMgc28gdGhlIGNoYWluIGl0IHJlbGVhc2VkIGNhbiBydW4gYmVmb3JlIHRoZVxuICogbmV4dCByZXRpcmVtZW50IGlzIGNvbnNpZGVyZWQuXG4gKlxuICogV2h5IG9uZSBvcmRlcmVkIGRpc3BlbnNlciBhbmQgbm90IGEgcG9sbCBwZXIgYmFycmllciAod2hpY2ggaXMgd2hhdCB0aGlzXG4gKiByZXBsYWNlZCk6IHRoZSBvcmRlciBvZiBzYWZldHktbmV0IHJldGlyZW1lbnRzIGRlY2lkZXMgdGhlIGRlbGl2ZXJ5IG9yZGVyIG9mXG4gKiBldmVyeSBjaGFpbiBwYXJrZWQgYmVoaW5kIGFuIHVuY2xhaW1lZCBidWZmZXJlZCBob29rIHBheWxvYWQ6IGEgaG9vayB0aGVcbiAqIHdvcmtmbG93IG5ldmVyIHJlYWRzIChhIGZpcmUtYW5kLWZvcmdldCBgY3JlYXRlSG9va2ApIHBhcmtzIGV2ZXJ5IGxhdGVyXG4gKiBhcm1lZCB3YWl0L2hvb2sgYmVoaW5kIGEgYmFycmllciB0aGF0IG9ubHkgdGhpcyBuZXQgY2FuIHJldGlyZS4gUGVyLWJhcnJpZXJcbiAqIHBvbGxzIGZpcmUgaW4gd2hhdGV2ZXIgb3JkZXIgdGhlaXIgcmUtYXJtIGN5Y2xlcyBsYW5kLCBhbmQgZWFjaCByZS1hcm1cbiAqIGF0dGFjaGVzIHRvIGEgYHByb21pc2VRdWV1ZWAgdGhhdCBncm93cyBiZXR3ZWVuIGNoZWNrcywgc28gd2l0aCBzZXZlcmFsXG4gKiBwYXJrZWQgc2VnbWVudHMgdGhlIHJlbGVhc2Ugb3JkZXIgZGVjYXlzIHRvIHRpbWluZyBub2lzZS4gRHJhd3MgKGB1c2VTdGVwYFxuICogY29ycmVsYXRpb24gaWRzKSB0aGVuIGRlcGVuZCBvbiB3aGljaCBzZWdtZW50IGhhcHBlbmVkIHRvIHJlbGVhc2UgZmlyc3Q6XG4gKiBjb25jcmV0ZWx5LCBvbiBob3cgTVVDSCBsb2cgdGhlIHJlcGxheSBsb2FkZWQsIHNpbmNlIHRoYXQgZGVjaWRlcyB3aGF0IGlzIGluXG4gKiB0aGUgcmVnaXN0cnkuIFRoYXQgaXMgdGhlIG1lY2hhbmlzbSBiZWhpbmQgc2xvdC1tb2RlIENPUlJVUFRFRF9FVkVOVF9MT0cgb25cbiAqIHN0b3JtLXNoYXBlZCBydW5zIChzZWUgc3Rvcm0tbG9nLXJlcGxheS50ZXN0LnRzLCBidWlsdCBmcm9tIGEgcHJvZHVjdGlvblxuICogbG9nKTogdHdvIHJlcGxheXMgb2YgdGhlIHNhbWUgcnVuIGhvbGRpbmcgZGlmZmVyZW50LWxlbmd0aCBwcmVmaXhlcyBib3VuZFxuICogdGhlIHNhbWUgY29ycmVsYXRpb24gb3JkaW5hbCB0byBkaWZmZXJlbnQgc3RlcHMuXG4gKlxuICogUmV0aXJpbmcgbG93ZXN0LWZpcnN0IGlzIG5vdCBtZXJlbHkgdGlkeSwgaXQgaXMgdGhlIG9ubHkgb3JkZXIgdGhhdCBjYW5ub3RcbiAqIGludmVydCB0aGUgbG9nOiBldmVyeSBnYXRlIHBvaW50cyBmcm9tIGEgaGlnaGVyIGluZGV4IHRvIGEgc3RyaWN0bHkgbG93ZXJcbiAqIG9uZSwgc28gYXQgZGVsaXZlcnkgaWRsZSB0aGUgbG93ZXN0IHVuZGVsaXZlcmVkIGVudHJ5IGdhdGVzIG9uIG5vdGhpbmdcbiAqIHN0aWxsIHJlZ2lzdGVyZWQ6IGl0IGlzIHRoZSBoZWFkIG9mIGV2ZXJ5IHBhcmtlZCBjaGFpbiAoaW4gcHJhY3RpY2UsIHRoZVxuICogdW5jbGFpbWVkIHBheWxvYWQgaXRzZWxmKS4gUmVsZWFzaW5nIGl0IGxldHMgdGhlIGNoYWluIGFib3ZlIGRlbGl2ZXJcbiAqIHRocm91Z2ggdGhlIG9yZGluYXJ5IGJhcnJpZXIgb3JkZXI7IGFueXRoaW5nIHRoZSByZWxlYXNlIHdha2VzIGZsaXBzXG4gKiB7QGxpbmsgaGFzUGFya2VkQ29tbWl0dGVkRGVsaXZlcnl9IGJhY2sgdG8gdHJ1ZSwgd2hpY2ggcmUtYmxvY2tzIHRoaXNcbiAqIGRpc3BlbnNlciB1bnRpbCB0aGUgY2hhaW4gaGFzIGZ1bGx5IGRyYWluZWQuIEEgaGlnaGVyIGVudHJ5IG11c3QgbmV2ZXIgYmVcbiAqIHJldGlyZWQgd2hpbGUgYSBsb3dlciBvbmUgaXMgcmVnaXN0ZXJlZCwgd2hpY2ggaXMgZXhhY3RseSB0aGUgaW52ZXJzaW9uXG4gKiBkZXNjcmliZWQgb24ge0BsaW5rIGF3YWl0RWFybGllckRlbGl2ZXJpZXN9LlxuICpcbiAqIFRoZSBkaXNwZW5zZXIgZ29lcyBkb3JtYW50IHdoZW4gdGhlIHJlZ2lzdHJ5IGVtcHRpZXMgYW5kIGlzIHJlLWFybWVkIGJ5IHRoZVxuICogbmV4dCByZWdpc3RyYXRpb24sIHNvIGFuIGlkbGUgY29udGV4dCBob2xkcyBubyBsaXZlIHRpbWVyLlxuICovXG5mdW5jdGlvbiBlbnN1cmVCYXJyaWVyU2FmZXR5TmV0KGN0eDogV29ya2Zsb3dPcmNoZXN0cmF0b3JDb250ZXh0KTogdm9pZCB7XG4gIGNvbnN0IGJhcnJpZXJzID0gY3R4LnBlbmRpbmdEZWxpdmVyeUJhcnJpZXJzO1xuICBpZiAoIWJhcnJpZXJzIHx8IGFjdGl2ZUJhcnJpZXJTYWZldHlOZXRzLmhhcyhjdHgpKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGFjdGl2ZUJhcnJpZXJTYWZldHlOZXRzLmFkZChjdHgpO1xuICBjb25zdCByZWFybSA9ICgpID0+IHtcbiAgICBzZXRUaW1lb3V0KGNoZWNrLCAwKTtcbiAgfTtcbiAgLy8gQSByZWplY3RlZCBwcm9taXNlUXVldWUgc2V0dGxlcyBpbW1lZGlhdGVseSBhbmQgZm9yZXZlciwgc28gcmUtYXJtaW5nXG4gIC8vIHRocm91Z2ggaXQgYXQgdGhlIG5vcm1hbCBjYWRlbmNlIHdvdWxkIGRlZ2VuZXJhdGUgaW50byBhIGJ1c3kgbG9vcCBvbiBhblxuICAvLyBhYmFuZG9uZWQgY29udGV4dC4gQmFjayBvZmYgaW5zdGVhZDogY29ycmVjdG5lc3Mgb25seSBuZWVkcyB0aGUgZGlzcGVuc2VyXG4gIC8vIHRvIHN0aWxsIGV4aXN0LCBzaW5jZSB0aGUgcmVnaXN0cnkgZ2F0ZXMgc3VzcGVuc2lvbiB2aWEgaXNEZWxpdmVyeUlkbGVcbiAgLy8gYW5kIGEgZGVhZCBkaXNwZW5zZXIgd291bGQgd2VkZ2UgdGhlIHJ1bi5cbiAgY29uc3QgcmVhcm1BZnRlclJlamVjdGlvbiA9ICgpID0+IHtcbiAgICBzZXRUaW1lb3V0KGNoZWNrLCA1MCk7XG4gIH07XG4gIGNvbnN0IGNoZWNrID0gKCkgPT4ge1xuICAgIGlmIChiYXJyaWVycy5zaXplID09PSAwKSB7XG4gICAgICAvLyBEb3JtYW50LiBUaGUgbmV4dCByZWdpc3RlckRlbGl2ZXJ5QmFycmllciByZS1hcm1zLlxuICAgICAgYWN0aXZlQmFycmllclNhZmV0eU5ldHMuZGVsZXRlKGN0eCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICghY2FuUmV0aXJlQWJhbmRvbmVkQmFycmllcnMoY3R4KSkge1xuICAgICAgLy8gQSBkZWxpdmVyeSBpcyBoeWRyYXRpbmcgb3IgY29tbWl0dGVkLWJ1dC1wYXJrZWQgb24gaXRzIGRlZmVycmFsOyBsZXRcbiAgICAgIC8vIHRoZSBxdWV1ZSBkcmFpbiBhbmQgcmUtY2hlY2sgYSB0aWNrIGxhdGVyIChzYW1lIGNhZGVuY2UgYXNcbiAgICAgIC8vIHNjaGVkdWxlV2hlbklkbGUpLlxuICAgICAgY3R4LnByb21pc2VRdWV1ZS50aGVuKHJlYXJtLCByZWFybUFmdGVyUmVqZWN0aW9uKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgLy8gSWRsZSB3aXRoIGVudHJpZXMgbGVmdDogbm90aGluZyByZW1haW5pbmcgZGVsaXZlcnMgb24gaXRzIG93biwgc29cbiAgICAvLyByZWxlYXNlIHBhcmtlZCBjaGFpbnMgZnJvbSB0aGUgaGVhZDogbG93ZXN0IGluZGV4IGZpcnN0LCBvbmUgYXQgYVxuICAgIC8vIHRpbWUsIHJlLXJlYWRpbmcgaWRsZSBiZXR3ZWVuIHJldGlyZW1lbnRzLiBBIHJldGlyZW1lbnQgdGhhdCB3YWtlcyBhXG4gICAgLy8gY2hhaW4gZmxpcHMge0BsaW5rIGhhc1BhcmtlZENvbW1pdHRlZERlbGl2ZXJ5fSBzeW5jaHJvbm91c2x5IChpdCBpc1xuICAgIC8vIGNvbXB1dGVkIGZyb20gdGhlIHJlZ2lzdHJ5IHRoaXMgbG9vcCBqdXN0IG11dGF0ZWQpLCB3aGljaCBzdG9wcyB0aGVcbiAgICAvLyBzd2VlcCBzbyB0aGUgY2hhaW4gZGVsaXZlcnMgYmVmb3JlIGFueXRoaW5nIGFib3ZlIGl0IGlzIHJlbGVhc2VkLiBBXG4gICAgLy8gcmV0aXJlbWVudCB0aGF0IHdha2VzIG5vdGhpbmcgKGEgc3RhbGUgcGF5bG9hZCBubyBkZWxpdmVyeSBnYXRlcyBvbilcbiAgICAvLyBrZWVwcyB0aGUgc3dlZXAgZ29pbmcsIHNvIGEgYmFja2xvZyBvZiB0aG9zZSBkcmFpbnMgaW4gT05FIGlkbGVcbiAgICAvLyBvYnNlcnZhdGlvbiwgc2luY2UgcGFjaW5nIHRoZW0gb25lIHBlciB0aW1lciB0aWNrIHdvdWxkIGhvbGRcbiAgICAvLyBjb25zdW1lZC1idXQtdW5kZWxpdmVyZWQgZXZlbnRzIGhvc3RhZ2UgbG9uZyBlbm91Z2ggdG8gdHJpcCB0aGUgZXZlbnRzXG4gICAgLy8gY29uc3VtZXIncyB1bmNvbnN1bWVkLWV2ZW50IGRlYWRsaW5lIGFuZCBmYWlsIGhlYWx0aHkgcmVwbGF5cy5cbiAgICB3aGlsZSAoYmFycmllcnMuc2l6ZSA+IDAgJiYgY2FuUmV0aXJlQWJhbmRvbmVkQmFycmllcnMoY3R4KSkge1xuICAgICAgbGV0IGxvd2VzdEluZGV4OiBudW1iZXIgfCB1bmRlZmluZWQ7XG4gICAgICBsZXQgbG93ZXN0RW50cnk6IERlbGl2ZXJ5QmFycmllckVudHJ5IHwgdW5kZWZpbmVkO1xuICAgICAgZm9yIChjb25zdCBbaW5kZXgsIGVudHJ5XSBvZiBiYXJyaWVycykge1xuICAgICAgICBpZiAobG93ZXN0SW5kZXggPT09IHVuZGVmaW5lZCB8fCBpbmRleCA8IGxvd2VzdEluZGV4KSB7XG4gICAgICAgICAgbG93ZXN0SW5kZXggPSBpbmRleDtcbiAgICAgICAgICBsb3dlc3RFbnRyeSA9IGVudHJ5O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBsb3dlc3RFbnRyeT8ucmV0aXJlKCk7XG4gICAgfVxuICAgIHNldFRpbWVvdXQoY2hlY2ssIDApO1xuICB9O1xuICBzZXRUaW1lb3V0KGNoZWNrLCAwKTtcbn1cblxuLyoqXG4gKiBXaGV0aGVyIHRoZSBzYWZldHktbmV0IGRpc3BlbnNlciBtYXkgcmV0aXJlIGFiYW5kb25lZCBiYXJyaWVycyByaWdodCBub3c6XG4gKiBubyBoeWRyYXRpb24gaW4gZmxpZ2h0IGFuZCBubyBjb21taXR0ZWQgZGVsaXZlcnkgc3RpbGwgd29ya2luZyB0aHJvdWdoIGl0c1xuICogZGV0YWNoZWQgZGVmZXJyYWwuIFRoaXMgaXMgZGVsaWJlcmF0ZWx5IFdFQUtFUiB0aGFuIHtAbGluayBpc0RlbGl2ZXJ5SWRsZX06XG4gKiB0aGUgZGlzcGVuc2VyIGlzIHdoYXQgZW1wdGllcyB0aGUgcmVnaXN0cnksIHNvIGdhdGluZyBpdCBvbiByZWdpc3RyeVxuICogZW1wdGluZXNzIHdvdWxkIGdhdGUgaXRzIG93biB3b3JrLlxuICovXG5mdW5jdGlvbiBjYW5SZXRpcmVBYmFuZG9uZWRCYXJyaWVycyhjdHg6IFdvcmtmbG93T3JjaGVzdHJhdG9yQ29udGV4dCk6IGJvb2xlYW4ge1xuICByZXR1cm4gY3R4LnBlbmRpbmdEZWxpdmVyaWVzID09PSAwICYmICFoYXNQYXJrZWRDb21taXR0ZWREZWxpdmVyeShjdHgpO1xufVxuXG4vKipcbiAqIFdoZXRoZXIgc29tZSByZWdpc3RlcmVkIGJyYW5jaC1kZWNpZGluZyBkZWxpdmVyeSBpcyBnb2luZyB0byByZWFjaCB0aGVcbiAqIHdvcmtmbG93IHdpdGhvdXQgYW55IGZ1cnRoZXIgaGVscCAoaXQgaXMgYXJtZWQgYW5kIG5vdCB0cmFuc2l0aXZlbHkgcGFya2VkXG4gKiBiZWhpbmQgYW4gdW5jbGFpbWVkIGJ1ZmZlcmVkIHBheWxvYWQsIHNlZSB7QGxpbmsgcmVzb2x2ZXNPbkl0c093bn0pIGJ1dFxuICogaGFzIG5vdCBiZWVuIGhhbmRlZCBvdmVyIHlldC5cbiAqXG4gKiBUaGlzIGlzIHRoZSBkZWxpdmVyeSBzdGF0ZSBgcGVuZGluZ0RlbGl2ZXJpZXNgIGNhbm5vdCBzZWUuIFRoYXQgY291bnRlclxuICogY292ZXJzIHRoZSBoeWRyYXRpb24gd2luZG93IGluc2lkZSBhIHNlcmlhbCBgcHJvbWlzZVF1ZXVlYCBzbG90IGFuZCBpc1xuICogcmVsZWFzZWQgdGhlcmUsIHdoaWxlIHRoZSBkZWxpdmVyeSdzIGByZXNvbHZlKClgIHJ1bnMgbGF0ZXIsIGZyb20gYVxuICogZGV0YWNoZWQgY29udGludWF0aW9uIGJlaGluZCB7QGxpbmsgYXdhaXRFYXJsaWVyRGVsaXZlcmllc30sIGluY2x1ZGluZyBpdHNcbiAqIG1hY3JvdGFzayB5aWVsZCB3aGVuZXZlciB0aGUgZGVsaXZlcnkgaGFkIHRvIGRlZmVyLiBSZXBsYXlpbmcgYSBiYXRjaCBvZiBOXG4gKiBwYXJhbGxlbCBzdGVwIHJlc3VsdHMgY29uc3VtZWQgaW4gb25lIGRyYWluIHdpbmRvdyBsZWF2ZXMgTi0xIG9mIHRoZW1cbiAqIHBhcmtlZCBvbiB0aGF0IHlpZWxkIHdpdGggYHBlbmRpbmdEZWxpdmVyaWVzYCBhbHJlYWR5IGF0IDAuIEFuIGlkbGUgY2hlY2tcbiAqIGFybWVkIGR1cmluZyB0aGUgc2FtZSB3aW5kb3cgKGEgcGVuZGluZyBgc2xlZXAoKWAgYXJtcyBvbmUgb24gZXZlcnkgcmVwbGF5KVxuICogY291bGQgdGhlbiBvYnNlcnZlIFwiaWRsZVwiIG1pZC1kZWZlcnJhbCBhbmQgcmFpc2UgYSBgV29ya2Zsb3dTdXNwZW5zaW9uYFxuICogQkVGT1JFIHRoZSB3b3JrZmxvdydzIG93biBjb250aW51YXRpb25zIHJhbjogYSBzdXNwZW5zaW9uIGNhcnJ5aW5nIG5vbmUgb2ZcbiAqIHRoZSBmb2xsb3ctdXAgd29yayB0aGUgYmF0Y2ggd2FzIGFib3V0IHRvIGNyZWF0ZSwgd2hpY2ggdGhlIHJ1bnRpbWVcbiAqIGR1dGlmdWxseSBzY2hlZHVsZXMgYXMgbm90aGluZywgbGVhdmluZyB0aGUgcnVuIGRvcm1hbnQgdW50aWwgYW4gdW5yZWxhdGVkXG4gKiB0aW1lciBmaXJlcyAodmVyY2VsL3dvcmtmbG93IzMxODMpLlxuICpcbiAqIERlbGl2ZXJpZXMgdGhhdCBkbyBOT1QgcmVzb2x2ZSBvbiB0aGVpciBvd24gbXVzdCBiZSBleGNsdWRlZCwgbm90IGZvclxuICogYWNjdXJhY3kgYnV0IGZvciB0ZXJtaW5hdGlvbjogYW4gdW5jbGFpbWVkIGJ1ZmZlcmVkIGhvb2sgcGF5bG9hZCBpcyByZXRpcmVkXG4gKiBCWSB0aGUgaWRsZSBzYWZldHkgbmV0IGluIHtAbGluayByZWdpc3RlckRlbGl2ZXJ5QmFycmllcn0sIHNvIGNvdW50aW5nIGl0XG4gKiBoZXJlIHdvdWxkIGdhdGUgaXRzIG93biByZXRpcmVtZW50LiBUaGF0IHJlYXNvbmluZyBleHRlbmRzIHRvIHdoYXRldmVyIGlzXG4gKiBwYXJrZWQgYmVoaW5kIHN1Y2ggYSBwYXlsb2FkIChhIHdhaXQsIGFuZCBhIHN0ZXAgZ2F0aW5nIG9uIHRoYXQgd2FpdCkgZm9yXG4gKiB0aGUgc2FtZSByZWFzb246IHRoZSB3aG9sZSBjaGFpbiBtb3ZlcyBvbmx5IG9uY2UgdGhlIG5ldCBmaXJlcywgYW5kIGl0XG4gKiBjYW5ub3QgZmlyZSB3aGlsZSB0aGUgY2hhaW4gaXMgY291bnRlZC4gU2VsZi1yZXNvbHZpbmcgZGVsaXZlcmllcyBhbHdheXNcbiAqIGRlbGl2ZXIgZnJvbSB0aGVpciBvd24gY2hhaW5zIChzZWUgdGhlIElOVkFSSUFOVCBvblxuICoge0BsaW5rIHJlZ2lzdGVyRGVsaXZlcnlCYXJyaWVyfSkgYW5kIG5ldmVyIG5lZWQgdGhhdCBuZXQsIHNvIHdhaXRpbmcgb25cbiAqIHRoZW0gaXMgZGVhZGxvY2stZnJlZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGhhc1BhcmtlZENvbW1pdHRlZERlbGl2ZXJ5KFxuICBjdHg6IFdvcmtmbG93T3JjaGVzdHJhdG9yQ29udGV4dFxuKTogYm9vbGVhbiB7XG4gIGNvbnN0IGJhcnJpZXJzID0gY3R4LnBlbmRpbmdEZWxpdmVyeUJhcnJpZXJzO1xuICBpZiAoIWJhcnJpZXJzIHx8IGJhcnJpZXJzLnNpemUgPT09IDApIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgLy8gU2hhcmVkIGFjcm9zcyB0aGlzIGNhbGwgb25seS4gU2VlIGByZXNvbHZlc09uSXRzT3duYC5cbiAgY29uc3Qgc2VsZlJlc29sdmluZyA9IG5ldyBNYXA8bnVtYmVyLCBib29sZWFuPigpO1xuICBmb3IgKGNvbnN0IFtpbmRleCwgZW50cnldIG9mIGJhcnJpZXJzKSB7XG4gICAgaWYgKHJlc29sdmVzT25JdHNPd24oYmFycmllcnMsIGluZGV4LCBlbnRyeSwgc2VsZlJlc29sdmluZykpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cbi8qKlxuICogV2hldGhlciBubyBkYXRhIGRlbGl2ZXJ5IChzdGVwIHJlc3VsdCwgaG9vayBwYXlsb2FkKSBpcyBpbiBmbGlnaHQgcmlnaHQgbm93LlxuICpcbiAqIFwiSW4gZmxpZ2h0XCIgaXMgdHdvIGRpc3RpbmN0IHdpbmRvd3MsIGVhY2ggd2l0aCBpdHMgb3duIGd1YXJkOlxuICogYHBlbmRpbmdEZWxpdmVyaWVzID4gMGAgY292ZXJzIGh5ZHJhdGlvbiBpbnNpZGUgdGhlIHNlcmlhbCBxdWV1ZSBzbG90cywgYW5kXG4gKiB7QGxpbmsgaGFzUGFya2VkQ29tbWl0dGVkRGVsaXZlcnl9IGNvdmVycyB0aGUgZGV0YWNoZWQgZ2FwIGJldHdlZW4gYSBzbG90XG4gKiByZWxlYXNpbmcgdGhhdCBjb3VudGVyIGFuZCB0aGUgZGVsaXZlcnkncyBgcmVzb2x2ZSgpYCBhY3R1YWxseSBydW5uaW5nLFxuICogZGVsaWJlcmF0ZWx5IG91dHNpZGUgYHBlbmRpbmdEZWxpdmVyaWVzYCAoc2VlIHN0ZXAudHMpLCBhbmQgaW52aXNpYmxlIHRvIGl0LlxuICpcbiAqIEFueXRoaW5nIHRoYXQgZGVjaWRlcyBhIHJlcGxheSBpcyBvdmVyLCBvciB0aGF0IGEgcmVwbGF5IHdlbnQgd3JvbmcsIGhhcyB0b1xuICogY29uc3VsdCB0aGlzIGZpcnN0OiB3aGlsZSBpdCBpcyBmYWxzZSB0aGUgd29ya2Zsb3cgVk0gaXMgbWlkLXJlYWN0aW9uLCBzb1xuICogd2hhdCBpdCBoYXMgYW5kIGhhcyBub3QgZG9uZSB5ZXQgc2F5cyBub3RoaW5nIGFib3V0IHRoZSBydW4uIFR3byBjYWxsZXJzXG4gKiByZWFkIGl0LCBmb3IgdGhlIHR3byBzdWNoIGRlY2lzaW9uczoge0BsaW5rIHNjaGVkdWxlV2hlbklkbGV9IGZvciB0aGVcbiAqIHN1c3BlbnNpb24sIGFuZCB0aGUgZXZlbnRzIGNvbnN1bWVyJ3MgdW5jb25zdW1lZC1ldmVudCBjaGVjayBmb3IgZGl2ZXJnZW5jZS5cbiAqXG4gKiBBIG5vbi1lbXB0eSBiYXJyaWVyIHJlZ2lzdHJ5IGNvdW50cyBhcyBpbiBmbGlnaHQsIGV2ZW4gd2hlbiBldmVyeSByZW1haW5pbmdcbiAqIGVudHJ5IGlzIHBhcmtlZCBiZWhpbmQgYW4gdW5jbGFpbWVkIGJ1ZmZlcmVkIHBheWxvYWQuIFRob3NlIGVudHJpZXMgb25seVxuICogbW92ZSB3aGVuIHRoZSBzYWZldHktbmV0IGRpc3BlbnNlciByZXRpcmVzIHRoZW0gKGxvd2VzdC1maXJzdCwgc2VlXG4gKiB7QGxpbmsgZW5zdXJlQmFycmllclNhZmV0eU5ldH0pLCBhbmQgdGhlIGRlbGl2ZXJpZXMgdGhleSByZWxlYXNlIGFyZSByZWFsXG4gKiB3b3JrZmxvdyByZWFjdGlvbnM6IGEgc3VzcGVuc2lvbiByYWlzZWQgYmVmb3JlIHRoZXkgcnVuIHdvdWxkIGJlIGNvbXB1dGVkXG4gKiBmcm9tIGEgVk0gdGhhdCBoYXMgbm90IHNlZW4gdGhlbSwgc2NoZWR1bGluZyBub25lIG9mIHRoZWlyIGZvbGxvdy11cCB3b3JrXG4gKiBhbmQgbGVhdmluZyB0aGUgcnVuIGRvcm1hbnQgKHRoZSB2ZXJjZWwvd29ya2Zsb3cjMzE4MyBzaGFwZSkuIFRoZSBkaXNwZW5zZXJcbiAqIGl0c2VsZiBpcyBnYXRlZCBvbiB7QGxpbmsgY2FuUmV0aXJlQWJhbmRvbmVkQmFycmllcnN9LCB0aGUgd2Vha2VyIHByZWRpY2F0ZVxuICogd2l0aG91dCB0aGUgcmVnaXN0cnkgdGVybSwgcHJlY2lzZWx5IHNvIGl0IGNhbiBkbyB0aGUgZHJhaW5pbmcgdGhhdCB0aGlzXG4gKiBwcmVkaWNhdGUgd2FpdHMgZm9yOyByZWdpc3RyeSBzaXplIHN0cmljdGx5IGRlY3JlYXNlcyBhdCBlYWNoIHJldGlyZW1lbnQsXG4gKiBzbyBpZGxlIGlzIGFsd2F5cyByZWFjaGVkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNEZWxpdmVyeUlkbGUoY3R4OiBXb3JrZmxvd09yY2hlc3RyYXRvckNvbnRleHQpOiBib29sZWFuIHtcbiAgcmV0dXJuIChcbiAgICBjdHgucGVuZGluZ0RlbGl2ZXJpZXMgPT09IDAgJiZcbiAgICAoIWN0eC5wZW5kaW5nRGVsaXZlcnlCYXJyaWVycyB8fCBjdHgucGVuZGluZ0RlbGl2ZXJ5QmFycmllcnMuc2l6ZSA9PT0gMClcbiAgKTtcbn1cblxuLyoqXG4gKiBTY2hlZHVsZSBhIGNhbGxiYWNrIHRvIGZpcmUgb25seSBhZnRlciBhbGwgcGVuZGluZyBkYXRhIGRlbGl2ZXJpZXNcbiAqIChzdGVwIHJlc3VsdHMsIGhvb2sgcGF5bG9hZHMpIGFuZCBhc3luYyBkZXNlcmlhbGl6YXRpb24gaGF2ZSBjb21wbGV0ZWQuXG4gKiBVc2VzIGEgcG9sbGluZyBsb29wOiBzZXRUaW1lb3V0KDApIOKGkiBjaGVjayBwZW5kaW5nRGVsaXZlcmllcyBhbmQgdGhlXG4gKiBiYXJyaWVyIHJlZ2lzdHJ5IOKGkiBpZiBhbnl0aGluZyBpcyBzdGlsbCBpbiBmbGlnaHQsIHdhaXQgZm9yIHByb21pc2VRdWV1ZSDihpJcbiAqIHJlcGVhdC4gVGhpcyBoYW5kbGVzIHRoZSBtdWx0aS1yb3VuZCBkZWxpdmVyeSBwYXR0ZXJuIHdoZXJlIGVhY2ggaG9va1xuICogcGF5bG9hZCBkZWxpdmVyeSBjeWNsZSBhcHBlbmRzIG5ldyBhc3luYyB3b3JrIHRvIHRoZSBwcm9taXNlUXVldWUuIFdoYXRcbiAqIGNvdW50cyBhcyBpbiBmbGlnaHQgaXMge0BsaW5rIGlzRGVsaXZlcnlJZGxlfS5cbiAqXG4gKiBUaGUgaW5pdGlhbCBgc2V0VGltZW91dCgwKWAgbWFjcm90YXNrIGlzIGxvYWQtYmVhcmluZyBhbmQgbXVzdCBOT1QgYmVcbiAqIGRvd25ncmFkZWQgdG8gYSBtaWNyb3Rhc2sgKGBxdWV1ZU1pY3JvdGFza2AvYFByb21pc2UucmVzb2x2ZSgpLnRoZW5gKS5cbiAqIGBwZW5kaW5nRGVsaXZlcmllc2Agb25seSBndWFyZHMgdGhlIGhvc3Qtc2lkZSBoeWRyYXRpb24gd2luZG93OyBiZXR3ZWVuIGFcbiAqIGRlbGl2ZXJ5J3MgYHJlc29sdmUoKWAgYW5kIHRoZSB3b3JrZmxvdyBWTSBib2R5IHJ1bm5pbmcgaXRzIGNvbnRpbnVhdGlvbiB0b1xuICogcmVnaXN0ZXIgdGhlIG5leHQgc3Vic2NyaWJlciwgYHBlbmRpbmdEZWxpdmVyaWVzYCBpcyBhbHJlYWR5IDAgZXZlbiB0aG91Z2hcbiAqIHRoZSBWTSBpcyBtaWQtcmVhY3Rpb24uIE5vZGUgZG9lcyBub3QgZ3VhcmFudGVlIGEgbWljcm90YXNrIHNjaGVkdWxlZCBpblxuICogdGhlIGhvc3QgY29udGV4dCBzZXR0bGVzIGFmdGVyIHRoZSBjcm9zcy1WTSBwcm9taXNlIGNoYWluIChyZXNvbHZlIGluIGhvc3RcbiAqIOKGkiB3b3JrZmxvdyBjb2RlIGluIFZNIOKGkiBzdWJzY3JpYmUgYmFjayBpbiBob3N0KTsgdGhlIG1hY3JvdGFzayBib3VuZGFyeVxuICogZ2l2ZXMgdGhhdCBjaGFpbiB0aW1lIHRvIHJ1biwgc28gdGhlIHN1c3BlbnNpb24gZG9lcyBub3QgcHJlZW1wdCBhIHNpYmxpbmdcbiAqIGRlbGl2ZXJ5IHN0aWxsIGluIGZsaWdodC4gRW1waXJpY2FsbHksIHJlcGxhY2luZyBpdCB3aXRoIGBxdWV1ZU1pY3JvdGFza2BcbiAqIGJyZWFrcyBob29rL3NsZWVwIGBQcm9taXNlLnJhY2VgIG9yZGVyaW5nIChDb3JydXB0ZWRFdmVudExvZ0Vycm9yKS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNjaGVkdWxlV2hlbklkbGUoXG4gIGN0eDogV29ya2Zsb3dPcmNoZXN0cmF0b3JDb250ZXh0LFxuICBmbjogKCkgPT4gdm9pZFxuKTogdm9pZCB7XG4gIGNvbnN0IGNoZWNrID0gKCkgPT4ge1xuICAgIGlmICghaXNEZWxpdmVyeUlkbGUoY3R4KSkge1xuICAgICAgLy8gQSBkZWxpdmVyeSBpcyBzdGlsbCBoeWRyYXRpbmcsIG9yIGlzIGNvbW1pdHRlZCBidXQgcGFya2VkIGJlaGluZCBpdHNcbiAgICAgIC8vIGRlZmVycmFsICh3aG9zZSByZXNvbHZlIHJ1bnMgb24gYSBkZXRhY2hlZCB0aW1lciwgbm90IHRoaXMgcXVldWUpLlxuICAgICAgLy8gRWl0aGVyIHdheTogbGV0IHRoZSBxdWV1ZSBkcmFpbiwgdGhlbiByZS1jaGVjayBhIHRpbWVyIHRpY2sgbGF0ZXIuXG4gICAgICBjdHgucHJvbWlzZVF1ZXVlLnRoZW4oKCkgPT4ge1xuICAgICAgICBzZXRUaW1lb3V0KGNoZWNrLCAwKTtcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBmbigpO1xuICAgIH1cbiAgfTtcbiAgc2V0VGltZW91dChjaGVjaywgMCk7XG59XG5cbi8qKiBTY2hlZHVsZSBhIGdlbmVyYXRpb24tZ3VhcmRlZCBzdXNwZW5zaW9uIGFmdGVyIGRlbGl2ZXJpZXMgc2V0dGxlLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNjaGVkdWxlV29ya2Zsb3dTdXNwZW5zaW9uKFxuICBjdHg6IFdvcmtmbG93T3JjaGVzdHJhdG9yQ29udGV4dFxuKTogdm9pZCB7XG4gIGNvbnN0IGdlbmVyYXRpb24gPSBjdHguc3VzcGVuc2lvbkdlbmVyYXRpb247XG4gIHNjaGVkdWxlV2hlbklkbGUoY3R4LCAoKSA9PiB7XG4gICAgaWYgKGdlbmVyYXRpb24gIT09IGN0eC5zdXNwZW5zaW9uR2VuZXJhdGlvbikgcmV0dXJuO1xuICAgIGN0eC5vbldvcmtmbG93RXJyb3IoXG4gICAgICBuZXcgV29ya2Zsb3dTdXNwZW5zaW9uKGN0eC5pbnZvY2F0aW9uc1F1ZXVlLCBjdHguZ2xvYmFsVGhpcylcbiAgICApO1xuICB9KTtcbn1cbiJdfQ==