@cdklabs/cdk-appmod-catalog-blueprints 1.0.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/.jsii +8644 -0
- package/LICENSE +202 -0
- package/README.md +212 -0
- package/lib/document-processing/agentic-document-processing.d.ts +16 -0
- package/lib/document-processing/agentic-document-processing.js +90 -0
- package/lib/document-processing/base-document-processing.d.ts +189 -0
- package/lib/document-processing/base-document-processing.js +509 -0
- package/lib/document-processing/bedrock-document-processing.d.ts +167 -0
- package/lib/document-processing/bedrock-document-processing.js +297 -0
- package/lib/document-processing/index.d.ts +3 -0
- package/lib/document-processing/index.js +20 -0
- package/lib/document-processing/resources/default-bedrock-invoke/index.py +63 -0
- package/lib/document-processing/resources/default-bedrock-invoke/requirements.txt +4 -0
- package/lib/document-processing/resources/default-doc-retrieval-lambda/index.mjs +92 -0
- package/lib/document-processing/resources/default-doc-retrieval-lambda/package.json +10 -0
- package/lib/document-processing/resources/default-error-handler/index.js +46 -0
- package/lib/document-processing/resources/default-error-handler/package.json +4 -0
- package/lib/document-processing/resources/default-image-processor/classifier.mjs +665 -0
- package/lib/document-processing/resources/default-image-processor/extractors.mjs +465 -0
- package/lib/document-processing/resources/default-image-processor/index.mjs +143 -0
- package/lib/document-processing/resources/default-image-processor/package-lock.json +12 -0
- package/lib/document-processing/resources/default-image-processor/package.json +4 -0
- package/lib/document-processing/resources/default-image-validator/index.mjs +76 -0
- package/lib/document-processing/resources/default-image-validator/package-lock.json +154 -0
- package/lib/document-processing/resources/default-image-validator/package.json +7 -0
- package/lib/document-processing/resources/default-pdf-processor/index.js +46 -0
- package/lib/document-processing/resources/default-pdf-validator/index.js +36 -0
- package/lib/document-processing/resources/default-sqs-consumer/index.py +111 -0
- package/lib/document-processing/resources/default-sqs-consumer/requirements.txt +4 -0
- package/lib/document-processing/resources/default-sqs-consumer/sample_payload.json +20 -0
- package/lib/document-processing/resources/default-sqs-consumer/sample_payload_multi.json +24 -0
- package/lib/document-processing/resources/default-strands-agent/index.py +111 -0
- package/lib/document-processing/resources/default-strands-agent/requirements.txt +6 -0
- package/lib/document-processing/tests/agentic-document-processing-nag.test.d.ts +1 -0
- package/lib/document-processing/tests/agentic-document-processing-nag.test.js +107 -0
- package/lib/document-processing/tests/agentic-document-processing.test.d.ts +1 -0
- package/lib/document-processing/tests/agentic-document-processing.test.js +125 -0
- package/lib/document-processing/tests/bedrock-document-processing-nag.test.d.ts +1 -0
- package/lib/document-processing/tests/bedrock-document-processing-nag.test.js +101 -0
- package/lib/document-processing/tests/bedrock-document-processing.test.d.ts +1 -0
- package/lib/document-processing/tests/bedrock-document-processing.test.js +79 -0
- package/lib/framework/custom-resource/default-runtimes.d.ts +21 -0
- package/lib/framework/custom-resource/default-runtimes.js +34 -0
- package/lib/framework/custom-resource/index.d.ts +1 -0
- package/lib/framework/custom-resource/index.js +18 -0
- package/lib/framework/foundation/access-log.d.ts +69 -0
- package/lib/framework/foundation/access-log.js +121 -0
- package/lib/framework/foundation/eventbridge-broker.d.ts +18 -0
- package/lib/framework/foundation/eventbridge-broker.js +42 -0
- package/lib/framework/foundation/index.d.ts +3 -0
- package/lib/framework/foundation/index.js +20 -0
- package/lib/framework/foundation/network.d.ts +19 -0
- package/lib/framework/foundation/network.js +83 -0
- package/lib/framework/index.d.ts +2 -0
- package/lib/framework/index.js +19 -0
- package/lib/framework/quickstart/base-quickstart.d.ts +30 -0
- package/lib/framework/quickstart/base-quickstart.js +30 -0
- package/lib/index.d.ts +4 -0
- package/lib/index.js +21 -0
- package/lib/tsconfig.tsbuildinfo +1 -0
- package/lib/utilities/cdk-nag-config.d.ts +42 -0
- package/lib/utilities/cdk-nag-config.js +194 -0
- package/lib/utilities/data-loader-lambda/index.py +282 -0
- package/lib/utilities/data-loader-lambda/requirements.txt +3 -0
- package/lib/utilities/data-loader.d.ts +173 -0
- package/lib/utilities/data-loader.js +447 -0
- package/lib/utilities/index.d.ts +3 -0
- package/lib/utilities/index.js +20 -0
- package/lib/utilities/lambda-iam-utils.d.ts +145 -0
- package/lib/utilities/lambda-iam-utils.js +235 -0
- package/lib/utilities/lambda_layers/data-masking/layer-construct.d.ts +42 -0
- package/lib/utilities/lambda_layers/data-masking/layer-construct.js +53 -0
- package/lib/utilities/lambda_layers/data-masking/layer-construct.ts +88 -0
- package/lib/utilities/observability/bedrock-observability.d.ts +18 -0
- package/lib/utilities/observability/bedrock-observability.js +131 -0
- package/lib/utilities/observability/cloudfront-distribution-observability-property-injector.d.ts +6 -0
- package/lib/utilities/observability/cloudfront-distribution-observability-property-injector.js +22 -0
- package/lib/utilities/observability/index.d.ts +6 -0
- package/lib/utilities/observability/index.js +25 -0
- package/lib/utilities/observability/lambda-observability-property-injector.d.ts +8 -0
- package/lib/utilities/observability/lambda-observability-property-injector.js +43 -0
- package/lib/utilities/observability/log-group-data-protection-props.d.ts +19 -0
- package/lib/utilities/observability/log-group-data-protection-props.js +5 -0
- package/lib/utilities/observability/observability.d.ts +83 -0
- package/lib/utilities/observability/observability.js +278 -0
- package/lib/utilities/observability/observable.d.ts +32 -0
- package/lib/utilities/observability/observable.js +3 -0
- package/lib/utilities/observability/powertools-config.d.ts +3 -0
- package/lib/utilities/observability/powertools-config.js +25 -0
- package/lib/utilities/observability/resources/bedrock-manage-logging-configuration/index.py +27 -0
- package/lib/utilities/observability/state-machine-observability-property-injector.d.ts +8 -0
- package/lib/utilities/observability/state-machine-observability-property-injector.js +49 -0
- package/lib/utilities/tests/data-loader-nag.test.d.ts +1 -0
- package/lib/utilities/tests/data-loader-nag.test.js +432 -0
- package/lib/utilities/tests/data-loader.test.d.ts +1 -0
- package/lib/utilities/tests/data-loader.test.js +284 -0
- package/lib/webapp/frontend-construct.d.ts +136 -0
- package/lib/webapp/frontend-construct.js +253 -0
- package/lib/webapp/index.d.ts +1 -0
- package/lib/webapp/index.js +18 -0
- package/lib/webapp/tests/frontend-construct-nag.test.d.ts +1 -0
- package/lib/webapp/tests/frontend-construct-nag.test.js +266 -0
- package/lib/webapp/tests/frontend-construct.test.d.ts +1 -0
- package/lib/webapp/tests/frontend-construct.test.js +385 -0
- package/package.json +183 -0
|
@@ -0,0 +1,447 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var _a;
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.DataLoader = exports.FileType = exports.DatabaseEngine = void 0;
|
|
5
|
+
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
|
|
6
|
+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
7
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
8
|
+
const path = require("path");
|
|
9
|
+
const aws_lambda_python_alpha_1 = require("@aws-cdk/aws-lambda-python-alpha");
|
|
10
|
+
const aws_cdk_lib_1 = require("aws-cdk-lib");
|
|
11
|
+
const aws_ec2_1 = require("aws-cdk-lib/aws-ec2");
|
|
12
|
+
const aws_iam_1 = require("aws-cdk-lib/aws-iam");
|
|
13
|
+
const aws_lambda_1 = require("aws-cdk-lib/aws-lambda");
|
|
14
|
+
const aws_s3_1 = require("aws-cdk-lib/aws-s3");
|
|
15
|
+
const aws_s3_deployment_1 = require("aws-cdk-lib/aws-s3-deployment");
|
|
16
|
+
const aws_stepfunctions_1 = require("aws-cdk-lib/aws-stepfunctions");
|
|
17
|
+
const aws_stepfunctions_tasks_1 = require("aws-cdk-lib/aws-stepfunctions-tasks");
|
|
18
|
+
const custom_resources_1 = require("aws-cdk-lib/custom-resources");
|
|
19
|
+
const constructs_1 = require("constructs");
|
|
20
|
+
/**
|
|
21
|
+
* Supported database engines
|
|
22
|
+
*/
|
|
23
|
+
var DatabaseEngine;
|
|
24
|
+
(function (DatabaseEngine) {
|
|
25
|
+
DatabaseEngine["MYSQL"] = "mysql";
|
|
26
|
+
DatabaseEngine["POSTGRESQL"] = "postgresql";
|
|
27
|
+
})(DatabaseEngine || (exports.DatabaseEngine = DatabaseEngine = {}));
|
|
28
|
+
/**
|
|
29
|
+
* Supported file types for data loading
|
|
30
|
+
*/
|
|
31
|
+
var FileType;
|
|
32
|
+
(function (FileType) {
|
|
33
|
+
/** Standard SQL file */
|
|
34
|
+
FileType["SQL"] = "sql";
|
|
35
|
+
/** MySQL dump file generated by mysqldump */
|
|
36
|
+
FileType["MYSQLDUMP"] = "mysqldump";
|
|
37
|
+
/** PostgreSQL dump file generated by pg_dump */
|
|
38
|
+
FileType["PGDUMP"] = "pgdump";
|
|
39
|
+
})(FileType || (exports.FileType = FileType = {}));
|
|
40
|
+
/**
|
|
41
|
+
* DataLoader construct for loading data into Aurora/RDS databases
|
|
42
|
+
*
|
|
43
|
+
* This construct provides a simplified solution for loading data from various file formats
|
|
44
|
+
* (SQL, mysqldump, pg_dump) into MySQL or PostgreSQL databases. It uses S3 for file storage,
|
|
45
|
+
* Step Functions for orchestration, and Lambda for processing.
|
|
46
|
+
*
|
|
47
|
+
* Architecture:
|
|
48
|
+
* 1. Files are uploaded to S3 bucket
|
|
49
|
+
* 2. Step Function is triggered with list of S3 keys
|
|
50
|
+
* 3. Step Function iterates over files in execution order
|
|
51
|
+
* 4. Lambda function processes each file against the database
|
|
52
|
+
*
|
|
53
|
+
* Example usage:
|
|
54
|
+
* Create a DataLoader with database configuration and file inputs.
|
|
55
|
+
* The construct will handle uploading files to S3, creating a Step Function
|
|
56
|
+
* to orchestrate processing, and executing the data loading pipeline.
|
|
57
|
+
*/
|
|
58
|
+
class DataLoader extends constructs_1.Construct {
|
|
59
|
+
constructor(scope, id, props) {
|
|
60
|
+
super(scope, id);
|
|
61
|
+
// Store file inputs for later use
|
|
62
|
+
this.fileInputs = props.fileInputs;
|
|
63
|
+
// Validate props
|
|
64
|
+
this._validateProps(props);
|
|
65
|
+
// Get removal policy with default
|
|
66
|
+
const removalPolicy = props.removalPolicy || aws_cdk_lib_1.RemovalPolicy.DESTROY;
|
|
67
|
+
// Create S3 bucket for storing files
|
|
68
|
+
this.bucket = this._createBucket(removalPolicy);
|
|
69
|
+
// Create Lambda function for processing
|
|
70
|
+
this.processorFunction = this._createProcessorFunction(props);
|
|
71
|
+
// Create Step Functions state machine
|
|
72
|
+
this.stateMachine = this._createStateMachine();
|
|
73
|
+
// Create custom resource provider for triggering execution
|
|
74
|
+
this.customResourceProvider = this._createCustomResourceProvider();
|
|
75
|
+
// Upload files to S3
|
|
76
|
+
this._setupFileProcessing(props);
|
|
77
|
+
// Create custom resource to trigger execution after files are uploaded
|
|
78
|
+
this.executionTrigger = this._createExecutionTrigger();
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Grants additional IAM permissions to the execution trigger Lambda function
|
|
82
|
+
* @param statement The IAM policy statement to add
|
|
83
|
+
*/
|
|
84
|
+
grantExecutionTriggerPermissions(statement) {
|
|
85
|
+
// Get the Lambda function from the custom resource provider
|
|
86
|
+
const triggerFunction = this.customResourceProvider.onEventHandler;
|
|
87
|
+
if (triggerFunction) {
|
|
88
|
+
triggerFunction.addToRolePolicy(statement);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Validates the construct properties
|
|
93
|
+
* @param props The DataLoader properties
|
|
94
|
+
* @private
|
|
95
|
+
*/
|
|
96
|
+
_validateProps(props) {
|
|
97
|
+
if (!props.databaseConfig) {
|
|
98
|
+
throw new Error('databaseConfig is required');
|
|
99
|
+
}
|
|
100
|
+
if (!props.databaseConfig.cluster && !props.databaseConfig.instance) {
|
|
101
|
+
throw new Error('Either cluster or instance must be provided in databaseConfig');
|
|
102
|
+
}
|
|
103
|
+
if (!props.fileInputs || props.fileInputs.length === 0) {
|
|
104
|
+
throw new Error('At least one file input is required');
|
|
105
|
+
}
|
|
106
|
+
// Validate file inputs
|
|
107
|
+
for (const fileInput of props.fileInputs) {
|
|
108
|
+
if (!fileInput.filePath) {
|
|
109
|
+
throw new Error('filePath is required for each file input');
|
|
110
|
+
}
|
|
111
|
+
if (!fileInput.fileType) {
|
|
112
|
+
throw new Error('fileType is required for each file input');
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
// Validate engine compatibility
|
|
116
|
+
for (const fileInput of props.fileInputs) {
|
|
117
|
+
if (props.databaseConfig.engine === DatabaseEngine.MYSQL &&
|
|
118
|
+
fileInput.fileType === FileType.PGDUMP) {
|
|
119
|
+
throw new Error('PostgreSQL dump files cannot be used with MySQL databases');
|
|
120
|
+
}
|
|
121
|
+
if (props.databaseConfig.engine === DatabaseEngine.POSTGRESQL &&
|
|
122
|
+
fileInput.fileType === FileType.MYSQLDUMP) {
|
|
123
|
+
throw new Error('MySQL dump files cannot be used with PostgreSQL databases');
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Creates the S3 bucket for storing files
|
|
129
|
+
* @param removalPolicy The removal policy to apply
|
|
130
|
+
* @returns The created S3 bucket
|
|
131
|
+
* @private
|
|
132
|
+
*/
|
|
133
|
+
_createBucket(removalPolicy) {
|
|
134
|
+
const bucket = new aws_s3_1.Bucket(this, 'DataLoaderBucket', {
|
|
135
|
+
encryption: aws_s3_1.BucketEncryption.S3_MANAGED,
|
|
136
|
+
blockPublicAccess: aws_s3_1.BlockPublicAccess.BLOCK_ALL,
|
|
137
|
+
removalPolicy: removalPolicy,
|
|
138
|
+
autoDeleteObjects: removalPolicy === aws_cdk_lib_1.RemovalPolicy.DESTROY,
|
|
139
|
+
});
|
|
140
|
+
return bucket;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Creates the Lambda function for processing data loading
|
|
144
|
+
* @param props The DataLoader properties
|
|
145
|
+
* @returns The created Lambda function
|
|
146
|
+
* @private
|
|
147
|
+
*/
|
|
148
|
+
_createProcessorFunction(props) {
|
|
149
|
+
// Create a dedicated security group for the Lambda function
|
|
150
|
+
const lambdaSecurityGroup = new aws_ec2_1.SecurityGroup(this, 'DataLoaderProcessorSecurityGroup', {
|
|
151
|
+
vpc: props.databaseConfig.vpc,
|
|
152
|
+
description: 'Security group for DataLoader processor Lambda function',
|
|
153
|
+
allowAllOutbound: true, // Lambda needs outbound access for AWS services and internet
|
|
154
|
+
});
|
|
155
|
+
// Allow Lambda to connect to the database
|
|
156
|
+
// Add ingress rule to database security group to allow connections from Lambda
|
|
157
|
+
props.databaseConfig.securityGroup.addIngressRule(lambdaSecurityGroup, aws_ec2_1.Port.tcp(props.databaseConfig.engine === DatabaseEngine.MYSQL ? 3306 : 5432), `Allow DataLoader Lambda to connect to ${props.databaseConfig.engine} database`);
|
|
158
|
+
// Create Lambda function with automatic dependency bundling
|
|
159
|
+
const lambdaFunction = new aws_lambda_python_alpha_1.PythonFunction(this, 'DataLoaderProcessor', {
|
|
160
|
+
entry: path.join(__dirname, 'data-loader-lambda'),
|
|
161
|
+
runtime: aws_lambda_1.Runtime.PYTHON_3_13,
|
|
162
|
+
handler: 'handler',
|
|
163
|
+
index: 'index.py',
|
|
164
|
+
timeout: props.timeout || aws_cdk_lib_1.Duration.minutes(15),
|
|
165
|
+
memorySize: props.memorySize || 1024,
|
|
166
|
+
architecture: aws_lambda_1.Architecture.ARM_64,
|
|
167
|
+
vpc: props.databaseConfig.vpc,
|
|
168
|
+
securityGroups: [lambdaSecurityGroup], // Use the dedicated Lambda security group
|
|
169
|
+
environment: {
|
|
170
|
+
DATABASE_ENGINE: props.databaseConfig.engine,
|
|
171
|
+
DATABASE_SECRET_ARN: props.databaseConfig.secret.secretArn,
|
|
172
|
+
DATABASE_NAME: props.databaseConfig.databaseName,
|
|
173
|
+
S3_BUCKET: this.bucket.bucketName,
|
|
174
|
+
},
|
|
175
|
+
bundling: {
|
|
176
|
+
// Use custom bundling commands to avoid Poetry conflicts
|
|
177
|
+
command: [
|
|
178
|
+
'bash', '-c', [
|
|
179
|
+
// Create a clean virtual environment
|
|
180
|
+
'python -m venv /tmp/venv',
|
|
181
|
+
// Activate the virtual environment
|
|
182
|
+
'source /tmp/venv/bin/activate',
|
|
183
|
+
// Install dependencies in the virtual environment
|
|
184
|
+
'pip install --upgrade pip',
|
|
185
|
+
'pip install -r requirements.txt -t /asset-output',
|
|
186
|
+
// Copy source files
|
|
187
|
+
'cp -r . /asset-output',
|
|
188
|
+
// Clean up __pycache__ and other unnecessary files
|
|
189
|
+
'find /asset-output -type d -name __pycache__ -exec rm -rf {} + || true',
|
|
190
|
+
'find /asset-output -name "*.pyc" -delete || true',
|
|
191
|
+
].join(' && '),
|
|
192
|
+
],
|
|
193
|
+
// Use the standard Python image to avoid pre-installed packages
|
|
194
|
+
image: aws_cdk_lib_1.DockerImage.fromRegistry('public.ecr.aws/docker/library/python:3.13.5-bullseye'),
|
|
195
|
+
},
|
|
196
|
+
});
|
|
197
|
+
// Grant permissions
|
|
198
|
+
this._grantPermissions(lambdaFunction, props);
|
|
199
|
+
return lambdaFunction;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Creates the Step Functions state machine
|
|
203
|
+
* @returns The created state machine
|
|
204
|
+
* @private
|
|
205
|
+
*/
|
|
206
|
+
_createStateMachine() {
|
|
207
|
+
// Create a Map state to iterate over file keys
|
|
208
|
+
const processFileTask = new aws_stepfunctions_tasks_1.LambdaInvoke(this, 'ProcessFileTask', {
|
|
209
|
+
lambdaFunction: this.processorFunction,
|
|
210
|
+
payload: aws_stepfunctions_1.TaskInput.fromObject({
|
|
211
|
+
's3Key.$': '$',
|
|
212
|
+
'bucketName': this.bucket.bucketName,
|
|
213
|
+
}),
|
|
214
|
+
});
|
|
215
|
+
// Create the state machine definition
|
|
216
|
+
const definition = new aws_stepfunctions_1.Map(this, 'ProcessFilesMap', {
|
|
217
|
+
itemsPath: '$.fileKeys',
|
|
218
|
+
maxConcurrency: 1, // Process files sequentially to maintain order
|
|
219
|
+
}).itemProcessor(processFileTask);
|
|
220
|
+
// Create the state machine
|
|
221
|
+
const stateMachine = new aws_stepfunctions_1.StateMachine(this, 'DataLoaderStateMachine', {
|
|
222
|
+
definitionBody: aws_stepfunctions_1.DefinitionBody.fromChainable(definition),
|
|
223
|
+
timeout: aws_cdk_lib_1.Duration.hours(2), // Allow up to 2 hours for the entire process
|
|
224
|
+
});
|
|
225
|
+
// Grant the state machine permission to invoke the Lambda function
|
|
226
|
+
this.processorFunction.grantInvoke(stateMachine);
|
|
227
|
+
return stateMachine;
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Grants necessary permissions to the Lambda function
|
|
231
|
+
* @param lambdaFunction The Lambda function
|
|
232
|
+
* @param props The DataLoader properties
|
|
233
|
+
* @private
|
|
234
|
+
*/
|
|
235
|
+
_grantPermissions(lambdaFunction, props) {
|
|
236
|
+
// Grant S3 permissions
|
|
237
|
+
this.bucket.grantRead(lambdaFunction);
|
|
238
|
+
// Grant Secrets Manager permissions
|
|
239
|
+
props.databaseConfig.secret.grantRead(lambdaFunction);
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Sets up file processing by uploading files to S3
|
|
243
|
+
* @param props The DataLoader properties
|
|
244
|
+
* @private
|
|
245
|
+
*/
|
|
246
|
+
_setupFileProcessing(props) {
|
|
247
|
+
// Separate local files from S3 URIs
|
|
248
|
+
const localFiles = props.fileInputs.filter(f => !f.filePath.startsWith('s3://'));
|
|
249
|
+
// Upload local files to S3 if any
|
|
250
|
+
if (localFiles.length > 0) {
|
|
251
|
+
// Process each file individually to handle both files and directories
|
|
252
|
+
localFiles.forEach((fileInput, index) => {
|
|
253
|
+
const filePath = fileInput.filePath;
|
|
254
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
255
|
+
const fs = require('fs');
|
|
256
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
257
|
+
const pathModule = require('path');
|
|
258
|
+
let resolvedPath;
|
|
259
|
+
if (pathModule.isAbsolute(filePath)) {
|
|
260
|
+
resolvedPath = filePath;
|
|
261
|
+
}
|
|
262
|
+
else {
|
|
263
|
+
// Resolve relative paths from the current working directory
|
|
264
|
+
resolvedPath = pathModule.resolve(filePath);
|
|
265
|
+
}
|
|
266
|
+
// Check if the path exists
|
|
267
|
+
if (!fs.existsSync(resolvedPath)) {
|
|
268
|
+
throw new Error(`File not found: ${resolvedPath}`);
|
|
269
|
+
}
|
|
270
|
+
if (fs.statSync(resolvedPath).isFile()) {
|
|
271
|
+
// For individual files, deploy from parent directory with include filter
|
|
272
|
+
const parentDir = pathModule.dirname(resolvedPath);
|
|
273
|
+
const fileName = pathModule.basename(resolvedPath);
|
|
274
|
+
new aws_s3_deployment_1.BucketDeployment(this, `DataLoaderFileDeployment${index}`, {
|
|
275
|
+
sources: [aws_s3_deployment_1.Source.asset(parentDir)],
|
|
276
|
+
destinationBucket: this.bucket,
|
|
277
|
+
destinationKeyPrefix: 'data-files/',
|
|
278
|
+
include: [fileName],
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
else {
|
|
282
|
+
// For directories, deploy entire directory
|
|
283
|
+
new aws_s3_deployment_1.BucketDeployment(this, `DataLoaderFileDeployment${index}`, {
|
|
284
|
+
sources: [aws_s3_deployment_1.Source.asset(resolvedPath)],
|
|
285
|
+
destinationBucket: this.bucket,
|
|
286
|
+
destinationKeyPrefix: 'data-files/',
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Creates a custom resource provider for triggering state machine execution
|
|
294
|
+
* @returns The custom resource provider
|
|
295
|
+
* @private
|
|
296
|
+
*/
|
|
297
|
+
_createCustomResourceProvider() {
|
|
298
|
+
// Create IAM role for the custom resource Lambda function with all necessary policies
|
|
299
|
+
const customResourceRole = new aws_iam_1.Role(this, 'StateMachineExecutionTriggerRole', {
|
|
300
|
+
assumedBy: new aws_iam_1.ServicePrincipal('lambda.amazonaws.com'),
|
|
301
|
+
description: 'IAM role for DataLoader custom resource Lambda function',
|
|
302
|
+
managedPolicies: [
|
|
303
|
+
aws_iam_1.ManagedPolicy.fromAwsManagedPolicyName('service-role/AWSLambdaBasicExecutionRole'),
|
|
304
|
+
],
|
|
305
|
+
inlinePolicies: {
|
|
306
|
+
StateMachineExecutionPolicy: new aws_iam_1.PolicyDocument({
|
|
307
|
+
statements: [
|
|
308
|
+
new aws_iam_1.PolicyStatement({
|
|
309
|
+
effect: aws_iam_1.Effect.ALLOW,
|
|
310
|
+
actions: [
|
|
311
|
+
'states:StartExecution',
|
|
312
|
+
'states:DescribeExecution',
|
|
313
|
+
'states:StopExecution',
|
|
314
|
+
],
|
|
315
|
+
resources: [
|
|
316
|
+
this.stateMachine.stateMachineArn,
|
|
317
|
+
`${this.stateMachine.stateMachineArn}:*`, // For execution ARNs
|
|
318
|
+
],
|
|
319
|
+
}),
|
|
320
|
+
],
|
|
321
|
+
}),
|
|
322
|
+
},
|
|
323
|
+
});
|
|
324
|
+
// Create Lambda function for custom resource with the pre-configured role
|
|
325
|
+
const customResourceFunction = new aws_lambda_1.Function(this, 'StateMachineExecutionTrigger', {
|
|
326
|
+
runtime: aws_lambda_1.Runtime.PYTHON_3_11,
|
|
327
|
+
handler: 'index.handler',
|
|
328
|
+
role: customResourceRole, // Attach the role during creation
|
|
329
|
+
code: aws_lambda_1.Code.fromInline(`
|
|
330
|
+
import json
|
|
331
|
+
import boto3
|
|
332
|
+
import logging
|
|
333
|
+
|
|
334
|
+
logger = logging.getLogger()
|
|
335
|
+
logger.setLevel(logging.INFO)
|
|
336
|
+
|
|
337
|
+
stepfunctions = boto3.client('stepfunctions')
|
|
338
|
+
|
|
339
|
+
def handler(event, context):
|
|
340
|
+
logger.info(f"Received event: {json.dumps(event)}")
|
|
341
|
+
|
|
342
|
+
request_type = event['RequestType']
|
|
343
|
+
|
|
344
|
+
if request_type == 'Create' or request_type == 'Update':
|
|
345
|
+
try:
|
|
346
|
+
# Get parameters from event
|
|
347
|
+
state_machine_arn = event['ResourceProperties']['StateMachineArn']
|
|
348
|
+
file_keys = event['ResourceProperties']['FileKeys']
|
|
349
|
+
|
|
350
|
+
# Start execution
|
|
351
|
+
response = stepfunctions.start_execution(
|
|
352
|
+
stateMachineArn=state_machine_arn,
|
|
353
|
+
input=json.dumps({
|
|
354
|
+
'fileKeys': file_keys
|
|
355
|
+
})
|
|
356
|
+
)
|
|
357
|
+
|
|
358
|
+
execution_arn = response['executionArn']
|
|
359
|
+
logger.info(f"Started execution: {execution_arn}")
|
|
360
|
+
|
|
361
|
+
return {
|
|
362
|
+
'Status': 'SUCCESS',
|
|
363
|
+
'PhysicalResourceId': execution_arn,
|
|
364
|
+
'Data': {
|
|
365
|
+
'ExecutionArn': execution_arn
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
except Exception as e:
|
|
370
|
+
logger.error(f"Error starting execution: {str(e)}")
|
|
371
|
+
return {
|
|
372
|
+
'Status': 'FAILED',
|
|
373
|
+
'Reason': str(e),
|
|
374
|
+
'PhysicalResourceId': 'failed'
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
elif request_type == 'Delete':
|
|
378
|
+
# For delete, we don't need to do anything special
|
|
379
|
+
return {
|
|
380
|
+
'Status': 'SUCCESS',
|
|
381
|
+
'PhysicalResourceId': event.get('PhysicalResourceId', 'none')
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
return {
|
|
385
|
+
'Status': 'SUCCESS',
|
|
386
|
+
'PhysicalResourceId': 'none'
|
|
387
|
+
}
|
|
388
|
+
`),
|
|
389
|
+
timeout: aws_cdk_lib_1.Duration.minutes(5),
|
|
390
|
+
});
|
|
391
|
+
// Create provider with the Lambda function that already has the correct role
|
|
392
|
+
const provider = new custom_resources_1.Provider(this, 'StateMachineExecutionProvider', {
|
|
393
|
+
onEventHandler: customResourceFunction,
|
|
394
|
+
});
|
|
395
|
+
return provider;
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* Creates a custom resource to trigger state machine execution
|
|
399
|
+
* @returns The custom resource
|
|
400
|
+
* @private
|
|
401
|
+
*/
|
|
402
|
+
_createExecutionTrigger() {
|
|
403
|
+
// Get ordered file keys
|
|
404
|
+
const orderedFileKeys = this._getOrderedFileKeys();
|
|
405
|
+
const customResource = new aws_cdk_lib_1.CustomResource(this, 'ExecutionTriggerResource', {
|
|
406
|
+
serviceToken: this.customResourceProvider.serviceToken,
|
|
407
|
+
properties: {
|
|
408
|
+
StateMachineArn: this.stateMachine.stateMachineArn,
|
|
409
|
+
FileKeys: orderedFileKeys,
|
|
410
|
+
// Add a timestamp to force updates when needed
|
|
411
|
+
Timestamp: Date.now().toString(),
|
|
412
|
+
},
|
|
413
|
+
});
|
|
414
|
+
// Ensure the custom resource runs after bucket deployment (if exists)
|
|
415
|
+
if (this.bucketDeployment) {
|
|
416
|
+
customResource.node.addDependency(this.stateMachine);
|
|
417
|
+
customResource.node.addDependency(this.bucketDeployment);
|
|
418
|
+
}
|
|
419
|
+
return customResource;
|
|
420
|
+
}
|
|
421
|
+
/**
|
|
422
|
+
* Gets the ordered file keys for execution
|
|
423
|
+
* @returns Array of S3 keys in execution order
|
|
424
|
+
* @private
|
|
425
|
+
*/
|
|
426
|
+
_getOrderedFileKeys() {
|
|
427
|
+
// Sort files by execution order
|
|
428
|
+
const sortedFiles = [...this.fileInputs].sort((a, b) => (a.executionOrder || 0) - (b.executionOrder || 0));
|
|
429
|
+
// Convert file paths to S3 keys
|
|
430
|
+
return sortedFiles.map(file => {
|
|
431
|
+
if (file.filePath.startsWith('s3://')) {
|
|
432
|
+
// Extract key from S3 URI
|
|
433
|
+
const parts = file.filePath.replace('s3://', '').split('/');
|
|
434
|
+
return parts.slice(1).join('/'); // Remove bucket name
|
|
435
|
+
}
|
|
436
|
+
else {
|
|
437
|
+
// Local files are uploaded with data-files/ prefix
|
|
438
|
+
const fileName = path.basename(file.filePath);
|
|
439
|
+
return `data-files/${fileName}`;
|
|
440
|
+
}
|
|
441
|
+
});
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
exports.DataLoader = DataLoader;
|
|
445
|
+
_a = JSII_RTTI_SYMBOL_1;
|
|
446
|
+
DataLoader[_a] = { fqn: "@cdklabs/cdk-appmod-catalog-blueprints.DataLoader", version: "1.0.0" };
|
|
447
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0YS1sb2FkZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi91c2UtY2FzZXMvdXRpbGl0aWVzL2RhdGEtbG9hZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEscUVBQXFFO0FBQ3JFLHNDQUFzQztBQUV0Qyw2QkFBNkI7QUFDN0IsOEVBQWtFO0FBQ2xFLDZDQUFtRjtBQUNuRixpREFBZ0Y7QUFDaEYsaURBQXFIO0FBQ3JILHVEQUFpRztBQUVqRywrQ0FBaUY7QUFDakYscUVBQXlFO0FBRXpFLHFFQUE2RjtBQUM3RixpRkFBbUU7QUFDbkUsbUVBQXdEO0FBQ3hELDJDQUF1QztBQUV2Qzs7R0FFRztBQUNILElBQVksY0FHWDtBQUhELFdBQVksY0FBYztJQUN4QixpQ0FBZSxDQUFBO0lBQ2YsMkNBQXlCLENBQUE7QUFDM0IsQ0FBQyxFQUhXLGNBQWMsOEJBQWQsY0FBYyxRQUd6QjtBQUVEOztHQUVHO0FBQ0gsSUFBWSxRQU9YO0FBUEQsV0FBWSxRQUFRO0lBQ2xCLHdCQUF3QjtJQUN4Qix1QkFBVyxDQUFBO0lBQ1gsNkNBQTZDO0lBQzdDLG1DQUF1QixDQUFBO0lBQ3ZCLGdEQUFnRDtJQUNoRCw2QkFBaUIsQ0FBQTtBQUNuQixDQUFDLEVBUFcsUUFBUSx3QkFBUixRQUFRLFFBT25CO0FBb0REOzs7Ozs7Ozs7Ozs7Ozs7OztHQWlCRztBQUNILE1BQWEsVUFBVyxTQUFRLHNCQUFTO0lBZ0J2QyxZQUFZLEtBQWdCLEVBQUUsRUFBVSxFQUFFLEtBQXNCO1FBQzlELEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFFakIsa0NBQWtDO1FBQ2xDLElBQUksQ0FBQyxVQUFVLEdBQUcsS0FBSyxDQUFDLFVBQVUsQ0FBQztRQUVuQyxpQkFBaUI7UUFDakIsSUFBSSxDQUFDLGNBQWMsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUUzQixrQ0FBa0M7UUFDbEMsTUFBTSxhQUFhLEdBQUcsS0FBSyxDQUFDLGFBQWEsSUFB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QXFCO1lBQ3hELENBQUM7aUJBQU0sQ0FBQztnQkFDTixtREFBbUQ7Z0JBQ25ELE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO2dCQUM5QyxPQUFPLGNBQWMsUUFBUSxFQUFFLENBQUM7WUFDbEMsQ0FBQztRQUNILENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQzs7QUEvYkgsZ0NBZ2NDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IEFtYXpvbi5jb20sIEluYy4gb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuXG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IHsgUHl0aG9uRnVuY3Rpb24gfSBmcm9tICdAYXdzLWNkay9hd3MtbGFtYmRhLXB5dGhvbi1hbHBoYSc7XG5pbXBvcnQgeyBEdXJhdGlvbiwgUmVtb3ZhbFBvbGljeSwgQ3VzdG9tUmVzb3VyY2UsIERvY2tlckltYWdlIH0gZnJvbSAnYXdzLWNkay1saWInO1xuaW1wb3J0IHsgSVZwYywgU2VjdXJpdHlHcm91cCwgUG9ydCwgSVNlY3VyaXR5R3JvdXAgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtZWMyJztcbmltcG9ydCB7IFBvbGljeVN0YXRlbWVudCwgUm9sZSwgU2VydmljZVByaW5jaXBhbCwgTWFuYWdlZFBvbGljeSwgUG9saWN5RG9jdW1lbnQsIEVmZmVjdCB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1pYW0nO1xuaW1wb3J0IHsgQXJjaGl0ZWN0dXJlLCBDb2RlLCBGdW5jdGlvbiBhcyBMYW1iZGFGdW5jdGlvbiwgUnVudGltZSB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1sYW1iZGEnO1xuaW1wb3J0IHsgSURhdGFiYXNlQ2x1c3RlciwgSURhdGFiYXNlSW5zdGFuY2UgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtcmRzJztcbmltcG9ydCB7IEJ1Y2tldCwgQnVja2V0RW5jcnlwdGlvbiwgQmxvY2tQdWJsaWNBY2Nlc3MgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtczMnO1xuaW1wb3J0IHsgQnVja2V0RGVwbG95bWVudCwgU291cmNlIH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLXMzLWRlcGxveW1lbnQnO1xuaW1wb3J0IHsgSVNlY3JldCB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1zZWNyZXRzbWFuYWdlcic7XG5pbXBvcnQgeyBTdGF0ZU1hY2hpbmUsIERlZmluaXRpb25Cb2R5LCBNYXAsIFRhc2tJbnB1dCB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1zdGVwZnVuY3Rpb25zJztcbmltcG9ydCB7IExhbWJkYUludm9rZSB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1zdGVwZnVuY3Rpb25zLXRhc2tzJztcbmltcG9ydCB7IFByb3ZpZGVyIH0gZnJvbSAnYXdzLWNkay1saWIvY3VzdG9tLXJlc291cmNlcyc7XG5pbXBvcnQgeyBDb25zdHJ1Y3QgfSBmcm9tICdjb25zdHJ1Y3RzJztcblxuLyoqXG4gKiBTdXBwb3J0ZWQgZGF0YWJhc2UgZW5naW5lc1xuICovXG5leHBvcnQgZW51bSBEYXRhYmFzZUVuZ2luZSB7XG4gIE1ZU1FMID0gJ215c3FsJyxcbiAgUE9TVEdSRVNRTCA9ICdwb3N0Z3Jlc3FsJyxcbn1cblxuLyoqXG4gKiBTdXBwb3J0ZWQgZmlsZSB0eXBlcyBmb3IgZGF0YSBsb2FkaW5nXG4gKi9cbmV4cG9ydCBlbnVtIEZpbGVUeXBlIHtcbiAgLyoqIFN0YW5kYXJkIFNRTCBmaWxlICovXG4gIFNRTCA9ICdzcWwnLFxuICAvKiogTXlTUUwgZHVtcCBmaWxlIGdlbmVyYXRlZCBieSBteXNxbGR1bXAgKi9cbiAgTVlTUUxEVU1QID0gJ215c3FsZHVtcCcsXG4gIC8qKiBQb3N0Z3JlU1FMIGR1bXAgZmlsZSBnZW5lcmF0ZWQgYnkgcGdfZHVtcCAqL1xuICBQR0RVTVAgPSAncGdkdW1wJyxcbn1cblxuLyoqXG4gKiBEYXRhYmFzZSBjb25uZWN0aW9uIGNvbmZpZ3VyYXRpb25cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBEYXRhYmFzZUNvbmZpZyB7XG4gIC8qKiBEYXRhYmFzZSBlbmdpbmUgdHlwZSAqL1xuICByZWFkb25seSBlbmdpbmU6IERhdGFiYXNlRW5naW5lO1xuICAvKiogRGF0YWJhc2UgY2x1c3RlciAoZm9yIEF1cm9yYSkgKi9cbiAgcmVhZG9ubHkgY2x1c3Rlcj86IElEYXRhYmFzZUNsdXN0ZXI7XG4gIC8qKiBEYXRhYmFzZSBpbnN0YW5jZSAoZm9yIFJEUykgKi9cbiAgcmVhZG9ubHkgaW5zdGFuY2U/OiBJRGF0YWJhc2VJbnN0YW5jZTtcbiAgLyoqIERhdGFiYXNlIGNyZWRlbnRpYWxzIHNlY3JldCAqL1xuICByZWFkb25seSBzZWNyZXQ6IElTZWNyZXQ7XG4gIC8qKiBEYXRhYmFzZSBuYW1lIHRvIGNvbm5lY3QgdG8gKi9cbiAgcmVhZG9ubHkgZGF0YWJhc2VOYW1lOiBzdHJpbmc7XG4gIC8qKiBWUEMgd2hlcmUgdGhlIGRhdGFiYXNlIGlzIGxvY2F0ZWQgKi9cbiAgcmVhZG9ubHkgdnBjOiBJVnBjO1xuICAvKiogU2VjdXJpdHkgZ3JvdXAgZm9yIGRhdGFiYXNlIGFjY2VzcyAqL1xuICByZWFkb25seSBzZWN1cml0eUdyb3VwOiBJU2VjdXJpdHlHcm91cDtcbn1cblxuLyoqXG4gKiBGaWxlIGlucHV0IGNvbmZpZ3VyYXRpb25cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBGaWxlSW5wdXQge1xuICAvKiogUGF0aCB0byB0aGUgZmlsZSAobG9jYWwgcGF0aCBvciBTMyBVUkkpICovXG4gIHJlYWRvbmx5IGZpbGVQYXRoOiBzdHJpbmc7XG4gIC8qKiBUeXBlIG9mIGZpbGUgKi9cbiAgcmVhZG9ubHkgZmlsZVR5cGU6IEZpbGVUeXBlO1xuICAvKiogRXhlY3V0aW9uIG9yZGVyIChsb3dlciBudW1iZXJzIGV4ZWN1dGUgZmlyc3QpICovXG4gIHJlYWRvbmx5IGV4ZWN1dGlvbk9yZGVyPzogbnVtYmVyO1xuICAvKiogV2hldGhlciB0byBjb250aW51ZSBvbiBlcnJvciAqL1xuICByZWFkb25seSBjb250aW51ZU9uRXJyb3I/OiBib29sZWFuO1xufVxuXG4vKipcbiAqIFByb3BlcnRpZXMgZm9yIHRoZSBEYXRhTG9hZGVyIGNvbnN0cnVjdFxuICovXG5leHBvcnQgaW50ZXJmYWNlIERhdGFMb2FkZXJQcm9wcyB7XG4gIC8qKiBEYXRhYmFzZSBjb25maWd1cmF0aW9uICovXG4gIHJlYWRvbmx5IGRhdGFiYXNlQ29uZmlnOiBEYXRhYmFzZUNvbmZpZztcbiAgLyoqIExpc3Qgb2YgZmlsZXMgdG8gbG9hZCAqL1xuICByZWFkb25seSBmaWxlSW5wdXRzOiBGaWxlSW5wdXRbXTtcbiAgLyoqIE9wdGlvbmFsIHJlbW92YWwgcG9saWN5IGZvciByZXNvdXJjZXMgKGRlZmF1bHRzIHRvIERFU1RST1kpICovXG4gIHJlYWRvbmx5IHJlbW92YWxQb2xpY3k/OiBSZW1vdmFsUG9saWN5O1xuICAvKiogT3B0aW9uYWwgdGltZW91dCBmb3IgTGFtYmRhIGZ1bmN0aW9uIChkZWZhdWx0cyB0byAxNSBtaW51dGVzKSAqL1xuICByZWFkb25seSB0aW1lb3V0PzogRHVyYXRpb247XG4gIC8qKiBPcHRpb25hbCBtZW1vcnkgc2l6ZSBmb3IgTGFtYmRhIGZ1bmN0aW9uIChkZWZhdWx0cyB0byAxMDI0IE1CKSAqL1xuICByZWFkb25seSBtZW1vcnlTaXplPzogbnVtYmVyO1xufVxuXG4vKipcbiAqIERhdGFMb2FkZXIgY29uc3RydWN0IGZvciBsb2FkaW5nIGRhdGEgaW50byBBdXJvcmEvUkRTIGRhdGFiYXNlc1xuICpcbiAqIFRoaXMgY29uc3RydWN0IHByb3ZpZGVzIGEgc2ltcGxpZmllZCBzb2x1dGlvbiBmb3IgbG9hZGluZyBkYXRhIGZyb20gdmFyaW91cyBmaWxlIGZvcm1hdHNcbiAqIChTUUwsIG15c3FsZHVtcCwgcGdfZHVtcCkgaW50byBNeVNRTCBvciBQb3N0Z3JlU1FMIGRhdGFiYXNlcy4gSXQgdXNlcyBTMyBmb3IgZmlsZSBzdG9yYWdlLFxuICogU3RlcCBGdW5jdGlvbnMgZm9yIG9yY2hlc3RyYXRpb24sIGFuZCBMYW1iZGEgZm9yIHByb2Nlc3NpbmcuXG4gKlxuICogQXJjaGl0ZWN0dXJlOlxuICogMS4gRmlsZXMgYXJlIHVwbG9hZGVkIHRvIFMzIGJ1Y2tldFxuICogMi4gU3RlcCBGdW5jdGlvbiBpcyB0cmlnZ2VyZWQgd2l0aCBsaXN0IG9mIFMzIGtleXNcbiAqIDMuIFN0ZXAgRnVuY3Rpb24gaXRlcmF0ZXMgb3ZlciBmaWxlcyBpbiBleGVjdXRpb24gb3JkZXJcbiAqIDQuIExhbWJkYSBmdW5jdGlvbiBwcm9jZXNzZXMgZWFjaCBmaWxlIGFnYWluc3QgdGhlIGRhdGFiYXNlXG4gKlxuICogRXhhbXBsZSB1c2FnZTpcbiAqIENyZWF0ZSBhIERhdGFMb2FkZXIgd2l0aCBkYXRhYmFzZSBjb25maWd1cmF0aW9uIGFuZCBmaWxlIGlucHV0cy5cbiAqIFRoZSBjb25zdHJ1Y3Qgd2lsbCBoYW5kbGUgdXBsb2FkaW5nIGZpbGVzIHRvIFMzLCBjcmVhdGluZyBhIFN0ZXAgRnVuY3Rpb25cbiAqIHRvIG9yY2hlc3RyYXRlIHByb2Nlc3NpbmcsIGFuZCBleGVjdXRpbmcgdGhlIGRhdGEgbG9hZGluZyBwaXBlbGluZS5cbiAqL1xuZXhwb3J0IGNsYXNzIERhdGFMb2FkZXIgZXh0ZW5kcyBDb25zdHJ1Y3Qge1xuICAvKiogVGhlIFMzIGJ1Y2tldCB1c2VkIGZvciBzdG9yaW5nIGZpbGVzICovXG4gIHB1YmxpYyByZWFkb25seSBidWNrZXQ6IEJ1Y2tldDtcbiAgLyoqIFRoZSBTdGVwIEZ1bmN0aW9ucyBzdGF0ZSBtYWNoaW5lIGZvciBvcmNoZXN0cmF0aW9uICovXG4gIHB1YmxpYyByZWFkb25seSBzdGF0ZU1hY2hpbmU6IFN0YXRlTWFjaGluZTtcbiAgLyoqIFRoZSBMYW1iZGEgZnVuY3Rpb24gdGhhdCBwcm9jZXNzZXMgdGhlIGRhdGEgbG9hZGluZyAqL1xuICBwdWJsaWMgcmVhZG9ubHkgcHJvY2Vzc29yRnVuY3Rpb246IExhbWJkYUZ1bmN0aW9uO1xuICAvKiogVGhlIGJ1Y2tldCBkZXBsb3ltZW50IGZvciB1cGxvYWRpbmcgZmlsZXMgKi9cbiAgcHVibGljIGJ1Y2tldERlcGxveW1lbnQ/OiBCdWNrZXREZXBsb3ltZW50O1xuICAvKiogVGhlIGN1c3RvbSByZXNvdXJjZSBwcm92aWRlciBmb3IgdHJpZ2dlcmluZyBzdGF0ZSBtYWNoaW5lIGV4ZWN1dGlvbiAqL1xuICBwdWJsaWMgcmVhZG9ubHkgY3VzdG9tUmVzb3VyY2VQcm92aWRlcjogUHJvdmlkZXI7XG4gIC8qKiBUaGUgY3VzdG9tIHJlc291cmNlIHRoYXQgdHJpZ2dlcnMgdGhlIHN0YXRlIG1hY2hpbmUgKi9cbiAgcHVibGljIHJlYWRvbmx5IGV4ZWN1dGlvblRyaWdnZXI6IEN1c3RvbVJlc291cmNlO1xuICAvKiogVGhlIGZpbGUgaW5wdXRzIGNvbmZpZ3VyYXRpb24gKi9cbiAgcHJpdmF0ZSByZWFkb25seSBmaWxlSW5wdXRzOiBGaWxlSW5wdXRbXTtcblxuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogRGF0YUxvYWRlclByb3BzKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkKTtcblxuICAgIC8vIFN0b3JlIGZpbGUgaW5wdXRzIGZvciBsYXRlciB1c2VcbiAgICB0aGlzLmZpbGVJbnB1dHMgPSBwcm9wcy5maWxlSW5wdXRzO1xuXG4gICAgLy8gVmFsaWRhdGUgcHJvcHNcbiAgICB0aGlzLl92YWxpZGF0ZVByb3BzKHByb3BzKTtcblxuICAgIC8vIEdldCByZW1vdmFsIHBvbGljeSB3aXRoIGRlZmF1bHRcbiAgICBjb25zdCByZW1vdmFsUG9saWN5ID0gcHJvcHMucmVtb3ZhbFBvbGljeSB8fCBSZW1vdmFsUG9saWN5LkRFU1RST1k7XG5cbiAgICAvLyBDcmVhdGUgUzMgYnVja2V0IGZvciBzdG9yaW5nIGZpbGVzXG4gICAgdGhpcy5idWNrZXQgPSB0aGlzLl9jcmVhdGVCdWNrZXQocmVtb3ZhbFBvbGljeSk7XG5cbiAgICAvLyBDcmVhdGUgTGFtYmRhIGZ1bmN0aW9uIGZvciBwcm9jZXNzaW5nXG4gICAgdGhpcy5wcm9jZXNzb3JGdW5jdGlvbiA9IHRoaXMuX2NyZWF0ZVByb2Nlc3NvckZ1bmN0aW9uKHByb3BzKTtcblxuICAgIC8vIENyZWF0ZSBTdGVwIEZ1bmN0aW9ucyBzdGF0ZSBtYWNoaW5lXG4gICAgdGhpcy5zdGF0ZU1hY2hpbmUgPSB0aGlzLl9jcmVhdGVTdGF0ZU1hY2hpbmUoKTtcblxuICAgIC8vIENyZWF0ZSBjdXN0b20gcmVzb3VyY2UgcHJvdmlkZXIgZm9yIHRyaWdnZXJpbmcgZXhlY3V0aW9uXG4gICAgdGhpcy5jdXN0b21SZXNvdXJjZVByb3ZpZGVyID0gdGhpcy5fY3JlYXRlQ3VzdG9tUmVzb3VyY2VQcm92aWRlcigpO1xuXG4gICAgLy8gVXBsb2FkIGZpbGVzIHRvIFMzXG4gICAgdGhpcy5fc2V0dXBGaWxlUHJvY2Vzc2luZyhwcm9wcyk7XG5cbiAgICAvLyBDcmVhdGUgY3VzdG9tIHJlc291cmNlIHRvIHRyaWdnZXIgZXhlY3V0aW9uIGFmdGVyIGZpbGVzIGFyZSB1cGxvYWRlZFxuICAgIHRoaXMuZXhlY3V0aW9uVHJpZ2dlciA9IHRoaXMuX2NyZWF0ZUV4ZWN1dGlvblRyaWdnZXIoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudHMgYWRkaXRpb25hbCBJQU0gcGVybWlzc2lvbnMgdG8gdGhlIGV4ZWN1dGlvbiB0cmlnZ2VyIExhbWJkYSBmdW5jdGlvblxuICAgKiBAcGFyYW0gc3RhdGVtZW50IFRoZSBJQU0gcG9saWN5IHN0YXRlbWVudCB0byBhZGRcbiAgICovXG4gIHB1YmxpYyBncmFudEV4ZWN1dGlvblRyaWdnZXJQZXJtaXNzaW9ucyhzdGF0ZW1lbnQ6IFBvbGljeVN0YXRlbWVudCk6IHZvaWQge1xuICAgIC8vIEdldCB0aGUgTGFtYmRhIGZ1bmN0aW9uIGZyb20gdGhlIGN1c3RvbSByZXNvdXJjZSBwcm92aWRlclxuICAgIGNvbnN0IHRyaWdnZXJGdW5jdGlvbiA9IHRoaXMuY3VzdG9tUmVzb3VyY2VQcm92aWRlci5vbkV2ZW50SGFuZGxlcjtcbiAgICBpZiAodHJpZ2dlckZ1bmN0aW9uKSB7XG4gICAgICB0cmlnZ2VyRnVuY3Rpb24uYWRkVG9Sb2xlUG9saWN5KHN0YXRlbWVudCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRlcyB0aGUgY29uc3RydWN0IHByb3BlcnRpZXNcbiAgICogQHBhcmFtIHByb3BzIFRoZSBEYXRhTG9hZGVyIHByb3BlcnRpZXNcbiAgICogQHByaXZhdGVcbiAgICovXG4gIHByaXZhdGUgX3ZhbGlkYXRlUHJvcHMocHJvcHM6IERhdGFMb2FkZXJQcm9wcyk6IHZvaWQge1xuICAgIGlmICghcHJvcHMuZGF0YWJhc2VDb25maWcpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignZGF0YWJhc2VDb25maWcgaXMgcmVxdWlyZWQnKTtcbiAgICB9XG5cbiAgICBpZiAoIXByb3BzLmRhdGFiYXNlQ29uZmlnLmNsdXN0ZXIgJiYgIXByb3BzLmRhdGFiYXNlQ29uZmlnLmluc3RhbmNlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0VpdGhlciBjbHVzdGVyIG9yIGluc3RhbmNlIG11c3QgYmUgcHJvdmlkZWQgaW4gZGF0YWJhc2VDb25maWcnKTtcbiAgICB9XG5cbiAgICBpZiAoIXByb3BzLmZpbGVJbnB1dHMgfHwgcHJvcHMuZmlsZUlucHV0cy5sZW5ndGggPT09IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQXQgbGVhc3Qgb25lIGZpbGUgaW5wdXQgaXMgcmVxdWlyZWQnKTtcbiAgICB9XG5cbiAgICAvLyBWYWxpZGF0ZSBmaWxlIGlucHV0c1xuICAgIGZvciAoY29uc3QgZmlsZUlucHV0IG9mIHByb3BzLmZpbGVJbnB1dHMpIHtcbiAgICAgIGlmICghZmlsZUlucHV0LmZpbGVQYXRoKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignZmlsZVBhdGggaXMgcmVxdWlyZWQgZm9yIGVhY2ggZmlsZSBpbnB1dCcpO1xuICAgICAgfVxuICAgICAgaWYgKCFmaWxlSW5wdXQuZmlsZVR5cGUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdmaWxlVHlwZSBpcyByZXF1aXJlZCBmb3IgZWFjaCBmaWxlIGlucHV0Jyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gVmFsaWRhdGUgZW5naW5lIGNvbXBhdGliaWxpdHlcbiAgICBmb3IgKGNvbnN0IGZpbGVJbnB1dCBvZiBwcm9wcy5maWxlSW5wdXRzKSB7XG4gICAgICBpZiAocHJvcHMuZGF0YWJhc2VDb25maWcuZW5naW5lID09PSBEYXRhYmFzZUVuZ2luZS5NWVNRTCAmJlxuICAgICAgICAgIGZpbGVJbnB1dC5maWxlVHlwZSA9PT0gRmlsZVR5cGUuUEdEVU1QKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignUG9zdGdyZVNRTCBkdW1wIGZpbGVzIGNhbm5vdCBiZSB1c2VkIHdpdGggTXlTUUwgZGF0YWJhc2VzJyk7XG4gICAgICB9XG4gICAgICBpZiAocHJvcHMuZGF0YWJhc2VDb25maWcuZW5naW5lID09PSBEYXRhYmFzZUVuZ2luZS5QT1NUR1JFU1FMICYmXG4gICAgICAgICAgZmlsZUlucHV0LmZpbGVUeXBlID09PSBGaWxlVHlwZS5NWVNRTERVTVApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNeVNRTCBkdW1wIGZpbGVzIGNhbm5vdCBiZSB1c2VkIHdpdGggUG9zdGdyZVNRTCBkYXRhYmFzZXMnKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyB0aGUgUzMgYnVja2V0IGZvciBzdG9yaW5nIGZpbGVzXG4gICAqIEBwYXJhbSByZW1vdmFsUG9saWN5IFRoZSByZW1vdmFsIHBvbGljeSB0byBhcHBseVxuICAgKiBAcmV0dXJucyBUaGUgY3JlYXRlZCBTMyBidWNrZXRcbiAgICogQHByaXZhdGVcbiAgICovXG4gIHByaXZhdGUgX2NyZWF0ZUJ1Y2tldChyZW1vdmFsUG9saWN5OiBSZW1vdmFsUG9saWN5KTogQnVja2V0IHtcbiAgICBjb25zdCBidWNrZXQgPSBuZXcgQnVja2V0KHRoaXMsICdEYXRhTG9hZGVyQnVja2V0Jywge1xuICAgICAgZW5jcnlwdGlvbjogQnVja2V0RW5jcnlwdGlvbi5TM19NQU5BR0VELFxuICAgICAgYmxvY2tQdWJsaWNBY2Nlc3M6IEJsb2NrUHVibGljQWNjZXNzLkJMT0NLX0FMTCxcbiAgICAgIHJlbW92YWxQb2xpY3k6IHJlbW92YWxQb2xpY3ksXG4gICAgICBhdXRvRGVsZXRlT2JqZWN0czogcmVtb3ZhbFBvbGljeSA9PT0gUmVtb3ZhbFBvbGljeS5ERVNUUk9ZLFxuICAgIH0pO1xuXG4gICAgcmV0dXJuIGJ1Y2tldDtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGVzIHRoZSBMYW1iZGEgZnVuY3Rpb24gZm9yIHByb2Nlc3NpbmcgZGF0YSBsb2FkaW5nXG4gICAqIEBwYXJhbSBwcm9wcyBUaGUgRGF0YUxvYWRlciBwcm9wZXJ0aWVzXG4gICAqIEByZXR1cm5zIFRoZSBjcmVhdGVkIExhbWJkYSBmdW5jdGlvblxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgcHJpdmF0ZSBfY3JlYXRlUHJvY2Vzc29yRnVuY3Rpb24ocHJvcHM6IERhdGFMb2FkZXJQcm9wcyk6IExhbWJkYUZ1bmN0aW9uIHtcbiAgICAvLyBDcmVhdGUgYSBkZWRpY2F0ZWQgc2VjdXJpdHkgZ3JvdXAgZm9yIHRoZSBMYW1iZGEgZnVuY3Rpb25cbiAgICBjb25zdCBsYW1iZGFTZWN1cml0eUdyb3VwID0gbmV3IFNlY3VyaXR5R3JvdXAodGhpcywgJ0RhdGFMb2FkZXJQcm9jZXNzb3JTZWN1cml0eUdyb3VwJywge1xuICAgICAgdnBjOiBwcm9wcy5kYXRhYmFzZUNvbmZpZy52cGMsXG4gICAgICBkZXNjcmlwdGlvbjogJ1NlY3VyaXR5IGdyb3VwIGZvciBEYXRhTG9hZGVyIHByb2Nlc3NvciBMYW1iZGEgZnVuY3Rpb24nLFxuICAgICAgYWxsb3dBbGxPdXRib3VuZDogdHJ1ZSwgLy8gTGFtYmRhIG5lZWRzIG91dGJvdW5kIGFjY2VzcyBmb3IgQVdTIHNlcnZpY2VzIGFuZCBpbnRlcm5ldFxuICAgIH0pO1xuXG4gICAgLy8gQWxsb3cgTGFtYmRhIHRvIGNvbm5lY3QgdG8gdGhlIGRhdGFiYXNlXG4gICAgLy8gQWRkIGluZ3Jlc3MgcnVsZSB0byBkYXRhYmFzZSBzZWN1cml0eSBncm91cCB0byBhbGxvdyBjb25uZWN0aW9ucyBmcm9tIExhbWJkYVxuICAgIHByb3BzLmRhdGFiYXNlQ29uZmlnLnNlY3VyaXR5R3JvdXAuYWRkSW5ncmVzc1J1bGUoXG4gICAgICBsYW1iZGFTZWN1cml0eUdyb3VwLFxuICAgICAgUG9ydC50Y3AocHJvcHMuZGF0YWJhc2VDb25maWcuZW5naW5lID09PSBEYXRhYmFzZUVuZ2luZS5NWVNRTCA/IDMzMDYgOiA1NDMyKSxcbiAgICAgIGBBbGxvdyBEYXRhTG9hZGVyIExhbWJkYSB0byBjb25uZWN0IHRvICR7cHJvcHMuZGF0YWJhc2VDb25maWcuZW5naW5lfSBkYXRhYmFzZWAsXG4gICAgKTtcblxuICAgIC8vIENyZWF0ZSBMYW1iZGEgZnVuY3Rpb24gd2l0aCBhdXRvbWF0aWMgZGVwZW5kZW5jeSBidW5kbGluZ1xuICAgIGNvbnN0IGxhbWJkYUZ1bmN0aW9uID0gbmV3IFB5dGhvbkZ1bmN0aW9uKHRoaXMsICdEYXRhTG9hZGVyUHJvY2Vzc29yJywge1xuICAgICAgZW50cnk6IHBhdGguam9pbihfX2Rpcm5hbWUsICdkYXRhLWxvYWRlci1sYW1iZGEnKSxcbiAgICAgIHJ1bnRpbWU6IFJ1bnRpbWUuUFlUSE9OXzNfMTMsXG4gICAgICBoYW5kbGVyOiAnaGFuZGxlcicsXG4gICAgICBpbmRleDogJ2luZGV4LnB5JyxcbiAgICAgIHRpbWVvdXQ6IHByb3BzLnRpbWVvdXQgfHwgRHVyYXRpb24ubWludXRlcygxNSksXG4gICAgICBtZW1vcnlTaXplOiBwcm9wcy5tZW1vcnlTaXplIHx8IDEwMjQsXG4gICAgICBhcmNoaXRlY3R1cmU6IEFyY2hpdGVjdHVyZS5BUk1fNjQsXG4gICAgICB2cGM6IHByb3BzLmRhdGFiYXNlQ29uZmlnLnZwYyxcbiAgICAgIHNlY3VyaXR5R3JvdXBzOiBbbGFtYmRhU2VjdXJpdHlHcm91cF0sIC8vIFVzZSB0aGUgZGVkaWNhdGVkIExhbWJkYSBzZWN1cml0eSBncm91cFxuICAgICAgZW52aXJvbm1lbnQ6IHtcbiAgICAgICAgREFUQUJBU0VfRU5HSU5FOiBwcm9wcy5kYXRhYmFzZUNvbmZpZy5lbmdpbmUsXG4gICAgICAgIERBVEFCQVNFX1NFQ1JFVF9BUk46IHByb3BzLmRhdGFiYXNlQ29uZmlnLnNlY3JldC5zZWNyZXRBcm4sXG4gICAgICAgIERBVEFCQVNFX05BTUU6IHByb3BzLmRhdGFiYXNlQ29uZmlnLmRhdGFiYXNlTmFtZSxcbiAgICAgICAgUzNfQlVDS0VUOiB0aGlzLmJ1Y2tldC5idWNrZXROYW1lLFxuICAgICAgfSxcbiAgICAgIGJ1bmRsaW5nOiB7XG4gICAgICAgIC8vIFVzZSBjdXN0b20gYnVuZGxpbmcgY29tbWFuZHMgdG8gYXZvaWQgUG9ldHJ5IGNvbmZsaWN0c1xuICAgICAgICBjb21tYW5kOiBbXG4gICAgICAgICAgJ2Jhc2gnLCAnLWMnLCBbXG4gICAgICAgICAgICAvLyBDcmVhdGUgYSBjbGVhbiB2aXJ0dWFsIGVudmlyb25tZW50XG4gICAgICAgICAgICAncHl0aG9uIC1tIHZlbnYgL3RtcC92ZW52JyxcbiAgICAgICAgICAgIC8vIEFjdGl2YXRlIHRoZSB2aXJ0dWFsIGVudmlyb25tZW50XG4gICAgICAgICAgICAnc291cmNlIC90bXAvdmVudi9iaW4vYWN0aXZhdGUnLFxuICAgICAgICAgICAgLy8gSW5zdGFsbCBkZXBlbmRlbmNpZXMgaW4gdGhlIHZpcnR1YWwgZW52aXJvbm1lbnRcbiAgICAgICAgICAgICdwaXAgaW5zdGFsbCAtLXVwZ3JhZGUgcGlwJyxcbiAgICAgICAgICAgICdwaXAgaW5zdGFsbCAtciByZXF1aXJlbWVudHMudHh0IC10IC9hc3NldC1vdXRwdXQnLFxuICAgICAgICAgICAgLy8gQ29weSBzb3VyY2UgZmlsZXNcbiAgICAgICAgICAgICdjcCAtciAuIC9hc3NldC1vdXRwdXQnLFxuICAgICAgICAgICAgLy8gQ2xlYW4gdXAgX19weWNhY2hlX18gYW5kIG90aGVyIHVubmVjZXNzYXJ5IGZpbGVzXG4gICAgICAgICAgICAnZmluZCAvYXNzZXQtb3V0cHV0IC10eXBlIGQgLW5hbWUgX19weWNhY2hlX18gLWV4ZWMgcm0gLXJmIHt9ICsgfHwgdHJ1ZScsXG4gICAgICAgICAgICAnZmluZCAvYXNzZXQtb3V0cHV0IC1uYW1lIFwiKi5weWNcIiAtZGVsZXRlIHx8IHRydWUnLFxuICAgICAgICAgIF0uam9pbignICYmICcpLFxuICAgICAgICBdLFxuICAgICAgICAvLyBVc2UgdGhlIHN0YW5kYXJkIFB5dGhvbiBpbWFnZSB0byBhdm9pZCBwcmUtaW5zdGFsbGVkIHBhY2thZ2VzXG4gICAgICAgIGltYWdlOiBEb2NrZXJJbWFnZS5mcm9tUmVnaXN0cnkoJ3B1YmxpYy5lY3IuYXdzL2RvY2tlci9saWJyYXJ5L3B5dGhvbjozLjEzLjUtYnVsbHNleWUnKSxcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICAvLyBHcmFudCBwZXJtaXNzaW9uc1xuICAgIHRoaXMuX2dyYW50UGVybWlzc2lvbnMobGFtYmRhRnVuY3Rpb24sIHByb3BzKTtcblxuICAgIHJldHVybiBsYW1iZGFGdW5jdGlvbjtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGVzIHRoZSBTdGVwIEZ1bmN0aW9ucyBzdGF0ZSBtYWNoaW5lXG4gICAqIEByZXR1cm5zIFRoZSBjcmVhdGVkIHN0YXRlIG1hY2hpbmVcbiAgICogQHByaXZhdGVcbiAgICovXG4gIHByaXZhdGUgX2NyZWF0ZVN0YXRlTWFjaGluZSgpOiBTdGF0ZU1hY2hpbmUge1xuICAgIC8vIENyZWF0ZSBhIE1hcCBzdGF0ZSB0byBpdGVyYXRlIG92ZXIgZmlsZSBrZXlzXG4gICAgY29uc3QgcHJvY2Vzc0ZpbGVUYXNrID0gbmV3IExhbWJkYUludm9rZSh0aGlzLCAnUHJvY2Vzc0ZpbGVUYXNrJywge1xuICAgICAgbGFtYmRhRnVuY3Rpb246IHRoaXMucHJvY2Vzc29yRnVuY3Rpb24sXG4gICAgICBwYXlsb2FkOiBUYXNrSW5wdXQuZnJvbU9iamVjdCh7XG4gICAgICAgICdzM0tleS4kJzogJyQnLFxuICAgICAgICAnYnVja2V0TmFtZSc6IHRoaXMuYnVja2V0LmJ1Y2tldE5hbWUsXG4gICAgICB9KSxcbiAgICB9KTtcblxuICAgIC8vIENyZWF0ZSB0aGUgc3RhdGUgbWFjaGluZSBkZWZpbml0aW9uXG4gICAgY29uc3QgZGVmaW5pdGlvbiA9IG5ldyBNYXAodGhpcywgJ1Byb2Nlc3NGaWxlc01hcCcsIHtcbiAgICAgIGl0ZW1zUGF0aDogJyQuZmlsZUtleXMnLFxuICAgICAgbWF4Q29uY3VycmVuY3k6IDEsIC8vIFByb2Nlc3MgZmlsZXMgc2VxdWVudGlhbGx5IHRvIG1haW50YWluIG9yZGVyXG4gICAgfSkuaXRlbVByb2Nlc3Nvcihwcm9jZXNzRmlsZVRhc2spO1xuXG4gICAgLy8gQ3JlYXRlIHRoZSBzdGF0ZSBtYWNoaW5lXG4gICAgY29uc3Qgc3RhdGVNYWNoaW5lID0gbmV3IFN0YXRlTWFjaGluZSh0aGlzLCAnRGF0YUxvYWRlclN0YXRlTWFjaGluZScsIHtcbiAgICAgIGRlZmluaXRpb25Cb2R5OiBEZWZpbml0aW9uQm9keS5mcm9tQ2hhaW5hYmxlKGRlZmluaXRpb24pLFxuICAgICAgdGltZW91dDogRHVyYXRpb24uaG91cnMoMiksIC8vIEFsbG93IHVwIHRvIDIgaG91cnMgZm9yIHRoZSBlbnRpcmUgcHJvY2Vzc1xuICAgIH0pO1xuXG4gICAgLy8gR3JhbnQgdGhlIHN0YXRlIG1hY2hpbmUgcGVybWlzc2lvbiB0byBpbnZva2UgdGhlIExhbWJkYSBmdW5jdGlvblxuICAgIHRoaXMucHJvY2Vzc29yRnVuY3Rpb24uZ3JhbnRJbnZva2Uoc3RhdGVNYWNoaW5lKTtcblxuICAgIHJldHVybiBzdGF0ZU1hY2hpbmU7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIG5lY2Vzc2FyeSBwZXJtaXNzaW9ucyB0byB0aGUgTGFtYmRhIGZ1bmN0aW9uXG4gICAqIEBwYXJhbSBsYW1iZGFGdW5jdGlvbiBUaGUgTGFtYmRhIGZ1bmN0aW9uXG4gICAqIEBwYXJhbSBwcm9wcyBUaGUgRGF0YUxvYWRlciBwcm9wZXJ0aWVzXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBwcml2YXRlIF9ncmFudFBlcm1pc3Npb25zKGxhbWJkYUZ1bmN0aW9uOiBMYW1iZGFGdW5jdGlvbiwgcHJvcHM6IERhdGFMb2FkZXJQcm9wcyk6IHZvaWQge1xuICAgIC8vIEdyYW50IFMzIHBlcm1pc3Npb25zXG4gICAgdGhpcy5idWNrZXQuZ3JhbnRSZWFkKGxhbWJkYUZ1bmN0aW9uKTtcblxuICAgIC8vIEdyYW50IFNlY3JldHMgTWFuYWdlciBwZXJtaXNzaW9uc1xuICAgIHByb3BzLmRhdGFiYXNlQ29uZmlnLnNlY3JldC5ncmFudFJlYWQobGFtYmRhRnVuY3Rpb24pO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldHMgdXAgZmlsZSBwcm9jZXNzaW5nIGJ5IHVwbG9hZGluZyBmaWxlcyB0byBTM1xuICAgKiBAcGFyYW0gcHJvcHMgVGhlIERhdGFMb2FkZXIgcHJvcGVydGllc1xuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgcHJpdmF0ZSBfc2V0dXBGaWxlUHJvY2Vzc2luZyhwcm9wczogRGF0YUxvYWRlclByb3BzKTogdm9pZCB7XG4gICAgLy8gU2VwYXJhdGUgbG9jYWwgZmlsZXMgZnJvbSBTMyBVUklzXG4gICAgY29uc3QgbG9jYWxGaWxlcyA9IHByb3BzLmZpbGVJbnB1dHMuZmlsdGVyKGYgPT4gIWYuZmlsZVBhdGguc3RhcnRzV2l0aCgnczM6Ly8nKSk7XG5cbiAgICAvLyBVcGxvYWQgbG9jYWwgZmlsZXMgdG8gUzMgaWYgYW55XG4gICAgaWYgKGxvY2FsRmlsZXMubGVuZ3RoID4gMCkge1xuICAgICAgLy8gUHJvY2VzcyBlYWNoIGZpbGUgaW5kaXZpZHVhbGx5IHRvIGhhbmRsZSBib3RoIGZpbGVzIGFuZCBkaXJlY3Rvcmllc1xuICAgICAgbG9jYWxGaWxlcy5mb3JFYWNoKChmaWxlSW5wdXQsIGluZGV4KSA9PiB7XG4gICAgICAgIGNvbnN0IGZpbGVQYXRoID0gZmlsZUlucHV0LmZpbGVQYXRoO1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXJlcXVpcmUtaW1wb3J0c1xuICAgICAgICBjb25zdCBmcyA9IHJlcXVpcmUoJ2ZzJyk7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tcmVxdWlyZS1pbXBvcnRzXG4gICAgICAgIGNvbnN0IHBhdGhNb2R1bGUgPSByZXF1aXJlKCdwYXRoJyk7XG5cbiAgICAgICAgbGV0IHJlc29sdmVkUGF0aDogc3RyaW5nO1xuICAgICAgICBpZiAocGF0aE1vZHVsZS5pc0Fic29sdXRlKGZpbGVQYXRoKSkge1xuICAgICAgICAgIHJlc29sdmVkUGF0aCA9IGZpbGVQYXRoO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIFJlc29sdmUgcmVsYXRpdmUgcGF0aHMgZnJvbSB0aGUgY3VycmVudCB3b3JraW5nIGRpcmVjdG9yeVxuICAgICAgICAgIHJlc29sdmVkUGF0aCA9IHBhdGhNb2R1bGUucmVzb2x2ZShmaWxlUGF0aCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBDaGVjayBpZiB0aGUgcGF0aCBleGlzdHNcbiAgICAgICAgaWYgKCFmcy5leGlzdHNTeW5jKHJlc29sdmVkUGF0aCkpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEZpbGUgbm90IGZvdW5kOiAke3Jlc29sdmVkUGF0aH1gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChmcy5zdGF0U3luYyhyZXNvbHZlZFBhdGgpLmlzRmlsZSgpKSB7XG4gICAgICAgICAgLy8gRm9yIGluZGl2aWR1YWwgZmlsZXMsIGRlcGxveSBmcm9tIHBhcmVudCBkaXJlY3Rvcnkgd2l0aCBpbmNsdWRlIGZpbHRlclxuICAgICAgICAgIGNvbnN0IHBhcmVudERpciA9IHBhdGhNb2R1bGUuZGlybmFtZShyZXNvbHZlZFBhdGgpO1xuICAgICAgICAgIGNvbnN0IGZpbGVOYW1lID0gcGF0aE1vZHVsZS5iYXNlbmFtZShyZXNvbHZlZFBhdGgpO1xuXG4gICAgICAgICAgbmV3IEJ1Y2tldERlcGxveW1lbnQodGhpcywgYERhdGFMb2FkZXJGaWxlRGVwbG95bWVudCR7aW5kZXh9YCwge1xuICAgICAgICAgICAgc291cmNlczogW1NvdXJjZS5hc3NldChwYXJlbnREaXIpXSxcbiAgICAgICAgICAgIGRlc3RpbmF0aW9uQnVja2V0OiB0aGlzLmJ1Y2tldCxcbiAgICAgICAgICAgIGRlc3RpbmF0aW9uS2V5UHJlZml4OiAnZGF0YS1maWxlcy8nLFxuICAgICAgICAgICAgaW5jbHVkZTogW2ZpbGVOYW1lXSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBGb3IgZGlyZWN0b3JpZXMsIGRlcGxveSBlbnRpcmUgZGlyZWN0b3J5XG4gICAgICAgICAgbmV3IEJ1Y2tldERlcGxveW1lbnQodGhpcywgYERhdGFMb2FkZXJGaWxlRGVwbG95bWVudCR7aW5kZXh9YCwge1xuICAgICAgICAgICAgc291cmNlczogW1NvdXJjZS5hc3NldChyZXNvbHZlZFBhdGgpXSxcbiAgICAgICAgICAgIGRlc3RpbmF0aW9uQnVja2V0OiB0aGlzLmJ1Y2tldCxcbiAgICAgICAgICAgIGRlc3RpbmF0aW9uS2V5UHJlZml4OiAnZGF0YS1maWxlcy8nLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyBhIGN1c3RvbSByZXNvdXJjZSBwcm92aWRlciBmb3IgdHJpZ2dlcmluZyBzdGF0ZSBtYWNoaW5lIGV4ZWN1dGlvblxuICAgKiBAcmV0dXJucyBUaGUgY3VzdG9tIHJlc291cmNlIHByb3ZpZGVyXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBwcml2YXRlIF9jcmVhdGVDdXN0b21SZXNvdXJjZVByb3ZpZGVyKCk6IFByb3ZpZGVyIHtcbiAgICAvLyBDcmVhdGUgSUFNIHJvbGUgZm9yIHRoZSBjdXN0b20gcmVzb3VyY2UgTGFtYmRhIGZ1bmN0aW9uIHdpdGggYWxsIG5lY2Vzc2FyeSBwb2xpY2llc1xuICAgIGNvbnN0IGN1c3RvbVJlc291cmNlUm9sZSA9IG5ldyBSb2xlKHRoaXMsICdTdGF0ZU1hY2hpbmVFeGVjdXRpb25UcmlnZ2VyUm9sZScsIHtcbiAgICAgIGFzc3VtZWRCeTogbmV3IFNlcnZpY2VQcmluY2lwYWwoJ2xhbWJkYS5hbWF6b25hd3MuY29tJyksXG4gICAgICBkZXNjcmlwdGlvbjogJ0lBTSByb2xlIGZvciBEYXRhTG9hZGVyIGN1c3RvbSByZXNvdXJjZSBMYW1iZGEgZnVuY3Rpb24nLFxuICAgICAgbWFuYWdlZFBvbGljaWVzOiBbXG4gICAgICAgIE1hbmFnZWRQb2xpY3kuZnJvbUF3c01hbmFnZWRQb2xpY3lOYW1lKCdzZXJ2aWNlLXJvbGUvQVdTTGFtYmRhQmFzaWNFeGVjdXRpb25Sb2xlJyksXG4gICAgICBdLFxuICAgICAgaW5saW5lUG9saWNpZXM6IHtcbiAgICAgICAgU3RhdGVNYWNoaW5lRXhlY3V0aW9uUG9saWN5OiBuZXcgUG9saWN5RG9jdW1lbnQoe1xuICAgICAgICAgIHN0YXRlbWVudHM6IFtcbiAgICAgICAgICAgIG5ldyBQb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICAgICAgICBlZmZlY3Q6IEVmZmVjdC5BTExPVyxcbiAgICAgICAgICAgICAgYWN0aW9uczogW1xuICAgICAgICAgICAgICAgICdzdGF0ZXM6U3RhcnRFeGVjdXRpb24nLFxuICAgICAgICAgICAgICAgICdzdGF0ZXM6RGVzY3JpYmVFeGVjdXRpb24nLFxuICAgICAgICAgICAgICAgICdzdGF0ZXM6U3RvcEV4ZWN1dGlvbicsXG4gICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICAgIHJlc291cmNlczogW1xuICAgICAgICAgICAgICAgIHRoaXMuc3RhdGVNYWNoaW5lLnN0YXRlTWFjaGluZUFybixcbiAgICAgICAgICAgICAgICBgJHt0aGlzLnN0YXRlTWFjaGluZS5zdGF0ZU1hY2hpbmVBcm59OipgLCAvLyBGb3IgZXhlY3V0aW9uIEFSTnNcbiAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgIF0sXG4gICAgICAgIH0pLFxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIC8vIENyZWF0ZSBMYW1iZGEgZnVuY3Rpb24gZm9yIGN1c3RvbSByZXNvdXJjZSB3aXRoIHRoZSBwcmUtY29uZmlndXJlZCByb2xlXG4gICAgY29uc3QgY3VzdG9tUmVzb3VyY2VGdW5jdGlvbiA9IG5ldyBMYW1iZGFGdW5jdGlvbih0aGlzLCAnU3RhdGVNYWNoaW5lRXhlY3V0aW9uVHJpZ2dlcicsIHtcbiAgICAgIHJ1bnRpbWU6IFJ1bnRpbWUuUFlUSE9OXzNfMTEsXG4gICAgICBoYW5kbGVyOiAnaW5kZXguaGFuZGxlcicsXG4gICAgICByb2xlOiBjdXN0b21SZXNvdXJjZVJvbGUsIC8vIEF0dGFjaCB0aGUgcm9sZSBkdXJpbmcgY3JlYXRpb25cbiAgICAgIGNvZGU6IENvZGUuZnJvbUlubGluZShgXG5pbXBvcnQganNvblxuaW1wb3J0IGJvdG8zXG5pbXBvcnQgbG9nZ2luZ1xuXG5sb2dnZXIgPSBsb2dnaW5nLmdldExvZ2dlcigpXG5sb2dnZXIuc2V0TGV2ZWwobG9nZ2luZy5JTkZPKVxuXG5zdGVwZnVuY3Rpb25zID0gYm90bzMuY2xpZW50KCdzdGVwZnVuY3Rpb25zJylcblxuZGVmIGhhbmRsZXIoZXZlbnQsIGNvbnRleHQpOlxuICAgIGxvZ2dlci5pbmZvKGZcIlJlY2VpdmVkIGV2ZW50OiB7anNvbi5kdW1wcyhldmVudCl9XCIpXG4gICAgXG4gICAgcmVxdWVzdF90eXBlID0gZXZlbnRbJ1JlcXVlc3RUeXBlJ11cbiAgICBcbiAgICBpZiByZXF1ZXN0X3R5cGUgPT0gJ0NyZWF0ZScgb3IgcmVxdWVzdF90eXBlID09ICdVcGRhdGUnOlxuICAgICAgICB0cnk6XG4gICAgICAgICAgICAjIEdldCBwYXJhbWV0ZXJzIGZyb20gZXZlbnRcbiAgICAgICAgICAgIHN0YXRlX21hY2hpbmVfYXJuID0gZXZlbnRbJ1Jlc291cmNlUHJvcGVydGllcyddWydTdGF0ZU1hY2hpbmVBcm4nXVxuICAgICAgICAgICAgZmlsZV9rZXlzID0gZXZlbnRbJ1Jlc291cmNlUHJvcGVydGllcyddWydGaWxlS2V5cyddXG4gICAgICAgICAgICBcbiAgICAgICAgICAgICMgU3RhcnQgZXhlY3V0aW9uXG4gICAgICAgICAgICByZXNwb25zZSA9IHN0ZXBmdW5jdGlvbnMuc3RhcnRfZXhlY3V0aW9uKFxuICAgICAgICAgICAgICAgIHN0YXRlTWFjaGluZUFybj1zdGF0ZV9tYWNoaW5lX2FybixcbiAgICAgICAgICAgICAgICBpbnB1dD1qc29uLmR1bXBzKHtcbiAgICAgICAgICAgICAgICAgICAgJ2ZpbGVLZXlzJzogZmlsZV9rZXlzXG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIClcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgZXhlY3V0aW9uX2FybiA9IHJlc3BvbnNlWydleGVjdXRpb25Bcm4nXVxuICAgICAgICAgICAgbG9nZ2VyLmluZm8oZlwiU3RhcnRlZCBleGVjdXRpb246IHtleGVjdXRpb25fYXJufVwiKVxuICAgICAgICAgICAgXG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICdTdGF0dXMnOiAnU1VDQ0VTUycsXG4gICAgICAgICAgICAgICAgJ1BoeXNpY2FsUmVzb3VyY2VJZCc6IGV4ZWN1dGlvbl9hcm4sXG4gICAgICAgICAgICAgICAgJ0RhdGEnOiB7XG4gICAgICAgICAgICAgICAgICAgICdFeGVjdXRpb25Bcm4nOiBleGVjdXRpb25fYXJuXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgXG4gICAgICAgIGV4Y2VwdCBFeGNlcHRpb24gYXMgZTpcbiAgICAgICAgICAgIGxvZ2dlci5lcnJvcihmXCJFcnJvciBzdGFydGluZyBleGVjdXRpb246IHtzdHIoZSl9XCIpXG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICdTdGF0dXMnOiAnRkFJTEVEJyxcbiAgICAgICAgICAgICAgICAnUmVhc29uJzogc3RyKGUpLFxuICAgICAgICAgICAgICAgICdQaHlzaWNhbFJlc291cmNlSWQnOiAnZmFpbGVkJ1xuICAgICAgICAgICAgfVxuICAgIFxuICAgIGVsaWYgcmVxdWVzdF90eXBlID09ICdEZWxldGUnOlxuICAgICAgICAjIEZvciBkZWxldGUsIHdlIGRvbid0IG5lZWQgdG8gZG8gYW55dGhpbmcgc3BlY2lhbFxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgJ1N0YXR1cyc6ICdTVUNDRVNTJyxcbiAgICAgICAgICAgICdQaHlzaWNhbFJlc291cmNlSWQnOiBldmVudC5nZXQoJ1BoeXNpY2FsUmVzb3VyY2VJZCcsICdub25lJylcbiAgICAgICAgfVxuICAgIFxuICAgIHJldHVybiB7XG4gICAgICAgICdTdGF0dXMnOiAnU1VDQ0VTUycsXG4gICAgICAgICdQaHlzaWNhbFJlc291cmNlSWQnOiAnbm9uZSdcbiAgICB9XG4gICAgICBgKSxcbiAgICAgIHRpbWVvdXQ6IER1cmF0aW9uLm1pbnV0ZXMoNSksXG4gICAgfSk7XG5cbiAgICAvLyBDcmVhdGUgcHJvdmlkZXIgd2l0aCB0aGUgTGFtYmRhIGZ1bmN0aW9uIHRoYXQgYWxyZWFkeSBoYXMgdGhlIGNvcnJlY3Qgcm9sZVxuICAgIGNvbnN0IHByb3ZpZGVyID0gbmV3IFByb3ZpZGVyKHRoaXMsICdTdGF0ZU1hY2hpbmVFeGVjdXRpb25Qcm92aWRlcicsIHtcbiAgICAgIG9uRXZlbnRIYW5kbGVyOiBjdXN0b21SZXNvdXJjZUZ1bmN0aW9uLFxuICAgIH0pO1xuXG4gICAgcmV0dXJuIHByb3ZpZGVyO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBjdXN0b20gcmVzb3VyY2UgdG8gdHJpZ2dlciBzdGF0ZSBtYWNoaW5lIGV4ZWN1dGlvblxuICAgKiBAcmV0dXJucyBUaGUgY3VzdG9tIHJlc291cmNlXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBwcml2YXRlIF9jcmVhdGVFeGVjdXRpb25UcmlnZ2VyKCk6IEN1c3RvbVJlc291cmNlIHtcbiAgICAvLyBHZXQgb3JkZXJlZCBmaWxlIGtleXNcbiAgICBjb25zdCBvcmRlcmVkRmlsZUtleXMgPSB0aGlzLl9nZXRPcmRlcmVkRmlsZUtleXMoKTtcblxuICAgIGNvbnN0IGN1c3RvbVJlc291cmNlID0gbmV3IEN1c3RvbVJlc291cmNlKHRoaXMsICdFeGVjdXRpb25UcmlnZ2VyUmVzb3VyY2UnLCB7XG4gICAgICBzZXJ2aWNlVG9rZW46IHRoaXMuY3VzdG9tUmVzb3VyY2VQcm92aWRlci5zZXJ2aWNlVG9rZW4sXG4gICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgIFN0YXRlTWFjaGluZUFybjogdGhpcy5zdGF0ZU1hY2hpbmUuc3RhdGVNYWNoaW5lQXJuLFxuICAgICAgICBGaWxlS2V5czogb3JkZXJlZEZpbGVLZXlzLFxuICAgICAgICAvLyBBZGQgYSB0aW1lc3RhbXAgdG8gZm9yY2UgdXBkYXRlcyB3aGVuIG5lZWRlZFxuICAgICAgICBUaW1lc3RhbXA6IERhdGUubm93KCkudG9TdHJpbmcoKSxcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICAvLyBFbnN1cmUgdGhlIGN1c3RvbSByZXNvdXJjZSBydW5zIGFmdGVyIGJ1Y2tldCBkZXBsb3ltZW50IChpZiBleGlzdHMpXG4gICAgaWYgKHRoaXMuYnVja2V0RGVwbG95bWVudCkge1xuICAgICAgY3VzdG9tUmVzb3VyY2Uubm9kZS5hZGREZXBlbmRlbmN5KHRoaXMuc3RhdGVNYWNoaW5lKTtcbiAgICAgIGN1c3RvbVJlc291cmNlLm5vZGUuYWRkRGVwZW5kZW5jeSh0aGlzLmJ1Y2tldERlcGxveW1lbnQpO1xuICAgIH1cblxuICAgIHJldHVybiBjdXN0b21SZXNvdXJjZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIHRoZSBvcmRlcmVkIGZpbGUga2V5cyBmb3IgZXhlY3V0aW9uXG4gICAqIEByZXR1cm5zIEFycmF5IG9mIFMzIGtleXMgaW4gZXhlY3V0aW9uIG9yZGVyXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBwcml2YXRlIF9nZXRPcmRlcmVkRmlsZUtleXMoKTogc3RyaW5nW10ge1xuICAgIC8vIFNvcnQgZmlsZXMgYnkgZXhlY3V0aW9uIG9yZGVyXG4gICAgY29uc3Qgc29ydGVkRmlsZXMgPSBbLi4udGhpcy5maWxlSW5wdXRzXS5zb3J0KFxuICAgICAgKGEsIGIpID0+IChhLmV4ZWN1dGlvbk9yZGVyIHx8IDApIC0gKGIuZXhlY3V0aW9uT3JkZXIgfHwgMCksXG4gICAgKTtcblxuICAgIC8vIENvbnZlcnQgZmlsZSBwYXRocyB0byBTMyBrZXlzXG4gICAgcmV0dXJuIHNvcnRlZEZpbGVzLm1hcChmaWxlID0+IHtcbiAgICAgIGlmIChmaWxlLmZpbGVQYXRoLnN0YXJ0c1dpdGgoJ3MzOi8vJykpIHtcbiAgICAgICAgLy8gRXh0cmFjdCBrZXkgZnJvbSBTMyBVUklcbiAgICAgICAgY29uc3QgcGFydHMgPSBmaWxlLmZpbGVQYXRoLnJlcGxhY2UoJ3MzOi8vJywgJycpLnNwbGl0KCcvJyk7XG4gICAgICAgIHJldHVybiBwYXJ0cy5zbGljZSgxKS5qb2luKCcvJyk7IC8vIFJlbW92ZSBidWNrZXQgbmFtZVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gTG9jYWwgZmlsZXMgYXJlIHVwbG9hZGVkIHdpdGggZGF0YS1maWxlcy8gcHJlZml4XG4gICAgICAgIGNvbnN0IGZpbGVOYW1lID0gcGF0aC5iYXNlbmFtZShmaWxlLmZpbGVQYXRoKTtcbiAgICAgICAgcmV0dXJuIGBkYXRhLWZpbGVzLyR7ZmlsZU5hbWV9YDtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxufVxuIl19
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./observability"), exports);
|
|
18
|
+
__exportStar(require("./lambda-iam-utils"), exports);
|
|
19
|
+
__exportStar(require("./data-loader"), exports);
|
|
20
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi91c2UtY2FzZXMvdXRpbGl0aWVzL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxrREFBZ0M7QUFDaEMscURBQW1DO0FBQ25DLGdEQUE4QiIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCAqIGZyb20gJy4vb2JzZXJ2YWJpbGl0eSc7XG5leHBvcnQgKiBmcm9tICcuL2xhbWJkYS1pYW0tdXRpbHMnO1xuZXhwb3J0ICogZnJvbSAnLi9kYXRhLWxvYWRlcic7XG4iXX0=
|