@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.
- package/CHANGELOG.md +56 -0
- package/README.md +494 -111
- package/data/agents/code-reviewer.md +8 -1
- package/data/agents/research-assistant.md +8 -1
- package/data/agents/task-manager.md +8 -1
- package/data/ensembles/business-advisor.md +8 -1
- package/data/ensembles/creative-studio.md +8 -1
- package/data/ensembles/development-team.md +8 -1
- package/data/ensembles/security-analysis-team.md +8 -1
- package/data/memories/conversation-history.md +8 -1
- package/data/memories/learning-progress.md +8 -1
- package/data/memories/project-context.md +8 -1
- package/data/personas/business-consultant.md +8 -1
- package/data/personas/creative-writer.md +8 -1
- package/data/personas/debug-detective.md +8 -1
- package/data/personas/eli5-explainer.md +8 -1
- package/data/personas/security-analyst.md +8 -1
- package/data/personas/technical-analyst.md +8 -1
- package/data/skills/code-review.md +8 -1
- package/data/skills/creative-writing.md +8 -1
- package/data/skills/data-analysis.md +8 -1
- package/data/skills/penetration-testing.md +8 -1
- package/data/skills/research.md +8 -1
- package/data/skills/threat-modeling.md +8 -1
- package/data/skills/translation.md +8 -1
- package/data/templates/code-documentation.md +8 -1
- package/data/templates/email-professional.md +8 -1
- package/data/templates/meeting-notes.md +8 -1
- package/data/templates/penetration-test-report.md +8 -1
- package/data/templates/project-brief.md +8 -1
- package/data/templates/report-executive.md +8 -1
- package/data/templates/security-vulnerability-report.md +8 -1
- package/data/templates/threat-assessment-report.md +8 -1
- package/dist/auth/GitHubAuthManager.d.ts +6 -1
- package/dist/auth/GitHubAuthManager.d.ts.map +1 -1
- package/dist/auth/GitHubAuthManager.js +45 -18
- package/dist/benchmarks/IndexPerformanceBenchmark.d.ts +98 -0
- package/dist/benchmarks/IndexPerformanceBenchmark.d.ts.map +1 -0
- package/dist/benchmarks/IndexPerformanceBenchmark.js +531 -0
- package/dist/cache/CollectionCache.d.ts.map +1 -1
- package/dist/cache/CollectionCache.js +13 -3
- package/dist/cache/CollectionIndexCache.d.ts +77 -0
- package/dist/cache/CollectionIndexCache.d.ts.map +1 -0
- package/dist/cache/CollectionIndexCache.js +349 -0
- package/dist/cache/LRUCache.d.ts +93 -0
- package/dist/cache/LRUCache.d.ts.map +1 -0
- package/dist/cache/LRUCache.js +299 -0
- package/dist/cache/index.d.ts +1 -0
- package/dist/cache/index.d.ts.map +1 -1
- package/dist/cache/index.js +2 -1
- package/dist/collection/CollectionBrowser.d.ts +21 -1
- package/dist/collection/CollectionBrowser.d.ts.map +1 -1
- package/dist/collection/CollectionBrowser.js +130 -10
- package/dist/collection/CollectionIndexManager.d.ts +151 -0
- package/dist/collection/CollectionIndexManager.d.ts.map +1 -0
- package/dist/collection/CollectionIndexManager.js +499 -0
- package/dist/collection/CollectionSearch.d.ts +55 -0
- package/dist/collection/CollectionSearch.d.ts.map +1 -1
- package/dist/collection/CollectionSearch.js +338 -13
- package/dist/collection/CollectionSeeder.d.ts.map +1 -1
- package/dist/collection/CollectionSeeder.js +38 -1
- package/dist/collection/ElementInstaller.d.ts +31 -0
- package/dist/collection/ElementInstaller.d.ts.map +1 -1
- package/dist/collection/ElementInstaller.js +77 -15
- package/dist/collection/PersonaSubmitter.d.ts +1 -1
- package/dist/collection/PersonaSubmitter.d.ts.map +1 -1
- package/dist/collection/PersonaSubmitter.js +2 -2
- package/dist/collection/index.d.ts +1 -0
- package/dist/collection/index.d.ts.map +1 -1
- package/dist/collection/index.js +2 -1
- package/dist/config/ConfigManager.d.ts +78 -0
- package/dist/config/ConfigManager.d.ts.map +1 -0
- package/dist/config/ConfigManager.js +216 -0
- package/dist/config/element-types.d.ts +135 -0
- package/dist/config/element-types.d.ts.map +1 -0
- package/dist/config/element-types.js +108 -0
- package/dist/config/index.d.ts +2 -0
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +3 -1
- package/dist/config/portfolio-constants.d.ts +83 -0
- package/dist/config/portfolio-constants.d.ts.map +1 -0
- package/dist/config/portfolio-constants.js +99 -0
- package/dist/elements/BaseElement.d.ts +14 -2
- package/dist/elements/BaseElement.d.ts.map +1 -1
- package/dist/elements/BaseElement.js +88 -6
- package/dist/elements/agents/Agent.d.ts +10 -1
- package/dist/elements/agents/Agent.d.ts.map +1 -1
- package/dist/elements/agents/Agent.js +66 -19
- package/dist/elements/agents/AgentManager.d.ts +2 -0
- package/dist/elements/agents/AgentManager.d.ts.map +1 -1
- package/dist/elements/agents/AgentManager.js +12 -10
- package/dist/elements/skills/Skill.d.ts +10 -1
- package/dist/elements/skills/Skill.d.ts.map +1 -1
- package/dist/elements/skills/Skill.js +40 -3
- package/dist/elements/skills/SkillManager.d.ts +1 -0
- package/dist/elements/skills/SkillManager.d.ts.map +1 -1
- package/dist/elements/skills/SkillManager.js +10 -4
- package/dist/elements/templates/Template.d.ts +10 -1
- package/dist/elements/templates/Template.d.ts.map +1 -1
- package/dist/elements/templates/Template.js +35 -18
- package/dist/elements/templates/TemplateManager.d.ts +1 -1
- package/dist/elements/templates/TemplateManager.d.ts.map +1 -1
- package/dist/elements/templates/TemplateManager.js +6 -5
- package/dist/generated/version.d.ts +2 -2
- package/dist/generated/version.js +3 -3
- package/dist/index.barrel.d.ts +1 -2
- package/dist/index.barrel.d.ts.map +1 -1
- package/dist/index.barrel.js +2 -4
- package/dist/index.d.ts +143 -25
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1883 -310
- package/dist/persona/PersonaElement.d.ts +10 -0
- package/dist/persona/PersonaElement.d.ts.map +1 -1
- package/dist/persona/PersonaElement.js +55 -32
- package/dist/persona/PersonaElementManager.d.ts.map +1 -1
- package/dist/persona/PersonaElementManager.js +13 -11
- package/dist/persona/PersonaLoader.d.ts.map +1 -1
- package/dist/persona/PersonaLoader.js +8 -2
- package/dist/persona/export-import/PersonaImporter.d.ts.map +1 -1
- package/dist/persona/export-import/PersonaImporter.js +24 -5
- package/dist/persona/export-import/PersonaSharer.d.ts +21 -0
- package/dist/persona/export-import/PersonaSharer.d.ts.map +1 -1
- package/dist/persona/export-import/PersonaSharer.js +198 -22
- package/dist/portfolio/DefaultElementProvider.d.ts +90 -0
- package/dist/portfolio/DefaultElementProvider.d.ts.map +1 -1
- package/dist/portfolio/DefaultElementProvider.js +499 -7
- package/dist/portfolio/GitHubPortfolioIndexer.d.ts +129 -0
- package/dist/portfolio/GitHubPortfolioIndexer.d.ts.map +1 -0
- package/dist/portfolio/GitHubPortfolioIndexer.js +475 -0
- package/dist/portfolio/MigrationManager.d.ts.map +1 -1
- package/dist/portfolio/MigrationManager.js +136 -3
- package/dist/portfolio/PortfolioIndexManager.d.ts +130 -0
- package/dist/portfolio/PortfolioIndexManager.d.ts.map +1 -0
- package/dist/portfolio/PortfolioIndexManager.js +478 -0
- package/dist/portfolio/PortfolioManager.d.ts +5 -0
- package/dist/portfolio/PortfolioManager.d.ts.map +1 -1
- package/dist/portfolio/PortfolioManager.js +61 -20
- package/dist/portfolio/PortfolioRepoManager.d.ts +75 -0
- package/dist/portfolio/PortfolioRepoManager.d.ts.map +1 -0
- package/dist/portfolio/PortfolioRepoManager.js +337 -0
- package/dist/portfolio/UnifiedIndexManager.d.ts +388 -0
- package/dist/portfolio/UnifiedIndexManager.d.ts.map +1 -0
- package/dist/portfolio/UnifiedIndexManager.js +1434 -0
- package/dist/portfolio/index.d.ts +15 -0
- package/dist/portfolio/index.d.ts.map +1 -0
- package/dist/portfolio/index.js +15 -0
- package/dist/portfolio/types.d.ts +7 -0
- package/dist/portfolio/types.d.ts.map +1 -1
- package/dist/portfolio/types.js +6 -1
- package/dist/security/InputValidator.d.ts.map +1 -1
- package/dist/security/InputValidator.js +50 -48
- package/dist/security/audit/SecurityAuditor.d.ts.map +1 -1
- package/dist/security/audit/SecurityAuditor.js +17 -9
- package/dist/security/audit/config/suppressions.d.ts.map +1 -1
- package/dist/security/audit/config/suppressions.js +19 -3
- package/dist/security/contentValidator.d.ts +2 -0
- package/dist/security/contentValidator.d.ts.map +1 -1
- package/dist/security/contentValidator.js +115 -4
- package/dist/security/secureYamlParser.d.ts +1 -0
- package/dist/security/secureYamlParser.d.ts.map +1 -1
- package/dist/security/secureYamlParser.js +29 -7
- package/dist/security/securityMonitor.d.ts +1 -1
- package/dist/security/securityMonitor.d.ts.map +1 -1
- package/dist/security/securityMonitor.js +1 -1
- package/dist/security/tokenManager.d.ts +1 -1
- package/dist/security/tokenManager.d.ts.map +1 -1
- package/dist/security/tokenManager.js +30 -10
- package/dist/server/ServerSetup.d.ts +22 -2
- package/dist/server/ServerSetup.d.ts.map +1 -1
- package/dist/server/ServerSetup.js +77 -12
- package/dist/server/tools/AuthTools.d.ts.map +1 -1
- package/dist/server/tools/AuthTools.js +33 -1
- package/dist/server/tools/BuildInfoTools.d.ts +25 -0
- package/dist/server/tools/BuildInfoTools.d.ts.map +1 -0
- package/dist/server/tools/BuildInfoTools.js +36 -0
- package/dist/server/tools/CollectionTools.d.ts.map +1 -1
- package/dist/server/tools/CollectionTools.js +55 -46
- package/dist/server/tools/ConfigTools.d.ts.map +1 -1
- package/dist/server/tools/ConfigTools.js +29 -1
- package/dist/server/tools/PersonaTools.d.ts +4 -2
- package/dist/server/tools/PersonaTools.d.ts.map +1 -1
- package/dist/server/tools/PersonaTools.js +5 -152
- package/dist/server/tools/PortfolioTools.d.ts +12 -0
- package/dist/server/tools/PortfolioTools.d.ts.map +1 -0
- package/dist/server/tools/PortfolioTools.js +221 -0
- package/dist/server/tools/index.d.ts +3 -1
- package/dist/server/tools/index.d.ts.map +1 -1
- package/dist/server/tools/index.js +4 -2
- package/dist/server/types.d.ts +40 -5
- package/dist/server/types.d.ts.map +1 -1
- package/dist/server/types.js +1 -1
- package/dist/services/BuildInfoService.d.ts +84 -0
- package/dist/services/BuildInfoService.d.ts.map +1 -0
- package/dist/services/BuildInfoService.js +271 -0
- package/dist/tools/portfolio/PortfolioElementAdapter.d.ts +54 -0
- package/dist/tools/portfolio/PortfolioElementAdapter.d.ts.map +1 -0
- package/dist/tools/portfolio/PortfolioElementAdapter.js +229 -0
- package/dist/tools/portfolio/submitToPortfolioTool.d.ts +164 -0
- package/dist/tools/portfolio/submitToPortfolioTool.d.ts.map +1 -0
- package/dist/tools/portfolio/submitToPortfolioTool.js +1523 -0
- package/dist/tools/portfolio/types.d.ts +41 -0
- package/dist/tools/portfolio/types.d.ts.map +1 -0
- package/dist/tools/portfolio/types.js +15 -0
- package/dist/types/collection.d.ts +51 -0
- package/dist/types/collection.d.ts.map +1 -1
- package/dist/types/collection.js +1 -1
- package/dist/utils/EarlyTerminationSearch.d.ts +41 -0
- package/dist/utils/EarlyTerminationSearch.d.ts.map +1 -0
- package/dist/utils/EarlyTerminationSearch.js +164 -0
- package/dist/utils/ErrorHandler.d.ts +86 -0
- package/dist/utils/ErrorHandler.d.ts.map +1 -0
- package/dist/utils/ErrorHandler.js +201 -0
- package/dist/utils/FileDiscoveryUtil.d.ts +53 -0
- package/dist/utils/FileDiscoveryUtil.d.ts.map +1 -0
- package/dist/utils/FileDiscoveryUtil.js +169 -0
- package/dist/utils/GitHubRateLimiter.d.ts +88 -0
- package/dist/utils/GitHubRateLimiter.d.ts.map +1 -0
- package/dist/utils/GitHubRateLimiter.js +315 -0
- package/dist/utils/PerformanceMonitor.d.ts +134 -0
- package/dist/utils/PerformanceMonitor.d.ts.map +1 -0
- package/dist/utils/PerformanceMonitor.js +347 -0
- package/dist/utils/RateLimiter.d.ts.map +1 -0
- package/dist/utils/RateLimiter.js +172 -0
- package/dist/utils/SecureDownloader.d.ts +241 -0
- package/dist/utils/SecureDownloader.d.ts.map +1 -0
- package/dist/utils/SecureDownloader.js +759 -0
- package/dist/utils/ToolCache.d.ts +82 -0
- package/dist/utils/ToolCache.d.ts.map +1 -0
- package/dist/utils/ToolCache.js +196 -0
- package/dist/utils/errorCodes.d.ts +136 -0
- package/dist/utils/errorCodes.d.ts.map +1 -0
- package/dist/utils/errorCodes.js +87 -0
- package/dist/utils/index.d.ts +3 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +4 -1
- package/dist/utils/installation.d.ts +1 -1
- package/dist/utils/installation.d.ts.map +1 -1
- package/dist/utils/installation.js +9 -8
- package/dist/utils/searchUtils.d.ts +31 -0
- package/dist/utils/searchUtils.d.ts.map +1 -1
- package/dist/utils/searchUtils.js +62 -1
- package/package.json +17 -7
- package/dist/config/updateConfig.d.ts +0 -84
- package/dist/config/updateConfig.d.ts.map +0 -1
- package/dist/config/updateConfig.js +0 -148
- package/dist/server/tools/UpdateTools.d.ts +0 -10
- package/dist/server/tools/UpdateTools.d.ts.map +0 -1
- package/dist/server/tools/UpdateTools.js +0 -85
- package/dist/update/BackupManager.d.ts +0 -63
- package/dist/update/BackupManager.d.ts.map +0 -1
- package/dist/update/BackupManager.js +0 -370
- package/dist/update/DependencyChecker.d.ts +0 -41
- package/dist/update/DependencyChecker.d.ts.map +0 -1
- package/dist/update/DependencyChecker.js +0 -132
- package/dist/update/RateLimiter.d.ts.map +0 -1
- package/dist/update/RateLimiter.js +0 -172
- package/dist/update/SignatureVerifier.d.ts +0 -71
- package/dist/update/SignatureVerifier.d.ts.map +0 -1
- package/dist/update/SignatureVerifier.js +0 -214
- package/dist/update/UpdateChecker.d.ts +0 -132
- package/dist/update/UpdateChecker.d.ts.map +0 -1
- package/dist/update/UpdateChecker.js +0 -506
- package/dist/update/UpdateManager.d.ts +0 -60
- package/dist/update/UpdateManager.d.ts.map +0 -1
- package/dist/update/UpdateManager.js +0 -730
- package/dist/update/VersionManager.d.ts +0 -31
- package/dist/update/VersionManager.d.ts.map +0 -1
- package/dist/update/VersionManager.js +0 -181
- package/dist/update/index.d.ts +0 -9
- package/dist/update/index.d.ts.map +0 -1
- package/dist/update/index.js +0 -9
- /package/dist/{update → utils}/RateLimiter.d.ts +0 -0
|
@@ -12,8 +12,18 @@ export class CollectionCache {
|
|
|
12
12
|
cacheDir;
|
|
13
13
|
cacheFile;
|
|
14
14
|
CACHE_TTL_MS = 24 * 60 * 60 * 1000; // 24 hours for collection cache
|
|
15
|
-
constructor(baseDir
|
|
16
|
-
|
|
15
|
+
constructor(baseDir) {
|
|
16
|
+
// Use environment variable if set, otherwise fall back to parameter or default
|
|
17
|
+
const envCacheDir = process.env.DOLLHOUSE_CACHE_DIR;
|
|
18
|
+
if (envCacheDir) {
|
|
19
|
+
this.cacheDir = envCacheDir;
|
|
20
|
+
logger.debug(`CollectionCache: Using environment cache directory: ${this.cacheDir}`);
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
const defaultBaseDir = baseDir || process.cwd();
|
|
24
|
+
this.cacheDir = path.join(defaultBaseDir, '.dollhousemcp', 'cache');
|
|
25
|
+
logger.debug(`CollectionCache: Using default cache directory: ${this.cacheDir}`);
|
|
26
|
+
}
|
|
17
27
|
this.cacheFile = path.join(this.cacheDir, 'collection-cache.json');
|
|
18
28
|
}
|
|
19
29
|
/**
|
|
@@ -159,4 +169,4 @@ export class CollectionCache {
|
|
|
159
169
|
};
|
|
160
170
|
}
|
|
161
171
|
}
|
|
162
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQ29sbGVjdGlvbkNhY2hlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NhY2hlL0NvbGxlY3Rpb25DYWNoZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7R0FFRztBQUVILE9BQU8sS0FBSyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ2xDLE9BQU8sS0FBSyxJQUFJLE1BQU0sTUFBTSxDQUFDO0FBQzdCLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUU1QyxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFnQmpFOztHQUVHO0FBQ0gsTUFBTSxPQUFPLGVBQWU7SUFDbEIsUUFBUSxDQUFTO0lBQ2pCLFNBQVMsQ0FBUztJQUNULFlBQVksR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUMsQ0FBQyxnQ0FBZ0M7SUFFckYsWUFBWSxVQUFrQixPQUFPLENBQUMsR0FBRyxFQUFFO1FBQ3pDLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsZUFBZSxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBQzdELElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLHVCQUF1QixDQUFDLENBQUM7SUFDckUsQ0FBQztJQUVEOztPQUVHO0lBQ0ssS0FBSyxDQUFDLGNBQWM7UUFDMUIsSUFBSSxDQUFDO1lBQ0gsTUFBTSxFQUFFLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUNyRCxDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLE1BQU0sQ0FBQyxLQUFLLENBQUMscUNBQXFDLEtBQUssRUFBRSxDQUFDLENBQUM7WUFDM0QsTUFBTSxLQUFLLENBQUM7UUFDZCxDQUFDO0lBQ0gsQ0FB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SSxJQUFJLENBQUMsWUFBWTtTQUMzRCxDQUFDO0lBQ0osQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBQZXJzaXN0ZW50IGNhY2hlIGZvciBjb2xsZWN0aW9uIGRhdGEgdG8gc3VwcG9ydCBvZmZsaW5lL2Fub255bW91cyBicm93c2luZ1xuICovXG5cbmltcG9ydCAqIGFzIGZzIGZyb20gJ2ZzL3Byb21pc2VzJztcbmltcG9ydCAqIGFzIHBhdGggZnJvbSAncGF0aCc7XG5pbXBvcnQgeyBsb2dnZXIgfSBmcm9tICcuLi91dGlscy9sb2dnZXIuanMnO1xuaW1wb3J0IHsgUGF0aFZhbGlkYXRvciB9IGZyb20gJy4uL3NlY3VyaXR5L3BhdGhWYWxpZGF0b3IuanMnO1xuaW1wb3J0IHsgU2VjdXJpdHlNb25pdG9yIH0gZnJvbSAnLi4vc2VjdXJpdHkvc2VjdXJpdHlNb25pdG9yLmpzJztcblxuZXhwb3J0IGludGVyZmFjZSBDb2xsZWN0aW9uSXRlbSB7XG4gIG5hbWU6IHN0cmluZztcbiAgcGF0aDogc3RyaW5nO1xuICBzaGE6IHN0cmluZztcbiAgY29udGVudD86IHN0cmluZztcbiAgbGFzdF9tb2RpZmllZD86IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDb2xsZWN0aW9uQ2FjaGVFbnRyeSB7XG4gIGl0ZW1zOiBDb2xsZWN0aW9uSXRlbVtdO1xuICB0aW1lc3RhbXA6IG51bWJlcjtcbiAgZXRhZz86IHN0cmluZztcbn1cblxuLyoqXG4gKiBQZXJzaXN0ZW50IGNhY2hlIGZvciBjb2xsZWN0aW9uIGRhdGEgdGhhdCBzdXBwb3J0cyBvZmZsaW5lIGJyb3dzaW5nXG4gKi9cbmV4cG9ydCBjbGFzcyBDb2xsZWN0aW9uQ2FjaGUge1xuICBwcml2YXRlIGNhY2hlRGlyOiBzdHJpbmc7XG4gIHByaXZhdGUgY2FjaGVGaWxlOiBzdHJpbmc7XG4gIHByaXZhdGUgcmVhZG9ubHkgQ0FDSEVfVFRMX01TID0gMjQgKiA2MCAqIDYwICogMTAwMDsgLy8gMjQgaG91cnMgZm9yIGNvbGxlY3Rpb24gY2FjaGVcbiAgXG4gIGNvbnN0cnVjdG9yKGJhc2VEaXI6IHN0cmluZyA9IHByb2Nlc3MuY3dkKCkpIHtcbiAgICB0aGlzLmNhY2hlRGlyID0gcGF0aC5qb2luKGJhc2VEaXIsICcuZG9sbGhvdXNlbWNwJywgJ2NhY2hlJyk7XG4gICAgdGhpcy5jYWNoZUZpbGUgPSBwYXRoLmpvaW4odGhpcy5jYWNoZURpciwgJ2NvbGxlY3Rpb24tY2FjaGUuanNvbicpO1xuICB9XG4gIFxuICAvKipcbiAgICogSW5pdGlhbGl6ZSBjYWNoZSBkaXJlY3RvcnlcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgZW5zdXJlQ2FjaGVEaXIoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IGZzLm1rZGlyKHRoaXMuY2FjaGVEaXIsIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBsb2dnZXIuZXJyb3IoYEZhaWxlZCB0byBjcmVhdGUgY2FjaGUgZGlyZWN0b3J5OiAke2Vycm9yfWApO1xuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfVxuICB9XG4gIFxuICAvKipcbiAgICogTG9hZCBjb2xsZWN0aW9uIGRhdGEgZnJvbSBwZXJzaXN0ZW50IGNhY2hlXG4gICAqL1xuICBhc3luYyBsb2FkQ2FjaGUoKTogUHJvbWlzZTxDb2xsZWN0aW9uQ2FjaGVFbnRyeSB8IG51bGw+IHtcbiAgICB0cnkge1xuICAgICAgLy8gVmFsaWRhdGUgY2FjaGUgZmlsZSBwYXRoIChiYXNpYyBzZWN1cml0eSBjaGVjaylcbiAgICAgIGlmICh0aGlzLmNhY2hlRmlsZS5pbmNsdWRlcygnLi4nKSB8fCB0aGlzLmNhY2hlRmlsZS5pbmNsdWRlcygnXFwwJykpIHtcbiAgICAgICAgLy8gU0VDVVJJVFkgRklYOiBBZGQgYXVkaXQgbG9nZ2luZyBmb3IgcGF0aCB0cmF2ZXJzYWwgYXR0ZW1wdCBkZXRlY3Rpb25cbiAgICAgICAgU2VjdXJpdHlNb25pdG9yLmxvZ1NlY3VyaXR5RXZlbnQoe1xuICAgICAgICAgIHR5cGU6ICdQQVRIX1RSQVZFUlNBTF9BVFRFTVBUJyxcbiAgICAgICAgICBzZXZlcml0eTogJ0hJR0gnLFxuICAgICAgICAgIHNvdXJjZTogJ0NvbGxlY3Rpb25DYWNoZS5sb2FkQ2FjaGUnLFxuICAgICAgICAgIGRldGFpbHM6IGBQb3RlbnRpYWwgcGF0aCB0cmF2ZXJzYWwgYXR0ZW1wdCBkZXRlY3RlZCBpbiBjYWNoZSBmaWxlIHBhdGg6ICR7dGhpcy5jYWNoZUZpbGUuc3Vic3RyaW5nKDAsIDEwMCl9YFxuICAgICAgICB9KTtcbiAgICAgICAgbG9nZ2VyLndhcm4oJ0ludmFsaWQgY2FjaGUgZmlsZSBwYXRoLCBza2lwcGluZyBjYWNoZSBsb2FkJyk7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgICAgXG4gICAgICBjb25zdCBkYXRhID0gYXdhaXQgZnMucmVhZEZpbGUodGhpcy5jYWNoZUZpbGUsICd1dGY4Jyk7XG4gICAgICBjb25zdCBjYWNoZTogQ29sbGVjdGlvbkNhY2hlRW50cnkgPSBKU09OLnBhcnNlKGRhdGEpO1xuICAgICAgXG4gICAgICAvLyBDaGVjayBpZiBjYWNoZSBpcyBleHBpcmVkXG4gICAgICBpZiAoRGF0ZS5ub3coKSAtIGNhY2hlLnRpbWVzdGFtcCA+IHRoaXMuQ0FDSEVfVFRMX01TKSB7XG4gICAgICAgIGxvZ2dlci5kZWJ1ZygnQ29sbGVjdGlvbiBjYWNoZSBleHBpcmVkLCB3aWxsIHJlZnJlc2ggZnJvbSBHaXRIdWInKTtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG4gICAgICBcbiAgICAgIGxvZ2dlci5kZWJ1ZyhgTG9hZGVkICR7Y2FjaGUuaXRlbXMubGVuZ3RofSBpdGVtcyBmcm9tIGNvbGxlY3Rpb24gY2FjaGVgKTtcbiAgICAgIHJldHVybiBjYWNoZTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgaWYgKChlcnJvciBhcyBhbnkpLmNvZGUgIT09ICdFTk9FTlQnKSB7XG4gICAgICAgIGxvZ2dlci5kZWJ1ZyhgRmFpbGVkIHRvIGxvYWQgY29sbGVjdGlvbiBjYWNoZTogJHtlcnJvcn1gKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgfVxuICBcbiAgLyoqXG4gICAqIFNhdmUgY29sbGVjdGlvbiBkYXRhIHRvIHBlcnNpc3RlbnQgY2FjaGVcbiAgICovXG4gIGFzeW5jIHNhdmVDYWNoZShpdGVtczogQ29sbGVjdGlvbkl0ZW1bXSwgZXRhZz86IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLmVuc3VyZUNhY2hlRGlyKCk7XG4gICAgICBcbiAgICAgIGNvbnN0IGNhY2hlRW50cnk6IENvbGxlY3Rpb25DYWNoZUVudHJ5ID0ge1xuICAgICAgICBpdGVtcyxcbiAgICAgICAgdGltZXN0YW1wOiBEYXRlLm5vdygpLFxuICAgICAgICBldGFnXG4gICAgICB9O1xuICAgICAgXG4gICAgICBjb25zdCBkYXRhID0gSlNPTi5zdHJpbmdpZnkoY2FjaGVFbnRyeSwgbnVsbCwgMik7XG4gICAgICBhd2FpdCBmcy53cml0ZUZpbGUodGhpcy5jYWNoZUZpbGUsIGRhdGEsICd1dGY4Jyk7XG4gICAgICBcbiAgICAgIGxvZ2dlci5kZWJ1ZyhgU2F2ZWQgJHtpdGVtcy5sZW5ndGh9IGl0ZW1zIHRvIGNvbGxlY3Rpb24gY2FjaGVgKTtcbiAgICAgIFxuICAgICAgLy8gU0VDVVJJVFkgRklYOiBBZGQgYXVkaXQgbG9nZ2luZyBmb3IgY2FjaGUgd3JpdGUgb3BlcmF0aW9uc1xuICAgICAgbG9nZ2VyLmRlYnVnKCdTZWN1cml0eSBhdWRpdDogQ2FjaGUgd3JpdGUgb3BlcmF0aW9uIGNvbXBsZXRlZCBzdWNjZXNzZnVsbHknKTtcbiAgICAgIFxuICAgICAgLy8gTG9nIG9wZXJhdGlvbiBjb21wbGV0ZWQgc3VjY2Vzc2Z1bGx5XG4gICAgICBsb2dnZXIuZGVidWcoYENhY2hlIGZpbGUgb3BlcmF0aW9uIGNvbXBsZXRlZCB3aXRoICR7aXRlbXMubGVuZ3RofSBpdGVtc2ApO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBsb2dnZXIuZXJyb3IoYEZhaWxlZCB0byBzYXZlIGNvbGxlY3Rpb24gY2FjaGU6ICR7ZXJyb3J9YCk7XG4gICAgICAvLyBEb24ndCB0aHJvdyAtIGNhY2hpbmcgZmFpbHVyZXMgc2hvdWxkbid0IGJyZWFrIGZ1bmN0aW9uYWxpdHlcbiAgICB9XG4gIH1cbiAgXG4gIC8qKlxuICAgKiBTZWFyY2ggY2FjaGVkIGNvbGxlY3Rpb24gaXRlbXMgd2l0aCBmdXp6eSBtYXRjaGluZ1xuICAgKi9cbiAgYXN5bmMgc2VhcmNoQ2FjaGUocXVlcnk6IHN0cmluZyk6IFByb21pc2U8Q29sbGVjdGlvbkl0ZW1bXT4ge1xuICAgIGNvbnN0IGNhY2hlID0gYXdhaXQgdGhpcy5sb2FkQ2FjaGUoKTtcbiAgICBpZiAoIWNhY2hlKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuICAgIFxuICAgIGNvbnN0IG5vcm1hbGl6ZWRRdWVyeSA9IHRoaXMubm9ybWFsaXplU2VhcmNoVGVybShxdWVyeSk7XG4gICAgcmV0dXJuIGNhY2hlLml0ZW1zLmZpbHRlcihpdGVtID0+IHtcbiAgICAgIC8vIFNlYXJjaCBpbiBmaWxlbmFtZSBhbmQgcGF0aCB3aXRoIG5vcm1hbGl6YXRpb25cbiAgICAgIGNvbnN0IG5vcm1hbGl6ZWROYW1lID0gdGhpcy5ub3JtYWxpemVTZWFyY2hUZXJtKGl0ZW0ubmFtZSk7XG4gICAgICBjb25zdCBub3JtYWxpemVkUGF0aCA9IHRoaXMubm9ybWFsaXplU2VhcmNoVGVybShpdGVtLnBhdGgpO1xuICAgICAgXG4gICAgICByZXR1cm4gbm9ybWFsaXplZE5hbWUuaW5jbHVkZXMobm9ybWFsaXplZFF1ZXJ5KSB8fCBcbiAgICAgICAgICAgICBub3JtYWxpemVkUGF0aC5pbmNsdWRlcyhub3JtYWxpemVkUXVlcnkpIHx8XG4gICAgICAgICAgICAgKGl0ZW0uY29udGVudCAmJiB0aGlzLm5vcm1hbGl6ZVNlYXJjaFRlcm0oaXRlbS5jb250ZW50KS5pbmNsdWRlcyhub3JtYWxpemVkUXVlcnkpKTtcbiAgICB9KTtcbiAgfVxuICBcbiAgLyoqXG4gICAqIE5vcm1hbGl6ZSBzZWFyY2ggdGVybXMgZm9yIGJldHRlciBtYXRjaGluZyAoaGFuZGxlcyBzcGFjZXMsIGRhc2hlcywgZXRjLilcbiAgICovXG4gIHByaXZhdGUgbm9ybWFsaXplU2VhcmNoVGVybSh0ZXJtOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHJldHVybiB0ZXJtLnRvTG93ZXJDYXNlKClcbiAgICAgIC5yZXBsYWNlKC9bLV9cXHNdKy9nLCAnICcpICAvLyBDb252ZXJ0IGRhc2hlcywgdW5kZXJzY29yZXMgdG8gc3BhY2VzXG4gICAgICAucmVwbGFjZSgvXFwubWQkLywgJycpICAgICAgIC8vIFJlbW92ZSAubWQgZXh0ZW5zaW9uXG4gICAgICAudHJpbSgpO1xuICB9XG4gIFxuICAvKipcbiAgICogR2V0IGNhY2hlZCBjb2xsZWN0aW9uIGl0ZW1zIGJ5IHR5cGUvcGF0aFxuICAgKi9cbiAgYXN5bmMgZ2V0SXRlbXNCeVBhdGgocGF0aFByZWZpeDogc3RyaW5nKTogUHJvbWlzZTxDb2xsZWN0aW9uSXRlbVtdPiB7XG4gICAgY29uc3QgY2FjaGUgPSBhd2FpdCB0aGlzLmxvYWRDYWNoZSgpO1xuICAgIGlmICghY2FjaGUpIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG4gICAgXG4gICAgcmV0dXJuIGNhY2hlLml0ZW1zLmZpbHRlcihpdGVtID0+IGl0ZW0ucGF0aC5zdGFydHNXaXRoKHBhdGhQcmVmaXgpKTtcbiAgfVxuICBcbiAgLyoqXG4gICAqIENoZWNrIGlmIGNhY2hlIGV4aXN0cyBhbmQgaXMgdmFsaWRcbiAgICovXG4gIGFzeW5jIGlzQ2FjaGVWYWxpZCgpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBjb25zdCBjYWNoZSA9IGF3YWl0IHRoaXMubG9hZENhY2hlKCk7XG4gICAgcmV0dXJuIGNhY2hlICE9PSBudWxsO1xuICB9XG4gIFxuICAvKipcbiAgICogQ2xlYXIgdGhlIGNhY2hlXG4gICAqL1xuICBhc3luYyBjbGVhckNhY2hlKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCBmcy51bmxpbmsodGhpcy5jYWNoZUZpbGUpO1xuICAgICAgbG9nZ2VyLmRlYnVnKCdDb2xsZWN0aW9uIGNhY2hlIGNsZWFyZWQnKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgaWYgKChlcnJvciBhcyBhbnkpLmNvZGUgIT09ICdFTk9FTlQnKSB7XG4gICAgICAgIGxvZ2dlci5kZWJ1ZyhgRmFpbGVkIHRvIGNsZWFyIGNvbGxlY3Rpb24gY2FjaGU6ICR7ZXJyb3J9YCk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIFxuICAvKipcbiAgICogR2V0IGNhY2hlIHN0YXRzIGZvciBkZWJ1Z2dpbmdcbiAgICovXG4gIGFzeW5jIGdldENhY2hlU3RhdHMoKTogUHJvbWlzZTx7IGl0ZW1Db3VudDogbnVtYmVyOyBjYWNoZUFnZTogbnVtYmVyOyBpc1ZhbGlkOiBib29sZWFuIH0+IHtcbiAgICBjb25zdCBjYWNoZSA9IGF3YWl0IHRoaXMubG9hZENhY2hlKCk7XG4gICAgaWYgKCFjYWNoZSkge1xuICAgICAgcmV0dXJuIHsgaXRlbUNvdW50OiAwLCBjYWNoZUFnZTogMCwgaXNWYWxpZDogZmFsc2UgfTtcbiAgICB9XG4gICAgXG4gICAgcmV0dXJuIHtcbiAgICAgIGl0ZW1Db3VudDogY2FjaGUuaXRlbXMubGVuZ3RoLFxuICAgICAgY2FjaGVBZ2U6IERhdGUubm93KCkgLSBjYWNoZS50aW1lc3RhbXAsXG4gICAgICBpc1ZhbGlkOiBEYXRlLm5vdygpIC0gY2FjaGUudGltZXN0YW1wIDw9IHRoaXMuQ0FDSEVfVFRMX01TXG4gICAgfTtcbiAgfVxufSJdfQ==
|
|
172
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQ29sbGVjdGlvbkNhY2hlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NhY2hlL0NvbGxlY3Rpb25DYWNoZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7R0FFRztBQUVILE9BQU8sS0FBSyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ2xDLE9BQU8sS0FBSyxJQUFJLE1BQU0sTUFBTSxDQUFDO0FBQzdCLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUU1QyxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFnQmpFOztHQUVHO0FBQ0gsTUFBTSxPQUFPLGVBQWU7SUFDbEIsUUFBUSxDQUFTO0lBQ2pCLFNBQVMsQ0FBUztJQUNULFlBQVksR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUMsQ0FBQyxnQ0FBZ0M7SUFFckYsWUFBWSxPQUFnQjtRQUMxQiwrRUFBK0U7UUFDL0UsTUFBTSxXQUFXLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxtQkFBbUIsQ0FBQztRQUNwRCxJQUFJLFdBQVcsRUFBRSxDQUFDO1lBQ2hCLElBQUksQ0FBQyxRQUFRLEdBQUcsV0FBVyxDQUFDO1lBQzVCLE1BQU0sQ0FBQyxLQUFLLENBQUMsdURBQXVELElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDO1FBQ3ZGLENBQUM7YUFBTSxDQUFDO1lBQ04sTUFBTSxjQUFjLEdBQUcsT0FBTyxJQUFJLE9BQU8sQ0FBQyxHQUFHLEVBQUUsQ0FBQztZQUNoRCxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsY0FBYyxFQUFFLGVBQWUsRUFBRSxPQUFPLENBQUMsQ0FBQztZQUNwRSxNQUFNLENBQUMsS0FBSyxDQUFDLG1EQUFtRCxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQztRQUNuRixDQUFDO1FBQ0QsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENB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QUcsTUFBTSxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7UUFDckMsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ1gsT0FBTyxFQUFFLFNBQVMsRUFBRSxDQUFDLEVBQUUsUUFBUSxFQUFFLENBQUMsRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLENBQUM7UUFDdkQsQ0FBQztRQUVELE9BQU87WUFDTCxTQUFTLEVBQUUsS0FBSyxDQUFDLEtBQUssQ0FBQyxNQUFNO1lBQzdCLFFBQVEsRUFBRSxJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsS0FBSyxDQUFDLFNBQVM7WUFDdEMsT0FBTyxFQUFFLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxLQUFLLENBQUMsU0FBUyxJQUFJLElBQUksQ0FBQyxZQUFZO1NBQzNELENBQUM7SUFDSixDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFBlcnNpc3RlbnQgY2FjaGUgZm9yIGNvbGxlY3Rpb24gZGF0YSB0byBzdXBwb3J0IG9mZmxpbmUvYW5vbnltb3VzIGJyb3dzaW5nXG4gKi9cblxuaW1wb3J0ICogYXMgZnMgZnJvbSAnZnMvcHJvbWlzZXMnO1xuaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCB7IGxvZ2dlciB9IGZyb20gJy4uL3V0aWxzL2xvZ2dlci5qcyc7XG5pbXBvcnQgeyBQYXRoVmFsaWRhdG9yIH0gZnJvbSAnLi4vc2VjdXJpdHkvcGF0aFZhbGlkYXRvci5qcyc7XG5pbXBvcnQgeyBTZWN1cml0eU1vbml0b3IgfSBmcm9tICcuLi9zZWN1cml0eS9zZWN1cml0eU1vbml0b3IuanMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIENvbGxlY3Rpb25JdGVtIHtcbiAgbmFtZTogc3RyaW5nO1xuICBwYXRoOiBzdHJpbmc7XG4gIHNoYTogc3RyaW5nO1xuICBjb250ZW50Pzogc3RyaW5nO1xuICBsYXN0X21vZGlmaWVkPzogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIENvbGxlY3Rpb25DYWNoZUVudHJ5IHtcbiAgaXRlbXM6IENvbGxlY3Rpb25JdGVtW107XG4gIHRpbWVzdGFtcDogbnVtYmVyO1xuICBldGFnPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIFBlcnNpc3RlbnQgY2FjaGUgZm9yIGNvbGxlY3Rpb24gZGF0YSB0aGF0IHN1cHBvcnRzIG9mZmxpbmUgYnJvd3NpbmdcbiAqL1xuZXhwb3J0IGNsYXNzIENvbGxlY3Rpb25DYWNoZSB7XG4gIHByaXZhdGUgY2FjaGVEaXI6IHN0cmluZztcbiAgcHJpdmF0ZSBjYWNoZUZpbGU6IHN0cmluZztcbiAgcHJpdmF0ZSByZWFkb25seSBDQUNIRV9UVExfTVMgPSAyNCAqIDYwICogNjAgKiAxMDAwOyAvLyAyNCBob3VycyBmb3IgY29sbGVjdGlvbiBjYWNoZVxuICBcbiAgY29uc3RydWN0b3IoYmFzZURpcj86IHN0cmluZykge1xuICAgIC8vIFVzZSBlbnZpcm9ubWVudCB2YXJpYWJsZSBpZiBzZXQsIG90aGVyd2lzZSBmYWxsIGJhY2sgdG8gcGFyYW1ldGVyIG9yIGRlZmF1bHRcbiAgICBjb25zdCBlbnZDYWNoZURpciA9IHByb2Nlc3MuZW52LkRPTExIT1VTRV9DQUNIRV9ESVI7XG4gICAgaWYgKGVudkNhY2hlRGlyKSB7XG4gICAgICB0aGlzLmNhY2hlRGlyID0gZW52Q2FjaGVEaXI7XG4gICAgICBsb2dnZXIuZGVidWcoYENvbGxlY3Rpb25DYWNoZTogVXNpbmcgZW52aXJvbm1lbnQgY2FjaGUgZGlyZWN0b3J5OiAke3RoaXMuY2FjaGVEaXJ9YCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IGRlZmF1bHRCYXNlRGlyID0gYmFzZURpciB8fCBwcm9jZXNzLmN3ZCgpO1xuICAgICAgdGhpcy5jYWNoZURpciA9IHBhdGguam9pbihkZWZhdWx0QmFzZURpciwgJy5kb2xsaG91c2VtY3AnLCAnY2FjaGUnKTtcbiAgICAgIGxvZ2dlci5kZWJ1ZyhgQ29sbGVjdGlvbkNhY2hlOiBVc2luZyBkZWZhdWx0IGNhY2hlIGRpcmVjdG9yeTogJHt0aGlzLmNhY2hlRGlyfWApO1xuICAgIH1cbiAgICB0aGlzLmNhY2hlRmlsZSA9IHBhdGguam9pbih0aGlzLmNhY2hlRGlyLCAnY29sbGVjdGlvbi1jYWNoZS5qc29uJyk7XG4gIH1cbiAgXG4gIC8qKlxuICAgKiBJbml0aWFsaXplIGNhY2hlIGRpcmVjdG9yeVxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBlbnN1cmVDYWNoZURpcigpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgZnMubWtkaXIodGhpcy5jYWNoZURpciwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ2dlci5lcnJvcihgRmFpbGVkIHRvIGNyZWF0ZSBjYWNoZSBkaXJlY3Rvcnk6ICR7ZXJyb3J9YCk7XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG4gIH1cbiAgXG4gIC8qKlxuICAgKiBMb2FkIGNvbGxlY3Rpb24gZGF0YSBmcm9tIHBlcnNpc3RlbnQgY2FjaGVcbiAgICovXG4gIGFzeW5jIGxvYWRDYWNoZSgpOiBQcm9taXNlPENvbGxlY3Rpb25DYWNoZUVudHJ5IHwgbnVsbD4ge1xuICAgIHRyeSB7XG4gICAgICAvLyBWYWxpZGF0ZSBjYWNoZSBmaWxlIHBhdGggKGJhc2ljIHNlY3VyaXR5IGNoZWNrKVxuICAgICAgaWYgKHRoaXMuY2FjaGVGaWxlLmluY2x1ZGVzKCcuLicpIHx8IHRoaXMuY2FjaGVGaWxlLmluY2x1ZGVzKCdcXDAnKSkge1xuICAgICAgICAvLyBTRUNVUklUWSBGSVg6IEFkZCBhdWRpdCBsb2dnaW5nIGZvciBwYXRoIHRyYXZlcnNhbCBhdHRlbXB0IGRldGVjdGlvblxuICAgICAgICBTZWN1cml0eU1vbml0b3IubG9nU2VjdXJpdHlFdmVudCh7XG4gICAgICAgICAgdHlwZTogJ1BBVEhfVFJBVkVSU0FMX0FUVEVNUFQnLFxuICAgICAgICAgIHNldmVyaXR5OiAnSElHSCcsXG4gICAgICAgICAgc291cmNlOiAnQ29sbGVjdGlvbkNhY2hlLmxvYWRDYWNoZScsXG4gICAgICAgICAgZGV0YWlsczogYFBvdGVudGlhbCBwYXRoIHRyYXZlcnNhbCBhdHRlbXB0IGRldGVjdGVkIGluIGNhY2hlIGZpbGUgcGF0aDogJHt0aGlzLmNhY2hlRmlsZS5zdWJzdHJpbmcoMCwgMTAwKX1gXG4gICAgICAgIH0pO1xuICAgICAgICBsb2dnZXIud2FybignSW52YWxpZCBjYWNoZSBmaWxlIHBhdGgsIHNraXBwaW5nIGNhY2hlIGxvYWQnKTtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG4gICAgICBcbiAgICAgIGNvbnN0IGRhdGEgPSBhd2FpdCBmcy5yZWFkRmlsZSh0aGlzLmNhY2hlRmlsZSwgJ3V0ZjgnKTtcbiAgICAgIGNvbnN0IGNhY2hlOiBDb2xsZWN0aW9uQ2FjaGVFbnRyeSA9IEpTT04ucGFyc2UoZGF0YSk7XG4gICAgICBcbiAgICAgIC8vIENoZWNrIGlmIGNhY2hlIGlzIGV4cGlyZWRcbiAgICAgIGlmIChEYXRlLm5vdygpIC0gY2FjaGUudGltZXN0YW1wID4gdGhpcy5DQUNIRV9UVExfTVMpIHtcbiAgICAgICAgbG9nZ2VyLmRlYnVnKCdDb2xsZWN0aW9uIGNhY2hlIGV4cGlyZWQsIHdpbGwgcmVmcmVzaCBmcm9tIEdpdEh1YicpO1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICAgIFxuICAgICAgbG9nZ2VyLmRlYnVnKGBMb2FkZWQgJHtjYWNoZS5pdGVtcy5sZW5ndGh9IGl0ZW1zIGZyb20gY29sbGVjdGlvbiBjYWNoZWApO1xuICAgICAgcmV0dXJuIGNhY2hlO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBpZiAoKGVycm9yIGFzIGFueSkuY29kZSAhPT0gJ0VOT0VOVCcpIHtcbiAgICAgICAgbG9nZ2VyLmRlYnVnKGBGYWlsZWQgdG8gbG9hZCBjb2xsZWN0aW9uIGNhY2hlOiAke2Vycm9yfWApO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9XG4gIFxuICAvKipcbiAgICogU2F2ZSBjb2xsZWN0aW9uIGRhdGEgdG8gcGVyc2lzdGVudCBjYWNoZVxuICAgKi9cbiAgYXN5bmMgc2F2ZUNhY2hlKGl0ZW1zOiBDb2xsZWN0aW9uSXRlbVtdLCBldGFnPzogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMuZW5zdXJlQ2FjaGVEaXIoKTtcbiAgICAgIFxuICAgICAgY29uc3QgY2FjaGVFbnRyeTogQ29sbGVjdGlvbkNhY2hlRW50cnkgPSB7XG4gICAgICAgIGl0ZW1zLFxuICAgICAgICB0aW1lc3RhbXA6IERhdGUubm93KCksXG4gICAgICAgIGV0YWdcbiAgICAgIH07XG4gICAgICBcbiAgICAgIGNvbnN0IGRhdGEgPSBKU09OLnN0cmluZ2lmeShjYWNoZUVudHJ5LCBudWxsLCAyKTtcbiAgICAgIGF3YWl0IGZzLndyaXRlRmlsZSh0aGlzLmNhY2hlRmlsZSwgZGF0YSwgJ3V0ZjgnKTtcbiAgICAgIFxuICAgICAgbG9nZ2VyLmRlYnVnKGBTYXZlZCAke2l0ZW1zLmxlbmd0aH0gaXRlbXMgdG8gY29sbGVjdGlvbiBjYWNoZWApO1xuICAgICAgXG4gICAgICAvLyBTRUNVUklUWSBGSVg6IEFkZCBhdWRpdCBsb2dnaW5nIGZvciBjYWNoZSB3cml0ZSBvcGVyYXRpb25zXG4gICAgICBsb2dnZXIuZGVidWcoJ1NlY3VyaXR5IGF1ZGl0OiBDYWNoZSB3cml0ZSBvcGVyYXRpb24gY29tcGxldGVkIHN1Y2Nlc3NmdWxseScpO1xuICAgICAgXG4gICAgICAvLyBMb2cgb3BlcmF0aW9uIGNvbXBsZXRlZCBzdWNjZXNzZnVsbHlcbiAgICAgIGxvZ2dlci5kZWJ1ZyhgQ2FjaGUgZmlsZSBvcGVyYXRpb24gY29tcGxldGVkIHdpdGggJHtpdGVtcy5sZW5ndGh9IGl0ZW1zYCk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ2dlci5lcnJvcihgRmFpbGVkIHRvIHNhdmUgY29sbGVjdGlvbiBjYWNoZTogJHtlcnJvcn1gKTtcbiAgICAgIC8vIERvbid0IHRocm93IC0gY2FjaGluZyBmYWlsdXJlcyBzaG91bGRuJ3QgYnJlYWsgZnVuY3Rpb25hbGl0eVxuICAgIH1cbiAgfVxuICBcbiAgLyoqXG4gICAqIFNlYXJjaCBjYWNoZWQgY29sbGVjdGlvbiBpdGVtcyB3aXRoIGZ1enp5IG1hdGNoaW5nXG4gICAqL1xuICBhc3luYyBzZWFyY2hDYWNoZShxdWVyeTogc3RyaW5nKTogUHJvbWlzZTxDb2xsZWN0aW9uSXRlbVtdPiB7XG4gICAgY29uc3QgY2FjaGUgPSBhd2FpdCB0aGlzLmxvYWRDYWNoZSgpO1xuICAgIGlmICghY2FjaGUpIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG4gICAgXG4gICAgY29uc3Qgbm9ybWFsaXplZFF1ZXJ5ID0gdGhpcy5ub3JtYWxpemVTZWFyY2hUZXJtKHF1ZXJ5KTtcbiAgICByZXR1cm4gY2FjaGUuaXRlbXMuZmlsdGVyKGl0ZW0gPT4ge1xuICAgICAgLy8gU2VhcmNoIGluIGZpbGVuYW1lIGFuZCBwYXRoIHdpdGggbm9ybWFsaXphdGlvblxuICAgICAgY29uc3Qgbm9ybWFsaXplZE5hbWUgPSB0aGlzLm5vcm1hbGl6ZVNlYXJjaFRlcm0oaXRlbS5uYW1lKTtcbiAgICAgIGNvbnN0IG5vcm1hbGl6ZWRQYXRoID0gdGhpcy5ub3JtYWxpemVTZWFyY2hUZXJtKGl0ZW0ucGF0aCk7XG4gICAgICBcbiAgICAgIHJldHVybiBub3JtYWxpemVkTmFtZS5pbmNsdWRlcyhub3JtYWxpemVkUXVlcnkpIHx8IFxuICAgICAgICAgICAgIG5vcm1hbGl6ZWRQYXRoLmluY2x1ZGVzKG5vcm1hbGl6ZWRRdWVyeSkgfHxcbiAgICAgICAgICAgICAoaXRlbS5jb250ZW50ICYmIHRoaXMubm9ybWFsaXplU2VhcmNoVGVybShpdGVtLmNvbnRlbnQpLmluY2x1ZGVzKG5vcm1hbGl6ZWRRdWVyeSkpO1xuICAgIH0pO1xuICB9XG4gIFxuICAvKipcbiAgICogTm9ybWFsaXplIHNlYXJjaCB0ZXJtcyBmb3IgYmV0dGVyIG1hdGNoaW5nIChoYW5kbGVzIHNwYWNlcywgZGFzaGVzLCBldGMuKVxuICAgKi9cbiAgcHJpdmF0ZSBub3JtYWxpemVTZWFyY2hUZXJtKHRlcm06IHN0cmluZyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRlcm0udG9Mb3dlckNhc2UoKVxuICAgICAgLnJlcGxhY2UoL1stX1xcc10rL2csICcgJykgIC8vIENvbnZlcnQgZGFzaGVzLCB1bmRlcnNjb3JlcyB0byBzcGFjZXNcbiAgICAgIC5yZXBsYWNlKC9cXC5tZCQvLCAnJykgICAgICAgLy8gUmVtb3ZlIC5tZCBleHRlbnNpb25cbiAgICAgIC50cmltKCk7XG4gIH1cbiAgXG4gIC8qKlxuICAgKiBHZXQgY2FjaGVkIGNvbGxlY3Rpb24gaXRlbXMgYnkgdHlwZS9wYXRoXG4gICAqL1xuICBhc3luYyBnZXRJdGVtc0J5UGF0aChwYXRoUHJlZml4OiBzdHJpbmcpOiBQcm9taXNlPENvbGxlY3Rpb25JdGVtW10+IHtcbiAgICBjb25zdCBjYWNoZSA9IGF3YWl0IHRoaXMubG9hZENhY2hlKCk7XG4gICAgaWYgKCFjYWNoZSkge1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cbiAgICBcbiAgICByZXR1cm4gY2FjaGUuaXRlbXMuZmlsdGVyKGl0ZW0gPT4gaXRlbS5wYXRoLnN0YXJ0c1dpdGgocGF0aFByZWZpeCkpO1xuICB9XG4gIFxuICAvKipcbiAgICogQ2hlY2sgaWYgY2FjaGUgZXhpc3RzIGFuZCBpcyB2YWxpZFxuICAgKi9cbiAgYXN5bmMgaXNDYWNoZVZhbGlkKCk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGNvbnN0IGNhY2hlID0gYXdhaXQgdGhpcy5sb2FkQ2FjaGUoKTtcbiAgICByZXR1cm4gY2FjaGUgIT09IG51bGw7XG4gIH1cbiAgXG4gIC8qKlxuICAgKiBDbGVhciB0aGUgY2FjaGVcbiAgICovXG4gIGFzeW5jIGNsZWFyQ2FjaGUoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IGZzLnVubGluayh0aGlzLmNhY2hlRmlsZSk7XG4gICAgICBsb2dnZXIuZGVidWcoJ0NvbGxlY3Rpb24gY2FjaGUgY2xlYXJlZCcpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBpZiAoKGVycm9yIGFzIGFueSkuY29kZSAhPT0gJ0VOT0VOVCcpIHtcbiAgICAgICAgbG9nZ2VyLmRlYnVnKGBGYWlsZWQgdG8gY2xlYXIgY29sbGVjdGlvbiBjYWNoZTogJHtlcnJvcn1gKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgXG4gIC8qKlxuICAgKiBHZXQgY2FjaGUgc3RhdHMgZm9yIGRlYnVnZ2luZ1xuICAgKi9cbiAgYXN5bmMgZ2V0Q2FjaGVTdGF0cygpOiBQcm9taXNlPHsgaXRlbUNvdW50OiBudW1iZXI7IGNhY2hlQWdlOiBudW1iZXI7IGlzVmFsaWQ6IGJvb2xlYW4gfT4ge1xuICAgIGNvbnN0IGNhY2hlID0gYXdhaXQgdGhpcy5sb2FkQ2FjaGUoKTtcbiAgICBpZiAoIWNhY2hlKSB7XG4gICAgICByZXR1cm4geyBpdGVtQ291bnQ6IDAsIGNhY2hlQWdlOiAwLCBpc1ZhbGlkOiBmYWxzZSB9O1xuICAgIH1cbiAgICBcbiAgICByZXR1cm4ge1xuICAgICAgaXRlbUNvdW50OiBjYWNoZS5pdGVtcy5sZW5ndGgsXG4gICAgICBjYWNoZUFnZTogRGF0ZS5ub3coKSAtIGNhY2hlLnRpbWVzdGFtcCxcbiAgICAgIGlzVmFsaWQ6IERhdGUubm93KCkgLSBjYWNoZS50aW1lc3RhbXAgPD0gdGhpcy5DQUNIRV9UVExfTVNcbiAgICB9O1xuICB9XG59Il19
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Smart cache for collection index with conditional fetching and performance optimization
|
|
3
|
+
*/
|
|
4
|
+
import { CollectionIndex } from '../types/collection.js';
|
|
5
|
+
import { GitHubClient } from '../collection/GitHubClient.js';
|
|
6
|
+
export declare class CollectionIndexCache {
|
|
7
|
+
private cache;
|
|
8
|
+
private readonly TTL;
|
|
9
|
+
private readonly INDEX_URL;
|
|
10
|
+
private cacheDir;
|
|
11
|
+
private cacheFile;
|
|
12
|
+
private githubClient;
|
|
13
|
+
private performanceMonitor;
|
|
14
|
+
private memoryCache;
|
|
15
|
+
private fetchPromise;
|
|
16
|
+
constructor(githubClient: GitHubClient, baseDir?: string);
|
|
17
|
+
/**
|
|
18
|
+
* Get the collection index with performance optimization and lazy loading
|
|
19
|
+
*/
|
|
20
|
+
getIndex(lazyLoad?: boolean): Promise<CollectionIndex>;
|
|
21
|
+
/**
|
|
22
|
+
* Check if current cache is valid (within TTL)
|
|
23
|
+
*/
|
|
24
|
+
private isValid;
|
|
25
|
+
/**
|
|
26
|
+
* Fetch fresh index from GitHub with conditional requests
|
|
27
|
+
*/
|
|
28
|
+
private fetchFresh;
|
|
29
|
+
/**
|
|
30
|
+
* Validate the structure of a collection index
|
|
31
|
+
*/
|
|
32
|
+
private validateIndexStructure;
|
|
33
|
+
/**
|
|
34
|
+
* Save cache to persistent storage
|
|
35
|
+
*/
|
|
36
|
+
private saveToDisk;
|
|
37
|
+
/**
|
|
38
|
+
* Load cache from persistent storage
|
|
39
|
+
*/
|
|
40
|
+
private loadFromDisk;
|
|
41
|
+
/**
|
|
42
|
+
* Ensure cache directory exists
|
|
43
|
+
*/
|
|
44
|
+
private ensureCacheDir;
|
|
45
|
+
/**
|
|
46
|
+
* Clear all cache data with performance monitoring
|
|
47
|
+
*/
|
|
48
|
+
clearCache(): Promise<void>;
|
|
49
|
+
/**
|
|
50
|
+
* Get comprehensive cache statistics for debugging and monitoring
|
|
51
|
+
*/
|
|
52
|
+
getCacheStats(): {
|
|
53
|
+
isValid: boolean;
|
|
54
|
+
age: number;
|
|
55
|
+
hasCache: boolean;
|
|
56
|
+
elements: number;
|
|
57
|
+
memoryCache: any;
|
|
58
|
+
performanceMetrics: any;
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Fetch fresh index with comprehensive fallback strategy
|
|
62
|
+
*/
|
|
63
|
+
private fetchFreshWithFallback;
|
|
64
|
+
/**
|
|
65
|
+
* Record performance metrics for cache operations
|
|
66
|
+
*/
|
|
67
|
+
private recordPerformanceMetrics;
|
|
68
|
+
/**
|
|
69
|
+
* Calculate cache hit rate (placeholder for future implementation)
|
|
70
|
+
*/
|
|
71
|
+
private calculateCacheHitRate;
|
|
72
|
+
/**
|
|
73
|
+
* Calculate average access time (placeholder for future implementation)
|
|
74
|
+
*/
|
|
75
|
+
private calculateAverageAccessTime;
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=CollectionIndexCache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CollectionIndexCache.d.ts","sourceRoot":"","sources":["../../src/cache/CollectionIndexCache.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,EAAE,eAAe,EAAe,MAAM,wBAAwB,CAAC;AAEtE,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAK7D,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,KAAK,CAA4B;IACzC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAkB;IACtC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAiG;IAC3H,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,kBAAkB,CAAqB;IAC/C,OAAO,CAAC,WAAW,CAAgB;IACnC,OAAO,CAAC,YAAY,CAAyC;gBAEjD,YAAY,EAAE,YAAY,EAAE,OAAO,GAAE,MAAsB;IAiBvE;;OAEG;IACG,QAAQ,CAAC,QAAQ,GAAE,OAAe,GAAG,OAAO,CAAC,eAAe,CAAC;IAiEnE;;OAEG;IACH,OAAO,CAAC,OAAO;IASf;;OAEG;YACW,UAAU;IAiExB;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAc9B;;OAEG;YACW,UAAU;IAmBxB;;OAEG;YACW,YAAY;IA4B1B;;OAEG;YACW,cAAc;IAS5B;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAwBjC;;OAEG;IACH,aAAa,IAAI;QACf,OAAO,EAAE,OAAO,CAAC;QACjB,GAAG,EAAE,MAAM,CAAC;QACZ,QAAQ,EAAE,OAAO,CAAC;QAClB,QAAQ,EAAE,MAAM,CAAC;QACjB,WAAW,EAAE,GAAG,CAAC;QACjB,kBAAkB,EAAE,GAAG,CAAC;KACzB;IA8BD;;OAEG;YACW,sBAAsB;IAuBpC;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAqBhC;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAK7B;;OAEG;IACH,OAAO,CAAC,0BAA0B;CAInC"}
|
|
@@ -0,0 +1,349 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Smart cache for collection index with conditional fetching and performance optimization
|
|
3
|
+
*/
|
|
4
|
+
import * as fs from 'fs/promises';
|
|
5
|
+
import * as path from 'path';
|
|
6
|
+
import { logger } from '../utils/logger.js';
|
|
7
|
+
import { SecurityMonitor } from '../security/securityMonitor.js';
|
|
8
|
+
import { CacheFactory } from './LRUCache.js';
|
|
9
|
+
import { PerformanceMonitor } from '../utils/PerformanceMonitor.js';
|
|
10
|
+
export class CollectionIndexCache {
|
|
11
|
+
cache = null;
|
|
12
|
+
TTL = 15 * 60 * 1000; // 15 minutes in milliseconds
|
|
13
|
+
INDEX_URL = 'https://raw.githubusercontent.com/DollhouseMCP/collection/main/public/collection-index.json';
|
|
14
|
+
cacheDir;
|
|
15
|
+
cacheFile;
|
|
16
|
+
githubClient;
|
|
17
|
+
performanceMonitor;
|
|
18
|
+
memoryCache;
|
|
19
|
+
fetchPromise = null; // Prevent concurrent fetches
|
|
20
|
+
constructor(githubClient, baseDir = process.cwd()) {
|
|
21
|
+
this.githubClient = githubClient;
|
|
22
|
+
this.cacheDir = path.join(baseDir, '.dollhousemcp', 'cache');
|
|
23
|
+
this.cacheFile = path.join(this.cacheDir, 'collection-index-cache.json');
|
|
24
|
+
this.performanceMonitor = PerformanceMonitor.getInstance();
|
|
25
|
+
// Initialize memory cache for frequently accessed data
|
|
26
|
+
this.memoryCache = CacheFactory.createAPICache({
|
|
27
|
+
maxSize: 50,
|
|
28
|
+
maxMemoryMB: 10,
|
|
29
|
+
ttlMs: 5 * 60 * 1000, // 5 minutes
|
|
30
|
+
onEviction: (key, value) => {
|
|
31
|
+
logger.debug('Collection memory cache eviction', { key });
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Get the collection index with performance optimization and lazy loading
|
|
37
|
+
*/
|
|
38
|
+
async getIndex(lazyLoad = false) {
|
|
39
|
+
const startTime = Date.now();
|
|
40
|
+
const memoryBefore = process.memoryUsage().heapUsed;
|
|
41
|
+
try {
|
|
42
|
+
// Check memory cache first for fastest access
|
|
43
|
+
const memoryCached = this.memoryCache.get('collection-index');
|
|
44
|
+
if (memoryCached && this.isValid()) {
|
|
45
|
+
logger.debug('Using memory cached collection index');
|
|
46
|
+
this.recordPerformanceMetrics(startTime, memoryBefore, 'memory-hit');
|
|
47
|
+
return memoryCached;
|
|
48
|
+
}
|
|
49
|
+
// Check if we have valid disk cached data
|
|
50
|
+
if (this.isValid()) {
|
|
51
|
+
logger.debug('Using valid disk cached collection index');
|
|
52
|
+
const result = this.cache.data;
|
|
53
|
+
this.memoryCache.set('collection-index', result);
|
|
54
|
+
this.recordPerformanceMetrics(startTime, memoryBefore, 'disk-hit');
|
|
55
|
+
return result;
|
|
56
|
+
}
|
|
57
|
+
// Prevent concurrent fetches
|
|
58
|
+
if (this.fetchPromise) {
|
|
59
|
+
logger.debug('Waiting for ongoing collection index fetch');
|
|
60
|
+
return await this.fetchPromise;
|
|
61
|
+
}
|
|
62
|
+
// Lazy loading: Only fetch if not in lazy mode or absolutely necessary
|
|
63
|
+
if (lazyLoad && this.cache?.data) {
|
|
64
|
+
logger.debug('Using stale cache in lazy load mode');
|
|
65
|
+
this.recordPerformanceMetrics(startTime, memoryBefore, 'lazy-stale');
|
|
66
|
+
return this.cache.data;
|
|
67
|
+
}
|
|
68
|
+
// Create fetch promise to prevent concurrent requests
|
|
69
|
+
this.fetchPromise = this.fetchFreshWithFallback();
|
|
70
|
+
try {
|
|
71
|
+
const result = await this.fetchPromise;
|
|
72
|
+
this.memoryCache.set('collection-index', result);
|
|
73
|
+
this.recordPerformanceMetrics(startTime, memoryBefore, 'fresh-fetch');
|
|
74
|
+
return result;
|
|
75
|
+
}
|
|
76
|
+
finally {
|
|
77
|
+
this.fetchPromise = null;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
catch (error) {
|
|
81
|
+
logger.error('Failed to get collection index:', error);
|
|
82
|
+
// Try loading from persistent cache as last resort
|
|
83
|
+
const persistentCache = await this.loadFromDisk();
|
|
84
|
+
if (persistentCache) {
|
|
85
|
+
logger.debug('Using persistent cache as last resort');
|
|
86
|
+
this.cache = persistentCache;
|
|
87
|
+
const result = persistentCache.data;
|
|
88
|
+
this.memoryCache.set('collection-index', result);
|
|
89
|
+
this.recordPerformanceMetrics(startTime, memoryBefore, 'disk-fallback');
|
|
90
|
+
return result;
|
|
91
|
+
}
|
|
92
|
+
throw error;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Check if current cache is valid (within TTL)
|
|
97
|
+
*/
|
|
98
|
+
isValid() {
|
|
99
|
+
if (!this.cache) {
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
const age = Date.now() - this.cache.fetchedAt.getTime();
|
|
103
|
+
return age < this.TTL;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Fetch fresh index from GitHub with conditional requests
|
|
107
|
+
*/
|
|
108
|
+
async fetchFresh() {
|
|
109
|
+
try {
|
|
110
|
+
// Build headers for conditional request
|
|
111
|
+
const headers = {
|
|
112
|
+
'Accept': 'application/json',
|
|
113
|
+
'User-Agent': 'DollhouseMCP/1.0'
|
|
114
|
+
};
|
|
115
|
+
// Add conditional headers if we have cache
|
|
116
|
+
if (this.cache?.etag) {
|
|
117
|
+
headers['If-None-Match'] = this.cache.etag;
|
|
118
|
+
}
|
|
119
|
+
if (this.cache?.lastModified) {
|
|
120
|
+
headers['If-Modified-Since'] = this.cache.lastModified;
|
|
121
|
+
}
|
|
122
|
+
// Use fetch directly for better control over conditional requests
|
|
123
|
+
const response = await fetch(this.INDEX_URL, { headers });
|
|
124
|
+
// 304 Not Modified - use cached data
|
|
125
|
+
if (response.status === 304) {
|
|
126
|
+
if (this.cache) {
|
|
127
|
+
// Update timestamp to extend cache validity
|
|
128
|
+
this.cache.fetchedAt = new Date();
|
|
129
|
+
await this.saveToDisk(this.cache);
|
|
130
|
+
logger.debug('Collection index not modified - refreshed cache timestamp');
|
|
131
|
+
return this.cache.data;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
if (!response.ok) {
|
|
135
|
+
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
136
|
+
}
|
|
137
|
+
const indexData = await response.json();
|
|
138
|
+
// Validate the index structure
|
|
139
|
+
if (!this.validateIndexStructure(indexData)) {
|
|
140
|
+
throw new Error('Invalid collection index structure received');
|
|
141
|
+
}
|
|
142
|
+
// Create new cache entry
|
|
143
|
+
const newCache = {
|
|
144
|
+
data: indexData,
|
|
145
|
+
fetchedAt: new Date(),
|
|
146
|
+
etag: response.headers.get('etag') || undefined,
|
|
147
|
+
lastModified: response.headers.get('last-modified') || undefined
|
|
148
|
+
};
|
|
149
|
+
this.cache = newCache;
|
|
150
|
+
// Save to persistent cache in background
|
|
151
|
+
this.saveToDisk(newCache).catch(error => {
|
|
152
|
+
logger.debug('Failed to save index cache to disk:', error);
|
|
153
|
+
});
|
|
154
|
+
logger.debug(`Fresh collection index fetched with ${indexData.total_elements} elements`);
|
|
155
|
+
return indexData;
|
|
156
|
+
}
|
|
157
|
+
catch (error) {
|
|
158
|
+
logger.debug('Failed to fetch fresh collection index:', error);
|
|
159
|
+
return null;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Validate the structure of a collection index
|
|
164
|
+
*/
|
|
165
|
+
validateIndexStructure(index) {
|
|
166
|
+
return (index &&
|
|
167
|
+
typeof index === 'object' &&
|
|
168
|
+
typeof index.version === 'string' &&
|
|
169
|
+
typeof index.generated === 'string' &&
|
|
170
|
+
typeof index.total_elements === 'number' &&
|
|
171
|
+
index.index &&
|
|
172
|
+
typeof index.index === 'object' &&
|
|
173
|
+
index.metadata &&
|
|
174
|
+
typeof index.metadata === 'object');
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Save cache to persistent storage
|
|
178
|
+
*/
|
|
179
|
+
async saveToDisk(cache) {
|
|
180
|
+
try {
|
|
181
|
+
await this.ensureCacheDir();
|
|
182
|
+
const cacheData = {
|
|
183
|
+
...cache,
|
|
184
|
+
fetchedAt: cache.fetchedAt.toISOString() // Serialize date
|
|
185
|
+
};
|
|
186
|
+
const data = JSON.stringify(cacheData, null, 2);
|
|
187
|
+
await fs.writeFile(this.cacheFile, data, 'utf8');
|
|
188
|
+
logger.debug('Collection index cache saved to disk');
|
|
189
|
+
}
|
|
190
|
+
catch (error) {
|
|
191
|
+
logger.debug('Failed to save collection index cache:', error);
|
|
192
|
+
// Don't throw - cache persistence failures shouldn't break functionality
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Load cache from persistent storage
|
|
197
|
+
*/
|
|
198
|
+
async loadFromDisk() {
|
|
199
|
+
try {
|
|
200
|
+
// Basic security check for path traversal
|
|
201
|
+
if (this.cacheFile.includes('..') || this.cacheFile.includes('\0')) {
|
|
202
|
+
SecurityMonitor.logSecurityEvent({
|
|
203
|
+
type: 'PATH_TRAVERSAL_ATTEMPT',
|
|
204
|
+
severity: 'HIGH',
|
|
205
|
+
source: 'CollectionIndexCache.loadFromDisk',
|
|
206
|
+
details: `Potential path traversal attempt detected: ${this.cacheFile.substring(0, 100)}`
|
|
207
|
+
});
|
|
208
|
+
return null;
|
|
209
|
+
}
|
|
210
|
+
const data = await fs.readFile(this.cacheFile, 'utf8');
|
|
211
|
+
const cacheData = JSON.parse(data);
|
|
212
|
+
return {
|
|
213
|
+
...cacheData,
|
|
214
|
+
fetchedAt: new Date(cacheData.fetchedAt) // Deserialize date
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
catch (error) {
|
|
218
|
+
if (error.code !== 'ENOENT') {
|
|
219
|
+
logger.debug('Failed to load collection index cache from disk:', error);
|
|
220
|
+
}
|
|
221
|
+
return null;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Ensure cache directory exists
|
|
226
|
+
*/
|
|
227
|
+
async ensureCacheDir() {
|
|
228
|
+
try {
|
|
229
|
+
await fs.mkdir(this.cacheDir, { recursive: true });
|
|
230
|
+
}
|
|
231
|
+
catch (error) {
|
|
232
|
+
logger.error('Failed to create cache directory:', error);
|
|
233
|
+
throw error;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Clear all cache data with performance monitoring
|
|
238
|
+
*/
|
|
239
|
+
async clearCache() {
|
|
240
|
+
const startTime = Date.now();
|
|
241
|
+
this.cache = null;
|
|
242
|
+
this.memoryCache.clear();
|
|
243
|
+
// Cancel any ongoing fetch
|
|
244
|
+
this.fetchPromise = null;
|
|
245
|
+
try {
|
|
246
|
+
await fs.unlink(this.cacheFile);
|
|
247
|
+
logger.debug('Collection index cache cleared from disk');
|
|
248
|
+
}
|
|
249
|
+
catch (error) {
|
|
250
|
+
if (error.code !== 'ENOENT') {
|
|
251
|
+
logger.debug('Failed to clear collection index cache:', error);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
logger.debug('Collection cache cleared', {
|
|
255
|
+
duration: Date.now() - startTime,
|
|
256
|
+
memoryFreed: this.memoryCache.getMemoryUsageMB()
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Get comprehensive cache statistics for debugging and monitoring
|
|
261
|
+
*/
|
|
262
|
+
getCacheStats() {
|
|
263
|
+
if (!this.cache) {
|
|
264
|
+
return {
|
|
265
|
+
isValid: false,
|
|
266
|
+
age: 0,
|
|
267
|
+
hasCache: false,
|
|
268
|
+
elements: 0,
|
|
269
|
+
memoryCache: this.memoryCache.getStats(),
|
|
270
|
+
performanceMetrics: null
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
const age = Date.now() - this.cache.fetchedAt.getTime();
|
|
274
|
+
return {
|
|
275
|
+
isValid: this.isValid(),
|
|
276
|
+
age,
|
|
277
|
+
hasCache: true,
|
|
278
|
+
elements: this.cache.data.total_elements,
|
|
279
|
+
memoryCache: this.memoryCache.getStats(),
|
|
280
|
+
performanceMetrics: {
|
|
281
|
+
cacheHitRate: this.calculateCacheHitRate(),
|
|
282
|
+
averageAccessTime: this.calculateAverageAccessTime()
|
|
283
|
+
}
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
// =====================================================
|
|
287
|
+
// PRIVATE HELPER METHODS FOR PERFORMANCE
|
|
288
|
+
// =====================================================
|
|
289
|
+
/**
|
|
290
|
+
* Fetch fresh index with comprehensive fallback strategy
|
|
291
|
+
*/
|
|
292
|
+
async fetchFreshWithFallback() {
|
|
293
|
+
try {
|
|
294
|
+
// Try to fetch fresh index
|
|
295
|
+
const freshIndex = await this.fetchFresh();
|
|
296
|
+
if (freshIndex) {
|
|
297
|
+
logger.debug('Collection index fetched successfully');
|
|
298
|
+
return freshIndex;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
catch (error) {
|
|
302
|
+
logger.warn('Fresh fetch failed, trying fallback', {
|
|
303
|
+
error: error instanceof Error ? error.message : String(error)
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
// Fall back to stale cache if available
|
|
307
|
+
if (this.cache?.data) {
|
|
308
|
+
logger.debug('Using stale cached collection index as fallback');
|
|
309
|
+
return this.cache.data;
|
|
310
|
+
}
|
|
311
|
+
throw new Error('No collection index available - fresh fetch failed and no cache exists');
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Record performance metrics for cache operations
|
|
315
|
+
*/
|
|
316
|
+
recordPerformanceMetrics(startTime, memoryBefore, operation) {
|
|
317
|
+
const duration = Date.now() - startTime;
|
|
318
|
+
const memoryAfter = process.memoryUsage().heapUsed;
|
|
319
|
+
logger.debug('Collection cache operation completed', {
|
|
320
|
+
operation,
|
|
321
|
+
duration,
|
|
322
|
+
memoryUsageMB: (memoryAfter - memoryBefore) / (1024 * 1024)
|
|
323
|
+
});
|
|
324
|
+
// Record cache performance metrics
|
|
325
|
+
this.performanceMonitor.recordCachePerformance('collectionIndex', {
|
|
326
|
+
hitRate: operation.includes('hit') ? 1 : 0,
|
|
327
|
+
avgHitTime: operation.includes('hit') ? duration : 0,
|
|
328
|
+
avgMissTime: operation.includes('hit') ? 0 : duration,
|
|
329
|
+
totalHits: operation.includes('hit') ? 1 : 0,
|
|
330
|
+
totalMisses: operation.includes('hit') ? 0 : 1,
|
|
331
|
+
evictions: 0
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* Calculate cache hit rate (placeholder for future implementation)
|
|
336
|
+
*/
|
|
337
|
+
calculateCacheHitRate() {
|
|
338
|
+
// This would be implemented with actual metrics tracking
|
|
339
|
+
return this.memoryCache.getStats().hitRate;
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* Calculate average access time (placeholder for future implementation)
|
|
343
|
+
*/
|
|
344
|
+
calculateAverageAccessTime() {
|
|
345
|
+
// This would be implemented with actual timing metrics
|
|
346
|
+
return 5; // Placeholder value
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQ29sbGVjdGlvbkluZGV4Q2FjaGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY2FjaGUvQ29sbGVjdGlvbkluZGV4Q2FjaGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0dBRUc7QUFFSCxPQUFPLEtBQUssRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUNsQyxPQUFPLEtBQUssSUFBSSxNQUFNLE1BQU0sQ0FBQztBQUU3QixPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFFNUMsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQ2pFLE9BQU8sRUFBWSxZQUFZLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDdkQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFFcEUsTUFBTSxPQUFPLG9CQUFvQjtJQUN2QixLQUFLLEdBQXVCLElBQUksQ0FBQztJQUN4QixHQUFHLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUMsQ0FBQyw2QkFBNkI7SUFDbkQsU0FBUyxHQUFHLDZGQUE2RixDQUFDO0lBQ25ILFFBQVEsQ0FBUztJQUNqQixTQUFTLENBQVM7SUFDbEIsWUFBWSxDQUFlO0lBQzNCLGtCQUFrQixDQUFxQjtJQUN2QyxXQUFXLENBQWdCO0lBQzNCLFlBQVksR0FBb0MsSUFBSSxDQUFDLENBQUMsNkJBQTZCO0lBRTNGLFlBQVksWUFBMEIsRUFBRSxVQUFrQixPQUFPLENBQUMsR0FBRyxFQUFFO1FBQ3JFLElBQUksQ0FBQyxZQUFZLEdBQUcsWUFBWSxDQUFDO1FBQ2pDLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsZUFBZSxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBQzdELElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLDZCQUE2QixDQUFDLENBQUM7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SyxxQkFBcUI7UUFDM0IseURBQXlEO1FBQ3pELE9BQU8sSUFBSSxDQUFDLFdBQVcsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxPQUFPLENBQUM7SUFDN0MsQ0FBQztJQUVEOztPQUVHO0lBQ0ssMEJBQTBCO1FBQ2hDLHVEQUF1RDtRQUN2RCxPQUFPLENBQUMsQ0FBQyxDQUFDLG9CQUFvQjtJQUNoQyxDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFNtYXJ0IGNhY2hlIGZvciBjb2xsZWN0aW9uIGluZGV4IHdpdGggY29uZGl0aW9uYWwgZmV0Y2hpbmcgYW5kIHBlcmZvcm1hbmNlIG9wdGltaXphdGlvblxuICovXG5cbmltcG9ydCAqIGFzIGZzIGZyb20gJ2ZzL3Byb21pc2VzJztcbmltcG9ydCAqIGFzIHBhdGggZnJvbSAncGF0aCc7XG5pbXBvcnQgeyBDb2xsZWN0aW9uSW5kZXgsIENhY2hlZEluZGV4IH0gZnJvbSAnLi4vdHlwZXMvY29sbGVjdGlvbi5qcyc7XG5pbXBvcnQgeyBsb2dnZXIgfSBmcm9tICcuLi91dGlscy9sb2dnZXIuanMnO1xuaW1wb3J0IHsgR2l0SHViQ2xpZW50IH0gZnJvbSAnLi4vY29sbGVjdGlvbi9HaXRIdWJDbGllbnQuanMnO1xuaW1wb3J0IHsgU2VjdXJpdHlNb25pdG9yIH0gZnJvbSAnLi4vc2VjdXJpdHkvc2VjdXJpdHlNb25pdG9yLmpzJztcbmltcG9ydCB7IExSVUNhY2hlLCBDYWNoZUZhY3RvcnkgfSBmcm9tICcuL0xSVUNhY2hlLmpzJztcbmltcG9ydCB7IFBlcmZvcm1hbmNlTW9uaXRvciB9IGZyb20gJy4uL3V0aWxzL1BlcmZvcm1hbmNlTW9uaXRvci5qcyc7XG5cbmV4cG9ydCBjbGFzcyBDb2xsZWN0aW9uSW5kZXhDYWNoZSB7XG4gIHByaXZhdGUgY2FjaGU6IENhY2hlZEluZGV4IHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgcmVhZG9ubHkgVFRMID0gMTUgKiA2MCAqIDEwMDA7IC8vIDE1IG1pbnV0ZXMgaW4gbWlsbGlzZWNvbmRzXG4gIHByaXZhdGUgcmVhZG9ubHkgSU5ERVhfVVJMID0gJ2h0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9Eb2xsaG91c2VNQ1AvY29sbGVjdGlvbi9tYWluL3B1YmxpYy9jb2xsZWN0aW9uLWluZGV4Lmpzb24nO1xuICBwcml2YXRlIGNhY2hlRGlyOiBzdHJpbmc7XG4gIHByaXZhdGUgY2FjaGVGaWxlOiBzdHJpbmc7XG4gIHByaXZhdGUgZ2l0aHViQ2xpZW50OiBHaXRIdWJDbGllbnQ7XG4gIHByaXZhdGUgcGVyZm9ybWFuY2VNb25pdG9yOiBQZXJmb3JtYW5jZU1vbml0b3I7XG4gIHByaXZhdGUgbWVtb3J5Q2FjaGU6IExSVUNhY2hlPGFueT47XG4gIHByaXZhdGUgZmV0Y2hQcm9taXNlOiBQcm9taXNlPENvbGxlY3Rpb25JbmRleD4gfCBudWxsID0gbnVsbDsgLy8gUHJldmVudCBjb25jdXJyZW50IGZldGNoZXNcbiAgXG4gIGNvbnN0cnVjdG9yKGdpdGh1YkNsaWVudDogR2l0SHViQ2xpZW50LCBiYXNlRGlyOiBzdHJpbmcgPSBwcm9jZXNzLmN3ZCgpKSB7XG4gICAgdGhpcy5naXRodWJDbGllbnQgPSBnaXRodWJDbGllbnQ7XG4gICAgdGhpcy5jYWNoZURpciA9IHBhdGguam9pbihiYXNlRGlyLCAnLmRvbGxob3VzZW1jcCcsICdjYWNoZScpO1xuICAgIHRoaXMuY2FjaGVGaWxlID0gcGF0aC5qb2luKHRoaXMuY2FjaGVEaXIsICdjb2xsZWN0aW9uLWluZGV4LWNhY2hlLmpzb24nKTtcbiAgICB0aGlzLnBlcmZvcm1hbmNlTW9uaXRvciA9IFBlcmZvcm1hbmNlTW9uaXRvci5nZXRJbnN0YW5jZSgpO1xuICAgIFxuICAgIC8vIEluaXRpYWxpemUgbWVtb3J5IGNhY2hlIGZvciBmcmVxdWVudGx5IGFjY2Vzc2VkIGRhdGFcbiAgICB0aGlzLm1lbW9yeUNhY2hlID0gQ2FjaGVGYWN0b3J5LmNyZWF0ZUFQSUNhY2hlKHtcbiAgICAgIG1heFNpemU6IDUwLFxuICAgICAgbWF4TWVtb3J5TUI6IDEwLFxuICAgICAgdHRsTXM6IDUgKiA2MCAqIDEwMDAsIC8vIDUgbWludXRlc1xuICAgICAgb25FdmljdGlvbjogKGtleSwgdmFsdWUpID0+IHtcbiAgICAgICAgbG9nZ2VyLmRlYnVnKCdDb2xsZWN0aW9uIG1lbW9yeSBjYWNoZSBldmljdGlvbicsIHsga2V5IH0pO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG4gIFxuICAvKipcbiAgICogR2V0IHRoZSBjb2xsZWN0aW9uIGluZGV4IHdpdGggcGVyZm9ybWFuY2Ugb3B0aW1pemF0aW9uIGFuZCBsYXp5IGxvYWRpbmdcbiAgICovXG4gIGFzeW5jIGdldEluZGV4KGxhenlMb2FkOiBib29sZWFuID0gZmFsc2UpOiBQcm9taXNlPENvbGxlY3Rpb25JbmRleD4ge1xuICAgIGNvbnN0IHN0YXJ0VGltZSA9IERhdGUubm93KCk7XG4gICAgY29uc3QgbWVtb3J5QmVmb3JlID0gcHJvY2Vzcy5tZW1vcnlVc2FnZSgpLmhlYXBVc2VkO1xuICAgIFxuICAgIHRyeSB7XG4gICAgICAvLyBDaGVjayBtZW1vcnkgY2FjaGUgZmlyc3QgZm9yIGZhc3Rlc3QgYWNjZXNzXG4gICAgICBjb25zdCBtZW1vcnlDYWNoZWQgPSB0aGlzLm1lbW9yeUNhY2hlLmdldCgnY29sbGVjdGlvbi1pbmRleCcpO1xuICAgICAgaWYgKG1lbW9yeUNhY2hlZCAmJiB0aGlzLmlzVmFsaWQoKSkge1xuICAgICAgICBsb2dnZXIuZGVidWcoJ1VzaW5nIG1lbW9yeSBjYWNoZWQgY29sbGVjdGlvbiBpbmRleCcpO1xuICAgICAgICB0aGlzLnJlY29yZFBlcmZvcm1hbmNlTWV0cmljcyhzdGFydFRpbWUsIG1lbW9yeUJlZm9yZSwgJ21lbW9yeS1oaXQnKTtcbiAgICAgICAgcmV0dXJuIG1lbW9yeUNhY2hlZDtcbiAgICAgIH1cbiAgICAgIFxuICAgICAgLy8gQ2hlY2sgaWYgd2UgaGF2ZSB2YWxpZCBkaXNrIGNhY2hlZCBkYXRhXG4gICAgICBpZiAodGhpcy5pc1ZhbGlkKCkpIHtcbiAgICAgICAgbG9nZ2VyLmRlYnVnKCdVc2luZyB2YWxpZCBkaXNrIGNhY2hlZCBjb2xsZWN0aW9uIGluZGV4Jyk7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IHRoaXMuY2FjaGUhLmRhdGE7XG4gICAgICAgIHRoaXMubWVtb3J5Q2FjaGUuc2V0KCdjb2xsZWN0aW9uLWluZGV4JywgcmVzdWx0KTtcbiAgICAgICAgdGhpcy5yZWNvcmRQZXJmb3JtYW5jZU1ldHJpY3Moc3RhcnRUaW1lLCBtZW1vcnlCZWZvcmUsICdkaXNrLWhpdCcpO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfVxuICAgICAgXG4gICAgICAvLyBQcmV2ZW50IGNvbmN1cnJlbnQgZmV0Y2hlc1xuICAgICAgaWYgKHRoaXMuZmV0Y2hQcm9taXNlKSB7XG4gICAgICAgIGxvZ2dlci5kZWJ1ZygnV2FpdGluZyBmb3Igb25nb2luZyBjb2xsZWN0aW9uIGluZGV4IGZldGNoJyk7XG4gICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmZldGNoUHJvbWlzZTtcbiAgICAgIH1cbiAgICAgIFxuICAgICAgLy8gTGF6eSBsb2FkaW5nOiBPbmx5IGZldGNoIGlmIG5vdCBpbiBsYXp5IG1vZGUgb3IgYWJzb2x1dGVseSBuZWNlc3NhcnlcbiAgICAgIGlmIChsYXp5TG9hZCAmJiB0aGlzLmNhY2hlPy5kYXRhKSB7XG4gICAgICAgIGxvZ2dlci5kZWJ1ZygnVXNpbmcgc3RhbGUgY2FjaGUgaW4gbGF6eSBsb2FkIG1vZGUnKTtcbiAgICAgICAgdGhpcy5yZWNvcmRQZXJmb3JtYW5jZU1ldHJpY3Moc3RhcnRUaW1lLCBtZW1vcnlCZWZvcmUsICdsYXp5LXN0YWxlJyk7XG4gICAgICAgIHJldHVybiB0aGlzLmNhY2hlLmRhdGE7XG4gICAgICB9XG4gICAgICBcbiAgICAgIC8vIENyZWF0ZSBmZXRjaCBwcm9taXNlIHRvIHByZXZlbnQgY29uY3VycmVudCByZXF1ZXN0c1xuICAgICAgdGhpcy5mZXRjaFByb21pc2UgPSB0aGlzLmZldGNoRnJlc2hXaXRoRmFsbGJhY2soKTtcbiAgICAgIFxuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy5mZXRjaFByb21pc2U7XG4gICAgICAgIHRoaXMubWVtb3J5Q2FjaGUuc2V0KCdjb2xsZWN0aW9uLWluZGV4JywgcmVzdWx0KTtcbiAgICAgICAgdGhpcy5yZWNvcmRQZXJmb3JtYW5jZU1ldHJpY3Moc3RhcnRUaW1lLCBtZW1vcnlCZWZvcmUsICdmcmVzaC1mZXRjaCcpO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgdGhpcy5mZXRjaFByb21pc2UgPSBudWxsO1xuICAgICAgfVxuICAgICAgXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ2dlci5lcnJvcignRmFpbGVkIHRvIGdldCBjb2xsZWN0aW9uIGluZGV4OicsIGVycm9yKTtcbiAgICAgIFxuICAgICAgLy8gVHJ5IGxvYWRpbmcgZnJvbSBwZXJzaXN0ZW50IGNhY2hlIGFzIGxhc3QgcmVzb3J0XG4gICAgICBjb25zdCBwZXJzaXN0ZW50Q2FjaGUgPSBhd2FpdCB0aGlzLmxvYWRGcm9tRGlzaygpO1xuICAgICAgaWYgKHBlcnNpc3RlbnRDYWNoZSkge1xuICAgICAgICBsb2dnZXIuZGVidWcoJ1VzaW5nIHBlcnNpc3RlbnQgY2FjaGUgYXMgbGFzdCByZXNvcnQnKTtcbiAgICAgICAgdGhpcy5jYWNoZSA9IHBlcnNpc3RlbnRDYWNoZTtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gcGVyc2lzdGVudENhY2hlLmRhdGE7XG4gICAgICAgIHRoaXMubWVtb3J5Q2FjaGUuc2V0KCdjb2xsZWN0aW9uLWluZGV4JywgcmVzdWx0KTtcbiAgICAgICAgdGhpcy5yZWNvcmRQZXJmb3JtYW5jZU1ldHJpY3Moc3RhcnRUaW1lLCBtZW1vcnlCZWZvcmUsICdkaXNrLWZhbGxiYWNrJyk7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9XG4gICAgICBcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cbiAgfVxuICBcbiAgLyoqXG4gICAqIENoZWNrIGlmIGN1cnJlbnQgY2FjaGUgaXMgdmFsaWQgKHdpdGhpbiBUVEwpXG4gICAqL1xuICBwcml2YXRlIGlzVmFsaWQoKTogYm9vbGVhbiB7XG4gICAgaWYgKCF0aGlzLmNhY2hlKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIFxuICAgIGNvbnN0IGFnZSA9IERhdGUubm93KCkgLSB0aGlzLmNhY2hlLmZldGNoZWRBdC5nZXRUaW1lKCk7XG4gICAgcmV0dXJuIGFnZSA8IHRoaXMuVFRMO1xuICB9XG4gIFxuICAvKipcbiAgICogRmV0Y2ggZnJlc2ggaW5kZXggZnJvbSBHaXRIdWIgd2l0aCBjb25kaXRpb25hbCByZXF1ZXN0c1xuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBmZXRjaEZyZXNoKCk6IFByb21pc2U8Q29sbGVjdGlvbkluZGV4IHwgbnVsbD4ge1xuICAgIHRyeSB7XG4gICAgICAvLyBCdWlsZCBoZWFkZXJzIGZvciBjb25kaXRpb25hbCByZXF1ZXN0XG4gICAgICBjb25zdCBoZWFkZXJzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge1xuICAgICAgICAnQWNjZXB0JzogJ2FwcGxpY2F0aW9uL2pzb24nLFxuICAgICAgICAnVXNlci1BZ2VudCc6ICdEb2xsaG91c2VNQ1AvMS4wJ1xuICAgICAgfTtcbiAgICAgIFxuICAgICAgLy8gQWRkIGNvbmRpdGlvbmFsIGhlYWRlcnMgaWYgd2UgaGF2ZSBjYWNoZVxuICAgICAgaWYgKHRoaXMuY2FjaGU/LmV0YWcpIHtcbiAgICAgICAgaGVhZGVyc1snSWYtTm9uZS1NYXRjaCddID0gdGhpcy5jYWNoZS5ldGFnO1xuICAgICAgfVxuICAgICAgaWYgKHRoaXMuY2FjaGU/Lmxhc3RNb2RpZmllZCkge1xuICAgICAgICBoZWFkZXJzWydJZi1Nb2RpZmllZC1TaW5jZSddID0gdGhpcy5jYWNoZS5sYXN0TW9kaWZpZWQ7XG4gICAgICB9XG4gICAgICBcbiAgICAgIC8vIFVzZSBmZXRjaCBkaXJlY3RseSBmb3IgYmV0dGVyIGNvbnRyb2wgb3ZlciBjb25kaXRpb25hbCByZXF1ZXN0c1xuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaCh0aGlzLklOREVYX1VSTCwgeyBoZWFkZXJzIH0pO1xuICAgICAgXG4gICAgICAvLyAzMDQgTm90IE1vZGlmaWVkIC0gdXNlIGNhY2hlZCBkYXRhXG4gICAgICBpZiAocmVzcG9uc2Uuc3RhdHVzID09PSAzMDQpIHtcbiAgICAgICAgaWYgKHRoaXMuY2FjaGUpIHtcbiAgICAgICAgICAvLyBVcGRhdGUgdGltZXN0YW1wIHRvIGV4dGVuZCBjYWNoZSB2YWxpZGl0eVxuICAgICAgICAgIHRoaXMuY2FjaGUuZmV0Y2hlZEF0ID0gbmV3IERhdGUoKTtcbiAgICAgICAgICBhd2FpdCB0aGlzLnNhdmVUb0Rpc2sodGhpcy5jYWNoZSk7XG4gICAgICAgICAgbG9nZ2VyLmRlYnVnKCdDb2xsZWN0aW9uIGluZGV4IG5vdCBtb2RpZmllZCAtIHJlZnJlc2hlZCBjYWNoZSB0aW1lc3RhbXAnKTtcbiAgICAgICAgICByZXR1cm4gdGhpcy5jYWNoZS5kYXRhO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBcbiAgICAgIGlmICghcmVzcG9uc2Uub2spIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBIVFRQICR7cmVzcG9uc2Uuc3RhdHVzfTogJHtyZXNwb25zZS5zdGF0dXNUZXh0fWApO1xuICAgICAgfVxuICAgICAgXG4gICAgICBjb25zdCBpbmRleERhdGEgPSBhd2FpdCByZXNwb25zZS5qc29uKCkgYXMgQ29sbGVjdGlvbkluZGV4O1xuICAgICAgXG4gICAgICAvLyBWYWxpZGF0ZSB0aGUgaW5kZXggc3RydWN0dXJlXG4gICAgICBpZiAoIXRoaXMudmFsaWRhdGVJbmRleFN0cnVjdHVyZShpbmRleERhdGEpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBjb2xsZWN0aW9uIGluZGV4IHN0cnVjdHVyZSByZWNlaXZlZCcpO1xuICAgICAgfVxuICAgICAgXG4gICAgICAvLyBDcmVhdGUgbmV3IGNhY2hlIGVudHJ5XG4gICAgICBjb25zdCBuZXdDYWNoZTogQ2FjaGVkSW5kZXggPSB7XG4gICAgICAgIGRhdGE6IGluZGV4RGF0YSxcbiAgICAgICAgZmV0Y2hlZEF0OiBuZXcgRGF0ZSgpLFxuICAgICAgICBldGFnOiByZXNwb25zZS5oZWFkZXJzLmdldCgnZXRhZycpIHx8IHVuZGVmaW5lZCxcbiAgICAgICAgbGFzdE1vZGlmaWVkOiByZXNwb25zZS5oZWFkZXJzLmdldCgnbGFzdC1tb2RpZmllZCcpIHx8IHVuZGVmaW5lZFxuICAgICAgfTtcbiAgICAgIFxuICAgICAgdGhpcy5jYWNoZSA9IG5ld0NhY2hlO1xuICAgICAgXG4gICAgICAvLyBTYXZlIHRvIHBlcnNpc3RlbnQgY2FjaGUgaW4gYmFja2dyb3VuZFxuICAgICAgdGhpcy5zYXZlVG9EaXNrKG5ld0NhY2hlKS5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIGxvZ2dlci5kZWJ1ZygnRmFpbGVkIHRvIHNhdmUgaW5kZXggY2FjaGUgdG8gZGlzazonLCBlcnJvcik7XG4gICAgICB9KTtcbiAgICAgIFxuICAgICAgbG9nZ2VyLmRlYnVnKGBGcmVzaCBjb2xsZWN0aW9uIGluZGV4IGZldGNoZWQgd2l0aCAke2luZGV4RGF0YS50b3RhbF9lbGVtZW50c30gZWxlbWVudHNgKTtcbiAgICAgIHJldHVybiBpbmRleERhdGE7XG4gICAgICBcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgbG9nZ2VyLmRlYnVnKCdGYWlsZWQgdG8gZmV0Y2ggZnJlc2ggY29sbGVjdGlvbiBpbmRleDonLCBlcnJvcik7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gIH1cbiAgXG4gIC8qKlxuICAgKiBWYWxpZGF0ZSB0aGUgc3RydWN0dXJlIG9mIGEgY29sbGVjdGlvbiBpbmRleFxuICAgKi9cbiAgcHJpdmF0ZSB2YWxpZGF0ZUluZGV4U3RydWN0dXJlKGluZGV4OiBhbnkpOiBpbmRleCBpcyBDb2xsZWN0aW9uSW5kZXgge1xuICAgIHJldHVybiAoXG4gICAgICBpbmRleCAmJlxuICAgICAgdHlwZW9mIGluZGV4ID09PSAnb2JqZWN0JyAmJlxuICAgICAgdHlwZW9mIGluZGV4LnZlcnNpb24gPT09ICdzdHJpbmcnICYmXG4gICAgICB0eXBlb2YgaW5kZXguZ2VuZXJhdGVkID09PSAnc3RyaW5nJyAmJlxuICAgICAgdHlwZW9mIGluZGV4LnRvdGFsX2VsZW1lbnRzID09PSAnbnVtYmVyJyAmJlxuICAgICAgaW5kZXguaW5kZXggJiZcbiAgICAgIHR5cGVvZiBpbmRleC5pbmRleCA9PT0gJ29iamVjdCcgJiZcbiAgICAgIGluZGV4Lm1ldGFkYXRhICYmXG4gICAgICB0eXBlb2YgaW5kZXgubWV0YWRhdGEgPT09ICdvYmplY3QnXG4gICAgKTtcbiAgfVxuICBcbiAgLyoqXG4gICAqIFNhdmUgY2FjaGUgdG8gcGVyc2lzdGVudCBzdG9yYWdlXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHNhdmVUb0Rpc2soY2FjaGU6IENhY2hlZEluZGV4KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMuZW5zdXJlQ2FjaGVEaXIoKTtcbiAgICAgIFxuICAgICAgY29uc3QgY2FjaGVEYXRhID0ge1xuICAgICAgICAuLi5jYWNoZSxcbiAgICAgICAgZmV0Y2hlZEF0OiBjYWNoZS5mZXRjaGVkQXQudG9JU09TdHJpbmcoKSAvLyBTZXJpYWxpemUgZGF0ZVxuICAgICAgfTtcbiAgICAgIFxuICAgICAgY29uc3QgZGF0YSA9IEpTT04uc3RyaW5naWZ5KGNhY2hlRGF0YSwgbnVsbCwgMik7XG4gICAgICBhd2FpdCBmcy53cml0ZUZpbGUodGhpcy5jYWNoZUZpbGUsIGRhdGEsICd1dGY4Jyk7XG4gICAgICBcbiAgICAgIGxvZ2dlci5kZWJ1ZygnQ29sbGVjdGlvbiBpbmRleCBjYWNoZSBzYXZlZCB0byBkaXNrJyk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ2dlci5kZWJ1ZygnRmFpbGVkIHRvIHNhdmUgY29sbGVjdGlvbiBpbmRleCBjYWNoZTonLCBlcnJvcik7XG4gICAgICAvLyBEb24ndCB0aHJvdyAtIGNhY2hlIHBlcnNpc3RlbmNlIGZhaWx1cmVzIHNob3VsZG4ndCBicmVhayBmdW5jdGlvbmFsaXR5XG4gICAgfVxuICB9XG4gIFxuICAvKipcbiAgICogTG9hZCBjYWNoZSBmcm9tIHBlcnNpc3RlbnQgc3RvcmFnZVxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBsb2FkRnJvbURpc2soKTogUHJvbWlzZTxDYWNoZWRJbmRleCB8IG51bGw+IHtcbiAgICB0cnkge1xuICAgICAgLy8gQmFzaWMgc2VjdXJpdHkgY2hlY2sgZm9yIHBhdGggdHJhdmVyc2FsXG4gICAgICBpZiAodGhpcy5jYWNoZUZpbGUuaW5jbHVkZXMoJy4uJykgfHwgdGhpcy5jYWNoZUZpbGUuaW5jbHVkZXMoJ1xcMCcpKSB7XG4gICAgICAgIFNlY3VyaXR5TW9uaXRvci5sb2dTZWN1cml0eUV2ZW50KHtcbiAgICAgICAgICB0eXBlOiAnUEFUSF9UUkFWRVJTQUxfQVRURU1QVCcsXG4gICAgICAgICAgc2V2ZXJpdHk6ICdISUdIJyxcbiAgICAgICAgICBzb3VyY2U6ICdDb2xsZWN0aW9uSW5kZXhDYWNoZS5sb2FkRnJvbURpc2snLFxuICAgICAgICAgIGRldGFpbHM6IGBQb3RlbnRpYWwgcGF0aCB0cmF2ZXJzYWwgYXR0ZW1wdCBkZXRlY3RlZDogJHt0aGlzLmNhY2hlRmlsZS5zdWJzdHJpbmcoMCwgMTAwKX1gXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICAgIFxuICAgICAgY29uc3QgZGF0YSA9IGF3YWl0IGZzLnJlYWRGaWxlKHRoaXMuY2FjaGVGaWxlLCAndXRmOCcpO1xuICAgICAgY29uc3QgY2FjaGVEYXRhID0gSlNPTi5wYXJzZShkYXRhKTtcbiAgICAgIFxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4uY2FjaGVEYXRhLFxuICAgICAgICBmZXRjaGVkQXQ6IG5ldyBEYXRlKGNhY2hlRGF0YS5mZXRjaGVkQXQpIC8vIERlc2VyaWFsaXplIGRhdGVcbiAgICAgIH07XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGlmICgoZXJyb3IgYXMgYW55KS5jb2RlICE9PSAnRU5PRU5UJykge1xuICAgICAgICBsb2dnZXIuZGVidWcoJ0ZhaWxlZCB0byBsb2FkIGNvbGxlY3Rpb24gaW5kZXggY2FjaGUgZnJvbSBkaXNrOicsIGVycm9yKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgfVxuICBcbiAgLyoqXG4gICAqIEVuc3VyZSBjYWNoZSBkaXJlY3RvcnkgZXhpc3RzXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGVuc3VyZUNhY2hlRGlyKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCBmcy5ta2Rpcih0aGlzLmNhY2hlRGlyLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgbG9nZ2VyLmVycm9yKCdGYWlsZWQgdG8gY3JlYXRlIGNhY2hlIGRpcmVjdG9yeTonLCBlcnJvcik7XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG4gIH1cbiAgXG4gIC8qKlxuICAgKiBDbGVhciBhbGwgY2FjaGUgZGF0YSB3aXRoIHBlcmZvcm1hbmNlIG1vbml0b3JpbmdcbiAgICovXG4gIGFzeW5jIGNsZWFyQ2FjaGUoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3Qgc3RhcnRUaW1lID0gRGF0ZS5ub3coKTtcbiAgICBcbiAgICB0aGlzLmNhY2hlID0gbnVsbDtcbiAgICB0aGlzLm1lbW9yeUNhY2hlLmNsZWFyKCk7XG4gICAgXG4gICAgLy8gQ2FuY2VsIGFueSBvbmdvaW5nIGZldGNoXG4gICAgdGhpcy5mZXRjaFByb21pc2UgPSBudWxsO1xuICAgIFxuICAgIHRyeSB7XG4gICAgICBhd2FpdCBmcy51bmxpbmsodGhpcy5jYWNoZUZpbGUpO1xuICAgICAgbG9nZ2VyLmRlYnVnKCdDb2xsZWN0aW9uIGluZGV4IGNhY2hlIGNsZWFyZWQgZnJvbSBkaXNrJyk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGlmICgoZXJyb3IgYXMgYW55KS5jb2RlICE9PSAnRU5PRU5UJykge1xuICAgICAgICBsb2dnZXIuZGVidWcoJ0ZhaWxlZCB0byBjbGVhciBjb2xsZWN0aW9uIGluZGV4IGNhY2hlOicsIGVycm9yKTtcbiAgICAgIH1cbiAgICB9XG4gICAgXG4gICAgbG9nZ2VyLmRlYnVnKCdDb2xsZWN0aW9uIGNhY2hlIGNsZWFyZWQnLCB7XG4gICAgICBkdXJhdGlvbjogRGF0ZS5ub3coKSAtIHN0YXJ0VGltZSxcbiAgICAgIG1lbW9yeUZyZWVkOiB0aGlzLm1lbW9yeUNhY2hlLmdldE1lbW9yeVVzYWdlTUIoKVxuICAgIH0pO1xuICB9XG4gIFxuICAvKipcbiAgICogR2V0IGNvbXByZWhlbnNpdmUgY2FjaGUgc3RhdGlzdGljcyBmb3IgZGVidWdnaW5nIGFuZCBtb25pdG9yaW5nXG4gICAqL1xuICBnZXRDYWNoZVN0YXRzKCk6IHsgXG4gICAgaXNWYWxpZDogYm9vbGVhbjsgXG4gICAgYWdlOiBudW1iZXI7IFxuICAgIGhhc0NhY2hlOiBib29sZWFuOyBcbiAgICBlbGVtZW50czogbnVtYmVyO1xuICAgIG1lbW9yeUNhY2hlOiBhbnk7XG4gICAgcGVyZm9ybWFuY2VNZXRyaWNzOiBhbnk7XG4gIH0ge1xuICAgIGlmICghdGhpcy5jYWNoZSkge1xuICAgICAgcmV0dXJuIHsgXG4gICAgICAgIGlzVmFsaWQ6IGZhbHNlLCBcbiAgICAgICAgYWdlOiAwLCBcbiAgICAgICAgaGFzQ2FjaGU6IGZhbHNlLCBcbiAgICAgICAgZWxlbWVudHM6IDAsXG4gICAgICAgIG1lbW9yeUNhY2hlOiB0aGlzLm1lbW9yeUNhY2hlLmdldFN0YXRzKCksXG4gICAgICAgIHBlcmZvcm1hbmNlTWV0cmljczogbnVsbFxuICAgICAgfTtcbiAgICB9XG4gICAgXG4gICAgY29uc3QgYWdlID0gRGF0ZS5ub3coKSAtIHRoaXMuY2FjaGUuZmV0Y2hlZEF0LmdldFRpbWUoKTtcbiAgICByZXR1cm4ge1xuICAgICAgaXNWYWxpZDogdGhpcy5pc1ZhbGlkKCksXG4gICAgICBhZ2UsXG4gICAgICBoYXNDYWNoZTogdHJ1ZSxcbiAgICAgIGVsZW1lbnRzOiB0aGlzLmNhY2hlLmRhdGEudG90YWxfZWxlbWVudHMsXG4gICAgICBtZW1vcnlDYWNoZTogdGhpcy5tZW1vcnlDYWNoZS5nZXRTdGF0cygpLFxuICAgICAgcGVyZm9ybWFuY2VNZXRyaWNzOiB7XG4gICAgICAgIGNhY2hlSGl0UmF0ZTogdGhpcy5jYWxjdWxhdGVDYWNoZUhpdFJhdGUoKSxcbiAgICAgICAgYXZlcmFnZUFjY2Vzc1RpbWU6IHRoaXMuY2FsY3VsYXRlQXZlcmFnZUFjY2Vzc1RpbWUoKVxuICAgICAgfVxuICAgIH07XG4gIH1cbiAgXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIC8vIFBSSVZBVEUgSEVMUEVSIE1FVEhPRFMgRk9SIFBFUkZPUk1BTkNFXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIFxuICAvKipcbiAgICogRmV0Y2ggZnJlc2ggaW5kZXggd2l0aCBjb21wcmVoZW5zaXZlIGZhbGxiYWNrIHN0cmF0ZWd5XG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGZldGNoRnJlc2hXaXRoRmFsbGJhY2soKTogUHJvbWlzZTxDb2xsZWN0aW9uSW5kZXg+IHtcbiAgICB0cnkge1xuICAgICAgLy8gVHJ5IHRvIGZldGNoIGZyZXNoIGluZGV4XG4gICAgICBjb25zdCBmcmVzaEluZGV4ID0gYXdhaXQgdGhpcy5mZXRjaEZyZXNoKCk7XG4gICAgICBpZiAoZnJlc2hJbmRleCkge1xuICAgICAgICBsb2dnZXIuZGVidWcoJ0NvbGxlY3Rpb24gaW5kZXggZmV0Y2hlZCBzdWNjZXNzZnVsbHknKTtcbiAgICAgICAgcmV0dXJuIGZyZXNoSW5kZXg7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ2dlci53YXJuKCdGcmVzaCBmZXRjaCBmYWlsZWQsIHRyeWluZyBmYWxsYmFjaycsIHtcbiAgICAgICAgZXJyb3I6IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogU3RyaW5nKGVycm9yKVxuICAgICAgfSk7XG4gICAgfVxuICAgIFxuICAgIC8vIEZhbGwgYmFjayB0byBzdGFsZSBjYWNoZSBpZiBhdmFpbGFibGVcbiAgICBpZiAodGhpcy5jYWNoZT8uZGF0YSkge1xuICAgICAgbG9nZ2VyLmRlYnVnKCdVc2luZyBzdGFsZSBjYWNoZWQgY29sbGVjdGlvbiBpbmRleCBhcyBmYWxsYmFjaycpO1xuICAgICAgcmV0dXJuIHRoaXMuY2FjaGUuZGF0YTtcbiAgICB9XG4gICAgXG4gICAgdGhyb3cgbmV3IEVycm9yKCdObyBjb2xsZWN0aW9uIGluZGV4IGF2YWlsYWJsZSAtIGZyZXNoIGZldGNoIGZhaWxlZCBhbmQgbm8gY2FjaGUgZXhpc3RzJyk7XG4gIH1cbiAgXG4gIC8qKlxuICAgKiBSZWNvcmQgcGVyZm9ybWFuY2UgbWV0cmljcyBmb3IgY2FjaGUgb3BlcmF0aW9uc1xuICAgKi9cbiAgcHJpdmF0ZSByZWNvcmRQZXJmb3JtYW5jZU1ldHJpY3Moc3RhcnRUaW1lOiBudW1iZXIsIG1lbW9yeUJlZm9yZTogbnVtYmVyLCBvcGVyYXRpb246IHN0cmluZyk6IHZvaWQge1xuICAgIGNvbnN0IGR1cmF0aW9uID0gRGF0ZS5ub3coKSAtIHN0YXJ0VGltZTtcbiAgICBjb25zdCBtZW1vcnlBZnRlciA9IHByb2Nlc3MubWVtb3J5VXNhZ2UoKS5oZWFwVXNlZDtcbiAgICBcbiAgICBsb2dnZXIuZGVidWcoJ0NvbGxlY3Rpb24gY2FjaGUgb3BlcmF0aW9uIGNvbXBsZXRlZCcsIHtcbiAgICAgIG9wZXJhdGlvbixcbiAgICAgIGR1cmF0aW9uLFxuICAgICAgbWVtb3J5VXNhZ2VNQjogKG1lbW9yeUFmdGVyIC0gbWVtb3J5QmVmb3JlKSAvICgxMDI0ICogMTAyNClcbiAgICB9KTtcbiAgICBcbiAgICAvLyBSZWNvcmQgY2FjaGUgcGVyZm9ybWFuY2UgbWV0cmljc1xuICAgIHRoaXMucGVyZm9ybWFuY2VNb25pdG9yLnJlY29yZENhY2hlUGVyZm9ybWFuY2UoJ2NvbGxlY3Rpb25JbmRleCcsIHtcbiAgICAgIGhpdFJhdGU6IG9wZXJhdGlvbi5pbmNsdWRlcygnaGl0JykgPyAxIDogMCxcbiAgICAgIGF2Z0hpdFRpbWU6IG9wZXJhdGlvbi5pbmNsdWRlcygnaGl0JykgPyBkdXJhdGlvbiA6IDAsXG4gICAgICBhdmdNaXNzVGltZTogb3BlcmF0aW9uLmluY2x1ZGVzKCdoaXQnKSA/IDAgOiBkdXJhdGlvbixcbiAgICAgIHRvdGFsSGl0czogb3BlcmF0aW9uLmluY2x1ZGVzKCdoaXQnKSA/IDEgOiAwLFxuICAgICAgdG90YWxNaXNzZXM6IG9wZXJhdGlvbi5pbmNsdWRlcygnaGl0JykgPyAwIDogMSxcbiAgICAgIGV2aWN0aW9uczogMFxuICAgIH0pO1xuICB9XG4gIFxuICAvKipcbiAgICogQ2FsY3VsYXRlIGNhY2hlIGhpdCByYXRlIChwbGFjZWhvbGRlciBmb3IgZnV0dXJlIGltcGxlbWVudGF0aW9uKVxuICAgKi9cbiAgcHJpdmF0ZSBjYWxjdWxhdGVDYWNoZUhpdFJhdGUoKTogbnVtYmVyIHtcbiAgICAvLyBUaGlzIHdvdWxkIGJlIGltcGxlbWVudGVkIHdpdGggYWN0dWFsIG1ldHJpY3MgdHJhY2tpbmdcbiAgICByZXR1cm4gdGhpcy5tZW1vcnlDYWNoZS5nZXRTdGF0cygpLmhpdFJhdGU7XG4gIH1cbiAgXG4gIC8qKlxuICAgKiBDYWxjdWxhdGUgYXZlcmFnZSBhY2Nlc3MgdGltZSAocGxhY2Vob2xkZXIgZm9yIGZ1dHVyZSBpbXBsZW1lbnRhdGlvbilcbiAgICovXG4gIHByaXZhdGUgY2FsY3VsYXRlQXZlcmFnZUFjY2Vzc1RpbWUoKTogbnVtYmVyIHtcbiAgICAvLyBUaGlzIHdvdWxkIGJlIGltcGxlbWVudGVkIHdpdGggYWN0dWFsIHRpbWluZyBtZXRyaWNzXG4gICAgcmV0dXJuIDU7IC8vIFBsYWNlaG9sZGVyIHZhbHVlXG4gIH1cbn0iXX0=
|