@workflow/core 5.0.0-beta.4 → 5.0.0-beta.6

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 (168) hide show
  1. package/dist/capture-stack.d.ts +16 -0
  2. package/dist/capture-stack.d.ts.map +1 -0
  3. package/dist/capture-stack.js +21 -0
  4. package/dist/classify-error.d.ts +7 -0
  5. package/dist/classify-error.d.ts.map +1 -1
  6. package/dist/classify-error.js +25 -4
  7. package/dist/context-errors.d.ts +27 -0
  8. package/dist/context-errors.d.ts.map +1 -0
  9. package/dist/context-errors.js +101 -0
  10. package/dist/context-violation-error.d.ts +97 -0
  11. package/dist/context-violation-error.d.ts.map +1 -0
  12. package/dist/context-violation-error.js +147 -0
  13. package/dist/create-hook.d.ts.map +1 -1
  14. package/dist/create-hook.js +4 -3
  15. package/dist/define-hook.d.ts.map +1 -1
  16. package/dist/define-hook.js +20 -5
  17. package/dist/describe-error.d.ts +70 -0
  18. package/dist/describe-error.d.ts.map +1 -0
  19. package/dist/describe-error.js +119 -0
  20. package/dist/encryption.d.ts.map +1 -1
  21. package/dist/encryption.js +4 -20
  22. package/dist/events-consumer.d.ts +7 -0
  23. package/dist/events-consumer.d.ts.map +1 -1
  24. package/dist/events-consumer.js +9 -2
  25. package/dist/flushable-stream.d.ts +10 -10
  26. package/dist/flushable-stream.d.ts.map +1 -1
  27. package/dist/flushable-stream.js +13 -12
  28. package/dist/global.d.ts +4 -0
  29. package/dist/global.d.ts.map +1 -1
  30. package/dist/global.js +8 -2
  31. package/dist/log-format.d.ts +25 -0
  32. package/dist/log-format.d.ts.map +1 -0
  33. package/dist/log-format.js +250 -0
  34. package/dist/logger.d.ts +28 -30
  35. package/dist/logger.d.ts.map +1 -1
  36. package/dist/logger.js +77 -31
  37. package/dist/private.js +3 -3
  38. package/dist/runtime/get-port-lazy.d.ts +10 -0
  39. package/dist/runtime/get-port-lazy.d.ts.map +1 -0
  40. package/dist/runtime/get-port-lazy.js +30 -0
  41. package/dist/runtime/get-world-lazy.d.ts +32 -0
  42. package/dist/runtime/get-world-lazy.d.ts.map +1 -0
  43. package/dist/runtime/get-world-lazy.js +56 -0
  44. package/dist/runtime/helpers.d.ts +38 -5
  45. package/dist/runtime/helpers.d.ts.map +1 -1
  46. package/dist/runtime/helpers.js +67 -18
  47. package/dist/runtime/resume-hook.js +4 -4
  48. package/dist/runtime/run.d.ts.map +1 -1
  49. package/dist/runtime/run.js +31 -6
  50. package/dist/runtime/start.js +3 -3
  51. package/dist/runtime/step-executor.d.ts +40 -0
  52. package/dist/runtime/step-executor.d.ts.map +1 -0
  53. package/dist/runtime/step-executor.js +480 -0
  54. package/dist/runtime/step-handler.d.ts.map +1 -1
  55. package/dist/runtime/step-handler.js +209 -111
  56. package/dist/runtime/suspension-handler.d.ts +22 -4
  57. package/dist/runtime/suspension-handler.d.ts.map +1 -1
  58. package/dist/runtime/suspension-handler.js +86 -73
  59. package/dist/runtime/world-init.d.ts +75 -0
  60. package/dist/runtime/world-init.d.ts.map +1 -0
  61. package/dist/runtime/world-init.js +75 -0
  62. package/dist/runtime/world.d.ts.map +1 -1
  63. package/dist/runtime/world.js +47 -18
  64. package/dist/runtime.d.ts +8 -7
  65. package/dist/runtime.d.ts.map +1 -1
  66. package/dist/runtime.js +649 -292
  67. package/dist/schemas.d.ts +1 -1
  68. package/dist/schemas.d.ts.map +1 -1
  69. package/dist/schemas.js +1 -1
  70. package/dist/serialization/client.d.ts +17 -0
  71. package/dist/serialization/client.d.ts.map +1 -0
  72. package/dist/serialization/client.js +44 -0
  73. package/dist/serialization/codec-devalue.d.ts +14 -0
  74. package/dist/serialization/codec-devalue.d.ts.map +1 -0
  75. package/dist/serialization/codec-devalue.js +98 -0
  76. package/dist/serialization/codec.d.ts +90 -0
  77. package/dist/serialization/codec.d.ts.map +1 -0
  78. package/dist/serialization/codec.js +17 -0
  79. package/dist/serialization/encryption.d.ts +32 -0
  80. package/dist/serialization/encryption.d.ts.map +1 -0
  81. package/dist/serialization/encryption.js +51 -0
  82. package/dist/serialization/errors.d.ts +21 -0
  83. package/dist/serialization/errors.d.ts.map +1 -0
  84. package/dist/serialization/errors.js +41 -0
  85. package/dist/serialization/format.d.ts +60 -0
  86. package/dist/serialization/format.d.ts.map +1 -0
  87. package/dist/serialization/format.js +97 -0
  88. package/dist/serialization/index.d.ts +18 -0
  89. package/dist/serialization/index.d.ts.map +1 -0
  90. package/dist/serialization/index.js +20 -0
  91. package/dist/serialization/reducers/class.d.ts +11 -0
  92. package/dist/serialization/reducers/class.d.ts.map +1 -0
  93. package/dist/serialization/reducers/class.js +68 -0
  94. package/dist/serialization/reducers/common.d.ts +16 -0
  95. package/dist/serialization/reducers/common.d.ts.map +1 -0
  96. package/dist/serialization/reducers/common.js +386 -0
  97. package/dist/serialization/reducers/step-function.d.ts +35 -0
  98. package/dist/serialization/reducers/step-function.d.ts.map +1 -0
  99. package/dist/serialization/reducers/step-function.js +88 -0
  100. package/dist/serialization/step.d.ts +17 -0
  101. package/dist/serialization/step.d.ts.map +1 -0
  102. package/dist/serialization/step.js +44 -0
  103. package/dist/serialization/types.d.ts +208 -0
  104. package/dist/serialization/types.d.ts.map +1 -0
  105. package/dist/serialization/types.js +21 -0
  106. package/dist/serialization/workflow.d.ts +29 -0
  107. package/dist/serialization/workflow.d.ts.map +1 -0
  108. package/dist/serialization/workflow.js +54 -0
  109. package/dist/serialization-format.d.ts.map +1 -1
  110. package/dist/serialization-format.js +77 -3
  111. package/dist/serialization.d.ts +209 -226
  112. package/dist/serialization.d.ts.map +1 -1
  113. package/dist/serialization.js +773 -633
  114. package/dist/sleep.d.ts.map +1 -1
  115. package/dist/sleep.js +3 -2
  116. package/dist/step/get-closure-vars.d.ts.map +1 -1
  117. package/dist/step/get-closure-vars.js +3 -2
  118. package/dist/step/get-step-metadata.d.ts.map +1 -1
  119. package/dist/step/get-step-metadata.js +3 -2
  120. package/dist/step/get-workflow-metadata.d.ts.map +1 -1
  121. package/dist/step/get-workflow-metadata.js +3 -2
  122. package/dist/step/writable-stream.d.ts.map +1 -1
  123. package/dist/step/writable-stream.js +3 -2
  124. package/dist/step.d.ts.map +1 -1
  125. package/dist/step.js +83 -16
  126. package/dist/symbols.d.ts +4 -0
  127. package/dist/symbols.d.ts.map +1 -1
  128. package/dist/symbols.js +5 -1
  129. package/dist/telemetry/semantic-conventions.d.ts +2 -2
  130. package/dist/telemetry/semantic-conventions.js +1 -1
  131. package/dist/util.d.ts +18 -3
  132. package/dist/util.d.ts.map +1 -1
  133. package/dist/util.js +28 -5
  134. package/dist/version.d.ts +1 -1
  135. package/dist/version.js +2 -2
  136. package/dist/vm/index.d.ts.map +1 -1
  137. package/dist/vm/index.js +3 -2
  138. package/dist/workflow/abort-controller.d.ts +65 -0
  139. package/dist/workflow/abort-controller.d.ts.map +1 -0
  140. package/dist/workflow/abort-controller.js +245 -0
  141. package/dist/workflow/create-hook.d.ts.map +1 -1
  142. package/dist/workflow/create-hook.js +3 -2
  143. package/dist/workflow/define-hook.d.ts +1 -1
  144. package/dist/workflow/define-hook.d.ts.map +1 -1
  145. package/dist/workflow/define-hook.js +8 -4
  146. package/dist/workflow/get-workflow-metadata.d.ts.map +1 -1
  147. package/dist/workflow/get-workflow-metadata.js +14 -3
  148. package/dist/workflow/hook.d.ts.map +1 -1
  149. package/dist/workflow/hook.js +2 -2
  150. package/dist/workflow/index.d.ts.map +1 -1
  151. package/dist/workflow/index.js +4 -3
  152. package/dist/workflow/world-init-stub.d.ts +15 -0
  153. package/dist/workflow/world-init-stub.d.ts.map +1 -0
  154. package/dist/workflow/world-init-stub.js +15 -0
  155. package/dist/workflow.d.ts.map +1 -1
  156. package/dist/workflow.js +71 -28
  157. package/docs/foundations/cancellation.mdx +460 -0
  158. package/docs/foundations/errors-and-retries.mdx +7 -3
  159. package/docs/foundations/index.mdx +3 -0
  160. package/docs/foundations/meta.json +3 -1
  161. package/docs/foundations/serialization.mdx +77 -41
  162. package/docs/foundations/starting-workflows.mdx +5 -1
  163. package/docs/foundations/versioning.mdx +263 -0
  164. package/docs/how-it-works/cancellation.mdx +287 -0
  165. package/docs/how-it-works/code-transform.mdx +2 -2
  166. package/docs/how-it-works/event-sourcing.mdx +2 -2
  167. package/docs/how-it-works/meta.json +2 -1
  168. package/package.json +15 -6
@@ -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 { 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
4
  import { decrypt as aesGcmDecrypt, encrypt as aesGcmEncrypt, } 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 } 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_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,24 @@ 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
+ function unwrapSerializationCause(error) {
70
+ if (error instanceof SerializationError && error.cause !== undefined) {
71
+ return error.cause;
72
+ }
73
+ if (error instanceof WorkflowRuntimeError && error.cause !== undefined) {
74
+ return error.cause;
75
+ }
76
+ return error;
77
+ }
182
78
  export function getSerializeStream(reducers, cryptoKey) {
183
79
  const encoder = new TextEncoder();
184
80
  // Resolve the key promise once on first use and cache the result.
@@ -210,7 +106,8 @@ export function getSerializeStream(reducers, cryptoKey) {
210
106
  controller.enqueue(frame);
211
107
  }
212
108
  catch (error) {
213
- controller.error(new WorkflowRuntimeError(formatSerializationError('stream chunk', error), { slug: 'serialization-failed', cause: error }));
109
+ const { message, hint } = formatSerializationError('stream chunk', error);
110
+ controller.error(new SerializationError(message, { hint, cause: error }));
214
111
  }
215
112
  },
216
113
  });
@@ -303,7 +200,7 @@ export class WorkflowServerReadableStream extends ReadableStream {
303
200
  #reader;
304
201
  constructor(runId, name, startIndex) {
305
202
  if (typeof name !== 'string' || name.length === 0) {
306
- throw new Error(`"name" is required, got "${name}"`);
203
+ throw new WorkflowRuntimeError(`"name" is required, got "${name}"`);
307
204
  }
308
205
  super({
309
206
  // @ts-expect-error Not sure why TypeScript is complaining about this
@@ -311,7 +208,7 @@ export class WorkflowServerReadableStream extends ReadableStream {
311
208
  pull: async (controller) => {
312
209
  let reader = this.#reader;
313
210
  if (!reader) {
314
- const world = await getWorld();
211
+ const world = await getWorldLazy();
315
212
  const stream = await world.streams.get(runId, name, startIndex);
316
213
  reader = this.#reader = stream.getReader();
317
214
  }
@@ -347,12 +244,12 @@ const STREAM_FLUSH_INTERVAL_MS = 10;
347
244
  export class WorkflowServerWritableStream extends WritableStream {
348
245
  constructor(runId, name) {
349
246
  if (typeof runId !== 'string') {
350
- throw new Error(`"runId" must be a string, got "${typeof runId}"`);
247
+ throw new WorkflowRuntimeError(`"runId" must be a string, got "${typeof runId}"`);
351
248
  }
352
249
  if (typeof name !== 'string' || name.length === 0) {
353
- throw new Error(`"name" is required, got "${name}"`);
250
+ throw new WorkflowRuntimeError(`"name" is required, got "${name}"`);
354
251
  }
355
- const worldPromise = getWorld();
252
+ const worldPromise = getWorldLazy();
356
253
  // Buffering state for batched writes
357
254
  // Encryption/decryption is handled at the framing level by
358
255
  // getSerializeStream/getDeserializeStream, not here.
@@ -457,115 +354,22 @@ export class WorkflowServerWritableStream extends WritableStream {
457
354
  });
458
355
  }
459
356
  }
460
- function revive(str) {
461
- // devalue.stringify() always produces valid JSON: special values
462
- // (undefined, NaN, Infinity, -0) are encoded as negative integer
463
- // sentinels and the remaining structure is ordinary JSON. Parsing
464
- // with JSON.parse yields the flattened form that unflatten() expects.
465
- return JSON.parse(str);
466
- }
467
- function getCommonReducers(global = globalThis) {
468
- const abToBase64 = (value, offset, length) => {
469
- // Avoid returning falsy value for zero-length buffers
470
- if (length === 0)
471
- return '.';
472
- // Create a proper copy to avoid ArrayBuffer detachment issues
473
- // Buffer.from(ArrayBuffer, offset, length) creates a view, not a copy
474
- const uint8 = new Uint8Array(value, offset, length);
475
- return Buffer.from(uint8).toString('base64');
476
- };
477
- const viewToBase64 = (value) => abToBase64(value.buffer, value.byteOffset, value.byteLength);
357
+ // ---- Composed reducers ----
358
+ // Composes modular reducers (common, class, step-function) with
359
+ // mode-specific Request/Response/Stream reducers below.
360
+ /**
361
+ * Base reducers shared across all serialization boundaries.
362
+ * Composes: class + step-function + common reducers from the modular modules.
363
+ */
364
+ function getAllBaseReducers(global = globalThis) {
365
+ // Class/Instance MUST come before Error so that custom Error subclasses
366
+ // with WORKFLOW_SERIALIZE take precedence (devalue uses first-match-wins).
478
367
  return {
479
- ArrayBuffer: (value) => value instanceof global.ArrayBuffer &&
480
- abToBase64(value, 0, value.byteLength),
481
- BigInt: (value) => typeof value === 'bigint' && value.toString(),
482
- BigInt64Array: (value) => value instanceof global.BigInt64Array && viewToBase64(value),
483
- BigUint64Array: (value) => value instanceof global.BigUint64Array && viewToBase64(value),
484
- // Class and Instance are intentionally placed before Error so that
485
- // custom Error subclasses with WORKFLOW_SERIALIZE take precedence
486
- // over the generic Error serialization (devalue uses first-match-wins).
487
- Class: (value) => {
488
- // Check if this is a class constructor with a classId property
489
- // (set by the SWC plugin for classes with static step/workflow methods)
490
- if (typeof value !== 'function')
491
- return false;
492
- const classId = value.classId;
493
- if (typeof classId !== 'string')
494
- return false;
495
- return { classId };
496
- },
497
- Instance: (value) => {
498
- // Check if this is an instance of a class with custom serialization
499
- if (value === null || typeof value !== 'object')
500
- return false;
501
- const cls = value.constructor;
502
- if (!cls || typeof cls !== 'function')
503
- return false;
504
- // Check if the class has a static WORKFLOW_SERIALIZE method
505
- const serialize = cls[WORKFLOW_SERIALIZE];
506
- if (typeof serialize !== 'function') {
507
- return false;
508
- }
509
- // Get the classId from the static class property (set by SWC plugin)
510
- const classId = cls.classId;
511
- if (typeof classId !== 'string') {
512
- throw new Error(`Class "${cls.name}" with ${String(WORKFLOW_SERIALIZE)} must have a static "classId" property.`);
513
- }
514
- // Serialize the instance using the custom serializer
515
- const data = serialize.call(cls, value);
516
- return { classId, data };
517
- },
518
- Date: (value) => {
519
- if (!(value instanceof global.Date))
520
- return false;
521
- const valid = !Number.isNaN(value.getDate());
522
- // Note: "." is to avoid returning a falsy value when the date is invalid
523
- return valid ? value.toISOString() : '.';
524
- },
525
- // DOMException is a special case: in Node.js it passes isNativeError()
526
- // and instanceof Error, but has a unique constructor signature
527
- // (message, name) and a read-only numeric `code` property derived from
528
- // `name`. It must be checked before the generic Error reducer.
529
- DOMException: (value) => {
530
- if (!types.isNativeError(value))
531
- return false;
532
- if (value.constructor?.name !== 'DOMException')
533
- return false;
534
- const reduced = {
535
- message: value.message,
536
- name: value.name,
537
- stack: value.stack,
538
- };
539
- if ('cause' in value)
540
- reduced.cause = value.cause;
541
- return reduced;
542
- },
543
- Error: (value) => {
544
- // Use types.isNativeError() instead of `instanceof global.Error`
545
- // because errors may originate from a different VM context (e.g.
546
- // FatalError from the host context passed into a VM-context workflow).
547
- // `instanceof` checks fail across VM boundaries since each context
548
- // has its own Error constructor, but isNativeError() uses V8's
549
- // internal type tag which works across all contexts.
550
- if (!types.isNativeError(value))
551
- return false;
552
- return {
553
- name: value.name,
554
- message: value.message,
555
- stack: value.stack,
556
- };
557
- },
558
- Float32Array: (value) => value instanceof global.Float32Array && viewToBase64(value),
559
- Float64Array: (value) => value instanceof global.Float64Array && viewToBase64(value),
560
- Headers: (value) => value instanceof global.Headers && Array.from(value),
561
- Int8Array: (value) => value instanceof global.Int8Array && viewToBase64(value),
562
- Int16Array: (value) => value instanceof global.Int16Array && viewToBase64(value),
563
- Int32Array: (value) => value instanceof global.Int32Array && viewToBase64(value),
564
- Map: (value) => value instanceof global.Map && Array.from(value),
565
- RegExp: (value) => value instanceof global.RegExp && {
566
- source: value.source,
567
- flags: value.flags,
568
- },
368
+ ...getClassReducers(),
369
+ ...getStepFunctionReducer(),
370
+ ...getCommonReducers(global),
371
+ // Request and Response reducers are mode-specific and added by
372
+ // getExternalReducers / getWorkflowReducers / getStepReducers below.
569
373
  Request: (value) => {
570
374
  if (!(value instanceof global.Request))
571
375
  return false;
@@ -580,6 +384,20 @@ function getCommonReducers(global = globalThis) {
580
384
  if (responseWritable) {
581
385
  data.responseWritable = responseWritable;
582
386
  }
387
+ // Forward the signal in two cases:
388
+ // 1. Already aborted — preserve aborted=true/reason so the hydrated
389
+ // step sees the cancellation that happened before serialize.
390
+ // 2. Already tagged with workflow infrastructure — i.e. a signal
391
+ // from a workflow-managed AbortController, which has stream/hook
392
+ // backing for cross-boundary propagation.
393
+ // Plain non-aborted native signals are intentionally dropped (would
394
+ // mint stream infra for every Request, including the auto-generated
395
+ // signal on `new Request(url)`).
396
+ if (value.signal &&
397
+ (value.signal.aborted ||
398
+ value.signal[ABORT_STREAM_NAME])) {
399
+ data.signal = value.signal;
400
+ }
583
401
  return data;
584
402
  },
585
403
  Response: (value) => {
@@ -595,50 +413,89 @@ function getCommonReducers(global = globalThis) {
595
413
  redirected: value.redirected,
596
414
  };
597
415
  },
598
- Set: (value) => value instanceof global.Set && Array.from(value),
599
- StepFunction: (value) => {
600
- if (typeof value !== 'function')
601
- return false;
602
- const stepId = value.stepId;
603
- if (typeof stepId !== 'string')
604
- return false;
605
- // Check if the step function has closure variables
606
- const closureVarsFn = value.__closureVarsFn;
607
- if (closureVarsFn && typeof closureVarsFn === 'function') {
608
- // Invoke the closure variables function and serialize along with stepId
609
- const closureVars = closureVarsFn();
610
- return { stepId, closureVars };
611
- }
612
- // No closure variables - return object with just stepId
613
- return { stepId };
614
- },
615
- URL: (value) => value instanceof global.URL && value.href,
616
- WorkflowFunction: (value) => {
617
- // Only match function references with a workflowId property (set by
618
- // the SWC compiler on workflow functions). Plain { workflowId } objects
619
- // are NOT matched — this prevents infinite recursion since the reduced
620
- // form { workflowId } is a plain object, not a function.
621
- if (typeof value !== 'function')
622
- return false;
623
- const workflowId = value.workflowId;
624
- if (typeof workflowId !== 'string')
625
- return false;
626
- return { workflowId };
627
- },
628
- URLSearchParams: (value) => {
629
- if (!(value instanceof global.URLSearchParams))
630
- return false;
631
- // Avoid returning a falsy value when the URLSearchParams is empty
632
- if (value.size === 0)
633
- return '.';
634
- return String(value);
635
- },
636
- Uint8Array: (value) => value instanceof global.Uint8Array && viewToBase64(value),
637
- Uint8ClampedArray: (value) => value instanceof global.Uint8ClampedArray && viewToBase64(value),
638
- Uint16Array: (value) => value instanceof global.Uint16Array && viewToBase64(value),
639
- Uint32Array: (value) => value instanceof global.Uint32Array && viewToBase64(value),
640
416
  };
641
417
  }
418
+ /**
419
+ * Shared logic for AbortController/AbortSignal reducers in external and step
420
+ * contexts. Assigns stream/hook names if not already present, optionally
421
+ * attaches an abort listener for real-time propagation, and returns the
422
+ * serialized representation.
423
+ */
424
+ function reduceAbortWithListener(signal, holder, global, ops, runId, cryptoKey) {
425
+ let streamName = holder[ABORT_STREAM_NAME];
426
+ let hookToken = holder[ABORT_HOOK_TOKEN];
427
+ if (!streamName) {
428
+ const id = (global[STABLE_ULID] || defaultUlid)();
429
+ streamName = getAbortStreamId(id);
430
+ hookToken = `abrt_${id}`;
431
+ holder[ABORT_STREAM_NAME] = streamName;
432
+ holder[ABORT_HOOK_TOKEN] = hookToken;
433
+ if (holder.signal) {
434
+ holder.signal[ABORT_STREAM_NAME] = streamName;
435
+ holder.signal[ABORT_HOOK_TOKEN] = hookToken;
436
+ }
437
+ }
438
+ // Deduped via ABORT_LISTENER_ATTACHED marker — see attachAbortListenerOnce.
439
+ attachAbortListenerOnce(signal, streamName, runId, cryptoKey, ops);
440
+ return {
441
+ streamName,
442
+ hookToken: hookToken,
443
+ aborted: signal.aborted,
444
+ reason: signal.aborted ? signal.reason : undefined,
445
+ };
446
+ }
447
+ /**
448
+ * Shared logic for AbortController/AbortSignal reducers in workflow context.
449
+ * Reads existing stream/hook names from symbols (must already be set).
450
+ */
451
+ function reduceAbortBySymbol(signal, holder) {
452
+ const streamName = holder[ABORT_STREAM_NAME] ?? holder.signal?.[ABORT_STREAM_NAME];
453
+ const hookToken = holder[ABORT_HOOK_TOKEN] ?? holder.signal?.[ABORT_HOOK_TOKEN];
454
+ if (!streamName) {
455
+ throw new Error('AbortController/AbortSignal stream name is not set');
456
+ }
457
+ return {
458
+ streamName,
459
+ hookToken: hookToken,
460
+ aborted: signal.aborted,
461
+ reason: signal.aborted ? signal.reason : undefined,
462
+ };
463
+ }
464
+ /**
465
+ * Attach a single abort listener to a signal, deduped across calls.
466
+ *
467
+ * Each serialization pass goes through the reducer, but a controller passed
468
+ * to N steps would otherwise accumulate N listeners — each writing the same
469
+ * stream packet and double-closing the stream on abort. The marker symbol
470
+ * ensures the stream-write side-effect runs at most once per (signal, runId).
471
+ */
472
+ function attachAbortListenerOnce(signal, streamName, runId, cryptoKey, ops) {
473
+ if (signal.aborted)
474
+ return;
475
+ if (signal[ABORT_LISTENER_ATTACHED])
476
+ return;
477
+ signal[ABORT_LISTENER_ATTACHED] = true;
478
+ signal.addEventListener('abort', () => {
479
+ ops.push((async () => {
480
+ try {
481
+ // Dehydrate via the same machinery the reader uses (hydrateStepArguments)
482
+ // so the reason round-trips with full type fidelity (DOMException,
483
+ // Errors, custom classes, etc.) and respects the run's encryption key.
484
+ // A bare JSON.stringify here would write a packet the reader can't
485
+ // decode and the listener-side abort would propagate with no reason.
486
+ const key = await cryptoKey;
487
+ const payload = await dehydrateStepArguments({ aborted: true, reason: signal.reason }, runId, key);
488
+ const writable = new WorkflowServerWritableStream(runId, streamName);
489
+ const writer = writable.getWriter();
490
+ await writer.write(payload);
491
+ await writer.close();
492
+ }
493
+ catch {
494
+ // Best-effort stream write
495
+ }
496
+ })());
497
+ }, { once: true });
498
+ }
642
499
  /**
643
500
  * Reducers for serialization boundary from the client side, passing arguments
644
501
  * to the workflow handler.
@@ -649,13 +506,15 @@ function getCommonReducers(global = globalThis) {
649
506
  */
650
507
  export function getExternalReducers(global = globalThis, ops, runId, cryptoKey) {
651
508
  return {
652
- ...getCommonReducers(global),
509
+ ...getAllBaseReducers(global),
653
510
  ReadableStream: (value) => {
654
511
  if (!(value instanceof global.ReadableStream))
655
512
  return false;
656
513
  // Stream must not be locked when passing across execution boundary
657
514
  if (value.locked) {
658
- throw new Error('ReadableStream is locked');
515
+ throw new SerializationError('ReadableStream is locked and cannot be passed across a workflow boundary.', {
516
+ hint: 'Pass the stream before calling .getReader() / .pipeThrough() / .pipeTo(), or tee it with .tee() and pass one of the branches.',
517
+ });
659
518
  }
660
519
  const streamId = (global[STABLE_ULID] || defaultUlid)();
661
520
  const name = `strm_${streamId}`;
@@ -683,6 +542,20 @@ export function getExternalReducers(global = globalThis, ops, runId, cryptoKey)
683
542
  ops.push(readable.pipeTo(value));
684
543
  return { name };
685
544
  },
545
+ AbortController: (value) => {
546
+ if (!global.AbortController ||
547
+ typeof global.AbortController !== 'function' ||
548
+ !(value instanceof global.AbortController))
549
+ return false;
550
+ return reduceAbortWithListener(value.signal, value, global, ops, runId, cryptoKey);
551
+ },
552
+ AbortSignal: (value) => {
553
+ if (!global.AbortSignal ||
554
+ typeof global.AbortSignal !== 'function' ||
555
+ !(value instanceof global.AbortSignal))
556
+ return false;
557
+ return reduceAbortWithListener(value, value, global, ops, runId, cryptoKey);
558
+ },
686
559
  };
687
560
  }
688
561
  /**
@@ -694,7 +567,7 @@ export function getExternalReducers(global = globalThis, ops, runId, cryptoKey)
694
567
  */
695
568
  export function getWorkflowReducers(global = globalThis) {
696
569
  return {
697
- ...getCommonReducers(global),
570
+ ...getAllBaseReducers(global),
698
571
  // Readable/Writable streams from within the workflow execution environment
699
572
  // are simply "handles" that can be passed around to other steps.
700
573
  ReadableStream: (value) => {
@@ -709,7 +582,7 @@ export function getWorkflowReducers(global = globalThis) {
709
582
  }
710
583
  const name = value[STREAM_NAME_SYMBOL];
711
584
  if (!name) {
712
- throw new Error('ReadableStream `name` is not set');
585
+ throw new WorkflowRuntimeError('ReadableStream `name` is not set');
713
586
  }
714
587
  const s = { name };
715
588
  const type = value[STREAM_TYPE_SYMBOL];
@@ -722,10 +595,36 @@ export function getWorkflowReducers(global = globalThis) {
722
595
  return false;
723
596
  const name = value[STREAM_NAME_SYMBOL];
724
597
  if (!name) {
725
- throw new Error('WritableStream `name` is not set');
598
+ throw new WorkflowRuntimeError('WritableStream `name` is not set');
726
599
  }
727
600
  return { name };
728
601
  },
602
+ // AbortController/AbortSignal in workflow context — just read symbols (handles).
603
+ // In the workflow VM, global.AbortController is a class but global.AbortSignal
604
+ // is a plain object (not a class), so instanceof checks won't work for signals.
605
+ // Detect instances by the presence of the ABORT_STREAM_NAME symbol instead.
606
+ AbortController: (value) => {
607
+ if (!value || !value.signal)
608
+ return false;
609
+ const holder = value;
610
+ const hasAbortSymbol = holder[ABORT_STREAM_NAME] ?? holder.signal?.[ABORT_STREAM_NAME];
611
+ const isNativeAbortController = global.AbortController &&
612
+ typeof global.AbortController === 'function' &&
613
+ value instanceof global.AbortController;
614
+ if (!hasAbortSymbol && !isNativeAbortController)
615
+ return false;
616
+ return reduceAbortBySymbol(value.signal, holder);
617
+ },
618
+ AbortSignal: (value) => {
619
+ const signal = value;
620
+ const hasAbortSymbol = signal && signal[ABORT_STREAM_NAME];
621
+ const isNativeAbortSignal = global.AbortSignal &&
622
+ typeof global.AbortSignal === 'function' &&
623
+ value instanceof global.AbortSignal;
624
+ if (!hasAbortSymbol && !isNativeAbortSignal)
625
+ return false;
626
+ return reduceAbortBySymbol(value, value);
627
+ },
729
628
  };
730
629
  }
731
630
  /**
@@ -739,13 +638,15 @@ export function getWorkflowReducers(global = globalThis) {
739
638
  */
740
639
  function getStepReducers(global = globalThis, ops, runId, cryptoKey) {
741
640
  return {
742
- ...getCommonReducers(global),
641
+ ...getAllBaseReducers(global),
743
642
  ReadableStream: (value) => {
744
643
  if (!(value instanceof global.ReadableStream))
745
644
  return false;
746
645
  // Stream must not be locked when passing across execution boundary
747
646
  if (value.locked) {
748
- throw new Error('ReadableStream is locked');
647
+ throw new SerializationError('ReadableStream is locked and cannot be passed across a workflow boundary.', {
648
+ hint: 'Pass the stream before calling .getReader() / .pipeThrough() / .pipeTo(), or tee it with .tee() and pass one of the branches.',
649
+ });
749
650
  }
750
651
  // Check if the stream already has the name symbol set, in which case
751
652
  // it's already being sunk to the server and we can just return the
@@ -784,116 +685,252 @@ function getStepReducers(global = globalThis, ops, runId, cryptoKey) {
784
685
  }
785
686
  return { name };
786
687
  },
688
+ AbortController: (value) => {
689
+ if (!global.AbortController ||
690
+ typeof global.AbortController !== 'function' ||
691
+ !(value instanceof global.AbortController))
692
+ return false;
693
+ return reduceAbortWithListener(value.signal, value, global, ops, runId, cryptoKey);
694
+ },
695
+ AbortSignal: (value) => {
696
+ if (!global.AbortSignal ||
697
+ typeof global.AbortSignal !== 'function' ||
698
+ !(value instanceof global.AbortSignal))
699
+ return false;
700
+ return reduceAbortWithListener(value, value, global, ops, runId, cryptoKey);
701
+ },
787
702
  };
788
703
  }
789
- export function getCommonRevivers(global = globalThis) {
790
- function reviveArrayBuffer(value) {
791
- // Handle sentinel value for zero-length buffers
792
- const base64 = value === '.' ? '' : value;
793
- const buffer = Buffer.from(base64, 'base64');
794
- const arrayBuffer = new global.ArrayBuffer(buffer.length);
795
- const uint8Array = new global.Uint8Array(arrayBuffer);
796
- uint8Array.set(buffer);
797
- return arrayBuffer;
704
+ /**
705
+ * Cancel dangling abort-stream readers on any AbortController instances found
706
+ * in the hydrated step arguments. Called after the step function returns
707
+ * (success or failure) to prevent reader promises from keeping the serverless
708
+ * function alive indefinitely.
709
+ */
710
+ export function cancelAbortReaders(...values) {
711
+ const visited = new WeakSet();
712
+ function cancelIfPresent(val) {
713
+ const cancel = val[ABORT_READER_CANCEL];
714
+ if (cancel && !cancel.signal.aborted) {
715
+ cancel.abort();
716
+ }
798
717
  }
799
- return {
800
- ArrayBuffer: reviveArrayBuffer,
801
- BigInt: (value) => global.BigInt(value),
802
- BigInt64Array: (value) => {
803
- const ab = reviveArrayBuffer(value);
804
- return new global.BigInt64Array(ab);
805
- },
806
- BigUint64Array: (value) => {
807
- const ab = reviveArrayBuffer(value);
808
- return new global.BigUint64Array(ab);
809
- },
810
- Date: (value) => new global.Date(value),
811
- DOMException: (value) => {
812
- const error = new global.DOMException(value.message, value.name);
813
- if (value.stack !== undefined)
814
- error.stack = value.stack;
815
- // DOMException's constructor doesn't accept a cause option, so
816
- // we set it manually when present in the serialized data.
817
- if ('cause' in value)
818
- error.cause = value.cause;
819
- return error;
820
- },
821
- Error: (value) => {
822
- const error = new global.Error(value.message);
823
- error.name = value.name;
824
- error.stack = value.stack;
825
- return error;
826
- },
827
- Float32Array: (value) => {
828
- const ab = reviveArrayBuffer(value);
829
- return new global.Float32Array(ab);
830
- },
831
- Float64Array: (value) => {
832
- const ab = reviveArrayBuffer(value);
833
- return new global.Float64Array(ab);
834
- },
835
- Headers: (value) => new global.Headers(value),
836
- Int8Array: (value) => {
837
- const ab = reviveArrayBuffer(value);
838
- return new global.Int8Array(ab);
839
- },
840
- Int16Array: (value) => {
841
- const ab = reviveArrayBuffer(value);
842
- return new global.Int16Array(ab);
843
- },
844
- Int32Array: (value) => {
845
- const ab = reviveArrayBuffer(value);
846
- return new global.Int32Array(ab);
847
- },
848
- Map: (value) => new global.Map(value),
849
- RegExp: (value) => new global.RegExp(value.source, value.flags),
850
- Class: (value) => {
851
- const classId = value.classId;
852
- // Pass the global object to support VM contexts where classes are registered
853
- // on the VM's global rather than the host's globalThis
854
- const cls = getSerializationClass(classId, global);
855
- if (!cls) {
856
- throw new Error(`Class "${classId}" not found. Make sure the class is registered with registerSerializationClass.`);
857
- }
858
- return cls;
859
- },
860
- Instance: (value) => {
861
- const classId = value.classId;
862
- const data = value.data;
863
- // Look up the class by classId from the registry
864
- // Pass the global object to support VM contexts where classes are registered
865
- // on the VM's global rather than the host's globalThis
866
- const cls = getSerializationClass(classId, global);
867
- if (!cls) {
868
- throw new Error(`Class "${classId}" not found. Make sure the class is registered with registerSerializationClass.`);
718
+ function walk(val) {
719
+ if (val == null || typeof val !== 'object')
720
+ return;
721
+ if (visited.has(val))
722
+ return;
723
+ visited.add(val);
724
+ if (val instanceof AbortController) {
725
+ cancelIfPresent(val);
726
+ cancelIfPresent(val.signal);
727
+ return;
728
+ }
729
+ if (val instanceof AbortSignal) {
730
+ cancelIfPresent(val);
731
+ return;
732
+ }
733
+ if (Array.isArray(val)) {
734
+ for (const item of val)
735
+ walk(item);
736
+ return;
737
+ }
738
+ if (val instanceof Map) {
739
+ for (const v of val.values())
740
+ walk(v);
741
+ return;
742
+ }
743
+ if (val instanceof Set) {
744
+ for (const v of val)
745
+ walk(v);
746
+ return;
747
+ }
748
+ // Request/Response expose `signal`/`body` as prototype getters, so
749
+ // Object.values() won't find them. Descend explicitly.
750
+ if (typeof Request !== 'undefined' && val instanceof Request) {
751
+ walk(val.signal);
752
+ return;
753
+ }
754
+ for (const v of Object.values(val))
755
+ walk(v);
756
+ }
757
+ for (const v of values)
758
+ walk(v);
759
+ }
760
+ /**
761
+ * Sets up a stream reader on the controller that listens for an abort packet.
762
+ * Returns the readerCancel controller so it can be stored on both the
763
+ * controller and signal for cleanup by cancelAbortReaders.
764
+ */
765
+ function setupAbortStreamReader(controller, runId, streamName, ops) {
766
+ const readerCancel = new AbortController();
767
+ ops.push((async () => {
768
+ try {
769
+ const readable = new WorkflowServerReadableStream(runId, streamName);
770
+ const reader = readable.getReader();
771
+ const result = await Promise.race([
772
+ reader.read(),
773
+ new Promise((resolve) => {
774
+ if (readerCancel.signal.aborted) {
775
+ resolve({ value: undefined, done: true });
776
+ return;
777
+ }
778
+ readerCancel.signal.addEventListener('abort', () => resolve({ value: undefined, done: true }), { once: true });
779
+ }),
780
+ ]);
781
+ reader.releaseLock();
782
+ if (result.value && !result.done) {
783
+ try {
784
+ // Hydrate via the same machinery the writer used so the reason
785
+ // round-trips with full type fidelity. Encryption key (if any)
786
+ // comes from the step context — set up by the step handler before
787
+ // this reader runs. Fallback to undefined for external-context
788
+ // revives (the hydrate path is encryption-key-tolerant).
789
+ const ctxForKey = contextStorage.getStore();
790
+ const data = (await hydrateStepArguments(result.value, runId, ctxForKey?.encryptionKey));
791
+ controller.abort(data?.reason);
792
+ }
793
+ catch {
794
+ controller.abort();
795
+ }
869
796
  }
870
- // Get the deserializer from the class
871
- const deserialize = cls[WORKFLOW_DESERIALIZE];
872
- if (typeof deserialize !== 'function') {
873
- throw new Error(`Class "${classId}" does not have a static ${String(WORKFLOW_DESERIALIZE)} method.`);
797
+ }
798
+ catch {
799
+ // Stream read failed — signal won't propagate in real-time,
800
+ // but hook-based propagation on next replay provides fallback
801
+ }
802
+ })());
803
+ return readerCancel;
804
+ }
805
+ /**
806
+ * Stores abort serialization symbols and the readerCancel controller
807
+ * on both the controller and its signal.
808
+ */
809
+ function tagAbortPair(controller, value, readerCancel) {
810
+ const taggedController = controller;
811
+ const taggedSignal = controller.signal;
812
+ taggedController[ABORT_STREAM_NAME] = value.streamName;
813
+ taggedController[ABORT_HOOK_TOKEN] = value.hookToken;
814
+ taggedSignal[ABORT_STREAM_NAME] = value.streamName;
815
+ taggedSignal[ABORT_HOOK_TOKEN] = value.hookToken;
816
+ if (readerCancel) {
817
+ taggedController[ABORT_READER_CANCEL] = readerCancel;
818
+ taggedSignal[ABORT_READER_CANCEL] = readerCancel;
819
+ }
820
+ }
821
+ /**
822
+ * Propagate abort-internal symbols from one signal to another. Used by the
823
+ * Request reviver because `new Request(url, { signal })` copies the signal
824
+ * internally — the constructed `request.signal` is a fresh AbortSignal that
825
+ * doesn't carry symbols from the source.
826
+ */
827
+ function copyAbortInternals(src, dest) {
828
+ const s = src;
829
+ const d = dest;
830
+ if (s[ABORT_STREAM_NAME] !== undefined) {
831
+ d[ABORT_STREAM_NAME] = s[ABORT_STREAM_NAME];
832
+ }
833
+ if (s[ABORT_HOOK_TOKEN] !== undefined) {
834
+ d[ABORT_HOOK_TOKEN] = s[ABORT_HOOK_TOKEN];
835
+ }
836
+ if (s[ABORT_READER_CANCEL] !== undefined) {
837
+ d[ABORT_READER_CANCEL] = s[ABORT_READER_CANCEL];
838
+ }
839
+ }
840
+ /**
841
+ * Creates an AbortController with stream-backed abort propagation.
842
+ * Used by step and external revivers where real abort signal behavior is needed.
843
+ *
844
+ * @param value - The serialized abort controller/signal data
845
+ * @param ops - The ops array for tracking async work
846
+ * @param runId - The workflow run ID (for stream reads)
847
+ * @returns A real AbortController with patched abort() method
848
+ */
849
+ function reviveAbortController(value, ops, runId) {
850
+ const controller = new AbortController();
851
+ if (value.aborted) {
852
+ tagAbortPair(controller, value);
853
+ controller.abort(value.reason);
854
+ }
855
+ else if (value.streamName) {
856
+ const readerCancel = setupAbortStreamReader(controller, runId, value.streamName, ops);
857
+ tagAbortPair(controller, value, readerCancel);
858
+ }
859
+ else {
860
+ tagAbortPair(controller, value);
861
+ }
862
+ // Override abort() to also write stream + resume hook (for step-initiated abort)
863
+ const originalAbort = controller.abort.bind(controller);
864
+ controller.abort = (reason) => {
865
+ if (controller.signal.aborted)
866
+ return;
867
+ originalAbort(reason);
868
+ const ctx = contextStorage.getStore();
869
+ if (ctx) {
870
+ ctx.ops.push((async () => {
871
+ try {
872
+ // Dehydrate the abort payload through the same machinery the hook
873
+ // event uses so the `reason` round-trips with full type fidelity
874
+ // (DOMException, custom errors, etc.) and respects the run's
875
+ // encryption key — symmetric with what the suspension handler
876
+ // writes for workflow-initiated aborts.
877
+ const payload = await dehydrateStepArguments({ aborted: true, reason }, ctx.workflowMetadata.workflowRunId, ctx.encryptionKey);
878
+ const writable = new WorkflowServerWritableStream(ctx.workflowMetadata.workflowRunId, value.streamName);
879
+ const writer = writable.getWriter();
880
+ await writer.write(payload);
881
+ await writer.close();
882
+ }
883
+ catch {
884
+ // Best-effort stream write
885
+ }
886
+ })());
887
+ if (value.hookToken) {
888
+ ctx.ops.push((async () => {
889
+ try {
890
+ const { resumeHook: resumeHookFn } = await import('./runtime/resume-hook.js');
891
+ await resumeHookFn(value.hookToken, {
892
+ aborted: true,
893
+ reason,
894
+ });
895
+ }
896
+ catch {
897
+ // Best-effort hook resume — retry on next replay
898
+ }
899
+ })());
874
900
  }
875
- // Deserialize the instance using the custom deserializer
876
- return deserialize.call(cls, data);
877
- },
878
- Set: (value) => new global.Set(value),
879
- URL: (value) => new global.URL(value),
880
- URLSearchParams: (value) => new global.URLSearchParams(value === '.' ? '' : value),
881
- Uint8Array: (value) => {
882
- const ab = reviveArrayBuffer(value);
883
- return new global.Uint8Array(ab);
884
- },
885
- Uint8ClampedArray: (value) => {
886
- const ab = reviveArrayBuffer(value);
887
- return new global.Uint8ClampedArray(ab);
888
- },
889
- Uint16Array: (value) => {
890
- const ab = reviveArrayBuffer(value);
891
- return new global.Uint16Array(ab);
892
- },
893
- Uint32Array: (value) => {
894
- const ab = reviveArrayBuffer(value);
895
- return new global.Uint32Array(ab);
896
- },
901
+ }
902
+ };
903
+ return controller;
904
+ }
905
+ /**
906
+ * Revives just an AbortSignal without the patched abort() overhead.
907
+ * Used when only a signal (not a controller) was serialized.
908
+ */
909
+ function reviveAbortSignal(value, ops, runId) {
910
+ const controller = new AbortController();
911
+ if (value.aborted) {
912
+ tagAbortPair(controller, value);
913
+ controller.abort(value.reason);
914
+ }
915
+ else if (value.streamName) {
916
+ const readerCancel = setupAbortStreamReader(controller, runId, value.streamName, ops);
917
+ tagAbortPair(controller, value, readerCancel);
918
+ }
919
+ else {
920
+ tagAbortPair(controller, value);
921
+ }
922
+ return controller.signal;
923
+ }
924
+ /**
925
+ * Base revivers shared across all serialization boundaries.
926
+ * Composes: class + common revivers from the modular modules.
927
+ *
928
+ * This is exported because serialization-format.ts and other files reference it.
929
+ */
930
+ export function getCommonRevivers(global = globalThis) {
931
+ return {
932
+ ...getClassRevivers(global),
933
+ ...getCommonReviversFromModule(global),
897
934
  };
898
935
  }
899
936
  /**
@@ -909,18 +946,31 @@ export function getExternalRevivers(global = globalThis, ops, runId, cryptoKey)
909
946
  ...getCommonRevivers(global),
910
947
  // StepFunction should not be returned from workflows to clients
911
948
  StepFunction: () => {
912
- throw new Error('Step functions cannot be deserialized in client context. Step functions should not be returned from workflows.');
949
+ throw new SerializationError('Step functions cannot be deserialized in client context. Step functions should not be returned from workflows.', {
950
+ hint: 'A step function reference reached the client. Return a serializable value (e.g. the step result) instead of the step itself.',
951
+ });
913
952
  },
914
953
  WorkflowFunction: (value) => Object.assign(() => {
915
- throw new Error('Workflow functions cannot be called directly. Use start() to invoke them.');
954
+ throw new SerializationError('Workflow functions cannot be called directly. Use start() to invoke them.', {
955
+ hint: 'Wrap the workflow with `start(workflowFn, { ... })` from `workflow` to begin a run instead of invoking it like a normal function.',
956
+ });
916
957
  }, { workflowId: value.workflowId }),
917
958
  Request: (value) => {
918
- return new global.Request(value.url, {
959
+ const init = {
919
960
  method: value.method,
920
961
  headers: new global.Headers(value.headers),
921
962
  body: value.body,
922
963
  duplex: value.duplex,
923
- });
964
+ };
965
+ if (value.signal)
966
+ init.signal = value.signal;
967
+ const request = new global.Request(value.url, init);
968
+ // The Request constructor creates an internal signal copy, so the
969
+ // abort-internal symbols set by reviveAbortSignal don't propagate.
970
+ // Re-tag the request's own signal so cancelAbortReaders can find it.
971
+ if (value.signal)
972
+ copyAbortInternals(value.signal, request.signal);
973
+ return request;
924
974
  },
925
975
  Response: (value) => {
926
976
  // Note: Response constructor only accepts status, statusText, and headers
@@ -982,6 +1032,8 @@ export function getExternalRevivers(global = globalThis, ops, runId, cryptoKey)
982
1032
  pollWritableLock(serialize.writable, state);
983
1033
  return serialize.writable;
984
1034
  },
1035
+ AbortController: (value) => reviveAbortController(value, ops, runId),
1036
+ AbortSignal: (value) => reviveAbortSignal(value, ops, runId),
985
1037
  };
986
1038
  }
987
1039
  /**
@@ -993,27 +1045,11 @@ export function getExternalRevivers(global = globalThis, ops, runId, cryptoKey)
993
1045
  * @returns
994
1046
  */
995
1047
  export function getWorkflowRevivers(global = globalThis) {
996
- // Get the useStep function from the VM's globalThis
997
- // This is set up by the workflow runner in workflow.ts
998
- // Use Symbol.for directly to access the symbol on the global object
999
- const useStep = global[Symbol.for('WORKFLOW_USE_STEP')];
1000
1048
  return {
1001
1049
  ...getCommonRevivers(global),
1002
- // StepFunction reviver for workflow context - returns useStep wrapper
1003
- // This allows step functions passed as arguments to start() to be called directly
1004
- // from workflow code, just like step functions defined in the same file
1005
- StepFunction: (value) => {
1006
- const stepId = value.stepId;
1007
- const closureVars = value.closureVars;
1008
- if (!useStep) {
1009
- throw new Error('WORKFLOW_USE_STEP not found on global object. Step functions cannot be deserialized outside workflow context.');
1010
- }
1011
- if (closureVars) {
1012
- // For step functions with closure variables, create a wrapper that provides them
1013
- return useStep(stepId, () => closureVars);
1014
- }
1015
- return useStep(stepId);
1016
- },
1050
+ // StepFunction reviver for workflow context - uses the modular reviver
1051
+ // which calls WORKFLOW_USE_STEP from global to reconstruct step proxies
1052
+ ...getStepFunctionReviver(global),
1017
1053
  Request: (value) => {
1018
1054
  Object.setPrototypeOf(value, global.Request.prototype);
1019
1055
  const responseWritable = value.responseWritable;
@@ -1021,7 +1057,9 @@ export function getWorkflowRevivers(global = globalThis) {
1021
1057
  value[WEBHOOK_RESPONSE_WRITABLE] = responseWritable;
1022
1058
  delete value.responseWritable;
1023
1059
  value.respondWith = () => {
1024
- throw new Error('`respondWith()` must be called from within a step function');
1060
+ throw new SerializationError('`respondWith()` must be called from within a step function.', {
1061
+ hint: 'Move the `respondWith(...)` call inside a `"use step"` function — it cannot be invoked from a workflow context.',
1062
+ });
1025
1063
  };
1026
1064
  }
1027
1065
  return value;
@@ -1029,7 +1067,9 @@ export function getWorkflowRevivers(global = globalThis) {
1029
1067
  // Workflow function reviver for workflow context — returns a function-like
1030
1068
  // object with .workflowId that mimics what the SWC compiler produces,
1031
1069
  WorkflowFunction: (value) => Object.assign(() => {
1032
- throw new Error('Workflow functions cannot be called directly. Use start() to invoke them.');
1070
+ throw new SerializationError('Workflow functions cannot be called directly. Use start() to invoke them.', {
1071
+ hint: 'Wrap the workflow with `start(workflowFn, { ... })` from `workflow` to begin a run instead of invoking it like a normal function.',
1072
+ });
1033
1073
  }, { workflowId: value.workflowId }),
1034
1074
  Response: (value) => {
1035
1075
  Object.setPrototypeOf(value, global.Response.prototype);
@@ -1066,6 +1106,30 @@ export function getWorkflowRevivers(global = globalThis) {
1066
1106
  },
1067
1107
  });
1068
1108
  },
1109
+ // AbortController/AbortSignal revived inside the workflow VM. Use the
1110
+ // real WorkflowAbortSignal class so addEventListener('abort', fn) actually
1111
+ // fires when the signal aborts (the previous no-op stub silently dropped
1112
+ // listener registrations — silent correctness bug for natural patterns
1113
+ // like `signal.addEventListener('abort', fn)` after receiving a deserialized
1114
+ // signal). The signal does not own a hook subscription here — abort state
1115
+ // is delivered via the existing replay machinery on the source side.
1116
+ AbortController: (value) => {
1117
+ const signal = new WorkflowAbortSignal(value.streamName, value.hookToken);
1118
+ if (value.aborted)
1119
+ signal._setAborted(value.reason);
1120
+ return {
1121
+ [ABORT_STREAM_NAME]: value.streamName,
1122
+ [ABORT_HOOK_TOKEN]: value.hookToken,
1123
+ signal,
1124
+ abort: () => { },
1125
+ };
1126
+ },
1127
+ AbortSignal: (value) => {
1128
+ const signal = new WorkflowAbortSignal(value.streamName, value.hookToken);
1129
+ if (value.aborted)
1130
+ signal._setAborted(value.reason);
1131
+ return signal;
1132
+ },
1069
1133
  };
1070
1134
  }
1071
1135
  /**
@@ -1081,59 +1145,91 @@ function getStepRevivers(global = globalThis, ops, runId, cryptoKey) {
1081
1145
  return {
1082
1146
  ...getCommonRevivers(global),
1083
1147
  // StepFunction reviver for step context - returns raw step function
1084
- // with closure variable support via AsyncLocalStorage
1148
+ // with closure variable support via AsyncLocalStorage.
1149
+ //
1150
+ // Handles four independent flags from the serialized payload:
1151
+ // - `closureVars`: invoke the body inside an AsyncLocalStorage frame
1152
+ // so the SWC-emitted `WORKFLOW_STEP_CONTEXT_STORAGE` IIFE in the
1153
+ // hoisted body can pull the closure variables back out.
1154
+ // - `boundThis`: a `this` value captured by
1155
+ // `useStep(...).bind(this)` in the workflow bundle (lexical-`this`
1156
+ // arrow steps). The wrapper invokes the body via
1157
+ // `stepFn.apply(boundThis, args)` so the body sees the same
1158
+ // `this` it would have had in the workflow bundle. Property
1159
+ // presence — not truthiness — is significant because
1160
+ // `bind(null)` and `bind(undefined)` are both legal and should
1161
+ // round-trip faithfully.
1162
+ // - `boundArgs`: prefilled args from
1163
+ // `useStep(...).bind(thisArg, x, y)`. Prepended to the call args
1164
+ // so partial application survives serialization.
1085
1165
  StepFunction: (value) => {
1086
1166
  const stepId = value.stepId;
1087
1167
  const closureVars = value.closureVars;
1168
+ const hasBoundThis = 'boundThis' in value;
1169
+ const boundThis = hasBoundThis ? value.boundThis : undefined;
1170
+ const boundArgs = Array.isArray(value.boundArgs) ? value.boundArgs : [];
1088
1171
  const stepFn = getStepFunction(stepId);
1089
1172
  if (!stepFn) {
1090
- throw new Error(`Step function "${stepId}" not found. Make sure the step function is registered.`);
1173
+ throw new SerializationError(`Step function "${stepId}" not found. Make sure the step function is registered.`, {
1174
+ 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.',
1175
+ });
1091
1176
  }
1092
- // If closure variables were serialized, return a wrapper function
1093
- // that sets up AsyncLocalStorage context when invoked
1094
- if (closureVars) {
1095
- const wrappedStepFn = ((...args) => {
1096
- // Get the current context from AsyncLocalStorage
1177
+ // Fast path: nothing to wrap.
1178
+ if (!closureVars && !hasBoundThis && boundArgs.length === 0) {
1179
+ return stepFn;
1180
+ }
1181
+ const wrappedStepFn = function (...args) {
1182
+ const callThis = hasBoundThis ? boundThis : this;
1183
+ const callArgs = boundArgs.length > 0 ? [...boundArgs, ...args] : args;
1184
+ if (closureVars) {
1097
1185
  const currentContext = contextStorage.getStore();
1098
1186
  if (!currentContext) {
1099
- throw new Error('Cannot call step function with closure variables outside step context');
1187
+ throw new WorkflowRuntimeError('Cannot call step function with closure variables outside step context');
1100
1188
  }
1101
- // Create a new context with the closure variables merged in
1102
1189
  const newContext = {
1103
1190
  ...currentContext,
1104
1191
  closureVars,
1105
1192
  };
1106
- // Run the step function with the new context that includes closure vars
1107
- return contextStorage.run(newContext, () => stepFn(...args));
1108
- });
1109
- // Copy properties from original step function
1110
- Object.defineProperty(wrappedStepFn, 'name', {
1111
- value: stepFn.name,
1112
- });
1113
- Object.defineProperty(wrappedStepFn, 'stepId', {
1114
- value: stepId,
1115
- writable: false,
1116
- enumerable: false,
1117
- configurable: false,
1118
- });
1119
- if (stepFn.maxRetries !== undefined) {
1120
- wrappedStepFn.maxRetries = stepFn.maxRetries;
1193
+ return contextStorage.run(newContext, () => stepFn.apply(callThis, callArgs));
1121
1194
  }
1122
- return wrappedStepFn;
1195
+ return stepFn.apply(callThis, callArgs);
1196
+ };
1197
+ // Copy properties from original step function
1198
+ Object.defineProperty(wrappedStepFn, 'name', {
1199
+ value: stepFn.name,
1200
+ });
1201
+ Object.defineProperty(wrappedStepFn, 'stepId', {
1202
+ value: stepId,
1203
+ writable: false,
1204
+ enumerable: false,
1205
+ configurable: false,
1206
+ });
1207
+ if (stepFn.maxRetries !== undefined) {
1208
+ wrappedStepFn.maxRetries = stepFn.maxRetries;
1123
1209
  }
1124
- return stepFn;
1210
+ return wrappedStepFn;
1125
1211
  },
1126
1212
  WorkflowFunction: (value) => Object.assign(() => {
1127
- throw new Error('Workflow functions cannot be called directly. Use start() to invoke them.');
1213
+ throw new SerializationError('Workflow functions cannot be called directly. Use start() to invoke them.', {
1214
+ hint: 'Wrap the workflow with `start(workflowFn, { ... })` from `workflow` to begin a run instead of invoking it like a normal function.',
1215
+ });
1128
1216
  }, { workflowId: value.workflowId }),
1129
1217
  Request: (value) => {
1130
1218
  const responseWritable = value.responseWritable;
1131
- const request = new global.Request(value.url, {
1219
+ const init = {
1132
1220
  method: value.method,
1133
1221
  headers: new global.Headers(value.headers),
1134
1222
  body: value.body,
1135
1223
  duplex: value.duplex,
1136
- });
1224
+ };
1225
+ if (value.signal)
1226
+ init.signal = value.signal;
1227
+ const request = new global.Request(value.url, init);
1228
+ // The Request constructor creates an internal signal copy, so the
1229
+ // abort-internal symbols set by reviveAbortSignal don't propagate.
1230
+ // Re-tag the request's own signal so cancelAbortReaders can find it.
1231
+ if (value.signal)
1232
+ copyAbortInternals(value.signal, request.signal);
1137
1233
  if (responseWritable) {
1138
1234
  request.respondWith = async (response) => {
1139
1235
  const writer = responseWritable.getWriter();
@@ -1203,209 +1299,256 @@ function getStepRevivers(global = globalThis, ops, runId, cryptoKey) {
1203
1299
  pollWritableLock(serialize.writable, state);
1204
1300
  return serialize.writable;
1205
1301
  },
1302
+ AbortController: (value) => reviveAbortController(value, ops, runId),
1303
+ AbortSignal: (value) => reviveAbortSignal(value, ops, runId),
1206
1304
  };
1207
1305
  }
1208
1306
  // ============================================================================
1209
1307
  // Encryption Helpers
1210
1308
  // ============================================================================
1309
+ // These delegate to the modular `encrypt`/`decrypt` from `./serialization/encryption.js`
1310
+ // but are kept as named exports for backwards compatibility with existing consumers.
1211
1311
  /**
1212
1312
  * Encrypt data if the world supports encryption.
1213
1313
  * Returns original data if encryption is not available.
1214
1314
  *
1215
- * @param data - Serialized data to encrypt
1216
- * @param key - Encryption key (undefined to skip encryption)
1217
- * @param context - Encryption context with runId
1218
- * @returns Encrypted data if encryption available, original data otherwise
1315
+ * @deprecated Use `encrypt` from `./serialization/encryption.js` instead.
1219
1316
  */
1220
1317
  export async function maybeEncrypt(data, key) {
1221
- if (!key)
1222
- return data;
1223
- const encrypted = await aesGcmEncrypt(key, data);
1224
- return encodeWithFormatPrefix(SerializationFormat.ENCRYPTED, encrypted);
1318
+ return (await encrypt(data, key));
1225
1319
  }
1226
1320
  /**
1227
1321
  * Decrypt data if it has the 'encr' prefix.
1228
1322
  *
1229
- * @param data - Data that may be encrypted
1230
- * @param key - Encryption key (undefined if no key available)
1231
- * @returns Decrypted data if encrypted, original data otherwise
1232
- * @throws {WorkflowRuntimeError} If the data is encrypted but no key is
1233
- * available. Callers (e.g., `Run.pollReturnValue()`, `hydrateStepReturnValue`)
1234
- * should be aware this can surface as a rejected promise during key rotation
1235
- * or misconfiguration scenarios.
1323
+ * @deprecated Use `decrypt` from `./serialization/encryption.js` instead.
1236
1324
  */
1237
1325
  export async function maybeDecrypt(data, key) {
1238
- // Legacy specVersion 1 runs stored event data as plain JSON arrays
1239
- // (not binary Uint8Array). Pass through as-is for backwards compat.
1240
- if (!(data instanceof Uint8Array)) {
1241
- return data;
1242
- }
1243
- if (isEncrypted(data)) {
1244
- if (!key) {
1245
- throw new WorkflowRuntimeError('Encrypted data encountered but no encryption key is available. ' +
1246
- 'Encryption is not configured or no key was provided for this run.');
1247
- }
1248
- // Strip the 'encr' format prefix — the prefix is a core framing concern
1249
- const { payload } = decodeFormatPrefix(data);
1250
- return aesGcmDecrypt(key, payload);
1251
- }
1252
- return data;
1326
+ return decrypt(data, key);
1253
1327
  }
1254
1328
  // ============================================================================
1255
1329
  // Dehydrate / Hydrate Functions
1256
1330
  // ============================================================================
1331
+ // These delegate to the modular mode modules (workflow, step, client) passing
1332
+ // mode-specific stream and Request/Response reducers/revivers as extra options.
1333
+ // The v1Compat path is handled inline before delegating to the modules.
1257
1334
  /**
1258
1335
  * Called from the `start()` function to serialize the workflow arguments
1259
1336
  * into a format that can be saved to the database and then hydrated from
1260
1337
  * within the workflow execution environment.
1261
- *
1262
- * @param value - The value to serialize
1263
- * @param runId - The workflow run ID (required for encryption context)
1264
- * @param key - Encryption key (undefined to skip encryption)
1265
- * @param ops - Promise array for stream operations
1266
- * @param global - Global object for serialization context
1267
- * @param v1Compat - Enable legacy v1 compatibility mode
1268
- * @returns The dehydrated value as binary data (Uint8Array) with format prefix
1269
1338
  */
1270
1339
  export async function dehydrateWorkflowArguments(value, runId, key, ops = [], global = globalThis, v1Compat = false) {
1271
- try {
1340
+ if (v1Compat) {
1272
1341
  const str = stringify(value, getExternalReducers(global, ops, runId, key));
1273
- if (v1Compat) {
1274
- return revive(str);
1275
- }
1276
- const payload = new TextEncoder().encode(str);
1277
- const serialized = encodeWithFormatPrefix(SerializationFormat.DEVALUE_V1, payload);
1278
- // Encrypt if world supports encryption
1279
- return maybeEncrypt(serialized, key);
1342
+ return revive(str);
1343
+ }
1344
+ try {
1345
+ return await clientModule.serialize(value, key, {
1346
+ global,
1347
+ extraReducers: getStreamAndRequestReducers(getExternalReducers(global, ops, runId, key)),
1348
+ });
1280
1349
  }
1281
1350
  catch (error) {
1282
- throw new WorkflowRuntimeError(formatSerializationError('workflow arguments', error), { slug: 'serialization-failed', cause: error });
1351
+ const cause = unwrapSerializationCause(error);
1352
+ const { message, hint } = formatSerializationError('workflow arguments', cause);
1353
+ throw new SerializationError(message, { hint, cause });
1283
1354
  }
1284
1355
  }
1285
1356
  /**
1286
1357
  * Called from workflow execution environment to hydrate the workflow
1287
1358
  * arguments from the database at the start of workflow execution.
1288
- *
1289
- * @param value - Binary serialized data (Uint8Array) with format prefix
1290
- * @param _runId - Workflow run ID (reserved for future decryption context; decryption is currently driven solely by the provided key)
1291
- * @param key - Encryption key (undefined to skip decryption)
1292
- * @param global - Global object for deserialization context
1293
- * @param extraRevivers - Additional revivers for custom types
1294
- * @returns The hydrated value
1295
1359
  */
1296
1360
  export async function hydrateWorkflowArguments(value, _runId, key, global = globalThis, extraRevivers = {}) {
1297
- // Decrypt if needed
1298
- const decrypted = await maybeDecrypt(value, key);
1299
- // Legacy specVersion 1 runs stored data as plain JSON arrays (not binary).
1300
- // These pass through maybeDecrypt unchanged and are deserialized directly
1301
- // via devalue's unflatten().
1302
- if (!(decrypted instanceof Uint8Array)) {
1303
- return unflatten(decrypted, {
1304
- ...getWorkflowRevivers(global),
1361
+ return workflowModule.deserialize(await maybeDecrypt(value, key), {
1362
+ global,
1363
+ extraRevivers: {
1364
+ ...getStreamAndRequestRevivers(getWorkflowRevivers(global)),
1305
1365
  ...extraRevivers,
1366
+ },
1367
+ });
1368
+ }
1369
+ /**
1370
+ * Dehydrate workflow return value for storage.
1371
+ */
1372
+ export async function dehydrateWorkflowReturnValue(value, _runId, key, global = globalThis, v1Compat = false) {
1373
+ if (v1Compat) {
1374
+ const str = stringify(value, getWorkflowReducers(global));
1375
+ return revive(str);
1376
+ }
1377
+ try {
1378
+ return await stepModule.serialize(value, key, {
1379
+ global,
1380
+ extraReducers: getStreamAndRequestReducers(getWorkflowReducers(global)),
1306
1381
  });
1307
1382
  }
1308
- const { format, payload } = decodeFormatPrefix(decrypted);
1309
- if (format === SerializationFormat.DEVALUE_V1) {
1310
- const str = new TextDecoder().decode(payload);
1311
- const obj = parse(str, {
1312
- ...getWorkflowRevivers(global),
1383
+ catch (error) {
1384
+ const cause = unwrapSerializationCause(error);
1385
+ const { message, hint } = formatSerializationError('workflow return value', cause);
1386
+ throw new SerializationError(message, { hint, cause });
1387
+ }
1388
+ }
1389
+ /**
1390
+ * Called from the client side to hydrate the workflow return value
1391
+ * of a completed workflow run.
1392
+ */
1393
+ export async function hydrateWorkflowReturnValue(value, runId, key, ops = [], global = globalThis, extraRevivers = {}) {
1394
+ return clientModule.deserialize(value, key, {
1395
+ global,
1396
+ extraRevivers: {
1397
+ ...getStreamAndRequestRevivers(getExternalRevivers(global, ops, runId, key)),
1313
1398
  ...extraRevivers,
1399
+ },
1400
+ });
1401
+ }
1402
+ /**
1403
+ * Called from the workflow handler when a step is being created.
1404
+ * Dehydrates values from within the workflow execution environment.
1405
+ */
1406
+ export async function dehydrateStepArguments(value, _runId, key, global = globalThis, v1Compat = false) {
1407
+ if (v1Compat) {
1408
+ const str = stringify(value, getWorkflowReducers(global));
1409
+ return revive(str);
1410
+ }
1411
+ try {
1412
+ return await stepModule.serialize(value, key, {
1413
+ global,
1414
+ extraReducers: getStreamAndRequestReducers(getWorkflowReducers(global)),
1314
1415
  });
1315
- return obj;
1316
1416
  }
1317
- throw new Error(`Unsupported serialization format: ${format}`);
1417
+ catch (error) {
1418
+ const cause = unwrapSerializationCause(error);
1419
+ const { message, hint } = formatSerializationError('step arguments', cause);
1420
+ throw new SerializationError(message, { hint, cause });
1421
+ }
1318
1422
  }
1319
1423
  /**
1320
- * Dehydrate workflow return value for storage.
1424
+ * Called from the step handler to hydrate the arguments of a step
1425
+ * from the database at the start of the step execution.
1426
+ */
1427
+ export async function hydrateStepArguments(value, runId, key, ops = [], global = globalThis, extraRevivers = {}) {
1428
+ return stepModule.deserialize(value, key, {
1429
+ global,
1430
+ extraRevivers: {
1431
+ ...getStreamAndRequestRevivers(getStepRevivers(global, ops, runId, key)),
1432
+ ...extraRevivers,
1433
+ },
1434
+ });
1435
+ }
1436
+ /**
1437
+ * Called from the step handler when a step has completed.
1438
+ * Dehydrates values from within the step execution environment.
1439
+ */
1440
+ export async function dehydrateStepReturnValue(value, runId, key, ops = [], global = globalThis, v1Compat = false) {
1441
+ if (v1Compat) {
1442
+ const str = stringify(value, getStepReducers(global, ops, runId, key));
1443
+ return revive(str);
1444
+ }
1445
+ try {
1446
+ return await stepModule.serialize(value, key, {
1447
+ global,
1448
+ extraReducers: getStreamAndRequestReducers(getStepReducers(global, ops, runId, key)),
1449
+ });
1450
+ }
1451
+ catch (error) {
1452
+ const cause = unwrapSerializationCause(error);
1453
+ const { message, hint } = formatSerializationError('step return value', cause);
1454
+ throw new SerializationError(message, { hint, cause });
1455
+ }
1456
+ }
1457
+ /**
1458
+ * Called from the step handler when a step throws. Dehydrates the thrown
1459
+ * value from within the step execution environment into a format that can
1460
+ * be saved to the database in a `step_failed` or `step_retrying` event.
1321
1461
  *
1322
- * @param value - The value to serialize
1462
+ * Any JavaScript value can be thrown (strings, numbers, objects, Errors,
1463
+ * Error subclasses), so the same serialization pipeline used for step
1464
+ * arguments and return values is applied here.
1465
+ *
1466
+ * @param value - The thrown value to serialize (can be any type)
1323
1467
  * @param runId - Run ID for encryption context
1324
1468
  * @param key - Encryption key (undefined to skip encryption)
1469
+ * @param ops - Promise array for stream operations
1325
1470
  * @param global - Global object for serialization context
1326
1471
  * @returns The dehydrated value as binary data (Uint8Array) with format prefix
1327
1472
  */
1328
- export async function dehydrateWorkflowReturnValue(value, _runId, key, global = globalThis, v1Compat = false) {
1473
+ export async function dehydrateStepError(value, runId, key, ops = [], global = globalThis) {
1329
1474
  try {
1330
- const str = stringify(value, getWorkflowReducers(global));
1331
- if (v1Compat) {
1332
- return revive(str);
1333
- }
1475
+ const str = stringify(value, getStepReducers(global, ops, runId, key));
1334
1476
  const payload = new TextEncoder().encode(str);
1335
1477
  const serialized = encodeWithFormatPrefix(SerializationFormat.DEVALUE_V1, payload);
1336
- // Encrypt if world supports encryption
1337
- return maybeEncrypt(serialized, key);
1478
+ return (await maybeEncrypt(serialized, key));
1338
1479
  }
1339
1480
  catch (error) {
1340
- throw new WorkflowRuntimeError(formatSerializationError('workflow return value', error), { slug: 'serialization-failed', cause: error });
1481
+ const cause = unwrapSerializationCause(error);
1482
+ const { message, hint } = formatSerializationError('step error', cause);
1483
+ throw new SerializationError(message, { hint, cause });
1341
1484
  }
1342
1485
  }
1343
1486
  /**
1344
- * Called from the client side (i.e. the execution environment where
1345
- * the workflow run was initiated from) to hydrate the workflow
1346
- * return value of a completed workflow run.
1487
+ * Called from the workflow handler when replaying the event log of a
1488
+ * `step_failed` or `step_retrying` event. Hydrates the thrown value from
1489
+ * the database so the workflow can see the original thrown value.
1347
1490
  *
1348
1491
  * @param value - Binary serialized data (Uint8Array) with format prefix
1349
1492
  * @param runId - Run ID for decryption context
1350
1493
  * @param key - Encryption key (undefined to skip decryption)
1351
- * @param ops - Promise array for stream operations
1352
1494
  * @param global - Global object for deserialization context
1353
1495
  * @param extraRevivers - Additional revivers for custom types
1354
- * @returns The hydrated return value, ready to be consumed by the client
1496
+ * @returns The hydrated thrown value, ready to reject the step promise
1355
1497
  */
1356
- export async function hydrateWorkflowReturnValue(value, runId, key, ops = [], global = globalThis, extraRevivers = {}) {
1357
- // Decrypt if needed
1498
+ export async function hydrateStepError(value, _runId, key, global = globalThis, extraRevivers = {}) {
1358
1499
  const decrypted = await maybeDecrypt(value, key);
1359
- // Legacy specVersion 1 runs stored data as plain JSON arrays (not binary).
1360
- // These pass through maybeDecrypt unchanged and are deserialized directly
1361
- // via devalue's unflatten().
1362
1500
  if (!(decrypted instanceof Uint8Array)) {
1501
+ // Treated as a devalue "flattened" array. In production this branch is
1502
+ // exercised by legacy code paths that bypassed `dehydrateStepError`; the
1503
+ // SDK version is pinned per workflow run via skew protection, so a
1504
+ // current-version producer always emits a Uint8Array here. If a
1505
+ // misshapen value reaches us, `unflatten` throws — that's intentional:
1506
+ // the higher-level hydration helpers (`hydrateStepIO`,
1507
+ // `hydrateResourceIO`) already wrap us in a try/catch that leaves the
1508
+ // field un-hydrated for o11y display, and surfacing the throw to logs
1509
+ // is more debuggable than silently masking the unsupported shape.
1363
1510
  return unflatten(decrypted, {
1364
- ...getExternalRevivers(global, ops, runId, key),
1511
+ ...getWorkflowRevivers(global),
1365
1512
  ...extraRevivers,
1366
1513
  });
1367
1514
  }
1368
1515
  const { format, payload } = decodeFormatPrefix(decrypted);
1369
1516
  if (format === SerializationFormat.DEVALUE_V1) {
1370
1517
  const str = new TextDecoder().decode(payload);
1371
- const obj = parse(str, {
1372
- ...getExternalRevivers(global, ops, runId, key),
1518
+ return parse(str, {
1519
+ ...getWorkflowRevivers(global),
1373
1520
  ...extraRevivers,
1374
1521
  });
1375
- return obj;
1376
1522
  }
1377
1523
  throw new Error(`Unsupported serialization format: ${format}`);
1378
1524
  }
1379
1525
  /**
1380
- * Called from the workflow handler when a step is being created.
1381
- * Dehydrates values from within the workflow execution environment
1382
- * into a format that can be saved to the database.
1526
+ * Called from the workflow handler when the workflow itself throws.
1527
+ * Dehydrates the thrown value from within the workflow execution environment
1528
+ * into a format that can be saved to the database in a `run_failed` event.
1383
1529
  *
1384
- * @param value - The value to serialize
1530
+ * @param value - The thrown value to serialize (can be any type)
1385
1531
  * @param runId - Run ID for encryption context
1386
1532
  * @param key - Encryption key (undefined to skip encryption)
1387
1533
  * @param global - Global object for serialization context
1388
- * @param v1Compat - Enable legacy v1 compatibility mode
1389
1534
  * @returns The dehydrated value as binary data (Uint8Array) with format prefix
1390
1535
  */
1391
- export async function dehydrateStepArguments(value, _runId, key, global = globalThis, v1Compat = false) {
1536
+ export async function dehydrateRunError(value, _runId, key, global = globalThis) {
1392
1537
  try {
1393
1538
  const str = stringify(value, getWorkflowReducers(global));
1394
- if (v1Compat) {
1395
- return revive(str);
1396
- }
1397
1539
  const payload = new TextEncoder().encode(str);
1398
1540
  const serialized = encodeWithFormatPrefix(SerializationFormat.DEVALUE_V1, payload);
1399
- // Encrypt if world supports encryption
1400
- return maybeEncrypt(serialized, key);
1541
+ return (await maybeEncrypt(serialized, key));
1401
1542
  }
1402
1543
  catch (error) {
1403
- throw new WorkflowRuntimeError(formatSerializationError('step arguments', error), { slug: 'serialization-failed', cause: error });
1544
+ const cause = unwrapSerializationCause(error);
1545
+ const { message, hint } = formatSerializationError('run error', cause);
1546
+ throw new SerializationError(message, { hint, cause });
1404
1547
  }
1405
1548
  }
1406
1549
  /**
1407
- * Called from the step handler to hydrate the arguments of a step
1408
- * from the database at the start of the step execution.
1550
+ * Called from the client side (or observability tools) to hydrate the run
1551
+ * error value of a failed workflow run.
1409
1552
  *
1410
1553
  * @param value - Binary serialized data (Uint8Array) with format prefix
1411
1554
  * @param runId - Run ID for decryption context
@@ -1413,59 +1556,31 @@ export async function dehydrateStepArguments(value, _runId, key, global = global
1413
1556
  * @param ops - Promise array for stream operations
1414
1557
  * @param global - Global object for deserialization context
1415
1558
  * @param extraRevivers - Additional revivers for custom types
1416
- * @returns The hydrated value, ready to be consumed by the step user-code function
1559
+ * @returns The hydrated thrown value, ready to be consumed by the client
1417
1560
  */
1418
- export async function hydrateStepArguments(value, runId, key, ops = [], global = globalThis, extraRevivers = {}) {
1419
- // Decrypt if needed
1561
+ export async function hydrateRunError(value, runId, key, ops = [], global = globalThis, extraRevivers = {}) {
1420
1562
  const decrypted = await maybeDecrypt(value, key);
1421
- // Legacy specVersion 1 runs stored data as plain JSON arrays (not binary).
1422
- // These pass through maybeDecrypt unchanged and are deserialized directly
1423
- // via devalue's unflatten().
1424
1563
  if (!(decrypted instanceof Uint8Array)) {
1564
+ // See the matching note in `hydrateStepError`: this branch is for
1565
+ // devalue flattened arrays from legacy callers; current SDK versions
1566
+ // always emit a Uint8Array, and a misshapen value here intentionally
1567
+ // throws via `unflatten` so the surrounding try/catch in o11y helpers
1568
+ // surfaces the issue rather than masking it.
1425
1569
  return unflatten(decrypted, {
1426
- ...getStepRevivers(global, ops, runId, key),
1570
+ ...getExternalRevivers(global, ops, runId, key),
1427
1571
  ...extraRevivers,
1428
1572
  });
1429
1573
  }
1430
1574
  const { format, payload } = decodeFormatPrefix(decrypted);
1431
1575
  if (format === SerializationFormat.DEVALUE_V1) {
1432
1576
  const str = new TextDecoder().decode(payload);
1433
- const obj = parse(str, {
1434
- ...getStepRevivers(global, ops, runId, key),
1577
+ return parse(str, {
1578
+ ...getExternalRevivers(global, ops, runId, key),
1435
1579
  ...extraRevivers,
1436
1580
  });
1437
- return obj;
1438
1581
  }
1439
1582
  throw new Error(`Unsupported serialization format: ${format}`);
1440
1583
  }
1441
- /**
1442
- * Called from the step handler when a step has completed.
1443
- * Dehydrates values from within the step execution environment
1444
- * into a format that can be saved to the database.
1445
- *
1446
- * @param value - The value to serialize
1447
- * @param runId - Run ID for encryption context
1448
- * @param key - Encryption key (undefined to skip encryption)
1449
- * @param ops - Promise array for stream operations
1450
- * @param global - Global object for serialization context
1451
- * @param v1Compat - Enable legacy v1 compatibility mode
1452
- * @returns The dehydrated value as binary data (Uint8Array) with format prefix
1453
- */
1454
- export async function dehydrateStepReturnValue(value, runId, key, ops = [], global = globalThis, v1Compat = false) {
1455
- try {
1456
- const str = stringify(value, getStepReducers(global, ops, runId, key));
1457
- if (v1Compat) {
1458
- return revive(str);
1459
- }
1460
- const payload = new TextEncoder().encode(str);
1461
- const serialized = encodeWithFormatPrefix(SerializationFormat.DEVALUE_V1, payload);
1462
- // Encrypt if world supports encryption
1463
- return maybeEncrypt(serialized, key);
1464
- }
1465
- catch (error) {
1466
- throw new WorkflowRuntimeError(formatSerializationError('step return value', error), { slug: 'serialization-failed', cause: error });
1467
- }
1468
- }
1469
1584
  /**
1470
1585
  * Called from the workflow handler when replaying the event log of a `step_completed` event.
1471
1586
  * Hydrates the return value of a step from the database.
@@ -1475,28 +1590,53 @@ export async function dehydrateStepReturnValue(value, runId, key, ops = [], glob
1475
1590
  * @param key - Encryption key (undefined to skip decryption)
1476
1591
  * @param global - Global object for deserialization context
1477
1592
  * @param extraRevivers - Additional revivers for custom types
1478
- * @returns The hydrated return value of a step, ready to be consumed by the workflow handler
1593
+ * Called from the workflow handler when replaying the event log
1594
+ * of a `step_completed` event.
1479
1595
  */
1480
1596
  export async function hydrateStepReturnValue(value, _runId, key, global = globalThis, extraRevivers = {}) {
1481
- // Decrypt if needed
1482
- const decrypted = await maybeDecrypt(value, key);
1483
- // Legacy specVersion 1 runs stored data as plain JSON arrays (not binary).
1484
- // These pass through maybeDecrypt unchanged and are deserialized directly
1485
- // via devalue's unflatten().
1486
- if (!(decrypted instanceof Uint8Array)) {
1487
- return unflatten(decrypted, {
1488
- ...getWorkflowRevivers(global),
1597
+ return workflowModule.deserialize(await maybeDecrypt(value, key), {
1598
+ global,
1599
+ extraRevivers: {
1600
+ ...getStreamAndRequestRevivers(getWorkflowRevivers(global)),
1489
1601
  ...extraRevivers,
1490
- });
1602
+ },
1603
+ });
1604
+ }
1605
+ // ---- Helpers to extract stream/Request/Response reducers and revivers ----
1606
+ // The mode-specific get*Reducers/get*Revivers functions return objects that
1607
+ // include both "common" entries (Date, Error, Map, etc.) and mode-specific
1608
+ // entries (ReadableStream, WritableStream, Request, Response, StepFunction).
1609
+ // The common entries are already composed by the codec. We only need to
1610
+ // pass through the mode-specific entries as extraReducers/extraRevivers.
1611
+ const STREAM_AND_REQUEST_KEYS = [
1612
+ 'ReadableStream',
1613
+ 'WritableStream',
1614
+ 'Request',
1615
+ 'Response',
1616
+ 'StepFunction',
1617
+ // Wire AbortController/AbortSignal through the client serialization path so
1618
+ // signals reachable via Request.signal (or as direct arguments) get their
1619
+ // dedicated reducer. Without this, devalue falls back to its arbitrary-POJO
1620
+ // path and fails for any signal the Request reducer forwards.
1621
+ 'AbortController',
1622
+ 'AbortSignal',
1623
+ ];
1624
+ function getStreamAndRequestReducers(allReducers) {
1625
+ const extra = {};
1626
+ for (const key of STREAM_AND_REQUEST_KEYS) {
1627
+ if (key in allReducers) {
1628
+ extra[key] = allReducers[key];
1629
+ }
1491
1630
  }
1492
- const { format, payload } = decodeFormatPrefix(decrypted);
1493
- if (format === SerializationFormat.DEVALUE_V1) {
1494
- const str = new TextDecoder().decode(payload);
1495
- return parse(str, {
1496
- ...getWorkflowRevivers(global),
1497
- ...extraRevivers,
1498
- });
1631
+ return extra;
1632
+ }
1633
+ function getStreamAndRequestRevivers(allRevivers) {
1634
+ const extra = {};
1635
+ for (const key of STREAM_AND_REQUEST_KEYS) {
1636
+ if (key in allRevivers) {
1637
+ extra[key] = allRevivers[key];
1638
+ }
1499
1639
  }
1500
- throw new Error(`Unsupported serialization format: ${format}`);
1640
+ return extra;
1501
1641
  }
1502
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VyaWFsaXphdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9zZXJpYWxpemF0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDbEMsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDeEQsT0FBTyxFQUFFLG9CQUFvQixFQUFFLGtCQUFrQixFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDM0UsT0FBTyxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUNwRSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDeEMsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDakUsT0FBTyxFQUNMLE9BQU8sSUFBSSxhQUFhLEVBQ3hCLE9BQU8sSUFBSSxhQUFhLEdBRXpCLE1BQU0saUJBQWlCLENBQUM7QUFhekIsT0FBTyxFQUNMLG9CQUFvQixFQUNwQixhQUFhLEVBQ2IsZ0JBQWdCLEVBQ2hCLGdCQUFnQixHQUNqQixNQUFNLHVCQUF1QixDQUFDO0FBQy9CLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDNUMsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUMvQyxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDOUMsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQzNELE9BQU8sRUFDTCxnQkFBZ0IsRUFDaEIsV0FBVyxFQUNYLGtCQUFrQixFQUNsQixrQkFBa0IsRUFDbEIseUJBQXlCLEdBQzFCLE1BQU0sY0FBYyxDQUFDO0FBRXRCLCtFQUErRTtBQUMvRSxxQ0FBcUM7QUFDckMsK0VBQStFO0FBQy9FLEVBQUU7QUFDRiw0RUFBNEU7QUFD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bnRlbnQiOlsiaW1wb3J0IHsgdHlwZXMgfSBmcm9tICdub2RlOnV0aWwnO1xuaW1wb3J0IHsgV29ya2Zsb3dSdW50aW1lRXJyb3IgfSBmcm9tICdAd29ya2Zsb3cvZXJyb3JzJztcbmltcG9ydCB7IFdPUktGTE9XX0RFU0VSSUFMSVpFLCBXT1JLRkxPV19TRVJJQUxJWkUgfSBmcm9tICdAd29ya2Zsb3cvc2VyZGUnO1xuaW1wb3J0IHsgRGV2YWx1ZUVycm9yLCBwYXJzZSwgc3RyaW5naWZ5LCB1bmZsYXR0ZW4gfSBmcm9tICdkZXZhbHVlJztcbmltcG9ydCB7IG1vbm90b25pY0ZhY3RvcnkgfSBmcm9tICd1bGlkJztcbmltcG9ydCB7IGdldFNlcmlhbGl6YXRpb25DbGFzcyB9IGZyb20gJy4vY2xhc3Mtc2VyaWFsaXphdGlvbi5qcyc7XG5pbXBvcnQge1xuICBkZWNyeXB0IGFzIGFlc0djbURlY3J5cHQsXG4gIGVuY3J5cHQgYXMgYWVzR2NtRW5jcnlwdCxcbiAgdHlwZSBDcnlwdG9LZXksXG59IGZyb20gJy4vZW5jcnlwdGlvbi5qcyc7XG5cbi8qKlxuICogRW5jcnlwdGlvbiBrZXkgcGFyYW1ldGVyIHR5cGUuIEFjY2VwdHMgYSByZXNvbHZlZCBrZXksIHVuZGVmaW5lZCAobm8gZW5jcnlwdGlvbiksXG4gKiBvciBhIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byBlaXRoZXIuIFRoaXMgYWxsb3dzIHN5bmNocm9ub3VzIGZ1bmN0aW9uIHNpZ25hdHVyZXNcbiAqIChlLmcuLCBnZXRSZWFkYWJsZSgpKSB0byB0aHJlYWQgdGhlIGtleSB0aHJvdWdoIHdpdGhvdXQgYXdhaXRpbmcgaXQg4oCUIHRoZSBwcm9taXNlXG4gKiBpcyByZXNvbHZlZCBsYXppbHkgaW5zaWRlIHRoZSBmaXJzdCBhc3luYyB0cmFuc2Zvcm0oKSBjYWxsLlxuICovXG5leHBvcnQgdHlwZSBFbmNyeXB0aW9uS2V5UGFyYW0gPVxuICB8IENyeXB0b0tleVxuICB8IHVuZGVmaW5lZFxuICB8IFByb21pc2U8Q3J5cHRvS2V5IHwgdW5kZWZpbmVkPjtcblxuaW1wb3J0IHtcbiAgY3JlYXRlRmx1c2hhYmxlU3RhdGUsXG4gIGZsdXNoYWJsZVBpcGUsXG4gIHBvbGxSZWFkYWJsZUxvY2ssXG4gIHBvbGxXcml0YWJsZUxvY2ssXG59IGZyb20gJy4vZmx1c2hhYmxlLXN0cmVhbS5qcyc7XG5pbXBvcnQgeyBydW50aW1lTG9nZ2VyIH0gZnJvbSAnLi9sb2dnZXIuanMnO1xuaW1wb3J0IHsgZ2V0U3RlcEZ1bmN0aW9uIH0gZnJvbSAnLi9wcml2YXRlLmpzJztcbmltcG9ydCB7IGdldFdvcmxkIH0gZnJvbSAnLi9ydW50aW1lL3dvcmxkLmpzJztcbmltcG9ydCB7IGNvbnRleHRTdG9yYWdlIH0gZnJvbSAnLi9zdGVwL2NvbnRleHQtc3RvcmFnZS5qcyc7XG5pbXBvcnQge1xuICBCT0RZX0lOSVRfU1lNQk9MLFxuICBTVEFCTEVfVUxJRCxcbiAgU1RSRUFNX05BTUVfU1lNQk9MLFxuICBTVFJFQU1fVFlQRV9TWU1CT0wsXG4gIFdFQkhPT0tfUkVTUE9OU0VfV1JJVEFCTEUsXG59IGZyb20gJy4vc3ltYm9scy5qcyc7XG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIFNlcmlhbGl6YXRpb24gRm9ybWF0IFByZWZpeCBTeXN0ZW1cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vXG4vLyBBbGwgc2VyaWFsaXplZCBwYXlsb2FkcyBhcmUgcHJlZml4ZWQgd2l0aCBhIDQtYnl0ZSBmb3JtYXQgaWRlbnRpZmllciB0aGF0XG4vLyBhbGxvd3MgdGhlIGNsaWVudCB0byBkZXRlcm1pbmUgaG93IHRvIGRlY29kZSB0aGUgcGF5bG9hZC4gVGhpcyBlbmFibGVzOlxuLy9cbi8vIDEuIFNlbGYtZGVzY3JpYmluZyBwYXlsb2FkcyAtIFRoZSBXb3JsZCBsYXllciBpcyBhZ25vc3RpYyB0byBzZXJpYWxpemF0aW9uIGZvcm1hdFxuLy8gMi4gR3JhZHVhbCBtaWdyYXRpb24gLSBPbGQgcnVucyBrZWVwIHdvcmtpbmcsIG5ldyBydW5zIGNhbiB1c2UgbmV3IGZvcm1hdHNcbi8vIDMuIENvbXBvc2FiaWxpdHkgLSBFbmNyeXB0aW9uIGNhbiB3cmFwIGFueSBmb3JtYXQgKGUuZy4sIFwiZW5jclwiIHdyYXBwaW5nIFwiZGV2bFwiKVxuLy8gNC4gRGVidWdnaW5nIC0gUmF3IGRhdGEgaW5zcGVjdGlvbiBpbW1lZGlhdGVseSByZXZlYWxzIHRoZSBmb3JtYXRcbi8vXG4vLyBGb3JtYXQ6IFs0IGJ5dGVzOiBmb3JtYXQgaWRlbnRpZmllcl1bcGF5bG9hZF1cbi8vXG4vLyBUaGUgNC1jaGFyYWN0ZXIgcHJlZml4IGNvbnZlbnRpb24gbWF0Y2hlcyBvdGhlciB3b3JrZmxvdyBJRHMgKHdydW4sIHN0ZXAsIHdhaXQsIGV0Yy4pXG4vL1xuLy8gQ3VycmVudCBmb3JtYXRzOlxuLy8gLSBcImRldmxcIiAtIGRldmFsdWUgc3RyaW5naWZ5L3BhcnNlIHdpdGggVGV4dEVuY29kZXIvVGV4dERlY29kZXIgKGN1cnJlbnQgZGVmYXVsdClcbi8vIC0gXCJlbmNyXCIgLSBFbmNyeXB0ZWQgcGF5bG9hZCAoaW5uZXIgcGF5bG9hZCBoYXMgaXRzIG93biBmb3JtYXQgcHJlZml4KVxuLy9cbi8vIEZ1dHVyZSBmb3JtYXRzIChyZXNlcnZlZCk6XG4vLyAtIFwiY2JvclwiIC0gQ0JPUiBiaW5hcnkgc2VyaWFsaXphdGlvblxuXG4vKipcbiAqIEtub3duIHNlcmlhbGl6YXRpb24gZm9ybWF0IGlkZW50aWZpZXJzLlxuICogRWFjaCBmb3JtYXQgSUQgaXMgZXhhY3RseSA0IEFTQ0lJIGNoYXJhY3RlcnMsIG1hdGNoaW5nIHRoZSBjb252ZW50aW9uXG4gKiB1c2VkIGZvciBvdGhlciB3b3JrZmxvdyBJRHMgKHdydW4sIHN0ZXAsIHdhaXQsIGV0Yy4pXG4gKi9cbmV4cG9ydCBjb25zdCBTZXJpYWxpemF0aW9uRm9ybWF0ID0ge1xuICAvKiogZGV2YWx1ZSBzdHJpbmdpZnkvcGFyc2Ugd2l0aCBUZXh0RW5jb2Rlci9UZXh0RGVjb2RlciAqL1xuICBERVZBTFVFX1YxOiAnZGV2bCcsXG4gIC8qKiBFbmNyeXB0ZWQgcGF5bG9hZCAoaW5uZXIgcGF5bG9hZCBoYXMgaXRzIG93biBmb3JtYXQgcHJlZml4KSAqL1xuICBFTkNSWVBURUQ6ICdlbmNyJyxcbn0gYXMgY29uc3Q7XG5cbmV4cG9ydCB0eXBlIFNlcmlhbGl6YXRpb25Gb3JtYXRUeXBlID1cbiAgKHR5cGVvZiBTZXJpYWxpemF0aW9uRm9ybWF0KVtrZXlvZiB0eXBlb2YgU2VyaWFsaXphdGlvbkZvcm1hdF07XG5cbi8qKiBMZW5ndGggb2YgdGhlIGZvcm1hdCBwcmVmaXggaW4gYnl0ZXMgKi9cbmNvbnN0IEZPUk1BVF9QUkVGSVhfTEVOR1RIID0gNDtcblxuLyoqIFRleHRFbmNvZGVyIGluc3RhbmNlIGZvciBmb3JtYXQgcHJlZml4IGVuY29kaW5nICovXG5jb25zdCBmb3JtYXRFbmNvZGVyID0gbmV3IFRleHRFbmNvZGVyKCk7XG5cbi8qKiBUZXh0RGVjb2RlciBpbnN0YW5jZSBmb3IgZm9ybWF0IHByZWZpeCBkZWNvZGluZyAqL1xuY29uc3QgZm9ybWF0RGVjb2RlciA9IG5ldyBUZXh0RGVjb2RlcigpO1xuXG4vKipcbiAqIEVuY29kZSBhIHBheWxvYWQgd2l0aCBhIGZvcm1hdCBwcmVmaXguXG4gKlxuICogQHBhcmFtIGZvcm1hdCAtIFRoZSBmb3JtYXQgaWRlbnRpZmllciAobXVzdCBiZSBleGFjdGx5IDQgQVNDSUkgY2hhcmFjdGVycylcbiAqIEBwYXJhbSBwYXlsb2FkIC0gVGhlIHNlcmlhbGl6ZWQgcGF5bG9hZCBieXRlc1xuICogQHJldHVybnMgQSBuZXcgVWludDhBcnJheSB3aXRoIGZvcm1hdCBwcmVmaXggcHJlcGVuZGVkXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBlbmNvZGVXaXRoRm9ybWF0UHJlZml4KFxuICBmb3JtYXQ6IFNlcmlhbGl6YXRpb25Gb3JtYXRUeXBlLFxuICBwYXlsb2FkOiBVaW50OEFycmF5IHwgdW5rbm93blxuKTogVWludDhBcnJheSB8IHVua25vd24ge1xuICBpZiAoIShwYXlsb2FkIGluc3RhbmNlb2YgVWludDhBcnJheSkpIHtcbiAgICByZXR1cm4gcGF5bG9hZDtcbiAgfVxuXG4gIGNvbnN0IHByZWZpeEJ5dGVzID0gZm9ybWF0RW5jb2Rlci5lbmNvZGUoZm9ybWF0KTtcbiAgaWYgKHByZWZpeEJ5dGVzLmxlbmd0aCAhPT0gRk9STUFUX1BSRUZJWF9MRU5HVEgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBgRm9ybWF0IGlkZW50aWZpZXIgbXVzdCBiZSBleGFjdGx5ICR7Rk9STUFUX1BSRUZJWF9MRU5HVEh9IEFTQ0lJIGNoYXJhY3RlcnMsIGdvdCBcIiR7Zm9ybWF0fVwiICgke3ByZWZpeEJ5dGVzLmxlbmd0aH0gYnl0ZXMpYFxuICAgICk7XG4gIH1cblxuICBjb25zdCByZXN1bHQgPSBuZXcgVWludDhBcnJheShGT1JNQVRfUFJFRklYX0xFTkdUSCArIHBheWxvYWQubGVuZ3RoKTtcbiAgcmVzdWx0LnNldChwcmVmaXhCeXRlcywgMCk7XG4gIHJlc3VsdC5zZXQocGF5bG9hZCwgRk9STUFUX1BSRUZJWF9MRU5HVEgpO1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG4vKipcbiAqIFBlZWsgYXQgdGhlIGZvcm1hdCBwcmVmaXggd2l0aG91dCBjb25zdW1pbmcgaXQuXG4gKiBVc2VmdWwgZm9yIGNoZWNraW5nIGlmIGRhdGEgaXMgZW5jcnlwdGVkIGJlZm9yZSBkZWNpZGluZyBob3cgdG8gcHJvY2VzcyBpdC5cbiAqXG4gKiBAcGFyYW0gZGF0YSAtIFRoZSBmb3JtYXQtcHJlZml4ZWQgZGF0YVxuICogQHJldHVybnMgVGhlIGZvcm1hdCBpZGVudGlmaWVyLCBvciBudWxsIGlmIGRhdGEgaXMgbGVnYWN5L25vbi1iaW5hcnlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBlZWtGb3JtYXRQcmVmaXgoXG4gIGRhdGE6IFVpbnQ4QXJyYXkgfCB1bmtub3duXG4pOiBTZXJpYWxpemF0aW9uRm9ybWF0VHlwZSB8IG51bGwge1xuICBpZiAoIShkYXRhIGluc3RhbmNlb2YgVWludDhBcnJheSkgfHwgZGF0YS5sZW5ndGggPCBGT1JNQVRfUFJFRklYX0xFTkdUSCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG4gIGNvbnN0IHByZWZpeEJ5dGVzID0gZGF0YS5zdWJhcnJheSgwLCBGT1JNQVRfUFJFRklYX0xFTkdUSCk7XG4gIGNvbnN0IGZvcm1hdCA9IGZvcm1hdERlY29kZXIuZGVjb2RlKHByZWZpeEJ5dGVzKTtcbiAgY29uc3Qga25vd25Gb3JtYXRzID0gT2JqZWN0LnZhbHVlcyhTZXJpYWxpemF0aW9uRm9ybWF0KSBhcyBzdHJpbmdbXTtcbiAgaWYgKCFrbm93bkZvcm1hdHMuaW5jbHVkZXMoZm9ybWF0KSkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG4gIHJldHVybiBmb3JtYXQgYXMgU2VyaWFsaXphdGlvbkZvcm1hdFR5cGU7XG59XG5cbi8qKlxuICogQ2hlY2sgaWYgZGF0YSBpcyBlbmNyeXB0ZWQgKGhhcyAnZW5jcicgZm9ybWF0IHByZWZpeCkuXG4gKlxuICogQHBhcmFtIGRhdGEgLSBUaGUgZm9ybWF0LXByZWZpeGVkIGRhdGFcbiAqIEByZXR1cm5zIHRydWUgaWYgZGF0YSBoYXMgdGhlIGVuY3J5cHRlZCBmb3JtYXQgcHJlZml4XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0VuY3J5cHRlZChkYXRhOiBVaW50OEFycmF5IHwgdW5rbm93bik6IGJvb2xlYW4ge1xuICByZXR1cm4gcGVla0Zvcm1hdFByZWZpeChkYXRhKSA9PT0gU2VyaWFsaXphdGlvbkZvcm1hdC5FTkNSWVBURUQ7XG59XG5cbi8qKlxuICogRGVjb2RlIGEgZm9ybWF0LXByZWZpeGVkIHBheWxvYWQuXG4gKlxuICogQHBhcmFtIGRhdGEgLSBUaGUgZm9ybWF0LXByZWZpeGVkIGRhdGFcbiAqIEByZXR1cm5zIEFuIG9iamVjdCB3aXRoIHRoZSBmb3JtYXQgaWRlbnRpZmllciBhbmQgcGF5bG9hZFxuICogQHRocm93cyBFcnJvciBpZiB0aGUgZGF0YSBpcyB0b28gc2hvcnQgb3IgaGFzIGFuIHVua25vd24gZm9ybWF0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZWNvZGVGb3JtYXRQcmVmaXgoZGF0YTogVWludDhBcnJheSB8IHVua25vd24pOiB7XG4gIGZvcm1hdDogU2VyaWFsaXphdGlvbkZvcm1hdFR5cGU7XG4gIHBheWxvYWQ6IFVpbnQ4QXJyYXk7XG59IHtcbiAgLy8gQ29tcGF0IGZvciBsZWdhY3kgc3BlY1ZlcnNpb24gMSBydW5zIHRoYXQgZG9uJ3QgaGF2ZSBhIGZvcm1hdCBwcmVmaXgsXG4gIC8vIGFuZCBkb24ndCBoYXZlIGEgYmluYXJ5IHBheWxvYWRcbiAgaWYgKCEoZGF0YSBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGZvcm1hdDogU2VyaWFsaXphdGlvbkZvcm1hdC5ERVZBTFVFX1YxLFxuICAgICAgcGF5bG9hZDogbmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKEpTT04uc3RyaW5naWZ5KGRhdGEpKSxcbiAgICB9O1xuICB9XG5cbiAgaWYgKGRhdGEubGVuZ3RoIDwgRk9STUFUX1BSRUZJWF9MRU5HVEgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBgRGF0YSB0b28gc2hvcnQgdG8gY29udGFpbiBmb3JtYXQgcHJlZml4OiBleHBlY3RlZCBhdCBsZWFzdCAke0ZPUk1BVF9QUkVGSVhfTEVOR1RIfSBieXRlcywgZ290ICR7ZGF0YS5sZW5ndGh9YFxuICAgICk7XG4gIH1cblxuICBjb25zdCBwcmVmaXhCeXRlcyA9IGRhdGEuc3ViYXJyYXkoMCwgRk9STUFUX1BSRUZJWF9MRU5HVEgpO1xuICBjb25zdCBmb3JtYXQgPSBmb3JtYXREZWNvZGVyLmRlY29kZShwcmVmaXhCeXRlcyk7XG5cbiAgLy8gVmFsaWRhdGUgdGhlIGZvcm1hdCBpcyBrbm93blxuICBjb25zdCBrbm93bkZvcm1hdHMgPSBPYmplY3QudmFsdWVzKFNlcmlhbGl6YXRpb25Gb3JtYXQpIGFzIHN0cmluZ1tdO1xuICBpZiAoIWtub3duRm9ybWF0cy5pbmNsdWRlcyhmb3JtYXQpKSB7XG4gICAgdGhyb3cgbmV3IFdvcmtmbG93UnVudGltZUVycm9yKFxuICAgICAgYFVua25vd24gc2VyaWFsaXphdGlvbiBmb3JtYXQ6IFwiJHtmb3JtYXR9XCIuIEtub3duIGZvcm1hdHM6ICR7a25vd25Gb3JtYXRzLmpvaW4oJywgJyl9YFxuICAgICk7XG4gIH1cblxuICBjb25zdCBwYXlsb2FkID0gZGF0YS5zdWJhcnJheShGT1JNQVRfUFJFRklYX0xFTkdUSCk7XG4gIHJldHVybiB7IGZvcm1hdDogZm9ybWF0IGFzIFNlcmlhbGl6YXRpb25Gb3JtYXRUeXBlLCBwYXlsb2FkIH07XG59XG5cbi8qKlxuICogRGVmYXVsdCBVTElEIGdlbmVyYXRvciBmb3IgY29udGV4dHMgd2hlcmUgVk0ncyBzZWVkZWQgYHN0YWJsZVVsaWRgIGlzbid0IGF2YWlsYWJsZS5cbiAqIFVzZWQgYXMgYSBmYWxsYmFjayB3aGVuIHNlcmlhbGl6aW5nIHN0cmVhbXMgb3V0c2lkZSB0aGUgd29ya2Zsb3cgVk0gY29udGV4dFxuICogKGUuZy4sIHdoZW4gc3RhcnRpbmcgYSB3b3JrZmxvdyBvciBoYW5kbGluZyBzdGVwIHJldHVybiB2YWx1ZXMpLlxuICovXG5jb25zdCBkZWZhdWx0VWxpZCA9IG1vbm90b25pY0ZhY3RvcnkoKTtcblxuLyoqXG4gKiBGb3JtYXQgYSBzZXJpYWxpemF0aW9uIGVycm9yIHdpdGggY29udGV4dCBhYm91dCB3aGF0IGZhaWxlZC5cbiAqIEV4dHJhY3RzIHBhdGgsIHZhbHVlLCBhbmQgcmVhc29uIGZyb20gZGV2YWx1ZSdzIERldmFsdWVFcnJvciB3aGVuIGF2YWlsYWJsZS5cbiAqIExvZ3MgdGhlIHByb2JsZW1hdGljIHZhbHVlIHRvIHRoZSBjb25zb2xlIGZvciBiZXR0ZXIgZGVidWdnaW5nLlxuICovXG5mdW5jdGlvbiBmb3JtYXRTZXJpYWxpemF0aW9uRXJyb3IoY29udGV4dDogc3RyaW5nLCBlcnJvcjogdW5rbm93bik6IHN0cmluZyB7XG4gIC8vIFVzZSBcInJldHVybmluZ1wiIGZvciByZXR1cm4gdmFsdWVzLCBcInBhc3NpbmdcIiBmb3IgYXJndW1lbnRzL2lucHV0c1xuICBjb25zdCB2ZXJiID0gY29udGV4dC5pbmNsdWRlcygncmV0dXJuIHZhbHVlJykgPyAncmV0dXJuaW5nJyA6ICdwYXNzaW5nJztcblxuICAvLyBCdWlsZCB0aGUgZXJyb3IgbWVzc2FnZSB3aXRoIHBhdGggaW5mbyBpZiBhdmFpbGFibGUgZnJvbSBEZXZhbHVlRXJyb3JcbiAgbGV0IG1lc3NhZ2UgPSBgRmFpbGVkIHRvIHNlcmlhbGl6ZSAke2NvbnRleHR9YDtcbiAgaWYgKGVycm9yIGluc3RhbmNlb2YgRGV2YWx1ZUVycm9yICYmIGVycm9yLnBhdGgpIHtcbiAgICBtZXNzYWdlICs9IGAgYXQgcGF0aCBcIiR7ZXJyb3IucGF0aH1cImA7XG4gIH1cbiAgbWVzc2FnZSArPSBgLiBFbnN1cmUgeW91J3JlICR7dmVyYn0gc2VyaWFsaXphYmxlIHR5cGVzIChwbGFpbiBvYmplY3RzLCBhcnJheXMsIHByaW1pdGl2ZXMsIERhdGUsIFJlZ0V4cCwgTWFwLCBTZXQpLmA7XG5cbiAgLy8gTG9nIHRoZSBwcm9ibGVtYXRpYyB2YWx1ZSBmb3IgZGVidWdnaW5nXG4gIGlmIChlcnJvciBpbnN0YW5jZW9mIERldmFsdWVFcnJvciAmJiBlcnJvci52YWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgcnVudGltZUxvZ2dlci5lcnJvcignU2VyaWFsaXphdGlvbiBmYWlsZWQnLCB7XG4gICAgICBjb250ZXh0LFxuICAgICAgcHJvYmxlbWF0aWNWYWx1ZTogZXJyb3IudmFsdWUsXG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4gbWVzc2FnZTtcbn1cblxuLyoqXG4gKiBEZXRlY3QgaWYgYSByZWFkYWJsZSBzdHJlYW0gaXMgYSBieXRlIHN0cmVhbS5cbiAqXG4gKiBAcGFyYW0gc3RyZWFtXG4gKiBAcmV0dXJucyBgXCJieXRlc1wiYCBpZiB0aGUgc3RyZWFtIGlzIGEgYnl0ZSBzdHJlYW0sIGB1bmRlZmluZWRgIG90aGVyd2lzZVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0U3RyZWFtVHlwZShzdHJlYW06IFJlYWRhYmxlU3RyZWFtKTogJ2J5dGVzJyB8IHVuZGVmaW5lZCB7XG4gIHRyeSB7XG4gICAgY29uc3QgcmVhZGVyID0gc3RyZWFtLmdldFJlYWRlcih7IG1vZGU6ICdieW9iJyB9KTtcbiAgICByZWFkZXIucmVsZWFzZUxvY2soKTtcbiAgICByZXR1cm4gJ2J5dGVzJztcbiAgfSBjYXRjaCB7fVxufVxuXG4vKipcbiAqIEZyYW1lIGZvcm1hdCBmb3Igc3RyZWFtIGNodW5rczpcbiAqICAgWzQtYnl0ZSBiaWctZW5kaWFuIGxlbmd0aF1bZm9ybWF0LXByZWZpeGVkIHBheWxvYWRdXG4gKlxuICogRWFjaCBjaHVuayBpcyBpbmRlcGVuZGVudGx5IGZyYW1lZCBzbyB0aGUgZGVzZXJpYWxpemVyIGNhbiBmaW5kXG4gKiBjaHVuayBib3VuZGFyaWVzIGV2ZW4gd2hlbiBtdWx0aXBsZSBjaHVua3MgYXJlIGNvbmNhdGVuYXRlZCBvclxuICogc3BsaXQgYWNyb3NzIHRyYW5zcG9ydCByZWFkcy5cbiAqL1xuY29uc3QgRlJBTUVfSEVBREVSX1NJWkUgPSA0O1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0U2VyaWFsaXplU3RyZWFtKFxuICByZWR1Y2VyczogUmVkdWNlcnMsXG4gIGNyeXB0b0tleTogRW5jcnlwdGlvbktleVBhcmFtXG4pOiBUcmFuc2Zvcm1TdHJlYW08YW55LCBVaW50OEFycmF5PiB7XG4gIGNvbnN0IGVuY29kZXIgPSBuZXcgVGV4dEVuY29kZXIoKTtcbiAgLy8gUmVzb2x2ZSB0aGUga2V5IHByb21pc2Ugb25jZSBvbiBmaXJzdCB1c2UgYW5kIGNhY2hlIHRoZSByZXN1bHQuXG4gIC8vIE5vdGU6IGlmIHRoZSBjcnlwdG9LZXkgcHJvbWlzZSByZWplY3RzIChlLmcuLCBuZXR3b3JrIGVycm9yIGZldGNoaW5nXG4gIC8vIHRoZSBkZXJpdmVkIGtleSksIHRoZSByZWplY3Rpb24gd29uJ3Qgc3VyZmFjZSB1bnRpbCB0aGUgZmlyc3QgY2h1bmtcbiAgLy8gaXMgcHJvY2Vzc2VkIOKAlCBub3QgYXQgc3RyZWFtIGNvbnN0cnVjdGlvbiB0aW1lLlxuICBjb25zdCBrZXlTdGF0ZSA9IHsgcmVzb2x2ZWQ6IGZhbHNlLCBrZXk6IHVuZGVmaW5lZCBhcyBDcnlwdG9LZXkgfCB1bmRlZmluZWQgfTtcbiAgY29uc3Qgc3RyZWFtID0gbmV3IFRyYW5zZm9ybVN0cmVhbTxhbnksIFVpbnQ4QXJyYXk+KHtcbiAgICBhc3luYyB0cmFuc2Zvcm0oY2h1bmssIGNvbnRyb2xsZXIpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGlmICgha2V5U3RhdGUucmVzb2x2ZWQpIHtcbiAgICAgICAgICBrZXlTdGF0ZS5rZXkgPSBhd2FpdCBjcnlwdG9LZXk7XG4gICAgICAgICAga2V5U3RhdGUucmVzb2x2ZWQgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHNlcmlhbGl6ZWQgPSBzdHJpbmdpZnkoY2h1bmssIHJlZHVjZXJzKTtcbiAgICAgICAgY29uc3QgcGF5bG9hZCA9IGVuY29kZXIuZW5jb2RlKHNlcmlhbGl6ZWQpO1xuICAgICAgICBsZXQgcHJlZml4ZWQgPSBlbmNvZGVXaXRoRm9ybWF0UHJlZml4KFxuICAgICAgICAgIFNlcmlhbGl6YXRpb25Gb3JtYXQuREVWQUxVRV9WMSxcbiAgICAgICAgICBwYXlsb2FkXG4gICAgICAgICkgYXMgVWludDhBcnJheTtcblxuICAgICAgICAvLyBFbmNyeXB0IHRoZSBmcmFtZSBwYXlsb2FkIGlmIGEga2V5IGlzIHByb3ZpZGVkLlxuICAgICAgICAvLyBUaGUgbGVuZ3RoIGhlYWRlciByZW1haW5zIGluIHRoZSBjbGVhciBzbyB0aGUgZGVzZXJpYWxpemVyIGNhblxuICAgICAgICAvLyBmaW5kIGZyYW1lIGJvdW5kYXJpZXMgcmVnYXJkbGVzcyBvZiB0cmFuc3BvcnQgY2h1bmtpbmcuXG4gICAgICAgIGlmIChrZXlTdGF0ZS5rZXkpIHtcbiAgICAgICAgICBjb25zdCBlbmNyeXB0ZWQgPSBhd2FpdCBhZXNHY21FbmNyeXB0KGtleVN0YXRlLmtleSwgcHJlZml4ZWQpO1xuICAgICAgICAgIHByZWZpeGVkID0gZW5jb2RlV2l0aEZvcm1hdFByZWZpeChcbiAgICAgICAgICAgIFNlcmlhbGl6YXRpb25Gb3JtYXQuRU5DUllQVEVELFxuICAgICAgICAgICAgZW5jcnlwdGVkXG4gICAgICAgICAgKSBhcyBVaW50OEFycmF5O1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gV3JpdGUgbGVuZ3RoLXByZWZpeGVkIGZyYW1lOiBbNC1ieXRlIGxlbmd0aF1bcHJlZml4ZWQgZGF0YV1cbiAgICAgICAgY29uc3QgZnJhbWUgPSBuZXcgVWludDhBcnJheShGUkFNRV9IRUFERVJfU0laRSArIHByZWZpeGVkLmxlbmd0aCk7XG4gICAgICAgIG5ldyBEYXRhVmlldyhmcmFtZS5idWZmZXIpLnNldFVpbnQzMigwLCBwcmVmaXhlZC5sZW5ndGgsIGZhbHNlKTtcbiAgICAgICAgZnJhbWUuc2V0KHByZWZpeGVkLCBGUkFNRV9IRUFERVJfU0laRSk7XG4gICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZShmcmFtZSk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBjb250cm9sbGVyLmVycm9yKFxuICAgICAgICAgIG5ldyBXb3JrZmxvd1J1bnRpbWVFcnJvcihcbiAgICAgICAgICAgIGZvcm1hdFNlcmlhbGl6YXRpb25FcnJvcignc3RyZWFtIGNodW5rJywgZXJyb3IpLFxuICAgICAgICAgICAgeyBzbHVnOiAnc2VyaWFsaXphdGlvbi1mYWlsZWQnLCBjYXVzZTogZXJyb3IgfVxuICAgICAgICAgIClcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9LFxuICB9KTtcbiAgcmV0dXJuIHN0cmVhbTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldERlc2VyaWFsaXplU3RyZWFtKFxuICByZXZpdmVyczogUmV2aXZlcnMsXG4gIGNyeXB0b0tleTogRW5jcnlwdGlvbktleVBhcmFtXG4pOiBUcmFuc2Zvcm1TdHJlYW08VWludDhBcnJheSwgYW55PiB7XG4gIGNvbnN0IGRlY29kZXIgPSBuZXcgVGV4dERlY29kZXIoKTtcbiAgbGV0IGJ1ZmZlciA9IG5ldyBVaW50OEFycmF5KDApO1xuICAvLyBSZXNvbHZlIHRoZSBrZXkgcHJvbWlzZSBvbmNlIG9uIGZpcnN0IHVzZSBhbmQgY2FjaGUgdGhlIHJlc3VsdC5cbiAgY29uc3Qga2V5U3RhdGUgPSB7IHJlc29sdmVkOiBmYWxzZSwga2V5OiB1bmRlZmluZWQgYXMgQ3J5cHRvS2V5IHwgdW5kZWZpbmVkIH07XG5cbiAgZnVuY3Rpb24gYXBwZW5kVG9CdWZmZXIoZGF0YTogVWludDhBcnJheSkge1xuICAgIGNvbnN0IG5ld0J1ZmZlciA9IG5ldyBVaW50OEFycmF5KGJ1ZmZlci5sZW5ndGggKyBkYXRhLmxlbmd0aCk7XG4gICAgbmV3QnVmZmVyLnNldChidWZmZXIsIDApO1xuICAgIG5ld0J1ZmZlci5zZXQoZGF0YSwgYnVmZmVyLmxlbmd0aCk7XG4gICAgYnVmZmVyID0gbmV3QnVmZmVyO1xuICB9XG5cbiAgYXN5bmMgZnVuY3Rpb24gcHJvY2Vzc0ZyYW1lcyhcbiAgICBjb250cm9sbGVyOiBUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlcjxhbnk+XG4gICkge1xuICAgIC8vIFJlc29sdmUgdGhlIGtleSBwcm9taXNlIG9uY2Ugb24gZmlyc3QgdXNlIGFuZCBjYWNoZSB0aGUgcmVzdWx0XG4gICAgaWYgKCFrZXlTdGF0ZS5yZXNvbHZlZCkge1xuICAgICAga2V5U3RhdGUua2V5ID0gYXdhaXQgY3J5cHRvS2V5O1xuICAgICAga2V5U3RhdGUucmVzb2x2ZWQgPSB0cnVlO1xuICAgIH1cblxuICAgIC8vIFRyeSB0byBleHRyYWN0IGNvbXBsZXRlIGxlbmd0aC1wcmVmaXhlZCBmcmFtZXNcbiAgICB3aGlsZSAoYnVmZmVyLmxlbmd0aCA+PSBGUkFNRV9IRUFERVJfU0laRSkge1xuICAgICAgY29uc3QgZnJhbWVMZW5ndGggPSBuZXcgRGF0YVZpZXcoXG4gICAgICAgIGJ1ZmZlci5idWZmZXIsXG4gICAgICAgIGJ1ZmZlci5ieXRlT2Zmc2V0LFxuICAgICAgICBidWZmZXIuYnl0ZUxlbmd0aFxuICAgICAgKS5nZXRVaW50MzIoMCwgZmFsc2UpO1xuXG4gICAgICBpZiAoYnVmZmVyLmxlbmd0aCA8IEZSQU1FX0hFQURFUl9TSVpFICsgZnJhbWVMZW5ndGgpIHtcbiAgICAgICAgYnJlYWs7IC8vIEluY29tcGxldGUgZnJhbWUsIHdhaXQgZm9yIG1vcmUgZGF0YVxuICAgICAgfVxuXG4gICAgICBjb25zdCBmcmFtZURhdGEgPSBidWZmZXIuc2xpY2UoXG4gICAgICAgIEZSQU1FX0hFQURFUl9TSVpFLFxuICAgICAgICBGUkFNRV9IRUFERVJfU0laRSArIGZyYW1lTGVuZ3RoXG4gICAgICApO1xuICAgICAgYnVmZmVyID0gYnVmZmVyLnNsaWNlKEZSQU1FX0hFQURFUl9TSVpFICsgZnJhbWVMZW5ndGgpO1xuXG4gICAgICBsZXQgeyBmb3JtYXQsIHBheWxvYWQgfSA9IGRlY29kZUZvcm1hdFByZWZpeChmcmFtZURhdGEpO1xuXG4gICAgICAvLyBJZiB0aGUgZnJhbWUgcGF5bG9hZCBpcyBlbmNyeXB0ZWQsIGRlY3J5cHQgaXQgZmlyc3QgdG8gcmV2ZWFsXG4gICAgICAvLyB0aGUgaW5uZXIgZm9ybWF0LXByZWZpeGVkIGRhdGEgKGUuZy4sICdkZXZsJyArIHNlcmlhbGl6ZWQgdGV4dCksXG4gICAgICAvLyB0aGVuIGZhbGwgdGhyb3VnaCB0byB0aGUgbm9ybWFsIGRlc2VyaWFsaXphdGlvbiBwYXRoLlxuICAgICAgaWYgKGZvcm1hdCA9PT0gU2VyaWFsaXphdGlvbkZvcm1hdC5FTkNSWVBURUQpIHtcbiAgICAgICAgaWYgKCFrZXlTdGF0ZS5rZXkpIHtcbiAgICAgICAgICBjb250cm9sbGVyLmVycm9yKFxuICAgICAgICAgICAgbmV3IFdvcmtmbG93UnVudGltZUVycm9yKFxuICAgICAgICAgICAgICAnRW5jcnlwdGVkIHN0cmVhbSBkYXRhIGVuY291bnRlcmVkIGJ1dCBubyBlbmNyeXB0aW9uIGtleSBpcyBhdmFpbGFibGUuICcgK1xuICAgICAgICAgICAgICAgICdFbmNyeXB0aW9uIGlzIG5vdCBjb25maWd1cmVkIG9yIG5vIGtleSB3YXMgcHJvdmlkZWQgZm9yIHRoaXMgcnVuLidcbiAgICAgICAgICAgIClcbiAgICAgICAgICApO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBkZWNyeXB0ZWQgPSBhd2FpdCBhZXNHY21EZWNyeXB0KGtleVN0YXRlLmtleSwgcGF5bG9hZCk7XG4gICAgICAgICh7IGZvcm1hdCwgcGF5bG9hZCB9ID0gZGVjb2RlRm9ybWF0UHJlZml4KGRlY3J5cHRlZCkpO1xuICAgICAgfVxuXG4gICAgICBpZiAoZm9ybWF0ID09PSBTZXJpYWxpemF0aW9uRm9ybWF0LkRFVkFMVUVfVjEpIHtcbiAgICAgICAgY29uc3QgdGV4dCA9IGRlY29kZXIuZGVjb2RlKHBheWxvYWQpO1xuICAgICAgICBjb250cm9sbGVyLmVucXVldWUocGFyc2UodGV4dCwgcmV2aXZlcnMpKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBjb25zdCBzdHJlYW0gPSBuZXcgVHJhbnNmb3JtU3RyZWFtPFVpbnQ4QXJyYXksIGFueT4oe1xuICAgIGFzeW5jIHRyYW5zZm9ybShjaHVuaywgY29udHJvbGxlcikge1xuICAgICAgLy8gRmlyc3QsIHRyeSB0byBkZXRlY3QgaWYgdGhpcyBpcyBsZW5ndGgtcHJlZml4ZWQgZnJhbWVkIGRhdGFcbiAgICAgIC8vIGJ5IGNoZWNraW5nIGlmIHRoZSBmaXJzdCA0IGJ5dGVzIGZvcm0gYSBwbGF1c2libGUgbGVuZ3RoLlxuICAgICAgaWYgKGJ1ZmZlci5sZW5ndGggPT09IDAgJiYgY2h1bmsubGVuZ3RoID49IEZSQU1FX0hFQURFUl9TSVpFKSB7XG4gICAgICAgIGNvbnN0IHBvc3NpYmxlTGVuZ3RoID0gbmV3IERhdGFWaWV3KFxuICAgICAgICAgIGNodW5rLmJ1ZmZlcixcbiAgICAgICAgICBjaHVuay5ieXRlT2Zmc2V0LFxuICAgICAgICAgIGNodW5rLmJ5dGVMZW5ndGhcbiAgICAgICAgKS5nZXRVaW50MzIoMCwgZmFsc2UpO1xuICAgICAgICBpZiAoXG4gICAgICAgICAgcG9zc2libGVMZW5ndGggPiAwICYmXG4gICAgICAgICAgcG9zc2libGVMZW5ndGggPCAxMDBfMDAwXzAwMCAvLyBzYW5pdHkgY2hlY2s6IDwgMTAwTUJcbiAgICAgICAgKSB7XG4gICAgICAgICAgLy8gTG9va3MgbGlrZSBmcmFtZWQgZGF0YVxuICAgICAgICAgIGFwcGVuZFRvQnVmZmVyKGNodW5rKTtcbiAgICAgICAgICBhd2FpdCBwcm9jZXNzRnJhbWVzKGNvbnRyb2xsZXIpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChidWZmZXIubGVuZ3RoID4gMCkge1xuICAgICAgICAvLyBBbHJlYWR5IGluIGZyYW1lZCBtb2RlIChoYXZlIGJ1ZmZlcmVkIGRhdGEpXG4gICAgICAgIGFwcGVuZFRvQnVmZmVyKGNodW5rKTtcbiAgICAgICAgYXdhaXQgcHJvY2Vzc0ZyYW1lcyhjb250cm9sbGVyKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICAvLyBMZWdhY3kgZm9ybWF0OiBuZXdsaW5lLWRlbGltaXRlZCBkZXZhbHVlIHRleHQgKG5vIGZyYW1pbmcpXG4gICAgICBjb25zdCB0ZXh0ID0gZGVjb2Rlci5kZWNvZGUoY2h1bmspO1xuICAgICAgY29uc3QgbGluZXMgPSB0ZXh0LnNwbGl0KCdcXG4nKTtcbiAgICAgIGZvciAoY29uc3QgbGluZSBvZiBsaW5lcykge1xuICAgICAgICBpZiAobGluZS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgY29udHJvbGxlci5lbnF1ZXVlKHBhcnNlKGxpbmUsIHJldml2ZXJzKSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9LFxuICAgIGFzeW5jIGZsdXNoKGNvbnRyb2xsZXIpIHtcbiAgICAgIC8vIFByb2Nlc3MgYW55IHJlbWFpbmluZyBmcmFtZWQgZGF0YVxuICAgICAgaWYgKGJ1ZmZlci5sZW5ndGggPiAwKSB7XG4gICAgICAgIGF3YWl0IHByb2Nlc3NGcmFtZXMoY29udHJvbGxlcik7XG4gICAgICB9XG4gICAgfSxcbiAgfSk7XG4gIHJldHVybiBzdHJlYW07XG59XG5cbmV4cG9ydCBjbGFzcyBXb3JrZmxvd1NlcnZlclJlYWRhYmxlU3RyZWFtIGV4dGVuZHMgUmVhZGFibGVTdHJlYW08VWludDhBcnJheT4ge1xuICAjcmVhZGVyPzogUmVhZGFibGVTdHJlYW1EZWZhdWx0UmVhZGVyPFVpbnQ4QXJyYXk+O1xuXG4gIGNvbnN0cnVjdG9yKHJ1bklkOiBzdHJpbmcsIG5hbWU6IHN0cmluZywgc3RhcnRJbmRleD86IG51bWJlcikge1xuICAgIGlmICh0eXBlb2YgbmFtZSAhPT0gJ3N0cmluZycgfHwgbmFtZS5sZW5ndGggPT09IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgXCJuYW1lXCIgaXMgcmVxdWlyZWQsIGdvdCBcIiR7bmFtZX1cImApO1xuICAgIH1cbiAgICBzdXBlcih7XG4gICAgICAvLyBAdHMtZXhwZWN0LWVycm9yIE5vdCBzdXJlIHdoeSBUeXBlU2NyaXB0IGlzIGNvbXBsYWluaW5nIGFib3V0IHRoaXNcbiAgICAgIHR5cGU6ICdieXRlcycsXG5cbiAgICAgIHB1bGw6IGFzeW5jIChjb250cm9sbGVyKSA9PiB7XG4gICAgICAgIGxldCByZWFkZXIgPSB0aGlzLiNyZWFkZXI7XG4gICAgICAgIGlmICghcmVhZGVyKSB7XG4gICAgICAgICAgY29uc3Qgd29ybGQgPSBhd2FpdCBnZXRXb3JsZCgpO1xuICAgICAgICAgIGNvbnN0IHN0cmVhbSA9IGF3YWl0IHdvcmxkLnN0cmVhbXMuZ2V0KHJ1bklkLCBuYW1lLCBzdGFydEluZGV4KTtcbiAgICAgICAgICByZWFkZXIgPSB0aGlzLiNyZWFkZXIgPSBzdHJlYW0uZ2V0UmVhZGVyKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFyZWFkZXIpIHtcbiAgICAgICAgICBjb250cm9sbGVyLmVycm9yKG5ldyBFcnJvcignRmFpbGVkIHRvIGdldCByZWFkZXInKSk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcmVhZGVyLnJlYWQoKTtcbiAgICAgICAgaWYgKHJlc3VsdC5kb25lKSB7XG4gICAgICAgICAgdGhpcy4jcmVhZGVyID0gdW5kZWZpbmVkO1xuICAgICAgICAgIGNvbnRyb2xsZXIuY2xvc2UoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBGb3J3YXJkIHJhdyBieXRlczsgZW5jcnlwdGlvbi9kZWNyeXB0aW9uIGlzIGhhbmRsZWQgYXQgdGhlXG4gICAgICAgICAgLy8gZnJhbWluZyBsZXZlbCBieSBnZXRTZXJpYWxpemVTdHJlYW0vZ2V0RGVzZXJpYWxpemVTdHJlYW0uXG4gICAgICAgICAgY29udHJvbGxlci5lbnF1ZXVlKHJlc3VsdC52YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBjYW5jZWw6IGFzeW5jIChyZWFzb24pID0+IHtcbiAgICAgICAgaWYgKHRoaXMuI3JlYWRlcikge1xuICAgICAgICAgIGF3YWl0IHRoaXMuI3JlYWRlci5jYW5jZWwocmVhc29uKS5jYXRjaCgoKSA9PiB7fSk7XG4gICAgICAgICAgdGhpcy4jcmVhZGVyID0gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgIH0pO1xuICB9XG59XG5cbi8qKlxuICogRGVmYXVsdCBmbHVzaCBpbnRlcnZhbCBpbiBtaWxsaXNlY29uZHMgZm9yIGJ1ZmZlcmVkIHN0cmVhbSB3cml0ZXMuXG4gKiBDaHVua3MgYXJlIGFjY3VtdWxhdGVkIGFuZCBmbHVzaGVkIHRvZ2V0aGVyIHRvIHJlZHVjZSBuZXR3b3JrIG92ZXJoZWFkLlxuICovXG5jb25zdCBTVFJFQU1fRkxVU0hfSU5URVJWQUxfTVMgPSAxMDtcblxuZXhwb3J0IGNsYXNzIFdvcmtmbG93U2VydmVyV3JpdGFibGVTdHJlYW0gZXh0ZW5kcyBXcml0YWJsZVN0cmVhbTxVaW50OEFycmF5PiB7XG4gIGNvbnN0cnVjdG9yKHJ1bklkOiBzdHJpbmcsIG5hbWU6IHN0cmluZykge1xuICAgIGlmICh0eXBlb2YgcnVuSWQgIT09ICdzdHJpbmcnKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFwicnVuSWRcIiBtdXN0IGJlIGEgc3RyaW5nLCBnb3QgXCIke3R5cGVvZiBydW5JZH1cImApO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIG5hbWUgIT09ICdzdHJpbmcnIHx8IG5hbWUubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFwibmFtZVwiIGlzIHJlcXVpcmVkLCBnb3QgXCIke25hbWV9XCJgKTtcbiAgICB9XG4gICAgY29uc3Qgd29ybGRQcm9taXNlID0gZ2V0V29ybGQoKTtcblxuICAgIC8vIEJ1ZmZlcmluZyBzdGF0ZSBmb3IgYmF0Y2hlZCB3cml0ZXNcbiAgICAvLyBFbmNyeXB0aW9uL2RlY3J5cHRpb24gaXMgaGFuZGxlZCBhdCB0aGUgZnJhbWluZyBsZXZlbCBieVxuICAgIC8vIGdldFNlcmlhbGl6ZVN0cmVhbS9nZXREZXNlcmlhbGl6ZVN0cmVhbSwgbm90IGhlcmUuXG4gICAgbGV0IGJ1ZmZlcjogVWludDhBcnJheVtdID0gW107XG4gICAgbGV0IGZsdXNoVGltZXI6IFJldHVyblR5cGU8dHlwZW9mIHNldFRpbWVvdXQ+IHwgbnVsbCA9IG51bGw7XG4gICAgbGV0IGZsdXNoUHJvbWlzZTogUHJvbWlzZTx2b2lkPiB8IG51bGwgPSBudWxsO1xuICAgIGxldCByZXNvbHZlZEZsdXNoSW50ZXJ2YWxNczogbnVtYmVyIHwgdW5kZWZpbmVkO1xuXG4gICAgY29uc3QgZmx1c2ggPSBhc3luYyAoKTogUHJvbWlzZTx2b2lkPiA9PiB7XG4gICAgICBpZiAoZmx1c2hUaW1lcikge1xuICAgICAgICBjbGVhclRpbWVvdXQoZmx1c2hUaW1lcik7XG4gICAgICAgIGZsdXNoVGltZXIgPSBudWxsO1xuICAgICAgfVxuXG4gICAgICBpZiAoYnVmZmVyLmxlbmd0aCA9PT0gMCkgcmV0dXJuO1xuXG4gICAgICAvLyBDb3B5IGNodW5rcyB0byBmbHVzaCwgYnV0IGRvbid0IGNsZWFyIGJ1ZmZlciB1bnRpbCB3cml0ZSBzdWNjZWVkc1xuICAgICAgLy8gVGhpcyBwcmV2ZW50cyBkYXRhIGxvc3MgaWYgdGhlIHdyaXRlIG9wZXJhdGlvbiBmYWlsc1xuICAgICAgY29uc3QgY2h1bmtzVG9GbHVzaCA9IGJ1ZmZlci5zbGljZSgpO1xuXG4gICAgICBjb25zdCB3b3JsZCA9IGF3YWl0IHdvcmxkUHJvbWlzZTtcbiAgICAgIC8vIENhY2hlIHRoZSBmbHVzaCBpbnRlcnZhbCBmcm9tIHRoZSB3b3JsZCBvbiBmaXJzdCB1c2VcbiAgICAgIGlmIChyZXNvbHZlZEZsdXNoSW50ZXJ2YWxNcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJlc29sdmVkRmx1c2hJbnRlcnZhbE1zID1cbiAgICAgICAgICB3b3JsZC5zdHJlYW1GbHVzaEludGVydmFsTXMgPz8gU1RSRUFNX0ZMVVNIX0lOVEVSVkFMX01TO1xuICAgICAgfVxuICAgICAgLy8gVXNlIHdyaXRlTXVsdGkgaWYgYXZhaWxhYmxlIGZvciBiYXRjaCB3cml0ZXNcbiAgICAgIGlmIChcbiAgICAgICAgdHlwZW9mIHdvcmxkLnN0cmVhbXMud3JpdGVNdWx0aSA9PT0gJ2Z1bmN0aW9uJyAmJlxuICAgICAgICBjaHVua3NUb0ZsdXNoLmxlbmd0aCA+IDFcbiAgICAgICkge1xuICAgICAgICBhd2FpdCB3b3JsZC5zdHJlYW1zLndyaXRlTXVsdGkocnVuSWQsIG5hbWUsIGNodW5rc1RvRmx1c2gpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gRmFsbCBiYWNrIHRvIHNlcXVlbnRpYWwgd3JpdGVzXG4gICAgICAgIGZvciAoY29uc3QgY2h1bmsgb2YgY2h1bmtzVG9GbHVzaCkge1xuICAgICAgICAgIGF3YWl0IHdvcmxkLnN0cmVhbXMud3JpdGUocnVuSWQsIG5hbWUsIGNodW5rKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBPbmx5IGNsZWFyIGJ1ZmZlciBhZnRlciBzdWNjZXNzZnVsIHdyaXRlIHRvIHByZXZlbnQgZGF0YSBsb3NzXG4gICAgICBidWZmZXIgPSBbXTtcbiAgICB9O1xuXG4gICAgLyoqIFJlc29sdmVycy9yZWplY3RvcnMgd2FpdGluZyBmb3IgdGhlIGN1cnJlbnQgc2NoZWR1bGVkIGZsdXNoICovXG4gICAgbGV0IGZsdXNoV2FpdGVyczogQXJyYXk8e1xuICAgICAgcmVzb2x2ZTogKCkgPT4gdm9pZDtcbiAgICAgIHJlamVjdDogKGVycjogdW5rbm93bikgPT4gdm9pZDtcbiAgICB9PiA9IFtdO1xuXG4gICAgY29uc3Qgc2NoZWR1bGVGbHVzaCA9ICgpOiB2b2lkID0+IHtcbiAgICAgIGlmIChmbHVzaFRpbWVyKSByZXR1cm47IC8vIEFscmVhZHkgc2NoZWR1bGVkXG5cbiAgICAgIGZsdXNoVGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgZmx1c2hUaW1lciA9IG51bGw7XG4gICAgICAgIGNvbnN0IGN1cnJlbnRXYWl0ZXJzID0gZmx1c2hXYWl0ZXJzO1xuICAgICAgICBmbHVzaFdhaXRlcnMgPSBbXTtcbiAgICAgICAgZmx1c2hQcm9taXNlID0gZmx1c2goKS50aGVuKFxuICAgICAgICAgICgpID0+IHtcbiAgICAgICAgICAgIGZvciAoY29uc3QgdyBvZiBjdXJyZW50V2FpdGVycykgdy5yZXNvbHZlKCk7XG4gICAgICAgICAgfSxcbiAgICAgICAgICAoZXJyKSA9PiB7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IHcgb2YgY3VycmVudFdhaXRlcnMpIHcucmVqZWN0KGVycik7XG4gICAgICAgICAgfVxuICAgICAgICApO1xuICAgICAgfSwgcmVzb2x2ZWRGbHVzaEludGVydmFsTXMgPz8gU1RSRUFNX0ZMVVNIX0lOVEVSVkFMX01TKTtcbiAgICB9O1xuXG4gICAgc3VwZXIoe1xuICAgICAgYXN5bmMgd3JpdGUoY2h1bmspIHtcbiAgICAgICAgLy8gV2FpdCBmb3IgYW55IGluLXByb2dyZXNzIGZsdXNoIHRvIGNvbXBsZXRlIGJlZm9yZSBhZGRpbmcgdG8gYnVmZmVyXG4gICAgICAgIGlmIChmbHVzaFByb21pc2UpIHtcbiAgICAgICAgICBhd2FpdCBmbHVzaFByb21pc2U7XG4gICAgICAgICAgZmx1c2hQcm9taXNlID0gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIGJ1ZmZlci5wdXNoKGNodW5rKTtcbiAgICAgICAgc2NoZWR1bGVGbHVzaCgpO1xuXG4gICAgICAgIC8vIFdhaXQgZm9yIHRoZSBzY2hlZHVsZWQgZmx1c2ggdG8gY29tcGxldGUgc28gdGhhdCBjYWxsZXJzXG4gICAgICAgIC8vIChsaWtlIGZsdXNoYWJsZVBpcGUpIGtub3cgZGF0YSBoYXMgcmVhY2hlZCB0aGUgc2VydmVyXG4gICAgICAgIC8vIGJlZm9yZSBkZWNyZW1lbnRpbmcgcGVuZGluZ09wcy4gV2l0aG91dCB0aGlzLCBwZW5kaW5nT3BzXG4gICAgICAgIC8vIHJlYWNoZXMgMCB3aGVuIHRoZSBidWZmZXJlZCB3cml0ZSByZXR1cm5zIChpbnN0YW50KSwgYnV0XG4gICAgICAgIC8vIHRoZSAxMG1zIGZsdXNoIHRpbWVyIGhhc24ndCBmaXJlZCB5ZXQuXG4gICAgICAgIGF3YWl0IG5ldyBQcm9taXNlPHZvaWQ+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICBmbHVzaFdhaXRlcnMucHVzaCh7IHJlc29sdmUsIHJlamVjdCB9KTtcbiAgICAgICAgfSk7XG4gICAgICB9LFxuICAgICAgYXN5bmMgY2xvc2UoKSB7XG4gICAgICAgIC8vIFdhaXQgZm9yIGFueSBpbi1wcm9ncmVzcyBmbHVzaCB0byBjb21wbGV0ZVxuICAgICAgICBpZiAoZmx1c2hQcm9taXNlKSB7XG4gICAgICAgICAgYXdhaXQgZmx1c2hQcm9taXNlO1xuICAgICAgICAgIGZsdXNoUHJvbWlzZSA9IG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBGbHVzaCBhbnkgcmVtYWluaW5nIGJ1ZmZlcmVkIGNodW5rc1xuICAgICAgICBhd2FpdCBmbHVzaCgpO1xuXG4gICAgICAgIGNvbnN0IHdvcmxkID0gYXdhaXQgd29ybGRQcm9taXNlO1xuICAgICAgICBhd2FpdCB3b3JsZC5zdHJlYW1zLmNsb3NlKHJ1bklkLCBuYW1lKTtcbiAgICAgIH0sXG4gICAgICBhYm9ydChyZWFzb24pIHtcbiAgICAgICAgLy8gQ2xlYW4gdXAgdGltZXIgdG8gcHJldmVudCBsZWFrc1xuICAgICAgICBpZiAoZmx1c2hUaW1lcikge1xuICAgICAgICAgIGNsZWFyVGltZW91dChmbHVzaFRpbWVyKTtcbiAgICAgICAgICBmbHVzaFRpbWVyID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICAvLyBEaXNjYXJkIGJ1ZmZlcmVkIGNodW5rcyAtIHRoZXkgd29uJ3QgYmUgd3JpdHRlblxuICAgICAgICBidWZmZXIgPSBbXTtcbiAgICAgICAgLy8gUmVqZWN0IGFueSBwZW5kaW5nIGZsdXNoV2FpdGVycyBzbyB0aGUgd3JpdGUoKSBwcm9taXNlcyBzZXR0bGVcbiAgICAgICAgLy8gYW5kIGRvbid0IGxlYWsuIFdpdGhvdXQgdGhpcywgd3JpdGUoKSBoYW5ncyBmb3JldmVyIG9uIGFuXG4gICAgICAgIC8vIHVuc2V0dGxlZCBwcm9taXNlIGJlY2F1c2UgdGhlIGNsZWFyZWQgdGltZXIgd2lsbCBuZXZlciBmaXJlLlxuICAgICAgICBjb25zdCB3YWl0ZXJzID0gZmx1c2hXYWl0ZXJzO1xuICAgICAgICBmbHVzaFdhaXRlcnMgPSBbXTtcbiAgICAgICAgY29uc3QgYWJvcnRFcnJvciA9IHJlYXNvbiA/PyBuZXcgRXJyb3IoJ1N0cmVhbSBhYm9ydGVkJyk7XG4gICAgICAgIGZvciAoY29uc3QgdyBvZiB3YWl0ZXJzKSB3LnJlamVjdChhYm9ydEVycm9yKTtcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cbn1cblxuLy8gVHlwZXMgdGhhdCBuZWVkIHNwZWNpYWxpemVkIGhhbmRsaW5nIHdoZW4gc2VyaWFsaXplZC9kZXNlcmlhbGl6ZWRcbi8vICEgSWYgYSB0eXBlIGlzIGFkZGVkIGhlcmUsIGl0IE1VU1QgYWxzbyBiZSBhZGRlZCB0byB0aGUgYFNlcmlhbGl6YWJsZWAgdHlwZSBpbiBgc2NoZW1hcy50c2BcbmV4cG9ydCBpbnRlcmZhY2UgU2VyaWFsaXphYmxlU3BlY2lhbCB7XG4gIEFycmF5QnVmZmVyOiBzdHJpbmc7IC8vIGJhc2U2NCBzdHJpbmdcbiAgQmlnSW50OiBzdHJpbmc7IC8vIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBiaWdpbnRcbiAgQmlnSW50NjRBcnJheTogc3RyaW5nOyAvLyBiYXNlNjQgc3RyaW5nXG4gIEJpZ1VpbnQ2NEFycmF5OiBzdHJpbmc7IC8vIGJhc2U2NCBzdHJpbmdcbiAgRGF0ZTogc3RyaW5nOyAvLyBJU08gc3RyaW5nXG4gIERPTUV4Y2VwdGlvbjoge1xuICAgIG1lc3NhZ2U6IHN0cmluZztcbiAgICBuYW1lOiBzdHJpbmc7XG4gICAgc3RhY2s/OiBzdHJpbmc7XG4gICAgY2F1c2U/OiB1bmtub3duO1xuICB9O1xuICBGbG9hdDMyQXJyYXk6IHN0cmluZzsgLy8gYmFzZTY0IHN0cmluZ1xuICBGbG9hdDY0QXJyYXk6IHN0cmluZzsgLy8gYmFzZTY0IHN0cmluZ1xuICBFcnJvcjogUmVjb3JkPHN0cmluZywgYW55PjtcbiAgSGVhZGVyczogW3N0cmluZywgc3RyaW5nXVtdO1xuICBJbnQ4QXJyYXk6IHN0cmluZzsgLy8gYmFzZTY0IHN0cmluZ1xuICBJbnQxNkFycmF5OiBzdHJpbmc7IC8vIGJhc2U2NCBzdHJpbmdcbiAgSW50MzJBcnJheTogc3RyaW5nOyAvLyBiYXNlNjQgc3RyaW5nXG4gIE1hcDogW2FueSwgYW55XVtdO1xuICBSZWFkYWJsZVN0cmVhbTpcbiAgICB8IHsgbmFtZTogc3RyaW5nOyB0eXBlPzogJ2J5dGVzJzsgc3RhcnRJbmRleD86IG51bWJlciB9XG4gICAgfCB7IGJvZHlJbml0OiBhbnkgfTtcbiAgUmVnRXhwOiB7IHNvdXJjZTogc3RyaW5nOyBmbGFnczogc3RyaW5nIH07XG4gIFJlcXVlc3Q6IHtcbiAgICBtZXRob2Q6IHN0cmluZztcbiAgICB1cmw6IHN0cmluZztcbiAgICBoZWFkZXJzOiBIZWFkZXJzO1xuICAgIGJvZHk6IFJlcXVlc3RbJ2JvZHknXTtcbiAgICBkdXBsZXg6IFJlcXVlc3RbJ2R1cGxleCddO1xuXG4gICAgLy8gVGhpcyBpcyBzcGVjaWZpY2FsbHkgZm9yIHRoZSBgUmVxdWVzdFdpdGhSZXNwb25zZWAgdHlwZSB3aGljaCBpcyB1c2VkIGZvciB3ZWJob29rc1xuICAgIHJlc3BvbnNlV3JpdGFibGU/OiBXcml0YWJsZVN0cmVhbTxSZXNwb25zZT47XG4gIH07XG4gIFJlc3BvbnNlOiB7XG4gICAgdHlwZTogUmVzcG9uc2VbJ3R5cGUnXTtcbiAgICB1cmw6IHN0cmluZztcbiAgICBzdGF0dXM6IG51bWJlcjtcbiAgICBzdGF0dXNUZXh0OiBzdHJpbmc7XG4gICAgaGVhZGVyczogSGVhZGVycztcbiAgICBib2R5OiBSZXNwb25zZVsnYm9keSddO1xuICAgIHJlZGlyZWN0ZWQ6IGJvb2xlYW47XG4gIH07XG4gIENsYXNzOiB7XG4gICAgY2xhc3NJZDogc3RyaW5nO1xuICB9O1xuICAvKipcbiAgICogQ3VzdG9tIHNlcmlhbGl6ZWQgY2xhc3MgaW5zdGFuY2UuXG4gICAqIFRoZSBjbGFzcyBtdXN0IGhhdmUgYSBgY2xhc3NJZGAgcHJvcGVydHkgYW5kIGJlIHJlZ2lzdGVyZWQgZm9yIGRlc2VyaWFsaXphdGlvbi5cbiAgICovXG4gIEluc3RhbmNlOiB7XG4gICAgY2xhc3NJZDogc3RyaW5nOyAvLyBVbmlxdWUgaWRlbnRpZmllciBmb3IgdGhlIGNsYXNzICh1c2VkIGZvciBsb29rdXAgZHVyaW5nIGRlc2VyaWFsaXphdGlvbilcbiAgICBkYXRhOiB1bmtub3duOyAvLyBUaGUgc2VyaWFsaXplZCBpbnN0YW5jZSBkYXRhXG4gIH07XG4gIFNldDogYW55W107XG4gIFN0ZXBGdW5jdGlvbjoge1xuICAgIHN0ZXBJZDogc3RyaW5nO1xuICAgIGNsb3N1cmVWYXJzPzogUmVjb3JkPHN0cmluZywgYW55PjtcbiAgfTtcbiAgVVJMOiBzdHJpbmc7XG4gIFdvcmtmbG93RnVuY3Rpb246IHtcbiAgICB3b3JrZmxvd0lkOiBzdHJpbmc7XG4gIH07XG4gIFVSTFNlYXJjaFBhcmFtczogc3RyaW5nO1xuICBVaW50OEFycmF5OiBzdHJpbmc7IC8vIGJhc2U2NCBzdHJpbmdcbiAgVWludDhDbGFtcGVkQXJyYXk6IHN0cmluZzsgLy8gYmFzZTY0IHN0cmluZ1xuICBVaW50MTZBcnJheTogc3RyaW5nOyAvLyBiYXNlNjQgc3RyaW5nXG4gIFVpbnQzMkFycmF5OiBzdHJpbmc7IC8vIGJhc2U2NCBzdHJpbmdcbiAgV3JpdGFibGVTdHJlYW06IHsgbmFtZTogc3RyaW5nIH07XG59XG5cbnR5cGUgUmVkdWNlcnMgPSB7XG4gIFtLIGluIGtleW9mIFNlcmlhbGl6YWJsZVNwZWNpYWxdOiAoXG4gICAgdmFsdWU6IGFueVxuICApID0+IFNlcmlhbGl6YWJsZVNwZWNpYWxbS10gfCBmYWxzZTtcbn07XG5cbnR5cGUgUmV2aXZlcnMgPSB7XG4gIFtLIGluIGtleW9mIFNlcmlhbGl6YWJsZVNwZWNpYWxdOiAodmFsdWU6IFNlcmlhbGl6YWJsZVNwZWNpYWxbS10pID0+IGFueTtcbn07XG5cbmZ1bmN0aW9uIHJldml2ZShzdHI6IHN0cmluZykge1xuICAvLyBkZXZhbHVlLnN0cmluZ2lmeSgpIGFsd2F5cyBwcm9kdWNlcyB2YWxpZCBKU09OOiBzcGVjaWFsIHZhbHVlc1xuICAvLyAodW5kZWZpbmVkLCBOYU4sIEluZmluaXR5LCAtMCkgYXJlIGVuY29kZWQgYXMgbmVnYXRpdmUgaW50ZWdlclxuICAvLyBzZW50aW5lbHMgYW5kIHRoZSByZW1haW5pbmcgc3RydWN0dXJlIGlzIG9yZGluYXJ5IEpTT04uIFBhcnNpbmdcbiAgLy8gd2l0aCBKU09OLnBhcnNlIHlpZWxkcyB0aGUgZmxhdHRlbmVkIGZvcm0gdGhhdCB1bmZsYXR0ZW4oKSBleHBlY3RzLlxuICByZXR1cm4gSlNPTi5wYXJzZShzdHIpO1xufVxuXG5mdW5jdGlvbiBnZXRDb21tb25SZWR1Y2VycyhnbG9iYWw6IFJlY29yZDxzdHJpbmcsIGFueT4gPSBnbG9iYWxUaGlzKSB7XG4gIGNvbnN0IGFiVG9CYXNlNjQgPSAoXG4gICAgdmFsdWU6IEFycmF5QnVmZmVyTGlrZSxcbiAgICBvZmZzZXQ6IG51bWJlcixcbiAgICBsZW5ndGg6IG51bWJlclxuICApID0+IHtcbiAgICAvLyBBdm9pZCByZXR1cm5pbmcgZmFsc3kgdmFsdWUgZm9yIHplcm8tbGVuZ3RoIGJ1ZmZlcnNcbiAgICBpZiAobGVuZ3RoID09PSAwKSByZXR1cm4gJy4nO1xuICAgIC8vIENyZWF0ZSBhIHByb3BlciBjb3B5IHRvIGF2b2lkIEFycmF5QnVmZmVyIGRldGFjaG1lbnQgaXNzdWVzXG4gICAgLy8gQnVmZmVyLmZyb20oQXJyYXlCdWZmZXIsIG9mZnNldCwgbGVuZ3RoKSBjcmVhdGVzIGEgdmlldywgbm90IGEgY29weVxuICAgIGNvbnN0IHVpbnQ4ID0gbmV3IFVpbnQ4QXJyYXkodmFsdWUsIG9mZnNldCwgbGVuZ3RoKTtcbiAgICByZXR1cm4gQnVmZmVyLmZyb20odWludDgpLnRvU3RyaW5nKCdiYXNlNjQnKTtcbiAgfTtcbiAgY29uc3Qgdmlld1RvQmFzZTY0ID0gKHZhbHVlOiBBcnJheUJ1ZmZlclZpZXcpID0+XG4gICAgYWJUb0Jhc2U2NCh2YWx1ZS5idWZmZXIsIHZhbHVlLmJ5dGVPZmZzZXQsIHZhbHVlLmJ5dGVMZW5ndGgpO1xuXG4gIHJldHVybiB7XG4gICAgQXJyYXlCdWZmZXI6ICh2YWx1ZSkgPT5cbiAgICAgIHZhbHVlIGluc3RhbmNlb2YgZ2xvYmFsLkFycmF5QnVmZmVyICYmXG4gICAgICBhYlRvQmFzZTY0KHZhbHVlLCAwLCB2YWx1ZS5ieXRlTGVuZ3RoKSxcbiAgICBCaWdJbnQ6ICh2YWx1ZSkgPT4gdHlwZW9mIHZhbHVlID09PSAnYmlnaW50JyAmJiB2YWx1ZS50b1N0cmluZygpLFxuICAgIEJpZ0ludDY0QXJyYXk6ICh2YWx1ZSkgPT5cbiAgICAgIHZhbHVlIGluc3RhbmNlb2YgZ2xvYmFsLkJpZ0ludDY0QXJyYXkgJiYgdmlld1RvQmFzZTY0KHZhbHVlKSxcbiAgICBCaWdVaW50NjRBcnJheTogKHZhbHVlKSA9PlxuICAgICAgdmFsdWUgaW5zdGFuY2VvZiBnbG9iYWwuQmlnVWludDY0QXJyYXkgJiYgdmlld1RvQmFzZTY0KHZhbHVlKSxcbiAgICAvLyBDbGFzcyBhbmQgSW5zdGFuY2UgYXJlIGludGVudGlvbmFsbHkgcGxhY2VkIGJlZm9yZSBFcnJvciBzbyB0aGF0XG4gICAgLy8gY3VzdG9tIEVycm9yIHN1YmNsYXNzZXMgd2l0aCBXT1JLRkxPV19TRVJJQUxJWkUgdGFrZSBwcmVjZWRlbmNlXG4gICAgLy8gb3ZlciB0aGUgZ2VuZXJpYyBFcnJvciBzZXJpYWxpemF0aW9uIChkZXZhbHVlIHVzZXMgZmlyc3QtbWF0Y2gtd2lucykuXG4gICAgQ2xhc3M6ICh2YWx1ZSkgPT4ge1xuICAgICAgLy8gQ2hlY2sgaWYgdGhpcyBpcyBhIGNsYXNzIGNvbnN0cnVjdG9yIHdpdGggYSBjbGFzc0lkIHByb3BlcnR5XG4gICAgICAvLyAoc2V0IGJ5IHRoZSBTV0MgcGx1Z2luIGZvciBjbGFzc2VzIHdpdGggc3RhdGljIHN0ZXAvd29ya2Zsb3cgbWV0aG9kcylcbiAgICAgIGlmICh0eXBlb2YgdmFsdWUgIT09ICdmdW5jdGlvbicpIHJldHVybiBmYWxzZTtcbiAgICAgIGNvbnN0IGNsYXNzSWQgPSAodmFsdWUgYXMgYW55KS5jbGFzc0lkO1xuICAgICAgaWYgKHR5cGVvZiBjbGFzc0lkICE9PSAnc3RyaW5nJykgcmV0dXJuIGZhbHNlO1xuICAgICAgcmV0dXJuIHsgY2xhc3NJZCB9O1xuICAgIH0sXG4gICAgSW5zdGFuY2U6ICh2YWx1ZSkgPT4ge1xuICAgICAgLy8gQ2hlY2sgaWYgdGhpcyBpcyBhbiBpbnN0YW5jZSBvZiBhIGNsYXNzIHdpdGggY3VzdG9tIHNlcmlhbGl6YXRpb25cbiAgICAgIGlmICh2YWx1ZSA9PT0gbnVsbCB8fCB0eXBlb2YgdmFsdWUgIT09ICdvYmplY3QnKSByZXR1cm4gZmFsc2U7XG4gICAgICBjb25zdCBjbHMgPSB2YWx1ZS5jb25zdHJ1Y3RvcjtcbiAgICAgIGlmICghY2xzIHx8IHR5cGVvZiBjbHMgIT09ICdmdW5jdGlvbicpIHJldHVybiBmYWxzZTtcblxuICAgICAgLy8gQ2hlY2sgaWYgdGhlIGNsYXNzIGhhcyBhIHN0YXRpYyBXT1JLRkxPV19TRVJJQUxJWkUgbWV0aG9kXG4gICAgICBjb25zdCBzZXJpYWxpemUgPSBjbHNbV09SS0ZMT1dfU0VSSUFMSVpFXTtcbiAgICAgIGlmICh0eXBlb2Ygc2VyaWFsaXplICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgLy8gR2V0IHRoZSBjbGFzc0lkIGZyb20gdGhlIHN0YXRpYyBjbGFzcyBwcm9wZXJ0eSAoc2V0IGJ5IFNXQyBwbHVnaW4pXG4gICAgICBjb25zdCBjbGFzc0lkID0gY2xzLmNsYXNzSWQ7XG4gICAgICBpZiAodHlwZW9mIGNsYXNzSWQgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICBgQ2xhc3MgXCIke2Nscy5uYW1lfVwiIHdpdGggJHtTdHJpbmcoV09SS0ZMT1dfU0VSSUFMSVpFKX0gbXVzdCBoYXZlIGEgc3RhdGljIFwiY2xhc3NJZFwiIHByb3BlcnR5LmBcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgLy8gU2VyaWFsaXplIHRoZSBpbnN0YW5jZSB1c2luZyB0aGUgY3VzdG9tIHNlcmlhbGl6ZXJcbiAgICAgIGNvbnN0IGRhdGEgPSBzZXJpYWxpemUuY2FsbChjbHMsIHZhbHVlKTtcbiAgICAgIHJldHVybiB7IGNsYXNzSWQsIGRhdGEgfTtcbiAgICB9LFxuICAgIERhdGU6ICh2YWx1ZSkgPT4ge1xuICAgICAgaWYgKCEodmFsdWUgaW5zdGFuY2VvZiBnbG9iYWwuRGF0ZSkpIHJldHVybiBmYWxzZTtcbiAgICAgIGNvbnN0IHZhbGlkID0gIU51bWJlci5pc05hTih2YWx1ZS5nZXREYXRlKCkpO1xuICAgICAgLy8gTm90ZTogXCIuXCIgaXMgdG8gYXZvaWQgcmV0dXJuaW5nIGEgZmFsc3kgdmFsdWUgd2hlbiB0aGUgZGF0ZSBpcyBpbnZhbGlkXG4gICAgICByZXR1cm4gdmFsaWQgPyB2YWx1ZS50b0lTT1N0cmluZygpIDogJy4nO1xuICAgIH0sXG4gICAgLy8gRE9NRXhjZXB0aW9uIGlzIGEgc3BlY2lhbCBjYXNlOiBpbiBOb2RlLmpzIGl0IHBhc3NlcyBpc05hdGl2ZUVycm9yKClcbiAgICAvLyBhbmQgaW5zdGFuY2VvZiBFcnJvciwgYnV0IGhhcyBhIHVuaXF1ZSBjb25zdHJ1Y3RvciBzaWduYXR1cmVcbiAgICAvLyAobWVzc2FnZSwgbmFtZSkgYW5kIGEgcmVhZC1vbmx5IG51bWVyaWMgYGNvZGVgIHByb3BlcnR5IGRlcml2ZWQgZnJvbVxuICAgIC8vIGBuYW1lYC4gSXQgbXVzdCBiZSBjaGVja2VkIGJlZm9yZSB0aGUgZ2VuZXJpYyBFcnJvciByZWR1Y2VyLlxuICAgIERPTUV4Y2VwdGlvbjogKHZhbHVlKSA9PiB7XG4gICAgICBpZiAoIXR5cGVzLmlzTmF0aXZlRXJyb3IodmFsdWUpKSByZXR1cm4gZmFsc2U7XG4gICAgICBpZiAodmFsdWUuY29uc3RydWN0b3I/Lm5hbWUgIT09ICdET01FeGNlcHRpb24nKSByZXR1cm4gZmFsc2U7XG4gICAgICBjb25zdCByZWR1Y2VkOiBTZXJpYWxpemFibGVTcGVjaWFsWydET01FeGNlcHRpb24nXSA9IHtcbiAgICAgICAgbWVzc2FnZTogdmFsdWUubWVzc2FnZSxcbiAgICAgICAgbmFtZTogdmFsdWUubmFtZSxcbiAgICAgICAgc3RhY2s6IHZhbHVlLnN0YWNrLFxuICAgICAgfTtcbiAgICAgIGlmICgnY2F1c2UnIGluIHZhbHVlKSByZWR1Y2VkLmNhdXNlID0gdmFsdWUuY2F1c2U7XG4gICAgICByZXR1cm4gcmVkdWNlZDtcbiAgICB9LFxuICAgIEVycm9yOiAodmFsdWUpID0+IHtcbiAgICAgIC8vIFVzZSB0eXBlcy5pc05hdGl2ZUVycm9yKCkgaW5zdGVhZCBvZiBgaW5zdGFuY2VvZiBnbG9iYWwuRXJyb3JgXG4gICAgICAvLyBiZWNhdXNlIGVycm9ycyBtYXkgb3JpZ2luYXRlIGZyb20gYSBkaWZmZXJlbnQgVk0gY29udGV4dCAoZS5nLlxuICAgICAgLy8gRmF0YWxFcnJvciBmcm9tIHRoZSBob3N0IGNvbnRleHQgcGFzc2VkIGludG8gYSBWTS1jb250ZXh0IHdvcmtmbG93KS5cbiAgICAgIC8vIGBpbnN0YW5jZW9mYCBjaGVja3MgZmFpbCBhY3Jvc3MgVk0gYm91bmRhcmllcyBzaW5jZSBlYWNoIGNvbnRleHRcbiAgICAgIC8vIGhhcyBpdHMgb3duIEVycm9yIGNvbnN0cnVjdG9yLCBidXQgaXNOYXRpdmVFcnJvcigpIHVzZXMgVjgnc1xuICAgICAgLy8gaW50ZXJuYWwgdHlwZSB0YWcgd2hpY2ggd29ya3MgYWNyb3NzIGFsbCBjb250ZXh0cy5cbiAgICAgIGlmICghdHlwZXMuaXNOYXRpdmVFcnJvcih2YWx1ZSkpIHJldHVybiBmYWxzZTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIG5hbWU6IHZhbHVlLm5hbWUsXG4gICAgICAgIG1lc3NhZ2U6IHZhbHVlLm1lc3NhZ2UsXG4gICAgICAgIHN0YWNrOiB2YWx1ZS5zdGFjayxcbiAgICAgIH07XG4gICAgfSxcbiAgICBGbG9hdDMyQXJyYXk6ICh2YWx1ZSkgPT5cbiAgICAgIHZhbHVlIGluc3RhbmNlb2YgZ2xvYmFsLkZsb2F0MzJBcnJheSAmJiB2aWV3VG9CYXNlNjQodmFsdWUpLFxuICAgIEZsb2F0NjRBcnJheTogKHZhbHVlKSA9PlxuICAgICAgdmFsdWUgaW5zdGFuY2VvZiBnbG9iYWwuRmxvYXQ2NEFycmF5ICYmIHZpZXdUb0Jhc2U2NCh2YWx1ZSksXG4gICAgSGVhZGVyczogKHZhbHVlKSA9PiB2YWx1ZSBpbnN0YW5jZW9mIGdsb2JhbC5IZWFkZXJzICYmIEFycmF5LmZyb20odmFsdWUpLFxuICAgIEludDhBcnJheTogKHZhbHVlKSA9PlxuICAgICAgdmFsdWUgaW5zdGFuY2VvZiBnbG9iYWwuSW50OEFycmF5ICYmIHZpZXdUb0Jhc2U2NCh2YWx1ZSksXG4gICAgSW50MTZBcnJheTogKHZhbHVlKSA9PlxuICAgICAgdmFsdWUgaW5zdGFuY2VvZiBnbG9iYWwuSW50MTZBcnJheSAmJiB2aWV3VG9CYXNlNjQodmFsdWUpLFxuICAgIEludDMyQXJyYXk6ICh2YWx1ZSkgPT5cbiAgICAgIHZhbHVlIGluc3RhbmNlb2YgZ2xvYmFsLkludDMyQXJyYXkgJiYgdmlld1RvQmFzZTY0KHZhbHVlKSxcbiAgICBNYXA6ICh2YWx1ZSkgPT4gdmFsdWUgaW5zdGFuY2VvZiBnbG9iYWwuTWFwICYmIEFycmF5LmZyb20odmFsdWUpLFxuICAgIFJlZ0V4cDogKHZhbHVlKSA9PlxuICAgICAgdmFsdWUgaW5zdGFuY2VvZiBnbG9iYWwuUmVnRXhwICYmIHtcbiAgICAgICAgc291cmNlOiB2YWx1ZS5zb3VyY2UsXG4gICAgICAgIGZsYWdzOiB2YWx1ZS5mbGFncyxcbiAgICAgIH0sXG4gICAgUmVxdWVzdDogKHZhbHVlKSA9PiB7XG4gICAgICBpZiAoISh2YWx1ZSBpbnN0YW5jZW9mIGdsb2JhbC5SZXF1ZXN0KSkgcmV0dXJuIGZhbHNlO1xuICAgICAgY29uc3QgZGF0YTogU2VyaWFsaXphYmxlU3BlY2lhbFsnUmVxdWVzdCddID0ge1xuICAgICAgICBtZXRob2Q6IHZhbHVlLm1ldGhvZCxcbiAgICAgICAgdXJsOiB2YWx1ZS51cmwsXG4gICAgICAgIGhlYWRlcnM6IHZhbHVlLmhlYWRlcnMsXG4gICAgICAgIGJvZHk6IHZhbHVlLmJvZHksXG4gICAgICAgIGR1cGxleDogdmFsdWUuZHVwbGV4LFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHJlc3BvbnNlV3JpdGFibGUgPSB2YWx1ZVtXRUJIT09LX1JFU1BPTlNFX1dSSVRBQkxFXTtcbiAgICAgIGlmIChyZXNwb25zZVdyaXRhYmxlKSB7XG4gICAgICAgIGRhdGEucmVzcG9uc2VXcml0YWJsZSA9IHJlc3BvbnNlV3JpdGFibGU7XG4gICAgICB9XG4gICAgICByZXR1cm4gZGF0YTtcbiAgICB9LFxuICAgIFJlc3BvbnNlOiAodmFsdWUpID0+IHtcbiAgICAgIGlmICghKHZhbHVlIGluc3RhbmNlb2YgZ2xvYmFsLlJlc3BvbnNlKSkgcmV0dXJuIGZhbHNlO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdHlwZTogdmFsdWUudHlwZSxcbiAgICAgICAgdXJsOiB2YWx1ZS51cmwsXG4gICAgICAgIHN0YXR1czogdmFsdWUuc3RhdHVzLFxuICAgICAgICBzdGF0dXNUZXh0OiB2YWx1ZS5zdGF0dXNUZXh0LFxuICAgICAgICBoZWFkZXJzOiB2YWx1ZS5oZWFkZXJzLFxuICAgICAgICBib2R5OiB2YWx1ZS5ib2R5LFxuICAgICAgICByZWRpcmVjdGVkOiB2YWx1ZS5yZWRpcmVjdGVkLFxuICAgICAgfTtcbiAgICB9LFxuICAgIFNldDogKHZhbHVlKSA9PiB2YWx1ZSBpbnN0YW5jZW9mIGdsb2JhbC5TZXQgJiYgQXJyYXkuZnJvbSh2YWx1ZSksXG4gICAgU3RlcEZ1bmN0aW9uOiAodmFsdWUpID0+IHtcbiAgICAgIGlmICh0eXBlb2YgdmFsdWUgIT09ICdmdW5jdGlvbicpIHJldHVybiBmYWxzZTtcbiAgICAgIGNvbnN0IHN0ZXBJZCA9ICh2YWx1ZSBhcyBhbnkpLnN0ZXBJZDtcbiAgICAgIGlmICh0eXBlb2Ygc3RlcElkICE9PSAnc3RyaW5nJykgcmV0dXJuIGZhbHNlO1xuXG4gICAgICAvLyBDaGVjayBpZiB0aGUgc3RlcCBmdW5jdGlvbiBoYXMgY2xvc3VyZSB2YXJpYWJsZXNcbiAgICAgIGNvbnN0IGNsb3N1cmVWYXJzRm4gPSAodmFsdWUgYXMgYW55KS5fX2Nsb3N1cmVWYXJzRm47XG4gICAgICBpZiAoY2xvc3VyZVZhcnNGbiAmJiB0eXBlb2YgY2xvc3VyZVZhcnNGbiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAvLyBJbnZva2UgdGhlIGNsb3N1cmUgdmFyaWFibGVzIGZ1bmN0aW9uIGFuZCBzZXJpYWxpemUgYWxvbmcgd2l0aCBzdGVwSWRcbiAgICAgICAgY29uc3QgY2xvc3VyZVZhcnMgPSBjbG9zdXJlVmFyc0ZuKCk7XG4gICAgICAgIHJldHVybiB7IHN0ZXBJZCwgY2xvc3VyZVZhcnMgfTtcbiAgICAgIH1cblxuICAgICAgLy8gTm8gY2xvc3VyZSB2YXJpYWJsZXMgLSByZXR1cm4gb2JqZWN0IHdpdGgganVzdCBzdGVwSWRcbiAgICAgIHJldHVybiB7IHN0ZXBJZCB9O1xuICAgIH0sXG4gICAgVVJMOiAodmFsdWUpID0+IHZhbHVlIGluc3RhbmNlb2YgZ2xvYmFsLlVSTCAmJiB2YWx1ZS5ocmVmLFxuICAgIFdvcmtmbG93RnVuY3Rpb246ICh2YWx1ZSkgPT4ge1xuICAgICAgLy8gT25seSBtYXRjaCBmdW5jdGlvbiByZWZlcmVuY2VzIHdpdGggYSB3b3JrZmxvd0lkIHByb3BlcnR5IChzZXQgYnlcbiAgICAgIC8vIHRoZSBTV0MgY29tcGlsZXIgb24gd29ya2Zsb3cgZnVuY3Rpb25zKS4gUGxhaW4geyB3b3JrZmxvd0lkIH0gb2JqZWN0c1xuICAgICAgLy8gYXJlIE5PVCBtYXRjaGVkIOKAlCB0aGlzIHByZXZlbnRzIGluZmluaXRlIHJlY3Vyc2lvbiBzaW5jZSB0aGUgcmVkdWNlZFxuICAgICAgLy8gZm9ybSB7IHdvcmtmbG93SWQgfSBpcyBhIHBsYWluIG9iamVjdCwgbm90IGEgZnVuY3Rpb24uXG4gICAgICBpZiAodHlwZW9mIHZhbHVlICE9PSAnZnVuY3Rpb24nKSByZXR1cm4gZmFsc2U7XG4gICAgICBjb25zdCB3b3JrZmxvd0lkID0gKHZhbHVlIGFzIGFueSkud29ya2Zsb3dJZDtcbiAgICAgIGlmICh0eXBlb2Ygd29ya2Zsb3dJZCAhPT0gJ3N0cmluZycpIHJldHVybiBmYWxzZTtcbiAgICAgIHJldHVybiB7IHdvcmtmbG93SWQgfTtcbiAgICB9LFxuICAgIFVSTFNlYXJjaFBhcmFtczogKHZhbHVlKSA9PiB7XG4gICAgICBpZiAoISh2YWx1ZSBpbnN0YW5jZW9mIGdsb2JhbC5VUkxTZWFyY2hQYXJhbXMpKSByZXR1cm4gZmFsc2U7XG5cbiAgICAgIC8vIEF2b2lkIHJldHVybmluZyBhIGZhbHN5IHZhbHVlIHdoZW4gdGhlIFVSTFNlYXJjaFBhcmFtcyBpcyBlbXB0eVxuICAgICAgaWYgKHZhbHVlLnNpemUgPT09IDApIHJldHVybiAnLic7XG5cbiAgICAgIHJldHVybiBTdHJpbmcodmFsdWUpO1xuICAgIH0sXG4gICAgVWludDhBcnJheTogKHZhbHVlKSA9PlxuICAgICAgdmFsdWUgaW5zdGFuY2VvZiBnbG9iYWwuVWludDhBcnJheSAmJiB2aWV3VG9CYXNlNjQodmFsdWUpLFxuICAgIFVpbnQ4Q2xhbXBlZEFycmF5OiAodmFsdWUpID0+XG4gICAgICB2YWx1ZSBpbnN0YW5jZW9mIGdsb2JhbC5VaW50OENsYW1wZWRBcnJheSAmJiB2aWV3VG9CYXNlNjQodmFsdWUpLFxuICAgIFVpbnQxNkFycmF5OiAodmFsdWUpID0+XG4gICAgICB2YWx1ZSBpbnN0YW5jZW9mIGdsb2JhbC5VaW50MTZBcnJheSAmJiB2aWV3VG9CYXNlNjQodmFsdWUpLFxuICAgIFVpbnQzMkFycmF5OiAodmFsdWUpID0+XG4gICAgICB2YWx1ZSBpbnN0YW5jZW9mIGdsb2JhbC5VaW50MzJBcnJheSAmJiB2aWV3VG9CYXNlNjQodmFsdWUpLFxuICB9IGFzIGNvbnN0IHNhdGlzZmllcyBQYXJ0aWFsPFJlZHVjZXJzPjtcbn1cblxuLyoqXG4gKiBSZWR1Y2VycyBmb3Igc2VyaWFsaXphdGlvbiBib3VuZGFyeSBmcm9tIHRoZSBjbGllbnQgc2lkZSwgcGFzc2luZyBhcmd1bWVudHNcbiAqIHRvIHRoZSB3b3JrZmxvdyBoYW5kbGVyLlxuICpcbiAqIEBwYXJhbSBnbG9iYWxcbiAqIEBwYXJhbSBvcHNcbiAqIEByZXR1cm5zXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRFeHRlcm5hbFJlZHVjZXJzKFxuICBnbG9iYWw6IFJlY29yZDxzdHJpbmcsIGFueT4gPSBnbG9iYWxUaGlzLFxuICBvcHM6IFByb21pc2U8dm9pZD5bXSxcbiAgcnVuSWQ6IHN0cmluZyxcbiAgY3J5cHRvS2V5OiBFbmNyeXB0aW9uS2V5UGFyYW1cbik6IFJlZHVjZXJzIHtcbiAgcmV0dXJuIHtcbiAgICAuLi5nZXRDb21tb25SZWR1Y2VycyhnbG9iYWwpLFxuXG4gICAgUmVhZGFibGVTdHJlYW06ICh2YWx1ZSkgPT4ge1xuICAgICAgaWYgKCEodmFsdWUgaW5zdGFuY2VvZiBnbG9iYWwuUmVhZGFibGVTdHJlYW0pKSByZXR1cm4gZmFsc2U7XG5cbiAgICAgIC8vIFN0cmVhbSBtdXN0IG5vdCBiZSBsb2NrZWQgd2hlbiBwYXNzaW5nIGFjcm9zcyBleGVjdXRpb24gYm91bmRhcnlcbiAgICAgIGlmICh2YWx1ZS5sb2NrZWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdSZWFkYWJsZVN0cmVhbSBpcyBsb2NrZWQnKTtcbiAgICAgIH1cblxuICAgICAgY29uc3Qgc3RyZWFtSWQgPSAoKGdsb2JhbCBhcyBhbnkpW1NUQUJMRV9VTElEXSB8fCBkZWZhdWx0VWxpZCkoKTtcbiAgICAgIGNvbnN0IG5hbWUgPSBgc3RybV8ke3N0cmVhbUlkfWA7XG4gICAgICBjb25zdCB0eXBlID0gZ2V0U3RyZWFtVHlwZSh2YWx1ZSk7XG5cbiAgICAgIGNvbnN0IHdyaXRhYmxlID0gbmV3IFdvcmtmbG93U2VydmVyV3JpdGFibGVTdHJlYW0ocnVuSWQsIG5hbWUpO1xuICAgICAgaWYgKHR5cGUgPT09ICdieXRlcycpIHtcbiAgICAgICAgb3BzLnB1c2godmFsdWUucGlwZVRvKHdyaXRhYmxlKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBvcHMucHVzaChcbiAgICAgICAgICB2YWx1ZVxuICAgICAgICAgICAgLnBpcGVUaHJvdWdoKFxuICAgICAgICAgICAgICBnZXRTZXJpYWxpemVTdHJlYW0oXG4gICAgICAgICAgICAgICAgZ2V0RXh0ZXJuYWxSZWR1Y2VycyhnbG9iYWwsIG9wcywgcnVuSWQsIGNyeXB0b0tleSksXG4gICAgICAgICAgICAgICAgY3J5cHRvS2V5XG4gICAgICAgICAgICAgIClcbiAgICAgICAgICAgIClcbiAgICAgICAgICAgIC5waXBlVG8od3JpdGFibGUpXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHM6IFNlcmlhbGl6YWJsZVNwZWNpYWxbJ1JlYWRhYmxlU3RyZWFtJ10gPSB7IG5hbWUgfTtcbiAgICAgIGlmICh0eXBlKSBzLnR5cGUgPSB0eXBlO1xuICAgICAgcmV0dXJuIHM7XG4gICAgfSxcblxuICAgIFdyaXRhYmxlU3RyZWFtOiAodmFsdWUpID0+IHtcbiAgICAgIGlmICghKHZhbHVlIGluc3RhbmNlb2YgZ2xvYmFsLldyaXRhYmxlU3RyZWFtKSkgcmV0dXJuIGZhbHNlO1xuXG4gICAgICBjb25zdCBzdHJlYW1JZCA9ICgoZ2xvYmFsIGFzIGFueSlbU1RBQkxFX1VMSURdIHx8IGRlZmF1bHRVbGlkKSgpO1xuICAgICAgY29uc3QgbmFtZSA9IGBzdHJtXyR7c3RyZWFtSWR9YDtcblxuICAgICAgY29uc3QgcmVhZGFibGUgPSBuZXcgV29ya2Zsb3dTZXJ2ZXJSZWFkYWJsZVN0cmVhbShydW5JZCwgbmFtZSk7XG4gICAgICBvcHMucHVzaChyZWFkYWJsZS5waXBlVG8odmFsdWUpKTtcblxuICAgICAgcmV0dXJuIHsgbmFtZSB9O1xuICAgIH0sXG4gIH07XG59XG5cbi8qKlxuICogUmVkdWNlcnMgZm9yIHNlcmlhbGl6YXRpb24gYm91bmRhcnkgZnJvbSB3aXRoaW4gdGhlIHdvcmtmbG93IGV4ZWN1dGlvblxuICogZW52aXJvbm1lbnQsIHBhc3NpbmcgcmV0dXJuIHZhbHVlIHRvIHRoZSBjbGllbnQgc2lkZSBhbmQgaW50byBzdGVwIGFyZ3VtZW50cy5cbiAqXG4gKiBAcGFyYW0gZ2xvYmFsXG4gKiBAcmV0dXJuc1xuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0V29ya2Zsb3dSZWR1Y2VycyhcbiAgZ2xvYmFsOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0gZ2xvYmFsVGhpc1xuKTogUmVkdWNlcnMge1xuICByZXR1cm4ge1xuICAgIC4uLmdldENvbW1vblJlZHVjZXJzKGdsb2JhbCksXG5cbiAgICAvLyBSZWFkYWJsZS9Xcml0YWJsZSBzdHJlYW1zIGZyb20gd2l0aGluIHRoZSB3b3JrZmxvdyBleGVjdXRpb24gZW52aXJvbm1lbnRcbiAgICAvLyBhcmUgc2ltcGx5IFwiaGFuZGxlc1wiIHRoYXQgY2FuIGJlIHBhc3NlZCBhcm91bmQgdG8gb3RoZXIgc3RlcHMuXG4gICAgUmVhZGFibGVTdHJlYW06ICh2YWx1ZSkgPT4ge1xuICAgICAgaWYgKCEodmFsdWUgaW5zdGFuY2VvZiBnbG9iYWwuUmVhZGFibGVTdHJlYW0pKSByZXR1cm4gZmFsc2U7XG5cbiAgICAgIC8vIENoZWNrIGlmIHRoaXMgaXMgYSBmYWtlIHN0cmVhbSBzdG9yaW5nIEJvZHlJbml0IGZyb20gUmVxdWVzdC9SZXNwb25zZSBjb25zdHJ1Y3RvclxuICAgICAgY29uc3QgYm9keUluaXQgPSB2YWx1ZVtCT0RZX0lOSVRfU1lNQk9MXTtcbiAgICAgIGlmIChib2R5SW5pdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIC8vIFRoaXMgaXMgYSBmYWtlIHN0cmVhbSAtIHNlcmlhbGl6ZSB0aGUgQm9keUluaXQgZGlyZWN0bHlcbiAgICAgICAgLy8gZGV2YWx1ZSB3aWxsIGhhbmRsZSBzZXJpYWxpemluZyBzdHJpbmdzLCBVaW50OEFycmF5LCBldGMuXG4gICAgICAgIHJldHVybiB7IGJvZHlJbml0IH07XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IG5hbWUgPSB2YWx1ZVtTVFJFQU1fTkFNRV9TWU1CT0xdO1xuICAgICAgaWYgKCFuYW1lKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignUmVhZGFibGVTdHJlYW0gYG5hbWVgIGlzIG5vdCBzZXQnKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHM6IFNlcmlhbGl6YWJsZVNwZWNpYWxbJ1JlYWRhYmxlU3RyZWFtJ10gPSB7IG5hbWUgfTtcbiAgICAgIGNvbnN0IHR5cGUgPSB2YWx1ZVtTVFJFQU1fVFlQRV9TWU1CT0xdO1xuICAgICAgaWYgKHR5cGUpIHMudHlwZSA9IHR5cGU7XG4gICAgICByZXR1cm4gcztcbiAgICB9LFxuICAgIFdyaXRhYmxlU3RyZWFtOiAodmFsdWUpID0+IHtcbiAgICAgIGlmICghKHZhbHVlIGluc3RhbmNlb2YgZ2xvYmFsLldyaXRhYmxlU3RyZWFtKSkgcmV0dXJuIGZhbHNlO1xuICAgICAgY29uc3QgbmFtZSA9IHZhbHVlW1NUUkVBTV9OQU1FX1NZTUJPTF07XG4gICAgICBpZiAoIW5hbWUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdXcml0YWJsZVN0cmVhbSBgbmFtZWAgaXMgbm90IHNldCcpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHsgbmFtZSB9O1xuICAgIH0sXG4gIH07XG59XG5cbi8qKlxuICogUmVkdWNlcnMgZm9yIHNlcmlhbGl6YXRpb24gYm91bmRhcnkgZnJvbSB3aXRoaW4gdGhlIHN0ZXAgZXhlY3V0aW9uXG4gKiBlbnZpcm9ubWVudCwgcGFzc2luZyByZXR1cm4gdmFsdWUgdG8gdGhlIHdvcmtmbG93IGhhbmRsZXIuXG4gKlxuICogQHBhcmFtIGdsb2JhbFxuICogQHBhcmFtIG9wc1xuICogQHBhcmFtIHJ1bklkXG4gKiBAcmV0dXJuc1xuICovXG5mdW5jdGlvbiBnZXRTdGVwUmVkdWNlcnMoXG4gIGdsb2JhbDogUmVjb3JkPHN0cmluZywgYW55PiA9IGdsb2JhbFRoaXMsXG4gIG9wczogUHJvbWlzZTx2b2lkPltdLFxuICBydW5JZDogc3RyaW5nLFxuICBjcnlwdG9LZXk6IEVuY3J5cHRpb25LZXlQYXJhbVxuKTogUmVkdWNlcnMge1xuICByZXR1cm4ge1xuICAgIC4uLmdldENvbW1vblJlZHVjZXJzKGdsb2JhbCksXG5cbiAgICBSZWFkYWJsZVN0cmVhbTogKHZhbHVlKSA9PiB7XG4gICAgICBpZiAoISh2YWx1ZSBpbnN0YW5jZW9mIGdsb2JhbC5SZWFkYWJsZVN0cmVhbSkpIHJldHVybiBmYWxzZTtcblxuICAgICAgLy8gU3RyZWFtIG11c3Qgbm90IGJlIGxvY2tlZCB3aGVuIHBhc3NpbmcgYWNyb3NzIGV4ZWN1dGlvbiBib3VuZGFyeVxuICAgICAgaWYgKHZhbHVlLmxvY2tlZCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1JlYWRhYmxlU3RyZWFtIGlzIGxvY2tlZCcpO1xuICAgICAgfVxuXG4gICAgICAvLyBDaGVjayBpZiB0aGUgc3RyZWFtIGFscmVhZHkgaGFzIHRoZSBuYW1lIHN5bWJvbCBzZXQsIGluIHdoaWNoIGNhc2VcbiAgICAgIC8vIGl0J3MgYWxyZWFkeSBiZWluZyBzdW5rIHRvIHRoZSBzZXJ2ZXIgYW5kIHdlIGNhbiBqdXN0IHJldHVybiB0aGVcbiAgICAgIC8vIG5hbWUgYW5kIHR5cGUuXG4gICAgICBsZXQgbmFtZSA9IHZhbHVlW1NUUkVBTV9OQU1FX1NZTUJPTF07XG4gICAgICBsZXQgdHlwZSA9IHZhbHVlW1NUUkVBTV9UWVBFX1NZTUJPTF07XG5cbiAgICAgIGlmICghbmFtZSkge1xuICAgICAgICBjb25zdCBzdHJlYW1JZCA9ICgoZ2xvYmFsIGFzIGFueSlbU1RBQkxFX1VMSURdIHx8IGRlZmF1bHRVbGlkKSgpO1xuICAgICAgICBuYW1lID0gYHN0cm1fJHtzdHJlYW1JZH1gO1xuICAgICAgICB0eXBlID0gZ2V0U3RyZWFtVHlwZSh2YWx1ZSk7XG5cbiAgICAgICAgY29uc3Qgd3JpdGFibGUgPSBuZXcgV29ya2Zsb3dTZXJ2ZXJXcml0YWJsZVN0cmVhbShydW5JZCwgbmFtZSk7XG4gICAgICAgIGlmICh0eXBlID09PSAnYnl0ZXMnKSB7XG4gICAgICAgICAgb3BzLnB1c2godmFsdWUucGlwZVRvKHdyaXRhYmxlKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgb3BzLnB1c2goXG4gICAgICAgICAgICB2YWx1ZVxuICAgICAgICAgICAgICAucGlwZVRocm91Z2goXG4gICAgICAgICAgICAgICAgZ2V0U2VyaWFsaXplU3RyZWFtKFxuICAgICAgICAgICAgICAgICAgZ2V0U3RlcFJlZHVjZXJzKGdsb2JhbCwgb3BzLCBydW5JZCwgY3J5cHRvS2V5KSxcbiAgICAgICAgICAgICAgICAgIGNyeXB0b0tleVxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAucGlwZVRvKHdyaXRhYmxlKVxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgY29uc3QgczogU2VyaWFsaXphYmxlU3BlY2lhbFsnUmVhZGFibGVTdHJlYW0nXSA9IHsgbmFtZSB9O1xuICAgICAgaWYgKHR5cGUpIHMudHlwZSA9IHR5cGU7XG4gICAgICByZXR1cm4gcztcbiAgICB9LFxuXG4gICAgV3JpdGFibGVTdHJlYW06ICh2YWx1ZSkgPT4ge1xuICAgICAgaWYgKCEodmFsdWUgaW5zdGFuY2VvZiBnbG9iYWwuV3JpdGFibGVTdHJlYW0pKSByZXR1cm4gZmFsc2U7XG5cbiAgICAgIGxldCBuYW1lID0gdmFsdWVbU1RSRUFNX05BTUVfU1lNQk9MXTtcbiAgICAgIGlmICghbmFtZSkge1xuICAgICAgICBjb25zdCBzdHJlYW1JZCA9ICgoZ2xvYmFsIGFzIGFueSlbU1RBQkxFX1VMSURdIHx8IGRlZmF1bHRVbGlkKSgpO1xuICAgICAgICBuYW1lID0gYHN0cm1fJHtzdHJlYW1JZH1gO1xuICAgICAgICBvcHMucHVzaChcbiAgICAgICAgICBuZXcgV29ya2Zsb3dTZXJ2ZXJSZWFkYWJsZVN0cmVhbShydW5JZCwgbmFtZSlcbiAgICAgICAgICAgIC5waXBlVGhyb3VnaChcbiAgICAgICAgICAgICAgZ2V0RGVzZXJpYWxpemVTdHJlYW0oXG4gICAgICAgICAgICAgICAgZ2V0U3RlcFJldml2ZXJzKGdsb2JhbCwgb3BzLCBydW5JZCwgY3J5cHRvS2V5KSxcbiAgICAgICAgICAgICAgICBjcnlwdG9LZXlcbiAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgKVxuICAgICAgICAgICAgLnBpcGVUbyh2YWx1ZSlcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHsgbmFtZSB9O1xuICAgIH0sXG4gIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRDb21tb25SZXZpdmVycyhnbG9iYWw6IFJlY29yZDxzdHJpbmcsIGFueT4gPSBnbG9iYWxUaGlzKSB7XG4gIGZ1bmN0aW9uIHJldml2ZUFycmF5QnVmZmVyKHZhbHVlOiBzdHJpbmcpIHtcbiAgICAvLyBIYW5kbGUgc2VudGluZWwgdmFsdWUgZm9yIHplcm8tbGVuZ3RoIGJ1ZmZlcnNcbiAgICBjb25zdCBiYXNlNjQgPSB2YWx1ZSA9PT0gJy4nID8gJycgOiB2YWx1ZTtcbiAgICBjb25zdCBidWZmZXIgPSBCdWZmZXIuZnJvbShiYXNlNjQsICdiYXNlNjQnKTtcbiAgICBjb25zdCBhcnJheUJ1ZmZlciA9IG5ldyBnbG9iYWwuQXJyYXlCdWZmZXIoYnVmZmVyLmxlbmd0aCk7XG4gICAgY29uc3QgdWludDhBcnJheSA9IG5ldyBnbG9iYWwuVWludDhBcnJheShhcnJheUJ1ZmZlcik7XG4gICAgdWludDhBcnJheS5zZXQoYnVmZmVyKTtcbiAgICByZXR1cm4gYXJyYXlCdWZmZXI7XG4gIH1cbiAgcmV0dXJuIHtcbiAgICBBcnJheUJ1ZmZlcjogcmV2aXZlQXJyYXlCdWZmZXIsXG4gICAgQmlnSW50OiAodmFsdWU6IHN0cmluZykgPT4gZ2xvYmFsLkJpZ0ludCh2YWx1ZSksXG4gICAgQmlnSW50NjRBcnJheTogKHZhbHVlOiBzdHJpbmcpID0+IHtcbiAgICAgIGNvbnN0IGFiID0gcmV2aXZlQXJyYXlCdWZmZXIodmFsdWUpO1xuICAgICAgcmV0dXJuIG5ldyBnbG9iYWwuQmlnSW50NjRBcnJheShhYik7XG4gICAgfSxcbiAgICBCaWdVaW50NjRBcnJheTogKHZhbHVlOiBzdHJpbmcpID0+IHtcbiAgICAgIGNvbnN0IGFiID0gcmV2aXZlQXJyYXlCdWZmZXIodmFsdWUpO1xuICAgICAgcmV0dXJuIG5ldyBnbG9iYWwuQmlnVWludDY0QXJyYXkoYWIpO1xuICAgIH0sXG4gICAgRGF0ZTogKHZhbHVlKSA9PiBuZXcgZ2xvYmFsLkRhdGUodmFsdWUpLFxuICAgIERPTUV4Y2VwdGlvbjogKHZhbHVlKSA9PiB7XG4gICAgICBjb25zdCBlcnJvciA9IG5ldyBnbG9iYWwuRE9NRXhjZXB0aW9uKHZhbHVlLm1lc3NhZ2UsIHZhbHVlLm5hbWUpO1xuICAgICAgaWYgKHZhbHVlLnN0YWNrICE9PSB1bmRlZmluZWQpIGVycm9yLnN0YWNrID0gdmFsdWUuc3RhY2s7XG4gICAgICAvLyBET01FeGNlcHRpb24ncyBjb25zdHJ1Y3RvciBkb2Vzbid0IGFjY2VwdCBhIGNhdXNlIG9wdGlvbiwgc29cbiAgICAgIC8vIHdlIHNldCBpdCBtYW51YWxseSB3aGVuIHByZXNlbnQgaW4gdGhlIHNlcmlhbGl6ZWQgZGF0YS5cbiAgICAgIGlmICgnY2F1c2UnIGluIHZhbHVlKSBlcnJvci5jYXVzZSA9IHZhbHVlLmNhdXNlO1xuICAgICAgcmV0dXJuIGVycm9yO1xuICAgIH0sXG4gICAgRXJyb3I6ICh2YWx1ZSkgPT4ge1xuICAgICAgY29uc3QgZXJyb3IgPSBuZXcgZ2xvYmFsLkVycm9yKHZhbHVlLm1lc3NhZ2UpO1xuICAgICAgZXJyb3IubmFtZSA9IHZhbHVlLm5hbWU7XG4gICAgICBlcnJvci5zdGFjayA9IHZhbHVlLnN0YWNrO1xuICAgICAgcmV0dXJuIGVycm9yO1xuICAgIH0sXG4gICAgRmxvYXQzMkFycmF5OiAodmFsdWU6IHN0cmluZykgPT4ge1xuICAgICAgY29uc3QgYWIgPSByZXZpdmVBcnJheUJ1ZmZlcih2YWx1ZSk7XG4gICAgICByZXR1cm4gbmV3IGdsb2JhbC5GbG9hdDMyQXJyYXkoYWIpO1xuICAgIH0sXG4gICAgRmxvYXQ2NEFycmF5OiAodmFsdWU6IHN0cmluZykgPT4ge1xuICAgICAgY29uc3QgYWIgPSByZXZpdmVBcnJheUJ1ZmZlcih2YWx1ZSk7XG4gICAgICByZXR1cm4gbmV3IGdsb2JhbC5GbG9hdDY0QXJyYXkoYWIpO1xuICAgIH0sXG4gICAgSGVhZGVyczogKHZhbHVlKSA9PiBuZXcgZ2xvYmFsLkhlYWRlcnModmFsdWUpLFxuICAgIEludDhBcnJheTogKHZhbHVlOiBzdHJpbmcpID0+IHtcbiAgICAgIGNvbnN0IGFiID0gcmV2aXZlQXJyYXlCdWZmZXIodmFsdWUpO1xuICAgICAgcmV0dXJuIG5ldyBnbG9iYWwuSW50OEFycmF5KGFiKTtcbiAgICB9LFxuICAgIEludDE2QXJyYXk6ICh2YWx1ZTogc3RyaW5nKSA9PiB7XG4gICAgICBjb25zdCBhYiA9IHJldml2ZUFycmF5QnVmZmVyKHZhbHVlKTtcbiAgICAgIHJldHVybiBuZXcgZ2xvYmFsLkludDE2QXJyYXkoYWIpO1xuICAgIH0sXG4gICAgSW50MzJBcnJheTogKHZhbHVlOiBzdHJpbmcpID0+IHtcbiAgICAgIGNvbnN0IGFiID0gcmV2aXZlQXJyYXlCdWZmZXIodmFsdWUpO1xuICAgICAgcmV0dXJuIG5ldyBnbG9iYWwuSW50MzJBcnJheShhYik7XG4gICAgfSxcbiAgICBNYXA6ICh2YWx1ZSkgPT4gbmV3IGdsb2JhbC5NYXAodmFsdWUpLFxuICAgIFJlZ0V4cDogKHZhbHVlKSA9PiBuZXcgZ2xvYmFsLlJlZ0V4cCh2YWx1ZS5zb3VyY2UsIHZhbHVlLmZsYWdzKSxcbiAgICBDbGFzczogKHZhbHVlKSA9PiB7XG4gICAgICBjb25zdCBjbGFzc0lkID0gdmFsdWUuY2xhc3NJZDtcbiAgICAgIC8vIFBhc3MgdGhlIGdsb2JhbCBvYmplY3QgdG8gc3VwcG9ydCBWTSBjb250ZXh0cyB3aGVyZSBjbGFzc2VzIGFyZSByZWdpc3RlcmVkXG4gICAgICAvLyBvbiB0aGUgVk0ncyBnbG9iYWwgcmF0aGVyIHRoYW4gdGhlIGhvc3QncyBnbG9iYWxUaGlzXG4gICAgICBjb25zdCBjbHMgPSBnZXRTZXJpYWxpemF0aW9uQ2xhc3MoY2xhc3NJZCwgZ2xvYmFsKTtcbiAgICAgIGlmICghY2xzKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICBgQ2xhc3MgXCIke2NsYXNzSWR9XCIgbm90IGZvdW5kLiBNYWtlIHN1cmUgdGhlIGNsYXNzIGlzIHJlZ2lzdGVyZWQgd2l0aCByZWdpc3RlclNlcmlhbGl6YXRpb25DbGFzcy5gXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICByZXR1cm4gY2xzO1xuICAgIH0sXG4gICAgSW5zdGFuY2U6ICh2YWx1ZSkgPT4ge1xuICAgICAgY29uc3QgY2xhc3NJZCA9IHZhbHVlLmNsYXNzSWQ7XG4gICAgICBjb25zdCBkYXRhID0gdmFsdWUuZGF0YTtcblxuICAgICAgLy8gTG9vayB1cCB0aGUgY2xhc3MgYnkgY2xhc3NJZCBmcm9tIHRoZSByZWdpc3RyeVxuICAgICAgLy8gUGFzcyB0aGUgZ2xvYmFsIG9iamVjdCB0byBzdXBwb3J0IFZNIGNvbnRleHRzIHdoZXJlIGNsYXNzZXMgYXJlIHJlZ2lzdGVyZWRcbiAgICAgIC8vIG9uIHRoZSBWTSdzIGdsb2JhbCByYXRoZXIgdGhhbiB0aGUgaG9zdCdzIGdsb2JhbFRoaXNcbiAgICAgIGNvbnN0IGNscyA9IGdldFNlcmlhbGl6YXRpb25DbGFzcyhjbGFzc0lkLCBnbG9iYWwpO1xuXG4gICAgICBpZiAoIWNscykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgYENsYXNzIFwiJHtjbGFzc0lkfVwiIG5vdCBmb3VuZC4gTWFrZSBzdXJlIHRoZSBjbGFzcyBpcyByZWdpc3RlcmVkIHdpdGggcmVnaXN0ZXJTZXJpYWxpemF0aW9uQ2xhc3MuYFxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICAvLyBHZXQgdGhlIGRlc2VyaWFsaXplciBmcm9tIHRoZSBjbGFzc1xuICAgICAgY29uc3QgZGVzZXJpYWxpemUgPSAoY2xzIGFzIGFueSlbV09SS0ZMT1dfREVTRVJJQUxJWkVdO1xuICAgICAgaWYgKHR5cGVvZiBkZXNlcmlhbGl6ZSAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgYENsYXNzIFwiJHtjbGFzc0lkfVwiIGRvZXMgbm90IGhhdmUgYSBzdGF0aWMgJHtTdHJpbmcoV09SS0ZMT1dfREVTRVJJQUxJWkUpfSBtZXRob2QuYFxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICAvLyBEZXNlcmlhbGl6ZSB0aGUgaW5zdGFuY2UgdXNpbmcgdGhlIGN1c3RvbSBkZXNlcmlhbGl6ZXJcbiAgICAgIHJldHVybiBkZXNlcmlhbGl6ZS5jYWxsKGNscywgZGF0YSk7XG4gICAgfSxcbiAgICBTZXQ6ICh2YWx1ZSkgPT4gbmV3IGdsb2JhbC5TZXQodmFsdWUpLFxuICAgIFVSTDogKHZhbHVlKSA9PiBuZXcgZ2xvYmFsLlVSTCh2YWx1ZSksXG4gICAgVVJMU2VhcmNoUGFyYW1zOiAodmFsdWUpID0+XG4gICAgICBuZXcgZ2xvYmFsLlVSTFNlYXJjaFBhcmFtcyh2YWx1ZSA9PT0gJy4nID8gJycgOiB2YWx1ZSksXG4gICAgVWludDhBcnJheTogKHZhbHVlOiBzdHJpbmcpID0+IHtcbiAgICAgIGNvbnN0IGFiID0gcmV2aXZlQXJyYXlCdWZmZXIodmFsdWUpO1xuICAgICAgcmV0dXJuIG5ldyBnbG9iYWwuVWludDhBcnJheShhYik7XG4gICAgfSxcbiAgICBVaW50OENsYW1wZWRBcnJheTogKHZhbHVlOiBzdHJpbmcpID0+IHtcbiAgICAgIGNvbnN0IGFiID0gcmV2aXZlQXJyYXlCdWZmZXIodmFsdWUpO1xuICAgICAgcmV0dXJuIG5ldyBnbG9iYWwuVWludDhDbGFtcGVkQXJyYXkoYWIpO1xuICAgIH0sXG4gICAgVWludDE2QXJyYXk6ICh2YWx1ZTogc3RyaW5nKSA9PiB7XG4gICAgICBjb25zdCBhYiA9IHJldml2ZUFycmF5QnVmZmVyKHZhbHVlKTtcbiAgICAgIHJldHVybiBuZXcgZ2xvYmFsLlVpbnQxNkFycmF5KGFiKTtcbiAgICB9LFxuICAgIFVpbnQzMkFycmF5OiAodmFsdWU6IHN0cmluZykgPT4ge1xuICAgICAgY29uc3QgYWIgPSByZXZpdmVBcnJheUJ1ZmZlcih2YWx1ZSk7XG4gICAgICByZXR1cm4gbmV3IGdsb2JhbC5VaW50MzJBcnJheShhYik7XG4gICAgfSxcbiAgfSBhcyBjb25zdCBzYXRpc2ZpZXMgUGFydGlhbDxSZXZpdmVycz47XG59XG5cbi8qKlxuICogUmV2aXZlcnMgZm9yIGRlc2VyaWFsaXphdGlvbiBib3VuZGFyeSBmcm9tIHRoZSBjbGllbnQgc2lkZSxcbiAqIHJlY2VpdmluZyB0aGUgcmV0dXJuIHZhbHVlIGZyb20gdGhlIHdvcmtmbG93IGhhbmRsZXIuXG4gKlxuICogQHBhcmFtIGdsb2JhbFxuICogQHBhcmFtIG9wc1xuICogQHBhcmFtIHJ1bklkXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRFeHRlcm5hbFJldml2ZXJzKFxuICBnbG9iYWw6IFJlY29yZDxzdHJpbmcsIGFueT4gPSBnbG9iYWxUaGlzLFxuICBvcHM6IFByb21pc2U8dm9pZD5bXSxcbiAgcnVuSWQ6IHN0cmluZyxcbiAgY3J5cHRvS2V5OiBFbmNyeXB0aW9uS2V5UGFyYW1cbik6IFJldml2ZXJzIHtcbiAgcmV0dXJuIHtcbiAgICAuLi5nZXRDb21tb25SZXZpdmVycyhnbG9iYWwpLFxuXG4gICAgLy8gU3RlcEZ1bmN0aW9uIHNob3VsZCBub3QgYmUgcmV0dXJuZWQgZnJvbSB3b3JrZmxvd3MgdG8gY2xpZW50c1xuICAgIFN0ZXBGdW5jdGlvbjogKCkgPT4ge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAnU3RlcCBmdW5jdGlvbnMgY2Fubm90IGJlIGRlc2VyaWFsaXplZCBpbiBjbGllbnQgY29udGV4dC4gU3RlcCBmdW5jdGlvbnMgc2hvdWxkIG5vdCBiZSByZXR1cm5lZCBmcm9tIHdvcmtmbG93cy4nXG4gICAgICApO1xuICAgIH0sXG5cbiAgICBXb3JrZmxvd0Z1bmN0aW9uOiAodmFsdWUpID0+XG4gICAgICBPYmplY3QuYXNzaWduKFxuICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICAgJ1dvcmtmbG93IGZ1bmN0aW9ucyBjYW5ub3QgYmUgY2FsbGVkIGRpcmVjdGx5LiBVc2Ugc3RhcnQoKSB0byBpbnZva2UgdGhlbS4nXG4gICAgICAgICAgKTtcbiAgICAgICAgfSxcbiAgICAgICAgeyB3b3JrZmxvd0lkOiB2YWx1ZS53b3JrZmxvd0lkIH1cbiAgICAgICksXG5cbiAgICBSZXF1ZXN0OiAodmFsdWUpID0+IHtcbiAgICAgIHJldHVybiBuZXcgZ2xvYmFsLlJlcXVlc3QodmFsdWUudXJsLCB7XG4gICAgICAgIG1ldGhvZDogdmFsdWUubWV0aG9kLFxuICAgICAgICBoZWFkZXJzOiBuZXcgZ2xvYmFsLkhlYWRlcnModmFsdWUuaGVhZGVycyksXG4gICAgICAgIGJvZHk6IHZhbHVlLmJvZHksXG4gICAgICAgIGR1cGxleDogdmFsdWUuZHVwbGV4LFxuICAgICAgfSk7XG4gICAgfSxcbiAgICBSZXNwb25zZTogKHZhbHVlKSA9PiB7XG4gICAgICAvLyBOb3RlOiBSZXNwb25zZSBjb25zdHJ1Y3RvciBvbmx5IGFjY2VwdHMgc3RhdHVzLCBzdGF0dXNUZXh0LCBhbmQgaGVhZGVyc1xuICAgICAgLy8gVGhlIHR5cGUsIHVybCwgYW5kIHJlZGlyZWN0ZWQgcHJvcGVydGllcyBhcmUgcmVhZC1vbmx5IGFuZCBzZXQgYnkgdGhlIGNvbnN0cnVjdG9yXG4gICAgICByZXR1cm4gbmV3IGdsb2JhbC5SZXNwb25zZSh2YWx1ZS5ib2R5LCB7XG4gICAgICAgIHN0YXR1czogdmFsdWUuc3RhdHVzLFxuICAgICAgICBzdGF0dXNUZXh0OiB2YWx1ZS5zdGF0dXNUZXh0LFxuICAgICAgICBoZWFkZXJzOiBuZXcgZ2xvYmFsLkhlYWRlcnModmFsdWUuaGVhZGVycyksXG4gICAgICB9KTtcbiAgICB9LFxuICAgIFJlYWRhYmxlU3RyZWFtOiAodmFsdWUpID0+IHtcbiAgICAgIC8vIElmIHRoaXMgaGFzIGJvZHlJbml0LCBpdCBjYW1lIGZyb20gYSBSZXNwb25zZSBjb25zdHJ1Y3RvclxuICAgICAgLy8gQ29udmVydCBpdCB0byBhIFJFQUwgc3RyZWFtIG5vdyB0aGF0IHdlJ3JlIG91dHNpZGUgdGhlIHdvcmtmbG93XG4gICAgICBpZiAoJ2JvZHlJbml0JyBpbiB2YWx1ZSkge1xuICAgICAgICBjb25zdCBib2R5SW5pdCA9IHZhbHVlLmJvZHlJbml0O1xuICAgICAgICAvLyBVc2UgdGhlIG5hdGl2ZSBSZXNwb25zZSBjb25zdHJ1Y3RvciB0byBwcm9wZXJseSBjb252ZXJ0IEJvZHlJbml0IHRvIFJlYWRhYmxlU3RyZWFtXG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gbmV3IGdsb2JhbC5SZXNwb25zZShib2R5SW5pdCk7XG4gICAgICAgIHJldHVybiByZXNwb25zZS5ib2R5O1xuICAgICAgfVxuXG4gICAgICBjb25zdCByZWFkYWJsZSA9IG5ldyBXb3JrZmxvd1NlcnZlclJlYWRhYmxlU3RyZWFtKFxuICAgICAgICBydW5JZCxcbiAgICAgICAgdmFsdWUubmFtZSxcbiAgICAgICAgdmFsdWUuc3RhcnRJbmRleFxuICAgICAgKTtcbiAgICAgIGlmICh2YWx1ZS50eXBlID09PSAnYnl0ZXMnKSB7XG4gICAgICAgIC8vIEZvciBieXRlIHN0cmVhbXMsIHVzZSBmbHVzaGFibGUgcGlwZSB3aXRoIGxvY2sgcG9sbGluZ1xuICAgICAgICBjb25zdCBzdGF0ZSA9IGNyZWF0ZUZsdXNoYWJsZVN0YXRlKCk7XG4gICAgICAgIG9wcy5wdXNoKHN0YXRlLnByb21pc2UpO1xuXG4gICAgICAgIC8vIENyZWF0ZSBhbiBpZGVudGl0eSB0cmFuc2Zvcm0gdG8gZ2l2ZSB0aGUgdXNlciBhIHJlYWRhYmxlXG4gICAgICAgIGNvbnN0IHsgcmVhZGFibGU6IHVzZXJSZWFkYWJsZSwgd3JpdGFibGUgfSA9XG4gICAgICAgICAgbmV3IGdsb2JhbC5UcmFuc2Zvcm1TdHJlYW0oKTtcblxuICAgICAgICAvLyBTdGFydCB0aGUgZmx1c2hhYmxlIHBpcGUgaW4gdGhlIGJhY2tncm91bmRcbiAgICAgICAgZmx1c2hhYmxlUGlwZShyZWFkYWJsZSwgd3JpdGFibGUsIHN0YXRlKS5jYXRjaCgoKSA9PiB7XG4gICAgICAgICAgLy8gRXJyb3JzIGFyZSBoYW5kbGVkIHZpYSBzdGF0ZS5yZWplY3RcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gU3RhcnQgcG9sbGluZyB0byBkZXRlY3Qgd2hlbiB1c2VyIHJlbGVhc2VzIGxvY2tcbiAgICAgICAgcG9sbFJlYWRhYmxlTG9jayh1c2VyUmVhZGFibGUsIHN0YXRlKTtcblxuICAgICAgICByZXR1cm4gdXNlclJlYWRhYmxlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgdHJhbnNmb3JtID0gZ2V0RGVzZXJpYWxpemVTdHJlYW0oXG4gICAgICAgICAgZ2V0RXh0ZXJuYWxSZXZpdmVycyhnbG9iYWwsIG9wcywgcnVuSWQsIGNyeXB0b0tleSksXG4gICAgICAgICAgY3J5cHRvS2V5XG4gICAgICAgICk7XG4gICAgICAgIGNvbnN0IHN0YXRlID0gY3JlYXRlRmx1c2hhYmxlU3RhdGUoKTtcbiAgICAgICAgb3BzLnB1c2goc3RhdGUucHJvbWlzZSk7XG5cbiAgICAgICAgLy8gU3RhcnQgdGhlIGZsdXNoYWJsZSBwaXBlIGluIHRoZSBiYWNrZ3JvdW5kXG4gICAgICAgIGZsdXNoYWJsZVBpcGUocmVhZGFibGUsIHRyYW5zZm9ybS53cml0YWJsZSwgc3RhdGUpLmNhdGNoKCgpID0+IHtcbiAgICAgICAgICAvLyBFcnJvcnMgYXJlIGhhbmRsZWQgdmlhIHN0YXRlLnJlamVjdFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBTdGFydCBwb2xsaW5nIHRvIGRldGVjdCB3aGVuIHVzZXIgcmVsZWFzZXMgbG9ja1xuICAgICAgICBwb2xsUmVhZGFibGVMb2NrKHRyYW5zZm9ybS5yZWFkYWJsZSwgc3RhdGUpO1xuXG4gICAgICAgIHJldHVybiB0cmFuc2Zvcm0ucmVhZGFibGU7XG4gICAgICB9XG4gICAgfSxcbiAgICBXcml0YWJsZVN0cmVhbTogKHZhbHVlKSA9PiB7XG4gICAgICBjb25zdCBzZXJpYWxpemUgPSBnZXRTZXJpYWxpemVTdHJlYW0oXG4gICAgICAgIGdldEV4dGVybmFsUmVkdWNlcnMoZ2xvYmFsLCBvcHMsIHJ1bklkLCBjcnlwdG9LZXkpLFxuICAgICAgICBjcnlwdG9LZXlcbiAgICAgICk7XG4gICAgICBjb25zdCBzZXJ2ZXJXcml0YWJsZSA9IG5ldyBXb3JrZmxvd1NlcnZlcldyaXRhYmxlU3RyZWFtKFxuICAgICAgICBydW5JZCxcbiAgICAgICAgdmFsdWUubmFtZVxuICAgICAgKTtcblxuICAgICAgLy8gQ3JlYXRlIGZsdXNoYWJsZSBzdGF0ZSBmb3IgdGhpcyBzdHJlYW1cbiAgICAgIGNvbnN0IHN0YXRlID0gY3JlYXRlRmx1c2hhYmxlU3RhdGUoKTtcbiAgICAgIG9wcy5wdXNoKHN0YXRlLnByb21pc2UpO1xuXG4gICAgICAvLyBTdGFydCB0aGUgZmx1c2hhYmxlIHBpcGUgaW4gdGhlIGJhY2tncm91bmRcbiAgICAgIGZsdXNoYWJsZVBpcGUoc2VyaWFsaXplLnJlYWRhYmxlLCBzZXJ2ZXJXcml0YWJsZSwgc3RhdGUpLmNhdGNoKCgpID0+IHtcbiAgICAgICAgLy8gRXJyb3JzIGFyZSBoYW5kbGVkIHZpYSBzdGF0ZS5yZWplY3RcbiAgICAgIH0pO1xuXG4gICAgICAvLyBTdGFydCBwb2xsaW5nIHRvIGRldGVjdCB3aGVuIHVzZXIgcmVsZWFzZXMgbG9ja1xuICAgICAgcG9sbFdyaXRhYmxlTG9jayhzZXJpYWxpemUud3JpdGFibGUsIHN0YXRlKTtcblxuICAgICAgcmV0dXJuIHNlcmlhbGl6ZS53cml0YWJsZTtcbiAgICB9LFxuICB9O1xufVxuXG4vKipcbiAqIFJldml2ZXJzIGZvciBkZXNlcmlhbGl6YXRpb24gYm91bmRhcnkgZnJvbSB3aXRoaW4gdGhlIHdvcmtmbG93IGV4ZWN1dGlvblxuICogZW52aXJvbm1lbnQsIHJlY2VpdmluZyBhcmd1bWVudHMgZnJvbSB0aGUgY2xpZW50IHNpZGUsIGFuZCByZXR1cm4gdmFsdWVzXG4gKiBmcm9tIHRoZSBzdGVwcy5cbiAqXG4gKiBAcGFyYW0gZ2xvYmFsXG4gKiBAcmV0dXJuc1xuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0V29ya2Zsb3dSZXZpdmVycyhcbiAgZ2xvYmFsOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0gZ2xvYmFsVGhpc1xuKTogUmV2aXZlcnMge1xuICAvLyBHZXQgdGhlIHVzZVN0ZXAgZnVuY3Rpb24gZnJvbSB0aGUgVk0ncyBnbG9iYWxUaGlzXG4gIC8vIFRoaXMgaXMgc2V0IHVwIGJ5IHRoZSB3b3JrZmxvdyBydW5uZXIgaW4gd29ya2Zsb3cudHNcbiAgLy8gVXNlIFN5bWJvbC5mb3IgZGlyZWN0bHkgdG8gYWNjZXNzIHRoZSBzeW1ib2wgb24gdGhlIGdsb2JhbCBvYmplY3RcbiAgY29uc3QgdXNlU3RlcCA9IChnbG9iYWwgYXMgYW55KVtTeW1ib2wuZm9yKCdXT1JLRkxPV19VU0VfU1RFUCcpXSBhc1xuICAgIHwgKChcbiAgICAgICAgc3RlcElkOiBzdHJpbmcsXG4gICAgICAgIGNsb3N1cmVWYXJzRm4/OiAoKSA9PiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPlxuICAgICAgKSA9PiAoLi4uYXJnczogdW5rbm93bltdKSA9PiBQcm9taXNlPHVua25vd24+KVxuICAgIHwgdW5kZWZpbmVkO1xuXG4gIHJldHVybiB7XG4gICAgLi4uZ2V0Q29tbW9uUmV2aXZlcnMoZ2xvYmFsKSxcbiAgICAvLyBTdGVwRnVuY3Rpb24gcmV2aXZlciBmb3Igd29ya2Zsb3cgY29udGV4dCAtIHJldHVybnMgdXNlU3RlcCB3cmFwcGVyXG4gICAgLy8gVGhpcyBhbGxvd3Mgc3RlcCBmdW5jdGlvbnMgcGFzc2VkIGFzIGFyZ3VtZW50cyB0byBzdGFydCgpIHRvIGJlIGNhbGxlZCBkaXJlY3RseVxuICAgIC8vIGZyb20gd29ya2Zsb3cgY29kZSwganVzdCBsaWtlIHN0ZXAgZnVuY3Rpb25zIGRlZmluZWQgaW4gdGhlIHNhbWUgZmlsZVxuICAgIFN0ZXBGdW5jdGlvbjogKHZhbHVlKSA9PiB7XG4gICAgICBjb25zdCBzdGVwSWQgPSB2YWx1ZS5zdGVwSWQ7XG4gICAgICBjb25zdCBjbG9zdXJlVmFycyA9IHZhbHVlLmNsb3N1cmVWYXJzO1xuXG4gICAgICBpZiAoIXVzZVN0ZXApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICdXT1JLRkxPV19VU0VfU1RFUCBub3QgZm91bmQgb24gZ2xvYmFsIG9iamVjdC4gU3RlcCBmdW5jdGlvbnMgY2Fubm90IGJlIGRlc2VyaWFsaXplZCBvdXRzaWRlIHdvcmtmbG93IGNvbnRleHQuJ1xuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICBpZiAoY2xvc3VyZVZhcnMpIHtcbiAgICAgICAgLy8gRm9yIHN0ZXAgZnVuY3Rpb25zIHdpdGggY2xvc3VyZSB2YXJpYWJsZXMsIGNyZWF0ZSBhIHdyYXBwZXIgdGhhdCBwcm92aWRlcyB0aGVtXG4gICAgICAgIHJldHVybiB1c2VTdGVwKHN0ZXBJZCwgKCkgPT4gY2xvc3VyZVZhcnMpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHVzZVN0ZXAoc3RlcElkKTtcbiAgICB9LFxuICAgIFJlcXVlc3Q6ICh2YWx1ZSkgPT4ge1xuICAgICAgT2JqZWN0LnNldFByb3RvdHlwZU9mKHZhbHVlLCBnbG9iYWwuUmVxdWVzdC5wcm90b3R5cGUpO1xuICAgICAgY29uc3QgcmVzcG9uc2VXcml0YWJsZSA9IHZhbHVlLnJlc3BvbnNlV3JpdGFibGU7XG4gICAgICBpZiAocmVzcG9uc2VXcml0YWJsZSkge1xuICAgICAgICAodmFsdWUgYXMgYW55KVtXRUJIT09LX1JFU1BPTlNFX1dSSVRBQkxFXSA9IHJlc3BvbnNlV3JpdGFibGU7XG4gICAgICAgIGRlbGV0ZSB2YWx1ZS5yZXNwb25zZVdyaXRhYmxlO1xuICAgICAgICAodmFsdWUgYXMgYW55KS5yZXNwb25kV2l0aCA9ICgpID0+IHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICAnYHJlc3BvbmRXaXRoKClgIG11c3QgYmUgY2FsbGVkIGZyb20gd2l0aGluIGEgc3RlcCBmdW5jdGlvbidcbiAgICAgICAgICApO1xuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH0sXG4gICAgLy8gV29ya2Zsb3cgZnVuY3Rpb24gcmV2aXZlciBmb3Igd29ya2Zsb3cgY29udGV4dCDigJQgcmV0dXJucyBhIGZ1bmN0aW9uLWxpa2VcbiAgICAvLyBvYmplY3Qgd2l0aCAud29ya2Zsb3dJZCB0aGF0IG1pbWljcyB3aGF0IHRoZSBTV0MgY29tcGlsZXIgcHJvZHVjZXMsXG4gICAgV29ya2Zsb3dGdW5jdGlvbjogKHZhbHVlKSA9PlxuICAgICAgT2JqZWN0LmFzc2lnbihcbiAgICAgICAgKCkgPT4ge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgICdXb3JrZmxvdyBmdW5jdGlvbnMgY2Fubm90IGJlIGNhbGxlZCBkaXJlY3RseS4gVXNlIHN0YXJ0KCkgdG8gaW52b2tlIHRoZW0uJ1xuICAgICAgICAgICk7XG4gICAgICAgIH0sXG4gICAgICAgIHsgd29ya2Zsb3dJZDogdmFsdWUud29ya2Zsb3dJZCB9XG4gICAgICApLFxuICAgIFJlc3BvbnNlOiAodmFsdWUpID0+IHtcbiAgICAgIE9iamVjdC5zZXRQcm90b3R5cGVPZih2YWx1ZSwgZ2xvYmFsLlJlc3BvbnNlLnByb3RvdHlwZSk7XG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfSxcbiAgICBSZWFkYWJsZVN0cmVhbTogKHZhbHVlKSA9PiB7XG4gICAgICAvLyBDaGVjayBpZiB0aGlzIGlzIGEgQm9keUluaXQgdGhhdCBzaG91bGQgYmUgd3JhcHBlZCBpbiBhIGZha2Ugc3RyZWFtXG4gICAgICBpZiAoJ2JvZHlJbml0JyBpbiB2YWx1ZSkge1xuICAgICAgICAvLyBSZWNyZWF0ZSB0aGUgZmFrZSBzdHJlYW0gd2l0aCB0aGUgQm9keUluaXRcbiAgICAgICAgcmV0dXJuIE9iamVjdC5jcmVhdGUoZ2xvYmFsLlJlYWRhYmxlU3RyZWFtLnByb3RvdHlwZSwge1xuICAgICAgICAgIFtCT0RZX0lOSVRfU1lNQk9MXToge1xuICAgICAgICAgICAgdmFsdWU6IHZhbHVlLmJvZHlJbml0LFxuICAgICAgICAgICAgd3JpdGFibGU6IGZhbHNlLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICAvLyBSZWd1bGFyIHN0cmVhbSBoYW5kbGluZ1xuICAgICAgcmV0dXJuIE9iamVjdC5jcmVhdGUoZ2xvYmFsLlJlYWRhYmxlU3RyZWFtLnByb3RvdHlwZSwge1xuICAgICAgICBbU1RSRUFNX05BTUVfU1lNQk9MXToge1xuICAgICAgICAgIHZhbHVlOiB2YWx1ZS5uYW1lLFxuICAgICAgICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICAgICAgfSxcbiAgICAgICAgW1NUUkVBTV9UWVBFX1NZTUJPTF06IHtcbiAgICAgICAgICB2YWx1ZTogdmFsdWUudHlwZSxcbiAgICAgICAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9LFxuICAgIFdyaXRhYmxlU3RyZWFtOiAodmFsdWUpID0+IHtcbiAgICAgIHJldHVybiBPYmplY3QuY3JlYXRlKGdsb2JhbC5Xcml0YWJsZVN0cmVhbS5wcm90b3R5cGUsIHtcbiAgICAgICAgW1NUUkVBTV9OQU1FX1NZTUJPTF06IHtcbiAgICAgICAgICB2YWx1ZTogdmFsdWUubmFtZSxcbiAgICAgICAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9LFxuICB9O1xufVxuXG4vKipcbiAqIFJldml2ZXJzIGZvciBkZXNlcmlhbGl6YXRpb24gYm91bmRhcnkgZnJvbSB3aXRoaW4gdGhlIHN0ZXAgZXhlY3V0aW9uXG4gKiBlbnZpcm9ubWVudCwgcmVjZWl2aW5nIGFyZ3VtZW50cyBmcm9tIHRoZSB3b3JrZmxvdyBoYW5kbGVyLlxuICpcbiAqIEBwYXJhbSBnbG9iYWxcbiAqIEBwYXJhbSBvcHNcbiAqIEBwYXJhbSBydW5JZFxuICogQHJldHVybnNcbiAqL1xuZnVuY3Rpb24gZ2V0U3RlcFJldml2ZXJzKFxuICBnbG9iYWw6IFJlY29yZDxzdHJpbmcsIGFueT4gPSBnbG9iYWxUaGlzLFxuICBvcHM6IFByb21pc2U8dm9pZD5bXSxcbiAgcnVuSWQ6IHN0cmluZyxcbiAgY3J5cHRvS2V5OiBFbmNyeXB0aW9uS2V5UGFyYW1cbik6IFJldml2ZXJzIHtcbiAgcmV0dXJuIHtcbiAgICAuLi5nZXRDb21tb25SZXZpdmVycyhnbG9iYWwpLFxuXG4gICAgLy8gU3RlcEZ1bmN0aW9uIHJldml2ZXIgZm9yIHN0ZXAgY29udGV4dCAtIHJldHVybnMgcmF3IHN0ZXAgZnVuY3Rpb25cbiAgICAvLyB3aXRoIGNsb3N1cmUgdmFyaWFibGUgc3VwcG9ydCB2aWEgQXN5bmNMb2NhbFN0b3JhZ2VcbiAgICBTdGVwRnVuY3Rpb246ICh2YWx1ZSkgPT4ge1xuICAgICAgY29uc3Qgc3RlcElkID0gdmFsdWUuc3RlcElkO1xuICAgICAgY29uc3QgY2xvc3VyZVZhcnMgPSB2YWx1ZS5jbG9zdXJlVmFycztcblxuICAgICAgY29uc3Qgc3RlcEZuID0gZ2V0U3RlcEZ1bmN0aW9uKHN0ZXBJZCk7XG4gICAgICBpZiAoIXN0ZXBGbikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgYFN0ZXAgZnVuY3Rpb24gXCIke3N0ZXBJZH1cIiBub3QgZm91bmQuIE1ha2Ugc3VyZSB0aGUgc3RlcCBmdW5jdGlvbiBpcyByZWdpc3RlcmVkLmBcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgLy8gSWYgY2xvc3VyZSB2YXJpYWJsZXMgd2VyZSBzZXJpYWxpemVkLCByZXR1cm4gYSB3cmFwcGVyIGZ1bmN0aW9uXG4gICAgICAvLyB0aGF0IHNldHMgdXAgQXN5bmNMb2NhbFN0b3JhZ2UgY29udGV4dCB3aGVuIGludm9rZWRcbiAgICAgIGlmIChjbG9zdXJlVmFycykge1xuICAgICAgICBjb25zdCB3cmFwcGVkU3RlcEZuID0gKCguLi5hcmdzOiBhbnlbXSkgPT4ge1xuICAgICAgICAgIC8vIEdldCB0aGUgY3VycmVudCBjb250ZXh0IGZyb20gQXN5bmNMb2NhbFN0b3JhZ2VcbiAgICAgICAgICBjb25zdCBjdXJyZW50Q29udGV4dCA9IGNvbnRleHRTdG9yYWdlLmdldFN0b3JlKCk7XG5cbiAgICAgICAgICBpZiAoIWN1cnJlbnRDb250ZXh0KSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICAgICdDYW5ub3QgY2FsbCBzdGVwIGZ1bmN0aW9uIHdpdGggY2xvc3VyZSB2YXJpYWJsZXMgb3V0c2lkZSBzdGVwIGNvbnRleHQnXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIENyZWF0ZSBhIG5ldyBjb250ZXh0IHdpdGggdGhlIGNsb3N1cmUgdmFyaWFibGVzIG1lcmdlZCBpblxuICAgICAgICAgIGNvbnN0IG5ld0NvbnRleHQgPSB7XG4gICAgICAgICAgICAuLi5jdXJyZW50Q29udGV4dCxcbiAgICAgICAgICAgIGNsb3N1cmVWYXJzLFxuICAgICAgICAgIH07XG5cbiAgICAgICAgICAvLyBSdW4gdGhlIHN0ZXAgZnVuY3Rpb24gd2l0aCB0aGUgbmV3IGNvbnRleHQgdGhhdCBpbmNsdWRlcyBjbG9zdXJlIHZhcnNcbiAgICAgICAgICByZXR1cm4gY29udGV4dFN0b3JhZ2UucnVuKG5ld0NvbnRleHQsICgpID0+IHN0ZXBGbiguLi5hcmdzKSk7XG4gICAgICAgIH0pIGFzIGFueTtcblxuICAgICAgICAvLyBDb3B5IHByb3BlcnRpZXMgZnJvbSBvcmlnaW5hbCBzdGVwIGZ1bmN0aW9uXG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh3cmFwcGVkU3RlcEZuLCAnbmFtZScsIHtcbiAgICAgICAgICB2YWx1ZTogc3RlcEZuLm5hbWUsXG4gICAgICAgIH0pO1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkod3JhcHBlZFN0ZXBGbiwgJ3N0ZXBJZCcsIHtcbiAgICAgICAgICB2YWx1ZTogc3RlcElkLFxuICAgICAgICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgICBjb25maWd1cmFibGU6IGZhbHNlLFxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKHN0ZXBGbi5tYXhSZXRyaWVzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB3cmFwcGVkU3RlcEZuLm1heFJldHJpZXMgPSBzdGVwRm4ubWF4UmV0cmllcztcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB3cmFwcGVkU3RlcEZuO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gc3RlcEZuO1xuICAgIH0sXG5cbiAgICBXb3JrZmxvd0Z1bmN0aW9uOiAodmFsdWUpID0+XG4gICAgICBPYmplY3QuYXNzaWduKFxuICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICAgJ1dvcmtmbG93IGZ1bmN0aW9ucyBjYW5ub3QgYmUgY2FsbGVkIGRpcmVjdGx5LiBVc2Ugc3RhcnQoKSB0byBpbnZva2UgdGhlbS4nXG4gICAgICAgICAgKTtcbiAgICAgICAgfSxcbiAgICAgICAgeyB3b3JrZmxvd0lkOiB2YWx1ZS53b3JrZmxvd0lkIH1cbiAgICAgICksXG5cbiAgICBSZXF1ZXN0OiAodmFsdWUpID0+IHtcbiAgICAgIGNvbnN0IHJlc3BvbnNlV3JpdGFibGUgPSB2YWx1ZS5yZXNwb25zZVdyaXRhYmxlO1xuICAgICAgY29uc3QgcmVxdWVzdCA9IG5ldyBnbG9iYWwuUmVxdWVzdCh2YWx1ZS51cmwsIHtcbiAgICAgICAgbWV0aG9kOiB2YWx1ZS5tZXRob2QsXG4gICAgICAgIGhlYWRlcnM6IG5ldyBnbG9iYWwuSGVhZGVycyh2YWx1ZS5oZWFkZXJzKSxcbiAgICAgICAgYm9keTogdmFsdWUuYm9keSxcbiAgICAgICAgZHVwbGV4OiB2YWx1ZS5kdXBsZXgsXG4gICAgICB9KTtcbiAgICAgIGlmIChyZXNwb25zZVdyaXRhYmxlKSB7XG4gICAgICAgIHJlcXVlc3QucmVzcG9uZFdpdGggPSBhc3luYyAocmVzcG9uc2U6IFJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgY29uc3Qgd3JpdGVyID0gcmVzcG9uc2VXcml0YWJsZS5nZXRXcml0ZXIoKTtcbiAgICAgICAgICBhd2FpdCB3cml0ZXIud3JpdGUocmVzcG9uc2UpO1xuICAgICAgICAgIGF3YWl0IHdyaXRlci5jbG9zZSgpO1xuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlcXVlc3Q7XG4gICAgfSxcbiAgICBSZXNwb25zZTogKHZhbHVlKSA9PiB7XG4gICAgICAvLyBOb3RlOiBSZXNwb25zZSBjb25zdHJ1Y3RvciBvbmx5IGFjY2VwdHMgc3RhdHVzLCBzdGF0dXNUZXh0LCBhbmQgaGVhZGVyc1xuICAgICAgLy8gVGhlIHR5cGUsIHVybCwgYW5kIHJlZGlyZWN0ZWQgcHJvcGVydGllcyBhcmUgcmVhZC1vbmx5IGFuZCBzZXQgYnkgdGhlIGNvbnN0cnVjdG9yXG4gICAgICByZXR1cm4gbmV3IGdsb2JhbC5SZXNwb25zZSh2YWx1ZS5ib2R5LCB7XG4gICAgICAgIHN0YXR1czogdmFsdWUuc3RhdHVzLFxuICAgICAgICBzdGF0dXNUZXh0OiB2YWx1ZS5zdGF0dXNUZXh0LFxuICAgICAgICBoZWFkZXJzOiBuZXcgZ2xvYmFsLkhlYWRlcnModmFsdWUuaGVhZGVycyksXG4gICAgICB9KTtcbiAgICB9LFxuICAgIFJlYWRhYmxlU3RyZWFtOiAodmFsdWUpID0+IHtcbiAgICAgIC8vIElmIHRoaXMgaGFzIGJvZHlJbml0LCBpdCBjYW1lIGZyb20gYSBSZXNwb25zZSBjb25zdHJ1Y3RvclxuICAgICAgLy8gQ29udmVydCBpdCB0byBhIFJFQUwgc3RyZWFtIG5vdyB0aGF0IHdlJ3JlIGluIHRoZSBzdGVwIGVudmlyb25tZW50XG4gICAgICBpZiAoJ2JvZHlJbml0JyBpbiB2YWx1ZSkge1xuICAgICAgICBjb25zdCBib2R5SW5pdCA9IHZhbHVlLmJvZHlJbml0O1xuICAgICAgICAvLyBVc2UgdGhlIG5hdGl2ZSBSZXNwb25zZSBjb25zdHJ1Y3RvciB0byBwcm9wZXJseSBjb252ZXJ0IEJvZHlJbml0IHRvIFJlYWRhYmxlU3RyZWFtXG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gbmV3IGdsb2JhbC5SZXNwb25zZShib2R5SW5pdCk7XG4gICAgICAgIHJldHVybiByZXNwb25zZS5ib2R5O1xuICAgICAgfVxuXG4gICAgICBjb25zdCByZWFkYWJsZSA9IG5ldyBXb3JrZmxvd1NlcnZlclJlYWRhYmxlU3RyZWFtKHJ1bklkLCB2YWx1ZS5uYW1lKTtcbiAgICAgIGlmICh2YWx1ZS50eXBlID09PSAnYnl0ZXMnKSB7XG4gICAgICAgIC8vIEZvciBieXRlIHN0cmVhbXMsIHVzZSBmbHVzaGFibGUgcGlwZSB3aXRoIGxvY2sgcG9sbGluZ1xuICAgICAgICBjb25zdCBzdGF0ZSA9IGNyZWF0ZUZsdXNoYWJsZVN0YXRlKCk7XG4gICAgICAgIG9wcy5wdXNoKHN0YXRlLnByb21pc2UpO1xuXG4gICAgICAgIC8vIENyZWF0ZSBhbiBpZGVudGl0eSB0cmFuc2Zvcm0gdG8gZ2l2ZSB0aGUgdXNlciBhIHJlYWRhYmxlXG4gICAgICAgIGNvbnN0IHsgcmVhZGFibGU6IHVzZXJSZWFkYWJsZSwgd3JpdGFibGUgfSA9XG4gICAgICAgICAgbmV3IGdsb2JhbC5UcmFuc2Zvcm1TdHJlYW0oKTtcblxuICAgICAgICAvLyBTdGFydCB0aGUgZmx1c2hhYmxlIHBpcGUgaW4gdGhlIGJhY2tncm91bmRcbiAgICAgICAgZmx1c2hhYmxlUGlwZShyZWFkYWJsZSwgd3JpdGFibGUsIHN0YXRlKS5jYXRjaCgoKSA9PiB7XG4gICAgICAgICAgLy8gRXJyb3JzIGFyZSBoYW5kbGVkIHZpYSBzdGF0ZS5yZWplY3RcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gU3RhcnQgcG9sbGluZyB0byBkZXRlY3Qgd2hlbiB1c2VyIHJlbGVhc2VzIGxvY2tcbiAgICAgICAgcG9sbFJlYWRhYmxlTG9jayh1c2VyUmVhZGFibGUsIHN0YXRlKTtcblxuICAgICAgICByZXR1cm4gdXNlclJlYWRhYmxlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgdHJhbnNmb3JtID0gZ2V0RGVzZXJpYWxpemVTdHJlYW0oXG4gICAgICAgICAgZ2V0U3RlcFJldml2ZXJzKGdsb2JhbCwgb3BzLCBydW5JZCwgY3J5cHRvS2V5KSxcbiAgICAgICAgICBjcnlwdG9LZXlcbiAgICAgICAgKTtcbiAgICAgICAgY29uc3Qgc3RhdGUgPSBjcmVhdGVGbHVzaGFibGVTdGF0ZSgpO1xuICAgICAgICBvcHMucHVzaChzdGF0ZS5wcm9taXNlKTtcblxuICAgICAgICAvLyBTdGFydCB0aGUgZmx1c2hhYmxlIHBpcGUgaW4gdGhlIGJhY2tncm91bmRcbiAgICAgICAgZmx1c2hhYmxlUGlwZShyZWFkYWJsZSwgdHJhbnNmb3JtLndyaXRhYmxlLCBzdGF0ZSkuY2F0Y2goKCkgPT4ge1xuICAgICAgICAgIC8vIEVycm9ycyBhcmUgaGFuZGxlZCB2aWEgc3RhdGUucmVqZWN0XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFN0YXJ0IHBvbGxpbmcgdG8gZGV0ZWN0IHdoZW4gdXNlciByZWxlYXNlcyBsb2NrXG4gICAgICAgIHBvbGxSZWFkYWJsZUxvY2sodHJhbnNmb3JtLnJlYWRhYmxlLCBzdGF0ZSk7XG5cbiAgICAgICAgcmV0dXJuIHRyYW5zZm9ybS5yZWFkYWJsZTtcbiAgICAgIH1cbiAgICB9LFxuICAgIFdyaXRhYmxlU3RyZWFtOiAodmFsdWUpID0+IHtcbiAgICAgIGNvbnN0IHNlcmlhbGl6ZSA9IGdldFNlcmlhbGl6ZVN0cmVhbShcbiAgICAgICAgZ2V0U3RlcFJlZHVjZXJzKGdsb2JhbCwgb3BzLCBydW5JZCwgY3J5cHRvS2V5KSxcbiAgICAgICAgY3J5cHRvS2V5XG4gICAgICApO1xuICAgICAgY29uc3Qgc2VydmVyV3JpdGFibGUgPSBuZXcgV29ya2Zsb3dTZXJ2ZXJXcml0YWJsZVN0cmVhbShcbiAgICAgICAgcnVuSWQsXG4gICAgICAgIHZhbHVlLm5hbWVcbiAgICAgICk7XG5cbiAgICAgIC8vIENyZWF0ZSBmbHVzaGFibGUgc3RhdGUgZm9yIHRoaXMgc3RyZWFtXG4gICAgICBjb25zdCBzdGF0ZSA9IGNyZWF0ZUZsdXNoYWJsZVN0YXRlKCk7XG4gICAgICBvcHMucHVzaChzdGF0ZS5wcm9taXNlKTtcblxuICAgICAgLy8gU3RhcnQgdGhlIGZsdXNoYWJsZSBwaXBlIGluIHRoZSBiYWNrZ3JvdW5kXG4gICAgICBmbHVzaGFibGVQaXBlKHNlcmlhbGl6ZS5yZWFkYWJsZSwgc2VydmVyV3JpdGFibGUsIHN0YXRlKS5jYXRjaCgoKSA9PiB7XG4gICAgICAgIC8vIEVycm9ycyBhcmUgaGFuZGxlZCB2aWEgc3RhdGUucmVqZWN0XG4gICAgICB9KTtcblxuICAgICAgLy8gU3RhcnQgcG9sbGluZyB0byBkZXRlY3Qgd2hlbiB1c2VyIHJlbGVhc2VzIGxvY2tcbiAgICAgIHBvbGxXcml0YWJsZUxvY2soc2VyaWFsaXplLndyaXRhYmxlLCBzdGF0ZSk7XG5cbiAgICAgIHJldHVybiBzZXJpYWxpemUud3JpdGFibGU7XG4gICAgfSxcbiAgfTtcbn1cblxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy8gRW5jcnlwdGlvbiBIZWxwZXJzXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbi8qKlxuICogRW5jcnlwdCBkYXRhIGlmIHRoZSB3b3JsZCBzdXBwb3J0cyBlbmNyeXB0aW9uLlxuICogUmV0dXJucyBvcmlnaW5hbCBkYXRhIGlmIGVuY3J5cHRpb24gaXMgbm90IGF2YWlsYWJsZS5cbiAqXG4gKiBAcGFyYW0gZGF0YSAtIFNlcmlhbGl6ZWQgZGF0YSB0byBlbmNyeXB0XG4gKiBAcGFyYW0ga2V5IC0gRW5jcnlwdGlvbiBrZXkgKHVuZGVmaW5lZCB0byBza2lwIGVuY3J5cHRpb24pXG4gKiBAcGFyYW0gY29udGV4dCAtIEVuY3J5cHRpb24gY29udGV4dCB3aXRoIHJ1bklkXG4gKiBAcmV0dXJucyBFbmNyeXB0ZWQgZGF0YSBpZiBlbmNyeXB0aW9uIGF2YWlsYWJsZSwgb3JpZ2luYWwgZGF0YSBvdGhlcndpc2VcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIG1heWJlRW5jcnlwdChcbiAgZGF0YTogVWludDhBcnJheSxcbiAga2V5OiBDcnlwdG9LZXkgfCB1bmRlZmluZWRcbik6IFByb21pc2U8VWludDhBcnJheT4ge1xuICBpZiAoIWtleSkgcmV0dXJuIGRhdGE7XG4gIGNvbnN0IGVuY3J5cHRlZCA9IGF3YWl0IGFlc0djbUVuY3J5cHQoa2V5LCBkYXRhKTtcbiAgcmV0dXJuIGVuY29kZVdpdGhGb3JtYXRQcmVmaXgoXG4gICAgU2VyaWFsaXphdGlvbkZvcm1hdC5FTkNSWVBURUQsXG4gICAgZW5jcnlwdGVkXG4gICkgYXMgVWludDhBcnJheTtcbn1cblxuLyoqXG4gKiBEZWNyeXB0IGRhdGEgaWYgaXQgaGFzIHRoZSAnZW5jcicgcHJlZml4LlxuICpcbiAqIEBwYXJhbSBkYXRhIC0gRGF0YSB0aGF0IG1heSBiZSBlbmNyeXB0ZWRcbiAqIEBwYXJhbSBrZXkgLSBFbmNyeXB0aW9uIGtleSAodW5kZWZpbmVkIGlmIG5vIGtleSBhdmFpbGFibGUpXG4gKiBAcmV0dXJucyBEZWNyeXB0ZWQgZGF0YSBpZiBlbmNyeXB0ZWQsIG9yaWdpbmFsIGRhdGEgb3RoZXJ3aXNlXG4gKiBAdGhyb3dzIHtXb3JrZmxvd1J1bnRpbWVFcnJvcn0gSWYgdGhlIGRhdGEgaXMgZW5jcnlwdGVkIGJ1dCBubyBrZXkgaXNcbiAqICAgYXZhaWxhYmxlLiBDYWxsZXJzIChlLmcuLCBgUnVuLnBvbGxSZXR1cm5WYWx1ZSgpYCwgYGh5ZHJhdGVTdGVwUmV0dXJuVmFsdWVgKVxuICogICBzaG91bGQgYmUgYXdhcmUgdGhpcyBjYW4gc3VyZmFjZSBhcyBhIHJlamVjdGVkIHByb21pc2UgZHVyaW5nIGtleSByb3RhdGlvblxuICogICBvciBtaXNjb25maWd1cmF0aW9uIHNjZW5hcmlvcy5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIG1heWJlRGVjcnlwdChcbiAgZGF0YTogVWludDhBcnJheSB8IHVua25vd24sXG4gIGtleTogQ3J5cHRvS2V5IHwgdW5kZWZpbmVkXG4pOiBQcm9taXNlPFVpbnQ4QXJyYXkgfCB1bmtub3duPiB7XG4gIC8vIExlZ2FjeSBzcGVjVmVyc2lvbiAxIHJ1bnMgc3RvcmVkIGV2ZW50IGRhdGEgYXMgcGxhaW4gSlNPTiBhcnJheXNcbiAgLy8gKG5vdCBiaW5hcnkgVWludDhBcnJheSkuIFBhc3MgdGhyb3VnaCBhcy1pcyBmb3IgYmFja3dhcmRzIGNvbXBhdC5cbiAgaWYgKCEoZGF0YSBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpKSB7XG4gICAgcmV0dXJuIGRhdGE7XG4gIH1cblxuICBpZiAoaXNFbmNyeXB0ZWQoZGF0YSkpIHtcbiAgICBpZiAoIWtleSkge1xuICAgICAgdGhyb3cgbmV3IFdvcmtmbG93UnVudGltZUVycm9yKFxuICAgICAgICAnRW5jcnlwdGVkIGRhdGEgZW5jb3VudGVyZWQgYnV0IG5vIGVuY3J5cHRpb24ga2V5IGlzIGF2YWlsYWJsZS4gJyArXG4gICAgICAgICAgJ0VuY3J5cHRpb24gaXMgbm90IGNvbmZpZ3VyZWQgb3Igbm8ga2V5IHdhcyBwcm92aWRlZCBmb3IgdGhpcyBydW4uJ1xuICAgICAgKTtcbiAgICB9XG4gICAgLy8gU3RyaXAgdGhlICdlbmNyJyBmb3JtYXQgcHJlZml4IOKAlCB0aGUgcHJlZml4IGlzIGEgY29yZSBmcmFtaW5nIGNvbmNlcm5cbiAgICBjb25zdCB7IHBheWxvYWQgfSA9IGRlY29kZUZvcm1hdFByZWZpeChkYXRhKTtcbiAgICByZXR1cm4gYWVzR2NtRGVjcnlwdChrZXksIHBheWxvYWQpO1xuICB9XG5cbiAgcmV0dXJuIGRhdGE7XG59XG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIERlaHlkcmF0ZSAvIEh5ZHJhdGUgRnVuY3Rpb25zXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbi8qKlxuICogQ2FsbGVkIGZyb20gdGhlIGBzdGFydCgpYCBmdW5jdGlvbiB0byBzZXJpYWxpemUgdGhlIHdvcmtmbG93IGFyZ3VtZW50c1xuICogaW50byBhIGZvcm1hdCB0aGF0IGNhbiBiZSBzYXZlZCB0byB0aGUgZGF0YWJhc2UgYW5kIHRoZW4gaHlkcmF0ZWQgZnJvbVxuICogd2l0aGluIHRoZSB3b3JrZmxvdyBleGVjdXRpb24gZW52aXJvbm1lbnQuXG4gKlxuICogQHBhcmFtIHZhbHVlIC0gVGhlIHZhbHVlIHRvIHNlcmlhbGl6ZVxuICogQHBhcmFtIHJ1bklkIC0gVGhlIHdvcmtmbG93IHJ1biBJRCAocmVxdWlyZWQgZm9yIGVuY3J5cHRpb24gY29udGV4dClcbiAqIEBwYXJhbSBrZXkgLSBFbmNyeXB0aW9uIGtleSAodW5kZWZpbmVkIHRvIHNraXAgZW5jcnlwdGlvbilcbiAqIEBwYXJhbSBvcHMgLSBQcm9taXNlIGFycmF5IGZvciBzdHJlYW0gb3BlcmF0aW9uc1xuICogQHBhcmFtIGdsb2JhbCAtIEdsb2JhbCBvYmplY3QgZm9yIHNlcmlhbGl6YXRpb24gY29udGV4dFxuICogQHBhcmFtIHYxQ29tcGF0IC0gRW5hYmxlIGxlZ2FjeSB2MSBjb21wYXRpYmlsaXR5IG1vZGVcbiAqIEByZXR1cm5zIFRoZSBkZWh5ZHJhdGVkIHZhbHVlIGFzIGJpbmFyeSBkYXRhIChVaW50OEFycmF5KSB3aXRoIGZvcm1hdCBwcmVmaXhcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGRlaHlkcmF0ZVdvcmtmbG93QXJndW1lbnRzKFxuICB2YWx1ZTogdW5rbm93bixcbiAgcnVuSWQ6IHN0cmluZyxcbiAga2V5OiBDcnlwdG9LZXkgfCB1bmRlZmluZWQsXG4gIG9wczogUHJvbWlzZTx2b2lkPltdID0gW10sXG4gIGdsb2JhbDogUmVjb3JkPHN0cmluZywgYW55PiA9IGdsb2JhbFRoaXMsXG4gIHYxQ29tcGF0ID0gZmFsc2Vcbik6IFByb21pc2U8VWludDhBcnJheSB8IHVua25vd24+IHtcbiAgdHJ5IHtcbiAgICBjb25zdCBzdHIgPSBzdHJpbmdpZnkodmFsdWUsIGdldEV4dGVybmFsUmVkdWNlcnMoZ2xvYmFsLCBvcHMsIHJ1bklkLCBrZXkpKTtcbiAgICBpZiAodjFDb21wYXQpIHtcbiAgICAgIHJldHVybiByZXZpdmUoc3RyKTtcbiAgICB9XG4gICAgY29uc3QgcGF5bG9hZCA9IG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZShzdHIpO1xuICAgIGNvbnN0IHNlcmlhbGl6ZWQgPSBlbmNvZGVXaXRoRm9ybWF0UHJlZml4KFxuICAgICAgU2VyaWFsaXphdGlvbkZvcm1hdC5ERVZBTFVFX1YxLFxuICAgICAgcGF5bG9hZFxuICAgICkgYXMgVWludDhBcnJheTtcblxuICAgIC8vIEVuY3J5cHQgaWYgd29ybGQgc3VwcG9ydHMgZW5jcnlwdGlvblxuICAgIHJldHVybiBtYXliZUVuY3J5cHQoc2VyaWFsaXplZCwga2V5KTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICB0aHJvdyBuZXcgV29ya2Zsb3dSdW50aW1lRXJyb3IoXG4gICAgICBmb3JtYXRTZXJpYWxpemF0aW9uRXJyb3IoJ3dvcmtmbG93IGFyZ3VtZW50cycsIGVycm9yKSxcbiAgICAgIHsgc2x1ZzogJ3NlcmlhbGl6YXRpb24tZmFpbGVkJywgY2F1c2U6IGVycm9yIH1cbiAgICApO1xuICB9XG59XG5cbi8qKlxuICogQ2FsbGVkIGZyb20gd29ya2Zsb3cgZXhlY3V0aW9uIGVudmlyb25tZW50IHRvIGh5ZHJhdGUgdGhlIHdvcmtmbG93XG4gKiBhcmd1bWVudHMgZnJvbSB0aGUgZGF0YWJhc2UgYXQgdGhlIHN0YXJ0IG9mIHdvcmtmbG93IGV4ZWN1dGlvbi5cbiAqXG4gKiBAcGFyYW0gdmFsdWUgLSBCaW5hcnkgc2VyaWFsaXplZCBkYXRhIChVaW50OEFycmF5KSB3aXRoIGZvcm1hdCBwcmVmaXhcbiAqIEBwYXJhbSBfcnVuSWQgLSBXb3JrZmxvdyBydW4gSUQgKHJlc2VydmVkIGZvciBmdXR1cmUgZGVjcnlwdGlvbiBjb250ZXh0OyBkZWNyeXB0aW9uIGlzIGN1cnJlbnRseSBkcml2ZW4gc29sZWx5IGJ5IHRoZSBwcm92aWRlZCBrZXkpXG4gKiBAcGFyYW0ga2V5IC0gRW5jcnlwdGlvbiBrZXkgKHVuZGVmaW5lZCB0byBza2lwIGRlY3J5cHRpb24pXG4gKiBAcGFyYW0gZ2xvYmFsIC0gR2xvYmFsIG9iamVjdCBmb3IgZGVzZXJpYWxpemF0aW9uIGNvbnRleHRcbiAqIEBwYXJhbSBleHRyYVJldml2ZXJzIC0gQWRkaXRpb25hbCByZXZpdmVycyBmb3IgY3VzdG9tIHR5cGVzXG4gKiBAcmV0dXJucyBUaGUgaHlkcmF0ZWQgdmFsdWVcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGh5ZHJhdGVXb3JrZmxvd0FyZ3VtZW50cyhcbiAgdmFsdWU6IFVpbnQ4QXJyYXkgfCB1bmtub3duLFxuICBfcnVuSWQ6IHN0cmluZyxcbiAga2V5OiBDcnlwdG9LZXkgfCB1bmRlZmluZWQsXG4gIGdsb2JhbDogUmVjb3JkPHN0cmluZywgYW55PiA9IGdsb2JhbFRoaXMsXG4gIGV4dHJhUmV2aXZlcnM6IFJlY29yZDxzdHJpbmcsICh2YWx1ZTogYW55KSA9PiBhbnk+ID0ge31cbikge1xuICAvLyBEZWNyeXB0IGlmIG5lZWRlZFxuICBjb25zdCBkZWNyeXB0ZWQgPSBhd2FpdCBtYXliZURlY3J5cHQodmFsdWUsIGtleSk7XG5cbiAgLy8gTGVnYWN5IHNwZWNWZXJzaW9uIDEgcnVucyBzdG9yZWQgZGF0YSBhcyBwbGFpbiBKU09OIGFycmF5cyAobm90IGJpbmFyeSkuXG4gIC8vIFRoZXNlIHBhc3MgdGhyb3VnaCBtYXliZURlY3J5cHQgdW5jaGFuZ2VkIGFuZCBhcmUgZGVzZXJpYWxpemVkIGRpcmVjdGx5XG4gIC8vIHZpYSBkZXZhbHVlJ3MgdW5mbGF0dGVuKCkuXG4gIGlmICghKGRlY3J5cHRlZCBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpKSB7XG4gICAgcmV0dXJuIHVuZmxhdHRlbihkZWNyeXB0ZWQgYXMgYW55W10sIHtcbiAgICAgIC4uLmdldFdvcmtmbG93UmV2aXZlcnMoZ2xvYmFsKSxcbiAgICAgIC4uLmV4dHJhUmV2aXZlcnMsXG4gICAgfSk7XG4gIH1cblxuICBjb25zdCB7IGZvcm1hdCwgcGF5bG9hZCB9ID0gZGVjb2RlRm9ybWF0UHJlZml4KGRlY3J5cHRlZCk7XG5cbiAgaWYgKGZvcm1hdCA9PT0gU2VyaWFsaXphdGlvbkZvcm1hdC5ERVZBTFVFX1YxKSB7XG4gICAgY29uc3Qgc3RyID0gbmV3IFRleHREZWNvZGVyKCkuZGVjb2RlKHBheWxvYWQpO1xuICAgIGNvbnN0IG9iaiA9IHBhcnNlKHN0ciwge1xuICAgICAgLi4uZ2V0V29ya2Zsb3dSZXZpdmVycyhnbG9iYWwpLFxuICAgICAgLi4uZXh0cmFSZXZpdmVycyxcbiAgICB9KTtcbiAgICByZXR1cm4gb2JqO1xuICB9XG5cbiAgdGhyb3cgbmV3IEVycm9yKGBVbnN1cHBvcnRlZCBzZXJpYWxpemF0aW9uIGZvcm1hdDogJHtmb3JtYXR9YCk7XG59XG5cbi8qKlxuICogRGVoeWRyYXRlIHdvcmtmbG93IHJldHVybiB2YWx1ZSBmb3Igc3RvcmFnZS5cbiAqXG4gKiBAcGFyYW0gdmFsdWUgLSBUaGUgdmFsdWUgdG8gc2VyaWFsaXplXG4gKiBAcGFyYW0gcnVuSWQgLSBSdW4gSUQgZm9yIGVuY3J5cHRpb24gY29udGV4dFxuICogQHBhcmFtIGtleSAtIEVuY3J5cHRpb24ga2V5ICh1bmRlZmluZWQgdG8gc2tpcCBlbmNyeXB0aW9uKVxuICogQHBhcmFtIGdsb2JhbCAtIEdsb2JhbCBvYmplY3QgZm9yIHNlcmlhbGl6YXRpb24gY29udGV4dFxuICogQHJldHVybnMgVGhlIGRlaHlkcmF0ZWQgdmFsdWUgYXMgYmluYXJ5IGRhdGEgKFVpbnQ4QXJyYXkpIHdpdGggZm9ybWF0IHByZWZpeFxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZGVoeWRyYXRlV29ya2Zsb3dSZXR1cm5WYWx1ZShcbiAgdmFsdWU6IHVua25vd24sXG4gIF9ydW5JZDogc3RyaW5nLFxuICBrZXk6IENyeXB0b0tleSB8IHVuZGVmaW5lZCxcbiAgZ2xvYmFsOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0gZ2xvYmFsVGhpcyxcbiAgdjFDb21wYXQgPSBmYWxzZVxuKTogUHJvbWlzZTxVaW50OEFycmF5IHwgdW5rbm93bj4ge1xuICB0cnkge1xuICAgIGNvbnN0IHN0ciA9IHN0cmluZ2lmeSh2YWx1ZSwgZ2V0V29ya2Zsb3dSZWR1Y2VycyhnbG9iYWwpKTtcbiAgICBpZiAodjFDb21wYXQpIHtcbiAgICAgIHJldHVybiByZXZpdmUoc3RyKTtcbiAgICB9XG4gICAgY29uc3QgcGF5bG9hZCA9IG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZShzdHIpO1xuICAgIGNvbnN0IHNlcmlhbGl6ZWQgPSBlbmNvZGVXaXRoRm9ybWF0UHJlZml4KFxuICAgICAgU2VyaWFsaXphdGlvbkZvcm1hdC5ERVZBTFVFX1YxLFxuICAgICAgcGF5bG9hZFxuICAgICkgYXMgVWludDhBcnJheTtcblxuICAgIC8vIEVuY3J5cHQgaWYgd29ybGQgc3VwcG9ydHMgZW5jcnlwdGlvblxuICAgIHJldHVybiBtYXliZUVuY3J5cHQoc2VyaWFsaXplZCwga2V5KTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICB0aHJvdyBuZXcgV29ya2Zsb3dSdW50aW1lRXJyb3IoXG4gICAgICBmb3JtYXRTZXJpYWxpemF0aW9uRXJyb3IoJ3dvcmtmbG93IHJldHVybiB2YWx1ZScsIGVycm9yKSxcbiAgICAgIHsgc2x1ZzogJ3NlcmlhbGl6YXRpb24tZmFpbGVkJywgY2F1c2U6IGVycm9yIH1cbiAgICApO1xuICB9XG59XG5cbi8qKlxuICogQ2FsbGVkIGZyb20gdGhlIGNsaWVudCBzaWRlIChpLmUuIHRoZSBleGVjdXRpb24gZW52aXJvbm1lbnQgd2hlcmVcbiAqIHRoZSB3b3JrZmxvdyBydW4gd2FzIGluaXRpYXRlZCBmcm9tKSB0byBoeWRyYXRlIHRoZSB3b3JrZmxvd1xuICogcmV0dXJuIHZhbHVlIG9mIGEgY29tcGxldGVkIHdvcmtmbG93IHJ1bi5cbiAqXG4gKiBAcGFyYW0gdmFsdWUgLSBCaW5hcnkgc2VyaWFsaXplZCBkYXRhIChVaW50OEFycmF5KSB3aXRoIGZvcm1hdCBwcmVmaXhcbiAqIEBwYXJhbSBydW5JZCAtIFJ1biBJRCBmb3IgZGVjcnlwdGlvbiBjb250ZXh0XG4gKiBAcGFyYW0ga2V5IC0gRW5jcnlwdGlvbiBrZXkgKHVuZGVmaW5lZCB0byBza2lwIGRlY3J5cHRpb24pXG4gKiBAcGFyYW0gb3BzIC0gUHJvbWlzZSBhcnJheSBmb3Igc3RyZWFtIG9wZXJhdGlvbnNcbiAqIEBwYXJhbSBnbG9iYWwgLSBHbG9iYWwgb2JqZWN0IGZvciBkZXNlcmlhbGl6YXRpb24gY29udGV4dFxuICogQHBhcmFtIGV4dHJhUmV2aXZlcnMgLSBBZGRpdGlvbmFsIHJldml2ZXJzIGZvciBjdXN0b20gdHlwZXNcbiAqIEByZXR1cm5zIFRoZSBoeWRyYXRlZCByZXR1cm4gdmFsdWUsIHJlYWR5IHRvIGJlIGNvbnN1bWVkIGJ5IHRoZSBjbGllbnRcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGh5ZHJhdGVXb3JrZmxvd1JldHVyblZhbHVlKFxuICB2YWx1ZTogVWludDhBcnJheSB8IHVua25vd24sXG4gIHJ1bklkOiBzdHJpbmcsXG4gIGtleTogQ3J5cHRvS2V5IHwgdW5kZWZpbmVkLFxuICBvcHM6IFByb21pc2U8dm9pZD5bXSA9IFtdLFxuICBnbG9iYWw6IFJlY29yZDxzdHJpbmcsIGFueT4gPSBnbG9iYWxUaGlzLFxuICBleHRyYVJldml2ZXJzOiBSZWNvcmQ8c3RyaW5nLCAodmFsdWU6IGFueSkgPT4gYW55PiA9IHt9XG4pIHtcbiAgLy8gRGVjcnlwdCBpZiBuZWVkZWRcbiAgY29uc3QgZGVjcnlwdGVkID0gYXdhaXQgbWF5YmVEZWNyeXB0KHZhbHVlLCBrZXkpO1xuXG4gIC8vIExlZ2FjeSBzcGVjVmVyc2lvbiAxIHJ1bnMgc3RvcmVkIGRhdGEgYXMgcGxhaW4gSlNPTiBhcnJheXMgKG5vdCBiaW5hcnkpLlxuICAvLyBUaGVzZSBwYXNzIHRocm91Z2ggbWF5YmVEZWNyeXB0IHVuY2hhbmdlZCBhbmQgYXJlIGRlc2VyaWFsaXplZCBkaXJlY3RseVxuICAvLyB2aWEgZGV2YWx1ZSdzIHVuZmxhdHRlbigpLlxuICBpZiAoIShkZWNyeXB0ZWQgaW5zdGFuY2VvZiBVaW50OEFycmF5KSkge1xuICAgIHJldHVybiB1bmZsYXR0ZW4oZGVjcnlwdGVkIGFzIGFueVtdLCB7XG4gICAgICAuLi5nZXRFeHRlcm5hbFJldml2ZXJzKGdsb2JhbCwgb3BzLCBydW5JZCwga2V5KSxcbiAgICAgIC4uLmV4dHJhUmV2aXZlcnMsXG4gICAgfSk7XG4gIH1cblxuICBjb25zdCB7IGZvcm1hdCwgcGF5bG9hZCB9ID0gZGVjb2RlRm9ybWF0UHJlZml4KGRlY3J5cHRlZCk7XG5cbiAgaWYgKGZvcm1hdCA9PT0gU2VyaWFsaXphdGlvbkZvcm1hdC5ERVZBTFVFX1YxKSB7XG4gICAgY29uc3Qgc3RyID0gbmV3IFRleHREZWNvZGVyKCkuZGVjb2RlKHBheWxvYWQpO1xuICAgIGNvbnN0IG9iaiA9IHBhcnNlKHN0ciwge1xuICAgICAgLi4uZ2V0RXh0ZXJuYWxSZXZpdmVycyhnbG9iYWwsIG9wcywgcnVuSWQsIGtleSksXG4gICAgICAuLi5leHRyYVJldml2ZXJzLFxuICAgIH0pO1xuICAgIHJldHVybiBvYmo7XG4gIH1cblxuICB0aHJvdyBuZXcgRXJyb3IoYFVuc3VwcG9ydGVkIHNlcmlhbGl6YXRpb24gZm9ybWF0OiAke2Zvcm1hdH1gKTtcbn1cblxuLyoqXG4gKiBDYWxsZWQgZnJvbSB0aGUgd29ya2Zsb3cgaGFuZGxlciB3aGVuIGEgc3RlcCBpcyBiZWluZyBjcmVhdGVkLlxuICogRGVoeWRyYXRlcyB2YWx1ZXMgZnJvbSB3aXRoaW4gdGhlIHdvcmtmbG93IGV4ZWN1dGlvbiBlbnZpcm9ubWVudFxuICogaW50byBhIGZvcm1hdCB0aGF0IGNhbiBiZSBzYXZlZCB0byB0aGUgZGF0YWJhc2UuXG4gKlxuICogQHBhcmFtIHZhbHVlIC0gVGhlIHZhbHVlIHRvIHNlcmlhbGl6ZVxuICogQHBhcmFtIHJ1bklkIC0gUnVuIElEIGZvciBlbmNyeXB0aW9uIGNvbnRleHRcbiAqIEBwYXJhbSBrZXkgLSBFbmNyeXB0aW9uIGtleSAodW5kZWZpbmVkIHRvIHNraXAgZW5jcnlwdGlvbilcbiAqIEBwYXJhbSBnbG9iYWwgLSBHbG9iYWwgb2JqZWN0IGZvciBzZXJpYWxpemF0aW9uIGNvbnRleHRcbiAqIEBwYXJhbSB2MUNvbXBhdCAtIEVuYWJsZSBsZWdhY3kgdjEgY29tcGF0aWJpbGl0eSBtb2RlXG4gKiBAcmV0dXJucyBUaGUgZGVoeWRyYXRlZCB2YWx1ZSBhcyBiaW5hcnkgZGF0YSAoVWludDhBcnJheSkgd2l0aCBmb3JtYXQgcHJlZml4XG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBkZWh5ZHJhdGVTdGVwQXJndW1lbnRzKFxuICB2YWx1ZTogdW5rbm93bixcbiAgX3J1bklkOiBzdHJpbmcsXG4gIGtleTogQ3J5cHRvS2V5IHwgdW5kZWZpbmVkLFxuICBnbG9iYWw6IFJlY29yZDxzdHJpbmcsIGFueT4gPSBnbG9iYWxUaGlzLFxuICB2MUNvbXBhdCA9IGZhbHNlXG4pOiBQcm9taXNlPFVpbnQ4QXJyYXkgfCB1bmtub3duPiB7XG4gIHRyeSB7XG4gICAgY29uc3Qgc3RyID0gc3RyaW5naWZ5KHZhbHVlLCBnZXRXb3JrZmxvd1JlZHVjZXJzKGdsb2JhbCkpO1xuICAgIGlmICh2MUNvbXBhdCkge1xuICAgICAgcmV0dXJuIHJldml2ZShzdHIpO1xuICAgIH1cbiAgICBjb25zdCBwYXlsb2FkID0gbmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKHN0cik7XG4gICAgY29uc3Qgc2VyaWFsaXplZCA9IGVuY29kZVdpdGhGb3JtYXRQcmVmaXgoXG4gICAgICBTZXJpYWxpemF0aW9uRm9ybWF0LkRFVkFMVUVfVjEsXG4gICAgICBwYXlsb2FkXG4gICAgKSBhcyBVaW50OEFycmF5O1xuXG4gICAgLy8gRW5jcnlwdCBpZiB3b3JsZCBzdXBwb3J0cyBlbmNyeXB0aW9uXG4gICAgcmV0dXJuIG1heWJlRW5jcnlwdChzZXJpYWxpemVkLCBrZXkpO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIHRocm93IG5ldyBXb3JrZmxvd1J1bnRpbWVFcnJvcihcbiAgICAgIGZvcm1hdFNlcmlhbGl6YXRpb25FcnJvcignc3RlcCBhcmd1bWVudHMnLCBlcnJvciksXG4gICAgICB7IHNsdWc6ICdzZXJpYWxpemF0aW9uLWZhaWxlZCcsIGNhdXNlOiBlcnJvciB9XG4gICAgKTtcbiAgfVxufVxuXG4vKipcbiAqIENhbGxlZCBmcm9tIHRoZSBzdGVwIGhhbmRsZXIgdG8gaHlkcmF0ZSB0aGUgYXJndW1lbnRzIG9mIGEgc3RlcFxuICogZnJvbSB0aGUgZGF0YWJhc2UgYXQgdGhlIHN0YXJ0IG9mIHRoZSBzdGVwIGV4ZWN1dGlvbi5cbiAqXG4gKiBAcGFyYW0gdmFsdWUgLSBCaW5hcnkgc2VyaWFsaXplZCBkYXRhIChVaW50OEFycmF5KSB3aXRoIGZvcm1hdCBwcmVmaXhcbiAqIEBwYXJhbSBydW5JZCAtIFJ1biBJRCBmb3IgZGVjcnlwdGlvbiBjb250ZXh0XG4gKiBAcGFyYW0ga2V5IC0gRW5jcnlwdGlvbiBrZXkgKHVuZGVmaW5lZCB0byBza2lwIGRlY3J5cHRpb24pXG4gKiBAcGFyYW0gb3BzIC0gUHJvbWlzZSBhcnJheSBmb3Igc3RyZWFtIG9wZXJhdGlvbnNcbiAqIEBwYXJhbSBnbG9iYWwgLSBHbG9iYWwgb2JqZWN0IGZvciBkZXNlcmlhbGl6YXRpb24gY29udGV4dFxuICogQHBhcmFtIGV4dHJhUmV2aXZlcnMgLSBBZGRpdGlvbmFsIHJldml2ZXJzIGZvciBjdXN0b20gdHlwZXNcbiAqIEByZXR1cm5zIFRoZSBoeWRyYXRlZCB2YWx1ZSwgcmVhZHkgdG8gYmUgY29uc3VtZWQgYnkgdGhlIHN0ZXAgdXNlci1jb2RlIGZ1bmN0aW9uXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBoeWRyYXRlU3RlcEFyZ3VtZW50cyhcbiAgdmFsdWU6IFVpbnQ4QXJyYXkgfCB1bmtub3duLFxuICBydW5JZDogc3RyaW5nLFxuICBrZXk6IENyeXB0b0tleSB8IHVuZGVmaW5lZCxcbiAgb3BzOiBQcm9taXNlPGFueT5bXSA9IFtdLFxuICBnbG9iYWw6IFJlY29yZDxzdHJpbmcsIGFueT4gPSBnbG9iYWxUaGlzLFxuICBleHRyYVJldml2ZXJzOiBSZWNvcmQ8c3RyaW5nLCAodmFsdWU6IGFueSkgPT4gYW55PiA9IHt9XG4pIHtcbiAgLy8gRGVjcnlwdCBpZiBuZWVkZWRcbiAgY29uc3QgZGVjcnlwdGVkID0gYXdhaXQgbWF5YmVEZWNyeXB0KHZhbHVlLCBrZXkpO1xuXG4gIC8vIExlZ2FjeSBzcGVjVmVyc2lvbiAxIHJ1bnMgc3RvcmVkIGRhdGEgYXMgcGxhaW4gSlNPTiBhcnJheXMgKG5vdCBiaW5hcnkpLlxuICAvLyBUaGVzZSBwYXNzIHRocm91Z2ggbWF5YmVEZWNyeXB0IHVuY2hhbmdlZCBhbmQgYXJlIGRlc2VyaWFsaXplZCBkaXJlY3RseVxuICAvLyB2aWEgZGV2YWx1ZSdzIHVuZmxhdHRlbigpLlxuICBpZiAoIShkZWNyeXB0ZWQgaW5zdGFuY2VvZiBVaW50OEFycmF5KSkge1xuICAgIHJldHVybiB1bmZsYXR0ZW4oZGVjcnlwdGVkIGFzIGFueVtdLCB7XG4gICAgICAuLi5nZXRTdGVwUmV2aXZlcnMoZ2xvYmFsLCBvcHMsIHJ1bklkLCBrZXkpLFxuICAgICAgLi4uZXh0cmFSZXZpdmVycyxcbiAgICB9KTtcbiAgfVxuXG4gIGNvbnN0IHsgZm9ybWF0LCBwYXlsb2FkIH0gPSBkZWNvZGVGb3JtYXRQcmVmaXgoZGVjcnlwdGVkKTtcblxuICBpZiAoZm9ybWF0ID09PSBTZXJpYWxpemF0aW9uRm9ybWF0LkRFVkFMVUVfVjEpIHtcbiAgICBjb25zdCBzdHIgPSBuZXcgVGV4dERlY29kZXIoKS5kZWNvZGUocGF5bG9hZCk7XG4gICAgY29uc3Qgb2JqID0gcGFyc2Uoc3RyLCB7XG4gICAgICAuLi5nZXRTdGVwUmV2aXZlcnMoZ2xvYmFsLCBvcHMsIHJ1bklkLCBrZXkpLFxuICAgICAgLi4uZXh0cmFSZXZpdmVycyxcbiAgICB9KTtcbiAgICByZXR1cm4gb2JqO1xuICB9XG5cbiAgdGhyb3cgbmV3IEVycm9yKGBVbnN1cHBvcnRlZCBzZXJpYWxpemF0aW9uIGZvcm1hdDogJHtmb3JtYXR9YCk7XG59XG5cbi8qKlxuICogQ2FsbGVkIGZyb20gdGhlIHN0ZXAgaGFuZGxlciB3aGVuIGEgc3RlcCBoYXMgY29tcGxldGVkLlxuICogRGVoeWRyYXRlcyB2YWx1ZXMgZnJvbSB3aXRoaW4gdGhlIHN0ZXAgZXhlY3V0aW9uIGVudmlyb25tZW50XG4gKiBpbnRvIGEgZm9ybWF0IHRoYXQgY2FuIGJlIHNhdmVkIHRvIHRoZSBkYXRhYmFzZS5cbiAqXG4gKiBAcGFyYW0gdmFsdWUgLSBUaGUgdmFsdWUgdG8gc2VyaWFsaXplXG4gKiBAcGFyYW0gcnVuSWQgLSBSdW4gSUQgZm9yIGVuY3J5cHRpb24gY29udGV4dFxuICogQHBhcmFtIGtleSAtIEVuY3J5cHRpb24ga2V5ICh1bmRlZmluZWQgdG8gc2tpcCBlbmNyeXB0aW9uKVxuICogQHBhcmFtIG9wcyAtIFByb21pc2UgYXJyYXkgZm9yIHN0cmVhbSBvcGVyYXRpb25zXG4gKiBAcGFyYW0gZ2xvYmFsIC0gR2xvYmFsIG9iamVjdCBmb3Igc2VyaWFsaXphdGlvbiBjb250ZXh0XG4gKiBAcGFyYW0gdjFDb21wYXQgLSBFbmFibGUgbGVnYWN5IHYxIGNvbXBhdGliaWxpdHkgbW9kZVxuICogQHJldHVybnMgVGhlIGRlaHlkcmF0ZWQgdmFsdWUgYXMgYmluYXJ5IGRhdGEgKFVpbnQ4QXJyYXkpIHdpdGggZm9ybWF0IHByZWZpeFxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZGVoeWRyYXRlU3RlcFJldHVyblZhbHVlKFxuICB2YWx1ZTogdW5rbm93bixcbiAgcnVuSWQ6IHN0cmluZyxcbiAga2V5OiBDcnlwdG9LZXkgfCB1bmRlZmluZWQsXG4gIG9wczogUHJvbWlzZTxhbnk+W10gPSBbXSxcbiAgZ2xvYmFsOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0gZ2xvYmFsVGhpcyxcbiAgdjFDb21wYXQgPSBmYWxzZVxuKTogUHJvbWlzZTxVaW50OEFycmF5IHwgdW5rbm93bj4ge1xuICB0cnkge1xuICAgIGNvbnN0IHN0ciA9IHN0cmluZ2lmeSh2YWx1ZSwgZ2V0U3RlcFJlZHVjZXJzKGdsb2JhbCwgb3BzLCBydW5JZCwga2V5KSk7XG4gICAgaWYgKHYxQ29tcGF0KSB7XG4gICAgICByZXR1cm4gcmV2aXZlKHN0cik7XG4gICAgfVxuICAgIGNvbnN0IHBheWxvYWQgPSBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoc3RyKTtcbiAgICBjb25zdCBzZXJpYWxpemVkID0gZW5jb2RlV2l0aEZvcm1hdFByZWZpeChcbiAgICAgIFNlcmlhbGl6YXRpb25Gb3JtYXQuREVWQUxVRV9WMSxcbiAgICAgIHBheWxvYWRcbiAgICApIGFzIFVpbnQ4QXJyYXk7XG5cbiAgICAvLyBFbmNyeXB0IGlmIHdvcmxkIHN1cHBvcnRzIGVuY3J5cHRpb25cbiAgICByZXR1cm4gbWF5YmVFbmNyeXB0KHNlcmlhbGl6ZWQsIGtleSk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgdGhyb3cgbmV3IFdvcmtmbG93UnVudGltZUVycm9yKFxuICAgICAgZm9ybWF0U2VyaWFsaXphdGlvbkVycm9yKCdzdGVwIHJldHVybiB2YWx1ZScsIGVycm9yKSxcbiAgICAgIHsgc2x1ZzogJ3NlcmlhbGl6YXRpb24tZmFpbGVkJywgY2F1c2U6IGVycm9yIH1cbiAgICApO1xuICB9XG59XG5cbi8qKlxuICogQ2FsbGVkIGZyb20gdGhlIHdvcmtmbG93IGhhbmRsZXIgd2hlbiByZXBsYXlpbmcgdGhlIGV2ZW50IGxvZyBvZiBhIGBzdGVwX2NvbXBsZXRlZGAgZXZlbnQuXG4gKiBIeWRyYXRlcyB0aGUgcmV0dXJuIHZhbHVlIG9mIGEgc3RlcCBmcm9tIHRoZSBkYXRhYmFzZS5cbiAqXG4gKiBAcGFyYW0gdmFsdWUgLSBCaW5hcnkgc2VyaWFsaXplZCBkYXRhIChVaW50OEFycmF5KSB3aXRoIGZvcm1hdCBwcmVmaXhcbiAqIEBwYXJhbSBydW5JZCAtIFJ1biBJRCBmb3IgZGVjcnlwdGlvbiBjb250ZXh0XG4gKiBAcGFyYW0ga2V5IC0gRW5jcnlwdGlvbiBrZXkgKHVuZGVmaW5lZCB0byBza2lwIGRlY3J5cHRpb24pXG4gKiBAcGFyYW0gZ2xvYmFsIC0gR2xvYmFsIG9iamVjdCBmb3IgZGVzZXJpYWxpemF0aW9uIGNvbnRleHRcbiAqIEBwYXJhbSBleHRyYVJldml2ZXJzIC0gQWRkaXRpb25hbCByZXZpdmVycyBmb3IgY3VzdG9tIHR5cGVzXG4gKiBAcmV0dXJucyBUaGUgaHlkcmF0ZWQgcmV0dXJuIHZhbHVlIG9mIGEgc3RlcCwgcmVhZHkgdG8gYmUgY29uc3VtZWQgYnkgdGhlIHdvcmtmbG93IGhhbmRsZXJcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGh5ZHJhdGVTdGVwUmV0dXJuVmFsdWUoXG4gIHZhbHVlOiBVaW50OEFycmF5IHwgdW5rbm93bixcbiAgX3J1bklkOiBzdHJpbmcsXG4gIGtleTogQ3J5cHRvS2V5IHwgdW5kZWZpbmVkLFxuICBnbG9iYWw6IFJlY29yZDxzdHJpbmcsIGFueT4gPSBnbG9iYWxUaGlzLFxuICBleHRyYVJldml2ZXJzOiBSZWNvcmQ8c3RyaW5nLCAodmFsdWU6IGFueSkgPT4gYW55PiA9IHt9XG4pIHtcbiAgLy8gRGVjcnlwdCBpZiBuZWVkZWRcbiAgY29uc3QgZGVjcnlwdGVkID0gYXdhaXQgbWF5YmVEZWNyeXB0KHZhbHVlLCBrZXkpO1xuXG4gIC8vIExlZ2FjeSBzcGVjVmVyc2lvbiAxIHJ1bnMgc3RvcmVkIGRhdGEgYXMgcGxhaW4gSlNPTiBhcnJheXMgKG5vdCBiaW5hcnkpLlxuICAvLyBUaGVzZSBwYXNzIHRocm91Z2ggbWF5YmVEZWNyeXB0IHVuY2hhbmdlZCBhbmQgYXJlIGRlc2VyaWFsaXplZCBkaXJlY3RseVxuICAvLyB2aWEgZGV2YWx1ZSdzIHVuZmxhdHRlbigpLlxuICBpZiAoIShkZWNyeXB0ZWQgaW5zdGFuY2VvZiBVaW50OEFycmF5KSkge1xuICAgIHJldHVybiB1bmZsYXR0ZW4oZGVjcnlwdGVkIGFzIGFueVtdLCB7XG4gICAgICAuLi5nZXRXb3JrZmxvd1Jldml2ZXJzKGdsb2JhbCksXG4gICAgICAuLi5leHRyYVJldml2ZXJzLFxuICAgIH0pO1xuICB9XG5cbiAgY29uc3QgeyBmb3JtYXQsIHBheWxvYWQgfSA9IGRlY29kZUZvcm1hdFByZWZpeChkZWNyeXB0ZWQpO1xuXG4gIGlmIChmb3JtYXQgPT09IFNlcmlhbGl6YXRpb25Gb3JtYXQuREVWQUxVRV9WMSkge1xuICAgIGNvbnN0IHN0ciA9IG5ldyBUZXh0RGVjb2RlcigpLmRlY29kZShwYXlsb2FkKTtcbiAgICByZXR1cm4gcGFyc2Uoc3RyLCB7XG4gICAgICAuLi5nZXRXb3JrZmxvd1Jldml2ZXJzKGdsb2JhbCksXG4gICAgICAuLi5leHRyYVJldml2ZXJzLFxuICAgIH0pO1xuICB9XG5cbiAgdGhyb3cgbmV3IEVycm9yKGBVbnN1cHBvcnRlZCBzZXJpYWxpemF0aW9uIGZvcm1hdDogJHtmb3JtYXR9YCk7XG59XG4iXX0=
1642
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VyaWFsaXphdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9zZXJpYWxpemF0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxvQkFBb0IsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQzVFLE9BQU8sRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUN0RCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDeEMsT0FBTyxFQUNMLE9BQU8sSUFBSSxhQUFhLEVBQ3hCLE9BQU8sSUFBSSxhQUFhLEdBRXpCLE1BQU0saUJBQWlCLENBQUM7QUFDekIsT0FBTyxFQUNMLG9CQUFvQixFQUNwQixhQUFhLEVBQ2IsZ0JBQWdCLEVBQ2hCLGdCQUFnQixHQUNqQixNQUFNLHVCQUF1QixDQUFDO0FBQy9CLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDL0MsMkVBQTJFO0FBQzNFLDBFQUEwRTtBQUMxRSwwRUFBMEU7QUFDMUUsNERBQTREO0FBQzVELHNFQUFzRTtBQUN0RSxzREFBc0Q7QUFDdEQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQzNELE9BQU8sS0FBSyxZQUFZLE1BQU0sMkJBQTJCLENBQUM7QUFDMUQsT0FBTyxFQUNMLE9BQU8sRUFFUCxPQUFPLEdBQ1IsTUFBTSwrQkFBK0IsQ0FBQztBQUN2QyxPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUNyRSxPQUFPLEVBQ0wsa0JBQWtCLEVBQ2xCLHNCQUFzQixFQUN0QixXQUFXLEVBQ1gsZ0JBQWdCLEdBQ2pCLE1BQU0sMkJBQTJCLENBQUM7QUFDbkMsT0FBTyxFQUNMLGdCQUFnQixFQUNoQixnQkFBZ0IsR0FDakIsTUFBTSxtQ0FBbUMsQ0FBQztBQUMzQyxPQUFPLEVBQ0wsaUJBQWlCLEVBQ2pC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QUFJLHVCQUF1QixFQUFFLENBQUM7UUFDMUMsSUFBSSxHQUFHLElBQUksV0FBVyxFQUFFLENBQUM7WUFDdkIsS0FBSyxDQUFDLEdBQUcsQ0FBQyxHQUFHLFdBQVcsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNoQyxDQUFDO0lBQ0gsQ0FBQztJQUNELE9BQU8sS0FBSyxDQUFDO0FBQ2YsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFNlcmlhbGl6YXRpb25FcnJvciwgV29ya2Zsb3dSdW50aW1lRXJyb3IgfSBmcm9tICdAd29ya2Zsb3cvZXJyb3JzJztcbmltcG9ydCB7IHBhcnNlLCBzdHJpbmdpZnksIHVuZmxhdHRlbiB9IGZyb20gJ2RldmFsdWUnO1xuaW1wb3J0IHsgbW9ub3RvbmljRmFjdG9yeSB9IGZyb20gJ3VsaWQnO1xuaW1wb3J0IHtcbiAgZGVjcnlwdCBhcyBhZXNHY21EZWNyeXB0LFxuICBlbmNyeXB0IGFzIGFlc0djbUVuY3J5cHQsXG4gIHR5cGUgQ3J5cHRvS2V5LFxufSBmcm9tICcuL2VuY3J5cHRpb24uanMnO1xuaW1wb3J0IHtcbiAgY3JlYXRlRmx1c2hhYmxlU3RhdGUsXG4gIGZsdXNoYWJsZVBpcGUsXG4gIHBvbGxSZWFkYWJsZUxvY2ssXG4gIHBvbGxXcml0YWJsZUxvY2ssXG59IGZyb20gJy4vZmx1c2hhYmxlLXN0cmVhbS5qcyc7XG5pbXBvcnQgeyBnZXRTdGVwRnVuY3Rpb24gfSBmcm9tICcuL3ByaXZhdGUuanMnO1xuLy8gVjI6IHVzZSBnZXRXb3JsZExhenkgaW4gc3RlcC1zaWRlIGNvZGUgcGF0aHMgc28gVHVyYm9wYWNrIGNhbiBzdGF0aWNhbGx5XG4vLyByZXNvbHZlIHRoZSB3b3JsZCBicmlkZ2UgZnJvbSB0aGUgc3RlcCBidW5kbGUgd2l0aG91dCBkcmFnZ2luZyB0aGUgZnVsbFxuLy8gd29ybGQudHMgbW9kdWxlIChhbmQgaXRzIGR5bmFtaWMtaW1wb3J0IGJlaGF2aW91cikgaW50byB0aGUgZmxvdyByb3V0ZS5cbi8vIFNlZSBgcGFja2FnZXMvY29yZS9zcmMvcnVudGltZS9nZXQtd29ybGQtbGF6eS50c2AgYW5kIHRoZVxuLy8gXCJUdXJib3BhY2sgTkZUIFRyYWNpbmcgRXJyb3JzIGluIFYyIENvbWJpbmVkIEZsb3cgUm91dGVcIiBzZWN0aW9uIG9mXG4vLyBgZG9jcy9jb250ZW50L2RvY3MvY2hhbmdlbG9nL2VhZ2VyLXByb2Nlc3NpbmcubWR4YC5cbmltcG9ydCB7IGdldFdvcmxkTGF6eSB9IGZyb20gJy4vcnVudGltZS9nZXQtd29ybGQtbGF6eS5qcyc7XG5pbXBvcnQgKiBhcyBjbGllbnRNb2R1bGUgZnJvbSAnLi9zZXJpYWxpemF0aW9uL2NsaWVudC5qcyc7XG5pbXBvcnQge1xuICBkZWNyeXB0LFxuICB0eXBlIEVuY3J5cHRpb25LZXlQYXJhbSxcbiAgZW5jcnlwdCxcbn0gZnJvbSAnLi9zZXJpYWxpemF0aW9uL2VuY3J5cHRpb24uanMnO1xuaW1wb3J0IHsgZm9ybWF0U2VyaWFsaXphdGlvbkVycm9yIH0gZnJvbSAnLi9zZXJpYWxpemF0aW9uL2Vycm9ycy5qcyc7XG5pbXBvcnQge1xuICBkZWNvZGVGb3JtYXRQcmVmaXgsXG4gIGVuY29kZVdpdGhGb3JtYXRQcmVmaXgsXG4gIGlzRW5jcnlwdGVkLFxuICBwZWVrRm9ybWF0UHJlZml4LFxufSBmcm9tICcuL3NlcmlhbGl6YXRpb24vZm9ybWF0LmpzJztcbmltcG9ydCB7XG4gIGdldENsYXNzUmVkdWNlcnMsXG4gIGdldENsYXNzUmV2aXZlcnMsXG59IGZyb20gJy4vc2VyaWFsaXphdGlvbi9yZWR1Y2Vycy9jbGFzcy5qcyc7XG5pbXBvcnQge1xuICBnZXRDb21tb25SZWR1Y2VycyxcbiAgZ2V0Q29tbW9uUmV2aXZlcnMgYXMgZ2V0Q29tbW9uUmV2aXZlcnNGcm9tTW9kdWxlLFxuICByZXZpdmUsXG59IGZyb20gJy4vc2VyaWFsaXphdGlvbi9yZWR1Y2Vycy9jb21tb24uanMnO1xuaW1wb3J0IHtcbiAgZ2V0U3RlcEZ1bmN0aW9uUmVkdWNlcixcbiAgZ2V0U3RlcEZ1bmN0aW9uUmV2aXZlcixcbn0gZnJvbSAnLi9zZXJpYWxpemF0aW9uL3JlZHVjZXJzL3N0ZXAtZnVuY3Rpb24uanMnO1xuaW1wb3J0ICogYXMgc3RlcE1vZHVsZSBmcm9tICcuL3NlcmlhbGl6YXRpb24vc3RlcC5qcyc7XG5pbXBvcnQge1xuICB0eXBlIEZvcm1hdFByZWZpeCxcbiAgaXNGb3JtYXRQcmVmaXgsXG4gIFNlcmlhbGl6YXRpb25Gb3JtYXQsXG59IGZyb20gJy4vc2VyaWFsaXphdGlvbi90eXBlcy5qcyc7XG5pbXBvcnQgKiBhcyB3b3JrZmxvd01vZHVsZSBmcm9tICcuL3NlcmlhbGl6YXRpb24vd29ya2Zsb3cuanMnO1xuaW1wb3J0IHsgY29udGV4dFN0b3JhZ2UgfSBmcm9tICcuL3N0ZXAvY29udGV4dC1zdG9yYWdlLmpzJztcbmltcG9ydCB7XG4gIEFCT1JUX0hPT0tfVE9LRU4sXG4gIEFCT1JUX0xJU1RFTkVSX0FUVEFDSEVELFxuICBBQk9SVF9SRUFERVJfQ0FOQ0VMLFxuICBBQk9SVF9TVFJFQU1fTkFNRSxcbiAgQk9EWV9JTklUX1NZTUJPTCxcbiAgU1RBQkxFX1VMSUQsXG4gIFNUUkVBTV9OQU1FX1NZTUJPTCxcbiAgU1RSRUFNX1RZUEVfU1lNQk9MLFxuICBXRUJIT09LX1JFU1BPTlNFX1dSSVRBQkxFLFxufSBmcm9tICcuL3N5bWJvbHMuanMnO1xuaW1wb3J0IHsgZ2V0QWJvcnRTdHJlYW1JZCB9IGZyb20gJy4vdXRpbC5qcyc7XG5pbXBvcnQgeyBXb3JrZmxvd0Fib3J0U2lnbmFsIH0gZnJvbSAnLi93b3JrZmxvdy9hYm9ydC1jb250cm9sbGVyLmpzJztcblxuLy8gUmUtZXhwb3J0IHR5cGVzIGFuZCB1dGlsaXRpZXMgZnJvbSB0aGUgbW9kdWxhciBzZXJpYWxpemF0aW9uIG1vZHVsZXNcbi8vIHNvIGV4aXN0aW5nIGNvbnN1bWVycyBvZiBgQHdvcmtmbG93L2NvcmUvc2VyaWFsaXphdGlvbmAga2VlcCB3b3JraW5nLlxuZXhwb3J0IHtcbiAgU2VyaWFsaXphdGlvbkZvcm1hdCxcbiAgdHlwZSBGb3JtYXRQcmVmaXgsXG4gIGlzRm9ybWF0UHJlZml4LFxuICBlbmNvZGVXaXRoRm9ybWF0UHJlZml4LFxuICBkZWNvZGVGb3JtYXRQcmVmaXgsXG4gIHBlZWtGb3JtYXRQcmVmaXgsXG4gIGlzRW5jcnlwdGVkLFxuICBlbmNyeXB0LFxuICBkZWNyeXB0LFxuICB0eXBlIEVuY3J5cHRpb25LZXlQYXJhbSxcbn07XG5cbi8vIFJlLWV4cG9ydCB0aGUgbGVnYWN5IFNlcmlhbGl6YXRpb25Gb3JtYXRUeXBlIGZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eS5cbi8vIE5ldyBjb2RlIHNob3VsZCB1c2UgRm9ybWF0UHJlZml4IGZyb20gJy4vc2VyaWFsaXphdGlvbi90eXBlcy5qcycuXG5leHBvcnQgdHlwZSBTZXJpYWxpemF0aW9uRm9ybWF0VHlwZSA9XG4gICh0eXBlb2YgU2VyaWFsaXphdGlvbkZvcm1hdClba2V5b2YgdHlwZW9mIFNlcmlhbGl6YXRpb25Gb3JtYXRdO1xuXG4vKipcbiAqIERlZmF1bHQgVUxJRCBnZW5lcmF0b3IgZm9yIGNvbnRleHRzIHdoZXJlIFZNJ3Mgc2VlZGVkIGBzdGFibGVVbGlkYCBpc24ndCBhdmFpbGFibGUuXG4gKiBVc2VkIGFzIGEgZmFsbGJhY2sgd2hlbiBzZXJpYWxpemluZyBzdHJlYW1zIG91dHNpZGUgdGhlIHdvcmtmbG93IFZNIGNvbnRleHRcbiAqIChlLmcuLCB3aGVuIHN0YXJ0aW5nIGEgd29ya2Zsb3cgb3IgaGFuZGxpbmcgc3RlcCByZXR1cm4gdmFsdWVzKS5cbiAqL1xuY29uc3QgZGVmYXVsdFVsaWQgPSBtb25vdG9uaWNGYWN0b3J5KCk7XG5cbi8qKlxuICogRGV0ZWN0IGlmIGEgcmVhZGFibGUgc3RyZWFtIGlzIGEgYnl0ZSBzdHJlYW0uXG4gKlxuICogQHBhcmFtIHN0cmVhbVxuICogQHJldHVybnMgYFwiYnl0ZXNcImAgaWYgdGhlIHN0cmVhbSBpcyBhIGJ5dGUgc3RyZWFtLCBgdW5kZWZpbmVkYCBvdGhlcndpc2VcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFN0cmVhbVR5cGUoc3RyZWFtOiBSZWFkYWJsZVN0cmVhbSk6ICdieXRlcycgfCB1bmRlZmluZWQge1xuICB0cnkge1xuICAgIGNvbnN0IHJlYWRlciA9IHN0cmVhbS5nZXRSZWFkZXIoeyBtb2RlOiAnYnlvYicgfSk7XG4gICAgcmVhZGVyLnJlbGVhc2VMb2NrKCk7XG4gICAgcmV0dXJuICdieXRlcyc7XG4gIH0gY2F0Y2gge31cbn1cblxuLyoqXG4gKiBGcmFtZSBmb3JtYXQgZm9yIHN0cmVhbSBjaHVua3M6XG4gKiAgIFs0LWJ5dGUgYmlnLWVuZGlhbiBsZW5ndGhdW2Zvcm1hdC1wcmVmaXhlZCBwYXlsb2FkXVxuICpcbiAqIEVhY2ggY2h1bmsgaXMgaW5kZXBlbmRlbnRseSBmcmFtZWQgc28gdGhlIGRlc2VyaWFsaXplciBjYW4gZmluZFxuICogY2h1bmsgYm91bmRhcmllcyBldmVuIHdoZW4gbXVsdGlwbGUgY2h1bmtzIGFyZSBjb25jYXRlbmF0ZWQgb3JcbiAqIHNwbGl0IGFjcm9zcyB0cmFuc3BvcnQgcmVhZHMuXG4gKi9cbmNvbnN0IEZSQU1FX0hFQURFUl9TSVpFID0gNDtcblxuLyoqXG4gKiBUaGUgbW9kZS1zcGVjaWZpYyBzZXJpYWxpemVycyAoYC4vc2VyaWFsaXphdGlvbi97Y2xpZW50LHN0ZXAsd29ya2Zsb3d9LnRzYClcbiAqIGFscmVhZHkgdGhyb3cgYSBgU2VyaWFsaXphdGlvbkVycm9yYCB3aG9zZSBgLmNhdXNlYCBpcyB0aGUgdW5kZXJseWluZ1xuICogZGV2YWx1ZSAvIHNlcmRlIGZhaWx1cmUuIFRoZSBvdXRlciBkZWh5ZHJhdGUvaHlkcmF0ZSB3cmFwcGVycyB3YW50IHRvXG4gKiByZS1mcmFtZSB0aGF0IGVycm9yIHdpdGggYSBtb3JlIHNwZWNpZmljIGNvbnRleHQgbGFiZWwgKGUuZy4gXCJ3b3JrZmxvd1xuICogYXJndW1lbnRzXCIgaW5zdGVhZCBvZiBnZW5lcmljIFwid29ya2Zsb3cgdmFsdWVcIiksIHNvIHRoZXkgdW53cmFwIHRoZVxuICogaW5uZXIgU2VyaWFsaXphdGlvbkVycm9yIGFuZCByZWZvcm1hdCB3aXRoIHRoZSBvcmlnaW5hbCBjYXVzZS4gRXJyb3JzXG4gKiB0aGF0IGFyZW4ndCBhbHJlYWR5IFNlcmlhbGl6YXRpb25FcnJvciBmbG93IHRocm91Z2ggdW5jaGFuZ2VkLlxuICovXG5mdW5jdGlvbiB1bndyYXBTZXJpYWxpemF0aW9uQ2F1c2UoZXJyb3I6IHVua25vd24pOiB1bmtub3duIHtcbiAgaWYgKGVycm9yIGluc3RhbmNlb2YgU2VyaWFsaXphdGlvbkVycm9yICYmIGVycm9yLmNhdXNlICE9PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4gZXJyb3IuY2F1c2U7XG4gIH1cbiAgaWYgKGVycm9yIGluc3RhbmNlb2YgV29ya2Zsb3dSdW50aW1lRXJyb3IgJiYgZXJyb3IuY2F1c2UgIT09IHVuZGVmaW5lZCkge1xuICAgIHJldHVybiBlcnJvci5jYXVzZTtcbiAgfVxuICByZXR1cm4gZXJyb3I7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRTZXJpYWxpemVTdHJlYW0oXG4gIHJlZHVjZXJzOiBQYXJ0aWFsPFJlZHVjZXJzPixcbiAgY3J5cHRvS2V5OiBFbmNyeXB0aW9uS2V5UGFyYW1cbik6IFRyYW5zZm9ybVN0cmVhbTxhbnksIFVpbnQ4QXJyYXk+IHtcbiAgY29uc3QgZW5jb2RlciA9IG5ldyBUZXh0RW5jb2RlcigpO1xuICAvLyBSZXNvbHZlIHRoZSBrZXkgcHJvbWlzZSBvbmNlIG9uIGZpcnN0IHVzZSBhbmQgY2FjaGUgdGhlIHJlc3VsdC5cbiAgLy8gTm90ZTogaWYgdGhlIGNyeXB0b0tleSBwcm9taXNlIHJlamVjdHMgKGUuZy4sIG5ldHdvcmsgZXJyb3IgZmV0Y2hpbmdcbiAgLy8gdGhlIGRlcml2ZWQga2V5KSwgdGhlIHJlamVjdGlvbiB3b24ndCBzdXJmYWNlIHVudGlsIHRoZSBmaXJzdCBjaHVua1xuICAvLyBpcyBwcm9jZXNzZWQg4oCUIG5vdCBhdCBzdHJlYW0gY29uc3RydWN0aW9uIHRpbWUuXG4gIGNvbnN0IGtleVN0YXRlID0geyByZXNvbHZlZDogZmFsc2UsIGtleTogdW5kZWZpbmVkIGFzIENyeXB0b0tleSB8IHVuZGVmaW5lZCB9O1xuICBjb25zdCBzdHJlYW0gPSBuZXcgVHJhbnNmb3JtU3RyZWFtPGFueSwgVWludDhBcnJheT4oe1xuICAgIGFzeW5jIHRyYW5zZm9ybShjaHVuaywgY29udHJvbGxlcikge1xuICAgICAgdHJ5IHtcbiAgICAgICAgaWYgKCFrZXlTdGF0ZS5yZXNvbHZlZCkge1xuICAgICAgICAgIGtleVN0YXRlLmtleSA9IGF3YWl0IGNyeXB0b0tleTtcbiAgICAgICAgICBrZXlTdGF0ZS5yZXNvbHZlZCA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgc2VyaWFsaXplZCA9IHN0cmluZ2lmeShjaHVuaywgcmVkdWNlcnMpO1xuICAgICAgICBjb25zdCBwYXlsb2FkID0gZW5jb2Rlci5lbmNvZGUoc2VyaWFsaXplZCk7XG4gICAgICAgIGxldCBwcmVmaXhlZCA9IGVuY29kZVdpdGhGb3JtYXRQcmVmaXgoXG4gICAgICAgICAgU2VyaWFsaXphdGlvbkZvcm1hdC5ERVZBTFVFX1YxLFxuICAgICAgICAgIHBheWxvYWRcbiAgICAgICAgKSBhcyBVaW50OEFycmF5O1xuXG4gICAgICAgIC8vIEVuY3J5cHQgdGhlIGZyYW1lIHBheWxvYWQgaWYgYSBrZXkgaXMgcHJvdmlkZWQuXG4gICAgICAgIC8vIFRoZSBsZW5ndGggaGVhZGVyIHJlbWFpbnMgaW4gdGhlIGNsZWFyIHNvIHRoZSBkZXNlcmlhbGl6ZXIgY2FuXG4gICAgICAgIC8vIGZpbmQgZnJhbWUgYm91bmRhcmllcyByZWdhcmRsZXNzIG9mIHRyYW5zcG9ydCBjaHVua2luZy5cbiAgICAgICAgaWYgKGtleVN0YXRlLmtleSkge1xuICAgICAgICAgIGNvbnN0IGVuY3J5cHRlZCA9IGF3YWl0IGFlc0djbUVuY3J5cHQoa2V5U3RhdGUua2V5LCBwcmVmaXhlZCk7XG4gICAgICAgICAgcHJlZml4ZWQgPSBlbmNvZGVXaXRoRm9ybWF0UHJlZml4KFxuICAgICAgICAgICAgU2VyaWFsaXphdGlvbkZvcm1hdC5FTkNSWVBURUQsXG4gICAgICAgICAgICBlbmNyeXB0ZWRcbiAgICAgICAgICApIGFzIFVpbnQ4QXJyYXk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBXcml0ZSBsZW5ndGgtcHJlZml4ZWQgZnJhbWU6IFs0LWJ5dGUgbGVuZ3RoXVtwcmVmaXhlZCBkYXRhXVxuICAgICAgICBjb25zdCBmcmFtZSA9IG5ldyBVaW50OEFycmF5KEZSQU1FX0hFQURFUl9TSVpFICsgcHJlZml4ZWQubGVuZ3RoKTtcbiAgICAgICAgbmV3IERhdGFWaWV3KGZyYW1lLmJ1ZmZlcikuc2V0VWludDMyKDAsIHByZWZpeGVkLmxlbmd0aCwgZmFsc2UpO1xuICAgICAgICBmcmFtZS5zZXQocHJlZml4ZWQsIEZSQU1FX0hFQURFUl9TSVpFKTtcbiAgICAgICAgY29udHJvbGxlci5lbnF1ZXVlKGZyYW1lKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGNvbnN0IHsgbWVzc2FnZSwgaGludCB9ID0gZm9ybWF0U2VyaWFsaXphdGlvbkVycm9yKFxuICAgICAgICAgICdzdHJlYW0gY2h1bmsnLFxuICAgICAgICAgIGVycm9yXG4gICAgICAgICk7XG4gICAgICAgIGNvbnRyb2xsZXIuZXJyb3IoXG4gICAgICAgICAgbmV3IFNlcmlhbGl6YXRpb25FcnJvcihtZXNzYWdlLCB7IGhpbnQsIGNhdXNlOiBlcnJvciB9KVxuICAgICAgICApO1xuICAgICAgfVxuICAgIH0sXG4gIH0pO1xuICByZXR1cm4gc3RyZWFtO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0RGVzZXJpYWxpemVTdHJlYW0oXG4gIHJldml2ZXJzOiBQYXJ0aWFsPFJldml2ZXJzPixcbiAgY3J5cHRvS2V5OiBFbmNyeXB0aW9uS2V5UGFyYW1cbik6IFRyYW5zZm9ybVN0cmVhbTxVaW50OEFycmF5LCBhbnk+IHtcbiAgY29uc3QgZGVjb2RlciA9IG5ldyBUZXh0RGVjb2RlcigpO1xuICBsZXQgYnVmZmVyID0gbmV3IFVpbnQ4QXJyYXkoMCk7XG4gIC8vIFJlc29sdmUgdGhlIGtleSBwcm9taXNlIG9uY2Ugb24gZmlyc3QgdXNlIGFuZCBjYWNoZSB0aGUgcmVzdWx0LlxuICBjb25zdCBrZXlTdGF0ZSA9IHsgcmVzb2x2ZWQ6IGZhbHNlLCBrZXk6IHVuZGVmaW5lZCBhcyBDcnlwdG9LZXkgfCB1bmRlZmluZWQgfTtcblxuICBmdW5jdGlvbiBhcHBlbmRUb0J1ZmZlcihkYXRhOiBVaW50OEFycmF5KSB7XG4gICAgY29uc3QgbmV3QnVmZmVyID0gbmV3IFVpbnQ4QXJyYXkoYnVmZmVyLmxlbmd0aCArIGRhdGEubGVuZ3RoKTtcbiAgICBuZXdCdWZmZXIuc2V0KGJ1ZmZlciwgMCk7XG4gICAgbmV3QnVmZmVyLnNldChkYXRhLCBidWZmZXIubGVuZ3RoKTtcbiAgICBidWZmZXIgPSBuZXdCdWZmZXI7XG4gIH1cblxuICBhc3luYyBmdW5jdGlvbiBwcm9jZXNzRnJhbWVzKFxuICAgIGNvbnRyb2xsZXI6IFRyYW5zZm9ybVN0cmVhbURlZmF1bHRDb250cm9sbGVyPGFueT5cbiAgKSB7XG4gICAgLy8gUmVzb2x2ZSB0aGUga2V5IHByb21pc2Ugb25jZSBvbiBmaXJzdCB1c2UgYW5kIGNhY2hlIHRoZSByZXN1bHRcbiAgICBpZiAoIWtleVN0YXRlLnJlc29sdmVkKSB7XG4gICAgICBrZXlTdGF0ZS5rZXkgPSBhd2FpdCBjcnlwdG9LZXk7XG4gICAgICBrZXlTdGF0ZS5yZXNvbHZlZCA9IHRydWU7XG4gICAgfVxuXG4gICAgLy8gVHJ5IHRvIGV4dHJhY3QgY29tcGxldGUgbGVuZ3RoLXByZWZpeGVkIGZyYW1lc1xuICAgIHdoaWxlIChidWZmZXIubGVuZ3RoID49IEZSQU1FX0hFQURFUl9TSVpFKSB7XG4gICAgICBjb25zdCBmcmFtZUxlbmd0aCA9IG5ldyBEYXRhVmlldyhcbiAgICAgICAgYnVmZmVyLmJ1ZmZlcixcbiAgICAgICAgYnVmZmVyLmJ5dGVPZmZzZXQsXG4gICAgICAgIGJ1ZmZlci5ieXRlTGVuZ3RoXG4gICAgICApLmdldFVpbnQzMigwLCBmYWxzZSk7XG5cbiAgICAgIGlmIChidWZmZXIubGVuZ3RoIDwgRlJBTUVfSEVBREVSX1NJWkUgKyBmcmFtZUxlbmd0aCkge1xuICAgICAgICBicmVhazsgLy8gSW5jb21wbGV0ZSBmcmFtZSwgd2FpdCBmb3IgbW9yZSBkYXRhXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGZyYW1lRGF0YSA9IGJ1ZmZlci5zbGljZShcbiAgICAgICAgRlJBTUVfSEVBREVSX1NJWkUsXG4gICAgICAgIEZSQU1FX0hFQURFUl9TSVpFICsgZnJhbWVMZW5ndGhcbiAgICAgICk7XG4gICAgICBidWZmZXIgPSBidWZmZXIuc2xpY2UoRlJBTUVfSEVBREVSX1NJWkUgKyBmcmFtZUxlbmd0aCk7XG5cbiAgICAgIGxldCB7IGZvcm1hdCwgcGF5bG9hZCB9ID0gZGVjb2RlRm9ybWF0UHJlZml4KGZyYW1lRGF0YSk7XG5cbiAgICAgIC8vIElmIHRoZSBmcmFtZSBwYXlsb2FkIGlzIGVuY3J5cHRlZCwgZGVjcnlwdCBpdCBmaXJzdCB0byByZXZlYWxcbiAgICAgIC8vIHRoZSBpbm5lciBmb3JtYXQtcHJlZml4ZWQgZGF0YSAoZS5nLiwgJ2RldmwnICsgc2VyaWFsaXplZCB0ZXh0KSxcbiAgICAgIC8vIHRoZW4gZmFsbCB0aHJvdWdoIHRvIHRoZSBub3JtYWwgZGVzZXJpYWxpemF0aW9uIHBhdGguXG4gICAgICBpZiAoZm9ybWF0ID09PSBTZXJpYWxpemF0aW9uRm9ybWF0LkVOQ1JZUFRFRCkge1xuICAgICAgICBpZiAoIWtleVN0YXRlLmtleSkge1xuICAgICAgICAgIGNvbnRyb2xsZXIuZXJyb3IoXG4gICAgICAgICAgICBuZXcgV29ya2Zsb3dSdW50aW1lRXJyb3IoXG4gICAgICAgICAgICAgICdFbmNyeXB0ZWQgc3RyZWFtIGRhdGEgZW5jb3VudGVyZWQgYnV0IG5vIGVuY3J5cHRpb24ga2V5IGlzIGF2YWlsYWJsZS4gJyArXG4gICAgICAgICAgICAgICAgJ0VuY3J5cHRpb24gaXMgbm90IGNvbmZpZ3VyZWQgb3Igbm8ga2V5IHdhcyBwcm92aWRlZCBmb3IgdGhpcyBydW4uJ1xuICAgICAgICAgICAgKVxuICAgICAgICAgICk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGRlY3J5cHRlZCA9IGF3YWl0IGFlc0djbURlY3J5cHQoa2V5U3RhdGUua2V5LCBwYXlsb2FkKTtcbiAgICAgICAgKHsgZm9ybWF0LCBwYXlsb2FkIH0gPSBkZWNvZGVGb3JtYXRQcmVmaXgoZGVjcnlwdGVkKSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChmb3JtYXQgPT09IFNlcmlhbGl6YXRpb25Gb3JtYXQuREVWQUxVRV9WMSkge1xuICAgICAgICBjb25zdCB0ZXh0ID0gZGVjb2Rlci5kZWNvZGUocGF5bG9hZCk7XG4gICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZShwYXJzZSh0ZXh0LCByZXZpdmVycykpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGNvbnN0IHN0cmVhbSA9IG5ldyBUcmFuc2Zvcm1TdHJlYW08VWludDhBcnJheSwgYW55Pih7XG4gICAgYXN5bmMgdHJhbnNmb3JtKGNodW5rLCBjb250cm9sbGVyKSB7XG4gICAgICAvLyBGaXJzdCwgdHJ5IHRvIGRldGVjdCBpZiB0aGlzIGlzIGxlbmd0aC1wcmVmaXhlZCBmcmFtZWQgZGF0YVxuICAgICAgLy8gYnkgY2hlY2tpbmcgaWYgdGhlIGZpcnN0IDQgYnl0ZXMgZm9ybSBhIHBsYXVzaWJsZSBsZW5ndGguXG4gICAgICBpZiAoYnVmZmVyLmxlbmd0aCA9PT0gMCAmJiBjaHVuay5sZW5ndGggPj0gRlJBTUVfSEVBREVSX1NJWkUpIHtcbiAgICAgICAgY29uc3QgcG9zc2libGVMZW5ndGggPSBuZXcgRGF0YVZpZXcoXG4gICAgICAgICAgY2h1bmsuYnVmZmVyLFxuICAgICAgICAgIGNodW5rLmJ5dGVPZmZzZXQsXG4gICAgICAgICAgY2h1bmsuYnl0ZUxlbmd0aFxuICAgICAgICApLmdldFVpbnQzMigwLCBmYWxzZSk7XG4gICAgICAgIGlmIChcbiAgICAgICAgICBwb3NzaWJsZUxlbmd0aCA+IDAgJiZcbiAgICAgICAgICBwb3NzaWJsZUxlbmd0aCA8IDEwMF8wMDBfMDAwIC8vIHNhbml0eSBjaGVjazogPCAxMDBNQlxuICAgICAgICApIHtcbiAgICAgICAgICAvLyBMb29rcyBsaWtlIGZyYW1lZCBkYXRhXG4gICAgICAgICAgYXBwZW5kVG9CdWZmZXIoY2h1bmspO1xuICAgICAgICAgIGF3YWl0IHByb2Nlc3NGcmFtZXMoY29udHJvbGxlcik7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKGJ1ZmZlci5sZW5ndGggPiAwKSB7XG4gICAgICAgIC8vIEFscmVhZHkgaW4gZnJhbWVkIG1vZGUgKGhhdmUgYnVmZmVyZWQgZGF0YSlcbiAgICAgICAgYXBwZW5kVG9CdWZmZXIoY2h1bmspO1xuICAgICAgICBhd2FpdCBwcm9jZXNzRnJhbWVzKGNvbnRyb2xsZXIpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIC8vIExlZ2FjeSBmb3JtYXQ6IG5ld2xpbmUtZGVsaW1pdGVkIGRldmFsdWUgdGV4dCAobm8gZnJhbWluZylcbiAgICAgIGNvbnN0IHRleHQgPSBkZWNvZGVyLmRlY29kZShjaHVuayk7XG4gICAgICBjb25zdCBsaW5lcyA9IHRleHQuc3BsaXQoJ1xcbicpO1xuICAgICAgZm9yIChjb25zdCBsaW5lIG9mIGxpbmVzKSB7XG4gICAgICAgIGlmIChsaW5lLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUocGFyc2UobGluZSwgcmV2aXZlcnMpKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0sXG4gICAgYXN5bmMgZmx1c2goY29udHJvbGxlcikge1xuICAgICAgLy8gUHJvY2VzcyBhbnkgcmVtYWluaW5nIGZyYW1lZCBkYXRhXG4gICAgICBpZiAoYnVmZmVyLmxlbmd0aCA+IDApIHtcbiAgICAgICAgYXdhaXQgcHJvY2Vzc0ZyYW1lcyhjb250cm9sbGVyKTtcbiAgICAgIH1cbiAgICB9LFxuICB9KTtcbiAgcmV0dXJuIHN0cmVhbTtcbn1cblxuZXhwb3J0IGNsYXNzIFdvcmtmbG93U2VydmVyUmVhZGFibGVTdHJlYW0gZXh0ZW5kcyBSZWFkYWJsZVN0cmVhbTxVaW50OEFycmF5PiB7XG4gICNyZWFkZXI/OiBSZWFkYWJsZVN0cmVhbURlZmF1bHRSZWFkZXI8VWludDhBcnJheT47XG5cbiAgY29uc3RydWN0b3IocnVuSWQ6IHN0cmluZywgbmFtZTogc3RyaW5nLCBzdGFydEluZGV4PzogbnVtYmVyKSB7XG4gICAgaWYgKHR5cGVvZiBuYW1lICE9PSAnc3RyaW5nJyB8fCBuYW1lLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhyb3cgbmV3IFdvcmtmbG93UnVudGltZUVycm9yKGBcIm5hbWVcIiBpcyByZXF1aXJlZCwgZ290IFwiJHtuYW1lfVwiYCk7XG4gICAgfVxuICAgIHN1cGVyKHtcbiAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgTm90IHN1cmUgd2h5IFR5cGVTY3JpcHQgaXMgY29tcGxhaW5pbmcgYWJvdXQgdGhpc1xuICAgICAgdHlwZTogJ2J5dGVzJyxcblxuICAgICAgcHVsbDogYXN5bmMgKGNvbnRyb2xsZXIpID0+IHtcbiAgICAgICAgbGV0IHJlYWRlciA9IHRoaXMuI3JlYWRlcjtcbiAgICAgICAgaWYgKCFyZWFkZXIpIHtcbiAgICAgICAgICBjb25zdCB3b3JsZCA9IGF3YWl0IGdldFdvcmxkTGF6eSgpO1xuICAgICAgICAgIGNvbnN0IHN0cmVhbSA9IGF3YWl0IHdvcmxkLnN0cmVhbXMuZ2V0KHJ1bklkLCBuYW1lLCBzdGFydEluZGV4KTtcbiAgICAgICAgICByZWFkZXIgPSB0aGlzLiNyZWFkZXIgPSBzdHJlYW0uZ2V0UmVhZGVyKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFyZWFkZXIpIHtcbiAgICAgICAgICBjb250cm9sbGVyLmVycm9yKG5ldyBFcnJvcignRmFpbGVkIHRvIGdldCByZWFkZXInKSk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcmVhZGVyLnJlYWQoKTtcbiAgICAgICAgaWYgKHJlc3VsdC5kb25lKSB7XG4gICAgICAgICAgdGhpcy4jcmVhZGVyID0gdW5kZWZpbmVkO1xuICAgICAgICAgIGNvbnRyb2xsZXIuY2xvc2UoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBGb3J3YXJkIHJhdyBieXRlczsgZW5jcnlwdGlvbi9kZWNyeXB0aW9uIGlzIGhhbmRsZWQgYXQgdGhlXG4gICAgICAgICAgLy8gZnJhbWluZyBsZXZlbCBieSBnZXRTZXJpYWxpemVTdHJlYW0vZ2V0RGVzZXJpYWxpemVTdHJlYW0uXG4gICAgICAgICAgY29udHJvbGxlci5lbnF1ZXVlKHJlc3VsdC52YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBjYW5jZWw6IGFzeW5jIChyZWFzb24pID0+IHtcbiAgICAgICAgaWYgKHRoaXMuI3JlYWRlcikge1xuICAgICAgICAgIGF3YWl0IHRoaXMuI3JlYWRlci5jYW5jZWwocmVhc29uKS5jYXRjaCgoKSA9PiB7fSk7XG4gICAgICAgICAgdGhpcy4jcmVhZGVyID0gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgIH0pO1xuICB9XG59XG5cbi8qKlxuICogRGVmYXVsdCBmbHVzaCBpbnRlcnZhbCBpbiBtaWxsaXNlY29uZHMgZm9yIGJ1ZmZlcmVkIHN0cmVhbSB3cml0ZXMuXG4gKiBDaHVua3MgYXJlIGFjY3VtdWxhdGVkIGFuZCBmbHVzaGVkIHRvZ2V0aGVyIHRvIHJlZHVjZSBuZXR3b3JrIG92ZXJoZWFkLlxuICovXG5jb25zdCBTVFJFQU1fRkxVU0hfSU5URVJWQUxfTVMgPSAxMDtcblxuZXhwb3J0IGNsYXNzIFdvcmtmbG93U2VydmVyV3JpdGFibGVTdHJlYW0gZXh0ZW5kcyBXcml0YWJsZVN0cmVhbTxVaW50OEFycmF5PiB7XG4gIGNvbnN0cnVjdG9yKHJ1bklkOiBzdHJpbmcsIG5hbWU6IHN0cmluZykge1xuICAgIGlmICh0eXBlb2YgcnVuSWQgIT09ICdzdHJpbmcnKSB7XG4gICAgICB0aHJvdyBuZXcgV29ya2Zsb3dSdW50aW1lRXJyb3IoXG4gICAgICAgIGBcInJ1bklkXCIgbXVzdCBiZSBhIHN0cmluZywgZ290IFwiJHt0eXBlb2YgcnVuSWR9XCJgXG4gICAgICApO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIG5hbWUgIT09ICdzdHJpbmcnIHx8IG5hbWUubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgV29ya2Zsb3dSdW50aW1lRXJyb3IoYFwibmFtZVwiIGlzIHJlcXVpcmVkLCBnb3QgXCIke25hbWV9XCJgKTtcbiAgICB9XG4gICAgY29uc3Qgd29ybGRQcm9taXNlID0gZ2V0V29ybGRMYXp5KCk7XG5cbiAgICAvLyBCdWZmZXJpbmcgc3RhdGUgZm9yIGJhdGNoZWQgd3JpdGVzXG4gICAgLy8gRW5jcnlwdGlvbi9kZWNyeXB0aW9uIGlzIGhhbmRsZWQgYXQgdGhlIGZyYW1pbmcgbGV2ZWwgYnlcbiAgICAvLyBnZXRTZXJpYWxpemVTdHJlYW0vZ2V0RGVzZXJpYWxpemVTdHJlYW0sIG5vdCBoZXJlLlxuICAgIGxldCBidWZmZXI6IFVpbnQ4QXJyYXlbXSA9IFtdO1xuICAgIGxldCBmbHVzaFRpbWVyOiBSZXR1cm5UeXBlPHR5cGVvZiBzZXRUaW1lb3V0PiB8IG51bGwgPSBudWxsO1xuICAgIGxldCBmbHVzaFByb21pc2U6IFByb21pc2U8dm9pZD4gfCBudWxsID0gbnVsbDtcbiAgICBsZXQgcmVzb2x2ZWRGbHVzaEludGVydmFsTXM6IG51bWJlciB8IHVuZGVmaW5lZDtcblxuICAgIGNvbnN0IGZsdXNoID0gYXN5bmMgKCk6IFByb21pc2U8dm9pZD4gPT4ge1xuICAgICAgaWYgKGZsdXNoVGltZXIpIHtcbiAgICAgICAgY2xlYXJUaW1lb3V0KGZsdXNoVGltZXIpO1xuICAgICAgICBmbHVzaFRpbWVyID0gbnVsbDtcbiAgICAgIH1cblxuICAgICAgaWYgKGJ1ZmZlci5sZW5ndGggPT09IDApIHJldHVybjtcblxuICAgICAgLy8gQ29weSBjaHVua3MgdG8gZmx1c2gsIGJ1dCBkb24ndCBjbGVhciBidWZmZXIgdW50aWwgd3JpdGUgc3VjY2VlZHNcbiAgICAgIC8vIFRoaXMgcHJldmVudHMgZGF0YSBsb3NzIGlmIHRoZSB3cml0ZSBvcGVyYXRpb24gZmFpbHNcbiAgICAgIGNvbnN0IGNodW5rc1RvRmx1c2ggPSBidWZmZXIuc2xpY2UoKTtcblxuICAgICAgY29uc3Qgd29ybGQgPSBhd2FpdCB3b3JsZFByb21pc2U7XG4gICAgICAvLyBDYWNoZSB0aGUgZmx1c2ggaW50ZXJ2YWwgZnJvbSB0aGUgd29ybGQgb24gZmlyc3QgdXNlXG4gICAgICBpZiAocmVzb2x2ZWRGbHVzaEludGVydmFsTXMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXNvbHZlZEZsdXNoSW50ZXJ2YWxNcyA9XG4gICAgICAgICAgd29ybGQuc3RyZWFtRmx1c2hJbnRlcnZhbE1zID8/IFNUUkVBTV9GTFVTSF9JTlRFUlZBTF9NUztcbiAgICAgIH1cbiAgICAgIC8vIFVzZSB3cml0ZU11bHRpIGlmIGF2YWlsYWJsZSBmb3IgYmF0Y2ggd3JpdGVzXG4gICAgICBpZiAoXG4gICAgICAgIHR5cGVvZiB3b3JsZC5zdHJlYW1zLndyaXRlTXVsdGkgPT09ICdmdW5jdGlvbicgJiZcbiAgICAgICAgY2h1bmtzVG9GbHVzaC5sZW5ndGggPiAxXG4gICAgICApIHtcbiAgICAgICAgYXdhaXQgd29ybGQuc3RyZWFtcy53cml0ZU11bHRpKHJ1bklkLCBuYW1lLCBjaHVua3NUb0ZsdXNoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIEZhbGwgYmFjayB0byBzZXF1ZW50aWFsIHdyaXRlc1xuICAgICAgICBmb3IgKGNvbnN0IGNodW5rIG9mIGNodW5rc1RvRmx1c2gpIHtcbiAgICAgICAgICBhd2FpdCB3b3JsZC5zdHJlYW1zLndyaXRlKHJ1bklkLCBuYW1lLCBjaHVuayk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gT25seSBjbGVhciBidWZmZXIgYWZ0ZXIgc3VjY2Vzc2Z1bCB3cml0ZSB0byBwcmV2ZW50IGRhdGEgbG9zc1xuICAgICAgYnVmZmVyID0gW107XG4gICAgfTtcblxuICAgIC8qKiBSZXNvbHZlcnMvcmVqZWN0b3JzIHdhaXRpbmcgZm9yIHRoZSBjdXJyZW50IHNjaGVkdWxlZCBmbHVzaCAqL1xuICAgIGxldCBmbHVzaFdhaXRlcnM6IEFycmF5PHtcbiAgICAgIHJlc29sdmU6ICgpID0+IHZvaWQ7XG4gICAgICByZWplY3Q6IChlcnI6IHVua25vd24pID0+IHZvaWQ7XG4gICAgfT4gPSBbXTtcblxuICAgIGNvbnN0IHNjaGVkdWxlRmx1c2ggPSAoKTogdm9pZCA9PiB7XG4gICAgICBpZiAoZmx1c2hUaW1lcikgcmV0dXJuOyAvLyBBbHJlYWR5IHNjaGVkdWxlZFxuXG4gICAgICBmbHVzaFRpbWVyID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIGZsdXNoVGltZXIgPSBudWxsO1xuICAgICAgICBjb25zdCBjdXJyZW50V2FpdGVycyA9IGZsdXNoV2FpdGVycztcbiAgICAgICAgZmx1c2hXYWl0ZXJzID0gW107XG4gICAgICAgIGZsdXNoUHJvbWlzZSA9IGZsdXNoKCkudGhlbihcbiAgICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IHcgb2YgY3VycmVudFdhaXRlcnMpIHcucmVzb2x2ZSgpO1xuICAgICAgICAgIH0sXG4gICAgICAgICAgKGVycikgPT4ge1xuICAgICAgICAgICAgZm9yIChjb25zdCB3IG9mIGN1cnJlbnRXYWl0ZXJzKSB3LnJlamVjdChlcnIpO1xuICAgICAgICAgIH1cbiAgICAgICAgKTtcbiAgICAgIH0sIHJlc29sdmVkRmx1c2hJbnRlcnZhbE1zID8/IFNUUkVBTV9GTFVTSF9JTlRFUlZBTF9NUyk7XG4gICAgfTtcblxuICAgIHN1cGVyKHtcbiAgICAgIGFzeW5jIHdyaXRlKGNodW5rKSB7XG4gICAgICAgIC8vIFdhaXQgZm9yIGFueSBpbi1wcm9ncmVzcyBmbHVzaCB0byBjb21wbGV0ZSBiZWZvcmUgYWRkaW5nIHRvIGJ1ZmZlclxuICAgICAgICBpZiAoZmx1c2hQcm9taXNlKSB7XG4gICAgICAgICAgYXdhaXQgZmx1c2hQcm9taXNlO1xuICAgICAgICAgIGZsdXNoUHJvbWlzZSA9IG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICBidWZmZXIucHVzaChjaHVuayk7XG4gICAgICAgIHNjaGVkdWxlRmx1c2goKTtcblxuICAgICAgICAvLyBXYWl0IGZvciB0aGUgc2NoZWR1bGVkIGZsdXNoIHRvIGNvbXBsZXRlIHNvIHRoYXQgY2FsbGVyc1xuICAgICAgICAvLyAobGlrZSBmbHVzaGFibGVQaXBlKSBrbm93IGRhdGEgaGFzIHJlYWNoZWQgdGhlIHNlcnZlclxuICAgICAgICAvLyBiZWZvcmUgZGVjcmVtZW50aW5nIHBlbmRpbmdPcHMuIFdpdGhvdXQgdGhpcywgcGVuZGluZ09wc1xuICAgICAgICAvLyByZWFjaGVzIDAgd2hlbiB0aGUgYnVmZmVyZWQgd3JpdGUgcmV0dXJucyAoaW5zdGFudCksIGJ1dFxuICAgICAgICAvLyB0aGUgMTBtcyBmbHVzaCB0aW1lciBoYXNuJ3QgZmlyZWQgeWV0LlxuICAgICAgICBhd2FpdCBuZXcgUHJvbWlzZTx2b2lkPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgZmx1c2hXYWl0ZXJzLnB1c2goeyByZXNvbHZlLCByZWplY3QgfSk7XG4gICAgICAgIH0pO1xuICAgICAgfSxcbiAgICAgIGFzeW5jIGNsb3NlKCkge1xuICAgICAgICAvLyBXYWl0IGZvciBhbnkgaW4tcHJvZ3Jlc3MgZmx1c2ggdG8gY29tcGxldGVcbiAgICAgICAgaWYgKGZsdXNoUHJvbWlzZSkge1xuICAgICAgICAgIGF3YWl0IGZsdXNoUHJvbWlzZTtcbiAgICAgICAgICBmbHVzaFByb21pc2UgPSBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gRmx1c2ggYW55IHJlbWFpbmluZyBidWZmZXJlZCBjaHVua3NcbiAgICAgICAgYXdhaXQgZmx1c2goKTtcblxuICAgICAgICBjb25zdCB3b3JsZCA9IGF3YWl0IHdvcmxkUHJvbWlzZTtcbiAgICAgICAgYXdhaXQgd29ybGQuc3RyZWFtcy5jbG9zZShydW5JZCwgbmFtZSk7XG4gICAgICB9LFxuICAgICAgYWJvcnQocmVhc29uKSB7XG4gICAgICAgIC8vIENsZWFuIHVwIHRpbWVyIHRvIHByZXZlbnQgbGVha3NcbiAgICAgICAgaWYgKGZsdXNoVGltZXIpIHtcbiAgICAgICAgICBjbGVhclRpbWVvdXQoZmx1c2hUaW1lcik7XG4gICAgICAgICAgZmx1c2hUaW1lciA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgLy8gRGlzY2FyZCBidWZmZXJlZCBjaHVua3MgLSB0aGV5IHdvbid0IGJlIHdyaXR0ZW5cbiAgICAgICAgYnVmZmVyID0gW107XG4gICAgICAgIC8vIFJlamVjdCBhbnkgcGVuZGluZyBmbHVzaFdhaXRlcnMgc28gdGhlIHdyaXRlKCkgcHJvbWlzZXMgc2V0dGxlXG4gICAgICAgIC8vIGFuZCBkb24ndCBsZWFrLiBXaXRob3V0IHRoaXMsIHdyaXRlKCkgaGFuZ3MgZm9yZXZlciBvbiBhblxuICAgICAgICAvLyB1bnNldHRsZWQgcHJvbWlzZSBiZWNhdXNlIHRoZSBjbGVhcmVkIHRpbWVyIHdpbGwgbmV2ZXIgZmlyZS5cbiAgICAgICAgY29uc3Qgd2FpdGVycyA9IGZsdXNoV2FpdGVycztcbiAgICAgICAgZmx1c2hXYWl0ZXJzID0gW107XG4gICAgICAgIGNvbnN0IGFib3J0RXJyb3IgPSByZWFzb24gPz8gbmV3IEVycm9yKCdTdHJlYW0gYWJvcnRlZCcpO1xuICAgICAgICBmb3IgKGNvbnN0IHcgb2Ygd2FpdGVycykgdy5yZWplY3QoYWJvcnRFcnJvcik7XG4gICAgICB9LFxuICAgIH0pO1xuICB9XG59XG5cbi8vIFJlLWV4cG9ydCB0eXBlcyBmcm9tIHRoZSBtb2R1bGFyIHNlcmlhbGl6YXRpb24gbW9kdWxlcy5cbmV4cG9ydCB0eXBlIHtcbiAgUmVkdWNlcnMsXG4gIFJldml2ZXJzLFxuICBTZXJpYWxpemFibGVTcGVjaWFsLFxufSBmcm9tICcuL3NlcmlhbGl6YXRpb24vdHlwZXMuanMnO1xuXG4vLyBJbXBvcnQgdHlwZXMgbG9jYWxseSBmb3IgdXNlIHdpdGhpbiB0aGlzIGZpbGUuXG5pbXBvcnQgdHlwZSB7XG4gIFJlZHVjZXJzLFxuICBSZXZpdmVycyxcbiAgU2VyaWFsaXphYmxlU3BlY2lhbCxcbn0gZnJvbSAnLi9zZXJpYWxpemF0aW9uL3R5cGVzLmpzJztcblxuLy8gLS0tLSBDb21wb3NlZCByZWR1Y2VycyAtLS0tXG4vLyBDb21wb3NlcyBtb2R1bGFyIHJlZHVjZXJzIChjb21tb24sIGNsYXNzLCBzdGVwLWZ1bmN0aW9uKSB3aXRoXG4vLyBtb2RlLXNwZWNpZmljIFJlcXVlc3QvUmVzcG9uc2UvU3RyZWFtIHJlZHVjZXJzIGJlbG93LlxuXG4vKipcbiAqIEJhc2UgcmVkdWNlcnMgc2hhcmVkIGFjcm9zcyBhbGwgc2VyaWFsaXphdGlvbiBib3VuZGFyaWVzLlxuICogQ29tcG9zZXM6IGNsYXNzICsgc3RlcC1mdW5jdGlvbiArIGNvbW1vbiByZWR1Y2VycyBmcm9tIHRoZSBtb2R1bGFyIG1vZHVsZXMuXG4gKi9cbmZ1bmN0aW9uIGdldEFsbEJhc2VSZWR1Y2VycyhcbiAgZ2xvYmFsOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0gZ2xvYmFsVGhpc1xuKTogUGFydGlhbDxSZWR1Y2Vycz4ge1xuICAvLyBDbGFzcy9JbnN0YW5jZSBNVVNUIGNvbWUgYmVmb3JlIEVycm9yIHNvIHRoYXQgY3VzdG9tIEVycm9yIHN1YmNsYXNzZXNcbiAgLy8gd2l0aCBXT1JLRkxPV19TRVJJQUxJWkUgdGFrZSBwcmVjZWRlbmNlIChkZXZhbHVlIHVzZXMgZmlyc3QtbWF0Y2gtd2lucykuXG4gIHJldHVybiB7XG4gICAgLi4uZ2V0Q2xhc3NSZWR1Y2VycygpLFxuICAgIC4uLmdldFN0ZXBGdW5jdGlvblJlZHVjZXIoKSxcbiAgICAuLi5nZXRDb21tb25SZWR1Y2VycyhnbG9iYWwpLFxuICAgIC8vIFJlcXVlc3QgYW5kIFJlc3BvbnNlIHJlZHVjZXJzIGFyZSBtb2RlLXNwZWNpZmljIGFuZCBhZGRlZCBieVxuICAgIC8vIGdldEV4dGVybmFsUmVkdWNlcnMgLyBnZXRXb3JrZmxvd1JlZHVjZXJzIC8gZ2V0U3RlcFJlZHVjZXJzIGJlbG93LlxuICAgIFJlcXVlc3Q6ICh2YWx1ZSkgPT4ge1xuICAgICAgaWYgKCEodmFsdWUgaW5zdGFuY2VvZiBnbG9iYWwuUmVxdWVzdCkpIHJldHVybiBmYWxzZTtcbiAgICAgIGNvbnN0IGRhdGE6IFNlcmlhbGl6YWJsZVNwZWNpYWxbJ1JlcXVlc3QnXSA9IHtcbiAgICAgICAgbWV0aG9kOiB2YWx1ZS5tZXRob2QsXG4gICAgICAgIHVybDogdmFsdWUudXJsLFxuICAgICAgICBoZWFkZXJzOiB2YWx1ZS5oZWFkZXJzLFxuICAgICAgICBib2R5OiB2YWx1ZS5ib2R5LFxuICAgICAgICBkdXBsZXg6IHZhbHVlLmR1cGxleCxcbiAgICAgIH07XG4gICAgICBjb25zdCByZXNwb25zZVdyaXRhYmxlID0gdmFsdWVbV0VCSE9PS19SRVNQT05TRV9XUklUQUJMRV07XG4gICAgICBpZiAocmVzcG9uc2VXcml0YWJsZSkge1xuICAgICAgICBkYXRhLnJlc3BvbnNlV3JpdGFibGUgPSByZXNwb25zZVdyaXRhYmxlO1xuICAgICAgfVxuICAgICAgLy8gRm9yd2FyZCB0aGUgc2lnbmFsIGluIHR3byBjYXNlczpcbiAgICAgIC8vICAgMS4gQWxyZWFkeSBhYm9ydGVkIOKAlCBwcmVzZXJ2ZSBhYm9ydGVkPXRydWUvcmVhc29uIHNvIHRoZSBoeWRyYXRlZFxuICAgICAgLy8gICAgICBzdGVwIHNlZXMgdGhlIGNhbmNlbGxhdGlvbiB0aGF0IGhhcHBlbmVkIGJlZm9yZSBzZXJpYWxpemUuXG4gICAgICAvLyAgIDIuIEFscmVhZHkgdGFnZ2VkIHdpdGggd29ya2Zsb3cgaW5mcmFzdHJ1Y3R1cmUg4oCUIGkuZS4gYSBzaWduYWxcbiAgICAgIC8vICAgICAgZnJvbSBhIHdvcmtmbG93LW1hbmFnZWQgQWJvcnRDb250cm9sbGVyLCB3aGljaCBoYXMgc3RyZWFtL2hvb2tcbiAgICAgIC8vICAgICAgYmFja2luZyBmb3IgY3Jvc3MtYm91bmRhcnkgcHJvcGFnYXRpb24uXG4gICAgICAvLyBQbGFpbiBub24tYWJvcnRlZCBuYXRpdmUgc2lnbmFscyBhcmUgaW50ZW50aW9uYWxseSBkcm9wcGVkICh3b3VsZFxuICAgICAgLy8gbWludCBzdHJlYW0gaW5mcmEgZm9yIGV2ZXJ5IFJlcXVlc3QsIGluY2x1ZGluZyB0aGUgYXV0by1nZW5lcmF0ZWRcbiAgICAgIC8vIHNpZ25hbCBvbiBgbmV3IFJlcXVlc3QodXJsKWApLlxuICAgICAgaWYgKFxuICAgICAgICB2YWx1ZS5zaWduYWwgJiZcbiAgICAgICAgKHZhbHVlLnNpZ25hbC5hYm9ydGVkIHx8XG4gICAgICAgICAgKHZhbHVlLnNpZ25hbCBhcyBBYm9ydEludGVybmFscylbQUJPUlRfU1RSRUFNX05BTUVdKVxuICAgICAgKSB7XG4gICAgICAgIGRhdGEuc2lnbmFsID0gdmFsdWUuc2lnbmFsO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGRhdGE7XG4gICAgfSxcbiAgICBSZXNwb25zZTogKHZhbHVlKSA9PiB7XG4gICAgICBpZiAoISh2YWx1ZSBpbnN0YW5jZW9mIGdsb2JhbC5SZXNwb25zZSkpIHJldHVybiBmYWxzZTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHR5cGU6IHZhbHVlLnR5cGUsXG4gICAgICAgIHVybDogdmFsdWUudXJsLFxuICAgICAgICBzdGF0dXM6IHZhbHVlLnN0YXR1cyxcbiAgICAgICAgc3RhdHVzVGV4dDogdmFsdWUuc3RhdHVzVGV4dCxcbiAgICAgICAgaGVhZGVyczogdmFsdWUuaGVhZGVycyxcbiAgICAgICAgYm9keTogdmFsdWUuYm9keSxcbiAgICAgICAgcmVkaXJlY3RlZDogdmFsdWUucmVkaXJlY3RlZCxcbiAgICAgIH07XG4gICAgfSxcbiAgfTtcbn1cblxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBTaGFyZWQgYWJvcnQgcmVkdWNlciBoZWxwZXJzXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxudHlwZSBBYm9ydFNlcmlhbGl6ZWREYXRhID0ge1xuICBzdHJlYW1OYW1lOiBzdHJpbmc7XG4gIGhvb2tUb2tlbjogc3RyaW5nO1xuICBhYm9ydGVkOiBib29sZWFuO1xuICByZWFzb246IHVua25vd247XG59O1xuXG4vKipcbiAqIFN5bWJvbC1rZXllZCBpbnRlcm5hbCBmaWVsZHMgdGFnZ2VkIG9udG8gQWJvcnRDb250cm9sbGVyL0Fib3J0U2lnbmFsXG4gKiBpbnN0YW5jZXMgKGFuZCBgaG9sZGVyYHMgaW4gcmVkdWNlciBoZWxwZXJzKS4gQWxsIG9wdGlvbmFsIOKAlCBhIHBsYWluXG4gKiBuYXRpdmUgaW5zdGFuY2UgaGFzIG5vbmUgb2YgdGhlbSBzZXQuXG4gKi9cbnR5cGUgQWJvcnRJbnRlcm5hbHMgPSB7XG4gIFtBQk9SVF9TVFJFQU1fTkFNRV0/OiBzdHJpbmc7XG4gIFtBQk9SVF9IT09LX1RPS0VOXT86IHN0cmluZztcbiAgW0FCT1JUX1JFQURFUl9DQU5DRUxdPzogQWJvcnRDb250cm9sbGVyO1xufTtcblxudHlwZSBBYm9ydFNpZ25hbExpa2UgPSBBYm9ydEludGVybmFscyAmIHtcbiAgYWJvcnRlZDogYm9vbGVhbjtcbiAgcmVhc29uPzogdW5rbm93bjtcbiAgYWRkRXZlbnRMaXN0ZW5lcj86IEZ1bmN0aW9uO1xufTtcblxudHlwZSBBYm9ydEhvbGRlciA9IEFib3J0SW50ZXJuYWxzICYgeyBzaWduYWw/OiBBYm9ydEludGVybmFscyB9O1xuXG4vKipcbiAqIFNoYXJlZCBsb2dpYyBmb3IgQWJvcnRDb250cm9sbGVyL0Fib3J0U2lnbmFsIHJlZHVjZXJzIGluIGV4dGVybmFsIGFuZCBzdGVwXG4gKiBjb250ZXh0cy4gQXNzaWducyBzdHJlYW0vaG9vayBuYW1lcyBpZiBub3QgYWxyZWFkeSBwcmVzZW50LCBvcHRpb25hbGx5XG4gKiBhdHRhY2hlcyBhbiBhYm9ydCBsaXN0ZW5lciBmb3IgcmVhbC10aW1lIHByb3BhZ2F0aW9uLCBhbmQgcmV0dXJucyB0aGVcbiAqIHNlcmlhbGl6ZWQgcmVwcmVzZW50YXRpb24uXG4gKi9cbmZ1bmN0aW9uIHJlZHVjZUFib3J0V2l0aExpc3RlbmVyKFxuICBzaWduYWw6IEFib3J0U2lnbmFsTGlrZSxcbiAgaG9sZGVyOiBBYm9ydEhvbGRlcixcbiAgZ2xvYmFsOiBSZWNvcmQ8c3RyaW5nLCBhbnk+LFxuICBvcHM6IFByb21pc2U8dm9pZD5bXSxcbiAgcnVuSWQ6IHN0cmluZyxcbiAgY3J5cHRvS2V5OiBFbmNyeXB0aW9uS2V5UGFyYW1cbik6IEFib3J0U2VyaWFsaXplZERhdGEge1xuICBsZXQgc3RyZWFtTmFtZSA9IGhvbGRlcltBQk9SVF9TVFJFQU1fTkFNRV07XG4gIGxldCBob29rVG9rZW4gPSBob2xkZXJbQUJPUlRfSE9PS19UT0tFTl07XG4gIGlmICghc3RyZWFtTmFtZSkge1xuICAgIGNvbnN0IGlkID0gKChnbG9iYWwgYXMgYW55KVtTVEFCTEVfVUxJRF0gfHwgZGVmYXVsdFVsaWQpKCk7XG4gICAgc3RyZWFtTmFtZSA9IGdldEFib3J0U3RyZWFtSWQoaWQpO1xuICAgIGhvb2tUb2tlbiA9IGBhYnJ0XyR7aWR9YDtcbiAgICBob2xkZXJbQUJPUlRfU1RSRUFNX05BTUVdID0gc3RyZWFtTmFtZTtcbiAgICBob2xkZXJbQUJPUlRfSE9PS19UT0tFTl0gPSBob29rVG9rZW47XG4gICAgaWYgKGhvbGRlci5zaWduYWwpIHtcbiAgICAgIGhvbGRlci5zaWduYWxbQUJPUlRfU1RSRUFNX05BTUVdID0gc3RyZWFtTmFtZTtcbiAgICAgIGhvbGRlci5zaWduYWxbQUJPUlRfSE9PS19UT0tFTl0gPSBob29rVG9rZW47XG4gICAgfVxuICB9XG5cbiAgLy8gRGVkdXBlZCB2aWEgQUJPUlRfTElTVEVORVJfQVRUQUNIRUQgbWFya2VyIOKAlCBzZWUgYXR0YWNoQWJvcnRMaXN0ZW5lck9uY2UuXG4gIGF0dGFjaEFib3J0TGlzdGVuZXJPbmNlKFxuICAgIHNpZ25hbCBhcyBBYm9ydFNpZ25hbCxcbiAgICBzdHJlYW1OYW1lLFxuICAgIHJ1bklkLFxuICAgIGNyeXB0b0tleSxcbiAgICBvcHNcbiAgKTtcblxuICByZXR1cm4ge1xuICAgIHN0cmVhbU5hbWUsXG4gICAgaG9va1Rva2VuOiBob29rVG9rZW4hLFxuICAgIGFib3J0ZWQ6IHNpZ25hbC5hYm9ydGVkLFxuICAgIHJlYXNvbjogc2lnbmFsLmFib3J0ZWQgPyBzaWduYWwucmVhc29uIDogdW5kZWZpbmVkLFxuICB9O1xufVxuXG4vKipcbiAqIFNoYXJlZCBsb2dpYyBmb3IgQWJvcnRDb250cm9sbGVyL0Fib3J0U2lnbmFsIHJlZHVjZXJzIGluIHdvcmtmbG93IGNvbnRleHQuXG4gKiBSZWFkcyBleGlzdGluZyBzdHJlYW0vaG9vayBuYW1lcyBmcm9tIHN5bWJvbHMgKG11c3QgYWxyZWFkeSBiZSBzZXQpLlxuICovXG5mdW5jdGlvbiByZWR1Y2VBYm9ydEJ5U3ltYm9sKFxuICBzaWduYWw6IHsgYWJvcnRlZDogYm9vbGVhbjsgcmVhc29uPzogdW5rbm93biB9LFxuICBob2xkZXI6IEFib3J0SG9sZGVyXG4pOiBBYm9ydFNlcmlhbGl6ZWREYXRhIHwgZmFsc2Uge1xuICBjb25zdCBzdHJlYW1OYW1lID1cbiAgICBob2xkZXJbQUJPUlRfU1RSRUFNX05BTUVdID8/IGhvbGRlci5zaWduYWw/LltBQk9SVF9TVFJFQU1fTkFNRV07XG4gIGNvbnN0IGhvb2tUb2tlbiA9XG4gICAgaG9sZGVyW0FCT1JUX0hPT0tfVE9LRU5dID8/IGhvbGRlci5zaWduYWw/LltBQk9SVF9IT09LX1RPS0VOXTtcbiAgaWYgKCFzdHJlYW1OYW1lKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdBYm9ydENvbnRyb2xsZXIvQWJvcnRTaWduYWwgc3RyZWFtIG5hbWUgaXMgbm90IHNldCcpO1xuICB9XG4gIHJldHVybiB7XG4gICAgc3RyZWFtTmFtZSxcbiAgICBob29rVG9rZW46IGhvb2tUb2tlbiEsXG4gICAgYWJvcnRlZDogc2lnbmFsLmFib3J0ZWQsXG4gICAgcmVhc29uOiBzaWduYWwuYWJvcnRlZCA/IHNpZ25hbC5yZWFzb24gOiB1bmRlZmluZWQsXG4gIH07XG59XG5cbi8qKlxuICogQXR0YWNoIGEgc2luZ2xlIGFib3J0IGxpc3RlbmVyIHRvIGEgc2lnbmFsLCBkZWR1cGVkIGFjcm9zcyBjYWxscy5cbiAqXG4gKiBFYWNoIHNlcmlhbGl6YXRpb24gcGFzcyBnb2VzIHRocm91Z2ggdGhlIHJlZHVjZXIsIGJ1dCBhIGNvbnRyb2xsZXIgcGFzc2VkXG4gKiB0byBOIHN0ZXBzIHdvdWxkIG90aGVyd2lzZSBhY2N1bXVsYXRlIE4gbGlzdGVuZXJzIOKAlCBlYWNoIHdyaXRpbmcgdGhlIHNhbWVcbiAqIHN0cmVhbSBwYWNrZXQgYW5kIGRvdWJsZS1jbG9zaW5nIHRoZSBzdHJlYW0gb24gYWJvcnQuIFRoZSBtYXJrZXIgc3ltYm9sXG4gKiBlbnN1cmVzIHRoZSBzdHJlYW0td3JpdGUgc2lkZS1lZmZlY3QgcnVucyBhdCBtb3N0IG9uY2UgcGVyIChzaWduYWwsIHJ1bklkKS5cbiAqL1xuZnVuY3Rpb24gYXR0YWNoQWJvcnRMaXN0ZW5lck9uY2UoXG4gIHNpZ25hbDogQWJvcnRTaWduYWwsXG4gIHN0cmVhbU5hbWU6IHN0cmluZyxcbiAgcnVuSWQ6IHN0cmluZyxcbiAgY3J5cHRvS2V5OiBFbmNyeXB0aW9uS2V5UGFyYW0sXG4gIG9wczogUHJvbWlzZTx2b2lkPltdXG4pOiB2b2lkIHtcbiAgaWYgKHNpZ25hbC5hYm9ydGVkKSByZXR1cm47XG4gIGlmICgoc2lnbmFsIGFzIGFueSlbQUJPUlRfTElTVEVORVJfQVRUQUNIRURdKSByZXR1cm47XG4gIChzaWduYWwgYXMgYW55KVtBQk9SVF9MSVNURU5FUl9BVFRBQ0hFRF0gPSB0cnVlO1xuXG4gIHNpZ25hbC5hZGRFdmVudExpc3RlbmVyKFxuICAgICdhYm9ydCcsXG4gICAgKCkgPT4ge1xuICAgICAgb3BzLnB1c2goXG4gICAgICAgIChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIC8vIERlaHlkcmF0ZSB2aWEgdGhlIHNhbWUgbWFjaGluZXJ5IHRoZSByZWFkZXIgdXNlcyAoaHlkcmF0ZVN0ZXBBcmd1bWVudHMpXG4gICAgICAgICAgICAvLyBzbyB0aGUgcmVhc29uIHJvdW5kLXRyaXBzIHdpdGggZnVsbCB0eXBlIGZpZGVsaXR5IChET01FeGNlcHRpb24sXG4gICAgICAgICAgICAvLyBFcnJvcnMsIGN1c3RvbSBjbGFzc2VzLCBldGMuKSBhbmQgcmVzcGVjdHMgdGhlIHJ1bidzIGVuY3J5cHRpb24ga2V5LlxuICAgICAgICAgICAgLy8gQSBiYXJlIEpTT04uc3RyaW5naWZ5IGhlcmUgd291bGQgd3JpdGUgYSBwYWNrZXQgdGhlIHJlYWRlciBjYW4ndFxuICAgICAgICAgICAgLy8gZGVjb2RlIGFuZCB0aGUgbGlzdGVuZXItc2lkZSBhYm9ydCB3b3VsZCBwcm9wYWdhdGUgd2l0aCBubyByZWFzb24uXG4gICAgICAgICAgICBjb25zdCBrZXkgPSBhd2FpdCBjcnlwdG9LZXk7XG4gICAgICAgICAgICBjb25zdCBwYXlsb2FkID0gYXdhaXQgZGVoeWRyYXRlU3RlcEFyZ3VtZW50cyhcbiAgICAgICAgICAgICAgeyBhYm9ydGVkOiB0cnVlLCByZWFzb246IHNpZ25hbC5yZWFzb24gfSxcbiAgICAgICAgICAgICAgcnVuSWQsXG4gICAgICAgICAgICAgIGtleVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGNvbnN0IHdyaXRhYmxlID0gbmV3IFdvcmtmbG93U2VydmVyV3JpdGFibGVTdHJlYW0oXG4gICAgICAgICAgICAgIHJ1bklkLFxuICAgICAgICAgICAgICBzdHJlYW1OYW1lXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgY29uc3Qgd3JpdGVyID0gd3JpdGFibGUuZ2V0V3JpdGVyKCk7XG4gICAgICAgICAgICBhd2FpdCB3cml0ZXIud3JpdGUocGF5bG9hZCBhcyBVaW50OEFycmF5KTtcbiAgICAgICAgICAgIGF3YWl0IHdyaXRlci5jbG9zZSgpO1xuICAgICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgICAgLy8gQmVzdC1lZmZvcnQgc3RyZWFtIHdyaXRlXG4gICAgICAgICAgfVxuICAgICAgICB9KSgpXG4gICAgICApO1xuICAgIH0sXG4gICAgeyBvbmNlOiB0cnVlIH1cbiAgKTtcbn1cblxuLyoqXG4gKiBSZWR1Y2VycyBmb3Igc2VyaWFsaXphdGlvbiBib3VuZGFyeSBmcm9tIHRoZSBjbGllbnQgc2lkZSwgcGFzc2luZyBhcmd1bWVudHNcbiAqIHRvIHRoZSB3b3JrZmxvdyBoYW5kbGVyLlxuICpcbiAqIEBwYXJhbSBnbG9iYWxcbiAqIEBwYXJhbSBvcHNcbiAqIEByZXR1cm5zXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRFeHRlcm5hbFJlZHVjZXJzKFxuICBnbG9iYWw6IFJlY29yZDxzdHJpbmcsIGFueT4gPSBnbG9iYWxUaGlzLFxuICBvcHM6IFByb21pc2U8dm9pZD5bXSxcbiAgcnVuSWQ6IHN0cmluZyxcbiAgY3J5cHRvS2V5OiBFbmNyeXB0aW9uS2V5UGFyYW1cbik6IFBhcnRpYWw8UmVkdWNlcnM+IHtcbiAgcmV0dXJuIHtcbiAgICAuLi5nZXRBbGxCYXNlUmVkdWNlcnMoZ2xvYmFsKSxcblxuICAgIFJlYWRhYmxlU3RyZWFtOiAodmFsdWUpID0+IHtcbiAgICAgIGlmICghKHZhbHVlIGluc3RhbmNlb2YgZ2xvYmFsLlJlYWRhYmxlU3RyZWFtKSkgcmV0dXJuIGZhbHNlO1xuXG4gICAgICAvLyBTdHJlYW0gbXVzdCBub3QgYmUgbG9ja2VkIHdoZW4gcGFzc2luZyBhY3Jvc3MgZXhlY3V0aW9uIGJvdW5kYXJ5XG4gICAgICBpZiAodmFsdWUubG9ja2VkKSB7XG4gICAgICAgIHRocm93IG5ldyBTZXJpYWxpemF0aW9uRXJyb3IoXG4gICAgICAgICAgJ1JlYWRhYmxlU3RyZWFtIGlzIGxvY2tlZCBhbmQgY2Fubm90IGJlIHBhc3NlZCBhY3Jvc3MgYSB3b3JrZmxvdyBib3VuZGFyeS4nLFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGhpbnQ6ICdQYXNzIHRoZSBzdHJlYW0gYmVmb3JlIGNhbGxpbmcgLmdldFJlYWRlcigpIC8gLnBpcGVUaHJvdWdoKCkgLyAucGlwZVRvKCksIG9yIHRlZSBpdCB3aXRoIC50ZWUoKSBhbmQgcGFzcyBvbmUgb2YgdGhlIGJyYW5jaGVzLicsXG4gICAgICAgICAgfVxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBzdHJlYW1JZCA9ICgoZ2xvYmFsIGFzIGFueSlbU1RBQkxFX1VMSURdIHx8IGRlZmF1bHRVbGlkKSgpO1xuICAgICAgY29uc3QgbmFtZSA9IGBzdHJtXyR7c3RyZWFtSWR9YDtcbiAgICAgIGNvbnN0IHR5cGUgPSBnZXRTdHJlYW1UeXBlKHZhbHVlKTtcblxuICAgICAgY29uc3Qgd3JpdGFibGUgPSBuZXcgV29ya2Zsb3dTZXJ2ZXJXcml0YWJsZVN0cmVhbShydW5JZCwgbmFtZSk7XG4gICAgICBpZiAodHlwZSA9PT0gJ2J5dGVzJykge1xuICAgICAgICBvcHMucHVzaCh2YWx1ZS5waXBlVG8od3JpdGFibGUpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG9wcy5wdXNoKFxuICAgICAgICAgIHZhbHVlXG4gICAgICAgICAgICAucGlwZVRocm91Z2goXG4gICAgICAgICAgICAgIGdldFNlcmlhbGl6ZVN0cmVhbShcbiAgICAgICAgICAgICAgICBnZXRFeHRlcm5hbFJlZHVjZXJzKGdsb2JhbCwgb3BzLCBydW5JZCwgY3J5cHRvS2V5KSxcbiAgICAgICAgICAgICAgICBjcnlwdG9LZXlcbiAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgKVxuICAgICAgICAgICAgLnBpcGVUbyh3cml0YWJsZSlcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgczogU2VyaWFsaXphYmxlU3BlY2lhbFsnUmVhZGFibGVTdHJlYW0nXSA9IHsgbmFtZSB9O1xuICAgICAgaWYgKHR5cGUpIHMudHlwZSA9IHR5cGU7XG4gICAgICByZXR1cm4gcztcbiAgICB9LFxuXG4gICAgV3JpdGFibGVTdHJlYW06ICh2YWx1ZSkgPT4ge1xuICAgICAgaWYgKCEodmFsdWUgaW5zdGFuY2VvZiBnbG9iYWwuV3JpdGFibGVTdHJlYW0pKSByZXR1cm4gZmFsc2U7XG5cbiAgICAgIGNvbnN0IHN0cmVhbUlkID0gKChnbG9iYWwgYXMgYW55KVtTVEFCTEVfVUxJRF0gfHwgZGVmYXVsdFVsaWQpKCk7XG4gICAgICBjb25zdCBuYW1lID0gYHN0cm1fJHtzdHJlYW1JZH1gO1xuXG4gICAgICBjb25zdCByZWFkYWJsZSA9IG5ldyBXb3JrZmxvd1NlcnZlclJlYWRhYmxlU3RyZWFtKHJ1bklkLCBuYW1lKTtcbiAgICAgIG9wcy5wdXNoKHJlYWRhYmxlLnBpcGVUbyh2YWx1ZSkpO1xuXG4gICAgICByZXR1cm4geyBuYW1lIH07XG4gICAgfSxcblxuICAgIEFib3J0Q29udHJvbGxlcjogKHZhbHVlKSA9PiB7XG4gICAgICBpZiAoXG4gICAgICAgICFnbG9iYWwuQWJvcnRDb250cm9sbGVyIHx8XG4gICAgICAgIHR5cGVvZiBnbG9iYWwuQWJvcnRDb250cm9sbGVyICE9PSAnZnVuY3Rpb24nIHx8XG4gICAgICAgICEodmFsdWUgaW5zdGFuY2VvZiBnbG9iYWwuQWJvcnRDb250cm9sbGVyKVxuICAgICAgKVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICByZXR1cm4gcmVkdWNlQWJvcnRXaXRoTGlzdGVuZXIoXG4gICAgICAgIHZhbHVlLnNpZ25hbCxcbiAgICAgICAgdmFsdWUsXG4gICAgICAgIGdsb2JhbCxcbiAgICAgICAgb3BzLFxuICAgICAgICBydW5JZCxcbiAgICAgICAgY3J5cHRvS2V5XG4gICAgICApO1xuICAgIH0sXG5cbiAgICBBYm9ydFNpZ25hbDogKHZhbHVlKSA9PiB7XG4gICAgICBpZiAoXG4gICAgICAgICFnbG9iYWwuQWJvcnRTaWduYWwgfHxcbiAgICAgICAgdHlwZW9mIGdsb2JhbC5BYm9ydFNpZ25hbCAhPT0gJ2Z1bmN0aW9uJyB8fFxuICAgICAgICAhKHZhbHVlIGluc3RhbmNlb2YgZ2xvYmFsLkFib3J0U2lnbmFsKVxuICAgICAgKVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICByZXR1cm4gcmVkdWNlQWJvcnRXaXRoTGlzdGVuZXIoXG4gICAgICAgIHZhbHVlLFxuICAgICAgICB2YWx1ZSxcbiAgICAgICAgZ2xvYmFsLFxuICAgICAgICBvcHMsXG4gICAgICAgIHJ1bklkLFxuICAgICAgICBjcnlwdG9LZXlcbiAgICAgICk7XG4gICAgfSxcbiAgfTtcbn1cblxuLyoqXG4gKiBSZWR1Y2VycyBmb3Igc2VyaWFsaXphdGlvbiBib3VuZGFyeSBmcm9tIHdpdGhpbiB0aGUgd29ya2Zsb3cgZXhlY3V0aW9uXG4gKiBlbnZpcm9ubWVudCwgcGFzc2luZyByZXR1cm4gdmFsdWUgdG8gdGhlIGNsaWVudCBzaWRlIGFuZCBpbnRvIHN0ZXAgYXJndW1lbnRzLlxuICpcbiAqIEBwYXJhbSBnbG9iYWxcbiAqIEByZXR1cm5zXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRXb3JrZmxvd1JlZHVjZXJzKFxuICBnbG9iYWw6IFJlY29yZDxzdHJpbmcsIGFueT4gPSBnbG9iYWxUaGlzXG4pOiBQYXJ0aWFsPFJlZHVjZXJzPiB7XG4gIHJldHVybiB7XG4gICAgLi4uZ2V0QWxsQmFzZVJlZHVjZXJzKGdsb2JhbCksXG5cbiAgICAvLyBSZWFkYWJsZS9Xcml0YWJsZSBzdHJlYW1zIGZyb20gd2l0aGluIHRoZSB3b3JrZmxvdyBleGVjdXRpb24gZW52aXJvbm1lbnRcbiAgICAvLyBhcmUgc2ltcGx5IFwiaGFuZGxlc1wiIHRoYXQgY2FuIGJlIHBhc3NlZCBhcm91bmQgdG8gb3RoZXIgc3RlcHMuXG4gICAgUmVhZGFibGVTdHJlYW06ICh2YWx1ZSkgPT4ge1xuICAgICAgaWYgKCEodmFsdWUgaW5zdGFuY2VvZiBnbG9iYWwuUmVhZGFibGVTdHJlYW0pKSByZXR1cm4gZmFsc2U7XG5cbiAgICAgIC8vIENoZWNrIGlmIHRoaXMgaXMgYSBmYWtlIHN0cmVhbSBzdG9yaW5nIEJvZHlJbml0IGZyb20gUmVxdWVzdC9SZXNwb25zZSBjb25zdHJ1Y3RvclxuICAgICAgY29uc3QgYm9keUluaXQgPSB2YWx1ZVtCT0RZX0lOSVRfU1lNQk9MXTtcbiAgICAgIGlmIChib2R5SW5pdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIC8vIFRoaXMgaXMgYSBmYWtlIHN0cmVhbSAtIHNlcmlhbGl6ZSB0aGUgQm9keUluaXQgZGlyZWN0bHlcbiAgICAgICAgLy8gZGV2YWx1ZSB3aWxsIGhhbmRsZSBzZXJpYWxpemluZyBzdHJpbmdzLCBVaW50OEFycmF5LCBldGMuXG4gICAgICAgIHJldHVybiB7IGJvZHlJbml0IH07XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IG5hbWUgPSB2YWx1ZVtTVFJFQU1fTkFNRV9TWU1CT0xdO1xuICAgICAgaWYgKCFuYW1lKSB7XG4gICAgICAgIHRocm93IG5ldyBXb3JrZmxvd1J1bnRpbWVFcnJvcignUmVhZGFibGVTdHJlYW0gYG5hbWVgIGlzIG5vdCBzZXQnKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHM6IFNlcmlhbGl6YWJsZVNwZWNpYWxbJ1JlYWRhYmxlU3RyZWFtJ10gPSB7IG5hbWUgfTtcbiAgICAgIGNvbnN0IHR5cGUgPSB2YWx1ZVtTVFJFQU1fVFlQRV9TWU1CT0xdO1xuICAgICAgaWYgKHR5cGUpIHMudHlwZSA9IHR5cGU7XG4gICAgICByZXR1cm4gcztcbiAgICB9LFxuICAgIFdyaXRhYmxlU3RyZWFtOiAodmFsdWUpID0+IHtcbiAgICAgIGlmICghKHZhbHVlIGluc3RhbmNlb2YgZ2xvYmFsLldyaXRhYmxlU3RyZWFtKSkgcmV0dXJuIGZhbHNlO1xuICAgICAgY29uc3QgbmFtZSA9IHZhbHVlW1NUUkVBTV9OQU1FX1NZTUJPTF07XG4gICAgICBpZiAoIW5hbWUpIHtcbiAgICAgICAgdGhyb3cgbmV3IFdvcmtmbG93UnVudGltZUVycm9yKCdXcml0YWJsZVN0cmVhbSBgbmFtZWAgaXMgbm90IHNldCcpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHsgbmFtZSB9O1xuICAgIH0sXG5cbiAgICAvLyBBYm9ydENvbnRyb2xsZXIvQWJvcnRTaWduYWwgaW4gd29ya2Zsb3cgY29udGV4dCDigJQganVzdCByZWFkIHN5bWJvbHMgKGhhbmRsZXMpLlxuICAgIC8vIEluIHRoZSB3b3JrZmxvdyBWTSwgZ2xvYmFsLkFib3J0Q29udHJvbGxlciBpcyBhIGNsYXNzIGJ1dCBnbG9iYWwuQWJvcnRTaWduYWxcbiAgICAvLyBpcyBhIHBsYWluIG9iamVjdCAobm90IGEgY2xhc3MpLCBzbyBpbnN0YW5jZW9mIGNoZWNrcyB3b24ndCB3b3JrIGZvciBzaWduYWxzLlxuICAgIC8vIERldGVjdCBpbnN0YW5jZXMgYnkgdGhlIHByZXNlbmNlIG9mIHRoZSBBQk9SVF9TVFJFQU1fTkFNRSBzeW1ib2wgaW5zdGVhZC5cbiAgICBBYm9ydENvbnRyb2xsZXI6ICh2YWx1ZSkgPT4ge1xuICAgICAgaWYgKCF2YWx1ZSB8fCAhdmFsdWUuc2lnbmFsKSByZXR1cm4gZmFsc2U7XG4gICAgICBjb25zdCBob2xkZXIgPSB2YWx1ZSBhcyBBYm9ydENvbnRyb2xsZXIgJiBBYm9ydEhvbGRlcjtcbiAgICAgIGNvbnN0IGhhc0Fib3J0U3ltYm9sID1cbiAgICAgICAgaG9sZGVyW0FCT1JUX1NUUkVBTV9OQU1FXSA/PyBob2xkZXIuc2lnbmFsPy5bQUJPUlRfU1RSRUFNX05BTUVdO1xuICAgICAgY29uc3QgaXNOYXRpdmVBYm9ydENvbnRyb2xsZXIgPVxuICAgICAgICBnbG9iYWwuQWJvcnRDb250cm9sbGVyICYmXG4gICAgICAgIHR5cGVvZiBnbG9iYWwuQWJvcnRDb250cm9sbGVyID09PSAnZnVuY3Rpb24nICYmXG4gICAgICAgIHZhbHVlIGluc3RhbmNlb2YgZ2xvYmFsLkFib3J0Q29udHJvbGxlcjtcbiAgICAgIGlmICghaGFzQWJvcnRTeW1ib2wgJiYgIWlzTmF0aXZlQWJvcnRDb250cm9sbGVyKSByZXR1cm4gZmFsc2U7XG4gICAgICByZXR1cm4gcmVkdWNlQWJvcnRCeVN5bWJvbCh2YWx1ZS5zaWduYWwsIGhvbGRlcik7XG4gICAgfSxcbiAgICBBYm9ydFNpZ25hbDogKHZhbHVlKSA9PiB7XG4gICAgICBjb25zdCBzaWduYWwgPSB2YWx1ZSBhcyAoQWJvcnRTaWduYWwgJiBBYm9ydEludGVybmFscykgfCB1bmRlZmluZWQ7XG4gICAgICBjb25zdCBoYXNBYm9ydFN5bWJvbCA9IHNpZ25hbCAmJiBzaWduYWxbQUJPUlRfU1RSRUFNX05BTUVdO1xuICAgICAgY29uc3QgaXNOYXRpdmVBYm9ydFNpZ25hbCA9XG4gICAgICAgIGdsb2JhbC5BYm9ydFNpZ25hbCAmJlxuICAgICAgICB0eXBlb2YgZ2xvYmFsLkFib3J0U2lnbmFsID09PSAnZnVuY3Rpb24nICYmXG4gICAgICAgIHZhbHVlIGluc3RhbmNlb2YgZ2xvYmFsLkFib3J0U2lnbmFsO1xuICAgICAgaWYgKCFoYXNBYm9ydFN5bWJvbCAmJiAhaXNOYXRpdmVBYm9ydFNpZ25hbCkgcmV0dXJuIGZhbHNlO1xuICAgICAgcmV0dXJuIHJlZHVjZUFib3J0QnlTeW1ib2wodmFsdWUsIHZhbHVlIGFzIEFib3J0SG9sZGVyKTtcbiAgICB9LFxuICB9O1xufVxuXG4vKipcbiAqIFJlZHVjZXJzIGZvciBzZXJpYWxpemF0aW9uIGJvdW5kYXJ5IGZyb20gd2l0aGluIHRoZSBzdGVwIGV4ZWN1dGlvblxuICogZW52aXJvbm1lbnQsIHBhc3NpbmcgcmV0dXJuIHZhbHVlIHRvIHRoZSB3b3JrZmxvdyBoYW5kbGVyLlxuICpcbiAqIEBwYXJhbSBnbG9iYWxcbiAqIEBwYXJhbSBvcHNcbiAqIEBwYXJhbSBydW5JZFxuICogQHJldHVybnNcbiAqL1xuZnVuY3Rpb24gZ2V0U3RlcFJlZHVjZXJzKFxuICBnbG9iYWw6IFJlY29yZDxzdHJpbmcsIGFueT4gPSBnbG9iYWxUaGlzLFxuICBvcHM6IFByb21pc2U8dm9pZD5bXSxcbiAgcnVuSWQ6IHN0cmluZyxcbiAgY3J5cHRvS2V5OiBFbmNyeXB0aW9uS2V5UGFyYW1cbik6IFBhcnRpYWw8UmVkdWNlcnM+IHtcbiAgcmV0dXJuIHtcbiAgICAuLi5nZXRBbGxCYXNlUmVkdWNlcnMoZ2xvYmFsKSxcblxuICAgIFJlYWRhYmxlU3RyZWFtOiAodmFsdWUpID0+IHtcbiAgICAgIGlmICghKHZhbHVlIGluc3RhbmNlb2YgZ2xvYmFsLlJlYWRhYmxlU3RyZWFtKSkgcmV0dXJuIGZhbHNlO1xuXG4gICAgICAvLyBTdHJlYW0gbXVzdCBub3QgYmUgbG9ja2VkIHdoZW4gcGFzc2luZyBhY3Jvc3MgZXhlY3V0aW9uIGJvdW5kYXJ5XG4gICAgICBpZiAodmFsdWUubG9ja2VkKSB7XG4gICAgICAgIHRocm93IG5ldyBTZXJpYWxpemF0aW9uRXJyb3IoXG4gICAgICAgICAgJ1JlYWRhYmxlU3RyZWFtIGlzIGxvY2tlZCBhbmQgY2Fubm90IGJlIHBhc3NlZCBhY3Jvc3MgYSB3b3JrZmxvdyBib3VuZGFyeS4nLFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGhpbnQ6ICdQYXNzIHRoZSBzdHJlYW0gYmVmb3JlIGNhbGxpbmcgLmdldFJlYWRlcigpIC8gLnBpcGVUaHJvdWdoKCkgLyAucGlwZVRvKCksIG9yIHRlZSBpdCB3aXRoIC50ZWUoKSBhbmQgcGFzcyBvbmUgb2YgdGhlIGJyYW5jaGVzLicsXG4gICAgICAgICAgfVxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICAvLyBDaGVjayBpZiB0aGUgc3RyZWFtIGFscmVhZHkgaGFzIHRoZSBuYW1lIHN5bWJvbCBzZXQsIGluIHdoaWNoIGNhc2VcbiAgICAgIC8vIGl0J3MgYWxyZWFkeSBiZWluZyBzdW5rIHRvIHRoZSBzZXJ2ZXIgYW5kIHdlIGNhbiBqdXN0IHJldHVybiB0aGVcbiAgICAgIC8vIG5hbWUgYW5kIHR5cGUuXG4gICAgICBsZXQgbmFtZSA9IHZhbHVlW1NUUkVBTV9OQU1FX1NZTUJPTF07XG4gICAgICBsZXQgdHlwZSA9IHZhbHVlW1NUUkVBTV9UWVBFX1NZTUJPTF07XG5cbiAgICAgIGlmICghbmFtZSkge1xuICAgICAgICBjb25zdCBzdHJlYW1JZCA9ICgoZ2xvYmFsIGFzIGFueSlbU1RBQkxFX1VMSURdIHx8IGRlZmF1bHRVbGlkKSgpO1xuICAgICAgICBuYW1lID0gYHN0cm1fJHtzdHJlYW1JZH1gO1xuICAgICAgICB0eXBlID0gZ2V0U3RyZWFtVHlwZSh2YWx1ZSk7XG5cbiAgICAgICAgY29uc3Qgd3JpdGFibGUgPSBuZXcgV29ya2Zsb3dTZXJ2ZXJXcml0YWJsZVN0cmVhbShydW5JZCwgbmFtZSk7XG4gICAgICAgIGlmICh0eXBlID09PSAnYnl0ZXMnKSB7XG4gICAgICAgICAgb3BzLnB1c2godmFsdWUucGlwZVRvKHdyaXRhYmxlKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgb3BzLnB1c2goXG4gICAgICAgICAgICB2YWx1ZVxuICAgICAgICAgICAgICAucGlwZVRocm91Z2goXG4gICAgICAgICAgICAgICAgZ2V0U2VyaWFsaXplU3RyZWFtKFxuICAgICAgICAgICAgICAgICAgZ2V0U3RlcFJlZHVjZXJzKGdsb2JhbCwgb3BzLCBydW5JZCwgY3J5cHRvS2V5KSxcbiAgICAgICAgICAgICAgICAgIGNyeXB0b0tleVxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAucGlwZVRvKHdyaXRhYmxlKVxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgY29uc3QgczogU2VyaWFsaXphYmxlU3BlY2lhbFsnUmVhZGFibGVTdHJlYW0nXSA9IHsgbmFtZSB9O1xuICAgICAgaWYgKHR5cGUpIHMudHlwZSA9IHR5cGU7XG4gICAgICByZXR1cm4gcztcbiAgICB9LFxuXG4gICAgV3JpdGFibGVTdHJlYW06ICh2YWx1ZSkgPT4ge1xuICAgICAgaWYgKCEodmFsdWUgaW5zdGFuY2VvZiBnbG9iYWwuV3JpdGFibGVTdHJlYW0pKSByZXR1cm4gZmFsc2U7XG5cbiAgICAgIGxldCBuYW1lID0gdmFsdWVbU1RSRUFNX05BTUVfU1lNQk9MXTtcbiAgICAgIGlmICghbmFtZSkge1xuICAgICAgICBjb25zdCBzdHJlYW1JZCA9ICgoZ2xvYmFsIGFzIGFueSlbU1RBQkxFX1VMSURdIHx8IGRlZmF1bHRVbGlkKSgpO1xuICAgICAgICBuYW1lID0gYHN0cm1fJHtzdHJlYW1JZH1gO1xuICAgICAgICBvcHMucHVzaChcbiAgICAgICAgICBuZXcgV29ya2Zsb3dTZXJ2ZXJSZWFkYWJsZVN0cmVhbShydW5JZCwgbmFtZSlcbiAgICAgICAgICAgIC5waXBlVGhyb3VnaChcbiAgICAgICAgICAgICAgZ2V0RGVzZXJpYWxpemVTdHJlYW0oXG4gICAgICAgICAgICAgICAgZ2V0U3RlcFJldml2ZXJzKGdsb2JhbCwgb3BzLCBydW5JZCwgY3J5cHRvS2V5KSxcbiAgICAgICAgICAgICAgICBjcnlwdG9LZXlcbiAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgKVxuICAgICAgICAgICAgLnBpcGVUbyh2YWx1ZSlcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHsgbmFtZSB9O1xuICAgIH0sXG5cbiAgICBBYm9ydENvbnRyb2xsZXI6ICh2YWx1ZSkgPT4ge1xuICAgICAgaWYgKFxuICAgICAgICAhZ2xvYmFsLkFib3J0Q29udHJvbGxlciB8fFxuICAgICAgICB0eXBlb2YgZ2xvYmFsLkFib3J0Q29udHJvbGxlciAhPT0gJ2Z1bmN0aW9uJyB8fFxuICAgICAgICAhKHZhbHVlIGluc3RhbmNlb2YgZ2xvYmFsLkFib3J0Q29udHJvbGxlcilcbiAgICAgIClcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgcmV0dXJuIHJlZHVjZUFib3J0V2l0aExpc3RlbmVyKFxuICAgICAgICB2YWx1ZS5zaWduYWwsXG4gICAgICAgIHZhbHVlLFxuICAgICAgICBnbG9iYWwsXG4gICAgICAgIG9wcyxcbiAgICAgICAgcnVuSWQsXG4gICAgICAgIGNyeXB0b0tleVxuICAgICAgKTtcbiAgICB9LFxuXG4gICAgQWJvcnRTaWduYWw6ICh2YWx1ZSkgPT4ge1xuICAgICAgaWYgKFxuICAgICAgICAhZ2xvYmFsLkFib3J0U2lnbmFsIHx8XG4gICAgICAgIHR5cGVvZiBnbG9iYWwuQWJvcnRTaWduYWwgIT09ICdmdW5jdGlvbicgfHxcbiAgICAgICAgISh2YWx1ZSBpbnN0YW5jZW9mIGdsb2JhbC5BYm9ydFNpZ25hbClcbiAgICAgIClcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgcmV0dXJuIHJlZHVjZUFib3J0V2l0aExpc3RlbmVyKFxuICAgICAgICB2YWx1ZSxcbiAgICAgICAgdmFsdWUsXG4gICAgICAgIGdsb2JhbCxcbiAgICAgICAgb3BzLFxuICAgICAgICBydW5JZCxcbiAgICAgICAgY3J5cHRvS2V5XG4gICAgICApO1xuICAgIH0sXG4gIH07XG59XG5cbi8qKlxuICogQ2FuY2VsIGRhbmdsaW5nIGFib3J0LXN0cmVhbSByZWFkZXJzIG9uIGFueSBBYm9ydENvbnRyb2xsZXIgaW5zdGFuY2VzIGZvdW5kXG4gKiBpbiB0aGUgaHlkcmF0ZWQgc3RlcCBhcmd1bWVudHMuIENhbGxlZCBhZnRlciB0aGUgc3RlcCBmdW5jdGlvbiByZXR1cm5zXG4gKiAoc3VjY2VzcyBvciBmYWlsdXJlKSB0byBwcmV2ZW50IHJlYWRlciBwcm9taXNlcyBmcm9tIGtlZXBpbmcgdGhlIHNlcnZlcmxlc3NcbiAqIGZ1bmN0aW9uIGFsaXZlIGluZGVmaW5pdGVseS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNhbmNlbEFib3J0UmVhZGVycyguLi52YWx1ZXM6IHVua25vd25bXSk6IHZvaWQge1xuICBjb25zdCB2aXNpdGVkID0gbmV3IFdlYWtTZXQoKTtcbiAgZnVuY3Rpb24gY2FuY2VsSWZQcmVzZW50KHZhbDogQWJvcnRJbnRlcm5hbHMpOiB2b2lkIHtcbiAgICBjb25zdCBjYW5jZWwgPSB2YWxbQUJPUlRfUkVBREVSX0NBTkNFTF07XG4gICAgaWYgKGNhbmNlbCAmJiAhY2FuY2VsLnNpZ25hbC5hYm9ydGVkKSB7XG4gICAgICBjYW5jZWwuYWJvcnQoKTtcbiAgICB9XG4gIH1cbiAgZnVuY3Rpb24gd2Fsayh2YWw6IHVua25vd24pOiB2b2lkIHtcbiAgICBpZiAodmFsID09IG51bGwgfHwgdHlwZW9mIHZhbCAhPT0gJ29iamVjdCcpIHJldHVybjtcbiAgICBpZiAodmlzaXRlZC5oYXModmFsIGFzIG9iamVjdCkpIHJldHVybjtcbiAgICB2aXNpdGVkLmFkZCh2YWwgYXMgb2JqZWN0KTtcbiAgICBpZiAodmFsIGluc3RhbmNlb2YgQWJvcnRDb250cm9sbGVyKSB7XG4gICAgICBjYW5jZWxJZlByZXNlbnQodmFsIGFzIEFib3J0Q29udHJvbGxlciAmIEFib3J0SW50ZXJuYWxzKTtcbiAgICAgIGNhbmNlbElmUHJlc2VudCh2YWwuc2lnbmFsIGFzIEFib3J0U2lnbmFsICYgQWJvcnRJbnRlcm5hbHMpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAodmFsIGluc3RhbmNlb2YgQWJvcnRTaWduYWwpIHtcbiAgICAgIGNhbmNlbElmUHJlc2VudCh2YWwgYXMgQWJvcnRTaWduYWwgJiBBYm9ydEludGVybmFscyk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChBcnJheS5pc0FycmF5KHZhbCkpIHtcbiAgICAgIGZvciAoY29uc3QgaXRlbSBvZiB2YWwpIHdhbGsoaXRlbSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICh2YWwgaW5zdGFuY2VvZiBNYXApIHtcbiAgICAgIGZvciAoY29uc3QgdiBvZiB2YWwudmFsdWVzKCkpIHdhbGsodik7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICh2YWwgaW5zdGFuY2VvZiBTZXQpIHtcbiAgICAgIGZvciAoY29uc3QgdiBvZiB2YWwpIHdhbGsodik7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIC8vIFJlcXVlc3QvUmVzcG9uc2UgZXhwb3NlIGBzaWduYWxgL2Bib2R5YCBhcyBwcm90b3R5cGUgZ2V0dGVycywgc29cbiAgICAvLyBPYmplY3QudmFsdWVzKCkgd29uJ3QgZmluZCB0aGVtLiBEZXNjZW5kIGV4cGxpY2l0bHkuXG4gICAgaWYgKHR5cGVvZiBSZXF1ZXN0ICE9PSAndW5kZWZpbmVkJyAmJiB2YWwgaW5zdGFuY2VvZiBSZXF1ZXN0KSB7XG4gICAgICB3YWxrKHZhbC5zaWduYWwpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IHYgb2YgT2JqZWN0LnZhbHVlcyh2YWwgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4pKSB3YWxrKHYpO1xuICB9XG4gIGZvciAoY29uc3QgdiBvZiB2YWx1ZXMpIHdhbGsodik7XG59XG5cbi8qKlxuICogU2V0cyB1cCBhIHN0cmVhbSByZWFkZXIgb24gdGhlIGNvbnRyb2xsZXIgdGhhdCBsaXN0ZW5zIGZvciBhbiBhYm9ydCBwYWNrZXQuXG4gKiBSZXR1cm5zIHRoZSByZWFkZXJDYW5jZWwgY29udHJvbGxlciBzbyBpdCBjYW4gYmUgc3RvcmVkIG9uIGJvdGggdGhlXG4gKiBjb250cm9sbGVyIGFuZCBzaWduYWwgZm9yIGNsZWFudXAgYnkgY2FuY2VsQWJvcnRSZWFkZXJzLlxuICovXG5mdW5jdGlvbiBzZXR1cEFib3J0U3RyZWFtUmVhZGVyKFxuICBjb250cm9sbGVyOiBBYm9ydENvbnRyb2xsZXIsXG4gIHJ1bklkOiBzdHJpbmcsXG4gIHN0cmVhbU5hbWU6IHN0cmluZyxcbiAgb3BzOiBQcm9taXNlPHZvaWQ+W11cbik6IEFib3J0Q29udHJvbGxlciB7XG4gIGNvbnN0IHJlYWRlckNhbmNlbCA9IG5ldyBBYm9ydENvbnRyb2xsZXIoKTtcblxuICBvcHMucHVzaChcbiAgICAoYXN5bmMgKCkgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcmVhZGFibGUgPSBuZXcgV29ya2Zsb3dTZXJ2ZXJSZWFkYWJsZVN0cmVhbShydW5JZCwgc3RyZWFtTmFtZSk7XG4gICAgICAgIGNvbnN0IHJlYWRlciA9IHJlYWRhYmxlLmdldFJlYWRlcigpO1xuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBQcm9taXNlLnJhY2UoW1xuICAgICAgICAgIHJlYWRlci5yZWFkKCksXG4gICAgICAgICAgbmV3IFByb21pc2U8eyB2YWx1ZTogdW5kZWZpbmVkOyBkb25lOiB0cnVlIH0+KChyZXNvbHZlKSA9PiB7XG4gICAgICAgICAgICBpZiAocmVhZGVyQ2FuY2VsLnNpZ25hbC5hYm9ydGVkKSB7XG4gICAgICAgICAgICAgIHJlc29sdmUoeyB2YWx1ZTogdW5kZWZpbmVkLCBkb25lOiB0cnVlIH0pO1xuICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZWFkZXJDYW5jZWwuc2lnbmFsLmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICAgICAgICAgICdhYm9ydCcsXG4gICAgICAgICAgICAgICgpID0+IHJlc29sdmUoeyB2YWx1ZTogdW5kZWZpbmVkLCBkb25lOiB0cnVlIH0pLFxuICAgICAgICAgICAgICB7IG9uY2U6IHRydWUgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9KSxcbiAgICAgICAgXSk7XG4gICAgICAgIHJlYWRlci5yZWxlYXNlTG9jaygpO1xuICAgICAgICBpZiAocmVzdWx0LnZhbHVlICYmICFyZXN1bHQuZG9uZSkge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAvLyBIeWRyYXRlIHZpYSB0aGUgc2FtZSBtYWNoaW5lcnkgdGhlIHdyaXRlciB1c2VkIHNvIHRoZSByZWFzb25cbiAgICAgICAgICAgIC8vIHJvdW5kLXRyaXBzIHdpdGggZnVsbCB0eXBlIGZpZGVsaXR5LiBFbmNyeXB0aW9uIGtleSAoaWYgYW55KVxuICAgICAgICAgICAgLy8gY29tZXMgZnJvbSB0aGUgc3RlcCBjb250ZXh0IOKAlCBzZXQgdXAgYnkgdGhlIHN0ZXAgaGFuZGxlciBiZWZvcmVcbiAgICAgICAgICAgIC8vIHRoaXMgcmVhZGVyIHJ1bnMuIEZhbGxiYWNrIHRvIHVuZGVmaW5lZCBmb3IgZXh0ZXJuYWwtY29udGV4dFxuICAgICAgICAgICAgLy8gcmV2aXZlcyAodGhlIGh5ZHJhdGUgcGF0aCBpcyBlbmNyeXB0aW9uLWtleS10b2xlcmFudCkuXG4gICAgICAgICAgICBjb25zdCBjdHhGb3JLZXkgPSBjb250ZXh0U3RvcmFnZS5nZXRTdG9yZSgpO1xuICAgICAgICAgICAgY29uc3QgZGF0YSA9IChhd2FpdCBoeWRyYXRlU3RlcEFyZ3VtZW50cyhcbiAgICAgICAgICAgICAgcmVzdWx0LnZhbHVlLFxuICAgICAgICAgICAgICBydW5JZCxcbiAgICAgICAgICAgICAgY3R4Rm9yS2V5Py5lbmNyeXB0aW9uS2V5XG4gICAgICAgICAgICApKSBhcyB7IHJlYXNvbj86IHVua25vd24gfSB8IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIGNvbnRyb2xsZXIuYWJvcnQoZGF0YT8ucmVhc29uKTtcbiAgICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICAgIGNvbnRyb2xsZXIuYWJvcnQoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICAvLyBTdHJlYW0gcmVhZCBmYWlsZWQg4oCUIHNpZ25hbCB3b24ndCBwcm9wYWdhdGUgaW4gcmVhbC10aW1lLFxuICAgICAgICAvLyBidXQgaG9vay1iYXNlZCBwcm9wYWdhdGlvbiBvbiBuZXh0IHJlcGxheSBwcm92aWRlcyBmYWxsYmFja1xuICAgICAgfVxuICAgIH0pKClcbiAgKTtcblxuICByZXR1cm4gcmVhZGVyQ2FuY2VsO1xufVxuXG4vKipcbiAqIFN0b3JlcyBhYm9ydCBzZXJpYWxpemF0aW9uIHN5bWJvbHMgYW5kIHRoZSByZWFkZXJDYW5jZWwgY29udHJvbGxlclxuICogb24gYm90aCB0aGUgY29udHJvbGxlciBhbmQgaXRzIHNpZ25hbC5cbiAqL1xuZnVuY3Rpb24gdGFnQWJvcnRQYWlyKFxuICBjb250cm9sbGVyOiBBYm9ydENvbnRyb2xsZXIsXG4gIHZhbHVlOiB7IHN0cmVhbU5hbWU6IHN0cmluZzsgaG9va1Rva2VuOiBzdHJpbmcgfSxcbiAgcmVhZGVyQ2FuY2VsPzogQWJvcnRDb250cm9sbGVyXG4pOiB2b2lkIHtcbiAgY29uc3QgdGFnZ2VkQ29udHJvbGxlciA9IGNvbnRyb2xsZXIgYXMgQWJvcnRDb250cm9sbGVyICYgQWJvcnRJbnRlcm5hbHM7XG4gIGNvbnN0IHRhZ2dlZFNpZ25hbCA9IGNvbnRyb2xsZXIuc2lnbmFsIGFzIEFib3J0U2lnbmFsICYgQWJvcnRJbnRlcm5hbHM7XG4gIHRhZ2dlZENvbnRyb2xsZXJbQUJPUlRfU1RSRUFNX05BTUVdID0gdmFsdWUuc3RyZWFtTmFtZTtcbiAgdGFnZ2VkQ29udHJvbGxlcltBQk9SVF9IT09LX1RPS0VOXSA9IHZhbHVlLmhvb2tUb2tlbjtcbiAgdGFnZ2VkU2lnbmFsW0FCT1JUX1NUUkVBTV9OQU1FXSA9IHZhbHVlLnN0cmVhbU5hbWU7XG4gIHRhZ2dlZFNpZ25hbFtBQk9SVF9IT09LX1RPS0VOXSA9IHZhbHVlLmhvb2tUb2tlbjtcbiAgaWYgKHJlYWRlckNhbmNlbCkge1xuICAgIHRhZ2dlZENvbnRyb2xsZXJbQUJPUlRfUkVBREVSX0NBTkNFTF0gPSByZWFkZXJDYW5jZWw7XG4gICAgdGFnZ2VkU2lnbmFsW0FCT1JUX1JFQURFUl9DQU5DRUxdID0gcmVhZGVyQ2FuY2VsO1xuICB9XG59XG5cbi8qKlxuICogUHJvcGFnYXRlIGFib3J0LWludGVybmFsIHN5bWJvbHMgZnJvbSBvbmUgc2lnbmFsIHRvIGFub3RoZXIuIFVzZWQgYnkgdGhlXG4gKiBSZXF1ZXN0IHJldml2ZXIgYmVjYXVzZSBgbmV3IFJlcXVlc3QodXJsLCB7IHNpZ25hbCB9KWAgY29waWVzIHRoZSBzaWduYWxcbiAqIGludGVybmFsbHkg4oCUIHRoZSBjb25zdHJ1Y3RlZCBgcmVxdWVzdC5zaWduYWxgIGlzIGEgZnJlc2ggQWJvcnRTaWduYWwgdGhhdFxuICogZG9lc24ndCBjYXJyeSBzeW1ib2xzIGZyb20gdGhlIHNvdXJjZS5cbiAqL1xuZnVuY3Rpb24gY29weUFib3J0SW50ZXJuYWxzKHNyYzogQWJvcnRTaWduYWwsIGRlc3Q6IEFib3J0U2lnbmFsKTogdm9pZCB7XG4gIGNvbnN0IHMgPSBzcmMgYXMgQWJvcnRTaWduYWwgJiBBYm9ydEludGVybmFscztcbiAgY29uc3QgZCA9IGRlc3QgYXMgQWJvcnRTaWduYWwgJiBBYm9ydEludGVybmFscztcbiAgaWYgKHNbQUJPUlRfU1RSRUFNX05BTUVdICE9PSB1bmRlZmluZWQpIHtcbiAgICBkW0FCT1JUX1NUUkVBTV9OQU1FXSA9IHNbQUJPUlRfU1RSRUFNX05BTUVdO1xuICB9XG4gIGlmIChzW0FCT1JUX0hPT0tfVE9LRU5dICE9PSB1bmRlZmluZWQpIHtcbiAgICBkW0FCT1JUX0hPT0tfVE9LRU5dID0gc1tBQk9SVF9IT09LX1RPS0VOXTtcbiAgfVxuICBpZiAoc1tBQk9SVF9SRUFERVJfQ0FOQ0VMXSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgZFtBQk9SVF9SRUFERVJfQ0FOQ0VMXSA9IHNbQUJPUlRfUkVBREVSX0NBTkNFTF07XG4gIH1cbn1cblxuLyoqXG4gKiBDcmVhdGVzIGFuIEFib3J0Q29udHJvbGxlciB3aXRoIHN0cmVhbS1iYWNrZWQgYWJvcnQgcHJvcGFnYXRpb24uXG4gKiBVc2VkIGJ5IHN0ZXAgYW5kIGV4dGVybmFsIHJldml2ZXJzIHdoZXJlIHJlYWwgYWJvcnQgc2lnbmFsIGJlaGF2aW9yIGlzIG5lZWRlZC5cbiAqXG4gKiBAcGFyYW0gdmFsdWUgLSBUaGUgc2VyaWFsaXplZCBhYm9ydCBjb250cm9sbGVyL3NpZ25hbCBkYXRhXG4gKiBAcGFyYW0gb3BzIC0gVGhlIG9wcyBhcnJheSBmb3IgdHJhY2tpbmcgYXN5bmMgd29ya1xuICogQHBhcmFtIHJ1bklkIC0gVGhlIHdvcmtmbG93IHJ1biBJRCAoZm9yIHN0cmVhbSByZWFkcylcbiAqIEByZXR1cm5zIEEgcmVhbCBBYm9ydENvbnRyb2xsZXIgd2l0aCBwYXRjaGVkIGFib3J0KCkgbWV0aG9kXG4gKi9cbmZ1bmN0aW9uIHJldml2ZUFib3J0Q29udHJvbGxlcihcbiAgdmFsdWU6IFNlcmlhbGl6YWJsZVNwZWNpYWxbJ0Fib3J0Q29udHJvbGxlciddLFxuICBvcHM6IFByb21pc2U8dm9pZD5bXSxcbiAgcnVuSWQ6IHN0cmluZ1xuKTogQWJvcnRDb250cm9sbGVyIHtcbiAgY29uc3QgY29udHJvbGxlciA9IG5ldyBBYm9ydENvbnRyb2xsZXIoKTtcblxuICBpZiAodmFsdWUuYWJvcnRlZCkge1xuICAgIHRhZ0Fib3J0UGFpcihjb250cm9sbGVyLCB2YWx1ZSk7XG4gICAgY29udHJvbGxlci5hYm9ydCh2YWx1ZS5yZWFzb24pO1xuICB9IGVsc2UgaWYgKHZhbHVlLnN0cmVhbU5hbWUpIHtcbiAgICBjb25zdCByZWFkZXJDYW5jZWwgPSBzZXR1cEFib3J0U3RyZWFtUmVhZGVyKFxuICAgICAgY29udHJvbGxlcixcbiAgICAgIHJ1bklkLFxuICAgICAgdmFsdWUuc3RyZWFtTmFtZSxcbiAgICAgIG9wc1xuICAgICk7XG4gICAgdGFnQWJvcnRQYWlyKGNvbnRyb2xsZXIsIHZhbHVlLCByZWFkZXJDYW5jZWwpO1xuICB9IGVsc2Uge1xuICAgIHRhZ0Fib3J0UGFpcihjb250cm9sbGVyLCB2YWx1ZSk7XG4gIH1cblxuICAvLyBPdmVycmlkZSBhYm9ydCgpIHRvIGFsc28gd3JpdGUgc3RyZWFtICsgcmVzdW1lIGhvb2sgKGZvciBzdGVwLWluaXRpYXRlZCBhYm9ydClcbiAgY29uc3Qgb3JpZ2luYWxBYm9ydCA9IGNvbnRyb2xsZXIuYWJvcnQuYmluZChjb250cm9sbGVyKTtcbiAgY29udHJvbGxlci5hYm9ydCA9IChyZWFzb24/OiB1bmtub3duKSA9PiB7XG4gICAgaWYgKGNvbnRyb2xsZXIuc2lnbmFsLmFib3J0ZWQpIHJldHVybjtcbiAgICBvcmlnaW5hbEFib3J0KHJlYXNvbik7XG5cbiAgICBjb25zdCBjdHggPSBjb250ZXh0U3RvcmFnZS5nZXRTdG9yZSgpO1xuICAgIGlmIChjdHgpIHtcbiAgICAgIGN0eC5vcHMucHVzaChcbiAgICAgICAgKGFzeW5jICgpID0+IHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgLy8gRGVoeWRyYXRlIHRoZSBhYm9ydCBwYXlsb2FkIHRocm91Z2ggdGhlIHNhbWUgbWFjaGluZXJ5IHRoZSBob29rXG4gICAgICAgICAgICAvLyBldmVudCB1c2VzIHNvIHRoZSBgcmVhc29uYCByb3VuZC10cmlwcyB3aXRoIGZ1bGwgdHlwZSBmaWRlbGl0eVxuICAgICAgICAgICAgLy8gKERPTUV4Y2VwdGlvbiwgY3VzdG9tIGVycm9ycywgZXRjLikgYW5kIHJlc3BlY3RzIHRoZSBydW4nc1xuICAgICAgICAgICAgLy8gZW5jcnlwdGlvbiBrZXkg4oCUIHN5bW1ldHJpYyB3aXRoIHdoYXQgdGhlIHN1c3BlbnNpb24gaGFuZGxlclxuICAgICAgICAgICAgLy8gd3JpdGVzIGZvciB3b3JrZmxvdy1pbml0aWF0ZWQgYWJvcnRzLlxuICAgICAgICAgICAgY29uc3QgcGF5bG9hZCA9IGF3YWl0IGRlaHlkcmF0ZVN0ZXBBcmd1bWVudHMoXG4gICAgICAgICAgICAgIHsgYWJvcnRlZDogdHJ1ZSwgcmVhc29uIH0sXG4gICAgICAgICAgICAgIGN0eC53b3JrZmxvd01ldGFkYXRhLndvcmtmbG93UnVuSWQsXG4gICAgICAgICAgICAgIGN0eC5lbmNyeXB0aW9uS2V5XG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgY29uc3Qgd3JpdGFibGUgPSBuZXcgV29ya2Zsb3dTZXJ2ZXJXcml0YWJsZVN0cmVhbShcbiAgICAgICAgICAgICAgY3R4LndvcmtmbG93TWV0YWRhdGEud29ya2Zsb3dSdW5JZCxcbiAgICAgICAgICAgICAgdmFsdWUuc3RyZWFtTmFtZVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGNvbnN0IHdyaXRlciA9IHdyaXRhYmxlLmdldFdyaXRlcigpO1xuICAgICAgICAgICAgYXdhaXQgd3JpdGVyLndyaXRlKHBheWxvYWQgYXMgVWludDhBcnJheSk7XG4gICAgICAgICAgICBhd2FpdCB3cml0ZXIuY2xvc2UoKTtcbiAgICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICAgIC8vIEJlc3QtZWZmb3J0IHN0cmVhbSB3cml0ZVxuICAgICAgICAgIH1cbiAgICAgICAgfSkoKVxuICAgICAgKTtcblxuICAgICAgaWYgKHZhbHVlLmhvb2tUb2tlbikge1xuICAgICAgICBjdHgub3BzLnB1c2goXG4gICAgICAgICAgKGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgIGNvbnN0IHsgcmVzdW1lSG9vazogcmVzdW1lSG9va0ZuIH0gPSBhd2FpdCBpbXBvcnQoXG4gICAgICAgICAgICAgICAgJy4vcnVudGltZS9yZXN1bWUtaG9vay5qcydcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgYXdhaXQgcmVzdW1lSG9va0ZuKHZhbHVlLmhvb2tUb2tlbiwge1xuICAgICAgICAgICAgICAgIGFib3J0ZWQ6IHRydWUsXG4gICAgICAgICAgICAgICAgcmVhc29uLFxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgICAgICAvLyBCZXN0LWVmZm9ydCBob29rIHJlc3VtZSDigJQgcmV0cnkgb24gbmV4dCByZXBsYXlcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KSgpXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIHJldHVybiBjb250cm9sbGVyO1xufVxuXG4vKipcbiAqIFJldml2ZXMganVzdCBhbiBBYm9ydFNpZ25hbCB3aXRob3V0IHRoZSBwYXRjaGVkIGFib3J0KCkgb3ZlcmhlYWQuXG4gKiBVc2VkIHdoZW4gb25seSBhIHNpZ25hbCAobm90IGEgY29udHJvbGxlcikgd2FzIHNlcmlhbGl6ZWQuXG4gKi9cbmZ1bmN0aW9uIHJldml2ZUFib3J0U2lnbmFsKFxuICB2YWx1ZTogU2VyaWFsaXphYmxlU3BlY2lhbFsnQWJvcnRTaWduYWwnXSxcbiAgb3BzOiBQcm9taXNlPHZvaWQ+W10sXG4gIHJ1bklkOiBzdHJpbmdcbik6IEFib3J0U2lnbmFsIHtcbiAgY29uc3QgY29udHJvbGxlciA9IG5ldyBBYm9ydENvbnRyb2xsZXIoKTtcblxuICBpZiAodmFsdWUuYWJvcnRlZCkge1xuICAgIHRhZ0Fib3J0UGFpcihjb250cm9sbGVyLCB2YWx1ZSk7XG4gICAgY29udHJvbGxlci5hYm9ydCh2YWx1ZS5yZWFzb24pO1xuICB9IGVsc2UgaWYgKHZhbHVlLnN0cmVhbU5hbWUpIHtcbiAgICBjb25zdCByZWFkZXJDYW5jZWwgPSBzZXR1cEFib3J0U3RyZWFtUmVhZGVyKFxuICAgICAgY29udHJvbGxlcixcbiAgICAgIHJ1bklkLFxuICAgICAgdmFsdWUuc3RyZWFtTmFtZSxcbiAgICAgIG9wc1xuICAgICk7XG4gICAgdGFnQWJvcnRQYWlyKGNvbnRyb2xsZXIsIHZhbHVlLCByZWFkZXJDYW5jZWwpO1xuICB9IGVsc2Uge1xuICAgIHRhZ0Fib3J0UGFpcihjb250cm9sbGVyLCB2YWx1ZSk7XG4gIH1cblxuICByZXR1cm4gY29udHJvbGxlci5zaWduYWw7XG59XG5cbi8qKlxuICogQmFzZSByZXZpdmVycyBzaGFyZWQgYWNyb3NzIGFsbCBzZXJpYWxpemF0aW9uIGJvdW5kYXJpZXMuXG4gKiBDb21wb3NlczogY2xhc3MgKyBjb21tb24gcmV2aXZlcnMgZnJvbSB0aGUgbW9kdWxhciBtb2R1bGVzLlxuICpcbiAqIFRoaXMgaXMgZXhwb3J0ZWQgYmVjYXVzZSBzZXJpYWxpemF0aW9uLWZvcm1hdC50cyBhbmQgb3RoZXIgZmlsZXMgcmVmZXJlbmNlIGl0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q29tbW9uUmV2aXZlcnMoZ2xvYmFsOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0gZ2xvYmFsVGhpcykge1xuICByZXR1cm4ge1xuICAgIC4uLmdldENsYXNzUmV2aXZlcnMoZ2xvYmFsKSxcbiAgICAuLi5nZXRDb21tb25SZXZpdmVyc0Zyb21Nb2R1bGUoZ2xvYmFsKSxcbiAgfSBhcyBjb25zdCBzYXRpc2ZpZXMgUGFydGlhbDxSZXZpdmVycz47XG59XG5cbi8qKlxuICogUmV2aXZlcnMgZm9yIGRlc2VyaWFsaXphdGlvbiBib3VuZGFyeSBmcm9tIHRoZSBjbGllbnQgc2lkZSxcbiAqIHJlY2VpdmluZyB0aGUgcmV0dXJuIHZhbHVlIGZyb20gdGhlIHdvcmtmbG93IGhhbmRsZXIuXG4gKlxuICogQHBhcmFtIGdsb2JhbFxuICogQHBhcmFtIG9wc1xuICogQHBhcmFtIHJ1bklkXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRFeHRlcm5hbFJldml2ZXJzKFxuICBnbG9iYWw6IFJlY29yZDxzdHJpbmcsIGFueT4gPSBnbG9iYWxUaGlzLFxuICBvcHM6IFByb21pc2U8dm9pZD5bXSxcbiAgcnVuSWQ6IHN0cmluZyxcbiAgY3J5cHRvS2V5OiBFbmNyeXB0aW9uS2V5UGFyYW1cbik6IFBhcnRpYWw8UmV2aXZlcnM+IHtcbiAgcmV0dXJuIHtcbiAgICAuLi5nZXRDb21tb25SZXZpdmVycyhnbG9iYWwpLFxuXG4gICAgLy8gU3RlcEZ1bmN0aW9uIHNob3VsZCBub3QgYmUgcmV0dXJuZWQgZnJvbSB3b3JrZmxvd3MgdG8gY2xpZW50c1xuICAgIFN0ZXBGdW5jdGlvbjogKCkgPT4ge1xuICAgICAgdGhyb3cgbmV3IFNlcmlhbGl6YXRpb25FcnJvcihcbiAgICAgICAgJ1N0ZXAgZnVuY3Rpb25zIGNhbm5vdCBiZSBkZXNlcmlhbGl6ZWQgaW4gY2xpZW50IGNvbnRleHQuIFN0ZXAgZnVuY3Rpb25zIHNob3VsZCBub3QgYmUgcmV0dXJuZWQgZnJvbSB3b3JrZmxvd3MuJyxcbiAgICAgICAge1xuICAgICAgICAgIGhpbnQ6ICdBIHN0ZXAgZnVuY3Rpb24gcmVmZXJlbmNlIHJlYWNoZWQgdGhlIGNsaWVudC4gUmV0dXJuIGEgc2VyaWFsaXphYmxlIHZhbHVlIChlLmcuIHRoZSBzdGVwIHJlc3VsdCkgaW5zdGVhZCBvZiB0aGUgc3RlcCBpdHNlbGYuJyxcbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9LFxuXG4gICAgV29ya2Zsb3dGdW5jdGlvbjogKHZhbHVlKSA9PlxuICAgICAgT2JqZWN0LmFzc2lnbihcbiAgICAgICAgKCkgPT4ge1xuICAgICAgICAgIHRocm93IG5ldyBTZXJpYWxpemF0aW9uRXJyb3IoXG4gICAgICAgICAgICAnV29ya2Zsb3cgZnVuY3Rpb25zIGNhbm5vdCBiZSBjYWxsZWQgZGlyZWN0bHkuIFVzZSBzdGFydCgpIHRvIGludm9rZSB0aGVtLicsXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGhpbnQ6ICdXcmFwIHRoZSB3b3JrZmxvdyB3aXRoIGBzdGFydCh3b3JrZmxvd0ZuLCB7IC4uLiB9KWAgZnJvbSBgd29ya2Zsb3dgIHRvIGJlZ2luIGEgcnVuIGluc3RlYWQgb2YgaW52b2tpbmcgaXQgbGlrZSBhIG5vcm1hbCBmdW5jdGlvbi4nLFxuICAgICAgICAgICAgfVxuICAgICAgICAgICk7XG4gICAgICAgIH0sXG4gICAgICAgIHsgd29ya2Zsb3dJZDogdmFsdWUud29ya2Zsb3dJZCB9XG4gICAgICApLFxuXG4gICAgUmVxdWVzdDogKHZhbHVlKSA9PiB7XG4gICAgICBjb25zdCBpbml0OiBSZXF1ZXN0SW5pdCAmIHsgZHVwbGV4Pzogc3RyaW5nIH0gPSB7XG4gICAgICAgIG1ldGhvZDogdmFsdWUubWV0aG9kLFxuICAgICAgICBoZWFkZXJzOiBuZXcgZ2xvYmFsLkhlYWRlcnModmFsdWUuaGVhZGVycyksXG4gICAgICAgIGJvZHk6IHZhbHVlLmJvZHksXG4gICAgICAgIGR1cGxleDogdmFsdWUuZHVwbGV4LFxuICAgICAgfTtcbiAgICAgIGlmICh2YWx1ZS5zaWduYWwpIGluaXQuc2lnbmFsID0gdmFsdWUuc2lnbmFsO1xuICAgICAgY29uc3QgcmVxdWVzdCA9IG5ldyBnbG9iYWwuUmVxdWVzdCh2YWx1ZS51cmwsIGluaXQpO1xuICAgICAgLy8gVGhlIFJlcXVlc3QgY29uc3RydWN0b3IgY3JlYXRlcyBhbiBpbnRlcm5hbCBzaWduYWwgY29weSwgc28gdGhlXG4gICAgICAvLyBhYm9ydC1pbnRlcm5hbCBzeW1ib2xzIHNldCBieSByZXZpdmVBYm9ydFNpZ25hbCBkb24ndCBwcm9wYWdhdGUuXG4gICAgICAvLyBSZS10YWcgdGhlIHJlcXVlc3QncyBvd24gc2lnbmFsIHNvIGNhbmNlbEFib3J0UmVhZGVycyBjYW4gZmluZCBpdC5cbiAgICAgIGlmICh2YWx1ZS5zaWduYWwpIGNvcHlBYm9ydEludGVybmFscyh2YWx1ZS5zaWduYWwsIHJlcXVlc3Quc2lnbmFsKTtcbiAgICAgIHJldHVybiByZXF1ZXN0O1xuICAgIH0sXG4gICAgUmVzcG9uc2U6ICh2YWx1ZSkgPT4ge1xuICAgICAgLy8gTm90ZTogUmVzcG9uc2UgY29uc3RydWN0b3Igb25seSBhY2NlcHRzIHN0YXR1cywgc3RhdHVzVGV4dCwgYW5kIGhlYWRlcnNcbiAgICAgIC8vIFRoZSB0eXBlLCB1cmwsIGFuZCByZWRpcmVjdGVkIHByb3BlcnRpZXMgYXJlIHJlYWQtb25seSBhbmQgc2V0IGJ5IHRoZSBjb25zdHJ1Y3RvclxuICAgICAgcmV0dXJuIG5ldyBnbG9iYWwuUmVzcG9uc2UodmFsdWUuYm9keSwge1xuICAgICAgICBzdGF0dXM6IHZhbHVlLnN0YXR1cyxcbiAgICAgICAgc3RhdHVzVGV4dDogdmFsdWUuc3RhdHVzVGV4dCxcbiAgICAgICAgaGVhZGVyczogbmV3IGdsb2JhbC5IZWFkZXJzKHZhbHVlLmhlYWRlcnMpLFxuICAgICAgfSk7XG4gICAgfSxcbiAgICBSZWFkYWJsZVN0cmVhbTogKHZhbHVlKSA9PiB7XG4gICAgICAvLyBJZiB0aGlzIGhhcyBib2R5SW5pdCwgaXQgY2FtZSBmcm9tIGEgUmVzcG9uc2UgY29uc3RydWN0b3JcbiAgICAgIC8vIENvbnZlcnQgaXQgdG8gYSBSRUFMIHN0cmVhbSBub3cgdGhhdCB3ZSdyZSBvdXRzaWRlIHRoZSB3b3JrZmxvd1xuICAgICAgaWYgKCdib2R5SW5pdCcgaW4gdmFsdWUpIHtcbiAgICAgICAgY29uc3QgYm9keUluaXQgPSB2YWx1ZS5ib2R5SW5pdDtcbiAgICAgICAgLy8gVXNlIHRoZSBuYXRpdmUgUmVzcG9uc2UgY29uc3RydWN0b3IgdG8gcHJvcGVybHkgY29udmVydCBCb2R5SW5pdCB0byBSZWFkYWJsZVN0cmVhbVxuICAgICAgICBjb25zdCByZXNwb25zZSA9IG5ldyBnbG9iYWwuUmVzcG9uc2UoYm9keUluaXQpO1xuICAgICAgICByZXR1cm4gcmVzcG9uc2UuYm9keTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgcmVhZGFibGUgPSBuZXcgV29ya2Zsb3dTZXJ2ZXJSZWFkYWJsZVN0cmVhbShcbiAgICAgICAgcnVuSWQsXG4gICAgICAgIHZhbHVlLm5hbWUsXG4gICAgICAgIHZhbHVlLnN0YXJ0SW5kZXhcbiAgICAgICk7XG4gICAgICBpZiAodmFsdWUudHlwZSA9PT0gJ2J5dGVzJykge1xuICAgICAgICAvLyBGb3IgYnl0ZSBzdHJlYW1zLCB1c2UgZmx1c2hhYmxlIHBpcGUgd2l0aCBsb2NrIHBvbGxpbmdcbiAgICAgICAgY29uc3Qgc3RhdGUgPSBjcmVhdGVGbHVzaGFibGVTdGF0ZSgpO1xuICAgICAgICBvcHMucHVzaChzdGF0ZS5wcm9taXNlKTtcblxuICAgICAgICAvLyBDcmVhdGUgYW4gaWRlbnRpdHkgdHJhbnNmb3JtIHRvIGdpdmUgdGhlIHVzZXIgYSByZWFkYWJsZVxuICAgICAgICBjb25zdCB7IHJlYWRhYmxlOiB1c2VyUmVhZGFibGUsIHdyaXRhYmxlIH0gPVxuICAgICAgICAgIG5ldyBnbG9iYWwuVHJhbnNmb3JtU3RyZWFtKCk7XG5cbiAgICAgICAgLy8gU3RhcnQgdGhlIGZsdXNoYWJsZSBwaXBlIGluIHRoZSBiYWNrZ3JvdW5kXG4gICAgICAgIGZsdXNoYWJsZVBpcGUocmVhZGFibGUsIHdyaXRhYmxlLCBzdGF0ZSkuY2F0Y2goKCkgPT4ge1xuICAgICAgICAgIC8vIEVycm9ycyBhcmUgaGFuZGxlZCB2aWEgc3RhdGUucmVqZWN0XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFN0YXJ0IHBvbGxpbmcgdG8gZGV0ZWN0IHdoZW4gdXNlciByZWxlYXNlcyBsb2NrXG4gICAgICAgIHBvbGxSZWFkYWJsZUxvY2sodXNlclJlYWRhYmxlLCBzdGF0ZSk7XG5cbiAgICAgICAgcmV0dXJuIHVzZXJSZWFkYWJsZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IHRyYW5zZm9ybSA9IGdldERlc2VyaWFsaXplU3RyZWFtKFxuICAgICAgICAgIGdldEV4dGVybmFsUmV2aXZlcnMoZ2xvYmFsLCBvcHMsIHJ1bklkLCBjcnlwdG9LZXkpLFxuICAgICAgICAgIGNyeXB0b0tleVxuICAgICAgICApO1xuICAgICAgICBjb25zdCBzdGF0ZSA9IGNyZWF0ZUZsdXNoYWJsZVN0YXRlKCk7XG4gICAgICAgIG9wcy5wdXNoKHN0YXRlLnByb21pc2UpO1xuXG4gICAgICAgIC8vIFN0YXJ0IHRoZSBmbHVzaGFibGUgcGlwZSBpbiB0aGUgYmFja2dyb3VuZFxuICAgICAgICBmbHVzaGFibGVQaXBlKHJlYWRhYmxlLCB0cmFuc2Zvcm0ud3JpdGFibGUsIHN0YXRlKS5jYXRjaCgoKSA9PiB7XG4gICAgICAgICAgLy8gRXJyb3JzIGFyZSBoYW5kbGVkIHZpYSBzdGF0ZS5yZWplY3RcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gU3RhcnQgcG9sbGluZyB0byBkZXRlY3Qgd2hlbiB1c2VyIHJlbGVhc2VzIGxvY2tcbiAgICAgICAgcG9sbFJlYWRhYmxlTG9jayh0cmFuc2Zvcm0ucmVhZGFibGUsIHN0YXRlKTtcblxuICAgICAgICByZXR1cm4gdHJhbnNmb3JtLnJlYWRhYmxlO1xuICAgICAgfVxuICAgIH0sXG4gICAgV3JpdGFibGVTdHJlYW06ICh2YWx1ZSkgPT4ge1xuICAgICAgY29uc3Qgc2VyaWFsaXplID0gZ2V0U2VyaWFsaXplU3RyZWFtKFxuICAgICAgICBnZXRFeHRlcm5hbFJlZHVjZXJzKGdsb2JhbCwgb3BzLCBydW5JZCwgY3J5cHRvS2V5KSxcbiAgICAgICAgY3J5cHRvS2V5XG4gICAgICApO1xuICAgICAgY29uc3Qgc2VydmVyV3JpdGFibGUgPSBuZXcgV29ya2Zsb3dTZXJ2ZXJXcml0YWJsZVN0cmVhbShcbiAgICAgICAgcnVuSWQsXG4gICAgICAgIHZhbHVlLm5hbWVcbiAgICAgICk7XG5cbiAgICAgIC8vIENyZWF0ZSBmbHVzaGFibGUgc3RhdGUgZm9yIHRoaXMgc3RyZWFtXG4gICAgICBjb25zdCBzdGF0ZSA9IGNyZWF0ZUZsdXNoYWJsZVN0YXRlKCk7XG4gICAgICBvcHMucHVzaChzdGF0ZS5wcm9taXNlKTtcblxuICAgICAgLy8gU3RhcnQgdGhlIGZsdXNoYWJsZSBwaXBlIGluIHRoZSBiYWNrZ3JvdW5kXG4gICAgICBmbHVzaGFibGVQaXBlKHNlcmlhbGl6ZS5yZWFkYWJsZSwgc2VydmVyV3JpdGFibGUsIHN0YXRlKS5jYXRjaCgoKSA9PiB7XG4gICAgICAgIC8vIEVycm9ycyBhcmUgaGFuZGxlZCB2aWEgc3RhdGUucmVqZWN0XG4gICAgICB9KTtcblxuICAgICAgLy8gU3RhcnQgcG9sbGluZyB0byBkZXRlY3Qgd2hlbiB1c2VyIHJlbGVhc2VzIGxvY2tcbiAgICAgIHBvbGxXcml0YWJsZUxvY2soc2VyaWFsaXplLndyaXRhYmxlLCBzdGF0ZSk7XG5cbiAgICAgIHJldHVybiBzZXJpYWxpemUud3JpdGFibGU7XG4gICAgfSxcblxuICAgIEFib3J0Q29udHJvbGxlcjogKHZhbHVlKSA9PiByZXZpdmVBYm9ydENvbnRyb2xsZXIodmFsdWUsIG9wcywgcnVuSWQpLFxuICAgIEFib3J0U2lnbmFsOiAodmFsdWUpID0+IHJldml2ZUFib3J0U2lnbmFsKHZhbHVlLCBvcHMsIHJ1bklkKSxcbiAgfTtcbn1cblxuLyoqXG4gKiBSZXZpdmVycyBmb3IgZGVzZXJpYWxpemF0aW9uIGJvdW5kYXJ5IGZyb20gd2l0aGluIHRoZSB3b3JrZmxvdyBleGVjdXRpb25cbiAqIGVudmlyb25tZW50LCByZWNlaXZpbmcgYXJndW1lbnRzIGZyb20gdGhlIGNsaWVudCBzaWRlLCBhbmQgcmV0dXJuIHZhbHVlc1xuICogZnJvbSB0aGUgc3RlcHMuXG4gKlxuICogQHBhcmFtIGdsb2JhbFxuICogQHJldHVybnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFdvcmtmbG93UmV2aXZlcnMoXG4gIGdsb2JhbDogUmVjb3JkPHN0cmluZywgYW55PiA9IGdsb2JhbFRoaXNcbik6IFBhcnRpYWw8UmV2aXZlcnM+IHtcbiAgcmV0dXJuIHtcbiAgICAuLi5nZXRDb21tb25SZXZpdmVycyhnbG9iYWwpLFxuICAgIC8vIFN0ZXBGdW5jdGlvbiByZXZpdmVyIGZvciB3b3JrZmxvdyBjb250ZXh0IC0gdXNlcyB0aGUgbW9kdWxhciByZXZpdmVyXG4gICAgLy8gd2hpY2ggY2FsbHMgV09SS0ZMT1dfVVNFX1NURVAgZnJvbSBnbG9iYWwgdG8gcmVjb25zdHJ1Y3Qgc3RlcCBwcm94aWVzXG4gICAgLi4uZ2V0U3RlcEZ1bmN0aW9uUmV2aXZlcihnbG9iYWwpLFxuICAgIFJlcXVlc3Q6ICh2YWx1ZSkgPT4ge1xuICAgICAgT2JqZWN0LnNldFByb3RvdHlwZU9mKHZhbHVlLCBnbG9iYWwuUmVxdWVzdC5wcm90b3R5cGUpO1xuICAgICAgY29uc3QgcmVzcG9uc2VXcml0YWJsZSA9IHZhbHVlLnJlc3BvbnNlV3JpdGFibGU7XG4gICAgICBpZiAocmVzcG9uc2VXcml0YWJsZSkge1xuICAgICAgICAodmFsdWUgYXMgYW55KVtXRUJIT09LX1JFU1BPTlNFX1dSSVRBQkxFXSA9IHJlc3BvbnNlV3JpdGFibGU7XG4gICAgICAgIGRlbGV0ZSB2YWx1ZS5yZXNwb25zZVdyaXRhYmxlO1xuICAgICAgICAodmFsdWUgYXMgYW55KS5yZXNwb25kV2l0aCA9ICgpID0+IHtcbiAgICAgICAgICB0aHJvdyBuZXcgU2VyaWFsaXphdGlvbkVycm9yKFxuICAgICAgICAgICAgJ2ByZXNwb25kV2l0aCgpYCBtdXN0IGJlIGNhbGxlZCBmcm9tIHdpdGhpbiBhIHN0ZXAgZnVuY3Rpb24uJyxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaGludDogJ01vdmUgdGhlIGByZXNwb25kV2l0aCguLi4pYCBjYWxsIGluc2lkZSBhIGBcInVzZSBzdGVwXCJgIGZ1bmN0aW9uIOKAlCBpdCBjYW5ub3QgYmUgaW52b2tlZCBmcm9tIGEgd29ya2Zsb3cgY29udGV4dC4nLFxuICAgICAgICAgICAgfVxuICAgICAgICAgICk7XG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfSxcbiAgICAvLyBXb3JrZmxvdyBmdW5jdGlvbiByZXZpdmVyIGZvciB3b3JrZmxvdyBjb250ZXh0IOKAlCByZXR1cm5zIGEgZnVuY3Rpb24tbGlrZVxuICAgIC8vIG9iamVjdCB3aXRoIC53b3JrZmxvd0lkIHRoYXQgbWltaWNzIHdoYXQgdGhlIFNXQyBjb21waWxlciBwcm9kdWNlcyxcbiAgICBXb3JrZmxvd0Z1bmN0aW9uOiAodmFsdWUpID0+XG4gICAgICBPYmplY3QuYXNzaWduKFxuICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgdGhyb3cgbmV3IFNlcmlhbGl6YXRpb25FcnJvcihcbiAgICAgICAgICAgICdXb3JrZmxvdyBmdW5jdGlvbnMgY2Fubm90IGJlIGNhbGxlZCBkaXJlY3RseS4gVXNlIHN0YXJ0KCkgdG8gaW52b2tlIHRoZW0uJyxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaGludDogJ1dyYXAgdGhlIHdvcmtmbG93IHdpdGggYHN0YXJ0KHdvcmtmbG93Rm4sIHsgLi4uIH0pYCBmcm9tIGB3b3JrZmxvd2AgdG8gYmVnaW4gYSBydW4gaW5zdGVhZCBvZiBpbnZva2luZyBpdCBsaWtlIGEgbm9ybWFsIGZ1bmN0aW9uLicsXG4gICAgICAgICAgICB9XG4gICAgICAgICAgKTtcbiAgICAgICAgfSxcbiAgICAgICAgeyB3b3JrZmxvd0lkOiB2YWx1ZS53b3JrZmxvd0lkIH1cbiAgICAgICksXG4gICAgUmVzcG9uc2U6ICh2YWx1ZSkgPT4ge1xuICAgICAgT2JqZWN0LnNldFByb3RvdHlwZU9mKHZhbHVlLCBnbG9iYWwuUmVzcG9uc2UucHJvdG90eXBlKTtcbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9LFxuICAgIFJlYWRhYmxlU3RyZWFtOiAodmFsdWUpID0+IHtcbiAgICAgIC8vIENoZWNrIGlmIHRoaXMgaXMgYSBCb2R5SW5pdCB0aGF0IHNob3VsZCBiZSB3cmFwcGVkIGluIGEgZmFrZSBzdHJlYW1cbiAgICAgIGlmICgnYm9keUluaXQnIGluIHZhbHVlKSB7XG4gICAgICAgIC8vIFJlY3JlYXRlIHRoZSBmYWtlIHN0cmVhbSB3aXRoIHRoZSBCb2R5SW5pdFxuICAgICAgICByZXR1cm4gT2JqZWN0LmNyZWF0ZShnbG9iYWwuUmVhZGFibGVTdHJlYW0ucHJvdG90eXBlLCB7XG4gICAgICAgICAgW0JPRFlfSU5JVF9TWU1CT0xdOiB7XG4gICAgICAgICAgICB2YWx1ZTogdmFsdWUuYm9keUluaXQsXG4gICAgICAgICAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIC8vIFJlZ3VsYXIgc3RyZWFtIGhhbmRsaW5nXG4gICAgICByZXR1cm4gT2JqZWN0LmNyZWF0ZShnbG9iYWwuUmVhZGFibGVTdHJlYW0ucHJvdG90eXBlLCB7XG4gICAgICAgIFtTVFJFQU1fTkFNRV9TWU1CT0xdOiB7XG4gICAgICAgICAgdmFsdWU6IHZhbHVlLm5hbWUsXG4gICAgICAgICAgd3JpdGFibGU6IGZhbHNlLFxuICAgICAgICB9LFxuICAgICAgICBbU1RSRUFNX1RZUEVfU1lNQk9MXToge1xuICAgICAgICAgIHZhbHVlOiB2YWx1ZS50eXBlLFxuICAgICAgICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH0sXG4gICAgV3JpdGFibGVTdHJlYW06ICh2YWx1ZSkgPT4ge1xuICAgICAgcmV0dXJuIE9iamVjdC5jcmVhdGUoZ2xvYmFsLldyaXRhYmxlU3RyZWFtLnByb3RvdHlwZSwge1xuICAgICAgICBbU1RSRUFNX05BTUVfU1lNQk9MXToge1xuICAgICAgICAgIHZhbHVlOiB2YWx1ZS5uYW1lLFxuICAgICAgICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH0sXG5cbiAgICAvLyBBYm9ydENvbnRyb2xsZXIvQWJvcnRTaWduYWwgcmV2aXZlZCBpbnNpZGUgdGhlIHdvcmtmbG93IFZNLiBVc2UgdGhlXG4gICAgLy8gcmVhbCBXb3JrZmxvd0Fib3J0U2lnbmFsIGNsYXNzIHNvIGFkZEV2ZW50TGlzdGVuZXIoJ2Fib3J0JywgZm4pIGFjdHVhbGx5XG4gICAgLy8gZmlyZXMgd2hlbiB0aGUgc2lnbmFsIGFib3J0cyAodGhlIHByZXZpb3VzIG5vLW9wIHN0dWIgc2lsZW50bHkgZHJvcHBlZFxuICAgIC8vIGxpc3RlbmVyIHJlZ2lzdHJhdGlvbnMg4oCUIHNpbGVudCBjb3JyZWN0bmVzcyBidWcgZm9yIG5hdHVyYWwgcGF0dGVybnNcbiAgICAvLyBsaWtlIGBzaWduYWwuYWRkRXZlbnRMaXN0ZW5lcignYWJvcnQnLCBmbilgIGFmdGVyIHJlY2VpdmluZyBhIGRlc2VyaWFsaXplZFxuICAgIC8vIHNpZ25hbCkuIFRoZSBzaWduYWwgZG9lcyBub3Qgb3duIGEgaG9vayBzdWJzY3JpcHRpb24gaGVyZSDigJQgYWJvcnQgc3RhdGVcbiAgICAvLyBpcyBkZWxpdmVyZWQgdmlhIHRoZSBleGlzdGluZyByZXBsYXkgbWFjaGluZXJ5IG9uIHRoZSBzb3VyY2Ugc2lkZS5cbiAgICBBYm9ydENvbnRyb2xsZXI6ICh2YWx1ZSkgPT4ge1xuICAgICAgY29uc3Qgc2lnbmFsID0gbmV3IFdvcmtmbG93QWJvcnRTaWduYWwodmFsdWUuc3RyZWFtTmFtZSwgdmFsdWUuaG9va1Rva2VuKTtcbiAgICAgIGlmICh2YWx1ZS5hYm9ydGVkKSBzaWduYWwuX3NldEFib3J0ZWQodmFsdWUucmVhc29uKTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIFtBQk9SVF9TVFJFQU1fTkFNRV06IHZhbHVlLnN0cmVhbU5hbWUsXG4gICAgICAgIFtBQk9SVF9IT09LX1RPS0VOXTogdmFsdWUuaG9va1Rva2VuLFxuICAgICAgICBzaWduYWwsXG4gICAgICAgIGFib3J0OiAoKSA9PiB7fSxcbiAgICAgIH07XG4gICAgfSxcbiAgICBBYm9ydFNpZ25hbDogKHZhbHVlKSA9PiB7XG4gICAgICBjb25zdCBzaWduYWwgPSBuZXcgV29ya2Zsb3dBYm9ydFNpZ25hbCh2YWx1ZS5zdHJlYW1OYW1lLCB2YWx1ZS5ob29rVG9rZW4pO1xuICAgICAgaWYgKHZhbHVlLmFib3J0ZWQpIHNpZ25hbC5fc2V0QWJvcnRlZCh2YWx1ZS5yZWFzb24pO1xuICAgICAgcmV0dXJuIHNpZ25hbDtcbiAgICB9LFxuICB9O1xufVxuXG4vKipcbiAqIFJldml2ZXJzIGZvciBkZXNlcmlhbGl6YXRpb24gYm91bmRhcnkgZnJvbSB3aXRoaW4gdGhlIHN0ZXAgZXhlY3V0aW9uXG4gKiBlbnZpcm9ubWVudCwgcmVjZWl2aW5nIGFyZ3VtZW50cyBmcm9tIHRoZSB3b3JrZmxvdyBoYW5kbGVyLlxuICpcbiAqIEBwYXJhbSBnbG9iYWxcbiAqIEBwYXJhbSBvcHNcbiAqIEBwYXJhbSBydW5JZFxuICogQHJldHVybnNcbiAqL1xuZnVuY3Rpb24gZ2V0U3RlcFJldml2ZXJzKFxuICBnbG9iYWw6IFJlY29yZDxzdHJpbmcsIGFueT4gPSBnbG9iYWxUaGlzLFxuICBvcHM6IFByb21pc2U8dm9pZD5bXSxcbiAgcnVuSWQ6IHN0cmluZyxcbiAgY3J5cHRvS2V5OiBFbmNyeXB0aW9uS2V5UGFyYW1cbik6IFBhcnRpYWw8UmV2aXZlcnM+IHtcbiAgcmV0dXJuIHtcbiAgICAuLi5nZXRDb21tb25SZXZpdmVycyhnbG9iYWwpLFxuXG4gICAgLy8gU3RlcEZ1bmN0aW9uIHJldml2ZXIgZm9yIHN0ZXAgY29udGV4dCAtIHJldHVybnMgcmF3IHN0ZXAgZnVuY3Rpb25cbiAgICAvLyB3aXRoIGNsb3N1cmUgdmFyaWFibGUgc3VwcG9ydCB2aWEgQXN5bmNMb2NhbFN0b3JhZ2UuXG4gICAgLy9cbiAgICAvLyBIYW5kbGVzIGZvdXIgaW5kZXBlbmRlbnQgZmxhZ3MgZnJvbSB0aGUgc2VyaWFsaXplZCBwYXlsb2FkOlxuICAgIC8vICAgLSBgY2xvc3VyZVZhcnNgOiBpbnZva2UgdGhlIGJvZHkgaW5zaWRlIGFuIEFzeW5jTG9jYWxTdG9yYWdlIGZyYW1lXG4gICAgLy8gICAgIHNvIHRoZSBTV0MtZW1pdHRlZCBgV09SS0ZMT1dfU1RFUF9DT05URVhUX1NUT1JBR0VgIElJRkUgaW4gdGhlXG4gICAgLy8gICAgIGhvaXN0ZWQgYm9keSBjYW4gcHVsbCB0aGUgY2xvc3VyZSB2YXJpYWJsZXMgYmFjayBvdXQuXG4gICAgLy8gICAtIGBib3VuZFRoaXNgOiAgIGEgYHRoaXNgIHZhbHVlIGNhcHR1cmVkIGJ5XG4gICAgLy8gICAgIGB1c2VTdGVwKC4uLikuYmluZCh0aGlzKWAgaW4gdGhlIHdvcmtmbG93IGJ1bmRsZSAobGV4aWNhbC1gdGhpc2BcbiAgICAvLyAgICAgYXJyb3cgc3RlcHMpLiBUaGUgd3JhcHBlciBpbnZva2VzIHRoZSBib2R5IHZpYVxuICAgIC8vICAgICBgc3RlcEZuLmFwcGx5KGJvdW5kVGhpcywgYXJncylgIHNvIHRoZSBib2R5IHNlZXMgdGhlIHNhbWVcbiAgICAvLyAgICAgYHRoaXNgIGl0IHdvdWxkIGhhdmUgaGFkIGluIHRoZSB3b3JrZmxvdyBidW5kbGUuIFByb3BlcnR5XG4gICAgLy8gICAgIHByZXNlbmNlIOKAlCBub3QgdHJ1dGhpbmVzcyDigJQgaXMgc2lnbmlmaWNhbnQgYmVjYXVzZVxuICAgIC8vICAgICBgYmluZChudWxsKWAgYW5kIGBiaW5kKHVuZGVmaW5lZClgIGFyZSBib3RoIGxlZ2FsIGFuZCBzaG91bGRcbiAgICAvLyAgICAgcm91bmQtdHJpcCBmYWl0aGZ1bGx5LlxuICAgIC8vICAgLSBgYm91bmRBcmdzYDogICBwcmVmaWxsZWQgYXJncyBmcm9tXG4gICAgLy8gICAgIGB1c2VTdGVwKC4uLikuYmluZCh0aGlzQXJnLCB4LCB5KWAuIFByZXBlbmRlZCB0byB0aGUgY2FsbCBhcmdzXG4gICAgLy8gICAgIHNvIHBhcnRpYWwgYXBwbGljYXRpb24gc3Vydml2ZXMgc2VyaWFsaXphdGlvbi5cbiAgICBTdGVwRnVuY3Rpb246ICh2YWx1ZSkgPT4ge1xuICAgICAgY29uc3Qgc3RlcElkID0gdmFsdWUuc3RlcElkO1xuICAgICAgY29uc3QgY2xvc3VyZVZhcnMgPSB2YWx1ZS5jbG9zdXJlVmFycztcbiAgICAgIGNvbnN0IGhhc0JvdW5kVGhpcyA9ICdib3VuZFRoaXMnIGluIHZhbHVlO1xuICAgICAgY29uc3QgYm91bmRUaGlzID0gaGFzQm91bmRUaGlzID8gdmFsdWUuYm91bmRUaGlzIDogdW5kZWZpbmVkO1xuICAgICAgY29uc3QgYm91bmRBcmdzID0gQXJyYXkuaXNBcnJheSh2YWx1ZS5ib3VuZEFyZ3MpID8gdmFsdWUuYm91bmRBcmdzIDogW107XG5cbiAgICAgIGNvbnN0IHN0ZXBGbiA9IGdldFN0ZXBGdW5jdGlvbihzdGVwSWQpO1xuICAgICAgaWYgKCFzdGVwRm4pIHtcbiAgICAgICAgdGhyb3cgbmV3IFNlcmlhbGl6YXRpb25FcnJvcihcbiAgICAgICAgICBgU3RlcCBmdW5jdGlvbiBcIiR7c3RlcElkfVwiIG5vdCBmb3VuZC4gTWFrZSBzdXJlIHRoZSBzdGVwIGZ1bmN0aW9uIGlzIHJlZ2lzdGVyZWQuYCxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBoaW50OiAnTWFrZSBzdXJlIHRoZSBzdGVwIGZpbGUgaXMgaW5jbHVkZWQgaW4geW91ciBidWlsZCAoaS5lLiBpdCBpcyBsaXN0ZWQgaW4gdGhlIHdvcmtmbG93IG1hbmlmZXN0KSwgYW5kIHRoYXQgdGhlIFNXQyBwbHVnaW4gaXMgY29uZmlndXJlZCBmb3IgdGhlIGZpbGUuJyxcbiAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIC8vIEZhc3QgcGF0aDogbm90aGluZyB0byB3cmFwLlxuICAgICAgaWYgKCFjbG9zdXJlVmFycyAmJiAhaGFzQm91bmRUaGlzICYmIGJvdW5kQXJncy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgcmV0dXJuIHN0ZXBGbjtcbiAgICAgIH1cblxuICAgICAgY29uc3Qgd3JhcHBlZFN0ZXBGbiA9IGZ1bmN0aW9uICh0aGlzOiB1bmtub3duLCAuLi5hcmdzOiBhbnlbXSkge1xuICAgICAgICBjb25zdCBjYWxsVGhpcyA9IGhhc0JvdW5kVGhpcyA/IGJvdW5kVGhpcyA6IHRoaXM7XG4gICAgICAgIGNvbnN0IGNhbGxBcmdzID0gYm91bmRBcmdzLmxlbmd0aCA+IDAgPyBbLi4uYm91bmRBcmdzLCAuLi5hcmdzXSA6IGFyZ3M7XG4gICAgICAgIGlmIChjbG9zdXJlVmFycykge1xuICAgICAgICAgIGNvbnN0IGN1cnJlbnRDb250ZXh0ID0gY29udGV4dFN0b3JhZ2UuZ2V0U3RvcmUoKTtcbiAgICAgICAgICBpZiAoIWN1cnJlbnRDb250ZXh0KSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgV29ya2Zsb3dSdW50aW1lRXJyb3IoXG4gICAgICAgICAgICAgICdDYW5ub3QgY2FsbCBzdGVwIGZ1bmN0aW9uIHdpdGggY2xvc3VyZSB2YXJpYWJsZXMgb3V0c2lkZSBzdGVwIGNvbnRleHQnXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zdCBuZXdDb250ZXh0ID0ge1xuICAgICAgICAgICAgLi4uY3VycmVudENvbnRleHQsXG4gICAgICAgICAgICBjbG9zdXJlVmFycyxcbiAgICAgICAgICB9O1xuICAgICAgICAgIHJldHVybiBjb250ZXh0U3RvcmFnZS5ydW4obmV3Q29udGV4dCwgKCkgPT5cbiAgICAgICAgICAgIHN0ZXBGbi5hcHBseShjYWxsVGhpcywgY2FsbEFyZ3MpXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc3RlcEZuLmFwcGx5KGNhbGxUaGlzLCBjYWxsQXJncyk7XG4gICAgICB9IGFzIGFueTtcblxuICAgICAgLy8gQ29weSBwcm9wZXJ0aWVzIGZyb20gb3JpZ2luYWwgc3RlcCBmdW5jdGlvblxuICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHdyYXBwZWRTdGVwRm4sICduYW1lJywge1xuICAgICAgICB2YWx1ZTogc3RlcEZuLm5hbWUsXG4gICAgICB9KTtcbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh3cmFwcGVkU3RlcEZuLCAnc3RlcElkJywge1xuICAgICAgICB2YWx1ZTogc3RlcElkLFxuICAgICAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgICBjb25maWd1cmFibGU6IGZhbHNlLFxuICAgICAgfSk7XG4gICAgICBpZiAoc3RlcEZuLm1heFJldHJpZXMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICB3cmFwcGVkU3RlcEZuLm1heFJldHJpZXMgPSBzdGVwRm4ubWF4UmV0cmllcztcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHdyYXBwZWRTdGVwRm47XG4gICAgfSxcblxuICAgIFdvcmtmbG93RnVuY3Rpb246ICh2YWx1ZSkgPT5cbiAgICAgIE9iamVjdC5hc3NpZ24oXG4gICAgICAgICgpID0+IHtcbiAgICAgICAgICB0aHJvdyBuZXcgU2VyaWFsaXphdGlvbkVycm9yKFxuICAgICAgICAgICAgJ1dvcmtmbG93IGZ1bmN0aW9ucyBjYW5ub3QgYmUgY2FsbGVkIGRpcmVjdGx5LiBVc2Ugc3RhcnQoKSB0byBpbnZva2UgdGhlbS4nLFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBoaW50OiAnV3JhcCB0aGUgd29ya2Zsb3cgd2l0aCBgc3RhcnQod29ya2Zsb3dGbiwgeyAuLi4gfSlgIGZyb20gYHdvcmtmbG93YCB0byBiZWdpbiBhIHJ1biBpbnN0ZWFkIG9mIGludm9raW5nIGl0IGxpa2UgYSBub3JtYWwgZnVuY3Rpb24uJyxcbiAgICAgICAgICAgIH1cbiAgICAgICAgICApO1xuICAgICAgICB9LFxuICAgICAgICB7IHdvcmtmbG93SWQ6IHZhbHVlLndvcmtmbG93SWQgfVxuICAgICAgKSxcblxuICAgIFJlcXVlc3Q6ICh2YWx1ZSkgPT4ge1xuICAgICAgY29uc3QgcmVzcG9uc2VXcml0YWJsZSA9IHZhbHVlLnJlc3BvbnNlV3JpdGFibGU7XG4gICAgICBjb25zdCBpbml0OiBSZXF1ZXN0SW5pdCAmIHsgZHVwbGV4Pzogc3RyaW5nIH0gPSB7XG4gICAgICAgIG1ldGhvZDogdmFsdWUubWV0aG9kLFxuICAgICAgICBoZWFkZXJzOiBuZXcgZ2xvYmFsLkhlYWRlcnModmFsdWUuaGVhZGVycyksXG4gICAgICAgIGJvZHk6IHZhbHVlLmJvZHksXG4gICAgICAgIGR1cGxleDogdmFsdWUuZHVwbGV4LFxuICAgICAgfTtcbiAgICAgIGlmICh2YWx1ZS5zaWduYWwpIGluaXQuc2lnbmFsID0gdmFsdWUuc2lnbmFsO1xuICAgICAgY29uc3QgcmVxdWVzdCA9IG5ldyBnbG9iYWwuUmVxdWVzdCh2YWx1ZS51cmwsIGluaXQpO1xuICAgICAgLy8gVGhlIFJlcXVlc3QgY29uc3RydWN0b3IgY3JlYXRlcyBhbiBpbnRlcm5hbCBzaWduYWwgY29weSwgc28gdGhlXG4gICAgICAvLyBhYm9ydC1pbnRlcm5hbCBzeW1ib2xzIHNldCBieSByZXZpdmVBYm9ydFNpZ25hbCBkb24ndCBwcm9wYWdhdGUuXG4gICAgICAvLyBSZS10YWcgdGhlIHJlcXVlc3QncyBvd24gc2lnbmFsIHNvIGNhbmNlbEFib3J0UmVhZGVycyBjYW4gZmluZCBpdC5cbiAgICAgIGlmICh2YWx1ZS5zaWduYWwpIGNvcHlBYm9ydEludGVybmFscyh2YWx1ZS5zaWduYWwsIHJlcXVlc3Quc2lnbmFsKTtcbiAgICAgIGlmIChyZXNwb25zZVdyaXRhYmxlKSB7XG4gICAgICAgIHJlcXVlc3QucmVzcG9uZFdpdGggPSBhc3luYyAocmVzcG9uc2U6IFJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgY29uc3Qgd3JpdGVyID0gcmVzcG9uc2VXcml0YWJsZS5nZXRXcml0ZXIoKTtcbiAgICAgICAgICBhd2FpdCB3cml0ZXIud3JpdGUocmVzcG9uc2UpO1xuICAgICAgICAgIGF3YWl0IHdyaXRlci5jbG9zZSgpO1xuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlcXVlc3Q7XG4gICAgfSxcbiAgICBSZXNwb25zZTogKHZhbHVlKSA9PiB7XG4gICAgICAvLyBOb3RlOiBSZXNwb25zZSBjb25zdHJ1Y3RvciBvbmx5IGFjY2VwdHMgc3RhdHVzLCBzdGF0dXNUZXh0LCBhbmQgaGVhZGVyc1xuICAgICAgLy8gVGhlIHR5cGUsIHVybCwgYW5kIHJlZGlyZWN0ZWQgcHJvcGVydGllcyBhcmUgcmVhZC1vbmx5IGFuZCBzZXQgYnkgdGhlIGNvbnN0cnVjdG9yXG4gICAgICByZXR1cm4gbmV3IGdsb2JhbC5SZXNwb25zZSh2YWx1ZS5ib2R5LCB7XG4gICAgICAgIHN0YXR1czogdmFsdWUuc3RhdHVzLFxuICAgICAgICBzdGF0dXNUZXh0OiB2YWx1ZS5zdGF0dXNUZXh0LFxuICAgICAgICBoZWFkZXJzOiBuZXcgZ2xvYmFsLkhlYWRlcnModmFsdWUuaGVhZGVycyksXG4gICAgICB9KTtcbiAgICB9LFxuICAgIFJlYWRhYmxlU3RyZWFtOiAodmFsdWUpID0+IHtcbiAgICAgIC8vIElmIHRoaXMgaGFzIGJvZHlJbml0LCBpdCBjYW1lIGZyb20gYSBSZXNwb25zZSBjb25zdHJ1Y3RvclxuICAgICAgLy8gQ29udmVydCBpdCB0byBhIFJFQUwgc3RyZWFtIG5vdyB0aGF0IHdlJ3JlIGluIHRoZSBzdGVwIGVudmlyb25tZW50XG4gICAgICBpZiAoJ2JvZHlJbml0JyBpbiB2YWx1ZSkge1xuICAgICAgICBjb25zdCBib2R5SW5pdCA9IHZhbHVlLmJvZHlJbml0O1xuICAgICAgICAvLyBVc2UgdGhlIG5hdGl2ZSBSZXNwb25zZSBjb25zdHJ1Y3RvciB0byBwcm9wZXJseSBjb252ZXJ0IEJvZHlJbml0IHRvIFJlYWRhYmxlU3RyZWFtXG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gbmV3IGdsb2JhbC5SZXNwb25zZShib2R5SW5pdCk7XG4gICAgICAgIHJldHVybiByZXNwb25zZS5ib2R5O1xuICAgICAgfVxuXG4gICAgICBjb25zdCByZWFkYWJsZSA9IG5ldyBXb3JrZmxvd1NlcnZlclJlYWRhYmxlU3RyZWFtKHJ1bklkLCB2YWx1ZS5uYW1lKTtcbiAgICAgIGlmICh2YWx1ZS50eXBlID09PSAnYnl0ZXMnKSB7XG4gICAgICAgIC8vIEZvciBieXRlIHN0cmVhbXMsIHVzZSBmbHVzaGFibGUgcGlwZSB3aXRoIGxvY2sgcG9sbGluZ1xuICAgICAgICBjb25zdCBzdGF0ZSA9IGNyZWF0ZUZsdXNoYWJsZVN0YXRlKCk7XG4gICAgICAgIG9wcy5wdXNoKHN0YXRlLnByb21pc2UpO1xuXG4gICAgICAgIC8vIENyZWF0ZSBhbiBpZGVudGl0eSB0cmFuc2Zvcm0gdG8gZ2l2ZSB0aGUgdXNlciBhIHJlYWRhYmxlXG4gICAgICAgIGNvbnN0IHsgcmVhZGFibGU6IHVzZXJSZWFkYWJsZSwgd3JpdGFibGUgfSA9XG4gICAgICAgICAgbmV3IGdsb2JhbC5UcmFuc2Zvcm1TdHJlYW0oKTtcblxuICAgICAgICAvLyBTdGFydCB0aGUgZmx1c2hhYmxlIHBpcGUgaW4gdGhlIGJhY2tncm91bmRcbiAgICAgICAgZmx1c2hhYmxlUGlwZShyZWFkYWJsZSwgd3JpdGFibGUsIHN0YXRlKS5jYXRjaCgoKSA9PiB7XG4gICAgICAgICAgLy8gRXJyb3JzIGFyZSBoYW5kbGVkIHZpYSBzdGF0ZS5yZWplY3RcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gU3RhcnQgcG9sbGluZyB0byBkZXRlY3Qgd2hlbiB1c2VyIHJlbGVhc2VzIGxvY2tcbiAgICAgICAgcG9sbFJlYWRhYmxlTG9jayh1c2VyUmVhZGFibGUsIHN0YXRlKTtcblxuICAgICAgICByZXR1cm4gdXNlclJlYWRhYmxlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgdHJhbnNmb3JtID0gZ2V0RGVzZXJpYWxpemVTdHJlYW0oXG4gICAgICAgICAgZ2V0U3RlcFJldml2ZXJzKGdsb2JhbCwgb3BzLCBydW5JZCwgY3J5cHRvS2V5KSxcbiAgICAgICAgICBjcnlwdG9LZXlcbiAgICAgICAgKTtcbiAgICAgICAgY29uc3Qgc3RhdGUgPSBjcmVhdGVGbHVzaGFibGVTdGF0ZSgpO1xuICAgICAgICBvcHMucHVzaChzdGF0ZS5wcm9taXNlKTtcblxuICAgICAgICAvLyBTdGFydCB0aGUgZmx1c2hhYmxlIHBpcGUgaW4gdGhlIGJhY2tncm91bmRcbiAgICAgICAgZmx1c2hhYmxlUGlwZShyZWFkYWJsZSwgdHJhbnNmb3JtLndyaXRhYmxlLCBzdGF0ZSkuY2F0Y2goKCkgPT4ge1xuICAgICAgICAgIC8vIEVycm9ycyBhcmUgaGFuZGxlZCB2aWEgc3RhdGUucmVqZWN0XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFN0YXJ0IHBvbGxpbmcgdG8gZGV0ZWN0IHdoZW4gdXNlciByZWxlYXNlcyBsb2NrXG4gICAgICAgIHBvbGxSZWFkYWJsZUxvY2sodHJhbnNmb3JtLnJlYWRhYmxlLCBzdGF0ZSk7XG5cbiAgICAgICAgcmV0dXJuIHRyYW5zZm9ybS5yZWFkYWJsZTtcbiAgICAgIH1cbiAgICB9LFxuICAgIFdyaXRhYmxlU3RyZWFtOiAodmFsdWUpID0+IHtcbiAgICAgIGNvbnN0IHNlcmlhbGl6ZSA9IGdldFNlcmlhbGl6ZVN0cmVhbShcbiAgICAgICAgZ2V0U3RlcFJlZHVjZXJzKGdsb2JhbCwgb3BzLCBydW5JZCwgY3J5cHRvS2V5KSxcbiAgICAgICAgY3J5cHRvS2V5XG4gICAgICApO1xuICAgICAgY29uc3Qgc2VydmVyV3JpdGFibGUgPSBuZXcgV29ya2Zsb3dTZXJ2ZXJXcml0YWJsZVN0cmVhbShcbiAgICAgICAgcnVuSWQsXG4gICAgICAgIHZhbHVlLm5hbWVcbiAgICAgICk7XG5cbiAgICAgIC8vIENyZWF0ZSBmbHVzaGFibGUgc3RhdGUgZm9yIHRoaXMgc3RyZWFtXG4gICAgICBjb25zdCBzdGF0ZSA9IGNyZWF0ZUZsdXNoYWJsZVN0YXRlKCk7XG4gICAgICBvcHMucHVzaChzdGF0ZS5wcm9taXNlKTtcblxuICAgICAgLy8gU3RhcnQgdGhlIGZsdXNoYWJsZSBwaXBlIGluIHRoZSBiYWNrZ3JvdW5kXG4gICAgICBmbHVzaGFibGVQaXBlKHNlcmlhbGl6ZS5yZWFkYWJsZSwgc2VydmVyV3JpdGFibGUsIHN0YXRlKS5jYXRjaCgoKSA9PiB7XG4gICAgICAgIC8vIEVycm9ycyBhcmUgaGFuZGxlZCB2aWEgc3RhdGUucmVqZWN0XG4gICAgICB9KTtcblxuICAgICAgLy8gU3RhcnQgcG9sbGluZyB0byBkZXRlY3Qgd2hlbiB1c2VyIHJlbGVhc2VzIGxvY2tcbiAgICAgIHBvbGxXcml0YWJsZUxvY2soc2VyaWFsaXplLndyaXRhYmxlLCBzdGF0ZSk7XG5cbiAgICAgIHJldHVybiBzZXJpYWxpemUud3JpdGFibGU7XG4gICAgfSxcblxuICAgIEFib3J0Q29udHJvbGxlcjogKHZhbHVlKSA9PiByZXZpdmVBYm9ydENvbnRyb2xsZXIodmFsdWUsIG9wcywgcnVuSWQpLFxuICAgIEFib3J0U2lnbmFsOiAodmFsdWUpID0+IHJldml2ZUFib3J0U2lnbmFsKHZhbHVlLCBvcHMsIHJ1bklkKSxcbiAgfTtcbn1cblxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy8gRW5jcnlwdGlvbiBIZWxwZXJzXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vLyBUaGVzZSBkZWxlZ2F0ZSB0byB0aGUgbW9kdWxhciBgZW5jcnlwdGAvYGRlY3J5cHRgIGZyb20gYC4vc2VyaWFsaXphdGlvbi9lbmNyeXB0aW9uLmpzYFxuLy8gYnV0IGFyZSBrZXB0IGFzIG5hbWVkIGV4cG9ydHMgZm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5IHdpdGggZXhpc3RpbmcgY29uc3VtZXJzLlxuXG4vKipcbiAqIEVuY3J5cHQgZGF0YSBpZiB0aGUgd29ybGQgc3VwcG9ydHMgZW5jcnlwdGlvbi5cbiAqIFJldHVybnMgb3JpZ2luYWwgZGF0YSBpZiBlbmNyeXB0aW9uIGlzIG5vdCBhdmFpbGFibGUuXG4gKlxuICogQGRlcHJlY2F0ZWQgVXNlIGBlbmNyeXB0YCBmcm9tIGAuL3NlcmlhbGl6YXRpb24vZW5jcnlwdGlvbi5qc2AgaW5zdGVhZC5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIG1heWJlRW5jcnlwdChcbiAgZGF0YTogVWludDhBcnJheSxcbiAga2V5OiBDcnlwdG9LZXkgfCB1bmRlZmluZWRcbik6IFByb21pc2U8VWludDhBcnJheT4ge1xuICByZXR1cm4gKGF3YWl0IGVuY3J5cHQoZGF0YSwga2V5KSkgYXMgVWludDhBcnJheTtcbn1cblxuLyoqXG4gKiBEZWNyeXB0IGRhdGEgaWYgaXQgaGFzIHRoZSAnZW5jcicgcHJlZml4LlxuICpcbiAqIEBkZXByZWNhdGVkIFVzZSBgZGVjcnlwdGAgZnJvbSBgLi9zZXJpYWxpemF0aW9uL2VuY3J5cHRpb24uanNgIGluc3RlYWQuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBtYXliZURlY3J5cHQoXG4gIGRhdGE6IFVpbnQ4QXJyYXkgfCB1bmtub3duLFxuICBrZXk6IENyeXB0b0tleSB8IHVuZGVmaW5lZFxuKTogUHJvbWlzZTxVaW50OEFycmF5IHwgdW5rbm93bj4ge1xuICByZXR1cm4gZGVjcnlwdChkYXRhLCBrZXkpO1xufVxuXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vLyBEZWh5ZHJhdGUgLyBIeWRyYXRlIEZ1bmN0aW9uc1xuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy8gVGhlc2UgZGVsZWdhdGUgdG8gdGhlIG1vZHVsYXIgbW9kZSBtb2R1bGVzICh3b3JrZmxvdywgc3RlcCwgY2xpZW50KSBwYXNzaW5nXG4vLyBtb2RlLXNwZWNpZmljIHN0cmVhbSBhbmQgUmVxdWVzdC9SZXNwb25zZSByZWR1Y2Vycy9yZXZpdmVycyBhcyBleHRyYSBvcHRpb25zLlxuLy8gVGhlIHYxQ29tcGF0IHBhdGggaXMgaGFuZGxlZCBpbmxpbmUgYmVmb3JlIGRlbGVnYXRpbmcgdG8gdGhlIG1vZHVsZXMuXG5cbi8qKlxuICogQ2FsbGVkIGZyb20gdGhlIGBzdGFydCgpYCBmdW5jdGlvbiB0byBzZXJpYWxpemUgdGhlIHdvcmtmbG93IGFyZ3VtZW50c1xuICogaW50byBhIGZvcm1hdCB0aGF0IGNhbiBiZSBzYXZlZCB0byB0aGUgZGF0YWJhc2UgYW5kIHRoZW4gaHlkcmF0ZWQgZnJvbVxuICogd2l0aGluIHRoZSB3b3JrZmxvdyBleGVjdXRpb24gZW52aXJvbm1lbnQuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBkZWh5ZHJhdGVXb3JrZmxvd0FyZ3VtZW50cyhcbiAgdmFsdWU6IHVua25vd24sXG4gIHJ1bklkOiBzdHJpbmcsXG4gIGtleTogQ3J5cHRvS2V5IHwgdW5kZWZpbmVkLFxuICBvcHM6IFByb21pc2U8dm9pZD5bXSA9IFtdLFxuICBnbG9iYWw6IFJlY29yZDxzdHJpbmcsIGFueT4gPSBnbG9iYWxUaGlzLFxuICB2MUNvbXBhdCA9IGZhbHNlXG4pOiBQcm9taXNlPFVpbnQ4QXJyYXkgfCB1bmtub3duPiB7XG4gIGlmICh2MUNvbXBhdCkge1xuICAgIGNvbnN0IHN0ciA9IHN0cmluZ2lmeSh2YWx1ZSwgZ2V0RXh0ZXJuYWxSZWR1Y2VycyhnbG9iYWwsIG9wcywgcnVuSWQsIGtleSkpO1xuICAgIHJldHVybiByZXZpdmUoc3RyKTtcbiAgfVxuICB0cnkge1xuICAgIHJldHVybiBhd2FpdCBjbGllbnRNb2R1bGUuc2VyaWFsaXplKHZhbHVlLCBrZXksIHtcbiAgICAgIGdsb2JhbCxcbiAgICAgIGV4dHJhUmVkdWNlcnM6IGdldFN0cmVhbUFuZFJlcXVlc3RSZWR1Y2VycyhcbiAgICAgICAgZ2V0RXh0ZXJuYWxSZWR1Y2VycyhnbG9iYWwsIG9wcywgcnVuSWQsIGtleSlcbiAgICAgICksXG4gICAgfSk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgY29uc3QgY2F1c2UgPSB1bndyYXBTZXJpYWxpemF0aW9uQ2F1c2UoZXJyb3IpO1xuICAgIGNvbnN0IHsgbWVzc2FnZSwgaGludCB9ID0gZm9ybWF0U2VyaWFsaXphdGlvbkVycm9yKFxuICAgICAgJ3dvcmtmbG93IGFyZ3VtZW50cycsXG4gICAgICBjYXVzZVxuICAgICk7XG4gICAgdGhyb3cgbmV3IFNlcmlhbGl6YXRpb25FcnJvcihtZXNzYWdlLCB7IGhpbnQsIGNhdXNlIH0pO1xuICB9XG59XG5cbi8qKlxuICogQ2FsbGVkIGZyb20gd29ya2Zsb3cgZXhlY3V0aW9uIGVudmlyb25tZW50IHRvIGh5ZHJhdGUgdGhlIHdvcmtmbG93XG4gKiBhcmd1bWVudHMgZnJvbSB0aGUgZGF0YWJhc2UgYXQgdGhlIHN0YXJ0IG9mIHdvcmtmbG93IGV4ZWN1dGlvbi5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGh5ZHJhdGVXb3JrZmxvd0FyZ3VtZW50cyhcbiAgdmFsdWU6IFVpbnQ4QXJyYXkgfCB1bmtub3duLFxuICBfcnVuSWQ6IHN0cmluZyxcbiAga2V5OiBDcnlwdG9LZXkgfCB1bmRlZmluZWQsXG4gIGdsb2JhbDogUmVjb3JkPHN0cmluZywgYW55PiA9IGdsb2JhbFRoaXMsXG4gIGV4dHJhUmV2aXZlcnM6IFJlY29yZDxzdHJpbmcsICh2YWx1ZTogYW55KSA9PiBhbnk+ID0ge31cbik6IFByb21pc2U8YW55PiB7XG4gIHJldHVybiB3b3JrZmxvd01vZHVsZS5kZXNlcmlhbGl6ZShhd2FpdCBtYXliZURlY3J5cHQodmFsdWUsIGtleSksIHtcbiAgICBnbG9iYWwsXG4gICAgZXh0cmFSZXZpdmVyczoge1xuICAgICAgLi4uZ2V0U3RyZWFtQW5kUmVxdWVzdFJldml2ZXJzKGdldFdvcmtmbG93UmV2aXZlcnMoZ2xvYmFsKSksXG4gICAgICAuLi5leHRyYVJldml2ZXJzLFxuICAgIH0sXG4gIH0pO1xufVxuXG4vKipcbiAqIERlaHlkcmF0ZSB3b3JrZmxvdyByZXR1cm4gdmFsdWUgZm9yIHN0b3JhZ2UuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBkZWh5ZHJhdGVXb3JrZmxvd1JldHVyblZhbHVlKFxuICB2YWx1ZTogdW5rbm93bixcbiAgX3J1bklkOiBzdHJpbmcsXG4gIGtleTogQ3J5cHRvS2V5IHwgdW5kZWZpbmVkLFxuICBnbG9iYWw6IFJlY29yZDxzdHJpbmcsIGFueT4gPSBnbG9iYWxUaGlzLFxuICB2MUNvbXBhdCA9IGZhbHNlXG4pOiBQcm9taXNlPFVpbnQ4QXJyYXkgfCB1bmtub3duPiB7XG4gIGlmICh2MUNvbXBhdCkge1xuICAgIGNvbnN0IHN0ciA9IHN0cmluZ2lmeSh2YWx1ZSwgZ2V0V29ya2Zsb3dSZWR1Y2VycyhnbG9iYWwpKTtcbiAgICByZXR1cm4gcmV2aXZlKHN0cik7XG4gIH1cbiAgdHJ5IHtcbiAgICByZXR1cm4gYXdhaXQgc3RlcE1vZHVsZS5zZXJpYWxpemUodmFsdWUsIGtleSwge1xuICAgICAgZ2xvYmFsLFxuICAgICAgZXh0cmFSZWR1Y2VyczogZ2V0U3RyZWFtQW5kUmVxdWVzdFJlZHVjZXJzKGdldFdvcmtmbG93UmVkdWNlcnMoZ2xvYmFsKSksXG4gICAgfSk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgY29uc3QgY2F1c2UgPSB1bndyYXBTZXJpYWxpemF0aW9uQ2F1c2UoZXJyb3IpO1xuICAgIGNvbnN0IHsgbWVzc2FnZSwgaGludCB9ID0gZm9ybWF0U2VyaWFsaXphdGlvbkVycm9yKFxuICAgICAgJ3dvcmtmbG93IHJldHVybiB2YWx1ZScsXG4gICAgICBjYXVzZVxuICAgICk7XG4gICAgdGhyb3cgbmV3IFNlcmlhbGl6YXRpb25FcnJvcihtZXNzYWdlLCB7IGhpbnQsIGNhdXNlIH0pO1xuICB9XG59XG5cbi8qKlxuICogQ2FsbGVkIGZyb20gdGhlIGNsaWVudCBzaWRlIHRvIGh5ZHJhdGUgdGhlIHdvcmtmbG93IHJldHVybiB2YWx1ZVxuICogb2YgYSBjb21wbGV0ZWQgd29ya2Zsb3cgcnVuLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gaHlkcmF0ZVdvcmtmbG93UmV0dXJuVmFsdWUoXG4gIHZhbHVlOiBVaW50OEFycmF5IHwgdW5rbm93bixcbiAgcnVuSWQ6IHN0cmluZyxcbiAga2V5OiBDcnlwdG9LZXkgfCB1bmRlZmluZWQsXG4gIG9wczogUHJvbWlzZTx2b2lkPltdID0gW10sXG4gIGdsb2JhbDogUmVjb3JkPHN0cmluZywgYW55PiA9IGdsb2JhbFRoaXMsXG4gIGV4dHJhUmV2aXZlcnM6IFJlY29yZDxzdHJpbmcsICh2YWx1ZTogYW55KSA9PiBhbnk+ID0ge31cbik6IFByb21pc2U8YW55PiB7XG4gIHJldHVybiBjbGllbnRNb2R1bGUuZGVzZXJpYWxpemUodmFsdWUsIGtleSwge1xuICAgIGdsb2JhbCxcbiAgICBleHRyYVJldml2ZXJzOiB7XG4gICAgICAuLi5nZXRTdHJlYW1BbmRSZXF1ZXN0UmV2aXZlcnMoXG4gICAgICAgIGdldEV4dGVybmFsUmV2aXZlcnMoZ2xvYmFsLCBvcHMsIHJ1bklkLCBrZXkpXG4gICAgICApLFxuICAgICAgLi4uZXh0cmFSZXZpdmVycyxcbiAgICB9LFxuICB9KTtcbn1cblxuLyoqXG4gKiBDYWxsZWQgZnJvbSB0aGUgd29ya2Zsb3cgaGFuZGxlciB3aGVuIGEgc3RlcCBpcyBiZWluZyBjcmVhdGVkLlxuICogRGVoeWRyYXRlcyB2YWx1ZXMgZnJvbSB3aXRoaW4gdGhlIHdvcmtmbG93IGV4ZWN1dGlvbiBlbnZpcm9ubWVudC5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGRlaHlkcmF0ZVN0ZXBBcmd1bWVudHMoXG4gIHZhbHVlOiB1bmtub3duLFxuICBfcnVuSWQ6IHN0cmluZyxcbiAga2V5OiBDcnlwdG9LZXkgfCB1bmRlZmluZWQsXG4gIGdsb2JhbDogUmVjb3JkPHN0cmluZywgYW55PiA9IGdsb2JhbFRoaXMsXG4gIHYxQ29tcGF0ID0gZmFsc2Vcbik6IFByb21pc2U8VWludDhBcnJheSB8IHVua25vd24+IHtcbiAgaWYgKHYxQ29tcGF0KSB7XG4gICAgY29uc3Qgc3RyID0gc3RyaW5naWZ5KHZhbHVlLCBnZXRXb3JrZmxvd1JlZHVjZXJzKGdsb2JhbCkpO1xuICAgIHJldHVybiByZXZpdmUoc3RyKTtcbiAgfVxuICB0cnkge1xuICAgIHJldHVybiBhd2FpdCBzdGVwTW9kdWxlLnNlcmlhbGl6ZSh2YWx1ZSwga2V5LCB7XG4gICAgICBnbG9iYWwsXG4gICAgICBleHRyYVJlZHVjZXJzOiBnZXRTdHJlYW1BbmRSZXF1ZXN0UmVkdWNlcnMoZ2V0V29ya2Zsb3dSZWR1Y2VycyhnbG9iYWwpKSxcbiAgICB9KTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBjb25zdCBjYXVzZSA9IHVud3JhcFNlcmlhbGl6YXRpb25DYXVzZShlcnJvcik7XG4gICAgY29uc3QgeyBtZXNzYWdlLCBoaW50IH0gPSBmb3JtYXRTZXJpYWxpemF0aW9uRXJyb3IoJ3N0ZXAgYXJndW1lbnRzJywgY2F1c2UpO1xuICAgIHRocm93IG5ldyBTZXJpYWxpemF0aW9uRXJyb3IobWVzc2FnZSwgeyBoaW50LCBjYXVzZSB9KTtcbiAgfVxufVxuXG4vKipcbiAqIENhbGxlZCBmcm9tIHRoZSBzdGVwIGhhbmRsZXIgdG8gaHlkcmF0ZSB0aGUgYXJndW1lbnRzIG9mIGEgc3RlcFxuICogZnJvbSB0aGUgZGF0YWJhc2UgYXQgdGhlIHN0YXJ0IG9mIHRoZSBzdGVwIGV4ZWN1dGlvbi5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGh5ZHJhdGVTdGVwQXJndW1lbnRzKFxuICB2YWx1ZTogVWludDhBcnJheSB8IHVua25vd24sXG4gIHJ1bklkOiBzdHJpbmcsXG4gIGtleTogQ3J5cHRvS2V5IHwgdW5kZWZpbmVkLFxuICBvcHM6IFByb21pc2U8YW55PltdID0gW10sXG4gIGdsb2JhbDogUmVjb3JkPHN0cmluZywgYW55PiA9IGdsb2JhbFRoaXMsXG4gIGV4dHJhUmV2aXZlcnM6IFJlY29yZDxzdHJpbmcsICh2YWx1ZTogYW55KSA9PiBhbnk+ID0ge31cbik6IFByb21pc2U8YW55PiB7XG4gIHJldHVybiBzdGVwTW9kdWxlLmRlc2VyaWFsaXplKHZhbHVlLCBrZXksIHtcbiAgICBnbG9iYWwsXG4gICAgZXh0cmFSZXZpdmVyczoge1xuICAgICAgLi4uZ2V0U3RyZWFtQW5kUmVxdWVzdFJldml2ZXJzKGdldFN0ZXBSZXZpdmVycyhnbG9iYWwsIG9wcywgcnVuSWQsIGtleSkpLFxuICAgICAgLi4uZXh0cmFSZXZpdmVycyxcbiAgICB9LFxuICB9KTtcbn1cblxuLyoqXG4gKiBDYWxsZWQgZnJvbSB0aGUgc3RlcCBoYW5kbGVyIHdoZW4gYSBzdGVwIGhhcyBjb21wbGV0ZWQuXG4gKiBEZWh5ZHJhdGVzIHZhbHVlcyBmcm9tIHdpdGhpbiB0aGUgc3RlcCBleGVjdXRpb24gZW52aXJvbm1lbnQuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBkZWh5ZHJhdGVTdGVwUmV0dXJuVmFsdWUoXG4gIHZhbHVlOiB1bmtub3duLFxuICBydW5JZDogc3RyaW5nLFxuICBrZXk6IENyeXB0b0tleSB8IHVuZGVmaW5lZCxcbiAgb3BzOiBQcm9taXNlPGFueT5bXSA9IFtdLFxuICBnbG9iYWw6IFJlY29yZDxzdHJpbmcsIGFueT4gPSBnbG9iYWxUaGlzLFxuICB2MUNvbXBhdCA9IGZhbHNlXG4pOiBQcm9taXNlPFVpbnQ4QXJyYXkgfCB1bmtub3duPiB7XG4gIGlmICh2MUNvbXBhdCkge1xuICAgIGNvbnN0IHN0ciA9IHN0cmluZ2lmeSh2YWx1ZSwgZ2V0U3RlcFJlZHVjZXJzKGdsb2JhbCwgb3BzLCBydW5JZCwga2V5KSk7XG4gICAgcmV0dXJuIHJldml2ZShzdHIpO1xuICB9XG4gIHRyeSB7XG4gICAgcmV0dXJuIGF3YWl0IHN0ZXBNb2R1bGUuc2VyaWFsaXplKHZhbHVlLCBrZXksIHtcbiAgICAgIGdsb2JhbCxcbiAgICAgIGV4dHJhUmVkdWNlcnM6IGdldFN0cmVhbUFuZFJlcXVlc3RSZWR1Y2VycyhcbiAgICAgICAgZ2V0U3RlcFJlZHVjZXJzKGdsb2JhbCwgb3BzLCBydW5JZCwga2V5KVxuICAgICAgKSxcbiAgICB9KTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBjb25zdCBjYXVzZSA9IHVud3JhcFNlcmlhbGl6YXRpb25DYXVzZShlcnJvcik7XG4gICAgY29uc3QgeyBtZXNzYWdlLCBoaW50IH0gPSBmb3JtYXRTZXJpYWxpemF0aW9uRXJyb3IoXG4gICAgICAnc3RlcCByZXR1cm4gdmFsdWUnLFxuICAgICAgY2F1c2VcbiAgICApO1xuICAgIHRocm93IG5ldyBTZXJpYWxpemF0aW9uRXJyb3IobWVzc2FnZSwgeyBoaW50LCBjYXVzZSB9KTtcbiAgfVxufVxuXG4vKipcbiAqIENhbGxlZCBmcm9tIHRoZSBzdGVwIGhhbmRsZXIgd2hlbiBhIHN0ZXAgdGhyb3dzLiBEZWh5ZHJhdGVzIHRoZSB0aHJvd25cbiAqIHZhbHVlIGZyb20gd2l0aGluIHRoZSBzdGVwIGV4ZWN1dGlvbiBlbnZpcm9ubWVudCBpbnRvIGEgZm9ybWF0IHRoYXQgY2FuXG4gKiBiZSBzYXZlZCB0byB0aGUgZGF0YWJhc2UgaW4gYSBgc3RlcF9mYWlsZWRgIG9yIGBzdGVwX3JldHJ5aW5nYCBldmVudC5cbiAqXG4gKiBBbnkgSmF2YVNjcmlwdCB2YWx1ZSBjYW4gYmUgdGhyb3duIChzdHJpbmdzLCBudW1iZXJzLCBvYmplY3RzLCBFcnJvcnMsXG4gKiBFcnJvciBzdWJjbGFzc2VzKSwgc28gdGhlIHNhbWUgc2VyaWFsaXphdGlvbiBwaXBlbGluZSB1c2VkIGZvciBzdGVwXG4gKiBhcmd1bWVudHMgYW5kIHJldHVybiB2YWx1ZXMgaXMgYXBwbGllZCBoZXJlLlxuICpcbiAqIEBwYXJhbSB2YWx1ZSAtIFRoZSB0aHJvd24gdmFsdWUgdG8gc2VyaWFsaXplIChjYW4gYmUgYW55IHR5cGUpXG4gKiBAcGFyYW0gcnVuSWQgLSBSdW4gSUQgZm9yIGVuY3J5cHRpb24gY29udGV4dFxuICogQHBhcmFtIGtleSAtIEVuY3J5cHRpb24ga2V5ICh1bmRlZmluZWQgdG8gc2tpcCBlbmNyeXB0aW9uKVxuICogQHBhcmFtIG9wcyAtIFByb21pc2UgYXJyYXkgZm9yIHN0cmVhbSBvcGVyYXRpb25zXG4gKiBAcGFyYW0gZ2xvYmFsIC0gR2xvYmFsIG9iamVjdCBmb3Igc2VyaWFsaXphdGlvbiBjb250ZXh0XG4gKiBAcmV0dXJucyBUaGUgZGVoeWRyYXRlZCB2YWx1ZSBhcyBiaW5hcnkgZGF0YSAoVWludDhBcnJheSkgd2l0aCBmb3JtYXQgcHJlZml4XG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBkZWh5ZHJhdGVTdGVwRXJyb3IoXG4gIHZhbHVlOiB1bmtub3duLFxuICBydW5JZDogc3RyaW5nLFxuICBrZXk6IENyeXB0b0tleSB8IHVuZGVmaW5lZCxcbiAgb3BzOiBQcm9taXNlPGFueT5bXSA9IFtdLFxuICBnbG9iYWw6IFJlY29yZDxzdHJpbmcsIGFueT4gPSBnbG9iYWxUaGlzXG4pOiBQcm9taXNlPFVpbnQ4QXJyYXk+IHtcbiAgdHJ5IHtcbiAgICBjb25zdCBzdHIgPSBzdHJpbmdpZnkodmFsdWUsIGdldFN0ZXBSZWR1Y2VycyhnbG9iYWwsIG9wcywgcnVuSWQsIGtleSkpO1xuICAgIGNvbnN0IHBheWxvYWQgPSBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoc3RyKTtcbiAgICBjb25zdCBzZXJpYWxpemVkID0gZW5jb2RlV2l0aEZvcm1hdFByZWZpeChcbiAgICAgIFNlcmlhbGl6YXRpb25Gb3JtYXQuREVWQUxVRV9WMSxcbiAgICAgIHBheWxvYWRcbiAgICApIGFzIFVpbnQ4QXJyYXk7XG4gICAgcmV0dXJuIChhd2FpdCBtYXliZUVuY3J5cHQoc2VyaWFsaXplZCwga2V5KSkgYXMgVWludDhBcnJheTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBjb25zdCBjYXVzZSA9IHVud3JhcFNlcmlhbGl6YXRpb25DYXVzZShlcnJvcik7XG4gICAgY29uc3QgeyBtZXNzYWdlLCBoaW50IH0gPSBmb3JtYXRTZXJpYWxpemF0aW9uRXJyb3IoJ3N0ZXAgZXJyb3InLCBjYXVzZSk7XG4gICAgdGhyb3cgbmV3IFNlcmlhbGl6YXRpb25FcnJvcihtZXNzYWdlLCB7IGhpbnQsIGNhdXNlIH0pO1xuICB9XG59XG5cbi8qKlxuICogQ2FsbGVkIGZyb20gdGhlIHdvcmtmbG93IGhhbmRsZXIgd2hlbiByZXBsYXlpbmcgdGhlIGV2ZW50IGxvZyBvZiBhXG4gKiBgc3RlcF9mYWlsZWRgIG9yIGBzdGVwX3JldHJ5aW5nYCBldmVudC4gSHlkcmF0ZXMgdGhlIHRocm93biB2YWx1ZSBmcm9tXG4gKiB0aGUgZGF0YWJhc2Ugc28gdGhlIHdvcmtmbG93IGNhbiBzZWUgdGhlIG9yaWdpbmFsIHRocm93biB2YWx1ZS5cbiAqXG4gKiBAcGFyYW0gdmFsdWUgLSBCaW5hcnkgc2VyaWFsaXplZCBkYXRhIChVaW50OEFycmF5KSB3aXRoIGZvcm1hdCBwcmVmaXhcbiAqIEBwYXJhbSBydW5JZCAtIFJ1biBJRCBmb3IgZGVjcnlwdGlvbiBjb250ZXh0XG4gKiBAcGFyYW0ga2V5IC0gRW5jcnlwdGlvbiBrZXkgKHVuZGVmaW5lZCB0byBza2lwIGRlY3J5cHRpb24pXG4gKiBAcGFyYW0gZ2xvYmFsIC0gR2xvYmFsIG9iamVjdCBmb3IgZGVzZXJpYWxpemF0aW9uIGNvbnRleHRcbiAqIEBwYXJhbSBleHRyYVJldml2ZXJzIC0gQWRkaXRpb25hbCByZXZpdmVycyBmb3IgY3VzdG9tIHR5cGVzXG4gKiBAcmV0dXJucyBUaGUgaHlkcmF0ZWQgdGhyb3duIHZhbHVlLCByZWFkeSB0byByZWplY3QgdGhlIHN0ZXAgcHJvbWlzZVxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gaHlkcmF0ZVN0ZXBFcnJvcihcbiAgdmFsdWU6IFVpbnQ4QXJyYXkgfCB1bmtub3duLFxuICBfcnVuSWQ6IHN0cmluZyxcbiAga2V5OiBDcnlwdG9LZXkgfCB1bmRlZmluZWQsXG4gIGdsb2JhbDogUmVjb3JkPHN0cmluZywgYW55PiA9IGdsb2JhbFRoaXMsXG4gIGV4dHJhUmV2aXZlcnM6IFJlY29yZDxzdHJpbmcsICh2YWx1ZTogYW55KSA9PiBhbnk+ID0ge31cbik6IFByb21pc2U8dW5rbm93bj4ge1xuICBjb25zdCBkZWNyeXB0ZWQgPSBhd2FpdCBtYXliZURlY3J5cHQodmFsdWUsIGtleSk7XG5cbiAgaWYgKCEoZGVjcnlwdGVkIGluc3RhbmNlb2YgVWludDhBcnJheSkpIHtcbiAgICAvLyBUcmVhdGVkIGFzIGEgZGV2YWx1ZSBcImZsYXR0ZW5lZFwiIGFycmF5LiBJbiBwcm9kdWN0aW9uIHRoaXMgYnJhbmNoIGlzXG4gICAgLy8gZXhlcmNpc2VkIGJ5IGxlZ2FjeSBjb2RlIHBhdGhzIHRoYXQgYnlwYXNzZWQgYGRlaHlkcmF0ZVN0ZXBFcnJvcmA7IHRoZVxuICAgIC8vIFNESyB2ZXJzaW9uIGlzIHBpbm5lZCBwZXIgd29ya2Zsb3cgcnVuIHZpYSBza2V3IHByb3RlY3Rpb24sIHNvIGFcbiAgICAvLyBjdXJyZW50LXZlcnNpb24gcHJvZHVjZXIgYWx3YXlzIGVtaXRzIGEgVWludDhBcnJheSBoZXJlLiBJZiBhXG4gICAgLy8gbWlzc2hhcGVuIHZhbHVlIHJlYWNoZXMgdXMsIGB1bmZsYXR0ZW5gIHRocm93cyDigJQgdGhhdCdzIGludGVudGlvbmFsOlxuICAgIC8vIHRoZSBoaWdoZXItbGV2ZWwgaHlkcmF0aW9uIGhlbHBlcnMgKGBoeWRyYXRlU3RlcElPYCxcbiAgICAvLyBgaHlkcmF0ZVJlc291cmNlSU9gKSBhbHJlYWR5IHdyYXAgdXMgaW4gYSB0cnkvY2F0Y2ggdGhhdCBsZWF2ZXMgdGhlXG4gICAgLy8gZmllbGQgdW4taHlkcmF0ZWQgZm9yIG8xMXkgZGlzcGxheSwgYW5kIHN1cmZhY2luZyB0aGUgdGhyb3cgdG8gbG9nc1xuICAgIC8vIGlzIG1vcmUgZGVidWdnYWJsZSB0aGFuIHNpbGVudGx5IG1hc2tpbmcgdGhlIHVuc3VwcG9ydGVkIHNoYXBlLlxuICAgIHJldHVybiB1bmZsYXR0ZW4oZGVjcnlwdGVkIGFzIGFueVtdLCB7XG4gICAgICAuLi5nZXRXb3JrZmxvd1Jldml2ZXJzKGdsb2JhbCksXG4gICAgICAuLi5leHRyYVJldml2ZXJzLFxuICAgIH0pO1xuICB9XG5cbiAgY29uc3QgeyBmb3JtYXQsIHBheWxvYWQgfSA9IGRlY29kZUZvcm1hdFByZWZpeChkZWNyeXB0ZWQpO1xuXG4gIGlmIChmb3JtYXQgPT09IFNlcmlhbGl6YXRpb25Gb3JtYXQuREVWQUxVRV9WMSkge1xuICAgIGNvbnN0IHN0ciA9IG5ldyBUZXh0RGVjb2RlcigpLmRlY29kZShwYXlsb2FkKTtcbiAgICByZXR1cm4gcGFyc2Uoc3RyLCB7XG4gICAgICAuLi5nZXRXb3JrZmxvd1Jldml2ZXJzKGdsb2JhbCksXG4gICAgICAuLi5leHRyYVJldml2ZXJzLFxuICAgIH0pO1xuICB9XG5cbiAgdGhyb3cgbmV3IEVycm9yKGBVbnN1cHBvcnRlZCBzZXJpYWxpemF0aW9uIGZvcm1hdDogJHtmb3JtYXR9YCk7XG59XG5cbi8qKlxuICogQ2FsbGVkIGZyb20gdGhlIHdvcmtmbG93IGhhbmRsZXIgd2hlbiB0aGUgd29ya2Zsb3cgaXRzZWxmIHRocm93cy5cbiAqIERlaHlkcmF0ZXMgdGhlIHRocm93biB2YWx1ZSBmcm9tIHdpdGhpbiB0aGUgd29ya2Zsb3cgZXhlY3V0aW9uIGVudmlyb25tZW50XG4gKiBpbnRvIGEgZm9ybWF0IHRoYXQgY2FuIGJlIHNhdmVkIHRvIHRoZSBkYXRhYmFzZSBpbiBhIGBydW5fZmFpbGVkYCBldmVudC5cbiAqXG4gKiBAcGFyYW0gdmFsdWUgLSBUaGUgdGhyb3duIHZhbHVlIHRvIHNlcmlhbGl6ZSAoY2FuIGJlIGFueSB0eXBlKVxuICogQHBhcmFtIHJ1bklkIC0gUnVuIElEIGZvciBlbmNyeXB0aW9uIGNvbnRleHRcbiAqIEBwYXJhbSBrZXkgLSBFbmNyeXB0aW9uIGtleSAodW5kZWZpbmVkIHRvIHNraXAgZW5jcnlwdGlvbilcbiAqIEBwYXJhbSBnbG9iYWwgLSBHbG9iYWwgb2JqZWN0IGZvciBzZXJpYWxpemF0aW9uIGNvbnRleHRcbiAqIEByZXR1cm5zIFRoZSBkZWh5ZHJhdGVkIHZhbHVlIGFzIGJpbmFyeSBkYXRhIChVaW50OEFycmF5KSB3aXRoIGZvcm1hdCBwcmVmaXhcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGRlaHlkcmF0ZVJ1bkVycm9yKFxuICB2YWx1ZTogdW5rbm93bixcbiAgX3J1bklkOiBzdHJpbmcsXG4gIGtleTogQ3J5cHRvS2V5IHwgdW5kZWZpbmVkLFxuICBnbG9iYWw6IFJlY29yZDxzdHJpbmcsIGFueT4gPSBnbG9iYWxUaGlzXG4pOiBQcm9taXNlPFVpbnQ4QXJyYXk+IHtcbiAgdHJ5IHtcbiAgICBjb25zdCBzdHIgPSBzdHJpbmdpZnkodmFsdWUsIGdldFdvcmtmbG93UmVkdWNlcnMoZ2xvYmFsKSk7XG4gICAgY29uc3QgcGF5bG9hZCA9IG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZShzdHIpO1xuICAgIGNvbnN0IHNlcmlhbGl6ZWQgPSBlbmNvZGVXaXRoRm9ybWF0UHJlZml4KFxuICAgICAgU2VyaWFsaXphdGlvbkZvcm1hdC5ERVZBTFVFX1YxLFxuICAgICAgcGF5bG9hZFxuICAgICkgYXMgVWludDhBcnJheTtcbiAgICByZXR1cm4gKGF3YWl0IG1heWJlRW5jcnlwdChzZXJpYWxpemVkLCBrZXkpKSBhcyBVaW50OEFycmF5O1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIGNvbnN0IGNhdXNlID0gdW53cmFwU2VyaWFsaXphdGlvbkNhdXNlKGVycm9yKTtcbiAgICBjb25zdCB7IG1lc3NhZ2UsIGhpbnQgfSA9IGZvcm1hdFNlcmlhbGl6YXRpb25FcnJvcigncnVuIGVycm9yJywgY2F1c2UpO1xuICAgIHRocm93IG5ldyBTZXJpYWxpemF0aW9uRXJyb3IobWVzc2FnZSwgeyBoaW50LCBjYXVzZSB9KTtcbiAgfVxufVxuXG4vKipcbiAqIENhbGxlZCBmcm9tIHRoZSBjbGllbnQgc2lkZSAob3Igb2JzZXJ2YWJpbGl0eSB0b29scykgdG8gaHlkcmF0ZSB0aGUgcnVuXG4gKiBlcnJvciB2YWx1ZSBvZiBhIGZhaWxlZCB3b3JrZmxvdyBydW4uXG4gKlxuICogQHBhcmFtIHZhbHVlIC0gQmluYXJ5IHNlcmlhbGl6ZWQgZGF0YSAoVWludDhBcnJheSkgd2l0aCBmb3JtYXQgcHJlZml4XG4gKiBAcGFyYW0gcnVuSWQgLSBSdW4gSUQgZm9yIGRlY3J5cHRpb24gY29udGV4dFxuICogQHBhcmFtIGtleSAtIEVuY3J5cHRpb24ga2V5ICh1bmRlZmluZWQgdG8gc2tpcCBkZWNyeXB0aW9uKVxuICogQHBhcmFtIG9wcyAtIFByb21pc2UgYXJyYXkgZm9yIHN0cmVhbSBvcGVyYXRpb25zXG4gKiBAcGFyYW0gZ2xvYmFsIC0gR2xvYmFsIG9iamVjdCBmb3IgZGVzZXJpYWxpemF0aW9uIGNvbnRleHRcbiAqIEBwYXJhbSBleHRyYVJldml2ZXJzIC0gQWRkaXRpb25hbCByZXZpdmVycyBmb3IgY3VzdG9tIHR5cGVzXG4gKiBAcmV0dXJucyBUaGUgaHlkcmF0ZWQgdGhyb3duIHZhbHVlLCByZWFkeSB0byBiZSBjb25zdW1lZCBieSB0aGUgY2xpZW50XG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBoeWRyYXRlUnVuRXJyb3IoXG4gIHZhbHVlOiBVaW50OEFycmF5IHwgdW5rbm93bixcbiAgcnVuSWQ6IHN0cmluZyxcbiAga2V5OiBDcnlwdG9LZXkgfCB1bmRlZmluZWQsXG4gIG9wczogUHJvbWlzZTx2b2lkPltdID0gW10sXG4gIGdsb2JhbDogUmVjb3JkPHN0cmluZywgYW55PiA9IGdsb2JhbFRoaXMsXG4gIGV4dHJhUmV2aXZlcnM6IFJlY29yZDxzdHJpbmcsICh2YWx1ZTogYW55KSA9PiBhbnk+ID0ge31cbik6IFByb21pc2U8dW5rbm93bj4ge1xuICBjb25zdCBkZWNyeXB0ZWQgPSBhd2FpdCBtYXliZURlY3J5cHQodmFsdWUsIGtleSk7XG5cbiAgaWYgKCEoZGVjcnlwdGVkIGluc3RhbmNlb2YgVWludDhBcnJheSkpIHtcbiAgICAvLyBTZWUgdGhlIG1hdGNoaW5nIG5vdGUgaW4gYGh5ZHJhdGVTdGVwRXJyb3JgOiB0aGlzIGJyYW5jaCBpcyBmb3JcbiAgICAvLyBkZXZhbHVlIGZsYXR0ZW5lZCBhcnJheXMgZnJvbSBsZWdhY3kgY2FsbGVyczsgY3VycmVudCBTREsgdmVyc2lvbnNcbiAgICAvLyBhbHdheXMgZW1pdCBhIFVpbnQ4QXJyYXksIGFuZCBhIG1pc3NoYXBlbiB2YWx1ZSBoZXJlIGludGVudGlvbmFsbHlcbiAgICAvLyB0aHJvd3MgdmlhIGB1bmZsYXR0ZW5gIHNvIHRoZSBzdXJyb3VuZGluZyB0cnkvY2F0Y2ggaW4gbzExeSBoZWxwZXJzXG4gICAgLy8gc3VyZmFjZXMgdGhlIGlzc3VlIHJhdGhlciB0aGFuIG1hc2tpbmcgaXQuXG4gICAgcmV0dXJuIHVuZmxhdHRlbihkZWNyeXB0ZWQgYXMgYW55W10sIHtcbiAgICAgIC4uLmdldEV4dGVybmFsUmV2aXZlcnMoZ2xvYmFsLCBvcHMsIHJ1bklkLCBrZXkpLFxuICAgICAgLi4uZXh0cmFSZXZpdmVycyxcbiAgICB9KTtcbiAgfVxuXG4gIGNvbnN0IHsgZm9ybWF0LCBwYXlsb2FkIH0gPSBkZWNvZGVGb3JtYXRQcmVmaXgoZGVjcnlwdGVkKTtcblxuICBpZiAoZm9ybWF0ID09PSBTZXJpYWxpemF0aW9uRm9ybWF0LkRFVkFMVUVfVjEpIHtcbiAgICBjb25zdCBzdHIgPSBuZXcgVGV4dERlY29kZXIoKS5kZWNvZGUocGF5bG9hZCk7XG4gICAgcmV0dXJuIHBhcnNlKHN0ciwge1xuICAgICAgLi4uZ2V0RXh0ZXJuYWxSZXZpdmVycyhnbG9iYWwsIG9wcywgcnVuSWQsIGtleSksXG4gICAgICAuLi5leHRyYVJldml2ZXJzLFxuICAgIH0pO1xuICB9XG5cbiAgdGhyb3cgbmV3IEVycm9yKGBVbnN1cHBvcnRlZCBzZXJpYWxpemF0aW9uIGZvcm1hdDogJHtmb3JtYXR9YCk7XG59XG5cbi8qKlxuICogQ2FsbGVkIGZyb20gdGhlIHdvcmtmbG93IGhhbmRsZXIgd2hlbiByZXBsYXlpbmcgdGhlIGV2ZW50IGxvZyBvZiBhIGBzdGVwX2NvbXBsZXRlZGAgZXZlbnQuXG4gKiBIeWRyYXRlcyB0aGUgcmV0dXJuIHZhbHVlIG9mIGEgc3RlcCBmcm9tIHRoZSBkYXRhYmFzZS5cbiAqXG4gKiBAcGFyYW0gdmFsdWUgLSBCaW5hcnkgc2VyaWFsaXplZCBkYXRhIChVaW50OEFycmF5KSB3aXRoIGZvcm1hdCBwcmVmaXhcbiAqIEBwYXJhbSBydW5JZCAtIFJ1biBJRCBmb3IgZGVjcnlwdGlvbiBjb250ZXh0XG4gKiBAcGFyYW0ga2V5IC0gRW5jcnlwdGlvbiBrZXkgKHVuZGVmaW5lZCB0byBza2lwIGRlY3J5cHRpb24pXG4gKiBAcGFyYW0gZ2xvYmFsIC0gR2xvYmFsIG9iamVjdCBmb3IgZGVzZXJpYWxpemF0aW9uIGNvbnRleHRcbiAqIEBwYXJhbSBleHRyYVJldml2ZXJzIC0gQWRkaXRpb25hbCByZXZpdmVycyBmb3IgY3VzdG9tIHR5cGVzXG4gKiBDYWxsZWQgZnJvbSB0aGUgd29ya2Zsb3cgaGFuZGxlciB3aGVuIHJlcGxheWluZyB0aGUgZXZlbnQgbG9nXG4gKiBvZiBhIGBzdGVwX2NvbXBsZXRlZGAgZXZlbnQuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBoeWRyYXRlU3RlcFJldHVyblZhbHVlKFxuICB2YWx1ZTogVWludDhBcnJheSB8IHVua25vd24sXG4gIF9ydW5JZDogc3RyaW5nLFxuICBrZXk6IENyeXB0b0tleSB8IHVuZGVmaW5lZCxcbiAgZ2xvYmFsOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0gZ2xvYmFsVGhpcyxcbiAgZXh0cmFSZXZpdmVyczogUmVjb3JkPHN0cmluZywgKHZhbHVlOiBhbnkpID0+IGFueT4gPSB7fVxuKTogUHJvbWlzZTxhbnk+IHtcbiAgcmV0dXJuIHdvcmtmbG93TW9kdWxlLmRlc2VyaWFsaXplKGF3YWl0IG1heWJlRGVjcnlwdCh2YWx1ZSwga2V5KSwge1xuICAgIGdsb2JhbCxcbiAgICBleHRyYVJldml2ZXJzOiB7XG4gICAgICAuLi5nZXRTdHJlYW1BbmRSZXF1ZXN0UmV2aXZlcnMoZ2V0V29ya2Zsb3dSZXZpdmVycyhnbG9iYWwpKSxcbiAgICAgIC4uLmV4dHJhUmV2aXZlcnMsXG4gICAgfSxcbiAgfSk7XG59XG5cbi8vIC0tLS0gSGVscGVycyB0byBleHRyYWN0IHN0cmVhbS9SZXF1ZXN0L1Jlc3BvbnNlIHJlZHVjZXJzIGFuZCByZXZpdmVycyAtLS0tXG4vLyBUaGUgbW9kZS1zcGVjaWZpYyBnZXQqUmVkdWNlcnMvZ2V0KlJldml2ZXJzIGZ1bmN0aW9ucyByZXR1cm4gb2JqZWN0cyB0aGF0XG4vLyBpbmNsdWRlIGJvdGggXCJjb21tb25cIiBlbnRyaWVzIChEYXRlLCBFcnJvciwgTWFwLCBldGMuKSBhbmQgbW9kZS1zcGVjaWZpY1xuLy8gZW50cmllcyAoUmVhZGFibGVTdHJlYW0sIFdyaXRhYmxlU3RyZWFtLCBSZXF1ZXN0LCBSZXNwb25zZSwgU3RlcEZ1bmN0aW9uKS5cbi8vIFRoZSBjb21tb24gZW50cmllcyBhcmUgYWxyZWFkeSBjb21wb3NlZCBieSB0aGUgY29kZWMuIFdlIG9ubHkgbmVlZCB0b1xuLy8gcGFzcyB0aHJvdWdoIHRoZSBtb2RlLXNwZWNpZmljIGVudHJpZXMgYXMgZXh0cmFSZWR1Y2Vycy9leHRyYVJldml2ZXJzLlxuXG5jb25zdCBTVFJFQU1fQU5EX1JFUVVFU1RfS0VZUyA9IFtcbiAgJ1JlYWRhYmxlU3RyZWFtJyxcbiAgJ1dyaXRhYmxlU3RyZWFtJyxcbiAgJ1JlcXVlc3QnLFxuICAnUmVzcG9uc2UnLFxuICAnU3RlcEZ1bmN0aW9uJyxcbiAgLy8gV2lyZSBBYm9ydENvbnRyb2xsZXIvQWJvcnRTaWduYWwgdGhyb3VnaCB0aGUgY2xpZW50IHNlcmlhbGl6YXRpb24gcGF0aCBzb1xuICAvLyBzaWduYWxzIHJlYWNoYWJsZSB2aWEgUmVxdWVzdC5zaWduYWwgKG9yIGFzIGRpcmVjdCBhcmd1bWVudHMpIGdldCB0aGVpclxuICAvLyBkZWRpY2F0ZWQgcmVkdWNlci4gV2l0aG91dCB0aGlzLCBkZXZhbHVlIGZhbGxzIGJhY2sgdG8gaXRzIGFyYml0cmFyeS1QT0pPXG4gIC8vIHBhdGggYW5kIGZhaWxzIGZvciBhbnkgc2lnbmFsIHRoZSBSZXF1ZXN0IHJlZHVjZXIgZm9yd2FyZHMuXG4gICdBYm9ydENvbnRyb2xsZXInLFxuICAnQWJvcnRTaWduYWwnLFxuXSBhcyBjb25zdDtcblxuZnVuY3Rpb24gZ2V0U3RyZWFtQW5kUmVxdWVzdFJlZHVjZXJzKFxuICBhbGxSZWR1Y2VyczogUmVjb3JkPHN0cmluZywgYW55PlxuKTogUmVjb3JkPHN0cmluZywgKHZhbHVlOiBhbnkpID0+IGFueT4ge1xuICBjb25zdCBleHRyYTogUmVjb3JkPHN0cmluZywgKHZhbHVlOiBhbnkpID0+IGFueT4gPSB7fTtcbiAgZm9yIChjb25zdCBrZXkgb2YgU1RSRUFNX0FORF9SRVFVRVNUX0tFWVMpIHtcbiAgICBpZiAoa2V5IGluIGFsbFJlZHVjZXJzKSB7XG4gICAgICBleHRyYVtrZXldID0gYWxsUmVkdWNlcnNba2V5XTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGV4dHJhO1xufVxuXG5mdW5jdGlvbiBnZXRTdHJlYW1BbmRSZXF1ZXN0UmV2aXZlcnMoXG4gIGFsbFJldml2ZXJzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+XG4pOiBSZWNvcmQ8c3RyaW5nLCAodmFsdWU6IGFueSkgPT4gYW55PiB7XG4gIGNvbnN0IGV4dHJhOiBSZWNvcmQ8c3RyaW5nLCAodmFsdWU6IGFueSkgPT4gYW55PiA9IHt9O1xuICBmb3IgKGNvbnN0IGtleSBvZiBTVFJFQU1fQU5EX1JFUVVFU1RfS0VZUykge1xuICAgIGlmIChrZXkgaW4gYWxsUmV2aXZlcnMpIHtcbiAgICAgIGV4dHJhW2tleV0gPSBhbGxSZXZpdmVyc1trZXldO1xuICAgIH1cbiAgfVxuICByZXR1cm4gZXh0cmE7XG59XG4iXX0=