@mnaoumov/typescript-lib 0.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (182) hide show
  1. package/@types/debug/package.json +4 -0
  2. package/LICENSE +21 -0
  3. package/README.md +15 -1
  4. package/dist/lib/cjs/@types/debug.d.cts +21 -0
  5. package/dist/lib/cjs/abort-controller.cjs +144 -0
  6. package/dist/lib/cjs/abort-controller.d.cts +136 -0
  7. package/dist/lib/cjs/aggregate-error.cjs +40 -0
  8. package/dist/lib/cjs/aggregate-error.d.cts +24 -0
  9. package/dist/lib/cjs/array-buffer.cjs +38 -0
  10. package/dist/lib/cjs/array-buffer.d.cts +16 -0
  11. package/dist/lib/cjs/array.cjs +76 -0
  12. package/dist/lib/cjs/array.d.cts +46 -0
  13. package/dist/lib/cjs/async-events.cjs +408 -0
  14. package/dist/lib/cjs/async-events.d.cts +456 -0
  15. package/dist/lib/cjs/async-operation-hook.cjs +55 -0
  16. package/dist/lib/cjs/async-operation-hook.d.cts +59 -0
  17. package/dist/lib/cjs/async.cjs +463 -0
  18. package/dist/lib/cjs/async.d.cts +415 -0
  19. package/dist/lib/cjs/beeper.cjs +68 -0
  20. package/dist/lib/cjs/beeper.d.cts +21 -0
  21. package/dist/lib/cjs/blob.cjs +102 -0
  22. package/dist/lib/cjs/blob.d.cts +60 -0
  23. package/dist/lib/cjs/bytes.cjs +56 -0
  24. package/dist/lib/cjs/bytes.d.cts +17 -0
  25. package/dist/lib/cjs/debug-controller.cjs +22 -0
  26. package/dist/lib/cjs/debug-controller.d.cts +87 -0
  27. package/dist/lib/cjs/debug.cjs +204 -0
  28. package/dist/lib/cjs/debug.d.cts +66 -0
  29. package/dist/lib/cjs/desktop-zip-extractor.cjs +157 -0
  30. package/dist/lib/cjs/desktop-zip-extractor.d.cts +96 -0
  31. package/dist/lib/cjs/disposable.cjs +364 -0
  32. package/dist/lib/cjs/disposable.d.cts +387 -0
  33. package/dist/lib/cjs/enum.cjs +42 -0
  34. package/dist/lib/cjs/enum.d.cts +24 -0
  35. package/dist/lib/cjs/error.cjs +239 -0
  36. package/dist/lib/cjs/error.d.cts +182 -0
  37. package/dist/lib/cjs/function.cjs +83 -0
  38. package/dist/lib/cjs/function.d.cts +128 -0
  39. package/dist/lib/cjs/html-element.cjs +283 -0
  40. package/dist/lib/cjs/html-element.d.cts +200 -0
  41. package/dist/lib/cjs/index.cjs +137 -0
  42. package/dist/lib/cjs/index.d.cts +33 -0
  43. package/dist/lib/cjs/jpeg-metadata.cjs +170 -0
  44. package/dist/lib/cjs/jpeg-metadata.d.cts +42 -0
  45. package/dist/lib/cjs/library-references.d.cts +2 -0
  46. package/dist/lib/cjs/library.cjs +100 -0
  47. package/dist/lib/cjs/library.d.cts +96 -0
  48. package/dist/lib/cjs/object-utils.cjs +559 -0
  49. package/dist/lib/cjs/object-utils.d.cts +298 -0
  50. package/dist/lib/cjs/path.cjs +171 -0
  51. package/dist/lib/cjs/path.d.cts +155 -0
  52. package/dist/lib/cjs/reg-exp.cjs +196 -0
  53. package/dist/lib/cjs/reg-exp.d.cts +87 -0
  54. package/dist/lib/cjs/string.cjs +268 -0
  55. package/dist/lib/cjs/string.d.cts +362 -0
  56. package/dist/lib/cjs/transformers/date-transformer.cjs +71 -0
  57. package/dist/lib/cjs/transformers/date-transformer.d.cts +39 -0
  58. package/dist/lib/cjs/transformers/group-transformer.cjs +115 -0
  59. package/dist/lib/cjs/transformers/group-transformer.d.cts +70 -0
  60. package/dist/lib/cjs/transformers/index.cjs +65 -0
  61. package/dist/lib/cjs/transformers/index.d.cts +9 -0
  62. package/dist/lib/cjs/transformers/map-transformer.cjs +71 -0
  63. package/dist/lib/cjs/transformers/map-transformer.d.cts +41 -0
  64. package/dist/lib/cjs/transformers/set-transformer.cjs +71 -0
  65. package/dist/lib/cjs/transformers/set-transformer.d.cts +39 -0
  66. package/dist/lib/cjs/transformers/skip-private-property-transformer.cjs +69 -0
  67. package/dist/lib/cjs/transformers/skip-private-property-transformer.d.cts +36 -0
  68. package/dist/lib/cjs/transformers/transformer.cjs +112 -0
  69. package/dist/lib/cjs/transformers/transformer.d.cts +70 -0
  70. package/dist/lib/cjs/transformers/two-way-map-transformer.cjs +72 -0
  71. package/dist/lib/cjs/transformers/two-way-map-transformer.d.cts +42 -0
  72. package/dist/lib/cjs/transformers/typed-transformer.cjs +36 -0
  73. package/dist/lib/cjs/transformers/typed-transformer.d.cts +39 -0
  74. package/dist/lib/cjs/two-way-map.cjs +150 -0
  75. package/dist/lib/cjs/two-way-map.d.cts +101 -0
  76. package/dist/lib/cjs/type-guards.cjs +70 -0
  77. package/dist/lib/cjs/type-guards.d.cts +84 -0
  78. package/dist/lib/cjs/type.cjs +63 -0
  79. package/dist/lib/cjs/type.d.cts +122 -0
  80. package/dist/lib/cjs/typescript-lib-state.cjs +68 -0
  81. package/dist/lib/cjs/typescript-lib-state.d.cts +56 -0
  82. package/dist/lib/cjs/url.cjs +78 -0
  83. package/dist/lib/cjs/url.d.cts +74 -0
  84. package/dist/lib/cjs/value-provider.cjs +42 -0
  85. package/dist/lib/cjs/value-provider.d.cts +29 -0
  86. package/dist/lib/cjs/value-wrapper.cjs +86 -0
  87. package/dist/lib/cjs/value-wrapper.d.cts +47 -0
  88. package/dist/lib/esm/@types/debug.d.mts +21 -0
  89. package/dist/lib/esm/abort-controller.d.mts +136 -0
  90. package/dist/lib/esm/abort-controller.mjs +115 -0
  91. package/dist/lib/esm/aggregate-error.d.mts +24 -0
  92. package/dist/lib/esm/aggregate-error.mjs +16 -0
  93. package/dist/lib/esm/array-buffer.d.mts +16 -0
  94. package/dist/lib/esm/array-buffer.mjs +14 -0
  95. package/dist/lib/esm/array.d.mts +46 -0
  96. package/dist/lib/esm/array.mjs +49 -0
  97. package/dist/lib/esm/async-events.d.mts +456 -0
  98. package/dist/lib/esm/async-events.mjs +383 -0
  99. package/dist/lib/esm/async-operation-hook.d.mts +59 -0
  100. package/dist/lib/esm/async-operation-hook.mjs +27 -0
  101. package/dist/lib/esm/async.d.mts +415 -0
  102. package/dist/lib/esm/async.mjs +435 -0
  103. package/dist/lib/esm/beeper.d.mts +21 -0
  104. package/dist/lib/esm/beeper.mjs +44 -0
  105. package/dist/lib/esm/blob.d.mts +60 -0
  106. package/dist/lib/esm/blob.mjs +77 -0
  107. package/dist/lib/esm/bytes.d.mts +17 -0
  108. package/dist/lib/esm/bytes.mjs +32 -0
  109. package/dist/lib/esm/debug-controller.d.mts +87 -0
  110. package/dist/lib/esm/debug-controller.mjs +6 -0
  111. package/dist/lib/esm/debug.d.mts +66 -0
  112. package/dist/lib/esm/debug.mjs +168 -0
  113. package/dist/lib/esm/desktop-zip-extractor.d.mts +96 -0
  114. package/dist/lib/esm/desktop-zip-extractor.mjs +136 -0
  115. package/dist/lib/esm/disposable.d.mts +387 -0
  116. package/dist/lib/esm/disposable.mjs +324 -0
  117. package/dist/lib/esm/enum.d.mts +24 -0
  118. package/dist/lib/esm/enum.mjs +17 -0
  119. package/dist/lib/esm/error.d.mts +182 -0
  120. package/dist/lib/esm/error.mjs +204 -0
  121. package/dist/lib/esm/function.d.mts +128 -0
  122. package/dist/lib/esm/function.mjs +52 -0
  123. package/dist/lib/esm/html-element.d.mts +200 -0
  124. package/dist/lib/esm/html-element.mjs +247 -0
  125. package/dist/lib/esm/index.d.mts +33 -0
  126. package/dist/lib/esm/index.mjs +72 -0
  127. package/dist/lib/esm/jpeg-metadata.d.mts +42 -0
  128. package/dist/lib/esm/jpeg-metadata.mjs +145 -0
  129. package/dist/lib/esm/library-references.d.mts +2 -0
  130. package/dist/lib/esm/library.d.mts +96 -0
  131. package/dist/lib/esm/library.mjs +74 -0
  132. package/dist/lib/esm/object-utils.d.mts +298 -0
  133. package/dist/lib/esm/object-utils.mjs +523 -0
  134. package/dist/lib/esm/path.d.mts +155 -0
  135. package/dist/lib/esm/path.mjs +122 -0
  136. package/dist/lib/esm/reg-exp.d.mts +87 -0
  137. package/dist/lib/esm/reg-exp.mjs +169 -0
  138. package/dist/lib/esm/string.d.mts +362 -0
  139. package/dist/lib/esm/string.mjs +230 -0
  140. package/dist/lib/esm/transformers/date-transformer.d.mts +39 -0
  141. package/dist/lib/esm/transformers/date-transformer.mjs +47 -0
  142. package/dist/lib/esm/transformers/group-transformer.d.mts +70 -0
  143. package/dist/lib/esm/transformers/group-transformer.mjs +94 -0
  144. package/dist/lib/esm/transformers/index.d.mts +9 -0
  145. package/dist/lib/esm/transformers/index.mjs +24 -0
  146. package/dist/lib/esm/transformers/map-transformer.d.mts +41 -0
  147. package/dist/lib/esm/transformers/map-transformer.mjs +47 -0
  148. package/dist/lib/esm/transformers/set-transformer.d.mts +39 -0
  149. package/dist/lib/esm/transformers/set-transformer.mjs +47 -0
  150. package/dist/lib/esm/transformers/skip-private-property-transformer.d.mts +36 -0
  151. package/dist/lib/esm/transformers/skip-private-property-transformer.mjs +45 -0
  152. package/dist/lib/esm/transformers/transformer.d.mts +70 -0
  153. package/dist/lib/esm/transformers/transformer.mjs +88 -0
  154. package/dist/lib/esm/transformers/two-way-map-transformer.d.mts +42 -0
  155. package/dist/lib/esm/transformers/two-way-map-transformer.mjs +48 -0
  156. package/dist/lib/esm/transformers/typed-transformer.d.mts +39 -0
  157. package/dist/lib/esm/transformers/typed-transformer.mjs +12 -0
  158. package/dist/lib/esm/two-way-map.d.mts +101 -0
  159. package/dist/lib/esm/two-way-map.mjs +126 -0
  160. package/dist/lib/esm/type-guards.d.mts +84 -0
  161. package/dist/lib/esm/type-guards.mjs +41 -0
  162. package/dist/lib/esm/type.d.mts +122 -0
  163. package/dist/lib/esm/type.mjs +39 -0
  164. package/dist/lib/esm/typescript-lib-state.d.mts +56 -0
  165. package/dist/lib/esm/typescript-lib-state.mjs +40 -0
  166. package/dist/lib/esm/url.d.mts +74 -0
  167. package/dist/lib/esm/url.mjs +50 -0
  168. package/dist/lib/esm/value-provider.d.mts +29 -0
  169. package/dist/lib/esm/value-provider.mjs +18 -0
  170. package/dist/lib/esm/value-wrapper.d.mts +47 -0
  171. package/dist/lib/esm/value-wrapper.mjs +62 -0
  172. package/package.json +153 -13
  173. package/transformers/date-transformer/package.json +6 -0
  174. package/transformers/group-transformer/package.json +6 -0
  175. package/transformers/index/package.json +6 -0
  176. package/transformers/map-transformer/package.json +6 -0
  177. package/transformers/package.json +6 -0
  178. package/transformers/set-transformer/package.json +6 -0
  179. package/transformers/skip-private-property-transformer/package.json +6 -0
  180. package/transformers/transformer/package.json +6 -0
  181. package/transformers/two-way-map-transformer/package.json +6 -0
  182. package/transformers/typed-transformer/package.json +6 -0
