@dollhousemcp/mcp-server 1.3.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 +132 -0
- package/LICENSE +51 -0
- package/README.md +1124 -0
- package/data/agents/code-reviewer.md +296 -0
- package/data/agents/research-assistant.md +259 -0
- package/data/agents/task-manager.md +206 -0
- package/data/ensembles/business-advisor.md +354 -0
- package/data/ensembles/creative-studio.md +288 -0
- package/data/ensembles/development-team.md +292 -0
- package/data/ensembles/security-analysis-team.md +438 -0
- package/data/memories/conversation-history.md +146 -0
- package/data/memories/learning-progress.md +376 -0
- package/data/memories/project-context.md +268 -0
- package/data/personas/business-consultant.md +50 -0
- package/data/personas/creative-writer.md +44 -0
- package/data/personas/debug-detective.md +59 -0
- package/data/personas/eli5-explainer.md +49 -0
- package/data/personas/security-analyst.md +161 -0
- package/data/personas/technical-analyst.md +43 -0
- package/data/skills/code-review.md +112 -0
- package/data/skills/creative-writing.md +174 -0
- package/data/skills/data-analysis.md +160 -0
- package/data/skills/penetration-testing.md +374 -0
- package/data/skills/research.md +181 -0
- package/data/skills/threat-modeling.md +469 -0
- package/data/skills/translation.md +148 -0
- package/data/templates/code-documentation.md +409 -0
- package/data/templates/email-professional.md +158 -0
- package/data/templates/meeting-notes.md +141 -0
- package/data/templates/penetration-test-report.md +608 -0
- package/data/templates/project-brief.md +234 -0
- package/data/templates/report-executive.md +258 -0
- package/data/templates/security-vulnerability-report.md +457 -0
- package/data/templates/threat-assessment-report.md +774 -0
- package/dist/cache/APICache.d.ts +23 -0
- package/dist/cache/APICache.d.ts.map +1 -0
- package/dist/cache/APICache.js +42 -0
- package/dist/cache/index.d.ts +5 -0
- package/dist/cache/index.d.ts.map +1 -0
- package/dist/cache/index.js +5 -0
- package/dist/collection/CollectionBrowser.d.ts +24 -0
- package/dist/collection/CollectionBrowser.d.ts.map +1 -0
- package/dist/collection/CollectionBrowser.js +120 -0
- package/dist/collection/CollectionSearch.d.ts +18 -0
- package/dist/collection/CollectionSearch.d.ts.map +1 -0
- package/dist/collection/CollectionSearch.js +48 -0
- package/dist/collection/ElementInstaller.d.ts +33 -0
- package/dist/collection/ElementInstaller.d.ts.map +1 -0
- package/dist/collection/ElementInstaller.js +142 -0
- package/dist/collection/GitHubClient.d.ts +22 -0
- package/dist/collection/GitHubClient.d.ts.map +1 -0
- package/dist/collection/GitHubClient.js +114 -0
- package/dist/collection/MarketplaceBrowser.d.ts +24 -0
- package/dist/collection/MarketplaceBrowser.d.ts.map +1 -0
- package/dist/collection/MarketplaceBrowser.js +115 -0
- package/dist/collection/MarketplaceSearch.d.ts +18 -0
- package/dist/collection/MarketplaceSearch.d.ts.map +1 -0
- package/dist/collection/MarketplaceSearch.js +48 -0
- package/dist/collection/PersonaDetails.d.ts +22 -0
- package/dist/collection/PersonaDetails.d.ts.map +1 -0
- package/dist/collection/PersonaDetails.js +71 -0
- package/dist/collection/PersonaInstaller.d.ts +26 -0
- package/dist/collection/PersonaInstaller.d.ts.map +1 -0
- package/dist/collection/PersonaInstaller.js +103 -0
- package/dist/collection/PersonaSubmitter.d.ts +19 -0
- package/dist/collection/PersonaSubmitter.d.ts.map +1 -0
- package/dist/collection/PersonaSubmitter.js +57 -0
- package/dist/collection/index.d.ts +10 -0
- package/dist/collection/index.d.ts.map +1 -0
- package/dist/collection/index.js +10 -0
- package/dist/config/constants.d.ts +25 -0
- package/dist/config/constants.d.ts.map +1 -0
- package/dist/config/constants.js +34 -0
- package/dist/config/index.d.ts +6 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +6 -0
- package/dist/config/indicator-config.d.ts +107 -0
- package/dist/config/indicator-config.d.ts.map +1 -0
- package/dist/config/indicator-config.js +158 -0
- package/dist/constants/defaultPersonas.d.ts +10 -0
- package/dist/constants/defaultPersonas.d.ts.map +1 -0
- package/dist/constants/defaultPersonas.js +18 -0
- package/dist/constants/limits.d.ts +10 -0
- package/dist/constants/limits.d.ts.map +1 -0
- package/dist/constants/limits.js +13 -0
- package/dist/elements/BaseElement.d.ts +81 -0
- package/dist/elements/BaseElement.d.ts.map +1 -0
- package/dist/elements/BaseElement.js +381 -0
- package/dist/elements/FeedbackProcessor.d.ts +57 -0
- package/dist/elements/FeedbackProcessor.d.ts.map +1 -0
- package/dist/elements/FeedbackProcessor.js +418 -0
- package/dist/elements/agents/Agent.d.ts +145 -0
- package/dist/elements/agents/Agent.d.ts.map +1 -0
- package/dist/elements/agents/Agent.js +848 -0
- package/dist/elements/agents/AgentManager.d.ts +125 -0
- package/dist/elements/agents/AgentManager.d.ts.map +1 -0
- package/dist/elements/agents/AgentManager.js +615 -0
- package/dist/elements/agents/constants.d.ts +42 -0
- package/dist/elements/agents/constants.d.ts.map +1 -0
- package/dist/elements/agents/constants.js +45 -0
- package/dist/elements/agents/goalTemplates.d.ts +44 -0
- package/dist/elements/agents/goalTemplates.d.ts.map +1 -0
- package/dist/elements/agents/goalTemplates.js +297 -0
- package/dist/elements/agents/index.d.ts +8 -0
- package/dist/elements/agents/index.d.ts.map +1 -0
- package/dist/elements/agents/index.js +8 -0
- package/dist/elements/agents/ruleEngineConfig.d.ts +76 -0
- package/dist/elements/agents/ruleEngineConfig.d.ts.map +1 -0
- package/dist/elements/agents/ruleEngineConfig.js +143 -0
- package/dist/elements/agents/types.d.ts +97 -0
- package/dist/elements/agents/types.d.ts.map +1 -0
- package/dist/elements/agents/types.js +5 -0
- package/dist/elements/ensembles/Ensemble.d.ts +144 -0
- package/dist/elements/ensembles/Ensemble.d.ts.map +1 -0
- package/dist/elements/ensembles/Ensemble.js +860 -0
- package/dist/elements/ensembles/EnsembleManager.d.ts +85 -0
- package/dist/elements/ensembles/EnsembleManager.d.ts.map +1 -0
- package/dist/elements/ensembles/EnsembleManager.js +378 -0
- package/dist/elements/ensembles/constants.d.ts +73 -0
- package/dist/elements/ensembles/constants.d.ts.map +1 -0
- package/dist/elements/ensembles/constants.js +92 -0
- package/dist/elements/ensembles/index.d.ts +8 -0
- package/dist/elements/ensembles/index.d.ts.map +1 -0
- package/dist/elements/ensembles/index.js +8 -0
- package/dist/elements/ensembles/types.d.ts +92 -0
- package/dist/elements/ensembles/types.d.ts.map +1 -0
- package/dist/elements/ensembles/types.js +8 -0
- package/dist/elements/index.d.ts +11 -0
- package/dist/elements/index.d.ts.map +1 -0
- package/dist/elements/index.js +12 -0
- package/dist/elements/memories/Memory.d.ts +110 -0
- package/dist/elements/memories/Memory.d.ts.map +1 -0
- package/dist/elements/memories/Memory.js +470 -0
- package/dist/elements/memories/MemoryManager.d.ts +86 -0
- package/dist/elements/memories/MemoryManager.d.ts.map +1 -0
- package/dist/elements/memories/MemoryManager.js +435 -0
- package/dist/elements/memories/constants.d.ts +42 -0
- package/dist/elements/memories/constants.d.ts.map +1 -0
- package/dist/elements/memories/constants.js +49 -0
- package/dist/elements/memories/index.d.ts +6 -0
- package/dist/elements/memories/index.d.ts.map +1 -0
- package/dist/elements/memories/index.js +6 -0
- package/dist/elements/skills/Skill.d.ts +109 -0
- package/dist/elements/skills/Skill.d.ts.map +1 -0
- package/dist/elements/skills/Skill.js +381 -0
- package/dist/elements/skills/index.d.ts +5 -0
- package/dist/elements/skills/index.d.ts.map +1 -0
- package/dist/elements/skills/index.js +5 -0
- package/dist/elements/templates/Template.d.ts +138 -0
- package/dist/elements/templates/Template.d.ts.map +1 -0
- package/dist/elements/templates/Template.js +673 -0
- package/dist/elements/templates/TemplateManager.d.ts +104 -0
- package/dist/elements/templates/TemplateManager.d.ts.map +1 -0
- package/dist/elements/templates/TemplateManager.js +501 -0
- package/dist/elements/templates/index.d.ts +6 -0
- package/dist/elements/templates/index.d.ts.map +1 -0
- package/dist/elements/templates/index.js +6 -0
- package/dist/errors/SecurityError.d.ts +29 -0
- package/dist/errors/SecurityError.d.ts.map +1 -0
- package/dist/errors/SecurityError.js +47 -0
- package/dist/errors/index.d.ts +2 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/index.js +2 -0
- package/dist/index.barrel.d.ts +21 -0
- package/dist/index.barrel.d.ts.map +1 -0
- package/dist/index.barrel.js +31 -0
- package/dist/index.d.ts +223 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1606 -0
- package/dist/marketplace/GitHubClient.d.ts +22 -0
- package/dist/marketplace/GitHubClient.d.ts.map +1 -0
- package/dist/marketplace/GitHubClient.js +112 -0
- package/dist/marketplace/MarketplaceBrowser.d.ts +24 -0
- package/dist/marketplace/MarketplaceBrowser.d.ts.map +1 -0
- package/dist/marketplace/MarketplaceBrowser.js +115 -0
- package/dist/marketplace/MarketplaceSearch.d.ts +18 -0
- package/dist/marketplace/MarketplaceSearch.d.ts.map +1 -0
- package/dist/marketplace/MarketplaceSearch.js +48 -0
- package/dist/marketplace/PersonaDetails.d.ts +22 -0
- package/dist/marketplace/PersonaDetails.d.ts.map +1 -0
- package/dist/marketplace/PersonaDetails.js +71 -0
- package/dist/marketplace/PersonaInstaller.d.ts +25 -0
- package/dist/marketplace/PersonaInstaller.d.ts.map +1 -0
- package/dist/marketplace/PersonaInstaller.js +100 -0
- package/dist/marketplace/PersonaSubmitter.d.ts +19 -0
- package/dist/marketplace/PersonaSubmitter.d.ts.map +1 -0
- package/dist/marketplace/PersonaSubmitter.js +57 -0
- package/dist/marketplace/index.d.ts +10 -0
- package/dist/marketplace/index.d.ts.map +1 -0
- package/dist/marketplace/index.js +10 -0
- package/dist/persona/PersonaElement.d.ts +64 -0
- package/dist/persona/PersonaElement.d.ts.map +1 -0
- package/dist/persona/PersonaElement.js +223 -0
- package/dist/persona/PersonaElementManager.d.ts +97 -0
- package/dist/persona/PersonaElementManager.d.ts.map +1 -0
- package/dist/persona/PersonaElementManager.js +348 -0
- package/dist/persona/PersonaLoader.d.ts +34 -0
- package/dist/persona/PersonaLoader.d.ts.map +1 -0
- package/dist/persona/PersonaLoader.js +145 -0
- package/dist/persona/PersonaManager.d.ts +112 -0
- package/dist/persona/PersonaManager.d.ts.map +1 -0
- package/dist/persona/PersonaManager.js +341 -0
- package/dist/persona/PersonaValidator.d.ts +39 -0
- package/dist/persona/PersonaValidator.d.ts.map +1 -0
- package/dist/persona/PersonaValidator.js +161 -0
- package/dist/persona/export-import/PersonaExporter.d.ts +43 -0
- package/dist/persona/export-import/PersonaExporter.d.ts.map +1 -0
- package/dist/persona/export-import/PersonaExporter.js +99 -0
- package/dist/persona/export-import/PersonaImporter.d.ts +65 -0
- package/dist/persona/export-import/PersonaImporter.d.ts.map +1 -0
- package/dist/persona/export-import/PersonaImporter.js +315 -0
- package/dist/persona/export-import/PersonaSharer.d.ts +60 -0
- package/dist/persona/export-import/PersonaSharer.d.ts.map +1 -0
- package/dist/persona/export-import/PersonaSharer.js +502 -0
- package/dist/persona/export-import/index.d.ts +10 -0
- package/dist/persona/export-import/index.d.ts.map +1 -0
- package/dist/persona/export-import/index.js +7 -0
- package/dist/persona/index.d.ts +7 -0
- package/dist/persona/index.d.ts.map +1 -0
- package/dist/persona/index.js +7 -0
- package/dist/portfolio/MigrationManager.d.ts +44 -0
- package/dist/portfolio/MigrationManager.d.ts.map +1 -0
- package/dist/portfolio/MigrationManager.js +163 -0
- package/dist/portfolio/PortfolioManager.d.ts +54 -0
- package/dist/portfolio/PortfolioManager.d.ts.map +1 -0
- package/dist/portfolio/PortfolioManager.js +224 -0
- package/dist/portfolio/types.d.ts +18 -0
- package/dist/portfolio/types.d.ts.map +1 -0
- package/dist/portfolio/types.js +13 -0
- package/dist/security/InputValidator.d.ts +80 -0
- package/dist/security/InputValidator.d.ts.map +1 -0
- package/dist/security/InputValidator.js +448 -0
- package/dist/security/audit/SecurityAuditor.d.ts +44 -0
- package/dist/security/audit/SecurityAuditor.d.ts.map +1 -0
- package/dist/security/audit/SecurityAuditor.js +274 -0
- package/dist/security/audit/config/suppressions.d.ts +34 -0
- package/dist/security/audit/config/suppressions.d.ts.map +1 -0
- package/dist/security/audit/config/suppressions.js +575 -0
- package/dist/security/audit/index.d.ts +14 -0
- package/dist/security/audit/index.d.ts.map +1 -0
- package/dist/security/audit/index.js +15 -0
- package/dist/security/audit/reporters/ConsoleReporter.d.ts +46 -0
- package/dist/security/audit/reporters/ConsoleReporter.d.ts.map +1 -0
- package/dist/security/audit/reporters/ConsoleReporter.js +174 -0
- package/dist/security/audit/reporters/JsonReporter.d.ts +13 -0
- package/dist/security/audit/reporters/JsonReporter.d.ts.map +1 -0
- package/dist/security/audit/reporters/JsonReporter.js +25 -0
- package/dist/security/audit/reporters/MarkdownReporter.d.ts +13 -0
- package/dist/security/audit/reporters/MarkdownReporter.d.ts.map +1 -0
- package/dist/security/audit/reporters/MarkdownReporter.js +79 -0
- package/dist/security/audit/rules/SecurityRules.d.ts +20 -0
- package/dist/security/audit/rules/SecurityRules.d.ts.map +1 -0
- package/dist/security/audit/rules/SecurityRules.js +244 -0
- package/dist/security/audit/scanners/CodeScanner.d.ts +47 -0
- package/dist/security/audit/scanners/CodeScanner.d.ts.map +1 -0
- package/dist/security/audit/scanners/CodeScanner.js +174 -0
- package/dist/security/audit/scanners/ConfigurationScanner.d.ts +13 -0
- package/dist/security/audit/scanners/ConfigurationScanner.d.ts.map +1 -0
- package/dist/security/audit/scanners/ConfigurationScanner.js +22 -0
- package/dist/security/audit/scanners/DependencyScanner.d.ts +13 -0
- package/dist/security/audit/scanners/DependencyScanner.d.ts.map +1 -0
- package/dist/security/audit/scanners/DependencyScanner.js +22 -0
- package/dist/security/audit/types.d.ts +94 -0
- package/dist/security/audit/types.d.ts.map +1 -0
- package/dist/security/audit/types.js +6 -0
- package/dist/security/commandValidator.d.ts +7 -0
- package/dist/security/commandValidator.d.ts.map +1 -0
- package/dist/security/commandValidator.js +78 -0
- package/dist/security/constants.d.ts +24 -0
- package/dist/security/constants.d.ts.map +1 -0
- package/dist/security/constants.js +26 -0
- package/dist/security/contentValidator.d.ts +47 -0
- package/dist/security/contentValidator.d.ts.map +1 -0
- package/dist/security/contentValidator.js +301 -0
- package/dist/security/errorHandler.d.ts +42 -0
- package/dist/security/errorHandler.d.ts.map +1 -0
- package/dist/security/errorHandler.js +166 -0
- package/dist/security/errors.d.ts +14 -0
- package/dist/security/errors.d.ts.map +1 -0
- package/dist/security/errors.js +28 -0
- package/dist/security/fileLockManager.d.ts +70 -0
- package/dist/security/fileLockManager.d.ts.map +1 -0
- package/dist/security/fileLockManager.js +187 -0
- package/dist/security/index.d.ts +12 -0
- package/dist/security/index.d.ts.map +1 -0
- package/dist/security/index.js +14 -0
- package/dist/security/pathValidator.d.ts +9 -0
- package/dist/security/pathValidator.d.ts.map +1 -0
- package/dist/security/pathValidator.js +102 -0
- package/dist/security/regexValidator.d.ts +59 -0
- package/dist/security/regexValidator.d.ts.map +1 -0
- package/dist/security/regexValidator.js +214 -0
- package/dist/security/secureYamlParser.d.ts +46 -0
- package/dist/security/secureYamlParser.d.ts.map +1 -0
- package/dist/security/secureYamlParser.js +203 -0
- package/dist/security/securityMonitor.d.ts +58 -0
- package/dist/security/securityMonitor.d.ts.map +1 -0
- package/dist/security/securityMonitor.js +108 -0
- package/dist/security/tokenManager.d.ts +85 -0
- package/dist/security/tokenManager.d.ts.map +1 -0
- package/dist/security/tokenManager.js +286 -0
- package/dist/security/validators/unicodeValidator.d.ts +97 -0
- package/dist/security/validators/unicodeValidator.d.ts.map +1 -0
- package/dist/security/validators/unicodeValidator.js +312 -0
- package/dist/security/yamlValidator.d.ts +21 -0
- package/dist/security/yamlValidator.d.ts.map +1 -0
- package/dist/security/yamlValidator.js +164 -0
- package/dist/server/ServerSetup.d.ts +35 -0
- package/dist/server/ServerSetup.d.ts.map +1 -0
- package/dist/server/ServerSetup.js +116 -0
- package/dist/server/index.d.ts +7 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +7 -0
- package/dist/server/startup.d.ts +31 -0
- package/dist/server/startup.d.ts.map +1 -0
- package/dist/server/startup.js +67 -0
- package/dist/server/tools/CollectionTools.d.ts +10 -0
- package/dist/server/tools/CollectionTools.d.ts.map +1 -0
- package/dist/server/tools/CollectionTools.js +96 -0
- package/dist/server/tools/ConfigTools.d.ts +10 -0
- package/dist/server/tools/ConfigTools.d.ts.map +1 -0
- package/dist/server/tools/ConfigTools.js +63 -0
- package/dist/server/tools/MarketplaceTools.d.ts +10 -0
- package/dist/server/tools/MarketplaceTools.d.ts.map +1 -0
- package/dist/server/tools/MarketplaceTools.js +96 -0
- package/dist/server/tools/PersonaTools.d.ts +10 -0
- package/dist/server/tools/PersonaTools.d.ts.map +1 -0
- package/dist/server/tools/PersonaTools.js +257 -0
- package/dist/server/tools/ToolRegistry.d.ts +37 -0
- package/dist/server/tools/ToolRegistry.d.ts.map +1 -0
- package/dist/server/tools/ToolRegistry.js +40 -0
- package/dist/server/tools/UpdateTools.d.ts +10 -0
- package/dist/server/tools/UpdateTools.d.ts.map +1 -0
- package/dist/server/tools/UpdateTools.js +64 -0
- package/dist/server/tools/UserTools.d.ts +10 -0
- package/dist/server/tools/UserTools.d.ts.map +1 -0
- package/dist/server/tools/UserTools.js +51 -0
- package/dist/server/tools/index.d.ts +10 -0
- package/dist/server/tools/index.d.ts.map +1 -0
- package/dist/server/tools/index.js +10 -0
- package/dist/server/types.d.ts +34 -0
- package/dist/server/types.d.ts.map +1 -0
- package/dist/server/types.js +5 -0
- package/dist/src/cache/APICache.d.ts +23 -0
- package/dist/src/cache/APICache.d.ts.map +1 -0
- package/dist/src/cache/APICache.js +42 -0
- package/dist/src/cache/index.d.ts +5 -0
- package/dist/src/cache/index.d.ts.map +1 -0
- package/dist/src/cache/index.js +5 -0
- package/dist/src/config/constants.d.ts +25 -0
- package/dist/src/config/constants.d.ts.map +1 -0
- package/dist/src/config/constants.js +30 -0
- package/dist/src/config/index.d.ts +6 -0
- package/dist/src/config/index.d.ts.map +1 -0
- package/dist/src/config/index.js +6 -0
- package/dist/src/config/indicator-config.d.ts +107 -0
- package/dist/src/config/indicator-config.d.ts.map +1 -0
- package/dist/src/config/indicator-config.js +158 -0
- package/dist/src/constants/defaultPersonas.d.ts +10 -0
- package/dist/src/constants/defaultPersonas.d.ts.map +1 -0
- package/dist/src/constants/defaultPersonas.js +18 -0
- package/dist/src/constants/limits.d.ts +10 -0
- package/dist/src/constants/limits.d.ts.map +1 -0
- package/dist/src/constants/limits.js +13 -0
- package/dist/src/errors/SecurityError.d.ts +29 -0
- package/dist/src/errors/SecurityError.d.ts.map +1 -0
- package/dist/src/errors/SecurityError.js +47 -0
- package/dist/src/errors/index.d.ts +2 -0
- package/dist/src/errors/index.d.ts.map +1 -0
- package/dist/src/errors/index.js +2 -0
- package/dist/src/index.barrel.d.ts +21 -0
- package/dist/src/index.barrel.d.ts.map +1 -0
- package/dist/src/index.barrel.js +31 -0
- package/dist/src/index.d.ts +220 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +1559 -0
- package/dist/src/marketplace/GitHubClient.d.ts +22 -0
- package/dist/src/marketplace/GitHubClient.d.ts.map +1 -0
- package/dist/src/marketplace/GitHubClient.js +112 -0
- package/dist/src/marketplace/MarketplaceBrowser.d.ts +21 -0
- package/dist/src/marketplace/MarketplaceBrowser.d.ts.map +1 -0
- package/dist/src/marketplace/MarketplaceBrowser.js +45 -0
- package/dist/src/marketplace/MarketplaceSearch.d.ts +18 -0
- package/dist/src/marketplace/MarketplaceSearch.d.ts.map +1 -0
- package/dist/src/marketplace/MarketplaceSearch.js +36 -0
- package/dist/src/marketplace/PersonaDetails.d.ts +22 -0
- package/dist/src/marketplace/PersonaDetails.d.ts.map +1 -0
- package/dist/src/marketplace/PersonaDetails.js +71 -0
- package/dist/src/marketplace/PersonaInstaller.d.ts +25 -0
- package/dist/src/marketplace/PersonaInstaller.d.ts.map +1 -0
- package/dist/src/marketplace/PersonaInstaller.js +100 -0
- package/dist/src/marketplace/PersonaSubmitter.d.ts +19 -0
- package/dist/src/marketplace/PersonaSubmitter.d.ts.map +1 -0
- package/dist/src/marketplace/PersonaSubmitter.js +57 -0
- package/dist/src/marketplace/index.d.ts +10 -0
- package/dist/src/marketplace/index.d.ts.map +1 -0
- package/dist/src/marketplace/index.js +10 -0
- package/dist/src/persona/PersonaLoader.d.ts +33 -0
- package/dist/src/persona/PersonaLoader.d.ts.map +1 -0
- package/dist/src/persona/PersonaLoader.js +139 -0
- package/dist/src/persona/PersonaManager.d.ts +112 -0
- package/dist/src/persona/PersonaManager.d.ts.map +1 -0
- package/dist/src/persona/PersonaManager.js +341 -0
- package/dist/src/persona/PersonaValidator.d.ts +33 -0
- package/dist/src/persona/PersonaValidator.d.ts.map +1 -0
- package/dist/src/persona/PersonaValidator.js +157 -0
- package/dist/src/persona/export-import/PersonaExporter.d.ts +43 -0
- package/dist/src/persona/export-import/PersonaExporter.d.ts.map +1 -0
- package/dist/src/persona/export-import/PersonaExporter.js +99 -0
- package/dist/src/persona/export-import/PersonaImporter.d.ts +65 -0
- package/dist/src/persona/export-import/PersonaImporter.d.ts.map +1 -0
- package/dist/src/persona/export-import/PersonaImporter.js +313 -0
- package/dist/src/persona/export-import/PersonaSharer.d.ts +60 -0
- package/dist/src/persona/export-import/PersonaSharer.d.ts.map +1 -0
- package/dist/src/persona/export-import/PersonaSharer.js +363 -0
- package/dist/src/persona/export-import/index.d.ts +10 -0
- package/dist/src/persona/export-import/index.d.ts.map +1 -0
- package/dist/src/persona/export-import/index.js +7 -0
- package/dist/src/persona/index.d.ts +7 -0
- package/dist/src/persona/index.d.ts.map +1 -0
- package/dist/src/persona/index.js +7 -0
- package/dist/src/security/InputValidator.d.ts +69 -0
- package/dist/src/security/InputValidator.d.ts.map +1 -0
- package/dist/src/security/InputValidator.js +381 -0
- package/dist/src/security/commandValidator.d.ts +7 -0
- package/dist/src/security/commandValidator.d.ts.map +1 -0
- package/dist/src/security/commandValidator.js +77 -0
- package/dist/src/security/constants.d.ts +21 -0
- package/dist/src/security/constants.d.ts.map +1 -0
- package/dist/src/security/constants.js +23 -0
- package/dist/src/security/contentValidator.d.ts +47 -0
- package/dist/src/security/contentValidator.d.ts.map +1 -0
- package/dist/src/security/contentValidator.js +188 -0
- package/dist/src/security/fileLockManager.d.ts +70 -0
- package/dist/src/security/fileLockManager.d.ts.map +1 -0
- package/dist/src/security/fileLockManager.js +187 -0
- package/dist/src/security/index.d.ts +12 -0
- package/dist/src/security/index.d.ts.map +1 -0
- package/dist/src/security/index.js +14 -0
- package/dist/src/security/pathValidator.d.ts +9 -0
- package/dist/src/security/pathValidator.d.ts.map +1 -0
- package/dist/src/security/pathValidator.js +97 -0
- package/dist/src/security/secureYamlParser.d.ts +46 -0
- package/dist/src/security/secureYamlParser.d.ts.map +1 -0
- package/dist/src/security/secureYamlParser.js +203 -0
- package/dist/src/security/securityMonitor.d.ts +58 -0
- package/dist/src/security/securityMonitor.d.ts.map +1 -0
- package/dist/src/security/securityMonitor.js +108 -0
- package/dist/src/security/tokenManager.d.ts +59 -0
- package/dist/src/security/tokenManager.d.ts.map +1 -0
- package/dist/src/security/tokenManager.js +216 -0
- package/dist/src/security/yamlValidator.d.ts +20 -0
- package/dist/src/security/yamlValidator.d.ts.map +1 -0
- package/dist/src/security/yamlValidator.js +138 -0
- package/dist/src/server/ServerSetup.d.ts +31 -0
- package/dist/src/server/ServerSetup.d.ts.map +1 -0
- package/dist/src/server/ServerSetup.js +79 -0
- package/dist/src/server/index.d.ts +7 -0
- package/dist/src/server/index.d.ts.map +1 -0
- package/dist/src/server/index.js +7 -0
- package/dist/src/server/tools/ConfigTools.d.ts +10 -0
- package/dist/src/server/tools/ConfigTools.d.ts.map +1 -0
- package/dist/src/server/tools/ConfigTools.js +63 -0
- package/dist/src/server/tools/MarketplaceTools.d.ts +10 -0
- package/dist/src/server/tools/MarketplaceTools.d.ts.map +1 -0
- package/dist/src/server/tools/MarketplaceTools.js +92 -0
- package/dist/src/server/tools/PersonaTools.d.ts +10 -0
- package/dist/src/server/tools/PersonaTools.d.ts.map +1 -0
- package/dist/src/server/tools/PersonaTools.js +257 -0
- package/dist/src/server/tools/ToolRegistry.d.ts +37 -0
- package/dist/src/server/tools/ToolRegistry.d.ts.map +1 -0
- package/dist/src/server/tools/ToolRegistry.js +40 -0
- package/dist/src/server/tools/UpdateTools.d.ts +10 -0
- package/dist/src/server/tools/UpdateTools.d.ts.map +1 -0
- package/dist/src/server/tools/UpdateTools.js +64 -0
- package/dist/src/server/tools/UserTools.d.ts +10 -0
- package/dist/src/server/tools/UserTools.d.ts.map +1 -0
- package/dist/src/server/tools/UserTools.js +51 -0
- package/dist/src/server/tools/index.d.ts +10 -0
- package/dist/src/server/tools/index.d.ts.map +1 -0
- package/dist/src/server/tools/index.js +10 -0
- package/dist/src/server/types.d.ts +34 -0
- package/dist/src/server/types.d.ts.map +1 -0
- package/dist/src/server/types.js +5 -0
- package/dist/src/tools/debug.d.ts +20 -0
- package/dist/src/tools/debug.d.ts.map +1 -0
- package/dist/src/tools/debug.js +37 -0
- package/dist/src/types/cache.d.ts +8 -0
- package/dist/src/types/cache.d.ts.map +1 -0
- package/dist/src/types/cache.js +5 -0
- package/dist/src/types/index.d.ts +8 -0
- package/dist/src/types/index.d.ts.map +1 -0
- package/dist/src/types/index.js +8 -0
- package/dist/src/types/marketplace.d.ts +23 -0
- package/dist/src/types/marketplace.d.ts.map +1 -0
- package/dist/src/types/marketplace.js +5 -0
- package/dist/src/types/mcp.d.ts +161 -0
- package/dist/src/types/mcp.d.ts.map +1 -0
- package/dist/src/types/mcp.js +75 -0
- package/dist/src/types/persona.d.ts +30 -0
- package/dist/src/types/persona.d.ts.map +1 -0
- package/dist/src/types/persona.js +5 -0
- package/dist/src/update/BackupManager.d.ts +46 -0
- package/dist/src/update/BackupManager.d.ts.map +1 -0
- package/dist/src/update/BackupManager.js +261 -0
- package/dist/src/update/DependencyChecker.d.ts +41 -0
- package/dist/src/update/DependencyChecker.d.ts.map +1 -0
- package/dist/src/update/DependencyChecker.js +132 -0
- package/dist/src/update/RateLimiter.d.ts +80 -0
- package/dist/src/update/RateLimiter.d.ts.map +1 -0
- package/dist/src/update/RateLimiter.js +172 -0
- package/dist/src/update/SignatureVerifier.d.ts +71 -0
- package/dist/src/update/SignatureVerifier.d.ts.map +1 -0
- package/dist/src/update/SignatureVerifier.js +214 -0
- package/dist/src/update/UpdateChecker.d.ts +127 -0
- package/dist/src/update/UpdateChecker.d.ts.map +1 -0
- package/dist/src/update/UpdateChecker.js +460 -0
- package/dist/src/update/UpdateManager.d.ts +41 -0
- package/dist/src/update/UpdateManager.d.ts.map +1 -0
- package/dist/src/update/UpdateManager.js +260 -0
- package/dist/src/update/VersionManager.d.ts +31 -0
- package/dist/src/update/VersionManager.d.ts.map +1 -0
- package/dist/src/update/VersionManager.js +134 -0
- package/dist/src/update/index.d.ts +9 -0
- package/dist/src/update/index.d.ts.map +1 -0
- package/dist/src/update/index.js +9 -0
- package/dist/src/utils/filesystem.d.ts +32 -0
- package/dist/src/utils/filesystem.d.ts.map +1 -0
- package/dist/src/utils/filesystem.js +73 -0
- package/dist/src/utils/git.d.ts +32 -0
- package/dist/src/utils/git.d.ts.map +1 -0
- package/dist/src/utils/git.js +65 -0
- package/dist/src/utils/index.d.ts +7 -0
- package/dist/src/utils/index.d.ts.map +1 -0
- package/dist/src/utils/index.js +7 -0
- package/dist/src/utils/logger.d.ts +45 -0
- package/dist/src/utils/logger.d.ts.map +1 -0
- package/dist/src/utils/logger.js +91 -0
- package/dist/src/utils/version.d.ts +25 -0
- package/dist/src/utils/version.d.ts.map +1 -0
- package/dist/src/utils/version.js +97 -0
- package/dist/test/src/cache/APICache.d.ts +23 -0
- package/dist/test/src/cache/APICache.d.ts.map +1 -0
- package/dist/test/src/cache/APICache.js +42 -0
- package/dist/test/src/cache/index.d.ts +5 -0
- package/dist/test/src/cache/index.d.ts.map +1 -0
- package/dist/test/src/cache/index.js +5 -0
- package/dist/test/src/collection/CollectionBrowser.d.ts +24 -0
- package/dist/test/src/collection/CollectionBrowser.d.ts.map +1 -0
- package/dist/test/src/collection/CollectionBrowser.js +115 -0
- package/dist/test/src/collection/CollectionSearch.d.ts +18 -0
- package/dist/test/src/collection/CollectionSearch.d.ts.map +1 -0
- package/dist/test/src/collection/CollectionSearch.js +48 -0
- package/dist/test/src/collection/GitHubClient.d.ts +22 -0
- package/dist/test/src/collection/GitHubClient.d.ts.map +1 -0
- package/dist/test/src/collection/GitHubClient.js +114 -0
- package/dist/test/src/collection/PersonaDetails.d.ts +22 -0
- package/dist/test/src/collection/PersonaDetails.d.ts.map +1 -0
- package/dist/test/src/collection/PersonaDetails.js +71 -0
- package/dist/test/src/collection/PersonaInstaller.d.ts +26 -0
- package/dist/test/src/collection/PersonaInstaller.d.ts.map +1 -0
- package/dist/test/src/collection/PersonaInstaller.js +103 -0
- package/dist/test/src/collection/PersonaSubmitter.d.ts +19 -0
- package/dist/test/src/collection/PersonaSubmitter.d.ts.map +1 -0
- package/dist/test/src/collection/PersonaSubmitter.js +57 -0
- package/dist/test/src/collection/index.d.ts +10 -0
- package/dist/test/src/collection/index.d.ts.map +1 -0
- package/dist/test/src/collection/index.js +10 -0
- package/dist/test/src/config/constants.d.ts +25 -0
- package/dist/test/src/config/constants.d.ts.map +1 -0
- package/dist/test/src/config/constants.js +30 -0
- package/dist/test/src/config/index.d.ts +6 -0
- package/dist/test/src/config/index.d.ts.map +1 -0
- package/dist/test/src/config/index.js +6 -0
- package/dist/test/src/config/indicator-config.d.ts +107 -0
- package/dist/test/src/config/indicator-config.d.ts.map +1 -0
- package/dist/test/src/config/indicator-config.js +158 -0
- package/dist/test/src/constants/defaultPersonas.d.ts +10 -0
- package/dist/test/src/constants/defaultPersonas.d.ts.map +1 -0
- package/dist/test/src/constants/defaultPersonas.js +18 -0
- package/dist/test/src/constants/limits.d.ts +10 -0
- package/dist/test/src/constants/limits.d.ts.map +1 -0
- package/dist/test/src/constants/limits.js +13 -0
- package/dist/test/src/elements/BaseElement.d.ts +81 -0
- package/dist/test/src/elements/BaseElement.d.ts.map +1 -0
- package/dist/test/src/elements/BaseElement.js +381 -0
- package/dist/test/src/elements/FeedbackProcessor.d.ts +57 -0
- package/dist/test/src/elements/FeedbackProcessor.d.ts.map +1 -0
- package/dist/test/src/elements/FeedbackProcessor.js +418 -0
- package/dist/test/src/elements/agents/Agent.d.ts +145 -0
- package/dist/test/src/elements/agents/Agent.d.ts.map +1 -0
- package/dist/test/src/elements/agents/Agent.js +848 -0
- package/dist/test/src/elements/agents/AgentManager.d.ts +125 -0
- package/dist/test/src/elements/agents/AgentManager.d.ts.map +1 -0
- package/dist/test/src/elements/agents/AgentManager.js +608 -0
- package/dist/test/src/elements/agents/constants.d.ts +42 -0
- package/dist/test/src/elements/agents/constants.d.ts.map +1 -0
- package/dist/test/src/elements/agents/constants.js +45 -0
- package/dist/test/src/elements/agents/goalTemplates.d.ts +44 -0
- package/dist/test/src/elements/agents/goalTemplates.d.ts.map +1 -0
- package/dist/test/src/elements/agents/goalTemplates.js +297 -0
- package/dist/test/src/elements/agents/index.d.ts +8 -0
- package/dist/test/src/elements/agents/index.d.ts.map +1 -0
- package/dist/test/src/elements/agents/index.js +8 -0
- package/dist/test/src/elements/agents/ruleEngineConfig.d.ts +76 -0
- package/dist/test/src/elements/agents/ruleEngineConfig.d.ts.map +1 -0
- package/dist/test/src/elements/agents/ruleEngineConfig.js +143 -0
- package/dist/test/src/elements/agents/types.d.ts +97 -0
- package/dist/test/src/elements/agents/types.d.ts.map +1 -0
- package/dist/test/src/elements/agents/types.js +5 -0
- package/dist/test/src/elements/index.d.ts +6 -0
- package/dist/test/src/elements/index.d.ts.map +1 -0
- package/dist/test/src/elements/index.js +6 -0
- package/dist/test/src/elements/memories/Memory.d.ts +110 -0
- package/dist/test/src/elements/memories/Memory.d.ts.map +1 -0
- package/dist/test/src/elements/memories/Memory.js +470 -0
- package/dist/test/src/elements/memories/MemoryManager.d.ts +86 -0
- package/dist/test/src/elements/memories/MemoryManager.d.ts.map +1 -0
- package/dist/test/src/elements/memories/MemoryManager.js +435 -0
- package/dist/test/src/elements/memories/constants.d.ts +42 -0
- package/dist/test/src/elements/memories/constants.d.ts.map +1 -0
- package/dist/test/src/elements/memories/constants.js +49 -0
- package/dist/test/src/elements/memories/index.d.ts +6 -0
- package/dist/test/src/elements/memories/index.d.ts.map +1 -0
- package/dist/test/src/elements/memories/index.js +6 -0
- package/dist/test/src/elements/skills/Skill.d.ts +109 -0
- package/dist/test/src/elements/skills/Skill.d.ts.map +1 -0
- package/dist/test/src/elements/skills/Skill.js +381 -0
- package/dist/test/src/elements/templates/Template.d.ts +138 -0
- package/dist/test/src/elements/templates/Template.d.ts.map +1 -0
- package/dist/test/src/elements/templates/Template.js +673 -0
- package/dist/test/src/elements/templates/TemplateManager.d.ts +104 -0
- package/dist/test/src/elements/templates/TemplateManager.d.ts.map +1 -0
- package/dist/test/src/elements/templates/TemplateManager.js +496 -0
- package/dist/test/src/elements/templates/index.d.ts +6 -0
- package/dist/test/src/elements/templates/index.d.ts.map +1 -0
- package/dist/test/src/elements/templates/index.js +6 -0
- package/dist/test/src/errors/SecurityError.d.ts +29 -0
- package/dist/test/src/errors/SecurityError.d.ts.map +1 -0
- package/dist/test/src/errors/SecurityError.js +47 -0
- package/dist/test/src/errors/index.d.ts +2 -0
- package/dist/test/src/errors/index.d.ts.map +1 -0
- package/dist/test/src/errors/index.js +2 -0
- package/dist/test/src/index.barrel.d.ts +21 -0
- package/dist/test/src/index.barrel.d.ts.map +1 -0
- package/dist/test/src/index.barrel.js +31 -0
- package/dist/test/src/index.d.ts +223 -0
- package/dist/test/src/index.d.ts.map +1 -0
- package/dist/test/src/index.js +1594 -0
- package/dist/test/src/marketplace/GitHubClient.d.ts +22 -0
- package/dist/test/src/marketplace/GitHubClient.d.ts.map +1 -0
- package/dist/test/src/marketplace/GitHubClient.js +112 -0
- package/dist/test/src/marketplace/MarketplaceBrowser.d.ts +21 -0
- package/dist/test/src/marketplace/MarketplaceBrowser.d.ts.map +1 -0
- package/dist/test/src/marketplace/MarketplaceBrowser.js +45 -0
- package/dist/test/src/marketplace/MarketplaceSearch.d.ts +18 -0
- package/dist/test/src/marketplace/MarketplaceSearch.d.ts.map +1 -0
- package/dist/test/src/marketplace/MarketplaceSearch.js +36 -0
- package/dist/test/src/marketplace/PersonaDetails.d.ts +22 -0
- package/dist/test/src/marketplace/PersonaDetails.d.ts.map +1 -0
- package/dist/test/src/marketplace/PersonaDetails.js +71 -0
- package/dist/test/src/marketplace/PersonaInstaller.d.ts +25 -0
- package/dist/test/src/marketplace/PersonaInstaller.d.ts.map +1 -0
- package/dist/test/src/marketplace/PersonaInstaller.js +100 -0
- package/dist/test/src/marketplace/PersonaSubmitter.d.ts +19 -0
- package/dist/test/src/marketplace/PersonaSubmitter.d.ts.map +1 -0
- package/dist/test/src/marketplace/PersonaSubmitter.js +57 -0
- package/dist/test/src/marketplace/index.d.ts +10 -0
- package/dist/test/src/marketplace/index.d.ts.map +1 -0
- package/dist/test/src/marketplace/index.js +10 -0
- package/dist/test/src/persona/PersonaElement.d.ts +64 -0
- package/dist/test/src/persona/PersonaElement.d.ts.map +1 -0
- package/dist/test/src/persona/PersonaElement.js +223 -0
- package/dist/test/src/persona/PersonaElementManager.d.ts +97 -0
- package/dist/test/src/persona/PersonaElementManager.d.ts.map +1 -0
- package/dist/test/src/persona/PersonaElementManager.js +342 -0
- package/dist/test/src/persona/PersonaLoader.d.ts +34 -0
- package/dist/test/src/persona/PersonaLoader.d.ts.map +1 -0
- package/dist/test/src/persona/PersonaLoader.js +145 -0
- package/dist/test/src/persona/PersonaManager.d.ts +112 -0
- package/dist/test/src/persona/PersonaManager.d.ts.map +1 -0
- package/dist/test/src/persona/PersonaManager.js +341 -0
- package/dist/test/src/persona/PersonaValidator.d.ts +33 -0
- package/dist/test/src/persona/PersonaValidator.d.ts.map +1 -0
- package/dist/test/src/persona/PersonaValidator.js +157 -0
- package/dist/test/src/persona/export-import/PersonaExporter.d.ts +43 -0
- package/dist/test/src/persona/export-import/PersonaExporter.d.ts.map +1 -0
- package/dist/test/src/persona/export-import/PersonaExporter.js +99 -0
- package/dist/test/src/persona/export-import/PersonaImporter.d.ts +65 -0
- package/dist/test/src/persona/export-import/PersonaImporter.d.ts.map +1 -0
- package/dist/test/src/persona/export-import/PersonaImporter.js +315 -0
- package/dist/test/src/persona/export-import/PersonaSharer.d.ts +60 -0
- package/dist/test/src/persona/export-import/PersonaSharer.d.ts.map +1 -0
- package/dist/test/src/persona/export-import/PersonaSharer.js +502 -0
- package/dist/test/src/persona/export-import/index.d.ts +10 -0
- package/dist/test/src/persona/export-import/index.d.ts.map +1 -0
- package/dist/test/src/persona/export-import/index.js +7 -0
- package/dist/test/src/persona/index.d.ts +7 -0
- package/dist/test/src/persona/index.d.ts.map +1 -0
- package/dist/test/src/persona/index.js +7 -0
- package/dist/test/src/portfolio/MigrationManager.d.ts +44 -0
- package/dist/test/src/portfolio/MigrationManager.d.ts.map +1 -0
- package/dist/test/src/portfolio/MigrationManager.js +163 -0
- package/dist/test/src/portfolio/PortfolioManager.d.ts +54 -0
- package/dist/test/src/portfolio/PortfolioManager.d.ts.map +1 -0
- package/dist/test/src/portfolio/PortfolioManager.js +224 -0
- package/dist/test/src/portfolio/types.d.ts +18 -0
- package/dist/test/src/portfolio/types.d.ts.map +1 -0
- package/dist/test/src/portfolio/types.js +13 -0
- package/dist/test/src/security/InputValidator.d.ts +80 -0
- package/dist/test/src/security/InputValidator.d.ts.map +1 -0
- package/dist/test/src/security/InputValidator.js +436 -0
- package/dist/test/src/security/audit/SecurityAuditor.d.ts +44 -0
- package/dist/test/src/security/audit/SecurityAuditor.d.ts.map +1 -0
- package/dist/test/src/security/audit/SecurityAuditor.js +274 -0
- package/dist/test/src/security/audit/config/suppressions.d.ts +34 -0
- package/dist/test/src/security/audit/config/suppressions.d.ts.map +1 -0
- package/dist/test/src/security/audit/config/suppressions.js +575 -0
- package/dist/test/src/security/audit/index.d.ts +14 -0
- package/dist/test/src/security/audit/index.d.ts.map +1 -0
- package/dist/test/src/security/audit/index.js +15 -0
- package/dist/test/src/security/audit/reporters/ConsoleReporter.d.ts +46 -0
- package/dist/test/src/security/audit/reporters/ConsoleReporter.d.ts.map +1 -0
- package/dist/test/src/security/audit/reporters/ConsoleReporter.js +174 -0
- package/dist/test/src/security/audit/reporters/JsonReporter.d.ts +13 -0
- package/dist/test/src/security/audit/reporters/JsonReporter.d.ts.map +1 -0
- package/dist/test/src/security/audit/reporters/JsonReporter.js +25 -0
- package/dist/test/src/security/audit/reporters/MarkdownReporter.d.ts +13 -0
- package/dist/test/src/security/audit/reporters/MarkdownReporter.d.ts.map +1 -0
- package/dist/test/src/security/audit/reporters/MarkdownReporter.js +79 -0
- package/dist/test/src/security/audit/rules/SecurityRules.d.ts +20 -0
- package/dist/test/src/security/audit/rules/SecurityRules.d.ts.map +1 -0
- package/dist/test/src/security/audit/rules/SecurityRules.js +244 -0
- package/dist/test/src/security/audit/scanners/CodeScanner.d.ts +47 -0
- package/dist/test/src/security/audit/scanners/CodeScanner.d.ts.map +1 -0
- package/dist/test/src/security/audit/scanners/CodeScanner.js +174 -0
- package/dist/test/src/security/audit/scanners/ConfigurationScanner.d.ts +13 -0
- package/dist/test/src/security/audit/scanners/ConfigurationScanner.d.ts.map +1 -0
- package/dist/test/src/security/audit/scanners/ConfigurationScanner.js +22 -0
- package/dist/test/src/security/audit/scanners/DependencyScanner.d.ts +13 -0
- package/dist/test/src/security/audit/scanners/DependencyScanner.d.ts.map +1 -0
- package/dist/test/src/security/audit/scanners/DependencyScanner.js +22 -0
- package/dist/test/src/security/audit/types.d.ts +94 -0
- package/dist/test/src/security/audit/types.d.ts.map +1 -0
- package/dist/test/src/security/audit/types.js +6 -0
- package/dist/test/src/security/commandValidator.d.ts +7 -0
- package/dist/test/src/security/commandValidator.d.ts.map +1 -0
- package/dist/test/src/security/commandValidator.js +78 -0
- package/dist/test/src/security/constants.d.ts +24 -0
- package/dist/test/src/security/constants.d.ts.map +1 -0
- package/dist/test/src/security/constants.js +26 -0
- package/dist/test/src/security/contentValidator.d.ts +47 -0
- package/dist/test/src/security/contentValidator.d.ts.map +1 -0
- package/dist/test/src/security/contentValidator.js +301 -0
- package/dist/test/src/security/errors.d.ts +14 -0
- package/dist/test/src/security/errors.d.ts.map +1 -0
- package/dist/test/src/security/errors.js +28 -0
- package/dist/test/src/security/fileLockManager.d.ts +70 -0
- package/dist/test/src/security/fileLockManager.d.ts.map +1 -0
- package/dist/test/src/security/fileLockManager.js +187 -0
- package/dist/test/src/security/index.d.ts +12 -0
- package/dist/test/src/security/index.d.ts.map +1 -0
- package/dist/test/src/security/index.js +14 -0
- package/dist/test/src/security/pathValidator.d.ts +9 -0
- package/dist/test/src/security/pathValidator.d.ts.map +1 -0
- package/dist/test/src/security/pathValidator.js +98 -0
- package/dist/test/src/security/regexValidator.d.ts +59 -0
- package/dist/test/src/security/regexValidator.d.ts.map +1 -0
- package/dist/test/src/security/regexValidator.js +214 -0
- package/dist/test/src/security/secureYamlParser.d.ts +46 -0
- package/dist/test/src/security/secureYamlParser.d.ts.map +1 -0
- package/dist/test/src/security/secureYamlParser.js +203 -0
- package/dist/test/src/security/securityMonitor.d.ts +58 -0
- package/dist/test/src/security/securityMonitor.d.ts.map +1 -0
- package/dist/test/src/security/securityMonitor.js +108 -0
- package/dist/test/src/security/tokenManager.d.ts +85 -0
- package/dist/test/src/security/tokenManager.d.ts.map +1 -0
- package/dist/test/src/security/tokenManager.js +286 -0
- package/dist/test/src/security/validators/unicodeValidator.d.ts +97 -0
- package/dist/test/src/security/validators/unicodeValidator.d.ts.map +1 -0
- package/dist/test/src/security/validators/unicodeValidator.js +312 -0
- package/dist/test/src/security/yamlValidator.d.ts +21 -0
- package/dist/test/src/security/yamlValidator.d.ts.map +1 -0
- package/dist/test/src/security/yamlValidator.js +164 -0
- package/dist/test/src/server/ServerSetup.d.ts +35 -0
- package/dist/test/src/server/ServerSetup.d.ts.map +1 -0
- package/dist/test/src/server/ServerSetup.js +116 -0
- package/dist/test/src/server/index.d.ts +7 -0
- package/dist/test/src/server/index.d.ts.map +1 -0
- package/dist/test/src/server/index.js +7 -0
- package/dist/test/src/server/startup.d.ts +31 -0
- package/dist/test/src/server/startup.d.ts.map +1 -0
- package/dist/test/src/server/startup.js +67 -0
- package/dist/test/src/server/tools/CollectionTools.d.ts +10 -0
- package/dist/test/src/server/tools/CollectionTools.d.ts.map +1 -0
- package/dist/test/src/server/tools/CollectionTools.js +96 -0
- package/dist/test/src/server/tools/ConfigTools.d.ts +10 -0
- package/dist/test/src/server/tools/ConfigTools.d.ts.map +1 -0
- package/dist/test/src/server/tools/ConfigTools.js +63 -0
- package/dist/test/src/server/tools/MarketplaceTools.d.ts +10 -0
- package/dist/test/src/server/tools/MarketplaceTools.d.ts.map +1 -0
- package/dist/test/src/server/tools/MarketplaceTools.js +92 -0
- package/dist/test/src/server/tools/PersonaTools.d.ts +10 -0
- package/dist/test/src/server/tools/PersonaTools.d.ts.map +1 -0
- package/dist/test/src/server/tools/PersonaTools.js +257 -0
- package/dist/test/src/server/tools/ToolRegistry.d.ts +37 -0
- package/dist/test/src/server/tools/ToolRegistry.d.ts.map +1 -0
- package/dist/test/src/server/tools/ToolRegistry.js +40 -0
- package/dist/test/src/server/tools/UpdateTools.d.ts +10 -0
- package/dist/test/src/server/tools/UpdateTools.d.ts.map +1 -0
- package/dist/test/src/server/tools/UpdateTools.js +64 -0
- package/dist/test/src/server/tools/UserTools.d.ts +10 -0
- package/dist/test/src/server/tools/UserTools.d.ts.map +1 -0
- package/dist/test/src/server/tools/UserTools.js +51 -0
- package/dist/test/src/server/tools/index.d.ts +10 -0
- package/dist/test/src/server/tools/index.d.ts.map +1 -0
- package/dist/test/src/server/tools/index.js +10 -0
- package/dist/test/src/server/types.d.ts +34 -0
- package/dist/test/src/server/types.d.ts.map +1 -0
- package/dist/test/src/server/types.js +5 -0
- package/dist/test/src/tools/debug.d.ts +20 -0
- package/dist/test/src/tools/debug.d.ts.map +1 -0
- package/dist/test/src/tools/debug.js +37 -0
- package/dist/test/src/types/cache.d.ts +8 -0
- package/dist/test/src/types/cache.d.ts.map +1 -0
- package/dist/test/src/types/cache.js +5 -0
- package/dist/test/src/types/collection.d.ts +23 -0
- package/dist/test/src/types/collection.d.ts.map +1 -0
- package/dist/test/src/types/collection.js +5 -0
- package/dist/test/src/types/elements/IElement.d.ts +123 -0
- package/dist/test/src/types/elements/IElement.d.ts.map +1 -0
- package/dist/test/src/types/elements/IElement.js +30 -0
- package/dist/test/src/types/elements/IElementManager.d.ts +65 -0
- package/dist/test/src/types/elements/IElementManager.d.ts.map +1 -0
- package/dist/test/src/types/elements/IElementManager.js +6 -0
- package/dist/test/src/types/elements/IRatingManager.d.ts +109 -0
- package/dist/test/src/types/elements/IRatingManager.d.ts.map +1 -0
- package/dist/test/src/types/elements/IRatingManager.js +6 -0
- package/dist/test/src/types/elements/IReferenceResolver.d.ts +52 -0
- package/dist/test/src/types/elements/IReferenceResolver.d.ts.map +1 -0
- package/dist/test/src/types/elements/IReferenceResolver.js +6 -0
- package/dist/test/src/types/elements/RatingBreakdowns.d.ts +49 -0
- package/dist/test/src/types/elements/RatingBreakdowns.d.ts.map +1 -0
- package/dist/test/src/types/elements/RatingBreakdowns.js +6 -0
- package/dist/test/src/types/elements/index.d.ts +9 -0
- package/dist/test/src/types/elements/index.d.ts.map +1 -0
- package/dist/test/src/types/elements/index.js +11 -0
- package/dist/test/src/types/index.d.ts +9 -0
- package/dist/test/src/types/index.d.ts.map +1 -0
- package/dist/test/src/types/index.js +9 -0
- package/dist/test/src/types/marketplace.d.ts +23 -0
- package/dist/test/src/types/marketplace.d.ts.map +1 -0
- package/dist/test/src/types/marketplace.js +5 -0
- package/dist/test/src/types/mcp.d.ts +84 -0
- package/dist/test/src/types/mcp.d.ts.map +1 -0
- package/dist/test/src/types/mcp.js +80 -0
- package/dist/test/src/types/persona.d.ts +30 -0
- package/dist/test/src/types/persona.d.ts.map +1 -0
- package/dist/test/src/types/persona.js +5 -0
- package/dist/test/src/update/BackupManager.d.ts +46 -0
- package/dist/test/src/update/BackupManager.d.ts.map +1 -0
- package/dist/test/src/update/BackupManager.js +261 -0
- package/dist/test/src/update/DependencyChecker.d.ts +41 -0
- package/dist/test/src/update/DependencyChecker.d.ts.map +1 -0
- package/dist/test/src/update/DependencyChecker.js +132 -0
- package/dist/test/src/update/RateLimiter.d.ts +80 -0
- package/dist/test/src/update/RateLimiter.d.ts.map +1 -0
- package/dist/test/src/update/RateLimiter.js +172 -0
- package/dist/test/src/update/SignatureVerifier.d.ts +71 -0
- package/dist/test/src/update/SignatureVerifier.d.ts.map +1 -0
- package/dist/test/src/update/SignatureVerifier.js +214 -0
- package/dist/test/src/update/UpdateChecker.d.ts +127 -0
- package/dist/test/src/update/UpdateChecker.d.ts.map +1 -0
- package/dist/test/src/update/UpdateChecker.js +469 -0
- package/dist/test/src/update/UpdateManager.d.ts +41 -0
- package/dist/test/src/update/UpdateManager.d.ts.map +1 -0
- package/dist/test/src/update/UpdateManager.js +260 -0
- package/dist/test/src/update/VersionManager.d.ts +31 -0
- package/dist/test/src/update/VersionManager.d.ts.map +1 -0
- package/dist/test/src/update/VersionManager.js +134 -0
- package/dist/test/src/update/index.d.ts +9 -0
- package/dist/test/src/update/index.d.ts.map +1 -0
- package/dist/test/src/update/index.js +9 -0
- package/dist/test/src/utils/filesystem.d.ts +29 -0
- package/dist/test/src/utils/filesystem.d.ts.map +1 -0
- package/dist/test/src/utils/filesystem.js +94 -0
- package/dist/test/src/utils/git.d.ts +32 -0
- package/dist/test/src/utils/git.d.ts.map +1 -0
- package/dist/test/src/utils/git.js +65 -0
- package/dist/test/src/utils/index.d.ts +7 -0
- package/dist/test/src/utils/index.d.ts.map +1 -0
- package/dist/test/src/utils/index.js +7 -0
- package/dist/test/src/utils/logger.d.ts +45 -0
- package/dist/test/src/utils/logger.d.ts.map +1 -0
- package/dist/test/src/utils/logger.js +91 -0
- package/dist/test/src/utils/version.d.ts +25 -0
- package/dist/test/src/utils/version.d.ts.map +1 -0
- package/dist/test/src/utils/version.js +97 -0
- package/dist/test/test/__tests__/integration/helpers/file-utils.d.ts +33 -0
- package/dist/test/test/__tests__/integration/helpers/file-utils.d.ts.map +1 -0
- package/dist/test/test/__tests__/integration/helpers/file-utils.js +83 -0
- package/dist/test/test/__tests__/integration/helpers/test-fixtures.d.ts +26 -0
- package/dist/test/test/__tests__/integration/helpers/test-fixtures.d.ts.map +1 -0
- package/dist/test/test/__tests__/integration/helpers/test-fixtures.js +95 -0
- package/dist/test/test/__tests__/integration/helpers/test-server.d.ts +26 -0
- package/dist/test/test/__tests__/integration/helpers/test-server.d.ts.map +1 -0
- package/dist/test/test/__tests__/integration/helpers/test-server.js +41 -0
- package/dist/test/test/__tests__/integration/setup.d.ts +8 -0
- package/dist/test/test/__tests__/integration/setup.d.ts.map +1 -0
- package/dist/test/test/__tests__/integration/setup.js +31 -0
- package/dist/test/test/__tests__/integration/teardown.d.ts +5 -0
- package/dist/test/test/__tests__/integration/teardown.d.ts.map +1 -0
- package/dist/test/test/__tests__/integration/teardown.js +23 -0
- package/dist/test/test/__tests__/security/framework/RapidSecurityTesting.d.ts +34 -0
- package/dist/test/test/__tests__/security/framework/RapidSecurityTesting.d.ts.map +1 -0
- package/dist/test/test/__tests__/security/framework/RapidSecurityTesting.js +224 -0
- package/dist/test/test/__tests__/security/framework/SecurityTestFramework.d.ts +89 -0
- package/dist/test/test/__tests__/security/framework/SecurityTestFramework.d.ts.map +1 -0
- package/dist/test/test/__tests__/security/framework/SecurityTestFramework.js +543 -0
- package/dist/test/test/__tests__/security/index.d.ts +46 -0
- package/dist/test/test/__tests__/security/index.d.ts.map +1 -0
- package/dist/test/test/__tests__/security/index.js +98 -0
- package/dist/test/test/__tests__/security/setup.d.ts +3 -0
- package/dist/test/test/__tests__/security/setup.d.ts.map +1 -0
- package/dist/test/test/__tests__/security/setup.js +23 -0
- package/dist/tools/debug.d.ts +20 -0
- package/dist/tools/debug.d.ts.map +1 -0
- package/dist/tools/debug.js +37 -0
- package/dist/types/cache.d.ts +8 -0
- package/dist/types/cache.d.ts.map +1 -0
- package/dist/types/cache.js +5 -0
- package/dist/types/collection.d.ts +23 -0
- package/dist/types/collection.d.ts.map +1 -0
- package/dist/types/collection.js +5 -0
- package/dist/types/elements/IElement.d.ts +123 -0
- package/dist/types/elements/IElement.d.ts.map +1 -0
- package/dist/types/elements/IElement.js +30 -0
- package/dist/types/elements/IElementManager.d.ts +65 -0
- package/dist/types/elements/IElementManager.d.ts.map +1 -0
- package/dist/types/elements/IElementManager.js +6 -0
- package/dist/types/elements/IRatingManager.d.ts +109 -0
- package/dist/types/elements/IRatingManager.d.ts.map +1 -0
- package/dist/types/elements/IRatingManager.js +6 -0
- package/dist/types/elements/IReferenceResolver.d.ts +52 -0
- package/dist/types/elements/IReferenceResolver.d.ts.map +1 -0
- package/dist/types/elements/IReferenceResolver.js +6 -0
- package/dist/types/elements/RatingBreakdowns.d.ts +49 -0
- package/dist/types/elements/RatingBreakdowns.d.ts.map +1 -0
- package/dist/types/elements/RatingBreakdowns.js +6 -0
- package/dist/types/elements/index.d.ts +9 -0
- package/dist/types/elements/index.d.ts.map +1 -0
- package/dist/types/elements/index.js +11 -0
- package/dist/types/index.d.ts +9 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +9 -0
- package/dist/types/marketplace.d.ts +23 -0
- package/dist/types/marketplace.d.ts.map +1 -0
- package/dist/types/marketplace.js +5 -0
- package/dist/types/mcp.d.ts +84 -0
- package/dist/types/mcp.d.ts.map +1 -0
- package/dist/types/mcp.js +80 -0
- package/dist/types/persona.d.ts +30 -0
- package/dist/types/persona.d.ts.map +1 -0
- package/dist/types/persona.js +5 -0
- package/dist/update/BackupManager.d.ts +46 -0
- package/dist/update/BackupManager.d.ts.map +1 -0
- package/dist/update/BackupManager.js +261 -0
- package/dist/update/DependencyChecker.d.ts +41 -0
- package/dist/update/DependencyChecker.d.ts.map +1 -0
- package/dist/update/DependencyChecker.js +132 -0
- package/dist/update/RateLimiter.d.ts +80 -0
- package/dist/update/RateLimiter.d.ts.map +1 -0
- package/dist/update/RateLimiter.js +172 -0
- package/dist/update/SignatureVerifier.d.ts +71 -0
- package/dist/update/SignatureVerifier.d.ts.map +1 -0
- package/dist/update/SignatureVerifier.js +214 -0
- package/dist/update/UpdateChecker.d.ts +127 -0
- package/dist/update/UpdateChecker.d.ts.map +1 -0
- package/dist/update/UpdateChecker.js +469 -0
- package/dist/update/UpdateManager.d.ts +41 -0
- package/dist/update/UpdateManager.d.ts.map +1 -0
- package/dist/update/UpdateManager.js +260 -0
- package/dist/update/VersionManager.d.ts +31 -0
- package/dist/update/VersionManager.d.ts.map +1 -0
- package/dist/update/VersionManager.js +134 -0
- package/dist/update/index.d.ts +9 -0
- package/dist/update/index.d.ts.map +1 -0
- package/dist/update/index.js +9 -0
- package/dist/utils/filesystem.d.ts +29 -0
- package/dist/utils/filesystem.d.ts.map +1 -0
- package/dist/utils/filesystem.js +94 -0
- package/dist/utils/git.d.ts +32 -0
- package/dist/utils/git.d.ts.map +1 -0
- package/dist/utils/git.js +65 -0
- package/dist/utils/index.d.ts +7 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +7 -0
- package/dist/utils/logger.d.ts +45 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +91 -0
- package/dist/utils/version.d.ts +25 -0
- package/dist/utils/version.d.ts.map +1 -0
- package/dist/utils/version.js +97 -0
- package/package.json +128 -0
|
@@ -0,0 +1,860 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ensemble Element - Orchestrates multiple elements working together
|
|
3
|
+
*
|
|
4
|
+
* Ensembles allow combining multiple elements (personas, skills, templates, agents, memories)
|
|
5
|
+
* into cohesive units with controlled activation, conflict resolution, and shared context.
|
|
6
|
+
*
|
|
7
|
+
* SECURITY MEASURES IMPLEMENTED:
|
|
8
|
+
* 1. Circular dependency detection with path tracking
|
|
9
|
+
* 2. Resource limits (max elements, nesting depth, activation time)
|
|
10
|
+
* 3. Input sanitization for all user-provided data
|
|
11
|
+
* 4. Activation timeout protection
|
|
12
|
+
* 5. Context size limits to prevent memory exhaustion
|
|
13
|
+
* 6. Audit logging for security events
|
|
14
|
+
* 7. Condition validation to prevent code injection
|
|
15
|
+
*/
|
|
16
|
+
import { BaseElement } from '../BaseElement.js';
|
|
17
|
+
import { ElementType } from '../../portfolio/types.js';
|
|
18
|
+
import { PortfolioManager } from '../../portfolio/PortfolioManager.js';
|
|
19
|
+
import { sanitizeInput } from '../../security/InputValidator.js';
|
|
20
|
+
import { UnicodeValidator } from '../../security/validators/unicodeValidator.js';
|
|
21
|
+
import { SecurityMonitor } from '../../security/securityMonitor.js';
|
|
22
|
+
import { logger } from '../../utils/logger.js';
|
|
23
|
+
import { ENSEMBLE_LIMITS, ENSEMBLE_DEFAULTS, ACTIVATION_STRATEGIES, CONFLICT_STRATEGIES, ELEMENT_ROLES, ENSEMBLE_SECURITY_EVENTS, ENSEMBLE_ERRORS, ENSEMBLE_PATTERNS } from './constants.js';
|
|
24
|
+
export class Ensemble extends BaseElement {
|
|
25
|
+
elements = new Map();
|
|
26
|
+
elementInstances = new Map();
|
|
27
|
+
sharedContext;
|
|
28
|
+
activationInProgress = false;
|
|
29
|
+
lastActivationResult;
|
|
30
|
+
constructor(metadata = {}) {
|
|
31
|
+
// SECURITY FIX: Sanitize all inputs during construction
|
|
32
|
+
const sanitizedMetadata = {
|
|
33
|
+
...metadata,
|
|
34
|
+
name: metadata.name ? sanitizeInput(UnicodeValidator.normalize(metadata.name).normalizedContent, 100) : undefined,
|
|
35
|
+
description: metadata.description ? sanitizeInput(UnicodeValidator.normalize(metadata.description).normalizedContent, 500) : undefined,
|
|
36
|
+
activationStrategy: metadata.activationStrategy || ENSEMBLE_DEFAULTS.ACTIVATION_STRATEGY,
|
|
37
|
+
conflictResolution: metadata.conflictResolution || ENSEMBLE_DEFAULTS.CONFLICT_RESOLUTION,
|
|
38
|
+
maxElements: metadata.maxElements ?? ENSEMBLE_LIMITS.MAX_ELEMENTS,
|
|
39
|
+
maxActivationTime: metadata.maxActivationTime ?? ENSEMBLE_LIMITS.MAX_ACTIVATION_TIME,
|
|
40
|
+
allowNested: metadata.allowNested ?? ENSEMBLE_DEFAULTS.ALLOW_NESTED,
|
|
41
|
+
maxNestingDepth: metadata.maxNestingDepth ?? ENSEMBLE_LIMITS.MAX_NESTING_DEPTH
|
|
42
|
+
};
|
|
43
|
+
// Validate activation strategy
|
|
44
|
+
if (!ACTIVATION_STRATEGIES.includes(sanitizedMetadata.activationStrategy)) {
|
|
45
|
+
throw new Error(ENSEMBLE_ERRORS.INVALID_STRATEGY);
|
|
46
|
+
}
|
|
47
|
+
// Validate conflict resolution strategy
|
|
48
|
+
if (!CONFLICT_STRATEGIES.includes(sanitizedMetadata.conflictResolution)) {
|
|
49
|
+
throw new Error(ENSEMBLE_ERRORS.INVALID_CONFLICT_RESOLUTION);
|
|
50
|
+
}
|
|
51
|
+
// Validate limits
|
|
52
|
+
if (sanitizedMetadata.maxElements > ENSEMBLE_LIMITS.MAX_ELEMENTS) {
|
|
53
|
+
throw new Error(ENSEMBLE_ERRORS.TOO_MANY_ELEMENTS);
|
|
54
|
+
}
|
|
55
|
+
if (sanitizedMetadata.maxNestingDepth > ENSEMBLE_LIMITS.MAX_NESTING_DEPTH) {
|
|
56
|
+
throw new Error(ENSEMBLE_ERRORS.NESTING_TOO_DEEP);
|
|
57
|
+
}
|
|
58
|
+
super(ElementType.ENSEMBLE, sanitizedMetadata);
|
|
59
|
+
// Ensure ensemble-specific metadata is stored
|
|
60
|
+
this.metadata = {
|
|
61
|
+
...this.metadata,
|
|
62
|
+
activationStrategy: sanitizedMetadata.activationStrategy,
|
|
63
|
+
conflictResolution: sanitizedMetadata.conflictResolution,
|
|
64
|
+
maxElements: sanitizedMetadata.maxElements,
|
|
65
|
+
maxActivationTime: sanitizedMetadata.maxActivationTime,
|
|
66
|
+
allowNested: sanitizedMetadata.allowNested,
|
|
67
|
+
maxNestingDepth: sanitizedMetadata.maxNestingDepth
|
|
68
|
+
};
|
|
69
|
+
// Initialize shared context
|
|
70
|
+
this.sharedContext = {
|
|
71
|
+
values: new Map(),
|
|
72
|
+
owners: new Map(),
|
|
73
|
+
timestamps: new Map()
|
|
74
|
+
};
|
|
75
|
+
// Set ensemble-specific extensions
|
|
76
|
+
this.extensions = {
|
|
77
|
+
elementCount: 0,
|
|
78
|
+
activationStrategy: sanitizedMetadata.activationStrategy,
|
|
79
|
+
conflictResolution: sanitizedMetadata.conflictResolution,
|
|
80
|
+
lastActivation: null
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Add an element to the ensemble
|
|
85
|
+
*/
|
|
86
|
+
addElement(elementId, elementType, role = ENSEMBLE_DEFAULTS.ELEMENT_ROLE, options = {}) {
|
|
87
|
+
// Check element limit
|
|
88
|
+
if (this.elements.size >= this.metadata.maxElements) {
|
|
89
|
+
SecurityMonitor.logSecurityEvent({
|
|
90
|
+
type: ENSEMBLE_SECURITY_EVENTS.RESOURCE_LIMIT_EXCEEDED,
|
|
91
|
+
severity: 'MEDIUM',
|
|
92
|
+
source: 'Ensemble.addElement',
|
|
93
|
+
details: `Maximum elements (${ENSEMBLE_LIMITS.MAX_ELEMENTS}) exceeded`
|
|
94
|
+
});
|
|
95
|
+
throw new Error(ENSEMBLE_ERRORS.TOO_MANY_ELEMENTS);
|
|
96
|
+
}
|
|
97
|
+
// Sanitize element ID
|
|
98
|
+
const sanitizedId = sanitizeInput(elementId, 100);
|
|
99
|
+
if (!ENSEMBLE_PATTERNS.ELEMENT_ID_PATTERN.test(sanitizedId)) {
|
|
100
|
+
throw new Error('Invalid element ID format');
|
|
101
|
+
}
|
|
102
|
+
// Validate role
|
|
103
|
+
if (!ELEMENT_ROLES.includes(role)) {
|
|
104
|
+
throw new Error('Invalid element role');
|
|
105
|
+
}
|
|
106
|
+
// Validate activation condition if provided
|
|
107
|
+
if (options.activationCondition) {
|
|
108
|
+
const sanitizedCondition = sanitizeInput(options.activationCondition, ENSEMBLE_LIMITS.MAX_CONDITION_LENGTH);
|
|
109
|
+
if (!this.isValidCondition(sanitizedCondition)) {
|
|
110
|
+
SecurityMonitor.logSecurityEvent({
|
|
111
|
+
type: ENSEMBLE_SECURITY_EVENTS.SUSPICIOUS_CONDITION,
|
|
112
|
+
severity: 'HIGH',
|
|
113
|
+
source: 'Ensemble.addElement',
|
|
114
|
+
details: `Suspicious activation condition: ${sanitizedCondition}`
|
|
115
|
+
});
|
|
116
|
+
throw new Error('Invalid activation condition syntax');
|
|
117
|
+
}
|
|
118
|
+
options.activationCondition = sanitizedCondition;
|
|
119
|
+
}
|
|
120
|
+
// Validate dependencies
|
|
121
|
+
if (options.dependencies) {
|
|
122
|
+
if (options.dependencies.length > ENSEMBLE_LIMITS.MAX_DEPENDENCIES) {
|
|
123
|
+
throw new Error(`Too many dependencies (max: ${ENSEMBLE_LIMITS.MAX_DEPENDENCIES})`);
|
|
124
|
+
}
|
|
125
|
+
// Sanitize each dependency
|
|
126
|
+
options.dependencies = options.dependencies.map(dep => sanitizeInput(dep, 100));
|
|
127
|
+
}
|
|
128
|
+
// Create ensemble element
|
|
129
|
+
const ensembleElement = {
|
|
130
|
+
elementId: sanitizedId,
|
|
131
|
+
elementType: sanitizeInput(elementType, 50),
|
|
132
|
+
role,
|
|
133
|
+
priority: options.priority ?? ENSEMBLE_DEFAULTS.PRIORITY,
|
|
134
|
+
activationCondition: options.activationCondition,
|
|
135
|
+
dependencies: options.dependencies
|
|
136
|
+
};
|
|
137
|
+
// Check for circular dependencies before adding
|
|
138
|
+
if (this.wouldCreateCircularDependency(sanitizedId, options.dependencies || [])) {
|
|
139
|
+
const circular = this.findCircularDependency(sanitizedId, options.dependencies || []);
|
|
140
|
+
SecurityMonitor.logSecurityEvent({
|
|
141
|
+
type: ENSEMBLE_SECURITY_EVENTS.CIRCULAR_DEPENDENCY,
|
|
142
|
+
severity: 'HIGH',
|
|
143
|
+
source: 'Ensemble.addElement',
|
|
144
|
+
details: `Circular dependency detected: ${circular.path.join(' -> ')}`
|
|
145
|
+
});
|
|
146
|
+
throw new Error(`${ENSEMBLE_ERRORS.CIRCULAR_DEPENDENCY}: ${circular.message}`);
|
|
147
|
+
}
|
|
148
|
+
this.elements.set(sanitizedId, ensembleElement);
|
|
149
|
+
this.extensions.elementCount = this.elements.size;
|
|
150
|
+
this.markDirty();
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Remove an element from the ensemble
|
|
154
|
+
*/
|
|
155
|
+
removeElement(elementId) {
|
|
156
|
+
const sanitizedId = sanitizeInput(elementId, 100);
|
|
157
|
+
if (!this.elements.has(sanitizedId)) {
|
|
158
|
+
throw new Error(ENSEMBLE_ERRORS.ELEMENT_NOT_FOUND);
|
|
159
|
+
}
|
|
160
|
+
// Remove element and its instance
|
|
161
|
+
this.elements.delete(sanitizedId);
|
|
162
|
+
this.elementInstances.delete(sanitizedId);
|
|
163
|
+
// Clean up dependencies pointing to this element
|
|
164
|
+
for (const [id, element] of this.elements) {
|
|
165
|
+
if (element.dependencies?.includes(sanitizedId)) {
|
|
166
|
+
element.dependencies = element.dependencies.filter(dep => dep !== sanitizedId);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
// Clean up shared context owned by this element
|
|
170
|
+
for (const [key, owner] of this.sharedContext.owners) {
|
|
171
|
+
if (owner === sanitizedId) {
|
|
172
|
+
this.sharedContext.values.delete(key);
|
|
173
|
+
this.sharedContext.owners.delete(key);
|
|
174
|
+
this.sharedContext.timestamps.delete(key);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
this.extensions.elementCount = this.elements.size;
|
|
178
|
+
this.markDirty();
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Activate the ensemble and all its elements based on strategy
|
|
182
|
+
*/
|
|
183
|
+
async activate() {
|
|
184
|
+
if (this.activationInProgress) {
|
|
185
|
+
throw new Error('Activation already in progress');
|
|
186
|
+
}
|
|
187
|
+
this.activationInProgress = true;
|
|
188
|
+
const startTime = Date.now();
|
|
189
|
+
const metadata = this.metadata;
|
|
190
|
+
try {
|
|
191
|
+
// Set status
|
|
192
|
+
this._status = 'active';
|
|
193
|
+
const result = {
|
|
194
|
+
success: true,
|
|
195
|
+
activatedElements: [],
|
|
196
|
+
failedElements: [],
|
|
197
|
+
conflicts: [],
|
|
198
|
+
totalDuration: 0,
|
|
199
|
+
elementResults: []
|
|
200
|
+
};
|
|
201
|
+
// Get activation order based on strategy
|
|
202
|
+
const activationOrder = this.getActivationOrder();
|
|
203
|
+
// Activate elements according to strategy
|
|
204
|
+
switch (metadata.activationStrategy) {
|
|
205
|
+
case 'sequential':
|
|
206
|
+
await this.activateSequential(activationOrder, result, metadata.maxActivationTime);
|
|
207
|
+
break;
|
|
208
|
+
case 'all':
|
|
209
|
+
// Activate all elements simultaneously as one unified entity
|
|
210
|
+
// Elements are layered/combined rather than acting separately
|
|
211
|
+
await this.activateAll(activationOrder, result, metadata.maxActivationTime);
|
|
212
|
+
break;
|
|
213
|
+
case 'priority':
|
|
214
|
+
await this.activatePriority(activationOrder, result, metadata.maxActivationTime);
|
|
215
|
+
break;
|
|
216
|
+
case 'conditional':
|
|
217
|
+
await this.activateConditional(activationOrder, result, metadata.maxActivationTime);
|
|
218
|
+
break;
|
|
219
|
+
case 'lazy':
|
|
220
|
+
// Lazy activation happens on-demand, just mark as ready
|
|
221
|
+
logger.info(`Ensemble ${this.id} ready for lazy activation`);
|
|
222
|
+
break;
|
|
223
|
+
}
|
|
224
|
+
result.totalDuration = Date.now() - startTime;
|
|
225
|
+
this.lastActivationResult = result;
|
|
226
|
+
this.extensions.lastActivation = new Date().toISOString();
|
|
227
|
+
if (result.failedElements.length > 0) {
|
|
228
|
+
logger.warn(`Ensemble activation completed with failures: ${result.failedElements.join(', ')}`);
|
|
229
|
+
}
|
|
230
|
+
else {
|
|
231
|
+
logger.info(`Ensemble ${this.id} activated successfully in ${result.totalDuration}ms`);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
catch (error) {
|
|
235
|
+
this._status = 'error';
|
|
236
|
+
throw error;
|
|
237
|
+
}
|
|
238
|
+
finally {
|
|
239
|
+
this.activationInProgress = false;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Deactivate the ensemble and all its elements
|
|
244
|
+
*/
|
|
245
|
+
async deactivate() {
|
|
246
|
+
this._status = 'inactive';
|
|
247
|
+
// Deactivate all element instances
|
|
248
|
+
const deactivationPromises = [];
|
|
249
|
+
for (const [elementId, instance] of this.elementInstances) {
|
|
250
|
+
if (instance.deactivate) {
|
|
251
|
+
deactivationPromises.push(instance.deactivate().catch(error => {
|
|
252
|
+
logger.error(`Failed to deactivate element ${elementId}:`, error);
|
|
253
|
+
}));
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
await Promise.all(deactivationPromises);
|
|
257
|
+
// Clear shared context
|
|
258
|
+
this.sharedContext.values.clear();
|
|
259
|
+
this.sharedContext.owners.clear();
|
|
260
|
+
this.sharedContext.timestamps.clear();
|
|
261
|
+
logger.info(`Ensemble ${this.id} deactivated`);
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Validate the ensemble configuration
|
|
265
|
+
*/
|
|
266
|
+
validate() {
|
|
267
|
+
const result = super.validate();
|
|
268
|
+
// Initialize arrays if they don't exist
|
|
269
|
+
if (!result.errors)
|
|
270
|
+
result.errors = [];
|
|
271
|
+
if (!result.warnings)
|
|
272
|
+
result.warnings = [];
|
|
273
|
+
// Check for circular dependencies
|
|
274
|
+
const circular = this.detectAllCircularDependencies();
|
|
275
|
+
if (circular.length > 0) {
|
|
276
|
+
for (const cycle of circular) {
|
|
277
|
+
result.errors.push({
|
|
278
|
+
field: 'dependencies',
|
|
279
|
+
message: cycle.message,
|
|
280
|
+
severity: 'high'
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
// Validate element count
|
|
285
|
+
if (this.elements.size === 0) {
|
|
286
|
+
result.warnings.push({
|
|
287
|
+
field: 'elements',
|
|
288
|
+
message: 'Ensemble has no elements',
|
|
289
|
+
suggestion: 'Add elements using addElement()'
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
// Check for orphaned dependencies
|
|
293
|
+
for (const [elementId, element] of this.elements) {
|
|
294
|
+
if (element.dependencies) {
|
|
295
|
+
for (const dep of element.dependencies) {
|
|
296
|
+
if (!this.elements.has(dep)) {
|
|
297
|
+
result.errors.push({
|
|
298
|
+
field: `${elementId}.dependencies`,
|
|
299
|
+
message: `Dependency '${dep}' not found in ensemble`,
|
|
300
|
+
severity: 'medium'
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
// Update valid flag based on errors
|
|
307
|
+
result.valid = result.errors.length === 0;
|
|
308
|
+
// Clean up empty arrays
|
|
309
|
+
if (result.errors.length === 0)
|
|
310
|
+
result.errors = undefined;
|
|
311
|
+
if (result.warnings.length === 0)
|
|
312
|
+
result.warnings = undefined;
|
|
313
|
+
return result;
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Check if adding an element would create a circular dependency
|
|
317
|
+
* MEDIUM FIX: Remove type safety bypass
|
|
318
|
+
* Previously: Used 'as any' which bypasses TypeScript checking
|
|
319
|
+
* Now: Creates proper EnsembleElement with all required fields
|
|
320
|
+
*/
|
|
321
|
+
wouldCreateCircularDependency(elementId, dependencies) {
|
|
322
|
+
// Create temporary graph with new element
|
|
323
|
+
const tempGraph = new Map(this.elements);
|
|
324
|
+
// Create a minimal valid EnsembleElement for dependency checking
|
|
325
|
+
const tempElement = {
|
|
326
|
+
elementId,
|
|
327
|
+
elementType: 'unknown', // Type doesn't matter for dependency checking
|
|
328
|
+
role: 'support', // Default role
|
|
329
|
+
dependencies
|
|
330
|
+
};
|
|
331
|
+
tempGraph.set(elementId, tempElement);
|
|
332
|
+
// Check for cycles
|
|
333
|
+
return this.hasCycle(tempGraph);
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* Find circular dependency path
|
|
337
|
+
*/
|
|
338
|
+
findCircularDependency(elementId, dependencies) {
|
|
339
|
+
const visited = new Set();
|
|
340
|
+
const recursionStack = new Set();
|
|
341
|
+
const path = [];
|
|
342
|
+
const dfs = (node) => {
|
|
343
|
+
visited.add(node);
|
|
344
|
+
recursionStack.add(node);
|
|
345
|
+
path.push(node);
|
|
346
|
+
const element = this.elements.get(node);
|
|
347
|
+
const deps = node === elementId ? dependencies : (element?.dependencies || []);
|
|
348
|
+
for (const dep of deps) {
|
|
349
|
+
if (!visited.has(dep)) {
|
|
350
|
+
const cycle = dfs(dep);
|
|
351
|
+
if (cycle)
|
|
352
|
+
return cycle;
|
|
353
|
+
}
|
|
354
|
+
else if (recursionStack.has(dep)) {
|
|
355
|
+
// Found cycle
|
|
356
|
+
const cycleStart = path.indexOf(dep);
|
|
357
|
+
return path.slice(cycleStart).concat(dep);
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
path.pop();
|
|
361
|
+
recursionStack.delete(node);
|
|
362
|
+
return null;
|
|
363
|
+
};
|
|
364
|
+
const cyclePath = dfs(elementId) || [];
|
|
365
|
+
return {
|
|
366
|
+
path: cyclePath,
|
|
367
|
+
message: `Circular dependency: ${cyclePath.join(' -> ')}`
|
|
368
|
+
};
|
|
369
|
+
}
|
|
370
|
+
/**
|
|
371
|
+
* Detect all circular dependencies in the ensemble
|
|
372
|
+
*/
|
|
373
|
+
detectAllCircularDependencies() {
|
|
374
|
+
const cycles = [];
|
|
375
|
+
const visited = new Set();
|
|
376
|
+
for (const elementId of this.elements.keys()) {
|
|
377
|
+
if (!visited.has(elementId) && this.hasCycleFrom(elementId, visited)) {
|
|
378
|
+
const cycle = this.findCircularDependency(elementId, this.elements.get(elementId).dependencies || []);
|
|
379
|
+
cycles.push(cycle);
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
return cycles;
|
|
383
|
+
}
|
|
384
|
+
/**
|
|
385
|
+
* Check if graph has any cycle
|
|
386
|
+
*/
|
|
387
|
+
hasCycle(graph) {
|
|
388
|
+
const visited = new Set();
|
|
389
|
+
const recursionStack = new Set();
|
|
390
|
+
const hasCycleDFS = (node) => {
|
|
391
|
+
visited.add(node);
|
|
392
|
+
recursionStack.add(node);
|
|
393
|
+
const element = graph.get(node);
|
|
394
|
+
const dependencies = element?.dependencies || [];
|
|
395
|
+
for (const dep of dependencies) {
|
|
396
|
+
if (!visited.has(dep)) {
|
|
397
|
+
if (hasCycleDFS(dep))
|
|
398
|
+
return true;
|
|
399
|
+
}
|
|
400
|
+
else if (recursionStack.has(dep)) {
|
|
401
|
+
return true;
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
recursionStack.delete(node);
|
|
405
|
+
return false;
|
|
406
|
+
};
|
|
407
|
+
for (const node of graph.keys()) {
|
|
408
|
+
if (!visited.has(node) && hasCycleDFS(node)) {
|
|
409
|
+
return true;
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
return false;
|
|
413
|
+
}
|
|
414
|
+
/**
|
|
415
|
+
* Check for cycle starting from a specific node
|
|
416
|
+
*/
|
|
417
|
+
hasCycleFrom(node, visited) {
|
|
418
|
+
const recursionStack = new Set();
|
|
419
|
+
const dfs = (current) => {
|
|
420
|
+
visited.add(current);
|
|
421
|
+
recursionStack.add(current);
|
|
422
|
+
const element = this.elements.get(current);
|
|
423
|
+
const dependencies = element?.dependencies || [];
|
|
424
|
+
for (const dep of dependencies) {
|
|
425
|
+
if (!visited.has(dep)) {
|
|
426
|
+
if (dfs(dep))
|
|
427
|
+
return true;
|
|
428
|
+
}
|
|
429
|
+
else if (recursionStack.has(dep)) {
|
|
430
|
+
return true;
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
recursionStack.delete(current);
|
|
434
|
+
return false;
|
|
435
|
+
};
|
|
436
|
+
return dfs(node);
|
|
437
|
+
}
|
|
438
|
+
/**
|
|
439
|
+
* Validate activation condition syntax
|
|
440
|
+
*/
|
|
441
|
+
isValidCondition(condition) {
|
|
442
|
+
// For now, only allow simple conditions
|
|
443
|
+
// Future: implement a proper condition parser
|
|
444
|
+
return ENSEMBLE_PATTERNS.CONDITION_PATTERN.test(condition);
|
|
445
|
+
}
|
|
446
|
+
/**
|
|
447
|
+
* Get activation order based on dependencies and strategy
|
|
448
|
+
*/
|
|
449
|
+
getActivationOrder() {
|
|
450
|
+
const order = [];
|
|
451
|
+
const visited = new Set();
|
|
452
|
+
// Topological sort for dependency order
|
|
453
|
+
const visit = (elementId) => {
|
|
454
|
+
if (visited.has(elementId))
|
|
455
|
+
return;
|
|
456
|
+
visited.add(elementId);
|
|
457
|
+
const element = this.elements.get(elementId);
|
|
458
|
+
if (element?.dependencies) {
|
|
459
|
+
for (const dep of element.dependencies) {
|
|
460
|
+
if (this.elements.has(dep)) {
|
|
461
|
+
visit(dep);
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
order.push(elementId);
|
|
466
|
+
};
|
|
467
|
+
// Visit all elements
|
|
468
|
+
for (const elementId of this.elements.keys()) {
|
|
469
|
+
visit(elementId);
|
|
470
|
+
}
|
|
471
|
+
return order;
|
|
472
|
+
}
|
|
473
|
+
/**
|
|
474
|
+
* Activate elements sequentially
|
|
475
|
+
*/
|
|
476
|
+
async activateSequential(order, result, maxTime) {
|
|
477
|
+
const startTime = Date.now();
|
|
478
|
+
for (const elementId of order) {
|
|
479
|
+
if (Date.now() - startTime > maxTime) {
|
|
480
|
+
SecurityMonitor.logSecurityEvent({
|
|
481
|
+
type: ENSEMBLE_SECURITY_EVENTS.ACTIVATION_TIMEOUT,
|
|
482
|
+
severity: 'HIGH',
|
|
483
|
+
source: 'Ensemble.activateSequential',
|
|
484
|
+
details: `Activation timeout after ${Date.now() - startTime}ms`
|
|
485
|
+
});
|
|
486
|
+
throw new Error(ENSEMBLE_ERRORS.ACTIVATION_TIMEOUT);
|
|
487
|
+
}
|
|
488
|
+
const elementResult = await this.activateElement(elementId);
|
|
489
|
+
result.elementResults.push(elementResult);
|
|
490
|
+
if (elementResult.success) {
|
|
491
|
+
result.activatedElements.push(elementId);
|
|
492
|
+
}
|
|
493
|
+
else {
|
|
494
|
+
result.failedElements.push(elementId);
|
|
495
|
+
}
|
|
496
|
+
// Small delay between activations
|
|
497
|
+
await new Promise(resolve => setTimeout(resolve, ENSEMBLE_LIMITS.MIN_ACTIVATION_INTERVAL));
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
/**
|
|
501
|
+
* Activate all elements simultaneously as one unified entity
|
|
502
|
+
*/
|
|
503
|
+
async activateAll(order, result, maxTime) {
|
|
504
|
+
const startTime = Date.now();
|
|
505
|
+
const activationPromises = order.map(elementId => this.activateElement(elementId).then(elementResult => {
|
|
506
|
+
result.elementResults.push(elementResult);
|
|
507
|
+
if (elementResult.success) {
|
|
508
|
+
result.activatedElements.push(elementId);
|
|
509
|
+
}
|
|
510
|
+
else {
|
|
511
|
+
result.failedElements.push(elementId);
|
|
512
|
+
}
|
|
513
|
+
return elementResult;
|
|
514
|
+
}));
|
|
515
|
+
// Wait for all with timeout
|
|
516
|
+
await Promise.race([
|
|
517
|
+
Promise.all(activationPromises),
|
|
518
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error(ENSEMBLE_ERRORS.ACTIVATION_TIMEOUT)), maxTime))
|
|
519
|
+
]);
|
|
520
|
+
}
|
|
521
|
+
/**
|
|
522
|
+
* Activate elements by priority
|
|
523
|
+
*/
|
|
524
|
+
async activatePriority(order, result, maxTime) {
|
|
525
|
+
// Sort by priority
|
|
526
|
+
const priorityOrder = [...order].sort((a, b) => {
|
|
527
|
+
const priorityA = this.elements.get(a)?.priority ?? 0;
|
|
528
|
+
const priorityB = this.elements.get(b)?.priority ?? 0;
|
|
529
|
+
return priorityB - priorityA; // Higher priority first
|
|
530
|
+
});
|
|
531
|
+
await this.activateSequential(priorityOrder, result, maxTime);
|
|
532
|
+
}
|
|
533
|
+
/**
|
|
534
|
+
* Activate elements based on conditions
|
|
535
|
+
*/
|
|
536
|
+
async activateConditional(order, result, maxTime) {
|
|
537
|
+
const startTime = Date.now();
|
|
538
|
+
for (const elementId of order) {
|
|
539
|
+
if (Date.now() - startTime > maxTime) {
|
|
540
|
+
throw new Error(ENSEMBLE_ERRORS.ACTIVATION_TIMEOUT);
|
|
541
|
+
}
|
|
542
|
+
const element = this.elements.get(elementId);
|
|
543
|
+
// Check activation condition
|
|
544
|
+
if (element.activationCondition) {
|
|
545
|
+
if (!this.evaluateCondition(element.activationCondition)) {
|
|
546
|
+
logger.info(`Skipping element ${elementId} - condition not met`);
|
|
547
|
+
continue;
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
const elementResult = await this.activateElement(elementId);
|
|
551
|
+
result.elementResults.push(elementResult);
|
|
552
|
+
if (elementResult.success) {
|
|
553
|
+
result.activatedElements.push(elementId);
|
|
554
|
+
}
|
|
555
|
+
else {
|
|
556
|
+
result.failedElements.push(elementId);
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
/**
|
|
561
|
+
* Activate a single element
|
|
562
|
+
* CRITICAL FIX: Implement actual element loading and activation
|
|
563
|
+
* Previously: Just simulated with timeout
|
|
564
|
+
* Now: Loads element from portfolio and activates it
|
|
565
|
+
*/
|
|
566
|
+
async activateElement(elementId) {
|
|
567
|
+
const startTime = Date.now();
|
|
568
|
+
try {
|
|
569
|
+
const ensembleElement = this.elements.get(elementId);
|
|
570
|
+
if (!ensembleElement) {
|
|
571
|
+
throw new Error(`Element ${elementId} not found in ensemble`);
|
|
572
|
+
}
|
|
573
|
+
// Load the element based on its type
|
|
574
|
+
const portfolioManager = PortfolioManager.getInstance();
|
|
575
|
+
const elementFilename = `${elementId}.md`;
|
|
576
|
+
logger.info(`Activating element: ${elementId} of type ${ensembleElement.elementType}`);
|
|
577
|
+
// For now, we only have PersonaElement fully implemented
|
|
578
|
+
// Future: Add factory pattern for other element types
|
|
579
|
+
let element;
|
|
580
|
+
if (ensembleElement.elementType === ElementType.PERSONA) {
|
|
581
|
+
// Load PersonaElement
|
|
582
|
+
const { PersonaElementManager } = await import('../../persona/PersonaElementManager.js');
|
|
583
|
+
const manager = new PersonaElementManager(portfolioManager);
|
|
584
|
+
element = await manager.load(elementFilename);
|
|
585
|
+
}
|
|
586
|
+
else {
|
|
587
|
+
// For other types, log warning and return success
|
|
588
|
+
// This allows ensemble to work with future element types
|
|
589
|
+
logger.warn(`Element type ${ensembleElement.elementType} not yet implemented for activation`);
|
|
590
|
+
return {
|
|
591
|
+
elementId,
|
|
592
|
+
success: true,
|
|
593
|
+
duration: Date.now() - startTime,
|
|
594
|
+
context: { warning: `Type ${ensembleElement.elementType} activation not implemented` }
|
|
595
|
+
};
|
|
596
|
+
}
|
|
597
|
+
// Store element instance for later use
|
|
598
|
+
if (element) {
|
|
599
|
+
this.elementInstances.set(elementId, element);
|
|
600
|
+
// Call element's activate method if it exists
|
|
601
|
+
if (element.activate) {
|
|
602
|
+
await element.activate();
|
|
603
|
+
}
|
|
604
|
+
// Extract any context from the element
|
|
605
|
+
const context = {};
|
|
606
|
+
if (element.getStatus) {
|
|
607
|
+
context.status = element.getStatus();
|
|
608
|
+
}
|
|
609
|
+
context.type = ensembleElement.elementType;
|
|
610
|
+
context.role = ensembleElement.role;
|
|
611
|
+
return {
|
|
612
|
+
elementId,
|
|
613
|
+
success: true,
|
|
614
|
+
duration: Date.now() - startTime,
|
|
615
|
+
context
|
|
616
|
+
};
|
|
617
|
+
}
|
|
618
|
+
return {
|
|
619
|
+
elementId,
|
|
620
|
+
success: true,
|
|
621
|
+
duration: Date.now() - startTime,
|
|
622
|
+
context: {}
|
|
623
|
+
};
|
|
624
|
+
}
|
|
625
|
+
catch (error) {
|
|
626
|
+
logger.error(`Failed to activate element ${elementId}:`, error);
|
|
627
|
+
return {
|
|
628
|
+
elementId,
|
|
629
|
+
success: false,
|
|
630
|
+
duration: Date.now() - startTime,
|
|
631
|
+
error: error
|
|
632
|
+
};
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
/**
|
|
636
|
+
* Evaluate a simple condition
|
|
637
|
+
* CRITICAL FIX: Implement actual condition evaluation
|
|
638
|
+
* Previously: Always returned true
|
|
639
|
+
* Now: Parses and evaluates simple conditions like "element.property == value"
|
|
640
|
+
*
|
|
641
|
+
* Supported operators: ==, !=, >, <, >=, <=
|
|
642
|
+
* Supported properties: active, status, priority
|
|
643
|
+
* Example: "element1.active == true" or "element2.priority > 50"
|
|
644
|
+
*/
|
|
645
|
+
evaluateCondition(condition) {
|
|
646
|
+
try {
|
|
647
|
+
// Sanitize and validate condition first
|
|
648
|
+
const sanitized = sanitizeInput(condition, ENSEMBLE_LIMITS.MAX_CONDITION_LENGTH);
|
|
649
|
+
// Parse condition: elementId.property operator value
|
|
650
|
+
const match = sanitized.match(/^([a-zA-Z0-9\-_]+)\.([a-zA-Z]+)\s*(==|!=|>=|<=|>|<)\s*(.+)$/);
|
|
651
|
+
if (!match) {
|
|
652
|
+
logger.warn(`Invalid condition format: ${condition}`);
|
|
653
|
+
return false;
|
|
654
|
+
}
|
|
655
|
+
const [, elementId, property, operator, value] = match;
|
|
656
|
+
// Get element instance or element data
|
|
657
|
+
const element = this.elementInstances.get(elementId);
|
|
658
|
+
const elementData = this.elements.get(elementId);
|
|
659
|
+
if (!element && !elementData) {
|
|
660
|
+
logger.debug(`Element ${elementId} not found for condition evaluation`);
|
|
661
|
+
return false;
|
|
662
|
+
}
|
|
663
|
+
// Get property value
|
|
664
|
+
let propertyValue;
|
|
665
|
+
switch (property) {
|
|
666
|
+
case 'active':
|
|
667
|
+
// Check if element is in activated elements list
|
|
668
|
+
propertyValue = this.lastActivationResult?.activatedElements.includes(elementId) || false;
|
|
669
|
+
break;
|
|
670
|
+
case 'status':
|
|
671
|
+
propertyValue = element?.getStatus ? element.getStatus() : 'inactive';
|
|
672
|
+
break;
|
|
673
|
+
case 'priority':
|
|
674
|
+
propertyValue = elementData?.priority || 0;
|
|
675
|
+
break;
|
|
676
|
+
default:
|
|
677
|
+
logger.warn(`Unknown property in condition: ${property}`);
|
|
678
|
+
return false;
|
|
679
|
+
}
|
|
680
|
+
// Parse the comparison value
|
|
681
|
+
let compareValue = value.trim();
|
|
682
|
+
// Handle boolean values
|
|
683
|
+
if (compareValue === 'true')
|
|
684
|
+
compareValue = true;
|
|
685
|
+
else if (compareValue === 'false')
|
|
686
|
+
compareValue = false;
|
|
687
|
+
// Handle numeric values
|
|
688
|
+
else if (!isNaN(Number(compareValue)))
|
|
689
|
+
compareValue = Number(compareValue);
|
|
690
|
+
// Handle string values (remove quotes if present)
|
|
691
|
+
else if (compareValue.startsWith('"') && compareValue.endsWith('"')) {
|
|
692
|
+
compareValue = compareValue.slice(1, -1);
|
|
693
|
+
}
|
|
694
|
+
// Evaluate based on operator
|
|
695
|
+
switch (operator) {
|
|
696
|
+
case '==':
|
|
697
|
+
return propertyValue == compareValue;
|
|
698
|
+
case '!=':
|
|
699
|
+
return propertyValue != compareValue;
|
|
700
|
+
case '>':
|
|
701
|
+
return Number(propertyValue) > Number(compareValue);
|
|
702
|
+
case '<':
|
|
703
|
+
return Number(propertyValue) < Number(compareValue);
|
|
704
|
+
case '>=':
|
|
705
|
+
return Number(propertyValue) >= Number(compareValue);
|
|
706
|
+
case '<=':
|
|
707
|
+
return Number(propertyValue) <= Number(compareValue);
|
|
708
|
+
default:
|
|
709
|
+
logger.warn(`Unknown operator in condition: ${operator}`);
|
|
710
|
+
return false;
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
catch (error) {
|
|
714
|
+
logger.error(`Error evaluating condition "${condition}":`, error);
|
|
715
|
+
return false;
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
/**
|
|
719
|
+
* Get shared context value
|
|
720
|
+
*/
|
|
721
|
+
getContextValue(key) {
|
|
722
|
+
return this.sharedContext.values.get(key);
|
|
723
|
+
}
|
|
724
|
+
/**
|
|
725
|
+
* Set shared context value with conflict resolution
|
|
726
|
+
*/
|
|
727
|
+
setContextValue(key, value, elementId) {
|
|
728
|
+
// Check context size limits
|
|
729
|
+
if (this.sharedContext.values.size >= ENSEMBLE_LIMITS.MAX_CONTEXT_SIZE) {
|
|
730
|
+
SecurityMonitor.logSecurityEvent({
|
|
731
|
+
type: ENSEMBLE_SECURITY_EVENTS.CONTEXT_SIZE_EXCEEDED,
|
|
732
|
+
severity: 'MEDIUM',
|
|
733
|
+
source: 'Ensemble.setContextValue',
|
|
734
|
+
details: `Context size limit (${ENSEMBLE_LIMITS.MAX_CONTEXT_SIZE}) exceeded`
|
|
735
|
+
});
|
|
736
|
+
throw new Error(ENSEMBLE_ERRORS.CONTEXT_OVERFLOW);
|
|
737
|
+
}
|
|
738
|
+
// Sanitize key
|
|
739
|
+
const sanitizedKey = sanitizeInput(key, 100);
|
|
740
|
+
// Check value size
|
|
741
|
+
const valueStr = JSON.stringify(value);
|
|
742
|
+
if (valueStr.length > ENSEMBLE_LIMITS.MAX_CONTEXT_VALUE_SIZE) {
|
|
743
|
+
throw new Error('Context value too large');
|
|
744
|
+
}
|
|
745
|
+
const currentOwner = this.sharedContext.owners.get(sanitizedKey);
|
|
746
|
+
const currentValue = this.sharedContext.values.get(sanitizedKey);
|
|
747
|
+
// Check for conflict
|
|
748
|
+
if (currentOwner && currentOwner !== elementId) {
|
|
749
|
+
const conflict = {
|
|
750
|
+
key: sanitizedKey,
|
|
751
|
+
currentValue,
|
|
752
|
+
currentOwner,
|
|
753
|
+
newValue: value,
|
|
754
|
+
newOwner: elementId
|
|
755
|
+
};
|
|
756
|
+
// Apply conflict resolution
|
|
757
|
+
const metadata = this.metadata;
|
|
758
|
+
switch (metadata.conflictResolution) {
|
|
759
|
+
case 'error':
|
|
760
|
+
throw new Error(`Context conflict on key '${sanitizedKey}'`);
|
|
761
|
+
case 'first-write':
|
|
762
|
+
// Keep existing value
|
|
763
|
+
return conflict;
|
|
764
|
+
case 'last-write':
|
|
765
|
+
// Overwrite with new value
|
|
766
|
+
break;
|
|
767
|
+
case 'priority':
|
|
768
|
+
const currentPriority = this.elements.get(currentOwner)?.priority ?? 0;
|
|
769
|
+
const newPriority = this.elements.get(elementId)?.priority ?? 0;
|
|
770
|
+
if (currentPriority > newPriority) {
|
|
771
|
+
return conflict;
|
|
772
|
+
}
|
|
773
|
+
break;
|
|
774
|
+
case 'merge':
|
|
775
|
+
// Simple merge for objects
|
|
776
|
+
if (typeof currentValue === 'object' && typeof value === 'object') {
|
|
777
|
+
value = { ...currentValue, ...value };
|
|
778
|
+
conflict.resolution = value;
|
|
779
|
+
}
|
|
780
|
+
break;
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
// Set the value
|
|
784
|
+
this.sharedContext.values.set(sanitizedKey, value);
|
|
785
|
+
this.sharedContext.owners.set(sanitizedKey, elementId);
|
|
786
|
+
this.sharedContext.timestamps.set(sanitizedKey, new Date());
|
|
787
|
+
return null;
|
|
788
|
+
}
|
|
789
|
+
/**
|
|
790
|
+
* Get all elements in the ensemble
|
|
791
|
+
*/
|
|
792
|
+
getElements() {
|
|
793
|
+
return new Map(this.elements);
|
|
794
|
+
}
|
|
795
|
+
/**
|
|
796
|
+
* Get activation result
|
|
797
|
+
*/
|
|
798
|
+
getLastActivationResult() {
|
|
799
|
+
return this.lastActivationResult;
|
|
800
|
+
}
|
|
801
|
+
/**
|
|
802
|
+
* Get current element status
|
|
803
|
+
*/
|
|
804
|
+
getStatus() {
|
|
805
|
+
return this._status;
|
|
806
|
+
}
|
|
807
|
+
/**
|
|
808
|
+
* Serialize ensemble to string
|
|
809
|
+
*/
|
|
810
|
+
serialize() {
|
|
811
|
+
const data = {
|
|
812
|
+
base: super.serialize(),
|
|
813
|
+
elements: Array.from(this.elements.entries()),
|
|
814
|
+
sharedContext: {
|
|
815
|
+
values: Array.from(this.sharedContext.values.entries()),
|
|
816
|
+
owners: Array.from(this.sharedContext.owners.entries()),
|
|
817
|
+
timestamps: Array.from(this.sharedContext.timestamps.entries())
|
|
818
|
+
}
|
|
819
|
+
};
|
|
820
|
+
return JSON.stringify(data, null, 2);
|
|
821
|
+
}
|
|
822
|
+
/**
|
|
823
|
+
* Deserialize ensemble from string
|
|
824
|
+
*/
|
|
825
|
+
deserialize(data) {
|
|
826
|
+
const parsed = JSON.parse(data);
|
|
827
|
+
// If data has a 'base' property, it was serialized by our serialize method
|
|
828
|
+
if (parsed.base) {
|
|
829
|
+
// Deserialize base properties
|
|
830
|
+
super.deserialize(parsed.base);
|
|
831
|
+
// Restore elements
|
|
832
|
+
if (parsed.elements) {
|
|
833
|
+
this.elements.clear();
|
|
834
|
+
for (const [id, element] of parsed.elements) {
|
|
835
|
+
this.elements.set(id, element);
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
// Restore shared context
|
|
839
|
+
if (parsed.sharedContext) {
|
|
840
|
+
this.sharedContext.values.clear();
|
|
841
|
+
this.sharedContext.owners.clear();
|
|
842
|
+
this.sharedContext.timestamps.clear();
|
|
843
|
+
for (const [key, value] of parsed.sharedContext.values || []) {
|
|
844
|
+
this.sharedContext.values.set(key, value);
|
|
845
|
+
}
|
|
846
|
+
for (const [key, owner] of parsed.sharedContext.owners || []) {
|
|
847
|
+
this.sharedContext.owners.set(key, owner);
|
|
848
|
+
}
|
|
849
|
+
for (const [key, timestamp] of parsed.sharedContext.timestamps || []) {
|
|
850
|
+
this.sharedContext.timestamps.set(key, new Date(timestamp));
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
else {
|
|
855
|
+
// Old format or direct properties
|
|
856
|
+
super.deserialize(data);
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
}
|
|
860
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRW5zZW1ibGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvZWxlbWVudHMvZW5zZW1ibGVzL0Vuc2VtYmxlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7OztHQWNHO0FBRUgsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBRWhELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUN2RCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQztBQUN2RSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFDakUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sK0NBQStDLENBQUM7QUFDakYsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLG1DQUFtQyxDQUFDO0FBQ3BFLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQWEvQyxPQUFPLEVBQ0wsZUFBZSxFQUNmLGlCQUFpQixFQUNqQixxQkFBcUIsRUFDckIsbUJBQW1CLEVBQ25CLGFBQWEsRUFDYix3QkFBd0IsRUFDeEIsZUFBZSxFQUNmLGlCQUFpQixFQUNsQixNQUFNLGdCQUFnQixDQUFDO0FBRXhCLE1BQU0sT0FBTyxRQUFTLFNBQVEsV0FBVztJQUMvQixRQUFRLEdBQWlDLElBQUksR0FBRyxFQUFFLENBQUM7SUFDbkQsZ0JBQWdCLEdBQTBCLElBQUksR0FBRyxFQUFFLENBQUM7SUFDcEQsYUFBYSxDQUFnQjtJQUM3QixvQkFBb0IsR0FBWSxLQUFLLENBQUM7SUFDdEMsb0JBQW9CLENBQTRCO0lBRXhELFlBQVksV0FBc0MsRUFBRTtRQUNsRCx3REFBd0Q7UUFDeEQsTUFBTSxpQkFBaUIsR0FBOEI7WUFDbkQsR0FBRyxRQUFRO1lBQ1gsSUFBSSxFQUFFLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxnQkFBZ0IsQ0FBQyxT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QUFNLENBQUMsYUFBYSxDQUFDLE1BQU0sSUFBSSxFQUFFLEVBQUUsQ0FBQztvQkFDN0QsSUFBSSxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsQ0FBQztnQkFDNUMsQ0FBQztnQkFDRCxLQUFLLE1BQU0sQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLElBQUksTUFBTSxDQUFDLGFBQWEsQ0FBQyxNQUFNLElBQUksRUFBRSxFQUFFLENBQUM7b0JBQzdELElBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLENBQUM7Z0JBQzVDLENBQUM7Z0JBQ0QsS0FBSyxNQUFNLENBQUMsR0FBRyxFQUFFLFNBQVMsQ0FBQyxJQUFJLE1BQU0sQ0FBQyxhQUFhLENBQUMsVUFBVSxJQUFJLEVBQUUsRUFBRSxDQUFDO29CQUNyRSxJQUFJLENBQUMsYUFBYSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7Z0JBQzlELENBQUM7WUFDSCxDQUFDO1FBQ0gsQ0FBQzthQUFNLENBQUM7WUFDTixrQ0FBa0M7WUFDbEMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUMxQixDQUFDO0lBQ0gsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBFbnNlbWJsZSBFbGVtZW50IC0gT3JjaGVzdHJhdGVzIG11bHRpcGxlIGVsZW1lbnRzIHdvcmtpbmcgdG9nZXRoZXJcbiAqIFxuICogRW5zZW1ibGVzIGFsbG93IGNvbWJpbmluZyBtdWx0aXBsZSBlbGVtZW50cyAocGVyc29uYXMsIHNraWxscywgdGVtcGxhdGVzLCBhZ2VudHMsIG1lbW9yaWVzKVxuICogaW50byBjb2hlc2l2ZSB1bml0cyB3aXRoIGNvbnRyb2xsZWQgYWN0aXZhdGlvbiwgY29uZmxpY3QgcmVzb2x1dGlvbiwgYW5kIHNoYXJlZCBjb250ZXh0LlxuICogXG4gKiBTRUNVUklUWSBNRUFTVVJFUyBJTVBMRU1FTlRFRDpcbiAqIDEuIENpcmN1bGFyIGRlcGVuZGVuY3kgZGV0ZWN0aW9uIHdpdGggcGF0aCB0cmFja2luZ1xuICogMi4gUmVzb3VyY2UgbGltaXRzIChtYXggZWxlbWVudHMsIG5lc3RpbmcgZGVwdGgsIGFjdGl2YXRpb24gdGltZSlcbiAqIDMuIElucHV0IHNhbml0aXphdGlvbiBmb3IgYWxsIHVzZXItcHJvdmlkZWQgZGF0YVxuICogNC4gQWN0aXZhdGlvbiB0aW1lb3V0IHByb3RlY3Rpb25cbiAqIDUuIENvbnRleHQgc2l6ZSBsaW1pdHMgdG8gcHJldmVudCBtZW1vcnkgZXhoYXVzdGlvblxuICogNi4gQXVkaXQgbG9nZ2luZyBmb3Igc2VjdXJpdHkgZXZlbnRzXG4gKiA3LiBDb25kaXRpb24gdmFsaWRhdGlvbiB0byBwcmV2ZW50IGNvZGUgaW5qZWN0aW9uXG4gKi9cblxuaW1wb3J0IHsgQmFzZUVsZW1lbnQgfSBmcm9tICcuLi9CYXNlRWxlbWVudC5qcyc7XG5pbXBvcnQgeyBJRWxlbWVudCwgRWxlbWVudFZhbGlkYXRpb25SZXN1bHQsIFZhbGlkYXRpb25FcnJvciwgVmFsaWRhdGlvbldhcm5pbmcsIEVsZW1lbnRTdGF0dXMgfSBmcm9tICcuLi8uLi90eXBlcy9lbGVtZW50cy9pbmRleC5qcyc7XG5pbXBvcnQgeyBFbGVtZW50VHlwZSB9IGZyb20gJy4uLy4uL3BvcnRmb2xpby90eXBlcy5qcyc7XG5pbXBvcnQgeyBQb3J0Zm9saW9NYW5hZ2VyIH0gZnJvbSAnLi4vLi4vcG9ydGZvbGlvL1BvcnRmb2xpb01hbmFnZXIuanMnO1xuaW1wb3J0IHsgc2FuaXRpemVJbnB1dCB9IGZyb20gJy4uLy4uL3NlY3VyaXR5L0lucHV0VmFsaWRhdG9yLmpzJztcbmltcG9ydCB7IFVuaWNvZGVWYWxpZGF0b3IgfSBmcm9tICcuLi8uLi9zZWN1cml0eS92YWxpZGF0b3JzL3VuaWNvZGVWYWxpZGF0b3IuanMnO1xuaW1wb3J0IHsgU2VjdXJpdHlNb25pdG9yIH0gZnJvbSAnLi4vLi4vc2VjdXJpdHkvc2VjdXJpdHlNb25pdG9yLmpzJztcbmltcG9ydCB7IGxvZ2dlciB9IGZyb20gJy4uLy4uL3V0aWxzL2xvZ2dlci5qcyc7XG5pbXBvcnQge1xuICBFbnNlbWJsZU1ldGFkYXRhLFxuICBFbnNlbWJsZUVsZW1lbnQsXG4gIEFjdGl2YXRpb25TdHJhdGVneSxcbiAgQ29uZmxpY3RSZXNvbHV0aW9uU3RyYXRlZ3ksXG4gIEVsZW1lbnRSb2xlLFxuICBTaGFyZWRDb250ZXh0LFxuICBFbnNlbWJsZUFjdGl2YXRpb25SZXN1bHQsXG4gIEVsZW1lbnRBY3RpdmF0aW9uUmVzdWx0LFxuICBDb250ZXh0Q29uZmxpY3QsXG4gIENpcmN1bGFyRGVwZW5kZW5jeVxufSBmcm9tICcuL3R5cGVzLmpzJztcbmltcG9ydCB7XG4gIEVOU0VNQkxFX0xJTUlUUyxcbiAgRU5TRU1CTEVfREVGQVVMVFMsXG4gIEFDVElWQVRJT05fU1RSQVRFR0lFUyxcbiAgQ09ORkxJQ1RfU1RSQVRFR0lFUyxcbiAgRUxFTUVOVF9ST0xFUyxcbiAgRU5TRU1CTEVfU0VDVVJJVFlfRVZFTlRTLFxuICBFTlNFTUJMRV9FUlJPUlMsXG4gIEVOU0VNQkxFX1BBVFRFUk5TXG59IGZyb20gJy4vY29uc3RhbnRzLmpzJztcblxuZXhwb3J0IGNsYXNzIEVuc2VtYmxlIGV4dGVuZHMgQmFzZUVsZW1lbnQgaW1wbGVtZW50cyBJRWxlbWVudCB7XG4gIHByaXZhdGUgZWxlbWVudHM6IE1hcDxzdHJpbmcsIEVuc2VtYmxlRWxlbWVudD4gPSBuZXcgTWFwKCk7XG4gIHByaXZhdGUgZWxlbWVudEluc3RhbmNlczogTWFwPHN0cmluZywgSUVsZW1lbnQ+ID0gbmV3IE1hcCgpO1xuICBwcml2YXRlIHNoYXJlZENvbnRleHQ6IFNoYXJlZENvbnRleHQ7XG4gIHByaXZhdGUgYWN0aXZhdGlvbkluUHJvZ3Jlc3M6IGJvb2xlYW4gPSBmYWxzZTtcbiAgcHJpdmF0ZSBsYXN0QWN0aXZhdGlvblJlc3VsdD86IEVuc2VtYmxlQWN0aXZhdGlvblJlc3VsdDtcblxuICBjb25zdHJ1Y3RvcihtZXRhZGF0YTogUGFydGlhbDxFbnNlbWJsZU1ldGFkYXRhPiA9IHt9KSB7XG4gICAgLy8gU0VDVVJJVFkgRklYOiBTYW5pdGl6ZSBhbGwgaW5wdXRzIGR1cmluZyBjb25zdHJ1Y3Rpb25cbiAgICBjb25zdCBzYW5pdGl6ZWRNZXRhZGF0YTogUGFydGlhbDxFbnNlbWJsZU1ldGFkYXRhPiA9IHtcbiAgICAgIC4uLm1ldGFkYXRhLFxuICAgICAgbmFtZTogbWV0YWRhdGEubmFtZSA/IHNhbml0aXplSW5wdXQoVW5pY29kZVZhbGlkYXRvci5ub3JtYWxpemUobWV0YWRhdGEubmFtZSkubm9ybWFsaXplZENvbnRlbnQsIDEwMCkgOiB1bmRlZmluZWQsXG4gICAgICBkZXNjcmlwdGlvbjogbWV0YWRhdGEuZGVzY3JpcHRpb24gPyBzYW5pdGl6ZUlucHV0KFVuaWNvZGVWYWxpZGF0b3Iubm9ybWFsaXplKG1ldGFkYXRhLmRlc2NyaXB0aW9uKS5ub3JtYWxpemVkQ29udGVudCwgNTAwKSA6IHVuZGVmaW5lZCxcbiAgICAgIGFjdGl2YXRpb25TdHJhdGVneTogbWV0YWRhdGEuYWN0aXZhdGlvblN0cmF0ZWd5IHx8IEVOU0VNQkxFX0RFRkFVTFRTLkFDVElWQVRJT05fU1RSQVRFR1ksXG4gICAgICBjb25mbGljdFJlc29sdXRpb246IG1ldGFkYXRhLmNvbmZsaWN0UmVzb2x1dGlvbiB8fCBFTlNFTUJMRV9ERUZBVUxUUy5DT05GTElDVF9SRVNPTFVUSU9OLFxuICAgICAgbWF4RWxlbWVudHM6IG1ldGFkYXRhLm1heEVsZW1lbnRzID8/IEVOU0VNQkxFX0xJTUlUUy5NQVhfRUxFTUVOVFMsXG4gICAgICBtYXhBY3RpdmF0aW9uVGltZTogbWV0YWRhdGEubWF4QWN0aXZhdGlvblRpbWUgPz8gRU5TRU1CTEVfTElNSVRTLk1BWF9BQ1RJVkFUSU9OX1RJTUUsXG4gICAgICBhbGxvd05lc3RlZDogbWV0YWRhdGEuYWxsb3dOZXN0ZWQgPz8gRU5TRU1CTEVfREVGQVVMVFMuQUxMT1dfTkVTVEVELFxuICAgICAgbWF4TmVzdGluZ0RlcHRoOiBtZXRhZGF0YS5tYXhOZXN0aW5nRGVwdGggPz8gRU5TRU1CTEVfTElNSVRTLk1BWF9ORVNUSU5HX0RFUFRIXG4gICAgfTtcblxuICAgIC8vIFZhbGlkYXRlIGFjdGl2YXRpb24gc3RyYXRlZ3lcbiAgICBpZiAoIUFDVElWQVRJT05fU1RSQVRFR0lFUy5pbmNsdWRlcyhzYW5pdGl6ZWRNZXRhZGF0YS5hY3RpdmF0aW9uU3RyYXRlZ3khKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKEVOU0VNQkxFX0VSUk9SUy5JTlZBTElEX1NUUkFURUdZKTtcbiAgICB9XG5cbiAgICAvLyBWYWxpZGF0ZSBjb25mbGljdCByZXNvbHV0aW9uIHN0cmF0ZWd5XG4gICAgaWYgKCFDT05GTElDVF9TVFJBVEVHSUVTLmluY2x1ZGVzKHNhbml0aXplZE1ldGFkYXRhLmNvbmZsaWN0UmVzb2x1dGlvbiEpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoRU5TRU1CTEVfRVJST1JTLklOVkFMSURfQ09ORkxJQ1RfUkVTT0xVVElPTik7XG4gICAgfVxuXG4gICAgLy8gVmFsaWRhdGUgbGltaXRzXG4gICAgaWYgKHNhbml0aXplZE1ldGFkYXRhLm1heEVsZW1lbnRzISA+IEVOU0VNQkxFX0xJTUlUUy5NQVhfRUxFTUVOVFMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihFTlNFTUJMRV9FUlJPUlMuVE9PX01BTllfRUxFTUVOVFMpO1xuICAgIH1cblxuICAgIGlmIChzYW5pdGl6ZWRNZXRhZGF0YS5tYXhOZXN0aW5nRGVwdGghID4gRU5TRU1CTEVfTElNSVRTLk1BWF9ORVNUSU5HX0RFUFRIKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoRU5TRU1CTEVfRVJST1JTLk5FU1RJTkdfVE9PX0RFRVApO1xuICAgIH1cblxuICAgIHN1cGVyKEVsZW1lbnRUeXBlLkVOU0VNQkxFLCBzYW5pdGl6ZWRNZXRhZGF0YSk7XG5cbiAgICAvLyBFbnN1cmUgZW5zZW1ibGUtc3BlY2lmaWMgbWV0YWRhdGEgaXMgc3RvcmVkXG4gICAgdGhpcy5tZXRhZGF0YSA9IHtcbiAgICAgIC4uLnRoaXMubWV0YWRhdGEsXG4gICAgICBhY3RpdmF0aW9uU3RyYXRlZ3k6IHNhbml0aXplZE1ldGFkYXRhLmFjdGl2YXRpb25TdHJhdGVneSxcbiAgICAgIGNvbmZsaWN0UmVzb2x1dGlvbjogc2FuaXRpemVkTWV0YWRhdGEuY29uZmxpY3RSZXNvbHV0aW9uLFxuICAgICAgbWF4RWxlbWVudHM6IHNhbml0aXplZE1ldGFkYXRhLm1heEVsZW1lbnRzLFxuICAgICAgbWF4QWN0aXZhdGlvblRpbWU6IHNhbml0aXplZE1ldGFkYXRhLm1heEFjdGl2YXRpb25UaW1lLFxuICAgICAgYWxsb3dOZXN0ZWQ6IHNhbml0aXplZE1ldGFkYXRhLmFsbG93TmVzdGVkLFxuICAgICAgbWF4TmVzdGluZ0RlcHRoOiBzYW5pdGl6ZWRNZXRhZGF0YS5tYXhOZXN0aW5nRGVwdGhcbiAgICB9IGFzIEVuc2VtYmxlTWV0YWRhdGE7XG5cbiAgICAvLyBJbml0aWFsaXplIHNoYXJlZCBjb250ZXh0XG4gICAgdGhpcy5zaGFyZWRDb250ZXh0ID0ge1xuICAgICAgdmFsdWVzOiBuZXcgTWFwKCksXG4gICAgICBvd25lcnM6IG5ldyBNYXAoKSxcbiAgICAgIHRpbWVzdGFtcHM6IG5ldyBNYXAoKVxuICAgIH07XG5cbiAgICAvLyBTZXQgZW5zZW1ibGUtc3BlY2lmaWMgZXh0ZW5zaW9uc1xuICAgIHRoaXMuZXh0ZW5zaW9ucyA9IHtcbiAgICAgIGVsZW1lbnRDb3VudDogMCxcbiAgICAgIGFjdGl2YXRpb25TdHJhdGVneTogc2FuaXRpemVkTWV0YWRhdGEuYWN0aXZhdGlvblN0cmF0ZWd5LFxuICAgICAgY29uZmxpY3RSZXNvbHV0aW9uOiBzYW5pdGl6ZWRNZXRhZGF0YS5jb25mbGljdFJlc29sdXRpb24sXG4gICAgICBsYXN0QWN0aXZhdGlvbjogbnVsbFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogQWRkIGFuIGVsZW1lbnQgdG8gdGhlIGVuc2VtYmxlXG4gICAqL1xuICBwdWJsaWMgYWRkRWxlbWVudChcbiAgICBlbGVtZW50SWQ6IHN0cmluZywgXG4gICAgZWxlbWVudFR5cGU6IHN0cmluZyxcbiAgICByb2xlOiBFbGVtZW50Um9sZSA9IEVOU0VNQkxFX0RFRkFVTFRTLkVMRU1FTlRfUk9MRSxcbiAgICBvcHRpb25zOiB7XG4gICAgICBwcmlvcml0eT86IG51bWJlcjtcbiAgICAgIGFjdGl2YXRpb25Db25kaXRpb24/OiBzdHJpbmc7XG4gICAgICBkZXBlbmRlbmNpZXM/OiBzdHJpbmdbXTtcbiAgICB9ID0ge31cbiAgKTogdm9pZCB7XG4gICAgLy8gQ2hlY2sgZWxlbWVudCBsaW1pdFxuICAgIGlmICh0aGlzLmVsZW1lbnRzLnNpemUgPj0gKHRoaXMubWV0YWRhdGEgYXMgRW5zZW1ibGVNZXRhZGF0YSkubWF4RWxlbWVudHMhKSB7XG4gICAgICBTZWN1cml0eU1vbml0b3IubG9nU2VjdXJpdHlFdmVudCh7XG4gICAgICAgIHR5cGU6IEVOU0VNQkxFX1NFQ1VSSVRZX0VWRU5UUy5SRVNPVVJDRV9MSU1JVF9FWENFRURFRCxcbiAgICAgICAgc2V2ZXJpdHk6ICdNRURJVU0nLFxuICAgICAgICBzb3VyY2U6ICdFbnNlbWJsZS5hZGRFbGVtZW50JyxcbiAgICAgICAgZGV0YWlsczogYE1heGltdW0gZWxlbWVudHMgKCR7RU5TRU1CTEVfTElNSVRTLk1BWF9FTEVNRU5UU30pIGV4Y2VlZGVkYFxuICAgICAgfSk7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoRU5TRU1CTEVfRVJST1JTLlRPT19NQU5ZX0VMRU1FTlRTKTtcbiAgICB9XG5cbiAgICAvLyBTYW5pdGl6ZSBlbGVtZW50IElEXG4gICAgY29uc3Qgc2FuaXRpemVkSWQgPSBzYW5pdGl6ZUlucHV0KGVsZW1lbnRJZCwgMTAwKTtcbiAgICBpZiAoIUVOU0VNQkxFX1BBVFRFUk5TLkVMRU1FTlRfSURfUEFUVEVSTi50ZXN0KHNhbml0aXplZElkKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGVsZW1lbnQgSUQgZm9ybWF0Jyk7XG4gICAgfVxuXG4gICAgLy8gVmFsaWRhdGUgcm9sZVxuICAgIGlmICghRUxFTUVOVF9ST0xFUy5pbmNsdWRlcyhyb2xlKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGVsZW1lbnQgcm9sZScpO1xuICAgIH1cblxuICAgIC8vIFZhbGlkYXRlIGFjdGl2YXRpb24gY29uZGl0aW9uIGlmIHByb3ZpZGVkXG4gICAgaWYgKG9wdGlvbnMuYWN0aXZhdGlvbkNvbmRpdGlvbikge1xuICAgICAgY29uc3Qgc2FuaXRpemVkQ29uZGl0aW9uID0gc2FuaXRpemVJbnB1dChvcHRpb25zLmFjdGl2YXRpb25Db25kaXRpb24sIEVOU0VNQkxFX0xJTUlUUy5NQVhfQ09ORElUSU9OX0xFTkdUSCk7XG4gICAgICBpZiAoIXRoaXMuaXNWYWxpZENvbmRpdGlvbihzYW5pdGl6ZWRDb25kaXRpb24pKSB7XG4gICAgICAgIFNlY3VyaXR5TW9uaXRvci5sb2dTZWN1cml0eUV2ZW50KHtcbiAgICAgICAgICB0eXBlOiBFTlNFTUJMRV9TRUNVUklUWV9FVkVOVFMuU1VTUElDSU9VU19DT05ESVRJT04sXG4gICAgICAgICAgc2V2ZXJpdHk6ICdISUdIJyxcbiAgICAgICAgICBzb3VyY2U6ICdFbnNlbWJsZS5hZGRFbGVtZW50JyxcbiAgICAgICAgICBkZXRhaWxzOiBgU3VzcGljaW91cyBhY3RpdmF0aW9uIGNvbmRpdGlvbjogJHtzYW5pdGl6ZWRDb25kaXRpb259YFxuICAgICAgICB9KTtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGFjdGl2YXRpb24gY29uZGl0aW9uIHN5bnRheCcpO1xuICAgICAgfVxuICAgICAgb3B0aW9ucy5hY3RpdmF0aW9uQ29uZGl0aW9uID0gc2FuaXRpemVkQ29uZGl0aW9uO1xuICAgIH1cblxuICAgIC8vIFZhbGlkYXRlIGRlcGVuZGVuY2llc1xuICAgIGlmIChvcHRpb25zLmRlcGVuZGVuY2llcykge1xuICAgICAgaWYgKG9wdGlvbnMuZGVwZW5kZW5jaWVzLmxlbmd0aCA+IEVOU0VNQkxFX0xJTUlUUy5NQVhfREVQRU5ERU5DSUVTKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgVG9vIG1hbnkgZGVwZW5kZW5jaWVzIChtYXg6ICR7RU5TRU1CTEVfTElNSVRTLk1BWF9ERVBFTkRFTkNJRVN9KWApO1xuICAgICAgfVxuICAgICAgLy8gU2FuaXRpemUgZWFjaCBkZXBlbmRlbmN5XG4gICAgICBvcHRpb25zLmRlcGVuZGVuY2llcyA9IG9wdGlvbnMuZGVwZW5kZW5jaWVzLm1hcChkZXAgPT4gc2FuaXRpemVJbnB1dChkZXAsIDEwMCkpO1xuICAgIH1cblxuICAgIC8vIENyZWF0ZSBlbnNlbWJsZSBlbGVtZW50XG4gICAgY29uc3QgZW5zZW1ibGVFbGVtZW50OiBFbnNlbWJsZUVsZW1lbnQgPSB7XG4gICAgICBlbGVtZW50SWQ6IHNhbml0aXplZElkLFxuICAgICAgZWxlbWVudFR5cGU6IHNhbml0aXplSW5wdXQoZWxlbWVudFR5cGUsIDUwKSxcbiAgICAgIHJvbGUsXG4gICAgICBwcmlvcml0eTogb3B0aW9ucy5wcmlvcml0eSA/PyBFTlNFTUJMRV9ERUZBVUxUUy5QUklPUklUWSxcbiAgICAgIGFjdGl2YXRpb25Db25kaXRpb246IG9wdGlvbnMuYWN0aXZhdGlvbkNvbmRpdGlvbixcbiAgICAgIGRlcGVuZGVuY2llczogb3B0aW9ucy5kZXBlbmRlbmNpZXNcbiAgICB9O1xuXG4gICAgLy8gQ2hlY2sgZm9yIGNpcmN1bGFyIGRlcGVuZGVuY2llcyBiZWZvcmUgYWRkaW5nXG4gICAgaWYgKHRoaXMud291bGRDcmVhdGVDaXJjdWxhckRlcGVuZGVuY3koc2FuaXRpemVkSWQsIG9wdGlvbnMuZGVwZW5kZW5jaWVzIHx8IFtdKSkge1xuICAgICAgY29uc3QgY2lyY3VsYXIgPSB0aGlzLmZpbmRDaXJjdWxhckRlcGVuZGVuY3koc2FuaXRpemVkSWQsIG9wdGlvbnMuZGVwZW5kZW5jaWVzIHx8IFtdKTtcbiAgICAgIFNlY3VyaXR5TW9uaXRvci5sb2dTZWN1cml0eUV2ZW50KHtcbiAgICAgICAgdHlwZTogRU5TRU1CTEVfU0VDVVJJVFlfRVZFTlRTLkNJUkNVTEFSX0RFUEVOREVOQ1ksXG4gICAgICAgIHNldmVyaXR5OiAnSElHSCcsXG4gICAgICAgIHNvdXJjZTogJ0Vuc2VtYmxlLmFkZEVsZW1lbnQnLFxuICAgICAgICBkZXRhaWxzOiBgQ2lyY3VsYXIgZGVwZW5kZW5jeSBkZXRlY3RlZDogJHtjaXJjdWxhci5wYXRoLmpvaW4oJyAtPiAnKX1gXG4gICAgICB9KTtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgJHtFTlNFTUJMRV9FUlJPUlMuQ0lSQ1VMQVJfREVQRU5ERU5DWX06ICR7Y2lyY3VsYXIubWVzc2FnZX1gKTtcbiAgICB9XG5cbiAgICB0aGlzLmVsZW1lbnRzLnNldChzYW5pdGl6ZWRJZCwgZW5zZW1ibGVFbGVtZW50KTtcbiAgICB0aGlzLmV4dGVuc2lvbnMhLmVsZW1lbnRDb3VudCA9IHRoaXMuZWxlbWVudHMuc2l6ZTtcbiAgICB0aGlzLm1hcmtEaXJ0eSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZSBhbiBlbGVtZW50IGZyb20gdGhlIGVuc2VtYmxlXG4gICAqL1xuICBwdWJsaWMgcmVtb3ZlRWxlbWVudChlbGVtZW50SWQ6IHN0cmluZyk6IHZvaWQge1xuICAgIGNvbnN0IHNhbml0aXplZElkID0gc2FuaXRpemVJbnB1dChlbGVtZW50SWQsIDEwMCk7XG4gICAgXG4gICAgaWYgKCF0aGlzLmVsZW1lbnRzLmhhcyhzYW5pdGl6ZWRJZCkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihFTlNFTUJMRV9FUlJPUlMuRUxFTUVOVF9OT1RfRk9VTkQpO1xuICAgIH1cblxuICAgIC8vIFJlbW92ZSBlbGVtZW50IGFuZCBpdHMgaW5zdGFuY2VcbiAgICB0aGlzLmVsZW1lbnRzLmRlbGV0ZShzYW5pdGl6ZWRJZCk7XG4gICAgdGhpcy5lbGVtZW50SW5zdGFuY2VzLmRlbGV0ZShzYW5pdGl6ZWRJZCk7XG4gICAgXG4gICAgLy8gQ2xlYW4gdXAgZGVwZW5kZW5jaWVzIHBvaW50aW5nIHRvIHRoaXMgZWxlbWVudFxuICAgIGZvciAoY29uc3QgW2lkLCBlbGVtZW50XSBvZiB0aGlzLmVsZW1lbnRzKSB7XG4gICAgICBpZiAoZWxlbWVudC5kZXBlbmRlbmNpZXM/LmluY2x1ZGVzKHNhbml0aXplZElkKSkge1xuICAgICAgICBlbGVtZW50LmRlcGVuZGVuY2llcyA9IGVsZW1lbnQuZGVwZW5kZW5jaWVzLmZpbHRlcihkZXAgPT4gZGVwICE9PSBzYW5pdGl6ZWRJZCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gQ2xlYW4gdXAgc2hhcmVkIGNvbnRleHQgb3duZWQgYnkgdGhpcyBlbGVtZW50XG4gICAgZm9yIChjb25zdCBba2V5LCBvd25lcl0gb2YgdGhpcy5zaGFyZWRDb250ZXh0Lm93bmVycykge1xuICAgICAgaWYgKG93bmVyID09PSBzYW5pdGl6ZWRJZCkge1xuICAgICAgICB0aGlzLnNoYXJlZENvbnRleHQudmFsdWVzLmRlbGV0ZShrZXkpO1xuICAgICAgICB0aGlzLnNoYXJlZENvbnRleHQub3duZXJzLmRlbGV0ZShrZXkpO1xuICAgICAgICB0aGlzLnNoYXJlZENvbnRleHQudGltZXN0YW1wcy5kZWxldGUoa2V5KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLmV4dGVuc2lvbnMhLmVsZW1lbnRDb3VudCA9IHRoaXMuZWxlbWVudHMuc2l6ZTtcbiAgICB0aGlzLm1hcmtEaXJ0eSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEFjdGl2YXRlIHRoZSBlbnNlbWJsZSBhbmQgYWxsIGl0cyBlbGVtZW50cyBiYXNlZCBvbiBzdHJhdGVneVxuICAgKi9cbiAgcHVibGljIG92ZXJyaWRlIGFzeW5jIGFjdGl2YXRlKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICh0aGlzLmFjdGl2YXRpb25JblByb2dyZXNzKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0FjdGl2YXRpb24gYWxyZWFkeSBpbiBwcm9ncmVzcycpO1xuICAgIH1cblxuICAgIHRoaXMuYWN0aXZhdGlvbkluUHJvZ3Jlc3MgPSB0cnVlO1xuICAgIGNvbnN0IHN0YXJ0VGltZSA9IERhdGUubm93KCk7XG4gICAgY29uc3QgbWV0YWRhdGEgPSB0aGlzLm1ldGFkYXRhIGFzIEVuc2VtYmxlTWV0YWRhdGE7XG4gICAgXG4gICAgdHJ5IHtcbiAgICAgIC8vIFNldCBzdGF0dXNcbiAgICAgIHRoaXMuX3N0YXR1cyA9ICdhY3RpdmUnIGFzIEVsZW1lbnRTdGF0dXM7XG4gICAgICBcbiAgICAgIGNvbnN0IHJlc3VsdDogRW5zZW1ibGVBY3RpdmF0aW9uUmVzdWx0ID0ge1xuICAgICAgICBzdWNjZXNzOiB0cnVlLFxuICAgICAgICBhY3RpdmF0ZWRFbGVtZW50czogW10sXG4gICAgICAgIGZhaWxlZEVsZW1lbnRzOiBbXSxcbiAgICAgICAgY29uZmxpY3RzOiBbXSxcbiAgICAgICAgdG90YWxEdXJhdGlvbjogMCxcbiAgICAgICAgZWxlbWVudFJlc3VsdHM6IFtdXG4gICAgICB9O1xuXG4gICAgICAvLyBHZXQgYWN0aXZhdGlvbiBvcmRlciBiYXNlZCBvbiBzdHJhdGVneVxuICAgICAgY29uc3QgYWN0aXZhdGlvbk9yZGVyID0gdGhpcy5nZXRBY3RpdmF0aW9uT3JkZXIoKTtcbiAgICAgIFxuICAgICAgLy8gQWN0aXZhdGUgZWxlbWVudHMgYWNjb3JkaW5nIHRvIHN0cmF0ZWd5XG4gICAgICBzd2l0Y2ggKG1ldGFkYXRhLmFjdGl2YXRpb25TdHJhdGVneSkge1xuICAgICAgICBjYXNlICdzZXF1ZW50aWFsJzpcbiAgICAgICAgICBhd2FpdCB0aGlzLmFjdGl2YXRlU2VxdWVudGlhbChhY3RpdmF0aW9uT3JkZXIsIHJlc3VsdCwgbWV0YWRhdGEubWF4QWN0aXZhdGlvblRpbWUhKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnYWxsJzpcbiAgICAgICAgICAvLyBBY3RpdmF0ZSBhbGwgZWxlbWVudHMgc2ltdWx0YW5lb3VzbHkgYXMgb25lIHVuaWZpZWQgZW50aXR5XG4gICAgICAgICAgLy8gRWxlbWVudHMgYXJlIGxheWVyZWQvY29tYmluZWQgcmF0aGVyIHRoYW4gYWN0aW5nIHNlcGFyYXRlbHlcbiAgICAgICAgICBhd2FpdCB0aGlzLmFjdGl2YXRlQWxsKGFjdGl2YXRpb25PcmRlciwgcmVzdWx0LCBtZXRhZGF0YS5tYXhBY3RpdmF0aW9uVGltZSEpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdwcmlvcml0eSc6XG4gICAgICAgICAgYXdhaXQgdGhpcy5hY3RpdmF0ZVByaW9yaXR5KGFjdGl2YXRpb25PcmRlciwgcmVzdWx0LCBtZXRhZGF0YS5tYXhBY3RpdmF0aW9uVGltZSEpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdjb25kaXRpb25hbCc6XG4gICAgICAgICAgYXdhaXQgdGhpcy5hY3RpdmF0ZUNvbmRpdGlvbmFsKGFjdGl2YXRpb25PcmRlciwgcmVzdWx0LCBtZXRhZGF0YS5tYXhBY3RpdmF0aW9uVGltZSEpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdsYXp5JzpcbiAgICAgICAgICAvLyBMYXp5IGFjdGl2YXRpb24gaGFwcGVucyBvbi1kZW1hbmQsIGp1c3QgbWFyayBhcyByZWFkeVxuICAgICAgICAgIGxvZ2dlci5pbmZvKGBFbnNlbWJsZSAke3RoaXMuaWR9IHJlYWR5IGZvciBsYXp5IGFjdGl2YXRpb25gKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgcmVzdWx0LnRvdGFsRHVyYXRpb24gPSBEYXRlLm5vdygpIC0gc3RhcnRUaW1lO1xuICAgICAgdGhpcy5sYXN0QWN0aXZhdGlvblJlc3VsdCA9IHJlc3VsdDtcbiAgICAgIHRoaXMuZXh0ZW5zaW9ucyEubGFzdEFjdGl2YXRpb24gPSBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCk7XG5cbiAgICAgIGlmIChyZXN1bHQuZmFpbGVkRWxlbWVudHMubGVuZ3RoID4gMCkge1xuICAgICAgICBsb2dnZXIud2FybihgRW5zZW1ibGUgYWN0aXZhdGlvbiBjb21wbGV0ZWQgd2l0aCBmYWlsdXJlczogJHtyZXN1bHQuZmFpbGVkRWxlbWVudHMuam9pbignLCAnKX1gKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGxvZ2dlci5pbmZvKGBFbnNlbWJsZSAke3RoaXMuaWR9IGFjdGl2YXRlZCBzdWNjZXNzZnVsbHkgaW4gJHtyZXN1bHQudG90YWxEdXJhdGlvbn1tc2ApO1xuICAgICAgfVxuXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHRoaXMuX3N0YXR1cyA9ICdlcnJvcicgYXMgRWxlbWVudFN0YXR1cztcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH0gZmluYWxseSB7XG4gICAgICB0aGlzLmFjdGl2YXRpb25JblByb2dyZXNzID0gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIERlYWN0aXZhdGUgdGhlIGVuc2VtYmxlIGFuZCBhbGwgaXRzIGVsZW1lbnRzXG4gICAqL1xuICBwdWJsaWMgb3ZlcnJpZGUgYXN5bmMgZGVhY3RpdmF0ZSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0aGlzLl9zdGF0dXMgPSAnaW5hY3RpdmUnIGFzIEVsZW1lbnRTdGF0dXM7XG4gICAgXG4gICAgLy8gRGVhY3RpdmF0ZSBhbGwgZWxlbWVudCBpbnN0YW5jZXNcbiAgICBjb25zdCBkZWFjdGl2YXRpb25Qcm9taXNlczogUHJvbWlzZTx2b2lkPltdID0gW107XG4gICAgXG4gICAgZm9yIChjb25zdCBbZWxlbWVudElkLCBpbnN0YW5jZV0gb2YgdGhpcy5lbGVtZW50SW5zdGFuY2VzKSB7XG4gICAgICBpZiAoaW5zdGFuY2UuZGVhY3RpdmF0ZSkge1xuICAgICAgICBkZWFjdGl2YXRpb25Qcm9taXNlcy5wdXNoKFxuICAgICAgICAgIGluc3RhbmNlLmRlYWN0aXZhdGUoKS5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICBsb2dnZXIuZXJyb3IoYEZhaWxlZCB0byBkZWFjdGl2YXRlIGVsZW1lbnQgJHtlbGVtZW50SWR9OmAsIGVycm9yKTtcbiAgICAgICAgICB9KVxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cblxuICAgIGF3YWl0IFByb21pc2UuYWxsKGRlYWN0aXZhdGlvblByb21pc2VzKTtcbiAgICBcbiAgICAvLyBDbGVhciBzaGFyZWQgY29udGV4dFxuICAgIHRoaXMuc2hhcmVkQ29udGV4dC52YWx1ZXMuY2xlYXIoKTtcbiAgICB0aGlzLnNoYXJlZENvbnRleHQub3duZXJzLmNsZWFyKCk7XG4gICAgdGhpcy5zaGFyZWRDb250ZXh0LnRpbWVzdGFtcHMuY2xlYXIoKTtcbiAgICBcbiAgICBsb2dnZXIuaW5mbyhgRW5zZW1ibGUgJHt0aGlzLmlkfSBkZWFjdGl2YXRlZGApO1xuICB9XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRlIHRoZSBlbnNlbWJsZSBjb25maWd1cmF0aW9uXG4gICAqL1xuICBwdWJsaWMgb3ZlcnJpZGUgdmFsaWRhdGUoKTogRWxlbWVudFZhbGlkYXRpb25SZXN1bHQge1xuICAgIGNvbnN0IHJlc3VsdCA9IHN1cGVyLnZhbGlkYXRlKCk7XG4gICAgXG4gICAgLy8gSW5pdGlhbGl6ZSBhcnJheXMgaWYgdGhleSBkb24ndCBleGlzdFxuICAgIGlmICghcmVzdWx0LmVycm9ycykgcmVzdWx0LmVycm9ycyA9IFtdO1xuICAgIGlmICghcmVzdWx0Lndhcm5pbmdzKSByZXN1bHQud2FybmluZ3MgPSBbXTtcbiAgICBcbiAgICAvLyBDaGVjayBmb3IgY2lyY3VsYXIgZGVwZW5kZW5jaWVzXG4gICAgY29uc3QgY2lyY3VsYXIgPSB0aGlzLmRldGVjdEFsbENpcmN1bGFyRGVwZW5kZW5jaWVzKCk7XG4gICAgaWYgKGNpcmN1bGFyLmxlbmd0aCA+IDApIHtcbiAgICAgIGZvciAoY29uc3QgY3ljbGUgb2YgY2lyY3VsYXIpIHtcbiAgICAgICAgcmVzdWx0LmVycm9ycy5wdXNoKHtcbiAgICAgICAgICBmaWVsZDogJ2RlcGVuZGVuY2llcycsXG4gICAgICAgICAgbWVzc2FnZTogY3ljbGUubWVzc2FnZSxcbiAgICAgICAgICBzZXZlcml0eTogJ2hpZ2gnXG4gICAgICAgIH0gYXMgVmFsaWRhdGlvbkVycm9yKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBWYWxpZGF0ZSBlbGVtZW50IGNvdW50XG4gICAgaWYgKHRoaXMuZWxlbWVudHMuc2l6ZSA9PT0gMCkge1xuICAgICAgcmVzdWx0Lndhcm5pbmdzLnB1c2goe1xuICAgICAgICBmaWVsZDogJ2VsZW1lbnRzJyxcbiAgICAgICAgbWVzc2FnZTogJ0Vuc2VtYmxlIGhhcyBubyBlbGVtZW50cycsXG4gICAgICAgIHN1Z2dlc3Rpb246ICdBZGQgZWxlbWVudHMgdXNpbmcgYWRkRWxlbWVudCgpJ1xuICAgICAgfSBhcyBWYWxpZGF0aW9uV2FybmluZyk7XG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgZm9yIG9ycGhhbmVkIGRlcGVuZGVuY2llc1xuICAgIGZvciAoY29uc3QgW2VsZW1lbnRJZCwgZWxlbWVudF0gb2YgdGhpcy5lbGVtZW50cykge1xuICAgICAgaWYgKGVsZW1lbnQuZGVwZW5kZW5jaWVzKSB7XG4gICAgICAgIGZvciAoY29uc3QgZGVwIG9mIGVsZW1lbnQuZGVwZW5kZW5jaWVzKSB7XG4gICAgICAgICAgaWYgKCF0aGlzLmVsZW1lbnRzLmhhcyhkZXApKSB7XG4gICAgICAgICAgICByZXN1bHQuZXJyb3JzLnB1c2goe1xuICAgICAgICAgICAgICBmaWVsZDogYCR7ZWxlbWVudElkfS5kZXBlbmRlbmNpZXNgLFxuICAgICAgICAgICAgICBtZXNzYWdlOiBgRGVwZW5kZW5jeSAnJHtkZXB9JyBub3QgZm91bmQgaW4gZW5zZW1ibGVgLFxuICAgICAgICAgICAgICBzZXZlcml0eTogJ21lZGl1bSdcbiAgICAgICAgICAgIH0gYXMgVmFsaWRhdGlvbkVycm9yKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBVcGRhdGUgdmFsaWQgZmxhZyBiYXNlZCBvbiBlcnJvcnNcbiAgICByZXN1bHQudmFsaWQgPSByZXN1bHQuZXJyb3JzLmxlbmd0aCA9PT0gMDtcbiAgICBcbiAgICAvLyBDbGVhbiB1cCBlbXB0eSBhcnJheXNcbiAgICBpZiAocmVzdWx0LmVycm9ycy5sZW5ndGggPT09IDApIHJlc3VsdC5lcnJvcnMgPSB1bmRlZmluZWQ7XG4gICAgaWYgKHJlc3VsdC53YXJuaW5ncy5sZW5ndGggPT09IDApIHJlc3VsdC53YXJuaW5ncyA9IHVuZGVmaW5lZDtcblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2sgaWYgYWRkaW5nIGFuIGVsZW1lbnQgd291bGQgY3JlYXRlIGEgY2lyY3VsYXIgZGVwZW5kZW5jeVxuICAgKiBNRURJVU0gRklYOiBSZW1vdmUgdHlwZSBzYWZldHkgYnlwYXNzXG4gICAqIFByZXZpb3VzbHk6IFVzZWQgJ2FzIGFueScgd2hpY2ggYnlwYXNzZXMgVHlwZVNjcmlwdCBjaGVja2luZ1xuICAgKiBOb3c6IENyZWF0ZXMgcHJvcGVyIEVuc2VtYmxlRWxlbWVudCB3aXRoIGFsbCByZXF1aXJlZCBmaWVsZHNcbiAgICovXG4gIHByaXZhdGUgd291bGRDcmVhdGVDaXJjdWxhckRlcGVuZGVuY3koZWxlbWVudElkOiBzdHJpbmcsIGRlcGVuZGVuY2llczogc3RyaW5nW10pOiBib29sZWFuIHtcbiAgICAvLyBDcmVhdGUgdGVtcG9yYXJ5IGdyYXBoIHdpdGggbmV3IGVsZW1lbnRcbiAgICBjb25zdCB0ZW1wR3JhcGggPSBuZXcgTWFwKHRoaXMuZWxlbWVudHMpO1xuICAgIFxuICAgIC8vIENyZWF0ZSBhIG1pbmltYWwgdmFsaWQgRW5zZW1ibGVFbGVtZW50IGZvciBkZXBlbmRlbmN5IGNoZWNraW5nXG4gICAgY29uc3QgdGVtcEVsZW1lbnQ6IEVuc2VtYmxlRWxlbWVudCA9IHtcbiAgICAgIGVsZW1lbnRJZCxcbiAgICAgIGVsZW1lbnRUeXBlOiAndW5rbm93bicsIC8vIFR5cGUgZG9lc24ndCBtYXR0ZXIgZm9yIGRlcGVuZGVuY3kgY2hlY2tpbmdcbiAgICAgIHJvbGU6ICdzdXBwb3J0JyBhcyBFbGVtZW50Um9sZSwgLy8gRGVmYXVsdCByb2xlXG4gICAgICBkZXBlbmRlbmNpZXNcbiAgICB9O1xuICAgIFxuICAgIHRlbXBHcmFwaC5zZXQoZWxlbWVudElkLCB0ZW1wRWxlbWVudCk7XG4gICAgXG4gICAgLy8gQ2hlY2sgZm9yIGN5Y2xlc1xuICAgIHJldHVybiB0aGlzLmhhc0N5Y2xlKHRlbXBHcmFwaCk7XG4gIH1cblxuICAvKipcbiAgICogRmluZCBjaXJjdWxhciBkZXBlbmRlbmN5IHBhdGhcbiAgICovXG4gIHByaXZhdGUgZmluZENpcmN1bGFyRGVwZW5kZW5jeShlbGVtZW50SWQ6IHN0cmluZywgZGVwZW5kZW5jaWVzOiBzdHJpbmdbXSk6IENpcmN1bGFyRGVwZW5kZW5jeSB7XG4gICAgY29uc3QgdmlzaXRlZCA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICAgIGNvbnN0IHJlY3Vyc2lvblN0YWNrID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gICAgY29uc3QgcGF0aDogc3RyaW5nW10gPSBbXTtcblxuICAgIGNvbnN0IGRmcyA9IChub2RlOiBzdHJpbmcpOiBzdHJpbmdbXSB8IG51bGwgPT4ge1xuICAgICAgdmlzaXRlZC5hZGQobm9kZSk7XG4gICAgICByZWN1cnNpb25TdGFjay5hZGQobm9kZSk7XG4gICAgICBwYXRoLnB1c2gobm9kZSk7XG5cbiAgICAgIGNvbnN0IGVsZW1lbnQgPSB0aGlzLmVsZW1lbnRzLmdldChub2RlKTtcbiAgICAgIGNvbnN0IGRlcHMgPSBub2RlID09PSBlbGVtZW50SWQgPyBkZXBlbmRlbmNpZXMgOiAoZWxlbWVudD8uZGVwZW5kZW5jaWVzIHx8IFtdKTtcblxuICAgICAgZm9yIChjb25zdCBkZXAgb2YgZGVwcykge1xuICAgICAgICBpZiAoIXZpc2l0ZWQuaGFzKGRlcCkpIHtcbiAgICAgICAgICBjb25zdCBjeWNsZSA9IGRmcyhkZXApO1xuICAgICAgICAgIGlmIChjeWNsZSkgcmV0dXJuIGN5Y2xlO1xuICAgICAgICB9IGVsc2UgaWYgKHJlY3Vyc2lvblN0YWNrLmhhcyhkZXApKSB7XG4gICAgICAgICAgLy8gRm91bmQgY3ljbGVcbiAgICAgICAgICBjb25zdCBjeWNsZVN0YXJ0ID0gcGF0aC5pbmRleE9mKGRlcCk7XG4gICAgICAgICAgcmV0dXJuIHBhdGguc2xpY2UoY3ljbGVTdGFydCkuY29uY2F0KGRlcCk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcGF0aC5wb3AoKTtcbiAgICAgIHJlY3Vyc2lvblN0YWNrLmRlbGV0ZShub2RlKTtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH07XG5cbiAgICBjb25zdCBjeWNsZVBhdGggPSBkZnMoZWxlbWVudElkKSB8fCBbXTtcbiAgICBcbiAgICByZXR1cm4ge1xuICAgICAgcGF0aDogY3ljbGVQYXRoLFxuICAgICAgbWVzc2FnZTogYENpcmN1bGFyIGRlcGVuZGVuY3k6ICR7Y3ljbGVQYXRoLmpvaW4oJyAtPiAnKX1gXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZXRlY3QgYWxsIGNpcmN1bGFyIGRlcGVuZGVuY2llcyBpbiB0aGUgZW5zZW1ibGVcbiAgICovXG4gIHByaXZhdGUgZGV0ZWN0QWxsQ2lyY3VsYXJEZXBlbmRlbmNpZXMoKTogQ2lyY3VsYXJEZXBlbmRlbmN5W10ge1xuICAgIGNvbnN0IGN5Y2xlczogQ2lyY3VsYXJEZXBlbmRlbmN5W10gPSBbXTtcbiAgICBjb25zdCB2aXNpdGVkID0gbmV3IFNldDxzdHJpbmc+KCk7XG5cbiAgICBmb3IgKGNvbnN0IGVsZW1lbnRJZCBvZiB0aGlzLmVsZW1lbnRzLmtleXMoKSkge1xuICAgICAgaWYgKCF2aXNpdGVkLmhhcyhlbGVtZW50SWQpICYmIHRoaXMuaGFzQ3ljbGVGcm9tKGVsZW1lbnRJZCwgdmlzaXRlZCkpIHtcbiAgICAgICAgY29uc3QgY3ljbGUgPSB0aGlzLmZpbmRDaXJjdWxhckRlcGVuZGVuY3koZWxlbWVudElkLCB0aGlzLmVsZW1lbnRzLmdldChlbGVtZW50SWQpIS5kZXBlbmRlbmNpZXMgfHwgW10pO1xuICAgICAgICBjeWNsZXMucHVzaChjeWNsZSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGN5Y2xlcztcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiBncmFwaCBoYXMgYW55IGN5Y2xlXG4gICAqL1xuICBwcml2YXRlIGhhc0N5Y2xlKGdyYXBoOiBNYXA8c3RyaW5nLCBFbnNlbWJsZUVsZW1lbnQ+KTogYm9vbGVhbiB7XG4gICAgY29uc3QgdmlzaXRlZCA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICAgIGNvbnN0IHJlY3Vyc2lvblN0YWNrID0gbmV3IFNldDxzdHJpbmc+KCk7XG5cbiAgICBjb25zdCBoYXNDeWNsZURGUyA9IChub2RlOiBzdHJpbmcpOiBib29sZWFuID0+IHtcbiAgICAgIHZpc2l0ZWQuYWRkKG5vZGUpO1xuICAgICAgcmVjdXJzaW9uU3RhY2suYWRkKG5vZGUpO1xuXG4gICAgICBjb25zdCBlbGVtZW50ID0gZ3JhcGguZ2V0KG5vZGUpO1xuICAgICAgY29uc3QgZGVwZW5kZW5jaWVzID0gZWxlbWVudD8uZGVwZW5kZW5jaWVzIHx8IFtdO1xuXG4gICAgICBmb3IgKGNvbnN0IGRlcCBvZiBkZXBlbmRlbmNpZXMpIHtcbiAgICAgICAgaWYgKCF2aXNpdGVkLmhhcyhkZXApKSB7XG4gICAgICAgICAgaWYgKGhhc0N5Y2xlREZTKGRlcCkpIHJldHVybiB0cnVlO1xuICAgICAgICB9IGVsc2UgaWYgKHJlY3Vyc2lvblN0YWNrLmhhcyhkZXApKSB7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmVjdXJzaW9uU3RhY2suZGVsZXRlKG5vZGUpO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH07XG5cbiAgICBmb3IgKGNvbnN0IG5vZGUgb2YgZ3JhcGgua2V5cygpKSB7XG4gICAgICBpZiAoIXZpc2l0ZWQuaGFzKG5vZGUpICYmIGhhc0N5Y2xlREZTKG5vZGUpKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBmb3IgY3ljbGUgc3RhcnRpbmcgZnJvbSBhIHNwZWNpZmljIG5vZGVcbiAgICovXG4gIHByaXZhdGUgaGFzQ3ljbGVGcm9tKG5vZGU6IHN0cmluZywgdmlzaXRlZDogU2V0PHN0cmluZz4pOiBib29sZWFuIHtcbiAgICBjb25zdCByZWN1cnNpb25TdGFjayA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuXG4gICAgY29uc3QgZGZzID0gKGN1cnJlbnQ6IHN0cmluZyk6IGJvb2xlYW4gPT4ge1xuICAgICAgdmlzaXRlZC5hZGQoY3VycmVudCk7XG4gICAgICByZWN1cnNpb25TdGFjay5hZGQoY3VycmVudCk7XG5cbiAgICAgIGNvbnN0IGVsZW1lbnQgPSB0aGlzLmVsZW1lbnRzLmdldChjdXJyZW50KTtcbiAgICAgIGNvbnN0IGRlcGVuZGVuY2llcyA9IGVsZW1lbnQ/LmRlcGVuZGVuY2llcyB8fCBbXTtcblxuICAgICAgZm9yIChjb25zdCBkZXAgb2YgZGVwZW5kZW5jaWVzKSB7XG4gICAgICAgIGlmICghdmlzaXRlZC5oYXMoZGVwKSkge1xuICAgICAgICAgIGlmIChkZnMoZGVwKSkgcmV0dXJuIHRydWU7XG4gICAgICAgIH0gZWxzZSBpZiAocmVjdXJzaW9uU3RhY2suaGFzKGRlcCkpIHtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZWN1cnNpb25TdGFjay5kZWxldGUoY3VycmVudCk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfTtcblxuICAgIHJldHVybiBkZnMobm9kZSk7XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGUgYWN0aXZhdGlvbiBjb25kaXRpb24gc3ludGF4XG4gICAqL1xuICBwcml2YXRlIGlzVmFsaWRDb25kaXRpb24oY29uZGl0aW9uOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICAvLyBGb3Igbm93LCBvbmx5IGFsbG93IHNpbXBsZSBjb25kaXRpb25zXG4gICAgLy8gRnV0dXJlOiBpbXBsZW1lbnQgYSBwcm9wZXIgY29uZGl0aW9uIHBhcnNlclxuICAgIHJldHVybiBFTlNFTUJMRV9QQVRURVJOUy5DT05ESVRJT05fUEFUVEVSTi50ZXN0KGNvbmRpdGlvbik7XG4gIH1cblxuICAvKipcbiAgICogR2V0IGFjdGl2YXRpb24gb3JkZXIgYmFzZWQgb24gZGVwZW5kZW5jaWVzIGFuZCBzdHJhdGVneVxuICAgKi9cbiAgcHJpdmF0ZSBnZXRBY3RpdmF0aW9uT3JkZXIoKTogc3RyaW5nW10ge1xuICAgIGNvbnN0IG9yZGVyOiBzdHJpbmdbXSA9IFtdO1xuICAgIGNvbnN0IHZpc2l0ZWQgPSBuZXcgU2V0PHN0cmluZz4oKTtcblxuICAgIC8vIFRvcG9sb2dpY2FsIHNvcnQgZm9yIGRlcGVuZGVuY3kgb3JkZXJcbiAgICBjb25zdCB2aXNpdCA9IChlbGVtZW50SWQ6IHN0cmluZykgPT4ge1xuICAgICAgaWYgKHZpc2l0ZWQuaGFzKGVsZW1lbnRJZCkpIHJldHVybjtcbiAgICAgIHZpc2l0ZWQuYWRkKGVsZW1lbnRJZCk7XG5cbiAgICAgIGNvbnN0IGVsZW1lbnQgPSB0aGlzLmVsZW1lbnRzLmdldChlbGVtZW50SWQpO1xuICAgICAgaWYgKGVsZW1lbnQ/LmRlcGVuZGVuY2llcykge1xuICAgICAgICBmb3IgKGNvbnN0IGRlcCBvZiBlbGVtZW50LmRlcGVuZGVuY2llcykge1xuICAgICAgICAgIGlmICh0aGlzLmVsZW1lbnRzLmhhcyhkZXApKSB7XG4gICAgICAgICAgICB2aXNpdChkZXApO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBvcmRlci5wdXNoKGVsZW1lbnRJZCk7XG4gICAgfTtcblxuICAgIC8vIFZpc2l0IGFsbCBlbGVtZW50c1xuICAgIGZvciAoY29uc3QgZWxlbWVudElkIG9mIHRoaXMuZWxlbWVudHMua2V5cygpKSB7XG4gICAgICB2aXNpdChlbGVtZW50SWQpO1xuICAgIH1cblxuICAgIHJldHVybiBvcmRlcjtcbiAgfVxuXG4gIC8qKlxuICAgKiBBY3RpdmF0ZSBlbGVtZW50cyBzZXF1ZW50aWFsbHlcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgYWN0aXZhdGVTZXF1ZW50aWFsKFxuICAgIG9yZGVyOiBzdHJpbmdbXSwgXG4gICAgcmVzdWx0OiBFbnNlbWJsZUFjdGl2YXRpb25SZXN1bHQsXG4gICAgbWF4VGltZTogbnVtYmVyXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHN0YXJ0VGltZSA9IERhdGUubm93KCk7XG5cbiAgICBmb3IgKGNvbnN0IGVsZW1lbnRJZCBvZiBvcmRlcikge1xuICAgICAgaWYgKERhdGUubm93KCkgLSBzdGFydFRpbWUgPiBtYXhUaW1lKSB7XG4gICAgICAgIFNlY3VyaXR5TW9uaXRvci5sb2dTZWN1cml0eUV2ZW50KHtcbiAgICAgICAgICB0eXBlOiBFTlNFTUJMRV9TRUNVUklUWV9FVkVOVFMuQUNUSVZBVElPTl9USU1FT1VULFxuICAgICAgICAgIHNldmVyaXR5OiAnSElHSCcsXG4gICAgICAgICAgc291cmNlOiAnRW5zZW1ibGUuYWN0aXZhdGVTZXF1ZW50aWFsJyxcbiAgICAgICAgICBkZXRhaWxzOiBgQWN0aXZhdGlvbiB0aW1lb3V0IGFmdGVyICR7RGF0ZS5ub3coKSAtIHN0YXJ0VGltZX1tc2BcbiAgICAgICAgfSk7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihFTlNFTUJMRV9FUlJPUlMuQUNUSVZBVElPTl9USU1FT1VUKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgZWxlbWVudFJlc3VsdCA9IGF3YWl0IHRoaXMuYWN0aXZhdGVFbGVtZW50KGVsZW1lbnRJZCk7XG4gICAgICByZXN1bHQuZWxlbWVudFJlc3VsdHMucHVzaChlbGVtZW50UmVzdWx0KTtcblxuICAgICAgaWYgKGVsZW1lbnRSZXN1bHQuc3VjY2Vzcykge1xuICAgICAgICByZXN1bHQuYWN0aXZhdGVkRWxlbWVudHMucHVzaChlbGVtZW50SWQpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzdWx0LmZhaWxlZEVsZW1lbnRzLnB1c2goZWxlbWVudElkKTtcbiAgICAgIH1cblxuICAgICAgLy8gU21hbGwgZGVsYXkgYmV0d2VlbiBhY3RpdmF0aW9uc1xuICAgICAgYXdhaXQgbmV3IFByb21pc2UocmVzb2x2ZSA9PiBzZXRUaW1lb3V0KHJlc29sdmUsIEVOU0VNQkxFX0xJTUlUUy5NSU5fQUNUSVZBVElPTl9JTlRFUlZBTCkpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBBY3RpdmF0ZSBhbGwgZWxlbWVudHMgc2ltdWx0YW5lb3VzbHkgYXMgb25lIHVuaWZpZWQgZW50aXR5XG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGFjdGl2YXRlQWxsKFxuICAgIG9yZGVyOiBzdHJpbmdbXSwgXG4gICAgcmVzdWx0OiBFbnNlbWJsZUFjdGl2YXRpb25SZXN1bHQsXG4gICAgbWF4VGltZTogbnVtYmVyXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHN0YXJ0VGltZSA9IERhdGUubm93KCk7XG4gICAgXG4gICAgY29uc3QgYWN0aXZhdGlvblByb21pc2VzID0gb3JkZXIubWFwKGVsZW1lbnRJZCA9PiBcbiAgICAgIHRoaXMuYWN0aXZhdGVFbGVtZW50KGVsZW1lbnRJZCkudGhlbihlbGVtZW50UmVzdWx0ID0+IHtcbiAgICAgICAgcmVzdWx0LmVsZW1lbnRSZXN1bHRzLnB1c2goZWxlbWVudFJlc3VsdCk7XG4gICAgICAgIGlmIChlbGVtZW50UmVzdWx0LnN1Y2Nlc3MpIHtcbiAgICAgICAgICByZXN1bHQuYWN0aXZhdGVkRWxlbWVudHMucHVzaChlbGVtZW50SWQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJlc3VsdC5mYWlsZWRFbGVtZW50cy5wdXNoKGVsZW1lbnRJZCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGVsZW1lbnRSZXN1bHQ7XG4gICAgICB9KVxuICAgICk7XG5cbiAgICAvLyBXYWl0IGZvciBhbGwgd2l0aCB0aW1lb3V0XG4gICAgYXdhaXQgUHJvbWlzZS5yYWNlKFtcbiAgICAgIFByb21pc2UuYWxsKGFjdGl2YXRpb25Qcm9taXNlcyksXG4gICAgICBuZXcgUHJvbWlzZSgoXywgcmVqZWN0KSA9PiBcbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiByZWplY3QobmV3IEVycm9yKEVOU0VNQkxFX0VSUk9SUy5BQ1RJVkFUSU9OX1RJTUVPVVQpKSwgbWF4VGltZSlcbiAgICAgIClcbiAgICBdKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBY3RpdmF0ZSBlbGVtZW50cyBieSBwcmlvcml0eVxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBhY3RpdmF0ZVByaW9yaXR5KFxuICAgIG9yZGVyOiBzdHJpbmdbXSwgXG4gICAgcmVzdWx0OiBFbnNlbWJsZUFjdGl2YXRpb25SZXN1bHQsXG4gICAgbWF4VGltZTogbnVtYmVyXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIC8vIFNvcnQgYnkgcHJpb3JpdHlcbiAgICBjb25zdCBwcmlvcml0eU9yZGVyID0gWy4uLm9yZGVyXS5zb3J0KChhLCBiKSA9PiB7XG4gICAgICBjb25zdCBwcmlvcml0eUEgPSB0aGlzLmVsZW1lbnRzLmdldChhKT8ucHJpb3JpdHkgPz8gMDtcbiAgICAgIGNvbnN0IHByaW9yaXR5QiA9IHRoaXMuZWxlbWVudHMuZ2V0KGIpPy5wcmlvcml0eSA/PyAwO1xuICAgICAgcmV0dXJuIHByaW9yaXR5QiAtIHByaW9yaXR5QTsgLy8gSGlnaGVyIHByaW9yaXR5IGZpcnN0XG4gICAgfSk7XG5cbiAgICBhd2FpdCB0aGlzLmFjdGl2YXRlU2VxdWVudGlhbChwcmlvcml0eU9yZGVyLCByZXN1bHQsIG1heFRpbWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEFjdGl2YXRlIGVsZW1lbnRzIGJhc2VkIG9uIGNvbmRpdGlvbnNcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgYWN0aXZhdGVDb25kaXRpb25hbChcbiAgICBvcmRlcjogc3RyaW5nW10sIFxuICAgIHJlc3VsdDogRW5zZW1ibGVBY3RpdmF0aW9uUmVzdWx0LFxuICAgIG1heFRpbWU6IG51bWJlclxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBzdGFydFRpbWUgPSBEYXRlLm5vdygpO1xuXG4gICAgZm9yIChjb25zdCBlbGVtZW50SWQgb2Ygb3JkZXIpIHtcbiAgICAgIGlmIChEYXRlLm5vdygpIC0gc3RhcnRUaW1lID4gbWF4VGltZSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoRU5TRU1CTEVfRVJST1JTLkFDVElWQVRJT05fVElNRU9VVCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGVsZW1lbnQgPSB0aGlzLmVsZW1lbnRzLmdldChlbGVtZW50SWQpITtcbiAgICAgIFxuICAgICAgLy8gQ2hlY2sgYWN0aXZhdGlvbiBjb25kaXRpb25cbiAgICAgIGlmIChlbGVtZW50LmFjdGl2YXRpb25Db25kaXRpb24pIHtcbiAgICAgICAgaWYgKCF0aGlzLmV2YWx1YXRlQ29uZGl0aW9uKGVsZW1lbnQuYWN0aXZhdGlvbkNvbmRpdGlvbikpIHtcbiAgICAgICAgICBsb2dnZXIuaW5mbyhgU2tpcHBpbmcgZWxlbWVudCAke2VsZW1lbnRJZH0gLSBjb25kaXRpb24gbm90IG1ldGApO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGVsZW1lbnRSZXN1bHQgPSBhd2FpdCB0aGlzLmFjdGl2YXRlRWxlbWVudChlbGVtZW50SWQpO1xuICAgICAgcmVzdWx0LmVsZW1lbnRSZXN1bHRzLnB1c2goZWxlbWVudFJlc3VsdCk7XG5cbiAgICAgIGlmIChlbGVtZW50UmVzdWx0LnN1Y2Nlc3MpIHtcbiAgICAgICAgcmVzdWx0LmFjdGl2YXRlZEVsZW1lbnRzLnB1c2goZWxlbWVudElkKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJlc3VsdC5mYWlsZWRFbGVtZW50cy5wdXNoKGVsZW1lbnRJZCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEFjdGl2YXRlIGEgc2luZ2xlIGVsZW1lbnRcbiAgICogQ1JJVElDQUwgRklYOiBJbXBsZW1lbnQgYWN0dWFsIGVsZW1lbnQgbG9hZGluZyBhbmQgYWN0aXZhdGlvblxuICAgKiBQcmV2aW91c2x5OiBKdXN0IHNpbXVsYXRlZCB3aXRoIHRpbWVvdXRcbiAgICogTm93OiBMb2FkcyBlbGVtZW50IGZyb20gcG9ydGZvbGlvIGFuZCBhY3RpdmF0ZXMgaXRcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgYWN0aXZhdGVFbGVtZW50KGVsZW1lbnRJZDogc3RyaW5nKTogUHJvbWlzZTxFbGVtZW50QWN0aXZhdGlvblJlc3VsdD4ge1xuICAgIGNvbnN0IHN0YXJ0VGltZSA9IERhdGUubm93KCk7XG4gICAgXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGVuc2VtYmxlRWxlbWVudCA9IHRoaXMuZWxlbWVudHMuZ2V0KGVsZW1lbnRJZCk7XG4gICAgICBpZiAoIWVuc2VtYmxlRWxlbWVudCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEVsZW1lbnQgJHtlbGVtZW50SWR9IG5vdCBmb3VuZCBpbiBlbnNlbWJsZWApO1xuICAgICAgfVxuXG4gICAgICAvLyBMb2FkIHRoZSBlbGVtZW50IGJhc2VkIG9uIGl0cyB0eXBlXG4gICAgICBjb25zdCBwb3J0Zm9saW9NYW5hZ2VyID0gUG9ydGZvbGlvTWFuYWdlci5nZXRJbnN0YW5jZSgpO1xuICAgICAgY29uc3QgZWxlbWVudEZpbGVuYW1lID0gYCR7ZWxlbWVudElkfS5tZGA7XG5cbiAgICAgIGxvZ2dlci5pbmZvKGBBY3RpdmF0aW5nIGVsZW1lbnQ6ICR7ZWxlbWVudElkfSBvZiB0eXBlICR7ZW5zZW1ibGVFbGVtZW50LmVsZW1lbnRUeXBlfWApO1xuICAgICAgXG4gICAgICAvLyBGb3Igbm93LCB3ZSBvbmx5IGhhdmUgUGVyc29uYUVsZW1lbnQgZnVsbHkgaW1wbGVtZW50ZWRcbiAgICAgIC8vIEZ1dHVyZTogQWRkIGZhY3RvcnkgcGF0dGVybiBmb3Igb3RoZXIgZWxlbWVudCB0eXBlc1xuICAgICAgbGV0IGVsZW1lbnQ6IElFbGVtZW50IHwgdW5kZWZpbmVkO1xuICAgICAgXG4gICAgICBpZiAoZW5zZW1ibGVFbGVtZW50LmVsZW1lbnRUeXBlID09PSBFbGVtZW50VHlwZS5QRVJTT05BKSB7XG4gICAgICAgIC8vIExvYWQgUGVyc29uYUVsZW1lbnRcbiAgICAgICAgY29uc3QgeyBQZXJzb25hRWxlbWVudE1hbmFnZXIgfSA9IGF3YWl0IGltcG9ydCgnLi4vLi4vcGVyc29uYS9QZXJzb25hRWxlbWVudE1hbmFnZXIuanMnKTtcbiAgICAgICAgY29uc3QgbWFuYWdlciA9IG5ldyBQZXJzb25hRWxlbWVudE1hbmFnZXIocG9ydGZvbGlvTWFuYWdlcik7XG4gICAgICAgIGVsZW1lbnQgPSBhd2FpdCBtYW5hZ2VyLmxvYWQoZWxlbWVudEZpbGVuYW1lKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIEZvciBvdGhlciB0eXBlcywgbG9nIHdhcm5pbmcgYW5kIHJldHVybiBzdWNjZXNzXG4gICAgICAgIC8vIFRoaXMgYWxsb3dzIGVuc2VtYmxlIHRvIHdvcmsgd2l0aCBmdXR1cmUgZWxlbWVudCB0eXBlc1xuICAgICAgICBsb2dnZXIud2FybihgRWxlbWVudCB0eXBlICR7ZW5zZW1ibGVFbGVtZW50LmVsZW1lbnRUeXBlfSBub3QgeWV0IGltcGxlbWVudGVkIGZvciBhY3RpdmF0aW9uYCk7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgZWxlbWVudElkLFxuICAgICAgICAgIHN1Y2Nlc3M6IHRydWUsXG4gICAgICAgICAgZHVyYXRpb246IERhdGUubm93KCkgLSBzdGFydFRpbWUsXG4gICAgICAgICAgY29udGV4dDogeyB3YXJuaW5nOiBgVHlwZSAke2Vuc2VtYmxlRWxlbWVudC5lbGVtZW50VHlwZX0gYWN0aXZhdGlvbiBub3QgaW1wbGVtZW50ZWRgIH1cbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgLy8gU3RvcmUgZWxlbWVudCBpbnN0YW5jZSBmb3IgbGF0ZXIgdXNlXG4gICAgICBpZiAoZWxlbWVudCkge1xuICAgICAgICB0aGlzLmVsZW1lbnRJbnN0YW5jZXMuc2V0KGVsZW1lbnRJZCwgZWxlbWVudCk7XG4gICAgICAgIFxuICAgICAgICAvLyBDYWxsIGVsZW1lbnQncyBhY3RpdmF0ZSBtZXRob2QgaWYgaXQgZXhpc3RzXG4gICAgICAgIGlmIChlbGVtZW50LmFjdGl2YXRlKSB7XG4gICAgICAgICAgYXdhaXQgZWxlbWVudC5hY3RpdmF0ZSgpO1xuICAgICAgICB9XG4gICAgICAgIFxuICAgICAgICAvLyBFeHRyYWN0IGFueSBjb250ZXh0IGZyb20gdGhlIGVsZW1lbnRcbiAgICAgICAgY29uc3QgY29udGV4dDogUmVjb3JkPHN0cmluZywgYW55PiA9IHt9O1xuICAgICAgICBpZiAoZWxlbWVudC5nZXRTdGF0dXMpIHtcbiAgICAgICAgICBjb250ZXh0LnN0YXR1cyA9IGVsZW1lbnQuZ2V0U3RhdHVzKCk7XG4gICAgICAgIH1cbiAgICAgICAgY29udGV4dC50eXBlID0gZW5zZW1ibGVFbGVtZW50LmVsZW1lbnRUeXBlO1xuICAgICAgICBjb250ZXh0LnJvbGUgPSBlbnNlbWJsZUVsZW1lbnQucm9sZTtcbiAgICAgICAgXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgZWxlbWVudElkLFxuICAgICAgICAgIHN1Y2Nlc3M6IHRydWUsXG4gICAgICAgICAgZHVyYXRpb246IERhdGUubm93KCkgLSBzdGFydFRpbWUsXG4gICAgICAgICAgY29udGV4dFxuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgXG4gICAgICByZXR1cm4ge1xuICAgICAgICBlbGVtZW50SWQsXG4gICAgICAgIHN1Y2Nlc3M6IHRydWUsXG4gICAgICAgIGR1cmF0aW9uOiBEYXRlLm5vdygpIC0gc3RhcnRUaW1lLFxuICAgICAgICBjb250ZXh0OiB7fVxuICAgICAgfTtcbiAgICAgIFxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBsb2dnZXIuZXJyb3IoYEZhaWxlZCB0byBhY3RpdmF0ZSBlbGVtZW50ICR7ZWxlbWVudElkfTpgLCBlcnJvcik7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBlbGVtZW50SWQsXG4gICAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgICAgICBkdXJhdGlvbjogRGF0ZS5ub3coKSAtIHN0YXJ0VGltZSxcbiAgICAgICAgZXJyb3I6IGVycm9yIGFzIEVycm9yXG4gICAgICB9O1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBFdmFsdWF0ZSBhIHNpbXBsZSBjb25kaXRpb25cbiAgICogQ1JJVElDQUwgRklYOiBJbXBsZW1lbnQgYWN0dWFsIGNvbmRpdGlvbiBldmFsdWF0aW9uXG4gICAqIFByZXZpb3VzbHk6IEFsd2F5cyByZXR1cm5lZCB0cnVlXG4gICAqIE5vdzogUGFyc2VzIGFuZCBldmFsdWF0ZXMgc2ltcGxlIGNvbmRpdGlvbnMgbGlrZSBcImVsZW1lbnQucHJvcGVydHkgPT0gdmFsdWVcIlxuICAgKiBcbiAgICogU3VwcG9ydGVkIG9wZXJhdG9yczogPT0sICE9LCA+LCA8LCA+PSwgPD1cbiAgICogU3VwcG9ydGVkIHByb3BlcnRpZXM6IGFjdGl2ZSwgc3RhdHVzLCBwcmlvcml0eVxuICAgKiBFeGFtcGxlOiBcImVsZW1lbnQxLmFjdGl2ZSA9PSB0cnVlXCIgb3IgXCJlbGVtZW50Mi5wcmlvcml0eSA+IDUwXCJcbiAgICovXG4gIHByaXZhdGUgZXZhbHVhdGVDb25kaXRpb24oY29uZGl0aW9uOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICB0cnkge1xuICAgICAgLy8gU2FuaXRpemUgYW5kIHZhbGlkYXRlIGNvbmRpdGlvbiBmaXJzdFxuICAgICAgY29uc3Qgc2FuaXRpemVkID0gc2FuaXRpemVJbnB1dChjb25kaXRpb24sIEVOU0VNQkxFX0xJTUlUUy5NQVhfQ09ORElUSU9OX0xFTkdUSCk7XG4gICAgICBcbiAgICAgIC8vIFBhcnNlIGNvbmRpdGlvbjogZWxlbWVudElkLnByb3BlcnR5IG9wZXJhdG9yIHZhbHVlXG4gICAgICBjb25zdCBtYXRjaCA9IHNhbml0aXplZC5tYXRjaCgvXihbYS16QS1aMC05XFwtX10rKVxcLihbYS16QS1aXSspXFxzKig9PXwhPXw+PXw8PXw+fDwpXFxzKiguKykkLyk7XG4gICAgICBcbiAgICAgIGlmICghbWF0Y2gpIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oYEludmFsaWQgY29uZGl0aW9uIGZvcm1hdDogJHtjb25kaXRpb259YCk7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIFxuICAgICAgY29uc3QgWywgZWxlbWVudElkLCBwcm9wZXJ0eSwgb3BlcmF0b3IsIHZhbHVlXSA9IG1hdGNoO1xuICAgICAgXG4gICAgICAvLyBHZXQgZWxlbWVudCBpbnN0YW5jZSBvciBlbGVtZW50IGRhdGFcbiAgICAgIGNvbnN0IGVsZW1lbnQgPSB0aGlzLmVsZW1lbnRJbnN0YW5jZXMuZ2V0KGVsZW1lbnRJZCk7XG4gICAgICBjb25zdCBlbGVtZW50RGF0YSA9IHRoaXMuZWxlbWVudHMuZ2V0KGVsZW1lbnRJZCk7XG4gICAgICBcbiAgICAgIGlmICghZWxlbWVudCAmJiAhZWxlbWVudERhdGEpIHtcbiAgICAgICAgbG9nZ2VyLmRlYnVnKGBFbGVtZW50ICR7ZWxlbWVudElkfSBub3QgZm91bmQgZm9yIGNvbmRpdGlvbiBldmFsdWF0aW9uYCk7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIFxuICAgICAgLy8gR2V0IHByb3BlcnR5IHZhbHVlXG4gICAgICBsZXQgcHJvcGVydHlWYWx1ZTogYW55O1xuICAgICAgXG4gICAgICBzd2l0Y2ggKHByb3BlcnR5KSB7XG4gICAgICAgIGNhc2UgJ2FjdGl2ZSc6XG4gICAgICAgICAgLy8gQ2hlY2sgaWYgZWxlbWVudCBpcyBpbiBhY3RpdmF0ZWQgZWxlbWVudHMgbGlzdFxuICAgICAgICAgIHByb3BlcnR5VmFsdWUgPSB0aGlzLmxhc3RBY3RpdmF0aW9uUmVzdWx0Py5hY3RpdmF0ZWRFbGVtZW50cy5pbmNsdWRlcyhlbGVtZW50SWQpIHx8IGZhbHNlO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIFxuICAgICAgICBjYXNlICdzdGF0dXMnOlxuICAgICAgICAgIHByb3BlcnR5VmFsdWUgPSBlbGVtZW50Py5nZXRTdGF0dXMgPyBlbGVtZW50LmdldFN0YXR1cygpIDogJ2luYWN0aXZlJztcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgICBcbiAgICAgICAgY2FzZSAncHJpb3JpdHknOlxuICAgICAgICAgIHByb3BlcnR5VmFsdWUgPSBlbGVtZW50RGF0YT8ucHJpb3JpdHkgfHwgMDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgICBcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICBsb2dnZXIud2FybihgVW5rbm93biBwcm9wZXJ0eSBpbiBjb25kaXRpb246ICR7cHJvcGVydHl9YCk7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgXG4gICAgICAvLyBQYXJzZSB0aGUgY29tcGFyaXNvbiB2YWx1ZVxuICAgICAgbGV0IGNvbXBhcmVWYWx1ZTogYW55ID0gdmFsdWUudHJpbSgpO1xuICAgICAgXG4gICAgICAvLyBIYW5kbGUgYm9vbGVhbiB2YWx1ZXNcbiAgICAgIGlmIChjb21wYXJlVmFsdWUgPT09ICd0cnVlJykgY29tcGFyZVZhbHVlID0gdHJ1ZTtcbiAgICAgIGVsc2UgaWYgKGNvbXBhcmVWYWx1ZSA9PT0gJ2ZhbHNlJykgY29tcGFyZVZhbHVlID0gZmFsc2U7XG4gICAgICAvLyBIYW5kbGUgbnVtZXJpYyB2YWx1ZXNcbiAgICAgIGVsc2UgaWYgKCFpc05hTihOdW1iZXIoY29tcGFyZVZhbHVlKSkpIGNvbXBhcmVWYWx1ZSA9IE51bWJlcihjb21wYXJlVmFsdWUpO1xuICAgICAgLy8gSGFuZGxlIHN0cmluZyB2YWx1ZXMgKHJlbW92ZSBxdW90ZXMgaWYgcHJlc2VudClcbiAgICAgIGVsc2UgaWYgKGNvbXBhcmVWYWx1ZS5zdGFydHNXaXRoKCdcIicpICYmIGNvbXBhcmVWYWx1ZS5lbmRzV2l0aCgnXCInKSkge1xuICAgICAgICBjb21wYXJlVmFsdWUgPSBjb21wYXJlVmFsdWUuc2xpY2UoMSwgLTEpO1xuICAgICAgfVxuICAgICAgXG4gICAgICAvLyBFdmFsdWF0ZSBiYXNlZCBvbiBvcGVyYXRvclxuICAgICAgc3dpdGNoIChvcGVyYXRvcikge1xuICAgICAgICBjYXNlICc9PSc6XG4gICAgICAgICAgcmV0dXJuIHByb3BlcnR5VmFsdWUgPT0gY29tcGFyZVZhbHVlO1xuICAgICAgICBjYXNlICchPSc6XG4gICAgICAgICAgcmV0dXJuIHByb3BlcnR5VmFsdWUgIT0gY29tcGFyZVZhbHVlO1xuICAgICAgICBjYXNlICc+JzpcbiAgICAgICAgICByZXR1cm4gTnVtYmVyKHByb3BlcnR5VmFsdWUpID4gTnVtYmVyKGNvbXBhcmVWYWx1ZSk7XG4gICAgICAgIGNhc2UgJzwnOlxuICAgICAgICAgIHJldHVybiBOdW1iZXIocHJvcGVydHlWYWx1ZSkgPCBOdW1iZXIoY29tcGFyZVZhbHVlKTtcbiAgICAgICAgY2FzZSAnPj0nOlxuICAgICAgICAgIHJldHVybiBOdW1iZXIocHJvcGVydHlWYWx1ZSkgPj0gTnVtYmVyKGNvbXBhcmVWYWx1ZSk7XG4gICAgICAgIGNhc2UgJzw9JzpcbiAgICAgICAgICByZXR1cm4gTnVtYmVyKHByb3BlcnR5VmFsdWUpIDw9IE51bWJlcihjb21wYXJlVmFsdWUpO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIGxvZ2dlci53YXJuKGBVbmtub3duIG9wZXJhdG9yIGluIGNvbmRpdGlvbjogJHtvcGVyYXRvcn1gKTtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICBcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgbG9nZ2VyLmVycm9yKGBFcnJvciBldmFsdWF0aW5nIGNvbmRpdGlvbiBcIiR7Y29uZGl0aW9ufVwiOmAsIGVycm9yKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogR2V0IHNoYXJlZCBjb250ZXh0IHZhbHVlXG4gICAqL1xuICBwdWJsaWMgZ2V0Q29udGV4dFZhbHVlKGtleTogc3RyaW5nKTogYW55IHtcbiAgICByZXR1cm4gdGhpcy5zaGFyZWRDb250ZXh0LnZhbHVlcy5nZXQoa2V5KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXQgc2hhcmVkIGNvbnRleHQgdmFsdWUgd2l0aCBjb25mbGljdCByZXNvbHV0aW9uXG4gICAqL1xuICBwdWJsaWMgc2V0Q29udGV4dFZhbHVlKGtleTogc3RyaW5nLCB2YWx1ZTogYW55LCBlbGVtZW50SWQ6IHN0cmluZyk6IENvbnRleHRDb25mbGljdCB8IG51bGwge1xuICAgIC8vIENoZWNrIGNvbnRleHQgc2l6ZSBsaW1pdHNcbiAgICBpZiAodGhpcy5zaGFyZWRDb250ZXh0LnZhbHVlcy5zaXplID49IEVOU0VNQkxFX0xJTUlUUy5NQVhfQ09OVEVYVF9TSVpFKSB7XG4gICAgICBTZWN1cml0eU1vbml0b3IubG9nU2VjdXJpdHlFdmVudCh7XG4gICAgICAgIHR5cGU6IEVOU0VNQkxFX1NFQ1VSSVRZX0VWRU5UUy5DT05URVhUX1NJWkVfRVhDRUVERUQsXG4gICAgICAgIHNldmVyaXR5OiAnTUVESVVNJyxcbiAgICAgICAgc291cmNlOiAnRW5zZW1ibGUuc2V0Q29udGV4dFZhbHVlJyxcbiAgICAgICAgZGV0YWlsczogYENvbnRleHQgc2l6ZSBsaW1pdCAoJHtFTlNFTUJMRV9MSU1JVFMuTUFYX0NPTlRFWFRfU0laRX0pIGV4Y2VlZGVkYFxuICAgICAgfSk7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoRU5TRU1CTEVfRVJST1JTLkNPTlRFWFRfT1ZFUkZMT1cpO1xuICAgIH1cblxuICAgIC8vIFNhbml0aXplIGtleVxuICAgIGNvbnN0IHNhbml0aXplZEtleSA9IHNhbml0aXplSW5wdXQoa2V5LCAxMDApO1xuICAgIFxuICAgIC8vIENoZWNrIHZhbHVlIHNpemVcbiAgICBjb25zdCB2YWx1ZVN0ciA9IEpTT04uc3RyaW5naWZ5KHZhbHVlKTtcbiAgICBpZiAodmFsdWVTdHIubGVuZ3RoID4gRU5TRU1CTEVfTElNSVRTLk1BWF9DT05URVhUX1ZBTFVFX1NJWkUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQ29udGV4dCB2YWx1ZSB0b28gbGFyZ2UnKTtcbiAgICB9XG5cbiAgICBjb25zdCBjdXJyZW50T3duZXIgPSB0aGlzLnNoYXJlZENvbnRleHQub3duZXJzLmdldChzYW5pdGl6ZWRLZXkpO1xuICAgIGNvbnN0IGN1cnJlbnRWYWx1ZSA9IHRoaXMuc2hhcmVkQ29udGV4dC52YWx1ZXMuZ2V0KHNhbml0aXplZEtleSk7XG4gICAgXG4gICAgLy8gQ2hlY2sgZm9yIGNvbmZsaWN0XG4gICAgaWYgKGN1cnJlbnRPd25lciAmJiBjdXJyZW50T3duZXIgIT09IGVsZW1lbnRJZCkge1xuICAgICAgY29uc3QgY29uZmxpY3Q6IENvbnRleHRDb25mbGljdCA9IHtcbiAgICAgICAga2V5OiBzYW5pdGl6ZWRLZXksXG4gICAgICAgIGN1cnJlbnRWYWx1ZSxcbiAgICAgICAgY3VycmVudE93bmVyLFxuICAgICAgICBuZXdWYWx1ZTogdmFsdWUsXG4gICAgICAgIG5ld093bmVyOiBlbGVtZW50SWRcbiAgICAgIH07XG5cbiAgICAgIC8vIEFwcGx5IGNvbmZsaWN0IHJlc29sdXRpb25cbiAgICAgIGNvbnN0IG1ldGFkYXRhID0gdGhpcy5tZXRhZGF0YSBhcyBFbnNlbWJsZU1ldGFkYXRhO1xuICAgICAgc3dpdGNoIChtZXRhZGF0YS5jb25mbGljdFJlc29sdXRpb24pIHtcbiAgICAgICAgY2FzZSAnZXJyb3InOlxuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgQ29udGV4dCBjb25mbGljdCBvbiBrZXkgJyR7c2FuaXRpemVkS2V5fSdgKTtcbiAgICAgICAgXG4gICAgICAgIGNhc2UgJ2ZpcnN0LXdyaXRlJzpcbiAgICAgICAgICAvLyBLZWVwIGV4aXN0aW5nIHZhbHVlXG4gICAgICAgICAgcmV0dXJuIGNvbmZsaWN0O1xuICAgICAgICBcbiAgICAgICAgY2FzZSAnbGFzdC13cml0ZSc6XG4gICAgICAgICAgLy8gT3ZlcndyaXRlIHdpdGggbmV3IHZhbHVlXG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIFxuICAgICAgICBjYXNlICdwcmlvcml0eSc6XG4gICAgICAgICAgY29uc3QgY3VycmVudFByaW9yaXR5ID0gdGhpcy5lbGVtZW50cy5nZXQoY3VycmVudE93bmVyKT8ucHJpb3JpdHkgPz8gMDtcbiAgICAgICAgICBjb25zdCBuZXdQcmlvcml0eSA9IHRoaXMuZWxlbWVudHMuZ2V0KGVsZW1lbnRJZCk/LnByaW9yaXR5ID8/IDA7XG4gICAgICAgICAgaWYgKGN1cnJlbnRQcmlvcml0eSA+IG5ld1ByaW9yaXR5KSB7XG4gICAgICAgICAgICByZXR1cm4gY29uZmxpY3Q7XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBcbiAgICAgICAgY2FzZSAnbWVyZ2UnOlxuICAgICAgICAgIC8vIFNpbXBsZSBtZXJnZSBmb3Igb2JqZWN0c1xuICAgICAgICAgIGlmICh0eXBlb2YgY3VycmVudFZhbHVlID09PSAnb2JqZWN0JyAmJiB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICB2YWx1ZSA9IHsgLi4uY3VycmVudFZhbHVlLCAuLi52YWx1ZSB9O1xuICAgICAgICAgICAgY29uZmxpY3QucmVzb2x1dGlvbiA9IHZhbHVlO1xuICAgICAgICAgIH1cbiAgICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBTZXQgdGhlIHZhbHVlXG4gICAgdGhpcy5zaGFyZWRDb250ZXh0LnZhbHVlcy5zZXQoc2FuaXRpemVkS2V5LCB2YWx1ZSk7XG4gICAgdGhpcy5zaGFyZWRDb250ZXh0Lm93bmVycy5zZXQoc2FuaXRpemVkS2V5LCBlbGVtZW50SWQpO1xuICAgIHRoaXMuc2hhcmVkQ29udGV4dC50aW1lc3RhbXBzLnNldChzYW5pdGl6ZWRLZXksIG5ldyBEYXRlKCkpO1xuXG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICAvKipcbiAgICogR2V0IGFsbCBlbGVtZW50cyBpbiB0aGUgZW5zZW1ibGVcbiAgICovXG4gIHB1YmxpYyBnZXRFbGVtZW50cygpOiBNYXA8c3RyaW5nLCBFbnNlbWJsZUVsZW1lbnQ+IHtcbiAgICByZXR1cm4gbmV3IE1hcCh0aGlzLmVsZW1lbnRzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgYWN0aXZhdGlvbiByZXN1bHRcbiAgICovXG4gIHB1YmxpYyBnZXRMYXN0QWN0aXZhdGlvblJlc3VsdCgpOiBFbnNlbWJsZUFjdGl2YXRpb25SZXN1bHQgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLmxhc3RBY3RpdmF0aW9uUmVzdWx0O1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBjdXJyZW50IGVsZW1lbnQgc3RhdHVzXG4gICAqL1xuICBwdWJsaWMgb3ZlcnJpZGUgZ2V0U3RhdHVzKCk6IEVsZW1lbnRTdGF0dXMge1xuICAgIHJldHVybiB0aGlzLl9zdGF0dXM7XG4gIH1cblxuICAvKipcbiAgICogU2VyaWFsaXplIGVuc2VtYmxlIHRvIHN0cmluZ1xuICAgKi9cbiAgcHVibGljIG92ZXJyaWRlIHNlcmlhbGl6ZSgpOiBzdHJpbmcge1xuICAgIGNvbnN0IGRhdGEgPSB7XG4gICAgICBiYXNlOiBzdXBlci5zZXJpYWxpemUoKSxcbiAgICAgIGVsZW1lbnRzOiBBcnJheS5mcm9tKHRoaXMuZWxlbWVudHMuZW50cmllcygpKSxcbiAgICAgIHNoYXJlZENvbnRleHQ6IHtcbiAgICAgICAgdmFsdWVzOiBBcnJheS5mcm9tKHRoaXMuc2hhcmVkQ29udGV4dC52YWx1ZXMuZW50cmllcygpKSxcbiAgICAgICAgb3duZXJzOiBBcnJheS5mcm9tKHRoaXMuc2hhcmVkQ29udGV4dC5vd25lcnMuZW50cmllcygpKSxcbiAgICAgICAgdGltZXN0YW1wczogQXJyYXkuZnJvbSh0aGlzLnNoYXJlZENvbnRleHQudGltZXN0YW1wcy5lbnRyaWVzKCkpXG4gICAgICB9XG4gICAgfTtcbiAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkoZGF0YSwgbnVsbCwgMik7XG4gIH1cblxuICAvKipcbiAgICogRGVzZXJpYWxpemUgZW5zZW1ibGUgZnJvbSBzdHJpbmdcbiAgICovXG4gIHB1YmxpYyBvdmVycmlkZSBkZXNlcmlhbGl6ZShkYXRhOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBwYXJzZWQgPSBKU09OLnBhcnNlKGRhdGEpO1xuICAgIFxuICAgIC8vIElmIGRhdGEgaGFzIGEgJ2Jhc2UnIHByb3BlcnR5LCBpdCB3YXMgc2VyaWFsaXplZCBieSBvdXIgc2VyaWFsaXplIG1ldGhvZFxuICAgIGlmIChwYXJzZWQuYmFzZSkge1xuICAgICAgLy8gRGVzZXJpYWxpemUgYmFzZSBwcm9wZXJ0aWVzXG4gICAgICBzdXBlci5kZXNlcmlhbGl6ZShwYXJzZWQuYmFzZSk7XG4gICAgICBcbiAgICAgIC8vIFJlc3RvcmUgZWxlbWVudHNcbiAgICAgIGlmIChwYXJzZWQuZWxlbWVudHMpIHtcbiAgICAgICAgdGhpcy5lbGVtZW50cy5jbGVhcigpO1xuICAgICAgICBmb3IgKGNvbnN0IFtpZCwgZWxlbWVudF0gb2YgcGFyc2VkLmVsZW1lbnRzKSB7XG4gICAgICAgICAgdGhpcy5lbGVtZW50cy5zZXQoaWQsIGVsZW1lbnQpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIFJlc3RvcmUgc2hhcmVkIGNvbnRleHRcbiAgICAgIGlmIChwYXJzZWQuc2hhcmVkQ29udGV4dCkge1xuICAgICAgICB0aGlzLnNoYXJlZENvbnRleHQudmFsdWVzLmNsZWFyKCk7XG4gICAgICAgIHRoaXMuc2hhcmVkQ29udGV4dC5vd25lcnMuY2xlYXIoKTtcbiAgICAgICAgdGhpcy5zaGFyZWRDb250ZXh0LnRpbWVzdGFtcHMuY2xlYXIoKTtcbiAgICAgICAgXG4gICAgICAgIGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIHBhcnNlZC5zaGFyZWRDb250ZXh0LnZhbHVlcyB8fCBbXSkge1xuICAgICAgICAgIHRoaXMuc2hhcmVkQ29udGV4dC52YWx1ZXMuc2V0KGtleSwgdmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIGZvciAoY29uc3QgW2tleSwgb3duZXJdIG9mIHBhcnNlZC5zaGFyZWRDb250ZXh0Lm93bmVycyB8fCBbXSkge1xuICAgICAgICAgIHRoaXMuc2hhcmVkQ29udGV4dC5vd25lcnMuc2V0KGtleSwgb3duZXIpO1xuICAgICAgICB9XG4gICAgICAgIGZvciAoY29uc3QgW2tleSwgdGltZXN0YW1wXSBvZiBwYXJzZWQuc2hhcmVkQ29udGV4dC50aW1lc3RhbXBzIHx8IFtdKSB7XG4gICAgICAgICAgdGhpcy5zaGFyZWRDb250ZXh0LnRpbWVzdGFtcHMuc2V0KGtleSwgbmV3IERhdGUodGltZXN0YW1wKSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLy8gT2xkIGZvcm1hdCBvciBkaXJlY3QgcHJvcGVydGllc1xuICAgICAgc3VwZXIuZGVzZXJpYWxpemUoZGF0YSk7XG4gICAgfVxuICB9XG59Il19
|