From 655f3b4d8fba8f64656dbe3252f77a5fac70a21a Mon Sep 17 00:00:00 2001 From: Itzik Paz Date: Tue, 16 Mar 2021 03:11:35 +0000 Subject: [PATCH 01/20] genomics pipeline using CDK --- src/aws-genomics-cdk/.gitignore | 8 + src/aws-genomics-cdk/.npmignore | 6 + src/aws-genomics-cdk/README.md | 14 + src/aws-genomics-cdk/app.config.json | 56 + .../assets/genomics-policy-s3.json | 33 + .../assets/launch_template_user_data.txt | 34 + src/aws-genomics-cdk/bin/aws-genomics-cdk.ts | 13 + src/aws-genomics-cdk/cdk.context.json | 63 + src/aws-genomics-cdk/cdk.json | 13 + src/aws-genomics-cdk/containers/README.md | 247 + src/aws-genomics-cdk/containers/build.sh | 67 + .../containers/entry.dockerfile | 15 + src/aws-genomics-cdk/containers/entrypoint.sh | 196 + .../containers/fastqc/Dockerfile | 33 + .../containers/minimap2/Dockerfile | 28 + src/aws-genomics-cdk/examples/README.md | 116 + .../examples/batch-fastqc-job.json | 27 + .../examples/batch-minimap2-job.json | 27 + src/aws-genomics-cdk/jest.config.js | 7 + .../lib/aws-genomics-cdk-stack.ts | 54 + .../batch-compute-environmnet-construct.ts | 66 + .../lib/batch/batch-iam-stack.ts | 89 + src/aws-genomics-cdk/lib/batch/batch-stack.ts | 122 + .../lib/batch/job-queue-construct.ts | 38 + .../lib/batch/launch-template-construct.ts | 60 + .../genomics-state-machine-stack.ts | 104 + .../step-functions/genomics-task-construct.ts | 52 + .../job-definition-construct.ts | 59 + .../lib/step-functions/job-definitions.ts | 68 + src/aws-genomics-cdk/lib/vpc/vpc-stack.ts | 32 + src/aws-genomics-cdk/package-lock.json | 7594 +++++++++++++++++ src/aws-genomics-cdk/package.json | 31 + .../test/aws-genomics-cdk.test.ts | 13 + src/aws-genomics-cdk/tsconfig.json | 24 + 34 files changed, 9409 insertions(+) create mode 100644 src/aws-genomics-cdk/.gitignore create mode 100644 src/aws-genomics-cdk/.npmignore create mode 100644 src/aws-genomics-cdk/README.md create mode 100644 src/aws-genomics-cdk/app.config.json create mode 100644 src/aws-genomics-cdk/assets/genomics-policy-s3.json create mode 100644 src/aws-genomics-cdk/assets/launch_template_user_data.txt create mode 100644 src/aws-genomics-cdk/bin/aws-genomics-cdk.ts create mode 100644 src/aws-genomics-cdk/cdk.context.json create mode 100644 src/aws-genomics-cdk/cdk.json create mode 100644 src/aws-genomics-cdk/containers/README.md create mode 100755 src/aws-genomics-cdk/containers/build.sh create mode 100644 src/aws-genomics-cdk/containers/entry.dockerfile create mode 100644 src/aws-genomics-cdk/containers/entrypoint.sh create mode 100644 src/aws-genomics-cdk/containers/fastqc/Dockerfile create mode 100644 src/aws-genomics-cdk/containers/minimap2/Dockerfile create mode 100644 src/aws-genomics-cdk/examples/README.md create mode 100644 src/aws-genomics-cdk/examples/batch-fastqc-job.json create mode 100644 src/aws-genomics-cdk/examples/batch-minimap2-job.json create mode 100644 src/aws-genomics-cdk/jest.config.js create mode 100644 src/aws-genomics-cdk/lib/aws-genomics-cdk-stack.ts create mode 100644 src/aws-genomics-cdk/lib/batch/batch-compute-environmnet-construct.ts create mode 100644 src/aws-genomics-cdk/lib/batch/batch-iam-stack.ts create mode 100644 src/aws-genomics-cdk/lib/batch/batch-stack.ts create mode 100644 src/aws-genomics-cdk/lib/batch/job-queue-construct.ts create mode 100644 src/aws-genomics-cdk/lib/batch/launch-template-construct.ts create mode 100644 src/aws-genomics-cdk/lib/step-functions/genomics-state-machine-stack.ts create mode 100644 src/aws-genomics-cdk/lib/step-functions/genomics-task-construct.ts create mode 100644 src/aws-genomics-cdk/lib/step-functions/job-definition-construct.ts create mode 100644 src/aws-genomics-cdk/lib/step-functions/job-definitions.ts create mode 100644 src/aws-genomics-cdk/lib/vpc/vpc-stack.ts create mode 100644 src/aws-genomics-cdk/package-lock.json create mode 100644 src/aws-genomics-cdk/package.json create mode 100644 src/aws-genomics-cdk/test/aws-genomics-cdk.test.ts create mode 100644 src/aws-genomics-cdk/tsconfig.json diff --git a/src/aws-genomics-cdk/.gitignore b/src/aws-genomics-cdk/.gitignore new file mode 100644 index 000000000..f60797b6a --- /dev/null +++ b/src/aws-genomics-cdk/.gitignore @@ -0,0 +1,8 @@ +*.js +!jest.config.js +*.d.ts +node_modules + +# CDK asset staging directory +.cdk.staging +cdk.out diff --git a/src/aws-genomics-cdk/.npmignore b/src/aws-genomics-cdk/.npmignore new file mode 100644 index 000000000..c1d6d45dc --- /dev/null +++ b/src/aws-genomics-cdk/.npmignore @@ -0,0 +1,6 @@ +*.ts +!*.d.ts + +# CDK asset staging directory +.cdk.staging +cdk.out diff --git a/src/aws-genomics-cdk/README.md b/src/aws-genomics-cdk/README.md new file mode 100644 index 000000000..324766518 --- /dev/null +++ b/src/aws-genomics-cdk/README.md @@ -0,0 +1,14 @@ +# Welcome to your CDK TypeScript project! + +This is a blank project for TypeScript development with CDK. + +The `cdk.json` file tells the CDK Toolkit how to execute your app. + +## Useful commands + + * `npm run build` compile typescript to js + * `npm run watch` watch for changes and compile + * `npm run test` perform the jest unit tests + * `cdk deploy` deploy this stack to your default AWS account/region + * `cdk diff` compare deployed stack with current state + * `cdk synth` emits the synthesized CloudFormation template diff --git a/src/aws-genomics-cdk/app.config.json b/src/aws-genomics-cdk/app.config.json new file mode 100644 index 000000000..028785b68 --- /dev/null +++ b/src/aws-genomics-cdk/app.config.json @@ -0,0 +1,56 @@ +{ + "accountID": "111111111111", + "region": "us-west-2", + "S3": { + "existingBucket": true, + "bucketName": "" + }, + "VPC": { + "createVPC": true, + "existingVPCName": "", + "maxAZs": 2, + "cidr": "10.0.0.0/16", + "cidrMask": 24 + }, + "batch": { + "defaultVolumeSize": 100, + "spotMaxVCPUs": 128, + "onDemendMaxVCPUs": 128, + "instanceTypes": [ + "c4.large", + "c4.xlarge", + "c4.2xlarge", + "c4.4xlarge", + "c4.8xlarge", + "c5.large", + "c5.xlarge", + "c5.2xlarge", + "c5.4xlarge", + "c5.9xlarge", + "c5.12xlarge", + "c5.18xlarge", + "c5.24xlarge" + ] + }, + "stepFunctions": { + "launchDemoPipeline": true, + "jobDefinitions": { + "fastqc": { + "repository": "genomics/fastqc", + "memoryLimit": 8000, + "vcpus": 4, + "spot": true, + "retryAttempts":1, + "timeout": 600 + }, + "minimap2": { + "repository": "genomics/minimap2", + "memoryLimit": 16000, + "vcpus": 8, + "spot": true, + "retryAttempts":1, + "timeout": 3600 + } + } + } +} \ No newline at end of file diff --git a/src/aws-genomics-cdk/assets/genomics-policy-s3.json b/src/aws-genomics-cdk/assets/genomics-policy-s3.json new file mode 100644 index 000000000..0f55b4d69 --- /dev/null +++ b/src/aws-genomics-cdk/assets/genomics-policy-s3.json @@ -0,0 +1,33 @@ +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Deny", + "Action": [ + "s3:Delete*", + "s3:PutBucket*" + ], + "Resource": [ + "arn:aws:s3:::BUCKET_NAME" + ] + }, + { + "Effect": "Allow", + "Action": [ + "s3:ListBucket*" + ], + "Resource": [ + "arn:aws:s3:::BUCKET_NAME" + ] + }, + { + "Effect": "Allow", + "Action": [ + "s3:*" + ], + "Resource": [ + "arn:aws:s3:::BUCKET_NAME/*" + ] + } + ] +} \ No newline at end of file diff --git a/src/aws-genomics-cdk/assets/launch_template_user_data.txt b/src/aws-genomics-cdk/assets/launch_template_user_data.txt new file mode 100644 index 000000000..54044af34 --- /dev/null +++ b/src/aws-genomics-cdk/assets/launch_template_user_data.txt @@ -0,0 +1,34 @@ +MIME-Version: 1.0 +Content-Type: multipart/mixed; boundary="==BOUNDARY==" + +--==BOUNDARY== +Content-Type: text/cloud-config; charset="us-ascii" + +packages: +- jq +- btrfs-progs +- sed +- git +- amazon-ssm-agent +- unzip + +runcmd: +# install aws-cli v2 and copy the static binary in an easy to find location for bind-mounts into containers +- curl -s "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "/tmp/awscliv2.zip" +- unzip -q /tmp/awscliv2.zip -d /tmp +- /tmp/aws/install -b /usr/bin + +# check that the aws-cli was actually installed. if not shutdown (terminate) the instance +- command -v aws || shutdown -P now + +- mkdir -p /opt/aws-cli/bin +- cp -a $(dirname $(find /usr/local/aws-cli -name 'aws' -type f))/. /opt/aws-cli/bin/ + + +# enable ecs spot instance draining +- echo ECS_ENABLE_SPOT_INSTANCE_DRAINING=true >> /etc/ecs/ecs.config + +- systemctl enable amazon-ssm-agent +- systemctl start amazon-ssm-agent + +--==BOUNDARY==-- \ No newline at end of file diff --git a/src/aws-genomics-cdk/bin/aws-genomics-cdk.ts b/src/aws-genomics-cdk/bin/aws-genomics-cdk.ts new file mode 100644 index 000000000..f1a12640c --- /dev/null +++ b/src/aws-genomics-cdk/bin/aws-genomics-cdk.ts @@ -0,0 +1,13 @@ +#!/usr/bin/env node +import 'source-map-support/register'; +import * as cdk from '@aws-cdk/core'; +import { AwsGenomicsCdkStack } from '../lib/aws-genomics-cdk-stack'; +import * as config from "../app.config.json"; + +const env = { + account: process.env.CDK_DEFAULT_ACCOUNT ?? config.accountID, + region: process.env.CDK_DEFAULT_REGION ?? config.region +} + +const app = new cdk.App(); +new AwsGenomicsCdkStack(app, 'AwsGenomicsCdkStack', {env: env}); diff --git a/src/aws-genomics-cdk/cdk.context.json b/src/aws-genomics-cdk/cdk.context.json new file mode 100644 index 000000000..b30a2f535 --- /dev/null +++ b/src/aws-genomics-cdk/cdk.context.json @@ -0,0 +1,63 @@ +{ + "availability-zones:account=549173009724:region=us-west-2": [ + "us-west-2a", + "us-west-2b", + "us-west-2c", + "us-west-2d" + ], + "vpc-provider:account=549173009724:filter.tag:Name=GenomicsPipelineStack/genomics-vpc-stack/genomics-vpc:region=us-west-2:returnAsymmetricSubnets=true": { + "vpcId": "vpc-0e12b34b410ce432d", + "vpcCidrBlock": "10.0.0.0/16", + "availabilityZones": [], + "subnetGroups": [ + { + "name": "public", + "type": "Public", + "subnets": [ + { + "subnetId": "subnet-01f8be5070f8f0c41", + "cidr": "10.0.3.0/24", + "availabilityZone": "us-west-2a", + "routeTableId": "rtb-0db455d5a3da84065" + }, + { + "subnetId": "subnet-0c0e2287b8f96dff9", + "cidr": "10.0.4.0/24", + "availabilityZone": "us-west-2b", + "routeTableId": "rtb-0c5cd45dbc8e33ef7" + }, + { + "subnetId": "subnet-0c2c15f728465a4c2", + "cidr": "10.0.5.0/24", + "availabilityZone": "us-west-2c", + "routeTableId": "rtb-0c2e59776f577a3b7" + } + ] + }, + { + "name": "private", + "type": "Private", + "subnets": [ + { + "subnetId": "subnet-0d82fc3969299134f", + "cidr": "10.0.0.0/24", + "availabilityZone": "us-west-2a", + "routeTableId": "rtb-0d6ddf764ea60615b" + }, + { + "subnetId": "subnet-095bc96659c1f7af4", + "cidr": "10.0.1.0/24", + "availabilityZone": "us-west-2b", + "routeTableId": "rtb-0de1df34a81474cf1" + }, + { + "subnetId": "subnet-013b7a044af9c6542", + "cidr": "10.0.2.0/24", + "availabilityZone": "us-west-2c", + "routeTableId": "rtb-0541671d21b141dc3" + } + ] + } + ] + } +} diff --git a/src/aws-genomics-cdk/cdk.json b/src/aws-genomics-cdk/cdk.json new file mode 100644 index 000000000..2f99395d6 --- /dev/null +++ b/src/aws-genomics-cdk/cdk.json @@ -0,0 +1,13 @@ +{ + "app": "npx ts-node --prefer-ts-exts bin/aws-genomics-cdk.ts", + "context": { + "@aws-cdk/core:enableStackNameDuplicates": "true", + "aws-cdk:enableDiffNoFail": "true", + "@aws-cdk/core:stackRelativeExports": "true", + "@aws-cdk/aws-ecr-assets:dockerIgnoreSupport": true, + "@aws-cdk/aws-secretsmanager:parseOwnedSecretName": true, + "@aws-cdk/aws-kms:defaultKeyPolicies": true, + "@aws-cdk/aws-s3:grantWriteWithoutAcl": true, + "@aws-cdk/aws-ecs-patterns:removeDefaultDesiredCount": true + } +} diff --git a/src/aws-genomics-cdk/containers/README.md b/src/aws-genomics-cdk/containers/README.md new file mode 100644 index 000000000..180712c1c --- /dev/null +++ b/src/aws-genomics-cdk/containers/README.md @@ -0,0 +1,247 @@ +# Setting up bioinformatics containers + +The CDK genomics pipeline project is leveraging [AWS Batch](https://aws.amazon.com/batch/) for +running bioinformatics jobs. AWS Batch works with docker containers which means we'll need to +build or use an existing docker container with the bioinfomatics tools installed. + +Start by creating a folder for your tool and place the Dockerfile inside of that folder. +There are few sample tools in this repos that you can look at: +**copy** - A tool for testing the system without the need to run any bioinfomatics tools. +**fastqc** - A quality control tool for high throughput sequence data. [Tool reference](https://www.bioinformatics.babraham.ac.uk/projects/fastqc/) +**minimap2** - Minimap2 is a versatile sequence alignment program that aligns DNA or mRNA sequences against a large reference database. [Tool reference](https://github.com/lh3/minimap2) + +For each of these tools you can find a folder that contains 2 files - Dockerfile and job.json +**Dockerfile** - The docker file to use for the bioinfomatics tool +**job.json** - A sample job you can use to test the tool with AWS bath. To run AWS batch command to test a job use the +follwing command: `aws batch submit-job --cli-input-json file://job.json` + + +### Building a container +This project include a tool to help build a container and push it to [Amazon Elastic Container Registry](https://aws.amazon.com/ecr/) (ECR) +The tool is relying on 2 environment variables CDK_DEFAULT_ACCOUNT (your AWS 12 digit account id) and +CDK_DEFAULT_REGION (the regiong where you would like to deploy your pipelione. e.g., us-west-2). You'll need to add this parameter +to your environment variables (e.g., `~/.bash_profile`). +To add these parameters to `~/.bash_profile`, open the file and add these 2 lines and make sure to set the region and account id +accordingly. +``` +export CDK_DEFAULT_REGION='us-west-2' +export CDK_DEFAULT_ACCOUNT='111111111111' +``` +Save the file and run the following command: `source ~/.bash_profile`. This will set the environment variabled. + +To build the container and push it to ECR use the build.sh script by running `./build.sh TOOL_NANE` (e.g., `./build.sh fastqc`). + +The build tool will first build the bioinformatics docker container and then will chain it with `entry.dockerfile` docker container. +This container overrides the docker `ENTRYPOINT` and introduce a script (`entrypoint.sh`) which will act as the docker +container `ENTRYPOINT`. This script can copy data files from urls and S3 buckets to the local running machine, then execute the +bioinformatics tool, and at the end will be able to save any output files creatd by the running tool back to an S3 bucket. + +When submitting a job to run the bioinfomatics tools, you can provide the following environment variables that will take +care of copying input files to the machine and copy output files to S3. + +``` +JOB_WORKFLOW_NAME + Optional + Name of the parent workflow for this job. + Used with JOB_WORKFLOW_EXECUTION_ID to generate a unique prefix for workflow outputs. + +JOB_WORKFLOW_EXECUTION_ID + Optional + Unique identifier for the current workflow run. Used with JOB_WORKFLOW_NAME + to generate a unique prefix for workflow outputs. + +JOB_AWS_CLI_PATH + Required if staging data from S3. + Default: /opt/aws-cli/bin + Path to add to the PATH environment variable so that the AWS CLI can be + located. Use this if bindmounting the AWS CLI from the host and it is + packaged in a self-contained way (e.g. not needing OS/distribution + specific shared libraries). The AWS CLI installed with `conda` is + sufficiently self-contained. Using a standard python virtualenv does + not work. + +JOB_DATA_ISOLATION + Optional + Default: null + Set to 1 if container will need to use an isolated data space - e.g. + it will operate in a volume mounted from the host for scratch + +JOB_INPUTS + Optional + Default: null + A space delimited list of http(s) urls or s3 object urls - e.g.: + https://somedomain.com/path s3://{prefix1}/{key_pattern1} [s3://{prefix2}/{key_pattern2} [...]] + for files that the job will use as inputs + +JOB_OUTPUTS + Optional + Default: null + A space delimited list of files - e.g.: + file1 [file2 [...]] + that the job generates that will be retained - i.e. transferred back to S3 + +JOB_OUTPUT_PREFIX + Required if JOB_OUTPUTS need to be stored on S3 + Default: null + S3 location (e.g. s3://bucket/prefix) were job outputs will be stored + +JOB_INPUT_S3_COPY_METHOD + Optional + Default: s3cp + If copying files from an S3 bucket, choose the method for the copy + s3cp: use s3 cp --no-progress --recursive --exclude "*" --include JOB_INPUT (an s3 input from the JOB_INPUTS) + s3sync: use s3 sync JOB_INPUT . (for each s3 input from the JOB_INPUTS) + +JOB_OUTPUT_S3_COPY_METHOD + Optional + Default: s3cp + If copying files to an S3 bucket, choose the method for the copy + s3cp: use s3 cp --no-progress file (a file from the JOB_OUTPUTS) + s3sync: use s3 sync LOCAL_PATH JOB_OUTPUT_PREFIX (Sync a local path to the JOB_OUTPUT_PREFIX location) +``` + +### Testing the bioinformatics tool +After [deploying the CDK genomics pipeline project](GITHUB URL) you could test the genomics tools directly with AWS Batch. +Create a file named job.json in the folder of the bioinformatics tool (the same folder where you places the Dockerfile) + +``` +{ + "jobName": "", + "jobQueue": "", + "jobDefinition": "", + "containerOverrides": { + "vcpus": 1, + "memory": 1000, + "command": [""], + "environment": [{ + "name": "JOB_INPUTS", + "value": "" + }, + { + "name": "JOB_INPUT_S3_COPY_METHOD", + "value": "" + }, + { + "name": "JOB_OUTPUTS", + "value": "" + }, + { + "name": "JOB_OUTPUT_S3_COPY_METHOD", + "value": "" + }, + { + "name": "JOB_OUTPUT_PREFIX", + "value": "" + }, + { + "name": "JOB_AWS_CLI_PATH", + "value": "/opt/aws-cli/bin" + } + ] + } +} + +``` + +**jobName** (string) +The name of the job. The first character must be alphanumeric, and up to 128 letters (uppercase and lowercase), +numbers, hyphens, and underscores are allowed. + +**jobQueue** (string) +The [job queue](https://docs.aws.amazon.com/batch/latest/userguide/job_queues.html) into which the job is submitted. +You can specify either the name or the Amazon Resource Name (ARN) of the queue. + +**jobDefinition** (string) +The [job definition](https://docs.aws.amazon.com/batch/latest/userguide/job_definitions.html) used by this job. +This value can be one of name , name:revision , or the Amazon Resource Name (ARN) for the job definition. If name is +specified without a revision then the latest active revision is used. + +**containerOverrides.vcpus** (integer) +The number of vCPUs to reserve for the container. This value overrides the value set in the job definition. + +**containerOverrides.memory** (integer) +The number of MiB of memory reserved for the job. This value overrides the value set in the job definition. + +**containerOverrides.command** (list) +The command to send to the container that overrides the default command from the Docker image or the job definition. + +**containerOverrides.environment** (list) +The environment variables to send to the container. You can add new environment variables, which are added to the +container at launch, or you can override the existing environment variables from the Docker image or the job definition. +(structure) +A key-value pair object. +**name** (string) +The name of the key-value pair. For environment variables, this is the name of the environment variable. +**value** (string) +The value of the key-value pair. For environment variables, this is the value of the environment variable. + +Example for a job.json +``` +{ + "jobName": "fastqc", + "jobQueue": "genomics-default-queue", + "jobDefinition": "genomics-fastqc:1", + "containerOverrides": { + "vcpus": 8, + "memory": 16000, + "command": ["fastqc *.gz"], + "environment": [{ + "name": "JOB_INPUTS", + "value": "s3://aws-batch-genomics-shared/secondary-analysis/example-files/fastq/NIST7035_R1_trim_samp-0p1.fastq.gz s3://aws-batch-genomics-shared/secondary-analysis/example-files/fastq/NIST7035_R2_trim_samp-0p1.fastq.gz" + }, + { + "name": "JOB_INPUT_S3_COPY_METHOD", + "value": "s3cp" + }, + { + "name": "JOB_OUTPUTS", + "value": "*.html *.zip" + }, + { + "name": "JOB_OUTPUT_S3_COPY_METHOD", + "value": "s3cp" + }, + { + "name": "JOB_OUTPUT_PREFIX", + "value": "s3://my-genomics-bucket-name/some-folder-name" + }, + { + "name": "JOB_AWS_CLI_PATH", + "value": v + } + ] + } +} + +``` +In this example we are running the FastQC tools that will take fastq files and generate a report. It will output zip and +html files which we will save to an S3 bucket. +**jobName** - "fastqc". A name that describe the job to be run. +**jobQueue** - "genomics-default-queue". A valid name of a job queue. This could be found in the AWS web console > +Batch > Job queues. +**jobDefinition** - "genomics-fastqc:1". A valid and active job definition and it's version. This could be found in the +AWS web console > Batch > Job definitions. +**containerOverrides.vcpus** - 8. Request a machine that has at least 8 cores. +**containerOverrides.memory** - 16000. Request a machine that has at least 16GiB of RAM. +**containerOverrides.command** - ["fastqc *.gz"]. Run the fastq command on all the .gz files in the working directory. +**containerOverrides.environment** - A list of key-value pairs. + +**name**: JOB_INPUTS. +**value**: fastq files from an S3 bucket + +**name**: JOB_INPUT_S3_COPY_METHOD +**value**: "s3cp. Use the aws s3 cp command to copy files from an S3 bucket to the a local directory. + +**name**: JOB_OUTPUTS. +**value**: "*.html *.zip". Copy all html and zip files from a local directory to an S3 bucket. + +**name**: JOB_OUTPUT_S3_COPY_METHOD. +**value**: "s3cp". Use the aws s3 cp command to copy files from a local directory to an S3 bucket. + +**name**: JOB_OUTPUT_PREFIX. +**value**: An S3 bucket and a prefix (folder) to copy the output files into. + +**name**: JOB_AWS_CLI_PATH. +**value**: "/opt/aws-cli/bin". Path to add to the PATH environment variable so that the AWS CLI can be located + +To run AWS batch command to test a job use the follwing command: `aws batch submit-job --cli-input-json file://job.json` \ No newline at end of file diff --git a/src/aws-genomics-cdk/containers/build.sh b/src/aws-genomics-cdk/containers/build.sh new file mode 100755 index 000000000..2657a80c5 --- /dev/null +++ b/src/aws-genomics-cdk/containers/build.sh @@ -0,0 +1,67 @@ +#!/bin/bash +set -e + +IMAGE_NAME=$1 +DOCKER_FILE_PATH="./${IMAGE_NAME}/Dockerfile" +REGISTRY="$CDK_DEFAULT_ACCOUNT.dkr.ecr.$CDK_DEFAULT_REGION.amazonaws.com" +REPOSITORY_NAME="genomics/${IMAGE_NAME}" +IMAGE_TAG=":latest" +IMAGE_WITH_TAG="${IMAGE_NAME}${IMAGE_TAG}" +REGISTRY_PATH="${REGISTRY}/${REPOSITORY_NAME}" +REGISTRY_PATH_WITH_TAG="${REGISTRY}/genomics/${IMAGE_WITH_TAG}" + + +if [ -z "${IMAGE_NAME}" ] +then + echo "Missing image name parameter." + exit 1 +fi + +if [[ ! -f "${DOCKER_FILE_PATH}" ]] +then + echo "${DOCKER_FILE_PATH} does not exist on the filesystem." + exit 1 +fi + +if [ -z "$CDK_DEFAULT_ACCOUNT" ] +then + echo "Missing CDK_DEFAULT_ACCOUNT environment variable." + exit 1 +fi + +if [ -z "$CDK_DEFAULT_REGION" ] +then + echo "Missing CDK_DEFAULT_REGION environment variable." + exit 1 +fi + + +echo "Docker Login to ECR" +eval $(aws ecr get-login --no-include-email --region ${CDK_DEFAULT_REGION}) + + +# Check if the repository exists in ECR and if not, create it +REPO=`aws ecr describe-repositories | grep -o ${REGISTRY_PATH}` || true +if [ "${REPO}" != "${REGISTRY_PATH}" ] +then + aws ecr create-repository --repository-name ${REPOSITORY_NAME} +fi + +# build the base image +docker build \ + -t ${IMAGE_NAME} \ + -f ${DOCKER_FILE_PATH} . + +# build the image with an AWS specific entrypoint +docker build \ + --build-arg BASE_IMAGE=${IMAGE_NAME} \ + -t ${IMAGE_WITH_TAG} \ + -f ./entry.dockerfile . + + +# tag the image +docker tag ${IMAGE_WITH_TAG} ${REGISTRY_PATH} + + +# push the image to the registry +docker push ${REGISTRY_PATH_WITH_TAG} \ No newline at end of file diff --git a/src/aws-genomics-cdk/containers/entry.dockerfile b/src/aws-genomics-cdk/containers/entry.dockerfile new file mode 100644 index 000000000..12c4a1784 --- /dev/null +++ b/src/aws-genomics-cdk/containers/entry.dockerfile @@ -0,0 +1,15 @@ +ARG BASE_IMAGE +FROM ${BASE_IMAGE}:latest + +RUN apt-get update +RUN apt-get install -y gettext-base wget +RUN apt-get clean + +ENV PATH=/opt/bin:$PATH + +COPY entrypoint.sh /opt/bin/entrypoint.sh +RUN chmod +x /opt/bin/entrypoint.sh + +WORKDIR /scratch + +ENTRYPOINT ["entrypoint.sh"] \ No newline at end of file diff --git a/src/aws-genomics-cdk/containers/entrypoint.sh b/src/aws-genomics-cdk/containers/entrypoint.sh new file mode 100644 index 000000000..6fb7bc993 --- /dev/null +++ b/src/aws-genomics-cdk/containers/entrypoint.sh @@ -0,0 +1,196 @@ +#!/bin/bash +# Universal entrypoint script for containerized tooling for use with AWS Batch +# that handles data staging of predefined inputs and outputs. +# +# Environment Variables +# JOB_WORKFLOW_NAME +# Optional +# Name of the parent workflow for this job. Used with JOB_WORKFLOW_EXECUTION_ID +# to generate a unique prefix for workflow outputs. +# +# JOB_WORKFLOW_EXECUTION_ID +# Optional +# Unique identifier for the current workflow run. Used with JOB_WORKFLOW_NAME +# to generate a unique prefix for workflow outputs. +# +# JOB_AWS_CLI_PATH +# Required if staging data from S3 +# Default: /opt/miniconda/bin +# Path to add to the PATH environment variable so that the AWS CLI can be +# located. Use this if bindmounting the AWS CLI from the host and it is +# packaged in a self-contained way (e.g. not needing OS/distribution +# specific shared libraries). The AWS CLI installed with `conda` is +# sufficiently self-contained. Using a standard python virtualenv does +# not work. +# +# JOB_DATA_ISOLATION +# Optional +# Default: null +# Set to 1 if container will need to use an isolated data space - e.g. +# it will operate in a volume mounted from the host for scratch +# +# JOB_INPUTS +# Optional +# Default: null +# A space delimited list of http(s) urls or s3 object urls - e.g.: +# https://somedomain.com/path s3://{prefix1}/{key_pattern1} [s3://{prefix2}/{key_pattern2} [...]] +# for files that the job will use as inputs +# +# JOB_OUTPUTS +# Optional +# Default: null +# A space delimited list of files - e.g.: +# file1 [file2 [...]] +# that the job generates that will be retained - i.e. transferred back to S3 +# +# JOB_OUTPUT_PREFIX +# Required if JOB_OUTPUTS need to be stored on S3 +# Default: null +# S3 location (e.g. s3://bucket/prefix) were job outputs will be stored +# +# JOB_INPUT_S3_COPY_METHOD +# Optional +# Default: s3cp +# If copying files from an S3 bucket, choose the method for the copy +# s3cp: use s3 cp --no-progress --recursive --exclude "*" --include JOB_INPUT (an s3 input from the JOB_INPUTS) +# s3sync: use s3 sync JOB_INPUT . (for each s3 input from the JOB_INPUTS) +# +# JOB_OUTPUT_S3_COPY_METHOD +# Optional +# Default: s3cp +# If copying files to an S3 bucket, choose the method for the copy +# s3cp: use s3 cp --no-progress file (a file from the JOB_OUTPUTS) +# s3sync: use s3 sync LOCAL_PATH JOB_OUTPUT_PREFIX (Sync a local path to the JOB_OUTPUT_PREFIX location) + +set -e # exit on error + +if [[ $JOB_VERBOSE ]]; then + set -x # enable echo +fi + +DEFAULT_AWS_CLI_PATH=/opt/aws-cli/bin +AWS_CLI_PATH=${JOB_AWS_CLI_PATH:-$DEFAULT_AWS_CLI_PATH} +PATH=$PATH:$AWS_CLI_PATH + +# ensure that JOB_INPUT_PREFIX is fully evaluated if present +if [[ $JOB_INPUT_PREFIX ]]; then + JOB_INPUT_PREFIX=`echo $JOB_INPUT_PREFIX | envsubst` +fi + +if [[ $JOB_DATA_ISOLATION && $JOB_DATA_ISOLATION == 1 ]]; then + ## AWS Batch places multiple jobs on an instance + ## To avoid file path clobbering if using a host mounted scratch use the JobID + ## and JobAttempt to create a unique path + + if [[ $AWS_BATCH_JOB_ID ]]; then + GUID="$AWS_BATCH_JOB_ID/$AWS_BATCH_JOB_ATTEMPT" + else + GUID=`date | md5sum | cut -d " " -f 1` + fi + + mkdir -p $GUID + cd $GUID +fi + +function stage_in() ( + # loops over list of inputs (patterns allowed) which are a space delimited list + # of s3 urls: + # s3://{prefix1}/{key_pattern1} [s3://{prefix2}/{key_pattern2} [...]] + # uses the AWS CLI to download objects + + # `noglob` option is needed so that patterns are not expanded against the + # local filesystem. this setting is local to the function + set -o noglob + + for item in "$@"; do + item=`echo $item | envsubst` + if [[ $item =~ ^s3:// ]]; then + if [[ $JOB_INPUT_S3_COPY_METHOD && $JOB_INPUT_S3_COPY_METHOD == 's3sync' ]]; then + echo "[input][s3sync] remote: $item ==> ./" + + aws s3 sync $item . + else + local item_key=`basename $item` + local item_prefix=`dirname $item` + + echo "[input][s3cp] remote: $item ==> ./$item_key" + + aws s3 cp \ + --no-progress \ + --recursive \ + --exclude "*" \ + --include "${item_key}" \ + ${item_prefix} . + fi + elif [[ $item =~ ^https?:// ]]; then + echo "[input][url] $item ==> ./" + + wget $item + else + echo "[input] local: $item" + + fi + done +) + +function stage_out() ( + # loops over list of outputs which are a space delimited list of filenames: + # file1 [file2 [...]] + # uses the AWS CLI to upload objects + + for item in "$@"; do + if [[ ! -f $item && ! -d $item ]]; then + # If an expected output is not found it is generally considered an + # error. To suppress this error when using glob expansion you can + # set the `nullglob` option (`shopt -s nullglob`) + echo "[output] ERROR: $item does not exist" 1>&2 + exit 1 + else + if [[ $JOB_OUTPUT_PREFIX && $JOB_OUTPUT_PREFIX =~ ^s3:// ]]; then + local item_key=`basename $item` + local output_prefix=$JOB_OUTPUT_PREFIX + + if [[ $JOB_WORKFLOW_NAME && $JOB_WORKFLOW_EXECUTION_ID ]]; then + local output_prefix=$output_prefix/$JOB_WORKFLOW_NAME/$JOB_WORKFLOW_EXECUTION_ID + fi + + if [[ $JOB_OUTPUT_S3_COPY_METHOD && $JOB_OUTPUT_S3_COPY_METHOD == 's3sync' ]]; then + echo "[output][s3sync] remote: $item ==> $output_prefix/" + + aws s3 sync $item $output_prefix/ + else + echo "[output][s3cp] remote: ./$item ==> $output_prefix/${item_key}" + + aws s3 cp \ + --no-progress \ + ./$item $output_prefix/${item_key} + fi + + + elif [[ $JOB_OUTPUT_PREFIX && ! $JOB_OUTPUT_PREFIX =~ ^s3:// ]]; then + echo "[output] ERROR: unsupported remote output destination $JOB_OUTPUT_PREFIX" 1>&2 + + else + echo "[output] local: ./$item" + + fi + fi + done +) + +# Command is specified in the JobSubmission container overrides. +# gives the user flexibility to specify tooling options as needed. +# +# Note that AWS Batch has an implicit 8kb limit on the amount of data allowed in +# container overrides, which includes environment variable data. +COMMAND=`echo "$*" | envsubst` + +printenv +stage_in $JOB_INPUTS + +echo "[command]: $COMMAND" +bash -c "$COMMAND" + + +stage_out $JOB_OUTPUTS + diff --git a/src/aws-genomics-cdk/containers/fastqc/Dockerfile b/src/aws-genomics-cdk/containers/fastqc/Dockerfile new file mode 100644 index 000000000..7b06bfe23 --- /dev/null +++ b/src/aws-genomics-cdk/containers/fastqc/Dockerfile @@ -0,0 +1,33 @@ +# base image +FROM ubuntu:xenial + +# metadata +LABEL base.image="ubuntu:xenial" +LABEL version="1" +LABEL software="FASTQC" +LABEL software.version="0.11.8" +LABEL description="A quality control analysis tool for high throughput sequencing data" +LABEL website="https://www.bioinformatics.babraham.ac.uk/projects/fastqc/" +LABEL license="https://github.com/s-andrews/FastQC/blob/master/LICENSE.txt" +LABEL maintainer="Abigail Shockey" +LABEL maintainer.email="abigail.shockey@slh.wisc.edu" + +RUN apt-get update && apt-get install -y \ + unzip \ + wget \ + perl \ + default-jre \ + && apt-get clean && apt-get autoclean && rm -rf /var/lib/apt/lists/* + +RUN wget https://www.bioinformatics.babraham.ac.uk/projects/fastqc/fastqc_v0.11.8.zip && \ + unzip fastqc_v0.11.8.zip && \ + rm fastqc_v0.11.8.zip && \ + chmod +x FastQC/fastqc + + +ENV PATH="${PATH}:/FastQC/" + +RUN mkdir /data +WORKDIR /data + +ENTRYPOINT ["fastqc"] \ No newline at end of file diff --git a/src/aws-genomics-cdk/containers/minimap2/Dockerfile b/src/aws-genomics-cdk/containers/minimap2/Dockerfile new file mode 100644 index 000000000..6a5b25cad --- /dev/null +++ b/src/aws-genomics-cdk/containers/minimap2/Dockerfile @@ -0,0 +1,28 @@ +FROM ubuntu:18.04 AS build + +ARG VERSION=2.17 + +# metadata +LABEL base.image="ubuntu:18.04" +LABEL container.version="1" +LABEL software="Minimap2" +LABEL software.version="${VERSION}" +LABEL description="versatile sequence alignment program that aligns DNA or mRNA sequences against a large reference database" +LABEL website="https://github.com/lh3/minimap2" +LABEL license="https://github.com/lh3/minimap2/blob/master/LICENSE.txt" +LABEL maintainer="Kelsey Florek" +LABEL maintainer.email="Kelsey.florek@slh.wisc.edu" + +# install dependeny tools +RUN apt-get update && apt-get install -y python curl bzip2 && apt-get clean + +# download and extract minimap2 +WORKDIR /opt/bin +RUN curl -L https://github.com/lh3/minimap2/releases/download/v2.17/minimap2-2.17_x64-linux.tar.bz2 | tar -jxvf - + +# add minimap2 to the path +ENV PATH="${PATH}:/opt/bin/minimap2-2.17_x64-linux" + +WORKDIR /scratch + +ENTRYPOINT ["minimap2"] \ No newline at end of file diff --git a/src/aws-genomics-cdk/examples/README.md b/src/aws-genomics-cdk/examples/README.md new file mode 100644 index 000000000..44797276e --- /dev/null +++ b/src/aws-genomics-cdk/examples/README.md @@ -0,0 +1,116 @@ +# Bioinformatics tools examples + +You can test the bioinfomatics tools with AWS Batch directly or start a full Step Functions pipeline. + +**jobName** - A name for the job, this will appear in the AWS Batch Job list +**jobQueue** - The name of the queue you want to use in AWS Batch. You can get this name from the AWS Batch console > +Job queues. +**jobDefinition** - The AWS Batch job definition including a version number. You can get this name from the AWS Batch console > +Job definitions. +**containerOverrides.vcpus** - The desired amount of vcpus to run this job. +**containerOverrides.memory** - The number of MiB of memory reserved for the job. +**containerOverrides.command** - The command to be executed. +**containerOverrides.environment** - Environment variables to send to the container. Refer to the special environment +variables in the [containers readme file](../README.md). + +Change the "JOB_OUTPUT_PREFIX" parameter to an existing bucket and choose a prefix (e.g., s3://mybucketname/test). + +### FastQC +To run the command, cd to the examples directory (e.g., ``cd src/aws-genomics-cdk/examples``) and run the following +command ``aws batch submit-job --cli-input-json file://batch-fastqc-job.json`` +If the job finish successfully you should see new html and zip files in the S3 location you configured. + +``` +batch-fastqc-job.json +{ + "jobName": "fastqc", + "jobQueue": "genomics-default-job-queue", + "jobDefinition": "genomics-fastqc:1", + "containerOverrides": { + "vcpus": 2, + "memory": 4000, + "command": ["fastqc *.gz"], + "environment": [{ + "name": "JOB_INPUTS", + "value": "s3://aws-batch-genomics-shared/secondary-analysis/example-files/fastq/NIST7035_R1_trim_samp-0p1.fastq.gz s3://aws-batch-genomics-shared/secondary-analysis/example-files/fastq/NIST7035_R2_trim_samp-0p1.fastq.gz" + }, + { + "name": "JOB_OUTPUTS", + "value": "*.html *.zip" + }, + { + "name": "JOB_OUTPUT_PREFIX", + "value": "s3://[YOUR BUCKET NAME]/[SOME PREFIX]" + }, + { + "name": "JOB_AWS_CLI_PATH", + "value": "/opt/aws-cli/bin" + } + ] + } +} + +``` + + +### Minimap2 +To run the command, cd to the examples directory (e.g., ``cd src/aws-genomics-cdk/examples``) and run the following +command ``aws batch submit-job --cli-input-json file://batch-minimap2-job.json`` +If the job finish successfully you should see new sam files in the S3 location you configured. +``` +batch-minimap2-job.json +{ + "jobName": "minimap2", + "jobQueue": "genomics-default-queue", + "jobDefinition": "minimap2:1", + "containerOverrides": { + "vcpus": 8, + "memory": 16000, + "command": ["minimap2 -ax map-pb Homo_sapiens_assembly38.fasta NIST7035_R1_trim_samp-0p1.fastq.gz > NIST7035.sam"], + "environment": [{ + "name": "JOB_INPUTS", + "value": "s3://broad-references/hg38/v0/Homo_sapiens_assembly38.fasta s3://aws-batch-genomics-shared/secondary-analysis/example-files/fastq/NIST7035_R1_trim_samp-0p1.fastq.gz" + }, + { + "name": "JOB_OUTPUTS", + "value": "*.sam" + }, + { + "name": "JOB_OUTPUT_PREFIX", + "value": "s3://[YOUR BUCKET NAME]/[SOME PREFIX]" + }, + { + "name": "JOB_AWS_CLI_PATH", + "value": "/opt/aws-cli/bin" + } + ] + } +} +``` + + +### A demo pipeline that runs FasqQC and then Minimap2 + +Logon to the AWS console, navigate to Step Functions and click on the "genomics-pipelines-state-machine" state machine. +Click on the "Start execution" button and use the following json content for the input section. Change the +"JOB_OUTPUT_PREFIX" parameter to an existing bucket and choose a prefix (e.g., s3://mybucketname/test). +``` +{ + "params": { + "environment": { + "JOB_OUTPUT_PREFIX": "[YOUR BUCKET NAME]/[SOME PREFIX]" + }, + "fastqc": { + "input": "s3://aws-batch-genomics-shared/secondary-analysis/example-files/fastq/NIST7035_R1_trim_samp-0p1.fastq.gz s3://aws-batch-genomics-shared/secondary-analysis/example-files/fastq/NIST7035_R2_trim_samp-0p1.fastq.gz", + "output": "*.html *.zip" + }, + "minimap2": { + "input": "s3://broad-references/hg38/v0/Homo_sapiens_assembly38.fasta s3://aws-batch-genomics-shared/secondary-analysis/example-files/fastq/NIST7035_R1_trim_samp-0p1.fastq.gz", + "fastaFileName": "Homo_sapiens_assembly38.fasta", + "fastqFiles": "NIST7035_R1_trim_samp-0p1.fastq.gz", + "samOutput": "hg38-NIST7035.sam", + "output": "*.sam" + } + } +} +``` \ No newline at end of file diff --git a/src/aws-genomics-cdk/examples/batch-fastqc-job.json b/src/aws-genomics-cdk/examples/batch-fastqc-job.json new file mode 100644 index 000000000..19730e23f --- /dev/null +++ b/src/aws-genomics-cdk/examples/batch-fastqc-job.json @@ -0,0 +1,27 @@ +{ + "jobName": "fastqc", + "jobQueue": "genomics-default-queue", + "jobDefinition": "fastqc:1", + "containerOverrides": { + "vcpus": 2, + "memory": 4000, + "command": ["fastqc *.gz"], + "environment": [{ + "name": "JOB_INPUTS", + "value": "s3://aws-batch-genomics-shared/secondary-analysis/example-files/fastq/NIST7035_R1_trim_samp-0p1.fastq.gz s3://aws-batch-genomics-shared/secondary-analysis/example-files/fastq/NIST7035_R2_trim_samp-0p1.fastq.gz" + }, + { + "name": "JOB_OUTPUTS", + "value": "*.html *.zip" + }, + { + "name": "JOB_OUTPUT_PREFIX", + "value": "s3://[YOUR BUCKET NAME]/[SOME PREFIX]" + }, + { + "name": "JOB_AWS_CLI_PATH", + "value": "/opt/aws-cli/bin" + } + ] + } +} diff --git a/src/aws-genomics-cdk/examples/batch-minimap2-job.json b/src/aws-genomics-cdk/examples/batch-minimap2-job.json new file mode 100644 index 000000000..7b8a711fc --- /dev/null +++ b/src/aws-genomics-cdk/examples/batch-minimap2-job.json @@ -0,0 +1,27 @@ +{ + "jobName": "minimap2", + "jobQueue": "genomics-default-queue", + "jobDefinition": "minimap2:1", + "containerOverrides": { + "vcpus": 8, + "memory": 16000, + "command": ["minimap2 -ax map-pb Homo_sapiens_assembly38.fasta NIST7035_R1_trim_samp-0p1.fastq.gz > NIST7035.sam"], + "environment": [{ + "name": "JOB_INPUTS", + "value": "s3://broad-references/hg38/v0/Homo_sapiens_assembly38.fasta s3://aws-batch-genomics-shared/secondary-analysis/example-files/fastq/NIST7035_R1_trim_samp-0p1.fastq.gz" + }, + { + "name": "JOB_OUTPUTS", + "value": "*.sam" + }, + { + "name": "JOB_OUTPUT_PREFIX", + "value": "s3://[YOUR BUCKET NAME]/[SOME PREFIX]" + }, + { + "name": "JOB_AWS_CLI_PATH", + "value": "/opt/aws-cli/bin" + } + ] + } +} \ No newline at end of file diff --git a/src/aws-genomics-cdk/jest.config.js b/src/aws-genomics-cdk/jest.config.js new file mode 100644 index 000000000..772f97490 --- /dev/null +++ b/src/aws-genomics-cdk/jest.config.js @@ -0,0 +1,7 @@ +module.exports = { + roots: ['/test'], + testMatch: ['**/*.test.ts'], + transform: { + '^.+\\.tsx?$': 'ts-jest' + } +}; diff --git a/src/aws-genomics-cdk/lib/aws-genomics-cdk-stack.ts b/src/aws-genomics-cdk/lib/aws-genomics-cdk-stack.ts new file mode 100644 index 000000000..e225d5d61 --- /dev/null +++ b/src/aws-genomics-cdk/lib/aws-genomics-cdk-stack.ts @@ -0,0 +1,54 @@ +import * as cdk from "@aws-cdk/core"; +import * as ec2 from "@aws-cdk/aws-ec2"; +import * as s3 from "@aws-cdk/aws-s3"; +import * as config from "../app.config.json"; +import GenomicsVpcStack from "./vpc/vpc-stack"; +import GenomicsBatchStack from "./batch/batch-stack"; +import GenomicsStateMachineProps from "./step-functions/genomics-state-machine-stack"; + +export class AwsGenomicsCdkStack extends cdk.Stack { + constructor(scope: cdk.Construct, id: string, props: cdk.StackProps) { + super(scope, id, props); + + // Create a new VPC or use an existing one + let vpc: ec2.Vpc; + if (config.VPC.createVPC) { + vpc = new GenomicsVpcStack(this, "genomics-vpc", props).vpc; + } else { + vpc = ec2.Vpc.fromLookup(this, "genomics-vpc-lookup", { + vpcName: config.VPC.existingVPCName, + }) as ec2.Vpc + } + + // Create a new bucket if set in the config + if (!config.S3.existingBucket) { + const bucketProps = { + bucketName: config.S3.bucketName, + encryption: s3.BucketEncryption.S3_MANAGED, + removalPolicy: cdk.RemovalPolicy.RETAIN, + }; + + new s3.Bucket(this, bucketProps.bucketName, bucketProps); + } + + // Create an AWS Batch resources + const batchProps = { + stackProps: props, + vpc: vpc, + bucket: config.S3.bucketName, + }; + + const batch = new GenomicsBatchStack(this, "genomics-batch", batchProps); + + if(config.stepFunctions.launchDemoPipeline === true){ + const genomicsDemoProps = { + genomicsDefaultQueue: batch.genomicsDefaultQueue, + genomicsHighPriorityQueue: batch.genomicsHighPriorityQueue, + env: props.env as cdk.ResourceEnvironment, + taskRole: batch.taskRole + }; + + new GenomicsStateMachineProps(this, "genomics-demo-pipeline", genomicsDemoProps) + } + } +} diff --git a/src/aws-genomics-cdk/lib/batch/batch-compute-environmnet-construct.ts b/src/aws-genomics-cdk/lib/batch/batch-compute-environmnet-construct.ts new file mode 100644 index 000000000..dd37e1895 --- /dev/null +++ b/src/aws-genomics-cdk/lib/batch/batch-compute-environmnet-construct.ts @@ -0,0 +1,66 @@ +import * as cdk from "@aws-cdk/core"; +import * as batch from "@aws-cdk/aws-batch"; +import * as ec2 from "@aws-cdk/aws-ec2"; +import * as ecs from "@aws-cdk/aws-ecs"; +import * as iam from "@aws-cdk/aws-iam"; + +export class GenomicsComputeEnvironmentProps { + readonly computeResourcesType?: batch.ComputeResourceType; + readonly vpc: ec2.Vpc; + readonly allocationStrategy?: batch.AllocationStrategy; + readonly computeResourcesTags?: { [key: string]: string }; + readonly instanceProfileArn: string; + readonly fleetRole: iam.Role; + readonly serviceRole: iam.Role; + readonly instanceTypes: ec2.InstanceType[]; + readonly launchTemplateName: string; + readonly maxvCpus: number; + readonly computeEnvironmentName: string; +} + +export default class GenomicsComputeEnvironment extends cdk.Construct { + public readonly computeEnvironment: batch.ComputeEnvironment; + + constructor( + scope: cdk.Construct, + id: string, + props: GenomicsComputeEnvironmentProps + ) { + super(scope, id); + + const computeResources = { + type: props.computeResourcesType ?? batch.ComputeResourceType.SPOT, + vpc: props.vpc, + allocationStrategy: + props.allocationStrategy ?? + batch.AllocationStrategy.SPOT_CAPACITY_OPTIMIZED, + computeResourcesTags: props.computeResourcesTags ?? { + Name: "genomics-instance", + Environment: "production", + }, + image: ecs.EcsOptimizedImage.amazonLinux2(), + instanceRole: props.instanceProfileArn, + spotFleetRole: props.fleetRole, + serviceRole: props.serviceRole, + instanceTypes: props.instanceTypes, + launchTemplate: { + launchTemplateName: props.launchTemplateName, + }, + maxvCpus: props.maxvCpus, + }; + + const computeEnvironmentProps = { + computeEnvironmentName: props.computeEnvironmentName, + enabled: true, + managed: true, + serviceRole: props.serviceRole, + computeResources: computeResources, + }; + + this.computeEnvironment = new batch.ComputeEnvironment( + this, + computeEnvironmentProps.computeEnvironmentName, + computeEnvironmentProps + ); + } +} diff --git a/src/aws-genomics-cdk/lib/batch/batch-iam-stack.ts b/src/aws-genomics-cdk/lib/batch/batch-iam-stack.ts new file mode 100644 index 000000000..57bb3b8d8 --- /dev/null +++ b/src/aws-genomics-cdk/lib/batch/batch-iam-stack.ts @@ -0,0 +1,89 @@ +import * as cdk from "@aws-cdk/core"; +import * as iam from "@aws-cdk/aws-iam"; +import * as path from "path"; +import * as fs from "fs"; + +export interface GenomicsIamProps { + readonly bucketName: string; + readonly account: string; +} + +export default class GenomicsIam extends cdk.Stack { + public readonly serviceRole: iam.Role; + public readonly taskRole: iam.Role; + public readonly instanceProfileArn: string; + public readonly fleetRole: iam.Role; + + constructor(scope: cdk.Construct, id: string, props: GenomicsIamProps) { + super(scope, id); + + // Create a task role to be used by AWS batch container + const taskRoleProps = { + roleName: "genomics-ecs-task-role", + assumedBy: new iam.ServicePrincipal("ecs-tasks.amazonaws.com"), + description: "allow ecs task to assume a role for the genomics pipleine", + managedPolicies: [iam.ManagedPolicy.fromAwsManagedPolicyName("AmazonS3ReadOnlyAccess")] + }; + + this.taskRole = new iam.Role(this, taskRoleProps.roleName, taskRoleProps); + + + // Create an instance role for the EC2 host machine for AWS Batch + const instanceRoleProps = { + roleName: "genomics-batch-instance-role", + assumedBy: new iam.ServicePrincipal("ec2.amazonaws.com"), + description: "allow ec2 instance to assume a role for the genomics pipleine", + managedPolicies: [ + iam.ManagedPolicy.fromAwsManagedPolicyName("service-role/AmazonEC2ContainerServiceforEC2Role"), + iam.ManagedPolicy.fromAwsManagedPolicyName("AmazonS3ReadOnlyAccess"), + iam.ManagedPolicy.fromAwsManagedPolicyName("AmazonSSMManagedInstanceCore") + ] + }; + + const instanceRole = new iam.Role(this, instanceRoleProps.roleName, instanceRoleProps); + + + // Create a spot fleet role to be used by AWS Batch when launching spot instances + const fleetRoleProps = { + roleName: "genomics-spot-fleet-role", + assumedBy: new iam.ServicePrincipal("ec2.amazonaws.com"), + description: "allow ec2 instance to assume a role for the genomics pipleine", + managedPolicies: [iam.ManagedPolicy.fromAwsManagedPolicyName("service-role/AmazonEC2SpotFleetTaggingRole")] + }; + + this.fleetRole = new iam.Role(this, fleetRoleProps.roleName, fleetRoleProps); + + + // Create a service role for AWS Batch so it can assume other roles for the genomics pipeline + const batchServiceRoleProps = { + roleName: "genomics-batch-service-role", + assumedBy: new iam.ServicePrincipal("batch.amazonaws.com"), + description: "allow batch to assume a role for the genomics pipleine", + managedPolicies: [iam.ManagedPolicy.fromAwsManagedPolicyName("service-role/AWSBatchServiceRole")] + }; + + this.serviceRole = new iam.Role(this, batchServiceRoleProps.roleName, batchServiceRoleProps); + + + // Create a policy to allow read and writes for an S3 bucket and add it to the task and instance roles + const filePath = path.join(__dirname, "../../assets/genomics-policy-s3.json"); + const bucketPolicy = fs.readFileSync(filePath, {encoding: "utf-8"}).replace(/BUCKET_NAME/g, props.bucketName); + + const policyProps = { + policyName: "genomics-policy-s3", + document: iam.PolicyDocument.fromJson(JSON.parse(bucketPolicy)), + force: true, + roles: [this.taskRole, instanceRole] + } + const policy = new iam.Policy(this, policyProps.policyName, policyProps); + + + // Create an instance profile to be used by AWS Batch compute environment + const instanceProfileProps = { + roles: [instanceRoleProps.roleName], + instanceProfileName: "genomics-batch-instance-profile" + }; + const instanceProfile = new iam.CfnInstanceProfile(this, instanceProfileProps.instanceProfileName, instanceProfileProps); + this.instanceProfileArn = `arn:aws:iam::${props.account}:instance-profile/${instanceProfileProps.instanceProfileName}`; + } +} \ No newline at end of file diff --git a/src/aws-genomics-cdk/lib/batch/batch-stack.ts b/src/aws-genomics-cdk/lib/batch/batch-stack.ts new file mode 100644 index 000000000..b2ff6076f --- /dev/null +++ b/src/aws-genomics-cdk/lib/batch/batch-stack.ts @@ -0,0 +1,122 @@ +import * as cdk from "@aws-cdk/core"; +import * as batch from "@aws-cdk/aws-batch"; +import * as ec2 from "@aws-cdk/aws-ec2"; +import * as iam from "@aws-cdk/aws-iam"; +import GenomicsComputeEnvironment from "./batch-compute-environmnet-construct"; +import GenomicsLaunchTemplate from "./launch-template-construct"; +import GenomicsJobQueue from "./job-queue-construct"; +import GenomicsIam from "./batch-iam-stack"; +import * as config from "../../app.config.json"; + + +export interface GenomicsBatchStackProps { + readonly stackProps: cdk.StackProps; + readonly vpc: ec2.Vpc; + readonly bucket: string; +}; + +export default class GenomicsBatchStack extends cdk.Stack { + + public readonly genomicsDefaultQueue: batch.JobQueue; + public readonly genomicsHighPriorityQueue: batch.JobQueue; + public readonly taskRole: iam.Role; + + constructor(scope: cdk.Construct, id: string, props: GenomicsBatchStackProps) { + super(scope, id, props.stackProps); + + const env = props.stackProps.env as cdk.Environment; + + // Create IAM roles and policies for AWS Batch + const genomicsIamProps = { + bucketName: props.bucket, + account: env.account as string + } + + const genomicsIam = new GenomicsIam(this, "genomics-iam", genomicsIamProps); + this.taskRole = genomicsIam.taskRole; + + + + // Create a EC2 Launch Template to be used by AWS Batch + const launchTemplateProps = { + launchTemplateName: "genomics-launch-template", + volumeSize: config.batch.defaultVolumeSize + }; + + const launchTemplate = new GenomicsLaunchTemplate(this, launchTemplateProps.launchTemplateName, launchTemplateProps); + + + // Create AWS Batch SPOT and On-Demand compute environments + let envInstanceType = []; + for (let i = 0; i < config.batch.instanceTypes.length; i++) { + envInstanceType.push(new ec2.InstanceType(config.batch.instanceTypes[i])); + } + + // Create spot compute environment for the genomics pipeline using SPOT instances + const spotComputeEnvironmentProps = { + computeEnvironmentName: "genomics-spot-compute-environment", + vpc: props.vpc, + instanceTypes: envInstanceType, + maxvCpus: config.batch.spotMaxVCPUs, + instanceProfileArn: genomicsIam.instanceProfileArn, + fleetRole: genomicsIam.fleetRole, + serviceRole: genomicsIam.serviceRole, + launchTemplateName: launchTemplate.template.launchTemplateName as string, + }; + + const spotComputeEnvironment = new GenomicsComputeEnvironment(this, + spotComputeEnvironmentProps.computeEnvironmentName, + spotComputeEnvironmentProps + ); + + // Create on demand compute environment using on demand instances + const onDemandComputeEnvironmentProps = { + computeEnvironmentName: "genomics-on-demand-compute-environment", + computeResourcesType: batch.ComputeResourceType.ON_DEMAND, + allocationStrategy: batch.AllocationStrategy.BEST_FIT, + vpc: props.vpc, + instanceTypes: envInstanceType, + maxvCpus: config.batch.onDemendMaxVCPUs, + instanceProfileArn: genomicsIam.instanceProfileArn, + fleetRole: genomicsIam.fleetRole, + serviceRole: genomicsIam.serviceRole, + launchTemplateName: launchTemplate.template.launchTemplateName as string, + }; + + const onDemandComputeEnvironment = new GenomicsComputeEnvironment(this, + onDemandComputeEnvironmentProps.computeEnvironmentName, + onDemandComputeEnvironmentProps + ); + + + // Create default queue, using spot first and then on-demand instances + const defaultQueueProps = { + computeEnvironments: [ + spotComputeEnvironment.computeEnvironment, + onDemandComputeEnvironment.computeEnvironment + ], + jobQueueName: "genomics-default-queue", + priority: 100 + }; + + const defaultQueue = new GenomicsJobQueue(this, defaultQueueProps.jobQueueName, defaultQueueProps); + this.genomicsDefaultQueue = defaultQueue.jobQueue; + + + // Create high priority queue, using on-demand instances and then spot + const highPriorityQueueProps = { + computeEnvironments: [ + onDemandComputeEnvironment.computeEnvironment, + spotComputeEnvironment.computeEnvironment + + ], + jobQueueName: "genomics-high-priority-queue", + priority: 1000 + } + + const highPriorityQueue = new GenomicsJobQueue(this, highPriorityQueueProps.jobQueueName, highPriorityQueueProps); + this.genomicsHighPriorityQueue = highPriorityQueue.jobQueue; + + + } +} diff --git a/src/aws-genomics-cdk/lib/batch/job-queue-construct.ts b/src/aws-genomics-cdk/lib/batch/job-queue-construct.ts new file mode 100644 index 000000000..f4721c4aa --- /dev/null +++ b/src/aws-genomics-cdk/lib/batch/job-queue-construct.ts @@ -0,0 +1,38 @@ +import * as cdk from "@aws-cdk/core"; +import * as batch from "@aws-cdk/aws-batch"; + +export interface GenomicsJobQueueProps { + readonly computeEnvironments: batch.ComputeEnvironment[]; + readonly jobQueueName: string; + readonly priority: number; +} + +export default class GenomicsJobQueue extends cdk.Construct { + public readonly jobQueue: batch.JobQueue; + + constructor(scope: cdk.Construct, id: string, props: GenomicsJobQueueProps) { + super(scope, id); + + let environments = []; + for (let i = 0; i < props.computeEnvironments.length; i++) { + let environment = { + computeEnvironment: props.computeEnvironments[i], + order: i + 1, + }; + + environments.push(environment); + } + + let jobQueueProps = { + jobQueueName: props.jobQueueName, + priority: props.priority, + computeEnvironments: environments, + }; + + this.jobQueue = new batch.JobQueue( + this, + jobQueueProps.jobQueueName, + jobQueueProps + ); + } +} diff --git a/src/aws-genomics-cdk/lib/batch/launch-template-construct.ts b/src/aws-genomics-cdk/lib/batch/launch-template-construct.ts new file mode 100644 index 000000000..361a4fe86 --- /dev/null +++ b/src/aws-genomics-cdk/lib/batch/launch-template-construct.ts @@ -0,0 +1,60 @@ +import * as cdk from "@aws-cdk/core"; +import * as ec2 from "@aws-cdk/aws-ec2"; +import * as path from "path"; +import * as fs from "fs"; + + +export interface GenomicsLaunchTemplateProps { + readonly launchTemplateName: string; + readonly volumeSize: number; + readonly volumeType?: string; + readonly encrypted?: boolean; + readonly userData?: string; +} + +export default class GenomicsLaunchTemplate extends cdk.Construct { + public readonly template: ec2.CfnLaunchTemplate; + + constructor( + scope: cdk.Construct, + id: string, + props: GenomicsLaunchTemplateProps + ) { + super(scope, id); + + let userData; + + if (props.userData !== undefined) { + userData = props.userData; + } else { + const filePath = path.join( + __dirname, + "../../assets/launch_template_user_data.txt" + ); + userData = fs.readFileSync(filePath).toString("base64"); + } + + const launchTemplateProps = { + launchTemplateName: props.launchTemplateName, + launchTemplateData: { + blockDeviceMappings: [ + { + deviceName: "/dev/xvda", + ebs: { + encrypted: props.encrypted ?? true, + volumeSize: props.volumeSize, + volumeType: props.volumeType ?? "gp2", + }, + }, + ], + userData: userData, + }, + }; + + this.template = new ec2.CfnLaunchTemplate( + this, + props.launchTemplateName, + launchTemplateProps + ); + } +} diff --git a/src/aws-genomics-cdk/lib/step-functions/genomics-state-machine-stack.ts b/src/aws-genomics-cdk/lib/step-functions/genomics-state-machine-stack.ts new file mode 100644 index 000000000..1cd6285c0 --- /dev/null +++ b/src/aws-genomics-cdk/lib/step-functions/genomics-state-machine-stack.ts @@ -0,0 +1,104 @@ +import * as cdk from "@aws-cdk/core"; +import * as batch from "@aws-cdk/aws-batch"; +import * as sfn from "@aws-cdk/aws-stepfunctions"; +import * as iam from "@aws-cdk/aws-iam"; +import * as jobDefinitions from "./job-definitions"; +import GenomicsTask from "./genomics-task-construct"; +import GenomicsJobDefinition from "./job-definition-construct"; +import * as config from "../../app.config.json"; + +export interface GenomicsStateMachineProps { + readonly genomicsDefaultQueue: batch.JobQueue; + readonly genomicsHighPriorityQueue: batch.JobQueue; + readonly env: cdk.ResourceEnvironment; + readonly taskRole: iam.Role; +} + +export default class GenomicsStateMachine extends cdk.Stack { + constructor( + scope: cdk.Construct, + id: string, + props: GenomicsStateMachineProps + ) { + super(scope, id, { env: props.env }); + + const jobDefinitionProps = { + env: props.env, + stack: this, + jobRole: props.taskRole, + }; + + const fastQC = new jobDefinitions.FastQcJobDefinition({ + ...jobDefinitionProps, + ...config.stepFunctions.jobDefinitions.fastqc, + }); + + const minimap2 = new jobDefinitions.Minimap2JObDefinition({ + ...jobDefinitionProps, + ...config.stepFunctions.jobDefinitions.minimap2, + }); + + const step1TaskProps = { + taskName: "FASTQC", + environment: { + JOB_INPUTS: sfn.JsonPath.stringAt("$.params.fastqc.input"), + JOB_OUTPUTS: sfn.JsonPath.stringAt("$.params.fastqc.output"), + }, + command: ["fastqc *.gz"], + jobDefinition: new GenomicsJobDefinition( + this, + fastQC.jobDefinitionName, + fastQC + ).jobDefinition, + queue: config.stepFunctions.jobDefinitions.fastqc.spot === true + ? props.genomicsDefaultQueue + : props.genomicsHighPriorityQueue, + }; + + const step1Task = new GenomicsTask( + this, + step1TaskProps.taskName, + step1TaskProps + ).task; + + const step2TaskProps = { + taskName: "MINIMAP2", + environment: { + JOB_INPUTS: sfn.JsonPath.stringAt("$.params.minimap2.input"), + FASTA_INPUT: sfn.JsonPath.stringAt("$.params.minimap2.fastaFileName"), + FASTQ_INPUT: sfn.JsonPath.stringAt("$.params.minimap2.fastqFiles"), + SAM_OUTPUT: sfn.JsonPath.stringAt("$.params.minimap2.samOutput"), + JOB_OUTPUTS: sfn.JsonPath.stringAt("$.params.minimap2.output"), + }, + command: ["minimap2 -ax map-pb $FASTA_INPUT $FASTQ_INPUT > $SAM_OUTPUT"], + jobDefinition: new GenomicsJobDefinition( + this, + minimap2.jobDefinitionName, + minimap2 + ).jobDefinition, + queue: config.stepFunctions.jobDefinitions.minimap2.spot === true + ? props.genomicsDefaultQueue + : props.genomicsHighPriorityQueue, + }; + + const step2Task = new GenomicsTask( + this, + step2TaskProps.taskName, + step2TaskProps + ).task; + + const definition = step1Task.next(step2Task); + + const stateMachineProps = { + definition, + stateMachineName: "genomics-pipelines-state-machine", + timeout: cdk.Duration.hours(1), + }; + + new sfn.StateMachine( + this, + stateMachineProps.stateMachineName, + stateMachineProps + ); + } +} diff --git a/src/aws-genomics-cdk/lib/step-functions/genomics-task-construct.ts b/src/aws-genomics-cdk/lib/step-functions/genomics-task-construct.ts new file mode 100644 index 000000000..086de8f67 --- /dev/null +++ b/src/aws-genomics-cdk/lib/step-functions/genomics-task-construct.ts @@ -0,0 +1,52 @@ +import * as cdk from "@aws-cdk/core"; +import * as batch from "@aws-cdk/aws-batch"; +import * as sfn from "@aws-cdk/aws-stepfunctions"; +import * as tasks from "@aws-cdk/aws-stepfunctions-tasks"; + +export interface GenomicsTaskProps { + readonly taskName: string; + readonly command: string[]; + readonly jobDefinition: batch.JobDefinition; + readonly queue: batch.JobQueue; + readonly awsCliPath?: string; + readonly environment?: { [key: string]: string }; +} + +export default class GenomicsTask extends cdk.Construct { + + public readonly task: tasks.BatchSubmitJob; + + constructor(scope: cdk.Construct, id: string, props: GenomicsTaskProps) { + super(scope, id); + + const defaultEnvironment = { + JOB_WORKFLOW_NAME: sfn.JsonPath.stringAt("$$.StateMachine.Name"), + JOB_WORKFLOW_EXECUTION: sfn.JsonPath.stringAt("$$.Execution.Name"), + JOB_OUTPUT_PREFIX: sfn.JsonPath.stringAt("$.params.environment.JOB_OUTPUT_PREFIX"), + JOB_AWS_CLI_PATH: props.awsCliPath ?? "/opt/aws-cli/bin" + } + + let environment; + if(props.environment){ + environment = {...defaultEnvironment, ...props.environment}; + } + else{ + environment = defaultEnvironment; + } + + const taskContainerProps = { + command: props.command, + environment: environment + }; + const taskProps = { + jobName: props.taskName, + jobDefinition: props.jobDefinition, + jobQueue: props.queue, + containerOverrides: taskContainerProps, + inputPath: "$", + resultPath: "$.result" + }; + + this.task = new tasks.BatchSubmitJob(this, taskProps.jobName, taskProps); + } +} \ No newline at end of file diff --git a/src/aws-genomics-cdk/lib/step-functions/job-definition-construct.ts b/src/aws-genomics-cdk/lib/step-functions/job-definition-construct.ts new file mode 100644 index 000000000..93e4fdfcb --- /dev/null +++ b/src/aws-genomics-cdk/lib/step-functions/job-definition-construct.ts @@ -0,0 +1,59 @@ +import * as cdk from "@aws-cdk/core"; +import * as batch from "@aws-cdk/aws-batch"; +import * as ecs from "@aws-cdk/aws-ecs"; + +import {GenomicsJobDefinitionProps} from "./job-definitions"; + +export default class GenomicsJobDefinition extends cdk.Construct{ + + public readonly jobDefinition: batch.JobDefinition; + + constructor(scope: cdk.Construct, id: string, props: GenomicsJobDefinitionProps) { + super(scope, id); + + const repositoryUri = `${props.env.account}.dkr.ecr.${props.env.region}.amazonaws.com/${props.repository}`; + const containerImage = ecs.ContainerImage.fromRegistry(repositoryUri); + + const mountPoints = [ + { + containerPath: "/opt/aws-cli", + readOnly: false, + sourceVolume: "awscli" + }, + { + containerPath: "/data", + readOnly: false, + sourceVolume: "data" + } + ]; + + const volumes = [ + { + name: "awscli", + host: { sourcePath: "/opt/aws-cli" } + }, + { + name: "data", + host: { sourcePath: "/data" } + } + ]; + + const jobDefinitionContainerProps = { + image: containerImage, + jobRole: props.jobRole, + memoryLimitMiB: props.memoryLimit, + mountPoints: mountPoints, + volumes: volumes, + vcpus: props.vcpus ?? 1 + }; + + const jobDefinitionProps = { + container: jobDefinitionContainerProps, + jobDefinitionName: props.jobDefinitionName as string, + retryAttempts: props.retryAttempts ?? 1, + timeout: cdk.Duration.seconds(props.timeout ?? 3600) + }; + + this.jobDefinition = new batch.JobDefinition(this, jobDefinitionProps.jobDefinitionName, jobDefinitionProps); + } +} \ No newline at end of file diff --git a/src/aws-genomics-cdk/lib/step-functions/job-definitions.ts b/src/aws-genomics-cdk/lib/step-functions/job-definitions.ts new file mode 100644 index 000000000..703c56bb4 --- /dev/null +++ b/src/aws-genomics-cdk/lib/step-functions/job-definitions.ts @@ -0,0 +1,68 @@ +import * as cdk from "@aws-cdk/core"; +import * as iam from "@aws-cdk/aws-iam"; + +export enum GenomicsJobDefinitionTypes { + FASTQC = "fastqc", + MINIMAP2 = "minimap2" +} + +export interface GenomicsJobDefinitionProps { + readonly repository: string; + readonly jobDefinitionName?: string; + readonly retryAttempts?: number; + readonly timeout?: number; + readonly env: cdk.ResourceEnvironment; + readonly stack: cdk.Stack; + readonly jobRole: iam.Role; + readonly memoryLimit?: number; + readonly vcpus?: number; +} + +class JobDefinitionBase implements GenomicsJobDefinitionProps { + public repository: string; + public jobDefinitionName: string; + public retryAttempts?: number; + public timeout?: number; + public env: cdk.ResourceEnvironment; + public stack: cdk.Stack; + public jobRole: iam.Role; + public memoryLimit?: number; + public vcpus?: number; + + constructor() { + this.retryAttempts = 1; + this.timeout = 3600; + this.memoryLimit = 16000; + this.vcpus = 8; + } +} + +export class FastQcJobDefinition extends JobDefinitionBase { + constructor(props: GenomicsJobDefinitionProps) { + super(); + this.repository = props.repository; + this.jobDefinitionName = GenomicsJobDefinitionTypes.FASTQC; + this.retryAttempts = props.retryAttempts ?? this.retryAttempts; + this.timeout = props.timeout ?? this.timeout; + this.env = props.env; + this.stack = props.stack; + this.jobRole = props.jobRole; + this.memoryLimit = props.memoryLimit ?? this.memoryLimit; + this.vcpus = props.vcpus ?? this.vcpus; + } +} + +export class Minimap2JObDefinition extends JobDefinitionBase { + constructor(props: GenomicsJobDefinitionProps) { + super(); + this.repository = props.repository; + this.jobDefinitionName = GenomicsJobDefinitionTypes.MINIMAP2; + this.retryAttempts = props.retryAttempts ?? this.retryAttempts; + this.timeout = props.timeout ?? this.timeout; + this.env = props.env; + this.stack = props.stack; + this.jobRole = props.jobRole; + this.memoryLimit = props.memoryLimit ?? this.memoryLimit; + this.vcpus = props.vcpus ?? this.vcpus; + } +} \ No newline at end of file diff --git a/src/aws-genomics-cdk/lib/vpc/vpc-stack.ts b/src/aws-genomics-cdk/lib/vpc/vpc-stack.ts new file mode 100644 index 000000000..e72678f9c --- /dev/null +++ b/src/aws-genomics-cdk/lib/vpc/vpc-stack.ts @@ -0,0 +1,32 @@ +import * as cdk from "@aws-cdk/core"; +import * as ec2 from "@aws-cdk/aws-ec2"; +import * as config from "../../app.config.json"; + +export default class GenomicsVpcStack extends cdk.Stack { + public readonly vpc: ec2.Vpc; + + constructor(scope: cdk.Construct, id: string, props: cdk.StackProps) { + super(scope, id, props); + + const subnetConf = [ + { + cidrMask: config.VPC.cidrMask, + name: "private", + subnetType: ec2.SubnetType.PRIVATE, + }, + { + cidrMask: config.VPC.cidrMask, + name: "public", + subnetType: ec2.SubnetType.PUBLIC, + } + ]; + + const vpcProp = { + cidr: config.VPC.cidr, + max_azs: config.VPC.maxAZs, + subnetConfiguration: subnetConf + }; + + this.vpc = new ec2.Vpc(this, "genomics-vpc", vpcProp); + } +} diff --git a/src/aws-genomics-cdk/package-lock.json b/src/aws-genomics-cdk/package-lock.json new file mode 100644 index 000000000..8a31410ac --- /dev/null +++ b/src/aws-genomics-cdk/package-lock.json @@ -0,0 +1,7594 @@ +{ + "name": "aws-genomics-cdk", + "version": "0.1.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@aws-cdk/assert": { + "version": "1.93.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/assert/-/assert-1.93.0.tgz", + "integrity": "sha512-yiQPc+gNjUSGg0VgTK55uzyP4QZdYhGZVhIxF2Imlr3FhTb8uYybYSzx+yhrYhxPnUmnP3BN/0rJexn4gR6iow==", + "dev": true, + "requires": { + "@aws-cdk/cloud-assembly-schema": "1.93.0", + "@aws-cdk/cloudformation-diff": "1.93.0", + "@aws-cdk/core": "1.93.0", + "@aws-cdk/cx-api": "1.93.0", + "constructs": "^3.2.0" + } + }, + "@aws-cdk/assets": { + "version": "1.93.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/assets/-/assets-1.93.0.tgz", + "integrity": "sha512-fUt6OqjkH0kJ9cpJftJl7W6FMGYlIVuK8jL8/72ouQL8CBEnasjsDRp9DWxT7cH1RWkieYrd3JKWLqVg3FDc+g==", + "requires": { + "@aws-cdk/core": "1.93.0", + "@aws-cdk/cx-api": "1.93.0", + "constructs": "^3.2.0" + } + }, + "@aws-cdk/aws-apigateway": { + "version": "1.93.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-apigateway/-/aws-apigateway-1.93.0.tgz", + "integrity": "sha512-korbRqW3H8LKEGaPDLPo4FrtENVLE0WsYzkhP7JB6SCrHCZWJM4RuCOax88n/rvz6Hw0LSrIPEynzueV11XOcA==", + "requires": { + "@aws-cdk/aws-certificatemanager": "1.93.0", + "@aws-cdk/aws-cloudwatch": "1.93.0", + "@aws-cdk/aws-cognito": "1.93.0", + "@aws-cdk/aws-ec2": "1.93.0", + "@aws-cdk/aws-elasticloadbalancingv2": "1.93.0", + "@aws-cdk/aws-iam": "1.93.0", + "@aws-cdk/aws-lambda": "1.93.0", + "@aws-cdk/aws-logs": "1.93.0", + "@aws-cdk/aws-s3": "1.93.0", + "@aws-cdk/aws-s3-assets": "1.93.0", + "@aws-cdk/core": "1.93.0", + "@aws-cdk/cx-api": "1.93.0", + "constructs": "^3.2.0" + } + }, + "@aws-cdk/aws-apigatewayv2": { + "version": "1.93.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-apigatewayv2/-/aws-apigatewayv2-1.93.0.tgz", + "integrity": "sha512-OFKnlwsPcrHhItclW94SwrHJxxHU4hJzMHjqlGqPm1XI6oBx0q/dXWdo+I+uq+fMMDYGzbc8zvxz5H+v+6A/2w==", + "requires": { + "@aws-cdk/aws-certificatemanager": "1.93.0", + "@aws-cdk/aws-cloudwatch": "1.93.0", + "@aws-cdk/aws-ec2": "1.93.0", + "@aws-cdk/aws-iam": "1.93.0", + "@aws-cdk/core": "1.93.0", + "constructs": "^3.2.0" + } + }, + "@aws-cdk/aws-apigatewayv2-integrations": { + "version": "1.93.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-apigatewayv2-integrations/-/aws-apigatewayv2-integrations-1.93.0.tgz", + "integrity": "sha512-R7HB7+t0PKjrk/zLNwKJzabJd7eVqz32F3xRIn4hvt6RCqJNADYJuqjTvqR84Vvj97QmsgbjYUv2lNvetBl6Nw==", + "requires": { + "@aws-cdk/aws-apigatewayv2": "1.93.0", + "@aws-cdk/aws-ec2": "1.93.0", + "@aws-cdk/aws-elasticloadbalancingv2": "1.93.0", + "@aws-cdk/aws-iam": "1.93.0", + "@aws-cdk/aws-lambda": "1.93.0", + "@aws-cdk/aws-servicediscovery": "1.93.0", + "@aws-cdk/core": "1.93.0", + "constructs": "^3.2.0" + } + }, + "@aws-cdk/aws-applicationautoscaling": { + "version": "1.93.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-applicationautoscaling/-/aws-applicationautoscaling-1.93.0.tgz", + "integrity": "sha512-mPXCunz/3QwOthrw+VRZ5EGRV+W8S3LuKxWMjCp/Ij6q8DXY74TFRmznOiEE3e6rW3/Pl3BZdLu3V4Ctl6oGOg==", + "requires": { + "@aws-cdk/aws-autoscaling-common": "1.93.0", + "@aws-cdk/aws-cloudwatch": "1.93.0", + "@aws-cdk/aws-iam": "1.93.0", + "@aws-cdk/core": "1.93.0", + "constructs": "^3.2.0" + } + }, + "@aws-cdk/aws-autoscaling": { + "version": "1.93.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-autoscaling/-/aws-autoscaling-1.93.0.tgz", + "integrity": "sha512-AZ7J1ZDxZe9HX00PhY/yRBUXPjJTots1+Xi9eTmXf8oetxJpPIpy3/23XMcGbO+QvWlWMbTKvNljM4C4ZLEhqg==", + "requires": { + "@aws-cdk/aws-autoscaling-common": "1.93.0", + "@aws-cdk/aws-cloudwatch": "1.93.0", + "@aws-cdk/aws-ec2": "1.93.0", + "@aws-cdk/aws-elasticloadbalancing": "1.93.0", + "@aws-cdk/aws-elasticloadbalancingv2": "1.93.0", + "@aws-cdk/aws-iam": "1.93.0", + "@aws-cdk/aws-sns": "1.93.0", + "@aws-cdk/core": "1.93.0", + "constructs": "^3.2.0" + } + }, + "@aws-cdk/aws-autoscaling-common": { + "version": "1.93.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-autoscaling-common/-/aws-autoscaling-common-1.93.0.tgz", + "integrity": "sha512-bfWYi0Zlzqg6ZfRyDU3HLxAjbB69v3nf1bO++27jrrPPE/j79fx7f9SYmtbbJnwPaUiBeeLm23I8PERyBLOmNQ==", + "requires": { + "@aws-cdk/aws-iam": "1.93.0", + "@aws-cdk/core": "1.93.0", + "constructs": "^3.2.0" + } + }, + "@aws-cdk/aws-autoscaling-hooktargets": { + "version": "1.93.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-autoscaling-hooktargets/-/aws-autoscaling-hooktargets-1.93.0.tgz", + "integrity": "sha512-YKWLZYr527rb+WA7rRxeLhxDB9D5I3Og0rRVmsu/tgPm60/MNcsVU5ps1MlNCWMxfZHQ19zXwgbIK0aQdzMvQg==", + "requires": { + "@aws-cdk/aws-autoscaling": "1.93.0", + "@aws-cdk/aws-iam": "1.93.0", + "@aws-cdk/aws-kms": "1.93.0", + "@aws-cdk/aws-lambda": "1.93.0", + "@aws-cdk/aws-sns": "1.93.0", + "@aws-cdk/aws-sns-subscriptions": "1.93.0", + "@aws-cdk/aws-sqs": "1.93.0", + "@aws-cdk/core": "1.93.0", + "constructs": "^3.2.0" + } + }, + "@aws-cdk/aws-batch": { + "version": "1.93.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-batch/-/aws-batch-1.93.0.tgz", + "integrity": "sha512-62iBagaWuFs8WyU0KIAJrfHb9aHTy3lEj+NczFGfsn+Bq2CWBOCheLGiHxI7smlYamw/O5Ru9NgCXoKbEQhVuQ==", + "requires": { + "@aws-cdk/aws-ec2": "1.93.0", + "@aws-cdk/aws-ecr": "1.93.0", + "@aws-cdk/aws-ecs": "1.93.0", + "@aws-cdk/aws-iam": "1.93.0", + "@aws-cdk/aws-secretsmanager": "1.93.0", + "@aws-cdk/aws-ssm": "1.93.0", + "@aws-cdk/core": "1.93.0", + "constructs": "^3.2.0" + } + }, + "@aws-cdk/aws-certificatemanager": { + "version": "1.93.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-certificatemanager/-/aws-certificatemanager-1.93.0.tgz", + "integrity": "sha512-m0B0FS099i4JxlYl5m3pQeVzs+kzX5r7ecoKOcJ0F3AE1IUndb6ODf3E/CPEP9A3IfOvCdF3yVv+TF3YQGVGLg==", + "requires": { + "@aws-cdk/aws-iam": "1.93.0", + "@aws-cdk/aws-lambda": "1.93.0", + "@aws-cdk/aws-route53": "1.93.0", + "@aws-cdk/core": "1.93.0", + "constructs": "^3.2.0" + } + }, + "@aws-cdk/aws-cloudformation": { + "version": "1.93.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-cloudformation/-/aws-cloudformation-1.93.0.tgz", + "integrity": "sha512-+2rw0atlRFErwuEqfO0b+rRKoVn4oo6mPbfBULKFabDYcu56oTobaKFJ2jBNtJyXojIws2qdghSp/qg4pp0rBA==", + "requires": { + "@aws-cdk/aws-iam": "1.93.0", + "@aws-cdk/aws-lambda": "1.93.0", + "@aws-cdk/aws-s3": "1.93.0", + "@aws-cdk/aws-sns": "1.93.0", + "@aws-cdk/core": "1.93.0", + "@aws-cdk/cx-api": "1.93.0", + "constructs": "^3.2.0" + } + }, + "@aws-cdk/aws-cloudfront": { + "version": "1.93.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-cloudfront/-/aws-cloudfront-1.93.0.tgz", + "integrity": "sha512-mthRLS5zs45Uwixiab4/EGqAkAmoup3A/JZ4VmXbjHM2zYvKb0a0gU/hQKwoX+kCpTjCpNcRJhoSZ6/ROLhjrg==", + "requires": { + "@aws-cdk/aws-certificatemanager": "1.93.0", + "@aws-cdk/aws-cloudwatch": "1.93.0", + "@aws-cdk/aws-ec2": "1.93.0", + "@aws-cdk/aws-iam": "1.93.0", + "@aws-cdk/aws-kms": "1.93.0", + "@aws-cdk/aws-lambda": "1.93.0", + "@aws-cdk/aws-s3": "1.93.0", + "@aws-cdk/aws-ssm": "1.93.0", + "@aws-cdk/core": "1.93.0", + "constructs": "^3.2.0" + } + }, + "@aws-cdk/aws-cloudwatch": { + "version": "1.93.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-cloudwatch/-/aws-cloudwatch-1.93.0.tgz", + "integrity": "sha512-oN0RZO1bvxopJTTGX18hZNnatnrXqFjv0CxLnjAToYkuCx5GSuVpigJeK0YrzDqVWC80eVnuqHSJ9ORvLTJ0/g==", + "requires": { + "@aws-cdk/aws-iam": "1.93.0", + "@aws-cdk/core": "1.93.0", + "constructs": "^3.2.0" + } + }, + "@aws-cdk/aws-codebuild": { + "version": "1.93.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-codebuild/-/aws-codebuild-1.93.0.tgz", + "integrity": "sha512-xkvvL5kw7SOSwgThELxj/r5R8gLFdIFz9iQe8PXvextlCxmGWBFIzTWJofmx/MLIm7eqQF/55iT3vKJ3S0Byow==", + "requires": { + "@aws-cdk/aws-cloudwatch": "1.93.0", + "@aws-cdk/aws-codecommit": "1.93.0", + "@aws-cdk/aws-ec2": "1.93.0", + "@aws-cdk/aws-ecr": "1.93.0", + "@aws-cdk/aws-ecr-assets": "1.93.0", + "@aws-cdk/aws-events": "1.93.0", + "@aws-cdk/aws-iam": "1.93.0", + "@aws-cdk/aws-kms": "1.93.0", + "@aws-cdk/aws-logs": "1.93.0", + "@aws-cdk/aws-s3": "1.93.0", + "@aws-cdk/aws-s3-assets": "1.93.0", + "@aws-cdk/aws-secretsmanager": "1.93.0", + "@aws-cdk/core": "1.93.0", + "@aws-cdk/region-info": "1.93.0", + "constructs": "^3.2.0" + } + }, + "@aws-cdk/aws-codecommit": { + "version": "1.93.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-codecommit/-/aws-codecommit-1.93.0.tgz", + "integrity": "sha512-+IHEUI7CkNseTzMCR6PFuIJf++FMuKUpPkaUSxoBmyUy6Mwtw6GDWQvvrN4d4RV45a4YWOdwD3WaKwEWvjqJ1w==", + "requires": { + "@aws-cdk/aws-events": "1.93.0", + "@aws-cdk/aws-iam": "1.93.0", + "@aws-cdk/core": "1.93.0", + "constructs": "^3.2.0" + } + }, + "@aws-cdk/aws-codeguruprofiler": { + "version": "1.93.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-codeguruprofiler/-/aws-codeguruprofiler-1.93.0.tgz", + "integrity": "sha512-ft+npsdzlokkh1mEjkAT21la4EeD33p7lv19ItfcYwgWsYR+LnzgxWRcUaa4dkKaAYlqZRy221YlkRvArngzxg==", + "requires": { + "@aws-cdk/aws-iam": "1.93.0", + "@aws-cdk/core": "1.93.0", + "constructs": "^3.2.0" + } + }, + "@aws-cdk/aws-cognito": { + "version": "1.93.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-cognito/-/aws-cognito-1.93.0.tgz", + "integrity": "sha512-+07WMXa0kiaFeApaDM76+4XXFt7y71sIGy5QiTRrDKsRlSt9ja5XyAX9J2hSku06NaYRfSWY88e2TX/19R6yWA==", + "requires": { + "@aws-cdk/aws-certificatemanager": "1.93.0", + "@aws-cdk/aws-iam": "1.93.0", + "@aws-cdk/aws-lambda": "1.93.0", + "@aws-cdk/core": "1.93.0", + "@aws-cdk/custom-resources": "1.93.0", + "constructs": "^3.2.0", + "punycode": "^2.1.1" + }, + "dependencies": { + "punycode": { + "version": "2.1.1", + "bundled": true + } + } + }, + "@aws-cdk/aws-databrew": { + "version": "1.93.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-databrew/-/aws-databrew-1.93.0.tgz", + "integrity": "sha512-scLTMm3F8mx1RjMB0Mo/fCyGP+WH1WHKXj6ot5fkBhSv3Xn+1zGtPme2V64HbiwntNyQ3GB369VFcxypfqncEA==", + "requires": { + "@aws-cdk/core": "1.93.0" + } + }, + "@aws-cdk/aws-dynamodb": { + "version": "1.93.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-dynamodb/-/aws-dynamodb-1.93.0.tgz", + "integrity": "sha512-y9fzUfvwBVhxdcCkj/Gr0QWsUwkf3TIxvxwgY3VsfM3C7HzIjz4P6D+BbA1kOui0zyPhMJkcnfkdG5PObI3F6g==", + "requires": { + "@aws-cdk/aws-applicationautoscaling": "1.93.0", + "@aws-cdk/aws-cloudwatch": "1.93.0", + "@aws-cdk/aws-iam": "1.93.0", + "@aws-cdk/aws-kms": "1.93.0", + "@aws-cdk/aws-lambda": "1.93.0", + "@aws-cdk/core": "1.93.0", + "@aws-cdk/custom-resources": "1.93.0", + "constructs": "^3.2.0" + } + }, + "@aws-cdk/aws-ec2": { + "version": "1.93.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-ec2/-/aws-ec2-1.93.0.tgz", + "integrity": "sha512-LWNY3SrCR+t8DTXbf5Qszw8GJcMOZzub/bQNmlgxYyXoxrW7tiVniDKRXR8tn3CCgUV/S1YH7h60QKYd8Vg9XQ==", + "requires": { + "@aws-cdk/aws-cloudwatch": "1.93.0", + "@aws-cdk/aws-iam": "1.93.0", + "@aws-cdk/aws-kms": "1.93.0", + "@aws-cdk/aws-logs": "1.93.0", + "@aws-cdk/aws-s3": "1.93.0", + "@aws-cdk/aws-s3-assets": "1.93.0", + "@aws-cdk/aws-ssm": "1.93.0", + "@aws-cdk/cloud-assembly-schema": "1.93.0", + "@aws-cdk/core": "1.93.0", + "@aws-cdk/cx-api": "1.93.0", + "@aws-cdk/region-info": "1.93.0", + "constructs": "^3.2.0" + } + }, + "@aws-cdk/aws-ecr": { + "version": "1.93.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-ecr/-/aws-ecr-1.93.0.tgz", + "integrity": "sha512-pU9IDvO2vxE5kb3FU4ejFvy0Ei85u0j3TgYI4Fj8ZCDZj8CJ25r33t87//tWbhLJjudj4engFnJXzmxlPxx91g==", + "requires": { + "@aws-cdk/aws-events": "1.93.0", + "@aws-cdk/aws-iam": "1.93.0", + "@aws-cdk/core": "1.93.0", + "constructs": "^3.2.0" + } + }, + "@aws-cdk/aws-ecr-assets": { + "version": "1.93.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-ecr-assets/-/aws-ecr-assets-1.93.0.tgz", + "integrity": "sha512-c0GSmUduhKk4pAzzbRZqhA1GjpDVxxm9tdNBKmW1MUAOSv+xDpNeBjH636hduREUNnhuepKlWn+BGcOMcqWiHA==", + "requires": { + "@aws-cdk/assets": "1.93.0", + "@aws-cdk/aws-ecr": "1.93.0", + "@aws-cdk/aws-iam": "1.93.0", + "@aws-cdk/aws-s3": "1.93.0", + "@aws-cdk/core": "1.93.0", + "@aws-cdk/cx-api": "1.93.0", + "constructs": "^3.2.0", + "minimatch": "^3.0.4" + }, + "dependencies": { + "balanced-match": { + "version": "1.0.0", + "bundled": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "concat-map": { + "version": "0.0.1", + "bundled": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "requires": { + "brace-expansion": "^1.1.7" + } + } + } + }, + "@aws-cdk/aws-ecs": { + "version": "1.93.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-ecs/-/aws-ecs-1.93.0.tgz", + "integrity": "sha512-LEbP7vJu5K7i1hCBxBiRJbwHTe3AkOjYgwX2PSJ67bb4FJRC1D+lmVD9Sir9ZCT0QVSlrmvC1q4e5e6FUP+lTw==", + "requires": { + "@aws-cdk/aws-applicationautoscaling": "1.93.0", + "@aws-cdk/aws-autoscaling": "1.93.0", + "@aws-cdk/aws-autoscaling-hooktargets": "1.93.0", + "@aws-cdk/aws-certificatemanager": "1.93.0", + "@aws-cdk/aws-cloudwatch": "1.93.0", + "@aws-cdk/aws-ec2": "1.93.0", + "@aws-cdk/aws-ecr": "1.93.0", + "@aws-cdk/aws-ecr-assets": "1.93.0", + "@aws-cdk/aws-elasticloadbalancing": "1.93.0", + "@aws-cdk/aws-elasticloadbalancingv2": "1.93.0", + "@aws-cdk/aws-iam": "1.93.0", + "@aws-cdk/aws-kms": "1.93.0", + "@aws-cdk/aws-lambda": "1.93.0", + "@aws-cdk/aws-logs": "1.93.0", + "@aws-cdk/aws-route53": "1.93.0", + "@aws-cdk/aws-route53-targets": "1.93.0", + "@aws-cdk/aws-s3": "1.93.0", + "@aws-cdk/aws-s3-assets": "1.93.0", + "@aws-cdk/aws-secretsmanager": "1.93.0", + "@aws-cdk/aws-servicediscovery": "1.93.0", + "@aws-cdk/aws-sns": "1.93.0", + "@aws-cdk/aws-sqs": "1.93.0", + "@aws-cdk/aws-ssm": "1.93.0", + "@aws-cdk/core": "1.93.0", + "@aws-cdk/cx-api": "1.93.0", + "constructs": "^3.2.0" + } + }, + "@aws-cdk/aws-efs": { + "version": "1.93.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-efs/-/aws-efs-1.93.0.tgz", + "integrity": "sha512-PdifxqrNGJT4jOceredsFLh3Z0R3IDw6Exg2xMVYcGZ81vUuEiP/U8lljTXlFHrYOg/TR1vMoyrFp8CGdgBHiQ==", + "requires": { + "@aws-cdk/aws-ec2": "1.93.0", + "@aws-cdk/aws-kms": "1.93.0", + "@aws-cdk/cloud-assembly-schema": "1.93.0", + "@aws-cdk/core": "1.93.0", + "@aws-cdk/cx-api": "1.93.0", + "constructs": "^3.2.0" + } + }, + "@aws-cdk/aws-eks": { + "version": "1.93.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-eks/-/aws-eks-1.93.0.tgz", + "integrity": "sha512-FXXtyQPksjn8klwLDKa4D9hqe/k+JglzpNiJNE7P3OCeGHFyJlKoZwVyxG7jg4rRS2ErJjfkiNRofrtelRMOdQ==", + "requires": { + "@aws-cdk/aws-autoscaling": "1.93.0", + "@aws-cdk/aws-ec2": "1.93.0", + "@aws-cdk/aws-iam": "1.93.0", + "@aws-cdk/aws-kms": "1.93.0", + "@aws-cdk/aws-lambda": "1.93.0", + "@aws-cdk/aws-ssm": "1.93.0", + "@aws-cdk/core": "1.93.0", + "@aws-cdk/custom-resources": "1.93.0", + "@aws-cdk/lambda-layer-awscli": "1.93.0", + "@aws-cdk/lambda-layer-kubectl": "1.93.0", + "constructs": "^3.2.0", + "yaml": "1.10.0" + }, + "dependencies": { + "yaml": { + "version": "1.10.0", + "bundled": true + } + } + }, + "@aws-cdk/aws-elasticloadbalancing": { + "version": "1.93.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-elasticloadbalancing/-/aws-elasticloadbalancing-1.93.0.tgz", + "integrity": "sha512-2nnEj7Pu5c3nKYIJDK6tFCS9bVDmhPbyShR3qbCLeImrV9G/pv+AwcQmlsGglaEw77IrTiy3scFxUwtILGRH8A==", + "requires": { + "@aws-cdk/aws-ec2": "1.93.0", + "@aws-cdk/core": "1.93.0", + "constructs": "^3.2.0" + } + }, + "@aws-cdk/aws-elasticloadbalancingv2": { + "version": "1.93.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-elasticloadbalancingv2/-/aws-elasticloadbalancingv2-1.93.0.tgz", + "integrity": "sha512-/vfqx+CNXfY721iu6BsF528dN3BUWkMTjAWnZ+wuB0IpEUK2Cd0uU5MpqiJUfjgG/a4x9CcbJgJfmR0on2o4ag==", + "requires": { + "@aws-cdk/aws-certificatemanager": "1.93.0", + "@aws-cdk/aws-cloudwatch": "1.93.0", + "@aws-cdk/aws-ec2": "1.93.0", + "@aws-cdk/aws-iam": "1.93.0", + "@aws-cdk/aws-lambda": "1.93.0", + "@aws-cdk/aws-s3": "1.93.0", + "@aws-cdk/cloud-assembly-schema": "1.93.0", + "@aws-cdk/core": "1.93.0", + "@aws-cdk/cx-api": "1.93.0", + "@aws-cdk/region-info": "1.93.0", + "constructs": "^3.2.0" + } + }, + "@aws-cdk/aws-events": { + "version": "1.93.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-events/-/aws-events-1.93.0.tgz", + "integrity": "sha512-bMniBA36M6PzqF2HXdpsMEcpVe6GhqUG05v3tqrBkoOqOjS6KG7h884n60Ru/DTTVBX78XKFcr8mUt7gJcjVEQ==", + "requires": { + "@aws-cdk/aws-iam": "1.93.0", + "@aws-cdk/core": "1.93.0", + "constructs": "^3.2.0" + } + }, + "@aws-cdk/aws-globalaccelerator": { + "version": "1.93.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-globalaccelerator/-/aws-globalaccelerator-1.93.0.tgz", + "integrity": "sha512-teBGtCqiYGJ19D7WTJz61r8lvh8bXVQghJ/7VYsZB3z2itr0242VKtbT5pkUlWPcGP9LZCXzk57gKDpn7Tt0dA==", + "requires": { + "@aws-cdk/aws-ec2": "1.93.0", + "@aws-cdk/core": "1.93.0", + "@aws-cdk/custom-resources": "1.93.0", + "constructs": "^3.2.0" + } + }, + "@aws-cdk/aws-glue": { + "version": "1.93.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-glue/-/aws-glue-1.93.0.tgz", + "integrity": "sha512-IizynY+E63nIBpyHBgJCLpgDrW3J1gvkyo/5psPSuAXRr1+pMvrNsArTU3BApvIJTmZV3zAV7xeu6+5JGdwyxQ==", + "requires": { + "@aws-cdk/aws-ec2": "1.93.0", + "@aws-cdk/aws-iam": "1.93.0", + "@aws-cdk/aws-kms": "1.93.0", + "@aws-cdk/aws-s3": "1.93.0", + "@aws-cdk/core": "1.93.0", + "constructs": "^3.2.0" + } + }, + "@aws-cdk/aws-iam": { + "version": "1.93.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-iam/-/aws-iam-1.93.0.tgz", + "integrity": "sha512-QhRh+B4w8Q70RmAQuNxsAKfDeui5qPgT8veyLyMQ1PMuB5K2qhK8l3EYP3cwhnCU8xo0bO0Z48W64LcKlFxH0A==", + "requires": { + "@aws-cdk/core": "1.93.0", + "@aws-cdk/region-info": "1.93.0", + "constructs": "^3.2.0" + } + }, + "@aws-cdk/aws-kms": { + "version": "1.93.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-kms/-/aws-kms-1.93.0.tgz", + "integrity": "sha512-bx90WaCMakEQzavpbmF/xAbGtJRhyZxlzJ6rnCpwI+2yKJjRVnHTUKsqWb5wCOo/v47n3RIL7LK5LZPiFJnR+g==", + "requires": { + "@aws-cdk/aws-iam": "1.93.0", + "@aws-cdk/core": "1.93.0", + "@aws-cdk/cx-api": "1.93.0", + "constructs": "^3.2.0" + } + }, + "@aws-cdk/aws-lambda": { + "version": "1.93.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-lambda/-/aws-lambda-1.93.0.tgz", + "integrity": "sha512-OawHCa7HHp9fLa872CtSKa2wAJz3g2oQVt0A9NzB7jDd3qkRhaVnCeVpe3tHc4hwK7srjS8xC0/ldYoQ/zOIvw==", + "requires": { + "@aws-cdk/aws-applicationautoscaling": "1.93.0", + "@aws-cdk/aws-cloudwatch": "1.93.0", + "@aws-cdk/aws-codeguruprofiler": "1.93.0", + "@aws-cdk/aws-ec2": "1.93.0", + "@aws-cdk/aws-ecr": "1.93.0", + "@aws-cdk/aws-ecr-assets": "1.93.0", + "@aws-cdk/aws-efs": "1.93.0", + "@aws-cdk/aws-events": "1.93.0", + "@aws-cdk/aws-iam": "1.93.0", + "@aws-cdk/aws-kms": "1.93.0", + "@aws-cdk/aws-logs": "1.93.0", + "@aws-cdk/aws-s3": "1.93.0", + "@aws-cdk/aws-s3-assets": "1.93.0", + "@aws-cdk/aws-signer": "1.93.0", + "@aws-cdk/aws-sqs": "1.93.0", + "@aws-cdk/core": "1.93.0", + "@aws-cdk/cx-api": "1.93.0", + "constructs": "^3.2.0" + } + }, + "@aws-cdk/aws-logs": { + "version": "1.93.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-logs/-/aws-logs-1.93.0.tgz", + "integrity": "sha512-jC0PGjz8Sp8/GfnJrF1Fg5u3J3Z+tWW0a9ExO+iGl2vmE91JBmwYRwU/06HDxev/E8iUZdGL6VMdlNWQ4a7m3g==", + "requires": { + "@aws-cdk/aws-cloudwatch": "1.93.0", + "@aws-cdk/aws-iam": "1.93.0", + "@aws-cdk/aws-kms": "1.93.0", + "@aws-cdk/aws-s3-assets": "1.93.0", + "@aws-cdk/core": "1.93.0", + "constructs": "^3.2.0" + } + }, + "@aws-cdk/aws-route53": { + "version": "1.93.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-route53/-/aws-route53-1.93.0.tgz", + "integrity": "sha512-2+1A2OtSTs/Ie/A30tYP+TIgnlabS4TtP2Nni4FODtVIPSpljvfGRZ1PhVjueFoeXNErWS0YWqaIUSyCfSnSnA==", + "requires": { + "@aws-cdk/aws-ec2": "1.93.0", + "@aws-cdk/aws-iam": "1.93.0", + "@aws-cdk/aws-logs": "1.93.0", + "@aws-cdk/cloud-assembly-schema": "1.93.0", + "@aws-cdk/core": "1.93.0", + "@aws-cdk/custom-resources": "1.93.0", + "constructs": "^3.2.0" + } + }, + "@aws-cdk/aws-route53-targets": { + "version": "1.93.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-route53-targets/-/aws-route53-targets-1.93.0.tgz", + "integrity": "sha512-/AiZEs1jFcveWLSN/7ogp79kuEu1P9PI4UG8Tjhy2ZJGJhWr7yrduO5cQjRqbQ1BvaCmBGR5Oa8RLwoLtGzNBQ==", + "requires": { + "@aws-cdk/aws-apigateway": "1.93.0", + "@aws-cdk/aws-apigatewayv2": "1.93.0", + "@aws-cdk/aws-cloudfront": "1.93.0", + "@aws-cdk/aws-cognito": "1.93.0", + "@aws-cdk/aws-ec2": "1.93.0", + "@aws-cdk/aws-elasticloadbalancing": "1.93.0", + "@aws-cdk/aws-elasticloadbalancingv2": "1.93.0", + "@aws-cdk/aws-globalaccelerator": "1.93.0", + "@aws-cdk/aws-iam": "1.93.0", + "@aws-cdk/aws-route53": "1.93.0", + "@aws-cdk/aws-s3": "1.93.0", + "@aws-cdk/core": "1.93.0", + "@aws-cdk/region-info": "1.93.0", + "constructs": "^3.2.0" + } + }, + "@aws-cdk/aws-s3": { + "version": "1.93.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-s3/-/aws-s3-1.93.0.tgz", + "integrity": "sha512-sDm3Q0DODqxCeYLLwTg+YdKLPQnH0MXr5n6C29ZomK7xdKk8kA7LN18MwiLAfrvggZxaA/7VkWsatP3Q+bYfoQ==", + "requires": { + "@aws-cdk/aws-events": "1.93.0", + "@aws-cdk/aws-iam": "1.93.0", + "@aws-cdk/aws-kms": "1.93.0", + "@aws-cdk/core": "1.93.0", + "@aws-cdk/cx-api": "1.93.0", + "constructs": "^3.2.0" + } + }, + "@aws-cdk/aws-s3-assets": { + "version": "1.93.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-s3-assets/-/aws-s3-assets-1.93.0.tgz", + "integrity": "sha512-iRNp01EGjgZRcqzIiPHAzweeBwI+B6W88ZgzwEBpiGI4PD17UOvabepPm53T+kRX1Ly57iDsi121ItI2p1Akwg==", + "requires": { + "@aws-cdk/assets": "1.93.0", + "@aws-cdk/aws-iam": "1.93.0", + "@aws-cdk/aws-kms": "1.93.0", + "@aws-cdk/aws-s3": "1.93.0", + "@aws-cdk/core": "1.93.0", + "@aws-cdk/cx-api": "1.93.0", + "constructs": "^3.2.0" + } + }, + "@aws-cdk/aws-sam": { + "version": "1.93.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-sam/-/aws-sam-1.93.0.tgz", + "integrity": "sha512-RQztwvPwbSTsOK3hLunwlKdPuQwIJhArXdMebfmMPqsU7eO7c0ZFjkMkHaOnWCI/qwhsgfKd3SmYTGCJp/mC0Q==", + "requires": { + "@aws-cdk/core": "1.93.0", + "constructs": "^3.2.0" + } + }, + "@aws-cdk/aws-secretsmanager": { + "version": "1.93.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-secretsmanager/-/aws-secretsmanager-1.93.0.tgz", + "integrity": "sha512-Vyl2k66J0Ag256W8YBcdS7QM9cr6/aBZuEq5kyFT9GMwhpQ5RpDT+OUg31Pu3mLizlU70YlYueegnUQYEjxTbQ==", + "requires": { + "@aws-cdk/aws-ec2": "1.93.0", + "@aws-cdk/aws-iam": "1.93.0", + "@aws-cdk/aws-kms": "1.93.0", + "@aws-cdk/aws-lambda": "1.93.0", + "@aws-cdk/aws-sam": "1.93.0", + "@aws-cdk/core": "1.93.0", + "@aws-cdk/cx-api": "1.93.0", + "constructs": "^3.2.0" + } + }, + "@aws-cdk/aws-servicediscovery": { + "version": "1.93.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-servicediscovery/-/aws-servicediscovery-1.93.0.tgz", + "integrity": "sha512-KFunVCODLl8WaP1F+yaUBsnhck4hItgYqtvF2YYt3FaEkefLOYRaOMqlvnmtOYLv4a776GSJnDrEW/2QBwD1HA==", + "requires": { + "@aws-cdk/aws-ec2": "1.93.0", + "@aws-cdk/aws-elasticloadbalancingv2": "1.93.0", + "@aws-cdk/aws-route53": "1.93.0", + "@aws-cdk/core": "1.93.0", + "constructs": "^3.2.0" + } + }, + "@aws-cdk/aws-signer": { + "version": "1.93.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-signer/-/aws-signer-1.93.0.tgz", + "integrity": "sha512-nLkClk9emiUVhXsYEiSqznbN23sq2IxOYemgZZP4nptKwOgRYbdQcmHzmaj7ps+cmu0yYIF26zrIGwNRJ0B2oQ==", + "requires": { + "@aws-cdk/core": "1.93.0", + "constructs": "^3.2.0" + } + }, + "@aws-cdk/aws-sns": { + "version": "1.93.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-sns/-/aws-sns-1.93.0.tgz", + "integrity": "sha512-acMvsQhItehHXNBS3K30Ws53DJUXbxLDfrEXQhrc0tubZEt4Oexgwla1QjrkXCBZaxIFlFH7Q3qUEkP5OtN7kQ==", + "requires": { + "@aws-cdk/aws-cloudwatch": "1.93.0", + "@aws-cdk/aws-events": "1.93.0", + "@aws-cdk/aws-iam": "1.93.0", + "@aws-cdk/aws-kms": "1.93.0", + "@aws-cdk/aws-sqs": "1.93.0", + "@aws-cdk/core": "1.93.0", + "constructs": "^3.2.0" + } + }, + "@aws-cdk/aws-sns-subscriptions": { + "version": "1.93.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-sns-subscriptions/-/aws-sns-subscriptions-1.93.0.tgz", + "integrity": "sha512-I9+WnBlW9aitiDXKx5WYSi0R/YBb2pIQMsTmftQGskg8mlzecmtHRIST8fEd1x8KBqPY4H7Fzx0YsVzItQnZnQ==", + "requires": { + "@aws-cdk/aws-iam": "1.93.0", + "@aws-cdk/aws-lambda": "1.93.0", + "@aws-cdk/aws-sns": "1.93.0", + "@aws-cdk/aws-sqs": "1.93.0", + "@aws-cdk/core": "1.93.0", + "constructs": "^3.2.0" + } + }, + "@aws-cdk/aws-sqs": { + "version": "1.93.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-sqs/-/aws-sqs-1.93.0.tgz", + "integrity": "sha512-f7f0gxrCjhqPTgrW3fpnFa3RoHqWKDQBnnzSSY4DhZZINE4AIEr44zBr1bP5olQ5oybdd5McBCVNmlr6813kpw==", + "requires": { + "@aws-cdk/aws-cloudwatch": "1.93.0", + "@aws-cdk/aws-iam": "1.93.0", + "@aws-cdk/aws-kms": "1.93.0", + "@aws-cdk/core": "1.93.0", + "constructs": "^3.2.0" + } + }, + "@aws-cdk/aws-ssm": { + "version": "1.93.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-ssm/-/aws-ssm-1.93.0.tgz", + "integrity": "sha512-ptcuPc5S5bNiI4xluHAoO4Y8fFY4vePr0bvG+l5QHTNWvvJa+TIwD/jz91xJCrt83qAHwcnjSGZj94JIK732PQ==", + "requires": { + "@aws-cdk/aws-iam": "1.93.0", + "@aws-cdk/aws-kms": "1.93.0", + "@aws-cdk/cloud-assembly-schema": "1.93.0", + "@aws-cdk/core": "1.93.0", + "constructs": "^3.2.0" + } + }, + "@aws-cdk/aws-stepfunctions": { + "version": "1.93.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-stepfunctions/-/aws-stepfunctions-1.93.0.tgz", + "integrity": "sha512-ak1iCdNL3tOjrsNYqX41pcRbawRjtup0oCrzoJutn7Hro8t7SxYASbx4rm7QjQpRvGKxFgFn86rhLrTIULVEag==", + "requires": { + "@aws-cdk/aws-cloudwatch": "1.93.0", + "@aws-cdk/aws-events": "1.93.0", + "@aws-cdk/aws-iam": "1.93.0", + "@aws-cdk/aws-logs": "1.93.0", + "@aws-cdk/aws-s3": "1.93.0", + "@aws-cdk/core": "1.93.0", + "constructs": "^3.2.0" + } + }, + "@aws-cdk/aws-stepfunctions-tasks": { + "version": "1.93.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-stepfunctions-tasks/-/aws-stepfunctions-tasks-1.93.0.tgz", + "integrity": "sha512-6go46xQQYxdhO2f7pTQHZm/tD6AMO4dBpmtycQBxZgiLJ60J7fsSUQU80I+RTMMq6EIc2H8VrixXoXyNAHtjig==", + "requires": { + "@aws-cdk/aws-apigateway": "1.93.0", + "@aws-cdk/aws-apigatewayv2": "1.93.0", + "@aws-cdk/aws-apigatewayv2-integrations": "1.93.0", + "@aws-cdk/aws-batch": "1.93.0", + "@aws-cdk/aws-cloudwatch": "1.93.0", + "@aws-cdk/aws-codebuild": "1.93.0", + "@aws-cdk/aws-databrew": "1.93.0", + "@aws-cdk/aws-dynamodb": "1.93.0", + "@aws-cdk/aws-ec2": "1.93.0", + "@aws-cdk/aws-ecr": "1.93.0", + "@aws-cdk/aws-ecr-assets": "1.93.0", + "@aws-cdk/aws-ecs": "1.93.0", + "@aws-cdk/aws-eks": "1.93.0", + "@aws-cdk/aws-glue": "1.93.0", + "@aws-cdk/aws-iam": "1.93.0", + "@aws-cdk/aws-kms": "1.93.0", + "@aws-cdk/aws-lambda": "1.93.0", + "@aws-cdk/aws-s3": "1.93.0", + "@aws-cdk/aws-sns": "1.93.0", + "@aws-cdk/aws-sqs": "1.93.0", + "@aws-cdk/aws-stepfunctions": "1.93.0", + "@aws-cdk/core": "1.93.0", + "constructs": "^3.2.0" + } + }, + "@aws-cdk/cfnspec": { + "version": "1.93.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/cfnspec/-/cfnspec-1.93.0.tgz", + "integrity": "sha512-uInqSj+xWDTU7HrGZEhzQawmI3ugtdv66r4JTPOjCLUB6qDtnGhT5dsK/MHNyQkC07WjDSjkF1BxAlnCC1NRtw==", + "dev": true, + "requires": { + "md5": "^2.3.0" + } + }, + "@aws-cdk/cloud-assembly-schema": { + "version": "1.93.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/cloud-assembly-schema/-/cloud-assembly-schema-1.93.0.tgz", + "integrity": "sha512-ky7MrButxqUwLS1LLSSxc5FXxr0BB9ECvJVdJJg0lfuL4+v/xB7Ba0vHdLtSd4dVPJ47MlqDdrE4uEQjlleDMQ==", + "requires": { + "jsonschema": "^1.4.0", + "semver": "^7.3.4" + }, + "dependencies": { + "jsonschema": { + "version": "1.4.0", + "bundled": true + }, + "lru-cache": { + "version": "6.0.0", + "bundled": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "semver": { + "version": "7.3.4", + "bundled": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "bundled": true + } + } + }, + "@aws-cdk/cloudformation-diff": { + "version": "1.93.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/cloudformation-diff/-/cloudformation-diff-1.93.0.tgz", + "integrity": "sha512-wjAlhERlIJZzXJ8UqOqUb6Iaq8ufwzvRwuUkmpX5xW5LGdqMqSgfQjbZCPf2gIVxWUrhmYvCKlH6QlR+mCUdqw==", + "dev": true, + "requires": { + "@aws-cdk/cfnspec": "1.93.0", + "colors": "^1.4.0", + "diff": "^5.0.0", + "fast-deep-equal": "^3.1.3", + "string-width": "^4.2.2", + "table": "^6.0.7" + } + }, + "@aws-cdk/core": { + "version": "1.93.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/core/-/core-1.93.0.tgz", + "integrity": "sha512-Z/1IZJJBfurswUKKMxoVbS0hJGIdVaTYlMCcSsYIlEVgv4D+4YfkRnWsp99IscUr1zvs+FTfM/K1ykXb8u2gaQ==", + "requires": { + "@aws-cdk/cloud-assembly-schema": "1.93.0", + "@aws-cdk/cx-api": "1.93.0", + "@aws-cdk/region-info": "1.93.0", + "@balena/dockerignore": "^1.0.2", + "constructs": "^3.2.0", + "fs-extra": "^9.1.0", + "ignore": "^5.1.8", + "minimatch": "^3.0.4" + }, + "dependencies": { + "@balena/dockerignore": { + "version": "1.0.2", + "bundled": true + }, + "at-least-node": { + "version": "1.0.0", + "bundled": true + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "concat-map": { + "version": "0.0.1", + "bundled": true + }, + "fs-extra": { + "version": "9.1.0", + "bundled": true, + "requires": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "graceful-fs": { + "version": "4.2.6", + "bundled": true + }, + "ignore": { + "version": "5.1.8", + "bundled": true + }, + "jsonfile": { + "version": "6.1.0", + "bundled": true, + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + } + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "universalify": { + "version": "2.0.0", + "bundled": true + } + } + }, + "@aws-cdk/custom-resources": { + "version": "1.93.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/custom-resources/-/custom-resources-1.93.0.tgz", + "integrity": "sha512-IzgxGK3hFFT/5BOuiNSrg8s04korg4lO7BYJdtpilroJsYLEuzv06u3XP8r8sR7XTseMbGqy5ppYfBc1glUr1w==", + "requires": { + "@aws-cdk/aws-cloudformation": "1.93.0", + "@aws-cdk/aws-ec2": "1.93.0", + "@aws-cdk/aws-iam": "1.93.0", + "@aws-cdk/aws-lambda": "1.93.0", + "@aws-cdk/aws-logs": "1.93.0", + "@aws-cdk/aws-sns": "1.93.0", + "@aws-cdk/core": "1.93.0", + "constructs": "^3.2.0" + } + }, + "@aws-cdk/cx-api": { + "version": "1.93.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/cx-api/-/cx-api-1.93.0.tgz", + "integrity": "sha512-uZNAjYbMaSwaqIBwW9pqFwPIp38LrLyyRraHjin02QuJBubOnZEGfpcuo4Io9JPAF6h0FZbDNavlt4qkzzKS4g==", + "requires": { + "@aws-cdk/cloud-assembly-schema": "1.93.0", + "semver": "^7.3.4" + }, + "dependencies": { + "lru-cache": { + "version": "6.0.0", + "bundled": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "semver": { + "version": "7.3.4", + "bundled": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "bundled": true + } + } + }, + "@aws-cdk/lambda-layer-awscli": { + "version": "1.93.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/lambda-layer-awscli/-/lambda-layer-awscli-1.93.0.tgz", + "integrity": "sha512-ue7GuV+9kXuHPEiw4HhJN81JZ3IVa2macTzVzt6fWvpE24BOT5z1oTJtIgWTjQE8gDRvCzwcHUl7IjHdT1QoMg==", + "requires": { + "@aws-cdk/aws-lambda": "1.93.0", + "@aws-cdk/core": "1.93.0", + "constructs": "^3.2.0" + } + }, + "@aws-cdk/lambda-layer-kubectl": { + "version": "1.93.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/lambda-layer-kubectl/-/lambda-layer-kubectl-1.93.0.tgz", + "integrity": "sha512-oGq+gO54Z4YuYDVn49QXWoUeGK7FSF1peA7QPpTEc3POHIUYNC/2fwRV6V6AsZQS0FSzBuOW+uX7sQ2nGjgP8A==", + "requires": { + "@aws-cdk/aws-lambda": "1.93.0", + "@aws-cdk/core": "1.93.0", + "constructs": "^3.2.0" + } + }, + "@aws-cdk/region-info": { + "version": "1.93.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/region-info/-/region-info-1.93.0.tgz", + "integrity": "sha512-JyCIv/NlUnd+elSD74EXO6ZjhPHg5KMMdiPpZM/+8RJuHnvtKI7fL0E31/DulgeVSj/S1TvjVn0xOoKAkfQrnw==" + }, + "@babel/code-frame": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", + "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", + "dev": true, + "requires": { + "@babel/highlight": "^7.12.13" + } + }, + "@babel/compat-data": { + "version": "7.13.11", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.13.11.tgz", + "integrity": "sha512-BwKEkO+2a67DcFeS3RLl0Z3Gs2OvdXewuWjc1Hfokhb5eQWP9YRYH1/+VrVZvql2CfjOiNGqSAFOYt4lsqTHzg==", + "dev": true + }, + "@babel/core": { + "version": "7.13.10", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.13.10.tgz", + "integrity": "sha512-bfIYcT0BdKeAZrovpMqX2Mx5NrgAckGbwT982AkdS5GNfn3KMGiprlBAtmBcFZRUmpaufS6WZFP8trvx8ptFDw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.12.13", + "@babel/generator": "^7.13.9", + "@babel/helper-compilation-targets": "^7.13.10", + "@babel/helper-module-transforms": "^7.13.0", + "@babel/helpers": "^7.13.10", + "@babel/parser": "^7.13.10", + "@babel/template": "^7.12.13", + "@babel/traverse": "^7.13.0", + "@babel/types": "^7.13.0", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.1.2", + "lodash": "^4.17.19", + "semver": "^6.3.0", + "source-map": "^0.5.0" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "@babel/generator": { + "version": "7.13.9", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.13.9.tgz", + "integrity": "sha512-mHOOmY0Axl/JCTkxTU6Lf5sWOg/v8nUa+Xkt4zMTftX0wqmb6Sh7J8gvcehBw7q0AhrhAR+FDacKjCZ2X8K+Sw==", + "dev": true, + "requires": { + "@babel/types": "^7.13.0", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "@babel/helper-compilation-targets": { + "version": "7.13.10", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.10.tgz", + "integrity": "sha512-/Xju7Qg1GQO4mHZ/Kcs6Au7gfafgZnwm+a7sy/ow/tV1sHeraRUHbjdat8/UvDor4Tez+siGKDk6zIKtCPKVJA==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.13.8", + "@babel/helper-validator-option": "^7.12.17", + "browserslist": "^4.14.5", + "semver": "^6.3.0" + } + }, + "@babel/helper-function-name": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz", + "integrity": "sha512-TZvmPn0UOqmvi5G4vvw0qZTpVptGkB1GL61R6lKvrSdIxGm5Pky7Q3fpKiIkQCAtRCBUwB0PaThlx9vebCDSwA==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.12.13", + "@babel/template": "^7.12.13", + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz", + "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==", + "dev": true, + "requires": { + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.0.tgz", + "integrity": "sha512-yvRf8Ivk62JwisqV1rFRMxiSMDGnN6KH1/mDMmIrij4jztpQNRoHqqMG3U6apYbGRPJpgPalhva9Yd06HlUxJQ==", + "dev": true, + "requires": { + "@babel/types": "^7.13.0" + } + }, + "@babel/helper-module-imports": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.12.13.tgz", + "integrity": "sha512-NGmfvRp9Rqxy0uHSSVP+SRIW1q31a7Ji10cLBcqSDUngGentY4FRiHOFZFE1CLU5eiL0oE8reH7Tg1y99TDM/g==", + "dev": true, + "requires": { + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-module-transforms": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.13.0.tgz", + "integrity": "sha512-Ls8/VBwH577+pw7Ku1QkUWIyRRNHpYlts7+qSqBBFCW3I8QteB9DxfcZ5YJpOwH6Ihe/wn8ch7fMGOP1OhEIvw==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.12.13", + "@babel/helper-replace-supers": "^7.13.0", + "@babel/helper-simple-access": "^7.12.13", + "@babel/helper-split-export-declaration": "^7.12.13", + "@babel/helper-validator-identifier": "^7.12.11", + "@babel/template": "^7.12.13", + "@babel/traverse": "^7.13.0", + "@babel/types": "^7.13.0", + "lodash": "^4.17.19" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz", + "integrity": "sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA==", + "dev": true, + "requires": { + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.13.0.tgz", + "integrity": "sha512-ZPafIPSwzUlAoWT8DKs1W2VyF2gOWthGd5NGFMsBcMMol+ZhK+EQY/e6V96poa6PA/Bh+C9plWN0hXO1uB8AfQ==", + "dev": true + }, + "@babel/helper-replace-supers": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.13.0.tgz", + "integrity": "sha512-Segd5me1+Pz+rmN/NFBOplMbZG3SqRJOBlY+mA0SxAv6rjj7zJqr1AVr3SfzUVTLCv7ZLU5FycOM/SBGuLPbZw==", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.13.0", + "@babel/helper-optimise-call-expression": "^7.12.13", + "@babel/traverse": "^7.13.0", + "@babel/types": "^7.13.0" + } + }, + "@babel/helper-simple-access": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.12.13.tgz", + "integrity": "sha512-0ski5dyYIHEfwpWGx5GPWhH35j342JaflmCeQmsPWcrOQDtCN6C1zKAVRFVbK53lPW2c9TsuLLSUDf0tIGJ5hA==", + "dev": true, + "requires": { + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz", + "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==", + "dev": true, + "requires": { + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", + "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", + "dev": true + }, + "@babel/helper-validator-option": { + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz", + "integrity": "sha512-TopkMDmLzq8ngChwRlyjR6raKD6gMSae4JdYDB8bByKreQgG0RBTuKe9LRxW3wFtUnjxOPRKBDwEH6Mg5KeDfw==", + "dev": true + }, + "@babel/helpers": { + "version": "7.13.10", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.13.10.tgz", + "integrity": "sha512-4VO883+MWPDUVRF3PhiLBUFHoX/bsLTGFpFK/HqvvfBZz2D57u9XzPVNFVBTc0PW/CWR9BXTOKt8NF4DInUHcQ==", + "dev": true, + "requires": { + "@babel/template": "^7.12.13", + "@babel/traverse": "^7.13.0", + "@babel/types": "^7.13.0" + } + }, + "@babel/highlight": { + "version": "7.13.10", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.13.10.tgz", + "integrity": "sha512-5aPpe5XQPzflQrFwL1/QoeHkP2MsA4JCntcXHRhEsdsfPVkvPi2w7Qix4iV7t5S/oC9OodGrggd8aco1g3SZFg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.12.11", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@babel/parser": { + "version": "7.13.11", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.13.11.tgz", + "integrity": "sha512-PhuoqeHoO9fc4ffMEVk4qb/w/s2iOSWohvbHxLtxui0eBg3Lg5gN1U8wp1V1u61hOWkPQJJyJzGH6Y+grwkq8Q==", + "dev": true + }, + "@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-top-level-await": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.13.tgz", + "integrity": "sha512-A81F9pDwyS7yM//KwbCSDqy3Uj4NMIurtplxphWxoYtNPov7cJsDkAFNNyVlIZ3jwGycVsurZ+LtOA8gZ376iQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/template": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz", + "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.12.13", + "@babel/parser": "^7.12.13", + "@babel/types": "^7.12.13" + } + }, + "@babel/traverse": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.13.0.tgz", + "integrity": "sha512-xys5xi5JEhzC3RzEmSGrs/b3pJW/o87SypZ+G/PhaE7uqVQNv/jlmVIBXuoh5atqQ434LfXV+sf23Oxj0bchJQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.12.13", + "@babel/generator": "^7.13.0", + "@babel/helper-function-name": "^7.12.13", + "@babel/helper-split-export-declaration": "^7.12.13", + "@babel/parser": "^7.13.0", + "@babel/types": "^7.13.0", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.19" + } + }, + "@babel/types": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.13.0.tgz", + "integrity": "sha512-hE+HE8rnG1Z6Wzo+MhaKE5lM5eMx71T4EHJgku2E3xIfaULhDcxiiRxUYgwX8qwP1BBSlag+TdGOt6JAidIZTA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.12.11", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + }, + "@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true + }, + "@cnakazawa/watch": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.4.tgz", + "integrity": "sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==", + "dev": true, + "requires": { + "exec-sh": "^0.3.2", + "minimist": "^1.2.0" + } + }, + "@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "requires": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + } + }, + "@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true + }, + "@jest/console": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", + "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^26.6.2", + "jest-util": "^26.6.2", + "slash": "^3.0.0" + } + }, + "@jest/core": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-26.6.3.tgz", + "integrity": "sha512-xvV1kKbhfUqFVuZ8Cyo+JPpipAHHAV3kcDBftiduK8EICXmTFddryy3P7NfZt8Pv37rA9nEJBKCCkglCPt/Xjw==", + "dev": true, + "requires": { + "@jest/console": "^26.6.2", + "@jest/reporters": "^26.6.2", + "@jest/test-result": "^26.6.2", + "@jest/transform": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "jest-changed-files": "^26.6.2", + "jest-config": "^26.6.3", + "jest-haste-map": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.6.2", + "jest-resolve-dependencies": "^26.6.3", + "jest-runner": "^26.6.3", + "jest-runtime": "^26.6.3", + "jest-snapshot": "^26.6.2", + "jest-util": "^26.6.2", + "jest-validate": "^26.6.2", + "jest-watcher": "^26.6.2", + "micromatch": "^4.0.2", + "p-each-series": "^2.1.0", + "rimraf": "^3.0.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "@jest/environment": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", + "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", + "dev": true, + "requires": { + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2" + } + }, + "@jest/fake-timers": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", + "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "@sinonjs/fake-timers": "^6.0.1", + "@types/node": "*", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" + } + }, + "@jest/globals": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-26.6.2.tgz", + "integrity": "sha512-85Ltnm7HlB/KesBUuALwQ68YTU72w9H2xW9FjZ1eL1U3lhtefjjl5c2MiUbpXt/i6LaPRvoOFJ22yCBSfQ0JIA==", + "dev": true, + "requires": { + "@jest/environment": "^26.6.2", + "@jest/types": "^26.6.2", + "expect": "^26.6.2" + } + }, + "@jest/reporters": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-26.6.2.tgz", + "integrity": "sha512-h2bW53APG4HvkOnVMo8q3QXa6pcaNt1HkwVsOPMBV6LD/q9oSpxNSYZQYkAnjdMjrJ86UuYeLo+aEZClV6opnw==", + "dev": true, + "requires": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^26.6.2", + "@jest/test-result": "^26.6.2", + "@jest/transform": "^26.6.2", + "@jest/types": "^26.6.2", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.2", + "graceful-fs": "^4.2.4", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^4.0.3", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "jest-haste-map": "^26.6.2", + "jest-resolve": "^26.6.2", + "jest-util": "^26.6.2", + "jest-worker": "^26.6.2", + "node-notifier": "^8.0.0", + "slash": "^3.0.0", + "source-map": "^0.6.0", + "string-length": "^4.0.1", + "terminal-link": "^2.0.0", + "v8-to-istanbul": "^7.0.0" + } + }, + "@jest/source-map": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-26.6.2.tgz", + "integrity": "sha512-YwYcCwAnNmOVsZ8mr3GfnzdXDAl4LaenZP5z+G0c8bzC9/dugL8zRmxZzdoTl4IaS3CryS1uWnROLPFmb6lVvA==", + "dev": true, + "requires": { + "callsites": "^3.0.0", + "graceful-fs": "^4.2.4", + "source-map": "^0.6.0" + } + }, + "@jest/test-result": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", + "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", + "dev": true, + "requires": { + "@jest/console": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + } + }, + "@jest/test-sequencer": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-26.6.3.tgz", + "integrity": "sha512-YHlVIjP5nfEyjlrSr8t/YdNfU/1XEt7c5b4OxcXCjyRhjzLYu/rO69/WHPuYcbCWkz8kAeZVZp2N2+IOLLEPGw==", + "dev": true, + "requires": { + "@jest/test-result": "^26.6.2", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^26.6.2", + "jest-runner": "^26.6.3", + "jest-runtime": "^26.6.3" + } + }, + "@jest/transform": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-26.6.2.tgz", + "integrity": "sha512-E9JjhUgNzvuQ+vVAL21vlyfy12gP0GhazGgJC4h6qUt1jSdUXGWJ1wfu/X7Sd8etSgxV4ovT1pb9v5D6QW4XgA==", + "dev": true, + "requires": { + "@babel/core": "^7.1.0", + "@jest/types": "^26.6.2", + "babel-plugin-istanbul": "^6.0.0", + "chalk": "^4.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^26.6.2", + "jest-regex-util": "^26.0.0", + "jest-util": "^26.6.2", + "micromatch": "^4.0.2", + "pirates": "^4.0.1", + "slash": "^3.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "^3.0.0" + } + }, + "@jest/types": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "@sinonjs/commons": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.2.tgz", + "integrity": "sha512-sruwd86RJHdsVf/AtBoijDmUqJp3B6hF/DGC23C+JaegnDHaZyewCjoVGTdg3J0uz3Zs7NnIT05OBOmML72lQw==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/fake-timers": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz", + "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.7.0" + } + }, + "@types/babel__core": { + "version": "7.1.13", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.13.tgz", + "integrity": "sha512-CC6amBNND16pTk4K3ZqKIaba6VGKAQs3gMjEY17FVd56oI/ZWt9OhS6riYiWv9s8ENbYUi7p8lgqb0QHQvUKQQ==", + "dev": true, + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "@types/babel__generator": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.2.tgz", + "integrity": "sha512-MdSJnBjl+bdwkLskZ3NGFp9YcXGx5ggLpQQPqtgakVhsWK0hTtNYhjpZLlWQTviGTvF8at+Bvli3jV7faPdgeQ==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@types/babel__template": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.0.tgz", + "integrity": "sha512-NTPErx4/FiPCGScH7foPyr+/1Dkzkni+rHiYHHoTjvwou7AQzJkNeD60A9CXRy+ZEN2B1bggmkTMCDb+Mv5k+A==", + "dev": true, + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@types/babel__traverse": { + "version": "7.11.1", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.11.1.tgz", + "integrity": "sha512-Vs0hm0vPahPMYi9tDjtP66llufgO3ST16WXaSTtDGEl9cewAl3AibmxWw6TINOqHPT9z0uABKAYjT9jNSg4npw==", + "dev": true, + "requires": { + "@babel/types": "^7.3.0" + } + }, + "@types/graceful-fs": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", + "integrity": "sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/istanbul-lib-coverage": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", + "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==", + "dev": true + }, + "@types/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "*" + } + }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, + "@types/jest": { + "version": "26.0.20", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-26.0.20.tgz", + "integrity": "sha512-9zi2Y+5USJRxd0FsahERhBwlcvFh6D2GLQnY2FH2BzK8J9s9omvNHIbvABwIluXa0fD8XVKMLTO0aOEuUfACAA==", + "dev": true, + "requires": { + "jest-diff": "^26.0.0", + "pretty-format": "^26.0.0" + } + }, + "@types/node": { + "version": "10.17.27", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.27.tgz", + "integrity": "sha512-J0oqm9ZfAXaPdwNXMMgAhylw5fhmXkToJd06vuDUSAgEDZ/n/69/69UmyBZbc+zT34UnShuDSBqvim3SPnozJg==", + "dev": true + }, + "@types/normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", + "dev": true + }, + "@types/prettier": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.2.3.tgz", + "integrity": "sha512-PijRCG/K3s3w1We6ynUKdxEc5AcuuH3NBmMDP8uvKVp6X43UY7NQlTzczakXP3DJR0F4dfNQIGjU2cUeRYs2AA==", + "dev": true + }, + "@types/stack-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", + "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", + "dev": true + }, + "@types/yargs": { + "version": "15.0.13", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.13.tgz", + "integrity": "sha512-kQ5JNTrbDv3Rp5X2n/iUu37IJBDU2gsZ5R/g1/KHOOEc5IKfUFjXT6DENPGduh08I/pamwtEq4oul7gUqKTQDQ==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "@types/yargs-parser": { + "version": "20.2.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.0.tgz", + "integrity": "sha512-37RSHht+gzzgYeobbG+KWryeAW8J33Nhr69cjTqSYymXVZEN9NbRYWoYlRtDhHKPVT1FyNKwaTPC1NynKZpzRA==", + "dev": true + }, + "abab": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", + "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==", + "dev": true + }, + "acorn": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.1.0.tgz", + "integrity": "sha512-LWCF/Wn0nfHOmJ9rzQApGnxnvgfROzGilS8936rqN/lfcYkY9MYZzdMqN+2NJ4SlTc+m5HiSa+kNfDtI64dwUA==", + "dev": true + }, + "acorn-globals": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", + "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", + "dev": true, + "requires": { + "acorn": "^7.1.1", + "acorn-walk": "^7.1.1" + }, + "dependencies": { + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true + } + } + }, + "acorn-walk": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", + "dev": true + }, + "ajv": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-7.2.1.tgz", + "integrity": "sha512-+nu0HDv7kNSOua9apAVc979qd932rrZeb3WOvoiD31A/p1mIE5/9bN2027pE2rOPYEdS3UHzsvof4hY+lM9/WQ==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "ansi-escapes": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", + "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==", + "dev": true, + "requires": { + "type-fest": "^0.11.0" + }, + "dependencies": { + "type-fest": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", + "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==", + "dev": true + } + } + }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dev": true, + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "dev": true + }, + "astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true + }, + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true + }, + "aws-cdk": { + "version": "1.93.0", + "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-1.93.0.tgz", + "integrity": "sha512-/nu/42rVYK06j/w2uoxLc4zCbpdyWBuAXLXj74UyilHakoKDCyvAA6LCiAOlLP8BrpFyd/tbdB3aRue8qCEb1A==", + "dev": true, + "requires": { + "@aws-cdk/cloud-assembly-schema": "1.93.0", + "@aws-cdk/cloudformation-diff": "1.93.0", + "@aws-cdk/cx-api": "1.93.0", + "@aws-cdk/region-info": "1.93.0", + "@aws-cdk/yaml-cfn": "1.93.0", + "archiver": "^5.2.0", + "aws-sdk": "^2.848.0", + "camelcase": "^6.2.0", + "cdk-assets": "1.93.0", + "colors": "^1.4.0", + "decamelize": "^5.0.0", + "fs-extra": "^9.1.0", + "glob": "^7.1.6", + "json-diff": "^0.5.4", + "minimatch": ">=3.0", + "promptly": "^3.2.0", + "proxy-agent": "^4.0.1", + "semver": "^7.3.4", + "source-map-support": "^0.5.19", + "table": "^6.0.7", + "uuid": "^8.3.2", + "wrap-ansi": "^7.0.0", + "yargs": "^16.2.0" + }, + "dependencies": { + "@aws-cdk/cfnspec": { + "version": "1.93.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/cfnspec/-/cfnspec-1.93.0.tgz", + "integrity": "sha512-uInqSj+xWDTU7HrGZEhzQawmI3ugtdv66r4JTPOjCLUB6qDtnGhT5dsK/MHNyQkC07WjDSjkF1BxAlnCC1NRtw==", + "dev": true, + "requires": { + "md5": "^2.3.0" + } + }, + "@aws-cdk/cloud-assembly-schema": { + "version": "1.93.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/cloud-assembly-schema/-/cloud-assembly-schema-1.93.0.tgz", + "integrity": "sha512-ky7MrButxqUwLS1LLSSxc5FXxr0BB9ECvJVdJJg0lfuL4+v/xB7Ba0vHdLtSd4dVPJ47MlqDdrE4uEQjlleDMQ==", + "dev": true, + "requires": { + "jsonschema": "^1.4.0", + "semver": "^7.3.4" + } + }, + "@aws-cdk/cloudformation-diff": { + "version": "1.93.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/cloudformation-diff/-/cloudformation-diff-1.93.0.tgz", + "integrity": "sha512-wjAlhERlIJZzXJ8UqOqUb6Iaq8ufwzvRwuUkmpX5xW5LGdqMqSgfQjbZCPf2gIVxWUrhmYvCKlH6QlR+mCUdqw==", + "dev": true, + "requires": { + "@aws-cdk/cfnspec": "1.93.0", + "colors": "^1.4.0", + "diff": "^5.0.0", + "fast-deep-equal": "^3.1.3", + "string-width": "^4.2.2", + "table": "^6.0.7" + } + }, + "@aws-cdk/cx-api": { + "version": "1.93.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/cx-api/-/cx-api-1.93.0.tgz", + "integrity": "sha512-uZNAjYbMaSwaqIBwW9pqFwPIp38LrLyyRraHjin02QuJBubOnZEGfpcuo4Io9JPAF6h0FZbDNavlt4qkzzKS4g==", + "dev": true, + "requires": { + "@aws-cdk/cloud-assembly-schema": "1.93.0", + "semver": "^7.3.4" + } + }, + "@aws-cdk/region-info": { + "version": "1.93.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/region-info/-/region-info-1.93.0.tgz", + "integrity": "sha512-JyCIv/NlUnd+elSD74EXO6ZjhPHg5KMMdiPpZM/+8RJuHnvtKI7fL0E31/DulgeVSj/S1TvjVn0xOoKAkfQrnw==", + "dev": true + }, + "@aws-cdk/yaml-cfn": { + "version": "1.93.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/yaml-cfn/-/yaml-cfn-1.93.0.tgz", + "integrity": "sha512-Nra7gJ1JHiYQHDG0Q07kRuo/15YnlDLfuTHkNQJjeCNqBQTVc4x/M/awPoVDZb9FcyYkmxqZHx8TOElEMT3OlQ==", + "dev": true, + "requires": { + "yaml": "1.10.0" + } + }, + "@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "dev": true + }, + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "requires": { + "debug": "4" + } + }, + "ajv": { + "version": "7.1.1", + "resolved": "https://registry.yarnpkg.com/ajv/-/ajv-7.1.1.tgz#1e6b37a454021fa9941713f38b952fc1c8d32a84", + "integrity": "sha512-ga/aqDYnUy/o7vbsRTFhhTsNeXiYb5JWDIcRIeZfwRNCefwjNTVYCGdGSUrEmiu3yDK3vFvNbgJxvrQW4JXrYQ==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "archiver": { + "version": "5.2.0", + "resolved": "https://registry.yarnpkg.com/archiver/-/archiver-5.2.0.tgz#25aa1b3d9febf7aec5b0f296e77e69960c26db94", + "integrity": "sha512-QEAKlgQuAtUxKeZB9w5/ggKXh21bZS+dzzuQ0RPBC20qtDCbTyzqmisoeJP46MP39fg4B4IcyvR+yeyEBdblsQ==", + "dev": true, + "requires": { + "archiver-utils": "^2.1.0", + "async": "^3.2.0", + "buffer-crc32": "^0.2.1", + "readable-stream": "^3.6.0", + "readdir-glob": "^1.0.0", + "tar-stream": "^2.1.4", + "zip-stream": "^4.0.4" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "requires": { + "safe-buffer": "~5.2.0" + } + } + } + }, + "archiver-utils": { + "version": "2.1.0", + "resolved": "https://registry.yarnpkg.com/archiver-utils/-/archiver-utils-2.1.0.tgz#e8a460e94b693c3e3da182a098ca6285ba9249e2", + "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==", + "dev": true, + "requires": { + "glob": "^7.1.4", + "graceful-fs": "^4.2.0", + "lazystream": "^1.0.0", + "lodash.defaults": "^4.2.0", + "lodash.difference": "^4.5.0", + "lodash.flatten": "^4.4.0", + "lodash.isplainobject": "^4.0.6", + "lodash.union": "^4.6.0", + "normalize-path": "^3.0.0", + "readable-stream": "^2.0.0" + } + }, + "ast-types": { + "version": "0.13.4", + "resolved": "https://registry.yarnpkg.com/ast-types/-/ast-types-0.13.4.tgz#ee0d77b343263965ecc3fb62da16e7222b2b6782", + "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", + "dev": true, + "requires": { + "tslib": "^2.0.1" + } + }, + "astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true + }, + "async": { + "version": "3.2.0", + "resolved": "https://registry.yarnpkg.com/async/-/async-3.2.0.tgz#b3a2685c5ebb641d3de02d161002c60fc9f85720", + "integrity": "sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw==", + "dev": true + }, + "at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true + }, + "aws-sdk": { + "version": "2.856.0", + "resolved": "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.856.0.tgz#a82719952949bdfda73832b465321a49577cf784", + "integrity": "sha512-B9uRDhIxlmaz5GIDC2Q+OgVMnsPFzuu1HknWedpTre6ARG+Ukm8KQ3VA5MhsBtSm61X5u1Uwk5AlEv+feLaShA==", + "dev": true, + "requires": { + "buffer": "4.9.2", + "events": "1.1.1", + "ieee754": "1.1.13", + "jmespath": "0.15.0", + "querystring": "0.2.0", + "sax": "1.2.1", + "url": "0.10.3", + "uuid": "3.3.2", + "xml2js": "0.4.19" + }, + "dependencies": { + "buffer": { + "version": "4.9.2", + "resolved": "https://registry.yarnpkg.com/buffer/-/buffer-4.9.2.tgz#230ead344002988644841ab0244af8c44bbe3ef8", + "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", + "dev": true, + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + }, + "dependencies": { + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true + } + } + }, + "ieee754": { + "version": "1.1.13", + "resolved": "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84", + "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", + "dev": true + }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "dev": true + } + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true + }, + "bl": { + "version": "4.1.0", + "resolved": "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "requires": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "requires": { + "safe-buffer": "~5.2.0" + } + } + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "buffer": { + "version": "5.7.1", + "resolved": "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", + "dev": true + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "bytes": { + "version": "3.1.0", + "resolved": "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "dev": true + }, + "camelcase": { + "version": "6.2.0", + "resolved": "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.0.tgz#924af881c9d525ac9d87f40d964e5cea982a1809", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", + "dev": true + }, + "cdk-assets": { + "version": "1.93.0", + "resolved": "https://registry.npmjs.org/cdk-assets/-/cdk-assets-1.93.0.tgz", + "integrity": "sha512-9t4s8CmUJJFn8HFDh4NS5KzhJh90Lu4gdFhDNXgYThnXjawRBkEyjgjAWKwFSrQJ9/lWXsBz5PdlvO0cewjSwg==", + "dev": true, + "requires": { + "@aws-cdk/cloud-assembly-schema": "1.93.0", + "@aws-cdk/cx-api": "1.93.0", + "archiver": "^5.2.0", + "aws-sdk": "^2.848.0", + "glob": "^7.1.6", + "yargs": "^16.2.0" + } + }, + "charenc": { + "version": "0.0.2", + "resolved": "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667", + "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=", + "dev": true + }, + "cli-color": { + "version": "0.1.7", + "resolved": "https://registry.yarnpkg.com/cli-color/-/cli-color-0.1.7.tgz#adc3200fa471cc211b0da7f566b71e98b9d67347", + "integrity": "sha1-rcMgD6RxzCEbDaf1ZrcemLnWc0c=", + "dev": true, + "requires": { + "es5-ext": "0.8.x" + } + }, + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "colors": { + "version": "1.4.0", + "resolved": "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "dev": true + }, + "compress-commons": { + "version": "4.1.0", + "resolved": "https://registry.yarnpkg.com/compress-commons/-/compress-commons-4.1.0.tgz#25ec7a4528852ccd1d441a7d4353cd0ece11371b", + "integrity": "sha512-ofaaLqfraD1YRTkrRKPCrGJ1pFeDG/MVCkVVV2FNGeWquSlqw5wOrwOfPQ1xF2u+blpeWASie5EubHz+vsNIgA==", + "dev": true, + "requires": { + "buffer-crc32": "^0.2.13", + "crc32-stream": "^4.0.1", + "normalize-path": "^3.0.0", + "readable-stream": "^3.6.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "requires": { + "safe-buffer": "~5.2.0" + } + } + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "crc-32": { + "version": "1.2.0", + "resolved": "https://registry.yarnpkg.com/crc-32/-/crc-32-1.2.0.tgz#cb2db6e29b88508e32d9dd0ec1693e7b41a18208", + "integrity": "sha512-1uBwHxF+Y/4yF5G48fwnKq6QsIXheor3ZLPT80yGBV1oEUwpPojlEhQbWKVw1VwcTQyMGHK1/XMmTjmlsmTTGA==", + "dev": true, + "requires": { + "exit-on-epipe": "~1.0.1", + "printj": "~1.1.0" + } + }, + "crc32-stream": { + "version": "4.0.2", + "resolved": "https://registry.yarnpkg.com/crc32-stream/-/crc32-stream-4.0.2.tgz#c922ad22b38395abe9d3870f02fa8134ed709007", + "integrity": "sha512-DxFZ/Hk473b/muq1VJ///PMNLj0ZMnzye9thBpmjpJKCc5eMgB95aK8zCGrGfQ90cWo561Te6HK9D+j4KPdM6w==", + "dev": true, + "requires": { + "crc-32": "^1.2.0", + "readable-stream": "^3.4.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "requires": { + "safe-buffer": "~5.2.0" + } + } + } + }, + "crypt": { + "version": "0.0.2", + "resolved": "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b", + "integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=", + "dev": true + }, + "data-uri-to-buffer": { + "version": "3.0.1", + "resolved": "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-3.0.1.tgz#594b8973938c5bc2c33046535785341abc4f3636", + "integrity": "sha512-WboRycPNsVw3B3TL559F7kuBUM4d8CgMEvk6xEJlOp7OBPjt6G7z8WMWlD2rOFZLk6OYfFIUGsCOWzcQH9K2og==", + "dev": true + }, + "debug": { + "version": "4.3.1", + "resolved": "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "decamelize": { + "version": "5.0.0", + "resolved": "https://registry.yarnpkg.com/decamelize/-/decamelize-5.0.0.tgz#88358157b010ef133febfd27c18994bd80c6215b", + "integrity": "sha512-U75DcT5hrio3KNtvdULAWnLiAPbFUC4191ldxMmj4FA/mRuBnmDwU0boNfPyFRhnan+Jm+haLeSn3P0afcBn4w==", + "dev": true + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "degenerator": { + "version": "2.2.0", + "resolved": "https://registry.yarnpkg.com/degenerator/-/degenerator-2.2.0.tgz#49e98c11fa0293c5b26edfbb52f15729afcdb254", + "integrity": "sha512-aiQcQowF01RxFI4ZLFMpzyotbQonhNpBao6dkI8JPk5a+hmSjR5ErHp2CQySmQe8os3VBqLCIh87nDBgZXvsmg==", + "dev": true, + "requires": { + "ast-types": "^0.13.2", + "escodegen": "^1.8.1", + "esprima": "^4.0.0" + } + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "dev": true + }, + "diff": { + "version": "5.0.0", + "resolved": "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "dev": true + }, + "difflib": { + "version": "0.2.4", + "resolved": "https://registry.yarnpkg.com/difflib/-/difflib-0.2.4.tgz#b5e30361a6db023176d562892db85940a718f47e", + "integrity": "sha1-teMDYabbAjF21WKJLbhZQKcY9H4=", + "dev": true, + "requires": { + "heap": ">= 0.2.0" + } + }, + "dreamopt": { + "version": "0.6.0", + "resolved": "https://registry.yarnpkg.com/dreamopt/-/dreamopt-0.6.0.tgz#d813ccdac8d39d8ad526775514a13dda664d6b4b", + "integrity": "sha1-2BPM2sjTnYrVJndVFKE92mZNa0s=", + "dev": true, + "requires": { + "wordwrap": ">=0.0.2" + } + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "es5-ext": { + "version": "0.8.2", + "resolved": "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.8.2.tgz#aba8d9e1943a895ac96837a62a39b3f55ecd94ab", + "integrity": "sha1-q6jZ4ZQ6iVrJaDemKjmz9V7NlKs=", + "dev": true + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "escodegen": { + "version": "1.14.3", + "resolved": "https://registry.yarnpkg.com/escodegen/-/escodegen-1.14.3.tgz#4e7b81fba61581dc97582ed78cab7f0e8d63f503", + "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", + "dev": true, + "requires": { + "esprima": "^4.0.1", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "events": { + "version": "1.1.1", + "resolved": "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924", + "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=", + "dev": true + }, + "exit-on-epipe": { + "version": "1.0.1", + "resolved": "https://registry.yarnpkg.com/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz#0bdd92e87d5285d267daa8171d0eb06159689692", + "integrity": "sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw==", + "dev": true + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "file-uri-to-path": { + "version": "2.0.0", + "resolved": "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-2.0.0.tgz#7b415aeba227d575851e0a5b0c640d7656403fba", + "integrity": "sha512-hjPFI8oE/2iQPVe4gbrJ73Pp+Xfub2+WI2LlXDbsaJBwT5wuMh35WNWVYYTpnz895shtwfyutMFLFywpQAFdLg==", + "dev": true + }, + "fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "dev": true + }, + "fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "requires": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "ftp": { + "version": "0.3.10", + "resolved": "https://registry.yarnpkg.com/ftp/-/ftp-0.3.10.tgz#9197d861ad8142f3e63d5a83bfe4c59f7330885d", + "integrity": "sha1-kZfYYa2BQvPmPVqDv+TFn3MwiF0=", + "dev": true, + "requires": { + "readable-stream": "1.1.x", + "xregexp": "2.0.0" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + } + } + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "get-uri": { + "version": "3.0.2", + "resolved": "https://registry.yarnpkg.com/get-uri/-/get-uri-3.0.2.tgz#f0ef1356faabc70e1f9404fa3b66b2ba9bfc725c", + "integrity": "sha512-+5s0SJbGoyiJTZZ2JTpFPLMPSch72KEqGOTvQsBqg0RBWvwhWUSYZFAtz3TPW0GXJuLBJPts1E241iHg+VRfhg==", + "dev": true, + "requires": { + "@tootallnate/once": "1", + "data-uri-to-buffer": "3", + "debug": "4", + "file-uri-to-path": "2", + "fs-extra": "^8.1.0", + "ftp": "^0.3.10" + }, + "dependencies": { + "fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true + } + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "graceful-fs": { + "version": "4.2.6", + "resolved": "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee", + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", + "dev": true + }, + "heap": { + "version": "0.2.6", + "resolved": "https://registry.yarnpkg.com/heap/-/heap-0.2.6.tgz#087e1f10b046932fc8594dd9e6d378afc9d1e5ac", + "integrity": "sha1-CH4fELBGky/IWU3Z5tN4r8nR5aw=", + "dev": true + }, + "http-errors": { + "version": "1.7.3", + "resolved": "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06", + "integrity": "sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + } + }, + "http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "dev": true, + "requires": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + } + }, + "https-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2", + "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "dev": true, + "requires": { + "agent-base": "6", + "debug": "4" + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "ip": { + "version": "1.1.5", + "resolved": "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a", + "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", + "dev": true + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "jmespath": { + "version": "0.15.0", + "resolved": "https://registry.yarnpkg.com/jmespath/-/jmespath-0.15.0.tgz#a3f222a9aae9f966f5d27c796510e28091764217", + "integrity": "sha1-o/Iiqarp+Wb10nx5ZRDigJF2Qhc=", + "dev": true + }, + "json-diff": { + "version": "0.5.4", + "resolved": "https://registry.yarnpkg.com/json-diff/-/json-diff-0.5.4.tgz#7bc8198c441756632aab66c7d9189d365a7a035a", + "integrity": "sha512-q5Xmx9QXNOzOzIlMoYtLrLiu4Jl/Ce2bn0CNcv54PhyH89CI4GWlGVDye8ei2Ijt9R3U+vsWPsXpLUNob8bs8Q==", + "dev": true, + "requires": { + "cli-color": "~0.1.6", + "difflib": "~0.2.1", + "dreamopt": "~0.6.0" + } + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + } + }, + "jsonschema": { + "version": "1.4.0", + "resolved": "https://registry.yarnpkg.com/jsonschema/-/jsonschema-1.4.0.tgz#1afa34c4bc22190d8e42271ec17ac8b3404f87b2", + "integrity": "sha512-/YgW6pRMr6M7C+4o8kS+B/2myEpHCrxO4PEWnqJNBFMjn7EWXqlQ4tGwL6xTHeRplwuZmcAncdvfOad1nT2yMw==", + "dev": true + }, + "lazystream": { + "version": "1.0.0", + "resolved": "https://registry.yarnpkg.com/lazystream/-/lazystream-1.0.0.tgz#f6995fe0f820392f61396be89462407bb77168e4", + "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", + "dev": true, + "requires": { + "readable-stream": "^2.0.5" + } + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "lodash.defaults": { + "version": "4.2.0", + "resolved": "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c", + "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=", + "dev": true + }, + "lodash.difference": { + "version": "4.5.0", + "resolved": "https://registry.yarnpkg.com/lodash.difference/-/lodash.difference-4.5.0.tgz#9ccb4e505d486b91651345772885a2df27fd017c", + "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=", + "dev": true + }, + "lodash.flatten": { + "version": "4.4.0", + "resolved": "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f", + "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=", + "dev": true + }, + "lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb", + "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", + "dev": true + }, + "lodash.union": { + "version": "4.6.0", + "resolved": "https://registry.yarnpkg.com/lodash.union/-/lodash.union-4.6.0.tgz#48bb5088409f16f1821666641c44dd1aaae3cd88", + "integrity": "sha1-SLtQiECfFvGCFmZkHETdGqrjzYg=", + "dev": true + }, + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "requires": { + "yallist": "^3.0.2" + } + }, + "md5": { + "version": "2.3.0", + "resolved": "https://registry.yarnpkg.com/md5/-/md5-2.3.0.tgz#c3da9a6aae3a30b46b7b0c349b87b110dc3bda4f", + "integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==", + "dev": true, + "requires": { + "charenc": "0.0.2", + "crypt": "0.0.2", + "is-buffer": "~1.1.6" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true + }, + "netmask": { + "version": "1.0.6", + "resolved": "https://registry.yarnpkg.com/netmask/-/netmask-1.0.6.tgz#20297e89d86f6f6400f250d9f4f6b4c1945fcd35", + "integrity": "sha1-ICl+idhvb2QA8lDZ9Pa0wZRfzTU=", + "dev": true + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "optionator": { + "version": "0.8.3", + "resolved": "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + } + }, + "pac-proxy-agent": { + "version": "4.1.0", + "resolved": "https://registry.yarnpkg.com/pac-proxy-agent/-/pac-proxy-agent-4.1.0.tgz#66883eeabadc915fc5e95457324cb0f0ac78defb", + "integrity": "sha512-ejNgYm2HTXSIYX9eFlkvqFp8hyJ374uDf0Zq5YUAifiSh1D6fo+iBivQZirGvVv8dCYUsLhmLBRhlAYvBKI5+Q==", + "dev": true, + "requires": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4", + "get-uri": "3", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "5", + "pac-resolver": "^4.1.0", + "raw-body": "^2.2.0", + "socks-proxy-agent": "5" + } + }, + "pac-resolver": { + "version": "4.1.0", + "resolved": "https://registry.yarnpkg.com/pac-resolver/-/pac-resolver-4.1.0.tgz#4b12e7d096b255a3b84e53f6831f32e9c7e5fe95", + "integrity": "sha512-d6lf2IrZJJ7ooVHr7BfwSjRO1yKSJMaiiWYSHcrxSIUtZrCa4KKGwcztdkZ/E9LFleJfjoi1yl+XLR7AX24nbQ==", + "dev": true, + "requires": { + "degenerator": "^2.2.0", + "ip": "^1.1.5", + "netmask": "^1.0.6" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, + "printj": { + "version": "1.1.2", + "resolved": "https://registry.yarnpkg.com/printj/-/printj-1.1.2.tgz#d90deb2975a8b9f600fb3a1c94e3f4c53c78a222", + "integrity": "sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ==", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "promptly": { + "version": "3.2.0", + "resolved": "https://registry.yarnpkg.com/promptly/-/promptly-3.2.0.tgz#a5517fbbf59bd31c1751d4e1d9bef1714f42b9d8", + "integrity": "sha512-WnR9obtgW+rG4oUV3hSnNGl1pHm3V1H/qD9iJBumGSmVsSC5HpZOLuu8qdMb6yCItGfT7dcRszejr/5P3i9Pug==", + "dev": true, + "requires": { + "read": "^1.0.4" + } + }, + "proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.yarnpkg.com/proxy-agent/-/proxy-agent-4.0.1.tgz#326c3250776c7044cd19655ccbfadf2e065a045c", + "integrity": "sha512-ODnQnW2jc/FUVwHHuaZEfN5otg/fMbvMxz9nMSUQfJ9JU7q2SZvSULSsjLloVgJOiv9yhc8GlNMKc4GkFmcVEA==", + "dev": true, + "requires": { + "agent-base": "^6.0.0", + "debug": "4", + "http-proxy-agent": "^4.0.0", + "https-proxy-agent": "^5.0.0", + "lru-cache": "^5.1.1", + "pac-proxy-agent": "^4.1.0", + "proxy-from-env": "^1.0.0", + "socks-proxy-agent": "^5.0.0" + } + }, + "proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "dev": true + }, + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", + "dev": true + }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "dev": true + }, + "raw-body": { + "version": "2.4.1", + "resolved": "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.1.tgz#30ac82f98bb5ae8c152e67149dac8d55153b168c", + "integrity": "sha512-9WmIKF6mkvA0SLmA2Knm9+qj89e+j1zqgyn8aXGd7+nAduPoqgI9lO57SAZNn/Byzo5P7JhXTyg9PzaJbH73bA==", + "dev": true, + "requires": { + "bytes": "3.1.0", + "http-errors": "1.7.3", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + } + }, + "read": { + "version": "1.0.7", + "resolved": "https://registry.yarnpkg.com/read/-/read-1.0.7.tgz#b3da19bd052431a97671d44a42634adf710b40c4", + "integrity": "sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ=", + "dev": true, + "requires": { + "mute-stream": "~0.0.4" + } + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "readdir-glob": { + "version": "1.1.1", + "resolved": "https://registry.yarnpkg.com/readdir-glob/-/readdir-glob-1.1.1.tgz#f0e10bb7bf7bfa7e0add8baffdc54c3f7dbee6c4", + "integrity": "sha512-91/k1EzZwDx6HbERR+zucygRFfiPl2zkIYZtv3Jjr6Mn7SkKcVct8aVO+sSRiGMc6fLf72du3d92/uY63YPdEA==", + "dev": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "sax": { + "version": "1.2.1", + "resolved": "https://registry.yarnpkg.com/sax/-/sax-1.2.1.tgz#7b8e656190b228e81a66aea748480d828cd2d37a", + "integrity": "sha1-e45lYZCyKOgaZq6nSEgNgozS03o=", + "dev": true + }, + "semver": { + "version": "7.3.4", + "resolved": "https://registry.yarnpkg.com/semver/-/semver-7.3.4.tgz#27aaa7d2e4ca76452f98d3add093a72c943edc97", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } + }, + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", + "dev": true + }, + "slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + } + }, + "smart-buffer": { + "version": "4.1.0", + "resolved": "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.1.0.tgz#91605c25d91652f4661ea69ccf45f1b331ca21ba", + "integrity": "sha512-iVICrxOzCynf/SNaBQCw34eM9jROU/s5rzIhpOvzhzuYHfJR/DhZfDkXiZSgKXfgv26HT3Yni3AV/DGw0cGnnw==", + "dev": true + }, + "socks": { + "version": "2.5.1", + "resolved": "https://registry.yarnpkg.com/socks/-/socks-2.5.1.tgz#7720640b6b5ec9a07d556419203baa3f0596df5f", + "integrity": "sha512-oZCsJJxapULAYJaEYBSzMcz8m3jqgGrHaGhkmU/o/PQfFWYWxkAaA0UMGImb6s6tEXfKi959X6VJjMMQ3P6TTQ==", + "dev": true, + "requires": { + "ip": "^1.1.5", + "smart-buffer": "^4.1.0" + } + }, + "socks-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-5.0.0.tgz#7c0f364e7b1cf4a7a437e71253bed72e9004be60", + "integrity": "sha512-lEpa1zsWCChxiynk+lCycKuC502RxDWLKJZoIhnxrWNjLSDGYRFflHA1/228VkRcnv9TIb8w98derGbpKxJRgA==", + "dev": true, + "requires": { + "agent-base": "6", + "debug": "4", + "socks": "^2.3.3" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "dev": true + }, + "string-width": { + "version": "4.2.2", + "resolved": "https://registry.yarnpkg.com/string-width/-/string-width-4.2.2.tgz#dafd4f9559a7585cfba529c6a0a4f73488ebd4c5", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "table": { + "version": "6.0.7", + "resolved": "https://registry.yarnpkg.com/table/-/table-6.0.7.tgz#e45897ffbcc1bcf9e8a87bf420f2c9e5a7a52a34", + "integrity": "sha512-rxZevLGTUzWna/qBLObOe16kB2RTnnbhciwgPbMMlazz1yZGVEgnZK762xyVdVznhqxrfCeBMmMkgOOaPwjH7g==", + "dev": true, + "requires": { + "ajv": "^7.0.2", + "lodash": "^4.17.20", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.0" + } + }, + "tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, + "requires": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "requires": { + "safe-buffer": "~5.2.0" + } + } + } + }, + "toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", + "dev": true + }, + "tslib": { + "version": "2.1.0", + "resolved": "https://registry.yarnpkg.com/tslib/-/tslib-2.1.0.tgz#da60860f1c2ecaa5703ab7d39bc05b6bf988b97a", + "integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==", + "dev": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2" + } + }, + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "dev": true + }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + }, + "dependencies": { + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + } + } + }, + "url": { + "version": "0.10.3", + "resolved": "https://registry.yarnpkg.com/url/-/url-0.10.3.tgz#021e4d9c7705f21bbf37d03ceb58767402774c64", + "integrity": "sha1-Ah5NnHcF8hu/N9A861h2dAJ3TGQ=", + "dev": true, + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true + }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true + }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "xml2js": { + "version": "0.4.19", + "resolved": "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.19.tgz#686c20f213209e94abf0d1bcf1efaa291c7827a7", + "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==", + "dev": true, + "requires": { + "sax": ">=0.6.0", + "xmlbuilder": "~9.0.1" + }, + "dependencies": { + "sax": { + "version": "1.2.4", + "resolved": "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "dev": true + } + } + }, + "xmlbuilder": { + "version": "9.0.7", + "resolved": "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d", + "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=", + "dev": true + }, + "xregexp": { + "version": "2.0.0", + "resolved": "https://registry.yarnpkg.com/xregexp/-/xregexp-2.0.0.tgz#52a63e56ca0b84a7f3a5f3d61872f126ad7a5943", + "integrity": "sha1-UqY+VsoLhKfzpfPWGHLxJq16WUM=", + "dev": true + }, + "y18n": { + "version": "5.0.5", + "resolved": "https://registry.yarnpkg.com/y18n/-/y18n-5.0.5.tgz#8769ec08d03b1ea2df2500acef561743bbb9ab18", + "integrity": "sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg==", + "dev": true + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "yaml": { + "version": "1.10.0", + "resolved": "https://registry.yarnpkg.com/yaml/-/yaml-1.10.0.tgz#3b593add944876077d4d683fee01081bd9fff31e", + "integrity": "sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg==", + "dev": true + }, + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + } + }, + "yargs-parser": { + "version": "20.2.6", + "resolved": "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.6.tgz#69f920addf61aafc0b8b89002f5d66e28f2d8b20", + "integrity": "sha512-AP1+fQIWSM/sMiET8fyayjx/J+JmTPt2Mr0FkrgqB4todtfa53sOsrSAcIrJRD5XS20bKUwaDIuMkWKCEiQLKA==", + "dev": true + }, + "zip-stream": { + "version": "4.1.0", + "resolved": "https://registry.yarnpkg.com/zip-stream/-/zip-stream-4.1.0.tgz#51dd326571544e36aa3f756430b313576dc8fc79", + "integrity": "sha512-zshzwQW7gG7hjpBlgeQP9RuyPGNxvJdzR8SUM3QhxCnLjWN2E7j3dOvpeDcQoETfHx0urRS7EtmVToql7YpU4A==", + "dev": true, + "requires": { + "archiver-utils": "^2.1.0", + "compress-commons": "^4.1.0", + "readable-stream": "^3.6.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "requires": { + "safe-buffer": "~5.2.0" + } + } + } + } + } + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "dev": true + }, + "aws4": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", + "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", + "dev": true + }, + "babel-jest": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-26.6.3.tgz", + "integrity": "sha512-pl4Q+GAVOHwvjrck6jKjvmGhnO3jHX/xuB9d27f+EJZ/6k+6nMuPjorrYp7s++bKKdANwzElBWnLWaObvTnaZA==", + "dev": true, + "requires": { + "@jest/transform": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/babel__core": "^7.1.7", + "babel-plugin-istanbul": "^6.0.0", + "babel-preset-jest": "^26.6.2", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "slash": "^3.0.0" + } + }, + "babel-plugin-istanbul": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz", + "integrity": "sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^4.0.0", + "test-exclude": "^6.0.0" + } + }, + "babel-plugin-jest-hoist": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.6.2.tgz", + "integrity": "sha512-PO9t0697lNTmcEHH69mdtYiOIkkOlj9fySqfO3K1eCcdISevLAE0xY59VLLUj0SoiPiTX/JU2CYFpILydUa5Lw==", + "dev": true, + "requires": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.0.0", + "@types/babel__traverse": "^7.0.6" + } + }, + "babel-preset-current-node-syntax": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", + "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", + "dev": true, + "requires": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.8.3" + } + }, + "babel-preset-jest": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-26.6.2.tgz", + "integrity": "sha512-YvdtlVm9t3k777c5NPQIv6cxFFFapys25HiUmuSgHwIZhfifweR5c5Sf5nwE3MAbfu327CYSvps8Yx6ANLyleQ==", + "dev": true, + "requires": { + "babel-plugin-jest-hoist": "^26.6.2", + "babel-preset-current-node-syntax": "^1.0.0" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "browser-process-hrtime": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", + "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", + "dev": true + }, + "browserslist": { + "version": "4.16.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.3.tgz", + "integrity": "sha512-vIyhWmIkULaq04Gt93txdh+j02yX/JzlyhLYbV3YQCn/zvES3JnY7TifHHvvr1w5hTDluNKMkV05cs4vy8Q7sw==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001181", + "colorette": "^1.2.1", + "electron-to-chromium": "^1.3.649", + "escalade": "^3.1.1", + "node-releases": "^1.1.70" + } + }, + "bs-logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", + "dev": true, + "requires": { + "fast-json-stable-stringify": "2.x" + } + }, + "bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dev": true, + "requires": { + "node-int64": "^0.4.0" + } + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "requires": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "caniuse-lite": { + "version": "1.0.30001200", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001200.tgz", + "integrity": "sha512-ic/jXfa6tgiPBAISWk16jRI2q8YfjxHnSG7ddSL1ptrIP8Uy11SayFrjXRAk3NumHpDb21fdTkbTxb/hOrFrnQ==", + "dev": true + }, + "capture-exit": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz", + "integrity": "sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==", + "dev": true, + "requires": { + "rsvp": "^4.8.4" + } + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true + }, + "charenc": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", + "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=", + "dev": true + }, + "ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "cjs-module-lexer": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-0.6.0.tgz", + "integrity": "sha512-uc2Vix1frTfnuzxxu1Hp4ktSvM3QaI4oXl4ZUqL1wjTu/BGki9TrCWoqLTg/drR1KwAEarXuRFCG2Svr1GxPFw==", + "dev": true + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true + }, + "collect-v8-coverage": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", + "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", + "dev": true + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "colorette": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", + "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==", + "dev": true + }, + "colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "dev": true + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "constructs": { + "version": "3.3.65", + "resolved": "https://registry.npmjs.org/constructs/-/constructs-3.3.65.tgz", + "integrity": "sha512-/tjHzxwK4Nz9SAm40kkC2mij3Y3LngVVj/dvk7Xpex25/PMhVRYy1pmJ0/5I5Y6bAMG1HRjcSAyf4k9YZyxJjw==" + }, + "convert-source-map": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + } + }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "crypt": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", + "integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=", + "dev": true + }, + "cssom": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", + "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", + "dev": true + }, + "cssstyle": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "dev": true, + "requires": { + "cssom": "~0.3.6" + }, + "dependencies": { + "cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", + "dev": true + } + } + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "data-urls": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", + "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", + "dev": true, + "requires": { + "abab": "^2.0.3", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0" + } + }, + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "decimal.js": { + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.2.1.tgz", + "integrity": "sha512-KaL7+6Fw6i5A2XSnsbhm/6B+NuEA7TZ4vqxnd5tXz9sbKtrN9Srj8ab4vKVdK8YAqZO9P1kg45Y6YLoduPf+kw==", + "dev": true + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "dev": true + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true + }, + "detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true + }, + "diff": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "dev": true + }, + "diff-sequences": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", + "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", + "dev": true + }, + "domexception": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", + "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", + "dev": true, + "requires": { + "webidl-conversions": "^5.0.0" + }, + "dependencies": { + "webidl-conversions": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", + "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", + "dev": true + } + } + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "electron-to-chromium": { + "version": "1.3.688", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.688.tgz", + "integrity": "sha512-tbKinYX7BomVBcWHzwGolzv3kqCdk/vQ36ao3MC8tQMXqs1ZpevYU2RTr7+hkDvGWtoQbe+nvvl+GfMFmRna/A==", + "dev": true + }, + "emittery": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.7.2.tgz", + "integrity": "sha512-A8OG5SR/ij3SsJdWDJdkkSYUjQdCUx6APQXem0SaEePBSRg4eymGYwBkKo1Y6DU+af/Jn2dBQqDBvjnr9Vi8nQ==", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "escodegen": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", + "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", + "dev": true, + "requires": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "exec-sh": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.4.tgz", + "integrity": "sha512-sEFIkc61v75sWeOe72qyrqg2Qg0OuLESziUDk/O/z2qgS15y2gWVFrI6f2Qn/qw/0/NCfCEsmNA4zOjkwEZT1A==", + "dev": true + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "dev": true + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "expect": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", + "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "ansi-styles": "^4.0.0", + "jest-get-type": "^26.3.0", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-regex-util": "^26.0.0" + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "fb-watchman": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", + "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", + "dev": true, + "requires": { + "bser": "2.1.1" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true + }, + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "requires": { + "map-cache": "^0.2.2" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, + "graceful-fs": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", + "dev": true + }, + "growly": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", + "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", + "dev": true, + "optional": true + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true + }, + "har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "dev": true, + "requires": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + }, + "dependencies": { + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + } + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "hosted-git-info": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", + "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", + "dev": true + }, + "html-encoding-sniffer": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", + "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", + "dev": true, + "requires": { + "whatwg-encoding": "^1.0.5" + } + }, + "html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "human-signals": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", + "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", + "dev": true + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "import-local": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", + "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==", + "dev": true, + "requires": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "dev": true, + "requires": { + "ci-info": "^2.0.0" + } + }, + "is-core-module": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz", + "integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "is-docker": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.1.1.tgz", + "integrity": "sha512-ZOoqiXfEwtGknTiuDEy8pN2CfE3TxMHprvNer1mXiqwkOT77Rw3YVrUQ52EqAOU3QAWDQ+bQdx7HJzrv7LS2Hw==", + "dev": true, + "optional": true + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "dev": true + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "is-potential-custom-element-name": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.0.tgz", + "integrity": "sha1-DFLlS8yjkbssSUsh6GJtczbG45c=", + "dev": true + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true + }, + "is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "optional": true, + "requires": { + "is-docker": "^2.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true + }, + "istanbul-lib-coverage": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", + "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==", + "dev": true + }, + "istanbul-lib-instrument": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", + "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "dev": true, + "requires": { + "@babel/core": "^7.7.5", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.0", + "semver": "^6.3.0" + } + }, + "istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "dev": true, + "requires": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + } + }, + "istanbul-lib-source-maps": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", + "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + } + }, + "istanbul-reports": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", + "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", + "dev": true, + "requires": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + } + }, + "jest": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest/-/jest-26.6.3.tgz", + "integrity": "sha512-lGS5PXGAzR4RF7V5+XObhqz2KZIDUA1yD0DG6pBVmy10eh0ZIXQImRuzocsI/N2XZ1GrLFwTS27In2i2jlpq1Q==", + "dev": true, + "requires": { + "@jest/core": "^26.6.3", + "import-local": "^3.0.2", + "jest-cli": "^26.6.3" + }, + "dependencies": { + "jest-cli": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-26.6.3.tgz", + "integrity": "sha512-GF9noBSa9t08pSyl3CY4frMrqp+aQXFGFkf5hEPbh/pIUFYWMK6ZLTfbmadxJVcJrdRoChlWQsA2VkJcDFK8hg==", + "dev": true, + "requires": { + "@jest/core": "^26.6.3", + "@jest/test-result": "^26.6.2", + "@jest/types": "^26.6.2", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "import-local": "^3.0.2", + "is-ci": "^2.0.0", + "jest-config": "^26.6.3", + "jest-util": "^26.6.2", + "jest-validate": "^26.6.2", + "prompts": "^2.0.1", + "yargs": "^15.4.1" + } + } + } + }, + "jest-changed-files": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-26.6.2.tgz", + "integrity": "sha512-fDS7szLcY9sCtIip8Fjry9oGf3I2ht/QT21bAHm5Dmf0mD4X3ReNUf17y+bO6fR8WgbIZTlbyG1ak/53cbRzKQ==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "execa": "^4.0.0", + "throat": "^5.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "execa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", + "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "human-signals": "^1.1.1", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.0", + "onetime": "^5.1.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + } + }, + "get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "is-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", + "dev": true + }, + "npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "requires": { + "path-key": "^3.0.0" + } + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "jest-config": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz", + "integrity": "sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==", + "dev": true, + "requires": { + "@babel/core": "^7.1.0", + "@jest/test-sequencer": "^26.6.3", + "@jest/types": "^26.6.2", + "babel-jest": "^26.6.3", + "chalk": "^4.0.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.1", + "graceful-fs": "^4.2.4", + "jest-environment-jsdom": "^26.6.2", + "jest-environment-node": "^26.6.2", + "jest-get-type": "^26.3.0", + "jest-jasmine2": "^26.6.3", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.6.2", + "jest-util": "^26.6.2", + "jest-validate": "^26.6.2", + "micromatch": "^4.0.2", + "pretty-format": "^26.6.2" + } + }, + "jest-diff": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", + "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "diff-sequences": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" + } + }, + "jest-docblock": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-26.0.0.tgz", + "integrity": "sha512-RDZ4Iz3QbtRWycd8bUEPxQsTlYazfYn/h5R65Fc6gOfwozFhoImx+affzky/FFBuqISPTqjXomoIGJVKBWoo0w==", + "dev": true, + "requires": { + "detect-newline": "^3.0.0" + } + }, + "jest-each": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-26.6.2.tgz", + "integrity": "sha512-Mer/f0KaATbjl8MCJ+0GEpNdqmnVmDYqCTJYTvoo7rqmRiDllmp2AYN+06F93nXcY3ur9ShIjS+CO/uD+BbH4A==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "chalk": "^4.0.0", + "jest-get-type": "^26.3.0", + "jest-util": "^26.6.2", + "pretty-format": "^26.6.2" + } + }, + "jest-environment-jsdom": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-26.6.2.tgz", + "integrity": "sha512-jgPqCruTlt3Kwqg5/WVFyHIOJHsiAvhcp2qiR2QQstuG9yWox5+iHpU3ZrcBxW14T4fe5Z68jAfLRh7joCSP2Q==", + "dev": true, + "requires": { + "@jest/environment": "^26.6.2", + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2", + "jsdom": "^16.4.0" + } + }, + "jest-environment-node": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-26.6.2.tgz", + "integrity": "sha512-zhtMio3Exty18dy8ee8eJ9kjnRyZC1N4C1Nt/VShN1apyXc8rWGtJ9lI7vqiWcyyXS4BVSEn9lxAM2D+07/Tag==", + "dev": true, + "requires": { + "@jest/environment": "^26.6.2", + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" + } + }, + "jest-get-type": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", + "dev": true + }, + "jest-haste-map": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.6.2.tgz", + "integrity": "sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "@types/graceful-fs": "^4.1.2", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "fsevents": "^2.1.2", + "graceful-fs": "^4.2.4", + "jest-regex-util": "^26.0.0", + "jest-serializer": "^26.6.2", + "jest-util": "^26.6.2", + "jest-worker": "^26.6.2", + "micromatch": "^4.0.2", + "sane": "^4.0.3", + "walker": "^1.0.7" + } + }, + "jest-jasmine2": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-26.6.3.tgz", + "integrity": "sha512-kPKUrQtc8aYwBV7CqBg5pu+tmYXlvFlSFYn18ev4gPFtrRzB15N2gW/Roew3187q2w2eHuu0MU9TJz6w0/nPEg==", + "dev": true, + "requires": { + "@babel/traverse": "^7.1.0", + "@jest/environment": "^26.6.2", + "@jest/source-map": "^26.6.2", + "@jest/test-result": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "expect": "^26.6.2", + "is-generator-fn": "^2.0.0", + "jest-each": "^26.6.2", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-runtime": "^26.6.3", + "jest-snapshot": "^26.6.2", + "jest-util": "^26.6.2", + "pretty-format": "^26.6.2", + "throat": "^5.0.0" + } + }, + "jest-leak-detector": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-26.6.2.tgz", + "integrity": "sha512-i4xlXpsVSMeKvg2cEKdfhh0H39qlJlP5Ex1yQxwF9ubahboQYMgTtz5oML35AVA3B4Eu+YsmwaiKVev9KCvLxg==", + "dev": true, + "requires": { + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" + } + }, + "jest-matcher-utils": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz", + "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "jest-diff": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" + } + }, + "jest-message-util": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", + "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^26.6.2", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "pretty-format": "^26.6.2", + "slash": "^3.0.0", + "stack-utils": "^2.0.2" + } + }, + "jest-mock": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", + "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "@types/node": "*" + } + }, + "jest-pnp-resolver": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", + "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", + "dev": true + }, + "jest-regex-util": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", + "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", + "dev": true + }, + "jest-resolve": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", + "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^26.6.2", + "read-pkg-up": "^7.0.1", + "resolve": "^1.18.1", + "slash": "^3.0.0" + } + }, + "jest-resolve-dependencies": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-26.6.3.tgz", + "integrity": "sha512-pVwUjJkxbhe4RY8QEWzN3vns2kqyuldKpxlxJlzEYfKSvY6/bMvxoFrYYzUO1Gx28yKWN37qyV7rIoIp2h8fTg==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "jest-regex-util": "^26.0.0", + "jest-snapshot": "^26.6.2" + } + }, + "jest-runner": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-26.6.3.tgz", + "integrity": "sha512-atgKpRHnaA2OvByG/HpGA4g6CSPS/1LK0jK3gATJAoptC1ojltpmVlYC3TYgdmGp+GLuhzpH30Gvs36szSL2JQ==", + "dev": true, + "requires": { + "@jest/console": "^26.6.2", + "@jest/environment": "^26.6.2", + "@jest/test-result": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.7.1", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "jest-config": "^26.6.3", + "jest-docblock": "^26.0.0", + "jest-haste-map": "^26.6.2", + "jest-leak-detector": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-resolve": "^26.6.2", + "jest-runtime": "^26.6.3", + "jest-util": "^26.6.2", + "jest-worker": "^26.6.2", + "source-map-support": "^0.5.6", + "throat": "^5.0.0" + } + }, + "jest-runtime": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.6.3.tgz", + "integrity": "sha512-lrzyR3N8sacTAMeonbqpnSka1dHNux2uk0qqDXVkMv2c/A3wYnvQ4EXuI013Y6+gSKSCxdaczvf4HF0mVXHRdw==", + "dev": true, + "requires": { + "@jest/console": "^26.6.2", + "@jest/environment": "^26.6.2", + "@jest/fake-timers": "^26.6.2", + "@jest/globals": "^26.6.2", + "@jest/source-map": "^26.6.2", + "@jest/test-result": "^26.6.2", + "@jest/transform": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0", + "cjs-module-lexer": "^0.6.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.4", + "jest-config": "^26.6.3", + "jest-haste-map": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.6.2", + "jest-snapshot": "^26.6.2", + "jest-util": "^26.6.2", + "jest-validate": "^26.6.2", + "slash": "^3.0.0", + "strip-bom": "^4.0.0", + "yargs": "^15.4.1" + } + }, + "jest-serializer": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.6.2.tgz", + "integrity": "sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g==", + "dev": true, + "requires": { + "@types/node": "*", + "graceful-fs": "^4.2.4" + } + }, + "jest-snapshot": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.6.2.tgz", + "integrity": "sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0", + "@jest/types": "^26.6.2", + "@types/babel__traverse": "^7.0.4", + "@types/prettier": "^2.0.0", + "chalk": "^4.0.0", + "expect": "^26.6.2", + "graceful-fs": "^4.2.4", + "jest-diff": "^26.6.2", + "jest-get-type": "^26.3.0", + "jest-haste-map": "^26.6.2", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-resolve": "^26.6.2", + "natural-compare": "^1.4.0", + "pretty-format": "^26.6.2", + "semver": "^7.3.2" + }, + "dependencies": { + "semver": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, + "jest-util": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "micromatch": "^4.0.2" + } + }, + "jest-validate": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.6.2.tgz", + "integrity": "sha512-NEYZ9Aeyj0i5rQqbq+tpIOom0YS1u2MVu6+euBsvpgIme+FOfRmoC4R5p0JiAUpaFvFy24xgrpMknarR/93XjQ==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "camelcase": "^6.0.0", + "chalk": "^4.0.0", + "jest-get-type": "^26.3.0", + "leven": "^3.1.0", + "pretty-format": "^26.6.2" + }, + "dependencies": { + "camelcase": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", + "dev": true + } + } + }, + "jest-watcher": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-26.6.2.tgz", + "integrity": "sha512-WKJob0P/Em2csiVthsI68p6aGKTIcsfjH9Gsx1f0A3Italz43e3ho0geSAVsmj09RWOELP1AZ/DXyJgOgDKxXQ==", + "dev": true, + "requires": { + "@jest/test-result": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "jest-util": "^26.6.2", + "string-length": "^4.0.1" + } + }, + "jest-worker": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", + "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", + "dev": true, + "requires": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true + }, + "jsdom": { + "version": "16.5.1", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.5.1.tgz", + "integrity": "sha512-pF73EOsJgwZekbDHEY5VO/yKXUkab/DuvrQB/ANVizbr6UAHJsDdHXuotZYwkJSGQl1JM+ivXaqY+XBDDL4TiA==", + "dev": true, + "requires": { + "abab": "^2.0.5", + "acorn": "^8.0.5", + "acorn-globals": "^6.0.0", + "cssom": "^0.4.4", + "cssstyle": "^2.3.0", + "data-urls": "^2.0.0", + "decimal.js": "^10.2.1", + "domexception": "^2.0.1", + "escodegen": "^2.0.0", + "html-encoding-sniffer": "^2.0.1", + "is-potential-custom-element-name": "^1.0.0", + "nwsapi": "^2.2.0", + "parse5": "6.0.1", + "request": "^2.88.2", + "request-promise-native": "^1.0.9", + "saxes": "^5.0.1", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.0.0", + "w3c-hr-time": "^1.0.2", + "w3c-xmlserializer": "^2.0.0", + "webidl-conversions": "^6.1.0", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0", + "ws": "^7.4.4", + "xml-name-validator": "^3.0.0" + } + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, + "json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "dev": true + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, + "json5": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "dev": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true + }, + "kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true + }, + "leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "lines-and-columns": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", + "dev": true + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", + "dev": true + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "requires": { + "semver": "^6.0.0" + } + }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "makeerror": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", + "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=", + "dev": true, + "requires": { + "tmpl": "1.0.x" + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "requires": { + "object-visit": "^1.0.0" + } + }, + "md5": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz", + "integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==", + "dev": true, + "requires": { + "charenc": "0.0.2", + "crypt": "0.0.2", + "is-buffer": "~1.1.6" + } + }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, + "mime-db": { + "version": "1.46.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.46.0.tgz", + "integrity": "sha512-svXaP8UQRZ5K7or+ZmfNhg2xX3yKDMUzqadsSqi4NCH/KomcH75MAMYAGVlvXn4+b/xOPhS3I2uHKRUzvjY7BQ==", + "dev": true + }, + "mime-types": { + "version": "2.1.29", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.29.tgz", + "integrity": "sha512-Y/jMt/S5sR9OaqteJtslsFZKWOIIqMACsJSiHghlCAyhf7jfVYjKBmLiX8OgpWeW+fjJ2b+Az69aPFPkUOY6xQ==", + "dev": true, + "requires": { + "mime-db": "1.46.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "dev": true, + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + } + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", + "dev": true + }, + "node-modules-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", + "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", + "dev": true + }, + "node-notifier": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-8.0.2.tgz", + "integrity": "sha512-oJP/9NAdd9+x2Q+rfphB2RJCHjod70RcRLjosiPMMu5gjIfwVnOUGq2nbTjTUbmy0DJ/tFIVT30+Qe3nzl4TJg==", + "dev": true, + "optional": true, + "requires": { + "growly": "^1.3.0", + "is-wsl": "^2.2.0", + "semver": "^7.3.2", + "shellwords": "^0.1.1", + "uuid": "^8.3.0", + "which": "^2.0.2" + }, + "dependencies": { + "semver": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "dev": true, + "optional": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "optional": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "node-releases": { + "version": "1.1.71", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.71.tgz", + "integrity": "sha512-zR6HoT6LrLCRBwukmrVbHv0EpEQjksO6GmFcZQQuCAy139BEsoVKPYnf3jongYW83fAa1torLGYwxxky/p28sg==", + "dev": true + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "requires": { + "path-key": "^2.0.0" + } + }, + "nwsapi": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", + "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", + "dev": true + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dev": true, + "requires": { + "isobject": "^3.0.0" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + } + }, + "p-each-series": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-2.2.0.tgz", + "integrity": "sha512-ycIL2+1V32th+8scbpTvyHNaHe02z0sjgh91XXjAk+ZeXoPN4Z46DVUnzdso0aX4KckKw0FNNFHdjZ2UsZvxiA==", + "dev": true + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } + }, + "parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", + "dev": true + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true + }, + "picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "dev": true + }, + "pirates": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", + "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", + "dev": true, + "requires": { + "node-modules-regexp": "^1.0.0" + } + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + } + }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "dev": true + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, + "pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + } + }, + "prompts": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.0.tgz", + "integrity": "sha512-awZAKrk3vN6CroQukBL+R9051a4R3zCZBlJm/HBfrSZ8iTpYix3VX1vU4mveiLpiwmOJT4wokTF9m6HUk4KqWQ==", + "dev": true, + "requires": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + } + }, + "psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", + "dev": true + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true + }, + "react-is": { + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.1.tgz", + "integrity": "sha512-NAnt2iGDXohE5LI7uBnLnqvLQMtzhkiAOLXTmv+qnF9Ky7xAPcX8Up/xWIhxvLVGJvuLiNc4xQLtuqDRzb4fSA==", + "dev": true + }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true + } + } + }, + "read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "requires": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + } + }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "repeat-element": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true + }, + "request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "dev": true, + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "dependencies": { + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true + } + } + }, + "request-promise-core": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz", + "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==", + "dev": true, + "requires": { + "lodash": "^4.17.19" + } + }, + "request-promise-native": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz", + "integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==", + "dev": true, + "requires": { + "request-promise-core": "1.1.4", + "stealthy-require": "^1.1.1", + "tough-cookie": "^2.3.3" + }, + "dependencies": { + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + } + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "resolve": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "dev": true, + "requires": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + } + }, + "resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "requires": { + "resolve-from": "^5.0.0" + } + }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "dev": true + }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "rsvp": { + "version": "4.8.5", + "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", + "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==", + "dev": true + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "requires": { + "ret": "~0.1.10" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "sane": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/sane/-/sane-4.1.0.tgz", + "integrity": "sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA==", + "dev": true, + "requires": { + "@cnakazawa/watch": "^1.0.3", + "anymatch": "^2.0.0", + "capture-exit": "^2.0.0", + "exec-sh": "^0.3.2", + "execa": "^1.0.0", + "fb-watchman": "^2.0.0", + "micromatch": "^3.1.4", + "minimist": "^1.1.1", + "walker": "~1.0.5" + }, + "dependencies": { + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + } + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + } + } + }, + "saxes": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", + "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", + "dev": true, + "requires": { + "xmlchars": "^2.2.0" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "shellwords": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", + "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", + "dev": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", + "dev": true + }, + "sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + } + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "requires": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "requires": { + "kind-of": "^3.2.0" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, + "source-map-resolve": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", + "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "dev": true, + "requires": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "source-map-url": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", + "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", + "dev": true + }, + "spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.7.tgz", + "integrity": "sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ==", + "dev": true + }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "dev": true, + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "stack-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", + "dev": true, + "requires": { + "escape-string-regexp": "^2.0.0" + }, + "dependencies": { + "escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true + } + } + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "stealthy-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", + "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", + "dev": true + }, + "string-length": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.1.tgz", + "integrity": "sha512-PKyXUd0LK0ePjSOnWn34V2uD6acUWev9uy0Ft05k0E8xRW+SKcA0F7eMr7h5xlzfn+4O3N+55rduYyet3Jk+jw==", + "dev": true, + "requires": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + } + }, + "string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true + }, + "strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "supports-hyperlinks": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.1.0.tgz", + "integrity": "sha512-zoE5/e+dnEijk6ASB6/qrK+oYdm2do1hjoLWrqUC/8WEIW1gbxFcKuBof7sW8ArN6e+AYvsE8HBGiVRWL/F5CA==", + "dev": true, + "requires": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + } + }, + "symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true + }, + "table": { + "version": "6.0.7", + "resolved": "https://registry.npmjs.org/table/-/table-6.0.7.tgz", + "integrity": "sha512-rxZevLGTUzWna/qBLObOe16kB2RTnnbhciwgPbMMlazz1yZGVEgnZK762xyVdVznhqxrfCeBMmMkgOOaPwjH7g==", + "dev": true, + "requires": { + "ajv": "^7.0.2", + "lodash": "^4.17.20", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.0" + } + }, + "terminal-link": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", + "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", + "dev": true, + "requires": { + "ansi-escapes": "^4.2.1", + "supports-hyperlinks": "^2.0.0" + } + }, + "test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "requires": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + } + }, + "throat": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", + "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==", + "dev": true + }, + "tmpl": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", + "integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=", + "dev": true + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "tough-cookie": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", + "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", + "dev": true, + "requires": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.1.2" + } + }, + "tr46": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.0.2.tgz", + "integrity": "sha512-3n1qG+/5kg+jrbTzwAykB5yRYtQCTqOGKq5U5PE3b0a1/mzo6snDhjGS0zJVJunO0NrT3Dg1MLy5TjWP/UJppg==", + "dev": true, + "requires": { + "punycode": "^2.1.1" + } + }, + "ts-jest": { + "version": "26.5.3", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-26.5.3.tgz", + "integrity": "sha512-nBiiFGNvtujdLryU7MiMQh1iPmnZ/QvOskBbD2kURiI1MwqvxlxNnaAB/z9TbslMqCsSbu5BXvSSQPc5tvHGeA==", + "dev": true, + "requires": { + "bs-logger": "0.x", + "buffer-from": "1.x", + "fast-json-stable-stringify": "2.x", + "jest-util": "^26.1.0", + "json5": "2.x", + "lodash": "4.x", + "make-error": "1.x", + "mkdirp": "1.x", + "semver": "7.x", + "yargs-parser": "20.x" + }, + "dependencies": { + "semver": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "yargs-parser": { + "version": "20.2.7", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.7.tgz", + "integrity": "sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw==", + "dev": true + } + } + }, + "ts-node": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-9.1.1.tgz", + "integrity": "sha512-hPlt7ZACERQGf03M253ytLY3dHbGNGrAq9qIHWUY9XHYl1z7wYngSr3OQ5xmui8o2AaxsONxIzjafLUiWBo1Fg==", + "dev": true, + "requires": { + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "source-map-support": "^0.5.17", + "yn": "3.1.1" + }, + "dependencies": { + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + } + } + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2" + } + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + }, + "typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "requires": { + "is-typedarray": "^1.0.0" + } + }, + "typescript": { + "version": "3.9.9", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.9.tgz", + "integrity": "sha512-kdMjTiekY+z/ubJCATUPlRDl39vXYiMV9iyeMuEuXZh2we6zz80uovNN2WlAxmmdE/Z/YQe+EbOEXB5RHEED3w==", + "dev": true + }, + "union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + } + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dev": true, + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true + } + } + }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "dev": true + }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "dev": true + }, + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true, + "optional": true + }, + "v8-to-istanbul": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-7.1.0.tgz", + "integrity": "sha512-uXUVqNUCLa0AH1vuVxzi+MI4RfxEOKt9pBgKwHbgH7st8Kv2P1m+jvWNnektzBh5QShF3ODgKmUFCf38LnVz1g==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0", + "source-map": "^0.7.3" + }, + "dependencies": { + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true + } + } + }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "w3c-hr-time": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", + "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", + "dev": true, + "requires": { + "browser-process-hrtime": "^1.0.0" + } + }, + "w3c-xmlserializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", + "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", + "dev": true, + "requires": { + "xml-name-validator": "^3.0.0" + } + }, + "walker": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz", + "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=", + "dev": true, + "requires": { + "makeerror": "1.0.x" + } + }, + "webidl-conversions": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", + "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", + "dev": true + }, + "whatwg-encoding": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", + "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", + "dev": true, + "requires": { + "iconv-lite": "0.4.24" + } + }, + "whatwg-mimetype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", + "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", + "dev": true + }, + "whatwg-url": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.4.0.tgz", + "integrity": "sha512-vwTUFf6V4zhcPkWp/4CQPr1TW9Ml6SF4lVyaIMBdJw5i6qUUJ1QWM4Z6YYVkfka0OUIzVo/0aNtGVGk256IKWw==", + "dev": true, + "requires": { + "lodash.sortby": "^4.7.0", + "tr46": "^2.0.2", + "webidl-conversions": "^6.1.0" + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true + }, + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "ws": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.4.tgz", + "integrity": "sha512-Qm8k8ojNQIMx7S+Zp8u/uHOx7Qazv3Yv4q68MiWWWOJhiwG5W3x7iqmRtJo8xxrciZUY4vRxUTJCKuRnF28ZZw==", + "dev": true + }, + "xml-name-validator": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", + "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", + "dev": true + }, + "xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true + }, + "y18n": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", + "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==", + "dev": true + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "dev": true, + "requires": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + } + }, + "yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true + } + } +} diff --git a/src/aws-genomics-cdk/package.json b/src/aws-genomics-cdk/package.json new file mode 100644 index 000000000..613a8ab2f --- /dev/null +++ b/src/aws-genomics-cdk/package.json @@ -0,0 +1,31 @@ +{ + "name": "aws-genomics-cdk", + "version": "0.1.0", + "bin": { + "aws-genomics-cdk": "bin/aws-genomics-cdk.js" + }, + "scripts": { + "build": "tsc", + "watch": "tsc -w", + "test": "jest", + "cdk": "cdk" + }, + "devDependencies": { + "@aws-cdk/assert": "1.93.0", + "@types/jest": "^26.0.10", + "@types/node": "10.17.27", + "jest": "^26.4.2", + "ts-jest": "^26.2.0", + "aws-cdk": "1.93.0", + "ts-node": "^9.0.0", + "typescript": "~3.9.7" + }, + "dependencies": { + "@aws-cdk/aws-batch": "^1.93.0", + "@aws-cdk/aws-ec2": "^1.93.0", + "@aws-cdk/aws-stepfunctions": "^1.93.0", + "@aws-cdk/aws-stepfunctions-tasks": "^1.93.0", + "@aws-cdk/core": "1.93.0", + "source-map-support": "^0.5.16" + } +} diff --git a/src/aws-genomics-cdk/test/aws-genomics-cdk.test.ts b/src/aws-genomics-cdk/test/aws-genomics-cdk.test.ts new file mode 100644 index 000000000..76d2138b2 --- /dev/null +++ b/src/aws-genomics-cdk/test/aws-genomics-cdk.test.ts @@ -0,0 +1,13 @@ +import { expect as expectCDK, matchTemplate, MatchStyle } from '@aws-cdk/assert'; +import * as cdk from '@aws-cdk/core'; +import * as AwsGenomicsCdk from '../lib/aws-genomics-cdk-stack'; + +test('Empty Stack', () => { + const app = new cdk.App(); + // WHEN + const stack = new AwsGenomicsCdk.AwsGenomicsCdkStack(app, 'MyTestStack'); + // THEN + expectCDK(stack).to(matchTemplate({ + "Resources": {} + }, MatchStyle.EXACT)) +}); diff --git a/src/aws-genomics-cdk/tsconfig.json b/src/aws-genomics-cdk/tsconfig.json new file mode 100644 index 000000000..19a2f2a52 --- /dev/null +++ b/src/aws-genomics-cdk/tsconfig.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + "target": "ES2018", + "module": "commonjs", + "lib": ["es2018"], + "declaration": true, + "strict": true, + "noImplicitAny": true, + "strictNullChecks": true, + "noImplicitThis": true, + "alwaysStrict": true, + "noUnusedLocals": false, + "noUnusedParameters": false, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": false, + "inlineSourceMap": true, + "inlineSources": true, + "experimentalDecorators": true, + "strictPropertyInitialization": false, + "typeRoots": ["./node_modules/@types"], + "resolveJsonModule": true + }, + "exclude": ["cdk.out"] +} From 660d04424d8212dc80fdf6085b8b81033315dfa7 Mon Sep 17 00:00:00 2001 From: Itzik Paz Date: Tue, 16 Mar 2021 20:07:40 +0000 Subject: [PATCH 02/20] CDK instructions --- src/aws-genomics-cdk/README.md | 150 ++++++++++++++++++++++++++++++--- 1 file changed, 140 insertions(+), 10 deletions(-) diff --git a/src/aws-genomics-cdk/README.md b/src/aws-genomics-cdk/README.md index 324766518..a51783607 100644 --- a/src/aws-genomics-cdk/README.md +++ b/src/aws-genomics-cdk/README.md @@ -1,14 +1,144 @@ -# Welcome to your CDK TypeScript project! +# Genomics Workflows on AWS - CDK code -This is a blank project for TypeScript development with CDK. +Contained herein is a CDK application for creating AWS resources for working with large-scale biomedical data - e.g. genomics. -The `cdk.json` file tells the CDK Toolkit how to execute your app. +In order to deploy this CDK application, you'll need an environment with AWS CLI access and AWS CDK installed. A quick +way yo get an environment for running this application is to launch [AWS Cloud9](https://aws.amazon.com/cloud9/). -## Useful commands +AWS Cloud9 is a cloud-based integrated development environment (IDE) that lets you write, run, and debug your code +with just a browser. It includes a code editor, debugger, and terminal. Cloud9 comes prepackaged with essential +tools for popular programming languages, including JavaScript, Python, PHP, and more, so you don’t need to install +files or configure your development machine to start new projects. + + +## Download + +Clone the repo to your local environment / Cloud9 environment. +``` +git clone https://github.com/aws-samples/aws-genomics-workflows.git +``` + +## Configure + +This CDK application requires an S3 bucket and a VPC. The application can create them as part of the deployment or +you could configure the application to use your own S3 bucket and/or existing VPC. + +After cloning the repo, open, update, and save the application configuration file - `app.config.json`. + +**accountID** - Your [AWS account id](https://docs.aws.amazon.com/IAM/latest/UserGuide/console_account-alias.html). +**region** - The [AWS region](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html) +you want to use for the deployment (e.g., us-east-1, us-west-2, etc.). +**S3.existingBucket** - If you want to use an existing bucket, set this value to true, otherwise set it to false to +create a new bucket. +**S3.bucketName** - The bucket name to use or create. +**VPC.createVPC** - If you want to create a new VPC, set this to true, otherwise set to false. +**VPC.existingVPCName** - If you set the createVPC option to false, you must provide a valid VPC name to use in the +same region of the deployment. +**VPC.maxAZs** - The amount of availability zones to use when creating a new VPC. +**VPC.cidr** - The [CIDR block](https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing) for the new VPC. +**VPC.cidrMask** - The [CIDR block subnet mask](https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing#Subnet_masks) +for the new VPC. +**batch.defaultVolumeSize** - The default EBS volume size in GiB to be attached to the EC2 instance under AWS Batch. +**batch.spotMaxVCPUs** - The limit on vcpus when using [spot instances](https://aws.amazon.com/ec2/spot/). +**batch.onDemendMaxVCPUs** - The limit on vcpus when using on-demand instances. +**batch.instanceTypes** - The [EC2 instance types](https://aws.amazon.com/ec2/instance-types/) to use in AWS Batch. +**stepFunctions.launchDemoPipeline** - If set to true, the application will deploy a demo pipeline using step fuinctions. +**stepFunctions.jobDefinitions** - List of parametrs for the demo application bioinformatics tools. +``` +{ + "accountID": "111111111111", + "region": "us-west-2", + "S3": { + "existingBucket": true, + "bucketName": "" + }, + "VPC": { + "createVPC": true, + "existingVPCName": "", + "maxAZs": 2, + "cidr": "10.0.0.0/16", + "cidrMask": 24 + }, + "batch": { + "defaultVolumeSize": 100, + "spotMaxVCPUs": 128, + "onDemendMaxVCPUs": 128, + "instanceTypes": [ + "c4.large", + "c4.xlarge", + "c4.2xlarge", + "c4.4xlarge", + "c4.8xlarge", + "c5.large", + "c5.xlarge", + "c5.2xlarge", + "c5.4xlarge", + "c5.9xlarge", + "c5.12xlarge", + "c5.18xlarge", + "c5.24xlarge" + ] + }, + "stepFunctions": { + "launchDemoPipeline": true, + "jobDefinitions": { + "fastqc": { + "repository": "genomics/fastqc", + "memoryLimit": 8000, + "vcpus": 4, + "spot": true, + "retryAttempts":1, + "timeout": 600 + }, + "minimap2": { + "repository": "genomics/minimap2", + "memoryLimit": 16000, + "vcpus": 8, + "spot": true, + "retryAttempts":1, + "timeout": 3600 + } + } + } +} +``` + +## Deploy + +To deploy the CDK application, use the command line and make sure you are in the root folder of the CDK application. +(`src/aws-genomics-cdk`). +First install the neccessary node.js modules +``` +npm install +``` + +Then deploy the application. +``` +# The "--require-approval never" parameter will skip the question to approve specific resouce creation, +# such as IAM roles. You can remove this parameter if you want to be prompted to approve creating these +# resources. +cdk deploy --all --require-approval never +``` + + +## Stacks + +| File | Description | +| :--- | :---------- | +| `lib/aws-genomics-cdk-stack.ts` | The main stack that initialize the rest of the stacks | +| `lib/vpc/vpc-stack.ts` | An optional stack that will launch a VPC | +| `lib/batch/batch-stack.ts` | An AWS Batch stack with 2 comnpute environments (spot and on demand) and 2 queues (default and high priority) | +| `lib/batch/batch-iam-stack.ts` | An IAM stack with roles and policies required for running AWS Batch | +| `lid/step-fuinctions/genomics-state-machine-stack.ts` | A step function demo of running a pipeline | + + +## Constructs + +| File | Description | +| :--- | :---------- | +| `lib/batch/batch-compute-environmnet-construct.ts` | A construct for creating an [AWS Batch compute environment](https://docs.aws.amazon.com/batch/latest/userguide/compute_environments.html) | +| `lib/batch/job-queue-construct.ts` | A construct for creating an [AWS Batch job queue](https://docs.aws.amazon.com/batch/latest/userguide/job_queues.html) | +| `lib/batch/launch-template-construct.ts` | A construct for creating an [EC2 launch template](https://docs.aws.amazon.com/autoscaling/ec2/userguide/LaunchTemplates.html) | +| `lib/step-functions/genomics-task-construct.ts` | A construct for creating a step function task that submits a batch job | +| `lib/step-functions/job-definition-construct.ts` | A construct for creating an [AWS Batch job definition](https://docs.aws.amazon.com/batch/latest/userguide/job_definitions.html) to be used as a task in step functions | - * `npm run build` compile typescript to js - * `npm run watch` watch for changes and compile - * `npm run test` perform the jest unit tests - * `cdk deploy` deploy this stack to your default AWS account/region - * `cdk diff` compare deployed stack with current state - * `cdk synth` emits the synthesized CloudFormation template From 7160346d383d1156143836e08d11432e6581403c Mon Sep 17 00:00:00 2001 From: Itzik Paz Date: Tue, 16 Mar 2021 13:17:53 -0700 Subject: [PATCH 03/20] Delete cdk.context.json --- src/aws-genomics-cdk/cdk.context.json | 63 --------------------------- 1 file changed, 63 deletions(-) delete mode 100644 src/aws-genomics-cdk/cdk.context.json diff --git a/src/aws-genomics-cdk/cdk.context.json b/src/aws-genomics-cdk/cdk.context.json deleted file mode 100644 index b30a2f535..000000000 --- a/src/aws-genomics-cdk/cdk.context.json +++ /dev/null @@ -1,63 +0,0 @@ -{ - "availability-zones:account=549173009724:region=us-west-2": [ - "us-west-2a", - "us-west-2b", - "us-west-2c", - "us-west-2d" - ], - "vpc-provider:account=549173009724:filter.tag:Name=GenomicsPipelineStack/genomics-vpc-stack/genomics-vpc:region=us-west-2:returnAsymmetricSubnets=true": { - "vpcId": "vpc-0e12b34b410ce432d", - "vpcCidrBlock": "10.0.0.0/16", - "availabilityZones": [], - "subnetGroups": [ - { - "name": "public", - "type": "Public", - "subnets": [ - { - "subnetId": "subnet-01f8be5070f8f0c41", - "cidr": "10.0.3.0/24", - "availabilityZone": "us-west-2a", - "routeTableId": "rtb-0db455d5a3da84065" - }, - { - "subnetId": "subnet-0c0e2287b8f96dff9", - "cidr": "10.0.4.0/24", - "availabilityZone": "us-west-2b", - "routeTableId": "rtb-0c5cd45dbc8e33ef7" - }, - { - "subnetId": "subnet-0c2c15f728465a4c2", - "cidr": "10.0.5.0/24", - "availabilityZone": "us-west-2c", - "routeTableId": "rtb-0c2e59776f577a3b7" - } - ] - }, - { - "name": "private", - "type": "Private", - "subnets": [ - { - "subnetId": "subnet-0d82fc3969299134f", - "cidr": "10.0.0.0/24", - "availabilityZone": "us-west-2a", - "routeTableId": "rtb-0d6ddf764ea60615b" - }, - { - "subnetId": "subnet-095bc96659c1f7af4", - "cidr": "10.0.1.0/24", - "availabilityZone": "us-west-2b", - "routeTableId": "rtb-0de1df34a81474cf1" - }, - { - "subnetId": "subnet-013b7a044af9c6542", - "cidr": "10.0.2.0/24", - "availabilityZone": "us-west-2c", - "routeTableId": "rtb-0541671d21b141dc3" - } - ] - } - ] - } -} From cfa359e06858ac8cd654116184914ec789c52da4 Mon Sep 17 00:00:00 2001 From: Itzik Paz Date: Tue, 16 Mar 2021 20:18:18 +0000 Subject: [PATCH 04/20] remove context file --- src/aws-genomics-cdk/.gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/src/aws-genomics-cdk/.gitignore b/src/aws-genomics-cdk/.gitignore index f60797b6a..a194581fd 100644 --- a/src/aws-genomics-cdk/.gitignore +++ b/src/aws-genomics-cdk/.gitignore @@ -6,3 +6,4 @@ node_modules # CDK asset staging directory .cdk.staging cdk.out +cdk.context.json \ No newline at end of file From 7030a121323301348acf74dc2436b42814e50dd6 Mon Sep 17 00:00:00 2001 From: "W. Lee Pang" Date: Thu, 25 Mar 2021 17:34:01 -0700 Subject: [PATCH 05/20] update job queue and compute environment guidance --- docs/core-env/setup-aws-batch.md | 25 ++++++++----------- .../gwfcore/gwfcore-batch.template.yaml | 4 +-- 2 files changed, 12 insertions(+), 17 deletions(-) diff --git a/docs/core-env/setup-aws-batch.md b/docs/core-env/setup-aws-batch.md index c23acced0..643193780 100644 --- a/docs/core-env/setup-aws-batch.md +++ b/docs/core-env/setup-aws-batch.md @@ -46,8 +46,8 @@ A complete AWS Batch environment consists of the following: 1. A Compute Environment that utilizes [EC2 Spot instances](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-spot-instances.html) for cost-effective computing 2. A Compute Environment that utilizes EC2 on-demand (e.g. [public pricing](https://aws.amazon.com/ec2/pricing/on-demand/)) instances for high-priority work that can't risk job interruptions or delays due to insufficient Spot capacity. -3. A default Job Queue that utilizes the Spot compute environment first, but spills over to the on-demand compute environment if defined capacity limits (i.e. Max vCPUs) are reached. -4. A priority Job Queue that leverages the on-demand and Spot CE's (in that order) and has higher priority than the default queue. +3. A default Job Queue that solely utilizes the Spot compute environment. This is for jobs where timeliness isn't a constraint, and can wait for the right instances to become available, as well has handle interruption. It also ensures the most cost savings. +4. A priority Job Queue that leverages the on-demand, and optionally Spot, CE's (in that order) and has higher priority than the default queue. This is for jobs that cannot handle interruption, and need to be executed immediately. ### Automated via CloudFormation @@ -81,7 +81,7 @@ You can create several compute environments to suit your needs. Below we'll cre 6. In the "Service role" drop down, select the `AWSBatchServiceRole` you created previously 7. In the "Instance role" drop down, select the `ecsInstanceRole` you created previously 8. For "Provisioning model" select "On-Demand" -9. "Allowed instance types" will be already populated with "optimal" - which is a mixture of M4, C4, and R4 instances. +9. "Allowed instance types" will be already populated with "optimal" - which is a mixture of M4, C4, and R4 instances. This should be sufficient for demonstration purposes. In a production setting, it is recommended to specify the instance famimlies and sizes most apprioriate for the jobs the CE will support. For the On-Demand CE, selecting newer instance types is beneficial as they tend to have better price per performance. 10. "Allocation strategy" will already be set to `BEST_FIT`. This is recommended for on-demand based compute environments as it ensures the most cost efficiency. 11. In the "Launch template" drop down, select the `genomics-workflow-template` you created previously 12. Set Minimum and Desired vCPUs to 0. @@ -112,7 +112,7 @@ Click on "Create" 6. In the "Service role" drop down, select the `AWSBatchServiceRole` you created previously 7. In the "Instance role" drop down, select the `ecsInstanceRole` you created previously 8. For "Provisioning model" select "Spot" -9. "Allowed instance types" will be already populated with "optimal" - which is a mixture of M4, C4, and R4 instances. +9. "Allowed instance types" will be already populated with "optimal" - which is a mixture of M4, C4, and R4 instances. This should be sufficient for demonstration purposes. In a production setting, it is recommended to specify the instance families and sizes most appropriate for the jobs the CE will support. For the SPOT CE a wider diversity of instance types is recommended to maximize the pools from which capacity can be drawn from. Limiting the size of instances is also recommended to avoid scheduling too many jobs on a SPOT instance that could be interrupted. 10. "Allocation strategy" will already be set to `SPOT_CAPACITY_OPTIMIZED`. This is recommended for Spot based compute environments as it ensures the most compute capacity is available for your jobs. 11. In the "Launch template" drop down, select the `genomics-workflow-template` you created previously 12. Set Minimum and Desired vCPUs to 0. @@ -135,20 +135,18 @@ Job queues can be associated with one or more compute environments in a preferre Below we'll create two job queues: * A "Default" job queue - * A "High Priority" job queue + * A "Priority" job queue Both job queues will use both compute environments you created previously. ##### Create a "default" job queue -This queue is intended for jobs that do not require urgent completion, and can handle potential interruption. This queue will schedule jobs to: +This queue is intended for jobs that do not require urgent completion, and can handle potential interruption. This queue will schedule jobs to only the "spot" compute environment. -1. The "spot" compute environment -2. The "ondemand" compute environment +!!! note + It is not recommended to configure a job queue to "spillover" from Spot to On-Demand. Doing so could lead Insufficient Capacity Errors, resulting in Batch unable to schedule jobs, leaving them stuck in "RUNNABLE" -in that order. - -Because it primarily leverages Spot instances, it will also be the most cost effective job queue. +Because it leverages Spot instances, it will also be the most cost effective job queue. * Go to the AWS Batch Console * Click on "Job queues" @@ -157,8 +155,7 @@ Because it primarily leverages Spot instances, it will also be the most cost eff * Set "Priority" to 1 * Under "Connected compute environments for this queue", using the drop down menu: - 1. Select the "spot" compute environment you created previously, then - 2. Select the "ondemand" compute environment you created previously + 1. Select the "spot" compute environment you created previously * Click on "Create Job Queue" @@ -169,7 +166,7 @@ This queue is intended for jobs that are urgent and **cannot** handle potential 1. The "ondemand" compute environment 2. The "spot" compute environment -in that order. +in that order. In this queue configuration, Batch will schedule jobs to the "ondemand" compute environment first. When the number of Max vCPUs for that environment is reached, Batch will begin scheduling jobs to the "spot" compute environment. The use of the "spot" compute environment is optional, and is used to help drain pending jobs from the queue faster. * Go to the AWS Batch Console * Click on "Job queues" diff --git a/src/templates/gwfcore/gwfcore-batch.template.yaml b/src/templates/gwfcore/gwfcore-batch.template.yaml index 6e1cf7f64..09e649905 100644 --- a/src/templates/gwfcore/gwfcore-batch.template.yaml +++ b/src/templates/gwfcore/gwfcore-batch.template.yaml @@ -256,9 +256,7 @@ Resources: ComputeEnvironmentOrder: - Order: 1 ComputeEnvironment: !Ref SpotComputeEnv - - Order: 2 - ComputeEnvironment: !Ref OnDemandComputeEnv - + ContainerInstanceLogGroup: Type: AWS::Logs::LogGroup Properties: From 2fd1b1e98387b0cabb254893920883c4d2d199ae Mon Sep 17 00:00:00 2001 From: Andrew Crabb Date: Fri, 26 Mar 2021 18:57:19 -0400 Subject: [PATCH 06/20] Add docs Custom Distribution section --- docs/core-env/build-custom-distribution.md | 7 +++ docs/core-env/custom-deploy.md | 58 +++++++++++++++++++++ docs/extra.css | 6 +++ docs/images/custom-deploy-0.png | Bin 0 -> 128666 bytes docs/images/custom-deploy-1.png | Bin 0 -> 96146 bytes docs/images/nextflow-0.png | Bin 0 -> 124111 bytes mkdocs.yml | 2 + 7 files changed, 73 insertions(+) create mode 100644 docs/core-env/build-custom-distribution.md create mode 100644 docs/core-env/custom-deploy.md create mode 100644 docs/images/custom-deploy-0.png create mode 100644 docs/images/custom-deploy-1.png create mode 100644 docs/images/nextflow-0.png diff --git a/docs/core-env/build-custom-distribution.md b/docs/core-env/build-custom-distribution.md new file mode 100644 index 000000000..d38cffb88 --- /dev/null +++ b/docs/core-env/build-custom-distribution.md @@ -0,0 +1,7 @@ +# Building Custom Resources + +This section describes how to build and upload customized templates and artifacts. + +## Building a Custom Distribution + +## Deploying a custom Distribution \ No newline at end of file diff --git a/docs/core-env/custom-deploy.md b/docs/core-env/custom-deploy.md new file mode 100644 index 000000000..926a5c4d9 --- /dev/null +++ b/docs/core-env/custom-deploy.md @@ -0,0 +1,58 @@ +# Customized Templates and Artifacts + +Deployments of the 'Nextflow on AWS Batch' solution are based on nested CloudFormation templates, and on artifacts comprising scripts, software packages, and configuration files. The templates and artifacts are stored in S3 buckets, and their S3 URLs are used when launching the top-level template and as parameters to that template's deployment. + +## VPC +The quick start link deploys the [AWS VPC Quickstart](https://aws.amazon.com/quickstart/architecture/vpc/), which creates a VPC with up to 4 Availability Zones, each with a public subnet and a private subnet with NAT Gateway access to the Internet. + +## Genomics Workflow Core +This quick start link deploys the CloudFormation template `gwfcore-root.template.yaml` for the Genomics Workflow Core (GWFCore) from the [Genomics Workflows on AWS](https://github.com/aws-samples/aws-genomics-workflows) solution. This template launches a number of nested templates, as shown below: + +* Root Stack __gwfcore-root__ - Top level template for Genomics Workflow Core + * S3 Stack __gwfcore-s3__ - S3 bucket (new or existing) for storing analysis results + * IAM Stack __gwfcore-iam__ - Creates IAM roles to use with AWS Batch scalable genomics workflow environment + * Code Stack __gwfcore-code__ - Creates AWS CodeCommit repos and CodeBuild projects for Genomics Workflows Core assets and artifacts + * Launch Template Stack __gwfcore-launch-template__ - Creates an EC2 Launch Template for AWS Batch based genomics workflows + * Batch Stack __gwfcore-batch__ - Deploys resource for a AWS Batch environment that is suitable for genomics, including default and high-priority JobQueues + +### Root Stack +The quick start solution links to the CloudFormation console, where the 'Amazon S3 URL' field is prefilled with the S3 URL of a copy of the root stack template, hosted in the public S3 bucket __aws-genomics-workflows__. + +custom-deploy-0 + +To use a customized root stack, upload your modified stack template to an S3 bucket (see [Building a Custom Distribution](build-custom-distribution.md)), and specify that template's URL in 'Amazon S3 URL'. + +### Artifacts and Nested Stacks +The subsequent screen, 'Specify Stack Details', allows for customization of the deployed resources in the 'Distribution Configuration' section. + +custom-deploy-1 + +* __Artifact S3 Bucket Name__ and __Artifact S3 Prefix__ define the location of the artifacts uploaded prior to this deployment. By default, pre-prepared artifacts are stored in the __aws-genomics-workflows__ bucket. +* __Template Root URL__ defines the bucket and prefix used to store nested templates, called by the root template. + +To use your own modified artifacts or nested templates, build and upload as described in [Building a Custom Distribution](build-custom-distribution.md), and specify the bucket and prefix in the fields above. + +## Workflow Orchestrators +### Nextflow +This quick start deploys the Nextflow template `nextflow-resources.template.yaml`, which launches one nested stack: + +* Root Stack __nextflow-resources__ - Creates resources specific to running Nextflow on AWS + * Container Build Stack __container-build__ - Creates resources for building a Docker container image using CodeBuild, storing the image in ECR, and optionally creating a corresponding Batch Job Definition + +The nextflow root stack is specified in the same way as the GWFCore root stack, above, and a location for a modified root stack may be specified as with the Core stack. + +The subsequent 'Specify Stack Details' screen has fields allowing the customization of the Nextflow deployment. + +nextflow-0 + +* __S3NextflowPrefix__, __S3LogsDirPrefix__, and __S3WorkDirPrefix__ specify the path within the GWFCore bucket in which to store per-run data and log files. +* __TemplateRootUrl__ specifies the path to the nested templates called by the Nextflow root template, as with the GWFCore root stack. diff --git a/docs/extra.css b/docs/extra.css index 5954fd434..4f061952c 100644 --- a/docs/extra.css +++ b/docs/extra.css @@ -57,4 +57,10 @@ .md-header, .md-footer, .md-footer-nav, .md-footer-meta { background-color: #232f3e !important; + } + + .screenshot { + style: "float: left"; + margin: 10px; + border: 1px solid lightgrey; } \ No newline at end of file diff --git a/docs/images/custom-deploy-0.png b/docs/images/custom-deploy-0.png new file mode 100644 index 0000000000000000000000000000000000000000..5e3ca574cadcac72c250106a6e8e0d7690322ab7 GIT binary patch literal 128666 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 XxN9Q-4c&4CPs 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%0DNbwPLru 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 i#s3@Y$2J5Q>w Date: Mon, 29 Mar 2021 22:23:12 -0700 Subject: [PATCH 07/20] ensure non-shimmed aws is used by host instance --- src/ecs-additions/ecs-additions-common.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/ecs-additions/ecs-additions-common.sh b/src/ecs-additions/ecs-additions-common.sh index 831db32c3..e4c26f232 100644 --- a/src/ecs-additions/ecs-additions-common.sh +++ b/src/ecs-additions/ecs-additions-common.sh @@ -14,6 +14,9 @@ cp /opt/ecs-additions/awscli-shim.sh /opt/aws-cli/bin/aws # Use rm -f /usr/local/aws-cli/v2/current/bin/aws cp /opt/ecs-additions/awscli-shim.sh /usr/local/aws-cli/v2/current/bin/aws # Used in Cromwell +# ensure that /usr/bin/aws points to the non-shimmed version +ln -sf /usr/local/aws-cli/v2/current/dist/aws /usr/bin/aws + # add 4GB of swap space dd if=/dev/zero of=/swapfile bs=128M count=32 chmod 600 /swapfile From 486c124d6440abac214469edad7b147645992b4d Mon Sep 17 00:00:00 2001 From: "W. Lee Pang" Date: Mon, 29 Mar 2021 23:00:32 -0700 Subject: [PATCH 08/20] add ebs-autoscale logs to cloudwatch config --- .../gwfcore/gwfcore-launch-template.template.yaml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/templates/gwfcore/gwfcore-launch-template.template.yaml b/src/templates/gwfcore/gwfcore-launch-template.template.yaml index 6862e1132..708e42cbe 100644 --- a/src/templates/gwfcore/gwfcore-launch-template.template.yaml +++ b/src/templates/gwfcore/gwfcore-launch-template.template.yaml @@ -148,6 +148,16 @@ Resources: "file_path": "/var/log/ecs/ecs-volume-plugin.log", "log_group_name": "/aws/ecs/container-instance/${Namespace}", "log_stream_name": "/aws/ecs/container-instance/${Namespace}/{instance_id}/ecs-volume-plugin.log" + }, + { + "file_path": "/var/log/ebs-autoscale-install.log", + "log_group_name": "/aws/ecs/container-instance/${Namespace}", + "log_stream_name": "/aws/ecs/container-instance/${Namespace}/{instance_id}/ebs-autoscale-install.log" + }, + { + "file_path": "/var/log/ebs-autoscale.log", + "log_group_name": "/aws/ecs/container-instance/${Namespace}", + "log_stream_name": "/aws/ecs/container-instance/${Namespace}/{instance_id}/ebs-autoscale.log" } ] } From dbf14a9c76a97699e86d08884005ddcc79f212f5 Mon Sep 17 00:00:00 2001 From: Andrew Crabb Date: Sun, 28 Mar 2021 19:21:36 -0400 Subject: [PATCH 09/20] Add docs Custom Deployment --- .travis.yml | 4 +- docs/core-env/build-custom-distribution.md | 65 +++++++++++++++++++++- docs/core-env/custom-deploy.md | 2 +- mkdocs.yml | 2 + 4 files changed, 68 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 240c76254..5e245f45f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -31,12 +31,12 @@ deploy: script: bash _scripts/deploy.sh --public --verbose production skip_cleanup: true on: - repo: aws-samples/aws-genomics-workflows + repo: $TRAVIS_REPO_SLUG branch: release tags: true - provider: script script: bash _scripts/deploy.sh --public --verbose test skip_cleanup: true on: - repo: aws-samples/aws-genomics-workflows + repo: $TRAVIS_REPO_SLUG branch: master \ No newline at end of file diff --git a/docs/core-env/build-custom-distribution.md b/docs/core-env/build-custom-distribution.md index d38cffb88..46ee3ff9c 100644 --- a/docs/core-env/build-custom-distribution.md +++ b/docs/core-env/build-custom-distribution.md @@ -1,7 +1,68 @@ # Building Custom Resources -This section describes how to build and upload customized templates and artifacts. +This section describes how to build and upload templates and artifacts to use in a customized deployment. Once uploaded, the locations of the templates and artifacts are used when deploying the Nextflow on AWS Batch solution (see [Customized Deployment](custom-deploy.md)) ## Building a Custom Distribution -## Deploying a custom Distribution \ No newline at end of file +This step involves building a distribution of templates and artifacts from the solution's source code. + +First, create a local clone of the [Genomics Workflows on AWS](https://github.com/aws-samples/aws-genomics-workflows) source code. The code base contains several directories: + +* `_scripts/`: Shell scripts for building and uploading the customized distribution of templates and artifacts +* `docs/`: Source code for the documentation, written in [MarkDown](https://markdownguide.org) for the [MkDocs](https://mkdocs.org) publishing platform. This documentation may be modified, expanded, and contributed in the same way as source code. +* `src/`: Source code for the components of the solution: + * `containers/`: CodeBuild buildspec files for building AWS-specific container images and pushing them to ECR + * `_common/` + * `build.sh`: A generic build script that first builds a base image for a container, then builds an AWS specific image + * `entrypoint.aws.sh`: A generic entrypoint script that wraps a call to a binary tool in the container with handlers data staging from/to S3 + * `nextflow/` + * `Dockerfile` + * `nextflow.aws.sh`: Docker entrypoint script to execute the Nextflow workflow on AWS Batch + * `ebs-autoscale/` + * `get-amazon-ebs-autoscale.sh`: Script to retrieve and install [Amazon EBS Autoscale](https://github.com/awslabs/amazon-ebs-autoscale) + * `ecs-additions/`: Scripts to be installed on ECS host instances to support the distribution + * `awscli-shim.sh`: Installed as `/opt/aws-cli/bin/aws` and mounted onto the container, allows container images without full glibc to use the AWS CLI v2 through supplied shared libraries (especially libz) and `LD_LIBRARY_PATH`. + * `ecs-additions-common.sh`: Utility script to install `fetch_and_run.sh`, Nextflow and Cromwell shims, and swap space + * `ecs-additions-cromwell-linux2-worker.sh`: + * `ecs-additions-cromwell.sh`: + * `ecs-additions-nextflow.sh`: + * `ecs-additions-step-functions.sh`: + * `fetch_and_run.sh`: Uses AWS CLI to download and run scripts and zip files from S3 + * `provision.sh`: Appended to the userdata in the launch template created by [gwfcore-launch-template](custom-deploy.md): Starts SSM Agent, ECS Agent, Docker; runs `get-amazon-ebs-autoscale.sh`, `ecs-additions-common.sh` and orchestrator-specific `ecs-additions-` scripts. + * `lambda/`: Lambda functions to create, modify or delete ECR registries or CodeBuild jobs + * `templates/`: CloudFormation templates for the solution stack, as described in [Customized Deployment](custom-deploy.md) + +## Deploying a Custom Distribution + +The script `_scripts/deploy.sh` will create a custom distribution of artifacts and templates from files in the source tree, then upload this distribution to an S3 bucket. It will optionally also build and deploy a static documentation site from the Markdown documentation files. Its usage is: + +```sh + deploy.sh [--site-bucket BUCKET] [--asset-bucket BUCKET] + [--asset-profile PROFILE] [--deploy-region REGION] + [--public] [--verbose] + STAGE + + --site-bucket BUCKET Deploy documentation site to BUCKET + --asset-bucket BUCKET Deploy assets to BUCKET + --asset-profile PROFILE Use PROFILE for AWS CLI commands + --deploy-region REGION Deploy in region REGION + --public Deploy to public bucket with '--acl public-read' (Default false) + --verbose Display more output + STAGE 'test' or 'production' +``` + +When running this script from the command line, use the value `test` for the stage. This will deploy the templates and artifacts into a directory `test` in your deployment bucket: + +``` +$ aws s3 ls s3://my-deployment-bucket/test/ + PRE artifacts/ + PRE templates/ +``` + +Use these values when deploying a customized installation, as described in [Customized Deployment](custom-deploy.md), sections 'Artifacts and Nested Stacks' and 'Nextflow'. In the example from above, the values to use would be: + +* Artifact S3 Bucket Name: `my-deployment-bucket` +* Artifact S3 Prefix: `test/artifacts` +* Template Root URL: `https://my-deployment-bucket.s3.amazonaws.com/test/templates` + +The use of `production` for stage is reserved for deployments from a Travis CI/CD environment; this usage will deploy into a subdirectory named after the current release tag. \ No newline at end of file diff --git a/docs/core-env/custom-deploy.md b/docs/core-env/custom-deploy.md index 926a5c4d9..7e487bf34 100644 --- a/docs/core-env/custom-deploy.md +++ b/docs/core-env/custom-deploy.md @@ -1,4 +1,4 @@ -# Customized Templates and Artifacts +# Customized Deployment Deployments of the 'Nextflow on AWS Batch' solution are based on nested CloudFormation templates, and on artifacts comprising scripts, software packages, and configuration files. The templates and artifacts are stored in S3 buckets, and their S3 URLs are used when launching the top-level template and as parameters to that template's deployment. diff --git a/mkdocs.yml b/mkdocs.yml index 32578d53e..a83f91d37 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -59,3 +59,5 @@ extra: s3: bucket: docs.opendata.aws prefix: genomics-workflows + +use_directory_urls: false \ No newline at end of file From c3872bf6d96065be6d2abfc46c446b0ce99a1ec0 Mon Sep 17 00:00:00 2001 From: "W. Lee Pang" Date: Thu, 25 Mar 2021 17:34:01 -0700 Subject: [PATCH 10/20] update job queue and compute environment guidance --- docs/core-env/setup-aws-batch.md | 25 ++++++++----------- .../gwfcore/gwfcore-batch.template.yaml | 4 +-- 2 files changed, 12 insertions(+), 17 deletions(-) diff --git a/docs/core-env/setup-aws-batch.md b/docs/core-env/setup-aws-batch.md index c23acced0..643193780 100644 --- a/docs/core-env/setup-aws-batch.md +++ b/docs/core-env/setup-aws-batch.md @@ -46,8 +46,8 @@ A complete AWS Batch environment consists of the following: 1. A Compute Environment that utilizes [EC2 Spot instances](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-spot-instances.html) for cost-effective computing 2. A Compute Environment that utilizes EC2 on-demand (e.g. [public pricing](https://aws.amazon.com/ec2/pricing/on-demand/)) instances for high-priority work that can't risk job interruptions or delays due to insufficient Spot capacity. -3. A default Job Queue that utilizes the Spot compute environment first, but spills over to the on-demand compute environment if defined capacity limits (i.e. Max vCPUs) are reached. -4. A priority Job Queue that leverages the on-demand and Spot CE's (in that order) and has higher priority than the default queue. +3. A default Job Queue that solely utilizes the Spot compute environment. This is for jobs where timeliness isn't a constraint, and can wait for the right instances to become available, as well has handle interruption. It also ensures the most cost savings. +4. A priority Job Queue that leverages the on-demand, and optionally Spot, CE's (in that order) and has higher priority than the default queue. This is for jobs that cannot handle interruption, and need to be executed immediately. ### Automated via CloudFormation @@ -81,7 +81,7 @@ You can create several compute environments to suit your needs. Below we'll cre 6. In the "Service role" drop down, select the `AWSBatchServiceRole` you created previously 7. In the "Instance role" drop down, select the `ecsInstanceRole` you created previously 8. For "Provisioning model" select "On-Demand" -9. "Allowed instance types" will be already populated with "optimal" - which is a mixture of M4, C4, and R4 instances. +9. "Allowed instance types" will be already populated with "optimal" - which is a mixture of M4, C4, and R4 instances. This should be sufficient for demonstration purposes. In a production setting, it is recommended to specify the instance famimlies and sizes most apprioriate for the jobs the CE will support. For the On-Demand CE, selecting newer instance types is beneficial as they tend to have better price per performance. 10. "Allocation strategy" will already be set to `BEST_FIT`. This is recommended for on-demand based compute environments as it ensures the most cost efficiency. 11. In the "Launch template" drop down, select the `genomics-workflow-template` you created previously 12. Set Minimum and Desired vCPUs to 0. @@ -112,7 +112,7 @@ Click on "Create" 6. In the "Service role" drop down, select the `AWSBatchServiceRole` you created previously 7. In the "Instance role" drop down, select the `ecsInstanceRole` you created previously 8. For "Provisioning model" select "Spot" -9. "Allowed instance types" will be already populated with "optimal" - which is a mixture of M4, C4, and R4 instances. +9. "Allowed instance types" will be already populated with "optimal" - which is a mixture of M4, C4, and R4 instances. This should be sufficient for demonstration purposes. In a production setting, it is recommended to specify the instance families and sizes most appropriate for the jobs the CE will support. For the SPOT CE a wider diversity of instance types is recommended to maximize the pools from which capacity can be drawn from. Limiting the size of instances is also recommended to avoid scheduling too many jobs on a SPOT instance that could be interrupted. 10. "Allocation strategy" will already be set to `SPOT_CAPACITY_OPTIMIZED`. This is recommended for Spot based compute environments as it ensures the most compute capacity is available for your jobs. 11. In the "Launch template" drop down, select the `genomics-workflow-template` you created previously 12. Set Minimum and Desired vCPUs to 0. @@ -135,20 +135,18 @@ Job queues can be associated with one or more compute environments in a preferre Below we'll create two job queues: * A "Default" job queue - * A "High Priority" job queue + * A "Priority" job queue Both job queues will use both compute environments you created previously. ##### Create a "default" job queue -This queue is intended for jobs that do not require urgent completion, and can handle potential interruption. This queue will schedule jobs to: +This queue is intended for jobs that do not require urgent completion, and can handle potential interruption. This queue will schedule jobs to only the "spot" compute environment. -1. The "spot" compute environment -2. The "ondemand" compute environment +!!! note + It is not recommended to configure a job queue to "spillover" from Spot to On-Demand. Doing so could lead Insufficient Capacity Errors, resulting in Batch unable to schedule jobs, leaving them stuck in "RUNNABLE" -in that order. - -Because it primarily leverages Spot instances, it will also be the most cost effective job queue. +Because it leverages Spot instances, it will also be the most cost effective job queue. * Go to the AWS Batch Console * Click on "Job queues" @@ -157,8 +155,7 @@ Because it primarily leverages Spot instances, it will also be the most cost eff * Set "Priority" to 1 * Under "Connected compute environments for this queue", using the drop down menu: - 1. Select the "spot" compute environment you created previously, then - 2. Select the "ondemand" compute environment you created previously + 1. Select the "spot" compute environment you created previously * Click on "Create Job Queue" @@ -169,7 +166,7 @@ This queue is intended for jobs that are urgent and **cannot** handle potential 1. The "ondemand" compute environment 2. The "spot" compute environment -in that order. +in that order. In this queue configuration, Batch will schedule jobs to the "ondemand" compute environment first. When the number of Max vCPUs for that environment is reached, Batch will begin scheduling jobs to the "spot" compute environment. The use of the "spot" compute environment is optional, and is used to help drain pending jobs from the queue faster. * Go to the AWS Batch Console * Click on "Job queues" diff --git a/src/templates/gwfcore/gwfcore-batch.template.yaml b/src/templates/gwfcore/gwfcore-batch.template.yaml index 6e1cf7f64..09e649905 100644 --- a/src/templates/gwfcore/gwfcore-batch.template.yaml +++ b/src/templates/gwfcore/gwfcore-batch.template.yaml @@ -256,9 +256,7 @@ Resources: ComputeEnvironmentOrder: - Order: 1 ComputeEnvironment: !Ref SpotComputeEnv - - Order: 2 - ComputeEnvironment: !Ref OnDemandComputeEnv - + ContainerInstanceLogGroup: Type: AWS::Logs::LogGroup Properties: From af31aa8f95bee48d8d6e3142af61175db056ef89 Mon Sep 17 00:00:00 2001 From: "W. Lee Pang" Date: Mon, 29 Mar 2021 22:23:12 -0700 Subject: [PATCH 11/20] ensure non-shimmed aws is used by host instance --- src/ecs-additions/ecs-additions-common.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/ecs-additions/ecs-additions-common.sh b/src/ecs-additions/ecs-additions-common.sh index 831db32c3..e4c26f232 100644 --- a/src/ecs-additions/ecs-additions-common.sh +++ b/src/ecs-additions/ecs-additions-common.sh @@ -14,6 +14,9 @@ cp /opt/ecs-additions/awscli-shim.sh /opt/aws-cli/bin/aws # Use rm -f /usr/local/aws-cli/v2/current/bin/aws cp /opt/ecs-additions/awscli-shim.sh /usr/local/aws-cli/v2/current/bin/aws # Used in Cromwell +# ensure that /usr/bin/aws points to the non-shimmed version +ln -sf /usr/local/aws-cli/v2/current/dist/aws /usr/bin/aws + # add 4GB of swap space dd if=/dev/zero of=/swapfile bs=128M count=32 chmod 600 /swapfile From 3bfb1d4791ae43a89da35d96cb5d42845e6a040d Mon Sep 17 00:00:00 2001 From: "W. Lee Pang" Date: Mon, 29 Mar 2021 23:00:32 -0700 Subject: [PATCH 12/20] add ebs-autoscale logs to cloudwatch config --- .../gwfcore/gwfcore-launch-template.template.yaml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/templates/gwfcore/gwfcore-launch-template.template.yaml b/src/templates/gwfcore/gwfcore-launch-template.template.yaml index 6862e1132..708e42cbe 100644 --- a/src/templates/gwfcore/gwfcore-launch-template.template.yaml +++ b/src/templates/gwfcore/gwfcore-launch-template.template.yaml @@ -148,6 +148,16 @@ Resources: "file_path": "/var/log/ecs/ecs-volume-plugin.log", "log_group_name": "/aws/ecs/container-instance/${Namespace}", "log_stream_name": "/aws/ecs/container-instance/${Namespace}/{instance_id}/ecs-volume-plugin.log" + }, + { + "file_path": "/var/log/ebs-autoscale-install.log", + "log_group_name": "/aws/ecs/container-instance/${Namespace}", + "log_stream_name": "/aws/ecs/container-instance/${Namespace}/{instance_id}/ebs-autoscale-install.log" + }, + { + "file_path": "/var/log/ebs-autoscale.log", + "log_group_name": "/aws/ecs/container-instance/${Namespace}", + "log_stream_name": "/aws/ecs/container-instance/${Namespace}/{instance_id}/ebs-autoscale.log" } ] } From acb9ad28aac559ba5197fd25730bcda26c518faa Mon Sep 17 00:00:00 2001 From: Andrew Crabb Date: Wed, 31 Mar 2021 20:12:26 -0400 Subject: [PATCH 13/20] Revise docs for Custom Deployment --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5e245f45f..240c76254 100644 --- a/.travis.yml +++ b/.travis.yml @@ -31,12 +31,12 @@ deploy: script: bash _scripts/deploy.sh --public --verbose production skip_cleanup: true on: - repo: $TRAVIS_REPO_SLUG + repo: aws-samples/aws-genomics-workflows branch: release tags: true - provider: script script: bash _scripts/deploy.sh --public --verbose test skip_cleanup: true on: - repo: $TRAVIS_REPO_SLUG + repo: aws-samples/aws-genomics-workflows branch: master \ No newline at end of file From 63ef2b7a06f6bd81c8315803b62c437209132ad5 Mon Sep 17 00:00:00 2001 From: EC2 Default User Date: Thu, 8 Apr 2021 02:07:18 +0000 Subject: [PATCH 14/20] created workflows --- src/aws-genomics-cdk/README.md | 134 +- src/aws-genomics-cdk/app.config.json | 43 +- .../assets/launch_template_user_data.txt | 69 +- src/aws-genomics-cdk/bin/aws-genomics-cdk.ts | 24 +- src/aws-genomics-cdk/containers/README.md | 232 +-- src/aws-genomics-cdk/containers/build.sh | 6 +- .../containers/bwa/Dockerfile | 39 + .../containers/gatk/Dockerfile | 3 + .../containers/picard/Dockerfile | 2 + .../containers/samtools/Dockerfile | 48 + src/aws-genomics-cdk/examples/README.md | 194 ++- .../examples/batch-bwa-job.json | 33 + .../examples/batch-fastqc-job.json | 14 +- .../examples/batch-gatk-dictionary.json | 21 + .../examples/batch-gatk-htc.json | 33 + .../batch-picard-add-missing-groups.json | 29 + .../examples/batch-samtools-index.json | 25 + .../examples/batch-samtools-sort.json | 25 + .../lib/aws-genomics-cdk-stack.ts | 52 +- .../batch-compute-environmnet-construct.ts | 4 +- .../lib/batch/batch-iam-stack.ts | 13 +- src/aws-genomics-cdk/lib/batch/batch-stack.ts | 15 +- .../genomics-state-machine-stack.ts | 104 -- .../lib/step-functions/job-definitions.ts | 68 - src/aws-genomics-cdk/lib/vpc/vpc-stack.ts | 4 +- .../genomics-task-construct.ts | 0 .../job-definition-construct.ts | 4 +- .../lib/workflows/job-definitions.ts | 132 ++ .../lib/workflows/variant-calling-stack.ts | 298 ++++ .../lib/workflows/workflow-config.ts | 4 + src/aws-genomics-cdk/package-lock.json | 1492 +++++++++-------- src/aws-genomics-cdk/package.json | 14 +- 32 files changed, 1936 insertions(+), 1242 deletions(-) create mode 100644 src/aws-genomics-cdk/containers/bwa/Dockerfile create mode 100644 src/aws-genomics-cdk/containers/gatk/Dockerfile create mode 100644 src/aws-genomics-cdk/containers/picard/Dockerfile create mode 100644 src/aws-genomics-cdk/containers/samtools/Dockerfile create mode 100644 src/aws-genomics-cdk/examples/batch-bwa-job.json create mode 100644 src/aws-genomics-cdk/examples/batch-gatk-dictionary.json create mode 100644 src/aws-genomics-cdk/examples/batch-gatk-htc.json create mode 100644 src/aws-genomics-cdk/examples/batch-picard-add-missing-groups.json create mode 100644 src/aws-genomics-cdk/examples/batch-samtools-index.json create mode 100644 src/aws-genomics-cdk/examples/batch-samtools-sort.json delete mode 100644 src/aws-genomics-cdk/lib/step-functions/genomics-state-machine-stack.ts delete mode 100644 src/aws-genomics-cdk/lib/step-functions/job-definitions.ts rename src/aws-genomics-cdk/lib/{step-functions => workflows}/genomics-task-construct.ts (100%) rename src/aws-genomics-cdk/lib/{step-functions => workflows}/job-definition-construct.ts (90%) create mode 100644 src/aws-genomics-cdk/lib/workflows/job-definitions.ts create mode 100644 src/aws-genomics-cdk/lib/workflows/variant-calling-stack.ts create mode 100644 src/aws-genomics-cdk/lib/workflows/workflow-config.ts diff --git a/src/aws-genomics-cdk/README.md b/src/aws-genomics-cdk/README.md index a51783607..3e6b5ecec 100644 --- a/src/aws-genomics-cdk/README.md +++ b/src/aws-genomics-cdk/README.md @@ -1,14 +1,18 @@ # Genomics Workflows on AWS - CDK code -Contained herein is a CDK application for creating AWS resources for working with large-scale biomedical data - e.g. genomics. +Contained herein is a CDK application for creating AWS resources for working +with large-scale biomedical data - e.g. genomics. -In order to deploy this CDK application, you'll need an environment with AWS CLI access and AWS CDK installed. A quick -way yo get an environment for running this application is to launch [AWS Cloud9](https://aws.amazon.com/cloud9/). +In order to deploy this CDK application, you'll need an environment with AWS +CLI access and AWS CDK installed. A quick way to get an environment for running +this application is to launch [AWS Cloud9](https://aws.amazon.com/cloud9/). -AWS Cloud9 is a cloud-based integrated development environment (IDE) that lets you write, run, and debug your code -with just a browser. It includes a code editor, debugger, and terminal. Cloud9 comes prepackaged with essential -tools for popular programming languages, including JavaScript, Python, PHP, and more, so you don’t need to install -files or configure your development machine to start new projects. +AWS Cloud9 is a cloud-based integrated development environment (IDE) that lets +you write, run, and debug your code with just a browser. It includes a code +editor, debugger, and terminal. Cloud9 comes prepackaged with essential +tools for popular programming languages, including JavaScript, Python, PHP, and +more, so you don’t need to install files or configure your development machine +to start new projects. ## Download @@ -20,41 +24,70 @@ git clone https://github.com/aws-samples/aws-genomics-workflows.git ## Configure -This CDK application requires an S3 bucket and a VPC. The application can create them as part of the deployment or -you could configure the application to use your own S3 bucket and/or existing VPC. - -After cloning the repo, open, update, and save the application configuration file - `app.config.json`. - -**accountID** - Your [AWS account id](https://docs.aws.amazon.com/IAM/latest/UserGuide/console_account-alias.html). -**region** - The [AWS region](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html) -you want to use for the deployment (e.g., us-east-1, us-west-2, etc.). -**S3.existingBucket** - If you want to use an existing bucket, set this value to true, otherwise set it to false to -create a new bucket. +This CDK application requires an S3 bucket and a VPC. The application can +create them as part of the deployment or you could configure the application to +use your own S3 bucket and/or existing VPC. + +After cloning the repo, open, update, and save the application configuration +file - `app.config.json`. + +**accountID** - Your +[AWS account id](https://docs.aws.amazon.com/IAM/latest/UserGuide/console_account-alias.html). +**region** - The +[AWS region](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html) +you want to use for the deployment (e.g., us-east-1, us-west-2, etc.). +**projectName** - A name for the project that will be used as a prefix for the +CDK stacks and constrcuts. +**tags** - A list of key,value strings to use as tags for the AWS resources +created by this app. +**S3.existingBucket** - If you want to use an existing bucket, set this value +to true, otherwise set it to false to create a new bucket. **S3.bucketName** - The bucket name to use or create. -**VPC.createVPC** - If you want to create a new VPC, set this to true, otherwise set to false. -**VPC.existingVPCName** - If you set the createVPC option to false, you must provide a valid VPC name to use in the -same region of the deployment. -**VPC.maxAZs** - The amount of availability zones to use when creating a new VPC. -**VPC.cidr** - The [CIDR block](https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing) for the new VPC. -**VPC.cidrMask** - The [CIDR block subnet mask](https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing#Subnet_masks) +**VPC.createVPC** - If you want to create a new VPC, set this to true, +otherwise set to false. +**VPC.VPCName** - The VPC name to use a create. +**VPC.maxAZs** - The amount of availability zones to use when creating a new +VPC. +**VPC.cidr** - The +[CIDR block](https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing) for +the new VPC. +**VPC.cidrMask** - The +[CIDR block subnet mask](https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing#Subnet_masks) for the new VPC. -**batch.defaultVolumeSize** - The default EBS volume size in GiB to be attached to the EC2 instance under AWS Batch. -**batch.spotMaxVCPUs** - The limit on vcpus when using [spot instances](https://aws.amazon.com/ec2/spot/). +**batch.defaultVolumeSize** - The default EBS volume size in GiB to be attached +to the EC2 instance under AWS Batch. +**batch.spotMaxVCPUs** - The limit on vcpus when using +[spot instances](https://aws.amazon.com/ec2/spot/). **batch.onDemendMaxVCPUs** - The limit on vcpus when using on-demand instances. -**batch.instanceTypes** - The [EC2 instance types](https://aws.amazon.com/ec2/instance-types/) to use in AWS Batch. -**stepFunctions.launchDemoPipeline** - If set to true, the application will deploy a demo pipeline using step fuinctions. -**stepFunctions.jobDefinitions** - List of parametrs for the demo application bioinformatics tools. +**batch.instanceTypes** - The +[EC2 instance types](https://aws.amazon.com/ec2/instance-types/) to use in +AWS Batch. +**workflows** - A list of workflows that you would like to launch. There are +demo workflows under the `lib/workflows` directory. To add a workflow, update +the code in the `lib/aws-genomics-cdk-stack.ts` file. Look for the workflows +section. + ``` { "accountID": "111111111111", "region": "us-west-2", + "projectName": "genomics", + "tags": [{ + "name": "Environment", + "value": "production" + }, + { + "name": "Project", + "value": "genomics-pipeline" + } + ] "S3": { "existingBucket": true, - "bucketName": "" + "bucketName": "YOUR-BUCKET-NAME" }, "VPC": { "createVPC": true, - "existingVPCName": "", + "VPCName": "genomics-vpc", "maxAZs": 2, "cidr": "10.0.0.0/16", "cidrMask": 24 @@ -79,34 +112,17 @@ for the new VPC. "c5.24xlarge" ] }, - "stepFunctions": { - "launchDemoPipeline": true, - "jobDefinitions": { - "fastqc": { - "repository": "genomics/fastqc", - "memoryLimit": 8000, - "vcpus": 4, - "spot": true, - "retryAttempts":1, - "timeout": 600 - }, - "minimap2": { - "repository": "genomics/minimap2", - "memoryLimit": 16000, - "vcpus": 8, - "spot": true, - "retryAttempts":1, - "timeout": 3600 - } - } - } + "workflows": [{ + "name": "variantCalling", + "spot": true + }] } ``` ## Deploy -To deploy the CDK application, use the command line and make sure you are in the root folder of the CDK application. -(`src/aws-genomics-cdk`). +To deploy the CDK application, use the command line and make sure you are in +the root folder of the CDK application (`src/aws-genomics-cdk`). First install the neccessary node.js modules ``` npm install @@ -114,9 +130,9 @@ npm install Then deploy the application. ``` -# The "--require-approval never" parameter will skip the question to approve specific resouce creation, -# such as IAM roles. You can remove this parameter if you want to be prompted to approve creating these -# resources. +# The "--require-approval never" parameter will skip the question to approve +# specific resouce creation, such as IAM roles. You can remove this parameter +# if you want to be prompted to approve creating these resources. cdk deploy --all --require-approval never ``` @@ -129,7 +145,7 @@ cdk deploy --all --require-approval never | `lib/vpc/vpc-stack.ts` | An optional stack that will launch a VPC | | `lib/batch/batch-stack.ts` | An AWS Batch stack with 2 comnpute environments (spot and on demand) and 2 queues (default and high priority) | | `lib/batch/batch-iam-stack.ts` | An IAM stack with roles and policies required for running AWS Batch | -| `lid/step-fuinctions/genomics-state-machine-stack.ts` | A step function demo of running a pipeline | +| `llib/workflows` | A folder containing pipeline stacks | ## Constructs @@ -139,6 +155,6 @@ cdk deploy --all --require-approval never | `lib/batch/batch-compute-environmnet-construct.ts` | A construct for creating an [AWS Batch compute environment](https://docs.aws.amazon.com/batch/latest/userguide/compute_environments.html) | | `lib/batch/job-queue-construct.ts` | A construct for creating an [AWS Batch job queue](https://docs.aws.amazon.com/batch/latest/userguide/job_queues.html) | | `lib/batch/launch-template-construct.ts` | A construct for creating an [EC2 launch template](https://docs.aws.amazon.com/autoscaling/ec2/userguide/LaunchTemplates.html) | -| `lib/step-functions/genomics-task-construct.ts` | A construct for creating a step function task that submits a batch job | -| `lib/step-functions/job-definition-construct.ts` | A construct for creating an [AWS Batch job definition](https://docs.aws.amazon.com/batch/latest/userguide/job_definitions.html) to be used as a task in step functions | +| `lib/workflows/genomics-task-construct.ts` | A construct for creating a step function task that submits a batch job | +| `lib/workflows/job-definition-construct.ts` | A construct for creating an [AWS Batch job definition](https://docs.aws.amazon.com/batch/latest/userguide/job_definitions.html) to be used as a task in step functions | diff --git a/src/aws-genomics-cdk/app.config.json b/src/aws-genomics-cdk/app.config.json index 028785b68..729d3ab4e 100644 --- a/src/aws-genomics-cdk/app.config.json +++ b/src/aws-genomics-cdk/app.config.json @@ -1,13 +1,23 @@ { - "accountID": "111111111111", + "accountID": "840249831562", "region": "us-west-2", + "projectName": "genomics", + "tags": [{ + "name": "Environment", + "value": "production" + }, + { + "name": "Project", + "value": "genomics-pipeline" + } + ], "S3": { "existingBucket": true, - "bucketName": "" + "bucketName": "genomics-pipelines-840249831562" }, "VPC": { "createVPC": true, - "existingVPCName": "", + "VPCName": "genomics-vpc", "maxAZs": 2, "cidr": "10.0.0.0/16", "cidrMask": 24 @@ -32,25 +42,8 @@ "c5.24xlarge" ] }, - "stepFunctions": { - "launchDemoPipeline": true, - "jobDefinitions": { - "fastqc": { - "repository": "genomics/fastqc", - "memoryLimit": 8000, - "vcpus": 4, - "spot": true, - "retryAttempts":1, - "timeout": 600 - }, - "minimap2": { - "repository": "genomics/minimap2", - "memoryLimit": 16000, - "vcpus": 8, - "spot": true, - "retryAttempts":1, - "timeout": 3600 - } - } - } -} \ No newline at end of file + "workflows": [{ + "name": "variantCalling", + "spot": true + }] +} diff --git a/src/aws-genomics-cdk/assets/launch_template_user_data.txt b/src/aws-genomics-cdk/assets/launch_template_user_data.txt index 54044af34..23eda50a7 100644 --- a/src/aws-genomics-cdk/assets/launch_template_user_data.txt +++ b/src/aws-genomics-cdk/assets/launch_template_user_data.txt @@ -4,6 +4,10 @@ Content-Type: multipart/mixed; boundary="==BOUNDARY==" --==BOUNDARY== Content-Type: text/cloud-config; charset="us-ascii" +#cloud-config +repo_update: true +repo_upgrade: security + packages: - jq - btrfs-progs @@ -11,8 +15,61 @@ packages: - git - amazon-ssm-agent - unzip +- amazon-cloudwatch-agent + +write_files: +- permissions: '0644' + path: /opt/aws/amazon-cloudwatch-agent/etc/config.json + content: | + { + "agent": { + "logfile": "/opt/aws/amazon-cloudwatch-agent/logs/amazon-cloudwatch-agent.log" + }, + "logs": { + "logs_collected": { + "files": { + "collect_list": [ + { + "file_path": "/opt/aws/amazon-cloudwatch-agent/logs/amazon-cloudwatch-agent.log", + "log_group_name": "/aws/ecs/container-instance/${Namespace}", + "log_stream_name": "/aws/ecs/container-instance/${Namespace}/{instance_id}/amazon-cloudwatch-agent.log" + }, + { + "file_path": "/var/log/cloud-init.log", + "log_group_name": "/aws/ecs/container-instance/${Namespace}", + "log_stream_name": "/aws/ecs/container-instance/${Namespace}/{instance_id}/cloud-init.log" + }, + { + "file_path": "/var/log/cloud-init-output.log", + "log_group_name": "/aws/ecs/container-instance/${Namespace}", + "log_stream_name": "/aws/ecs/container-instance/${Namespace}/{instance_id}/cloud-init-output.log" + }, + { + "file_path": "/var/log/ecs/ecs-init.log", + "log_group_name": "/aws/ecs/container-instance/${Namespace}", + "log_stream_name": "/aws/ecs/container-instance/${Namespace}/{instance_id}/ecs-init.log" + }, + { + "file_path": "/var/log/ecs/ecs-agent.log", + "log_group_name": "/aws/ecs/container-instance/${Namespace}", + "log_stream_name": "/aws/ecs/container-instance/${Namespace}/{instance_id}/ecs-agent.log" + }, + { + "file_path": "/var/log/ecs/ecs-volume-plugin.log", + "log_group_name": "/aws/ecs/container-instance/${Namespace}", + "log_stream_name": "/aws/ecs/container-instance/${Namespace}/{instance_id}/ecs-volume-plugin.log" + } + ] + } + } + } + } runcmd: + +# start the amazon-cloudwatch-agent +- /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -s -c file:/opt/aws/amazon-cloudwatch-agent/etc/config.json + # install aws-cli v2 and copy the static binary in an easy to find location for bind-mounts into containers - curl -s "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "/tmp/awscliv2.zip" - unzip -q /tmp/awscliv2.zip -d /tmp @@ -24,11 +81,19 @@ runcmd: - mkdir -p /opt/aws-cli/bin - cp -a $(dirname $(find /usr/local/aws-cli -name 'aws' -type f))/. /opt/aws-cli/bin/ +# set environment variables for provisioning +- export GWFCORE_NAMESPACE=${Namespace} +- export INSTALLED_ARTIFACTS_S3_ROOT_URL=$(aws ssm get-parameter --name /gwfcore/${Namespace}/installed-artifacts/s3-root-url --query 'Parameter.Value' --output text) # enable ecs spot instance draining - echo ECS_ENABLE_SPOT_INSTANCE_DRAINING=true >> /etc/ecs/ecs.config -- systemctl enable amazon-ssm-agent -- systemctl start amazon-ssm-agent +# pull docker images only if missing +- echo ECS_IMAGE_PULL_BEHAVIOR=prefer-cached >> /etc/ecs/ecs.config + +- cd /opt +- aws s3 sync $INSTALLED_ARTIFACTS_S3_ROOT_URL/ecs-additions ./ecs-additions +- chmod a+x /opt/ecs-additions/provision.sh +- /opt/ecs-additions/provision.sh --==BOUNDARY==-- \ No newline at end of file diff --git a/src/aws-genomics-cdk/bin/aws-genomics-cdk.ts b/src/aws-genomics-cdk/bin/aws-genomics-cdk.ts index f1a12640c..a30fb404c 100644 --- a/src/aws-genomics-cdk/bin/aws-genomics-cdk.ts +++ b/src/aws-genomics-cdk/bin/aws-genomics-cdk.ts @@ -1,13 +1,23 @@ #!/usr/bin/env node -import 'source-map-support/register'; -import * as cdk from '@aws-cdk/core'; -import { AwsGenomicsCdkStack } from '../lib/aws-genomics-cdk-stack'; +import "source-map-support/register"; +import * as cdk from "@aws-cdk/core"; +import { AwsGenomicsCdkStack } from "../lib/aws-genomics-cdk-stack"; import * as config from "../app.config.json"; const env = { - account: process.env.CDK_DEFAULT_ACCOUNT ?? config.accountID, - region: process.env.CDK_DEFAULT_REGION ?? config.region -} + account: process.env.CDK_DEFAULT_ACCOUNT ?? config.accountID, + region: process.env.CDK_DEFAULT_REGION ?? config.region, +}; const app = new cdk.App(); -new AwsGenomicsCdkStack(app, 'AwsGenomicsCdkStack', {env: env}); +const genomicsStack = new AwsGenomicsCdkStack( + app, + `${config.projectName}CdkStack`, + { + env: env, + } +); + +for (let i = 0; i < config.tags.length; i++) { + cdk.Tags.of(genomicsStack).add(config.tags[i].name, config.tags[i].value); +} diff --git a/src/aws-genomics-cdk/containers/README.md b/src/aws-genomics-cdk/containers/README.md index 180712c1c..5951991b6 100644 --- a/src/aws-genomics-cdk/containers/README.md +++ b/src/aws-genomics-cdk/containers/README.md @@ -1,43 +1,68 @@ # Setting up bioinformatics containers -The CDK genomics pipeline project is leveraging [AWS Batch](https://aws.amazon.com/batch/) for -running bioinformatics jobs. AWS Batch works with docker containers which means we'll need to -build or use an existing docker container with the bioinfomatics tools installed. - -Start by creating a folder for your tool and place the Dockerfile inside of that folder. -There are few sample tools in this repos that you can look at: -**copy** - A tool for testing the system without the need to run any bioinfomatics tools. -**fastqc** - A quality control tool for high throughput sequence data. [Tool reference](https://www.bioinformatics.babraham.ac.uk/projects/fastqc/) -**minimap2** - Minimap2 is a versatile sequence alignment program that aligns DNA or mRNA sequences against a large reference database. [Tool reference](https://github.com/lh3/minimap2) - -For each of these tools you can find a folder that contains 2 files - Dockerfile and job.json -**Dockerfile** - The docker file to use for the bioinfomatics tool -**job.json** - A sample job you can use to test the tool with AWS bath. To run AWS batch command to test a job use the -follwing command: `aws batch submit-job --cli-input-json file://job.json` +The CDK genomics pipeline project is leveraging +[AWS Batch](https://aws.amazon.com/batch/) for +running bioinformatics jobs. AWS Batch works with docker containers which means +we'll need to build or use an existing docker container with the bioinfomatics +tools installed. + +Start by creating a folder for your tool and place the Dockerfile inside of +that folder. There are few sample tools in this repos that you can look at: +**[fastqc](https://www.bioinformatics.babraham.ac.uk/projects/fastqc/)** - +A quality control tool for high throughput sequence data. +**[minimap2](https://github.com/lh3/minimap2)** -A versatile sequence alignment +program that aligns DNA or mRNA sequences against a large reference database. +**[bwa](https://github.com/lh3/bwa)** - A software package for mapping +low-divergent sequences against a large reference genome, such as the human +genome. +**[gatk](https://gatk.broadinstitute.org/hc/en-us)** - A genomic analysis +toolkit focused on variant discovery. +**[picard](https://broadinstitute.github.io/picard/)** - Picard is a set of +command line tools for manipulating high-throughput sequencing (HTS) data and +formats such as SAM/BAM/CRAM and VCF. +**[samtools](https://github.com/samtools/samtools)** - Provide various +utilities for manipulating alignments in the SAM format, including sorting, +merging, indexing and generating alignments in a per-position format. + + +For each of these tools you can find a folder that contains a Dockerfile - +a docker file to use for the bioinfomatics tool. ### Building a container -This project include a tool to help build a container and push it to [Amazon Elastic Container Registry](https://aws.amazon.com/ecr/) (ECR) -The tool is relying on 2 environment variables CDK_DEFAULT_ACCOUNT (your AWS 12 digit account id) and -CDK_DEFAULT_REGION (the regiong where you would like to deploy your pipelione. e.g., us-west-2). You'll need to add this parameter -to your environment variables (e.g., `~/.bash_profile`). -To add these parameters to `~/.bash_profile`, open the file and add these 2 lines and make sure to set the region and account id -accordingly. +This project include a tool to help build a container and push it to +[Amazon Elastic Container Registry](https://aws.amazon.com/ecr/) (ECR). +The tool is relying on 2 environment variables ``CDK_DEFAULT_ACCOUNT`` +(your AWS 12 digit account id) and ``CDK_DEFAULT_REGION`` (the regiong where +you would like to deploy your pipelione. e.g., us-west-2). You'll need to add +this parameter to your environment variables (e.g., `~/.bash_profile`). + +To add these parameters to `~/.bash_profile`, open the file and add these +2 lines and make sure to set the region and account id accordingly. ``` export CDK_DEFAULT_REGION='us-west-2' export CDK_DEFAULT_ACCOUNT='111111111111' ``` -Save the file and run the following command: `source ~/.bash_profile`. This will set the environment variabled. - -To build the container and push it to ECR use the build.sh script by running `./build.sh TOOL_NANE` (e.g., `./build.sh fastqc`). - -The build tool will first build the bioinformatics docker container and then will chain it with `entry.dockerfile` docker container. -This container overrides the docker `ENTRYPOINT` and introduce a script (`entrypoint.sh`) which will act as the docker -container `ENTRYPOINT`. This script can copy data files from urls and S3 buckets to the local running machine, then execute the -bioinformatics tool, and at the end will be able to save any output files creatd by the running tool back to an S3 bucket. - -When submitting a job to run the bioinfomatics tools, you can provide the following environment variables that will take -care of copying input files to the machine and copy output files to S3. +Save the file and run the following command: `source ~/.bash_profile`. This +will set the environment variabled. + +To build the container and push it to ECR use the build.sh script by running +`./build.sh TOOL_NANE [optional: PROJECT_NAME]` (e.g., `./build.sh fastqc` or +`./build fastqc my-project-name`). +The default value for `PROJECT_NAME` is `genomics` which will add the container +repository under `genomics/TOOL_NANE` + +The build tool will first build the bioinformatics docker container and then +will chain it with `entry.dockerfile` docker container. This container +overrides the docker `ENTRYPOINT` and introduce a script (`entrypoint.sh`) +which will act as the docker container `ENTRYPOINT`. This script can copy data +files from urls and S3 buckets to the local running machine, then execute the +bioinformatics tool, and at the end will be able to save any output files +creatd by the running tool back to an S3 bucket. + +When submitting a job to run the bioinfomatics tools, you can provide the +following environment variables that will take care of copying input files to +the machine and copy output files to S3. ``` JOB_WORKFLOW_NAME @@ -101,147 +126,4 @@ JOB_OUTPUT_S3_COPY_METHOD ``` ### Testing the bioinformatics tool -After [deploying the CDK genomics pipeline project](GITHUB URL) you could test the genomics tools directly with AWS Batch. -Create a file named job.json in the folder of the bioinformatics tool (the same folder where you places the Dockerfile) - -``` -{ - "jobName": "", - "jobQueue": "", - "jobDefinition": "", - "containerOverrides": { - "vcpus": 1, - "memory": 1000, - "command": [""], - "environment": [{ - "name": "JOB_INPUTS", - "value": "" - }, - { - "name": "JOB_INPUT_S3_COPY_METHOD", - "value": "" - }, - { - "name": "JOB_OUTPUTS", - "value": "" - }, - { - "name": "JOB_OUTPUT_S3_COPY_METHOD", - "value": "" - }, - { - "name": "JOB_OUTPUT_PREFIX", - "value": "" - }, - { - "name": "JOB_AWS_CLI_PATH", - "value": "/opt/aws-cli/bin" - } - ] - } -} - -``` - -**jobName** (string) -The name of the job. The first character must be alphanumeric, and up to 128 letters (uppercase and lowercase), -numbers, hyphens, and underscores are allowed. - -**jobQueue** (string) -The [job queue](https://docs.aws.amazon.com/batch/latest/userguide/job_queues.html) into which the job is submitted. -You can specify either the name or the Amazon Resource Name (ARN) of the queue. - -**jobDefinition** (string) -The [job definition](https://docs.aws.amazon.com/batch/latest/userguide/job_definitions.html) used by this job. -This value can be one of name , name:revision , or the Amazon Resource Name (ARN) for the job definition. If name is -specified without a revision then the latest active revision is used. - -**containerOverrides.vcpus** (integer) -The number of vCPUs to reserve for the container. This value overrides the value set in the job definition. - -**containerOverrides.memory** (integer) -The number of MiB of memory reserved for the job. This value overrides the value set in the job definition. - -**containerOverrides.command** (list) -The command to send to the container that overrides the default command from the Docker image or the job definition. - -**containerOverrides.environment** (list) -The environment variables to send to the container. You can add new environment variables, which are added to the -container at launch, or you can override the existing environment variables from the Docker image or the job definition. -(structure) -A key-value pair object. -**name** (string) -The name of the key-value pair. For environment variables, this is the name of the environment variable. -**value** (string) -The value of the key-value pair. For environment variables, this is the value of the environment variable. - -Example for a job.json -``` -{ - "jobName": "fastqc", - "jobQueue": "genomics-default-queue", - "jobDefinition": "genomics-fastqc:1", - "containerOverrides": { - "vcpus": 8, - "memory": 16000, - "command": ["fastqc *.gz"], - "environment": [{ - "name": "JOB_INPUTS", - "value": "s3://aws-batch-genomics-shared/secondary-analysis/example-files/fastq/NIST7035_R1_trim_samp-0p1.fastq.gz s3://aws-batch-genomics-shared/secondary-analysis/example-files/fastq/NIST7035_R2_trim_samp-0p1.fastq.gz" - }, - { - "name": "JOB_INPUT_S3_COPY_METHOD", - "value": "s3cp" - }, - { - "name": "JOB_OUTPUTS", - "value": "*.html *.zip" - }, - { - "name": "JOB_OUTPUT_S3_COPY_METHOD", - "value": "s3cp" - }, - { - "name": "JOB_OUTPUT_PREFIX", - "value": "s3://my-genomics-bucket-name/some-folder-name" - }, - { - "name": "JOB_AWS_CLI_PATH", - "value": v - } - ] - } -} - -``` -In this example we are running the FastQC tools that will take fastq files and generate a report. It will output zip and -html files which we will save to an S3 bucket. -**jobName** - "fastqc". A name that describe the job to be run. -**jobQueue** - "genomics-default-queue". A valid name of a job queue. This could be found in the AWS web console > -Batch > Job queues. -**jobDefinition** - "genomics-fastqc:1". A valid and active job definition and it's version. This could be found in the -AWS web console > Batch > Job definitions. -**containerOverrides.vcpus** - 8. Request a machine that has at least 8 cores. -**containerOverrides.memory** - 16000. Request a machine that has at least 16GiB of RAM. -**containerOverrides.command** - ["fastqc *.gz"]. Run the fastq command on all the .gz files in the working directory. -**containerOverrides.environment** - A list of key-value pairs. - -**name**: JOB_INPUTS. -**value**: fastq files from an S3 bucket - -**name**: JOB_INPUT_S3_COPY_METHOD -**value**: "s3cp. Use the aws s3 cp command to copy files from an S3 bucket to the a local directory. - -**name**: JOB_OUTPUTS. -**value**: "*.html *.zip". Copy all html and zip files from a local directory to an S3 bucket. - -**name**: JOB_OUTPUT_S3_COPY_METHOD. -**value**: "s3cp". Use the aws s3 cp command to copy files from a local directory to an S3 bucket. - -**name**: JOB_OUTPUT_PREFIX. -**value**: An S3 bucket and a prefix (folder) to copy the output files into. - -**name**: JOB_AWS_CLI_PATH. -**value**: "/opt/aws-cli/bin". Path to add to the PATH environment variable so that the AWS CLI can be located - -To run AWS batch command to test a job use the follwing command: `aws batch submit-job --cli-input-json file://job.json` \ No newline at end of file +Navigate to the [examples section](SET URL) of this repo. \ No newline at end of file diff --git a/src/aws-genomics-cdk/containers/build.sh b/src/aws-genomics-cdk/containers/build.sh index 2657a80c5..e5fcca915 100755 --- a/src/aws-genomics-cdk/containers/build.sh +++ b/src/aws-genomics-cdk/containers/build.sh @@ -1,14 +1,16 @@ #!/bin/bash set -e +DEFAULT_PROJECT_NAME="genomics" IMAGE_NAME=$1 +PROJECT_NAME="${2:-$DEFAULT_PROJECT_NAME}" DOCKER_FILE_PATH="./${IMAGE_NAME}/Dockerfile" REGISTRY="$CDK_DEFAULT_ACCOUNT.dkr.ecr.$CDK_DEFAULT_REGION.amazonaws.com" -REPOSITORY_NAME="genomics/${IMAGE_NAME}" +REPOSITORY_NAME="${PROJECT_NAME}/${IMAGE_NAME}" IMAGE_TAG=":latest" IMAGE_WITH_TAG="${IMAGE_NAME}${IMAGE_TAG}" REGISTRY_PATH="${REGISTRY}/${REPOSITORY_NAME}" -REGISTRY_PATH_WITH_TAG="${REGISTRY}/genomics/${IMAGE_WITH_TAG}" +REGISTRY_PATH_WITH_TAG="${REGISTRY}/${PROJECT_NAME}/${IMAGE_WITH_TAG}" if [ -z "${IMAGE_NAME}" ] diff --git a/src/aws-genomics-cdk/containers/bwa/Dockerfile b/src/aws-genomics-cdk/containers/bwa/Dockerfile new file mode 100644 index 000000000..c99832a2b --- /dev/null +++ b/src/aws-genomics-cdk/containers/bwa/Dockerfile @@ -0,0 +1,39 @@ +FROM public.ecr.aws/lts/ubuntu:18.04 AS build + +ARG BWA_VERSION=0.7.17 + +RUN apt-get update -y \ + && apt-get install -y \ + wget \ + make \ + gcc \ + zlib1g-dev \ + bzip2 + + +WORKDIR /opt/src +RUN wget https://github.com/lh3/bwa/releases/download/v${BWA_VERSION}/bwa-${BWA_VERSION}.tar.bz2 \ + && tar -xjvf bwa-*.tar.bz2 \ + && cd bwa-* \ + && make \ + && cp bwa /opt/src + + +FROM public.ecr.aws/lts/ubuntu:18.04 AS final + +RUN apt-get update -y \ + && apt-get install -y \ + wget \ + make \ + zlib1g \ + bzip2 \ + && apt-get clean + +WORKDIR /opt/bin +COPY --from=build /opt/src/bwa . + +ENV PATH=/opt/bin:$PATH + +WORKDIR /scratch + +ENTRYPOINT ["bwa"] \ No newline at end of file diff --git a/src/aws-genomics-cdk/containers/gatk/Dockerfile b/src/aws-genomics-cdk/containers/gatk/Dockerfile new file mode 100644 index 000000000..186d4094b --- /dev/null +++ b/src/aws-genomics-cdk/containers/gatk/Dockerfile @@ -0,0 +1,3 @@ +FROM broadinstitute/gatk:4.1.3.0 + +ENTRYPOINT ["gatk"] \ No newline at end of file diff --git a/src/aws-genomics-cdk/containers/picard/Dockerfile b/src/aws-genomics-cdk/containers/picard/Dockerfile new file mode 100644 index 000000000..76083889c --- /dev/null +++ b/src/aws-genomics-cdk/containers/picard/Dockerfile @@ -0,0 +1,2 @@ +FROM broadinstitute/picard + diff --git a/src/aws-genomics-cdk/containers/samtools/Dockerfile b/src/aws-genomics-cdk/containers/samtools/Dockerfile new file mode 100644 index 000000000..961a0fb68 --- /dev/null +++ b/src/aws-genomics-cdk/containers/samtools/Dockerfile @@ -0,0 +1,48 @@ +FROM public.ecr.aws/lts/ubuntu:18.04 AS build + +ARG VERSION=1.9 + +# Metadata +LABEL container.base.image="ubuntu:18.04" +LABEL software.name="SAMtools" +LABEL software.version=${VERSION} +LABEL software.description="Utilities for the Sequence Alignment/Map (SAM/BAM/CRAM) formats" +LABEL software.website="http://www.htslib.org" +LABEL software.documentation="http://www.htslib.org/doc/samtools.html" +LABEL software.license="MIT/Expat" +LABEL tags="Genomics" + +# System and library dependencies +RUN apt-get -y update && \ + apt-get -y install \ + autoconf \ + automake \ + make \ + gcc \ + perl \ + zlib1g-dev \ + libbz2-dev \ + liblzma-dev \ + libcurl4-gnutls-dev \ + libssl-dev \ + libncurses5-dev \ + wget && \ + apt-get clean + +# Application installation +RUN wget -O /samtools-${VERSION}.tar.bz2 \ + https://github.com/samtools/samtools/releases/download/${VERSION}/samtools-${VERSION}.tar.bz2 && \ + tar xvjf /samtools-${VERSION}.tar.bz2 && rm /samtools-${VERSION}.tar.bz2 + +WORKDIR /samtools-${VERSION} +RUN ./configure && make + +FROM public.ecr.aws/lts/ubuntu:18.04 AS final +COPY --from=build /samtools-*/samtools /usr/local/bin + +RUN apt-get -y update && \ + apt-get -y install \ + libcurl3-gnutls && \ + apt-get clean + +ENTRYPOINT ["samtools"] \ No newline at end of file diff --git a/src/aws-genomics-cdk/examples/README.md b/src/aws-genomics-cdk/examples/README.md index 44797276e..0a82f4800 100644 --- a/src/aws-genomics-cdk/examples/README.md +++ b/src/aws-genomics-cdk/examples/README.md @@ -1,50 +1,31 @@ # Bioinformatics tools examples -You can test the bioinfomatics tools with AWS Batch directly or start a full Step Functions pipeline. - -**jobName** - A name for the job, this will appear in the AWS Batch Job list -**jobQueue** - The name of the queue you want to use in AWS Batch. You can get this name from the AWS Batch console > -Job queues. -**jobDefinition** - The AWS Batch job definition including a version number. You can get this name from the AWS Batch console > -Job definitions. -**containerOverrides.vcpus** - The desired amount of vcpus to run this job. -**containerOverrides.memory** - The number of MiB of memory reserved for the job. -**containerOverrides.command** - The command to be executed. -**containerOverrides.environment** - Environment variables to send to the container. Refer to the special environment -variables in the [containers readme file](../README.md). - -Change the "JOB_OUTPUT_PREFIX" parameter to an existing bucket and choose a prefix (e.g., s3://mybucketname/test). - -### FastQC -To run the command, cd to the examples directory (e.g., ``cd src/aws-genomics-cdk/examples``) and run the following -command ``aws batch submit-job --cli-input-json file://batch-fastqc-job.json`` -If the job finish successfully you should see new html and zip files in the S3 location you configured. +After [deploying the CDK genomics pipeline project](GITHUB URL) you could test +the genomics tools directly with AWS Batch or start a Step Functions pipeline. + +### Testing bioinformatics tools using AWS Batch +Create a file named batch-TOOL_NANE.json. ``` -batch-fastqc-job.json { - "jobName": "fastqc", - "jobQueue": "genomics-default-job-queue", - "jobDefinition": "genomics-fastqc:1", + "jobName": "", + "jobQueue": "", + "jobDefinition": "", "containerOverrides": { - "vcpus": 2, - "memory": 4000, - "command": ["fastqc *.gz"], + "vcpus": 1, + "memory": 1000, + "command": [""], "environment": [{ "name": "JOB_INPUTS", - "value": "s3://aws-batch-genomics-shared/secondary-analysis/example-files/fastq/NIST7035_R1_trim_samp-0p1.fastq.gz s3://aws-batch-genomics-shared/secondary-analysis/example-files/fastq/NIST7035_R2_trim_samp-0p1.fastq.gz" + "value": "" }, { "name": "JOB_OUTPUTS", - "value": "*.html *.zip" + "value": "" }, { "name": "JOB_OUTPUT_PREFIX", - "value": "s3://[YOUR BUCKET NAME]/[SOME PREFIX]" - }, - { - "name": "JOB_AWS_CLI_PATH", - "value": "/opt/aws-cli/bin" + "value": "" } ] } @@ -52,65 +33,116 @@ batch-fastqc-job.json ``` +**jobName** (string) +The name of the job. The first character must be alphanumeric, and up to 128 +letters (uppercase and lowercase), numbers, hyphens, and underscores are +allowed. + +**jobQueue** (string) +The [job queue](https://docs.aws.amazon.com/batch/latest/userguide/job_queues.html) +into which the job is submitted. You can specify either the name or the Amazon +Resource Name (ARN) of the queue. + +**jobDefinition** (string) +The [job definition](https://docs.aws.amazon.com/batch/latest/userguide/job_definitions.html) +used by this job. This value can be one of name , name:revision , or the Amazon +Resource Name (ARN) for the job definition. If name is specified without +a revision then the latest active revision is used. -### Minimap2 -To run the command, cd to the examples directory (e.g., ``cd src/aws-genomics-cdk/examples``) and run the following -command ``aws batch submit-job --cli-input-json file://batch-minimap2-job.json`` -If the job finish successfully you should see new sam files in the S3 location you configured. +**containerOverrides.vcpus** (integer optional) +The number of vCPUs to reserve for the container. This value overrides the +value set in the job definition. + +**containerOverrides.memory** (integer optional) +The number of MiB of memory reserved for the job. This value overrides the +value set in the job definition. + +**containerOverrides.command** (list) +The command to send to the container that overrides the default command from +the Docker image or the job definition. + +**containerOverrides.environment** (list) +The environment variables to send to the container. You can add new environment +variables, which are added to the container at launch, or you can override the +existing environment variables from the Docker image or the job definition. +(structure) +A key-value pair object. +**name** (string) +The name of the key-value pair. For environment variables, this is the name of +the environment variable. +**value** (string) +The value of the key-value pair. For environment variables, this is the value +of the environment variable. + +Example for a `batch-fastqc.json` ``` -batch-minimap2-job.json { - "jobName": "minimap2", + "jobName": "fastqc", "jobQueue": "genomics-default-queue", - "jobDefinition": "minimap2:1", + "jobDefinition": "genomics-fastqc:1", "containerOverrides": { - "vcpus": 8, - "memory": 16000, - "command": ["minimap2 -ax map-pb Homo_sapiens_assembly38.fasta NIST7035_R1_trim_samp-0p1.fastq.gz > NIST7035.sam"], + "vcpus": 1, + "memory": 1000, + "command": ["fastqc *.gz"], "environment": [{ - "name": "JOB_INPUTS", - "value": "s3://broad-references/hg38/v0/Homo_sapiens_assembly38.fasta s3://aws-batch-genomics-shared/secondary-analysis/example-files/fastq/NIST7035_R1_trim_samp-0p1.fastq.gz" - }, - { - "name": "JOB_OUTPUTS", - "value": "*.sam" - }, - { - "name": "JOB_OUTPUT_PREFIX", - "value": "s3://[YOUR BUCKET NAME]/[SOME PREFIX]" - }, - { - "name": "JOB_AWS_CLI_PATH", - "value": "/opt/aws-cli/bin" - } + "name": "JOB_INPUTS", + "value": "s3://aws-batch-genomics-shared/secondary-analysis/example-files/fastq/NIST7035_R*.fastq.gz" + }, + { + "name": "JOB_OUTPUTS", + "value": "*.html *.zip" + }, + { + "name": "JOB_OUTPUT_PREFIX", + "value": "s3://my-genomics-bucket-name/some-folder-name" + } ] } } + ``` +In this example we are running the FastQC tools that will take fastq files and +generate a report. It will output zip and html files which we will save to an +S3 bucket. +**jobName** - "fastqc". A name that describe the job to be run. +**jobQueue** - "genomics-default-queue". A valid name of a job queue. This +could be found in the AWS web console > Batch > Job queues. +**jobDefinition** - "genomics-fastqc:1". A valid and active job definition and +it's version. This could be found in the AWS web console > Batch > Job +definitions. +**containerOverrides.vcpus** - 1. Request a machine that has at least 1 core. +**containerOverrides.memory** - 1000. Request a machine that has at least +1000MiB of RAM. +**containerOverrides.command** - ["fastqc *.gz"]. Run the fastq command on all +the .gz files in the working directory. +**containerOverrides.environment** - A list of key-value pairs. +**name**: JOB_INPUTS. +**value**: fastq files from a source S3 bucket -### A demo pipeline that runs FasqQC and then Minimap2 +**name**: JOB_OUTPUTS. +**value**: "*.html *.zip". Copy all html and zip files from a local directory +to an S3 bucket. + +**name**: JOB_OUTPUT_PREFIX. +**value**: An S3 bucket and a prefix (folder) to copy the output files into. + + +There are several examples under the `examples` directory. To run an example, +edit the example file you want to run (e.g., `examples/batch-fastqc-job.json`), +update the `JOB_INPUTS` to a valid source of your sample fastq files, or leave +the default value to use a demo sample. Update the `JOB_OUTPUT_PREFIX` to a +valid s3 bucket and a subfolder where you want the output zip and html files +to be saved to. + +Change directory to the examples directory and then submit the job to Batch. -Logon to the AWS console, navigate to Step Functions and click on the "genomics-pipelines-state-machine" state machine. -Click on the "Start execution" button and use the following json content for the input section. Change the -"JOB_OUTPUT_PREFIX" parameter to an existing bucket and choose a prefix (e.g., s3://mybucketname/test). ``` -{ - "params": { - "environment": { - "JOB_OUTPUT_PREFIX": "[YOUR BUCKET NAME]/[SOME PREFIX]" - }, - "fastqc": { - "input": "s3://aws-batch-genomics-shared/secondary-analysis/example-files/fastq/NIST7035_R1_trim_samp-0p1.fastq.gz s3://aws-batch-genomics-shared/secondary-analysis/example-files/fastq/NIST7035_R2_trim_samp-0p1.fastq.gz", - "output": "*.html *.zip" - }, - "minimap2": { - "input": "s3://broad-references/hg38/v0/Homo_sapiens_assembly38.fasta s3://aws-batch-genomics-shared/secondary-analysis/example-files/fastq/NIST7035_R1_trim_samp-0p1.fastq.gz", - "fastaFileName": "Homo_sapiens_assembly38.fasta", - "fastqFiles": "NIST7035_R1_trim_samp-0p1.fastq.gz", - "samOutput": "hg38-NIST7035.sam", - "output": "*.sam" - } - } -} -``` \ No newline at end of file +cd examples +aws batch submit-job --cli-input-json file://batch-fastqc-job.json +``` + +Navigate to the Batch jobs page (AWS console -> AWS Batch -> Jobs -> select the +job queue you used (e.g., `genomics-default-queue`) to track the progress of +the job. You can click on the job name and them click on the Log stream name +link to track the stdout on the running task. diff --git a/src/aws-genomics-cdk/examples/batch-bwa-job.json b/src/aws-genomics-cdk/examples/batch-bwa-job.json new file mode 100644 index 000000000..d68d3ef94 --- /dev/null +++ b/src/aws-genomics-cdk/examples/batch-bwa-job.json @@ -0,0 +1,33 @@ +{ + "jobName": "bwa", + "jobQueue": "genomics-default-queue", + "jobDefinition": "bwa:3", + "containerOverrides": { + "command": ["bwa mem -t 8 -p -o ${SAMPLE_ID}.sam ${REFERENCE_NAME}.fasta ${SAMPLE_ID}_*1*.fastq.gz"], + "environment": [{ + "name": "JOB_INPUTS", + "value": "s3://genomics-pipelines-840249831562/sample/ s3://genomics-pipelines-840249831562/hg38/v0/" + }, + { + "name": "SAMPLE_ID", + "value": "NIST7035" + }, + { + "name": "REFERENCE_NAME", + "value": "Homo_sapiens_assembly38" + }, + { + "name": "JOB_OUTPUTS", + "value": "*.sam" + }, + { + "name": "JOB_OUTPUT_PREFIX", + "value": "s3://genomics-pipelines-840249831562/output" + }, + { + "name": "JOB_INPUT_S3_COPY_METHOD", + "value": "s3sync" + } + ] + } +} \ No newline at end of file diff --git a/src/aws-genomics-cdk/examples/batch-fastqc-job.json b/src/aws-genomics-cdk/examples/batch-fastqc-job.json index 19730e23f..ffd1848c2 100644 --- a/src/aws-genomics-cdk/examples/batch-fastqc-job.json +++ b/src/aws-genomics-cdk/examples/batch-fastqc-job.json @@ -1,14 +1,12 @@ { "jobName": "fastqc", "jobQueue": "genomics-default-queue", - "jobDefinition": "fastqc:1", + "jobDefinition": "fastqc:3", "containerOverrides": { - "vcpus": 2, - "memory": 4000, "command": ["fastqc *.gz"], "environment": [{ "name": "JOB_INPUTS", - "value": "s3://aws-batch-genomics-shared/secondary-analysis/example-files/fastq/NIST7035_R1_trim_samp-0p1.fastq.gz s3://aws-batch-genomics-shared/secondary-analysis/example-files/fastq/NIST7035_R2_trim_samp-0p1.fastq.gz" + "value": "s3://aws-batch-genomics-shared/secondary-analysis/example-files/fastq/NIST7035_R*.fastq.gz" }, { "name": "JOB_OUTPUTS", @@ -16,12 +14,8 @@ }, { "name": "JOB_OUTPUT_PREFIX", - "value": "s3://[YOUR BUCKET NAME]/[SOME PREFIX]" - }, - { - "name": "JOB_AWS_CLI_PATH", - "value": "/opt/aws-cli/bin" + "value": "s3://genomics-pipelines-840249831562/output" } ] } -} +} \ No newline at end of file diff --git a/src/aws-genomics-cdk/examples/batch-gatk-dictionary.json b/src/aws-genomics-cdk/examples/batch-gatk-dictionary.json new file mode 100644 index 000000000..f0a4a98e4 --- /dev/null +++ b/src/aws-genomics-cdk/examples/batch-gatk-dictionary.json @@ -0,0 +1,21 @@ +{ + "jobName": "gatk-create-dictionary", + "jobQueue": "genomics-default-queue", + "jobDefinition": "gatkCreateSequenceDictionary:1", + "containerOverrides": { + "command": ["java -jar /usr/app/picard.jar CreateSequenceDictionary R=Homo_sapiens_assembly38.fasta O=Homo_sapiens_assembly38.dict"], + "environment": [{ + "name": "JOB_INPUTS", + "value": "s3://genomics-pipelines-840249831562/hg38/v0/Homo_sapiens_assembly38.fasta" + }, + { + "name": "JOB_OUTPUTS", + "value": "*.dict" + }, + { + "name": "JOB_OUTPUT_PREFIX", + "value": "s3://genomics-pipelines-840249831562/hg38/v0" + } + ] + } +} \ No newline at end of file diff --git a/src/aws-genomics-cdk/examples/batch-gatk-htc.json b/src/aws-genomics-cdk/examples/batch-gatk-htc.json new file mode 100644 index 000000000..89ca2b06b --- /dev/null +++ b/src/aws-genomics-cdk/examples/batch-gatk-htc.json @@ -0,0 +1,33 @@ +{ + "jobName": "gatkHaploTypeCaller", + "jobQueue": "genomics-default-queue", + "jobDefinition": "gatkHaplotypeCaller:1", + "containerOverrides": { + "command": ["gatk --java-options \"-Xmx4g\" HaplotypeCaller -R ${REFERENCE_NAME}.fasta -I ${SAMPLE_ID}.bam -O ${SAMPLE_ID}.vcf.gz -bamout ${SAMPLE_ID}.out.bam"], + "environment": [{ + "name": "JOB_INPUTS", + "value": "s3://genomics-pipelines-840249831562/output/ s3://genomics-pipelines-840249831562/hg38/v0/" + }, + { + "name": "SAMPLE_ID", + "value": "NIST7035" + }, + { + "name": "REFERENCE_NAME", + "value": "Homo_sapiens_assembly38" + }, + { + "name": "JOB_OUTPUTS", + "value": "*.out.bam *.vcf.gz" + }, + { + "name": "JOB_OUTPUT_PREFIX", + "value": "s3://genomics-pipelines-840249831562/output" + }, + { + "name": "JOB_INPUT_S3_COPY_METHOD", + "value": "s3sync" + } + ] + } +} diff --git a/src/aws-genomics-cdk/examples/batch-picard-add-missing-groups.json b/src/aws-genomics-cdk/examples/batch-picard-add-missing-groups.json new file mode 100644 index 000000000..a93b8fffc --- /dev/null +++ b/src/aws-genomics-cdk/examples/batch-picard-add-missing-groups.json @@ -0,0 +1,29 @@ +{ + "jobName": "picard-add-missing-groups", + "jobQueue": "genomics-default-queue", + "jobDefinition": "picardAddMissingGroups:1", + "containerOverrides": { + "command": ["java -jar /usr/picard/picard.jar AddOrReplaceReadGroups", + " -I ${SAMPLE_ID}.bam -O ${SAMPLE_ID}.rg.bam -RGID 4 --RGLB lib1 ", + " --RGPL ILLUMINA --RGPU unit1 --RGSM 20;", + " cp ${SAMPLE_ID}.rg.bam ${SAMPLE_ID}.bam;", + " rm ${SAMPLE_ID}.rg.bam"], + "environment": [{ + "name": "JOB_INPUTS", + "value": "s3://genomics-pipelines-840249831562/output/NIST7035.bam" + }, + { + "name": "SAMPLE_ID", + "value": "NIST7035" + }, + { + "name": "JOB_OUTPUTS", + "value": "*.bam" + }, + { + "name": "JOB_OUTPUT_PREFIX", + "value": "s3://genomics-pipelines-840249831562/output" + } + ] + } +} \ No newline at end of file diff --git a/src/aws-genomics-cdk/examples/batch-samtools-index.json b/src/aws-genomics-cdk/examples/batch-samtools-index.json new file mode 100644 index 000000000..ebd6da035 --- /dev/null +++ b/src/aws-genomics-cdk/examples/batch-samtools-index.json @@ -0,0 +1,25 @@ +{ + "jobName": "samtoolsIndex", + "jobQueue": "genomics-default-queue", + "jobDefinition": "samtoolsIndex:2", + "containerOverrides": { + "command": ["samtools index ${SAMPLE_ID}.bam"], + "environment": [{ + "name": "JOB_INPUTS", + "value": "s3://genomics-pipelines-840249831562/output/NIST7035.bam" + }, + { + "name": "SAMPLE_ID", + "value": "NIST7035" + }, + { + "name": "JOB_OUTPUTS", + "value": "*.bam *.bai" + }, + { + "name": "JOB_OUTPUT_PREFIX", + "value": "s3://genomics-pipelines-840249831562/output" + } + ] + } +} \ No newline at end of file diff --git a/src/aws-genomics-cdk/examples/batch-samtools-sort.json b/src/aws-genomics-cdk/examples/batch-samtools-sort.json new file mode 100644 index 000000000..6747ea62e --- /dev/null +++ b/src/aws-genomics-cdk/examples/batch-samtools-sort.json @@ -0,0 +1,25 @@ +{ + "jobName": "samtoolsSort", + "jobQueue": "genomics-default-queue", + "jobDefinition": "samtoolsSort:1", + "containerOverrides": { + "command": ["samtools sort -@ 4 -o ${SAMPLE_ID}.bam ${SAMPLE_ID}.sam"], + "environment": [{ + "name": "JOB_INPUTS", + "value": "s3://genomics-pipelines-840249831562/output/NIST7035.sam" + }, + { + "name": "SAMPLE_ID", + "value": "NIST7035" + }, + { + "name": "JOB_OUTPUTS", + "value": "*.bam" + }, + { + "name": "JOB_OUTPUT_PREFIX", + "value": "s3://genomics-pipelines-840249831562/output" + } + ] + } +} \ No newline at end of file diff --git a/src/aws-genomics-cdk/lib/aws-genomics-cdk-stack.ts b/src/aws-genomics-cdk/lib/aws-genomics-cdk-stack.ts index e225d5d61..cc0954223 100644 --- a/src/aws-genomics-cdk/lib/aws-genomics-cdk-stack.ts +++ b/src/aws-genomics-cdk/lib/aws-genomics-cdk-stack.ts @@ -4,7 +4,10 @@ import * as s3 from "@aws-cdk/aws-s3"; import * as config from "../app.config.json"; import GenomicsVpcStack from "./vpc/vpc-stack"; import GenomicsBatchStack from "./batch/batch-stack"; -import GenomicsStateMachineProps from "./step-functions/genomics-state-machine-stack"; + +//Workflows +import { WorkflowConfig } from "./workflows/workflow-config"; +import VariantCallingStateMachine from "./workflows/variant-calling-stack"; export class AwsGenomicsCdkStack extends cdk.Stack { constructor(scope: cdk.Construct, id: string, props: cdk.StackProps) { @@ -13,11 +16,11 @@ export class AwsGenomicsCdkStack extends cdk.Stack { // Create a new VPC or use an existing one let vpc: ec2.Vpc; if (config.VPC.createVPC) { - vpc = new GenomicsVpcStack(this, "genomics-vpc", props).vpc; + vpc = new GenomicsVpcStack(this, config.VPC.VPCName, props).vpc; } else { - vpc = ec2.Vpc.fromLookup(this, "genomics-vpc-lookup", { - vpcName: config.VPC.existingVPCName, - }) as ec2.Vpc + vpc = ec2.Vpc.fromLookup(this, `${config.projectName}-vpc-lookup`, { + vpcName: config.VPC.VPCName, + }) as ec2.Vpc; } // Create a new bucket if set in the config @@ -38,17 +41,34 @@ export class AwsGenomicsCdkStack extends cdk.Stack { bucket: config.S3.bucketName, }; - const batch = new GenomicsBatchStack(this, "genomics-batch", batchProps); - - if(config.stepFunctions.launchDemoPipeline === true){ - const genomicsDemoProps = { - genomicsDefaultQueue: batch.genomicsDefaultQueue, - genomicsHighPriorityQueue: batch.genomicsHighPriorityQueue, - env: props.env as cdk.ResourceEnvironment, - taskRole: batch.taskRole - }; - - new GenomicsStateMachineProps(this, "genomics-demo-pipeline", genomicsDemoProps) + const batch = new GenomicsBatchStack( + this, + `${config.projectName}-batch`, + batchProps + ); + + // loop throgh the app.config workflows file and set infrastructure for + // the provided workflows + let workflow: WorkflowConfig; + for (let i = 0; i < config.workflows.length; i++) { + workflow = config.workflows[i] as WorkflowConfig; + + switch (workflow.name) { + case "variantCalling": + new VariantCallingStateMachine( + this, + `${config.projectName}-${workflow.name}`, + { + stackProps: props, + batchQueue: + workflow.spot === true + ? batch.genomicsDefaultQueue + : batch.genomicsHighPriorityQueue, + taskRole: batch.taskRole, + } + ); + break; + } } } } diff --git a/src/aws-genomics-cdk/lib/batch/batch-compute-environmnet-construct.ts b/src/aws-genomics-cdk/lib/batch/batch-compute-environmnet-construct.ts index dd37e1895..843f15ce3 100644 --- a/src/aws-genomics-cdk/lib/batch/batch-compute-environmnet-construct.ts +++ b/src/aws-genomics-cdk/lib/batch/batch-compute-environmnet-construct.ts @@ -3,6 +3,7 @@ import * as batch from "@aws-cdk/aws-batch"; import * as ec2 from "@aws-cdk/aws-ec2"; import * as ecs from "@aws-cdk/aws-ecs"; import * as iam from "@aws-cdk/aws-iam"; +import * as config from "../../app.config.json"; export class GenomicsComputeEnvironmentProps { readonly computeResourcesType?: batch.ComputeResourceType; @@ -35,8 +36,7 @@ export default class GenomicsComputeEnvironment extends cdk.Construct { props.allocationStrategy ?? batch.AllocationStrategy.SPOT_CAPACITY_OPTIMIZED, computeResourcesTags: props.computeResourcesTags ?? { - Name: "genomics-instance", - Environment: "production", + Name: `${config.projectName}-instance` }, image: ecs.EcsOptimizedImage.amazonLinux2(), instanceRole: props.instanceProfileArn, diff --git a/src/aws-genomics-cdk/lib/batch/batch-iam-stack.ts b/src/aws-genomics-cdk/lib/batch/batch-iam-stack.ts index 57bb3b8d8..37135f434 100644 --- a/src/aws-genomics-cdk/lib/batch/batch-iam-stack.ts +++ b/src/aws-genomics-cdk/lib/batch/batch-iam-stack.ts @@ -2,6 +2,7 @@ import * as cdk from "@aws-cdk/core"; import * as iam from "@aws-cdk/aws-iam"; import * as path from "path"; import * as fs from "fs"; +import * as config from "../../app.config.json"; export interface GenomicsIamProps { readonly bucketName: string; @@ -19,7 +20,7 @@ export default class GenomicsIam extends cdk.Stack { // Create a task role to be used by AWS batch container const taskRoleProps = { - roleName: "genomics-ecs-task-role", + roleName: `${config.projectName}-ecs-task-role`, assumedBy: new iam.ServicePrincipal("ecs-tasks.amazonaws.com"), description: "allow ecs task to assume a role for the genomics pipleine", managedPolicies: [iam.ManagedPolicy.fromAwsManagedPolicyName("AmazonS3ReadOnlyAccess")] @@ -30,7 +31,7 @@ export default class GenomicsIam extends cdk.Stack { // Create an instance role for the EC2 host machine for AWS Batch const instanceRoleProps = { - roleName: "genomics-batch-instance-role", + roleName: `${config.projectName}-batch-instance-role`, assumedBy: new iam.ServicePrincipal("ec2.amazonaws.com"), description: "allow ec2 instance to assume a role for the genomics pipleine", managedPolicies: [ @@ -45,7 +46,7 @@ export default class GenomicsIam extends cdk.Stack { // Create a spot fleet role to be used by AWS Batch when launching spot instances const fleetRoleProps = { - roleName: "genomics-spot-fleet-role", + roleName: `${config.projectName}-spot-fleet-role`, assumedBy: new iam.ServicePrincipal("ec2.amazonaws.com"), description: "allow ec2 instance to assume a role for the genomics pipleine", managedPolicies: [iam.ManagedPolicy.fromAwsManagedPolicyName("service-role/AmazonEC2SpotFleetTaggingRole")] @@ -56,7 +57,7 @@ export default class GenomicsIam extends cdk.Stack { // Create a service role for AWS Batch so it can assume other roles for the genomics pipeline const batchServiceRoleProps = { - roleName: "genomics-batch-service-role", + roleName: `${config.projectName}-batch-service-role`, assumedBy: new iam.ServicePrincipal("batch.amazonaws.com"), description: "allow batch to assume a role for the genomics pipleine", managedPolicies: [iam.ManagedPolicy.fromAwsManagedPolicyName("service-role/AWSBatchServiceRole")] @@ -70,7 +71,7 @@ export default class GenomicsIam extends cdk.Stack { const bucketPolicy = fs.readFileSync(filePath, {encoding: "utf-8"}).replace(/BUCKET_NAME/g, props.bucketName); const policyProps = { - policyName: "genomics-policy-s3", + policyName: `${config.projectName}-policy-s3`, document: iam.PolicyDocument.fromJson(JSON.parse(bucketPolicy)), force: true, roles: [this.taskRole, instanceRole] @@ -81,7 +82,7 @@ export default class GenomicsIam extends cdk.Stack { // Create an instance profile to be used by AWS Batch compute environment const instanceProfileProps = { roles: [instanceRoleProps.roleName], - instanceProfileName: "genomics-batch-instance-profile" + instanceProfileName: `${config.projectName}-batch-instance-profile` }; const instanceProfile = new iam.CfnInstanceProfile(this, instanceProfileProps.instanceProfileName, instanceProfileProps); this.instanceProfileArn = `arn:aws:iam::${props.account}:instance-profile/${instanceProfileProps.instanceProfileName}`; diff --git a/src/aws-genomics-cdk/lib/batch/batch-stack.ts b/src/aws-genomics-cdk/lib/batch/batch-stack.ts index b2ff6076f..6c0fa176f 100644 --- a/src/aws-genomics-cdk/lib/batch/batch-stack.ts +++ b/src/aws-genomics-cdk/lib/batch/batch-stack.ts @@ -32,14 +32,14 @@ export default class GenomicsBatchStack extends cdk.Stack { account: env.account as string } - const genomicsIam = new GenomicsIam(this, "genomics-iam", genomicsIamProps); + const genomicsIam = new GenomicsIam(this, `${config.projectName}-iam`, genomicsIamProps); this.taskRole = genomicsIam.taskRole; // Create a EC2 Launch Template to be used by AWS Batch const launchTemplateProps = { - launchTemplateName: "genomics-launch-template", + launchTemplateName: `${config.projectName}-launch-template`, volumeSize: config.batch.defaultVolumeSize }; @@ -54,7 +54,7 @@ export default class GenomicsBatchStack extends cdk.Stack { // Create spot compute environment for the genomics pipeline using SPOT instances const spotComputeEnvironmentProps = { - computeEnvironmentName: "genomics-spot-compute-environment", + computeEnvironmentName: `${config.projectName}-spot-compute-environment`, vpc: props.vpc, instanceTypes: envInstanceType, maxvCpus: config.batch.spotMaxVCPUs, @@ -71,7 +71,7 @@ export default class GenomicsBatchStack extends cdk.Stack { // Create on demand compute environment using on demand instances const onDemandComputeEnvironmentProps = { - computeEnvironmentName: "genomics-on-demand-compute-environment", + computeEnvironmentName: `${config.projectName}-on-demand-compute-environment`, computeResourcesType: batch.ComputeResourceType.ON_DEMAND, allocationStrategy: batch.AllocationStrategy.BEST_FIT, vpc: props.vpc, @@ -92,10 +92,9 @@ export default class GenomicsBatchStack extends cdk.Stack { // Create default queue, using spot first and then on-demand instances const defaultQueueProps = { computeEnvironments: [ - spotComputeEnvironment.computeEnvironment, - onDemandComputeEnvironment.computeEnvironment + spotComputeEnvironment.computeEnvironment ], - jobQueueName: "genomics-default-queue", + jobQueueName: `${config.projectName}-default-queue`, priority: 100 }; @@ -110,7 +109,7 @@ export default class GenomicsBatchStack extends cdk.Stack { spotComputeEnvironment.computeEnvironment ], - jobQueueName: "genomics-high-priority-queue", + jobQueueName: `${config.projectName}-high-priority-queue`, priority: 1000 } diff --git a/src/aws-genomics-cdk/lib/step-functions/genomics-state-machine-stack.ts b/src/aws-genomics-cdk/lib/step-functions/genomics-state-machine-stack.ts deleted file mode 100644 index 1cd6285c0..000000000 --- a/src/aws-genomics-cdk/lib/step-functions/genomics-state-machine-stack.ts +++ /dev/null @@ -1,104 +0,0 @@ -import * as cdk from "@aws-cdk/core"; -import * as batch from "@aws-cdk/aws-batch"; -import * as sfn from "@aws-cdk/aws-stepfunctions"; -import * as iam from "@aws-cdk/aws-iam"; -import * as jobDefinitions from "./job-definitions"; -import GenomicsTask from "./genomics-task-construct"; -import GenomicsJobDefinition from "./job-definition-construct"; -import * as config from "../../app.config.json"; - -export interface GenomicsStateMachineProps { - readonly genomicsDefaultQueue: batch.JobQueue; - readonly genomicsHighPriorityQueue: batch.JobQueue; - readonly env: cdk.ResourceEnvironment; - readonly taskRole: iam.Role; -} - -export default class GenomicsStateMachine extends cdk.Stack { - constructor( - scope: cdk.Construct, - id: string, - props: GenomicsStateMachineProps - ) { - super(scope, id, { env: props.env }); - - const jobDefinitionProps = { - env: props.env, - stack: this, - jobRole: props.taskRole, - }; - - const fastQC = new jobDefinitions.FastQcJobDefinition({ - ...jobDefinitionProps, - ...config.stepFunctions.jobDefinitions.fastqc, - }); - - const minimap2 = new jobDefinitions.Minimap2JObDefinition({ - ...jobDefinitionProps, - ...config.stepFunctions.jobDefinitions.minimap2, - }); - - const step1TaskProps = { - taskName: "FASTQC", - environment: { - JOB_INPUTS: sfn.JsonPath.stringAt("$.params.fastqc.input"), - JOB_OUTPUTS: sfn.JsonPath.stringAt("$.params.fastqc.output"), - }, - command: ["fastqc *.gz"], - jobDefinition: new GenomicsJobDefinition( - this, - fastQC.jobDefinitionName, - fastQC - ).jobDefinition, - queue: config.stepFunctions.jobDefinitions.fastqc.spot === true - ? props.genomicsDefaultQueue - : props.genomicsHighPriorityQueue, - }; - - const step1Task = new GenomicsTask( - this, - step1TaskProps.taskName, - step1TaskProps - ).task; - - const step2TaskProps = { - taskName: "MINIMAP2", - environment: { - JOB_INPUTS: sfn.JsonPath.stringAt("$.params.minimap2.input"), - FASTA_INPUT: sfn.JsonPath.stringAt("$.params.minimap2.fastaFileName"), - FASTQ_INPUT: sfn.JsonPath.stringAt("$.params.minimap2.fastqFiles"), - SAM_OUTPUT: sfn.JsonPath.stringAt("$.params.minimap2.samOutput"), - JOB_OUTPUTS: sfn.JsonPath.stringAt("$.params.minimap2.output"), - }, - command: ["minimap2 -ax map-pb $FASTA_INPUT $FASTQ_INPUT > $SAM_OUTPUT"], - jobDefinition: new GenomicsJobDefinition( - this, - minimap2.jobDefinitionName, - minimap2 - ).jobDefinition, - queue: config.stepFunctions.jobDefinitions.minimap2.spot === true - ? props.genomicsDefaultQueue - : props.genomicsHighPriorityQueue, - }; - - const step2Task = new GenomicsTask( - this, - step2TaskProps.taskName, - step2TaskProps - ).task; - - const definition = step1Task.next(step2Task); - - const stateMachineProps = { - definition, - stateMachineName: "genomics-pipelines-state-machine", - timeout: cdk.Duration.hours(1), - }; - - new sfn.StateMachine( - this, - stateMachineProps.stateMachineName, - stateMachineProps - ); - } -} diff --git a/src/aws-genomics-cdk/lib/step-functions/job-definitions.ts b/src/aws-genomics-cdk/lib/step-functions/job-definitions.ts deleted file mode 100644 index 703c56bb4..000000000 --- a/src/aws-genomics-cdk/lib/step-functions/job-definitions.ts +++ /dev/null @@ -1,68 +0,0 @@ -import * as cdk from "@aws-cdk/core"; -import * as iam from "@aws-cdk/aws-iam"; - -export enum GenomicsJobDefinitionTypes { - FASTQC = "fastqc", - MINIMAP2 = "minimap2" -} - -export interface GenomicsJobDefinitionProps { - readonly repository: string; - readonly jobDefinitionName?: string; - readonly retryAttempts?: number; - readonly timeout?: number; - readonly env: cdk.ResourceEnvironment; - readonly stack: cdk.Stack; - readonly jobRole: iam.Role; - readonly memoryLimit?: number; - readonly vcpus?: number; -} - -class JobDefinitionBase implements GenomicsJobDefinitionProps { - public repository: string; - public jobDefinitionName: string; - public retryAttempts?: number; - public timeout?: number; - public env: cdk.ResourceEnvironment; - public stack: cdk.Stack; - public jobRole: iam.Role; - public memoryLimit?: number; - public vcpus?: number; - - constructor() { - this.retryAttempts = 1; - this.timeout = 3600; - this.memoryLimit = 16000; - this.vcpus = 8; - } -} - -export class FastQcJobDefinition extends JobDefinitionBase { - constructor(props: GenomicsJobDefinitionProps) { - super(); - this.repository = props.repository; - this.jobDefinitionName = GenomicsJobDefinitionTypes.FASTQC; - this.retryAttempts = props.retryAttempts ?? this.retryAttempts; - this.timeout = props.timeout ?? this.timeout; - this.env = props.env; - this.stack = props.stack; - this.jobRole = props.jobRole; - this.memoryLimit = props.memoryLimit ?? this.memoryLimit; - this.vcpus = props.vcpus ?? this.vcpus; - } -} - -export class Minimap2JObDefinition extends JobDefinitionBase { - constructor(props: GenomicsJobDefinitionProps) { - super(); - this.repository = props.repository; - this.jobDefinitionName = GenomicsJobDefinitionTypes.MINIMAP2; - this.retryAttempts = props.retryAttempts ?? this.retryAttempts; - this.timeout = props.timeout ?? this.timeout; - this.env = props.env; - this.stack = props.stack; - this.jobRole = props.jobRole; - this.memoryLimit = props.memoryLimit ?? this.memoryLimit; - this.vcpus = props.vcpus ?? this.vcpus; - } -} \ No newline at end of file diff --git a/src/aws-genomics-cdk/lib/vpc/vpc-stack.ts b/src/aws-genomics-cdk/lib/vpc/vpc-stack.ts index e72678f9c..895e1e484 100644 --- a/src/aws-genomics-cdk/lib/vpc/vpc-stack.ts +++ b/src/aws-genomics-cdk/lib/vpc/vpc-stack.ts @@ -23,10 +23,10 @@ export default class GenomicsVpcStack extends cdk.Stack { const vpcProp = { cidr: config.VPC.cidr, - max_azs: config.VPC.maxAZs, + maxAZs: config.VPC.maxAZs, subnetConfiguration: subnetConf }; - this.vpc = new ec2.Vpc(this, "genomics-vpc", vpcProp); + this.vpc = new ec2.Vpc(this, config.VPC.VPCName, vpcProp); } } diff --git a/src/aws-genomics-cdk/lib/step-functions/genomics-task-construct.ts b/src/aws-genomics-cdk/lib/workflows/genomics-task-construct.ts similarity index 100% rename from src/aws-genomics-cdk/lib/step-functions/genomics-task-construct.ts rename to src/aws-genomics-cdk/lib/workflows/genomics-task-construct.ts diff --git a/src/aws-genomics-cdk/lib/step-functions/job-definition-construct.ts b/src/aws-genomics-cdk/lib/workflows/job-definition-construct.ts similarity index 90% rename from src/aws-genomics-cdk/lib/step-functions/job-definition-construct.ts rename to src/aws-genomics-cdk/lib/workflows/job-definition-construct.ts index 93e4fdfcb..2a6671f0e 100644 --- a/src/aws-genomics-cdk/lib/step-functions/job-definition-construct.ts +++ b/src/aws-genomics-cdk/lib/workflows/job-definition-construct.ts @@ -49,11 +49,11 @@ export default class GenomicsJobDefinition extends cdk.Construct{ const jobDefinitionProps = { container: jobDefinitionContainerProps, - jobDefinitionName: props.jobDefinitionName as string, + jobDefinitionName: id, retryAttempts: props.retryAttempts ?? 1, timeout: cdk.Duration.seconds(props.timeout ?? 3600) }; - this.jobDefinition = new batch.JobDefinition(this, jobDefinitionProps.jobDefinitionName, jobDefinitionProps); + this.jobDefinition = new batch.JobDefinition(this, id, jobDefinitionProps); } } \ No newline at end of file diff --git a/src/aws-genomics-cdk/lib/workflows/job-definitions.ts b/src/aws-genomics-cdk/lib/workflows/job-definitions.ts new file mode 100644 index 000000000..8dc951183 --- /dev/null +++ b/src/aws-genomics-cdk/lib/workflows/job-definitions.ts @@ -0,0 +1,132 @@ +import * as cdk from "@aws-cdk/core"; +import * as iam from "@aws-cdk/aws-iam"; + +export enum GenomicsJobDefinitionTypes { + FASTQC = "fastqc", + MINIMAP2 = "minimap2", + GATK = "gatk", + BWA = "bwa", + SAMTOOLS = "samtools", + PICARD = "picard" +} + +export interface GenomicsJobDefinitionProps { + readonly repository: string; + readonly jobDefinitionName?: string; + readonly retryAttempts?: number; + readonly timeout?: number; + readonly env: cdk.ResourceEnvironment; + readonly stack: cdk.Stack; + readonly jobRole: iam.Role; + readonly memoryLimit?: number; + readonly vcpus?: number; +} + +export class JobDefinitionBase implements GenomicsJobDefinitionProps { + public repository: string; + public jobDefinitionName: string; + public retryAttempts?: number; + public timeout?: number; + public env: cdk.ResourceEnvironment; + public stack: cdk.Stack; + public jobRole: iam.Role; + public memoryLimit?: number; + public vcpus?: number; + + constructor() { + this.retryAttempts = 1; + this.timeout = 3600; + this.memoryLimit = 16000; + this.vcpus = 8; + } +} + +export class FastQcJobDefinition extends JobDefinitionBase { + constructor(props: GenomicsJobDefinitionProps) { + super(); + this.repository = props.repository; + this.jobDefinitionName = GenomicsJobDefinitionTypes.FASTQC; + this.retryAttempts = props.retryAttempts ?? this.retryAttempts; + this.timeout = props.timeout ?? this.timeout; + this.env = props.env; + this.stack = props.stack; + this.jobRole = props.jobRole; + this.memoryLimit = props.memoryLimit ?? this.memoryLimit; + this.vcpus = props.vcpus ?? this.vcpus; + } +} + +export class Minimap2JObDefinition extends JobDefinitionBase { + constructor(props: GenomicsJobDefinitionProps) { + super(); + this.repository = props.repository; + this.jobDefinitionName = GenomicsJobDefinitionTypes.MINIMAP2; + this.retryAttempts = props.retryAttempts ?? this.retryAttempts; + this.timeout = props.timeout ?? this.timeout; + this.env = props.env; + this.stack = props.stack; + this.jobRole = props.jobRole; + this.memoryLimit = props.memoryLimit ?? this.memoryLimit; + this.vcpus = props.vcpus ?? this.vcpus; + } +} + +export class GatkJObDefinition extends JobDefinitionBase { + constructor(props: GenomicsJobDefinitionProps) { + super(); + this.repository = props.repository; + this.jobDefinitionName = GenomicsJobDefinitionTypes.GATK; + this.retryAttempts = props.retryAttempts ?? this.retryAttempts; + this.timeout = props.timeout ?? this.timeout; + this.env = props.env; + this.stack = props.stack; + this.jobRole = props.jobRole; + this.memoryLimit = props.memoryLimit ?? this.memoryLimit; + this.vcpus = props.vcpus ?? this.vcpus; + } +} + +export class BwaJObDefinition extends JobDefinitionBase { + constructor(props: GenomicsJobDefinitionProps) { + super(); + this.repository = props.repository; + this.jobDefinitionName = GenomicsJobDefinitionTypes.BWA; + this.retryAttempts = props.retryAttempts ?? this.retryAttempts; + this.timeout = props.timeout ?? this.timeout; + this.env = props.env; + this.stack = props.stack; + this.jobRole = props.jobRole; + this.memoryLimit = props.memoryLimit ?? this.memoryLimit; + this.vcpus = props.vcpus ?? this.vcpus; + } +} + +export class SamToolsJObDefinition extends JobDefinitionBase { + constructor(props: GenomicsJobDefinitionProps) { + super(); + this.repository = props.repository; + this.jobDefinitionName = GenomicsJobDefinitionTypes.SAMTOOLS; + this.retryAttempts = props.retryAttempts ?? this.retryAttempts; + this.timeout = props.timeout ?? this.timeout; + this.env = props.env; + this.stack = props.stack; + this.jobRole = props.jobRole; + this.memoryLimit = props.memoryLimit ?? this.memoryLimit; + this.vcpus = props.vcpus ?? this.vcpus; + } +} + +export class PicardJObDefinition extends JobDefinitionBase { + constructor(props: GenomicsJobDefinitionProps) { + super(); + this.repository = props.repository; + this.jobDefinitionName = GenomicsJobDefinitionTypes.PICARD; + this.retryAttempts = props.retryAttempts ?? this.retryAttempts; + this.timeout = props.timeout ?? this.timeout; + this.env = props.env; + this.stack = props.stack; + this.jobRole = props.jobRole; + this.memoryLimit = props.memoryLimit ?? this.memoryLimit; + this.vcpus = props.vcpus ?? this.vcpus; + } +} \ No newline at end of file diff --git a/src/aws-genomics-cdk/lib/workflows/variant-calling-stack.ts b/src/aws-genomics-cdk/lib/workflows/variant-calling-stack.ts new file mode 100644 index 000000000..43babde50 --- /dev/null +++ b/src/aws-genomics-cdk/lib/workflows/variant-calling-stack.ts @@ -0,0 +1,298 @@ +import * as cdk from "@aws-cdk/core"; +import * as batch from "@aws-cdk/aws-batch"; +import * as sfn from "@aws-cdk/aws-stepfunctions"; +import * as iam from "@aws-cdk/aws-iam"; +import * as jobDefinitions from "./job-definitions"; +import * as tasks from "@aws-cdk/aws-stepfunctions-tasks"; +import GenomicsTask from "./genomics-task-construct"; +import GenomicsJobDefinition from "./job-definition-construct"; + +export interface GenomicsStateMachineProps { + readonly stackProps: cdk.StackProps; + readonly batchQueue: batch.JobQueue; + readonly taskRole: iam.Role; +} + +/** + * A stack for variant calling using GATK HaplotypeCaller + * The stack will set the following pipeline: + * FastQC -> bwa mem -> samtools sort -> samtools index -> GATK HaplotypeCaller + * + * The result for each step will be stage via S3 and will be used for the next + * step of the pipeline. + * + * The final output will be a realigned reads stored in a bam file on S3 + * + **/ +export default class VariantCallingStateMachine extends cdk.Stack { + getTimeout(defs: jobDefinitions.JobDefinitionBase[]): number { + let result: number = 0; + for (let i = 0; i < defs.length; i++) { + result += (defs[i].timeout ?? 3600) * (defs[i].retryAttempts ?? 1); + } + return result; + } + + constructor( + scope: cdk.Construct, + id: string, + props: GenomicsStateMachineProps + ) { + super(scope, id, props.stackProps); + + // Default properties for initializing a job definition class + const defaultJobDefinitionProps = { + env: props.stackProps.env as cdk.ResourceEnvironment, + stack: this, + jobRole: props.taskRole, + }; + + // Initialzing a job definition for the gatk tool to run create dictionary + // This won't be used as part of the pipeline but just create a batch job + // definition that can be used to create a dictionary to reference databases + const gatkCreateDisctionary = new jobDefinitions.GatkJObDefinition({ + ...defaultJobDefinitionProps, + repository: "genomics/gatk", + timeout: 600, + memoryLimit: 8000, + vcpus: 4, + }); + + new GenomicsJobDefinition( + this, + `${gatkCreateDisctionary.jobDefinitionName}CreateSequenceDictionary`, + gatkCreateDisctionary + ); + + // Initialzie a job definition for the FastQC tool + const fastQC = new jobDefinitions.FastQcJobDefinition({ + ...defaultJobDefinitionProps, + repository: "genomics/fastqc", + timeout: 600, + memoryLimit: 1000, + vcpus: 1, + }); + + // Initilalize a job definitiion for the BWA tool to run bwa mem + const bwaMem = new jobDefinitions.BwaJObDefinition({ + ...defaultJobDefinitionProps, + repository: "genomics/bwa", + timeout: 600, + memoryLimit: 8000, + vcpus: 8, + }); + + // Initilalize a job definitiion for the sam tool to run samtools sort + const samToolsSort = new jobDefinitions.SamToolsJObDefinition({ + ...defaultJobDefinitionProps, + repository: "genomics/samtools", + timeout: 300, + memoryLimit: 8000, + vcpus: 4, + }); + + // Initilalize a job definitiion for the sam tool to run samtools index + const samToolsIndex = new jobDefinitions.SamToolsJObDefinition({ + ...defaultJobDefinitionProps, + repository: "genomics/samtools", + timeout: 300, + memoryLimit: 1000, + vcpus: 1, + }); + + // Initialize a job definition for the picard tool to add missing groups + const picardAddMissingGroups = new jobDefinitions.PicardJObDefinition({ + ...defaultJobDefinitionProps, + repository: "genomics/picard", + timeout: 600, + memoryLimit: 8000, + vcpus: 4, + }); + + // Initilalize a job definitiion for the gatk tool to run gatk HaplotypeCaller + const gatkHaplotypeCaller = new jobDefinitions.GatkJObDefinition({ + ...defaultJobDefinitionProps, + repository: "genomics/gatk", + timeout: 3600, + memoryLimit: 16000, + vcpus: 8, + }); + + // Set the total timeout for the entire execution + const totalTimeout = this.getTimeout([ + fastQC, + bwaMem, + samToolsSort, + samToolsIndex, + gatkHaplotypeCaller, + ]); + + // Set the first task to FastQC + const step1TaskProps = { + taskName: "FASTQC", + environment: { + JOB_INPUTS: sfn.JsonPath.stringAt("$.params.fastqc.input"), + JOB_OUTPUTS: sfn.JsonPath.stringAt("$.params.fastqc.output"), + }, + command: ["fastqc *.gz"], + jobDefinition: new GenomicsJobDefinition( + this, + fastQC.jobDefinitionName, + fastQC + ).jobDefinition, + queue: props.batchQueue, + }; + + const step1Task = new GenomicsTask( + this, + step1TaskProps.taskName, + step1TaskProps + ).task; + + // Set the second task to bwa mem + const step2TaskProps = { + taskName: "BWAMEM", + environment: { + JOB_INPUTS: sfn.JsonPath.stringAt("$.params.bwa.input"), + SAMPLE_ID: sfn.JsonPath.stringAt("$.params.common.sampleId"), + REFERENCE_NAME: sfn.JsonPath.stringAt("$.params.common.referenceName"), + JOB_OUTPUTS: sfn.JsonPath.stringAt("$.params.bwa.output"), + }, + command: [ + "bwa mem -t 8 -p ", + " -o ${SAMPLE_ID}.sam ${REFERENCE_NAME}.fasta ${SAMPLE_ID}_*1*.fastq.gz" + ], + jobDefinition: new GenomicsJobDefinition( + this, + bwaMem.jobDefinitionName, + bwaMem + ).jobDefinition, + queue: props.batchQueue, + }; + + const step2Task = new GenomicsTask( + this, + step2TaskProps.taskName, + step2TaskProps + ).task; + + // Set the third task to samtools sort + const step3TaskProps = { + taskName: "SAMTOOLS-SORT", + environment: { + JOB_INPUTS: sfn.JsonPath.stringAt("$.params.samtoolsSort.input"), + SAMPLE_ID: sfn.JsonPath.stringAt("$.params.common.sampleId"), + JOB_OUTPUTS: sfn.JsonPath.stringAt("$.params.samtoolsSort.output"), + }, + command: ["samtools sort -@ 4 -o ${SAMPLE_ID}.bam ${SAMPLE_ID}.sam"], + jobDefinition: new GenomicsJobDefinition( + this, + `${samToolsSort.jobDefinitionName}Sort`, + samToolsSort + ).jobDefinition, + queue: props.batchQueue, + }; + + const step3Task = new GenomicsTask( + this, + step3TaskProps.taskName, + step3TaskProps + ).task; + + // set the forth task to picard AddOrReplaceReadGroups + const step4TaskProps = { + taskName: "PICARD-ADDMISSINGGROUPS", + environment: { + JOB_INPUTS: sfn.JsonPath.stringAt("$.params.picard.input"), + SAMPLE_ID: sfn.JsonPath.stringAt("$.params.common.sampleId"), + JOB_OUTPUTS: sfn.JsonPath.stringAt("$.params.picard.output"), + }, + command: [ + "java -jar /usr/picard/picard.jar AddOrReplaceReadGroups", + " -I ${SAMPLE_ID}.bam -O ${SAMPLE_ID}.rg.bam -RGID 4 --RGLB lib1", + " --RGPL ILLUMINA --RGPU unit1 --RGSM 20;", + " mv ${SAMPLE_ID}.rg.bam ${SAMPLE_ID}.bam", + ], + jobDefinition: new GenomicsJobDefinition( + this, + `${picardAddMissingGroups.jobDefinitionName}AddMissingGroups`, + picardAddMissingGroups + ).jobDefinition, + queue: props.batchQueue, + }; + + const step4Task = new GenomicsTask( + this, + step4TaskProps.taskName, + step4TaskProps + ).task; + + // Set the fifth task to samtools index + const step5TaskProps = { + taskName: "SAMTOOLS-INDEX", + environment: { + JOB_INPUTS: sfn.JsonPath.stringAt("$.params.samtoolsIndex.input"), + SAMPLE_ID: sfn.JsonPath.stringAt("$.params.common.sampleId"), + JOB_OUTPUTS: sfn.JsonPath.stringAt("$.params.samtoolsIndex.output"), + }, + command: ["samtools index ${SAMPLE_ID}.bam"], + jobDefinition: new GenomicsJobDefinition( + this, + `${samToolsIndex.jobDefinitionName}Index`, + samToolsIndex + ).jobDefinition, + queue: props.batchQueue, + }; + + const step5Task = new GenomicsTask( + this, + step5TaskProps.taskName, + step5TaskProps + ).task; + + // set the fifth task to gatk HaplotypeCaller + const step6TaskProps = { + taskName: "GATK-HAPLOTYPECALLER", + environment: { + JOB_INPUTS: sfn.JsonPath.stringAt("$.params.gatk.input"), + SAMPLE_ID: sfn.JsonPath.stringAt("$.params.common.sampleId"), + REFERENCE_NAME: sfn.JsonPath.stringAt("$.params.common.referenceName"), + JOB_OUTPUTS: sfn.JsonPath.stringAt("$.params.gatk.output"), + JOB_INPUT_S3_COPY_METHOD: "s3sync" + }, + command: [ + 'gatk --java-options "-Xmx4g" HaplotypeCaller', + ' -R ${REFERENCE_NAME}.fasta -I ${SAMPLE_ID}.bam', + ' -O ${SAMPLE_ID}.vcf.gz -bamout ${SAMPLE_ID}.out.bam', + ], + jobDefinition: new GenomicsJobDefinition( + this, + `${gatkHaplotypeCaller.jobDefinitionName}HaplotypeCaller`, + gatkHaplotypeCaller + ).jobDefinition, + queue: props.batchQueue, + }; + + const step6Task = new GenomicsTask( + this, + step6TaskProps.taskName, + step6TaskProps + ).task; + + const definition = step1Task.next( + step2Task.next(step3Task.next(step4Task.next(step5Task.next(step6Task)))) + ); + + const stateMachineProps = { + definition, + stateMachineName: "genomics-pipelines-variant-calling", + timeout: cdk.Duration.seconds(totalTimeout), + }; + + new sfn.StateMachine( + this, + stateMachineProps.stateMachineName, + stateMachineProps + ); + } +} diff --git a/src/aws-genomics-cdk/lib/workflows/workflow-config.ts b/src/aws-genomics-cdk/lib/workflows/workflow-config.ts new file mode 100644 index 000000000..3bef5e641 --- /dev/null +++ b/src/aws-genomics-cdk/lib/workflows/workflow-config.ts @@ -0,0 +1,4 @@ +export interface WorkflowConfig { + readonly name: string; + readonly spot: boolean; +} \ No newline at end of file diff --git a/src/aws-genomics-cdk/package-lock.json b/src/aws-genomics-cdk/package-lock.json index 8a31410ac..f91dbd911 100644 --- a/src/aws-genomics-cdk/package-lock.json +++ b/src/aws-genomics-cdk/package-lock.json @@ -5,252 +5,253 @@ "requires": true, "dependencies": { "@aws-cdk/assert": { - "version": "1.93.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/assert/-/assert-1.93.0.tgz", - "integrity": "sha512-yiQPc+gNjUSGg0VgTK55uzyP4QZdYhGZVhIxF2Imlr3FhTb8uYybYSzx+yhrYhxPnUmnP3BN/0rJexn4gR6iow==", + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/assert/-/assert-1.96.0.tgz", + "integrity": "sha512-IcnV35/g1L8BlceMS5h/aAYXR/pecR8ltbRGxMK/f9nArjrg2Nn7fowM7B1PxdrSFpbBzcEL4Lm8G+hXFmxfcg==", "dev": true, "requires": { - "@aws-cdk/cloud-assembly-schema": "1.93.0", - "@aws-cdk/cloudformation-diff": "1.93.0", - "@aws-cdk/core": "1.93.0", - "@aws-cdk/cx-api": "1.93.0", - "constructs": "^3.2.0" + "@aws-cdk/cloud-assembly-schema": "1.96.0", + "@aws-cdk/cloudformation-diff": "1.96.0", + "@aws-cdk/core": "1.96.0", + "@aws-cdk/cx-api": "1.96.0", + "constructs": "^3.3.69" } }, "@aws-cdk/assets": { - "version": "1.93.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/assets/-/assets-1.93.0.tgz", - "integrity": "sha512-fUt6OqjkH0kJ9cpJftJl7W6FMGYlIVuK8jL8/72ouQL8CBEnasjsDRp9DWxT7cH1RWkieYrd3JKWLqVg3FDc+g==", + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/assets/-/assets-1.96.0.tgz", + "integrity": "sha512-gt+BNsFCUs/SCvwKhifZhEtsZNBFvzbUFrNaheCbNvbhs+k04/tBTEnOeoNLaCdD3yWXMnbxaxah1H76QADx9A==", "requires": { - "@aws-cdk/core": "1.93.0", - "@aws-cdk/cx-api": "1.93.0", - "constructs": "^3.2.0" + "@aws-cdk/core": "1.96.0", + "@aws-cdk/cx-api": "1.96.0", + "constructs": "^3.3.69" } }, "@aws-cdk/aws-apigateway": { - "version": "1.93.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/aws-apigateway/-/aws-apigateway-1.93.0.tgz", - "integrity": "sha512-korbRqW3H8LKEGaPDLPo4FrtENVLE0WsYzkhP7JB6SCrHCZWJM4RuCOax88n/rvz6Hw0LSrIPEynzueV11XOcA==", - "requires": { - "@aws-cdk/aws-certificatemanager": "1.93.0", - "@aws-cdk/aws-cloudwatch": "1.93.0", - "@aws-cdk/aws-cognito": "1.93.0", - "@aws-cdk/aws-ec2": "1.93.0", - "@aws-cdk/aws-elasticloadbalancingv2": "1.93.0", - "@aws-cdk/aws-iam": "1.93.0", - "@aws-cdk/aws-lambda": "1.93.0", - "@aws-cdk/aws-logs": "1.93.0", - "@aws-cdk/aws-s3": "1.93.0", - "@aws-cdk/aws-s3-assets": "1.93.0", - "@aws-cdk/core": "1.93.0", - "@aws-cdk/cx-api": "1.93.0", - "constructs": "^3.2.0" + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-apigateway/-/aws-apigateway-1.96.0.tgz", + "integrity": "sha512-XP5BZbA+tt2MAKACwDC31aW/X4UYBBvNEYXNxXjrbiL3xhe6Rnsi/ols9WsRRoflLLlimPhu3/YHiiUsQ5LzDw==", + "requires": { + "@aws-cdk/aws-certificatemanager": "1.96.0", + "@aws-cdk/aws-cloudwatch": "1.96.0", + "@aws-cdk/aws-cognito": "1.96.0", + "@aws-cdk/aws-ec2": "1.96.0", + "@aws-cdk/aws-elasticloadbalancingv2": "1.96.0", + "@aws-cdk/aws-iam": "1.96.0", + "@aws-cdk/aws-lambda": "1.96.0", + "@aws-cdk/aws-logs": "1.96.0", + "@aws-cdk/aws-s3": "1.96.0", + "@aws-cdk/aws-s3-assets": "1.96.0", + "@aws-cdk/core": "1.96.0", + "@aws-cdk/cx-api": "1.96.0", + "constructs": "^3.3.69" } }, "@aws-cdk/aws-apigatewayv2": { - "version": "1.93.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/aws-apigatewayv2/-/aws-apigatewayv2-1.93.0.tgz", - "integrity": "sha512-OFKnlwsPcrHhItclW94SwrHJxxHU4hJzMHjqlGqPm1XI6oBx0q/dXWdo+I+uq+fMMDYGzbc8zvxz5H+v+6A/2w==", + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-apigatewayv2/-/aws-apigatewayv2-1.96.0.tgz", + "integrity": "sha512-qZVCHcJUXAV42h/ZiNa2eANW7+5kPYwFeJCLT82L/HUZKprkOzWazb90JIfpTYs9jjMI/pPtSEoAftd/2uwvcQ==", "requires": { - "@aws-cdk/aws-certificatemanager": "1.93.0", - "@aws-cdk/aws-cloudwatch": "1.93.0", - "@aws-cdk/aws-ec2": "1.93.0", - "@aws-cdk/aws-iam": "1.93.0", - "@aws-cdk/core": "1.93.0", - "constructs": "^3.2.0" + "@aws-cdk/aws-certificatemanager": "1.96.0", + "@aws-cdk/aws-cloudwatch": "1.96.0", + "@aws-cdk/aws-ec2": "1.96.0", + "@aws-cdk/aws-iam": "1.96.0", + "@aws-cdk/core": "1.96.0", + "constructs": "^3.3.69" } }, "@aws-cdk/aws-apigatewayv2-integrations": { - "version": "1.93.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/aws-apigatewayv2-integrations/-/aws-apigatewayv2-integrations-1.93.0.tgz", - "integrity": "sha512-R7HB7+t0PKjrk/zLNwKJzabJd7eVqz32F3xRIn4hvt6RCqJNADYJuqjTvqR84Vvj97QmsgbjYUv2lNvetBl6Nw==", + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-apigatewayv2-integrations/-/aws-apigatewayv2-integrations-1.96.0.tgz", + "integrity": "sha512-SffGJaOd8uriPf7sGwN6Ll/+nn1gMq7l/ZqVru1KWkwG0BZnJrdBgrBWa4HQ7ZVlzKtfa4cftwE7hmxZZdQl/g==", "requires": { - "@aws-cdk/aws-apigatewayv2": "1.93.0", - "@aws-cdk/aws-ec2": "1.93.0", - "@aws-cdk/aws-elasticloadbalancingv2": "1.93.0", - "@aws-cdk/aws-iam": "1.93.0", - "@aws-cdk/aws-lambda": "1.93.0", - "@aws-cdk/aws-servicediscovery": "1.93.0", - "@aws-cdk/core": "1.93.0", - "constructs": "^3.2.0" + "@aws-cdk/aws-apigatewayv2": "1.96.0", + "@aws-cdk/aws-ec2": "1.96.0", + "@aws-cdk/aws-elasticloadbalancingv2": "1.96.0", + "@aws-cdk/aws-iam": "1.96.0", + "@aws-cdk/aws-lambda": "1.96.0", + "@aws-cdk/aws-servicediscovery": "1.96.0", + "@aws-cdk/core": "1.96.0", + "constructs": "^3.3.69" } }, "@aws-cdk/aws-applicationautoscaling": { - "version": "1.93.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/aws-applicationautoscaling/-/aws-applicationautoscaling-1.93.0.tgz", - "integrity": "sha512-mPXCunz/3QwOthrw+VRZ5EGRV+W8S3LuKxWMjCp/Ij6q8DXY74TFRmznOiEE3e6rW3/Pl3BZdLu3V4Ctl6oGOg==", + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-applicationautoscaling/-/aws-applicationautoscaling-1.96.0.tgz", + "integrity": "sha512-NxW709a4ioLHLK9/yi+mlBzjOMlXaXnXfpzwIu17AUcFQBitKyQ3vo/PAIZYFupI5BhidlgjFtD67CZlPZXZHg==", "requires": { - "@aws-cdk/aws-autoscaling-common": "1.93.0", - "@aws-cdk/aws-cloudwatch": "1.93.0", - "@aws-cdk/aws-iam": "1.93.0", - "@aws-cdk/core": "1.93.0", - "constructs": "^3.2.0" + "@aws-cdk/aws-autoscaling-common": "1.96.0", + "@aws-cdk/aws-cloudwatch": "1.96.0", + "@aws-cdk/aws-iam": "1.96.0", + "@aws-cdk/core": "1.96.0", + "constructs": "^3.3.69" } }, "@aws-cdk/aws-autoscaling": { - "version": "1.93.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/aws-autoscaling/-/aws-autoscaling-1.93.0.tgz", - "integrity": "sha512-AZ7J1ZDxZe9HX00PhY/yRBUXPjJTots1+Xi9eTmXf8oetxJpPIpy3/23XMcGbO+QvWlWMbTKvNljM4C4ZLEhqg==", + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-autoscaling/-/aws-autoscaling-1.96.0.tgz", + "integrity": "sha512-AUX0Fg+sduris7u0xGLUoO8Vf4NtKEm9zM3mZzlMk2tanZ7tUrnp2M54fFXxcFiwF37r2KE2ioosG9n+7jLb1w==", "requires": { - "@aws-cdk/aws-autoscaling-common": "1.93.0", - "@aws-cdk/aws-cloudwatch": "1.93.0", - "@aws-cdk/aws-ec2": "1.93.0", - "@aws-cdk/aws-elasticloadbalancing": "1.93.0", - "@aws-cdk/aws-elasticloadbalancingv2": "1.93.0", - "@aws-cdk/aws-iam": "1.93.0", - "@aws-cdk/aws-sns": "1.93.0", - "@aws-cdk/core": "1.93.0", - "constructs": "^3.2.0" + "@aws-cdk/aws-autoscaling-common": "1.96.0", + "@aws-cdk/aws-cloudwatch": "1.96.0", + "@aws-cdk/aws-ec2": "1.96.0", + "@aws-cdk/aws-elasticloadbalancing": "1.96.0", + "@aws-cdk/aws-elasticloadbalancingv2": "1.96.0", + "@aws-cdk/aws-iam": "1.96.0", + "@aws-cdk/aws-sns": "1.96.0", + "@aws-cdk/core": "1.96.0", + "constructs": "^3.3.69" } }, "@aws-cdk/aws-autoscaling-common": { - "version": "1.93.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/aws-autoscaling-common/-/aws-autoscaling-common-1.93.0.tgz", - "integrity": "sha512-bfWYi0Zlzqg6ZfRyDU3HLxAjbB69v3nf1bO++27jrrPPE/j79fx7f9SYmtbbJnwPaUiBeeLm23I8PERyBLOmNQ==", + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-autoscaling-common/-/aws-autoscaling-common-1.96.0.tgz", + "integrity": "sha512-i3lBOLNW4dvGDYLVdvnnFOmV5JmpsHg6tSKDMHdtfsYqR3lswfAg+qAuAmazYIz2JlG+UVIJRmcSmZVEQKKpIA==", "requires": { - "@aws-cdk/aws-iam": "1.93.0", - "@aws-cdk/core": "1.93.0", - "constructs": "^3.2.0" + "@aws-cdk/aws-iam": "1.96.0", + "@aws-cdk/core": "1.96.0", + "constructs": "^3.3.69" } }, "@aws-cdk/aws-autoscaling-hooktargets": { - "version": "1.93.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/aws-autoscaling-hooktargets/-/aws-autoscaling-hooktargets-1.93.0.tgz", - "integrity": "sha512-YKWLZYr527rb+WA7rRxeLhxDB9D5I3Og0rRVmsu/tgPm60/MNcsVU5ps1MlNCWMxfZHQ19zXwgbIK0aQdzMvQg==", + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-autoscaling-hooktargets/-/aws-autoscaling-hooktargets-1.96.0.tgz", + "integrity": "sha512-a8KKkjpHjv++5Vz2waQWisv+Hs3lN7/iUOTNadCEMECjdrQe0tX5qCh/8FsxGv/EQXMhMOGYCY3S+uW3SYJIuA==", "requires": { - "@aws-cdk/aws-autoscaling": "1.93.0", - "@aws-cdk/aws-iam": "1.93.0", - "@aws-cdk/aws-kms": "1.93.0", - "@aws-cdk/aws-lambda": "1.93.0", - "@aws-cdk/aws-sns": "1.93.0", - "@aws-cdk/aws-sns-subscriptions": "1.93.0", - "@aws-cdk/aws-sqs": "1.93.0", - "@aws-cdk/core": "1.93.0", - "constructs": "^3.2.0" + "@aws-cdk/aws-autoscaling": "1.96.0", + "@aws-cdk/aws-iam": "1.96.0", + "@aws-cdk/aws-kms": "1.96.0", + "@aws-cdk/aws-lambda": "1.96.0", + "@aws-cdk/aws-sns": "1.96.0", + "@aws-cdk/aws-sns-subscriptions": "1.96.0", + "@aws-cdk/aws-sqs": "1.96.0", + "@aws-cdk/core": "1.96.0", + "constructs": "^3.3.69" } }, "@aws-cdk/aws-batch": { - "version": "1.93.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/aws-batch/-/aws-batch-1.93.0.tgz", - "integrity": "sha512-62iBagaWuFs8WyU0KIAJrfHb9aHTy3lEj+NczFGfsn+Bq2CWBOCheLGiHxI7smlYamw/O5Ru9NgCXoKbEQhVuQ==", + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-batch/-/aws-batch-1.96.0.tgz", + "integrity": "sha512-QKMKRwoG9FBWq8INUQCfuj6M+DQ8SvRHdRe3ZWFJQ8FL5bEvWltgLLwd0ixCzJojj3wrfJoEroCB2KaEYa/6CQ==", "requires": { - "@aws-cdk/aws-ec2": "1.93.0", - "@aws-cdk/aws-ecr": "1.93.0", - "@aws-cdk/aws-ecs": "1.93.0", - "@aws-cdk/aws-iam": "1.93.0", - "@aws-cdk/aws-secretsmanager": "1.93.0", - "@aws-cdk/aws-ssm": "1.93.0", - "@aws-cdk/core": "1.93.0", - "constructs": "^3.2.0" + "@aws-cdk/aws-ec2": "1.96.0", + "@aws-cdk/aws-ecr": "1.96.0", + "@aws-cdk/aws-ecs": "1.96.0", + "@aws-cdk/aws-iam": "1.96.0", + "@aws-cdk/aws-secretsmanager": "1.96.0", + "@aws-cdk/aws-ssm": "1.96.0", + "@aws-cdk/core": "1.96.0", + "constructs": "^3.3.69" } }, "@aws-cdk/aws-certificatemanager": { - "version": "1.93.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/aws-certificatemanager/-/aws-certificatemanager-1.93.0.tgz", - "integrity": "sha512-m0B0FS099i4JxlYl5m3pQeVzs+kzX5r7ecoKOcJ0F3AE1IUndb6ODf3E/CPEP9A3IfOvCdF3yVv+TF3YQGVGLg==", + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-certificatemanager/-/aws-certificatemanager-1.96.0.tgz", + "integrity": "sha512-eCuSAj0gAbugVsbud28fhR2tS7LzhIzJTE2qLgqMb3kn1f/osToXgg8oJ7+qXiLcLpDquL8TuJW3GVFMKMkjEw==", "requires": { - "@aws-cdk/aws-iam": "1.93.0", - "@aws-cdk/aws-lambda": "1.93.0", - "@aws-cdk/aws-route53": "1.93.0", - "@aws-cdk/core": "1.93.0", - "constructs": "^3.2.0" + "@aws-cdk/aws-iam": "1.96.0", + "@aws-cdk/aws-lambda": "1.96.0", + "@aws-cdk/aws-route53": "1.96.0", + "@aws-cdk/core": "1.96.0", + "constructs": "^3.3.69" } }, "@aws-cdk/aws-cloudformation": { - "version": "1.93.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/aws-cloudformation/-/aws-cloudformation-1.93.0.tgz", - "integrity": "sha512-+2rw0atlRFErwuEqfO0b+rRKoVn4oo6mPbfBULKFabDYcu56oTobaKFJ2jBNtJyXojIws2qdghSp/qg4pp0rBA==", + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-cloudformation/-/aws-cloudformation-1.96.0.tgz", + "integrity": "sha512-wLcIfjxPU+mS0ys0O7TBQ0Ju7KdS83q6eS0qBlBelGpZQjjEi2RULOej2EpVMBAHXd3vEgGKrOUCEPbMP2jI/A==", "requires": { - "@aws-cdk/aws-iam": "1.93.0", - "@aws-cdk/aws-lambda": "1.93.0", - "@aws-cdk/aws-s3": "1.93.0", - "@aws-cdk/aws-sns": "1.93.0", - "@aws-cdk/core": "1.93.0", - "@aws-cdk/cx-api": "1.93.0", - "constructs": "^3.2.0" + "@aws-cdk/aws-iam": "1.96.0", + "@aws-cdk/aws-lambda": "1.96.0", + "@aws-cdk/aws-s3": "1.96.0", + "@aws-cdk/aws-sns": "1.96.0", + "@aws-cdk/core": "1.96.0", + "@aws-cdk/cx-api": "1.96.0", + "constructs": "^3.3.69" } }, "@aws-cdk/aws-cloudfront": { - "version": "1.93.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/aws-cloudfront/-/aws-cloudfront-1.93.0.tgz", - "integrity": "sha512-mthRLS5zs45Uwixiab4/EGqAkAmoup3A/JZ4VmXbjHM2zYvKb0a0gU/hQKwoX+kCpTjCpNcRJhoSZ6/ROLhjrg==", - "requires": { - "@aws-cdk/aws-certificatemanager": "1.93.0", - "@aws-cdk/aws-cloudwatch": "1.93.0", - "@aws-cdk/aws-ec2": "1.93.0", - "@aws-cdk/aws-iam": "1.93.0", - "@aws-cdk/aws-kms": "1.93.0", - "@aws-cdk/aws-lambda": "1.93.0", - "@aws-cdk/aws-s3": "1.93.0", - "@aws-cdk/aws-ssm": "1.93.0", - "@aws-cdk/core": "1.93.0", - "constructs": "^3.2.0" + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-cloudfront/-/aws-cloudfront-1.96.0.tgz", + "integrity": "sha512-P4fA72zbyXc2XRl5dlfmlSNVVm3EJUYQ4YKrTrqkT1l0pqPEIzc1Ad1o8zMBlEuyJ2EjLYASMv2Ik9Emc3ySgw==", + "requires": { + "@aws-cdk/aws-certificatemanager": "1.96.0", + "@aws-cdk/aws-cloudwatch": "1.96.0", + "@aws-cdk/aws-ec2": "1.96.0", + "@aws-cdk/aws-iam": "1.96.0", + "@aws-cdk/aws-kms": "1.96.0", + "@aws-cdk/aws-lambda": "1.96.0", + "@aws-cdk/aws-s3": "1.96.0", + "@aws-cdk/aws-ssm": "1.96.0", + "@aws-cdk/core": "1.96.0", + "constructs": "^3.3.69" } }, "@aws-cdk/aws-cloudwatch": { - "version": "1.93.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/aws-cloudwatch/-/aws-cloudwatch-1.93.0.tgz", - "integrity": "sha512-oN0RZO1bvxopJTTGX18hZNnatnrXqFjv0CxLnjAToYkuCx5GSuVpigJeK0YrzDqVWC80eVnuqHSJ9ORvLTJ0/g==", + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-cloudwatch/-/aws-cloudwatch-1.96.0.tgz", + "integrity": "sha512-vlYf3Jay+srt1A6SOX5/fcFWQmXcouTzDWQovvg36DWPNknH2dF9nHpf7YrEesj7Nwxlo9aA0MrFBYqThlsy3w==", "requires": { - "@aws-cdk/aws-iam": "1.93.0", - "@aws-cdk/core": "1.93.0", - "constructs": "^3.2.0" + "@aws-cdk/aws-iam": "1.96.0", + "@aws-cdk/core": "1.96.0", + "constructs": "^3.3.69" } }, "@aws-cdk/aws-codebuild": { - "version": "1.93.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/aws-codebuild/-/aws-codebuild-1.93.0.tgz", - "integrity": "sha512-xkvvL5kw7SOSwgThELxj/r5R8gLFdIFz9iQe8PXvextlCxmGWBFIzTWJofmx/MLIm7eqQF/55iT3vKJ3S0Byow==", - "requires": { - "@aws-cdk/aws-cloudwatch": "1.93.0", - "@aws-cdk/aws-codecommit": "1.93.0", - "@aws-cdk/aws-ec2": "1.93.0", - "@aws-cdk/aws-ecr": "1.93.0", - "@aws-cdk/aws-ecr-assets": "1.93.0", - "@aws-cdk/aws-events": "1.93.0", - "@aws-cdk/aws-iam": "1.93.0", - "@aws-cdk/aws-kms": "1.93.0", - "@aws-cdk/aws-logs": "1.93.0", - "@aws-cdk/aws-s3": "1.93.0", - "@aws-cdk/aws-s3-assets": "1.93.0", - "@aws-cdk/aws-secretsmanager": "1.93.0", - "@aws-cdk/core": "1.93.0", - "@aws-cdk/region-info": "1.93.0", - "constructs": "^3.2.0" + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-codebuild/-/aws-codebuild-1.96.0.tgz", + "integrity": "sha512-aEswphnappGAsnMXXNPEEVgUv0kx56+AJyTYE5OjctpIPWov6/RmpKhzqpFudGX16FmVDeXOo3m2U7kKYW/pXw==", + "requires": { + "@aws-cdk/aws-cloudwatch": "1.96.0", + "@aws-cdk/aws-codecommit": "1.96.0", + "@aws-cdk/aws-ec2": "1.96.0", + "@aws-cdk/aws-ecr": "1.96.0", + "@aws-cdk/aws-ecr-assets": "1.96.0", + "@aws-cdk/aws-events": "1.96.0", + "@aws-cdk/aws-iam": "1.96.0", + "@aws-cdk/aws-kms": "1.96.0", + "@aws-cdk/aws-logs": "1.96.0", + "@aws-cdk/aws-s3": "1.96.0", + "@aws-cdk/aws-s3-assets": "1.96.0", + "@aws-cdk/aws-secretsmanager": "1.96.0", + "@aws-cdk/core": "1.96.0", + "@aws-cdk/region-info": "1.96.0", + "@aws-cdk/yaml-cfn": "1.96.0", + "constructs": "^3.3.69" } }, "@aws-cdk/aws-codecommit": { - "version": "1.93.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/aws-codecommit/-/aws-codecommit-1.93.0.tgz", - "integrity": "sha512-+IHEUI7CkNseTzMCR6PFuIJf++FMuKUpPkaUSxoBmyUy6Mwtw6GDWQvvrN4d4RV45a4YWOdwD3WaKwEWvjqJ1w==", + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-codecommit/-/aws-codecommit-1.96.0.tgz", + "integrity": "sha512-sJb6K5U/9B55nmPuV6cer0FBWl8+IWYd7wJs+5jofXSEQ/PghiNGd0KAg+TSEbMTB3A/BxBTW0dnwXb076caQg==", "requires": { - "@aws-cdk/aws-events": "1.93.0", - "@aws-cdk/aws-iam": "1.93.0", - "@aws-cdk/core": "1.93.0", - "constructs": "^3.2.0" + "@aws-cdk/aws-events": "1.96.0", + "@aws-cdk/aws-iam": "1.96.0", + "@aws-cdk/core": "1.96.0", + "constructs": "^3.3.69" } }, "@aws-cdk/aws-codeguruprofiler": { - "version": "1.93.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/aws-codeguruprofiler/-/aws-codeguruprofiler-1.93.0.tgz", - "integrity": "sha512-ft+npsdzlokkh1mEjkAT21la4EeD33p7lv19ItfcYwgWsYR+LnzgxWRcUaa4dkKaAYlqZRy221YlkRvArngzxg==", + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-codeguruprofiler/-/aws-codeguruprofiler-1.96.0.tgz", + "integrity": "sha512-P+7U76bKLB0MDKCer6w1JqfnzmN05Ezi4SfqXMjURj89DB8sHs0SxUvkfGd2oN4VgeWa3S9Ko4KUmihNS59ILA==", "requires": { - "@aws-cdk/aws-iam": "1.93.0", - "@aws-cdk/core": "1.93.0", - "constructs": "^3.2.0" + "@aws-cdk/aws-iam": "1.96.0", + "@aws-cdk/core": "1.96.0", + "constructs": "^3.3.69" } }, "@aws-cdk/aws-cognito": { - "version": "1.93.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/aws-cognito/-/aws-cognito-1.93.0.tgz", - "integrity": "sha512-+07WMXa0kiaFeApaDM76+4XXFt7y71sIGy5QiTRrDKsRlSt9ja5XyAX9J2hSku06NaYRfSWY88e2TX/19R6yWA==", - "requires": { - "@aws-cdk/aws-certificatemanager": "1.93.0", - "@aws-cdk/aws-iam": "1.93.0", - "@aws-cdk/aws-lambda": "1.93.0", - "@aws-cdk/core": "1.93.0", - "@aws-cdk/custom-resources": "1.93.0", - "constructs": "^3.2.0", + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-cognito/-/aws-cognito-1.96.0.tgz", + "integrity": "sha512-TSo/jmGv9mWvj8MgBH0LMQ+IatP54sKqywBuREEy0qnNma/Uuii7JYZ4/YYXqc7hNtWyUNNXr+jzj89elI6w4w==", + "requires": { + "@aws-cdk/aws-certificatemanager": "1.96.0", + "@aws-cdk/aws-iam": "1.96.0", + "@aws-cdk/aws-lambda": "1.96.0", + "@aws-cdk/core": "1.96.0", + "@aws-cdk/custom-resources": "1.96.0", + "constructs": "^3.3.69", "punycode": "^2.1.1" }, "dependencies": { @@ -261,70 +262,70 @@ } }, "@aws-cdk/aws-databrew": { - "version": "1.93.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/aws-databrew/-/aws-databrew-1.93.0.tgz", - "integrity": "sha512-scLTMm3F8mx1RjMB0Mo/fCyGP+WH1WHKXj6ot5fkBhSv3Xn+1zGtPme2V64HbiwntNyQ3GB369VFcxypfqncEA==", + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-databrew/-/aws-databrew-1.96.0.tgz", + "integrity": "sha512-qoE4IHZ8Ps2iw6EVCwNV3VdN2jVcpEIAhxjht/98WMNI1k81yFzYngLqzJj7e3QPnSWslT4jLi52IVXwi1+tgQ==", "requires": { - "@aws-cdk/core": "1.93.0" + "@aws-cdk/core": "1.96.0" } }, "@aws-cdk/aws-dynamodb": { - "version": "1.93.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/aws-dynamodb/-/aws-dynamodb-1.93.0.tgz", - "integrity": "sha512-y9fzUfvwBVhxdcCkj/Gr0QWsUwkf3TIxvxwgY3VsfM3C7HzIjz4P6D+BbA1kOui0zyPhMJkcnfkdG5PObI3F6g==", + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-dynamodb/-/aws-dynamodb-1.96.0.tgz", + "integrity": "sha512-Q8cpBG6RBR8YTKVqJ/L5WuHRHe2aJXaQhrGvFb7nxeamxsakH2MtumUFJX8DHV+zyYN1KHOaWonPYHC4UVjusw==", "requires": { - "@aws-cdk/aws-applicationautoscaling": "1.93.0", - "@aws-cdk/aws-cloudwatch": "1.93.0", - "@aws-cdk/aws-iam": "1.93.0", - "@aws-cdk/aws-kms": "1.93.0", - "@aws-cdk/aws-lambda": "1.93.0", - "@aws-cdk/core": "1.93.0", - "@aws-cdk/custom-resources": "1.93.0", - "constructs": "^3.2.0" + "@aws-cdk/aws-applicationautoscaling": "1.96.0", + "@aws-cdk/aws-cloudwatch": "1.96.0", + "@aws-cdk/aws-iam": "1.96.0", + "@aws-cdk/aws-kms": "1.96.0", + "@aws-cdk/aws-lambda": "1.96.0", + "@aws-cdk/core": "1.96.0", + "@aws-cdk/custom-resources": "1.96.0", + "constructs": "^3.3.69" } }, "@aws-cdk/aws-ec2": { - "version": "1.93.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/aws-ec2/-/aws-ec2-1.93.0.tgz", - "integrity": "sha512-LWNY3SrCR+t8DTXbf5Qszw8GJcMOZzub/bQNmlgxYyXoxrW7tiVniDKRXR8tn3CCgUV/S1YH7h60QKYd8Vg9XQ==", - "requires": { - "@aws-cdk/aws-cloudwatch": "1.93.0", - "@aws-cdk/aws-iam": "1.93.0", - "@aws-cdk/aws-kms": "1.93.0", - "@aws-cdk/aws-logs": "1.93.0", - "@aws-cdk/aws-s3": "1.93.0", - "@aws-cdk/aws-s3-assets": "1.93.0", - "@aws-cdk/aws-ssm": "1.93.0", - "@aws-cdk/cloud-assembly-schema": "1.93.0", - "@aws-cdk/core": "1.93.0", - "@aws-cdk/cx-api": "1.93.0", - "@aws-cdk/region-info": "1.93.0", - "constructs": "^3.2.0" + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-ec2/-/aws-ec2-1.96.0.tgz", + "integrity": "sha512-jU5gpfFm5ZKVznHgHk7TD9luthg2lcsBhQJC7K3ZkRqKf0UZiAyhy5qQs1SYYPIl5DikYAWHOjJRKtUbsXDT/w==", + "requires": { + "@aws-cdk/aws-cloudwatch": "1.96.0", + "@aws-cdk/aws-iam": "1.96.0", + "@aws-cdk/aws-kms": "1.96.0", + "@aws-cdk/aws-logs": "1.96.0", + "@aws-cdk/aws-s3": "1.96.0", + "@aws-cdk/aws-s3-assets": "1.96.0", + "@aws-cdk/aws-ssm": "1.96.0", + "@aws-cdk/cloud-assembly-schema": "1.96.0", + "@aws-cdk/core": "1.96.0", + "@aws-cdk/cx-api": "1.96.0", + "@aws-cdk/region-info": "1.96.0", + "constructs": "^3.3.69" } }, "@aws-cdk/aws-ecr": { - "version": "1.93.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/aws-ecr/-/aws-ecr-1.93.0.tgz", - "integrity": "sha512-pU9IDvO2vxE5kb3FU4ejFvy0Ei85u0j3TgYI4Fj8ZCDZj8CJ25r33t87//tWbhLJjudj4engFnJXzmxlPxx91g==", + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-ecr/-/aws-ecr-1.96.0.tgz", + "integrity": "sha512-URY1abET2RxDTzm67jU/D7kM8xqV3wMu2W6lxwvIabO8x9K9EqTFZ5ZSaC3bO+4OKZ0L+1RGAHRoUY4mOUpe/g==", "requires": { - "@aws-cdk/aws-events": "1.93.0", - "@aws-cdk/aws-iam": "1.93.0", - "@aws-cdk/core": "1.93.0", - "constructs": "^3.2.0" + "@aws-cdk/aws-events": "1.96.0", + "@aws-cdk/aws-iam": "1.96.0", + "@aws-cdk/core": "1.96.0", + "constructs": "^3.3.69" } }, "@aws-cdk/aws-ecr-assets": { - "version": "1.93.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/aws-ecr-assets/-/aws-ecr-assets-1.93.0.tgz", - "integrity": "sha512-c0GSmUduhKk4pAzzbRZqhA1GjpDVxxm9tdNBKmW1MUAOSv+xDpNeBjH636hduREUNnhuepKlWn+BGcOMcqWiHA==", - "requires": { - "@aws-cdk/assets": "1.93.0", - "@aws-cdk/aws-ecr": "1.93.0", - "@aws-cdk/aws-iam": "1.93.0", - "@aws-cdk/aws-s3": "1.93.0", - "@aws-cdk/core": "1.93.0", - "@aws-cdk/cx-api": "1.93.0", - "constructs": "^3.2.0", + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-ecr-assets/-/aws-ecr-assets-1.96.0.tgz", + "integrity": "sha512-3jbVxgeTaZ+D+rjqG71xxjWT6qggI7txhDanQjhmHEC4ND6Ac/dKwzhNwtsU/lKA825GTNinihY2RH5lF43RsA==", + "requires": { + "@aws-cdk/assets": "1.96.0", + "@aws-cdk/aws-ecr": "1.96.0", + "@aws-cdk/aws-iam": "1.96.0", + "@aws-cdk/aws-s3": "1.96.0", + "@aws-cdk/core": "1.96.0", + "@aws-cdk/cx-api": "1.96.0", + "constructs": "^3.3.69", "minimatch": "^3.0.4" }, "dependencies": { @@ -354,415 +355,415 @@ } }, "@aws-cdk/aws-ecs": { - "version": "1.93.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/aws-ecs/-/aws-ecs-1.93.0.tgz", - "integrity": "sha512-LEbP7vJu5K7i1hCBxBiRJbwHTe3AkOjYgwX2PSJ67bb4FJRC1D+lmVD9Sir9ZCT0QVSlrmvC1q4e5e6FUP+lTw==", - "requires": { - "@aws-cdk/aws-applicationautoscaling": "1.93.0", - "@aws-cdk/aws-autoscaling": "1.93.0", - "@aws-cdk/aws-autoscaling-hooktargets": "1.93.0", - "@aws-cdk/aws-certificatemanager": "1.93.0", - "@aws-cdk/aws-cloudwatch": "1.93.0", - "@aws-cdk/aws-ec2": "1.93.0", - "@aws-cdk/aws-ecr": "1.93.0", - "@aws-cdk/aws-ecr-assets": "1.93.0", - "@aws-cdk/aws-elasticloadbalancing": "1.93.0", - "@aws-cdk/aws-elasticloadbalancingv2": "1.93.0", - "@aws-cdk/aws-iam": "1.93.0", - "@aws-cdk/aws-kms": "1.93.0", - "@aws-cdk/aws-lambda": "1.93.0", - "@aws-cdk/aws-logs": "1.93.0", - "@aws-cdk/aws-route53": "1.93.0", - "@aws-cdk/aws-route53-targets": "1.93.0", - "@aws-cdk/aws-s3": "1.93.0", - "@aws-cdk/aws-s3-assets": "1.93.0", - "@aws-cdk/aws-secretsmanager": "1.93.0", - "@aws-cdk/aws-servicediscovery": "1.93.0", - "@aws-cdk/aws-sns": "1.93.0", - "@aws-cdk/aws-sqs": "1.93.0", - "@aws-cdk/aws-ssm": "1.93.0", - "@aws-cdk/core": "1.93.0", - "@aws-cdk/cx-api": "1.93.0", - "constructs": "^3.2.0" + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-ecs/-/aws-ecs-1.96.0.tgz", + "integrity": "sha512-FrXJYfT8iUUeVlTk90NE43vZ6klMNNIU/yVM/TNtiyUm+cFeQOHybHor6R47auQ/fffihia+ZxAjK77UXNrqqA==", + "requires": { + "@aws-cdk/aws-applicationautoscaling": "1.96.0", + "@aws-cdk/aws-autoscaling": "1.96.0", + "@aws-cdk/aws-autoscaling-hooktargets": "1.96.0", + "@aws-cdk/aws-certificatemanager": "1.96.0", + "@aws-cdk/aws-cloudwatch": "1.96.0", + "@aws-cdk/aws-ec2": "1.96.0", + "@aws-cdk/aws-ecr": "1.96.0", + "@aws-cdk/aws-ecr-assets": "1.96.0", + "@aws-cdk/aws-elasticloadbalancing": "1.96.0", + "@aws-cdk/aws-elasticloadbalancingv2": "1.96.0", + "@aws-cdk/aws-iam": "1.96.0", + "@aws-cdk/aws-kms": "1.96.0", + "@aws-cdk/aws-lambda": "1.96.0", + "@aws-cdk/aws-logs": "1.96.0", + "@aws-cdk/aws-route53": "1.96.0", + "@aws-cdk/aws-route53-targets": "1.96.0", + "@aws-cdk/aws-s3": "1.96.0", + "@aws-cdk/aws-s3-assets": "1.96.0", + "@aws-cdk/aws-secretsmanager": "1.96.0", + "@aws-cdk/aws-servicediscovery": "1.96.0", + "@aws-cdk/aws-sns": "1.96.0", + "@aws-cdk/aws-sqs": "1.96.0", + "@aws-cdk/aws-ssm": "1.96.0", + "@aws-cdk/core": "1.96.0", + "@aws-cdk/cx-api": "1.96.0", + "constructs": "^3.3.69" } }, "@aws-cdk/aws-efs": { - "version": "1.93.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/aws-efs/-/aws-efs-1.93.0.tgz", - "integrity": "sha512-PdifxqrNGJT4jOceredsFLh3Z0R3IDw6Exg2xMVYcGZ81vUuEiP/U8lljTXlFHrYOg/TR1vMoyrFp8CGdgBHiQ==", + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-efs/-/aws-efs-1.96.0.tgz", + "integrity": "sha512-oxAzIitrA82J0jFPAz/qvOL+d6YpxwArXJFDrNAPHZ64UgFMMv6lPTgaOMhe+MNN7S6DJMJ6EPmyRJnRg77Xgw==", "requires": { - "@aws-cdk/aws-ec2": "1.93.0", - "@aws-cdk/aws-kms": "1.93.0", - "@aws-cdk/cloud-assembly-schema": "1.93.0", - "@aws-cdk/core": "1.93.0", - "@aws-cdk/cx-api": "1.93.0", - "constructs": "^3.2.0" + "@aws-cdk/aws-ec2": "1.96.0", + "@aws-cdk/aws-kms": "1.96.0", + "@aws-cdk/cloud-assembly-schema": "1.96.0", + "@aws-cdk/core": "1.96.0", + "@aws-cdk/cx-api": "1.96.0", + "constructs": "^3.3.69" } }, "@aws-cdk/aws-eks": { - "version": "1.93.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/aws-eks/-/aws-eks-1.93.0.tgz", - "integrity": "sha512-FXXtyQPksjn8klwLDKa4D9hqe/k+JglzpNiJNE7P3OCeGHFyJlKoZwVyxG7jg4rRS2ErJjfkiNRofrtelRMOdQ==", - "requires": { - "@aws-cdk/aws-autoscaling": "1.93.0", - "@aws-cdk/aws-ec2": "1.93.0", - "@aws-cdk/aws-iam": "1.93.0", - "@aws-cdk/aws-kms": "1.93.0", - "@aws-cdk/aws-lambda": "1.93.0", - "@aws-cdk/aws-ssm": "1.93.0", - "@aws-cdk/core": "1.93.0", - "@aws-cdk/custom-resources": "1.93.0", - "@aws-cdk/lambda-layer-awscli": "1.93.0", - "@aws-cdk/lambda-layer-kubectl": "1.93.0", - "constructs": "^3.2.0", - "yaml": "1.10.0" + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-eks/-/aws-eks-1.96.0.tgz", + "integrity": "sha512-ejU7JuPj/0iIiXKOv9et/vfWorjIbmo58rE4CASjjeaxNWcfQ1WMK95TO5RWbwiFURB74V2cVmRM60he+rpyRA==", + "requires": { + "@aws-cdk/aws-autoscaling": "1.96.0", + "@aws-cdk/aws-ec2": "1.96.0", + "@aws-cdk/aws-iam": "1.96.0", + "@aws-cdk/aws-kms": "1.96.0", + "@aws-cdk/aws-lambda": "1.96.0", + "@aws-cdk/aws-ssm": "1.96.0", + "@aws-cdk/core": "1.96.0", + "@aws-cdk/custom-resources": "1.96.0", + "@aws-cdk/lambda-layer-awscli": "1.96.0", + "@aws-cdk/lambda-layer-kubectl": "1.96.0", + "constructs": "^3.3.69", + "yaml": "1.10.2" }, "dependencies": { "yaml": { - "version": "1.10.0", + "version": "1.10.2", "bundled": true } } }, "@aws-cdk/aws-elasticloadbalancing": { - "version": "1.93.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/aws-elasticloadbalancing/-/aws-elasticloadbalancing-1.93.0.tgz", - "integrity": "sha512-2nnEj7Pu5c3nKYIJDK6tFCS9bVDmhPbyShR3qbCLeImrV9G/pv+AwcQmlsGglaEw77IrTiy3scFxUwtILGRH8A==", + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-elasticloadbalancing/-/aws-elasticloadbalancing-1.96.0.tgz", + "integrity": "sha512-hesfjjB69kWiQW+4Mwye7cnnNJN758CNH6Kekbbkm92IKDa37w/da2RZJzwvOQ1NZ8GWJuSH22/PqGuwEplKOw==", "requires": { - "@aws-cdk/aws-ec2": "1.93.0", - "@aws-cdk/core": "1.93.0", - "constructs": "^3.2.0" + "@aws-cdk/aws-ec2": "1.96.0", + "@aws-cdk/core": "1.96.0", + "constructs": "^3.3.69" } }, "@aws-cdk/aws-elasticloadbalancingv2": { - "version": "1.93.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/aws-elasticloadbalancingv2/-/aws-elasticloadbalancingv2-1.93.0.tgz", - "integrity": "sha512-/vfqx+CNXfY721iu6BsF528dN3BUWkMTjAWnZ+wuB0IpEUK2Cd0uU5MpqiJUfjgG/a4x9CcbJgJfmR0on2o4ag==", - "requires": { - "@aws-cdk/aws-certificatemanager": "1.93.0", - "@aws-cdk/aws-cloudwatch": "1.93.0", - "@aws-cdk/aws-ec2": "1.93.0", - "@aws-cdk/aws-iam": "1.93.0", - "@aws-cdk/aws-lambda": "1.93.0", - "@aws-cdk/aws-s3": "1.93.0", - "@aws-cdk/cloud-assembly-schema": "1.93.0", - "@aws-cdk/core": "1.93.0", - "@aws-cdk/cx-api": "1.93.0", - "@aws-cdk/region-info": "1.93.0", - "constructs": "^3.2.0" + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-elasticloadbalancingv2/-/aws-elasticloadbalancingv2-1.96.0.tgz", + "integrity": "sha512-hb03P0x6ISZlX96AkPRHJ4dkNnWcGbR+qmXv1vhr8erBoBDEzYDxuBn8D2POiNGPD+/nWzmYNZyOr9P2ptq05A==", + "requires": { + "@aws-cdk/aws-certificatemanager": "1.96.0", + "@aws-cdk/aws-cloudwatch": "1.96.0", + "@aws-cdk/aws-ec2": "1.96.0", + "@aws-cdk/aws-iam": "1.96.0", + "@aws-cdk/aws-lambda": "1.96.0", + "@aws-cdk/aws-s3": "1.96.0", + "@aws-cdk/cloud-assembly-schema": "1.96.0", + "@aws-cdk/core": "1.96.0", + "@aws-cdk/cx-api": "1.96.0", + "@aws-cdk/region-info": "1.96.0", + "constructs": "^3.3.69" } }, "@aws-cdk/aws-events": { - "version": "1.93.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/aws-events/-/aws-events-1.93.0.tgz", - "integrity": "sha512-bMniBA36M6PzqF2HXdpsMEcpVe6GhqUG05v3tqrBkoOqOjS6KG7h884n60Ru/DTTVBX78XKFcr8mUt7gJcjVEQ==", + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-events/-/aws-events-1.96.0.tgz", + "integrity": "sha512-sbfwjyvpRiDIKnJ9T4wDyv9e1783bzHPBalZqoUCmITXEDzETM1JR6lvsEbnIdzLlutx2MALIL4fKc9lWmeMVA==", "requires": { - "@aws-cdk/aws-iam": "1.93.0", - "@aws-cdk/core": "1.93.0", - "constructs": "^3.2.0" + "@aws-cdk/aws-iam": "1.96.0", + "@aws-cdk/core": "1.96.0", + "constructs": "^3.3.69" } }, "@aws-cdk/aws-globalaccelerator": { - "version": "1.93.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/aws-globalaccelerator/-/aws-globalaccelerator-1.93.0.tgz", - "integrity": "sha512-teBGtCqiYGJ19D7WTJz61r8lvh8bXVQghJ/7VYsZB3z2itr0242VKtbT5pkUlWPcGP9LZCXzk57gKDpn7Tt0dA==", + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-globalaccelerator/-/aws-globalaccelerator-1.96.0.tgz", + "integrity": "sha512-QmyoEyhQn1DeQ+BvRwbqsRgf4HrIhfDbsKnrQptGvjtdqhBkcixSFupkpp34AfyOuNAv1pXFn8F4itTC8/chnQ==", "requires": { - "@aws-cdk/aws-ec2": "1.93.0", - "@aws-cdk/core": "1.93.0", - "@aws-cdk/custom-resources": "1.93.0", - "constructs": "^3.2.0" + "@aws-cdk/aws-ec2": "1.96.0", + "@aws-cdk/core": "1.96.0", + "@aws-cdk/custom-resources": "1.96.0", + "constructs": "^3.3.69" } }, "@aws-cdk/aws-glue": { - "version": "1.93.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/aws-glue/-/aws-glue-1.93.0.tgz", - "integrity": "sha512-IizynY+E63nIBpyHBgJCLpgDrW3J1gvkyo/5psPSuAXRr1+pMvrNsArTU3BApvIJTmZV3zAV7xeu6+5JGdwyxQ==", + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-glue/-/aws-glue-1.96.0.tgz", + "integrity": "sha512-Ne6QrAhFoayp0qtPYGwnjEY8/XOTUlzHOMy8pTm3BACFXiYwOYSb1oDyqyTQtpMixr0CuoVSc0dhYXNzuyteQg==", "requires": { - "@aws-cdk/aws-ec2": "1.93.0", - "@aws-cdk/aws-iam": "1.93.0", - "@aws-cdk/aws-kms": "1.93.0", - "@aws-cdk/aws-s3": "1.93.0", - "@aws-cdk/core": "1.93.0", - "constructs": "^3.2.0" + "@aws-cdk/aws-ec2": "1.96.0", + "@aws-cdk/aws-iam": "1.96.0", + "@aws-cdk/aws-kms": "1.96.0", + "@aws-cdk/aws-s3": "1.96.0", + "@aws-cdk/core": "1.96.0", + "constructs": "^3.3.69" } }, "@aws-cdk/aws-iam": { - "version": "1.93.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/aws-iam/-/aws-iam-1.93.0.tgz", - "integrity": "sha512-QhRh+B4w8Q70RmAQuNxsAKfDeui5qPgT8veyLyMQ1PMuB5K2qhK8l3EYP3cwhnCU8xo0bO0Z48W64LcKlFxH0A==", + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-iam/-/aws-iam-1.96.0.tgz", + "integrity": "sha512-ikpmhDFgmhZmvU89aVon0BVtJS85ez/VqlE9Xvo3UBEKjoCt5ptvIX9tqbqlBp3FwKWvOEXVgKE81kn5OWvDWg==", "requires": { - "@aws-cdk/core": "1.93.0", - "@aws-cdk/region-info": "1.93.0", - "constructs": "^3.2.0" + "@aws-cdk/core": "1.96.0", + "@aws-cdk/region-info": "1.96.0", + "constructs": "^3.3.69" } }, "@aws-cdk/aws-kms": { - "version": "1.93.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/aws-kms/-/aws-kms-1.93.0.tgz", - "integrity": "sha512-bx90WaCMakEQzavpbmF/xAbGtJRhyZxlzJ6rnCpwI+2yKJjRVnHTUKsqWb5wCOo/v47n3RIL7LK5LZPiFJnR+g==", + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-kms/-/aws-kms-1.96.0.tgz", + "integrity": "sha512-yNtEsekR188JEFbS0AD5kDXUD2kQnzJd69GV+mNUcJtmwbJQVzs8m/wnZaVcx+Q8+qLEXPro2H0evCfyExJR5w==", "requires": { - "@aws-cdk/aws-iam": "1.93.0", - "@aws-cdk/core": "1.93.0", - "@aws-cdk/cx-api": "1.93.0", - "constructs": "^3.2.0" + "@aws-cdk/aws-iam": "1.96.0", + "@aws-cdk/core": "1.96.0", + "@aws-cdk/cx-api": "1.96.0", + "constructs": "^3.3.69" } }, "@aws-cdk/aws-lambda": { - "version": "1.93.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/aws-lambda/-/aws-lambda-1.93.0.tgz", - "integrity": "sha512-OawHCa7HHp9fLa872CtSKa2wAJz3g2oQVt0A9NzB7jDd3qkRhaVnCeVpe3tHc4hwK7srjS8xC0/ldYoQ/zOIvw==", - "requires": { - "@aws-cdk/aws-applicationautoscaling": "1.93.0", - "@aws-cdk/aws-cloudwatch": "1.93.0", - "@aws-cdk/aws-codeguruprofiler": "1.93.0", - "@aws-cdk/aws-ec2": "1.93.0", - "@aws-cdk/aws-ecr": "1.93.0", - "@aws-cdk/aws-ecr-assets": "1.93.0", - "@aws-cdk/aws-efs": "1.93.0", - "@aws-cdk/aws-events": "1.93.0", - "@aws-cdk/aws-iam": "1.93.0", - "@aws-cdk/aws-kms": "1.93.0", - "@aws-cdk/aws-logs": "1.93.0", - "@aws-cdk/aws-s3": "1.93.0", - "@aws-cdk/aws-s3-assets": "1.93.0", - "@aws-cdk/aws-signer": "1.93.0", - "@aws-cdk/aws-sqs": "1.93.0", - "@aws-cdk/core": "1.93.0", - "@aws-cdk/cx-api": "1.93.0", - "constructs": "^3.2.0" + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-lambda/-/aws-lambda-1.96.0.tgz", + "integrity": "sha512-U3j6ipy9gIrQEysE3jvSfBeBalkjxp6ZPNr3mOCECtgNcWhoHaoSmwwvGCvhbnsL6ZxjwwGH2Bm5raoWyeu9YQ==", + "requires": { + "@aws-cdk/aws-applicationautoscaling": "1.96.0", + "@aws-cdk/aws-cloudwatch": "1.96.0", + "@aws-cdk/aws-codeguruprofiler": "1.96.0", + "@aws-cdk/aws-ec2": "1.96.0", + "@aws-cdk/aws-ecr": "1.96.0", + "@aws-cdk/aws-ecr-assets": "1.96.0", + "@aws-cdk/aws-efs": "1.96.0", + "@aws-cdk/aws-events": "1.96.0", + "@aws-cdk/aws-iam": "1.96.0", + "@aws-cdk/aws-kms": "1.96.0", + "@aws-cdk/aws-logs": "1.96.0", + "@aws-cdk/aws-s3": "1.96.0", + "@aws-cdk/aws-s3-assets": "1.96.0", + "@aws-cdk/aws-signer": "1.96.0", + "@aws-cdk/aws-sqs": "1.96.0", + "@aws-cdk/core": "1.96.0", + "@aws-cdk/cx-api": "1.96.0", + "constructs": "^3.3.69" } }, "@aws-cdk/aws-logs": { - "version": "1.93.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/aws-logs/-/aws-logs-1.93.0.tgz", - "integrity": "sha512-jC0PGjz8Sp8/GfnJrF1Fg5u3J3Z+tWW0a9ExO+iGl2vmE91JBmwYRwU/06HDxev/E8iUZdGL6VMdlNWQ4a7m3g==", + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-logs/-/aws-logs-1.96.0.tgz", + "integrity": "sha512-LflFQ1Tz8VhiG4XHLqMmNw+AIM8chrnTjGoDulsOKASMcX254amLQYl137LLXpUI5eyr+P520o4XUh/AyRBy5Q==", "requires": { - "@aws-cdk/aws-cloudwatch": "1.93.0", - "@aws-cdk/aws-iam": "1.93.0", - "@aws-cdk/aws-kms": "1.93.0", - "@aws-cdk/aws-s3-assets": "1.93.0", - "@aws-cdk/core": "1.93.0", - "constructs": "^3.2.0" + "@aws-cdk/aws-cloudwatch": "1.96.0", + "@aws-cdk/aws-iam": "1.96.0", + "@aws-cdk/aws-kms": "1.96.0", + "@aws-cdk/aws-s3-assets": "1.96.0", + "@aws-cdk/core": "1.96.0", + "constructs": "^3.3.69" } }, "@aws-cdk/aws-route53": { - "version": "1.93.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/aws-route53/-/aws-route53-1.93.0.tgz", - "integrity": "sha512-2+1A2OtSTs/Ie/A30tYP+TIgnlabS4TtP2Nni4FODtVIPSpljvfGRZ1PhVjueFoeXNErWS0YWqaIUSyCfSnSnA==", + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-route53/-/aws-route53-1.96.0.tgz", + "integrity": "sha512-9fLrM+cP9hKPbhH1SGKuqSs0p4uYIg4KHjkB9JMUMc/DJ0jE9r+uOA5Hx3YLUCBf70AfTdjzaiUpnwaNWQdDkQ==", "requires": { - "@aws-cdk/aws-ec2": "1.93.0", - "@aws-cdk/aws-iam": "1.93.0", - "@aws-cdk/aws-logs": "1.93.0", - "@aws-cdk/cloud-assembly-schema": "1.93.0", - "@aws-cdk/core": "1.93.0", - "@aws-cdk/custom-resources": "1.93.0", - "constructs": "^3.2.0" + "@aws-cdk/aws-ec2": "1.96.0", + "@aws-cdk/aws-iam": "1.96.0", + "@aws-cdk/aws-logs": "1.96.0", + "@aws-cdk/cloud-assembly-schema": "1.96.0", + "@aws-cdk/core": "1.96.0", + "@aws-cdk/custom-resources": "1.96.0", + "constructs": "^3.3.69" } }, "@aws-cdk/aws-route53-targets": { - "version": "1.93.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/aws-route53-targets/-/aws-route53-targets-1.93.0.tgz", - "integrity": "sha512-/AiZEs1jFcveWLSN/7ogp79kuEu1P9PI4UG8Tjhy2ZJGJhWr7yrduO5cQjRqbQ1BvaCmBGR5Oa8RLwoLtGzNBQ==", - "requires": { - "@aws-cdk/aws-apigateway": "1.93.0", - "@aws-cdk/aws-apigatewayv2": "1.93.0", - "@aws-cdk/aws-cloudfront": "1.93.0", - "@aws-cdk/aws-cognito": "1.93.0", - "@aws-cdk/aws-ec2": "1.93.0", - "@aws-cdk/aws-elasticloadbalancing": "1.93.0", - "@aws-cdk/aws-elasticloadbalancingv2": "1.93.0", - "@aws-cdk/aws-globalaccelerator": "1.93.0", - "@aws-cdk/aws-iam": "1.93.0", - "@aws-cdk/aws-route53": "1.93.0", - "@aws-cdk/aws-s3": "1.93.0", - "@aws-cdk/core": "1.93.0", - "@aws-cdk/region-info": "1.93.0", - "constructs": "^3.2.0" + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-route53-targets/-/aws-route53-targets-1.96.0.tgz", + "integrity": "sha512-ygP8mZx+tqveQ6oCWvIIu8laAbwINzRcV6YDg4D38sN2V+tjUkr+6hGsHkpVqdc1hcT4EwBum/Ul9lIkp53Ypg==", + "requires": { + "@aws-cdk/aws-apigateway": "1.96.0", + "@aws-cdk/aws-apigatewayv2": "1.96.0", + "@aws-cdk/aws-cloudfront": "1.96.0", + "@aws-cdk/aws-cognito": "1.96.0", + "@aws-cdk/aws-ec2": "1.96.0", + "@aws-cdk/aws-elasticloadbalancing": "1.96.0", + "@aws-cdk/aws-elasticloadbalancingv2": "1.96.0", + "@aws-cdk/aws-globalaccelerator": "1.96.0", + "@aws-cdk/aws-iam": "1.96.0", + "@aws-cdk/aws-route53": "1.96.0", + "@aws-cdk/aws-s3": "1.96.0", + "@aws-cdk/core": "1.96.0", + "@aws-cdk/region-info": "1.96.0", + "constructs": "^3.3.69" } }, "@aws-cdk/aws-s3": { - "version": "1.93.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/aws-s3/-/aws-s3-1.93.0.tgz", - "integrity": "sha512-sDm3Q0DODqxCeYLLwTg+YdKLPQnH0MXr5n6C29ZomK7xdKk8kA7LN18MwiLAfrvggZxaA/7VkWsatP3Q+bYfoQ==", + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-s3/-/aws-s3-1.96.0.tgz", + "integrity": "sha512-dqsjXJRaUK3u3Ij9RvR0N+xmfvQkiUHTL3Wxgg9WUqgG2Q0fO2lEcsKLvkc4B1isWMlBg3Dy9vY3fFZUke4gBg==", "requires": { - "@aws-cdk/aws-events": "1.93.0", - "@aws-cdk/aws-iam": "1.93.0", - "@aws-cdk/aws-kms": "1.93.0", - "@aws-cdk/core": "1.93.0", - "@aws-cdk/cx-api": "1.93.0", - "constructs": "^3.2.0" + "@aws-cdk/aws-events": "1.96.0", + "@aws-cdk/aws-iam": "1.96.0", + "@aws-cdk/aws-kms": "1.96.0", + "@aws-cdk/core": "1.96.0", + "@aws-cdk/cx-api": "1.96.0", + "constructs": "^3.3.69" } }, "@aws-cdk/aws-s3-assets": { - "version": "1.93.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/aws-s3-assets/-/aws-s3-assets-1.93.0.tgz", - "integrity": "sha512-iRNp01EGjgZRcqzIiPHAzweeBwI+B6W88ZgzwEBpiGI4PD17UOvabepPm53T+kRX1Ly57iDsi121ItI2p1Akwg==", + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-s3-assets/-/aws-s3-assets-1.96.0.tgz", + "integrity": "sha512-NK9jD4+2BSSw3RKIWlzxDFZkinwtyWlMf1uxzbUKw8KuxpmuMhkx8OwWwKxM50BaNOKVAbBfXh8uhQTyCsQ4Zg==", "requires": { - "@aws-cdk/assets": "1.93.0", - "@aws-cdk/aws-iam": "1.93.0", - "@aws-cdk/aws-kms": "1.93.0", - "@aws-cdk/aws-s3": "1.93.0", - "@aws-cdk/core": "1.93.0", - "@aws-cdk/cx-api": "1.93.0", - "constructs": "^3.2.0" + "@aws-cdk/assets": "1.96.0", + "@aws-cdk/aws-iam": "1.96.0", + "@aws-cdk/aws-kms": "1.96.0", + "@aws-cdk/aws-s3": "1.96.0", + "@aws-cdk/core": "1.96.0", + "@aws-cdk/cx-api": "1.96.0", + "constructs": "^3.3.69" } }, "@aws-cdk/aws-sam": { - "version": "1.93.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/aws-sam/-/aws-sam-1.93.0.tgz", - "integrity": "sha512-RQztwvPwbSTsOK3hLunwlKdPuQwIJhArXdMebfmMPqsU7eO7c0ZFjkMkHaOnWCI/qwhsgfKd3SmYTGCJp/mC0Q==", + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-sam/-/aws-sam-1.96.0.tgz", + "integrity": "sha512-Lv3JqBzvm+MdAeAw3VqH9+/Ia2GLP3ebZuTC5NKXBqyAih7Gh4kUI2Yoxc31la02aUz7aDhXwaev+3ujw9niJg==", "requires": { - "@aws-cdk/core": "1.93.0", - "constructs": "^3.2.0" + "@aws-cdk/core": "1.96.0", + "constructs": "^3.3.69" } }, "@aws-cdk/aws-secretsmanager": { - "version": "1.93.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/aws-secretsmanager/-/aws-secretsmanager-1.93.0.tgz", - "integrity": "sha512-Vyl2k66J0Ag256W8YBcdS7QM9cr6/aBZuEq5kyFT9GMwhpQ5RpDT+OUg31Pu3mLizlU70YlYueegnUQYEjxTbQ==", + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-secretsmanager/-/aws-secretsmanager-1.96.0.tgz", + "integrity": "sha512-CVk9UeBv92qwUjGiQ4IfkcINqS4jDg6p87i94GkrBt2xx+1NiGuIhGPkbgCbCiwLevZB2THJZDlUmVmQbip/cg==", "requires": { - "@aws-cdk/aws-ec2": "1.93.0", - "@aws-cdk/aws-iam": "1.93.0", - "@aws-cdk/aws-kms": "1.93.0", - "@aws-cdk/aws-lambda": "1.93.0", - "@aws-cdk/aws-sam": "1.93.0", - "@aws-cdk/core": "1.93.0", - "@aws-cdk/cx-api": "1.93.0", - "constructs": "^3.2.0" + "@aws-cdk/aws-ec2": "1.96.0", + "@aws-cdk/aws-iam": "1.96.0", + "@aws-cdk/aws-kms": "1.96.0", + "@aws-cdk/aws-lambda": "1.96.0", + "@aws-cdk/aws-sam": "1.96.0", + "@aws-cdk/core": "1.96.0", + "@aws-cdk/cx-api": "1.96.0", + "constructs": "^3.3.69" } }, "@aws-cdk/aws-servicediscovery": { - "version": "1.93.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/aws-servicediscovery/-/aws-servicediscovery-1.93.0.tgz", - "integrity": "sha512-KFunVCODLl8WaP1F+yaUBsnhck4hItgYqtvF2YYt3FaEkefLOYRaOMqlvnmtOYLv4a776GSJnDrEW/2QBwD1HA==", + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-servicediscovery/-/aws-servicediscovery-1.96.0.tgz", + "integrity": "sha512-aNhXfc1SekD4ZJDVtu45OdSkn+NnzBJlGEB8FrVL2hEK1QpX1xpsxljcc8b7nZ3ld3cVmd6ntuUvBjAYE9mTjA==", "requires": { - "@aws-cdk/aws-ec2": "1.93.0", - "@aws-cdk/aws-elasticloadbalancingv2": "1.93.0", - "@aws-cdk/aws-route53": "1.93.0", - "@aws-cdk/core": "1.93.0", - "constructs": "^3.2.0" + "@aws-cdk/aws-ec2": "1.96.0", + "@aws-cdk/aws-elasticloadbalancingv2": "1.96.0", + "@aws-cdk/aws-route53": "1.96.0", + "@aws-cdk/core": "1.96.0", + "constructs": "^3.3.69" } }, "@aws-cdk/aws-signer": { - "version": "1.93.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/aws-signer/-/aws-signer-1.93.0.tgz", - "integrity": "sha512-nLkClk9emiUVhXsYEiSqznbN23sq2IxOYemgZZP4nptKwOgRYbdQcmHzmaj7ps+cmu0yYIF26zrIGwNRJ0B2oQ==", + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-signer/-/aws-signer-1.96.0.tgz", + "integrity": "sha512-UkdcpL4e/NJ6POdgKS/575uyvPHx8fV8XQSF34m3If5Xoq3GLoZhzskWg0ayzM5ogxaisiDb4JMta64sud+SOQ==", "requires": { - "@aws-cdk/core": "1.93.0", - "constructs": "^3.2.0" + "@aws-cdk/core": "1.96.0", + "constructs": "^3.3.69" } }, "@aws-cdk/aws-sns": { - "version": "1.93.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/aws-sns/-/aws-sns-1.93.0.tgz", - "integrity": "sha512-acMvsQhItehHXNBS3K30Ws53DJUXbxLDfrEXQhrc0tubZEt4Oexgwla1QjrkXCBZaxIFlFH7Q3qUEkP5OtN7kQ==", + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-sns/-/aws-sns-1.96.0.tgz", + "integrity": "sha512-r7IfRHkVnqmEgoU10QdJQwMy8fqfmtPoRfPqFHDUWSdsSR361UW2O36mOn4m69UJv2L08EjjPn2ZdltqwQAHIg==", "requires": { - "@aws-cdk/aws-cloudwatch": "1.93.0", - "@aws-cdk/aws-events": "1.93.0", - "@aws-cdk/aws-iam": "1.93.0", - "@aws-cdk/aws-kms": "1.93.0", - "@aws-cdk/aws-sqs": "1.93.0", - "@aws-cdk/core": "1.93.0", - "constructs": "^3.2.0" + "@aws-cdk/aws-cloudwatch": "1.96.0", + "@aws-cdk/aws-events": "1.96.0", + "@aws-cdk/aws-iam": "1.96.0", + "@aws-cdk/aws-kms": "1.96.0", + "@aws-cdk/aws-sqs": "1.96.0", + "@aws-cdk/core": "1.96.0", + "constructs": "^3.3.69" } }, "@aws-cdk/aws-sns-subscriptions": { - "version": "1.93.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/aws-sns-subscriptions/-/aws-sns-subscriptions-1.93.0.tgz", - "integrity": "sha512-I9+WnBlW9aitiDXKx5WYSi0R/YBb2pIQMsTmftQGskg8mlzecmtHRIST8fEd1x8KBqPY4H7Fzx0YsVzItQnZnQ==", + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-sns-subscriptions/-/aws-sns-subscriptions-1.96.0.tgz", + "integrity": "sha512-QeYXAC9aF8l7wpe4cUUouomPZSJZnOXJY3REkaYLHMJoQoNn16VU/HzqUT9hVwuuC8YlMQ6nCr30HqCdFieK0A==", "requires": { - "@aws-cdk/aws-iam": "1.93.0", - "@aws-cdk/aws-lambda": "1.93.0", - "@aws-cdk/aws-sns": "1.93.0", - "@aws-cdk/aws-sqs": "1.93.0", - "@aws-cdk/core": "1.93.0", - "constructs": "^3.2.0" + "@aws-cdk/aws-iam": "1.96.0", + "@aws-cdk/aws-lambda": "1.96.0", + "@aws-cdk/aws-sns": "1.96.0", + "@aws-cdk/aws-sqs": "1.96.0", + "@aws-cdk/core": "1.96.0", + "constructs": "^3.3.69" } }, "@aws-cdk/aws-sqs": { - "version": "1.93.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/aws-sqs/-/aws-sqs-1.93.0.tgz", - "integrity": "sha512-f7f0gxrCjhqPTgrW3fpnFa3RoHqWKDQBnnzSSY4DhZZINE4AIEr44zBr1bP5olQ5oybdd5McBCVNmlr6813kpw==", + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-sqs/-/aws-sqs-1.96.0.tgz", + "integrity": "sha512-d5IbcqqxP3ZVB25WEYVKhpXg0LVXphply+yyMIxoF7wWh6oGxXJUGOXLErYxJtz4vzlV+2wKwv2zBaIrzhXeFw==", "requires": { - "@aws-cdk/aws-cloudwatch": "1.93.0", - "@aws-cdk/aws-iam": "1.93.0", - "@aws-cdk/aws-kms": "1.93.0", - "@aws-cdk/core": "1.93.0", - "constructs": "^3.2.0" + "@aws-cdk/aws-cloudwatch": "1.96.0", + "@aws-cdk/aws-iam": "1.96.0", + "@aws-cdk/aws-kms": "1.96.0", + "@aws-cdk/core": "1.96.0", + "constructs": "^3.3.69" } }, "@aws-cdk/aws-ssm": { - "version": "1.93.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/aws-ssm/-/aws-ssm-1.93.0.tgz", - "integrity": "sha512-ptcuPc5S5bNiI4xluHAoO4Y8fFY4vePr0bvG+l5QHTNWvvJa+TIwD/jz91xJCrt83qAHwcnjSGZj94JIK732PQ==", + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-ssm/-/aws-ssm-1.96.0.tgz", + "integrity": "sha512-Z8uFIaT3ZNpONnuSlY5JQTxk5rZ2nfCLBJXy9Ka1EcqWvuNAmnGaXcatYgzsgAfWj31OT0IUpzn49pak1aLeVQ==", "requires": { - "@aws-cdk/aws-iam": "1.93.0", - "@aws-cdk/aws-kms": "1.93.0", - "@aws-cdk/cloud-assembly-schema": "1.93.0", - "@aws-cdk/core": "1.93.0", - "constructs": "^3.2.0" + "@aws-cdk/aws-iam": "1.96.0", + "@aws-cdk/aws-kms": "1.96.0", + "@aws-cdk/cloud-assembly-schema": "1.96.0", + "@aws-cdk/core": "1.96.0", + "constructs": "^3.3.69" } }, "@aws-cdk/aws-stepfunctions": { - "version": "1.93.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/aws-stepfunctions/-/aws-stepfunctions-1.93.0.tgz", - "integrity": "sha512-ak1iCdNL3tOjrsNYqX41pcRbawRjtup0oCrzoJutn7Hro8t7SxYASbx4rm7QjQpRvGKxFgFn86rhLrTIULVEag==", + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-stepfunctions/-/aws-stepfunctions-1.96.0.tgz", + "integrity": "sha512-57F2pQrTT4jShsZR5KRhlatuiztzYtHq3OXg7fRkCKw/bgFbXPgImt9Qp0ksRPEA+JvV1mHWhYh4lYHOTqa+Og==", "requires": { - "@aws-cdk/aws-cloudwatch": "1.93.0", - "@aws-cdk/aws-events": "1.93.0", - "@aws-cdk/aws-iam": "1.93.0", - "@aws-cdk/aws-logs": "1.93.0", - "@aws-cdk/aws-s3": "1.93.0", - "@aws-cdk/core": "1.93.0", - "constructs": "^3.2.0" + "@aws-cdk/aws-cloudwatch": "1.96.0", + "@aws-cdk/aws-events": "1.96.0", + "@aws-cdk/aws-iam": "1.96.0", + "@aws-cdk/aws-logs": "1.96.0", + "@aws-cdk/aws-s3": "1.96.0", + "@aws-cdk/core": "1.96.0", + "constructs": "^3.3.69" } }, "@aws-cdk/aws-stepfunctions-tasks": { - "version": "1.93.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/aws-stepfunctions-tasks/-/aws-stepfunctions-tasks-1.93.0.tgz", - "integrity": "sha512-6go46xQQYxdhO2f7pTQHZm/tD6AMO4dBpmtycQBxZgiLJ60J7fsSUQU80I+RTMMq6EIc2H8VrixXoXyNAHtjig==", - "requires": { - "@aws-cdk/aws-apigateway": "1.93.0", - "@aws-cdk/aws-apigatewayv2": "1.93.0", - "@aws-cdk/aws-apigatewayv2-integrations": "1.93.0", - "@aws-cdk/aws-batch": "1.93.0", - "@aws-cdk/aws-cloudwatch": "1.93.0", - "@aws-cdk/aws-codebuild": "1.93.0", - "@aws-cdk/aws-databrew": "1.93.0", - "@aws-cdk/aws-dynamodb": "1.93.0", - "@aws-cdk/aws-ec2": "1.93.0", - "@aws-cdk/aws-ecr": "1.93.0", - "@aws-cdk/aws-ecr-assets": "1.93.0", - "@aws-cdk/aws-ecs": "1.93.0", - "@aws-cdk/aws-eks": "1.93.0", - "@aws-cdk/aws-glue": "1.93.0", - "@aws-cdk/aws-iam": "1.93.0", - "@aws-cdk/aws-kms": "1.93.0", - "@aws-cdk/aws-lambda": "1.93.0", - "@aws-cdk/aws-s3": "1.93.0", - "@aws-cdk/aws-sns": "1.93.0", - "@aws-cdk/aws-sqs": "1.93.0", - "@aws-cdk/aws-stepfunctions": "1.93.0", - "@aws-cdk/core": "1.93.0", - "constructs": "^3.2.0" + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/aws-stepfunctions-tasks/-/aws-stepfunctions-tasks-1.96.0.tgz", + "integrity": "sha512-SWojkFsloDem8lQF96beVNMmSscf8qrduV3nBxjTA/UD5ySvWS+EpifEqjn3FCmATJw1h7qOXc/FUALGyMe6Fg==", + "requires": { + "@aws-cdk/aws-apigateway": "1.96.0", + "@aws-cdk/aws-apigatewayv2": "1.96.0", + "@aws-cdk/aws-apigatewayv2-integrations": "1.96.0", + "@aws-cdk/aws-batch": "1.96.0", + "@aws-cdk/aws-cloudwatch": "1.96.0", + "@aws-cdk/aws-codebuild": "1.96.0", + "@aws-cdk/aws-databrew": "1.96.0", + "@aws-cdk/aws-dynamodb": "1.96.0", + "@aws-cdk/aws-ec2": "1.96.0", + "@aws-cdk/aws-ecr": "1.96.0", + "@aws-cdk/aws-ecr-assets": "1.96.0", + "@aws-cdk/aws-ecs": "1.96.0", + "@aws-cdk/aws-eks": "1.96.0", + "@aws-cdk/aws-glue": "1.96.0", + "@aws-cdk/aws-iam": "1.96.0", + "@aws-cdk/aws-kms": "1.96.0", + "@aws-cdk/aws-lambda": "1.96.0", + "@aws-cdk/aws-s3": "1.96.0", + "@aws-cdk/aws-sns": "1.96.0", + "@aws-cdk/aws-sqs": "1.96.0", + "@aws-cdk/aws-stepfunctions": "1.96.0", + "@aws-cdk/core": "1.96.0", + "constructs": "^3.3.69" } }, "@aws-cdk/cfnspec": { - "version": "1.93.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/cfnspec/-/cfnspec-1.93.0.tgz", - "integrity": "sha512-uInqSj+xWDTU7HrGZEhzQawmI3ugtdv66r4JTPOjCLUB6qDtnGhT5dsK/MHNyQkC07WjDSjkF1BxAlnCC1NRtw==", + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/cfnspec/-/cfnspec-1.96.0.tgz", + "integrity": "sha512-icJHNGbYQIFgpQarXWEdTxJ1EpXB2yzkN94bxEow+1HR8LtCBr9KIX/+82dT6UvLfz24ThBtwdNuw9zJkA3Otw==", "dev": true, "requires": { "md5": "^2.3.0" } }, "@aws-cdk/cloud-assembly-schema": { - "version": "1.93.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/cloud-assembly-schema/-/cloud-assembly-schema-1.93.0.tgz", - "integrity": "sha512-ky7MrButxqUwLS1LLSSxc5FXxr0BB9ECvJVdJJg0lfuL4+v/xB7Ba0vHdLtSd4dVPJ47MlqDdrE4uEQjlleDMQ==", + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/cloud-assembly-schema/-/cloud-assembly-schema-1.96.0.tgz", + "integrity": "sha512-2Fypls2LkWDuc2BRaKmK9eBPknG0Gis+FoCrpn/r3l7xWvqTHfDaC/gpJqIdGpHKVEbFvRewh92WGm4zdbob9A==", "requires": { "jsonschema": "^1.4.0", - "semver": "^7.3.4" + "semver": "^7.3.5" }, "dependencies": { "jsonschema": { @@ -777,7 +778,7 @@ } }, "semver": { - "version": "7.3.4", + "version": "7.3.5", "bundled": true, "requires": { "lru-cache": "^6.0.0" @@ -790,29 +791,29 @@ } }, "@aws-cdk/cloudformation-diff": { - "version": "1.93.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/cloudformation-diff/-/cloudformation-diff-1.93.0.tgz", - "integrity": "sha512-wjAlhERlIJZzXJ8UqOqUb6Iaq8ufwzvRwuUkmpX5xW5LGdqMqSgfQjbZCPf2gIVxWUrhmYvCKlH6QlR+mCUdqw==", + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/cloudformation-diff/-/cloudformation-diff-1.96.0.tgz", + "integrity": "sha512-l85qhLx0g3RLaDHvEFh3dVAgjeJWttvhQDNnFmXagfArNhhjprz8T2Degy6tBCAjmxJ1W+vr+GZjgq6ACh6VCQ==", "dev": true, "requires": { - "@aws-cdk/cfnspec": "1.93.0", + "@aws-cdk/cfnspec": "1.96.0", "colors": "^1.4.0", "diff": "^5.0.0", "fast-deep-equal": "^3.1.3", "string-width": "^4.2.2", - "table": "^6.0.7" + "table": "^6.0.9" } }, "@aws-cdk/core": { - "version": "1.93.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/core/-/core-1.93.0.tgz", - "integrity": "sha512-Z/1IZJJBfurswUKKMxoVbS0hJGIdVaTYlMCcSsYIlEVgv4D+4YfkRnWsp99IscUr1zvs+FTfM/K1ykXb8u2gaQ==", + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/core/-/core-1.96.0.tgz", + "integrity": "sha512-W8pAE2n9WgBDi0uHe0rUb95sVUe+rIe8pWZuHq60HhD5Omjb7qVxV5D95Z8TOkOrbLbCYJEUjsLV/ka0iqMOnQ==", "requires": { - "@aws-cdk/cloud-assembly-schema": "1.93.0", - "@aws-cdk/cx-api": "1.93.0", - "@aws-cdk/region-info": "1.93.0", + "@aws-cdk/cloud-assembly-schema": "1.96.0", + "@aws-cdk/cx-api": "1.96.0", + "@aws-cdk/region-info": "1.96.0", "@balena/dockerignore": "^1.0.2", - "constructs": "^3.2.0", + "constructs": "^3.3.69", "fs-extra": "^9.1.0", "ignore": "^5.1.8", "minimatch": "^3.0.4" @@ -882,27 +883,27 @@ } }, "@aws-cdk/custom-resources": { - "version": "1.93.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/custom-resources/-/custom-resources-1.93.0.tgz", - "integrity": "sha512-IzgxGK3hFFT/5BOuiNSrg8s04korg4lO7BYJdtpilroJsYLEuzv06u3XP8r8sR7XTseMbGqy5ppYfBc1glUr1w==", + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/custom-resources/-/custom-resources-1.96.0.tgz", + "integrity": "sha512-zQ6bVX+5kTeDs1Jw1viSC5s62sGiok1/ZGlvJ5lyFXtg6NCX+hKPmt+eZYJAAmFSRwMPWw+kD4+OWXFfSNJ2Lg==", "requires": { - "@aws-cdk/aws-cloudformation": "1.93.0", - "@aws-cdk/aws-ec2": "1.93.0", - "@aws-cdk/aws-iam": "1.93.0", - "@aws-cdk/aws-lambda": "1.93.0", - "@aws-cdk/aws-logs": "1.93.0", - "@aws-cdk/aws-sns": "1.93.0", - "@aws-cdk/core": "1.93.0", - "constructs": "^3.2.0" + "@aws-cdk/aws-cloudformation": "1.96.0", + "@aws-cdk/aws-ec2": "1.96.0", + "@aws-cdk/aws-iam": "1.96.0", + "@aws-cdk/aws-lambda": "1.96.0", + "@aws-cdk/aws-logs": "1.96.0", + "@aws-cdk/aws-sns": "1.96.0", + "@aws-cdk/core": "1.96.0", + "constructs": "^3.3.69" } }, "@aws-cdk/cx-api": { - "version": "1.93.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/cx-api/-/cx-api-1.93.0.tgz", - "integrity": "sha512-uZNAjYbMaSwaqIBwW9pqFwPIp38LrLyyRraHjin02QuJBubOnZEGfpcuo4Io9JPAF6h0FZbDNavlt4qkzzKS4g==", + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/cx-api/-/cx-api-1.96.0.tgz", + "integrity": "sha512-LiPWV1ALunni72XU6BywqyCxHDIMUsDQ0HYfRak37hAstAOhdqeUOlnG3goB9MTkMF7FOcU61a/izGDlVwPXQg==", "requires": { - "@aws-cdk/cloud-assembly-schema": "1.93.0", - "semver": "^7.3.4" + "@aws-cdk/cloud-assembly-schema": "1.96.0", + "semver": "^7.3.5" }, "dependencies": { "lru-cache": { @@ -913,7 +914,7 @@ } }, "semver": { - "version": "7.3.4", + "version": "7.3.5", "bundled": true, "requires": { "lru-cache": "^6.0.0" @@ -926,29 +927,43 @@ } }, "@aws-cdk/lambda-layer-awscli": { - "version": "1.93.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/lambda-layer-awscli/-/lambda-layer-awscli-1.93.0.tgz", - "integrity": "sha512-ue7GuV+9kXuHPEiw4HhJN81JZ3IVa2macTzVzt6fWvpE24BOT5z1oTJtIgWTjQE8gDRvCzwcHUl7IjHdT1QoMg==", + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/lambda-layer-awscli/-/lambda-layer-awscli-1.96.0.tgz", + "integrity": "sha512-V2OAc4Zndop2fz+58xxDQ8EBnaK59ZQ910ze/2BKUBly47m9iCc6zgDn9JfYmv/CSq13ei9/iXveUrN5g1eAew==", "requires": { - "@aws-cdk/aws-lambda": "1.93.0", - "@aws-cdk/core": "1.93.0", - "constructs": "^3.2.0" + "@aws-cdk/aws-lambda": "1.96.0", + "@aws-cdk/core": "1.96.0", + "constructs": "^3.3.69" } }, "@aws-cdk/lambda-layer-kubectl": { - "version": "1.93.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/lambda-layer-kubectl/-/lambda-layer-kubectl-1.93.0.tgz", - "integrity": "sha512-oGq+gO54Z4YuYDVn49QXWoUeGK7FSF1peA7QPpTEc3POHIUYNC/2fwRV6V6AsZQS0FSzBuOW+uX7sQ2nGjgP8A==", + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/lambda-layer-kubectl/-/lambda-layer-kubectl-1.96.0.tgz", + "integrity": "sha512-jO2LLIlhBwPaDEDmKP+k7EbQ76czD8N4QAVCnpR1x/PhK0JFDF3qfr2kvrNfIkJkN8pQJT5oP7imh8+d2j9hJw==", "requires": { - "@aws-cdk/aws-lambda": "1.93.0", - "@aws-cdk/core": "1.93.0", - "constructs": "^3.2.0" + "@aws-cdk/aws-lambda": "1.96.0", + "@aws-cdk/core": "1.96.0", + "constructs": "^3.3.69" } }, "@aws-cdk/region-info": { - "version": "1.93.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/region-info/-/region-info-1.93.0.tgz", - "integrity": "sha512-JyCIv/NlUnd+elSD74EXO6ZjhPHg5KMMdiPpZM/+8RJuHnvtKI7fL0E31/DulgeVSj/S1TvjVn0xOoKAkfQrnw==" + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/region-info/-/region-info-1.96.0.tgz", + "integrity": "sha512-esmTSLHD/OMf2YLPfB5rULgDi07xbpErD7Y3nqXxgR/M7zmd8AaT45qaDwIz17Tw+CrwL4KHud9HOT2xvdq3sQ==" + }, + "@aws-cdk/yaml-cfn": { + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/yaml-cfn/-/yaml-cfn-1.96.0.tgz", + "integrity": "sha512-+1FCGcBaAK9OPYiLwSsSLzmgNlewdwsvN/1A8zceMSaOcsPgnKzpZCR4H6Ct/GA7Xu5Lg9h3Y823icN+0+NJ7A==", + "requires": { + "yaml": "1.10.2" + }, + "dependencies": { + "yaml": { + "version": "1.10.2", + "bundled": true + } + } }, "@babel/code-frame": { "version": "7.12.13", @@ -1772,9 +1787,9 @@ "dev": true }, "ajv": { - "version": "7.2.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-7.2.1.tgz", - "integrity": "sha512-+nu0HDv7kNSOua9apAVc979qd932rrZeb3WOvoiD31A/p1mIE5/9bN2027pE2rOPYEdS3UHzsvof4hY+lM9/WQ==", + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.0.5.tgz", + "integrity": "sha512-RkiLa/AeJx7+9OvniQ/qeWu0w74A8DiPPBclQ6ji3ZQkv5KamO+QGpqmi7O4JIw3rHGUXZ6CoP9tsAkn3gyazg==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", @@ -1904,20 +1919,20 @@ "dev": true }, "aws-cdk": { - "version": "1.93.0", - "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-1.93.0.tgz", - "integrity": "sha512-/nu/42rVYK06j/w2uoxLc4zCbpdyWBuAXLXj74UyilHakoKDCyvAA6LCiAOlLP8BrpFyd/tbdB3aRue8qCEb1A==", + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-1.96.0.tgz", + "integrity": "sha512-u4T+jbMuaID1Q7eytAvzaAYxVAGiWWmMYVundowqOfkTBIATaBntFf6T0pB5PxrAcJyW3vKm1hDtETcZlDVIow==", "dev": true, "requires": { - "@aws-cdk/cloud-assembly-schema": "1.93.0", - "@aws-cdk/cloudformation-diff": "1.93.0", - "@aws-cdk/cx-api": "1.93.0", - "@aws-cdk/region-info": "1.93.0", - "@aws-cdk/yaml-cfn": "1.93.0", - "archiver": "^5.2.0", + "@aws-cdk/cloud-assembly-schema": "1.96.0", + "@aws-cdk/cloudformation-diff": "1.96.0", + "@aws-cdk/cx-api": "1.96.0", + "@aws-cdk/region-info": "1.96.0", + "@aws-cdk/yaml-cfn": "1.96.0", + "archiver": "^5.3.0", "aws-sdk": "^2.848.0", "camelcase": "^6.2.0", - "cdk-assets": "1.93.0", + "cdk-assets": "1.96.0", "colors": "^1.4.0", "decamelize": "^5.0.0", "fs-extra": "^9.1.0", @@ -1926,70 +1941,70 @@ "minimatch": ">=3.0", "promptly": "^3.2.0", "proxy-agent": "^4.0.1", - "semver": "^7.3.4", + "semver": "^7.3.5", "source-map-support": "^0.5.19", - "table": "^6.0.7", + "table": "^6.0.9", "uuid": "^8.3.2", "wrap-ansi": "^7.0.0", "yargs": "^16.2.0" }, "dependencies": { "@aws-cdk/cfnspec": { - "version": "1.93.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/cfnspec/-/cfnspec-1.93.0.tgz", - "integrity": "sha512-uInqSj+xWDTU7HrGZEhzQawmI3ugtdv66r4JTPOjCLUB6qDtnGhT5dsK/MHNyQkC07WjDSjkF1BxAlnCC1NRtw==", + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/cfnspec/-/cfnspec-1.96.0.tgz", + "integrity": "sha512-icJHNGbYQIFgpQarXWEdTxJ1EpXB2yzkN94bxEow+1HR8LtCBr9KIX/+82dT6UvLfz24ThBtwdNuw9zJkA3Otw==", "dev": true, "requires": { "md5": "^2.3.0" } }, "@aws-cdk/cloud-assembly-schema": { - "version": "1.93.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/cloud-assembly-schema/-/cloud-assembly-schema-1.93.0.tgz", - "integrity": "sha512-ky7MrButxqUwLS1LLSSxc5FXxr0BB9ECvJVdJJg0lfuL4+v/xB7Ba0vHdLtSd4dVPJ47MlqDdrE4uEQjlleDMQ==", + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/cloud-assembly-schema/-/cloud-assembly-schema-1.96.0.tgz", + "integrity": "sha512-2Fypls2LkWDuc2BRaKmK9eBPknG0Gis+FoCrpn/r3l7xWvqTHfDaC/gpJqIdGpHKVEbFvRewh92WGm4zdbob9A==", "dev": true, "requires": { "jsonschema": "^1.4.0", - "semver": "^7.3.4" + "semver": "^7.3.5" } }, "@aws-cdk/cloudformation-diff": { - "version": "1.93.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/cloudformation-diff/-/cloudformation-diff-1.93.0.tgz", - "integrity": "sha512-wjAlhERlIJZzXJ8UqOqUb6Iaq8ufwzvRwuUkmpX5xW5LGdqMqSgfQjbZCPf2gIVxWUrhmYvCKlH6QlR+mCUdqw==", + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/cloudformation-diff/-/cloudformation-diff-1.96.0.tgz", + "integrity": "sha512-l85qhLx0g3RLaDHvEFh3dVAgjeJWttvhQDNnFmXagfArNhhjprz8T2Degy6tBCAjmxJ1W+vr+GZjgq6ACh6VCQ==", "dev": true, "requires": { - "@aws-cdk/cfnspec": "1.93.0", + "@aws-cdk/cfnspec": "1.96.0", "colors": "^1.4.0", "diff": "^5.0.0", "fast-deep-equal": "^3.1.3", "string-width": "^4.2.2", - "table": "^6.0.7" + "table": "^6.0.9" } }, "@aws-cdk/cx-api": { - "version": "1.93.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/cx-api/-/cx-api-1.93.0.tgz", - "integrity": "sha512-uZNAjYbMaSwaqIBwW9pqFwPIp38LrLyyRraHjin02QuJBubOnZEGfpcuo4Io9JPAF6h0FZbDNavlt4qkzzKS4g==", + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/cx-api/-/cx-api-1.96.0.tgz", + "integrity": "sha512-LiPWV1ALunni72XU6BywqyCxHDIMUsDQ0HYfRak37hAstAOhdqeUOlnG3goB9MTkMF7FOcU61a/izGDlVwPXQg==", "dev": true, "requires": { - "@aws-cdk/cloud-assembly-schema": "1.93.0", - "semver": "^7.3.4" + "@aws-cdk/cloud-assembly-schema": "1.96.0", + "semver": "^7.3.5" } }, "@aws-cdk/region-info": { - "version": "1.93.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/region-info/-/region-info-1.93.0.tgz", - "integrity": "sha512-JyCIv/NlUnd+elSD74EXO6ZjhPHg5KMMdiPpZM/+8RJuHnvtKI7fL0E31/DulgeVSj/S1TvjVn0xOoKAkfQrnw==", + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/region-info/-/region-info-1.96.0.tgz", + "integrity": "sha512-esmTSLHD/OMf2YLPfB5rULgDi07xbpErD7Y3nqXxgR/M7zmd8AaT45qaDwIz17Tw+CrwL4KHud9HOT2xvdq3sQ==", "dev": true }, "@aws-cdk/yaml-cfn": { - "version": "1.93.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/yaml-cfn/-/yaml-cfn-1.93.0.tgz", - "integrity": "sha512-Nra7gJ1JHiYQHDG0Q07kRuo/15YnlDLfuTHkNQJjeCNqBQTVc4x/M/awPoVDZb9FcyYkmxqZHx8TOElEMT3OlQ==", + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/yaml-cfn/-/yaml-cfn-1.96.0.tgz", + "integrity": "sha512-+1FCGcBaAK9OPYiLwSsSLzmgNlewdwsvN/1A8zceMSaOcsPgnKzpZCR4H6Ct/GA7Xu5Lg9h3Y823icN+0+NJ7A==", "dev": true, "requires": { - "yaml": "1.10.0" + "yaml": "1.10.2" } }, "@tootallnate/once": { @@ -2008,9 +2023,9 @@ } }, "ajv": { - "version": "7.1.1", - "resolved": "https://registry.yarnpkg.com/ajv/-/ajv-7.1.1.tgz#1e6b37a454021fa9941713f38b952fc1c8d32a84", - "integrity": "sha512-ga/aqDYnUy/o7vbsRTFhhTsNeXiYb5JWDIcRIeZfwRNCefwjNTVYCGdGSUrEmiu3yDK3vFvNbgJxvrQW4JXrYQ==", + "version": "8.0.2", + "resolved": "https://registry.yarnpkg.com/ajv/-/ajv-8.0.2.tgz#1396e27f208ed56dd5638ab5a251edeb1c91d402", + "integrity": "sha512-V0HGxJd0PiDF0ecHYIesTOqfd1gJguwQUOYfMfAWnRsWQEXfc5ifbUFhD3Wjc+O+y7VAqL+g07prq9gHQ/JOZQ==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", @@ -2035,9 +2050,9 @@ } }, "archiver": { - "version": "5.2.0", - "resolved": "https://registry.yarnpkg.com/archiver/-/archiver-5.2.0.tgz#25aa1b3d9febf7aec5b0f296e77e69960c26db94", - "integrity": "sha512-QEAKlgQuAtUxKeZB9w5/ggKXh21bZS+dzzuQ0RPBC20qtDCbTyzqmisoeJP46MP39fg4B4IcyvR+yeyEBdblsQ==", + "version": "5.3.0", + "resolved": "https://registry.yarnpkg.com/archiver/-/archiver-5.3.0.tgz#dd3e097624481741df626267564f7dd8640a45ba", + "integrity": "sha512-iUw+oDwK0fgNpvveEsdQ0Ase6IIKztBJU2U0E9MzszMfmVVUyv1QJhS2ITW9ZCqx8dktAxVAjWWkKehuZE8OPg==", "dev": true, "requires": { "archiver-utils": "^2.1.0", @@ -2045,8 +2060,8 @@ "buffer-crc32": "^0.2.1", "readable-stream": "^3.6.0", "readdir-glob": "^1.0.0", - "tar-stream": "^2.1.4", - "zip-stream": "^4.0.4" + "tar-stream": "^2.2.0", + "zip-stream": "^4.1.0" }, "dependencies": { "readable-stream": { @@ -2123,9 +2138,9 @@ "dev": true }, "aws-sdk": { - "version": "2.856.0", - "resolved": "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.856.0.tgz#a82719952949bdfda73832b465321a49577cf784", - "integrity": "sha512-B9uRDhIxlmaz5GIDC2Q+OgVMnsPFzuu1HknWedpTre6ARG+Ukm8KQ3VA5MhsBtSm61X5u1Uwk5AlEv+feLaShA==", + "version": "2.866.0", + "resolved": "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.866.0.tgz#8150fb2e0cfecd281968edee7cad84598d8d7a09", + "integrity": "sha512-6Z581Ek2Yfm78NpeEFMNuSoyiYG7tipEaqfWNFR1AGyYheZwql4ajhzzlpWn91LBpdm7qcFldSNY9U0tKpKWNw==", "dev": true, "requires": { "buffer": "4.9.2", @@ -2261,6 +2276,16 @@ "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", "dev": true }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, "camelcase": { "version": "6.2.0", "resolved": "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.0.tgz#924af881c9d525ac9d87f40d964e5cea982a1809", @@ -2268,14 +2293,14 @@ "dev": true }, "cdk-assets": { - "version": "1.93.0", - "resolved": "https://registry.npmjs.org/cdk-assets/-/cdk-assets-1.93.0.tgz", - "integrity": "sha512-9t4s8CmUJJFn8HFDh4NS5KzhJh90Lu4gdFhDNXgYThnXjawRBkEyjgjAWKwFSrQJ9/lWXsBz5PdlvO0cewjSwg==", + "version": "1.96.0", + "resolved": "https://registry.npmjs.org/cdk-assets/-/cdk-assets-1.96.0.tgz", + "integrity": "sha512-hjOdlUPNCh9BOih0ALRzCy7w/VouZDYq5B84gMPNGvsFTmUBi4rlsa964fyZlu3sDB5rNgOXOkTjQuZ9L4BGQg==", "dev": true, "requires": { - "@aws-cdk/cloud-assembly-schema": "1.93.0", - "@aws-cdk/cx-api": "1.93.0", - "archiver": "^5.2.0", + "@aws-cdk/cloud-assembly-schema": "1.96.0", + "@aws-cdk/cx-api": "1.96.0", + "archiver": "^5.3.0", "aws-sdk": "^2.848.0", "glob": "^7.1.6", "yargs": "^16.2.0" @@ -2650,12 +2675,29 @@ } } }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, + "get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + } + }, "get-uri": { "version": "3.0.2", "resolved": "https://registry.yarnpkg.com/get-uri/-/get-uri-3.0.2.tgz#f0ef1356faabc70e1f9404fa3b66b2ba9bfc725c", @@ -2718,6 +2760,21 @@ "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", "dev": true }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-symbols": { + "version": "1.0.2", + "resolved": "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", + "dev": true + }, "heap": { "version": "0.2.6", "resolved": "https://registry.yarnpkg.com/heap/-/heap-0.2.6.tgz#087e1f10b046932fc8594dd9e6d378afc9d1e5ac", @@ -2795,6 +2852,15 @@ "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", "dev": true }, + "is-boolean-object": { + "version": "1.1.0", + "resolved": "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.0.tgz#e2aaad3a3a8fca34c28f6eee135b156ed2587ff0", + "integrity": "sha512-a7Uprx8UtD+HWdyYwnD1+ExtTgqQtD2k/1yJgtXP6wnMm8byhkoTZRl+95LLThpzNZJ5aEvi46cdH+ayMFRwmA==", + "dev": true, + "requires": { + "call-bind": "^1.0.0" + } + }, "is-buffer": { "version": "1.1.6", "resolved": "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be", @@ -2807,6 +2873,18 @@ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, + "is-number-object": { + "version": "1.0.4", + "resolved": "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.4.tgz#36ac95e741cf18b283fc1ddf5e83da798e3ec197", + "integrity": "sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw==", + "dev": true + }, + "is-string": { + "version": "1.0.5", + "resolved": "https://registry.yarnpkg.com/is-string/-/is-string-1.0.5.tgz#40493ed198ef3ff477b8c7f92f644ec82a5cd3a6", + "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==", + "dev": true + }, "isarray": { "version": "1.0.0", "resolved": "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11", @@ -2871,10 +2949,10 @@ "type-check": "~0.3.2" } }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", "dev": true }, "lodash.defaults": { @@ -2901,6 +2979,12 @@ "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", "dev": true }, + "lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193", + "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", + "dev": true + }, "lodash.union": { "version": "4.6.0", "resolved": "https://registry.yarnpkg.com/lodash.union/-/lodash.union-4.6.0.tgz#48bb5088409f16f1821666641c44dd1aaae3cd88", @@ -2949,9 +3033,9 @@ "dev": true }, "netmask": { - "version": "1.0.6", - "resolved": "https://registry.yarnpkg.com/netmask/-/netmask-1.0.6.tgz#20297e89d86f6f6400f250d9f4f6b4c1945fcd35", - "integrity": "sha1-ICl+idhvb2QA8lDZ9Pa0wZRfzTU=", + "version": "2.0.1", + "resolved": "https://registry.yarnpkg.com/netmask/-/netmask-2.0.1.tgz#5a5cbdcbb7b6de650870e15e83d3e9553a414cf4", + "integrity": "sha512-gB8eG6ubxz67c7O2gaGiyWdRUIbH61q7anjgueDqCC9kvIs/b4CTtCMaQKeJbv1/Y7FT19I4zKwYmjnjInRQsg==", "dev": true }, "normalize-path": { @@ -3001,14 +3085,14 @@ } }, "pac-resolver": { - "version": "4.1.0", - "resolved": "https://registry.yarnpkg.com/pac-resolver/-/pac-resolver-4.1.0.tgz#4b12e7d096b255a3b84e53f6831f32e9c7e5fe95", - "integrity": "sha512-d6lf2IrZJJ7ooVHr7BfwSjRO1yKSJMaiiWYSHcrxSIUtZrCa4KKGwcztdkZ/E9LFleJfjoi1yl+XLR7AX24nbQ==", + "version": "4.2.0", + "resolved": "https://registry.yarnpkg.com/pac-resolver/-/pac-resolver-4.2.0.tgz#b82bcb9992d48166920bc83c7542abb454bd9bdd", + "integrity": "sha512-rPACZdUyuxT5Io/gFKUeeZFfE5T7ve7cAkE5TUZRRfuKP0u5Hocwe48X7ZEm6mYB+bTB0Qf+xlVlA/RM/i6RCQ==", "dev": true, "requires": { "degenerator": "^2.2.0", "ip": "^1.1.5", - "netmask": "^1.0.6" + "netmask": "^2.0.1" } }, "path-is-absolute": { @@ -3154,9 +3238,9 @@ "dev": true }, "semver": { - "version": "7.3.4", - "resolved": "https://registry.yarnpkg.com/semver/-/semver-7.3.4.tgz#27aaa7d2e4ca76452f98d3add093a72c943edc97", - "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "version": "7.3.5", + "resolved": "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", "dev": true, "requires": { "lru-cache": "^6.0.0" @@ -3203,9 +3287,9 @@ "dev": true }, "socks": { - "version": "2.5.1", - "resolved": "https://registry.yarnpkg.com/socks/-/socks-2.5.1.tgz#7720640b6b5ec9a07d556419203baa3f0596df5f", - "integrity": "sha512-oZCsJJxapULAYJaEYBSzMcz8m3jqgGrHaGhkmU/o/PQfFWYWxkAaA0UMGImb6s6tEXfKi959X6VJjMMQ3P6TTQ==", + "version": "2.6.0", + "resolved": "https://registry.yarnpkg.com/socks/-/socks-2.6.0.tgz#6b984928461d39871b3666754b9000ecf39dfac2", + "integrity": "sha512-mNmr9owlinMplev0Wd7UHFlqI4ofnBnNzFuzrm63PPaHgbkqCFe4T5LzwKmtQ/f2tX0NTpcdVLyD/FHxFBstYw==", "dev": true, "requires": { "ip": "^1.1.5", @@ -3275,13 +3359,18 @@ } }, "table": { - "version": "6.0.7", - "resolved": "https://registry.yarnpkg.com/table/-/table-6.0.7.tgz#e45897ffbcc1bcf9e8a87bf420f2c9e5a7a52a34", - "integrity": "sha512-rxZevLGTUzWna/qBLObOe16kB2RTnnbhciwgPbMMlazz1yZGVEgnZK762xyVdVznhqxrfCeBMmMkgOOaPwjH7g==", + "version": "6.0.9", + "resolved": "https://registry.yarnpkg.com/table/-/table-6.0.9.tgz#790a12bf1e09b87b30e60419bafd6a1fd85536fb", + "integrity": "sha512-F3cLs9a3hL1Z7N4+EkSscsel3z55XT950AvB05bwayrNg5T1/gykXtigioTAjbltvbMSJvvhFCbnf6mX+ntnJQ==", "dev": true, "requires": { - "ajv": "^7.0.2", - "lodash": "^4.17.20", + "ajv": "^8.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "lodash.clonedeep": "^4.5.0", + "lodash.flatten": "^4.4.0", + "lodash.truncate": "^4.4.2", "slice-ansi": "^4.0.0", "string-width": "^4.2.0" } @@ -3471,9 +3560,9 @@ "dev": true }, "yaml": { - "version": "1.10.0", - "resolved": "https://registry.yarnpkg.com/yaml/-/yaml-1.10.0.tgz#3b593add944876077d4d683fee01081bd9fff31e", - "integrity": "sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg==", + "version": "1.10.2", + "resolved": "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", "dev": true }, "yargs": { @@ -3492,9 +3581,9 @@ } }, "yargs-parser": { - "version": "20.2.6", - "resolved": "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.6.tgz#69f920addf61aafc0b8b89002f5d66e28f2d8b20", - "integrity": "sha512-AP1+fQIWSM/sMiET8fyayjx/J+JmTPt2Mr0FkrgqB4todtfa53sOsrSAcIrJRD5XS20bKUwaDIuMkWKCEiQLKA==", + "version": "20.2.7", + "resolved": "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.7.tgz#61df85c113edfb5a7a4e36eb8aa60ef423cbc90a", + "integrity": "sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw==", "dev": true }, "zip-stream": { @@ -3769,6 +3858,16 @@ "unset-value": "^1.0.0" } }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -3941,9 +4040,9 @@ "dev": true }, "constructs": { - "version": "3.3.65", - "resolved": "https://registry.npmjs.org/constructs/-/constructs-3.3.65.tgz", - "integrity": "sha512-/tjHzxwK4Nz9SAm40kkC2mij3Y3LngVVj/dvk7Xpex25/PMhVRYy1pmJ0/5I5Y6bAMG1HRjcSAyf4k9YZyxJjw==" + "version": "3.3.71", + "resolved": "https://registry.npmjs.org/constructs/-/constructs-3.3.71.tgz", + "integrity": "sha512-3KFtTsA7OV27m/+pJhN4iJkKzHbPIPvyvEX5BQ/JCAWjfCHOQEVpIgxHLpT4i8L1OFta+pJrzcEVAHo6UitwqA==" }, "convert-source-map": { "version": "1.7.0", @@ -4550,6 +4649,17 @@ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, + "get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + } + }, "get-package-type": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", @@ -4664,6 +4774,12 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, + "has-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", + "dev": true + }, "has-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", @@ -4821,6 +4937,15 @@ "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", "dev": true }, + "is-boolean-object": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.0.tgz", + "integrity": "sha512-a7Uprx8UtD+HWdyYwnD1+ExtTgqQtD2k/1yJgtXP6wnMm8byhkoTZRl+95LLThpzNZJ5aEvi46cdH+ayMFRwmA==", + "dev": true, + "requires": { + "call-bind": "^1.0.0" + } + }, "is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", @@ -4915,6 +5040,12 @@ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true }, + "is-number-object": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.4.tgz", + "integrity": "sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw==", + "dev": true + }, "is-plain-object": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", @@ -4936,6 +5067,12 @@ "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", "dev": true }, + "is-string": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", + "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==", + "dev": true + }, "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", @@ -5718,12 +5855,30 @@ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, + "lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", + "dev": true + }, + "lodash.flatten": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", + "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=", + "dev": true + }, "lodash.sortby": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", "dev": true }, + "lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", + "dev": true + }, "lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -7071,13 +7226,18 @@ "dev": true }, "table": { - "version": "6.0.7", - "resolved": "https://registry.npmjs.org/table/-/table-6.0.7.tgz", - "integrity": "sha512-rxZevLGTUzWna/qBLObOe16kB2RTnnbhciwgPbMMlazz1yZGVEgnZK762xyVdVznhqxrfCeBMmMkgOOaPwjH7g==", - "dev": true, - "requires": { - "ajv": "^7.0.2", - "lodash": "^4.17.20", + "version": "6.0.9", + "resolved": "https://registry.npmjs.org/table/-/table-6.0.9.tgz", + "integrity": "sha512-F3cLs9a3hL1Z7N4+EkSscsel3z55XT950AvB05bwayrNg5T1/gykXtigioTAjbltvbMSJvvhFCbnf6mX+ntnJQ==", + "dev": true, + "requires": { + "ajv": "^8.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "lodash.clonedeep": "^4.5.0", + "lodash.flatten": "^4.4.0", + "lodash.truncate": "^4.4.2", "slice-ansi": "^4.0.0", "string-width": "^4.2.0" } diff --git a/src/aws-genomics-cdk/package.json b/src/aws-genomics-cdk/package.json index 613a8ab2f..eb5f361e2 100644 --- a/src/aws-genomics-cdk/package.json +++ b/src/aws-genomics-cdk/package.json @@ -11,21 +11,21 @@ "cdk": "cdk" }, "devDependencies": { - "@aws-cdk/assert": "1.93.0", + "@aws-cdk/assert": "1.96.0", "@types/jest": "^26.0.10", "@types/node": "10.17.27", "jest": "^26.4.2", "ts-jest": "^26.2.0", - "aws-cdk": "1.93.0", + "aws-cdk": "1.96.0", "ts-node": "^9.0.0", "typescript": "~3.9.7" }, "dependencies": { - "@aws-cdk/aws-batch": "^1.93.0", - "@aws-cdk/aws-ec2": "^1.93.0", - "@aws-cdk/aws-stepfunctions": "^1.93.0", - "@aws-cdk/aws-stepfunctions-tasks": "^1.93.0", - "@aws-cdk/core": "1.93.0", + "@aws-cdk/aws-batch": "^1.96.0", + "@aws-cdk/aws-ec2": "^1.96.0", + "@aws-cdk/aws-stepfunctions": "^1.96.0", + "@aws-cdk/aws-stepfunctions-tasks": "^1.96.0", + "@aws-cdk/core": "1.96.0", "source-map-support": "^0.5.16" } } From 182e361988b4fd962b70d44d15316a65696cd20d Mon Sep 17 00:00:00 2001 From: Itzik Paz Date: Thu, 8 Apr 2021 17:30:16 +0000 Subject: [PATCH 15/20] examples cleanup --- src/aws-genomics-cdk/app.config.json | 4 +-- .../examples/batch-bwa-job.json | 10 ++----- .../examples/batch-fastqc-job.json | 4 +-- .../examples/batch-gatk-dictionary.json | 4 +-- .../examples/batch-gatk-htc.json | 4 +-- .../examples/batch-minimap2-job.json | 28 ++++++++----------- .../batch-picard-add-missing-groups.json | 14 +++++----- .../examples/batch-samtools-index.json | 6 ++-- .../examples/batch-samtools-sort.json | 4 +-- 9 files changed, 35 insertions(+), 43 deletions(-) diff --git a/src/aws-genomics-cdk/app.config.json b/src/aws-genomics-cdk/app.config.json index 729d3ab4e..e61947793 100644 --- a/src/aws-genomics-cdk/app.config.json +++ b/src/aws-genomics-cdk/app.config.json @@ -1,5 +1,5 @@ { - "accountID": "840249831562", + "accountID": "111111111111", "region": "us-west-2", "projectName": "genomics", "tags": [{ @@ -13,7 +13,7 @@ ], "S3": { "existingBucket": true, - "bucketName": "genomics-pipelines-840249831562" + "bucketName": "YOUR-BUCKET-NAME" }, "VPC": { "createVPC": true, diff --git a/src/aws-genomics-cdk/examples/batch-bwa-job.json b/src/aws-genomics-cdk/examples/batch-bwa-job.json index d68d3ef94..943015f9f 100644 --- a/src/aws-genomics-cdk/examples/batch-bwa-job.json +++ b/src/aws-genomics-cdk/examples/batch-bwa-job.json @@ -1,12 +1,12 @@ { "jobName": "bwa", "jobQueue": "genomics-default-queue", - "jobDefinition": "bwa:3", + "jobDefinition": "bwa:1", "containerOverrides": { "command": ["bwa mem -t 8 -p -o ${SAMPLE_ID}.sam ${REFERENCE_NAME}.fasta ${SAMPLE_ID}_*1*.fastq.gz"], "environment": [{ "name": "JOB_INPUTS", - "value": "s3://genomics-pipelines-840249831562/sample/ s3://genomics-pipelines-840249831562/hg38/v0/" + "value": "s3://aws-batch-genomics-shared/secondary-analysis/example-files/fastq/NIST7035* s3://broad-references/hg38/v0/Homo_sapiens_assembly38.fasta*" }, { "name": "SAMPLE_ID", @@ -22,11 +22,7 @@ }, { "name": "JOB_OUTPUT_PREFIX", - "value": "s3://genomics-pipelines-840249831562/output" - }, - { - "name": "JOB_INPUT_S3_COPY_METHOD", - "value": "s3sync" + "value": "s3://YOUR-BUCKET-NAME/output" } ] } diff --git a/src/aws-genomics-cdk/examples/batch-fastqc-job.json b/src/aws-genomics-cdk/examples/batch-fastqc-job.json index ffd1848c2..3c98fb3d1 100644 --- a/src/aws-genomics-cdk/examples/batch-fastqc-job.json +++ b/src/aws-genomics-cdk/examples/batch-fastqc-job.json @@ -1,7 +1,7 @@ { "jobName": "fastqc", "jobQueue": "genomics-default-queue", - "jobDefinition": "fastqc:3", + "jobDefinition": "fastqc:1", "containerOverrides": { "command": ["fastqc *.gz"], "environment": [{ @@ -14,7 +14,7 @@ }, { "name": "JOB_OUTPUT_PREFIX", - "value": "s3://genomics-pipelines-840249831562/output" + "value": "s3://YOUR-BUCKET-NAME/output" } ] } diff --git a/src/aws-genomics-cdk/examples/batch-gatk-dictionary.json b/src/aws-genomics-cdk/examples/batch-gatk-dictionary.json index f0a4a98e4..c6d083096 100644 --- a/src/aws-genomics-cdk/examples/batch-gatk-dictionary.json +++ b/src/aws-genomics-cdk/examples/batch-gatk-dictionary.json @@ -6,7 +6,7 @@ "command": ["java -jar /usr/app/picard.jar CreateSequenceDictionary R=Homo_sapiens_assembly38.fasta O=Homo_sapiens_assembly38.dict"], "environment": [{ "name": "JOB_INPUTS", - "value": "s3://genomics-pipelines-840249831562/hg38/v0/Homo_sapiens_assembly38.fasta" + "value": "s3://broad-references/hg38/v0/Homo_sapiens_assembly38.fasta" }, { "name": "JOB_OUTPUTS", @@ -14,7 +14,7 @@ }, { "name": "JOB_OUTPUT_PREFIX", - "value": "s3://genomics-pipelines-840249831562/hg38/v0" + "value": "s3://YOUR-BUCKET-NAME/ref" } ] } diff --git a/src/aws-genomics-cdk/examples/batch-gatk-htc.json b/src/aws-genomics-cdk/examples/batch-gatk-htc.json index 89ca2b06b..70963057e 100644 --- a/src/aws-genomics-cdk/examples/batch-gatk-htc.json +++ b/src/aws-genomics-cdk/examples/batch-gatk-htc.json @@ -6,7 +6,7 @@ "command": ["gatk --java-options \"-Xmx4g\" HaplotypeCaller -R ${REFERENCE_NAME}.fasta -I ${SAMPLE_ID}.bam -O ${SAMPLE_ID}.vcf.gz -bamout ${SAMPLE_ID}.out.bam"], "environment": [{ "name": "JOB_INPUTS", - "value": "s3://genomics-pipelines-840249831562/output/ s3://genomics-pipelines-840249831562/hg38/v0/" + "value": "s3://YOUR-BUCKET-NAME/ref s3://YOUR-BUCKET-NAME/samples" }, { "name": "SAMPLE_ID", @@ -22,7 +22,7 @@ }, { "name": "JOB_OUTPUT_PREFIX", - "value": "s3://genomics-pipelines-840249831562/output" + "value": "s3://YOUR-BUCKET-NAME/output" }, { "name": "JOB_INPUT_S3_COPY_METHOD", diff --git a/src/aws-genomics-cdk/examples/batch-minimap2-job.json b/src/aws-genomics-cdk/examples/batch-minimap2-job.json index 7b8a711fc..91b5692bf 100644 --- a/src/aws-genomics-cdk/examples/batch-minimap2-job.json +++ b/src/aws-genomics-cdk/examples/batch-minimap2-job.json @@ -7,21 +7,17 @@ "memory": 16000, "command": ["minimap2 -ax map-pb Homo_sapiens_assembly38.fasta NIST7035_R1_trim_samp-0p1.fastq.gz > NIST7035.sam"], "environment": [{ - "name": "JOB_INPUTS", - "value": "s3://broad-references/hg38/v0/Homo_sapiens_assembly38.fasta s3://aws-batch-genomics-shared/secondary-analysis/example-files/fastq/NIST7035_R1_trim_samp-0p1.fastq.gz" - }, - { - "name": "JOB_OUTPUTS", - "value": "*.sam" - }, - { - "name": "JOB_OUTPUT_PREFIX", - "value": "s3://[YOUR BUCKET NAME]/[SOME PREFIX]" - }, - { - "name": "JOB_AWS_CLI_PATH", - "value": "/opt/aws-cli/bin" - } + "name": "JOB_INPUTS", + "value": "s3://broad-references/hg38/v0/Homo_sapiens_assembly38.fasta s3://aws-batch-genomics-shared/secondary-analysis/example-files/fastq/NIST7035_R1_trim_samp-0p1.fastq.gz" + }, + { + "name": "JOB_OUTPUTS", + "value": "*.sam" + }, + { + "name": "JOB_OUTPUT_PREFIX", + "value": "s3://YOUR-BUCKET-NAME/output" + } ] } -} \ No newline at end of file +} diff --git a/src/aws-genomics-cdk/examples/batch-picard-add-missing-groups.json b/src/aws-genomics-cdk/examples/batch-picard-add-missing-groups.json index a93b8fffc..1ad527a3e 100644 --- a/src/aws-genomics-cdk/examples/batch-picard-add-missing-groups.json +++ b/src/aws-genomics-cdk/examples/batch-picard-add-missing-groups.json @@ -4,13 +4,13 @@ "jobDefinition": "picardAddMissingGroups:1", "containerOverrides": { "command": ["java -jar /usr/picard/picard.jar AddOrReplaceReadGroups", - " -I ${SAMPLE_ID}.bam -O ${SAMPLE_ID}.rg.bam -RGID 4 --RGLB lib1 ", - " --RGPL ILLUMINA --RGPU unit1 --RGSM 20;", - " cp ${SAMPLE_ID}.rg.bam ${SAMPLE_ID}.bam;", - " rm ${SAMPLE_ID}.rg.bam"], + " -I ${SAMPLE_ID}.bam -O ${SAMPLE_ID}.rg.bam -RGID 4 --RGLB lib1 ", + " --RGPL ILLUMINA --RGPU unit1 --RGSM 20;", + " mv ${SAMPLE_ID}.rg.bam ${SAMPLE_ID}.bam;" + ], "environment": [{ "name": "JOB_INPUTS", - "value": "s3://genomics-pipelines-840249831562/output/NIST7035.bam" + "value": "s3://YOUR-BUCKET-NAME/samples/NIST7035.bam" }, { "name": "SAMPLE_ID", @@ -22,8 +22,8 @@ }, { "name": "JOB_OUTPUT_PREFIX", - "value": "s3://genomics-pipelines-840249831562/output" + "value": "s3://YOUR-BUCKET-NAME/output" } ] } -} \ No newline at end of file +} diff --git a/src/aws-genomics-cdk/examples/batch-samtools-index.json b/src/aws-genomics-cdk/examples/batch-samtools-index.json index ebd6da035..e57e601c1 100644 --- a/src/aws-genomics-cdk/examples/batch-samtools-index.json +++ b/src/aws-genomics-cdk/examples/batch-samtools-index.json @@ -1,12 +1,12 @@ { "jobName": "samtoolsIndex", "jobQueue": "genomics-default-queue", - "jobDefinition": "samtoolsIndex:2", + "jobDefinition": "samtoolsIndex:1", "containerOverrides": { "command": ["samtools index ${SAMPLE_ID}.bam"], "environment": [{ "name": "JOB_INPUTS", - "value": "s3://genomics-pipelines-840249831562/output/NIST7035.bam" + "value": "s3://YOUR-BUCKET-NAME/samples/NIST7035.bam" }, { "name": "SAMPLE_ID", @@ -18,7 +18,7 @@ }, { "name": "JOB_OUTPUT_PREFIX", - "value": "s3://genomics-pipelines-840249831562/output" + "value": "s3://YOUR-BUCKET-NAME/output" } ] } diff --git a/src/aws-genomics-cdk/examples/batch-samtools-sort.json b/src/aws-genomics-cdk/examples/batch-samtools-sort.json index 6747ea62e..7b9a9936a 100644 --- a/src/aws-genomics-cdk/examples/batch-samtools-sort.json +++ b/src/aws-genomics-cdk/examples/batch-samtools-sort.json @@ -6,7 +6,7 @@ "command": ["samtools sort -@ 4 -o ${SAMPLE_ID}.bam ${SAMPLE_ID}.sam"], "environment": [{ "name": "JOB_INPUTS", - "value": "s3://genomics-pipelines-840249831562/output/NIST7035.sam" + "value": "s3://YOUR-BUCKET-NAME/samples/NIST7035.sam" }, { "name": "SAMPLE_ID", @@ -18,7 +18,7 @@ }, { "name": "JOB_OUTPUT_PREFIX", - "value": "s3://genomics-pipelines-840249831562/output" + "value": "s3://YOUR-BUCKET-NAME/output" } ] } From 74debf62169476fdacb7b1814ddb53f051f9408a Mon Sep 17 00:00:00 2001 From: Henrique Silva Date: Wed, 14 Apr 2021 11:26:03 +0100 Subject: [PATCH 16/20] add server timeouts to cromwell.conf --- src/templates/cromwell/cromwell-resources.template.yaml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/templates/cromwell/cromwell-resources.template.yaml b/src/templates/cromwell/cromwell-resources.template.yaml index 6b2738490..5670b568b 100644 --- a/src/templates/cromwell/cromwell-resources.template.yaml +++ b/src/templates/cromwell/cromwell-resources.template.yaml @@ -411,6 +411,15 @@ Resources: port = 8000 } + akka { + http { + server { + request-timeout = 300s + idle-timeout = 300s + } + } + } + system { job-rate-control { jobs = 1 From 2b9716b17b655ed61402d0c6fa7b27baf61b9931 Mon Sep 17 00:00:00 2001 From: Henrique Silva Date: Wed, 14 Apr 2021 11:35:09 +0100 Subject: [PATCH 17/20] add aws config file --- src/templates/cromwell/cromwell-resources.template.yaml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/templates/cromwell/cromwell-resources.template.yaml b/src/templates/cromwell/cromwell-resources.template.yaml index 5670b568b..02bbb9d99 100644 --- a/src/templates/cromwell/cromwell-resources.template.yaml +++ b/src/templates/cromwell/cromwell-resources.template.yaml @@ -606,6 +606,15 @@ Resources: owner: "ec2-user" group: "ec2-user" + "/home/ec2-user/.aws/config": + content: !Sub | + [default] + region = ${AWS::Region} + + mode: "000644" + owner: "ec2-user" + group: "ec2-user" + commands: 00_get_instance_id: command: curl -s http://169.254.169.254/latest/meta-data/instance-id/ > /etc/instance-id From 47a9f9429a61ba4d1d617577b90a32cb853265dc Mon Sep 17 00:00:00 2001 From: Andrew Crabb Date: Thu, 15 Apr 2021 18:40:55 -0400 Subject: [PATCH 18/20] Add nextflow-and-core template --- .../gwfcore/gwfcore-root.template.yaml | 6 +- .../gwfcore/gwfcore-s3.template.yaml | 6 +- .../nextflow/nextflow-and-core.template.yaml | 268 ++++++++++++++++++ 3 files changed, 274 insertions(+), 6 deletions(-) create mode 100644 src/templates/nextflow/nextflow-and-core.template.yaml diff --git a/src/templates/gwfcore/gwfcore-root.template.yaml b/src/templates/gwfcore/gwfcore-root.template.yaml index 08973d76f..5aa0b003c 100644 --- a/src/templates/gwfcore/gwfcore-root.template.yaml +++ b/src/templates/gwfcore/gwfcore-root.template.yaml @@ -78,9 +78,9 @@ Parameters: Description: Does this bucket already exist? Type: String AllowedValues: - - Yes - - No - Default: No + - "Yes" + - "No" + Default: "No" DefaultCEMinvCpus: Description: The minimum number of CPUs for the default Batch Compute Environment Type: Number diff --git a/src/templates/gwfcore/gwfcore-s3.template.yaml b/src/templates/gwfcore/gwfcore-s3.template.yaml index c0ec825f5..b182ff756 100644 --- a/src/templates/gwfcore/gwfcore-s3.template.yaml +++ b/src/templates/gwfcore/gwfcore-s3.template.yaml @@ -32,9 +32,9 @@ Parameters: Type: String Description: Does this bucket already exist? If not, it will be created. AllowedValues: - - Yes - - No - Default: No + - "Yes" + - "No" + Default: "No" Conditions: BucketDoesNotExist: diff --git a/src/templates/nextflow/nextflow-and-core.template.yaml b/src/templates/nextflow/nextflow-and-core.template.yaml new file mode 100644 index 000000000..4001695e0 --- /dev/null +++ b/src/templates/nextflow/nextflow-and-core.template.yaml @@ -0,0 +1,268 @@ +--- +AWSTemplateFormatVersion: '2010-09-09' +Description: >- + (WWPS-GLS-WF-NEXTFLOW-AIO) Creates the complete set of resources needed to run + genomics workflows using Nextflow on AWS Batch + + +Mappings: + TagMap: + default: + architecture: "genomics-workflows" + solution: "nextflow" + tags: + - Key: "architecture" + Value: "genomics-workflows" + - Key: "solution" + Value: "nextflow" + + +Metadata: + AWS::CloudFormation::Interface: + ParameterGroups: + - Label: + default: "VPC" + Parameters: + - VpcId + - SubnetIds + - Label: + default: "Data Storage" + Parameters: + - S3DataBucketName + - ExistingDataBucket + - Label: + default: "AWS Batch" + Parameters: + - DefaultCEMinvCpus + - DefaultCEMaxvCpus + - PriorityCEMinvCpus + - PriorityCEMaxvCpus + - Label: + default: "Nextflow Resources" + Parameters: + - S3NextflowPrefix + - S3LogsDirPrefix + - S3WorkDirPrefix + - NextflowVersion + - NextflowVersionSpecified + + ParameterLabels: + VpcId: + default: VPC ID + SubnetIds: + default: VPC Subnet IDs + S3DataBucketName: + default: S3 Data Bucket Name + ExistingDataBucket: + default: Existing Data Bucket? + DefaultCEMinvCpus: + default: Default Min vCPU + DefaultCEMaxvCpus: + default: Default Max vCPU + PriorityCEMinvCpus: + default: High Priority Min vCPU + PriorityCEMaxvCpus: + default: High Priority Max vCPU + S3NextflowPrefix: + default: S3 Nextflow Prefix + S3LogsDirPrefix: + default: S3 Logs Dir Prefix + S3WorkDirPrefix: + default: S3 Work Dir Prefix + NextflowVersion: + default: Nextflow Version + NextflowVersionSpecified: + default: Nextflow Version Specified? + TemplateRootUrl: + default: Template Root URL + + +Parameters: + VpcId: + Type: AWS::EC2::VPC::Id + Description: 'The VPC to create security groups and deploy AWS Batch to. NOTE: Must be the same VPC as the provided subnet IDs.' + SubnetIds: + Type: List + Description: 'Subnets you want your batch compute environment to launch in. We recommend private subnets. NOTE: Must be from the VPC provided.' + + S3DataBucketName: + Description: >- + A S3 bucket name for storing analysis results + The bucket name must respect the S3 bucket naming conventions + (can contain lowercase letters, numbers, periods and hyphens). + If left blank a unique bucket name will be generated. + + Type: String + Default: "" + AllowedPattern: "((?=^.{3,63}$)(?!^(\\d+\\.)+\\d+$)(^(([a-z0-9]|[a-z0-9][a-z0-9\\-]*[a-z0-9])\\.)*([a-z0-9]|[a-z0-9][a-z0-9\\-]*[a-z0-9])$)|(^.{0}$))" + ConstraintDescription: "Must respect S3 bucket naming conventions" + + ExistingDataBucket: + Description: Does this data bucket already exist? + Type: String + AllowedValues: + - "Yes" + - "No" + Default: "No" + DefaultCEMinvCpus: + Description: The minimum number of CPUs for the default Batch Compute Environment + Type: Number + Default: 0 + DefaultCEMaxvCpus: + Description: The maximum number of CPUs for the default Batch Compute Environment + Type: Number + Default: 100 + PriorityCEMinvCpus: + Description: The minimum number of CPUs for the high-priority Batch Compute Environment + Type: Number + Default: 0 + PriorityCEMaxvCpus: + Description: The maximum number of CPUs for the high-priority Batch Compute Environment + Type: Number + Default: 100 + + S3NextflowPrefix: + Type: String + Description: >- + (Optional) Parent folder in the GWFCore bucket for metadata folders. + Default: _nextflow + S3LogsDirPrefix: + Type: String + Description: >- + (Optional) Folder in the GWFCore bucket under the {Nextflow Prefix} + for session cache and logs. + Default: logs + S3WorkDirPrefix: + Type: String + Description: >- + (Optional) Folder in the GWFCore bucket under the {Nextflow Prefix} + that contains workflow intermediate results + Default: runs + NextflowVersion: + Type: String + Default: latest + AllowedValues: + - latest + - specify ... + Description: >- + Version of Nextflow to use. Select "specify ..." to provide a specific version. + NextflowVersionSpecified: + Type: String + Description: >- + Specific version of Nextflow to use. Must match a released version number - e.g. "20.04.1". + Default: "" + + ArtifactBucketName: + Type: String + Default: aws-genomics-workflows + Description: >- + S3 Bucket where distrubution artifacts and additions scripts are stored + ArtifactBucketPrefix: + Type: String + Default: artifacts # dist: pin_version + Description: >- + Prefix in ArtifactBucketName where distribution artifacts and additions scripts are stored + + TemplateRootUrl: + Type: String + Description: >- + Root URL for where nested templates are stored + Default: https://aws-genomics-workflows.s3.amazonaws.com/templates + ConstraintDescription: >- + Must be a valid S3 URL + AllowedPattern: "https://[a-z0-9-./]{0,}s3([a-z0-9-.]+)*\\.amazonaws\\.com/[a-z0-9-./]{3,}" + + +Resources: + GenomicsWorkflowStack: + Type: AWS::CloudFormation::Stack + Properties: + TemplateURL: !Sub ${TemplateRootUrl}/gwfcore/gwfcore-root.template.yaml + Parameters: + Namespace: !Sub ${AWS::StackName}-gwfcore + VpcId: !Ref VpcId + SubnetIds: !Join [",", !Ref SubnetIds ] + S3BucketName: !Ref S3DataBucketName + ExistingBucket: !Ref ExistingDataBucket + DefaultCEMinvCpus: !Ref DefaultCEMinvCpus + DefaultCEMaxvCpus: !Ref DefaultCEMaxvCpus + PriorityCEMinvCpus: !Ref PriorityCEMinvCpus + PriorityCEMaxvCpus: !Ref PriorityCEMaxvCpus + ArtifactBucketName: !Ref ArtifactBucketName + ArtifactBucketPrefix: !Ref ArtifactBucketPrefix + TemplateRootUrl: !Ref TemplateRootUrl + Tags: !FindInMap ["TagMap", "default", "tags"] + + NextflowStack: + Type: AWS::CloudFormation::Stack + DependsOn: GenomicsWorkflowStack + Properties: + TemplateURL: !Sub ${TemplateRootUrl}/nextflow/nextflow-resources.template.yaml + Parameters: + Namespace: !Sub ${AWS::StackName}-nextflow + GWFCoreNamespace: !Sub "${AWS::StackName}-gwfcore" + S3NextflowPrefix: !Ref S3NextflowPrefix + S3LogsDirPrefix: !Ref S3LogsDirPrefix + S3WorkDirPrefix: !Ref S3WorkDirPrefix + NextflowVersion: !Ref NextflowVersion + NextflowVersionSpecified: !Ref NextflowVersionSpecified + TemplateRootUrl: !Ref TemplateRootUrl + Tags: !FindInMap ["TagMap", "default", "tags"] + + +Outputs: + NextflowContainerImage: + Value: !GetAtt NextflowStack.Outputs.NextflowContainerImage + Export: + Name: !Sub "${AWS::StackName}-NextflowContainerImage" + + NextflowJobDefinition: + Value: !GetAtt NextflowStack.Outputs.NextflowJobDefinition + Export: + Name: !Sub "${AWS::StackName}-NextflowJobDefinition" + Description: >- + Batch Job Definition that creates a nextflow head node for running workflows + + S3NextFlowBucket: + Value: !GetAtt NextflowStack.Outputs.NextflowBucket + Export: + Name: !Sub "${AWS::StackName}-NextflowBucket" + Description: >- + S3 Bucket used to store Nextflow metadata (session cache, logs, and intermediate results) + S3NextflowLogsDir: + Value: !GetAtt NextflowStack.Outputs.LogsDir + Export: + Name: !Sub "${AWS::StackName}-NextflowLogsDir" + Description: >- + S3 URI where nextflow session cache and logs are stored. + S3NextflowWorkDir: + Value: !GetAtt NextflowStack.Outputs.WorkDir + Export: + Name: !Sub "${AWS::StackName}-NextflowWorkDir" + Description: >- + S3 URI where workflow intermediate results are stored. + + VpcId: + Description: >- + The VPC created for your Nextflow stack. + Value: !Ref VpcId + S3DataBucket: + Value: !GetAtt 'GenomicsWorkflowStack.Outputs.S3BucketName' + Export: + Name: !Sub "${AWS::StackName}-DataBucket" + Description: >- + S3 bucket for storing genomics workflow input and output data + BatchDefaultQueue: + Value: !GetAtt 'GenomicsWorkflowStack.Outputs.DefaultJobQueueArn' + Export: + Name: !Sub "${AWS::StackName}-DefaultJobQueue" + Description: >- + The default AWS Batch job queue for workflow jobs, based on EC2 SPOT instances + BatchPriorityQueue: + Value: !GetAtt 'GenomicsWorkflowStack.Outputs.PriorityJobQueueArn' + Export: + Name: !Sub "${AWS::StackName}-PriorityJobQueue" + Description: >- + AWS Batch job queue for high priority workflow jobs, based on EC2 On-Demand + instances +... \ No newline at end of file From 7deb10b0c363eeffc8531c94acc9aa9945c3d340 Mon Sep 17 00:00:00 2001 From: Andrew Crabb Date: Wed, 21 Apr 2021 19:45:41 -0400 Subject: [PATCH 19/20] Require namespace for nextflow-and-core --- .../nextflow/nextflow-and-core.template.yaml | 32 ++++++++++++------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/src/templates/nextflow/nextflow-and-core.template.yaml b/src/templates/nextflow/nextflow-and-core.template.yaml index 4001695e0..0b0572a68 100644 --- a/src/templates/nextflow/nextflow-and-core.template.yaml +++ b/src/templates/nextflow/nextflow-and-core.template.yaml @@ -23,6 +23,7 @@ Metadata: - Label: default: "VPC" Parameters: + - Namespace - VpcId - SubnetIds - Label: @@ -47,6 +48,8 @@ Metadata: - NextflowVersionSpecified ParameterLabels: + Namespace: + default: Namespace VpcId: default: VPC ID SubnetIds: @@ -78,6 +81,13 @@ Metadata: Parameters: + Namespace: + Type: String + Description: Namespace (e.g. project name) to use to label resources. Between 4-20 letters, digits, and '-', starting with a letter. + AllowedPattern: "^[a-zA-Z]{1}[a-zA-Z0-9\\-]{3,19}$" + ConstraintDescription: "Between 4-20 letters, digits, '-', starting with a letter" + Default: "nextflow" + VpcId: Type: AWS::EC2::VPC::Id Description: 'The VPC to create security groups and deploy AWS Batch to. NOTE: Must be the same VPC as the provided subnet IDs.' @@ -179,7 +189,7 @@ Resources: Properties: TemplateURL: !Sub ${TemplateRootUrl}/gwfcore/gwfcore-root.template.yaml Parameters: - Namespace: !Sub ${AWS::StackName}-gwfcore + Namespace: !Sub ${Namespace}-gwfcore VpcId: !Ref VpcId SubnetIds: !Join [",", !Ref SubnetIds ] S3BucketName: !Ref S3DataBucketName @@ -199,8 +209,8 @@ Resources: Properties: TemplateURL: !Sub ${TemplateRootUrl}/nextflow/nextflow-resources.template.yaml Parameters: - Namespace: !Sub ${AWS::StackName}-nextflow - GWFCoreNamespace: !Sub "${AWS::StackName}-gwfcore" + Namespace: !Sub ${Namespace}-nextflow + GWFCoreNamespace: !Sub "${Namespace}-gwfcore" S3NextflowPrefix: !Ref S3NextflowPrefix S3LogsDirPrefix: !Ref S3LogsDirPrefix S3WorkDirPrefix: !Ref S3WorkDirPrefix @@ -214,31 +224,31 @@ Outputs: NextflowContainerImage: Value: !GetAtt NextflowStack.Outputs.NextflowContainerImage Export: - Name: !Sub "${AWS::StackName}-NextflowContainerImage" + Name: !Sub "${Namespace}-NextflowContainerImage" NextflowJobDefinition: Value: !GetAtt NextflowStack.Outputs.NextflowJobDefinition Export: - Name: !Sub "${AWS::StackName}-NextflowJobDefinition" + Name: !Sub "${Namespace}-NextflowJobDefinition" Description: >- Batch Job Definition that creates a nextflow head node for running workflows S3NextFlowBucket: Value: !GetAtt NextflowStack.Outputs.NextflowBucket Export: - Name: !Sub "${AWS::StackName}-NextflowBucket" + Name: !Sub "${Namespace}-NextflowBucket" Description: >- S3 Bucket used to store Nextflow metadata (session cache, logs, and intermediate results) S3NextflowLogsDir: Value: !GetAtt NextflowStack.Outputs.LogsDir Export: - Name: !Sub "${AWS::StackName}-NextflowLogsDir" + Name: !Sub "${Namespace}-NextflowLogsDir" Description: >- S3 URI where nextflow session cache and logs are stored. S3NextflowWorkDir: Value: !GetAtt NextflowStack.Outputs.WorkDir Export: - Name: !Sub "${AWS::StackName}-NextflowWorkDir" + Name: !Sub "${Namespace}-NextflowWorkDir" Description: >- S3 URI where workflow intermediate results are stored. @@ -249,19 +259,19 @@ Outputs: S3DataBucket: Value: !GetAtt 'GenomicsWorkflowStack.Outputs.S3BucketName' Export: - Name: !Sub "${AWS::StackName}-DataBucket" + Name: !Sub "${Namespace}-DataBucket" Description: >- S3 bucket for storing genomics workflow input and output data BatchDefaultQueue: Value: !GetAtt 'GenomicsWorkflowStack.Outputs.DefaultJobQueueArn' Export: - Name: !Sub "${AWS::StackName}-DefaultJobQueue" + Name: !Sub "${Namespace}-DefaultJobQueue" Description: >- The default AWS Batch job queue for workflow jobs, based on EC2 SPOT instances BatchPriorityQueue: Value: !GetAtt 'GenomicsWorkflowStack.Outputs.PriorityJobQueueArn' Export: - Name: !Sub "${AWS::StackName}-PriorityJobQueue" + Name: !Sub "${Namespace}-PriorityJobQueue" Description: >- AWS Batch job queue for high priority workflow jobs, based on EC2 On-Demand instances From ad992af7b37263204bbb073d5272afa8ad0bbab2 Mon Sep 17 00:00:00 2001 From: "W. Lee Pang, PhD" Date: Thu, 22 Apr 2021 17:47:27 -0700 Subject: [PATCH 20/20] quote the conditional as well --- src/templates/gwfcore/gwfcore-s3.template.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/templates/gwfcore/gwfcore-s3.template.yaml b/src/templates/gwfcore/gwfcore-s3.template.yaml index b182ff756..29680cca6 100644 --- a/src/templates/gwfcore/gwfcore-s3.template.yaml +++ b/src/templates/gwfcore/gwfcore-s3.template.yaml @@ -40,7 +40,7 @@ Conditions: BucketDoesNotExist: Fn::Equals: - !Ref ExistingBucket - - No + - "No" GenerateBucketName: Fn::Equals: - !Ref S3BucketName @@ -82,4 +82,4 @@ Outputs: - BucketDoesNotExist - !GetAtt S3Bucket.Arn - !Join [":::", ["arn:aws:s3", !Ref S3BucketName]] -... \ No newline at end of file +...