@dollhousemcp/mcp-server 1.4.4 → 1.5.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 (667) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/README.md +68 -7
  3. package/dist/auth/GitHubAuthManager.d.ts +93 -0
  4. package/dist/auth/GitHubAuthManager.d.ts.map +1 -0
  5. package/dist/auth/GitHubAuthManager.js +465 -0
  6. package/dist/generated/version.d.ts +2 -2
  7. package/dist/generated/version.js +3 -3
  8. package/dist/index.d.ts +23 -0
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/index.js +244 -5
  11. package/dist/security/tokenManager.d.ts +34 -0
  12. package/dist/security/tokenManager.d.ts.map +1 -1
  13. package/dist/security/tokenManager.js +199 -1
  14. package/dist/server/ServerSetup.d.ts.map +1 -1
  15. package/dist/server/ServerSetup.js +4 -1
  16. package/dist/server/tools/AuthTools.d.ts +10 -0
  17. package/dist/server/tools/AuthTools.d.ts.map +1 -0
  18. package/dist/server/tools/AuthTools.js +41 -0
  19. package/dist/server/types.d.ts +3 -0
  20. package/dist/server/types.d.ts.map +1 -1
  21. package/dist/server/types.js +1 -1
  22. package/package.json +1 -1
  23. package/dist/collection/MarketplaceBrowser.d.ts +0 -24
  24. package/dist/collection/MarketplaceBrowser.d.ts.map +0 -1
  25. package/dist/collection/MarketplaceBrowser.js +0 -115
  26. package/dist/collection/MarketplaceSearch.d.ts +0 -18
  27. package/dist/collection/MarketplaceSearch.d.ts.map +0 -1
  28. package/dist/collection/MarketplaceSearch.js +0 -48
  29. package/dist/collection/PersonaInstaller.d.ts +0 -26
  30. package/dist/collection/PersonaInstaller.d.ts.map +0 -1
  31. package/dist/collection/PersonaInstaller.js +0 -103
  32. package/dist/elements/ensembles/Ensemble.d.ts +0 -144
  33. package/dist/elements/ensembles/Ensemble.d.ts.map +0 -1
  34. package/dist/elements/ensembles/Ensemble.js +0 -860
  35. package/dist/elements/ensembles/EnsembleManager.d.ts +0 -85
  36. package/dist/elements/ensembles/EnsembleManager.d.ts.map +0 -1
  37. package/dist/elements/ensembles/EnsembleManager.js +0 -378
  38. package/dist/elements/ensembles/constants.d.ts +0 -73
  39. package/dist/elements/ensembles/constants.d.ts.map +0 -1
  40. package/dist/elements/ensembles/constants.js +0 -92
  41. package/dist/elements/ensembles/index.d.ts +0 -8
  42. package/dist/elements/ensembles/index.d.ts.map +0 -1
  43. package/dist/elements/ensembles/index.js +0 -8
  44. package/dist/elements/ensembles/types.d.ts +0 -92
  45. package/dist/elements/ensembles/types.d.ts.map +0 -1
  46. package/dist/elements/ensembles/types.js +0 -8
  47. package/dist/elements/memories/Memory.d.ts +0 -110
  48. package/dist/elements/memories/Memory.d.ts.map +0 -1
  49. package/dist/elements/memories/Memory.js +0 -470
  50. package/dist/elements/memories/MemoryManager.d.ts +0 -86
  51. package/dist/elements/memories/MemoryManager.d.ts.map +0 -1
  52. package/dist/elements/memories/MemoryManager.js +0 -435
  53. package/dist/elements/memories/constants.d.ts +0 -42
  54. package/dist/elements/memories/constants.d.ts.map +0 -1
  55. package/dist/elements/memories/constants.js +0 -49
  56. package/dist/elements/memories/index.d.ts +0 -6
  57. package/dist/elements/memories/index.d.ts.map +0 -1
  58. package/dist/elements/memories/index.js +0 -6
  59. package/dist/marketplace/GitHubClient.d.ts +0 -22
  60. package/dist/marketplace/GitHubClient.d.ts.map +0 -1
  61. package/dist/marketplace/GitHubClient.js +0 -112
  62. package/dist/marketplace/MarketplaceBrowser.d.ts +0 -24
  63. package/dist/marketplace/MarketplaceBrowser.d.ts.map +0 -1
  64. package/dist/marketplace/MarketplaceBrowser.js +0 -115
  65. package/dist/marketplace/MarketplaceSearch.d.ts +0 -18
  66. package/dist/marketplace/MarketplaceSearch.d.ts.map +0 -1
  67. package/dist/marketplace/MarketplaceSearch.js +0 -48
  68. package/dist/marketplace/PersonaDetails.d.ts +0 -22
  69. package/dist/marketplace/PersonaDetails.d.ts.map +0 -1
  70. package/dist/marketplace/PersonaDetails.js +0 -71
  71. package/dist/marketplace/PersonaInstaller.d.ts +0 -25
  72. package/dist/marketplace/PersonaInstaller.d.ts.map +0 -1
  73. package/dist/marketplace/PersonaInstaller.js +0 -100
  74. package/dist/marketplace/PersonaSubmitter.d.ts +0 -19
  75. package/dist/marketplace/PersonaSubmitter.d.ts.map +0 -1
  76. package/dist/marketplace/PersonaSubmitter.js +0 -57
  77. package/dist/marketplace/index.d.ts +0 -10
  78. package/dist/marketplace/index.d.ts.map +0 -1
  79. package/dist/marketplace/index.js +0 -10
  80. package/dist/server/tools/MarketplaceTools.d.ts +0 -10
  81. package/dist/server/tools/MarketplaceTools.d.ts.map +0 -1
  82. package/dist/server/tools/MarketplaceTools.js +0 -96
  83. package/dist/src/cache/APICache.d.ts +0 -23
  84. package/dist/src/cache/APICache.d.ts.map +0 -1
  85. package/dist/src/cache/APICache.js +0 -42
  86. package/dist/src/cache/index.d.ts +0 -5
  87. package/dist/src/cache/index.d.ts.map +0 -1
  88. package/dist/src/cache/index.js +0 -5
  89. package/dist/src/config/constants.d.ts +0 -25
  90. package/dist/src/config/constants.d.ts.map +0 -1
  91. package/dist/src/config/constants.js +0 -30
  92. package/dist/src/config/index.d.ts +0 -6
  93. package/dist/src/config/index.d.ts.map +0 -1
  94. package/dist/src/config/index.js +0 -6
  95. package/dist/src/config/indicator-config.d.ts +0 -107
  96. package/dist/src/config/indicator-config.d.ts.map +0 -1
  97. package/dist/src/config/indicator-config.js +0 -158
  98. package/dist/src/constants/defaultPersonas.d.ts +0 -10
  99. package/dist/src/constants/defaultPersonas.d.ts.map +0 -1
  100. package/dist/src/constants/defaultPersonas.js +0 -18
  101. package/dist/src/constants/limits.d.ts +0 -10
  102. package/dist/src/constants/limits.d.ts.map +0 -1
  103. package/dist/src/constants/limits.js +0 -13
  104. package/dist/src/errors/SecurityError.d.ts +0 -29
  105. package/dist/src/errors/SecurityError.d.ts.map +0 -1
  106. package/dist/src/errors/SecurityError.js +0 -47
  107. package/dist/src/errors/index.d.ts +0 -2
  108. package/dist/src/errors/index.d.ts.map +0 -1
  109. package/dist/src/errors/index.js +0 -2
  110. package/dist/src/index.barrel.d.ts +0 -21
  111. package/dist/src/index.barrel.d.ts.map +0 -1
  112. package/dist/src/index.barrel.js +0 -31
  113. package/dist/src/index.d.ts +0 -220
  114. package/dist/src/index.d.ts.map +0 -1
  115. package/dist/src/index.js +0 -1559
  116. package/dist/src/marketplace/GitHubClient.d.ts +0 -22
  117. package/dist/src/marketplace/GitHubClient.d.ts.map +0 -1
  118. package/dist/src/marketplace/GitHubClient.js +0 -112
  119. package/dist/src/marketplace/MarketplaceBrowser.d.ts +0 -21
  120. package/dist/src/marketplace/MarketplaceBrowser.d.ts.map +0 -1
  121. package/dist/src/marketplace/MarketplaceBrowser.js +0 -45
  122. package/dist/src/marketplace/MarketplaceSearch.d.ts +0 -18
  123. package/dist/src/marketplace/MarketplaceSearch.d.ts.map +0 -1
  124. package/dist/src/marketplace/MarketplaceSearch.js +0 -36
  125. package/dist/src/marketplace/PersonaDetails.d.ts +0 -22
  126. package/dist/src/marketplace/PersonaDetails.d.ts.map +0 -1
  127. package/dist/src/marketplace/PersonaDetails.js +0 -71
  128. package/dist/src/marketplace/PersonaInstaller.d.ts +0 -25
  129. package/dist/src/marketplace/PersonaInstaller.d.ts.map +0 -1
  130. package/dist/src/marketplace/PersonaInstaller.js +0 -100
  131. package/dist/src/marketplace/PersonaSubmitter.d.ts +0 -19
  132. package/dist/src/marketplace/PersonaSubmitter.d.ts.map +0 -1
  133. package/dist/src/marketplace/PersonaSubmitter.js +0 -57
  134. package/dist/src/marketplace/index.d.ts +0 -10
  135. package/dist/src/marketplace/index.d.ts.map +0 -1
  136. package/dist/src/marketplace/index.js +0 -10
  137. package/dist/src/persona/PersonaLoader.d.ts +0 -33
  138. package/dist/src/persona/PersonaLoader.d.ts.map +0 -1
  139. package/dist/src/persona/PersonaLoader.js +0 -139
  140. package/dist/src/persona/PersonaManager.d.ts +0 -112
  141. package/dist/src/persona/PersonaManager.d.ts.map +0 -1
  142. package/dist/src/persona/PersonaManager.js +0 -341
  143. package/dist/src/persona/PersonaValidator.d.ts +0 -33
  144. package/dist/src/persona/PersonaValidator.d.ts.map +0 -1
  145. package/dist/src/persona/PersonaValidator.js +0 -157
  146. package/dist/src/persona/export-import/PersonaExporter.d.ts +0 -43
  147. package/dist/src/persona/export-import/PersonaExporter.d.ts.map +0 -1
  148. package/dist/src/persona/export-import/PersonaExporter.js +0 -99
  149. package/dist/src/persona/export-import/PersonaImporter.d.ts +0 -65
  150. package/dist/src/persona/export-import/PersonaImporter.d.ts.map +0 -1
  151. package/dist/src/persona/export-import/PersonaImporter.js +0 -313
  152. package/dist/src/persona/export-import/PersonaSharer.d.ts +0 -60
  153. package/dist/src/persona/export-import/PersonaSharer.d.ts.map +0 -1
  154. package/dist/src/persona/export-import/PersonaSharer.js +0 -363
  155. package/dist/src/persona/export-import/index.d.ts +0 -10
  156. package/dist/src/persona/export-import/index.d.ts.map +0 -1
  157. package/dist/src/persona/export-import/index.js +0 -7
  158. package/dist/src/persona/index.d.ts +0 -7
  159. package/dist/src/persona/index.d.ts.map +0 -1
  160. package/dist/src/persona/index.js +0 -7
  161. package/dist/src/security/InputValidator.d.ts +0 -69
  162. package/dist/src/security/InputValidator.d.ts.map +0 -1
  163. package/dist/src/security/InputValidator.js +0 -381
  164. package/dist/src/security/commandValidator.d.ts +0 -7
  165. package/dist/src/security/commandValidator.d.ts.map +0 -1
  166. package/dist/src/security/commandValidator.js +0 -77
  167. package/dist/src/security/constants.d.ts +0 -21
  168. package/dist/src/security/constants.d.ts.map +0 -1
  169. package/dist/src/security/constants.js +0 -23
  170. package/dist/src/security/contentValidator.d.ts +0 -47
  171. package/dist/src/security/contentValidator.d.ts.map +0 -1
  172. package/dist/src/security/contentValidator.js +0 -188
  173. package/dist/src/security/fileLockManager.d.ts +0 -70
  174. package/dist/src/security/fileLockManager.d.ts.map +0 -1
  175. package/dist/src/security/fileLockManager.js +0 -187
  176. package/dist/src/security/index.d.ts +0 -12
  177. package/dist/src/security/index.d.ts.map +0 -1
  178. package/dist/src/security/index.js +0 -14
  179. package/dist/src/security/pathValidator.d.ts +0 -9
  180. package/dist/src/security/pathValidator.d.ts.map +0 -1
  181. package/dist/src/security/pathValidator.js +0 -97
  182. package/dist/src/security/secureYamlParser.d.ts +0 -46
  183. package/dist/src/security/secureYamlParser.d.ts.map +0 -1
  184. package/dist/src/security/secureYamlParser.js +0 -203
  185. package/dist/src/security/securityMonitor.d.ts +0 -58
  186. package/dist/src/security/securityMonitor.d.ts.map +0 -1
  187. package/dist/src/security/securityMonitor.js +0 -108
  188. package/dist/src/security/tokenManager.d.ts +0 -59
  189. package/dist/src/security/tokenManager.d.ts.map +0 -1
  190. package/dist/src/security/tokenManager.js +0 -216
  191. package/dist/src/security/yamlValidator.d.ts +0 -20
  192. package/dist/src/security/yamlValidator.d.ts.map +0 -1
  193. package/dist/src/security/yamlValidator.js +0 -138
  194. package/dist/src/server/ServerSetup.d.ts +0 -31
  195. package/dist/src/server/ServerSetup.d.ts.map +0 -1
  196. package/dist/src/server/ServerSetup.js +0 -79
  197. package/dist/src/server/index.d.ts +0 -7
  198. package/dist/src/server/index.d.ts.map +0 -1
  199. package/dist/src/server/index.js +0 -7
  200. package/dist/src/server/tools/ConfigTools.d.ts +0 -10
  201. package/dist/src/server/tools/ConfigTools.d.ts.map +0 -1
  202. package/dist/src/server/tools/ConfigTools.js +0 -63
  203. package/dist/src/server/tools/MarketplaceTools.d.ts +0 -10
  204. package/dist/src/server/tools/MarketplaceTools.d.ts.map +0 -1
  205. package/dist/src/server/tools/MarketplaceTools.js +0 -92
  206. package/dist/src/server/tools/PersonaTools.d.ts +0 -10
  207. package/dist/src/server/tools/PersonaTools.d.ts.map +0 -1
  208. package/dist/src/server/tools/PersonaTools.js +0 -257
  209. package/dist/src/server/tools/ToolRegistry.d.ts +0 -37
  210. package/dist/src/server/tools/ToolRegistry.d.ts.map +0 -1
  211. package/dist/src/server/tools/ToolRegistry.js +0 -40
  212. package/dist/src/server/tools/UpdateTools.d.ts +0 -10
  213. package/dist/src/server/tools/UpdateTools.d.ts.map +0 -1
  214. package/dist/src/server/tools/UpdateTools.js +0 -64
  215. package/dist/src/server/tools/UserTools.d.ts +0 -10
  216. package/dist/src/server/tools/UserTools.d.ts.map +0 -1
  217. package/dist/src/server/tools/UserTools.js +0 -51
  218. package/dist/src/server/tools/index.d.ts +0 -10
  219. package/dist/src/server/tools/index.d.ts.map +0 -1
  220. package/dist/src/server/tools/index.js +0 -10
  221. package/dist/src/server/types.d.ts +0 -34
  222. package/dist/src/server/types.d.ts.map +0 -1
  223. package/dist/src/server/types.js +0 -5
  224. package/dist/src/tools/debug.d.ts +0 -20
  225. package/dist/src/tools/debug.d.ts.map +0 -1
  226. package/dist/src/tools/debug.js +0 -37
  227. package/dist/src/types/cache.d.ts +0 -8
  228. package/dist/src/types/cache.d.ts.map +0 -1
  229. package/dist/src/types/cache.js +0 -5
  230. package/dist/src/types/index.d.ts +0 -8
  231. package/dist/src/types/index.d.ts.map +0 -1
  232. package/dist/src/types/index.js +0 -8
  233. package/dist/src/types/marketplace.d.ts +0 -23
  234. package/dist/src/types/marketplace.d.ts.map +0 -1
  235. package/dist/src/types/marketplace.js +0 -5
  236. package/dist/src/types/mcp.d.ts +0 -161
  237. package/dist/src/types/mcp.d.ts.map +0 -1
  238. package/dist/src/types/mcp.js +0 -75
  239. package/dist/src/types/persona.d.ts +0 -30
  240. package/dist/src/types/persona.d.ts.map +0 -1
  241. package/dist/src/types/persona.js +0 -5
  242. package/dist/src/update/BackupManager.d.ts +0 -46
  243. package/dist/src/update/BackupManager.d.ts.map +0 -1
  244. package/dist/src/update/BackupManager.js +0 -261
  245. package/dist/src/update/DependencyChecker.d.ts +0 -41
  246. package/dist/src/update/DependencyChecker.d.ts.map +0 -1
  247. package/dist/src/update/DependencyChecker.js +0 -132
  248. package/dist/src/update/RateLimiter.d.ts +0 -80
  249. package/dist/src/update/RateLimiter.d.ts.map +0 -1
  250. package/dist/src/update/RateLimiter.js +0 -172
  251. package/dist/src/update/SignatureVerifier.d.ts +0 -71
  252. package/dist/src/update/SignatureVerifier.d.ts.map +0 -1
  253. package/dist/src/update/SignatureVerifier.js +0 -214
  254. package/dist/src/update/UpdateChecker.d.ts +0 -127
  255. package/dist/src/update/UpdateChecker.d.ts.map +0 -1
  256. package/dist/src/update/UpdateChecker.js +0 -460
  257. package/dist/src/update/UpdateManager.d.ts +0 -41
  258. package/dist/src/update/UpdateManager.d.ts.map +0 -1
  259. package/dist/src/update/UpdateManager.js +0 -260
  260. package/dist/src/update/VersionManager.d.ts +0 -31
  261. package/dist/src/update/VersionManager.d.ts.map +0 -1
  262. package/dist/src/update/VersionManager.js +0 -134
  263. package/dist/src/update/index.d.ts +0 -9
  264. package/dist/src/update/index.d.ts.map +0 -1
  265. package/dist/src/update/index.js +0 -9
  266. package/dist/src/utils/filesystem.d.ts +0 -32
  267. package/dist/src/utils/filesystem.d.ts.map +0 -1
  268. package/dist/src/utils/filesystem.js +0 -73
  269. package/dist/src/utils/git.d.ts +0 -32
  270. package/dist/src/utils/git.d.ts.map +0 -1
  271. package/dist/src/utils/git.js +0 -65
  272. package/dist/src/utils/index.d.ts +0 -7
  273. package/dist/src/utils/index.d.ts.map +0 -1
  274. package/dist/src/utils/index.js +0 -7
  275. package/dist/src/utils/logger.d.ts +0 -45
  276. package/dist/src/utils/logger.d.ts.map +0 -1
  277. package/dist/src/utils/logger.js +0 -91
  278. package/dist/src/utils/version.d.ts +0 -25
  279. package/dist/src/utils/version.d.ts.map +0 -1
  280. package/dist/src/utils/version.js +0 -97
  281. package/dist/test/src/cache/APICache.d.ts +0 -23
  282. package/dist/test/src/cache/APICache.d.ts.map +0 -1
  283. package/dist/test/src/cache/APICache.js +0 -42
  284. package/dist/test/src/cache/index.d.ts +0 -5
  285. package/dist/test/src/cache/index.d.ts.map +0 -1
  286. package/dist/test/src/cache/index.js +0 -5
  287. package/dist/test/src/collection/CollectionBrowser.d.ts +0 -24
  288. package/dist/test/src/collection/CollectionBrowser.d.ts.map +0 -1
  289. package/dist/test/src/collection/CollectionBrowser.js +0 -115
  290. package/dist/test/src/collection/CollectionSearch.d.ts +0 -18
  291. package/dist/test/src/collection/CollectionSearch.d.ts.map +0 -1
  292. package/dist/test/src/collection/CollectionSearch.js +0 -48
  293. package/dist/test/src/collection/GitHubClient.d.ts +0 -22
  294. package/dist/test/src/collection/GitHubClient.d.ts.map +0 -1
  295. package/dist/test/src/collection/GitHubClient.js +0 -114
  296. package/dist/test/src/collection/PersonaDetails.d.ts +0 -22
  297. package/dist/test/src/collection/PersonaDetails.d.ts.map +0 -1
  298. package/dist/test/src/collection/PersonaDetails.js +0 -71
  299. package/dist/test/src/collection/PersonaInstaller.d.ts +0 -26
  300. package/dist/test/src/collection/PersonaInstaller.d.ts.map +0 -1
  301. package/dist/test/src/collection/PersonaInstaller.js +0 -103
  302. package/dist/test/src/collection/PersonaSubmitter.d.ts +0 -19
  303. package/dist/test/src/collection/PersonaSubmitter.d.ts.map +0 -1
  304. package/dist/test/src/collection/PersonaSubmitter.js +0 -57
  305. package/dist/test/src/collection/index.d.ts +0 -10
  306. package/dist/test/src/collection/index.d.ts.map +0 -1
  307. package/dist/test/src/collection/index.js +0 -10
  308. package/dist/test/src/config/constants.d.ts +0 -25
  309. package/dist/test/src/config/constants.d.ts.map +0 -1
  310. package/dist/test/src/config/constants.js +0 -30
  311. package/dist/test/src/config/index.d.ts +0 -6
  312. package/dist/test/src/config/index.d.ts.map +0 -1
  313. package/dist/test/src/config/index.js +0 -6
  314. package/dist/test/src/config/indicator-config.d.ts +0 -107
  315. package/dist/test/src/config/indicator-config.d.ts.map +0 -1
  316. package/dist/test/src/config/indicator-config.js +0 -158
  317. package/dist/test/src/constants/defaultPersonas.d.ts +0 -10
  318. package/dist/test/src/constants/defaultPersonas.d.ts.map +0 -1
  319. package/dist/test/src/constants/defaultPersonas.js +0 -18
  320. package/dist/test/src/constants/limits.d.ts +0 -10
  321. package/dist/test/src/constants/limits.d.ts.map +0 -1
  322. package/dist/test/src/constants/limits.js +0 -13
  323. package/dist/test/src/elements/BaseElement.d.ts +0 -81
  324. package/dist/test/src/elements/BaseElement.d.ts.map +0 -1
  325. package/dist/test/src/elements/BaseElement.js +0 -381
  326. package/dist/test/src/elements/FeedbackProcessor.d.ts +0 -57
  327. package/dist/test/src/elements/FeedbackProcessor.d.ts.map +0 -1
  328. package/dist/test/src/elements/FeedbackProcessor.js +0 -418
  329. package/dist/test/src/elements/agents/Agent.d.ts +0 -145
  330. package/dist/test/src/elements/agents/Agent.d.ts.map +0 -1
  331. package/dist/test/src/elements/agents/Agent.js +0 -848
  332. package/dist/test/src/elements/agents/AgentManager.d.ts +0 -125
  333. package/dist/test/src/elements/agents/AgentManager.d.ts.map +0 -1
  334. package/dist/test/src/elements/agents/AgentManager.js +0 -608
  335. package/dist/test/src/elements/agents/constants.d.ts +0 -42
  336. package/dist/test/src/elements/agents/constants.d.ts.map +0 -1
  337. package/dist/test/src/elements/agents/constants.js +0 -45
  338. package/dist/test/src/elements/agents/goalTemplates.d.ts +0 -44
  339. package/dist/test/src/elements/agents/goalTemplates.d.ts.map +0 -1
  340. package/dist/test/src/elements/agents/goalTemplates.js +0 -297
  341. package/dist/test/src/elements/agents/index.d.ts +0 -8
  342. package/dist/test/src/elements/agents/index.d.ts.map +0 -1
  343. package/dist/test/src/elements/agents/index.js +0 -8
  344. package/dist/test/src/elements/agents/ruleEngineConfig.d.ts +0 -76
  345. package/dist/test/src/elements/agents/ruleEngineConfig.d.ts.map +0 -1
  346. package/dist/test/src/elements/agents/ruleEngineConfig.js +0 -143
  347. package/dist/test/src/elements/agents/types.d.ts +0 -97
  348. package/dist/test/src/elements/agents/types.d.ts.map +0 -1
  349. package/dist/test/src/elements/agents/types.js +0 -5
  350. package/dist/test/src/elements/index.d.ts +0 -6
  351. package/dist/test/src/elements/index.d.ts.map +0 -1
  352. package/dist/test/src/elements/index.js +0 -6
  353. package/dist/test/src/elements/memories/Memory.d.ts +0 -110
  354. package/dist/test/src/elements/memories/Memory.d.ts.map +0 -1
  355. package/dist/test/src/elements/memories/Memory.js +0 -470
  356. package/dist/test/src/elements/memories/MemoryManager.d.ts +0 -86
  357. package/dist/test/src/elements/memories/MemoryManager.d.ts.map +0 -1
  358. package/dist/test/src/elements/memories/MemoryManager.js +0 -435
  359. package/dist/test/src/elements/memories/constants.d.ts +0 -42
  360. package/dist/test/src/elements/memories/constants.d.ts.map +0 -1
  361. package/dist/test/src/elements/memories/constants.js +0 -49
  362. package/dist/test/src/elements/memories/index.d.ts +0 -6
  363. package/dist/test/src/elements/memories/index.d.ts.map +0 -1
  364. package/dist/test/src/elements/memories/index.js +0 -6
  365. package/dist/test/src/elements/skills/Skill.d.ts +0 -109
  366. package/dist/test/src/elements/skills/Skill.d.ts.map +0 -1
  367. package/dist/test/src/elements/skills/Skill.js +0 -381
  368. package/dist/test/src/elements/templates/Template.d.ts +0 -138
  369. package/dist/test/src/elements/templates/Template.d.ts.map +0 -1
  370. package/dist/test/src/elements/templates/Template.js +0 -673
  371. package/dist/test/src/elements/templates/TemplateManager.d.ts +0 -104
  372. package/dist/test/src/elements/templates/TemplateManager.d.ts.map +0 -1
  373. package/dist/test/src/elements/templates/TemplateManager.js +0 -496
  374. package/dist/test/src/elements/templates/index.d.ts +0 -6
  375. package/dist/test/src/elements/templates/index.d.ts.map +0 -1
  376. package/dist/test/src/elements/templates/index.js +0 -6
  377. package/dist/test/src/errors/SecurityError.d.ts +0 -29
  378. package/dist/test/src/errors/SecurityError.d.ts.map +0 -1
  379. package/dist/test/src/errors/SecurityError.js +0 -47
  380. package/dist/test/src/errors/index.d.ts +0 -2
  381. package/dist/test/src/errors/index.d.ts.map +0 -1
  382. package/dist/test/src/errors/index.js +0 -2
  383. package/dist/test/src/index.barrel.d.ts +0 -21
  384. package/dist/test/src/index.barrel.d.ts.map +0 -1
  385. package/dist/test/src/index.barrel.js +0 -31
  386. package/dist/test/src/index.d.ts +0 -223
  387. package/dist/test/src/index.d.ts.map +0 -1
  388. package/dist/test/src/index.js +0 -1594
  389. package/dist/test/src/marketplace/GitHubClient.d.ts +0 -22
  390. package/dist/test/src/marketplace/GitHubClient.d.ts.map +0 -1
  391. package/dist/test/src/marketplace/GitHubClient.js +0 -112
  392. package/dist/test/src/marketplace/MarketplaceBrowser.d.ts +0 -21
  393. package/dist/test/src/marketplace/MarketplaceBrowser.d.ts.map +0 -1
  394. package/dist/test/src/marketplace/MarketplaceBrowser.js +0 -45
  395. package/dist/test/src/marketplace/MarketplaceSearch.d.ts +0 -18
  396. package/dist/test/src/marketplace/MarketplaceSearch.d.ts.map +0 -1
  397. package/dist/test/src/marketplace/MarketplaceSearch.js +0 -36
  398. package/dist/test/src/marketplace/PersonaDetails.d.ts +0 -22
  399. package/dist/test/src/marketplace/PersonaDetails.d.ts.map +0 -1
  400. package/dist/test/src/marketplace/PersonaDetails.js +0 -71
  401. package/dist/test/src/marketplace/PersonaInstaller.d.ts +0 -25
  402. package/dist/test/src/marketplace/PersonaInstaller.d.ts.map +0 -1
  403. package/dist/test/src/marketplace/PersonaInstaller.js +0 -100
  404. package/dist/test/src/marketplace/PersonaSubmitter.d.ts +0 -19
  405. package/dist/test/src/marketplace/PersonaSubmitter.d.ts.map +0 -1
  406. package/dist/test/src/marketplace/PersonaSubmitter.js +0 -57
  407. package/dist/test/src/marketplace/index.d.ts +0 -10
  408. package/dist/test/src/marketplace/index.d.ts.map +0 -1
  409. package/dist/test/src/marketplace/index.js +0 -10
  410. package/dist/test/src/persona/PersonaElement.d.ts +0 -64
  411. package/dist/test/src/persona/PersonaElement.d.ts.map +0 -1
  412. package/dist/test/src/persona/PersonaElement.js +0 -223
  413. package/dist/test/src/persona/PersonaElementManager.d.ts +0 -97
  414. package/dist/test/src/persona/PersonaElementManager.d.ts.map +0 -1
  415. package/dist/test/src/persona/PersonaElementManager.js +0 -342
  416. package/dist/test/src/persona/PersonaLoader.d.ts +0 -34
  417. package/dist/test/src/persona/PersonaLoader.d.ts.map +0 -1
  418. package/dist/test/src/persona/PersonaLoader.js +0 -145
  419. package/dist/test/src/persona/PersonaManager.d.ts +0 -112
  420. package/dist/test/src/persona/PersonaManager.d.ts.map +0 -1
  421. package/dist/test/src/persona/PersonaManager.js +0 -341
  422. package/dist/test/src/persona/PersonaValidator.d.ts +0 -33
  423. package/dist/test/src/persona/PersonaValidator.d.ts.map +0 -1
  424. package/dist/test/src/persona/PersonaValidator.js +0 -157
  425. package/dist/test/src/persona/export-import/PersonaExporter.d.ts +0 -43
  426. package/dist/test/src/persona/export-import/PersonaExporter.d.ts.map +0 -1
  427. package/dist/test/src/persona/export-import/PersonaExporter.js +0 -99
  428. package/dist/test/src/persona/export-import/PersonaImporter.d.ts +0 -65
  429. package/dist/test/src/persona/export-import/PersonaImporter.d.ts.map +0 -1
  430. package/dist/test/src/persona/export-import/PersonaImporter.js +0 -315
  431. package/dist/test/src/persona/export-import/PersonaSharer.d.ts +0 -60
  432. package/dist/test/src/persona/export-import/PersonaSharer.d.ts.map +0 -1
  433. package/dist/test/src/persona/export-import/PersonaSharer.js +0 -502
  434. package/dist/test/src/persona/export-import/index.d.ts +0 -10
  435. package/dist/test/src/persona/export-import/index.d.ts.map +0 -1
  436. package/dist/test/src/persona/export-import/index.js +0 -7
  437. package/dist/test/src/persona/index.d.ts +0 -7
  438. package/dist/test/src/persona/index.d.ts.map +0 -1
  439. package/dist/test/src/persona/index.js +0 -7
  440. package/dist/test/src/portfolio/MigrationManager.d.ts +0 -44
  441. package/dist/test/src/portfolio/MigrationManager.d.ts.map +0 -1
  442. package/dist/test/src/portfolio/MigrationManager.js +0 -163
  443. package/dist/test/src/portfolio/PortfolioManager.d.ts +0 -54
  444. package/dist/test/src/portfolio/PortfolioManager.d.ts.map +0 -1
  445. package/dist/test/src/portfolio/PortfolioManager.js +0 -224
  446. package/dist/test/src/portfolio/types.d.ts +0 -18
  447. package/dist/test/src/portfolio/types.d.ts.map +0 -1
  448. package/dist/test/src/portfolio/types.js +0 -13
  449. package/dist/test/src/security/InputValidator.d.ts +0 -80
  450. package/dist/test/src/security/InputValidator.d.ts.map +0 -1
  451. package/dist/test/src/security/InputValidator.js +0 -436
  452. package/dist/test/src/security/audit/SecurityAuditor.d.ts +0 -44
  453. package/dist/test/src/security/audit/SecurityAuditor.d.ts.map +0 -1
  454. package/dist/test/src/security/audit/SecurityAuditor.js +0 -274
  455. package/dist/test/src/security/audit/config/suppressions.d.ts +0 -34
  456. package/dist/test/src/security/audit/config/suppressions.d.ts.map +0 -1
  457. package/dist/test/src/security/audit/config/suppressions.js +0 -575
  458. package/dist/test/src/security/audit/index.d.ts +0 -14
  459. package/dist/test/src/security/audit/index.d.ts.map +0 -1
  460. package/dist/test/src/security/audit/index.js +0 -15
  461. package/dist/test/src/security/audit/reporters/ConsoleReporter.d.ts +0 -46
  462. package/dist/test/src/security/audit/reporters/ConsoleReporter.d.ts.map +0 -1
  463. package/dist/test/src/security/audit/reporters/ConsoleReporter.js +0 -174
  464. package/dist/test/src/security/audit/reporters/JsonReporter.d.ts +0 -13
  465. package/dist/test/src/security/audit/reporters/JsonReporter.d.ts.map +0 -1
  466. package/dist/test/src/security/audit/reporters/JsonReporter.js +0 -25
  467. package/dist/test/src/security/audit/reporters/MarkdownReporter.d.ts +0 -13
  468. package/dist/test/src/security/audit/reporters/MarkdownReporter.d.ts.map +0 -1
  469. package/dist/test/src/security/audit/reporters/MarkdownReporter.js +0 -79
  470. package/dist/test/src/security/audit/rules/SecurityRules.d.ts +0 -20
  471. package/dist/test/src/security/audit/rules/SecurityRules.d.ts.map +0 -1
  472. package/dist/test/src/security/audit/rules/SecurityRules.js +0 -244
  473. package/dist/test/src/security/audit/scanners/CodeScanner.d.ts +0 -47
  474. package/dist/test/src/security/audit/scanners/CodeScanner.d.ts.map +0 -1
  475. package/dist/test/src/security/audit/scanners/CodeScanner.js +0 -174
  476. package/dist/test/src/security/audit/scanners/ConfigurationScanner.d.ts +0 -13
  477. package/dist/test/src/security/audit/scanners/ConfigurationScanner.d.ts.map +0 -1
  478. package/dist/test/src/security/audit/scanners/ConfigurationScanner.js +0 -22
  479. package/dist/test/src/security/audit/scanners/DependencyScanner.d.ts +0 -13
  480. package/dist/test/src/security/audit/scanners/DependencyScanner.d.ts.map +0 -1
  481. package/dist/test/src/security/audit/scanners/DependencyScanner.js +0 -22
  482. package/dist/test/src/security/audit/types.d.ts +0 -94
  483. package/dist/test/src/security/audit/types.d.ts.map +0 -1
  484. package/dist/test/src/security/audit/types.js +0 -6
  485. package/dist/test/src/security/commandValidator.d.ts +0 -7
  486. package/dist/test/src/security/commandValidator.d.ts.map +0 -1
  487. package/dist/test/src/security/commandValidator.js +0 -78
  488. package/dist/test/src/security/constants.d.ts +0 -24
  489. package/dist/test/src/security/constants.d.ts.map +0 -1
  490. package/dist/test/src/security/constants.js +0 -26
  491. package/dist/test/src/security/contentValidator.d.ts +0 -47
  492. package/dist/test/src/security/contentValidator.d.ts.map +0 -1
  493. package/dist/test/src/security/contentValidator.js +0 -301
  494. package/dist/test/src/security/errors.d.ts +0 -14
  495. package/dist/test/src/security/errors.d.ts.map +0 -1
  496. package/dist/test/src/security/errors.js +0 -28
  497. package/dist/test/src/security/fileLockManager.d.ts +0 -70
  498. package/dist/test/src/security/fileLockManager.d.ts.map +0 -1
  499. package/dist/test/src/security/fileLockManager.js +0 -187
  500. package/dist/test/src/security/index.d.ts +0 -12
  501. package/dist/test/src/security/index.d.ts.map +0 -1
  502. package/dist/test/src/security/index.js +0 -14
  503. package/dist/test/src/security/pathValidator.d.ts +0 -9
  504. package/dist/test/src/security/pathValidator.d.ts.map +0 -1
  505. package/dist/test/src/security/pathValidator.js +0 -98
  506. package/dist/test/src/security/regexValidator.d.ts +0 -59
  507. package/dist/test/src/security/regexValidator.d.ts.map +0 -1
  508. package/dist/test/src/security/regexValidator.js +0 -214
  509. package/dist/test/src/security/secureYamlParser.d.ts +0 -46
  510. package/dist/test/src/security/secureYamlParser.d.ts.map +0 -1
  511. package/dist/test/src/security/secureYamlParser.js +0 -203
  512. package/dist/test/src/security/securityMonitor.d.ts +0 -58
  513. package/dist/test/src/security/securityMonitor.d.ts.map +0 -1
  514. package/dist/test/src/security/securityMonitor.js +0 -108
  515. package/dist/test/src/security/tokenManager.d.ts +0 -85
  516. package/dist/test/src/security/tokenManager.d.ts.map +0 -1
  517. package/dist/test/src/security/tokenManager.js +0 -286
  518. package/dist/test/src/security/validators/unicodeValidator.d.ts +0 -97
  519. package/dist/test/src/security/validators/unicodeValidator.d.ts.map +0 -1
  520. package/dist/test/src/security/validators/unicodeValidator.js +0 -312
  521. package/dist/test/src/security/yamlValidator.d.ts +0 -21
  522. package/dist/test/src/security/yamlValidator.d.ts.map +0 -1
  523. package/dist/test/src/security/yamlValidator.js +0 -164
  524. package/dist/test/src/server/ServerSetup.d.ts +0 -35
  525. package/dist/test/src/server/ServerSetup.d.ts.map +0 -1
  526. package/dist/test/src/server/ServerSetup.js +0 -116
  527. package/dist/test/src/server/index.d.ts +0 -7
  528. package/dist/test/src/server/index.d.ts.map +0 -1
  529. package/dist/test/src/server/index.js +0 -7
  530. package/dist/test/src/server/startup.d.ts +0 -31
  531. package/dist/test/src/server/startup.d.ts.map +0 -1
  532. package/dist/test/src/server/startup.js +0 -67
  533. package/dist/test/src/server/tools/CollectionTools.d.ts +0 -10
  534. package/dist/test/src/server/tools/CollectionTools.d.ts.map +0 -1
  535. package/dist/test/src/server/tools/CollectionTools.js +0 -96
  536. package/dist/test/src/server/tools/ConfigTools.d.ts +0 -10
  537. package/dist/test/src/server/tools/ConfigTools.d.ts.map +0 -1
  538. package/dist/test/src/server/tools/ConfigTools.js +0 -63
  539. package/dist/test/src/server/tools/MarketplaceTools.d.ts +0 -10
  540. package/dist/test/src/server/tools/MarketplaceTools.d.ts.map +0 -1
  541. package/dist/test/src/server/tools/MarketplaceTools.js +0 -92
  542. package/dist/test/src/server/tools/PersonaTools.d.ts +0 -10
  543. package/dist/test/src/server/tools/PersonaTools.d.ts.map +0 -1
  544. package/dist/test/src/server/tools/PersonaTools.js +0 -257
  545. package/dist/test/src/server/tools/ToolRegistry.d.ts +0 -37
  546. package/dist/test/src/server/tools/ToolRegistry.d.ts.map +0 -1
  547. package/dist/test/src/server/tools/ToolRegistry.js +0 -40
  548. package/dist/test/src/server/tools/UpdateTools.d.ts +0 -10
  549. package/dist/test/src/server/tools/UpdateTools.d.ts.map +0 -1
  550. package/dist/test/src/server/tools/UpdateTools.js +0 -64
  551. package/dist/test/src/server/tools/UserTools.d.ts +0 -10
  552. package/dist/test/src/server/tools/UserTools.d.ts.map +0 -1
  553. package/dist/test/src/server/tools/UserTools.js +0 -51
  554. package/dist/test/src/server/tools/index.d.ts +0 -10
  555. package/dist/test/src/server/tools/index.d.ts.map +0 -1
  556. package/dist/test/src/server/tools/index.js +0 -10
  557. package/dist/test/src/server/types.d.ts +0 -34
  558. package/dist/test/src/server/types.d.ts.map +0 -1
  559. package/dist/test/src/server/types.js +0 -5
  560. package/dist/test/src/tools/debug.d.ts +0 -20
  561. package/dist/test/src/tools/debug.d.ts.map +0 -1
  562. package/dist/test/src/tools/debug.js +0 -37
  563. package/dist/test/src/types/cache.d.ts +0 -8
  564. package/dist/test/src/types/cache.d.ts.map +0 -1
  565. package/dist/test/src/types/cache.js +0 -5
  566. package/dist/test/src/types/collection.d.ts +0 -23
  567. package/dist/test/src/types/collection.d.ts.map +0 -1
  568. package/dist/test/src/types/collection.js +0 -5
  569. package/dist/test/src/types/elements/IElement.d.ts +0 -123
  570. package/dist/test/src/types/elements/IElement.d.ts.map +0 -1
  571. package/dist/test/src/types/elements/IElement.js +0 -30
  572. package/dist/test/src/types/elements/IElementManager.d.ts +0 -65
  573. package/dist/test/src/types/elements/IElementManager.d.ts.map +0 -1
  574. package/dist/test/src/types/elements/IElementManager.js +0 -6
  575. package/dist/test/src/types/elements/IRatingManager.d.ts +0 -109
  576. package/dist/test/src/types/elements/IRatingManager.d.ts.map +0 -1
  577. package/dist/test/src/types/elements/IRatingManager.js +0 -6
  578. package/dist/test/src/types/elements/IReferenceResolver.d.ts +0 -52
  579. package/dist/test/src/types/elements/IReferenceResolver.d.ts.map +0 -1
  580. package/dist/test/src/types/elements/IReferenceResolver.js +0 -6
  581. package/dist/test/src/types/elements/RatingBreakdowns.d.ts +0 -49
  582. package/dist/test/src/types/elements/RatingBreakdowns.d.ts.map +0 -1
  583. package/dist/test/src/types/elements/RatingBreakdowns.js +0 -6
  584. package/dist/test/src/types/elements/index.d.ts +0 -9
  585. package/dist/test/src/types/elements/index.d.ts.map +0 -1
  586. package/dist/test/src/types/elements/index.js +0 -11
  587. package/dist/test/src/types/index.d.ts +0 -9
  588. package/dist/test/src/types/index.d.ts.map +0 -1
  589. package/dist/test/src/types/index.js +0 -9
  590. package/dist/test/src/types/marketplace.d.ts +0 -23
  591. package/dist/test/src/types/marketplace.d.ts.map +0 -1
  592. package/dist/test/src/types/marketplace.js +0 -5
  593. package/dist/test/src/types/mcp.d.ts +0 -84
  594. package/dist/test/src/types/mcp.d.ts.map +0 -1
  595. package/dist/test/src/types/mcp.js +0 -80
  596. package/dist/test/src/types/persona.d.ts +0 -30
  597. package/dist/test/src/types/persona.d.ts.map +0 -1
  598. package/dist/test/src/types/persona.js +0 -5
  599. package/dist/test/src/update/BackupManager.d.ts +0 -46
  600. package/dist/test/src/update/BackupManager.d.ts.map +0 -1
  601. package/dist/test/src/update/BackupManager.js +0 -261
  602. package/dist/test/src/update/DependencyChecker.d.ts +0 -41
  603. package/dist/test/src/update/DependencyChecker.d.ts.map +0 -1
  604. package/dist/test/src/update/DependencyChecker.js +0 -132
  605. package/dist/test/src/update/RateLimiter.d.ts +0 -80
  606. package/dist/test/src/update/RateLimiter.d.ts.map +0 -1
  607. package/dist/test/src/update/RateLimiter.js +0 -172
  608. package/dist/test/src/update/SignatureVerifier.d.ts +0 -71
  609. package/dist/test/src/update/SignatureVerifier.d.ts.map +0 -1
  610. package/dist/test/src/update/SignatureVerifier.js +0 -214
  611. package/dist/test/src/update/UpdateChecker.d.ts +0 -127
  612. package/dist/test/src/update/UpdateChecker.d.ts.map +0 -1
  613. package/dist/test/src/update/UpdateChecker.js +0 -469
  614. package/dist/test/src/update/UpdateManager.d.ts +0 -41
  615. package/dist/test/src/update/UpdateManager.d.ts.map +0 -1
  616. package/dist/test/src/update/UpdateManager.js +0 -260
  617. package/dist/test/src/update/VersionManager.d.ts +0 -31
  618. package/dist/test/src/update/VersionManager.d.ts.map +0 -1
  619. package/dist/test/src/update/VersionManager.js +0 -134
  620. package/dist/test/src/update/index.d.ts +0 -9
  621. package/dist/test/src/update/index.d.ts.map +0 -1
  622. package/dist/test/src/update/index.js +0 -9
  623. package/dist/test/src/utils/filesystem.d.ts +0 -29
  624. package/dist/test/src/utils/filesystem.d.ts.map +0 -1
  625. package/dist/test/src/utils/filesystem.js +0 -94
  626. package/dist/test/src/utils/git.d.ts +0 -32
  627. package/dist/test/src/utils/git.d.ts.map +0 -1
  628. package/dist/test/src/utils/git.js +0 -65
  629. package/dist/test/src/utils/index.d.ts +0 -7
  630. package/dist/test/src/utils/index.d.ts.map +0 -1
  631. package/dist/test/src/utils/index.js +0 -7
  632. package/dist/test/src/utils/logger.d.ts +0 -45
  633. package/dist/test/src/utils/logger.d.ts.map +0 -1
  634. package/dist/test/src/utils/logger.js +0 -91
  635. package/dist/test/src/utils/version.d.ts +0 -25
  636. package/dist/test/src/utils/version.d.ts.map +0 -1
  637. package/dist/test/src/utils/version.js +0 -97
  638. package/dist/test/test/__tests__/integration/helpers/file-utils.d.ts +0 -33
  639. package/dist/test/test/__tests__/integration/helpers/file-utils.d.ts.map +0 -1
  640. package/dist/test/test/__tests__/integration/helpers/file-utils.js +0 -83
  641. package/dist/test/test/__tests__/integration/helpers/test-fixtures.d.ts +0 -26
  642. package/dist/test/test/__tests__/integration/helpers/test-fixtures.d.ts.map +0 -1
  643. package/dist/test/test/__tests__/integration/helpers/test-fixtures.js +0 -95
  644. package/dist/test/test/__tests__/integration/helpers/test-server.d.ts +0 -26
  645. package/dist/test/test/__tests__/integration/helpers/test-server.d.ts.map +0 -1
  646. package/dist/test/test/__tests__/integration/helpers/test-server.js +0 -41
  647. package/dist/test/test/__tests__/integration/setup.d.ts +0 -8
  648. package/dist/test/test/__tests__/integration/setup.d.ts.map +0 -1
  649. package/dist/test/test/__tests__/integration/setup.js +0 -31
  650. package/dist/test/test/__tests__/integration/teardown.d.ts +0 -5
  651. package/dist/test/test/__tests__/integration/teardown.d.ts.map +0 -1
  652. package/dist/test/test/__tests__/integration/teardown.js +0 -23
  653. package/dist/test/test/__tests__/security/framework/RapidSecurityTesting.d.ts +0 -34
  654. package/dist/test/test/__tests__/security/framework/RapidSecurityTesting.d.ts.map +0 -1
  655. package/dist/test/test/__tests__/security/framework/RapidSecurityTesting.js +0 -224
  656. package/dist/test/test/__tests__/security/framework/SecurityTestFramework.d.ts +0 -89
  657. package/dist/test/test/__tests__/security/framework/SecurityTestFramework.d.ts.map +0 -1
  658. package/dist/test/test/__tests__/security/framework/SecurityTestFramework.js +0 -543
  659. package/dist/test/test/__tests__/security/index.d.ts +0 -46
  660. package/dist/test/test/__tests__/security/index.d.ts.map +0 -1
  661. package/dist/test/test/__tests__/security/index.js +0 -98
  662. package/dist/test/test/__tests__/security/setup.d.ts +0 -3
  663. package/dist/test/test/__tests__/security/setup.d.ts.map +0 -1
  664. package/dist/test/test/__tests__/security/setup.js +0 -23
  665. package/dist/types/marketplace.d.ts +0 -23
  666. package/dist/types/marketplace.d.ts.map +0 -1
  667. package/dist/types/marketplace.js +0 -5
