UNPKG

cdk-amazon-chime-resources

Version:

![Experimental](https://img.shields.io/badge/experimental-important.svg?style=for-the-badge)

251 lines 35.7 kB
"use strict"; 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=