@@ -0,0 +1,463 @@
1
+ /*
2
+ THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
3
+ if you want to view the source, please visit the github repository of this plugin
4
+ */
5
+
6
+ "use strict";
7
+ var __defProp = Object.defineProperty;
8
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
9
+ var __getOwnPropNames = Object.getOwnPropertyNames;
10
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
11
+ var __export = (target, all) => {
12
+ for (var name in all)
13
+ __defProp(target, name, { get: all[name], enumerable: true });
14
+ };
15
+ var __copyProps = (to, from, except, desc) => {
16
+ if (from && typeof from === "object" || typeof from === "function") {
17
+ for (let key of __getOwnPropNames(from))
18
+ if (!__hasOwnProp.call(to, key) && key !== except)
19
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
20
+ }
21
+ return to;
22
+ };
23
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
24
+ var async_exports = {};
25
+ __export(async_exports, {
26
+ addErrorHandler: () => addErrorHandler,
27
+ asyncFilter: () => asyncFilter,
28
+ asyncFilterInPlace: () => asyncFilterInPlace,
29
+ asyncFlatMap: () => asyncFlatMap,
30
+ asyncMap: () => asyncMap,
31
+ chain: () => chain,
32
+ convertAsyncToSync: () => convertAsyncToSync,
33
+ convertSyncToAsync: () => convertSyncToAsync,
34
+ handleSilentError: () => handleSilentError,
35
+ ignoreError: () => ignoreError,
36
+ invokeAsyncSafely: () => invokeAsyncSafely,
37
+ invokeAsyncSafelyAfterDelay: () => invokeAsyncSafelyAfterDelay,
38
+ marksAsTerminateRetry: () => marksAsTerminateRetry,
39
+ neverEnds: () => neverEnds,
40
+ nextTickAsync: () => nextTickAsync,
41
+ normalizePromisable: () => normalizePromisable,
42
+ promiseAllAsyncFnsSequentially: () => promiseAllAsyncFnsSequentially,
43
+ promiseAllSequentially: () => promiseAllSequentially,
44
+ queueMicrotaskAsync: () => queueMicrotaskAsync,
45
+ requestAnimationFrameAsync: () => requestAnimationFrameAsync,
46
+ retryWithTimeout: () => retryWithTimeout,
47
+ runWithTimeout: () => runWithTimeout,
48
+ setImmediateAsync: () => setImmediateAsync,
49
+ setTimeoutAsync: () => setTimeoutAsync,
50
+ sleep: () => sleep,
51
+ timeout: () => timeout,
52
+ toArray: () => toArray
53
+ });
54
+ module.exports = __toCommonJS(async_exports);
55
+ var import_abort_controller = require('./abort-controller.cjs');
56
+ var import_async_operation_hook = require('./async-operation-hook.cjs');
57
+ var import_debug = require('./debug.cjs');
58
+ var import_error = require('./error.cjs');
59
+ var import_function = require('./function.cjs');
60
+ var import_object_utils = require('./object-utils.cjs');
61
+ var import_type_guards = require('./type-guards.cjs');
62
+ async function addErrorHandler(asyncFunction, stackTrace) {
63
+ stackTrace ??= (0, import_error.getStackTrace)(1);
64
+ const wasScheduledWithinIgnoreContext = (0, import_error.isAsyncErrorIgnoreContextActive)();
65
+ try {
66
+ await asyncFunction();
67
+ } catch (asyncError) {
68
+ const wrappedError = new import_error.CustomStackTraceError({
69
+ cause: asyncError,
70
+ message: import_error.ASYNC_WRAPPER_ERROR_MESSAGE,
71
+ stackTrace
72
+ });
73
+ if (handleSilentError(wrappedError)) {
74
+ return;
75
+ }
76
+ (0, import_error.emitAsyncErrorEvent)(wrappedError, wasScheduledWithinIgnoreContext);
77
+ }
78
+ }
79
+ async function asyncFilter(array, predicate) {
80
+ const ans = [];
81
+ const length = array.length;
82
+ for (let index = 0; index < length; index++) {
83
+ if (!Object.hasOwn(array, index)) {
84
+ continue;
85
+ }
86
+ const item = array[index];
87
+ if (await predicate(item, index, array)) {
88
+ ans.push(item);
89
+ }
90
+ }
91
+ return ans;
92
+ }
93
+ async function asyncFilterInPlace(array, predicate) {
94
+ const length = array.length;
95
+ let writeIndex = 0;
96
+ for (let readIndex = 0; readIndex < length; readIndex++) {
97
+ if (!Object.hasOwn(array, readIndex)) {
98
+ continue;
99
+ }
100
+ const current = array[readIndex];
101
+ if (await predicate(current, readIndex, array)) {
102
+ array[writeIndex++] = current;
103
+ }
104
+ }
105
+ array.length = writeIndex;
106
+ }
107
+ async function asyncFlatMap(array, callback) {
108
+ const nestedResults = await asyncMap(array, callback);
109
+ return nestedResults.flat();
110
+ }
111
+ async function asyncMap(array, callback) {
112
+ return await promiseAllSequentially(array.map(callback));
113
+ }
114
+ function convertAsyncToSync(asyncFunction, stackTrace) {
115
+ stackTrace ??= (0, import_error.getStackTrace)(1);
116
+ return (...$arguments) => {
117
+ (0, import_type_guards.assertNonNullable)(stackTrace);
118
+ const innerStackTrace = (0, import_error.getStackTrace)(1);
119
+ stackTrace += `
120
+ at --- convertAsyncToSync --- (0)
121
+ ${innerStackTrace}`;
122
+ invokeAsyncSafely(() => asyncFunction(...$arguments), stackTrace);
123
+ };
124
+ }
125
+ function convertSyncToAsync(syncFunction) {
126
+ return async (...$arguments) => {
127
+ await (0, import_function.noopAsync)();
128
+ return syncFunction(...$arguments);
129
+ };
130
+ }
131
+ function handleSilentError(error) {
132
+ let cause = error;
133
+ while (!(cause instanceof import_error.SilentError)) {
134
+ if (!(cause instanceof Error)) {
135
+ return false;
136
+ }
137
+ cause = cause.cause;
138
+ }
139
+ (0, import_debug.getLibDebugger)("Async:handleSilentError")(error);
140
+ return true;
141
+ }
142
+ async function ignoreError(promise, fallbackValue) {
143
+ const ignoreErrorDebugger = (0, import_debug.getLibDebugger)("Async:ignoreError");
144
+ const stackTrace = (0, import_error.getStackTrace)(1);
145
+ try {
146
+ return await promise;
147
+ } catch (error) {
148
+ ignoreErrorDebugger(
149
+ "Ignored error",
150
+ new import_error.CustomStackTraceError({
151
+ cause: error,
152
+ message: "Ignored error",
153
+ stackTrace
154
+ })
155
+ );
156
+ return fallbackValue;
157
+ }
158
+ }
159
+ function invokeAsyncSafely(asyncFunction, stackTrace) {
160
+ stackTrace ??= (0, import_error.getStackTrace)(1);
161
+ let result;
162
+ try {
163
+ result = asyncFunction();
164
+ } catch (error) {
165
+ (0, import_async_operation_hook.notifyAsyncOperationStarted)(addErrorHandler(() => Promise.reject(error), stackTrace));
166
+ }
167
+ if (result instanceof Promise) {
168
+ (0, import_async_operation_hook.notifyAsyncOperationStarted)(addErrorHandler(() => result, stackTrace));
169
+ }
170
+ }
171
+ function invokeAsyncSafelyAfterDelay(params) {
172
+ const {
173
+ asyncFunction,
174
+ delayInMilliseconds = 0
175
+ } = params;
176
+ const abortSignal = params.abortSignal ?? (0, import_abort_controller.abortSignalNever)();
177
+ abortSignal.throwIfAborted();
178
+ const stackTrace = params.stackTrace ?? (0, import_error.getStackTrace)(1);
179
+ invokeAsyncSafely(async () => {
180
+ await sleep({ abortSignal, milliseconds: delayInMilliseconds, shouldThrowOnAbort: true });
181
+ await asyncFunction(abortSignal);
182
+ }, stackTrace);
183
+ }
184
+ async function promiseAllAsyncFnsSequentially(asyncFns) {
185
+ const results = [];
186
+ for (const asyncFunction of asyncFns) {
187
+ results.push(await asyncFunction());
188
+ }
189
+ return results;
190
+ }
191
+ async function promiseAllSequentially(promises) {
192
+ return await promiseAllAsyncFnsSequentially(promises.map((promise) => () => promise));
193
+ }
194
+ const terminateRetryErrors = /* @__PURE__ */ new WeakSet();
195
+ function chain(chainPromise, promisableFunction) {
196
+ let nextChainPromise = chainPromise;
197
+ if (chainPromise) {
198
+ nextChainPromise = chainPromise.then(() => promisableFunction() ?? void 0);
199
+ } else {
200
+ const promisable = promisableFunction();
201
+ if (promisable) {
202
+ nextChainPromise = promisable instanceof Promise ? promisable : Promise.resolve(promisable);
203
+ }
204
+ }
205
+ nextChainPromise?.catch(import_function.noop);
206
+ return nextChainPromise;
207
+ }
208
+ function marksAsTerminateRetry(error) {
209
+ terminateRetryErrors.add(error);
210
+ }
211
+ async function neverEnds() {
212
+ await new Promise(() => {
213
+ (0, import_function.noop)();
214
+ });
215
+ (0, import_type_guards.assert)(false, "Should never happen");
216
+ }
217
+ async function nextTickAsync() {
218
+ return new Promise((resolve) => {
219
+ queueMicrotask(() => {
220
+ resolve();
221
+ });
222
+ });
223
+ }
224
+ function normalizePromisable(promisable) {
225
+ if (!promisable) {
226
+ return promisable;
227
+ }
228
+ if (promisable instanceof Promise) {
229
+ return promisable;
230
+ }
231
+ return promisable.then ? Promise.resolve(promisable) : promisable;
232
+ }
233
+ async function queueMicrotaskAsync() {
234
+ return new Promise((resolve) => {
235
+ queueMicrotask(() => {
236
+ resolve();
237
+ });
238
+ });
239
+ }
240
+ async function requestAnimationFrameAsync(fallbackTimeoutInMilliseconds) {
241
+ const requestAnimationFrameAsyncPromise = new Promise((resolve) => {
242
+ window.requestAnimationFrame(() => {
243
+ resolve();
244
+ });
245
+ });
246
+ const DEFAULT_FALLBACK_TIMEOUT_IN_MILLISECONDS = 100;
247
+ fallbackTimeoutInMilliseconds ??= DEFAULT_FALLBACK_TIMEOUT_IN_MILLISECONDS;
248
+ return Promise.race([requestAnimationFrameAsyncPromise, fallbackTimeoutInMilliseconds > 0 ? sleep({ milliseconds: fallbackTimeoutInMilliseconds }) : neverEnds()]);
249
+ }
250
+ async function retryWithTimeout(params) {
251
+ const retryWithTimeoutDebugger = (0, import_debug.getLibDebugger)("Async:retryWithTimeout");
252
+ const stackTrace = params.stackTrace ?? (0, import_error.getStackTrace)(1);
253
+ const DEFAULT_RETRY_OPTIONS = {
254
+ // eslint-disable-next-line no-magic-numbers -- Extracting magic number as a constant would be repetitive, as the value is used only once and its name would be the same as the property.
255
+ retryDelayInMilliseconds: 100,
256
+ shouldRetryOnError: false,
257
+ // eslint-disable-next-line no-magic-numbers -- Extracting magic number as a constant would be repetitive, as the value is used only once and its name would be the same as the property.
258
+ timeoutInMilliseconds: 5e3
259
+ };
260
+ const fullOptions = { ...DEFAULT_RETRY_OPTIONS, ...params.retryOptions };
261
+ fullOptions.abortSignal?.throwIfAborted();
262
+ await runWithTimeout((0, import_object_utils.normalizeOptionalProperties)({
263
+ context: { operationName: params.operationName ?? "", retryFunction: params.operationFunction },
264
+ onTimeout: params.onTimeout,
265
+ async operationFunction(abortSignal) {
266
+ const combinedAbortSignal = (0, import_abort_controller.abortSignalAny)(fullOptions.abortSignal, abortSignal);
267
+ combinedAbortSignal.throwIfAborted();
268
+ let attempt = 0;
269
+ while (!combinedAbortSignal.aborted) {
270
+ attempt++;
271
+ let isSuccess;
272
+ try {
273
+ isSuccess = await params.operationFunction(combinedAbortSignal);
274
+ } catch (error) {
275
+ if (combinedAbortSignal.aborted || !fullOptions.shouldRetryOnError || terminateRetryErrors.has(error)) {
276
+ throw new import_error.CustomStackTraceError({
277
+ cause: error,
278
+ message: "retryWithTimeout failed",
279
+ stackTrace
280
+ });
281
+ }
282
+ (0, import_error.printError)(error);
283
+ isSuccess = false;
284
+ }
285
+ if (isSuccess) {
286
+ (0, import_debug.printWithStackTrace)({
287
+ $arguments: [{
288
+ operationFunction: params.operationFunction,
289
+ operationName: params.operationName ?? ""
290
+ }],
291
+ debuggerInstance: retryWithTimeoutDebugger,
292
+ message: `Retry completed successfully after ${String(attempt)} attempts`,
293
+ stackTrace
294
+ });
295
+ return;
296
+ }
297
+ (0, import_debug.printWithStackTrace)({
298
+ $arguments: [{
299
+ operationFunction: params.operationFunction,
300
+ operationName: params.operationName ?? ""
301
+ }],
302
+ debuggerInstance: retryWithTimeoutDebugger,
303
+ message: `Retry attempt ${String(attempt)} completed unsuccessfully. Trying again in ${String(fullOptions.retryDelayInMilliseconds)} milliseconds`,
304
+ stackTrace
305
+ });
306
+ await sleep({ abortSignal, milliseconds: fullOptions.retryDelayInMilliseconds });
307
+ }
308
+ },
309
+ operationName: params.operationName ?? "",
310
+ stackTrace,
311
+ timeoutInMilliseconds: fullOptions.timeoutInMilliseconds
312
+ }));
313
+ }
314
+ async function runWithTimeout(params) {
315
+ const stackTrace = params.stackTrace ?? (0, import_error.getStackTrace)(1);
316
+ const startTime = performance.now();
317
+ const runAbortController = new AbortController();
318
+ const timeoutAbortController = new AbortController();
319
+ let result = null;
320
+ let hasResult = false;
321
+ let isCompleted = false;
322
+ const runWithTimeoutDebugger = (0, import_debug.getLibDebugger)("Async:runWithTimeout");
323
+ const onTimeout = params.onTimeout ?? defaultOnTimeout;
324
+ await Promise.race([run(), innerTimeout()]);
325
+ if (hasResult && !runAbortController.signal.aborted) {
326
+ return result;
327
+ }
328
+ throw new import_error.CustomStackTraceError({
329
+ cause: runAbortController.signal.reason,
330
+ message: "Run with timeout failed",
331
+ stackTrace
332
+ });
333
+ async function run() {
334
+ try {
335
+ result = await params.operationFunction(runAbortController.signal);
336
+ const duration = Math.trunc(performance.now() - startTime);
337
+ (0, import_debug.printWithStackTrace)({
338
+ $arguments: [{
339
+ context: params.context,
340
+ operationFunction: params.operationFunction,
341
+ operationName: params.operationName ?? ""
342
+ }],
343
+ debuggerInstance: runWithTimeoutDebugger,
344
+ message: `Execution time: ${String(duration)} milliseconds`,
345
+ stackTrace
346
+ });
347
+ hasResult = true;
348
+ } catch (error) {
349
+ runAbortController.abort(error);
350
+ } finally {
351
+ isCompleted = true;
352
+ timeoutAbortController.abort(new Error("Completed"));
353
+ }
354
+ }
355
+ async function innerTimeout() {
356
+ await sleep({ abortSignal: timeoutAbortController.signal, milliseconds: params.timeoutInMilliseconds });
357
+ if (isCompleted) {
358
+ return;
359
+ }
360
+ const duration = Math.trunc(performance.now() - startTime);
361
+ (0, import_debug.printWithStackTrace)({
362
+ $arguments: [{
363
+ context: params.context,
364
+ operationFunction: params.operationFunction,
365
+ operationName: params.operationName ?? ""
366
+ }],
367
+ debuggerInstance: runWithTimeoutDebugger,
368
+ message: `Timed out after ${String(duration)} milliseconds`,
369
+ stackTrace
370
+ });
371
+ const timeoutContext = (0, import_object_utils.normalizeOptionalProperties)({
372
+ duration,
373
+ onOperationCompleted(callback) {
374
+ timeoutAbortController.signal.addEventListener("abort", callback);
375
+ },
376
+ operationName: params.operationName ?? "",
377
+ terminateOperation() {
378
+ const error = new Error(`Timed out after ${String(duration)} milliseconds`);
379
+ runAbortController.abort(error);
380
+ timeoutAbortController.abort(error);
381
+ }
382
+ });
383
+ onTimeout(timeoutContext);
384
+ await (0, import_abort_controller.waitForAbort)(timeoutAbortController.signal);
385
+ }
386
+ }
387
+ async function setImmediateAsync() {
388
+ return new Promise((resolve) => {
389
+ setImmediate(() => {
390
+ resolve();
391
+ });
392
+ });
393
+ }
394
+ async function setTimeoutAsync(delay) {
395
+ await new Promise((resolve) => {
396
+ window.setTimeout(resolve, delay);
397
+ });
398
+ }
399
+ async function sleep(params) {
400
+ const {
401
+ abortSignal,
402
+ milliseconds,
403
+ shouldThrowOnAbort
404
+ } = params;
405
+ await (0, import_abort_controller.waitForAbort)((0, import_abort_controller.abortSignalAny)(abortSignal, (0, import_abort_controller.abortSignalTimeout)(milliseconds)));
406
+ if (shouldThrowOnAbort) {
407
+ abortSignal?.throwIfAborted();
408
+ }
409
+ }
410
+ async function timeout(params) {
411
+ const {
412
+ abortSignal,
413
+ shouldThrowOnAbort,
414
+ timeoutInMilliseconds
415
+ } = params;
416
+ await sleep((0, import_object_utils.normalizeOptionalProperties)({
417
+ abortSignal,
418
+ milliseconds: timeoutInMilliseconds,
419
+ shouldThrowOnAbort
420
+ }));
421
+ throw new Error(`Timed out in ${String(timeoutInMilliseconds)} milliseconds`);
422
+ }
423
+ async function toArray(iter) {
424
+ const array = [];
425
+ for await (const item of iter) {
426
+ array.push(item);
427
+ }
428
+ return array;
429
+ }
430
+ function defaultOnTimeout(context) {
431
+ context.terminateOperation();
432
+ }
433
+ // Annotate the CommonJS export names for ESM import in node:
434
+ 0 && (module.exports = {
435
+ addErrorHandler,
436
+ asyncFilter,
437
+ asyncFilterInPlace,
438
+ asyncFlatMap,
439
+ asyncMap,
440
+ chain,
441
+ convertAsyncToSync,
442
+ convertSyncToAsync,
443
+ handleSilentError,
444
+ ignoreError,
445
+ invokeAsyncSafely,
446
+ invokeAsyncSafelyAfterDelay,
447
+ marksAsTerminateRetry,
448
+ neverEnds,
449
+ nextTickAsync,
450
+ normalizePromisable,
451
+ promiseAllAsyncFnsSequentially,
452
+ promiseAllSequentially,
453
+ queueMicrotaskAsync,
454
+ requestAnimationFrameAsync,
455
+ retryWithTimeout,
456
+ runWithTimeout,
457
+ setImmediateAsync,
458
+ setTimeoutAsync,
459
+ sleep,
460
+ timeout,
461
+ toArray
462
+ });
463
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2FzeW5jLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIvKipcbiAqIEBmaWxlXG4gKlxuICogQ29udGFpbnMgdXRpbGl0eSBmdW5jdGlvbnMgZm9yIGFzeW5jaHJvbm91cyBvcGVyYXRpb25zLlxuICovXG5cbmltcG9ydCB0eXBlIHsgUHJvbWlzYWJsZSB9IGZyb20gJ3R5cGUtZmVzdCc7XG5cbmltcG9ydCB0eXBlIHtcbiAgR2VuZXJpY0FzeW5jRnVuY3Rpb24sXG4gIEdlbmVyaWNGdW5jdGlvbixcbiAgR2VuZXJpY1ZvaWRGdW5jdGlvblxufSBmcm9tICcuL2Z1bmN0aW9uLnRzJztcblxuaW1wb3J0IHtcbiAgYWJvcnRTaWduYWxBbnksXG4gIGFib3J0U2lnbmFsTmV2ZXIsXG4gIGFib3J0U2lnbmFsVGltZW91dCxcbiAgd2FpdEZvckFib3J0XG59IGZyb20gJy4vYWJvcnQtY29udHJvbGxlci50cyc7XG5pbXBvcnQgeyBub3RpZnlBc3luY09wZXJhdGlvblN0YXJ0ZWQgfSBmcm9tICcuL2FzeW5jLW9wZXJhdGlvbi1ob29rLnRzJztcbmltcG9ydCB7XG4gIGdldExpYkRlYnVnZ2VyLFxuICBwcmludFdpdGhTdGFja1RyYWNlXG59IGZyb20gJy4vZGVidWcudHMnO1xuaW1wb3J0IHtcbiAgQVNZTkNfV1JBUFBFUl9FUlJPUl9NRVNTQUdFLFxuICBDdXN0b21TdGFja1RyYWNlRXJyb3IsXG4gIGVtaXRBc3luY0Vycm9yRXZlbnQsXG4gIGdldFN0YWNrVHJhY2UsXG4gIGlzQXN5bmNFcnJvcklnbm9yZUNvbnRleHRBY3RpdmUsXG4gIHByaW50RXJyb3IsXG4gIFNpbGVudEVycm9yXG59IGZyb20gJy4vZXJyb3IudHMnO1xuaW1wb3J0IHtcbiAgbm9vcCxcbiAgbm9vcEFzeW5jXG59IGZyb20gJy4vZnVuY3Rpb24udHMnO1xuaW1wb3J0IHsgbm9ybWFsaXplT3B0aW9uYWxQcm9wZXJ0aWVzIH0gZnJvbSAnLi9vYmplY3QtdXRpbHMudHMnO1xuaW1wb3J0IHtcbiAgYXNzZXJ0LFxuICBhc3NlcnROb25OdWxsYWJsZVxufSBmcm9tICcuL3R5cGUtZ3VhcmRzLnRzJztcblxuLyoqXG4gKiBQYXJhbWV0ZXJzIGZvciB7QGxpbmsgaW52b2tlQXN5bmNTYWZlbHlBZnRlckRlbGF5fS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBJbnZva2VBc3luY1NhZmVseUFmdGVyRGVsYXlQYXJhbXMge1xuICAvKipcbiAgICogVGhlIGFib3J0IHNpZ25hbCB0byBsaXN0ZW4gdG8uXG4gICAqL1xuICByZWFkb25seSBhYm9ydFNpZ25hbD86IEFib3J0U2lnbmFsO1xuXG4gIC8qKlxuICAgKiBUaGUgYXN5bmNocm9ub3VzIGZ1bmN0aW9uIHRvIGludm9rZS5cbiAgICpcbiAgICogQHBhcmFtIGFib3J0U2lnbmFsIC0gVGhlIGFib3J0IHNpZ25hbCB0byBsaXN0ZW4gdG8uXG4gICAqL1xuICByZWFkb25seSBhc3luY0Z1bmN0aW9uOiAoYWJvcnRTaWduYWw6IEFib3J0U2lnbmFsKSA9PiBQcm9taXNhYmxlPHZvaWQ+O1xuXG4gIC8qKlxuICAgKiBUaGUgZGVsYXkgaW4gbWlsbGlzZWNvbmRzLlxuICAgKlxuICAgKiBAZGVmYXVsdCBgMGBcbiAgICovXG4gIHJlYWRvbmx5IGRlbGF5SW5NaWxsaXNlY29uZHM/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFRoZSBzdGFjayB0cmFjZSBvZiB0aGUgc291cmNlIGZ1bmN0aW9uLlxuICAgKi9cbiAgcmVhZG9ubHkgc3RhY2tUcmFjZT86IHN0cmluZztcbn1cblxuLyoqXG4gKiBBIHR5cGUgcmVwcmVzZW50aW5nIGEgZnVuY3Rpb24gdGhhdCByZXNvbHZlcyBhIHtAbGluayBQcm9taXNlfS5cbiAqXG4gKiBAdHlwZVBhcmFtIFQgLSBUaGUgdHlwZSBvZiB0aGUgdmFsdWUuXG4gKi9cbmV4cG9ydCB0eXBlIFByb21pc2VSZXNvbHZlPFQ+ID0gdW5kZWZpbmVkIGV4dGVuZHMgVCA/ICh2YWx1ZT86IFByb21pc2VMaWtlPFQ+IHwgVCkgPT4gdm9pZFxuICA6ICh2YWx1ZTogUHJvbWlzZUxpa2U8VD4gfCBUKSA9PiB2b2lkO1xuXG4vKipcbiAqIE9wdGlvbnMgZm9yIHtAbGluayByZXRyeVdpdGhUaW1lb3V0fS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBSZXRyeU9wdGlvbnMge1xuICAvKipcbiAgICogQSBhYm9ydCBzaWduYWwgdG8gY2FuY2VsIHRoZSByZXRyeSBvcGVyYXRpb24uXG4gICAqL1xuICByZWFkb25seSBhYm9ydFNpZ25hbD86IEFib3J0U2lnbmFsO1xuXG4gIC8qKlxuICAgKiBBIGRlbGF5IGluIG1pbGxpc2Vjb25kcyBiZXR3ZWVuIHJldHJ5IGF0dGVtcHRzLlxuICAgKlxuICAgKiBAZGVmYXVsdCBgMTAwYFxuICAgKi9cbiAgcmVhZG9ubHkgcmV0cnlEZWxheUluTWlsbGlzZWNvbmRzPzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIHJldHJ5IHRoZSBmdW5jdGlvbiBvbiBlcnJvci5cbiAgICpcbiAgICogQGRlZmF1bHQgYGZhbHNlYFxuICAgKi9cbiAgcmVhZG9ubHkgc2hvdWxkUmV0cnlPbkVycm9yPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogQSBtYXhpbXVtIHRpbWUgaW4gbWlsbGlzZWNvbmRzIHRvIHdhaXQgYmVmb3JlIGdpdmluZyB1cCBvbiByZXRyeWluZy5cbiAgICpcbiAgICogQGRlZmF1bHQgYDUwMDBgXG4gICAqL1xuICByZWFkb25seSB0aW1lb3V0SW5NaWxsaXNlY29uZHM/OiBudW1iZXI7XG59XG5cbi8qKlxuICogQWRkcyBhbiBlcnJvciBoYW5kbGVyIHRvIGEge0BsaW5rIFByb21pc2V9IHRoYXQgY2F0Y2hlcyBhbnkgZXJyb3JzIGFuZCBlbWl0cyBhbiBhc3luYyBlcnJvciBldmVudC5cbiAqXG4gKiBAcGFyYW0gYXN5bmNGdW5jdGlvbiAtIFRoZSBhc3luY2hyb25vdXMgZnVuY3Rpb24gdG8gYWRkIGFuIGVycm9yIGhhbmRsZXIgdG8uXG4gKiBAcGFyYW0gc3RhY2tUcmFjZSAtIFRoZSBzdGFjayB0cmFjZSBvZiB0aGUgc291cmNlIGZ1bmN0aW9uLlxuICogQHJldHVybnMgQSB7QGxpbmsgUHJvbWlzZX0gdGhhdCByZXNvbHZlcyB3aGVuIHRoZSBhc3luY2hyb25vdXMgZnVuY3Rpb24gY29tcGxldGVzIG9yIGVtaXRzIGFzeW5jIGVycm9yIGV2ZW50LlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gYWRkRXJyb3JIYW5kbGVyKGFzeW5jRnVuY3Rpb246ICgpID0+IFByb21pc2U8dW5rbm93bj4sIHN0YWNrVHJhY2U/OiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgc3RhY2tUcmFjZSA/Pz0gZ2V0U3RhY2tUcmFjZSgxKTtcbiAgLy8gQ2FwdHVyZSB0aGUgaWdub3JlIGNvbnRleHQgc3luY2hyb25vdXNseSBhdCBzY2hlZHVsZSB0aW1lLCBzbyBhIGRlZmVycmVkIHJlamVjdGlvbiBzZXR0bGluZyBhZnRlciB0aGUgc2NvcGUgZXhpdHMgaXMgc3RpbGwgaWdub3JlZC5cbiAgY29uc3Qgd2FzU2NoZWR1bGVkV2l0aGluSWdub3JlQ29udGV4dCA9IGlzQXN5bmNFcnJvcklnbm9yZUNvbnRleHRBY3RpdmUoKTtcbiAgdHJ5IHtcbiAgICBhd2FpdCBhc3luY0Z1bmN0aW9uKCk7XG4gIH0gY2F0Y2ggKGFzeW5jRXJyb3IpIHtcbiAgICBjb25zdCB3cmFwcGVkRXJyb3IgPSBuZXcgQ3VzdG9tU3RhY2tUcmFjZUVycm9yKHtcbiAgICAgIGNhdXNlOiBhc3luY0Vycm9yLFxuICAgICAgbWVzc2FnZTogQVNZTkNfV1JBUFBFUl9FUlJPUl9NRVNTQUdFLFxuICAgICAgc3RhY2tUcmFjZVxuICAgIH0pO1xuICAgIGlmIChoYW5kbGVTaWxlbnRFcnJvcih3cmFwcGVkRXJyb3IpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGVtaXRBc3luY0Vycm9yRXZlbnQod3JhcHBlZEVycm9yLCB3YXNTY2hlZHVsZWRXaXRoaW5JZ25vcmVDb250ZXh0KTtcbiAgfVxufVxuXG4vKipcbiAqIEZpbHRlcnMgYW4gYXJyYXkgYXN5bmNocm9ub3VzbHksIGtlZXBpbmcgb25seSB0aGUgZWxlbWVudHMgdGhhdCBzYXRpc2Z5IHRoZSBwcm92aWRlZCBwcmVkaWNhdGUgZnVuY3Rpb24uXG4gKlxuICogQHR5cGVQYXJhbSBUIC0gVGhlIHR5cGUgb2YgZWxlbWVudHMgaW4gdGhlIGlucHV0IGFycmF5LlxuICogQHBhcmFtIGFycmF5IC0gVGhlIGFycmF5IHRvIGZpbHRlci5cbiAqIEBwYXJhbSBwcmVkaWNhdGUgLSBUaGUgcHJlZGljYXRlIGZ1bmN0aW9uIHRvIHRlc3QgZWFjaCBlbGVtZW50LlxuICogQHJldHVybnMgQSB7QGxpbmsgUHJvbWlzZX0gdGhhdCByZXNvbHZlcyB3aXRoIGFuIGFycmF5IG9mIGVsZW1lbnRzIHRoYXQgc2F0aXNmeSB0aGUgcHJlZGljYXRlIGZ1bmN0aW9uLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gYXN5bmNGaWx0ZXI8VD4oYXJyYXk6IFRbXSwgcHJlZGljYXRlOiAodmFsdWU6IFQsIGluZGV4OiBudW1iZXIsIGFycmF5OiBUW10pID0+IFByb21pc2FibGU8Ym9vbGVhbj4pOiBQcm9taXNlPFRbXT4ge1xuICBjb25zdCBhbnM6IFRbXSA9IFtdO1xuXG4gIGNvbnN0IGxlbmd0aCA9IGFycmF5Lmxlbmd0aDtcbiAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IGxlbmd0aDsgaW5kZXgrKykge1xuICAgIGlmICghT2JqZWN0Lmhhc093bihhcnJheSwgaW5kZXgpKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBjb25zdCBpdGVtID0gYXJyYXlbaW5kZXhdIGFzIFQ7XG4gICAgaWYgKGF3YWl0IHByZWRpY2F0ZShpdGVtLCBpbmRleCwgYXJyYXkpKSB7XG4gICAgICBhbnMucHVzaChpdGVtKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gYW5zO1xufVxuXG4vKipcbiAqIEZpbHRlcnMgYW4gYXJyYXkgYXN5bmNocm9ub3VzbHkgaW4gcGxhY2UsIGtlZXBpbmcgb25seSB0aGUgZWxlbWVudHMgdGhhdCBzYXRpc2Z5IHRoZSBwcm92aWRlZCBwcmVkaWNhdGUgZnVuY3Rpb24uXG4gKlxuICogQHR5cGVQYXJhbSBUIC0gVGhlIHR5cGUgb2YgZWxlbWVudHMgaW4gdGhlIGlucHV0IGFycmF5LlxuICogQHBhcmFtIGFycmF5IC0gVGhlIGFycmF5IHRvIGZpbHRlci5cbiAqIEBwYXJhbSBwcmVkaWNhdGUgLSBUaGUgcHJlZGljYXRlIGZ1bmN0aW9uIHRvIHRlc3QgZWFjaCBlbGVtZW50LlxuICogQHJldHVybnMgQSB7QGxpbmsgUHJvbWlzZX0gdGhhdCByZXNvbHZlcyB3aGVuIHRoZSBhcnJheSBpcyBmaWx0ZXJlZC5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGFzeW5jRmlsdGVySW5QbGFjZTxUPihhcnJheTogVFtdLCBwcmVkaWNhdGU6ICh2YWx1ZTogVCwgaW5kZXg6IG51bWJlciwgYXJyYXk6IFRbXSkgPT4gUHJvbWlzYWJsZTxib29sZWFuPik6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCBsZW5ndGggPSBhcnJheS5sZW5ndGg7XG4gIGxldCB3cml0ZUluZGV4ID0gMDtcbiAgZm9yIChsZXQgcmVhZEluZGV4ID0gMDsgcmVhZEluZGV4IDwgbGVuZ3RoOyByZWFkSW5kZXgrKykge1xuICAgIGlmICghT2JqZWN0Lmhhc093bihhcnJheSwgcmVhZEluZGV4KSkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgY29uc3QgY3VycmVudCA9IGFycmF5W3JlYWRJbmRleF0gYXMgVDtcbiAgICBpZiAoYXdhaXQgcHJlZGljYXRlKGN1cnJlbnQsIHJlYWRJbmRleCwgYXJyYXkpKSB7XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcmVxdWlyZS1hdG9taWMtdXBkYXRlcyAtLSBZZXMsIGl0IGlzIGEgcG90ZW50aWFsIHJhY2UgY29uZGl0aW9uLCBidXQgSSBkb24ndCBhbiBlbGVnYW50IHdheSB0byBmaXggaXQuXG4gICAgICBhcnJheVt3cml0ZUluZGV4KytdID0gY3VycmVudDtcbiAgICB9XG4gIH1cbiAgYXJyYXkubGVuZ3RoID0gd3JpdGVJbmRleDtcbn1cblxuLyoqXG4gKiBNYXBzIG92ZXIgYW4gYXJyYXkgYXN5bmNocm9ub3VzbHksIGFwcGx5aW5nIHRoZSBwcm92aWRlZCBjYWxsYmFjayBmdW5jdGlvbiB0byBlYWNoIGVsZW1lbnQsIGFuZCB0aGVuIGZsYXR0ZW5zIHRoZSByZXN1bHRzIGludG8gYSBzaW5nbGUgYXJyYXkuXG4gKlxuICogQHR5cGVQYXJhbSBUIC0gVGhlIHR5cGUgb2YgZWxlbWVudHMgaW4gdGhlIGlucHV0IGFycmF5LlxuICogQHR5cGVQYXJhbSBVIC0gVGhlIHR5cGUgb2YgZWxlbWVudHMgaW4gdGhlIG91dHB1dCBhcnJheS5cbiAqIEBwYXJhbSBhcnJheSAtIFRoZSBhcnJheSB0byBtYXAgb3ZlciBhbmQgZmxhdHRlbi5cbiAqIEBwYXJhbSBjYWxsYmFjayAtIFRoZSBjYWxsYmFjayBmdW5jdGlvbiB0byBhcHBseSB0byBlYWNoIGVsZW1lbnQuXG4gKiBAcmV0dXJucyBBIHtAbGluayBQcm9taXNlfSB0aGF0IHJlc29sdmVzIHdpdGggYSBmbGF0dGVuZWQgYXJyYXkgb2YgdGhlIHJlc3VsdHMgb2YgdGhlIGNhbGxiYWNrIGZ1bmN0aW9uLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gYXN5bmNGbGF0TWFwPFQsIFU+KGFycmF5OiBUW10sIGNhbGxiYWNrOiAodmFsdWU6IFQsIGluZGV4OiBudW1iZXIsIGFycmF5OiBUW10pID0+IFByb21pc2FibGU8VVtdPik6IFByb21pc2U8VVtdPiB7XG4gIGNvbnN0IG5lc3RlZFJlc3VsdHMgPSBhd2FpdCBhc3luY01hcChhcnJheSwgY2FsbGJhY2spO1xuICByZXR1cm4gbmVzdGVkUmVzdWx0cy5mbGF0KCk7XG59XG5cbi8qKlxuICogTWFwcyBvdmVyIGFuIGFycmF5IGFzeW5jaHJvbm91c2x5LCBhcHBseWluZyB0aGUgcHJvdmlkZWQgY2FsbGJhY2sgZnVuY3Rpb24gdG8gZWFjaCBlbGVtZW50LlxuICpcbiAqIEB0eXBlUGFyYW0gVCAtIFRoZSB0eXBlIG9mIGVsZW1lbnRzIGluIHRoZSBpbnB1dCBhcnJheS5cbiAqIEB0eXBlUGFyYW0gVSAtIFRoZSB0eXBlIG9mIGVsZW1lbnRzIGluIHRoZSBvdXRwdXQgYXJyYXkuXG4gKiBAcGFyYW0gYXJyYXkgLSBUaGUgYXJyYXkgdG8gbWFwIG92ZXIuXG4gKiBAcGFyYW0gY2FsbGJhY2sgLSBUaGUgY2FsbGJhY2sgZnVuY3Rpb24gdG8gYXBwbHkgdG8gZWFjaCBlbGVtZW50LlxuICogQHJldHVybnMgQSB7QGxpbmsgUHJvbWlzZX0gdGhhdCByZXNvbHZlcyB3aXRoIGFuIGFycmF5IG9mIHRoZSByZXN1bHRzIG9mIHRoZSBjYWxsYmFjayBmdW5jdGlvbi5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGFzeW5jTWFwPFQsIFU+KGFycmF5OiBUW10sIGNhbGxiYWNrOiAodmFsdWU6IFQsIGluZGV4OiBudW1iZXIsIGFycmF5OiBUW10pID0+IFByb21pc2FibGU8VT4pOiBQcm9taXNlPFVbXT4ge1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgdW5pY29ybi9uby1hcnJheS1jYWxsYmFjay1yZWZlcmVuY2UgLS0gUGFzc2luZyBgY2FsbGJhY2tgIHN0cmFpZ2h0IHRocm91Z2ggaXMgdGhlIGNvbnRyYWN0OiBpdCBpcyBkZWNsYXJlZCBhcyBgKHZhbHVlLCBpbmRleCwgYXJyYXkpYCBzbyB0aGF0IGl0IHJlY2VpdmVzIGV4YWN0bHkgd2hhdCBgQXJyYXkjbWFwYCBzdXBwbGllcy4gV3JhcHBpbmcgaXQgdG8gdGFrZSBvbmx5IHRoZSB2YWx1ZSB3b3VsZCBxdWlldGx5IHN0b3AgZm9yd2FyZGluZyB0aGUgb3RoZXIgdHdvLlxuICByZXR1cm4gYXdhaXQgcHJvbWlzZUFsbFNlcXVlbnRpYWxseShhcnJheS5tYXAoY2FsbGJhY2spKTtcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBhbiBhc3luY2hyb25vdXMgZnVuY3Rpb24gdG8gYSBzeW5jaHJvbm91cyBvbmUgYnkgYXV0b21hdGljYWxseSBoYW5kbGluZyB0aGUgUHJvbWlzZSByZWplY3Rpb24uXG4gKlxuICogQHR5cGVQYXJhbSBBcmd1bWVudHMgLSBUaGUgdHlwZXMgb2YgdGhlIGFyZ3VtZW50cyB0aGUgZnVuY3Rpb24gYWNjZXB0cy5cbiAqIEBwYXJhbSBhc3luY0Z1bmN0aW9uIC0gVGhlIGFzeW5jaHJvbm91cyBmdW5jdGlvbiB0byBjb252ZXJ0LlxuICogQHBhcmFtIHN0YWNrVHJhY2UgLSBUaGUgc3RhY2sgdHJhY2Ugb2YgdGhlIHNvdXJjZSBmdW5jdGlvbi5cbiAqIEByZXR1cm5zIEEgZnVuY3Rpb24gdGhhdCB3cmFwcyB0aGUgYXN5bmNocm9ub3VzIGZ1bmN0aW9uIGluIGEgc3luY2hyb25vdXMgaW50ZXJmYWNlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY29udmVydEFzeW5jVG9TeW5jPEFyZ3VtZW50cyBleHRlbmRzIHVua25vd25bXT4oYXN5bmNGdW5jdGlvbjogR2VuZXJpY0FzeW5jRnVuY3Rpb248QXJndW1lbnRzPiwgc3RhY2tUcmFjZT86IHN0cmluZyk6IEdlbmVyaWNWb2lkRnVuY3Rpb248QXJndW1lbnRzPiB7XG4gIHN0YWNrVHJhY2UgPz89IGdldFN0YWNrVHJhY2UoMSk7XG4gIHJldHVybiAoLi4uJGFyZ3VtZW50czogQXJndW1lbnRzKTogdm9pZCA9PiB7XG4gICAgYXNzZXJ0Tm9uTnVsbGFibGUoc3RhY2tUcmFjZSk7XG4gICAgY29uc3QgaW5uZXJTdGFja1RyYWNlID0gZ2V0U3RhY2tUcmFjZSgxKTtcbiAgICBzdGFja1RyYWNlICs9IGBcXG4gICAgYXQgLS0tIGNvbnZlcnRBc3luY1RvU3luYyAtLS0gKDApXFxuJHtpbm5lclN0YWNrVHJhY2V9YDtcbiAgICBpbnZva2VBc3luY1NhZmVseSgoKSA9PiBhc3luY0Z1bmN0aW9uKC4uLiRhcmd1bWVudHMpLCBzdGFja1RyYWNlKTtcbiAgfTtcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBhIHN5bmNocm9ub3VzIGZ1bmN0aW9uIHRvIGFuIGFzeW5jaHJvbm91cyBvbmUgYnkgd3JhcHBpbmcgaXQgaW4gYSB7QGxpbmsgUHJvbWlzZX0uXG4gKlxuICogQHR5cGVQYXJhbSBBcmd1bWVudHMgLSBUaGUgdHlwZXMgb2YgdGhlIGFyZ3VtZW50cyB0aGUgZnVuY3Rpb24gYWNjZXB0cy5cbiAqIEB0eXBlUGFyYW0gUmVzdWx0IC0gVGhlIHR5cGUgb2YgdGhlIGZ1bmN0aW9uJ3MgcmV0dXJuIHZhbHVlLlxuICogQHBhcmFtIHN5bmNGdW5jdGlvbiAtIFRoZSBzeW5jaHJvbm91cyBmdW5jdGlvbiB0byBjb252ZXJ0LlxuICogQHJldHVybnMgQSBmdW5jdGlvbiB0aGF0IHdyYXBzIHRoZSBzeW5jaHJvbm91cyBmdW5jdGlvbiBpbiBhbiBhc3luY2hyb25vdXMgaW50ZXJmYWNlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY29udmVydFN5bmNUb0FzeW5jPEFyZ3VtZW50cyBleHRlbmRzIHVua25vd25bXSwgUmVzdWx0PihzeW5jRnVuY3Rpb246IEdlbmVyaWNGdW5jdGlvbjxBcmd1bWVudHMsIFJlc3VsdD4pOiBHZW5lcmljQXN5bmNGdW5jdGlvbjxBcmd1bWVudHMsIFJlc3VsdD4ge1xuICByZXR1cm4gYXN5bmMgKC4uLiRhcmd1bWVudHM6IEFyZ3VtZW50cyk6IFByb21pc2U8UmVzdWx0PiA9PiB7XG4gICAgYXdhaXQgbm9vcEFzeW5jKCk7XG4gICAgcmV0dXJuIHN5bmNGdW5jdGlvbiguLi4kYXJndW1lbnRzKTtcbiAgfTtcbn1cblxuLyoqXG4gKiBIYW5kbGVzIGEgc2lsZW50IGVycm9yLlxuICpcbiAqIEBwYXJhbSBlcnJvciAtIFRoZSBlcnJvciB0byBoYW5kbGUuXG4gKiBAcmV0dXJucyBXaGV0aGVyIHRoZSBlcnJvciBpcyBhIHNpbGVudCBlcnJvci5cbiAqL1xuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHVuaWNvcm4vY29uc2lzdGVudC1ib29sZWFuLW5hbWUgLS0gVGhlIG5hbWUgc3RhdGVzIHRoZSBhY3Rpb247IHRoZSBib29sZWFuIG9ubHkgcmVwb3J0cyB3aGV0aGVyIHRoZSBlcnJvciB3YXMgaGFuZGxlZC5cbmV4cG9ydCBmdW5jdGlvbiBoYW5kbGVTaWxlbnRFcnJvcihlcnJvcjogdW5rbm93bik6IGJvb2xlYW4ge1xuICBsZXQgY2F1c2UgPSBlcnJvcjtcbiAgd2hpbGUgKCEoY2F1c2UgaW5zdGFuY2VvZiBTaWxlbnRFcnJvcikpIHtcbiAgICBpZiAoIShjYXVzZSBpbnN0YW5jZW9mIEVycm9yKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGNhdXNlID0gY2F1c2UuY2F1c2U7XG4gIH1cblxuICBnZXRMaWJEZWJ1Z2dlcignQXN5bmM6aGFuZGxlU2lsZW50RXJyb3InKShlcnJvcik7XG4gIHJldHVybiB0cnVlO1xufVxuLyoqXG4gKiBJZ25vcmVzIGFuIGVycm9yIHRoYXQgaXMgdGhyb3duIGJ5IGFuIGFzeW5jaHJvbm91cyBmdW5jdGlvbi5cbiAqXG4gKiBAcGFyYW0gcHJvbWlzZSAtIFRoZSBwcm9taXNlIHRvIGlnbm9yZSB0aGUgZXJyb3Igb2YuXG4gKiBAcGFyYW0gZmFsbGJhY2tWYWx1ZSAtIEFsd2F5cyBgdW5kZWZpbmVkYC5cbiAqIEByZXR1cm5zIEEge0BsaW5rIFByb21pc2V9IHRoYXQgcmVzb2x2ZXMgd2hlbiB0aGUgYXN5bmNocm9ub3VzIGZ1bmN0aW9uIGNvbXBsZXRlcyBvciBmYWlscy5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGlnbm9yZUVycm9yKHByb21pc2U6IFByb21pc2U8dW5rbm93bj4sIGZhbGxiYWNrVmFsdWU/OiB1bmRlZmluZWQpOiBQcm9taXNlPHZvaWQ+O1xuLyoqXG4gKiBJbnZva2VzIGFuIGFzeW5jaHJvbm91cyBmdW5jdGlvbiBhbmQgcmV0dXJucyBhIGZhbGxiYWNrIHZhbHVlIGlmIGFuIGVycm9yIGlzIHRocm93bi5cbiAqXG4gKiBAdHlwZVBhcmFtIFQgLSBUaGUgdHlwZSBvZiB0aGUgdmFsdWUgcmV0dXJuZWQgYnkgdGhlIGFzeW5jaHJvbm91cyBmdW5jdGlvbi5cbiAqIEBwYXJhbSBwcm9taXNlIC0gVGhlIHByb21pc2UgdG8gaWdub3JlIHRoZSBlcnJvciBvZi5cbiAqIEBwYXJhbSBmYWxsYmFja1ZhbHVlIC0gVGhlIHZhbHVlIHRvIHJldHVybiBpZiBhbiBlcnJvciBpcyB0aHJvd24uXG4gKiBAcmV0dXJucyBBIHtAbGluayBQcm9taXNlfSB0aGF0IHJlc29sdmVzIHdpdGggdGhlIHZhbHVlIHJldHVybmVkIGJ5IHRoZSBhc3luY2hyb25vdXMgZnVuY3Rpb24gb3IgdGhlIGZhbGxiYWNrIHZhbHVlIGlmIGFuIGVycm9yIGlzIHRocm93bi5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGlnbm9yZUVycm9yPFQ+KHByb21pc2U6IFByb21pc2U8VD4sIGZhbGxiYWNrVmFsdWU6IFQpOiBQcm9taXNlPFQ+O1xuLyoqXG4gKiBJZ25vcmVzIGFuIGVycm9yIHRoYXQgaXMgdGhyb3duIGJ5IGFuIGFzeW5jaHJvbm91cyBmdW5jdGlvbi5cbiAqXG4gKiBAdHlwZVBhcmFtIFQgLSBUaGUgdHlwZSBvZiB0aGUgdmFsdWUgcmV0dXJuZWQgYnkgdGhlIGFzeW5jaHJvbm91cyBmdW5jdGlvbi5cbiAqIEBwYXJhbSBwcm9taXNlIC0gVGhlIHByb21pc2UgdG8gaWdub3JlIHRoZSBlcnJvciBvZi5cbiAqIEBwYXJhbSBmYWxsYmFja1ZhbHVlIC0gVGhlIHZhbHVlIHRvIHJldHVybiBpZiBhbiBlcnJvciBpcyB0aHJvd24uXG4gKiBAcmV0dXJucyBBIHtAbGluayBQcm9taXNlfSB0aGF0IHJlc29sdmVzIHdpdGggdGhlIHZhbHVlIHJldHVybmVkIGJ5IHRoZSBhc3luY2hyb25vdXMgZnVuY3Rpb24gb3IgdGhlIGZhbGxiYWNrIHZhbHVlIGlmIGFuIGVycm9yIGlzIHRocm93bi5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGlnbm9yZUVycm9yPFQ+KHByb21pc2U6IFByb21pc2U8VD4sIGZhbGxiYWNrVmFsdWU/OiBUKTogUHJvbWlzZTxUIHwgdm9pZD4ge1xuICBjb25zdCBpZ25vcmVFcnJvckRlYnVnZ2VyID0gZ2V0TGliRGVidWdnZXIoJ0FzeW5jOmlnbm9yZUVycm9yJyk7XG4gIGNvbnN0IHN0YWNrVHJhY2UgPSBnZXRTdGFja1RyYWNlKDEpO1xuICB0cnkge1xuICAgIHJldHVybiBhd2FpdCBwcm9taXNlO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIGlnbm9yZUVycm9yRGVidWdnZXIoXG4gICAgICAnSWdub3JlZCBlcnJvcicsXG4gICAgICBuZXcgQ3VzdG9tU3RhY2tUcmFjZUVycm9yKHtcbiAgICAgICAgY2F1c2U6IGVycm9yLFxuICAgICAgICBtZXNzYWdlOiAnSWdub3JlZCBlcnJvcicsXG4gICAgICAgIHN0YWNrVHJhY2VcbiAgICAgIH0pXG4gICAgKTtcbiAgICByZXR1cm4gZmFsbGJhY2tWYWx1ZTtcbiAgfVxufVxuXG4vKipcbiAqIEludm9rZXMgYSB7QGxpbmsgUHJvbWlzZX0gYW5kIHNhZmVseSBoYW5kbGVzIGFueSBlcnJvcnMgYnkgY2F0Y2hpbmcgdGhlbSBhbmQgZW1pdHRpbmcgYW4gYXN5bmMgZXJyb3IgZXZlbnQuXG4gKlxuICogQHBhcmFtIGFzeW5jRnVuY3Rpb24gLSBUaGUgYXN5bmNocm9ub3VzIGZ1bmN0aW9uIHRvIGludm9rZSBzYWZlbHkuXG4gKiBAcGFyYW0gc3RhY2tUcmFjZSAtIFRoZSBzdGFjayB0cmFjZSBvZiB0aGUgc291cmNlIGZ1bmN0aW9uLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaW52b2tlQXN5bmNTYWZlbHkoYXN5bmNGdW5jdGlvbjogKCkgPT4gUHJvbWlzYWJsZTx1bmtub3duPiwgc3RhY2tUcmFjZT86IHN0cmluZyk6IHZvaWQge1xuICBzdGFja1RyYWNlID8/PSBnZXRTdGFja1RyYWNlKDEpO1xuXG4gIGxldCByZXN1bHQ6IHVua25vd247XG4gIHRyeSB7XG4gICAgcmVzdWx0ID0gYXN5bmNGdW5jdGlvbigpO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvcHJlZmVyLXByb21pc2UtcmVqZWN0LWVycm9ycyAtLSBSZS1yZWplY3RpbmcgdGhlIG9yaWdpbmFsIGNhdWdodCBlcnJvciBhcy1pcy5cbiAgICBub3RpZnlBc3luY09wZXJhdGlvblN0YXJ0ZWQoYWRkRXJyb3JIYW5kbGVyKCgpID0+IFByb21pc2UucmVqZWN0KGVycm9yKSwgc3RhY2tUcmFjZSkpO1xuICB9XG4gIGlmIChyZXN1bHQgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgbm90aWZ5QXN5bmNPcGVyYXRpb25TdGFydGVkKGFkZEVycm9ySGFuZGxlcigoKSA9PiByZXN1bHQsIHN0YWNrVHJhY2UpKTtcbiAgfVxufVxuXG4vKipcbiAqIEludm9rZXMgYW4gYXN5bmNocm9ub3VzIGZ1bmN0aW9uIGFmdGVyIGEgZGVsYXkuXG4gKlxuICogQHBhcmFtIHBhcmFtcyAtIFRoZSBwYXJhbWV0ZXJzIGZvciB0aGUgZnVuY3Rpb24uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpbnZva2VBc3luY1NhZmVseUFmdGVyRGVsYXkocGFyYW1zOiBJbnZva2VBc3luY1NhZmVseUFmdGVyRGVsYXlQYXJhbXMpOiB2b2lkIHtcbiAgY29uc3Qge1xuICAgIGFzeW5jRnVuY3Rpb24sXG4gICAgZGVsYXlJbk1pbGxpc2Vjb25kcyA9IDBcbiAgfSA9IHBhcmFtcztcbiAgY29uc3QgYWJvcnRTaWduYWwgPSBwYXJhbXMuYWJvcnRTaWduYWwgPz8gYWJvcnRTaWduYWxOZXZlcigpO1xuICBhYm9ydFNpZ25hbC50aHJvd0lmQWJvcnRlZCgpO1xuICBjb25zdCBzdGFja1RyYWNlID0gcGFyYW1zLnN0YWNrVHJhY2UgPz8gZ2V0U3RhY2tUcmFjZSgxKTtcbiAgaW52b2tlQXN5bmNTYWZlbHkoYXN5bmMgKCkgPT4ge1xuICAgIGF3YWl0IHNsZWVwKHsgYWJvcnRTaWduYWwsIG1pbGxpc2Vjb25kczogZGVsYXlJbk1pbGxpc2Vjb25kcywgc2hvdWxkVGhyb3dPbkFib3J0OiB0cnVlIH0pO1xuICAgIGF3YWl0IGFzeW5jRnVuY3Rpb24oYWJvcnRTaWduYWwpO1xuICB9LCBzdGFja1RyYWNlKTtcbn1cblxuLyoqXG4gKiBFeGVjdXRlcyBhc3luYyBmdW5jdGlvbnMgc2VxdWVudGlhbGx5LlxuICpcbiAqIEB0eXBlUGFyYW0gVCAtIFRoZSB0eXBlIG9mIHRoZSB2YWx1ZS5cbiAqIEBwYXJhbSBhc3luY0ZucyAtIFRoZSBhc3luYyBmdW5jdGlvbnMgdG8gZXhlY3V0ZSBzZXF1ZW50aWFsbHkuXG4gKiBAcmV0dXJucyBBIHtAbGluayBQcm9taXNlfSB0aGF0IHJlc29sdmVzIHdpdGggYW4gYXJyYXkgb2YgdGhlIHJlc3VsdHMgb2YgdGhlIGFzeW5jIGZ1bmN0aW9ucy5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHByb21pc2VBbGxBc3luY0Zuc1NlcXVlbnRpYWxseTxUPihhc3luY0ZuczogKCgpID0+IFByb21pc2FibGU8VD4pW10pOiBQcm9taXNlPFRbXT4ge1xuICBjb25zdCByZXN1bHRzOiBUW10gPSBbXTtcbiAgZm9yIChjb25zdCBhc3luY0Z1bmN0aW9uIG9mIGFzeW5jRm5zKSB7XG4gICAgcmVzdWx0cy5wdXNoKGF3YWl0IGFzeW5jRnVuY3Rpb24oKSk7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdHM7XG59XG5cbi8qKlxuICogRXhlY3V0ZXMgcHJvbWlzZXMgc2VxdWVudGlhbGx5LlxuICpcbiAqIEB0eXBlUGFyYW0gVCAtIFRoZSB0eXBlIG9mIHRoZSB2YWx1ZS5cbiAqIEBwYXJhbSBwcm9taXNlcyAtIFRoZSBwcm9taXNlcyB0byBleGVjdXRlIHNlcXVlbnRpYWxseS5cbiAqIEByZXR1cm5zIEEge0BsaW5rIFByb21pc2V9IHRoYXQgcmVzb2x2ZXMgd2l0aCBhbiBhcnJheSBvZiB0aGUgcmVzdWx0cyBvZiB0aGUgcHJvbWlzZXMuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBwcm9taXNlQWxsU2VxdWVudGlhbGx5PFQ+KHByb21pc2VzOiBQcm9taXNhYmxlPFQ+W10pOiBQcm9taXNlPFRbXT4ge1xuICByZXR1cm4gYXdhaXQgcHJvbWlzZUFsbEFzeW5jRm5zU2VxdWVudGlhbGx5KHByb21pc2VzLm1hcCgocHJvbWlzZSkgPT4gKCkgPT4gcHJvbWlzZSkpO1xufVxuXG5jb25zdCB0ZXJtaW5hdGVSZXRyeUVycm9ycyA9IG5ldyBXZWFrU2V0PEVycm9yPigpO1xuXG4vKipcbiAqIE9wdGlvbnMgZm9yIHtAbGluayByZXRyeVdpdGhUaW1lb3V0fS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBSZXRyeVdpdGhUaW1lb3V0UGFyYW1zIHtcbiAgLyoqXG4gICAqIFRoZSBmdW5jdGlvbiB0byBoYW5kbGUgdGhlIHRpbWVvdXQuXG4gICAqXG4gICAqIEBwYXJhbSBjb250ZXh0IC0gVGhlIHRpbWVvdXQgY29udGV4dC5cbiAgICovXG4gIHJlYWRvbmx5IG9uVGltZW91dD86IChjb250ZXh0OiBUaW1lb3V0Q29udGV4dCkgPT4gdm9pZDtcblxuICAvKipcbiAgICogVGhlIGZ1bmN0aW9uIHRvIGV4ZWN1dGUuXG4gICAqXG4gICAqIEBwYXJhbSBhYm9ydFNpZ25hbCAtIFRoZSBhYm9ydCBzaWduYWwgdG8gbGlzdGVuIHRvLlxuICAgKiBAcmV0dXJucyBUaGUgcmVzdWx0IG9mIHRoZSBmdW5jdGlvbi5cbiAgICovXG4gIHJlYWRvbmx5IG9wZXJhdGlvbkZ1bmN0aW9uOiAoYWJvcnRTaWduYWw6IEFib3J0U2lnbmFsKSA9PiBQcm9taXNhYmxlPGJvb2xlYW4+O1xuXG4gIC8qKlxuICAgKiBUaGUgbmFtZSBvZiB0aGUgb3BlcmF0aW9uLlxuICAgKlxuICAgKiBAZGVmYXVsdCBgJydgXG4gICAqL1xuICByZWFkb25seSBvcGVyYXRpb25OYW1lPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgcmV0cnkgb3B0aW9ucy5cbiAgICovXG4gIHJlYWRvbmx5IHJldHJ5T3B0aW9ucz86IFJldHJ5T3B0aW9ucztcblxuICAvKipcbiAgICogVGhlIHN0YWNrIHRyYWNlIG9mIHRoZSBzb3VyY2UgZnVuY3Rpb24uXG4gICAqL1xuICByZWFkb25seSBzdGFja1RyYWNlPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIE9wdGlvbnMgZm9yIHtAbGluayBydW5XaXRoVGltZW91dH0uXG4gKlxuICogQHR5cGVQYXJhbSBSZXN1bHQgLSBUaGUgdHlwZSBvZiB0aGUgcmVzdWx0IHJldHVybmVkIGJ5IHRoZSBvcGVyYXRpb24gZnVuY3Rpb24uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUnVuV2l0aFRpbWVvdXRQYXJhbXM8UmVzdWx0PiB7XG4gIC8qKlxuICAgKiBUaGUgY29udGV4dCBvZiB0aGUgZnVuY3Rpb24uXG4gICAqL1xuICByZWFkb25seSBjb250ZXh0PzogdW5rbm93bjtcblxuICAvKipcbiAgICogVGhlIGZ1bmN0aW9uIHRvIGhhbmRsZSB0aGUgdGltZW91dC5cbiAgICpcbiAgICogQHBhcmFtIGNvbnRleHQgLSBUaGUgdGltZW91dCBjb250ZXh0LlxuICAgKi9cbiAgcmVhZG9ubHkgb25UaW1lb3V0PzogKGNvbnRleHQ6IFRpbWVvdXRDb250ZXh0KSA9PiB2b2lkO1xuXG4gIC8qKlxuICAgKiBUaGUgb3BlcmF0aW9uIGZ1bmN0aW9uIHRvIGV4ZWN1dGUuXG4gICAqXG4gICAqIEBwYXJhbSBhYm9ydFNpZ25hbCAtIFRoZSBhYm9ydCBzaWduYWwgdG8gbGlzdGVuIHRvLlxuICAgKiBAcmV0dXJucyBUaGUgcmVzdWx0IG9mIHRoZSBmdW5jdGlvbi5cbiAgICovXG4gIHJlYWRvbmx5IG9wZXJhdGlvbkZ1bmN0aW9uOiAoYWJvcnRTaWduYWw6IEFib3J0U2lnbmFsKSA9PiBQcm9taXNhYmxlPFJlc3VsdD47XG5cbiAgLyoqXG4gICAqIFRoZSBuYW1lIG9mIHRoZSBvcGVyYXRpb24uXG4gICAqXG4gICAqIEBkZWZhdWx0IGAnJ2BcbiAgICovXG4gIHJlYWRvbmx5IG9wZXJhdGlvbk5hbWU/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBzdGFjayB0cmFjZSBvZiB0aGUgc291cmNlIGZ1bmN0aW9uLlxuICAgKi9cbiAgcmVhZG9ubHkgc3RhY2tUcmFjZT86IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgICogVGhlIG1heGltdW0gdGltZSB0byB3YWl0IGluIG1pbGxpc2Vjb25kcy5cbiAgICovXG4gIHJlYWRvbmx5IHRpbWVvdXRJbk1pbGxpc2Vjb25kczogbnVtYmVyO1xufVxuXG4vKipcbiAqIFBhcmFtZXRlcnMgZm9yIHtAbGluayBzbGVlcH0uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU2xlZXBQYXJhbXMge1xuICAvKipcbiAgICogVGhlIGFib3J0IHNpZ25hbCB0byBsaXN0ZW4gdG8uXG4gICAqL1xuICByZWFkb25seSBhYm9ydFNpZ25hbD86IEFib3J0U2lnbmFsO1xuXG4gIC8qKlxuICAgKiBUaGUgdGltZSB0byB3YWl0IGluIG1pbGxpc2Vjb25kcy5cbiAgICovXG4gIHJlYWRvbmx5IG1pbGxpc2Vjb25kczogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIHRocm93IGFuIGVycm9yIGlmIHRoZSBhYm9ydCBzaWduYWwgaXMgYWJvcnRlZC5cbiAgICpcbiAgICogQGRlZmF1bHQgYGZhbHNlYFxuICAgKi9cbiAgcmVhZG9ubHkgc2hvdWxkVGhyb3dPbkFib3J0PzogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBDb250ZXh0IHByb3ZpZGVkIHRvIHRoZSB0aW1lb3V0IGhhbmRsZXIuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVGltZW91dENvbnRleHQge1xuICAvKipcbiAgICogVGhlIGR1cmF0aW9uIGluIG1pbGxpc2Vjb25kcyBzaW5jZSB0aGUgb3BlcmF0aW9uIHN0YXJ0ZWQuXG4gICAqL1xuICByZWFkb25seSBkdXJhdGlvbjogbnVtYmVyO1xuICAvKipcbiAgICogUmVnaXN0ZXJzIGEgY2FsbGJhY2sgdG8gYmUgaW52b2tlZCB3aGVuIHRoZSBvcGVyYXRpb24gY29tcGxldGVzLlxuICAgKlxuICAgKiBAcGFyYW0gY2FsbGJhY2sgLSBUaGUgZnVuY3Rpb24gdG8gY2FsbCB3aGVuIHRoZSBvcGVyYXRpb24gY29tcGxldGVzLlxuICAgKi9cbiAgb25PcGVyYXRpb25Db21wbGV0ZWQ6IChjYWxsYmFjazogKCkgPT4gdm9pZCkgPT4gdm9pZDtcbiAgLyoqXG4gICAqIFRoZSBuYW1lIG9mIHRoZSBvcGVyYXRpb24uXG4gICAqL1xuICByZWFkb25seSBvcGVyYXRpb25OYW1lOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBUZXJtaW5hdGVzIHRoZSBvcGVyYXRpb24gdGhhdCB0aW1lZCBvdXQuXG4gICAqL1xuICB0ZXJtaW5hdGVPcGVyYXRpb246ICgpID0+IHZvaWQ7XG59XG5cbi8qKlxuICogUGFyYW1ldGVycyBmb3Ige0BsaW5rIHRpbWVvdXR9LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFRpbWVvdXRQYXJhbXMge1xuICAvKipcbiAgICogVGhlIGFib3J0IHNpZ25hbCB0byBsaXN0ZW4gdG8uXG4gICAqL1xuICByZWFkb25seSBhYm9ydFNpZ25hbD86IEFib3J0U2lnbmFsO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIHRocm93IGFuIGVycm9yIGlmIHRoZSBhYm9ydCBzaWduYWwgaXMgYWJvcnRlZC5cbiAgICpcbiAgICogQGRlZmF1bHQgYGZhbHNlYFxuICAgKi9cbiAgcmVhZG9ubHkgc2hvdWxkVGhyb3dPbkFib3J0PzogYm9vbGVhbjtcblxuICAvKipcbiAgICogVGhlIHRpbWVvdXQgcGVyaW9kIGluIG1pbGxpc2Vjb25kcy5cbiAgICovXG4gIHJlYWRvbmx5IHRpbWVvdXRJbk1pbGxpc2Vjb25kczogbnVtYmVyO1xufVxuXG4vKipcbiAqIENoYWlucyBhIHByb21pc2Ugd2l0aCBhbm90aGVyIHByb21pc2UuXG4gKlxuICogQHBhcmFtIGNoYWluUHJvbWlzZSAtIFJlcHJlc2VudHMgdGhlIGNoYWluZWQgcHJvbWlzZS5cbiAqIEBwYXJhbSBwcm9taXNhYmxlRnVuY3Rpb24gLSBUaGUgZnVuY3Rpb24gdG8gY2hhaW4uXG4gKiBAcmV0dXJucyBDaGFpbmVkIHByb21pc2Ugb3IgYG51bGxgIGlmIG5vIGFzeW5jIGxvZ2ljIGlzIGNoYWluZWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjaGFpbihjaGFpblByb21pc2U6IG51bGwgfCBQcm9taXNlPHZvaWQ+LCBwcm9taXNhYmxlRnVuY3Rpb246ICgpID0+IG51bGwgfCBQcm9taXNhYmxlPHZvaWQ+KTogbnVsbCB8IFByb21pc2U8dm9pZD4ge1xuICBsZXQgbmV4dENoYWluUHJvbWlzZSA9IGNoYWluUHJvbWlzZTtcbiAgaWYgKGNoYWluUHJvbWlzZSkge1xuICAgIG5leHRDaGFpblByb21pc2UgPSBjaGFpblByb21pc2UudGhlbigoKSA9PiBwcm9taXNhYmxlRnVuY3Rpb24oKSA/PyB1bmRlZmluZWQpO1xuICB9IGVsc2Uge1xuICAgIGNvbnN0IHByb21pc2FibGUgPSBwcm9taXNhYmxlRnVuY3Rpb24oKTtcbiAgICBpZiAocHJvbWlzYWJsZSkge1xuICAgICAgbmV4dENoYWluUHJvbWlzZSA9IHByb21pc2FibGUgaW5zdGFuY2VvZiBQcm9taXNlID8gcHJvbWlzYWJsZSBhcyBQcm9taXNlPHZvaWQ+IDogUHJvbWlzZS5yZXNvbHZlKHByb21pc2FibGUpO1xuICAgIH1cbiAgfVxuXG4gIG5leHRDaGFpblByb21pc2U/LmNhdGNoKG5vb3ApO1xuICByZXR1cm4gbmV4dENoYWluUHJvbWlzZTtcbn1cblxuLyoqXG4gKiBNYXJrcyBhbiBlcnJvciB0byB0ZXJtaW5hdGUgcmV0cnkgbG9naWMuXG4gKlxuICogQHBhcmFtIGVycm9yIC0gVGhlIGVycm9yIHRvIG1hcmsgdG8gdGVybWluYXRlIHJldHJ5IGxvZ2ljLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbWFya3NBc1Rlcm1pbmF0ZVJldHJ5KGVycm9yOiBFcnJvcik6IHZvaWQge1xuICB0ZXJtaW5hdGVSZXRyeUVycm9ycy5hZGQoZXJyb3IpO1xufVxuXG4vKipcbiAqIEFuIGFzeW5jIGZ1bmN0aW9uIHRoYXQgbmV2ZXIgZW5kcy5cbiAqXG4gKiBAcmV0dXJucyBBIHtAbGluayBQcm9taXNlfSB0aGF0IG5ldmVyIHJlc29sdmVzLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gbmV2ZXJFbmRzKCk6IFByb21pc2U8bmV2ZXI+IHtcbiAgYXdhaXQgbmV3IFByb21pc2UoKCkgPT4ge1xuICAgIG5vb3AoKTtcbiAgfSk7XG4gIC8qIHY4IGlnbm9yZSBzdGFydCAtLSBFeGhhdXN0aXZlIHN3aXRjaCBndWFyZDsgdGhlIGF3YWl0IGFib3ZlIG5ldmVyIHJlc29sdmVzLiAqL1xuICBhc3NlcnQoZmFsc2UsICdTaG91bGQgbmV2ZXIgaGFwcGVuJyk7XG4gIC8qIHY4IGlnbm9yZSBzdG9wICovXG59XG5cbi8qKlxuICogR2V0cyB0aGUgbmV4dCB0aWNrLlxuICpcbiAqIEByZXR1cm5zIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdoZW4gdGhlIG5leHQgdGljayBpcyBhdmFpbGFibGUuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBuZXh0VGlja0FzeW5jKCk6IFByb21pc2U8dm9pZD4ge1xuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICBxdWV1ZU1pY3JvdGFzaygoKSA9PiB7XG4gICAgICByZXNvbHZlKCk7XG4gICAgfSk7XG4gIH0pO1xufVxuXG4vKipcbiAqIENvbnZlcnRzIHRvIG5hdGl2ZSBwcm9taXNhYmxlLCBjb252ZXJ0aW5nIHtAbGluayBQcm9taXNlTGlrZX0gKGFrYSBUaGVuYWJsZSkgdG8gYSBuYXRpdmUge0BsaW5rIFByb21pc2V9LlxuICpcbiAqIEB0eXBlUGFyYW0gVCAtIFRoZSB0eXBlIG9mIHRoZSB2YWx1ZS5cbiAqIEBwYXJhbSBwcm9taXNhYmxlIC0gVGhlIHByb21pc2FibGUgdG8gbm9ybWFsaXplLlxuICogQHJldHVybnMgVGhlIHZhbHVlIGl0c2VsZiBvciBhIG5hdGl2ZSB7QGxpbmsgUHJvbWlzZX0gaWYgdGhlIHZhbHVlIGlzIGEge0BsaW5rIFByb21pc2VMaWtlfS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG5vcm1hbGl6ZVByb21pc2FibGU8VD4ocHJvbWlzYWJsZTogUHJvbWlzYWJsZTxUPik6IFByb21pc2U8VD4gfCBUIHtcbiAgaWYgKCFwcm9taXNhYmxlKSB7XG4gICAgcmV0dXJuIHByb21pc2FibGU7XG4gIH1cblxuICBpZiAocHJvbWlzYWJsZSBpbnN0YW5jZW9mIFByb21pc2UpIHtcbiAgICByZXR1cm4gcHJvbWlzYWJsZSBhcyBQcm9taXNlPFQ+O1xuICB9XG5cbiAgcmV0dXJuIChwcm9taXNhYmxlIGFzIFBhcnRpYWw8UHJvbWlzZUxpa2U8VD4+KS50aGVuID8gUHJvbWlzZS5yZXNvbHZlKHByb21pc2FibGUpIDogKHByb21pc2FibGUgYXMgVCk7XG59XG5cbi8qKlxuICogR2V0cyB0aGUgbmV4dCBxdWV1ZSBtaWNyb3Rhc2suXG4gKlxuICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiB0aGUgbmV4dCBxdWV1ZSBtaWNyb3Rhc2sgaXMgYXZhaWxhYmxlLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcXVldWVNaWNyb3Rhc2tBc3luYygpOiBQcm9taXNlPHZvaWQ+IHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgcXVldWVNaWNyb3Rhc2soKCkgPT4ge1xuICAgICAgcmVzb2x2ZSgpO1xuICAgIH0pO1xuICB9KTtcbn1cblxuLyoqXG4gKiBHZXRzIHRoZSBuZXh0IHJlcXVlc3QgYW5pbWF0aW9uIGZyYW1lLlxuICpcbiAqIEBwYXJhbSBmYWxsYmFja1RpbWVvdXRJbk1pbGxpc2Vjb25kcyAtIFRoZSBmYWxsYmFjayB0aW1lb3V0IGluIG1pbGxpc2Vjb25kcyB0byByZXNvbHZlIHRoZSBwcm9taXNlIGlmIGByZXF1ZXN0QW5pbWF0aW9uRnJhbWVgIGRvZXMgbm90IGZpcmUgKGUuZy4gdGhlIHdpbmRvdyBpcyBub3QgYWN0aXZlKS5cbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERlZmF1bHRzIHRvIGAxMDBgIG1pbGxpc2Vjb25kcy4gVXNlIGAwYCB0byBkaXNhYmxlIHRoZSBmYWxsYmFjay5cbiAqIEByZXR1cm5zIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdoZW4gdGhlIG5leHQgcmVxdWVzdCBhbmltYXRpb24gZnJhbWUgaXMgYXZhaWxhYmxlIChvciB3aGVuIHRoZSBmYWxsYmFjayB0aW1lIGlzIHJlYWNoZWQpLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcmVxdWVzdEFuaW1hdGlvbkZyYW1lQXN5bmMoZmFsbGJhY2tUaW1lb3V0SW5NaWxsaXNlY29uZHM/OiBudW1iZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgcmVxdWVzdEFuaW1hdGlvbkZyYW1lQXN5bmNQcm9taXNlID0gbmV3IFByb21pc2U8dm9pZD4oKHJlc29sdmUpID0+IHtcbiAgICB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcbiAgICAgIHJlc29sdmUoKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgY29uc3QgREVGQVVMVF9GQUxMQkFDS19USU1FT1VUX0lOX01JTExJU0VDT05EUyA9IDEwMDtcbiAgZmFsbGJhY2tUaW1lb3V0SW5NaWxsaXNlY29uZHMgPz89IERFRkFVTFRfRkFMTEJBQ0tfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFM7XG5cbiAgcmV0dXJuIFByb21pc2UucmFjZShbcmVxdWVzdEFuaW1hdGlvbkZyYW1lQXN5bmNQcm9taXNlLCBmYWxsYmFja1RpbWVvdXRJbk1pbGxpc2Vjb25kcyA+IDAgPyBzbGVlcCh7IG1pbGxpc2Vjb25kczogZmFsbGJhY2tUaW1lb3V0SW5NaWxsaXNlY29uZHMgfSkgOiBuZXZlckVuZHMoKV0pO1xufVxuXG4vKipcbiAqIFJldHJpZXMgdGhlIHByb3ZpZGVkIGZ1bmN0aW9uIHVudGlsIGl0IHJldHVybnMgYHRydWVgIG9yIHRoZSB0aW1lb3V0IGlzIHJlYWNoZWQuXG4gKlxuICogQHBhcmFtIHBhcmFtcyAtIFRoZSBwYXJhbWV0ZXJzIGZvciB0aGUgZnVuY3Rpb24uXG4gKiBAcmV0dXJucyBBIHtAbGluayBQcm9taXNlfSB0aGF0IHJlc29sdmVzIHdoZW4gdGhlIGZ1bmN0aW9uIHJldHVybnMgYHRydWVgIG9yIHJlamVjdHMgd2hlbiB0aGUgdGltZW91dCBpcyByZWFjaGVkLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcmV0cnlXaXRoVGltZW91dChwYXJhbXM6IFJldHJ5V2l0aFRpbWVvdXRQYXJhbXMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgcmV0cnlXaXRoVGltZW91dERlYnVnZ2VyID0gZ2V0TGliRGVidWdnZXIoJ0FzeW5jOnJldHJ5V2l0aFRpbWVvdXQnKTtcbiAgY29uc3Qgc3RhY2tUcmFjZSA9IHBhcmFtcy5zdGFja1RyYWNlID8/IGdldFN0YWNrVHJhY2UoMSk7XG4gIGNvbnN0IERFRkFVTFRfUkVUUllfT1BUSU9OUyA9IHtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tbWFnaWMtbnVtYmVycyAtLSBFeHRyYWN0aW5nIG1hZ2ljIG51bWJlciBhcyBhIGNvbnN0YW50IHdvdWxkIGJlIHJlcGV0aXRpdmUsIGFzIHRoZSB2YWx1ZSBpcyB1c2VkIG9ubHkgb25jZSBhbmQgaXRzIG5hbWUgd291bGQgYmUgdGhlIHNhbWUgYXMgdGhlIHByb3BlcnR5LlxuICAgIHJldHJ5RGVsYXlJbk1pbGxpc2Vjb25kczogMTAwLFxuICAgIHNob3VsZFJldHJ5T25FcnJvcjogZmFsc2UsXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLW1hZ2ljLW51bWJlcnMgLS0gRXh0cmFjdGluZyBtYWdpYyBudW1iZXIgYXMgYSBjb25zdGFudCB3b3VsZCBiZSByZXBldGl0aXZlLCBhcyB0aGUgdmFsdWUgaXMgdXNlZCBvbmx5IG9uY2UgYW5kIGl0cyBuYW1lIHdvdWxkIGJlIHRoZSBzYW1lIGFzIHRoZSBwcm9wZXJ0eS5cbiAgICB0aW1lb3V0SW5NaWxsaXNlY29uZHM6IDUwMDBcbiAgfTtcbiAgY29uc3QgZnVsbE9wdGlvbnMgPSB7IC4uLkRFRkFVTFRfUkVUUllfT1BUSU9OUywgLi4ucGFyYW1zLnJldHJ5T3B0aW9ucyB9O1xuICBmdWxsT3B0aW9ucy5hYm9ydFNpZ25hbD8udGhyb3dJZkFib3J0ZWQoKTtcblxuICBhd2FpdCBydW5XaXRoVGltZW91dChub3JtYWxpemVPcHRpb25hbFByb3BlcnRpZXM8UnVuV2l0aFRpbWVvdXRQYXJhbXM8dm9pZD4+KHtcbiAgICBjb250ZXh0OiB7IG9wZXJhdGlvbk5hbWU6IHBhcmFtcy5vcGVyYXRpb25OYW1lID8/ICcnLCByZXRyeUZ1bmN0aW9uOiBwYXJhbXMub3BlcmF0aW9uRnVuY3Rpb24gfSxcbiAgICBvblRpbWVvdXQ6IHBhcmFtcy5vblRpbWVvdXQsXG4gICAgYXN5bmMgb3BlcmF0aW9uRnVuY3Rpb24oYWJvcnRTaWduYWw6IEFib3J0U2lnbmFsKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICBjb25zdCBjb21iaW5lZEFib3J0U2lnbmFsID0gYWJvcnRTaWduYWxBbnkoZnVsbE9wdGlvbnMuYWJvcnRTaWduYWwsIGFib3J0U2lnbmFsKTtcbiAgICAgIGNvbWJpbmVkQWJvcnRTaWduYWwudGhyb3dJZkFib3J0ZWQoKTtcbiAgICAgIGxldCBhdHRlbXB0ID0gMDtcbiAgICAgIHdoaWxlICghY29tYmluZWRBYm9ydFNpZ25hbC5hYm9ydGVkKSB7XG4gICAgICAgIGF0dGVtcHQrKztcbiAgICAgICAgbGV0IGlzU3VjY2VzczogYm9vbGVhbjtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBpc1N1Y2Nlc3MgPSBhd2FpdCBwYXJhbXMub3BlcmF0aW9uRnVuY3Rpb24oY29tYmluZWRBYm9ydFNpZ25hbCk7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bm5lY2Vzc2FyeS1jb25kaXRpb24gLS0gSXQgbWlnaHQgY2hhbmdlZCBpbnNpZGUgYGZuKClgLiBFU0xpbnQgbWlzdGFrZW5seSBkb2VzIG5vdCByZWNvZ25pemUgaXQuXG4gICAgICAgICAgaWYgKGNvbWJpbmVkQWJvcnRTaWduYWwuYWJvcnRlZCB8fCAhZnVsbE9wdGlvbnMuc2hvdWxkUmV0cnlPbkVycm9yIHx8IHRlcm1pbmF0ZVJldHJ5RXJyb3JzLmhhcyhlcnJvciBhcyBFcnJvcikpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBDdXN0b21TdGFja1RyYWNlRXJyb3Ioe1xuICAgICAgICAgICAgICBjYXVzZTogZXJyb3IsXG4gICAgICAgICAgICAgIG1lc3NhZ2U6ICdyZXRyeVdpdGhUaW1lb3V0IGZhaWxlZCcsXG4gICAgICAgICAgICAgIHN0YWNrVHJhY2VcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgICBwcmludEVycm9yKGVycm9yKTtcbiAgICAgICAgICBpc1N1Y2Nlc3MgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaXNTdWNjZXNzKSB7XG4gICAgICAgICAgcHJpbnRXaXRoU3RhY2tUcmFjZSh7XG4gICAgICAgICAgICAkYXJndW1lbnRzOiBbe1xuICAgICAgICAgICAgICBvcGVyYXRpb25GdW5jdGlvbjogcGFyYW1zLm9wZXJhdGlvbkZ1bmN0aW9uLFxuICAgICAgICAgICAgICBvcGVyYXRpb25OYW1lOiBwYXJhbXMub3BlcmF0aW9uTmFtZSA/PyAnJ1xuICAgICAgICAgICAgfV0sXG4gICAgICAgICAgICBkZWJ1Z2dlckluc3RhbmNlOiByZXRyeVdpdGhUaW1lb3V0RGVidWdnZXIsXG4gICAgICAgICAgICBtZXNzYWdlOiBgUmV0cnkgY29tcGxldGVkIHN1Y2Nlc3NmdWxseSBhZnRlciAke1N0cmluZyhhdHRlbXB0KX0gYXR0ZW1wdHNgLFxuICAgICAgICAgICAgc3RhY2tUcmFjZVxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHByaW50V2l0aFN0YWNrVHJhY2Uoe1xuICAgICAgICAgICRhcmd1bWVudHM6IFt7XG4gICAgICAgICAgICBvcGVyYXRpb25GdW5jdGlvbjogcGFyYW1zLm9wZXJhdGlvbkZ1bmN0aW9uLFxuICAgICAgICAgICAgb3BlcmF0aW9uTmFtZTogcGFyYW1zLm9wZXJhdGlvbk5hbWUgPz8gJydcbiAgICAgICAgICB9XSxcbiAgICAgICAgICBkZWJ1Z2dlckluc3RhbmNlOiByZXRyeVdpdGhUaW1lb3V0RGVidWdnZXIsXG4gICAgICAgICAgbWVzc2FnZTogYFJldHJ5IGF0dGVtcHQgJHtTdHJpbmcoYXR0ZW1wdCl9IGNvbXBsZXRlZCB1bnN1Y2Nlc3NmdWxseS4gVHJ5aW5nIGFnYWluIGluICR7U3RyaW5nKGZ1bGxPcHRpb25zLnJldHJ5RGVsYXlJbk1pbGxpc2Vjb25kcyl9IG1pbGxpc2Vjb25kc2AsXG4gICAgICAgICAgc3RhY2tUcmFjZVxuICAgICAgICB9KTtcblxuICAgICAgICBhd2FpdCBzbGVlcCh7IGFib3J0U2lnbmFsLCBtaWxsaXNlY29uZHM6IGZ1bGxPcHRpb25zLnJldHJ5RGVsYXlJbk1pbGxpc2Vjb25kcyB9KTtcbiAgICAgIH1cbiAgICB9LFxuICAgIG9wZXJhdGlvbk5hbWU6IHBhcmFtcy5vcGVyYXRpb25OYW1lID8/ICcnLFxuICAgIHN0YWNrVHJhY2UsXG4gICAgdGltZW91dEluTWlsbGlzZWNvbmRzOiBmdWxsT3B0aW9ucy50aW1lb3V0SW5NaWxsaXNlY29uZHNcbiAgfSkpO1xufVxuXG4vKipcbiAqIEV4ZWN1dGVzIGEgZnVuY3Rpb24gd2l0aCBhIHRpbWVvdXQuIElmIHRoZSBmdW5jdGlvbiBkb2VzIG5vdCBjb21wbGV0ZSB3aXRoaW4gdGhlIHNwZWNpZmllZCB0aW1lLCBpdCBpcyBjb25zaWRlcmVkIHRvIGhhdmUgdGltZWQgb3V0LlxuICpcbiAqIElmIGBERUJVRz1vYnNpZGlhbi1kZXYtdXRpbHM6QXN5bmM6cnVuV2l0aFRpbWVvdXRgIGlzIHNldCwgdGhlIGV4ZWN1dGlvbiBpcyBub3QgdGVybWluYXRlZCBhZnRlciB0aGUgdGltZW91dCBhbmQgdGhlIGZ1bmN0aW9uIGlzIGFsbG93ZWQgdG8gcnVuIGluZGVmaW5pdGVseS5cbiAqXG4gKiBAdHlwZVBhcmFtIFJlc3VsdCAtIFRoZSB0eXBlIG9mIHRoZSByZXN1bHQgZnJvbSB0aGUgYXN5bmNocm9ub3VzIGZ1bmN0aW9uLlxuICogQHBhcmFtIHBhcmFtcyAtIFRoZSBwYXJhbWV0ZXJzIGZvciB0aGUgZnVuY3Rpb24uXG4gKiBAcmV0dXJucyBBIHtAbGluayBQcm9taXNlfSB0aGF0IHJlc29sdmVzIHdpdGggdGhlIHJlc3VsdCBvZiB0aGUgYXN5bmNocm9ub3VzIGZ1bmN0aW9uIG9yIHJlamVjdHMgaWYgaXQgdGltZXMgb3V0LlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcnVuV2l0aFRpbWVvdXQ8UmVzdWx0PihwYXJhbXM6IFJ1bldpdGhUaW1lb3V0UGFyYW1zPFJlc3VsdD4pOiBQcm9taXNlPFJlc3VsdD4ge1xuICBjb25zdCBzdGFja1RyYWNlID0gcGFyYW1zLnN0YWNrVHJhY2UgPz8gZ2V0U3RhY2tUcmFjZSgxKTtcbiAgY29uc3Qgc3RhcnRUaW1lID0gcGVyZm9ybWFuY2Uubm93KCk7XG5cbiAgY29uc3QgcnVuQWJvcnRDb250cm9sbGVyID0gbmV3IEFib3J0Q29udHJvbGxlcigpO1xuICBjb25zdCB0aW1lb3V0QWJvcnRDb250cm9sbGVyID0gbmV3IEFib3J0Q29udHJvbGxlcigpO1xuXG4gIGxldCByZXN1bHQ6IG51bGwgfCBSZXN1bHQgPSBudWxsO1xuICBsZXQgaGFzUmVzdWx0ID0gZmFsc2U7XG4gIGxldCBpc0NvbXBsZXRlZCA9IGZhbHNlO1xuICBjb25zdCBydW5XaXRoVGltZW91dERlYnVnZ2VyID0gZ2V0TGliRGVidWdnZXIoJ0FzeW5jOnJ1bldpdGhUaW1lb3V0Jyk7XG4gIGNvbnN0IG9uVGltZW91dCA9IHBhcmFtcy5vblRpbWVvdXQgPz8gZGVmYXVsdE9uVGltZW91dDtcblxuICBhd2FpdCBQcm9taXNlLnJhY2UoW3J1bigpLCBpbm5lclRpbWVvdXQoKV0pO1xuICAvLyBUaGUgcmVzdWx0IGlzIG9ubHkgdmFsaWQgaWYgdGhlIHJ1biBmaW5pc2hlZCBvbiBpdHMgb3duLiBXaGVuIHRoZSB0aW1lb3V0IHRlcm1pbmF0ZWQgaXQsIHRoZVxuICAvLyBvcGVyYXRpb24gbWlnaHQgc3RpbGwgcmVzb2x2ZSBhZnRlcndhcmRzIChlLmcuIGEgcmV0cnkgbG9vcCB0aGF0IGV4aXRzIG9uIGFib3J0KSwgYnV0IHRoYXQgdmFsdWVcbiAgLy8gaXMgcGFzdCB0aGUgZGVhZGxpbmUgYW5kIG11c3QgYmUgdHJlYXRlZCBhcyBhIGZhaWx1cmUsIG5vdCBhIHN1Y2Nlc3MuXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW5uZWNlc3NhcnktY29uZGl0aW9uIC0tIEJvdGggbWlnaHQgY2hhbmdlIGluc2lkZSBgcnVuKClgL2Bpbm5lclRpbWVvdXQoKWAuIEVTTGludCBtaXN0YWtlbmx5IGRvZXMgbm90IHJlY29nbml6ZSBpdC5cbiAgaWYgKGhhc1Jlc3VsdCAmJiAhcnVuQWJvcnRDb250cm9sbGVyLnNpZ25hbC5hYm9ydGVkKSB7XG4gICAgcmV0dXJuIHJlc3VsdCBhcyBSZXN1bHQ7XG4gIH1cblxuICB0aHJvdyBuZXcgQ3VzdG9tU3RhY2tUcmFjZUVycm9yKHtcbiAgICBjYXVzZTogcnVuQWJvcnRDb250cm9sbGVyLnNpZ25hbC5yZWFzb24sXG4gICAgbWVzc2FnZTogJ1J1biB3aXRoIHRpbWVvdXQgZmFpbGVkJyxcbiAgICBzdGFja1RyYWNlXG4gIH0pO1xuXG4gIGFzeW5jIGZ1bmN0aW9uIHJ1bigpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0cnkge1xuICAgICAgcmVzdWx0ID0gYXdhaXQgcGFyYW1zLm9wZXJhdGlvbkZ1bmN0aW9uKHJ1bkFib3J0Q29udHJvbGxlci5zaWduYWwpO1xuICAgICAgY29uc3QgZHVyYXRpb24gPSBNYXRoLnRydW5jKHBlcmZvcm1hbmNlLm5vdygpIC0gc3RhcnRUaW1lKTtcbiAgICAgIHByaW50V2l0aFN0YWNrVHJhY2Uoe1xuICAgICAgICAkYXJndW1lbnRzOiBbe1xuICAgICAgICAgIGNvbnRleHQ6IHBhcmFtcy5jb250ZXh0LFxuICAgICAgICAgIG9wZXJhdGlvbkZ1bmN0aW9uOiBwYXJhbXMub3BlcmF0aW9uRnVuY3Rpb24sXG4gICAgICAgICAgb3BlcmF0aW9uTmFtZTogcGFyYW1zLm9wZXJhdGlvbk5hbWUgPz8gJydcbiAgICAgICAgfV0sXG4gICAgICAgIGRlYnVnZ2VySW5zdGFuY2U6IHJ1bldpdGhUaW1lb3V0RGVidWdnZXIsXG4gICAgICAgIG1lc3NhZ2U6IGBFeGVjdXRpb24gdGltZTogJHtTdHJpbmcoZHVyYXRpb24pfSBtaWxsaXNlY29uZHNgLFxuICAgICAgICBzdGFja1RyYWNlXG4gICAgICB9KTtcbiAgICAgIGhhc1Jlc3VsdCA9IHRydWU7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHJ1bkFib3J0Q29udHJvbGxlci5hYm9ydChlcnJvcik7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGlzQ29tcGxldGVkID0gdHJ1ZTtcbiAgICAgIHRpbWVvdXRBYm9ydENvbnRyb2xsZXIuYWJvcnQobmV3IEVycm9yKCdDb21wbGV0ZWQnKSk7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgZnVuY3Rpb24gaW5uZXJUaW1lb3V0KCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGF3YWl0IHNsZWVwKHsgYWJvcnRTaWduYWw6IHRpbWVvdXRBYm9ydENvbnRyb2xsZXIuc2lnbmFsLCBtaWxsaXNlY29uZHM6IHBhcmFtcy50aW1lb3V0SW5NaWxsaXNlY29uZHMgfSk7XG5cbiAgICBpZiAoaXNDb21wbGV0ZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgZHVyYXRpb24gPSBNYXRoLnRydW5jKHBlcmZvcm1hbmNlLm5vdygpIC0gc3RhcnRUaW1lKTtcbiAgICBwcmludFdpdGhTdGFja1RyYWNlKHtcbiAgICAgICRhcmd1bWVudHM6IFt7XG4gICAgICAgIGNvbnRleHQ6IHBhcmFtcy5jb250ZXh0LFxuICAgICAgICBvcGVyYXRpb25GdW5jdGlvbjogcGFyYW1zLm9wZXJhdGlvbkZ1bmN0aW9uLFxuICAgICAgICBvcGVyYXRpb25OYW1lOiBwYXJhbXMub3BlcmF0aW9uTmFtZSA/PyAnJ1xuICAgICAgfV0sXG4gICAgICBkZWJ1Z2dlckluc3RhbmNlOiBydW5XaXRoVGltZW91dERlYnVnZ2VyLFxuICAgICAgbWVzc2FnZTogYFRpbWVkIG91dCBhZnRlciAke1N0cmluZyhkdXJhdGlvbil9IG1pbGxpc2Vjb25kc2AsXG4gICAgICBzdGFja1RyYWNlXG4gICAgfSk7XG5cbiAgICBjb25zdCB0aW1lb3V0Q29udGV4dDogVGltZW91dENvbnRleHQgPSBub3JtYWxpemVPcHRpb25hbFByb3BlcnRpZXM8VGltZW91dENvbnRleHQ+KHtcbiAgICAgIGR1cmF0aW9uLFxuICAgICAgb25PcGVyYXRpb25Db21wbGV0ZWQoY2FsbGJhY2spIHtcbiAgICAgICAgdGltZW91dEFib3J0Q29udHJvbGxlci5zaWduYWwuYWRkRXZlbnRMaXN0ZW5lcignYWJvcnQnLCBjYWxsYmFjayk7XG4gICAgICB9LFxuICAgICAgb3BlcmF0aW9uTmFtZTogcGFyYW1zLm9wZXJhdGlvbk5hbWUgPz8gJycsXG4gICAgICB0ZXJtaW5hdGVPcGVyYXRpb24oKSB7XG4gICAgICAgIGNvbnN0IGVycm9yID0gbmV3IEVycm9yKGBUaW1lZCBvdXQgYWZ0ZXIgJHtTdHJpbmcoZHVyYXRpb24pfSBtaWxsaXNlY29uZHNgKTtcbiAgICAgICAgcnVuQWJvcnRDb250cm9sbGVyLmFib3J0KGVycm9yKTtcbiAgICAgICAgdGltZW91dEFib3J0Q29udHJvbGxlci5hYm9ydChlcnJvcik7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBvblRpbWVvdXQodGltZW91dENvbnRleHQpO1xuICAgIGF3YWl0IHdhaXRGb3JBYm9ydCh0aW1lb3V0QWJvcnRDb250cm9sbGVyLnNpZ25hbCk7XG4gIH1cbn1cblxuLyoqXG4gKiBHZXRzIHRoZSBuZXh0IHNldCBpbW1lZGlhdGUuXG4gKlxuICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiB0aGUgbmV4dCBzZXQgaW1tZWRpYXRlIGlzIGF2YWlsYWJsZS5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHNldEltbWVkaWF0ZUFzeW5jKCk6IFByb21pc2U8dm9pZD4ge1xuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICBzZXRJbW1lZGlhdGUoKCkgPT4ge1xuICAgICAgcmVzb2x2ZSgpO1xuICAgIH0pO1xuICB9KTtcbn1cblxuLyoqXG4gKiBEZWxheXMgZXhlY3V0aW9uIGZvciBhIHNwZWNpZmllZCBudW1iZXIgb2YgbWlsbGlzZWNvbmRzLlxuICpcbiAqIEBwYXJhbSBkZWxheSAtIFRoZSB0aW1lIHRvIHdhaXQgaW4gbWlsbGlzZWNvbmRzLlxuICogQHJldHVybnMgQSB7QGxpbmsgUHJvbWlzZX0gdGhhdCByZXNvbHZlcyBhZnRlciB0aGUgc3BlY2lmaWVkIGRlbGF5LlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gc2V0VGltZW91dEFzeW5jKGRlbGF5PzogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiB7XG4gIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgd2luZG93LnNldFRpbWVvdXQocmVzb2x2ZSwgZGVsYXkpO1xuICB9KTtcbn1cblxuLyoqXG4gKiBEZWxheXMgZXhlY3V0aW9uIGZvciBhIHNwZWNpZmllZCBudW1iZXIgb2YgbWlsbGlzZWNvbmRzLlxuICpcbiAqIEBwYXJhbSBwYXJhbXMgLSBUaGUgcGFyYW1ldGVycyBmb3IgdGhlIGZ1bmN0aW9uLlxuICogQHJldHVybnMgQSB7QGxpbmsgUHJvbWlzZX0gdGhhdCByZXNvbHZlcyBhZnRlciB0aGUgc3BlY2lmaWVkIGRlbGF5LlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gc2xlZXAocGFyYW1zOiBTbGVlcFBhcmFtcyk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCB7XG4gICAgYWJvcnRTaWduYWwsXG4gICAgbWlsbGlzZWNvbmRzLFxuICAgIHNob3VsZFRocm93T25BYm9ydFxuICB9ID0gcGFyYW1zO1xuICBhd2FpdCB3YWl0Rm9yQWJvcnQoYWJvcnRTaWduYWxBbnkoYWJvcnRTaWduYWwsIGFib3J0U2lnbmFsVGltZW91dChtaWxsaXNlY29uZHMpKSk7XG4gIGlmIChzaG91bGRUaHJvd09uQWJvcnQpIHtcbiAgICBhYm9ydFNpZ25hbD8udGhyb3dJZkFib3J0ZWQoKTtcbiAgfVxufVxuXG4vKipcbiAqIFJldHVybnMgYSB7QGxpbmsgUHJvbWlzZX0gdGhhdCByZWplY3RzIGFmdGVyIHRoZSBzcGVjaWZpZWQgdGltZW91dCBwZXJpb2QuXG4gKlxuICogQHBhcmFtIHBhcmFtcyAtIFRoZSBwYXJhbWV0ZXJzIGZvciB0aGUgZnVuY3Rpb24uXG4gKiBAcmV0dXJucyBBIHtAbGluayBQcm9taXNlfSB0aGF0IGFsd2F5cyByZWplY3RzIHdpdGggYSB0aW1lb3V0IGVycm9yLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gdGltZW91dChwYXJhbXM6IFRpbWVvdXRQYXJhbXMpOiBQcm9taXNlPG5ldmVyPiB7XG4gIGNvbnN0IHtcbiAgICBhYm9ydFNpZ25hbCxcbiAgICBzaG91bGRUaHJvd09uQWJvcnQsXG4gICAgdGltZW91dEluTWlsbGlzZWNvbmRzXG4gIH0gPSBwYXJhbXM7XG4gIGF3YWl0IHNsZWVwKG5vcm1hbGl6ZU9wdGlvbmFsUHJvcGVydGllczxTbGVlcFBhcmFtcz4oe1xuICAgIGFib3J0U2lnbmFsLFxuICAgIG1pbGxpc2Vjb25kczogdGltZW91dEluTWlsbGlzZWNvbmRzLFxuICAgIHNob3VsZFRocm93T25BYm9ydFxuICB9KSk7XG4gIHRocm93IG5ldyBFcnJvcihgVGltZWQgb3V0IGluICR7U3RyaW5nKHRpbWVvdXRJbk1pbGxpc2Vjb25kcyl9IG1pbGxpc2Vjb25kc2ApO1xufVxuXG4vKipcbiAqIENvbnZlcnRzIGFuIEFzeW5jSXRlcmFibGVJdGVyYXRvciB0byBhbiBhcnJheSBieSBjb25zdW1pbmcgYWxsIGl0cyBlbGVtZW50cy5cbiAqXG4gKiBAdHlwZVBhcmFtIFQgLSBUaGUgdHlwZSBvZiBlbGVtZW50cyBwcm9kdWNlZCBieSB0aGUgQXN5bmNJdGVyYWJsZUl0ZXJhdG9yLlxuICogQHBhcmFtIGl0ZXIgLSBUaGUgQXN5bmNJdGVyYWJsZUl0ZXJhdG9yIHRvIGNvbnZlcnQuXG4gKiBAcmV0dXJucyBBIHtAbGluayBQcm9taXNlfSB0aGF0IHJlc29sdmVzIHdpdGggYW4gYXJyYXkgb2YgYWxsIHRoZSBlbGVtZW50cyBpbiB0aGUgQXN5bmNJdGVyYWJsZUl0ZXJhdG9yLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gdG9BcnJheTxUPihpdGVyOiBBc3luY0l0ZXJhYmxlSXRlcmF0b3I8VD4pOiBQcm9taXNlPFRbXT4ge1xuICBjb25zdCBhcnJheTogVFtdID0gW107XG4gIGZvciBhd2FpdCAoY29uc3QgaXRlbSBvZiBpdGVyKSB7XG4gICAgYXJyYXkucHVzaChpdGVtKTtcbiAgfVxuICByZXR1cm4gYXJyYXk7XG59XG5cbmZ1bmN0aW9uIGRlZmF1bHRPblRpbWVvdXQoY29udGV4dDogVGltZW91dENvbnRleHQpOiB2b2lkIHtcbiAgY29udGV4dC50ZXJtaW5hdGVPcGVyYXRpb24oKTtcbn1cbiJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFjQSw4QkFLTztBQUNQLGtDQUE0QztBQUM1QyxtQkFHTztBQUNQLG1CQVFPO0FBQ1Asc0JBR087QUFDUCwwQkFBNEM7QUFDNUMseUJB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