@dollhousemcp/mcp-server 1.5.1 → 1.6.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 (274) hide show
  1. package/CHANGELOG.md +90 -0
  2. package/README.md +497 -110
  3. package/data/agents/code-reviewer.md +8 -1
  4. package/data/agents/research-assistant.md +8 -1
  5. package/data/agents/task-manager.md +8 -1
  6. package/data/ensembles/business-advisor.md +8 -1
  7. package/data/ensembles/creative-studio.md +8 -1
  8. package/data/ensembles/development-team.md +8 -1
  9. package/data/ensembles/security-analysis-team.md +8 -1
  10. package/data/memories/conversation-history.md +8 -1
  11. package/data/memories/learning-progress.md +8 -1
  12. package/data/memories/project-context.md +8 -1
  13. package/data/personas/business-consultant.md +8 -1
  14. package/data/personas/creative-writer.md +8 -1
  15. package/data/personas/debug-detective.md +8 -1
  16. package/data/personas/eli5-explainer.md +8 -1
  17. package/data/personas/security-analyst.md +8 -1
  18. package/data/personas/technical-analyst.md +8 -1
  19. package/data/skills/code-review.md +8 -1
  20. package/data/skills/creative-writing.md +8 -1
  21. package/data/skills/data-analysis.md +8 -1
  22. package/data/skills/penetration-testing.md +8 -1
  23. package/data/skills/research.md +8 -1
  24. package/data/skills/threat-modeling.md +8 -1
  25. package/data/skills/translation.md +8 -1
  26. package/data/templates/code-documentation.md +8 -1
  27. package/data/templates/email-professional.md +8 -1
  28. package/data/templates/meeting-notes.md +8 -1
  29. package/data/templates/penetration-test-report.md +8 -1
  30. package/data/templates/project-brief.md +8 -1
  31. package/data/templates/report-executive.md +8 -1
  32. package/data/templates/security-vulnerability-report.md +8 -1
  33. package/data/templates/threat-assessment-report.md +8 -1
  34. package/dist/auth/GitHubAuthManager.d.ts +6 -1
  35. package/dist/auth/GitHubAuthManager.d.ts.map +1 -1
  36. package/dist/auth/GitHubAuthManager.js +45 -18
  37. package/dist/benchmarks/IndexPerformanceBenchmark.d.ts +98 -0
  38. package/dist/benchmarks/IndexPerformanceBenchmark.d.ts.map +1 -0
  39. package/dist/benchmarks/IndexPerformanceBenchmark.js +531 -0
  40. package/dist/cache/CollectionCache.d.ts +65 -0
  41. package/dist/cache/CollectionCache.d.ts.map +1 -0
  42. package/dist/cache/CollectionCache.js +172 -0
  43. package/dist/cache/CollectionIndexCache.d.ts +77 -0
  44. package/dist/cache/CollectionIndexCache.d.ts.map +1 -0
  45. package/dist/cache/CollectionIndexCache.js +349 -0
  46. package/dist/cache/LRUCache.d.ts +93 -0
  47. package/dist/cache/LRUCache.d.ts.map +1 -0
  48. package/dist/cache/LRUCache.js +299 -0
  49. package/dist/cache/index.d.ts +2 -0
  50. package/dist/cache/index.d.ts.map +1 -1
  51. package/dist/cache/index.js +3 -1
  52. package/dist/collection/CollectionBrowser.d.ts +44 -1
  53. package/dist/collection/CollectionBrowser.d.ts.map +1 -1
  54. package/dist/collection/CollectionBrowser.js +260 -28
  55. package/dist/collection/CollectionIndexManager.d.ts +151 -0
  56. package/dist/collection/CollectionIndexManager.d.ts.map +1 -0
  57. package/dist/collection/CollectionIndexManager.js +499 -0
  58. package/dist/collection/CollectionSearch.d.ts +75 -1
  59. package/dist/collection/CollectionSearch.d.ts.map +1 -1
  60. package/dist/collection/CollectionSearch.js +435 -6
  61. package/dist/collection/CollectionSeeder.d.ts +36 -0
  62. package/dist/collection/CollectionSeeder.d.ts.map +1 -0
  63. package/dist/collection/CollectionSeeder.js +267 -0
  64. package/dist/collection/ElementInstaller.d.ts +31 -0
  65. package/dist/collection/ElementInstaller.d.ts.map +1 -1
  66. package/dist/collection/ElementInstaller.js +77 -15
  67. package/dist/collection/PersonaSubmitter.d.ts +48 -1
  68. package/dist/collection/PersonaSubmitter.d.ts.map +1 -1
  69. package/dist/collection/PersonaSubmitter.js +170 -34
  70. package/dist/collection/index.d.ts +2 -0
  71. package/dist/collection/index.d.ts.map +1 -1
  72. package/dist/collection/index.js +3 -1
  73. package/dist/config/ConfigManager.d.ts +78 -0
  74. package/dist/config/ConfigManager.d.ts.map +1 -0
  75. package/dist/config/ConfigManager.js +216 -0
  76. package/dist/config/element-types.d.ts +135 -0
  77. package/dist/config/element-types.d.ts.map +1 -0
  78. package/dist/config/element-types.js +108 -0
  79. package/dist/config/index.d.ts +2 -0
  80. package/dist/config/index.d.ts.map +1 -1
  81. package/dist/config/index.js +3 -1
  82. package/dist/config/portfolio-constants.d.ts +83 -0
  83. package/dist/config/portfolio-constants.d.ts.map +1 -0
  84. package/dist/config/portfolio-constants.js +99 -0
  85. package/dist/elements/BaseElement.d.ts +14 -2
  86. package/dist/elements/BaseElement.d.ts.map +1 -1
  87. package/dist/elements/BaseElement.js +88 -6
  88. package/dist/elements/agents/Agent.d.ts +10 -1
  89. package/dist/elements/agents/Agent.d.ts.map +1 -1
  90. package/dist/elements/agents/Agent.js +66 -19
  91. package/dist/elements/agents/AgentManager.d.ts +2 -0
  92. package/dist/elements/agents/AgentManager.d.ts.map +1 -1
  93. package/dist/elements/agents/AgentManager.js +12 -10
  94. package/dist/elements/skills/Skill.d.ts +10 -1
  95. package/dist/elements/skills/Skill.d.ts.map +1 -1
  96. package/dist/elements/skills/Skill.js +40 -3
  97. package/dist/elements/skills/SkillManager.d.ts +1 -0
  98. package/dist/elements/skills/SkillManager.d.ts.map +1 -1
  99. package/dist/elements/skills/SkillManager.js +10 -4
  100. package/dist/elements/templates/Template.d.ts +10 -1
  101. package/dist/elements/templates/Template.d.ts.map +1 -1
  102. package/dist/elements/templates/Template.js +35 -18
  103. package/dist/elements/templates/TemplateManager.d.ts +1 -1
  104. package/dist/elements/templates/TemplateManager.d.ts.map +1 -1
  105. package/dist/elements/templates/TemplateManager.js +6 -5
  106. package/dist/generated/version.d.ts +2 -2
  107. package/dist/generated/version.js +3 -3
  108. package/dist/index.barrel.d.ts +1 -2
  109. package/dist/index.barrel.d.ts.map +1 -1
  110. package/dist/index.barrel.js +2 -4
  111. package/dist/index.d.ts +154 -25
  112. package/dist/index.d.ts.map +1 -1
  113. package/dist/index.js +1951 -264
  114. package/dist/persona/PersonaElement.d.ts +10 -0
  115. package/dist/persona/PersonaElement.d.ts.map +1 -1
  116. package/dist/persona/PersonaElement.js +55 -32
  117. package/dist/persona/PersonaElementManager.d.ts.map +1 -1
  118. package/dist/persona/PersonaElementManager.js +13 -11
  119. package/dist/persona/PersonaLoader.d.ts.map +1 -1
  120. package/dist/persona/PersonaLoader.js +8 -2
  121. package/dist/persona/export-import/PersonaImporter.d.ts.map +1 -1
  122. package/dist/persona/export-import/PersonaImporter.js +24 -5
  123. package/dist/persona/export-import/PersonaSharer.d.ts +21 -0
  124. package/dist/persona/export-import/PersonaSharer.d.ts.map +1 -1
  125. package/dist/persona/export-import/PersonaSharer.js +198 -22
  126. package/dist/portfolio/DefaultElementProvider.d.ts +90 -0
  127. package/dist/portfolio/DefaultElementProvider.d.ts.map +1 -1
  128. package/dist/portfolio/DefaultElementProvider.js +499 -7
  129. package/dist/portfolio/GitHubPortfolioIndexer.d.ts +129 -0
  130. package/dist/portfolio/GitHubPortfolioIndexer.d.ts.map +1 -0
  131. package/dist/portfolio/GitHubPortfolioIndexer.js +475 -0
  132. package/dist/portfolio/MigrationManager.d.ts.map +1 -1
  133. package/dist/portfolio/MigrationManager.js +136 -3
  134. package/dist/portfolio/PortfolioIndexManager.d.ts +130 -0
  135. package/dist/portfolio/PortfolioIndexManager.d.ts.map +1 -0
  136. package/dist/portfolio/PortfolioIndexManager.js +478 -0
  137. package/dist/portfolio/PortfolioManager.d.ts +5 -0
  138. package/dist/portfolio/PortfolioManager.d.ts.map +1 -1
  139. package/dist/portfolio/PortfolioManager.js +61 -20
  140. package/dist/portfolio/PortfolioRepoManager.d.ts +75 -0
  141. package/dist/portfolio/PortfolioRepoManager.d.ts.map +1 -0
  142. package/dist/portfolio/PortfolioRepoManager.js +337 -0
  143. package/dist/portfolio/UnifiedIndexManager.d.ts +388 -0
  144. package/dist/portfolio/UnifiedIndexManager.d.ts.map +1 -0
  145. package/dist/portfolio/UnifiedIndexManager.js +1434 -0
  146. package/dist/portfolio/index.d.ts +15 -0
  147. package/dist/portfolio/index.d.ts.map +1 -0
  148. package/dist/portfolio/index.js +15 -0
  149. package/dist/portfolio/types.d.ts +7 -0
  150. package/dist/portfolio/types.d.ts.map +1 -1
  151. package/dist/portfolio/types.js +6 -1
  152. package/dist/security/InputValidator.d.ts.map +1 -1
  153. package/dist/security/InputValidator.js +50 -48
  154. package/dist/security/audit/SecurityAuditor.d.ts.map +1 -1
  155. package/dist/security/audit/SecurityAuditor.js +17 -9
  156. package/dist/security/audit/config/suppressions.d.ts.map +1 -1
  157. package/dist/security/audit/config/suppressions.js +19 -3
  158. package/dist/security/contentValidator.d.ts +2 -0
  159. package/dist/security/contentValidator.d.ts.map +1 -1
  160. package/dist/security/contentValidator.js +115 -4
  161. package/dist/security/secureYamlParser.d.ts +1 -0
  162. package/dist/security/secureYamlParser.d.ts.map +1 -1
  163. package/dist/security/secureYamlParser.js +29 -7
  164. package/dist/security/securityMonitor.d.ts +1 -1
  165. package/dist/security/securityMonitor.d.ts.map +1 -1
  166. package/dist/security/securityMonitor.js +1 -1
  167. package/dist/security/tokenManager.d.ts +1 -1
  168. package/dist/security/tokenManager.d.ts.map +1 -1
  169. package/dist/security/tokenManager.js +30 -10
  170. package/dist/server/ServerSetup.d.ts +22 -2
  171. package/dist/server/ServerSetup.d.ts.map +1 -1
  172. package/dist/server/ServerSetup.js +77 -12
  173. package/dist/server/tools/AuthTools.d.ts.map +1 -1
  174. package/dist/server/tools/AuthTools.js +33 -1
  175. package/dist/server/tools/BuildInfoTools.d.ts +25 -0
  176. package/dist/server/tools/BuildInfoTools.d.ts.map +1 -0
  177. package/dist/server/tools/BuildInfoTools.js +36 -0
  178. package/dist/server/tools/CollectionTools.d.ts.map +1 -1
  179. package/dist/server/tools/CollectionTools.js +62 -42
  180. package/dist/server/tools/ConfigTools.d.ts.map +1 -1
  181. package/dist/server/tools/ConfigTools.js +29 -1
  182. package/dist/server/tools/PersonaTools.d.ts +4 -2
  183. package/dist/server/tools/PersonaTools.d.ts.map +1 -1
  184. package/dist/server/tools/PersonaTools.js +5 -152
  185. package/dist/server/tools/PortfolioTools.d.ts +12 -0
  186. package/dist/server/tools/PortfolioTools.d.ts.map +1 -0
  187. package/dist/server/tools/PortfolioTools.js +221 -0
  188. package/dist/server/tools/index.d.ts +3 -1
  189. package/dist/server/tools/index.d.ts.map +1 -1
  190. package/dist/server/tools/index.js +4 -2
  191. package/dist/server/types.d.ts +41 -5
  192. package/dist/server/types.d.ts.map +1 -1
  193. package/dist/server/types.js +1 -1
  194. package/dist/services/BuildInfoService.d.ts +84 -0
  195. package/dist/services/BuildInfoService.d.ts.map +1 -0
  196. package/dist/services/BuildInfoService.js +271 -0
  197. package/dist/tools/portfolio/PortfolioElementAdapter.d.ts +54 -0
  198. package/dist/tools/portfolio/PortfolioElementAdapter.d.ts.map +1 -0
  199. package/dist/tools/portfolio/PortfolioElementAdapter.js +229 -0
  200. package/dist/tools/portfolio/submitToPortfolioTool.d.ts +164 -0
  201. package/dist/tools/portfolio/submitToPortfolioTool.d.ts.map +1 -0
  202. package/dist/tools/portfolio/submitToPortfolioTool.js +1523 -0
  203. package/dist/tools/portfolio/types.d.ts +41 -0
  204. package/dist/tools/portfolio/types.d.ts.map +1 -0
  205. package/dist/tools/portfolio/types.js +15 -0
  206. package/dist/types/collection.d.ts +51 -0
  207. package/dist/types/collection.d.ts.map +1 -1
  208. package/dist/types/collection.js +1 -1
  209. package/dist/utils/EarlyTerminationSearch.d.ts +41 -0
  210. package/dist/utils/EarlyTerminationSearch.d.ts.map +1 -0
  211. package/dist/utils/EarlyTerminationSearch.js +164 -0
  212. package/dist/utils/ErrorHandler.d.ts +86 -0
  213. package/dist/utils/ErrorHandler.d.ts.map +1 -0
  214. package/dist/utils/ErrorHandler.js +201 -0
  215. package/dist/utils/FileDiscoveryUtil.d.ts +53 -0
  216. package/dist/utils/FileDiscoveryUtil.d.ts.map +1 -0
  217. package/dist/utils/FileDiscoveryUtil.js +169 -0
  218. package/dist/utils/GitHubRateLimiter.d.ts +88 -0
  219. package/dist/utils/GitHubRateLimiter.d.ts.map +1 -0
  220. package/dist/utils/GitHubRateLimiter.js +315 -0
  221. package/dist/utils/PerformanceMonitor.d.ts +134 -0
  222. package/dist/utils/PerformanceMonitor.d.ts.map +1 -0
  223. package/dist/utils/PerformanceMonitor.js +347 -0
  224. package/dist/utils/RateLimiter.d.ts.map +1 -0
  225. package/dist/utils/RateLimiter.js +172 -0
  226. package/dist/utils/SecureDownloader.d.ts +241 -0
  227. package/dist/utils/SecureDownloader.d.ts.map +1 -0
  228. package/dist/utils/SecureDownloader.js +759 -0
  229. package/dist/utils/ToolCache.d.ts +82 -0
  230. package/dist/utils/ToolCache.d.ts.map +1 -0
  231. package/dist/utils/ToolCache.js +196 -0
  232. package/dist/utils/errorCodes.d.ts +136 -0
  233. package/dist/utils/errorCodes.d.ts.map +1 -0
  234. package/dist/utils/errorCodes.js +87 -0
  235. package/dist/utils/index.d.ts +3 -0
  236. package/dist/utils/index.d.ts.map +1 -1
  237. package/dist/utils/index.js +4 -1
  238. package/dist/utils/installation.d.ts +1 -1
  239. package/dist/utils/installation.d.ts.map +1 -1
  240. package/dist/utils/installation.js +9 -8
  241. package/dist/utils/searchUtils.d.ts +54 -0
  242. package/dist/utils/searchUtils.d.ts.map +1 -0
  243. package/dist/utils/searchUtils.js +118 -0
  244. package/package.json +17 -7
  245. package/dist/config/updateConfig.d.ts +0 -84
  246. package/dist/config/updateConfig.d.ts.map +0 -1
  247. package/dist/config/updateConfig.js +0 -148
  248. package/dist/server/tools/UpdateTools.d.ts +0 -10
  249. package/dist/server/tools/UpdateTools.d.ts.map +0 -1
  250. package/dist/server/tools/UpdateTools.js +0 -85
  251. package/dist/update/BackupManager.d.ts +0 -63
  252. package/dist/update/BackupManager.d.ts.map +0 -1
  253. package/dist/update/BackupManager.js +0 -370
  254. package/dist/update/DependencyChecker.d.ts +0 -41
  255. package/dist/update/DependencyChecker.d.ts.map +0 -1
  256. package/dist/update/DependencyChecker.js +0 -132
  257. package/dist/update/RateLimiter.d.ts.map +0 -1
  258. package/dist/update/RateLimiter.js +0 -172
  259. package/dist/update/SignatureVerifier.d.ts +0 -71
  260. package/dist/update/SignatureVerifier.d.ts.map +0 -1
  261. package/dist/update/SignatureVerifier.js +0 -214
  262. package/dist/update/UpdateChecker.d.ts +0 -132
  263. package/dist/update/UpdateChecker.d.ts.map +0 -1
  264. package/dist/update/UpdateChecker.js +0 -506
  265. package/dist/update/UpdateManager.d.ts +0 -60
  266. package/dist/update/UpdateManager.d.ts.map +0 -1
  267. package/dist/update/UpdateManager.js +0 -730
  268. package/dist/update/VersionManager.d.ts +0 -31
  269. package/dist/update/VersionManager.d.ts.map +0 -1
  270. package/dist/update/VersionManager.js +0 -181
  271. package/dist/update/index.d.ts +0 -9
  272. package/dist/update/index.d.ts.map +0 -1
  273. package/dist/update/index.js +0 -9
  274. /package/dist/{update → utils}/RateLimiter.d.ts +0 -0
