@aws-cdk/aws-apigateway
Version:
The CDK Construct Library for AWS::ApiGateway
250 lines • 33.7 kB
JavaScript
var _a;
Object.defineProperty(exports, "__esModule", { value: true });
exports.StepFunctionsIntegration = void 0;
const jsiiDeprecationWarnings = require("../../.warnings.jsii.js");
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
const fs = require("fs");
const path = require("path");
const iam = require("@aws-cdk/aws-iam");
const sfn = require("@aws-cdk/aws-stepfunctions");
const core_1 = require("@aws-cdk/core");
const integration_1 = require("../integration");
const model_1 = require("../model");
const aws_1 = require("./aws");
/**
* Options to integrate with various StepFunction API
*/
class StepFunctionsIntegration {
/**
* Integrates a Synchronous Express State Machine from AWS Step Functions to an API Gateway method.
*
* @example
*
* const stateMachine = new stepfunctions.StateMachine(this, 'MyStateMachine', {
* stateMachineType: stepfunctions.StateMachineType.EXPRESS,
* definition: stepfunctions.Chain.start(new stepfunctions.Pass(this, 'Pass')),
* });
*
* const api = new apigateway.RestApi(this, 'Api', {
* restApiName: 'MyApi',
* });
* api.root.addMethod('GET', apigateway.StepFunctionsIntegration.startExecution(stateMachine));
*/
static startExecution(stateMachine, options) {
try {
jsiiDeprecationWarnings._aws_cdk_aws_apigateway_StepFunctionsExecutionIntegrationOptions(options);
}
catch (error) {
if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
Error.captureStackTrace(error, this.startExecution);
}
throw error;
}
return new StepFunctionsExecutionIntegration(stateMachine, options);
}
}
exports.StepFunctionsIntegration = StepFunctionsIntegration;
_a = JSII_RTTI_SYMBOL_1;
StepFunctionsIntegration[_a] = { fqn: "@aws-cdk/aws-apigateway.StepFunctionsIntegration", version: "1.204.0" };
class StepFunctionsExecutionIntegration extends aws_1.AwsIntegration {
constructor(stateMachine, options = {}) {
super({
service: 'states',
action: 'StartSyncExecution',
options: {
credentialsRole: options.credentialsRole,
integrationResponses: integrationResponse(),
passthroughBehavior: integration_1.PassthroughBehavior.NEVER,
requestTemplates: requestTemplates(stateMachine, options),
...options,
},
});
this.stateMachine = stateMachine;
}
bind(method) {
const bindResult = super.bind(method);
const credentialsRole = bindResult.options?.credentialsRole ?? new iam.Role(method, 'StartSyncExecutionRole', {
assumedBy: new iam.ServicePrincipal('apigateway.amazonaws.com'),
});
this.stateMachine.grantStartSyncExecution(credentialsRole);
let stateMachineName;
if (this.stateMachine instanceof sfn.StateMachine) {
const stateMachineType = this.stateMachine.stateMachineType;
if (stateMachineType !== sfn.StateMachineType.EXPRESS) {
throw new Error('State Machine must be of type "EXPRESS". Please use StateMachineType.EXPRESS as the stateMachineType');
}
//if not imported, extract the name from the CFN layer to reach the
//literal value if it is given (rather than a token)
stateMachineName = this.stateMachine.node.defaultChild.stateMachineName;
}
else {
//imported state machine
stateMachineName = `StateMachine-${this.stateMachine.stack.node.addr}`;
}
let deploymentToken;
if (stateMachineName !== undefined && !core_1.Token.isUnresolved(stateMachineName)) {
deploymentToken = JSON.stringify({ stateMachineName });
}
for (const methodResponse of METHOD_RESPONSES) {
method.addMethodResponse(methodResponse);
}
return {
...bindResult,
options: {
...bindResult.options,
credentialsRole,
},
deploymentToken,
};
}
}
/**
* Defines the integration response that passes the result on success,
* or the error on failure, from the synchronous execution to the caller.
*
* @returns integrationResponse mapping
*/
function integrationResponse() {
const errorResponse = [
{
/**
* Specifies the regular expression (regex) pattern used to choose
* an integration response based on the response from the back end.
* In this case it will match all '4XX' HTTP Errors
*/
selectionPattern: '4\\d{2}',
statusCode: '400',
responseTemplates: {
'application/json': `{
"error": "Bad request!"
}`,
},
},
{
/**
* Match all '5XX' HTTP Errors
*/
selectionPattern: '5\\d{2}',
statusCode: '500',
responseTemplates: {
'application/json': '"error": $input.path(\'$.error\')',
},
},
];
const integResponse = [
{
statusCode: '200',
responseTemplates: {
/* eslint-disable */
'application/json': [
'#set($inputRoot = $input.path(\'$\'))',
'#if($input.path(\'$.status\').toString().equals("FAILED"))',
'#set($context.responseOverride.status = 500)',
'{',
'"error": "$input.path(\'$.error\')",',
'"cause": "$input.path(\'$.cause\')"',
'}',
'#else',
'$input.path(\'$.output\')',
'#end',
].join('\n'),
},
},
...errorResponse,
];
return integResponse;
}
/**
* Defines the request template that will be used for the integration
* @param stateMachine
* @param options
* @returns requestTemplate
*/
function requestTemplates(stateMachine, options) {
const templateStr = templateString(stateMachine, options);
const requestTemplate = {
'application/json': templateStr,
};
return requestTemplate;
}
/**
* Reads the VTL template and returns the template string to be used
* for the request template.
*
* @param stateMachine
* @param includeRequestContext
* @param options
* @reutrns templateString
*/
function templateString(stateMachine, options) {
let templateStr;
let requestContextStr = '';
const includeHeader = options.headers ?? false;
const includeQueryString = options.querystring ?? true;
const includePath = options.path ?? true;
const includeAuthorizer = options.authorizer ?? false;
if (options.requestContext && Object.keys(options.requestContext).length > 0) {
requestContextStr = requestContext(options.requestContext);
}
templateStr = fs.readFileSync(path.join(__dirname, 'stepfunctions.vtl'), { encoding: 'utf-8' });
templateStr = templateStr.replace('%STATEMACHINE%', stateMachine.stateMachineArn);
templateStr = templateStr.replace('%INCLUDE_HEADERS%', String(includeHeader));
templateStr = templateStr.replace('%INCLUDE_QUERYSTRING%', String(includeQueryString));
templateStr = templateStr.replace('%INCLUDE_PATH%', String(includePath));
templateStr = templateStr.replace('%INCLUDE_AUTHORIZER%', String(includeAuthorizer));
templateStr = templateStr.replace('%REQUESTCONTEXT%', requestContextStr);
return templateStr;
}
function requestContext(requestContextObj) {
const context = {
accountId: requestContextObj?.accountId ? '$context.identity.accountId' : undefined,
apiId: requestContextObj?.apiId ? '$context.apiId' : undefined,
apiKey: requestContextObj?.apiKey ? '$context.identity.apiKey' : undefined,
authorizerPrincipalId: requestContextObj?.authorizerPrincipalId ? '$context.authorizer.principalId' : undefined,
caller: requestContextObj?.caller ? '$context.identity.caller' : undefined,
cognitoAuthenticationProvider: requestContextObj?.cognitoAuthenticationProvider ? '$context.identity.cognitoAuthenticationProvider' : undefined,
cognitoAuthenticationType: requestContextObj?.cognitoAuthenticationType ? '$context.identity.cognitoAuthenticationType' : undefined,
cognitoIdentityId: requestContextObj?.cognitoIdentityId ? '$context.identity.cognitoIdentityId' : undefined,
cognitoIdentityPoolId: requestContextObj?.cognitoIdentityPoolId ? '$context.identity.cognitoIdentityPoolId' : undefined,
httpMethod: requestContextObj?.httpMethod ? '$context.httpMethod' : undefined,
stage: requestContextObj?.stage ? '$context.stage' : undefined,
sourceIp: requestContextObj?.sourceIp ? '$context.identity.sourceIp' : undefined,
user: requestContextObj?.user ? '$context.identity.user' : undefined,
userAgent: requestContextObj?.userAgent ? '$context.identity.userAgent' : undefined,
userArn: requestContextObj?.userArn ? '$context.identity.userArn' : undefined,
requestId: requestContextObj?.requestId ? '$context.requestId' : undefined,
resourceId: requestContextObj?.resourceId ? '$context.resourceId' : undefined,
resourcePath: requestContextObj?.resourcePath ? '$context.resourcePath' : undefined,
};
const contextAsString = JSON.stringify(context);
// The VTL Template conflicts with double-quotes (") for strings.
// Before sending to the template, we replace double-quotes (") with @@ and replace it back inside the .vtl file
const doublequotes = '"';
const replaceWith = '@@';
return contextAsString.split(doublequotes).join(replaceWith);
}
/**
* Method response model for each HTTP code response
*/
const METHOD_RESPONSES = [
{
statusCode: '200',
responseModels: {
'application/json': model_1.Model.EMPTY_MODEL,
},
},
{
statusCode: '400',
responseModels: {
'application/json': model_1.Model.ERROR_MODEL,
},
},
{
statusCode: '500',
responseModels: {
'application/json': model_1.Model.ERROR_MODEL,
},
},
];
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RlcGZ1bmN0aW9ucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInN0ZXBmdW5jdGlvbnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUEseUJBQXlCO0FBQ3pCLDZCQUE2QjtBQUM3Qix3Q0FBd0M7QUFDeEMsa0RBQWtEO0FBQ2xELHdDQUFzQztBQUV0QyxnREFBNEY7QUFFNUYsb0NBQWlDO0FBQ2pDLCtCQUF1QztBQThFdkM7O0dBRUc7QUFDSCxNQUFhLHdCQUF3QjtJQUNuQzs7Ozs7Ozs7Ozs7Ozs7T0FjRztJQUNJLE1BQU0sQ0FBQyxjQUFjLENBQUMsWUFBK0IsRUFBRSxPQUFrRDs7Ozs7Ozs7OztRQUM5RyxPQUFPLElBQUksaUNBQWlDLENBQUMsWUFBWSxFQUFFLE9BQU8sQ0FBQyxDQUFDO0tBQ3JFOztBQWxCSCw0REFtQkM7OztBQUVELE1BQU0saUNBQWtDLFNBQVEsb0JBQWM7SUFFNUQsWUFBWSxZQUErQixFQUFFLFVBQW9ELEVBQUU7UUFDakcsS0FBSyxDQUFDO1lBQ0osT0FBTyxFQUFFLFFBQVE7WUFDakIsTUFBTSxFQUFFLG9CQUFvQjtZQUM1QixPQUFPLEVBQUU7Z0JBQ1AsZUFBZSxFQUFFLE9BQU8sQ0FBQyxlQUFlO2dCQUN4QyxvQkFBb0IsRUFBRSxtQkFBbUIsRUFBRTtnQkFDM0MsbUJBQW1CLEVBQUUsaUNBQW1CLENBQUMsS0FBSztnQkFDOUMsZ0JBQWdCLEVBQUUsZ0JBQWdCLENBQUMsWUFBWSxFQUFFLE9BQU8sQ0FBQztnQkFDekQsR0FBRyxPQUFPO2FBQ1g7U0FDRixDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsWUFBWSxHQUFHLFlBQVksQ0FBQztLQUNsQztJQUVNLElBQUksQ0FBQyxNQUFjO1FBQ3hCLE1BQU0sVUFBVSxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7UUFFdEMsTUFBTSxlQUFlLEdBQUcsVUFBVSxDQUFDLE9BQU8sRUFBRSxlQUFlLElBQUksSUFBSSxHQUFHLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSx3QkFBd0IsRUFBRTtZQUM1RyxTQUFTLEVBQUUsSUFBSSxHQUFHLENBQUMsZ0JBQWdCLENBQUMsMEJBQTBCLENBQUM7U0FDaEUsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxDQUFDLFlBQVksQ0FBQyx1QkFBdUIsQ0FBQyxlQUFlLENBQUMsQ0FBQztRQUUzRCxJQUFJLGdCQUFnQixDQUFDO1FBRXJCLElBQUksSUFBSSxDQUFDLFlBQVksWUFBWSxHQUFHLENBQUMsWUFBWSxFQUFFO1lBQ2pELE1BQU0sZ0JBQWdCLEdBQUksSUFBSSxDQUFDLFlBQWlDLENBQUMsZ0JBQWdCLENBQUM7WUFDbEYsSUFBSSxnQkFBZ0IsS0FBSyxHQUFHLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxFQUFFO2dCQUNyRCxNQUFNLElBQUksS0FBSyxDQUFDLHNHQUFzRyxDQUFDLENBQUM7YUFDekg7WUFFRCxtRUFBbUU7WUFDbkUsb0RBQW9EO1lBQ3BELGdCQUFnQixHQUFJLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLFlBQW9DLENBQUMsZ0JBQWdCLENBQUM7U0FDbEc7YUFBTTtZQUNMLHdCQUF3QjtZQUN4QixnQkFBZ0IsR0FBRyxnQkFBZ0IsSUFBSSxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO1NBQ3hFO1FBRUQsSUFBSSxlQUFlLENBQUM7UUFFcEIsSUFBSSxnQkFBZ0IsS0FBSyxTQUFTLElBQUksQ0FBQyxZQUFLLENBQUMsWUFBWSxDQUFDLGdCQUFnQixDQUFDLEVBQUU7WUFDM0UsZUFBZSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsRUFBRSxnQkFBZ0IsRUFBRSxDQUFDLENBQUM7U0FDeEQ7UUFFRCxLQUFLLE1BQU0sY0FBYyxJQUFJLGdCQUFnQixFQUFFO1lBQzdDLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxjQUFjLENBQUMsQ0FBQztTQUMxQztRQUVELE9BQU87WUFDTCxHQUFHLFVBQVU7WUFDYixPQUFPLEVBQUU7Z0JBQ1AsR0FBRyxVQUFVLENBQUMsT0FBTztnQkFDckIsZUFBZTthQUNoQjtZQUNELGVBQWU7U0FDaEIsQ0FBQztLQUNIO0NBQ0Y7QUFFRDs7Ozs7R0FLRztBQUNILFNBQVMsbUJBQW1CO0lBQzFCLE1BQU0sYUFBYSxHQUFHO1FBQ3BCO1lBQ0U7Ozs7ZUFJRztZQUNILGdCQUFnQixFQUFFLFNBQVM7WUFDM0IsVUFBVSxFQUFFLEtBQUs7WUFDakIsaUJBQWlCLEVBQUU7Z0JBQ2pCLGtCQUFrQixFQUFFOztZQUVoQjthQUNMO1NBQ0Y7UUFDRDtZQUNFOztlQUVHO1lBQ0gsZ0JBQWdCLEVBQUUsU0FBUztZQUMzQixVQUFVLEVBQUUsS0FBSztZQUNqQixpQkFBaUIsRUFBRTtnQkFDakIsa0JBQWtCLEVBQUUsbUNBQW1DO2FBQ3hEO1NBQ0Y7S0FDRixDQUFDO0lBRUYsTUFBTSxhQUFhLEdBQUc7UUFDcEI7WUFDRSxVQUFVLEVBQUUsS0FBSztZQUNqQixpQkFBaUIsRUFBRTtnQkFDakIsb0JBQW9CO2dCQUNwQixrQkFBa0IsRUFBRTtvQkFDbEIsdUNBQXVDO29CQUN2Qyw0REFBNEQ7b0JBQzFELDhDQUE4QztvQkFDOUMsR0FBRztvQkFDRCxzQ0FBc0M7b0JBQ3RDLHFDQUFxQztvQkFDdkMsR0FBRztvQkFDTCxPQUFPO29CQUNMLDJCQUEyQjtvQkFDN0IsTUFBTTtpQkFFUCxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7YUFDYjtTQUNGO1FBQ0QsR0FBRyxhQUFhO0tBQ2pCLENBQUM7SUFFRixPQUFPLGFBQWEsQ0FBQztBQUN2QixDQUFDO0FBRUQ7Ozs7O0dBS0c7QUFDSCxTQUFTLGdCQUFnQixDQUFDLFlBQStCLEVBQUUsT0FBaUQ7SUFDMUcsTUFBTSxXQUFXLEdBQUcsY0FBYyxDQUFDLFlBQVksRUFBRSxPQUFPLENBQUMsQ0FBQztJQUUxRCxNQUFNLGVBQWUsR0FDbkI7UUFDRSxrQkFBa0IsRUFBRSxXQUFXO0tBQ2hDLENBQUM7SUFFSixPQUFPLGVBQWUsQ0FBQztBQUN6QixDQUFDO0FBRUQ7Ozs7Ozs7O0dBUUc7QUFDSCxTQUFTLGNBQWMsQ0FDckIsWUFBK0IsRUFDL0IsT0FBaUQ7SUFDakQsSUFBSSxXQUFtQixDQUFDO0lBRXhCLElBQUksaUJBQWlCLEdBQUcsRUFBRSxDQUFDO0lBRTNCLE1BQU0sYUFBYSxHQUFHLE9BQU8sQ0FBQyxPQUFPLElBQUcsS0FBSyxDQUFDO0lBQzlDLE1BQU0sa0JBQWtCLEdBQUcsT0FBTyxDQUFDLFdBQVcsSUFBRyxJQUFJLENBQUM7SUFDdEQsTUFBTSxXQUFXLEdBQUcsT0FBTyxDQUFDLElBQUksSUFBRyxJQUFJLENBQUM7SUFDeEMsTUFBTSxpQkFBaUIsR0FBRyxPQUFPLENBQUMsVUFBVSxJQUFJLEtBQUssQ0FBQztJQUV0RCxJQUFJLE9BQU8sQ0FBQyxjQUFjLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsY0FBYyxDQUFDLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtRQUM1RSxpQkFBaUIsR0FBRyxjQUFjLENBQUMsT0FBTyxDQUFDLGNBQWMsQ0FBQyxDQUFDO0tBQzVEO0lBRUQsV0FBVyxHQUFHLEVBQUUsQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsbUJBQW1CLENBQUMsRUFBRSxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsQ0FBQyxDQUFDO0lBQ2hHLFdBQVcsR0FBRyxXQUFXLENBQUMsT0FBTyxDQUFDLGdCQUFnQixFQUFFLFlBQVksQ0FBQyxlQUFlLENBQUMsQ0FBQztJQUNsRixXQUFXLEdBQUcsV0FBVyxDQUFDLE9BQU8sQ0FBQyxtQkFBbUIsRUFBRSxNQUFNLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQztJQUM5RSxXQUFXLEdBQUcsV0FBVyxDQUFDLE9BQU8sQ0FBQyx1QkFBdUIsRUFBRSxNQUFNLENBQUMsa0JBQWtCLENBQUMsQ0FBQyxDQUFDO0lBQ3ZGLFdBQVcsR0FBRyxXQUFXLENBQUMsT0FBTyxDQUFDLGdCQUFnQixFQUFFLE1BQU0sQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDO0lBQ3pFLFdBQVcsR0FBRyxXQUFXLENBQUMsT0FBTyxDQUFDLHNCQUFzQixFQUFFLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLENBQUM7SUFDckYsV0FBVyxHQUFHLFdBQVcsQ0FBQyxPQUFPLENBQUMsa0JBQWtCLEVBQUUsaUJBQWlCLENBQUMsQ0FBQztJQUV6RSxPQUFPLFdBQVcsQ0FBQztBQUNyQixDQUFDO0FBRUQsU0FBUyxjQUFjLENBQUMsaUJBQTZDO0lBQ25FLE1BQU0sT0FBTyxHQUFHO1FBQ2QsU0FBUyxFQUFFLGlCQUFpQixFQUFFLFNBQVMsQ0FBQSxDQUFDLENBQUMsNkJBQTZCLENBQUEsQ0FBQyxDQUFDLFNBQVM7UUFDakYsS0FBSyxFQUFFLGlCQUFpQixFQUFFLEtBQUssQ0FBQSxDQUFDLENBQUMsZ0JBQWdCLENBQUEsQ0FBQyxDQUFDLFNBQVM7UUFDNUQsTUFBTSxFQUFFLGlCQUFpQixFQUFFLE1BQU0sQ0FBQSxDQUFDLENBQUMsMEJBQTBCLENBQUEsQ0FBQyxDQUFDLFNBQVM7UUFDeEUscUJBQXFCLEVBQUUsaUJBQWlCLEVBQUUscUJBQXFCLENBQUEsQ0FBQyxDQUFDLGlDQUFpQyxDQUFBLENBQUMsQ0FBQyxTQUFTO1FBQzdHLE1BQU0sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLENBQUEsQ0FBQyxDQUFDLDBCQUEwQixDQUFBLENBQUMsQ0FBQyxTQUFTO1FBQ3hFLDZCQUE2QixFQUFFLGlCQUFpQixFQUFFLDZCQUE2QixDQUFBLENBQUMsQ0FBQyxpREFBaUQsQ0FBQSxDQUFDLENBQUMsU0FBUztRQUM3SSx5QkFBeUIsRUFBRSxpQkFBaUIsRUFBRSx5QkFBeUIsQ0FBQSxDQUFDLENBQUMsNkNBQTZDLENBQUEsQ0FBQyxDQUFDLFNBQVM7UUFDakksaUJBQWlCLEVBQUUsaUJBQWlCLEVBQUUsaUJBQWlCLENBQUEsQ0FBQyxDQUFDLHFDQUFxQyxDQUFBLENBQUMsQ0FBQyxTQUFTO1FBQ3pHLHFCQUFxQixFQUFFLGlCQUFpQixFQUFFLHFCQUFxQixDQUFBLENBQUMsQ0FBQyx5Q0FBeUMsQ0FBQSxDQUFDLENBQUMsU0FBUztRQUNySCxVQUFVLEVBQUUsaUJBQWlCLEVBQUUsVUFBVSxDQUFBLENBQUMsQ0FBQyxxQkFBcUIsQ0FBQSxDQUFDLENBQUMsU0FBUztRQUMzRSxLQUFLLEVBQUUsaUJBQWlCLEVBQUUsS0FBSyxDQUFBLENBQUMsQ0FBQyxnQkFBZ0IsQ0FBQSxDQUFDLENBQUMsU0FBUztRQUM1RCxRQUFRLEVBQUUsaUJBQWlCLEVBQUUsUUFBUSxDQUFBLENBQUMsQ0FBQyw0QkFBNEIsQ0FBQSxDQUFDLENBQUMsU0FBUztRQUM5RSxJQUFJLEVBQUUsaUJBQWlCLEVBQUUsSUFBSSxDQUFBLENBQUMsQ0FBQyx3QkFBd0IsQ0FBQSxDQUFDLENBQUMsU0FBUztRQUNsRSxTQUFTLEVBQUUsaUJBQWlCLEVBQUUsU0FBUyxDQUFBLENBQUMsQ0FBQyw2QkFBNkIsQ0FBQSxDQUFDLENBQUMsU0FBUztRQUNqRixPQUFPLEVBQUUsaUJBQWlCLEVBQUUsT0FBTyxDQUFBLENBQUMsQ0FBQywyQkFBMkIsQ0FBQSxDQUFDLENBQUMsU0FBUztRQUMzRSxTQUFTLEVBQUUsaUJBQWlCLEVBQUUsU0FBUyxDQUFBLENBQUMsQ0FBQyxvQkFBb0IsQ0FBQSxDQUFDLENBQUMsU0FBUztRQUN4RSxVQUFVLEVBQUUsaUJBQWlCLEVBQUUsVUFBVSxDQUFBLENBQUMsQ0FBQyxxQkFBcUIsQ0FBQSxDQUFDLENBQUMsU0FBUztRQUMzRSxZQUFZLEVBQUUsaUJBQWlCLEVBQUUsWUFBWSxDQUFBLENBQUMsQ0FBQyx1QkFBdUIsQ0FBQSxDQUFDLENBQUMsU0FBUztLQUNsRixDQUFDO0lBRUYsTUFBTSxlQUFlLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUVoRCxpRUFBaUU7SUFDakUsZ0hBQWdIO0lBQ2hILE1BQU0sWUFBWSxHQUFHLEdBQUcsQ0FBQztJQUN6QixNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUM7SUFDekIsT0FBTyxlQUFlLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztBQUMvRCxDQUFDO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLGdCQUFnQixHQUFHO0lBQ3ZCO1FBQ0UsVUFBVSxFQUFFLEtBQUs7UUFDakIsY0FBYyxFQUFFO1lBQ2Qsa0JBQWtCLEVBQUUsYUFBSyxDQUFDLFdBQVc7U0FDdEM7S0FDRjtJQUNEO1FBQ0UsVUFBVSxFQUFFLEtBQUs7UUFDakIsY0FBYyxFQUFFO1lBQ2Qsa0JBQWtCLEVBQUUsYUFBSyxDQUFDLFdBQVc7U0FDdEM7S0FDRjtJQUNEO1FBQ0UsVUFBVSxFQUFFLEtBQUs7UUFDakIsY0FBYyxFQUFFO1lBQ2Qsa0JBQWtCLEVBQUUsYUFBSyxDQUFDLFdBQVc7U0FDdEM7S0FDRjtDQUNGLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBmcyBmcm9tICdmcyc7XG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0ICogYXMgaWFtIGZyb20gJ0Bhd3MtY2RrL2F3cy1pYW0nO1xuaW1wb3J0ICogYXMgc2ZuIGZyb20gJ0Bhd3MtY2RrL2F3cy1zdGVwZnVuY3Rpb25zJztcbmltcG9ydCB7IFRva2VuIH0gZnJvbSAnQGF3cy1jZGsvY29yZSc7XG5pbXBvcnQgeyBSZXF1ZXN0Q29udGV4dCB9IGZyb20gJy4nO1xuaW1wb3J0IHsgSW50ZWdyYXRpb25Db25maWcsIEludGVncmF0aW9uT3B0aW9ucywgUGFzc3Rocm91Z2hCZWhhdmlvciB9IGZyb20gJy4uL2ludGVncmF0aW9uJztcbmltcG9ydCB7IE1ldGhvZCB9IGZyb20gJy4uL21ldGhvZCc7XG5pbXBvcnQgeyBNb2RlbCB9IGZyb20gJy4uL21vZGVsJztcbmltcG9ydCB7IEF3c0ludGVncmF0aW9uIH0gZnJvbSAnLi9hd3MnO1xuLyoqXG4gKiBPcHRpb25zIHdoZW4gY29uZmlndXJpbmcgU3RlcCBGdW5jdGlvbnMgc3luY2hyb25vdXMgaW50ZWdyYXRpb24gd2l0aCBSZXN0IEFQSVxuICovXG5leHBvcnQgaW50ZXJmYWNlIFN0ZXBGdW5jdGlvbnNFeGVjdXRpb25JbnRlZ3JhdGlvbk9wdGlvbnMgZXh0ZW5kcyBJbnRlZ3JhdGlvbk9wdGlvbnMge1xuXG4gIC8qKlxuICAgKiBXaGljaCBkZXRhaWxzIG9mIHRoZSBpbmNvbWluZyByZXF1ZXN0IG11c3QgYmUgcGFzc2VkIG9udG8gdGhlIHVuZGVybHlpbmcgc3RhdGUgbWFjaGluZSxcbiAgICogc3VjaCBhcywgYWNjb3VudCBpZCwgdXNlciBpZGVudGl0eSwgcmVxdWVzdCBpZCwgZXRjLiBUaGUgZXhlY3V0aW9uIGlucHV0IHdpbGwgaW5jbHVkZSBhIG5ldyBrZXkgYHJlcXVlc3RDb250ZXh0YDpcbiAgICpcbiAgICoge1xuICAgKiAgIFwiYm9keVwiOiB7fSxcbiAgICogICBcInJlcXVlc3RDb250ZXh0XCI6IHtcbiAgICogICAgICAgXCJrZXlcIjogXCJ2YWx1ZVwiXG4gICAqICAgfVxuICAgKiB9XG4gICAqXG4gICAqIEBkZWZhdWx0IC0gYWxsIHBhcmFtZXRlcnMgd2l0aGluIHJlcXVlc3QgY29udGV4dCB3aWxsIGJlIHNldCBhcyBmYWxzZVxuICAgKi9cbiAgcmVhZG9ubHkgcmVxdWVzdENvbnRleHQ/OiBSZXF1ZXN0Q29udGV4dDtcblxuICAvKipcbiAgICogQ2hlY2sgaWYgcXVlcnlzdHJpbmcgaXMgdG8gYmUgaW5jbHVkZWQgaW5zaWRlIHRoZSBleGVjdXRpb24gaW5wdXQuIFRoZSBleGVjdXRpb24gaW5wdXQgd2lsbCBpbmNsdWRlIGEgbmV3IGtleSBgcXVlcnlTdHJpbmdgOlxuICAgKlxuICAgKiB7XG4gICAqICAgXCJib2R5XCI6IHt9LFxuICAgKiAgIFwicXVlcnlzdHJpbmdcIjoge1xuICAgKiAgICAgXCJrZXlcIjogXCJ2YWx1ZVwiXG4gICAqICAgfVxuICAgKiB9XG4gICAqXG4gICAqIEBkZWZhdWx0IHRydWVcbiAgICovXG4gIHJlYWRvbmx5IHF1ZXJ5c3RyaW5nPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogQ2hlY2sgaWYgcGF0aCBpcyB0byBiZSBpbmNsdWRlZCBpbnNpZGUgdGhlIGV4ZWN1dGlvbiBpbnB1dC4gVGhlIGV4ZWN1dGlvbiBpbnB1dCB3aWxsIGluY2x1ZGUgYSBuZXcga2V5IGBwYXRoYDpcbiAgICpcbiAgICoge1xuICAgKiAgIFwiYm9keVwiOiB7fSxcbiAgICogICBcInBhdGhcIjoge1xuICAgKiAgICAgXCJyZXNvdXJjZU5hbWVcIjogXCJyZXNvdXJjZVZhbHVlXCJcbiAgICogICB9XG4gICAqIH1cbiAgICpcbiAgICogQGRlZmF1bHQgdHJ1ZVxuICAgKi9cbiAgcmVhZG9ubHkgcGF0aD86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIENoZWNrIGlmIGhlYWRlciBpcyB0byBiZSBpbmNsdWRlZCBpbnNpZGUgdGhlIGV4ZWN1dGlvbiBpbnB1dC4gVGhlIGV4ZWN1dGlvbiBpbnB1dCB3aWxsIGluY2x1ZGUgYSBuZXcga2V5IGBoZWFkZXJzYDpcbiAgICpcbiAgICoge1xuICAgKiAgIFwiYm9keVwiOiB7fSxcbiAgICogICBcImhlYWRlcnNcIjoge1xuICAgKiAgICAgIFwiaGVhZGVyMVwiOiBcInZhbHVlXCIsXG4gICAqICAgICAgXCJoZWFkZXIyXCI6IFwidmFsdWVcIlxuICAgKiAgIH1cbiAgICogfVxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgcmVhZG9ubHkgaGVhZGVycz86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIElmIHRoZSB3aG9sZSBhdXRob3JpemVyIG9iamVjdCwgaW5jbHVkaW5nIGN1c3RvbSBjb250ZXh0IHZhbHVlcyBzaG91bGQgYmUgaW4gdGhlIGV4ZWN1dGlvbiBpbnB1dC4gVGhlIGV4ZWN1dGlvbiBpbnB1dCB3aWxsIGluY2x1ZGUgYSBuZXcga2V5IGBhdXRob3JpemVyYDpcbiAgICpcbiAgICoge1xuICAgKiAgIFwiYm9keVwiOiB7fSxcbiAgICogICBcImF1dGhvcml6ZXJcIjoge1xuICAgKiAgICAgXCJrZXlcIjogXCJ2YWx1ZVwiXG4gICAqICAgfVxuICAgKiB9XG4gICAqXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICByZWFkb25seSBhdXRob3JpemVyPzogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBPcHRpb25zIHRvIGludGVncmF0ZSB3aXRoIHZhcmlvdXMgU3RlcEZ1bmN0aW9uIEFQSVxuICovXG5leHBvcnQgY2xhc3MgU3RlcEZ1bmN0aW9uc0ludGVncmF0aW9uIHtcbiAgLyoqXG4gICAqIEludGVncmF0ZXMgYSBTeW5jaHJvbm91cyBFeHByZXNzIFN0YXRlIE1hY2hpbmUgZnJvbSBBV1MgU3RlcCBGdW5jdGlvbnMgdG8gYW4gQVBJIEdhdGV3YXkgbWV0aG9kLlxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKlxuICAgKiAgICBjb25zdCBzdGF0ZU1hY2hpbmUgPSBuZXcgc3RlcGZ1bmN0aW9ucy5TdGF0ZU1hY2hpbmUodGhpcywgJ015U3RhdGVNYWNoaW5lJywge1xuICAgKiAgICAgICBzdGF0ZU1hY2hpbmVUeXBlOiBzdGVwZnVuY3Rpb25zLlN0YXRlTWFjaGluZVR5cGUuRVhQUkVTUyxcbiAgICogICAgICAgZGVmaW5pdGlvbjogc3RlcGZ1bmN0aW9ucy5DaGFpbi5zdGFydChuZXcgc3RlcGZ1bmN0aW9ucy5QYXNzKHRoaXMsICdQYXNzJykpLFxuICAgKiAgICB9KTtcbiAgICpcbiAgICogICAgY29uc3QgYXBpID0gbmV3IGFwaWdhdGV3YXkuUmVzdEFwaSh0aGlzLCAnQXBpJywge1xuICAgKiAgICAgICByZXN0QXBpTmFtZTogJ015QXBpJyxcbiAgICogICAgfSk7XG4gICAqICAgIGFwaS5yb290LmFkZE1ldGhvZCgnR0VUJywgYXBpZ2F0ZXdheS5TdGVwRnVuY3Rpb25zSW50ZWdyYXRpb24uc3RhcnRFeGVjdXRpb24oc3RhdGVNYWNoaW5lKSk7XG4gICAqL1xuICBwdWJsaWMgc3RhdGljIHN0YXJ0RXhlY3V0aW9uKHN0YXRlTWFjaGluZTogc2ZuLklTdGF0ZU1hY2hpbmUsIG9wdGlvbnM/OiBTdGVwRnVuY3Rpb25zRXhlY3V0aW9uSW50ZWdyYXRpb25PcHRpb25zKTogQXdzSW50ZWdyYXRpb24ge1xuICAgIHJldHVybiBuZXcgU3RlcEZ1bmN0aW9uc0V4ZWN1dGlvbkludGVncmF0aW9uKHN0YXRlTWFjaGluZSwgb3B0aW9ucyk7XG4gIH1cbn1cblxuY2xhc3MgU3RlcEZ1bmN0aW9uc0V4ZWN1dGlvbkludGVncmF0aW9uIGV4dGVuZHMgQXdzSW50ZWdyYXRpb24ge1xuICBwcml2YXRlIHJlYWRvbmx5IHN0YXRlTWFjaGluZTogc2ZuLklTdGF0ZU1hY2hpbmU7XG4gIGNvbnN0cnVjdG9yKHN0YXRlTWFjaGluZTogc2ZuLklTdGF0ZU1hY2hpbmUsIG9wdGlvbnM6IFN0ZXBGdW5jdGlvbnNFeGVjdXRpb25JbnRlZ3JhdGlvbk9wdGlvbnMgPSB7fSkge1xuICAgIHN1cGVyKHtcbiAgICAgIHNlcnZpY2U6ICdzdGF0ZXMnLFxuICAgICAgYWN0aW9uOiAnU3RhcnRTeW5jRXhlY3V0aW9uJyxcbiAgICAgIG9wdGlvbnM6IHtcbiAgICAgICAgY3JlZGVudGlhbHNSb2xlOiBvcHRpb25zLmNyZWRlbnRpYWxzUm9sZSxcbiAgICAgICAgaW50ZWdyYXRpb25SZXNwb25zZXM6IGludGVncmF0aW9uUmVzcG9uc2UoKSxcbiAgICAgICAgcGFzc3Rocm91Z2hCZWhhdmlvcjogUGFzc3Rocm91Z2hCZWhhdmlvci5ORVZFUixcbiAgICAgICAgcmVxdWVzdFRlbXBsYXRlczogcmVxdWVzdFRlbXBsYXRlcyhzdGF0ZU1hY2hpbmUsIG9wdGlvbnMpLFxuICAgICAgICAuLi5vcHRpb25zLFxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIHRoaXMuc3RhdGVNYWNoaW5lID0gc3RhdGVNYWNoaW5lO1xuICB9XG5cbiAgcHVibGljIGJpbmQobWV0aG9kOiBNZXRob2QpOiBJbnRlZ3JhdGlvbkNvbmZpZyB7XG4gICAgY29uc3QgYmluZFJlc3VsdCA9IHN1cGVyLmJpbmQobWV0aG9kKTtcblxuICAgIGNvbnN0IGNyZWRlbnRpYWxzUm9sZSA9IGJpbmRSZXN1bHQub3B0aW9ucz8uY3JlZGVudGlhbHNSb2xlID8/IG5ldyBpYW0uUm9sZShtZXRob2QsICdTdGFydFN5bmNFeGVjdXRpb25Sb2xlJywge1xuICAgICAgYXNzdW1lZEJ5OiBuZXcgaWFtLlNlcnZpY2VQcmluY2lwYWwoJ2FwaWdhdGV3YXkuYW1hem9uYXdzLmNvbScpLFxuICAgIH0pO1xuICAgIHRoaXMuc3RhdGVNYWNoaW5lLmdyYW50U3RhcnRTeW5jRXhlY3V0aW9uKGNyZWRlbnRpYWxzUm9sZSk7XG5cbiAgICBsZXQgc3RhdGVNYWNoaW5lTmFtZTtcblxuICAgIGlmICh0aGlzLnN0YXRlTWFjaGluZSBpbnN0YW5jZW9mIHNmbi5TdGF0ZU1hY2hpbmUpIHtcbiAgICAgIGNvbnN0IHN0YXRlTWFjaGluZVR5cGUgPSAodGhpcy5zdGF0ZU1hY2hpbmUgYXMgc2ZuLlN0YXRlTWFjaGluZSkuc3RhdGVNYWNoaW5lVHlwZTtcbiAgICAgIGlmIChzdGF0ZU1hY2hpbmVUeXBlICE9PSBzZm4uU3RhdGVNYWNoaW5lVHlwZS5FWFBSRVNTKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignU3RhdGUgTWFjaGluZSBtdXN0IGJlIG9mIHR5cGUgXCJFWFBSRVNTXCIuIFBsZWFzZSB1c2UgU3RhdGVNYWNoaW5lVHlwZS5FWFBSRVNTIGFzIHRoZSBzdGF0ZU1hY2hpbmVUeXBlJyk7XG4gICAgICB9XG5cbiAgICAgIC8vaWYgbm90IGltcG9ydGVkLCBleHRyYWN0IHRoZSBuYW1lIGZyb20gdGhlIENGTiBsYXllciB0byByZWFjaCB0aGVcbiAgICAgIC8vbGl0ZXJhbCB2YWx1ZSBpZiBpdCBpcyBnaXZlbiAocmF0aGVyIHRoYW4gYSB0b2tlbilcbiAgICAgIHN0YXRlTWFjaGluZU5hbWUgPSAodGhpcy5zdGF0ZU1hY2hpbmUubm9kZS5kZWZhdWx0Q2hpbGQgYXMgc2ZuLkNmblN0YXRlTWFjaGluZSkuc3RhdGVNYWNoaW5lTmFtZTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy9pbXBvcnRlZCBzdGF0ZSBtYWNoaW5lXG4gICAgICBzdGF0ZU1hY2hpbmVOYW1lID0gYFN0YXRlTWFjaGluZS0ke3RoaXMuc3RhdGVNYWNoaW5lLnN0YWNrLm5vZGUuYWRkcn1gO1xuICAgIH1cblxuICAgIGxldCBkZXBsb3ltZW50VG9rZW47XG5cbiAgICBpZiAoc3RhdGVNYWNoaW5lTmFtZSAhPT0gdW5kZWZpbmVkICYmICFUb2tlbi5pc1VucmVzb2x2ZWQoc3RhdGVNYWNoaW5lTmFtZSkpIHtcbiAgICAgIGRlcGxveW1lbnRUb2tlbiA9IEpTT04uc3RyaW5naWZ5KHsgc3RhdGVNYWNoaW5lTmFtZSB9KTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IG1ldGhvZFJlc3BvbnNlIG9mIE1FVEhPRF9SRVNQT05TRVMpIHtcbiAgICAgIG1ldGhvZC5hZGRNZXRob2RSZXNwb25zZShtZXRob2RSZXNwb25zZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLmJpbmRSZXN1bHQsXG4gICAgICBvcHRpb25zOiB7XG4gICAgICAgIC4uLmJpbmRSZXN1bHQub3B0aW9ucyxcbiAgICAgICAgY3JlZGVudGlhbHNSb2xlLFxuICAgICAgfSxcbiAgICAgIGRlcGxveW1lbnRUb2tlbixcbiAgICB9O1xuICB9XG59XG5cbi8qKlxuICogRGVmaW5lcyB0aGUgaW50ZWdyYXRpb24gcmVzcG9uc2UgdGhhdCBwYXNzZXMgdGhlIHJlc3VsdCBvbiBzdWNjZXNzLFxuICogb3IgdGhlIGVycm9yIG9uIGZhaWx1cmUsIGZyb20gdGhlIHN5bmNocm9ub3VzIGV4ZWN1dGlvbiB0byB0aGUgY2FsbGVyLlxuICpcbiAqIEByZXR1cm5zIGludGVncmF0aW9uUmVzcG9uc2UgbWFwcGluZ1xuICovXG5mdW5jdGlvbiBpbnRlZ3JhdGlvblJlc3BvbnNlKCkge1xuICBjb25zdCBlcnJvclJlc3BvbnNlID0gW1xuICAgIHtcbiAgICAgIC8qKlxuICAgICAgICogU3BlY2lmaWVzIHRoZSByZWd1bGFyIGV4cHJlc3Npb24gKHJlZ2V4KSBwYXR0ZXJuIHVzZWQgdG8gY2hvb3NlXG4gICAgICAgKiBhbiBpbnRlZ3JhdGlvbiByZXNwb25zZSBiYXNlZCBvbiB0aGUgcmVzcG9uc2UgZnJvbSB0aGUgYmFjayBlbmQuXG4gICAgICAgKiBJbiB0aGlzIGNhc2UgaXQgd2lsbCBtYXRjaCBhbGwgJzRYWCcgSFRUUCBFcnJvcnNcbiAgICAgICAqL1xuICAgICAgc2VsZWN0aW9uUGF0dGVybjogJzRcXFxcZHsyfScsXG4gICAgICBzdGF0dXNDb2RlOiAnNDAwJyxcbiAgICAgIHJlc3BvbnNlVGVtcGxhdGVzOiB7XG4gICAgICAgICdhcHBsaWNhdGlvbi9qc29uJzogYHtcbiAgICAgICAgICAgIFwiZXJyb3JcIjogXCJCYWQgcmVxdWVzdCFcIlxuICAgICAgICAgIH1gLFxuICAgICAgfSxcbiAgICB9LFxuICAgIHtcbiAgICAgIC8qKlxuICAgICAgICogTWF0Y2ggYWxsICc1WFgnIEhUVFAgRXJyb3JzXG4gICAgICAgKi9cbiAgICAgIHNlbGVjdGlvblBhdHRlcm46ICc1XFxcXGR7Mn0nLFxuICAgICAgc3RhdHVzQ29kZTogJzUwMCcsXG4gICAgICByZXNwb25zZVRlbXBsYXRlczoge1xuICAgICAgICAnYXBwbGljYXRpb24vanNvbic6ICdcImVycm9yXCI6ICRpbnB1dC5wYXRoKFxcJyQuZXJyb3JcXCcpJyxcbiAgICAgIH0sXG4gICAgfSxcbiAgXTtcblxuICBjb25zdCBpbnRlZ1Jlc3BvbnNlID0gW1xuICAgIHtcbiAgICAgIHN0YXR1c0NvZGU6ICcyMDAnLFxuICAgICAgcmVzcG9uc2VUZW1wbGF0ZXM6IHtcbiAgICAgICAgLyogZXNsaW50LWRpc2FibGUgKi9cbiAgICAgICAgJ2FwcGxpY2F0aW9uL2pzb24nOiBbXG4gICAgICAgICAgJyNzZXQoJGlucHV0Um9vdCA9ICRpbnB1dC5wYXRoKFxcJyRcXCcpKScsXG4gICAgICAgICAgJyNpZigkaW5wdXQucGF0aChcXCckLnN0YXR1c1xcJykudG9TdHJpbmcoKS5lcXVhbHMoXCJGQUlMRURcIikpJyxcbiAgICAgICAgICAgICcjc2V0KCRjb250ZXh0LnJlc3BvbnNlT3ZlcnJpZGUuc3RhdHVzID0gNTAwKScsXG4gICAgICAgICAgICAneycsXG4gICAgICAgICAgICAgICdcImVycm9yXCI6IFwiJGlucHV0LnBhdGgoXFwnJC5lcnJvclxcJylcIiwnLFxuICAgICAgICAgICAgICAnXCJjYXVzZVwiOiBcIiRpbnB1dC5wYXRoKFxcJyQuY2F1c2VcXCcpXCInLFxuICAgICAgICAgICAgJ30nLFxuICAgICAgICAgICcjZWxzZScsXG4gICAgICAgICAgICAnJGlucHV0LnBhdGgoXFwnJC5vdXRwdXRcXCcpJyxcbiAgICAgICAgICAnI2VuZCcsXG4gICAgICAgIC8qIGVzbGludC1lbmFibGUgKi9cbiAgICAgICAgXS5qb2luKCdcXG4nKSxcbiAgICAgIH0sXG4gICAgfSxcbiAgICAuLi5lcnJvclJlc3BvbnNlLFxuICBdO1xuXG4gIHJldHVybiBpbnRlZ1Jlc3BvbnNlO1xufVxuXG4vKipcbiAqIERlZmluZXMgdGhlIHJlcXVlc3QgdGVtcGxhdGUgdGhhdCB3aWxsIGJlIHVzZWQgZm9yIHRoZSBpbnRlZ3JhdGlvblxuICogQHBhcmFtIHN0YXRlTWFjaGluZVxuICogQHBhcmFtIG9wdGlvbnNcbiAqIEByZXR1cm5zIHJlcXVlc3RUZW1wbGF0ZVxuICovXG5mdW5jdGlvbiByZXF1ZXN0VGVtcGxhdGVzKHN0YXRlTWFjaGluZTogc2ZuLklTdGF0ZU1hY2hpbmUsIG9wdGlvbnM6IFN0ZXBGdW5jdGlvbnNFeGVjdXRpb25JbnRlZ3JhdGlvbk9wdGlvbnMpIHtcbiAgY29uc3QgdGVtcGxhdGVTdHIgPSB0ZW1wbGF0ZVN0cmluZyhzdGF0ZU1hY2hpbmUsIG9wdGlvbnMpO1xuXG4gIGNvbnN0IHJlcXVlc3RUZW1wbGF0ZTogeyBbY29udGVudFR5cGU6c3RyaW5nXSA6IHN0cmluZyB9ID1cbiAgICB7XG4gICAgICAnYXBwbGljYXRpb24vanNvbic6IHRlbXBsYXRlU3RyLFxuICAgIH07XG5cbiAgcmV0dXJuIHJlcXVlc3RUZW1wbGF0ZTtcbn1cblxuLyoqXG4gKiBSZWFkcyB0aGUgVlRMIHRlbXBsYXRlIGFuZCByZXR1cm5zIHRoZSB0ZW1wbGF0ZSBzdHJpbmcgdG8gYmUgdXNlZFxuICogZm9yIHRoZSByZXF1ZXN0IHRlbXBsYXRlLlxuICpcbiAqIEBwYXJhbSBzdGF0ZU1hY2hpbmVcbiAqIEBwYXJhbSBpbmNsdWRlUmVxdWVzdENvbnRleHRcbiAqIEBwYXJhbSBvcHRpb25zXG4gKiBAcmV1dHJucyB0ZW1wbGF0ZVN0cmluZ1xuICovXG5mdW5jdGlvbiB0ZW1wbGF0ZVN0cmluZyhcbiAgc3RhdGVNYWNoaW5lOiBzZm4uSVN0YXRlTWFjaGluZSxcbiAgb3B0aW9uczogU3RlcEZ1bmN0aW9uc0V4ZWN1dGlvbkludGVncmF0aW9uT3B0aW9ucyk6IHN0cmluZyB7XG4gIGxldCB0ZW1wbGF0ZVN0cjogc3RyaW5nO1xuXG4gIGxldCByZXF1ZXN0Q29udGV4dFN0ciA9ICcnO1xuXG4gIGNvbnN0IGluY2x1ZGVIZWFkZXIgPSBvcHRpb25zLmhlYWRlcnM/PyBmYWxzZTtcbiAgY29uc3QgaW5jbHVkZVF1ZXJ5U3RyaW5nID0gb3B0aW9ucy5xdWVyeXN0cmluZz8/IHRydWU7XG4gIGNvbnN0IGluY2x1ZGVQYXRoID0gb3B0aW9ucy5wYXRoPz8gdHJ1ZTtcbiAgY29uc3QgaW5jbHVkZUF1dGhvcml6ZXIgPSBvcHRpb25zLmF1dGhvcml6ZXIgPz8gZmFsc2U7XG5cbiAgaWYgKG9wdGlvbnMucmVxdWVzdENvbnRleHQgJiYgT2JqZWN0LmtleXMob3B0aW9ucy5yZXF1ZXN0Q29udGV4dCkubGVuZ3RoID4gMCkge1xuICAgIHJlcXVlc3RDb250ZXh0U3RyID0gcmVxdWVzdENvbnRleHQob3B0aW9ucy5yZXF1ZXN0Q29udGV4dCk7XG4gIH1cblxuICB0ZW1wbGF0ZVN0ciA9IGZzLnJlYWRGaWxlU3luYyhwYXRoLmpvaW4oX19kaXJuYW1lLCAnc3RlcGZ1bmN0aW9ucy52dGwnKSwgeyBlbmNvZGluZzogJ3V0Zi04JyB9KTtcbiAgdGVtcGxhdGVTdHIgPSB0ZW1wbGF0ZVN0ci5yZXBsYWNlKCclU1RBVEVNQUNISU5FJScsIHN0YXRlTWFjaGluZS5zdGF0ZU1hY2hpbmVBcm4pO1xuICB0ZW1wbGF0ZVN0ciA9IHRlbXBsYXRlU3RyLnJlcGxhY2UoJyVJTkNMVURFX0hFQURFUlMlJywgU3RyaW5nKGluY2x1ZGVIZWFkZXIpKTtcbiAgdGVtcGxhdGVTdHIgPSB0ZW1wbGF0ZVN0ci5yZXBsYWNlKCclSU5DTFVERV9RVUVSWVNUUklORyUnLCBTdHJpbmcoaW5jbHVkZVF1ZXJ5U3RyaW5nKSk7XG4gIHRlbXBsYXRlU3RyID0gdGVtcGxhdGVTdHIucmVwbGFjZSgnJUlOQ0xVREVfUEFUSCUnLCBTdHJpbmcoaW5jbHVkZVBhdGgpKTtcbiAgdGVtcGxhdGVTdHIgPSB0ZW1wbGF0ZVN0ci5yZXBsYWNlKCclSU5DTFVERV9BVVRIT1JJWkVSJScsIFN0cmluZyhpbmNsdWRlQXV0aG9yaXplcikpO1xuICB0ZW1wbGF0ZVN0ciA9IHRlbXBsYXRlU3RyLnJlcGxhY2UoJyVSRVFVRVNUQ09OVEVYVCUnLCByZXF1ZXN0Q29udGV4dFN0cik7XG5cbiAgcmV0dXJuIHRlbXBsYXRlU3RyO1xufVxuXG5mdW5jdGlvbiByZXF1ZXN0Q29udGV4dChyZXF1ZXN0Q29udGV4dE9iajogUmVxdWVzdENvbnRleHQgfCB1bmRlZmluZWQpOiBzdHJpbmcge1xuICBjb25zdCBjb250ZXh0ID0ge1xuICAgIGFjY291bnRJZDogcmVxdWVzdENvbnRleHRPYmo/LmFjY291bnRJZD8gJyRjb250ZXh0LmlkZW50aXR5LmFjY291bnRJZCc6IHVuZGVmaW5lZCxcbiAgICBhcGlJZDogcmVxdWVzdENvbnRleHRPYmo/LmFwaUlkPyAnJGNvbnRleHQuYXBpSWQnOiB1bmRlZmluZWQsXG4gICAgYXBpS2V5OiByZXF1ZXN0Q29udGV4dE9iaj8uYXBpS2V5PyAnJGNvbnRleHQuaWRlbnRpdHkuYXBpS2V5JzogdW5kZWZpbmVkLFxuICAgIGF1dGhvcml6ZXJQcmluY2lwYWxJZDogcmVxdWVzdENvbnRleHRPYmo/LmF1dGhvcml6ZXJQcmluY2lwYWxJZD8gJyRjb250ZXh0LmF1dGhvcml6ZXIucHJpbmNpcGFsSWQnOiB1bmRlZmluZWQsXG4gICAgY2FsbGVyOiByZXF1ZXN0Q29udGV4dE9iaj8uY2FsbGVyPyAnJGNvbnRleHQuaWRlbnRpdHkuY2FsbGVyJzogdW5kZWZpbmVkLFxuICAgIGNvZ25pdG9BdXRoZW50aWNhdGlvblByb3ZpZGVyOiByZXF1ZXN0Q29udGV4dE9iaj8uY29nbml0b0F1dGhlbnRpY2F0aW9uUHJvdmlkZXI/ICckY29udGV4dC5pZGVudGl0eS5jb2duaXRvQXV0aGVudGljYXRpb25Qcm92aWRlcic6IHVuZGVmaW5lZCxcbiAgICBjb2duaXRvQXV0aGVudGljYXRpb25UeXBlOiByZXF1ZXN0Q29udGV4dE9iaj8uY29nbml0b0F1dGhlbnRpY2F0aW9uVHlwZT8gJyRjb250ZXh0LmlkZW50aXR5LmNvZ25pdG9BdXRoZW50aWNhdGlvblR5cGUnOiB1bmRlZmluZWQsXG4gICAgY29nbml0b0lkZW50aXR5SWQ6IHJlcXVlc3RDb250ZXh0T2JqPy5jb2duaXRvSWRlbnRpdHlJZD8gJyRjb250ZXh0LmlkZW50aXR5LmNvZ25pdG9JZGVudGl0eUlkJzogdW5kZWZpbmVkLFxuICAgIGNvZ25pdG9JZGVudGl0eVBvb2xJZDogcmVxdWVzdENvbnRleHRPYmo/LmNvZ25pdG9JZGVudGl0eVBvb2xJZD8gJyRjb250ZXh0LmlkZW50aXR5LmNvZ25pdG9JZGVudGl0eVBvb2xJZCc6IHVuZGVmaW5lZCxcbiAgICBodHRwTWV0aG9kOiByZXF1ZXN0Q29udGV4dE9iaj8uaHR0cE1ldGhvZD8gJyRjb250ZXh0Lmh0dHBNZXRob2QnOiB1bmRlZmluZWQsXG4gICAgc3RhZ2U6IHJlcXVlc3RDb250ZXh0T2JqPy5zdGFnZT8gJyRjb250ZXh0LnN0YWdlJzogdW5kZWZpbmVkLFxuICAgIHNvdXJjZUlwOiByZXF1ZXN0Q29udGV4dE9iaj8uc291cmNlSXA/ICckY29udGV4dC5pZGVudGl0eS5zb3VyY2VJcCc6IHVuZGVmaW5lZCxcbiAgICB1c2VyOiByZXF1ZXN0Q29udGV4dE9iaj8udXNlcj8gJyRjb250ZXh0LmlkZW50aXR5LnVzZXInOiB1bmRlZmluZWQsXG4gICAgdXNlckFnZW50OiByZXF1ZXN0Q29udGV4dE9iaj8udXNlckFnZW50PyAnJGNvbnRleHQuaWRlbnRpdHkudXNlckFnZW50JzogdW5kZWZpbmVkLFxuICAgIHVzZXJBcm46IHJlcXVlc3RDb250ZXh0T2JqPy51c2VyQXJuPyAnJGNvbnRleHQuaWRlbnRpdHkudXNlckFybic6IHVuZGVmaW5lZCxcbiAgICByZXF1ZXN0SWQ6IHJlcXVlc3RDb250ZXh0T2JqPy5yZXF1ZXN0SWQ/ICckY29udGV4dC5yZXF1ZXN0SWQnOiB1bmRlZmluZWQsXG4gICAgcmVzb3VyY2VJZDogcmVxdWVzdENvbnRleHRPYmo/LnJlc291cmNlSWQ/ICckY29udGV4dC5yZXNvdXJjZUlkJzogdW5kZWZpbmVkLFxuICAgIHJlc291cmNlUGF0aDogcmVxdWVzdENvbnRleHRPYmo/LnJlc291cmNlUGF0aD8gJyRjb250ZXh0LnJlc291cmNlUGF0aCc6IHVuZGVmaW5lZCxcbiAgfTtcblxuICBjb25zdCBjb250ZXh0QXNTdHJpbmcgPSBKU09OLnN0cmluZ2lmeShjb250ZXh0KTtcblxuICAvLyBUaGUgVlRMIFRlbXBsYXRlIGNvbmZsaWN0cyB3aXRoIGRvdWJsZS1xdW90ZXMgKFwiKSBmb3Igc3RyaW5ncy5cbiAgLy8gQmVmb3JlIHNlbmRpbmcgdG8gdGhlIHRlbXBsYXRlLCB3ZSByZXBsYWNlIGRvdWJsZS1xdW90ZXMgKFwiKSB3aXRoIEBAIGFuZCByZXBsYWNlIGl0IGJhY2sgaW5zaWRlIHRoZSAudnRsIGZpbGVcbiAgY29uc3QgZG91YmxlcXVvdGVzID0gJ1wiJztcbiAgY29uc3QgcmVwbGFjZVdpdGggPSAnQEAnO1xuICByZXR1cm4gY29udGV4dEFzU3RyaW5nLnNwbGl0KGRvdWJsZXF1b3Rlcykuam9pbihyZXBsYWNlV2l0aCk7XG59XG5cbi8qKlxuICogTWV0aG9kIHJlc3BvbnNlIG1vZGVsIGZvciBlYWNoIEhUVFAgY29kZSByZXNwb25zZVxuICovXG5jb25zdCBNRVRIT0RfUkVTUE9OU0VTID0gW1xuICB7XG4gICAgc3RhdHVzQ29kZTogJzIwMCcsXG4gICAgcmVzcG9uc2VNb2RlbHM6IHtcbiAgICAgICdhcHBsaWNhdGlvbi9qc29uJzogTW9kZWwuRU1QVFlfTU9ERUwsXG4gICAgfSxcbiAgfSxcbiAge1xuICAgIHN0YXR1c0NvZGU6ICc0MDAnLFxuICAgIHJlc3BvbnNlTW9kZWxzOiB7XG4gICAgICAnYXBwbGljYXRpb24vanNvbic6IE1vZGVsLkVSUk9SX01PREVMLFxuICAgIH0sXG4gIH0sXG4gIHtcbiAgICBzdGF0dXNDb2RlOiAnNTAwJyxcbiAgICByZXNwb25zZU1vZGVsczoge1xuICAgICAgJ2FwcGxpY2F0aW9uL2pzb24nOiBNb2RlbC5FUlJPUl9NT0RFTCxcbiAgICB9LFxuICB9LFxuXTtcbiJdfQ==
;