cdk-amazon-chime-resources
Version:

251 lines • 35.7 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.DeleteKinesisVideoStreamPool = exports.UpdateKinesisVideoStreamPool = exports.CreateKinesisVideoStreamPool = void 0;
/* eslint-disable import/no-extraneous-dependencies */
const client_chime_sdk_media_pipelines_1 = require("@aws-sdk/client-chime-sdk-media-pipelines");
const client_kinesis_video_1 = require("@aws-sdk/client-kinesis-video");
const client_ssm_1 = require("@aws-sdk/client-ssm");
const ssmClient = new client_ssm_1.SSMClient({ region: process.env.AWS_REGION });
const chimeSDKMediaPipelineClient = new client_chime_sdk_media_pipelines_1.ChimeSDKMediaPipelinesClient({
region: process.env.AWS_REGION,
});
const kinesisVideoClient = new client_kinesis_video_1.KinesisVideoClient({
region: process.env.AWS_REGION,
});
let getParameterCommandOutput;
function capitalizeKeys(obj) {
if (Array.isArray(obj)) {
return obj.map((item) => capitalizeKeys(item));
}
if (typeof obj === 'object') {
const capitalizedObj = {};
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
const capitalizedKey = key.charAt(0).toUpperCase() + key.slice(1);
const value = obj[key];
capitalizedObj[capitalizedKey] =
typeof value === 'string' && !isNaN(parseFloat(value))
? parseFloat(value)
: capitalizeKeys(value);
}
}
return capitalizedObj;
}
return obj;
}
let createMediaPipelineKinesisVideoStreamPoolCommandOutput;
let createMediaPipelineKinesisVideoStreamPoolCommandInput;
const formatProps = (props) => {
let formattedTags = [];
if (props.tags) {
console.info(`Formatting Tags: ${JSON.stringify(props.tags)}`);
props.tags.forEach((tag) => {
formattedTags.push(capitalizeKeys(tag));
});
console.info(`Formatted Tags: ${JSON.stringify(formattedTags)}`);
}
console.log(`New formattedTags: ${formattedTags}`);
createMediaPipelineKinesisVideoStreamPoolCommandInput = {
PoolName: props.poolName,
StreamConfiguration: capitalizeKeys(props.streamConfiguration),
...(props.tags && { Tags: formattedTags }),
...(props.clientRequestToken && {
ClientRequestToken: props.clientRequestToken,
}),
};
console.info(`mediaInsightsPipelineConfigurationParams: ${JSON.stringify(createMediaPipelineKinesisVideoStreamPoolCommandInput)}`);
return createMediaPipelineKinesisVideoStreamPoolCommandInput;
};
const CreateKinesisVideoStreamPool = async (uid, props) => {
console.log(`Creating Kinesis Video Stream Pool: ${uid}`);
console.log(`CreateKinesisVideoStreamPool props: ${JSON.stringify(props)}`);
createMediaPipelineKinesisVideoStreamPoolCommandInput = formatProps(props);
console.log(`CreateKinesisVideoStreamPool params: ${JSON.stringify(createMediaPipelineKinesisVideoStreamPoolCommandInput)}`);
try {
createMediaPipelineKinesisVideoStreamPoolCommandOutput =
await chimeSDKMediaPipelineClient.send(new client_chime_sdk_media_pipelines_1.CreateMediaPipelineKinesisVideoStreamPoolCommand(createMediaPipelineKinesisVideoStreamPoolCommandInput));
console.log(`createMediaInsightsPipelineConfigurationResponse: ${JSON.stringify(createMediaPipelineKinesisVideoStreamPoolCommandOutput)}`);
}
catch (error) {
if (error instanceof Error) {
console.error(error);
throw error;
}
}
try {
await ssmClient.send(new client_ssm_1.PutParameterCommand({
Name: '/chime/KinesisVideoStreamPoolId' + uid,
Value: createMediaPipelineKinesisVideoStreamPoolCommandOutput
.KinesisVideoStreamPoolConfiguration?.PoolId,
Description: 'KinesisVideoStreamPoolId' + uid,
Overwrite: true,
Type: 'String',
}));
}
catch (error) {
if (error instanceof Error) {
console.error(error);
throw error;
}
}
return createMediaPipelineKinesisVideoStreamPoolCommandOutput.KinesisVideoStreamPoolConfiguration;
};
exports.CreateKinesisVideoStreamPool = CreateKinesisVideoStreamPool;
let updateMediaPipelineKinesisVideoStreamPoolCommandInput;
let updateMediaPipelineKinesisVideoStreamPoolCommandOutput;
const UpdateKinesisVideoStreamPool = async (uid, props) => {
console.log(`UpdateKinesisVideoStreamPool: ${uid}`);
console.log(`UpdateKinesisVideoStreamPool props: ${JSON.stringify(props)}`);
try {
getParameterCommandOutput = await ssmClient.send(new client_ssm_1.GetParameterCommand({
Name: '/chime/KinesisVideoStreamPoolId' + uid,
}));
}
catch (error) {
if (error instanceof Error) {
console.error(error);
throw error;
}
}
updateMediaPipelineKinesisVideoStreamPoolCommandInput = {
Identifier: getParameterCommandOutput.Parameter.Value,
StreamConfiguration: {
DataRetentionInHours: Number(props.streamConfiguration.dataRetentionInHours),
},
};
console.log(`Update Media Insights Pipeline Configuration params: ${JSON.stringify(updateMediaPipelineKinesisVideoStreamPoolCommandInput)}`);
try {
updateMediaPipelineKinesisVideoStreamPoolCommandOutput =
await chimeSDKMediaPipelineClient.send(new client_chime_sdk_media_pipelines_1.UpdateMediaPipelineKinesisVideoStreamPoolCommand(updateMediaPipelineKinesisVideoStreamPoolCommandInput));
console.log(`createMediaInsightsPipelineConfigurationResponse: ${JSON.stringify(updateMediaPipelineKinesisVideoStreamPoolCommandOutput)}`);
}
catch (error) {
if (error instanceof Error) {
console.error(error);
throw error;
}
}
return updateMediaPipelineKinesisVideoStreamPoolCommandOutput.KinesisVideoStreamPoolConfiguration;
};
exports.UpdateKinesisVideoStreamPool = UpdateKinesisVideoStreamPool;
const DeleteKinesisVideoStreamPool = async (uid, props) => {
console.log(`DeleteKinesisVideoStreamPool: ${uid}`);
try {
getParameterCommandOutput = await ssmClient.send(new client_ssm_1.GetParameterCommand({
Name: '/chime/KinesisVideoStreamPoolId' + uid,
}));
}
catch (error) {
if (error instanceof Error) {
console.error(error);
throw error;
}
}
try {
await ssmClient.send(new client_ssm_1.DeleteParameterCommand({
Name: '/chime/KinesisVideoStreamPoolId' + uid,
}));
}
catch (error) {
if (error instanceof Error) {
console.error(error);
throw error;
}
}
console.info(`deleteMediaInsightsPipelineIdentifier: ${props.poolName}`);
try {
await chimeSDKMediaPipelineClient.send(new client_chime_sdk_media_pipelines_1.DeleteMediaPipelineKinesisVideoStreamPoolCommand({
Identifier: props.poolName,
}));
}
catch (error) {
if (error instanceof Error) {
console.error(error);
throw error;
}
}
await getMediaPipelineKinesisVideoStreamPool(props.poolName, 18);
const streamsToDelete = await listAllStreams(props.poolName);
await deleteAllStreams(streamsToDelete);
return;
};
exports.DeleteKinesisVideoStreamPool = DeleteKinesisVideoStreamPool;
async function listAllStreams(prefix) {
let nextToken;
const streams = [];
try {
do {
const input = {
MaxResults: 100,
NextToken: nextToken,
StreamNameCondition: {
ComparisonOperator: client_kinesis_video_1.ComparisonOperator.BEGINS_WITH,
ComparisonValue: 'ChimeMediaPipelines-' + prefix,
},
};
const response = await kinesisVideoClient.send(new client_kinesis_video_1.ListStreamsCommand(input));
if (response.StreamInfoList) {
for (const streamInfo of response.StreamInfoList) {
if (streamInfo.StreamARN) {
streams.push(streamInfo.StreamARN);
}
}
}
nextToken = response.NextToken;
} while (nextToken);
}
catch (error) {
console.error('Error listing streams:', error);
throw error; // Rethrow the error if you want to handle it further up the call stack
}
console.log('Streams to delete: ', streams);
return streams;
}
async function deleteAllStreams(streamARNs) {
try {
for (const streamARN of streamARNs) {
await kinesisVideoClient.send(new client_kinesis_video_1.DeleteStreamCommand({ StreamARN: streamARN }));
console.log('Deleted: ', streamARN);
}
}
catch (error) {
console.error('Error listing streams:', error);
throw error; // Rethrow the error if you want to handle it further up the call stack
}
console.log('All streams deleted');
}
async function getMediaPipelineKinesisVideoStreamPool(identifier, maxAttempts) {
const input = {
Identifier: identifier,
};
const command = new client_chime_sdk_media_pipelines_1.GetMediaPipelineKinesisVideoStreamPoolCommand(input);
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
try {
const response = await chimeSDKMediaPipelineClient.send(command);
return response;
}
catch (error) {
if (error instanceof Error) {
const typedError = error;
if (typedError.name === 'ResourceNotFoundException' ||
typedError.$metadata?.httpStatusCode === 404) {
console.log(`Resource with identifier ${identifier} not found.`);
return null;
}
else {
console.error('Error:', error);
await sleep(10000);
}
}
else {
console.error('An unexpected error occurred:', error);
throw error;
}
}
}
throw new Error(`Failed to delete media pipeline after ${maxAttempts} attempts`);
}
function sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoia2luZXNpc1ZpZGVvU3RyZWFtUG9vbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9yZXNvdXJjZXMvbWVkaWEtcGlwZWxpbmVzL2tpbmVzaXNWaWRlb1N0cmVhbVBvb2wudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsc0RBQXNEO0FBQ3RELGdHQVdtRDtBQUVuRCx3RUFLdUM7QUFFdkMsb0RBTTZCO0FBSTdCLE1BQU0sU0FBUyxHQUFHLElBQUksc0JBQVMsQ0FBQyxFQUFFLE1BQU0sRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLFVBQVUsRUFBRSxDQUFDLENBQUM7QUFFcEUsTUFBTSwyQkFBMkIsR0FBRyxJQUFJLCtEQUE0QixDQUFDO0lBQ25FLE1BQU0sRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLFVBQVU7Q0FDL0IsQ0FBQyxDQUFDO0FBRUgsTUFBTSxrQkFBa0IsR0FBRyxJQUFJLHlDQUFrQixDQUFDO0lBQ2hELE1BQU0sRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLFVBQVU7Q0FDL0IsQ0FBQyxDQUFDO0FBRUgsSUFBSSx5QkFBb0QsQ0FBQztBQUV6RCxTQUFTLGNBQWMsQ0FBQyxHQUFRO0lBQzlCLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO1FBQ3ZCLE9BQU8sR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7SUFDakQsQ0FBQztJQUVELElBQUksT0FBTyxHQUFHLEtBQUssUUFBUSxFQUFFLENBQUM7UUFDNUIsTUFBTSxjQUFjLEdBQTJCLEVBQUUsQ0FBQztRQUNsRCxLQUFLLE1BQU0sR0FBRyxJQUFJLEdBQUcsRUFBRSxDQUFDO1lBQ3RCLElBQUksR0FBRyxDQUFDLGNBQWMsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO2dCQUM1QixNQUFNLGNBQWMsR0FBRyxHQUFHLENBQUMsTUFB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QU0sMkJBQTJCLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQ2pFLE9BQU8sUUFBUSxDQUFDO1FBQ2xCLENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsSUFBSSxLQUFLLFlBQVksS0FBSyxFQUFFLENBQUM7Z0JBQzNCLE1BQU0sVUFBVSxHQUFHLEtBR2xCLENBQUM7Z0JBQ0YsSUFDRSxVQUFVLENBQUMsSUFBSSxLQUFLLDJCQUEyQjtvQkFDL0MsVUFBVSxDQUFDLFNBQVMsRUFBRSxjQUFjLEtBQUssR0FBRyxFQUM1QyxDQUFDO29CQUNELE9BQU8sQ0FBQyxHQUFHLENBQUMsNEJBQTRCLFVBQVUsYUFBYSxDQUFDLENBQUM7b0JBQ2pFLE9BQU8sSUFBSSxDQUFDO2dCQUNkLENBQUM7cUJBQU0sQ0FBQztvQkFDTixPQUFPLENBQUMsS0FBSyxDQUFDLFFBQVEsRUFBRSxLQUFLLENBQUMsQ0FBQztvQkFDL0IsTUFBTSxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUM7Z0JBQ3JCLENBQUM7WUFDSCxDQUFDO2lCQUFNLENBQUM7Z0JBQ04sT0FBTyxDQUFDLEtBQUssQ0FBQywrQkFBK0IsRUFBRSxLQUFLLENBQUMsQ0FBQztnQkFDdEQsTUFBTSxLQUFLLENBQUM7WUFDZCxDQUFDO1FBQ0gsQ0FBQztJQUNILENBQUM7SUFDRCxNQUFNLElBQUksS0FBSyxDQUNiLHlDQUF5QyxXQUFXLFdBQVcsQ0FDaEUsQ0FBQztBQUNKLENBQUM7QUFFRCxTQUFTLEtBQUssQ0FBQyxFQUFVO0lBQ3ZCLE9BQU8sSUFBSSxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLFVBQVUsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUMzRCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyogZXNsaW50LWRpc2FibGUgaW1wb3J0L25vLWV4dHJhbmVvdXMtZGVwZW5kZW5jaWVzICovXG5pbXBvcnQge1xuICBDaGltZVNES01lZGlhUGlwZWxpbmVzQ2xpZW50LFxuICBDcmVhdGVNZWRpYVBpcGVsaW5lS2luZXNpc1ZpZGVvU3RyZWFtUG9vbENvbW1hbmQsXG4gIENyZWF0ZU1lZGlhUGlwZWxpbmVLaW5lc2lzVmlkZW9TdHJlYW1Qb29sQ29tbWFuZE91dHB1dCxcbiAgQ3JlYXRlTWVkaWFQaXBlbGluZUtpbmVzaXNWaWRlb1N0cmVhbVBvb2xDb21tYW5kSW5wdXQsXG4gIFRhZyxcbiAgVXBkYXRlTWVkaWFQaXBlbGluZUtpbmVzaXNWaWRlb1N0cmVhbVBvb2xDb21tYW5kSW5wdXQsXG4gIFVwZGF0ZU1lZGlhUGlwZWxpbmVLaW5lc2lzVmlkZW9TdHJlYW1Qb29sQ29tbWFuZE91dHB1dCxcbiAgVXBkYXRlTWVkaWFQaXBlbGluZUtpbmVzaXNWaWRlb1N0cmVhbVBvb2xDb21tYW5kLFxuICBEZWxldGVNZWRpYVBpcGVsaW5lS2luZXNpc1ZpZGVvU3RyZWFtUG9vbENvbW1hbmQsXG4gIEdldE1lZGlhUGlwZWxpbmVLaW5lc2lzVmlkZW9TdHJlYW1Qb29sQ29tbWFuZCxcbn0gZnJvbSAnQGF3cy1zZGsvY2xpZW50LWNoaW1lLXNkay1tZWRpYS1waXBlbGluZXMnO1xuXG5pbXBvcnQge1xuICBLaW5lc2lzVmlkZW9DbGllbnQsXG4gIExpc3RTdHJlYW1zQ29tbWFuZCxcbiAgRGVsZXRlU3RyZWFtQ29tbWFuZCxcbiAgQ29tcGFyaXNvbk9wZXJhdG9yLFxufSBmcm9tICdAYXdzLXNkay9jbGllbnQta2luZXNpcy12aWRlbyc7XG5cbmltcG9ydCB7XG4gIFNTTUNsaWVudCxcbiAgRGVsZXRlUGFyYW1ldGVyQ29tbWFuZCxcbiAgR2V0UGFyYW1ldGVyQ29tbWFuZCxcbiAgR2V0UGFyYW1ldGVyQ29tbWFuZE91dHB1dCxcbiAgUHV0UGFyYW1ldGVyQ29tbWFuZCxcbn0gZnJvbSAnQGF3cy1zZGsvY2xpZW50LXNzbSc7XG5cbmltcG9ydCB7IEtpbmVzaXNWaWRlb1N0cmVhbVBvb2xQcm9wcyB9IGZyb20gJy4uLy4uL21lZGlhLXBpcGVsaW5lcy9raW5lc2lzVmlkZW9TdHJlYW1Qb29sJztcblxuY29uc3Qgc3NtQ2xpZW50ID0gbmV3IFNTTUNsaWVudCh7IHJlZ2lvbjogcHJvY2Vzcy5lbnYuQVdTX1JFR0lPTiB9KTtcblxuY29uc3QgY2hpbWVTREtNZWRpYVBpcGVsaW5lQ2xpZW50ID0gbmV3IENoaW1lU0RLTWVkaWFQaXBlbGluZXNDbGllbnQoe1xuICByZWdpb246IHByb2Nlc3MuZW52LkFXU19SRUdJT04sXG59KTtcblxuY29uc3Qga2luZXNpc1ZpZGVvQ2xpZW50ID0gbmV3IEtpbmVzaXNWaWRlb0NsaWVudCh7XG4gIHJlZ2lvbjogcHJvY2Vzcy5lbnYuQVdTX1JFR0lPTixcbn0pO1xuXG5sZXQgZ2V0UGFyYW1ldGVyQ29tbWFuZE91dHB1dDogR2V0UGFyYW1ldGVyQ29tbWFuZE91dHB1dDtcblxuZnVuY3Rpb24gY2FwaXRhbGl6ZUtleXMob2JqOiBhbnkpOiBhbnkge1xuICBpZiAoQXJyYXkuaXNBcnJheShvYmopKSB7XG4gICAgcmV0dXJuIG9iai5tYXAoKGl0ZW0pID0+IGNhcGl0YWxpemVLZXlzKGl0ZW0pKTtcbiAgfVxuXG4gIGlmICh0eXBlb2Ygb2JqID09PSAnb2JqZWN0Jykge1xuICAgIGNvbnN0IGNhcGl0YWxpemVkT2JqOiB7IFtrZXk6IHN0cmluZ106IGFueSB9ID0ge307XG4gICAgZm9yIChjb25zdCBrZXkgaW4gb2JqKSB7XG4gICAgICBpZiAob2JqLmhhc093blByb3BlcnR5KGtleSkpIHtcbiAgICAgICAgY29uc3QgY2FwaXRhbGl6ZWRLZXkgPSBrZXkuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyBrZXkuc2xpY2UoMSk7XG4gICAgICAgIGNvbnN0IHZhbHVlID0gb2JqW2tleV07XG4gICAgICAgIGNhcGl0YWxpemVkT2JqW2NhcGl0YWxpemVkS2V5XSA9XG4gICAgICAgICAgdHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJyAmJiAhaXNOYU4ocGFyc2VGbG9hdCh2YWx1ZSkpXG4gICAgICAgICAgICA/IHBhcnNlRmxvYXQodmFsdWUpXG4gICAgICAgICAgICA6IGNhcGl0YWxpemVLZXlzKHZhbHVlKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGNhcGl0YWxpemVkT2JqO1xuICB9XG5cbiAgcmV0dXJuIG9iajtcbn1cblxubGV0IGNyZWF0ZU1lZGlhUGlwZWxpbmVLaW5lc2lzVmlkZW9TdHJlYW1Qb29sQ29tbWFuZE91dHB1dDogQ3JlYXRlTWVkaWFQaXBlbGluZUtpbmVzaXNWaWRlb1N0cmVhbVBvb2xDb21tYW5kT3V0cHV0O1xubGV0IGNyZWF0ZU1lZGlhUGlwZWxpbmVLaW5lc2lzVmlkZW9TdHJlYW1Qb29sQ29tbWFuZElucHV0OiBDcmVhdGVNZWRpYVBpcGVsaW5lS2luZXNpc1ZpZGVvU3RyZWFtUG9vbENvbW1hbmRJbnB1dDtcblxuY29uc3QgZm9ybWF0UHJvcHMgPSAocHJvcHM6IEtpbmVzaXNWaWRlb1N0cmVhbVBvb2xQcm9wcykgPT4ge1xuICBsZXQgZm9ybWF0dGVkVGFnczogVGFnW10gPSBbXTtcblxuICBpZiAocHJvcHMudGFncykge1xuICAgIGNvbnNvbGUuaW5mbyhgRm9ybWF0dGluZyBUYWdzOiAke0pTT04uc3RyaW5naWZ5KHByb3BzLnRhZ3MpfWApO1xuICAgIHByb3BzLnRhZ3MuZm9yRWFjaCgodGFnKSA9PiB7XG4gICAgICBmb3JtYXR0ZWRUYWdzLnB1c2goY2FwaXRhbGl6ZUtleXModGFnKSk7XG4gICAgfSk7XG4gICAgY29uc29sZS5pbmZvKGBGb3JtYXR0ZWQgVGFnczogJHtKU09OLnN0cmluZ2lmeShmb3JtYXR0ZWRUYWdzKX1gKTtcbiAgfVxuICBjb25zb2xlLmxvZyhgTmV3IGZvcm1hdHRlZFRhZ3M6ICR7Zm9ybWF0dGVkVGFnc31gKTtcblxuICBjcmVhdGVNZWRpYVBpcGVsaW5lS2luZXNpc1ZpZGVvU3RyZWFtUG9vbENvbW1hbmRJbnB1dCA9IHtcbiAgICBQb29sTmFtZTogcHJvcHMucG9vbE5hbWUsXG4gICAgU3RyZWFtQ29uZmlndXJhdGlvbjogY2FwaXRhbGl6ZUtleXMocHJvcHMuc3RyZWFtQ29uZmlndXJhdGlvbiksXG4gICAgLi4uKHByb3BzLnRhZ3MgJiYgeyBUYWdzOiBmb3JtYXR0ZWRUYWdzIH0pLFxuICAgIC4uLihwcm9wcy5jbGllbnRSZXF1ZXN0VG9rZW4gJiYge1xuICAgICAgQ2xpZW50UmVxdWVzdFRva2VuOiBwcm9wcy5jbGllbnRSZXF1ZXN0VG9rZW4sXG4gICAgfSksXG4gIH07XG5cbiAgY29uc29sZS5pbmZvKFxuICAgIGBtZWRpYUluc2lnaHRzUGlwZWxpbmVDb25maWd1cmF0aW9uUGFyYW1zOiAke0pTT04uc3RyaW5naWZ5KFxuICAgICAgY3JlYXRlTWVkaWFQaXBlbGluZUtpbmVzaXNWaWRlb1N0cmVhbVBvb2xDb21tYW5kSW5wdXQsXG4gICAgKX1gLFxuICApO1xuXG4gIHJldHVybiBjcmVhdGVNZWRpYVBpcGVsaW5lS2luZXNpc1ZpZGVvU3RyZWFtUG9vbENvbW1hbmRJbnB1dDtcbn07XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ3JlYXRlTWVkaWFJbnNpZ2h0c1BpcGVsaW5lQ29uZmlndXJhdGlvblByb3BzIHt9XG5leHBvcnQgY29uc3QgQ3JlYXRlS2luZXNpc1ZpZGVvU3RyZWFtUG9vbCA9IGFzeW5jIChcbiAgdWlkOiBzdHJpbmcsXG4gIHByb3BzOiBLaW5lc2lzVmlkZW9TdHJlYW1Qb29sUHJvcHMsXG4pID0+IHtcbiAgY29uc29sZS5sb2coYENyZWF0aW5nIEtpbmVzaXMgVmlkZW8gU3RyZWFtIFBvb2w6ICR7dWlkfWApO1xuICBjb25zb2xlLmxvZyhgQ3JlYXRlS2luZXNpc1ZpZGVvU3RyZWFtUG9vbCBwcm9wczogJHtKU09OLnN0cmluZ2lmeShwcm9wcyl9YCk7XG4gIGNyZWF0ZU1lZGlhUGlwZWxpbmVLaW5lc2lzVmlkZW9TdHJlYW1Qb29sQ29tbWFuZElucHV0ID0gZm9ybWF0UHJvcHMocHJvcHMpO1xuICBjb25zb2xlLmxvZyhcbiAgICBgQ3JlYXRlS2luZXNpc1ZpZGVvU3RyZWFtUG9vbCBwYXJhbXM6ICR7SlNPTi5zdHJpbmdpZnkoXG4gICAgICBjcmVhdGVNZWRpYVBpcGVsaW5lS2luZXNpc1ZpZGVvU3RyZWFtUG9vbENvbW1hbmRJbnB1dCxcbiAgICApfWAsXG4gICk7XG5cbiAgdHJ5IHtcbiAgICBjcmVhdGVNZWRpYVBpcGVsaW5lS2luZXNpc1ZpZGVvU3RyZWFtUG9vbENvbW1hbmRPdXRwdXQgPVxuICAgICAgYXdhaXQgY2hpbWVTREtNZWRpYVBpcGVsaW5lQ2xpZW50LnNlbmQoXG4gICAgICAgIG5ldyBDcmVhdGVNZWRpYVBpcGVsaW5lS2luZXNpc1ZpZGVvU3RyZWFtUG9vbENvbW1hbmQoXG4gICAgICAgICAgY3JlYXRlTWVkaWFQaXBlbGluZUtpbmVzaXNWaWRlb1N0cmVhbVBvb2xDb21tYW5kSW5wdXQsXG4gICAgICAgICksXG4gICAgICApO1xuICAgIGNvbnNvbGUubG9nKFxuICAgICAgYGNyZWF0ZU1lZGlhSW5zaWdodHNQaXBlbGluZUNvbmZpZ3VyYXRpb25SZXNwb25zZTogJHtKU09OLnN0cmluZ2lmeShcbiAgICAgICAgY3JlYXRlTWVkaWFQaXBlbGluZUtpbmVzaXNWaWRlb1N0cmVhbVBvb2xDb21tYW5kT3V0cHV0LFxuICAgICAgKX1gLFxuICAgICk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgaWYgKGVycm9yIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfVxuICB9XG5cbiAgdHJ5IHtcbiAgICBhd2FpdCBzc21DbGllbnQuc2VuZChcbiAgICAgIG5ldyBQdXRQYXJhbWV0ZXJDb21tYW5kKHtcbiAgICAgICAgTmFtZTogJy9jaGltZS9LaW5lc2lzVmlkZW9TdHJlYW1Qb29sSWQnICsgdWlkLFxuICAgICAgICBWYWx1ZTpcbiAgICAgICAgICBjcmVhdGVNZWRpYVBpcGVsaW5lS2luZXNpc1ZpZGVvU3RyZWFtUG9vbENvbW1hbmRPdXRwdXRcbiAgICAgICAgICAgIC5LaW5lc2lzVmlkZW9TdHJlYW1Qb29sQ29uZmlndXJhdGlvbj8uUG9vbElkLFxuICAgICAgICBEZXNjcmlwdGlvbjogJ0tpbmVzaXNWaWRlb1N0cmVhbVBvb2xJZCcgKyB1aWQsXG4gICAgICAgIE92ZXJ3cml0ZTogdHJ1ZSxcbiAgICAgICAgVHlwZTogJ1N0cmluZycsXG4gICAgICB9KSxcbiAgICApO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cbiAgfVxuICByZXR1cm4gY3JlYXRlTWVkaWFQaXBlbGluZUtpbmVzaXNWaWRlb1N0cmVhbVBvb2xDb21tYW5kT3V0cHV0LktpbmVzaXNWaWRlb1N0cmVhbVBvb2xDb25maWd1cmF0aW9uO1xufTtcblxubGV0IHVwZGF0ZU1lZGlhUGlwZWxpbmVLaW5lc2lzVmlkZW9TdHJlYW1Qb29sQ29tbWFuZElucHV0OiBVcGRhdGVNZWRpYVBpcGVsaW5lS2luZXNpc1ZpZGVvU3RyZWFtUG9vbENvbW1hbmRJbnB1dDtcbmxldCB1cGRhdGVNZWRpYVBpcGVsaW5lS2luZXNpc1ZpZGVvU3RyZWFtUG9vbENvbW1hbmRPdXRwdXQ6IFVwZGF0ZU1lZGlhUGlwZWxpbmVLaW5lc2lzVmlkZW9TdHJlYW1Qb29sQ29tbWFuZE91dHB1dDtcblxuZXhwb3J0IGNvbnN0IFVwZGF0ZUtpbmVzaXNWaWRlb1N0cmVhbVBvb2wgPSBhc3luYyAoXG4gIHVpZDogc3RyaW5nLFxuICBwcm9wczogS2luZXNpc1ZpZGVvU3RyZWFtUG9vbFByb3BzLFxuKSA9PiB7XG4gIGNvbnNvbGUubG9nKGBVcGRhdGVLaW5lc2lzVmlkZW9TdHJlYW1Qb29sOiAke3VpZH1gKTtcbiAgY29uc29sZS5sb2coYFVwZGF0ZUtpbmVzaXNWaWRlb1N0cmVhbVBvb2wgcHJvcHM6ICR7SlNPTi5zdHJpbmdpZnkocHJvcHMpfWApO1xuXG4gIHRyeSB7XG4gICAgZ2V0UGFyYW1ldGVyQ29tbWFuZE91dHB1dCA9IGF3YWl0IHNzbUNsaWVudC5zZW5kKFxuICAgICAgbmV3IEdldFBhcmFtZXRlckNvbW1hbmQoe1xuICAgICAgICBOYW1lOiAnL2NoaW1lL0tpbmVzaXNWaWRlb1N0cmVhbVBvb2xJZCcgKyB1aWQsXG4gICAgICB9KSxcbiAgICApO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cbiAgfVxuXG4gIHVwZGF0ZU1lZGlhUGlwZWxpbmVLaW5lc2lzVmlkZW9TdHJlYW1Qb29sQ29tbWFuZElucHV0ID0ge1xuICAgIElkZW50aWZpZXI6IGdldFBhcmFtZXRlckNvbW1hbmRPdXRwdXQuUGFyYW1ldGVyIS5WYWx1ZSEsXG4gICAgU3RyZWFtQ29uZmlndXJhdGlvbjoge1xuICAgICAgRGF0YVJldGVudGlvbkluSG91cnM6IE51bWJlcihcbiAgICAgICAgcHJvcHMuc3RyZWFtQ29uZmlndXJhdGlvbi5kYXRhUmV0ZW50aW9uSW5Ib3VycyxcbiAgICAgICksXG4gICAgfSxcbiAgfTtcblxuICBjb25zb2xlLmxvZyhcbiAgICBgVXBkYXRlIE1lZGlhIEluc2lnaHRzIFBpcGVsaW5lIENvbmZpZ3VyYXRpb24gcGFyYW1zOiAke0pTT04uc3RyaW5naWZ5KFxuICAgICAgdXBkYXRlTWVkaWFQaXBlbGluZUtpbmVzaXNWaWRlb1N0cmVhbVBvb2xDb21tYW5kSW5wdXQsXG4gICAgKX1gLFxuICApO1xuXG4gIHRyeSB7XG4gICAgdXBkYXRlTWVkaWFQaXBlbGluZUtpbmVzaXNWaWRlb1N0cmVhbVBvb2xDb21tYW5kT3V0cHV0ID1cbiAgICAgIGF3YWl0IGNoaW1lU0RLTWVkaWFQaXBlbGluZUNsaWVudC5zZW5kKFxuICAgICAgICBuZXcgVXBkYXRlTWVkaWFQaXBlbGluZUtpbmVzaXNWaWRlb1N0cmVhbVBvb2xDb21tYW5kKFxuICAgICAgICAgIHVwZGF0ZU1lZGlhUGlwZWxpbmVLaW5lc2lzVmlkZW9TdHJlYW1Qb29sQ29tbWFuZElucHV0LFxuICAgICAgICApLFxuICAgICAgKTtcbiAgICBjb25zb2xlLmxvZyhcbiAgICAgIGBjcmVhdGVNZWRpYUluc2lnaHRzUGlwZWxpbmVDb25maWd1cmF0aW9uUmVzcG9uc2U6ICR7SlNPTi5zdHJpbmdpZnkoXG4gICAgICAgIHVwZGF0ZU1lZGlhUGlwZWxpbmVLaW5lc2lzVmlkZW9TdHJlYW1Qb29sQ29tbWFuZE91dHB1dCxcbiAgICAgICl9YCxcbiAgICApO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdXBkYXRlTWVkaWFQaXBlbGluZUtpbmVzaXNWaWRlb1N0cmVhbVBvb2xDb21tYW5kT3V0cHV0LktpbmVzaXNWaWRlb1N0cmVhbVBvb2xDb25maWd1cmF0aW9uO1xufTtcblxuZXhwb3J0IGNvbnN0IERlbGV0ZUtpbmVzaXNWaWRlb1N0cmVhbVBvb2wgPSBhc3luYyAoXG4gIHVpZDogc3RyaW5nLFxuICBwcm9wczogS2luZXNpc1ZpZGVvU3RyZWFtUG9vbFByb3BzLFxuKSA9PiB7XG4gIGNvbnNvbGUubG9nKGBEZWxldGVLaW5lc2lzVmlkZW9TdHJlYW1Qb29sOiAke3VpZH1gKTtcblxuICB0cnkge1xuICAgIGdldFBhcmFtZXRlckNvbW1hbmRPdXRwdXQgPSBhd2FpdCBzc21DbGllbnQuc2VuZChcbiAgICAgIG5ldyBHZXRQYXJhbWV0ZXJDb21tYW5kKHtcbiAgICAgICAgTmFtZTogJy9jaGltZS9LaW5lc2lzVmlkZW9TdHJlYW1Qb29sSWQnICsgdWlkLFxuICAgICAgfSksXG4gICAgKTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG4gIH1cblxuICB0cnkge1xuICAgIGF3YWl0IHNzbUNsaWVudC5zZW5kKFxuICAgICAgbmV3IERlbGV0ZVBhcmFtZXRlckNvbW1hbmQoe1xuICAgICAgICBOYW1lOiAnL2NoaW1lL0tpbmVzaXNWaWRlb1N0cmVhbVBvb2xJZCcgKyB1aWQsXG4gICAgICB9KSxcbiAgICApO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cbiAgfVxuXG4gIGNvbnNvbGUuaW5mbyhgZGVsZXRlTWVkaWFJbnNpZ2h0c1BpcGVsaW5lSWRlbnRpZmllcjogJHtwcm9wcy5wb29sTmFtZX1gKTtcblxuICB0cnkge1xuICAgIGF3YWl0IGNoaW1lU0RLTWVkaWFQaXBlbGluZUNsaWVudC5zZW5kKFxuICAgICAgbmV3IERlbGV0ZU1lZGlhUGlwZWxpbmVLaW5lc2lzVmlkZW9TdHJlYW1Qb29sQ29tbWFuZCh7XG4gICAgICAgIElkZW50aWZpZXI6IHByb3BzLnBvb2xOYW1lLFxuICAgICAgfSksXG4gICAgKTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG4gIH1cblxuICBhd2FpdCBnZXRNZWRpYVBpcGVsaW5lS2luZXNpc1ZpZGVvU3RyZWFtUG9vbChwcm9wcy5wb29sTmFtZSEsIDE4KTtcblxuICBjb25zdCBzdHJlYW1zVG9EZWxldGUgPSBhd2FpdCBsaXN0QWxsU3RyZWFtcyhwcm9wcy5wb29sTmFtZSEpO1xuICBhd2FpdCBkZWxldGVBbGxTdHJlYW1zKHN0cmVhbXNUb0RlbGV0ZSk7XG4gIHJldHVybjtcbn07XG5cbmFzeW5jIGZ1bmN0aW9uIGxpc3RBbGxTdHJlYW1zKHByZWZpeDogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmdbXT4ge1xuICBsZXQgbmV4dFRva2VuOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gIGNvbnN0IHN0cmVhbXM6IHN0cmluZ1tdID0gW107XG5cbiAgdHJ5IHtcbiAgICBkbyB7XG4gICAgICBjb25zdCBpbnB1dCA9IHtcbiAgICAgICAgTWF4UmVzdWx0czogMTAwLFxuICAgICAgICBOZXh0VG9rZW46IG5leHRUb2tlbixcbiAgICAgICAgU3RyZWFtTmFtZUNvbmRpdGlvbjoge1xuICAgICAgICAgIENvbXBhcmlzb25PcGVyYXRvcjogQ29tcGFyaXNvbk9wZXJhdG9yLkJFR0lOU19XSVRILFxuICAgICAgICAgIENvbXBhcmlzb25WYWx1ZTogJ0NoaW1lTWVkaWFQaXBlbGluZXMtJyArIHByZWZpeCxcbiAgICAgICAgfSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQga2luZXNpc1ZpZGVvQ2xpZW50LnNlbmQoXG4gICAgICAgIG5ldyBMaXN0U3RyZWFtc0NvbW1hbmQoaW5wdXQpLFxuICAgICAgKTtcbiAgICAgIGlmIChyZXNwb25zZS5TdHJlYW1JbmZvTGlzdCkge1xuICAgICAgICBmb3IgKGNvbnN0IHN0cmVhbUluZm8gb2YgcmVzcG9uc2UuU3RyZWFtSW5mb0xpc3QpIHtcbiAgICAgICAgICBpZiAoc3RyZWFtSW5mby5TdHJlYW1BUk4pIHtcbiAgICAgICAgICAgIHN0cmVhbXMucHVzaChzdHJlYW1JbmZvLlN0cmVhbUFSTik7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBuZXh0VG9rZW4gPSByZXNwb25zZS5OZXh0VG9rZW47XG4gICAgfSB3aGlsZSAobmV4dFRva2VuKTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBjb25zb2xlLmVycm9yKCdFcnJvciBsaXN0aW5nIHN0cmVhbXM6JywgZXJyb3IpO1xuICAgIHRocm93IGVycm9yOyAvLyBSZXRocm93IHRoZSBlcnJvciBpZiB5b3Ugd2FudCB0byBoYW5kbGUgaXQgZnVydGhlciB1cCB0aGUgY2FsbCBzdGFja1xuICB9XG4gIGNvbnNvbGUubG9nKCdTdHJlYW1zIHRvIGRlbGV0ZTogJywgc3RyZWFtcyk7XG4gIHJldHVybiBzdHJlYW1zO1xufVxuXG5hc3luYyBmdW5jdGlvbiBkZWxldGVBbGxTdHJlYW1zKHN0cmVhbUFSTnM6IHN0cmluZ1tdKTogUHJvbWlzZTx2b2lkPiB7XG4gIHRyeSB7XG4gICAgZm9yIChjb25zdCBzdHJlYW1BUk4gb2Ygc3RyZWFtQVJOcykge1xuICAgICAgYXdhaXQga2luZXNpc1ZpZGVvQ2xpZW50LnNlbmQoXG4gICAgICAgIG5ldyBEZWxldGVTdHJlYW1Db21tYW5kKHsgU3RyZWFtQVJOOiBzdHJlYW1BUk4gfSksXG4gICAgICApO1xuICAgICAgY29uc29sZS5sb2coJ0RlbGV0ZWQ6ICcsIHN0cmVhbUFSTik7XG4gICAgfVxuICB9IGNhdGNoIChlcnJvcikge1xuICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIGxpc3Rpbmcgc3RyZWFtczonLCBlcnJvcik7XG4gICAgdGhyb3cgZXJyb3I7IC8vIFJldGhyb3cgdGhlIGVycm9yIGlmIHlvdSB3YW50IHRvIGhhbmRsZSBpdCBmdXJ0aGVyIHVwIHRoZSBjYWxsIHN0YWNrXG4gIH1cbiAgY29uc29sZS5sb2coJ0FsbCBzdHJlYW1zIGRlbGV0ZWQnKTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gZ2V0TWVkaWFQaXBlbGluZUtpbmVzaXNWaWRlb1N0cmVhbVBvb2woXG4gIGlkZW50aWZpZXI6IHN0cmluZyxcbiAgbWF4QXR0ZW1wdHM6IG51bWJlcixcbikge1xuICBjb25zdCBpbnB1dCA9IHtcbiAgICBJZGVudGlmaWVyOiBpZGVudGlmaWVyLFxuICB9O1xuICBjb25zdCBjb21tYW5kID0gbmV3IEdldE1lZGlhUGlwZWxpbmVLaW5lc2lzVmlkZW9TdHJlYW1Qb29sQ29tbWFuZChpbnB1dCk7XG5cbiAgZm9yIChsZXQgYXR0ZW1wdCA9IDE7IGF0dGVtcHQgPD0gbWF4QXR0ZW1wdHM7IGF0dGVtcHQrKykge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGNoaW1lU0RLTWVkaWFQaXBlbGluZUNsaWVudC5zZW5kKGNvbW1hbmQpO1xuICAgICAgcmV0dXJuIHJlc3BvbnNlO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICBjb25zdCB0eXBlZEVycm9yID0gZXJyb3IgYXMge1xuICAgICAgICAgIG5hbWU6IHN0cmluZztcbiAgICAgICAgICAkbWV0YWRhdGE/OiB7IGh0dHBTdGF0dXNDb2RlOiBudW1iZXIgfTtcbiAgICAgICAgfTtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIHR5cGVkRXJyb3IubmFtZSA9PT0gJ1Jlc291cmNlTm90Rm91bmRFeGNlcHRpb24nIHx8XG4gICAgICAgICAgdHlwZWRFcnJvci4kbWV0YWRhdGE/Lmh0dHBTdGF0dXNDb2RlID09PSA0MDRcbiAgICAgICAgKSB7XG4gICAgICAgICAgY29uc29sZS5sb2coYFJlc291cmNlIHdpdGggaWRlbnRpZmllciAke2lkZW50aWZpZXJ9IG5vdCBmb3VuZC5gKTtcbiAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvcjonLCBlcnJvcik7XG4gICAgICAgICAgYXdhaXQgc2xlZXAoMTAwMDApO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zb2xlLmVycm9yKCdBbiB1bmV4cGVjdGVkIGVycm9yIG9jY3VycmVkOicsIGVycm9yKTtcbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHRocm93IG5ldyBFcnJvcihcbiAgICBgRmFpbGVkIHRvIGRlbGV0ZSBtZWRpYSBwaXBlbGluZSBhZnRlciAke21heEF0dGVtcHRzfSBhdHRlbXB0c2AsXG4gICk7XG59XG5cbmZ1bmN0aW9uIHNsZWVwKG1zOiBudW1iZXIpIHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiBzZXRUaW1lb3V0KHJlc29sdmUsIG1zKSk7XG59XG4iXX0=