cdk-cost-analyzer 0.1.41 → 0.1.43

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/.cdk-cost-analyzer-cache/metadata.json +8 -8
  2. package/dist/action/api/index.d.ts +1 -0
  3. package/dist/action/api/single-template-types.d.ts +4 -0
  4. package/dist/action/api/types.d.ts +3 -0
  5. package/dist/action/config/types.d.ts +2 -0
  6. package/dist/action/optimization/OptimizationEngine.d.ts +11 -0
  7. package/dist/action/optimization/analyzers/GravitonMigrationAnalyzer.d.ts +17 -0
  8. package/dist/action/optimization/analyzers/NATGatewayOptimizationAnalyzer.d.ts +13 -0
  9. package/dist/action/optimization/analyzers/ReservedInstanceAnalyzer.d.ts +13 -0
  10. package/dist/action/optimization/analyzers/RightSizingAnalyzer.d.ts +13 -0
  11. package/dist/action/optimization/analyzers/SavingsPlansAnalyzer.d.ts +11 -0
  12. package/dist/action/optimization/analyzers/SpotInstanceAnalyzer.d.ts +12 -0
  13. package/dist/action/optimization/analyzers/StorageOptimizationAnalyzer.d.ts +14 -0
  14. package/dist/action/optimization/defaults.d.ts +2 -0
  15. package/dist/action/optimization/index.d.ts +10 -0
  16. package/dist/action/optimization/types.d.ts +35 -0
  17. package/dist/action/reporter/RecommendationReporter.d.ts +3 -0
  18. package/dist/analysis/SingleTemplateAnalyzer.js +12 -1
  19. package/dist/api/index.d.ts +1 -0
  20. package/dist/api/index.js +2 -1
  21. package/dist/api/single-template-types.d.ts +4 -0
  22. package/dist/api/single-template-types.js +1 -1
  23. package/dist/api/types.d.ts +3 -0
  24. package/dist/api/types.js +1 -1
  25. package/dist/cli/index.js +13 -2
  26. package/dist/config/types.d.ts +2 -0
  27. package/dist/config/types.js +1 -1
  28. package/dist/optimization/OptimizationEngine.d.ts +11 -0
  29. package/dist/optimization/OptimizationEngine.js +51 -0
  30. package/dist/optimization/analyzers/GravitonMigrationAnalyzer.d.ts +17 -0
  31. package/dist/optimization/analyzers/GravitonMigrationAnalyzer.js +209 -0
  32. package/dist/optimization/analyzers/NATGatewayOptimizationAnalyzer.d.ts +13 -0
  33. package/dist/optimization/analyzers/NATGatewayOptimizationAnalyzer.js +142 -0
  34. package/dist/optimization/analyzers/ReservedInstanceAnalyzer.d.ts +13 -0
  35. package/dist/optimization/analyzers/ReservedInstanceAnalyzer.js +102 -0
  36. package/dist/optimization/analyzers/RightSizingAnalyzer.d.ts +13 -0
  37. package/dist/optimization/analyzers/RightSizingAnalyzer.js +109 -0
  38. package/dist/optimization/analyzers/SavingsPlansAnalyzer.d.ts +11 -0
  39. package/dist/optimization/analyzers/SavingsPlansAnalyzer.js +102 -0
  40. package/dist/optimization/analyzers/SpotInstanceAnalyzer.d.ts +12 -0
  41. package/dist/optimization/analyzers/SpotInstanceAnalyzer.js +113 -0
  42. package/dist/optimization/analyzers/StorageOptimizationAnalyzer.d.ts +14 -0
  43. package/dist/optimization/analyzers/StorageOptimizationAnalyzer.js +142 -0
  44. package/dist/optimization/defaults.d.ts +2 -0
  45. package/dist/optimization/defaults.js +22 -0
  46. package/dist/optimization/index.d.ts +10 -0
  47. package/dist/optimization/index.js +22 -0
  48. package/dist/optimization/types.d.ts +35 -0
  49. package/dist/optimization/types.js +3 -0
  50. package/dist/releasetag.txt +1 -1
  51. package/dist/reporter/RecommendationReporter.d.ts +3 -0
  52. package/dist/reporter/RecommendationReporter.js +133 -0
  53. package/dist/reporter/SingleTemplateReporter.js +11 -1
  54. package/docs/CALCULATORS.md +374 -8
  55. package/docs/README.md +3 -2
  56. package/docs/RECOMMENDATIONS.md +466 -0
  57. package/docs/SINGLE-TEMPLATE-ANALYSIS.md +59 -16
  58. package/docs/index.md +38 -8
  59. package/examples/recommendations-demo.json +74 -0
  60. package/package.json +1 -1
@@ -2,35 +2,35 @@
2
2
  "entries": {
3
3
  "AmazonS3:US East (N. Virginia):storageClass:General Purpose|volumeType:Standard": {
4
4
  "price": 0.023,
5
- "timestamp": 1773136672167
5
+ "timestamp": 1773167205303
6
6
  },
7
7
  "AmazonDynamoDB:US East (N. Virginia):group:DDB-ReadUnits|productFamily:Amazon DynamoDB PayPerRequest Throughput": {
8
8
  "price": 0.023,
9
- "timestamp": 1773136672179
9
+ "timestamp": 1773167205310
10
10
  },
11
11
  "AmazonDynamoDB:US East (N. Virginia):group:DDB-WriteUnits|productFamily:Amazon DynamoDB PayPerRequest Throughput": {
12
12
  "price": 0.023,
13
- "timestamp": 1773136672179
13
+ "timestamp": 1773167205310
14
14
  },
15
15
  "AmazonEC2:US East (N. Virginia):capacitystatus:Used|instanceType:t3.micro|operatingSystem:Linux|preInstalledSw:NA|tenancy:Shared": {
16
16
  "price": 0.023,
17
- "timestamp": 1773136672189
17
+ "timestamp": 1773167205328
18
18
  },
19
19
  "AWSLambda:US East (N. Virginia):group:AWS-Lambda-Requests": {
20
20
  "price": 0.023,
21
- "timestamp": 1773136672195
21
+ "timestamp": 1773167205334
22
22
  },
23
23
  "AWSLambda:US East (N. Virginia):group:AWS-Lambda-Duration": {
24
24
  "price": 0.023,
25
- "timestamp": 1773136672195
25
+ "timestamp": 1773167205335
26
26
  },
27
27
  "AmazonS3:EU (Frankfurt):storageClass:General Purpose|volumeType:Standard": {
28
28
  "price": 0.023,
29
- "timestamp": 1773136680510
29
+ "timestamp": 1773167214815
30
30
  },
31
31
  "AmazonS3:invalid-region-123:storageClass:General Purpose|volumeType:Standard": {
32
32
  "price": 0.023,
33
- "timestamp": 1773136680557
33
+ "timestamp": 1773167214873
34
34
  }
35
35
  }
36
36
  }
@@ -10,6 +10,7 @@ export * from '../config';
10
10
  export * from '../synthesis';
11
11
  export * from '../threshold';
12
12
  export * from '../pipeline';
13
+ export * from '../optimization';
13
14
  export declare function analyzeCosts(options: AnalyzeOptions): Promise<CostAnalysisResult>;
14
15
  /**
15
16
  * Analyze a single CloudFormation template for estimated monthly costs
@@ -1,5 +1,6 @@
1
1
  import { ResourceCost } from '../pricing/types';
2
2
  import { UsageAssumptionsConfig, CacheConfig } from '../config/types';
3
+ import { OptimizationResult } from '../optimization/types';
3
4
  /**
4
5
  * Configuration options for single template analysis
5
6
  */
@@ -7,6 +8,8 @@ export interface AnalysisConfig {
7
8
  usageAssumptions?: UsageAssumptionsConfig;
8
9
  excludedResourceTypes?: string[];
9
10
  cacheConfig?: CacheConfig;
11
+ recommendations?: boolean;
12
+ minimumSavingsThreshold?: number;
10
13
  }
11
14
  /**
12
15
  * Metadata about the analysis
@@ -62,6 +65,7 @@ export interface SingleTemplateCostResult {
62
65
  costBreakdown: CostBreakdown;
63
66
  summary: string;
64
67
  metadata: AnalysisMetadata;
68
+ recommendations?: OptimizationResult;
65
69
  }
66
70
  /**
67
71
  * Options for analyzing a single template
@@ -1,9 +1,11 @@
1
1
  import { ResourceCost, ModifiedResourceCost } from '../pricing/types';
2
+ import { OptimizationResult } from '../optimization/types';
2
3
  export interface AnalyzeOptions {
3
4
  baseTemplate: string;
4
5
  targetTemplate: string;
5
6
  region?: string;
6
7
  format?: 'text' | 'json' | 'markdown';
8
+ recommendations?: boolean;
7
9
  }
8
10
  export interface CostAnalysisResult {
9
11
  totalDelta: number;
@@ -12,4 +14,5 @@ export interface CostAnalysisResult {
12
14
  removedResources: ResourceCost[];
13
15
  modifiedResources: ModifiedResourceCost[];
14
16
  summary: string;
17
+ recommendations?: OptimizationResult;
15
18
  }
@@ -1,9 +1,11 @@
1
+ import { OptimizationConfig } from '../optimization/types';
1
2
  export interface CostAnalyzerConfig {
2
3
  thresholds?: ThresholdConfig;
3
4
  usageAssumptions?: UsageAssumptionsConfig;
4
5
  synthesis?: SynthesisConfig;
5
6
  exclusions?: ExclusionsConfig;
6
7
  cache?: CacheConfig;
8
+ optimization?: OptimizationConfig;
7
9
  }
8
10
  export interface ThresholdConfig {
9
11
  default?: ThresholdLevels;
@@ -0,0 +1,11 @@
1
+ import { ResourceWithId } from '../diff/types';
2
+ import { ResourceCost } from '../pricing/types';
3
+ import { OptimizationAnalyzer, OptimizationConfig, OptimizationResult } from './types';
4
+ export declare class OptimizationEngine {
5
+ private readonly config;
6
+ private readonly analyzers;
7
+ constructor(analyzers: OptimizationAnalyzer[], config?: OptimizationConfig);
8
+ analyze(resources: ResourceWithId[], resourceCosts: ResourceCost[], region: string): Promise<OptimizationResult>;
9
+ private filterAnalyzers;
10
+ private applyThreshold;
11
+ }
@@ -0,0 +1,17 @@
1
+ import { ResourceWithId } from '../../diff/types';
2
+ import { ResourceCost } from '../../pricing/types';
3
+ import { OptimizationAnalyzer, OptimizationCategory, Recommendation } from '../types';
4
+ export declare class GravitonMigrationAnalyzer implements OptimizationAnalyzer {
5
+ readonly category: OptimizationCategory;
6
+ readonly name = "Graviton Migration";
7
+ isApplicable(resources: ResourceWithId[]): boolean;
8
+ analyze(resources: ResourceWithId[], resourceCosts: ResourceCost[], _region: string): Promise<Recommendation[]>;
9
+ private analyzeResource;
10
+ private analyzeEC2;
11
+ private analyzeRDS;
12
+ private analyzeElastiCache;
13
+ private extractFamily;
14
+ private extractRDSFamily;
15
+ private extractElastiCacheFamily;
16
+ private findCost;
17
+ }
@@ -0,0 +1,13 @@
1
+ import { ResourceWithId } from '../../diff/types';
2
+ import { ResourceCost } from '../../pricing/types';
3
+ import { OptimizationAnalyzer, OptimizationCategory, Recommendation } from '../types';
4
+ export declare class NATGatewayOptimizationAnalyzer implements OptimizationAnalyzer {
5
+ readonly category: OptimizationCategory;
6
+ readonly name = "NAT Gateway Optimization";
7
+ isApplicable(resources: ResourceWithId[]): boolean;
8
+ analyze(resources: ResourceWithId[], resourceCosts: ResourceCost[], _region: string): Promise<Recommendation[]>;
9
+ private suggestNATInstanceForDev;
10
+ private suggestVPCEndpoints;
11
+ private suggestConsolidation;
12
+ private findCost;
13
+ }
@@ -0,0 +1,13 @@
1
+ import { ResourceWithId } from '../../diff/types';
2
+ import { ResourceCost } from '../../pricing/types';
3
+ import { OptimizationAnalyzer, OptimizationCategory, Recommendation } from '../types';
4
+ export declare class ReservedInstanceAnalyzer implements OptimizationAnalyzer {
5
+ readonly category: OptimizationCategory;
6
+ readonly name = "Reserved Instance";
7
+ isApplicable(resources: ResourceWithId[]): boolean;
8
+ analyze(resources: ResourceWithId[], resourceCosts: ResourceCost[], _region: string): Promise<Recommendation[]>;
9
+ private createRecommendation;
10
+ private getServiceLabel;
11
+ private getInstanceInfo;
12
+ private findCost;
13
+ }
@@ -0,0 +1,13 @@
1
+ import { ResourceWithId } from '../../diff/types';
2
+ import { ResourceCost } from '../../pricing/types';
3
+ import { OptimizationAnalyzer, OptimizationCategory, Recommendation } from '../types';
4
+ export declare class RightSizingAnalyzer implements OptimizationAnalyzer {
5
+ readonly category: OptimizationCategory;
6
+ readonly name = "Right-Sizing";
7
+ isApplicable(resources: ResourceWithId[]): boolean;
8
+ analyze(resources: ResourceWithId[], resourceCosts: ResourceCost[], _region: string): Promise<Recommendation[]>;
9
+ private analyzeResource;
10
+ private getInstanceType;
11
+ private extractSize;
12
+ private findCost;
13
+ }
@@ -0,0 +1,11 @@
1
+ import { ResourceWithId } from '../../diff/types';
2
+ import { ResourceCost } from '../../pricing/types';
3
+ import { OptimizationAnalyzer, OptimizationCategory, Recommendation } from '../types';
4
+ export declare class SavingsPlansAnalyzer implements OptimizationAnalyzer {
5
+ readonly category: OptimizationCategory;
6
+ readonly name = "Savings Plans";
7
+ isApplicable(resources: ResourceWithId[]): boolean;
8
+ analyze(resources: ResourceWithId[], resourceCosts: ResourceCost[], _region: string): Promise<Recommendation[]>;
9
+ private hasMultipleComputeTypes;
10
+ private findCost;
11
+ }
@@ -0,0 +1,12 @@
1
+ import { ResourceWithId } from '../../diff/types';
2
+ import { ResourceCost } from '../../pricing/types';
3
+ import { OptimizationAnalyzer, OptimizationCategory, Recommendation } from '../types';
4
+ export declare class SpotInstanceAnalyzer implements OptimizationAnalyzer {
5
+ readonly category: OptimizationCategory;
6
+ readonly name = "Spot Instances";
7
+ isApplicable(resources: ResourceWithId[]): boolean;
8
+ analyze(resources: ResourceWithId[], resourceCosts: ResourceCost[], _region: string): Promise<Recommendation[]>;
9
+ private analyzeASG;
10
+ private analyzeECSService;
11
+ private findCost;
12
+ }
@@ -0,0 +1,14 @@
1
+ import { ResourceWithId } from '../../diff/types';
2
+ import { ResourceCost } from '../../pricing/types';
3
+ import { OptimizationAnalyzer, OptimizationCategory, Recommendation } from '../types';
4
+ export declare class StorageOptimizationAnalyzer implements OptimizationAnalyzer {
5
+ readonly category: OptimizationCategory;
6
+ readonly name = "Storage Optimization";
7
+ isApplicable(resources: ResourceWithId[]): boolean;
8
+ analyze(resources: ResourceWithId[], resourceCosts: ResourceCost[], _region: string): Promise<Recommendation[]>;
9
+ private analyzeS3Bucket;
10
+ private analyzeEBSVolume;
11
+ private analyzeLaunchTemplate;
12
+ private hasIntelligentTieringConfig;
13
+ private findCost;
14
+ }
@@ -0,0 +1,2 @@
1
+ import { OptimizationAnalyzer } from './types';
2
+ export declare function createDefaultAnalyzers(): OptimizationAnalyzer[];
@@ -0,0 +1,10 @@
1
+ export { OptimizationEngine } from './OptimizationEngine';
2
+ export { createDefaultAnalyzers } from './defaults';
3
+ export { OptimizationAnalyzer, OptimizationCategory, OptimizationConfig, OptimizationResult, Recommendation, RecommendationPriority, } from './types';
4
+ export { GravitonMigrationAnalyzer } from './analyzers/GravitonMigrationAnalyzer';
5
+ export { NATGatewayOptimizationAnalyzer } from './analyzers/NATGatewayOptimizationAnalyzer';
6
+ export { StorageOptimizationAnalyzer } from './analyzers/StorageOptimizationAnalyzer';
7
+ export { ReservedInstanceAnalyzer } from './analyzers/ReservedInstanceAnalyzer';
8
+ export { SavingsPlansAnalyzer } from './analyzers/SavingsPlansAnalyzer';
9
+ export { RightSizingAnalyzer } from './analyzers/RightSizingAnalyzer';
10
+ export { SpotInstanceAnalyzer } from './analyzers/SpotInstanceAnalyzer';
@@ -0,0 +1,35 @@
1
+ import { ResourceWithId } from '../diff/types';
2
+ import { ResourceCost } from '../pricing/types';
3
+ export type RecommendationPriority = 'high' | 'medium' | 'low';
4
+ export type OptimizationCategory = 'reserved-instance' | 'savings-plan' | 'right-sizing' | 'graviton-migration' | 'storage-optimization' | 'spot-instance' | 'nat-gateway-optimization';
5
+ export interface Recommendation {
6
+ id: string;
7
+ title: string;
8
+ description: string;
9
+ category: OptimizationCategory;
10
+ priority: RecommendationPriority;
11
+ estimatedMonthlySavings: number;
12
+ estimatedSavingsPercent: number;
13
+ affectedResources: string[];
14
+ actionItems: string[];
15
+ caveats: string[];
16
+ }
17
+ export interface OptimizationResult {
18
+ recommendations: Recommendation[];
19
+ totalEstimatedMonthlySavings: number;
20
+ currency: string;
21
+ analyzedResourceCount: number;
22
+ analyzedAt: string;
23
+ }
24
+ export interface OptimizationAnalyzer {
25
+ readonly category: OptimizationCategory;
26
+ readonly name: string;
27
+ isApplicable(resources: ResourceWithId[]): boolean;
28
+ analyze(resources: ResourceWithId[], resourceCosts: ResourceCost[], region: string): Promise<Recommendation[]>;
29
+ }
30
+ export interface OptimizationConfig {
31
+ enabled?: boolean;
32
+ minimumSavingsThreshold?: number;
33
+ enabledCategories?: OptimizationCategory[];
34
+ disabledCategories?: OptimizationCategory[];
35
+ }
@@ -0,0 +1,3 @@
1
+ import { OptimizationResult } from '../optimization/types';
2
+ export declare function formatRecommendationsText(result: OptimizationResult, minSavings?: number): string;
3
+ export declare function formatRecommendationsMarkdown(result: OptimizationResult, minSavings?: number): string;
@@ -37,6 +37,8 @@ exports.SingleTemplateAnalyzer = void 0;
37
37
  const crypto = __importStar(require("crypto"));
38
38
  const TemplateParser_1 = require("../parser/TemplateParser");
39
39
  const PricingService_1 = require("../pricing/PricingService");
40
+ const OptimizationEngine_1 = require("../optimization/OptimizationEngine");
41
+ const defaults_1 = require("../optimization/defaults");
40
42
  /**
41
43
  * Service for analyzing costs in a single CloudFormation template
42
44
  */
