@mnaoumov/obsidian-dev-toolkit 0.0.0 → 1.0.0

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 (252) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +7 -1
  3. package/bundlers/esbuild/package.json +6 -0
  4. package/bundlers/esbuild-impl/copy-to-obsidian-plugins-folder-plugin/package.json +6 -0
  5. package/bundlers/esbuild-impl/dependency/package.json +6 -0
  6. package/bundlers/esbuild-impl/fix-source-maps-plugin/package.json +6 -0
  7. package/bundlers/esbuild-impl/index/package.json +6 -0
  8. package/bundlers/esbuild-impl/obsidian-plugin-builder/package.json +6 -0
  9. package/bundlers/esbuild-impl/package.json +6 -0
  10. package/bundlers/esbuild-impl/preprocess-plugin/package.json +6 -0
  11. package/bundlers/esbuild-impl/rename-css-plugin/package.json +6 -0
  12. package/bundlers/index/package.json +6 -0
  13. package/bundlers/package.json +6 -0
  14. package/dist/demo-vault-helper/main.js +782 -0
  15. package/dist/demo-vault-helper/manifest.json +9 -0
  16. package/dist/integration-test-plugin/main.js +45388 -0
  17. package/dist/integration-test-plugin/manifest.json +8 -0
  18. package/dist/lib/cjs/bundlers/esbuild-impl/copy-to-obsidian-plugins-folder-plugin.cjs +335 -0
  19. package/dist/lib/cjs/bundlers/esbuild-impl/copy-to-obsidian-plugins-folder-plugin.d.cts +38 -0
  20. package/dist/lib/cjs/bundlers/esbuild-impl/dependency.cjs +253 -0
  21. package/dist/lib/cjs/bundlers/esbuild-impl/dependency.d.cts +20 -0
  22. package/dist/lib/cjs/bundlers/esbuild-impl/fix-source-maps-plugin.cjs +226 -0
  23. package/dist/lib/cjs/bundlers/esbuild-impl/fix-source-maps-plugin.d.cts +34 -0
  24. package/dist/lib/cjs/bundlers/esbuild-impl/index.cjs +192 -0
  25. package/dist/lib/cjs/bundlers/esbuild-impl/index.d.cts +7 -0
  26. package/dist/lib/cjs/bundlers/esbuild-impl/obsidian-plugin-builder.cjs +375 -0
  27. package/dist/lib/cjs/bundlers/esbuild-impl/obsidian-plugin-builder.d.cts +98 -0
  28. package/dist/lib/cjs/bundlers/esbuild-impl/preprocess-plugin.cjs +247 -0
  29. package/dist/lib/cjs/bundlers/esbuild-impl/preprocess-plugin.d.cts +30 -0
  30. package/dist/lib/cjs/bundlers/esbuild-impl/rename-css-plugin.cjs +184 -0
  31. package/dist/lib/cjs/bundlers/esbuild-impl/rename-css-plugin.d.cts +14 -0
  32. package/dist/lib/cjs/bundlers/esbuild.cjs +177 -0
  33. package/dist/lib/cjs/bundlers/esbuild.d.cts +11 -0
  34. package/dist/lib/cjs/bundlers/index.cjs +180 -0
  35. package/dist/lib/cjs/bundlers/index.d.cts +3 -0
  36. package/dist/lib/cjs/demo-vault-app-json.cjs +199 -0
  37. package/dist/lib/cjs/demo-vault-app-json.d.cts +93 -0
  38. package/dist/lib/cjs/demo-vault-buttons.cjs +580 -0
  39. package/dist/lib/cjs/demo-vault-buttons.d.cts +259 -0
  40. package/dist/lib/cjs/demo-vault-coverage.cjs +725 -0
  41. package/dist/lib/cjs/demo-vault-coverage.d.cts +533 -0
  42. package/dist/lib/cjs/demo-vault.cjs +309 -0
  43. package/dist/lib/cjs/demo-vault.d.cts +33 -0
  44. package/dist/lib/cjs/formatters/dprint.cjs +173 -0
  45. package/dist/lib/cjs/formatters/dprint.d.cts +15 -0
  46. package/dist/lib/cjs/formatters/index.cjs +177 -0
  47. package/dist/lib/cjs/formatters/index.d.cts +2 -0
  48. package/dist/lib/cjs/index.cjs +207 -0
  49. package/dist/lib/cjs/index.d.cts +16 -0
  50. package/dist/lib/cjs/integration-test-setup.cjs +142 -0
  51. package/dist/lib/cjs/integration-test-setup.d.cts +33 -0
  52. package/dist/lib/cjs/integration-test-vitest-global-setup.cjs +176 -0
  53. package/dist/lib/cjs/integration-test-vitest-global-setup.d.cts +39 -0
  54. package/dist/lib/cjs/jest-setup.cjs +147 -0
  55. package/dist/lib/cjs/jest-setup.d.cts +13 -0
  56. package/dist/lib/cjs/linters/eslint-config.cjs +365 -0
  57. package/dist/lib/cjs/linters/eslint-config.d.cts +25 -0
  58. package/dist/lib/cjs/linters/eslint-rules/index.cjs +201 -0
  59. package/dist/lib/cjs/linters/eslint-rules/index.d.cts +10 -0
  60. package/dist/lib/cjs/linters/eslint-rules/manifest-description.cjs +268 -0
  61. package/dist/lib/cjs/linters/eslint-rules/manifest-description.d.cts +54 -0
  62. package/dist/lib/cjs/linters/eslint-rules/manifest-helpers.cjs +231 -0
  63. package/dist/lib/cjs/linters/eslint-rules/manifest-helpers.d.cts +141 -0
  64. package/dist/lib/cjs/linters/eslint-rules/manifest-id.cjs +228 -0
  65. package/dist/lib/cjs/linters/eslint-rules/manifest-id.d.cts +32 -0
  66. package/dist/lib/cjs/linters/eslint-rules/manifest-name.cjs +229 -0
  67. package/dist/lib/cjs/linters/eslint-rules/manifest-name.d.cts +30 -0
  68. package/dist/lib/cjs/linters/eslint-rules/manifest-schema.cjs +329 -0
  69. package/dist/lib/cjs/linters/eslint-rules/manifest-schema.d.cts +45 -0
  70. package/dist/lib/cjs/linters/eslint-rules/no-over-cap-wait-in-eval-in-obsidian.cjs +670 -0
  71. package/dist/lib/cjs/linters/eslint-rules/no-over-cap-wait-in-eval-in-obsidian.d.cts +10 -0
  72. package/dist/lib/cjs/linters/eslint-rules/no-untrusted-input-events.cjs +260 -0
  73. package/dist/lib/cjs/linters/eslint-rules/no-untrusted-input-events.d.cts +10 -0
  74. package/dist/lib/cjs/linters/eslint-rules/obsidian-dev-utils-plugin.cjs +186 -0
  75. package/dist/lib/cjs/linters/eslint-rules/obsidian-dev-utils-plugin.d.cts +13 -0
  76. package/dist/lib/cjs/linters/eslint-rules/require-component-suffix.cjs +291 -0
  77. package/dist/lib/cjs/linters/eslint-rules/require-component-suffix.d.cts +18 -0
  78. package/dist/lib/cjs/linters/eslint.cjs +173 -0
  79. package/dist/lib/cjs/linters/eslint.d.cts +15 -0
  80. package/dist/lib/cjs/linters/index.cjs +189 -0
  81. package/dist/lib/cjs/linters/index.d.cts +6 -0
  82. package/dist/lib/cjs/linters/markdownlint.cjs +173 -0
  83. package/dist/lib/cjs/linters/markdownlint.d.cts +15 -0
  84. package/dist/lib/cjs/linters/obsidianmd-rule-custom-message.cjs +189 -0
  85. package/dist/lib/cjs/linters/obsidianmd-rule-custom-message.d.cts +40 -0
  86. package/dist/lib/cjs/obsidian-plugin-repo-paths.cjs +229 -0
  87. package/dist/lib/cjs/obsidian-plugin-repo-paths.d.cts +253 -0
  88. package/dist/lib/cjs/setup.cjs +176 -0
  89. package/dist/lib/cjs/setup.d.cts +21 -0
  90. package/dist/lib/cjs/templates.cjs +185 -0
  91. package/dist/lib/cjs/templates.d.cts +13 -0
  92. package/dist/lib/cjs/test-runners/index.cjs +183 -0
  93. package/dist/lib/cjs/test-runners/index.d.cts +4 -0
  94. package/dist/lib/cjs/test-runners/integration-test-plugin.cjs +224 -0
  95. package/dist/lib/cjs/test-runners/integration-test-plugin.d.cts +44 -0
  96. package/dist/lib/cjs/test-runners/performance-eval-cap.cjs +170 -0
  97. package/dist/lib/cjs/test-runners/performance-eval-cap.d.cts +27 -0
  98. package/dist/lib/cjs/test-runners/stale-build-global-setup.cjs +230 -0
  99. package/dist/lib/cjs/test-runners/stale-build-global-setup.d.cts +86 -0
  100. package/dist/lib/cjs/test-runners/vitest-config.cjs +497 -0
  101. package/dist/lib/cjs/test-runners/vitest-config.d.cts +200 -0
  102. package/dist/lib/cjs/version.cjs +275 -0
  103. package/dist/lib/cjs/version.d.cts +92 -0
  104. package/dist/lib/cjs/vitest-setup.cjs +147 -0
  105. package/dist/lib/cjs/vitest-setup.d.cts +11 -0
  106. package/dist/lib/esm/bundlers/esbuild-impl/copy-to-obsidian-plugins-folder-plugin.d.mts +38 -0
  107. package/dist/lib/esm/bundlers/esbuild-impl/copy-to-obsidian-plugins-folder-plugin.mjs +226 -0
  108. package/dist/lib/esm/bundlers/esbuild-impl/dependency.d.mts +20 -0
  109. package/dist/lib/esm/bundlers/esbuild-impl/dependency.mjs +138 -0
  110. package/dist/lib/esm/bundlers/esbuild-impl/fix-source-maps-plugin.d.mts +34 -0
  111. package/dist/lib/esm/bundlers/esbuild-impl/fix-source-maps-plugin.mjs +116 -0
  112. package/dist/lib/esm/bundlers/esbuild-impl/index.d.mts +7 -0
  113. package/dist/lib/esm/bundlers/esbuild-impl/index.mjs +64 -0
  114. package/dist/lib/esm/bundlers/esbuild-impl/obsidian-plugin-builder.d.mts +98 -0
  115. package/dist/lib/esm/bundlers/esbuild-impl/obsidian-plugin-builder.mjs +255 -0
  116. package/dist/lib/esm/bundlers/esbuild-impl/preprocess-plugin.d.mts +30 -0
  117. package/dist/lib/esm/bundlers/esbuild-impl/preprocess-plugin.mjs +134 -0
  118. package/dist/lib/esm/bundlers/esbuild-impl/rename-css-plugin.d.mts +14 -0
  119. package/dist/lib/esm/bundlers/esbuild-impl/rename-css-plugin.mjs +71 -0
  120. package/dist/lib/esm/bundlers/esbuild.d.mts +11 -0
  121. package/dist/lib/esm/bundlers/esbuild.mjs +66 -0
  122. package/dist/lib/esm/bundlers/index.d.mts +3 -0
  123. package/dist/lib/esm/bundlers/index.mjs +56 -0
  124. package/dist/lib/esm/demo-vault-app-json.d.mts +93 -0
  125. package/dist/lib/esm/demo-vault-app-json.mjs +83 -0
  126. package/dist/lib/esm/demo-vault-buttons.d.mts +259 -0
  127. package/dist/lib/esm/demo-vault-buttons.mjs +460 -0
  128. package/dist/lib/esm/demo-vault-coverage.d.mts +533 -0
  129. package/dist/lib/esm/demo-vault-coverage.mjs +626 -0
  130. package/dist/lib/esm/demo-vault.d.mts +33 -0
  131. package/dist/lib/esm/demo-vault.mjs +205 -0
  132. package/dist/lib/esm/formatters/dprint.d.mts +15 -0
  133. package/dist/lib/esm/formatters/dprint.mjs +60 -0
  134. package/dist/lib/esm/formatters/index.d.mts +2 -0
  135. package/dist/lib/esm/formatters/index.mjs +54 -0
  136. package/dist/lib/esm/index.d.mts +16 -0
  137. package/dist/lib/esm/index.mjs +74 -0
  138. package/dist/lib/esm/integration-test-setup.d.mts +33 -0
  139. package/dist/lib/esm/integration-test-setup.mjs +52 -0
  140. package/dist/lib/esm/integration-test-vitest-global-setup.d.mts +39 -0
  141. package/dist/lib/esm/integration-test-vitest-global-setup.mjs +65 -0
  142. package/dist/lib/esm/jest-setup.d.mts +13 -0
  143. package/dist/lib/esm/jest-setup.mjs +61 -0
  144. package/dist/lib/esm/linters/eslint-config.d.mts +25 -0
  145. package/dist/lib/esm/linters/eslint-config.mjs +247 -0
  146. package/dist/lib/esm/linters/eslint-rules/index.d.mts +10 -0
  147. package/dist/lib/esm/linters/eslint-rules/index.mjs +70 -0
  148. package/dist/lib/esm/linters/eslint-rules/manifest-description.d.mts +54 -0
  149. package/dist/lib/esm/linters/eslint-rules/manifest-description.mjs +154 -0
  150. package/dist/lib/esm/linters/eslint-rules/manifest-helpers.d.mts +141 -0
  151. package/dist/lib/esm/linters/eslint-rules/manifest-helpers.mjs +98 -0
  152. package/dist/lib/esm/linters/eslint-rules/manifest-id.d.mts +32 -0
  153. package/dist/lib/esm/linters/eslint-rules/manifest-id.mjs +117 -0
  154. package/dist/lib/esm/linters/eslint-rules/manifest-name.d.mts +30 -0
  155. package/dist/lib/esm/linters/eslint-rules/manifest-name.mjs +118 -0
  156. package/dist/lib/esm/linters/eslint-rules/manifest-schema.d.mts +45 -0
  157. package/dist/lib/esm/linters/eslint-rules/manifest-schema.mjs +220 -0
  158. package/dist/lib/esm/linters/eslint-rules/no-over-cap-wait-in-eval-in-obsidian.d.mts +10 -0
  159. package/dist/lib/esm/linters/eslint-rules/no-over-cap-wait-in-eval-in-obsidian.mjs +559 -0
  160. package/dist/lib/esm/linters/eslint-rules/no-untrusted-input-events.d.mts +10 -0
  161. package/dist/lib/esm/linters/eslint-rules/no-untrusted-input-events.mjs +146 -0
  162. package/dist/lib/esm/linters/eslint-rules/obsidian-dev-utils-plugin.d.mts +13 -0
  163. package/dist/lib/esm/linters/eslint-rules/obsidian-dev-utils-plugin.mjs +73 -0
  164. package/dist/lib/esm/linters/eslint-rules/require-component-suffix.d.mts +18 -0
  165. package/dist/lib/esm/linters/eslint-rules/require-component-suffix.mjs +175 -0
  166. package/dist/lib/esm/linters/eslint.d.mts +15 -0
  167. package/dist/lib/esm/linters/eslint.mjs +60 -0
  168. package/dist/lib/esm/linters/index.d.mts +6 -0
  169. package/dist/lib/esm/linters/index.mjs +62 -0
  170. package/dist/lib/esm/linters/markdownlint.d.mts +15 -0
  171. package/dist/lib/esm/linters/markdownlint.mjs +60 -0
  172. package/dist/lib/esm/linters/obsidianmd-rule-custom-message.d.mts +40 -0
  173. package/dist/lib/esm/linters/obsidianmd-rule-custom-message.mjs +75 -0
  174. package/dist/lib/esm/obsidian-plugin-repo-paths.d.mts +253 -0
  175. package/dist/lib/esm/obsidian-plugin-repo-paths.mjs +116 -0
  176. package/dist/lib/esm/setup.d.mts +21 -0
  177. package/dist/lib/esm/setup.mjs +63 -0
  178. package/dist/lib/esm/templates.d.mts +13 -0
  179. package/dist/lib/esm/templates.mjs +65 -0
  180. package/dist/lib/esm/test-runners/index.d.mts +4 -0
  181. package/dist/lib/esm/test-runners/index.mjs +58 -0
  182. package/dist/lib/esm/test-runners/integration-test-plugin.d.mts +44 -0
  183. package/dist/lib/esm/test-runners/integration-test-plugin.mjs +102 -0
  184. package/dist/lib/esm/test-runners/performance-eval-cap.d.mts +27 -0
  185. package/dist/lib/esm/test-runners/performance-eval-cap.mjs +56 -0
  186. package/dist/lib/esm/test-runners/stale-build-global-setup.d.mts +86 -0
  187. package/dist/lib/esm/test-runners/stale-build-global-setup.mjs +123 -0
  188. package/dist/lib/esm/test-runners/vitest-config.d.mts +200 -0
  189. package/dist/lib/esm/test-runners/vitest-config.mjs +377 -0
  190. package/dist/lib/esm/version.d.mts +92 -0
  191. package/dist/lib/esm/version.mjs +168 -0
  192. package/dist/lib/esm/vitest-setup.d.mts +11 -0
  193. package/dist/lib/esm/vitest-setup.mjs +61 -0
  194. package/dist/templates/.markdownlint-cli2.mjs +4 -0
  195. package/dist/templates/.nano-staged.mjs +4 -0
  196. package/dist/templates/commitlint.config.ts +3 -0
  197. package/dist/templates/dprint.json +26 -0
  198. package/dist/templates/eslint.config.mts +3 -0
  199. package/dist/templates/scripts/build/build-clean.ts +4 -0
  200. package/dist/templates/scripts/build/build-compile-svelte.ts +4 -0
  201. package/dist/templates/scripts/build/build-compile-typescript.ts +4 -0
  202. package/dist/templates/scripts/build/build-compile.ts +4 -0
  203. package/dist/templates/scripts/build/build-templates.ts +4 -0
  204. package/dist/templates/scripts/bundlers/esbuild/build.ts +4 -0
  205. package/dist/templates/scripts/bundlers/esbuild/dev.ts +4 -0
  206. package/dist/templates/scripts/commitlint-config.ts +3 -0
  207. package/dist/templates/scripts/eslint-config.ts +10 -0
  208. package/dist/templates/scripts/formatters/dprint/format-check.ts +8 -0
  209. package/dist/templates/scripts/formatters/dprint/format.ts +8 -0
  210. package/dist/templates/scripts/gate/gate.ts +10 -0
  211. package/dist/templates/scripts/linters/cspell/spellcheck.ts +8 -0
  212. package/dist/templates/scripts/linters/eslint/lint-fix.ts +8 -0
  213. package/dist/templates/scripts/linters/eslint/lint.ts +8 -0
  214. package/dist/templates/scripts/linters/markdownlint/lint-md-fix.ts +8 -0
  215. package/dist/templates/scripts/linters/markdownlint/lint-md.ts +8 -0
  216. package/dist/templates/scripts/linters/over-exposure/find-overexposed-fix.ts +25 -0
  217. package/dist/templates/scripts/linters/over-exposure/find-overexposed.ts +15 -0
  218. package/dist/templates/scripts/markdownlint-cli2-config.ts +3 -0
  219. package/dist/templates/scripts/nano-staged-config.ts +3 -0
  220. package/dist/templates/scripts/test-runners/vitest/test-coverage.ts +4 -0
  221. package/dist/templates/scripts/test-runners/vitest/test-watch.ts +4 -0
  222. package/dist/templates/scripts/test-runners/vitest/test.ts +4 -0
  223. package/dist/templates/scripts/version/version.ts +10 -0
  224. package/dist/templates/scripts/vitest-config.ts +3 -0
  225. package/dist/templates/vitest.config.ts +3 -0
  226. package/formatters/dprint/package.json +6 -0
  227. package/formatters/index/package.json +6 -0
  228. package/formatters/package.json +6 -0
  229. package/linters/eslint/package.json +6 -0
  230. package/linters/eslint-config/package.json +6 -0
  231. package/linters/eslint-rules/index/package.json +6 -0
  232. package/linters/eslint-rules/manifest-description/package.json +6 -0
  233. package/linters/eslint-rules/manifest-helpers/package.json +6 -0
  234. package/linters/eslint-rules/manifest-id/package.json +6 -0
  235. package/linters/eslint-rules/manifest-name/package.json +6 -0
  236. package/linters/eslint-rules/manifest-schema/package.json +6 -0
  237. package/linters/eslint-rules/no-over-cap-wait-in-eval-in-obsidian/package.json +6 -0
  238. package/linters/eslint-rules/no-untrusted-input-events/package.json +6 -0
  239. package/linters/eslint-rules/obsidian-dev-utils-plugin/package.json +6 -0
  240. package/linters/eslint-rules/package.json +6 -0
  241. package/linters/eslint-rules/require-component-suffix/package.json +6 -0
  242. package/linters/index/package.json +6 -0
  243. package/linters/markdownlint/package.json +6 -0
  244. package/linters/obsidianmd-rule-custom-message/package.json +6 -0
  245. package/linters/package.json +6 -0
  246. package/package.json +241 -13
  247. package/test-runners/index/package.json +6 -0
  248. package/test-runners/integration-test-plugin/package.json +6 -0
  249. package/test-runners/package.json +6 -0
  250. package/test-runners/performance-eval-cap/package.json +6 -0
  251. package/test-runners/stale-build-global-setup/package.json +6 -0
  252. package/test-runners/vitest-config/package.json +6 -0