@@ -0,0 +1,267 @@
1
+ /**
2
+ * Collection seeder for anonymous/offline browsing
3
+ * Provides basic collection data that doesn't require GitHub authentication
4
+ */
5
+ /**
6
+ * Basic collection data that can be used without GitHub API access
7
+ * This provides a minimal set of well-known collection items
8
+ */
9
+ export class CollectionSeeder {
10
+ // Cache the seed data as a static property for memory efficiency
11
+ static cachedSeedData = null;
12
+ /**
13
+ * Get seed data for the collection cache
14
+ * This includes popular/essential items that are commonly requested
15
+ * Data is cached as a static property to avoid recreation on every call
16
+ */
17
+ static getSeedData() {
18
+ // Return cached data if available
19
+ if (CollectionSeeder.cachedSeedData) {
20
+ return CollectionSeeder.cachedSeedData;
21
+ }
22
+ // Create and cache the seed data
23
+ CollectionSeeder.cachedSeedData = [
24
+ // Popular Personas
25
+ {
26
+ name: 'creative-writer.md',
27
+ path: 'library/personas/creative-writer.md',
28
+ sha: 'seed-data',
29
+ last_modified: new Date().toISOString()
30
+ },
31
+ {
32
+ name: 'eli5-explainer.md',
33
+ path: 'library/personas/eli5-explainer.md',
34
+ sha: 'seed-data',
35
+ last_modified: new Date().toISOString()
36
+ },
37
+ {
38
+ name: 'debug-detective.md',
39
+ path: 'library/personas/debug-detective.md',
40
+ sha: 'seed-data',
41
+ last_modified: new Date().toISOString()
42
+ },
43
+ {
44
+ name: 'technical-analyst.md',
45
+ path: 'library/personas/technical-analyst.md',
46
+ sha: 'seed-data',
47
+ last_modified: new Date().toISOString()
48
+ },
49
+ {
50
+ name: 'business-consultant.md',
51
+ path: 'library/personas/business-consultant.md',
52
+ sha: 'seed-data',
53
+ last_modified: new Date().toISOString()
54
+ },
55
+ {
56
+ name: 'security-analyst.md',
57
+ path: 'library/personas/security-analyst.md',
58
+ sha: 'seed-data',
59
+ last_modified: new Date().toISOString()
60
+ },
61
+ // Popular Skills
62
+ {
63
+ name: 'code-review.md',
64
+ path: 'library/skills/code-review.md',
65
+ sha: 'seed-data',
66
+ last_modified: new Date().toISOString()
67
+ },
68
+ {
69
+ name: 'creative-writing.md',
70
+ path: 'library/skills/creative-writing.md',
71
+ sha: 'seed-data',
72
+ last_modified: new Date().toISOString()
73
+ },
74
+ {
75
+ name: 'data-analysis.md',
76
+ path: 'library/skills/data-analysis.md',
77
+ sha: 'seed-data',
78
+ last_modified: new Date().toISOString()
79
+ },
80
+ {
81
+ name: 'research.md',
82
+ path: 'library/skills/research.md',
83
+ sha: 'seed-data',
84
+ last_modified: new Date().toISOString()
85
+ },
86
+ {
87
+ name: 'translation.md',
88
+ path: 'library/skills/translation.md',
89
+ sha: 'seed-data',
90
+ last_modified: new Date().toISOString()
91
+ },
92
+ {
93
+ name: 'threat-modeling.md',
94
+ path: 'library/skills/threat-modeling.md',
95
+ sha: 'seed-data',
96
+ last_modified: new Date().toISOString()
97
+ },
98
+ {
99
+ name: 'penetration-testing.md',
100
+ path: 'library/skills/penetration-testing.md',
101
+ sha: 'seed-data',
102
+ last_modified: new Date().toISOString()
103
+ },
104
+ // Popular Agents
105
+ {
106
+ name: 'code-reviewer.md',
107
+ path: 'library/agents/code-reviewer.md',
108
+ sha: 'seed-data',
109
+ last_modified: new Date().toISOString()
110
+ },
111
+ {
112
+ name: 'research-assistant.md',
113
+ path: 'library/agents/research-assistant.md',
114
+ sha: 'seed-data',
115
+ last_modified: new Date().toISOString()
116
+ },
117
+ {
118
+ name: 'task-manager.md',
119
+ path: 'library/agents/task-manager.md',
120
+ sha: 'seed-data',
121
+ last_modified: new Date().toISOString()
122
+ },
123
+ // Popular Templates
124
+ {
125
+ name: 'code-documentation.md',
126
+ path: 'library/templates/code-documentation.md',
127
+ sha: 'seed-data',
128
+ last_modified: new Date().toISOString()
129
+ },
130
+ {
131
+ name: 'email-professional.md',
132
+ path: 'library/templates/email-professional.md',
133
+ sha: 'seed-data',
134
+ last_modified: new Date().toISOString()
135
+ },
136
+ {
137
+ name: 'meeting-notes.md',
138
+ path: 'library/templates/meeting-notes.md',
139
+ sha: 'seed-data',
140
+ last_modified: new Date().toISOString()
141
+ },
142
+ {
143
+ name: 'project-brief.md',
144
+ path: 'library/templates/project-brief.md',
145
+ sha: 'seed-data',
146
+ last_modified: new Date().toISOString()
147
+ },
148
+ {
149
+ name: 'report-executive.md',
150
+ path: 'library/templates/report-executive.md',
151
+ sha: 'seed-data',
152
+ last_modified: new Date().toISOString()
153
+ },
154
+ {
155
+ name: 'penetration-test-report.md',
156
+ path: 'library/templates/penetration-test-report.md',
157
+ sha: 'seed-data',
158
+ last_modified: new Date().toISOString()
159
+ },
160
+ {
161
+ name: 'security-vulnerability-report.md',
162
+ path: 'library/templates/security-vulnerability-report.md',
163
+ sha: 'seed-data',
164
+ last_modified: new Date().toISOString()
165
+ },
166
+ {
167
+ name: 'threat-assessment-report.md',
168
+ path: 'library/templates/threat-assessment-report.md',
169
+ sha: 'seed-data',
170
+ last_modified: new Date().toISOString()
171
+ },
172
+ // Popular Ensembles
173
+ {
174
+ name: 'business-advisor.md',
175
+ path: 'library/ensembles/business-advisor.md',
176
+ sha: 'seed-data',
177
+ last_modified: new Date().toISOString()
178
+ },
179
+ {
180
+ name: 'creative-studio.md',
181
+ path: 'library/ensembles/creative-studio.md',
182
+ sha: 'seed-data',
183
+ last_modified: new Date().toISOString()
184
+ },
185
+ {
186
+ name: 'development-team.md',
187
+ path: 'library/ensembles/development-team.md',
188
+ sha: 'seed-data',
189
+ last_modified: new Date().toISOString()
190
+ },
191
+ {
192
+ name: 'security-analysis-team.md',
193
+ path: 'library/ensembles/security-analysis-team.md',
194
+ sha: 'seed-data',
195
+ last_modified: new Date().toISOString()
196
+ },
197
+ // Test Elements for E2E Testing
198
+ {
199
+ name: 'safe-roundtrip-tester.md',
200
+ path: 'library/skills/safe-roundtrip-tester.md',
201
+ sha: 'seed-data',
202
+ last_modified: new Date().toISOString()
203
+ },
204
+ {
205
+ name: 'roundtrip-test-skill.md',
206
+ path: 'library/skills/roundtrip-test-skill.md',
207
+ sha: 'seed-data',
208
+ last_modified: new Date().toISOString()
209
+ },
210
+ {
211
+ name: 'test-validator.md',
212
+ path: 'library/skills/test-validator.md',
213
+ sha: 'seed-data',
214
+ last_modified: new Date().toISOString()
215
+ },
216
+ {
217
+ name: 'sample-skill.md',
218
+ path: 'library/skills/sample-skill.md',
219
+ sha: 'seed-data',
220
+ last_modified: new Date().toISOString()
221
+ },
222
+ {
223
+ name: 'test-element.md',
224
+ path: 'library/agents/test-element.md',
225
+ sha: 'seed-data',
226
+ last_modified: new Date().toISOString()
227
+ },
228
+ {
229
+ name: 'testing-framework.md',
230
+ path: 'library/templates/testing-framework.md',
231
+ sha: 'seed-data',
232
+ last_modified: new Date().toISOString()
233
+ }
234
+ ];
235
+ return CollectionSeeder.cachedSeedData;
236
+ }
237
+ /**
238
+ * Get collection statistics from seed data
239
+ */
240
+ static getSeedStats() {
241
+ const seedData = this.getSeedData();
242
+ const typeCount = new Map();
243
+ seedData.forEach(item => {
244
+ // Extract type from path (library/personas/name.md -> personas)
245
+ const pathParts = item.path.split('/');
246
+ const type = pathParts[1] || 'unknown';
247
+ typeCount.set(type, (typeCount.get(type) || 0) + 1);
248
+ });
249
+ return {
250
+ total: seedData.length,
251
+ byType: Object.fromEntries(typeCount)
252
+ };
253
+ }
254
+ /**
255
+ * Check if an item is available in seed data
256
+ */
257
+ static isItemInSeedData(path) {
258
+ return this.getSeedData().some(item => item.path === path);
259
+ }
260
+ /**
261
+ * Get seed item by path
262
+ */
263
+ static getSeedItem(path) {
264
+ return this.getSeedData().find(item => item.path === path);
265
+ }
266
+ }
267
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQ29sbGVjdGlvblNlZWRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb2xsZWN0aW9uL0NvbGxlY3Rpb25TZWVkZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7OztHQUdHO0FBSUg7OztHQUdHO0FBQ0gsTUFBTSxPQUFPLGdCQUFnQjtJQUMzQixpRUFBaUU7SUFDekQsTUFBTSxDQUFDLGNBQWMsR0FBNEIsSUFBSSxDQUFDO0lBRTlEOzs7O09BSUc7SUFDSCxNQUFNLENBQUMsV0FBVztRQUNoQixrQ0FBa0M7UUFDbEMsSUFBSSxnQkFBZ0IsQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUNwQyxPQUFPLGdCQUFnQixDQUFDLGNBQWMsQ0FBQztRQUN6QyxDQUFDO1FBRUQsaUNBQWlDO1FBQ2pDLGdCQUFnQixDQUFDLGNBQWMsR0FBRztZQUNoQyxtQkFBbUI7WUFDbkI7Z0JBQ0UsSUFBSSxFQUFFLG9CQUFvQjtnQkFDMUIsSUFBSSxFQUFFLHFDQUFxQztnQkFDM0MsR0FBRyxFQUFFLFdBQVc7Z0JBQ2hCLGFBQWEsRUFBRSxJQUFJLElBQUksRUFBRSxDQUFDLFdBQVcsRUFBRTthQUN4QztZQUNEO2dCQUNFLElBQUksRUFBRSxtQkFBbUI7Z0JBQ3pCLElBQUksRUFBRSxvQ0FBb0M7Z0JBQzFDLEdBQUcsRUFBRSxXQUFXO2dCQUNoQixhQUFhLEVBQUUsSUFBSSxJQUFJLEVBQUUsQ0FBQyxXQUFXLEVBQUU7YUFDeEM7WUFDRDtnQkFDRSxJQUFJLEVBQUUsb0JBQW9CO2dCQUMxQixJQUFJLEVBQUUscUNBQXFDO2dCQUMzQyxHQUFHLEVBQUUsV0FBVztnQkFDaEIsYUFBYSxFQUFFLElBQUksSUFBSSxFQUFFLENBQUMsV0FBVyxFQUFFO2FBQ3hDO1lBQ0Q7Z0JBQ0UsSUFBSSxFQUFFLHNCQUFzQjtnQkFDNUIsSUFBSSxFQUFFLHVDQUF1QztnQkFDN0MsR0FBRyxFQUFFLFdBQVc7Z0JBQ2hCLGFBQWEsRUFBRSxJQUFJLElBQUksRUFB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QUFDLGdCQUFnQixDQUFDLElBQVk7UUFDbEMsT0FBTyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksS0FBSyxJQUFJLENBQUMsQ0FBQztJQUM3RCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxNQUFNLENBQUMsV0FBVyxDQUFDLElBQVk7UUFDN0IsT0FBTyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksS0FBSyxJQUFJLENBQUMsQ0FBQztJQUM3RCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBDb2xsZWN0aW9uIHNlZWRlciBmb3IgYW5vbnltb3VzL29mZmxpbmUgYnJvd3NpbmdcbiAqIFByb3ZpZGVzIGJhc2ljIGNvbGxlY3Rpb24gZGF0YSB0aGF0IGRvZXNuJ3QgcmVxdWlyZSBHaXRIdWIgYXV0aGVudGljYXRpb25cbiAqL1xuXG5pbXBvcnQgeyBDb2xsZWN0aW9uSXRlbSB9IGZyb20gJy4uL2NhY2hlL0NvbGxlY3Rpb25DYWNoZS5qcyc7XG5cbi8qKlxuICogQmFzaWMgY29sbGVjdGlvbiBkYXRhIHRoYXQgY2FuIGJlIHVzZWQgd2l0aG91dCBHaXRIdWIgQVBJIGFjY2Vzc1xuICogVGhpcyBwcm92aWRlcyBhIG1pbmltYWwgc2V0IG9mIHdlbGwta25vd24gY29sbGVjdGlvbiBpdGVtc1xuICovXG5leHBvcnQgY2xhc3MgQ29sbGVjdGlvblNlZWRlciB7XG4gIC8vIENhY2hlIHRoZSBzZWVkIGRhdGEgYXMgYSBzdGF0aWMgcHJvcGVydHkgZm9yIG1lbW9yeSBlZmZpY2llbmN5XG4gIHByaXZhdGUgc3RhdGljIGNhY2hlZFNlZWREYXRhOiBDb2xsZWN0aW9uSXRlbVtdIHwgbnVsbCA9IG51bGw7XG4gIFxuICAvKipcbiAgICogR2V0IHNlZWQgZGF0YSBmb3IgdGhlIGNvbGxlY3Rpb24gY2FjaGVcbiAgICogVGhpcyBpbmNsdWRlcyBwb3B1bGFyL2Vzc2VudGlhbCBpdGVtcyB0aGF0IGFyZSBjb21tb25seSByZXF1ZXN0ZWRcbiAgICogRGF0YSBpcyBjYWNoZWQgYXMgYSBzdGF0aWMgcHJvcGVydHkgdG8gYXZvaWQgcmVjcmVhdGlvbiBvbiBldmVyeSBjYWxsXG4gICAqL1xuICBzdGF0aWMgZ2V0U2VlZERhdGEoKTogQ29sbGVjdGlvbkl0ZW1bXSB7XG4gICAgLy8gUmV0dXJuIGNhY2hlZCBkYXRhIGlmIGF2YWlsYWJsZVxuICAgIGlmIChDb2xsZWN0aW9uU2VlZGVyLmNhY2hlZFNlZWREYXRhKSB7XG4gICAgICByZXR1cm4gQ29sbGVjdGlvblNlZWRlci5jYWNoZWRTZWVkRGF0YTtcbiAgICB9XG4gICAgXG4gICAgLy8gQ3JlYXRlIGFuZCBjYWNoZSB0aGUgc2VlZCBkYXRhXG4gICAgQ29sbGVjdGlvblNlZWRlci5jYWNoZWRTZWVkRGF0YSA9IFtcbiAgICAgIC8vIFBvcHVsYXIgUGVyc29uYXNcbiAgICAgIHtcbiAgICAgICAgbmFtZTogJ2NyZWF0aXZlLXdyaXRlci5tZCcsXG4gICAgICAgIHBhdGg6ICdsaWJyYXJ5L3BlcnNvbmFzL2NyZWF0aXZlLXdyaXRlci5tZCcsXG4gICAgICAgIHNoYTogJ3NlZWQtZGF0YScsXG4gICAgICAgIGxhc3RfbW9kaWZpZWQ6IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKVxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgbmFtZTogJ2VsaTUtZXhwbGFpbmVyLm1kJyxcbiAgICAgICAgcGF0aDogJ2xpYnJhcnkvcGVyc29uYXMvZWxpNS1leHBsYWluZXIubWQnLFxuICAgICAgICBzaGE6ICdzZWVkLWRhdGEnLFxuICAgICAgICBsYXN0X21vZGlmaWVkOiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKClcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIG5hbWU6ICdkZWJ1Zy1kZXRlY3RpdmUubWQnLFxuICAgICAgICBwYXRoOiAnbGlicmFyeS9wZXJzb25hcy9kZWJ1Zy1kZXRlY3RpdmUubWQnLFxuICAgICAgICBzaGE6ICdzZWVkLWRhdGEnLFxuICAgICAgICBsYXN0X21vZGlmaWVkOiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKClcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIG5hbWU6ICd0ZWNobmljYWwtYW5hbHlzdC5tZCcsXG4gICAgICAgIHBhdGg6ICdsaWJyYXJ5L3BlcnNvbmFzL3RlY2huaWNhbC1hbmFseXN0Lm1kJyxcbiAgICAgICAgc2hhOiAnc2VlZC1kYXRhJyxcbiAgICAgICAgbGFzdF9tb2RpZmllZDogbmV3IERhdGUoKS50b0lTT1N0cmluZygpXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBuYW1lOiAnYnVzaW5lc3MtY29uc3VsdGFudC5tZCcsXG4gICAgICAgIHBhdGg6ICdsaWJyYXJ5L3BlcnNvbmFzL2J1c2luZXNzLWNvbnN1bHRhbnQubWQnLFxuICAgICAgICBzaGE6ICdzZWVkLWRhdGEnLFxuICAgICAgICBsYXN0X21vZGlmaWVkOiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKClcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIG5hbWU6ICdzZWN1cml0eS1hbmFseXN0Lm1kJyxcbiAgICAgICAgcGF0aDogJ2xpYnJhcnkvcGVyc29uYXMvc2VjdXJpdHktYW5hbHlzdC5tZCcsXG4gICAgICAgIHNoYTogJ3NlZWQtZGF0YScsXG4gICAgICAgIGxhc3RfbW9kaWZpZWQ6IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKVxuICAgICAgfSxcbiAgICAgIFxuICAgICAgLy8gUG9wdWxhciBTa2lsbHNcbiAgICAgIHtcbiAgICAgICAgbmFtZTogJ2NvZGUtcmV2aWV3Lm1kJyxcbiAgICAgICAgcGF0aDogJ2xpYnJhcnkvc2tpbGxzL2NvZGUtcmV2aWV3Lm1kJyxcbiAgICAgICAgc2hhOiAnc2VlZC1kYXRhJyxcbiAgICAgICAgbGFzdF9tb2RpZmllZDogbmV3IERhdGUoKS50b0lTT1N0cmluZygpXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBuYW1lOiAnY3JlYXRpdmUtd3JpdGluZy5tZCcsXG4gICAgICAgIHBhdGg6ICdsaWJyYXJ5L3NraWxscy9jcmVhdGl2ZS13cml0aW5nLm1kJyxcbiAgICAgICAgc2hhOiAnc2VlZC1kYXRhJyxcbiAgICAgICAgbGFzdF9tb2RpZmllZDogbmV3IERhdGUoKS50b0lTT1N0cmluZygpXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBuYW1lOiAnZGF0YS1hbmFseXNpcy5tZCcsXG4gICAgICAgIHBhdGg6ICdsaWJyYXJ5L3NraWxscy9kYXRhLWFuYWx5c2lzLm1kJyxcbiAgICAgICAgc2hhOiAnc2VlZC1kYXRhJyxcbiAgICAgICAgbGFzdF9tb2RpZmllZDogbmV3IERhdGUoKS50b0lTT1N0cmluZygpXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBuYW1lOiAncmVzZWFyY2gubWQnLFxuICAgICAgICBwYXRoOiAnbGlicmFyeS9za2lsbHMvcmVzZWFyY2gubWQnLFxuICAgICAgICBzaGE6ICdzZWVkLWRhdGEnLFxuICAgICAgICBsYXN0X21vZGlmaWVkOiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKClcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIG5hbWU6ICd0cmFuc2xhdGlvbi5tZCcsXG4gICAgICAgIHBhdGg6ICdsaWJyYXJ5L3NraWxscy90cmFuc2xhdGlvbi5tZCcsXG4gICAgICAgIHNoYTogJ3NlZWQtZGF0YScsXG4gICAgICAgIGxhc3RfbW9kaWZpZWQ6IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKVxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgbmFtZTogJ3RocmVhdC1tb2RlbGluZy5tZCcsXG4gICAgICAgIHBhdGg6ICdsaWJyYXJ5L3NraWxscy90aHJlYXQtbW9kZWxpbmcubWQnLFxuICAgICAgICBzaGE6ICdzZWVkLWRhdGEnLFxuICAgICAgICBsYXN0X21vZGlmaWVkOiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKClcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIG5hbWU6ICdwZW5ldHJhdGlvbi10ZXN0aW5nLm1kJyxcbiAgICAgICAgcGF0aDogJ2xpYnJhcnkvc2tpbGxzL3BlbmV0cmF0aW9uLXRlc3RpbmcubWQnLFxuICAgICAgICBzaGE6ICdzZWVkLWRhdGEnLFxuICAgICAgICBsYXN0X21vZGlmaWVkOiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKClcbiAgICAgIH0sXG4gICAgICBcbiAgICAgIC8vIFBvcHVsYXIgQWdlbnRzXG4gICAgICB7XG4gICAgICAgIG5hbWU6ICdjb2RlLXJldmlld2VyLm1kJyxcbiAgICAgICAgcGF0aDogJ2xpYnJhcnkvYWdlbnRzL2NvZGUtcmV2aWV3ZXIubWQnLFxuICAgICAgICBzaGE6ICdzZWVkLWRhdGEnLFxuICAgICAgICBsYXN0X21vZGlmaWVkOiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKClcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIG5hbWU6ICdyZXNlYXJjaC1hc3Npc3RhbnQubWQnLFxuICAgICAgICBwYXRoOiAnbGlicmFyeS9hZ2VudHMvcmVzZWFyY2gtYXNzaXN0YW50Lm1kJyxcbiAgICAgICAgc2hhOiAnc2VlZC1kYXRhJyxcbiAgICAgICAgbGFzdF9tb2RpZmllZDogbmV3IERhdGUoKS50b0lTT1N0cmluZygpXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBuYW1lOiAndGFzay1tYW5hZ2VyLm1kJyxcbiAgICAgICAgcGF0aDogJ2xpYnJhcnkvYWdlbnRzL3Rhc2stbWFuYWdlci5tZCcsXG4gICAgICAgIHNoYTogJ3NlZWQtZGF0YScsXG4gICAgICAgIGxhc3RfbW9kaWZpZWQ6IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKVxuICAgICAgfSxcbiAgICAgIFxuICAgICAgLy8gUG9wdWxhciBUZW1wbGF0ZXNcbiAgICAgIHtcbiAgICAgICAgbmFtZTogJ2NvZGUtZG9jdW1lbnRhdGlvbi5tZCcsXG4gICAgICAgIHBhdGg6ICdsaWJyYXJ5L3RlbXBsYXRlcy9jb2RlLWRvY3VtZW50YXRpb24ubWQnLFxuICAgICAgICBzaGE6ICdzZWVkLWRhdGEnLFxuICAgICAgICBsYXN0X21vZGlmaWVkOiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKClcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIG5hbWU6ICdlbWFpbC1wcm9mZXNzaW9uYWwubWQnLFxuICAgICAgICBwYXRoOiAnbGlicmFyeS90ZW1wbGF0ZXMvZW1haWwtcHJvZmVzc2lvbmFsLm1kJyxcbiAgICAgICAgc2hhOiAnc2VlZC1kYXRhJyxcbiAgICAgICAgbGFzdF9tb2RpZmllZDogbmV3IERhdGUoKS50b0lTT1N0cmluZygpXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBuYW1lOiAnbWVldGluZy1ub3Rlcy5tZCcsXG4gICAgICAgIHBhdGg6ICdsaWJyYXJ5L3RlbXBsYXRlcy9tZWV0aW5nLW5vdGVzLm1kJyxcbiAgICAgICAgc2hhOiAnc2VlZC1kYXRhJyxcbiAgICAgICAgbGFzdF9tb2RpZmllZDogbmV3IERhdGUoKS50b0lTT1N0cmluZygpXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBuYW1lOiAncHJvamVjdC1icmllZi5tZCcsXG4gICAgICAgIHBhdGg6ICdsaWJyYXJ5L3RlbXBsYXRlcy9wcm9qZWN0LWJyaWVmLm1kJyxcbiAgICAgICAgc2hhOiAnc2VlZC1kYXRhJyxcbiAgICAgICAgbGFzdF9tb2RpZmllZDogbmV3IERhdGUoKS50b0lTT1N0cmluZygpXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBuYW1lOiAncmVwb3J0LWV4ZWN1dGl2ZS5tZCcsXG4gICAgICAgIHBhdGg6ICdsaWJyYXJ5L3RlbXBsYXRlcy9yZXBvcnQtZXhlY3V0aXZlLm1kJyxcbiAgICAgICAgc2hhOiAnc2VlZC1kYXRhJyxcbiAgICAgICAgbGFzdF9tb2RpZmllZDogbmV3IERhdGUoKS50b0lTT1N0cmluZygpXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBuYW1lOiAncGVuZXRyYXRpb24tdGVzdC1yZXBvcnQubWQnLFxuICAgICAgICBwYXRoOiAnbGlicmFyeS90ZW1wbGF0ZXMvcGVuZXRyYXRpb24tdGVzdC1yZXBvcnQubWQnLFxuICAgICAgICBzaGE6ICdzZWVkLWRhdGEnLFxuICAgICAgICBsYXN0X21vZGlmaWVkOiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKClcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIG5hbWU6ICdzZWN1cml0eS12dWxuZXJhYmlsaXR5LXJlcG9ydC5tZCcsXG4gICAgICAgIHBhdGg6ICdsaWJyYXJ5L3RlbXBsYXRlcy9zZWN1cml0eS12dWxuZXJhYmlsaXR5LXJlcG9ydC5tZCcsXG4gICAgICAgIHNoYTogJ3NlZWQtZGF0YScsXG4gICAgICAgIGxhc3RfbW9kaWZpZWQ6IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKVxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgbmFtZTogJ3RocmVhdC1hc3Nlc3NtZW50LXJlcG9ydC5tZCcsXG4gICAgICAgIHBhdGg6ICdsaWJyYXJ5L3RlbXBsYXRlcy90aHJlYXQtYXNzZXNzbWVudC1yZXBvcnQubWQnLFxuICAgICAgICBzaGE6ICdzZWVkLWRhdGEnLFxuICAgICAgICBsYXN0X21vZGlmaWVkOiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKClcbiAgICAgIH0sXG4gICAgICBcbiAgICAgIC8vIFBvcHVsYXIgRW5zZW1ibGVzXG4gICAgICB7XG4gICAgICAgIG5hbWU6ICdidXNpbmVzcy1hZHZpc29yLm1kJyxcbiAgICAgICAgcGF0aDogJ2xpYnJhcnkvZW5zZW1ibGVzL2J1c2luZXNzLWFkdmlzb3IubWQnLFxuICAgICAgICBzaGE6ICdzZWVkLWRhdGEnLFxuICAgICAgICBsYXN0X21vZGlmaWVkOiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKClcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIG5hbWU6ICdjcmVhdGl2ZS1zdHVkaW8ubWQnLFxuICAgICAgICBwYXRoOiAnbGlicmFyeS9lbnNlbWJsZXMvY3JlYXRpdmUtc3R1ZGlvLm1kJyxcbiAgICAgICAgc2hhOiAnc2VlZC1kYXRhJyxcbiAgICAgICAgbGFzdF9tb2RpZmllZDogbmV3IERhdGUoKS50b0lTT1N0cmluZygpXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBuYW1lOiAnZGV2ZWxvcG1lbnQtdGVhbS5tZCcsXG4gICAgICAgIHBhdGg6ICdsaWJyYXJ5L2Vuc2VtYmxlcy9kZXZlbG9wbWVudC10ZWFtLm1kJyxcbiAgICAgICAgc2hhOiAnc2VlZC1kYXRhJyxcbiAgICAgICAgbGFzdF9tb2RpZmllZDogbmV3IERhdGUoKS50b0lTT1N0cmluZygpXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBuYW1lOiAnc2VjdXJpdHktYW5hbHlzaXMtdGVhbS5tZCcsXG4gICAgICAgIHBhdGg6ICdsaWJyYXJ5L2Vuc2VtYmxlcy9zZWN1cml0eS1hbmFseXNpcy10ZWFtLm1kJyxcbiAgICAgICAgc2hhOiAnc2VlZC1kYXRhJyxcbiAgICAgICAgbGFzdF9tb2RpZmllZDogbmV3IERhdGUoKS50b0lTT1N0cmluZygpXG4gICAgICB9LFxuICAgICAgXG4gICAgICAvLyBUZXN0IEVsZW1lbnRzIGZvciBFMkUgVGVzdGluZ1xuICAgICAge1xuICAgICAgICBuYW1lOiAnc2FmZS1yb3VuZHRyaXAtdGVzdGVyLm1kJyxcbiAgICAgICAgcGF0aDogJ2xpYnJhcnkvc2tpbGxzL3NhZmUtcm91bmR0cmlwLXRlc3Rlci5tZCcsXG4gICAgICAgIHNoYTogJ3NlZWQtZGF0YScsXG4gICAgICAgIGxhc3RfbW9kaWZpZWQ6IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKVxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgbmFtZTogJ3JvdW5kdHJpcC10ZXN0LXNraWxsLm1kJyxcbiAgICAgICAgcGF0aDogJ2xpYnJhcnkvc2tpbGxzL3JvdW5kdHJpcC10ZXN0LXNraWxsLm1kJyxcbiAgICAgICAgc2hhOiAnc2VlZC1kYXRhJyxcbiAgICAgICAgbGFzdF9tb2RpZmllZDogbmV3IERhdGUoKS50b0lTT1N0cmluZygpXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBuYW1lOiAndGVzdC12YWxpZGF0b3IubWQnLFxuICAgICAgICBwYXRoOiAnbGlicmFyeS9za2lsbHMvdGVzdC12YWxpZGF0b3IubWQnLFxuICAgICAgICBzaGE6ICdzZWVkLWRhdGEnLFxuICAgICAgICBsYXN0X21vZGlmaWVkOiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKClcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIG5hbWU6ICdzYW1wbGUtc2tpbGwubWQnLFxuICAgICAgICBwYXRoOiAnbGlicmFyeS9za2lsbHMvc2FtcGxlLXNraWxsLm1kJyxcbiAgICAgICAgc2hhOiAnc2VlZC1kYXRhJyxcbiAgICAgICAgbGFzdF9tb2RpZmllZDogbmV3IERhdGUoKS50b0lTT1N0cmluZygpXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBuYW1lOiAndGVzdC1lbGVtZW50Lm1kJyxcbiAgICAgICAgcGF0aDogJ2xpYnJhcnkvYWdlbnRzL3Rlc3QtZWxlbWVudC5tZCcsXG4gICAgICAgIHNoYTogJ3NlZWQtZGF0YScsXG4gICAgICAgIGxhc3RfbW9kaWZpZWQ6IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKVxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgbmFtZTogJ3Rlc3RpbmctZnJhbWV3b3JrLm1kJyxcbiAgICAgICAgcGF0aDogJ2xpYnJhcnkvdGVtcGxhdGVzL3Rlc3RpbmctZnJhbWV3b3JrLm1kJyxcbiAgICAgICAgc2hhOiAnc2VlZC1kYXRhJyxcbiAgICAgICAgbGFzdF9tb2RpZmllZDogbmV3IERhdGUoKS50b0lTT1N0cmluZygpXG4gICAgICB9XG4gICAgXTtcbiAgICBcbiAgICByZXR1cm4gQ29sbGVjdGlvblNlZWRlci5jYWNoZWRTZWVkRGF0YTtcbiAgfVxuICBcbiAgLyoqXG4gICAqIEdldCBjb2xsZWN0aW9uIHN0YXRpc3RpY3MgZnJvbSBzZWVkIGRhdGFcbiAgICovXG4gIHN0YXRpYyBnZXRTZWVkU3RhdHMoKSB7XG4gICAgY29uc3Qgc2VlZERhdGEgPSB0aGlzLmdldFNlZWREYXRhKCk7XG4gICAgY29uc3QgdHlwZUNvdW50ID0gbmV3IE1hcDxzdHJpbmcsIG51bWJlcj4oKTtcbiAgICBcbiAgICBzZWVkRGF0YS5mb3JFYWNoKGl0ZW0gPT4ge1xuICAgICAgLy8gRXh0cmFjdCB0eXBlIGZyb20gcGF0aCAobGlicmFyeS9wZXJzb25hcy9uYW1lLm1kIC0+IHBlcnNvbmFzKVxuICAgICAgY29uc3QgcGF0aFBhcnRzID0gaXRlbS5wYXRoLnNwbGl0KCcvJyk7XG4gICAgICBjb25zdCB0eXBlID0gcGF0aFBhcnRzWzFdIHx8ICd1bmtub3duJztcbiAgICAgIHR5cGVDb3VudC5zZXQodHlwZSwgKHR5cGVDb3VudC5nZXQodHlwZSkgfHwgMCkgKyAxKTtcbiAgICB9KTtcbiAgICBcbiAgICByZXR1cm4ge1xuICAgICAgdG90YWw6IHNlZWREYXRhLmxlbmd0aCxcbiAgICAgIGJ5VHlwZTogT2JqZWN0LmZyb21FbnRyaWVzKHR5cGVDb3VudClcbiAgICB9O1xuICB9XG4gIFxuICAvKipcbiAgICogQ2hlY2sgaWYgYW4gaXRlbSBpcyBhdmFpbGFibGUgaW4gc2VlZCBkYXRhXG4gICAqL1xuICBzdGF0aWMgaXNJdGVtSW5TZWVkRGF0YShwYXRoOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5nZXRTZWVkRGF0YSgpLnNvbWUoaXRlbSA9PiBpdGVtLnBhdGggPT09IHBhdGgpO1xuICB9XG4gIFxuICAvKipcbiAgICogR2V0IHNlZWQgaXRlbSBieSBwYXRoXG4gICAqL1xuICBzdGF0aWMgZ2V0U2VlZEl0ZW0ocGF0aDogc3RyaW5nKTogQ29sbGVjdGlvbkl0ZW0gfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLmdldFNlZWREYXRhKCkuZmluZChpdGVtID0+IGl0ZW0ucGF0aCA9PT0gcGF0aCk7XG4gIH1cbn0iXX0=
@@ -1,6 +1,22 @@
1
1
  /**
2
2
  * Install AI customization elements from collection
3
3
  * Supports all element types: personas, skills, templates, agents, memories, ensembles
4
+ *
5
+ * SECURITY FIX (2025-08-12): Fixed critical vulnerability where content was written to disk
6
+ * BEFORE validation was complete. This could allow malicious content to persist on the
7
+ * filesystem even when validation failed. The fix implements:
8
+ *
9
+ * 1. VALIDATE-BEFORE-WRITE PATTERN: All content validation (ContentValidator.sanitizePersonaContent,
10
+ * SecureYamlParser.safeMatter, metadata validation, etc.) is now performed BEFORE any disk operations.
11
+ *
12
+ * 2. ATOMIC FILE OPERATIONS: Uses temporary file + atomic rename to prevent partial file corruption
13
+ * and ensure complete cleanup on any failure during the write process.
14
+ *
15
+ * 3. GUARANTEED CLEANUP: If any part of the write operation fails, temporary files are automatically
16
+ * cleaned up, preventing orphaned malicious content on the filesystem.
17
+ *
18
+ * The vulnerability existed in installContent() where fs.writeFile() was called after validation
19
+ * but before final success confirmation, creating a window where malicious content could persist.
4
20
  */