@@ -81,6 +83,14 @@ class SingleTemplateAnalyzer {
81
83
  const metadata = this.generateMetadata(template, region, resourceCosts, analyzedAt);
82
84
  // Generate summary (placeholder - will be replaced by reporter)
83
85
  const summary = `Total monthly cost: $${totalMonthlyCost.toFixed(2)} USD`;
86
+ // Run optimization analysis if requested
87
+ let recommendations;
88
+ if (config?.recommendations) {
89
+ const engine = new OptimizationEngine_1.OptimizationEngine((0, defaults_1.createDefaultAnalyzers)(), {
90
+ minimumSavingsThreshold: config.minimumSavingsThreshold,
91
+ });
92
+ recommendations = await engine.analyze(resources, resourceCosts, region);
93
+ }
84
94
  return {
85
95
  totalMonthlyCost,
86
96
  currency: 'USD',
@@ -88,6 +98,7 @@ class SingleTemplateAnalyzer {
88
98
  costBreakdown,
89
99
  summary,
90
100
  metadata,
101
+ recommendations,
91
102
  };
92
103
  }
93
104
  finally {
@@ -165,4 +176,4 @@ class SingleTemplateAnalyzer {
165
176
  }
166
177
  }
167
178
  exports.SingleTemplateAnalyzer = SingleTemplateAnalyzer;
168
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU2luZ2xlVGVtcGxhdGVBbmFseXplci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hbmFseXNpcy9TaW5nbGVUZW1wbGF0ZUFuYWx5emVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLCtDQUFpQztBQUNqQyw2REFBMEQ7QUFDMUQsOERBQTJEO0FBWTNEOztHQUVHO0FBQ0gsTUFBYSxzQkFBc0I7SUFDakM7Ozs7Ozs7T0FPRztJQUNILEtBQUssQ0FBQyxZQUFZLENBQ2hCLFFBQWdCLEVBQ2hCLE1BQWMsRUFDZCxNQUF1QjtRQUV2QixNQUFNLE1BQU0sR0FBRyxJQUFJLCtCQUFjLEVBQUUsQ0FBQztRQUNwQyxNQUFNLGNBQWMsR0FBRyxJQUFJLCtCQUFjLENBQ3ZDLE1BQU0sRUFDTixNQUFNLEVBQUUsZ0JBQWdCLEVBQ3hCLE1BQU0sRUFBRSxxQkFBcUIsRUFDN0IsTUFBTSxFQUFFLFdBQVcsQ0FDcEIsQ0FBQztRQUVGLElBQUksQ0FBQztZQUNILHFCQUFxQjtZQUNyQixNQUFNLGNBQWMsR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQzlDLE1BQU0sU0FBUyxHQUFxQixNQUFNLENBQUMsT0FBTyxDQUFDLGNBQWMsQ0FBQyxTQUFTLElBQUksRUFBRSxDQUFDLENBQUMsR0FBRyxDQUNwRixDQUFDLENBQUMsU0FBUyxFQUFFLFFBQVEsQ0FBZ0IsRUFBRSxFQUFFLENBQUMsQ0FBQztnQkFDekMsU0FBUztnQkFDVCxJQUFJLEVBQUUsUUFBUSxDQUFDLElBQUk7Z0JBQ25CLFVBQVUsRUFBRSxRQUFRLENBQUMsVUFBVSxJQUFJLEVBQUU7YUFDdEMsQ0FBQyxDQUNILENBQUM7WUFFRixvQ0FBb0M7WUFDcEMsTUFBTSxVQUFVLEdBQUcsSUFBSSxJQUFJLEVBQUUsQ0FBQztZQUM5QixNQUFNLGFBQWEsR0FBMkIsTUFBTSxPQUFPLENBQUMs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VyxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLENBQUM7UUFFL0MsT0FBTztZQUNMLGNBQWM7WUFDZCxpQkFBaUI7WUFDakIsV0FBVztTQUNaLENBQUM7SUFDSixDQUFDO0lBRUQ7O09BRUc7SUFDSyxnQkFBZ0IsQ0FDdEIsUUFBZ0IsRUFDaEIsTUFBYyxFQUNkLGFBQXFDLEVBQ3JDLFVBQWdCO1FBRWhCLDRCQUE0QjtRQUM1QixNQUFNLFlBQVksR0FBRyxNQUFNLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUVqRywyQ0FBMkM7UUFDM0MsTUFBTSxzQkFBc0IsR0FBRyxhQUFhLENBQUMsTUFBTSxDQUNqRCxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLFdBQVcsQ0FBQyxVQUFVLEtBQUssU0FBUyxJQUFJLEVBQUUsQ0FBQyxXQUFXLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FDN0UsQ0FBQyxNQUFNLENBQUM7UUFDVCxNQUFNLHdCQUF3QixHQUFHLGFBQWEsQ0FBQyxNQUFNLEdBQUcsc0JBQXNCLENBQUM7UUFFL0UsT0FBTztZQUNMLFlBQVk7WUFDWixNQUFNO1lBQ04sVUFBVTtZQUNWLGFBQWEsRUFBRSxhQUFhLENBQUMsTUFBTTtZQUNuQyxzQkFBc0I7WUFDdEIsd0JBQXdCO1NBQ3pCLENBQUM7SUFDSixDQUFDO0NBQ0Y7QUFuS0Qsd0RBbUtDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgY3J5cHRvIGZyb20gJ2NyeXB0byc7XG5pbXBvcnQgeyBUZW1wbGF0ZVBhcnNlciB9IGZyb20gJy4uL3BhcnNlci9UZW1wbGF0ZVBhcnNlcic7XG5pbXBvcnQgeyBQcmljaW5nU2VydmljZSB9IGZyb20gJy4uL3ByaWNpbmcvUHJpY2luZ1NlcnZpY2UnO1xuaW1wb3J0IHsgUmVzb3VyY2VXaXRoSWQgfSBmcm9tICcuLi9kaWZmL3R5cGVzJztcbmltcG9ydCB7XG4gIEFuYWx5c2lzQ29uZmlnLFxuICBTaW5nbGVUZW1wbGF0ZUNvc3RSZXN1bHQsXG4gIENvc3RCcmVha2Rvd24sXG4gIFJlc291cmNlVHlwZUNvc3QsXG4gIENvbmZpZGVuY2VMZXZlbENvc3QsXG4gIEVuaGFuY2VkUmVzb3VyY2VDb3N0LFxuICBBbmFseXNpc01ldGFkYXRhLFxufSBmcm9tICcuLi9hcGkvc2luZ2xlLXRlbXBsYXRlLXR5cGVzJztcblxuLyoqXG4gKiBTZXJ2aWNlIGZvciBhbmFseXppbmcgY29zdHMgaW4gYSBzaW5nbGUgQ2xvdWRGb3JtYXRpb24gdGVtcGxhdGVcbiAqL1xuZXhwb3J0IGNsYXNzIFNpbmdsZVRlbXBsYXRlQW5hbHl6ZXIge1xuICAvKipcbiAgICogQW5hbHl6ZSBjb3N0cyBmb3IgYWxsIHJlc291cmNlcyBpbiBhIHNpbmdsZSB0ZW1wbGF0ZVxuICAgKiBcbiAgICogQHBhcmFtIHRlbXBsYXRlIC0gQ2xvdWRGb3JtYXRpb24gdGVtcGxhdGUgY29udGVudCAoSlNPTiBvciBZQU1MKVxuICAgKiBAcGFyYW0gcmVnaW9uIC0gQVdTIHJlZ2lvbiBmb3IgcHJpY2luZyBjYWxjdWxhdGlvbnNcbiAgICogQHBhcmFtIGNvbmZpZyAtIE9wdGlvbmFsIGNvbmZpZ3VyYXRpb24gZm9yIGFuYWx5c2lzXG4gICAqIEByZXR1cm5zIFByb21pc2UgcmVzb2x2aW5nIHRvIGRldGFpbGVkIGNvc3QgYW5hbHlzaXMgcmVzdWx0XG4gICAqL1xuICBhc3luYyBhbmFseXplQ29zdHMoXG4gICAgdGVtcGxhdGU6IHN0cmluZyxcbiAgICByZWdpb246IHN0cmluZyxcbiAgICBjb25maWc/OiBBbmFseXNpc0NvbmZpZyxcbiAgKTogUHJvbWlzZTxTaW5nbGVUZW1wbGF0ZUNvc3RSZXN1bHQ+IHtcbiAgICBjb25zdCBwYXJzZXIgPSBuZXcgVGVtcGxhdGVQYXJzZXIoKTtcbiAgICBjb25zdCBwcmljaW5nU2VydmljZSA9IG5ldyBQcmljaW5nU2VydmljZShcbiAgICAgIHJlZ2lvbixcbiAgICAgIGNvbmZpZz8udXNhZ2VBc3N1bXB0aW9ucyxcbiAgICAgIGNvbmZpZz8uZXhjbHVkZWRSZXNvdXJjZVR5cGVzLFxuICAgICAgY29uZmlnPy5jYWNoZUNvbmZpZyxcbiAgICApO1xuXG4gICAgdHJ5IHtcbiAgICAgIC8vIFBhcnNlIHRoZSB0ZW1wbGF0ZVxuICAgICAgY29uc3QgcGFyc2VkVGVtcGxhdGUgPSBwYXJzZXIucGFyc2UodGVtcGxhdGUpO1xuICAgICAgY29uc3QgcmVzb3VyY2VzOiBSZXNvdXJjZVdpdGhJZFtdID0gT2JqZWN0LmVudHJpZXMocGFyc2VkVGVtcGxhdGUuUmVzb3VyY2VzIHx8IHt9KS5tYXAoXG4gICAgICAgIChbbG9naWNhbElkLCByZXNvdXJjZV06IFtzdHJpbmcsIGFueV0pID0+ICh7XG4gICAgICAgICAgbG9naWNhbElkLFxuICAgICAgICAgIHR5cGU6IHJlc291cmNlLlR5cGUsXG4gICAgICAgICAgcHJvcGVydGllczogcmVzb3VyY2UuUHJvcGVydGllcyB8fCB7fSxcbiAgICAgICAgfSksXG4gICAgICApO1xuXG4gICAgICAvLyBDYWxjdWxhdGUgY29zdHMgZm9yIGFsbCByZXNvdXJjZXNcbiAgICAgIGNvbnN0IGFuYWx5emVkQXQgPSBuZXcgRGF0ZSgpO1xuICAgICAgY29uc3QgcmVzb3VyY2VDb3N0czogRW5oYW5jZWRSZXNvdXJjZUNvc3RbXSA9IGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgICByZXNvdXJjZXMubWFwKGFzeW5jIChyZXNvdXJjZSkgPT4ge1xuICAgICAgICAgIGNvbnN0IG1vbnRobHlDb3N0ID0gYXdhaXQgcHJpY2luZ1NlcnZpY2UuZ2V0UmVzb3VyY2VDb3N0KHJlc291cmNlLCByZWdpb24sIHJlc291cmNlcyk7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGxvZ2ljYWxJZDogcmVzb3VyY2UubG9naWNhbElkLFxuICAgICAgICAgICAgdHlwZTogcmVzb3VyY2UudHlwZSxcbiAgICAgICAgICAgIG1vbnRobHlDb3N0LFxuICAgICAgICAgICAgcHJvcGVydGllczogcmVzb3VyY2UucHJvcGVydGllcyxcbiAgICAgICAgICAgIHJlZ2lvbixcbiAgICAgICAgICAgIGNhbGN1bGF0ZWRBdDogYW5hbHl6ZWRBdCxcbiAgICAgICAgICB9O1xuICAgICAgICB9KSxcbiAgICAgICk7XG5cbiAgICAgIC8vIENhbGN1bGF0ZSB0b3RhbCBjb3N0XG4gICAgICBjb25zdCB0b3RhbE1vbnRobHlDb3N0ID0gcmVzb3VyY2VDb3N0cy5yZWR1Y2UoXG4gICAgICAgIChzdW0sIHJjKSA9PiBzdW0gKyByYy5tb250aGx5Q29zdC5hbW91bnQsXG4gICAgICAgIDAsXG4gICAgICApO1xuXG4gICAgICAvLyBHZW5lcmF0ZSBjb3N0IGJyZWFrZG93blxuICAgICAgY29uc3QgY29zdEJyZWFrZG93biA9IHRoaXMuZ2VuZXJhdGVDb3N0QnJlYWtkb3duKHJlc291cmNlQ29zdHMpO1xuXG4gICAgICAvLyBHZW5lcmF0ZSBtZXRhZGF0YVxuICAgICAgY29uc3QgbWV0YWRhdGEgPSB0aGlzLmdlbmVyYXRlTWV0YWRhdGEodGVtcGxhdGUsIHJlZ2lvbiwgcmVzb3VyY2VDb3N0cywgYW5hbHl6ZWRBdCk7XG5cbiAgICAgIC8vIEdlbmVyYXRlIHN1bW1hcnkgKHBsYWNlaG9sZGVyIC0gd2lsbCBiZSByZXBsYWNlZCBieSByZXBvcnRlcilcbiAgICAgIGNvbnN0IHN1bW1hcnkgPSBgVG90YWwgbW9udGhseSBjb3N0OiAkJHt0b3RhbE1vbnRobHlDb3N0LnRvRml4ZWQoMil9IFVTRGA7XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIHRvdGFsTW9udGhseUNvc3QsXG4gICAgICAgIGN1cnJlbmN5OiAnVVNEJyxcbiAgICAgICAgcmVzb3VyY2VDb3N0cyxcbiAgICAgICAgY29zdEJyZWFrZG93bixcbiAgICAgICAgc3VtbWFyeSxcbiAgICAgICAgbWV0YWRhdGEsXG4gICAgICB9O1xuICAgIH0gZmluYWxseSB7XG4gICAgICAvLyBDbGVhbiB1cCBwcmljaW5nIHNlcnZpY2UgcmVzb3VyY2VzXG4gICAgICBwcmljaW5nU2VydmljZS5kZXN0cm95KCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEdlbmVyYXRlIGNvc3QgYnJlYWtkb3duIGdyb3VwZWQgYnkgcmVzb3VyY2UgdHlwZSBhbmQgY29uZmlkZW5jZSBsZXZlbFxuICAgKi9cbiAgcHJpdmF0ZSBnZW5lcmF0ZUNvc3RCcmVha2Rvd24ocmVzb3VyY2VDb3N0czogRW5oYW5jZWRSZXNvdXJjZUNvc3RbXSk6IENvc3RCcmVha2Rvd24ge1xuICAgIC8vIEdyb3VwIGJ5IHJlc291cmNlIHR5cGVcbiAgICBjb25zdCBieVR5cGVNYXAgPSBuZXcgTWFwPHN0cmluZywgRW5oYW5jZWRSZXNvdXJjZUNvc3RbXT4oKTtcbiAgICBmb3IgKGNvbnN0IHJjIG9mIHJlc291cmNlQ29zdHMpIHtcbiAgICAgIGNvbnN0IGV4aXN0aW5nID0gYnlUeXBlTWFwLmdldChyYy50eXBlKSB8fCBbXTtcbiAgICAgIGV4aXN0aW5nLnB1c2gocmMpO1xuICAgICAgYnlUeXBlTWFwLnNldChyYy50eXBlLCBleGlzdGluZyk7XG4gICAgfVxuXG4gICAgY29uc3QgYnlSZXNvdXJjZVR5cGU6IFJlc291cmNlVHlwZUNvc3RbXSA9IEFycmF5LmZyb20oYnlUeXBlTWFwLmVudHJpZXMoKSlcbiAgICAgIC5tYXAoKFtyZXNvdXJjZVR5cGUsIHJlc291cmNlc10pID0+ICh7XG4gICAgICAgIHJlc291cmNlVHlwZSxcbiAgICAgICAgY291bnQ6IHJlc291cmNlcy5sZW5ndGgsXG4gICAgICAgIHRvdGFsQ29zdDogcmVzb3VyY2VzLnJlZHVjZSgoc3VtLCByKSA9PiBzdW0gKyByLm1vbnRobHlDb3N0LmFtb3VudCwgMCksXG4gICAgICAgIHJlc291cmNlczogcmVzb3VyY2VzLm1hcCgocikgPT4gKHtcbiAgICAgICAgICBsb2dpY2FsSWQ6IHIubG9naWNhbElkLFxuICAgICAgICAgIHR5cGU6IHIudHlwZSxcbiAgICAgICAgICBtb250aGx5Q29zdDogci5tb250aGx5Q29zdCxcbiAgICAgICAgfSkpLFxuICAgICAgfSkpXG4gICAgICAuc29ydCgoYSwgYikgPT4gYi50b3RhbENvc3QgLSBhLnRvdGFsQ29zdCk7IC8vIFNvcnQgYnkgY29zdCBkZXNjZW5kaW5nXG5cbiAgICAvLyBHcm91cCBieSBjb25maWRlbmNlIGxldmVsXG4gICAgY29uc3QgYnlDb25maWRlbmNlTWFwID0gbmV3IE1hcDxzdHJpbmcsIEVuaGFuY2VkUmVzb3VyY2VDb3N0W10+KCk7XG4gICAgZm9yIChjb25zdCByYyBvZiByZXNvdXJjZUNvc3RzKSB7XG4gICAgICBjb25zdCBjb25maWRlbmNlID0gcmMubW9udGhseUNvc3QuY29uZmlkZW5jZTtcbiAgICAgIGNvbnN0IGV4aXN0aW5nID0gYnlDb25maWRlbmNlTWFwLmdldChjb25maWRlbmNlKSB8fCBbXTtcbiAgICAgIGV4aXN0aW5nLnB1c2gocmMpO1xuICAgICAgYnlDb25maWRlbmNlTWFwLnNldChjb25maWRlbmNlLCBleGlzdGluZyk7XG4gICAgfVxuXG4gICAgY29uc3QgYnlDb25maWRlbmNlTGV2ZWw6IENvbmZpZGVuY2VMZXZlbENvc3RbXSA9IEFycmF5LmZyb20oYnlDb25maWRlbmNlTWFwLmVudHJpZXMoKSkubWFwKFxuICAgICAgKFtjb25maWRlbmNlLCByZXNvdXJjZXNdKSA9PiAoe1xuICAgICAgICBjb25maWRlbmNlOiBjb25maWRlbmNlIGFzICdoaWdoJyB8ICdtZWRpdW0nIHwgJ2xvdycgfCAndW5rbm93bicsXG4gICAgICAgIGNvdW50OiByZXNvdXJjZXMubGVuZ3RoLFxuICAgICAgICB0b3RhbENvc3Q6IHJlc291cmNlcy5yZWR1Y2UoKHN1bSwgcikgPT4gc3VtICsgci5tb250aGx5Q29zdC5hbW91bnQsIDApLFxuICAgICAgfSksXG4gICAgKTtcblxuICAgIC8vIENvbGxlY3QgYWxsIHVuaXF1ZSBhc3N1bXB0aW9uc1xuICAgIGNvbnN0IGFzc3VtcHRpb25zU2V0ID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gICAgZm9yIChjb25zdCByYyBvZiByZXNvdXJjZUNvc3RzKSB7XG4gICAgICBmb3IgKGNvbnN0IGFzc3VtcHRpb24gb2YgcmMubW9udGhseUNvc3QuYXNzdW1wdGlvbnMpIHtcbiAgICAgICAgYXNzdW1wdGlvbnNTZXQuYWRkKGFzc3VtcHRpb24pO1xuICAgICAgfVxuICAgIH1cbiAgICBjb25zdCBhc3N1bXB0aW9ucyA9IEFycmF5LmZyb20oYXNzdW1wdGlvbnNTZXQpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGJ5UmVzb3VyY2VUeXBlLFxuICAgICAgYnlDb25maWRlbmNlTGV2ZWwsXG4gICAgICBhc3N1bXB0aW9ucyxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEdlbmVyYXRlIG1ldGFkYXRhIGFib3V0IHRoZSBhbmFseXNpc1xuICAgKi9cbiAgcHJpdmF0ZSBnZW5lcmF0ZU1ldGFkYXRhKFxuICAgIHRlbXBsYXRlOiBzdHJpbmcsXG4gICAgcmVnaW9uOiBzdHJpbmcsXG4gICAgcmVzb3VyY2VDb3N0czogRW5oYW5jZWRSZXNvdXJjZUNvc3RbXSxcbiAgICBhbmFseXplZEF0OiBEYXRlLFxuICApOiBBbmFseXNpc01ldGFkYXRhIHtcbiAgICAvLyBHZW5lcmF0ZSBoYXNoIG9mIHRlbXBsYXRlXG4gICAgY29uc3QgdGVtcGxhdGVIYXNoID0gY3J5cHRvLmNyZWF0ZUhhc2goJ3NoYTI1NicpLnVwZGF0ZSh0ZW1wbGF0ZSkuZGlnZXN0KCdoZXgnKS5zdWJzdHJpbmcoMCwgMTYpO1xuXG4gICAgLy8gQ291bnQgc3VwcG9ydGVkIHZzIHVuc3VwcG9ydGVkIHJlc291cmNlc1xuICAgIGNvbnN0IHN1cHBvcnRlZFJlc291cmNlQ291bnQgPSByZXNvdXJjZUNvc3RzLmZpbHRlcihcbiAgICAgIChyYykgPT4gcmMubW9udGhseUNvc3QuY29uZmlkZW5jZSAhPT0gJ3Vua25vd24nIHx8IHJjLm1vbnRobHlDb3N0LmFtb3VudCA+IDAsXG4gICAgKS5sZW5ndGg7XG4gICAgY29uc3QgdW5zdXBwb3J0ZWRSZXNvdXJjZUNvdW50ID0gcmVzb3VyY2VDb3N0cy5sZW5ndGggLSBzdXBwb3J0ZWRSZXNvdXJjZUNvdW50O1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHRlbXBsYXRlSGFzaCxcbiAgICAgIHJlZ2lvbixcbiAgICAgIGFuYWx5emVkQXQsXG4gICAgICByZXNvdXJjZUNvdW50OiByZXNvdXJjZUNvc3RzLmxlbmd0aCxcbiAgICAgIHN1cHBvcnRlZFJlc291cmNlQ291bnQsXG4gICAgICB1bnN1cHBvcnRlZFJlc291cmNlQ291bnQsXG4gICAgfTtcbiAgfVxufVxuIl19
179
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU2luZ2xlVGVtcGxhdGVBbmFseXplci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hbmFseXNpcy9TaW5nbGVUZW1wbGF0ZUFuYWx5emVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLCtDQUFpQztBQUNqQyw2REFBMEQ7QUFDMUQsOERBQTJEO0FBVzNELDJFQUF3RTtBQUN4RSx1REFBa0U7QUFFbEU7O0dBRUc7QUFDSCxNQUFhLHNCQUFzQjtJQUNqQzs7Ozs7OztPQU9HO0lBQ0gsS0FBSyxDQUFDLFlBQVksQ0FDaEIsUUFBZ0IsRUFDaEIsTUFBYyxFQUNkLE1BQXVCO1FBRXZCLE1BQU0sTUFBTSxHQUFHLElBQUksK0JBQWMsRUFBRSxDQUFDO1FBQ3BDLE1BQU0sY0FBYyxHQUFHLElBQUksK0JBQWMsQ0FDdkMsTUFBTSxFQUNOLE1BQU0sRUFBRSxnQkFBZ0IsRUFDeEIsTUFBTSxFQUFFLHFCQUFxQixFQUM3QixNQUFNLEVBQUUsV0FBVyxDQUNwQixDQUFDO1FBRUYsSUFBSSxDQUFDO1lBQ0gscUJBQXFCO1lBQ3JCLE1BQU0sY0FBYyxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDOUMsTUFBTSxTQUFTLEdBQXFCLE1BQU0sQ0FBQyxPQUFPLENBQUMsY0FBYyxDQUFDLFNBQVMsSUFBSSxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQ3BGLENBQUMsQ0FBQyxTQUFTLEVBQUUsUUFBUSxDQUFnQixFQUFFLEVBQUUsQ0FBQyxDQUFDO2dCQUN6QyxTQUFTO2dCQUNULElBQUksRUFBRSxRQUFRLENBQUMsSUFBSTtnQkFDbkIsVUFBVSxFQUFFLFFBQVEsQ0FBQyxVQUFVLElBQUksRUFBRTthQUN0QyxDQUFDLENBQ0gsQ0FBQztZQUVGLG9DQUFvQztZQUNwQyxNQUFNLFVBQVUsR0FBRyxJQUFJLElBQUksRUFBRSxDQUFDO1lBQzlCLE1BQU0s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WUFDTixVQUFVO1lBQ1YsYUFBYSxFQUFFLGFBQWEsQ0FBQyxNQUFNO1lBQ25DLHNCQUFzQjtZQUN0Qix3QkFBd0I7U0FDekIsQ0FBQztJQUNKLENBQUM7Q0FDRjtBQTdLRCx3REE2S0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBjcnlwdG8gZnJvbSAnY3J5cHRvJztcbmltcG9ydCB7IFRlbXBsYXRlUGFyc2VyIH0gZnJvbSAnLi4vcGFyc2VyL1RlbXBsYXRlUGFyc2VyJztcbmltcG9ydCB7IFByaWNpbmdTZXJ2aWNlIH0gZnJvbSAnLi4vcHJpY2luZy9QcmljaW5nU2VydmljZSc7XG5pbXBvcnQgeyBSZXNvdXJjZVdpdGhJZCB9IGZyb20gJy4uL2RpZmYvdHlwZXMnO1xuaW1wb3J0IHtcbiAgQW5hbHlzaXNDb25maWcsXG4gIFNpbmdsZVRlbXBsYXRlQ29zdFJlc3VsdCxcbiAgQ29zdEJyZWFrZG93bixcbiAgUmVzb3VyY2VUeXBlQ29zdCxcbiAgQ29uZmlkZW5jZUxldmVsQ29zdCxcbiAgRW5oYW5jZWRSZXNvdXJjZUNvc3QsXG4gIEFuYWx5c2lzTWV0YWRhdGEsXG59IGZyb20gJy4uL2FwaS9zaW5nbGUtdGVtcGxhdGUtdHlwZXMnO1xuaW1wb3J0IHsgT3B0aW1pemF0aW9uRW5naW5lIH0gZnJvbSAnLi4vb3B0aW1pemF0aW9uL09wdGltaXphdGlvbkVuZ2luZSc7XG5pbXBvcnQgeyBjcmVhdGVEZWZhdWx0QW5hbHl6ZXJzIH0gZnJvbSAnLi4vb3B0aW1pemF0aW9uL2RlZmF1bHRzJztcblxuLyoqXG4gKiBTZXJ2aWNlIGZvciBhbmFseXppbmcgY29zdHMgaW4gYSBzaW5nbGUgQ2xvdWRGb3JtYXRpb24gdGVtcGxhdGVcbiAqL1xuZXhwb3J0IGNsYXNzIFNpbmdsZVRlbXBsYXRlQW5hbHl6ZXIge1xuICAvKipcbiAgICogQW5hbHl6ZSBjb3N0cyBmb3IgYWxsIHJlc291cmNlcyBpbiBhIHNpbmdsZSB0ZW1wbGF0ZVxuICAgKiBcbiAgICogQHBhcmFtIHRlbXBsYXRlIC0gQ2xvdWRGb3JtYXRpb24gdGVtcGxhdGUgY29udGVudCAoSlNPTiBvciBZQU1MKVxuICAgKiBAcGFyYW0gcmVnaW9uIC0gQVdTIHJlZ2lvbiBmb3IgcHJpY2luZyBjYWxjdWxhdGlvbnNcbiAgICogQHBhcmFtIGNvbmZpZyAtIE9wdGlvbmFsIGNvbmZpZ3VyYXRpb24gZm9yIGFuYWx5c2lzXG4gICAqIEByZXR1cm5zIFByb21pc2UgcmVzb2x2aW5nIHRvIGRldGFpbGVkIGNvc3QgYW5hbHlzaXMgcmVzdWx0XG4gICAqL1xuICBhc3luYyBhbmFseXplQ29zdHMoXG4gICAgdGVtcGxhdGU6IHN0cmluZyxcbiAgICByZWdpb246IHN0cmluZyxcbiAgICBjb25maWc/OiBBbmFseXNpc0NvbmZpZyxcbiAgKTogUHJvbWlzZTxTaW5nbGVUZW1wbGF0ZUNvc3RSZXN1bHQ+IHtcbiAgICBjb25zdCBwYXJzZXIgPSBuZXcgVGVtcGxhdGVQYXJzZXIoKTtcbiAgICBjb25zdCBwcmljaW5nU2VydmljZSA9IG5ldyBQcmljaW5nU2VydmljZShcbiAgICAgIHJlZ2lvbixcbiAgICAgIGNvbmZpZz8udXNhZ2VBc3N1bXB0aW9ucyxcbiAgICAgIGNvbmZpZz8uZXhjbHVkZWRSZXNvdXJjZVR5cGVzLFxuICAgICAgY29uZmlnPy5jYWNoZUNvbmZpZyxcbiAgICApO1xuXG4gICAgdHJ5IHtcbiAgICAgIC8vIFBhcnNlIHRoZSB0ZW1wbGF0ZVxuICAgICAgY29uc3QgcGFyc2VkVGVtcGxhdGUgPSBwYXJzZXIucGFyc2UodGVtcGxhdGUpO1xuICAgICAgY29uc3QgcmVzb3VyY2VzOiBSZXNvdXJjZVdpdGhJZFtdID0gT2JqZWN0LmVudHJpZXMocGFyc2VkVGVtcGxhdGUuUmVzb3VyY2VzIHx8IHt9KS5tYXAoXG4gICAgICAgIChbbG9naWNhbElkLCByZXNvdXJjZV06IFtzdHJpbmcsIGFueV0pID0+ICh7XG4gICAgICAgICAgbG9naWNhbElkLFxuICAgICAgICAgIHR5cGU6IHJlc291cmNlLlR5cGUsXG4gICAgICAgICAgcHJvcGVydGllczogcmVzb3VyY2UuUHJvcGVydGllcyB8fCB7fSxcbiAgICAgICAgfSksXG4gICAgICApO1xuXG4gICAgICAvLyBDYWxjdWxhdGUgY29zdHMgZm9yIGFsbCByZXNvdXJjZXNcbiAgICAgIGNvbnN0IGFuYWx5emVkQXQgPSBuZXcgRGF0ZSgpO1xuICAgICAgY29uc3QgcmVzb3VyY2VDb3N0czogRW5oYW5jZWRSZXNvdXJjZUNvc3RbXSA9IGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgICByZXNvdXJjZXMubWFwKGFzeW5jIChyZXNvdXJjZSkgPT4ge1xuICAgICAgICAgIGNvbnN0IG1vbnRobHlDb3N0ID0gYXdhaXQgcHJpY2luZ1NlcnZpY2UuZ2V0UmVzb3VyY2VDb3N0KHJlc291cmNlLCByZWdpb24sIHJlc291cmNlcyk7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGxvZ2ljYWxJZDogcmVzb3VyY2UubG9naWNhbElkLFxuICAgICAgICAgICAgdHlwZTogcmVzb3VyY2UudHlwZSxcbiAgICAgICAgICAgIG1vbnRobHlDb3N0LFxuICAgICAgICAgICAgcHJvcGVydGllczogcmVzb3VyY2UucHJvcGVydGllcyxcbiAgICAgICAgICAgIHJlZ2lvbixcbiAgICAgICAgICAgIGNhbGN1bGF0ZWRBdDogYW5hbHl6ZWRBdCxcbiAgICAgICAgICB9O1xuICAgICAgICB9KSxcbiAgICAgICk7XG5cbiAgICAgIC8vIENhbGN1bGF0ZSB0b3RhbCBjb3N0XG4gICAgICBjb25zdCB0b3RhbE1vbnRobHlDb3N0ID0gcmVzb3VyY2VDb3N0cy5yZWR1Y2UoXG4gICAgICAgIChzdW0sIHJjKSA9PiBzdW0gKyByYy5tb250aGx5Q29zdC5hbW91bnQsXG4gICAgICAgIDAsXG4gICAgICApO1xuXG4gICAgICAvLyBHZW5lcmF0ZSBjb3N0IGJyZWFrZG93blxuICAgICAgY29uc3QgY29zdEJyZWFrZG93biA9IHRoaXMuZ2VuZXJhdGVDb3N0QnJlYWtkb3duKHJlc291cmNlQ29zdHMpO1xuXG4gICAgICAvLyBHZW5lcmF0ZSBtZXRhZGF0YVxuICAgICAgY29uc3QgbWV0YWRhdGEgPSB0aGlzLmdlbmVyYXRlTWV0YWRhdGEodGVtcGxhdGUsIHJlZ2lvbiwgcmVzb3VyY2VDb3N0cywgYW5hbHl6ZWRBdCk7XG5cbiAgICAgIC8vIEdlbmVyYXRlIHN1bW1hcnkgKHBsYWNlaG9sZGVyIC0gd2lsbCBiZSByZXBsYWNlZCBieSByZXBvcnRlcilcbiAgICAgIGNvbnN0IHN1bW1hcnkgPSBgVG90YWwgbW9udGhseSBjb3N0OiAkJHt0b3RhbE1vbnRobHlDb3N0LnRvRml4ZWQoMil9IFVTRGA7XG5cbiAgICAgIC8vIFJ1biBvcHRpbWl6YXRpb24gYW5hbHlzaXMgaWYgcmVxdWVzdGVkXG4gICAgICBsZXQgcmVjb21tZW5kYXRpb25zO1xuICAgICAgaWYgKGNvbmZpZz8ucmVjb21tZW5kYXRpb25zKSB7XG4gICAgICAgIGNvbnN0IGVuZ2luZSA9IG5ldyBPcHRpbWl6YXRpb25FbmdpbmUoY3JlYXRlRGVmYXVsdEFuYWx5emVycygpLCB7XG4gICAgICAgICAgbWluaW11bVNhdmluZ3NUaHJlc2hvbGQ6IGNvbmZpZy5taW5pbXVtU2F2aW5nc1RocmVzaG9sZCxcbiAgICAgICAgfSk7XG4gICAgICAgIHJlY29tbWVuZGF0aW9ucyA9IGF3YWl0IGVuZ2luZS5hbmFseXplKHJlc291cmNlcywgcmVzb3VyY2VDb3N0cywgcmVnaW9uKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdG90YWxNb250aGx5Q29zdCxcbiAgICAgICAgY3VycmVuY3k6ICdVU0QnLFxuICAgICAgICByZXNvdXJjZUNvc3RzLFxuICAgICAgICBjb3N0QnJlYWtkb3duLFxuICAgICAgICBzdW1tYXJ5LFxuICAgICAgICBtZXRhZGF0YSxcbiAgICAgICAgcmVjb21tZW5kYXRpb25zLFxuICAgICAgfTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgLy8gQ2xlYW4gdXAgcHJpY2luZyBzZXJ2aWNlIHJlc291cmNlc1xuICAgICAgcHJpY2luZ1NlcnZpY2UuZGVzdHJveSgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBHZW5lcmF0ZSBjb3N0IGJyZWFrZG93biBncm91cGVkIGJ5IHJlc291cmNlIHR5cGUgYW5kIGNvbmZpZGVuY2UgbGV2ZWxcbiAgICovXG4gIHByaXZhdGUgZ2VuZXJhdGVDb3N0QnJlYWtkb3duKHJlc291cmNlQ29zdHM6IEVuaGFuY2VkUmVzb3VyY2VDb3N0W10pOiBDb3N0QnJlYWtkb3duIHtcbiAgICAvLyBHcm91cCBieSByZXNvdXJjZSB0eXBlXG4gICAgY29uc3QgYnlUeXBlTWFwID0gbmV3IE1hcDxzdHJpbmcsIEVuaGFuY2VkUmVzb3VyY2VDb3N0W10+KCk7XG4gICAgZm9yIChjb25zdCByYyBvZiByZXNvdXJjZUNvc3RzKSB7XG4gICAgICBjb25zdCBleGlzdGluZyA9IGJ5VHlwZU1hcC5nZXQocmMudHlwZSkgfHwgW107XG4gICAgICBleGlzdGluZy5wdXNoKHJjKTtcbiAgICAgIGJ5VHlwZU1hcC5zZXQocmMudHlwZSwgZXhpc3RpbmcpO1xuICAgIH1cblxuICAgIGNvbnN0IGJ5UmVzb3VyY2VUeXBlOiBSZXNvdXJjZVR5cGVDb3N0W10gPSBBcnJheS5mcm9tKGJ5VHlwZU1hcC5lbnRyaWVzKCkpXG4gICAgICAubWFwKChbcmVzb3VyY2VUeXBlLCByZXNvdXJjZXNdKSA9PiAoe1xuICAgICAgICByZXNvdXJjZVR5cGUsXG4gICAgICAgIGNvdW50OiByZXNvdXJjZXMubGVuZ3RoLFxuICAgICAgICB0b3RhbENvc3Q6IHJlc291cmNlcy5yZWR1Y2UoKHN1bSwgcikgPT4gc3VtICsgci5tb250aGx5Q29zdC5hbW91bnQsIDApLFxuICAgICAgICByZXNvdXJjZXM6IHJlc291cmNlcy5tYXAoKHIpID0+ICh7XG4gICAgICAgICAgbG9naWNhbElkOiByLmxvZ2ljYWxJZCxcbiAgICAgICAgICB0eXBlOiByLnR5cGUsXG4gICAgICAgICAgbW9udGhseUNvc3Q6IHIubW9udGhseUNvc3QsXG4gICAgICAgIH0pKSxcbiAgICAgIH0pKVxuICAgICAgLnNvcnQoKGEsIGIpID0+IGIudG90YWxDb3N0IC0gYS50b3RhbENvc3QpOyAvLyBTb3J0IGJ5IGNvc3QgZGVzY2VuZGluZ1xuXG4gICAgLy8gR3JvdXAgYnkgY29uZmlkZW5jZSBsZXZlbFxuICAgIGNvbnN0IGJ5Q29uZmlkZW5jZU1hcCA9IG5ldyBNYXA8c3RyaW5nLCBFbmhhbmNlZFJlc291cmNlQ29zdFtdPigpO1xuICAgIGZvciAoY29uc3QgcmMgb2YgcmVzb3VyY2VDb3N0cykge1xuICAgICAgY29uc3QgY29uZmlkZW5jZSA9IHJjLm1vbnRobHlDb3N0LmNvbmZpZGVuY2U7XG4gICAgICBjb25zdCBleGlzdGluZyA9IGJ5Q29uZmlkZW5jZU1hcC5nZXQoY29uZmlkZW5jZSkgfHwgW107XG4gICAgICBleGlzdGluZy5wdXNoKHJjKTtcbiAgICAgIGJ5Q29uZmlkZW5jZU1hcC5zZXQoY29uZmlkZW5jZSwgZXhpc3RpbmcpO1xuICAgIH1cblxuICAgIGNvbnN0IGJ5Q29uZmlkZW5jZUxldmVsOiBDb25maWRlbmNlTGV2ZWxDb3N0W10gPSBBcnJheS5mcm9tKGJ5Q29uZmlkZW5jZU1hcC5lbnRyaWVzKCkpLm1hcChcbiAgICAgIChbY29uZmlkZW5jZSwgcmVzb3VyY2VzXSkgPT4gKHtcbiAgICAgICAgY29uZmlkZW5jZTogY29uZmlkZW5jZSBhcyAnaGlnaCcgfCAnbWVkaXVtJyB8ICdsb3cnIHwgJ3Vua25vd24nLFxuICAgICAgICBjb3VudDogcmVzb3VyY2VzLmxlbmd0aCxcbiAgICAgICAgdG90YWxDb3N0OiByZXNvdXJjZXMucmVkdWNlKChzdW0sIHIpID0+IHN1bSArIHIubW9udGhseUNvc3QuYW1vdW50LCAwKSxcbiAgICAgIH0pLFxuICAgICk7XG5cbiAgICAvLyBDb2xsZWN0IGFsbCB1bmlxdWUgYXNzdW1wdGlvbnNcbiAgICBjb25zdCBhc3N1bXB0aW9uc1NldCA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICAgIGZvciAoY29uc3QgcmMgb2YgcmVzb3VyY2VDb3N0cykge1xuICAgICAgZm9yIChjb25zdCBhc3N1bXB0aW9uIG9mIHJjLm1vbnRobHlDb3N0LmFzc3VtcHRpb25zKSB7XG4gICAgICAgIGFzc3VtcHRpb25zU2V0LmFkZChhc3N1bXB0aW9uKTtcbiAgICAgIH1cbiAgICB9XG4gICAgY29uc3QgYXNzdW1wdGlvbnMgPSBBcnJheS5mcm9tKGFzc3VtcHRpb25zU2V0KTtcblxuICAgIHJldHVybiB7XG4gICAgICBieVJlc291cmNlVHlwZSxcbiAgICAgIGJ5Q29uZmlkZW5jZUxldmVsLFxuICAgICAgYXNzdW1wdGlvbnMsXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZW5lcmF0ZSBtZXRhZGF0YSBhYm91dCB0aGUgYW5hbHlzaXNcbiAgICovXG4gIHByaXZhdGUgZ2VuZXJhdGVNZXRhZGF0YShcbiAgICB0ZW1wbGF0ZTogc3RyaW5nLFxuICAgIHJlZ2lvbjogc3RyaW5nLFxuICAgIHJlc291cmNlQ29zdHM6IEVuaGFuY2VkUmVzb3VyY2VDb3N0W10sXG4gICAgYW5hbHl6ZWRBdDogRGF0ZSxcbiAgKTogQW5hbHlzaXNNZXRhZGF0YSB7XG4gICAgLy8gR2VuZXJhdGUgaGFzaCBvZiB0ZW1wbGF0ZVxuICAgIGNvbnN0IHRlbXBsYXRlSGFzaCA9IGNyeXB0by5jcmVhdGVIYXNoKCdzaGEyNTYnKS51cGRhdGUodGVtcGxhdGUpLmRpZ2VzdCgnaGV4Jykuc3Vic3RyaW5nKDAsIDE2KTtcblxuICAgIC8vIENvdW50IHN1cHBvcnRlZCB2cyB1bnN1cHBvcnRlZCByZXNvdXJjZXNcbiAgICBjb25zdCBzdXBwb3J0ZWRSZXNvdXJjZUNvdW50ID0gcmVzb3VyY2VDb3N0cy5maWx0ZXIoXG4gICAgICAocmMpID0+IHJjLm1vbnRobHlDb3N0LmNvbmZpZGVuY2UgIT09ICd1bmtub3duJyB8fCByYy5tb250aGx5Q29zdC5hbW91bnQgPiAwLFxuICAgICkubGVuZ3RoO1xuICAgIGNvbnN0IHVuc3VwcG9ydGVkUmVzb3VyY2VDb3VudCA9IHJlc291cmNlQ29zdHMubGVuZ3RoIC0gc3VwcG9ydGVkUmVzb3VyY2VDb3VudDtcblxuICAgIHJldHVybiB7XG4gICAgICB0ZW1wbGF0ZUhhc2gsXG4gICAgICByZWdpb24sXG4gICAgICBhbmFseXplZEF0LFxuICAgICAgcmVzb3VyY2VDb3VudDogcmVzb3VyY2VDb3N0cy5sZW5ndGgsXG4gICAgICBzdXBwb3J0ZWRSZXNvdXJjZUNvdW50LFxuICAgICAgdW5zdXBwb3J0ZWRSZXNvdXJjZUNvdW50LFxuICAgIH07XG4gIH1cbn1cbiJdfQ==
@@ -10,6 +10,7 @@ export * from '../config';
10
10
  export * from '../synthesis';
11
11
  export * from '../threshold';
12
12
  export * from '../pipeline';
13
+ export * from '../optimization';
13
14
  export declare function analyzeCosts(options: AnalyzeOptions): Promise<CostAnalysisResult>;
14
15
  /**
15
16
  * Analyze a single CloudFormation template for estimated monthly costs
package/dist/api/index.js CHANGED
@@ -36,6 +36,7 @@ __exportStar(require("../config"), exports);
36
36
  __exportStar(require("../synthesis"), exports);
37
37
  __exportStar(require("../threshold"), exports);
38
38
  __exportStar(require("../pipeline"), exports);
39
+ __exportStar(require("../optimization"), exports);
39
40
  async function analyzeCosts(options) {
40
41
  const region = options.region || 'eu-central-1';
41
42
  const format = options.format || 'text';
@@ -117,4 +118,4 @@ async function analyzeSingleTemplate(options) {
117
118
  throw error;
118
119
  }
119
120
  }
120
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXBpL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBb0JBLG9DQW1DQztBQXVCRCxzREFxQ0M7QUFqSEQsbURBQWdEO0FBQ2hELDZEQUEwRDtBQUMxRCw4REFBMkQ7QUFDM0QsbURBQWdEO0FBQ2hELCtFQUE0RTtBQUM1RSwrRUFBNEU7QUFFNUUsMENBQXdCO0FBQ3hCLDBEQUF3QztBQUN4QywyREFBOEQ7QUFBckQsb0hBQUEsa0JBQWtCLE9BQUE7QUFDM0IsMENBQTZFO0FBQXBFLHdHQUFBLGVBQWUsT0FBQTtBQUFFLGlIQUFBLHdCQUF3QixPQUFBO0FBQ2xELGtEQUFnQztBQUNoQyxvREFBa0M7QUFDbEMsNENBQTBCO0FBQzFCLCtDQUE2QjtBQUM3QiwrQ0FBNkI7QUFDN0IsOENBQTRCO0FBRXJCLEtBQUssVUFBVSxZQUFZLENBQUMsT0FBdUI7SUFDeEQsTUFBTSxNQUFNLEdBQUcsT0FBTyxDQUFDLE1BQU0sSUFBSSxjQUFjLENBQUM7SUFDaEQsTUFBTSxNQUFNLEdBQUcsT0FBTyxDQUFDLE1BQU0sSUFBSSxNQUFNLENBQUM7SUFFeEMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLElBQUksQ0FBQyxPQUFPLENBQUMsY0FBYyxFQUFFLENBQUM7UUFDckQsTUFBTSxJQUFJLEtBQUssQ0FBQyxtREFBbUQsQ0FBQyxDQUFDO0lBQ3ZFLENBQUM7SUFFRCxNQUFNLE1BQU0sR0FBRyxJQUFJLCtCQUFjLEVBQUUsQ0FBQztJQUNwQyxNQUFNLFVBQVUsR0FBRyxJQUFJLHVCQUFVLEVBQUUsQ0FBQztJQUNwQyxNQUFNLGNBQWMsR0FBRyxJQUFJLCtCQUFjLEVBQUUsQ0FBQztJQUM1QyxNQUFNLFFBQVEsR0FBRyxJQUFJLG1CQUFRLEVBQUUsQ0FBQztJQUVoQyxJQUFJLENBQUM7UUFDSCxNQUFNLGVBQWUsR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUMzRCxNQUFNLGlCQUFpQixHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBRS9ELE1BQU0sSUFBSSxHQUFHLFVBQVUsQ0FBQyxJQUFJLENBQUMsZUFBZSxFQUFFLGlCQUFpQixDQUFDLENBQUM7UUFFakUsTUFBTSxTQUFTLEdBQUcsTUFBTSxjQUFjLENBQUMsWUFBWSxDQUFDLElBQUksRUFBRSxNQUFNLENBQUMsQ0FBQztRQUVsRSxNQUFNLE9BQU8sR0FBRyxRQUFRLENBQUMsY0FBYyxDQUFDLFNBQVMsRUFBRSxNQUFNLENBQUMsQ0FBQztRQUUzRCxPQUFPO1lBQ0wsVUFBVSxFQUFFLFNBQVMsQ0FBQyxVQUFVO1lBQ2hDLFFBQVEsRUFBRSxTQUFTLENBQUMsUUFBUTtZQUM1QixjQUFjLEVBQUUsU0FBUyxDQUFDLFVBQVU7WUFDcEMsZ0JBQWdCLEVBQUUsU0FBUyxDQUFDLFlBQVk7WUFDeEMsaUJBQWlCLEVBQUUsU0FBUyxDQUFDLGFBQWE7WUFDMUMsT0FBTztTQUNSLENBQUM7SUFDSixDQUFDO1lBQVMsQ0FBQztRQUNULG9EQUFvRDtRQUNwRCxjQUFjLENBQUMsT0FBTyxFQUFFLENBQUM7SUFDM0IsQ0FBQztBQUNILENBQUM7QUFFRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FvQkc7QUFDSSxLQUFLLFVBQVUscUJBQXFCLENBQ3pDLE9BQXFDO0lBRXJDLE1BQU0sTUFBTSxHQUFHLE9BQU8sQ0FBQyxNQUFNLElBQUksY0FBYyxDQUFDO0lBQ2hELE1BQU0sTUFBTSxHQUFHLE9BQU8sQ0FBQyxNQUFNLElBQUksTUFBTSxDQUFDO0lBRXhDLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDdEIsTUFBTSxJQUFJLEtBQUssQ0FBQyw4QkFBOEIsQ0FBQyxDQUFDO0lBQ2xELENBQUM7SUFFRCxNQUFNLFFBQVEsR0FBRyxJQUFJLCtDQUFzQixFQUFFLENBQUM7SUFDOUMsTUFBTSxRQUFRLEdBQUcsSUFBSSwrQ0FBc0IsRUFBRSxDQUFDO0lBRTlDLElBQUksQ0FBQztRQUNILHVCQUF1QjtRQUN2QixNQUFNLE1BQU0sR0FBRyxNQUFNLFFBQVEsQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDLFFBQVEsRUFBRSxNQUFNLEVBQUUsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBRXJGLGdEQUFnRDtRQUNoRCxNQUFNLE9BQU8sR0FBRyxRQUFRLENBQUMsY0FBYyxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQztRQUV4RCxPQUFPO1lBQ0wsR0FBRyxNQUFNO1lBQ1QsT0FBTztTQUNSLENBQUM7SUFDSixDQUFDO0lBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztRQUNmLGdDQUFnQztRQUNoQyxJQUFJLEtBQUssWUFBWSxLQUFLLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsNEJBQTRCLENBQUMsRUFBRSxDQUFDO1lBQ25GLE1BQU0sSUFBSSxLQUFLLENBQ2IsNEVBQTRFO2dCQUM1RSx5RUFBeUU7Z0JBQ3pFLHdDQUF3QztnQkFDeEMsaURBQWlEO2dCQUNqRCwyREFBMkQsQ0FDNUQsQ0FBQztRQUNKLENBQUM7UUFDRCxNQUFNLEtBQUssQ0FBQztJQUNkLENBQUM7QUFDSCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQW5hbHl6ZU9wdGlvbnMsIENvc3RBbmFseXNpc1Jlc3VsdCB9IGZyb20gJy4vdHlwZXMnO1xuaW1wb3J0IHsgQW5hbHl6ZVNpbmdsZVRlbXBsYXRlT3B0aW9ucywgU2luZ2xlVGVtcGxhdGVDb3N0UmVzdWx0IH0gZnJvbSAnLi9zaW5nbGUtdGVtcGxhdGUtdHlwZXMnO1xuaW1wb3J0IHsgRGlmZkVuZ2luZSB9IGZyb20gJy4uL2RpZmYvRGlmZkVuZ2luZSc7XG5pbXBvcnQgeyBUZW1wbGF0ZVBhcnNlciB9IGZyb20gJy4uL3BhcnNlci9UZW1wbGF0ZVBhcnNlcic7XG5pbXBvcnQgeyBQcmljaW5nU2VydmljZSB9IGZyb20gJy4uL3ByaWNpbmcvUHJpY2luZ1NlcnZpY2UnO1xuaW1wb3J0IHsgUmVwb3J0ZXIgfSBmcm9tICcuLi9yZXBvcnRlci9SZXBvcnRlcic7XG5pbXBvcnQgeyBTaW5nbGVUZW1wbGF0ZVJlcG9ydGVyIH0gZnJvbSAnLi4vcmVwb3J0ZXIvU2luZ2xlVGVtcGxhdGVSZXBvcnRlcic7XG5pbXBvcnQgeyBTaW5nbGVUZW1wbGF0ZUFuYWx5emVyIH0gZnJvbSAnLi4vYW5hbHlzaXMvU2luZ2xlVGVtcGxhdGVBbmFseXplcic7XG5cbmV4cG9ydCAqIGZyb20gJy4vdHlwZXMnO1xuZXhwb3J0ICogZnJvbSAnLi9zaW5nbGUtdGVtcGxhdGUtdHlwZXMnO1xuZXhwb3J0IHsgVGVtcGxhdGVQYXJzZUVycm9yIH0gZnJvbSAnLi4vcGFyc2VyL1RlbXBsYXRlUGFyc2VyJztcbmV4cG9ydCB7IFByaWNpbmdBUElFcnJvciwgVW5zdXBwb3J0ZWRSZXNvdXJjZUVycm9yIH0gZnJvbSAnLi4vcHJpY2luZy90eXBlcyc7XG5leHBvcnQgKiBmcm9tICcuLi9pbnRlZ3JhdGlvbnMnO1xuZXhwb3J0ICogZnJvbSAnLi4vcmVwb3J0ZXIvdHlwZXMnO1xuZXhwb3J0ICogZnJvbSAnLi4vY29uZmlnJztcbmV4cG9ydCAqIGZyb20gJy4uL3N5bnRoZXNpcyc7XG5leHBvcnQgKiBmcm9tICcuLi90aHJlc2hvbGQnO1xuZXhwb3J0ICogZnJvbSAnLi4vcGlwZWxpbmUnO1xuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gYW5hbHl6ZUNvc3RzKG9wdGlvbnM6IEFuYWx5emVPcHRpb25zKTogUHJvbWlzZTxDb3N0QW5hbHlzaXNSZXN1bHQ+IHtcbiAgY29uc3QgcmVnaW9uID0gb3B0aW9ucy5yZWdpb24gfHwgJ2V1LWNlbnRyYWwtMSc7XG4gIGNvbnN0IGZvcm1hdCA9IG9wdGlvbnMuZm9ybWF0IHx8ICd0ZXh0JztcblxuICBpZiAoIW9wdGlvbnMuYmFzZVRlbXBsYXRlIHx8ICFvcHRpb25zLnRhcmdldFRlbXBsYXRlKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdCb3RoIGJhc2VUZW1wbGF0ZSBhbmQgdGFyZ2V0VGVtcGxhdGUgYXJlIHJlcXVpcmVkJyk7XG4gIH1cblxuICBjb25zdCBwYXJzZXIgPSBuZXcgVGVtcGxhdGVQYXJzZXIoKTtcbiAgY29uc3QgZGlmZkVuZ2luZSA9IG5ldyBEaWZmRW5naW5lKCk7XG4gIGNvbnN0IHByaWNpbmdTZXJ2aWNlID0gbmV3IFByaWNpbmdTZXJ2aWNlKCk7XG4gIGNvbnN0IHJlcG9ydGVyID0gbmV3IFJlcG9ydGVyKCk7XG5cbiAgdHJ5IHtcbiAgICBjb25zdCBiYXNlVGVtcGxhdGVPYmogPSBwYXJzZXIucGFyc2Uob3B0aW9ucy5iYXNlVGVtcGxhdGUpO1xuICAgIGNvbnN0IHRhcmdldFRlbXBsYXRlT2JqID0gcGFyc2VyLnBhcnNlKG9wdGlvbnMudGFyZ2V0VGVtcGxhdGUpO1xuXG4gICAgY29uc3QgZGlmZiA9IGRpZmZFbmdpbmUuZGlmZihiYXNlVGVtcGxhdGVPYmosIHRhcmdldFRlbXBsYXRlT2JqKTtcblxuICAgIGNvbnN0IGNvc3REZWx0YSA9IGF3YWl0IHByaWNpbmdTZXJ2aWNlLmdldENvc3REZWx0YShkaWZmLCByZWdpb24pO1xuXG4gICAgY29uc3Qgc3VtbWFyeSA9IHJlcG9ydGVyLmdlbmVyYXRlUmVwb3J0KGNvc3REZWx0YSwgZm9ybWF0KTtcblxuICAgIHJldHVybiB7XG4gICAgICB0b3RhbERlbHRhOiBjb3N0RGVsdGEudG90YWxEZWx0YSxcbiAgICAgIGN1cnJlbmN5OiBjb3N0RGVsdGEuY3VycmVuY3ksXG4gICAgICBhZGRlZFJlc291cmNlczogY29zdERlbHRhLmFkZGVkQ29zdHMsXG4gICAgICByZW1vdmVkUmVzb3VyY2VzOiBjb3N0RGVsdGEucmVtb3ZlZENvc3RzLFxuICAgICAgbW9kaWZpZWRSZXNvdXJjZXM6IGNvc3REZWx0YS5tb2RpZmllZENvc3RzLFxuICAgICAgc3VtbWFyeSxcbiAgICB9O1xuICB9IGZpbmFsbHkge1xuICAgIC8vIENsZWFuIHVwIHJlc291cmNlcyB0byBwcmV2ZW50IGhhbmdpbmcgY29ubmVjdGlvbnNcbiAgICBwcmljaW5nU2VydmljZS5kZXN0cm95KCk7XG4gIH1cbn1cblxuLyoqXG4gKiBBbmFseXplIGEgc2luZ2xlIENsb3VkRm9ybWF0aW9uIHRlbXBsYXRlIGZvciBlc3RpbWF0ZWQgbW9udGhseSBjb3N0c1xuICogXG4gKiBAcGFyYW0gb3B0aW9ucyAtIENvbmZpZ3VyYXRpb24gb3B0aW9ucyBpbmNsdWRpbmcgdGVtcGxhdGUgY29udGVudCwgcmVnaW9uLCBmb3JtYXQsIGFuZCBhbmFseXNpcyBjb25maWdcbiAqIEByZXR1cm5zIFByb21pc2UgcmVzb2x2aW5nIHRvIGRldGFpbGVkIGNvc3QgYW5hbHlzaXMgcmVzdWx0XG4gKiBcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCByZXN1bHQgPSBhd2FpdCBhbmFseXplU2luZ2xlVGVtcGxhdGUoe1xuICogICB0ZW1wbGF0ZTogZnMucmVhZEZpbGVTeW5jKCd0ZW1wbGF0ZS5qc29uJywgJ3V0Zi04JyksXG4gKiAgIHJlZ2lvbjogJ3VzLWVhc3QtMScsXG4gKiAgIGZvcm1hdDogJ3RleHQnLFxuICogICBjb25maWc6IHtcbiAqICAgICB1c2FnZUFzc3VtcHRpb25zOiB7XG4gKiAgICAgICBsYW1iZGE6IHsgaW52b2NhdGlvbnNQZXJNb250aDogMTAwMDAwMCB9XG4gKiAgICAgfVxuICogICB9XG4gKiB9KTtcbiAqIGNvbnNvbGUubG9nKHJlc3VsdC5zdW1tYXJ5KTtcbiAqIGBgYFxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gYW5hbHl6ZVNpbmdsZVRlbXBsYXRlKFxuICBvcHRpb25zOiBBbmFseXplU2luZ2xlVGVtcGxhdGVPcHRpb25zLFxuKTogUHJvbWlzZTxTaW5nbGVUZW1wbGF0ZUNvc3RSZXN1bHQ+IHtcbiAgY29uc3QgcmVnaW9uID0gb3B0aW9ucy5yZWdpb24gfHwgJ2V1LWNlbnRyYWwtMSc7XG4gIGNvbnN0IGZvcm1hdCA9IG9wdGlvbnMuZm9ybWF0IHx8ICd0ZXh0JztcblxuICBpZiAoIW9wdGlvbnMudGVtcGxhdGUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1RlbXBsYXRlIGNvbnRlbnQgaXMgcmVxdWlyZWQnKTtcbiAgfVxuXG4gIGNvbnN0IGFuYWx5emVyID0gbmV3IFNpbmdsZVRlbXBsYXRlQW5hbHl6ZXIoKTtcbiAgY29uc3QgcmVwb3J0ZXIgPSBuZXcgU2luZ2xlVGVtcGxhdGVSZXBvcnRlcigpO1xuXG4gIHRyeSB7XG4gICAgLy8gQW5hbHl6ZSB0aGUgdGVtcGxhdGVcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBhbmFseXplci5hbmFseXplQ29zdHMob3B0aW9ucy50ZW1wbGF0ZSwgcmVnaW9uLCBvcHRpb25zLmNvbmZpZyk7XG5cbiAgICAvLyBHZW5lcmF0ZSBmb3JtYXR0ZWQgc3VtbWFyeSB1c2luZyB0aGUgcmVwb3J0ZXJcbiAgICBjb25zdCBzdW1tYXJ5ID0gcmVwb3J0ZXIuZ2VuZXJhdGVSZXBvcnQocmVzdWx0LCBmb3JtYXQpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLnJlc3VsdCxcbiAgICAgIHN1bW1hcnksXG4gICAgfTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAvLyBIYW5kbGUgQVdTIGNyZWRlbnRpYWxzIGVycm9yc1xuICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIEVycm9yICYmIGVycm9yLm1lc3NhZ2UuaW5jbHVkZXMoJ0NvdWxkIG5vdCBsb2FkIGNyZWRlbnRpYWxzJykpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgJ0FXUyBjcmVkZW50aWFscyBub3QgY29uZmlndXJlZC4gUGxlYXNlIHNldCBBV1MgY3JlZGVudGlhbHMgdXNpbmcgb25lIG9mOlxcbicgK1xuICAgICAgICAnICAtIEFXU19BQ0NFU1NfS0VZX0lEIGFuZCBBV1NfU0VDUkVUX0FDQ0VTU19LRVkgZW52aXJvbm1lbnQgdmFyaWFibGVzXFxuJyArXG4gICAgICAgICcgIC0gQVdTX1BST0ZJTEUgZW52aXJvbm1lbnQgdmFyaWFibGVcXG4nICtcbiAgICAgICAgJyAgLSBBV1MgY3JlZGVudGlhbHMgZmlsZSAofi8uYXdzL2NyZWRlbnRpYWxzKVxcbicgK1xuICAgICAgICAnICAtIEZvciBDSS9DRCwgY29uZmlndXJlIEFXUyBjcmVkZW50aWFscyBpbiB5b3VyIHBpcGVsaW5lJyxcbiAgICAgICk7XG4gICAgfVxuICAgIHRocm93IGVycm9yO1xuICB9XG59XG5cbiJdfQ==
121
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXBpL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBcUJBLG9DQW1DQztBQXVCRCxzREFxQ0M7QUFsSEQsbURBQWdEO0FBQ2hELDZEQUEwRDtBQUMxRCw4REFBMkQ7QUFDM0QsbURBQWdEO0FBQ2hELCtFQUE0RTtBQUM1RSwrRUFBNEU7QUFFNUUsMENBQXdCO0FBQ3hCLDBEQUF3QztBQUN4QywyREFBOEQ7QUFBckQsb0hBQUEsa0JBQWtCLE9BQUE7QUFDM0IsMENBQTZFO0FBQXBFLHdHQUFBLGVBQWUsT0FBQTtBQUFFLGlIQUFBLHdCQUF3QixPQUFBO0FBQ2xELGtEQUFnQztBQUNoQyxvREFBa0M7QUFDbEMsNENBQTBCO0FBQzFCLCtDQUE2QjtBQUM3QiwrQ0FBNkI7QUFDN0IsOENBQTRCO0FBQzVCLGtEQUFnQztBQUV6QixLQUFLLFVBQVUsWUFBWSxDQUFDLE9BQXVCO0lBQ3hELE1BQU0sTUFBTSxHQUFHLE9BQU8sQ0FBQyxNQUFNLElBQUksY0FBYyxDQUFDO0lBQ2hELE1BQU0sTUFBTSxHQUFHLE9BQU8sQ0FBQyxNQUFNLElBQUksTUFBTSxDQUFDO0lBRXhDLElBQUksQ0FBQyxPQUFPLENBQUMsWUFBWSxJQUFJLENBQUMsT0FBTyxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBQ3JELE1BQU0sSUFBSSxLQUFLLENBQUMsbURBQW1ELENBQUMsQ0FBQztJQUN2RSxDQUFDO0lBRUQsTUFBTSxNQUFNLEdBQUcsSUFBSSwrQkFBYyxFQUFFLENBQUM7SUFDcEMsTUFBTSxVQUFVLEdBQUcsSUFBSSx1QkFBVSxFQUFFLENBQUM7SUFDcEMsTUFBTSxjQUFjLEdBQUcsSUFBSSwrQkFBYyxFQUFFLENBQUM7SUFDNUMsTUFBTSxRQUFRLEdBQUcsSUFBSSxtQkFBUSxFQUFFLENBQUM7SUFFaEMsSUFBSSxDQUFDO1FBQ0gsTUFBTSxlQUFlLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDM0QsTUFBTSxpQkFBaUIsR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxjQUFjLENBQUMsQ0FBQztRQUUvRCxNQUFNLElBQUksR0FBRyxVQUFVLENBQUMsSUFBSSxDQUFDLGVBQWUsRUFBRSxpQkFBaUIsQ0FBQyxDQUFDO1FBRWpFLE1BQU0sU0FBUyxHQUFHLE1BQU0sY0FBYyxDQUFDLFlBQVksQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFFbEUsTUFBTSxPQUFPLEdBQUcsUUFBUSxDQUFDLGNBQWMsQ0FBQyxTQUFTLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFFM0QsT0FBTztZQUNMLFVBQVUsRUFBRSxTQUFTLENBQUMsVUFBVTtZQUNoQyxRQUFRLEVBQUUsU0FBUyxDQUFDLFFBQVE7WUFDNUIsY0FBYyxFQUFFLFNBQVMsQ0FBQyxVQUFVO1lBQ3BDLGdCQUFnQixFQUFFLFNBQVMsQ0FBQyxZQUFZO1lBQ3hDLGlCQUFpQixFQUFFLFNBQVMsQ0FBQyxhQUFhO1lBQzFDLE9BQU87U0FDUixDQUFDO0lBQ0osQ0FBQztZQUFTLENBQUM7UUFDVCxvREFBb0Q7UUFDcEQsY0FBYyxDQUFDLE9BQU8sRUFBRSxDQUFDO0lBQzNCLENBQUM7QUFDSCxDQUFDO0FBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBb0JHO0FBQ0ksS0FBSyxVQUFVLHFCQUFxQixDQUN6QyxPQUFxQztJQUVyQyxNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsTUFBTSxJQUFJLGNBQWMsQ0FBQztJQUNoRCxNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsTUFBTSxJQUFJLE1BQU0sQ0FBQztJQUV4QyxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQ3RCLE1BQU0sSUFBSSxLQUFLLENBQUMsOEJBQThCLENBQUMsQ0FBQztJQUNsRCxDQUFDO0lBRUQsTUFBTSxRQUFRLEdBQUcsSUFBSSwrQ0FBc0IsRUFBRSxDQUFDO0lBQzlDLE1BQU0sUUFBUSxHQUFHLElBQUksK0NBQXNCLEVBQUUsQ0FBQztJQUU5QyxJQUFJLENBQUM7UUFDSCx1QkFBdUI7UUFDdkIsTUFBTSxNQUFNLEdBQUcsTUFBTSxRQUFRLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxRQUFRLEVBQUUsTUFBTSxFQUFFLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUVyRixnREFBZ0Q7UUFDaEQsTUFBTSxPQUFPLEdBQUcsUUFBUSxDQUFDLGNBQWMsQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFFeEQsT0FBTztZQUNMLEdBQUcsTUFBTTtZQUNULE9BQU87U0FDUixDQUFDO0lBQ0osQ0FBQztJQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7UUFDZixnQ0FBZ0M7UUFDaEMsSUFBSSxLQUFLLFlBQVksS0FBSyxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLDRCQUE0QixDQUFDLEVBQUUsQ0FBQztZQUNuRixNQUFNLElBQUksS0FBSyxDQUNiLDRFQUE0RTtnQkFDNUUseUVBQXlFO2dCQUN6RSx3Q0FBd0M7Z0JBQ3hDLGlEQUFpRDtnQkFDakQsMkRBQTJELENBQzVELENBQUM7UUFDSixDQUFDO1FBQ0QsTUFBTSxLQUFLLENBQUM7SUFDZCxDQUFDO0FBQ0gsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEFuYWx5emVPcHRpb25zLCBDb3N0QW5hbHlzaXNSZXN1bHQgfSBmcm9tICcuL3R5cGVzJztcbmltcG9ydCB7IEFuYWx5emVTaW5nbGVUZW1wbGF0ZU9wdGlvbnMsIFNpbmdsZVRlbXBsYXRlQ29zdFJlc3VsdCB9IGZyb20gJy4vc2luZ2xlLXRlbXBsYXRlLXR5cGVzJztcbmltcG9ydCB7IERpZmZFbmdpbmUgfSBmcm9tICcuLi9kaWZmL0RpZmZFbmdpbmUnO1xuaW1wb3J0IHsgVGVtcGxhdGVQYXJzZXIgfSBmcm9tICcuLi9wYXJzZXIvVGVtcGxhdGVQYXJzZXInO1xuaW1wb3J0IHsgUHJpY2luZ1NlcnZpY2UgfSBmcm9tICcuLi9wcmljaW5nL1ByaWNpbmdTZXJ2aWNlJztcbmltcG9ydCB7IFJlcG9ydGVyIH0gZnJvbSAnLi4vcmVwb3J0ZXIvUmVwb3J0ZXInO1xuaW1wb3J0IHsgU2luZ2xlVGVtcGxhdGVSZXBvcnRlciB9IGZyb20gJy4uL3JlcG9ydGVyL1NpbmdsZVRlbXBsYXRlUmVwb3J0ZXInO1xuaW1wb3J0IHsgU2luZ2xlVGVtcGxhdGVBbmFseXplciB9IGZyb20gJy4uL2FuYWx5c2lzL1NpbmdsZVRlbXBsYXRlQW5hbHl6ZXInO1xuXG5leHBvcnQgKiBmcm9tICcuL3R5cGVzJztcbmV4cG9ydCAqIGZyb20gJy4vc2luZ2xlLXRlbXBsYXRlLXR5cGVzJztcbmV4cG9ydCB7IFRlbXBsYXRlUGFyc2VFcnJvciB9IGZyb20gJy4uL3BhcnNlci9UZW1wbGF0ZVBhcnNlcic7XG5leHBvcnQgeyBQcmljaW5nQVBJRXJyb3IsIFVuc3VwcG9ydGVkUmVzb3VyY2VFcnJvciB9IGZyb20gJy4uL3ByaWNpbmcvdHlwZXMnO1xuZXhwb3J0ICogZnJvbSAnLi4vaW50ZWdyYXRpb25zJztcbmV4cG9ydCAqIGZyb20gJy4uL3JlcG9ydGVyL3R5cGVzJztcbmV4cG9ydCAqIGZyb20gJy4uL2NvbmZpZyc7XG5leHBvcnQgKiBmcm9tICcuLi9zeW50aGVzaXMnO1xuZXhwb3J0ICogZnJvbSAnLi4vdGhyZXNob2xkJztcbmV4cG9ydCAqIGZyb20gJy4uL3BpcGVsaW5lJztcbmV4cG9ydCAqIGZyb20gJy4uL29wdGltaXphdGlvbic7XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBhbmFseXplQ29zdHMob3B0aW9uczogQW5hbHl6ZU9wdGlvbnMpOiBQcm9taXNlPENvc3RBbmFseXNpc1Jlc3VsdD4ge1xuICBjb25zdCByZWdpb24gPSBvcHRpb25zLnJlZ2lvbiB8fCAnZXUtY2VudHJhbC0xJztcbiAgY29uc3QgZm9ybWF0ID0gb3B0aW9ucy5mb3JtYXQgfHwgJ3RleHQnO1xuXG4gIGlmICghb3B0aW9ucy5iYXNlVGVtcGxhdGUgfHwgIW9wdGlvbnMudGFyZ2V0VGVtcGxhdGUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0JvdGggYmFzZVRlbXBsYXRlIGFuZCB0YXJnZXRUZW1wbGF0ZSBhcmUgcmVxdWlyZWQnKTtcbiAgfVxuXG4gIGNvbnN0IHBhcnNlciA9IG5ldyBUZW1wbGF0ZVBhcnNlcigpO1xuICBjb25zdCBkaWZmRW5naW5lID0gbmV3IERpZmZFbmdpbmUoKTtcbiAgY29uc3QgcHJpY2luZ1NlcnZpY2UgPSBuZXcgUHJpY2luZ1NlcnZpY2UoKTtcbiAgY29uc3QgcmVwb3J0ZXIgPSBuZXcgUmVwb3J0ZXIoKTtcblxuICB0cnkge1xuICAgIGNvbnN0IGJhc2VUZW1wbGF0ZU9iaiA9IHBhcnNlci5wYXJzZShvcHRpb25zLmJhc2VUZW1wbGF0ZSk7XG4gICAgY29uc3QgdGFyZ2V0VGVtcGxhdGVPYmogPSBwYXJzZXIucGFyc2Uob3B0aW9ucy50YXJnZXRUZW1wbGF0ZSk7XG5cbiAgICBjb25zdCBkaWZmID0gZGlmZkVuZ2luZS5kaWZmKGJhc2VUZW1wbGF0ZU9iaiwgdGFyZ2V0VGVtcGxhdGVPYmopO1xuXG4gICAgY29uc3QgY29zdERlbHRhID0gYXdhaXQgcHJpY2luZ1NlcnZpY2UuZ2V0Q29zdERlbHRhKGRpZmYsIHJlZ2lvbik7XG5cbiAgICBjb25zdCBzdW1tYXJ5ID0gcmVwb3J0ZXIuZ2VuZXJhdGVSZXBvcnQoY29zdERlbHRhLCBmb3JtYXQpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHRvdGFsRGVsdGE6IGNvc3REZWx0YS50b3RhbERlbHRhLFxuICAgICAgY3VycmVuY3k6IGNvc3REZWx0YS5jdXJyZW5jeSxcbiAgICAgIGFkZGVkUmVzb3VyY2VzOiBjb3N0RGVsdGEuYWRkZWRDb3N0cyxcbiAgICAgIHJlbW92ZWRSZXNvdXJjZXM6IGNvc3REZWx0YS5yZW1vdmVkQ29zdHMsXG4gICAgICBtb2RpZmllZFJlc291cmNlczogY29zdERlbHRhLm1vZGlmaWVkQ29zdHMsXG4gICAgICBzdW1tYXJ5LFxuICAgIH07XG4gIH0gZmluYWxseSB7XG4gICAgLy8gQ2xlYW4gdXAgcmVzb3VyY2VzIHRvIHByZXZlbnQgaGFuZ2luZyBjb25uZWN0aW9uc1xuICAgIHByaWNpbmdTZXJ2aWNlLmRlc3Ryb3koKTtcbiAgfVxufVxuXG4vKipcbiAqIEFuYWx5emUgYSBzaW5nbGUgQ2xvdWRGb3JtYXRpb24gdGVtcGxhdGUgZm9yIGVzdGltYXRlZCBtb250aGx5IGNvc3RzXG4gKiBcbiAqIEBwYXJhbSBvcHRpb25zIC0gQ29uZmlndXJhdGlvbiBvcHRpb25zIGluY2x1ZGluZyB0ZW1wbGF0ZSBjb250ZW50LCByZWdpb24sIGZvcm1hdCwgYW5kIGFuYWx5c2lzIGNvbmZpZ1xuICogQHJldHVybnMgUHJvbWlzZSByZXNvbHZpbmcgdG8gZGV0YWlsZWQgY29zdCBhbmFseXNpcyByZXN1bHRcbiAqIFxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGFuYWx5emVTaW5nbGVUZW1wbGF0ZSh7XG4gKiAgIHRlbXBsYXRlOiBmcy5yZWFkRmlsZVN5bmMoJ3RlbXBsYXRlLmpzb24nLCAndXRmLTgnKSxcbiAqICAgcmVnaW9uOiAndXMtZWFzdC0xJyxcbiAqICAgZm9ybWF0OiAndGV4dCcsXG4gKiAgIGNvbmZpZzoge1xuICogICAgIHVzYWdlQXNzdW1wdGlvbnM6IHtcbiAqICAgICAgIGxhbWJkYTogeyBpbnZvY2F0aW9uc1Blck1vbnRoOiAxMDAwMDAwIH1cbiAqICAgICB9XG4gKiAgIH1cbiAqIH0pO1xuICogY29uc29sZS5sb2cocmVzdWx0LnN1bW1hcnkpO1xuICogYGBgXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBhbmFseXplU2luZ2xlVGVtcGxhdGUoXG4gIG9wdGlvbnM6IEFuYWx5emVTaW5nbGVUZW1wbGF0ZU9wdGlvbnMsXG4pOiBQcm9taXNlPFNpbmdsZVRlbXBsYXRlQ29zdFJlc3VsdD4ge1xuICBjb25zdCByZWdpb24gPSBvcHRpb25zLnJlZ2lvbiB8fCAnZXUtY2VudHJhbC0xJztcbiAgY29uc3QgZm9ybWF0ID0gb3B0aW9ucy5mb3JtYXQgfHwgJ3RleHQnO1xuXG4gIGlmICghb3B0aW9ucy50ZW1wbGF0ZSkge1xuICAgIHRocm93IG5ldyBFcnJvcignVGVtcGxhdGUgY29udGVudCBpcyByZXF1aXJlZCcpO1xuICB9XG5cbiAgY29uc3QgYW5hbHl6ZXIgPSBuZXcgU2luZ2xlVGVtcGxhdGVBbmFseXplcigpO1xuICBjb25zdCByZXBvcnRlciA9IG5ldyBTaW5nbGVUZW1wbGF0ZVJlcG9ydGVyKCk7XG5cbiAgdHJ5IHtcbiAgICAvLyBBbmFseXplIHRoZSB0ZW1wbGF0ZVxuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGFuYWx5emVyLmFuYWx5emVDb3N0cyhvcHRpb25zLnRlbXBsYXRlLCByZWdpb24sIG9wdGlvbnMuY29uZmlnKTtcblxuICAgIC8vIEdlbmVyYXRlIGZvcm1hdHRlZCBzdW1tYXJ5IHVzaW5nIHRoZSByZXBvcnRlclxuICAgIGNvbnN0IHN1bW1hcnkgPSByZXBvcnRlci5nZW5lcmF0ZVJlcG9ydChyZXN1bHQsIGZvcm1hdCk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgLi4ucmVzdWx0LFxuICAgICAgc3VtbWFyeSxcbiAgICB9O1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIC8vIEhhbmRsZSBBV1MgY3JlZGVudGlhbHMgZXJyb3JzXG4gICAgaWYgKGVycm9yIGluc3RhbmNlb2YgRXJyb3IgJiYgZXJyb3IubWVzc2FnZS5pbmNsdWRlcygnQ291bGQgbm90IGxvYWQgY3JlZGVudGlhbHMnKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAnQVdTIGNyZWRlbnRpYWxzIG5vdCBjb25maWd1cmVkLiBQbGVhc2Ugc2V0IEFXUyBjcmVkZW50aWFscyB1c2luZyBvbmUgb2Y6XFxuJyArXG4gICAgICAgICcgIC0gQVdTX0FDQ0VTU19LRVlfSUQgYW5kIEFXU19TRUNSRVRfQUNDRVNTX0tFWSBlbnZpcm9ubWVudCB2YXJpYWJsZXNcXG4nICtcbiAgICAgICAgJyAgLSBBV1NfUFJPRklMRSBlbnZpcm9ubWVudCB2YXJpYWJsZVxcbicgK1xuICAgICAgICAnICAtIEFXUyBjcmVkZW50aWFscyBmaWxlICh+Ly5hd3MvY3JlZGVudGlhbHMpXFxuJyArXG4gICAgICAgICcgIC0gRm9yIENJL0NELCBjb25maWd1cmUgQVdTIGNyZWRlbnRpYWxzIGluIHlvdXIgcGlwZWxpbmUnLFxuICAgICAgKTtcbiAgICB9XG4gICAgdGhyb3cgZXJyb3I7XG4gIH1cbn1cblxuIl19
@@ -1,5 +1,6 @@
1
1
  import { ResourceCost } from '../pricing/types';
2
2
  import { UsageAssumptionsConfig, CacheConfig } from '../config/types';
3
+ import { OptimizationResult } from '../optimization/types';
3
4
  /**
4
5
  * Configuration options for single template analysis
5
6
  */
@@ -7,6 +8,8 @@ export interface AnalysisConfig {
7
8
  usageAssumptions?: UsageAssumptionsConfig;
8
9
  excludedResourceTypes?: string[];
9
10
  cacheConfig?: CacheConfig;
11
+ recommendations?: boolean;
12
+ minimumSavingsThreshold?: number;
10
13
  }
11
14
  /**
12
15
  * Metadata about the analysis
@@ -62,6 +65,7 @@ export interface SingleTemplateCostResult {
62
65
  costBreakdown: CostBreakdown;
63
66
  summary: string;
64
67
  metadata: AnalysisMetadata;
68
+ recommendations?: OptimizationResult;
65
69
  }
66
70
  /**
67
71
  * Options for analyzing a single template
@@ -1,3 +1,3 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2luZ2xlLXRlbXBsYXRlLXR5cGVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FwaS9zaW5nbGUtdGVtcGxhdGUtdHlwZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFJlc291cmNlQ29zdCB9IGZyb20gJy4uL3ByaWNpbmcvdHlwZXMnO1xuaW1wb3J0IHsgVXNhZ2VBc3N1bXB0aW9uc0NvbmZpZywgQ2FjaGVDb25maWcgfSBmcm9tICcuLi9jb25maWcvdHlwZXMnO1xuXG4vKipcbiAqIENvbmZpZ3VyYXRpb24gb3B0aW9ucyBmb3Igc2luZ2xlIHRlbXBsYXRlIGFuYWx5c2lzXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQW5hbHlzaXNDb25maWcge1xuICB1c2FnZUFzc3VtcHRpb25zPzogVXNhZ2VBc3N1bXB0aW9uc0NvbmZpZztcbiAgZXhjbHVkZWRSZXNvdXJjZVR5cGVzPzogc3RyaW5nW107XG4gIGNhY2hlQ29uZmlnPzogQ2FjaGVDb25maWc7XG59XG5cbi8qKlxuICogTWV0YWRhdGEgYWJvdXQgdGhlIGFuYWx5c2lzXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQW5hbHlzaXNNZXRhZGF0YSB7XG4gIHRlbXBsYXRlSGFzaDogc3RyaW5nO1xuICByZWdpb246IHN0cmluZztcbiAgYW5hbHl6ZWRBdDogRGF0ZTtcbiAgcmVzb3VyY2VDb3VudDogbnVtYmVyO1xuICBzdXBwb3J0ZWRSZXNvdXJjZUNvdW50OiBudW1iZXI7XG4gIHVuc3VwcG9ydGVkUmVzb3VyY2VDb3VudDogbnVtYmVyO1xufVxuXG4vKipcbiAqIENvc3QgaW5mb3JtYXRpb24gZ3JvdXBlZCBieSByZXNvdXJjZSB0eXBlXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUmVzb3VyY2VUeXBlQ29zdCB7XG4gIHJlc291cmNlVHlwZTogc3RyaW5nO1xuICBjb3VudDogbnVtYmVyO1xuICB0b3RhbENvc3Q6IG51bWJlcjtcbiAgcmVzb3VyY2VzOiBSZXNvdXJjZUNvc3RbXTtcbn1cblxuLyoqXG4gKiBDb3N0IGluZm9ybWF0aW9uIGdyb3VwZWQgYnkgY29uZmlkZW5jZSBsZXZlbFxuICovXG5leHBvcnQgaW50ZXJmYWNlIENvbmZpZGVuY2VMZXZlbENvc3Qge1xuICBjb25maWRlbmNlOiAnaGlnaCcgfCAnbWVkaXVtJyB8ICdsb3cnIHwgJ3Vua25vd24nO1xuICBjb3VudDogbnVtYmVyO1xuICB0b3RhbENvc3Q6IG51bWJlcjtcbn1cblxuLyoqXG4gKiBEZXRhaWxlZCBjb3N0IGJyZWFrZG93biBmb3IgYSB0ZW1wbGF0ZVxuICovXG5leHBvcnQgaW50ZXJmYWNlIENvc3RCcmVha2Rvd24ge1xuICBieVJlc291cmNlVHlwZTogUmVzb3VyY2VUeXBlQ29zdFtdO1xuICBieUNvbmZpZGVuY2VMZXZlbDogQ29uZmlkZW5jZUxldmVsQ29zdFtdO1xuICBhc3N1bXB0aW9uczogc3RyaW5nW107XG59XG5cbi8qKlxuICogRW5oYW5jZWQgcmVzb3VyY2UgY29zdCB3aXRoIGFkZGl0aW9uYWwgbWV0YWRhdGFcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBFbmhhbmNlZFJlc291cmNlQ29zdCBleHRlbmRzIFJlc291cmNlQ29zdCB7XG4gIHByb3BlcnRpZXM/OiBSZWNvcmQ8c3RyaW5nLCBhbnk+O1xuICByZWdpb246IHN0cmluZztcbiAgY2FsY3VsYXRlZEF0OiBEYXRlO1xufVxuXG4vKipcbiAqIFJlc3VsdCBvZiBzaW5nbGUgdGVtcGxhdGUgY29zdCBhbmFseXNpc1xuICovXG5leHBvcnQgaW50ZXJmYWNlIFNpbmdsZVRlbXBsYXRlQ29zdFJlc3VsdCB7XG4gIHRvdGFsTW9udGhseUNvc3Q6IG51bWJlcjtcbiAgY3VycmVuY3k6IHN0cmluZztcbiAgcmVzb3VyY2VDb3N0czogRW5oYW5jZWRSZXNvdXJjZUNvc3RbXTtcbiAgY29zdEJyZWFrZG93bjogQ29zdEJyZWFrZG93bjtcbiAgc3VtbWFyeTogc3RyaW5nO1xuICBtZXRhZGF0YTogQW5hbHlzaXNNZXRhZGF0YTtcbn1cblxuLyoqXG4gKiBPcHRpb25zIGZvciBhbmFseXppbmcgYSBzaW5nbGUgdGVtcGxhdGVcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBBbmFseXplU2luZ2xlVGVtcGxhdGVPcHRpb25zIHtcbiAgdGVtcGxhdGU6IHN0cmluZztcbiAgcmVnaW9uPzogc3RyaW5nO1xuICBmb3JtYXQ/OiAndGV4dCcgfCAnanNvbicgfCAnbWFya2Rvd24nO1xuICBjb25maWc/OiBBbmFseXNpc0NvbmZpZztcbn1cblxuLyoqXG4gKiBPcHRpb25zIGZvciBnZW5lcmF0aW5nIHNpbmdsZSB0ZW1wbGF0ZSByZXBvcnRzXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU2luZ2xlVGVtcGxhdGVSZXBvcnRPcHRpb25zIHtcbiAgc2hvd0JyZWFrZG93bj86IGJvb2xlYW47XG4gIHNob3dBc3N1bXB0aW9ucz86IGJvb2xlYW47XG4gIGdyb3VwQnlUeXBlPzogYm9vbGVhbjtcbiAgc29ydEJ5PzogJ2Nvc3QnIHwgJ25hbWUnIHwgJ3R5cGUnO1xufVxuIl19
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2luZ2xlLXRlbXBsYXRlLXR5cGVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FwaS9zaW5nbGUtdGVtcGxhdGUtdHlwZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFJlc291cmNlQ29zdCB9IGZyb20gJy4uL3ByaWNpbmcvdHlwZXMnO1xuaW1wb3J0IHsgVXNhZ2VBc3N1bXB0aW9uc0NvbmZpZywgQ2FjaGVDb25maWcgfSBmcm9tICcuLi9jb25maWcvdHlwZXMnO1xuaW1wb3J0IHsgT3B0aW1pemF0aW9uUmVzdWx0IH0gZnJvbSAnLi4vb3B0aW1pemF0aW9uL3R5cGVzJztcblxuLyoqXG4gKiBDb25maWd1cmF0aW9uIG9wdGlvbnMgZm9yIHNpbmdsZSB0ZW1wbGF0ZSBhbmFseXNpc1xuICovXG5leHBvcnQgaW50ZXJmYWNlIEFuYWx5c2lzQ29uZmlnIHtcbiAgdXNhZ2VBc3N1bXB0aW9ucz86IFVzYWdlQXNzdW1wdGlvbnNDb25maWc7XG4gIGV4Y2x1ZGVkUmVzb3VyY2VUeXBlcz86IHN0cmluZ1tdO1xuICBjYWNoZUNvbmZpZz86IENhY2hlQ29uZmlnO1xuICByZWNvbW1lbmRhdGlvbnM/OiBib29sZWFuO1xuICBtaW5pbXVtU2F2aW5nc1RocmVzaG9sZD86IG51bWJlcjtcbn1cblxuLyoqXG4gKiBNZXRhZGF0YSBhYm91dCB0aGUgYW5hbHlzaXNcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBBbmFseXNpc01ldGFkYXRhIHtcbiAgdGVtcGxhdGVIYXNoOiBzdHJpbmc7XG4gIHJlZ2lvbjogc3RyaW5nO1xuICBhbmFseXplZEF0OiBEYXRlO1xuICByZXNvdXJjZUNvdW50OiBudW1iZXI7XG4gIHN1cHBvcnRlZFJlc291cmNlQ291bnQ6IG51bWJlcjtcbiAgdW5zdXBwb3J0ZWRSZXNvdXJjZUNvdW50OiBudW1iZXI7XG59XG5cbi8qKlxuICogQ29zdCBpbmZvcm1hdGlvbiBncm91cGVkIGJ5IHJlc291cmNlIHR5cGVcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBSZXNvdXJjZVR5cGVDb3N0IHtcbiAgcmVzb3VyY2VUeXBlOiBzdHJpbmc7XG4gIGNvdW50OiBudW1iZXI7XG4gIHRvdGFsQ29zdDogbnVtYmVyO1xuICByZXNvdXJjZXM6IFJlc291cmNlQ29zdFtdO1xufVxuXG4vKipcbiAqIENvc3QgaW5mb3JtYXRpb24gZ3JvdXBlZCBieSBjb25maWRlbmNlIGxldmVsXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ29uZmlkZW5jZUxldmVsQ29zdCB7XG4gIGNvbmZpZGVuY2U6ICdoaWdoJyB8ICdtZWRpdW0nIHwgJ2xvdycgfCAndW5rbm93bic7XG4gIGNvdW50OiBudW1iZXI7XG4gIHRvdGFsQ29zdDogbnVtYmVyO1xufVxuXG4vKipcbiAqIERldGFpbGVkIGNvc3QgYnJlYWtkb3duIGZvciBhIHRlbXBsYXRlXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ29zdEJyZWFrZG93biB7XG4gIGJ5UmVzb3VyY2VUeXBlOiBSZXNvdXJjZVR5cGVDb3N0W107XG4gIGJ5Q29uZmlkZW5jZUxldmVsOiBDb25maWRlbmNlTGV2ZWxDb3N0W107XG4gIGFzc3VtcHRpb25zOiBzdHJpbmdbXTtcbn1cblxuLyoqXG4gKiBFbmhhbmNlZCByZXNvdXJjZSBjb3N0IHdpdGggYWRkaXRpb25hbCBtZXRhZGF0YVxuICovXG5leHBvcnQgaW50ZXJmYWNlIEVuaGFuY2VkUmVzb3VyY2VDb3N0IGV4dGVuZHMgUmVzb3VyY2VDb3N0IHtcbiAgcHJvcGVydGllcz86IFJlY29yZDxzdHJpbmcsIGFueT47XG4gIHJlZ2lvbjogc3RyaW5nO1xuICBjYWxjdWxhdGVkQXQ6IERhdGU7XG59XG5cbi8qKlxuICogUmVzdWx0IG9mIHNpbmdsZSB0ZW1wbGF0ZSBjb3N0IGFuYWx5c2lzXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU2luZ2xlVGVtcGxhdGVDb3N0UmVzdWx0IHtcbiAgdG90YWxNb250aGx5Q29zdDogbnVtYmVyO1xuICBjdXJyZW5jeTogc3RyaW5nO1xuICByZXNvdXJjZUNvc3RzOiBFbmhhbmNlZFJlc291cmNlQ29zdFtdO1xuICBjb3N0QnJlYWtkb3duOiBDb3N0QnJlYWtkb3duO1xuICBzdW1tYXJ5OiBzdHJpbmc7XG4gIG1ldGFkYXRhOiBBbmFseXNpc01ldGFkYXRhO1xuICByZWNvbW1lbmRhdGlvbnM/OiBPcHRpbWl6YXRpb25SZXN1bHQ7XG59XG5cbi8qKlxuICogT3B0aW9ucyBmb3IgYW5hbHl6aW5nIGEgc2luZ2xlIHRlbXBsYXRlXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQW5hbHl6ZVNpbmdsZVRlbXBsYXRlT3B0aW9ucyB7XG4gIHRlbXBsYXRlOiBzdHJpbmc7XG4gIHJlZ2lvbj86IHN0cmluZztcbiAgZm9ybWF0PzogJ3RleHQnIHwgJ2pzb24nIHwgJ21hcmtkb3duJztcbiAgY29uZmlnPzogQW5hbHlzaXNDb25maWc7XG59XG5cbi8qKlxuICogT3B0aW9ucyBmb3IgZ2VuZXJhdGluZyBzaW5nbGUgdGVtcGxhdGUgcmVwb3J0c1xuICovXG5leHBvcnQgaW50ZXJmYWNlIFNpbmdsZVRlbXBsYXRlUmVwb3J0T3B0aW9ucyB7XG4gIHNob3dCcmVha2Rvd24/OiBib29sZWFuO1xuICBzaG93QXNzdW1wdGlvbnM/OiBib29sZWFuO1xuICBncm91cEJ5VHlwZT86IGJvb2xlYW47XG4gIHNvcnRCeT86ICdjb3N0JyB8ICduYW1lJyB8ICd0eXBlJztcbn1cbiJdfQ==
@@ -1,9 +1,11 @@
1
1
  import { ResourceCost, ModifiedResourceCost } from '../pricing/types';
2
+ import { OptimizationResult } from '../optimization/types';
2
3
  export interface AnalyzeOptions {
3
4
  baseTemplate: string;
4
5
  targetTemplate: string;
5
6
  region?: string;
6
7
  format?: 'text' | 'json' | 'markdown';
8
+ recommendations?: boolean;
7
9
  }
8
10
  export interface CostAnalysisResult {
9
11
  totalDelta: number;
@@ -12,4 +14,5 @@ export interface CostAnalysisResult {
12
14
  removedResources: ResourceCost[];
13
15
  modifiedResources: ModifiedResourceCost[];
14
16
  summary: string;
17
+ recommendations?: OptimizationResult;
15
18
  }
package/dist/api/types.js CHANGED
@@ -1,3 +1,3 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXBpL3R5cGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBSZXNvdXJjZUNvc3QsIE1vZGlmaWVkUmVzb3VyY2VDb3N0IH0gZnJvbSAnLi4vcHJpY2luZy90eXBlcyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgQW5hbHl6ZU9wdGlvbnMge1xuICBiYXNlVGVtcGxhdGU6IHN0cmluZztcbiAgdGFyZ2V0VGVtcGxhdGU6IHN0cmluZztcbiAgcmVnaW9uPzogc3RyaW5nO1xuICBmb3JtYXQ/OiAndGV4dCcgfCAnanNvbicgfCAnbWFya2Rvd24nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIENvc3RBbmFseXNpc1Jlc3VsdCB7XG4gIHRvdGFsRGVsdGE6IG51bWJlcjtcbiAgY3VycmVuY3k6IHN0cmluZztcbiAgYWRkZWRSZXNvdXJjZXM6IFJlc291cmNlQ29zdFtdO1xuICByZW1vdmVkUmVzb3VyY2VzOiBSZXNvdXJjZUNvc3RbXTtcbiAgbW9kaWZpZWRSZXNvdXJjZXM6IE1vZGlmaWVkUmVzb3VyY2VDb3N0W107XG4gIHN1bW1hcnk6IHN0cmluZztcbn1cbiJdfQ==
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXBpL3R5cGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBSZXNvdXJjZUNvc3QsIE1vZGlmaWVkUmVzb3VyY2VDb3N0IH0gZnJvbSAnLi4vcHJpY2luZy90eXBlcyc7XG5pbXBvcnQgeyBPcHRpbWl6YXRpb25SZXN1bHQgfSBmcm9tICcuLi9vcHRpbWl6YXRpb24vdHlwZXMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIEFuYWx5emVPcHRpb25zIHtcbiAgYmFzZVRlbXBsYXRlOiBzdHJpbmc7XG4gIHRhcmdldFRlbXBsYXRlOiBzdHJpbmc7XG4gIHJlZ2lvbj86IHN0cmluZztcbiAgZm9ybWF0PzogJ3RleHQnIHwgJ2pzb24nIHwgJ21hcmtkb3duJztcbiAgcmVjb21tZW5kYXRpb25zPzogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDb3N0QW5hbHlzaXNSZXN1bHQge1xuICB0b3RhbERlbHRhOiBudW1iZXI7XG4gIGN1cnJlbmN5OiBzdHJpbmc7XG4gIGFkZGVkUmVzb3VyY2VzOiBSZXNvdXJjZUNvc3RbXTtcbiAgcmVtb3ZlZFJlc291cmNlczogUmVzb3VyY2VDb3N0W107XG4gIG1vZGlmaWVkUmVzb3VyY2VzOiBNb2RpZmllZFJlc291cmNlQ29zdFtdO1xuICBzdW1tYXJ5OiBzdHJpbmc7XG4gIHJlY29tbWVuZGF0aW9ucz86IE9wdGltaXphdGlvblJlc3VsdDtcbn1cbiJdfQ==