@@ -1,848 +0,0 @@
1
- /**
2
- * Agent element implementation.
3
- * Autonomous goal-oriented actors with decision-making capabilities.
4
- *
5
- * SECURITY MEASURES IMPLEMENTED:
6
- * 1. Goal validation to prevent malicious objectives
7
- * 2. Decision framework sandboxing
8
- * 3. State size limits to prevent DoS
9
- * 4. Risk assessment for damage prevention
10
- * 5. Audit logging for all decisions and actions
11
- */
12
- import { BaseElement } from '../BaseElement.js';
13
- import { ElementType } from '../../portfolio/types.js';
14
- import { sanitizeInput } from '../../security/InputValidator.js';
15
- import { UnicodeValidator } from '../../security/validators/unicodeValidator.js';
16
- import { SecurityMonitor } from '../../security/securityMonitor.js';
17
- import { logger } from '../../utils/logger.js';
18
- import { AGENT_LIMITS, AGENT_DEFAULTS, DECISION_FRAMEWORKS, RISK_TOLERANCE_LEVELS } from './constants.js';
19
- import { validateRuleEngineConfig } from './ruleEngineConfig.js';
20
- import { applyGoalTemplate, recommendGoalTemplate, validateGoalAgainstTemplate } from './goalTemplates.js';
21
- export class Agent extends BaseElement {
22
- state;
23
- isDirtyState = false;
24
- ruleEngineConfig;
25
- constructor(metadata) {
26
- // Sanitize all inputs
27
- const sanitizedMetadata = {
28
- ...metadata,
29
- name: metadata.name ? sanitizeInput(UnicodeValidator.normalize(metadata.name).normalizedContent, 100) : undefined,
30
- description: metadata.description ? sanitizeInput(UnicodeValidator.normalize(metadata.description).normalizedContent, 500) : undefined,
31
- specializations: metadata.specializations?.map(s => sanitizeInput(s, 50)),
32
- decisionFramework: metadata.decisionFramework || AGENT_DEFAULTS.DECISION_FRAMEWORK,
33
- riskTolerance: metadata.riskTolerance || AGENT_DEFAULTS.RISK_TOLERANCE,
34
- learningEnabled: metadata.learningEnabled ?? AGENT_DEFAULTS.LEARNING_ENABLED,
35
- maxConcurrentGoals: metadata.maxConcurrentGoals ?? AGENT_DEFAULTS.MAX_CONCURRENT_GOALS
36
- };
37
- // MEDIUM PRIORITY IMPROVEMENT: Validate decision framework configuration
38
- // Ensures only supported frameworks are used
39
- if (sanitizedMetadata.decisionFramework &&
40
- !DECISION_FRAMEWORKS.includes(sanitizedMetadata.decisionFramework)) {
41
- throw new Error(`Invalid decision framework: ${sanitizedMetadata.decisionFramework}. ` +
42
- `Supported frameworks: ${DECISION_FRAMEWORKS.join(', ')}`);
43
- }
44
- // Validate risk tolerance level
45
- if (sanitizedMetadata.riskTolerance &&
46
- !RISK_TOLERANCE_LEVELS.includes(sanitizedMetadata.riskTolerance)) {
47
- throw new Error(`Invalid risk tolerance: ${sanitizedMetadata.riskTolerance}. ` +
48
- `Supported levels: ${RISK_TOLERANCE_LEVELS.join(', ')}`);
49
- }
50
- // Validate max concurrent goals
51
- if (sanitizedMetadata.maxConcurrentGoals !== undefined) {
52
- const maxGoals = sanitizedMetadata.maxConcurrentGoals;
53
- if (!Number.isInteger(maxGoals) || maxGoals < 1 || maxGoals > AGENT_LIMITS.MAX_GOALS) {
54
- throw new Error(`maxConcurrentGoals must be between 1 and ${AGENT_LIMITS.MAX_GOALS}`);
55
- }
56
- }
57
- super(ElementType.AGENT, sanitizedMetadata);
58
- // Initialize state
59
- this.state = {
60
- goals: [],
61
- decisions: [],
62
- context: {},
63
- lastActive: new Date(),
64
- sessionCount: 0
65
- };
66
- // Set agent-specific extensions
67
- this.extensions = {
68
- decisionFramework: sanitizedMetadata.decisionFramework,
69
- riskTolerance: sanitizedMetadata.riskTolerance,
70
- learningEnabled: sanitizedMetadata.learningEnabled,
71
- specializations: sanitizedMetadata.specializations || [],
72
- ruleEngineConfig: metadata.ruleEngineConfig
73
- };
74
- // Initialize rule engine configuration (with validation)
75
- this.ruleEngineConfig = validateRuleEngineConfig(this.extensions.ruleEngineConfig || {});
76
- }
77
- /**
78
- * Add a new goal with security validation
79
- */
80
- addGoal(goal) {
81
- // Validate goal count
82
- if (this.state.goals.length >= AGENT_LIMITS.MAX_GOALS) {
83
- throw new Error(`Maximum number of goals (${AGENT_LIMITS.MAX_GOALS}) reached`);
84
- }
85
- // Sanitize goal description
86
- const sanitizedDescription = sanitizeInput(UnicodeValidator.normalize(goal.description || '').normalizedContent, AGENT_LIMITS.MAX_GOAL_LENGTH);
87
- if (!sanitizedDescription || sanitizedDescription.length < 3) {
88
- throw new Error('Goal description must be at least 3 characters');
89
- }
90
- // Validate goal for security threats
91
- const securityCheck = this.validateGoalSecurity(sanitizedDescription);
92
- if (!securityCheck.safe) {
93
- SecurityMonitor.logSecurityEvent({
94
- type: 'CONTENT_INJECTION_ATTEMPT',
95
- severity: 'HIGH',
96
- source: 'Agent.addGoal',
97
- details: `Potentially malicious goal rejected: ${securityCheck.reason}`,
98
- additionalData: { agentId: this.id }
99
- });
100
- throw new Error(`Goal contains potentially harmful content: ${securityCheck.reason}`);
101
- }
102
- // Calculate Eisenhower quadrant
103
- const importance = goal.importance || 5;
104
- const urgency = goal.urgency || 5;
105
- const eisenhowerQuadrant = this.calculateEisenhowerQuadrant(importance, urgency);
106
- // Create new goal
107
- const newGoal = {
108
- id: `goal_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
109
- description: sanitizedDescription,
110
- priority: goal.priority || AGENT_DEFAULTS.GOAL_PRIORITY,
111
- status: 'pending',
112
- importance,
113
- urgency,
114
- eisenhowerQuadrant,
115
- createdAt: new Date(),
116
- updatedAt: new Date(),
117
- dependencies: goal.dependencies || [],
118
- riskLevel: goal.riskLevel || 'low',
119
- estimatedEffort: goal.estimatedEffort,
120
- notes: goal.notes ? sanitizeInput(goal.notes, 500) : undefined
121
- };
122
- // MEDIUM PRIORITY IMPROVEMENT: Detect dependency cycles before adding goal
123
- if (newGoal.dependencies && newGoal.dependencies.length > 0) {
124
- const cycleCheck = this.detectDependencyCycle(newGoal.id, newGoal.dependencies);
125
- if (cycleCheck.hasCycle) {
126
- throw new Error(`Dependency cycle detected: ${cycleCheck.path.join(' → ')}`);
127
- }
128
- }
129
- this.state.goals.push(newGoal);
130
- this.isDirtyState = true;
131
- this.markDirty();
132
- logger.info(`Goal added to agent ${this.metadata.name}`, { goalId: newGoal.id });
133
- return newGoal;
134
- }
135
- /**
136
- * Make a decision for a goal
137
- */
138
- async makeDecision(goalId, context) {
139
- // MEDIUM PRIORITY IMPROVEMENT: Track performance metrics for decision making
140
- const startTime = Date.now();
141
- const performanceMetrics = {};
142
- const goal = this.state.goals.find(g => g.id === goalId);
143
- if (!goal) {
144
- throw new Error(`Goal ${goalId} not found`);
145
- }
146
- if (goal.status === 'completed' || goal.status === 'cancelled') {
147
- throw new Error(`Cannot make decision for ${goal.status} goal`);
148
- }
149
- // Update goal status
150
- goal.status = 'in_progress';
151
- goal.updatedAt = new Date();
152
- // Prepare decision context
153
- const decisionContext = {
154
- ...this.state.context,
155
- ...context,
156
- goal,
157
- agentMetadata: this.metadata,
158
- previousDecisions: this.state.decisions.filter(d => d.goalId === goalId)
159
- };
160
- // Make decision based on framework (with timing)
161
- const frameworkStart = Date.now();
162
- const decision = await this.executeDecisionFramework(goal, decisionContext);
163
- performanceMetrics.frameworkTimeMs = Date.now() - frameworkStart;
164
- // Risk assessment (with timing)
165
- const riskStart = Date.now();
166
- const riskAssessment = this.assessRisk(decision, goal, decisionContext);
167
- performanceMetrics.riskAssessmentTimeMs = Date.now() - riskStart;
168
- // Calculate total decision time
169
- performanceMetrics.decisionTimeMs = Date.now() - startTime;
170
- // Create decision record
171
- const decisionRecord = {
172
- id: `decision_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
173
- goalId,
174
- timestamp: new Date(),
175
- decision: decision.action,
176
- reasoning: decision.reasoning,
177
- framework: this.extensions?.decisionFramework || AGENT_DEFAULTS.DECISION_FRAMEWORK,
178
- confidence: decision.confidence,
179
- riskAssessment,
180
- performanceMetrics // Add performance tracking
181
- };
182
- // OPTIMIZATION: Use efficient circular buffer pattern
183
- // Add to history with limit (avoid array slicing for better performance)
184
- if (this.state.decisions.length >= AGENT_LIMITS.MAX_DECISION_HISTORY) {
185
- // Remove oldest entry before adding new one (O(n) but happens infrequently)
186
- this.state.decisions.shift();
187
- }
188
- this.state.decisions.push(decisionRecord);
189
- this.isDirtyState = true;
190
- this.markDirty();
191
- // Log decision for audit
192
- SecurityMonitor.logSecurityEvent({
193
- type: 'AGENT_DECISION',
194
- severity: 'LOW',
195
- source: 'Agent.makeDecision',
196
- details: `Agent ${this.metadata.name} made decision for goal ${goalId}`,
197
- additionalData: {
198
- agentId: this.id,
199
- goalId,
200
- framework: decisionRecord.framework,
201
- riskLevel: riskAssessment.level
202
- }
203
- });
204
- return decisionRecord;
205
- }
206
- /**
207
- * Execute decision framework
208
- */
209
- async executeDecisionFramework(goal, context) {
210
- const framework = this.extensions?.decisionFramework || AGENT_DEFAULTS.DECISION_FRAMEWORK;
211
- switch (framework) {
212
- case 'rule_based':
213
- return this.ruleBasedDecision(goal, context);
214
- case 'ml_based':
215
- // Placeholder for ML-based decisions
216
- logger.warn('ML-based decisions not yet implemented, falling back to rule-based');
217
- return this.ruleBasedDecision(goal, context);
218
- case 'programmatic':
219
- return this.programmaticDecision(goal, context);
220
- case 'hybrid':
221
- // Combine multiple frameworks
222
- const ruleDecision = await this.ruleBasedDecision(goal, context);
223
- const progDecision = await this.programmaticDecision(goal, context);
224
- // Average confidence and combine reasoning
225
- return {
226
- action: ruleDecision.confidence > progDecision.confidence ? ruleDecision.action : progDecision.action,
227
- reasoning: `Rule-based: ${ruleDecision.reasoning}\nProgrammatic: ${progDecision.reasoning}`,
228
- confidence: (ruleDecision.confidence + progDecision.confidence) / 2
229
- };
230
- default:
231
- throw new Error(`Unknown decision framework: ${framework}`);
232
- }
233
- }
234
- /**
235
- * Rule-based decision making
236
- */
237
- async ruleBasedDecision(goal, context) {
238
- const rules = [
239
- // High priority + high urgency = immediate action
240
- {
241
- condition: (g) => g.priority === this.ruleEngineConfig.ruleBased.priority.critical &&
242
- g.urgency > this.ruleEngineConfig.ruleBased.urgencyThresholds.immediate,
243
- action: this.ruleEngineConfig.actions.executeImmediately,
244
- reasoning: 'Critical priority with high urgency requires immediate action',
245
- confidence: this.ruleEngineConfig.ruleBased.confidence.critical
246
- },
247
- // Blocked by dependencies
248
- {
249
- condition: (g, ctx) => {
250
- if (!g.dependencies || g.dependencies.length === 0)
251
- return false;
252
- const blockedDeps = g.dependencies.filter(depId => {
253
- const dep = this.state.goals.find(goal => goal.id === depId);
254
- return dep && dep.status !== 'completed';
255
- });
256
- return blockedDeps.length > 0;
257
- },
258
- action: this.ruleEngineConfig.actions.waitForDependencies,
259
- reasoning: 'Goal has incomplete dependencies',
260
- confidence: this.ruleEngineConfig.ruleBased.confidence.blocked
261
- },
262
- // Risk assessment
263
- {
264
- condition: (g) => g.riskLevel === 'high' && this.extensions?.riskTolerance === 'conservative',
265
- action: this.ruleEngineConfig.actions.requestApproval,
266
- reasoning: 'High risk goal requires approval in conservative mode',
267
- confidence: this.ruleEngineConfig.ruleBased.confidence.riskApproval
268
- },
269
- // Resource availability
270
- {
271
- condition: (g, ctx) => {
272
- const activeGoals = this.state.goals.filter(goal => goal.status === 'in_progress').length;
273
- const maxConcurrent = this.metadata.maxConcurrentGoals || AGENT_DEFAULTS.MAX_CONCURRENT_GOALS;
274
- return activeGoals >= maxConcurrent;
275
- },
276
- action: this.ruleEngineConfig.actions.queueForLater,
277
- reasoning: 'Maximum concurrent goals reached',
278
- confidence: this.ruleEngineConfig.ruleBased.confidence.resourceLimit
279
- },
280
- // Default action
281
- {
282
- condition: () => true,
283
- action: this.ruleEngineConfig.actions.proceedWithGoal,
284
- reasoning: 'No blocking conditions found',
285
- confidence: this.ruleEngineConfig.ruleBased.confidence.default
286
- }
287
- ];
288
- // Evaluate rules in order
289
- for (const rule of rules) {
290
- if (rule.condition(goal, context)) {
291
- return {
292
- action: rule.action,
293
- reasoning: rule.reasoning,
294
- confidence: rule.confidence
295
- };
296
- }
297
- }
298
- // Fallback (should not reach here)
299
- return {
300
- action: this.ruleEngineConfig.actions.reviewManually,
301
- reasoning: 'No applicable rules found',
302
- confidence: 0.5
303
- };
304
- }
305
- /**
306
- * Programmatic decision making
307
- */
308
- async programmaticDecision(goal, context) {
309
- // Calculate decision score based on multiple factors
310
- let score = 0;
311
- const factors = [];
312
- // Factor 1: Eisenhower matrix
313
- if (goal.eisenhowerQuadrant === 'do_first') {
314
- score += this.ruleEngineConfig.programmatic.scoreWeights.eisenhower.doFirst;
315
- factors.push('High importance and urgency (Do First quadrant)');
316
- }
317
- else if (goal.eisenhowerQuadrant === 'schedule') {
318
- score += this.ruleEngineConfig.programmatic.scoreWeights.eisenhower.schedule;
319
- factors.push('High importance, low urgency (Schedule quadrant)');
320
- }
321
- else if (goal.eisenhowerQuadrant === 'delegate') {
322
- score += this.ruleEngineConfig.programmatic.scoreWeights.eisenhower.delegate;
323
- factors.push('Low importance, high urgency (Delegate quadrant)');
324
- }
325
- // Factor 2: Risk level
326
- if (goal.riskLevel === 'low') {
327
- score += this.ruleEngineConfig.programmatic.scoreWeights.risk.low;
328
- factors.push('Low risk');
329
- }
330
- else if (goal.riskLevel === 'medium') {
331
- score += this.ruleEngineConfig.programmatic.scoreWeights.risk.medium;
332
- factors.push('Medium risk');
333
- }
334
- else {
335
- score += this.ruleEngineConfig.programmatic.scoreWeights.risk.high;
336
- factors.push('High risk penalty');
337
- }
338
- // Factor 3: Dependencies
339
- if (!goal.dependencies || goal.dependencies.length === 0) {
340
- score += this.ruleEngineConfig.programmatic.scoreWeights.noDependencies;
341
- factors.push('No dependencies');
342
- }
343
- // Factor 4: Estimated effort
344
- if (goal.estimatedEffort && goal.estimatedEffort <= this.ruleEngineConfig.programmatic.quickWinHours) {
345
- score += this.ruleEngineConfig.programmatic.scoreWeights.quickWin;
346
- factors.push(`Quick win (≤${this.ruleEngineConfig.programmatic.quickWinHours} hours)`);
347
- }
348
- // Factor 5: Previous success rate
349
- const previousDecisions = this.state.decisions.filter(d => d.outcome === 'success');
350
- const successRate = previousDecisions.length / Math.max(this.state.decisions.length, 1);
351
- if (successRate > this.ruleEngineConfig.programmatic.successRateThreshold) {
352
- score += this.ruleEngineConfig.programmatic.scoreWeights.successBonus;
353
- factors.push(`High success rate (${(successRate * 100).toFixed(0)}%)`);
354
- }
355
- // Determine action based on score
356
- let action;
357
- let confidence;
358
- if (score >= this.ruleEngineConfig.programmatic.actionThresholds.executeImmediately) {
359
- action = this.ruleEngineConfig.actions.executeImmediately;
360
- confidence = this.ruleEngineConfig.programmatic.confidenceLevels.executeImmediately;
361
- }
362
- else if (score >= this.ruleEngineConfig.programmatic.actionThresholds.proceed) {
363
- action = this.ruleEngineConfig.actions.proceedWithGoal;
364
- confidence = this.ruleEngineConfig.programmatic.confidenceLevels.proceed;
365
- }
366
- else if (score >= this.ruleEngineConfig.programmatic.actionThresholds.schedule) {
367
- action = this.ruleEngineConfig.actions.scheduleForLater;
368
- confidence = this.ruleEngineConfig.programmatic.confidenceLevels.schedule;
369
- }
370
- else {
371
- action = this.ruleEngineConfig.actions.reviewAndRevise;
372
- confidence = this.ruleEngineConfig.programmatic.confidenceLevels.review;
373
- }
374
- return {
375
- action,
376
- reasoning: `Score: ${score}. Factors: ${factors.join(', ')}`,
377
- confidence
378
- };
379
- }
380
- /**
381
- * Assess risk for a decision
382
- */
383
- assessRisk(decision, goal, context) {
384
- const factors = [];
385
- let riskScore = 0;
386
- // Check for immediate execution with high risk
387
- if (decision.action === 'execute_immediately' && goal.riskLevel === 'high') {
388
- factors.push('Immediate execution of high-risk goal');
389
- riskScore += 30;
390
- }
391
- // Check for low confidence decisions
392
- if (decision.confidence < 0.6) {
393
- factors.push('Low decision confidence');
394
- riskScore += 20;
395
- }
396
- // Check for complex dependencies
397
- if (goal.dependencies && goal.dependencies.length > 3) {
398
- factors.push('Complex dependency chain');
399
- riskScore += 15;
400
- }
401
- // Check for aggressive risk tolerance with high-risk goal
402
- if (this.extensions?.riskTolerance === 'aggressive' && goal.riskLevel === 'high') {
403
- factors.push('Aggressive risk tolerance with high-risk goal');
404
- riskScore += 25;
405
- }
406
- // Determine risk level
407
- let level;
408
- const mitigations = [];
409
- if (riskScore >= 50) {
410
- level = 'high';
411
- mitigations.push('Request human approval');
412
- mitigations.push('Create backup plan');
413
- mitigations.push('Monitor closely');
414
- }
415
- else if (riskScore >= 25) {
416
- level = 'medium';
417
- mitigations.push('Add checkpoints');
418
- mitigations.push('Review after completion');
419
- }
420
- else {
421
- level = 'low';
422
- mitigations.push('Standard monitoring');
423
- }
424
- return {
425
- level,
426
- factors,
427
- mitigations: mitigations.length > 0 ? mitigations : undefined
428
- };
429
- }
430
- /**
431
- * Calculate Eisenhower quadrant
432
- */
433
- calculateEisenhowerQuadrant(importance, urgency) {
434
- if (importance >= 7 && urgency >= 7) {
435
- return 'do_first';
436
- }
437
- else if (importance >= 7 && urgency < 7) {
438
- return 'schedule';
439
- }
440
- else if (importance < 7 && urgency >= 7) {
441
- return 'delegate';
442
- }
443
- else {
444
- return 'eliminate';
445
- }
446
- }
447
- /**
448
- * Validate goal for security threats
449
- */
450
- validateGoalSecurity(goal) {
451
- // Check for command injection patterns
452
- const dangerousPatterns = [
453
- /system\s*\(/i,
454
- /exec\s*\(/i,
455
- /eval\s*\(/i,
456
- /require\s*\(/i,
457
- /import\s*\(/i,
458
- /\$\{.*\}/,
459
- /`.*`/,
460
- /process\.\w+/i,
461
- /child_process/i
462
- ];
463
- for (const pattern of dangerousPatterns) {
464
- if (pattern.test(goal)) {
465
- return { safe: false, reason: 'Contains potentially dangerous code patterns' };
466
- }
467
- }
468
- // Check for social engineering attempts
469
- const socialEngineeringPatterns = [
470
- /password|credential|secret|token|key/i,
471
- /hack|exploit|breach|attack/i,
472
- /delete\s+all|destroy|wipe|erase\s+everything/i,
473
- /steal|theft|rob/i
474
- ];
475
- for (const pattern of socialEngineeringPatterns) {
476
- if (pattern.test(goal)) {
477
- return { safe: false, reason: 'Contains potentially harmful intent' };
478
- }
479
- }
480
- return { safe: true };
481
- }
482
- /**
483
- * Get agent state
484
- */
485
- getState() {
486
- return { ...this.state };
487
- }
488
- /**
489
- * Update agent context
490
- */
491
- updateContext(key, value) {
492
- const sanitizedKey = sanitizeInput(key, 50);
493
- // Validate context size
494
- const contextStr = JSON.stringify({ ...this.state.context, [sanitizedKey]: value });
495
- if (contextStr.length > AGENT_LIMITS.MAX_CONTEXT_LENGTH) {
496
- throw new Error(`Context size exceeds maximum of ${AGENT_LIMITS.MAX_CONTEXT_LENGTH} characters`);
497
- }
498
- this.state.context[sanitizedKey] = value;
499
- this.isDirtyState = true;
500
- this.markDirty();
501
- }
502
- /**
503
- * Complete a goal
504
- */
505
- completeGoal(goalId, outcome = 'success') {
506
- const goal = this.state.goals.find(g => g.id === goalId);
507
- if (!goal) {
508
- throw new Error(`Goal ${goalId} not found`);
509
- }
510
- goal.status = outcome === 'success' ? 'completed' : 'failed';
511
- goal.completedAt = new Date();
512
- goal.updatedAt = new Date();
513
- // Update actual effort if it was being tracked
514
- if (goal.estimatedEffort && goal.createdAt) {
515
- const hoursElapsed = (goal.completedAt.getTime() - goal.createdAt.getTime()) / (1000 * 60 * 60);
516
- goal.actualEffort = Math.round(hoursElapsed * 10) / 10;
517
- }
518
- // Update decision outcomes
519
- const decisions = this.state.decisions.filter(d => d.goalId === goalId);
520
- decisions.forEach(d => {
521
- if (!d.outcome) {
522
- d.outcome = outcome;
523
- }
524
- });
525
- this.isDirtyState = true;
526
- this.markDirty();
527
- logger.info(`Goal ${goalId} completed with outcome: ${outcome}`);
528
- }
529
- /**
530
- * Detect dependency cycles in goal dependencies
531
- * MEDIUM PRIORITY IMPROVEMENT: Prevents circular dependencies between goals
532
- */
533
- detectDependencyCycle(newGoalId, dependencies) {
534
- // Build dependency graph including the new goal
535
- const visited = new Set();
536
- const recursionStack = new Set();
537
- const path = [];
538
- // Helper function to perform DFS
539
- const hasCycleDFS = (goalId) => {
540
- visited.add(goalId);
541
- recursionStack.add(goalId);
542
- path.push(goalId);
543
- // Get dependencies for current goal
544
- let deps = [];
545
- if (goalId === newGoalId) {
546
- // For the new goal being added, use provided dependencies
547
- deps = dependencies;
548
- }
549
- else {
550
- // For existing goals, get from state
551
- const goal = this.state.goals.find(g => g.id === goalId);
552
- deps = goal?.dependencies || [];
553
- }
554
- // Check each dependency
555
- for (const depId of deps) {
556
- if (!visited.has(depId)) {
557
- if (hasCycleDFS(depId)) {
558
- return true;
559
- }
560
- }
561
- else if (recursionStack.has(depId)) {
562
- // Found a cycle - add the repeated node to show the cycle
563
- path.push(depId);
564
- return true;
565
- }
566
- }
567
- recursionStack.delete(goalId);
568
- // Only pop from path if we're not returning a cycle
569
- if (!deps.some(depId => recursionStack.has(depId))) {
570
- path.pop();
571
- }
572
- return false;
573
- };
574
- // Check if adding this goal would create a cycle
575
- const hasCycle = hasCycleDFS(newGoalId);
576
- return {
577
- hasCycle,
578
- path: hasCycle ? path : []
579
- };
580
- }
581
- /**
582
- * Get goals by status
583
- */
584
- getGoalsByStatus(status) {
585
- return this.state.goals.filter(g => g.status === status);
586
- }
587
- /**
588
- * Get goals by quadrant
589
- */
590
- getGoalsByQuadrant(quadrant) {
591
- return this.state.goals.filter(g => g.eisenhowerQuadrant === quadrant);
592
- }
593
- /**
594
- * Calculate agent performance metrics
595
- * MEDIUM PRIORITY IMPROVEMENT: Enhanced to include decision timing metrics
596
- */
597
- getPerformanceMetrics() {
598
- const completedGoals = this.state.goals.filter(g => g.status === 'completed');
599
- const failedGoals = this.state.goals.filter(g => g.status === 'failed');
600
- const inProgressGoals = this.state.goals.filter(g => g.status === 'in_progress');
601
- const totalCompleted = completedGoals.length + failedGoals.length;
602
- const successRate = totalCompleted > 0 ? completedGoals.length / totalCompleted : 0;
603
- // Calculate average completion time
604
- let totalTime = 0;
605
- let timeCount = 0;
606
- completedGoals.forEach(goal => {
607
- if (goal.completedAt && goal.createdAt) {
608
- totalTime += goal.completedAt.getTime() - goal.createdAt.getTime();
609
- timeCount++;
610
- }
611
- });
612
- const averageCompletionTime = timeCount > 0 ? totalTime / timeCount / (1000 * 60 * 60) : 0; // in hours
613
- // Calculate decision accuracy
614
- const decisionsWithOutcome = this.state.decisions.filter(d => d.outcome);
615
- const successfulDecisions = decisionsWithOutcome.filter(d => d.outcome === 'success');
616
- const decisionAccuracy = decisionsWithOutcome.length > 0
617
- ? successfulDecisions.length / decisionsWithOutcome.length
618
- : 0;
619
- // Calculate average decision timing metrics
620
- const decisionsWithMetrics = this.state.decisions.filter(d => d.performanceMetrics);
621
- let avgDecisionTime = 0;
622
- let avgFrameworkTime = 0;
623
- let avgRiskTime = 0;
624
- if (decisionsWithMetrics.length > 0) {
625
- const totalDecisionTime = decisionsWithMetrics.reduce((sum, d) => sum + (d.performanceMetrics?.decisionTimeMs || 0), 0);
626
- const totalFrameworkTime = decisionsWithMetrics.reduce((sum, d) => sum + (d.performanceMetrics?.frameworkTimeMs || 0), 0);
627
- const totalRiskTime = decisionsWithMetrics.reduce((sum, d) => sum + (d.performanceMetrics?.riskAssessmentTimeMs || 0), 0);
628
- avgDecisionTime = totalDecisionTime / decisionsWithMetrics.length;
629
- avgFrameworkTime = totalFrameworkTime / decisionsWithMetrics.length;
630
- avgRiskTime = totalRiskTime / decisionsWithMetrics.length;
631
- }
632
- return {
633
- successRate,
634
- averageCompletionTime,
635
- goalsCompleted: completedGoals.length,
636
- goalsInProgress: inProgressGoals.length,
637
- decisionAccuracy,
638
- averageDecisionTimeMs: decisionsWithMetrics.length > 0 ? avgDecisionTime : undefined,
639
- averageFrameworkTimeMs: decisionsWithMetrics.length > 0 ? avgFrameworkTime : undefined,
640
- averageRiskAssessmentTimeMs: decisionsWithMetrics.length > 0 ? avgRiskTime : undefined
641
- };
642
- }
643
- /**
644
- * Validate the agent
645
- */
646
- validate() {
647
- const result = super.validate();
648
- const errors = result.errors || [];
649
- const warnings = result.warnings || [];
650
- const suggestions = result.suggestions || [];
651
- // Validate decision framework
652
- if (this.extensions?.decisionFramework && !DECISION_FRAMEWORKS.includes(this.extensions.decisionFramework)) {
653
- errors.push({
654
- field: 'extensions.decisionFramework',
655
- message: `Invalid decision framework. Must be one of: ${DECISION_FRAMEWORKS.join(', ')}`
656
- });
657
- }
658
- // Validate risk tolerance
659
- if (this.extensions?.riskTolerance && !RISK_TOLERANCE_LEVELS.includes(this.extensions.riskTolerance)) {
660
- errors.push({
661
- field: 'extensions.riskTolerance',
662
- message: `Invalid risk tolerance. Must be one of: ${RISK_TOLERANCE_LEVELS.join(', ')}`
663
- });
664
- }
665
- // Validate state size
666
- const stateSize = JSON.stringify(this.state).length;
667
- if (stateSize > AGENT_LIMITS.MAX_STATE_SIZE) {
668
- errors.push({
669
- field: 'state',
670
- message: `State size (${stateSize} bytes) exceeds maximum of ${AGENT_LIMITS.MAX_STATE_SIZE} bytes`
671
- });
672
- }
673
- // Check for orphaned dependencies
674
- const allGoalIds = new Set(this.state.goals.map(g => g.id));
675
- this.state.goals.forEach(goal => {
676
- if (goal.dependencies) {
677
- goal.dependencies.forEach(depId => {
678
- if (!allGoalIds.has(depId)) {
679
- warnings.push({
680
- field: `goal.${goal.id}.dependencies`,
681
- message: `Dependency ${depId} not found`,
682
- severity: 'medium'
683
- });
684
- }
685
- });
686
- }
687
- });
688
- // Suggestions
689
- if (this.state.goals.length === 0) {
690
- suggestions.push('Add some goals to make the agent functional');
691
- }
692
- if (!this.extensions?.specializations || this.extensions.specializations.length === 0) {
693
- suggestions.push('Consider adding specializations to improve agent focus');
694
- }
695
- const metrics = this.getPerformanceMetrics();
696
- if (metrics.successRate < 0.5 && metrics.goalsCompleted > 5) {
697
- suggestions.push('Low success rate detected. Consider reviewing goal difficulty or decision framework');
698
- }
699
- return {
700
- valid: errors.length === 0,
701
- errors: errors.length > 0 ? errors : undefined,
702
- warnings: warnings.length > 0 ? warnings : undefined,
703
- suggestions: suggestions.length > 0 ? suggestions : undefined
704
- };
705
- }
706
- /**
707
- * Serialize agent including state
708
- */
709
- serialize() {
710
- const data = {
711
- ...JSON.parse(super.serialize()),
712
- state: this.state
713
- };
714
- return JSON.stringify(data, null, 2);
715
- }
716
- /**
717
- * Deserialize agent including state
718
- */
719
- deserialize(data) {
720
- const validationResult = UnicodeValidator.normalize(data);
721
- const parsed = JSON.parse(validationResult.normalizedContent);
722
- // Deserialize base properties
723
- super.deserialize(JSON.stringify({
724
- id: parsed.id,
725
- type: parsed.type,
726
- version: parsed.version,
727
- metadata: parsed.metadata,
728
- references: parsed.references,
729
- extensions: parsed.extensions,
730
- ratings: parsed.ratings
731
- }));
732
- // Deserialize state with validation
733
- if (parsed.state) {
734
- // Validate state size
735
- const stateStr = JSON.stringify(parsed.state);
736
- if (stateStr.length > AGENT_LIMITS.MAX_STATE_SIZE) {
737
- throw new Error(`State size exceeds maximum of ${AGENT_LIMITS.MAX_STATE_SIZE} bytes`);
738
- }
739
- // Restore dates
740
- if (parsed.state.goals) {
741
- parsed.state.goals.forEach((goal) => {
742
- goal.createdAt = new Date(goal.createdAt);
743
- goal.updatedAt = new Date(goal.updatedAt);
744
- if (goal.completedAt) {
745
- goal.completedAt = new Date(goal.completedAt);
746
- }
747
- });
748
- }
749
- if (parsed.state.decisions) {
750
- parsed.state.decisions.forEach((decision) => {
751
- decision.timestamp = new Date(decision.timestamp);
752
- });
753
- }
754
- if (parsed.state.lastActive) {
755
- parsed.state.lastActive = new Date(parsed.state.lastActive);
756
- }
757
- this.state = parsed.state;
758
- }
759
- this.isDirtyState = false;
760
- }
761
- /**
762
- * Agent activation
763
- */
764
- async activate() {
765
- await super.activate();
766
- // Update session tracking
767
- this.state.sessionCount++;
768
- this.state.lastActive = new Date();
769
- this.isDirtyState = true;
770
- // Log activation
771
- logger.info(`Agent ${this.metadata.name} activated`, {
772
- sessionCount: this.state.sessionCount,
773
- activeGoals: this.getGoalsByStatus('in_progress').length
774
- });
775
- }
776
- /**
777
- * Agent deactivation
778
- */
779
- async deactivate() {
780
- // Save any pending state
781
- if (this.isDirtyState) {
782
- logger.debug(`Agent ${this.metadata.name} has unsaved state changes`);
783
- }
784
- await super.deactivate();
785
- }
786
- /**
787
- * Check if agent needs state persistence
788
- */
789
- needsStatePersistence() {
790
- return this.isDirtyState;
791
- }
792
- /**
793
- * Mark state as persisted
794
- */
795
- markStatePersisted() {
796
- this.isDirtyState = false;
797
- }
798
- /**
799
- * Create a goal from a template
800
- * LOW PRIORITY IMPROVEMENT: Goal template system for common patterns
801
- */
802
- addGoalFromTemplate(templateId, customFields) {
803
- // Apply template to get goal data
804
- const goalData = applyGoalTemplate(templateId, customFields);
805
- // Create goal using the template data
806
- return this.addGoal(goalData);
807
- }
808
- /**
809
- * Get template recommendations based on goal description
810
- */
811
- getGoalTemplateRecommendations(description) {
812
- return recommendGoalTemplate(description);
813
- }
814
- /**
815
- * Validate a goal against its template
816
- */
817
- validateGoalTemplate(goalId) {
818
- const goal = this.state.goals.find(g => g.id === goalId);
819
- if (!goal) {
820
- return { valid: false, errors: ['Goal not found'] };
821
- }
822
- // If goal was created from template, validate against it
823
- const templateId = goal.templateId;
824
- return validateGoalAgainstTemplate(goal, templateId);
825
- }
826
- /**
827
- * Update rule engine configuration
828
- */
829
- updateRuleEngineConfig(config) {
830
- this.ruleEngineConfig = validateRuleEngineConfig({
831
- ...this.ruleEngineConfig,
832
- ...config
833
- });
834
- // Update extensions
835
- this.extensions = {
836
- ...this.extensions,
837
- ruleEngineConfig: this.ruleEngineConfig
838
- };
839
- this.markDirty();
840
- }
841
- /**
842
- * Get current rule engine configuration
843
- */
844
- getRuleEngineConfig() {
845
- return { ...this.ruleEngineConfig };
846
- }
847
- }
848
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQWdlbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvZWxlbWVudHMvYWdlbnRzL0FnZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7O0dBVUc7QUFFSCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFFaEQsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ3ZELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQztBQUNqRSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSwrQ0FBK0MsQ0FBQztBQUNqRixPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFDcEUsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBTy9DLE9BQU8sRUFDTCxZQUFZLEVBQ1osY0FBYyxFQUNkLG1CQUFtQixFQUNuQixxQkFBcUIsRUFDdEIsTUFBTSxnQkFBZ0IsQ0FBQztBQUN4QixPQUFPLEVBR0wsd0JBQXdCLEVBQ3pCLE1BQU0sdUJBQXVCLENBQUM7QUFDL0IsT0FBTyxFQUNMLGlCQUFpQixFQUNqQixxQkFBcUIsRUFDckIsMkJBQTJCLEVBQzVCLE1BQU0sb0JBQW9CLENBQUM7QUFFNUIsTUFBTSxPQUFPLEtBQU0sU0FBUSxXQUFXO0lBQzVCLEtBQUssQ0FBYTtJQUNsQixZQUFZLEdBQVksS0FBSyxDQUFDO0lBQzlCLGdCQUFnQixDQUFtQjtJQUUzQyxZQUFZLFFBQWdDO1FBQzFDLHNCQUFzQjtRQUN0QixNQUFNLGlCQUFpQixHQUEyQjtZQUNoRCxHQUFHLFFBQVE7WUFDWCxJQUFJLEVBQUUsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsYUFBYSxDQUFDLGdCQUFnQixDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsaUJBQWlCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxD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LENBQUMsZ0JBQWdCLEdBQUcsd0JBQXdCLENBQUM7WUFDL0MsR0FBRyxJQUFJLENBQUMsZ0JBQWdCO1lBQ3hCLEdBQUcsTUFBTTtTQUNWLENBQUMsQ0FBQztRQUVILG9CQUFvQjtRQUNwQixJQUFJLENBQUMsVUFBVSxHQUFHO1lBQ2hCLEdBQUcsSUFBSSxDQUFDLFVBQVU7WUFDbEIsZ0JBQWdCLEVBQUUsSUFBSSxDQUFDLGdCQUFnQjtTQUN4QyxDQUFDO1FBRUYsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO0lBQ25CLENBQUM7SUFFRDs7T0FFRztJQUNJLG1CQUFtQjtRQUN4QixPQUFPLEVBQUUsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztJQUN0QyxDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEFnZW50IGVsZW1lbnQgaW1wbGVtZW50YXRpb24uXG4gKiBBdXRvbm9tb3VzIGdvYWwtb3JpZW50ZWQgYWN0b3JzIHdpdGggZGVjaXNpb24tbWFraW5nIGNhcGFiaWxpdGllcy5cbiAqIFxuICogU0VDVVJJVFkgTUVBU1VSRVMgSU1QTEVNRU5URUQ6XG4gKiAxLiBHb2FsIHZhbGlkYXRpb24gdG8gcHJldmVudCBtYWxpY2lvdXMgb2JqZWN0aXZlc1xuICogMi4gRGVjaXNpb24gZnJhbWV3b3JrIHNhbmRib3hpbmdcbiAqIDMuIFN0YXRlIHNpemUgbGltaXRzIHRvIHByZXZlbnQgRG9TXG4gKiA0LiBSaXNrIGFzc2Vzc21lbnQgZm9yIGRhbWFnZSBwcmV2ZW50aW9uXG4gKiA1LiBBdWRpdCBsb2dnaW5nIGZvciBhbGwgZGVjaXNpb25zIGFuZCBhY3Rpb25zXG4gKi9cblxuaW1wb3J0IHsgQmFzZUVsZW1lbnQgfSBmcm9tICcuLi9CYXNlRWxlbWVudC5qcyc7XG5pbXBvcnQgeyBJRWxlbWVudCwgRWxlbWVudFZhbGlkYXRpb25SZXN1bHQsIFZhbGlkYXRpb25FcnJvciwgVmFsaWRhdGlvbldhcm5pbmcsIEVsZW1lbnRTdGF0dXMgfSBmcm9tICcuLi8uLi90eXBlcy9lbGVtZW50cy9pbmRleC5qcyc7XG5pbXBvcnQgeyBFbGVtZW50VHlwZSB9IGZyb20gJy4uLy4uL3BvcnRmb2xpby90eXBlcy5qcyc7XG5pbXBvcnQgeyBzYW5pdGl6ZUlucHV0IH0gZnJvbSAnLi4vLi4vc2VjdXJpdHkvSW5wdXRWYWxpZGF0b3IuanMnO1xuaW1wb3J0IHsgVW5pY29kZVZhbGlkYXRvciB9IGZyb20gJy4uLy4uL3NlY3VyaXR5L3ZhbGlkYXRvcnMvdW5pY29kZVZhbGlkYXRvci5qcyc7XG5pbXBvcnQgeyBTZWN1cml0eU1vbml0b3IgfSBmcm9tICcuLi8uLi9zZWN1cml0eS9zZWN1cml0eU1vbml0b3IuanMnO1xuaW1wb3J0IHsgbG9nZ2VyIH0gZnJvbSAnLi4vLi4vdXRpbHMvbG9nZ2VyLmpzJztcbmltcG9ydCB7IFxuICBBZ2VudEdvYWwsIFxuICBBZ2VudERlY2lzaW9uLCBcbiAgQWdlbnRTdGF0ZSwgXG4gIEFnZW50TWV0YWRhdGEgXG59IGZyb20gJy4vdHlwZXMuanMnO1xuaW1wb3J0IHsgXG4gIEFHRU5UX0xJTUlUUywgXG4gIEFHRU5UX0RFRkFVTFRTLFxuICBERUNJU0lPTl9GUkFNRVdPUktTLFxuICBSSVNLX1RPTEVSQU5DRV9MRVZFTFNcbn0gZnJvbSAnLi9jb25zdGFudHMuanMnO1xuaW1wb3J0IHsgXG4gIFJ1bGVFbmdpbmVDb25maWcsIFxuICBERUZBVUxUX1JVTEVfRU5HSU5FX0NPTkZJRywgXG4gIHZhbGlkYXRlUnVsZUVuZ2luZUNvbmZpZyBcbn0gZnJvbSAnLi9ydWxlRW5naW5lQ29uZmlnLmpzJztcbmltcG9ydCB7IFxuICBhcHBseUdvYWxUZW1wbGF0ZSwgXG4gIHJlY29tbWVuZEdvYWxUZW1wbGF0ZSwgXG4gIHZhbGlkYXRlR29hbEFnYWluc3RUZW1wbGF0ZSBcbn0gZnJvbSAnLi9nb2FsVGVtcGxhdGVzLmpzJztcblxuZXhwb3J0IGNsYXNzIEFnZW50IGV4dGVuZHMgQmFzZUVsZW1lbnQgaW1wbGVtZW50cyBJRWxlbWVudCB7XG4gIHByaXZhdGUgc3RhdGU6IEFnZW50U3RhdGU7XG4gIHByaXZhdGUgaXNEaXJ0eVN0YXRlOiBib29sZWFuID0gZmFsc2U7XG4gIHByaXZhdGUgcnVsZUVuZ2luZUNvbmZpZzogUnVsZUVuZ2luZUNvbmZpZztcblxuICBjb25zdHJ1Y3RvcihtZXRhZGF0YTogUGFydGlhbDxBZ2VudE1ldGFkYXRhPikge1xuICAgIC8vIFNhbml0aXplIGFsbCBpbnB1dHNcbiAgICBjb25zdCBzYW5pdGl6ZWRNZXRhZGF0YTogUGFydGlhbDxBZ2VudE1ldGFkYXRhPiA9IHtcbiAgICAgIC4uLm1ldGFkYXRhLFxuICAgICAgbmFtZTogbWV0YWRhdGEubmFtZSA/IHNhbml0aXplSW5wdXQoVW5pY29kZVZhbGlkYXRvci5ub3JtYWxpemUobWV0YWRhdGEubmFtZSkubm9ybWFsaXplZENvbnRlbnQsIDEwMCkgOiB1bmRlZmluZWQsXG4gICAgICBkZXNjcmlwdGlvbjogbWV0YWRhdGEuZGVzY3JpcHRpb24gPyBzYW5pdGl6ZUlucHV0KFVuaWNvZGVWYWxpZGF0b3Iubm9ybWFsaXplKG1ldGFkYXRhLmRlc2NyaXB0aW9uKS5ub3JtYWxpemVkQ29udGVudCwgNTAwKSA6IHVuZGVmaW5lZCxcbiAgICAgIHNwZWNpYWxpemF0aW9uczogbWV0YWRhdGEuc3BlY2lhbGl6YXRpb25zPy5tYXAocyA9PiBzYW5pdGl6ZUlucHV0KHMsIDUwKSksXG4gICAgICBkZWNpc2lvbkZyYW1ld29yazogbWV0YWRhdGEuZGVjaXNpb25GcmFtZXdvcmsgfHwgQUdFTlRfREVGQVVMVFMuREVDSVNJT05fRlJBTUVXT1JLLFxuICAgICAgcmlza1RvbGVyYW5jZTogbWV0YWRhdGEucmlza1RvbGVyYW5jZSB8fCBBR0VOVF9ERUZBVUxUUy5SSVNLX1RPTEVSQU5DRSxcbiAgICAgIGxlYXJuaW5nRW5hYmxlZDogbWV0YWRhdGEubGVhcm5pbmdFbmFibGVkID8/IEFHRU5UX0RFRkFVTFRTLkxFQVJOSU5HX0VOQUJMRUQsXG4gICAgICBtYXhDb25jdXJyZW50R29hbHM6IG1ldGFkYXRhLm1heENvbmN1cnJlbnRHb2FscyA/PyBBR0VOVF9ERUZBVUxUUy5NQVhfQ09OQ1VSUkVOVF9HT0FMU1xuICAgIH07XG5cbiAgICAvLyBNRURJVU0gUFJJT1JJVFkgSU1QUk9WRU1FTlQ6IFZhbGlkYXRlIGRlY2lzaW9uIGZyYW1ld29yayBjb25maWd1cmF0aW9uXG4gICAgLy8gRW5zdXJlcyBvbmx5IHN1cHBvcnRlZCBmcmFtZXdvcmtzIGFyZSB1c2VkXG4gICAgaWYgKHNhbml0aXplZE1ldGFkYXRhLmRlY2lzaW9uRnJhbWV3b3JrICYmIFxuICAgICAgICAhREVDSVNJT05fRlJBTUVXT1JLUy5pbmNsdWRlcyhzYW5pdGl6ZWRNZXRhZGF0YS5kZWNpc2lvbkZyYW1ld29yaykpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBkZWNpc2lvbiBmcmFtZXdvcms6ICR7c2FuaXRpemVkTWV0YWRhdGEuZGVjaXNpb25GcmFtZXdvcmt9LiBgICtcbiAgICAgICAgYFN1cHBvcnRlZCBmcmFtZXdvcmtzOiAke0RFQ0lTSU9OX0ZSQU1FV09SS1Muam9pbignLCAnKX1gKTtcbiAgICB9XG5cbiAgICAvLyBWYWxpZGF0ZSByaXNrIHRvbGVyYW5jZSBsZXZlbFxuICAgIGlmIChzYW5pdGl6ZWRNZXRhZGF0YS5yaXNrVG9sZXJhbmNlICYmIFxuICAgICAgICAhUklTS19UT0xFUkFOQ0VfTEVWRUxTLmluY2x1ZGVzKHNhbml0aXplZE1ldGFkYXRhLnJpc2tUb2xlcmFuY2UpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgcmlzayB0b2xlcmFuY2U6ICR7c2FuaXRpemVkTWV0YWRhdGEucmlza1RvbGVyYW5jZX0uIGAgK1xuICAgICAgICBgU3VwcG9ydGVkIGxldmVsczogJHtSSVNLX1RPTEVSQU5DRV9MRVZFTFMuam9pbignLCAnKX1gKTtcbiAgICB9XG5cbiAgICAvLyBWYWxpZGF0ZSBtYXggY29uY3VycmVudCBnb2Fsc1xuICAgIGlmIChzYW5pdGl6ZWRNZXRhZGF0YS5tYXhDb25jdXJyZW50R29hbHMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgY29uc3QgbWF4R29hbHMgPSBzYW5pdGl6ZWRNZXRhZGF0YS5tYXhDb25jdXJyZW50R29hbHM7XG4gICAgICBpZiAoIU51bWJlci5pc0ludGVnZXIobWF4R29hbHMpIHx8IG1heEdvYWxzIDwgMSB8fCBtYXhHb2FscyA+IEFHRU5UX0xJTUlUUy5NQVhfR09BTFMpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBtYXhDb25jdXJyZW50R29hbHMgbXVzdCBiZSBiZXR3ZWVuIDEgYW5kICR7QUdFTlRfTElNSVRTLk1BWF9HT0FMU31gKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBzdXBlcihFbGVtZW50VHlwZS5BR0VOVCwgc2FuaXRpemVkTWV0YWRhdGEpO1xuXG4gICAgLy8gSW5pdGlhbGl6ZSBzdGF0ZVxuICAgIHRoaXMuc3RhdGUgPSB7XG4gICAgICBnb2FsczogW10sXG4gICAgICBkZWNpc2lvbnM6IFtdLFxuICAgICAgY29udGV4dDoge30sXG4gICAgICBsYXN0QWN0aXZlOiBuZXcgRGF0ZSgpLFxuICAgICAgc2Vzc2lvbkNvdW50OiAwXG4gICAgfTtcblxuICAgIC8vIFNldCBhZ2VudC1zcGVjaWZpYyBleHRlbnNpb25zXG4gICAgdGhpcy5leHRlbnNpb25zID0ge1xuICAgICAgZGVjaXNpb25GcmFtZXdvcms6IHNhbml0aXplZE1ldGFkYXRhLmRlY2lzaW9uRnJhbWV3b3JrLFxuICAgICAgcmlza1RvbGVyYW5jZTogc2FuaXRpemVkTWV0YWRhdGEucmlza1RvbGVyYW5jZSxcbiAgICAgIGxlYXJuaW5nRW5hYmxlZDogc2FuaXRpemVkTWV0YWRhdGEubGVhcm5pbmdFbmFibGVkLFxuICAgICAgc3BlY2lhbGl6YXRpb25zOiBzYW5pdGl6ZWRNZXRhZGF0YS5zcGVjaWFsaXphdGlvbnMgfHwgW10sXG4gICAgICBydWxlRW5naW5lQ29uZmlnOiBtZXRhZGF0YS5ydWxlRW5naW5lQ29uZmlnXG4gICAgfTtcblxuICAgIC8vIEluaXRpYWxpemUgcnVsZSBlbmdpbmUgY29uZmlndXJhdGlvbiAod2l0aCB2YWxpZGF0aW9uKVxuICAgIHRoaXMucnVsZUVuZ2luZUNvbmZpZyA9IHZhbGlkYXRlUnVsZUVuZ2luZUNvbmZpZyhcbiAgICAgIHRoaXMuZXh0ZW5zaW9ucy5ydWxlRW5naW5lQ29uZmlnIHx8IHt9XG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGQgYSBuZXcgZ29hbCB3aXRoIHNlY3VyaXR5IHZhbGlkYXRpb25cbiAgICovXG4gIHB1YmxpYyBhZGRHb2FsKGdvYWw6IFBhcnRpYWw8QWdlbnRHb2FsPik6IEFnZW50R29hbCB7XG4gICAgLy8gVmFsaWRhdGUgZ29hbCBjb3VudFxuICAgIGlmICh0aGlzLnN0YXRlLmdvYWxzLmxlbmd0aCA+PSBBR0VOVF9MSU1JVFMuTUFYX0dPQUxTKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYE1heGltdW0gbnVtYmVyIG9mIGdvYWxzICgke0FHRU5UX0xJTUlUUy5NQVhfR09BTFN9KSByZWFjaGVkYCk7XG4gICAgfVxuXG4gICAgLy8gU2FuaXRpemUgZ29hbCBkZXNjcmlwdGlvblxuICAgIGNvbnN0IHNhbml0aXplZERlc2NyaXB0aW9uID0gc2FuaXRpemVJbnB1dChcbiAgICAgIFVuaWNvZGVWYWxpZGF0b3Iubm9ybWFsaXplKGdvYWwuZGVzY3JpcHRpb24gfHwgJycpLm5vcm1hbGl6ZWRDb250ZW50LFxuICAgICAgQUdFTlRfTElNSVRTLk1BWF9HT0FMX0xFTkdUSFxuICAgICk7XG5cbiAgICBpZiAoIXNhbml0aXplZERlc2NyaXB0aW9uIHx8IHNhbml0aXplZERlc2NyaXB0aW9uLmxlbmd0aCA8IDMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignR29hbCBkZXNjcmlwdGlvbiBtdXN0IGJlIGF0IGxlYXN0IDMgY2hhcmFjdGVycycpO1xuICAgIH1cblxuICAgIC8vIFZhbGlkYXRlIGdvYWwgZm9yIHNlY3VyaXR5IHRocmVhdHNcbiAgICBjb25zdCBzZWN1cml0eUNoZWNrID0gdGhpcy52YWxpZGF0ZUdvYWxTZWN1cml0eShzYW5pdGl6ZWREZXNjcmlwdGlvbik7XG4gICAgaWYgKCFzZWN1cml0eUNoZWNrLnNhZmUpIHtcbiAgICAgIFNlY3VyaXR5TW9uaXRvci5sb2dTZWN1cml0eUV2ZW50KHtcbiAgICAgICAgdHlwZTogJ0NPTlRFTlRfSU5KRUNUSU9OX0FUVEVNUFQnLFxuICAgICAgICBzZXZlcml0eTogJ0hJR0gnLFxuICAgICAgICBzb3VyY2U6ICdBZ2VudC5hZGRHb2FsJyxcbiAgICAgICAgZGV0YWlsczogYFBvdGVudGlhbGx5IG1hbGljaW91cyBnb2FsIHJlamVjdGVkOiAke3NlY3VyaXR5Q2hlY2sucmVhc29ufWAsXG4gICAgICAgIGFkZGl0aW9uYWxEYXRhOiB7IGFnZW50SWQ6IHRoaXMuaWQgfVxuICAgICAgfSk7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEdvYWwgY29udGFpbnMgcG90ZW50aWFsbHkgaGFybWZ1bCBjb250ZW50OiAke3NlY3VyaXR5Q2hlY2sucmVhc29ufWApO1xuICAgIH1cblxuICAgIC8vIENhbGN1bGF0ZSBFaXNlbmhvd2VyIHF1YWRyYW50XG4gICAgY29uc3QgaW1wb3J0YW5jZSA9IGdvYWwuaW1wb3J0YW5jZSB8fCA1O1xuICAgIGNvbnN0IHVyZ2VuY3kgPSBnb2FsLnVyZ2VuY3kgfHwgNTtcbiAgICBjb25zdCBlaXNlbmhvd2VyUXVhZHJhbnQgPSB0aGlzLmNhbGN1bGF0ZUVpc2VuaG93ZXJRdWFkcmFudChpbXBvcnRhbmNlLCB1cmdlbmN5KTtcblxuICAgIC8vIENyZWF0ZSBuZXcgZ29hbFxuICAgIGNvbnN0IG5ld0dvYWw6IEFnZW50R29hbCA9IHtcbiAgICAgIGlkOiBgZ29hbF8ke0RhdGUubm93KCl9XyR7TWF0aC5yYW5kb20oKS50b1N0cmluZygzNikuc3Vic3RyKDIsIDkpfWAsXG4gICAgICBkZXNjcmlwdGlvbjogc2FuaXRpemVkRGVzY3JpcHRpb24sXG4gICAgICBwcmlvcml0eTogZ29hbC5wcmlvcml0eSB8fCBBR0VOVF9ERUZBVUxUUy5HT0FMX1BSSU9SSVRZLFxuICAgICAgc3RhdHVzOiAncGVuZGluZycsXG4gICAgICBpbXBvcnRhbmNlLFxuICAgICAgdXJnZW5jeSxcbiAgICAgIGVpc2VuaG93ZXJRdWFkcmFudCxcbiAgICAgIGNyZWF0ZWRBdDogbmV3IERhdGUoKSxcbiAgICAgIHVwZGF0ZWRBdDogbmV3IERhdGUoKSxcbiAgICAgIGRlcGVuZGVuY2llczogZ29hbC5kZXBlbmRlbmNpZXMgfHwgW10sXG4gICAgICByaXNrTGV2ZWw6IGdvYWwucmlza0xldmVsIHx8ICdsb3cnLFxuICAgICAgZXN0aW1hdGVkRWZmb3J0OiBnb2FsLmVzdGltYXRlZEVmZm9ydCxcbiAgICAgIG5vdGVzOiBnb2FsLm5vdGVzID8gc2FuaXRpemVJbnB1dChnb2FsLm5vdGVzLCA1MDApIDogdW5kZWZpbmVkXG4gICAgfTtcblxuICAgIC8vIE1FRElVTSBQUklPUklUWSBJTVBST1ZFTUVOVDogRGV0ZWN0IGRlcGVuZGVuY3kgY3ljbGVzIGJlZm9yZSBhZGRpbmcgZ29hbFxuICAgIGlmIChuZXdHb2FsLmRlcGVuZGVuY2llcyAmJiBuZXdHb2FsLmRlcGVuZGVuY2llcy5sZW5ndGggPiAwKSB7XG4gICAgICBjb25zdCBjeWNsZUNoZWNrID0gdGhpcy5kZXRlY3REZXBlbmRlbmN5Q3ljbGUobmV3R29hbC5pZCwgbmV3R29hbC5kZXBlbmRlbmNpZXMpO1xuICAgICAgaWYgKGN5Y2xlQ2hlY2suaGFzQ3ljbGUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBEZXBlbmRlbmN5IGN5Y2xlIGRldGVjdGVkOiAke2N5Y2xlQ2hlY2sucGF0aC5qb2luKCcg4oaSICcpfWApO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuc3RhdGUuZ29hbHMucHVzaChuZXdHb2FsKTtcbiAgICB0aGlzLmlzRGlydHlTdGF0ZSA9IHRydWU7XG4gICAgdGhpcy5tYXJrRGlydHkoKTtcblxuICAgIGxvZ2dlci5pbmZvKGBHb2FsIGFkZGVkIHRvIGFnZW50ICR7dGhpcy5tZXRhZGF0YS5uYW1lfWAsIHsgZ29hbElkOiBuZXdHb2FsLmlkIH0pO1xuXG4gICAgcmV0dXJuIG5ld0dvYWw7XG4gIH1cblxuICAvKipcbiAgICogTWFrZSBhIGRlY2lzaW9uIGZvciBhIGdvYWxcbiAgICovXG4gIHB1YmxpYyBhc3luYyBtYWtlRGVjaXNpb24oZ29hbElkOiBzdHJpbmcsIGNvbnRleHQ/OiBSZWNvcmQ8c3RyaW5nLCBhbnk+KTogUHJvbWlzZTxBZ2VudERlY2lzaW9uPiB7XG4gICAgLy8gTUVESVVNIFBSSU9SSVRZIElNUFJPVkVNRU5UOiBUcmFjayBwZXJmb3JtYW5jZSBtZXRyaWNzIGZvciBkZWNpc2lvbiBtYWtpbmdcbiAgICBjb25zdCBzdGFydFRpbWUgPSBEYXRlLm5vdygpO1xuICAgIGNvbnN0IHBlcmZvcm1hbmNlTWV0cmljczoge1xuICAgICAgZGVjaXNpb25UaW1lTXM/OiBudW1iZXI7XG4gICAgICBmcmFtZXdvcmtUaW1lTXM/OiBudW1iZXI7XG4gICAgICByaXNrQXNzZXNzbWVudFRpbWVNcz86IG51bWJlcjtcbiAgICB9ID0ge307XG5cbiAgICBjb25zdCBnb2FsID0gdGhpcy5zdGF0ZS5nb2Fscy5maW5kKGcgPT4gZy5pZCA9PT0gZ29hbElkKTtcbiAgICBpZiAoIWdvYWwpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgR29hbCAke2dvYWxJZH0gbm90IGZvdW5kYCk7XG4gICAgfVxuXG4gICAgaWYgKGdvYWwuc3RhdHVzID09PSAnY29tcGxldGVkJyB8fCBnb2FsLnN0YXR1cyA9PT0gJ2NhbmNlbGxlZCcpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgQ2Fubm90IG1ha2UgZGVjaXNpb24gZm9yICR7Z29hbC5zdGF0dXN9IGdvYWxgKTtcbiAgICB9XG5cbiAgICAvLyBVcGRhdGUgZ29hbCBzdGF0dXNcbiAgICBnb2FsLnN0YXR1cyA9ICdpbl9wcm9ncmVzcyc7XG4gICAgZ29hbC51cGRhdGVkQXQgPSBuZXcgRGF0ZSgpO1xuXG4gICAgLy8gUHJlcGFyZSBkZWNpc2lvbiBjb250ZXh0XG4gICAgY29uc3QgZGVjaXNpb25Db250ZXh0ID0ge1xuICAgICAgLi4udGhpcy5zdGF0ZS5jb250ZXh0LFxuICAgICAgLi4uY29udGV4dCxcbiAgICAgIGdvYWwsXG4gICAgICBhZ2VudE1ldGFkYXRhOiB0aGlzLm1ldGFkYXRhLFxuICAgICAgcHJldmlvdXNEZWNpc2lvbnM6IHRoaXMuc3RhdGUuZGVjaXNpb25zLmZpbHRlcihkID0+IGQuZ29hbElkID09PSBnb2FsSWQpXG4gICAgfTtcblxuICAgIC8vIE1ha2UgZGVjaXNpb24gYmFzZWQgb24gZnJhbWV3b3JrICh3aXRoIHRpbWluZylcbiAgICBjb25zdCBmcmFtZXdvcmtTdGFydCA9IERhdGUubm93KCk7XG4gICAgY29uc3QgZGVjaXNpb24gPSBhd2FpdCB0aGlzLmV4ZWN1dGVEZWNpc2lvbkZyYW1ld29yayhnb2FsLCBkZWNpc2lvbkNvbnRleHQpO1xuICAgIHBlcmZvcm1hbmNlTWV0cmljcy5mcmFtZXdvcmtUaW1lTXMgPSBEYXRlLm5vdygpIC0gZnJhbWV3b3JrU3RhcnQ7XG5cbiAgICAvLyBSaXNrIGFzc2Vzc21lbnQgKHdpdGggdGltaW5nKVxuICAgIGNvbnN0IHJpc2tTdGFydCA9IERhdGUubm93KCk7XG4gICAgY29uc3Qgcmlza0Fzc2Vzc21lbnQgPSB0aGlzLmFzc2Vzc1Jpc2soZGVjaXNpb24sIGdvYWwsIGRlY2lzaW9uQ29udGV4dCk7XG4gICAgcGVyZm9ybWFuY2VNZXRyaWNzLnJpc2tBc3Nlc3NtZW50VGltZU1zID0gRGF0ZS5ub3coKSAtIHJpc2tTdGFydDtcblxuICAgIC8vIENhbGN1bGF0ZSB0b3RhbCBkZWNpc2lvbiB0aW1lXG4gICAgcGVyZm9ybWFuY2VNZXRyaWNzLmRlY2lzaW9uVGltZU1zID0gRGF0ZS5ub3coKSAtIHN0YXJ0VGltZTtcblxuICAgIC8vIENyZWF0ZSBkZWNpc2lvbiByZWNvcmRcbiAgICBjb25zdCBkZWNpc2lvblJlY29yZDogQWdlbnREZWNpc2lvbiA9IHtcbiAgICAgIGlkOiBgZGVjaXNpb25fJHtEYXRlLm5vdygpfV8ke01hdGgucmFuZG9tKCkudG9TdHJpbmcoMzYpLnN1YnN0cigyLCA5KX1gLFxuICAgICAgZ29hbElkLFxuICAgICAgdGltZXN0YW1wOiBuZXcgRGF0ZSgpLFxuICAgICAgZGVjaXNpb246IGRlY2lzaW9uLmFjdGlvbixcbiAgICAgIHJlYXNvbmluZzogZGVjaXNpb24ucmVhc29uaW5nLFxuICAgICAgZnJhbWV3b3JrOiB0aGlzLmV4dGVuc2lvbnM/LmRlY2lzaW9uRnJhbWV3b3JrIHx8IEFHRU5UX0RFRkFVTFRTLkRFQ0lTSU9OX0ZSQU1FV09SSyxcbiAgICAgIGNvbmZpZGVuY2U6IGRlY2lzaW9uLmNvbmZpZGVuY2UsXG4gICAgICByaXNrQXNzZXNzbWVudCxcbiAgICAgIHBlcmZvcm1hbmNlTWV0cmljcyAgLy8gQWRkIHBlcmZvcm1hbmNlIHRyYWNraW5nXG4gICAgfTtcblxuICAgIC8vIE9QVElNSVpBVElPTjogVXNlIGVmZmljaWVudCBjaXJjdWxhciBidWZmZXIgcGF0dGVyblxuICAgIC8vIEFkZCB0byBoaXN0b3J5IHdpdGggbGltaXQgKGF2b2lkIGFycmF5IHNsaWNpbmcgZm9yIGJldHRlciBwZXJmb3JtYW5jZSlcbiAgICBpZiAodGhpcy5zdGF0ZS5kZWNpc2lvbnMubGVuZ3RoID49IEFHRU5UX0xJTUlUUy5NQVhfREVDSVNJT05fSElTVE9SWSkge1xuICAgICAgLy8gUmVtb3ZlIG9sZGVzdCBlbnRyeSBiZWZvcmUgYWRkaW5nIG5ldyBvbmUgKE8obikgYnV0IGhhcHBlbnMgaW5mcmVxdWVudGx5KVxuICAgICAgdGhpcy5zdGF0ZS5kZWNpc2lvbnMuc2hpZnQoKTtcbiAgICB9XG4gICAgdGhpcy5zdGF0ZS5kZWNpc2lvbnMucHVzaChkZWNpc2lvblJlY29yZCk7XG5cbiAgICB0aGlzLmlzRGlydHlTdGF0ZSA9IHRydWU7XG4gICAgdGhpcy5tYXJrRGlydHkoKTtcblxuICAgIC8vIExvZyBkZWNpc2lvbiBmb3IgYXVkaXRcbiAgICBTZWN1cml0eU1vbml0b3IubG9nU2VjdXJpdHlFdmVudCh7XG4gICAgICB0eXBlOiAnQUdFTlRfREVDSVNJT04nLFxuICAgICAgc2V2ZXJpdHk6ICdMT1cnLFxuICAgICAgc291cmNlOiAnQWdlbnQubWFrZURlY2lzaW9uJyxcbiAgICAgIGRldGFpbHM6IGBBZ2VudCAke3RoaXMubWV0YWRhdGEubmFtZX0gbWFkZSBkZWNpc2lvbiBmb3IgZ29hbCAke2dvYWxJZH1gLFxuICAgICAgYWRkaXRpb25hbERhdGE6IHtcbiAgICAgICAgYWdlbnRJZDogdGhpcy5pZCxcbiAgICAgICAgZ29hbElkLFxuICAgICAgICBmcmFtZXdvcms6IGRlY2lzaW9uUmVjb3JkLmZyYW1ld29yayxcbiAgICAgICAgcmlza0xldmVsOiByaXNrQXNzZXNzbWVudC5sZXZlbFxuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIGRlY2lzaW9uUmVjb3JkO1xuICB9XG5cbiAgLyoqXG4gICAqIEV4ZWN1dGUgZGVjaXNpb24gZnJhbWV3b3JrXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGV4ZWN1dGVEZWNpc2lvbkZyYW1ld29yayhcbiAgICBnb2FsOiBBZ2VudEdvYWwsXG4gICAgY29udGV4dDogUmVjb3JkPHN0cmluZywgYW55PlxuICApOiBQcm9taXNlPHsgYWN0aW9uOiBzdHJpbmc7IHJlYXNvbmluZzogc3RyaW5nOyBjb25maWRlbmNlOiBudW1iZXIgfT4ge1xuICAgIGNvbnN0IGZyYW1ld29yayA9IHRoaXMuZXh0ZW5zaW9ucz8uZGVjaXNpb25GcmFtZXdvcmsgfHwgQUdFTlRfREVGQVVMVFMuREVDSVNJT05fRlJBTUVXT1JLO1xuXG4gICAgc3dpdGNoIChmcmFtZXdvcmspIHtcbiAgICAgIGNhc2UgJ3J1bGVfYmFzZWQnOlxuICAgICAgICByZXR1cm4gdGhpcy5ydWxlQmFzZWREZWNpc2lvbihnb2FsLCBjb250ZXh0KTtcbiAgICAgIFxuICAgICAgY2FzZSAnbWxfYmFzZWQnOlxuICAgICAgICAvLyBQbGFjZWhvbGRlciBmb3IgTUwtYmFzZWQgZGVjaXNpb25zXG4gICAgICAgIGxvZ2dlci53YXJuKCdNTC1iYXNlZCBkZWNpc2lvbnMgbm90IHlldCBpbXBsZW1lbnRlZCwgZmFsbGluZyBiYWNrIHRvIHJ1bGUtYmFzZWQnKTtcbiAgICAgICAgcmV0dXJuIHRoaXMucnVsZUJhc2VkRGVjaXNpb24oZ29hbCwgY29udGV4dCk7XG4gICAgICBcbiAgICAgIGNhc2UgJ3Byb2dyYW1tYXRpYyc6XG4gICAgICAgIHJldHVybiB0aGlzLnByb2dyYW1tYXRpY0RlY2lzaW9uKGdvYWwsIGNvbnRleHQpO1xuICAgICAgXG4gICAgICBjYXNlICdoeWJyaWQnOlxuICAgICAgICAvLyBDb21iaW5lIG11bHRpcGxlIGZyYW1ld29ya3NcbiAgICAgICAgY29uc3QgcnVsZURlY2lzaW9uID0gYXdhaXQgdGhpcy5ydWxlQmFzZWREZWNpc2lvbihnb2FsLCBjb250ZXh0KTtcbiAgICAgICAgY29uc3QgcHJvZ0RlY2lzaW9uID0gYXdhaXQgdGhpcy5wcm9ncmFtbWF0aWNEZWNpc2lvbihnb2FsLCBjb250ZXh0KTtcbiAgICAgICAgXG4gICAgICAgIC8vIEF2ZXJhZ2UgY29uZmlkZW5jZSBhbmQgY29tYmluZSByZWFzb25pbmdcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBhY3Rpb246IHJ1bGVEZWNpc2lvbi5jb25maWRlbmNlID4gcHJvZ0RlY2lzaW9uLmNvbmZpZGVuY2UgPyBydWxlRGVjaXNpb24uYWN0aW9uIDogcHJvZ0RlY2lzaW9uLmFjdGlvbixcbiAgICAgICAgICByZWFzb25pbmc6IGBSdWxlLWJhc2VkOiAke3J1bGVEZWNpc2lvbi5yZWFzb25pbmd9XFxuUHJvZ3JhbW1hdGljOiAke3Byb2dEZWNpc2lvbi5yZWFzb25pbmd9YCxcbiAgICAgICAgICBjb25maWRlbmNlOiAocnVsZURlY2lzaW9uLmNvbmZpZGVuY2UgKyBwcm9nRGVjaXNpb24uY29uZmlkZW5jZSkgLyAyXG4gICAgICAgIH07XG4gICAgICBcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5rbm93biBkZWNpc2lvbiBmcmFtZXdvcms6ICR7ZnJhbWV3b3JrfWApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSdWxlLWJhc2VkIGRlY2lzaW9uIG1ha2luZ1xuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBydWxlQmFzZWREZWNpc2lvbihcbiAgICBnb2FsOiBBZ2VudEdvYWwsXG4gICAgY29udGV4dDogUmVjb3JkPHN0cmluZywgYW55PlxuICApOiBQcm9taXNlPHsgYWN0aW9uOiBzdHJpbmc7IHJlYXNvbmluZzogc3RyaW5nOyBjb25maWRlbmNlOiBudW1iZXIgfT4ge1xuICAgIGNvbnN0IHJ1bGVzOiBBcnJheTx7XG4gICAgICBjb25kaXRpb246IChnOiBBZ2VudEdvYWwsIGN0eDogUmVjb3JkPHN0cmluZywgYW55PikgPT4gYm9vbGVhbjtcbiAgICAgIGFjdGlvbjogc3RyaW5nO1xuICAgICAgcmVhc29uaW5nOiBzdHJpbmc7XG4gICAgICBjb25maWRlbmNlOiBudW1iZXI7XG4gICAgfT4gPSBbXG4gICAgICAvLyBIaWdoIHByaW9yaXR5ICsgaGlnaCB1cmdlbmN5ID0gaW1tZWRpYXRlIGFjdGlvblxuICAgICAge1xuICAgICAgICBjb25kaXRpb246IChnKSA9PiBnLnByaW9yaXR5ID09PSB0aGlzLnJ1bGVFbmdpbmVDb25maWcucnVsZUJhc2VkLnByaW9yaXR5LmNyaXRpY2FsICYmIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgZy51cmdlbmN5ID4gdGhpcy5ydWxlRW5naW5lQ29uZmlnLnJ1bGVCYXNlZC51cmdlbmN5VGhyZXNob2xkcy5pbW1lZGlhdGUsXG4gICAgICAgIGFjdGlvbjogdGhpcy5ydWxlRW5naW5lQ29uZmlnLmFjdGlvbnMuZXhlY3V0ZUltbWVkaWF0ZWx5LFxuICAgICAgICByZWFzb25pbmc6ICdDcml0aWNhbCBwcmlvcml0eSB3aXRoIGhpZ2ggdXJnZW5jeSByZXF1aXJlcyBpbW1lZGlhdGUgYWN0aW9uJyxcbiAgICAgICAgY29uZmlkZW5jZTogdGhpcy5ydWxlRW5naW5lQ29uZmlnLnJ1bGVCYXNlZC5jb25maWRlbmNlLmNyaXRpY2FsXG4gICAgICB9LFxuICAgICAgLy8gQmxvY2tlZCBieSBkZXBlbmRlbmNpZXNcbiAgICAgIHtcbiAgICAgICAgY29uZGl0aW9uOiAoZywgY3R4KSA9PiB7XG4gICAgICAgICAgaWYgKCFnLmRlcGVuZGVuY2llcyB8fCBnLmRlcGVuZGVuY2llcy5sZW5ndGggPT09IDApIHJldHVybiBmYWxzZTtcbiAgICAgICAgICBjb25zdCBibG9ja2VkRGVwcyA9IGcuZGVwZW5kZW5jaWVzLmZpbHRlcihkZXBJZCA9PiB7XG4gICAgICAgICAgICBjb25zdCBkZXAgPSB0aGlzLnN0YXRlLmdvYWxzLmZpbmQoZ29hbCA9PiBnb2FsLmlkID09PSBkZXBJZCk7XG4gICAgICAgICAgICByZXR1cm4gZGVwICYmIGRlcC5zdGF0dXMgIT09ICdjb21wbGV0ZWQnO1xuICAgICAgICAgIH0pO1xuICAgICAgICAgIHJldHVybiBibG9ja2VkRGVwcy5sZW5ndGggPiAwO1xuICAgICAgICB9LFxuICAgICAgICBhY3Rpb246IHRoaXMucnVsZUVuZ2luZUNvbmZpZy5hY3Rpb25zLndhaXRGb3JEZXBlbmRlbmNpZXMsXG4gICAgICAgIHJlYXNvbmluZzogJ0dvYWwgaGFzIGluY29tcGxldGUgZGVwZW5kZW5jaWVzJyxcbiAgICAgICAgY29uZmlkZW5jZTogdGhpcy5ydWxlRW5naW5lQ29uZmlnLnJ1bGVCYXNlZC5jb25maWRlbmNlLmJsb2NrZWRcbiAgICAgIH0sXG4gICAgICAvLyBSaXNrIGFzc2Vzc21lbnRcbiAgICAgIHtcbiAgICAgICAgY29uZGl0aW9uOiAoZykgPT4gZy5yaXNrTGV2ZWwgPT09ICdoaWdoJyAmJiB0aGlzLmV4dGVuc2lvbnM/LnJpc2tUb2xlcmFuY2UgPT09ICdjb25zZXJ2YXRpdmUnLFxuICAgICAgICBhY3Rpb246IHRoaXMucnVsZUVuZ2luZUNvbmZpZy5hY3Rpb25zLnJlcXVlc3RBcHByb3ZhbCxcbiAgICAgICAgcmVhc29uaW5nOiAnSGlnaCByaXNrIGdvYWwgcmVxdWlyZXMgYXBwcm92YWwgaW4gY29uc2VydmF0aXZlIG1vZGUnLFxuICAgICAgICBjb25maWRlbmNlOiB0aGlzLnJ1bGVFbmdpbmVDb25maWcucnVsZUJhc2VkLmNvbmZpZGVuY2Uucmlza0FwcHJvdmFsXG4gICAgICB9LFxuICAgICAgLy8gUmVzb3VyY2UgYXZhaWxhYmlsaXR5XG4gICAgICB7XG4gICAgICAgIGNvbmRpdGlvbjogKGcsIGN0eCkgPT4ge1xuICAgICAgICAgIGNvbnN0IGFjdGl2ZUdvYWxzID0gdGhpcy5zdGF0ZS5nb2Fscy5maWx0ZXIoZ29hbCA9PiBnb2FsLnN0YXR1cyA9PT0gJ2luX3Byb2dyZXNzJykubGVuZ3RoO1xuICAgICAgICAgIGNvbnN0IG1heENvbmN1cnJlbnQgPSAodGhpcy5tZXRhZGF0YSBhcyBBZ2VudE1ldGFkYXRhKS5tYXhDb25jdXJyZW50R29hbHMgfHwgQUdFTlRfREVGQVVMVFMuTUFYX0NPTkNVUlJFTlRfR09BTFM7XG4gICAgICAgICAgcmV0dXJuIGFjdGl2ZUdvYWxzID49IG1heENvbmN1cnJlbnQ7XG4gICAgICAgIH0sXG4gICAgICAgIGFjdGlvbjogdGhpcy5ydWxlRW5naW5lQ29uZmlnLmFjdGlvbnMucXVldWVGb3JMYXRlcixcbiAgICAgICAgcmVhc29uaW5nOiAnTWF4aW11bSBjb25jdXJyZW50IGdvYWxzIHJlYWNoZWQnLFxuICAgICAgICBjb25maWRlbmNlOiB0aGlzLnJ1bGVFbmdpbmVDb25maWcucnVsZUJhc2VkLmNvbmZpZGVuY2UucmVzb3VyY2VMaW1pdFxuICAgICAgfSxcbiAgICAgIC8vIERlZmF1bHQgYWN0aW9uXG4gICAgICB7XG4gICAgICAgIGNvbmRpdGlvbjogKCkgPT4gdHJ1ZSxcbiAgICAgICAgYWN0aW9uOiB0aGlzLnJ1bGVFbmdpbmVDb25maWcuYWN0aW9ucy5wcm9jZWVkV2l0aEdvYWwsXG4gICAgICAgIHJlYXNvbmluZzogJ05vIGJsb2NraW5nIGNvbmRpdGlvbnMgZm91bmQnLFxuICAgICAgICBjb25maWRlbmNlOiB0aGlzLnJ1bGVFbmdpbmVDb25maWcucnVsZUJhc2VkLmNvbmZpZGVuY2UuZGVmYXVsdFxuICAgICAgfVxuICAgIF07XG5cbiAgICAvLyBFdmFsdWF0ZSBydWxlcyBpbiBvcmRlclxuICAgIGZvciAoY29uc3QgcnVsZSBvZiBydWxlcykge1xuICAgICAgaWYgKHJ1bGUuY29uZGl0aW9uKGdvYWwsIGNvbnRleHQpKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgYWN0aW9uOiBydWxlLmFjdGlvbixcbiAgICAgICAgICByZWFzb25pbmc6IHJ1bGUucmVhc29uaW5nLFxuICAgICAgICAgIGNvbmZpZGVuY2U6IHJ1bGUuY29uZmlkZW5jZVxuICAgICAgICB9O1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIEZhbGxiYWNrIChzaG91bGQgbm90IHJlYWNoIGhlcmUpXG4gICAgcmV0dXJuIHtcbiAgICAgIGFjdGlvbjogdGhpcy5ydWxlRW5naW5lQ29uZmlnLmFjdGlvbnMucmV2aWV3TWFudWFsbHksXG4gICAgICByZWFzb25pbmc6ICdObyBhcHBsaWNhYmxlIHJ1bGVzIGZvdW5kJyxcbiAgICAgIGNvbmZpZGVuY2U6IDAuNVxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogUHJvZ3JhbW1hdGljIGRlY2lzaW9uIG1ha2luZ1xuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBwcm9ncmFtbWF0aWNEZWNpc2lvbihcbiAgICBnb2FsOiBBZ2VudEdvYWwsXG4gICAgY29udGV4dDogUmVjb3JkPHN0cmluZywgYW55PlxuICApOiBQcm9taXNlPHsgYWN0aW9uOiBzdHJpbmc7IHJlYXNvbmluZzogc3RyaW5nOyBjb25maWRlbmNlOiBudW1iZXIgfT4ge1xuICAgIC8vIENhbGN1bGF0ZSBkZWNpc2lvbiBzY29yZSBiYXNlZCBvbiBtdWx0aXBsZSBmYWN0b3JzXG4gICAgbGV0IHNjb3JlID0gMDtcbiAgICBjb25zdCBmYWN0b3JzOiBzdHJpbmdbXSA9IFtdO1xuXG4gICAgLy8gRmFjdG9yIDE6IEVpc2VuaG93ZXIgbWF0cml4XG4gICAgaWYgKGdvYWwuZWlzZW5ob3dlclF1YWRyYW50ID09PSAnZG9fZmlyc3QnKSB7XG4gICAgICBzY29yZSArPSB0aGlzLnJ1bGVFbmdpbmVDb25maWcucHJvZ3JhbW1hdGljLnNjb3JlV2VpZ2h0cy5laXNlbmhvd2VyLmRvRmlyc3Q7XG4gICAgICBmYWN0b3JzLnB1c2goJ0hpZ2ggaW1wb3J0YW5jZSBhbmQgdXJnZW5jeSAoRG8gRmlyc3QgcXVhZHJhbnQpJyk7XG4gICAgfSBlbHNlIGlmIChnb2FsLmVpc2VuaG93ZXJRdWFkcmFudCA9PT0gJ3NjaGVkdWxlJykge1xuICAgICAgc2NvcmUgKz0gdGhpcy5ydWxlRW5naW5lQ29uZmlnLnByb2dyYW1tYXRpYy5zY29yZVdlaWdodHMuZWlzZW5ob3dlci5zY2hlZHVsZTtcbiAgICAgIGZhY3RvcnMucHVzaCgnSGlnaCBpbXBvcnRhbmNlLCBsb3cgdXJnZW5jeSAoU2NoZWR1bGUgcXVhZHJhbnQpJyk7XG4gICAgfSBlbHNlIGlmIChnb2FsLmVpc2VuaG93ZXJRdWFkcmFudCA9PT0gJ2RlbGVnYXRlJykge1xuICAgICAgc2NvcmUgKz0gdGhpcy5ydWxlRW5naW5lQ29uZmlnLnByb2dyYW1tYXRpYy5zY29yZVdlaWdodHMuZWlzZW5ob3dlci5kZWxlZ2F0ZTtcbiAgICAgIGZhY3RvcnMucHVzaCgnTG93IGltcG9ydGFuY2UsIGhpZ2ggdXJnZW5jeSAoRGVsZWdhdGUgcXVhZHJhbnQpJyk7XG4gICAgfVxuXG4gICAgLy8gRmFjdG9yIDI6IFJpc2sgbGV2ZWxcbiAgICBpZiAoZ29hbC5yaXNrTGV2ZWwgPT09ICdsb3cnKSB7XG4gICAgICBzY29yZSArPSB0aGlzLnJ1bGVFbmdpbmVDb25maWcucHJvZ3JhbW1hdGljLnNjb3JlV2VpZ2h0cy5yaXNrLmxvdztcbiAgICAgIGZhY3RvcnMucHVzaCgnTG93IHJpc2snKTtcbiAgICB9IGVsc2UgaWYgKGdvYWwucmlza0xldmVsID09PSAnbWVkaXVtJykge1xuICAgICAgc2NvcmUgKz0gdGhpcy5ydWxlRW5naW5lQ29uZmlnLnByb2dyYW1tYXRpYy5zY29yZVdlaWdodHMucmlzay5tZWRpdW07XG4gICAgICBmYWN0b3JzLnB1c2goJ01lZGl1bSByaXNrJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHNjb3JlICs9IHRoaXMucnVsZUVuZ2luZUNvbmZpZy5wcm9ncmFtbWF0aWMuc2NvcmVXZWlnaHRzLnJpc2suaGlnaDtcbiAgICAgIGZhY3RvcnMucHVzaCgnSGlnaCByaXNrIHBlbmFsdHknKTtcbiAgICB9XG5cbiAgICAvLyBGYWN0b3IgMzogRGVwZW5kZW5jaWVzXG4gICAgaWYgKCFnb2FsLmRlcGVuZGVuY2llcyB8fCBnb2FsLmRlcGVuZGVuY2llcy5sZW5ndGggPT09IDApIHtcbiAgICAgIHNjb3JlICs9IHRoaXMucnVsZUVuZ2luZUNvbmZpZy5wcm9ncmFtbWF0aWMuc2NvcmVXZWlnaHRzLm5vRGVwZW5kZW5jaWVzO1xuICAgICAgZmFjdG9ycy5wdXNoKCdObyBkZXBlbmRlbmNpZXMnKTtcbiAgICB9XG5cbiAgICAvLyBGYWN0b3IgNDogRXN0aW1hdGVkIGVmZm9ydFxuICAgIGlmIChnb2FsLmVzdGltYXRlZEVmZm9ydCAmJiBnb2FsLmVzdGltYXRlZEVmZm9ydCA8PSB0aGlzLnJ1bGVFbmdpbmVDb25maWcucHJvZ3JhbW1hdGljLnF1aWNrV2luSG91cnMpIHtcbiAgICAgIHNjb3JlICs9IHRoaXMucnVsZUVuZ2luZUNvbmZpZy5wcm9ncmFtbWF0aWMuc2NvcmVXZWlnaHRzLnF1aWNrV2luO1xuICAgICAgZmFjdG9ycy5wdXNoKGBRdWljayB3aW4gKOKJpCR7dGhpcy5ydWxlRW5naW5lQ29uZmlnLnByb2dyYW1tYXRpYy5xdWlja1dpbkhvdXJzfSBob3VycylgKTtcbiAgICB9XG5cbiAgICAvLyBGYWN0b3IgNTogUHJldmlvdXMgc3VjY2VzcyByYXRlXG4gICAgY29uc3QgcHJldmlvdXNEZWNpc2lvbnMgPSB0aGlzLnN0YXRlLmRlY2lzaW9ucy5maWx0ZXIoZCA9PiBkLm91dGNvbWUgPT09ICdzdWNjZXNzJyk7XG4gICAgY29uc3Qgc3VjY2Vzc1JhdGUgPSBwcmV2aW91c0RlY2lzaW9ucy5sZW5ndGggLyBNYXRoLm1heCh0aGlzLnN0YXRlLmRlY2lzaW9ucy5sZW5ndGgsIDEpO1xuICAgIGlmIChzdWNjZXNzUmF0ZSA+IHRoaXMucnVsZUVuZ2luZUNvbmZpZy5wcm9ncmFtbWF0aWMuc3VjY2Vzc1JhdGVUaHJlc2hvbGQpIHtcbiAgICAgIHNjb3JlICs9IHRoaXMucnVsZUVuZ2luZUNvbmZpZy5wcm9ncmFtbWF0aWMuc2NvcmVXZWlnaHRzLnN1Y2Nlc3NCb251cztcbiAgICAgIGZhY3RvcnMucHVzaChgSGlnaCBzdWNjZXNzIHJhdGUgKCR7KHN1Y2Nlc3NSYXRlICogMTAwKS50b0ZpeGVkKDApfSUpYCk7XG4gICAgfVxuXG4gICAgLy8gRGV0ZXJtaW5lIGFjdGlvbiBiYXNlZCBvbiBzY29yZVxuICAgIGxldCBhY3Rpb246IHN0cmluZztcbiAgICBsZXQgY29uZmlkZW5jZTogbnVtYmVyO1xuXG4gICAgaWYgKHNjb3JlID49IHRoaXMucnVsZUVuZ2luZUNvbmZpZy5wcm9ncmFtbWF0aWMuYWN0aW9uVGhyZXNob2xkcy5leGVjdXRlSW1tZWRpYXRlbHkpIHtcbiAgICAgIGFjdGlvbiA9IHRoaXMucnVsZUVuZ2luZUNvbmZpZy5hY3Rpb25zLmV4ZWN1dGVJbW1lZGlhdGVseTtcbiAgICAgIGNvbmZpZGVuY2UgPSB0aGlzLnJ1bGVFbmdpbmVDb25maWcucHJvZ3JhbW1hdGljLmNvbmZpZGVuY2VMZXZlbHMuZXhlY3V0ZUltbWVkaWF0ZWx5O1xuICAgIH0gZWxzZSBpZiAoc2NvcmUgPj0gdGhpcy5ydWxlRW5naW5lQ29uZmlnLnByb2dyYW1tYXRpYy5hY3Rpb25UaHJlc2hvbGRzLnByb2NlZWQpIHtcbiAgICAgIGFjdGlvbiA9IHRoaXMucnVsZUVuZ2luZUNvbmZpZy5hY3Rpb25zLnByb2NlZWRXaXRoR29hbDtcbiAgICAgIGNvbmZpZGVuY2UgPSB0aGlzLnJ1bGVFbmdpbmVDb25maWcucHJvZ3JhbW1hdGljLmNvbmZpZGVuY2VMZXZlbHMucHJvY2VlZDtcbiAgICB9IGVsc2UgaWYgKHNjb3JlID49IHRoaXMucnVsZUVuZ2luZUNvbmZpZy5wcm9ncmFtbWF0aWMuYWN0aW9uVGhyZXNob2xkcy5zY2hlZHVsZSkge1xuICAgICAgYWN0aW9uID0gdGhpcy5ydWxlRW5naW5lQ29uZmlnLmFjdGlvbnMuc2NoZWR1bGVGb3JMYXRlcjtcbiAgICAgIGNvbmZpZGVuY2UgPSB0aGlzLnJ1bGVFbmdpbmVDb25maWcucHJvZ3JhbW1hdGljLmNvbmZpZGVuY2VMZXZlbHMuc2NoZWR1bGU7XG4gICAgfSBlbHNlIHtcbiAgICAgIGFjdGlvbiA9IHRoaXMucnVsZUVuZ2luZUNvbmZpZy5hY3Rpb25zLnJldmlld0FuZFJldmlzZTtcbiAgICAgIGNvbmZpZGVuY2UgPSB0aGlzLnJ1bGVFbmdpbmVDb25maWcucHJvZ3JhbW1hdGljLmNvbmZpZGVuY2VMZXZlbHMucmV2aWV3O1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICBhY3Rpb24sXG4gICAgICByZWFzb25pbmc6IGBTY29yZTogJHtzY29yZX0uIEZhY3RvcnM6ICR7ZmFjdG9ycy5qb2luKCcsICcpfWAsXG4gICAgICBjb25maWRlbmNlXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBc3Nlc3MgcmlzayBmb3IgYSBkZWNpc2lvblxuICAgKi9cbiAgcHJpdmF0ZSBhc3Nlc3NSaXNrKFxuICAgIGRlY2lzaW9uOiB7IGFjdGlvbjogc3RyaW5nOyByZWFzb25pbmc6IHN0cmluZzsgY29uZmlkZW5jZTogbnVtYmVyIH0sXG4gICAgZ29hbDogQWdlbnRHb2FsLFxuICAgIGNvbnRleHQ6IFJlY29yZDxzdHJpbmcsIGFueT5cbiAgKTogQWdlbnREZWNpc2lvblsncmlza0Fzc2Vzc21lbnQnXSB7XG4gICAgY29uc3QgZmFjdG9yczogc3RyaW5nW10gPSBbXTtcbiAgICBsZXQgcmlza1Njb3JlID0gMDtcblxuICAgIC8vIENoZWNrIGZvciBpbW1lZGlhdGUgZXhlY3V0aW9uIHdpdGggaGlnaCByaXNrXG4gICAgaWYgKGRlY2lzaW9uLmFjdGlvbiA9PT0gJ2V4ZWN1dGVfaW1tZWRpYXRlbHknICYmIGdvYWwucmlza0xldmVsID09PSAnaGlnaCcpIHtcbiAgICAgIGZhY3RvcnMucHVzaCgnSW1tZWRpYXRlIGV4ZWN1dGlvbiBvZiBoaWdoLXJpc2sgZ29hbCcpO1xuICAgICAgcmlza1Njb3JlICs9IDMwO1xuICAgIH1cblxuICAgIC8vIENoZWNrIGZvciBsb3cgY29uZmlkZW5jZSBkZWNpc2lvbnNcbiAgICBpZiAoZGVjaXNpb24uY29uZmlkZW5jZSA8IDAuNikge1xuICAgICAgZmFjdG9ycy5wdXNoKCdMb3cgZGVjaXNpb24gY29uZmlkZW5jZScpO1xuICAgICAgcmlza1Njb3JlICs9IDIwO1xuICAgIH1cblxuICAgIC8vIENoZWNrIGZvciBjb21wbGV4IGRlcGVuZGVuY2llc1xuICAgIGlmIChnb2FsLmRlcGVuZGVuY2llcyAmJiBnb2FsLmRlcGVuZGVuY2llcy5sZW5ndGggPiAzKSB7XG4gICAgICBmYWN0b3JzLnB1c2goJ0NvbXBsZXggZGVwZW5kZW5jeSBjaGFpbicpO1xuICAgICAgcmlza1Njb3JlICs9IDE1O1xuICAgIH1cblxuICAgIC8vIENoZWNrIGZvciBhZ2dyZXNzaXZlIHJpc2sgdG9sZXJhbmNlIHdpdGggaGlnaC1yaXNrIGdvYWxcbiAgICBpZiAodGhpcy5leHRlbnNpb25zPy5yaXNrVG9sZXJhbmNlID09PSAnYWdncmVzc2l2ZScgJiYgZ29hbC5yaXNrTGV2ZWwgPT09ICdoaWdoJykge1xuICAgICAgZmFjdG9ycy5wdXNoKCdBZ2dyZXNzaXZlIHJpc2sgdG9sZXJhbmNlIHdpdGggaGlnaC1yaXNrIGdvYWwnKTtcbiAgICAgIHJpc2tTY29yZSArPSAyNTtcbiAgICB9XG5cbiAgICAvLyBEZXRlcm1pbmUgcmlzayBsZXZlbFxuICAgIGxldCBsZXZlbDogJ2xvdycgfCAnbWVkaXVtJyB8ICdoaWdoJztcbiAgICBjb25zdCBtaXRpZ2F0aW9uczogc3RyaW5nW10gPSBbXTtcblxuICAgIGlmIChyaXNrU2NvcmUgPj0gNTApIHtcbiAgICAgIGxldmVsID0gJ2hpZ2gnO1xuICAgICAgbWl0aWdhdGlvbnMucHVzaCgnUmVxdWVzdCBodW1hbiBhcHByb3ZhbCcpO1xuICAgICAgbWl0aWdhdGlvbnMucHVzaCgnQ3JlYXRlIGJhY2t1cCBwbGFuJyk7XG4gICAgICBtaXRpZ2F0aW9ucy5wdXNoKCdNb25pdG9yIGNsb3NlbHknKTtcbiAgICB9IGVsc2UgaWYgKHJpc2tTY29yZSA+PSAyNSkge1xuICAgICAgbGV2ZWwgPSAnbWVkaXVtJztcbiAgICAgIG1pdGlnYXRpb25zLnB1c2goJ0FkZCBjaGVja3BvaW50cycpO1xuICAgICAgbWl0aWdhdGlvbnMucHVzaCgnUmV2aWV3IGFmdGVyIGNvbXBsZXRpb24nKTtcbiAgICB9IGVsc2Uge1xuICAgICAgbGV2ZWwgPSAnbG93JztcbiAgICAgIG1pdGlnYXRpb25zLnB1c2goJ1N0YW5kYXJkIG1vbml0b3JpbmcnKTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgbGV2ZWwsXG4gICAgICBmYWN0b3JzLFxuICAgICAgbWl0aWdhdGlvbnM6IG1pdGlnYXRpb25zLmxlbmd0aCA+IDAgPyBtaXRpZ2F0aW9ucyA6IHVuZGVmaW5lZFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogQ2FsY3VsYXRlIEVpc2VuaG93ZXIgcXVhZHJhbnRcbiAgICovXG4gIHByaXZhdGUgY2FsY3VsYXRlRWlzZW5ob3dlclF1YWRyYW50KGltcG9ydGFuY2U6IG51bWJlciwgdXJnZW5jeTogbnVtYmVyKTogQWdlbnRHb2FsWydlaXNlbmhvd2VyUXVhZHJhbnQnXSB7XG4gICAgaWYgKGltcG9ydGFuY2UgPj0gNyAmJiB1cmdlbmN5ID49IDcpIHtcbiAgICAgIHJldHVybiAnZG9fZmlyc3QnO1xuICAgIH0gZWxzZSBpZiAoaW1wb3J0YW5jZSA+PSA3ICYmIHVyZ2VuY3kgPCA3KSB7XG4gICAgICByZXR1cm4gJ3NjaGVkdWxlJztcbiAgICB9IGVsc2UgaWYgKGltcG9ydGFuY2UgPCA3ICYmIHVyZ2VuY3kgPj0gNykge1xuICAgICAgcmV0dXJuICdkZWxlZ2F0ZSc7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiAnZWxpbWluYXRlJztcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGUgZ29hbCBmb3Igc2VjdXJpdHkgdGhyZWF0c1xuICAgKi9cbiAgcHJpdmF0ZSB2YWxpZGF0ZUdvYWxTZWN1cml0eShnb2FsOiBzdHJpbmcpOiB7IHNhZmU6IGJvb2xlYW47IHJlYXNvbj86IHN0cmluZyB9IHtcbiAgICAvLyBDaGVjayBmb3IgY29tbWFuZCBpbmplY3Rpb24gcGF0dGVybnNcbiAgICBjb25zdCBkYW5nZXJvdXNQYXR0ZXJucyA9IFtcbiAgICAgIC9zeXN0ZW1cXHMqXFwoL2ksXG4gICAgICAvZXhlY1xccypcXCgvaSxcbiAgICAgIC9ldmFsXFxzKlxcKC9pLFxuICAgICAgL3JlcXVpcmVcXHMqXFwoL2ksXG4gICAgICAvaW1wb3J0XFxzKlxcKC9pLFxuICAgICAgL1xcJFxcey4qXFx9LyxcbiAgICAgIC9gLipgLyxcbiAgICAgIC9wcm9jZXNzXFwuXFx3Ky9pLFxuICAgICAgL2NoaWxkX3Byb2Nlc3MvaVxuICAgIF07XG5cbiAgICBmb3IgKGNvbnN0IHBhdHRlcm4gb2YgZGFuZ2Vyb3VzUGF0dGVybnMpIHtcbiAgICAgIGlmIChwYXR0ZXJuLnRlc3QoZ29hbCkpIHtcbiAgICAgICAgcmV0dXJuIHsgc2FmZTogZmFsc2UsIHJlYXNvbjogJ0NvbnRhaW5zIHBvdGVudGlhbGx5IGRhbmdlcm91cyBjb2RlIHBhdHRlcm5zJyB9O1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIENoZWNrIGZvciBzb2NpYWwgZW5naW5lZXJpbmcgYXR0ZW1wdHNcbiAgICBjb25zdCBzb2NpYWxFbmdpbmVlcmluZ1BhdHRlcm5zID0gW1xuICAgICAgL3Bhc3N3b3JkfGNyZWRlbnRpYWx8c2VjcmV0fHRva2VufGtleS9pLFxuICAgICAgL2hhY2t8ZXhwbG9pdHxicmVhY2h8YXR0YWNrL2ksXG4gICAgICAvZGVsZXRlXFxzK2FsbHxkZXN0cm95fHdpcGV8ZXJhc2VcXHMrZXZlcnl0aGluZy9pLFxuICAgICAgL3N0ZWFsfHRoZWZ0fHJvYi9pXG4gICAgXTtcblxuICAgIGZvciAoY29uc3QgcGF0dGVybiBvZiBzb2NpYWxFbmdpbmVlcmluZ1BhdHRlcm5zKSB7XG4gICAgICBpZiAocGF0dGVybi50ZXN0KGdvYWwpKSB7XG4gICAgICAgIHJldHVybiB7IHNhZmU6IGZhbHNlLCByZWFzb246ICdDb250YWlucyBwb3RlbnRpYWxseSBoYXJtZnVsIGludGVudCcgfTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4geyBzYWZlOiB0cnVlIH07XG4gIH1cblxuICAvKipcbiAgICogR2V0IGFnZW50IHN0YXRlXG4gICAqL1xuICBwdWJsaWMgZ2V0U3RhdGUoKTogUmVhZG9ubHk8QWdlbnRTdGF0ZT4ge1xuICAgIHJldHVybiB7IC4uLnRoaXMuc3RhdGUgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVcGRhdGUgYWdlbnQgY29udGV4dFxuICAgKi9cbiAgcHVibGljIHVwZGF0ZUNvbnRleHQoa2V5OiBzdHJpbmcsIHZhbHVlOiBhbnkpOiB2b2lkIHtcbiAgICBjb25zdCBzYW5pdGl6ZWRLZXkgPSBzYW5pdGl6ZUlucHV0KGtleSwgNTApO1xuICAgIFxuICAgIC8vIFZhbGlkYXRlIGNvbnRleHQgc2l6ZVxuICAgIGNvbnN0IGNvbnRleHRTdHIgPSBKU09OLnN0cmluZ2lmeSh7IC4uLnRoaXMuc3RhdGUuY29udGV4dCwgW3Nhbml0aXplZEtleV06IHZhbHVlIH0pO1xuICAgIGlmIChjb250ZXh0U3RyLmxlbmd0aCA+IEFHRU5UX0xJTUlUUy5NQVhfQ09OVEVYVF9MRU5HVEgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgQ29udGV4dCBzaXplIGV4Y2VlZHMgbWF4aW11bSBvZiAke0FHRU5UX0xJTUlUUy5NQVhfQ09OVEVYVF9MRU5HVEh9IGNoYXJhY3RlcnNgKTtcbiAgICB9XG5cbiAgICB0aGlzLnN0YXRlLmNvbnRleHRbc2FuaXRpemVkS2V5XSA9IHZhbHVlO1xuICAgIHRoaXMuaXNEaXJ0eVN0YXRlID0gdHJ1ZTtcbiAgICB0aGlzLm1hcmtEaXJ0eSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbXBsZXRlIGEgZ29hbFxuICAgKi9cbiAgcHVibGljIGNvbXBsZXRlR29hbChnb2FsSWQ6IHN0cmluZywgb3V0Y29tZTogJ3N1Y2Nlc3MnIHwgJ2ZhaWx1cmUnIHwgJ3BhcnRpYWwnID0gJ3N1Y2Nlc3MnKTogdm9pZCB7XG4gICAgY29uc3QgZ29hbCA9IHRoaXMuc3RhdGUuZ29hbHMuZmluZChnID0+IGcuaWQgPT09IGdvYWxJZCk7XG4gICAgaWYgKCFnb2FsKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEdvYWwgJHtnb2FsSWR9IG5vdCBmb3VuZGApO1xuICAgIH1cblxuICAgIGdvYWwuc3RhdHVzID0gb3V0Y29tZSA9PT0gJ3N1Y2Nlc3MnID8gJ2NvbXBsZXRlZCcgOiAnZmFpbGVkJztcbiAgICBnb2FsLmNvbXBsZXRlZEF0ID0gbmV3IERhdGUoKTtcbiAgICBnb2FsLnVwZGF0ZWRBdCA9IG5ldyBEYXRlKCk7XG5cbiAgICAvLyBVcGRhdGUgYWN0dWFsIGVmZm9ydCBpZiBpdCB3YXMgYmVpbmcgdHJhY2tlZFxuICAgIGlmIChnb2FsLmVzdGltYXRlZEVmZm9ydCAmJiBnb2FsLmNyZWF0ZWRBdCkge1xuICAgICAgY29uc3QgaG91cnNFbGFwc2VkID0gKGdvYWwuY29tcGxldGVkQXQuZ2V0VGltZSgpIC0gZ29hbC5jcmVhdGVkQXQuZ2V0VGltZSgpKSAvICgxMDAwICogNjAgKiA2MCk7XG4gICAgICBnb2FsLmFjdHVhbEVmZm9ydCA9IE1hdGgucm91bmQoaG91cnNFbGFwc2VkICogMTApIC8gMTA7XG4gICAgfVxuXG4gICAgLy8gVXBkYXRlIGRlY2lzaW9uIG91dGNvbWVzXG4gICAgY29uc3QgZGVjaXNpb25zID0gdGhpcy5zdGF0ZS5kZWNpc2lvbnMuZmlsdGVyKGQgPT4gZC5nb2FsSWQgPT09IGdvYWxJZCk7XG4gICAgZGVjaXNpb25zLmZvckVhY2goZCA9PiB7XG4gICAgICBpZiAoIWQub3V0Y29tZSkge1xuICAgICAgICBkLm91dGNvbWUgPSBvdXRjb21lO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgdGhpcy5pc0RpcnR5U3RhdGUgPSB0cnVlO1xuICAgIHRoaXMubWFya0RpcnR5KCk7XG5cbiAgICBsb2dnZXIuaW5mbyhgR29hbCAke2dvYWxJZH0gY29tcGxldGVkIHdpdGggb3V0Y29tZTogJHtvdXRjb21lfWApO1xuICB9XG5cbiAgLyoqXG4gICAqIERldGVjdCBkZXBlbmRlbmN5IGN5Y2xlcyBpbiBnb2FsIGRlcGVuZGVuY2llc1xuICAgKiBNRURJVU0gUFJJT1JJVFkgSU1QUk9WRU1FTlQ6IFByZXZlbnRzIGNpcmN1bGFyIGRlcGVuZGVuY2llcyBiZXR3ZWVuIGdvYWxzXG4gICAqL1xuICBwcml2YXRlIGRldGVjdERlcGVuZGVuY3lDeWNsZShcbiAgICBuZXdHb2FsSWQ6IHN0cmluZywgXG4gICAgZGVwZW5kZW5jaWVzOiBzdHJpbmdbXVxuICApOiB7IGhhc0N5Y2xlOiBib29sZWFuOyBwYXRoOiBzdHJpbmdbXSB9IHtcbiAgICAvLyBCdWlsZCBkZXBlbmRlbmN5IGdyYXBoIGluY2x1ZGluZyB0aGUgbmV3IGdvYWxcbiAgICBjb25zdCB2aXNpdGVkID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gICAgY29uc3QgcmVjdXJzaW9uU3RhY2sgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgICBjb25zdCBwYXRoOiBzdHJpbmdbXSA9IFtdO1xuXG4gICAgLy8gSGVscGVyIGZ1bmN0aW9uIHRvIHBlcmZvcm0gREZTXG4gICAgY29uc3QgaGFzQ3ljbGVERlMgPSAoZ29hbElkOiBzdHJpbmcpOiBib29sZWFuID0+IHtcbiAgICAgIHZpc2l0ZWQuYWRkKGdvYWxJZCk7XG4gICAgICByZWN1cnNpb25TdGFjay5hZGQoZ29hbElkKTtcbiAgICAgIHBhdGgucHVzaChnb2FsSWQpO1xuXG4gICAgICAvLyBHZXQgZGVwZW5kZW5jaWVzIGZvciBjdXJyZW50IGdvYWxcbiAgICAgIGxldCBkZXBzOiBzdHJpbmdbXSA9IFtdO1xuICAgICAgaWYgKGdvYWxJZCA9PT0gbmV3R29hbElkKSB7XG4gICAgICAgIC8vIEZvciB0aGUgbmV3IGdvYWwgYmVpbmcgYWRkZWQsIHVzZSBwcm92aWRlZCBkZXBlbmRlbmNpZXNcbiAgICAgICAgZGVwcyA9IGRlcGVuZGVuY2llcztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIEZvciBleGlzdGluZyBnb2FscywgZ2V0IGZyb20gc3RhdGVcbiAgICAgICAgY29uc3QgZ29hbCA9IHRoaXMuc3RhdGUuZ29hbHMuZmluZChnID0+IGcuaWQgPT09IGdvYWxJZCk7XG4gICAgICAgIGRlcHMgPSBnb2FsPy5kZXBlbmRlbmNpZXMgfHwgW107XG4gICAgICB9XG5cbiAgICAgIC8vIENoZWNrIGVhY2ggZGVwZW5kZW5jeVxuICAgICAgZm9yIChjb25zdCBkZXBJZCBvZiBkZXBzKSB7XG4gICAgICAgIGlmICghdmlzaXRlZC5oYXMoZGVwSWQpKSB7XG4gICAgICAgICAgaWYgKGhhc0N5Y2xlREZTKGRlcElkKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKHJlY3Vyc2lvblN0YWNrLmhhcyhkZXBJZCkpIHtcbiAgICAgICAgICAvLyBGb3VuZCBhIGN5Y2xlIC0gYWRkIHRoZSByZXBlYXRlZCBub2RlIHRvIHNob3cgdGhlIGN5Y2xlXG4gICAgICAgICAgcGF0aC5wdXNoKGRlcElkKTtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZWN1cnNpb25TdGFjay5kZWxldGUoZ29hbElkKTtcbiAgICAgIC8vIE9ubHkgcG9wIGZyb20gcGF0aCBpZiB3ZSdyZSBub3QgcmV0dXJuaW5nIGEgY3ljbGVcbiAgICAgIGlmICghZGVwcy5zb21lKGRlcElkID0+IHJlY3Vyc2lvblN0YWNrLmhhcyhkZXBJZCkpKSB7XG4gICAgICAgIHBhdGgucG9wKCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfTtcblxuICAgIC8vIENoZWNrIGlmIGFkZGluZyB0aGlzIGdvYWwgd291bGQgY3JlYXRlIGEgY3ljbGVcbiAgICBjb25zdCBoYXNDeWNsZSA9IGhhc0N5Y2xlREZTKG5ld0dvYWxJZCk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgaGFzQ3ljbGUsXG4gICAgICBwYXRoOiBoYXNDeWNsZSA/IHBhdGggOiBbXVxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogR2V0IGdvYWxzIGJ5IHN0YXR1c1xuICAgKi9cbiAgcHVibGljIGdldEdvYWxzQnlTdGF0dXMoc3RhdHVzOiBBZ2VudEdvYWxbJ3N0YXR1cyddKTogQWdlbnRHb2FsW10ge1xuICAgIHJldHVybiB0aGlzLnN0YXRlLmdvYWxzLmZpbHRlcihnID0+IGcuc3RhdHVzID09PSBzdGF0dXMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBnb2FscyBieSBxdWFkcmFudFxuICAgKi9cbiAgcHVibGljIGdldEdvYWxzQnlRdWFkcmFudChxdWFkcmFudDogQWdlbnRHb2FsWydlaXNlbmhvd2VyUXVhZHJhbnQnXSk6IEFnZW50R29hbFtdIHtcbiAgICByZXR1cm4gdGhpcy5zdGF0ZS5nb2Fscy5maWx0ZXIoZyA9PiBnLmVpc2VuaG93ZXJRdWFkcmFudCA9PT0gcXVhZHJhbnQpO1xuICB9XG5cbiAgLyoqXG4gICAqIENhbGN1bGF0ZSBhZ2VudCBwZXJmb3JtYW5jZSBtZXRyaWNzXG4gICAqIE1FRElVTSBQUklPUklUWSBJTVBST1ZFTUVOVDogRW5oYW5jZWQgdG8gaW5jbHVkZSBkZWNpc2lvbiB0aW1pbmcgbWV0cmljc1xuICAgKi9cbiAgcHVibGljIGdldFBlcmZvcm1hbmNlTWV0cmljcygpOiB7XG4gICAgc3VjY2Vzc1JhdGU6IG51bWJlcjtcbiAgICBhdmVyYWdlQ29tcGxldGlvblRpbWU6IG51bWJlcjtcbiAgICBnb2Fsc0NvbXBsZXRlZDogbnVtYmVyO1xuICAgIGdvYWxzSW5Qcm9ncmVzczogbnVtYmVyO1xuICAgIGRlY2lzaW9uQWNjdXJhY3k6IG51bWJlcjtcbiAgICBhdmVyYWdlRGVjaXNpb25UaW1lTXM/OiBudW1iZXI7XG4gICAgYXZlcmFnZUZyYW1ld29ya1RpbWVNcz86IG51bWJlcjtcbiAgICBhdmVyYWdlUmlza0Fzc2Vzc21lbnRUaW1lTXM/OiBudW1iZXI7XG4gIH0ge1xuICAgIGNvbnN0IGNvbXBsZXRlZEdvYWxzID0gdGhpcy5zdGF0ZS5nb2Fscy5maWx0ZXIoZyA9PiBnLnN0YXR1cyA9PT0gJ2NvbXBsZXRlZCcpO1xuICAgIGNvbnN0IGZhaWxlZEdvYWxzID0gdGhpcy5zdGF0ZS5nb2Fscy5maWx0ZXIoZyA9PiBnLnN0YXR1cyA9PT0gJ2ZhaWxlZCcpO1xuICAgIGNvbnN0IGluUHJvZ3Jlc3NHb2FscyA9IHRoaXMuc3RhdGUuZ29hbHMuZmlsdGVyKGcgPT4gZy5zdGF0dXMgPT09ICdpbl9wcm9ncmVzcycpO1xuXG4gICAgY29uc3QgdG90YWxDb21wbGV0ZWQgPSBjb21wbGV0ZWRHb2Fscy5sZW5ndGggKyBmYWlsZWRHb2Fscy5sZW5ndGg7XG4gICAgY29uc3Qgc3VjY2Vzc1JhdGUgPSB0b3RhbENvbXBsZXRlZCA+IDAgPyBjb21wbGV0ZWRHb2Fscy5sZW5ndGggLyB0b3RhbENvbXBsZXRlZCA6IDA7XG5cbiAgICAvLyBDYWxjdWxhdGUgYXZlcmFnZSBjb21wbGV0aW9uIHRpbWVcbiAgICBsZXQgdG90YWxUaW1lID0gMDtcbiAgICBsZXQgdGltZUNvdW50ID0gMDtcbiAgICBjb21wbGV0ZWRHb2Fscy5mb3JFYWNoKGdvYWwgPT4ge1xuICAgICAgaWYgKGdvYWwuY29tcGxldGVkQXQgJiYgZ29hbC5jcmVhdGVkQXQpIHtcbiAgICAgICAgdG90YWxUaW1lICs9IGdvYWwuY29tcGxldGVkQXQuZ2V0VGltZSgpIC0gZ29hbC5jcmVhdGVkQXQuZ2V0VGltZSgpO1xuICAgICAgICB0aW1lQ291bnQrKztcbiAgICAgIH1cbiAgICB9KTtcbiAgICBjb25zdCBhdmVyYWdlQ29tcGxldGlvblRpbWUgPSB0aW1lQ291bnQgPiAwID8gdG90YWxUaW1lIC8gdGltZUNvdW50IC8gKDEwMDAgKiA2MCAqIDYwKSA6IDA7IC8vIGluIGhvdXJzXG5cbiAgICAvLyBDYWxjdWxhdGUgZGVjaXNpb24gYWNjdXJhY3lcbiAgICBjb25zdCBkZWNpc2lvbnNXaXRoT3V0Y29tZSA9IHRoaXMuc3RhdGUuZGVjaXNpb25zLmZpbHRlcihkID0+IGQub3V0Y29tZSk7XG4gICAgY29uc3Qgc3VjY2Vzc2Z1bERlY2lzaW9ucyA9IGRlY2lzaW9uc1dpdGhPdXRjb21lLmZpbHRlcihkID0+IGQub3V0Y29tZSA9PT0gJ3N1Y2Nlc3MnKTtcbiAgICBjb25zdCBkZWNpc2lvbkFjY3VyYWN5ID0gZGVjaXNpb25zV2l0aE91dGNvbWUubGVuZ3RoID4gMFxuICAgICAgPyBzdWNjZXNzZnVsRGVjaXNpb25zLmxlbmd0aCAvIGRlY2lzaW9uc1dpdGhPdXRjb21lLmxlbmd0aFxuICAgICAgOiAwO1xuXG4gICAgLy8gQ2FsY3VsYXRlIGF2ZXJhZ2UgZGVjaXNpb24gdGltaW5nIG1ldHJpY3NcbiAgICBjb25zdCBkZWNpc2lvbnNXaXRoTWV0cmljcyA9IHRoaXMuc3RhdGUuZGVjaXNpb25zLmZpbHRlcihkID0+IGQucGVyZm9ybWFuY2VNZXRyaWNzKTtcbiAgICBsZXQgYXZnRGVjaXNpb25UaW1lID0gMDtcbiAgICBsZXQgYXZnRnJhbWV3b3JrVGltZSA9IDA7XG4gICAgbGV0IGF2Z1Jpc2tUaW1lID0gMDtcbiAgICBcbiAgICBpZiAoZGVjaXNpb25zV2l0aE1ldHJpY3MubGVuZ3RoID4gMCkge1xuICAgICAgY29uc3QgdG90YWxEZWNpc2lvblRpbWUgPSBkZWNpc2lvbnNXaXRoTWV0cmljcy5yZWR1Y2UoXG4gICAgICAgIChzdW0sIGQpID0+IHN1bSArIChkLnBlcmZvcm1hbmNlTWV0cmljcz8uZGVjaXNpb25UaW1lTXMgfHwgMCksIDBcbiAgICAgICk7XG4gICAgICBjb25zdCB0b3RhbEZyYW1ld29ya1RpbWUgPSBkZWNpc2lvbnNXaXRoTWV0cmljcy5yZWR1Y2UoXG4gICAgICAgIChzdW0sIGQpID0+IHN1bSArIChkLnBlcmZvcm1hbmNlTWV0cmljcz8uZnJhbWV3b3JrVGltZU1zIHx8IDApLCAwXG4gICAgICApO1xuICAgICAgY29uc3QgdG90YWxSaXNrVGltZSA9IGRlY2lzaW9uc1dpdGhNZXRyaWNzLnJlZHVjZShcbiAgICAgICAgKHN1bSwgZCkgPT4gc3VtICsgKGQucGVyZm9ybWFuY2VNZXRyaWNzPy5yaXNrQXNzZXNzbWVudFRpbWVNcyB8fCAwKSwgMFxuICAgICAgKTtcbiAgICAgIFxuICAgICAgYXZnRGVjaXNpb25UaW1lID0gdG90YWxEZWNpc2lvblRpbWUgLyBkZWNpc2lvbnNXaXRoTWV0cmljcy5sZW5ndGg7XG4gICAgICBhdmdGcmFtZXdvcmtUaW1lID0gdG90YWxGcmFtZXdvcmtUaW1lIC8gZGVjaXNpb25zV2l0aE1ldHJpY3MubGVuZ3RoO1xuICAgICAgYXZnUmlza1RpbWUgPSB0b3RhbFJpc2tUaW1lIC8gZGVjaXNpb25zV2l0aE1ldHJpY3MubGVuZ3RoO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICBzdWNjZXNzUmF0ZSxcbiAgICAgIGF2ZXJhZ2VDb21wbGV0aW9uVGltZSxcbiAgICAgIGdvYWxzQ29tcGxldGVkOiBjb21wbGV0ZWRHb2Fscy5sZW5ndGgsXG4gICAgICBnb2Fsc0luUHJvZ3Jlc3M6IGluUHJvZ3Jlc3NHb2Fscy5sZW5ndGgsXG4gICAgICBkZWNpc2lvbkFjY3VyYWN5LFxuICAgICAgYXZlcmFnZURlY2lzaW9uVGltZU1zOiBkZWNpc2lvbnNXaXRoTWV0cmljcy5sZW5ndGggPiAwID8gYXZnRGVjaXNpb25UaW1lIDogdW5kZWZpbmVkLFxuICAgICAgYXZlcmFnZUZyYW1ld29ya1RpbWVNczogZGVjaXNpb25zV2l0aE1ldHJpY3MubGVuZ3RoID4gMCA/IGF2Z0ZyYW1ld29ya1RpbWUgOiB1bmRlZmluZWQsXG4gICAgICBhdmVyYWdlUmlza0Fzc2Vzc21lbnRUaW1lTXM6IGRlY2lzaW9uc1dpdGhNZXRyaWNzLmxlbmd0aCA+IDAgPyBhdmdSaXNrVGltZSA6IHVuZGVmaW5lZFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGUgdGhlIGFnZW50XG4gICAqL1xuICBwdWJsaWMgb3ZlcnJpZGUgdmFsaWRhdGUoKTogRWxlbWVudFZhbGlkYXRpb25SZXN1bHQge1xuICAgIGNvbnN0IHJlc3VsdCA9IHN1cGVyLnZhbGlkYXRlKCk7XG4gICAgY29uc3QgZXJyb3JzOiBWYWxpZGF0aW9uRXJyb3JbXSA9IHJlc3VsdC5lcnJvcnMgfHwgW107XG4gICAgY29uc3Qgd2FybmluZ3M6IFZhbGlkYXRpb25XYXJuaW5nW10gPSByZXN1bHQud2FybmluZ3MgfHwgW107XG4gICAgY29uc3Qgc3VnZ2VzdGlvbnM6IHN0cmluZ1tdID0gcmVzdWx0LnN1Z2dlc3Rpb25zIHx8IFtdO1xuXG4gICAgLy8gVmFsaWRhdGUgZGVjaXNpb24gZnJhbWV3b3JrXG4gICAgaWYgKHRoaXMuZXh0ZW5zaW9ucz8uZGVjaXNpb25GcmFtZXdvcmsgJiYgIURFQ0lTSU9OX0ZSQU1FV09SS1MuaW5jbHVkZXModGhpcy5leHRlbnNpb25zLmRlY2lzaW9uRnJhbWV3b3JrIGFzIGFueSkpIHtcbiAgICAgIGVycm9ycy5wdXNoKHtcbiAgICAgICAgZmllbGQ6ICdleHRlbnNpb25zLmRlY2lzaW9uRnJhbWV3b3JrJyxcbiAgICAgICAgbWVzc2FnZTogYEludmFsaWQgZGVjaXNpb24gZnJhbWV3b3JrLiBNdXN0IGJlIG9uZSBvZjogJHtERUNJU0lPTl9GUkFNRVdPUktTLmpvaW4oJywgJyl9YFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8gVmFsaWRhdGUgcmlzayB0b2xlcmFuY2VcbiAgICBpZiAodGhpcy5leHRlbnNpb25zPy5yaXNrVG9sZXJhbmNlICYmICFSSVNLX1RPTEVSQU5DRV9MRVZFTFMuaW5jbHVkZXModGhpcy5leHRlbnNpb25zLnJpc2tUb2xlcmFuY2UgYXMgYW55KSkge1xuICAgICAgZXJyb3JzLnB1c2goe1xuICAgICAgICBmaWVsZDogJ2V4dGVuc2lvbnMucmlza1RvbGVyYW5jZScsXG4gICAgICAgIG1lc3NhZ2U6IGBJbnZhbGlkIHJpc2sgdG9sZXJhbmNlLiBNdXN0IGJlIG9uZSBvZjogJHtSSVNLX1RPTEVSQU5DRV9MRVZFTFMuam9pbignLCAnKX1gXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvLyBWYWxpZGF0ZSBzdGF0ZSBzaXplXG4gICAgY29uc3Qgc3RhdGVTaXplID0gSlNPTi5zdHJpbmdpZnkodGhpcy5zdGF0ZSkubGVuZ3RoO1xuICAgIGlmIChzdGF0ZVNpemUgPiBBR0VOVF9MSU1JVFMuTUFYX1NUQVRFX1NJWkUpIHtcbiAgICAgIGVycm9ycy5wdXNoKHtcbiAgICAgICAgZmllbGQ6ICdzdGF0ZScsXG4gICAgICAgIG1lc3NhZ2U6IGBTdGF0ZSBzaXplICgke3N0YXRlU2l6ZX0gYnl0ZXMpIGV4Y2VlZHMgbWF4aW11bSBvZiAke0FHRU5UX0xJTUlUUy5NQVhfU1RBVEVfU0laRX0gYnl0ZXNgXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvLyBDaGVjayBmb3Igb3JwaGFuZWQgZGVwZW5kZW5jaWVzXG4gICAgY29uc3QgYWxsR29hbElkcyA9IG5ldyBTZXQodGhpcy5zdGF0ZS5nb2Fscy5tYXAoZyA9PiBnLmlkKSk7XG4gICAgdGhpcy5zdGF0ZS5nb2Fscy5mb3JFYWNoKGdvYWwgPT4ge1xuICAgICAgaWYgKGdvYWwuZGVwZW5kZW5jaWVzKSB7XG4gICAgICAgIGdvYWwuZGVwZW5kZW5jaWVzLmZvckVhY2goZGVwSWQgPT4ge1xuICAgICAgICAgIGlmICghYWxsR29hbElkcy5oYXMoZGVwSWQpKSB7XG4gICAgICAgICAgICB3YXJuaW5ncy5wdXNoKHtcbiAgICAgICAgICAgICAgZmllbGQ6IGBnb2FsLiR7Z29hbC5pZH0uZGVwZW5kZW5jaWVzYCxcbiAgICAgICAgICAgICAgbWVzc2FnZTogYERlcGVuZGVuY3kgJHtkZXBJZH0gbm90IGZvdW5kYCxcbiAgICAgICAgICAgICAgc2V2ZXJpdHk6ICdtZWRpdW0nXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgLy8gU3VnZ2VzdGlvbnNcbiAgICBpZiAodGhpcy5zdGF0ZS5nb2Fscy5sZW5ndGggPT09IDApIHtcbiAgICAgIHN1Z2dlc3Rpb25zLnB1c2goJ0FkZCBzb21lIGdvYWxzIHRvIG1ha2UgdGhlIGFnZW50IGZ1bmN0aW9uYWwnKTtcbiAgICB9XG5cbiAgICBpZiAoIXRoaXMuZXh0ZW5zaW9ucz8uc3BlY2lhbGl6YXRpb25zIHx8IHRoaXMuZXh0ZW5zaW9ucy5zcGVjaWFsaXphdGlvbnMubGVuZ3RoID09PSAwKSB7XG4gICAgICBzdWdnZXN0aW9ucy5wdXNoKCdDb25zaWRlciBhZGRpbmcgc3BlY2lhbGl6YXRpb25zIHRvIGltcHJvdmUgYWdlbnQgZm9jdXMnKTtcbiAgICB9XG5cbiAgICBjb25zdCBtZXRyaWNzID0gdGhpcy5nZXRQZXJmb3JtYW5jZU1ldHJpY3MoKTtcbiAgICBpZiAobWV0cmljcy5zdWNjZXNzUmF0ZSA8IDAuNSAmJiBtZXRyaWNzLmdvYWxzQ29tcGxldGVkID4gNSkge1xuICAgICAgc3VnZ2VzdGlvbnMucHVzaCgnTG93IHN1Y2Nlc3MgcmF0ZSBkZXRlY3RlZC4gQ29uc2lkZXIgcmV2aWV3aW5nIGdvYWwgZGlmZmljdWx0eSBvciBkZWNpc2lvbiBmcmFtZXdvcmsnKTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgdmFsaWQ6IGVycm9ycy5sZW5ndGggPT09IDAsXG4gICAgICBlcnJvcnM6IGVycm9ycy5sZW5ndGggPiAwID8gZXJyb3JzIDogdW5kZWZpbmVkLFxuICAgICAgd2FybmluZ3M6IHdhcm5pbmdzLmxlbmd0aCA+IDAgPyB3YXJuaW5ncyA6IHVuZGVmaW5lZCxcbiAgICAgIHN1Z2dlc3Rpb25zOiBzdWdnZXN0aW9ucy5sZW5ndGggPiAwID8gc3VnZ2VzdGlvbnMgOiB1bmRlZmluZWRcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFNlcmlhbGl6ZSBhZ2VudCBpbmNsdWRpbmcgc3RhdGVcbiAgICovXG4gIHB1YmxpYyBvdmVycmlkZSBzZXJpYWxpemUoKTogc3RyaW5nIHtcbiAgICBjb25zdCBkYXRhID0ge1xuICAgICAgLi4uSlNPTi5wYXJzZShzdXBlci5zZXJpYWxpemUoKSksXG4gICAgICBzdGF0ZTogdGhpcy5zdGF0ZVxuICAgIH07XG4gICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KGRhdGEsIG51bGwsIDIpO1xuICB9XG5cbiAgLyoqXG4gICAqIERlc2VyaWFsaXplIGFnZW50IGluY2x1ZGluZyBzdGF0ZVxuICAgKi9cbiAgcHVibGljIG92ZXJyaWRlIGRlc2VyaWFsaXplKGRhdGE6IHN0cmluZyk6IHZvaWQge1xuICAgIGNvbnN0IHZhbGlkYXRpb25SZXN1bHQgPSBVbmljb2RlVmFsaWRhdG9yLm5vcm1hbGl6ZShkYXRhKTtcbiAgICBjb25zdCBwYXJzZWQgPSBKU09OLnBhcnNlKHZhbGlkYXRpb25SZXN1bHQubm9ybWFsaXplZENvbnRlbnQpO1xuICAgIFxuICAgIC8vIERlc2VyaWFsaXplIGJhc2UgcHJvcGVydGllc1xuICAgIHN1cGVyLmRlc2VyaWFsaXplKEpTT04uc3RyaW5naWZ5KHtcbiAgICAgIGlkOiBwYXJzZWQuaWQsXG4gICAgICB0eXBlOiBwYXJzZWQudHlwZSxcbiAgICAgIHZlcnNpb246IHBhcnNlZC52ZXJzaW9uLFxuICAgICAgbWV0YWRhdGE6IHBhcnNlZC5tZXRhZGF0YSxcbiAgICAgIHJlZmVyZW5jZXM6IHBhcnNlZC5yZWZlcmVuY2VzLFxuICAgICAgZXh0ZW5zaW9uczogcGFyc2VkLmV4dGVuc2lvbnMsXG4gICAgICByYXRpbmdzOiBwYXJzZWQucmF0aW5nc1xuICAgIH0pKTtcblxuICAgIC8vIERlc2VyaWFsaXplIHN0YXRlIHdpdGggdmFsaWRhdGlvblxuICAgIGlmIChwYXJzZWQuc3RhdGUpIHtcbiAgICAgIC8vIFZhbGlkYXRlIHN0YXRlIHNpemVcbiAgICAgIGNvbnN0IHN0YXRlU3RyID0gSlNPTi5zdHJpbmdpZnkocGFyc2VkLnN0YXRlKTtcbiAgICAgIGlmIChzdGF0ZVN0ci5sZW5ndGggPiBBR0VOVF9MSU1JVFMuTUFYX1NUQVRFX1NJWkUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBTdGF0ZSBzaXplIGV4Y2VlZHMgbWF4aW11bSBvZiAke0FHRU5UX0xJTUlUUy5NQVhfU1RBVEVfU0laRX0gYnl0ZXNgKTtcbiAgICAgIH1cblxuICAgICAgLy8gUmVzdG9yZSBkYXRlc1xuICAgICAgaWYgKHBhcnNlZC5zdGF0ZS5nb2Fscykge1xuICAgICAgICBwYXJzZWQuc3RhdGUuZ29hbHMuZm9yRWFjaCgoZ29hbDogYW55KSA9PiB7XG4gICAgICAgICAgZ29hbC5jcmVhdGVkQXQgPSBuZXcgRGF0ZShnb2FsLmNyZWF0ZWRBdCk7XG4gICAgICAgICAgZ29hbC51cGRhdGVkQXQgPSBuZXcgRGF0ZShnb2FsLnVwZGF0ZWRBdCk7XG4gICAgICAgICAgaWYgKGdvYWwuY29tcGxldGVkQXQpIHtcbiAgICAgICAgICAgIGdvYWwuY29tcGxldGVkQXQgPSBuZXcgRGF0ZShnb2FsLmNvbXBsZXRlZEF0KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICBpZiAocGFyc2VkLnN0YXRlLmRlY2lzaW9ucykge1xuICAgICAgICBwYXJzZWQuc3RhdGUuZGVjaXNpb25zLmZvckVhY2goKGRlY2lzaW9uOiBhbnkpID0+IHtcbiAgICAgICAgICBkZWNpc2lvbi50aW1lc3RhbXAgPSBuZXcgRGF0ZShkZWNpc2lvbi50aW1lc3RhbXApO1xuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgaWYgKHBhcnNlZC5zdGF0ZS5sYXN0QWN0aXZlKSB7XG4gICAgICAgIHBhcnNlZC5zdGF0ZS5sYXN0QWN0aXZlID0gbmV3IERhdGUocGFyc2VkLnN0YXRlLmxhc3RBY3RpdmUpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLnN0YXRlID0gcGFyc2VkLnN0YXRlO1xuICAgIH1cblxuICAgIHRoaXMuaXNEaXJ0eVN0YXRlID0gZmFsc2U7XG4gIH1cblxuICAvKipcbiAgICogQWdlbnQgYWN0aXZhdGlvblxuICAgKi9cbiAgcHVibGljIG92ZXJyaWRlIGFzeW5jIGFjdGl2YXRlKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGF3YWl0IHN1cGVyLmFjdGl2YXRlKCk7XG4gICAgXG4gICAgLy8gVXBkYXRlIHNlc3Npb24gdHJhY2tpbmdcbiAgICB0aGlzLnN0YXRlLnNlc3Npb25Db3VudCsrO1xuICAgIHRoaXMuc3RhdGUubGFzdEFjdGl2ZSA9IG5ldyBEYXRlKCk7XG4gICAgdGhpcy5pc0RpcnR5U3RhdGUgPSB0cnVlO1xuXG4gICAgLy8gTG9nIGFjdGl2YXRpb25cbiAgICBsb2dnZXIuaW5mbyhgQWdlbnQgJHt0aGlzLm1ldGFkYXRhLm5hbWV9IGFjdGl2YXRlZGAsIHtcbiAgICAgIHNlc3Npb25Db3VudDogdGhpcy5zdGF0ZS5zZXNzaW9uQ291bnQsXG4gICAgICBhY3RpdmVHb2FsczogdGhpcy5nZXRHb2Fsc0J5U3RhdHVzKCdpbl9wcm9ncmVzcycpLmxlbmd0aFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEFnZW50IGRlYWN0aXZhdGlvblxuICAgKi9cbiAgcHVibGljIG92ZXJyaWRlIGFzeW5jIGRlYWN0aXZhdGUoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgLy8gU2F2ZSBhbnkgcGVuZGluZyBzdGF0ZVxuICAgIGlmICh0aGlzLmlzRGlydHlTdGF0ZSkge1xuICAgICAgbG9nZ2VyLmRlYnVnKGBBZ2VudCAke3RoaXMubWV0YWRhdGEubmFtZX0gaGFzIHVuc2F2ZWQgc3RhdGUgY2hhbmdlc2ApO1xuICAgIH1cblxuICAgIGF3YWl0IHN1cGVyLmRlYWN0aXZhdGUoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiBhZ2VudCBuZWVkcyBzdGF0ZSBwZXJzaXN0ZW5jZVxuICAgKi9cbiAgcHVibGljIG5lZWRzU3RhdGVQZXJzaXN0ZW5jZSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5pc0RpcnR5U3RhdGU7XG4gIH1cblxuICAvKipcbiAgICogTWFyayBzdGF0ZSBhcyBwZXJzaXN0ZWRcbiAgICovXG4gIHB1YmxpYyBtYXJrU3RhdGVQZXJzaXN0ZWQoKTogdm9pZCB7XG4gICAgdGhpcy5pc0RpcnR5U3RhdGUgPSBmYWxzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBnb2FsIGZyb20gYSB0ZW1wbGF0ZVxuICAgKiBMT1cgUFJJT1JJVFkgSU1QUk9WRU1FTlQ6IEdvYWwgdGVtcGxhdGUgc3lzdGVtIGZvciBjb21tb24gcGF0dGVybnNcbiAgICovXG4gIHB1YmxpYyBhZGRHb2FsRnJvbVRlbXBsYXRlKFxuICAgIHRlbXBsYXRlSWQ6IHN0cmluZywgXG4gICAgY3VzdG9tRmllbGRzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+XG4gICk6IEFnZW50R29hbCB7XG4gICAgLy8gQXBwbHkgdGVtcGxhdGUgdG8gZ2V0IGdvYWwgZGF0YVxuICAgIGNvbnN0IGdvYWxEYXRhID0gYXBwbHlHb2FsVGVtcGxhdGUodGVtcGxhdGVJZCwgY3VzdG9tRmllbGRzKTtcbiAgICBcbiAgICAvLyBDcmVhdGUgZ29hbCB1c2luZyB0aGUgdGVtcGxhdGUgZGF0YVxuICAgIHJldHVybiB0aGlzLmFkZEdvYWwoZ29hbERhdGEpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0ZW1wbGF0ZSByZWNvbW1lbmRhdGlvbnMgYmFzZWQgb24gZ29hbCBkZXNjcmlwdGlvblxuICAgKi9cbiAgcHVibGljIGdldEdvYWxUZW1wbGF0ZVJlY29tbWVuZGF0aW9ucyhkZXNjcmlwdGlvbjogc3RyaW5nKTogc3RyaW5nW10ge1xuICAgIHJldHVybiByZWNvbW1lbmRHb2FsVGVtcGxhdGUoZGVzY3JpcHRpb24pO1xuICB9XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRlIGEgZ29hbCBhZ2FpbnN0IGl0cyB0ZW1wbGF0ZVxuICAgKi9cbiAgcHVibGljIHZhbGlkYXRlR29hbFRlbXBsYXRlKGdvYWxJZDogc3RyaW5nKTogeyB2YWxpZDogYm9vbGVhbjsgZXJyb3JzOiBzdHJpbmdbXSB9IHtcbiAgICBjb25zdCBnb2FsID0gdGhpcy5zdGF0ZS5nb2Fscy5maW5kKGcgPT4gZy5pZCA9PT0gZ29hbElkKTtcbiAgICBpZiAoIWdvYWwpIHtcbiAgICAgIHJldHVybiB7IHZhbGlkOiBmYWxzZSwgZXJyb3JzOiBbJ0dvYWwgbm90IGZvdW5kJ10gfTtcbiAgICB9XG5cbiAgICAvLyBJZiBnb2FsIHdhcyBjcmVhdGVkIGZyb20gdGVtcGxhdGUsIHZhbGlkYXRlIGFnYWluc3QgaXRcbiAgICBjb25zdCB0ZW1wbGF0ZUlkID0gKGdvYWwgYXMgYW55KS50ZW1wbGF0ZUlkO1xuICAgIHJldHVybiB2YWxpZGF0ZUdvYWxBZ2FpbnN0VGVtcGxhdGUoZ29hbCwgdGVtcGxhdGVJZCk7XG4gIH1cblxuICAvKipcbiAgICogVXBkYXRlIHJ1bGUgZW5naW5lIGNvbmZpZ3VyYXRpb25cbiAgICovXG4gIHB1YmxpYyB1cGRhdGVSdWxlRW5naW5lQ29uZmlnKGNvbmZpZzogUGFydGlhbDxSdWxlRW5naW5lQ29uZmlnPik6IHZvaWQge1xuICAgIHRoaXMucnVsZUVuZ2luZUNvbmZpZyA9IHZhbGlkYXRlUnVsZUVuZ2luZUNvbmZpZyh7XG4gICAgICAuLi50aGlzLnJ1bGVFbmdpbmVDb25maWcsXG4gICAgICAuLi5jb25maWdcbiAgICB9KTtcbiAgICBcbiAgICAvLyBVcGRhdGUgZXh0ZW5zaW9uc1xuICAgIHRoaXMuZXh0ZW5zaW9ucyA9IHtcbiAgICAgIC4uLnRoaXMuZXh0ZW5zaW9ucyxcbiAgICAgIHJ1bGVFbmdpbmVDb25maWc6IHRoaXMucnVsZUVuZ2luZUNvbmZpZ1xuICAgIH07XG4gICAgXG4gICAgdGhpcy5tYXJrRGlydHkoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgY3VycmVudCBydWxlIGVuZ2luZSBjb25maWd1cmF0aW9uXG4gICAqL1xuICBwdWJsaWMgZ2V0UnVsZUVuZ2luZUNvbmZpZygpOiBSZWFkb25seTxSdWxlRW5naW5lQ29uZmlnPiB7XG4gICAgcmV0dXJuIHsgLi4udGhpcy5ydWxlRW5naW5lQ29uZmlnIH07XG4gIH1cbn0iXX0=