@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.
471 lines • 56.2 kB
JavaScript
"use strict";
var _a;
Object.defineProperty(exports, "__esModule", { value: true });
exports.JobApi = 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_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/jobs');
/**
* Job API construct.
*
* @stability stable
*/
class JobApi extends constructs_1.Construct {
/**
* @stability stable
*/
constructor(scope, id, props) {
var _b, _c, _d, _e;
super(scope, id);
this._restApi = new cdk_restapi_1.RestApi(this, 'JobRestApi', {
enableCors: true,
authorizationType: (_b = props === null || props === void 0 ? void 0 : props.authorizationType) !== null && _b !== void 0 ? _b : aws_apigateway_1.AuthorizationType.NONE,
authorizer: (_c = props === null || props === void 0 ? void 0 : props.authorizer) !== null && _c !== void 0 ? _c : undefined,
resources: [
{
path: '/jobs/{jobId}/associate',
httpMethod: cdk_restapi_1.HttpMethod.PUT,
lambdaFunction: this.createAssociateTargetsWithJobFunction(),
},
{
path: '/jobs',
httpMethod: cdk_restapi_1.HttpMethod.POST,
lambdaFunction: this.createCreateJobFunction(),
},
{
path: '/jobs',
httpMethod: cdk_restapi_1.HttpMethod.GET,
lambdaFunction: this.createListJobsFunction(),
},
{
path: '/jobs/{jobId}',
httpMethod: cdk_restapi_1.HttpMethod.GET,
lambdaFunction: this.createGetJobFunction(),
},
{
path: '/jobs/{jobId}',
httpMethod: cdk_restapi_1.HttpMethod.PUT,
lambdaFunction: this.createUpdateJobFunction(),
},
{
path: '/jobs/{jobId}',
httpMethod: cdk_restapi_1.HttpMethod.DELETE,
lambdaFunction: this.createDeleteJobFunction(),
},
{
path: '/jobs/{jobId}/cancel',
httpMethod: cdk_restapi_1.HttpMethod.PUT,
lambdaFunction: this.createCancelJobFunction(),
},
{
path: '/jobs/{jobId}/document',
httpMethod: cdk_restapi_1.HttpMethod.GET,
lambdaFunction: this.createGetJobDocumentFunction(),
},
{
path: '/jobs/{jobId}/things/{thingName}',
httpMethod: cdk_restapi_1.HttpMethod.GET,
lambdaFunction: this.createGetJobExecutionFunction(),
},
{
path: 'jobs/{jobId}/status',
httpMethod: cdk_restapi_1.HttpMethod.GET,
lambdaFunction: this.createListJobExecutionsForJobFunction(),
},
{
path: '/things/{thingName}/jobs',
httpMethod: cdk_restapi_1.HttpMethod.GET,
lambdaFunction: this.createListJobExecutionsForThingFunction(),
},
{
path: '/jobs/{jobId}/things/{thingName}',
httpMethod: cdk_restapi_1.HttpMethod.DELETE,
lambdaFunction: this.createDeleteJobExecutionFunction(),
},
{
path: '/jobs/{jobId}/things/{thingName}/cancel',
httpMethod: cdk_restapi_1.HttpMethod.PUT,
lambdaFunction: this.createCancelJobExecutionFunction(),
},
{
path: '/job-templates',
httpMethod: cdk_restapi_1.HttpMethod.POST,
lambdaFunction: this.createCreateJobTemplateFunction(),
},
{
path: '/job-templates',
httpMethod: cdk_restapi_1.HttpMethod.GET,
lambdaFunction: this.createListJobTemplatesFunction(),
},
{
path: '/job-templates/{jobTemplateId}',
httpMethod: cdk_restapi_1.HttpMethod.GET,
lambdaFunction: this.createGetJobTemplateFunction(),
},
{
path: '/job-templates/{jobTemplateId}',
httpMethod: cdk_restapi_1.HttpMethod.DELETE,
lambdaFunction: this.createDeleteJobTemplateFunction(),
},
],
});
if (props === null || props === void 0 ? void 0 : props.scheduleFunction) {
const targetType = 'CreateJob';
props.scheduleFunction.addTargetFunction(targetType, {
targetFunction: this.createCreateScheduleJobFunction(),
});
(_d = props === null || props === void 0 ? void 0 : props.scheduleFunction) === null || _d === void 0 ? void 0 : _d.listSchedulesFunction.addEnvironment('FIXED_TARGET_TYPE', targetType);
(_e = props === null || props === void 0 ? void 0 : props.scheduleFunction) === null || _e === void 0 ? void 0 : _e.createScheduleFunction.addEnvironment('FIXED_TARGET_TYPE', targetType);
this._restApi.addResources([
{
path: '/schedules',
httpMethod: cdk_restapi_1.HttpMethod.GET,
lambdaFunction: props === null || props === void 0 ? void 0 : props.scheduleFunction.listSchedulesFunction,
},
{
path: '/schedules',
httpMethod: cdk_restapi_1.HttpMethod.POST,
lambdaFunction: props === null || props === void 0 ? void 0 : props.scheduleFunction.createScheduleFunction,
},
{
path: '/schedules/{scheduleId}',
httpMethod: cdk_restapi_1.HttpMethod.GET,
lambdaFunction: props === null || props === void 0 ? void 0 : props.scheduleFunction.fetchScheduleFunction,
},
{
path: '/schedules/{scheduleId}',
httpMethod: cdk_restapi_1.HttpMethod.PUT,
lambdaFunction: props === null || props === void 0 ? void 0 : props.scheduleFunction.updateScheduleFunction,
},
{
path: '/schedules/{scheduleId}',
httpMethod: cdk_restapi_1.HttpMethod.DELETE,
lambdaFunction: props === null || props === void 0 ? void 0 : props.scheduleFunction.deleteScheduleFunction,
},
]);
}
}
/**
* Job API API ID.
*
* @stability stable
*/
get restApiId() {
return this._restApi.restApiId;
}
createCreateScheduleJobFunction() {
var _b;
const createJobFunction = new aws_lambda_nodejs_1.NodejsFunction(this, 'CreateScheduleJobFunction', {
entry: `${LAMBDA_ASSETS_PATH}/create-schedule-job/app.ts`,
});
(_b = createJobFunction.role) === null || _b === void 0 ? void 0 : _b.attachInlinePolicy(new aws_iam_1.Policy(this, 'iot-create-schedule-job-policy', {
statements: [
new aws_iam_1.PolicyStatement({
actions: [
'iot:CreateJob',
],
resources: ['*'],
}),
],
}));
return createJobFunction;
}
createAssociateTargetsWithJobFunction() {
var _b;
const createJobFunction = new aws_lambda_nodejs_1.NodejsFunction(this, 'AssociateTargetsWithJobFunction', {
entry: `${LAMBDA_ASSETS_PATH}/associate-targets-with-job/app.ts`,
});
(_b = createJobFunction.role) === null || _b === void 0 ? void 0 : _b.attachInlinePolicy(new aws_iam_1.Policy(this, 'iot-associate-targets-with-job', {
statements: [
new aws_iam_1.PolicyStatement({
actions: [
'iot:AssociateTargetsWithJob',
],
resources: ['*'],
}),
],
}));
return createJobFunction;
}
createCreateJobFunction() {
var _b;
const createJobFunction = new aws_lambda_nodejs_1.NodejsFunction(this, 'CreateJobFunction', {
entry: `${LAMBDA_ASSETS_PATH}/create-job/app.ts`,
});
(_b = createJobFunction.role) === null || _b === void 0 ? void 0 : _b.attachInlinePolicy(new aws_iam_1.Policy(this, 'iot-create-job-policy', {
statements: [
new aws_iam_1.PolicyStatement({
actions: [
'iot:CreateJob',
],
resources: ['*'],
}),
],
}));
return createJobFunction;
}
createListJobsFunction() {
var _b;
const listJobsFunction = new aws_lambda_nodejs_1.NodejsFunction(this, 'ListJobsFunction', {
entry: `${LAMBDA_ASSETS_PATH}/list-jobs/app.ts`,
});
(_b = listJobsFunction.role) === null || _b === void 0 ? void 0 : _b.attachInlinePolicy(new aws_iam_1.Policy(this, 'iot-list-jobs-policy', {
statements: [
new aws_iam_1.PolicyStatement({
actions: [
'iot:ListJobs',
],
resources: ['*'],
}),
],
}));
return listJobsFunction;
}
createGetJobFunction() {
var _b;
const getJobFunction = new aws_lambda_nodejs_1.NodejsFunction(this, 'GetJobFunction', {
entry: `${LAMBDA_ASSETS_PATH}/get-job/app.ts`,
});
(_b = getJobFunction.role) === null || _b === void 0 ? void 0 : _b.attachInlinePolicy(new aws_iam_1.Policy(this, 'iot-describe-job-policy', {
statements: [
new aws_iam_1.PolicyStatement({
actions: [
'iot:DescribeJob',
],
resources: ['*'],
}),
],
}));
return getJobFunction;
}
createUpdateJobFunction() {
var _b;
const updateJobFunction = new aws_lambda_nodejs_1.NodejsFunction(this, 'UpdateJobFunction', {
entry: `${LAMBDA_ASSETS_PATH}/update-job/app.ts`,
});
(_b = updateJobFunction.role) === null || _b === void 0 ? void 0 : _b.attachInlinePolicy(new aws_iam_1.Policy(this, 'iot-update-job-policy', {
statements: [
new aws_iam_1.PolicyStatement({
actions: [
'iot:UpdateJob',
],
resources: ['*'],
}),
],
}));
return updateJobFunction;
}
createDeleteJobFunction() {
var _b;
const deleteJobFunction = new aws_lambda_nodejs_1.NodejsFunction(this, 'DeleteJobFunction', {
entry: `${LAMBDA_ASSETS_PATH}/delete-job/app.ts`,
});
(_b = deleteJobFunction.role) === null || _b === void 0 ? void 0 : _b.attachInlinePolicy(new aws_iam_1.Policy(this, 'iot-delete-job-policy', {
statements: [
new aws_iam_1.PolicyStatement({
actions: [
'iot:DeleteJob',
],
resources: ['*'],
}),
],
}));
return deleteJobFunction;
}
createCancelJobFunction() {
var _b;
const cancelJobFunction = new aws_lambda_nodejs_1.NodejsFunction(this, 'CancelJobFunction', {
entry: `${LAMBDA_ASSETS_PATH}/cancel-job/app.ts`,
});
(_b = cancelJobFunction.role) === null || _b === void 0 ? void 0 : _b.attachInlinePolicy(new aws_iam_1.Policy(this, 'iot-cancel-job-policy', {
statements: [
new aws_iam_1.PolicyStatement({
actions: [
'iot:CancelJob',
],
resources: ['*'],
}),
],
}));
return cancelJobFunction;
}
createGetJobExecutionFunction() {
var _b;
const getJobExecutionFunction = new aws_lambda_nodejs_1.NodejsFunction(this, 'GetJobExecutionFunction', {
entry: `${LAMBDA_ASSETS_PATH}/get-job-execution/app.ts`,
});
(_b = getJobExecutionFunction.role) === null || _b === void 0 ? void 0 : _b.attachInlinePolicy(new aws_iam_1.Policy(this, 'iot-describe-job-execution-policy', {
statements: [
new aws_iam_1.PolicyStatement({
actions: [
'iot:DescribeJobExecution',
],
resources: ['*'],
}),
],
}));
return getJobExecutionFunction;
}
createListJobExecutionsForJobFunction() {
var _b;
const listJobExecutionsForJob = new aws_lambda_nodejs_1.NodejsFunction(this, 'listJobExecutionsForJob', {
entry: `${LAMBDA_ASSETS_PATH}/list-job-executions-for-job/app.ts`,
});
(_b = listJobExecutionsForJob.role) === null || _b === void 0 ? void 0 : _b.attachInlinePolicy(new aws_iam_1.Policy(this, 'list-job-execution-for-job', {
statements: [
new aws_iam_1.PolicyStatement({
actions: [
'iot:ListJobExecutionsForJob',
],
resources: ['*'],
}),
],
}));
return listJobExecutionsForJob;
}
createListJobExecutionsForThingFunction() {
var _b;
const listJobExecutionsForThing = new aws_lambda_nodejs_1.NodejsFunction(this, 'listJobExecutionsForThing', {
entry: `${LAMBDA_ASSETS_PATH}/list-job-executions-for-thing/app.ts`,
});
(_b = listJobExecutionsForThing.role) === null || _b === void 0 ? void 0 : _b.attachInlinePolicy(new aws_iam_1.Policy(this, 'list-job-executions-for-thing', {
statements: [
new aws_iam_1.PolicyStatement({
actions: [
'iot:ListJobExecutionsForThing',
],
resources: ['*'],
}),
],
}));
return listJobExecutionsForThing;
}
createDeleteJobExecutionFunction() {
var _b;
const deleteJobExecutionFunction = new aws_lambda_nodejs_1.NodejsFunction(this, 'DeleteJobExecutionFunction', {
entry: `${LAMBDA_ASSETS_PATH}/delete-job-execution/app.ts`,
});
(_b = deleteJobExecutionFunction.role) === null || _b === void 0 ? void 0 : _b.attachInlinePolicy(new aws_iam_1.Policy(this, 'iot-delete-job-execution-policy', {
statements: [
new aws_iam_1.PolicyStatement({
actions: [
'iot:DeleteJobExecution',
],
resources: ['*'],
}),
],
}));
return deleteJobExecutionFunction;
}
createCancelJobExecutionFunction() {
var _b;
const cancelJobExecutionFunction = new aws_lambda_nodejs_1.NodejsFunction(this, 'CancelJobExecutionFunction', {
entry: `${LAMBDA_ASSETS_PATH}/cancel-job-execution/app.ts`,
});
(_b = cancelJobExecutionFunction.role) === null || _b === void 0 ? void 0 : _b.attachInlinePolicy(new aws_iam_1.Policy(this, 'iot-cancel-job-execution-policy', {
statements: [
new aws_iam_1.PolicyStatement({
actions: [
'iot:CancelJobExecution',
],
resources: ['*'],
}),
],
}));
return cancelJobExecutionFunction;
}
createGetJobDocumentFunction() {
var _b;
const getJobDocumentFunction = new aws_lambda_nodejs_1.NodejsFunction(this, 'GetJobDocumentFunction', {
entry: `${LAMBDA_ASSETS_PATH}/get-job-document/app.ts`,
});
(_b = getJobDocumentFunction.role) === null || _b === void 0 ? void 0 : _b.attachInlinePolicy(new aws_iam_1.Policy(this, 'iot-get-job-document', {
statements: [
new aws_iam_1.PolicyStatement({
actions: [
'iot:GetJobDocument',
],
resources: ['*'],
}),
],
}));
return getJobDocumentFunction;
}
createCreateJobTemplateFunction() {
var _b;
const createJobTemplateFunction = new aws_lambda_nodejs_1.NodejsFunction(this, 'CreateJobTemplateFunction', {
entry: `${LAMBDA_ASSETS_PATH}/create-job-template/app.ts`,
});
(_b = createJobTemplateFunction.role) === null || _b === void 0 ? void 0 : _b.attachInlinePolicy(new aws_iam_1.Policy(this, 'iot-create-job-template-policy', {
statements: [
new aws_iam_1.PolicyStatement({
actions: [
'iot:CreateJobTemplate',
],
resources: ['*'],
}),
],
}));
return createJobTemplateFunction;
}
createListJobTemplatesFunction() {
var _b;
const listJobTemplatesFunction = new aws_lambda_nodejs_1.NodejsFunction(this, 'ListJobTemplatesFunction', {
entry: `${LAMBDA_ASSETS_PATH}/list-job-templates/app.ts`,
});
(_b = listJobTemplatesFunction.role) === null || _b === void 0 ? void 0 : _b.attachInlinePolicy(new aws_iam_1.Policy(this, 'iot-list-job-templates-policy', {
statements: [
new aws_iam_1.PolicyStatement({
actions: [
'iot:ListJobTemplates',
],
resources: ['*'],
}),
],
}));
return listJobTemplatesFunction;
}
createGetJobTemplateFunction() {
var _b;
const getJobTemplateFunction = new aws_lambda_nodejs_1.NodejsFunction(this, 'GetJobTemplateFunction', {
entry: `${LAMBDA_ASSETS_PATH}/get-job-template/app.ts`,
});
(_b = getJobTemplateFunction.role) === null || _b === void 0 ? void 0 : _b.attachInlinePolicy(new aws_iam_1.Policy(this, 'iot-get-job-template', {
statements: [
new aws_iam_1.PolicyStatement({
actions: [
'iot:DescribeJobTemplate',
],
resources: ['*'],
}),
],
}));
return getJobTemplateFunction;
}
createDeleteJobTemplateFunction() {
var _b;
const deleteJobTemplateFunction = new aws_lambda_nodejs_1.NodejsFunction(this, 'DeleteJobTemplateFunction', {
entry: `${LAMBDA_ASSETS_PATH}/delete-job-template/app.ts`,
});
(_b = deleteJobTemplateFunction.role) === null || _b === void 0 ? void 0 : _b.attachInlinePolicy(new aws_iam_1.Policy(this, 'iot-delete-job-template-policy', {
statements: [
new aws_iam_1.PolicyStatement({
actions: [
'iot:DeleteJobTemplate',
],
resources: ['*'],
}),
],
}));
return deleteJobTemplateFunction;
}
}
exports.JobApi = JobApi;
_a = JSII_RTTI_SYMBOL_1;
JobApi[_a] = { fqn: "@softchef/cdk-iot-device-management.JobApi", version: "2.0.0" };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiam9iLWFwaS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9qb2ItYXBpLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsNkJBQTZCO0FBQzdCLHVEQUcrQjtBQUkvQiwrREFHb0M7QUFDcEMsaURBRzZCO0FBQzdCLHFFQUV1QztBQUN2QywyQ0FFb0I7QUFFcEIsTUFBTSxrQkFBa0IsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsRUFBRSx1QkFBdUIsQ0FBQyxDQUFDOzs7Ozs7QUFhNUUsTUFBYSxNQUFPLFNBQVEsc0JBQVM7Ozs7SUFNbkMsWUFBWSxLQUFnQixFQUFFLEVBQVUsRUFBRSxLQUFtQjs7UUFDM0QsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztRQUNqQixJQUFJLENBQUMsUUFBUSxHQUFHLElBQUkscUJBQU8sQ0FBQyxJQUFJLEVBQUUsWUFBWSxFQUFFO1lBQzlDLFVBQVUsRUFBRSxJQUFJO1lBQ2hCLGlCQUFpQixRQUFFLEtBQUssYUFBTCxLQUFLLHVCQUFMLEtBQUssQ0FBRSxpQkFBaUIsbUNBQUksa0NBQWlCLENBQUMsSUFBSTtZQUNyRSxVQUFVLFFBQUUsS0FBSyxhQUFMLEtBQUssdUJBQUwsS0FBSyxDQUFFLFVBQVUsbUNBQUksU0FBUztZQUMxQyxTQUFTLEVBQUU7Z0JBQ1Q7b0JBQ0UsSUFBSSxFQUFFLHlCQUF5QjtvQkFDL0IsVUFBVSxFQUFFLHdCQUFVLENBQUMsR0FBRztvQkFDMUIsY0FBYyxFQUFFLElBQUksQ0FBQyxxQ0FBcUMsRUFBRTtpQkFDN0Q7Z0JBQ0Q7b0JBQ0UsSUFBSSxFQUFFLE9BQU87b0JBQ2IsVUFBVSxFQUFFLHdCQUFVLENBQUMsSUFBSTtvQkFDM0IsY0FBYyxFQUFFLElBQUksQ0FBQyx1QkFBdUIsRUFBRTtpQkFDL0M7Z0JBQ0Q7b0JBQ0UsSUFBSSxFQUFFLE9BQU87b0JBQ2IsVUFBVSxFQUFFLHdCQUFVLENBQUMsR0FBRztvQkFDMUIsY0FBYyxFQUFFLElBQUksQ0FBQyxzQkFBc0IsRUFBRTtpQkFDOUM7Z0JBQ0Q7b0JBQ0UsSUFBSSxFQUFFLGVBQWU7b0JBQ3JCLFVBQVUsRUFBRSx3QkFBVSxDQUFDLEdBQUc7b0JBQzFCLGNBQWMsRUFBRSxJQUFJLENBQUMsb0JBQW9CLEVBQUU7aUJBQzVDO2dCQUNEO29CQUNFLElBQUksRUFBRSxlQUFlO29CQUNyQixVQUFVLEVBQUUsd0JBQVUsQ0FBQyxHQUFHO29CQUMxQixjQUFjLEVBQUUsSUFBSSxDQUFDLHVCQUF1QixFQUFFO2lCQUMvQztnQkFDRDtvQkFDRSxJQUFJLEVBQUUsZUFBZTtvQkFDckIsVUFBVSxFQUFFLHdCQUFVLENBQUMsTUFBTTtvQkFDN0IsY0FBYyxFQUFFLElBQUksQ0FBQyx1QkFBdUIsRUFBRTtpQkFDL0M7Z0JBQ0Q7b0JBQ0UsSUFBSSxFQUFFLHNCQUFzQjtvQkFDNUIsVUFBVSxFQUFFLHdCQUFVLENBQUMsR0FBRztvQkFDMUIsY0FBYyxFQUFFLElBQUksQ0FBQyx1QkFBdUIsRUFBRTtpQkFDL0M7Z0JBQ0Q7b0JBQ0UsSUFBSSxFQUFFLHdCQUF3QjtvQkFDOUIsVUFBVSxFQUFFLHdCQUFVLENBQUMsR0FBRztvQkFDMUIsY0FBYyxFQUFFLElBQUksQ0FBQyw0QkFBNEIsRUFBRTtpQkFDcEQ7Z0JBQ0Q7b0JBQ0UsSUFBSSxFQUFFLGtDQUFrQztvQkFDeEMsVUFBVSxFQUFFLHdCQUFVLENBQUMsR0FBRztvQkFDMUIsY0FBYyxFQUFFLElBQUksQ0FBQyw2QkFBNkIsRUFBRTtpQkFDckQ7Z0JBQ0Q7b0JBQ0UsSUFBSSxFQUFFLHFCQUFxQjtvQkFDM0IsVUFBVSxFQUFFLHdCQUFVLENBQUMsR0FBRztvQkFDMUIsY0FBYyxFQUFFLElBQUksQ0FBQyxxQ0FBcUMsRUFBRTtpQkFDN0Q7Z0JBQ0Q7b0JBQ0UsSUFBSSxFQUFFLDBCQUEwQjtvQkFDaEMsVUFBVSxFQUFFLHdCQUFVLENBQUMsR0FBRztvQkFDMUIsY0FBYyxFQUFFLElBQUksQ0FBQyx1Q0FBdUMsRUFBRTtpQkFDL0Q7Z0JBQ0Q7b0JBQ0UsSUFBSSxFQUFFLGtDQUFrQztvQkFDeEMsVUFBVSxFQUFFLHdCQUFVLENBQUMsTUFBTTtvQkFDN0IsY0FBYyxFQUFFLElBQUksQ0FBQyxnQ0FBZ0MsRUFBRTtpQkFDeEQ7Z0JBQ0Q7b0JBQ0UsSUFBSSxFQUFFLHlDQUF5QztvQkFDL0MsVUFBVSxFQUFFLHdCQUFVLENBQUMsR0FBRztvQkFDMUIsY0FBYyxFQUFFLElBQUksQ0FBQyxnQ0FBZ0MsRUFBRTtpQkFDeEQ7Z0JBQ0Q7b0JBQ0UsSUFBSSxFQUFFLGdCQUFnQjtvQkFDdEIsVUFBVSxFQUFFLHdCQUFVLENBQUMsSUFBSTtvQkFDM0IsY0FBYyxFQUFFLElBQUksQ0FBQywrQkFBK0IsRUFBRTtpQkFDdkQ7Z0JBQ0Q7b0JBQ0UsSUFBSSxFQUFFLGdCQUFnQjtvQkFDdEIsVUFBVSxFQUFFLHdCQUFVLENBQUMsR0FBRztvQkFDMUIsY0FBYyxFQUFFLElBQUksQ0FBQyw4QkFBOEIsRUFBRTtpQkFDdEQ7Z0JBQ0Q7b0JBQ0UsSUFBSSxFQUFFLGdDQUFnQztvQkFDdEMsVUFBVSxFQUFFLHdCQUFVLENBQUMsR0FBRztvQkFDMUIsY0FBYyxFQUFFLElBQUksQ0FBQyw0QkFBNEIsRUFBRTtpQkFDcEQ7Z0JBQ0Q7b0JBQ0UsSUFBSSxFQUFFLGdDQUFnQztvQkFDdEMsVUFBVSxFQUFFLHdCQUFVLENBQUMsTUFBTTtvQkFDN0IsY0FBYyxFQUFFLElBQUksQ0FBQywrQkFBK0IsRUFBRTtpQkFDdkQ7YUFDRjtTQUNGLENBQUMsQ0FBQztRQUNILElBQUksS0FBSyxhQUFMLEtBQUssdUJBQUwsS0FBSyxDQUFFLGdCQUFnQixFQUFFO1lBQzNCLE1BQU0sVUFBVSxHQUFXLFdBQVcsQ0FBQztZQUN2QyxLQUFLLENBQUMsZ0JBQWdCLENBQUMsaUJBQWlCLENBQUMsVUFBVSxFQUFFO2dCQUNuRCxjQUFjLEVBQUUsSUFBSSxDQUFDLCtCQUErQixFQUFFO2FBQ3ZELENBQUMsQ0FBQztZQUNILE1BQUEsS0FBSyxhQUFMLEtBQUssdUJBQUwsS0FBSyxDQUFFLGdCQUFnQiwwQ0FBRSxxQkFBcUIsQ0FBQyxjQUFjLENBQUMsbUJBQW1CLEVBQUUsVUFBVSxFQUFFO1lBQy9GLE1BQUEsS0FBSyxhQUFMLEtBQUssdUJBQUwsS0FBSyxDQUFFLGdCQUFnQiwwQ0FBRSxzQkFBc0IsQ0FBQyxjQUFjLENBQUMsbUJBQW1CLEVBQUUsVUFBVSxFQUFFO1lBQ2hHLElBQUksQ0FBQyxRQUFRLENBQUMsWUFBWSxDQUFDO2dCQUN6QjtvQkFDRSxJQUFJLEVBQUUsWUFBWTtvQkFDbEIsVUFBVSxFQUFFLHdCQUFVLENBQUMsR0FBRztvQkFDMUIsY0FBYyxFQUFFLEtBQUssYUFBTCxLQUFLLHVCQUFMLEtBQUssQ0FBRSxnQkFBZ0IsQ0FBQyxxQkFBcUI7aUJBQzlEO2dCQUNEO29CQUNFLElBQUksRUFBRSxZQUFZO29CQUNsQixVQUFVLEVBQUUsd0JBQVUsQ0FBQyxJQUFJO29CQUMzQixjQUFjLEVBQUUsS0FBSyxhQUFMLEtBQUssdUJBQUwsS0FBSyxDQUFFLGdCQUFnQixDQUFDLHNCQUFzQjtpQkFDL0Q7Z0JBQ0Q7b0JBQ0UsSUFBSSxFQUFFLHlCQUF5QjtvQkFDL0IsVUFBVSxFQUFFLHdCQUFVLENBQUMsR0FBRztvQkFDMUIsY0FBYyxFQUFFLEtBQUssYUFBTCxLQUFLLHVCQUFMLEtBQUssQ0FBRSxnQkFBZ0IsQ0FBQyxxQkFBcUI7aUJBQzlEO2dCQUNEO29CQUNFLElBQUksRUFBRSx5QkFBeUI7b0JBQy9CLFVBQVUsRUFBRSx3QkFBVSxDQUFDLEdBQUc7b0JBQzFCLGNBQWMsRUFBRSxLQUFLLGFBQUwsS0FBSyx1QkFBTCxLQUFLLENBQUUsZ0JBQWdCLENBQUMsc0JBQXNCO2lCQUMvRDtnQkFDRDtvQkFDRSxJQUFJLEVBQUUseUJBQXlCO29CQUMvQixVQUFVLEVBQUUsd0JBQVUsQ0FBQyxNQUFNO29CQUM3QixjQUFjLEVBQUUsS0FBSyxhQUFMLEtBQUssdUJBQUwsS0FBSyxDQUFFLGdCQUFnQixDQUFDLHNCQUFzQjtpQkFDL0Q7YUFDRixDQUFDLENBQUM7U0FDSjtJQUNILENBQUM7Ozs7OztJQUdELElBQUksU0FBUztRQUNYLE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUM7SUFDakMsQ0FBQztJQUVPLCtCQUErQjs7UUFDckMsTUFBTSxpQkFBaUIsR0FBRyxJQUFJLGtDQUFjLENBQUMsSUFBSSxFQUFFLDJCQUEyQixFQUFFO1lBQzlFLEtBQUssRUFBRSxHQUFHLGtCQUFrQiw2QkFBNkI7U0FDMUQsQ0FBQyxDQUFDO1FBQ0gsTUFBQSxpQkFBaUIsQ0FBQyxJQUFJLDBDQUFFLGtCQUFrQixDQUN4QyxJQUFJLGdCQUFNLENBQUMsSUFBSSxFQUFFLGdDQUFnQyxFQUFFO1lBQ2pELFVBQVUsRUFBRTtnQkFDVixJQUFJLHlCQUFlLENBQUM7b0JBQ2xCLE9BQU8sRUFBRTt3QkFDUCxlQUFlO3FCQUNoQjtvQkFDRCxTQUFTLEVBQUUsQ0FBQyxHQUFHLENBQUM7aUJBQ2pCLENBQUM7YUFDSDtTQUNGLENBQUMsRUFDRjtRQUNGLE9BQU8saUJBQWlCLENBQUM7SUFDM0IsQ0FBQztJQUVPLHFDQUFxQzs7UUFDM0MsTUFBTSxpQkFBaUIsR0FBRyxJQUFJLGtDQUFjLENBQUMsSUFBSSxFQUFFLGlDQUFpQyxFQUFFO1lBQ3BGLEtBQUssRUFBRSxHQUFHLGtCQUFrQixvQ0FBb0M7U0FDakUsQ0FBQyxDQUFDO1FBQ0gsTUFBQSxpQkFBaUIsQ0FBQyxJQUFJLDBDQUFFLGtCQUFrQixDQUN4QyxJQUFJLGdCQUFNLENBQUMsSUFBSSxFQUFFLGdDQUFnQyxFQUFFO1lBQ2pELFVBQVUsRUFBRTtnQkFDVixJQUFJLHlCQUFlLENBQUM7b0JBQ2xCLE9BQU8sRUFBRTt3QkFDUCw2QkFBNkI7cUJBQzlCO29CQUNELFNBQVMsRUFBRSxDQUFDLEdBQUcsQ0FBQztpQkFDakIsQ0FBQzthQUNIO1NBQ0YsQ0FBQyxFQUNGO1FBQ0YsT0FBTyxpQkFBaUIsQ0FBQztJQUMzQixDQUFDO0lBRU8sdUJBQXVCOztRQUM3QixNQUFNLGlCQUFpQixHQUFHLElBQUksa0NBQWMsQ0FBQyxJQUFJLEVBQUUsbUJBQW1CLEVBQUU7WUFDdEUsS0FBSyxFQUFFLEdBQUcsa0JBQWtCLG9CQUFvQjtTQUNqRCxDQUFDLENBQUM7UUFDSCxNQUFBLGlCQUFpQixDQUFDLElBQUksMENBQUUsa0JBQWtCLENBQ3hDLElBQUksZ0JBQU0sQ0FBQyxJQUFJLEVBQUUsdUJBQXVCLEVBQUU7WUFDeEMsVUFBVSxFQUFFO2dCQUNWLElBQUkseUJBQWUsQ0FBQztvQkFDbEIsT0FBTyxFQUFFO3dCQUNQLGVBQWU7cUJBQ2hCO29CQUNELFNBQVMsRUFBRSxDQUFDLEdBQUcsQ0FBQztpQkFDakIsQ0FBQzthQUNIO1NBQ0YsQ0FBQyxFQUNGO1FBQ0YsT0FBTyxpQkFBaUIsQ0FBQztJQUMzQixDQUFDO0lBRU8sc0JBQXNCOztRQUM1QixNQUFNLGdCQUFnQixHQUFHLElBQUksa0NBQWMsQ0FBQyxJQUFJLEVBQUUsa0JBQWtCLEVBQUU7WUFDcEUsS0FBSyxFQUFFLEdBQUcsa0JBQWtCLG1CQUFtQjtTQUNoRCxDQUFDLENBQUM7UUFDSCxNQUFBLGdCQUFnQixDQUFDLElBQUksMENBQUUsa0JBQWtCLENBQ3ZDLElBQUksZ0JBQU0sQ0FBQyxJQUFJLEVBQUUsc0JBQXNCLEVBQUU7WUFDdkMsVUFBVSxFQUFFO2dCQUNWLElBQUkseUJBQWUsQ0FBQztvQkFDbEIsT0FBTyxFQUFFO3dCQUNQLGNBQWM7cUJBQ2Y7b0JBQ0QsU0FBUyxFQUFFLENBQUMsR0FBRyxDQUFDO2lCQUNqQixDQUFDO2FBQ0g7U0FDRixDQUFDLEVBQ0Y7UUFDRixPQUFPLGdCQUFnQixDQUFDO0lBQzFCLENBQUM7SUFFTyxvQkFBb0I7O1FBQzFCLE1BQU0sY0FBYyxHQUFHLElBQUksa0NBQWMsQ0FBQyxJQUFJLEVBQUUsZ0JBQWdCLEVBQUU7WUFDaEUsS0FBSyxFQUFFLEdBQUcsa0JBQWtCLGlCQUFpQjtTQUM5QyxDQUFDLENBQUM7UUFDSCxNQUFBLGNBQWMsQ0FBQyxJQUFJLDBDQUFFLGtCQUFrQixDQUNyQyxJQUFJLGdCQUFNLENBQUMsSUFBSSxFQUFFLHlCQUF5QixFQUFFO1lBQzFDLFVBQVUsRUFBRTtnQkFDVixJQUFJLHlCQUFlLENBQUM7b0JBQ2xCLE9BQU8sRUFBRTt3QkFDUCxpQkFBaUI7cUJBQ2xCO29CQUNELFNBQVMsRUFBRSxDQUFDLEdBQUcsQ0FBQztpQkFDakIsQ0FBQzthQUNIO1NBQ0YsQ0FBQyxFQUNGO1FBQ0YsT0FBTyxjQUFjLENBQUM7SUFDeEIsQ0FBQztJQUVPLHVCQUF1Qjs7UUFDN0IsTUFBTSxpQkFBaUIsR0FBRyxJQUFJLGtDQUFjLENBQUMsSUFBSSxFQUFFLG1CQUFtQixFQUFFO1lBQ3RFLEtBQUssRUFBRSxHQUFHLGtCQUFrQixvQkFBb0I7U0FDakQsQ0FBQyxDQUFDO1FBQ0gsTUFBQSxpQkFBaUIsQ0FBQyxJQUFJLDBDQUFFLGtCQUFrQixDQUN4QyxJQUFJLGdCQUFNLENBQUMsSUFBSSxFQUFFLHVCQUF1QixFQUFFO1lBQ3hDLFVBQVUsRUFBRTtnQkFDVixJQUFJLHlCQUFlLENBQUM7b0JBQ2xCLE9BQU8sRUFBRTt3QkFDUCxlQUFlO3FCQUNoQjtvQkFDRCxTQUFTLEVBQUUsQ0FBQyxHQUFHLENBQUM7aUJBQ2pCLENBQUM7YUFDSDtTQUNGLENBQUMsRUFDRjtRQUNGLE9BQU8saUJBQWlCLENBQUM7SUFDM0IsQ0FBQztJQUVPLHVCQUF1Qjs7UUFDN0IsTUFBTSxpQkFBaUIsR0FBRyxJQUFJLGtDQUFjLENBQUMsSUFBSSxFQUFFLG1CQUFtQixFQUFFO1lBQ3RFLEtBQUssRUFBRSxHQUFHLGtCQUFrQixvQkFBb0I7U0FDakQsQ0FBQyxDQUFDO1FBQ0gsTUFBQSxpQkFBaUIsQ0FBQyxJQUFJLDBDQUFFLGtCQUFrQixDQUN4QyxJQUFJLGdCQUFNLENBQUMsSUFBSSxFQUFFLHVCQUF1QixFQUFFO1lBQ3hDLFVBQVUsRUFBRTtnQkFDVixJQUFJLHlCQUFlLENBQUM7b0JBQ2xCLE9BQU8sRUFBRTt3QkFDUCxlQUFlO3FCQUNoQjtvQkFDRCxTQUFTLEVBQUUsQ0FBQyxHQUFHLENBQUM7aUJBQ2pCLENBQUM7YUFDSDtTQUNGLENBQUMsRUFDRjtRQUNGLE9BQU8saUJBQWlCLENBQUM7SUFDM0IsQ0FBQztJQUVPLHVCQUF1Qjs7UUFDN0IsTUFBTSxpQkFBaUIsR0FBRyxJQUFJLGtDQUFjLENBQUMsSUFBSSxFQUFFLG1CQUFtQixFQUFFO1lBQ3RFLEtBQUssRUFBRSxHQUFHLGtCQUFrQixvQkFBb0I7U0FDakQsQ0FBQyxDQUFDO1FBQ0gsTUFBQSxpQkFBaUIsQ0FBQyxJQUFJLDBDQUFFLGtCQUFrQixDQUN4QyxJQUFJLGdCQUFNLENBQUMsSUFBSSxFQUFFLHVCQUF1QixFQUFFO1lBQ3hDLFVBQVUsRUFBRTtnQkFDVixJQUFJLHlCQUFlLENBQUM7b0JBQ2xCLE9BQU8sRUFBRTt3QkFDUCxlQUFlO3FCQUNoQjtvQkFDRCxTQUFTLEVBQUUsQ0FBQyxHQUFHLENBQUM7aUJBQ2pCLENBQUM7YUFDSDtTQUNGLENBQUMsRUFDRjtRQUNGLE9BQU8saUJBQWlCLENBQUM7SUFDM0IsQ0FBQztJQUVPLDZCQUE2Qjs7UUFDbkMsTUFBTSx1QkFBdUIsR0FBRyxJQUFJLGtDQUFjLENBQUMsSUFBSSxFQUFFLHlCQUF5QixFQUFFO1lBQ2xGLEtBQUssRUFBRSxHQUFHLGtCQUFrQiwyQkFBMkI7U0FDeEQsQ0FBQyxDQUFDO1FBQ0gsTUFBQSx1QkFBdUIsQ0FBQyxJQUFJLDBDQUFFLGtCQUFrQixDQUM5QyxJQUFJLGdCQUFNLENBQUMsSUFBSSxFQUFFLG1DQUFtQyxFQUFFO1lBQ3BELFVBQVUsRUFBRTtnQkFDVixJQUFJLHlCQUFlLENBQUM7b0JBQ2xCLE9BQU8sRUFBRTt3QkFDUCwwQkFBMEI7cUJBQzNCO29CQUNELFNBQVMsRUFBRSxDQUFDLEdBQUcsQ0FBQztpQkFDakIsQ0FBQzthQUNIO1NBQ0YsQ0FBQyxFQUNGO1FBQ0YsT0FBTyx1QkFBdUIsQ0FBQztJQUNqQyxDQUFDO0lBRU8scUNBQXFDOztRQUMzQyxNQUFNLHVCQUF1QixHQUFHLElBQUksa0NBQWMsQ0FBQyxJQUFJLEVBQUUseUJBQXlCLEVBQUU7WUFDbEYsS0FBSyxFQUFFLEdBQUcsa0JBQWtCLHFDQUFxQztTQUNsRSxDQUFDLENBQUM7UUFDSCxNQUFBLHVCQUF1QixDQUFDLElBQUksMENBQUUsa0JBQWtCLENBQzlDLElBQUksZ0JBQU0sQ0FBQyxJQUFJLEVBQUUsNEJBQTRCLEVBQUU7WUFDN0MsVUFBVSxFQUFFO2dCQUNWLElBQUkseUJBQWUsQ0FBQztvQkFDbEIsT0FBTyxFQUFFO3dCQUNQLDZCQUE2QjtxQkFDOUI7b0JBQ0QsU0FBUyxFQUFFLENBQUMsR0FBRyxDQUFDO2lCQUNqQixDQUFDO2FBQ0g7U0FDRixDQUFDLEVBQ0Y7UUFDRixPQUFPLHVCQUF1QixDQUFDO0lBQ2pDLENBQUM7SUFFTyx1Q0FBdUM7O1FBQzdDLE1BQU0seUJBQXlCLEdBQUcsSUFBSSxrQ0FBYyxDQUFDLElBQUksRUFBRSwyQkFBMkIsRUFBRTtZQUN0RixLQUFLLEVBQUUsR0FBRyxrQkFBa0IsdUNBQXVDO1NBQ3BFLENBQUMsQ0FBQztRQUNILE1BQUEseUJBQXlCLENBQUMsSUFBSSwwQ0FBRSxrQkFBa0IsQ0FDaEQsSUFBSSxnQkFBTSxDQUFDLElBQUksRUFBRSwrQkFBK0IsRUFBRTtZQUNoRCxVQUFVLEVBQUU7Z0JBQ1YsSUFBSSx5QkFBZSxDQUFDO29CQUNsQixPQUFPLEVBQUU7d0JBQ1AsK0JBQStCO3FCQUNoQztvQkFDRCxTQUFTLEVBQUUsQ0FBQyxHQUFHLENBQUM7aUJBQ2pCLENBQUM7YUFDSDtTQUNGLENBQUMsRUFDRjtRQUNGLE9BQU8seUJBQXlCLENBQUM7SUFDbkMsQ0FBQztJQUVPLGdDQUFnQzs7UUFDdEMsTUFBTSwwQkFBMEIsR0FBRyxJQUFJLGtDQUFjLENBQUMsSUFBSSxFQUFFLDRCQUE0QixFQUFFO1lBQ3hGLEtBQUssRUFBRSxHQUFHLGtCQUFrQiw4QkFBOEI7U0FDM0QsQ0FBQyxDQUFDO1FBQ0gsTUFBQSwwQkFBMEIsQ0FBQyxJQUFJLDBDQUFFLGtCQUFrQixDQUNqRCxJQUFJLGdCQUFNLENBQUMsSUFBSSxFQUFFLGlDQUFpQyxFQUFFO1lBQ2xELFVBQVUsRUFBRTtnQkFDVixJQUFJLHlCQUFlLENBQUM7b0JBQ2xCLE9BQU8sRUFBRTt3QkFDUCx3QkFBd0I7cUJBQ3pCO29CQUNELFNBQVMsRUFBRSxDQUFDLEdBQUcsQ0FBQztpQkFDakIsQ0FBQzthQUNIO1NBQ0YsQ0FBQyxFQUNGO1FBQ0YsT0FBTywwQkFBMEIsQ0FBQztJQUNwQyxDQUFDO0lBRU8sZ0NBQWdDOztRQUN0QyxNQUFNLDBCQUEwQixHQUFHLElBQUksa0NBQWMsQ0FBQyxJQUFJLEVBQUUsNEJBQTRCLEVBQUU7WUFDeEYsS0FBSyxFQUFFLEdBQUcsa0JBQWtCLDhCQUE4QjtTQUMzRCxDQUFDLENBQUM7UUFDSCxNQUFBLDBCQUEwQixDQUFDLElBQUksMENBQUUsa0JBQWtCLENBQ2pELElBQUksZ0JBQU0sQ0FBQyxJQUFJLEVBQUUsaUNBQWlDLEVBQUU7WUFDbEQsVUFBVSxFQUFFO2dCQUNWLElBQUkseUJBQWUsQ0FBQztvQkFDbEIsT0FBTyxFQUFFO3dCQUNQLHdCQUF3QjtxQkFDekI7b0JBQ0QsU0FBUyxFQUFFLENBQUMsR0FBRyxDQUFDO2lCQUNqQixDQUFDO2FBQ0g7U0FDRixDQUFDLEVBQ0Y7UUFDRixPQUFPLDBCQUEwQixDQUFDO0lBQ3BDLENBQUM7SUFFTyw0QkFBNEI7O1FBQ2xDLE1BQU0sc0JBQXNCLEdBQUcsSUFBSSxrQ0FBYyxDQUFDLElBQUksRUFBRSx3QkFBd0IsRUFBRTtZQUNoRixLQUFLLEVBQUUsR0FBRyxrQkFBa0IsMEJBQTBCO1NBQ3ZELENBQUMsQ0FBQztRQUNILE1BQUEsc0JBQXNCLENBQUMsSUFBSSwwQ0FBRSxrQkFBa0IsQ0FDN0MsSUFBSSxnQkFBTSxDQUFDLElBQUksRUFBRSxzQkFBc0IsRUFBRTtZQUN2QyxVQUFVLEVBQUU7Z0JBQ1YsSUFBSSx5QkFBZSxDQUFDO29CQUNsQixPQUFPLEVBQUU7d0JBQ1Asb0JBQW9CO3FCQUNyQjtvQkFDRCxTQUFTLEVBQUUsQ0FBQyxHQUFHLENBQUM7aUJBQ2pCLENBQUM7YUFDSDtTQUNGLENBQUMsRUFDRjtRQUNGLE9BQU8sc0JBQXNCLENBQUM7SUFDaEMsQ0FBQztJQUVPLCtCQUErQjs7UUFDckMsTUFBTSx5QkFBeUIsR0FBRyxJQUFJLGtDQUFjLENBQUMsSUFBSSxFQUFFLDJCQUEyQixFQUFFO1lBQ3RGLEtBQUssRUFBRSxHQUFHLGtCQUFrQiw2QkFBNkI7U0FDMUQsQ0FBQyxDQUFDO1FBQ0gsTUFBQSx5QkFBeUIsQ0FBQyxJQUFJLDBDQUFFLGtCQUFrQixDQUNoRCxJQUFJLGdCQUFNLENBQUMsSUFBSSxFQUFFLGdDQUFnQyxFQUFFO1lBQ2pELFVBQVUsRUFBRTtnQkFDVixJQUFJLHlCQUFlLENBQUM7b0JBQ2xCLE9BQU8sRUFBRTt3QkFDUCx1QkFBdUI7cUJBQ3hCO29CQUNELFNBQVMsRUFBRSxDQUFDLEdBQUcsQ0FBQztpQkFDakIsQ0FBQzthQUNIO1NBQ0YsQ0FBQyxFQUNGO1FBQ0YsT0FBTyx5QkFBeUIsQ0FBQztJQUNuQyxDQUFDO0lBQ08sOEJBQThCOztRQUNwQyxNQUFNLHdCQUF3QixHQUFHLElBQUksa0NBQWMsQ0FBQyxJQUFJLEVBQUUsMEJBQTBCLEVBQUU7WUFDcEYsS0FBSyxFQUFFLEdBQUcsa0JBQWtCLDRCQUE0QjtTQUN6RCxDQUFDLENBQUM7UUFDSCxNQUFBLHdCQUF3QixDQUFDLElBQUksMENBQUUsa0JBQWtCLENBQy9DLElBQUksZ0JBQU0sQ0FBQyxJQUFJLEVBQUUsK0JBQStCLEVBQUU7WUFDaEQsVUFBVSxFQUFFO2dCQUNWLElBQUkseUJBQWUsQ0FBQztvQkFDbEIsT0FBTyxFQUFFO3dCQUNQLHNCQUFzQjtxQkFDdkI7b0JBQ0QsU0FBUyxFQUFFLENBQUMsR0FBRyxDQUFDO2lCQUNqQixDQUFDO2FBQ0g7U0FDRixDQUFDLEVBQ0Y7UUFDRixPQUFPLHdCQUF3QixDQUFDO0lBQ2xDLENBQUM7SUFFTyw0QkFBNEI7O1FBQ2xDLE1BQU0sc0JBQXNCLEdBQUcsSUFBSSxrQ0FBYyxDQUFDLElBQUksRUFBRSx3QkFBd0IsRUFBRTtZQUNoRixLQUFLLEVBQUUsR0FBRyxrQkFBa0IsMEJBQTBCO1NBQ3ZELENBQUMsQ0FBQztRQUNILE1BQUEsc0JBQXNCLENBQUMsSUFBSSwwQ0FBRSxrQkFBa0IsQ0FDN0MsSUFBSSxnQkFBTSxDQUFDLElBQUksRUFBRSxzQkFBc0IsRUFBRTtZQUN2QyxVQUFVLEVBQUU7Z0JBQ1YsSUFBSSx5QkFBZSxDQUFDO29CQUNsQixPQUFPLEVBQUU7d0JBQ1AseUJBQXlCO3FCQUMxQjtvQkFDRCxTQUFTLEVBQUUsQ0FBQyxHQUFHLENBQUM7aUJBQ2pCLENBQUM7YUFDSDtTQUNGLENBQUMsRUFDRjtRQUNGLE9BQU8sc0JBQXNCLENBQUM7SUFDaEMsQ0FBQztJQUVPLCtCQUErQjs7UUFDckMsTUFBTSx5QkFBeUIsR0FBRyxJQUFJLGtDQUFjLENBQUMsSUFBSSxFQUFFLDJCQUEyQixFQUFFO1lBQ3RGLEtBQUssRUFBRSxHQUFHLGtCQUFrQiw2QkFBNkI7U0FDMUQsQ0FBQyxDQUFDO1FBQ0gsTUFBQSx5QkFBeUIsQ0FBQyxJQUFJLDBDQUFFLGtCQUFrQixDQUNoRCxJQUFJLGdCQUFNLENBQUMsSUFBSSxFQUFFLGdDQUFnQyxFQUFFO1lBQ2pELFVBQVUsRUFBRTtnQkFDVixJQUFJLHlCQUFlLENBQUM7b0JBQ2xCLE9BQU8sRUFBRTt3QkFDUCx1QkFBdUI7cUJBQ3hCO29CQUNELFNBQVMsRUFBRSxDQUFDLEdBQUcsQ0FBQztpQkFDakIsQ0FBQzthQUNIO1NBQ0YsQ0FBQyxFQUNGO1FBQ0YsT0FBTyx5QkFBeUIsQ0FBQztJQUNuQyxDQUFDOztBQWplSCx3QkFrZUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IHtcbiAgUmVzdEFwaSxcbiAgSHR0cE1ldGhvZCxcbn0gZnJvbSAnQHNvZnRjaGVmL2Nkay1yZXN0YXBpJztcbmltcG9ydCB7XG4gIFNjaGVkdWxlRnVuY3Rpb24sXG59IGZyb20gJ0Bzb2Z0Y2hlZi9jZGstc2NoZWR1bGUtZnVuY3Rpb24nO1xuaW1wb3J0IHtcbiAgQXV0aG9yaXphdGlvblR5cGUsXG4gIElBdXRob3JpemVyLFxufSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtYXBpZ2F0ZXdheSc7XG5pbXBvcnQge1xuICBQb2xpY3ksXG4gIFBvbGljeVN0YXRlbWVudCxcbn0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWlhbSc7XG5pbXBvcnQge1xuICBOb2RlanNGdW5jdGlvbixcbn0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWxhbWJkYS1ub2RlanMnO1xuaW1wb3J0IHtcbiAgQ29uc3RydWN0LFxufSBmcm9tICdjb25zdHJ1Y3RzJztcblxuY29uc3QgTEFNQkRBX0FTU0VUU19QQVRIID0gcGF0aC5yZXNvbHZlKF9fZGlybmFtZSwgJy4uL2xhbWJkYS1hc3NldHMvam9icycpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBcbmV4cG9ydCBpbnRlcmZhY2UgSm9iQXBpUHJvcHMge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICByZWFkb25seSBhdXRob3JpemF0aW9uVHlwZT86IEF1dGhvcml6YXRpb25UeXBlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICByZWFkb25seSBhdXRob3JpemVyPzogSUF1dGhvcml6ZXIgfCB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcmVhZG9ubHkgc2NoZWR1bGVGdW5jdGlvbj86IFNjaGVkdWxlRnVuY3Rpb247XG59XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbmV4cG9ydCBjbGFzcyBKb2JBcGkgZXh0ZW5kcyBDb25zdHJ1Y3Qge1xuICAvKipcbiAgICogVGhlIEpvYiBBUEkgR2F0ZXdheVxuICAgKi9cbiAgcHJpdmF0ZSByZWFkb25seSBfcmVzdEFwaTogUmVzdEFwaTtcblxuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wcz86IEpvYkFwaVByb3BzKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkKTtcbiAgICB0aGlzLl9yZXN0QXBpID0gbmV3IFJlc3RBcGkodGhpcywgJ0pvYlJlc3RBcGknLCB7XG4gICAgICBlbmFibGVDb3JzOiB0cnVlLFxuICAgICAgYXV0aG9yaXphdGlvblR5cGU6IHByb3BzPy5hdXRob3JpemF0aW9uVHlwZSA/PyBBdXRob3JpemF0aW9uVHlwZS5OT05FLFxuICAgICAgYXV0aG9yaXplcjogcHJvcHM/LmF1dGhvcml6ZXIgPz8gdW5kZWZpbmVkLFxuICAgICAgcmVzb3VyY2VzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBwYXRoOiAnL2pvYnMve2pvYklkfS9hc3NvY2lhdGUnLFxuICAgICAgICAgIGh0dHBNZXRob2Q6IEh0dHBNZXRob2QuUFVULFxuICAgICAgICAgIGxhbWJkYUZ1bmN0aW9uOiB0aGlzLmNyZWF0ZUFzc29jaWF0ZVRhcmdldHNXaXRoSm9iRnVuY3Rpb24oKSxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIHBhdGg6ICcvam9icycsXG4gICAgICAgICAgaHR0cE1ldGhvZDogSHR0cE1ldGhvZC5QT1NULFxuICAgICAgICAgIGxhbWJkYUZ1bmN0aW9uOiB0aGlzLmNyZWF0ZUNyZWF0ZUpvYkZ1bmN0aW9uKCksXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBwYXRoOiAnL2pvYnMnLFxuICAgICAgICAgIGh0dHBNZXRob2Q6IEh0dHBNZXRob2QuR0VULFxuICAgICAgICAgIGxhbWJkYUZ1bmN0aW9uOiB0aGlzLmNyZWF0ZUxpc3RKb2JzRnVuY3Rpb24oKSxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIHBhdGg6ICcvam9icy97am9iSWR9JyxcbiAgICAgICAgICBodHRwTWV0aG9kOiBIdHRwTWV0aG9kLkdFVCxcbiAgICAgICAgICBsYW1iZGFGdW5jdGlvbjogdGhpcy5jcmVhdGVHZXRKb2JGdW5jdGlvbigpLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgcGF0aDogJy9qb2JzL3tqb2JJZH0nLFxuICAgICAgICAgIGh0dHBNZXRob2Q6IEh0dHBNZXRob2QuUFVULFxuICAgICAgICAgIGxhbWJkYUZ1bmN0aW9uOiB0aGlzLmNyZWF0ZVVwZGF0ZUpvYkZ1bmN0aW9uKCksXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBwYXRoOiAnL2pvYnMve2pvYklkfScsXG4gICAgICAgICAgaHR0cE1ldGhvZDogSHR0cE1ldGhvZC5ERUxFVEUsXG4gICAgICAgICAgbGFtYmRhRnVuY3Rpb246IHRoaXMuY3JlYXRlRGVsZXRlSm9iRnVuY3Rpb24oKSxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIHBhdGg6ICcvam9icy97am9iSWR9L2NhbmNlbCcsXG4gICAgICAgICAgaHR0cE1ldGhvZDogSHR0cE1ldGhvZC5QVVQsXG4gICAgICAgICAgbGFtYmRhRnVuY3Rpb246IHRoaXMuY3JlYXRlQ2FuY2VsSm9iRnVuY3Rpb24oKSxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIHBhdGg6ICcvam9icy97am9iSWR9L2RvY3VtZW50JyxcbiAgICAgICAgICBodHRwTWV0aG9kOiBIdHRwTWV0aG9kLkdFVCxcbiAgICAgICAgICBsYW1iZGFGdW5jdGlvbjogdGhpcy5jcmVhdGVHZXRKb2JEb2N1bWVudEZ1bmN0aW9uKCksXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBwYXRoOiAnL2pvYnMve2pvYklkfS90aGluZ3Mve3RoaW5nTmFtZX0nLFxuICAgICAgICAgIGh0dHBNZXRob2Q6IEh0dHBNZXRob2QuR0VULFxuICAgICAgICAgIGxhbWJkYUZ1bmN0aW9uOiB0aGlzLmNyZWF0ZUdldEpvYkV4ZWN1dGlvbkZ1bmN0aW9uKCksXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBwYXRoOiAnam9icy97am9iSWR9L3N0YXR1cycsXG4gICAgICAgICAgaHR0cE1ldGhvZDogSHR0cE1ldGhvZC5HRVQsXG4gICAgICAgICAgbGFtYmRhRnVuY3Rpb246IHRoaXMuY3JlYXRlTGlzdEpvYkV4ZWN1dGlvbnNGb3JKb2JGdW5jdGlvbigpLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgcGF0aDogJy90aGluZ3Mve3RoaW5nTmFtZX0vam9icycsXG4gICAgICAgICAgaHR0cE1ldGhvZDogSHR0cE1ldGhvZC5HRVQsXG4gICAgICAgICAgbGFtYmRhRnVuY3Rpb246IHRoaXMuY3JlYXRlTGlzdEpvYkV4ZWN1dGlvbnNGb3JUaGluZ0Z1bmN0aW9uKCksXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBwYXRoOiAnL2pvYnMve2pvYklkfS90aGluZ3Mve3RoaW5nTmFtZX0nLFxuICAgICAgICAgIGh0dHBNZXRob2Q6IEh0dHBNZXRob2QuREVMRVRFLFxuICAgICAgICAgIGxhbWJkYUZ1bmN0aW9uOiB0aGlzLmNyZWF0ZURlbGV0ZUpvYkV4ZWN1dGlvbkZ1bmN0aW9uKCksXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBwYXRoOiAnL2pvYnMve2pvYklkfS90aGluZ3Mve3RoaW5nTmFtZX0vY2FuY2VsJyxcbiAgICAgICAgICBodHRwTWV0aG9kOiBIdHRwTWV0aG9kLlBVVCxcbiAgICAgICAgICBsYW1iZGFGdW5jdGlvbjogdGhpcy5jcmVhdGVDYW5jZWxKb2JFeGVjdXRpb25GdW5jdGlvbigpLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgcGF0aDogJy9qb2ItdGVtcGxhdGVzJyxcbiAgICAgICAgICBodHRwTWV0aG9kOiBIdHRwTWV0aG9kLlBPU1QsXG4gICAgICAgICAgbGFtYmRhRnVuY3Rpb246IHRoaXMuY3JlYXRlQ3JlYXRlSm9iVGVtcGxhdGVGdW5jdGlvbigpLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgcGF0aDogJy9qb2ItdGVtcGxhdGVzJyxcbiAgICAgICAgICBodHRwTWV0aG9kOiBIdHRwTWV0aG9kLkdFVCxcbiAgICAgICAgICBsYW1iZGFGdW5jdGlvbjogdGhpcy5jcmVhdGVMaXN0Sm9iVGVtcGxhdGVzRnVuY3Rpb24oKSxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIHBhdGg6ICcvam9iLXRlbXBsYXRlcy97am9iVGVtcGxhdGVJZH0nLFxuICAgICAgICAgIGh0dHBNZXRob2Q6IEh0dHBNZXRob2QuR0VULFxuICAgICAgICAgIGxhbWJkYUZ1bmN0aW9uOiB0aGlzLmNyZWF0ZUdldEpvYlRlbXBsYXRlRnVuY3Rpb24oKSxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIHBhdGg6ICcvam9iLXRlbXBsYXRlcy97am9iVGVtcGxhdGVJZH0nLFxuICAgICAgICAgIGh0dHBNZXRob2Q6IEh0dHBNZXRob2QuREVMRVRFLFxuICAgICAgICAgIGxhbWJkYUZ1bmN0aW9uOiB0aGlzLmNyZWF0ZURlbGV0ZUpvYlRlbXBsYXRlRnVuY3Rpb24oKSxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfSk7XG4gICAgaWYgKHByb3BzPy5zY2hlZHVsZUZ1bmN0aW9uKSB7XG4gICAgICBjb25zdCB0YXJnZXRUeXBlOiBzdHJpbmcgPSAnQ3JlYXRlSm9iJztcbiAgICAgIHByb3BzLnNjaGVkdWxlRnVuY3Rpb24uYWRkVGFyZ2V0RnVuY3Rpb24odGFyZ2V0VHlwZSwge1xuICAgICAgICB0YXJnZXRGdW5jdGlvbjogdGhpcy5jcmVhdGVDcmVhdGVTY2hlZHVsZUpvYkZ1bmN0aW9uKCksXG4gICAgICB9KTtcbiAgICAgIHByb3BzPy5zY2hlZHVsZUZ1bmN0aW9uPy5saXN0U2NoZWR1bGVzRnVuY3Rpb24uYWRkRW52aXJvbm1lbnQoJ0ZJWEVEX1RBUkdFVF9UWVBFJywgdGFyZ2V0VHlwZSk7XG4gICAgICBwcm9wcz8uc2NoZWR1bGVGdW5jdGlvbj8uY3JlYXRlU2NoZWR1bGVGdW5jdGlvbi5hZGRFbnZpcm9ubWVudCgnRklYRURfVEFSR0VUX1RZUEUnLCB0YXJnZXRUeXBlKTtcbiAgICAgIHRoaXMuX3Jlc3RBcGkuYWRkUmVzb3VyY2VzKFtcbiAgICAgICAge1xuICAgICAgICAgIHBhdGg6ICcvc2NoZWR1bGVzJyxcbiAgICAgICAgICBodHRwTWV0aG9kOiBIdHRwTWV0aG9kLkdFVCxcbiAgICAgICAgICBsYW1iZGFGdW5jdGlvbjogcHJvcHM/LnNjaGVkdWxlRnVuY3Rpb24ubGlzdFNjaGVkdWxlc0Z1bmN0aW9uLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgcGF0aDogJy9zY2hlZHVsZXMnLFxuICAgICAgICAgIGh0dHBNZXRob2Q6IEh0dHBNZXRob2QuUE9TVCxcbiAgICAgICAgICBsYW1iZGFGdW5jdGlvbjogcHJvcHM/LnNjaGVkdWxlRnVuY3Rpb24uY3JlYXRlU2NoZWR1bGVGdW5jdGlvbixcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIHBhdGg6ICcvc2NoZWR1bGVzL3tzY2hlZHVsZUlkfScsXG4gICAgICAgICAgaHR0cE1ldGhvZDogSHR0cE1ldGhvZC5HRVQsXG4gICAgICAgICAgbGFtYmRhRnVuY3Rpb246IHByb3BzPy5zY2hlZHVsZUZ1bmN0aW9uLmZldGNoU2NoZWR1bGVGdW5jdGlvbixcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIHBhdGg6ICcvc2NoZWR1bGVzL3tzY2hlZHVsZUlkfScsXG4gICAgICAgICAgaHR0cE1ldGhvZDogSHR0cE1ldGhvZC5QVVQsXG4gICAgICAgICAgbGFtYmRhRnVuY3Rpb246IHByb3BzPy5zY2hlZHVsZUZ1bmN0aW9uLnVwZGF0ZVNjaGVkdWxlRnVuY3Rpb24sXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBwYXRoOiAnL3NjaGVkdWxlcy97c2NoZWR1bGVJZH0nLFxuICAgICAgICAgIGh0dHBNZXRob2Q6IEh0dHBNZXRob2QuREVMRVRFLFxuICAgICAgICAgIGxhbWJkYUZ1bmN0aW9uOiBwcm9wcz8uc2NoZWR1bGVGdW5jdGlvbi5kZWxldGVTY2hlZHVsZUZ1bmN0aW9uLFxuICAgICAgICB9LFxuICAgICAgXSk7XG4gICAgfVxuICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgZ2V0IHJlc3RBcGlJZCgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLl9yZXN0QXBpLnJlc3RBcGlJZDtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlQ3JlYXRlU2NoZWR1bGVKb2JGdW5jdGlvbigpOiBOb2RlanNGdW5jdGlvbiB7XG4gICAgY29uc3QgY3JlYXRlSm9iRnVuY3Rpb24gPSBuZXcgTm9kZWpzRnVuY3Rpb24odGhpcywgJ0NyZWF0ZVNjaGVkdWxlSm9iRnVuY3Rpb24nLCB7XG4gICAgICBlbnRyeTogYCR7TEFNQkRBX0FTU0VUU19QQVRIfS9jcmVhdGUtc2NoZWR1bGUtam9iL2FwcC50c2AsXG4gICAgfSk7XG4gICAgY3JlYXRlSm9iRnVuY3Rpb24ucm9sZT8uYXR0YWNoSW5saW5lUG9saWN5KFxuICAgICAgbmV3IFBvbGljeSh0aGlzLCAnaW90LWNyZWF0ZS1zY2hlZHVsZS1qb2ItcG9saWN5Jywge1xuICAgICAgICBzdGF0ZW1lbnRzOiBbXG4gICAgICAgICAgbmV3IFBvbGljeVN0YXRlbWVudCh7XG4gICAgICAgICAgICBhY3Rpb25zOiBbXG4gICAgICAgICAgICAgICdpb3Q6Q3JlYXRlSm9iJyxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICByZXNvdXJjZXM6IFsnKiddLFxuICAgICAgICAgIH0pLFxuICAgICAgICBdLFxuICAgICAgfSksXG4gICAgKTtcbiAgICByZXR1cm4gY3JlYXRlSm9iRnVuY3Rpb247XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZUFzc29jaWF0ZVRhcmdldHNXaXRoSm9iRnVuY3Rpb24oKTogTm9kZWpzRnVuY3Rpb24ge1xuICAgIGNvbnN0IGNyZWF0ZUpvYkZ1bmN0aW9uID0gbmV3IE5vZGVqc0Z1bmN0aW9uKHRoaXMsICdBc3NvY2lhdGVUYXJnZXRzV2l0aEpvYkZ1bmN0aW9uJywge1xuICAgICAgZW50cnk6IGAke0xBTUJEQV9BU1NFVFNfUEFUSH0vYXNzb2NpYXRlLXRhcmdldHMtd2l0aC1qb2IvYXBwLnRzYCxcbiAgICB9KTtcbiAgICBjcmVhdGVKb2JGdW5jdGlvbi5yb2xlPy5hdHRhY2hJbmxpbmVQb2xpY3koXG4gICAgICBuZXcgUG9saWN5KHRoaXMsICdpb3QtYXNzb2NpYXRlLXRhcmdldHMtd2l0aC1qb2InLCB7XG4gICAgICAgIHN0YXRlbWVudHM6IFtcbiAgICAgICAgICBuZXcgUG9saWN5U3RhdGVtZW50KHtcbiAgICAgICAgICAgIGFjdGlvbnM6IFtcbiAgICAgICAgICAgICAgJ2lvdDpBc3NvY2lhdGVUYXJnZXRzV2l0aEpvYicsXG4gICAgICAgICAgICBdLFxuICAgICAgICAgICAgcmVzb3VyY2VzOiBbJyonXSxcbiAgICAgICAgICB9KSxcbiAgICAgICAgXSxcbiAgICAgIH0pLFxuICAgICk7XG4gICAgcmV0dXJuIGNyZWF0ZUpvYkZ1bmN0aW9uO1xuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVDcmVhdGVKb2JGdW5jdGlvbigpOiBOb2RlanNGdW5jdGlvbiB7XG4gICAgY29uc3QgY3JlYXRlSm9iRnVuY3Rpb24gPSBuZXcgTm9kZWpzRnVuY3Rpb24odGhpcywgJ0NyZWF0ZUpvYkZ1bmN0aW9uJywge1xuICAgICAgZW50cnk6IGAke0xBTUJEQV9BU1NFVFNfUEFUSH0vY3JlYXRlLWpvYi9hcHAudHNgLFxuICAgIH0pO1xuICAgIGNyZWF0ZUpvYkZ1bmN0aW9uLnJvbGU/LmF0dGFjaElubGluZVBvbGljeShcbiAgICAgIG5ldyBQb2xpY3kodGhpcywgJ2lvdC1jcmVhdGUtam9iLXBvbGljeScsIHtcbiAgICAgICAgc3RhdGVtZW50czogW1xuICAgICAgICAgIG5ldyBQb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICAgICAgYWN0aW9uczogW1xuICAgICAgICAgICAgICAnaW90OkNyZWF0ZUpvYicsXG4gICAgICAgICAgICBdLFxuICAgICAgICAgICAgcmVzb3VyY2VzOiBbJyonXSxcbiAgICAgICAgICB9KSxcbiAgICAgICAgXSxcbiAgICAgIH0pLFxuICAgICk7XG4gICAgcmV0dXJuIGNyZWF0ZUpvYkZ1bmN0aW9uO1xuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVMaXN0Sm9ic0Z1bmN0aW9uKCk6IE5vZGVqc0Z1bmN0aW9uIHtcbiAgICBjb25zdCBsaXN0Sm9ic0Z1bmN0aW9uID0gbmV3IE5vZGVqc0Z1bmN0aW9uKHRoaXMsICdMaXN0Sm9ic0Z1bmN0aW9uJywge1xuICAgICAgZW50cnk6IGAke0xBTUJEQV9BU1NFVFNfUEFUSH0vbGlzdC1qb2JzL2FwcC50c2AsXG4gICAgfSk7XG4gICAgbGlzdEpvYnNGdW5jdGlvbi5yb2xlPy5hdHRhY2hJbmxpbmVQb2xpY3koXG4gICAgICBuZXcgUG9saWN5KHRoaXMsICdpb3QtbGlzdC1qb2JzLXBvbGljeScsIHtcbiAgICAgICAgc3RhdGVtZW50czogW1xuICAgICAgICAgIG5ldyBQb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICAgICAgYWN0aW9uczogW1xuICAgICAgICAgICAgICAnaW90Okxpc3RKb2JzJyxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICByZXNvdXJjZXM6IFsnKiddLFxuICAgICAgICAgIH0pLFxuICAgICAgICBdLFxuICAgICAgfSksXG4gICAgKTtcbiAgICByZXR1cm4gbGlzdEpvYnNGdW5jdGlvbjtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlR2V0Sm9iRnVuY3Rpb24oKTogTm9kZWpzRnVuY3Rpb24ge1xuICAgIGNvbnN0IGdldEpvYkZ1bmN0aW9uID0gbmV3IE5vZGVqc0Z1bmN0aW9uKHRoaXMsICdHZXRKb2JGdW5jdGlvbicsIHtcbiAgICAgIGVudHJ5OiBgJHtMQU1CREFfQVNTRVRTX1BBVEh9L2dldC1qb2IvYXBwLnRzYCxcbiAgICB9KTtcbiAgICBnZXRKb2JGdW5jdGlvbi5yb2xlPy5hdHRhY2hJbmxpbmVQb2xpY3koXG4gICAgICBuZXcgUG9saWN5KHRoaXMsICdpb3QtZGVzY3JpYmUtam9iLXBvbGljeScsIHtcbiAgICAgICAgc3RhdGVtZW50czogW1xuICAgICAgICAgIG5ldyBQb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICAgICAgYWN0aW9uczogW1xuICAgICAgICAgICAgICAnaW90OkRlc2NyaWJlSm9iJyxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICByZXNvdXJjZXM6IFsnKiddLFxuICAgICAgICAgIH0pLFxuICAgICAgICBdLFxuICAgICAgfSksXG4gICAgKTtcbiAgICByZXR1cm4gZ2V0Sm9iRnVuY3Rpb247XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZVVwZGF0ZUpvYkZ1bmN0aW9uKCk6IE5vZGVqc0Z1bmN0aW9uIHtcbiAgICBjb25zdCB1cGRhdGVKb2JGdW5jdGlvbiA9IG5ldyBOb2RlanNGdW5jdGlvbih0aGlzLCAnVXBkYXRlSm9iRnVuY3Rpb24nLCB7XG4gICAgICBlbnRyeTogYCR7TEFNQkRBX0FTU0VUU19QQVRIfS91cGRhdGUtam9iL2FwcC50c2AsXG4gICAgfSk7XG4gICAgdXBkYXRlSm9iRnVuY3Rpb24ucm9sZT8uYXR0YWNoSW5saW5lUG9saWN5KFxuICAgICAgbmV3IFBvbGljeSh0aGlzLCAnaW90LXVwZGF0ZS1qb2ItcG9saWN5Jywge1xuICAgICAgICBzdGF0ZW1lbnRzOiBbXG4gICAgICAgICAgbmV3IFBvbGljeVN0YXRlbWVudCh7XG4gICAgICAgICAgICBhY3Rpb25zOiBbXG4gICAgICAgICAgICAgICdpb3Q6VXBkYXRlSm9iJyxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICByZXNvdXJjZXM6IFsnKiddLFxuICAgICAgICAgIH0pLFxuICAgICAgICBdLFxuICAgICAgfSksXG4gICAgKTtcbiAgICByZXR1cm4gdXBkYXRlSm9iRnVuY3Rpb247XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZURlbGV0ZUpvYkZ1bmN0aW9uKCk6IE5vZGVqc0Z1bmN0aW9uIHtcbiAgICBjb25zdCBkZWxldGVKb2JGdW5jdGlvbiA9IG5ldyBOb2RlanNGdW5jdGlvbih0aGlzLCAnRGVsZXRlSm9iRnVuY3Rpb24nLCB7XG4gICAgICBlbnRyeTogYCR7TEFNQkRBX0FTU0VUU19QQVRIfS9kZWxldGUtam9iL2FwcC50c2AsXG4gICAgfSk7XG4gICAgZGVsZXRlSm9iRnVuY3Rpb24ucm9sZT8uYXR0YWNoSW5saW5lUG9saWN5KFxuICAgICAgbmV3IFBvbGljeSh0aGlzLCAnaW90LWRlbGV0ZS1qb2ItcG9saWN5Jywge1xuICAgICAgICBzdGF0ZW1lbnRzOiBbXG4gICAgICAgICAgbmV3IFBvbGljeVN0YXRlbWVudCh7XG4gICAgICAgICAgICBhY3Rpb25zOiBbXG4gICAgICAgICAgICAgICdpb3Q6RGVsZXRlSm9iJyxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICByZXNvdXJjZXM6IFsnKiddLFxuICAgICAgICAgIH0pLFxuICAgICAgICBdLFxuICAgICAgfSksXG4gICAgKTtcbiAgICByZXR1cm4gZGVsZXRlSm9iRnVuY3Rpb247XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZUNhbmNlbEpvYkZ1bmN0aW9uKCk6IE5vZGVqc0Z1bmN0aW9uIHtcbiAgICBjb25zdCBjYW5jZWxKb2JGdW5jdGlvbiA9IG5ldyBOb2RlanNGdW5jdGlvbih0aGlzLCAnQ2FuY2VsSm9iRnVuY3Rpb24nLCB7XG4gICAgICBlbnRyeTogYCR7TEFNQkRBX0FTU0VUU19QQVRIfS9jYW5jZWwtam9iL2FwcC50c2AsXG4gICAgfSk7XG4gICAgY2FuY2VsSm9iRnVuY3Rpb24ucm9sZT8uYXR0YWNoSW5saW5lUG9saWN5KFxuICAgICAgbmV3IFBvbGljeSh0aGlzLCAnaW90LWNhbmNlbC1qb2ItcG9saWN5Jywge1xuICAgICAgICBzdGF0ZW1lbnRzOiBbXG4gICAgICAgICAgbmV3IFBvbGljeVN0YXRlbWVudCh7XG4gICAgICAgICAgICBhY3Rpb25zOiBbXG4gICAgICAgICAgICAgICdpb3Q6Q2FuY2VsSm9iJyxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICByZXNvdXJjZXM6IFsnKiddLFxuICAgICAgICAgIH0pLFxuICAgICAgICBdLFxuICAgICAgfSksXG4gICAgKTtcbiAgICByZXR1cm4gY2FuY2VsSm9iRnVuY3Rpb247XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZUdldEpvYkV4ZWN1dGlvbkZ1bmN0aW9uKCk6IE5vZGVqc0Z1bmN0aW9uIHtcbiAgICBjb25zdCBnZXRKb2JFeGVjdXRpb25GdW5jdGlvbiA9IG5ldyBOb2RlanNGdW5jdGlvbih0aGlzLCAnR2V0Sm9iRXhlY3V0aW9uRnVuY3Rpb24nLCB7XG4gICAgICBlbnRyeTogYCR7TEFNQkRBX0FTU0VUU19QQVRIfS9nZXQtam9iLWV4ZWN1dGlvbi9hcHAudHNgLFxuICAgIH0pO1xuICAgIGdldEpvYkV4ZWN1dGlvbkZ1bmN0aW9uLnJvbGU/LmF0dGFjaElubGluZVBvbGljeShcbiAgICAgIG5ldyBQb2xpY3kodGhpcywgJ2lvdC1kZXNjcmliZS1qb2ItZXhlY3V0aW9uLXBvbGljeScsIHtcbiAgICAgICAgc3RhdGVtZW50czogW1xuICAgICAgICAgIG5ldyBQb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICAgICAgYWN0aW9uczogW1xuICAgICAgICAgICAgICAnaW90OkRlc2NyaWJlSm9iRXhlY3V0aW9uJyxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICByZXNvdXJjZXM6IFsnKiddLFxuICAgICAgICAgIH0pLFxuICAgICAgICBdLFxuICAgICAgfSksXG4gICAgKTtcbiAgICByZXR1cm4gZ2V0Sm9iRXhlY3V0aW9uRnVuY3Rpb247XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZUxpc3RKb2JFeGVjdXRpb25zRm9ySm9iRnVuY3Rpb24oKTogTm9kZWpzRnVuY3Rpb24ge1xuICAgIGNvbnN0IGxpc3RKb2JFeGVjdXRpb25zRm9ySm9iID0gbmV3IE5vZGVqc0Z1bmN0aW9uKHRoaXMsICdsaXN0Sm9iRXhlY3V0aW9uc0ZvckpvYicsIHtcbiAgICAgIGVudHJ5OiBgJHtMQU1CREFfQVNTRVRTX1BBVEh9L2xpc3Qtam9iLWV4ZWN1dGlvbnMtZm9yLWpvYi9hcHAudHNgLFxuICAgIH0pO1xuICAgIGxpc3RKb2JFeGVjdXRpb25zRm9ySm9iLnJvbGU/LmF0dGFjaElubGluZVBvbGljeShcbiAgICAgIG5ldyBQb2xpY3kodGhpcywgJ2xpc3Qtam9iLWV4ZWN1dGlvbi1mb3Itam9iJywge1xuICAgICAgICBzdGF0ZW1lbnRzOiBbXG4gICAgICAgICAgbmV3IFBvbGljeVN0YXRlbWVudCh7XG4gICAgICAgICAgICBhY3Rpb25zOiBbXG4gICAgICAgICAgICAgICdpb3Q6TGlzdEpvYkV4ZWN1dGlvbnNGb3JKb2InLFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIHJlc291cmNlczogWycqJ10sXG4gICAgICAgICAgfSksXG4gICAgICAgIF0sXG4gICAgICB9KSxcbiAgICApO1xuICAgIHJldHVybiBsaXN0Sm9iRXhlY3V0aW9uc0ZvckpvYjtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlTGlzdEpvYkV4ZWN1dGlvbnNGb3JUaGluZ0Z1bmN0aW9uKCk6IE5vZGVqc0Z1bmN0aW9uIHtcbiAgICBjb25zdCBsaXN0Sm9iRXhlY3V0aW9uc0ZvclRoaW5nID0gbmV3IE5vZGVqc0Z1bmN0aW9uKHRoaXMsICdsaXN0Sm9iRXhlY3V0aW9uc0ZvclRoaW5nJywge1xuICAgICAgZW50cnk6IGAke0xBTUJEQV9BU1NFVFNfU