| Interface | Description |
|---|---|
| ArtifactsConfig |
(experimental) The type returned from
IArtifacts.bind(software.constructs.Construct, software.amazon.awscdk.services.codebuild.IProject). |
| ArtifactsProps |
(experimental) Properties common to all Artifacts classes.
|
| BatchBuildConfig |
(experimental) The type returned from
IProject.enableBatchBuilds(). |
| BindToCodePipelineOptions |
(experimental) The extra options passed to the
IProject.bindToCodePipeline method. |
| BitBucketSourceCredentialsProps |
(experimental) Construction properties of
BitBucketSourceCredentials. |
| BitBucketSourceProps |
(experimental) Construction properties for
BitBucketSource. |
| BucketCacheOptions | |
| BuildEnvironment | |
| BuildEnvironmentVariable | |
| BuildImageBindOptions |
(experimental) Optional arguments to
IBuildImage.binder - currently empty. |
| BuildImageConfig |
(experimental) The return type from
IBuildImage.binder - currently empty. |
| CfnProject.ArtifactsProperty | |
| CfnProject.BatchRestrictionsProperty | |
| CfnProject.BuildStatusConfigProperty | |
| CfnProject.CloudWatchLogsConfigProperty | |
| CfnProject.EnvironmentProperty | |
| CfnProject.EnvironmentVariableProperty | |
| CfnProject.GitSubmodulesConfigProperty | |
| CfnProject.LogsConfigProperty | |
| CfnProject.ProjectBuildBatchConfigProperty | |
| CfnProject.ProjectCacheProperty | |
| CfnProject.ProjectFileSystemLocationProperty | |
| CfnProject.ProjectSourceVersionProperty | |
| CfnProject.ProjectTriggersProperty | |
| CfnProject.RegistryCredentialProperty | |
| CfnProject.S3LogsConfigProperty | |
| CfnProject.SourceAuthProperty | |
| CfnProject.SourceProperty | |
| CfnProject.VpcConfigProperty | |
| CfnProject.WebhookFilterProperty | |
| CfnProjectProps |
Properties for defining a `AWS::CodeBuild::Project`.
|
| CfnReportGroup.ReportExportConfigProperty | |
| CfnReportGroup.S3ReportExportConfigProperty | |
| CfnReportGroupProps |
Properties for defining a `AWS::CodeBuild::ReportGroup`.
|
| CfnSourceCredentialProps |
Properties for defining a `AWS::CodeBuild::SourceCredential`.
|
| CloudWatchLoggingOptions |
(experimental) Information about logs built to a CloudWatch Log Group for a build project.
|
| CodeCommitSourceProps |
(experimental) Construction properties for
CodeCommitSource. |
| CommonProjectProps | |
| DockerImageOptions |
(experimental) The options when creating a CodeBuild Docker build image using
LinuxBuildImage.fromDockerRegistry or WindowsBuildImage.fromDockerRegistry. |
| EfsFileSystemLocationProps |
(experimental) Construction properties for
EfsFileSystemLocation. |
| FileSystemConfig |
(experimental) The type returned from
IFileSystemLocation.bind(software.constructs.Construct, software.amazon.awscdk.services.codebuild.IProject). |
| GitHubEnterpriseSourceCredentialsProps |
(experimental) Creation properties for
GitHubEnterpriseSourceCredentials. |
| GitHubEnterpriseSourceProps |
(experimental) Construction properties for
GitHubEnterpriseSource. |
| GitHubSourceCredentialsProps |
(experimental) Creation properties for
GitHubSourceCredentials. |
| GitHubSourceProps |
(experimental) Construction properties for
GitHubSource and GitHubEnterpriseSource. |
| IArtifacts |
(experimental) The abstract interface of a CodeBuild build output.
|
| IArtifacts.Jsii$Default |
Internal default implementation for
IArtifacts. |
| IBindableBuildImage |
(experimental) A variant of
IBuildImage that allows binding to the project. |
| IBindableBuildImage.Jsii$Default |
Internal default implementation for
IBindableBuildImage. |
| IBuildImage |
(experimental) Represents a Docker image used for the CodeBuild Project builds.
|
| IBuildImage.Jsii$Default |
Internal default implementation for
IBuildImage. |
| IFileSystemLocation |
(experimental) The interface of a CodeBuild FileSystemLocation.
|
| IFileSystemLocation.Jsii$Default |
Internal default implementation for
IFileSystemLocation. |
| IProject | |
| IProject.Jsii$Default |
Internal default implementation for
IProject. |
| IReportGroup |
(experimental) The interface representing the ReportGroup resource - either an existing one, imported using the
ReportGroup.fromReportGroupName method, or a new one, created with the ReportGroup class. |
| IReportGroup.Jsii$Default |
Internal default implementation for
IReportGroup. |
| ISource |
(experimental) The abstract interface of a CodeBuild source.
|
| ISource.Jsii$Default |
Internal default implementation for
ISource. |
| LoggingOptions |
(experimental) Information about logs for the build project.
|
| PipelineProjectProps | |
| ProjectProps | |
| ReportGroupProps |
(experimental) Construction properties for
ReportGroup. |
| S3ArtifactsProps |
(experimental) Construction properties for
S3Artifacts. |
| S3LoggingOptions |
(experimental) Information about logs built to an S3 bucket for a build project.
|
| S3SourceProps |
(experimental) Construction properties for
S3Source. |
| SourceConfig |
(experimental) The type returned from
ISource.bind(software.constructs.Construct, software.amazon.awscdk.services.codebuild.IProject). |
| SourceProps |
(experimental) Properties common to all Source classes.
|
| UntrustedCodeBoundaryPolicyProps |
(experimental) Construction properties for UntrustedCodeBoundaryPolicy.
|
| Enum | Description |
|---|---|
| BuildEnvironmentVariableType | |
| ComputeType |
(experimental) Build machine compute type.
|
| EventAction |
(experimental) The types of webhook event actions.
|
| ImagePullPrincipalType |
(experimental) The type of principal CodeBuild will use to pull your build Docker image.
|
| LocalCacheMode |
(experimental) Local cache modes to enable for the CodeBuild Project.
|
| WindowsImageType |
(experimental) Environment type for Windows Docker images.
|
---
AWS CodeBuild is a fully managed continuous integration service that compiles source code, runs tests, and produces software packages that are ready to deploy. With CodeBuild, you don’t need to provision, manage, and scale your own build servers. CodeBuild scales continuously and processes multiple builds concurrently, so your builds are not left waiting in a queue. You can get started quickly by using prepackaged build environments, or you can create custom build environments that use your own build tools. With CodeBuild, you are charged by the minute for the compute resources you use.
Install the module:
$ npm i @aws-cdk/aws-codebuild
Import it into your code:
// Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826 import software.amazon.awscdk.aws_codebuild;
The codebuild.Project construct represents a build project resource. See the
reference documentation for a comprehensive list of initialization properties,
methods and attributes.
Build projects are usually associated with a source, which is specified via
the source property which accepts a class that extends the Source
abstract base class.
The default is to have no source associated with the build project;
the buildSpec option is required in that case.
Here's a CodeBuild project with no source which simply prints Hello, CodeBuild!:
CodeCommitSourceUse an AWS CodeCommit repository as the source of this build:
// Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
import software.amazon.awscdk.aws_codebuild;
import software.amazon.awscdk.aws_codecommit;
Repository repository = new Repository(this, "MyRepo", new RepositoryProps().repositoryName("foo"));
new Project(this, "MyFirstCodeCommitProject", new ProjectProps()
.source(codebuild.Source.codeCommit(new CodeCommitSourceProps().repository(repository))));
S3SourceCreate a CodeBuild project with an S3 bucket as the source:
// Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
import software.amazon.awscdk.aws_codebuild;
import software.amazon.awscdk.aws_s3;
Bucket bucket = new Bucket(this, "MyBucket");
new Project(this, "MyProject", new ProjectProps()
.source(codebuild.Source.s3(new S3SourceProps()
.bucket(bucket)
.path("path/to/file.zip"))));
GitHubSource and GitHubEnterpriseSourceThese source types can be used to build code from a GitHub repository. Example:
// Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
Object gitHubSource = codebuild.Source.gitHub(Map.of(
"owner", "awslabs",
"repo", "aws-cdk",
"webhook", true, // optional, default: true if `webhookFilters` were provided, false otherwise
"webhookTriggersBatchBuild", true, // optional, default is false
"webhookFilters", asList(codebuild.FilterGroup
.inEventOf(codebuild.EventAction.PUSH)
.andBranchIs('master').andCommitMessageIs("the commit message"))));
To provide GitHub credentials, please either go to AWS CodeBuild Console to connect
or call ImportSourceCredentials to persist your personal access token.
Example:
aws codebuild import-source-credentials --server-type GITHUB --auth-type PERSONAL_ACCESS_TOKEN --token <token_value>
BitBucketSourceThis source type can be used to build code from a BitBucket repository.
// Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
Object bbSource = codebuild.Source.bitBucket(Map.of(
"owner", "owner",
"repo", "repo"));
For all Git sources, you can fetch submodules while cloing git repo.
// Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
Object gitHubSource = codebuild.Source.gitHub(Map.of(
"owner", "awslabs",
"repo", "aws-cdk",
"fetchSubmodules", true));
CodeBuild Projects can produce Artifacts and upload them to S3. For example:
// Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
Object project = codebuild.Project(stack, "MyProject", Map.of(
"buildSpec", codebuild.BuildSpec.fromObject(Map.of(
"version", "0.2")),
"artifacts", codebuild.Artifacts.s3(Map.of(
"bucket", bucket,
"includeBuildId", false,
"packageZip", true,
"path", "another/path",
"identifier", "AddArtifact1"))));
If you'd prefer your buildspec to be rendered as YAML in the template,
use the fromObjectToYaml() method instead of fromObject().
Because we've not set the name property, this example will set the
overrideArtifactName parameter, and produce an artifact named as defined in
the Buildspec file, uploaded to an S3 bucket (bucket). The path will be
another/path and the artifact will be a zipfile.
To add a CodeBuild Project as an Action to CodePipeline,
use the PipelineProject class instead of Project.
It's a simple class that doesn't allow you to specify sources,
secondarySources, artifacts or secondaryArtifacts,
as these are handled by setting input and output CodePipeline Artifact instances on the Action,
instead of setting them on the Project.
// Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826 Object project = PipelineProject.Builder.create(this, "Project").build();
For more details, see the readme of the @aws-cdk/@aws-codepipeline-actions package.
You can save time when your project builds by using a cache. A cache can store reusable pieces of your build environment and use them across multiple builds. Your build project can use one of two types of caching: Amazon S3 or local. In general, S3 caching is a good option for small and intermediate build artifacts that are more expensive to build than to download. Local caching is a good option for large intermediate build artifacts because the cache is immediately available on the build host.
With S3 caching, the cache is stored in an S3 bucket which is available from multiple hosts.
// Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
Project.Builder.create(this, "Project")
.source(codebuild.Source.bitBucket(Map.of(
"owner", "awslabs",
"repo", "aws-cdk")))
.cache(codebuild.Cache.bucket(new Bucket(this, "Bucket")))
.build();
With local caching, the cache is stored on the codebuild instance itself. This is simple, cheap and fast, but CodeBuild cannot guarantee a reuse of instance and hence cannot guarantee cache hits. For example, when a build starts and caches files locally, if two subsequent builds start at the same time afterwards only one of those builds would get the cache. Three different cache modes are supported, which can be turned on individually.
LocalCacheMode.SOURCE caches Git metadata for primary and secondary sources.LocalCacheMode.DOCKER_LAYER caches existing Docker layers.LocalCacheMode.CUSTOM caches directories you specify in the buildspec file.
// Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
Project.Builder.create(this, "Project")
.source(codebuild.Source.gitHubEnterprise(Map.of(
"httpsCloneUrl", "https://my-github-enterprise.com/owner/repo")))
// Enable Docker AND custom caching
.cache(codebuild.Cache.local(LocalCacheMode.getDOCKER_LAYER(), LocalCacheMode.getCUSTOM()))
.build();
By default, projects use a small instance with an Ubuntu 18.04 image. You
can use the environment property to customize the build environment:
buildImage defines the Docker image used. See Images below for
details on how to define build images.computeType defines the instance type used for the build.privileged can be set to true to allow privileged access.environmentVariables can be set at this level (and also at the project
level).
The CodeBuild library supports both Linux and Windows images via the
LinuxBuildImage and WindowsBuildImage classes, respectively.
You can specify one of the predefined Windows/Linux images by using one
of the constants such as WindowsBuildImage.WIN_SERVER_CORE_2019_BASE,
WindowsBuildImage.WINDOWS_BASE_2_0 or LinuxBuildImage.STANDARD_2_0.
Alternatively, you can specify a custom image using one of the static methods on
LinuxBuildImage:
LinuxBuildImage.fromDockerRegistry(image[, { secretsManagerCredentials }]) to reference an image in any public or private Docker registry.LinuxBuildImage.fromEcrRepository(repo[, tag]) to reference an image available in an
ECR repository.LinuxBuildImage.fromAsset(parent, id, props) to use an image created from a
local asset.LinuxBuildImage.fromCodeBuildImageId(id) to reference a pre-defined, CodeBuild-provided Docker image.
or one of the corresponding methods on WindowsBuildImage:
WindowsBuildImage.fromDockerRegistry(image[, { secretsManagerCredentials }, imageType])WindowsBuildImage.fromEcrRepository(repo[, tag, imageType])WindowsBuildImage.fromAsset(parent, id, props, [, imageType])
Note that the WindowsBuildImage version of the static methods accepts an optional parameter of type WindowsImageType,
which can be either WindowsImageType.STANDARD, the default, or WindowsImageType.SERVER_2019:
// Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
Project.Builder.create(this, "Project")
.environment(Map.of(
"buildImage", codebuild.WindowsBuildImage.fromEcrRepository(ecrRepository, "v1.0", codebuild.WindowsImageType.getSERVER_2019())))...
.build();
The following example shows how to define an image from a Docker asset:
The following example shows how to define an image from an ECR repository:
The following example shows how to define an image from a private docker registry:
The class LinuxGpuBuildImage contains constants for working with
AWS Deep Learning Container images:
// Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
Project.Builder.create(this, "Project")
.environment(Map.of(
"buildImage", codebuild.LinuxGpuBuildImage.getDLC_TENSORFLOW_2_1_0_INFERENCE()))...
.build();
One complication is that the repositories for the DLC images are in
different accounts in different AWS regions.
In most cases, the CDK will handle providing the correct account for you;
in rare cases (for example, deploying to new regions)
where our information might be out of date,
you can always specify the account
(along with the repository name and tag)
explicitly using the awsDeepLearningContainersImage method:
// Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
Project.Builder.create(this, "Project")
.environment(Map.of(
"buildImage", codebuild.LinuxGpuBuildImage.awsDeepLearningContainersImage("tensorflow-inference", "2.1.0-gpu-py36-cu101-ubuntu18.04", "123456789012")))...
.build();
CodeBuild lets you specify an S3 Bucket, CloudWatch Log Group or both to receive logs from your projects.
By default, logs will go to cloudwatch.
// Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
Project.Builder.create(this, "Project")
.logging(Map.of(
"cloudWatch", Map.of(
"logGroup", new LogGroup(this, "MyLogGroup"))))...
.build();
// Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
Project.Builder.create(this, "Project")
.logging(Map.of(
"s3", Map.of(
"bucket", new Bucket(this, "LogBucket"))))...
.build();
CodeBuild allows you to store credentials used when communicating with various sources, like GitHub:
// Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
GitHubSourceCredentials.Builder.create(this, "CodeBuildGitHubCreds")
.accessToken(cdk.SecretValue.secretsManager("my-token"))
.build();
and BitBucket:
// Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
BitBucketSourceCredentials.Builder.create(this, "CodeBuildBitBucketCreds")
.username(cdk.SecretValue.secretsManager("my-bitbucket-creds", Map.of("jsonField", "username")))
.password(cdk.SecretValue.secretsManager("my-bitbucket-creds", Map.of("jsonField", "password")))
.build();
Note: the credentials are global to a given account in a given region -
they are not defined per CodeBuild project.
CodeBuild only allows storing a single credential of a given type
(GitHub, GitHub Enterprise or BitBucket)
in a given account in a given region -
any attempt to save more than one will result in an error.
You can use the list-source-credentials AWS CLI operation
to inspect what credentials are stored in your account.
You can specify a test report in your buildspec:
// Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
Object project = Project.Builder.create(this, "Project")
.buildSpec(codebuild.BuildSpec.fromObject(Map.of(
// ...
"reports", Map.of(
"myReport", Map.of(
"files", "** /*",
"base-directory", "build/test-results")))))
.build();
This will create a new test report group,
with the name <ProjectName>-myReport.
The project's role in the CDK will always be granted permissions to create and use report groups with names starting with the project's name; if you'd rather not have those permissions added, you can opt out of it when creating the project:
// Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
Object project = Project.Builder.create(this, "Project")
// ...
.grantReportGroupPermissions(false)
.build();
Alternatively, you can specify an ARN of an existing resource group, instead of a simple name, in your buildspec:
// Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
// create a new ReportGroup
Object reportGroup = new ReportGroup(this, "ReportGroup");
Object project = Project.Builder.create(this, "Project")
.buildSpec(codebuild.BuildSpec.fromObject(Map.of(
// ...
"reports", Map.of(
reportGroup.getReportGroupArn(), Map.of(
"files", "** /*",
"base-directory", "build/test-results")))))
.build();
If you do that, you need to grant the project's role permissions to write reports to that report group:
// Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826 reportGroup.grantWrite(project);
For more information on the test reports feature, see the AWS CodeBuild documentation.
CodeBuild projects can be used either as a source for events or be triggered by events via an event rule.
The @aws-cdk/aws-events-targets.CodeBuildProject allows using an AWS CodeBuild
project as a AWS CloudWatch event rule target:
// Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
// start build when a commit is pushed
import software.amazon.awscdk.aws_events_targets;
codeCommitRepository.onCommit("OnCommit", Map.of(
"target", new CodeBuildProject(project)));
To define Amazon CloudWatch event rules for build projects, use one of the onXxx
methods:
// Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
Object rule = project.onStateChange("BuildStateChange", Map.of(
"target", new LambdaFunction(fn)));
CodeBuild Projects can get their sources from multiple places, and produce multiple outputs. For example:
// Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
Object project = Project.Builder.create(this, "MyProject")
.secondarySources(asList(codebuild.Source.codeCommit(Map.of(
"identifier", "source2",
"repository", repo))))
.secondaryArtifacts(asList(codebuild.Artifacts.s3(Map.of(
"identifier", "artifact2",
"bucket", bucket,
"path", "some/path",
"name", "file.zip"))))
.build();
Note that the identifier property is required for both secondary sources and
artifacts.
The contents of the secondary source is available to the build under the
directory specified by the CODEBUILD_SRC_DIR_<identifier> environment variable
(so, CODEBUILD_SRC_DIR_source2 in the above case).
The secondary artifacts have their own section in the buildspec, under the
regular artifacts one. Each secondary artifact has its own section, beginning
with their identifier.
So, a buildspec for the above Project could look something like this:
// Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
Object project = Project.Builder.create(this, "MyProject")
// secondary sources and artifacts as above...
.buildSpec(codebuild.BuildSpec.fromObject(Map.of(
"version", "0.2",
"phases", Map.of(
"build", Map.of(
"commands", asList("cd $CODEBUILD_SRC_DIR_source2", "touch output2.txt"))),
"artifacts", Map.of(
"secondary-artifacts", Map.of(
"artifact2", Map.of(
"base-directory", "$CODEBUILD_SRC_DIR_source2",
"files", asList("output2.txt")))))))
.build();
Typically, resources in an VPC are not accessible by AWS CodeBuild. To enable access, you must provide additional VPC-specific configuration information as part of your CodeBuild project configuration. This includes the VPC ID, the VPC subnet IDs, and the VPC security group IDs. VPC-enabled builds are then able to access resources inside your VPC.
For further Information see https://docs.aws.amazon.com/codebuild/latest/userguide/vpc-support.html
Use Cases VPC connectivity from AWS CodeBuild builds makes it possible to:
Your builds can access any resource that's hosted in your VPC.
Enable Amazon VPC Access in your CodeBuild Projects
Pass the VPC when defining your Project, then make sure to
give the CodeBuild's security group the right permissions
to access the resources that it needs by using the
connections object.
For example:
// Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
Object vpc = new Vpc(this, "MyVPC");
Object project = Project.Builder.create(this, "MyProject")
.vpc(vpc)
.buildSpec(codebuild.BuildSpec.fromObject(Map.of()))
.build();
project.connections.allowTo(loadBalancer, ec2.Port.tcp(443));
Add support for CodeBuild to build on AWS EFS file system mounts using
the new ProjectFileSystemLocation.
The fileSystemLocations property which accepts a list ProjectFileSystemLocation
as represented by the interface IFileSystemLocations.
The only supported file system type is EFS.
For example:
// Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
Project.Builder.create(stack, "MyProject")
.buildSpec(codebuild.BuildSpec.fromObject(Map.of(
"version", "0.2")))
.fileSystemLocations(asList(codebuild.FileSystemLocation.efs(Map.of(
"identifier", "myidentifier2",
"location", "myclodation.mydnsroot.com:/loc",
"mountPoint", "/media",
"mountOptions", "opts"))))
.build();
Here's a CodeBuild project with a simple example that creates a project mounted on AWS EFS:
To enable batch builds you should call enableBatchBuilds() on the project instance.
It returns an object containing the batch service role that was created,
or undefined if batch builds could not be enabled, for example if the project was imported.
// Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
import software.amazon.awscdk.aws_codebuild;
Project project = new Project(this, "MyProject", new ProjectProps()...);
if (project.enableBatchBuilds()) {
System.out.println("Batch builds were enabled");
}
There are two types of timeouts that can be set when creating your Project.
The timeout property can be used to set an upper limit on how long your Project is able to run without being marked as completed.
The default is 60 minutes.
An example of overriding the default follows.
// Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
import software.amazon.awscdk.aws_codebuild;
new Project(stack, "MyProject", new ProjectProps()
.timeout(Duration.minutes(90)));
The queuedTimeout property can be used to set an upper limit on how your Project remains queued to run.
There is no default value for this property.
As an example, to allow your Project to queue for up to thirty (30) minutes before the build fails,
use the following code.
// Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
import software.amazon.awscdk.aws_codebuild;
new Project(stack, "MyProject", new ProjectProps()
.queuedTimeout(Duration.minutes(30)));
By default if a new build is triggered it will be run even if there is a previous build already in progress. It is possible to limit the maximum concurrent builds to value between 1 and the account specific maximum limit. By default there is no explicit limit.
// Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
import software.amazon.awscdk.aws_codebuild;
new Project(stack, "MyProject", new ProjectProps()
.concurrentBuildLimit(1));
Copyright © 2021. All rights reserved.