@softchef/cdk-iot-device-management
Version:
IoT device management is composed of things, thing types, thing groups, jobs, files API services. The constructs can be used independently, that are based on full-managed service to create an API Gateway & Lambda function.
409 lines • 51.1 kB
JavaScript
"use strict";
var _a;
Object.defineProperty(exports, "__esModule", { value: true });
exports.FileApi = void 0;
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
const path = require("path");
const cdk_restapi_1 = require("@softchef/cdk-restapi");
const aws_apigateway_1 = require("aws-cdk-lib/aws-apigateway");
const aws_dynamodb_1 = require("aws-cdk-lib/aws-dynamodb");
const aws_iam_1 = require("aws-cdk-lib/aws-iam");
const aws_lambda_nodejs_1 = require("aws-cdk-lib/aws-lambda-nodejs");
const constructs_1 = require("constructs");
const LAMBDA_ASSETS_PATH = path.resolve(__dirname, '../lambda-assets/files');
/**
* File API construct.
*
* @stability stable
*/
class FileApi extends constructs_1.Construct {
/**
* @stability stable
*/
constructor(scope, id, props) {
var _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y;
super(scope, id);
this.categoryTable = new aws_dynamodb_1.Table(this, 'CategoryTable', {
partitionKey: {
name: 'categoryId',
type: aws_dynamodb_1.AttributeType.STRING,
},
readCapacity: (_c = (_b = props === null || props === void 0 ? void 0 : props.categoryTableConfig) === null || _b === void 0 ? void 0 : _b.primaryIndex.readCapacity) !== null && _c !== void 0 ? _c : 1,
writeCapacity: (_e = (_d = props === null || props === void 0 ? void 0 : props.categoryTableConfig) === null || _d === void 0 ? void 0 : _d.primaryIndex.writeCapacity) !== null && _e !== void 0 ? _e : 1,
});
this.categoryTable.addGlobalSecondaryIndex({
indexName: 'query-by-parent-id',
partitionKey: {
name: 'parentId',
type: aws_dynamodb_1.AttributeType.STRING,
},
projectionType: aws_dynamodb_1.ProjectionType.ALL,
readCapacity: (_g = (_f = props === null || props === void 0 ? void 0 : props.categoryTableConfig) === null || _f === void 0 ? void 0 : _f.indexQueryByParentId.readCapacity) !== null && _g !== void 0 ? _g : 1,
writeCapacity: (_j = (_h = props === null || props === void 0 ? void 0 : props.categoryTableConfig) === null || _h === void 0 ? void 0 : _h.indexQueryByParentId.writeCapacity) !== null && _j !== void 0 ? _j : 1,
});
this.fileTable = new aws_dynamodb_1.Table(this, 'FileTable', {
partitionKey: {
name: 'fileId',
type: aws_dynamodb_1.AttributeType.STRING,
},
readCapacity: (_l = (_k = props === null || props === void 0 ? void 0 : props.fileTableConfig) === null || _k === void 0 ? void 0 : _k.primaryIndex.readCapacity) !== null && _l !== void 0 ? _l : 1,
writeCapacity: (_o = (_m = props === null || props === void 0 ? void 0 : props.fileTableConfig) === null || _m === void 0 ? void 0 : _m.primaryIndex.writeCapacity) !== null && _o !== void 0 ? _o : 1,
});
this.fileTable.addGlobalSecondaryIndex({
indexName: 'query-by-category-id-and-locale',
partitionKey: {
name: 'categoryId',
type: aws_dynamodb_1.AttributeType.STRING,
},
sortKey: {
name: 'locale',
type: aws_dynamodb_1.AttributeType.STRING,
},
projectionType: aws_dynamodb_1.ProjectionType.ALL,
readCapacity: (_q = (_p = props === null || props === void 0 ? void 0 : props.fileTableConfig) === null || _p === void 0 ? void 0 : _p.indexQueryByCategoryIdAndLocale.readCapacity) !== null && _q !== void 0 ? _q : 1,
writeCapacity: (_s = (_r = props === null || props === void 0 ? void 0 : props.fileTableConfig) === null || _r === void 0 ? void 0 : _r.indexQueryByCategoryIdAndLocale.writeCapacity) !== null && _s !== void 0 ? _s : 1,
});
this.fileTable.addGlobalSecondaryIndex({
indexName: 'get-file-by-checksum-and-version',
partitionKey: {
name: 'checksum',
type: aws_dynamodb_1.AttributeType.STRING,
},
sortKey: {
name: 'version',
type: aws_dynamodb_1.AttributeType.STRING,
},
projectionType: aws_dynamodb_1.ProjectionType.ALL,
readCapacity: (_u = (_t = props === null || props === void 0 ? void 0 : props.fileTableConfig) === null || _t === void 0 ? void 0 : _t.indexGetFileByChecksumAndVersion.readCapacity) !== null && _u !== void 0 ? _u : 1,
writeCapacity: (_w = (_v = props === null || props === void 0 ? void 0 : props.fileTableConfig) === null || _v === void 0 ? void 0 : _v.indexGetFileByChecksumAndVersion.writeCapacity) !== null && _w !== void 0 ? _w : 1,
});
this._restApi = new cdk_restapi_1.RestApi(this, 'FileRestApi', {
enableCors: true,
authorizationType: (_x = props === null || props === void 0 ? void 0 : props.authorizationType) !== null && _x !== void 0 ? _x : aws_apigateway_1.AuthorizationType.NONE,
authorizer: (_y = props === null || props === void 0 ? void 0 : props.authorizer) !== null && _y !== void 0 ? _y : undefined,
resources: [
{
path: '/categories',
httpMethod: cdk_restapi_1.HttpMethod.POST,
lambdaFunction: this.createCreateCategoryFunction(),
},
{
path: '/categories',
httpMethod: cdk_restapi_1.HttpMethod.GET,
lambdaFunction: this.createListCategoriesFunction(),
},
{
path: '/categories/{categoryId}',
httpMethod: cdk_restapi_1.HttpMethod.GET,
lambdaFunction: this.createGetCategoryFunction(),
},
{
path: '/categories/{categoryId}',
httpMethod: cdk_restapi_1.HttpMethod.PUT,
lambdaFunction: this.createUpdateCategoryFunction(),
},
{
path: '/categories/{categoryId}',
httpMethod: cdk_restapi_1.HttpMethod.DELETE,
lambdaFunction: this.createDeleteCategoryFunction(),
},
{
path: '/categories/{categoryId}/files',
httpMethod: cdk_restapi_1.HttpMethod.GET,
lambdaFunction: this.createListFilesByCategoryFunction(),
},
{
path: '/files',
httpMethod: cdk_restapi_1.HttpMethod.GET,
lambdaFunction: this.createListFilesFunction(),
},
{
path: '/files',
httpMethod: cdk_restapi_1.HttpMethod.POST,
lambdaFunction: this.createCreateFilesFunction(),
},
{
path: '/files',
httpMethod: cdk_restapi_1.HttpMethod.PUT,
lambdaFunction: this.createUpdateFilesFunction(),
},
{
path: '/files',
httpMethod: cdk_restapi_1.HttpMethod.DELETE,
lambdaFunction: this.createDeleteFilesFunction(),
},
{
path: '/files/{checksum}/versions/{version}',
httpMethod: cdk_restapi_1.HttpMethod.GET,
lambdaFunction: this.createGetFilesFunction(),
},
],
});
}
/**
* File API API ID.
*
* @stability stable
*/
get restApiId() {
return this._restApi.restApiId;
}
createCreateCategoryFunction() {
var _b;
const createCategoryFunction = new aws_lambda_nodejs_1.NodejsFunction(this, 'CreateCategoryFunction', {
entry: `${LAMBDA_ASSETS_PATH}/create-category/app.ts`,
environment: {
CATEGORY_TABLE_NAME: this.categoryTable.tableName,
},
});
(_b = createCategoryFunction.role) === null || _b === void 0 ? void 0 : _b.attachInlinePolicy(new aws_iam_1.Policy(this, 'create-category-policy', {
statements: [
new aws_iam_1.PolicyStatement({
actions: [
'dynamodb:GetItem',
'dynamodb:PutItem',
],
resources: [
this.categoryTable.tableArn,
],
}),
],
}));
return createCategoryFunction;
}
createListCategoriesFunction() {
var _b;
const listCategoriesFunction = new aws_lambda_nodejs_1.NodejsFunction(this, 'ListCategoriesFunction', {
entry: `${LAMBDA_ASSETS_PATH}/list-categories/app.ts`,
environment: {
CATEGORY_TABLE_NAME: this.categoryTable.tableName,
},
});
(_b = listCategoriesFunction.role) === null || _b === void 0 ? void 0 : _b.attachInlinePolicy(new aws_iam_1.Policy(this, 'list-categories-policy', {
statements: [
new aws_iam_1.PolicyStatement({
actions: [
'dynamodb:Query',
'dynamodb:Scan',
'dynamodb:GetItem',
],
resources: [
this.categoryTable.tableArn,
`${this.categoryTable.tableArn}/index/query-by-parent-id`,
],
}),
],
}));
return listCategoriesFunction;
}
createGetCategoryFunction() {
var _b;
const getCategoryFunction = new aws_lambda_nodejs_1.NodejsFunction(this, 'GetCategoryFunction', {
entry: `${LAMBDA_ASSETS_PATH}/get-category/app.ts`,
environment: {
CATEGORY_TABLE_NAME: this.categoryTable.tableName,
},
});
(_b = getCategoryFunction.role) === null || _b === void 0 ? void 0 : _b.attachInlinePolicy(new aws_iam_1.Policy(this, 'get-category-policy', {
statements: [
new aws_iam_1.PolicyStatement({
actions: [
'dynamodb:GetItem',
],
resources: [
this.categoryTable.tableArn,
],
}),
],
}));
return getCategoryFunction;
}
createUpdateCategoryFunction() {
var _b;
const updateCategoryFunction = new aws_lambda_nodejs_1.NodejsFunction(this, 'UpdateCategoryFunction', {
entry: `${LAMBDA_ASSETS_PATH}/update-category/app.ts`,
environment: {
CATEGORY_TABLE_NAME: this.categoryTable.tableName,
},
});
(_b = updateCategoryFunction.role) === null || _b === void 0 ? void 0 : _b.attachInlinePolicy(new aws_iam_1.Policy(this, 'update-category-policy', {
statements: [
new aws_iam_1.PolicyStatement({
actions: [
'dynamodb:GetItem',
'dynamodb:UpdateItem',
],
resources: [
this.categoryTable.tableArn,
],
}),
],
}));
return updateCategoryFunction;
}
createDeleteCategoryFunction() {
var _b;
const deleteCategoryFunction = new aws_lambda_nodejs_1.NodejsFunction(this, 'DeleteCategoryFunction', {
entry: `${LAMBDA_ASSETS_PATH}/delete-category/app.ts`,
environment: {
CATEGORY_TABLE_NAME: this.categoryTable.tableName,
},
});
(_b = deleteCategoryFunction.role) === null || _b === void 0 ? void 0 : _b.attachInlinePolicy(new aws_iam_1.Policy(this, 'delete-category-policy', {
statements: [
new aws_iam_1.PolicyStatement({
actions: [
'dynamodb:DeleteItem',
],
resources: [
this.categoryTable.tableArn,
],
}),
],
}));
return deleteCategoryFunction;
}
createCreateFilesFunction() {
var _b;
const createFilesFunction = new aws_lambda_nodejs_1.NodejsFunction(this, 'CreateFilesFunction', {
entry: `${LAMBDA_ASSETS_PATH}/create-files/app.ts`,
environment: {
FILE_TABLE_NAME: this.fileTable.tableName,
CATEGORY_TABLE_NAME: this.categoryTable.tableName,
},
});
(_b = createFilesFunction.role) === null || _b === void 0 ? void 0 : _b.attachInlinePolicy(new aws_iam_1.Policy(this, 'create-file-policy', {
statements: [
new aws_iam_1.PolicyStatement({
actions: [
'dynamodb:GetItem',
'dynamodb:Query',
'dynamodb:BatchWriteItem',
],
resources: [
this.fileTable.tableArn,
`${this.fileTable.tableArn}/index/get-file-by-checksum-and-version`,
this.categoryTable.tableArn,
],
}),
],
}));
return createFilesFunction;
}
createListFilesFunction() {
var _b;
const listFilesFunction = new aws_lambda_nodejs_1.NodejsFunction(this, 'ListFilesFunction', {
entry: `${LAMBDA_ASSETS_PATH}/list-files/app.ts`,
environment: {
FILE_TABLE_NAME: this.fileTable.tableName,
},
});
(_b = listFilesFunction.role) === null || _b === void 0 ? void 0 : _b.attachInlinePolicy(new aws_iam_1.Policy(this, 'list-files-policy', {
statements: [
new aws_iam_1.PolicyStatement({
actions: [
'dynamodb:Scan',
],
resources: [
this.fileTable.tableArn,
],
}),
],
}));
return listFilesFunction;
}
createListFilesByCategoryFunction() {
var _b;
const listFilesByCategoryFunction = new aws_lambda_nodejs_1.NodejsFunction(this, 'ListFilesByCategoryFunction', {
entry: `${LAMBDA_ASSETS_PATH}/list-files-by-category/app.ts`,
environment: {
FILE_TABLE_NAME: this.fileTable.tableName,
},
});
(_b = listFilesByCategoryFunction.role) === null || _b === void 0 ? void 0 : _b.attachInlinePolicy(new aws_iam_1.Policy(this, 'list-files-by-category-policy', {
statements: [
new aws_iam_1.PolicyStatement({
actions: [
'dynamodb:Query',
],
resources: [
this.fileTable.tableArn,
`${this.fileTable.tableArn}/index/query-by-category-id-and-locale`,
],
}),
],
}));
return listFilesByCategoryFunction;
}
createGetFilesFunction() {
var _b;
const getFilesFunction = new aws_lambda_nodejs_1.NodejsFunction(this, 'GetFilesFunction', {
entry: `${LAMBDA_ASSETS_PATH}/get-files/app.ts`,
environment: {
FILE_TABLE_NAME: this.fileTable.tableName,
},
});
(_b = getFilesFunction.role) === null || _b === void 0 ? void 0 : _b.attachInlinePolicy(new aws_iam_1.Policy(this, 'get-files-policy', {
statements: [
new aws_iam_1.PolicyStatement({
actions: [
'dynamodb:Query',
],
resources: [
this.fileTable.tableArn,
],
}),
],
}));
return getFilesFunction;
}
createUpdateFilesFunction() {
var _b;
const updateFilesFunction = new aws_lambda_nodejs_1.NodejsFunction(this, 'UpdateFilesFunction', {
entry: `${LAMBDA_ASSETS_PATH}/update-files/app.ts`,
environment: {
FILE_TABLE_NAME: this.fileTable.tableName,
},
});
(_b = updateFilesFunction.role) === null || _b === void 0 ? void 0 : _b.attachInlinePolicy(new aws_iam_1.Policy(this, 'update-file-policy', {
statements: [
new aws_iam_1.PolicyStatement({
actions: [
'dynamodb:BatchWriteItem',
'dynamodb:BatchGetItem',
],
resources: [
this.fileTable.tableArn,
],
}),
],
}));
return updateFilesFunction;
}
createDeleteFilesFunction() {
var _b;
const deleteFilesFunction = new aws_lambda_nodejs_1.NodejsFunction(this, 'DeleteFilesFunction', {
entry: `${LAMBDA_ASSETS_PATH}/delete-files/app.ts`,
environment: {
FILE_TABLE_NAME: this.fileTable.tableName,
},
});
(_b = deleteFilesFunction.role) === null || _b === void 0 ? void 0 : _b.attachInlinePolicy(new aws_iam_1.Policy(this, 'delete-file-policy', {
statements: [
new aws_iam_1.PolicyStatement({
actions: [
'dynamodb:BatchWriteItem',
],
resources: [
this.fileTable.tableArn,
],
}),
],
}));
return deleteFilesFunction;
}
}
exports.FileApi = FileApi;
_a = JSII_RTTI_SYMBOL_1;
FileApi[_a] = { fqn: "@softchef/cdk-iot-device-management.FileApi", version: "2.0.0" };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsZS1hcGkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvZmlsZS1hcGkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSw2QkFBNkI7QUFDN0IsdURBRytCO0FBQy9CLCtEQUdvQztBQUNwQywyREFJa0M7QUFDbEMsaURBRzZCO0FBQzdCLHFFQUV1QztBQUN2QywyQ0FFb0I7QUFFcEIsTUFBTSxrQkFBa0IsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsRUFBRSx3QkFBd0IsQ0FBQyxDQUFDOzs7Ozs7QUF5QzdFLE1BQWEsT0FBUSxTQUFRLHNCQUFTOzs7O0lBVXBDLFlBQVksS0FBZ0IsRUFBRSxFQUFVLEVBQUUsS0FBb0I7O1FBQzVELEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDakIsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLG9CQUFLLENBQUMsSUFBSSxFQUFFLGVBQWUsRUFBRTtZQUNwRCxZQUFZLEVBQUU7Z0JBQ1osSUFBSSxFQUFFLFlBQVk7Z0JBQ2xCLElBQUksRUFBRSw0QkFBYSxDQUFDLE1BQU07YUFDM0I7WUFDRCxZQUFZLGNBQUUsS0FBSyxhQUFMLEtBQUssdUJBQUwsS0FBSyxDQUFFLG1CQUFtQiwwQ0FBRSxZQUFZLENBQUMsWUFBWSxtQ0FBSSxDQUFDO1lBQ3hFLGFBQWEsY0FBRSxLQUFLLGFBQUwsS0FBSyx1QkFBTCxLQUFLLENBQUUsbUJBQW1CLDBDQUFFLFlBQVksQ0FBQyxhQUFhLG1DQUFJLENBQUM7U0FDM0UsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxDQUFDLGFBQWEsQ0FBQyx1QkFBdUIsQ0FBQztZQUN6QyxTQUFTLEVBQUUsb0JBQW9CO1lBQy9CLFlBQVksRUFBRTtnQkFDWixJQUFJLEVBQUUsVUFBVTtnQkFDaEIsSUFBSSxFQUFFLDRCQUFhLENBQUMsTUFBTTthQUMzQjtZQUNELGNBQWMsRUFBRSw2QkFBYyxDQUFDLEdBQUc7WUFDbEMsWUFBWSxjQUFFLEtBQUss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QkFDVixJQUFJLHlCQUFlLENBQUM7b0JBQ2xCLE9BQU8sRUFBRTt3QkFDUCx5QkFBeUI7cUJBQzFCO29CQUNELFNBQVMsRUFBRTt3QkFDVCxJQUFJLENBQUMsU0FBUyxDQUFDLFFBQVE7cUJBQ3hCO2lCQUNGLENBQUM7YUFDSDtTQUNGLENBQUMsRUFDRjtRQUNGLE9BQU8sbUJBQW1CLENBQUM7SUFDN0IsQ0FBQzs7QUExWkgsMEJBMlpDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCB7XG4gIFJlc3RBcGksXG4gIEh0dHBNZXRob2QsXG59IGZyb20gJ0Bzb2Z0Y2hlZi9jZGstcmVzdGFwaSc7XG5pbXBvcnQge1xuICBBdXRob3JpemF0aW9uVHlwZSxcbiAgSUF1dGhvcml6ZXIsXG59IGZyb20gJ2F3cy1jZGstbGliL2F3cy1hcGlnYXRld2F5JztcbmltcG9ydCB7XG4gIEF0dHJpYnV0ZVR5cGUsXG4gIFByb2plY3Rpb25UeXBlLFxuICBUYWJsZSxcbn0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWR5bmFtb2RiJztcbmltcG9ydCB7XG4gIFBvbGljeSxcbiAgUG9saWN5U3RhdGVtZW50LFxufSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtaWFtJztcbmltcG9ydCB7XG4gIE5vZGVqc0Z1bmN0aW9uLFxufSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtbGFtYmRhLW5vZGVqcyc7XG5pbXBvcnQge1xuICBDb25zdHJ1Y3QsXG59IGZyb20gJ2NvbnN0cnVjdHMnO1xuXG5jb25zdCBMQU1CREFfQVNTRVRTX1BBVEggPSBwYXRoLnJlc29sdmUoX19kaXJuYW1lLCAnLi4vbGFtYmRhLWFzc2V0cy9maWxlcycpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG5leHBvcnQgaW50ZXJmYWNlIENhcGFjaXR5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHJlYWRvbmx5IHdyaXRlQ2FwYWNpdHk/OiBudW1iZXI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHJlYWRvbmx5IHJlYWRDYXBhY2l0eT86IG51bWJlcjtcbn1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbmV4cG9ydCBpbnRlcmZhY2UgQ2F0ZWdvcnlUYWJsZUNvbmZpZyB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHJlYWRvbmx5IHByaW1hcnlJbmRleDogQ2FwYWNpdHk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcmVhZG9ubHkgaW5kZXhRdWVyeUJ5UGFyZW50SWQ6IENhcGFjaXR5O1xufVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG5leHBvcnQgaW50ZXJmYWNlIEZpbGVUYWJsZUNvbmZpZyB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHJlYWRvbmx5IHByaW1hcnlJbmRleDogQ2FwYWNpdHk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICByZWFkb25seSBpbmRleFF1ZXJ5QnlDYXRlZ29yeUlkQW5kTG9jYWxlOiBDYXBhY2l0eTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICByZWFkb25seSBpbmRleEdldEZpbGVCeUNoZWNrc3VtQW5kVmVyc2lvbjogQ2FwYWNpdHk7XG59XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICBcbmV4cG9ydCBpbnRlcmZhY2UgRmlsZUFwaVByb3BzIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcmVhZG9ubHkgYXV0aG9yaXphdGlvblR5cGU/OiBBdXRob3JpemF0aW9uVHlwZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcmVhZG9ubHkgYXV0aG9yaXplcj86IElBdXRob3JpemVyIHwgdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHJlYWRvbmx5IGNhdGVnb3J5VGFibGVDb25maWc/OiBDYXRlZ29yeVRhYmxlQ29uZmlnO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcmVhZG9ubHkgZmlsZVRhYmxlQ29uZmlnPzogRmlsZVRhYmxlQ29uZmlnO1xufVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuZXhwb3J0IGNsYXNzIEZpbGVBcGkgZXh0ZW5kcyBDb25zdHJ1Y3Qge1xuICAvKipcbiAgICogVGhlIEZpbGUgQVBJIEdhdGV3YXlcbiAgICovXG4gIHByaXZhdGUgcmVhZG9ubHkgX3Jlc3RBcGk6IFJlc3RBcGk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICBwdWJsaWMgcmVhZG9ubHkgY2F0ZWdvcnlUYWJsZTogVGFibGU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHB1YmxpYyByZWFkb25seSBmaWxlVGFibGU6IFRhYmxlO1xuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzPzogRmlsZUFwaVByb3BzKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkKTtcbiAgICB0aGlzLmNhdGVnb3J5VGFibGUgPSBuZXcgVGFibGUodGhpcywgJ0NhdGVnb3J5VGFibGUnLCB7XG4gICAgICBwYXJ0aXRpb25LZXk6IHtcbiAgICAgICAgbmFtZTogJ2NhdGVnb3J5SWQnLFxuICAgICAgICB0eXBlOiBBdHRyaWJ1dGVUeXBlLlNUUklORyxcbiAgICAgIH0sXG4gICAgICByZWFkQ2FwYWNpdHk6IHByb3BzPy5jYXRlZ29yeVRhYmxlQ29uZmlnPy5wcmltYXJ5SW5kZXgucmVhZENhcGFjaXR5ID8/IDEsXG4gICAgICB3cml0ZUNhcGFjaXR5OiBwcm9wcz8uY2F0ZWdvcnlUYWJsZUNvbmZpZz8ucHJpbWFyeUluZGV4LndyaXRlQ2FwYWNpdHkgPz8gMSxcbiAgICB9KTtcbiAgICB0aGlzLmNhdGVnb3J5VGFibGUuYWRkR2xvYmFsU2Vjb25kYXJ5SW5kZXgoe1xuICAgICAgaW5kZXhOYW1lOiAncXVlcnktYnktcGFyZW50LWlkJyxcbiAgICAgIHBhcnRpdGlvbktleToge1xuICAgICAgICBuYW1lOiAncGFyZW50SWQnLFxuICAgICAgICB0eXBlOiBBdHRyaWJ1dGVUeXBlLlNUUklORyxcbiAgICAgIH0sXG4gICAgICBwcm9qZWN0aW9uVHlwZTogUHJvamVjdGlvblR5cGUuQUxMLFxuICAgICAgcmVhZENhcGFjaXR5OiBwcm9wcz8uY2F0ZWdvcnlUYWJsZUNvbmZpZz8uaW5kZXhRdWVyeUJ5UGFyZW50SWQucmVhZENhcGFjaXR5ID8/IDEsXG4gICAgICB3cml0ZUNhcGFjaXR5OiBwcm9wcz8uY2F0ZWdvcnlUYWJsZUNvbmZpZz8uaW5kZXhRdWVyeUJ5UGFyZW50SWQud3JpdGVDYXBhY2l0eSA/PyAxLFxuICAgIH0pO1xuICAgIHRoaXMuZmlsZVRhYmxlID0gbmV3IFRhYmxlKHRoaXMsICdGaWxlVGFibGUnLCB7XG4gICAgICBwYXJ0aXRpb25LZXk6IHtcbiAgICAgICAgbmFtZTogJ2ZpbGVJZCcsXG4gICAgICAgIHR5cGU6IEF0dHJpYnV0ZVR5cGUuU1RSSU5HLFxuICAgICAgfSxcbiAgICAgIHJlYWRDYXBhY2l0eTogcHJvcHM/LmZpbGVUYWJsZUNvbmZpZz8ucHJpbWFyeUluZGV4LnJlYWRDYXBhY2l0eSA/PyAxLFxuICAgICAgd3JpdGVDYXBhY2l0eTogcHJvcHM/LmZpbGVUYWJsZUNvbmZpZz8ucHJpbWFyeUluZGV4LndyaXRlQ2FwYWNpdHkgPz8gMSxcbiAgICB9KTtcbiAgICB0aGlzLmZpbGVUYWJsZS5hZGRHbG9iYWxTZWNvbmRhcnlJbmRleCh7XG4gICAgICBpbmRleE5hbWU6ICdxdWVyeS1ieS1jYXRlZ29yeS1pZC1hbmQtbG9jYWxlJyxcbiAgICAgIHBhcnRpdGlvbktleToge1xuICAgICAgICBuYW1lOiAnY2F0ZWdvcnlJZCcsXG4gICAgICAgIHR5cGU6IEF0dHJpYnV0ZVR5cGUuU1RSSU5HLFxuICAgICAgfSxcbiAgICAgIHNvcnRLZXk6IHtcbiAgICAgICAgbmFtZTogJ2xvY2FsZScsXG4gICAgICAgIHR5cGU6IEF0dHJpYnV0ZVR5cGUuU1RSSU5HLFxuICAgICAgfSxcbiAgICAgIHByb2plY3Rpb25UeXBlOiBQcm9qZWN0aW9uVHlwZS5BTEwsXG4gICAgICByZWFkQ2FwYWNpdHk6IHByb3BzPy5maWxlVGFibGVDb25maWc/LmluZGV4UXVlcnlCeUNhdGVnb3J5SWRBbmRMb2NhbGUucmVhZENhcGFjaXR5ID8/IDEsXG4gICAgICB3cml0ZUNhcGFjaXR5OiBwcm9wcz8uZmlsZVRhYmxlQ29uZmlnPy5pbmRleFF1ZXJ5QnlDYXRlZ29yeUlkQW5kTG9jYWxlLndyaXRlQ2FwYWNpdHkgPz8gMSxcbiAgICB9KTtcbiAgICB0aGlzLmZpbGVUYWJsZS5hZGRHbG9iYWxTZWNvbmRhcnlJbmRleCh7XG4gICAgICBpbmRleE5hbWU6ICdnZXQtZmlsZS1ieS1jaGVja3N1bS1hbmQtdmVyc2lvbicsXG4gICAgICBwYXJ0aXRpb25LZXk6IHtcbiAgICAgICAgbmFtZTogJ2NoZWNrc3VtJyxcbiAgICAgICAgdHlwZTogQXR0cmlidXRlVHlwZS5TVFJJTkcsXG4gICAgICB9LFxuICAgICAgc29ydEtleToge1xuICAgICAgICBuYW1lOiAndmVyc2lvbicsXG4gICAgICAgIHR5cGU6IEF0dHJpYnV0ZVR5cGUuU1RSSU5HLFxuICAgICAgfSxcbiAgICAgIHByb2plY3Rpb25UeXBlOiBQcm9qZWN0aW9uVHlwZS5BTEwsXG4gICAgICByZWFkQ2FwYWNpdHk6IHByb3BzPy5maWxlVGFibGVDb25maWc/LmluZGV4R2V0RmlsZUJ5Q2hlY2tzdW1BbmRWZXJzaW9uLnJlYWRDYXBhY2l0eSA/PyAxLFxuICAgICAgd3JpdGVDYXBhY2l0eTogcHJvcHM/LmZpbGVUYWJsZUNvbmZpZz8uaW5kZXhHZXRGaWxlQnlDaGVja3N1bUFuZFZlcnNpb24ud3JpdGVDYXBhY2l0eSA/PyAxLFxuICAgIH0pO1xuXG4gICAgdGhpcy5fcmVzdEFwaSA9IG5ldyBSZXN0QXBpKHRoaXMsICdGaWxlUmVzdEFwaScsIHtcbiAgICAgIGVuYWJsZUNvcnM6IHRydWUsXG4gICAgICBhdXRob3JpemF0aW9uVHlwZTogcHJvcHM/LmF1dGhvcml6YXRpb25UeXBlID8/IEF1dGhvcml6YXRpb25UeXBlLk5PTkUsXG4gICAgICBhdXRob3JpemVyOiBwcm9wcz8uYXV0aG9yaXplciA/PyB1bmRlZmluZWQsXG4gICAgICByZXNvdXJjZXM6IFtcbiAgICAgICAge1xuICAgICAgICAgIHBhdGg6ICcvY2F0ZWdvcmllcycsXG4gICAgICAgICAgaHR0cE1ldGhvZDogSHR0cE1ldGhvZC5QT1NULFxuICAgICAgICAgIGxhbWJkYUZ1bmN0aW9uOiB0aGlzLmNyZWF0ZUNyZWF0ZUNhdGVnb3J5RnVuY3Rpb24oKSxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIHBhdGg6ICcvY2F0ZWdvcmllcycsXG4gICAgICAgICAgaHR0cE1ldGhvZDogSHR0cE1ldGhvZC5HRVQsXG4gICAgICAgICAgbGFtYmRhRnVuY3Rpb246IHRoaXMuY3JlYXRlTGlzdENhdGVnb3JpZXNGdW5jdGlvbigpLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgcGF0aDogJy9jYXRlZ29yaWVzL3tjYXRlZ29yeUlkfScsXG4gICAgICAgICAgaHR0cE1ldGhvZDogSHR0cE1ldGhvZC5HRVQsXG4gICAgICAgICAgbGFtYmRhRnVuY3Rpb246IHRoaXMuY3JlYXRlR2V0Q2F0ZWdvcnlGdW5jdGlvbigpLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgcGF0aDogJy9jYXRlZ29yaWVzL3tjYXRlZ29yeUlkfScsXG4gICAgICAgICAgaHR0cE1ldGhvZDogSHR0cE1ldGhvZC5QVVQsXG4gICAgICAgICAgbGFtYmRhRnVuY3Rpb246IHRoaXMuY3JlYXRlVXBkYXRlQ2F0ZWdvcnlGdW5jdGlvbigpLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgcGF0aDogJy9jYXRlZ29yaWVzL3tjYXRlZ29yeUlkfScsXG4gICAgICAgICAgaHR0cE1ldGhvZDogSHR0cE1ldGhvZC5ERUxFVEUsXG4gICAgICAgICAgbGFtYmRhRnVuY3Rpb246IHRoaXMuY3JlYXRlRGVsZXRlQ2F0ZWdvcnlGdW5jdGlvbigpLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgcGF0aDogJy9jYXRlZ29yaWVzL3tjYXRlZ29yeUlkfS9maWxlcycsXG4gICAgICAgICAgaHR0cE1ldGhvZDogSHR0cE1ldGhvZC5HRVQsXG4gICAgICAgICAgbGFtYmRhRnVuY3Rpb246IHRoaXMuY3JlYXRlTGlzdEZpbGVzQnlDYXRlZ29yeUZ1bmN0aW9uKCksXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBwYXRoOiAnL2ZpbGVzJyxcbiAgICAgICAgICBodHRwTWV0aG9kOiBIdHRwTWV0aG9kLkdFVCxcbiAgICAgICAgICBsYW1iZGFGdW5jdGlvbjogdGhpcy5jcmVhdGVMaXN0RmlsZXNGdW5jdGlvbigpLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgcGF0aDogJy9maWxlcycsXG4gICAgICAgICAgaHR0cE1ldGhvZDogSHR0cE1ldGhvZC5QT1NULFxuICAgICAgICAgIGxhbWJkYUZ1bmN0aW9uOiB0aGlzLmNyZWF0ZUNyZWF0ZUZpbGVzRnVuY3Rpb24oKSxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIHBhdGg6ICcvZmlsZXMnLFxuICAgICAgICAgIGh0dHBNZXRob2Q6IEh0dHBNZXRob2QuUFVULFxuICAgICAgICAgIGxhbWJkYUZ1bmN0aW9uOiB0aGlzLmNyZWF0ZVVwZGF0ZUZpbGVzRnVuY3Rpb24oKSxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIHBhdGg6ICcvZmlsZXMnLFxuICAgICAgICAgIGh0dHBNZXRob2Q6IEh0dHBNZXRob2QuREVMRVRFLFxuICAgICAgICAgIGxhbWJkYUZ1bmN0aW9uOiB0aGlzLmNyZWF0ZURlbGV0ZUZpbGVzRnVuY3Rpb24oKSxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIHBhdGg6ICcvZmlsZXMve2NoZWNrc3VtfS92ZXJzaW9ucy97dmVyc2lvbn0nLFxuICAgICAgICAgIGh0dHBNZXRob2Q6IEh0dHBNZXRob2QuR0VULFxuICAgICAgICAgIGxhbWJkYUZ1bmN0aW9uOiB0aGlzLmNyZWF0ZUdldEZpbGVzRnVuY3Rpb24oKSxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfSk7XG4gIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgZ2V0IHJlc3RBcGlJZCgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLl9yZXN0QXBpLnJlc3RBcGlJZDtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlQ3JlYXRlQ2F0ZWdvcnlGdW5jdGlvbigpOiBOb2RlanNGdW5jdGlvbiB7XG4gICAgY29uc3QgY3JlYXRlQ2F0ZWdvcnlGdW5jdGlvbiA9IG5ldyBOb2RlanNGdW5jdGlvbih0aGlzLCAnQ3JlYXRlQ2F0ZWdvcnlGdW5jdGlvbicsIHtcbiAgICAgIGVudHJ5OiBgJHtMQU1CREFfQVNTRVRTX1BBVEh9L2NyZWF0ZS1jYXRlZ29yeS9hcHAudHNgLFxuICAgICAgZW52aXJvbm1lbnQ6IHtcbiAgICAgICAgQ0FURUdPUllfVEFCTEVfTkFNRTogdGhpcy5jYXRlZ29yeVRhYmxlLnRhYmxlTmFtZSxcbiAgICAgIH0sXG4gICAgfSk7XG4gICAgY3JlYXRlQ2F0ZWdvcnlGdW5jdGlvbi5yb2xlPy5hdHRhY2hJbmxpbmVQb2xpY3koXG4gICAgICBuZXcgUG9saWN5KHRoaXMsICdjcmVhdGUtY2F0ZWdvcnktcG9saWN5Jywge1xuICAgICAgICBzdGF0ZW1lbnRzOiBbXG4gICAgICAgICAgbmV3IFBvbGljeVN0YXRlbWVudCh7XG4gICAgICAgICAgICBhY3Rpb25zOiBbXG4gICAgICAgICAgICAgICdkeW5hbW9kYjpHZXRJdGVtJyxcbiAgICAgICAgICAgICAgJ2R5bmFtb2RiOlB1dEl0ZW0nLFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIHJlc291cmNlczogW1xuICAgICAgICAgICAgICB0aGlzLmNhdGVnb3J5VGFibGUudGFibGVBcm4sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0pLFxuICAgICAgICBdLFxuICAgICAgfSksXG4gICAgKTtcbiAgICByZXR1cm4gY3JlYXRlQ2F0ZWdvcnlGdW5jdGlvbjtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlTGlzdENhdGVnb3JpZXNGdW5jdGlvbigpOiBOb2RlanNGdW5jdGlvbiB7XG4gICAgY29uc3QgbGlzdENhdGVnb3JpZXNGdW5jdGlvbiA9IG5ldyBOb2RlanNGdW5jdGlvbih0aGlzLCAnTGlzdENhdGVnb3JpZXNGdW5jdGlvbicsIHtcbiAgICAgIGVudHJ5OiBgJHtMQU1CREFfQVNTRVRTX1BBVEh9L2xpc3QtY2F0ZWdvcmllcy9hcHAudHNgLFxuICAgICAgZW52aXJvbm1lbnQ6IHtcbiAgICAgICAgQ0FURUdPUllfVEFCTEVfTkFNRTogdGhpcy5jYXRlZ29yeVRhYmxlLnRhYmxlTmFtZSxcbiAgICAgIH0sXG4gICAgfSk7XG4gICAgbGlzdENhdGVnb3JpZXNGdW5jdGlvbi5yb2xlPy5hdHRhY2hJbmxpbmVQb2xpY3koXG4gICAgICBuZXcgUG9saWN5KHRoaXMsICdsaXN0LWNhdGVnb3JpZXMtcG9saWN5Jywge1xuICAgICAgICBzdGF0ZW1lbnRzOiBbXG4gICAgICAgICAgbmV3IFBvbGljeVN0YXRlbWVudCh7XG4gICAgICAgICAgICBhY3Rpb25zOiBbXG4gICAgICAgICAgICAgICdkeW5hbW9kYjpRdWVyeScsXG4gICAgICAgICAgICAgICdkeW5hbW9kYjpTY2FuJyxcbiAgICAgICAgICAgICAgJ2R5bmFtb2RiOkdldEl0ZW0nLFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIHJlc291cmNlczogW1xuICAgICAgICAgICAgICB0aGlzLmNhdGVnb3J5VGFibGUudGFibGVBcm4sXG4gICAgICAgICAgICAgIGAke3RoaXMuY2F0ZWdvcnlUYWJsZS50YWJsZUFybn0vaW5kZXgvcXVlcnktYnktcGFyZW50LWlkYCxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSksXG4gICAgICAgIF0sXG4gICAgICB9KSxcbiAgICApO1xuICAgIHJldHVybiBsaXN0Q2F0ZWdvcmllc0Z1bmN0aW9uO1xuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVHZXRDYXRlZ29yeUZ1bmN0aW9uKCk6IE5vZGVqc0Z1bmN0aW9uIHtcbiAgICBjb25zdCBnZXRDYXRlZ29yeUZ1bmN0aW9uID0gbmV3IE5vZGVqc0Z1bmN0aW9uKHRoaXMsICdHZXRDYXRlZ29yeUZ1bmN0aW9uJywge1xuICAgICAgZW50cnk6IGAke0xBTUJEQV9BU1NFVFNfUEFUSH0vZ2V0LWNhdGVnb3J5L2FwcC50c2AsXG4gICAgICBlbnZpcm9ubWVudDoge1xuICAgICAgICBDQVRFR09SWV9UQUJMRV9OQU1FOiB0aGlzLmNhdGVnb3J5VGFibGUudGFibGVOYW1lLFxuICAgICAgfSxcbiAgICB9KTtcbiAgICBnZXRDYXRlZ29yeUZ1bmN0aW9uLnJvbGU/LmF0dGFjaElubGluZVBvbGljeShcbiAgICAgIG5ldyBQb2xpY3kodGhpcywgJ2dldC1jYXRlZ29yeS1wb2xpY3knLCB7XG4gICAgICAgIHN0YXRlbWVudHM6IFtcbiAgICAgICAgICBuZXcgUG9saWN5U3RhdGVtZW50KHtcbiAgICAgICAgICAgIGFjdGlvbnM6IFtcbiAgICAgICAgICAgICAgJ2R5bmFtb2RiOkdldEl0ZW0nLFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIHJlc291cmNlczogW1xuICAgICAgICAgICAgICB0aGlzLmNhdGVnb3J5VGFibGUudGFibGVBcm4sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0pLFxuICAgICAgICBdLFxuICAgICAgfSksXG4gICAgKTtcbiAgICByZXR1cm4gZ2V0Q2F0ZWdvcnlGdW5jdGlvbjtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlVXBkYXRlQ2F0ZWdvcnlGdW5jdGlvbigpOiBOb2RlanNGdW5jdGlvbiB7XG4gICAgY29uc3QgdXBkYXRlQ2F0ZWdvcnlGdW5jdGlvbiA9IG5ldyBOb2RlanNGdW5jdGlvbih0aGlzLCAnVXBkYXRlQ2F0ZWdvcnlGdW5jdGlvbicsIHtcbiAgICAgIGVudHJ5OiBgJHtMQU1CREFfQVNTRVRTX1BBVEh9L3VwZGF0ZS1jYXRlZ29yeS9hcHAudHNgLFxuICAgICAgZW52aXJvbm1lbnQ6IHtcbiAgICAgICAgQ0FURUdPUllfVEFCTEVfTkFNRTogdGhpcy5jYXRlZ29yeVRhYmxlLnRhYmxlTmFtZSxcbiAgICAgIH0sXG4gICAgfSk7XG4gICAgdXBkYXRlQ2F0ZWdvcnlGdW5jdGlvbi5yb2xlPy5hdHRhY2hJbmxpbmVQb2xpY3koXG4gICAgICBuZXcgUG9saWN5KHRoaXMsICd1cGRhdGUtY2F0ZWdvcnktcG9saWN5Jywge1xuICAgICAgICBzdGF0ZW1lbnRzOiBbXG4gICAgICAgICAgbmV3IFBvbGljeVN0YXRlbWVudCh7XG4gICAgICAgICAgICBhY3Rpb25zOiBbXG4gICAgICAgICAgICAgICdkeW5hbW9kYjpHZXRJdGVtJyxcbiAgICAgICAgICAgICAgJ2R5bmFtb2RiOlVwZGF0ZUl0ZW0nLFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIHJlc291cmNlczogW1xuICAgICAgICAgICAgICB0aGlzLmNhdGVnb3J5VGFibGUudGFibGVBcm4sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0pLFxuICAgICAgICBdLFxuICAgICAgfSksXG4gICAgKTtcbiAgICByZXR1cm4gdXBkYXRlQ2F0ZWdvcnlGdW5jdGlvbjtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlRGVsZXRlQ2F0ZWdvcnlGdW5jdGlvbigpOiBOb2RlanNGdW5jdGlvbiB7XG4gICAgY29uc3QgZGVsZXRlQ2F0ZWdvcnlGdW5jdGlvbiA9IG5ldyBOb2RlanNGdW5jdGlvbih0aGlzLCAnRGVsZXRlQ2F0ZWdvcnlGdW5jdGlvbicsIHtcbiAgICAgIGVudHJ5OiBgJHtMQU1CREFfQVNTRVRTX1BBVEh9L2RlbGV0ZS1jYXRlZ29yeS9hcHAudHNgLFxuICAgICAgZW52aXJvbm1lbnQ6IHtcbiAgICAgICAgQ0FURUdPUllfVEFCTEVfTkFNRTogdGhpcy5jYXRlZ29yeVRhYmxlLnRhYmxlTmFtZSxcbiAgICAgIH0sXG4gICAgfSk7XG4gICAgZGVsZXRlQ2F0ZWdvcnlGdW5jdGlvbi5yb2xlPy5hdHRhY2hJbmxpbmVQb2xpY3koXG4gICAgICBuZXcgUG9saWN5KHRoaXMsICdkZWxldGUtY2F0ZWdvcnktcG9saWN5Jywge1xuICAgICAgICBzdGF0ZW1lbnRzOiBbXG4gICAgICAgICAgbmV3IFBvbGljeVN0YXRlbWVudCh7XG4gICAgICAgICAgICBhY3Rpb25zOiBbXG4gICAgICAgICAgICAgICdkeW5hbW9kYjpEZWxldGVJdGVtJyxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICByZXNvdXJjZXM6IFtcbiAgICAgICAgICAgICAgdGhpcy5jYXRlZ29yeVRhYmxlLnRhYmxlQXJuLFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9KSxcbiAgICAgICAgXSxcbiAgICAgIH0pLFxuICAgICk7XG4gICAgcmV0dXJuIGRlbGV0ZUNhdGVnb3J5RnVuY3Rpb247XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZUNyZWF0ZUZpbGVzRnVuY3Rpb24oKTogTm9kZWpzRnVuY3Rpb24ge1xuICAgIGNvbnN0IGNyZWF0ZUZpbGVzRnVuY3Rpb24gPSBuZXcgTm9kZWpzRnVuY3Rpb24odGhpcywgJ0NyZWF0ZUZpbGVzRnVuY3Rpb24nLCB7XG4gICAgICBlbnRyeTogYCR7TEFNQkRBX0FTU0VUU19QQVRIfS9jcmVhdGUtZmlsZXMvYXBwLnRzYCxcbiAgICAgIGVudmlyb25tZW50OiB7XG4gICAgICAgIEZJTEVfVEFCTEVfTkFNRTogdGhpcy5maWxlVGFibGUudGFibGVOYW1lLFxuICAgICAgICBDQVRFR09SWV9UQUJMRV9OQU1FOiB0aGlzLmNhdGVnb3J5VGFibGUudGFibGVOYW1lLFxuICAgICAgfSxcbiAgICB9KTtcbiAgICBjcmVhdGVGaWxlc0Z1bmN0aW9uLnJvbGU/LmF0dGFjaElubGluZVBvbGljeShcbiAgICAgIG5ldyBQb2xpY3kodGhpcywgJ2NyZWF0ZS1maWxlLXBvbGljeScsIHtcbiAgICAgICAgc3RhdGVtZW50czogW1xuICAgICAgICAgIG5ldyBQb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICAgICAgYWN0aW9uczogW1xuICAgICAgICAgICAgICAnZHluYW1vZGI6R2V0SXRlbScsXG4gICAgICAgICAgICAgICdkeW5hbW9kYjpRdWVyeScsXG4gICAgICAgICAgICAgICdkeW5hbW9kYjpCYXRjaFdyaXRlSXRlbScsXG4gICAgICAgICAgICBdLFxuICAgICAgICAgICAgcmVzb3VyY2VzOiBbXG4gICAgICAgICAgICAgIHRoaXMuZmlsZVRhYmxlLnRhYmxlQXJuLFxuICAgICAgICAgICAgICBgJHt0aGlzLmZpbGVUYWJsZS50YWJsZUFybn0vaW5kZXgvZ2V0LWZpbGUtYnktY2hlY2tzdW0tYW5kLXZlcnNpb25gLFxuICAgICAgICAgICAgICB0aGlzLmNhdGVnb3J5VGFibGUudGFibGVBcm4sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0pLFxuICAgICAgICBdLFxuICAgICAgfSksXG4gICAgKTtcbiAgICByZXR1cm4gY3JlYXRlRmlsZXNGdW5jdGlvbjtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlTGlzdEZpbGVzRnVuY3Rpb24oKTogTm9kZWpzRnVuY3Rpb24ge1xuICAgIGNvbnN0IGxpc3RGaWxlc0Z1bmN0aW9uID0gbmV3IE5vZGVqc0Z1bmN0aW9uKHRoaXMsICdMaXN0RmlsZXNGdW5jdGlvbicsIHtcbiAgICAgIGVudHJ5OiBgJHtMQU1CREFfQVNTRVRTX1BBVEh9L2xpc3QtZmlsZXMvYXBwLnRzYCxcbiAgICAgIGVudmlyb25tZW50OiB7XG4gICAgICAgIEZJTEVfVEFCTEVfTkFNRTogdGhpcy5maWxlVGFibGUudGFibGVOYW1lLFxuICAgICAgfSxcbiAgICB9KTtcbiAgICBsaXN0RmlsZXNGdW5jdGlvbi5yb2xlPy5hdHRhY2hJbmxpbmVQb2xpY3koXG4gICAgICBuZXcgUG9saWN5KHRoaXMsICdsaXN0LWZpbGVzLXBvbGljeScsIHtcbiAgICAgICAgc3RhdGVtZW50czogW1xuICAgICAgICAgIG5ldyBQb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICAgICAgYWN0aW9uczogW1xuICAgICAgICAgICAgICAnZHluYW1vZGI6U2NhbicsXG4gICAgICAgICAgICBdLFxuICAgICAgICAgICAgcmVzb3VyY2VzOiBbXG4gICAgICAgICAgICAgIHRoaXMuZmlsZVRhYmxlLnRhYmxlQXJuLFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9KSxcbiAgICAgICAgXSxcbiAgICAgIH0pLFxuICAgICk7XG4gICAgcmV0dXJuIGxpc3RGaWxlc0Z1bmN0aW9uO1xuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVMaXN0RmlsZXNCeUNhdGVnb3J5RnVuY3Rpb24oKTogTm9kZWpzRnVuY3Rpb24ge1xuICAgIGNvbnN0IGxpc3RGaWxlc0J5Q2F0ZWdvcnlGdW5jdGlvbiA9IG5ldyBOb2RlanNGdW5jdGlvbih0aGlzLCAnTGlzdEZpbGVzQnlDYXRlZ29yeUZ1bmN0aW9uJywge1xuICAgICAgZW50cnk6IGAke0xBTUJEQV9BU1NFVFNfUEFUSH0vbGlzdC1maWxlcy1ieS1jYXRlZ29yeS9hcHAudHNgLFxuICAgICAgZW52aXJvbm1lbnQ6IHtcbiAgICAgICAgRklMRV9UQUJMRV9OQU1FOiB0aGlzLmZpbGVUYWJsZS50YWJsZU5hbWUsXG4gICAgICB9LFxuICAgIH0pO1xuICAgIGxpc3RGaWxlc0J5Q2F0ZWdvcnlGdW5jdGlvbi5yb2xlPy5hdHRhY2hJbmxpbmVQb2xpY3koXG4gICAgICBuZXcgUG9saWN5KHRoaXMsICdsaXN0LWZpbGVzLWJ5LWNhdGVnb3J5LXBvbGljeScsIHtcbiAgICAgICAgc3RhdGVtZW50czogW1xuICAgICAgICAgIG5ldyBQb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICAgICAgYWN0aW9uczogW1xuICAgICAgICAgICAgICAnZHluYW1vZGI6UXVlcnknLFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIHJlc291cmNlczogW1xuICAgICAgICAgICAgICB0aGlzLmZpbGVUYWJsZS50YWJsZUFybixcbiAgICAgICAgICAgICAgYCR7dGhpcy5maWxlVGFibGUudGFibGVBcm59L2luZGV4L3F1ZXJ5LWJ5LWNhdGVnb3J5LWlkLWFuZC1sb2NhbGVgLFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9KSxcbiAgICAgICAgXSxcbiAgICAgIH0pLFxuICAgICk7XG4gICAgcmV0dXJuIGxpc3RGaWxlc0J5Q2F0ZWdvcnlGdW5jdGlvbjtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlR2V0RmlsZXNGdW5jdGlvbigpOiBOb2RlanNGdW5jdGlvbiB7XG4gICAgY29uc3QgZ2V0RmlsZXNGdW5jdGlvbiA9IG5ldyBOb2RlanNGdW5jdGlvbih0aGlzLCAnR2V0RmlsZXNGdW5jdGlvbicsIHtcbiAgICAgIGVudHJ5OiBgJHtMQU1CREFfQVNTRVRTX1BBVEh9L2dldC1maWxlcy9hcHAudHNgLFxuICAgICAgZW52aXJvbm1lbnQ6IHtcbiAgICAgICAgRklMRV9UQUJMRV9OQU1FOiB0aGlzLmZpbGVUYWJsZS50YWJsZU5hbWUsXG4gICAgICB9LFxuICAgIH0pO1xuICAgIGdldEZpbGVzRnVuY3Rpb24ucm9sZT8uYXR0YWNoSW5saW5lUG9saWN5KFxuICAgICAgbmV3IFBvbGljeSh0aGlzLCAnZ2V0LWZpbGVzLXBvbGljeScsIHtcbiAgICAgICAgc3RhdGVtZW50czogW1xuICAgICAgICAgIG5ldyBQb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICAgICAgYWN0aW9uczogW1xuICAgICAgICAgICAgICAnZHluYW1vZGI6UXVlcnknLFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIHJlc291cmNlczogW1xuICAgICAgICAgICAgICB0aGlzLmZpbGVUYWJsZS50YWJsZUFybixcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSksXG4gICAgICAgIF0sXG4gICAgICB9KSxcbiAgICApO1xuICAgIHJldHVybiBnZXRGaWxlc0Z1bmN0aW9uO1xuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVVcGRhdGVGaWxlc0Z1bmN0aW9uKCk6IE5vZGVqc0Z1bmN0aW9uIHtcbiAgICBjb25zdCB1cGRhdGVGaWxlc0Z1bmN0aW9uID0gbmV3IE5vZGVqc0Z1bmN0aW9uKHRoaXMsICdVcGRhdGVGaWxlc0Z1bmN0aW9uJywge1xuICAgICAgZW50cnk6IGAke0xBTUJEQV9BU1NFVFNfUEFUSH0vdXBkYXRlLWZpbGVzL2FwcC50c2AsXG4gICAgICBlbnZpcm9ubWVudDoge1xuICAgICAgICBGSUxFX1RBQkxFX05BTUU6IHRoaXMuZmlsZVRhYmxlLnRhYmxlTmFtZSxcbiAgICAgIH0sXG4gICAgfSk7XG4gICAgdXBkYXRlRmlsZXNGdW5jdGlvbi5yb2xlPy5hdHRhY2hJbmxpbmVQb2xpY3koXG4gICAgICBuZXcgUG9saWN5KHRoaXMsICd1cGRhdGUtZmlsZS1wb2xpY3knLCB7XG4gICAgICAgIHN0YXRlbWVudHM6IFtcbiAgICAgICAgICBuZXcgUG9saWN5U3RhdGVtZW50KHtcbiAgICAgICAgICAgIGFjdGlvbnM6IFtcbiAgICAgICAgICAgICAgJ2R5bmFtb2RiOkJhdGNoV3JpdGVJdGVtJyxcbiAgICAgICAgICAgICAgJ2R5bmFtb2RiOkJhdGNoR2V0SXRlbScsXG4gICAgICAgICAgICBdLFxuICAgICAgI