5
21
  import { GitHubClient } from './GitHubClient.js';
6
22
  import { IElementMetadata } from '../types/elements/IElement.js';
@@ -13,6 +29,9 @@ export declare class ElementInstaller {
13
29
  /**
14
30
  * Install AI customization element from the collection
15
31
  * Automatically detects element type from path structure
32
+ *
33
+ * SECURITY FIX: Implements validate-before-write pattern with atomic operations
34
+ * to prevent malicious content persistence on validation failure.
16
35
  */
17
36
  installContent(inputPath: string): Promise<{
18
37
  success: boolean;
@@ -21,6 +40,18 @@ export declare class ElementInstaller {
21
40
  elementType?: ElementType;
22
41
  filename?: string;
23
42
  }>;
43
+ /**
44
+ * Atomic file write operation with guaranteed cleanup on failure
45
+ *
46
+ * SECURITY FIX: This method ensures that file writes are atomic and any
47
+ * failures during the write process will not leave partial or corrupted
48
+ * files on the filesystem. Uses temporary file + rename for atomicity.
49
+ *
50
+ * @param destination - Final destination path for the file
51
+ * @param content - Content to write to the file
52
+ * @throws Error if write operation fails (with guaranteed cleanup)
53
+ */
54
+ private atomicWriteFile;
24
55
  /**
25
56
  * Get ElementType from string
26
57
  */
@@ -1 +1 @@
1
- {"version":3,"file":"ElementInstaller.d.ts","sourceRoot":"","sources":["../../src/collection/ElementInstaller.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAMjE,OAAO,EAAoB,WAAW,EAAE,MAAM,kCAAkC,CAAC;AAEjF,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,gBAAgB,CAAmB;IAC3C,OAAO,CAAC,OAAO,CAAmE;gBAEtE,YAAY,EAAE,YAAY;IAKtC;;;OAGG;IACG,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC;QAC/C,OAAO,EAAE,OAAO,CAAC;QACjB,OAAO,EAAE,MAAM,CAAC;QAChB,QAAQ,CAAC,EAAE,gBAAgB,CAAC;QAC5B,WAAW,CAAC,EAAE,WAAW,CAAC;QAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC;IA+FF;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAgBhC;;OAEG;IACH,oBAAoB,CAAC,QAAQ,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,GAAG,MAAM;CAmBrG"}
1
+ {"version":3,"file":"ElementInstaller.d.ts","sourceRoot":"","sources":["../../src/collection/ElementInstaller.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAIH,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAMjE,OAAO,EAAoB,WAAW,EAAE,MAAM,kCAAkC,CAAC;AAEjF,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,gBAAgB,CAAmB;IAC3C,OAAO,CAAC,OAAO,CAAmE;gBAEtE,YAAY,EAAE,YAAY;IAKtC;;;;;;OAMG;IACG,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC;QAC/C,OAAO,EAAE,OAAO,CAAC;QACjB,OAAO,EAAE,MAAM,CAAC;QAChB,QAAQ,CAAC,EAAE,gBAAgB,CAAC;QAC5B,WAAW,CAAC,EAAE,WAAW,CAAC;QAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC;IAqGF;;;;;;;;;;OAUG;YACW,eAAe;IA8B7B;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAgBhC;;OAEG;IACH,oBAAoB,CAAC,QAAQ,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,GAAG,MAAM;CAmBrG"}
@@ -1,6 +1,22 @@
1
1
  /**
2
2
  * Install AI customization elements from collection
3
3
  * Supports all element types: personas, skills, templates, agents, memories, ensembles
4
+ *
5
+ * SECURITY FIX (2025-08-12): Fixed critical vulnerability where content was written to disk
6
+ * BEFORE validation was complete. This could allow malicious content to persist on the
7
+ * filesystem even when validation failed. The fix implements:
8
+ *
9
+ * 1. VALIDATE-BEFORE-WRITE PATTERN: All content validation (ContentValidator.sanitizePersonaContent,
10
+ * SecureYamlParser.safeMatter, metadata validation, etc.) is now performed BEFORE any disk operations.
11
+ *
12
+ * 2. ATOMIC FILE OPERATIONS: Uses temporary file + atomic rename to prevent partial file corruption
13
+ * and ensure complete cleanup on any failure during the write process.
14
+ *
15
+ * 3. GUARANTEED CLEANUP: If any part of the write operation fails, temporary files are automatically
16
+ * cleaned up, preventing orphaned malicious content on the filesystem.
17
+ *
18
+ * The vulnerability existed in installContent() where fs.writeFile() was called after validation
19
+ * but before final success confirmation, creating a window where malicious content could persist.
4
20
  */
5
21
  import * as fs from 'fs/promises';
6
22
  import * as path from 'path';
@@ -21,11 +37,14 @@ export class ElementInstaller {
21
37
  /**
22
38
  * Install AI customization element from the collection
23
39
  * Automatically detects element type from path structure
40
+ *
41
+ * SECURITY FIX: Implements validate-before-write pattern with atomic operations
42
+ * to prevent malicious content persistence on validation failure.
24
43
  */
25
44
  async installContent(inputPath) {
26
- // Validate and sanitize the input path
45
+ // SECURITY: Validate and sanitize the input path first
27
46
  const sanitizedPath = validatePath(inputPath);
28
- // Detect element type from path structure
47
+ // SECURITY: Detect element type from path structure and validate format
29
48
  // Expected format: library/[element-type]/[category]/[element].md
30
49
  const pathParts = sanitizedPath.split('/');
31
50
  if (pathParts.length < 3 || pathParts[0] !== 'library') {
@@ -33,26 +52,29 @@ export class ElementInstaller {
33
52
  }
34
53
  const elementTypeStr = pathParts[1];
35
54
  const elementType = this.getElementTypeFromString(elementTypeStr);
36
- // Ensure the path ends with .md
55
+ // SECURITY: Ensure the path ends with .md to prevent arbitrary file types
37
56
  if (!sanitizedPath.endsWith('.md')) {
38
57
  throw new Error('Invalid file type. Only .md files are allowed.');
39
58
  }
59
+ // STEP 1: FETCH CONTENT INTO MEMORY (NO DISK OPERATIONS YET)
40
60
  const url = `${this.baseUrl}/${sanitizedPath}`;
41
61
  const data = await this.githubClient.fetchFromGitHub(url);
42
62
  if (data.type !== 'file') {
43
63
  throw new Error('Path does not point to a file');
44
64
  }
45
- // Check file size before downloading
65
+ // SECURITY: Check file size before downloading to prevent DoS attacks
46
66
  if (data.size > SECURITY_LIMITS.MAX_PERSONA_SIZE_BYTES) {
47
67
  throw new Error(`File too large (${data.size} bytes, max ${SECURITY_LIMITS.MAX_PERSONA_SIZE_BYTES} bytes)`);
48
68
  }
49
- // Decode Base64 content
69
+ // Decode Base64 content into memory only
50
70
  const content = Buffer.from(data.content, 'base64').toString('utf-8');
51
- // Validate content size after decoding
71
+ // STEP 2: PERFORM ALL VALIDATION BEFORE ANY DISK OPERATIONS
72
+ // This is the critical security fix - validate everything in memory first
73
+ // SECURITY: Validate content size after decoding
52
74
  validateContentSize(content, SECURITY_LIMITS.MAX_PERSONA_SIZE_BYTES);
53
- // Sanitize content for security threats
75
+ // SECURITY: Sanitize content for security threats (XSS, injection, etc.)
54
76
  const sanitizedContent = ContentValidator.sanitizePersonaContent(content);
55
- // Use secure YAML parser
77
+ // SECURITY: Use secure YAML parser to prevent YAML bombs and injection
56
78
  let parsed;
57
79
  try {
58
80
  parsed = SecureYamlParser.safeMatter(sanitizedContent);
@@ -64,22 +86,22 @@ export class ElementInstaller {
64
86
  throw error;
65
87
  }
66
88
  const metadata = parsed.data;
67
- // Additional metadata validation for injection attacks
89
+ // SECURITY: Additional metadata validation for injection attacks
68
90
  const metadataValidation = ContentValidator.validateMetadata(metadata);
69
91
  if (!metadataValidation.isValid) {
70
92
  throw new Error(`Security validation failed: ${metadataValidation.detectedPatterns?.join(', ')}`);
71
93
  }
72
- // Validate metadata
94
+ // SECURITY: Validate required metadata fields
73
95
  if (!metadata.name || !metadata.description) {
74
96
  throw new Error('Invalid content: missing required name or description');
75
97
  }
76
- // Generate and validate local filename
98
+ // SECURITY: Generate and validate local filename to prevent path traversal
77
99
  const originalFilename = sanitizedPath.split('/').pop() || 'downloaded-element.md';
78
100
  const filename = validateFilename(originalFilename);
79
101
  // Get appropriate directory for element type
80
102
  const elementDir = this.portfolioManager.getElementDir(elementType);
81
103
  const localPath = path.join(elementDir, filename);
82
- // Check if file already exists
104
+ // SECURITY: Check if file already exists before any write operations
83
105
  try {
84
106
  await fs.access(localPath);
85
107
  return {
@@ -90,8 +112,10 @@ export class ElementInstaller {
90
112
  catch {
91
113
  // File doesn't exist, proceed with installation
92
114
  }
93
- // Write the sanitized file
94
- await fs.writeFile(localPath, sanitizedContent, 'utf-8');
115
+ // STEP 3: ALL VALIDATION COMPLETE - NOW PERFORM ATOMIC WRITE OPERATION
116
+ // SECURITY FIX: Use atomic write to prevent partial file corruption and
117
+ // ensure cleanup on any failure during the write process
118
+ await this.atomicWriteFile(localPath, sanitizedContent);
95
119
  return {
96
120
  success: true,
97
121
  message: `AI customization element installed successfully!`,
@@ -100,6 +124,44 @@ export class ElementInstaller {
100
124
  elementType
101
125
  };
102
126
  }
127
+ /**
128
+ * Atomic file write operation with guaranteed cleanup on failure
129
+ *
130
+ * SECURITY FIX: This method ensures that file writes are atomic and any
131
+ * failures during the write process will not leave partial or corrupted
132
+ * files on the filesystem. Uses temporary file + rename for atomicity.
133
+ *
134
+ * @param destination - Final destination path for the file
135
+ * @param content - Content to write to the file
136
+ * @throws Error if write operation fails (with guaranteed cleanup)
137
+ */
138
+ async atomicWriteFile(destination, content) {
139
+ // Generate unique temporary file name to avoid collisions
140
+ const tempFile = `${destination}.tmp.${Date.now()}.${Math.random().toString(36).substring(2)}`;
141
+ try {
142
+ // SECURITY: Write to temporary file first
143
+ // If this fails, no files are left on disk
144
+ await fs.writeFile(tempFile, content, 'utf-8');
145
+ // SECURITY: Atomic rename operation
146
+ // On most filesystems, rename is atomic - the file appears with complete content
147
+ // or doesn't appear at all. This prevents partial file corruption.
148
+ await fs.rename(tempFile, destination);
149
+ }
150
+ catch (error) {
151
+ // SECURITY: Guaranteed cleanup of temporary file on ANY failure
152
+ // This ensures no temporary files are left behind even if the
153
+ // rename operation fails after successful write
154
+ try {
155
+ await fs.unlink(tempFile);
156
+ }
157
+ catch (cleanupError) {
158
+ // Ignore cleanup errors - the file may not exist if writeFile failed
159
+ // The original error is more important to propagate
160
+ }
161
+ // Re-throw the original error to maintain error handling semantics
162
+ throw error;
163
+ }
164
+ }
103
165
  /**
104
166
  * Get ElementType from string
105
167
  */
@@ -137,4 +199,4 @@ export class ElementInstaller {
137
199
  `🚀 **Ready to use!**`;
138
200
  }
139
201
  }
140
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRWxlbWVudEluc3RhbGxlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb2xsZWN0aW9uL0VsZW1lbnRJbnN0YWxsZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7OztHQUdHO0FBRUgsT0FBTyxLQUFLLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDbEMsT0FBTyxLQUFLLElBQUksTUFBTSxNQUFNLENBQUM7QUFHN0IsT0FBTyxFQUFFLFlBQVksRUFBRSxnQkFBZ0IsRUFBRSxtQkFBbUIsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQ3BHLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUMzRCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUNuRSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUNuRSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDM0QsT0FBTyxFQUFFLGdCQUFnQixFQUFFLFdBQVcsRUFBRSxNQUFNLGtDQUFrQyxDQUFDO0FBRWpGLE1BQU0sT0FBTyxnQkFBZ0I7SUFDbkIsWUFBWSxDQUFlO0lBQzNCLGdCQUFnQixDQUFtQjtJQUNuQyxPQUFPLEdBQUcsK0RBQStELENBQUM7SUFFbEYsWUFBWSxZQUEwQjtRQUNwQyxJQUFJLENBQUMsWUFBWSxHQUFHLFlBQVksQ0FBQztRQUNqQyxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsZ0JBQWdCLENBQUMsV0FBVyxFQUFFLENBQUM7SUFDekQsQ0FBQztJQUVEOzs7T0FHRztJQUNILEtBQUssQ0FBQyxjQUFjLENBQUMsU0FBaUI7UUFPcEMsdUNBQXVDO1FBQ3ZDLE1BQU0sYUFBYSxHQUFHLFlBQVksQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUU5QywwQ0FBMEM7UUFDMUMsa0VBQWtFO1FBQ2xFLE1BQU0sU0FBUyxHQUFHLGFBQWEsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFD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QyxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ3ZHLENBQUM7UUFFRCxPQUFPLFdBQVcsQ0FBQztJQUNyQixDQUFDO0lBRUQ7O09BRUc7SUFDSCxvQkFBb0IsQ0FBQyxRQUEwQixFQUFFLFFBQWdCLEVBQUUsV0FBd0I7UUFDekYsTUFBTSxVQUFVLEdBQWdDO1lBQzlDLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBQyxFQUFFLElBQUk7WUFDM0IsQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLEVBQUUsSUFBSTtZQUN6QixDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUMsRUFBRSxJQUFJO1lBQzVCLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxFQUFFLElBQUk7WUFDekIsQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLEVBQUUsSUFBSTtZQUMxQixDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUMsRUFBRSxJQUFJO1NBQzdCLENBQUM7UUFFRixNQUFNLEtBQUssR0FBRyxVQUFVLENBQUMsV0FBVyxDQUFDLElBQUksSUFBSSxDQUFDO1FBQzlDLE1BQU0sUUFBUSxHQUFHLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsV0FBVyxFQUFFLEdBQUcsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUU1RSxPQUFPLDREQUE0RDtZQUNqRSxHQUFHLEtBQUssTUFBTSxRQUFRLENBQUMsSUFBSSxNQUFNLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLE1BQU0sUUFBUSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLElBQUk7WUFDbkYsWUFBWSxRQUFRLElBQUk7WUFDeEIsZ0JBQWdCLFFBQVEsTUFBTTtZQUM5QixzQkFBc0IsQ0FBQztJQUMzQixDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEluc3RhbGwgQUkgY3VzdG9taXphdGlvbiBlbGVtZW50cyBmcm9tIGNvbGxlY3Rpb25cbiAqIFN1cHBvcnRzIGFsbCBlbGVtZW50IHR5cGVzOiBwZXJzb25hcywgc2tpbGxzLCB0ZW1wbGF0ZXMsIGFnZW50cywgbWVtb3JpZXMsIGVuc2VtYmxlc1xuICovXG5cbmltcG9ydCAqIGFzIGZzIGZyb20gJ2ZzL3Byb21pc2VzJztcbmltcG9ydCAqIGFzIHBhdGggZnJvbSAncGF0aCc7XG5pbXBvcnQgeyBHaXRIdWJDbGllbnQgfSBmcm9tICcuL0dpdEh1YkNsaWVudC5qcyc7XG5pbXBvcnQgeyBJRWxlbWVudE1ldGFkYXRhIH0gZnJvbSAnLi4vdHlwZXMvZWxlbWVudHMvSUVsZW1lbnQuanMnO1xuaW1wb3J0IHsgdmFsaWRhdGVQYXRoLCB2YWxpZGF0ZUZpbGVuYW1lLCB2YWxpZGF0ZUNvbnRlbnRTaXplIH0gZnJvbSAnLi4vc2VjdXJpdHkvSW5wdXRWYWxpZGF0b3IuanMnO1xuaW1wb3J0IHsgU0VDVVJJVFlfTElNSVRTIH0gZnJvbSAnLi4vc2VjdXJpdHkvY29uc3RhbnRzLmpzJztcbmltcG9ydCB7IENvbnRlbnRWYWxpZGF0b3IgfSBmcm9tICcuLi9zZWN1cml0eS9jb250ZW50VmFsaWRhdG9yLmpzJztcbmltcG9ydCB7IFNlY3VyZVlhbWxQYXJzZXIgfSBmcm9tICcuLi9zZWN1cml0eS9zZWN1cmVZYW1sUGFyc2VyLmpzJztcbmltcG9ydCB7IFNlY3VyaXR5RXJyb3IgfSBmcm9tICcuLi9lcnJvcnMvU2VjdXJpdHlFcnJvci5qcyc7XG5pbXBvcnQgeyBQb3J0Zm9saW9NYW5hZ2VyLCBFbGVtZW50VHlwZSB9IGZyb20gJy4uL3BvcnRmb2xpby9Qb3J0Zm9saW9NYW5hZ2VyLmpzJztcblxuZXhwb3J0IGNsYXNzIEVsZW1lbnRJbnN0YWxsZXIge1xuICBwcml2YXRlIGdpdGh1YkNsaWVudDogR2l0SHViQ2xpZW50O1xuICBwcml2YXRlIHBvcnRmb2xpb01hbmFnZXI6IFBvcnRmb2xpb01hbmFnZXI7XG4gIHByaXZhdGUgYmFzZVVybCA9ICdodHRwczovL2FwaS5naXRodWIuY29tL3JlcG9zL0RvbGxob3VzZU1DUC9jb2xsZWN0aW9uL2NvbnRlbnRzJztcbiAgXG4gIGNvbnN0cnVjdG9yKGdpdGh1YkNsaWVudDogR2l0SHViQ2xpZW50KSB7XG4gICAgdGhpcy5naXRodWJDbGllbnQgPSBnaXRodWJDbGllbnQ7XG4gICAgdGhpcy5wb3J0Zm9saW9NYW5hZ2VyID0gUG9ydGZvbGlvTWFuYWdlci5nZXRJbnN0YW5jZSgpO1xuICB9XG4gIFxuICAvKipcbiAgICogSW5zdGFsbCBBSSBjdXN0b21pemF0aW9uIGVsZW1lbnQgZnJvbSB0aGUgY29sbGVjdGlvblxuICAgKiBBdXRvbWF0aWNhbGx5IGRldGVjdHMgZWxlbWVudCB0eXBlIGZyb20gcGF0aCBzdHJ1Y3R1cmVcbiAgICovXG4gIGFzeW5jIGluc3RhbGxDb250ZW50KGlucHV0UGF0aDogc3RyaW5nKTogUHJvbWlzZTx7IFxuICAgIHN1Y2Nlc3M6IGJvb2xlYW47IFxuICAgIG1lc3NhZ2U6IHN0cmluZztcbiAgICBtZXRhZGF0YT86IElFbGVtZW50TWV0YWRhdGE7XG4gICAgZWxlbWVudFR5cGU/OiBFbGVtZW50VHlwZTtcbiAgICBmaWxlbmFtZT86IHN0cmluZztcbiAgfT4ge1xuICAgIC8vIFZhbGlkYXRlIGFuZCBzYW5pdGl6ZSB0aGUgaW5wdXQgcGF0aFxuICAgIGNvbnN0IHNhbml0aXplZFBhdGggPSB2YWxpZGF0ZVBhdGgoaW5wdXRQYXRoKTtcbiAgICBcbiAgICAvLyBEZXRlY3QgZWxlbWVudCB0eXBlIGZyb20gcGF0aCBzdHJ1Y3R1cmVcbiAgICAvLyBFeHBlY3RlZCBmb3JtYXQ6IGxpYnJhcnkvW2VsZW1lbnQtdHlwZV0vW2NhdGVnb3J5XS9bZWxlbWVudF0ubWRcbiAgICBjb25zdCBwYXRoUGFydHMgPSBzYW5pdGl6ZWRQYXRoLnNwbGl0KCcvJyk7XG4gICAgaWYgKHBhdGhQYXJ0cy5sZW5ndGggPCAzIHx8IHBhdGhQYXJ0c1swXSAhPT0gJ2xpYnJhcnknKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgY29sbGVjdGlvbiBwYXRoIGZvcm1hdC4gRXhwZWN0ZWQ6IGxpYnJhcnkvW2VsZW1lbnQtdHlwZV0vW2NhdGVnb3J5XS9bZWxlbWVudF0ubWQnKTtcbiAgICB9XG4gICAgXG4gICAgY29uc3QgZWxlbWVudFR5cGVTdHIgPSBwYXRoUGFydHNbMV07XG4gICAgY29uc3QgZWxlbWVudFR5cGUgPSB0aGlzLmdldEVsZW1lbnRUeXBlRnJvbVN0cmluZyhlbGVtZW50VHlwZVN0cik7XG4gICAgXG4gICAgLy8gRW5zdXJlIHRoZSBwYXRoIGVuZHMgd2l0aCAubWRcbiAgICBpZiAoIXNhbml0aXplZFBhdGguZW5kc1dpdGgoJy5tZCcpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgZmlsZSB0eXBlLiBPbmx5IC5tZCBmaWxlcyBhcmUgYWxsb3dlZC4nKTtcbiAgICB9XG4gICAgXG4gICAgY29uc3QgdXJsID0gYCR7dGhpcy5iYXNlVXJsfS8ke3Nhbml0aXplZFBhdGh9YDtcbiAgICBjb25zdCBkYXRhID0gYXdhaXQgdGhpcy5naXRodWJDbGllbnQuZmV0Y2hGcm9tR2l0SHViKHVybCk7XG4gICAgXG4gICAgaWYgKGRhdGEudHlwZSAhPT0gJ2ZpbGUnKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1BhdGggZG9lcyBub3QgcG9pbnQgdG8gYSBmaWxlJyk7XG4gICAgfVxuICAgIFxuICAgIC8vIENoZWNrIGZpbGUgc2l6ZSBiZWZvcmUgZG93bmxvYWRpbmdcbiAgICBpZiAoZGF0YS5zaXplID4gU0VDVVJJVFlfTElNSVRTLk1BWF9QRVJTT05BX1NJWkVfQllURVMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgRmlsZSB0b28gbGFyZ2UgKCR7ZGF0YS5zaXplfSBieXRlcywgbWF4ICR7U0VDVVJJVFlfTElNSVRTLk1BWF9QRVJTT05BX1NJWkVfQllURVN9IGJ5dGVzKWApO1xuICAgIH1cbiAgICBcbiAgICAvLyBEZWNvZGUgQmFzZTY0IGNvbnRlbnRcbiAgICBjb25zdCBjb250ZW50ID0gQnVmZmVyLmZyb20oZGF0YS5jb250ZW50LCAnYmFzZTY0JykudG9TdHJpbmcoJ3V0Zi04Jyk7XG4gICAgXG4gICAgLy8gVmFsaWRhdGUgY29udGVudCBzaXplIGFmdGVyIGRlY29kaW5nXG4gICAgdmFsaWRhdGVDb250ZW50U2l6ZShjb250ZW50LCBTRUNVUklUWV9MSU1JVFMuTUFYX1BFUlNPTkFfU0laRV9CWVRFUyk7XG4gICAgXG4gICAgLy8gU2FuaXRpemUgY29udGVudCBmb3Igc2VjdXJpdHkgdGhyZWF0c1xuICAgIGNvbnN0IHNhbml0aXplZENvbnRlbnQgPSBDb250ZW50VmFsaWRhdG9yLnNhbml0aXplUGVyc29uYUNvbnRlbnQoY29udGVudCk7XG4gICAgXG4gICAgLy8gVXNlIHNlY3VyZSBZQU1MIHBhcnNlclxuICAgIGxldCBwYXJzZWQ7XG4gICAgdHJ5IHtcbiAgICAgIHBhcnNlZCA9IFNlY3VyZVlhbWxQYXJzZXIuc2FmZU1hdHRlcihzYW5pdGl6ZWRDb250ZW50KTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgU2VjdXJpdHlFcnJvcikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFNlY3VyaXR5IHRocmVhdCBpbiBjb250ZW50OiAke2Vycm9yLm1lc3NhZ2V9YCk7XG4gICAgICB9XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG4gICAgXG4gICAgY29uc3QgbWV0YWRhdGEgPSBwYXJzZWQuZGF0YSBhcyBJRWxlbWVudE1ldGFkYXRhO1xuICAgIFxuICAgIC8vIEFkZGl0aW9uYWwgbWV0YWRhdGEgdmFsaWRhdGlvbiBmb3IgaW5qZWN0aW9uIGF0dGFja3NcbiAgICBjb25zdCBtZXRhZGF0YVZhbGlkYXRpb24gPSBDb250ZW50VmFsaWRhdG9yLnZhbGlkYXRlTWV0YWRhdGEobWV0YWRhdGEpO1xuICAgIGlmICghbWV0YWRhdGFWYWxpZGF0aW9uLmlzVmFsaWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgU2VjdXJpdHkgdmFsaWRhdGlvbiBmYWlsZWQ6ICR7bWV0YWRhdGFWYWxpZGF0aW9uLmRldGVjdGVkUGF0dGVybnM/LmpvaW4oJywgJyl9YCk7XG4gICAgfVxuICAgIFxuICAgIC8vIFZhbGlkYXRlIG1ldGFkYXRhXG4gICAgaWYgKCFtZXRhZGF0YS5uYW1lIHx8ICFtZXRhZGF0YS5kZXNjcmlwdGlvbikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGNvbnRlbnQ6IG1pc3NpbmcgcmVxdWlyZWQgbmFtZSBvciBkZXNjcmlwdGlvbicpO1xuICAgIH1cbiAgICBcbiAgICAvLyBHZW5lcmF0ZSBhbmQgdmFsaWRhdGUgbG9jYWwgZmlsZW5hbWVcbiAgICBjb25zdCBvcmlnaW5hbEZpbGVuYW1lID0gc2FuaXRpemVkUGF0aC5zcGxpdCgnLycpLnBvcCgpIHx8ICdkb3dubG9hZGVkLWVsZW1lbnQubWQnO1xuICAgIGNvbnN0IGZpbGVuYW1lID0gdmFsaWRhdGVGaWxlbmFtZShvcmlnaW5hbEZpbGVuYW1lKTtcbiAgICBcbiAgICAvLyBHZXQgYXBwcm9wcmlhdGUgZGlyZWN0b3J5IGZvciBlbGVtZW50IHR5cGVcbiAgICBjb25zdCBlbGVtZW50RGlyID0gdGhpcy5wb3J0Zm9saW9NYW5hZ2VyLmdldEVsZW1lbnREaXIoZWxlbWVudFR5cGUpO1xuICAgIGNvbnN0IGxvY2FsUGF0aCA9IHBhdGguam9pbihlbGVtZW50RGlyLCBmaWxlbmFtZSk7XG4gICAgXG4gICAgLy8gQ2hlY2sgaWYgZmlsZSBhbHJlYWR5IGV4aXN0c1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCBmcy5hY2Nlc3MobG9jYWxQYXRoKTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgICAgICBtZXNzYWdlOiBgQUkgY3VzdG9taXphdGlvbiBlbGVtZW50IGFscmVhZHkgZXhpc3RzOiAke2ZpbGVuYW1lfVxcblxcblRoZSBlbGVtZW50IGhhcyBhbHJlYWR5IGJlZW4gaW5zdGFsbGVkLmBcbiAgICAgIH07XG4gICAgfSBjYXRjaCB7XG4gICAgICAvLyBGaWxlIGRvZXNuJ3QgZXhpc3QsIHByb2NlZWQgd2l0aCBpbnN0YWxsYXRpb25cbiAgICB9XG4gICAgXG4gICAgLy8gV3JpdGUgdGhlIHNhbml0aXplZCBmaWxlXG4gICAgYXdhaXQgZnMud3JpdGVGaWxlKGxvY2FsUGF0aCwgc2FuaXRpemVkQ29udGVudCwgJ3V0Zi04Jyk7XG4gICAgXG4gICAgcmV0dXJuIHtcbiAgICAgIHN1Y2Nlc3M6IHRydWUsXG4gICAgICBtZXNzYWdlOiBgQUkgY3VzdG9taXphdGlvbiBlbGVtZW50IGluc3RhbGxlZCBzdWNjZXNzZnVsbHkhYCxcbiAgICAgIG1ldGFkYXRhLFxuICAgICAgZmlsZW5hbWUsXG4gICAgICBlbGVtZW50VHlwZVxuICAgIH07XG4gIH1cbiAgXG4gIC8qKlxuICAgKiBHZXQgRWxlbWVudFR5cGUgZnJvbSBzdHJpbmdcbiAgICovXG4gIHByaXZhdGUgZ2V0RWxlbWVudFR5cGVGcm9tU3RyaW5nKHR5cGVTdHI6IHN0cmluZyk6IEVsZW1lbnRUeXBlIHtcbiAgICBjb25zdCB0eXBlTWFwOiBSZWNvcmQ8c3RyaW5nLCBFbGVtZW50VHlwZT4gPSB7XG4gICAgICAncGVyc29uYXMnOiBFbGVtZW50VHlwZS5QRVJTT05BLFxuICAgICAgJ3NraWxscyc6IEVsZW1lbnRUeXBlLlNLSUxMLFxuICAgICAgJ3RlbXBsYXRlcyc6IEVsZW1lbnRUeXBlLlRFTVBMQVRFLFxuICAgICAgJ2FnZW50cyc6IEVsZW1lbnRUeXBlLkFHRU5UXG4gICAgfTtcbiAgICBcbiAgICBjb25zdCBlbGVtZW50VHlwZSA9IHR5cGVNYXBbdHlwZVN0cl07XG4gICAgaWYgKCFlbGVtZW50VHlwZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIGVsZW1lbnQgdHlwZTogJHt0eXBlU3RyfS4gVmFsaWQgdHlwZXM6ICR7T2JqZWN0LmtleXModHlwZU1hcCkuam9pbignLCAnKX1gKTtcbiAgICB9XG4gICAgXG4gICAgcmV0dXJuIGVsZW1lbnRUeXBlO1xuICB9XG4gIFxuICAvKipcbiAgICogRm9ybWF0IGluc3RhbGxhdGlvbiBzdWNjZXNzIG1lc3NhZ2VcbiAgICovXG4gIGZvcm1hdEluc3RhbGxTdWNjZXNzKG1ldGFkYXRhOiBJRWxlbWVudE1ldGFkYXRhLCBmaWxlbmFtZTogc3RyaW5nLCBlbGVtZW50VHlwZTogRWxlbWVudFR5cGUpOiBzdHJpbmcge1xuICAgIGNvbnN0IHR5cGVFbW9qaXM6IFJlY29yZDxFbGVtZW50VHlwZSwgc3RyaW5nPiA9IHtcbiAgICAgIFtFbGVtZW50VHlwZS5QRVJTT05BXTogJ/Cfjq0nLFxuICAgICAgW0VsZW1lbnRUeXBlLlNLSUxMXTogJ/Cfjq8nLFxuICAgICAgW0VsZW1lbnRUeXBlLlRFTVBMQVRFXTogJ/Cfk4QnLFxuICAgICAgW0VsZW1lbnRUeXBlLkFHRU5UXTogJ/CfpJYnLFxuICAgICAgW0VsZW1lbnRUeXBlLk1FTU9SWV06ICfwn6egJyxcbiAgICAgIFtFbGVtZW50VHlwZS5FTlNFTUJMRV06ICfwn468J1xuICAgIH07XG4gICAgXG4gICAgY29uc3QgZW1vamkgPSB0eXBlRW1vamlzW2VsZW1lbnRUeXBlXSB8fCAn8J+Tpic7XG4gICAgY29uc3QgdHlwZU5hbWUgPSBlbGVtZW50VHlwZS5jaGFyQXQoMCkudG9VcHBlckNhc2UoKSArIGVsZW1lbnRUeXBlLnNsaWNlKDEpO1xuICAgIFxuICAgIHJldHVybiBg4pyFICoqQUkgQ3VzdG9taXphdGlvbiBFbGVtZW50IEluc3RhbGxlZCBTdWNjZXNzZnVsbHkhKipcXG5cXG5gICtcbiAgICAgIGAke2Vtb2ppfSAqKiR7bWV0YWRhdGEubmFtZX0qKiAke21ldGFkYXRhLmF1dGhvciA/IGBieSAke21ldGFkYXRhLmF1dGhvcn1gIDogJyd9XFxuYCArXG4gICAgICBg8J+TgSBUeXBlOiAke3R5cGVOYW1lfVxcbmAgK1xuICAgICAgYPCfk4QgU2F2ZWQgYXM6ICR7ZmlsZW5hbWV9XFxuXFxuYCArXG4gICAgICBg8J+agCAqKlJlYWR5IHRvIHVzZSEqKmA7XG4gIH1cbn0iXX0=
202
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRWxlbWVudEluc3RhbGxlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb2xsZWN0aW9uL0VsZW1lbnRJbnN0YWxsZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FtQkc7QUFFSCxPQUFPLEtBQUssRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUNsQyxPQUFPLEtBQUssSUFBSSxNQUFNLE1BQU0sQ0FBQztBQUc3QixPQUFPLEVBQUUsWUFBWSxFQUFFLGdCQUFnQixFQUFFLG1CQUFtQixFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDcEcsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQzNELE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQ25FLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQ25FLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUMzRCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsV0FBVyxFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFFakYsTUFBTSxPQUFPLGdCQUFnQjtJQUNuQixZQUFZLENBQWU7SUFDM0IsZ0JBQWdCLENBQW1CO0lBQ25DLE9BQU8sR0FBRywrREFBK0QsQ0FBQztJQUVsRixZQUFZLFlBQTBCO1FBQ3BDLElBQUksQ0FBQyxZQUFZLEdBQUcsWUFBWSxDQUFDO1FBQ2pDLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxnQkFBZ0IsQ0FBQyxXQUFXLEVBQUUsQ0FBQztJQUN6RCxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0gsS0FBSyxDQUFDLGNBQWMsQ0FBQyxTQUFpQjtRQU9wQyx1REFBdUQ7UUFDdkQsTUFBTSxhQUFhLEdBQUcsWUFBWSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBRTlDLHdFQUF3RTtRQUN4RSxrRUFBa0U7UUFDbEUsTUFBTSxTQUFTLEdBQUcsYUFBYSxDQUFD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QUF3QjtRQUN6RixNQUFNLFVBQVUsR0FBZ0M7WUFDOUMsQ0FBQyxXQUFXLENBQUMsT0FBTyxDQUFDLEVBQUUsSUFBSTtZQUMzQixDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsRUFBRSxJQUFJO1lBQ3pCLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxFQUFFLElBQUk7WUFDNUIsQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLEVBQUUsSUFBSTtZQUN6QixDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsRUFBRSxJQUFJO1lBQzFCLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxFQUFFLElBQUk7U0FDN0IsQ0FBQztRQUVGLE1BQU0sS0FBSyxHQUFHLFVBQVUsQ0FBQyxXQUFXLENBQUMsSUFBSSxJQUFJLENBQUM7UUFDOUMsTUFBTSxRQUFRLEdBQUcsV0FBVyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxXQUFXLEVBQUUsR0FBRyxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRTVFLE9BQU8sNERBQTREO1lBQ2pFLEdBQUcsS0FBSyxNQUFNLFFBQVEsQ0FBQyxJQUFJLE1BQU0sUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsTUFBTSxRQUFRLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsSUFBSTtZQUNuRixZQUFZLFFBQVEsSUFBSTtZQUN4QixnQkFBZ0IsUUFBUSxNQUFNO1lBQzlCLHNCQUFzQixDQUFDO0lBQzNCLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogSW5zdGFsbCBBSSBjdXN0b21pemF0aW9uIGVsZW1lbnRzIGZyb20gY29sbGVjdGlvblxuICogU3VwcG9ydHMgYWxsIGVsZW1lbnQgdHlwZXM6IHBlcnNvbmFzLCBza2lsbHMsIHRlbXBsYXRlcywgYWdlbnRzLCBtZW1vcmllcywgZW5zZW1ibGVzXG4gKiBcbiAqIFNFQ1VSSVRZIEZJWCAoMjAyNS0wOC0xMik6IEZpeGVkIGNyaXRpY2FsIHZ1bG5lcmFiaWxpdHkgd2hlcmUgY29udGVudCB3YXMgd3JpdHRlbiB0byBkaXNrXG4gKiBCRUZPUkUgdmFsaWRhdGlvbiB3YXMgY29tcGxldGUuIFRoaXMgY291bGQgYWxsb3cgbWFsaWNpb3VzIGNvbnRlbnQgdG8gcGVyc2lzdCBvbiB0aGVcbiAqIGZpbGVzeXN0ZW0gZXZlbiB3aGVuIHZhbGlkYXRpb24gZmFpbGVkLiBUaGUgZml4IGltcGxlbWVudHM6XG4gKiBcbiAqIDEuIFZBTElEQVRFLUJFRk9SRS1XUklURSBQQVRURVJOOiBBbGwgY29udGVudCB2YWxpZGF0aW9uIChDb250ZW50VmFsaWRhdG9yLnNhbml0aXplUGVyc29uYUNvbnRlbnQsXG4gKiAgICBTZWN1cmVZYW1sUGFyc2VyLnNhZmVNYXR0ZXIsIG1ldGFkYXRhIHZhbGlkYXRpb24sIGV0Yy4pIGlzIG5vdyBwZXJmb3JtZWQgQkVGT1JFIGFueSBkaXNrIG9wZXJhdGlvbnMuXG4gKiBcbiAqIDIuIEFUT01JQyBGSUxFIE9QRVJBVElPTlM6IFVzZXMgdGVtcG9yYXJ5IGZpbGUgKyBhdG9taWMgcmVuYW1lIHRvIHByZXZlbnQgcGFydGlhbCBmaWxlIGNvcnJ1cHRpb25cbiAqICAgIGFuZCBlbnN1cmUgY29tcGxldGUgY2xlYW51cCBvbiBhbnkgZmFpbHVyZSBkdXJpbmcgdGhlIHdyaXRlIHByb2Nlc3MuXG4gKiBcbiAqIDMuIEdVQVJBTlRFRUQgQ0xFQU5VUDogSWYgYW55IHBhcnQgb2YgdGhlIHdyaXRlIG9wZXJhdGlvbiBmYWlscywgdGVtcG9yYXJ5IGZpbGVzIGFyZSBhdXRvbWF0aWNhbGx5XG4gKiAgICBjbGVhbmVkIHVwLCBwcmV2ZW50aW5nIG9ycGhhbmVkIG1hbGljaW91cyBjb250ZW50IG9uIHRoZSBmaWxlc3lzdGVtLlxuICogXG4gKiBUaGUgdnVsbmVyYWJpbGl0eSBleGlzdGVkIGluIGluc3RhbGxDb250ZW50KCkgd2hlcmUgZnMud3JpdGVGaWxlKCkgd2FzIGNhbGxlZCBhZnRlciB2YWxpZGF0aW9uXG4gKiBidXQgYmVmb3JlIGZpbmFsIHN1Y2Nlc3MgY29uZmlybWF0aW9uLCBjcmVhdGluZyBhIHdpbmRvdyB3aGVyZSBtYWxpY2lvdXMgY29udGVudCBjb3VsZCBwZXJzaXN0LlxuICovXG5cbmltcG9ydCAqIGFzIGZzIGZyb20gJ2ZzL3Byb21pc2VzJztcbmltcG9ydCAqIGFzIHBhdGggZnJvbSAncGF0aCc7XG5pbXBvcnQgeyBHaXRIdWJDbGllbnQgfSBmcm9tICcuL0dpdEh1YkNsaWVudC5qcyc7XG5pbXBvcnQgeyBJRWxlbWVudE1ldGFkYXRhIH0gZnJvbSAnLi4vdHlwZXMvZWxlbWVudHMvSUVsZW1lbnQuanMnO1xuaW1wb3J0IHsgdmFsaWRhdGVQYXRoLCB2YWxpZGF0ZUZpbGVuYW1lLCB2YWxpZGF0ZUNvbnRlbnRTaXplIH0gZnJvbSAnLi4vc2VjdXJpdHkvSW5wdXRWYWxpZGF0b3IuanMnO1xuaW1wb3J0IHsgU0VDVVJJVFlfTElNSVRTIH0gZnJvbSAnLi4vc2VjdXJpdHkvY29uc3RhbnRzLmpzJztcbmltcG9ydCB7IENvbnRlbnRWYWxpZGF0b3IgfSBmcm9tICcuLi9zZWN1cml0eS9jb250ZW50VmFsaWRhdG9yLmpzJztcbmltcG9ydCB7IFNlY3VyZVlhbWxQYXJzZXIgfSBmcm9tICcuLi9zZWN1cml0eS9zZWN1cmVZYW1sUGFyc2VyLmpzJztcbmltcG9ydCB7IFNlY3VyaXR5RXJyb3IgfSBmcm9tICcuLi9lcnJvcnMvU2VjdXJpdHlFcnJvci5qcyc7XG5pbXBvcnQgeyBQb3J0Zm9saW9NYW5hZ2VyLCBFbGVtZW50VHlwZSB9IGZyb20gJy4uL3BvcnRmb2xpby9Qb3J0Zm9saW9NYW5hZ2VyLmpzJztcblxuZXhwb3J0IGNsYXNzIEVsZW1lbnRJbnN0YWxsZXIge1xuICBwcml2YXRlIGdpdGh1YkNsaWVudDogR2l0SHViQ2xpZW50O1xuICBwcml2YXRlIHBvcnRmb2xpb01hbmFnZXI6IFBvcnRmb2xpb01hbmFnZXI7XG4gIHByaXZhdGUgYmFzZVVybCA9ICdodHRwczovL2FwaS5naXRodWIuY29tL3JlcG9zL0RvbGxob3VzZU1DUC9jb2xsZWN0aW9uL2NvbnRlbnRzJztcbiAgXG4gIGNvbnN0cnVjdG9yKGdpdGh1YkNsaWVudDogR2l0SHViQ2xpZW50KSB7XG4gICAgdGhpcy5naXRodWJDbGllbnQgPSBnaXRodWJDbGllbnQ7XG4gICAgdGhpcy5wb3J0Zm9saW9NYW5hZ2VyID0gUG9ydGZvbGlvTWFuYWdlci5nZXRJbnN0YW5jZSgpO1xuICB9XG4gIFxuICAvKipcbiAgICogSW5zdGFsbCBBSSBjdXN0b21pemF0aW9uIGVsZW1lbnQgZnJvbSB0aGUgY29sbGVjdGlvblxuICAgKiBBdXRvbWF0aWNhbGx5IGRldGVjdHMgZWxlbWVudCB0eXBlIGZyb20gcGF0aCBzdHJ1Y3R1cmVcbiAgICogXG4gICAqIFNFQ1VSSVRZIEZJWDogSW1wbGVtZW50cyB2YWxpZGF0ZS1iZWZvcmUtd3JpdGUgcGF0dGVybiB3aXRoIGF0b21pYyBvcGVyYXRpb25zXG4gICAqIHRvIHByZXZlbnQgbWFsaWNpb3VzIGNvbnRlbnQgcGVyc2lzdGVuY2Ugb24gdmFsaWRhdGlvbiBmYWlsdXJlLlxuICAgKi9cbiAgYXN5bmMgaW5zdGFsbENvbnRlbnQoaW5wdXRQYXRoOiBzdHJpbmcpOiBQcm9taXNlPHsgXG4gICAgc3VjY2VzczogYm9vbGVhbjsgXG4gICAgbWVzc2FnZTogc3RyaW5nO1xuICAgIG1ldGFkYXRhPzogSUVsZW1lbnRNZXRhZGF0YTtcbiAgICBlbGVtZW50VHlwZT86IEVsZW1lbnRUeXBlO1xuICAgIGZpbGVuYW1lPzogc3RyaW5nO1xuICB9PiB7XG4gICAgLy8gU0VDVVJJVFk6IFZhbGlkYXRlIGFuZCBzYW5pdGl6ZSB0aGUgaW5wdXQgcGF0aCBmaXJzdFxuICAgIGNvbnN0IHNhbml0aXplZFBhdGggPSB2YWxpZGF0ZVBhdGgoaW5wdXRQYXRoKTtcbiAgICBcbiAgICAvLyBTRUNVUklUWTogRGV0ZWN0IGVsZW1lbnQgdHlwZSBmcm9tIHBhdGggc3RydWN0dXJlIGFuZCB2YWxpZGF0ZSBmb3JtYXRcbiAgICAvLyBFeHBlY3RlZCBmb3JtYXQ6IGxpYnJhcnkvW2VsZW1lbnQtdHlwZV0vW2NhdGVnb3J5XS9bZWxlbWVudF0ubWRcbiAgICBjb25zdCBwYXRoUGFydHMgPSBzYW5pdGl6ZWRQYXRoLnNwbGl0KCcvJyk7XG4gICAgaWYgKHBhdGhQYXJ0cy5sZW5ndGggPCAzIHx8IHBhdGhQYXJ0c1swXSAhPT0gJ2xpYnJhcnknKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgY29sbGVjdGlvbiBwYXRoIGZvcm1hdC4gRXhwZWN0ZWQ6IGxpYnJhcnkvW2VsZW1lbnQtdHlwZV0vW2NhdGVnb3J5XS9bZWxlbWVudF0ubWQnKTtcbiAgICB9XG4gICAgXG4gICAgY29uc3QgZWxlbWVudFR5cGVTdHIgPSBwYXRoUGFydHNbMV07XG4gICAgY29uc3QgZWxlbWVudFR5cGUgPSB0aGlzLmdldEVsZW1lbnRUeXBlRnJvbVN0cmluZyhlbGVtZW50VHlwZVN0cik7XG4gICAgXG4gICAgLy8gU0VDVVJJVFk6IEVuc3VyZSB0aGUgcGF0aCBlbmRzIHdpdGggLm1kIHRvIHByZXZlbnQgYXJiaXRyYXJ5IGZpbGUgdHlwZXNcbiAgICBpZiAoIXNhbml0aXplZFBhdGguZW5kc1dpdGgoJy5tZCcpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgZmlsZSB0eXBlLiBPbmx5IC5tZCBmaWxlcyBhcmUgYWxsb3dlZC4nKTtcbiAgICB9XG4gICAgXG4gICAgLy8gU1RFUCAxOiBGRVRDSCBDT05URU5UIElOVE8gTUVNT1JZIChOTyBESVNLIE9QRVJBVElPTlMgWUVUKVxuICAgIGNvbnN0IHVybCA9IGAke3RoaXMuYmFzZVVybH0vJHtzYW5pdGl6ZWRQYXRofWA7XG4gICAgY29uc3QgZGF0YSA9IGF3YWl0IHRoaXMuZ2l0aHViQ2xpZW50LmZldGNoRnJvbUdpdEh1Yih1cmwpO1xuICAgIFxuICAgIGlmIChkYXRhLnR5cGUgIT09ICdmaWxlJykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdQYXRoIGRvZXMgbm90IHBvaW50IHRvIGEgZmlsZScpO1xuICAgIH1cbiAgICBcbiAgICAvLyBTRUNVUklUWTogQ2hlY2sgZmlsZSBzaXplIGJlZm9yZSBkb3dubG9hZGluZyB0byBwcmV2ZW50IERvUyBhdHRhY2tzXG4gICAgaWYgKGRhdGEuc2l6ZSA+IFNFQ1VSSVRZX0xJTUlUUy5NQVhfUEVSU09OQV9TSVpFX0JZVEVTKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEZpbGUgdG9vIGxhcmdlICgke2RhdGEuc2l6ZX0gYnl0ZXMsIG1heCAke1NFQ1VSSVRZX0xJTUlUUy5NQVhfUEVSU09OQV9TSVpFX0JZVEVTfSBieXRlcylgKTtcbiAgICB9XG4gICAgXG4gICAgLy8gRGVjb2RlIEJhc2U2NCBjb250ZW50IGludG8gbWVtb3J5IG9ubHlcbiAgICBjb25zdCBjb250ZW50ID0gQnVmZmVyLmZyb20oZGF0YS5jb250ZW50LCAnYmFzZTY0JykudG9TdHJpbmcoJ3V0Zi04Jyk7XG4gICAgXG4gICAgLy8gU1RFUCAyOiBQRVJGT1JNIEFMTCBWQUxJREFUSU9OIEJFRk9SRSBBTlkgRElTSyBPUEVSQVRJT05TXG4gICAgLy8gVGhpcyBpcyB0aGUgY3JpdGljYWwgc2VjdXJpdHkgZml4IC0gdmFsaWRhdGUgZXZlcnl0aGluZyBpbiBtZW1vcnkgZmlyc3RcbiAgICBcbiAgICAvLyBTRUNVUklUWTogVmFsaWRhdGUgY29udGVudCBzaXplIGFmdGVyIGRlY29kaW5nXG4gICAgdmFsaWRhdGVDb250ZW50U2l6ZShjb250ZW50LCBTRUNVUklUWV9MSU1JVFMuTUFYX1BFUlNPTkFfU0laRV9CWVRFUyk7XG4gICAgXG4gICAgLy8gU0VDVVJJVFk6IFNhbml0aXplIGNvbnRlbnQgZm9yIHNlY3VyaXR5IHRocmVhdHMgKFhTUywgaW5qZWN0aW9uLCBldGMuKVxuICAgIGNvbnN0IHNhbml0aXplZENvbnRlbnQgPSBDb250ZW50VmFsaWRhdG9yLnNhbml0aXplUGVyc29uYUNvbnRlbnQoY29udGVudCk7XG4gICAgXG4gICAgLy8gU0VDVVJJVFk6IFVzZSBzZWN1cmUgWUFNTCBwYXJzZXIgdG8gcHJldmVudCBZQU1MIGJvbWJzIGFuZCBpbmplY3Rpb25cbiAgICBsZXQgcGFyc2VkO1xuICAgIHRyeSB7XG4gICAgICBwYXJzZWQgPSBTZWN1cmVZYW1sUGFyc2VyLnNhZmVNYXR0ZXIoc2FuaXRpemVkQ29udGVudCk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIFNlY3VyaXR5RXJyb3IpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBTZWN1cml0eSB0aHJlYXQgaW4gY29udGVudDogJHtlcnJvci5tZXNzYWdlfWApO1xuICAgICAgfVxuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfVxuICAgIFxuICAgIGNvbnN0IG1ldGFkYXRhID0gcGFyc2VkLmRhdGEgYXMgSUVsZW1lbnRNZXRhZGF0YTtcbiAgICBcbiAgICAvLyBTRUNVUklUWTogQWRkaXRpb25hbCBtZXRhZGF0YSB2YWxpZGF0aW9uIGZvciBpbmplY3Rpb24gYXR0YWNrc1xuICAgIGNvbnN0IG1ldGFkYXRhVmFsaWRhdGlvbiA9IENvbnRlbnRWYWxpZGF0b3IudmFsaWRhdGVNZXRhZGF0YShtZXRhZGF0YSk7XG4gICAgaWYgKCFtZXRhZGF0YVZhbGlkYXRpb24uaXNWYWxpZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBTZWN1cml0eSB2YWxpZGF0aW9uIGZhaWxlZDogJHttZXRhZGF0YVZhbGlkYXRpb24uZGV0ZWN0ZWRQYXR0ZXJucz8uam9pbignLCAnKX1gKTtcbiAgICB9XG4gICAgXG4gICAgLy8gU0VDVVJJVFk6IFZhbGlkYXRlIHJlcXVpcmVkIG1ldGFkYXRhIGZpZWxkc1xuICAgIGlmICghbWV0YWRhdGEubmFtZSB8fCAhbWV0YWRhdGEuZGVzY3JpcHRpb24pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBjb250ZW50OiBtaXNzaW5nIHJlcXVpcmVkIG5hbWUgb3IgZGVzY3JpcHRpb24nKTtcbiAgICB9XG4gICAgXG4gICAgLy8gU0VDVVJJVFk6IEdlbmVyYXRlIGFuZCB2YWxpZGF0ZSBsb2NhbCBmaWxlbmFtZSB0byBwcmV2ZW50IHBhdGggdHJhdmVyc2FsXG4gICAgY29uc3Qgb3JpZ2luYWxGaWxlbmFtZSA9IHNhbml0aXplZFBhdGguc3BsaXQoJy8nKS5wb3AoKSB8fCAnZG93bmxvYWRlZC1lbGVtZW50Lm1kJztcbiAgICBjb25zdCBmaWxlbmFtZSA9IHZhbGlkYXRlRmlsZW5hbWUob3JpZ2luYWxGaWxlbmFtZSk7XG4gICAgXG4gICAgLy8gR2V0IGFwcHJvcHJpYXRlIGRpcmVjdG9yeSBmb3IgZWxlbWVudCB0eXBlXG4gICAgY29uc3QgZWxlbWVudERpciA9IHRoaXMucG9ydGZvbGlvTWFuYWdlci5nZXRFbGVtZW50RGlyKGVsZW1lbnRUeXBlKTtcbiAgICBjb25zdCBsb2NhbFBhdGggPSBwYXRoLmpvaW4oZWxlbWVudERpciwgZmlsZW5hbWUpO1xuICAgIFxuICAgIC8vIFNFQ1VSSVRZOiBDaGVjayBpZiBmaWxlIGFscmVhZHkgZXhpc3RzIGJlZm9yZSBhbnkgd3JpdGUgb3BlcmF0aW9uc1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCBmcy5hY2Nlc3MobG9jYWxQYXRoKTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgICAgICBtZXNzYWdlOiBgQUkgY3VzdG9taXphdGlvbiBlbGVtZW50IGFscmVhZHkgZXhpc3RzOiAke2ZpbGVuYW1lfVxcblxcblRoZSBlbGVtZW50IGhhcyBhbHJlYWR5IGJlZW4gaW5zdGFsbGVkLmBcbiAgICAgIH07XG4gICAgfSBjYXRjaCB7XG4gICAgICAvLyBGaWxlIGRvZXNuJ3QgZXhpc3QsIHByb2NlZWQgd2l0aCBpbnN0YWxsYXRpb25cbiAgICB9XG4gICAgXG4gICAgLy8gU1RFUCAzOiBBTEwgVkFMSURBVElPTiBDT01QTEVURSAtIE5PVyBQRVJGT1JNIEFUT01JQyBXUklURSBPUEVSQVRJT05cbiAgICAvLyBTRUNVUklUWSBGSVg6IFVzZSBhdG9taWMgd3JpdGUgdG8gcHJldmVudCBwYXJ0aWFsIGZpbGUgY29ycnVwdGlvbiBhbmRcbiAgICAvLyBlbnN1cmUgY2xlYW51cCBvbiBhbnkgZmFpbHVyZSBkdXJpbmcgdGhlIHdyaXRlIHByb2Nlc3NcbiAgICBhd2FpdCB0aGlzLmF0b21pY1dyaXRlRmlsZShsb2NhbFBhdGgsIHNhbml0aXplZENvbnRlbnQpO1xuICAgIFxuICAgIHJldHVybiB7XG4gICAgICBzdWNjZXNzOiB0cnVlLFxuICAgICAgbWVzc2FnZTogYEFJIGN1c3RvbWl6YXRpb24gZWxlbWVudCBpbnN0YWxsZWQgc3VjY2Vzc2Z1bGx5IWAsXG4gICAgICBtZXRhZGF0YSxcbiAgICAgIGZpbGVuYW1lLFxuICAgICAgZWxlbWVudFR5cGVcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEF0b21pYyBmaWxlIHdyaXRlIG9wZXJhdGlvbiB3aXRoIGd1YXJhbnRlZWQgY2xlYW51cCBvbiBmYWlsdXJlXG4gICAqIFxuICAgKiBTRUNVUklUWSBGSVg6IFRoaXMgbWV0aG9kIGVuc3VyZXMgdGhhdCBmaWxlIHdyaXRlcyBhcmUgYXRvbWljIGFuZCBhbnlcbiAgICogZmFpbHVyZXMgZHVyaW5nIHRoZSB3cml0ZSBwcm9jZXNzIHdpbGwgbm90IGxlYXZlIHBhcnRpYWwgb3IgY29ycnVwdGVkXG4gICAqIGZpbGVzIG9uIHRoZSBmaWxlc3lzdGVtLiBVc2VzIHRlbXBvcmFyeSBmaWxlICsgcmVuYW1lIGZvciBhdG9taWNpdHkuXG4gICAqIFxuICAgKiBAcGFyYW0gZGVzdGluYXRpb24gLSBGaW5hbCBkZXN0aW5hdGlvbiBwYXRoIGZvciB0aGUgZmlsZVxuICAgKiBAcGFyYW0gY29udGVudCAtIENvbnRlbnQgdG8gd3JpdGUgdG8gdGhlIGZpbGVcbiAgICogQHRocm93cyBFcnJvciBpZiB3cml0ZSBvcGVyYXRpb24gZmFpbHMgKHdpdGggZ3VhcmFudGVlZCBjbGVhbnVwKVxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBhdG9taWNXcml0ZUZpbGUoZGVzdGluYXRpb246IHN0cmluZywgY29udGVudDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgLy8gR2VuZXJhdGUgdW5pcXVlIHRlbXBvcmFyeSBmaWxlIG5hbWUgdG8gYXZvaWQgY29sbGlzaW9uc1xuICAgIGNvbnN0IHRlbXBGaWxlID0gYCR7ZGVzdGluYXRpb259LnRtcC4ke0RhdGUubm93KCl9LiR7TWF0aC5yYW5kb20oKS50b1N0cmluZygzNikuc3Vic3RyaW5nKDIpfWA7XG4gICAgXG4gICAgdHJ5IHtcbiAgICAgIC8vIFNFQ1VSSVRZOiBXcml0ZSB0byB0ZW1wb3JhcnkgZmlsZSBmaXJzdFxuICAgICAgLy8gSWYgdGhpcyBmYWlscywgbm8gZmlsZXMgYXJlIGxlZnQgb24gZGlza1xuICAgICAgYXdhaXQgZnMud3JpdGVGaWxlKHRlbXBGaWxlLCBjb250ZW50LCAndXRmLTgnKTtcbiAgICAgIFxuICAgICAgLy8gU0VDVVJJVFk6IEF0b21pYyByZW5hbWUgb3BlcmF0aW9uXG4gICAgICAvLyBPbiBtb3N0IGZpbGVzeXN0ZW1zLCByZW5hbWUgaXMgYXRvbWljIC0gdGhlIGZpbGUgYXBwZWFycyB3aXRoIGNvbXBsZXRlIGNvbnRlbnRcbiAgICAgIC8vIG9yIGRvZXNuJ3QgYXBwZWFyIGF0IGFsbC4gVGhpcyBwcmV2ZW50cyBwYXJ0aWFsIGZpbGUgY29ycnVwdGlvbi5cbiAgICAgIGF3YWl0IGZzLnJlbmFtZSh0ZW1wRmlsZSwgZGVzdGluYXRpb24pO1xuICAgICAgXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIC8vIFNFQ1VSSVRZOiBHdWFyYW50ZWVkIGNsZWFudXAgb2YgdGVtcG9yYXJ5IGZpbGUgb24gQU5ZIGZhaWx1cmVcbiAgICAgIC8vIFRoaXMgZW5zdXJlcyBubyB0ZW1wb3JhcnkgZmlsZXMgYXJlIGxlZnQgYmVoaW5kIGV2ZW4gaWYgdGhlXG4gICAgICAvLyByZW5hbWUgb3BlcmF0aW9uIGZhaWxzIGFmdGVyIHN1Y2Nlc3NmdWwgd3JpdGVcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IGZzLnVubGluayh0ZW1wRmlsZSk7XG4gICAgICB9IGNhdGNoIChjbGVhbnVwRXJyb3IpIHtcbiAgICAgICAgLy8gSWdub3JlIGNsZWFudXAgZXJyb3JzIC0gdGhlIGZpbGUgbWF5IG5vdCBleGlzdCBpZiB3cml0ZUZpbGUgZmFpbGVkXG4gICAgICAgIC8vIFRoZSBvcmlnaW5hbCBlcnJvciBpcyBtb3JlIGltcG9ydGFudCB0byBwcm9wYWdhdGVcbiAgICAgIH1cbiAgICAgIFxuICAgICAgLy8gUmUtdGhyb3cgdGhlIG9yaWdpbmFsIGVycm9yIHRvIG1haW50YWluIGVycm9yIGhhbmRsaW5nIHNlbWFudGljc1xuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfVxuICB9XG4gIFxuICAvKipcbiAgICogR2V0IEVsZW1lbnRUeXBlIGZyb20gc3RyaW5nXG4gICAqL1xuICBwcml2YXRlIGdldEVsZW1lbnRUeXBlRnJvbVN0cmluZyh0eXBlU3RyOiBzdHJpbmcpOiBFbGVtZW50VHlwZSB7XG4gICAgY29uc3QgdHlwZU1hcDogUmVjb3JkPHN0cmluZywgRWxlbWVudFR5cGU+ID0ge1xuICAgICAgJ3BlcnNvbmFzJzogRWxlbWVudFR5cGUuUEVSU09OQSxcbiAgICAgICdza2lsbHMnOiBFbGVtZW50VHlwZS5TS0lMTCxcbiAgICAgICd0ZW1wbGF0ZXMnOiBFbGVtZW50VHlwZS5URU1QTEFURSxcbiAgICAgICdhZ2VudHMnOiBFbGVtZW50VHlwZS5BR0VOVFxuICAgIH07XG4gICAgXG4gICAgY29uc3QgZWxlbWVudFR5cGUgPSB0eXBlTWFwW3R5cGVTdHJdO1xuICAgIGlmICghZWxlbWVudFR5cGUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgVW5rbm93biBlbGVtZW50IHR5cGU6ICR7dHlwZVN0cn0uIFZhbGlkIHR5cGVzOiAke09iamVjdC5rZXlzKHR5cGVNYXApLmpvaW4oJywgJyl9YCk7XG4gICAgfVxuICAgIFxuICAgIHJldHVybiBlbGVtZW50VHlwZTtcbiAgfVxuICBcbiAgLyoqXG4gICAqIEZvcm1hdCBpbnN0YWxsYXRpb24gc3VjY2VzcyBtZXNzYWdlXG4gICAqL1xuICBmb3JtYXRJbnN0YWxsU3VjY2VzcyhtZXRhZGF0YTogSUVsZW1lbnRNZXRhZGF0YSwgZmlsZW5hbWU6IHN0cmluZywgZWxlbWVudFR5cGU6IEVsZW1lbnRUeXBlKTogc3RyaW5nIHtcbiAgICBjb25zdCB0eXBlRW1vamlzOiBSZWNvcmQ8RWxlbWVudFR5cGUsIHN0cmluZz4gPSB7XG4gICAgICBbRWxlbWVudFR5cGUuUEVSU09OQV06ICfwn46tJyxcbiAgICAgIFtFbGVtZW50VHlwZS5TS0lMTF06ICfwn46vJyxcbiAgICAgIFtFbGVtZW50VHlwZS5URU1QTEFURV06ICfwn5OEJyxcbiAgICAgIFtFbGVtZW50VHlwZS5BR0VOVF06ICfwn6SWJyxcbiAgICAgIFtFbGVtZW50VHlwZS5NRU1PUlldOiAn8J+noCcsXG4gICAgICBbRWxlbWVudFR5cGUuRU5TRU1CTEVdOiAn8J+OvCdcbiAgICB9O1xuICAgIFxuICAgIGNvbnN0IGVtb2ppID0gdHlwZUVtb2ppc1tlbGVtZW50VHlwZV0gfHwgJ/Cfk6YnO1xuICAgIGNvbnN0IHR5cGVOYW1lID0gZWxlbWVudFR5cGUuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyBlbGVtZW50VHlwZS5zbGljZSgxKTtcbiAgICBcbiAgICByZXR1cm4gYOKchSAqKkFJIEN1c3RvbWl6YXRpb24gRWxlbWVudCBJbnN0YWxsZWQgU3VjY2Vzc2Z1bGx5ISoqXFxuXFxuYCArXG4gICAgICBgJHtlbW9qaX0gKioke21ldGFkYXRhLm5hbWV9KiogJHttZXRhZGF0YS5hdXRob3IgPyBgYnkgJHttZXRhZGF0YS5hdXRob3J9YCA6ICcnfVxcbmAgK1xuICAgICAgYPCfk4EgVHlwZTogJHt0eXBlTmFtZX1cXG5gICtcbiAgICAgIGDwn5OEIFNhdmVkIGFzOiAke2ZpbGVuYW1lfVxcblxcbmAgK1xuICAgICAgYPCfmoAgKipSZWFkeSB0byB1c2UhKipgO1xuICB9XG59Il19