@dollhousemcp/mcp-server 1.5.2 → 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 (272) hide show
  1. package/CHANGELOG.md +56 -0
  2. package/README.md +494 -111
  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.map +1 -1
  41. package/dist/cache/CollectionCache.js +13 -3
  42. package/dist/cache/CollectionIndexCache.d.ts +77 -0
  43. package/dist/cache/CollectionIndexCache.d.ts.map +1 -0
  44. package/dist/cache/CollectionIndexCache.js +349 -0
  45. package/dist/cache/LRUCache.d.ts +93 -0
  46. package/dist/cache/LRUCache.d.ts.map +1 -0
  47. package/dist/cache/LRUCache.js +299 -0
  48. package/dist/cache/index.d.ts +1 -0
  49. package/dist/cache/index.d.ts.map +1 -1
  50. package/dist/cache/index.js +2 -1
  51. package/dist/collection/CollectionBrowser.d.ts +21 -1
  52. package/dist/collection/CollectionBrowser.d.ts.map +1 -1
  53. package/dist/collection/CollectionBrowser.js +130 -10
  54. package/dist/collection/CollectionIndexManager.d.ts +151 -0
  55. package/dist/collection/CollectionIndexManager.d.ts.map +1 -0
  56. package/dist/collection/CollectionIndexManager.js +499 -0
  57. package/dist/collection/CollectionSearch.d.ts +55 -0
  58. package/dist/collection/CollectionSearch.d.ts.map +1 -1
  59. package/dist/collection/CollectionSearch.js +338 -13
  60. package/dist/collection/CollectionSeeder.d.ts.map +1 -1
  61. package/dist/collection/CollectionSeeder.js +38 -1
  62. package/dist/collection/ElementInstaller.d.ts +31 -0
  63. package/dist/collection/ElementInstaller.d.ts.map +1 -1
  64. package/dist/collection/ElementInstaller.js +77 -15
  65. package/dist/collection/PersonaSubmitter.d.ts +1 -1
  66. package/dist/collection/PersonaSubmitter.d.ts.map +1 -1
  67. package/dist/collection/PersonaSubmitter.js +2 -2
  68. package/dist/collection/index.d.ts +1 -0
  69. package/dist/collection/index.d.ts.map +1 -1
  70. package/dist/collection/index.js +2 -1
  71. package/dist/config/ConfigManager.d.ts +78 -0
  72. package/dist/config/ConfigManager.d.ts.map +1 -0
  73. package/dist/config/ConfigManager.js +216 -0
  74. package/dist/config/element-types.d.ts +135 -0
  75. package/dist/config/element-types.d.ts.map +1 -0
  76. package/dist/config/element-types.js +108 -0
  77. package/dist/config/index.d.ts +2 -0
  78. package/dist/config/index.d.ts.map +1 -1
  79. package/dist/config/index.js +3 -1
  80. package/dist/config/portfolio-constants.d.ts +83 -0
  81. package/dist/config/portfolio-constants.d.ts.map +1 -0
  82. package/dist/config/portfolio-constants.js +99 -0
  83. package/dist/elements/BaseElement.d.ts +14 -2
  84. package/dist/elements/BaseElement.d.ts.map +1 -1
  85. package/dist/elements/BaseElement.js +88 -6
  86. package/dist/elements/agents/Agent.d.ts +10 -1
  87. package/dist/elements/agents/Agent.d.ts.map +1 -1
  88. package/dist/elements/agents/Agent.js +66 -19
  89. package/dist/elements/agents/AgentManager.d.ts +2 -0
  90. package/dist/elements/agents/AgentManager.d.ts.map +1 -1
  91. package/dist/elements/agents/AgentManager.js +12 -10
  92. package/dist/elements/skills/Skill.d.ts +10 -1
  93. package/dist/elements/skills/Skill.d.ts.map +1 -1
  94. package/dist/elements/skills/Skill.js +40 -3
  95. package/dist/elements/skills/SkillManager.d.ts +1 -0
  96. package/dist/elements/skills/SkillManager.d.ts.map +1 -1
  97. package/dist/elements/skills/SkillManager.js +10 -4
  98. package/dist/elements/templates/Template.d.ts +10 -1
  99. package/dist/elements/templates/Template.d.ts.map +1 -1
  100. package/dist/elements/templates/Template.js +35 -18
  101. package/dist/elements/templates/TemplateManager.d.ts +1 -1
  102. package/dist/elements/templates/TemplateManager.d.ts.map +1 -1
  103. package/dist/elements/templates/TemplateManager.js +6 -5
  104. package/dist/generated/version.d.ts +2 -2
  105. package/dist/generated/version.js +3 -3
  106. package/dist/index.barrel.d.ts +1 -2
  107. package/dist/index.barrel.d.ts.map +1 -1
  108. package/dist/index.barrel.js +2 -4
  109. package/dist/index.d.ts +143 -25
  110. package/dist/index.d.ts.map +1 -1
  111. package/dist/index.js +1883 -310
  112. package/dist/persona/PersonaElement.d.ts +10 -0
  113. package/dist/persona/PersonaElement.d.ts.map +1 -1
  114. package/dist/persona/PersonaElement.js +55 -32
  115. package/dist/persona/PersonaElementManager.d.ts.map +1 -1
  116. package/dist/persona/PersonaElementManager.js +13 -11
  117. package/dist/persona/PersonaLoader.d.ts.map +1 -1
  118. package/dist/persona/PersonaLoader.js +8 -2
  119. package/dist/persona/export-import/PersonaImporter.d.ts.map +1 -1
  120. package/dist/persona/export-import/PersonaImporter.js +24 -5
  121. package/dist/persona/export-import/PersonaSharer.d.ts +21 -0
  122. package/dist/persona/export-import/PersonaSharer.d.ts.map +1 -1
  123. package/dist/persona/export-import/PersonaSharer.js +198 -22
  124. package/dist/portfolio/DefaultElementProvider.d.ts +90 -0
  125. package/dist/portfolio/DefaultElementProvider.d.ts.map +1 -1
  126. package/dist/portfolio/DefaultElementProvider.js +499 -7
  127. package/dist/portfolio/GitHubPortfolioIndexer.d.ts +129 -0
  128. package/dist/portfolio/GitHubPortfolioIndexer.d.ts.map +1 -0
  129. package/dist/portfolio/GitHubPortfolioIndexer.js +475 -0
  130. package/dist/portfolio/MigrationManager.d.ts.map +1 -1
  131. package/dist/portfolio/MigrationManager.js +136 -3
  132. package/dist/portfolio/PortfolioIndexManager.d.ts +130 -0
  133. package/dist/portfolio/PortfolioIndexManager.d.ts.map +1 -0
  134. package/dist/portfolio/PortfolioIndexManager.js +478 -0
  135. package/dist/portfolio/PortfolioManager.d.ts +5 -0
  136. package/dist/portfolio/PortfolioManager.d.ts.map +1 -1
  137. package/dist/portfolio/PortfolioManager.js +61 -20
  138. package/dist/portfolio/PortfolioRepoManager.d.ts +75 -0
  139. package/dist/portfolio/PortfolioRepoManager.d.ts.map +1 -0
  140. package/dist/portfolio/PortfolioRepoManager.js +337 -0
  141. package/dist/portfolio/UnifiedIndexManager.d.ts +388 -0
  142. package/dist/portfolio/UnifiedIndexManager.d.ts.map +1 -0
  143. package/dist/portfolio/UnifiedIndexManager.js +1434 -0
  144. package/dist/portfolio/index.d.ts +15 -0
  145. package/dist/portfolio/index.d.ts.map +1 -0
  146. package/dist/portfolio/index.js +15 -0
  147. package/dist/portfolio/types.d.ts +7 -0
  148. package/dist/portfolio/types.d.ts.map +1 -1
  149. package/dist/portfolio/types.js +6 -1
  150. package/dist/security/InputValidator.d.ts.map +1 -1
  151. package/dist/security/InputValidator.js +50 -48
  152. package/dist/security/audit/SecurityAuditor.d.ts.map +1 -1
  153. package/dist/security/audit/SecurityAuditor.js +17 -9
  154. package/dist/security/audit/config/suppressions.d.ts.map +1 -1
  155. package/dist/security/audit/config/suppressions.js +19 -3
  156. package/dist/security/contentValidator.d.ts +2 -0
  157. package/dist/security/contentValidator.d.ts.map +1 -1
  158. package/dist/security/contentValidator.js +115 -4
  159. package/dist/security/secureYamlParser.d.ts +1 -0
  160. package/dist/security/secureYamlParser.d.ts.map +1 -1
  161. package/dist/security/secureYamlParser.js +29 -7
  162. package/dist/security/securityMonitor.d.ts +1 -1
  163. package/dist/security/securityMonitor.d.ts.map +1 -1
  164. package/dist/security/securityMonitor.js +1 -1
  165. package/dist/security/tokenManager.d.ts +1 -1
  166. package/dist/security/tokenManager.d.ts.map +1 -1
  167. package/dist/security/tokenManager.js +30 -10
  168. package/dist/server/ServerSetup.d.ts +22 -2
  169. package/dist/server/ServerSetup.d.ts.map +1 -1
  170. package/dist/server/ServerSetup.js +77 -12
  171. package/dist/server/tools/AuthTools.d.ts.map +1 -1
  172. package/dist/server/tools/AuthTools.js +33 -1
  173. package/dist/server/tools/BuildInfoTools.d.ts +25 -0
  174. package/dist/server/tools/BuildInfoTools.d.ts.map +1 -0
  175. package/dist/server/tools/BuildInfoTools.js +36 -0
  176. package/dist/server/tools/CollectionTools.d.ts.map +1 -1
  177. package/dist/server/tools/CollectionTools.js +55 -46
  178. package/dist/server/tools/ConfigTools.d.ts.map +1 -1
  179. package/dist/server/tools/ConfigTools.js +29 -1
  180. package/dist/server/tools/PersonaTools.d.ts +4 -2
  181. package/dist/server/tools/PersonaTools.d.ts.map +1 -1
  182. package/dist/server/tools/PersonaTools.js +5 -152
  183. package/dist/server/tools/PortfolioTools.d.ts +12 -0
  184. package/dist/server/tools/PortfolioTools.d.ts.map +1 -0
  185. package/dist/server/tools/PortfolioTools.js +221 -0
  186. package/dist/server/tools/index.d.ts +3 -1
  187. package/dist/server/tools/index.d.ts.map +1 -1
  188. package/dist/server/tools/index.js +4 -2
  189. package/dist/server/types.d.ts +40 -5
  190. package/dist/server/types.d.ts.map +1 -1
  191. package/dist/server/types.js +1 -1
  192. package/dist/services/BuildInfoService.d.ts +84 -0
  193. package/dist/services/BuildInfoService.d.ts.map +1 -0
  194. package/dist/services/BuildInfoService.js +271 -0
  195. package/dist/tools/portfolio/PortfolioElementAdapter.d.ts +54 -0
  196. package/dist/tools/portfolio/PortfolioElementAdapter.d.ts.map +1 -0
  197. package/dist/tools/portfolio/PortfolioElementAdapter.js +229 -0
  198. package/dist/tools/portfolio/submitToPortfolioTool.d.ts +164 -0
  199. package/dist/tools/portfolio/submitToPortfolioTool.d.ts.map +1 -0
  200. package/dist/tools/portfolio/submitToPortfolioTool.js +1523 -0
  201. package/dist/tools/portfolio/types.d.ts +41 -0
  202. package/dist/tools/portfolio/types.d.ts.map +1 -0
  203. package/dist/tools/portfolio/types.js +15 -0
  204. package/dist/types/collection.d.ts +51 -0
  205. package/dist/types/collection.d.ts.map +1 -1
  206. package/dist/types/collection.js +1 -1
  207. package/dist/utils/EarlyTerminationSearch.d.ts +41 -0
  208. package/dist/utils/EarlyTerminationSearch.d.ts.map +1 -0
  209. package/dist/utils/EarlyTerminationSearch.js +164 -0
  210. package/dist/utils/ErrorHandler.d.ts +86 -0
  211. package/dist/utils/ErrorHandler.d.ts.map +1 -0
  212. package/dist/utils/ErrorHandler.js +201 -0
  213. package/dist/utils/FileDiscoveryUtil.d.ts +53 -0
  214. package/dist/utils/FileDiscoveryUtil.d.ts.map +1 -0
  215. package/dist/utils/FileDiscoveryUtil.js +169 -0
  216. package/dist/utils/GitHubRateLimiter.d.ts +88 -0
  217. package/dist/utils/GitHubRateLimiter.d.ts.map +1 -0
  218. package/dist/utils/GitHubRateLimiter.js +315 -0
  219. package/dist/utils/PerformanceMonitor.d.ts +134 -0
  220. package/dist/utils/PerformanceMonitor.d.ts.map +1 -0
  221. package/dist/utils/PerformanceMonitor.js +347 -0
  222. package/dist/utils/RateLimiter.d.ts.map +1 -0
  223. package/dist/utils/RateLimiter.js +172 -0
  224. package/dist/utils/SecureDownloader.d.ts +241 -0
  225. package/dist/utils/SecureDownloader.d.ts.map +1 -0
  226. package/dist/utils/SecureDownloader.js +759 -0
  227. package/dist/utils/ToolCache.d.ts +82 -0
  228. package/dist/utils/ToolCache.d.ts.map +1 -0
  229. package/dist/utils/ToolCache.js +196 -0
  230. package/dist/utils/errorCodes.d.ts +136 -0
  231. package/dist/utils/errorCodes.d.ts.map +1 -0
  232. package/dist/utils/errorCodes.js +87 -0
  233. package/dist/utils/index.d.ts +3 -0
  234. package/dist/utils/index.d.ts.map +1 -1
  235. package/dist/utils/index.js +4 -1
  236. package/dist/utils/installation.d.ts +1 -1
  237. package/dist/utils/installation.d.ts.map +1 -1
  238. package/dist/utils/installation.js +9 -8
  239. package/dist/utils/searchUtils.d.ts +31 -0
  240. package/dist/utils/searchUtils.d.ts.map +1 -1
  241. package/dist/utils/searchUtils.js +62 -1
  242. package/package.json +17 -7
  243. package/dist/config/updateConfig.d.ts +0 -84
  244. package/dist/config/updateConfig.d.ts.map +0 -1
  245. package/dist/config/updateConfig.js +0 -148
  246. package/dist/server/tools/UpdateTools.d.ts +0 -10
  247. package/dist/server/tools/UpdateTools.d.ts.map +0 -1
  248. package/dist/server/tools/UpdateTools.js +0 -85
  249. package/dist/update/BackupManager.d.ts +0 -63
  250. package/dist/update/BackupManager.d.ts.map +0 -1
  251. package/dist/update/BackupManager.js +0 -370
  252. package/dist/update/DependencyChecker.d.ts +0 -41
  253. package/dist/update/DependencyChecker.d.ts.map +0 -1
  254. package/dist/update/DependencyChecker.js +0 -132
  255. package/dist/update/RateLimiter.d.ts.map +0 -1
  256. package/dist/update/RateLimiter.js +0 -172
  257. package/dist/update/SignatureVerifier.d.ts +0 -71
  258. package/dist/update/SignatureVerifier.d.ts.map +0 -1
  259. package/dist/update/SignatureVerifier.js +0 -214
  260. package/dist/update/UpdateChecker.d.ts +0 -132
  261. package/dist/update/UpdateChecker.d.ts.map +0 -1
  262. package/dist/update/UpdateChecker.js +0 -506
  263. package/dist/update/UpdateManager.d.ts +0 -60
  264. package/dist/update/UpdateManager.d.ts.map +0 -1
  265. package/dist/update/UpdateManager.js +0 -730
  266. package/dist/update/VersionManager.d.ts +0 -31
  267. package/dist/update/VersionManager.d.ts.map +0 -1
  268. package/dist/update/VersionManager.js +0 -181
  269. package/dist/update/index.d.ts +0 -9
  270. package/dist/update/index.d.ts.map +0 -1
  271. package/dist/update/index.js +0 -9
  272. /package/dist/{update → utils}/RateLimiter.d.ts +0 -0
