@workflow/core 5.0.0-beta.1 → 5.0.0-beta.11

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 (215) hide show
  1. package/README.md +1 -1
  2. package/dist/attribute-changes.d.ts +7 -0
  3. package/dist/attribute-changes.d.ts.map +1 -0
  4. package/dist/attribute-changes.js +25 -0
  5. package/dist/capabilities.js +1 -1
  6. package/dist/capture-stack.d.ts +16 -0
  7. package/dist/capture-stack.d.ts.map +1 -0
  8. package/dist/capture-stack.js +21 -0
  9. package/dist/class-serialization.js +1 -1
  10. package/dist/classify-error.d.ts +11 -3
  11. package/dist/classify-error.d.ts.map +1 -1
  12. package/dist/classify-error.js +56 -6
  13. package/dist/context-errors.d.ts +27 -0
  14. package/dist/context-errors.d.ts.map +1 -0
  15. package/dist/context-errors.js +101 -0
  16. package/dist/context-violation-error.d.ts +97 -0
  17. package/dist/context-violation-error.d.ts.map +1 -0
  18. package/dist/context-violation-error.js +147 -0
  19. package/dist/create-hook.d.ts.map +1 -1
  20. package/dist/create-hook.js +4 -3
  21. package/dist/define-hook.d.ts.map +1 -1
  22. package/dist/define-hook.js +20 -5
  23. package/dist/describe-error.d.ts +70 -0
  24. package/dist/describe-error.d.ts.map +1 -0
  25. package/dist/describe-error.js +165 -0
  26. package/dist/encryption.d.ts +22 -1
  27. package/dist/encryption.d.ts.map +1 -1
  28. package/dist/encryption.js +72 -27
  29. package/dist/events-consumer.d.ts +7 -0
  30. package/dist/events-consumer.d.ts.map +1 -1
  31. package/dist/events-consumer.js +18 -3
  32. package/dist/flushable-stream.d.ts +10 -10
  33. package/dist/flushable-stream.d.ts.map +1 -1
  34. package/dist/flushable-stream.js +18 -13
  35. package/dist/global.d.ts +4 -0
  36. package/dist/global.d.ts.map +1 -1
  37. package/dist/global.js +8 -2
  38. package/dist/index.d.ts +1 -0
  39. package/dist/index.d.ts.map +1 -1
  40. package/dist/index.js +2 -1
  41. package/dist/log-format.d.ts +25 -0
  42. package/dist/log-format.d.ts.map +1 -0
  43. package/dist/log-format.js +250 -0
  44. package/dist/logger.d.ts +28 -30
  45. package/dist/logger.d.ts.map +1 -1
  46. package/dist/logger.js +77 -31
  47. package/dist/private.js +3 -3
  48. package/dist/runtime/constants.d.ts +48 -0
  49. package/dist/runtime/constants.d.ts.map +1 -1
  50. package/dist/runtime/constants.js +91 -8
  51. package/dist/runtime/get-port-lazy.d.ts +10 -0
  52. package/dist/runtime/get-port-lazy.d.ts.map +1 -0
  53. package/dist/runtime/get-port-lazy.js +30 -0
  54. package/dist/runtime/get-world-lazy.d.ts +32 -0
  55. package/dist/runtime/get-world-lazy.d.ts.map +1 -0
  56. package/dist/runtime/get-world-lazy.js +56 -0
  57. package/dist/runtime/helpers.d.ts +38 -5
  58. package/dist/runtime/helpers.d.ts.map +1 -1
  59. package/dist/runtime/helpers.js +141 -25
  60. package/dist/runtime/replay-budget.d.ts +98 -0
  61. package/dist/runtime/replay-budget.d.ts.map +1 -0
  62. package/dist/runtime/replay-budget.js +191 -0
  63. package/dist/runtime/resume-hook.d.ts.map +1 -1
  64. package/dist/runtime/resume-hook.js +5 -4
  65. package/dist/runtime/run.d.ts.map +1 -1
  66. package/dist/runtime/run.js +31 -6
  67. package/dist/runtime/runs.d.ts.map +1 -1
  68. package/dist/runtime/runs.js +4 -1
  69. package/dist/runtime/start.js +9 -4
  70. package/dist/runtime/step-executor.d.ts +42 -0
  71. package/dist/runtime/step-executor.d.ts.map +1 -0
  72. package/dist/runtime/step-executor.js +493 -0
  73. package/dist/runtime/step-handler.d.ts.map +1 -1
  74. package/dist/runtime/step-handler.js +217 -115
  75. package/dist/runtime/suspension-handler.d.ts +22 -4
  76. package/dist/runtime/suspension-handler.d.ts.map +1 -1
  77. package/dist/runtime/suspension-handler.js +90 -73
  78. package/dist/runtime/world-init.d.ts +75 -0
  79. package/dist/runtime/world-init.d.ts.map +1 -0
  80. package/dist/runtime/world-init.js +75 -0
  81. package/dist/runtime/world.d.ts.map +1 -1
  82. package/dist/runtime/world.js +47 -18
  83. package/dist/runtime.d.ts +8 -7
  84. package/dist/runtime.d.ts.map +1 -1
  85. package/dist/runtime.js +802 -320
  86. package/dist/schemas.d.ts +1 -1
  87. package/dist/schemas.d.ts.map +1 -1
  88. package/dist/schemas.js +1 -1
  89. package/dist/serialization/client.d.ts +17 -0
  90. package/dist/serialization/client.d.ts.map +1 -0
  91. package/dist/serialization/client.js +45 -0
  92. package/dist/serialization/codec-devalue.d.ts +14 -0
  93. package/dist/serialization/codec-devalue.d.ts.map +1 -0
  94. package/dist/serialization/codec-devalue.js +98 -0
  95. package/dist/serialization/codec.d.ts +90 -0
  96. package/dist/serialization/codec.d.ts.map +1 -0
  97. package/dist/serialization/codec.js +17 -0
  98. package/dist/serialization/encryption.d.ts +32 -0
  99. package/dist/serialization/encryption.d.ts.map +1 -0
  100. package/dist/serialization/encryption.js +67 -0
  101. package/dist/serialization/errors.d.ts +34 -0
  102. package/dist/serialization/errors.d.ts.map +1 -0
  103. package/dist/serialization/errors.js +59 -0
  104. package/dist/serialization/format.d.ts +60 -0
  105. package/dist/serialization/format.d.ts.map +1 -0
  106. package/dist/serialization/format.js +97 -0
  107. package/dist/serialization/index.d.ts +18 -0
  108. package/dist/serialization/index.d.ts.map +1 -0
  109. package/dist/serialization/index.js +20 -0
  110. package/dist/serialization/reducers/class.d.ts +11 -0
  111. package/dist/serialization/reducers/class.d.ts.map +1 -0
  112. package/dist/serialization/reducers/class.js +68 -0
  113. package/dist/serialization/reducers/common.d.ts +16 -0
  114. package/dist/serialization/reducers/common.d.ts.map +1 -0
  115. package/dist/serialization/reducers/common.js +417 -0
  116. package/dist/serialization/reducers/step-function.d.ts +35 -0
  117. package/dist/serialization/reducers/step-function.d.ts.map +1 -0
  118. package/dist/serialization/reducers/step-function.js +88 -0
  119. package/dist/serialization/step.d.ts +17 -0
  120. package/dist/serialization/step.d.ts.map +1 -0
  121. package/dist/serialization/step.js +45 -0
  122. package/dist/serialization/types.d.ts +228 -0
  123. package/dist/serialization/types.d.ts.map +1 -0
  124. package/dist/serialization/types.js +21 -0
  125. package/dist/serialization/workflow.d.ts +29 -0
  126. package/dist/serialization/workflow.d.ts.map +1 -0
  127. package/dist/serialization/workflow.js +54 -0
  128. package/dist/serialization-format.d.ts +16 -2
  129. package/dist/serialization-format.d.ts.map +1 -1
  130. package/dist/serialization-format.js +103 -5
  131. package/dist/serialization.d.ts +217 -226
  132. package/dist/serialization.d.ts.map +1 -1
  133. package/dist/serialization.js +956 -645
  134. package/dist/set-attributes.d.ts +13 -0
  135. package/dist/set-attributes.d.ts.map +1 -0
  136. package/dist/set-attributes.js +40 -0
  137. package/dist/sleep.d.ts.map +1 -1
  138. package/dist/sleep.js +3 -2
  139. package/dist/source-map.d.ts.map +1 -1
  140. package/dist/source-map.js +44 -6
  141. package/dist/step/context-storage.d.ts +16 -0
  142. package/dist/step/context-storage.d.ts.map +1 -1
  143. package/dist/step/context-storage.js +1 -1
  144. package/dist/step/get-closure-vars.d.ts.map +1 -1
  145. package/dist/step/get-closure-vars.js +3 -2
  146. package/dist/step/get-step-metadata.d.ts.map +1 -1
  147. package/dist/step/get-step-metadata.js +3 -2
  148. package/dist/step/get-workflow-metadata.d.ts.map +1 -1
  149. package/dist/step/get-workflow-metadata.js +3 -2
  150. package/dist/step/writable-stream.d.ts.map +1 -1
  151. package/dist/step/writable-stream.js +44 -4
  152. package/dist/step.d.ts.map +1 -1
  153. package/dist/step.js +97 -19
  154. package/dist/symbols.d.ts +26 -0
  155. package/dist/symbols.d.ts.map +1 -1
  156. package/dist/symbols.js +27 -1
  157. package/dist/telemetry/semantic-conventions.d.ts +2 -2
  158. package/dist/telemetry/semantic-conventions.js +1 -1
  159. package/dist/telemetry.js +1 -1
  160. package/dist/types.d.ts +6 -0
  161. package/dist/types.d.ts.map +1 -1
  162. package/dist/types.js +23 -1
  163. package/dist/util.d.ts +18 -3
  164. package/dist/util.d.ts.map +1 -1
  165. package/dist/util.js +28 -5
  166. package/dist/version.d.ts +1 -1
  167. package/dist/version.d.ts.map +1 -1
  168. package/dist/version.js +2 -2
  169. package/dist/vm/index.d.ts.map +1 -1
  170. package/dist/vm/index.js +3 -2
  171. package/dist/vm/uint8array-base64.js +1 -1
  172. package/dist/vm/uuid.js +1 -1
  173. package/dist/workflow/abort-controller.d.ts +65 -0
  174. package/dist/workflow/abort-controller.d.ts.map +1 -0
  175. package/dist/workflow/abort-controller.js +260 -0
  176. package/dist/workflow/create-hook.d.ts.map +1 -1
  177. package/dist/workflow/create-hook.js +3 -2
  178. package/dist/workflow/define-hook.d.ts +1 -1
  179. package/dist/workflow/define-hook.d.ts.map +1 -1
  180. package/dist/workflow/define-hook.js +8 -4
  181. package/dist/workflow/get-workflow-metadata.d.ts.map +1 -1
  182. package/dist/workflow/get-workflow-metadata.js +14 -3
  183. package/dist/workflow/hook.d.ts.map +1 -1
  184. package/dist/workflow/hook.js +13 -4
  185. package/dist/workflow/index.d.ts +1 -0
  186. package/dist/workflow/index.d.ts.map +1 -1
  187. package/dist/workflow/index.js +5 -3
  188. package/dist/workflow/set-attributes.d.ts +74 -0
  189. package/dist/workflow/set-attributes.d.ts.map +1 -0
  190. package/dist/workflow/set-attributes.js +66 -0
  191. package/dist/workflow/sleep.d.ts.map +1 -1
  192. package/dist/workflow/sleep.js +22 -3
  193. package/dist/workflow/world-init-stub.d.ts +15 -0
  194. package/dist/workflow/world-init-stub.d.ts.map +1 -0
  195. package/dist/workflow/world-init-stub.js +15 -0
  196. package/dist/workflow/writable-stream.js +1 -1
  197. package/dist/workflow.d.ts.map +1 -1
  198. package/dist/workflow.js +83 -31
  199. package/docs/api-reference/create-webhook.mdx +37 -18
  200. package/docs/api-reference/experimental-set-attributes.mdx +63 -0
  201. package/docs/api-reference/get-workflow-metadata.mdx +34 -0
  202. package/docs/api-reference/index.mdx +3 -0
  203. package/docs/foundations/cancellation.mdx +460 -0
  204. package/docs/foundations/errors-and-retries.mdx +7 -3
  205. package/docs/foundations/index.mdx +3 -3
  206. package/docs/foundations/meta.json +3 -2
  207. package/docs/foundations/serialization.mdx +78 -42
  208. package/docs/foundations/starting-workflows.mdx +6 -2
  209. package/docs/foundations/versioning.mdx +263 -0
  210. package/docs/how-it-works/cancellation.mdx +287 -0
  211. package/docs/how-it-works/code-transform.mdx +2 -2
  212. package/docs/how-it-works/event-sourcing.mdx +2 -2
  213. package/docs/how-it-works/meta.json +2 -1
  214. package/package.json +16 -7
  215. package/docs/foundations/common-patterns.mdx +0 -265
@@ -1,161 +1,39 @@
1
- import { types } from 'node:util';
2
- import { WorkflowRuntimeError } from '@workflow/errors';
3
- import { WORKFLOW_DESERIALIZE, WORKFLOW_SERIALIZE } from '@workflow/serde';
4
- import { DevalueError, parse, stringify, unflatten } from 'devalue';
1
+ import { RuntimeDecryptionError, SerializationError, WorkflowRuntimeError, } from '@workflow/errors';
2
+ import { parse, stringify, unflatten } from 'devalue';
5
3
  import { monotonicFactory } from 'ulid';
6
- import { getSerializationClass } from './class-serialization.js';
7
- import { decrypt as aesGcmDecrypt, encrypt as aesGcmEncrypt, } from './encryption.js';
4
+ import { decrypt as aesGcmDecrypt, encrypt as aesGcmEncrypt, importKey, } from './encryption.js';
8
5
  import { createFlushableState, flushablePipe, pollReadableLock, pollWritableLock, } from './flushable-stream.js';
9
- import { runtimeLogger } from './logger.js';
10
6
  import { getStepFunction } from './private.js';
11
- import { getWorld } from './runtime/world.js';
7
+ // V2: use getWorldLazy in step-side code paths so Turbopack can statically
8
+ // resolve the world bridge from the step bundle without dragging the full
9
+ // world.ts module (and its dynamic-import behaviour) into the flow route.
10
+ // See `packages/core/src/runtime/get-world-lazy.ts` and the
11
+ // "Turbopack NFT Tracing Errors in V2 Combined Flow Route" section of
12
+ // `docs/content/docs/changelog/eager-processing.mdx`.
13
+ import { getWorldLazy } from './runtime/get-world-lazy.js';
14
+ import * as clientModule from './serialization/client.js';
15
+ import { decrypt, encrypt, } from './serialization/encryption.js';
16
+ import { formatSerializationError, rethrowIfRuntimeError, } from './serialization/errors.js';
17
+ import { decodeFormatPrefix, encodeWithFormatPrefix, isEncrypted, peekFormatPrefix, } from './serialization/format.js';
18
+ import { getClassReducers, getClassRevivers, } from './serialization/reducers/class.js';
19
+ import { getCommonReducers, getCommonRevivers as getCommonReviversFromModule, revive, } from './serialization/reducers/common.js';
20
+ import { getStepFunctionReducer, getStepFunctionReviver, } from './serialization/reducers/step-function.js';
21
+ import * as stepModule from './serialization/step.js';
22
+ import { isFormatPrefix, SerializationFormat, } from './serialization/types.js';
23
+ import * as workflowModule from './serialization/workflow.js';
12
24
  import { contextStorage } from './step/context-storage.js';
13
- import { BODY_INIT_SYMBOL, STABLE_ULID, STREAM_NAME_SYMBOL, STREAM_TYPE_SYMBOL, WEBHOOK_RESPONSE_WRITABLE, } from './symbols.js';
14
- // ============================================================================
15
- // Serialization Format Prefix System
16
- // ============================================================================
17
- //
18
- // All serialized payloads are prefixed with a 4-byte format identifier that
19
- // allows the client to determine how to decode the payload. This enables:
20
- //
21
- // 1. Self-describing payloads - The World layer is agnostic to serialization format
22
- // 2. Gradual migration - Old runs keep working, new runs can use new formats
23
- // 3. Composability - Encryption can wrap any format (e.g., "encr" wrapping "devl")
24
- // 4. Debugging - Raw data inspection immediately reveals the format
25
- //
26
- // Format: [4 bytes: format identifier][payload]
27
- //
28
- // The 4-character prefix convention matches other workflow IDs (wrun, step, wait, etc.)
29
- //
30
- // Current formats:
31
- // - "devl" - devalue stringify/parse with TextEncoder/TextDecoder (current default)
32
- // - "encr" - Encrypted payload (inner payload has its own format prefix)
33
- //
34
- // Future formats (reserved):
35
- // - "cbor" - CBOR binary serialization
36
- /**
37
- * Known serialization format identifiers.
38
- * Each format ID is exactly 4 ASCII characters, matching the convention
39
- * used for other workflow IDs (wrun, step, wait, etc.)
40
- */
41
- export const SerializationFormat = {
42
- /** devalue stringify/parse with TextEncoder/TextDecoder */
43
- DEVALUE_V1: 'devl',
44
- /** Encrypted payload (inner payload has its own format prefix) */
45
- ENCRYPTED: 'encr',
46
- };
47
- /** Length of the format prefix in bytes */
48
- const FORMAT_PREFIX_LENGTH = 4;
49
- /** TextEncoder instance for format prefix encoding */
50
- const formatEncoder = new TextEncoder();
51
- /** TextDecoder instance for format prefix decoding */
52
- const formatDecoder = new TextDecoder();
53
- /**
54
- * Encode a payload with a format prefix.
55
- *
56
- * @param format - The format identifier (must be exactly 4 ASCII characters)
57
- * @param payload - The serialized payload bytes
58
- * @returns A new Uint8Array with format prefix prepended
59
- */
60
- export function encodeWithFormatPrefix(format, payload) {
61
- if (!(payload instanceof Uint8Array)) {
62
- return payload;
63
- }
64
- const prefixBytes = formatEncoder.encode(format);
65
- if (prefixBytes.length !== FORMAT_PREFIX_LENGTH) {
66
- throw new Error(`Format identifier must be exactly ${FORMAT_PREFIX_LENGTH} ASCII characters, got "${format}" (${prefixBytes.length} bytes)`);
67
- }
68
- const result = new Uint8Array(FORMAT_PREFIX_LENGTH + payload.length);
69
- result.set(prefixBytes, 0);
70
- result.set(payload, FORMAT_PREFIX_LENGTH);
71
- return result;
72
- }
73
- /**
74
- * Peek at the format prefix without consuming it.
75
- * Useful for checking if data is encrypted before deciding how to process it.
76
- *
77
- * @param data - The format-prefixed data
78
- * @returns The format identifier, or null if data is legacy/non-binary
79
- */
80
- export function peekFormatPrefix(data) {
81
- if (!(data instanceof Uint8Array) || data.length < FORMAT_PREFIX_LENGTH) {
82
- return null;
83
- }
84
- const prefixBytes = data.subarray(0, FORMAT_PREFIX_LENGTH);
85
- const format = formatDecoder.decode(prefixBytes);
86
- const knownFormats = Object.values(SerializationFormat);
87
- if (!knownFormats.includes(format)) {
88
- return null;
89
- }
90
- return format;
91
- }
92
- /**
93
- * Check if data is encrypted (has 'encr' format prefix).
94
- *
95
- * @param data - The format-prefixed data
96
- * @returns true if data has the encrypted format prefix
97
- */
98
- export function isEncrypted(data) {
99
- return peekFormatPrefix(data) === SerializationFormat.ENCRYPTED;
100
- }
101
- /**
102
- * Decode a format-prefixed payload.
103
- *
104
- * @param data - The format-prefixed data
105
- * @returns An object with the format identifier and payload
106
- * @throws Error if the data is too short or has an unknown format
107
- */
108
- export function decodeFormatPrefix(data) {
109
- // Compat for legacy specVersion 1 runs that don't have a format prefix,
110
- // and don't have a binary payload
111
- if (!(data instanceof Uint8Array)) {
112
- return {
113
- format: SerializationFormat.DEVALUE_V1,
114
- payload: new TextEncoder().encode(JSON.stringify(data)),
115
- };
116
- }
117
- if (data.length < FORMAT_PREFIX_LENGTH) {
118
- throw new Error(`Data too short to contain format prefix: expected at least ${FORMAT_PREFIX_LENGTH} bytes, got ${data.length}`);
119
- }
120
- const prefixBytes = data.subarray(0, FORMAT_PREFIX_LENGTH);
121
- const format = formatDecoder.decode(prefixBytes);
122
- // Validate the format is known
123
- const knownFormats = Object.values(SerializationFormat);
124
- if (!knownFormats.includes(format)) {
125
- throw new WorkflowRuntimeError(`Unknown serialization format: "${format}". Known formats: ${knownFormats.join(', ')}`);
126
- }
127
- const payload = data.subarray(FORMAT_PREFIX_LENGTH);
128
- return { format: format, payload };
129
- }
25
+ import { ABORT_HOOK_TOKEN, ABORT_LISTENER_ATTACHED, ABORT_READER_CANCEL, ABORT_STREAM_NAME, BODY_INIT_SYMBOL, STABLE_ULID, STREAM_NAME_SYMBOL, STREAM_SERVER_DEPLOYMENT_ID_SYMBOL, STREAM_SERVER_RUN_ID_SYMBOL, STREAM_TYPE_SYMBOL, WEBHOOK_RESPONSE_WRITABLE, } from './symbols.js';
26
+ import { getAbortStreamId } from './util.js';
27
+ import { WorkflowAbortSignal } from './workflow/abort-controller.js';
28
+ // Re-export types and utilities from the modular serialization modules
29
+ // so existing consumers of `@workflow/core/serialization` keep working.
30
+ export { SerializationFormat, isFormatPrefix, encodeWithFormatPrefix, decodeFormatPrefix, peekFormatPrefix, isEncrypted, encrypt, decrypt, };
130
31
  /**
131
32
  * Default ULID generator for contexts where VM's seeded `stableUlid` isn't available.
132
33
  * Used as a fallback when serializing streams outside the workflow VM context
133
34
  * (e.g., when starting a workflow or handling step return values).
134
35
  */
135
36
  const defaultUlid = monotonicFactory();
136
- /**
137
- * Format a serialization error with context about what failed.
138
- * Extracts path, value, and reason from devalue's DevalueError when available.
139
- * Logs the problematic value to the console for better debugging.
140
- */
141
- function formatSerializationError(context, error) {
142
- // Use "returning" for return values, "passing" for arguments/inputs
143
- const verb = context.includes('return value') ? 'returning' : 'passing';
144
- // Build the error message with path info if available from DevalueError
145
- let message = `Failed to serialize ${context}`;
146
- if (error instanceof DevalueError && error.path) {
147
- message += ` at path "${error.path}"`;
148
- }
149
- message += `. Ensure you're ${verb} serializable types (plain objects, arrays, primitives, Date, RegExp, Map, Set).`;
150
- // Log the problematic value for debugging
151
- if (error instanceof DevalueError && error.value !== undefined) {
152
- runtimeLogger.error('Serialization failed', {
153
- context,
154
- problematicValue: error.value,
155
- });
156
- }
157
- return message;
158
- }
159
37
  /**
160
38
  * Detect if a readable stream is a byte stream.
161
39
  *
@@ -179,6 +57,33 @@ export function getStreamType(stream) {
179
57
  * split across transport reads.
180
58
  */
181
59
  const FRAME_HEADER_SIZE = 4;
60
+ /**
61
+ * The mode-specific serializers (`./serialization/{client,step,workflow}.ts`)
62
+ * already throw a `SerializationError` whose `.cause` is the underlying
63
+ * devalue / serde failure. The outer dehydrate/hydrate wrappers want to
64
+ * re-frame that error with a more specific context label (e.g. "workflow
65
+ * arguments" instead of generic "workflow value"), so they unwrap the
66
+ * inner SerializationError and reformat with the original cause. Errors
67
+ * that aren't already SerializationError flow through unchanged.
68
+ *
69
+ * `RuntimeDecryptionError` is an exception: it must keep its identity (and
70
+ * `context`) so the run-failure classifier routes it to `RUNTIME_ERROR`,
71
+ * so this rethrows it unchanged before any unwrapping. Note this guard
72
+ * must run before the generic `WorkflowRuntimeError` unwrap below, since
73
+ * `RuntimeDecryptionError` extends `WorkflowRuntimeError` and carries a
74
+ * `cause` (the underlying DOMException) that would otherwise be unwrapped
75
+ * and reframed as a `SerializationError`.
76
+ */
77
+ function unwrapSerializationCause(error) {
78
+ rethrowIfRuntimeError(error);
79
+ if (error instanceof SerializationError && error.cause !== undefined) {
80
+ return error.cause;
81
+ }
82
+ if (error instanceof WorkflowRuntimeError && error.cause !== undefined) {
83
+ return error.cause;
84
+ }
85
+ return error;
86
+ }
182
87
  export function getSerializeStream(reducers, cryptoKey) {
183
88
  const encoder = new TextEncoder();
184
89
  // Resolve the key promise once on first use and cache the result.
@@ -210,7 +115,15 @@ export function getSerializeStream(reducers, cryptoKey) {
210
115
  controller.enqueue(frame);
211
116
  }
212
117
  catch (error) {
213
- controller.error(new WorkflowRuntimeError(formatSerializationError('stream chunk', error), { slug: 'serialization-failed', cause: error }));
118
+ // Encryption failures must keep their RuntimeDecryptionError
119
+ // identity (RUNTIME_ERROR) rather than be reframed as a
120
+ // SerializationError (USER_ERROR).
121
+ if (RuntimeDecryptionError.is(error)) {
122
+ controller.error(error);
123
+ return;
124
+ }
125
+ const { message, hint } = formatSerializationError('stream chunk', error);
126
+ controller.error(new SerializationError(message, { hint, cause: error }));
214
127
  }
215
128
  },
216
129
  });
@@ -247,11 +160,30 @@ export function getDeserializeStream(revivers, cryptoKey) {
247
160
  // then fall through to the normal deserialization path.
248
161
  if (format === SerializationFormat.ENCRYPTED) {
249
162
  if (!keyState.key) {
250
- controller.error(new WorkflowRuntimeError('Encrypted stream data encountered but no encryption key is available. ' +
251
- 'Encryption is not configured or no key was provided for this run.'));
163
+ controller.error(new RuntimeDecryptionError('Encrypted stream data encountered but no encryption key is available. ' +
164
+ 'Encryption is not configured or no key was provided for this run.', {
165
+ context: {
166
+ operation: 'decrypt',
167
+ byteLength: payload.byteLength,
168
+ formatPrefix: 'encr',
169
+ },
170
+ }));
252
171
  return;
253
172
  }
254
- const decrypted = await aesGcmDecrypt(keyState.key, payload);
173
+ let decrypted;
174
+ try {
175
+ decrypted = await aesGcmDecrypt(keyState.key, payload);
176
+ }
177
+ catch (error) {
178
+ // The low-level AES layer only sees the stripped payload, so it
179
+ // cannot record the outer envelope prefix. We peeked it here
180
+ // (`encr`), so enrich the diagnostic context with the real format
181
+ // prefix before propagating — mirroring serialization/encryption.ts.
182
+ if (RuntimeDecryptionError.is(error) && error.context) {
183
+ error.context.formatPrefix = format;
184
+ }
185
+ throw error;
186
+ }
255
187
  ({ format, payload } = decodeFormatPrefix(decrypted));
256
188
  }
257
189
  if (format === SerializationFormat.DEVALUE_V1) {
@@ -303,7 +235,7 @@ export class WorkflowServerReadableStream extends ReadableStream {
303
235
  #reader;
304
236
  constructor(runId, name, startIndex) {
305
237
  if (typeof name !== 'string' || name.length === 0) {
306
- throw new Error(`"name" is required, got "${name}"`);
238
+ throw new WorkflowRuntimeError(`"name" is required, got "${name}"`);
307
239
  }
308
240
  super({
309
241
  // @ts-expect-error Not sure why TypeScript is complaining about this
@@ -311,7 +243,7 @@ export class WorkflowServerReadableStream extends ReadableStream {
311
243
  pull: async (controller) => {
312
244
  let reader = this.#reader;
313
245
  if (!reader) {
314
- const world = await getWorld();
246
+ const world = await getWorldLazy();
315
247
  const stream = await world.streams.get(runId, name, startIndex);
316
248
  reader = this.#reader = stream.getReader();
317
249
  }
@@ -347,12 +279,12 @@ const STREAM_FLUSH_INTERVAL_MS = 10;
347
279
  export class WorkflowServerWritableStream extends WritableStream {
348
280
  constructor(runId, name) {
349
281
  if (typeof runId !== 'string') {
350
- throw new Error(`"runId" must be a string, got "${typeof runId}"`);
282
+ throw new WorkflowRuntimeError(`"runId" must be a string, got "${typeof runId}"`);
351
283
  }
352
284
  if (typeof name !== 'string' || name.length === 0) {
353
- throw new Error(`"name" is required, got "${name}"`);
285
+ throw new WorkflowRuntimeError(`"name" is required, got "${name}"`);
354
286
  }
355
- const worldPromise = getWorld();
287
+ const worldPromise = getWorldLazy();
356
288
  // Buffering state for batched writes
357
289
  // Encryption/decryption is handled at the framing level by
358
290
  // getSerializeStream/getDeserializeStream, not here.
@@ -457,113 +389,22 @@ export class WorkflowServerWritableStream extends WritableStream {
457
389
  });
458
390
  }
459
391
  }
460
- function revive(str) {
461
- // biome-ignore lint/security/noGlobalEval: Eval is safe here - we are only passing value from `devalue.stringify()`
462
- // biome-ignore lint/complexity/noCommaOperator: This is how you do global scope eval
463
- return (0, eval)(`(${str})`);
464
- }
465
- function getCommonReducers(global = globalThis) {
466
- const abToBase64 = (value, offset, length) => {
467
- // Avoid returning falsy value for zero-length buffers
468
- if (length === 0)
469
- return '.';
470
- // Create a proper copy to avoid ArrayBuffer detachment issues
471
- // Buffer.from(ArrayBuffer, offset, length) creates a view, not a copy
472
- const uint8 = new Uint8Array(value, offset, length);
473
- return Buffer.from(uint8).toString('base64');
474
- };
475
- const viewToBase64 = (value) => abToBase64(value.buffer, value.byteOffset, value.byteLength);
392
+ // ---- Composed reducers ----
393
+ // Composes modular reducers (common, class, step-function) with
394
+ // mode-specific Request/Response/Stream reducers below.
395
+ /**
396
+ * Base reducers shared across all serialization boundaries.
397
+ * Composes: class + step-function + common reducers from the modular modules.
398
+ */
399
+ function getAllBaseReducers(global = globalThis) {
400
+ // Class/Instance MUST come before Error so that custom Error subclasses
401
+ // with WORKFLOW_SERIALIZE take precedence (devalue uses first-match-wins).
476
402
  return {
477
- ArrayBuffer: (value) => value instanceof global.ArrayBuffer &&
478
- abToBase64(value, 0, value.byteLength),
479
- BigInt: (value) => typeof value === 'bigint' && value.toString(),
480
- BigInt64Array: (value) => value instanceof global.BigInt64Array && viewToBase64(value),
481
- BigUint64Array: (value) => value instanceof global.BigUint64Array && viewToBase64(value),
482
- // Class and Instance are intentionally placed before Error so that
483
- // custom Error subclasses with WORKFLOW_SERIALIZE take precedence
484
- // over the generic Error serialization (devalue uses first-match-wins).
485
- Class: (value) => {
486
- // Check if this is a class constructor with a classId property
487
- // (set by the SWC plugin for classes with static step/workflow methods)
488
- if (typeof value !== 'function')
489
- return false;
490
- const classId = value.classId;
491
- if (typeof classId !== 'string')
492
- return false;
493
- return { classId };
494
- },
495
- Instance: (value) => {
496
- // Check if this is an instance of a class with custom serialization
497
- if (value === null || typeof value !== 'object')
498
- return false;
499
- const cls = value.constructor;
500
- if (!cls || typeof cls !== 'function')
501
- return false;
502
- // Check if the class has a static WORKFLOW_SERIALIZE method
503
- const serialize = cls[WORKFLOW_SERIALIZE];
504
- if (typeof serialize !== 'function') {
505
- return false;
506
- }
507
- // Get the classId from the static class property (set by SWC plugin)
508
- const classId = cls.classId;
509
- if (typeof classId !== 'string') {
510
- throw new Error(`Class "${cls.name}" with ${String(WORKFLOW_SERIALIZE)} must have a static "classId" property.`);
511
- }
512
- // Serialize the instance using the custom serializer
513
- const data = serialize.call(cls, value);
514
- return { classId, data };
515
- },
516
- Date: (value) => {
517
- if (!(value instanceof global.Date))
518
- return false;
519
- const valid = !Number.isNaN(value.getDate());
520
- // Note: "." is to avoid returning a falsy value when the date is invalid
521
- return valid ? value.toISOString() : '.';
522
- },
523
- // DOMException is a special case: in Node.js it passes isNativeError()
524
- // and instanceof Error, but has a unique constructor signature
525
- // (message, name) and a read-only numeric `code` property derived from
526
- // `name`. It must be checked before the generic Error reducer.
527
- DOMException: (value) => {
528
- if (!types.isNativeError(value))
529
- return false;
530
- if (value.constructor?.name !== 'DOMException')
531
- return false;
532
- const reduced = {
533
- message: value.message,
534
- name: value.name,
535
- stack: value.stack,
536
- };
537
- if ('cause' in value)
538
- reduced.cause = value.cause;
539
- return reduced;
540
- },
541
- Error: (value) => {
542
- // Use types.isNativeError() instead of `instanceof global.Error`
543
- // because errors may originate from a different VM context (e.g.
544
- // FatalError from the host context passed into a VM-context workflow).
545
- // `instanceof` checks fail across VM boundaries since each context
546
- // has its own Error constructor, but isNativeError() uses V8's
547
- // internal type tag which works across all contexts.
548
- if (!types.isNativeError(value))
549
- return false;
550
- return {
551
- name: value.name,
552
- message: value.message,
553
- stack: value.stack,
554
- };
555
- },
556
- Float32Array: (value) => value instanceof global.Float32Array && viewToBase64(value),
557
- Float64Array: (value) => value instanceof global.Float64Array && viewToBase64(value),
558
- Headers: (value) => value instanceof global.Headers && Array.from(value),
559
- Int8Array: (value) => value instanceof global.Int8Array && viewToBase64(value),
560
- Int16Array: (value) => value instanceof global.Int16Array && viewToBase64(value),
561
- Int32Array: (value) => value instanceof global.Int32Array && viewToBase64(value),
562
- Map: (value) => value instanceof global.Map && Array.from(value),
563
- RegExp: (value) => value instanceof global.RegExp && {
564
- source: value.source,
565
- flags: value.flags,
566
- },
403
+ ...getClassReducers(),
404
+ ...getStepFunctionReducer(),
405
+ ...getCommonReducers(global),
406
+ // Request and Response reducers are mode-specific and added by
407
+ // getExternalReducers / getWorkflowReducers / getStepReducers below.
567
408
  Request: (value) => {
568
409
  if (!(value instanceof global.Request))
569
410
  return false;
@@ -578,6 +419,20 @@ function getCommonReducers(global = globalThis) {
578
419
  if (responseWritable) {
579
420
  data.responseWritable = responseWritable;
580
421
  }
422
+ // Forward the signal in two cases:
423
+ // 1. Already aborted — preserve aborted=true/reason so the hydrated
424
+ // step sees the cancellation that happened before serialize.
425
+ // 2. Already tagged with workflow infrastructure — i.e. a signal
426
+ // from a workflow-managed AbortController, which has stream/hook
427
+ // backing for cross-boundary propagation.
428
+ // Plain non-aborted native signals are intentionally dropped (would
429
+ // mint stream infra for every Request, including the auto-generated
430
+ // signal on `new Request(url)`).
431
+ if (value.signal &&
432
+ (value.signal.aborted ||
433
+ value.signal[ABORT_STREAM_NAME])) {
434
+ data.signal = value.signal;
435
+ }
581
436
  return data;
582
437
  },
583
438
  Response: (value) => {
@@ -593,50 +448,89 @@ function getCommonReducers(global = globalThis) {
593
448
  redirected: value.redirected,
594
449
  };
595
450
  },
596
- Set: (value) => value instanceof global.Set && Array.from(value),
597
- StepFunction: (value) => {
598
- if (typeof value !== 'function')
599
- return false;
600
- const stepId = value.stepId;
601
- if (typeof stepId !== 'string')
602
- return false;
603
- // Check if the step function has closure variables
604
- const closureVarsFn = value.__closureVarsFn;
605
- if (closureVarsFn && typeof closureVarsFn === 'function') {
606
- // Invoke the closure variables function and serialize along with stepId
607
- const closureVars = closureVarsFn();
608
- return { stepId, closureVars };
609
- }
610
- // No closure variables - return object with just stepId
611
- return { stepId };
612
- },
613
- URL: (value) => value instanceof global.URL && value.href,
614
- WorkflowFunction: (value) => {
615
- // Only match function references with a workflowId property (set by
616
- // the SWC compiler on workflow functions). Plain { workflowId } objects
617
- // are NOT matched — this prevents infinite recursion since the reduced
618
- // form { workflowId } is a plain object, not a function.
619
- if (typeof value !== 'function')
620
- return false;
621
- const workflowId = value.workflowId;
622
- if (typeof workflowId !== 'string')
623
- return false;
624
- return { workflowId };
625
- },
626
- URLSearchParams: (value) => {
627
- if (!(value instanceof global.URLSearchParams))
628
- return false;
629
- // Avoid returning a falsy value when the URLSearchParams is empty
630
- if (value.size === 0)
631
- return '.';
632
- return String(value);
633
- },
634
- Uint8Array: (value) => value instanceof global.Uint8Array && viewToBase64(value),
635
- Uint8ClampedArray: (value) => value instanceof global.Uint8ClampedArray && viewToBase64(value),
636
- Uint16Array: (value) => value instanceof global.Uint16Array && viewToBase64(value),
637
- Uint32Array: (value) => value instanceof global.Uint32Array && viewToBase64(value),
638
451
  };
639
452
  }
453
+ /**
454
+ * Shared logic for AbortController/AbortSignal reducers in external and step
455
+ * contexts. Assigns stream/hook names if not already present, optionally
456
+ * attaches an abort listener for real-time propagation, and returns the
457
+ * serialized representation.
458
+ */
459
+ function reduceAbortWithListener(signal, holder, global, ops, runId, cryptoKey) {
460
+ let streamName = holder[ABORT_STREAM_NAME];
461
+ let hookToken = holder[ABORT_HOOK_TOKEN];
462
+ if (!streamName) {
463
+ const id = (global[STABLE_ULID] || defaultUlid)();
464
+ streamName = getAbortStreamId(id);
465
+ hookToken = `abrt_${id}`;
466
+ holder[ABORT_STREAM_NAME] = streamName;
467
+ holder[ABORT_HOOK_TOKEN] = hookToken;
468
+ if (holder.signal) {
469
+ holder.signal[ABORT_STREAM_NAME] = streamName;
470
+ holder.signal[ABORT_HOOK_TOKEN] = hookToken;
471
+ }
472
+ }
473
+ // Deduped via ABORT_LISTENER_ATTACHED marker — see attachAbortListenerOnce.
474
+ attachAbortListenerOnce(signal, streamName, runId, cryptoKey, ops);
475
+ return {
476
+ streamName,
477
+ hookToken: hookToken,
478
+ aborted: signal.aborted,
479
+ reason: signal.aborted ? signal.reason : undefined,
480
+ };
481
+ }
482
+ /**
483
+ * Shared logic for AbortController/AbortSignal reducers in workflow context.
484
+ * Reads existing stream/hook names from symbols (must already be set).
485
+ */
486
+ function reduceAbortBySymbol(signal, holder) {
487
+ const streamName = holder[ABORT_STREAM_NAME] ?? holder.signal?.[ABORT_STREAM_NAME];
488
+ const hookToken = holder[ABORT_HOOK_TOKEN] ?? holder.signal?.[ABORT_HOOK_TOKEN];
489
+ if (!streamName) {
490
+ throw new Error('AbortController/AbortSignal stream name is not set');
491
+ }
492
+ return {
493
+ streamName,
494
+ hookToken: hookToken,
495
+ aborted: signal.aborted,
496
+ reason: signal.aborted ? signal.reason : undefined,
497
+ };
498
+ }
499
+ /**
500
+ * Attach a single abort listener to a signal, deduped across calls.
501
+ *
502
+ * Each serialization pass goes through the reducer, but a controller passed
503
+ * to N steps would otherwise accumulate N listeners — each writing the same
504
+ * stream packet and double-closing the stream on abort. The marker symbol
505
+ * ensures the stream-write side-effect runs at most once per (signal, runId).
506
+ */
507
+ function attachAbortListenerOnce(signal, streamName, runId, cryptoKey, ops) {
508
+ if (signal.aborted)
509
+ return;
510
+ if (signal[ABORT_LISTENER_ATTACHED])
511
+ return;
512
+ signal[ABORT_LISTENER_ATTACHED] = true;
513
+ signal.addEventListener('abort', () => {
514
+ ops.push((async () => {
515
+ try {
516
+ // Dehydrate via the same machinery the reader uses (hydrateStepArguments)
517
+ // so the reason round-trips with full type fidelity (DOMException,
518
+ // Errors, custom classes, etc.) and respects the run's encryption key.
519
+ // A bare JSON.stringify here would write a packet the reader can't
520
+ // decode and the listener-side abort would propagate with no reason.
521
+ const key = await cryptoKey;
522
+ const payload = await dehydrateStepArguments({ aborted: true, reason: signal.reason }, runId, key);
523
+ const writable = new WorkflowServerWritableStream(runId, streamName);
524
+ const writer = writable.getWriter();
525
+ await writer.write(payload);
526
+ await writer.close();
527
+ }
528
+ catch {
529
+ // Best-effort stream write
530
+ }
531
+ })());
532
+ }, { once: true });
533
+ }
640
534
  /**
641
535
  * Reducers for serialization boundary from the client side, passing arguments
642
536
  * to the workflow handler.
@@ -647,13 +541,15 @@ function getCommonReducers(global = globalThis) {
647
541
  */
648
542
  export function getExternalReducers(global = globalThis, ops, runId, cryptoKey) {
649
543
  return {
650
- ...getCommonReducers(global),
544
+ ...getAllBaseReducers(global),
651
545
  ReadableStream: (value) => {
652
546
  if (!(value instanceof global.ReadableStream))
653
547
  return false;
654
548
  // Stream must not be locked when passing across execution boundary
655
549
  if (value.locked) {
656
- throw new Error('ReadableStream is locked');
550
+ throw new SerializationError('ReadableStream is locked and cannot be passed across a workflow boundary.', {
551
+ hint: 'Pass the stream before calling .getReader() / .pipeThrough() / .pipeTo(), or tee it with .tee() and pass one of the branches.',
552
+ });
657
553
  }
658
554
  const streamId = (global[STABLE_ULID] || defaultUlid)();
659
555
  const name = `strm_${streamId}`;
@@ -675,12 +571,49 @@ export function getExternalReducers(global = globalThis, ops, runId, cryptoKey)
675
571
  WritableStream: (value) => {
676
572
  if (!(value instanceof global.WritableStream))
677
573
  return false;
574
+ // Fast path: when the writable is already backed by a workflow
575
+ // server stream (e.g. it came from a step-context `getWritable()`
576
+ // or was hydrated from a workflow input by `getStepRevivers`),
577
+ // forward its underlying `(runId, name)` to the receiving run.
578
+ // The receiving run's step-side reviver opens a server writable
579
+ // against the original `(runId, name)` and resolves that run's
580
+ // encryption key directly, so writes land on the original stream
581
+ // for the full lifetime of the receiving run — no in-process
582
+ // bridge tied to the dehydrating step's lifetime.
583
+ const existingName = value[STREAM_NAME_SYMBOL];
584
+ const existingRunId = value[STREAM_SERVER_RUN_ID_SYMBOL];
585
+ if (typeof existingName === 'string' &&
586
+ typeof existingRunId === 'string') {
587
+ const descriptor = {
588
+ name: existingName,
589
+ runId: existingRunId,
590
+ };
591
+ const existingDeploymentId = value[STREAM_SERVER_DEPLOYMENT_ID_SYMBOL];
592
+ if (typeof existingDeploymentId === 'string') {
593
+ descriptor.deploymentId = existingDeploymentId;
594
+ }
595
+ return descriptor;
596
+ }
678
597
  const streamId = (global[STABLE_ULID] || defaultUlid)();
679
598
  const name = `strm_${streamId}`;
680
599
  const readable = new WorkflowServerReadableStream(runId, name);
681
600
  ops.push(readable.pipeTo(value));
682
601
  return { name };
683
602
  },
603
+ AbortController: (value) => {
604
+ if (!global.AbortController ||
605
+ typeof global.AbortController !== 'function' ||
606
+ !(value instanceof global.AbortController))
607
+ return false;
608
+ return reduceAbortWithListener(value.signal, value, global, ops, runId, cryptoKey);
609
+ },
610
+ AbortSignal: (value) => {
611
+ if (!global.AbortSignal ||
612
+ typeof global.AbortSignal !== 'function' ||
613
+ !(value instanceof global.AbortSignal))
614
+ return false;
615
+ return reduceAbortWithListener(value, value, global, ops, runId, cryptoKey);
616
+ },
684
617
  };
685
618
  }
686
619
  /**
@@ -692,7 +625,7 @@ export function getExternalReducers(global = globalThis, ops, runId, cryptoKey)
692
625
  */
693
626
  export function getWorkflowReducers(global = globalThis) {
694
627
  return {
695
- ...getCommonReducers(global),
628
+ ...getAllBaseReducers(global),
696
629
  // Readable/Writable streams from within the workflow execution environment
697
630
  // are simply "handles" that can be passed around to other steps.
698
631
  ReadableStream: (value) => {
@@ -707,7 +640,7 @@ export function getWorkflowReducers(global = globalThis) {
707
640
  }
708
641
  const name = value[STREAM_NAME_SYMBOL];
709
642
  if (!name) {
710
- throw new Error('ReadableStream `name` is not set');
643
+ throw new WorkflowRuntimeError('ReadableStream `name` is not set');
711
644
  }
712
645
  const s = { name };
713
646
  const type = value[STREAM_TYPE_SYMBOL];
@@ -720,9 +653,46 @@ export function getWorkflowReducers(global = globalThis) {
720
653
  return false;
721
654
  const name = value[STREAM_NAME_SYMBOL];
722
655
  if (!name) {
723
- throw new Error('WritableStream `name` is not set');
656
+ throw new WorkflowRuntimeError('WritableStream `name` is not set');
724
657
  }
725
- return { name };
658
+ const s = { name };
659
+ // When the handle was forwarded from another run (parent → child
660
+ // via `start()`), preserve the foreign runId so the step-side
661
+ // reviver opens the writable against the original stream.
662
+ const foreignRunId = value[STREAM_SERVER_RUN_ID_SYMBOL];
663
+ if (typeof foreignRunId === 'string')
664
+ s.runId = foreignRunId;
665
+ const foreignDeploymentId = value[STREAM_SERVER_DEPLOYMENT_ID_SYMBOL];
666
+ if (typeof foreignDeploymentId === 'string') {
667
+ s.deploymentId = foreignDeploymentId;
668
+ }
669
+ return s;
670
+ },
671
+ // AbortController/AbortSignal in workflow context — just read symbols (handles).
672
+ // In the workflow VM, global.AbortController is a class but global.AbortSignal
673
+ // is a plain object (not a class), so instanceof checks won't work for signals.
674
+ // Detect instances by the presence of the ABORT_STREAM_NAME symbol instead.
675
+ AbortController: (value) => {
676
+ if (!value || !value.signal)
677
+ return false;
678
+ const holder = value;
679
+ const hasAbortSymbol = holder[ABORT_STREAM_NAME] ?? holder.signal?.[ABORT_STREAM_NAME];
680
+ const isNativeAbortController = global.AbortController &&
681
+ typeof global.AbortController === 'function' &&
682
+ value instanceof global.AbortController;
683
+ if (!hasAbortSymbol && !isNativeAbortController)
684
+ return false;
685
+ return reduceAbortBySymbol(value.signal, holder);
686
+ },
687
+ AbortSignal: (value) => {
688
+ const signal = value;
689
+ const hasAbortSymbol = signal?.[ABORT_STREAM_NAME];
690
+ const isNativeAbortSignal = global.AbortSignal &&
691
+ typeof global.AbortSignal === 'function' &&
692
+ value instanceof global.AbortSignal;
693
+ if (!hasAbortSymbol && !isNativeAbortSignal)
694
+ return false;
695
+ return reduceAbortBySymbol(value, value);
726
696
  },
727
697
  };
728
698
  }
@@ -737,13 +707,15 @@ export function getWorkflowReducers(global = globalThis) {
737
707
  */
738
708
  function getStepReducers(global = globalThis, ops, runId, cryptoKey) {
739
709
  return {
740
- ...getCommonReducers(global),
710
+ ...getAllBaseReducers(global),
741
711
  ReadableStream: (value) => {
742
712
  if (!(value instanceof global.ReadableStream))
743
713
  return false;
744
714
  // Stream must not be locked when passing across execution boundary
745
715
  if (value.locked) {
746
- throw new Error('ReadableStream is locked');
716
+ throw new SerializationError('ReadableStream is locked and cannot be passed across a workflow boundary.', {
717
+ hint: 'Pass the stream before calling .getReader() / .pipeThrough() / .pipeTo(), or tee it with .tee() and pass one of the branches.',
718
+ });
747
719
  }
748
720
  // Check if the stream already has the name symbol set, in which case
749
721
  // it's already being sunk to the server and we can just return the
@@ -773,6 +745,7 @@ function getStepReducers(global = globalThis, ops, runId, cryptoKey) {
773
745
  if (!(value instanceof global.WritableStream))
774
746
  return false;
775
747
  let name = value[STREAM_NAME_SYMBOL];
748
+ const foreignRunId = value[STREAM_SERVER_RUN_ID_SYMBOL];
776
749
  if (!name) {
777
750
  const streamId = (global[STABLE_ULID] || defaultUlid)();
778
751
  name = `strm_${streamId}`;
@@ -780,120 +753,277 @@ function getStepReducers(global = globalThis, ops, runId, cryptoKey) {
780
753
  .pipeThrough(getDeserializeStream(getStepRevivers(global, ops, runId, cryptoKey), cryptoKey))
781
754
  .pipeTo(value));
782
755
  }
783
- return { name };
756
+ const s = { name };
757
+ if (typeof foreignRunId === 'string')
758
+ s.runId = foreignRunId;
759
+ const foreignDeploymentId = value[STREAM_SERVER_DEPLOYMENT_ID_SYMBOL];
760
+ if (typeof foreignDeploymentId === 'string') {
761
+ s.deploymentId = foreignDeploymentId;
762
+ }
763
+ return s;
764
+ },
765
+ AbortController: (value) => {
766
+ if (!global.AbortController ||
767
+ typeof global.AbortController !== 'function' ||
768
+ !(value instanceof global.AbortController))
769
+ return false;
770
+ return reduceAbortWithListener(value.signal, value, global, ops, runId, cryptoKey);
771
+ },
772
+ AbortSignal: (value) => {
773
+ if (!global.AbortSignal ||
774
+ typeof global.AbortSignal !== 'function' ||
775
+ !(value instanceof global.AbortSignal))
776
+ return false;
777
+ return reduceAbortWithListener(value, value, global, ops, runId, cryptoKey);
784
778
  },
785
779
  };
786
780
  }
787
- export function getCommonRevivers(global = globalThis) {
788
- function reviveArrayBuffer(value) {
789
- // Handle sentinel value for zero-length buffers
790
- const base64 = value === '.' ? '' : value;
791
- const buffer = Buffer.from(base64, 'base64');
792
- const arrayBuffer = new global.ArrayBuffer(buffer.length);
793
- const uint8Array = new global.Uint8Array(arrayBuffer);
794
- uint8Array.set(buffer);
795
- return arrayBuffer;
781
+ /**
782
+ * Cancel dangling abort-stream readers on any AbortController instances found
783
+ * in the hydrated step arguments. Called after the step function returns
784
+ * (success or failure) to prevent reader promises from keeping the serverless
785
+ * function alive indefinitely.
786
+ */
787
+ export function cancelAbortReaders(...values) {
788
+ const visited = new WeakSet();
789
+ function cancelIfPresent(val) {
790
+ const cancel = val[ABORT_READER_CANCEL];
791
+ if (cancel && !cancel.signal.aborted) {
792
+ cancel.abort();
793
+ }
796
794
  }
797
- return {
798
- ArrayBuffer: reviveArrayBuffer,
799
- BigInt: (value) => global.BigInt(value),
800
- BigInt64Array: (value) => {
801
- const ab = reviveArrayBuffer(value);
802
- return new global.BigInt64Array(ab);
803
- },
804
- BigUint64Array: (value) => {
805
- const ab = reviveArrayBuffer(value);
806
- return new global.BigUint64Array(ab);
807
- },
808
- Date: (value) => new global.Date(value),
809
- DOMException: (value) => {
810
- const error = new global.DOMException(value.message, value.name);
811
- if (value.stack !== undefined)
812
- error.stack = value.stack;
813
- // DOMException's constructor doesn't accept a cause option, so
814
- // we set it manually when present in the serialized data.
815
- if ('cause' in value)
816
- error.cause = value.cause;
817
- return error;
818
- },
819
- Error: (value) => {
820
- const error = new global.Error(value.message);
821
- error.name = value.name;
822
- error.stack = value.stack;
823
- return error;
824
- },
825
- Float32Array: (value) => {
826
- const ab = reviveArrayBuffer(value);
827
- return new global.Float32Array(ab);
828
- },
829
- Float64Array: (value) => {
830
- const ab = reviveArrayBuffer(value);
831
- return new global.Float64Array(ab);
832
- },
833
- Headers: (value) => new global.Headers(value),
834
- Int8Array: (value) => {
835
- const ab = reviveArrayBuffer(value);
836
- return new global.Int8Array(ab);
837
- },
838
- Int16Array: (value) => {
839
- const ab = reviveArrayBuffer(value);
840
- return new global.Int16Array(ab);
841
- },
842
- Int32Array: (value) => {
843
- const ab = reviveArrayBuffer(value);
844
- return new global.Int32Array(ab);
845
- },
846
- Map: (value) => new global.Map(value),
847
- RegExp: (value) => new global.RegExp(value.source, value.flags),
848
- Class: (value) => {
849
- const classId = value.classId;
850
- // Pass the global object to support VM contexts where classes are registered
851
- // on the VM's global rather than the host's globalThis
852
- const cls = getSerializationClass(classId, global);
853
- if (!cls) {
854
- throw new Error(`Class "${classId}" not found. Make sure the class is registered with registerSerializationClass.`);
855
- }
856
- return cls;
857
- },
858
- Instance: (value) => {
859
- const classId = value.classId;
860
- const data = value.data;
861
- // Look up the class by classId from the registry
862
- // Pass the global object to support VM contexts where classes are registered
863
- // on the VM's global rather than the host's globalThis
864
- const cls = getSerializationClass(classId, global);
865
- if (!cls) {
866
- throw new Error(`Class "${classId}" not found. Make sure the class is registered with registerSerializationClass.`);
795
+ function walk(val) {
796
+ if (val == null || typeof val !== 'object')
797
+ return;
798
+ if (visited.has(val))
799
+ return;
800
+ visited.add(val);
801
+ if (val instanceof AbortController) {
802
+ cancelIfPresent(val);
803
+ cancelIfPresent(val.signal);
804
+ return;
805
+ }
806
+ if (val instanceof AbortSignal) {
807
+ cancelIfPresent(val);
808
+ return;
809
+ }
810
+ if (Array.isArray(val)) {
811
+ for (const item of val)
812
+ walk(item);
813
+ return;
814
+ }
815
+ if (val instanceof Map) {
816
+ for (const v of val.values())
817
+ walk(v);
818
+ return;
819
+ }
820
+ if (val instanceof Set) {
821
+ for (const v of val)
822
+ walk(v);
823
+ return;
824
+ }
825
+ // Request/Response expose `signal`/`body` as prototype getters, so
826
+ // Object.values() won't find them. Descend explicitly.
827
+ if (typeof Request !== 'undefined' && val instanceof Request) {
828
+ walk(val.signal);
829
+ return;
830
+ }
831
+ for (const v of Object.values(val))
832
+ walk(v);
833
+ }
834
+ for (const v of values)
835
+ walk(v);
836
+ }
837
+ /**
838
+ * Sets up a stream reader on the controller that listens for an abort packet.
839
+ * Returns the readerCancel controller so it can be stored on both the
840
+ * controller and signal for cleanup by cancelAbortReaders.
841
+ */
842
+ function setupAbortStreamReader(controller, runId, streamName, ops) {
843
+ const readerCancel = new AbortController();
844
+ ops.push((async () => {
845
+ try {
846
+ const readable = new WorkflowServerReadableStream(runId, streamName);
847
+ const reader = readable.getReader();
848
+ const result = await Promise.race([
849
+ reader.read(),
850
+ new Promise((resolve) => {
851
+ if (readerCancel.signal.aborted) {
852
+ resolve({ value: undefined, done: true });
853
+ return;
854
+ }
855
+ readerCancel.signal.addEventListener('abort', () => resolve({ value: undefined, done: true }), { once: true });
856
+ }),
857
+ ]);
858
+ reader.releaseLock();
859
+ if (result.value && !result.done) {
860
+ try {
861
+ // Hydrate via the same machinery the writer used so the reason
862
+ // round-trips with full type fidelity. Encryption key (if any)
863
+ // comes from the step context — set up by the step handler before
864
+ // this reader runs. Fallback to undefined for external-context
865
+ // revives (the hydrate path is encryption-key-tolerant).
866
+ const ctxForKey = contextStorage.getStore();
867
+ const data = (await hydrateStepArguments(result.value, runId, ctxForKey?.encryptionKey));
868
+ controller.abort(data?.reason);
869
+ }
870
+ catch {
871
+ controller.abort();
872
+ }
867
873
  }
868
- // Get the deserializer from the class
869
- const deserialize = cls[WORKFLOW_DESERIALIZE];
870
- if (typeof deserialize !== 'function') {
871
- throw new Error(`Class "${classId}" does not have a static ${String(WORKFLOW_DESERIALIZE)} method.`);
874
+ }
875
+ catch {
876
+ // Stream read failed — signal won't propagate in real-time,
877
+ // but hook-based propagation on next replay provides fallback
878
+ }
879
+ })());
880
+ return readerCancel;
881
+ }
882
+ /**
883
+ * Stores abort serialization symbols and the readerCancel controller
884
+ * on both the controller and its signal.
885
+ */
886
+ function tagAbortPair(controller, value, readerCancel) {
887
+ const taggedController = controller;
888
+ const taggedSignal = controller.signal;
889
+ taggedController[ABORT_STREAM_NAME] = value.streamName;
890
+ taggedController[ABORT_HOOK_TOKEN] = value.hookToken;
891
+ taggedSignal[ABORT_STREAM_NAME] = value.streamName;
892
+ taggedSignal[ABORT_HOOK_TOKEN] = value.hookToken;
893
+ if (readerCancel) {
894
+ taggedController[ABORT_READER_CANCEL] = readerCancel;
895
+ taggedSignal[ABORT_READER_CANCEL] = readerCancel;
896
+ }
897
+ }
898
+ /**
899
+ * Propagate abort-internal symbols from one signal to another. Used by the
900
+ * Request reviver because `new Request(url, { signal })` copies the signal
901
+ * internally — the constructed `request.signal` is a fresh AbortSignal that
902
+ * doesn't carry symbols from the source.
903
+ */
904
+ function copyAbortInternals(src, dest) {
905
+ const s = src;
906
+ const d = dest;
907
+ if (s[ABORT_STREAM_NAME] !== undefined) {
908
+ d[ABORT_STREAM_NAME] = s[ABORT_STREAM_NAME];
909
+ }
910
+ if (s[ABORT_HOOK_TOKEN] !== undefined) {
911
+ d[ABORT_HOOK_TOKEN] = s[ABORT_HOOK_TOKEN];
912
+ }
913
+ if (s[ABORT_READER_CANCEL] !== undefined) {
914
+ d[ABORT_READER_CANCEL] = s[ABORT_READER_CANCEL];
915
+ }
916
+ }
917
+ /**
918
+ * Creates an AbortController with stream-backed abort propagation.
919
+ * Used by step and external revivers where real abort signal behavior is needed.
920
+ *
921
+ * @param value - The serialized abort controller/signal data
922
+ * @param ops - The ops array for tracking async work
923
+ * @param runId - The workflow run ID (for stream reads)
924
+ * @returns A real AbortController with patched abort() method
925
+ */
926
+ function reviveAbortController(value, ops, runId) {
927
+ const controller = new AbortController();
928
+ if (value.aborted) {
929
+ tagAbortPair(controller, value);
930
+ controller.abort(value.reason);
931
+ }
932
+ else if (value.streamName) {
933
+ const readerCancel = setupAbortStreamReader(controller, runId, value.streamName, ops);
934
+ tagAbortPair(controller, value, readerCancel);
935
+ }
936
+ else {
937
+ tagAbortPair(controller, value);
938
+ }
939
+ // Override abort() to also write stream + resume hook (for step-initiated abort)
940
+ const originalAbort = controller.abort.bind(controller);
941
+ controller.abort = (reason) => {
942
+ if (controller.signal.aborted)
943
+ return;
944
+ originalAbort(reason);
945
+ const ctx = contextStorage.getStore();
946
+ if (ctx) {
947
+ ctx.ops.push((async () => {
948
+ try {
949
+ // Dehydrate the abort payload through the same machinery the hook
950
+ // event uses so the `reason` round-trips with full type fidelity
951
+ // (DOMException, custom errors, etc.) and respects the run's
952
+ // encryption key — symmetric with what the suspension handler
953
+ // writes for workflow-initiated aborts.
954
+ const payload = await dehydrateStepArguments({ aborted: true, reason }, ctx.workflowMetadata.workflowRunId, ctx.encryptionKey);
955
+ const writable = new WorkflowServerWritableStream(ctx.workflowMetadata.workflowRunId, value.streamName);
956
+ const writer = writable.getWriter();
957
+ await writer.write(payload);
958
+ await writer.close();
959
+ }
960
+ catch {
961
+ // Best-effort stream write
962
+ }
963
+ })());
964
+ if (value.hookToken) {
965
+ ctx.ops.push((async () => {
966
+ try {
967
+ const { resumeHook: resumeHookFn } = await import('./runtime/resume-hook.js');
968
+ await resumeHookFn(value.hookToken, {
969
+ aborted: true,
970
+ reason,
971
+ });
972
+ }
973
+ catch {
974
+ // Best-effort hook resume — retry on next replay
975
+ }
976
+ })());
872
977
  }
873
- // Deserialize the instance using the custom deserializer
874
- return deserialize.call(cls, data);
875
- },
876
- Set: (value) => new global.Set(value),
877
- URL: (value) => new global.URL(value),
878
- URLSearchParams: (value) => new global.URLSearchParams(value === '.' ? '' : value),
879
- Uint8Array: (value) => {
880
- const ab = reviveArrayBuffer(value);
881
- return new global.Uint8Array(ab);
882
- },
883
- Uint8ClampedArray: (value) => {
884
- const ab = reviveArrayBuffer(value);
885
- return new global.Uint8ClampedArray(ab);
886
- },
887
- Uint16Array: (value) => {
888
- const ab = reviveArrayBuffer(value);
889
- return new global.Uint16Array(ab);
890
- },
891
- Uint32Array: (value) => {
892
- const ab = reviveArrayBuffer(value);
893
- return new global.Uint32Array(ab);
894
- },
978
+ }
979
+ };
980
+ return controller;
981
+ }
982
+ /**
983
+ * Revives just an AbortSignal without the patched abort() overhead.
984
+ * Used when only a signal (not a controller) was serialized.
985
+ */
986
+ function reviveAbortSignal(value, ops, runId) {
987
+ const controller = new AbortController();
988
+ if (value.aborted) {
989
+ tagAbortPair(controller, value);
990
+ controller.abort(value.reason);
991
+ }
992
+ else if (value.streamName) {
993
+ const readerCancel = setupAbortStreamReader(controller, runId, value.streamName, ops);
994
+ tagAbortPair(controller, value, readerCancel);
995
+ }
996
+ else {
997
+ tagAbortPair(controller, value);
998
+ }
999
+ return controller.signal;
1000
+ }
1001
+ /**
1002
+ * Base revivers shared across all serialization boundaries.
1003
+ * Composes: class + common revivers from the modular modules.
1004
+ *
1005
+ * This is exported because serialization-format.ts and other files reference it.
1006
+ */
1007
+ export function getCommonRevivers(global = globalThis) {
1008
+ return {
1009
+ ...getClassRevivers(global),
1010
+ ...getCommonReviversFromModule(global),
895
1011
  };
896
1012
  }
1013
+ /**
1014
+ * Resolve the encrypt-only key needed when a child writes into another run's
1015
+ * stream. New descriptors include the owner's deployment ID; descriptors
1016
+ * created by older SDK versions fall back to loading the owning run.
1017
+ */
1018
+ async function getForwardedWritableEncryptionKey(runId, deploymentId) {
1019
+ const world = await getWorldLazy();
1020
+ if (!world.getEncryptionKeyForRun)
1021
+ return undefined;
1022
+ const rawKey = deploymentId
1023
+ ? await world.getEncryptionKeyForRun(runId, { deploymentId })
1024
+ : await world.getEncryptionKeyForRun(await world.runs.get(runId));
1025
+ return rawKey ? await importKey(rawKey, ['encrypt']) : undefined;
1026
+ }
897
1027
  /**
898
1028
  * Revivers for deserialization boundary from the client side,
899
1029
  * receiving the return value from the workflow handler.
@@ -907,18 +1037,31 @@ export function getExternalRevivers(global = globalThis, ops, runId, cryptoKey)
907
1037
  ...getCommonRevivers(global),
908
1038
  // StepFunction should not be returned from workflows to clients
909
1039
  StepFunction: () => {
910
- throw new Error('Step functions cannot be deserialized in client context. Step functions should not be returned from workflows.');
1040
+ throw new SerializationError('Step functions cannot be deserialized in client context. Step functions should not be returned from workflows.', {
1041
+ hint: 'A step function reference reached the client. Return a serializable value (e.g. the step result) instead of the step itself.',
1042
+ });
911
1043
  },
912
1044
  WorkflowFunction: (value) => Object.assign(() => {
913
- throw new Error('Workflow functions cannot be called directly. Use start() to invoke them.');
1045
+ throw new SerializationError('Workflow functions cannot be called directly. Use start() to invoke them.', {
1046
+ hint: 'Wrap the workflow with `start(workflowFn, { ... })` from `workflow` to begin a run instead of invoking it like a normal function.',
1047
+ });
914
1048
  }, { workflowId: value.workflowId }),
915
1049
  Request: (value) => {
916
- return new global.Request(value.url, {
1050
+ const init = {
917
1051
  method: value.method,
918
1052
  headers: new global.Headers(value.headers),
919
1053
  body: value.body,
920
1054
  duplex: value.duplex,
921
- });
1055
+ };
1056
+ if (value.signal)
1057
+ init.signal = value.signal;
1058
+ const request = new global.Request(value.url, init);
1059
+ // The Request constructor creates an internal signal copy, so the
1060
+ // abort-internal symbols set by reviveAbortSignal don't propagate.
1061
+ // Re-tag the request's own signal so cancelAbortReaders can find it.
1062
+ if (value.signal)
1063
+ copyAbortInternals(value.signal, request.signal);
1064
+ return request;
922
1065
  },
923
1066
  Response: (value) => {
924
1067
  // Note: Response constructor only accepts status, statusText, and headers
@@ -967,8 +1110,15 @@ export function getExternalRevivers(global = globalThis, ops, runId, cryptoKey)
967
1110
  }
968
1111
  },
969
1112
  WritableStream: (value) => {
970
- const serialize = getSerializeStream(getExternalReducers(global, ops, runId, cryptoKey), cryptoKey);
971
- const serverWritable = new WorkflowServerWritableStream(runId, value.name);
1113
+ // Same handling as `getStepRevivers.WritableStream` see comments
1114
+ // there for the cross-run case (writable carries `runId` from
1115
+ // parent → child forwarding via `start()`).
1116
+ const targetRunId = typeof value.runId === 'string' ? value.runId : runId;
1117
+ const targetKey = targetRunId === runId
1118
+ ? cryptoKey
1119
+ : getForwardedWritableEncryptionKey(targetRunId, value.deploymentId);
1120
+ const serialize = getSerializeStream(getExternalReducers(global, ops, targetRunId, targetKey), targetKey);
1121
+ const serverWritable = new WorkflowServerWritableStream(targetRunId, value.name);
972
1122
  // Create flushable state for this stream
973
1123
  const state = createFlushableState();
974
1124
  ops.push(state.promise);
@@ -978,8 +1128,24 @@ export function getExternalRevivers(global = globalThis, ops, runId, cryptoKey)
978
1128
  });
979
1129
  // Start polling to detect when user releases lock
980
1130
  pollWritableLock(serialize.writable, state);
1131
+ Object.defineProperty(serialize.writable, STREAM_NAME_SYMBOL, {
1132
+ value: value.name,
1133
+ writable: false,
1134
+ });
1135
+ Object.defineProperty(serialize.writable, STREAM_SERVER_RUN_ID_SYMBOL, {
1136
+ value: targetRunId,
1137
+ writable: false,
1138
+ });
1139
+ if (typeof value.deploymentId === 'string') {
1140
+ Object.defineProperty(serialize.writable, STREAM_SERVER_DEPLOYMENT_ID_SYMBOL, {
1141
+ value: value.deploymentId,
1142
+ writable: false,
1143
+ });
1144
+ }
981
1145
  return serialize.writable;
982
1146
  },
1147
+ AbortController: (value) => reviveAbortController(value, ops, runId),
1148
+ AbortSignal: (value) => reviveAbortSignal(value, ops, runId),
983
1149
  };
984
1150
  }
985
1151
  /**
@@ -991,27 +1157,11 @@ export function getExternalRevivers(global = globalThis, ops, runId, cryptoKey)
991
1157
  * @returns
992
1158
  */
993
1159
  export function getWorkflowRevivers(global = globalThis) {
994
- // Get the useStep function from the VM's globalThis
995
- // This is set up by the workflow runner in workflow.ts
996
- // Use Symbol.for directly to access the symbol on the global object
997
- const useStep = global[Symbol.for('WORKFLOW_USE_STEP')];
998
1160
  return {
999
1161
  ...getCommonRevivers(global),
1000
- // StepFunction reviver for workflow context - returns useStep wrapper
1001
- // This allows step functions passed as arguments to start() to be called directly
1002
- // from workflow code, just like step functions defined in the same file
1003
- StepFunction: (value) => {
1004
- const stepId = value.stepId;
1005
- const closureVars = value.closureVars;
1006
- if (!useStep) {
1007
- throw new Error('WORKFLOW_USE_STEP not found on global object. Step functions cannot be deserialized outside workflow context.');
1008
- }
1009
- if (closureVars) {
1010
- // For step functions with closure variables, create a wrapper that provides them
1011
- return useStep(stepId, () => closureVars);
1012
- }
1013
- return useStep(stepId);
1014
- },
1162
+ // StepFunction reviver for workflow context - uses the modular reviver
1163
+ // which calls WORKFLOW_USE_STEP from global to reconstruct step proxies
1164
+ ...getStepFunctionReviver(global),
1015
1165
  Request: (value) => {
1016
1166
  Object.setPrototypeOf(value, global.Request.prototype);
1017
1167
  const responseWritable = value.responseWritable;
@@ -1019,7 +1169,9 @@ export function getWorkflowRevivers(global = globalThis) {
1019
1169
  value[WEBHOOK_RESPONSE_WRITABLE] = responseWritable;
1020
1170
  delete value.responseWritable;
1021
1171
  value.respondWith = () => {
1022
- throw new Error('`respondWith()` must be called from within a step function');
1172
+ throw new SerializationError('`respondWith()` must be called from within a step function.', {
1173
+ hint: 'Move the `respondWith(...)` call inside a `"use step"` function — it cannot be invoked from a workflow context.',
1174
+ });
1023
1175
  };
1024
1176
  }
1025
1177
  return value;
@@ -1027,7 +1179,9 @@ export function getWorkflowRevivers(global = globalThis) {
1027
1179
  // Workflow function reviver for workflow context — returns a function-like
1028
1180
  // object with .workflowId that mimics what the SWC compiler produces,
1029
1181
  WorkflowFunction: (value) => Object.assign(() => {
1030
- throw new Error('Workflow functions cannot be called directly. Use start() to invoke them.');
1182
+ throw new SerializationError('Workflow functions cannot be called directly. Use start() to invoke them.', {
1183
+ hint: 'Wrap the workflow with `start(workflowFn, { ... })` from `workflow` to begin a run instead of invoking it like a normal function.',
1184
+ });
1031
1185
  }, { workflowId: value.workflowId }),
1032
1186
  Response: (value) => {
1033
1187
  Object.setPrototypeOf(value, global.Response.prototype);
@@ -1057,12 +1211,52 @@ export function getWorkflowRevivers(global = globalThis) {
1057
1211
  });
1058
1212
  },
1059
1213
  WritableStream: (value) => {
1060
- return Object.create(global.WritableStream.prototype, {
1214
+ const descriptor = {
1061
1215
  [STREAM_NAME_SYMBOL]: {
1062
1216
  value: value.name,
1063
1217
  writable: false,
1064
1218
  },
1065
- });
1219
+ };
1220
+ // Preserve the foreign runId, if present, so that when the
1221
+ // handle is later passed to a step the workflow reducer can
1222
+ // forward it through to the step reviver.
1223
+ if (typeof value.runId === 'string') {
1224
+ descriptor[STREAM_SERVER_RUN_ID_SYMBOL] = {
1225
+ value: value.runId,
1226
+ writable: false,
1227
+ };
1228
+ }
1229
+ if (typeof value.deploymentId === 'string') {
1230
+ descriptor[STREAM_SERVER_DEPLOYMENT_ID_SYMBOL] = {
1231
+ value: value.deploymentId,
1232
+ writable: false,
1233
+ };
1234
+ }
1235
+ return Object.create(global.WritableStream.prototype, descriptor);
1236
+ },
1237
+ // AbortController/AbortSignal revived inside the workflow VM. Use the
1238
+ // real WorkflowAbortSignal class so addEventListener('abort', fn) actually
1239
+ // fires when the signal aborts (the previous no-op stub silently dropped
1240
+ // listener registrations — silent correctness bug for natural patterns
1241
+ // like `signal.addEventListener('abort', fn)` after receiving a deserialized
1242
+ // signal). The signal does not own a hook subscription here — abort state
1243
+ // is delivered via the existing replay machinery on the source side.
1244
+ AbortController: (value) => {
1245
+ const signal = new WorkflowAbortSignal(value.streamName, value.hookToken);
1246
+ if (value.aborted)
1247
+ signal._setAborted(value.reason);
1248
+ return {
1249
+ [ABORT_STREAM_NAME]: value.streamName,
1250
+ [ABORT_HOOK_TOKEN]: value.hookToken,
1251
+ signal,
1252
+ abort: () => { },
1253
+ };
1254
+ },
1255
+ AbortSignal: (value) => {
1256
+ const signal = new WorkflowAbortSignal(value.streamName, value.hookToken);
1257
+ if (value.aborted)
1258
+ signal._setAborted(value.reason);
1259
+ return signal;
1066
1260
  },
1067
1261
  };
1068
1262
  }
@@ -1075,63 +1269,95 @@ export function getWorkflowRevivers(global = globalThis) {
1075
1269
  * @param runId
1076
1270
  * @returns
1077
1271
  */
1078
- function getStepRevivers(global = globalThis, ops, runId, cryptoKey) {
1272
+ function getStepRevivers(global = globalThis, ops, runId, cryptoKey, deploymentId) {
1079
1273
  return {
1080
1274
  ...getCommonRevivers(global),
1081
1275
  // StepFunction reviver for step context - returns raw step function
1082
- // with closure variable support via AsyncLocalStorage
1276
+ // with closure variable support via AsyncLocalStorage.
1277
+ //
1278
+ // Handles four independent flags from the serialized payload:
1279
+ // - `closureVars`: invoke the body inside an AsyncLocalStorage frame
1280
+ // so the SWC-emitted `WORKFLOW_STEP_CONTEXT_STORAGE` IIFE in the
1281
+ // hoisted body can pull the closure variables back out.
1282
+ // - `boundThis`: a `this` value captured by
1283
+ // `useStep(...).bind(this)` in the workflow bundle (lexical-`this`
1284
+ // arrow steps). The wrapper invokes the body via
1285
+ // `stepFn.apply(boundThis, args)` so the body sees the same
1286
+ // `this` it would have had in the workflow bundle. Property
1287
+ // presence — not truthiness — is significant because
1288
+ // `bind(null)` and `bind(undefined)` are both legal and should
1289
+ // round-trip faithfully.
1290
+ // - `boundArgs`: prefilled args from
1291
+ // `useStep(...).bind(thisArg, x, y)`. Prepended to the call args
1292
+ // so partial application survives serialization.
1083
1293
  StepFunction: (value) => {
1084
1294
  const stepId = value.stepId;
1085
1295
  const closureVars = value.closureVars;
1296
+ const hasBoundThis = 'boundThis' in value;
1297
+ const boundThis = hasBoundThis ? value.boundThis : undefined;
1298
+ const boundArgs = Array.isArray(value.boundArgs) ? value.boundArgs : [];
1086
1299
  const stepFn = getStepFunction(stepId);
1087
1300
  if (!stepFn) {
1088
- throw new Error(`Step function "${stepId}" not found. Make sure the step function is registered.`);
1301
+ throw new SerializationError(`Step function "${stepId}" not found. Make sure the step function is registered.`, {
1302
+ hint: 'Make sure the step file is included in your build (i.e. it is listed in the workflow manifest), and that the SWC plugin is configured for the file.',
1303
+ });
1304
+ }
1305
+ // Fast path: nothing to wrap.
1306
+ if (!closureVars && !hasBoundThis && boundArgs.length === 0) {
1307
+ return stepFn;
1089
1308
  }
1090
- // If closure variables were serialized, return a wrapper function
1091
- // that sets up AsyncLocalStorage context when invoked
1092
- if (closureVars) {
1093
- const wrappedStepFn = ((...args) => {
1094
- // Get the current context from AsyncLocalStorage
1309
+ const wrappedStepFn = function (...args) {
1310
+ const callThis = hasBoundThis ? boundThis : this;
1311
+ const callArgs = boundArgs.length > 0 ? [...boundArgs, ...args] : args;
1312
+ if (closureVars) {
1095
1313
  const currentContext = contextStorage.getStore();
1096
1314
  if (!currentContext) {
1097
- throw new Error('Cannot call step function with closure variables outside step context');
1315
+ throw new WorkflowRuntimeError('Cannot call step function with closure variables outside step context');
1098
1316
  }
1099
- // Create a new context with the closure variables merged in
1100
1317
  const newContext = {
1101
1318
  ...currentContext,
1102
1319
  closureVars,
1103
1320
  };
1104
- // Run the step function with the new context that includes closure vars
1105
- return contextStorage.run(newContext, () => stepFn(...args));
1106
- });
1107
- // Copy properties from original step function
1108
- Object.defineProperty(wrappedStepFn, 'name', {
1109
- value: stepFn.name,
1110
- });
1111
- Object.defineProperty(wrappedStepFn, 'stepId', {
1112
- value: stepId,
1113
- writable: false,
1114
- enumerable: false,
1115
- configurable: false,
1116
- });
1117
- if (stepFn.maxRetries !== undefined) {
1118
- wrappedStepFn.maxRetries = stepFn.maxRetries;
1321
+ return contextStorage.run(newContext, () => stepFn.apply(callThis, callArgs));
1119
1322
  }
1120
- return wrappedStepFn;
1323
+ return stepFn.apply(callThis, callArgs);
1324
+ };
1325
+ // Copy properties from original step function
1326
+ Object.defineProperty(wrappedStepFn, 'name', {
1327
+ value: stepFn.name,
1328
+ });
1329
+ Object.defineProperty(wrappedStepFn, 'stepId', {
1330
+ value: stepId,
1331
+ writable: false,
1332
+ enumerable: false,
1333
+ configurable: false,
1334
+ });
1335
+ if (stepFn.maxRetries !== undefined) {
1336
+ wrappedStepFn.maxRetries = stepFn.maxRetries;
1121
1337
  }
1122
- return stepFn;
1338
+ return wrappedStepFn;
1123
1339
  },
1124
1340
  WorkflowFunction: (value) => Object.assign(() => {
1125
- throw new Error('Workflow functions cannot be called directly. Use start() to invoke them.');
1341
+ throw new SerializationError('Workflow functions cannot be called directly. Use start() to invoke them.', {
1342
+ hint: 'Wrap the workflow with `start(workflowFn, { ... })` from `workflow` to begin a run instead of invoking it like a normal function.',
1343
+ });
1126
1344
  }, { workflowId: value.workflowId }),
1127
1345
  Request: (value) => {
1128
1346
  const responseWritable = value.responseWritable;
1129
- const request = new global.Request(value.url, {
1347
+ const init = {
1130
1348
  method: value.method,
1131
1349
  headers: new global.Headers(value.headers),
1132
1350
  body: value.body,
1133
1351
  duplex: value.duplex,
1134
- });
1352
+ };
1353
+ if (value.signal)
1354
+ init.signal = value.signal;
1355
+ const request = new global.Request(value.url, init);
1356
+ // The Request constructor creates an internal signal copy, so the
1357
+ // abort-internal symbols set by reviveAbortSignal don't propagate.
1358
+ // Re-tag the request's own signal so cancelAbortReaders can find it.
1359
+ if (value.signal)
1360
+ copyAbortInternals(value.signal, request.signal);
1135
1361
  if (responseWritable) {
1136
1362
  request.respondWith = async (response) => {
1137
1363
  const writer = responseWritable.getWriter();
@@ -1175,7 +1401,7 @@ function getStepRevivers(global = globalThis, ops, runId, cryptoKey) {
1175
1401
  return userReadable;
1176
1402
  }
1177
1403
  else {
1178
- const transform = getDeserializeStream(getStepRevivers(global, ops, runId, cryptoKey), cryptoKey);
1404
+ const transform = getDeserializeStream(getStepRevivers(global, ops, runId, cryptoKey, deploymentId), cryptoKey);
1179
1405
  const state = createFlushableState();
1180
1406
  ops.push(state.promise);
1181
1407
  // Start the flushable pipe in the background
@@ -1188,8 +1414,29 @@ function getStepRevivers(global = globalThis, ops, runId, cryptoKey) {
1188
1414
  }
1189
1415
  },
1190
1416
  WritableStream: (value) => {
1191
- const serialize = getSerializeStream(getStepReducers(global, ops, runId, cryptoKey), cryptoKey);
1192
- const serverWritable = new WorkflowServerWritableStream(runId, value.name);
1417
+ // Same-run case: the writable belongs to the current run. Use the
1418
+ // local cryptoKey and write to the local runId's server stream.
1419
+ //
1420
+ // Cross-run case (parent → child via `start()`): the descriptor
1421
+ // carries the original `runId` and `name`. Open a server writable
1422
+ // against the original `(runId, name)` and resolve THAT run's key
1423
+ // for encryption. The resolution is async but doesn't need to
1424
+ // block reviver return — `getSerializeStream` accepts the
1425
+ // `Promise<CryptoKey | undefined>` directly and awaits it lazily
1426
+ // on the first chunk written. The key is imported encrypt-only
1427
+ // so the receiving run can never decrypt anything else on the
1428
+ // owning run's stream — it can only contribute new writes.
1429
+ const targetRunId = typeof value.runId === 'string' ? value.runId : runId;
1430
+ const targetDeploymentId = typeof value.deploymentId === 'string'
1431
+ ? value.deploymentId
1432
+ : targetRunId === runId
1433
+ ? deploymentId
1434
+ : undefined;
1435
+ const targetKey = targetRunId === runId
1436
+ ? cryptoKey
1437
+ : getForwardedWritableEncryptionKey(targetRunId, targetDeploymentId);
1438
+ const serialize = getSerializeStream(getStepReducers(global, ops, targetRunId, targetKey), targetKey);
1439
+ const serverWritable = new WorkflowServerWritableStream(targetRunId, value.name);
1193
1440
  // Create flushable state for this stream
1194
1441
  const state = createFlushableState();
1195
1442
  ops.push(state.promise);
@@ -1199,211 +1446,278 @@ function getStepRevivers(global = globalThis, ops, runId, cryptoKey) {
1199
1446
  });
1200
1447
  // Start polling to detect when user releases lock
1201
1448
  pollWritableLock(serialize.writable, state);
1449
+ // Record the underlying `(runId, name)` so downstream reducers can
1450
+ // recognize that this writable is already backed by a workflow
1451
+ // server stream. When forwarded across `start()` again — e.g.
1452
+ // the child passes this writable on to a grandchild — the
1453
+ // external reducer needs both to emit the original `runId` in
1454
+ // the descriptor.
1455
+ Object.defineProperty(serialize.writable, STREAM_NAME_SYMBOL, {
1456
+ value: value.name,
1457
+ writable: false,
1458
+ });
1459
+ Object.defineProperty(serialize.writable, STREAM_SERVER_RUN_ID_SYMBOL, {
1460
+ value: targetRunId,
1461
+ writable: false,
1462
+ });
1463
+ if (targetDeploymentId) {
1464
+ Object.defineProperty(serialize.writable, STREAM_SERVER_DEPLOYMENT_ID_SYMBOL, {
1465
+ value: targetDeploymentId,
1466
+ writable: false,
1467
+ });
1468
+ }
1202
1469
  return serialize.writable;
1203
1470
  },
1471
+ AbortController: (value) => reviveAbortController(value, ops, runId),
1472
+ AbortSignal: (value) => reviveAbortSignal(value, ops, runId),
1204
1473
  };
1205
1474
  }
1206
1475
  // ============================================================================
1207
1476
  // Encryption Helpers
1208
1477
  // ============================================================================
1478
+ // These delegate to the modular `encrypt`/`decrypt` from `./serialization/encryption.js`
1479
+ // but are kept as named exports for backwards compatibility with existing consumers.
1209
1480
  /**
1210
1481
  * Encrypt data if the world supports encryption.
1211
1482
  * Returns original data if encryption is not available.
1212
1483
  *
1213
- * @param data - Serialized data to encrypt
1214
- * @param key - Encryption key (undefined to skip encryption)
1215
- * @param context - Encryption context with runId
1216
- * @returns Encrypted data if encryption available, original data otherwise
1484
+ * @deprecated Use `encrypt` from `./serialization/encryption.js` instead.
1217
1485
  */
1218
1486
  export async function maybeEncrypt(data, key) {
1219
- if (!key)
1220
- return data;
1221
- const encrypted = await aesGcmEncrypt(key, data);
1222
- return encodeWithFormatPrefix(SerializationFormat.ENCRYPTED, encrypted);
1487
+ return (await encrypt(data, key));
1223
1488
  }
1224
1489
  /**
1225
1490
  * Decrypt data if it has the 'encr' prefix.
1226
1491
  *
1227
- * @param data - Data that may be encrypted
1228
- * @param key - Encryption key (undefined if no key available)
1229
- * @returns Decrypted data if encrypted, original data otherwise
1230
- * @throws {WorkflowRuntimeError} If the data is encrypted but no key is
1231
- * available. Callers (e.g., `Run.pollReturnValue()`, `hydrateStepReturnValue`)
1232
- * should be aware this can surface as a rejected promise during key rotation
1233
- * or misconfiguration scenarios.
1492
+ * @deprecated Use `decrypt` from `./serialization/encryption.js` instead.
1234
1493
  */
1235
1494
  export async function maybeDecrypt(data, key) {
1236
- // Legacy specVersion 1 runs stored event data as plain JSON arrays
1237
- // (not binary Uint8Array). Pass through as-is for backwards compat.
1238
- if (!(data instanceof Uint8Array)) {
1239
- return data;
1240
- }
1241
- if (isEncrypted(data)) {
1242
- if (!key) {
1243
- throw new WorkflowRuntimeError('Encrypted data encountered but no encryption key is available. ' +
1244
- 'Encryption is not configured or no key was provided for this run.');
1245
- }
1246
- // Strip the 'encr' format prefix — the prefix is a core framing concern
1247
- const { payload } = decodeFormatPrefix(data);
1248
- return aesGcmDecrypt(key, payload);
1249
- }
1250
- return data;
1495
+ return decrypt(data, key);
1251
1496
  }
1252
1497
  // ============================================================================
1253
1498
  // Dehydrate / Hydrate Functions
1254
1499
  // ============================================================================
1500
+ // These delegate to the modular mode modules (workflow, step, client) passing
1501
+ // mode-specific stream and Request/Response reducers/revivers as extra options.
1502
+ // The v1Compat path is handled inline before delegating to the modules.
1255
1503
  /**
1256
1504
  * Called from the `start()` function to serialize the workflow arguments
1257
1505
  * into a format that can be saved to the database and then hydrated from
1258
1506
  * within the workflow execution environment.
1259
- *
1260
- * @param value - The value to serialize
1261
- * @param runId - The workflow run ID (required for encryption context)
1262
- * @param key - Encryption key (undefined to skip encryption)
1263
- * @param ops - Promise array for stream operations
1264
- * @param global - Global object for serialization context
1265
- * @param v1Compat - Enable legacy v1 compatibility mode
1266
- * @returns The dehydrated value as binary data (Uint8Array) with format prefix
1267
1507
  */
1268
1508
  export async function dehydrateWorkflowArguments(value, runId, key, ops = [], global = globalThis, v1Compat = false) {
1269
- try {
1509
+ if (v1Compat) {
1270
1510
  const str = stringify(value, getExternalReducers(global, ops, runId, key));
1271
- if (v1Compat) {
1272
- return revive(str);
1273
- }
1274
- const payload = new TextEncoder().encode(str);
1275
- const serialized = encodeWithFormatPrefix(SerializationFormat.DEVALUE_V1, payload);
1276
- // Encrypt if world supports encryption
1277
- return maybeEncrypt(serialized, key);
1511
+ return revive(str);
1512
+ }
1513
+ try {
1514
+ return await clientModule.serialize(value, key, {
1515
+ global,
1516
+ extraReducers: getStreamAndRequestReducers(getExternalReducers(global, ops, runId, key)),
1517
+ });
1278
1518
  }
1279
1519
  catch (error) {
1280
- throw new WorkflowRuntimeError(formatSerializationError('workflow arguments', error), { slug: 'serialization-failed', cause: error });
1520
+ const cause = unwrapSerializationCause(error);
1521
+ const { message, hint } = formatSerializationError('workflow arguments', cause);
1522
+ throw new SerializationError(message, { hint, cause });
1281
1523
  }
1282
1524
  }
1283
1525
  /**
1284
1526
  * Called from workflow execution environment to hydrate the workflow
1285
1527
  * arguments from the database at the start of workflow execution.
1286
- *
1287
- * @param value - Binary serialized data (Uint8Array) with format prefix
1288
- * @param _runId - Workflow run ID (reserved for future decryption context; decryption is currently driven solely by the provided key)
1289
- * @param key - Encryption key (undefined to skip decryption)
1290
- * @param global - Global object for deserialization context
1291
- * @param extraRevivers - Additional revivers for custom types
1292
- * @returns The hydrated value
1293
1528
  */
1294
1529
  export async function hydrateWorkflowArguments(value, _runId, key, global = globalThis, extraRevivers = {}) {
1295
- // Decrypt if needed
1296
- const decrypted = await maybeDecrypt(value, key);
1297
- // Legacy specVersion 1 runs stored data as plain JSON arrays (not binary).
1298
- // These pass through maybeDecrypt unchanged and are deserialized directly
1299
- // via devalue's unflatten().
1300
- if (!(decrypted instanceof Uint8Array)) {
1301
- return unflatten(decrypted, {
1302
- ...getWorkflowRevivers(global),
1530
+ return workflowModule.deserialize(await maybeDecrypt(value, key), {
1531
+ global,
1532
+ extraRevivers: {
1533
+ ...getStreamAndRequestRevivers(getWorkflowRevivers(global)),
1303
1534
  ...extraRevivers,
1535
+ },
1536
+ });
1537
+ }
1538
+ /**
1539
+ * Dehydrate workflow return value for storage.
1540
+ */
1541
+ export async function dehydrateWorkflowReturnValue(value, _runId, key, global = globalThis, v1Compat = false) {
1542
+ if (v1Compat) {
1543
+ const str = stringify(value, getWorkflowReducers(global));
1544
+ return revive(str);
1545
+ }
1546
+ try {
1547
+ return await stepModule.serialize(value, key, {
1548
+ global,
1549
+ extraReducers: getStreamAndRequestReducers(getWorkflowReducers(global)),
1304
1550
  });
1305
1551
  }
1306
- const { format, payload } = decodeFormatPrefix(decrypted);
1307
- if (format === SerializationFormat.DEVALUE_V1) {
1308
- const str = new TextDecoder().decode(payload);
1309
- const obj = parse(str, {
1310
- ...getWorkflowRevivers(global),
1552
+ catch (error) {
1553
+ const cause = unwrapSerializationCause(error);
1554
+ const { message, hint } = formatSerializationError('workflow return value', cause);
1555
+ throw new SerializationError(message, { hint, cause });
1556
+ }
1557
+ }
1558
+ /**
1559
+ * Called from the client side to hydrate the workflow return value
1560
+ * of a completed workflow run.
1561
+ */
1562
+ export async function hydrateWorkflowReturnValue(value, runId, key, ops = [], global = globalThis, extraRevivers = {}) {
1563
+ return clientModule.deserialize(value, key, {
1564
+ global,
1565
+ extraRevivers: {
1566
+ ...getStreamAndRequestRevivers(getExternalRevivers(global, ops, runId, key)),
1311
1567
  ...extraRevivers,
1568
+ },
1569
+ });
1570
+ }
1571
+ /**
1572
+ * Called from the workflow handler when a step is being created.
1573
+ * Dehydrates values from within the workflow execution environment.
1574
+ */
1575
+ export async function dehydrateStepArguments(value, _runId, key, global = globalThis, v1Compat = false) {
1576
+ if (v1Compat) {
1577
+ const str = stringify(value, getWorkflowReducers(global));
1578
+ return revive(str);
1579
+ }
1580
+ try {
1581
+ return await stepModule.serialize(value, key, {
1582
+ global,
1583
+ extraReducers: getStreamAndRequestReducers(getWorkflowReducers(global)),
1312
1584
  });
1313
- return obj;
1314
1585
  }
1315
- throw new Error(`Unsupported serialization format: ${format}`);
1586
+ catch (error) {
1587
+ const cause = unwrapSerializationCause(error);
1588
+ const { message, hint } = formatSerializationError('step arguments', cause);
1589
+ throw new SerializationError(message, { hint, cause });
1590
+ }
1316
1591
  }
1317
1592
  /**
1318
- * Dehydrate workflow return value for storage.
1593
+ * Called from the step handler to hydrate the arguments of a step
1594
+ * from the database at the start of the step execution.
1595
+ */
1596
+ export async function hydrateStepArguments(value, runId, key, ops = [], global = globalThis, extraRevivers = {}, deploymentId) {
1597
+ return stepModule.deserialize(value, key, {
1598
+ global,
1599
+ extraRevivers: {
1600
+ ...getStreamAndRequestRevivers(getStepRevivers(global, ops, runId, key, deploymentId)),
1601
+ ...extraRevivers,
1602
+ },
1603
+ });
1604
+ }
1605
+ /**
1606
+ * Called from the step handler when a step has completed.
1607
+ * Dehydrates values from within the step execution environment.
1608
+ */
1609
+ export async function dehydrateStepReturnValue(value, runId, key, ops = [], global = globalThis, v1Compat = false) {
1610
+ if (v1Compat) {
1611
+ const str = stringify(value, getStepReducers(global, ops, runId, key));
1612
+ return revive(str);
1613
+ }
1614
+ try {
1615
+ return await stepModule.serialize(value, key, {
1616
+ global,
1617
+ extraReducers: getStreamAndRequestReducers(getStepReducers(global, ops, runId, key)),
1618
+ });
1619
+ }
1620
+ catch (error) {
1621
+ const cause = unwrapSerializationCause(error);
1622
+ const { message, hint } = formatSerializationError('step return value', cause);
1623
+ throw new SerializationError(message, { hint, cause });
1624
+ }
1625
+ }
1626
+ /**
1627
+ * Called from the step handler when a step throws. Dehydrates the thrown
1628
+ * value from within the step execution environment into a format that can
1629
+ * be saved to the database in a `step_failed` or `step_retrying` event.
1630
+ *
1631
+ * Any JavaScript value can be thrown (strings, numbers, objects, Errors,
1632
+ * Error subclasses), so the same serialization pipeline used for step
1633
+ * arguments and return values is applied here.
1319
1634
  *
1320
- * @param value - The value to serialize
1635
+ * @param value - The thrown value to serialize (can be any type)
1321
1636
  * @param runId - Run ID for encryption context
1322
1637
  * @param key - Encryption key (undefined to skip encryption)
1638
+ * @param ops - Promise array for stream operations
1323
1639
  * @param global - Global object for serialization context
1324
1640
  * @returns The dehydrated value as binary data (Uint8Array) with format prefix
1325
1641
  */
1326
- export async function dehydrateWorkflowReturnValue(value, _runId, key, global = globalThis, v1Compat = false) {
1642
+ export async function dehydrateStepError(value, runId, key, ops = [], global = globalThis) {
1327
1643
  try {
1328
- const str = stringify(value, getWorkflowReducers(global));
1329
- if (v1Compat) {
1330
- return revive(str);
1331
- }
1644
+ const str = stringify(value, getStepReducers(global, ops, runId, key));
1332
1645
  const payload = new TextEncoder().encode(str);
1333
1646
  const serialized = encodeWithFormatPrefix(SerializationFormat.DEVALUE_V1, payload);
1334
- // Encrypt if world supports encryption
1335
- return maybeEncrypt(serialized, key);
1647
+ return (await maybeEncrypt(serialized, key));
1336
1648
  }
1337
1649
  catch (error) {
1338
- throw new WorkflowRuntimeError(formatSerializationError('workflow return value', error), { slug: 'serialization-failed', cause: error });
1650
+ const cause = unwrapSerializationCause(error);
1651
+ const { message, hint } = formatSerializationError('step error', cause);
1652
+ throw new SerializationError(message, { hint, cause });
1339
1653
  }
1340
1654
  }
1341
1655
  /**
1342
- * Called from the client side (i.e. the execution environment where
1343
- * the workflow run was initiated from) to hydrate the workflow
1344
- * return value of a completed workflow run.
1656
+ * Called from the workflow handler when replaying the event log of a
1657
+ * `step_failed` or `step_retrying` event. Hydrates the thrown value from
1658
+ * the database so the workflow can see the original thrown value.
1345
1659
  *
1346
1660
  * @param value - Binary serialized data (Uint8Array) with format prefix
1347
1661
  * @param runId - Run ID for decryption context
1348
1662
  * @param key - Encryption key (undefined to skip decryption)
1349
- * @param ops - Promise array for stream operations
1350
1663
  * @param global - Global object for deserialization context
1351
1664
  * @param extraRevivers - Additional revivers for custom types
1352
- * @returns The hydrated return value, ready to be consumed by the client
1665
+ * @returns The hydrated thrown value, ready to reject the step promise
1353
1666
  */
1354
- export async function hydrateWorkflowReturnValue(value, runId, key, ops = [], global = globalThis, extraRevivers = {}) {
1355
- // Decrypt if needed
1667
+ export async function hydrateStepError(value, _runId, key, global = globalThis, extraRevivers = {}) {
1356
1668
  const decrypted = await maybeDecrypt(value, key);
1357
- // Legacy specVersion 1 runs stored data as plain JSON arrays (not binary).
1358
- // These pass through maybeDecrypt unchanged and are deserialized directly
1359
- // via devalue's unflatten().
1360
1669
  if (!(decrypted instanceof Uint8Array)) {
1670
+ // Treated as a devalue "flattened" array. In production this branch is
1671
+ // exercised by legacy code paths that bypassed `dehydrateStepError`; the
1672
+ // SDK version is pinned per workflow run via skew protection, so a
1673
+ // current-version producer always emits a Uint8Array here. If a
1674
+ // misshapen value reaches us, `unflatten` throws — that's intentional:
1675
+ // the higher-level hydration helpers (`hydrateStepIO`,
1676
+ // `hydrateResourceIO`) already wrap us in a try/catch that leaves the
1677
+ // field un-hydrated for o11y display, and surfacing the throw to logs
1678
+ // is more debuggable than silently masking the unsupported shape.
1361
1679
  return unflatten(decrypted, {
1362
- ...getExternalRevivers(global, ops, runId, key),
1680
+ ...getWorkflowRevivers(global),
1363
1681
  ...extraRevivers,
1364
1682
  });
1365
1683
  }
1366
1684
  const { format, payload } = decodeFormatPrefix(decrypted);
1367
1685
  if (format === SerializationFormat.DEVALUE_V1) {
1368
1686
  const str = new TextDecoder().decode(payload);
1369
- const obj = parse(str, {
1370
- ...getExternalRevivers(global, ops, runId, key),
1687
+ return parse(str, {
1688
+ ...getWorkflowRevivers(global),
1371
1689
  ...extraRevivers,
1372
1690
  });
1373
- return obj;
1374
1691
  }
1375
1692
  throw new Error(`Unsupported serialization format: ${format}`);
1376
1693
  }
1377
1694
  /**
1378
- * Called from the workflow handler when a step is being created.
1379
- * Dehydrates values from within the workflow execution environment
1380
- * into a format that can be saved to the database.
1695
+ * Called from the workflow handler when the workflow itself throws.
1696
+ * Dehydrates the thrown value from within the workflow execution environment
1697
+ * into a format that can be saved to the database in a `run_failed` event.
1381
1698
  *
1382
- * @param value - The value to serialize
1699
+ * @param value - The thrown value to serialize (can be any type)
1383
1700
  * @param runId - Run ID for encryption context
1384
1701
  * @param key - Encryption key (undefined to skip encryption)
1385
1702
  * @param global - Global object for serialization context
1386
- * @param v1Compat - Enable legacy v1 compatibility mode
1387
1703
  * @returns The dehydrated value as binary data (Uint8Array) with format prefix
1388
1704
  */
1389
- export async function dehydrateStepArguments(value, _runId, key, global = globalThis, v1Compat = false) {
1705
+ export async function dehydrateRunError(value, _runId, key, global = globalThis) {
1390
1706
  try {
1391
1707
  const str = stringify(value, getWorkflowReducers(global));
1392
- if (v1Compat) {
1393
- return revive(str);
1394
- }
1395
1708
  const payload = new TextEncoder().encode(str);
1396
1709
  const serialized = encodeWithFormatPrefix(SerializationFormat.DEVALUE_V1, payload);
1397
- // Encrypt if world supports encryption
1398
- return maybeEncrypt(serialized, key);
1710
+ return (await maybeEncrypt(serialized, key));
1399
1711
  }
1400
1712
  catch (error) {
1401
- throw new WorkflowRuntimeError(formatSerializationError('step arguments', error), { slug: 'serialization-failed', cause: error });
1713
+ const cause = unwrapSerializationCause(error);
1714
+ const { message, hint } = formatSerializationError('run error', cause);
1715
+ throw new SerializationError(message, { hint, cause });
1402
1716
  }
1403
1717
  }
1404
1718
  /**
1405
- * Called from the step handler to hydrate the arguments of a step
1406
- * from the database at the start of the step execution.
1719
+ * Called from the client side (or observability tools) to hydrate the run
1720
+ * error value of a failed workflow run.
1407
1721
  *
1408
1722
  * @param value - Binary serialized data (Uint8Array) with format prefix
1409
1723
  * @param runId - Run ID for decryption context
@@ -1411,59 +1725,31 @@ export async function dehydrateStepArguments(value, _runId, key, global = global
1411
1725
  * @param ops - Promise array for stream operations
1412
1726
  * @param global - Global object for deserialization context
1413
1727
  * @param extraRevivers - Additional revivers for custom types
1414
- * @returns The hydrated value, ready to be consumed by the step user-code function
1728
+ * @returns The hydrated thrown value, ready to be consumed by the client
1415
1729
  */
1416
- export async function hydrateStepArguments(value, runId, key, ops = [], global = globalThis, extraRevivers = {}) {
1417
- // Decrypt if needed
1730
+ export async function hydrateRunError(value, runId, key, ops = [], global = globalThis, extraRevivers = {}) {
1418
1731
  const decrypted = await maybeDecrypt(value, key);
1419
- // Legacy specVersion 1 runs stored data as plain JSON arrays (not binary).
1420
- // These pass through maybeDecrypt unchanged and are deserialized directly
1421
- // via devalue's unflatten().
1422
1732
  if (!(decrypted instanceof Uint8Array)) {
1733
+ // See the matching note in `hydrateStepError`: this branch is for
1734
+ // devalue flattened arrays from legacy callers; current SDK versions
1735
+ // always emit a Uint8Array, and a misshapen value here intentionally
1736
+ // throws via `unflatten` so the surrounding try/catch in o11y helpers
1737
+ // surfaces the issue rather than masking it.
1423
1738
  return unflatten(decrypted, {
1424
- ...getStepRevivers(global, ops, runId, key),
1739
+ ...getExternalRevivers(global, ops, runId, key),
1425
1740
  ...extraRevivers,
1426
1741
  });
1427
1742
  }
1428
1743
  const { format, payload } = decodeFormatPrefix(decrypted);
1429
1744
  if (format === SerializationFormat.DEVALUE_V1) {
1430
1745
  const str = new TextDecoder().decode(payload);
1431
- const obj = parse(str, {
1432
- ...getStepRevivers(global, ops, runId, key),
1746
+ return parse(str, {
1747
+ ...getExternalRevivers(global, ops, runId, key),
1433
1748
  ...extraRevivers,
1434
1749
  });
1435
- return obj;
1436
1750
  }
1437
1751
  throw new Error(`Unsupported serialization format: ${format}`);
1438
1752
  }
1439
- /**
1440
- * Called from the step handler when a step has completed.
1441
- * Dehydrates values from within the step execution environment
1442
- * into a format that can be saved to the database.
1443
- *
1444
- * @param value - The value to serialize
1445
- * @param runId - Run ID for encryption context
1446
- * @param key - Encryption key (undefined to skip encryption)
1447
- * @param ops - Promise array for stream operations
1448
- * @param global - Global object for serialization context
1449
- * @param v1Compat - Enable legacy v1 compatibility mode
1450
- * @returns The dehydrated value as binary data (Uint8Array) with format prefix
1451
- */
1452
- export async function dehydrateStepReturnValue(value, runId, key, ops = [], global = globalThis, v1Compat = false) {
1453
- try {
1454
- const str = stringify(value, getStepReducers(global, ops, runId, key));
1455
- if (v1Compat) {
1456
- return revive(str);
1457
- }
1458
- const payload = new TextEncoder().encode(str);
1459
- const serialized = encodeWithFormatPrefix(SerializationFormat.DEVALUE_V1, payload);
1460
- // Encrypt if world supports encryption
1461
- return maybeEncrypt(serialized, key);
1462
- }
1463
- catch (error) {
1464
- throw new WorkflowRuntimeError(formatSerializationError('step return value', error), { slug: 'serialization-failed', cause: error });
1465
- }
1466
- }
1467
1753
  /**
1468
1754
  * Called from the workflow handler when replaying the event log of a `step_completed` event.
1469
1755
  * Hydrates the return value of a step from the database.
@@ -1473,28 +1759,53 @@ export async function dehydrateStepReturnValue(value, runId, key, ops = [], glob
1473
1759
  * @param key - Encryption key (undefined to skip decryption)
1474
1760
  * @param global - Global object for deserialization context
1475
1761
  * @param extraRevivers - Additional revivers for custom types
1476
- * @returns The hydrated return value of a step, ready to be consumed by the workflow handler
1762
+ * Called from the workflow handler when replaying the event log
1763
+ * of a `step_completed` event.
1477
1764
  */
1478
1765
  export async function hydrateStepReturnValue(value, _runId, key, global = globalThis, extraRevivers = {}) {
1479
- // Decrypt if needed
1480
- const decrypted = await maybeDecrypt(value, key);
1481
- // Legacy specVersion 1 runs stored data as plain JSON arrays (not binary).
1482
- // These pass through maybeDecrypt unchanged and are deserialized directly
1483
- // via devalue's unflatten().
1484
- if (!(decrypted instanceof Uint8Array)) {
1485
- return unflatten(decrypted, {
1486
- ...getWorkflowRevivers(global),
1766
+ return workflowModule.deserialize(await maybeDecrypt(value, key), {
1767
+ global,
1768
+ extraRevivers: {
1769
+ ...getStreamAndRequestRevivers(getWorkflowRevivers(global)),
1487
1770
  ...extraRevivers,
1488
- });
1771
+ },
1772
+ });
1773
+ }
1774
+ // ---- Helpers to extract stream/Request/Response reducers and revivers ----
1775
+ // The mode-specific get*Reducers/get*Revivers functions return objects that
1776
+ // include both "common" entries (Date, Error, Map, etc.) and mode-specific
1777
+ // entries (ReadableStream, WritableStream, Request, Response, StepFunction).
1778
+ // The common entries are already composed by the codec. We only need to
1779
+ // pass through the mode-specific entries as extraReducers/extraRevivers.
1780
+ const STREAM_AND_REQUEST_KEYS = [
1781
+ 'ReadableStream',
1782
+ 'WritableStream',
1783
+ 'Request',
1784
+ 'Response',
1785
+ 'StepFunction',
1786
+ // Wire AbortController/AbortSignal through the client serialization path so
1787
+ // signals reachable via Request.signal (or as direct arguments) get their
1788
+ // dedicated reducer. Without this, devalue falls back to its arbitrary-POJO
1789
+ // path and fails for any signal the Request reducer forwards.
1790
+ 'AbortController',
1791
+ 'AbortSignal',
1792
+ ];
1793
+ function getStreamAndRequestReducers(allReducers) {
1794
+ const extra = {};
1795
+ for (const key of STREAM_AND_REQUEST_KEYS) {
1796
+ if (key in allReducers) {
1797
+ extra[key] = allReducers[key];
1798
+ }
1489
1799
  }
1490
- const { format, payload } = decodeFormatPrefix(decrypted);
1491
- if (format === SerializationFormat.DEVALUE_V1) {
1492
- const str = new TextDecoder().decode(payload);
1493
- return parse(str, {
1494
- ...getWorkflowRevivers(global),
1495
- ...extraRevivers,
1496
- });
1800
+ return extra;
1801
+ }
1802
+ function getStreamAndRequestRevivers(allRevivers) {
1803
+ const extra = {};
1804
+ for (const key of STREAM_AND_REQUEST_KEYS) {
1805
+ if (key in allRevivers) {
1806
+ extra[key] = allRevivers[key];
1807
+ }
1497
1808
  }
1498
- throw new Error(`Unsupported serialization format: ${format}`);
1809
+ return extra;
1499
1810
  }
1500
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VyaWFsaXphdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9zZXJpYWxpemF0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDbEMsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDeEQsT0FBTyxFQUFFLG9CQUFvQixFQUFFLGtCQUFrQixFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDM0UsT0FBTyxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUNwRSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDeEMsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDakUsT0FBTyxFQUNMLE9BQU8sSUFBSSxhQUFhLEVBQ3hCLE9BQU8sSUFBSSxhQUFhLEdBRXpCLE1BQU0saUJBQWlCLENBQUM7QUFhekIsT0FBTyxFQUNMLG9CQUFvQixFQUNwQixhQUFhLEVBQ2IsZ0JBQWdCLEVBQ2hCLGdCQUFnQixHQUNqQixNQUFNLHVCQUF1QixDQUFDO0FBQy9CLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDNUMsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUMvQyxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDOUMsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQzNELE9BQU8sRUFDTCxnQkFBZ0IsRUFDaEIsV0FBVyxFQUNYLGtCQUFrQixFQUNsQixrQkFBa0IsRUFDbEIseUJBQXlCLEdBQzFCLE1BQU0sY0FBYyxDQUFDO0FBRXRCLCtFQUErRTtBQUMvRSxxQ0FBcUM7QUFDckMsK0VBQStFO0FBQy9FLEVBQUU7QUFDRiw0RUFBNEU7QUFD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
1811
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VyaWFsaXphdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9zZXJpYWxpemF0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCxzQkFBc0IsRUFDdEIsa0JBQWtCLEVBQ2xCLG9CQUFvQixHQUNyQixNQUFNLGtCQUFrQixDQUFDO0FBQzFCLE9BQU8sRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUN0RCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDeEMsT0FBTyxFQUNMLE9BQU8sSUFBSSxhQUFhLEVBQ3hCLE9BQU8sSUFBSSxhQUFhLEVBRXhCLFNBQVMsR0FDVixNQUFNLGlCQUFpQixDQUFDO0FBQ3pCLE9BQU8sRUFDTCxvQkFBb0IsRUFDcEIsYUFBYSxFQUNiLGdCQUFnQixFQUNoQixnQkFBZ0IsR0FDakIsTUFBTSx1QkFBdUIsQ0FBQztBQUMvQixPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQy9DLDJFQUEyRTtBQUMzRSwwRUFBMEU7QUFDMUUsMEVBQTBFO0FBQzFFLDREQUE0RDtBQUM1RCxzRUFBc0U7QUFDdEUsc0RBQXNEO0FBQ3RELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUMzRCxPQUFPLEtBQUssWUFBWSxNQUFNLDJCQUEyQixDQUFDO0FBQzFELE9BQU8sRUFDTCxPQUFPLEVBRVAsT0FBTyxHQUNSLE1BQU0sK0JBQStCLENBQUM7QUFDdkMsT0FBTyxFQUNMLHdCQUF3QixFQUN4QixxQkFBcUIsR0FDdEIsTUFBTSwyQkFBMkIsQ0FBQztBQUNuQyxPQUFPLEVBQ0wsa0JBQWtCLEVBQ2xCLHNCQUFzQixFQUN0QixXQUFXLEVBQ1gsZ0JBQWdCLEdBQ2pCLE1BQU0sMkJBQTJCLENBQUM7QUFDbkMsT0FBTyxFQUNMLGdCQUFnQixFQUNoQixnQkFBZ0IsR0FDakIsTUFBTSxt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SyxDQUFDLEdBQUcsQ0FBQyxHQUFHLFdBQVcsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNoQyxDQUFDO0lBQ0gsQ0FBQztJQUNELE9BQU8sS0FBSyxDQUFDO0FBQ2YsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIFJ1bnRpbWVEZWNyeXB0aW9uRXJyb3IsXG4gIFNlcmlhbGl6YXRpb25FcnJvcixcbiAgV29ya2Zsb3dSdW50aW1lRXJyb3IsXG59IGZyb20gJ0B3b3JrZmxvdy9lcnJvcnMnO1xuaW1wb3J0IHsgcGFyc2UsIHN0cmluZ2lmeSwgdW5mbGF0dGVuIH0gZnJvbSAnZGV2YWx1ZSc7XG5pbXBvcnQgeyBtb25vdG9uaWNGYWN0b3J5IH0gZnJvbSAndWxpZCc7XG5pbXBvcnQge1xuICBkZWNyeXB0IGFzIGFlc0djbURlY3J5cHQsXG4gIGVuY3J5cHQgYXMgYWVzR2NtRW5jcnlwdCxcbiAgdHlwZSBDcnlwdG9LZXksXG4gIGltcG9ydEtleSxcbn0gZnJvbSAnLi9lbmNyeXB0aW9uLmpzJztcbmltcG9ydCB7XG4gIGNyZWF0ZUZsdXNoYWJsZVN0YXRlLFxuICBmbHVzaGFibGVQaXBlLFxuICBwb2xsUmVhZGFibGVMb2NrLFxuICBwb2xsV3JpdGFibGVMb2NrLFxufSBmcm9tICcuL2ZsdXNoYWJsZS1zdHJlYW0uanMnO1xuaW1wb3J0IHsgZ2V0U3RlcEZ1bmN0aW9uIH0gZnJvbSAnLi9wcml2YXRlLmpzJztcbi8vIFYyOiB1c2UgZ2V0V29ybGRMYXp5IGluIHN0ZXAtc2lkZSBjb2RlIHBhdGhzIHNvIFR1cmJvcGFjayBjYW4gc3RhdGljYWxseVxuLy8gcmVzb2x2ZSB0aGUgd29ybGQgYnJpZGdlIGZyb20gdGhlIHN0ZXAgYnVuZGxlIHdpdGhvdXQgZHJhZ2dpbmcgdGhlIGZ1bGxcbi8vIHdvcmxkLnRzIG1vZHVsZSAoYW5kIGl0cyBkeW5hbWljLWltcG9ydCBiZWhhdmlvdXIpIGludG8gdGhlIGZsb3cgcm91dGUuXG4vLyBTZWUgYHBhY2thZ2VzL2NvcmUvc3JjL3J1bnRpbWUvZ2V0LXdvcmxkLWxhenkudHNgIGFuZCB0aGVcbi8vIFwiVHVyYm9wYWNrIE5GVCBUcmFjaW5nIEVycm9ycyBpbiBWMiBDb21iaW5lZCBGbG93IFJvdXRlXCIgc2VjdGlvbiBvZlxuLy8gYGRvY3MvY29udGVudC9kb2NzL2NoYW5nZWxvZy9lYWdlci1wcm9jZXNzaW5nLm1keGAuXG5pbXBvcnQgeyBnZXRXb3JsZExhenkgfSBmcm9tICcuL3J1bnRpbWUvZ2V0LXdvcmxkLWxhenkuanMnO1xuaW1wb3J0ICogYXMgY2xpZW50TW9kdWxlIGZyb20gJy4vc2VyaWFsaXphdGlvbi9jbGllbnQuanMnO1xuaW1wb3J0IHtcbiAgZGVjcnlwdCxcbiAgdHlwZSBFbmNyeXB0aW9uS2V5UGFyYW0sXG4gIGVuY3J5cHQsXG59IGZyb20gJy4vc2VyaWFsaXphdGlvbi9lbmNyeXB0aW9uLmpzJztcbmltcG9ydCB7XG4gIGZvcm1hdFNlcmlhbGl6YXRpb25FcnJvcixcbiAgcmV0aHJvd0lmUnVudGltZUVycm9yLFxufSBmcm9tICcuL3NlcmlhbGl6YXRpb24vZXJyb3JzLmpzJztcbmltcG9ydCB7XG4gIGRlY29kZUZvcm1hdFByZWZpeCxcbiAgZW5jb2RlV2l0aEZvcm1hdFByZWZpeCxcbiAgaXNFbmNyeXB0ZWQsXG4gIHBlZWtGb3JtYXRQcmVmaXgsXG59IGZyb20gJy4vc2VyaWFsaXphdGlvbi9mb3JtYXQuanMnO1xuaW1wb3J0IHtcbiAgZ2V0Q2xhc3NSZWR1Y2VycyxcbiAgZ2V0Q2xhc3NSZXZpdmVycyxcbn0gZnJvbSAnLi9zZXJpYWxpemF0aW9uL3JlZHVjZXJzL2NsYXNzLmpzJztcbmltcG9ydCB7XG4gIGdldENvbW1vblJlZHVjZXJzLFxuICBnZXRDb21tb25SZXZpdmVycyBhcyBnZXRDb21tb25SZXZpdmVyc0Zyb21Nb2R1bGUsXG4gIHJldml2ZSxcbn0gZnJvbSAnLi9zZXJpYWxpemF0aW9uL3JlZHVjZXJzL2NvbW1vbi5qcyc7XG5pbXBvcnQge1xuICBnZXRTdGVwRnVuY3Rpb25SZWR1Y2VyLFxuICBnZXRTdGVwRnVuY3Rpb25SZXZpdmVyLFxufSBmcm9tICcuL3NlcmlhbGl6YXRpb24vcmVkdWNlcnMvc3RlcC1mdW5jdGlvbi5qcyc7XG5pbXBvcnQgKiBhcyBzdGVwTW9kdWxlIGZyb20gJy4vc2VyaWFsaXphdGlvbi9zdGVwLmpzJztcbmltcG9ydCB7XG4gIHR5cGUgRm9ybWF0UHJlZml4LFxuICBpc0Zvcm1hdFByZWZpeCxcbiAgU2VyaWFsaXphdGlvbkZvcm1hdCxcbn0gZnJvbSAnLi9zZXJpYWxpemF0aW9uL3R5cGVzLmpzJztcbmltcG9ydCAqIGFzIHdvcmtmbG93TW9kdWxlIGZyb20gJy4vc2VyaWFsaXphdGlvbi93b3JrZmxvdy5qcyc7XG5pbXBvcnQgeyBjb250ZXh0U3RvcmFnZSB9IGZyb20gJy4vc3RlcC9jb250ZXh0LXN0b3JhZ2UuanMnO1xuaW1wb3J0IHtcbiAgQUJPUlRfSE9PS19UT0tFTixcbiAgQUJPUlRfTElTVEVORVJfQVRUQUNIRUQsXG4gIEFCT1JUX1JFQURFUl9DQU5DRUwsXG4gIEFCT1JUX1NUUkVBTV9OQU1FLFxuICBCT0RZX0lOSVRfU1lNQk9MLFxuICBTVEFCTEVfVUxJRCxcbiAgU1RSRUFNX05BTUVfU1lNQk9MLFxuICBTVFJFQU1fU0VSVkVSX0RFUExPWU1FTlRfSURfU1lNQk9MLFxuICBTVFJFQU1fU0VSVkVSX1JVTl9JRF9TWU1CT0wsXG4gIFNUUkVBTV9UWVBFX1NZTUJPTCxcbiAgV0VCSE9PS19SRVNQT05TRV9XUklUQUJMRSxcbn0gZnJvbSAnLi9zeW1ib2xzLmpzJztcbmltcG9ydCB7IGdldEFib3J0U3RyZWFtSWQgfSBmcm9tICcuL3V0aWwuanMnO1xuaW1wb3J0IHsgV29ya2Zsb3dBYm9ydFNpZ25hbCB9IGZyb20gJy4vd29ya2Zsb3cvYWJvcnQtY29udHJvbGxlci5qcyc7XG5cbi8vIFJlLWV4cG9ydCB0eXBlcyBhbmQgdXRpbGl0aWVzIGZyb20gdGhlIG1vZHVsYXIgc2VyaWFsaXphdGlvbiBtb2R1bGVzXG4vLyBzbyBleGlzdGluZyBjb25zdW1lcnMgb2YgYEB3b3JrZmxvdy9jb3JlL3NlcmlhbGl6YXRpb25gIGtlZXAgd29ya2luZy5cbmV4cG9ydCB7XG4gIFNlcmlhbGl6YXRpb25Gb3JtYXQsXG4gIHR5cGUgRm9ybWF0UHJlZml4LFxuICBpc0Zvcm1hdFByZWZpeCxcbiAgZW5jb2RlV2l0aEZvcm1hdFByZWZpeCxcbiAgZGVjb2RlRm9ybWF0UHJlZml4LFxuICBwZWVrRm9ybWF0UHJlZml4LFxuICBpc0VuY3J5cHRlZCxcbiAgZW5jcnlwdCxcbiAgZGVjcnlwdCxcbiAgdHlwZSBFbmNyeXB0aW9uS2V5UGFyYW0sXG59O1xuXG4vLyBSZS1leHBvcnQgdGhlIGxlZ2FjeSBTZXJpYWxpemF0aW9uRm9ybWF0VHlwZSBmb3IgYmFja3dhcmRzIGNvbXBhdGliaWxpdHkuXG4vLyBOZXcgY29kZSBzaG91bGQgdXNlIEZvcm1hdFByZWZpeCBmcm9tICcuL3NlcmlhbGl6YXRpb24vdHlwZXMuanMnLlxuZXhwb3J0IHR5cGUgU2VyaWFsaXphdGlvbkZvcm1hdFR5cGUgPVxuICAodHlwZW9mIFNlcmlhbGl6YXRpb25Gb3JtYXQpW2tleW9mIHR5cGVvZiBTZXJpYWxpemF0aW9uRm9ybWF0XTtcblxuLyoqXG4gKiBEZWZhdWx0IFVMSUQgZ2VuZXJhdG9yIGZvciBjb250ZXh0cyB3aGVyZSBWTSdzIHNlZWRlZCBgc3RhYmxlVWxpZGAgaXNuJ3QgYXZhaWxhYmxlLlxuICogVXNlZCBhcyBhIGZhbGxiYWNrIHdoZW4gc2VyaWFsaXppbmcgc3RyZWFtcyBvdXRzaWRlIHRoZSB3b3JrZmxvdyBWTSBjb250ZXh0XG4gKiAoZS5nLiwgd2hlbiBzdGFydGluZyBhIHdvcmtmbG93IG9yIGhhbmRsaW5nIHN0ZXAgcmV0dXJuIHZhbHVlcykuXG4gKi9cbmNvbnN0IGRlZmF1bHRVbGlkID0gbW9ub3RvbmljRmFjdG9yeSgpO1xuXG4vKipcbiAqIERldGVjdCBpZiBhIHJlYWRhYmxlIHN0cmVhbSBpcyBhIGJ5dGUgc3RyZWFtLlxuICpcbiAqIEBwYXJhbSBzdHJlYW1cbiAqIEByZXR1cm5zIGBcImJ5dGVzXCJgIGlmIHRoZSBzdHJlYW0gaXMgYSBieXRlIHN0cmVhbSwgYHVuZGVmaW5lZGAgb3RoZXJ3aXNlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRTdHJlYW1UeXBlKHN0cmVhbTogUmVhZGFibGVTdHJlYW0pOiAnYnl0ZXMnIHwgdW5kZWZpbmVkIHtcbiAgdHJ5IHtcbiAgICBjb25zdCByZWFkZXIgPSBzdHJlYW0uZ2V0UmVhZGVyKHsgbW9kZTogJ2J5b2InIH0pO1xuICAgIHJlYWRlci5yZWxlYXNlTG9jaygpO1xuICAgIHJldHVybiAnYnl0ZXMnO1xuICB9IGNhdGNoIHt9XG59XG5cbi8qKlxuICogRnJhbWUgZm9ybWF0IGZvciBzdHJlYW0gY2h1bmtzOlxuICogICBbNC1ieXRlIGJpZy1lbmRpYW4gbGVuZ3RoXVtmb3JtYXQtcHJlZml4ZWQgcGF5bG9hZF1cbiAqXG4gKiBFYWNoIGNodW5rIGlzIGluZGVwZW5kZW50bHkgZnJhbWVkIHNvIHRoZSBkZXNlcmlhbGl6ZXIgY2FuIGZpbmRcbiAqIGNodW5rIGJvdW5kYXJpZXMgZXZlbiB3aGVuIG11bHRpcGxlIGNodW5rcyBhcmUgY29uY2F0ZW5hdGVkIG9yXG4gKiBzcGxpdCBhY3Jvc3MgdHJhbnNwb3J0IHJlYWRzLlxuICovXG5jb25zdCBGUkFNRV9IRUFERVJfU0laRSA9IDQ7XG5cbi8qKlxuICogVGhlIG1vZGUtc3BlY2lmaWMgc2VyaWFsaXplcnMgKGAuL3NlcmlhbGl6YXRpb24ve2NsaWVudCxzdGVwLHdvcmtmbG93fS50c2ApXG4gKiBhbHJlYWR5IHRocm93IGEgYFNlcmlhbGl6YXRpb25FcnJvcmAgd2hvc2UgYC5jYXVzZWAgaXMgdGhlIHVuZGVybHlpbmdcbiAqIGRldmFsdWUgLyBzZXJkZSBmYWlsdXJlLiBUaGUgb3V0ZXIgZGVoeWRyYXRlL2h5ZHJhdGUgd3JhcHBlcnMgd2FudCB0b1xuICogcmUtZnJhbWUgdGhhdCBlcnJvciB3aXRoIGEgbW9yZSBzcGVjaWZpYyBjb250ZXh0IGxhYmVsIChlLmcuIFwid29ya2Zsb3dcbiAqIGFyZ3VtZW50c1wiIGluc3RlYWQgb2YgZ2VuZXJpYyBcIndvcmtmbG93IHZhbHVlXCIpLCBzbyB0aGV5IHVud3JhcCB0aGVcbiAqIGlubmVyIFNlcmlhbGl6YXRpb25FcnJvciBhbmQgcmVmb3JtYXQgd2l0aCB0aGUgb3JpZ2luYWwgY2F1c2UuIEVycm9yc1xuICogdGhhdCBhcmVuJ3QgYWxyZWFkeSBTZXJpYWxpemF0aW9uRXJyb3IgZmxvdyB0aHJvdWdoIHVuY2hhbmdlZC5cbiAqXG4gKiBgUnVudGltZURlY3J5cHRpb25FcnJvcmAgaXMgYW4gZXhjZXB0aW9uOiBpdCBtdXN0IGtlZXAgaXRzIGlkZW50aXR5IChhbmRcbiAqIGBjb250ZXh0YCkgc28gdGhlIHJ1bi1mYWlsdXJlIGNsYXNzaWZpZXIgcm91dGVzIGl0IHRvIGBSVU5USU1FX0VSUk9SYCxcbiAqIHNvIHRoaXMgcmV0aHJvd3MgaXQgdW5jaGFuZ2VkIGJlZm9yZSBhbnkgdW53cmFwcGluZy4gTm90ZSB0aGlzIGd1YXJkXG4gKiBtdXN0IHJ1biBiZWZvcmUgdGhlIGdlbmVyaWMgYFdvcmtmbG93UnVudGltZUVycm9yYCB1bndyYXAgYmVsb3csIHNpbmNlXG4gKiBgUnVudGltZURlY3J5cHRpb25FcnJvcmAgZXh0ZW5kcyBgV29ya2Zsb3dSdW50aW1lRXJyb3JgIGFuZCBjYXJyaWVzIGFcbiAqIGBjYXVzZWAgKHRoZSB1bmRlcmx5aW5nIERPTUV4Y2VwdGlvbikgdGhhdCB3b3VsZCBvdGhlcndpc2UgYmUgdW53cmFwcGVkXG4gKiBhbmQgcmVmcmFtZWQgYXMgYSBgU2VyaWFsaXphdGlvbkVycm9yYC5cbiAqL1xuZnVuY3Rpb24gdW53cmFwU2VyaWFsaXphdGlvbkNhdXNlKGVycm9yOiB1bmtub3duKTogdW5rbm93biB7XG4gIHJldGhyb3dJZlJ1bnRpbWVFcnJvcihlcnJvcik7XG4gIGlmIChlcnJvciBpbnN0YW5jZW9mIFNlcmlhbGl6YXRpb25FcnJvciAmJiBlcnJvci5jYXVzZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIGVycm9yLmNhdXNlO1xuICB9XG4gIGlmIChlcnJvciBpbnN0YW5jZW9mIFdvcmtmbG93UnVudGltZUVycm9yICYmIGVycm9yLmNhdXNlICE9PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4gZXJyb3IuY2F1c2U7XG4gIH1cbiAgcmV0dXJuIGVycm9yO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0U2VyaWFsaXplU3RyZWFtKFxuICByZWR1Y2VyczogUGFydGlhbDxSZWR1Y2Vycz4sXG4gIGNyeXB0b0tleTogRW5jcnlwdGlvbktleVBhcmFtXG4pOiBUcmFuc2Zvcm1TdHJlYW08YW55LCBVaW50OEFycmF5PiB7XG4gIGNvbnN0IGVuY29kZXIgPSBuZXcgVGV4dEVuY29kZXIoKTtcbiAgLy8gUmVzb2x2ZSB0aGUga2V5IHByb21pc2Ugb25jZSBvbiBmaXJzdCB1c2UgYW5kIGNhY2hlIHRoZSByZXN1bHQuXG4gIC8vIE5vdGU6IGlmIHRoZSBjcnlwdG9LZXkgcHJvbWlzZSByZWplY3RzIChlLmcuLCBuZXR3b3JrIGVycm9yIGZldGNoaW5nXG4gIC8vIHRoZSBkZXJpdmVkIGtleSksIHRoZSByZWplY3Rpb24gd29uJ3Qgc3VyZmFjZSB1bnRpbCB0aGUgZmlyc3QgY2h1bmtcbiAgLy8gaXMgcHJvY2Vzc2VkIOKAlCBub3QgYXQgc3RyZWFtIGNvbnN0cnVjdGlvbiB0aW1lLlxuICBjb25zdCBrZXlTdGF0ZSA9IHsgcmVzb2x2ZWQ6IGZhbHNlLCBrZXk6IHVuZGVmaW5lZCBhcyBDcnlwdG9LZXkgfCB1bmRlZmluZWQgfTtcbiAgY29uc3Qgc3RyZWFtID0gbmV3IFRyYW5zZm9ybVN0cmVhbTxhbnksIFVpbnQ4QXJyYXk+KHtcbiAgICBhc3luYyB0cmFuc2Zvcm0oY2h1bmssIGNvbnRyb2xsZXIpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGlmICgha2V5U3RhdGUucmVzb2x2ZWQpIHtcbiAgICAgICAgICBrZXlTdGF0ZS5rZXkgPSBhd2FpdCBjcnlwdG9LZXk7XG4gICAgICAgICAga2V5U3RhdGUucmVzb2x2ZWQgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHNlcmlhbGl6ZWQgPSBzdHJpbmdpZnkoY2h1bmssIHJlZHVjZXJzKTtcbiAgICAgICAgY29uc3QgcGF5bG9hZCA9IGVuY29kZXIuZW5jb2RlKHNlcmlhbGl6ZWQpO1xuICAgICAgICBsZXQgcHJlZml4ZWQgPSBlbmNvZGVXaXRoRm9ybWF0UHJlZml4KFxuICAgICAgICAgIFNlcmlhbGl6YXRpb25Gb3JtYXQuREVWQUxVRV9WMSxcbiAgICAgICAgICBwYXlsb2FkXG4gICAgICAgICkgYXMgVWludDhBcnJheTtcblxuICAgICAgICAvLyBFbmNyeXB0IHRoZSBmcmFtZSBwYXlsb2FkIGlmIGEga2V5IGlzIHByb3ZpZGVkLlxuICAgICAgICAvLyBUaGUgbGVuZ3RoIGhlYWRlciByZW1haW5zIGluIHRoZSBjbGVhciBzbyB0aGUgZGVzZXJpYWxpemVyIGNhblxuICAgICAgICAvLyBmaW5kIGZyYW1lIGJvdW5kYXJpZXMgcmVnYXJkbGVzcyBvZiB0cmFuc3BvcnQgY2h1bmtpbmcuXG4gICAgICAgIGlmIChrZXlTdGF0ZS5rZXkpIHtcbiAgICAgICAgICBjb25zdCBlbmNyeXB0ZWQgPSBhd2FpdCBhZXNHY21FbmNyeXB0KGtleVN0YXRlLmtleSwgcHJlZml4ZWQpO1xuICAgICAgICAgIHByZWZpeGVkID0gZW5jb2RlV2l0aEZvcm1hdFByZWZpeChcbiAgICAgICAgICAgIFNlcmlhbGl6YXRpb25Gb3JtYXQuRU5DUllQVEVELFxuICAgICAgICAgICAgZW5jcnlwdGVkXG4gICAgICAgICAgKSBhcyBVaW50OEFycmF5O1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gV3JpdGUgbGVuZ3RoLXByZWZpeGVkIGZyYW1lOiBbNC1ieXRlIGxlbmd0aF1bcHJlZml4ZWQgZGF0YV1cbiAgICAgICAgY29uc3QgZnJhbWUgPSBuZXcgVWludDhBcnJheShGUkFNRV9IRUFERVJfU0laRSArIHByZWZpeGVkLmxlbmd0aCk7XG4gICAgICAgIG5ldyBEYXRhVmlldyhmcmFtZS5idWZmZXIpLnNldFVpbnQzMigwLCBwcmVmaXhlZC5sZW5ndGgsIGZhbHNlKTtcbiAgICAgICAgZnJhbWUuc2V0KHByZWZpeGVkLCBGUkFNRV9IRUFERVJfU0laRSk7XG4gICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZShmcmFtZSk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAvLyBFbmNyeXB0aW9uIGZhaWx1cmVzIG11c3Qga2VlcCB0aGVpciBSdW50aW1lRGVjcnlwdGlvbkVycm9yXG4gICAgICAgIC8vIGlkZW50aXR5IChSVU5USU1FX0VSUk9SKSByYXRoZXIgdGhhbiBiZSByZWZyYW1lZCBhcyBhXG4gICAgICAgIC8vIFNlcmlhbGl6YXRpb25FcnJvciAoVVNFUl9FUlJPUikuXG4gICAgICAgIGlmIChSdW50aW1lRGVjcnlwdGlvbkVycm9yLmlzKGVycm9yKSkge1xuICAgICAgICAgIGNvbnRyb2xsZXIuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB7IG1lc3NhZ2UsIGhpbnQgfSA9IGZvcm1hdFNlcmlhbGl6YXRpb25FcnJvcihcbiAgICAgICAgICAnc3RyZWFtIGNodW5rJyxcbiAgICAgICAgICBlcnJvclxuICAgICAgICApO1xuICAgICAgICBjb250cm9sbGVyLmVycm9yKFxuICAgICAgICAgIG5ldyBTZXJpYWxpemF0aW9uRXJyb3IobWVzc2FnZSwgeyBoaW50LCBjYXVzZTogZXJyb3IgfSlcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9LFxuICB9KTtcbiAgcmV0dXJuIHN0cmVhbTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldERlc2VyaWFsaXplU3RyZWFtKFxuICByZXZpdmVyczogUGFydGlhbDxSZXZpdmVycz4sXG4gIGNyeXB0b0tleTogRW5jcnlwdGlvbktleVBhcmFtXG4pOiBUcmFuc2Zvcm1TdHJlYW08VWludDhBcnJheSwgYW55PiB7XG4gIGNvbnN0IGRlY29kZXIgPSBuZXcgVGV4dERlY29kZXIoKTtcbiAgbGV0IGJ1ZmZlciA9IG5ldyBVaW50OEFycmF5KDApO1xuICAvLyBSZXNvbHZlIHRoZSBrZXkgcHJvbWlzZSBvbmNlIG9uIGZpcnN0IHVzZSBhbmQgY2FjaGUgdGhlIHJlc3VsdC5cbiAgY29uc3Qga2V5U3RhdGUgPSB7IHJlc29sdmVkOiBmYWxzZSwga2V5OiB1bmRlZmluZWQgYXMgQ3J5cHRvS2V5IHwgdW5kZWZpbmVkIH07XG5cbiAgZnVuY3Rpb24gYXBwZW5kVG9CdWZmZXIoZGF0YTogVWludDhBcnJheSkge1xuICAgIGNvbnN0IG5ld0J1ZmZlciA9IG5ldyBVaW50OEFycmF5KGJ1ZmZlci5sZW5ndGggKyBkYXRhLmxlbmd0aCk7XG4gICAgbmV3QnVmZmVyLnNldChidWZmZXIsIDApO1xuICAgIG5ld0J1ZmZlci5zZXQoZGF0YSwgYnVmZmVyLmxlbmd0aCk7XG4gICAgYnVmZmVyID0gbmV3QnVmZmVyO1xuICB9XG5cbiAgYXN5bmMgZnVuY3Rpb24gcHJvY2Vzc0ZyYW1lcyhcbiAgICBjb250cm9sbGVyOiBUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlcjxhbnk+XG4gICkge1xuICAgIC8vIFJlc29sdmUgdGhlIGtleSBwcm9taXNlIG9uY2Ugb24gZmlyc3QgdXNlIGFuZCBjYWNoZSB0aGUgcmVzdWx0XG4gICAgaWYgKCFrZXlTdGF0ZS5yZXNvbHZlZCkge1xuICAgICAga2V5U3RhdGUua2V5ID0gYXdhaXQgY3J5cHRvS2V5O1xuICAgICAga2V5U3RhdGUucmVzb2x2ZWQgPSB0cnVlO1xuICAgIH1cblxuICAgIC8vIFRyeSB0byBleHRyYWN0IGNvbXBsZXRlIGxlbmd0aC1wcmVmaXhlZCBmcmFtZXNcbiAgICB3aGlsZSAoYnVmZmVyLmxlbmd0aCA+PSBGUkFNRV9IRUFERVJfU0laRSkge1xuICAgICAgY29uc3QgZnJhbWVMZW5ndGggPSBuZXcgRGF0YVZpZXcoXG4gICAgICAgIGJ1ZmZlci5idWZmZXIsXG4gICAgICAgIGJ1ZmZlci5ieXRlT2Zmc2V0LFxuICAgICAgICBidWZmZXIuYnl0ZUxlbmd0aFxuICAgICAgKS5nZXRVaW50MzIoMCwgZmFsc2UpO1xuXG4gICAgICBpZiAoYnVmZmVyLmxlbmd0aCA8IEZSQU1FX0hFQURFUl9TSVpFICsgZnJhbWVMZW5ndGgpIHtcbiAgICAgICAgYnJlYWs7IC8vIEluY29tcGxldGUgZnJhbWUsIHdhaXQgZm9yIG1vcmUgZGF0YVxuICAgICAgfVxuXG4gICAgICBjb25zdCBmcmFtZURhdGEgPSBidWZmZXIuc2xpY2UoXG4gICAgICAgIEZSQU1FX0hFQURFUl9TSVpFLFxuICAgICAgICBGUkFNRV9IRUFERVJfU0laRSArIGZyYW1lTGVuZ3RoXG4gICAgICApO1xuICAgICAgYnVmZmVyID0gYnVmZmVyLnNsaWNlKEZSQU1FX0hFQURFUl9TSVpFICsgZnJhbWVMZW5ndGgpO1xuXG4gICAgICBsZXQgeyBmb3JtYXQsIHBheWxvYWQgfSA9IGRlY29kZUZvcm1hdFByZWZpeChmcmFtZURhdGEpO1xuXG4gICAgICAvLyBJZiB0aGUgZnJhbWUgcGF5bG9hZCBpcyBlbmNyeXB0ZWQsIGRlY3J5cHQgaXQgZmlyc3QgdG8gcmV2ZWFsXG4gICAgICAvLyB0aGUgaW5uZXIgZm9ybWF0LXByZWZpeGVkIGRhdGEgKGUuZy4sICdkZXZsJyArIHNlcmlhbGl6ZWQgdGV4dCksXG4gICAgICAvLyB0aGVuIGZhbGwgdGhyb3VnaCB0byB0aGUgbm9ybWFsIGRlc2VyaWFsaXphdGlvbiBwYXRoLlxuICAgICAgaWYgKGZvcm1hdCA9PT0gU2VyaWFsaXphdGlvbkZvcm1hdC5FTkNSWVBURUQpIHtcbiAgICAgICAgaWYgKCFrZXlTdGF0ZS5rZXkpIHtcbiAgICAgICAgICBjb250cm9sbGVyLmVycm9yKFxuICAgICAgICAgICAgbmV3IFJ1bnRpbWVEZWNyeXB0aW9uRXJyb3IoXG4gICAgICAgICAgICAgICdFbmNyeXB0ZWQgc3RyZWFtIGRhdGEgZW5jb3VudGVyZWQgYnV0IG5vIGVuY3J5cHRpb24ga2V5IGlzIGF2YWlsYWJsZS4gJyArXG4gICAgICAgICAgICAgICAgJ0VuY3J5cHRpb24gaXMgbm90IGNvbmZpZ3VyZWQgb3Igbm8ga2V5IHdhcyBwcm92aWRlZCBmb3IgdGhpcyBydW4uJyxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGNvbnRleHQ6IHtcbiAgICAgICAgICAgICAgICAgIG9wZXJhdGlvbjogJ2RlY3J5cHQnLFxuICAgICAgICAgICAgICAgICAgYnl0ZUxlbmd0aDogcGF5bG9hZC5ieXRlTGVuZ3RoLFxuICAgICAgICAgICAgICAgICAgZm9ybWF0UHJlZml4OiAnZW5jcicsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKVxuICAgICAgICAgICk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGxldCBkZWNyeXB0ZWQ6IFVpbnQ4QXJyYXk7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgZGVjcnlwdGVkID0gYXdhaXQgYWVzR2NtRGVjcnlwdChrZXlTdGF0ZS5rZXksIHBheWxvYWQpO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgIC8vIFRoZSBsb3ctbGV2ZWwgQUVTIGxheWVyIG9ubHkgc2VlcyB0aGUgc3RyaXBwZWQgcGF5bG9hZCwgc28gaXRcbiAgICAgICAgICAvLyBjYW5ub3QgcmVjb3JkIHRoZSBvdXRlciBlbnZlbG9wZSBwcmVmaXguIFdlIHBlZWtlZCBpdCBoZXJlXG4gICAgICAgICAgLy8gKGBlbmNyYCksIHNvIGVucmljaCB0aGUgZGlhZ25vc3RpYyBjb250ZXh0IHdpdGggdGhlIHJlYWwgZm9ybWF0XG4gICAgICAgICAgLy8gcHJlZml4IGJlZm9yZSBwcm9wYWdhdGluZyDigJQgbWlycm9yaW5nIHNlcmlhbGl6YXRpb24vZW5jcnlwdGlvbi50cy5cbiAgICAgICAgICBpZiAoUnVudGltZURlY3J5cHRpb25FcnJvci5pcyhlcnJvcikgJiYgZXJyb3IuY29udGV4dCkge1xuICAgICAgICAgICAgZXJyb3IuY29udGV4dC5mb3JtYXRQcmVmaXggPSBmb3JtYXQ7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG4gICAgICAgICh7IGZvcm1hdCwgcGF5bG9hZCB9ID0gZGVjb2RlRm9ybWF0UHJlZml4KGRlY3J5cHRlZCkpO1xuICAgICAgfVxuXG4gICAgICBpZiAoZm9ybWF0ID09PSBTZXJpYWxpemF0aW9uRm9ybWF0LkRFVkFMVUVfVjEpIHtcbiAgICAgICAgY29uc3QgdGV4dCA9IGRlY29kZXIuZGVjb2RlKHBheWxvYWQpO1xuICAgICAgICBjb250cm9sbGVyLmVucXVldWUocGFyc2UodGV4dCwgcmV2aXZlcnMpKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBjb25zdCBzdHJlYW0gPSBuZXcgVHJhbnNmb3JtU3RyZWFtPFVpbnQ4QXJyYXksIGFueT4oe1xuICAgIGFzeW5jIHRyYW5zZm9ybShjaHVuaywgY29udHJvbGxlcikge1xuICAgICAgLy8gRmlyc3QsIHRyeSB0byBkZXRlY3QgaWYgdGhpcyBpcyBsZW5ndGgtcHJlZml4ZWQgZnJhbWVkIGRhdGFcbiAgICAgIC8vIGJ5IGNoZWNraW5nIGlmIHRoZSBmaXJzdCA0IGJ5dGVzIGZvcm0gYSBwbGF1c2libGUgbGVuZ3RoLlxuICAgICAgaWYgKGJ1ZmZlci5sZW5ndGggPT09IDAgJiYgY2h1bmsubGVuZ3RoID49IEZSQU1FX0hFQURFUl9TSVpFKSB7XG4gICAgICAgIGNvbnN0IHBvc3NpYmxlTGVuZ3RoID0gbmV3IERhdGFWaWV3KFxuICAgICAgICAgIGNodW5rLmJ1ZmZlcixcbiAgICAgICAgICBjaHVuay5ieXRlT2Zmc2V0LFxuICAgICAgICAgIGNodW5rLmJ5dGVMZW5ndGhcbiAgICAgICAgKS5nZXRVaW50MzIoMCwgZmFsc2UpO1xuICAgICAgICBpZiAoXG4gICAgICAgICAgcG9zc2libGVMZW5ndGggPiAwICYmXG4gICAgICAgICAgcG9zc2libGVMZW5ndGggPCAxMDBfMDAwXzAwMCAvLyBzYW5pdHkgY2hlY2s6IDwgMTAwTUJcbiAgICAgICAgKSB7XG4gICAgICAgICAgLy8gTG9va3MgbGlrZSBmcmFtZWQgZGF0YVxuICAgICAgICAgIGFwcGVuZFRvQnVmZmVyKGNodW5rKTtcbiAgICAgICAgICBhd2FpdCBwcm9jZXNzRnJhbWVzKGNvbnRyb2xsZXIpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChidWZmZXIubGVuZ3RoID4gMCkge1xuICAgICAgICAvLyBBbHJlYWR5IGluIGZyYW1lZCBtb2RlIChoYXZlIGJ1ZmZlcmVkIGRhdGEpXG4gICAgICAgIGFwcGVuZFRvQnVmZmVyKGNodW5rKTtcbiAgICAgICAgYXdhaXQgcHJvY2Vzc0ZyYW1lcyhjb250cm9sbGVyKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICAvLyBMZWdhY3kgZm9ybWF0OiBuZXdsaW5lLWRlbGltaXRlZCBkZXZhbHVlIHRleHQgKG5vIGZyYW1pbmcpXG4gICAgICBjb25zdCB0ZXh0ID0gZGVjb2Rlci5kZWNvZGUoY2h1bmspO1xuICAgICAgY29uc3QgbGluZXMgPSB0ZXh0LnNwbGl0KCdcXG4nKTtcbiAgICAgIGZvciAoY29uc3QgbGluZSBvZiBsaW5lcykge1xuICAgICAgICBpZiAobGluZS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgY29udHJvbGxlci5lbnF1ZXVlKHBhcnNlKGxpbmUsIHJldml2ZXJzKSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9LFxuICAgIGFzeW5jIGZsdXNoKGNvbnRyb2xsZXIpIHtcbiAgICAgIC8vIFByb2Nlc3MgYW55IHJlbWFpbmluZyBmcmFtZWQgZGF0YVxuICAgICAgaWYgKGJ1ZmZlci5sZW5ndGggPiAwKSB7XG4gICAgICAgIGF3YWl0IHByb2Nlc3NGcmFtZXMoY29udHJvbGxlcik7XG4gICAgICB9XG4gICAgfSxcbiAgfSk7XG4gIHJldHVybiBzdHJlYW07XG59XG5cbmV4cG9ydCBjbGFzcyBXb3JrZmxvd1NlcnZlclJlYWRhYmxlU3RyZWFtIGV4dGVuZHMgUmVhZGFibGVTdHJlYW08VWludDhBcnJheT4ge1xuICAjcmVhZGVyPzogUmVhZGFibGVTdHJlYW1EZWZhdWx0UmVhZGVyPFVpbnQ4QXJyYXk+O1xuXG4gIGNvbnN0cnVjdG9yKHJ1bklkOiBzdHJpbmcsIG5hbWU6IHN0cmluZywgc3RhcnRJbmRleD86IG51bWJlcikge1xuICAgIGlmICh0eXBlb2YgbmFtZSAhPT0gJ3N0cmluZycgfHwgbmFtZS5sZW5ndGggPT09IDApIHtcbiAgICAgIHRocm93IG5ldyBXb3JrZmxvd1J1bnRpbWVFcnJvcihgXCJuYW1lXCIgaXMgcmVxdWlyZWQsIGdvdCBcIiR7bmFtZX1cImApO1xuICAgIH1cbiAgICBzdXBlcih7XG4gICAgICAvLyBAdHMtZXhwZWN0LWVycm9yIE5vdCBzdXJlIHdoeSBUeXBlU2NyaXB0IGlzIGNvbXBsYWluaW5nIGFib3V0IHRoaXNcbiAgICAgIHR5cGU6ICdieXRlcycsXG5cbiAgICAgIHB1bGw6IGFzeW5jIChjb250cm9sbGVyKSA9PiB7XG4gICAgICAgIGxldCByZWFkZXIgPSB0aGlzLiNyZWFkZXI7XG4gICAgICAgIGlmICghcmVhZGVyKSB7XG4gICAgICAgICAgY29uc3Qgd29ybGQgPSBhd2FpdCBnZXRXb3JsZExhenkoKTtcbiAgICAgICAgICBjb25zdCBzdHJlYW0gPSBhd2FpdCB3b3JsZC5zdHJlYW1zLmdldChydW5JZCwgbmFtZSwgc3RhcnRJbmRleCk7XG4gICAgICAgICAgcmVhZGVyID0gdGhpcy4jcmVhZGVyID0gc3RyZWFtLmdldFJlYWRlcigpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghcmVhZGVyKSB7XG4gICAgICAgICAgY29udHJvbGxlci5lcnJvcihuZXcgRXJyb3IoJ0ZhaWxlZCB0byBnZXQgcmVhZGVyJykpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHJlYWRlci5yZWFkKCk7XG4gICAgICAgIGlmIChyZXN1bHQuZG9uZSkge1xuICAgICAgICAgIHRoaXMuI3JlYWRlciA9IHVuZGVmaW5lZDtcbiAgICAgICAgICBjb250cm9sbGVyLmNsb3NlKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gRm9yd2FyZCByYXcgYnl0ZXM7IGVuY3J5cHRpb24vZGVjcnlwdGlvbiBpcyBoYW5kbGVkIGF0IHRoZVxuICAgICAgICAgIC8vIGZyYW1pbmcgbGV2ZWwgYnkgZ2V0U2VyaWFsaXplU3RyZWFtL2dldERlc2VyaWFsaXplU3RyZWFtLlxuICAgICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZShyZXN1bHQudmFsdWUpO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgY2FuY2VsOiBhc3luYyAocmVhc29uKSA9PiB7XG4gICAgICAgIGlmICh0aGlzLiNyZWFkZXIpIHtcbiAgICAgICAgICBhd2FpdCB0aGlzLiNyZWFkZXIuY2FuY2VsKHJlYXNvbikuY2F0Y2goKCkgPT4ge30pO1xuICAgICAgICAgIHRoaXMuI3JlYWRlciA9IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICB9KTtcbiAgfVxufVxuXG4vKipcbiAqIERlZmF1bHQgZmx1c2ggaW50ZXJ2YWwgaW4gbWlsbGlzZWNvbmRzIGZvciBidWZmZXJlZCBzdHJlYW0gd3JpdGVzLlxuICogQ2h1bmtzIGFyZSBhY2N1bXVsYXRlZCBhbmQgZmx1c2hlZCB0b2dldGhlciB0byByZWR1Y2UgbmV0d29yayBvdmVyaGVhZC5cbiAqL1xuY29uc3QgU1RSRUFNX0ZMVVNIX0lOVEVSVkFMX01TID0gMTA7XG5cbmV4cG9ydCBjbGFzcyBXb3JrZmxvd1NlcnZlcldyaXRhYmxlU3RyZWFtIGV4dGVuZHMgV3JpdGFibGVTdHJlYW08VWludDhBcnJheT4ge1xuICBjb25zdHJ1Y3RvcihydW5JZDogc3RyaW5nLCBuYW1lOiBzdHJpbmcpIHtcbiAgICBpZiAodHlwZW9mIHJ1bklkICE9PSAnc3RyaW5nJykge1xuICAgICAgdGhyb3cgbmV3IFdvcmtmbG93UnVudGltZUVycm9yKFxuICAgICAgICBgXCJydW5JZFwiIG11c3QgYmUgYSBzdHJpbmcsIGdvdCBcIiR7dHlwZW9mIHJ1bklkfVwiYFxuICAgICAgKTtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBuYW1lICE9PSAnc3RyaW5nJyB8fCBuYW1lLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhyb3cgbmV3IFdvcmtmbG93UnVudGltZUVycm9yKGBcIm5hbWVcIiBpcyByZXF1aXJlZCwgZ290IFwiJHtuYW1lfVwiYCk7XG4gICAgfVxuICAgIGNvbnN0IHdvcmxkUHJvbWlzZSA9IGdldFdvcmxkTGF6eSgpO1xuXG4gICAgLy8gQnVmZmVyaW5nIHN0YXRlIGZvciBiYXRjaGVkIHdyaXRlc1xuICAgIC8vIEVuY3J5cHRpb24vZGVjcnlwdGlvbiBpcyBoYW5kbGVkIGF0IHRoZSBmcmFtaW5nIGxldmVsIGJ5XG4gICAgLy8gZ2V0U2VyaWFsaXplU3RyZWFtL2dldERlc2VyaWFsaXplU3RyZWFtLCBub3QgaGVyZS5cbiAgICBsZXQgYnVmZmVyOiBVaW50OEFycmF5W10gPSBbXTtcbiAgICBsZXQgZmx1c2hUaW1lcjogUmV0dXJuVHlwZTx0eXBlb2Ygc2V0VGltZW91dD4gfCBudWxsID0gbnVsbDtcbiAgICBsZXQgZmx1c2hQcm9taXNlOiBQcm9taXNlPHZvaWQ+IHwgbnVsbCA9IG51bGw7XG4gICAgbGV0IHJlc29sdmVkRmx1c2hJbnRlcnZhbE1zOiBudW1iZXIgfCB1bmRlZmluZWQ7XG5cbiAgICBjb25zdCBmbHVzaCA9IGFzeW5jICgpOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgICAgIGlmIChmbHVzaFRpbWVyKSB7XG4gICAgICAgIGNsZWFyVGltZW91dChmbHVzaFRpbWVyKTtcbiAgICAgICAgZmx1c2hUaW1lciA9IG51bGw7XG4gICAgICB9XG5cbiAgICAgIGlmIChidWZmZXIubGVuZ3RoID09PSAwKSByZXR1cm47XG5cbiAgICAgIC8vIENvcHkgY2h1bmtzIHRvIGZsdXNoLCBidXQgZG9uJ3QgY2xlYXIgYnVmZmVyIHVudGlsIHdyaXRlIHN1Y2NlZWRzXG4gICAgICAvLyBUaGlzIHByZXZlbnRzIGRhdGEgbG9zcyBpZiB0aGUgd3JpdGUgb3BlcmF0aW9uIGZhaWxzXG4gICAgICBjb25zdCBjaHVua3NUb0ZsdXNoID0gYnVmZmVyLnNsaWNlKCk7XG5cbiAgICAgIGNvbnN0IHdvcmxkID0gYXdhaXQgd29ybGRQcm9taXNlO1xuICAgICAgLy8gQ2FjaGUgdGhlIGZsdXNoIGludGVydmFsIGZyb20gdGhlIHdvcmxkIG9uIGZpcnN0IHVzZVxuICAgICAgaWYgKHJlc29sdmVkRmx1c2hJbnRlcnZhbE1zID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmVzb2x2ZWRGbHVzaEludGVydmFsTXMgPVxuICAgICAgICAgIHdvcmxkLnN0cmVhbUZsdXNoSW50ZXJ2YWxNcyA/PyBTVFJFQU1fRkxVU0hfSU5URVJWQUxfTVM7XG4gICAgICB9XG4gICAgICAvLyBVc2Ugd3JpdGVNdWx0aSBpZiBhdmFpbGFibGUgZm9yIGJhdGNoIHdyaXRlc1xuICAgICAgaWYgKFxuICAgICAgICB0eXBlb2Ygd29ybGQuc3RyZWFtcy53cml0ZU11bHRpID09PSAnZnVuY3Rpb24nICYmXG4gICAgICAgIGNodW5rc1RvRmx1c2gubGVuZ3RoID4gMVxuICAgICAgKSB7XG4gICAgICAgIGF3YWl0IHdvcmxkLnN0cmVhbXMud3JpdGVNdWx0aShydW5JZCwgbmFtZSwgY2h1bmtzVG9GbHVzaCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBGYWxsIGJhY2sgdG8gc2VxdWVudGlhbCB3cml0ZXNcbiAgICAgICAgZm9yIChjb25zdCBjaHVuayBvZiBjaHVua3NUb0ZsdXNoKSB7XG4gICAgICAgICAgYXdhaXQgd29ybGQuc3RyZWFtcy53cml0ZShydW5JZCwgbmFtZSwgY2h1bmspO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIE9ubHkgY2xlYXIgYnVmZmVyIGFmdGVyIHN1Y2Nlc3NmdWwgd3JpdGUgdG8gcHJldmVudCBkYXRhIGxvc3NcbiAgICAgIGJ1ZmZlciA9IFtdO1xuICAgIH07XG5cbiAgICAvKiogUmVzb2x2ZXJzL3JlamVjdG9ycyB3YWl0aW5nIGZvciB0aGUgY3VycmVudCBzY2hlZHVsZWQgZmx1c2ggKi9cbiAgICBsZXQgZmx1c2hXYWl0ZXJzOiBBcnJheTx7XG4gICAgICByZXNvbHZlOiAoKSA9PiB2b2lkO1xuICAgICAgcmVqZWN0OiAoZXJyOiB1bmtub3duKSA9PiB2b2lkO1xuICAgIH0+ID0gW107XG5cbiAgICBjb25zdCBzY2hlZHVsZUZsdXNoID0gKCk6IHZvaWQgPT4ge1xuICAgICAgaWYgKGZsdXNoVGltZXIpIHJldHVybjsgLy8gQWxyZWFkeSBzY2hlZHVsZWRcblxuICAgICAgZmx1c2hUaW1lciA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICBmbHVzaFRpbWVyID0gbnVsbDtcbiAgICAgICAgY29uc3QgY3VycmVudFdhaXRlcnMgPSBmbHVzaFdhaXRlcnM7XG4gICAgICAgIGZsdXNoV2FpdGVycyA9IFtdO1xuICAgICAgICBmbHVzaFByb21pc2UgPSBmbHVzaCgpLnRoZW4oXG4gICAgICAgICAgKCkgPT4ge1xuICAgICAgICAgICAgZm9yIChjb25zdCB3IG9mIGN1cnJlbnRXYWl0ZXJzKSB3LnJlc29sdmUoKTtcbiAgICAgICAgICB9LFxuICAgICAgICAgIChlcnIpID0+IHtcbiAgICAgICAgICAgIGZvciAoY29uc3QgdyBvZiBjdXJyZW50V2FpdGVycykgdy5yZWplY3QoZXJyKTtcbiAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgICB9LCByZXNvbHZlZEZsdXNoSW50ZXJ2YWxNcyA/PyBTVFJFQU1fRkxVU0hfSU5URVJWQUxfTVMpO1xuICAgIH07XG5cbiAgICBzdXBlcih7XG4gICAgICBhc3luYyB3cml0ZShjaHVuaykge1xuICAgICAgICAvLyBXYWl0IGZvciBhbnkgaW4tcHJvZ3Jlc3MgZmx1c2ggdG8gY29tcGxldGUgYmVmb3JlIGFkZGluZyB0byBidWZmZXJcbiAgICAgICAgaWYgKGZsdXNoUHJvbWlzZSkge1xuICAgICAgICAgIGF3YWl0IGZsdXNoUHJvbWlzZTtcbiAgICAgICAgICBmbHVzaFByb21pc2UgPSBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgYnVmZmVyLnB1c2goY2h1bmspO1xuICAgICAgICBzY2hlZHVsZUZsdXNoKCk7XG5cbiAgICAgICAgLy8gV2FpdCBmb3IgdGhlIHNjaGVkdWxlZCBmbHVzaCB0byBjb21wbGV0ZSBzbyB0aGF0IGNhbGxlcnNcbiAgICAgICAgLy8gKGxpa2UgZmx1c2hhYmxlUGlwZSkga25vdyBkYXRhIGhhcyByZWFjaGVkIHRoZSBzZXJ2ZXJcbiAgICAgICAgLy8gYmVmb3JlIGRlY3JlbWVudGluZyBwZW5kaW5nT3BzLiBXaXRob3V0IHRoaXMsIHBlbmRpbmdPcHNcbiAgICAgICAgLy8gcmVhY2hlcyAwIHdoZW4gdGhlIGJ1ZmZlcmVkIHdyaXRlIHJldHVybnMgKGluc3RhbnQpLCBidXRcbiAgICAgICAgLy8gdGhlIDEwbXMgZmx1c2ggdGltZXIgaGFzbid0IGZpcmVkIHlldC5cbiAgICAgICAgYXdhaXQgbmV3IFByb21pc2U8dm9pZD4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgIGZsdXNoV2FpdGVycy5wdXNoKHsgcmVzb2x2ZSwgcmVqZWN0IH0pO1xuICAgICAgICB9KTtcbiAgICAgIH0sXG4gICAgICBhc3luYyBjbG9zZSgpIHtcbiAgICAgICAgLy8gV2FpdCBmb3IgYW55IGluLXByb2dyZXNzIGZsdXNoIHRvIGNvbXBsZXRlXG4gICAgICAgIGlmIChmbHVzaFByb21pc2UpIHtcbiAgICAgICAgICBhd2FpdCBmbHVzaFByb21pc2U7XG4gICAgICAgICAgZmx1c2hQcm9taXNlID0gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEZsdXNoIGFueSByZW1haW5pbmcgYnVmZmVyZWQgY2h1bmtzXG4gICAgICAgIGF3YWl0IGZsdXNoKCk7XG5cbiAgICAgICAgY29uc3Qgd29ybGQgPSBhd2FpdCB3b3JsZFByb21pc2U7XG4gICAgICAgIGF3YWl0IHdvcmxkLnN0cmVhbXMuY2xvc2UocnVuSWQsIG5hbWUpO1xuICAgICAgfSxcbiAgICAgIGFib3J0KHJlYXNvbikge1xuICAgICAgICAvLyBDbGVhbiB1cCB0aW1lciB0byBwcmV2ZW50IGxlYWtzXG4gICAgICAgIGlmIChmbHVzaFRpbWVyKSB7XG4gICAgICAgICAgY2xlYXJUaW1lb3V0KGZsdXNoVGltZXIpO1xuICAgICAgICAgIGZsdXNoVGltZXIgPSBudWxsO1xuICAgICAgICB9XG4gICAgICAgIC8vIERpc2NhcmQgYnVmZmVyZWQgY2h1bmtzIC0gdGhleSB3b24ndCBiZSB3cml0dGVuXG4gICAgICAgIGJ1ZmZlciA9IFtdO1xuICAgICAgICAvLyBSZWplY3QgYW55IHBlbmRpbmcgZmx1c2hXYWl0ZXJzIHNvIHRoZSB3cml0ZSgpIHByb21pc2VzIHNldHRsZVxuICAgICAgICAvLyBhbmQgZG9uJ3QgbGVhay4gV2l0aG91dCB0aGlzLCB3cml0ZSgpIGhhbmdzIGZvcmV2ZXIgb24gYW5cbiAgICAgICAgLy8gdW5zZXR0bGVkIHByb21pc2UgYmVjYXVzZSB0aGUgY2xlYXJlZCB0aW1lciB3aWxsIG5ldmVyIGZpcmUuXG4gICAgICAgIGNvbnN0IHdhaXRlcnMgPSBmbHVzaFdhaXRlcnM7XG4gICAgICAgIGZsdXNoV2FpdGVycyA9IFtdO1xuICAgICAgICBjb25zdCBhYm9ydEVycm9yID0gcmVhc29uID8/IG5ldyBFcnJvcignU3RyZWFtIGFib3J0ZWQnKTtcbiAgICAgICAgZm9yIChjb25zdCB3IG9mIHdhaXRlcnMpIHcucmVqZWN0KGFib3J0RXJyb3IpO1xuICAgICAgfSxcbiAgICB9KTtcbiAgfVxufVxuXG4vLyBSZS1leHBvcnQgdHlwZXMgZnJvbSB0aGUgbW9kdWxhciBzZXJpYWxpemF0aW9uIG1vZHVsZXMuXG5leHBvcnQgdHlwZSB7XG4gIFJlZHVjZXJzLFxuICBSZXZpdmVycyxcbiAgU2VyaWFsaXphYmxlU3BlY2lhbCxcbn0gZnJvbSAnLi9zZXJpYWxpemF0aW9uL3R5cGVzLmpzJztcblxuLy8gSW1wb3J0IHR5cGVzIGxvY2FsbHkgZm9yIHVzZSB3aXRoaW4gdGhpcyBmaWxlLlxuaW1wb3J0IHR5cGUge1xuICBSZWR1Y2VycyxcbiAgUmV2aXZlcnMsXG4gIFNlcmlhbGl6YWJsZVNwZWNpYWwsXG59IGZyb20gJy4vc2VyaWFsaXphdGlvbi90eXBlcy5qcyc7XG5cbi8vIC0tLS0gQ29tcG9zZWQgcmVkdWNlcnMgLS0tLVxuLy8gQ29tcG9zZXMgbW9kdWxhciByZWR1Y2VycyAoY29tbW9uLCBjbGFzcywgc3RlcC1mdW5jdGlvbikgd2l0aFxuLy8gbW9kZS1zcGVjaWZpYyBSZXF1ZXN0L1Jlc3BvbnNlL1N0cmVhbSByZWR1Y2VycyBiZWxvdy5cblxuLyoqXG4gKiBCYXNlIHJlZHVjZXJzIHNoYXJlZCBhY3Jvc3MgYWxsIHNlcmlhbGl6YXRpb24gYm91bmRhcmllcy5cbiAqIENvbXBvc2VzOiBjbGFzcyArIHN0ZXAtZnVuY3Rpb24gKyBjb21tb24gcmVkdWNlcnMgZnJvbSB0aGUgbW9kdWxhciBtb2R1bGVzLlxuICovXG5mdW5jdGlvbiBnZXRBbGxCYXNlUmVkdWNlcnMoXG4gIGdsb2JhbDogUmVjb3JkPHN0cmluZywgYW55PiA9IGdsb2JhbFRoaXNcbik6IFBhcnRpYWw8UmVkdWNlcnM+IHtcbiAgLy8gQ2xhc3MvSW5zdGFuY2UgTVVTVCBjb21lIGJlZm9yZSBFcnJvciBzbyB0aGF0IGN1c3RvbSBFcnJvciBzdWJjbGFzc2VzXG4gIC8vIHdpdGggV09SS0ZMT1dfU0VSSUFMSVpFIHRha2UgcHJlY2VkZW5jZSAoZGV2YWx1ZSB1c2VzIGZpcnN0LW1hdGNoLXdpbnMpLlxuICByZXR1cm4ge1xuICAgIC4uLmdldENsYXNzUmVkdWNlcnMoKSxcbiAgICAuLi5nZXRTdGVwRnVuY3Rpb25SZWR1Y2VyKCksXG4gICAgLi4uZ2V0Q29tbW9uUmVkdWNlcnMoZ2xvYmFsKSxcbiAgICAvLyBSZXF1ZXN0IGFuZCBSZXNwb25zZSByZWR1Y2VycyBhcmUgbW9kZS1zcGVjaWZpYyBhbmQgYWRkZWQgYnlcbiAgICAvLyBnZXRFeHRlcm5hbFJlZHVjZXJzIC8gZ2V0V29ya2Zsb3dSZWR1Y2VycyAvIGdldFN0ZXBSZWR1Y2VycyBiZWxvdy5cbiAgICBSZXF1ZXN0OiAodmFsdWUpID0+IHtcbiAgICAgIGlmICghKHZhbHVlIGluc3RhbmNlb2YgZ2xvYmFsLlJlcXVlc3QpKSByZXR1cm4gZmFsc2U7XG4gICAgICBjb25zdCBkYXRhOiBTZXJpYWxpemFibGVTcGVjaWFsWydSZXF1ZXN0J10gPSB7XG4gICAgICAgIG1ldGhvZDogdmFsdWUubWV0aG9kLFxuICAgICAgICB1cmw6IHZhbHVlLnVybCxcbiAgICAgICAgaGVhZGVyczogdmFsdWUuaGVhZGVycyxcbiAgICAgICAgYm9keTogdmFsdWUuYm9keSxcbiAgICAgICAgZHVwbGV4OiB2YWx1ZS5kdXBsZXgsXG4gICAgICB9O1xuICAgICAgY29uc3QgcmVzcG9uc2VXcml0YWJsZSA9IHZhbHVlW1dFQkhPT0tfUkVTUE9OU0VfV1JJVEFCTEVdO1xuICAgICAgaWYgKHJlc3BvbnNlV3JpdGFibGUpIHtcbiAgICAgICAgZGF0YS5yZXNwb25zZVdyaXRhYmxlID0gcmVzcG9uc2VXcml0YWJsZTtcbiAgICAgIH1cbiAgICAgIC8vIEZvcndhcmQgdGhlIHNpZ25hbCBpbiB0d28gY2FzZXM6XG4gICAgICAvLyAgIDEuIEFscmVhZHkgYWJvcnRlZCDigJQgcHJlc2VydmUgYWJvcnRlZD10cnVlL3JlYXNvbiBzbyB0aGUgaHlkcmF0ZWRcbiAgICAgIC8vICAgICAgc3RlcCBzZWVzIHRoZSBjYW5jZWxsYXRpb24gdGhhdCBoYXBwZW5lZCBiZWZvcmUgc2VyaWFsaXplLlxuICAgICAgLy8gICAyLiBBbHJlYWR5IHRhZ2dlZCB3aXRoIHdvcmtmbG93IGluZnJhc3RydWN0dXJlIOKAlCBpLmUuIGEgc2lnbmFsXG4gICAgICAvLyAgICAgIGZyb20gYSB3b3JrZmxvdy1tYW5hZ2VkIEFib3J0Q29udHJvbGxlciwgd2hpY2ggaGFzIHN0cmVhbS9ob29rXG4gICAgICAvLyAgICAgIGJhY2tpbmcgZm9yIGNyb3NzLWJvdW5kYXJ5IHByb3BhZ2F0aW9uLlxuICAgICAgLy8gUGxhaW4gbm9uLWFib3J0ZWQgbmF0aXZlIHNpZ25hbHMgYXJlIGludGVudGlvbmFsbHkgZHJvcHBlZCAod291bGRcbiAgICAgIC8vIG1pbnQgc3RyZWFtIGluZnJhIGZvciBldmVyeSBSZXF1ZXN0LCBpbmNsdWRpbmcgdGhlIGF1dG8tZ2VuZXJhdGVkXG4gICAgICAvLyBzaWduYWwgb24gYG5ldyBSZXF1ZXN0KHVybClgKS5cbiAgICAgIGlmIChcbiAgICAgICAgdmFsdWUuc2lnbmFsICYmXG4gICAgICAgICh2YWx1ZS5zaWduYWwuYWJvcnRlZCB8fFxuICAgICAgICAgICh2YWx1ZS5zaWduYWwgYXMgQWJvcnRJbnRlcm5hbHMpW0FCT1JUX1NUUkVBTV9OQU1FXSlcbiAgICAgICkge1xuICAgICAgICBkYXRhLnNpZ25hbCA9IHZhbHVlLnNpZ25hbDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBkYXRhO1xuICAgIH0sXG4gICAgUmVzcG9uc2U6ICh2YWx1ZSkgPT4ge1xuICAgICAgaWYgKCEodmFsdWUgaW5zdGFuY2VvZiBnbG9iYWwuUmVzcG9uc2UpKSByZXR1cm4gZmFsc2U7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB0eXBlOiB2YWx1ZS50eXBlLFxuICAgICAgICB1cmw6IHZhbHVlLnVybCxcbiAgICAgICAgc3RhdHVzOiB2YWx1ZS5zdGF0dXMsXG4gICAgICAgIHN0YXR1c1RleHQ6IHZhbHVlLnN0YXR1c1RleHQsXG4gICAgICAgIGhlYWRlcnM6IHZhbHVlLmhlYWRlcnMsXG4gICAgICAgIGJvZHk6IHZhbHVlLmJvZHksXG4gICAgICAgIHJlZGlyZWN0ZWQ6IHZhbHVlLnJlZGlyZWN0ZWQsXG4gICAgICB9O1xuICAgIH0sXG4gIH07XG59XG5cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gU2hhcmVkIGFib3J0IHJlZHVjZXIgaGVscGVyc1xuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbnR5cGUgQWJvcnRTZXJpYWxpemVkRGF0YSA9IHtcbiAgc3RyZWFtTmFtZTogc3RyaW5nO1xuICBob29rVG9rZW46IHN0cmluZztcbiAgYWJvcnRlZDogYm9vbGVhbjtcbiAgcmVhc29uOiB1bmtub3duO1xufTtcblxuLyoqXG4gKiBTeW1ib2wta2V5ZWQgaW50ZXJuYWwgZmllbGRzIHRhZ2dlZCBvbnRvIEFib3J0Q29udHJvbGxlci9BYm9ydFNpZ25hbFxuICogaW5zdGFuY2VzIChhbmQgYGhvbGRlcmBzIGluIHJlZHVjZXIgaGVscGVycykuIEFsbCBvcHRpb25hbCDigJQgYSBwbGFpblxuICogbmF0aXZlIGluc3RhbmNlIGhhcyBub25lIG9mIHRoZW0gc2V0LlxuICovXG50eXBlIEFib3J0SW50ZXJuYWxzID0ge1xuICBbQUJPUlRfU1RSRUFNX05BTUVdPzogc3RyaW5nO1xuICBbQUJPUlRfSE9PS19UT0tFTl0/OiBzdHJpbmc7XG4gIFtBQk9SVF9SRUFERVJfQ0FOQ0VMXT86IEFib3J0Q29udHJvbGxlcjtcbn07XG5cbnR5cGUgQWJvcnRTaWduYWxMaWtlID0gQWJvcnRJbnRlcm5hbHMgJiB7XG4gIGFib3J0ZWQ6IGJvb2xlYW47XG4gIHJlYXNvbj86IHVua25vd247XG4gIGFkZEV2ZW50TGlzdGVuZXI/OiBGdW5jdGlvbjtcbn07XG5cbnR5cGUgQWJvcnRIb2xkZXIgPSBBYm9ydEludGVybmFscyAmIHsgc2lnbmFsPzogQWJvcnRJbnRlcm5hbHMgfTtcblxuLyoqXG4gKiBTaGFyZWQgbG9naWMgZm9yIEFib3J0Q29udHJvbGxlci9BYm9ydFNpZ25hbCByZWR1Y2VycyBpbiBleHRlcm5hbCBhbmQgc3RlcFxuICogY29udGV4dHMuIEFzc2lnbnMgc3RyZWFtL2hvb2sgbmFtZXMgaWYgbm90IGFscmVhZHkgcHJlc2VudCwgb3B0aW9uYWxseVxuICogYXR0YWNoZXMgYW4gYWJvcnQgbGlzdGVuZXIgZm9yIHJlYWwtdGltZSBwcm9wYWdhdGlvbiwgYW5kIHJldHVybnMgdGhlXG4gKiBzZXJpYWxpemVkIHJlcHJlc2VudGF0aW9uLlxuICovXG5mdW5jdGlvbiByZWR1Y2VBYm9ydFdpdGhMaXN0ZW5lcihcbiAgc2lnbmFsOiBBYm9ydFNpZ25hbExpa2UsXG4gIGhvbGRlcjogQWJvcnRIb2xkZXIsXG4gIGdsb2JhbDogUmVjb3JkPHN0cmluZywgYW55PixcbiAgb3BzOiBQcm9taXNlPHZvaWQ+W10sXG4gIHJ1bklkOiBzdHJpbmcsXG4gIGNyeXB0b0tleTogRW5jcnlwdGlvbktleVBhcmFtXG4pOiBBYm9ydFNlcmlhbGl6ZWREYXRhIHtcbiAgbGV0IHN0cmVhbU5hbWUgPSBob2xkZXJbQUJPUlRfU1RSRUFNX05BTUVdO1xuICBsZXQgaG9va1Rva2VuID0gaG9sZGVyW0FCT1JUX0hPT0tfVE9LRU5dO1xuICBpZiAoIXN0cmVhbU5hbWUpIHtcbiAgICBjb25zdCBpZCA9ICgoZ2xvYmFsIGFzIGFueSlbU1RBQkxFX1VMSURdIHx8IGRlZmF1bHRVbGlkKSgpO1xuICAgIHN0cmVhbU5hbWUgPSBnZXRBYm9ydFN0cmVhbUlkKGlkKTtcbiAgICBob29rVG9rZW4gPSBgYWJydF8ke2lkfWA7XG4gICAgaG9sZGVyW0FCT1JUX1NUUkVBTV9OQU1FXSA9IHN0cmVhbU5hbWU7XG4gICAgaG9sZGVyW0FCT1JUX0hPT0tfVE9LRU5dID0gaG9va1Rva2VuO1xuICAgIGlmIChob2xkZXIuc2lnbmFsKSB7XG4gICAgICBob2xkZXIuc2lnbmFsW0FCT1JUX1NUUkVBTV9OQU1FXSA9IHN0cmVhbU5hbWU7XG4gICAgICBob2xkZXIuc2lnbmFsW0FCT1JUX0hPT0tfVE9LRU5dID0gaG9va1Rva2VuO1xuICAgIH1cbiAgfVxuXG4gIC8vIERlZHVwZWQgdmlhIEFCT1JUX0xJU1RFTkVSX0FUVEFDSEVEIG1hcmtlciDigJQgc2VlIGF0dGFjaEFib3J0TGlzdGVuZXJPbmNlLlxuICBhdHRhY2hBYm9ydExpc3RlbmVyT25jZShcbiAgICBzaWduYWwgYXMgQWJvcnRTaWduYWwsXG4gICAgc3RyZWFtTmFtZSxcbiAgICBydW5JZCxcbiAgICBjcnlwdG9LZXksXG4gICAgb3BzXG4gICk7XG5cbiAgcmV0dXJuIHtcbiAgICBzdHJlYW1OYW1lLFxuICAgIGhvb2tUb2tlbjogaG9va1Rva2VuISxcbiAgICBhYm9ydGVkOiBzaWduYWwuYWJvcnRlZCxcbiAgICByZWFzb246IHNpZ25hbC5hYm9ydGVkID8gc2lnbmFsLnJlYXNvbiA6IHVuZGVmaW5lZCxcbiAgfTtcbn1cblxuLyoqXG4gKiBTaGFyZWQgbG9naWMgZm9yIEFib3J0Q29udHJvbGxlci9BYm9ydFNpZ25hbCByZWR1Y2VycyBpbiB3b3JrZmxvdyBjb250ZXh0LlxuICogUmVhZHMgZXhpc3Rpbmcgc3RyZWFtL2hvb2sgbmFtZXMgZnJvbSBzeW1ib2xzIChtdXN0IGFscmVhZHkgYmUgc2V0KS5cbiAqL1xuZnVuY3Rpb24gcmVkdWNlQWJvcnRCeVN5bWJvbChcbiAgc2lnbmFsOiB7IGFib3J0ZWQ6IGJvb2xlYW47IHJlYXNvbj86IHVua25vd24gfSxcbiAgaG9sZGVyOiBBYm9ydEhvbGRlclxuKTogQWJvcnRTZXJpYWxpemVkRGF0YSB8IGZhbHNlIHtcbiAgY29uc3Qgc3RyZWFtTmFtZSA9XG4gICAgaG9sZGVyW0FCT1JUX1NUUkVBTV9OQU1FXSA/PyBob2xkZXIuc2lnbmFsPy5bQUJPUlRfU1RSRUFNX05BTUVdO1xuICBjb25zdCBob29rVG9rZW4gPVxuICAgIGhvbGRlcltBQk9SVF9IT09LX1RPS0VOXSA/PyBob2xkZXIuc2lnbmFsPy5bQUJPUlRfSE9PS19UT0tFTl07XG4gIGlmICghc3RyZWFtTmFtZSkge1xuICAgIHRocm93IG5ldyBFcnJvcignQWJvcnRDb250cm9sbGVyL0Fib3J0U2lnbmFsIHN0cmVhbSBuYW1lIGlzIG5vdCBzZXQnKTtcbiAgfVxuICByZXR1cm4ge1xuICAgIHN0cmVhbU5hbWUsXG4gICAgaG9va1Rva2VuOiBob29rVG9rZW4hLFxuICAgIGFib3J0ZWQ6IHNpZ25hbC5hYm9ydGVkLFxuICAgIHJlYXNvbjogc2lnbmFsLmFib3J0ZWQgPyBzaWduYWwucmVhc29uIDogdW5kZWZpbmVkLFxuICB9O1xufVxuXG4vKipcbiAqIEF0dGFjaCBhIHNpbmdsZSBhYm9ydCBsaXN0ZW5lciB0byBhIHNpZ25hbCwgZGVkdXBlZCBhY3Jvc3MgY2FsbHMuXG4gKlxuICogRWFjaCBzZXJpYWxpemF0aW9uIHBhc3MgZ29lcyB0aHJvdWdoIHRoZSByZWR1Y2VyLCBidXQgYSBjb250cm9sbGVyIHBhc3NlZFxuICogdG8gTiBzdGVwcyB3b3VsZCBvdGhlcndpc2UgYWNjdW11bGF0ZSBOIGxpc3RlbmVycyDigJQgZWFjaCB3cml0aW5nIHRoZSBzYW1lXG4gKiBzdHJlYW0gcGFja2V0IGFuZCBkb3VibGUtY2xvc2luZyB0aGUgc3RyZWFtIG9uIGFib3J0LiBUaGUgbWFya2VyIHN5bWJvbFxuICogZW5zdXJlcyB0aGUgc3RyZWFtLXdyaXRlIHNpZGUtZWZmZWN0IHJ1bnMgYXQgbW9zdCBvbmNlIHBlciAoc2lnbmFsLCBydW5JZCkuXG4gKi9cbmZ1bmN0aW9uIGF0dGFjaEFib3J0TGlzdGVuZXJPbmNlKFxuICBzaWduYWw6IEFib3J0U2lnbmFsLFxuICBzdHJlYW1OYW1lOiBzdHJpbmcsXG4gIHJ1bklkOiBzdHJpbmcsXG4gIGNyeXB0b0tleTogRW5jcnlwdGlvbktleVBhcmFtLFxuICBvcHM6IFByb21pc2U8dm9pZD5bXVxuKTogdm9pZCB7XG4gIGlmIChzaWduYWwuYWJvcnRlZCkgcmV0dXJuO1xuICBpZiAoKHNpZ25hbCBhcyBhbnkpW0FCT1JUX0xJU1RFTkVSX0FUVEFDSEVEXSkgcmV0dXJuO1xuICAoc2lnbmFsIGFzIGFueSlbQUJPUlRfTElTVEVORVJfQVRUQUNIRURdID0gdHJ1ZTtcblxuICBzaWduYWwuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAnYWJvcnQnLFxuICAgICgpID0+IHtcbiAgICAgIG9wcy5wdXNoKFxuICAgICAgICAoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAvLyBEZWh5ZHJhdGUgdmlhIHRoZSBzYW1lIG1hY2hpbmVyeSB0aGUgcmVhZGVyIHVzZXMgKGh5ZHJhdGVTdGVwQXJndW1lbnRzKVxuICAgICAgICAgICAgLy8gc28gdGhlIHJlYXNvbiByb3VuZC10cmlwcyB3aXRoIGZ1bGwgdHlwZSBmaWRlbGl0eSAoRE9NRXhjZXB0aW9uLFxuICAgICAgICAgICAgLy8gRXJyb3JzLCBjdXN0b20gY2xhc3NlcywgZXRjLikgYW5kIHJlc3BlY3RzIHRoZSBydW4ncyBlbmNyeXB0aW9uIGtleS5cbiAgICAgICAgICAgIC8vIEEgYmFyZSBKU09OLnN0cmluZ2lmeSBoZXJlIHdvdWxkIHdyaXRlIGEgcGFja2V0IHRoZSByZWFkZXIgY2FuJ3RcbiAgICAgICAgICAgIC8vIGRlY29kZSBhbmQgdGhlIGxpc3RlbmVyLXNpZGUgYWJvcnQgd291bGQgcHJvcGFnYXRlIHdpdGggbm8gcmVhc29uLlxuICAgICAgICAgICAgY29uc3Qga2V5ID0gYXdhaXQgY3J5cHRvS2V5O1xuICAgICAgICAgICAgY29uc3QgcGF5bG9hZCA9IGF3YWl0IGRlaHlkcmF0ZVN0ZXBBcmd1bWVudHMoXG4gICAgICAgICAgICAgIHsgYWJvcnRlZDogdHJ1ZSwgcmVhc29uOiBzaWduYWwucmVhc29uIH0sXG4gICAgICAgICAgICAgIHJ1bklkLFxuICAgICAgICAgICAgICBrZXlcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBjb25zdCB3cml0YWJsZSA9IG5ldyBXb3JrZmxvd1NlcnZlcldyaXRhYmxlU3RyZWFtKFxuICAgICAgICAgICAgICBydW5JZCxcbiAgICAgICAgICAgICAgc3RyZWFtTmFtZVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGNvbnN0IHdyaXRlciA9IHdyaXRhYmxlLmdldFdyaXRlcigpO1xuICAgICAgICAgICAgYXdhaXQgd3JpdGVyLndyaXRlKHBheWxvYWQgYXMgVWludDhBcnJheSk7XG4gICAgICAgICAgICBhd2FpdCB3cml0ZXIuY2xvc2UoKTtcbiAgICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICAgIC8vIEJlc3QtZWZmb3J0IHN0cmVhbSB3cml0ZVxuICAgICAgICAgIH1cbiAgICAgICAgfSkoKVxuICAgICAgKTtcbiAgICB9LFxuICAgIHsgb25jZTogdHJ1ZSB9XG4gICk7XG59XG5cbi8qKlxuICogUmVkdWNlcnMgZm9yIHNlcmlhbGl6YXRpb24gYm91bmRhcnkgZnJvbSB0aGUgY2xpZW50IHNpZGUsIHBhc3NpbmcgYXJndW1lbnRzXG4gKiB0byB0aGUgd29ya2Zsb3cgaGFuZGxlci5cbiAqXG4gKiBAcGFyYW0gZ2xvYmFsXG4gKiBAcGFyYW0gb3BzXG4gKiBAcmV0dXJuc1xuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0RXh0ZXJuYWxSZWR1Y2VycyhcbiAgZ2xvYmFsOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0gZ2xvYmFsVGhpcyxcbiAgb3BzOiBQcm9taXNlPHZvaWQ+W10sXG4gIHJ1bklkOiBzdHJpbmcsXG4gIGNyeXB0b0tleTogRW5jcnlwdGlvbktleVBhcmFtXG4pOiBQYXJ0aWFsPFJlZHVjZXJzPiB7XG4gIHJldHVybiB7XG4gICAgLi4uZ2V0QWxsQmFzZVJlZHVjZXJzKGdsb2JhbCksXG5cbiAgICBSZWFkYWJsZVN0cmVhbTogKHZhbHVlKSA9PiB7XG4gICAgICBpZiAoISh2YWx1ZSBpbnN0YW5jZW9mIGdsb2JhbC5SZWFkYWJsZVN0cmVhbSkpIHJldHVybiBmYWxzZTtcblxuICAgICAgLy8gU3RyZWFtIG11c3Qgbm90IGJlIGxvY2tlZCB3aGVuIHBhc3NpbmcgYWNyb3NzIGV4ZWN1dGlvbiBib3VuZGFyeVxuICAgICAgaWYgKHZhbHVlLmxvY2tlZCkge1xuICAgICAgICB0aHJvdyBuZXcgU2VyaWFsaXphdGlvbkVycm9yKFxuICAgICAgICAgICdSZWFkYWJsZVN0cmVhbSBpcyBsb2NrZWQgYW5kIGNhbm5vdCBiZSBwYXNzZWQgYWNyb3NzIGEgd29ya2Zsb3cgYm91bmRhcnkuJyxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBoaW50OiAnUGFzcyB0aGUgc3RyZWFtIGJlZm9yZSBjYWxsaW5nIC5nZXRSZWFkZXIoKSAvIC5waXBlVGhyb3VnaCgpIC8gLnBpcGVUbygpLCBvciB0ZWUgaXQgd2l0aCAudGVlKCkgYW5kIHBhc3Mgb25lIG9mIHRoZSBicmFuY2hlcy4nLFxuICAgICAgICAgIH1cbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgY29uc3Qgc3RyZWFtSWQgPSAoKGdsb2JhbCBhcyBhbnkpW1NUQUJMRV9VTElEXSB8fCBkZWZhdWx0VWxpZCkoKTtcbiAgICAgIGNvbnN0IG5hbWUgPSBgc3RybV8ke3N0cmVhbUlkfWA7XG4gICAgICBjb25zdCB0eXBlID0gZ2V0U3RyZWFtVHlwZSh2YWx1ZSk7XG5cbiAgICAgIGNvbnN0IHdyaXRhYmxlID0gbmV3IFdvcmtmbG93U2VydmVyV3JpdGFibGVTdHJlYW0ocnVuSWQsIG5hbWUpO1xuICAgICAgaWYgKHR5cGUgPT09ICdieXRlcycpIHtcbiAgICAgICAgb3BzLnB1c2godmFsdWUucGlwZVRvKHdyaXRhYmxlKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBvcHMucHVzaChcbiAgICAgICAgICB2YWx1ZVxuICAgICAgICAgICAgLnBpcGVUaHJvdWdoKFxuICAgICAgICAgICAgICBnZXRTZXJpYWxpemVTdHJlYW0oXG4gICAgICAgICAgICAgICAgZ2V0RXh0ZXJuYWxSZWR1Y2VycyhnbG9iYWwsIG9wcywgcnVuSWQsIGNyeXB0b0tleSksXG4gICAgICAgICAgICAgICAgY3J5cHRvS2V5XG4gICAgICAgICAgICAgIClcbiAgICAgICAgICAgIClcbiAgICAgICAgICAgIC5waXBlVG8od3JpdGFibGUpXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHM6IFNlcmlhbGl6YWJsZVNwZWNpYWxbJ1JlYWRhYmxlU3RyZWFtJ10gPSB7IG5hbWUgfTtcbiAgICAgIGlmICh0eXBlKSBzLnR5cGUgPSB0eXBlO1xuICAgICAgcmV0dXJuIHM7XG4gICAgfSxcblxuICAgIFdyaXRhYmxlU3RyZWFtOiAodmFsdWUpID0+IHtcbiAgICAgIGlmICghKHZhbHVlIGluc3RhbmNlb2YgZ2xvYmFsLldyaXRhYmxlU3RyZWFtKSkgcmV0dXJuIGZhbHNlO1xuXG4gICAgICAvLyBGYXN0IHBhdGg6IHdoZW4gdGhlIHdyaXRhYmxlIGlzIGFscmVhZHkgYmFja2VkIGJ5IGEgd29ya2Zsb3dcbiAgICAgIC8vIHNlcnZlciBzdHJlYW0gKGUuZy4gaXQgY2FtZSBmcm9tIGEgc3RlcC1jb250ZXh0IGBnZXRXcml0YWJsZSgpYFxuICAgICAgLy8gb3Igd2FzIGh5ZHJhdGVkIGZyb20gYSB3b3JrZmxvdyBpbnB1dCBieSBgZ2V0U3RlcFJldml2ZXJzYCksXG4gICAgICAvLyBmb3J3YXJkIGl0cyB1bmRlcmx5aW5nIGAocnVuSWQsIG5hbWUpYCB0byB0aGUgcmVjZWl2aW5nIHJ1bi5cbiAgICAgIC8vIFRoZSByZWNlaXZpbmcgcnVuJ3Mgc3RlcC1zaWRlIHJldml2ZXIgb3BlbnMgYSBzZXJ2ZXIgd3JpdGFibGVcbiAgICAgIC8vIGFnYWluc3QgdGhlIG9yaWdpbmFsIGAocnVuSWQsIG5hbWUpYCBhbmQgcmVzb2x2ZXMgdGhhdCBydW4nc1xuICAgICAgLy8gZW5jcnlwdGlvbiBrZXkgZGlyZWN0bHksIHNvIHdyaXRlcyBsYW5kIG9uIHRoZSBvcmlnaW5hbCBzdHJlYW1cbiAgICAgIC8vIGZvciB0aGUgZnVsbCBsaWZldGltZSBvZiB0aGUgcmVjZWl2aW5nIHJ1biDigJQgbm8gaW4tcHJvY2Vzc1xuICAgICAgLy8gYnJpZGdlIHRpZWQgdG8gdGhlIGRlaHlkcmF0aW5nIHN0ZXAncyBsaWZldGltZS5cbiAgICAgIGNvbnN0IGV4aXN0aW5nTmFtZSA9ICh2YWx1ZSBhcyBhbnkpW1NUUkVBTV9OQU1FX1NZTUJPTF07XG4gICAgICBjb25zdCBleGlzdGluZ1J1bklkID0gKHZhbHVlIGFzIGFueSlbU1RSRUFNX1NFUlZFUl9SVU5fSURfU1lNQk9MXTtcbiAgICAgIGlmIChcbiAgICAgICAgdHlwZW9mIGV4aXN0aW5nTmFtZSA9PT0gJ3N0cmluZycgJiZcbiAgICAgICAgdHlwZW9mIGV4aXN0aW5nUnVuSWQgPT09ICdzdHJpbmcnXG4gICAgICApIHtcbiAgICAgICAgY29uc3QgZGVzY3JpcHRvcjogU2VyaWFsaXphYmxlU3BlY2lhbFsnV3JpdGFibGVTdHJlYW0nXSA9IHtcbiAgICAgICAgICBuYW1lOiBleGlzdGluZ05hbWUsXG4gICAgICAgICAgcnVuSWQ6IGV4aXN0aW5nUnVuSWQsXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IGV4aXN0aW5nRGVwbG95bWVudElkID0gKHZhbHVlIGFzIGFueSlbXG4gICAgICAgICAgU1RSRUFNX1NFUlZFUl9ERVBMT1lNRU5UX0lEX1NZTUJPTFxuICAgICAgICBdO1xuICAgICAgICBpZiAodHlwZW9mIGV4aXN0aW5nRGVwbG95bWVudElkID09PSAnc3RyaW5nJykge1xuICAgICAgICAgIGRlc2NyaXB0b3IuZGVwbG95bWVudElkID0gZXhpc3RpbmdEZXBsb3ltZW50SWQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGRlc2NyaXB0b3I7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHN0cmVhbUlkID0gKChnbG9iYWwgYXMgYW55KVtTVEFCTEVfVUxJRF0gfHwgZGVmYXVsdFVsaWQpKCk7XG4gICAgICBjb25zdCBuYW1lID0gYHN0cm1fJHtzdHJlYW1JZH1gO1xuICAgICAgY29uc3QgcmVhZGFibGUgPSBuZXcgV29ya2Zsb3dTZXJ2ZXJSZWFkYWJsZVN0cmVhbShydW5JZCwgbmFtZSk7XG4gICAgICBvcHMucHVzaChyZWFkYWJsZS5waXBlVG8odmFsdWUpKTtcblxuICAgICAgcmV0dXJuIHsgbmFtZSB9O1xuICAgIH0sXG5cbiAgICBBYm9ydENvbnRyb2xsZXI6ICh2YWx1ZSkgPT4ge1xuICAgICAgaWYgKFxuICAgICAgICAhZ2xvYmFsLkFib3J0Q29udHJvbGxlciB8fFxuICAgICAgICB0eXBlb2YgZ2xvYmFsLkFib3J0Q29udHJvbGxlciAhPT0gJ2Z1bmN0aW9uJyB8fFxuICAgICAgICAhKHZhbHVlIGluc3RhbmNlb2YgZ2xvYmFsLkFib3J0Q29udHJvbGxlcilcbiAgICAgIClcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgcmV0dXJuIHJlZHVjZUFib3J0V2l0aExpc3RlbmVyKFxuICAgICAgICB2YWx1ZS5zaWduYWwsXG4gICAgICAgIHZhbHVlLFxuICAgICAgICBnbG9iYWwsXG4gICAgICAgIG9wcyxcbiAgICAgICAgcnVuSWQsXG4gICAgICAgIGNyeXB0b0tleVxuICAgICAgKTtcbiAgICB9LFxuXG4gICAgQWJvcnRTaWduYWw6ICh2YWx1ZSkgPT4ge1xuICAgICAgaWYgKFxuICAgICAgICAhZ2xvYmFsLkFib3J0U2lnbmFsIHx8XG4gICAgICAgIHR5cGVvZiBnbG9iYWwuQWJvcnRTaWduYWwgIT09ICdmdW5jdGlvbicgfHxcbiAgICAgICAgISh2YWx1ZSBpbnN0YW5jZW9mIGdsb2JhbC5BYm9ydFNpZ25hbClcbiAgICAgIClcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgcmV0dXJuIHJlZHVjZUFib3J0V2l0aExpc3RlbmVyKFxuICAgICAgICB2YWx1ZSxcbiAgICAgICAgdmFsdWUsXG4gICAgICAgIGdsb2JhbCxcbiAgICAgICAgb3BzLFxuICAgICAgICBydW5JZCxcbiAgICAgICAgY3J5cHRvS2V5XG4gICAgICApO1xuICAgIH0sXG4gIH07XG59XG5cbi8qKlxuICogUmVkdWNlcnMgZm9yIHNlcmlhbGl6YXRpb24gYm91bmRhcnkgZnJvbSB3aXRoaW4gdGhlIHdvcmtmbG93IGV4ZWN1dGlvblxuICogZW52aXJvbm1lbnQsIHBhc3NpbmcgcmV0dXJuIHZhbHVlIHRvIHRoZSBjbGllbnQgc2lkZSBhbmQgaW50byBzdGVwIGFyZ3VtZW50cy5cbiAqXG4gKiBAcGFyYW0gZ2xvYmFsXG4gKiBAcmV0dXJuc1xuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0V29ya2Zsb3dSZWR1Y2VycyhcbiAgZ2xvYmFsOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0gZ2xvYmFsVGhpc1xuKTogUGFydGlhbDxSZWR1Y2Vycz4ge1xuICByZXR1cm4ge1xuICAgIC4uLmdldEFsbEJhc2VSZWR1Y2VycyhnbG9iYWwpLFxuXG4gICAgLy8gUmVhZGFibGUvV3JpdGFibGUgc3RyZWFtcyBmcm9tIHdpdGhpbiB0aGUgd29ya2Zsb3cgZXhlY3V0aW9uIGVudmlyb25tZW50XG4gICAgLy8gYXJlIHNpbXBseSBcImhhbmRsZXNcIiB0aGF0IGNhbiBiZSBwYXNzZWQgYXJvdW5kIHRvIG90aGVyIHN0ZXBzLlxuICAgIFJlYWRhYmxlU3RyZWFtOiAodmFsdWUpID0+IHtcbiAgICAgIGlmICghKHZhbHVlIGluc3RhbmNlb2YgZ2xvYmFsLlJlYWRhYmxlU3RyZWFtKSkgcmV0dXJuIGZhbHNlO1xuXG4gICAgICAvLyBDaGVjayBpZiB0aGlzIGlzIGEgZmFrZSBzdHJlYW0gc3RvcmluZyBCb2R5SW5pdCBmcm9tIFJlcXVlc3QvUmVzcG9uc2UgY29uc3RydWN0b3JcbiAgICAgIGNvbnN0IGJvZHlJbml0ID0gdmFsdWVbQk9EWV9JTklUX1NZTUJPTF07XG4gICAgICBpZiAoYm9keUluaXQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAvLyBUaGlzIGlzIGEgZmFrZSBzdHJlYW0gLSBzZXJpYWxpemUgdGhlIEJvZHlJbml0IGRpcmVjdGx5XG4gICAgICAgIC8vIGRldmFsdWUgd2lsbCBoYW5kbGUgc2VyaWFsaXppbmcgc3RyaW5ncywgVWludDhBcnJheSwgZXRjLlxuICAgICAgICByZXR1cm4geyBib2R5SW5pdCB9O1xuICAgICAgfVxuXG4gICAgICBjb25zdCBuYW1lID0gdmFsdWVbU1RSRUFNX05BTUVfU1lNQk9MXTtcbiAgICAgIGlmICghbmFtZSkge1xuICAgICAgICB0aHJvdyBuZXcgV29ya2Zsb3dSdW50aW1lRXJyb3IoJ1JlYWRhYmxlU3RyZWFtIGBuYW1lYCBpcyBub3Qgc2V0Jyk7XG4gICAgICB9XG4gICAgICBjb25zdCBzOiBTZXJpYWxpemFibGVTcGVjaWFsWydSZWFkYWJsZVN0cmVhbSddID0geyBuYW1lIH07XG4gICAgICBjb25zdCB0eXBlID0gdmFsdWVbU1RSRUFNX1RZUEVfU1lNQk9MXTtcbiAgICAgIGlmICh0eXBlKSBzLnR5cGUgPSB0eXBlO1xuICAgICAgcmV0dXJuIHM7XG4gICAgfSxcbiAgICBXcml0YWJsZVN0cmVhbTogKHZhbHVlKSA9PiB7XG4gICAgICBpZiAoISh2YWx1ZSBpbnN0YW5jZW9mIGdsb2JhbC5Xcml0YWJsZVN0cmVhbSkpIHJldHVybiBmYWxzZTtcbiAgICAgIGNvbnN0IG5hbWUgPSB2YWx1ZVtTVFJFQU1fTkFNRV9TWU1CT0xdO1xuICAgICAgaWYgKCFuYW1lKSB7XG4gICAgICAgIHRocm93IG5ldyBXb3JrZmxvd1J1bnRpbWVFcnJvcignV3JpdGFibGVTdHJlYW0gYG5hbWVgIGlzIG5vdCBzZXQnKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHM6IFNlcmlhbGl6YWJsZVNwZWNpYWxbJ1dyaXRhYmxlU3RyZWFtJ10gPSB7IG5hbWUgfTtcbiAgICAgIC8vIFdoZW4gdGhlIGhhbmRsZSB3YXMgZm9yd2FyZGVkIGZyb20gYW5vdGhlciBydW4gKHBhcmVudCDihpIgY2hpbGRcbiAgICAgIC8vIHZpYSBgc3RhcnQoKWApLCBwcmVzZXJ2ZSB0aGUgZm9yZWlnbiBydW5JZCBzbyB0aGUgc3RlcC1zaWRlXG4gICAgICAvLyByZXZpdmVyIG9wZW5zIHRoZSB3cml0YWJsZSBhZ2FpbnN0IHRoZSBvcmlnaW5hbCBzdHJlYW0uXG4gICAgICBjb25zdCBmb3JlaWduUnVuSWQgPSB2YWx1ZVtTVFJFQU1fU0VSVkVSX1JVTl9JRF9TWU1CT0xdO1xuICAgICAgaWYgKHR5cGVvZiBmb3JlaWduUnVuSWQgPT09ICdzdHJpbmcnKSBzLnJ1bklkID0gZm9yZWlnblJ1bklkO1xuICAgICAgY29uc3QgZm9yZWlnbkRlcGxveW1lbnRJZCA9IHZhbHVlW1NUUkVBTV9TRVJWRVJfREVQTE9ZTUVOVF9JRF9TWU1CT0xdO1xuICAgICAgaWYgKHR5cGVvZiBmb3JlaWduRGVwbG95bWVudElkID09PSAnc3RyaW5nJykge1xuICAgICAgICBzLmRlcGxveW1lbnRJZCA9IGZvcmVpZ25EZXBsb3ltZW50SWQ7XG4gICAgICB9XG4gICAgICByZXR1cm4gcztcbiAgICB9LFxuXG4gICAgLy8gQWJvcnRDb250cm9sbGVyL0Fib3J0U2lnbmFsIGluIHdvcmtmbG93IGNvbnRleHQg4oCUIGp1c3QgcmVhZCBzeW1ib2xzIChoYW5kbGVzKS5cbiAgICAvLyBJbiB0aGUgd29ya2Zsb3cgVk0sIGdsb2JhbC5BYm9ydENvbnRyb2xsZXIgaXMgYSBjbGFzcyBidXQgZ2xvYmFsLkFib3J0U2lnbmFsXG4gICAgLy8gaXMgYSBwbGFpbiBvYmplY3QgKG5vdCBhIGNsYXNzKSwgc28gaW5zdGFuY2VvZiBjaGVja3Mgd29uJ3Qgd29yayBmb3Igc2lnbmFscy5cbiAgICAvLyBEZXRlY3QgaW5zdGFuY2VzIGJ5IHRoZSBwcmVzZW5jZSBvZiB0aGUgQUJPUlRfU1RSRUFNX05BTUUgc3ltYm9sIGluc3RlYWQuXG4gICAgQWJvcnRDb250cm9sbGVyOiAodmFsdWUpID0+IHtcbiAgICAgIGlmICghdmFsdWUgfHwgIXZhbHVlLnNpZ25hbCkgcmV0dXJuIGZhbHNlO1xuICAgICAgY29uc3QgaG9sZGVyID0gdmFsdWUgYXMgQWJvcnRDb250cm9sbGVyICYgQWJvcnRIb2xkZXI7XG4gICAgICBjb25zdCBoYXNBYm9ydFN5bWJvbCA9XG4gICAgICAgIGhvbGRlcltBQk9SVF9TVFJFQU1fTkFNRV0gPz8gaG9sZGVyLnNpZ25hbD8uW0FCT1JUX1NUUkVBTV9OQU1FXTtcbiAgICAgIGNvbnN0IGlzTmF0aXZlQWJvcnRDb250cm9sbGVyID1cbiAgICAgICAgZ2xvYmFsLkFib3J0Q29udHJvbGxlciAmJlxuICAgICAgICB0eXBlb2YgZ2xvYmFsLkFib3J0Q29udHJvbGxlciA9PT0gJ2Z1bmN0aW9uJyAmJlxuICAgICAgICB2YWx1ZSBpbnN0YW5jZW9mIGdsb2JhbC5BYm9ydENvbnRyb2xsZXI7XG4gICAgICBpZiAoIWhhc0Fib3J0U3ltYm9sICYmICFpc05hdGl2ZUFib3J0Q29udHJvbGxlcikgcmV0dXJuIGZhbHNlO1xuICAgICAgcmV0dXJuIHJlZHVjZUFib3J0QnlTeW1ib2wodmFsdWUuc2lnbmFsLCBob2xkZXIpO1xuICAgIH0sXG4gICAgQWJvcnRTaWduYWw6ICh2YWx1ZSkgPT4ge1xuICAgICAgY29uc3Qgc2lnbmFsID0gdmFsdWUgYXMgKEFib3J0U2lnbmFsICYgQWJvcnRJbnRlcm5hbHMpIHwgdW5kZWZpbmVkO1xuICAgICAgY29uc3QgaGFzQWJvcnRTeW1ib2wgPSBzaWduYWw/LltBQk9SVF9TVFJFQU1fTkFNRV07XG4gICAgICBjb25zdCBpc05hdGl2ZUFib3J0U2lnbmFsID1cbiAgICAgICAgZ2xvYmFsLkFib3J0U2lnbmFsICYmXG4gICAgICAgIHR5cGVvZiBnbG9iYWwuQWJvcnRTaWduYWwgPT09ICdmdW5jdGlvbicgJiZcbiAgICAgICAgdmFsdWUgaW5zdGFuY2VvZiBnbG9iYWwuQWJvcnRTaWduYWw7XG4gICAgICBpZiAoIWhhc0Fib3J0U3ltYm9sICYmICFpc05hdGl2ZUFib3J0U2lnbmFsKSByZXR1cm4gZmFsc2U7XG4gICAgICByZXR1cm4gcmVkdWNlQWJvcnRCeVN5bWJvbCh2YWx1ZSwgdmFsdWUgYXMgQWJvcnRIb2xkZXIpO1xuICAgIH0sXG4gIH07XG59XG5cbi8qKlxuICogUmVkdWNlcnMgZm9yIHNlcmlhbGl6YXRpb24gYm91bmRhcnkgZnJvbSB3aXRoaW4gdGhlIHN0ZXAgZXhlY3V0aW9uXG4gKiBlbnZpcm9ubWVudCwgcGFzc2luZyByZXR1cm4gdmFsdWUgdG8gdGhlIHdvcmtmbG93IGhhbmRsZXIuXG4gKlxuICogQHBhcmFtIGdsb2JhbFxuICogQHBhcmFtIG9wc1xuICogQHBhcmFtIHJ1bklkXG4gKiBAcmV0dXJuc1xuICovXG5mdW5jdGlvbiBnZXRTdGVwUmVkdWNlcnMoXG4gIGdsb2JhbDogUmVjb3JkPHN0cmluZywgYW55PiA9IGdsb2JhbFRoaXMsXG4gIG9wczogUHJvbWlzZTx2b2lkPltdLFxuICBydW5JZDogc3RyaW5nLFxuICBjcnlwdG9LZXk6IEVuY3J5cHRpb25LZXlQYXJhbVxuKTogUGFydGlhbDxSZWR1Y2Vycz4ge1xuICByZXR1cm4ge1xuICAgIC4uLmdldEFsbEJhc2VSZWR1Y2VycyhnbG9iYWwpLFxuXG4gICAgUmVhZGFibGVTdHJlYW06ICh2YWx1ZSkgPT4ge1xuICAgICAgaWYgKCEodmFsdWUgaW5zdGFuY2VvZiBnbG9iYWwuUmVhZGFibGVTdHJlYW0pKSByZXR1cm4gZmFsc2U7XG5cbiAgICAgIC8vIFN0cmVhbSBtdXN0IG5vdCBiZSBsb2NrZWQgd2hlbiBwYXNzaW5nIGFjcm9zcyBleGVjdXRpb24gYm91bmRhcnlcbiAgICAgIGlmICh2YWx1ZS5sb2NrZWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IFNlcmlhbGl6YXRpb25FcnJvcihcbiAgICAgICAgICAnUmVhZGFibGVTdHJlYW0gaXMgbG9ja2VkIGFuZCBjYW5ub3QgYmUgcGFzc2VkIGFjcm9zcyBhIHdvcmtmbG93IGJvdW5kYXJ5LicsXG4gICAgICAgICAge1xuICAgICAgICAgICAgaGludDogJ1Bhc3MgdGhlIHN0cmVhbSBiZWZvcmUgY2FsbGluZyAuZ2V0UmVhZGVyKCkgLyAucGlwZVRocm91Z2goKSAvIC5waXBlVG8oKSwgb3IgdGVlIGl0IHdpdGggLnRlZSgpIGFuZCBwYXNzIG9uZSBvZiB0aGUgYnJhbmNoZXMuJyxcbiAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIC8vIENoZWNrIGlmIHRoZSBzdHJlYW0gYWxyZWFkeSBoYXMgdGhlIG5hbWUgc3ltYm9sIHNldCwgaW4gd2hpY2ggY2FzZVxuICAgICAgLy8gaXQncyBhbHJlYWR5IGJlaW5nIHN1bmsgdG8gdGhlIHNlcnZlciBhbmQgd2UgY2FuIGp1c3QgcmV0dXJuIHRoZVxuICAgICAgLy8gbmFtZSBhbmQgdHlwZS5cbiAgICAgIGxldCBuYW1lID0gdmFsdWVbU1RSRUFNX05BTUVfU1lNQk9MXTtcbiAgICAgIGxldCB0eXBlID0gdmFsdWVbU1RSRUFNX1RZUEVfU1lNQk9MXTtcblxuICAgICAgaWYgKCFuYW1lKSB7XG4gICAgICAgIGNvbnN0IHN0cmVhbUlkID0gKChnbG9iYWwgYXMgYW55KVtTVEFCTEVfVUxJRF0gfHwgZGVmYXVsdFVsaWQpKCk7XG4gICAgICAgIG5hbWUgPSBgc3RybV8ke3N0cmVhbUlkfWA7XG4gICAgICAgIHR5cGUgPSBnZXRTdHJlYW1UeXBlKHZhbHVlKTtcblxuICAgICAgICBjb25zdCB3cml0YWJsZSA9IG5ldyBXb3JrZmxvd1NlcnZlcldyaXRhYmxlU3RyZWFtKHJ1bklkLCBuYW1lKTtcbiAgICAgICAgaWYgKHR5cGUgPT09ICdieXRlcycpIHtcbiAgICAgICAgICBvcHMucHVzaCh2YWx1ZS5waXBlVG8od3JpdGFibGUpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBvcHMucHVzaChcbiAgICAgICAgICAgIHZhbHVlXG4gICAgICAgICAgICAgIC5waXBlVGhyb3VnaChcbiAgICAgICAgICAgICAgICBnZXRTZXJpYWxpemVTdHJlYW0oXG4gICAgICAgICAgICAgICAgICBnZXRTdGVwUmVkdWNlcnMoZ2xvYmFsLCBvcHMsIHJ1bklkLCBjcnlwdG9LZXkpLFxuICAgICAgICAgICAgICAgICAgY3J5cHRvS2V5XG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgIC5waXBlVG8od3JpdGFibGUpXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBjb25zdCBzOiBTZXJpYWxpemFibGVTcGVjaWFsWydSZWFkYWJsZVN0cmVhbSddID0geyBuYW1lIH07XG4gICAgICBpZiAodHlwZSkgcy50eXBlID0gdHlwZTtcbiAgICAgIHJldHVybiBzO1xuICAgIH0sXG5cbiAgICBXcml0YWJsZVN0cmVhbTogKHZhbHVlKSA9PiB7XG4gICAgICBpZiAoISh2YWx1ZSBpbnN0YW5jZW9mIGdsb2JhbC5Xcml0YWJsZVN0cmVhbSkpIHJldHVybiBmYWxzZTtcblxuICAgICAgbGV0IG5hbWUgPSB2YWx1ZVtTVFJFQU1fTkFNRV9TWU1CT0xdO1xuICAgICAgY29uc3QgZm9yZWlnblJ1bklkID0gKHZhbHVlIGFzIGFueSlbU1RSRUFNX1NFUlZFUl9SVU5fSURfU1lNQk9MXTtcbiAgICAgIGlmICghbmFtZSkge1xuICAgICAgICBjb25zdCBzdHJlYW1JZCA9ICgoZ2xvYmFsIGFzIGFueSlbU1RBQkxFX1VMSURdIHx8IGRlZmF1bHRVbGlkKSgpO1xuICAgICAgICBuYW1lID0gYHN0cm1fJHtzdHJlYW1JZH1gO1xuICAgICAgICBvcHMucHVzaChcbiAgICAgICAgICBuZXcgV29ya2Zsb3dTZXJ2ZXJSZWFkYWJsZVN0cmVhbShydW5JZCwgbmFtZSlcbiAgICAgICAgICAgIC5waXBlVGhyb3VnaChcbiAgICAgICAgICAgICAgZ2V0RGVzZXJpYWxpemVTdHJlYW0oXG4gICAgICAgICAgICAgICAgZ2V0U3RlcFJldml2ZXJzKGdsb2JhbCwgb3BzLCBydW5JZCwgY3J5cHRvS2V5KSxcbiAgICAgICAgICAgICAgICBjcnlwdG9LZXlcbiAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgKVxuICAgICAgICAgICAgLnBpcGVUbyh2YWx1ZSlcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgczogU2VyaWFsaXphYmxlU3BlY2lhbFsnV3JpdGFibGVTdHJlYW0nXSA9IHsgbmFtZSB9O1xuICAgICAgaWYgKHR5cGVvZiBmb3JlaWduUnVuSWQgPT09ICdzdHJpbmcnKSBzLnJ1bklkID0gZm9yZWlnblJ1bklkO1xuICAgICAgY29uc3QgZm9yZWlnbkRlcGxveW1lbnRJZCA9ICh2YWx1ZSBhcyBhbnkpW1xuICAgICAgICBTVFJFQU1fU0VSVkVSX0RFUExPWU1FTlRfSURfU1lNQk9MXG4gICAgICBdO1xuICAgICAgaWYgKHR5cGVvZiBmb3JlaWduRGVwbG95bWVudElkID09PSAnc3RyaW5nJykge1xuICAgICAgICBzLmRlcGxveW1lbnRJZCA9IGZvcmVpZ25EZXBsb3ltZW50SWQ7XG4gICAgICB9XG4gICAgICByZXR1cm4gcztcbiAgICB9LFxuXG4gICAgQWJvcnRDb250cm9sbGVyOiAodmFsdWUpID0+IHtcbiAgICAgIGlmIChcbiAgICAgICAgIWdsb2JhbC5BYm9ydENvbnRyb2xsZXIgfHxcbiAgICAgICAgdHlwZW9mIGdsb2JhbC5BYm9ydENvbnRyb2xsZXIgIT09ICdmdW5jdGlvbicgfHxcbiAgICAgICAgISh2YWx1ZSBpbnN0YW5jZW9mIGdsb2JhbC5BYm9ydENvbnRyb2xsZXIpXG4gICAgICApXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIHJldHVybiByZWR1Y2VBYm9ydFdpdGhMaXN0ZW5lcihcbiAgICAgICAgdmFsdWUuc2lnbmFsLFxuICAgICAgICB2YWx1ZSxcbiAgICAgICAgZ2xvYmFsLFxuICAgICAgICBvcHMsXG4gICAgICAgIHJ1bklkLFxuICAgICAgICBjcnlwdG9LZXlcbiAgICAgICk7XG4gICAgfSxcblxuICAgIEFib3J0U2lnbmFsOiAodmFsdWUpID0+IHtcbiAgICAgIGlmIChcbiAgICAgICAgIWdsb2JhbC5BYm9ydFNpZ25hbCB8fFxuICAgICAgICB0eXBlb2YgZ2xvYmFsLkFib3J0U2lnbmFsICE9PSAnZnVuY3Rpb24nIHx8XG4gICAgICAgICEodmFsdWUgaW5zdGFuY2VvZiBnbG9iYWwuQWJvcnRTaWduYWwpXG4gICAgICApXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIHJldHVybiByZWR1Y2VBYm9ydFdpdGhMaXN0ZW5lcihcbiAgICAgICAgdmFsdWUsXG4gICAgICAgIHZhbHVlLFxuICAgICAgICBnbG9iYWwsXG4gICAgICAgIG9wcyxcbiAgICAgICAgcnVuSWQsXG4gICAgICAgIGNyeXB0b0tleVxuICAgICAgKTtcbiAgICB9LFxuICB9O1xufVxuXG4vKipcbiAqIENhbmNlbCBkYW5nbGluZyBhYm9ydC1zdHJlYW0gcmVhZGVycyBvbiBhbnkgQWJvcnRDb250cm9sbGVyIGluc3RhbmNlcyBmb3VuZFxuICogaW4gdGhlIGh5ZHJhdGVkIHN0ZXAgYXJndW1lbnRzLiBDYWxsZWQgYWZ0ZXIgdGhlIHN0ZXAgZnVuY3Rpb24gcmV0dXJuc1xuICogKHN1Y2Nlc3Mgb3IgZmFpbHVyZSkgdG8gcHJldmVudCByZWFkZXIgcHJvbWlzZXMgZnJvbSBrZWVwaW5nIHRoZSBzZXJ2ZXJsZXNzXG4gKiBmdW5jdGlvbiBhbGl2ZSBpbmRlZmluaXRlbHkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjYW5jZWxBYm9ydFJlYWRlcnMoLi4udmFsdWVzOiB1bmtub3duW10pOiB2b2lkIHtcbiAgY29uc3QgdmlzaXRlZCA9IG5ldyBXZWFrU2V0KCk7XG4gIGZ1bmN0aW9uIGNhbmNlbElmUHJlc2VudCh2YWw6IEFib3J0SW50ZXJuYWxzKTogdm9pZCB7XG4gICAgY29uc3QgY2FuY2VsID0gdmFsW0FCT1JUX1JFQURFUl9DQU5DRUxdO1xuICAgIGlmIChjYW5jZWwgJiYgIWNhbmNlbC5zaWduYWwuYWJvcnRlZCkge1xuICAgICAgY2FuY2VsLmFib3J0KCk7XG4gICAgfVxuICB9XG4gIGZ1bmN0aW9uIHdhbGsodmFsOiB1bmtub3duKTogdm9pZCB7XG4gICAgaWYgKHZhbCA9PSBudWxsIHx8IHR5cGVvZiB2YWwgIT09ICdvYmplY3QnKSByZXR1cm47XG4gICAgaWYgKHZpc2l0ZWQuaGFzKHZhbCBhcyBvYmplY3QpKSByZXR1cm47XG4gICAgdmlzaXRlZC5hZGQodmFsIGFzIG9iamVjdCk7XG4gICAgaWYgKHZhbCBpbnN0YW5jZW9mIEFib3J0Q29udHJvbGxlcikge1xuICAgICAgY2FuY2VsSWZQcmVzZW50KHZhbCBhcyBBYm9ydENvbnRyb2xsZXIgJiBBYm9ydEludGVybmFscyk7XG4gICAgICBjYW5jZWxJZlByZXNlbnQodmFsLnNpZ25hbCBhcyBBYm9ydFNpZ25hbCAmIEFib3J0SW50ZXJuYWxzKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHZhbCBpbnN0YW5jZW9mIEFib3J0U2lnbmFsKSB7XG4gICAgICBjYW5jZWxJZlByZXNlbnQodmFsIGFzIEFib3J0U2lnbmFsICYgQWJvcnRJbnRlcm5hbHMpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWwpKSB7XG4gICAgICBmb3IgKGNvbnN0IGl0ZW0gb2YgdmFsKSB3YWxrKGl0ZW0pO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAodmFsIGluc3RhbmNlb2YgTWFwKSB7XG4gICAgICBmb3IgKGNvbnN0IHYgb2YgdmFsLnZhbHVlcygpKSB3YWxrKHYpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAodmFsIGluc3RhbmNlb2YgU2V0KSB7XG4gICAgICBmb3IgKGNvbnN0IHYgb2YgdmFsKSB3YWxrKHYpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICAvLyBSZXF1ZXN0L1Jlc3BvbnNlIGV4cG9zZSBgc2lnbmFsYC9gYm9keWAgYXMgcHJvdG90eXBlIGdldHRlcnMsIHNvXG4gICAgLy8gT2JqZWN0LnZhbHVlcygpIHdvbid0IGZpbmQgdGhlbS4gRGVzY2VuZCBleHBsaWNpdGx5LlxuICAgIGlmICh0eXBlb2YgUmVxdWVzdCAhPT0gJ3VuZGVmaW5lZCcgJiYgdmFsIGluc3RhbmNlb2YgUmVxdWVzdCkge1xuICAgICAgd2Fsayh2YWwuc2lnbmFsKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgZm9yIChjb25zdCB2IG9mIE9iamVjdC52YWx1ZXModmFsIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KSkgd2Fsayh2KTtcbiAgfVxuICBmb3IgKGNvbnN0IHYgb2YgdmFsdWVzKSB3YWxrKHYpO1xufVxuXG4vKipcbiAqIFNldHMgdXAgYSBzdHJlYW0gcmVhZGVyIG9uIHRoZSBjb250cm9sbGVyIHRoYXQgbGlzdGVucyBmb3IgYW4gYWJvcnQgcGFja2V0LlxuICogUmV0dXJucyB0aGUgcmVhZGVyQ2FuY2VsIGNvbnRyb2xsZXIgc28gaXQgY2FuIGJlIHN0b3JlZCBvbiBib3RoIHRoZVxuICogY29udHJvbGxlciBhbmQgc2lnbmFsIGZvciBjbGVhbnVwIGJ5IGNhbmNlbEFib3J0UmVhZGVycy5cbiAqL1xuZnVuY3Rpb24gc2V0dXBBYm9ydFN0cmVhbVJlYWRlcihcbiAgY29udHJvbGxlcjogQWJvcnRDb250cm9sbGVyLFxuICBydW5JZDogc3RyaW5nLFxuICBzdHJlYW1OYW1lOiBzdHJpbmcsXG4gIG9wczogUHJvbWlzZTx2b2lkPltdXG4pOiBBYm9ydENvbnRyb2xsZXIge1xuICBjb25zdCByZWFkZXJDYW5jZWwgPSBuZXcgQWJvcnRDb250cm9sbGVyKCk7XG5cbiAgb3BzLnB1c2goXG4gICAgKGFzeW5jICgpID0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHJlYWRhYmxlID0gbmV3IFdvcmtmbG93U2VydmVyUmVhZGFibGVTdHJlYW0ocnVuSWQsIHN0cmVhbU5hbWUpO1xuICAgICAgICBjb25zdCByZWFkZXIgPSByZWFkYWJsZS5nZXRSZWFkZXIoKTtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgUHJvbWlzZS5yYWNlKFtcbiAgICAgICAgICByZWFkZXIucmVhZCgpLFxuICAgICAgICAgIG5ldyBQcm9taXNlPHsgdmFsdWU6IHVuZGVmaW5lZDsgZG9uZTogdHJ1ZSB9PigocmVzb2x2ZSkgPT4ge1xuICAgICAgICAgICAgaWYgKHJlYWRlckNhbmNlbC5zaWduYWwuYWJvcnRlZCkge1xuICAgICAgICAgICAgICByZXNvbHZlKHsgdmFsdWU6IHVuZGVmaW5lZCwgZG9uZTogdHJ1ZSB9KTtcbiAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVhZGVyQ2FuY2VsLnNpZ25hbC5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgICAgICAgICAnYWJvcnQnLFxuICAgICAgICAgICAgICAoKSA9PiByZXNvbHZlKHsgdmFsdWU6IHVuZGVmaW5lZCwgZG9uZTogdHJ1ZSB9KSxcbiAgICAgICAgICAgICAgeyBvbmNlOiB0cnVlIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSksXG4gICAgICAgIF0pO1xuICAgICAgICByZWFkZXIucmVsZWFzZUxvY2soKTtcbiAgICAgICAgaWYgKHJlc3VsdC52YWx1ZSAmJiAhcmVzdWx0LmRvbmUpIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgLy8gSHlkcmF0ZSB2aWEgdGhlIHNhbWUgbWFjaGluZXJ5IHRoZSB3cml0ZXIgdXNlZCBzbyB0aGUgcmVhc29uXG4gICAgICAgICAgICAvLyByb3VuZC10cmlwcyB3aXRoIGZ1bGwgdHlwZSBmaWRlbGl0eS4gRW5jcnlwdGlvbiBrZXkgKGlmIGFueSlcbiAgICAgICAgICAgIC8vIGNvbWVzIGZyb20gdGhlIHN0ZXAgY29udGV4dCDigJQgc2V0IHVwIGJ5IHRoZSBzdGVwIGhhbmRsZXIgYmVmb3JlXG4gICAgICAgICAgICAvLyB0aGlzIHJlYWRlciBydW5zLiBGYWxsYmFjayB0byB1bmRlZmluZWQgZm9yIGV4dGVybmFsLWNvbnRleHRcbiAgICAgICAgICAgIC8vIHJldml2ZXMgKHRoZSBoeWRyYXRlIHBhdGggaXMgZW5jcnlwdGlvbi1rZXktdG9sZXJhbnQpLlxuICAgICAgICAgICAgY29uc3QgY3R4Rm9yS2V5ID0gY29udGV4dFN0b3JhZ2UuZ2V0U3RvcmUoKTtcbiAgICAgICAgICAgIGNvbnN0IGRhdGEgPSAoYXdhaXQgaHlkcmF0ZVN0ZXBBcmd1bWVudHMoXG4gICAgICAgICAgICAgIHJlc3VsdC52YWx1ZSxcbiAgICAgICAgICAgICAgcnVuSWQsXG4gICAgICAgICAgICAgIGN0eEZvcktleT8uZW5jcnlwdGlvbktleVxuICAgICAgICAgICAgKSkgYXMgeyByZWFzb24/OiB1bmtub3duIH0gfCB1bmRlZmluZWQ7XG4gICAgICAgICAgICBjb250cm9sbGVyLmFib3J0KGRhdGE/LnJlYXNvbik7XG4gICAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgICBjb250cm9sbGVyLmFib3J0KCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgLy8gU3RyZWFtIHJlYWQgZmFpbGVkIOKAlCBzaWduYWwgd29uJ3QgcHJvcGFnYXRlIGluIHJlYWwtdGltZSxcbiAgICAgICAgLy8gYnV0IGhvb2stYmFzZWQgcHJvcGFnYXRpb24gb24gbmV4dCByZXBsYXkgcHJvdmlkZXMgZmFsbGJhY2tcbiAgICAgIH1cbiAgICB9KSgpXG4gICk7XG5cbiAgcmV0dXJuIHJlYWRlckNhbmNlbDtcbn1cblxuLyoqXG4gKiBTdG9yZXMgYWJvcnQgc2VyaWFsaXphdGlvbiBzeW1ib2xzIGFuZCB0aGUgcmVhZGVyQ2FuY2VsIGNvbnRyb2xsZXJcbiAqIG9uIGJvdGggdGhlIGNvbnRyb2xsZXIgYW5kIGl0cyBzaWduYWwuXG4gKi9cbmZ1bmN0aW9uIHRhZ0Fib3J0UGFpcihcbiAgY29udHJvbGxlcjogQWJvcnRDb250cm9sbGVyLFxuICB2YWx1ZTogeyBzdHJlYW1OYW1lOiBzdHJpbmc7IGhvb2tUb2tlbjogc3RyaW5nIH0sXG4gIHJlYWRlckNhbmNlbD86IEFib3J0Q29udHJvbGxlclxuKTogdm9pZCB7XG4gIGNvbnN0IHRhZ2dlZENvbnRyb2xsZXIgPSBjb250cm9sbGVyIGFzIEFib3J0Q29udHJvbGxlciAmIEFib3J0SW50ZXJuYWxzO1xuICBjb25zdCB0YWdnZWRTaWduYWwgPSBjb250cm9sbGVyLnNpZ25hbCBhcyBBYm9ydFNpZ25hbCAmIEFib3J0SW50ZXJuYWxzO1xuICB0YWdnZWRDb250cm9sbGVyW0FCT1JUX1NUUkVBTV9OQU1FXSA9IHZhbHVlLnN0cmVhbU5hbWU7XG4gIHRhZ2dlZENvbnRyb2xsZXJbQUJPUlRfSE9PS19UT0tFTl0gPSB2YWx1ZS5ob29rVG9rZW47XG4gIHRhZ2dlZFNpZ25hbFtBQk9SVF9TVFJFQU1fTkFNRV0gPSB2YWx1ZS5zdHJlYW1OYW1lO1xuICB0YWdnZWRTaWduYWxbQUJPUlRfSE9PS19UT0tFTl0gPSB2YWx1ZS5ob29rVG9rZW47XG4gIGlmIChyZWFkZXJDYW5jZWwpIHtcbiAgICB0YWdnZWRDb250cm9sbGVyW0FCT1JUX1JFQURFUl9DQU5DRUxdID0gcmVhZGVyQ2FuY2VsO1xuICAgIHRhZ2dlZFNpZ25hbFtBQk9SVF9SRUFERVJfQ0FOQ0VMXSA9IHJlYWRlckNhbmNlbDtcbiAgfVxufVxuXG4vKipcbiAqIFByb3BhZ2F0ZSBhYm9ydC1pbnRlcm5hbCBzeW1ib2xzIGZyb20gb25lIHNpZ25hbCB0byBhbm90aGVyLiBVc2VkIGJ5IHRoZVxuICogUmVxdWVzdCByZXZpdmVyIGJlY2F1c2UgYG5ldyBSZXF1ZXN0KHVybCwgeyBzaWduYWwgfSlgIGNvcGllcyB0aGUgc2lnbmFsXG4gKiBpbnRlcm5hbGx5IOKAlCB0aGUgY29uc3RydWN0ZWQgYHJlcXVlc3Quc2lnbmFsYCBpcyBhIGZyZXNoIEFib3J0U2lnbmFsIHRoYXRcbiAqIGRvZXNuJ3QgY2Fycnkgc3ltYm9scyBmcm9tIHRoZSBzb3VyY2UuXG4gKi9cbmZ1bmN0aW9uIGNvcHlBYm9ydEludGVybmFscyhzcmM6IEFib3J0U2lnbmFsLCBkZXN0OiBBYm9ydFNpZ25hbCk6IHZvaWQge1xuICBjb25zdCBzID0gc3JjIGFzIEFib3J0U2lnbmFsICYgQWJvcnRJbnRlcm5hbHM7XG4gIGNvbnN0IGQgPSBkZXN0IGFzIEFib3J0U2lnbmFsICYgQWJvcnRJbnRlcm5hbHM7XG4gIGlmIChzW0FCT1JUX1NUUkVBTV9OQU1FXSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgZFtBQk9SVF9TVFJFQU1fTkFNRV0gPSBzW0FCT1JUX1NUUkVBTV9OQU1FXTtcbiAgfVxuICBpZiAoc1tBQk9SVF9IT09LX1RPS0VOXSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgZFtBQk9SVF9IT09LX1RPS0VOXSA9IHNbQUJPUlRfSE9PS19UT0tFTl07XG4gIH1cbiAgaWYgKHNbQUJPUlRfUkVBREVSX0NBTkNFTF0gIT09IHVuZGVmaW5lZCkge1xuICAgIGRbQUJPUlRfUkVBREVSX0NBTkNFTF0gPSBzW0FCT1JUX1JFQURFUl9DQU5DRUxdO1xuICB9XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhbiBBYm9ydENvbnRyb2xsZXIgd2l0aCBzdHJlYW0tYmFja2VkIGFib3J0IHByb3BhZ2F0aW9uLlxuICogVXNlZCBieSBzdGVwIGFuZCBleHRlcm5hbCByZXZpdmVycyB3aGVyZSByZWFsIGFib3J0IHNpZ25hbCBiZWhhdmlvciBpcyBuZWVkZWQuXG4gKlxuICogQHBhcmFtIHZhbHVlIC0gVGhlIHNlcmlhbGl6ZWQgYWJvcnQgY29udHJvbGxlci9zaWduYWwgZGF0YVxuICogQHBhcmFtIG9wcyAtIFRoZSBvcHMgYXJyYXkgZm9yIHRyYWNraW5nIGFzeW5jIHdvcmtcbiAqIEBwYXJhbSBydW5JZCAtIFRoZSB3b3JrZmxvdyBydW4gSUQgKGZvciBzdHJlYW0gcmVhZHMpXG4gKiBAcmV0dXJucyBBIHJlYWwgQWJvcnRDb250cm9sbGVyIHdpdGggcGF0Y2hlZCBhYm9ydCgpIG1ldGhvZFxuICovXG5mdW5jdGlvbiByZXZpdmVBYm9ydENvbnRyb2xsZXIoXG4gIHZhbHVlOiBTZXJpYWxpemFibGVTcGVjaWFsWydBYm9ydENvbnRyb2xsZXInXSxcbiAgb3BzOiBQcm9taXNlPHZvaWQ+W10sXG4gIHJ1bklkOiBzdHJpbmdcbik6IEFib3J0Q29udHJvbGxlciB7XG4gIGNvbnN0IGNvbnRyb2xsZXIgPSBuZXcgQWJvcnRDb250cm9sbGVyKCk7XG5cbiAgaWYgKHZhbHVlLmFib3J0ZWQpIHtcbiAgICB0YWdBYm9ydFBhaXIoY29udHJvbGxlciwgdmFsdWUpO1xuICAgIGNvbnRyb2xsZXIuYWJvcnQodmFsdWUucmVhc29uKTtcbiAgfSBlbHNlIGlmICh2YWx1ZS5zdHJlYW1OYW1lKSB7XG4gICAgY29uc3QgcmVhZGVyQ2FuY2VsID0gc2V0dXBBYm9ydFN0cmVhbVJlYWRlcihcbiAgICAgIGNvbnRyb2xsZXIsXG4gICAgICBydW5JZCxcbiAgICAgIHZhbHVlLnN0cmVhbU5hbWUsXG4gICAgICBvcHNcbiAgICApO1xuICAgIHRhZ0Fib3J0UGFpcihjb250cm9sbGVyLCB2YWx1ZSwgcmVhZGVyQ2FuY2VsKTtcbiAgfSBlbHNlIHtcbiAgICB0YWdBYm9ydFBhaXIoY29udHJvbGxlciwgdmFsdWUpO1xuICB9XG5cbiAgLy8gT3ZlcnJpZGUgYWJvcnQoKSB0byBhbHNvIHdyaXRlIHN0cmVhbSArIHJlc3VtZSBob29rIChmb3Igc3RlcC1pbml0aWF0ZWQgYWJvcnQpXG4gIGNvbnN0IG9yaWdpbmFsQWJvcnQgPSBjb250cm9sbGVyLmFib3J0LmJpbmQoY29udHJvbGxlcik7XG4gIGNvbnRyb2xsZXIuYWJvcnQgPSAocmVhc29uPzogdW5rbm93bikgPT4ge1xuICAgIGlmIChjb250cm9sbGVyLnNpZ25hbC5hYm9ydGVkKSByZXR1cm47XG4gICAgb3JpZ2luYWxBYm9ydChyZWFzb24pO1xuXG4gICAgY29uc3QgY3R4ID0gY29udGV4dFN0b3JhZ2UuZ2V0U3RvcmUoKTtcbiAgICBpZiAoY3R4KSB7XG4gICAgICBjdHgub3BzLnB1c2goXG4gICAgICAgIChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIC8vIERlaHlkcmF0ZSB0aGUgYWJvcnQgcGF5bG9hZCB0aHJvdWdoIHRoZSBzYW1lIG1hY2hpbmVyeSB0aGUgaG9va1xuICAgICAgICAgICAgLy8gZXZlbnQgdXNlcyBzbyB0aGUgYHJlYXNvbmAgcm91bmQtdHJpcHMgd2l0aCBmdWxsIHR5cGUgZmlkZWxpdHlcbiAgICAgICAgICAgIC8vIChET01FeGNlcHRpb24sIGN1c3RvbSBlcnJvcnMsIGV0Yy4pIGFuZCByZXNwZWN0cyB0aGUgcnVuJ3NcbiAgICAgICAgICAgIC8vIGVuY3J5cHRpb24ga2V5IOKAlCBzeW1tZXRyaWMgd2l0aCB3aGF0IHRoZSBzdXNwZW5zaW9uIGhhbmRsZXJcbiAgICAgICAgICAgIC8vIHdyaXRlcyBmb3Igd29ya2Zsb3ctaW5pdGlhdGVkIGFib3J0cy5cbiAgICAgICAgICAgIGNvbnN0IHBheWxvYWQgPSBhd2FpdCBkZWh5ZHJhdGVTdGVwQXJndW1lbnRzKFxuICAgICAgICAgICAgICB7IGFib3J0ZWQ6IHRydWUsIHJlYXNvbiB9LFxuICAgICAgICAgICAgICBjdHgud29ya2Zsb3dNZXRhZGF0YS53b3JrZmxvd1J1bklkLFxuICAgICAgICAgICAgICBjdHguZW5jcnlwdGlvbktleVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGNvbnN0IHdyaXRhYmxlID0gbmV3IFdvcmtmbG93U2VydmVyV3JpdGFibGVTdHJlYW0oXG4gICAgICAgICAgICAgIGN0eC53b3JrZmxvd01ldGFkYXRhLndvcmtmbG93UnVuSWQsXG4gICAgICAgICAgICAgIHZhbHVlLnN0cmVhbU5hbWVcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBjb25zdCB3cml0ZXIgPSB3cml0YWJsZS5nZXRXcml0ZXIoKTtcbiAgICAgICAgICAgIGF3YWl0IHdyaXRlci53cml0ZShwYXlsb2FkIGFzIFVpbnQ4QXJyYXkpO1xuICAgICAgICAgICAgYXdhaXQgd3JpdGVyLmNsb3NlKCk7XG4gICAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgICAvLyBCZXN0LWVmZm9ydCBzdHJlYW0gd3JpdGVcbiAgICAgICAgICB9XG4gICAgICAgIH0pKClcbiAgICAgICk7XG5cbiAgICAgIGlmICh2YWx1ZS5ob29rVG9rZW4pIHtcbiAgICAgICAgY3R4Lm9wcy5wdXNoKFxuICAgICAgICAgIChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICBjb25zdCB7IHJlc3VtZUhvb2s6IHJlc3VtZUhvb2tGbiB9ID0gYXdhaXQgaW1wb3J0KFxuICAgICAgICAgICAgICAgICcuL3J1bnRpbWUvcmVzdW1lLWhvb2suanMnXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIGF3YWl0IHJlc3VtZUhvb2tGbih2YWx1ZS5ob29rVG9rZW4sIHtcbiAgICAgICAgICAgICAgICBhYm9ydGVkOiB0cnVlLFxuICAgICAgICAgICAgICAgIHJlYXNvbixcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICAgICAgLy8gQmVzdC1lZmZvcnQgaG9vayByZXN1bWUg4oCUIHJldHJ5IG9uIG5leHQgcmVwbGF5XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSkoKVxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICByZXR1cm4gY29udHJvbGxlcjtcbn1cblxuLyoqXG4gKiBSZXZpdmVzIGp1c3QgYW4gQWJvcnRTaWduYWwgd2l0aG91dCB0aGUgcGF0Y2hlZCBhYm9ydCgpIG92ZXJoZWFkLlxuICogVXNlZCB3aGVuIG9ubHkgYSBzaWduYWwgKG5vdCBhIGNvbnRyb2xsZXIpIHdhcyBzZXJpYWxpemVkLlxuICovXG5mdW5jdGlvbiByZXZpdmVBYm9ydFNpZ25hbChcbiAgdmFsdWU6IFNlcmlhbGl6YWJsZVNwZWNpYWxbJ0Fib3J0U2lnbmFsJ10sXG4gIG9wczogUHJvbWlzZTx2b2lkPltdLFxuICBydW5JZDogc3RyaW5nXG4pOiBBYm9ydFNpZ25hbCB7XG4gIGNvbnN0IGNvbnRyb2xsZXIgPSBuZXcgQWJvcnRDb250cm9sbGVyKCk7XG5cbiAgaWYgKHZhbHVlLmFib3J0ZWQpIHtcbiAgICB0YWdBYm9ydFBhaXIoY29udHJvbGxlciwgdmFsdWUpO1xuICAgIGNvbnRyb2xsZXIuYWJvcnQodmFsdWUucmVhc29uKTtcbiAgfSBlbHNlIGlmICh2YWx1ZS5zdHJlYW1OYW1lKSB7XG4gICAgY29uc3QgcmVhZGVyQ2FuY2VsID0gc2V0dXBBYm9ydFN0cmVhbVJlYWRlcihcbiAgICAgIGNvbnRyb2xsZXIsXG4gICAgICBydW5JZCxcbiAgICAgIHZhbHVlLnN0cmVhbU5hbWUsXG4gICAgICBvcHNcbiAgICApO1xuICAgIHRhZ0Fib3J0UGFpcihjb250cm9sbGVyLCB2YWx1ZSwgcmVhZGVyQ2FuY2VsKTtcbiAgfSBlbHNlIHtcbiAgICB0YWdBYm9ydFBhaXIoY29udHJvbGxlciwgdmFsdWUpO1xuICB9XG5cbiAgcmV0dXJuIGNvbnRyb2xsZXIuc2lnbmFsO1xufVxuXG4vKipcbiAqIEJhc2UgcmV2aXZlcnMgc2hhcmVkIGFjcm9zcyBhbGwgc2VyaWFsaXphdGlvbiBib3VuZGFyaWVzLlxuICogQ29tcG9zZXM6IGNsYXNzICsgY29tbW9uIHJldml2ZXJzIGZyb20gdGhlIG1vZHVsYXIgbW9kdWxlcy5cbiAqXG4gKiBUaGlzIGlzIGV4cG9ydGVkIGJlY2F1c2Ugc2VyaWFsaXphdGlvbi1mb3JtYXQudHMgYW5kIG90aGVyIGZpbGVzIHJlZmVyZW5jZSBpdC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldENvbW1vblJldml2ZXJzKGdsb2JhbDogUmVjb3JkPHN0cmluZywgYW55PiA9IGdsb2JhbFRoaXMpIHtcbiAgcmV0dXJuIHtcbiAgICAuLi5nZXRDbGFzc1Jldml2ZXJzKGdsb2JhbCksXG4gICAgLi4uZ2V0Q29tbW9uUmV2aXZlcnNGcm9tTW9kdWxlKGdsb2JhbCksXG4gIH0gYXMgY29uc3Qgc2F0aXNmaWVzIFBhcnRpYWw8UmV2aXZlcnM+O1xufVxuXG4vKipcbiAqIFJlc29sdmUgdGhlIGVuY3J5cHQtb25seSBrZXkgbmVlZGVkIHdoZW4gYSBjaGlsZCB3cml0ZXMgaW50byBhbm90aGVyIHJ1bidzXG4gKiBzdHJlYW0uIE5ldyBkZXNjcmlwdG9ycyBpbmNsdWRlIHRoZSBvd25lcidzIGRlcGxveW1lbnQgSUQ7IGRlc2NyaXB0b3JzXG4gKiBjcmVhdGVkIGJ5IG9sZGVyIFNESyB2ZXJzaW9ucyBmYWxsIGJhY2sgdG8gbG9hZGluZyB0aGUgb3duaW5nIHJ1bi5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gZ2V0Rm9yd2FyZGVkV3JpdGFibGVFbmNyeXB0aW9uS2V5KFxuICBydW5JZDogc3RyaW5nLFxuICBkZXBsb3ltZW50SWQ6IHN0cmluZyB8IHVuZGVmaW5lZFxuKTogUHJvbWlzZTxDcnlwdG9LZXkgfCB1bmRlZmluZWQ+IHtcbiAgY29uc3Qgd29ybGQgPSBhd2FpdCBnZXRXb3JsZExhenkoKTtcbiAgaWYgKCF3b3JsZC5nZXRFbmNyeXB0aW9uS2V5Rm9yUnVuKSByZXR1cm4gdW5kZWZpbmVkO1xuXG4gIGNvbnN0IHJhd0tleSA9IGRlcGxveW1lbnRJZFxuICAgID8gYXdhaXQgd29ybGQuZ2V0RW5jcnlwdGlvbktleUZvclJ1bihydW5JZCwgeyBkZXBsb3ltZW50SWQgfSlcbiAgICA6IGF3YWl0IHdvcmxkLmdldEVuY3J5cHRpb25LZXlGb3JSdW4oYXdhaXQgd29ybGQucnVucy5nZXQocnVuSWQpKTtcbiAgcmV0dXJuIHJhd0tleSA/IGF3YWl0IGltcG9ydEtleShyYXdLZXksIFsnZW5jcnlwdCddKSA6IHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBSZXZpdmVycyBmb3IgZGVzZXJpYWxpemF0aW9uIGJvdW5kYXJ5IGZyb20gdGhlIGNsaWVudCBzaWRlLFxuICogcmVjZWl2aW5nIHRoZSByZXR1cm4gdmFsdWUgZnJvbSB0aGUgd29ya2Zsb3cgaGFuZGxlci5cbiAqXG4gKiBAcGFyYW0gZ2xvYmFsXG4gKiBAcGFyYW0gb3BzXG4gKiBAcGFyYW0gcnVuSWRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEV4dGVybmFsUmV2aXZlcnMoXG4gIGdsb2JhbDogUmVjb3JkPHN0cmluZywgYW55PiA9IGdsb2JhbFRoaXMsXG4gIG9wczogUHJvbWlzZTx2b2lkPltdLFxuICBydW5JZDogc3RyaW5nLFxuICBjcnlwdG9LZXk6IEVuY3J5cHRpb25LZXlQYXJhbVxuKTogUGFydGlhbDxSZXZpdmVycz4ge1xuICByZXR1cm4ge1xuICAgIC4uLmdldENvbW1vblJldml2ZXJzKGdsb2JhbCksXG5cbiAgICAvLyBTdGVwRnVuY3Rpb24gc2hvdWxkIG5vdCBiZSByZXR1cm5lZCBmcm9tIHdvcmtmbG93cyB0byBjbGllbnRzXG4gICAgU3RlcEZ1bmN0aW9uOiAoKSA9PiB7XG4gICAgICB0aHJvdyBuZXcgU2VyaWFsaXphdGlvbkVycm9yKFxuICAgICAgICAnU3RlcCBmdW5jdGlvbnMgY2Fubm90IGJlIGRlc2VyaWFsaXplZCBpbiBjbGllbnQgY29udGV4dC4gU3RlcCBmdW5jdGlvbnMgc2hvdWxkIG5vdCBiZSByZXR1cm5lZCBmcm9tIHdvcmtmbG93cy4nLFxuICAgICAgICB7XG4gICAgICAgICAgaGludDogJ0Egc3RlcCBmdW5jdGlvbiByZWZlcmVuY2UgcmVhY2hlZCB0aGUgY2xpZW50LiBSZXR1cm4gYSBzZXJpYWxpemFibGUgdmFsdWUgKGUuZy4gdGhlIHN0ZXAgcmVzdWx0KSBpbnN0ZWFkIG9mIHRoZSBzdGVwIGl0c2VsZi4nLFxuICAgICAgICB9XG4gICAgICApO1xuICAgIH0sXG5cbiAgICBXb3JrZmxvd0Z1bmN0aW9uOiAodmFsdWUpID0+XG4gICAgICBPYmplY3QuYXNzaWduKFxuICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgdGhyb3cgbmV3IFNlcmlhbGl6YXRpb25FcnJvcihcbiAgICAgICAgICAgICdXb3JrZmxvdyBmdW5jdGlvbnMgY2Fubm90IGJlIGNhbGxlZCBkaXJlY3RseS4gVXNlIHN0YXJ0KCkgdG8gaW52b2tlIHRoZW0uJyxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaGludDogJ1dyYXAgdGhlIHdvcmtmbG93IHdpdGggYHN0YXJ0KHdvcmtmbG93Rm4sIHsgLi4uIH0pYCBmcm9tIGB3b3JrZmxvd2AgdG8gYmVnaW4gYSBydW4gaW5zdGVhZCBvZiBpbnZva2luZyBpdCBsaWtlIGEgbm9ybWFsIGZ1bmN0aW9uLicsXG4gICAgICAgICAgICB9XG4gICAgICAgICAgKTtcbiAgICAgICAgfSxcbiAgICAgICAgeyB3b3JrZmxvd0lkOiB2YWx1ZS53b3JrZmxvd0lkIH1cbiAgICAgICksXG5cbiAgICBSZXF1ZXN0OiAodmFsdWUpID0+IHtcbiAgICAgIGNvbnN0IGluaXQ6IFJlcXVlc3RJbml0ICYgeyBkdXBsZXg/OiBzdHJpbmcgfSA9IHtcbiAgICAgICAgbWV0aG9kOiB2YWx1ZS5tZXRob2QsXG4gICAgICAgIGhlYWRlcnM6IG5ldyBnbG9iYWwuSGVhZGVycyh2YWx1ZS5oZWFkZXJzKSxcbiAgICAgICAgYm9keTogdmFsdWUuYm9keSxcbiAgICAgICAgZHVwbGV4OiB2YWx1ZS5kdXBsZXgsXG4gICAgICB9O1xuICAgICAgaWYgKHZhbHVlLnNpZ25hbCkgaW5pdC5zaWduYWwgPSB2YWx1ZS5zaWduYWw7XG4gICAgICBjb25zdCByZXF1ZXN0ID0gbmV3IGdsb2JhbC5SZXF1ZXN0KHZhbHVlLnVybCwgaW5pdCk7XG4gICAgICAvLyBUaGUgUmVxdWVzdCBjb25zdHJ1Y3RvciBjcmVhdGVzIGFuIGludGVybmFsIHNpZ25hbCBjb3B5LCBzbyB0aGVcbiAgICAgIC8vIGFib3J0LWludGVybmFsIHN5bWJvbHMgc2V0IGJ5IHJldml2ZUFib3J0U2lnbmFsIGRvbid0IHByb3BhZ2F0ZS5cbiAgICAgIC8vIFJlLXRhZyB0aGUgcmVxdWVzdCdzIG93biBzaWduYWwgc28gY2FuY2VsQWJvcnRSZWFkZXJzIGNhbiBmaW5kIGl0LlxuICAgICAgaWYgKHZhbHVlLnNpZ25hbCkgY29weUFib3J0SW50ZXJuYWxzKHZhbHVlLnNpZ25hbCwgcmVxdWVzdC5zaWduYWwpO1xuICAgICAgcmV0dXJuIHJlcXVlc3Q7XG4gICAgfSxcbiAgICBSZXNwb25zZTogKHZhbHVlKSA9PiB7XG4gICAgICAvLyBOb3RlOiBSZXNwb25zZSBjb25zdHJ1Y3RvciBvbmx5IGFjY2VwdHMgc3RhdHVzLCBzdGF0dXNUZXh0LCBhbmQgaGVhZGVyc1xuICAgICAgLy8gVGhlIHR5cGUsIHVybCwgYW5kIHJlZGlyZWN0ZWQgcHJvcGVydGllcyBhcmUgcmVhZC1vbmx5IGFuZCBzZXQgYnkgdGhlIGNvbnN0cnVjdG9yXG4gICAgICByZXR1cm4gbmV3IGdsb2JhbC5SZXNwb25zZSh2YWx1ZS5ib2R5LCB7XG4gICAgICAgIHN0YXR1czogdmFsdWUuc3RhdHVzLFxuICAgICAgICBzdGF0dXNUZXh0OiB2YWx1ZS5zdGF0dXNUZXh0LFxuICAgICAgICBoZWFkZXJzOiBuZXcgZ2xvYmFsLkhlYWRlcnModmFsdWUuaGVhZGVycyksXG4gICAgICB9KTtcbiAgICB9LFxuICAgIFJlYWRhYmxlU3RyZWFtOiAodmFsdWUpID0+IHtcbiAgICAgIC8vIElmIHRoaXMgaGFzIGJvZHlJbml0LCBpdCBjYW1lIGZyb20gYSBSZXNwb25zZSBjb25zdHJ1Y3RvclxuICAgICAgLy8gQ29udmVydCBpdCB0byBhIFJFQUwgc3RyZWFtIG5vdyB0aGF0IHdlJ3JlIG91dHNpZGUgdGhlIHdvcmtmbG93XG4gICAgICBpZiAoJ2JvZHlJbml0JyBpbiB2YWx1ZSkge1xuICAgICAgICBjb25zdCBib2R5SW5pdCA9IHZhbHVlLmJvZHlJbml0O1xuICAgICAgICAvLyBVc2UgdGhlIG5hdGl2ZSBSZXNwb25zZSBjb25zdHJ1Y3RvciB0byBwcm9wZXJseSBjb252ZXJ0IEJvZHlJbml0IHRvIFJlYWRhYmxlU3RyZWFtXG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gbmV3IGdsb2JhbC5SZXNwb25zZShib2R5SW5pdCk7XG4gICAgICAgIHJldHVybiByZXNwb25zZS5ib2R5O1xuICAgICAgfVxuXG4gICAgICBjb25zdCByZWFkYWJsZSA9IG5ldyBXb3JrZmxvd1NlcnZlclJlYWRhYmxlU3RyZWFtKFxuICAgICAgICBydW5JZCxcbiAgICAgICAgdmFsdWUubmFtZSxcbiAgICAgICAgdmFsdWUuc3RhcnRJbmRleFxuICAgICAgKTtcbiAgICAgIGlmICh2YWx1ZS50eXBlID09PSAnYnl0ZXMnKSB7XG4gICAgICAgIC8vIEZvciBieXRlIHN0cmVhbXMsIHVzZSBmbHVzaGFibGUgcGlwZSB3aXRoIGxvY2sgcG9sbGluZ1xuICAgICAgICBjb25zdCBzdGF0ZSA9IGNyZWF0ZUZsdXNoYWJsZVN0YXRlKCk7XG4gICAgICAgIG9wcy5wdXNoKHN0YXRlLnByb21pc2UpO1xuXG4gICAgICAgIC8vIENyZWF0ZSBhbiBpZGVudGl0eSB0cmFuc2Zvcm0gdG8gZ2l2ZSB0aGUgdXNlciBhIHJlYWRhYmxlXG4gICAgICAgIGNvbnN0IHsgcmVhZGFibGU6IHVzZXJSZWFkYWJsZSwgd3JpdGFibGUgfSA9XG4gICAgICAgICAgbmV3IGdsb2JhbC5UcmFuc2Zvcm1TdHJlYW0oKTtcblxuICAgICAgICAvLyBTdGFydCB0aGUgZmx1c2hhYmxlIHBpcGUgaW4gdGhlIGJhY2tncm91bmRcbiAgICAgICAgZmx1c2hhYmxlUGlwZShyZWFkYWJsZSwgd3JpdGFibGUsIHN0YXRlKS5jYXRjaCgoKSA9PiB7XG4gICAgICAgICAgLy8gRXJyb3JzIGFyZSBoYW5kbGVkIHZpYSBzdGF0ZS5yZWplY3RcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gU3RhcnQgcG9sbGluZyB0byBkZXRlY3Qgd2hlbiB1c2VyIHJlbGVhc2VzIGxvY2tcbiAgICAgICAgcG9sbFJlYWRhYmxlTG9jayh1c2VyUmVhZGFibGUsIHN0YXRlKTtcblxuICAgICAgICByZXR1cm4gdXNlclJlYWRhYmxlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgdHJhbnNmb3JtID0gZ2V0RGVzZXJpYWxpemVTdHJlYW0oXG4gICAgICAgICAgZ2V0RXh0ZXJuYWxSZXZpdmVycyhnbG9iYWwsIG9wcywgcnVuSWQsIGNyeXB0b0tleSksXG4gICAgICAgICAgY3J5cHRvS2V5XG4gICAgICAgICk7XG4gICAgICAgIGNvbnN0IHN0YXRlID0gY3JlYXRlRmx1c2hhYmxlU3RhdGUoKTtcbiAgICAgICAgb3BzLnB1c2goc3RhdGUucHJvbWlzZSk7XG5cbiAgICAgICAgLy8gU3RhcnQgdGhlIGZsdXNoYWJsZSBwaXBlIGluIHRoZSBiYWNrZ3JvdW5kXG4gICAgICAgIGZsdXNoYWJsZVBpcGUocmVhZGFibGUsIHRyYW5zZm9ybS53cml0YWJsZSwgc3RhdGUpLmNhdGNoKCgpID0+IHtcbiAgICAgICAgICAvLyBFcnJvcnMgYXJlIGhhbmRsZWQgdmlhIHN0YXRlLnJlamVjdFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBTdGFydCBwb2xsaW5nIHRvIGRldGVjdCB3aGVuIHVzZXIgcmVsZWFzZXMgbG9ja1xuICAgICAgICBwb2xsUmVhZGFibGVMb2NrKHRyYW5zZm9ybS5yZWFkYWJsZSwgc3RhdGUpO1xuXG4gICAgICAgIHJldHVybiB0cmFuc2Zvcm0ucmVhZGFibGU7XG4gICAgICB9XG4gICAgfSxcbiAgICBXcml0YWJsZVN0cmVhbTogKHZhbHVlKSA9PiB7XG4gICAgICAvLyBTYW1lIGhhbmRsaW5nIGFzIGBnZXRTdGVwUmV2aXZlcnMuV3JpdGFibGVTdHJlYW1gIOKAlCBzZWUgY29tbWVudHNcbiAgICAgIC8vIHRoZXJlIGZvciB0aGUgY3Jvc3MtcnVuIGNhc2UgKHdyaXRhYmxlIGNhcnJpZXMgYHJ1bklkYCBmcm9tXG4gICAgICAvLyBwYXJlbnQg4oaSIGNoaWxkIGZvcndhcmRpbmcgdmlhIGBzdGFydCgpYCkuXG4gICAgICBjb25zdCB0YXJnZXRSdW5JZCA9IHR5cGVvZiB2YWx1ZS5ydW5JZCA9PT0gJ3N0cmluZycgPyB2YWx1ZS5ydW5JZCA6IHJ1bklkO1xuICAgICAgY29uc3QgdGFyZ2V0S2V5OiBFbmNyeXB0aW9uS2V5UGFyYW0gPVxuICAgICAgICB0YXJnZXRSdW5JZCA9PT0gcnVuSWRcbiAgICAgICAgICA/IGNyeXB0b0tleVxuICAgICAgICAgIDogZ2V0Rm9yd2FyZGVkV3JpdGFibGVFbmNyeXB0aW9uS2V5KHRhcmdldFJ1bklkLCB2YWx1ZS5kZXBsb3ltZW50SWQpO1xuXG4gICAgICBjb25zdCBzZXJpYWxpemUgPSBnZXRTZXJpYWxpemVTdHJlYW0oXG4gICAgICAgIGdldEV4dGVybmFsUmVkdWNlcnMoZ2xvYmFsLCBvcHMsIHRhcmdldFJ1bklkLCB0YXJnZXRLZXkpLFxuICAgICAgICB0YXJnZXRLZXlcbiAgICAgICk7XG4gICAgICBjb25zdCBzZXJ2ZXJXcml0YWJsZSA9IG5ldyBXb3JrZmxvd1NlcnZlcldyaXRhYmxlU3RyZWFtKFxuICAgICAgICB0YXJnZXRSdW5JZCxcbiAgICAgICAgdmFsdWUubmFtZVxuICAgICAgKTtcblxuICAgICAgLy8gQ3JlYXRlIGZsdXNoYWJsZSBzdGF0ZSBmb3IgdGhpcyBzdHJlYW1cbiAgICAgIGNvbnN0IHN0YXRlID0gY3JlYXRlRmx1c2hhYmxlU3RhdGUoKTtcbiAgICAgIG9wcy5wdXNoKHN0YXRlLnByb21pc2UpO1xuXG4gICAgICAvLyBTdGFydCB0aGUgZmx1c2hhYmxlIHBpcGUgaW4gdGhlIGJhY2tncm91bmRcbiAgICAgIGZsdXNoYWJsZVBpcGUoc2VyaWFsaXplLnJlYWRhYmxlLCBzZXJ2ZXJXcml0YWJsZSwgc3RhdGUpLmNhdGNoKCgpID0+IHtcbiAgICAgICAgLy8gRXJyb3JzIGFyZSBoYW5kbGVkIHZpYSBzdGF0ZS5yZWplY3RcbiAgICAgIH0pO1xuXG4gICAgICAvLyBTdGFydCBwb2xsaW5nIHRvIGRldGVjdCB3aGVuIHVzZXIgcmVsZWFzZXMgbG9ja1xuICAgICAgcG9sbFdyaXRhYmxlTG9jayhzZXJpYWxpemUud3JpdGFibGUsIHN0YXRlKTtcblxuICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHNlcmlhbGl6ZS53cml0YWJsZSwgU1RSRUFNX05BTUVfU1lNQk9MLCB7XG4gICAgICAgIHZhbHVlOiB2YWx1ZS5uYW1lLFxuICAgICAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgICB9KTtcbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShzZXJpYWxpemUud3JpdGFibGUsIFNUUkVBTV9TRVJWRVJfUlVOX0lEX1NZTUJPTCwge1xuICAgICAgICB2YWx1ZTogdGFyZ2V0UnVuSWQsXG4gICAgICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICAgIH0pO1xuICAgICAgaWYgKHR5cGVvZiB2YWx1ZS5kZXBsb3ltZW50SWQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShcbiAgICAgICAgICBzZXJpYWxpemUud3JpdGFibGUsXG4gICAgICAgICAgU1RSRUFNX1NFUlZFUl9ERVBMT1lNRU5UX0lEX1NZTUJPTCxcbiAgICAgICAgICB7XG4gICAgICAgICAgICB2YWx1ZTogdmFsdWUuZGVwbG95bWVudElkLFxuICAgICAgICAgICAgd3JpdGFibGU6IGZhbHNlLFxuICAgICAgICAgIH1cbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHNlcmlhbGl6ZS53cml0YWJsZTtcbiAgICB9LFxuXG4gICAgQWJvcnRDb250cm9sbGVyOiAodmFsdWUpID0+IHJldml2ZUFib3J0Q29udHJvbGxlcih2YWx1ZSwgb3BzLCBydW5JZCksXG4gICAgQWJvcnRTaWduYWw6ICh2YWx1ZSkgPT4gcmV2aXZlQWJvcnRTaWduYWwodmFsdWUsIG9wcywgcnVuSWQpLFxuICB9O1xufVxuXG4vKipcbiAqIFJldml2ZXJzIGZvciBkZXNlcmlhbGl6YXRpb24gYm91bmRhcnkgZnJvbSB3aXRoaW4gdGhlIHdvcmtmbG93IGV4ZWN1dGlvblxuICogZW52aXJvbm1lbnQsIHJlY2VpdmluZyBhcmd1bWVudHMgZnJvbSB0aGUgY2xpZW50IHNpZGUsIGFuZCByZXR1cm4gdmFsdWVzXG4gKiBmcm9tIHRoZSBzdGVwcy5cbiAqXG4gKiBAcGFyYW0gZ2xvYmFsXG4gKiBAcmV0dXJuc1xuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0V29ya2Zsb3dSZXZpdmVycyhcbiAgZ2xvYmFsOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0gZ2xvYmFsVGhpc1xuKTogUGFydGlhbDxSZXZpdmVycz4ge1xuICByZXR1cm4ge1xuICAgIC4uLmdldENvbW1vblJldml2ZXJzKGdsb2JhbCksXG4gICAgLy8gU3RlcEZ1bmN0aW9uIHJldml2ZXIgZm9yIHdvcmtmbG93IGNvbnRleHQgLSB1c2VzIHRoZSBtb2R1bGFyIHJldml2ZXJcbiAgICAvLyB3aGljaCBjYWxscyBXT1JLRkxPV19VU0VfU1RFUCBmcm9tIGdsb2JhbCB0byByZWNvbnN0cnVjdCBzdGVwIHByb3hpZXNcbiAgICAuLi5nZXRTdGVwRnVuY3Rpb25SZXZpdmVyKGdsb2JhbCksXG4gICAgUmVxdWVzdDogKHZhbHVlKSA9PiB7XG4gICAgICBPYmplY3Quc2V0UHJvdG90eXBlT2YodmFsdWUsIGdsb2JhbC5SZXF1ZXN0LnByb3RvdHlwZSk7XG4gICAgICBjb25zdCByZXNwb25zZVdyaXRhYmxlID0gdmFsdWUucmVzcG9uc2VXcml0YWJsZTtcbiAgICAgIGlmIChyZXNwb25zZVdyaXRhYmxlKSB7XG4gICAgICAgICh2YWx1ZSBhcyBhbnkpW1dFQkhPT0tfUkVTUE9OU0VfV1JJVEFCTEVdID0gcmVzcG9uc2VXcml0YWJsZTtcbiAgICAgICAgZGVsZXRlIHZhbHVlLnJlc3BvbnNlV3JpdGFibGU7XG4gICAgICAgICh2YWx1ZSBhcyBhbnkpLnJlc3BvbmRXaXRoID0gKCkgPT4ge1xuICAgICAgICAgIHRocm93IG5ldyBTZXJpYWxpemF0aW9uRXJyb3IoXG4gICAgICAgICAgICAnYHJlc3BvbmRXaXRoKClgIG11c3QgYmUgY2FsbGVkIGZyb20gd2l0aGluIGEgc3RlcCBmdW5jdGlvbi4nLFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBoaW50OiAnTW92ZSB0aGUgYHJlc3BvbmRXaXRoKC4uLilgIGNhbGwgaW5zaWRlIGEgYFwidXNlIHN0ZXBcImAgZnVuY3Rpb24g4oCUIGl0IGNhbm5vdCBiZSBpbnZva2VkIGZyb20gYSB3b3JrZmxvdyBjb250ZXh0LicsXG4gICAgICAgICAgICB9XG4gICAgICAgICAgKTtcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9LFxuICAgIC8vIFdvcmtmbG93IGZ1bmN0aW9uIHJldml2ZXIgZm9yIHdvcmtmbG93IGNvbnRleHQg4oCUIHJldHVybnMgYSBmdW5jdGlvbi1saWtlXG4gICAgLy8gb2JqZWN0IHdpdGggLndvcmtmbG93SWQgdGhhdCBtaW1pY3Mgd2hhdCB0aGUgU1dDIGNvbXBpbGVyIHByb2R1Y2VzLFxuICAgIFdvcmtmbG93RnVuY3Rpb246ICh2YWx1ZSkgPT5cbiAgICAgIE9iamVjdC5hc3NpZ24oXG4gICAgICAgICgpID0+IHtcbiAgICAgICAgICB0aHJvdyBuZXcgU2VyaWFsaXphdGlvbkVycm9yKFxuICAgICAgICAgICAgJ1dvcmtmbG93IGZ1bmN0aW9ucyBjYW5ub3QgYmUgY2FsbGVkIGRpcmVjdGx5LiBVc2Ugc3RhcnQoKSB0byBpbnZva2UgdGhlbS4nLFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBoaW50OiAnV3JhcCB0aGUgd29ya2Zsb3cgd2l0aCBgc3RhcnQod29ya2Zsb3dGbiwgeyAuLi4gfSlgIGZyb20gYHdvcmtmbG93YCB0byBiZWdpbiBhIHJ1biBpbnN0ZWFkIG9mIGludm9raW5nIGl0IGxpa2UgYSBub3JtYWwgZnVuY3Rpb24uJyxcbiAgICAgICAgICAgIH1cbiAgICAgICAgICApO1xuICAgICAgICB9LFxuICAgICAgICB7IHdvcmtmbG93SWQ6IHZhbHVlLndvcmtmbG93SWQgfVxuICAgICAgKSxcbiAgICBSZXNwb25zZTogKHZhbHVlKSA9PiB7XG4gICAgICBPYmplY3Quc2V0UHJvdG90eXBlT2YodmFsdWUsIGdsb2JhbC5SZXNwb25zZS5wcm90b3R5cGUpO1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH0sXG4gICAgUmVhZGFibGVTdHJlYW06ICh2YWx1ZSkgPT4ge1xuICAgICAgLy8gQ2hlY2sgaWYgdGhpcyBpcyBhIEJvZHlJbml0IHRoYXQgc2hvdWxkIGJlIHdyYXBwZWQgaW4gYSBmYWtlIHN0cmVhbVxuICAgICAgaWYgKCdib2R5SW5pdCcgaW4gdmFsdWUpIHtcbiAgICAgICAgLy8gUmVjcmVhdGUgdGhlIGZha2Ugc3RyZWFtIHdpdGggdGhlIEJvZHlJbml0XG4gICAgICAgIHJldHVybiBPYmplY3QuY3JlYXRlKGdsb2JhbC5SZWFkYWJsZVN0cmVhbS5wcm90b3R5cGUsIHtcbiAgICAgICAgICBbQk9EWV9JTklUX1NZTUJPTF06IHtcbiAgICAgICAgICAgIHZhbHVlOiB2YWx1ZS5ib2R5SW5pdCxcbiAgICAgICAgICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgLy8gUmVndWxhciBzdHJlYW0gaGFuZGxpbmdcbiAgICAgIHJldHVybiBPYmplY3QuY3JlYXRlKGdsb2JhbC5SZWFkYWJsZVN0cmVhbS5wcm90b3R5cGUsIHtcbiAgICAgICAgW1NUUkVBTV9OQU1FX1NZTUJPTF06IHtcbiAgICAgICAgICB2YWx1ZTogdmFsdWUubmFtZSxcbiAgICAgICAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgICAgIH0sXG4gICAgICAgIFtTVFJFQU1fVFlQRV9TWU1CT0xdOiB7XG4gICAgICAgICAgdmFsdWU6IHZhbHVlLnR5cGUsXG4gICAgICAgICAgd3JpdGFibGU6IGZhbHNlLFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfSxcbiAgICBXcml0YWJsZVN0cmVhbTogKHZhbHVlKSA9PiB7XG4gICAgICBjb25zdCBkZXNjcmlwdG9yOiBQcm9wZXJ0eURlc2NyaXB0b3JNYXAgPSB7XG4gICAgICAgIFtTVFJFQU1fTkFNRV9TWU1CT0xdOiB7XG4gICAgICAgICAgdmFsdWU6IHZhbHVlLm5hbWUsXG4gICAgICAgICAgd3JpdGFibGU6IGZhbHNlLFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICAgIC8vIFByZXNlcnZlIHRoZSBmb3JlaWduIHJ1bklkLCBpZiBwcmVzZW50LCBzbyB0aGF0IHdoZW4gdGhlXG4gICAgICAvLyBoYW5kbGUgaXMgbGF0ZXIgcGFzc2VkIHRvIGEgc3RlcCB0aGUgd29ya2Zsb3cgcmVkdWNlciBjYW5cbiAgICAgIC8vIGZvcndhcmQgaXQgdGhyb3VnaCB0byB0aGUgc3RlcCByZXZpdmVyLlxuICAgICAgaWYgKHR5cGVvZiB2YWx1ZS5ydW5JZCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgZGVzY3JpcHRvcltTVFJFQU1fU0VSVkVSX1JVTl9JRF9TWU1CT0xdID0ge1xuICAgICAgICAgIHZhbHVlOiB2YWx1ZS5ydW5JZCxcbiAgICAgICAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICBpZiAodHlwZW9mIHZhbHVlLmRlcGxveW1lbnRJZCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgZGVzY3JpcHRvcltTVFJFQU1fU0VSVkVSX0RFUExPWU1FTlRfSURfU1lNQk9MXSA9IHtcbiAgICAgICAgICB2YWx1ZTogdmFsdWUuZGVwbG95bWVudElkLFxuICAgICAgICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBPYmplY3QuY3JlYXRlKGdsb2JhbC5Xcml0YWJsZVN0cmVhbS5wcm90b3R5cGUsIGRlc2NyaXB0b3IpO1xuICAgIH0sXG5cbiAgICAvLyBBYm9ydENvbnRyb2xsZXIvQWJvcnRTaWduYWwgcmV2aXZlZCBpbnNpZGUgdGhlIHdvcmtmbG93IFZNLiBVc2UgdGhlXG4gICAgLy8gcmVhbCBXb3JrZmxvd0Fib3J0U2lnbmFsIGNsYXNzIHNvIGFkZEV2ZW50TGlzdGVuZXIoJ2Fib3J0JywgZm4pIGFjdHVhbGx5XG4gICAgLy8gZmlyZXMgd2hlbiB0aGUgc2lnbmFsIGFib3J0cyAodGhlIHByZXZpb3VzIG5vLW9wIHN0dWIgc2lsZW50bHkgZHJvcHBlZFxuICAgIC8vIGxpc3RlbmVyIHJlZ2lzdHJhdGlvbnMg4oCUIHNpbGVudCBjb3JyZWN0bmVzcyBidWcgZm9yIG5hdHVyYWwgcGF0dGVybnNcbiAgICAvLyBsaWtlIGBzaWduYWwuYWRkRXZlbnRMaXN0ZW5lcignYWJvcnQnLCBmbilgIGFmdGVyIHJlY2VpdmluZyBhIGRlc2VyaWFsaXplZFxuICAgIC8vIHNpZ25hbCkuIFRoZSBzaWduYWwgZG9lcyBub3Qgb3duIGEgaG9vayBzdWJzY3JpcHRpb24gaGVyZSDigJQgYWJvcnQgc3RhdGVcbiAgICAvLyBpcyBkZWxpdmVyZWQgdmlhIHRoZSBleGlzdGluZyByZXBsYXkgbWFjaGluZXJ5IG9uIHRoZSBzb3VyY2Ugc2lkZS5cbiAgICBBYm9ydENvbnRyb2xsZXI6ICh2YWx1ZSkgPT4ge1xuICAgICAgY29uc3Qgc2lnbmFsID0gbmV3IFdvcmtmbG93QWJvcnRTaWduYWwodmFsdWUuc3RyZWFtTmFtZSwgdmFsdWUuaG9va1Rva2VuKTtcbiAgICAgIGlmICh2YWx1ZS5hYm9ydGVkKSBzaWduYWwuX3NldEFib3J0ZWQodmFsdWUucmVhc29uKTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIFtBQk9SVF9TVFJFQU1fTkFNRV06IHZhbHVlLnN0cmVhbU5hbWUsXG4gICAgICAgIFtBQk9SVF9IT09LX1RPS0VOXTogdmFsdWUuaG9va1Rva2VuLFxuICAgICAgICBzaWduYWwsXG4gICAgICAgIGFib3J0OiAoKSA9PiB7fSxcbiAgICAgIH07XG4gICAgfSxcbiAgICBBYm9ydFNpZ25hbDogKHZhbHVlKSA9PiB7XG4gICAgICBjb25zdCBzaWduYWwgPSBuZXcgV29ya2Zsb3dBYm9ydFNpZ25hbCh2YWx1ZS5zdHJlYW1OYW1lLCB2YWx1ZS5ob29rVG9rZW4pO1xuICAgICAgaWYgKHZhbHVlLmFib3J0ZWQpIHNpZ25hbC5fc2V0QWJvcnRlZCh2YWx1ZS5yZWFzb24pO1xuICAgICAgcmV0dXJuIHNpZ25hbDtcbiAgICB9LFxuICB9O1xufVxuXG4vKipcbiAqIFJldml2ZXJzIGZvciBkZXNlcmlhbGl6YXRpb24gYm91bmRhcnkgZnJvbSB3aXRoaW4gdGhlIHN0ZXAgZXhlY3V0aW9uXG4gKiBlbnZpcm9ubWVudCwgcmVjZWl2aW5nIGFyZ3VtZW50cyBmcm9tIHRoZSB3b3JrZmxvdyBoYW5kbGVyLlxuICpcbiAqIEBwYXJhbSBnbG9iYWxcbiAqIEBwYXJhbSBvcHNcbiAqIEBwYXJhbSBydW5JZFxuICogQHJldHVybnNcbiAqL1xuZnVuY3Rpb24gZ2V0U3RlcFJldml2ZXJzKFxuICBnbG9iYWw6IFJlY29yZDxzdHJpbmcsIGFueT4gPSBnbG9iYWxUaGlzLFxuICBvcHM6IFByb21pc2U8dm9pZD5bXSxcbiAgcnVuSWQ6IHN0cmluZyxcbiAgY3J5cHRvS2V5OiBFbmNyeXB0aW9uS2V5UGFyYW0sXG4gIGRlcGxveW1lbnRJZD86IHN0cmluZ1xuKTogUGFydGlhbDxSZXZpdmVycz4ge1xuICByZXR1cm4ge1xuICAgIC4uLmdldENvbW1vblJldml2ZXJzKGdsb2JhbCksXG5cbiAgICAvLyBTdGVwRnVuY3Rpb24gcmV2aXZlciBmb3Igc3RlcCBjb250ZXh0IC0gcmV0dXJucyByYXcgc3RlcCBmdW5jdGlvblxuICAgIC8vIHdpdGggY2xvc3VyZSB2YXJpYWJsZSBzdXBwb3J0IHZpYSBBc3luY0xvY2FsU3RvcmFnZS5cbiAgICAvL1xuICAgIC8vIEhhbmRsZXMgZm91ciBpbmRlcGVuZGVudCBmbGFncyBmcm9tIHRoZSBzZXJpYWxpemVkIHBheWxvYWQ6XG4gICAgLy8gICAtIGBjbG9zdXJlVmFyc2A6IGludm9rZSB0aGUgYm9keSBpbnNpZGUgYW4gQXN5bmNMb2NhbFN0b3JhZ2UgZnJhbWVcbiAgICAvLyAgICAgc28gdGhlIFNXQy1lbWl0dGVkIGBXT1JLRkxPV19TVEVQX0NPTlRFWFRfU1RPUkFHRWAgSUlGRSBpbiB0aGVcbiAgICAvLyAgICAgaG9pc3RlZCBib2R5IGNhbiBwdWxsIHRoZSBjbG9zdXJlIHZhcmlhYmxlcyBiYWNrIG91dC5cbiAgICAvLyAgIC0gYGJvdW5kVGhpc2A6ICAgYSBgdGhpc2AgdmFsdWUgY2FwdHVyZWQgYnlcbiAgICAvLyAgICAgYHVzZVN0ZXAoLi4uKS5iaW5kKHRoaXMpYCBpbiB0aGUgd29ya2Zsb3cgYnVuZGxlIChsZXhpY2FsLWB0aGlzYFxuICAgIC8vICAgICBhcnJvdyBzdGVwcykuIFRoZSB3cmFwcGVyIGludm9rZXMgdGhlIGJvZHkgdmlhXG4gICAgLy8gICAgIGBzdGVwRm4uYXBwbHkoYm91bmRUaGlzLCBhcmdzKWAgc28gdGhlIGJvZHkgc2VlcyB0aGUgc2FtZVxuICAgIC8vICAgICBgdGhpc2AgaXQgd291bGQgaGF2ZSBoYWQgaW4gdGhlIHdvcmtmbG93IGJ1bmRsZS4gUHJvcGVydHlcbiAgICAvLyAgICAgcHJlc2VuY2Ug4oCUIG5vdCB0cnV0aGluZXNzIOKAlCBpcyBzaWduaWZpY2FudCBiZWNhdXNlXG4gICAgLy8gICAgIGBiaW5kKG51bGwpYCBhbmQgYGJpbmQodW5kZWZpbmVkKWAgYXJlIGJvdGggbGVnYWwgYW5kIHNob3VsZFxuICAgIC8vICAgICByb3VuZC10cmlwIGZhaXRoZnVsbHkuXG4gICAgLy8gICAtIGBib3VuZEFyZ3NgOiAgIHByZWZpbGxlZCBhcmdzIGZyb21cbiAgICAvLyAgICAgYHVzZVN0ZXAoLi4uKS5iaW5kKHRoaXNBcmcsIHgsIHkpYC4gUHJlcGVuZGVkIHRvIHRoZSBjYWxsIGFyZ3NcbiAgICAvLyAgICAgc28gcGFydGlhbCBhcHBsaWNhdGlvbiBzdXJ2aXZlcyBzZXJpYWxpemF0aW9uLlxuICAgIFN0ZXBGdW5jdGlvbjogKHZhbHVlKSA9PiB7XG4gICAgICBjb25zdCBzdGVwSWQgPSB2YWx1ZS5zdGVwSWQ7XG4gICAgICBjb25zdCBjbG9zdXJlVmFycyA9IHZhbHVlLmNsb3N1cmVWYXJzO1xuICAgICAgY29uc3QgaGFzQm91bmRUaGlzID0gJ2JvdW5kVGhpcycgaW4gdmFsdWU7XG4gICAgICBjb25zdCBib3VuZFRoaXMgPSBoYXNCb3VuZFRoaXMgPyB2YWx1ZS5ib3VuZFRoaXMgOiB1bmRlZmluZWQ7XG4gICAgICBjb25zdCBib3VuZEFyZ3MgPSBBcnJheS5pc0FycmF5KHZhbHVlLmJvdW5kQXJncykgPyB2YWx1ZS5ib3VuZEFyZ3MgOiBbXTtcblxuICAgICAgY29uc3Qgc3RlcEZuID0gZ2V0U3RlcEZ1bmN0aW9uKHN0ZXBJZCk7XG4gICAgICBpZiAoIXN0ZXBGbikge1xuICAgICAgICB0aHJvdyBuZXcgU2VyaWFsaXphdGlvbkVycm9yKFxuICAgICAgICAgIGBTdGVwIGZ1bmN0aW9uIFwiJHtzdGVwSWR9XCIgbm90IGZvdW5kLiBNYWtlIHN1cmUgdGhlIHN0ZXAgZnVuY3Rpb24gaXMgcmVnaXN0ZXJlZC5gLFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGhpbnQ6ICdNYWtlIHN1cmUgdGhlIHN0ZXAgZmlsZSBpcyBpbmNsdWRlZCBpbiB5b3VyIGJ1aWxkIChpLmUuIGl0IGlzIGxpc3RlZCBpbiB0aGUgd29ya2Zsb3cgbWFuaWZlc3QpLCBhbmQgdGhhdCB0aGUgU1dDIHBsdWdpbiBpcyBjb25maWd1cmVkIGZvciB0aGUgZmlsZS4nLFxuICAgICAgICAgIH1cbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgLy8gRmFzdCBwYXRoOiBub3RoaW5nIHRvIHdyYXAuXG4gICAgICBpZiAoIWNsb3N1cmVWYXJzICYmICFoYXNCb3VuZFRoaXMgJiYgYm91bmRBcmdzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICByZXR1cm4gc3RlcEZuO1xuICAgICAgfVxuXG4gICAgICBjb25zdCB3cmFwcGVkU3RlcEZuID0gZnVuY3Rpb24gKHRoaXM6IHVua25vd24sIC4uLmFyZ3M6IGFueVtdKSB7XG4gICAgICAgIGNvbnN0IGNhbGxUaGlzID0gaGFzQm91bmRUaGlzID8gYm91bmRUaGlzIDogdGhpcztcbiAgICAgICAgY29uc3QgY2FsbEFyZ3MgPSBib3VuZEFyZ3MubGVuZ3RoID4gMCA/IFsuLi5ib3VuZEFyZ3MsIC4uLmFyZ3NdIDogYXJncztcbiAgICAgICAgaWYgKGNsb3N1cmVWYXJzKSB7XG4gICAgICAgICAgY29uc3QgY3VycmVudENvbnRleHQgPSBjb250ZXh0U3RvcmFnZS5nZXRTdG9yZSgpO1xuICAgICAgICAgIGlmICghY3VycmVudENvbnRleHQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBXb3JrZmxvd1J1bnRpbWVFcnJvcihcbiAgICAgICAgICAgICAgJ0Nhbm5vdCBjYWxsIHN0ZXAgZnVuY3Rpb24gd2l0aCBjbG9zdXJlIHZhcmlhYmxlcyBvdXRzaWRlIHN0ZXAgY29udGV4dCdcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnN0IG5ld0NvbnRleHQgPSB7XG4gICAgICAgICAgICAuLi5jdXJyZW50Q29udGV4dCxcbiAgICAgICAgICAgIGNsb3N1cmVWYXJzLFxuICAgICAgICAgIH07XG4gICAgICAgICAgcmV0dXJuIGNvbnRleHRTdG9yYWdlLnJ1bihuZXdDb250ZXh0LCAoKSA9PlxuICAgICAgICAgICAgc3RlcEZuLmFwcGx5KGNhbGxUaGlzLCBjYWxsQXJncylcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBzdGVwRm4uYXBwbHkoY2FsbFRoaXMsIGNhbGxBcmdzKTtcbiAgICAgIH0gYXMgYW55O1xuXG4gICAgICAvLyBDb3B5IHByb3BlcnRpZXMgZnJvbSBvcmlnaW5hbCBzdGVwIGZ1bmN0aW9uXG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkod3JhcHBlZFN0ZXBGbiwgJ25hbWUnLCB7XG4gICAgICAgIHZhbHVlOiBzdGVwRm4ubmFtZSxcbiAgICAgIH0pO1xuICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHdyYXBwZWRTdGVwRm4sICdzdGVwSWQnLCB7XG4gICAgICAgIHZhbHVlOiBzdGVwSWQsXG4gICAgICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogZmFsc2UsXG4gICAgICB9KTtcbiAgICAgIGlmIChzdGVwRm4ubWF4UmV0cmllcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHdyYXBwZWRTdGVwRm4ubWF4UmV0cmllcyA9IHN0ZXBGbi5tYXhSZXRyaWVzO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gd3JhcHBlZFN0ZXBGbjtcbiAgICB9LFxuXG4gICAgV29ya2Zsb3dGdW5jdGlvbjogKHZhbHVlKSA9PlxuICAgICAgT2JqZWN0LmFzc2lnbihcbiAgICAgICAgKCkgPT4ge1xuICAgICAgICAgIHRocm93IG5ldyBTZXJpYWxpemF0aW9uRXJyb3IoXG4gICAgICAgICAgICAnV29ya2Zsb3cgZnVuY3Rpb25zIGNhbm5vdCBiZSBjYWxsZWQgZGlyZWN0bHkuIFVzZSBzdGFydCgpIHRvIGludm9rZSB0aGVtLicsXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGhpbnQ6ICdXcmFwIHRoZSB3b3JrZmxvdyB3aXRoIGBzdGFydCh3b3JrZmxvd0ZuLCB7IC4uLiB9KWAgZnJvbSBgd29ya2Zsb3dgIHRvIGJlZ2luIGEgcnVuIGluc3RlYWQgb2YgaW52b2tpbmcgaXQgbGlrZSBhIG5vcm1hbCBmdW5jdGlvbi4nLFxuICAgICAgICAgICAgfVxuICAgICAgICAgICk7XG4gICAgICAgIH0sXG4gICAgICAgIHsgd29ya2Zsb3dJZDogdmFsdWUud29ya2Zsb3dJZCB9XG4gICAgICApLFxuXG4gICAgUmVxdWVzdDogKHZhbHVlKSA9PiB7XG4gICAgICBjb25zdCByZXNwb25zZVdyaXRhYmxlID0gdmFsdWUucmVzcG9uc2VXcml0YWJsZTtcbiAgICAgIGNvbnN0IGluaXQ6IFJlcXVlc3RJbml0ICYgeyBkdXBsZXg/OiBzdHJpbmcgfSA9IHtcbiAgICAgICAgbWV0aG9kOiB2YWx1ZS5tZXRob2QsXG4gICAgICAgIGhlYWRlcnM6IG5ldyBnbG9iYWwuSGVhZGVycyh2YWx1ZS5oZWFkZXJzKSxcbiAgICAgICAgYm9keTogdmFsdWUuYm9keSxcbiAgICAgICAgZHVwbGV4OiB2YWx1ZS5kdXBsZXgsXG4gICAgICB9O1xuICAgICAgaWYgKHZhbHVlLnNpZ25hbCkgaW5pdC5zaWduYWwgPSB2YWx1ZS5zaWduYWw7XG4gICAgICBjb25zdCByZXF1ZXN0ID0gbmV3IGdsb2JhbC5SZXF1ZXN0KHZhbHVlLnVybCwgaW5pdCk7XG4gICAgICAvLyBUaGUgUmVxdWVzdCBjb25zdHJ1Y3RvciBjcmVhdGVzIGFuIGludGVybmFsIHNpZ25hbCBjb3B5LCBzbyB0aGVcbiAgICAgIC8vIGFib3J0LWludGVybmFsIHN5bWJvbHMgc2V0IGJ5IHJldml2ZUFib3J0U2lnbmFsIGRvbid0IHByb3BhZ2F0ZS5cbiAgICAgIC8vIFJlLXRhZyB0aGUgcmVxdWVzdCdzIG93biBzaWduYWwgc28gY2FuY2VsQWJvcnRSZWFkZXJzIGNhbiBmaW5kIGl0LlxuICAgICAgaWYgKHZhbHVlLnNpZ25hbCkgY29weUFib3J0SW50ZXJuYWxzKHZhbHVlLnNpZ25hbCwgcmVxdWVzdC5zaWduYWwpO1xuICAgICAgaWYgKHJlc3BvbnNlV3JpdGFibGUpIHtcbiAgICAgICAgcmVxdWVzdC5yZXNwb25kV2l0aCA9IGFzeW5jIChyZXNwb25zZTogUmVzcG9uc2UpID0+IHtcbiAgICAgICAgICBjb25zdCB3cml0ZXIgPSByZXNwb25zZVdyaXRhYmxlLmdldFdyaXRlcigpO1xuICAgICAgICAgIGF3YWl0IHdyaXRlci53cml0ZShyZXNwb25zZSk7XG4gICAgICAgICAgYXdhaXQgd3JpdGVyLmNsb3NlKCk7XG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVxdWVzdDtcbiAgICB9LFxuICAgIFJlc3BvbnNlOiAodmFsdWUpID0+IHtcbiAgICAgIC8vIE5vdGU6IFJlc3BvbnNlIGNvbnN0cnVjdG9yIG9ubHkgYWNjZXB0cyBzdGF0dXMsIHN0YXR1c1RleHQsIGFuZCBoZWFkZXJzXG4gICAgICAvLyBUaGUgdHlwZSwgdXJsLCBhbmQgcmVkaXJlY3RlZCBwcm9wZXJ0aWVzIGFyZSByZWFkLW9ubHkgYW5kIHNldCBieSB0aGUgY29uc3RydWN0b3JcbiAgICAgIHJldHVybiBuZXcgZ2xvYmFsLlJlc3BvbnNlKHZhbHVlLmJvZHksIHtcbiAgICAgICAgc3RhdHVzOiB2YWx1ZS5zdGF0dXMsXG4gICAgICAgIHN0YXR1c1RleHQ6IHZhbHVlLnN0YXR1c1RleHQsXG4gICAgICAgIGhlYWRlcnM6IG5ldyBnbG9iYWwuSGVhZGVycyh2YWx1ZS5oZWFkZXJzKSxcbiAgICAgIH0pO1xuICAgIH0sXG4gICAgUmVhZGFibGVTdHJlYW06ICh2YWx1ZSkgPT4ge1xuICAgICAgLy8gSWYgdGhpcyBoYXMgYm9keUluaXQsIGl0IGNhbWUgZnJvbSBhIFJlc3BvbnNlIGNvbnN0cnVjdG9yXG4gICAgICAvLyBDb252ZXJ0IGl0IHRvIGEgUkVBTCBzdHJlYW0gbm93IHRoYXQgd2UncmUgaW4gdGhlIHN0ZXAgZW52aXJvbm1lbnRcbiAgICAgIGlmICgnYm9keUluaXQnIGluIHZhbHVlKSB7XG4gICAgICAgIGNvbnN0IGJvZHlJbml0ID0gdmFsdWUuYm9keUluaXQ7XG4gICAgICAgIC8vIFVzZSB0aGUgbmF0aXZlIFJlc3BvbnNlIGNvbnN0cnVjdG9yIHRvIHByb3Blcmx5IGNvbnZlcnQgQm9keUluaXQgdG8gUmVhZGFibGVTdHJlYW1cbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBuZXcgZ2xvYmFsLlJlc3BvbnNlKGJvZHlJbml0KTtcbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlLmJvZHk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHJlYWRhYmxlID0gbmV3IFdvcmtmbG93U2VydmVyUmVhZGFibGVTdHJlYW0ocnVuSWQsIHZhbHVlLm5hbWUpO1xuICAgICAgaWYgKHZhbHVlLnR5cGUgPT09ICdieXRlcycpIHtcbiAgICAgICAgLy8gRm9yIGJ5dGUgc3RyZWFtcywgdXNlIGZsdXNoYWJsZSBwaXBlIHdpdGggbG9jayBwb2xsaW5nXG4gICAgICAgIGNvbnN0IHN0YXRlID0gY3JlYXRlRmx1c2hhYmxlU3RhdGUoKTtcbiAgICAgICAgb3BzLnB1c2goc3RhdGUucHJvbWlzZSk7XG5cbiAgICAgICAgLy8gQ3JlYXRlIGFuIGlkZW50aXR5IHRyYW5zZm9ybSB0byBnaXZlIHRoZSB1c2VyIGEgcmVhZGFibGVcbiAgICAgICAgY29uc3QgeyByZWFkYWJsZTogdXNlclJlYWRhYmxlLCB3cml0YWJsZSB9ID1cbiAgICAgICAgICBuZXcgZ2xvYmFsLlRyYW5zZm9ybVN0cmVhbSgpO1xuXG4gICAgICAgIC8vIFN0YXJ0IHRoZSBmbHVzaGFibGUgcGlwZSBpbiB0aGUgYmFja2dyb3VuZFxuICAgICAgICBmbHVzaGFibGVQaXBlKHJlYWRhYmxlLCB3cml0YWJsZSwgc3RhdGUpLmNhdGNoKCgpID0+IHtcbiAgICAgICAgICAvLyBFcnJvcnMgYXJlIGhhbmRsZWQgdmlhIHN0YXRlLnJlamVjdFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBTdGFydCBwb2xsaW5nIHRvIGRldGVjdCB3aGVuIHVzZXIgcmVsZWFzZXMgbG9ja1xuICAgICAgICBwb2xsUmVhZGFibGVMb2NrKHVzZXJSZWFkYWJsZSwgc3RhdGUpO1xuXG4gICAgICAgIHJldHVybiB1c2VyUmVhZGFibGU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCB0cmFuc2Zvcm0gPSBnZXREZXNlcmlhbGl6ZVN0cmVhbShcbiAgICAgICAgICBnZXRTdGVwUmV2aXZlcnMoZ2xvYmFsLCBvcHMsIHJ1bklkLCBjcnlwdG9LZXksIGRlcGxveW1lbnRJZCksXG4gICAgICAgICAgY3J5cHRvS2V5XG4gICAgICAgICk7XG4gICAgICAgIGNvbnN0IHN0YXRlID0gY3JlYXRlRmx1c2hhYmxlU3RhdGUoKTtcbiAgICAgICAgb3BzLnB1c2goc3RhdGUucHJvbWlzZSk7XG5cbiAgICAgICAgLy8gU3RhcnQgdGhlIGZsdXNoYWJsZSBwaXBlIGluIHRoZSBiYWNrZ3JvdW5kXG4gICAgICAgIGZsdXNoYWJsZVBpcGUocmVhZGFibGUsIHRyYW5zZm9ybS53cml0YWJsZSwgc3RhdGUpLmNhdGNoKCgpID0+IHtcbiAgICAgICAgICAvLyBFcnJvcnMgYXJlIGhhbmRsZWQgdmlhIHN0YXRlLnJlamVjdFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBTdGFydCBwb2xsaW5nIHRvIGRldGVjdCB3aGVuIHVzZXIgcmVsZWFzZXMgbG9ja1xuICAgICAgICBwb2xsUmVhZGFibGVMb2NrKHRyYW5zZm9ybS5yZWFkYWJsZSwgc3RhdGUpO1xuXG4gICAgICAgIHJldHVybiB0cmFuc2Zvcm0ucmVhZGFibGU7XG4gICAgICB9XG4gICAgfSxcbiAgICBXcml0YWJsZVN0cmVhbTogKHZhbHVlKSA9PiB7XG4gICAgICAvLyBTYW1lLXJ1biBjYXNlOiB0aGUgd3JpdGFibGUgYmVsb25ncyB0byB0aGUgY3VycmVudCBydW4uIFVzZSB0aGVcbiAgICAgIC8vIGxvY2FsIGNyeXB0b0tleSBhbmQgd3JpdGUgdG8gdGhlIGxvY2FsIHJ1bklkJ3Mgc2VydmVyIHN0cmVhbS5cbiAgICAgIC8vXG4gICAgICAvLyBDcm9zcy1ydW4gY2FzZSAocGFyZW50IOKGkiBjaGlsZCB2aWEgYHN0YXJ0KClgKTogdGhlIGRlc2NyaXB0b3JcbiAgICAgIC8vIGNhcnJpZXMgdGhlIG9yaWdpbmFsIGBydW5JZGAgYW5kIGBuYW1lYC4gT3BlbiBhIHNlcnZlciB3cml0YWJsZVxuICAgICAgLy8gYWdhaW5zdCB0aGUgb3JpZ2luYWwgYChydW5JZCwgbmFtZSlgIGFuZCByZXNvbHZlIFRIQVQgcnVuJ3Mga2V5XG4gICAgICAvLyBmb3IgZW5jcnlwdGlvbi4gVGhlIHJlc29sdXRpb24gaXMgYXN5bmMgYnV0IGRvZXNuJ3QgbmVlZCB0b1xuICAgICAgLy8gYmxvY2sgcmV2aXZlciByZXR1cm4g4oCUIGBnZXRTZXJpYWxpemVTdHJlYW1gIGFjY2VwdHMgdGhlXG4gICAgICAvLyBgUHJvbWlzZTxDcnlwdG9LZXkgfCB1bmRlZmluZWQ+YCBkaXJlY3RseSBhbmQgYXdhaXRzIGl0IGxhemlseVxuICAgICAgLy8gb24gdGhlIGZpcnN0IGNodW5rIHdyaXR0ZW4uIFRoZSBrZXkgaXMgaW1wb3J0ZWQgZW5jcnlwdC1vbmx5XG4gICAgICAvLyBzbyB0aGUgcmVjZWl2aW5nIHJ1biBjYW4gbmV2ZXIgZGVjcnlwdCBhbnl0aGluZyBlbHNlIG9uIHRoZVxuICAgICAgLy8gb3duaW5nIHJ1bidzIHN0cmVhbSDigJQgaXQgY2FuIG9ubHkgY29udHJpYnV0ZSBuZXcgd3JpdGVzLlxuICAgICAgY29uc3QgdGFyZ2V0UnVuSWQgPSB0eXBlb2YgdmFsdWUucnVuSWQgPT09ICdzdHJpbmcnID8gdmFsdWUucnVuSWQgOiBydW5JZDtcbiAgICAgIGNvbnN0IHRhcmdldERlcGxveW1lbnRJZCA9XG4gICAgICAgIHR5cGVvZiB2YWx1ZS5kZXBsb3ltZW50SWQgPT09ICdzdHJpbmcnXG4gICAgICAgICAgPyB2YWx1ZS5kZXBsb3ltZW50SWRcbiAgICAgICAgICA6IHRhcmdldFJ1bklkID09PSBydW5JZFxuICAgICAgICAgICAgPyBkZXBsb3ltZW50SWRcbiAgICAgICAgICAgIDogdW5kZWZpbmVkO1xuICAgICAgY29uc3QgdGFyZ2V0S2V5OiBFbmNyeXB0aW9uS2V5UGFyYW0gPVxuICAgICAgICB0YXJnZXRSdW5JZCA9PT0gcnVuSWRcbiAgICAgICAgICA/IGNyeXB0b0tleVxuICAgICAgICAgIDogZ2V0Rm9yd2FyZGVkV3JpdGFibGVFbmNyeXB0aW9uS2V5KHRhcmdldFJ1bklkLCB0YXJnZXREZXBsb3ltZW50SWQpO1xuXG4gICAgICBjb25zdCBzZXJpYWxpemUgPSBnZXRTZXJpYWxpemVTdHJlYW0oXG4gICAgICAgIGdldFN0ZXBSZWR1Y2VycyhnbG9iYWwsIG9wcywgdGFyZ2V0UnVuSWQsIHRhcmdldEtleSksXG4gICAgICAgIHRhcmdldEtleVxuICAgICAgKTtcbiAgICAgIGNvbnN0IHNlcnZlcldyaXRhYmxlID0gbmV3IFdvcmtmbG93U2VydmVyV3JpdGFibGVTdHJlYW0oXG4gICAgICAgIHRhcmdldFJ1bklkLFxuICAgICAgICB2YWx1ZS5uYW1lXG4gICAgICApO1xuXG4gICAgICAvLyBDcmVhdGUgZmx1c2hhYmxlIHN0YXRlIGZvciB0aGlzIHN0cmVhbVxuICAgICAgY29uc3Qgc3RhdGUgPSBjcmVhdGVGbHVzaGFibGVTdGF0ZSgpO1xuICAgICAgb3BzLnB1c2goc3RhdGUucHJvbWlzZSk7XG5cbiAgICAgIC8vIFN0YXJ0IHRoZSBmbHVzaGFibGUgcGlwZSBpbiB0aGUgYmFja2dyb3VuZFxuICAgICAgZmx1c2hhYmxlUGlwZShzZXJpYWxpemUucmVhZGFibGUsIHNlcnZlcldyaXRhYmxlLCBzdGF0ZSkuY2F0Y2goKCkgPT4ge1xuICAgICAgICAvLyBFcnJvcnMgYXJlIGhhbmRsZWQgdmlhIHN0YXRlLnJlamVjdFxuICAgICAgfSk7XG5cbiAgICAgIC8vIFN0YXJ0IHBvbGxpbmcgdG8gZGV0ZWN0IHdoZW4gdXNlciByZWxlYXNlcyBsb2NrXG4gICAgICBwb2xsV3JpdGFibGVMb2NrKHNlcmlhbGl6ZS53cml0YWJsZSwgc3RhdGUpO1xuXG4gICAgICAvLyBSZWNvcmQgdGhlIHVuZGVybHlpbmcgYChydW5JZCwgbmFtZSlgIHNvIGRvd25zdHJlYW0gcmVkdWNlcnMgY2FuXG4gICAgICAvLyByZWNvZ25pemUgdGhhdCB0aGlzIHdyaXRhYmxlIGlzIGFscmVhZHkgYmFja2VkIGJ5IGEgd29ya2Zsb3dcbiAgICAgIC8vIHNlcnZlciBzdHJlYW0uIFdoZW4gZm9yd2FyZGVkIGFjcm9zcyBgc3RhcnQoKWAgYWdhaW4g4oCUIGUuZy5cbiAgICAgIC8vIHRoZSBjaGlsZCBwYXNzZXMgdGhpcyB3cml0YWJsZSBvbiB0byBhIGdyYW5kY2hpbGQg4oCUIHRoZVxuICAgICAgLy8gZXh0ZXJuYWwgcmVkdWNlciBuZWVkcyBib3RoIHRvIGVtaXQgdGhlIG9yaWdpbmFsIGBydW5JZGAgaW5cbiAgICAgIC8vIHRoZSBkZXNjcmlwdG9yLlxuICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHNlcmlhbGl6ZS53cml0YWJsZSwgU1RSRUFNX05BTUVfU1lNQk9MLCB7XG4gICAgICAgIHZhbHVlOiB2YWx1ZS5uYW1lLFxuICAgICAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgICB9KTtcbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShzZXJpYWxpemUud3JpdGFibGUsIFNUUkVBTV9TRVJWRVJfUlVOX0lEX1NZTUJPTCwge1xuICAgICAgICB2YWx1ZTogdGFyZ2V0UnVuSWQsXG4gICAgICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICAgIH0pO1xuICAgICAgaWYgKHRhcmdldERlcGxveW1lbnRJZCkge1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoXG4gICAgICAgICAgc2VyaWFsaXplLndyaXRhYmxlLFxuICAgICAgICAgIFNUUkVBTV9TRVJWRVJfREVQTE9ZTUVOVF9JRF9TWU1CT0wsXG4gICAgICAgICAge1xuICAgICAgICAgICAgdmFsdWU6IHRhcmdldERlcGxveW1lbnRJZCxcbiAgICAgICAgICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBzZXJpYWxpemUud3JpdGFibGU7XG4gICAgfSxcblxuICAgIEFib3J0Q29udHJvbGxlcjogKHZhbHVlKSA9PiByZXZpdmVBYm9ydENvbnRyb2xsZXIodmFsdWUsIG9wcywgcnVuSWQpLFxuICAgIEFib3J0U2lnbmFsOiAodmFsdWUpID0+IHJldml2ZUFib3J0U2lnbmFsKHZhbHVlLCBvcHMsIHJ1bklkKSxcbiAgfTtcbn1cblxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy8gRW5jcnlwdGlvbiBIZWxwZXJzXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vLyBUaGVzZSBkZWxlZ2F0ZSB0byB0aGUgbW9kdWxhciBgZW5jcnlwdGAvYGRlY3J5cHRgIGZyb20gYC4vc2VyaWFsaXphdGlvbi9lbmNyeXB0aW9uLmpzYFxuLy8gYnV0IGFyZSBrZXB0IGFzIG5hbWVkIGV4cG9ydHMgZm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5IHdpdGggZXhpc3RpbmcgY29uc3VtZXJzLlxuXG4vKipcbiAqIEVuY3J5cHQgZGF0YSBpZiB0aGUgd29ybGQgc3VwcG9ydHMgZW5jcnlwdGlvbi5cbiAqIFJldHVybnMgb3JpZ2luYWwgZGF0YSBpZiBlbmNyeXB0aW9uIGlzIG5vdCBhdmFpbGFibGUuXG4gKlxuICogQGRlcHJlY2F0ZWQgVXNlIGBlbmNyeXB0YCBmcm9tIGAuL3NlcmlhbGl6YXRpb24vZW5jcnlwdGlvbi5qc2AgaW5zdGVhZC5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIG1heWJlRW5jcnlwdChcbiAgZGF0YTogVWludDhBcnJheSxcbiAga2V5OiBDcnlwdG9LZXkgfCB1bmRlZmluZWRcbik6IFByb21pc2U8VWludDhBcnJheT4ge1xuICByZXR1cm4gKGF3YWl0IGVuY3J5cHQoZGF0YSwga2V5KSkgYXMgVWludDhBcnJheTtcbn1cblxuLyoqXG4gKiBEZWNyeXB0IGRhdGEgaWYgaXQgaGFzIHRoZSAnZW5jcicgcHJlZml4LlxuICpcbiAqIEBkZXByZWNhdGVkIFVzZSBgZGVjcnlwdGAgZnJvbSBgLi9zZXJpYWxpemF0aW9uL2VuY3J5cHRpb24uanNgIGluc3RlYWQuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBtYXliZURlY3J5cHQoXG4gIGRhdGE6IFVpbnQ4QXJyYXkgfCB1bmtub3duLFxuICBrZXk6IENyeXB0b0tleSB8IHVuZGVmaW5lZFxuKTogUHJvbWlzZTxVaW50OEFycmF5IHwgdW5rbm93bj4ge1xuICByZXR1cm4gZGVjcnlwdChkYXRhLCBrZXkpO1xufVxuXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vLyBEZWh5ZHJhdGUgLyBIeWRyYXRlIEZ1bmN0aW9uc1xuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy8gVGhlc2UgZGVsZWdhdGUgdG8gdGhlIG1vZHVsYXIgbW9kZSBtb2R1bGVzICh3b3JrZmxvdywgc3RlcCwgY2xpZW50KSBwYXNzaW5nXG4vLyBtb2RlLXNwZWNpZmljIHN0cmVhbSBhbmQgUmVxdWVzdC9SZXNwb25zZSByZWR1Y2Vycy9yZXZpdmVycyBhcyBleHRyYSBvcHRpb25zLlxuLy8gVGhlIHYxQ29tcGF0IHBhdGggaXMgaGFuZGxlZCBpbmxpbmUgYmVmb3JlIGRlbGVnYXRpbmcgdG8gdGhlIG1vZHVsZXMuXG5cbi8qKlxuICogQ2FsbGVkIGZyb20gdGhlIGBzdGFydCgpYCBmdW5jdGlvbiB0byBzZXJpYWxpemUgdGhlIHdvcmtmbG93IGFyZ3VtZW50c1xuICogaW50byBhIGZvcm1hdCB0aGF0IGNhbiBiZSBzYXZlZCB0byB0aGUgZGF0YWJhc2UgYW5kIHRoZW4gaHlkcmF0ZWQgZnJvbVxuICogd2l0aGluIHRoZSB3b3JrZmxvdyBleGVjdXRpb24gZW52aXJvbm1lbnQuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBkZWh5ZHJhdGVXb3JrZmxvd0FyZ3VtZW50cyhcbiAgdmFsdWU6IHVua25vd24sXG4gIHJ1bklkOiBzdHJpbmcsXG4gIGtleTogQ3J5cHRvS2V5IHwgdW5kZWZpbmVkLFxuICBvcHM6IFByb21pc2U8dm9pZD5bXSA9IFtdLFxuICBnbG9iYWw6IFJlY29yZDxzdHJpbmcsIGFueT4gPSBnbG9iYWxUaGlzLFxuICB2MUNvbXBhdCA9IGZhbHNlXG4pOiBQcm9taXNlPFVpbnQ4QXJyYXkgfCB1bmtub3duPiB7XG4gIGlmICh2MUNvbXBhdCkge1xuICAgIGNvbnN0IHN0ciA9IHN0cmluZ2lmeSh2YWx1ZSwgZ2V0RXh0ZXJuYWxSZWR1Y2VycyhnbG9iYWwsIG9wcywgcnVuSWQsIGtleSkpO1xuICAgIHJldHVybiByZXZpdmUoc3RyKTtcbiAgfVxuICB0cnkge1xuICAgIHJldHVybiBhd2FpdCBjbGllbnRNb2R1bGUuc2VyaWFsaXplKHZhbHVlLCBrZXksIHtcbiAgICAgIGdsb2JhbCxcbiAgICAgIGV4dHJhUmVkdWNlcnM6IGdldFN0cmVhbUFuZFJlcXVlc3RSZWR1Y2VycyhcbiAgICAgICAgZ2V0RXh0ZXJuYWxSZWR1Y2VycyhnbG9iYWwsIG9wcywgcnVuSWQsIGtleSlcbiAgICAgICksXG4gICAgfSk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgY29uc3QgY2F1c2UgPSB1bndyYXBTZXJpYWxpemF0aW9uQ2F1c2UoZXJyb3IpO1xuICAgIGNvbnN0IHsgbWVzc2FnZSwgaGludCB9ID0gZm9ybWF0U2VyaWFsaXphdGlvbkVycm9yKFxuICAgICAgJ3dvcmtmbG93IGFyZ3VtZW50cycsXG4gICAgICBjYXVzZVxuICAgICk7XG4gICAgdGhyb3cgbmV3IFNlcmlhbGl6YXRpb25FcnJvcihtZXNzYWdlLCB7IGhpbnQsIGNhdXNlIH0pO1xuICB9XG59XG5cbi8qKlxuICogQ2FsbGVkIGZyb20gd29ya2Zsb3cgZXhlY3V0aW9uIGVudmlyb25tZW50IHRvIGh5ZHJhdGUgdGhlIHdvcmtmbG93XG4gKiBhcmd1bWVudHMgZnJvbSB0aGUgZGF0YWJhc2UgYXQgdGhlIHN0YXJ0IG9mIHdvcmtmbG93IGV4ZWN1dGlvbi5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGh5ZHJhdGVXb3JrZmxvd0FyZ3VtZW50cyhcbiAgdmFsdWU6IFVpbnQ4QXJyYXkgfCB1bmtub3duLFxuICBfcnVuSWQ6IHN0cmluZyxcbiAga2V5OiBDcnlwdG9LZXkgfCB1bmRlZmluZWQsXG4gIGdsb2JhbDogUmVjb3JkPHN0cmluZywgYW55PiA9IGdsb2JhbFRoaXMsXG4gIGV4dHJhUmV2aXZlcnM6IFJlY29yZDxzdHJpbmcsICh2YWx1ZTogYW55KSA9PiBhbnk+ID0ge31cbik6IFByb21pc2U8YW55PiB7XG4gIHJldHVybiB3b3JrZmxvd01vZHVsZS5kZXNlcmlhbGl6ZShhd2FpdCBtYXliZURlY3J5cHQodmFsdWUsIGtleSksIHtcbiAgICBnbG9iYWwsXG4gICAgZXh0cmFSZXZpdmVyczoge1xuICAgICAgLi4uZ2V0U3RyZWFtQW5kUmVxdWVzdFJldml2ZXJzKGdldFdvcmtmbG93UmV2aXZlcnMoZ2xvYmFsKSksXG4gICAgICAuLi5leHRyYVJldml2ZXJzLFxuICAgIH0sXG4gIH0pO1xufVxuXG4vKipcbiAqIERlaHlkcmF0ZSB3b3JrZmxvdyByZXR1cm4gdmFsdWUgZm9yIHN0b3JhZ2UuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBkZWh5ZHJhdGVXb3JrZmxvd1JldHVyblZhbHVlKFxuICB2YWx1ZTogdW5rbm93bixcbiAgX3J1bklkOiBzdHJpbmcsXG4gIGtleTogQ3J5cHRvS2V5IHwgdW5kZWZpbmVkLFxuICBnbG9iYWw6IFJlY29yZDxzdHJpbmcsIGFueT4gPSBnbG9iYWxUaGlzLFxuICB2MUNvbXBhdCA9IGZhbHNlXG4pOiBQcm9taXNlPFVpbnQ4QXJyYXkgfCB1bmtub3duPiB7XG4gIGlmICh2MUNvbXBhdCkge1xuICAgIGNvbnN0IHN0ciA9IHN0cmluZ2lmeSh2YWx1ZSwgZ2V0V29ya2Zsb3dSZWR1Y2VycyhnbG9iYWwpKTtcbiAgICByZXR1cm4gcmV2aXZlKHN0cik7XG4gIH1cbiAgdHJ5IHtcbiAgICByZXR1cm4gYXdhaXQgc3RlcE1vZHVsZS5zZXJpYWxpemUodmFsdWUsIGtleSwge1xuICAgICAgZ2xvYmFsLFxuICAgICAgZXh0cmFSZWR1Y2VyczogZ2V0U3RyZWFtQW5kUmVxdWVzdFJlZHVjZXJzKGdldFdvcmtmbG93UmVkdWNlcnMoZ2xvYmFsKSksXG4gICAgfSk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgY29uc3QgY2F1c2UgPSB1bndyYXBTZXJpYWxpemF0aW9uQ2F1c2UoZXJyb3IpO1xuICAgIGNvbnN0IHsgbWVzc2FnZSwgaGludCB9ID0gZm9ybWF0U2VyaWFsaXphdGlvbkVycm9yKFxuICAgICAgJ3dvcmtmbG93IHJldHVybiB2YWx1ZScsXG4gICAgICBjYXVzZVxuICAgICk7XG4gICAgdGhyb3cgbmV3IFNlcmlhbGl6YXRpb25FcnJvcihtZXNzYWdlLCB7IGhpbnQsIGNhdXNlIH0pO1xuICB9XG59XG5cbi8qKlxuICogQ2FsbGVkIGZyb20gdGhlIGNsaWVudCBzaWRlIHRvIGh5ZHJhdGUgdGhlIHdvcmtmbG93IHJldHVybiB2YWx1ZVxuICogb2YgYSBjb21wbGV0ZWQgd29ya2Zsb3cgcnVuLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gaHlkcmF0ZVdvcmtmbG93UmV0dXJuVmFsdWUoXG4gIHZhbHVlOiBVaW50OEFycmF5IHwgdW5rbm93bixcbiAgcnVuSWQ6IHN0cmluZyxcbiAga2V5OiBDcnlwdG9LZXkgfCB1bmRlZmluZWQsXG4gIG9wczogUHJvbWlzZTx2b2lkPltdID0gW10sXG4gIGdsb2JhbDogUmVjb3JkPHN0cmluZywgYW55PiA9IGdsb2JhbFRoaXMsXG4gIGV4dHJhUmV2aXZlcnM6IFJlY29yZDxzdHJpbmcsICh2YWx1ZTogYW55KSA9PiBhbnk+ID0ge31cbik6IFByb21pc2U8YW55PiB7XG4gIHJldHVybiBjbGllbnRNb2R1bGUuZGVzZXJpYWxpemUodmFsdWUsIGtleSwge1xuICAgIGdsb2JhbCxcbiAgICBleHRyYVJldml2ZXJzOiB7XG4gICAgICAuLi5nZXRTdHJlYW1BbmRSZXF1ZXN0UmV2aXZlcnMoXG4gICAgICAgIGdldEV4dGVybmFsUmV2aXZlcnMoZ2xvYmFsLCBvcHMsIHJ1bklkLCBrZXkpXG4gICAgICApLFxuICAgICAgLi4uZXh0cmFSZXZpdmVycyxcbiAgICB9LFxuICB9KTtcbn1cblxuLyoqXG4gKiBDYWxsZWQgZnJvbSB0aGUgd29ya2Zsb3cgaGFuZGxlciB3aGVuIGEgc3RlcCBpcyBiZWluZyBjcmVhdGVkLlxuICogRGVoeWRyYXRlcyB2YWx1ZXMgZnJvbSB3aXRoaW4gdGhlIHdvcmtmbG93IGV4ZWN1dGlvbiBlbnZpcm9ubWVudC5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGRlaHlkcmF0ZVN0ZXBBcmd1bWVudHMoXG4gIHZhbHVlOiB1bmtub3duLFxuICBfcnVuSWQ6IHN0cmluZyxcbiAga2V5OiBDcnlwdG9LZXkgfCB1bmRlZmluZWQsXG4gIGdsb2JhbDogUmVjb3JkPHN0cmluZywgYW55PiA9IGdsb2JhbFRoaXMsXG4gIHYxQ29tcGF0ID0gZmFsc2Vcbik6IFByb21pc2U8VWludDhBcnJheSB8IHVua25vd24+IHtcbiAgaWYgKHYxQ29tcGF0KSB7XG4gICAgY29uc3Qgc3RyID0gc3RyaW5naWZ5KHZhbHVlLCBnZXRXb3JrZmxvd1JlZHVjZXJzKGdsb2JhbCkpO1xuICAgIHJldHVybiByZXZpdmUoc3RyKTtcbiAgfVxuICB0cnkge1xuICAgIHJldHVybiBhd2FpdCBzdGVwTW9kdWxlLnNlcmlhbGl6ZSh2YWx1ZSwga2V5LCB7XG4gICAgICBnbG9iYWwsXG4gICAgICBleHRyYVJlZHVjZXJzOiBnZXRTdHJlYW1BbmRSZXF1ZXN0UmVkdWNlcnMoZ2V0V29ya2Zsb3dSZWR1Y2VycyhnbG9iYWwpKSxcbiAgICB9KTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBjb25zdCBjYXVzZSA9IHVud3JhcFNlcmlhbGl6YXRpb25DYXVzZShlcnJvcik7XG4gICAgY29uc3QgeyBtZXNzYWdlLCBoaW50IH0gPSBmb3JtYXRTZXJpYWxpemF0aW9uRXJyb3IoJ3N0ZXAgYXJndW1lbnRzJywgY2F1c2UpO1xuICAgIHRocm93IG5ldyBTZXJpYWxpemF0aW9uRXJyb3IobWVzc2FnZSwgeyBoaW50LCBjYXVzZSB9KTtcbiAgfVxufVxuXG4vKipcbiAqIENhbGxlZCBmcm9tIHRoZSBzdGVwIGhhbmRsZXIgdG8gaHlkcmF0ZSB0aGUgYXJndW1lbnRzIG9mIGEgc3RlcFxuICogZnJvbSB0aGUgZGF0YWJhc2UgYXQgdGhlIHN0YXJ0IG9mIHRoZSBzdGVwIGV4ZWN1dGlvbi5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGh5ZHJhdGVTdGVwQXJndW1lbnRzKFxuICB2YWx1ZTogVWludDhBcnJheSB8IHVua25vd24sXG4gIHJ1bklkOiBzdHJpbmcsXG4gIGtleTogQ3J5cHRvS2V5IHwgdW5kZWZpbmVkLFxuICBvcHM6IFByb21pc2U8YW55PltdID0gW10sXG4gIGdsb2JhbDogUmVjb3JkPHN0cmluZywgYW55PiA9IGdsb2JhbFRoaXMsXG4gIGV4dHJhUmV2aXZlcnM6IFJlY29yZDxzdHJpbmcsICh2YWx1ZTogYW55KSA9PiBhbnk+ID0ge30sXG4gIGRlcGxveW1lbnRJZD86IHN0cmluZ1xuKTogUHJvbWlzZTxhbnk+IHtcbiAgcmV0dXJuIHN0ZXBNb2R1bGUuZGVzZXJpYWxpemUodmFsdWUsIGtleSwge1xuICAgIGdsb2JhbCxcbiAgICBleHRyYVJldml2ZXJzOiB7XG4gICAgICAuLi5nZXRTdHJlYW1BbmRSZXF1ZXN0UmV2aXZlcnMoXG4gICAgICAgIGdldFN0ZXBSZXZpdmVycyhnbG9iYWwsIG9wcywgcnVuSWQsIGtleSwgZGVwbG95bWVudElkKVxuICAgICAgKSxcbiAgICAgIC4uLmV4dHJhUmV2aXZlcnMsXG4gICAgfSxcbiAgfSk7XG59XG5cbi8qKlxuICogQ2FsbGVkIGZyb20gdGhlIHN0ZXAgaGFuZGxlciB3aGVuIGEgc3RlcCBoYXMgY29tcGxldGVkLlxuICogRGVoeWRyYXRlcyB2YWx1ZXMgZnJvbSB3aXRoaW4gdGhlIHN0ZXAgZXhlY3V0aW9uIGVudmlyb25tZW50LlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZGVoeWRyYXRlU3RlcFJldHVyblZhbHVlKFxuICB2YWx1ZTogdW5rbm93bixcbiAgcnVuSWQ6IHN0cmluZyxcbiAga2V5OiBDcnlwdG9LZXkgfCB1bmRlZmluZWQsXG4gIG9wczogUHJvbWlzZTxhbnk+W10gPSBbXSxcbiAgZ2xvYmFsOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0gZ2xvYmFsVGhpcyxcbiAgdjFDb21wYXQgPSBmYWxzZVxuKTogUHJvbWlzZTxVaW50OEFycmF5IHwgdW5rbm93bj4ge1xuICBpZiAodjFDb21wYXQpIHtcbiAgICBjb25zdCBzdHIgPSBzdHJpbmdpZnkodmFsdWUsIGdldFN0ZXBSZWR1Y2VycyhnbG9iYWwsIG9wcywgcnVuSWQsIGtleSkpO1xuICAgIHJldHVybiByZXZpdmUoc3RyKTtcbiAgfVxuICB0cnkge1xuICAgIHJldHVybiBhd2FpdCBzdGVwTW9kdWxlLnNlcmlhbGl6ZSh2YWx1ZSwga2V5LCB7XG4gICAgICBnbG9iYWwsXG4gICAgICBleHRyYVJlZHVjZXJzOiBnZXRTdHJlYW1BbmRSZXF1ZXN0UmVkdWNlcnMoXG4gICAgICAgIGdldFN0ZXBSZWR1Y2VycyhnbG9iYWwsIG9wcywgcnVuSWQsIGtleSlcbiAgICAgICksXG4gICAgfSk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgY29uc3QgY2F1c2UgPSB1bndyYXBTZXJpYWxpemF0aW9uQ2F1c2UoZXJyb3IpO1xuICAgIGNvbnN0IHsgbWVzc2FnZSwgaGludCB9ID0gZm9ybWF0U2VyaWFsaXphdGlvbkVycm9yKFxuICAgICAgJ3N0ZXAgcmV0dXJuIHZhbHVlJyxcbiAgICAgIGNhdXNlXG4gICAgKTtcbiAgICB0aHJvdyBuZXcgU2VyaWFsaXphdGlvbkVycm9yKG1lc3NhZ2UsIHsgaGludCwgY2F1c2UgfSk7XG4gIH1cbn1cblxuLyoqXG4gKiBDYWxsZWQgZnJvbSB0aGUgc3RlcCBoYW5kbGVyIHdoZW4gYSBzdGVwIHRocm93cy4gRGVoeWRyYXRlcyB0aGUgdGhyb3duXG4gKiB2YWx1ZSBmcm9tIHdpdGhpbiB0aGUgc3RlcCBleGVjdXRpb24gZW52aXJvbm1lbnQgaW50byBhIGZvcm1hdCB0aGF0IGNhblxuICogYmUgc2F2ZWQgdG8gdGhlIGRhdGFiYXNlIGluIGEgYHN0ZXBfZmFpbGVkYCBvciBgc3RlcF9yZXRyeWluZ2AgZXZlbnQuXG4gKlxuICogQW55IEphdmFTY3JpcHQgdmFsdWUgY2FuIGJlIHRocm93biAoc3RyaW5ncywgbnVtYmVycywgb2JqZWN0cywgRXJyb3JzLFxuICogRXJyb3Igc3ViY2xhc3NlcyksIHNvIHRoZSBzYW1lIHNlcmlhbGl6YXRpb24gcGlwZWxpbmUgdXNlZCBmb3Igc3RlcFxuICogYXJndW1lbnRzIGFuZCByZXR1cm4gdmFsdWVzIGlzIGFwcGxpZWQgaGVyZS5cbiAqXG4gKiBAcGFyYW0gdmFsdWUgLSBUaGUgdGhyb3duIHZhbHVlIHRvIHNlcmlhbGl6ZSAoY2FuIGJlIGFueSB0eXBlKVxuICogQHBhcmFtIHJ1bklkIC0gUnVuIElEIGZvciBlbmNyeXB0aW9uIGNvbnRleHRcbiAqIEBwYXJhbSBrZXkgLSBFbmNyeXB0aW9uIGtleSAodW5kZWZpbmVkIHRvIHNraXAgZW5jcnlwdGlvbilcbiAqIEBwYXJhbSBvcHMgLSBQcm9taXNlIGFycmF5IGZvciBzdHJlYW0gb3BlcmF0aW9uc1xuICogQHBhcmFtIGdsb2JhbCAtIEdsb2JhbCBvYmplY3QgZm9yIHNlcmlhbGl6YXRpb24gY29udGV4dFxuICogQHJldHVybnMgVGhlIGRlaHlkcmF0ZWQgdmFsdWUgYXMgYmluYXJ5IGRhdGEgKFVpbnQ4QXJyYXkpIHdpdGggZm9ybWF0IHByZWZpeFxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZGVoeWRyYXRlU3RlcEVycm9yKFxuICB2YWx1ZTogdW5rbm93bixcbiAgcnVuSWQ6IHN0cmluZyxcbiAga2V5OiBDcnlwdG9LZXkgfCB1bmRlZmluZWQsXG4gIG9wczogUHJvbWlzZTxhbnk+W10gPSBbXSxcbiAgZ2xvYmFsOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0gZ2xvYmFsVGhpc1xuKTogUHJvbWlzZTxVaW50OEFycmF5PiB7XG4gIHRyeSB7XG4gICAgY29uc3Qgc3RyID0gc3RyaW5naWZ5KHZhbHVlLCBnZXRTdGVwUmVkdWNlcnMoZ2xvYmFsLCBvcHMsIHJ1bklkLCBrZXkpKTtcbiAgICBjb25zdCBwYXlsb2FkID0gbmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKHN0cik7XG4gICAgY29uc3Qgc2VyaWFsaXplZCA9IGVuY29kZVdpdGhGb3JtYXRQcmVmaXgoXG4gICAgICBTZXJpYWxpemF0aW9uRm9ybWF0LkRFVkFMVUVfVjEsXG4gICAgICBwYXlsb2FkXG4gICAgKSBhcyBVaW50OEFycmF5O1xuICAgIHJldHVybiAoYXdhaXQgbWF5YmVFbmNyeXB0KHNlcmlhbGl6ZWQsIGtleSkpIGFzIFVpbnQ4QXJyYXk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgY29uc3QgY2F1c2UgPSB1bndyYXBTZXJpYWxpemF0aW9uQ2F1c2UoZXJyb3IpO1xuICAgIGNvbnN0IHsgbWVzc2FnZSwgaGludCB9ID0gZm9ybWF0U2VyaWFsaXphdGlvbkVycm9yKCdzdGVwIGVycm9yJywgY2F1c2UpO1xuICAgIHRocm93IG5ldyBTZXJpYWxpemF0aW9uRXJyb3IobWVzc2FnZSwgeyBoaW50LCBjYXVzZSB9KTtcbiAgfVxufVxuXG4vKipcbiAqIENhbGxlZCBmcm9tIHRoZSB3b3JrZmxvdyBoYW5kbGVyIHdoZW4gcmVwbGF5aW5nIHRoZSBldmVudCBsb2cgb2YgYVxuICogYHN0ZXBfZmFpbGVkYCBvciBgc3RlcF9yZXRyeWluZ2AgZXZlbnQuIEh5ZHJhdGVzIHRoZSB0aHJvd24gdmFsdWUgZnJvbVxuICogdGhlIGRhdGFiYXNlIHNvIHRoZSB3b3JrZmxvdyBjYW4gc2VlIHRoZSBvcmlnaW5hbCB0aHJvd24gdmFsdWUuXG4gKlxuICogQHBhcmFtIHZhbHVlIC0gQmluYXJ5IHNlcmlhbGl6ZWQgZGF0YSAoVWludDhBcnJheSkgd2l0aCBmb3JtYXQgcHJlZml4XG4gKiBAcGFyYW0gcnVuSWQgLSBSdW4gSUQgZm9yIGRlY3J5cHRpb24gY29udGV4dFxuICogQHBhcmFtIGtleSAtIEVuY3J5cHRpb24ga2V5ICh1bmRlZmluZWQgdG8gc2tpcCBkZWNyeXB0aW9uKVxuICogQHBhcmFtIGdsb2JhbCAtIEdsb2JhbCBvYmplY3QgZm9yIGRlc2VyaWFsaXphdGlvbiBjb250ZXh0XG4gKiBAcGFyYW0gZXh0cmFSZXZpdmVycyAtIEFkZGl0aW9uYWwgcmV2aXZlcnMgZm9yIGN1c3RvbSB0eXBlc1xuICogQHJldHVybnMgVGhlIGh5ZHJhdGVkIHRocm93biB2YWx1ZSwgcmVhZHkgdG8gcmVqZWN0IHRoZSBzdGVwIHByb21pc2VcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGh5ZHJhdGVTdGVwRXJyb3IoXG4gIHZhbHVlOiBVaW50OEFycmF5IHwgdW5rbm93bixcbiAgX3J1bklkOiBzdHJpbmcsXG4gIGtleTogQ3J5cHRvS2V5IHwgdW5kZWZpbmVkLFxuICBnbG9iYWw6IFJlY29yZDxzdHJpbmcsIGFueT4gPSBnbG9iYWxUaGlzLFxuICBleHRyYVJldml2ZXJzOiBSZWNvcmQ8c3RyaW5nLCAodmFsdWU6IGFueSkgPT4gYW55PiA9IHt9XG4pOiBQcm9taXNlPHVua25vd24+IHtcbiAgY29uc3QgZGVjcnlwdGVkID0gYXdhaXQgbWF5YmVEZWNyeXB0KHZhbHVlLCBrZXkpO1xuXG4gIGlmICghKGRlY3J5cHRlZCBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpKSB7XG4gICAgLy8gVHJlYXRlZCBhcyBhIGRldmFsdWUgXCJmbGF0dGVuZWRcIiBhcnJheS4gSW4gcHJvZHVjdGlvbiB0aGlzIGJyYW5jaCBpc1xuICAgIC8vIGV4ZXJjaXNlZCBieSBsZWdhY3kgY29kZSBwYXRocyB0aGF0IGJ5cGFzc2VkIGBkZWh5ZHJhdGVTdGVwRXJyb3JgOyB0aGVcbiAgICAvLyBTREsgdmVyc2lvbiBpcyBwaW5uZWQgcGVyIHdvcmtmbG93IHJ1biB2aWEgc2tldyBwcm90ZWN0aW9uLCBzbyBhXG4gICAgLy8gY3VycmVudC12ZXJzaW9uIHByb2R1Y2VyIGFsd2F5cyBlbWl0cyBhIFVpbnQ4QXJyYXkgaGVyZS4gSWYgYVxuICAgIC8vIG1pc3NoYXBlbiB2YWx1ZSByZWFjaGVzIHVzLCBgdW5mbGF0dGVuYCB0aHJvd3Mg4oCUIHRoYXQncyBpbnRlbnRpb25hbDpcbiAgICAvLyB0aGUgaGlnaGVyLWxldmVsIGh5ZHJhdGlvbiBoZWxwZXJzIChgaHlkcmF0ZVN0ZXBJT2AsXG4gICAgLy8gYGh5ZHJhdGVSZXNvdXJjZUlPYCkgYWxyZWFkeSB3cmFwIHVzIGluIGEgdHJ5L2NhdGNoIHRoYXQgbGVhdmVzIHRoZVxuICAgIC8vIGZpZWxkIHVuLWh5ZHJhdGVkIGZvciBvMTF5IGRpc3BsYXksIGFuZCBzdXJmYWNpbmcgdGhlIHRocm93IHRvIGxvZ3NcbiAgICAvLyBpcyBtb3JlIGRlYnVnZ2FibGUgdGhhbiBzaWxlbnRseSBtYXNraW5nIHRoZSB1bnN1cHBvcnRlZCBzaGFwZS5cbiAgICByZXR1cm4gdW5mbGF0dGVuKGRlY3J5cHRlZCBhcyBhbnlbXSwge1xuICAgICAgLi4uZ2V0V29ya2Zsb3dSZXZpdmVycyhnbG9iYWwpLFxuICAgICAgLi4uZXh0cmFSZXZpdmVycyxcbiAgICB9KTtcbiAgfVxuXG4gIGNvbnN0IHsgZm9ybWF0LCBwYXlsb2FkIH0gPSBkZWNvZGVGb3JtYXRQcmVmaXgoZGVjcnlwdGVkKTtcblxuICBpZiAoZm9ybWF0ID09PSBTZXJpYWxpemF0aW9uRm9ybWF0LkRFVkFMVUVfVjEpIHtcbiAgICBjb25zdCBzdHIgPSBuZXcgVGV4dERlY29kZXIoKS5kZWNvZGUocGF5bG9hZCk7XG4gICAgcmV0dXJuIHBhcnNlKHN0ciwge1xuICAgICAgLi4uZ2V0V29ya2Zsb3dSZXZpdmVycyhnbG9iYWwpLFxuICAgICAgLi4uZXh0cmFSZXZpdmVycyxcbiAgICB9KTtcbiAgfVxuXG4gIHRocm93IG5ldyBFcnJvcihgVW5zdXBwb3J0ZWQgc2VyaWFsaXphdGlvbiBmb3JtYXQ6ICR7Zm9ybWF0fWApO1xufVxuXG4vKipcbiAqIENhbGxlZCBmcm9tIHRoZSB3b3JrZmxvdyBoYW5kbGVyIHdoZW4gdGhlIHdvcmtmbG93IGl0c2VsZiB0aHJvd3MuXG4gKiBEZWh5ZHJhdGVzIHRoZSB0aHJvd24gdmFsdWUgZnJvbSB3aXRoaW4gdGhlIHdvcmtmbG93IGV4ZWN1dGlvbiBlbnZpcm9ubWVudFxuICogaW50byBhIGZvcm1hdCB0aGF0IGNhbiBiZSBzYXZlZCB0byB0aGUgZGF0YWJhc2UgaW4gYSBgcnVuX2ZhaWxlZGAgZXZlbnQuXG4gKlxuICogQHBhcmFtIHZhbHVlIC0gVGhlIHRocm93biB2YWx1ZSB0byBzZXJpYWxpemUgKGNhbiBiZSBhbnkgdHlwZSlcbiAqIEBwYXJhbSBydW5JZCAtIFJ1biBJRCBmb3IgZW5jcnlwdGlvbiBjb250ZXh0XG4gKiBAcGFyYW0ga2V5IC0gRW5jcnlwdGlvbiBrZXkgKHVuZGVmaW5lZCB0byBza2lwIGVuY3J5cHRpb24pXG4gKiBAcGFyYW0gZ2xvYmFsIC0gR2xvYmFsIG9iamVjdCBmb3Igc2VyaWFsaXphdGlvbiBjb250ZXh0XG4gKiBAcmV0dXJucyBUaGUgZGVoeWRyYXRlZCB2YWx1ZSBhcyBiaW5hcnkgZGF0YSAoVWludDhBcnJheSkgd2l0aCBmb3JtYXQgcHJlZml4XG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBkZWh5ZHJhdGVSdW5FcnJvcihcbiAgdmFsdWU6IHVua25vd24sXG4gIF9ydW5JZDogc3RyaW5nLFxuICBrZXk6IENyeXB0b0tleSB8IHVuZGVmaW5lZCxcbiAgZ2xvYmFsOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0gZ2xvYmFsVGhpc1xuKTogUHJvbWlzZTxVaW50OEFycmF5PiB7XG4gIHRyeSB7XG4gICAgY29uc3Qgc3RyID0gc3RyaW5naWZ5KHZhbHVlLCBnZXRXb3JrZmxvd1JlZHVjZXJzKGdsb2JhbCkpO1xuICAgIGNvbnN0IHBheWxvYWQgPSBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoc3RyKTtcbiAgICBjb25zdCBzZXJpYWxpemVkID0gZW5jb2RlV2l0aEZvcm1hdFByZWZpeChcbiAgICAgIFNlcmlhbGl6YXRpb25Gb3JtYXQuREVWQUxVRV9WMSxcbiAgICAgIHBheWxvYWRcbiAgICApIGFzIFVpbnQ4QXJyYXk7XG4gICAgcmV0dXJuIChhd2FpdCBtYXliZUVuY3J5cHQoc2VyaWFsaXplZCwga2V5KSkgYXMgVWludDhBcnJheTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBjb25zdCBjYXVzZSA9IHVud3JhcFNlcmlhbGl6YXRpb25DYXVzZShlcnJvcik7XG4gICAgY29uc3QgeyBtZXNzYWdlLCBoaW50IH0gPSBmb3JtYXRTZXJpYWxpemF0aW9uRXJyb3IoJ3J1biBlcnJvcicsIGNhdXNlKTtcbiAgICB0aHJvdyBuZXcgU2VyaWFsaXphdGlvbkVycm9yKG1lc3NhZ2UsIHsgaGludCwgY2F1c2UgfSk7XG4gIH1cbn1cblxuLyoqXG4gKiBDYWxsZWQgZnJvbSB0aGUgY2xpZW50IHNpZGUgKG9yIG9ic2VydmFiaWxpdHkgdG9vbHMpIHRvIGh5ZHJhdGUgdGhlIHJ1blxuICogZXJyb3IgdmFsdWUgb2YgYSBmYWlsZWQgd29ya2Zsb3cgcnVuLlxuICpcbiAqIEBwYXJhbSB2YWx1ZSAtIEJpbmFyeSBzZXJpYWxpemVkIGRhdGEgKFVpbnQ4QXJyYXkpIHdpdGggZm9ybWF0IHByZWZpeFxuICogQHBhcmFtIHJ1bklkIC0gUnVuIElEIGZvciBkZWNyeXB0aW9uIGNvbnRleHRcbiAqIEBwYXJhbSBrZXkgLSBFbmNyeXB0aW9uIGtleSAodW5kZWZpbmVkIHRvIHNraXAgZGVjcnlwdGlvbilcbiAqIEBwYXJhbSBvcHMgLSBQcm9taXNlIGFycmF5IGZvciBzdHJlYW0gb3BlcmF0aW9uc1xuICogQHBhcmFtIGdsb2JhbCAtIEdsb2JhbCBvYmplY3QgZm9yIGRlc2VyaWFsaXphdGlvbiBjb250ZXh0XG4gKiBAcGFyYW0gZXh0cmFSZXZpdmVycyAtIEFkZGl0aW9uYWwgcmV2aXZlcnMgZm9yIGN1c3RvbSB0eXBlc1xuICogQHJldHVybnMgVGhlIGh5ZHJhdGVkIHRocm93biB2YWx1ZSwgcmVhZHkgdG8gYmUgY29uc3VtZWQgYnkgdGhlIGNsaWVudFxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gaHlkcmF0ZVJ1bkVycm9yKFxuICB2YWx1ZTogVWludDhBcnJheSB8IHVua25vd24sXG4gIHJ1bklkOiBzdHJpbmcsXG4gIGtleTogQ3J5cHRvS2V5IHwgdW5kZWZpbmVkLFxuICBvcHM6IFByb21pc2U8dm9pZD5bXSA9IFtdLFxuICBnbG9iYWw6IFJlY29yZDxzdHJpbmcsIGFueT4gPSBnbG9iYWxUaGlzLFxuICBleHRyYVJldml2ZXJzOiBSZWNvcmQ8c3RyaW5nLCAodmFsdWU6IGFueSkgPT4gYW55PiA9IHt9XG4pOiBQcm9taXNlPHVua25vd24+IHtcbiAgY29uc3QgZGVjcnlwdGVkID0gYXdhaXQgbWF5YmVEZWNyeXB0KHZhbHVlLCBrZXkpO1xuXG4gIGlmICghKGRlY3J5cHRlZCBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpKSB7XG4gICAgLy8gU2VlIHRoZSBtYXRjaGluZyBub3RlIGluIGBoeWRyYXRlU3RlcEVycm9yYDogdGhpcyBicmFuY2ggaXMgZm9yXG4gICAgLy8gZGV2YWx1ZSBmbGF0dGVuZWQgYXJyYXlzIGZyb20gbGVnYWN5IGNhbGxlcnM7IGN1cnJlbnQgU0RLIHZlcnNpb25zXG4gICAgLy8gYWx3YXlzIGVtaXQgYSBVaW50OEFycmF5LCBhbmQgYSBtaXNzaGFwZW4gdmFsdWUgaGVyZSBpbnRlbnRpb25hbGx5XG4gICAgLy8gdGhyb3dzIHZpYSBgdW5mbGF0dGVuYCBzbyB0aGUgc3Vycm91bmRpbmcgdHJ5L2NhdGNoIGluIG8xMXkgaGVscGVyc1xuICAgIC8vIHN1cmZhY2VzIHRoZSBpc3N1ZSByYXRoZXIgdGhhbiBtYXNraW5nIGl0LlxuICAgIHJldHVybiB1bmZsYXR0ZW4oZGVjcnlwdGVkIGFzIGFueVtdLCB7XG4gICAgICAuLi5nZXRFeHRlcm5hbFJldml2ZXJzKGdsb2JhbCwgb3BzLCBydW5JZCwga2V5KSxcbiAgICAgIC4uLmV4dHJhUmV2aXZlcnMsXG4gICAgfSk7XG4gIH1cblxuICBjb25zdCB7IGZvcm1hdCwgcGF5bG9hZCB9ID0gZGVjb2RlRm9ybWF0UHJlZml4KGRlY3J5cHRlZCk7XG5cbiAgaWYgKGZvcm1hdCA9PT0gU2VyaWFsaXphdGlvbkZvcm1hdC5ERVZBTFVFX1YxKSB7XG4gICAgY29uc3Qgc3RyID0gbmV3IFRleHREZWNvZGVyKCkuZGVjb2RlKHBheWxvYWQpO1xuICAgIHJldHVybiBwYXJzZShzdHIsIHtcbiAgICAgIC4uLmdldEV4dGVybmFsUmV2aXZlcnMoZ2xvYmFsLCBvcHMsIHJ1bklkLCBrZXkpLFxuICAgICAgLi4uZXh0cmFSZXZpdmVycyxcbiAgICB9KTtcbiAgfVxuXG4gIHRocm93IG5ldyBFcnJvcihgVW5zdXBwb3J0ZWQgc2VyaWFsaXphdGlvbiBmb3JtYXQ6ICR7Zm9ybWF0fWApO1xufVxuXG4vKipcbiAqIENhbGxlZCBmcm9tIHRoZSB3b3JrZmxvdyBoYW5kbGVyIHdoZW4gcmVwbGF5aW5nIHRoZSBldmVudCBsb2cgb2YgYSBgc3RlcF9jb21wbGV0ZWRgIGV2ZW50LlxuICogSHlkcmF0ZXMgdGhlIHJldHVybiB2YWx1ZSBvZiBhIHN0ZXAgZnJvbSB0aGUgZGF0YWJhc2UuXG4gKlxuICogQHBhcmFtIHZhbHVlIC0gQmluYXJ5IHNlcmlhbGl6ZWQgZGF0YSAoVWludDhBcnJheSkgd2l0aCBmb3JtYXQgcHJlZml4XG4gKiBAcGFyYW0gcnVuSWQgLSBSdW4gSUQgZm9yIGRlY3J5cHRpb24gY29udGV4dFxuICogQHBhcmFtIGtleSAtIEVuY3J5cHRpb24ga2V5ICh1bmRlZmluZWQgdG8gc2tpcCBkZWNyeXB0aW9uKVxuICogQHBhcmFtIGdsb2JhbCAtIEdsb2JhbCBvYmplY3QgZm9yIGRlc2VyaWFsaXphdGlvbiBjb250ZXh0XG4gKiBAcGFyYW0gZXh0cmFSZXZpdmVycyAtIEFkZGl0aW9uYWwgcmV2aXZlcnMgZm9yIGN1c3RvbSB0eXBlc1xuICogQ2FsbGVkIGZyb20gdGhlIHdvcmtmbG93IGhhbmRsZXIgd2hlbiByZXBsYXlpbmcgdGhlIGV2ZW50IGxvZ1xuICogb2YgYSBgc3RlcF9jb21wbGV0ZWRgIGV2ZW50LlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gaHlkcmF0ZVN0ZXBSZXR1cm5WYWx1ZShcbiAgdmFsdWU6IFVpbnQ4QXJyYXkgfCB1bmtub3duLFxuICBfcnVuSWQ6IHN0cmluZyxcbiAga2V5OiBDcnlwdG9LZXkgfCB1bmRlZmluZWQsXG4gIGdsb2JhbDogUmVjb3JkPHN0cmluZywgYW55PiA9IGdsb2JhbFRoaXMsXG4gIGV4dHJhUmV2aXZlcnM6IFJlY29yZDxzdHJpbmcsICh2YWx1ZTogYW55KSA9PiBhbnk+ID0ge31cbik6IFByb21pc2U8YW55PiB7XG4gIHJldHVybiB3b3JrZmxvd01vZHVsZS5kZXNlcmlhbGl6ZShhd2FpdCBtYXliZURlY3J5cHQodmFsdWUsIGtleSksIHtcbiAgICBnbG9iYWwsXG4gICAgZXh0cmFSZXZpdmVyczoge1xuICAgICAgLi4uZ2V0U3RyZWFtQW5kUmVxdWVzdFJldml2ZXJzKGdldFdvcmtmbG93UmV2aXZlcnMoZ2xvYmFsKSksXG4gICAgICAuLi5leHRyYVJldml2ZXJzLFxuICAgIH0sXG4gIH0pO1xufVxuXG4vLyAtLS0tIEhlbHBlcnMgdG8gZXh0cmFjdCBzdHJlYW0vUmVxdWVzdC9SZXNwb25zZSByZWR1Y2VycyBhbmQgcmV2aXZlcnMgLS0tLVxuLy8gVGhlIG1vZGUtc3BlY2lmaWMgZ2V0KlJlZHVjZXJzL2dldCpSZXZpdmVycyBmdW5jdGlvbnMgcmV0dXJuIG9iamVjdHMgdGhhdFxuLy8gaW5jbHVkZSBib3RoIFwiY29tbW9uXCIgZW50cmllcyAoRGF0ZSwgRXJyb3IsIE1hcCwgZXRjLikgYW5kIG1vZGUtc3BlY2lmaWNcbi8vIGVudHJpZXMgKFJlYWRhYmxlU3RyZWFtLCBXcml0YWJsZVN0cmVhbSwgUmVxdWVzdCwgUmVzcG9uc2UsIFN0ZXBGdW5jdGlvbikuXG4vLyBUaGUgY29tbW9uIGVudHJpZXMgYXJlIGFscmVhZHkgY29tcG9zZWQgYnkgdGhlIGNvZGVjLiBXZSBvbmx5IG5lZWQgdG9cbi8vIHBhc3MgdGhyb3VnaCB0aGUgbW9kZS1zcGVjaWZpYyBlbnRyaWVzIGFzIGV4dHJhUmVkdWNlcnMvZXh0cmFSZXZpdmVycy5cblxuY29uc3QgU1RSRUFNX0FORF9SRVFVRVNUX0tFWVMgPSBbXG4gICdSZWFkYWJsZVN0cmVhbScsXG4gICdXcml0YWJsZVN0cmVhbScsXG4gICdSZXF1ZXN0JyxcbiAgJ1Jlc3BvbnNlJyxcbiAgJ1N0ZXBGdW5jdGlvbicsXG4gIC8vIFdpcmUgQWJvcnRDb250cm9sbGVyL0Fib3J0U2lnbmFsIHRocm91Z2ggdGhlIGNsaWVudCBzZXJpYWxpemF0aW9uIHBhdGggc29cbiAgLy8gc2lnbmFscyByZWFjaGFibGUgdmlhIFJlcXVlc3Quc2lnbmFsIChvciBhcyBkaXJlY3QgYXJndW1lbnRzKSBnZXQgdGhlaXJcbiAgLy8gZGVkaWNhdGVkIHJlZHVjZXIuIFdpdGhvdXQgdGhpcywgZGV2YWx1ZSBmYWxscyBiYWNrIHRvIGl0cyBhcmJpdHJhcnktUE9KT1xuICAvLyBwYXRoIGFuZCBmYWlscyBmb3IgYW55IHNpZ25hbCB0aGUgUmVxdWVzdCByZWR1Y2VyIGZvcndhcmRzLlxuICAnQWJvcnRDb250cm9sbGVyJyxcbiAgJ0Fib3J0U2lnbmFsJyxcbl0gYXMgY29uc3Q7XG5cbmZ1bmN0aW9uIGdldFN0cmVhbUFuZFJlcXVlc3RSZWR1Y2VycyhcbiAgYWxsUmVkdWNlcnM6IFJlY29yZDxzdHJpbmcsIGFueT5cbik6IFJlY29yZDxzdHJpbmcsICh2YWx1ZTogYW55KSA9PiBhbnk+IHtcbiAgY29uc3QgZXh0cmE6IFJlY29yZDxzdHJpbmcsICh2YWx1ZTogYW55KSA9PiBhbnk+ID0ge307XG4gIGZvciAoY29uc3Qga2V5IG9mIFNUUkVBTV9BTkRfUkVRVUVTVF9LRVlTKSB7XG4gICAgaWYgKGtleSBpbiBhbGxSZWR1Y2Vycykge1xuICAgICAgZXh0cmFba2V5XSA9IGFsbFJlZHVjZXJzW2tleV07XG4gICAgfVxuICB9XG4gIHJldHVybiBleHRyYTtcbn1cblxuZnVuY3Rpb24gZ2V0U3RyZWFtQW5kUmVxdWVzdFJldml2ZXJzKFxuICBhbGxSZXZpdmVyczogUmVjb3JkPHN0cmluZywgYW55PlxuKTogUmVjb3JkPHN0cmluZywgKHZhbHVlOiBhbnkpID0+IGFueT4ge1xuICBjb25zdCBleHRyYTogUmVjb3JkPHN0cmluZywgKHZhbHVlOiBhbnkpID0+IGFueT4gPSB7fTtcbiAgZm9yIChjb25zdCBrZXkgb2YgU1RSRUFNX0FORF9SRVFVRVNUX0tFWVMpIHtcbiAgICBpZiAoa2V5IGluIGFsbFJldml2ZXJzKSB7XG4gICAgICBleHRyYVtrZXldID0gYWxsUmV2aXZlcnNba2V5XTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGV4dHJhO1xufVxuIl19