@@ -0,0 +1,670 @@
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
+ (function () {
7
+ function ensureDisposeSymbols(symbolConstructor = Symbol) {
8
+ symbolConstructor.asyncDispose ??= symbolConstructor.for('Symbol.asyncDispose');
9
+ symbolConstructor.dispose ??= symbolConstructor.for('Symbol.dispose');
10
+ }
11
+
12
+ function ensureBrowserProcess() {
13
+ const browserProcess = {
14
+ browser: true,
15
+ cwd() {
16
+ return '/';
17
+ },
18
+ env: {},
19
+ platform: 'android'
20
+ };
21
+
22
+ // eslint-disable-next-line obsidianmd/no-global-this, unicorn/no-unnecessary-global-this -- Must stay `globalThis`-qualified: in the emitted banner a bare `process` is a free identifier, so reading it where the host has none throws a ReferenceError instead of yielding `undefined`. That is the very case this function exists to handle.
23
+ const existingProcess = globalThis.process;
24
+
25
+ if (!existingProcess) {
26
+ // eslint-disable-next-line obsidianmd/no-global-this -- Actively use globalThis.
27
+ globalThis.process = browserProcess;
28
+ return;
29
+ }
30
+
31
+ if (existingProcess.versions?.node) {
32
+ return;
33
+ }
34
+
35
+ const existingProcessRecord = existingProcess;
36
+
37
+ for (const [key, value] of Object.entries(browserProcess)) {
38
+ existingProcessRecord[key] ??= value;
39
+ }
40
+
41
+ existingProcessRecord['browser'] = true;
42
+ }
43
+
44
+ function keepName($unknown) {
45
+ return $unknown;
46
+ }
47
+
48
+ (function initCjs() {
49
+ // eslint-disable-next-line obsidianmd/no-global-this -- Actively use globalThis.
50
+ const globalThisRecord = globalThis;
51
+ ensureDisposeSymbols();
52
+ globalThisRecord['__name'] ??= keepName;
53
+ globalThisRecord['__extractDefault'] ??= extractDefault;
54
+
55
+ ensureBrowserProcess();
56
+
57
+ // eslint-disable-next-line unicorn/consistent-function-scoping -- Serialized with initCjs into the banner; at module scope it would be left out of it.
58
+ function extractDefault(module) {
59
+ return module && module.__esModule && 'default' in module ? module.default : module;
60
+ }
61
+ })();
62
+ })();
63
+ (function patchObsidianRequire() {
64
+ const originalRequire = require;
65
+ if (!originalRequire || originalRequire.__isPatched) {
66
+ return;
67
+ }
68
+
69
+ // eslint-disable-next-line no-global-assign, no-implicit-globals -- We need to patch the `require()` function.
70
+ require = Object.assign(
71
+ (id) => requirePatched(id),
72
+ originalRequire,
73
+ {
74
+ __isPatched: true
75
+ }
76
+ );
77
+
78
+ function extractDefault(module) {
79
+ return module && module.__esModule && 'default' in module ? module.default : module;
80
+ }
81
+
82
+ const OBSIDIAN_BUILT_IN_MODULE_NAMES = new Set([
83
+ '@codemirror/autocomplete',
84
+ '@codemirror/collab',
85
+ '@codemirror/commands',
86
+ '@codemirror/language',
87
+ '@codemirror/lint',
88
+ '@codemirror/search',
89
+ '@codemirror/state',
90
+ '@codemirror/text',
91
+ '@codemirror/view',
92
+ '@lezer/common',
93
+ '@lezer/highlight',
94
+ '@lezer/lr',
95
+ 'obsidian']
96
+ );
97
+
98
+ const DEPRECATED_OBSIDIAN_BUILT_IN_MODULE_NAMES = new Set([
99
+ '@codemirror/closebrackets',
100
+ '@codemirror/comment',
101
+ '@codemirror/fold',
102
+ '@codemirror/gutter',
103
+ '@codemirror/highlight',
104
+ '@codemirror/history',
105
+ '@codemirror/matchbrackets',
106
+ '@codemirror/panel',
107
+ '@codemirror/rangeset',
108
+ '@codemirror/rectangular-selection',
109
+ '@codemirror/stream-parser',
110
+ '@codemirror/tooltip']
111
+ );
112
+
113
+ function requirePatched(id) {
114
+ if (OBSIDIAN_BUILT_IN_MODULE_NAMES.has(id) || DEPRECATED_OBSIDIAN_BUILT_IN_MODULE_NAMES.has(id)) {
115
+ return originalRequire?.(id);
116
+ }
117
+
118
+ // eslint-disable-next-line @typescript-eslint/no-deprecated, obsidianmd/no-global-this -- Need access to app. Actively use globalThis.
119
+ if (globalThis.app.isMobile) {
120
+ if (id === 'process' || id === 'node:process') {
121
+ // eslint-disable-next-line no-console -- Valid usage.
122
+ console.debug(`The most likely you can safely ignore this error. Module not found: ${id}. Fake process object is returned instead.`);
123
+
124
+ return process;
125
+ }
126
+ } else {
127
+ const module = originalRequire?.(id);
128
+ if (module) {
129
+ return extractDefault(module);
130
+ }
131
+ }
132
+
133
+ // eslint-disable-next-line no-console -- Valid usage.
134
+ console.debug(`The most likely you can safely ignore this error. Module not found: ${id}. Empty object is returned instead.`);
135
+ return {};
136
+ }
137
+ })();
138
+
139
+ "use strict";
140
+ var __defProp = Object.defineProperty;
141
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
142
+ var __getOwnPropNames = Object.getOwnPropertyNames;
143
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
144
+ var __export = (target, all) => {
145
+ for (var name in all)
146
+ __defProp(target, name, { get: all[name], enumerable: true });
147
+ };
148
+ var __copyProps = (to, from, except, desc) => {
149
+ if (from && typeof from === "object" || typeof from === "function") {
150
+ for (let key of __getOwnPropNames(from))
151
+ if (!__hasOwnProp.call(to, key) && key !== except)
152
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
153
+ }
154
+ return to;
155
+ };
156
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
157
+ var no_over_cap_wait_in_eval_in_obsidian_exports = {};
158
+ __export(no_over_cap_wait_in_eval_in_obsidian_exports, {
159
+ MESSAGE_ID: () => MESSAGE_ID,
160
+ noOverCapWaitInEvalInObsidian: () => noOverCapWaitInEvalInObsidian
161
+ });
162
+ module.exports = __toCommonJS(no_over_cap_wait_in_eval_in_obsidian_exports);
163
+ var import_ts_estree_node = require('@mnaoumov/typescript-dev-toolkit/linters/eslint-rules/ts-estree-node');
164
+ var import_obsidian_integration_testing = require('obsidian-integration-testing');
165
+ var import_performance_eval_cap = require('../../test-runners/performance-eval-cap.cjs');
166
+ const MESSAGE_ID = "noOverCapWaitInEvalInObsidian";
167
+ const WAIT_UNTIL_DEFAULT_TIMEOUT_IN_MILLISECONDS = 5e3;
168
+ const INPUT_PROPERTY_NAME = "input";
169
+ const SLEEP_CALLEE_NAME = "sleep";
170
+ const TIMEOUT_PROPERTY_NAME = "timeoutInMilliseconds";
171
+ const WAIT_UNTIL_CALLEE_NAME = "waitUntil";
172
+ const CLOCK_OBJECT_NAMES = /* @__PURE__ */ new Set(["Date", "performance"]);
173
+ const NOW_METHOD_NAME = "now";
174
+ const CLOSURE_NAMES_BY_CALLEE_NAME = /* @__PURE__ */ new Map([
175
+ ["evalInObsidian", ["callback"]],
176
+ ["pollInObsidian", ["poll", "start"]]
177
+ ]);
178
+ const noOverCapWaitInEvalInObsidian = {
179
+ create(context) {
180
+ const options = context.options[0];
181
+ const defaultCapInMilliseconds = context.filename.endsWith(import_performance_eval_cap.DESKTOP_PERFORMANCE_TEST_FILE_SUFFIX) ? import_performance_eval_cap.PERFORMANCE_EVAL_CAP_IN_MILLISECONDS : import_obsidian_integration_testing.DEFAULT_EVAL_CAP_IN_MILLISECONDS;
182
+ const capInMilliseconds = options?.capInMilliseconds ?? defaultCapInMilliseconds;
183
+ const callGraph = {
184
+ callCountByCalleeNodeByCallerNode: /* @__PURE__ */ new Map(),
185
+ stateByClosureNode: /* @__PURE__ */ new Map(),
186
+ waitInMillisecondsByFunctionNode: /* @__PURE__ */ new Map()
187
+ };
188
+ function addCall(target, calleeNode, callCount) {
189
+ const state = readClosureState(target);
190
+ state.functionNodes.add(calleeNode);
191
+ const callCountByCalleeNode = callGraph.callCountByCalleeNodeByCallerNode.get(target.functionNode) ?? /* @__PURE__ */ new Map();
192
+ callGraph.callCountByCalleeNodeByCallerNode.set(target.functionNode, callCountByCalleeNode);
193
+ callCountByCalleeNode.set(calleeNode, (callCountByCalleeNode.get(calleeNode) ?? 0) + callCount);
194
+ }
195
+ function addWait(target, waitInMilliseconds) {
196
+ readClosureState(target);
197
+ const runningTotalInMilliseconds = callGraph.waitInMillisecondsByFunctionNode.get(target.functionNode) ?? 0;
198
+ callGraph.waitInMillisecondsByFunctionNode.set(target.functionNode, runningTotalInMilliseconds + waitInMilliseconds);
199
+ }
200
+ function chargeHelperCall(callNode, target) {
201
+ const helperNode = readCalledHelperNode(callNode, target.closure, context);
202
+ if (!helperNode) {
203
+ return;
204
+ }
205
+ addCall(target, helperNode, readLoopMultiplier(callNode, target, context));
206
+ }
207
+ function chargeLoopDeadline(node) {
208
+ const loopNode = (0, import_ts_estree_node.toTSESTreeNode)(node);
209
+ const target = findChargeTarget(loopNode);
210
+ if (!target) {
211
+ return;
212
+ }
213
+ const deadlineInMilliseconds = readLoopDeadlineInMilliseconds(loopNode, target.closure, context);
214
+ if (deadlineInMilliseconds === null) {
215
+ return;
216
+ }
217
+ addWait(target, deadlineInMilliseconds * readLoopMultiplier(loopNode, target, context));
218
+ }
219
+ function chargeWaitCall(callNode, target) {
220
+ const budgetExpression = readWaitBudgetExpression(callNode);
221
+ if (budgetExpression === void 0) {
222
+ return;
223
+ }
224
+ const waitInMilliseconds = budgetExpression === null ? WAIT_UNTIL_DEFAULT_TIMEOUT_IN_MILLISECONDS : resolveNumber(budgetExpression, target.closure, context);
225
+ if (waitInMilliseconds === null) {
226
+ return;
227
+ }
228
+ addWait(target, waitInMilliseconds * readLoopMultiplier(callNode, target, context));
229
+ }
230
+ function readClosureState(target) {
231
+ const state = callGraph.stateByClosureNode.get(target.closure.closureNode) ?? {
232
+ closureNode: target.closure.closureNode,
233
+ functionNodes: /* @__PURE__ */ new Set(),
234
+ reportNode: target.closure.reportNode
235
+ };
236
+ callGraph.stateByClosureNode.set(target.closure.closureNode, state);
237
+ state.functionNodes.add(target.functionNode);
238
+ return state;
239
+ }
240
+ return {
241
+ "CallExpression"(node) {
242
+ const callNode = (0, import_ts_estree_node.toTSESTreeNode)(node);
243
+ const target = findChargeTarget(callNode);
244
+ if (!target) {
245
+ return;
246
+ }
247
+ chargeWaitCall(callNode, target);
248
+ chargeHelperCall(callNode, target);
249
+ },
250
+ DoWhileStatement: chargeLoopDeadline,
251
+ ForStatement: chargeLoopDeadline,
252
+ "Program:exit"() {
253
+ for (const state of callGraph.stateByClosureNode.values()) {
254
+ const totalInMilliseconds = readClosureWaitInMilliseconds(state, callGraph);
255
+ if (totalInMilliseconds < capInMilliseconds) {
256
+ continue;
257
+ }
258
+ context.report({
259
+ data: {
260
+ capInMilliseconds: String(capInMilliseconds),
261
+ totalInMilliseconds: String(totalInMilliseconds)
262
+ },
263
+ messageId: MESSAGE_ID,
264
+ node: state.reportNode
265
+ });
266
+ }
267
+ },
268
+ WhileStatement: chargeLoopDeadline
269
+ };
270
+ },
271
+ meta: {
272
+ docs: {
273
+ description: "Disallow an in-Obsidian closure declaring more waiting than the transport's script-timeout cap allows"
274
+ },
275
+ messages: {
276
+ [MESSAGE_ID]: "This closure declares {{ totalInMilliseconds }} ms of waiting, at or over the transport's {{ capInMilliseconds }} ms cap, so it can only ever die as a bare `script timeout`: wait in Node instead, with a short DOM-reading `pollInObsidian` `poll`, an `until` evaluated in Node, and the long budget in `timeoutInMilliseconds`."
277
+ },
278
+ schema: [{
279
+ additionalProperties: false,
280
+ properties: {
281
+ capInMilliseconds: {
282
+ minimum: 1,
283
+ type: "integer"
284
+ }
285
+ },
286
+ type: "object"
287
+ }],
288
+ type: "problem"
289
+ }
290
+ };
291
+ function collectReachableFunctionNodes(functionNode, callGraph, reachableNodes) {
292
+ if (reachableNodes.has(functionNode)) {
293
+ return;
294
+ }
295
+ reachableNodes.add(functionNode);
296
+ for (const calleeNode of callGraph.callCountByCalleeNodeByCallerNode.get(functionNode)?.keys() ?? []) {
297
+ collectReachableFunctionNodes(calleeNode, callGraph, reachableNodes);
298
+ }
299
+ }
300
+ function findChargeTarget(node) {
301
+ let innermostFunctionNode;
302
+ let currentNode = node.parent;
303
+ while (currentNode) {
304
+ const closure = readEvalClosure(currentNode);
305
+ if (closure) {
306
+ return {
307
+ closure,
308
+ functionNode: innermostFunctionNode ?? closure.closureNode
309
+ };
310
+ }
311
+ if (!innermostFunctionNode && isFunctionNode(currentNode)) {
312
+ innermostFunctionNode = currentNode;
313
+ }
314
+ currentNode = currentNode.parent;
315
+ }
316
+ return null;
317
+ }
318
+ function findVariable(scope, name) {
319
+ let currentScope = scope;
320
+ while (currentScope) {
321
+ const variable = currentScope.variables.find((candidate) => candidate.name === name);
322
+ if (variable) {
323
+ return variable;
324
+ }
325
+ currentScope = currentScope.upper;
326
+ }
327
+ return null;
328
+ }
329
+ function isAssignmentExpression(node) {
330
+ return node.type === "AssignmentExpression";
331
+ }
332
+ function isBinaryExpression(node) {
333
+ return node.type === "BinaryExpression";
334
+ }
335
+ function isCallExpression(node) {
336
+ return node.type === "CallExpression";
337
+ }
338
+ function isClosureFunction(node) {
339
+ return node.type === "FunctionExpression" || node.type === "ArrowFunctionExpression";
340
+ }
341
+ function isDeclaredInsideClosure(functionNode, closure) {
342
+ let currentNode = functionNode.parent;
343
+ while (currentNode) {
344
+ if (currentNode === closure.closureNode) {
345
+ return true;
346
+ }
347
+ currentNode = currentNode.parent;
348
+ }
349
+ return false;
350
+ }
351
+ function isForStatement(node) {
352
+ return node.type === "ForStatement";
353
+ }
354
+ function isFunctionNode(node) {
355
+ return isClosureFunction(node) || node.type === "FunctionDeclaration";
356
+ }
357
+ function isIdentifier(node) {
358
+ return node.type === "Identifier";
359
+ }
360
+ function isLogicalAndExpression(node) {
361
+ return node.type === "LogicalExpression" && node.operator === "&&";
362
+ }
363
+ function isLoopStatement(node) {
364
+ return node.type === "WhileStatement" || node.type === "DoWhileStatement" || isForStatement(node);
365
+ }
366
+ function isMemberExpression(node) {
367
+ return node.type === "MemberExpression";
368
+ }
369
+ function isNumericLiteral(node) {
370
+ return node.type === "Literal" && typeof node.value === "number";
371
+ }
372
+ function isObjectExpression(node) {
373
+ return node.type === "ObjectExpression";
374
+ }
375
+ function isObjectPattern(node) {
376
+ return node.type === "ObjectPattern";
377
+ }
378
+ function isProperty(node) {
379
+ return node.type === "Property";
380
+ }
381
+ function isUpdateExpression(node) {
382
+ return node.type === "UpdateExpression";
383
+ }
384
+ function isVariableDeclaration(node) {
385
+ return node.type === "VariableDeclaration";
386
+ }
387
+ function isVariableDeclarator(node) {
388
+ return node.type === "VariableDeclarator";
389
+ }
390
+ function readBoundExpression(node, closure, context) {
391
+ const variable = findVariable(context.sourceCode.getScope(node), node.name);
392
+ if (!variable) {
393
+ return null;
394
+ }
395
+ for (const definition of variable.defs) {
396
+ const definitionNode = (0, import_ts_estree_node.toTSESTreeNode)(definition.node);
397
+ if (isVariableDeclarator(definitionNode) && definitionNode.init) {
398
+ return definitionNode.init;
399
+ }
400
+ if (definitionNode === closure.closureNode) {
401
+ const inputKey = readParameterInputKey(closure.closureNode, node.name);
402
+ return inputKey === null ? null : readInputPropertyValue(closure.paramsNode, inputKey);
403
+ }
404
+ }
405
+ return null;
406
+ }
407
+ function readCalledHelperNode(callNode, closure, context) {
408
+ const calleeNode = callNode.callee;
409
+ if (!isIdentifier(calleeNode)) {
410
+ return null;
411
+ }
412
+ const variable = findVariable(context.sourceCode.getScope(calleeNode), calleeNode.name);
413
+ if (!variable) {
414
+ return null;
415
+ }
416
+ for (const definition of variable.defs) {
417
+ const functionNode = readDefinitionFunctionNode((0, import_ts_estree_node.toTSESTreeNode)(definition.node));
418
+ if (functionNode && isDeclaredInsideClosure(functionNode, closure)) {
419
+ return functionNode;
420
+ }
421
+ }
422
+ return null;
423
+ }
424
+ function readCallGraphWaitInMilliseconds(functionNode, callGraph, visitedNodes) {
425
+ if (visitedNodes.has(functionNode)) {
426
+ return 0;
427
+ }
428
+ visitedNodes.add(functionNode);
429
+ let totalInMilliseconds = callGraph.waitInMillisecondsByFunctionNode.get(functionNode) ?? 0;
430
+ for (const [calleeNode, callCount] of callGraph.callCountByCalleeNodeByCallerNode.get(functionNode) ?? []) {
431
+ totalInMilliseconds += callCount * readCallGraphWaitInMilliseconds(calleeNode, callGraph, visitedNodes);
432
+ }
433
+ visitedNodes.delete(functionNode);
434
+ return totalInMilliseconds;
435
+ }
436
+ function readClockName(node) {
437
+ if (!isCallExpression(node) || node.arguments.length > 0) {
438
+ return null;
439
+ }
440
+ const calleeNode = node.callee;
441
+ if (!isMemberExpression(calleeNode) || calleeNode.computed) {
442
+ return null;
443
+ }
444
+ const objectNode = calleeNode.object;
445
+ const propertyNode = calleeNode.property;
446
+ return !isIdentifier(objectNode) || !isIdentifier(propertyNode) || propertyNode.name !== NOW_METHOD_NAME || !CLOCK_OBJECT_NAMES.has(objectNode.name) ? null : objectNode.name;
447
+ }
448
+ function readClosureNames(callNode) {
449
+ return isIdentifier(callNode.callee) ? CLOSURE_NAMES_BY_CALLEE_NAME.get(callNode.callee.name) ?? null : null;
450
+ }
451
+ function readClosureWaitInMilliseconds(state, callGraph) {
452
+ const reachableNodes = /* @__PURE__ */ new Set();
453
+ collectReachableFunctionNodes(state.closureNode, callGraph, reachableNodes);
454
+ let totalInMilliseconds = readCallGraphWaitInMilliseconds(state.closureNode, callGraph, /* @__PURE__ */ new Set());
455
+ for (const functionNode of state.functionNodes) {
456
+ const ownWaitInMilliseconds = callGraph.waitInMillisecondsByFunctionNode.get(functionNode);
457
+ if (ownWaitInMilliseconds === void 0 || reachableNodes.has(functionNode)) {
458
+ continue;
459
+ }
460
+ totalInMilliseconds += ownWaitInMilliseconds;
461
+ }
462
+ return totalInMilliseconds;
463
+ }
464
+ function readConjuncts(node) {
465
+ return isLogicalAndExpression(node) ? [...readConjuncts(node.left), ...readConjuncts(node.right)] : [node];
466
+ }
467
+ function readDeadlineGuardInMilliseconds(node, closure, context) {
468
+ if (!isBinaryExpression(node)) {
469
+ return null;
470
+ }
471
+ const isClockOnLeft = node.operator === "<" || node.operator === "<=";
472
+ if (!isClockOnLeft && node.operator !== ">" && node.operator !== ">=") {
473
+ return null;
474
+ }
475
+ const clockName = readClockName(isClockOnLeft ? node.left : node.right);
476
+ const deadlineNode = isClockOnLeft ? node.right : node.left;
477
+ if (clockName === null || !isIdentifier(deadlineNode)) {
478
+ return null;
479
+ }
480
+ const boundNode = readBoundExpression(deadlineNode, closure, context);
481
+ return !boundNode || !isBinaryExpression(boundNode) || boundNode.operator !== "+" || readClockName(boundNode.left) !== clockName ? null : resolveNumber(boundNode.right, closure, context);
482
+ }
483
+ function readDefinitionFunctionNode(definitionNode) {
484
+ if (isFunctionNode(definitionNode)) {
485
+ return definitionNode;
486
+ }
487
+ if (!isVariableDeclarator(definitionNode) || !definitionNode.init) {
488
+ return null;
489
+ }
490
+ const initNode = definitionNode.init;
491
+ return isFunctionNode(initNode) ? initNode : null;
492
+ }
493
+ function readEvalClosure(node) {
494
+ if (!isClosureFunction(node)) {
495
+ return null;
496
+ }
497
+ const propertyNode = node.parent;
498
+ if (!isProperty(propertyNode)) {
499
+ return null;
500
+ }
501
+ const paramsNode = propertyNode.parent;
502
+ if (!isObjectExpression(paramsNode) || !isIdentifier(propertyNode.key)) {
503
+ return null;
504
+ }
505
+ const callNode = paramsNode.parent;
506
+ if (!isCallExpression(callNode) || callNode.arguments[0] !== paramsNode) {
507
+ return null;
508
+ }
509
+ const closureNames = readClosureNames(callNode);
510
+ return closureNames?.includes(propertyNode.key.name) ? {
511
+ closureNode: node,
512
+ paramsNode,
513
+ reportNode: propertyNode
514
+ } : null;
515
+ }
516
+ function readInputPropertyValue(paramsNode, keyName) {
517
+ const inputProperty = paramsNode.properties.find(
518
+ (property) => isProperty(property) && isIdentifier(property.key) && property.key.name === INPUT_PROPERTY_NAME
519
+ );
520
+ const inputNode = inputProperty?.value;
521
+ if (!inputNode || !isObjectExpression(inputNode)) {
522
+ return null;
523
+ }
524
+ const valueProperty = inputNode.properties.find(
525
+ (property) => isProperty(property) && isIdentifier(property.key) && property.key.name === keyName
526
+ );
527
+ return valueProperty?.value ?? null;
528
+ }
529
+ function readLoopDeadlineInMilliseconds(loopNode, closure, context) {
530
+ if (!loopNode.test) {
531
+ return null;
532
+ }
533
+ for (const conjunct of readConjuncts(loopNode.test)) {
534
+ const deadlineInMilliseconds = readDeadlineGuardInMilliseconds(conjunct, closure, context);
535
+ if (deadlineInMilliseconds !== null) {
536
+ return deadlineInMilliseconds;
537
+ }
538
+ }
539
+ return null;
540
+ }
541
+ function readLoopExclusiveBound(testNode, counterName, closure, context) {
542
+ for (const conjunct of readConjuncts(testNode)) {
543
+ if (!isBinaryExpression(conjunct) || conjunct.operator !== "<" && conjunct.operator !== "<=") {
544
+ continue;
545
+ }
546
+ const counterNode = conjunct.left;
547
+ if (!isIdentifier(counterNode) || counterNode.name !== counterName) {
548
+ continue;
549
+ }
550
+ const boundValue = resolveNumber(conjunct.right, closure, context);
551
+ if (boundValue === null) {
552
+ continue;
553
+ }
554
+ return conjunct.operator === "<" ? boundValue : boundValue + 1;
555
+ }
556
+ return null;
557
+ }
558
+ function readLoopIterationCount(loopNode, closure, context) {
559
+ if (!isForStatement(loopNode) || !loopNode.test || !loopNode.init || !isVariableDeclaration(loopNode.init)) {
560
+ return null;
561
+ }
562
+ const declaratorNodes = loopNode.init.declarations;
563
+ const declaratorNode = declaratorNodes.length === 1 ? declaratorNodes[0] : void 0;
564
+ if (!declaratorNode?.init || !isIdentifier(declaratorNode.id)) {
565
+ return null;
566
+ }
567
+ const startValue = resolveNumber(declaratorNode.init, closure, context);
568
+ const stepSize = readLoopStepSize(loopNode.update, declaratorNode.id, closure, context);
569
+ const boundValue = readLoopExclusiveBound(loopNode.test, declaratorNode.id.name, closure, context);
570
+ if (startValue === null || stepSize === null || stepSize <= 0 || boundValue === null) {
571
+ return null;
572
+ }
573
+ const span = boundValue - startValue;
574
+ return span > 0 ? Math.ceil(span / stepSize) : 0;
575
+ }
576
+ function readLoopMultiplier(node, target, context) {
577
+ const closure = target.closure;
578
+ let multiplier = 1;
579
+ let currentNode = node.parent;
580
+ while (currentNode && currentNode !== target.functionNode) {
581
+ if (isLoopStatement(currentNode) && readLoopDeadlineInMilliseconds(currentNode, closure, context) === null) {
582
+ const iterationCount = readLoopIterationCount(currentNode, closure, context);
583
+ if (iterationCount !== null) {
584
+ multiplier *= iterationCount;
585
+ }
586
+ }
587
+ currentNode = currentNode.parent;
588
+ }
589
+ return multiplier;
590
+ }
591
+ function readLoopStepSize(updateNode, counterNode, closure, context) {
592
+ if (!updateNode) {
593
+ return null;
594
+ }
595
+ if (isUpdateExpression(updateNode)) {
596
+ const argumentNode = updateNode.argument;
597
+ return updateNode.operator === "++" && isIdentifier(argumentNode) && argumentNode.name === counterNode.name ? 1 : null;
598
+ }
599
+ if (!isAssignmentExpression(updateNode) || updateNode.operator !== "+=") {
600
+ return null;
601
+ }
602
+ const targetNode = updateNode.left;
603
+ return !isIdentifier(targetNode) || targetNode.name !== counterNode.name ? null : resolveNumber(updateNode.right, closure, context);
604
+ }
605
+ function readParameterInputKey(closureNode, localName) {
606
+ for (const parameterNode of closureNode.params) {
607
+ if (!isObjectPattern(parameterNode)) {
608
+ continue;
609
+ }
610
+ for (const property of parameterNode.properties) {
611
+ if (!isProperty(property) || property.computed || !isIdentifier(property.key) || !isIdentifier(property.value)) {
612
+ continue;
613
+ }
614
+ if (property.value.name === localName) {
615
+ return property.key.name;
616
+ }
617
+ }
618
+ }
619
+ return null;
620
+ }
621
+ function readWaitBudgetExpression(callNode) {
622
+ if (!isIdentifier(callNode.callee)) {
623
+ return void 0;
624
+ }
625
+ const calleeName = callNode.callee.name;
626
+ if (calleeName === SLEEP_CALLEE_NAME) {
627
+ return callNode.arguments[0] ?? void 0;
628
+ }
629
+ if (calleeName !== WAIT_UNTIL_CALLEE_NAME) {
630
+ return void 0;
631
+ }
632
+ const paramsNode = callNode.arguments[0];
633
+ if (!paramsNode || !isObjectExpression(paramsNode)) {
634
+ return void 0;
635
+ }
636
+ const timeoutProperty = paramsNode.properties.find(
637
+ (property) => isProperty(property) && isIdentifier(property.key) && property.key.name === TIMEOUT_PROPERTY_NAME
638
+ );
639
+ return timeoutProperty?.value ?? null;
640
+ }
641
+ function resolveNumber(node, closure, context) {
642
+ const visitedNodes = /* @__PURE__ */ new Set();
643
+ let currentNode = node;
644
+ while (!visitedNodes.has(currentNode)) {
645
+ visitedNodes.add(currentNode);
646
+ if (isNumericLiteral(currentNode)) {
647
+ return currentNode.value;
648
+ }
649
+ if (isBinaryExpression(currentNode) && currentNode.operator === "*") {
650
+ const leftValue = resolveNumber(currentNode.left, closure, context);
651
+ const rightValue = resolveNumber(currentNode.right, closure, context);
652
+ return leftValue === null || rightValue === null ? null : leftValue * rightValue;
653
+ }
654
+ if (!isIdentifier(currentNode)) {
655
+ return null;
656
+ }
657
+ const boundNode = readBoundExpression(currentNode, closure, context);
658
+ if (!boundNode) {
659
+ return null;
660
+ }
661
+ currentNode = boundNode;
662
+ }
663
+ return null;
664
+ }
665
+ // Annotate the CommonJS export names for ESM import in node:
666
+ 0 && (module.exports = {
667
+ MESSAGE_ID,
668
+ noOverCapWaitInEvalInObsidian
669
+ });
670
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vLi4vLi4vc3JjL2xpbnRlcnMvZXNsaW50LXJ1bGVzL25vLW92ZXItY2FwLXdhaXQtaW4tZXZhbC1pbi1vYnNpZGlhbi50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiLyoqXG4gKiBAZmlsZVxuICpcbiAqIEVTTGludCBydWxlOiBuby1vdmVyLWNhcC13YWl0LWluLWV2YWwtaW4tb2JzaWRpYW5cbiAqXG4gKiBSZXBvcnRzIGFuIGBldmFsSW5PYnNpZGlhbmAgLyBgcG9sbEluT2JzaWRpYW5gIGNsb3N1cmUgdGhhdCBkZWNsYXJlcyBtb3JlIHdhaXRpbmdcbiAqIHRoYW4gdGhlIHRyYW5zcG9ydCBjYW4gZXZlciBob25vdXIuXG4gKlxuICogQSBzaW5nbGUgY2xvc3VyZSBpcyBldmFsdWF0ZWQgdGhyb3VnaCBvbmUgdHJhbnNwb3J0IGNhbGwsIGFuZCB0aGF0IGNhbGwgaXMgY2FwcGVkIGF0XG4gKiByb3VnaGx5IDMwIHNlY29uZHMgXHUyMDE0IEFwcGl1bSBzdXJmYWNlcyB0aGUgY2FwIGFzIGEgYmFyZSBgV2ViRHJpdmVyRXJyb3I6IHNjcmlwdCB0aW1lb3V0YFxuICogbmFtaW5nIG9ubHkgYEFwcGl1bVRyYW5zcG9ydC5ldmFsdWF0ZWAsIENEUCBhcyBhIGNvbW1hbmQgdGltZW91dC4gTmVpdGhlciBuYW1lcyB0aGUgd2FpdFxuICogdGhhdCBhY3R1YWxseSBibGV3IHRoZSBidWRnZXQsIHNvIHRoZSBmYWlsdXJlIHJlYWRzIGFzIGEgYnJva2VuIGRldmljZSByYXRoZXIgdGhhbiBhcyBhXG4gKiBjbG9zdXJlIGFza2luZyBmb3IgbW9yZSB0aW1lIHRoYW4gZXhpc3RzLiBUaGF0IG1pc2RpYWdub3NpcyBjb3N0IHR3byBkYXlzLlxuICpcbiAqIFRoZSBjYXAgdGhlIHJ1bGUgYXNzdW1lcyB3aGVuIGBjYXBJbk1pbGxpc2Vjb25kc2AgaXMgbm90IGNvbmZpZ3VyZWQgaXNcbiAqIGBERUZBVUxUX0VWQUxfQ0FQX0lOX01JTExJU0VDT05EU2AsIGltcG9ydGVkIGZyb20gYG9ic2lkaWFuLWludGVncmF0aW9uLXRlc3RpbmdgIFx1MjAxNCB0aGUgc2FtZSBjb25zdGFudFxuICogYm90aCBvZiBpdHMgdHJhbnNwb3J0cyBlbmZvcmNlLCBzbyB0aGUgcnVsZSBjYW5ub3QgZHJpZnQgZnJvbSB0aGUgdGhpbmcgaXQgaXMgcHJlZGljdGluZy4gVGhhdCBpbXBvcnRcbiAqIGlzIHdoeSB0aGUgaGFybmVzcyBpcyBhIHJlcXVpcmVkIHBlZXIgb2YgdGhpcyBsaWJyYXJ5IHJhdGhlciB0aGFuIGFuIG9wdGlvbmFsIG9uZTogdGhlIHNoYXJlZCBFU0xpbnRcbiAqIGNvbmZpZyBsb2FkcyB0aGlzIHJ1bGUsIHNvIGV2ZXJ5IGNvbnN1bWluZyByZXBvIHJlc29sdmVzIGl0IGF0IGxpbnQgdGltZS5cbiAqXG4gKiBPTkUgS0lORCBPRiBGSUxFIERFRkFVTFRTIEhJR0hFUjogYSBgKi5kZXNrdG9wLXBlcmZvcm1hbmNlLmludGVncmF0aW9uLnRlc3QudHNgIGlzIG1lYXN1cmVkIGFnYWluc3RcbiAqIGBQRVJGT1JNQU5DRV9FVkFMX0NBUF9JTl9NSUxMSVNFQ09ORFNgICg2MDAgMDAwKSwgdGhlIHBlci1ldmFsIGNhcCB0aGUgc2hhcmVkIHZpdGVzdCBjb25maWcgZ2l2ZXMgdGhlXG4gKiBgaW50ZWdyYXRpb24tdGVzdHM6ZGVza3RvcC1wZXJmb3JtYW5jZWAgcHJvamVjdCwgaW1wb3J0ZWQgZnJvbSB0aGF0IHNhbWUgbW9kdWxlIHJhdGhlciB0aGFuIHJlc3RhdGVkLlxuICogVGhhdCByYWlzZSBpcyBhIGRlbGliZXJhdGUgQlVER0VUOiBhIHBlcmYgc3VpdGUncyBtZWFzdXJlbWVudCBpcyBvbmUgbG9uZyBpbi1wYWdlIGV2YWx1YXRpb24sIGFuZCBpdHNcbiAqIGZpbGVzIHJ1biBvbiBubyBvdGhlciBwcm9qZWN0LiBFdmVyeSBvdGhlciBmaWxlIGtlZXBzIHRoZSBzaW5nbGUgdHJhbnNwb3J0IGRlZmF1bHQsIGFuZCB0aGF0IGlzIHRoZVxuICogY29udmVudGlvbiByYXRoZXIgdGhhbiBhIGdhcDogYSByZXBvIHRoYXQgcmFpc2VzIGl0cyBvd24gZGVza3RvcCBgY29tbWFuZFRpbWVvdXRJbk1pbGxpc2Vjb25kc2AgaXNcbiAqIHNldHRpbmcgYSBiYWNrc3RvcCwgTk9UIGEgYnVkZ2V0IGEgY2xvc3VyZSBtYXkgc3BlbmQsIHNvIHRoZSBydWxlIGRvZXMgbm90IHJlYWQgdGhhdCByYWlzZSBhbmQga2VlcHNcbiAqIGVuZm9yY2luZyAzMCAwMDAgYWdhaW5zdCBpdC4gQSBjcm9zcy1wbGF0Zm9ybSBzdWl0ZSBjb3VsZCBub3Qgc3BlbmQgaXQgYW55d2F5OiBBcHBpdW0gY2FwcyBldmVyeVxuICogY2xvc3VyZSBhdCAzMCAwMDAgd2hhdGV2ZXIgYSBkZXNrdG9wIHJhaXNlIHNheXMuIEFuIGV4cGxpY2l0IGBjYXBJbk1pbGxpc2Vjb25kc2Agc3RpbGwgb3ZlcnJpZGVzIGJvdGhcbiAqIGRlZmF1bHRzLCBmb3IgZXZlcnkgZmlsZSB0aGUgcnVsZSBpcyBjb25maWd1cmVkIG9uLlxuICpcbiAqIEEgY2xvc3VyZSBkZWNsYXJpbmcgYSAzMCAwMDAgbXMgYHdhaXRVbnRpbGAsIG9yIHR3byAyMCAwMDAgbXMgb25lcywgdGhlcmVmb3JlIGNhbm5vdFxuICogc3VjY2VlZCBvbiBhbnkgbWFjaGluZSBzbG93IGVub3VnaCB0byBuZWVkIHRoZSB0aW1lIGl0IGFza3MgZm9yLiBUaGUgZml4IGlzIHRvIG1vdmUgdGhlXG4gKiB3YWl0aW5nIHRvIE5vZGU6IGBwb2xsSW5PYnNpZGlhbmAgcnVucyBhIFNIT1JUIERPTS1yZWFkaW5nIGBwb2xsYCBjbG9zdXJlIHJlcGVhdGVkbHksXG4gKiBldmFsdWF0ZXMgYHVudGlsYCBpbiBOb2RlLCBhbmQgY2FycmllcyB0aGUgbG9uZyBidWRnZXQgaW4gYHRpbWVvdXRJbk1pbGxpc2Vjb25kc2AsIHNvIG5vXG4gKiBzaW5nbGUgdHJhbnNwb3J0IGNhbGwgaXMgZXZlciBsb25nLlxuICpcbiAqIFdIQVQgQ09VTlRTIHRvd2FyZCBhIGNsb3N1cmUncyBidWRnZXQsIHN1bW1lZCBsZXhpY2FsbHk6IGV2ZXJ5IGB3YWl0VW50aWxgIGluc2lkZSBpdCBcdTIwMTRcbiAqIHRha2luZyB0aGUgaGVscGVyJ3MgZG9jdW1lbnRlZCA1IDAwMCBtcyBkZWZhdWx0IHdoZW4gYHRpbWVvdXRJbk1pbGxpc2Vjb25kc2AgaXMgb21pdHRlZCxcbiAqIHdoaWNoIGlzIHdoYXQgbWFrZXMgc2V2ZXJhbCBzbWFsbCBzaWJsaW5nIHdhaXRzIGFkZCB1cCBob25lc3RseSBcdTIwMTQgcGx1cyBldmVyeSBgc2xlZXAobilgXG4gKiBzZXR0bGUuIFdhaXRzIGluc2lkZSBhIGhlbHBlciBkZWNsYXJlZCB3aXRoaW4gdGhlIGNsb3N1cmUgY291bnQgdG9vOyB0aGUgZW5jbG9zaW5nXG4gKiBjbG9zdXJlIGlzIGZvdW5kIGJ5IHdhbGtpbmcgb3V0d2FyZHMsIHNvIGEgbmVzdGVkIGZ1bmN0aW9uIGF0dHJpYnV0ZXMgdG8gdGhlIGNsb3N1cmUgaXRcbiAqIHJ1bnMgaW5zaWRlIC0tIG9uY2UgcGVyIENBTEwgU0lURSwgcGVyIHRoZSBIRUxQRVJTIHBhcmFncmFwaCBiZWxvdy5cbiAqXG4gKiBXSEFUIERPRVMgTk9ULiBBIGJ1ZGdldCB0aGF0IGNhbm5vdCBiZSByZXNvbHZlZCB0byBhIG51bWJlciBjb250cmlidXRlcyBub3RoaW5nIGFuZCBpc1xuICogbmV2ZXIgcmVwb3J0ZWQgKG93bmVyLCAyMDI2LTA5LTA5KS4gU2NvcGUgYW5hbHlzaXMgcmVzb2x2ZXMgdGhlIHNoYXBlcyB0aGF0IGFjdHVhbGx5XG4gKiBvY2N1ciBcdTIwMTQgYSBsaXRlcmFsLCBhIGBjb25zdGAgaW4gYW55IGVuY2xvc2luZyBzY29wZSwgYW5kIGEgZGVzdHJ1Y3R1cmVkIGNhbGxiYWNrXG4gKiBwYXJhbWV0ZXIgZm9sbG93ZWQgYmFjayB0aHJvdWdoIHRoZSBjYWxsJ3Mgb3duIGBpbnB1dGAgb2JqZWN0IFx1MjAxNCBhbmQgcmVzb2x2aW5nIHRocm91Z2hcbiAqIHNjb3BlIHJhdGhlciB0aGFuIGJ5IHJlZ2V4IGlzIHRoZSB3aG9sZSByZWFzb24gdGhpcyBpcyBhIHJ1bGUgYW5kIG5vdCBhIHNjcmlwdC4gQnV0IGFcbiAqIHZhbHVlIGFycml2aW5nIGZyb20gYSBjYWxsZXIgKGBvcHRpb25zLnRpbWVvdXQgPz8gREVGQVVMVGAsIHRocmVhZGVkIHRocm91Z2ggYVxuICogcGFyYW1ldGVyKSB3b3VsZCBuZWVkIGFuYWx5c2lzIGFjcm9zcyBjYWxsIGJvdW5kYXJpZXMsIGFuZCByZXBvcnRpbmcgZXZlcnkgc3VjaCBzaXRlIHdvdWxkXG4gKiBtYWtlIGVhY2ggbGVnaXRpbWF0ZWx5IHBhcmFtZXRlcml6ZWQgaGVscGVyIHJlZCBhY3Jvc3MgdGhpcnR5IHJlcG9zLlxuICpcbiAqIExPT1BTIHdlcmUgb25jZSBvdXQgb2Ygc2NvcGUgd2hvbGVzYWxlLCBvbiB0aGUgcmVhc29uaW5nIHRoYXQgYSBgc2xlZXBgIGluIGEgYHdoaWxlYCBoYXMgbm9cbiAqIHN0YXRpY2FsbHkgZGVjbGFyZWQgY2VpbGluZy4gVGhhdCBpcyB0cnVlIG9mIGB3aGlsZSAodHJ1ZSlgIGFuZCBmYWxzZSBvZiB0aGUgbG9vcCB0aGVzZVxuICogc3VpdGVzIGFjdHVhbGx5IHdyaXRlLCB3aGljaCBkZWNsYXJlcyBpdHMgY2VpbGluZyBhcyBwbGFpbmx5IGFzIGFueSBsaXRlcmFsIHRpbWVvdXQgXHUyMDE0IGFuZFxuICogbGVhdmluZyB0aGVtIGFsbCBvdXQgaGlkIDIyIG92ZXItY2FwIGNsb3N1cmVzIGFjcm9zcyBzaXggcmVwb3MsIG9uZSBvZiB0aGVtIHRlbiB0aW1lcyBvdmVyLlxuICogVHdvIHNoYXBlcyBhcmUgcmVhZCBub3csIGJvdGggdGhyb3VnaCB0aGUgc2FtZSBzY29wZSB3YWxrIGEgYnVkZ2V0IHVzZXM6XG4gKlxuICogLSBBIERFQURMSU5FIGxvb3AgXHUyMDE0IGBjb25zdCBkZWFkbGluZSA9IERhdGUubm93KCkgKyBCVURHRVRgLCBndWFyZGVkIGJ5IGBEYXRlLm5vdygpIDwgZGVhZGxpbmVgIFx1MjAxNFxuICogICBjYW5ub3QgcnVuIGxvbmdlciB0aGFuIGBCVURHRVRgIHdoYXRldmVyIGl0cyBwb2xsIGludGVydmFsLCBzbyBgQlVER0VUYCBpcyBjaGFyZ2VkIHRvIHRoZVxuICogICBjbG9zdXJlIE9OQ0UgcGVyIGxvb3AsIG9uIHRvcCBvZiB0aGUgc2luZ2xlIGl0ZXJhdGlvbiBpdHMgaW5uZXIgd2FpdHMgYXJlIGFscmVhZHkgY2hhcmdlZFxuICogICAoYSBwb2xsIHRoYXQgc3RhcnRzIGp1c3QgdW5kZXIgdGhlIGRlYWRsaW5lIHN0aWxsIHJ1bnMgdG8gY29tcGxldGlvbiwgc28gdGhlIHN1bSBvZiB0aGUgdHdvXG4gKiAgIGlzIHRoZSBob25lc3Qgd29yc3QgY2FzZSByYXRoZXIgdGhhbiBhIGRvdWJsZSBjb3VudCkuIGBwZXJmb3JtYW5jZS5ub3coKWAgY291bnRzIGFzIHdlbGwgYXNcbiAqICAgYERhdGUubm93KClgOiBhIGBwZXJmb3JtYW5jZWAtd3JpdHRlbiBkZWFkbGluZSByZWFkIGFzIHVuYm91bmRlZCBpcyB3aHkgb25lIDI0NSAwMjUgbXNcbiAqICAgY2xvc3VyZSB3YXMgYWJzZW50IGZyb20gZXZlcnkgcm9zdGVyIHByb2R1Y2VkIGJlZm9yZSB0aGlzLlxuICogLSBBIENPVU5USU5HIGBmb3JgIFx1MjAxNCBgZm9yIChsZXQgYXR0ZW1wdCA9IDA7IGF0dGVtcHQgPCBBVFRFTVBUUzsgYXR0ZW1wdCsrKWAgXHUyMDE0IG11bHRpcGxpZXMgZXZlcnlcbiAqICAgd2FpdCBpbnNpZGUgaXQgYnkgaXRzIGl0ZXJhdGlvbiBjb3VudCwgcmVhZCBmcm9tIHRoZSBsb29wJ3Mgb3duIHN0YXJ0LCBib3VuZCBhbmQgc3RlcC5cbiAqXG4gKiBFaXRoZXIgY2VpbGluZyBtYXkgYmUgT05FIENPTkpVTkNUIG9mIGEgY29tcG91bmQgdGVzdCAoYHdoaWxlIChjb3VudCA8IGV4cGVjdGVkICYmIERhdGUubm93KCkgPCBkZWFkbGluZSlgLFxuICogYGZvciAobGV0IGF0dGVtcHQgPSAwOyBhdHRlbXB0IDwgQVRURU1QVFMgJiYgIWlzT3BlbjsgYXR0ZW1wdCsrKWApLCB3aGljaCBpcyBob3cgYm90aCBhcmUgYWN0dWFsbHlcbiAqIHdyaXR0ZW46IGEgcHJvZ3Jlc3MgY29uZGl0aW9uIGJlc2lkZSB0aGUgZ3VhcmQgZG9lcyBub3QgcmVtb3ZlIHRoZSBjZWlsaW5nIHRoZSBvdGhlciBjb25qdW5jdCBkZWNsYXJlcy5cbiAqXG4gKiBBbnl0aGluZyBlbHNlIGtlZXBzIHRoZSBvbGQgcGVyLWl0ZXJhdGlvbiBjaGFyZ2UgcmF0aGVyIHRoYW4gYSBndWVzcyBcdTIwMTQgYHdoaWxlICh0cnVlKWAsIGEgYGZvclx1MjAyNm9mYCxcbiAqIGEgYm91bmQgb3IgZGVhZGxpbmUgdGhhdCBkb2VzIG5vdCByZXNvbHZlIFx1MjAxNCB3aGljaCBpcyB3aGF0IGtlZXBzIGEgZ2VudWluZWx5IHVuYm91bmRlZCBsb29wIHNpbGVudC5cbiAqXG4gKiBBIEhFTFBFUiBkZWNsYXJlZCBpbnNpZGUgdGhlIGNsb3N1cmUgaXMgY2hhcmdlZCBvbmNlIHBlciBDQUxMIFNJVEUsIHdoaWNoIGlzIGhvdyBtYW55IHRpbWVzIGl0cyB3YWl0aW5nXG4gKiBhY3R1YWxseSBydW5zLiBJdHMgb3duIHdhaXRzIGFyZSBzdW1tZWQgb25jZSBhbmQgbXVsdGlwbGllZCBieSB0aGUgY2FsbHMgdGhhdCByZWFjaCBpdCwgZWFjaCBjYWxsXG4gKiBjYXJyeWluZyB0aGUgY291bnRpbmcgbG9vcHMgaXQgaXMgaXRzZWxmIHdyaXR0ZW4gaW5zaWRlIFx1MjAxNCBzbyBhIGxvY2FsIGB3YWl0VW50aWwoY2hlY2spYCBvZlxuICogYGZvciAoYXR0ZW1wdCA8IDQwKSBhd2FpdCBzbGVlcCgyNTApYCBjYWxsZWQgdGhyZWUgdGltZXMgZGVjbGFyZXMgMzAgMDAwIG1zIHJhdGhlciB0aGFuIHRoZSAxMCAwMDAgbXMgYVxuICogc2luZ2xlIGF0dHJpYnV0aW9uIHJlcG9ydGVkLiBUaHJlZSBib3VuZHMga2VlcCB0aGF0IGhvbmVzdDpcbiAqXG4gKiAtIEEgaGVscGVyIGRlY2xhcmVkIE9VVFNJREUgdGhlIGNsb3N1cmUgc3RheXMgb3V0IG9mIHNjb3BlLCBmb3IgdGhlIHNhbWUgcmVhc29uIGEgYnVkZ2V0IGFycml2aW5nIGZyb21cbiAqICAgYSBjYWxsZXIgaXM6IHJlYWRpbmcgaXQgbmVlZHMgYW5hbHlzaXMgYWNyb3NzIGNhbGwgYm91bmRhcmllcywgYW5kIHdpZGVuaW5nIHRoZXJlIHdvdWxkIG1ha2UgZXZlcnlcbiAqICAgbGVnaXRpbWF0ZWx5IHBhcmFtZXRlcml6ZWQgaGVscGVyIGluIGV2ZXJ5IGNvbnN1bWluZyByZXBvIHJlZC5cbiAqIC0gUkVDVVJTSU9OIHRlcm1pbmF0ZXMgYnkgY2hhcmdpbmcgYSByZS1lbnRlcmVkIGhlbHBlciBub3RoaW5nLCBzbyBuZWl0aGVyIGEgc2VsZi1jYWxsIG5vciBhIG11dHVhbGx5XG4gKiAgIHJlY3Vyc2l2ZSBwYWlyIGlzIGNoYXJnZWQgZm9yZXZlci4gQSByZWN1cnNpdmUgY2FsbCBjb250cmlidXRlcyB0aGUgc2lsZW5jZSBhbiB1bmJvdW5kZWQgbG9vcCBkb2VzLlxuICogLSBBIGhlbHBlciB0aGUgY2xvc3VyZSBuZXZlciBSRUFDSEVTIFx1MjAxNCBkZWFkLCBvciBjYWxsZWQgdGhyb3VnaCBzb21ldGhpbmcgdGhpcyBydWxlIGNhbm5vdCByZXNvbHZlLCBzdWNoXG4gKiAgIGFzIGEgYmFyZSByZWZlcmVuY2UgaGFuZGVkIHRvIGBmb3JFYWNoYCBcdTIwMTQga2VlcHMgdGhlIGZsYXQgc2luZ2xlIGNoYXJnZSBpdCBoYXMgYWx3YXlzIGhhZC4gU28gbm9cbiAqICAgY2xvc3VyZSB0aGlzIHJ1bGUgcmVwb3J0cyB0b2RheSBmYWxscyBzaWxlbnQgYmVjYXVzZSBhIGNhbGwgc2l0ZSBjb3VsZCBub3QgYmUgcmVhZC5cbiAqXG4gKiBXaGF0IHRoZSBwZXItY2FsbC1zaXRlIGNvdW50IGRvZXMgTk9UIGZpeCBpcyBhIEJSQU5DSFkgaGVscGVyOiBhbiBgaWZgIC8gYGVsc2VgIGlzIHN1bW1lZCBsZXhpY2FsbHkgbGlrZVxuICogYW55IHR3byBzaWJsaW5nIHdhaXRzLCBzbyBib3RoIGFybXMgYXJlIGNoYXJnZWQgYXQgZXZlcnkgY2FsbCBzaXRlLiBBIGhlbHBlciB3aG9zZSB0d28gZGlyZWN0aW9ucyB3YWl0XG4gKiBkaWZmZXJlbnRseSBpcyB0aGVyZWZvcmUgYmV0dGVyIHdyaXR0ZW4gYXMgdHdvIGhlbHBlcnMsIHdoaWNoIGlzIHdoYXQgdGhpcyByZXBvJ3Mgb3duXG4gKiBgc3JjL29ic2lkaWFuL2NvbXBvbmVudHMvc3ludGF4LWhpZ2hsaWdodGluZy1jb21wb25lbnQub2JzaWRpYW4uaW50ZWdyYXRpb24udGVzdC50c2Agbm93IGRvZXMuXG4gKlxuICogTm90IGV2ZXJ5IG92ZXItY2FwIGNsb3N1cmUgY2FuIGJlY29tZSBhIGBwb2xsYCAvIGB1bnRpbGAgcGFpciwgc28gdGhlIHJ1bGUgaXMgbWVhbnQgdG8gYmVcbiAqIGRpc2FibGVkIFx1MjAxNCB3aXRoIGEgcmVhc29uIFx1MjAxNCBhdCB0aGUgc2l0ZXMgdGhhdCBoYXZlIG9uZS4gYHJlcXVpcmUtZGVzY3JpcHRpb25gIG1ha2VzIHRoYXRcbiAqIHJlYXNvbiBtYW5kYXRvcnksIHdoaWNoIGlzIHRoZSBwb2ludDogaXQgdHVybnMgYW4gaW52aXNpYmxlIGFzc3VtcHRpb24gaW50byBhIHdyaXR0ZW4gb25lLlxuICpcbiAqIEEgQ0xPU1VSRSBERUxJQkVSQVRFTFkgTEVGVCBVTkRFUiBUSEUgQ0FQIFNBWVMgU08sIGluIGEgY29tbWVudCBvcGVuaW5nIHdpdGggdGhlIGV4YWN0IGxpbmVcbiAqXG4gKiAgICAgVW5kZXIgdGhlIHRyYW5zcG9ydCdzIH4zMHMgcGVyLWNsb3N1cmUgY2FwLCBub3QgYXQgaXQuXG4gKlxuICogYW5kIHRoZW4gc2F5aW5nLCBmb3IgdGhhdCBjbG9zdXJlLCB3aGF0IHRoZSBidWRnZXQgaXMgbWFkZSBvZiBhbmQgd2h5IGl0IHN0YXlzLiBUaGlzIHJ1bGUgaXMgc2lsZW50XG4gKiBvbiBzdWNoIGEgY2xvc3VyZSBieSBjb25zdHJ1Y3Rpb24gXHUyMDE0IGl0IGlzIHVuZGVyIHRoZSBjYXAgXHUyMDE0IHNvIHdpdGhvdXQgdGhlIGxpbmUgdGhlcmUgaXMgbm8gd2F5IHRvIHRlbGxcbiAqIGEgYnVkZ2V0IHNvbWVib2R5IHJlYWQgYW5kIGtlcHQgZnJvbSBvbmUgbm9ib2R5IGhhcyBsb29rZWQgYXQsIGFuZCBhIHN3ZWVwIHJ1biB3aXRoIGEgbG93ZXJcbiAqIGBjYXBJbk1pbGxpc2Vjb25kc2AgcmUtb3BlbnMgdGhlIHNhbWUgZGVjaXNpb25zIGV2ZXJ5IHRpbWUuIFRoZSBsaW5lIGlzIHRoZSB3aG9sZSBvZiB0aGUgY29udmVudGlvbixcbiAqIHdoaWNoIGlzIHdoYXQgbGV0cyBzdWNoIGEgc3dlZXAgc3VidHJhY3QgdGhlIGNsb3N1cmVzIGFscmVhZHkgcmVhZCBhbmQgZHJpdmUgdGhlIHJlbWFpbmRlciB0byB6ZXJvLlxuICpcbiAqIFR3byBwbGFjZW1lbnRzLCBiZWNhdXNlIGEgY2VpbGluZyBsaXZlcyBpbiB0d28gcGxhY2VzLiBBIGNvbW1lbnQgSU5TSURFIHRoZSBjbG9zdXJlLCBvdmVyIHRoYXRcbiAqIGNsb3N1cmUncyBvd24gY2VpbGluZyBjb25zdGFudCwgc3BlYWtzIGZvciB0aGF0IGNsb3N1cmUgYWxvbmU7IG9uZSBhdCBNT0RVTEUgc2NvcGUsIG92ZXIgYSBjb25zdGFudFxuICogdGhlIHdob2xlIGZpbGUgc2hhcmVzLCBzcGVha3MgZm9yIGV2ZXJ5IGNsb3N1cmUgaW4gdGhlIGZpbGUuIEEgY2xvc3VyZSB3aXRoIG5vIGNlaWxpbmcgY29uc3RhbnQgYXRcbiAqIGFsbCBcdTIwMTQgc2V2ZXJhbCBgd2FpdFVudGlsYCBjYWxscyB0YWtpbmcgdGhlIGRvY3VtZW50ZWQgZGVmYXVsdCBcdTIwMTQgdGFrZXMgdGhlIGluLWNsb3N1cmUgZm9ybSBhdCB0aGUgdG9wXG4gKiBvZiBpdHMgYm9keS5cbiAqXG4gKiBTYXlpbmcgaXQgaXMgTk9UIHRoZSBzYW1lIGFzIGNsZWFyaW5nIGl0LiBBIGJ1ZGdldCB1bmRlciB0aGUgY2FwIGlzIG5vdCBhIGRlZmVjdCwgYW5kIFwicmVhZCwgYW5kIGxlZnRcbiAqIGFzIGl0IGlzXCIgaXMgYSBjb3JyZWN0IG91dGNvbWU6IHRpZ2h0ZW5pbmcgYSBjZWlsaW5nIHRvIGJyaW5nIGEgbnVtYmVyIGRvd24gaXMgaG93IGEgc3VpdGUgc3RhcnRzXG4gKiBmYWlsaW5nIGxlZ2l0aW1hdGVseSBvbiBhIGNvbGQgbWFjaGluZS5cbiAqL1xuaW1wb3J0IHR5cGUgeyBUU0VTVHJlZSB9IGZyb20gJ0B0eXBlc2NyaXB0LWVzbGludC91dGlscyc7XG5pbXBvcnQgdHlwZSB7XG4gIFJ1bGUsXG4gIFNjb3BlXG59IGZyb20gJ2VzbGludCc7XG5cbmltcG9ydCB7IHRvVFNFU1RyZWVOb2RlIH0gZnJvbSAnQG1uYW91bW92L3R5cGVzY3JpcHQtZGV2LXRvb2xraXQvbGludGVycy9lc2xpbnQtcnVsZXMvdHMtZXN0cmVlLW5vZGUnO1xuaW1wb3J0IHsgREVGQVVMVF9FVkFMX0NBUF9JTl9NSUxMSVNFQ09ORFMgfSBmcm9tICdvYnNpZGlhbi1pbnRlZ3JhdGlvbi10ZXN0aW5nJztcblxuaW1wb3J0IHtcbiAgREVTS1RPUF9QRVJGT1JNQU5DRV9URVNUX0ZJTEVfU1VGRklYLFxuICBQRVJGT1JNQU5DRV9FVkFMX0NBUF9JTl9NSUxMSVNFQ09ORFNcbn0gZnJvbSAnLi4vLi4vdGVzdC1ydW5uZXJzL3BlcmZvcm1hbmNlLWV2YWwtY2FwLnRzJztcblxuLyoqXG4gKiBNZXNzYWdlIElEIHJlcG9ydGVkIHdoZW4gYW4gaW4tT2JzaWRpYW4gY2xvc3VyZSBkZWNsYXJlcyBtb3JlIHdhaXRpbmcgdGhhbiB0aGUgdHJhbnNwb3J0J3MgY2FwIGFsbG93cy5cbiAqL1xuZXhwb3J0IGNvbnN0IE1FU1NBR0VfSUQgPSAnbm9PdmVyQ2FwV2FpdEluRXZhbEluT2JzaWRpYW4nO1xuXG4vKipcbiAqIFRoZSBidWRnZXQgYSBgd2FpdFVudGlsYCB0YWtlcyB3aGVuIGl0IG9taXRzIGB0aW1lb3V0SW5NaWxsaXNlY29uZHNgLCBwZXIgYFdhaXRVbnRpbFBhcmFtc2AuXG4gKi9cbmNvbnN0IFdBSVRfVU5USUxfREVGQVVMVF9USU1FT1VUX0lOX01JTExJU0VDT05EUyA9IDUwMDA7XG5cbmNvbnN0IElOUFVUX1BST1BFUlRZX05BTUUgPSAnaW5wdXQnO1xuY29uc3QgU0xFRVBfQ0FMTEVFX05BTUUgPSAnc2xlZXAnO1xuY29uc3QgVElNRU9VVF9QUk9QRVJUWV9OQU1FID0gJ3RpbWVvdXRJbk1pbGxpc2Vjb25kcyc7XG5jb25zdCBXQUlUX1VOVElMX0NBTExFRV9OQU1FID0gJ3dhaXRVbnRpbCc7XG5cbi8qKlxuICogVGhlIGNsb2NrcyBhIGRlYWRsaW5lIG1heSBiZSB0YWtlbiBmcm9tLiBCb3RoIG9jY3VyIGluIHRoZXNlIHN1aXRlcywgYW5kIGEgcnVsZSB0aGF0IGtuZXcgb25seSBgRGF0ZWBcbiAqIHJlYWQgZXZlcnkgYHBlcmZvcm1hbmNlYC13cml0dGVuIGRlYWRsaW5lIGFzIHVuYm91bmRlZC5cbiAqL1xuY29uc3QgQ0xPQ0tfT0JKRUNUX05BTUVTID0gbmV3IFNldChbJ0RhdGUnLCAncGVyZm9ybWFuY2UnXSk7XG5cbmNvbnN0IE5PV19NRVRIT0RfTkFNRSA9ICdub3cnO1xuXG4vKipcbiAqIFdoaWNoIHByb3BlcnRpZXMgb2YgZWFjaCBoZWxwZXIncyBwYXJhbWV0ZXIgb2JqZWN0IGhvbGQgYSBjbG9zdXJlIHRoYXQgcnVucyBJTlNJREUgT2JzaWRpYW4sIGFuZCBpc1xuICogdGhlcmVmb3JlIHN1YmplY3QgdG8gdGhlIGNhcC4gYHBvbGxJbk9ic2lkaWFuYCdzIGB1bnRpbGAgaXMgZGVsaWJlcmF0ZWx5IGFic2VudDogaXQgaXMgZXZhbHVhdGVkIGluXG4gKiBOb2RlLCB3aGljaCBpcyB0aGUgZW50aXJlIHBvaW50IG9mIGNvbnZlcnRpbmcgdG8gaXQuXG4gKi9cbmNvbnN0IENMT1NVUkVfTkFNRVNfQllfQ0FMTEVFX05BTUUgPSBuZXcgTWFwPHN0cmluZywgcmVhZG9ubHkgc3RyaW5nW10+KFtcbiAgWydldmFsSW5PYnNpZGlhbicsIFsnY2FsbGJhY2snXV0sXG4gIFsncG9sbEluT2JzaWRpYW4nLCBbJ3BvbGwnLCAnc3RhcnQnXV1cbl0pO1xuXG4vKipcbiAqIEV2ZXJ5dGhpbmcgb25lIGZpbGUgYWNjdW11bGF0ZWQsIGtleWVkIGJ5IHRoZSBmdW5jdGlvbiBlYWNoIGNoYXJnZSB3YXMgd3JpdHRlbiBpbnNpZGUuXG4gKlxuICogQSB3YWl0IGlzIGNoYXJnZWQgdG8gdGhlIGlubmVybW9zdCBmdW5jdGlvbiBpdCBpcyB3cml0dGVuIGluIHJhdGhlciB0aGFuIHN0cmFpZ2h0IHRvIHRoZSBjbG9zdXJlLCBhbmQgYVxuICogY2FsbCB0byBhIGhlbHBlciB0aGUgY2xvc3VyZSBkZWNsYXJlcyBpcyByZWNvcmRlZCBhcyBhbiBlZGdlLCBzbyBhIGNsb3N1cmUncyB0b3RhbCBpcyBpdHMgb3duIHdhaXRpbmdcbiAqIHBsdXMgZWFjaCBoZWxwZXIncyB3YWl0aW5nIG11bHRpcGxpZWQgYnkgdGhlIGNhbGxzIHRoYXQgYWN0dWFsbHkgcmVhY2ggaXQuXG4gKi9cbmludGVyZmFjZSBDYWxsR3JhcGgge1xuICAvKipcbiAgICogSG93IG1hbnkgdGltZXMgZWFjaCBmdW5jdGlvbiBjYWxscyBlYWNoIGhlbHBlciBkZWNsYXJlZCBpbnNpZGUgdGhlIHNhbWUgY2xvc3VyZS5cbiAgICovXG4gIHJlYWRvbmx5IGNhbGxDb3VudEJ5Q2FsbGVlTm9kZUJ5Q2FsbGVyTm9kZTogTWFwPEhlbHBlckZ1bmN0aW9uLCBNYXA8SGVscGVyRnVuY3Rpb24sIG51bWJlcj4+O1xuXG4gIC8qKlxuICAgKiBUaGUgY2xvc3VyZXMgc2VlbiBzbyBmYXIsIGJ5IHRoZSBmdW5jdGlvbiBub2RlIGVhY2ggb25lIGlzIHdyaXR0ZW4gYXMuXG4gICAqL1xuICByZWFkb25seSBzdGF0ZUJ5Q2xvc3VyZU5vZGU6IE1hcDxDbG9zdXJlRnVuY3Rpb24sIENsb3N1cmVTdGF0ZT47XG5cbiAgLyoqXG4gICAqIFRoZSB3YWl0aW5nIHdyaXR0ZW4gRElSRUNUTFkgaW5zaWRlIGVhY2ggZnVuY3Rpb24sIGV4Y2x1ZGluZyB3aGF0ZXZlciB0aGUgaGVscGVycyBpdCBjYWxscyBkZWNsYXJlLlxuICAgKi9cbiAgcmVhZG9ubHkgd2FpdEluTWlsbGlzZWNvbmRzQnlGdW5jdGlvbk5vZGU6IE1hcDxIZWxwZXJGdW5jdGlvbiwgbnVtYmVyPjtcbn1cblxuLyoqXG4gKiBUaGUgcnVsZSdzIHNpbmdsZSBvcHRpb24gb2JqZWN0LlxuICovXG5pbnRlcmZhY2UgQ2FwT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBUaGUgYnVkZ2V0IGF0IG9yIG92ZXIgd2hpY2ggYSBjbG9zdXJlIGlzIHJlcG9ydGVkLCBpbiBtaWxsaXNlY29uZHMuXG4gICAqL1xuICByZWFkb25seSBjYXBJbk1pbGxpc2Vjb25kcz86IG51bWJlcjtcbn1cblxuLyoqXG4gKiBUaGUgZnVuY3Rpb24gYSBjaGFyZ2UgaXMgYXR0cmlidXRlZCB0bywgdG9nZXRoZXIgd2l0aCB0aGUgaW4tT2JzaWRpYW4gY2xvc3VyZSBpdCB1bHRpbWF0ZWx5IHJ1bnMgaW5zaWRlLlxuICovXG5pbnRlcmZhY2UgQ2hhcmdlVGFyZ2V0IHtcbiAgLyoqXG4gICAqIFRoZSBjbG9zdXJlIHRoZSBjaGFyZ2UgcnVucyBpbnNpZGUsIGNhcnJpZWQgc28gYSBidWRnZXQgdGhyZWFkZWQgdGhyb3VnaCBpdHMgY2FsbCBzdGlsbCByZXNvbHZlcy5cbiAgICovXG4gIHJlYWRvbmx5IGNsb3N1cmU6IEV2YWxDbG9zdXJlO1xuXG4gIC8qKlxuICAgKiBUaGUgaW5uZXJtb3N0IGZ1bmN0aW9uIHRoZSBjaGFyZ2UgaXMgd3JpdHRlbiBpbjogdGhlIGNsb3N1cmUgaXRzZWxmLCBvciBhIGhlbHBlciBkZWNsYXJlZCB3aXRoaW4gaXQuXG4gICAqL1xuICByZWFkb25seSBmdW5jdGlvbk5vZGU6IEhlbHBlckZ1bmN0aW9uO1xufVxuXG4vKipcbiAqIEEgZnVuY3Rpb24gd3JpdHRlbiBhcyBhbiBvYmplY3QgcHJvcGVydHksIHdoaWNoIGlzIHRoZSBvbmx5IGZvcm0gZWl0aGVyIGhlbHBlcidzIGNsb3N1cmVzIHRha2UuXG4gKi9cbnR5cGUgQ2xvc3VyZUZ1bmN0aW9uID0gVFNFU1RyZWUuQXJyb3dGdW5jdGlvbkV4cHJlc3Npb24gfCBUU0VTVHJlZS5GdW5jdGlvbkV4cHJlc3Npb247XG5cbi8qKlxuICogT25lIGluLU9ic2lkaWFuIGNsb3N1cmUncyBhY2N1bXVsYXRlZCBjaGFyZ2VzLlxuICovXG5pbnRlcmZhY2UgQ2xvc3VyZVN0YXRlIHtcbiAgLyoqXG4gICAqIFRoZSBjbG9zdXJlJ3Mgb3duIGZ1bmN0aW9uIG5vZGUsIHRoZSByb290IGV2ZXJ5IHJlYWNoYWJsZSBoZWxwZXIgaXMgY291bnRlZCBmcm9tLlxuICAgKi9cbiAgcmVhZG9ubHkgY2xvc3VyZU5vZGU6IENsb3N1cmVGdW5jdGlvbjtcblxuICAvKipcbiAgICogRXZlcnkgZnVuY3Rpb24gY2hhcmdlZCBpbnNpZGUgdGhpcyBjbG9zdXJlOiB0aGUgY2xvc3VyZSBpdHNlbGYsIGFuZCBlYWNoIGhlbHBlciBpdCBkZWNsYXJlcy5cbiAgICovXG4gIHJlYWRvbmx5IGZ1bmN0aW9uTm9kZXM6IFNldDxIZWxwZXJGdW5jdGlvbj47XG5cbiAgLyoqXG4gICAqIFRoZSBwcm9wZXJ0eSB0aGUgY2xvc3VyZSBpcyB3cml0dGVuIGFzLCByZXBvcnRlZCBvbi5cbiAgICovXG4gIHJlYWRvbmx5IHJlcG9ydE5vZGU6IFRTRVNUcmVlLk5vZGU7XG59XG5cbi8qKlxuICogQW4gaW4tT2JzaWRpYW4gY2xvc3VyZSwgdG9nZXRoZXIgd2l0aCB0aGUgY2FsbCBpdCBiZWxvbmdzIHRvIChuZWVkZWQgdG8gcmVzb2x2ZSBhIGJ1ZGdldCB0aHJlYWRlZFxuICogdGhyb3VnaCB0aGF0IGNhbGwncyBgaW5wdXRgKSBhbmQgdGhlIG5vZGUgdG8gcmVwb3J0IG9uLlxuICovXG5pbnRlcmZhY2UgRXZhbENsb3N1cmUge1xuICAvKipcbiAgICogVGhlIGNsb3N1cmUncyBmdW5jdGlvbiBub2RlLCB3aGljaCBpZGVudGlmaWVzIHRoZSBjbG9zdXJlIGFjcm9zcyBzaWJsaW5nIHdhaXRzIGFuZCBjYXJyaWVzIHRoZVxuICAgKiBwYXJhbWV0ZXIgcGF0dGVybiBhIGJ1ZGdldCB0aHJlYWRlZCB0aHJvdWdoIGBpbnB1dGAgaXMgZGVzdHJ1Y3R1cmVkIGJ5LlxuICAgKi9cbiAgcmVhZG9ubHkgY2xvc3VyZU5vZGU6IENsb3N1cmVGdW5jdGlvbjtcblxuICAvKipcbiAgICogVGhlIGhlbHBlcidzIHBhcmFtZXRlciBvYmplY3QsIGNhcnJpZWQgc28gYSBidWRnZXQgdGhyZWFkZWQgdGhyb3VnaCBgaW5wdXRgIGlzIHJlYWQgZnJvbSB0aGUgb2JqZWN0XG4gICAqIHRoZSBjbG9zdXJlIHdhcyBhbHJlYWR5IGZvdW5kIGluIHJhdGhlciB0aGFuIHJlLWRlcml2ZWQgZnJvbSB0aGUgY2FsbC5cbiAgICovXG4gIHJlYWRvbmx5IHBhcmFtc05vZGU6IFRTRVNUcmVlLk9iamVjdEV4cHJlc3Npb247XG5cbiAgLyoqXG4gICAqIFRoZSBwcm9wZXJ0eSB0aGUgY2xvc3VyZSBpcyB3cml0dGVuIGFzLCByZXBvcnRlZCBvbiBzbyB0aGUgbWVzc2FnZSBwb2ludHMgYXQgYGNhbGxiYWNrYCAvIGBwb2xsYFxuICAgKiByYXRoZXIgdGhhbiBhdCB3aGljaGV2ZXIgd2FpdCBoYXBwZW5lZCB0byBjb21lIGZpcnN0LlxuICAgKi9cbiAgcmVhZG9ubHkgcmVwb3J0Tm9kZTogVFNFU1RyZWUuTm9kZTtcbn1cblxuLyoqXG4gKiBBIGZ1bmN0aW9uIHdhaXRpbmcgY2FuIGJlIGNoYXJnZWQgdG86IGFuIGluLU9ic2lkaWFuIGNsb3N1cmUsIG9yIGEgaGVscGVyIGRlY2xhcmVkIGluc2lkZSBvbmUgXHUyMDE0IHdoaWNoIGFcbiAqIGBmdW5jdGlvbmAgZGVjbGFyYXRpb24gaXMgYXMgcmVhZGlseSBhcyBhbiBhcnJvdyBvciBhIGZ1bmN0aW9uIGV4cHJlc3Npb24uXG4gKi9cbnR5cGUgSGVscGVyRnVuY3Rpb24gPSBDbG9zdXJlRnVuY3Rpb24gfCBUU0VTVHJlZS5GdW5jdGlvbkRlY2xhcmF0aW9uO1xuXG4vKipcbiAqIEEgbG9vcCB3aG9zZSBvd24gdGVzdCBjYW4gZGVjbGFyZSBhIGNlaWxpbmcuIGBmb3JcdTIwMjZvZmAgLyBgZm9yXHUyMDI2aW5gIGFyZSBkZWxpYmVyYXRlbHkgYWJzZW50OiBuZWl0aGVyXG4gKiBkZWNsYXJlcyBvbmUgc3RhdGljYWxseSwgc28gYm90aCBrZWVwIHRoZSBwZXItaXRlcmF0aW9uIGNoYXJnZSBldmVyeSB1bnNpemVkIGxvb3AgZ2V0cy5cbiAqL1xudHlwZSBMb29wU3RhdGVtZW50ID0gVFNFU1RyZWUuRG9XaGlsZVN0YXRlbWVudCB8IFRTRVNUcmVlLkZvclN0YXRlbWVudCB8IFRTRVNUcmVlLldoaWxlU3RhdGVtZW50O1xuXG4vKipcbiAqIEVTTGludCBydWxlIGRpc2FsbG93aW5nIGFuIGluLU9ic2lkaWFuIGNsb3N1cmUgd2hvc2UgZGVjbGFyZWQgd2FpdGluZyBleGNlZWRzIHRoZSB0cmFuc3BvcnQncyBzY3JpcHQtdGltZW91dCBjYXAuXG4gKi9cbmV4cG9ydCBjb25zdCBub092ZXJDYXBXYWl0SW5FdmFsSW5PYnNpZGlhbjogUnVsZS5SdWxlTW9kdWxlID0ge1xuICBjcmVhdGUoY29udGV4dCkge1xuICAgIGNvbnN0IG9wdGlvbnMgPSBjb250ZXh0Lm9wdGlvbnNbMF0gYXMgQ2FwT3B0aW9ucyB8IHVuZGVmaW5lZDtcbiAgICBjb25zdCBkZWZhdWx0Q2FwSW5NaWxsaXNlY29uZHMgPSBjb250ZXh0LmZpbGVuYW1lLmVuZHNXaXRoKERFU0tUT1BfUEVSRk9STUFOQ0VfVEVTVF9GSUxFX1NVRkZJWClcbiAgICAgID8gUEVSRk9STUFOQ0VfRVZBTF9DQVBfSU5fTUlMTElTRUNPTkRTXG4gICAgICA6IERFRkFVTFRfRVZBTF9DQVBfSU5fTUlMTElTRUNPTkRTO1xuICAgIGNvbnN0IGNhcEluTWlsbGlzZWNvbmRzID0gb3B0aW9ucz8uY2FwSW5NaWxsaXNlY29uZHMgPz8gZGVmYXVsdENhcEluTWlsbGlzZWNvbmRzO1xuICAgIGNvbnN0IGNhbGxHcmFwaDogQ2FsbEdyYXBoID0ge1xuICAgICAgY2FsbENvdW50QnlDYWxsZWVOb2RlQnlDYWxsZXJOb2RlOiBuZXcgTWFwPEhlbHBlckZ1bmN0aW9uLCBNYXA8SGVscGVyRnVuY3Rpb24sIG51bWJlcj4+KCksXG4gICAgICBzdGF0ZUJ5Q2xvc3VyZU5vZGU6IG5ldyBNYXA8Q2xvc3VyZUZ1bmN0aW9uLCBDbG9zdXJlU3RhdGU+KCksXG4gICAgICB3YWl0SW5NaWxsaXNlY29uZHNCeUZ1bmN0aW9uTm9kZTogbmV3IE1hcDxIZWxwZXJGdW5jdGlvbiwgbnVtYmVyPigpXG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFJlY29yZHMgdGhhdCBvbmUgZnVuY3Rpb24gY2FsbHMgYSBoZWxwZXIgZGVjbGFyZWQgaW5zaWRlIHRoZSBzYW1lIGNsb3N1cmUuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdGFyZ2V0IC0gVGhlIGZ1bmN0aW9uIHRoZSBjYWxsIGlzIHdyaXR0ZW4gaW4uXG4gICAgICogQHBhcmFtIGNhbGxlZU5vZGUgLSBUaGUgaGVscGVyIGJlaW5nIGNhbGxlZC5cbiAgICAgKiBAcGFyYW0gY2FsbENvdW50IC0gSG93IG1hbnkgdGltZXMgdGhlIGNhbGwgcnVucywgYXMgdGhlIHByb2R1Y3Qgb2YgaXRzIGVuY2xvc2luZyBjb3VudGluZyBsb29wcy5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBhZGRDYWxsKHRhcmdldDogQ2hhcmdlVGFyZ2V0LCBjYWxsZWVOb2RlOiBIZWxwZXJGdW5jdGlvbiwgY2FsbENvdW50OiBudW1iZXIpOiB2b2lkIHtcbiAgICAgIGNvbnN0IHN0YXRlID0gcmVhZENsb3N1cmVTdGF0ZSh0YXJnZXQpO1xuICAgICAgc3RhdGUuZnVuY3Rpb25Ob2Rlcy5hZGQoY2FsbGVlTm9kZSk7XG5cbiAgICAgIGNvbnN0IGNhbGxDb3VudEJ5Q2FsbGVlTm9kZSA9IGNhbGxHcmFwaC5jYWxsQ291bnRCeUNhbGxlZU5vZGVCeUNhbGxlck5vZGUuZ2V0KHRhcmdldC5mdW5jdGlvbk5vZGUpXG4gICAgICAgID8/IG5ldyBNYXA8SGVscGVyRnVuY3Rpb24sIG51bWJlcj4oKTtcbiAgICAgIGNhbGxHcmFwaC5jYWxsQ291bnRCeUNhbGxlZU5vZGVCeUNhbGxlck5vZGUuc2V0KHRhcmdldC5mdW5jdGlvbk5vZGUsIGNhbGxDb3VudEJ5Q2FsbGVlTm9kZSk7XG4gICAgICBjYWxsQ291bnRCeUNhbGxlZU5vZGUuc2V0KGNhbGxlZU5vZGUsIChjYWxsQ291bnRCeUNhbGxlZU5vZGUuZ2V0KGNhbGxlZU5vZGUpID8/IDApICsgY2FsbENvdW50KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBZGRzIHdhaXRpbmcgdG8gdGhlIHJ1bm5pbmcgdG90YWwgb2YgdGhlIGZ1bmN0aW9uIGl0IHdhcyB3cml0dGVuIGluLlxuICAgICAqXG4gICAgICogQHBhcmFtIHRhcmdldCAtIFRoZSBmdW5jdGlvbiB0byBjaGFyZ2UuXG4gICAgICogQHBhcmFtIHdhaXRJbk1pbGxpc2Vjb25kcyAtIFRoZSB3YWl0aW5nIHRvIGFkZC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBhZGRXYWl0KHRhcmdldDogQ2hhcmdlVGFyZ2V0LCB3YWl0SW5NaWxsaXNlY29uZHM6IG51bWJlcik6IHZvaWQge1xuICAgICAgcmVhZENsb3N1cmVTdGF0ZSh0YXJnZXQpO1xuICAgICAgY29uc3QgcnVubmluZ1RvdGFsSW5NaWxsaXNlY29uZHMgPSBjYWxsR3JhcGgud2FpdEluTWlsbGlzZWNvbmRzQnlGdW5jdGlvbk5vZGUuZ2V0KHRhcmdldC5mdW5jdGlvbk5vZGUpID8/IDA7XG4gICAgICBjYWxsR3JhcGgud2FpdEluTWlsbGlzZWNvbmRzQnlGdW5jdGlvbk5vZGUuc2V0KHRhcmdldC5mdW5jdGlvbk5vZGUsIHJ1bm5pbmdUb3RhbEluTWlsbGlzZWNvbmRzICsgd2FpdEluTWlsbGlzZWNvbmRzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZWNvcmRzIGEgY2FsbCB0byBhIGhlbHBlciB0aGUgY2xvc3VyZSBkZWNsYXJlcywgc28gaXRzIHdhaXRpbmcgaXMgY291bnRlZCBvbmNlIHBlciBjYWxsIHNpdGUuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gY2FsbE5vZGUgLSBUaGUgY2FsbCBleHByZXNzaW9uLlxuICAgICAqIEBwYXJhbSB0YXJnZXQgLSBUaGUgZnVuY3Rpb24gdGhlIGNhbGwgaXMgd3JpdHRlbiBpbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjaGFyZ2VIZWxwZXJDYWxsKGNhbGxOb2RlOiBUU0VTVHJlZS5DYWxsRXhwcmVzc2lvbiwgdGFyZ2V0OiBDaGFyZ2VUYXJnZXQpOiB2b2lkIHtcbiAgICAgIGNvbnN0IGhlbHBlck5vZGUgPSByZWFkQ2FsbGVkSGVscGVyTm9kZShjYWxsTm9kZSwgdGFyZ2V0LmNsb3N1cmUsIGNvbnRleHQpO1xuICAgICAgaWYgKCFoZWxwZXJOb2RlKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgYWRkQ2FsbCh0YXJnZXQsIGhlbHBlck5vZGUsIHJlYWRMb29wTXVsdGlwbGllcihjYWxsTm9kZSwgdGFyZ2V0LCBjb250ZXh0KSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hhcmdlcyBhIGRlYWRsaW5lLWJvdW5kZWQgbG9vcCBpdHMgd2hvbGUgZGVhZGxpbmUsIG9uY2UuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gbm9kZSAtIFRoZSBsb29wIHN0YXRlbWVudC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjaGFyZ2VMb29wRGVhZGxpbmUobm9kZTogUnVsZS5Ob2RlKTogdm9pZCB7XG4gICAgICBjb25zdCBsb29wTm9kZSA9IHRvVFNFU1RyZWVOb2RlKG5vZGUpIGFzIExvb3BTdGF0ZW1lbnQ7XG5cbiAgICAgIGNvbnN0IHRhcmdldCA9IGZpbmRDaGFyZ2VUYXJnZXQobG9vcE5vZGUpO1xuICAgICAgaWYgKCF0YXJnZXQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBkZWFkbGluZUluTWlsbGlzZWNvbmRzID0gcmVhZExvb3BEZWFkbGluZUluTWlsbGlzZWNvbmRzKGxvb3BOb2RlLCB0YXJnZXQuY2xvc3VyZSwgY29udGV4dCk7XG4gICAgICBpZiAoZGVhZGxpbmVJbk1pbGxpc2Vjb25kcyA9PT0gbnVsbCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGFkZFdhaXQodGFyZ2V0LCBkZWFkbGluZUluTWlsbGlzZWNvbmRzICogcmVhZExvb3BNdWx0aXBsaWVyKGxvb3BOb2RlLCB0YXJnZXQsIGNvbnRleHQpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGFyZ2VzIGEgd2FpdCBjYWxsIHRoZSBidWRnZXQgaXQgZGVjbGFyZXMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gY2FsbE5vZGUgLSBUaGUgY2FsbCBleHByZXNzaW9uLlxuICAgICAqIEBwYXJhbSB0YXJnZXQgLSBUaGUgZnVuY3Rpb24gdGhlIGNhbGwgaXMgd3JpdHRlbiBpbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjaGFyZ2VXYWl0Q2FsbChjYWxsTm9kZTogVFNFU1RyZWUuQ2FsbEV4cHJlc3Npb24sIHRhcmdldDogQ2hhcmdlVGFyZ2V0KTogdm9pZCB7XG4gICAgICBjb25zdCBidWRnZXRFeHByZXNzaW9uID0gcmVhZFdhaXRCdWRnZXRFeHByZXNzaW9uKGNhbGxOb2RlKTtcbiAgICAgIGlmIChidWRnZXRFeHByZXNzaW9uID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBjb25zdCB3YWl0SW5NaWxsaXNlY29uZHMgPSBidWRnZXRFeHByZXNzaW9uID09PSBudWxsXG4gICAgICAgID8gV0FJVF9VTlRJTF9ERUZBVUxUX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTXG4gICAgICAgIDogcmVzb2x2ZU51bWJlcihidWRnZXRFeHByZXNzaW9uLCB0YXJnZXQuY2xvc3VyZSwgY29udGV4dCk7XG4gICAgICBpZiAod2FpdEluTWlsbGlzZWNvbmRzID09PSBudWxsKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgYWRkV2FpdCh0YXJnZXQsIHdhaXRJbk1pbGxpc2Vjb25kcyAqIHJlYWRMb29wTXVsdGlwbGllcihjYWxsTm9kZSwgdGFyZ2V0LCBjb250ZXh0KSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVnaXN0ZXJzIHRoZSBjbG9zdXJlIGEgY2hhcmdlIGJlbG9uZ3MgdG8sIGFuZCB0aGUgZnVuY3Rpb24gdGhlIGNoYXJnZSB3YXMgd3JpdHRlbiBpbi5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB0YXJnZXQgLSBUaGUgZnVuY3Rpb24gYmVpbmcgY2hhcmdlZC5cbiAgICAgKiBAcmV0dXJucyBUaGF0IGNsb3N1cmUncyBhY2N1bXVsYXRlZCBzdGF0ZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiByZWFkQ2xvc3VyZVN0YXRlKHRhcmdldDogQ2hhcmdlVGFyZ2V0KTogQ2xvc3VyZVN0YXRlIHtcbiAgICAgIGNvbnN0IHN0YXRlID0gY2FsbEdyYXBoLnN0YXRlQnlDbG9zdXJlTm9kZS5nZXQodGFyZ2V0LmNsb3N1cmUuY2xvc3VyZU5vZGUpID8/IHtcbiAgICAgICAgY2xvc3VyZU5vZGU6IHRhcmdldC5jbG9zdXJlLmNsb3N1cmVOb2RlLFxuICAgICAgICBmdW5jdGlvbk5vZGVzOiBuZXcgU2V0PEhlbHBlckZ1bmN0aW9uPigpLFxuICAgICAgICByZXBvcnROb2RlOiB0YXJnZXQuY2xvc3VyZS5yZXBvcnROb2RlXG4gICAgICB9O1xuICAgICAgY2FsbEdyYXBoLnN0YXRlQnlDbG9zdXJlTm9kZS5zZXQodGFyZ2V0LmNsb3N1cmUuY2xvc3VyZU5vZGUsIHN0YXRlKTtcbiAgICAgIHN0YXRlLmZ1bmN0aW9uTm9kZXMuYWRkKHRhcmdldC5mdW5jdGlvbk5vZGUpO1xuICAgICAgcmV0dXJuIHN0YXRlO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICAnQ2FsbEV4cHJlc3Npb24nKG5vZGU6IFJ1bGUuTm9kZSk6IHZvaWQge1xuICAgICAgICBjb25zdCBjYWxsTm9kZSA9IHRvVFNFU1RyZWVOb2RlKG5vZGUpIGFzIFRTRVNUcmVlLkNhbGxFeHByZXNzaW9uO1xuXG4gICAgICAgIGNvbnN0IHRhcmdldCA9IGZpbmRDaGFyZ2VUYXJnZXQoY2FsbE5vZGUpO1xuICAgICAgICBpZiAoIXRhcmdldCkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNoYXJnZVdhaXRDYWxsKGNhbGxOb2RlLCB0YXJnZXQpO1xuICAgICAgICBjaGFyZ2VIZWxwZXJDYWxsKGNhbGxOb2RlLCB0YXJnZXQpO1xuICAgICAgfSxcbiAgICAgIERvV2hpbGVTdGF0ZW1lbnQ6IGNoYXJnZUxvb3BEZWFkbGluZSxcbiAgICAgIEZvclN0YXRlbWVudDogY2hhcmdlTG9vcERlYWRsaW5lLFxuICAgICAgJ1Byb2dyYW06ZXhpdCcoKTogdm9pZCB7XG4gICAgICAgIGZvciAoY29uc3Qgc3RhdGUgb2YgY2FsbEdyYXBoLnN0YXRlQnlDbG9zdXJlTm9kZS52YWx1ZXMoKSkge1xuICAgICAgICAgIGNvbnN0IHRvdGFsSW5NaWxsaXNlY29uZHMgPSByZWFkQ2xvc3VyZVdhaXRJbk1pbGxpc2Vjb25kcyhzdGF0ZSwgY2FsbEdyYXBoKTtcbiAgICAgICAgICBpZiAodG90YWxJbk1pbGxpc2Vjb25kcyA8IGNhcEluTWlsbGlzZWNvbmRzKSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb250ZXh0LnJlcG9ydCh7XG4gICAgICAgICAgICBkYXRhOiB7XG4gICAgICAgICAgICAgIGNhcEluTWlsbGlzZWNvbmRzOiBTdHJpbmcoY2FwSW5NaWxsaXNlY29uZHMpLFxuICAgICAgICAgICAgICB0b3RhbEluTWlsbGlzZWNvbmRzOiBTdHJpbmcodG90YWxJbk1pbGxpc2Vjb25kcylcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBtZXNzYWdlSWQ6IE1FU1NBR0VfSUQsXG4gICAgICAgICAgICBub2RlOiBzdGF0ZS5yZXBvcnROb2RlXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBXaGlsZVN0YXRlbWVudDogY2hhcmdlTG9vcERlYWRsaW5lXG4gICAgfTtcbiAgfSxcbiAgbWV0YToge1xuICAgIGRvY3M6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnRGlzYWxsb3cgYW4gaW4tT2JzaWRpYW4gY2xvc3VyZSBkZWNsYXJpbmcgbW9yZSB3YWl0aW5nIHRoYW4gdGhlIHRyYW5zcG9ydFxcJ3Mgc2NyaXB0LXRpbWVvdXQgY2FwIGFsbG93cydcbiAgICB9LFxuICAgIG1lc3NhZ2VzOiB7XG4gICAgICBbTUVTU0FHRV9JRF06ICdUaGlzIGNsb3N1cmUgZGVjbGFyZXMge3sgdG90YWxJbk1pbGxpc2Vjb25kcyB9fSBtcyBvZiB3YWl0aW5nLCBhdCBvciBvdmVyIHRoZSB0cmFuc3BvcnRcXCdzIHt7IGNhcEluTWlsbGlzZWNvbmRzIH19IG1zIGNhcCwgc28gaXQgY2FuIG9ubHkgZXZlciBkaWUgYXMgYSBiYXJlIGBzY3JpcHQgdGltZW91dGA6IHdhaXQgaW4gTm9kZSBpbnN0ZWFkLCB3aXRoIGEgc2hvcnQgRE9NLXJlYWRpbmcgYHBvbGxJbk9ic2lkaWFuYCBgcG9sbGAsIGFuIGB1bnRpbGAgZXZhbHVhdGVkIGluIE5vZGUsIGFuZCB0aGUgbG9uZyBidWRnZXQgaW4gYHRpbWVvdXRJbk1pbGxpc2Vjb25kc2AuJ1xuICAgIH0sXG4gICAgc2NoZW1hOiBbe1xuICAgICAgYWRkaXRpb25hbFByb3BlcnRpZXM6IGZhbHNlLFxuICAgICAgcHJvcGVydGllczoge1xuICAgICAgICBjYXBJbk1pbGxpc2Vjb25kczoge1xuICAgICAgICAgIG1pbmltdW06IDEsXG4gICAgICAgICAgdHlwZTogJ2ludGVnZXInXG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICB0eXBlOiAnb2JqZWN0J1xuICAgIH1dLFxuICAgIHR5cGU6ICdwcm9ibGVtJ1xuICB9XG59O1xuXG4vKipcbiAqIENvbGxlY3RzIGV2ZXJ5IGhlbHBlciByZWFjaGFibGUgZnJvbSBhIGZ1bmN0aW9uIGJ5IGZvbGxvd2luZyB0aGUgY2FsbHMgcmVjb3JkZWQgZm9yIGl0cyBjbG9zdXJlLlxuICpcbiAqIEEgaGVscGVyIE5PVCBpbiB0aGUgYW5zd2VyIGlzIG9uZSBubyBjYWxsIHNpdGUgY2FuIHJlYWNoLCB3aGljaCBpcyB3aGF0IHRoZSBmbGF0IGZhbGxiYWNrIGNoYXJnZSBpc1xuICoga2V5ZWQgb2ZmOiBpdCBpcyBlaXRoZXIgZGVhZCwgb3IgY2FsbGVkIHRocm91Z2ggc29tZXRoaW5nIHRoaXMgcnVsZSBjYW5ub3QgcmVhZC5cbiAqXG4gKiBAcGFyYW0gZnVuY3Rpb25Ob2RlIC0gVGhlIGZ1bmN0aW9uIHRvIHN0YXJ0IGZyb20uXG4gKiBAcGFyYW0gY2FsbEdyYXBoIC0gVGhlIGZpbGUncyBhY2N1bXVsYXRlZCBjaGFyZ2VzLlxuICogQHBhcmFtIHJlYWNoYWJsZU5vZGVzIC0gVGhlIHNldCB0byBjb2xsZWN0IGludG8sIHdoaWNoIGRvdWJsZXMgYXMgdGhlIHZpc2l0ZWQgc2V0LlxuICovXG5mdW5jdGlvbiBjb2xsZWN0UmVhY2hhYmxlRnVuY3Rpb25Ob2RlcyhmdW5jdGlvbk5vZGU6IEhlbHBlckZ1bmN0aW9uLCBjYWxsR3JhcGg6IENhbGxHcmFwaCwgcmVhY2hhYmxlTm9kZXM6IFNldDxIZWxwZXJGdW5jdGlvbj4pOiB2b2lkIHtcbiAgaWYgKHJlYWNoYWJsZU5vZGVzLmhhcyhmdW5jdGlvbk5vZGUpKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgcmVhY2hhYmxlTm9kZXMuYWRkKGZ1bmN0aW9uTm9kZSk7XG5cbiAgZm9yIChjb25zdCBjYWxsZWVOb2RlIG9mIGNhbGxHcmFwaC5jYWxsQ291bnRCeUNhbGxlZU5vZGVCeUNhbGxlck5vZGUuZ2V0KGZ1bmN0aW9uTm9kZSk/LmtleXMoKSA/PyBbXSkge1xuICAgIGNvbGxlY3RSZWFjaGFibGVGdW5jdGlvbk5vZGVzKGNhbGxlZU5vZGUsIGNhbGxHcmFwaCwgcmVhY2hhYmxlTm9kZXMpO1xuICB9XG59XG5cbi8qKlxuICogRmluZHMgdGhlIGZ1bmN0aW9uIGEgbm9kZSdzIHdhaXRpbmcgaXMgY2hhcmdlZCB0bywgd2Fsa2luZyBvdXR3YXJkcy5cbiAqXG4gKiBUaGUgd2FsayBkb2VzIG5vdCBzdG9wIGF0IHRoZSBmaXJzdCBlbmNsb3NpbmcgZnVuY3Rpb246IGEgd2FpdCBpbnNpZGUgYSBoZWxwZXIgZGVjbGFyZWQgd2l0aGluIHRoZVxuICogY2FsbGJhY2sgc3RpbGwgcnVucyBpbnNpZGUgdGhlIGNhbGxiYWNrLCBzbyBpdCBrZWVwcyBnb2luZyB1bnRpbCBpdCByZWFjaGVzIGEgZnVuY3Rpb24gdGhhdCBJUyBvbmUgb2ZcbiAqIHRoZSBoZWxwZXIncyBpbi1PYnNpZGlhbiBjbG9zdXJlcy4gV2hhdCBpdCBSRU1FTUJFUlMgb24gdGhlIHdheSBpcyB0aGUgaW5uZXJtb3N0IGZ1bmN0aW9uIGl0IHBhc3NlZCwgc29cbiAqIGEgaGVscGVyJ3Mgd2FpdGluZyBpcyBhY2N1bXVsYXRlZCBhZ2FpbnN0IHRoZSBoZWxwZXIgYW5kIGNoYXJnZWQgdG8gdGhlIGNsb3N1cmUgb25jZSBwZXIgY2FsbCBzaXRlLlxuICpcbiAqIEBwYXJhbSBub2RlIC0gVGhlIG5vZGUgdG8gc3RhcnQgZnJvbS5cbiAqIEByZXR1cm5zIFRoZSBjaGFyZ2UgdGFyZ2V0LCBvciBgbnVsbGAgd2hlbiB0aGUgbm9kZSBkb2VzIG5vdCBydW4gaW5zaWRlIGFuIGluLU9ic2lkaWFuIGNsb3N1cmUuXG4gKi9cbmZ1bmN0aW9uIGZpbmRDaGFyZ2VUYXJnZXQobm9kZTogVFNFU1RyZWUuTm9kZSk6IENoYXJnZVRhcmdldCB8IG51bGwge1xuICBsZXQgaW5uZXJtb3N0RnVuY3Rpb25Ob2RlOiBIZWxwZXJGdW5jdGlvbiB8IHVuZGVmaW5lZDtcbiAgbGV0IGN1cnJlbnROb2RlOiBUU0VTVHJlZS5Ob2RlIHwgdW5kZWZpbmVkID0gbm9kZS5wYXJlbnQ7XG5cbiAgd2hpbGUgKGN1cnJlbnROb2RlKSB7XG4gICAgY29uc3QgY2xvc3VyZSA9IHJlYWRFdmFsQ2xvc3VyZShjdXJyZW50Tm9kZSk7XG4gICAgaWYgKGNsb3N1cmUpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGNsb3N1cmUsXG4gICAgICAgIGZ1bmN0aW9uTm9kZTogaW5uZXJtb3N0RnVuY3Rpb25Ob2RlID8/IGNsb3N1cmUuY2xvc3VyZU5vZGVcbiAgICAgIH07XG4gICAgfVxuXG4gICAgaWYgKCFpbm5lcm1vc3RGdW5jdGlvbk5vZGUgJiYgaXNGdW5jdGlvbk5vZGUoY3VycmVudE5vZGUpKSB7XG4gICAgICBpbm5lcm1vc3RGdW5jdGlvbk5vZGUgPSBjdXJyZW50Tm9kZTtcbiAgICB9XG5cbiAgICBjdXJyZW50Tm9kZSA9IGN1cnJlbnROb2RlLnBhcmVudDtcbiAgfVxuXG4gIHJldHVybiBudWxsO1xufVxuXG4vKipcbiAqIEZpbmRzIGEgdmFyaWFibGUgYnkgbmFtZSwgd2Fsa2luZyBvdXR3YXJkcyBmcm9tIHRoZSBnaXZlbiBzY29wZS5cbiAqXG4gKiBAcGFyYW0gc2NvcGUgLSBUaGUgc2NvcGUgdG8gc3RhcnQgZnJvbS5cbiAqIEBwYXJhbSBuYW1lIC0gVGhlIHZhcmlhYmxlJ3MgbmFtZS5cbiAqIEByZXR1cm5zIFRoZSB2YXJpYWJsZSwgb3IgYG51bGxgIHdoZW4gbm90aGluZyBpbiBzY29wZSBkZWNsYXJlcyB0aGF0IG5hbWUuXG4gKi9cbmZ1bmN0aW9uIGZpbmRWYXJpYWJsZShzY29wZTogU2NvcGUuU2NvcGUsIG5hbWU6IHN0cmluZyk6IG51bGwgfCBTY29wZS5WYXJpYWJsZSB7XG4gIGxldCBjdXJyZW50U2NvcGU6IG51bGwgfCBTY29wZS5TY29wZSA9IHNjb3BlO1xuXG4gIHdoaWxlIChjdXJyZW50U2NvcGUpIHtcbiAgICBjb25zdCB2YXJpYWJsZSA9IGN1cnJlbnRTY29wZS52YXJpYWJsZXMuZmluZCgoY2FuZGlkYXRlKSA9PiBjYW5kaWRhdGUubmFtZSA9PT0gbmFtZSk7XG4gICAgaWYgKHZhcmlhYmxlKSB7XG4gICAgICByZXR1cm4gdmFyaWFibGU7XG4gICAgfVxuICAgIGN1cnJlbnRTY29wZSA9IGN1cnJlbnRTY29wZS51cHBlcjtcbiAgfVxuXG4gIHJldHVybiBudWxsO1xufVxuXG4vKipcbiAqIENoZWNrcyB3aGV0aGVyIGEgbm9kZSBpcyBhbiBhc3NpZ25tZW50IGV4cHJlc3Npb24uXG4gKlxuICogQHBhcmFtIG5vZGUgLSBUaGUgbm9kZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIGB0cnVlYCBpZiB0aGUgbm9kZSBpcyBhbiBgQXNzaWdubWVudEV4cHJlc3Npb25gLlxuICovXG5mdW5jdGlvbiBpc0Fzc2lnbm1lbnRFeHByZXNzaW9uKG5vZGU6IFRTRVNUcmVlLk5vZGUpOiBub2RlIGlzIFRTRVNUcmVlLkFzc2lnbm1lbnRFeHByZXNzaW9uIHtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnNhZmUtZW51bS1jb21wYXJpc29uIC0tIEFTVCBub2RlIHR5cGUgc3RyaW5nIGxpdGVyYWxzIG1hdGNoIHRoZSBUU0VTVHJlZSBlbnVtIHZhbHVlcy5cbiAgcmV0dXJuIG5vZGUudHlwZSA9PT0gJ0Fzc2lnbm1lbnRFeHByZXNzaW9uJztcbn1cblxuLyoqXG4gKiBDaGVja3Mgd2hldGhlciBhIG5vZGUgaXMgYSBiaW5hcnkgZXhwcmVzc2lvbi5cbiAqXG4gKiBAcGFyYW0gbm9kZSAtIFRoZSBub2RlIHRvIGNoZWNrLlxuICogQHJldHVybnMgYHRydWVgIGlmIHRoZSBub2RlIGlzIGEgYEJpbmFyeUV4cHJlc3Npb25gLlxuICovXG5mdW5jdGlvbiBpc0JpbmFyeUV4cHJlc3Npb24obm9kZTogVFNFU1RyZWUuTm9kZSk6IG5vZGUgaXMgVFNFU1RyZWUuQmluYXJ5RXhwcmVzc2lvbiB7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW5zYWZlLWVudW0tY29tcGFyaXNvbiAtLSBBU1Qgbm9kZSB0eXBlIHN0cmluZyBsaXRlcmFscyBtYXRjaCB0aGUgVFNFU1RyZWUgZW51bSB2YWx1ZXMuXG4gIHJldHVybiBub2RlLnR5cGUgPT09ICdCaW5hcnlFeHByZXNzaW9uJztcbn1cblxuLyoqXG4gKiBDaGVja3Mgd2hldGhlciBhIG5vZGUgaXMgYSBjYWxsIGV4cHJlc3Npb24uXG4gKlxuICogQHBhcmFtIG5vZGUgLSBUaGUgbm9kZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIGB0cnVlYCBpZiB0aGUgbm9kZSBpcyBhIGBDYWxsRXhwcmVzc2lvbmAuXG4gKi9cbmZ1bmN0aW9uIGlzQ2FsbEV4cHJlc3Npb24obm9kZTogVFNFU1RyZWUuTm9kZSk6IG5vZGUgaXMgVFNFU1RyZWUuQ2FsbEV4cHJlc3Npb24ge1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVuc2FmZS1lbnVtLWNvbXBhcmlzb24gLS0gQVNUIG5vZGUgdHlwZSBzdHJpbmcgbGl0ZXJhbHMgbWF0Y2ggdGhlIFRTRVNUcmVlIGVudW0gdmFsdWVzLlxuICByZXR1cm4gbm9kZS50eXBlID09PSAnQ2FsbEV4cHJlc3Npb24nO1xufVxuXG4vKipcbiAqIENoZWNrcyB3aGV0aGVyIGEgbm9kZSBpcyBhIGZ1bmN0aW9uIHdyaXR0ZW4gYXMgYW4gb2JqZWN0IHByb3BlcnR5J3MgdmFsdWUuXG4gKlxuICogQHBhcmFtIG5vZGUgLSBUaGUgbm9kZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIGB0cnVlYCBpZiB0aGUgbm9kZSBpcyBhIGBGdW5jdGlvbkV4cHJlc3Npb25gIG9yIGFuIGBBcnJvd0Z1bmN0aW9uRXhwcmVzc2lvbmAuXG4gKi9cbmZ1bmN0aW9uIGlzQ2xvc3VyZUZ1bmN0aW9uKG5vZGU6IFRTRVNUcmVlLk5vZGUpOiBub2RlIGlzIENsb3N1cmVGdW5jdGlvbiB7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW5zYWZlLWVudW0tY29tcGFyaXNvbiAtLSBBU1Qgbm9kZSB0eXBlIHN0cmluZyBsaXRlcmFscyBtYXRjaCB0aGUgVFNFU1RyZWUgZW51bSB2YWx1ZXMuXG4gIHJldHVybiBub2RlLnR5cGUgPT09ICdGdW5jdGlvbkV4cHJlc3Npb24nIHx8IG5vZGUudHlwZSA9PT0gJ0Fycm93RnVuY3Rpb25FeHByZXNzaW9uJztcbn1cblxuLyoqXG4gKiBDaGVja3Mgd2hldGhlciBhIGZ1bmN0aW9uIGlzIGRlY2xhcmVkIHNvbWV3aGVyZSBpbnNpZGUgYW4gaW4tT2JzaWRpYW4gY2xvc3VyZS5cbiAqXG4gKiBBIGhlbHBlciBkZWNsYXJlZCBPVVRTSURFIHRoZSBjbG9zdXJlIGFuc3dlcnMgYGZhbHNlYCwgd2hpY2ggaXMgd2hhdCBrZWVwcyB0aGlzIHJ1bGUncyBhbmFseXNpcyBpbnNpZGVcbiAqIG9uZSBjbG9zdXJlIHJhdGhlciB0aGFuIGZvbGxvd2luZyBjYWxscyBhY3Jvc3MgYm91bmRhcmllcyBpdCBkZWxpYmVyYXRlbHkgZGVjbGluZXMgdG8gcmVhZC5cbiAqXG4gKiBAcGFyYW0gZnVuY3Rpb25Ob2RlIC0gVGhlIGZ1bmN0aW9uIHRvIGNoZWNrLlxuICogQHBhcmFtIGNsb3N1cmUgLSBUaGUgY2xvc3VyZSB0byBjaGVjayBhZ2FpbnN0LlxuICogQHJldHVybnMgYHRydWVgIHdoZW4gdGhlIGZ1bmN0aW9uIGlzIGRlY2xhcmVkIGxleGljYWxseSBpbnNpZGUgdGhlIGNsb3N1cmUuXG4gKi9cbmZ1bmN0aW9uIGlzRGVjbGFyZWRJbnNpZGVDbG9zdXJlKGZ1bmN0aW9uTm9kZTogSGVscGVyRnVuY3Rpb24sIGNsb3N1cmU6IEV2YWxDbG9zdXJlKTogYm9vbGVhbiB7XG4gIGxldCBjdXJyZW50Tm9kZTogVFNFU1RyZWUuTm9kZSB8IHVuZGVmaW5lZCA9IGZ1bmN0aW9uTm9kZS5wYXJlbnQ7XG5cbiAgd2hpbGUgKGN1cnJlbnROb2RlKSB7XG4gICAgaWYgKGN1cnJlbnROb2RlID09PSBjbG9zdXJlLmNsb3N1cmVOb2RlKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgY3VycmVudE5vZGUgPSBjdXJyZW50Tm9kZS5wYXJlbnQ7XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59XG5cbi8qKlxuICogQ2hlY2tzIHdoZXRoZXIgYSBub2RlIGlzIGEgY291bnRpbmcgYGZvcmAgc3RhdGVtZW50LlxuICpcbiAqIEBwYXJhbSBub2RlIC0gVGhlIG5vZGUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyBgdHJ1ZWAgaWYgdGhlIG5vZGUgaXMgYSBgRm9yU3RhdGVtZW50YC5cbiAqL1xuZnVuY3Rpb24gaXNGb3JTdGF0ZW1lbnQobm9kZTogVFNFU1RyZWUuTm9kZSk6IG5vZGUgaXMgVFNFU1RyZWUuRm9yU3RhdGVtZW50IHtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnNhZmUtZW51bS1jb21wYXJpc29uIC0tIEFTVCBub2RlIHR5cGUgc3RyaW5nIGxpdGVyYWxzIG1hdGNoIHRoZSBUU0VTVHJlZSBlbnVtIHZhbHVlcy5cbiAgcmV0dXJuIG5vZGUudHlwZSA9PT0gJ0ZvclN0YXRlbWVudCc7XG59XG5cbi8qKlxuICogQ2hlY2tzIHdoZXRoZXIgYSBub2RlIGlzIGEgZnVuY3Rpb24gd2FpdGluZyBjYW4gYmUgY2hhcmdlZCB0by5cbiAqXG4gKiBBIGBmdW5jdGlvbmAgZGVjbGFyYXRpb24gY291bnRzIGFzIHdlbGwgYXMgdGhlIHR3byBleHByZXNzaW9uIGZvcm1zLCBiZWNhdXNlIHRoYXQgaXMgaG93IHRoZXNlIHN1aXRlc1xuICogd3JpdGUgYSBsb2NhbCByZXRyeSBoZWxwZXIuXG4gKlxuICogQHBhcmFtIG5vZGUgLSBUaGUgbm9kZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIGB0cnVlYCBpZiB0aGUgbm9kZSBpcyBhIGBGdW5jdGlvbkRlY2xhcmF0aW9uYCwgYSBgRnVuY3Rpb25FeHByZXNzaW9uYCBvciBhbiBgQXJyb3dGdW5jdGlvbkV4cHJlc3Npb25gLlxuICovXG5mdW5jdGlvbiBpc0Z1bmN0aW9uTm9kZShub2RlOiBUU0VTVHJlZS5Ob2RlKTogbm9kZSBpcyBIZWxwZXJGdW5jdGlvbiB7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW5zYWZlLWVudW0tY29tcGFyaXNvbiAtLSBBU1Qgbm9kZSB0eXBlIHN0cmluZyBsaXRlcmFscyBtYXRjaCB0aGUgVFNFU1RyZWUgZW51bSB2YWx1ZXMuXG4gIHJldHVybiBpc0Nsb3N1cmVGdW5jdGlvbihub2RlKSB8fCBub2RlLnR5cGUgPT09ICdGdW5jdGlvbkRlY2xhcmF0aW9uJztcbn1cblxuLyoqXG4gKiBDaGVja3Mgd2hldGhlciBhIG5vZGUgaXMgYW4gaWRlbnRpZmllci5cbiAqXG4gKiBAcGFyYW0gbm9kZSAtIFRoZSBub2RlIHRvIGNoZWNrLlxuICogQHJldHVybnMgYHRydWVgIGlmIHRoZSBub2RlIGlzIGFuIGBJZGVudGlmaWVyYC5cbiAqL1xuZnVuY3Rpb24gaXNJZGVudGlmaWVyKG5vZGU6IFRTRVNUcmVlLk5vZGUpOiBub2RlIGlzIFRTRVNUcmVlLklkZW50aWZpZXIge1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVuc2FmZS1lbnVtLWNvbXBhcmlzb24gLS0gQVNUIG5vZGUgdHlwZSBzdHJpbmcgbGl0ZXJhbHMgbWF0Y2ggdGhlIFRTRVNUcmVlIGVudW0gdmFsdWVzLlxuICByZXR1cm4gbm9kZS50eXBlID09PSAnSWRlbnRpZmllcic7XG59XG5cbi8qKlxuICogQ2hlY2tzIHdoZXRoZXIgYSBub2RlIGlzIGFuIGAmJmAgY2hhaW4sIHdob3NlIGNvbmp1bmN0cyBhIGNlaWxpbmcgbWF5IGJlIGRlY2xhcmVkIGluIG9uZSBvZi5cbiAqXG4gKiBAcGFyYW0gbm9kZSAtIFRoZSBub2RlIHRvIGNoZWNrLlxuICogQHJldHVybnMgYHRydWVgIGlmIHRoZSBub2RlIGlzIGEgYExvZ2ljYWxFeHByZXNzaW9uYCB3aXRoIHRoZSBgJiZgIG9wZXJhdG9yLlxuICovXG5mdW5jdGlvbiBpc0xvZ2ljYWxBbmRFeHByZXNzaW9uKG5vZGU6IFRTRVNUcmVlLk5vZGUpOiBub2RlIGlzIFRTRVNUcmVlLkxvZ2ljYWxFeHByZXNzaW9uIHtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnNhZmUtZW51bS1jb21wYXJpc29uIC0tIEFTVCBub2RlIHR5cGUgc3RyaW5nIGxpdGVyYWxzIG1hdGNoIHRoZSBUU0VTVHJlZSBlbnVtIHZhbHVlcy5cbiAgcmV0dXJuIG5vZGUudHlwZSA9PT0gJ0xvZ2ljYWxFeHByZXNzaW9uJyAmJiBub2RlLm9wZXJhdG9yID09PSAnJiYnO1xufVxuXG4vKipcbiAqIENoZWNrcyB3aGV0aGVyIGEgbm9kZSBpcyBhIGxvb3Agd2hvc2Ugb3duIHRlc3QgY2FuIGRlY2xhcmUgYSBjZWlsaW5nLlxuICpcbiAqIEBwYXJhbSBub2RlIC0gVGhlIG5vZGUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyBgdHJ1ZWAgaWYgdGhlIG5vZGUgaXMgYSBgV2hpbGVTdGF0ZW1lbnRgLCBhIGBEb1doaWxlU3RhdGVtZW50YCBvciBhIGBGb3JTdGF0ZW1lbnRgLlxuICovXG5mdW5jdGlvbiBpc0xvb3BTdGF0ZW1lbnQobm9kZTogVFNFU1RyZWUuTm9kZSk6IG5vZGUgaXMgTG9vcFN0YXRlbWVudCB7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW5zYWZlLWVudW0tY29tcGFyaXNvbiAtLSBBU1Qgbm9kZSB0eXBlIHN0cmluZyBsaXRlcmFscyBtYXRjaCB0aGUgVFNFU1RyZWUgZW51bSB2YWx1ZXMuXG4gIHJldHVybiBub2RlLnR5cGUgPT09ICdXaGlsZVN0YXRlbWVudCcgfHwgbm9kZS50eXBlID09PSAnRG9XaGlsZVN0YXRlbWVudCcgfHwgaXNGb3JTdGF0ZW1lbnQobm9kZSk7XG59XG5cbi8qKlxuICogQ2hlY2tzIHdoZXRoZXIgYSBub2RlIGlzIGEgbWVtYmVyIGV4cHJlc3Npb24uXG4gKlxuICogQHBhcmFtIG5vZGUgLSBUaGUgbm9kZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIGB0cnVlYCBpZiB0aGUgbm9kZSBpcyBhIGBNZW1iZXJFeHByZXNzaW9uYC5cbiAqL1xuZnVuY3Rpb24gaXNNZW1iZXJFeHByZXNzaW9uKG5vZGU6IFRTRVNUcmVlLk5vZGUpOiBub2RlIGlzIFRTRVNUcmVlLk1lbWJlckV4cHJlc3Npb24ge1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVuc2FmZS1lbnVtLWNvbXBhcmlzb24gLS0gQVNUIG5vZGUgdHlwZSBzdHJpbmcgbGl0ZXJhbHMgbWF0Y2ggdGhlIFRTRVNUcmVlIGVudW0gdmFsdWVzLlxuICByZXR1cm4gbm9kZS50eXBlID09PSAnTWVtYmVyRXhwcmVzc2lvbic7XG59XG5cbi8qKlxuICogQ2hlY2tzIHdoZXRoZXIgYSBub2RlIGlzIGEgbnVtZXJpYyBsaXRlcmFsLlxuICpcbiAqIEBwYXJhbSBub2RlIC0gVGhlIG5vZGUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyBgdHJ1ZWAgaWYgdGhlIG5vZGUgaXMgYSBgTGl0ZXJhbGAgaG9sZGluZyBhIG51bWJlci5cbiAqL1xuZnVuY3Rpb24gaXNOdW1lcmljTGl0ZXJhbChub2RlOiBUU0VTVHJlZS5Ob2RlKTogbm9kZSBpcyBUU0VTVHJlZS5OdW1iZXJMaXRlcmFsIHtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnNhZmUtZW51bS1jb21wYXJpc29uIC0tIEFTVCBub2RlIHR5cGUgc3RyaW5nIGxpdGVyYWxzIG1hdGNoIHRoZSBUU0VTVHJlZSBlbnVtIHZhbHVlcy5cbiAgcmV0dXJuIG5vZGUudHlwZSA9PT0gJ0xpdGVyYWwnICYmIHR5cGVvZiBub2RlLnZhbHVlID09PSAnbnVtYmVyJztcbn1cblxuLyoqXG4gKiBDaGVja3Mgd2hldGhlciBhIG5vZGUgaXMgYW4gb2JqZWN0IGxpdGVyYWwuXG4gKlxuICogQHBhcmFtIG5vZGUgLSBUaGUgbm9kZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIGB0cnVlYCBpZiB0aGUgbm9kZSBpcyBhbiBgT2JqZWN0RXhwcmVzc2lvbmAuXG4gKi9cbmZ1bmN0aW9uIGlzT2JqZWN0RXhwcmVzc2lvbihub2RlOiBUU0VTVHJlZS5Ob2RlKTogbm9kZSBpcyBUU0VTVHJlZS5PYmplY3RFeHByZXNzaW9uIHtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnNhZmUtZW51bS1jb21wYXJpc29uIC0tIEFTVCBub2RlIHR5cGUgc3RyaW5nIGxpdGVyYWxzIG1hdGNoIHRoZSBUU0VTVHJlZSBlbnVtIHZhbHVlcy5cbiAgcmV0dXJuIG5vZGUudHlwZSA9PT0gJ09iamVjdEV4cHJlc3Npb24nO1xufVxuXG4vKipcbiAqIENoZWNrcyB3aGV0aGVyIGEgbm9kZSBpcyBhbiBvYmplY3QgZGVzdHJ1Y3R1cmluZyBwYXR0ZXJuLlxuICpcbiAqIEBwYXJhbSBub2RlIC0gVGhlIG5vZGUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyBgdHJ1ZWAgaWYgdGhlIG5vZGUgaXMgYW4gYE9iamVjdFBhdHRlcm5gLlxuICovXG5mdW5jdGlvbiBpc09iamVjdFBhdHRlcm4obm9kZTogVFNFU1RyZWUuTm9kZSk6IG5vZGUgaXMgVFNFU1RyZWUuT2JqZWN0UGF0dGVybiB7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW5zYWZlLWVudW0tY29tcGFyaXNvbiAtLSBBU1Qgbm9kZSB0eXBlIHN0cmluZyBsaXRlcmFscyBtYXRjaCB0aGUgVFNFU1RyZWUgZW51bSB2YWx1ZXMuXG4gIHJldHVybiBub2RlLnR5cGUgPT09ICdPYmplY3RQYXR0ZXJuJztcbn1cblxuLyoqXG4gKiBDaGVja3Mgd2hldGhlciBhIG5vZGUgaXMgYW4gb2JqZWN0LWxpdGVyYWwgb3Igb2JqZWN0LXBhdHRlcm4gcHJvcGVydHkuXG4gKlxuICogQHBhcmFtIG5vZGUgLSBUaGUgbm9kZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIGB0cnVlYCBpZiB0aGUgbm9kZSBpcyBhIGBQcm9wZXJ0eWAuXG4gKi9cbmZ1bmN0aW9uIGlzUHJvcGVydHkobm9kZTogVFNFU1RyZWUuTm9kZSk6IG5vZGUgaXMgVFNFU1RyZWUuUHJvcGVydHkge1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVuc2FmZS1lbnVtLWNvbXBhcmlzb24gLS0gQVNUIG5vZGUgdHlwZSBzdHJpbmcgbGl0ZXJhbHMgbWF0Y2ggdGhlIFRTRVNUcmVlIGVudW0gdmFsdWVzLlxuICByZXR1cm4gbm9kZS50eXBlID09PSAnUHJvcGVydHknO1xufVxuXG4vKipcbiAqIENoZWNrcyB3aGV0aGVyIGEgbm9kZSBpcyBhbiB1cGRhdGUgZXhwcmVzc2lvbi5cbiAqXG4gKiBAcGFyYW0gbm9kZSAtIFRoZSBub2RlIHRvIGNoZWNrLlxuICogQHJldHVybnMgYHRydWVgIGlmIHRoZSBub2RlIGlzIGFuIGBVcGRhdGVFeHByZXNzaW9uYC5cbiAqL1xuZnVuY3Rpb24gaXNVcGRhdGVFeHByZXNzaW9uKG5vZGU6IFRTRVNUcmVlLk5vZGUpOiBub2RlIGlzIFRTRVNUcmVlLlVwZGF0ZUV4cHJlc3Npb24ge1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVuc2FmZS1lbnVtLWNvbXBhcmlzb24gLS0gQVNUIG5vZGUgdHlwZSBzdHJpbmcgbGl0ZXJhbHMgbWF0Y2ggdGhlIFRTRVNUcmVlIGVudW0gdmFsdWVzLlxuICByZXR1cm4gbm9kZS50eXBlID09PSAnVXBkYXRlRXhwcmVzc2lvbic7XG59XG5cbi8qKlxuICogQ2hlY2tzIHdoZXRoZXIgYSBub2RlIGlzIGEgdmFyaWFibGUgZGVjbGFyYXRpb24uXG4gKlxuICogQHBhcmFtIG5vZGUgLSBUaGUgbm9kZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIGB0cnVlYCBpZiB0aGUgbm9kZSBpcyBhIGBWYXJpYWJsZURlY2xhcmF0aW9uYC5cbiAqL1xuZnVuY3Rpb24gaXNWYXJpYWJsZURlY2xhcmF0aW9uKG5vZGU6IFRTRVNUcmVlLk5vZGUpOiBub2RlIGlzIFRTRVNUcmVlLlZhcmlhYmxlRGVjbGFyYXRpb24ge1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVuc2FmZS1lbnVtLWNvbXBhcmlzb24gLS0gQVNUIG5vZGUgdHlwZSBzdHJpbmcgbGl0ZXJhbHMgbWF0Y2ggdGhlIFRTRVNUcmVlIGVudW0gdmFsdWVzLlxuICByZXR1cm4gbm9kZS50eXBlID09PSAnVmFyaWFibGVEZWNsYXJhdGlvbic7XG59XG5cbi8qKlxuICogQ2hlY2tzIHdoZXRoZXIgYSBub2RlIGlzIGEgdmFyaWFibGUgZGVjbGFyYXRvci5cbiAqXG4gKiBAcGFyYW0gbm9kZSAtIFRoZSBub2RlIHRvIGNoZWNrLlxuICogQHJldHVybnMgYHRydWVgIGlmIHRoZSBub2RlIGlzIGEgYFZhcmlhYmxlRGVjbGFyYXRvcmAuXG4gKi9cbmZ1bmN0aW9uIGlzVmFyaWFibGVEZWNsYXJhdG9yKG5vZGU6IFRTRVNUcmVlLk5vZGUpOiBub2RlIGlzIFRTRVNUcmVlLlZhcmlhYmxlRGVjbGFyYXRvciB7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW5zYWZlLWVudW0tY29tcGFyaXNvbiAtLSBBU1Qgbm9kZSB0eXBlIHN0cmluZyBsaXRlcmFscyBtYXRjaCB0aGUgVFNFU1RyZWUgZW51bSB2YWx1ZXMuXG4gIHJldHVybiBub2RlLnR5cGUgPT09ICdWYXJpYWJsZURlY2xhcmF0b3InO1xufVxuXG4vKipcbiAqIFJlYWRzIHRoZSBleHByZXNzaW9uIGFuIGlkZW50aWZpZXIgaXMgYm91bmQgdG8uXG4gKlxuICogQSBgY29uc3RgIGFuc3dlcnMgd2l0aCBpdHMgaW5pdGlhbGl6ZXI7IGEgZGVzdHJ1Y3R1cmVkIHBhcmFtZXRlciBvZiBUSElTIGNsb3N1cmUgYW5zd2VycyB3aXRoIHdoYXQgdGhlXG4gKiBjYWxsJ3Mgb3duIGBpbnB1dGAgc3VwcGxpZXMgZm9yIHRoZSBrZXkgaXQgd2FzIGRlc3RydWN0dXJlZCBieSwgd2hpY2ggaXMgaG93IGEgYnVkZ2V0IHdyaXR0ZW4gb25jZSBhdFxuICogdGhlIGNhbGwgc2l0ZSByZWFjaGVzIGEgY2xvc3VyZSB0aGF0IGNhbiBjbG9zZSBvdmVyIG5vdGhpbmcuXG4gKlxuICogQHBhcmFtIG5vZGUgLSBUaGUgaWRlbnRpZmllciB0byByZXNvbHZlLlxuICogQHBhcmFtIGNsb3N1cmUgLSBUaGUgY2xvc3VyZSB0aGUgaWRlbnRpZmllciB3YXMgd3JpdHRlbiBpbnNpZGUuXG4gKiBAcGFyYW0gY29udGV4dCAtIFRoZSBydWxlIGNvbnRleHQsIHVzZWQgdG8gcmVzb2x2ZSB0aGUgaWRlbnRpZmllciB0aHJvdWdoIHNjb3BlLlxuICogQHJldHVybnMgVGhlIGV4cHJlc3Npb24gaXQgaXMgYm91bmQgdG8sIG9yIGBudWxsYCB3aGVuIG5vdGhpbmcgc3RhdGljYWxseSBiaW5kcyBpdC5cbiAqL1xuZnVuY3Rpb24gcmVhZEJvdW5kRXhwcmVzc2lvbihub2RlOiBUU0VTVHJlZS5JZGVudGlmaWVyLCBjbG9zdXJlOiBFdmFsQ2xvc3VyZSwgY29udGV4dDogUnVsZS5SdWxlQ29udGV4dCk6IG51bGwgfCBUU0VTVHJlZS5Ob2RlIHtcbiAgY29uc3QgdmFyaWFibGUgPSBmaW5kVmFyaWFibGUoY29udGV4dC5zb3VyY2VDb2RlLmdldFNjb3BlKG5vZGUpLCBub2RlLm5hbWUpO1xuICBpZiAoIXZhcmlhYmxlKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBmb3IgKGNvbnN0IGRlZmluaXRpb24gb2YgdmFyaWFibGUuZGVmcykge1xuICAgIGNvbnN0IGRlZmluaXRpb25Ob2RlID0gdG9UU0VTVHJlZU5vZGUoZGVmaW5pdGlvbi5ub2RlKTtcblxuICAgIGlmIChpc1ZhcmlhYmxlRGVjbGFyYXRvcihkZWZpbml0aW9uTm9kZSkgJiYgZGVmaW5pdGlvbk5vZGUuaW5pdCkge1xuICAgICAgcmV0dXJuIGRlZmluaXRpb25Ob2RlLmluaXQ7XG4gICAgfVxuXG4gICAgaWYgKGRlZmluaXRpb25Ob2RlID09PSBjbG9zdXJlLmNsb3N1cmVOb2RlKSB7XG4gICAgICBjb25zdCBpbnB1dEtleSA9IHJlYWRQYXJhbWV0ZXJJbnB1dEtleShjbG9zdXJlLmNsb3N1cmVOb2RlLCBub2RlLm5hbWUpO1xuICAgICAgcmV0dXJuIGlucHV0S2V5ID09PSBudWxsID8gbnVsbCA6IHJlYWRJbnB1dFByb3BlcnR5VmFsdWUoY2xvc3VyZS5wYXJhbXNOb2RlLCBpbnB1dEtleSk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG51bGw7XG59XG5cbi8qKlxuICogUmVhZHMgdGhlIGhlbHBlciBhIGNhbGwgbmFtZXMsIHdoZW4gdGhhdCBoZWxwZXIgaXMgZGVjbGFyZWQgaW5zaWRlIHRoZSBnaXZlbiBjbG9zdXJlLlxuICpcbiAqIEJvdGggZm9ybXMgdGhlc2Ugc3VpdGVzIHdyaXRlIGFyZSByZXNvbHZlZCB0aHJvdWdoIHRoZSBzYW1lIHNjb3BlIHdhbGsgYSBidWRnZXQgdXNlczogYSBgZnVuY3Rpb25gXG4gKiBkZWNsYXJhdGlvbiwgYW5kIGEgYGNvbnN0YCBib3VuZCB0byBhbiBhcnJvdyBvciBhIGZ1bmN0aW9uIGV4cHJlc3Npb24uXG4gKlxuICogQHBhcmFtIGNhbGxOb2RlIC0gVGhlIGNhbGwgZXhwcmVzc2lvbi5cbiAqIEBwYXJhbSBjbG9zdXJlIC0gVGhlIGluLU9ic2lkaWFuIGNsb3N1cmUgdGhlIGNhbGwgcnVucyBpbnNpZGUuXG4gKiBAcGFyYW0gY29udGV4dCAtIFRoZSBydWxlIGNvbnRleHQsIHVzZWQgdG8gcmVzb2x2ZSB0aGUgY2FsbGVlIHRocm91Z2ggc2NvcGUuXG4gKiBAcmV0dXJucyBUaGUgaGVscGVyJ3MgZnVuY3Rpb24gbm9kZSwgb3IgYG51bGxgIHdoZW4gdGhlIGNhbGxlZSBpcyBub3QgYSBoZWxwZXIgb2YgdGhpcyBjbG9zdXJlLlxuICovXG5mdW5jdGlvbiByZWFkQ2FsbGVkSGVscGVyTm9kZShjYWxsTm9kZTogVFNFU1RyZWUuQ2FsbEV4cHJlc3Npb24sIGNsb3N1cmU6IEV2YWxDbG9zdXJlLCBjb250ZXh0OiBSdWxlLlJ1bGVDb250ZXh0KTogSGVscGVyRnVuY3Rpb24gfCBudWxsIHtcbiAgY29uc3QgY2FsbGVlTm9kZSA9IGNhbGxOb2RlLmNhbGxlZSBhcyBUU0VTVHJlZS5Ob2RlO1xuICBpZiAoIWlzSWRlbnRpZmllcihjYWxsZWVOb2RlKSkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgY29uc3QgdmFyaWFibGUgPSBmaW5kVmFyaWFibGUoY29udGV4dC5zb3VyY2VDb2RlLmdldFNjb3BlKGNhbGxlZU5vZGUpLCBjYWxsZWVOb2RlLm5hbWUpO1xuICBpZiAoIXZhcmlhYmxlKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBmb3IgKGNvbnN0IGRlZmluaXRpb24gb2YgdmFyaWFibGUuZGVmcykge1xuICAgIGNvbnN0IGZ1bmN0aW9uTm9kZSA9IHJlYWREZWZpbml0aW9uRnVuY3Rpb25Ob2RlKHRvVFNFU1RyZWVOb2RlKGRlZmluaXRpb24ubm9kZSkpO1xuICAgIGlmIChmdW5jdGlvbk5vZGUgJiYgaXNEZWNsYXJlZEluc2lkZUNsb3N1cmUoZnVuY3Rpb25Ob2RlLCBjbG9zdXJlKSkge1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uTm9kZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn1cblxuLyoqXG4gKiBTdW1zIGEgZnVuY3Rpb24ncyBvd24gd2FpdGluZyBwbHVzIHRoYXQgb2YgZXZlcnkgaGVscGVyIGl0IGNhbGxzLCBtdWx0aXBsaWVkIGJ5IHRoZSBjYWxscyB0aGF0IHJlYWNoIGl0LlxuICpcbiAqIEEgZnVuY3Rpb24gYWxyZWFkeSBvbiB0aGUgc3RhY2sgY29udHJpYnV0ZXMgTk9USElORywgd2hpY2ggaXMgd2hhdCB0ZXJtaW5hdGVzIGRpcmVjdCBhbmQgbXV0dWFsXG4gKiByZWN1cnNpb24gXHUyMDE0IHRoZSBzYW1lIHNpbGVuY2UgYW4gdW5ib3VuZGVkIGxvb3AgZ2V0cywgcmF0aGVyIHRoYW4gYSBndWVzcyBhdCBob3cgb2Z0ZW4gaXQgcmVwZWF0cy4gVGhlXG4gKiBzdGFjayBpcyB1bndvdW5kIG9uIHRoZSB3YXkgb3V0LCBzbyBhIGhlbHBlciByZWFjaGVkIGRvd24gdHdvIGRpZmZlcmVudCBwYXRocyBpcyBjb3VudGVkIG9uIGJvdGguXG4gKlxuICogQHBhcmFtIGZ1bmN0aW9uTm9kZSAtIFRoZSBmdW5jdGlvbiB0byB0b3RhbC5cbiAqIEBwYXJhbSBjYWxsR3JhcGggLSBUaGUgZmlsZSdzIGFjY3VtdWxhdGVkIGNoYXJnZXMuXG4gKiBAcGFyYW0gdmlzaXRlZE5vZGVzIC0gVGhlIGZ1bmN0aW9ucyBjdXJyZW50bHkgYmVpbmcgdG90YWxsZWQsIHdoaWNoIGlzIHRoZSByZWN1cnNpb24gc3RhY2suXG4gKiBAcmV0dXJucyBUaGUgd2FpdGluZywgaW4gbWlsbGlzZWNvbmRzLlxuICovXG5mdW5jdGlvbiByZWFkQ2FsbEdyYXBoV2FpdEluTWlsbGlzZWNvbmRzKGZ1bmN0aW9uTm9kZTogSGVscGVyRnVuY3Rpb24sIGNhbGxHcmFwaDogQ2FsbEdyYXBoLCB2aXNpdGVkTm9kZXM6IFNldDxIZWxwZXJGdW5jdGlvbj4pOiBudW1iZXIge1xuICBpZiAodmlzaXRlZE5vZGVzLmhhcyhmdW5jdGlvbk5vZGUpKSB7XG4gICAgcmV0dXJuIDA7XG4gIH1cblxuICB2aXNpdGVkTm9kZXMuYWRkKGZ1bmN0aW9uTm9kZSk7XG5cbiAgbGV0IHRvdGFsSW5NaWxsaXNlY29uZHMgPSBjYWxsR3JhcGgud2FpdEluTWlsbGlzZWNvbmRzQnlGdW5jdGlvbk5vZGUuZ2V0KGZ1bmN0aW9uTm9kZSkgPz8gMDtcbiAgZm9yIChjb25zdCBbY2FsbGVlTm9kZSwgY2FsbENvdW50XSBvZiBjYWxsR3JhcGguY2FsbENvdW50QnlDYWxsZWVOb2RlQnlDYWxsZXJOb2RlLmdldChmdW5jdGlvbk5vZGUpID8/IFtdKSB7XG4gICAgdG90YWxJbk1pbGxpc2Vjb25kcyArPSBjYWxsQ291bnQgKiByZWFkQ2FsbEdyYXBoV2FpdEluTWlsbGlzZWNvbmRzKGNhbGxlZU5vZGUsIGNhbGxHcmFwaCwgdmlzaXRlZE5vZGVzKTtcbiAgfVxuXG4gIHZpc2l0ZWROb2Rlcy5kZWxldGUoZnVuY3Rpb25Ob2RlKTtcbiAgcmV0dXJuIHRvdGFsSW5NaWxsaXNlY29uZHM7XG59XG5cbi8qKlxuICogUmVhZHMgdGhlIGNsb2NrIGEgbm9kZSByZWFkcyB0aGUgY3VycmVudCB0aW1lIGZyb20sIGlmIHRoYXQgaXMgd2hhdCBpdCBkb2VzLlxuICpcbiAqIEBwYXJhbSBub2RlIC0gVGhlIG5vZGUgdG8gaW5zcGVjdC5cbiAqIEByZXR1cm5zIFRoZSBjbG9jayBvYmplY3QncyBuYW1lIChgRGF0ZWAgb3IgYHBlcmZvcm1hbmNlYCksIG9yIGBudWxsYCB3aGVuIHRoZSBub2RlIGlzIG5vdCBhIGNsb2NrIHJlYWRpbmcuXG4gKi9cbmZ1bmN0aW9uIHJlYWRDbG9ja05hbWUobm9kZTogVFNFU1RyZWUuTm9kZSk6IG51bGwgfCBzdHJpbmcge1xuICBpZiAoIWlzQ2FsbEV4cHJlc3Npb24obm9kZSkgfHwgbm9kZS5hcmd1bWVudHMubGVuZ3RoID4gMCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgY29uc3QgY2FsbGVlTm9kZSA9IG5vZGUuY2FsbGVlIGFzIFRTRVNUcmVlLk5vZGU7XG4gIGlmICghaXNNZW1iZXJFeHByZXNzaW9uKGNhbGxlZU5vZGUpIHx8IGNhbGxlZU5vZGUuY29tcHV0ZWQpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGNvbnN0IG9iamVjdE5vZGUgPSBjYWxsZWVOb2RlLm9iamVjdCBhcyBUU0VTVHJlZS5Ob2RlO1xuICBjb25zdCBwcm9wZXJ0eU5vZGUgPSBjYWxsZWVOb2RlLnByb3BlcnR5IGFzIFRTRVNUcmVlLk5vZGU7XG4gIHJldHVybiAhaXNJZGVudGlmaWVyKG9iamVjdE5vZGUpIHx8ICFpc0lkZW50aWZpZXIocHJvcGVydHlOb2RlKSB8fCBwcm9wZXJ0eU5vZGUubmFtZSAhPT0gTk9XX01FVEhPRF9OQU1FIHx8ICFDTE9DS19PQkpFQ1RfTkFNRVMuaGFzKG9iamVjdE5vZGUubmFtZSkgPyBudWxsIDogb2JqZWN0Tm9kZS5uYW1lO1xufVxuXG4vKipcbiAqIFJlYWRzIHRoZSBjbG9zdXJlIHByb3BlcnR5IG5hbWVzIGEgY2FsbCdzIHBhcmFtZXRlciBvYmplY3QgbWF5IGNhcnJ5LCBieSB0aGUgaGVscGVyIGl0IGNhbGxzLlxuICpcbiAqIEBwYXJhbSBjYWxsTm9kZSAtIFRoZSBjYWxsIGV4cHJlc3Npb24uXG4gKiBAcmV0dXJucyBUaGUgaW4tT2JzaWRpYW4gY2xvc3VyZSBwcm9wZXJ0eSBuYW1lcywgb3IgYG51bGxgIHdoZW4gdGhlIGNhbGxlZSBpcyBub3Qgb25lIG9mIHRoZSBoZWxwZXJzLlxuICovXG5mdW5jdGlvbiByZWFkQ2xvc3VyZU5hbWVzKGNhbGxOb2RlOiBUU0VTVHJlZS5DYWxsRXhwcmVzc2lvbik6IG51bGwgfCByZWFkb25seSBzdHJpbmdbXSB7XG4gIHJldHVybiBpc0lkZW50aWZpZXIoY2FsbE5vZGUuY2FsbGVlKSA/IENMT1NVUkVfTkFNRVNfQllfQ0FMTEVFX05BTUUuZ2V0KGNhbGxOb2RlLmNhbGxlZS5uYW1lKSA/PyBudWxsIDogbnVsbDtcbn1cblxuLyoqXG4gKiBSZWFkcyBvbmUgY2xvc3VyZSdzIHdob2xlIGRlY2xhcmVkIHdhaXRpbmcuXG4gKlxuICogRXZlcnl0aGluZyB0aGUgY2xvc3VyZSBjYW4gUkVBQ0ggaXMgdG90YWxsZWQgdGhyb3VnaCB0aGUgY2FsbCBncmFwaCwgb25jZSBwZXIgY2FsbCBzaXRlLiBFdmVyeXRoaW5nIGl0XG4gKiBjYW5ub3QgXHUyMDE0IGEgaGVscGVyIG5vdGhpbmcgY2FsbHMsIG9yIG9uZSBjYWxsZWQgdGhyb3VnaCBhIHJlZmVyZW5jZSB0aGlzIHJ1bGUgY2Fubm90IGZvbGxvdyBcdTIwMTQga2VlcHMgdGhlXG4gKiBmbGF0IHNpbmdsZSBjaGFyZ2UgYSBsZXhpY2FsIGF0dHJpYnV0aW9uIGFsd2F5cyBnYXZlIGl0LCBzbyBubyBjbG9zdXJlIHJlcG9ydGVkIGJlZm9yZSB0aGlzIHJ1bGUgY291bnRlZFxuICogY2FsbCBzaXRlcyBmYWxscyBzaWxlbnQgbm93IHRoYXQgaXQgZG9lcy5cbiAqXG4gKiBAcGFyYW0gc3RhdGUgLSBUaGUgY2xvc3VyZSdzIGFjY3VtdWxhdGVkIGNoYXJnZXMuXG4gKiBAcGFyYW0gY2FsbEdyYXBoIC0gVGhlIGZpbGUncyBhY2N1bXVsYXRlZCBjaGFyZ2VzLlxuICogQHJldHVybnMgVGhlIHdhaXRpbmcgdGhlIGNsb3N1cmUgZGVjbGFyZXMsIGluIG1pbGxpc2Vjb25kcy5cbiAqL1xuZnVuY3Rpb24gcmVhZENsb3N1cmVXYWl0SW5NaWxsaXNlY29uZHMoc3RhdGU6IENsb3N1cmVTdGF0ZSwgY2FsbEdyYXBoOiBDYWxsR3JhcGgpOiBudW1iZXIge1xuICBjb25zdCByZWFjaGFibGVOb2RlcyA9IG5ldyBTZXQ8SGVscGVyRnVuY3Rpb24+KCk7XG4gIGNvbGxlY3RSZWFjaGFibGVGdW5jdGlvbk5vZGVzKHN0YXRlLmNsb3N1cmVOb2RlLCBjYWxsR3JhcGgsIHJlYWNoYWJsZU5vZGVzKTtcblxuICBsZXQgdG90YWxJbk1pbGxpc2Vjb25kcyA9IHJlYWRDYWxsR3JhcGhXYWl0SW5NaWxsaXNlY29uZHMoc3RhdGUuY2xvc3VyZU5vZGUsIGNhbGxHcmFwaCwgbmV3IFNldDxIZWxwZXJGdW5jdGlvbj4oKSk7XG5cbiAgZm9yIChjb25zdCBmdW5jdGlvbk5vZGUgb2Ygc3RhdGUuZnVuY3Rpb25Ob2Rlcykge1xuICAgIGNvbnN0IG93bldhaXRJbk1pbGxpc2Vjb25kcyA9IGNhbGxHcmFwaC53YWl0SW5NaWxsaXNlY29uZHNCeUZ1bmN0aW9uTm9kZS5nZXQoZnVuY3Rpb25Ob2RlKTtcbiAgICBpZiAob3duV2FpdEluTWlsbGlzZWNvbmRzID09PSB1bmRlZmluZWQgfHwgcmVhY2hhYmxlTm9kZXMuaGFzKGZ1bmN0aW9uTm9kZSkpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIHRvdGFsSW5NaWxsaXNlY29uZHMgKz0gb3duV2FpdEluTWlsbGlzZWNvbmRzO1xuICB9XG5cbiAgcmV0dXJuIHRvdGFsSW5NaWxsaXNlY29uZHM7XG59XG5cbi8qKlxuICogRmxhdHRlbnMgYW4gYCYmYCBjaGFpbiBpbnRvIHRoZSBjb25kaXRpb25zIGl0IGlzIGJ1aWx0IGZyb20uXG4gKlxuICogQSB0ZXN0IHRoYXQgaXMgbm90IGFuIGAmJmAgY2hhaW4gYW5zd2VycyB3aXRoIGl0c2VsZiwgc28gYSBjYWxsZXIgbmV2ZXIgc3BlY2lhbC1jYXNlcyB0aGUgc2ltcGxlIGZvcm0uXG4gKlxuICogQHBhcmFtIG5vZGUgLSBUaGUgZXhwcmVzc2lvbiB0byBmbGF0dGVuLlxuICogQHJldHVybnMgRXZlcnkgY29uanVuY3QsIGxlZnQgdG8gcmlnaHQuXG4gKi9cbmZ1bmN0aW9uIHJlYWRDb25qdW5jdHMobm9kZTogVFNFU1RyZWUuRXhwcmVzc2lvbik6IFRTRVNUcmVlLkV4cHJlc3Npb25bXSB7XG4gIHJldHVybiBpc0xvZ2ljYWxBbmRFeHByZXNzaW9uKG5vZGUpID8gWy4uLnJlYWRDb25qdW5jdHMobm9kZS5sZWZ0KSwgLi4ucmVhZENvbmp1bmN0cyhub2RlLnJpZ2h0KV0gOiBbbm9kZV07XG59XG5cbi8qKlxuICogUmVhZHMgdGhlIGNlaWxpbmcgYSBzaW5nbGUgYGNsb2NrLm5vdygpIDwgZGVhZGxpbmVgIGNvbXBhcmlzb24gZGVjbGFyZXMuXG4gKlxuICogQm90aCBvcGVyYW5kIG9yZGVycyBhcmUgcmVhZCwgc2luY2UgYGRlYWRsaW5lID4gY2xvY2subm93KClgIGlzIHRoZSBzYW1lIGd1YXJkIHdyaXR0ZW4gdGhlIG90aGVyIHdheVxuICogcm91bmQuIFRoZSBiaW5kaW5nIG11c3QgdGFrZSBpdHMgdGltZSBmcm9tIHRoZSBTQU1FIGNsb2NrIGFzIHRoZSBndWFyZDogYSBjb21wYXJpc29uIGFjcm9zcyB0aGUgdHdvXG4gKiBtZWFzdXJlcyBub3RoaW5nLCBhbmQgZGVjbGluaW5nIGl0IGlzIHRoZSBzaWxlbmNlIGFueSB1bnJlc29sdmFibGUgdmFsdWUgYWxyZWFkeSBnZXRzLlxuICpcbiAqIEBwYXJhbSBub2RlIC0gVGhlIGNvbmRpdGlvbiB0byBpbnNwZWN0LlxuICogQHBhcmFtIGNsb3N1cmUgLSBUaGUgaW4tT2JzaWRpYW4gY2xvc3VyZSB0aGUgbG9vcCBydW5zIGluc2lkZS5cbiAqIEBwYXJhbSBjb250ZXh0IC0gVGhlIHJ1bGUgY29udGV4dCwgdXNlZCB0byByZXNvbHZlIHRoZSBkZWFkbGluZSB0aHJvdWdoIHNjb3BlLlxuICogQHJldHVybnMgVGhlIGNlaWxpbmcgaW4gbWlsbGlzZWNvbmRzLCBvciBgbnVsbGAgd2hlbiB0aGUgY29uZGl0aW9uIGRlY2xhcmVzIG5vbmUuXG4gKi9cbmZ1bmN0aW9uIHJlYWREZWFkbGluZUd1YXJkSW5NaWxsaXNlY29uZHMobm9kZTogVFNFU1RyZWUuTm9kZSwgY2xvc3VyZTogRXZhbENsb3N1cmUsIGNvbnRleHQ6IFJ1bGUuUnVsZUNvbnRleHQpOiBudWxsIHwgbnVtYmVyIHtcbiAgaWYgKCFpc0JpbmFyeUV4cHJlc3Npb24obm9kZSkpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGNvbnN0IGlzQ2xvY2tPbkxlZnQgPSBub2RlLm9wZXJhdG9yID09PSAnPCcgfHwgbm9kZS5vcGVyYXRvciA9PT0gJzw9JztcbiAgaWYgKCFpc0Nsb2NrT25MZWZ0ICYmIG5vZGUub3BlcmF0b3IgIT09ICc+JyAmJiBub2RlLm9wZXJhdG9yICE9PSAnPj0nKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBjb25zdCBjbG9ja05hbWUgPSByZWFkQ2xvY2tOYW1lKGlzQ2xvY2tPbkxlZnQgPyBub2RlLmxlZnQgOiBub2RlLnJpZ2h0KTtcbiAgY29uc3QgZGVhZGxpbmVOb2RlID0gKGlzQ2xvY2tPbkxlZnQgPyBub2RlLnJpZ2h0IDogbm9kZS5sZWZ0KSBhcyBUU0VTVHJlZS5Ob2RlO1xuICBpZiAoY2xvY2tOYW1lID09PSBudWxsIHx8ICFpc0lkZW50aWZpZXIoZGVhZGxpbmVOb2RlKSkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgY29uc3QgYm91bmROb2RlID0gcmVhZEJvdW5kRXhwcmVzc2lvbihkZWFkbGluZU5vZGUsIGNsb3N1cmUsIGNvbnRleHQpO1xuICByZXR1cm4gIWJvdW5kTm9kZSB8fCAhaXNCaW5hcnlFeHByZXNzaW9uKGJvdW5kTm9kZSkgfHwgYm91bmROb2RlLm9wZXJhdG9yICE9PSAnKycgfHwgKHJlYWRDbG9ja05hbWUoYm91bmROb2RlLmxlZnQpICE9PSBjbG9ja05hbWUpID8gbnVsbCA6IHJlc29sdmVOdW1iZXIoYm91bmROb2RlLnJpZ2h0LCBjbG9zdXJlLCBjb250ZXh0KTtcbn1cblxuLyoqXG4gKiBSZWFkcyB0aGUgZnVuY3Rpb24gYSBzY29wZSBkZWZpbml0aW9uIGRlY2xhcmVzLCBpZiBpdCBkZWNsYXJlcyBvbmUuXG4gKlxuICogQHBhcmFtIGRlZmluaXRpb25Ob2RlIC0gVGhlIG5vZGUgYSB2YXJpYWJsZSdzIGRlZmluaXRpb24gcG9pbnRzIGF0LlxuICogQHJldHVybnMgVGhlIGZ1bmN0aW9uIGl0IGRlY2xhcmVzLCBvciBgbnVsbGAgd2hlbiB0aGUgbmFtZSBpcyBib3VuZCB0byBhbnl0aGluZyBlbHNlLlxuICovXG5mdW5jdGlvbiByZWFkRGVmaW5pdGlvbkZ1bmN0aW9uTm9kZShkZWZpbml0aW9uTm9kZTogVFNFU1RyZWUuTm9kZSk6IEhlbHBlckZ1bmN0aW9uIHwgbnVsbCB7XG4gIGlmIChpc0Z1bmN0aW9uTm9kZShkZWZpbml0aW9uTm9kZSkpIHtcbiAgICByZXR1cm4gZGVmaW5pdGlvbk5vZGU7XG4gIH1cblxuICBpZiAoIWlzVmFyaWFibGVEZWNsYXJhdG9yKGRlZmluaXRpb25Ob2RlKSB8fCAhZGVmaW5pdGlvbk5vZGUuaW5pdCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgY29uc3QgaW5pdE5vZGUgPSBkZWZpbml0aW9uTm9kZS5pbml0IGFzIFRTRVNUcmVlLk5vZGU7XG4gIHJldHVybiBpc0Z1bmN0aW9uTm9kZShpbml0Tm9kZSkgPyBpbml0Tm9kZSA6IG51bGw7XG59XG5cbi8qKlxuICogUmVhZHMgdGhlIGluLU9ic2lkaWFuIGNsb3N1cmUgYSBmdW5jdGlvbiBub2RlIGlzLCBpZiBpdCBpcyBvbmUuXG4gKlxuICogQSBjbG9zdXJlIHF1YWxpZmllcyB3aGVuIGl0IGlzIHRoZSB2YWx1ZSBvZiBhIGBjYWxsYmFja2AgLyBgcG9sbGAgLyBgc3RhcnRgIHByb3BlcnR5IG9mIHRoZSBvYmplY3RcbiAqIGxpdGVyYWwgcGFzc2VkIGFzIHRoZSBoZWxwZXIncyBmaXJzdCBhcmd1bWVudCBcdTIwMTQgd2hpY2ggY292ZXJzIGJvdGggdGhlIG1ldGhvZCBzaG9ydGhhbmRcbiAqIChgYXN5bmMgY2FsbGJhY2soeyBcdTIwMjYgfSkgeyBcdTIwMjYgfWApIGFuZCBhbiBhcnJvdyAoYGNhbGxiYWNrOiBhc3luYyAoeyBcdTIwMjYgfSkgPT4geyBcdTIwMjYgfWApLlxuICpcbiAqIEBwYXJhbSBub2RlIC0gVGhlIG5vZGUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyBUaGUgY2xvc3VyZSwgb3IgYG51bGxgIHdoZW4gdGhlIG5vZGUgaXMgbm90IGFuIGluLU9ic2lkaWFuIGNsb3N1cmUuXG4gKi9cbmZ1bmN0aW9uIHJlYWRFdmFsQ2xvc3VyZShub2RlOiBUU0VTVHJlZS5Ob2RlKTogRXZhbENsb3N1cmUgfCBudWxsIHtcbiAgaWYgKCFpc0Nsb3N1cmVGdW5jdGlvbihub2RlKSkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgY29uc3QgcHJvcGVydHlOb2RlID0gbm9kZS5wYXJlbnQ7XG4gIGlmICghaXNQcm9wZXJ0eShwcm9wZXJ0eU5vZGUpKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICAvKlxuICAgKiBUaGUgb2JqZWN0IGNoZWNrIGNvbWVzIEJFRk9SRSB0aGUga2V5IGNoZWNrIGJlY2F1c2UgYSBmdW5jdGlvbiBjYW4gcmVhY2ggYSBwcm9wZXJ0eSB0aHJvdWdoIGl0c1xuICAgKiBDT01QVVRFRCBLRVkgYXMgd2VsbCBhcyB0aHJvdWdoIGl0cyB2YWx1ZSAtLSBgeyBbKCkgPT4gJ2EnXTogMSB9YCBpcyBsZWdhbCAtLSBhbmQgYSBkZXN0cnVjdHVyaW5nXG4gICAqIHBhdHRlcm4gY2FuIGNhcnJ5IG9uZSB0b28uIE5laXRoZXIgaXMgYSBoZWxwZXIgY2FsbCdzIHBhcmFtZXRlciBvYmplY3QuXG4gICAqL1xuICBjb25zdCBwYXJhbXNOb2RlID0gcHJvcGVydHlOb2RlLnBhcmVudDtcbiAgaWYgKCFpc09iamVjdEV4cHJlc3Npb24ocGFyYW1zTm9kZSkgfHwgIWlzSWRlbnRpZmllcihwcm9wZXJ0eU5vZGUua2V5KSkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgY29uc3QgY2FsbE5vZGUgPSBwYXJhbXNOb2RlLnBhcmVudDtcbiAgaWYgKCFpc0NhbGxFeHByZXNzaW9uKGNhbGxOb2RlKSB8fCBjYWxsTm9kZS5hcmd1bWVudHNbMF0gIT09IHBhcmFtc05vZGUpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGNvbnN0IGNsb3N1cmVOYW1lcyA9IHJlYWRDbG9zdXJlTmFtZXMoY2FsbE5vZGUpO1xuICByZXR1cm4gY2xvc3VyZU5hbWVzPy5pbmNsdWRlcyhwcm9wZXJ0eU5vZGUua2V5Lm5hbWUpXG4gICAgPyB7XG4gICAgICBjbG9zdXJlTm9kZTogbm9kZSxcbiAgICAgIHBhcmFtc05vZGUsXG4gICAgICByZXBvcnROb2RlOiBwcm9wZXJ0eU5vZGVcbiAgICB9XG4gICAgOiBudWxsO1xufVxuXG4vKipcbiAqIFJlYWRzIHRoZSB2YWx1ZSBhIGNhbGwncyBvd24gYGlucHV0YCBvYmplY3Qgc3VwcGxpZXMgZm9yIG9uZSBrZXkuXG4gKlxuICogVGhpcyBpcyBob3cgYSBidWRnZXQgZGVjbGFyZWQgb25jZSBhdCB0aGUgY2FsbCBzaXRlIHJlYWNoZXMgdGhlIGNsb3N1cmUsIHdoaWNoIGNhbm5vdCBjbG9zZSBvdmVyXG4gKiBhbnl0aGluZzogYGlucHV0OiB7IHNldHRsZVRpbWVvdXRJbk1pbGxpc2Vjb25kczogU0VUVExFIH1gIGFycml2ZXMgZGVzdHJ1Y3R1cmVkIGluIHRoZSBjYWxsYmFjaydzXG4gKiBwYXJhbWV0ZXIgb2JqZWN0LlxuICpcbiAqIEBwYXJhbSBwYXJhbXNOb2RlIC0gVGhlIGhlbHBlcidzIHBhcmFtZXRlciBvYmplY3QuXG4gKiBAcGFyYW0ga2V5TmFtZSAtIFRoZSBgaW5wdXRgIHByb3BlcnR5IHRvIHJlYWQuXG4gKiBAcmV0dXJucyBUaGUgZXhwcmVzc2lvbiBzdXBwbHlpbmcgdGhhdCBrZXksIG9yIGBudWxsYCB3aGVuIHRoZSBjYWxsJ3MgYGlucHV0YCBkb2VzIG5vdCBkZWNsYXJlIGl0LlxuICovXG5mdW5jdGlvbiByZWFkSW5wdXRQcm9wZXJ0eVZhbHVlKHBhcmFtc05vZGU6IFRTRVNUcmVlLk9iamVjdEV4cHJlc3Npb24sIGtleU5hbWU6IHN0cmluZyk6IG51bGwgfCBUU0VTVHJlZS5Ob2RlIHtcbiAgY29uc3QgaW5wdXRQcm9wZXJ0eSA9IHBhcmFtc05vZGUucHJvcGVydGllcy5maW5kKChwcm9wZXJ0eSkgPT5cbiAgICBpc1Byb3BlcnR5KHByb3BlcnR5IGFzIFRTRVNUcmVlLk5vZGUpXG4gICAgJiYgaXNJZGVudGlmaWVyKChwcm9wZXJ0eSBhcyBUU0VTVHJlZS5Qcm9wZXJ0eSkua2V5IGFzIFRTRVNUcmVlLk5vZGUpXG4gICAgJiYgKChwcm9wZXJ0eSBhcyBUU0VTVHJlZS5Qcm9wZXJ0eSkua2V5IGFzIFRTRVNUcmVlLklkZW50aWZpZXIpLm5hbWUgPT09IElOUFVUX1BST1BFUlRZX05BTUVcbiAgKSBhcyBUU0VTVHJlZS5Qcm9wZXJ0eSB8IHVuZGVmaW5lZDtcblxuICBjb25zdCBpbnB1dE5vZGUgPSBpbnB1dFByb3BlcnR5Py52YWx1ZSBhcyBUU0VTVHJlZS5Ob2RlIHwgdW5kZWZpbmVkO1xuICBpZiAoIWlucHV0Tm9kZSB8fCAhaXNPYmplY3RFeHByZXNzaW9uKGlucHV0Tm9kZSkpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGNvbnN0IHZhbHVlUHJvcGVydHkgPSBpbnB1dE5vZGUucHJvcGVydGllcy5maW5kKChwcm9wZXJ0eSkgPT5cbiAgICBpc1Byb3BlcnR5KHByb3BlcnR5IGFzIFRTRVNUcmVlLk5vZGUpXG4gICAgJiYgaXNJZGVudGlmaWVyKChwcm9wZXJ0eSBhcyBUU0VTVHJlZS5Qcm9wZXJ0eSkua2V5IGFzIFRTRVNUcmVlLk5vZGUpXG4gICAgJiYgKChwcm9wZXJ0eSBhcyBUU0VTVHJlZS5Qcm9wZXJ0eSkua2V5IGFzIFRTRVNUcmVlLklkZW50aWZpZXIpLm5hbWUgPT09IGtleU5hbWVcbiAgKSBhcyBUU0VTVHJlZS5Qcm9wZXJ0eSB8IHVuZGVmaW5lZDtcblxuICByZXR1cm4gKHZhbHVlUHJvcGVydHk/LnZhbHVlIGFzIFRTRVNUcmVlLk5vZGUgfCB1bmRlZmluZWQpID8/IG51bGw7XG59XG5cbi8qKlxuICogUmVhZHMgdGhlIHdob2xlLWxvb3AgY2VpbGluZyBhIGNsb2NrIGRlYWRsaW5lIGRlY2xhcmVzLCBpbiBtaWxsaXNlY29uZHMuXG4gKlxuICogVGhlIGd1YXJkIGlzIGxvb2tlZCBmb3IgYW1vbmcgdGhlIHRlc3QncyBgJiZgIGNvbmp1bmN0cyByYXRoZXIgdGhhbiBhcyB0aGUgd2hvbGUgdGVzdCwgYmVjYXVzZSB0aGVcbiAqIGxvb3BzIHRoYXQgY2Fycnkgb25lIHBhaXIgaXQgd2l0aCBhIHByb2dyZXNzIGNvbmRpdGlvbiBcdTIwMTQgYHdoaWxlIChjb3VudCA8IGV4cGVjdGVkICYmIERhdGUubm93KCkgPCBkZWFkbGluZSlgXG4gKiBcdTIwMTQgYW5kIGEgY29tcG91bmQgdGVzdCBtdXN0IG5vdCByZW1vdmUgYSBjZWlsaW5nIG9uZSBvZiBpdHMgY29uanVuY3RzIHBsYWlubHkgZGVjbGFyZXMuXG4gKlxuICogQHBhcmFtIGxvb3BOb2RlIC0gVGhlIGxvb3AgdG8gaW5zcGVjdC5cbiAqIEBwYXJhbSBjbG9zdXJlIC0gVGhlIGluLU9ic2lkaWFuIGNsb3N1cmUgdGhlIGxvb3AgcnVucyBpbnNpZGUuXG4gKiBAcGFyYW0gY29udGV4dCAtIFRoZSBydWxlIGNvbnRleHQsIHVzZWQgdG8gcmVzb2x2ZSB0aGUgZGVhZGxpbmUgdGhyb3VnaCBzY29wZS5cbiAqIEByZXR1cm5zIFRoZSBjZWlsaW5nIGluIG1pbGxpc2Vjb25kcywgb3IgYG51bGxgIHdoZW4gdGhlIGxvb3AgZGVjbGFyZXMgbm9uZS5cbiAqL1xuZnVuY3Rpb24gcmVhZExvb3BEZWFkbGluZUluTWlsbGlzZWNvbmRzKGxvb3BOb2RlOiBMb29wU3RhdGVtZW50LCBjbG9zdXJlOiBFdmFsQ2xvc3VyZSwgY29udGV4dDogUnVsZS5SdWxlQ29udGV4dCk6IG51bGwgfCBudW1iZXIge1xuICBpZiAoIWxvb3BOb2RlLnRlc3QpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGZvciAoY29uc3QgY29uanVuY3Qgb2YgcmVhZENvbmp1bmN0cyhsb29wTm9kZS50ZXN0KSkge1xuICAgIGNvbnN0IGRlYWRsaW5lSW5NaWxsaXNlY29uZHMgPSByZWFkRGVhZGxpbmVHdWFyZEluTWlsbGlzZWNvbmRzKGNvbmp1bmN0LCBjbG9zdXJlLCBjb250ZXh0KTtcbiAgICBpZiAoZGVhZGxpbmVJbk1pbGxpc2Vjb25kcyAhPT0gbnVsbCkge1xuICAgICAgcmV0dXJuIGRlYWRsaW5lSW5NaWxsaXNlY29uZHM7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG51bGw7XG59XG5cbi8qKlxuICogUmVhZHMgdGhlIGZpcnN0IHZhbHVlIGEgbG9vcCdzIHRlc3Qgd2lsbCBub3QgbGV0IGl0cyBjb3VudGVyIHJlYWNoLlxuICpcbiAqIEFuIGluY2x1c2l2ZSBib3VuZCBhbnN3ZXJzIG9uZSBoaWdoZXIgdGhhbiBpdCBpcyB3cml0dGVuLCBzbyBhIGNhbGxlciB3b3JrcyBpbiBvbmUgY3VycmVuY3kgcmF0aGVyIHRoYW5cbiAqIGNhcnJ5aW5nIHRoZSBvcGVyYXRvciBhbG9uZyB3aXRoIHRoZSBudW1iZXIuIFRoZSB0ZXN0IGlzIHJlYWQgYXMgYCYmYCBjb25qdW5jdHMgZm9yIHRoZSBzYW1lIHJlYXNvbiBhXG4gKiBkZWFkbGluZSBndWFyZCBpczogYGF0dGVtcHQgPCBBVFRFTVBUUyAmJiAhaXNPcGVuYCBzdGlsbCBjYW5ub3QgcnVuIG1vcmUgdGhhbiBgQVRURU1QVFNgIHRpbWVzLlxuICpcbiAqIEBwYXJhbSB0ZXN0Tm9kZSAtIFRoZSBsb29wJ3MgdGVzdC5cbiAqIEBwYXJhbSBjb3VudGVyTmFtZSAtIFRoZSBuYW1lIG9mIHRoZSBjb3VudGVyIHRoZSBsb29wIGFkdmFuY2VzLlxuICogQHBhcmFtIGNsb3N1cmUgLSBUaGUgaW4tT2JzaWRpYW4gY2xvc3VyZSB0aGUgbG9vcCBydW5zIGluc2lkZS5cbiAqIEBwYXJhbSBjb250ZXh0IC0gVGhlIHJ1bGUgY29udGV4dCwgdXNlZCB0byByZXNvbHZlIHRoZSBib3VuZCB0aHJvdWdoIHNjb3BlLlxuICogQHJldHVybnMgVGhlIGV4Y2x1c2l2ZSBib3VuZCwgb3IgYG51bGxgIHdoZW4gbm8gY29uanVuY3QgYm91bmRzIHRoYXQgY291bnRlciBieSBhIHJlc29sdmFibGUgbnVtYmVyLlxuICovXG5mdW5jdGlvbiByZWFkTG9vcEV4Y2x1c2l2ZUJvdW5kKFxuICB0ZXN0Tm9kZTogVFNFU1RyZWUuRXhwcmVzc2lvbixcbiAgY291bnRlck5hbWU6IHN0cmluZyxcbiAgY2xvc3VyZTogRXZhbENsb3N1cmUsXG4gIGNvbnRleHQ6IFJ1bGUuUnVsZUNvbnRleHRcbik6IG51bGwgfCBudW1iZXIge1xuICBmb3IgKGNvbnN0IGNvbmp1bmN0IG9mIHJlYWRDb25qdW5jdHModGVzdE5vZGUpKSB7XG4gICAgaWYgKCFpc0JpbmFyeUV4cHJlc3Npb24oY29uanVuY3QpIHx8IChjb25qdW5jdC5vcGVyYXRvciAhPT0gJzwnICYmIGNvbmp1bmN0Lm9wZXJhdG9yICE9PSAnPD0nKSkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgY29uc3QgY291bnRlck5vZGUgPSBjb25qdW5jdC5sZWZ0IGFzIFRTRVNUcmVlLk5vZGU7XG4gICAgaWYgKCFpc0lkZW50aWZpZXIoY291bnRlck5vZGUpIHx8IGNvdW50ZXJOb2RlLm5hbWUgIT09IGNvdW50ZXJOYW1lKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBjb25zdCBib3VuZFZhbHVlID0gcmVzb2x2ZU51bWJlcihjb25qdW5jdC5yaWdodCwgY2xvc3VyZSwgY29udGV4dCk7XG4gICAgaWYgKGJvdW5kVmFsdWUgPT09IG51bGwpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIHJldHVybiBjb25qdW5jdC5vcGVyYXRvciA9PT0gJzwnID8gYm91bmRWYWx1ZSA6IGJvdW5kVmFsdWUgKyAxO1xuICB9XG5cbiAgcmV0dXJuIG51bGw7XG59XG5cbi8qKlxuICogUmVhZHMgaG93IG1hbnkgdGltZXMgYSBjb3VudGluZyBgZm9yYCBydW5zLlxuICpcbiAqIFRoZSBib3VuZCBpcyByZWFkIGZyb20gdGhlIHNhbWUgYCYmYCBjb25qdW5jdHMgYSBkZWFkbGluZSBpcywgZm9yIHRoZSBzYW1lIHJlYXNvbjpcbiAqIGBhdHRlbXB0IDwgQVRURU1QVFMgJiYgIWlzT3BlbmAgc3RpbGwgY2Fubm90IHJ1biBtb3JlIHRoYW4gYEFUVEVNUFRTYCB0aW1lcy4gVGhlIFNURVAgaXMgcmVhZCByYXRoZXJcbiAqIHRoYW4gcHJlc3VtZWQgdG8gYmUgb25lLCBvciBhIGBmb3IgKGxldCBlbGFwc2VkID0gMDsgZWxhcHNlZCA8IEJVREdFVDsgZWxhcHNlZCArPSBJTlRFUlZBTClgIHBvbGwgd291bGRcbiAqIGJlIGNvdW50ZWQgYEJVREdFVGAgdGltZXMuXG4gKlxuICogQHBhcmFtIGxvb3BOb2RlIC0gVGhlIGxvb3AgdG8gaW5zcGVjdC5cbiAqIEBwYXJhbSBjbG9zdXJlIC0gVGhlIGluLU9ic2lkaWFuIGNsb3N1cmUgdGhlIGxvb3AgcnVucyBpbnNpZGUuXG4gKiBAcGFyYW0gY29udGV4dCAtIFRoZSBydWxlIGNvbnRleHQsIHVzZWQgdG8gcmVzb2x2ZSB0aGUgc3RhcnQsIGJvdW5kIGFuZCBzdGVwIHRocm91Z2ggc2NvcGUuXG4gKiBAcmV0dXJucyBUaGUgaXRlcmF0aW9uIGNvdW50LCBvciBgbnVsbGAgd2hlbiBpdCBpcyBub3Qgc3RhdGljYWxseSBrbm93YWJsZS5cbiAqL1xuZnVuY3Rpb24gcmVhZExvb3BJdGVyYXRpb25Db3VudChsb29wTm9kZTogTG9vcFN0YXRlbWVudCwgY2xvc3VyZTogRXZhbENsb3N1cmUsIGNvbnRleHQ6IFJ1bGUuUnVsZUNvbnRleHQpOiBudWxsIHwgbnVtYmVyIHtcbiAgaWYgKCFpc0ZvclN0YXRlbWVudChsb29wTm9kZSkgfHwgIWxvb3BOb2RlLnRlc3QgfHwgIWxvb3BOb2RlLmluaXQgfHwgIWlzVmFyaWFibGVEZWNsYXJhdGlvbihsb29wTm9kZS5pbml0KSkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgY29uc3QgZGVjbGFyYXRvck5vZGVzID0gbG9vcE5vZGUuaW5pdC5kZWNsYXJhdGlvbnM7XG4gIGNvbnN0IGRlY2xhcmF0b3JOb2RlID0gZGVjbGFyYXRvck5vZGVzLmxlbmd0aCA9PT0gMSA/IGRlY2xhcmF0b3JOb2Rlc1swXSA6IHVuZGVmaW5lZDtcbiAgaWYgKCFkZWNsYXJhdG9yTm9kZT8uaW5pdCB8fCAhaXNJZGVudGlmaWVyKGRlY2xhcmF0b3JOb2RlLmlkKSkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgY29uc3Qgc3RhcnRWYWx1ZSA9IHJlc29sdmVOdW1iZXIoZGVjbGFyYXRvck5vZGUuaW5pdCwgY2xvc3VyZSwgY29udGV4dCk7XG4gIGNvbnN0IHN0ZXBTaXplID0gcmVhZExvb3BTdGVwU2l6ZShsb29wTm9kZS51cGRhdGUsIGRlY2xhcmF0b3JOb2RlLmlkLCBjbG9zdXJlLCBjb250ZXh0KTtcbiAgY29uc3QgYm91bmRWYWx1ZSA9IHJlYWRMb29wRXhjbHVzaXZlQm91bmQobG9vcE5vZGUudGVzdCwgZGVjbGFyYXRvck5vZGUuaWQubmFtZSwgY2xvc3VyZSwgY29udGV4dCk7XG4gIGlmIChzdGFydFZhbHVlID09PSBudWxsIHx8IHN0ZXBTaXplID09PSBudWxsIHx8IHN0ZXBTaXplIDw9IDAgfHwgYm91bmRWYWx1ZSA9PT0gbnVsbCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgY29uc3Qgc3BhbiA9IGJvdW5kVmFsdWUgLSBzdGFydFZhbHVlO1xuICByZXR1cm4gc3BhbiA+IDAgPyBNYXRoLmNlaWwoc3BhbiAvIHN0ZXBTaXplKSA6IDA7XG59XG5cbi8qKlxuICogUmVhZHMgaG93IG1hbnkgdGltZXMgc29tZXRoaW5nIHdyaXR0ZW4gYXQgYSBub2RlIGFjdHVhbGx5IHJ1bnMsIGFzIHRoZSBwcm9kdWN0IG9mIGl0cyBlbmNsb3NpbmcgbG9vcHMuXG4gKlxuICogQSBsb29wIHRoYXQgaXMgbm90IHN0YXRpY2FsbHkgY291bnRhYmxlIGNvbnRyaWJ1dGVzIGEgZmFjdG9yIG9mIE9ORSByYXRoZXIgdGhhbiBkaXNxdWFsaWZ5aW5nIHRoZSBzdW06XG4gKiB0aGF0IGlzIHRoZSBwZXItaXRlcmF0aW9uIGNoYXJnZSB0aGlzIHJ1bGUgaGFzIGFsd2F5cyBtYWRlLCBhbmQgaXQgaXMgd2hhdCBrZWVwcyBhbiB1bmJvdW5kZWRcbiAqIGB3aGlsZSAodHJ1ZSlgIHNpbGVudCBpbnN0ZWFkIG9mIGd1ZXNzZWQgYXQuIEEgREVBRExJTkUtYm91bmRlZCBsb29wIGNvbnRyaWJ1dGVzIG9uZSBhcyB3ZWxsLCBiZWNhdXNlXG4gKiBpdHMgd2hvbGUtbG9vcCBjZWlsaW5nIGlzIGNoYXJnZWQgc2VwYXJhdGVseSBhbmQgbXVsdGlwbHlpbmcgdG9vIHdvdWxkIGNvdW50IHRoZSBzYW1lIHdhaXRpbmcgdHdpY2UuXG4gKlxuICogVGhlIHdhbGsgc3RvcHMgYXQgdGhlIGZ1bmN0aW9uIHRoZSBub2RlIGlzIENIQVJHRUQgdG8sIG5vdCBhdCB0aGUgY2xvc3VyZSwgc28gdGhlIGxvb3BzIGFyb3VuZCBhIGhlbHBlcidzXG4gKiBvd24gd2FpdHMgYW5kIHRoZSBsb29wcyBhcm91bmQgZWFjaCBjYWxsIHRvIHRoYXQgaGVscGVyIGFyZSBjb3VudGVkIG9uY2UgZWFjaCByYXRoZXIgdGhhbiB0d2ljZS5cbiAqXG4gKiBAcGFyYW0gbm9kZSAtIFRoZSBub2RlIHRvIGNvdW50IHRoZSBydW5zIG9mLlxuICogQHBhcmFtIHRhcmdldCAtIFRoZSBmdW5jdGlvbiB0aGUgbm9kZSBpcyBjaGFyZ2VkIHRvLlxuICogQHBhcmFtIGNvbnRleHQgLSBUaGUgcnVsZSBjb250ZXh0LCB1c2VkIHRvIHJlc29sdmUgbG9vcCBib3VuZHMgdGhyb3VnaCBzY29wZS5cbiAqIEByZXR1cm5zIFRoZSBtdWx0aXBsaWVyLCBuZXZlciBsZXNzIHRoYW4gb25lLlxuICovXG5mdW5jdGlvbiByZWFkTG9vcE11bHRpcGxpZXIobm9kZTogVFNFU1RyZWUuTm9kZSwgdGFyZ2V0OiBDaGFyZ2VUYXJnZXQsIGNvbnRleHQ6IFJ1bGUuUnVsZUNvbnRleHQpOiBudW1iZXIge1xuICBjb25zdCBjbG9zdXJlID0gdGFyZ2V0LmNsb3N1cmU7XG4gIGxldCBtdWx0aXBsaWVyID0gMTtcbiAgbGV0IGN1cnJlbnROb2RlOiBUU0VTVHJlZS5Ob2RlIHwgdW5kZWZpbmVkID0gbm9kZS5wYXJlbnQ7XG5cbiAgd2hpbGUgKGN1cnJlbnROb2RlICYmIGN1cnJlbnROb2RlICE9PSB0YXJnZXQuZnVuY3Rpb25Ob2RlKSB7XG4gICAgaWYgKGlzTG9vcFN0YXRlbWVudChjdXJyZW50Tm9kZSkgJiYgcmVhZExvb3BEZWFkbGluZUluTWlsbGlzZWNvbmRzKGN1cnJlbnROb2RlLCBjbG9zdXJlLCBjb250ZXh0KSA9PT0gbnVsbCkge1xuICAgICAgY29uc3QgaXRlcmF0aW9uQ291bnQgPSByZWFkTG9vcEl0ZXJhdGlvbkNvdW50KGN1cnJlbnROb2RlLCBjbG9zdXJlLCBjb250ZXh0KTtcbiAgICAgIGlmIChpdGVyYXRpb25Db3VudCAhPT0gbnVsbCkge1xuICAgICAgICBtdWx0aXBsaWVyICo9IGl0ZXJhdGlvbkNvdW50O1xuICAgICAgfVxuICAgIH1cbiAgICBjdXJyZW50Tm9kZSA9IGN1cnJlbnROb2RlLnBhcmVudDtcbiAgfVxuXG4gIHJldHVybiBtdWx0aXBsaWVyO1xufVxuXG4vKipcbiAqIFJlYWRzIGhvdyBmYXIgYSBjb3VudGluZyBsb29wJ3MgdmFyaWFibGUgYWR2YW5jZXMgZWFjaCBpdGVyYXRpb24uXG4gKlxuICogQHBhcmFtIHVwZGF0ZU5vZGUgLSBUaGUgbG9vcCdzIHVwZGF0ZSBleHByZXNzaW9uLlxuICogQHBhcmFtIGNvdW50ZXJOb2RlIC0gVGhlIGlkZW50aWZpZXIgdGhlIGxvb3AgY291bnRzIG9uLlxuICogQHBhcmFtIGNsb3N1cmUgLSBUaGUgaW4tT2JzaWRpYW4gY2xvc3VyZSB0aGUgbG9vcCBydW5zIGluc2lkZS5cbiAqIEBwYXJhbSBjb250ZXh0IC0gVGhlIHJ1bGUgY29udGV4dCwgdXNlZCB0byByZXNvbHZlIGEgbm9uLWxpdGVyYWwgc3RlcCB0aHJvdWdoIHNjb3BlLlxuICogQHJldHVybnMgVGhlIHN0ZXAsIG9yIGBudWxsYCB3aGVuIHRoZSB1cGRhdGUgaXMgbm90IGEgcGxhaW4gYWR2YW5jZSBvZiB0aGUgbG9vcCdzIG93biBjb3VudGVyLlxuICovXG5mdW5jdGlvbiByZWFkTG9vcFN0ZXBTaXplKFxuICB1cGRhdGVOb2RlOiBudWxsIHwgVFNFU1RyZWUuRXhwcmVzc2lvbixcbiAgY291bnRlck5vZGU6IFRTRVNUcmVlLklkZW50aWZpZXIsXG4gIGNsb3N1cmU6IEV2YWxDbG9zdXJlLFxuICBjb250ZXh0OiBSdWxlLlJ1bGVDb250ZXh0XG4pOiBudWxsIHwgbnVtYmVyIHtcbiAgaWYgKCF1cGRhdGVOb2RlKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBpZiAoaXNVcGRhdGVFeHByZXNzaW9uKHVwZGF0ZU5vZGUpKSB7XG4gICAgY29uc3QgYXJndW1lbnROb2RlID0gdXBkYXRlTm9kZS5hcmd1bWVudCBhcyBUU0VTVHJlZS5Ob2RlO1xuICAgIHJldHVybiB1cGRhdGVOb2RlLm9wZXJhdG9yID09PSAnKysnICYmIGlzSWRlbnRpZmllcihhcmd1bWVudE5vZGUpICYmIGFyZ3VtZW50Tm9kZS5uYW1lID09PSBjb3VudGVyTm9kZS5uYW1lID8gMSA6IG51bGw7XG4gIH1cblxuICBpZiAoIWlzQXNzaWdubWVudEV4cHJlc3Npb24odXBkYXRlTm9kZSkgfHwgdXBkYXRlTm9kZS5vcGVyYXRvciAhPT0gJys9Jykge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgY29uc3QgdGFyZ2V0Tm9kZSA9IHVwZGF0ZU5vZGUubGVmdCBhcyBUU0VTVHJlZS5Ob2RlO1xuICByZXR1cm4gIWlzSWRlbnRpZmllcih0YXJnZXROb2RlKSB8fCB0YXJnZXROb2RlLm5hbWUgIT09IGNvdW50ZXJOb2RlLm5hbWUgPyBudWxsIDogcmVzb2x2ZU51bWJlcih1cGRhdGVOb2RlLnJpZ2h0LCBjbG9zdXJlLCBjb250ZXh0KTtcbn1cblxuLyoqXG4gKiBSZWFkcyB0aGUgYGlucHV0YCBrZXkgYSBkZXN0cnVjdHVyZWQgY2xvc3VyZSBwYXJhbWV0ZXIgaXMgYm91bmQgZnJvbS5cbiAqXG4gKiBUaGUgYmluZGluZyBtYXkgYmUgcmVuYW1lZCAoYHRpbWVvdXRJbk1pbGxpc2Vjb25kczogdGltZW91dGApLCBzbyB0aGUgS0VZIGlzIHdoYXQgdGhlIGNhbGwncyBgaW5wdXRgXG4gKiBpcyBsb29rZWQgdXAgYnksIG5ldmVyIHRoZSBsb2NhbCBuYW1lLlxuICpcbiAqIEBwYXJhbSBjbG9zdXJlTm9kZSAtIFRoZSBjbG9zdXJlIHdob3NlIHBhcmFtZXRlcnMgdG8gcmVhZC5cbiAqIEBwYXJhbSBsb2NhbE5hbWUgLSBUaGUgbmFtZSB0aGUgYnVkZ2V0IGlzIGJvdW5kIHRvIGluc2lkZSB0aGUgY2xvc3VyZS5cbiAqIEByZXR1cm5zIFRoZSBgaW5wdXRgIGtleSwgb3IgYG51bGxgIHdoZW4gdGhlIG5hbWUgaXMgbm90IGJvdW5kIGJ5IGEgcGxhaW4gZGVzdHJ1Y3R1cmVkIHByb3BlcnR5LlxuICovXG5mdW5jdGlvbiByZWFkUGFyYW1ldGVySW5wdXRLZXkoY2xvc3VyZU5vZGU6IENsb3N1cmVGdW5jdGlvbiwgbG9jYWxOYW1lOiBzdHJpbmcpOiBudWxsIHwgc3RyaW5nIHtcbiAgZm9yIChjb25zdCBwYXJhbWV0ZXJOb2RlIG9mIGNsb3N1cmVOb2RlLnBhcmFtcykge1xuICAgIGlmICghaXNPYmplY3RQYXR0ZXJuKHBhcmFtZXRlck5vZGUpKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IHByb3BlcnR5IG9mIHBhcmFtZXRlck5vZGUucHJvcGVydGllcykge1xuICAgICAgaWYgKCFpc1Byb3BlcnR5KHByb3BlcnR5KSB8fCBwcm9wZXJ0eS5jb21wdXRlZCB8fCAhaXNJZGVudGlmaWVyKHByb3BlcnR5LmtleSkgfHwgIWlzSWRlbnRpZmllcihwcm9wZXJ0eS52YWx1ZSkpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGlmIChwcm9wZXJ0eS52YWx1ZS5uYW1lID09PSBsb2NhbE5hbWUpIHtcbiAgICAgICAgcmV0dXJuIHByb3BlcnR5LmtleS5uYW1lO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBudWxsO1xufVxuXG4vKipcbiAqIFJlYWRzIHRoZSBleHByZXNzaW9uIGNhcnJ5aW5nIGEgd2FpdCBjYWxsJ3MgZGVjbGFyZWQgYnVkZ2V0LlxuICpcbiAqIEBwYXJhbSBjYWxsTm9kZSAtIFRoZSBjYWxsIGV4cHJlc3Npb24gdG8gaW5zcGVjdC5cbiAqIEByZXR1cm5zIFRoZSBleHByZXNzaW9uIHRvIHJlc29sdmU7IGBudWxsYCBmb3IgYSBgd2FpdFVudGlsYCB0aGF0IG9taXRzIGl0cyB0aW1lb3V0LCB3aGljaCB0YWtlcyB0aGVcbiAqIGhlbHBlcidzIGRlZmF1bHQ7IG9yIGB1bmRlZmluZWRgIHdoZW4gdGhlIGNhbGwgaXMgbm90IGEgd2FpdCBhdCBhbGwuXG4gKi9cbmZ1bmN0aW9uIHJlYWRXYWl0QnVkZ2V0RXhwcmVzc2lvbihjYWxsTm9kZTogVFNFU1RyZWUuQ2FsbEV4cHJlc3Npb24pOiBudWxsIHwgVFNFU1RyZWUuTm9kZSB8IHVuZGVmaW5lZCB7XG4gIGlmICghaXNJZGVudGlmaWVyKGNhbGxOb2RlLmNhbGxlZSkpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgY29uc3QgY2FsbGVlTmFtZSA9IGNhbGxOb2RlLmNhbGxlZS5uYW1lO1xuXG4gIGlmIChjYWxsZWVOYW1lID09PSBTTEVFUF9DQUxMRUVfTkFNRSkge1xuICAgIHJldHVybiAoY2FsbE5vZGUuYXJndW1lbnRzWzBdKSA/PyB1bmRlZmluZWQ7XG4gIH1cblxuICBpZiAoY2FsbGVlTmFtZSAhPT0gV0FJVF9VTlRJTF9DQUxMRUVfTkFNRSkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICBjb25zdCBwYXJhbXNOb2RlID0gY2FsbE5vZGUuYXJndW1lbnRzWzBdIGFzIFRTRVNUcmVlLk5vZGUgfCB1bmRlZmluZWQ7XG4gIGlmICghcGFyYW1zTm9kZSB8fCAhaXNPYmplY3RFeHByZXNzaW9uKHBhcmFtc05vZGUpKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIGNvbnN0IHRpbWVvdXRQcm9wZXJ0eSA9IHBhcmFtc05vZGUucHJvcGVydGllcy5maW5kKChwcm9wZXJ0eSkgPT5cbiAgICBpc1Byb3BlcnR5KHByb3BlcnR5IGFzIFRTRVNUcmVlLk5vZGUpXG4gICAgJiYgaXNJZGVudGlmaWVyKChwcm9wZXJ0eSBhcyBUU0VTVHJlZS5Qcm9wZXJ0eSkua2V5IGFzIFRTRVNUcmVlLk5vZGUpXG4gICAgJiYgKChwcm9wZXJ0eSBhcyBUU0VTVHJlZS5Qcm9wZXJ0eSkua2V5IGFzIFRTRVNUcmVlLklkZW50aWZpZXIpLm5hbWUgPT09IFRJTUVPVVRfUFJPUEVSVFlfTkFNRVxuICApIGFzIFRTRVNUcmVlLlByb3BlcnR5IHwgdW5kZWZpbmVkO1xuXG4gIHJldHVybiAodGltZW91dFByb3BlcnR5Py52YWx1ZSkgPz8gbnVsbDtcbn1cblxuLyoqXG4gKiBSZXNvbHZlcyBhbiBleHByZXNzaW9uIHRvIGEgbnVtYmVyLCB0aHJvdWdoIHNjb3BlLlxuICpcbiAqIEV2ZXJ5IG51bWJlciB0aGUgcnVsZSByZWFkcyBjb21lcyB0aHJvdWdoIGhlcmUgXHUyMDE0IGEgd2FpdCdzIGJ1ZGdldCwgYSBsb29wJ3MgZGVhZGxpbmUsIGFuZCBhIGNvdW50aW5nXG4gKiBsb29wJ3Mgc3RhcnQsIGJvdW5kIGFuZCBzdGVwIFx1MjAxNCB3aGljaCBpcyB3aHkgaXQgaXMgbmFtZWQgZm9yIHdoYXQgaXQgcmVzb2x2ZXMgcmF0aGVyIHRoYW4gZm9yXG4gKiBtaWxsaXNlY29uZHMuXG4gKlxuICogSGFuZGxlcyBhIG51bWVyaWMgbGl0ZXJhbCwgYSBsaXRlcmFsLW9ubHkgcHJvZHVjdCAoYDYwICogMTAwMGApLCBhbiBpZGVudGlmaWVyIGJvdW5kIHRvIGVpdGhlciBpbiBhbnlcbiAqIGVuY2xvc2luZyBzY29wZSwgYW5kIGEgZGVzdHJ1Y3R1cmVkIGNsb3N1cmUgcGFyYW1ldGVyIGZvbGxvd2VkIGJhY2sgdGhyb3VnaCB0aGUgY2FsbCdzIG93biBgaW5wdXRgLlxuICogQW55dGhpbmcgZWxzZSBpcyB1bnJlc29sdmFibGUgYW5kIGFuc3dlcnMgYG51bGxgLCB3aGljaCB0aGUgY2FsbGVyIHRyZWF0cyBhcyBjb250cmlidXRpbmcgbm90aGluZy5cbiAqXG4gKiBFYWNoIGlkZW50aWZpZXIgaXMgcmVzb2x2ZWQgZnJvbSBJVFMgT1dOIHNjb3BlIHJhdGhlciB0aGFuIGZyb20gdGhlIHdhaXQncywgc28gYSB2YWx1ZSBzdXBwbGllZCBieSB0aGVcbiAqIGNhbGwncyBgaW5wdXRgIHJlc29sdmVzIGF0IHRoZSBjYWxsIHNpdGUgXHUyMDE0IHdoZXJlIGl0IHdhcyB3cml0dGVuIFx1MjAxNCBhbmQgaXMgbm90IGNhcHR1cmVkIGJ5IGEgc2FtZS1uYW1lZFxuICogYmluZGluZyB0aGF0IGhhcHBlbnMgdG8gZXhpc3QgaW5zaWRlIHRoZSBjbG9zdXJlLlxuICpcbiAqIEBwYXJhbSBub2RlIC0gVGhlIGV4cHJlc3Npb24gdG8gcmVzb2x2ZS5cbiAqIEBwYXJhbSBjbG9zdXJlIC0gVGhlIGNsb3N1cmUgdGhlIGV4cHJlc3Npb24gd2FzIHdyaXR0ZW4gaW5zaWRlLlxuICogQHBhcmFtIGNvbnRleHQgLSBUaGUgcnVsZSBjb250ZXh0LCB1c2VkIHRvIHJlc29sdmUgaWRlbnRpZmllcnMgdGhyb3VnaCBzY29wZS5cbiAqIEByZXR1cm5zIFRoZSBudW1iZXIsIG9yIGBudWxsYCB3aGVuIGl0IGNhbm5vdCBiZSByZXNvbHZlZCBzdGF0aWNhbGx5LlxuICovXG5mdW5jdGlvbiByZXNvbHZlTnVtYmVyKG5vZGU6IFRTRVNUcmVlLk5vZGUsIGNsb3N1cmU6IEV2YWxDbG9zdXJlLCBjb250ZXh0OiBSdWxlLlJ1bGVDb250ZXh0KTogbnVsbCB8IG51bWJlciB7XG4gIGNvbnN0IHZpc2l0ZWROb2RlcyA9IG5ldyBTZXQ8VFNFU1RyZWUuTm9kZT4oKTtcbiAgbGV0IGN1cnJlbnROb2RlID0gbm9kZTtcblxuICB3aGlsZSAoIXZpc2l0ZWROb2Rlcy5oYXMoY3VycmVudE5vZGUpKSB7XG4gICAgdmlzaXRlZE5vZGVzLmFkZChjdXJyZW50Tm9kZSk7XG5cbiAgICBpZiAoaXNOdW1lcmljTGl0ZXJhbChjdXJyZW50Tm9kZSkpIHtcbiAgICAgIHJldHVybiBjdXJyZW50Tm9kZS52YWx1ZTtcbiAgICB9XG5cbiAgICBpZiAoaXNCaW5hcnlFeHByZXNzaW9uKGN1cnJlbnROb2RlKSAmJiBjdXJyZW50Tm9kZS5vcGVyYXRvciA9PT0gJyonKSB7XG4gICAgICBjb25zdCBsZWZ0VmFsdWUgPSByZXNvbHZlTnVtYmVyKGN1cnJlbnROb2RlLmxlZnQsIGNsb3N1cmUsIGNvbnRleHQpO1xuICAgICAgY29uc3QgcmlnaHRWYWx1ZSA9IHJlc29sdmVOdW1iZXIoY3VycmVudE5vZGUucmlnaHQsIGNsb3N1cmUsIGNvbnRleHQpO1xuXG4gICAgICByZXR1cm4gbGVmdFZhbHVlID09PSBudWxsIHx8IHJpZ2h0VmFsdWUgPT09IG51bGwgPyBudWxsIDogbGVmdFZhbHVlICogcmlnaHRWYWx1ZTtcbiAgICB9XG5cbiAgICBpZiAoIWlzSWRlbnRpZmllcihjdXJyZW50Tm9kZSkpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGNvbnN0IGJvdW5kTm9kZSA9IHJlYWRCb3VuZEV4cHJlc3Npb24oY3VycmVudE5vZGUsIGNsb3N1cmUsIGNvbnRleHQpO1xuICAgIGlmICghYm91bmROb2RlKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBjdXJyZW50Tm9kZSA9IGJvdW5kTm9kZTtcbiAgfVxuXG4gIHJldHVybiBudWxsO1xufVxuIl0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBOEhBLDRCQUErQjtBQUMvQiwwQ0FBaUQ7QUFFakQsa0NBR087QUFLQSxNQUFNLGFBQWE7QUFLMUIsTUFBTSw2Q0FBNkM7QUFFbkQsTUFBTSxzQkFBc0I7QUFDNUIsTUFBTSxvQkFBb0I7QUFDMUIsTUFBTSx3QkFBd0I7QUFDOUIsTUFBTSx5QkFBeUI7QUFNL0IsTUFBTSxxQkFBcUIsb0JBQUksSUFBSSxDQUFDLFFBQVEsYUFBYSxDQUFDO0FBRTFELE1BQU0sa0JBQWtCO0FBT3hCLE1BQU0sK0JBQStCLG9CQUFJLElBQStCO0FBQUEsRUFDdEUsQ0FBQyxrQkFBa0IsQ0FBQyxVQUFVLENBQUM7QUFBQSxFQUMvQixDQUFDLGtCQUFrQixDQUFDLFFBQVEsT0FBTyxDQUFDO0FBQ3RDLENBQUM7QUFtSE0sTUFBTSxnQ0FBaUQ7QUFBQSxFQUM1RCxPQUFPLFNBQVM7QUFDZCxVQUFNLFVBQVUsUUFBUSxRQUFRLENBQUM7QUFDakMsVUFBTSwyQkFBMkIsUUFBUSxT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