@@ -0,0 +1,475 @@
1
+ /**
2
+ * GitHub Portfolio Indexer - Fetches and indexes user's GitHub portfolio for fast searching
3
+ *
4
+ * Features:
5
+ * - Singleton pattern for efficient resource usage
6
+ * - Smart caching with TTL and invalidation after user actions
7
+ * - GraphQL/REST API integration for efficient fetching
8
+ * - Rate limiting and authentication handling
9
+ * - Fallback strategy for resilient operation
10
+ * - Performance optimized for 1000+ portfolio elements
11
+ */
12
+ import { GitHubClient } from '../collection/GitHubClient.js';
13
+ import { PortfolioRepoManager } from './PortfolioRepoManager.js';
14
+ import { ElementType } from './types.js';
15
+ import { logger } from '../utils/logger.js';
16
+ import { SecurityMonitor } from '../security/securityMonitor.js';
17
+ import { UnicodeValidator } from '../security/validators/unicodeValidator.js';
18
+ import { ErrorHandler, ErrorCategory } from '../utils/ErrorHandler.js';
19
+ import { APICache } from '../cache/APICache.js';
20
+ export class GitHubPortfolioIndexer {
21
+ static instance = null;
22
+ static instanceLock = false;
23
+ cache = null;
24
+ lastFetch = null;
25
+ ttl = 15 * 60 * 1000; // 15 minutes
26
+ recentUserAction = false;
27
+ actionTimestamp = null;
28
+ actionGracePeriod = 2 * 60 * 1000; // 2 minutes after action
29
+ githubClient;
30
+ portfolioRepoManager;
31
+ apiCache;
32
+ rateLimitTracker;
33
+ constructor() {
34
+ this.apiCache = new APICache(); // Uses default settings
35
+ this.rateLimitTracker = new Map();
36
+ this.githubClient = new GitHubClient(this.apiCache, this.rateLimitTracker);
37
+ this.portfolioRepoManager = new PortfolioRepoManager();
38
+ logger.debug('GitHubPortfolioIndexer created');
39
+ }
40
+ /**
41
+ * Singleton pattern with thread safety
42
+ */
43
+ static getInstance() {
44
+ if (!this.instance) {
45
+ if (this.instanceLock) {
46
+ throw new Error('GitHubPortfolioIndexer instance is being created by another thread');
47
+ }
48
+ try {
49
+ this.instanceLock = true;
50
+ this.instance = new GitHubPortfolioIndexer();
51
+ }
52
+ finally {
53
+ this.instanceLock = false;
54
+ }
55
+ }
56
+ return this.instance;
57
+ }
58
+ /**
59
+ * Main method to get GitHub portfolio index
60
+ */
61
+ async getIndex(force = false) {
62
+ try {
63
+ // Check if we need fresh data
64
+ if (force || this.shouldFetchFresh()) {
65
+ return await this.fetchFresh();
66
+ }
67
+ // Return cached data if available and valid
68
+ if (this.cache && this.isCacheValid()) {
69
+ logger.debug('Returning cached GitHub portfolio index', {
70
+ username: this.cache.username,
71
+ totalElements: this.cache.totalElements,
72
+ age: this.lastFetch ? Date.now() - this.lastFetch.getTime() : 'unknown'
73
+ });
74
+ return this.cache;
75
+ }
76
+ // Try to fetch fresh, fall back to stale cache on failure
77
+ try {
78
+ return await this.fetchFresh();
79
+ }
80
+ catch (error) {
81
+ logger.warn('Failed to fetch fresh GitHub portfolio index, checking for stale cache', {
82
+ error: error instanceof Error ? error.message : String(error)
83
+ });
84
+ // Return stale cache if available
85
+ if (this.cache) {
86
+ logger.info('Returning stale GitHub portfolio cache as fallback', {
87
+ username: this.cache.username,
88
+ age: this.lastFetch ? Date.now() - this.lastFetch.getTime() : 'unknown'
89
+ });
90
+ return this.cache;
91
+ }
92
+ // Return empty index as last resort
93
+ return this.createEmptyIndex();
94
+ }
95
+ }
96
+ catch (error) {
97
+ ErrorHandler.logError('GitHubPortfolioIndexer.getIndex', error);
98
+ // Return stale cache or empty index
99
+ if (this.cache) {
100
+ return this.cache;
101
+ }
102
+ return this.createEmptyIndex();
103
+ }
104
+ }
105
+ /**
106
+ * Invalidate cache after user actions
107
+ */
108
+ invalidateAfterAction(action) {
109
+ logger.info('Invalidating GitHub portfolio cache after user action', { action });
110
+ this.recentUserAction = true;
111
+ this.actionTimestamp = new Date();
112
+ // Log security event for audit trail
113
+ SecurityMonitor.logSecurityEvent({
114
+ type: 'PORTFOLIO_CACHE_INVALIDATION',
115
+ severity: 'LOW',
116
+ source: 'GitHubPortfolioIndexer.invalidateAfterAction',
117
+ details: `Cache invalidated after user action: ${action}`,
118
+ metadata: { action }
119
+ });
120
+ }
121
+ /**
122
+ * Clear all cached data
123
+ */
124
+ clearCache() {
125
+ this.cache = null;
126
+ this.lastFetch = null;
127
+ this.recentUserAction = false;
128
+ this.actionTimestamp = null;
129
+ this.apiCache.clear();
130
+ logger.info('GitHub portfolio cache cleared');
131
+ }
132
+ /**
133
+ * Get cache statistics
134
+ */
135
+ getCacheStats() {
136
+ return {
137
+ hasCachedData: this.cache !== null,
138
+ lastFetch: this.lastFetch,
139
+ isStale: !this.isCacheValid(),
140
+ recentUserAction: this.recentUserAction,
141
+ totalElements: this.cache?.totalElements || 0
142
+ };
143
+ }
144
+ /**
145
+ * Fetch fresh data from GitHub
146
+ */
147
+ async fetchFresh() {
148
+ const startTime = Date.now();
149
+ logger.info('Fetching fresh GitHub portfolio index...');
150
+ try {
151
+ // Get GitHub username from token
152
+ const username = await this.getGitHubUsername();
153
+ const repository = 'dollhouse-portfolio';
154
+ // Check if portfolio repository exists
155
+ const repoExists = await this.portfolioRepoManager.checkPortfolioExists(username);
156
+ if (!repoExists) {
157
+ logger.info('GitHub portfolio repository does not exist', { username });
158
+ return this.createEmptyIndex(username, repository);
159
+ }
160
+ // Fetch repository content using GitHub API
161
+ const index = await this.fetchRepositoryContent(username, repository);
162
+ // Update cache
163
+ this.cache = index;
164
+ this.lastFetch = new Date();
165
+ this.recentUserAction = false;
166
+ this.actionTimestamp = null;
167
+ const duration = Date.now() - startTime;
168
+ logger.info('GitHub portfolio index fetched successfully', {
169
+ username,
170
+ totalElements: index.totalElements,
171
+ duration: `${duration}ms`,
172
+ rateLimitRemaining: index.rateLimitInfo?.remaining
173
+ });
174
+ // Log security event
175
+ SecurityMonitor.logSecurityEvent({
176
+ type: 'PORTFOLIO_FETCH_SUCCESS',
177
+ severity: 'LOW',
178
+ source: 'GitHubPortfolioIndexer.fetchFresh',
179
+ details: `Fetched GitHub portfolio with ${index.totalElements} elements in ${duration}ms`,
180
+ metadata: { username, duration, totalElements: index.totalElements }
181
+ });
182
+ return index;
183
+ }
184
+ catch (error) {
185
+ const duration = Date.now() - startTime;
186
+ ErrorHandler.logError('GitHubPortfolioIndexer.fetchFresh', error, { duration });
187
+ throw ErrorHandler.wrapError(error, 'Failed to fetch GitHub portfolio index', ErrorCategory.NETWORK_ERROR);
188
+ }
189
+ }
190
+ /**
191
+ * Fetch repository content from GitHub API
192
+ */
193
+ async fetchRepositoryContent(username, repository) {
194
+ // Try GraphQL first for better performance, fallback to REST
195
+ try {
196
+ return await this.fetchWithGraphQL(username, repository);
197
+ }
198
+ catch (graphqlError) {
199
+ logger.debug('GraphQL fetch failed, falling back to REST API', {
200
+ error: graphqlError instanceof Error ? graphqlError.message : String(graphqlError)
201
+ });
202
+ return await this.fetchWithREST(username, repository);
203
+ }
204
+ }
205
+ /**
206
+ * Fetch using GraphQL for better performance
207
+ */
208
+ async fetchWithGraphQL(username, repository) {
209
+ const query = `
210
+ query GetPortfolioContent($owner: String!, $name: String!) {
211
+ repository(owner: $owner, name: $name) {
212
+ defaultBranchRef {
213
+ target {
214
+ ... on Commit {
215
+ oid
216
+ history(first: 1) {
217
+ nodes {
218
+ committedDate
219
+ }
220
+ }
221
+ }
222
+ }
223
+ }
224
+ object(expression: "HEAD:") {
225
+ ... on Tree {
226
+ entries {
227
+ name
228
+ type
229
+ object {
230
+ ... on Tree {
231
+ entries {
232
+ name
233
+ type
234
+ oid
235
+ object {
236
+ ... on Blob {
237
+ byteSize
238
+ text
239
+ }
240
+ }
241
+ }
242
+ }
243
+ }
244
+ }
245
+ }
246
+ }
247
+ }
248
+ rateLimit {
249
+ remaining
250
+ resetAt
251
+ }
252
+ }
253
+ `;
254
+ const variables = { owner: username, name: repository };
255
+ const response = await this.githubClient.fetchFromGitHub('https://api.github.com/graphql', true);
256
+ // Note: This is a simplified GraphQL implementation
257
+ // In a real implementation, you would send POST request with query and variables
258
+ throw new Error('GraphQL implementation not yet complete');
259
+ }
260
+ /**
261
+ * Fetch using REST API with pagination
262
+ */
263
+ async fetchWithREST(username, repository) {
264
+ const normalizedUsername = UnicodeValidator.normalize(username).normalizedContent;
265
+ // Get repository info and latest commit
266
+ const repoInfo = await this.githubClient.fetchFromGitHub(`https://api.github.com/repos/${normalizedUsername}/${repository}`);
267
+ const latestCommit = await this.githubClient.fetchFromGitHub(`https://api.github.com/repos/${normalizedUsername}/${repository}/commits/HEAD`);
268
+ // Initialize index
269
+ const index = {
270
+ username: normalizedUsername,
271
+ repository,
272
+ lastUpdated: new Date(latestCommit.commit.committer.date),
273
+ elements: new Map(),
274
+ totalElements: 0,
275
+ sha: latestCommit.sha
276
+ };
277
+ // Initialize element type maps
278
+ for (const elementType of Object.values(ElementType)) {
279
+ index.elements.set(elementType, []);
280
+ }
281
+ // Fetch content for each element type
282
+ for (const elementType of Object.values(ElementType)) {
283
+ try {
284
+ const entries = await this.fetchElementTypeContent(normalizedUsername, repository, elementType);
285
+ index.elements.set(elementType, entries);
286
+ index.totalElements += entries.length;
287
+ }
288
+ catch (error) {
289
+ logger.warn(`Failed to fetch ${elementType} from GitHub portfolio`, {
290
+ error: error instanceof Error ? error.message : String(error)
291
+ });
292
+ // Continue with other element types
293
+ }
294
+ }
295
+ return index;
296
+ }
297
+ /**
298
+ * Fetch content for a specific element type
299
+ */
300
+ async fetchElementTypeContent(username, repository, elementType) {
301
+ try {
302
+ // Get directory listing
303
+ const contents = await this.githubClient.fetchFromGitHub(`https://api.github.com/repos/${username}/${repository}/contents/${elementType}`);
304
+ if (!Array.isArray(contents)) {
305
+ return [];
306
+ }
307
+ const entries = [];
308
+ const maxConcurrent = 5; // Limit concurrent requests
309
+ // Process files in batches to avoid rate limiting
310
+ for (let i = 0; i < contents.length; i += maxConcurrent) {
311
+ const batch = contents.slice(i, i + maxConcurrent);
312
+ const batchPromises = batch
313
+ .filter(item => item.type === 'file' && item.name.endsWith('.md'))
314
+ .map(item => this.createGitHubIndexEntry(username, repository, elementType, item));
315
+ const batchResults = await Promise.allSettled(batchPromises);
316
+ for (const result of batchResults) {
317
+ if (result.status === 'fulfilled' && result.value) {
318
+ entries.push(result.value);
319
+ }
320
+ }
321
+ // Add delay between batches to respect rate limits
322
+ if (i + maxConcurrent < contents.length) {
323
+ await new Promise(resolve => setTimeout(resolve, 100));
324
+ }
325
+ }
326
+ return entries;
327
+ }
328
+ catch (error) {
329
+ // Directory might not exist
330
+ if (error instanceof Error && error.message.includes('404')) {
331
+ return [];
332
+ }
333
+ throw error;
334
+ }
335
+ }
336
+ /**
337
+ * Create GitHub index entry from API response
338
+ */
339
+ async createGitHubIndexEntry(username, repository, elementType, fileInfo) {
340
+ try {
341
+ // Parse metadata from filename or fetch content if needed
342
+ const name = fileInfo.name.replace('.md', '').replace(/-/g, ' ');
343
+ const entry = {
344
+ path: fileInfo.path,
345
+ name,
346
+ elementType,
347
+ sha: fileInfo.sha,
348
+ htmlUrl: fileInfo.html_url,
349
+ downloadUrl: fileInfo.download_url,
350
+ lastModified: new Date(), // GitHub API doesn't provide file modification time directly
351
+ size: fileInfo.size || 0
352
+ };
353
+ // Optionally fetch content to extract metadata
354
+ // This is expensive, so only do it for small files or when specifically needed
355
+ if (fileInfo.size && fileInfo.size < 10000) { // Only for files < 10KB
356
+ try {
357
+ const content = await this.githubClient.fetchFromGitHub(fileInfo.download_url);
358
+ const metadata = this.parseMetadataFromContent(content);
359
+ if (metadata.name)
360
+ entry.name = metadata.name;
361
+ if (metadata.description)
362
+ entry.description = metadata.description;
363
+ if (metadata.version)
364
+ entry.version = metadata.version;
365
+ if (metadata.author)
366
+ entry.author = metadata.author;
367
+ }
368
+ catch (metadataError) {
369
+ // Non-critical error, continue without metadata
370
+ logger.debug('Failed to fetch metadata for file', {
371
+ path: fileInfo.path,
372
+ error: metadataError instanceof Error ? metadataError.message : String(metadataError)
373
+ });
374
+ }
375
+ }
376
+ return entry;
377
+ }
378
+ catch (error) {
379
+ logger.debug('Failed to create GitHub index entry', {
380
+ path: fileInfo.path,
381
+ error: error instanceof Error ? error.message : String(error)
382
+ });
383
+ return null;
384
+ }
385
+ }
386
+ /**
387
+ * Parse metadata from file content (frontmatter)
388
+ */
389
+ parseMetadataFromContent(content) {
390
+ const metadata = {};
391
+ // Simple frontmatter parsing (could use a proper YAML parser)
392
+ const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
393
+ if (frontmatterMatch) {
394
+ const frontmatter = frontmatterMatch[1];
395
+ const nameMatch = frontmatter.match(/^name:\s*(.+)$/m);
396
+ if (nameMatch)
397
+ metadata.name = nameMatch[1].trim();
398
+ const descMatch = frontmatter.match(/^description:\s*(.+)$/m);
399
+ if (descMatch)
400
+ metadata.description = descMatch[1].trim();
401
+ const versionMatch = frontmatter.match(/^version:\s*(.+)$/m);
402
+ if (versionMatch)
403
+ metadata.version = versionMatch[1].trim();
404
+ const authorMatch = frontmatter.match(/^author:\s*(.+)$/m);
405
+ if (authorMatch)
406
+ metadata.author = authorMatch[1].trim();
407
+ }
408
+ return metadata;
409
+ }
410
+ /**
411
+ * Get GitHub username from authenticated token
412
+ */
413
+ async getGitHubUsername() {
414
+ try {
415
+ const userInfo = await this.githubClient.fetchFromGitHub('https://api.github.com/user', true);
416
+ return userInfo.login;
417
+ }
418
+ catch (error) {
419
+ throw new Error('Failed to get GitHub username. Please ensure you are authenticated with GitHub.');
420
+ }
421
+ }
422
+ /**
423
+ * Check if cache is valid
424
+ */
425
+ isCacheValid() {
426
+ if (!this.cache || !this.lastFetch) {
427
+ return false;
428
+ }
429
+ const age = Date.now() - this.lastFetch.getTime();
430
+ return age < this.ttl;
431
+ }
432
+ /**
433
+ * Determine if we should fetch fresh data
434
+ */
435
+ shouldFetchFresh() {
436
+ // Always fetch if no cache
437
+ if (!this.cache || !this.lastFetch) {
438
+ return true;
439
+ }
440
+ // Check for recent user actions
441
+ if (this.recentUserAction && this.actionTimestamp) {
442
+ const actionAge = Date.now() - this.actionTimestamp.getTime();
443
+ if (actionAge < this.actionGracePeriod) {
444
+ logger.debug('Fetching fresh due to recent user action', { actionAge });
445
+ return true;
446
+ }
447
+ else {
448
+ // Grace period expired, clear action flag
449
+ this.recentUserAction = false;
450
+ this.actionTimestamp = null;
451
+ }
452
+ }
453
+ // Check TTL
454
+ return !this.isCacheValid();
455
+ }
456
+ /**
457
+ * Create empty index when no portfolio exists
458
+ */
459
+ createEmptyIndex(username, repository) {
460
+ const index = {
461
+ username: username || 'unknown',
462
+ repository: repository || 'dollhouse-portfolio',
463
+ lastUpdated: new Date(),
464
+ elements: new Map(),
465
+ totalElements: 0,
466
+ sha: ''
467
+ };
468
+ // Initialize empty element type maps
469
+ for (const elementType of Object.values(ElementType)) {
470
+ index.elements.set(elementType, []);
471
+ }
472
+ return index;
473
+ }
474
+ }
475
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiR2l0SHViUG9ydGZvbGlvSW5kZXhlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9wb3J0Zm9saW8vR2l0SHViUG9ydGZvbGlvSW5kZXhlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7OztHQVVHO0FBRUgsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQzdELE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBRWpFLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFDekMsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQzVDLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUNqRSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSw0Q0FBNEMsQ0FBQztBQUM5RSxPQUFPLEVBQUUsWUFBWSxFQUFFLGFBQWEsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ3ZFLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQW9DaEQsTUFBTSxPQUFPLHNCQUFzQjtJQUN6QixNQUFNLENBQUMsUUFBUSxHQUFrQyxJQUFJLENBQUM7SUFDdEQsTUFBTSxDQUFDLFlBQVksR0FBRyxLQUFLLENBQUM7SUFFNUIsS0FBSyxHQUFnQyxJQUFJLENBQUM7SUFDMUMsU0FBUyxHQUFnQixJQUFJLENBQUM7SUFDckIsR0FBRyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDLENBQUMsYUFBYTtJQUM1QyxnQkFBZ0IsR0FBRyxLQUFLLENBQUM7SUFDekIsZUFBZSxHQUFnQixJQUFJLENBQUM7SUFDM0IsaUJBQWlCLEdBQUcsQ0FBQyxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUMsQ0FBQyx5QkFBeUI7SUFFckUsWUFBWSxDQUFlO0lBQzNCLG9CQUFvQixDQUF1QjtJQUMzQyxRQUFRLENBQVc7SUFDbkIs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QUU7WUFDbkIsYUFBYSxFQUFFLENBQUM7WUFDaEIsR0FBRyxFQUFFLEVBQUU7U0FDUixDQUFDO1FBRUYscUNBQXFDO1FBQ3JDLEtBQUssTUFBTSxXQUFXLElBQUksTUFBTSxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDO1lBQ3JELEtBQUssQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLFdBQVcsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUN0QyxDQUFDO1FBRUQsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBHaXRIdWIgUG9ydGZvbGlvIEluZGV4ZXIgLSBGZXRjaGVzIGFuZCBpbmRleGVzIHVzZXIncyBHaXRIdWIgcG9ydGZvbGlvIGZvciBmYXN0IHNlYXJjaGluZ1xuICogXG4gKiBGZWF0dXJlczpcbiAqIC0gU2luZ2xldG9uIHBhdHRlcm4gZm9yIGVmZmljaWVudCByZXNvdXJjZSB1c2FnZVxuICogLSBTbWFydCBjYWNoaW5nIHdpdGggVFRMIGFuZCBpbnZhbGlkYXRpb24gYWZ0ZXIgdXNlciBhY3Rpb25zXG4gKiAtIEdyYXBoUUwvUkVTVCBBUEkgaW50ZWdyYXRpb24gZm9yIGVmZmljaWVudCBmZXRjaGluZ1xuICogLSBSYXRlIGxpbWl0aW5nIGFuZCBhdXRoZW50aWNhdGlvbiBoYW5kbGluZ1xuICogLSBGYWxsYmFjayBzdHJhdGVneSBmb3IgcmVzaWxpZW50IG9wZXJhdGlvblxuICogLSBQZXJmb3JtYW5jZSBvcHRpbWl6ZWQgZm9yIDEwMDArIHBvcnRmb2xpbyBlbGVtZW50c1xuICovXG5cbmltcG9ydCB7IEdpdEh1YkNsaWVudCB9IGZyb20gJy4uL2NvbGxlY3Rpb24vR2l0SHViQ2xpZW50LmpzJztcbmltcG9ydCB7IFBvcnRmb2xpb1JlcG9NYW5hZ2VyIH0gZnJvbSAnLi9Qb3J0Zm9saW9SZXBvTWFuYWdlci5qcyc7XG5pbXBvcnQgeyBUb2tlbk1hbmFnZXIgfSBmcm9tICcuLi9zZWN1cml0eS90b2tlbk1hbmFnZXIuanMnO1xuaW1wb3J0IHsgRWxlbWVudFR5cGUgfSBmcm9tICcuL3R5cGVzLmpzJztcbmltcG9ydCB7IGxvZ2dlciB9IGZyb20gJy4uL3V0aWxzL2xvZ2dlci5qcyc7XG5pbXBvcnQgeyBTZWN1cml0eU1vbml0b3IgfSBmcm9tICcuLi9zZWN1cml0eS9zZWN1cml0eU1vbml0b3IuanMnO1xuaW1wb3J0IHsgVW5pY29kZVZhbGlkYXRvciB9IGZyb20gJy4uL3NlY3VyaXR5L3ZhbGlkYXRvcnMvdW5pY29kZVZhbGlkYXRvci5qcyc7XG5pbXBvcnQgeyBFcnJvckhhbmRsZXIsIEVycm9yQ2F0ZWdvcnkgfSBmcm9tICcuLi91dGlscy9FcnJvckhhbmRsZXIuanMnO1xuaW1wb3J0IHsgQVBJQ2FjaGUgfSBmcm9tICcuLi9jYWNoZS9BUElDYWNoZS5qcyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgR2l0SHViSW5kZXhFbnRyeSB7XG4gIHBhdGg6IHN0cmluZztcbiAgbmFtZTogc3RyaW5nO1xuICBkZXNjcmlwdGlvbj86IHN0cmluZztcbiAgdmVyc2lvbj86IHN0cmluZztcbiAgYXV0aG9yPzogc3RyaW5nO1xuICBlbGVtZW50VHlwZTogRWxlbWVudFR5cGU7XG4gIHNoYTogc3RyaW5nOyAvLyBGaWxlIFNIQSBmb3IgY2hhbmdlIGRldGVjdGlvblxuICBodG1sVXJsOiBzdHJpbmc7IC8vIExpbmsgdG8gR2l0SHViXG4gIGRvd25sb2FkVXJsOiBzdHJpbmc7XG4gIGxhc3RNb2RpZmllZDogRGF0ZTtcbiAgc2l6ZTogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEdpdEh1YlBvcnRmb2xpb0luZGV4IHtcbiAgdXNlcm5hbWU6IHN0cmluZztcbiAgcmVwb3NpdG9yeTogc3RyaW5nO1xuICBsYXN0VXBkYXRlZDogRGF0ZTtcbiAgZWxlbWVudHM6IE1hcDxFbGVtZW50VHlwZSwgR2l0SHViSW5kZXhFbnRyeVtdPjtcbiAgdG90YWxFbGVtZW50czogbnVtYmVyO1xuICBzaGE6IHN0cmluZzsgLy8gTGF0ZXN0IGNvbW1pdCBTSEFcbiAgcmF0ZUxpbWl0SW5mbz86IHtcbiAgICByZW1haW5pbmc6IG51bWJlcjtcbiAgICByZXNldFRpbWU6IERhdGU7XG4gIH07XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgR2l0SHViRmV0Y2hPcHRpb25zIHtcbiAgZm9yY2U/OiBib29sZWFuO1xuICBtYXhFbGVtZW50cz86IG51bWJlcjtcbiAgZWxlbWVudFR5cGVzPzogRWxlbWVudFR5cGVbXTtcbiAgdXNlR3JhcGhRTD86IGJvb2xlYW47XG59XG5cbmV4cG9ydCBjbGFzcyBHaXRIdWJQb3J0Zm9saW9JbmRleGVyIHtcbiAgcHJpdmF0ZSBzdGF0aWMgaW5zdGFuY2U6IEdpdEh1YlBvcnRmb2xpb0luZGV4ZXIgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBzdGF0aWMgaW5zdGFuY2VMb2NrID0gZmFsc2U7XG4gIFxuICBwcml2YXRlIGNhY2hlOiBHaXRIdWJQb3J0Zm9saW9JbmRleCB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIGxhc3RGZXRjaDogRGF0ZSB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIHJlYWRvbmx5IHR0bCA9IDE1ICogNjAgKiAxMDAwOyAvLyAxNSBtaW51dGVzXG4gIHByaXZhdGUgcmVjZW50VXNlckFjdGlvbiA9IGZhbHNlO1xuICBwcml2YXRlIGFjdGlvblRpbWVzdGFtcDogRGF0ZSB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIHJlYWRvbmx5IGFjdGlvbkdyYWNlUGVyaW9kID0gMiAqIDYwICogMTAwMDsgLy8gMiBtaW51dGVzIGFmdGVyIGFjdGlvblxuICBcbiAgcHJpdmF0ZSBnaXRodWJDbGllbnQ6IEdpdEh1YkNsaWVudDtcbiAgcHJpdmF0ZSBwb3J0Zm9saW9SZXBvTWFuYWdlcjogUG9ydGZvbGlvUmVwb01hbmFnZXI7XG4gIHByaXZhdGUgYXBpQ2FjaGU6IEFQSUNhY2hlO1xuICBwcml2YXRlIHJhdGVMaW1pdFRyYWNrZXI6IE1hcDxzdHJpbmcsIG51bWJlcltdPjtcbiAgXG4gIHByaXZhdGUgY29uc3RydWN0b3IoKSB7XG4gICAgdGhpcy5hcGlDYWNoZSA9IG5ldyBBUElDYWNoZSgpOyAvLyBVc2VzIGRlZmF1bHQgc2V0dGluZ3NcbiAgICB0aGlzLnJhdGVMaW1pdFRyYWNrZXIgPSBuZXcgTWFwKCk7XG4gICAgdGhpcy5naXRodWJDbGllbnQgPSBuZXcgR2l0SHViQ2xpZW50KHRoaXMuYXBpQ2FjaGUsIHRoaXMucmF0ZUxpbWl0VHJhY2tlcik7XG4gICAgdGhpcy5wb3J0Zm9saW9SZXBvTWFuYWdlciA9IG5ldyBQb3J0Zm9saW9SZXBvTWFuYWdlcigpO1xuICAgIFxuICAgIGxvZ2dlci5kZWJ1ZygnR2l0SHViUG9ydGZvbGlvSW5kZXhlciBjcmVhdGVkJyk7XG4gIH1cblxuICAvKipcbiAgICogU2luZ2xldG9uIHBhdHRlcm4gd2l0aCB0aHJlYWQgc2FmZXR5XG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGdldEluc3RhbmNlKCk6IEdpdEh1YlBvcnRmb2xpb0luZGV4ZXIge1xuICAgIGlmICghdGhpcy5pbnN0YW5jZSkge1xuICAgICAgaWYgKHRoaXMuaW5zdGFuY2VMb2NrKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignR2l0SHViUG9ydGZvbGlvSW5kZXhlciBpbnN0YW5jZSBpcyBiZWluZyBjcmVhdGVkIGJ5IGFub3RoZXIgdGhyZWFkJyk7XG4gICAgICB9XG4gICAgICBcbiAgICAgIHRyeSB7XG4gICAgICAgIHRoaXMuaW5zdGFuY2VMb2NrID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5pbnN0YW5jZSA9IG5ldyBHaXRIdWJQb3J0Zm9saW9JbmRleGVyKCk7XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICB0aGlzLmluc3RhbmNlTG9jayA9IGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdGhpcy5pbnN0YW5jZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNYWluIG1ldGhvZCB0byBnZXQgR2l0SHViIHBvcnRmb2xpbyBpbmRleFxuICAgKi9cbiAgcHVibGljIGFzeW5jIGdldEluZGV4KGZvcmNlID0gZmFsc2UpOiBQcm9taXNlPEdpdEh1YlBvcnRmb2xpb0luZGV4PiB7XG4gICAgdHJ5IHtcbiAgICAgIC8vIENoZWNrIGlmIHdlIG5lZWQgZnJlc2ggZGF0YVxuICAgICAgaWYgKGZvcmNlIHx8IHRoaXMuc2hvdWxkRmV0Y2hGcmVzaCgpKSB7XG4gICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmZldGNoRnJlc2goKTtcbiAgICAgIH1cbiAgICAgIFxuICAgICAgLy8gUmV0dXJuIGNhY2hlZCBkYXRhIGlmIGF2YWlsYWJsZSBhbmQgdmFsaWRcbiAgICAgIGlmICh0aGlzLmNhY2hlICYmIHRoaXMuaXNDYWNoZVZhbGlkKCkpIHtcbiAgICAgICAgbG9nZ2VyLmRlYnVnKCdSZXR1cm5pbmcgY2FjaGVkIEdpdEh1YiBwb3J0Zm9saW8gaW5kZXgnLCB7XG4gICAgICAgICAgdXNlcm5hbWU6IHRoaXMuY2FjaGUudXNlcm5hbWUsXG4gICAgICAgICAgdG90YWxFbGVtZW50czogdGhpcy5jYWNoZS50b3RhbEVsZW1lbnRzLFxuICAgICAgICAgIGFnZTogdGhpcy5sYXN0RmV0Y2ggPyBEYXRlLm5vdygpIC0gdGhpcy5sYXN0RmV0Y2guZ2V0VGltZSgpIDogJ3Vua25vd24nXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gdGhpcy5jYWNoZTtcbiAgICAgIH1cbiAgICAgIFxuICAgICAgLy8gVHJ5IHRvIGZldGNoIGZyZXNoLCBmYWxsIGJhY2sgdG8gc3RhbGUgY2FjaGUgb24gZmFpbHVyZVxuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuZmV0Y2hGcmVzaCgpO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oJ0ZhaWxlZCB0byBmZXRjaCBmcmVzaCBHaXRIdWIgcG9ydGZvbGlvIGluZGV4LCBjaGVja2luZyBmb3Igc3RhbGUgY2FjaGUnLCB7XG4gICAgICAgICAgZXJyb3I6IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogU3RyaW5nKGVycm9yKVxuICAgICAgICB9KTtcbiAgICAgICAgXG4gICAgICAgIC8vIFJldHVybiBzdGFsZSBjYWNoZSBpZiBhdmFpbGFibGVcbiAgICAgICAgaWYgKHRoaXMuY2FjaGUpIHtcbiAgICAgICAgICBsb2dnZXIuaW5mbygnUmV0dXJuaW5nIHN0YWxlIEdpdEh1YiBwb3J0Zm9saW8gY2FjaGUgYXMgZmFsbGJhY2snLCB7XG4gICAgICAgICAgICB1c2VybmFtZTogdGhpcy5jYWNoZS51c2VybmFtZSxcbiAgICAgICAgICAgIGFnZTogdGhpcy5sYXN0RmV0Y2ggPyBEYXRlLm5vdygpIC0gdGhpcy5sYXN0RmV0Y2guZ2V0VGltZSgpIDogJ3Vua25vd24nXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgcmV0dXJuIHRoaXMuY2FjaGU7XG4gICAgICAgIH1cbiAgICAgICAgXG4gICAgICAgIC8vIFJldHVybiBlbXB0eSBpbmRleCBhcyBsYXN0IHJlc29ydFxuICAgICAgICByZXR1cm4gdGhpcy5jcmVhdGVFbXB0eUluZGV4KCk7XG4gICAgICB9XG4gICAgICBcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgRXJyb3JIYW5kbGVyLmxvZ0Vycm9yKCdHaXRIdWJQb3J0Zm9saW9JbmRleGVyLmdldEluZGV4JywgZXJyb3IpO1xuICAgICAgXG4gICAgICAvLyBSZXR1cm4gc3RhbGUgY2FjaGUgb3IgZW1wdHkgaW5kZXhcbiAgICAgIGlmICh0aGlzLmNhY2hlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNhY2hlO1xuICAgICAgfVxuICAgICAgXG4gICAgICByZXR1cm4gdGhpcy5jcmVhdGVFbXB0eUluZGV4KCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEludmFsaWRhdGUgY2FjaGUgYWZ0ZXIgdXNlciBhY3Rpb25zXG4gICAqL1xuICBwdWJsaWMgaW52YWxpZGF0ZUFmdGVyQWN0aW9uKGFjdGlvbjogc3RyaW5nKTogdm9pZCB7XG4gICAgbG9nZ2VyLmluZm8oJ0ludmFsaWRhdGluZyBHaXRIdWIgcG9ydGZvbGlvIGNhY2hlIGFmdGVyIHVzZXIgYWN0aW9uJywgeyBhY3Rpb24gfSk7XG4gICAgXG4gICAgdGhpcy5yZWNlbnRVc2VyQWN0aW9uID0gdHJ1ZTtcbiAgICB0aGlzLmFjdGlvblRpbWVzdGFtcCA9IG5ldyBEYXRlKCk7XG4gICAgXG4gICAgLy8gTG9nIHNlY3VyaXR5IGV2ZW50IGZvciBhdWRpdCB0cmFpbFxuICAgIFNlY3VyaXR5TW9uaXRvci5sb2dTZWN1cml0eUV2ZW50KHtcbiAgICAgIHR5cGU6ICdQT1JURk9MSU9fQ0FDSEVfSU5WQUxJREFUSU9OJyxcbiAgICAgIHNldmVyaXR5OiAnTE9XJyxcbiAgICAgIHNvdXJjZTogJ0dpdEh1YlBvcnRmb2xpb0luZGV4ZXIuaW52YWxpZGF0ZUFmdGVyQWN0aW9uJyxcbiAgICAgIGRldGFpbHM6IGBDYWNoZSBpbnZhbGlkYXRlZCBhZnRlciB1c2VyIGFjdGlvbjogJHthY3Rpb259YCxcbiAgICAgIG1ldGFkYXRhOiB7IGFjdGlvbiB9XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQ2xlYXIgYWxsIGNhY2hlZCBkYXRhXG4gICAqL1xuICBwdWJsaWMgY2xlYXJDYWNoZSgpOiB2b2lkIHtcbiAgICB0aGlzLmNhY2hlID0gbnVsbDtcbiAgICB0aGlzLmxhc3RGZXRjaCA9IG51bGw7XG4gICAgdGhpcy5yZWNlbnRVc2VyQWN0aW9uID0gZmFsc2U7XG4gICAgdGhpcy5hY3Rpb25UaW1lc3RhbXAgPSBudWxsO1xuICAgIHRoaXMuYXBpQ2FjaGUuY2xlYXIoKTtcbiAgICBcbiAgICBsb2dnZXIuaW5mbygnR2l0SHViIHBvcnRmb2xpbyBjYWNoZSBjbGVhcmVkJyk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IGNhY2hlIHN0YXRpc3RpY3NcbiAgICovXG4gIHB1YmxpYyBnZXRDYWNoZVN0YXRzKCk6IHtcbiAgICBoYXNDYWNoZWREYXRhOiBib29sZWFuO1xuICAgIGxhc3RGZXRjaDogRGF0ZSB8IG51bGw7XG4gICAgaXNTdGFsZTogYm9vbGVhbjtcbiAgICByZWNlbnRVc2VyQWN0aW9uOiBib29sZWFuO1xuICAgIHRvdGFsRWxlbWVudHM6IG51bWJlcjtcbiAgfSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGhhc0NhY2hlZERhdGE6IHRoaXMuY2FjaGUgIT09IG51bGwsXG4gICAgICBsYXN0RmV0Y2g6IHRoaXMubGFzdEZldGNoLFxuICAgICAgaXNTdGFsZTogIXRoaXMuaXNDYWNoZVZhbGlkKCksXG4gICAgICByZWNlbnRVc2VyQWN0aW9uOiB0aGlzLnJlY2VudFVzZXJBY3Rpb24sXG4gICAgICB0b3RhbEVsZW1lbnRzOiB0aGlzLmNhY2hlPy50b3RhbEVsZW1lbnRzIHx8IDBcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEZldGNoIGZyZXNoIGRhdGEgZnJvbSBHaXRIdWJcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgZmV0Y2hGcmVzaCgpOiBQcm9taXNlPEdpdEh1YlBvcnRmb2xpb0luZGV4PiB7XG4gICAgY29uc3Qgc3RhcnRUaW1lID0gRGF0ZS5ub3coKTtcbiAgICBsb2dnZXIuaW5mbygnRmV0Y2hpbmcgZnJlc2ggR2l0SHViIHBvcnRmb2xpbyBpbmRleC4uLicpO1xuICAgIFxuICAgIHRyeSB7XG4gICAgICAvLyBHZXQgR2l0SHViIHVzZXJuYW1lIGZyb20gdG9rZW5cbiAgICAgIGNvbnN0IHVzZXJuYW1lID0gYXdhaXQgdGhpcy5nZXRHaXRIdWJVc2VybmFtZSgpO1xuICAgICAgY29uc3QgcmVwb3NpdG9yeSA9ICdkb2xsaG91c2UtcG9ydGZvbGlvJztcbiAgICAgIFxuICAgICAgLy8gQ2hlY2sgaWYgcG9ydGZvbGlvIHJlcG9zaXRvcnkgZXhpc3RzXG4gICAgICBjb25zdCByZXBvRXhpc3RzID0gYXdhaXQgdGhpcy5wb3J0Zm9saW9SZXBvTWFuYWdlci5jaGVja1BvcnRmb2xpb0V4aXN0cyh1c2VybmFtZSk7XG4gICAgICBpZiAoIXJlcG9FeGlzdHMpIHtcbiAgICAgICAgbG9nZ2VyLmluZm8oJ0dpdEh1YiBwb3J0Zm9saW8gcmVwb3NpdG9yeSBkb2VzIG5vdCBleGlzdCcsIHsgdXNlcm5hbWUgfSk7XG4gICAgICAgIHJldHVybiB0aGlzLmNyZWF0ZUVtcHR5SW5kZXgodXNlcm5hbWUsIHJlcG9zaXRvcnkpO1xuICAgICAgfVxuICAgICAgXG4gICAgICAvLyBGZXRjaCByZXBvc2l0b3J5IGNvbnRlbnQgdXNpbmcgR2l0SHViIEFQSVxuICAgICAgY29uc3QgaW5kZXggPSBhd2FpdCB0aGlzLmZldGNoUmVwb3NpdG9yeUNvbnRlbnQodXNlcm5hbWUsIHJlcG9zaXRvcnkpO1xuICAgICAgXG4gICAgICAvLyBVcGRhdGUgY2FjaGVcbiAgICAgIHRoaXMuY2FjaGUgPSBpbmRleDtcbiAgICAgIHRoaXMubGFzdEZldGNoID0gbmV3IERhdGUoKTtcbiAgICAgIHRoaXMucmVjZW50VXNlckFjdGlvbiA9IGZhbHNlO1xuICAgICAgdGhpcy5hY3Rpb25UaW1lc3RhbXAgPSBudWxsO1xuICAgICAgXG4gICAgICBjb25zdCBkdXJhdGlvbiA9IERhdGUubm93KCkgLSBzdGFydFRpbWU7XG4gICAgICBsb2dnZXIuaW5mbygnR2l0SHViIHBvcnRmb2xpbyBpbmRleCBmZXRjaGVkIHN1Y2Nlc3NmdWxseScsIHtcbiAgICAgICAgdXNlcm5hbWUsXG4gICAgICAgIHRvdGFsRWxlbWVudHM6IGluZGV4LnRvdGFsRWxlbWVudHMsXG4gICAgICAgIGR1cmF0aW9uOiBgJHtkdXJhdGlvbn1tc2AsXG4gICAgICAgIHJhdGVMaW1pdFJlbWFpbmluZzogaW5kZXgucmF0ZUxpbWl0SW5mbz8ucmVtYWluaW5nXG4gICAgICB9KTtcbiAgICAgIFxuICAgICAgLy8gTG9nIHNlY3VyaXR5IGV2ZW50XG4gICAgICBTZWN1cml0eU1vbml0b3IubG9nU2VjdXJpdHlFdmVudCh7XG4gICAgICAgIHR5cGU6ICdQT1JURk9MSU9fRkVUQ0hfU1VDQ0VTUycsXG4gICAgICAgIHNldmVyaXR5OiAnTE9XJyxcbiAgICAgICAgc291cmNlOiAnR2l0SHViUG9ydGZvbGlvSW5kZXhlci5mZXRjaEZyZXNoJyxcbiAgICAgICAgZGV0YWlsczogYEZldGNoZWQgR2l0SHViIHBvcnRmb2xpbyB3aXRoICR7aW5kZXgudG90YWxFbGVtZW50c30gZWxlbWVudHMgaW4gJHtkdXJhdGlvbn1tc2AsXG4gICAgICAgIG1ldGFkYXRhOiB7IHVzZXJuYW1lLCBkdXJhdGlvbiwgdG90YWxFbGVtZW50czogaW5kZXgudG90YWxFbGVtZW50cyB9XG4gICAgICB9KTtcbiAgICAgIFxuICAgICAgcmV0dXJuIGluZGV4O1xuICAgICAgXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGNvbnN0IGR1cmF0aW9uID0gRGF0ZS5ub3coKSAtIHN0YXJ0VGltZTtcbiAgICAgIEVycm9ySGFuZGxlci5sb2dFcnJvcignR2l0SHViUG9ydGZvbGlvSW5kZXhlci5mZXRjaEZyZXNoJywgZXJyb3IsIHsgZHVyYXRpb24gfSk7XG4gICAgICB0aHJvdyBFcnJvckhhbmRsZXIud3JhcEVycm9yKGVycm9yLCAnRmFpbGVkIHRvIGZldGNoIEdpdEh1YiBwb3J0Zm9saW8gaW5kZXgnLCBFcnJvckNhdGVnb3J5Lk5FVFdPUktfRVJST1IpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBGZXRjaCByZXBvc2l0b3J5IGNvbnRlbnQgZnJvbSBHaXRIdWIgQVBJXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGZldGNoUmVwb3NpdG9yeUNvbnRlbnQodXNlcm5hbWU6IHN0cmluZywgcmVwb3NpdG9yeTogc3RyaW5nKTogUHJvbWlzZTxHaXRIdWJQb3J0Zm9saW9JbmRleD4ge1xuICAgIC8vIFRyeSBHcmFwaFFMIGZpcnN0IGZvciBiZXR0ZXIgcGVyZm9ybWFuY2UsIGZhbGxiYWNrIHRvIFJFU1RcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuZmV0Y2hXaXRoR3JhcGhRTCh1c2VybmFtZSwgcmVwb3NpdG9yeSk7XG4gICAgfSBjYXRjaCAoZ3JhcGhxbEVycm9yKSB7XG4gICAgICBsb2dnZXIuZGVidWcoJ0dyYXBoUUwgZmV0Y2ggZmFpbGVkLCBmYWxsaW5nIGJhY2sgdG8gUkVTVCBBUEknLCB7XG4gICAgICAgIGVycm9yOiBncmFwaHFsRXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGdyYXBocWxFcnJvci5tZXNzYWdlIDogU3RyaW5nKGdyYXBocWxFcnJvcilcbiAgICAgIH0pO1xuICAgICAgXG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5mZXRjaFdpdGhSRVNUKHVzZXJuYW1lLCByZXBvc2l0b3J5KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRmV0Y2ggdXNpbmcgR3JhcGhRTCBmb3IgYmV0dGVyIHBlcmZvcm1hbmNlXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGZldGNoV2l0aEdyYXBoUUwodXNlcm5hbWU6IHN0cmluZywgcmVwb3NpdG9yeTogc3RyaW5nKTogUHJvbWlzZTxHaXRIdWJQb3J0Zm9saW9JbmRleD4ge1xuICAgIGNvbnN0IHF1ZXJ5ID0gYFxuICAgICAgcXVlcnkgR2V0UG9ydGZvbGlvQ29udGVudCgkb3duZXI6IFN0cmluZyEsICRuYW1lOiBTdHJpbmchKSB7XG4gICAgICAgIHJlcG9zaXRvcnkob3duZXI6ICRvd25lciwgbmFtZTogJG5hbWUpIHtcbiAgICAgICAgICBkZWZhdWx0QnJhbmNoUmVmIHtcbiAgICAgICAgICAgIHRhcmdldCB7XG4gICAgICAgICAgICAgIC4uLiBvbiBDb21taXQge1xuICAgICAgICAgICAgICAgIG9pZFxuICAgICAgICAgICAgICAgIGhpc3RvcnkoZmlyc3Q6IDEpIHtcbiAgICAgICAgICAgICAgICAgIG5vZGVzIHtcbiAgICAgICAgICAgICAgICAgICAgY29tbWl0dGVkRGF0ZVxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBvYmplY3QoZXhwcmVzc2lvbjogXCJIRUFEOlwiKSB7XG4gICAgICAgICAgICAuLi4gb24gVHJlZSB7XG4gICAgICAgICAgICAgIGVudHJpZXMge1xuICAgICAgICAgICAgICAgIG5hbWVcbiAgICAgICAgICAgICAgICB0eXBlXG4gICAgICAgICAgICAgICAgb2JqZWN0IHtcbiAgICAgICAgICAgICAgICAgIC4uLiBvbiBUcmVlIHtcbiAgICAgICAgICAgICAgICAgICAgZW50cmllcyB7XG4gICAgICAgICAgICAgICAgICAgICAgbmFtZVxuICAgICAgICAgICAgICAgICAgICAgIHR5cGVcbiAgICAgICAgICAgICAgICAgICAgICBvaWRcbiAgICAgICAgICAgICAgICAgICAgICBvYmplY3Qge1xuICAgICAgICAgICAgICAgICAgICAgICAgLi4uIG9uIEJsb2Ige1xuICAgICAgICAgICAgICAgICAgICAgICAgICBieXRlU2l6ZVxuICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXh0XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJhdGVMaW1pdCB7XG4gICAgICAgICAgcmVtYWluaW5nXG4gICAgICAgICAgcmVzZXRBdFxuICAgICAgICB9XG4gICAgICB9XG4gICAgYDtcbiAgICBcbiAgICBjb25zdCB2YXJpYWJsZXMgPSB7IG93bmVyOiB1c2VybmFtZSwgbmFtZTogcmVwb3NpdG9yeSB9O1xuICAgIFxuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy5naXRodWJDbGllbnQuZmV0Y2hGcm9tR2l0SHViKCdodHRwczovL2FwaS5naXRodWIuY29tL2dyYXBocWwnLCB0cnVlKTtcbiAgICBcbiAgICAvLyBOb3RlOiBUaGlzIGlzIGEgc2ltcGxpZmllZCBHcmFwaFFMIGltcGxlbWVudGF0aW9uXG4gICAgLy8gSW4gYSByZWFsIGltcGxlbWVudGF0aW9uLCB5b3Ugd291bGQgc2VuZCBQT1NUIHJlcXVlc3Qgd2l0aCBxdWVyeSBhbmQgdmFyaWFibGVzXG4gICAgdGhyb3cgbmV3IEVycm9yKCdHcmFwaFFMIGltcGxlbWVudGF0aW9uIG5vdCB5ZXQgY29tcGxldGUnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGZXRjaCB1c2luZyBSRVNUIEFQSSB3aXRoIHBhZ2luYXRpb25cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgZmV0Y2hXaXRoUkVTVCh1c2VybmFtZTogc3RyaW5nLCByZXBvc2l0b3J5OiBzdHJpbmcpOiBQcm9taXNlPEdpdEh1YlBvcnRmb2xpb0luZGV4PiB7XG4gICAgY29uc3Qgbm9ybWFsaXplZFVzZXJuYW1lID0gVW5pY29kZVZhbGlkYXRvci5ub3JtYWxpemUodXNlcm5hbWUpLm5vcm1hbGl6ZWRDb250ZW50O1xuICAgIFxuICAgIC8vIEdldCByZXBvc2l0b3J5IGluZm8gYW5kIGxhdGVzdCBjb21taXRcbiAgICBjb25zdCByZXBvSW5mbyA9IGF3YWl0IHRoaXMuZ2l0aHViQ2xpZW50LmZldGNoRnJvbUdpdEh1YihcbiAgICAgIGBodHRwczovL2FwaS5naXRodWIuY29tL3JlcG9zLyR7bm9ybWFsaXplZFVzZXJuYW1lfS8ke3JlcG9zaXRvcnl9YFxuICAgICk7XG4gICAgXG4gICAgY29uc3QgbGF0ZXN0Q29tbWl0ID0gYXdhaXQgdGhpcy5naXRodWJDbGllbnQuZmV0Y2hGcm9tR2l0SHViKFxuICAgICAgYGh0dHBzOi8vYXBpLmdpdGh1Yi5jb20vcmVwb3MvJHtub3JtYWxpemVkVXNlcm5hbWV9LyR7cmVwb3NpdG9yeX0vY29tbWl0cy9IRUFEYFxuICAgICk7XG4gICAgXG4gICAgLy8gSW5pdGlhbGl6ZSBpbmRleFxuICAgIGNvbnN0IGluZGV4OiBHaXRIdWJQb3J0Zm9saW9JbmRleCA9IHtcbiAgICAgIHVzZXJuYW1lOiBub3JtYWxpemVkVXNlcm5hbWUsXG4gICAgICByZXBvc2l0b3J5LFxuICAgICAgbGFzdFVwZGF0ZWQ6IG5ldyBEYXRlKGxhdGVzdENvbW1pdC5jb21taXQuY29tbWl0dGVyLmRhdGUpLFxuICAgICAgZWxlbWVudHM6IG5ldyBNYXAoKSxcbiAgICAgIHRvdGFsRWxlbWVudHM6IDAsXG4gICAgICBzaGE6IGxhdGVzdENvbW1pdC5zaGFcbiAgICB9O1xuICAgIFxuICAgIC8vIEluaXRpYWxpemUgZWxlbWVudCB0eXBlIG1hcHNcbiAgICBmb3IgKGNvbnN0IGVsZW1lbnRUeXBlIG9mIE9iamVjdC52YWx1ZXMoRWxlbWVudFR5cGUpKSB7XG4gICAgICBpbmRleC5lbGVtZW50cy5zZXQoZWxlbWVudFR5cGUsIFtdKTtcbiAgICB9XG4gICAgXG4gICAgLy8gRmV0Y2ggY29udGVudCBmb3IgZWFjaCBlbGVtZW50IHR5cGVcbiAgICBmb3IgKGNvbnN0IGVsZW1lbnRUeXBlIG9mIE9iamVjdC52YWx1ZXMoRWxlbWVudFR5cGUpKSB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBlbnRyaWVzID0gYXdhaXQgdGhpcy5mZXRjaEVsZW1lbnRUeXBlQ29udGVudChub3JtYWxpemVkVXNlcm5hbWUsIHJlcG9zaXRvcnksIGVsZW1lbnRUeXBlKTtcbiAgICAgICAgaW5kZXguZWxlbWVudHMuc2V0KGVsZW1lbnRUeXBlLCBlbnRyaWVzKTtcbiAgICAgICAgaW5kZXgudG90YWxFbGVtZW50cyArPSBlbnRyaWVzLmxlbmd0aDtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGxvZ2dlci53YXJuKGBGYWlsZWQgdG8gZmV0Y2ggJHtlbGVtZW50VHlwZX0gZnJvbSBHaXRIdWIgcG9ydGZvbGlvYCwge1xuICAgICAgICAgIGVycm9yOiBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IFN0cmluZyhlcnJvcilcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIENvbnRpbnVlIHdpdGggb3RoZXIgZWxlbWVudCB0eXBlc1xuICAgICAgfVxuICAgIH1cbiAgICBcbiAgICByZXR1cm4gaW5kZXg7XG4gIH1cblxuICAvKipcbiAgICogRmV0Y2ggY29udGVudCBmb3IgYSBzcGVjaWZpYyBlbGVtZW50IHR5cGVcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgZmV0Y2hFbGVtZW50VHlwZUNvbnRlbnQoXG4gICAgdXNlcm5hbWU6IHN0cmluZyxcbiAgICByZXBvc2l0b3J5OiBzdHJpbmcsXG4gICAgZWxlbWVudFR5cGU6IEVsZW1lbnRUeXBlXG4gICk6IFByb21pc2U8R2l0SHViSW5kZXhFbnRyeVtdPiB7XG4gICAgdHJ5IHtcbiAgICAgIC8vIEdldCBkaXJlY3RvcnkgbGlzdGluZ1xuICAgICAgY29uc3QgY29udGVudHMgPSBhd2FpdCB0aGlzLmdpdGh1YkNsaWVudC5mZXRjaEZyb21HaXRIdWIoXG4gICAgICAgIGBodHRwczovL2FwaS5naXRodWIuY29tL3JlcG9zLyR7dXNlcm5hbWV9LyR7cmVwb3NpdG9yeX0vY29udGVudHMvJHtlbGVtZW50VHlwZX1gXG4gICAgICApO1xuICAgICAgXG4gICAgICBpZiAoIUFycmF5LmlzQXJyYXkoY29udGVudHMpKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cbiAgICAgIFxuICAgICAgY29uc3QgZW50cmllczogR2l0SHViSW5kZXhFbnRyeVtdID0gW107XG4gICAgICBjb25zdCBtYXhDb25jdXJyZW50ID0gNTsgLy8gTGltaXQgY29uY3VycmVudCByZXF1ZXN0c1xuICAgICAgXG4gICAgICAvLyBQcm9jZXNzIGZpbGVzIGluIGJhdGNoZXMgdG8gYXZvaWQgcmF0ZSBsaW1pdGluZ1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjb250ZW50cy5sZW5ndGg7IGkgKz0gbWF4Q29uY3VycmVudCkge1xuICAgICAgICBjb25zdCBiYXRjaCA9IGNvbnRlbnRzLnNsaWNlKGksIGkgKyBtYXhDb25jdXJyZW50KTtcbiAgICAgICAgY29uc3QgYmF0Y2hQcm9taXNlcyA9IGJhdGNoXG4gICAgICAgICAgLmZpbHRlcihpdGVtID0+IGl0ZW0udHlwZSA9PT0gJ2ZpbGUnICYmIGl0ZW0ubmFtZS5lbmRzV2l0aCgnLm1kJykpXG4gICAgICAgICAgLm1hcChpdGVtID0+IHRoaXMuY3JlYXRlR2l0SHViSW5kZXhFbnRyeSh1c2VybmFtZSwgcmVwb3NpdG9yeSwgZWxlbWVudFR5cGUsIGl0ZW0pKTtcbiAgICAgICAgXG4gICAgICAgIGNvbnN0IGJhdGNoUmVzdWx0cyA9IGF3YWl0IFByb21pc2UuYWxsU2V0dGxlZChiYXRjaFByb21pc2VzKTtcbiAgICAgICAgXG4gICAgICAgIGZvciAoY29uc3QgcmVzdWx0IG9mIGJhdGNoUmVzdWx0cykge1xuICAgICAgICAgIGlmIChyZXN1bHQuc3RhdHVzID09PSAnZnVsZmlsbGVkJyAmJiByZXN1bHQudmFsdWUpIHtcbiAgICAgICAgICAgIGVudHJpZXMucHVzaChyZXN1bHQudmFsdWUpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBcbiAgICAgICAgLy8gQWRkIGRlbGF5IGJldHdlZW4gYmF0Y2hlcyB0byByZXNwZWN0IHJhdGUgbGltaXRzXG4gICAgICAgIGlmIChpICsgbWF4Q29uY3VycmVudCA8IGNvbnRlbnRzLmxlbmd0aCkge1xuICAgICAgICAgIGF3YWl0IG5ldyBQcm9taXNlKHJlc29sdmUgPT4gc2V0VGltZW91dChyZXNvbHZlLCAxMDApKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgXG4gICAgICByZXR1cm4gZW50cmllcztcbiAgICAgIFxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAvLyBEaXJlY3RvcnkgbWlnaHQgbm90IGV4aXN0XG4gICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBFcnJvciAmJiBlcnJvci5tZXNzYWdlLmluY2x1ZGVzKCc0MDQnKSkge1xuICAgICAgICByZXR1cm4gW107XG4gICAgICB9XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIEdpdEh1YiBpbmRleCBlbnRyeSBmcm9tIEFQSSByZXNwb25zZVxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBjcmVhdGVHaXRIdWJJbmRleEVudHJ5KFxuICAgIHVzZXJuYW1lOiBzdHJpbmcsXG4gICAgcmVwb3NpdG9yeTogc3RyaW5nLFxuICAgIGVsZW1lbnRUeXBlOiBFbGVtZW50VHlwZSxcbiAgICBmaWxlSW5mbzogYW55XG4gICk6IFByb21pc2U8R2l0SHViSW5kZXhFbnRyeSB8IG51bGw+IHtcbiAgICB0cnkge1xuICAgICAgLy8gUGFyc2UgbWV0YWRhdGEgZnJvbSBmaWxlbmFtZSBvciBmZXRjaCBjb250ZW50IGlmIG5lZWRlZFxuICAgICAgY29uc3QgbmFtZSA9IGZpbGVJbmZvLm5hbWUucmVwbGFjZSgnLm1kJywgJycpLnJlcGxhY2UoLy0vZywgJyAnKTtcbiAgICAgIFxuICAgICAgY29uc3QgZW50cnk6IEdpdEh1YkluZGV4RW50cnkgPSB7XG4gICAgICAgIHBhdGg6IGZpbGVJbmZvLnBhdGgsXG4gICAgICAgIG5hbWUsXG4gICAgICAgIGVsZW1lbnRUeXBlLFxuICAgICAgICBzaGE6IGZpbGVJbmZvLnNoYSxcbiAgICAgICAgaHRtbFVybDogZmlsZUluZm8uaHRtbF91cmwsXG4gICAgICAgIGRvd25sb2FkVXJsOiBmaWxlSW5mby5kb3dubG9hZF91cmwsXG4gICAgICAgIGxhc3RNb2RpZmllZDogbmV3IERhdGUoKSwgLy8gR2l0SHViIEFQSSBkb2Vzbid0IHByb3ZpZGUgZmlsZSBtb2RpZmljYXRpb24gdGltZSBkaXJlY3RseVxuICAgICAgICBzaXplOiBmaWxlSW5mby5zaXplIHx8IDBcbiAgICAgIH07XG4gICAgICBcbiAgICAgIC8vIE9wdGlvbmFsbHkgZmV0Y2ggY29udGVudCB0byBleHRyYWN0IG1ldGFkYXRhXG4gICAgICAvLyBUaGlzIGlzIGV4cGVuc2l2ZSwgc28gb25seSBkbyBpdCBmb3Igc21hbGwgZmlsZXMgb3Igd2hlbiBzcGVjaWZpY2FsbHkgbmVlZGVkXG4gICAgICBpZiAoZmlsZUluZm8uc2l6ZSAmJiBmaWxlSW5mby5zaXplIDwgMTAwMDApIHsgLy8gT25seSBmb3IgZmlsZXMgPCAxMEtCXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgY29udGVudCA9IGF3YWl0IHRoaXMuZ2l0aHViQ2xpZW50LmZldGNoRnJvbUdpdEh1YihmaWxlSW5mby5kb3dubG9hZF91cmwpO1xuICAgICAgICAgIGNvbnN0IG1ldGFkYXRhID0gdGhpcy5wYXJzZU1ldGFkYXRhRnJvbUNvbnRlbnQoY29udGVudCk7XG4gICAgICAgICAgXG4gICAgICAgICAgaWYgKG1ldGFkYXRhLm5hbWUpIGVudHJ5Lm5hbWUgPSBtZXRhZGF0YS5uYW1lO1xuICAgICAgICAgIGlmIChtZXRhZGF0YS5kZXNjcmlwdGlvbikgZW50cnkuZGVzY3JpcHRpb24gPSBtZXRhZGF0YS5kZXNjcmlwdGlvbjtcbiAgICAgICAgICBpZiAobWV0YWRhdGEudmVyc2lvbikgZW50cnkudmVyc2lvbiA9IG1ldGFkYXRhLnZlcnNpb247XG4gICAgICAgICAgaWYgKG1ldGFkYXRhLmF1dGhvcikgZW50cnkuYXV0aG9yID0gbWV0YWRhdGEuYXV0aG9yO1xuICAgICAgICB9IGNhdGNoIChtZXRhZGF0YUVycm9yKSB7XG4gICAgICAgICAgLy8gTm9uLWNyaXRpY2FsIGVycm9yLCBjb250aW51ZSB3aXRob3V0IG1ldGFkYXRhXG4gICAgICAgICAgbG9nZ2VyLmRlYnVnKCdGYWlsZWQgdG8gZmV0Y2ggbWV0YWRhdGEgZm9yIGZpbGUnLCB7XG4gICAgICAgICAgICBwYXRoOiBmaWxlSW5mby5wYXRoLFxuICAgICAgICAgICAgZXJyb3I6IG1ldGFkYXRhRXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IG1ldGFkYXRhRXJyb3IubWVzc2FnZSA6IFN0cmluZyhtZXRhZGF0YUVycm9yKVxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBcbiAgICAgIHJldHVybiBlbnRyeTtcbiAgICAgIFxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBsb2dnZXIuZGVidWcoJ0ZhaWxlZCB0byBjcmVhdGUgR2l0SHViIGluZGV4IGVudHJ5Jywge1xuICAgICAgICBwYXRoOiBmaWxlSW5mby5wYXRoLFxuICAgICAgICBlcnJvcjogZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpXG4gICAgICB9KTtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBQYXJzZSBtZXRhZGF0YSBmcm9tIGZpbGUgY29udGVudCAoZnJvbnRtYXR0ZXIpXG4gICAqL1xuICBwcml2YXRlIHBhcnNlTWV0YWRhdGFGcm9tQ29udGVudChjb250ZW50OiBzdHJpbmcpOiB7XG4gICAgbmFtZT86IHN0cmluZztcbiAgICBkZXNjcmlwdGlvbj86IHN0cmluZztcbiAgICB2ZXJzaW9uPzogc3RyaW5nO1xuICAgIGF1dGhvcj86IHN0cmluZztcbiAgfSB7XG4gICAgY29uc3QgbWV0YWRhdGE6IGFueSA9IHt9O1xuICAgIFxuICAgIC8vIFNpbXBsZSBmcm9udG1hdHRlciBwYXJzaW5nIChjb3VsZCB1c2UgYSBwcm9wZXIgWUFNTCBwYXJzZXIpXG4gICAgY29uc3QgZnJvbnRtYXR0ZXJNYXRjaCA9IGNvbnRlbnQubWF0Y2goL14tLS1cXG4oW1xcc1xcU10qPylcXG4tLS0vKTtcbiAgICBpZiAoZnJvbnRtYXR0ZXJNYXRjaCkge1xuICAgICAgY29uc3QgZnJvbnRtYXR0ZXIgPSBmcm9udG1hdHRlck1hdGNoWzFdO1xuICAgICAgXG4gICAgICBjb25zdCBuYW1lTWF0Y2ggPSBmcm9udG1hdHRlci5tYXRjaCgvXm5hbWU6XFxzKiguKykkL20pO1xuICAgICAgaWYgKG5hbWVNYXRjaCkgbWV0YWRhdGEubmFtZSA9IG5hbWVNYXRjaFsxXS50cmltKCk7XG4gICAgICBcbiAgICAgIGNvbnN0IGRlc2NNYXRjaCA9IGZyb250bWF0dGVyLm1hdGNoKC9eZGVzY3JpcHRpb246XFxzKiguKykkL20pO1xuICAgICAgaWYgKGRlc2NNYXRjaCkgbWV0YWRhdGEuZGVzY3JpcHRpb24gPSBkZXNjTWF0Y2hbMV0udHJpbSgpO1xuICAgICAgXG4gICAgICBjb25zdCB2ZXJzaW9uTWF0Y2ggPSBmcm9udG1hdHRlci5tYXRjaCgvXnZlcnNpb246XFxzKiguKykkL20pO1xuICAgICAgaWYgKHZlcnNpb25NYXRjaCkgbWV0YWRhdGEudmVyc2lvbiA9IHZlcnNpb25NYXRjaFsxXS50cmltKCk7XG4gICAgICBcbiAgICAgIGNvbnN0IGF1dGhvck1hdGNoID0gZnJvbnRtYXR0ZXIubWF0Y2goL15hdXRob3I6XFxzKiguKykkL20pO1xuICAgICAgaWYgKGF1dGhvck1hdGNoKSBtZXRhZGF0YS5hdXRob3IgPSBhdXRob3JNYXRjaFsxXS50cmltKCk7XG4gICAgfVxuICAgIFxuICAgIHJldHVybiBtZXRhZGF0YTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgR2l0SHViIHVzZXJuYW1lIGZyb20gYXV0aGVudGljYXRlZCB0b2tlblxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBnZXRHaXRIdWJVc2VybmFtZSgpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCB1c2VySW5mbyA9IGF3YWl0IHRoaXMuZ2l0aHViQ2xpZW50LmZldGNoRnJvbUdpdEh1YignaHR0cHM6Ly9hcGkuZ2l0aHViLmNvbS91c2VyJywgdHJ1ZSk7XG4gICAgICByZXR1cm4gdXNlckluZm8ubG9naW47XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignRmFpbGVkIHRvIGdldCBHaXRIdWIgdXNlcm5hbWUuIFBsZWFzZSBlbnN1cmUgeW91IGFyZSBhdXRoZW50aWNhdGVkIHdpdGggR2l0SHViLicpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiBjYWNoZSBpcyB2YWxpZFxuICAgKi9cbiAgcHJpdmF0ZSBpc0NhY2hlVmFsaWQoKTogYm9vbGVhbiB7XG4gICAgaWYgKCF0aGlzLmNhY2hlIHx8ICF0aGlzLmxhc3RGZXRjaCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBcbiAgICBjb25zdCBhZ2UgPSBEYXRlLm5vdygpIC0gdGhpcy5sYXN0RmV0Y2guZ2V0VGltZSgpO1xuICAgIHJldHVybiBhZ2UgPCB0aGlzLnR0bDtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZXRlcm1pbmUgaWYgd2Ugc2hvdWxkIGZldGNoIGZyZXNoIGRhdGFcbiAgICovXG4gIHByaXZhdGUgc2hvdWxkRmV0Y2hGcmVzaCgpOiBib29sZWFuIHtcbiAgICAvLyBBbHdheXMgZmV0Y2ggaWYgbm8gY2FjaGVcbiAgICBpZiAoIXRoaXMuY2FjaGUgfHwgIXRoaXMubGFzdEZldGNoKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgXG4gICAgLy8gQ2hlY2sgZm9yIHJlY2VudCB1c2VyIGFjdGlvbnNcbiAgICBpZiAodGhpcy5yZWNlbnRVc2VyQWN0aW9uICYmIHRoaXMuYWN0aW9uVGltZXN0YW1wKSB7XG4gICAgICBjb25zdCBhY3Rpb25BZ2UgPSBEYXRlLm5vdygpIC0gdGhpcy5hY3Rpb25UaW1lc3RhbXAuZ2V0VGltZSgpO1xuICAgICAgaWYgKGFjdGlvbkFnZSA8IHRoaXMuYWN0aW9uR3JhY2VQZXJpb2QpIHtcbiAgICAgICAgbG9nZ2VyLmRlYnVnKCdGZXRjaGluZyBmcmVzaCBkdWUgdG8gcmVjZW50IHVzZXIgYWN0aW9uJywgeyBhY3Rpb25BZ2UgfSk7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gR3JhY2UgcGVyaW9kIGV4cGlyZWQsIGNsZWFyIGFjdGlvbiBmbGFnXG4gICAgICAgIHRoaXMucmVjZW50VXNlckFjdGlvbiA9IGZhbHNlO1xuICAgICAgICB0aGlzLmFjdGlvblRpbWVzdGFtcCA9IG51bGw7XG4gICAgICB9XG4gICAgfVxuICAgIFxuICAgIC8vIENoZWNrIFRUTFxuICAgIHJldHVybiAhdGhpcy5pc0NhY2hlVmFsaWQoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgZW1wdHkgaW5kZXggd2hlbiBubyBwb3J0Zm9saW8gZXhpc3RzXG4gICAqL1xuICBwcml2YXRlIGNyZWF0ZUVtcHR5SW5kZXgodXNlcm5hbWU/OiBzdHJpbmcsIHJlcG9zaXRvcnk/OiBzdHJpbmcpOiBHaXRIdWJQb3J0Zm9saW9JbmRleCB7XG4gICAgY29uc3QgaW5kZXg6IEdpdEh1YlBvcnRmb2xpb0luZGV4ID0ge1xuICAgICAgdXNlcm5hbWU6IHVzZXJuYW1lIHx8ICd1bmtub3duJyxcbiAgICAgIHJlcG9zaXRvcnk6IHJlcG9zaXRvcnkgfHwgJ2RvbGxob3VzZS1wb3J0Zm9saW8nLFxuICAgICAgbGFzdFVwZGF0ZWQ6IG5ldyBEYXRlKCksXG4gICAgICBlbGVtZW50czogbmV3IE1hcCgpLFxuICAgICAgdG90YWxFbGVtZW50czogMCxcbiAgICAgIHNoYTogJydcbiAgICB9O1xuICAgIFxuICAgIC8vIEluaXRpYWxpemUgZW1wdHkgZWxlbWVudCB0eXBlIG1hcHNcbiAgICBmb3IgKGNvbnN0IGVsZW1lbnRUeXBlIG9mIE9iamVjdC52YWx1ZXMoRWxlbWVudFR5cGUpKSB7XG4gICAgICBpbmRleC5lbGVtZW50cy5zZXQoZWxlbWVudFR5cGUsIFtdKTtcbiAgICB9XG4gICAgXG4gICAgcmV0dXJuIGluZGV4O1xuICB9XG59Il19
@@ -1 +1 @@
1
- {"version":3,"file":"MigrationManager.d.ts","sourceRoot":"","sources":["../../src/portfolio/MigrationManager.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAIzC,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,gBAAgB,CAAmB;gBAE/B,gBAAgB,EAAE,gBAAgB;IAI9C;;OAEG;IACU,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC;IAQ/C;;OAEG;IACU,OAAO,CAAC,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,eAAe,CAAC;IA2E9E;;OAEG;YACW,cAAc;IAiC5B;;OAEG;YACW,YAAY;IAuB1B;;OAEG;IACU,kBAAkB,IAAI,OAAO,CAAC;QACzC,iBAAiB,EAAE,OAAO,CAAC;QAC3B,kBAAkB,EAAE,MAAM,CAAC;QAC3B,eAAe,EAAE,OAAO,CAAC;QACzB,cAAc,EAAE,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;KAC7C,CAAC;CAsBH"}
1
+ {"version":3,"file":"MigrationManager.d.ts","sourceRoot":"","sources":["../../src/portfolio/MigrationManager.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAOzC,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,gBAAgB,CAAmB;gBAE/B,gBAAgB,EAAE,gBAAgB;IAI9C;;OAEG;IACU,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC;IAQ/C;;OAEG;IACU,OAAO,CAAC,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,eAAe,CAAC;IA8I9E;;OAEG;YACW,cAAc;IA6F5B;;OAEG;YACW,YAAY;IAwC1B;;OAEG;IACU,kBAAkB,IAAI,OAAO,CAAC;QACzC,iBAAiB,EAAE,OAAO,CAAC;QAC3B,kBAAkB,EAAE,MAAM,CAAC;QAC3B,eAAe,EAAE,OAAO,CAAC;QACzB,cAAc,EAAE,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;KAC7C,CAAC;CAsBH"}