[
  {
    "path": "LAB00-Terraform-Install-AWS-Configuration.md",
    "content": "## LAB: Terraform Install, AWS Configuration with Terraform\n\nThis scenario shows:\n- how to configure your Terraform with AWS\n\n## Steps\n\n- Install Terraform:\n  -  https://developer.hashicorp.com/terraform/tutorials/aws-get-started/install-cli \n\n- For Windows:\n \n``` \nchoco install terraform\n``` \n\n- Then, add Terraform app into the Environment Variables.\n\n  ![image](https://user-images.githubusercontent.com/10358317/226994354-ef99ce99-c9b7-480e-ad09-36b88c6fe841.png)\n\n- Download AWS CLI:\n  - https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html\n\n- For Windows: \n\n```\nmsiexec.exe /i https://awscli.amazonaws.com/AWSCLIV2.msi\n```\n\n  ![image](https://user-images.githubusercontent.com/10358317/226995232-d88e1533-2aa0-4d6c-b201-5ab1c58d389f.png)\n\n\n- Create AWS Root Account:\n  - https://repost.aws/knowledge-center/create-and-activate-aws-account \n\n- Create IAM Admin User:\n\n  ![image](https://user-images.githubusercontent.com/10358317/226996766-678ae1af-1161-4d8a-9b49-4bb3915b1ba5.png)\n\n\n- Create AWS Access Keys. \n\n- Access keys consist of two parts: \n  - an access key ID (for example, AKIAIOSFODNN7EXAMPLE),\n  - a secret access key (for example, wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY). \n\n- You must use both the access key ID and secret access key together to authenticate your requests.\n\n  ![image](https://user-images.githubusercontent.com/10358317/226998180-cd80ae08-a05c-479b-baad-fae9c2f094df.png)\n\n- Configure AWS with AWS CLI (use command: aws configure):\n\n``` \n$ aws configure\nAWS Access Key ID [None]: AKIAIOSFODNN7EXAMPLE\nAWS Secret Access Key [None]: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY\nDefault region name [None]: eu-central-1\nDefault output format [None]: json\n``` \n\n- After command, AWS creates:\n  - Credentials file => C:\\Users\\username\\.aws\\credentials\n  - Config file      => C:\\Users\\username\\.aws\\config\n\n``` \n# credentials file\n[default]\naws_access_key_id = AKIAIOSFODNN7EXAMPLE\naws_secret_access_key = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY\n``` \n\n``` \n# config file\n[default]\nregion = eu-central-1\noutput = json\n``` \n\n- Now, it is your ready to run Terraform!\n\n## Reference\n- Terraform Install: https://developer.hashicorp.com/terraform/tutorials/aws-get-started/install-cli\n- AWS CLI Install: https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html\n- AWS Access Keys: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html\n- AWS CLI Configuration: https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html\n"
  },
  {
    "path": "LAB01-Terraform-Docker-Without-Cloud.md",
    "content": "## LAB-01: Terraform Docker => Pull Docker Image, Create Docker Container on Local Machine\n\nThis scenario shows:\n- how to use Terraform to manage Docker commands (image pull, container create, etc.)\n- without using any cloud, with Terraform Docker module, learning Terraform and making more practice could be easier.\n\n\n**Code:** https://github.com/omerbsezer/Fast-Terraform/blob/main/labs/terraform-docker-without-cloud/main.tf\n\n### Prerequisite\n\n- You should have a look following lab: \n  - [LAB-00: Terraform Install, AWS Configuration with Terraform](https://github.com/omerbsezer/Fast-Terraform/blob/main/LAB00-Terraform-Install-AWS-Configuration.md)\n- Install Docker on your system.\n  - Ubuntu: https://docs.docker.com/engine/install/ubuntu/\n  - Windows: https://docs.docker.com/desktop/install/windows-install/\n  - Mac: https://docs.docker.com/desktop/install/mac-install/ \n\n## Steps\n\n- Create main.tf and copy the code:\n \n``` \n# main.tf\nterraform {\n  required_providers {\n    docker = {\n      source  = \"kreuzwerker/docker\"\n      version = \"~> 3.0.2\"\n    }\n  }\n}\n\nprovider \"docker\" {\n  host    =  \"npipe:////.//pipe//docker_engine\"\n}\n\nresource \"docker_image\" \"windows\" {\n  name         = \"mcr.microsoft.com/powershell:lts-windowsservercore-1809\"\n  keep_locally = true\n}\n\n# docker container run -p 80:8000 --name=tutorial -it mcr.microsoft.com/powershell:lts-windowsservercore-1809 powershell\nresource \"docker_container\" \"windows\" {\n  image = docker_image.windows.image_id\n  name  = \"tutorial\"\n  \n  stdin_open = true             # docker run -i\n  tty        = true             # docker run -t\n  \n  entrypoint = [\"powershell\"]\n  \n  ports {\n    internal = 80\n    external = 8000\n  }\n}\n``` \n**Code:** https://github.com/omerbsezer/Fast-Terraform/blob/main/labs/terraform-docker-without-cloud/main.tf\n\n![image](https://user-images.githubusercontent.com/10358317/227287393-09ff08a1-9db2-4fc5-98e8-1a20c2bdf9be.png)\n\n- Run init command:\n\n``` \nterraform init\n``` \n\n![image](https://user-images.githubusercontent.com/10358317/227279233-74013a80-0a71-4c0c-84b7-e9cec6c9d30f.png)\n\n- Validate file:\n\n``` \nterraform validate\n``` \n\n- Run plan command:\n\n``` \nterraform plan\n``` \n\n![image](https://user-images.githubusercontent.com/10358317/227279536-a2f72789-36f6-4ee1-82df-a0bed834d34d.png)\n\n- Run apply command to create resources. Then, Terraform asks to confirm, write \"yes\":\n\n``` \nterraform apply\n```   \n\n![image](https://user-images.githubusercontent.com/10358317/227281131-7463a9dc-1f61-4f48-a906-410725c0af19.png)\n\n- With \"docker container ls -a\", running container is viewed: \n\n![image](https://user-images.githubusercontent.com/10358317/227280862-04483fb7-530d-4a75-ad22-21e8a5cbf49b.png)\n\n- Run following command to connect container powershell:\n \n```\ndocker container exec -it tutorial powershell\n```\n\n- Now, we are in the container, to prove it, we are looking at the users in the container (ContainerAdministrator, ContainerUser)\n\n![image](https://user-images.githubusercontent.com/10358317/227282456-4452cbe2-611c-491a-a9f7-f6bbaab28d69.png)\n\n- Before Terraform runs the container, it pulls the image:\n\n![image](https://user-images.githubusercontent.com/10358317/227283686-a6b2ee63-8c01-4610-84c0-3f5d5f622166.png)\n\n- When \"keep_locally = true\" in image part, image will be kept after terraform destroy.\n\n```\nterraform destroy\n```\n\n![image](https://user-images.githubusercontent.com/10358317/227284301-9fa06ebe-faa5-47aa-ac52-234bf6ca2c4e.png)\n\n- After destroy command, container is deleted, but image is still kept\n\n![image](https://user-images.githubusercontent.com/10358317/227285010-450e8cc2-b3e8-4dd5-9272-65d9f69bfd18.png)\n\n- With Terraform, we can manage docker images, containers..\n- More information: https://registry.terraform.io/providers/kreuzwerker/docker/latest/docs/resources/container\n\n\n"
  },
  {
    "path": "LAB02-Resources-Basic-EC2.md",
    "content": "## LAB-02: Resources => Provision Basic EC2 (Ubuntu 22.04)\n\nThis scenario shows:\n- how to create EC2 with Ubuntu 22.04\n\n**Code:** https://github.com/omerbsezer/Fast-Terraform/blob/main/labs/basic-resource-ec2-ubuntu/main.tf\n\n### Prerequisite\n\n- You should have a look following lab: \n  - [LAB-00: Terraform Install, AWS Configuration with Terraform](https://github.com/omerbsezer/Fast-Terraform/blob/main/LAB00-Terraform-Install-AWS-Configuration.md)\n\n## Steps\n\n- Create main.tf and copy the code\n \n``` \n# main.tf\nterraform {\n  required_providers {\n    aws = {\n      source  = \"hashicorp/aws\"\n      version = \"~> 4.16\"\n    }\n  }\n\n  required_version = \">= 1.2.0\"\n}\n\nprovider \"aws\" {\n\tregion = \"eu-central-1\"\n}\n\nresource \"aws_instance\" \"instance\" {\n\tami           = \"ami-0d1ddd83282187d18\" # Ubuntu 22.04 eu-central-1 Frankfurt\n\tinstance_type = \"t2.nano\"\n\n\ttags = {\n\t\tName = \"Basic Instance\"\n\t}\n}\n``` \n\n**Code:** https://github.com/omerbsezer/Fast-Terraform/blob/main/labs/basic-resource-ec2-ubuntu/main.tf\n\n![image](https://user-images.githubusercontent.com/10358317/227008999-64295471-d0b3-48c8-a717-e6323c2091e9.png)\n\n\n- Run init command:\n\n``` \nterraform init\n``` \n\n![image](https://user-images.githubusercontent.com/10358317/227001872-ef246cee-f8a9-4c66-845b-17d7ad32e8a5.png)\n  \n- Init command downloads required executable files from Terraform (.terraform):\n\n![image](https://user-images.githubusercontent.com/10358317/227002641-a15545c6-9e40-4f23-80a6-ed07b2c4b7b1.png)\n \n- Validate file:\n\n``` \nterraform validate\n``` \n\n![image](https://user-images.githubusercontent.com/10358317/227002220-a6d67605-e870-40e1-9e0f-252f68c4ba0a.png)\n\n\n- Run plan command:\n\n``` \nterraform plan\n``` \n\n![image](https://user-images.githubusercontent.com/10358317/227003057-6805d76e-75a1-440d-a288-876668fe7e27.png)\n  \n![image](https://user-images.githubusercontent.com/10358317/227003299-c02f0d18-7588-4b41-8a80-5e180ffea50e.png)\n  \n- Run apply command to create resources. Then, Terraform asks to confirm, write \"yes\":\n\n``` \nterraform apply\n```   \n\n![image](https://user-images.githubusercontent.com/10358317/227007465-7f4a1315-6f16-45af-a21b-25d896a718a7.png)\n\n- It creates the resources that are defined in the main.tf:\n\n![image](https://user-images.githubusercontent.com/10358317/227007779-6fea1041-31c3-4f0f-b8c2-a1673bfef150.png)\n\n- After apply command, terraform creates state files:\n\n![image](https://user-images.githubusercontent.com/10358317/227009288-9009ff78-0b24-451a-a5a5-5533b9d3c0fb.png)\n\n- On AWS, go to EC2 services:\n\n![image](https://user-images.githubusercontent.com/10358317/227004589-8329e520-ce4a-4cf7-8eb9-a4e71f4d46a1.png)\n\n- On EC2 Dashboard: \n\n![image](https://user-images.githubusercontent.com/10358317/227004417-47f719c4-8ccc-413d-a17d-11409e82173d.png)\n\n- Security Group Configuration is configured as default, inbound ports are defined as \"all\" (this is not good for security, but for now, it's ok!), egress ports are defined as \"all\"\n\n![image](https://user-images.githubusercontent.com/10358317/227005971-42e763de-734c-47d7-9916-a490ee97f8ee.png)\n\n- Network Configuration is configured as default, but availability zone is defined as \"eu-central-1\"\n\n![image](https://user-images.githubusercontent.com/10358317/227005316-351ea88a-dbd5-4820-a2f8-0d768437c3c7.png)\n \n- Storage Configuration is configured as default, 8GB EBS (Elastic Block Storage) is attached:\n\n![image](https://user-images.githubusercontent.com/10358317/227005692-9721e61a-9217-45ca-a466-d4717fb91ff1.png)\n\n- Delete all resources. Then, Terraform asks to confirm, write \"yes\"::\n\n``` \nterraform destroy\n``` \n\n![image](https://user-images.githubusercontent.com/10358317/229283240-60381539-93e7-4795-bdb0-7ab179cf7ed4.png)\n\n![image](https://user-images.githubusercontent.com/10358317/229283607-5eb607f0-ad8a-46fb-9f1b-e6aee38fb4db.png)\n  \n- On AWS EC2 Instances, EC2 was terminated, it'll be disappeared in max. 1 hour. Once an EC2 is terminated, that EC2 is deleted permanently:\n\n![image](https://user-images.githubusercontent.com/10358317/227008611-4c7e0d5f-2765-47f5-9b6f-af78d4d7314f.png)\n \n- Destroy command is important to terminate the resources. \n- If you forget the destroy command, your EC2 runs until termination and you MUST pay the usage price of EC2.\n\n![image](https://user-images.githubusercontent.com/10358317/227049834-12b0223c-fd10-46ca-9602-391e6267434f.png)\n\n- It is really IMPORTANT to check whether unnecessary paid services are closed or not.\n\n![image](https://user-images.githubusercontent.com/10358317/227050101-0dd27ac2-b10f-4812-90f9-18cfbc51de80.png)\n\n\n"
  },
  {
    "path": "LAB03-Variables-Locals-Output-EC2.md",
    "content": "## LAB-03: Variables, Locals, Output => Provision EC2s\n\nThis scenario shows:\n- how to create EC2 using Variables, Locals and Output\n\n**Code:** https://github.com/omerbsezer/Fast-Terraform/tree/main/labs/variables-locals-output\n\n### Prerequisite\n\n- You should have a look following lab: \n  - [LAB-00: Terraform Install, AWS Configuration with Terraform](https://github.com/omerbsezer/Fast-Terraform/blob/main/LAB00-Terraform-Install-AWS-Configuration.md)\n\n## Steps\n\n- Create main.tf and copy the code:\n \n``` \n# main.tf\nterraform {\n  required_providers {\n    aws = {\n      source  = \"hashicorp/aws\"\n      version = \"~> 4.16\"\n    }\n  }\n\n  required_version = \">= 1.2.0\"\n}\n\nprovider \"aws\" {\n   region     = var.location\n}\n\nlocals {\n  staging_env = \"staging\"\n}\n\nresource \"aws_vpc\" \"my_vpc\" {\n  cidr_block = \"10.0.0.0/16\"\n  enable_dns_hostnames = true\n  tags = {\n    Name = \"${local.staging_env}-vpc-tag\"\n  }\n}\n\nresource \"aws_subnet\" \"my_subnet\" {\n  vpc_id = aws_vpc.my_vpc.id\n  cidr_block = \"10.0.0.0/16\"\n  availability_zone = var.availability_zone\n  tags = {\n    Name = \"${local.staging_env}-subnet-tag\"\n  }\n}\n\nresource \"aws_internet_gateway\" \"my_vpc_igw\" {\n  vpc_id = aws_vpc.my_vpc.id\n  tags = {\n    Name = \"${local.staging_env}-Internet Gateway\"\n  }\n}\n\nresource \"aws_route_table\" \"my_vpc_eu_central_1c_public\" {\n    vpc_id = aws_vpc.my_vpc.id\n    route {\n        cidr_block = \"0.0.0.0/0\"\n        gateway_id = aws_internet_gateway.my_vpc_igw.id\n    }\n    tags = {\n        Name = \"${local.staging_env}- Public Subnet Route Table\"\n    }\n}\nresource \"aws_route_table_association\" \"my_vpc_eu_central_1c_public\" {\n    subnet_id      = aws_subnet.my_subnet.id\n    route_table_id = aws_route_table.my_vpc_eu_central_1c_public.id\n}\n\nresource \"aws_instance\" \"ec2_example\" {\n   \n   ami                         = var.ami\n   instance_type               = var.instance_type\n   subnet_id                   = aws_subnet.my_subnet.id\n   associate_public_ip_address = true\n   \n   tags = {\n           Name = var.tag\n   }\n}\n\n# output single values\noutput \"public_ip\" {\n  value = aws_instance.ec2_example.public_ip\n}\n\n# output single values\noutput \"public_dns\" {\n  value = aws_instance.ec2_example.public_dns\n} \n\n# output multiple values\noutput \"instance_ips\" {\n  value = {\n    public_ip  = aws_instance.ec2_example.public_ip\n    private_ip = aws_instance.ec2_example.private_ip\n  }\n} \n```\n- Code: https://github.com/omerbsezer/Fast-Terraform/blob/main/labs/variables-locals-output/main.tf\n\n![image](https://user-images.githubusercontent.com/10358317/227576390-d65cfefb-ac47-4873-9b49-31774174d2d8.png)\n\n\n- Create variables.tf:\n```\nvariable \"instance_type\" {\n    type = string\n    description = \"EC2 Instance Type\"\n}\n\nvariable \"tag\" {\n    type = string\n    description = \"The tag for the EC2 instance\"\n}\n\nvariable \"location\" {\n    type = string\n    description = \"The project region\"\n    default = \"eu-central-1\"\n}\n\nvariable  \"availability_zone\" {\n    type = string\n    description = \"The project availability zone\"\n    default = \"eu-central-1c\"\n} \n\nvariable \"ami\" {\n    type = string\n    description = \"The project region\"\n}\n```\n- Code: https://github.com/omerbsezer/Fast-Terraform/blob/main/labs/variables-locals-output/variables.tf\n\n![image](https://user-images.githubusercontent.com/10358317/227576884-4a6d5052-cc5b-47e7-bd9f-30d5955bdcda.png)\n\n- Create terraform-dev.tfvars:\n\n```\n instance_type     =   \"t2.nano\"\n tag               =   \"EC2 Instance for DEV\"\n location          =   \"eu-central-1\"\n availability_zone =   \"eu-central-1c\"\n ami               =   \"ami-0e067cc8a2b58de59\" # Ubuntu 20.04 eu-central-1 Frankfurt\n```\n- Code: https://github.com/omerbsezer/Fast-Terraform/blob/main/labs/variables-locals-output/terraform-dev.tfvars\n\n![image](https://user-images.githubusercontent.com/10358317/227577004-107a8d30-b137-43bc-835c-74c3ce27117d.png)\n\n- Create terraform-prod.tfvars:\n\n```\ninstance_type     =   \"t2.micro\"\ntag               =   \"EC2 Instance for PROD\"\nlocation          =   \"eu-central-1\"\navailability_zone =   \"eu-central-1c\"\nami               =   \"ami-0d1ddd83282187d18\" # Ubuntu 22.04 eu-central-1 Frankfurt\n```\n- Code: https://github.com/omerbsezer/Fast-Terraform/blob/main/labs/variables-locals-output/terraform-prod.tfvars\n\n![image](https://user-images.githubusercontent.com/10358317/227577134-e6023e7a-7d54-4406-ae8a-97bf3e89e9fe.png)\n\n- Run init command:\n\n``` \nterraform init\n``` \n\n![image](https://user-images.githubusercontent.com/10358317/227567351-655c2233-a5fd-4fea-a9d2-ddcc32f12d0e.png)\n\n\n- Validate file:\n\n``` \nterraform validate\n``` \n\n![image](https://user-images.githubusercontent.com/10358317/227567482-7592f836-5d61-46c7-8467-0bc36fc6e852.png)\n\n- Run plan command with DEV tfvar file:\n\n``` \nterraform plan --var-file=\"terraform-dev.tfvars\"\n``` \n\n![image](https://user-images.githubusercontent.com/10358317/227568275-14f0bdd6-20b7-450e-8f19-383a7c36a629.png)\n\n- Run apply command to create resources, with DEV tfvar file. Then, Terraform asks to confirm, write \"yes\":\n\n``` \nterraform apply --var-file=\"terraform-dev.tfvars\"\n```  \n\n![image](https://user-images.githubusercontent.com/10358317/227573622-460f5970-612f-49ed-bcaa-cfeecd9d2c49.png)\n\n![image](https://user-images.githubusercontent.com/10358317/229284493-13646f69-5e8d-4dc0-aa21-6d6149b8acb3.png)\n\n- On AWS EC2 Instances:\n\n![image](https://user-images.githubusercontent.com/10358317/227574209-11e89611-4776-4fc0-a76d-80c56a263c71.png)\n\n- On VPC Section:\n\n![image](https://user-images.githubusercontent.com/10358317/227575010-944ff35b-47a8-4caf-81e8-46e4d7089d4a.png)\n\n- Destroy DEV Environment:\n\n```\nterraform destroy --var-file=\"terraform-dev.tfvars\"\n```\n\n![image](https://user-images.githubusercontent.com/10358317/229284618-506f4daf-70c7-4411-b399-9e865b4d81a1.png)\n\n![image](https://user-images.githubusercontent.com/10358317/229284719-ac78448b-7386-4fe8-afcc-8f3a6ae6edc8.png)\n\n- Update locals for PROD in main.tf:\n\n```\n....\nlocals {\n  staging_env = \"product\"\n}\n.....\n```\n\n![image](https://user-images.githubusercontent.com/10358317/227581270-6cdba303-e29c-486e-abf3-831529a459b9.png)\n\n- Run plan command with PROD tfvar file:\n\n``` \nterraform plan --var-file=\"terraform-prod.tfvars\"\n``` \n\n![image](https://user-images.githubusercontent.com/10358317/227578564-ff43db34-2e35-45d8-bffa-f5d132dd0967.png)\n\n- Run apply command to create resources, with PROD tfvar file. Then, Terraform asks to confirm, write \"yes\":\n\n``` \nterraform apply --var-file=\"terraform-prod.tfvars\"\n```  \n\n![image](https://user-images.githubusercontent.com/10358317/227578878-4d3e2d4c-2878-4b90-8751-246598748da6.png)\n\n\n- On AWS EC2 Instances:\n\n![image](https://user-images.githubusercontent.com/10358317/227579473-a9f883ee-28d7-4a39-9647-6371712303ea.png)\n\n- On VPC Section:\n\n![image](https://user-images.githubusercontent.com/10358317/227579952-e70efbd3-0d42-46b7-b661-ad7b4f9ba41e.png)\n\n\n- Destroy PROD Environment:\n\n```\nterraform destroy --var-file=\"terraform-prod.tfvars\"\n```\n\n![image](https://user-images.githubusercontent.com/10358317/229284826-cbaf8761-e960-44ed-867d-3b1f6e3ae88f.png)\n\n![image](https://user-images.githubusercontent.com/10358317/229284932-f216c36c-235d-4511-8510-11f613321422.png)\n\n- On EC2 Instances, all instances are terminated:\n\n![image](https://user-images.githubusercontent.com/10358317/227580749-328c2a30-ae0c-441f-9fa0-e40f20fa818b.png)\n\n"
  },
  {
    "path": "LAB04-Meta-Arguments-IAM-User-Group-Policy.md",
    "content": "## LAB-04: Meta Arguments (Count, For_Each, Map) => Provision IAM Users, User Groups, Policies, Attachment Policy-User Group\n\nThis scenario shows:\n- how to create IAM User, User Groups, Permission Policies, Attachment Policy-User Group\n- how to use Count, For_Each, Map\n\n**Code:** https://github.com/omerbsezer/Fast-Terraform/tree/main/labs/iamuser-metaargs-count-for-foreach-map\n\n### Prerequisite\n\n- You should have a look following lab: \n  - [LAB-00: Terraform Install, AWS Configuration with Terraform](https://github.com/omerbsezer/Fast-Terraform/blob/main/LAB00-Terraform-Install-AWS-Configuration.md)\n\n## Steps\n\n### Count\n\n- Create main.tf under count directory and copy the code:\n \n``` \n# main.tf\nterraform {\n  required_providers {\n    aws = {\n      source  = \"hashicorp/aws\"\n      version = \"~> 4.16\"\n    }\n  }\n\n  required_version = \">= 1.2.0\"\n}\n#####################################################\n# User - User Group Attachment (With Index Count)\nresource \"aws_iam_user_group_membership\" \"user1_group_attach\" {\n  user = aws_iam_user.user_example[0].name\n\n  groups = [\n    aws_iam_group.admin_group.name,\n    aws_iam_group.dev_group.name,\n  ]\n}\n\nresource \"aws_iam_user_group_membership\" \"user2_group_attach\" {\n  user = aws_iam_user.user_example[1].id\n\n  groups = [\n    aws_iam_group.admin_group.name\n  ]\n}\n\nresource \"aws_iam_user_group_membership\" \"user3_group_attach\" {\n  user = aws_iam_user.user_example[2].name\n\n  groups = [\n    aws_iam_group.dev_group.name\n  ]\n}\n#####################################################\n# User Group Definition\nresource \"aws_iam_group\" \"admin_group\" {\n  name = \"admin_group\"\n}\n\nresource \"aws_iam_group\" \"dev_group\" {\n  name = \"dev_group\"\n}\n#####################################################\n# Policy Definition, Policy-Group Attachment\ndata \"aws_iam_policy_document\" \"admin_policy\" {\n  statement {\n    effect    = \"Allow\"\n    actions   = [\"*\"]\n    resources = [\"*\"]\n  }\n}\nresource \"aws_iam_policy\" \"admin_policy\" {\n  name        = \"admin-policy\"\n  description = \"Admin policy\"\n  policy      = data.aws_iam_policy_document.admin_policy.json\n}\n\ndata \"aws_iam_policy_document\" \"ec2_policy\" {\n  statement {\n    effect    = \"Allow\"\n    actions   = [\"ec2:Describe*\"]\n    resources = [\"*\"]\n  }\n}\n\nresource \"aws_iam_policy\" \"ec2_policy\" {\n  name        = \"ec2-policy\"\n  description = \"EC2 policy\"\n  policy      = data.aws_iam_policy_document.ec2_policy.json\n}\n\n#####################################################\n# Policy Attachment to the Admin, Dev Group \nresource \"aws_iam_group_policy_attachment\" \"admin_group_admin_policy_attach\" {\n  group      = aws_iam_group.admin_group.name\n  policy_arn = aws_iam_policy.admin_policy.arn\n}\n\nresource \"aws_iam_group_policy_attachment\" \"dev_group_ec2_policy_attach\" {\n  group      = aws_iam_group.dev_group.name\n  policy_arn = aws_iam_policy.ec2_policy.arn\n}\n\n#####################################################\n# Username Definition\n# With Count\nresource \"aws_iam_user\" \"user_example\" {\n  count = length(var.user_names)\n  name  = var.user_names[count.index]\n}\n# count, use list \nvariable \"user_names\" {\n  description = \"IAM usernames\"\n  type        = list(string)\n  default     = [\"username1_admin_dev\", \"username2_admin\", \"username3_dev_ec2\"]\n}\n#####################################################\n# With for loop\noutput \"print_the_names\" {\n  value = [for name in var.user_names : name]\n}\n``` \n\n**File:** https://github.com/omerbsezer/Fast-Terraform/blob/main/labs/iamuser-metaargs-count-for-foreach-map/count/main.tf\n\n![image](https://user-images.githubusercontent.com/10358317/228506487-f1b0f962-9812-4c4a-a189-f88e55ae55f9.png)\n\n- Run init command:\n\n``` \nterraform init\n```\n\n- Validate file:\n\n``` \nterraform validate\n``` \n\n![image](https://user-images.githubusercontent.com/10358317/228507230-6a771b36-1bcb-44c5-969f-21640b041a6a.png)\n\n- Run plan command:\n\n``` \nterraform plan\n``` \n\n![image](https://user-images.githubusercontent.com/10358317/229285029-7915460b-24fa-472d-bf32-515d389fdd03.png)\n\n- Run apply command:\n\n``` \nterraform apply\n``` \n\n![image](https://user-images.githubusercontent.com/10358317/229285059-a60d56f4-fe38-43d1-816d-e9537cedf884.png)\n\n![image](https://user-images.githubusercontent.com/10358317/229285114-09358bae-94dc-49b1-bec4-a7951a6bd3d8.png)\n\n- On AWS > IAM > Users, users are created:\n\n![image](https://user-images.githubusercontent.com/10358317/228508807-573a9e39-d906-4ec3-b32a-f1cd57cc5504.png)\n\n- Click on \"username1_admin_dev\" to see the policies:\n\n![image](https://user-images.githubusercontent.com/10358317/228509359-07dcf4ca-9f2d-422d-9dea-c346f4341168.png)\n\n- To see user groups membership:\n\n![image](https://user-images.githubusercontent.com/10358317/228509893-ed5fc830-94ec-4815-b1be-0811c2e0e566.png)\n\n- Users in the \"admin_group\":\n\n![image](https://user-images.githubusercontent.com/10358317/228510263-8c6b2b28-20bc-4e86-82a3-8c96c1143b93.png)\n\n- EC2 Policy for \"username3_dev_ec2\":\n\n![image](https://user-images.githubusercontent.com/10358317/228510983-1458f5f5-275b-4fe2-bc17-84d05bf4cd6c.png)\n\n\n- Destroy resources:\n\n```\nterraform destroy\n```\n\n![image](https://user-images.githubusercontent.com/10358317/229285219-a0693f5b-f730-4f09-bcc4-5ddfab11b8b7.png)\n\n### For Each\n\n- To test \"for_each\", main.tf under for_each.\n- Some differents from previous one: \n  - not index, with name. e.g. aws_iam_user.user_example[\"username1_admin_dev\"].name\n  - s3 policy, attachment\n  - for_each implementation\n  \n```\nterraform {\n  required_providers {\n    aws = {\n      source  = \"hashicorp/aws\"\n      version = \"~> 4.16\"\n    }\n  }\n\n  required_version = \">= 1.2.0\"\n}\n\n#####################################################\n# User - User Group Attachment (With Index Count)\nresource \"aws_iam_user_group_membership\" \"user1_group_attach\" {\n  user = aws_iam_user.user_example[\"username1_admin_dev\"].name\n\n  groups = [\n    aws_iam_group.admin_group.name,\n    aws_iam_group.dev_group.name,\n  ]\n}\n\nresource \"aws_iam_user_group_membership\" \"user2_group_attach\" {\n  user = aws_iam_user.user_example[\"username2_admin\"].id\n\n  groups = [\n    aws_iam_group.admin_group.name\n  ]\n}\n\nresource \"aws_iam_user_group_membership\" \"user3_group_attach\" {\n  user = aws_iam_user.user_example[\"username3_dev_s3\"].name\n\n  groups = [\n    aws_iam_group.dev_group.name\n  ]\n}\n#####################################################\n# User Group Definition\nresource \"aws_iam_group\" \"admin_group\" {\n  name = \"admin_group\"\n}\n\nresource \"aws_iam_group\" \"dev_group\" {\n  name = \"dev_group\"\n}\n#####################################################\n# Policy Definition, Policy-Group Attachment\ndata \"aws_iam_policy_document\" \"admin_policy\" {\n  statement {\n    effect    = \"Allow\"\n    actions   = [\"*\"]\n    resources = [\"*\"]\n  }\n}\nresource \"aws_iam_policy\" \"admin_policy\" {\n  name        = \"admin-policy\"\n  description = \"Admin policy\"\n  policy      = data.aws_iam_policy_document.admin_policy.json\n}\n\ndata \"aws_iam_policy_document\" \"s3_policy\" {\n  statement {\n    effect    = \"Allow\"\n    actions   = [\"s3:*\"]\n    resources = [\n      \"arn:aws:s3:::mybucket\",\n      \"arn:aws:s3:::mybucket/*\"\n    ]\n  }\n}\n\nresource \"aws_iam_policy\" \"s3_policy\" {\n  name        = \"s3-policy\"\n  description = \"S3 policy\"\n  policy      = data.aws_iam_policy_document.s3_policy.json\n}\n\n#####################################################\n# Policy Attachment to the Admin, Dev Group \nresource \"aws_iam_group_policy_attachment\" \"admin_group_admin_policy_attach\" {\n  group      = aws_iam_group.admin_group.name\n  policy_arn = aws_iam_policy.admin_policy.arn\n}\n\nresource \"aws_iam_group_policy_attachment\" \"dev_group_s3_policy_attach\" {\n  group      = aws_iam_group.dev_group.name\n  policy_arn = aws_iam_policy.s3_policy.arn\n}\n#####################################################\n# With for_each\nresource \"aws_iam_user\" \"user_example\" {\n  for_each = var.user_names\n  name  = each.value\n}\n# for each, use set instead of list\nvariable \"user_names\" {\n  description = \"IAM usernames\"\n  type        = set(string)\n  default     = [\"username1_admin_dev\", \"username2_admin\", \"username3_dev_s3\"]\n}\n#####################################################\n# With for loop\noutput \"print_the_names\" {\n  value = [for name in var.user_names : name]\n}\n\n```\n**File:** https://github.com/omerbsezer/Fast-Terraform/blob/main/labs/iamuser-metaargs-count-for-foreach-map/for_each/main.tf\n\n- This time, for dev groups, it creates S3 Permission Policy\n\n- Run init command:\n\n``` \nterraform init\n```\n\n- Validate file:\n\n``` \nterraform validate\n``` \n\n- Run plan command:\n\n``` \nterraform plan\n``` \n\n- Run apply command:\n\n``` \nterraform apply\n``` \n\n![image](https://user-images.githubusercontent.com/10358317/229285279-fe30ddd9-3cec-46c1-88d5-8a504994a956.png)\n\n![image](https://user-images.githubusercontent.com/10358317/228515164-73df4541-e651-40b9-b6d3-068797d7060b.png)\n\nOn AWS, the different from previous example, s3 policy is created:\n\n![image](https://user-images.githubusercontent.com/10358317/228515836-b26ef31f-1961-4062-ad0a-73dd40789fff.png)\n\n\n![image](https://user-images.githubusercontent.com/10358317/228515699-7aabe035-2d17-4140-9c5a-121e72427810.png)\n\n- Destroy resources:\n\n```\nterraform destroy\n```\n\n![image](https://user-images.githubusercontent.com/10358317/228517742-bfe17919-ce01-4400-a2ac-dade7a041dbd.png)\n\n\n### Map\n\n- You can also use map to define usernames, following yaml file shows how to use maps\n\n```\nterraform {\n  required_providers {\n    aws = {\n      source  = \"hashicorp/aws\"\n      version = \"~> 4.16\"\n    }\n  }\n\n  required_version = \">= 1.2.0\"\n}\n\n#####################################################\n# With for_each\nresource \"aws_iam_user\" \"example\" {\n  for_each = var.user_names\n  name  = each.value\n}\n# With Map\nvariable \"user_names\" {\n  description = \"map\"\n  type        = map(string)\n  default     = {\n    user1      = \"username1\"\n    user2      = \"username2\"\n    user3      = \"username3\"\n  }\n}\n# with for loop on map \noutput \"user_with_roles\" {\n  value = [for name, role in var.user_names : \"${name} is the ${role}\"]\n}\n```\n\n**File:** https://github.com/omerbsezer/Fast-Terraform/blob/main/labs/iamuser-metaargs-count-for-foreach-map/map/main.tf\n"
  },
  {
    "path": "LAB05-Dynamic-Blocks-Security-Groups-EC2.md",
    "content": "## LAB-05: Dynamic Blocks => Provision Security Groups, EC2, VPC\n\nThis scenario shows:\n- how to create Dynamic Blocks for Security Group Definition\n\n**Code:** https://github.com/omerbsezer/Fast-Terraform/blob/main/labs/dynamic-blocks/main.tf\n\n### Prerequisite\n\n- You should have a look following lab: \n  - [LAB-00: Terraform Install, AWS Configuration with Terraform](https://github.com/omerbsezer/Fast-Terraform/blob/main/LAB00-Terraform-Install-AWS-Configuration.md)\n\n## Steps\n\n- With Dynamic Blocks, preventing repetition same code. \n \n``` \n...\nlocals {\n   ingress_rules = [{\n      port        = 22\n      description = \"Ingress rules for port SSH\"\n   },\n   {\n      port        = 80\n      description = \"Ingress rules for port HTTP\"\n   },\n   {\n      port        = 443\n      description = \"Ingress rules for port HTTPS\"\n   }]\n}\n\nresource \"aws_security_group\" \"main\" {\n   ...\n   dynamic \"ingress\" {\n      for_each = local.ingress_rules\n\n      content {\n         description = ingress.value.description\n         from_port   = ingress.value.port\n         to_port     = ingress.value.port\n         protocol    = \"tcp\"\n         cidr_blocks = [\"0.0.0.0/0\"]\n      }\n   }\n   ...\n}\n...\n``` \n\n![image](https://user-images.githubusercontent.com/10358317/229287304-d23dca31-d871-4c88-a4fa-e1994ef671d0.png)\n\n- Copy the following main.tf:\n \n```\nterraform {\n  required_providers {\n    aws = {\n      source  = \"hashicorp/aws\"\n      version = \"~> 4.16\"\n    }\n  }\n\n  required_version = \">= 1.2.0\"\n}\n\nprovider \"aws\" {\n\tregion = \"eu-central-1\"\n}\n\nresource \"aws_vpc\" \"my_vpc\" {\n  cidr_block           = \"10.0.0.0/16\"\n  enable_dns_hostnames = true\n  tags = {\n    Name = \"My VPC\"\n  }\n}\n\nresource \"aws_subnet\" \"public\" {\n  vpc_id            = aws_vpc.my_vpc.id\n  cidr_block        = \"10.0.0.0/24\"\n  availability_zone = \"eu-central-1c\"\n  tags = {\n    Name = \"Public Subnet\"\n  }\n}\n\nresource \"aws_internet_gateway\" \"my_vpc_igw\" {\n  vpc_id = aws_vpc.my_vpc.id\n  tags = {\n    Name = \"My VPC - Internet Gateway\"\n  }\n}\n\nresource \"aws_route_table\" \"my_vpc_eu_central_1c_public\" {\n    vpc_id = aws_vpc.my_vpc.id\n    route {\n        cidr_block = \"0.0.0.0/0\"\n        gateway_id = aws_internet_gateway.my_vpc_igw.id\n    }\n    tags = {\n        Name = \"Public Subnet Route Table\"\n    }\n}\nresource \"aws_route_table_association\" \"my_vpc_eu_central_1c_public\" {\n    subnet_id      = aws_subnet.public.id\n    route_table_id = aws_route_table.my_vpc_eu_central_1c_public.id\n}\n\nlocals {\n   ingress_rules = [{\n      port        = 22\n      description = \"Ingress rules for port SSH\"\n   },\n   {\n      port        = 80\n      description = \"Ingress rules for port HTTP\"\n   },\n   {\n      port        = 443\n      description = \"Ingress rules for port HTTPS\"\n   }]\n}\n\nresource \"aws_security_group\" \"main\" {\n   name        = \"resource_with_dynamic_block\"\n   description = \"Allow SSH inbound connections\"\n   vpc_id      =  aws_vpc.my_vpc.id \n\n   dynamic \"ingress\" {\n      for_each = local.ingress_rules\n\n      content {\n         description = ingress.value.description\n         from_port   = ingress.value.port\n         to_port     = ingress.value.port\n         protocol    = \"tcp\"\n         cidr_blocks = [\"0.0.0.0/0\"]\n      }\n   }\n\n   egress {\n    from_port       = 0\n    to_port         = 0\n    protocol        = \"-1\"\n    cidr_blocks     = [\"0.0.0.0/0\"]\n   }\n\n   tags = {\n      Name = \"AWS security group dynamic block\"\n   }\n}\n\nresource \"aws_instance\" \"ubuntu2204\" {\n  ami                         = \"ami-0d1ddd83282187d18\" # Ubuntu 22.04 eu-central-1 Frankfurt\n  instance_type               = \"t2.nano\"\n  key_name                    = \"testkey\"\n  vpc_security_group_ids      = [aws_security_group.main.id]\n  subnet_id                   = aws_subnet.public.id\n  associate_public_ip_address = true\n  tags = {\n    Name = \"Ubuntu 22.04\"\n  }\n}\n\noutput \"instance_ubuntu2204_public_ip\" {\n  value = \"${aws_instance.ubuntu2204.public_ip}\"\n}\n``` \n\n**Code:** https://github.com/omerbsezer/Fast-Terraform/blob/main/labs/dynamic-blocks/main.tf\n\n- Run init, validate command:\n\n``` \nterraform init\nterraform validate\n``` \n\n- Run plan, apply command:\n\n``` \nterraform plan\nterraform apply\n``` \n\n![image](https://user-images.githubusercontent.com/10358317/229287533-de896cdf-6189-45f1-a631-5f609be22721.png)\n\n![image](https://user-images.githubusercontent.com/10358317/229287613-9815134c-4e36-4d70-adff-c7a272d82a31.png)\n\n- On AWS EC2 Instances:\n\n![image](https://user-images.githubusercontent.com/10358317/229287673-ddbfa4a9-ca15-4375-a584-043cf259d344.png)\n\n- Security groups are created with Dynamic Blocks:\n\n![image](https://user-images.githubusercontent.com/10358317/229287707-b5f215cd-0faf-4cbc-bc1d-868d96f2672d.png)\n\n- Destroy infrastructure:\n\n```\nterraform destroy \n``` \n\n![image](https://user-images.githubusercontent.com/10358317/229287838-c3ffcaa2-a931-4c9b-9efe-40760d76a6af.png)\n\n![image](https://user-images.githubusercontent.com/10358317/229287904-a2ff9428-f15b-4b2e-a2fb-749d11f4e317.png)\n"
  },
  {
    "path": "LAB06-Data-Sources-EC2.md",
    "content": "## LAB-06: Data Sources with Depends_on => Provision EC2\n\nThis scenario shows:\n- how to use Data Source to fetch/retrieve data (existed resource information) from AWS\n\n**Code:** https://github.com/omerbsezer/Fast-Terraform/blob/main/labs/data-sources/main.tf\n\n### Prerequisite\n\n- You should have a look following lab: \n  - [LAB-00: Terraform Install, AWS Configuration with Terraform](https://github.com/omerbsezer/Fast-Terraform/blob/main/LAB00-Terraform-Install-AWS-Configuration.md)\n\n## Steps\n\n- With data sources, existed resource information can be fetched/retrieved.\n- \"filter\" provide to select/filter the existed instances\n- \"depends_on\" provide to run the data block after resource created \n \n``` \n...\ndata \"aws_instance\" \"data_instance\" {\n    filter {\n      name = \"tag:Name\"\n      values = [\"Basic Instance\"]\n    }\n\n    depends_on = [\n      aws_instance.instance\n    ]\n} \n\noutput \"instance_info\" {\n  value = data.aws_instance.data_instance\n}\n...\n``` \n\n![image](https://user-images.githubusercontent.com/10358317/229291040-febb8404-4c00-48c3-b99d-ea0af0e68825.png)\n\n- Create main.tf:\n\n```\nterraform {\n  required_providers {\n    aws = {\n      source  = \"hashicorp/aws\"\n      version = \"~> 4.16\"\n    }\n  }\n\n  required_version = \">= 1.2.0\"\n}\n\nprovider \"aws\" {\n\tregion = \"eu-central-1\"\n}\n\nresource \"aws_instance\" \"instance\" {\n\tami           = \"ami-0d1ddd83282187d18\" # Ubuntu 22.04 eu-central-1 Frankfurt\n\tinstance_type = \"t2.nano\"\n\n\ttags = {\n\t\tName = \"Basic Instance\"\n\t}\n}\n\n# filter/select the existed instances\n# depends_on if aws_instance.instance is created\n\ndata \"aws_instance\" \"data_instance\" {\n    filter {\n      name = \"tag:Name\"\n      values = [\"Basic Instance\"]\n    }\n\n    depends_on = [\n      aws_instance.instance\n    ]\n} \n\noutput \"instance_info\" {\n  value = data.aws_instance.data_instance\n}\n\noutput \"instance_public_ip\" {\n  value = data.aws_instance.data_instance.public_ip\n}\n```\n\n**Code:** https://github.com/omerbsezer/Fast-Terraform/blob/main/labs/data-sources/main.tf\n\n![image](https://user-images.githubusercontent.com/10358317/229291093-e5febd7a-fa05-44bc-a224-00a18035b869.png)\n\n- Run init, validate command:\n\n``` \nterraform init\nterraform validate\n``` \n\n- Run plan, apply command:\n\n``` \nterraform plan\nterraform apply\n``` \n\n![image](https://user-images.githubusercontent.com/10358317/229291488-831a796e-b77a-43ee-92a1-814630834907.png)\n\n![image](https://user-images.githubusercontent.com/10358317/229291530-985497f5-87a4-41d8-8fec-3f6217d62e6d.png)\n\n- With output, details can be viewed:\n\n![image](https://user-images.githubusercontent.com/10358317/229291636-963cfbf8-4735-4d62-bae4-c803f70a1775.png)\n\n![image](https://user-images.githubusercontent.com/10358317/229291821-28dea44f-04cf-42ef-b436-cbdfc77bd294.png)\n\n- Destroy infrastructure:\n\n```\nterraform destroy \n``` \n\n![image](https://user-images.githubusercontent.com/10358317/229291943-7a61e1c5-743f-4508-928f-04d738c2bb5a.png)\n\n![image](https://user-images.githubusercontent.com/10358317/229291973-1d789992-8a90-4709-8da1-2db5b3b79b46.png)\n\n\n"
  },
  {
    "path": "LAB07-Provisioners-Null-Resources.md",
    "content": "## LAB-07: Provisioners (file, remote-exec), Null Resources (local-exec) => Provision Key-Pair, SSH Connection\n\nThis scenario shows:\n- how to create file, run command using \"remote-exec\" provisioners on remote instance,\n- how to create file using provisioner \"file\" on remote instance,\n- how to create file, run command using \"local-exec\" on local pc,\n- how to create key-pairs for SSH connection.\n\n**Code:** https://github.com/omerbsezer/Fast-Terraform/blob/main/labs/provisioners-nullresources/main.tf\n\n### Prerequisite\n\n- You should have a look following lab: \n  - [LAB-00: Terraform Install, AWS Configuration with Terraform](https://github.com/omerbsezer/Fast-Terraform/blob/main/LAB00-Terraform-Install-AWS-Configuration.md)\n  \n## Steps\n\n- SSH key-pairs (public and private key) are used to connect remote server. Public key (xx.pub) is on the remote server, with private key, user can connect using SSH.\n\n- There are 2 ways of creating key-pairs (public and private key):\n  - Creating them on cloud (AWS)\n  \t- EC2 > Key-pairs > Create Key-Pair\n  - Creating them on on-premise \n  \t- \"ssh-keygen -t rsa -b 2048\" \n\n- Creating key-pairs on AWS: Go to EC2 > Key-pairs\n\n![image](https://user-images.githubusercontent.com/10358317/228974087-b57126ab-6589-48fe-b609-1f18dc2f0c7e.png)\n\n- After creating key-pairs, public key is listed on AWS:\n\n![image](https://user-images.githubusercontent.com/10358317/228974292-0d2d16ec-5590-4929-9b4e-8bc0215dcd60.png)\n\n- Private key (testkey.pem) is downloaded on your PC:\n\n![image](https://user-images.githubusercontent.com/10358317/228974369-46c54f25-ea80-40dd-9c75-670ece815bf2.png)\n\n- Copy this testkey.pem into your directory on which main.tf exists.\n\n![image](https://user-images.githubusercontent.com/10358317/228974784-de1b9be4-9083-45ec-a9ab-5a1e54aee2c5.png)\n\n- With provisioner \"file\", on the remote instance, new file can be created\n- With provisioner \"remote-exec\", on the remote instance, any command can be run\n- With provisioner \"local-exec\", on the local PC, any command can be run on any shell (bash, powershell)\n- With \"null_resource\", without creating any resource, any command can be run.\n- Provisioners in the resource only runs once while creating resource on remote instance \n- Provisioners in the \"null_resource\" run multiple times and it doesn't depend on the resource.  \n \n``` \n...\nresource \"aws_instance\" \"ubuntu2204\" {\n\n  ...\n  provisioner \"file\" {\n    source      = \"test-file.txt\" \n    destination = \"/home/ubuntu/test-file.txt\"\n  }\n\n  provisioner \"file\" {\n    content     = \"I want to copy this string to the destination file => server.txt (using provisioner file content)\"\n    destination = \"/home/ubuntu/server.txt\"\n  }\n  \n  provisioner \"remote-exec\" {\n    inline = [\n      \"touch hello.txt\",\n      \"echo helloworld remote-exec provisioner >> hello.txt\",\n    ]\n  }\n\n  connection {\n      type        = \"ssh\"\n      host        = self.public_ip\n      user        = \"ubuntu\"\n      private_key = file(\"testkey.pem\")\n      timeout     = \"4m\"\n   }\n}\n\nresource \"null_resource\" \"example\" {\n  provisioner \"local-exec\" {\n    command = \"'This is test file for null resource local-exec' >>  nullresource-generated.txt\"\n    interpreter = [\"PowerShell\", \"-Command\"]\n  }\n}\n...\n``` \n\n![image](https://user-images.githubusercontent.com/10358317/229303293-52a67375-9d3f-43f0-86a3-955ff6e6613a.png)\n\n- Create main.tf\n\n```\nterraform {\n  required_providers {\n    aws = {\n      source  = \"hashicorp/aws\"\n      version = \"~> 4.16\"\n    }\n  }\n  required_version = \">= 1.2.0\"\n}\n\nprovider \"aws\" {\n\tregion = \"eu-central-1\"\n}\n\nresource \"aws_vpc\" \"my_vpc\" {\n  cidr_block           = \"10.0.0.0/16\"\n  enable_dns_hostnames = true\n  tags = {\n    Name = \"My VPC\"\n  }\n}\n\nresource \"aws_subnet\" \"public\" {\n  vpc_id            = aws_vpc.my_vpc.id\n  cidr_block        = \"10.0.0.0/24\"\n  availability_zone = \"eu-central-1c\"\n  tags = {\n    Name = \"Public Subnet\"\n  }\n}\n\nresource \"aws_internet_gateway\" \"my_vpc_igw\" {\n  vpc_id = aws_vpc.my_vpc.id\n  tags = {\n    Name = \"My VPC - Internet Gateway\"\n  }\n}\n\nresource \"aws_route_table\" \"my_vpc_eu_central_1c_public\" {\n    vpc_id = aws_vpc.my_vpc.id\n    route {\n        cidr_block = \"0.0.0.0/0\"\n        gateway_id = aws_internet_gateway.my_vpc_igw.id\n    }\n    tags = {\n        Name = \"Public Subnet Route Table\"\n    }\n}\nresource \"aws_route_table_association\" \"my_vpc_eu_central_1c_public\" {\n    subnet_id      = aws_subnet.public.id\n    route_table_id = aws_route_table.my_vpc_eu_central_1c_public.id\n}\n\nresource \"aws_security_group\" \"allow_ssh\" {\n  name        = \"allow_ssh_sg\"\n  description = \"Allow SSH inbound connections\"\n  vpc_id      = aws_vpc.my_vpc.id\n  # for SSH\n  ingress {\n    from_port   = 22\n    to_port     = 22\n    protocol    = \"tcp\"\n    cidr_blocks = [\"0.0.0.0/0\"]\n  }\n  egress {\n    from_port       = 0\n    to_port         = 0\n    protocol        = \"-1\"\n    cidr_blocks     = [\"0.0.0.0/0\"]\n  }\n  tags = {\n    Name = \"allow_ssh_sg\"\n  }\n}\n\nresource \"aws_instance\" \"ubuntu2204\" {\n\n  ami                         = \"ami-0d1ddd83282187d18\" # Ubuntu 22.04 eu-central-1 Frankfurt\n  instance_type               = \"t2.nano\" \n  key_name                    = \"testkey\"\n  vpc_security_group_ids      = [aws_security_group.allow_ssh.id]\n  subnet_id                   = aws_subnet.public.id\n  associate_public_ip_address = true\n\n  tags = {\n    Name = \"Ubuntu 22.04\"\n  }\n\n  provisioner \"file\" {\n    source      = \"test-file.txt\" \n    destination = \"/home/ubuntu/test-file.txt\"\n  }\n\n  provisioner \"file\" {\n    content     = \"I want to copy this string to the destination file => server.txt (using provisioner file content)\"\n    destination = \"/home/ubuntu/server.txt\"\n  }\n  \n  provisioner \"remote-exec\" {\n    inline = [\n      \"touch hello.txt\",\n      \"echo helloworld remote-exec provisioner >> hello.txt\",\n    ]\n  }\n\n  connection {\n      type        = \"ssh\"\n      host        = self.public_ip\n      user        = \"ubuntu\"\n      private_key = file(\"testkey.pem\")\n      timeout     = \"4m\"\n   }\n}\n\nresource \"null_resource\" \"example\" {\n  provisioner \"local-exec\" {\n    command = \"'This is test file for null resource local-exec' >>  nullresource-generated.txt\"\n    interpreter = [\"PowerShell\", \"-Command\"]\n  }\n}\n``` \n\n**Code:** https://github.com/omerbsezer/Fast-Terraform/blob/main/labs/provisioners-nullresources/main.tf\n\n- Run init, validate command:\n\n``` \nterraform init\nterraform validate\n``` \n\n- Run plan, apply command:\n\n``` \nterraform plan\nterraform apply\n``` \n\n![image](https://user-images.githubusercontent.com/10358317/229302416-31b1baa5-7aac-45fa-8ca5-15120b0c6f2e.png)\n\n![image](https://user-images.githubusercontent.com/10358317/229302498-c338ee6c-b16d-4e4a-a21b-3577c9403aed.png)\n\n- On AWS EC2 Instance:\n\n![image](https://user-images.githubusercontent.com/10358317/229302953-73056a26-c85e-4fad-ba68-115f3fc3dcf1.png)\n\n- Make SSH connection:\n\n``` \nssh -i testkey.pem ubuntu@<PublicIP>\n``` \n\n- Provisioners run and files were created on remote instance:\n\n![image](https://user-images.githubusercontent.com/10358317/229302702-57df3eec-f6f9-4d5e-af1b-bfb47cc9a906.png)\n\n- On local PC, local provisioner also created file:\n\n![image](https://user-images.githubusercontent.com/10358317/229302840-0e17e5ac-cc34-4252-9cf6-9df56a034a4a.png)\n\n- Destroy infrastructure:\n\n```\nterraform destroy \n``` \n\n![image](https://user-images.githubusercontent.com/10358317/229303068-c096e9f4-c6b6-45e4-b3a9-71ef0336a755.png)\n\n![image](https://user-images.githubusercontent.com/10358317/229303188-3fd076c2-fac4-4ef2-8c7d-958c0f825640.png)\n\n- On AWS EC2 Instance:\n\n![image](https://user-images.githubusercontent.com/10358317/229303226-adaead1f-6f6a-4138-9640-4dfce873166c.png)\n\n"
  },
  {
    "path": "LAB08-Modules-EC2.md",
    "content": "## LAB-08: Modules => Provision EC2\n\nThis scenario shows:\n- how to create and use modules \n\n**Code:** https://github.com/omerbsezer/Fast-Terraform/tree/main/labs/modules\n\n### Prerequisite\n\n- You should have a look following lab: \n  - [LAB-00: Terraform Install, AWS Configuration with Terraform](https://github.com/omerbsezer/Fast-Terraform/blob/main/LAB00-Terraform-Install-AWS-Configuration.md)\n\n## Steps\n\n- With modules, it helps:\n  - organize configuration\n  - encapsulation \n  - re-usability\n  - consistency\n\n- Main.tf refers modules (directories)\n- Each modules have variables.tf\n\n\n### Module Calls (Main.tf)\n\n**Main.tf Code:** https://github.com/omerbsezer/Fast-Terraform/blob/main/labs/modules/main.tf\n\n``` \n...\nmodule \"webserver-1\" {\n  source = \".//module1\"\n\n  instance_type     =   \"t2.nano\"\n  tag               =   \"Webserver1 - Module1 - 20.04\"\n  location          =   \"eu-central-1\"\n  availability_zone =   \"eu-central-1c\"\n  ami               =   \"ami-0e067cc8a2b58de59\" # Ubuntu 20.04 eu-central-1 Frankfurt\n\n}\n\nmodule \"webserver-2\" {\n  source = \".//module2\"\n\n  instance_type     =   \"t2.micro\"\n  tag               =   \"Webserver2 - Module2 - 22.04\"\n  location          =   \"eu-central-1\"\n  availability_zone =   \"eu-central-1a\"\n  ami               =   \"ami-0d1ddd83282187d18\" # Ubuntu 22.04 eu-central-1 Frankfurt\n}\n``` \n\n![image](https://user-images.githubusercontent.com/10358317/229362702-43148537-03fc-4876-9883-ccee83a63f56.png)\n\n### Module1\n\n**Module1 Variables.tf Code:** https://github.com/omerbsezer/Fast-Terraform/blob/main/labs/modules/module1/variables.tf\n\n``` \nvariable \"instance_type\" {\n    type = string\n    description = \"EC2 Instance Type\"\n}\n\nvariable \"tag\" {\n    type = string\n    description = \"The tag for the EC2 instance\"\n}\n\nvariable \"location\" {\n    type = string\n    description = \"The project region\"\n    default = \"eu-central-1\"\n}\n\nvariable  \"availability_zone\" {\n    type = string\n    description = \"The project availability zone\"\n    default = \"eu-central-1c\"\n} \n\nvariable \"ami\" {\n    type = string\n    description = \"The project region\"\n}\n``` \n\n**Module1 Main.tf Code:** https://github.com/omerbsezer/Fast-Terraform/blob/main/labs/modules/module1/main.tf\n\n\n### Module2\n\n- Module2 variables.tf is same as module1 variables.tf\n\n**Module2 Variables.tf Code:** https://github.com/omerbsezer/Fast-Terraform/blob/main/labs/modules/module2/variables.tf\n\n- Module2 main.tf code is different from module1 main.tf\n\n**Module2 Main.tf Code:** https://github.com/omerbsezer/Fast-Terraform/blob/main/labs/modules/module2/main.tf\n\n### Terraform Run\n\n- Run init, validate command:\n\n``` \nterraform init\nterraform validate\n``` \n\n![image](https://user-images.githubusercontent.com/10358317/229363829-54d98270-7cb6-499d-8ca5-235187945e78.png)\n\n![image](https://user-images.githubusercontent.com/10358317/229363852-4df92036-b8d1-4206-9da9-d6769237f46f.png)\n\n- Run plan, apply command:\n\n``` \nterraform plan\nterraform apply\n``` \n\n![image](https://user-images.githubusercontent.com/10358317/229364064-2ac5ad88-f93c-4cb3-a803-de43a10e5885.png)\n\n![image](https://user-images.githubusercontent.com/10358317/229364027-755c7df6-4ecb-4fe0-9c10-ee30ecfa31c0.png)\n\n- On AWS, 2 EC2 Instances:\n\n![image](https://user-images.githubusercontent.com/10358317/229364124-4ce9c58c-c2e2-42e6-8f00-13a8c63185a0.png)\n\n![image](https://user-images.githubusercontent.com/10358317/229364304-23917adf-d488-4294-bc49-ce89c879817a.png)\n\n\n- On AWS, 2 VPCs:\n\n![image](https://user-images.githubusercontent.com/10358317/229364188-792953e2-0d57-4560-8591-3c13203864ab.png)\n\n![image](https://user-images.githubusercontent.com/10358317/229364233-41b910a9-d6cc-4e09-bbb7-11dd2054de56.png)\n\n- On Browser:\n\n![image](https://user-images.githubusercontent.com/10358317/229364349-7572c383-e934-4e6b-b0be-f3ba4c098ac4.png)\n\n![image](https://user-images.githubusercontent.com/10358317/229364366-ba334719-7789-42f7-b5e4-7cecfc7eb42a.png)\n\n- Destroy infrastructure:\n\n```\nterraform destroy \n``` \n\n![image](https://user-images.githubusercontent.com/10358317/229364565-c6f07625-008b-4e64-a62b-dc80ea6db4e3.png)\n\n![image](https://user-images.githubusercontent.com/10358317/229364693-bcc9c21d-d091-49ef-b176-d71cabf813fb.png)\n\n- On AWS, EC2s are terminated:\n\n![image](https://user-images.githubusercontent.com/10358317/229364904-22116720-7b4a-42d3-8b10-a34fc9dccafb.png)\n\n"
  },
  {
    "path": "LAB09-Workspaces-EC2.md",
    "content": "## LAB-09: Workspaces => Provision EC2 with Different tfvars Files\n\nThis scenario shows:\n- how to create, manage workspaces using EC2 and variables.\n\n**Code:**  https://github.com/omerbsezer/Fast-Terraform/tree/main/labs/workspace\n\n### Prerequisite\n\n- You should have a look following lab: \n  - [LAB-00: Terraform Install, AWS Configuration with Terraform](https://github.com/omerbsezer/Fast-Terraform/blob/main/LAB00-Terraform-Install-AWS-Configuration.md)\n\n## Steps\n\n- With workspaces,\n  - a parallel, distinct copy of your infrastructure which you can test and verify in the development, test, and staging \n  - like git, you are working on different workspaces (like branch)\n  - single code but different workspaces\n  - it creates multiple state files\n\n- Workspace commands:\n\n``` \nterraform workspace help                       # help for workspace commands\nterraform workspace new [WorkspaceName]        # create new workspace\nterraform workspace select [WorkspaceName]     # change/select another workspace\nterraform workspace show                       # show current workspace\nterraform workspace list                       # list all workspaces\nterraform workspace delete [WorkspaceName]     # delete existed workspace\n``` \n\n![image](https://user-images.githubusercontent.com/10358317/229855095-05b608f7-04aa-4603-9516-600d0c692d01.png)\n\n- We have basic main.tf file with EC2, variables:\n\n``` \nterraform {\n  required_providers {\n    aws = {\n      source  = \"hashicorp/aws\"\n      version = \"~> 4.16\"\n    }\n  }\n\n  required_version = \">= 1.2.0\"\n}\n\nprovider \"aws\" {\n\tregion = var.location\n}\n\nlocals {\n    tag = \"${terraform.workspace} EC2\"\n}\n\nresource \"aws_instance\" \"instance\" {\n\tami           = var.ami\n\tinstance_type = var.instance_type\n\n\ttags = {\n\t\tName = local.tag\n\t}\n}\n``` \n\n**Code:**  https://github.com/omerbsezer/Fast-Terraform/blob/main/labs/workspace/main.tf\n\n![image](https://user-images.githubusercontent.com/10358317/230614196-cd007efe-388e-408b-a92e-bb064e07e0ab.png)\n\n- Variables.tf file:\n\n```\nvariable \"instance_type\" {\n    type = string\n    description = \"EC2 Instance Type\"\n}\n\nvariable \"location\" {\n    type = string\n    description = \"The project region\"\n    default = \"eu-central-1\"\n}\n\nvariable \"ami\" {\n    type = string\n    description = \"The project region\"\n}\n```\n\n**Code:**  https://github.com/omerbsezer/Fast-Terraform/blob/main/labs/workspace/variables.tf\n\n![image](https://user-images.githubusercontent.com/10358317/230614240-504aaebd-00a5-4d85-8ecd-73df9a9a2254.png)\n\n- For development workspace, terraform-dev.tfvars:\n\n```\ninstance_type     =   \"t2.nano\"\nlocation          =   \"eu-central-1\"\nami               =   \"ami-0e067cc8a2b58de59\" # Ubuntu 20.04 eu-central-1 Frankfurt\n```\n\n**Code:**  https://github.com/omerbsezer/Fast-Terraform/blob/main/labs/workspace/terraform-dev.tfvars\n\n![image](https://user-images.githubusercontent.com/10358317/230614271-f5c5ccde-3d29-40ae-845f-5260060e2a5c.png)\n\n\n- For product workspace, terraform-prod.tfvars:\n\n```\ninstance_type     =   \"t2.micro\"\nlocation          =   \"eu-central-1\"\nami               =   \"ami-0d1ddd83282187d18\" # Ubuntu 22.04 eu-central-1 Frankfurt\n```\n\n**Code:**  https://github.com/omerbsezer/Fast-Terraform/blob/main/labs/workspace/terraform-prod.tfvars\n\n![image](https://user-images.githubusercontent.com/10358317/230614321-0f2ba768-cc0d-44f6-b68f-8a5c94ccb976.png)\n\n- To list current workspaces on the local:\n\n```\nterraform workspace list\n```\n\n![image](https://user-images.githubusercontent.com/10358317/230609965-a282fba2-d318-4a24-b189-c928abdbd2cf.png)\n\n- 2 workspaces are created (DEV, PROD):\n\n```\nterraform workspace new dev\nterraform workspace new prod\nterraform workspace list\n```\n\n![image](https://user-images.githubusercontent.com/10358317/230610099-3b8e3d91-e0a9-4a4e-bb25-8a8e15a489b5.png)\n\n- Switch to DEV workspace, show current workspace and initialize terraform:\n\n```\nterraform workspace select dev\nterraform workspace show\nterraform init\n```\n\n![image](https://user-images.githubusercontent.com/10358317/230610877-e76ed796-6e38-4493-89d7-2dbdbd43457f.png)\n\n- Create infrastructure in DEV workspace: \n\n```\nterraform plan -var-file=\"terraform-dev.tfvars\"     # for test, dry-run\nterraform apply -var-file=\"terraform-dev.tfvars\"\n```\n\n- On AWS, it creates dev EC2:\n\n![image](https://user-images.githubusercontent.com/10358317/230612063-b66afd1e-749a-41fe-b899-c68933ad4aa8.png)\n\n\n- Switch to PROD workspace, create infrastructure in PROD workspace: \n\n```\nterraform workspace select prod\nterraform plan -var-file=\"terraform-prod.tfvars\"     # for test, dry-run\nterraform apply -var-file=\"terraform-prod.tfvars\"\n```\n\n![image](https://user-images.githubusercontent.com/10358317/230612548-c8b79323-7f28-43c2-adc7-c7874ad3ed90.png)\n\n- On AWS, it creates prod EC2:\n\n![image](https://user-images.githubusercontent.com/10358317/230612752-565fdef3-7f89-496c-b108-03d6d38008ef.png)\n\n- With workspace, 2 state files are created for each workspace:\n\n![image](https://user-images.githubusercontent.com/10358317/230612889-dcd95404-3b0c-4b35-a3e4-a7844ca54a86.png)\n\n\n- Switch to DEV workspace, destroy infrastructure only in DEV workspace: \n\n```\nterraform workspace select dev\nterraform destroy -var-file=\"terraform-dev.tfvars\"  \n```\n\n![image](https://user-images.githubusercontent.com/10358317/230613305-4bfe6f81-e1bb-41c6-88cd-3ba9a37ee519.png)\n\n- On AWS, ONLY dev EC2 is terminated:\n\n![image](https://user-images.githubusercontent.com/10358317/230613441-3e52a33d-6721-47bf-a72e-1b28e524aac9.png)\n\n\n- Switch to PROD workspace, destroy infrastructure only in PROD workspace: \n\n```\nterraform workspace select prod\nterraform destroy -var-file=\"terraform-prod.tfvars\"  \n```\n\n![image](https://user-images.githubusercontent.com/10358317/230613867-c347eb16-6f5d-452c-85cf-4e54d3dfc89f.png)\n\n- On AWS, ONLY prod EC2 is terminated:\n\n![image](https://user-images.githubusercontent.com/10358317/230613937-92d8ec9c-ffd2-48f7-9cbd-be6ca11500b5.png)\n\n\n## References\n- https://jhooq.com/terraform-workspaces/\n\n\n\n\n"
  },
  {
    "path": "LAB10-Templates-User-Policy.md",
    "content": "## LAB-10: Templates => Provision IAM User, User Access Key, Policy\n\nThis scenario shows:\n- how to use templates while creating policy \n\n**Code:**  https://github.com/omerbsezer/Fast-Terraform/tree/main/labs/template\n\n### Prerequisite\n\n- You should have a look following lab: \n  - [LAB-00: Terraform Install, AWS Configuration with Terraform](https://github.com/omerbsezer/Fast-Terraform/blob/main/LAB00-Terraform-Install-AWS-Configuration.md)\n\n## Steps\n\n- With templates,\n  - avoid to write same code snippets multiple time,\n  - provide to shorten the code \n\n- Create main.tf file.\n- This file creates IAM user, user access key, give some permission policy for EC2, S3, Lambda, DynamoDb. \n\n```\n# main.tf\nterraform {\n  required_providers {\n    aws = {\n      source  = \"hashicorp/aws\"\n      version = \"~> 4.16\"\n    }\n  }\n\n  required_version = \">= 1.2.0\"\n}\n\nprovider \"aws\" {\n\tregion = \"eu-central-1\"\n}\n\nresource \"aws_iam_user\" \"newuser\" {\n  name = \"New-User\"     # must only contain alphanumeric characters, hyphens, underscores, commas, periods, @ symbols, plus and equals signs\n}\nresource \"aws_iam_access_key\" \"access_key\" {\n  user = aws_iam_user.newuser.name\n}\n\nresource \"aws_iam_user_policy\" \"instanceManageUser_assume_role\" {\n  name = \"EC2-S3-Lambda-DynamoDb-Policy\"\n  user = \"${aws_iam_user.newuser.name}\"\n  policy = templatefile(\"${path.module}/policy.tftpl\", {\n    ec2_policies = [\n      \"ec2:RunInstances\",\n      \"ec2:StopInstances\",\n      \"ec2:StartInstances\",\n      \"ec2:TerminateInstances\",\n      \"ec2:TerminateInstances\",\n      \"ec2:Describe*\",\n      \"ec2:CreateTags\",\n      \"ec2:RequestSpotInstances\"\n    ],\n    s3_policies = [\n      \"s3:Get*\",\n      \"s3:List*\",\n      \"s3:Describe*\",\n      \"s3-object-lambda:Get*\",\n      \"s3-object-lambda:List*\"\n    ],\n    lambda_policies = [\n      \"lambda:Create*\",\n      \"lambda:List*\",\n      \"lambda:Delete*\",\n      \"lambda:Get*\"\n    ],\n    dynamodb_policies = [\n      \"dynamodb:Describe*\",\n      \"dynamodb:Update*\",\n      \"dynamodb:Get*\",\n      \"dynamodb:List*\",\n      \"dynamodb:BatchGetItem\",\n      \"dynamodb:Query\",\n      \"dynamodb:Scan\",\n      \"dynamodb:PartiQLSelect\"\n    ],\n  })\n}\n\noutput \"secret_key\" {\n  value = aws_iam_access_key.access_key.secret\n  sensitive = true\n}\n\noutput \"access_key\" {\n  value = aws_iam_access_key.access_key.id\n}\n``` \n\n**Code:**  https://github.com/omerbsezer/Fast-Terraform/blob/main/labs/template/main.tf\n\n![image](https://user-images.githubusercontent.com/10358317/230635156-50072817-9f9c-428a-906f-ebfe77e4f3ae.png)\n\n\n- Template file => Policy.tftpl:\n\n``` \n{\n    \"Version\": \"2012-10-17\",\n    \"Statement\": [\n        {\n            \"Effect\": \"Allow\",\n            \"Action\": ${jsonencode(ec2_policies)},\n            \"Resource\": \"*\"\n        },\n        {\n            \"Effect\": \"Allow\",\n            \"Action\": ${jsonencode(s3_policies)},\n            \"Resource\": \"*\"\n        },\n        {\n            \"Effect\": \"Allow\",\n            \"Action\": ${jsonencode(lambda_policies)},\n            \"Resource\": \"*\"\n        },\n         {\n            \"Effect\": \"Allow\",\n            \"Action\": ${jsonencode(dynamodb_policies)},\n            \"Resource\": \"*\"\n        }\n    ]\n}\n```\n\n**Code:**  https://github.com/omerbsezer/Fast-Terraform/blob/main/labs/template/policy.tftpl\n\n![image](https://user-images.githubusercontent.com/10358317/230635437-a2833841-b6be-4a2d-8c7b-a89c1d60c9ad.png)\n\n- Run init, validate command:\n\n``` \nterraform init\nterraform validate\n``` \n\n![image](https://user-images.githubusercontent.com/10358317/230635918-74679513-1e33-4348-9b82-5b7ee631d7e5.png)\n\n- Run plan, apply command:\n\n``` \nterraform plan   # for dry-run\nterraform apply\n``` \n\n![image](https://user-images.githubusercontent.com/10358317/230636213-a285546a-7f38-4c04-bdb7-81254be09654.png)\n\n![image](https://user-images.githubusercontent.com/10358317/230636709-d2f2115f-54f1-4e1c-9075-9e035f4ca15a.png)\n\n- On AWS IAM:\n\n![image](https://user-images.githubusercontent.com/10358317/230636965-74714983-435a-4009-a015-1117032c5815.png)\n\n![image](https://user-images.githubusercontent.com/10358317/230637038-235ad9fa-6f03-434b-a1df-15b38b218b19.png)\n\n\n- Run destroy command to delete user:\n\n``` \nterraform destroy\n``` \n\n![image](https://user-images.githubusercontent.com/10358317/230637447-5f1eb783-3a8f-45cc-afb6-522e27d74a9a.png)\n\n"
  },
  {
    "path": "LAB11-Backend-Remote-State.md",
    "content": "## LAB-11: Backend - Remote States => Provision EC2 and Save State File on S3\n\nThis scenario shows:\n- how to use backend and save Terraform state file on S3\n\n**Code:**  https://github.com/omerbsezer/Fast-Terraform/blob/main/labs/backend-remote-state/\n\n### Prerequisite\n\n- You should have a look following lab: \n  - [LAB-00: Terraform Install, AWS Configuration with Terraform](https://github.com/omerbsezer/Fast-Terraform/blob/main/LAB00-Terraform-Install-AWS-Configuration.md)\n\n## Steps\n\n- With enabling remote state file using backend:\n  - multiple user can work on the same state file\n  - saving common state file on S3 is possible\n\n- Create S3 bucket on AWS\n\n![image](https://user-images.githubusercontent.com/10358317/230646169-7b9a7210-bd64-4f50-acf7-12690d293490.png)\n\n![image](https://user-images.githubusercontent.com/10358317/230646417-8c460ba7-e45b-4560-8859-d1ebfcac4812.png)\n\n\n- Create basic main.tf file.\n\n\n```\n# main.tf\nterraform {\n  required_providers {\n    aws = {\n      source  = \"hashicorp/aws\"\n      version = \"~> 4.16\"\n    }\n  }\n\n  required_version = \">= 1.2.0\"\n\n  backend \"s3\" {\n    bucket = \"terraform-state\"\n    key = \"key/terraform.tfstate\"\n    region = \"eu-central-1\"\n  }\n}\n\nprovider \"aws\" {\n   region = \"eu-central-1\"\n}\n\nresource \"aws_instance\" \"instance\" {\n   ami           = \"ami-0d1ddd83282187d18\" # Ubuntu 22.04 eu-central-1 Frankfurt\n   instance_type = \"t2.nano\"\n\n   tags = {\n      Name = \"Basic Instance\"\n   }\n}\n```\n\n**Code:**  https://github.com/omerbsezer/Fast-Terraform/blob/main/labs/backend-remote-state/main.tf\n\n![image](https://user-images.githubusercontent.com/10358317/230646618-f1200c13-eb83-4bcd-b353-a6c9a02272bd.png)\n\n\n- Run init, validate command:\n\n``` \nterraform init\nterraform validate\n``` \n\n![image](https://user-images.githubusercontent.com/10358317/230646686-0b8ad133-d2e4-4ebf-8505-00eb769b1e5a.png)\n\n- Run plan, apply command:\n\n``` \nterraform plan   # for dry-run\nterraform apply\n``` \n\n- On AWS S3, tfstate file is created:\n\n![image](https://user-images.githubusercontent.com/10358317/230647235-3224ec77-2483-460c-81c6-40e9e434f869.png)\n\n- On local machine, state file is not saved now:\n\n![image](https://user-images.githubusercontent.com/10358317/230647627-b5038f51-b34f-443c-b72a-d9c140d3d770.png)\n\n- On AWS, state file can be viewed, downloaded:\n\n![image](https://user-images.githubusercontent.com/10358317/230647970-97d72d67-a588-40ff-a94f-3ea765dfe274.png)\n\n- With pull command, state file can be download on local machine:\n\n``` \nterraform state pull > terraform.tfstate\n``` \n\n![image](https://user-images.githubusercontent.com/10358317/230648330-d89d0b53-617b-4449-a2cb-b92b163cbfdd.png)\n\n\n- Run destroy command:\n\n``` \nterraform destroy\n``` \n\n- After destroy command,  all resources are deleted in state file on S3:\n\n![image](https://user-images.githubusercontent.com/10358317/230649315-7cb1d236-145b-49ed-ad3f-60aaa01d7ca0.png)\n\n- To download updated state file:\n\n``` \nterraform state pull > terraform.tfstate\n``` \n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2023 Ömer Berat Sezer\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# Fast-Terraform (with AWS)\nThis repo covers Terraform with Hands-on LABs and Samples using AWS (comprehensive, but simple): \n- Resources, Data Sources, Variables, Meta Arguments, Provisioners, Dynamic Blocks, Modules, Workspaces, Templates, Remote State.\n- Provisioning AWS Components (EC2, EBS, EFS, IAM Roles, IAM Policies, Key-Pairs, VPC with Network Components, Lambda, ECR, ECS with Fargate, EKS with Managed Nodes, ASG, ELB, API Gateway, S3, CloudFront CodeCommit, CodePipeline, CodeBuild, CodeDeploy), use cases and details. Possible usage scenarios are aimed to update over time.\n\nWhy was this repo created?\n- **Shows Terraform details in short with simple, clean demos and Hands-on LABs**\n- **Shows Terraform AWS Hands-on Samples, Use Cases**\n\n**Keywords:** Terraform, Infrastructure as Code, AWS, Cloud Provisioning\n\n# Quick Look (How-To): Terraform Hands-on LABs\nThese LABs focus on Terraform features, help to learn Terraform:\n\n- [LAB-00: Installing Terraform, AWS Configuration with Terraform](https://github.com/omerbsezer/Fast-Terraform/blob/main/LAB00-Terraform-Install-AWS-Configuration.md)\n- [LAB-01: Terraform Docker => Pull Docker Image, Create Docker Container on Local Machine](https://github.com/omerbsezer/Fast-Terraform/blob/main/LAB01-Terraform-Docker-Without-Cloud.md)\n- [LAB-02: Resources => Provision Basic EC2 (Ubuntu 22.04)](https://github.com/omerbsezer/Fast-Terraform/blob/main/LAB02-Resources-Basic-EC2.md)\n- [LAB-03: Variables, Locals, Output => Provision EC2s](https://github.com/omerbsezer/Fast-Terraform/blob/main/LAB03-Variables-Locals-Output-EC2.md)\n- [LAB-04: Meta Arguments (Count, For_Each, Map) => Provision IAM Users, Groups, Policies, Attachment Policy-User](https://github.com/omerbsezer/Fast-Terraform/blob/main/LAB04-Meta-Arguments-IAM-User-Group-Policy.md)\n- [LAB-05: Dynamic Blocks => Provision Security Groups, EC2, VPC](https://github.com/omerbsezer/Fast-Terraform/blob/main/LAB05-Dynamic-Blocks-Security-Groups-EC2.md)\n- [LAB-06: Data Sources with Depends_on => Provision EC2](https://github.com/omerbsezer/Fast-Terraform/blob/main/LAB06-Data-Sources-EC2.md)\n- [LAB-07: Provisioners (file, remote-exec), Null Resources (local-exec) => Provision Key-Pair, SSH Connection](https://github.com/omerbsezer/Fast-Terraform/blob/main/LAB07-Provisioners-Null-Resources.md)\n- [LAB-08: Modules => Provision EC2](https://github.com/omerbsezer/Fast-Terraform/blob/main/LAB08-Modules-EC2.md)\n- [LAB-09: Workspaces => Provision EC2 with Different tfvars Files](https://github.com/omerbsezer/Fast-Terraform/blob/main/LAB09-Workspaces-EC2.md)\n- [LAB-10: Templates => Provision IAM User, User Access Key, Policy](https://github.com/omerbsezer/Fast-Terraform/blob/main/LAB10-Templates-User-Policy.md)\n- [LAB-11: Backend - Remote States => Provision EC2 and Save State File on S3](https://github.com/omerbsezer/Fast-Terraform/blob/main/LAB11-Backend-Remote-State.md)\n- [Terraform Cheatsheet](https://github.com/omerbsezer/Fast-Terraform/blob/main/Terraform-Cheatsheet.md)\n\n# Quick Look (How-To): AWS Terraform Hands-on Samples\nThese samples focus on how to create and use AWS components (EC2, EBS, EFS, IAM Roles, IAM Policies, Key-Pairs, VPC with Network Components, Lambda, ECR, ECS with Fargate, EKS with Managed Nodes, ASG, ELB, API Gateway, S3, CloudFront, CodeCommit, CodePipeline, CodeBuild, CodeDeploy) with Terraform:\n\n- [SAMPLE-01: Provisioning EC2s (Windows 2019 Server, Ubuntu 20.04) on VPC (Subnet), Creating Key-Pair, Connecting Ubuntu using SSH, and Connecting Windows Using RDP](https://github.com/omerbsezer/Fast-Terraform/blob/main/SAMPLE01-EC2-VPC-Ubuntu-Win-SSH-RDP.md)\n- [SAMPLE-02: Provisioning Lambda Function, API Gateway and Reaching HTML Page in Python Code From Browser](https://github.com/omerbsezer/Fast-Terraform/blob/main/SAMPLE02-Lambda-API-Gateway-Python.md)\n- [SAMPLE-03: EBS (Elastic Block Storage: HDD, SDD) and EFS (Elastic File System: NFS) Configuration with EC2s (Ubuntu and Windows Instances)](https://github.com/omerbsezer/Fast-Terraform/blob/main/SAMPLE03-EC2-EBS-EFS.md)\n- [SAMPLE-04: Provisioning ECR (Elastic Container Repository), Pushing Image to ECR, Provisioning ECS (Elastic Container Service), VPC (Virtual Private Cloud), ELB (Elastic Load Balancer), ECS Tasks and Service on Fargate Cluster](https://github.com/omerbsezer/Fast-Terraform/blob/main/SAMPLE04-ECR-ECS-ELB-VPC-ECS-Service.md)\n- [SAMPLE-05: Provisioning ECR, Lambda Function and API Gateway to run Flask App Container on Lambda](https://github.com/omerbsezer/Fast-Terraform/blob/main/SAMPLE05-Lambda-Container-ApiGateway-FlaskApp.md)\n- [SAMPLE-06: Provisioning EKS (Elastic Kubernetes Service) with Managed Nodes using Blueprint and Modules](https://github.com/omerbsezer/Fast-Terraform/blob/main/SAMPLE06-EKS-ManagedNodes-Blueprint.md)\n- [SAMPLE-07: CI/CD on AWS => Provisioning CodeCommit and CodePipeline, Triggering CodeBuild and CodeDeploy, Running on Lambda Container](https://github.com/omerbsezer/Fast-Terraform/blob/main/SAMPLE07-CodeCommit-Pipeline-Build-Deploy-Lambda.md)\n- [SAMPLE-08: Provisioning S3 and CloudFront to serve Static Web Site](https://github.com/omerbsezer/Fast-Terraform/blob/main/SAMPLE08-S3-CloudFront-Static-WebSite.md)\n- [SAMPLE-09: Running Gitlab Server using Docker on Local Machine and Making Connection to Provisioned Gitlab Runner on EC2 in Home Internet without Using VPN](https://github.com/omerbsezer/Fast-Terraform/blob/main/SAMPLE09-GitlabServer-on-Premise-GitlabRunner-on-EC2.md)\n\n\n# Table of Contents\n- [Motivation](#motivation)\n- [What is Terraform?](#what_is_terraform)\n- [How Terraform Works?](#how_terrafom_works)\n- [Terraform File Components](#terrafom_file_components)\n  - [Providers](#providers)\n  - [Resources](#resources)\n  - [Variables (tfvar)](#variables)\n  - [Values (Locals, Outputs)](#values)\n  - [Meta Arguments](#meta_arguments)\n  - [Dynamic Blocks](#dynamic_blocks)\n  - [Data Sources](#datasources)\n  - [Provisioners (file, remote_exec, local_exec), Null Resource](#provisioners)\n  - [Modules](#modules)\n  - [Workspaces](#workspaces)\n  - [Templates](#templates)\n  - [Backends and Remote States](#backends_remote_states)\n- [Terraform Best Practices](#best_practice)\n- [AWS Terraform Hands-on Samples](#samples)\n  - [SAMPLE-01: EC2s (Windows 2019 Server, Ubuntu 20.04), VPC, Key-Pairs for SSH, RDP connections](#ec2_vpc_key_pair_ssh_rdp)\n  - [SAMPLE-02: Provisioning Lambda Function, API Gateway and Reaching HTML Page in Python Code From Browsers](#lambda_apigateway_python)\n  - [SAMPLE-03: EBS (Elastic Block Storage: HDD, SDD) and EFS (Elastic File System: NFS) Configuration with EC2s (Ubuntu and Windows Instances)](#ebs_efs_ec2)\n  - [SAMPLE-04: Provisioning ECR (Elastic Container Repository), Pushing Image to ECR, Provisioning ECS (Elastic Container Service), VPC (Virtual Private Cloud), ELB (Elastic Load Balancer), ECS Tasks and Service on Fargate Cluster](#ecr_ecs_elb_vpc_ecs_service_fargate)\n  - [SAMPLE-05: Provisioning ECR, Lambda Function and API Gateway to run Flask App Container on Lambda](#ecr_lambda_apigateway_container)\n  - [SAMPLE-06: Provisioning EKS (Elastic Kubernetes Service) with Managed Nodes using Blueprint and Modules](#eks_managednodes_blueprint)\n  - [SAMPLE-07: CI/CD on AWS => Provisioning CodeCommit and CodePipeline, Triggering CodeBuild and CodeDeploy, Running on Lambda Container](#ci_cd)\n  - [SAMPLE-08: Provisioning S3 and CloudFront to serve Static Web Site](#s3_cloudfront)\n  - [SAMPLE-09: Running Gitlab Server using Docker on Local Machine and Making Connection to Provisioned Gitlab Runner on EC2 in Home Internet without Using VPN](#gitlabrunner)\n- [Details](#details)\n- [Terraform Cheatsheet](#cheatsheet)\n- [Other Useful Resources Related Terraform](#resource)\n- [References](#references)\n\n## Motivation <a name=\"motivation\"></a>\nWhy should we use / learn Terraform?\n- Terraform is cloud-agnostic and popular tool to create/provision Cloud Infrastructure resources/objects (e.g. Virtual Private Cloud, Virtual Machines, Lambda, etc.)\n  - Manage any infrastructure\n  - Similar to Native Infrastructure as Code (IaC): CloudFormation (AWS), Resource Manager (Azure), Google Cloud Deployment Manager (Google Cloud) \n- It is free, open source (https://github.com/hashicorp/terraform) and has a large community with enterprise support options.\n- Commands, tasks, codes turn into the IaC.\n  - With IaC, tasks is savable, versionable, repetable and testable.\n  - With IaC, desired configuration is defined as 'Declerative Way'.\n- **Agentless:** Terraform doesn’t require any software to be installed on the managed infrastructure\n- It has well-designed documentation:\n  - https://developer.hashicorp.com/terraform/language\n  - https://registry.terraform.io/providers/hashicorp/aws/latest/docs\n- Terraform uses a modular structure.\n- Terraform tracks your infrastructure with TF state file.\n  ![image](https://user-images.githubusercontent.com/10358317/231144158-63009879-4687-492e-8f6a-5e233dab3f28.png)(ref: Redis)\n\n## What is Terraform? <a name=\"what_is_terraform\"></a>\n- Terraform is cloud-independent provisioning tool to create Cloud infrastructure. \n- Creating infrastructure code with HCL (Hashicorp Language) that is similar to YAML, JSON, Python.\n- Terraform Basic Tutorial for AWS: \n  - https://developer.hashicorp.com/terraform/tutorials/aws-get-started\n- Reference and Details: \n  - https://developer.hashicorp.com/terraform/intro\n  ![image](https://user-images.githubusercontent.com/10358317/231143883-a2348511-dd12-4e0f-806d-3144ac88aa4d.png)(ref: Terraform)\n\n## How Terraform Works? <a name=\"how_terrafom_works\"></a>\n- Terraform works with different providers (AWS, Google CLoud, Azure, Docker, K8s, etc.)\n- After creating Terraform Files (tf), terraform commands:\n  - **init**: downloads the required executable apps dependent on providers.\n  - **validate**: confirms the tf files.\n  - **plan**: dry-run for the infrastructure, not actually running/provisioning the infrastructure\n  - **apply**: runs/provisions the infrastructure\n  - **destroy**: deletes the infrastructure\n\n- Main Commands:\n```\nterraform init\nterraform validate\nterraform plan            # ask for confirmation (yes/no), after running command\nterraform apply           # ask for confirmation (yes/no), after running command\nterraform destroy         # ask for confirmation (yes/no), after running command\n```\n\n- Command Variants:\n```\nterraform plan --var-file=\"terraform-dev.tfvars\"            # specific variable files\nterraform apply -auto-approve                               # no ask for confirmation\nterraform apply --var-file=\"terraform-prod.tfvars\"          # specific variable files\nterraform destroy --var-file=\"terraform-prod.tfvars\"        # specific variable files\n```\n- Terraform Command Structure:\n\n  ![image](https://user-images.githubusercontent.com/10358317/234230001-67475a51-d894-4234-8917-07d14355b205.png)\n\n- Terraform Workflow:\n\n  ![image](https://user-images.githubusercontent.com/10358317/231147788-ba40b795-4050-49df-b1ad-48b273257410.png)\n\n- TF state file stores the latest status of the infrastructure after running \"apply\" command.\n- TF state file deletes the status of the infrastructure after running \"destroy\" command.\n- TF state files are stored:\n  - on local PC \n  - on remote cloud (AWS S3, Terraform Cloud) \n\n- Please have a look LABs and SAMPLEs to learn how Terraform works in real scenarios.\n \n## Terraform File Components <a name=\"terrafom_file_components\"></a>\n- Terraform file has different components to define infrastructure for different purposes. \n  - Providers,\n  - Resources,\n  - Variables,\n  - Values (locals, outputs),\n  - Meta Argurments (for, for_each, map, depends_on, life_cycle),\n  - Dynamic Blocks,\n  - Data Sources,\n  - Provisioners,\n  - Workspaces,\n  - Modules,\n  - Templates.\n\n### Providers <a name=\"providers\"></a>\n- Terraform supposes for different providers (AWS, Google Cloud, Azure).\n- Terraform downloads required executable files from own cloud to run IaC (code) for the corresponding providers.\n- AWS (https://registry.terraform.io/providers/hashicorp/aws/latest/docs): \n\n  ![image](https://user-images.githubusercontent.com/10358317/231405120-1d6907be-53f6-46e8-8e6f-a5dd73a0cfb5.png)\n\n- Google Cloud (GCP) (https://registry.terraform.io/providers/hashicorp/google/latest/docs):\n\n  ![image](https://user-images.githubusercontent.com/10358317/231405236-73faf1e4-3ea8-45df-982e-d56f64eba2a5.png)\n\n- Azure (https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs):\n\n  ![image](https://user-images.githubusercontent.com/10358317/231405457-7b90a689-96c6-434d-a319-162adc04f772.png)\n  \n - Docker (https://registry.terraform.io/providers/kreuzwerker/docker/latest/docs/resources/container):\n   \n   ![image](https://user-images.githubusercontent.com/10358317/231437580-0dc3ce8f-bbbe-4b4e-97b7-6598e85cb59e.png)\n\n### Resources <a name=\"resources\"></a>\n- Resources are used to define for different cloud components and objects (e.g. EC2 instances, VPC, VPC Compoenents: Router Tables, Subnets, IGW, .., Lambda, API Gateway, S3 Buckets, etc.). \n- To learn the details, features of the cloud components, you should know how the cloud works, which components cloud have, how to configure the cloud components.\n- Syntax:\n  - **resource <AWS_Object> <User_Defined_Variable_Name_With_Underscore> {}**\n    - e.g. resource \"aws_instance\" \"instance\" {}\n    - e.g. resource \"aws_vpc\" \"my_vpc\" {}\n    - e.g. resource \"aws_subnet\" \"public\" {}\n    - e.g. resource \"aws_security_group\" \"allow_ssh\" {}\n  \n    ![image](https://user-images.githubusercontent.com/10358317/231420818-d0c3e679-787b-4d85-a784-6f4acdb7fa01.png)\n  \n- Important part is to check the usage of the resources (shows which arguments are optional, or required) from Terraform Registry page by searching the \"Object\" terms like \"instance\", \"vpc\", \"security groups\"\n  - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance\n  \n  ![image](https://user-images.githubusercontent.com/10358317/231423197-71c23a76-a55e-4cf0-bb51-d81e45b30ff1.png)\n\n- There are different parts:\n  - **Argument References (inputs)** (some parts are optional, or required)\n  - **Attributes References (outputs)**\n  - **Example code snippet** to show how it uses\n  - **Others** (e.g. timeouts, imports)\n\n- Go to LAB to learn resources:\n  - [LAB-02: Resources => Provision Basic EC2 (Ubuntu 22.04)](https://github.com/omerbsezer/Fast-Terraform/blob/main/LAB02-Resources-Basic-EC2.md)\n\n### Variables (tfvar) <a name=\"variables\"></a>\n- Variables help to avoid hard coding on the infrastructure code. \n- The Terraform language uses the following types for its values:\n  - **string:** a sequence of Unicode characters representing some text, like \"hello\".\n  - **number:** a numeric value. The number type can represent both whole numbers like 15 and fractional values like 6.283185.\n  - **bool:** a boolean value, either true or false. bool values can be used in conditional logic.\n  - **list (or tuple):** a sequence of values, like [\"one\", \"two\"]. Elements in a list or tuple are identified by consecutive whole numbers, starting with zero.\n  - **map (or object):** a group of values identified by named labels, like {name = \"Mabel\", age = 52}.\n  - Strings, numbers, and bools are sometimes called primitive types. Lists/tuples and maps/objects are sometimes called complex types, structural types, or collection types.\n- Normally, if you define variables, after running \"terraform apply\" command, on the terminal, stdout requests from the user to enter variables.\n- But, if the \"tfvar\" file is defined, variables in the \"tfvar\" file are entered automatically in the corresponding variable fields.  \n\n  ![image](https://user-images.githubusercontent.com/10358317/231144889-3edd38a4-1ff9-4c82-8155-50f0089757fa.png)\n\n- Tfvar files for development (\"DEV\") environment: \n \n  ![image](https://user-images.githubusercontent.com/10358317/231437129-29191b28-368d-4fe5-8b99-abae9986e424.png)\n\n- Tfvar files for production (\"PROD\") environment: \n\n  ![image](https://user-images.githubusercontent.com/10358317/231145166-f032ae1e-9bbb-436a-9c0e-3c0be8fb627c.png)\n\n- Go to LAB to learn variables and tfvar file, and provisioning EC2 for different environments:\n  - [LAB-03: Variables, Locals, Output => Provision EC2s](https://github.com/omerbsezer/Fast-Terraform/blob/main/LAB03-Variables-Locals-Output-EC2.md)\n\n### Values (Locals, Outputs) <a name=\"values\"></a>\n- \"Locals\" are also the variables that are mostly used as place-holder variables.\n\n  ![image](https://user-images.githubusercontent.com/10358317/231438120-8c6f0cb4-ea56-457f-8532-7bc2ee4bc39b.png)\n\n- \"Outputs\" are used to put the cloud objects' information (e.g. public IP, DNS, detailed info) out as stdout.  \n\n  ![image](https://user-images.githubusercontent.com/10358317/231438718-880861bb-900d-49e2-b642-eafe0437a457.png)\n  \n- \"Outputs\" after running \"terraform apply\" command on the terminal stdout:\n\n  ![image](https://user-images.githubusercontent.com/10358317/231439218-d8f19bdb-ed5c-48b0-ad49-1f48fbb649f8.png)\n\n- Go to LAB to learn more about variables, locals, outputs and provisioning EC2:\n  - [LAB-03: Variables, Locals, Output => Provision EC2s](https://github.com/omerbsezer/Fast-Terraform/blob/main/LAB03-Variables-Locals-Output-EC2.md)\n\n### Meta Arguments <a name=\"meta_arguments\"></a>\n- Different meta arguments are used for different purposes:\n  - **count:** the number of objects (e.g. variables, resources, etc.)\n    - https://developer.hashicorp.com/terraform/language/meta-arguments/count \n  - **for:** iteration over the list of objects (e.g. variables, resources, etc.)\n  - **for_each:** iteration over the set of objects (e.g. variables, resources, etc.)  \n    - https://developer.hashicorp.com/terraform/language/meta-arguments/for_each\n  - **depends_on:** shows the priority order of creation of the resource. If \"A\" should be created before \"B\", user should write \"depends_on= A\" as an argument under \"B\". \n    - https://developer.hashicorp.com/terraform/language/meta-arguments/depends_on \n  - **life_cycle:** uses to make life cycle relationship between objects (e.g. variables, resources, etc.)\n    - https://developer.hashicorp.com/terraform/language/meta-arguments/lifecycle \n  - **providers:** specifies which provider configuration to use for a resource, overriding Terraform's default behavior.\n    - https://developer.hashicorp.com/terraform/language/meta-arguments/resource-provider\n\n- Count:  \n\n  ![image](https://user-images.githubusercontent.com/10358317/231446996-da7cfb44-3c6a-43a2-ab89-8dd93a8318a5.png)\n\n- For_each, For:\n\n  ![image](https://user-images.githubusercontent.com/10358317/231447409-b09e98e5-4ce8-4d7d-83e0-60edc6c9b88e.png)\n\n- Go to LAB to learn:\n  - [LAB-04: Meta Arguments (Count, For_Each, Map) => Provision IAM Users, Groups, Policies, Attachment Policy-User](https://github.com/omerbsezer/Fast-Terraform/blob/main/LAB04-Meta-Arguments-IAM-User-Group-Policy.md)\n\n### Dynamic Blocks <a name=\"dynamic_blocks\"></a>\n- \"Dynamic blocks\" creates small code template that reduces the code repetition.\n- In the example below, it isn't needed to create parameters (description, from_port, to_port, protocol, cidr_blocks) for each ingress ports:\n\n  ![image](https://user-images.githubusercontent.com/10358317/231145371-c9322d06-326d-44f7-95e2-e9ec6f806bfe.png)\n\n- Go to LAB to learn:\n  - [LAB-05: Dynamic Blocks => Provision Security Groups, EC2, VPC](https://github.com/omerbsezer/Fast-Terraform/blob/main/LAB05-Dynamic-Blocks-Security-Groups-EC2.md)\n\n### Data Sources <a name=\"datasources\"></a>\n- \"Data Sources\" helps to retrieve/fetch/get data/information from previously created/existed cloud objects/resources.\n\n- In the example below:\n  - \"filter\" keyword is used to select/filter the existed objects (reources, instances, etc.)\n  - \"depends_on\" keyword provides to run the data block after resource created.\n  \n  ![image](https://user-images.githubusercontent.com/10358317/231145418-c333d2df-706f-4325-8eb2-5d677fa30ce5.png)\n\n- Go to LAB to learn:\n  - [LAB-06: Data Sources with Depends_on => Provision EC2](https://github.com/omerbsezer/Fast-Terraform/blob/main/LAB06-Data-Sources-EC2.md)\n\n### Provisioners <a name=\"provisioners\"></a>\n- \"Provisioners\" provides to run any commands on the remote instance/virtual machine, or on the local machine.\n- \"Provisioners\" in the resource block runs only once while creating the resource on remote instance. If the resource is created/provisioned before, \"provisioner\" block in the resource block doesn't run again.\n- With \"null_resource\":\n  - Without creating any resource, \n  - Without depending any resource, \n  - Any commands can be run.\n- Provisioners in the \"null_resource\" run multiple times and it doesn't depend on the resource.  \n- With provisioner \"file\", on the remote instance, new file can be created\n- With provisioner \"remote-exec\", on the remote instance, any command can be run\n- With provisioner \"local-exec\", on the local PC, any command can be run on any shell (bash, powershell)\n\n  ![image](https://user-images.githubusercontent.com/10358317/231145525-4f97c4a1-dc6f-4323-a8ca-7041c27d00d9.png)\n\n- Go to LAB to learn about different provisioners:\n  - [LAB-07: Provisioners (file, remote-exec), Null Resources (local-exec) => Provision Key-Pair, SSH Connection](https://github.com/omerbsezer/Fast-Terraform/blob/main/LAB07-Provisioners-Null-Resources.md)\n\n### Modules <a name=\"modules\"></a>\n- \"Modules\" helps organize configuration, encapsulation, re-usability and consistency.\n- \"Modules\" is the structure/container for multiple resources that are used together.  \n- Each modules usually have variables.tf that is configured from the parent tf file.\n- Details: https://developer.hashicorp.com/terraform/language/modules\n- AWS modules for different components (VPC, IAM, SG, EKS, S3, Lambda, RDS, etc.) \n  - https://registry.terraform.io/browse/modules?provider=aws\n\n    ![image](https://user-images.githubusercontent.com/10358317/231145600-59034277-0781-4285-9fa8-987a1c7f6e27.png)\n\n- Go to LAB to learn:\n  - [LAB-08: Modules => Provision EC2](https://github.com/omerbsezer/Fast-Terraform/blob/main/LAB08-Modules-EC2.md)\n\n### Workspaces <a name=\"workspaces\"></a>\n- With \"Workspaces\":\n  - a parallel, distinct copy of your infrastructure which you can test and verify in the development, test, and staging, \n  - like git, you are working on different workspaces (like branch),\n  - single code but different workspaces,\n  - it creates multiple state files on different workspace directories.\n  \n- Workspace commands:\n\n``` \nterraform workspace help                       # help for workspace commands\nterraform workspace new [WorkspaceName]        # create new workspace\nterraform workspace select [WorkspaceName]     # change/select another workspace\nterraform workspace show                       # show current workspace\nterraform workspace list                       # list all workspaces\nterraform workspace delete [WorkspaceName]     # delete existed workspace\n``` \n- \"dev\" and \"prod\" workspaces are created:\n  \n  ![image](https://user-images.githubusercontent.com/10358317/231145703-c35b657c-7e39-4d53-980f-4561fda9489d.png)\n\n- Go to LAB to learn:\n  - [LAB-09: Workspaces => Provision EC2 with Different tfvars Files](https://github.com/omerbsezer/Fast-Terraform/blob/main/LAB09-Workspaces-EC2.md)\n\n### Templates <a name=\"templates\"></a>\n- With \"Templates\" (.tftpl files):\n  - avoid to write same code snippets multiple times,\n  - provide to shorten the code\n\n- In the example below, templates fields are filled with list in the resource code block:\n\n  ![image](https://user-images.githubusercontent.com/10358317/231479114-e7cf013a-4b83-4288-b581-c180bbee7eee.png)\n\n- Go to LAB to learn \"Templates\":\n  - [LAB-10: Templates => Provision IAM User, User Access Key, Policy](https://github.com/omerbsezer/Fast-Terraform/blob/main/LAB10-Templates-User-Policy.md)\n\n### Backend and Remote States <a name=\"backends_remote_states\"></a>\n- With enabling remote state file using backend:\n  - multiple user can work on the same state file\n  - saving common state file on S3 is possible\n\n- With backend part (\"s3\"), state file is stored on S3:\n\n  ![image](https://user-images.githubusercontent.com/10358317/231481348-2b0a35aa-f2a6-4335-87fb-fe6df31f9e73.png)\n\n- On AWS S3 Bucket, terraform.tfstate file is saved:\n\n  ![image](https://user-images.githubusercontent.com/10358317/231145912-908af9fe-56ef-479e-8ee4-9c5f7f92329e.png)\n\n- Go to LAB to learn:\n  - [LAB-11: Backend - Remote States => Provision EC2 and Save State File on S3](https://github.com/omerbsezer/Fast-Terraform/blob/main/LAB11-Backend-Remote-State.md)\n\n## Terraform Best Practices <a name=\"best_practice\"></a>\n\n- Don't change/edit anything on state file manually. Manipulate state file only through TF commands (e.g. terraform apply, terraform state). \n- Use remote state file to share the file with other users. Keep state file on the Cloud (S3, Terraform Cloud, etc.)\n- To prevent concurrent changes, state locking is important. Hence concurrent change from multiple user can be avoided. \n  - S3 supports state locking and consistency via DynamoDB.\n- Backing up state file is also important to save the status. S3 enables versioning. Versioning state file can provide you backing up the state file.\n- If you use multiple environment (dev, test, staging, production), use 1 state file per environment. Terraform workspace provide multiple state files for different environments.\n- Use Git repositories (Github, Gitlab) to host TF codes to share other users.\n- Behave your Infrastructure code as like your application code. Create CI pipeline/process for your TF Code (review tf code, run automated tests). This will shift your infrastructure code high quality.\n- Execute Terraform only in an automated build, CD pipeline/process. This helps to run code automatically and run from one/single place. \n- For naming conventions: https://www.terraform-best-practices.com/naming \n\n## AWS Terraform Hands-on Samples <a name=\"samples\"></a>\n\n### SAMPLE-01: EC2s (Windows 2019 Server, Ubuntu 20.04), VPC, Key-Pairs for SSH, RDP connections <a name=\"ec2_vpc_key_pair_ssh_rdp\"></a>\n- This sample shows:\n  - how to create Key-pairs (public and private keys) on AWS,\n  - how to create EC2s (Ubuntu 20.04, Windows 2019 Server),\n  - how to create Virtual Private Cloud (VPC), VPC Components (Public Subnet, Internet Gateway, Route Table) and link to each others,\n  - how to create Security Groups (for SSH and Remote Desktop).\n- **Code:** https://github.com/omerbsezer/Fast-Terraform/tree/main/samples/ec2-vpc-ubuntu-win-ssh-rdp\n- **Go to the Hands-On Sample:**\n  - [SAMPLE-01: Provisioning EC2s (Windows 2019 Server, Ubuntu 20.04) on VPC (Subnet), Creating Key-Pair, Connecting Ubuntu using SSH, and Connecting Windows Using RDP](https://github.com/omerbsezer/Fast-Terraform/blob/main/SAMPLE01-EC2-VPC-Ubuntu-Win-SSH-RDP.md)\n  \n  ![image](https://user-images.githubusercontent.com/10358317/233837033-01c37232-75f8-4815-a5d6-e3f73139963e.png)\n  \n  \n### SAMPLE-02:  Provisioning Lambda Function, API Gateway and Reaching HTML Page in Python Code From Browsers <a name=\"lambda_apigateway_python\"></a>\n- This sample shows:\n  - how to create Lambda function with Python code,\n  - how to create lambda role, policy, policy-role attachment, lambda api gateway permission, zipping code,\n  - how to create api-gateway resource and method definition, lambda - api gateway connection, deploying api gateway, api-gateway deployment URL as output\n  - details on AWS Lambda, API-Gateway, IAM.\n- **Code:** https://github.com/omerbsezer/Fast-Terraform/tree/main/samples/lambda-role-policy-apigateway-python\n- **Go to the Hands-On Sample:**\n  - [SAMPLE-02: Provisioning Lambda Function, API Gateway and Reaching HTML Page in Python Code From Browser](https://github.com/omerbsezer/Fast-Terraform/blob/main/SAMPLE02-Lambda-API-Gateway-Python.md)\n  \n  ![image](https://user-images.githubusercontent.com/10358317/233837058-7909658d-b06d-49e3-8f81-d56ccf295609.png)\n\n### SAMPLE-03: EBS (Elastic Block Storage: HDD, SDD) and EFS (Elastic File System: NFS) Configuration with EC2s (Ubuntu and Windows Instances) <a name=\"ebs_efs_ec2\"></a>\n- This sample shows:\n  - how to create EBS, mount on Ubuntu and Windows Instances,\n  - how to create EFS, mount on Ubuntu Instance,\n  - how to provision VPC, subnet, IGW, route table, security group.\n- **Code:** https://github.com/omerbsezer/Fast-Terraform/tree/main/samples/ec2-ebs-efs\n- **Go to the Hands-On Sample:**\n  - [SAMPLE-03: EBS (Elastic Block Storage: HDD, SDD) and EFS (Elastic File System: NFS) Configuration with EC2s (Ubuntu and Windows Instances)](https://github.com/omerbsezer/Fast-Terraform/blob/main/SAMPLE03-EC2-EBS-EFS.md)\n  \n  ![image](https://user-images.githubusercontent.com/10358317/230903321-5bca3385-9564-44f1-bde8-fe1c873c870a.png)\n  \n### SAMPLE-04: Provisioning ECR (Elastic Container Repository), Pushing Image to ECR, Provisioning ECS (Elastic Container Service), VPC (Virtual Private Cloud), ELB (Elastic Load Balancer), ECS Tasks and Service on Fargate Cluster <a name=\"ecr_ecs_elb_vpc_ecs_service_fargate\"></a>  \n- This sample shows:\n  - how to create Flask-app Docker image,\n  - how to provision ECR and push to image to this ECR,\n  - how to provision VPC, Internet Gateway, Route Table, 3 Public Subnets,\n  - how to provision ALB (Application Load Balancer), Listener, Target Group,\n  - how to provision ECS Fargate Cluster, Task and Service (running container as Service).\n- **Code:** https://github.com/omerbsezer/Fast-Terraform/tree/main/samples/ecr-ecs-elb-vpc-ecsservice-container \n- **Go to the Hands-On Sample:**\n  - [SAMPLE-04: Provisioning ECR (Elastic Container Repository), Pushing Image to ECR, Provisioning ECS (Elastic Container Service), VPC (Virtual Private Cloud), ELB (Elastic Load Balancer), ECS Tasks and Service on Fargate Cluster](https://github.com/omerbsezer/Fast-Terraform/blob/main/SAMPLE04-ECR-ECS-ELB-VPC-ECS-Service.md)\n  \n  ![ecr-ecs](https://user-images.githubusercontent.com/10358317/232244927-7d819c66-328a-4dd5-b3e1-18b2c7fd92aa.png)\n  \n ### SAMPLE-05: Provisioning ECR, Lambda Function and API Gateway to run Flask App Container on Lambda <a name=\"ecr_lambda_apigateway_container\"></a>  \n- This sample shows:\n  - how to create Flask-app-serverless image to run on Lambda,\n  - how to create ECR and to push image to ECR,\n  - how to create Lambda function, Lambda role, policy, policy-role attachment, Lambda API Gateway permission,\n  - how to create API Gateway resource and method definition, Lambda - API Gateway connection, deploying API Gateway.\n- **Code:** https://github.com/omerbsezer/Fast-Terraform/tree/main/samples/lambda-container-apigateway-flaskapp\n- **Go to the Hands-On Sample:**\n  - [SAMPLE-05: Provisioning ECR, Lambda Function and API Gateway to run Flask App Container on Lambda](https://github.com/omerbsezer/Fast-Terraform/blob/main/SAMPLE05-Lambda-Container-ApiGateway-FlaskApp.md)  \n\n  ![image](https://user-images.githubusercontent.com/10358317/233119966-9800d18c-8d0c-40de-9c1d-d14726743e5a.png)\n  \n  ![image](https://user-images.githubusercontent.com/10358317/233121075-ab2ac298-71b2-467d-8068-834f16b0f3c7.png)\n\n### SAMPLE-06: Provisioning EKS (Elastic Kubernetes Service) with Managed Nodes using Blueprint and Modules <a name=\"eks_managednodes_blueprint\"></a>  \n\n- This sample shows:\n  - how to create EKS cluster with managed nodes using BluePrints and Modules.\n  - EKS Blueprint is used to provision EKS cluster with managed nodes easily. \n  - EKS Blueprint is used from: \n    - https://github.com/aws-ia/terraform-aws-eks-blueprints\n- **Code:** https://github.com/omerbsezer/Fast-Terraform/tree/main/samples/eks-managed-node-blueprint\n- **Go to the Hands-On Sample:** \n  - [SAMPLE-06: Provisioning EKS (Elastic Kubernetes Service) with Managed Nodes using Blueprint and Modules](https://github.com/omerbsezer/Fast-Terraform/blob/main/SAMPLE06-EKS-ManagedNodes-Blueprint.md)\n\n  ![image](https://user-images.githubusercontent.com/10358317/233836920-20d2b13b-7cb2-42c0-bb3f-70780f5f107d.png)\n\n  ![image](https://user-images.githubusercontent.com/10358317/233836945-dfb85038-f5be-40a8-abe7-15b1334b854d.png)\n\n ### SAMPLE-07: CI/CD on AWS => Provisioning CodeCommit and CodePipeline, Triggering CodeBuild and CodeDeploy, Running on Lambda Container <a name=\"ci_cd\"></a>  \n\n- This sample shows:\n  - how to create code repository using CodeCommit,\n  - how to create pipeline with CodePipeline, create S3 bucket to store Artifacts for codepipeline stages' connection (source, build, deploy),\n  - how to create builder with CodeBuild ('buildspec_build.yaml'), build the source code, create a Docker image,\n  - how to create ECR (Elastic Container Repository) and push the build image into the ECR,\n  - how to create Lambda Function (by CodeBuild automatically) and run/deploy container on Lambda ('buildspec_deploy.yaml').\n- Source code is pulled from:\n  - https://github.com/aws-samples/codepipeline-for-lambda-using-terraform\n- Some of the fields are updated. \n- It works with 'hashicorp/aws ~> 4.15.1', 'terraform >= 0.15'\n- **Code:** https://github.com/omerbsezer/Fast-Terraform/tree/main/samples/codecommit-codepipeline-codebuild-codedeploy-lambda-container\n- **Go to the Hands-On Sample:**    \n  - [SAMPLE-07: CI/CD on AWS => Provisioning CodeCommit and CodePipeline, Triggering CodeBuild and CodeDeploy, Running on Lambda Container](https://github.com/omerbsezer/Fast-Terraform/blob/main/SAMPLE07-CodeCommit-Pipeline-Build-Deploy-Lambda.md)\n\n  ![image](https://user-images.githubusercontent.com/10358317/233652299-66b39788-66ee-4a5e-b8e0-ece418fe98e3.png)\n\n ### SAMPLE-08: Provisioning S3 and CloudFront to serve Static Web Site <a name=\"s3_cloudfront\"></a>\n\n- This sample shows:\n  - how to create S3 Bucket, \n  - how to to copy the website to S3 Bucket, \n  - how to configure S3 bucket policy,\n  - how to create CloudFront distribution to refer S3 Static Web Site,\n  - how to configure CloudFront (default_cache_behavior, ordered_cache_behavior, ttl, price_class, restrictions, viewer_certificate).\n- **Code:** https://github.com/omerbsezer/Fast-Terraform/blob/main/samples/s3-cloudfront-static-website/\n- **Go to the Hands-On Sample:**    \n  - [SAMPLE-08: Provisioning S3 and CloudFront to serve Static Web Site](https://github.com/omerbsezer/Fast-Terraform/blob/main/SAMPLE08-S3-CloudFront-Static-WebSite.md)\n\n  ![image](https://user-images.githubusercontent.com/10358317/234044290-e14650ed-93b4-4c49-8891-edeb959ffacb.png)\n\n ### SAMPLE-09: Running Gitlab Server using Docker on Local Machine and Making Connection to Provisioned Gitlab Runner on EC2 in Home Internet without Using VPN <a name=\"gitlabrunner\"></a>\n \n- This sample shows:\n  - how to run Gitlab Server using Docker on WSL2 on-premise,\n  - how to redirect external traffic to docker container port (Gitlab server),\n  - how to configure on-premise PC network configuration,\n  - how to run EC2 and install docker, gitlab-runner on EC2,\n  - how to register Gitlab runner on EC2 to Gitlab Server on-premise (in Home),\n  - how to run job on EC2 and returns artifacts to Gitlab Server on-premise (in Home).\n- **Code:** https://github.com/omerbsezer/Fast-Terraform/blob/main/samples/gitlabserver-on-premise-runner-on-EC2/\n- **Go to the Hands-On Sample:**\n  - [SAMPLE-09: Running Gitlab Server using Docker on Local Machine and Making Connection to Provisioned Gitlab Runner on EC2 in Home Internet without Using VPN](https://github.com/omerbsezer/Fast-Terraform/blob/main/SAMPLE09-GitlabServer-on-Premise-GitlabRunner-on-EC2.md)\n\n## Details <a name=\"details\"></a>\n- To validate the Terraform files:\n  - \"terraform validate\"\n- For dry-run:\n  - \"terraform plan\"\n- For formatting:\n  - \"terraform fmt\"\n- For debugging:\n  - **Bash:** export TF_LOG=\"DEBUG\"\n  - **PowerShell:** $env:TF_LOG=\"DEBUG\"\n- For debug logging:  \n  - **Bash:** export TF_LOG_PATH=\"tmp/terraform.log\"\n  - **PowerShell:** $env:TF_LOG_PATH=\"C:\\tmp\\terraform.log\"\n\n## Terraform Cheatsheet <a name=\"cheatsheet\"></a>\n\n- [Terraform Cheatsheet](https://github.com/omerbsezer/Fast-Terraform/blob/main/Terraform-Cheatsheet.md)\n\n## Other Useful Resources Related Terraform <a name=\"resource\"></a>\n- **AWS Samples (Advanced):** \n  - https://github.com/aws-samples\n- **AWS Samples with Terraform (Advanced):** \n  - https://github.com/orgs/aws-samples/repositories?q=Terraform&type=all&language=&sort= \n- **AWS Integration and Automation (Advanced):**  \n  - https://github.com/aws-ia\n- **Reference Guide: Terraform Registry Documents** \n  - https://registry.terraform.io/providers/hashicorp/aws/latest/docs  \n\n## References <a name=\"references\"></a>\n- Redis: https://developer.redis.com/create/aws/terraform/\n- https://developer.hashicorp.com/terraform/intro\n- https://github.com/aws-samples\n- https://github.com/orgs/aws-samples/repositories?q=Terraform&type=all&language=&sort= \n- https://github.com/aws-ia/terraform-aws-eks-blueprints\n- https://github.com/aws-ia\n\n"
  },
  {
    "path": "SAMPLE01-EC2-VPC-Ubuntu-Win-SSH-RDP.md",
    "content": "## SAMPLE-01: Provisioning EC2s (Windows 2019 Server, Ubuntu 20.04) on VPC (Subnet), Creating Key-Pair, Connecting Ubuntu using SSH, and Connecting Windows Using RDP\n\nThis sample shows:\n- how to create Key-pairs (public and private keys) on AWS.\n- how to create EC2s (Ubuntu 20.04, Windows 2019 Server).\n- how to create Virtual Private Cloud (VPC), VPC Components (Public Subnet, Internet Gateway, Route Table) and link to each others.\n- how to create Security Groups (for SSH and Remote Desktop).\n\n**Code:** https://github.com/omerbsezer/Fast-Terraform/tree/main/samples/ec2-vpc-ubuntu-win-ssh-rdp\n\n  ![1 VPC-IG-EC2](https://github.com/user-attachments/assets/29c5a207-bc35-43f1-8c4e-75d77acf77c1)\n\n### Prerequisite\n\n- You should have a look following lab: \n  - [LAB-00: Terraform Install, AWS Configuration with Terraform](https://github.com/omerbsezer/Fast-Terraform/blob/main/LAB00-Terraform-Install-AWS-Configuration.md)\n\n## Steps\n\n- SSH key-pairs (public and private key) are used to connect remote server. Public key (xx.pub) is on the remote server, with private key, user can connect using SSH.\n\n- There are 2 ways of creating key-pairs (public and private key):\n  - Creating them on cloud (AWS)\n  \t- EC2 > Key-pairs > Create Key-Pair\n  - Creating them on on-premise \n  \t- \"ssh-keygen -t rsa -b 2048\" \n\n- Creating key-pairs on AWS: Go to EC2 > Key-pairs\n\n![image](https://user-images.githubusercontent.com/10358317/228974087-b57126ab-6589-48fe-b609-1f18dc2f0c7e.png)\n\n- After creating key-pairs, public key is listed on AWS:\n\n![image](https://user-images.githubusercontent.com/10358317/228974292-0d2d16ec-5590-4929-9b4e-8bc0215dcd60.png)\n\n- Private key (testkey.pem) is downloaded on your PC:\n\n![image](https://user-images.githubusercontent.com/10358317/228974369-46c54f25-ea80-40dd-9c75-670ece815bf2.png)\n\n- Copy this testkey.pem into your directory on which main.tf exists.\n\n![image](https://user-images.githubusercontent.com/10358317/228974784-de1b9be4-9083-45ec-a9ab-5a1e54aee2c5.png)\n\n\n- Create main.tf under count directory and copy the code:\n \n``` \n# main.tf\nterraform {\n  required_providers {\n    aws = {\n      source  = \"hashicorp/aws\"\n      version = \"~> 4.16\"\n    }\n  }\n  required_version = \">= 1.2.0\"\n}\n\nprovider \"aws\" {\n\tregion = \"eu-central-1\"\n}\n\nresource \"aws_vpc\" \"my_vpc\" {\n  cidr_block           = \"10.0.0.0/16\"\n  enable_dns_hostnames = true\n  tags = {\n    Name = \"My VPC\"\n  }\n}\n\nresource \"aws_subnet\" \"public\" {\n  vpc_id            = aws_vpc.my_vpc.id\n  cidr_block        = \"10.0.0.0/24\"\n  availability_zone = \"eu-central-1c\"\n  tags = {\n    Name = \"Public Subnet\"\n  }\n}\n\nresource \"aws_internet_gateway\" \"my_vpc_igw\" {\n  vpc_id = aws_vpc.my_vpc.id\n  tags = {\n    Name = \"My VPC - Internet Gateway\"\n  }\n}\n\nresource \"aws_route_table\" \"my_vpc_eu_central_1c_public\" {\n    vpc_id = aws_vpc.my_vpc.id\n    route {\n        cidr_block = \"0.0.0.0/0\"\n        gateway_id = aws_internet_gateway.my_vpc_igw.id\n    }\n    tags = {\n        Name = \"Public Subnet Route Table\"\n    }\n}\nresource \"aws_route_table_association\" \"my_vpc_eu_central_1c_public\" {\n    subnet_id      = aws_subnet.public.id\n    route_table_id = aws_route_table.my_vpc_eu_central_1c_public.id\n}\n\nresource \"aws_security_group\" \"allow_ssh\" {\n  name        = \"allow_ssh_sg\"\n  description = \"Allow SSH inbound connections\"\n  vpc_id      = aws_vpc.my_vpc.id\n  # for SSH\n  ingress {\n    from_port   = 22\n    to_port     = 22\n    protocol    = \"tcp\"\n    cidr_blocks = [\"0.0.0.0/0\"]\n  }\n  # for HTTP Apache Server\n  ingress {\n    from_port   = 80\n    to_port     = 80\n    protocol    = \"tcp\"\n    cidr_blocks = [\"0.0.0.0/0\"]\n  }\n  # for RDP\n  ingress {\n    from_port        = 3389\n    to_port          = 3389\n    protocol         = \"tcp\"\n    cidr_blocks      = [\"0.0.0.0/0\"]\n  }\n  # for ping\n  ingress {\n    from_port        = -1\n    to_port          = -1\n    protocol         = \"icmp\"\n    cidr_blocks      = [\"10.0.0.0/16\"]\n  }\n  egress {\n    from_port       = 0\n    to_port         = 0\n    protocol        = \"-1\"\n    cidr_blocks     = [\"0.0.0.0/0\"]\n  }\n  tags = {\n    Name = \"allow_ssh_sg\"\n  }\n}\n\nresource \"aws_instance\" \"ubuntu2004\" {\n  ami                         = \"ami-0e067cc8a2b58de59\" # Ubuntu 20.04 eu-central-1 Frankfurt\n  instance_type               = \"t2.nano\"\n  key_name                    = \"testkey\"\n  vpc_security_group_ids      = [aws_security_group.allow_ssh.id]\n  subnet_id                   = aws_subnet.public.id\n  associate_public_ip_address = true\n  user_data = <<-EOF\n\t\t           #! /bin/bash\n                           sudo apt-get update\n\t\t           sudo apt-get install -y apache2\n\t\t           sudo systemctl start apache2\n\t\t           sudo systemctl enable apache2\n\t\t           echo \"<h1>Deployed via Terraform from $(hostname -f)</h1>\" | sudo tee /var/www/html/index.html\n  EOF\n  tags = {\n    Name = \"Ubuntu 20.04\"\n  }\n}\n\nresource \"aws_instance\" \"win2019\" {\n\tami                         = \"ami-02c2da541ae36c6fc\" # Windows 2019 Server eu-central-1 Frankfurt\n\tinstance_type               = \"t2.micro\"\n        key_name                    = \"testkey\"\n        vpc_security_group_ids      = [aws_security_group.allow_ssh.id]\n        subnet_id                   = aws_subnet.public.id  \n\tassociate_public_ip_address = true\n        tags = {\n\t\tName = \"Win 2019 Server\"\n\t}\n}\n\noutput \"instance_ubuntu2004_public_ip\" {\n  value = \"${aws_instance.ubuntu2004.public_ip}\"\n}\n\noutput \"instance_win2019_public_ip\" {\n  value = \"${aws_instance.win2019.public_ip}\"\n}\n``` \n\n**Code:** https://github.com/omerbsezer/Fast-Terraform/blob/main/samples/ec2-vpc-ubuntu-win-ssh-rdp/main.tf\n\n![image](https://user-images.githubusercontent.com/10358317/228973324-4bc1c6ad-1099-4f56-8e6f-c002f719d9d4.png)\n\n- Run init command:\n\n``` \nterraform init\n``` \n\n![image](https://user-images.githubusercontent.com/10358317/228975022-6ed0663d-dca8-427b-8a9b-7cce25522117.png)\n\n- Validate file:\n\n``` \nterraform validate\n``` \n\n![image](https://user-images.githubusercontent.com/10358317/228975088-077a0562-ee85-4ad2-8cc9-2f4ccd1c4c94.png)\n\n\n- Run plan command:\n\n``` \nterraform plan\n``` \n\n- Run apply command to create resources. Then, Terraform asks to confirm, write \"yes\":\n\n``` \nterraform apply\n```\n\n![image](https://user-images.githubusercontent.com/10358317/228975493-a28ece3e-b00d-436e-aab1-de7b679378f3.png)\n\n![image](https://user-images.githubusercontent.com/10358317/229282068-a4f293cf-cde7-4b6b-9e9e-48bd40822aae.png)\n\n- On AWS EC2 > Instances, Ubuntu 20.04:\n\n![image](https://user-images.githubusercontent.com/10358317/228975962-72c0fbe9-e1dc-482c-8edc-573013424953.png)\n\n- Security groups (SSG), for SSH (port 22), RDP (port 3389), HTTP (80), ICMP (for ping):\n\n![image](https://user-images.githubusercontent.com/10358317/228976204-c4993141-c8ad-4110-8f05-c1fb1e2c13c2.png)\n\n![image](https://user-images.githubusercontent.com/10358317/228976348-f07e284e-be34-4898-9b81-92a756910a56.png)\n\n- On AWS EC2 > Instances, Window 2019 Server:\n\n![image](https://user-images.githubusercontent.com/10358317/228976557-7951b759-73fd-46a6-b325-08389e52b86f.png)\n\n- Windows has same SSG like Ubuntu.\n\n- Storage, Elastic Block Storage default:\n\n![image](https://user-images.githubusercontent.com/10358317/228976823-4e80c3e5-8ec6-4e4b-b5d2-aa064982954d.png)\n\n- On AWS VPC (Virtual Private Cloud) Service:\n\n![image](https://user-images.githubusercontent.com/10358317/228977082-f0634c8e-8701-45e2-aa22-f0b7dc1e3400.png)\n\n- While installing Ubuntu20.04, userdata is used to install Apache Server on it. With SSG Port 80, using public IP, we can see the index.html, like hosting server:\n\n![image](https://user-images.githubusercontent.com/10358317/228978767-aee0b725-eff2-40b2-8a30-93f40c15a052.png)\n\n\n- SSH to Ubuntu 20.04 (ssh -i testkey.pem ubuntu@<PublicIPAddress>):\n\n![image](https://user-images.githubusercontent.com/10358317/228977324-3393ae14-85d8-48ba-9133-bc7a6f1ef73b.png)\n\n- Run:\n  \n```   \nsudo apt install net-tools\nifconfig \n``` \n\n- Private IP can be seen:\n  \n![image](https://user-images.githubusercontent.com/10358317/228977710-610437ee-c1c2-4a7e-82e7-ac07d38aed62.png)\n\n- Make remote connection to Windows (RDP):\n  \n![image](https://user-images.githubusercontent.com/10358317/228977887-14d82ad9-41ff-43eb-bdaf-2c3e007df506.png)\n\n- Download RDP App:\n  \n![image](https://user-images.githubusercontent.com/10358317/228978036-79956ff6-755e-4205-aa17-4ac45f8e6642.png)\n  \n- To get password, upload testkey.pem file:\n  \n![image](https://user-images.githubusercontent.com/10358317/228978295-f822464a-a448-434f-a22e-5f623620d69e.png)\n\n![image](https://user-images.githubusercontent.com/10358317/228978459-8fabb789-eec4-4582-b0e2-4b44d0e2de43.png)\n  \n- Now, we reach Windows using RDP:\n  \n![image](https://user-images.githubusercontent.com/10358317/229282800-7ee0cd35-fd46-4ece-9b04-45fa5c785fef.png)\n  \n- Pinging to Ubuntu20.04 from Windows:\n  \n![image](https://user-images.githubusercontent.com/10358317/228979379-1ed193a4-c5e4-4526-8a8e-0ecb2cf1a534.png)\n  \n- Opening firewall rules to ping from Ubuntu to Windows:\n- Windows Defender -> Advance Settings -> Inbound Rules -> File and Printer Sharing (Echo Request - ICMPv4 - In) -> Right Click (Enable)\n  \n![image](https://user-images.githubusercontent.com/10358317/228980207-1f699349-9d09-4304-ad1f-d66187a0b9e1.png)\n  \n- Pinging to Windows 2019 Server from Ubuntu20.04:\n  \n![image](https://user-images.githubusercontent.com/10358317/228980821-98c1b545-c1c1-41ca-a53c-f5049641c9df.png)\n  \n- Viewing Ubuntu CPU, RAM:\n  \n![image](https://user-images.githubusercontent.com/10358317/228981485-341444fb-f806-49fe-9a6c-c7edc0d25f17.png)\n  \n![image](https://user-images.githubusercontent.com/10358317/228981584-9823ad8d-169f-4ef2-b4bc-61852b95393b.png)\n  \n- Destroy infrastructure:\n\n```\nterraform destroy \n``` \n  \n![image](https://user-images.githubusercontent.com/10358317/229281383-6c8e01ea-af3a-4477-9be6-a10096318333.png)\n  \n![image](https://user-images.githubusercontent.com/10358317/229281239-b1713771-2960-4746-a1bd-f7543913bd66.png)\n\n- Be sure that instances are terminated. Because if they works, we pay the fee of them:\n\n![image](https://user-images.githubusercontent.com/10358317/228982134-2a648783-0f11-47e9-865d-1dc92dffdd0f.png)\n\n- We can also monitor the CPU, Disk, Network Usage on AWS EC2:\n\t\n![image](https://user-images.githubusercontent.com/10358317/228983384-7b4a0e36-0605-4f33-901f-2a0ebd79c4f6.png)\n\n"
  },
  {
    "path": "SAMPLE02-Lambda-API-Gateway-Python.md",
    "content": "## SAMPLE-02: Provisioning Lambda Function, API Gateway and Reaching HTML Page in Python Code From Browser\n\nThis sample shows:\n- how to create Lambda function with Python code,\n- how to create Lambda Role, Policy, Policy-Role attachment, Lambda API-gateway permission, uploading code,\n- how to create API-gateway resource and method definition, Lambda-API-gateway connection, deploying API-gateway,\n- details on AWS Lambda, API-Gateway, IAM\n\n![3 Lambda-TF](https://github.com/user-attachments/assets/554cfb9b-44a3-4eb0-b278-a3ae5c25ffbe)\n\n\nThere are 3 main parts:\n- lambda.tf: It includes lambda function, lambda role, policy, policy-role attachment, lambda api gateway permission, zipping code\n- api-gateway.tf: It includes api-gateway resource and method definition, lambda - api gateway connection, deploying api gateway, api-gateway deployment URL as output\n- code/main.py: It includes basic lambda handler with basic HTML code, and REST API response. \n\n**Code:** https://github.com/omerbsezer/Fast-Terraform/tree/main/samples/lambda-role-policy-apigateway-python\n\n### Prerequisite\n\n- You should have a look following lab: \n  - [LAB-00: Terraform Install, AWS Configuration with Terraform](https://github.com/omerbsezer/Fast-Terraform/blob/main/LAB00-Terraform-Install-AWS-Configuration.md)\n\n## Steps\n\n- Create lambda.tf:\n  - **Terraform Configuration:** Specifies the AWS provider version and Terraform version.\n  - **IAM Role and Policy:** Creates an IAM role for the Lambda function and attaches a policy that allows the Lambda function to write logs to CloudWatch.\n  - **Zipping Lambda Code:** Prepares the Python code by zipping it into a format that Lambda can execute.\n  - **Lambda Function:** Creates a Lambda function using the specified IAM role, code, and runtime.\n  - **API Gateway Integration:** Grants API Gateway permission to invoke the Lambda function.\n \n``` \nterraform {\n  required_providers {\n    aws = {\n      source  = \"hashicorp/aws\"\n      version = \"~> 4.16\"\n    }\n  }\n  required_version = \">= 1.2.0\"\n}\n\n# Create IAM Role for lambda\nresource \"aws_iam_role\" \"lambda_role\" {\n name   = \"aws_lambda_role\"\n assume_role_policy = <<EOF\n{\n  \"Version\": \"2012-10-17\",\n  \"Statement\": [\n    {\n      \"Action\": \"sts:AssumeRole\",\n      \"Principal\": {\n        \"Service\": \"lambda.amazonaws.com\"\n      },\n      \"Effect\": \"Allow\",\n      \"Sid\": \"\"\n    }\n  ]\n}\nEOF\n}\n\n# IAM policy for the lambda\nresource \"aws_iam_policy\" \"iam_policy_for_lambda\" {\n\n  name         = \"aws_iam_policy_for_aws_lambda_role\"\n  path         = \"/\"\n  description  = \"AWS IAM Policy for managing aws lambda role\"\n  policy = <<EOF\n{\n  \"Version\": \"2012-10-17\",\n  \"Statement\": [\n    {\n      \"Action\": [\n        \"logs:CreateLogGroup\",\n        \"logs:CreateLogStream\",\n        \"logs:PutLogEvents\"\n      ],\n      \"Resource\": \"arn:aws:logs:*:*:*\",\n      \"Effect\": \"Allow\"\n    }\n  ]\n}\nEOF\n}\n\n# Role - Policy Attachment\nresource \"aws_iam_role_policy_attachment\" \"attach_iam_policy_to_iam_role\" {\n  role        = aws_iam_role.lambda_role.name\n  policy_arn  = aws_iam_policy.iam_policy_for_lambda.arn\n}\n\n# Zipping the code, lambda wants the code as zip file\ndata \"archive_file\" \"zip_the_python_code\" {\n type        = \"zip\"\n source_dir  = \"${path.module}/code/\"\n output_path = \"${path.module}/code/main.zip\"\n}\n\n# Lambda Function, in terraform ${path.module} is the current directory.\nresource \"aws_lambda_function\" \"lambda_function\" {\n filename                       = \"${path.module}/code/main.zip\"\n function_name                  = \"Lambda-Function\"\n role                           = aws_iam_role.lambda_role.arn\n handler                        = \"main.lambda_handler\"\n runtime                        = \"python3.8\"\n depends_on                     = [aws_iam_role_policy_attachment.attach_iam_policy_to_iam_role]\n}\n\n# With Lambda permission, API Gateway can invoke Lambda \nresource \"aws_lambda_permission\" \"apigw\" {\n statement_id  = \"AllowAPIGatewayInvoke\"\n action        = \"lambda:InvokeFunction\"\n function_name = aws_lambda_function.lambda_function.function_name\n principal     = \"apigateway.amazonaws.com\"\n # The \"/*/*\" portion grants access from any method on any resource within the API Gateway REST API.\n source_arn = \"${aws_api_gateway_rest_api.example.execution_arn}/*/*\"\n}\n``` \n\n**Code:** https://github.com/omerbsezer/Fast-Terraform/blob/main/samples/lambda-role-policy-apigateway-python/lambda.tf\n\n![image](https://user-images.githubusercontent.com/10358317/230722794-2ba9d223-90f3-4634-8fba-d5290ecf6e8a.png)\n\n- Create api-gateway.tf: \n  - **Proxy Usage:** The {proxy+} path is used to dynamically route all requests to the Lambda function, eliminating the need to define individual paths and methods.\n  - **Flexibility:** The ANY method allows all HTTP methods, making the API flexible.\n  - **AWS_PROXY Integration:** Simplifies the interaction between API Gateway and Lambda by passing the entire request data to Lambda, allowing it to process dynamically.\n \n```\n# Create API Gateway with Rest API type\nresource \"aws_api_gateway_rest_api\" \"example\" {\n  name        = \"Serverless\"\n  description = \"Serverless Application using Terraform\"\n}\n\nresource \"aws_api_gateway_resource\" \"proxy\" {\n   rest_api_id = aws_api_gateway_rest_api.example.id\n   parent_id   = aws_api_gateway_rest_api.example.root_resource_id\n   path_part   = \"{proxy+}\"     # with proxy, this resource will match any request path\n}\n\nresource \"aws_api_gateway_method\" \"proxy\" {\n   rest_api_id   = aws_api_gateway_rest_api.example.id\n   resource_id   = aws_api_gateway_resource.proxy.id\n   http_method   = \"ANY\"       # with ANY, it allows any request method to be used, all incoming requests will match this resource\n   authorization = \"NONE\"\n}\n\n# API Gateway - Lambda Connection\nresource \"aws_api_gateway_integration\" \"lambda\" {\n   rest_api_id = aws_api_gateway_rest_api.example.id\n   resource_id = aws_api_gateway_method.proxy.resource_id\n   http_method = aws_api_gateway_method.proxy.http_method\n   integration_http_method = \"POST\"\n   type                    = \"AWS_PROXY\"  # With AWS_PROXY, it causes API gateway to call into the API of another AWS service\n   uri                     = aws_lambda_function.lambda_function.invoke_arn\n}\n\n# The proxy resource cannot match an empty path at the root of the API. \n# To handle that, a similar configuration must be applied to the root resource that is built in to the REST API object\nresource \"aws_api_gateway_method\" \"proxy_root\" {\n   rest_api_id   = aws_api_gateway_rest_api.example.id\n   resource_id   = aws_api_gateway_rest_api.example.root_resource_id\n   http_method   = \"ANY\"\n   authorization = \"NONE\"\n}\n\nresource \"aws_api_gateway_integration\" \"lambda_root\" {\n   rest_api_id = aws_api_gateway_rest_api.example.id\n   resource_id = aws_api_gateway_method.proxy_root.resource_id\n   http_method = aws_api_gateway_method.proxy_root.http_method\n   integration_http_method = \"POST\"\n   type                    = \"AWS_PROXY\"  # With AWS_PROXY, it causes API gateway to call into the API of another AWS service\n   uri                     = aws_lambda_function.lambda_function.invoke_arn\n}\n\n# Deploy API Gateway\nresource \"aws_api_gateway_deployment\" \"example\" {\n   depends_on = [\n     aws_api_gateway_integration.lambda,\n     aws_api_gateway_integration.lambda_root,\n   ]\n   rest_api_id = aws_api_gateway_rest_api.example.id\n   stage_name  = \"test\"\n}\n\n# Output to the URL \noutput \"base_url\" {\n  value = aws_api_gateway_deployment.example.invoke_url\n}\n```\n\n**Code:** https://github.com/omerbsezer/Fast-Terraform/blob/main/samples/lambda-role-policy-apigateway-python/api-gateway.tf\n\n![image](https://user-images.githubusercontent.com/10358317/230722822-b8352e6e-6ebf-4dec-ab36-0f5d7bcfe914.png)\n\n\n- Create main.py under code directory:\n\n```\ndef lambda_handler(event, context):\n   content = \"\"\"\n   <html>\n   <h1> Hello Website running on Lambda! Deployed via Terraform </h1>\n   </html>\n   \"\"\"\n   response ={\n     \"statusCode\": 200,\n     \"body\": content,\n     \"headers\": {\"Content-Type\": \"text/html\",}, \n   }\n   return response\n```\n\n**Code:** https://github.com/omerbsezer/Fast-Terraform/blob/main/samples/lambda-role-policy-apigateway-python/code/main.py\n\n![image](https://user-images.githubusercontent.com/10358317/230722767-2f89b91b-eab3-4348-b405-7ca773bee803.png)\n\n- Run init, validate command:\n\n``` \nterraform init\nterraform validate\n``` \n\n![image](https://user-images.githubusercontent.com/10358317/230722951-8516b9fd-2b03-4391-b91f-a338c207b669.png)\n\n- Run plan, apply command:\n\n``` \nterraform plan   # for dry-run\nterraform apply\n``` \n\n![image](https://user-images.githubusercontent.com/10358317/230723022-f5443b26-7b50-4834-ad2a-a8f1f277ecbb.png)\n\n![image](https://user-images.githubusercontent.com/10358317/230723143-a4cd31a1-a48a-4ed9-92aa-1ddc4ecafb2a.png)\n\n- On AWS Lambda:\n\n![image](https://user-images.githubusercontent.com/10358317/230723176-fe26cd48-b8cc-463f-9bba-cb8573514e64.png)\n\n![image](https://user-images.githubusercontent.com/10358317/230723214-0e056c50-567e-4cca-bc67-73328301b24c.png)\n\n- Create a test by clicking \"Test\" for lambda function:\n\n![image](https://user-images.githubusercontent.com/10358317/230723292-5496d0f0-977d-46e4-96ee-239808e56284.png)\n\n- Status code 200, OK is returned successfully:\n\n![image](https://user-images.githubusercontent.com/10358317/230723342-bb606c2f-b9d6-47d0-93b6-e935e00481e1.png)\n\n- Execution Role is created, seen on Lambda\n\n![image](https://user-images.githubusercontent.com/10358317/230723943-f9cafb0e-a03a-4c40-a55e-792c5416c8ed.png)\n\n- Role on IAM:\n\n![image](https://user-images.githubusercontent.com/10358317/230724180-0829397f-fc53-4199-8eb5-8c206237d771.png)\n\n- Policy on IAM:\n\n![image](https://user-images.githubusercontent.com/10358317/230724019-dfd4936c-85a0-42a3-b3f3-fcae018ca8e6.png)\n\n- On AWS Lambda: With Lambda permission, API Gateway can invoke Lambda \n\n![image](https://user-images.githubusercontent.com/10358317/230724344-09c46001-af57-4637-ab46-3df38cfd5b27.png)\n\n\n- Lambda is triggered by API-Gateway:\n\n![image](https://user-images.githubusercontent.com/10358317/230723832-95739c09-ec36-4eb6-b1a4-5acbd675ea27.png)\n\n- On AWS API-Gateway:\n\n![image](https://user-images.githubusercontent.com/10358317/230723491-4f377afc-8fc9-4ab9-ba99-41970e205207.png)\n\n![image](https://user-images.githubusercontent.com/10358317/230723560-b5f814e0-c1e2-4961-99e1-4f846de3797e.png)\n\n- By clicking \"Test\" to test api-gateway\n\n![image](https://user-images.githubusercontent.com/10358317/230723599-0a7f38e9-2f64-4dde-8da2-e19c3ceccd7c.png)\n\n![image](https://user-images.githubusercontent.com/10358317/230723628-76d57abe-4943-4876-bbaa-b2e1021476e5.png)\n\n- HTML page that runs on Lambda Function using API-Gateway can be reached. With API-Gateway, lambda function gets DNS and traffic from internet comes to the Lambda function. \n\n![image](https://user-images.githubusercontent.com/10358317/230723675-38fa5f25-c7ef-46e9-8eba-5e5691b47c88.png)\n\n\n- Run destroy command:\n\n``` \nterraform destroy\n``` \n\n![image](https://user-images.githubusercontent.com/10358317/230724579-86f8228a-efcb-4ae8-bcc3-009fa54a5d14.png)\n\n- On AWS Lambda, function is deleted:\n\n![image](https://user-images.githubusercontent.com/10358317/230724707-4e5070cf-a801-4b3e-9aa7-560b279a48a5.png)\n\n## References\n- https://www.tecracer.com/blog/2021/08/iam-what-happens-when-you-assume-a-role.html\n- https://medium.com/paul-zhao-projects/serverless-applications-with-aws-lambda-and-api-gateway-using-terraform-37d3de435d21\n- https://github.com/rahulwagh/Terraform-Topics/tree/master/aws-lambda\n"
  },
  {
    "path": "SAMPLE03-EC2-EBS-EFS.md",
    "content": "## SAMPLE-03: EBS (Elastic Block Store: HDD, SDD) and EFS (Elastic File System: NFS) Configuration with EC2s (Ubuntu and Windows Instances)\n\nThis sample shows:\n- how to provision EBS, mount on Ubuntu and Windows Instances.\n- how to provision EFS, mount on Ubuntu Instance.\n  - EFS is not supported on Windows Instance: https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/AmazonEFS.html\n- how to provision VPC, subnet, IGW, route table, security group. \n\n![aws-ebs-efs](https://github.com/user-attachments/assets/dc4efaf8-9d16-4a83-aeeb-9c0a082a4903)\n\nThere are 3 main parts:\n- **main.tf**: It includes 2 EC2 (Ubuntu, Windows), VPC, subnet, IGW, route table, security group implementation.\n- **efs.tf**: It includes EFS configuration for Ubuntu EC2. \n- **ebs.tf**: It includes EBS configuration for both Ubuntu and Windows EC2s.\n\n![image](https://user-images.githubusercontent.com/10358317/230903321-5bca3385-9564-44f1-bde8-fe1c873c870a.png)\n\n**Code:** https://github.com/omerbsezer/Fast-Terraform/tree/main/samples/ec2-ebs-efs\n\n# Table of Contents\n- [Key-Pair](#keypair)\n- [VPC, EC2, SG Implementation](#vpc)\n- [EBS Implementation](#ebs)\n- [EFS Implementation](#efs)\n- [Terraform Run](#run)\n- [EBS Final Setup and Test on Ubuntu](#ebsfinalubuntu)\n- [EFS Final Setup and Test on Ubuntu](#efsfinalubuntu)\n- [EBS Final Setup and Test on Windows](#ebsfinalwindows)\n\n\n\n### Prerequisite\n\n- You should have a look following lab: \n  - [LAB-00: Terraform Install, AWS Configuration with Terraform](https://github.com/omerbsezer/Fast-Terraform/blob/main/LAB00-Terraform-Install-AWS-Configuration.md)\n\n## Steps\n\n### Key-Pair <a name=\"keypair\"></a>\n\n SSH key-pairs (public and private key) are used to connect remote server. Public key (xx.pub) is on the remote server, with private key, user can connect using SSH.\n\n- There are 2 ways of creating key-pairs (public and private key):\n  - Creating them on cloud (AWS)\n  \t- EC2 > Key-pairs > Create Key-Pair\n  - Creating them on on-premise \n  \t- \"ssh-keygen -t rsa -b 2048\" \n\n- Creating key-pairs on AWS: Go to EC2 > Key-pairs\n\n![image](https://user-images.githubusercontent.com/10358317/228974087-b57126ab-6589-48fe-b609-1f18dc2f0c7e.png)\n\n- After creating key-pairs, public key is listed on AWS:\n\n![image](https://user-images.githubusercontent.com/10358317/228974292-0d2d16ec-5590-4929-9b4e-8bc0215dcd60.png)\n\n- Private key (testkey.pem) is downloaded on your PC:\n\n![image](https://user-images.githubusercontent.com/10358317/228974369-46c54f25-ea80-40dd-9c75-670ece815bf2.png)\n\n- Copy this testkey.pem into your directory on which main.tf exists.\n\n![image](https://user-images.githubusercontent.com/10358317/228974784-de1b9be4-9083-45ec-a9ab-5a1e54aee2c5.png)\n\n### VPC, EC2, SG Implementation <a name=\"vpc\"></a>\n\n- Create main.tf:\n \n```\nterraform {\n  required_providers {\n    aws = {\n      source  = \"hashicorp/aws\"\n      version = \"~> 5.81.0\"\n    }\n  }\n  required_version = \">= 1.10.2\"\n}\n\nprovider \"aws\" {\n\tregion = \"eu-central-1\"\n}\n\nresource \"aws_vpc\" \"my_vpc\" {\n  cidr_block           = \"10.0.0.0/16\"\n  enable_dns_hostnames = true\n  tags = {\n    Name = \"My VPC\"\n  }\n}\n\nresource \"aws_subnet\" \"public\" {\n  vpc_id            = aws_vpc.my_vpc.id\n  cidr_block        = \"10.0.0.0/24\"\n  availability_zone = \"eu-central-1c\"\n  tags = {\n    Name = \"Public Subnet\"\n  }\n}\n\nresource \"aws_internet_gateway\" \"my_vpc_igw\" {\n  vpc_id = aws_vpc.my_vpc.id\n  tags = {\n    Name = \"My VPC - Internet Gateway\"\n  }\n}\n\nresource \"aws_route_table\" \"my_vpc_eu_central_1c_public\" {\n    vpc_id = aws_vpc.my_vpc.id\n    route {\n        cidr_block = \"0.0.0.0/0\"\n        gateway_id = aws_internet_gateway.my_vpc_igw.id\n    }\n    tags = {\n        Name = \"Public Subnet Route Table\"\n    }\n}\nresource \"aws_route_table_association\" \"my_vpc_eu_central_1c_public\" {\n    subnet_id      = aws_subnet.public.id\n    route_table_id = aws_route_table.my_vpc_eu_central_1c_public.id\n}\n\nresource \"aws_security_group\" \"sg_config\" {\n  name        = \"allow_ssh_sg\"\n  description = \"Allow SSH inbound connections\"\n  vpc_id      = aws_vpc.my_vpc.id\n  # for SSH\n  ingress {\n    from_port        = 22\n    to_port          = 22\n    protocol         = \"tcp\"\n    cidr_blocks      = [\"0.0.0.0/0\"]\n  }\n  # for HTTP Apache Server\n  ingress {\n    from_port        = 80\n    to_port          = 80\n    protocol         = \"tcp\"\n    cidr_blocks      = [\"0.0.0.0/0\"]\n  }\n  # for RDP\n  ingress {\n    from_port        = 3389\n    to_port          = 3389\n    protocol         = \"tcp\"\n    cidr_blocks      = [\"0.0.0.0/0\"]\n  }\n  # for ping\n  ingress {\n    from_port        = -1\n    to_port          = -1\n    protocol         = \"icmp\"\n    cidr_blocks      = [\"10.0.0.0/16\"]\n  }\n  # EFS mount target, important to connect with NFS file system, it must be added.\n  ingress {\n    from_port        = 2049\n    to_port          = 2049\n    protocol         = \"tcp\"\n    cidr_blocks      = [\"0.0.0.0/0\"]\n  }\n  egress {\n    from_port       = 0\n    to_port         = 0\n    protocol        = \"-1\"\n    cidr_blocks     = [\"0.0.0.0/0\"]\n  }\n  tags = {\n    Name = \"allow_ssh_sg\"\n  }\n}\n\nresource \"aws_instance\" \"ubuntu2004\" {\n  ami                         = \"ami-0e067cc8a2b58de59\" # Ubuntu 20.04 eu-central-1 Frankfurt\n  instance_type               = \"t2.nano\"\n  key_name                    = \"testkey\"\n  vpc_security_group_ids      = [aws_security_group.sg_config.id]\n  subnet_id                   = aws_subnet.public.id\n  associate_public_ip_address = true\n  tags = {\n    Name = \"Ubuntu 20.04\"\n  }\n}\n\nresource \"aws_instance\" \"win2019\" {\n  ami                         = \"ami-02c2da541ae36c6fc\" # Windows 2019 Server eu-central-1 Frankfurt\n  instance_type               = \"t2.micro\"\n  key_name                    = \"testkey\"\n  vpc_security_group_ids      = [aws_security_group.allow_ssh.id]\n  subnet_id                   = aws_subnet.public.id  \n  associate_public_ip_address = true\n  tags = {\n\t\tName = \"Win 2019 Server\"\n\t}\n}\n\noutput \"instance_ubuntu2004_public_ip\" {\n  value = \"${aws_instance.ubuntu2004.public_ip}\"\n}\n\noutput \"instance_win2019_public_ip\" {\n  value = \"${aws_instance.win2019.public_ip}\"\n}\n```\n\n**Code:** https://github.com/omerbsezer/Fast-Terraform/blob/main/samples/ec2-ebs-efs/main.tf\n\n![image](https://user-images.githubusercontent.com/10358317/228973324-4bc1c6ad-1099-4f56-8e6f-c002f719d9d4.png)\n\n### EBS Implementation <a name=\"ebs\"></a>\n\n- Create ebs.tf:\n \n```\n# Creating EBS for Ubuntu\n# details: https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ebs_volume\nresource \"aws_ebs_volume\" \"ebs_ubuntu\" {\n  availability_zone = \"eu-central-1c\"\n  size = 20   # The size of the drive in GiBs.\n  type= \"gp2\" # default gp2. others: standard, gp2, gp3, io1, io2, sc1 or st1\n}\n\n# EBS-Ubuntu attachment\nresource \"aws_volume_attachment\" \"ubuntu2004_ebs_ubuntu\" {\n  device_name = \"/dev/sdh\"\n  volume_id   = \"${aws_ebs_volume.ebs_ubuntu.id}\"\n  instance_id = \"${aws_instance.ubuntu2004.id}\"\n}\n\n# Creating EBS for Windows\n# details: https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ebs_volume\nresource \"aws_ebs_volume\" \"ebs_windows\" {\n  availability_zone = \"eu-central-1c\"\n  size = 15   # The size of the drive in GiBs.\n  type= \"gp2\" # default gp2. others: standard, gp2, gp3, io1, io2, sc1 or st1\n}\n\n# EBS-Windows attachment\nresource \"aws_volume_attachment\" \"win2019_ebs_windows\" {\n  device_name = \"/dev/sdg\"\n  volume_id   = \"${aws_ebs_volume.ebs_windows.id}\"\n  instance_id = \"${aws_instance.win2019.id}\"\n}\n```\n\n**Code:** https://github.com/omerbsezer/Fast-Terraform/blob/main/samples/ec2-ebs-efs/ebs.tf\n\n![image](https://user-images.githubusercontent.com/10358317/230891729-cda1f5a7-0d7e-4763-ad26-709b23596ad5.png)\n\n### EFS Implementation <a name=\"efs\"></a>\n\n- Create efs.tf:\n \n```\n# Creating Amazon EFS File system\n# Amazon EFS supports two lifecycle policies. Transition into IA and Transition out of IA\nresource \"aws_efs_file_system\" \"efs\" {\n  lifecycle_policy {\n    transition_to_ia = \"AFTER_30_DAYS\"\n  }\n  tags = {\n    Name = \"efs-example\"\n  }\n}\n\n# Creating the EFS access point for AWS EFS File system\nresource \"aws_efs_access_point\" \"access_point\" {\n  file_system_id = aws_efs_file_system.efs.id\n}\n\n# Creating the AWS EFS System policy to transition files into and out of the file system.\n# The EFS System Policy allows clients to mount, read and perform, write operations on File system \n# The communication of client and EFS is set using aws:secureTransport Option\nresource \"aws_efs_file_system_policy\" \"policy\" {\n  file_system_id = aws_efs_file_system.efs.id\n  policy = <<POLICY\n{\n    \"Version\": \"2012-10-17\",\n    \"Id\": \"Policy01\",\n    \"Statement\": [\n        {\n            \"Sid\": \"Statement\",\n            \"Effect\": \"Allow\",\n            \"Principal\": {\n                \"AWS\": \"*\"\n            },\n            \"Resource\": \"${aws_efs_file_system.efs.arn}\",\n            \"Action\": [\n                \"elasticfilesystem:ClientMount\",\n                \"elasticfilesystem:ClientRootAccess\",\n                \"elasticfilesystem:ClientWrite\"\n            ],\n            \"Condition\": {\n                \"Bool\": {\n                    \"aws:SecureTransport\": \"false\"\n                }\n            }\n        }\n    ]\n}\nPOLICY\n}\n\n# Creating the AWS EFS Mount point in a specified Subnet \nresource \"aws_efs_mount_target\" \"mount\" {\n  file_system_id = aws_efs_file_system.efs.id\n  subnet_id      = aws_subnet.public.id\n  security_groups = [aws_security_group.sg_config.id]  # open ingress 2049 port for EFS\n}\n\nresource \"null_resource\" \"configure_nfs\" {\n  depends_on = [aws_efs_mount_target.mount]\n   \n  connection {\n    type     = \"ssh\"\n    user     = \"ubuntu\"\n    private_key = file(\"testkey.pem\")\n    host     = aws_instance.ubuntu2004.public_ip\n  }\n\n  provisioner \"remote-exec\" {\n    inline = [\n      \"sudo apt install nfs-common -y\",\n      \"mkdir ~/efs\",\n      \"cd ~/efs\",\n      \"df -kh\"\n    ]\n  }\n}\n```\n\n**Code:** https://github.com/omerbsezer/Fast-Terraform/blob/main/samples/ec2-ebs-efs/efs.tf\n\n![image](https://user-images.githubusercontent.com/10358317/230891861-918ccb30-f78e-45be-9780-5d9046a829de.png)\n\n### Terraform Run <a name=\"run\"></a>\n\n- Run init, validate, plan, apply commands:\n\n``` \nterraform init\nterraform validate\nterraform plan\nterraform apply\n``` \n\n![image](https://user-images.githubusercontent.com/10358317/230892963-1699dbe3-5b7e-43a2-a2a0-bfd71e463c41.png)\n\n![image](https://user-images.githubusercontent.com/10358317/230893093-c7e6f1dd-f5f0-4b57-9c67-b56d6a872fbb.png)\n\n### EBS Final Setup and Test on Ubuntu <a name=\"ebsfinalubuntu\"></a>\n\n- On AWS EC2:\n\n![image](https://user-images.githubusercontent.com/10358317/230893309-620f3483-4056-4685-ada9-e49f88e8cc64.png)\n\n- On AWS EC2 Volumes, EC2 have default root volumes (8GB, 30GB).\n- New addition volumes (15GB, 20GB) are added as a second volume of EC2s.\n\n![image](https://user-images.githubusercontent.com/10358317/230893508-3ca0ae47-0738-46af-b8b6-2e59ce022034.png)\n\n- Connect to the Ubuntu via SSH:\n\n```\nssh -i .\\testkey.pem ubuntu@3.69.53.254\nlsblk\n```\n\n![image](https://user-images.githubusercontent.com/10358317/230894465-f33c048f-78aa-47f0-8c5b-878cd8a4368c.png)\n\n- Formatting disk, mounting EBS:\n\n```\nsudo file -s /dev/xvdh       # “/dev/xvdf: data“, it means your volume is empty.\n\n#format, Format the volume to the ext4 or xfs\nsudo mkfs -t ext4 /dev/xvdh  # prefer ext4  \n# sudo mkfs -t xfs /dev/xvdh\n\n# mounting EBS\nsudo mkdir newvolume\nsudo mount /dev/xvdh newvolume\ncd newvolume\ndf -h .\n```\n\n![image](https://user-images.githubusercontent.com/10358317/230894735-e13ebfb7-fb47-4d98-ae11-7e2358294c92.png)\n\n### EFS Final Setup and Test on Ubuntu <a name=\"efsfinalubuntu\"></a>\n\n- Go to EFS Service, new EFS filesystem:\n\n![image](https://user-images.githubusercontent.com/10358317/230894988-0a461c41-e8e2-4dfb-a44e-34b5a88f973d.png)\n\n- Click \"Attach\" to attach EFS to EC2:\n\n![image](https://user-images.githubusercontent.com/10358317/230895234-e9497503-0345-4cb3-9332-9b62202d7e37.png)\n\n- Copy the command:\n\n![image](https://user-images.githubusercontent.com/10358317/230895361-1d45f9fa-cc76-4261-9cc0-460e7d704182.png)\n\n- Mount the EFS:\n\n```\ne.g. sudo mount -t nfs4 -o nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport fs-0adf50bc47d99ff95.efs.eu-central-1.amazonaws.com:/ efs\n```\n\n- After mounting EFS, EFS mounted directory can be seen in the list.\n- Although creating 2 x 200MB files, root part's size does not change. It shows that EFS is mounted successfully, files are created on EFS part.\n\n![image](https://user-images.githubusercontent.com/10358317/230896271-ded8a2f6-cfb8-4d18-a29d-fba4277126cc.png)\n\n### EBS Final Setup and Test on Windows <a name=\"ebsfinalwindows\"></a>\n\n- Connect Windows with RDP, get password using pem key:\n\n![image](https://user-images.githubusercontent.com/10358317/230897189-9d7fcb1a-0129-4b6a-a06e-64715e645476.png)\n\n![image](https://user-images.githubusercontent.com/10358317/230897253-09e44ee7-ca2c-4720-ab25-f912213a15f1.png)\n\n\n- For mounting disk on Windows:\n  - Folow: https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/ebs-using-volumes.html, open disk management utility\n\n- Make \"Online\" the disk:\n\n![image](https://user-images.githubusercontent.com/10358317/230897820-eefb2070-d7a4-4d0b-b466-06441ef7e44b.png)\n\n- Make \"Initialize\" the disk, with MBR:\n\n![image](https://user-images.githubusercontent.com/10358317/230898135-6f8d7012-10b3-4e4b-bf29-27619166782d.png)\n\n- New Simple Volume:\n\n![image](https://user-images.githubusercontent.com/10358317/230898370-40f2b976-3a7c-4b7b-ae3e-0897b0c3a277.png)\n\n- Final configuration:\n\n![image](https://user-images.githubusercontent.com/10358317/230898488-a35862a9-d171-40b5-8f1d-4f97a986346a.png)\n\n- New EBS disk is mounted successfully:\n\n![image](https://user-images.githubusercontent.com/10358317/230898597-ca1d7ffe-80ba-45cb-9465-1463436392ae.png)\n\n- Destroy infrastructure:\n\n```\nterraform destroy \n``` \n\n- It is easy to manage 17 resources:\n\n![image](https://user-images.githubusercontent.com/10358317/230901325-0a1cd3c1-2080-4749-a084-f370c17b95de.png)\n\n## References:\n- https://adamtheautomator.com/terraform-efs/\n- https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/ebs-using-volumes.html\n"
  },
  {
    "path": "SAMPLE04-ECR-ECS-ELB-VPC-ECS-Service.md",
    "content": "## SAMPLE-04: Provisioning ECR (Elastic Container Repository), Pushing Image to ECR, Provisioning ECS (Elastic Container Service), VPC (Virtual Private Cloud), ELB (Elastic Load Balancer), ECS Tasks and Service on Fargate Cluster\n\nThis sample shows:\n- how to create Flask-app Docker image,\n- how to provision ECR and push to image to this ECR,\n- how to provision VPC, Internet Gateway, Route Table, 3 Public Subnets,\n- how to provision ALB (Application Load Balancer), Listener, Target Group,  \n- how to provision ECS Fargate Cluster, Task and Service (running container as Service)\n\nThere are 5 main parts:\n- **0_ecr.tf**: includes private ECR code\n- **1_vpc.tf**: includes VPC, IGW, Route Table, Subnets code\n- **2_ecs.tf**: includes ECS Cluster, Task Definition, Role and Policy code\n- **3_elb.tf**: includes to ALB, Listener, Target Group, Security Group code \n- **4_ecs_service.tf**: includes ECS Fargate Service code with linking to loadbalancer, subnets, task definition.\n\n   ![ecr-ecs](https://user-images.githubusercontent.com/10358317/232244927-7d819c66-328a-4dd5-b3e1-18b2c7fd92aa.png)\n\n**Code:** https://github.com/omerbsezer/Fast-Terraform/tree/main/samples/ecr-ecs-elb-vpc-ecsservice-container\n\n**ECS Pricing:**\n- For the ECS Cluster:\n  - **Free**\n- For the ECS on 1 EC2 Instance (e.g. m5.large => 2 vCPU, 8 GB RAM):\n  - **Per Hour:** $0.096  \n  - **Per Day:**  $2.304\n  - **For 30 days:** $69.12\n  - Please have look for instance pricing: https://aws.amazon.com/ec2/pricing/on-demand/ \n- For the Fargate: \n  - AWS Fargate pricing is calculated based on the **vCPU and memory** resources used from the time you start to download your container image until the ECS Task (Container) terminate.\n    - e.g. 2 x (1vCPU, 4GB RAM) on Linux: \n      - **Per Hour:** 2 x ($0,0665) = $0.133\n      - **Per Day:** $3,18\n      - **Per 30 Days:** $95.67\n    - e.g. 2 x (1vCPU, 4GB RAM) on Win: \n      - **Per Hour:** 2 x ($0,199) = $0.398\n      - **Per Day:** $9.55\n      - **Per 30 Days:** $286.56\n  - Please have look for fargate pricing: https://aws.amazon.com/fargate/pricing/\n\n# Table of Contents\n- [Flask App Docker Image Creation](#app)\n- [Creating ECR (Elastic Container Repository), Pushing Image into ECR](#ecr)\n- [Creating VPC (Virtual Private Cloud)](#vpc)\n- [Creating ECS (Elastic Container Service)](#ecs)\n- [Creating ELB (Elastic Load Balancer)](#elb)\n- [Creating ECS Service](#ecsservice)\n- [Demo: Terraform Run](#run)\n\n### Prerequisite\n\n- You should have a look following lab: \n  - [LAB-00: Terraform Install, AWS Configuration with Terraform](https://github.com/omerbsezer/Fast-Terraform/blob/main/LAB00-Terraform-Install-AWS-Configuration.md)\n\n## Steps\n\n### Flask App Docker Image Creation <a name=\"app\"></a>\n- We have Flask-App to run on AWS ECS. To build image, please have a look:\n  - https://github.com/omerbsezer/Fast-Terraform/tree/main/samples/ecr-ecs-elb-vpc-ecsservice-container/flask-app\n\n### Creating ECR (Elastic Container Repository), Pushing Image into ECR <a name=\"ecr\"></a>\n\n- Create 0_ecr.tf:\n \n```\nterraform {\n  required_providers {\n    aws = {\n      source  = \"hashicorp/aws\"\n      version = \"~> 4.16\"\n    }\n  }\n  required_version = \">= 1.2.0\"\n}\n\n# Creating Elastic Container Repository for application\nresource \"aws_ecr_repository\" \"flask_app\" {\n  name = \"flask-app\"\n}\n```\n\n**Code:** https://github.com/omerbsezer/Fast-Terraform/blob/main/samples/ecr-ecs-elb-vpc-ecsservice-container/ecr/0_ecr.tf\n\n![image](https://user-images.githubusercontent.com/10358317/232241506-8abd69f6-8802-434e-976f-0420a226fa3f.png)\n\n```\ncd /ecr\nterraform init\nterraform plan\nterraform apply\n```\n\n- On AWS ECR:\n\n  ![image](https://user-images.githubusercontent.com/10358317/232226427-e8a9883e-298d-4268-b553-960f31994933.png)\n\n- To see the pushing docker commands, click \"View Push Commands\"\n\n```\naws ecr get-login-password --region eu-central-1 | docker login --username AWS --password-stdin <UserID>.dkr.ecr.eu-central-1.amazonaws.com\ndocker tag flask-app:latest <UserID>.ecr.eu-central-1.amazonaws.com/flask-app:latest\ndocker push <UserID>.dkr.ecr.eu-central-1.amazonaws.com/flask-app:latest\n```\n\n- Image was pushed:\n\n  ![image](https://user-images.githubusercontent.com/10358317/232226726-bffcca9f-4654-44bc-86dc-02a8d2d17c38.png)\n\n- On AWS ECR:\n\n  ![image](https://user-images.githubusercontent.com/10358317/232226806-aa709e35-25de-4110-ad5c-92949cc1ebe8.png) \n\n### Creating VPC (Virtual Private Cloud) <a name=\"vpc\"></a>\n\n- Create 1_vpc.tf:\n \n```\n# Internet Access -> IGW ->  Route Table -> Subnets\nterraform {\n  required_providers {\n    aws = {\n      source  = \"hashicorp/aws\"\n      version = \"~> 4.16\"\n    }\n  }\n  required_version = \">= 1.2.0\"\n}\n\nprovider \"aws\" {\n\tregion = \"eu-central-1\"\n}\n\nresource \"aws_vpc\" \"my_vpc\" {\n  cidr_block           = \"10.0.0.0/16\"\n  enable_dns_hostnames = true\n  tags = {\n    Name = \"My VPC\"\n  }\n}\n\nresource \"aws_subnet\" \"public_subnet_a\" {\n  availability_zone = \"eu-central-1a\"\n  vpc_id            = aws_vpc.my_vpc.id\n  cidr_block        = \"10.0.0.0/24\"\n  tags = {\n    Name = \"Public Subnet A\"\n  }\n}\n\nresource \"aws_subnet\" \"public_subnet_b\" {\n  availability_zone = \"eu-central-1b\"\n  vpc_id            = aws_vpc.my_vpc.id\n  cidr_block        = \"10.0.1.0/24\"\n  tags = {\n    Name = \"Public Subnet B\"\n  }\n}\n\nresource \"aws_subnet\" \"public_subnet_c\" {\n  availability_zone = \"eu-central-1c\"\n  vpc_id            = aws_vpc.my_vpc.id\n  cidr_block        = \"10.0.2.0/24\"\n  tags = {\n    Name = \"Public Subnet C\"\n  }\n}\n\nresource \"aws_internet_gateway\" \"igw\" {\n  vpc_id = aws_vpc.my_vpc.id\n  tags = {\n    Name = \"My VPC - Internet Gateway\"\n  }\n}\n\nresource \"aws_route_table\" \"route_table\" {\n    vpc_id = aws_vpc.my_vpc.id\n    route {\n        cidr_block = \"0.0.0.0/0\"\n        gateway_id = aws_internet_gateway.igw.id\n    }\n    tags = {\n        Name = \"Public Subnet Route Table\"\n    }\n}\n\nresource \"aws_route_table_association\" \"route_table_association1\" {\n    subnet_id      = aws_subnet.public_subnet_a.id\n    route_table_id = aws_route_table.route_table.id\n}\n\nresource \"aws_route_table_association\" \"route_table_association2\" {\n    subnet_id      = aws_subnet.public_subnet_b.id\n    route_table_id = aws_route_table.route_table.id\n}\n\nresource \"aws_route_table_association\" \"route_table_association3\" {\n    subnet_id      = aws_subnet.public_subnet_c.id\n    route_table_id = aws_route_table.route_table.id\n}\n```\n\n**Code:** https://github.com/omerbsezer/Fast-Terraform/blob/main/samples/ecr-ecs-elb-vpc-ecsservice-container/1_vpc.tf\n\n![image](https://user-images.githubusercontent.com/10358317/232241321-50a2fe1f-4fb2-4c82-b785-02bf1b326c63.png)\n\n### Creating ECS (Elastic Container Service) <a name=\"ecs\"></a>\n\n- Create 2_ecs.tf:\n \n```\n# Getting data existed ECR\ndata \"aws_ecr_repository\" \"flask_app\" {\n  name = \"flask-app\"\n}\n\n# Creating ECS Cluster\nresource \"aws_ecs_cluster\" \"my_cluster\" {\n  name = \"my-cluster\" # Naming the cluster\n}\n\n# Creating ECS Task\nresource \"aws_ecs_task_definition\" \"flask_app_task\" {\n  family                   = \"flask-app-task\" \n  container_definitions    = <<DEFINITION\n  [\n    {\n      \"name\": \"flask-app-task\",\n      \"image\": \"${data.aws_ecr_repository.flask_app.repository_url}\",\n      \"essential\": true,\n      \"portMappings\": [\n        {\n          \"containerPort\": 5000,\n          \"hostPort\": 5000\n        }\n      ],\n      \"memory\": 512,\n      \"cpu\": 256\n    }\n  ]\n  DEFINITION\n  requires_compatibilities = [\"FARGATE\"] # Stating that we are using ECS Fargate\n  network_mode             = \"awsvpc\"    # Using awsvpc as our network mode as this is required for Fargate\n  memory                   = 512         # Specifying the memory our container requires\n  cpu                      = 256         # Specifying the CPU our container requires\n  execution_role_arn       = \"${aws_iam_role.ecsTaskExecutionRole.arn}\"\n}\n\n# Creating Role for ECS\nresource \"aws_iam_role\" \"ecsTaskExecutionRole\" {\n  name               = \"ecsTaskExecutionRole\"\n  assume_role_policy = \"${data.aws_iam_policy_document.assume_role_policy.json}\"\n}\n\ndata \"aws_iam_policy_document\" \"assume_role_policy\" {\n  statement {\n    actions = [\"sts:AssumeRole\"]\n\n    principals {\n      type        = \"Service\"\n      identifiers = [\"ecs-tasks.amazonaws.com\"]\n    }\n  }\n}\n\n# Role - Policy Attachment for ECS\nresource \"aws_iam_role_policy_attachment\" \"ecsTaskExecutionRole_policy\" {\n  role       = \"${aws_iam_role.ecsTaskExecutionRole.name}\"\n  policy_arn = \"arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy\"\n}\n```\n\n**Code:** https://github.com/omerbsezer/Fast-Terraform/blob/main/samples/ecr-ecs-elb-vpc-ecsservice-container/2_ecs.tf\n\n![image](https://user-images.githubusercontent.com/10358317/232241736-14bbd3db-0c7d-4892-8f76-d762ed971c7e.png)\n\n### Creating ELB (Elastic Load Balancer) <a name=\"elb\"></a>\n\n- Create 3_elb.tf:\n \n```\n# Internet Access -> IGW -> LB Security Groups -> Application Load Balancer  (Listener 80) -> Target Groups  -> ECS Service -> ECS SG -> Tasks on each subnets \n\n# Creating Load Balancer (LB)\nresource \"aws_alb\" \"application_load_balancer\" {\n  name               = \"test-lb-tf\" # Naming our load balancer\n  load_balancer_type = \"application\"\n  subnets = [ \n    \"${aws_subnet.public_subnet_a.id}\",\n    \"${aws_subnet.public_subnet_b.id}\",\n    \"${aws_subnet.public_subnet_c.id}\"\n  ]\n  # Referencing the security group\n  security_groups = [\"${aws_security_group.load_balancer_security_group.id}\"]\n}\n\n# Creating a security group for LB\nresource \"aws_security_group\" \"load_balancer_security_group\" {\n  vpc_id      = aws_vpc.my_vpc.id\n  ingress {\n    from_port   = 80\n    to_port     = 80\n    protocol    = \"tcp\"\n    cidr_blocks = [\"0.0.0.0/0\"] # Allowing traffic in from all sources\n  }\n\n  egress {\n    from_port   = 0\n    to_port     = 0\n    protocol    = \"-1\"\n    cidr_blocks = [\"0.0.0.0/0\"]\n  }\n}\n\n# Creating LB Target Group\nresource \"aws_lb_target_group\" \"target_group\" {\n  name        = \"target-group\"\n  port        = 80\n  protocol    = \"HTTP\"\n  target_type = \"ip\"\n  vpc_id      = \"${aws_vpc.my_vpc.id}\" \n}\n\n# Creating LB Listener\nresource \"aws_lb_listener\" \"listener\" {\n  load_balancer_arn = \"${aws_alb.application_load_balancer.arn}\" # Referencing our load balancer\n  port              = \"80\"\n  protocol          = \"HTTP\"\n  default_action {\n    type             = \"forward\"\n    target_group_arn = \"${aws_lb_target_group.target_group.arn}\" # Referencing our target group\n  }\n}\n```\n\n**Code:** https://github.com/omerbsezer/Fast-Terraform/blob/main/samples/ecr-ecs-elb-vpc-ecsservice-container/3_elb.tf\n\n![image](https://user-images.githubusercontent.com/10358317/232241821-b859d54f-69ae-40ba-8034-b35fc5309fe1.png)\n\n### Creating ECS Service <a name=\"ecsservice\"></a>\n\n- Create 4_ecs_service.tf:\n \n```\n# Creating ECS Service\nresource \"aws_ecs_service\" \"my_first_service\" {\n  name            = \"my-first-service\"                             # Naming our first service\n  cluster         = \"${aws_ecs_cluster.my_cluster.id}\"             # Referencing our created Cluster\n  task_definition = \"${aws_ecs_task_definition.flask_app_task.arn}\" # Referencing the task our service will spin up\n  launch_type     = \"FARGATE\"\n  desired_count   = 3 # Setting the number of containers to 3\n\n  load_balancer {\n    target_group_arn = \"${aws_lb_target_group.target_group.arn}\" # Referencing our target group\n    container_name   = \"${aws_ecs_task_definition.flask_app_task.family}\"\n    container_port   = 5000 # Specifying the container port\n  }\n\n  network_configuration {\n    subnets          = [\"${aws_subnet.public_subnet_a.id}\", \"${aws_subnet.public_subnet_b.id}\", \"${aws_subnet.public_subnet_c.id}\"]\n    assign_public_ip = true                                                # Providing our containers with public IPs\n    security_groups  = [\"${aws_security_group.service_security_group.id}\"] # Setting the security group\n  }\n}\n\n# Creating SG for ECS Container Service, referencing the load balancer security group\nresource \"aws_security_group\" \"service_security_group\" {\n  vpc_id      = aws_vpc.my_vpc.id\n  ingress {\n    from_port = 0\n    to_port   = 0\n    protocol  = \"-1\"\n    # Only allowing traffic in from the load balancer security group\n    security_groups = [\"${aws_security_group.load_balancer_security_group.id}\"]\n  }\n\n  egress {\n    from_port   = 0\n    to_port     = 0\n    protocol    = \"-1\"\n    cidr_blocks = [\"0.0.0.0/0\"]\n  }\n}\n\n#Log the load balancer app URL\noutput \"app_url\" {\n  value = aws_alb.application_load_balancer.dns_name\n}\n```\n\n**Code:** https://github.com/omerbsezer/Fast-Terraform/blob/main/samples/ecr-ecs-elb-vpc-ecsservice-container/4_ecs_service.tf\n\n![image](https://user-images.githubusercontent.com/10358317/232241887-e71759c4-6a09-4cb3-9f18-f0dc36e08eda.png)\n\n### Demo: Terraform Run <a name=\"run\"></a>\n\n- Run:\n \n```\nterraform init\nterraform validate\nterraform plan\nterraform apply\n```\n\n![image](https://user-images.githubusercontent.com/10358317/232227578-21f28564-d960-45ea-af0d-3c4b3bddbc91.png)\n\n![image](https://user-images.githubusercontent.com/10358317/232227661-5ea1a161-03f0-4a76-b5c1-c9d3c1610333.png)\n\n- On AWS ECS Cluster:\n\n  ![image](https://user-images.githubusercontent.com/10358317/232227690-14ca0e5d-43bf-443e-b228-338081f17eb8.png)\n\n- On AWS ECS Service (service runs on the cluster):\n\n  ![image](https://user-images.githubusercontent.com/10358317/232227740-b0216d39-d141-4174-a506-61fc46245f02.png)\n\n- ECS Service Tasks (task includes running 3 containers):\n\n  ![image](https://user-images.githubusercontent.com/10358317/232227792-8f3bcd80-edcb-4893-bb5e-25432d87f38f.png)\n\n- Running Container Details (CPU, Memory Usage, Network, Environment Variable, Volume Configuration, Logs):\n\n  ![image](https://user-images.githubusercontent.com/10358317/232227895-07a3475a-c62a-4966-a35b-807fb4e136a6.png)\n\n- On AWS EC2 > LoadBalancer:\n\n  ![image](https://user-images.githubusercontent.com/10358317/232228088-74870060-9cbb-46e6-9f28-6162ff310e2e.png)\n\n- Target Groups:\n\n  ![image](https://user-images.githubusercontent.com/10358317/232228412-d53c99d9-ec75-44ab-a5dc-c5b9e77cd638.png)\n  \n- On AWS VPC:\n\n  ![image](https://user-images.githubusercontent.com/10358317/232229182-87c75449-0bd5-4048-833c-d0e9c3dc41c0.png)\n \n- When go to the output of the ELB DNS: http://test-lb-tf-634023821.eu-central-1.elb.amazonaws.com/\n\n  ![image](https://user-images.githubusercontent.com/10358317/232228546-8c9beb79-2133-438e-a05c-a36beef7b3f5.png)\n  \n- LB redirects 3 different containers. Each container has own SQLlite. So, each refresh to LB page, it shows 3 different page:\n- Container 0:\n\n  ![image](https://user-images.githubusercontent.com/10358317/232228846-a442f536-e127-448e-a699-350be155c5bb.png)\n  \n- Container 1: \n\n  ![image](https://user-images.githubusercontent.com/10358317/232228931-3370f751-fe9a-43e9-b75b-ec98b0a3693b.png)\n   \n- Container 2: \n\n  ![image](https://user-images.githubusercontent.com/10358317/232228879-fc9ca3fb-6d0c-4be6-a484-b6ac76375dd2.png)\n\n \n- Destroy the infra:\n\n```\nterraform destroy\n```\n\n![image](https://user-images.githubusercontent.com/10358317/232229470-6fd4dc95-bb63-4bda-860a-1fecc14a4fa5.png)\n\n- Delete the ECR Repo:\n\n```\ncd ecr\nterraform destroy\n```\n\n![image](https://user-images.githubusercontent.com/10358317/232229541-913de839-4df6-4d5b-881b-56be12801334.png)\n\n"
  },
  {
    "path": "SAMPLE05-Lambda-Container-ApiGateway-FlaskApp.md",
    "content": "## SAMPLE-05: Provisioning ECR, Lambda Function and API Gateway to run Flask App Container on Lambda\n\nThis sample shows:\n- how to create Flask-app-serverless image to run on Lambda,\n- how to create ECR and to push image to ECR,\n- how to create Lambda function, Lambda role, policy, policy-role attachment, Lambda API Gateway permission\n- how to create API Gateway resource and method definition, Lambda - API Gateway connection, deploying API Gateway\n\nThere are 3 main parts:\n- **0_ecr.tf**: includes private ECR code.\n- **1_lambda.tf**: includes lambda function, lambda role, policy, policy-role attachment, lambda api gateway permission code.\n- **2_api_gateway.tf**: includes api-gateway resource and method definition, lambda - api gateway connection, deploying api gateway code.\n\n![image](https://user-images.githubusercontent.com/10358317/233119705-ba6544e0-dbfc-49f5-9a65-c20b82f7bae1.png)\n\n**Code:** https://github.com/omerbsezer/Fast-Terraform/tree/main/samples/lambda-container-apigateway-flaskapp\n\n# Table of Contents\n- [Flask App Docker Image Creation](#app)\n- [Creating ECR (Elastic Container Repository), Pushing Image into ECR](#ecr)\n- [Creating Lambda](#lambda)\n- [Creating API Gateway](#apigateway)\n- [Demo: Terraform Run](#run)\n\n### Prerequisite\n\n- You should have a look following lab: \n  - [LAB-00: Terraform Install, AWS Configuration with Terraform](https://github.com/omerbsezer/Fast-Terraform/blob/main/LAB00-Terraform-Install-AWS-Configuration.md)\n\n## Steps\n\n### Flask App Docker Image Creation <a name=\"app\"></a>\n- We have Flask-App to run on AWS ECS. To build image, please have a look:\n  - https://github.com/omerbsezer/Fast-Terraform/tree/main/samples/lambda-container-apigateway-flaskapp/flask-app-serverless\n\n### Creating ECR (Elastic Container Repository), Pushing Image into ECR <a name=\"ecr\"></a>\n\n- Create 0_ecr.tf:\n \n```\nterraform {\n  required_providers {\n    aws = {\n      source  = \"hashicorp/aws\"\n      version = \"~> 4.16\"\n    }\n  }\n  required_version = \">= 1.2.0\"\n}\n\n# Creating Elastic Container Repository for application\nresource \"aws_ecr_repository\" \"flask_app_serverless\" {\n  name = \"flask-app-serverless\"\n}\n```\n\n**Code:** https://github.com/omerbsezer/Fast-Terraform/blob/main/samples/lambda-container-apigateway-flaskapp/ecr/0_ecr.tf\n\n```\ncd /ecr\nterraform init\nterraform plan\nterraform apply\n```\n\n- On AWS ECR:\n\n  ![image](https://user-images.githubusercontent.com/10358317/232346390-161b1cf6-c22c-476c-ba75-4fb2501f39ca.png)\n\n- To see the pushing docker commands, click \"View Push Commands\"\n\n```\naws ecr get-login-password --region eu-central-1 | docker login --username AWS --password-stdin <UserID>.dkr.ecr.eu-central-1.amazonaws.com\ndocker tag flask-app-serverless:latest <UserID>.ecr.eu-central-1.amazonaws.com/flask-app-serverless:latest\ndocker push <UserID>.dkr.ecr.eu-central-1.amazonaws.com/flask-app-serverless:latest\n```\n\n- Image on AWS ECR:\n\n  ![image](https://user-images.githubusercontent.com/10358317/232346479-48ecccd2-7b47-437f-a19a-dc25cbe79de0.png)\n\n### Creating Lambda <a name=\"lambda\"></a>\n\n- Difference between Lambda function code and Lambda container: Defining the image on the Lambda Function.\n\n```\n# Getting data existed ECR\ndata \"aws_ecr_repository\" \"flask_app_serverless\" {\n  name = \"flask-app-serverless\" \n}\n\n# Lambda Function, in terraform ${path.module} is the current directory.\nresource \"aws_lambda_function\" \"lambda_function\" {\n function_name = \"Lambda-Function\"\n role          = aws_iam_role.lambda_role.arn\n # tag is required, \"source image ... is not valid\" error will pop up\n image_uri     = \"${data.aws_ecr_repository.flask_app_serverless.repository_url}:latest\"    # lambda image on ECR\n package_type  = \"Image\"\n depends_on    = [aws_iam_role_policy_attachment.attach_iam_policy_to_iam_role]\n}\n```\n\n![image](https://user-images.githubusercontent.com/10358317/232440083-86117379-a961-49bd-b1a6-55a4dea4685f.png)\n\n- Create 1_lambda.tf:\n \n```\nterraform {\n  required_providers {\n    aws = {\n      source  = \"hashicorp/aws\"\n      version = \"~> 4.16\"\n    }\n  }\n  required_version = \">= 1.2.0\"\n}\n\n# Create IAM Role for lambda\nresource \"aws_iam_role\" \"lambda_role\" {\n name   = \"aws_lambda_role\"\n assume_role_policy = <<EOF\n{\n  \"Version\": \"2012-10-17\",\n  \"Statement\": [\n    {\n      \"Action\": \"sts:AssumeRole\",\n      \"Principal\": {\n        \"Service\": \"lambda.amazonaws.com\"\n      },\n      \"Effect\": \"Allow\",\n      \"Sid\": \"\"\n    }\n  ]\n}\nEOF\n}\n\n# IAM policy for the lambda\nresource \"aws_iam_policy\" \"iam_policy_for_lambda\" {\n\n  name         = \"aws_iam_policy_for_aws_lambda_role\"\n  path         = \"/\"\n  description  = \"AWS IAM Policy for managing aws lambda role\"\n  policy = <<EOF\n{\n  \"Version\": \"2012-10-17\",\n  \"Statement\": [\n    {\n      \"Action\": [\n        \"logs:CreateLogGroup\",\n        \"logs:CreateLogStream\",\n        \"logs:PutLogEvents\"\n      ],\n      \"Resource\": \"arn:aws:logs:*:*:*\",\n      \"Effect\": \"Allow\"\n    }\n  ]\n}\nEOF\n}\n\n# Role - Policy Attachment\nresource \"aws_iam_role_policy_attachment\" \"attach_iam_policy_to_iam_role\" {\n  role        = aws_iam_role.lambda_role.name\n  policy_arn  = aws_iam_policy.iam_policy_for_lambda.arn\n}\n\n# Getting data existed ECR\ndata \"aws_ecr_repository\" \"flask_app_serverless\" {\n  name = \"flask-app-serverless\"\n}\n\n# Lambda Function, in terraform ${path.module} is the current directory.\nresource \"aws_lambda_function\" \"lambda_function\" {\n function_name = \"Lambda-Function\"\n role          = aws_iam_role.lambda_role.arn\n # tag is required, \"source image ... is not valid\" error will pop up\n image_uri     = \"${data.aws_ecr_repository.flask_app_serverless.repository_url}:latest\"\n package_type  = \"Image\"\n depends_on    = [aws_iam_role_policy_attachment.attach_iam_policy_to_iam_role]\n}\n\n# With Lambda permission, API Gateway can invoke Lambda \nresource \"aws_lambda_permission\" \"apigw\" {\n statement_id  = \"AllowAPIGatewayInvoke\"\n action        = \"lambda:InvokeFunction\"\n function_name = aws_lambda_function.lambda_function.function_name\n principal     = \"apigateway.amazonaws.com\"\n # The \"/*/*\" portion grants access from any method on any resource within the API Gateway REST API.\n source_arn = \"${aws_api_gateway_rest_api.example.execution_arn}/*/*\"\n}\n```\n\n**Code:** https://github.com/omerbsezer/Fast-Terraform/blob/main/samples/lambda-container-apigateway-flaskapp/1_lambda.tf\n\n![image](https://user-images.githubusercontent.com/10358317/232438855-8cf0d0f9-31fd-43b7-a2c2-0ec29970c59b.png)\n\n### Creating API Gateway <a name=\"apigateway\"></a>\n\n- Create 2_api_gateway.tf:\n \n```\n# Create API Gateway with Rest API type\nresource \"aws_api_gateway_rest_api\" \"example\" {\n  name        = \"Serverless\"\n  description = \"Serverless Application using Terraform\"\n}\n\nresource \"aws_api_gateway_resource\" \"proxy\" {\n   rest_api_id = aws_api_gateway_rest_api.example.id\n   parent_id   = aws_api_gateway_rest_api.example.root_resource_id\n   path_part   = \"{proxy+}\"     # with proxy, this resource will match any request path\n}\n\nresource \"aws_api_gateway_method\" \"proxy\" {\n   rest_api_id   = aws_api_gateway_rest_api.example.id\n   resource_id   = aws_api_gateway_resource.proxy.id\n   http_method   = \"ANY\"       # with ANY, it allows any request method to be used, all incoming requests will match this resource\n   authorization = \"NONE\"\n}\n\n# API Gateway - Lambda Connection\nresource \"aws_api_gateway_integration\" \"lambda\" {\n   rest_api_id = aws_api_gateway_rest_api.example.id\n   resource_id = aws_api_gateway_method.proxy.resource_id\n   http_method = aws_api_gateway_method.proxy.http_method\n   integration_http_method = \"POST\"\n   type                    = \"AWS_PROXY\"  # With AWS_PROXY, it causes API gateway to call into the API of another AWS service\n   uri                     = aws_lambda_function.lambda_function.invoke_arn\n}\n\n# The proxy resource cannot match an empty path at the root of the API. \n# To handle that, a similar configuration must be applied to the root resource that is built in to the REST API object\nresource \"aws_api_gateway_method\" \"proxy_root\" {\n   rest_api_id   = aws_api_gateway_rest_api.example.id\n   resource_id   = aws_api_gateway_rest_api.example.root_resource_id\n   http_method   = \"ANY\"\n   authorization = \"NONE\"\n}\n\nresource \"aws_api_gateway_integration\" \"lambda_root\" {\n   rest_api_id = aws_api_gateway_rest_api.example.id\n   resource_id = aws_api_gateway_method.proxy_root.resource_id\n   http_method = aws_api_gateway_method.proxy_root.http_method\n   integration_http_method = \"POST\"\n   type                    = \"AWS_PROXY\"  # With AWS_PROXY, it causes API gateway to call into the API of another AWS service\n   uri                     = aws_lambda_function.lambda_function.invoke_arn\n}\n\n# Deploy API Gateway\nresource \"aws_api_gateway_deployment\" \"example\" {\n   depends_on = [\n     aws_api_gateway_integration.lambda,\n     aws_api_gateway_integration.lambda_root,\n   ]\n   rest_api_id = aws_api_gateway_rest_api.example.id\n   stage_name  = \"test\"\n}\n\n# Output to the URL \noutput \"base_url\" {\n  value = aws_api_gateway_deployment.example.invoke_url\n}\n```\n\n**Code:** https://github.com/omerbsezer/Fast-Terraform/blob/main/samples/lambda-container-apigateway-flaskapp/2_api_gateway.tf\n\n![image](https://user-images.githubusercontent.com/10358317/232439028-4659f2ab-27aa-4f7a-843e-355bcd53037b.png)\n\n### Demo: Terraform Run <a name=\"run\"></a>\n\n- Run:\n \n```\nterraform init\nterraform validate\nterraform plan\nterraform apply\n```\n\n![image](https://user-images.githubusercontent.com/10358317/232347038-4b86203f-a61c-4e31-9d3c-086b789b53e2.png)\n\n- On AWS Lambda, new Lambda function is created:\n\n  ![image](https://user-images.githubusercontent.com/10358317/232347067-959a2fd3-f151-4cf8-91e8-6d1f092b5062.png)\n  \n- This time, Container is running on the Lambda:\n\n  ![image](https://user-images.githubusercontent.com/10358317/232347172-1f4f0a52-0dc5-406d-9ba1-babc5c71c73d.png)\n  \n- On AWS API-Gateway, new API is created:\n\n  ![image](https://user-images.githubusercontent.com/10358317/232347258-ba322926-e628-4a62-9cf6-7f95c5a7c72e.png)\n  \n- Flask App is running in container, container is running on Lambda:\n\n  ![image](https://user-images.githubusercontent.com/10358317/232347302-da720c4a-da30-4ea7-a567-06b2d10686c3.png)\n  \n- Edit posts with \"Edit\" button, new post with \"New Post\", Delete post with \"Delete Post\".\n- Copied DB file into the \"/tmp/\" directory to get write permission. Lambda allows only the files under \"/tmp/\" to have write permission.\n\n  ![image](https://user-images.githubusercontent.com/10358317/232347487-b61b8383-93e0-4a92-a56c-035b7ed1d0c7.png)\n\n  ![image](https://user-images.githubusercontent.com/10358317/232347570-82dc83e3-a869-488f-ba51-2446e555b6d2.png)\n  \n- CloudWatch automatically logs the Lambda. If there is a debug issue, view the log groups under the Cloud Watch.\n\n  ![image](https://user-images.githubusercontent.com/10358317/232348787-fda0e125-c6ed-4504-9e37-138501412838.png)\n \n- Destroy the infra:\n\n```\nterraform destroy\n```\n\n![image](https://user-images.githubusercontent.com/10358317/232347666-f2464a4d-85a7-49d2-bee4-c6062d886c22.png)\n\n- Delete the ECR Repo:\n\n```\ncd ecr\nterraform destroy\n```\n\n![image](https://user-images.githubusercontent.com/10358317/232347728-ea8c3c13-4b22-4be3-bdba-b33a43023208.png)\n"
  },
  {
    "path": "SAMPLE06-EKS-ManagedNodes-Blueprint.md",
    "content": "## SAMPLE-06: Provisioning EKS (Elastic Kubernetes Service) with Managed Nodes using Blueprint and Modules \n\nThis sample shows:\n- how to create EKS cluster with managed nodes using BluePrints and Modules.\n\n**Notes:**\n- EKS Blueprint is used to provision EKS cluster with managed nodes easily. \n- TF file creates 65 Resources, it takes ~30 mins to provision cluster.\n- EKS Blueprint is used from: \n  - https://github.com/aws-ia/terraform-aws-eks-blueprints\n- Gameserver example is updated and run: \n  - https://github.com/aws-ia/terraform-aws-eks-blueprints/tree/main/examples/agones-game-controller \n\nThere are 1 main part:\n- **main.tf**: includes:\n  - EKS module: 2 managed nodes, 1 ASG for managed nodes, 1 Elastic IP, 3 SGs\n  - EKS addon module: metrics_server, cluster_autoscaler\n  - VPC module: 1 VPC, 6 Subnets (3 Public, 3 Private), 3 Route Tables, 1 IGW, 1 NAT, 1 NACL \n\n**Code:** https://github.com/omerbsezer/Fast-Terraform/tree/main/samples/eks-managed-node-blueprint\n\n**EKS Pricing:**\n- For the Cluster (Managed Control Plane):\n  - **Per Hour:** $0.10 per for each Amazon EKS cluster\n  - **Per Day:**  $2.4\n  - **For 30 days:** $72\n- For the 1 Worker Node Linux (e.g. m5.large => 2 vCPU, 8 GB RAM):\n  - **Per Hour:** $0.096  \n  - **Per Day:**  $2.304\n  - **For 30 days:** $69.12\n  - Please have look for instance pricing: https://aws.amazon.com/ec2/pricing/on-demand/ \n- For the Fargate: \n  - AWS Fargate pricing is calculated based on the **vCPU and memory** resources used from the time you start to download your container image until the EKS Pod terminate.\n    - e.g. 2 x (1vCPU, 4GB RAM) on Linux: \n      - **Per Hour:** 2 x ($0,0665) = $0.133\n      - **Per Day:** $3,18\n      - **Per 30 Days:** $95.67\n    - e.g. 2 x (1vCPU, 4GB RAM) on Win: \n      - **Per Hour:** 2 x ($0,199) = $0.398\n      - **Per Day:** $9.55\n      - **Per 30 Days:** $286.56\n  - Please have look for fargate pricing: https://aws.amazon.com/fargate/pricing/ \n- https://cloudonaut.io/versus/docker-containers/eks-fargate-vs-eks-managed-node-group/\n- https://cloudonaut.io/versus/docker-containers/ecs-fargate-vs-eks-managed-node-group/ \n\n### Prerequisite\n\n- You should have a look following lab: \n  - [LAB-00: Terraform Install, AWS Configuration with Terraform](https://github.com/omerbsezer/Fast-Terraform/blob/main/LAB00-Terraform-Install-AWS-Configuration.md)\n\n## Steps\n\n- Create main.tf:\n \n```\nterraform {\n  required_providers {\n   aws = {\n      source  = \"hashicorp/aws\"\n      version = \">= 4.47\"\n    }\n    kubernetes = {\n      source  = \"hashicorp/kubernetes\"\n      version = \">= 2.10\"\n    }\n    helm = {\n      source  = \"hashicorp/helm\"\n      version = \">= 2.4.1\"\n    }\n  }\n  required_version = \">= 1.2.0\"\n}\n\nprovider \"aws\" {\n  region = local.region\n}\n\nprovider \"kubernetes\" {\n  host                   = module.eks.cluster_endpoint\n  cluster_ca_certificate = base64decode(module.eks.cluster_certificate_authority_data)\n  token                  = data.aws_eks_cluster_auth.this.token\n}\n\nprovider \"helm\" {\n  kubernetes {\n    host                   = module.eks.cluster_endpoint\n    cluster_ca_certificate = base64decode(module.eks.cluster_certificate_authority_data)\n    token                  = data.aws_eks_cluster_auth.this.token\n  }\n}\n\ndata \"aws_eks_cluster_auth\" \"this\" {\n  name = module.eks.cluster_name\n}\n\ndata \"aws_availability_zones\" \"available\" {}\n\nlocals {\n  name   = basename(path.cwd)\n  region = \"eu-central-1\"\n\n  cluster_version = \"1.24\"\n\n  vpc_cidr = \"10.0.0.0/16\"\n  azs      = slice(data.aws_availability_zones.available.names, 0, 3)\n\n  tags = {\n    Blueprint  = local.name\n    GithubRepo = \"github.com/aws-ia/terraform-aws-eks-blueprints\"\n  }\n}\n\n################################################################################\n# Cluster\n################################################################################\n\n#tfsec:ignore:aws-eks-enable-control-plane-logging\nmodule \"eks\" {\n  source  = \"terraform-aws-modules/eks/aws\"\n  version = \"~> 19.12\"\n\n  cluster_name                   = local.name\n  cluster_version                = local.cluster_version\n  cluster_endpoint_public_access = true\n\n  # EKS Addons\n  cluster_addons = {\n    coredns    = {}\n    kube-proxy = {}\n    vpc-cni    = {}\n  }\n\n  vpc_id     = module.vpc.vpc_id\n  subnet_ids = module.vpc.private_subnets\n\n  eks_managed_node_groups = {\n    initial = {\n      instance_types = [\"m5.large\"]\n\n      min_size     = 1\n      max_size     = 3\n      desired_size = 2\n    }\n  }\n\n  tags = local.tags\n}\n\n################################################################################\n# Kubernetes Addons\n################################################################################\n\nmodule \"eks_blueprints_kubernetes_addons\" {\n  source = \"github.com/aws-ia/terraform-aws-eks-blueprints/modules/kubernetes-addons\"\n  \n  eks_cluster_id       = module.eks.cluster_name\n  eks_cluster_endpoint = module.eks.cluster_endpoint\n  eks_oidc_provider    = module.eks.oidc_provider\n  eks_cluster_version  = module.eks.cluster_version\n\n  # Add-ons\n  enable_metrics_server     = true\n  enable_cluster_autoscaler = true\n  eks_worker_security_group_id = module.eks.cluster_security_group_id\n\n  tags = local.tags\n}\n\n################################################################################\n# Supporting Resources\n################################################################################\n\nmodule \"vpc\" {\n  source  = \"terraform-aws-modules/vpc/aws\"\n  version = \"~> 4.0\"\n\n  name = local.name\n  cidr = local.vpc_cidr\n\n  azs             = local.azs\n  private_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 4, k)]\n  public_subnets  = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 48)]\n\n  enable_nat_gateway = true\n  single_nat_gateway = true\n\n  public_subnet_tags = {\n    \"kubernetes.io/role/elb\" = 1\n  }\n\n  private_subnet_tags = {\n    \"kubernetes.io/role/internal-elb\" = 1\n  }\n\n  tags = local.tags\n}\n\noutput \"configure_kubectl\" {\n  description = \"Configure kubectl: make sure you're logged in with the correct AWS profile and run the following command to update your kubeconfig\"\n  value       = \"aws eks --region ${local.region} update-kubeconfig --name ${module.eks.cluster_name}\"\n}\n```\n\n**Code:** https://github.com/omerbsezer/Fast-Terraform/blob/main/samples/eks-managed-node-blueprint/main.tf\n\n![image](https://user-images.githubusercontent.com/10358317/233113882-6b81b0ca-d35a-42da-b1c0-4b5236375ddf.png)\n\n### Demo: Terraform Run <a name=\"run\"></a>\n\n- Run:\n \n```\nterraform init\nterraform validate\nterraform plan\nterraform apply\n```\n\n![image](https://user-images.githubusercontent.com/10358317/233094869-ac12920c-d536-476a-b283-306c1846a3d7.png)\n\n- Run to add cluster into your kubeconfig:\n\n```\naws eks --region eu-central-1 update-kubeconfig --name eks-managed-node\n```\n\n![image](https://user-images.githubusercontent.com/10358317/233095399-80e169b6-de30-446e-84c2-7745655179a3.png)\n\n- To see nodes, pods\n\n```\nkubectl get nodes -o wide\nkubectl get pods -o wide --all-namespaces\n```\n\n![image](https://user-images.githubusercontent.com/10358317/233095954-d3745626-eebc-483a-b298-c6d829ce7979.png)\n\n- Create test pod (nginx)\n\n```\nkubectl run my-nginx --image=nginx\nkubectl get pods -o wide --all-namespaces\n```\n\n![image](https://user-images.githubusercontent.com/10358317/233096322-d9738e2e-5ea5-4187-8763-d9cabd27ffd7.png)\n\n![image](https://user-images.githubusercontent.com/10358317/233096504-a991ed50-5a85-4f46-bc33-b795237f26b4.png)\n\n- Enter the pod using sh:\n\n```\nkubectl exec -it my-nginx -- sh\n```\n\n![image](https://user-images.githubusercontent.com/10358317/233097613-f81a3773-97cc-4795-aab0-82795417b270.png)\n\n- On AWS EKS:\n\n  ![image](https://user-images.githubusercontent.com/10358317/233097928-5db41f20-f491-491d-bf09-08c38df7ec66.png)\n  \n- Cluster Pod:\n\n  ![image](https://user-images.githubusercontent.com/10358317/233098383-57785983-298a-41d6-8bdb-54f6f80eff47.png)\n  \n- Cluster Deployments:\n\n  ![image](https://user-images.githubusercontent.com/10358317/233098742-86803d33-1565-4577-aee5-ef86f74b7717.png)\n \n- By using kubectl, details can be viewed:\n\n  ![image](https://user-images.githubusercontent.com/10358317/233099053-5087c41a-2366-42c8-8b0f-235edb7c8325.png)\n  \n- Cluster Nodes:\n\n  ![image](https://user-images.githubusercontent.com/10358317/233099628-31296830-ef25-4d1b-b582-92f6cf936600.png)\n\n- Because of the min_size=1, one of the managed node was terminated automatically.\n```\neks_managed_node_groups = {\n    initial = {\n      instance_types = [\"m5.large\"]\n\n      min_size     = 1\n      max_size     = 3\n      desired_size = 2\n    }\n  }\n```\n\n- On AWS EKS:\n\n  ![image](https://user-images.githubusercontent.com/10358317/233104836-bdc1a075-e27b-45b0-8fb2-262e73814f47.png)\n\n- API Services: \n\n  ![image](https://user-images.githubusercontent.com/10358317/233100299-05267ceb-559b-4c11-9876-d427192b50bc.png)\n\n- All details about the K8s can be viewed on AWS GUI:\n\n  ![image](https://user-images.githubusercontent.com/10358317/233100875-4b47facd-a02e-4f93-9431-68556e3d7c52.png)\n\n- On AWS VPC (1 VPC, 3 public subnets, 3 private subnets):\n\n  ![image](https://user-images.githubusercontent.com/10358317/233101406-d1ec1fe1-0359-4b24-9d66-c3e45aa2a911.png)\n\n- On AWS EC2 Instance: \n\n  ![image](https://user-images.githubusercontent.com/10358317/233101685-89e5780e-57d9-4720-bb16-ece80092060b.png)\n\n- On AWS Elastic IP:\n\n  ![image](https://user-images.githubusercontent.com/10358317/233102192-efce23f0-b2f0-48ec-9530-14210f6c6525.png)\n\n- In addition, these are created: 3 Route Tables, 1 IGW, 1 NAT, 1 Elastic IP, 1 NACL, 1 ASG for managed nodes\n\n  ![image](https://user-images.githubusercontent.com/10358317/233104088-376aa429-3502-4347-8cdd-a176ed3bdc74.png)\n\n- To clean up your environment, destroy the Terraform modules in reverse order.\n- Destroy the Kubernetes Add-ons, EKS cluster with Node groups and VPC:\n\n```\nterraform destroy -target=\"module.eks_blueprints_kubernetes_addons\" -auto-approve\n```\n\n  ![image](https://user-images.githubusercontent.com/10358317/233106155-b4e43456-2852-4476-bb05-8e734abb3ba4.png)\n\n- Destroy EKS (managed node) (takes ~12-15 mins):\n\n```\nterraform destroy -target=\"module.eks\" -auto-approve\n```\n\n![image](https://user-images.githubusercontent.com/10358317/233111468-092cff32-9555-4814-8a80-10678b590d12.png)\n\n- Destroy VPC:\n\n```\nterraform destroy -target=\"module.vpc\" -auto-approve\n```\n\n![image](https://user-images.githubusercontent.com/10358317/233110739-72c833a1-6347-4e9a-be33-5f4d93f7990f.png)\n\n\n- Finally, destroy any additional resources that are not in the above modules\n\n```\nterraform destroy -auto-approve\n```\n\n## References\n- https://github.com/aws-ia/terraform-aws-eks-blueprints\n- https://github.com/aws-ia/terraform-aws-eks-blueprints/tree/main/examples/agones-game-controller\n"
  },
  {
    "path": "SAMPLE07-CodeCommit-Pipeline-Build-Deploy-Lambda.md",
    "content": "## SAMPLE-07: CI/CD on AWS => Provisioning CodeCommit and CodePipeline, Triggering CodeBuild and CodeDeploy on Lambda Container\n\nThis sample shows:\n- how to create code repository using CodeCommit,\n- how to create pipeline with CodePipeline, create S3 bucket to store Artifacts for codepipeline stages' connection (source, build, deploy),\n- how to create builder with CodeBuild ('buildspec_build.yaml'), build the source code, create a Docker image,\n- how to create ECR (Elastic Container Repository) and push the build image into the ECR,\n- how to create Lambda Function (by CodeBuild automatically) and run/deploy container on Lambda ('buildspec_deploy.yaml').\n\n**Notes:**\n- Source code is pulled from:\n  - https://github.com/aws-samples/codepipeline-for-lambda-using-terraform\n- Some of the fields are updated. \n- It works with 'hashicorp/aws ~> 4.15.1', 'terraform >= 0.15'\n\n**Code:** https://github.com/omerbsezer/Fast-Terraform/tree/main/samples/codecommit-codepipeline-codebuild-codedeploy-lambda-container\n\n![image](https://user-images.githubusercontent.com/10358317/233652299-66b39788-66ee-4a5e-b8e0-ece418fe98e3.png)\n\n# Table of Contents\n- [Main Part](#main_part)\n- [CodeCommit Module](#codecommit)\n- [CodePipeline Module](#codepipeline)\n- [ECR Module](#ecr)\n- [Lambda Part](#lambda)\n- [Demo: Terraform Run](#run)\n\n### Prerequisite\n\n- You should have a look following lab: \n  - [LAB-00: Terraform Install, AWS Configuration with Terraform](https://github.com/omerbsezer/Fast-Terraform/blob/main/LAB00-Terraform-Install-AWS-Configuration.md)\n\n## Steps\n\n- Code:\n\n![image](https://user-images.githubusercontent.com/10358317/233652134-e5c732c0-1c88-4244-b321-b8f777476c85.png)\n\n### Main Part <a name=\"main_part\"></a>\n\n- Create main.tf:\n \n```\nlocals {\n  env_namespace         = join(\"_\", [var.org_name, var.team_name, var.project_id, var.env[\"dev\"]])\n  general_namespace     = join(\"_\", [var.org_name, var.team_name, var.project_id])\n  #s3 bucket naming based on best practices: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html\n  s3_bucket_namespace   = join(\"-\", [var.org_name, var.team_name, var.project_id, var.env[\"dev\"]])\n}\ndata \"aws_caller_identity\" \"current\" {}\nmodule \"codepipeline\" {\n  source                 = \"./modules/codepipeline\"\n  general_namespace      = local.general_namespace\n  env_namespace          = local.env_namespace\n  s3_bucket_namespace    = local.s3_bucket_namespace\n  codecommit_repo        = module.codecommit.codecommit_configs.repository_name\n  codecommit_branch      = module.codecommit.codecommit_configs.default_branch\n  codebuild_image        = var.codebuild_image\n  codebuild_type         = var.codebuild_type\n  codebuild_compute_type = var.codebuild_compute_type\n  ecr_repo_arn           = module.ecr.ecr_configs.ecr_repo_arn\n  build_args = [\n    {\n      name  = \"REPO_URI\"\n      value = module.ecr.ecr_configs.ecr_repo_url\n    },\n    {\n      name  = \"REPO_ARN\"\n      value = module.ecr.ecr_configs.ecr_repo_arn\n    },\n    {\n      name  = \"TERRAFORM_VERSION\"\n      value = var.terraform_ver\n    },\n    {\n      name  = \"ENV_NAMESPACE\"\n      value = local.env_namespace\n    },\n    {\n      name  = \"AWS_ACCOUNT_ID\"\n      value = data.aws_caller_identity.current.account_id\n    }\n  ]\n}\n\nmodule \"codecommit\" {\n  source            = \"./modules/codecommit\"\n  general_namespace = local.general_namespace\n  env_namespace     = local.env_namespace\n  codecommit_branch = var.codecommit_branch\n}\n\nmodule \"ecr\" {\n  source            = \"./modules/ecr\"\n  general_namespace = local.general_namespace\n  env_namespace     = local.env_namespace\n}\n```\n\n**Code:** https://github.com/omerbsezer/Fast-Terraform/blob/main/samples/codecommit-codepipeline-codebuild-codedeploy-lambda-container/main.tf\n\n![image](https://user-images.githubusercontent.com/10358317/233831575-895408b8-0929-4125-9716-96675f3878f0.png)\n\n- Create output.tf:\n\n```\noutput \"codepipeline\" {\n    value = module.codepipeline.codepipeline_configs.codepipeline\n}\noutput \"codecommit\" {\n    value = module.codecommit.codecommit_configs.clone_repository_url\n}\noutput \"ecrrepo\" {\n    value = module.ecr.ecr_configs.ecr_repo_url\n}\n```\n\n**Code:** https://github.com/omerbsezer/Fast-Terraform/blob/main/samples/codecommit-codepipeline-codebuild-codedeploy-lambda-container/outputs.tf\n\n![image](https://user-images.githubusercontent.com/10358317/233831613-28d0dc5d-2299-4862-84e2-ce5a4d220c13.png)\n\n- Create providers.tf:\n\n```\nprovider \"aws\" {\n  region = \"eu-central-1\"\n}\n\nterraform {\n  required_version = \">= 0.15\"\n  required_providers {\n    aws = {\n      source  = \"hashicorp/aws\"\n      version = \"~> 4.15.1\"\n      # Will allow installation of 4.15.1 and 4.15.10 but not 4.16.0\n      # Get error when using 4.16.0\n    }\n  }\n}\n```\n\n**Code:** https://github.com/omerbsezer/Fast-Terraform/blob/main/samples/codecommit-codepipeline-codebuild-codedeploy-lambda-container/providers.tf\n\n![image](https://user-images.githubusercontent.com/10358317/233831633-549163df-5e40-4f6d-a025-f6c70e726a41.png)\n\n- Create terraform.tfvars:\n\n```\norg_name   = \"org\"\nteam_name  = \"awsteam\"\nproject_id = \"lambda\"\nregion     = \"eu-central-1\"\nenv = {\n  \"dev\" = \"dev\"\n  \"qa\"  = \"qa\"\n}\ncodebuild_compute_type = \"BUILD_GENERAL1_MEDIUM\"\ncodebuild_image        = \"aws/codebuild/amazonlinux2-x86_64-standard:3.0\"\ncodebuild_type         = \"LINUX_CONTAINER\"\ncodecommit_branch      = \"master\"\n```\n\n**Code:** https://github.com/omerbsezer/Fast-Terraform/blob/main/samples/codecommit-codepipeline-codebuild-codedeploy-lambda-container/terraform.tfvars\n\n![image](https://user-images.githubusercontent.com/10358317/233831672-ad9901a6-3706-4527-a301-f8d0659c1805.png)\n\n- Create variables.tf:\n\n```\nvariable \"org_name\" {\n  description = \"Your Organization name\"\n  type        = string\n}\nvariable \"team_name\" {\n  description = \"Your Team name\"\n  type        = string\n}\nvariable \"project_id\" {\n  description = \"Your Project ID\"\n  type        = string\n}\nvariable \"env\" {\n  description = \"Your deployment environment\"\n  type        = map(any)\n  default = {\n    \"dev\" = \"dev\"\n  }\n}\nvariable \"region\" {\n  description = \"Your AWS Region\"\n  type        = string\n}\nvariable \"codebuild_type\" {\n  description = \"Your CodeBuild Project Type\"\n  type        = string\n}\nvariable \"codebuild_image\" {\n  description = \"Your CodeBuild Project Image\"\n  type        = string\n}\nvariable \"codebuild_compute_type\" {\n  description = \"Your CodeBuild Project Compute Type\"\n  type        = string\n}\nvariable \"codecommit_branch\" {\n  description = \"Your CodeCommit Branch\"\n  type        = string\n}\nvariable \"terraform_ver\" {\n    description = \"Terraform Version number for passing it to codebuild\"\n    default     = \"1.2.2\"\n    type        = string\n}\n```\n\n**Code:** https://github.com/omerbsezer/Fast-Terraform/blob/main/samples/codecommit-codepipeline-codebuild-codedeploy-lambda-container/variables.tf\n\n![image](https://user-images.githubusercontent.com/10358317/233831701-4d1d1357-ea2e-400d-b53d-da08acf9cd12.png)\n\n### CodeCommit Module <a name=\"codecommit\"></a>\n\n- Create main.tf:\n\n```\ndata \"aws_caller_identity\" \"current\" {}\nresource \"aws_codecommit_repository\" \"codecommit_repo\" {\n  repository_name = \"${var.general_namespace}_code_repo\"\n  default_branch  = \"${var.codecommit_branch}\"\n  description     = \"Application repo for lambda ${var.general_namespace}\"\n}\n```\n\n**Code:** https://github.com/omerbsezer/Fast-Terraform/blob/main/samples/codecommit-codepipeline-codebuild-codedeploy-lambda-container/modules/codecommit/main.tf\n\n![image](https://user-images.githubusercontent.com/10358317/233831728-26ce5e78-3738-4be6-bf1b-8d67bd605817.png)\n\n- Create outputs.tf:\n\n```\noutput \"codecommit_configs\" {\n    value = {\n        repository_name         = aws_codecommit_repository.codecommit_repo.repository_name\n        default_branch          = aws_codecommit_repository.codecommit_repo.default_branch\n        clone_repository_url    = aws_codecommit_repository.codecommit_repo.clone_url_http\n    }\n}\n```\n\n**Code:** https://github.com/omerbsezer/Fast-Terraform/blob/main/samples/codecommit-codepipeline-codebuild-codedeploy-lambda-container/modules/codecommit/outputs.tf\n\n![image](https://user-images.githubusercontent.com/10358317/233831757-a363b671-be88-4ac3-a5a8-13cd2e870491.png)\n\n- Create variables.tf:\n\n```\nvariable \"codecommit_branch\" {\n    type = string\n    default = \"master\"\n}\nvariable \"general_namespace\" {\n    type = string\n}\nvariable \"env_namespace\" {\n    type = string\n}\n```\n\n**Code:** https://github.com/omerbsezer/Fast-Terraform/blob/main/samples/codecommit-codepipeline-codebuild-codedeploy-lambda-container/modules/codecommit/variables.tf\n\n![image](https://user-images.githubusercontent.com/10358317/233831783-fdec8f23-5d03-44a4-8b1a-824581a21af0.png)\n\n### CodePipeline Module <a name=\"codepipeline\"></a>\n\n- Create main.tf\n\n```\nlocals {\n  projects  = [\"build\", \"deploy\"]\n}\nresource \"aws_s3_bucket\" \"codepipeline_bucket\" {\n  bucket = \"${var.s3_bucket_namespace}-codepipeline-bucket\"\n}\n\nresource \"aws_s3_bucket_acl\" \"codepipeline_bucket_acl\" {\n  bucket = aws_s3_bucket.codepipeline_bucket.id\n  acl    = \"private\"\n}\n\nresource \"aws_codebuild_project\" \"project\" {\n    count           = length(local.projects)\n    name            = \"${var.env_namespace}_${local.projects[count.index]}\"\n    #name           = \"${var.org}_${var.name}_${var.attribute}_${var.env[\"dev\"]}_codebuild_docker_build\"\n    build_timeout   = \"5\" #The default is 60 minutes.\n    service_role    = aws_iam_role.lambda_codebuild_role.arn\n    artifacts {\n        type = \"CODEPIPELINE\"\n    }\n    environment {\n      compute_type                = var.codebuild_compute_type\n      image                       = var.codebuild_image\n      type                        = var.codebuild_type\n      #compute_type               = \"BUILD_GENERAL1_MEDIUM\"\n      #image                      = \"aws/codebuild/amazonlinux2-x86_64-standard:3.0\"\n      #type                       = \"LINUX_CONTAINER\"\n      image_pull_credentials_type = \"CODEBUILD\"\n      privileged_mode             = true\n\n      dynamic \"environment_variable\" {\n        for_each = var.build_args\n        content {\n          name  = environment_variable.value.name\n          value = environment_variable.value.value\n        }\n      }\n    }\n    source {\n        type      = \"CODEPIPELINE\"\n        buildspec = file(\"${path.module}/templates/buildspec_${local.projects[count.index]}.yml\")\n        #buildspec = file(\"${path.module}/stage1-buildspec.yml\")\n    }\n\n    source_version = \"master\"\n\n    tags = {\n        env = var.env_namespace\n    }\n}\n\nresource \"aws_codepipeline\" \"codepipeline\" {\n  name     = \"${var.env_namespace}_pipeline\"\n  role_arn = aws_iam_role.lambda_codepipeline_role.arn\n\n  artifact_store {\n    location = aws_s3_bucket.codepipeline_bucket.bucket\n    type     = \"S3\"\n  }\n\n  stage {\n    name = \"Source\"\n\n    action {\n      name     = \"Source\"\n      category = \"Source\"\n      owner    = \"AWS\"\n      provider = \"CodeCommit\"\n      version  = \"1\"\n      output_artifacts = [\n      \"source_output\"]\n\n      configuration = {\n        #BranchName     = aws_codecommit_repository.lambda_codecommit_repo.default_branch\n        BranchName      = var.codecommit_branch\n        RepositoryName  = var.codecommit_repo\n        #RepositoryName = aws_codecommit_repository.lambda_codecommit_repo.repository_name\n      }\n    }\n  }\n\n  stage {\n    name = \"Build\"\n\n    action {\n      name     = \"Docker_Build\"\n      category = \"Build\"\n      owner    = \"AWS\"\n      provider = \"CodeBuild\"\n      input_artifacts = [\n      \"source_output\"]\n      version = \"1\"\n\n      configuration = {\n        ProjectName = aws_codebuild_project.project[0].name\n      }\n    }\n  }\n\n  stage {\n    name = \"Deploy\"\n\n    action {\n      name     = \"Deploy_Docker\"\n      category = \"Build\"\n      owner    = \"AWS\"\n      provider = \"CodeBuild\"\n      input_artifacts = [\n      \"source_output\"]\n      version = \"1\"\n\n      configuration = {\n        ProjectName = aws_codebuild_project.project[1].name\n      }\n    }\n  }\n}\n```\n\n**Code:** https://github.com/omerbsezer/Fast-Terraform/blob/main/samples/codecommit-codepipeline-codebuild-codedeploy-lambda-container/modules/codepipeline/main.tf\n\n![image](https://user-images.githubusercontent.com/10358317/233831984-3bcab992-17a0-413b-bf1e-f38289a959a2.png)\n\n![image](https://user-images.githubusercontent.com/10358317/233832006-949a9c52-d266-4150-97c7-0305cceddc08.png)\n\n- Create outputs.tf\n\n```\noutput \"codepipeline_configs\" {\n    value = {\n        codepipeline = aws_codepipeline.codepipeline.arn\n    }\n}\noutput \"deployment_role_arn\" {\n    value = aws_iam_role.lambda_codebuild_role.arn\n}\n```\n\n**Code:** https://github.com/omerbsezer/Fast-Terraform/blob/main/samples/codecommit-codepipeline-codebuild-codedeploy-lambda-container/modules/codepipeline/outputs.tf\n\n![image](https://user-images.githubusercontent.com/10358317/233832055-65f1b99b-4a16-47b7-9c01-b88d3ec256d8.png)\n\n- Create roles.tf\n\n```\nresource \"aws_iam_role\" \"lambda_codepipeline_role\" {\n  name = \"${var.env_namespace}_codepipeline_role\"\n\n  assume_role_policy = <<EOF\n{\n  \"Version\": \"2012-10-17\",\n  \"Statement\": [\n    {\n      \"Effect\": \"Allow\",\n      \"Principal\": {\n        \"Service\": \"codepipeline.amazonaws.com\"\n      },\n      \"Action\": \"sts:AssumeRole\"\n    }\n  ]\n}\nEOF\n}\n\nresource \"aws_iam_role_policy\" \"lambda_codepipeline_policy\" {\n  name = \"${var.env_namespace}_codepipeline_policy\"\n  role = aws_iam_role.lambda_codepipeline_role.id\n\n  policy = <<EOF\n{\n  \"Version\": \"2012-10-17\",\n  \"Statement\": [\n    {\n      \"Effect\":\"Allow\",\n      \"Action\": [\n        \"s3:GetObject\",\n        \"s3:GetObjectVersion\",\n        \"s3:GetBucketVersioning\",\n        \"s3:PutObject\"\n      ],\n      \"Resource\": [\n        \"${aws_s3_bucket.codepipeline_bucket.arn}\",\n        \"${aws_s3_bucket.codepipeline_bucket.arn}/*\"\n      ]\n    },\n    {\n      \"Effect\": \"Allow\",\n      \"Action\": [\n        \"codebuild:*\",\n        \"codecommit:*\"\n      ],\n      \"Resource\": \"*\"\n    }\n  ]\n}\nEOF\n}\n\nresource \"aws_iam_role\" \"lambda_codebuild_role\" {\n  name               = \"${var.env_namespace}_codebuild_role\"\n  assume_role_policy = <<EOF\n{\n  \"Version\": \"2012-10-17\",\n  \"Statement\": [\n    {\n      \"Effect\": \"Allow\",\n      \"Principal\": {\n        \"Service\": \"codebuild.amazonaws.com\"\n      },\n      \"Action\": \"sts:AssumeRole\"\n    }\n  ]\n}\nEOF\n}\n\nresource \"aws_iam_role_policy\" \"lambda_codebuild_role_policy\" {\n  role   = aws_iam_role.lambda_codebuild_role.name\n  policy = <<POLICY\n{\n  \"Version\": \"2012-10-17\",\n  \"Statement\": [\n    {\n      \"Effect\": \"Allow\",\n      \"Resource\": [\n        \"*\"\n      ],\n      \"Action\": [\n        \"logs:CreateLogGroup\",\n        \"logs:CreateLogStream\",\n        \"logs:PutLogEvents\",\n        \"sts:AssumeRole\",\n        \"codebuild:*\",\n        \"lambda:*\",\n        \"iam:AddRoleToInstanceProfile\",\n        \"iam:AttachRolePolicy\",\n        \"iam:CreateInstanceProfile\",\n        \"iam:CreatePolicy\",\n        \"iam:CreateRole\",\n        \"iam:GetRole\",\n        \"iam:ListAttachedRolePolicies\",\n        \"iam:ListPolicies\",\n        \"iam:ListRolePolicies\",\n        \"iam:ListRoles\",\n        \"iam:PassRole\",\n        \"iam:PutRolePolicy\",\n        \"iam:UpdateAssumeRolePolicy\",\n        \"iam:GetRolePolicy\"\n      ]\n    },\n    {\n      \"Effect\": \"Allow\",\n      \"Resource\": [\n        \"${var.ecr_repo_arn}\"\n      ],\n      \"Action\": [\n        \"ecr:*\"\n      ]\n    },\n    {\n      \"Effect\": \"Allow\",\n      \"Resource\": [\n        \"*\"\n      ],\n      \"Action\": [\n        \"ecr:GetAuthorizationToken\"\n      ]\n    },\n    {\n      \"Effect\": \"Allow\",\n      \"Action\": [\n        \"s3:*\"\n      ],\n      \"Resource\": [\n        \"${aws_s3_bucket.codepipeline_bucket.arn}\",\n        \"${aws_s3_bucket.codepipeline_bucket.arn}/*\",\n        \"arn:aws:s3:::BUCKET_NAME\",\n        \"arn:aws:s3:::BUCKET_NAME/*\"\n      ]\n    }\n  ]\n}\nPOLICY\n}\n```\n\n**Code:** https://github.com/omerbsezer/Fast-Terraform/blob/main/samples/codecommit-codepipeline-codebuild-codedeploy-lambda-container/modules/codepipeline/roles.tf\n\n![image](https://user-images.githubusercontent.com/10358317/233832109-cd0c7938-3522-4c5e-a6d1-75bc06a11da7.png)\n\n- Create variables.tf\n\n```\nvariable \"codecommit_branch\" {\n    type = string\n}\nvariable \"codecommit_repo\" {\n    type = string\n}\nvariable \"general_namespace\" {\n    type = string\n}\nvariable \"env_namespace\" {\n    type = string\n}\nvariable \"s3_bucket_namespace\" {\n    type = string\n}\nvariable \"ecr_repo_arn\" {\n    type = string\n}\nvariable \"codebuild_image\" {\n    type = string\n    default = \"aws/codebuild/amazonlinux2-x86_64-standard:3.0\"\n}\nvariable \"codebuild_type\" {\n    type = string\n    default = \"LINUX_CONTAINER\"\n}\nvariable \"codebuild_compute_type\" {\n    type = string\n    default = \"BUILD_GENERAL1_MEDIUM\"\n}\nvariable \"build_args\" {\n    type        = any\n}\n```\n\n**Code:** https://github.com/omerbsezer/Fast-Terraform/blob/main/samples/codecommit-codepipeline-codebuild-codedeploy-lambda-container/modules/codepipeline/variables.tf\n\n![image](https://user-images.githubusercontent.com/10358317/233832129-c41dee01-6194-496d-8b14-d8a3fc79f158.png)\n\n- Create buildspec_build.yml under templates:\n\n```\nversion: 0.2\n\nphases:\n  pre_build:\n    commands:\n      - echo Logging in to Amazon ECR...\n      - aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com\n      - IMAGE_URI=$REPO_URI:latest\n      - echo $IMAGE_URI\n  build:\n    commands:\n      - echo `ls -lrt`\n      - echo Build started on `date`\n      - echo Building the Docker image...          \n      - docker build -t $IMAGE_URI ./lambda_bootstrap/lambda/\n  post_build:\n    commands:\n      - bash -c \"if [ /\"$CODEBUILD_BUILD_SUCCEEDING/\" == /\"0/\" ]; then exit 1; fi\"\n      - echo Build completed on `date`\n      - echo Pushing the Docker image...\n      - docker push $IMAGE_URI\n```\n\n**Code:** https://github.com/omerbsezer/Fast-Terraform/blob/main/samples/codecommit-codepipeline-codebuild-codedeploy-lambda-container/modules/codepipeline/templates/buildspec_build.yml\n\n![image](https://user-images.githubusercontent.com/10358317/233832160-42cf2a4a-cba5-4254-a613-f91b37f27a5c.png)\n\n- Create buildspec_deploy.yml under templates:\n\n```\nversion: 0.2\n\nphases:\n  install:\n    runtime-versions:\n      python: 3.7\n    commands:\n      - tf_version=$TERRAFORM_VERSION\n      - wget https://releases.hashicorp.com/terraform/\"$TERRAFORM_VERSION\"/terraform_\"$TERRAFORM_VERSION\"_linux_amd64.zip\n      - unzip terraform_\"$TERRAFORM_VERSION\"_linux_amd64.zip\n      - mv terraform /usr/local/bin/\n      - curl -sSLo install.sh https://install.hclq.sh\n      - sh install.sh\n  pre_build:\n    commands:\n      - echo Logging into Amazon ECR...\n      - aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com\n  build:\n    commands:\n      - echo Build started on `date`\n      - terraform --version\n      - cd lambda_bootstrap/\n      - echo Updating ENV_namespace in terraform.tfvars\n      - cat terraform.tfvars | hclq set 'env_namespace' $ENV_NAMESPACE | hclq set 'ecr_repo_url' $REPO_URI | hclq set 'ecr_repo_arn' $REPO_ARN | tee terraform.tfvars\n      - terraform init -input=false\n      - terraform validate\n      - terraform apply -auto-approve\n```\n\n**Code:** https://github.com/omerbsezer/Fast-Terraform/blob/main/samples/codecommit-codepipeline-codebuild-codedeploy-lambda-container/modules/codepipeline/templates/buildspec_deploy.yml\n\n![image](https://user-images.githubusercontent.com/10358317/233832212-dc3ca548-6390-4ea3-9c18-b890e81648a6.png)\n\n### ECR Module <a name=\"ecr\"></a>\n- Create main.tf:\n\n```\ndata \"aws_caller_identity\" \"current\" {}\nresource \"aws_ecr_repository\" \"ecr_repo\" {\n  name                 = \"${var.general_namespace}_docker_repo\"\n  #image_tag_mutability = \"IMMUTABLE\" #a capability that prevents image tags from being overwritten\n  image_scanning_configuration {\n    scan_on_push = true #https://docs.aws.amazon.com/AmazonECR/latest/userguide/image-scanning.html\n  }\n  tags = {\n    env = var.env_namespace\n  }\n}\n```\n\n**Code:** https://github.com/omerbsezer/Fast-Terraform/blob/main/samples/codecommit-codepipeline-codebuild-codedeploy-lambda-container/modules/ecr/main.tf\n\n![image](https://user-images.githubusercontent.com/10358317/233832299-e05ba389-3a04-47aa-b91a-478f75b72493.png)\n\n- Create outputs.tf:\n\n```\noutput \"ecr_configs\" {\n    value = {\n        ecr_repo_url = aws_ecr_repository.ecr_repo.repository_url\n        ecr_repo_arn = aws_ecr_repository.ecr_repo.arn\n    }\n}\n```\n\n**Code:** https://github.com/omerbsezer/Fast-Terraform/blob/main/samples/codecommit-codepipeline-codebuild-codedeploy-lambda-container/modules/ecr/outputs.tf\n\n![image](https://user-images.githubusercontent.com/10358317/233832327-78081e78-7477-4f98-909f-f2c03450a8a2.png)\n\n- Create variables.tf:\n\n```\nvariable \"general_namespace\" {\n    type = string\n}\nvariable \"env_namespace\" {\n    type = string\n}\n```\n\n**Code:** https://github.com/omerbsezer/Fast-Terraform/blob/main/samples/codecommit-codepipeline-codebuild-codedeploy-lambda-container/modules/ecr/variables.tf\n\n![image](https://user-images.githubusercontent.com/10358317/233832341-f9cd9510-ce6d-40fb-8562-4b6d56a46b98.png)\n\n### Lambda Part <a name=\"lambda\"></a>\n- Create main.tf:\n\n```\ndata \"aws_ecr_image\" \"lambda_image_latest\" {\n  repository_name = split(\"/\", var.ecr_repo_url)[1]\n  image_tag       = \"latest\"\n}\n\nresource \"aws_iam_role\" \"iam_for_lambda\" {\n  name               = \"${var.env_namespace}_lambda_role\"\n  assume_role_policy = <<EOF\n{\n    \"Version\": \"2012-10-17\",\n    \"Statement\": [\n        {\n            \"Effect\": \"Allow\",\n            \"Principal\": {\n                \"Service\": \"lambda.amazonaws.com\"\n            },\n            \"Action\": \"sts:AssumeRole\"\n        }\n    ]\n}\nEOF\n}\n\nresource \"aws_iam_role_policy\" \"iam_policy_for_lambda\" {\n  role   = aws_iam_role.iam_for_lambda.name\n  policy = <<POLICY\n{\n  \"Version\": \"2012-10-17\",\n  \"Statement\": [\n    {\n      \"Effect\": \"Allow\",\n      \"Resource\": [\n        \"${var.ecr_repo_arn}\"\n      ],\n      \"Action\": [\n        \"ecr:*\"\n      ]\n    },\n    {\n      \"Effect\": \"Allow\",\n      \"Resource\": [\n        \"*\"\n      ],\n      \"Action\": [\n        \"ecr:GetAuthorizationToken\"\n      ]\n    }\n  ]\n}\nPOLICY\n}\nresource \"aws_lambda_function\" \"main\" {\n  function_name    = \"${var.env_namespace}_lambda\"\n  image_uri        = \"${var.ecr_repo_url}:latest\"\n  package_type     = \"Image\"\n  role             = aws_iam_role.iam_for_lambda.arn\n  source_code_hash = data.aws_ecr_image.lambda_image_latest.id\n}\n```\n\n**Code:** https://github.com/omerbsezer/Fast-Terraform/blob/main/samples/codecommit-codepipeline-codebuild-codedeploy-lambda-container/lambda_bootstrap/main.tf\n\n![image](https://user-images.githubusercontent.com/10358317/233832538-24fe7678-9f67-4799-be4b-610576678c95.png)\n\n- Create outputs.tf:\n```\noutput \"lambda_arn\" {\n    value = aws_lambda_function.main.arn\n}\n```\n\n**Code:** https://github.com/omerbsezer/Fast-Terraform/blob/main/samples/codecommit-codepipeline-codebuild-codedeploy-lambda-container/lambda_bootstrap/outputs.tf\n\n![image](https://user-images.githubusercontent.com/10358317/233832555-7b19b218-998d-41f4-93a0-48b69ac1d74f.png)\n\n- Create providers.tf:\n\n```\nprovider \"aws\" {\n  region = \"eu-central-1\"\n}\n\nterraform {\n  required_version = \">= 0.15\"\n  required_providers {\n    aws = {\n      source  = \"hashicorp/aws\"\n      version = \"~> 4.15.1\"\n      # Will allow installation of 4.15.1 and 4.15.10 but not 4.16.0\n      # Get error when using 4.16.0\n    }\n  }\n}\n```\n\n**Code:** https://github.com/omerbsezer/Fast-Terraform/blob/main/samples/codecommit-codepipeline-codebuild-codedeploy-lambda-container/lambda_bootstrap/providers.tf\n\n![image](https://user-images.githubusercontent.com/10358317/233832580-46078909-5327-4e8f-bcf1-f387c119bc96.png)\n\n- Create terraform.tfvars:\n\n```\nenv_namespace = \"\"\necr_repo_url = \"\"\necr_repo_arn = \"\"\n```\n\n**Code:** https://github.com/omerbsezer/Fast-Terraform/blob/main/samples/codecommit-codepipeline-codebuild-codedeploy-lambda-container/lambda_bootstrap/terraform.tfvars\n\n- Create variables.tf:\n\n```\nvariable \"env_namespace\" {\n    type = string\n    description = \"Value is coming from tfvars file that is being updated by buildspec environment variables\"\n}\nvariable \"ecr_repo_url\" {\n    type = string\n    description = \"Value is coming from tfvars file that is being updated by buildspec environment variables\"\n}\nvariable \"ecr_repo_arn\" {\n    type = string\n    description = \"Value is coming from tfvars file that is being updated by buildspec environment variables\"\n}\n```\n\n**Code:** https://github.com/omerbsezer/Fast-Terraform/blob/main/samples/codecommit-codepipeline-codebuild-codedeploy-lambda-container/lambda_bootstrap/variables.tf\n\n![image](https://user-images.githubusercontent.com/10358317/233832595-207be71a-a552-4a1e-9c5b-936c14878533.png)\n\n**Lambda Details, Dockerfile:** https://github.com/omerbsezer/Fast-Terraform/tree/main/samples/codecommit-codepipeline-codebuild-codedeploy-lambda-container/lambda_bootstrap/lambda\n\n![image](https://user-images.githubusercontent.com/10358317/233832640-11e81033-96de-4f54-b7de-1dec2be2e24a.png)\n\n![image](https://user-images.githubusercontent.com/10358317/233832656-dc4be9d6-fb45-4c62-9790-16a242305b13.png)\n\n### Demo: Terraform Run <a name=\"run\"></a>\n\n- Run:\n \n```\nterraform init\nterraform validate\nterraform plan\nterraform apply\n```\n\n![image](https://user-images.githubusercontent.com/10358317/233833654-1382237d-7052-483c-806d-9c3ecc1f6229.png)\n\n- Create IAM CodeCommit HTTPS Key on AWS IAM. Go to IAM User > User > Security Credentials > HTTPS Git credentials for AWS CodeCommit\n- Generate credentials (username and password) to push the code to the CodeCommit\n\n![image](https://user-images.githubusercontent.com/10358317/233833803-93025986-640a-43ca-afd2-4a1c8494f197.png)\n\n- Pull the repo from AWS CodeCommit:\n\n```\ngit clone https://git-codecommit.eu-central-1.amazonaws.com/v1/repos/org_awsteam_lambda_code_repo\n```\n\n![image](https://user-images.githubusercontent.com/10358317/233833969-fc1aed7f-67cc-4a4d-b932-2acca8bc6527.png)\n\n- Enter Credential on Git Bash Emulator to download empty project:\n\n```\ngit config --global credential.helper '!aws codecommit credential-helper --profile CodeCommitProfile $@'\ngit config --global credential.UseHttpPath true\ngit clone https://git-codecommit.eu-central-1.amazonaws.com/v1/repos/org_awsteam_lambda_code_repo\n```\n\n![image](https://user-images.githubusercontent.com/10358317/233834809-13d3cd70-ee69-46dc-907e-214a3e8d9375.png)\n\n- Copy the \"lambda_bootstrap\" into the downloaded project 'org_awsteam_lambda_code_repo':\n\n```\ncp lambda_bootstrap /org_awsteam_lambda_code_repo/ \ngit add . && git commit -m \"Initial Commit\" && git push\n```\n\n- Push the code into the CodeCommit Repo:\n\n![image](https://user-images.githubusercontent.com/10358317/233834664-85a51381-f938-46e8-afb0-23064c4dbd09.png)\n\n- On AWS CodeCommit, code is pushed:\n\n![image](https://user-images.githubusercontent.com/10358317/233834726-fa1228d9-772a-4931-bf3f-4dcc6f4bb523.png)\n\n- After pushing the code, it triggers CodePipeline:\n\n![image](https://user-images.githubusercontent.com/10358317/233835282-b53e5022-eac6-4212-9245-309db4c68678.png)\n\n- On AWS CodeBuild:\n\n![image](https://user-images.githubusercontent.com/10358317/233835172-f6afe81a-f6d3-4065-935c-f086ae6dbd0f.png)\n\n- On AWS CodeBuild, Dev Code Build Logs:\n\n![image](https://user-images.githubusercontent.com/10358317/233835613-f26c8658-7ea9-4deb-92f0-3b7607112e80.png)\n\n- On AWS CodeBuild, Deploy Image Build Logs on Lambda:\n\n![image](https://user-images.githubusercontent.com/10358317/233835429-d0c6a136-9580-4ef1-b343-9bce48972822.png)\n\n- On AWS ECR, Docker image was pushed by CodeBuild:\n\n![image](https://user-images.githubusercontent.com/10358317/233835727-821e1456-2799-4e67-9994-7f3382d327ab.png)\n\n- On AWS Lambda:\n\n![image](https://user-images.githubusercontent.com/10358317/233835833-3ec1c5cb-0235-44f3-84a9-9491ffc996b5.png)\n\n- Testing interface with Lambda Test:\n\n![image](https://user-images.githubusercontent.com/10358317/233835876-a6b87862-730b-4bb4-ae6a-66389b0cd744.png)\n\n- Lambda Code returns (it returns house prices and addresses):\n\n![image](https://user-images.githubusercontent.com/10358317/233835933-129e6368-5d65-45a5-8b3e-204cd496f1d5.png)\n\n- On AWS S3, S3 bucket stores Artifacts for codepipeline stages' connection (source, build, deploy):\n\n![image](https://user-images.githubusercontent.com/10358317/233836246-8474c407-367b-4795-9d39-ddbe2d952a6e.png)\n\n- Before destroy, delete the bucket file using GUI:\n\n![image](https://user-images.githubusercontent.com/10358317/233836359-2bef706c-348e-4b5d-9b45-d41fd7804394.png)\n\n- Finally, destroy infrastructure:\n\n```\nterraform destroy -auto-approve\n```\n\n![image](https://user-images.githubusercontent.com/10358317/233836460-b773ccfb-8a35-4f5d-9002-61a0ce2dbad0.png)\n\n- After destroying; control Lambda, ECR, S3, CodeCommit, CodeBuild, CodePipeline to be sure that everything is deleted.\n\n## References\n- https://github.com/aws-samples/codepipeline-for-lambda-using-terraform\n"
  },
  {
    "path": "SAMPLE08-S3-CloudFront-Static-WebSite.md",
    "content": "## SAMPLE-08: Provisioning S3 and CloudFront to serve Static Web Site\n\nThis sample shows:\n- how to create S3 Bucket, \n- how to to copy the website to S3 Bucket, \n- how to configure S3 bucket policy,\n- how to create CloudFront distribution to refer S3 Static Web Site,\n- how to configure CloudFront (default_cache_behavior, ordered_cache_behavior, ttl, price_class, restrictions, viewer_certificate).\n\n**Code:** https://github.com/omerbsezer/Fast-Terraform/blob/main/samples/s3-cloudfront-static-website/\n\n### Prerequisite\n\n- You should have a look following lab: \n  - [LAB-00: Terraform Install, AWS Configuration with Terraform](https://github.com/omerbsezer/Fast-Terraform/blob/main/LAB00-Terraform-Install-AWS-Configuration.md)\n\n## Steps\n\n- Create s3.tf:\n \n```\nterraform {\n  required_providers {\n    aws = {\n      source  = \"hashicorp/aws\"\n      version = \"~> 4.16\"\n    }\n  }\n  required_version = \">= 1.2.0\"\n}\n\nprovider \"aws\" {\n  region  = \"eu-central-1\"\n}\n\nresource \"aws_s3_bucket\" \"mybucket\" {\n  bucket = \"s3-mybucket-website2023\"\n  acl    = \"private\"\n  # Add specefic S3 policy in the s3-policy.json on the same directory\n  # policy = file(\"s3-policy.json\")\n\n  versioning {\n    enabled = false\n  }\n\n  website {\n    index_document = \"index.html\"\n    error_document = \"error.html\"\n\t\n\t# Add routing rules if required\n    # routing_rules = <<EOF\n    #                [{\n    #                    \"Condition\": {\n    #                        \"KeyPrefixEquals\": \"docs/\"\n    #                    },\n    #                    \"Redirect\": {\n    #                        \"ReplaceKeyPrefixWith\": \"documents/\"\n    #                    }\n    #                }]\n    #                EOF\n  }\n\n  tags = {\n    Environment = \"development\"\n    Name        = \"my-tag\"\n  }\n\n}\n\n#Upload files of your static website\nresource \"aws_s3_bucket_object\" \"html\" {\n  for_each = fileset(\"${path.module}/website/\", \"*.html\")\n\n  bucket = aws_s3_bucket.mybucket.bucket\n  key    = each.value\n  source = \"${path.module}/website/${each.value}\"\n  etag   = filemd5(\"${path.module}/website/${each.value}\")\n  content_type = \"text/html\"\n}\n\nresource \"aws_s3_bucket_object\" \"svg\" {\n  for_each = fileset(\"${path.module}/website/\", \"**/*.svg\")\n\n  bucket = aws_s3_bucket.mybucket.bucket\n  key    = each.value\n  source = \"${path.module}/website/${each.value}\"\n  etag   = filemd5(\"${path.module}/website/${each.value}\")\n  content_type = \"image/svg+xml\"\n}\n\nresource \"aws_s3_bucket_object\" \"css\" {\n  for_each = fileset(\"${path.module}/website/\", \"**/*.css\")\n\n  bucket = aws_s3_bucket.mybucket.bucket\n  key    = each.value\n  source = \"${path.module}/website/${each.value}\"\n  etag   = filemd5(\"${path.module}/website/${each.value}\")\n  content_type = \"text/css\"\n}\n\nresource \"aws_s3_bucket_object\" \"js\" {\n  for_each = fileset(\"${path.module}/website/\", \"**/*.js\")\n\n  bucket = aws_s3_bucket.mybucket.bucket\n  key    = each.value\n  source = \"${path.module}/website/${each.value}\"\n  etag   = filemd5(\"${path.module}/website/${each.value}\")\n  content_type = \"application/javascript\"\n}\n\n\nresource \"aws_s3_bucket_object\" \"images\" {\n  for_each = fileset(\"${path.module}/website/\", \"**/*.png\")\n\n  bucket = aws_s3_bucket.mybucket.bucket\n  key    = each.value\n  source = \"${path.module}/website/${each.value}\"\n  etag   = filemd5(\"${path.module}/website/${each.value}\")\n  content_type = \"image/png\"\n}\n\nresource \"aws_s3_bucket_object\" \"json\" {\n  for_each = fileset(\"${path.module}/website/\", \"**/*.json\")\n\n  bucket = aws_s3_bucket.mybucket.bucket\n  key    = each.value\n  source = \"${path.module}/website/${each.value}\"\n  etag   = filemd5(\"${path.module}/website/${each.value}\")\n  content_type = \"application/json\"\n}\n# Add more aws_s3_bucket_object for the type of files you want to upload\n# The reason for having multiple aws_s3_bucket_object with file type is to make sure\n# we add the correct content_type for the file in S3. Otherwise website load may have issues\n\n# Print the files processed so far\noutput \"fileset-results\" {\n  value = fileset(\"${path.module}/website/\", \"**/*\")\n}\n\ndata \"aws_iam_policy_document\" \"s3_policy\" {\n  statement {\n    actions   = [\"s3:GetObject\"]\n    resources = [\"${aws_s3_bucket.mybucket.arn}/*\"]\n\n    principals {\n      type        = \"AWS\"\n      identifiers = [aws_cloudfront_origin_access_identity.origin_access_identity.iam_arn]\n    }\n  }\n}\n\nresource \"aws_s3_bucket_policy\" \"mybucket\" {\n  bucket = aws_s3_bucket.mybucket.id\n  policy = data.aws_iam_policy_document.s3_policy.json\n}\n\nresource \"aws_s3_bucket_public_access_block\" \"mybucket\" {\n  bucket = aws_s3_bucket.mybucket.id\n\n  block_public_acls       = true\n  block_public_policy     = true\n  //ignore_public_acls      = true\n  //restrict_public_buckets = true\n}\n```\n\n**Code:** https://github.com/omerbsezer/Fast-Terraform/blob/main/samples/s3-cloudfront-static-website/s3.tf\n\n![image](https://user-images.githubusercontent.com/10358317/234043000-4dbbf5bd-8c87-4c3b-872e-6b9958217cc3.png)\n\n- Create cloudfront.tf:\n \n```\nlocals {\n  s3_origin_id = \"s3-my-website2023\"\n}\n\nresource \"aws_cloudfront_origin_access_identity\" \"origin_access_identity\" {\n  comment = \"s3-my-website2023\"\n}\n\nresource \"aws_cloudfront_distribution\" \"s3_distribution\" {\n  origin {\n    domain_name = aws_s3_bucket.mybucket.bucket_regional_domain_name\n    origin_id   = local.s3_origin_id\n\n    s3_origin_config {\n      origin_access_identity = aws_cloudfront_origin_access_identity.origin_access_identity.cloudfront_access_identity_path\n    }\n  }\n\n  enabled             = true\n  is_ipv6_enabled     = true\n  comment             = \"my-cloudfront\"\n  default_root_object = \"index.html\"\n\n  # Configure logging here if required \t\n  #logging_config {\n  #  include_cookies = false\n  #  bucket          = \"mylogs.s3.amazonaws.com\"\n  #  prefix          = \"myprefix\"\n  #}\n\n  # If you have domain configured use it here \n  #aliases = [\"mywebsite.example.com\", \"s3-static-web-dev.example.com\"]\n\n  default_cache_behavior {\n    allowed_methods  = [\"DELETE\", \"GET\", \"HEAD\", \"OPTIONS\", \"PATCH\", \"POST\", \"PUT\"]\n    cached_methods   = [\"GET\", \"HEAD\"]\n    target_origin_id = local.s3_origin_id\n\n    forwarded_values {\n      query_string = false\n\n      cookies {\n        forward = \"none\"\n      }\n    }\n\n    viewer_protocol_policy = \"allow-all\"\n    min_ttl                = 0\n    default_ttl            = 3600\n    max_ttl                = 86400\n  }\n\n  # Cache behavior with precedence 0\n  ordered_cache_behavior {\n    path_pattern     = \"/content/immutable/*\"\n    allowed_methods  = [\"GET\", \"HEAD\", \"OPTIONS\"]\n    cached_methods   = [\"GET\", \"HEAD\", \"OPTIONS\"]\n    target_origin_id = local.s3_origin_id\n\n    forwarded_values {\n      query_string = false\n      headers      = [\"Origin\"]\n\n      cookies {\n        forward = \"none\"\n      }\n    }\n\n    min_ttl                = 0\n    default_ttl            = 86400\n    max_ttl                = 31536000\n    compress               = true\n    viewer_protocol_policy = \"redirect-to-https\"\n  }\n\n  # Cache behavior with precedence 1\n  ordered_cache_behavior {\n    path_pattern     = \"/content/*\"\n    allowed_methods  = [\"GET\", \"HEAD\", \"OPTIONS\"]\n    cached_methods   = [\"GET\", \"HEAD\"]\n    target_origin_id = local.s3_origin_id\n\n    forwarded_values {\n      query_string = false\n\n      cookies {\n        forward = \"none\"\n      }\n    }\n\n    min_ttl                = 0\n    default_ttl            = 3600\n    max_ttl                = 86400\n    compress               = true\n    viewer_protocol_policy = \"redirect-to-https\"\n  }\n\n  price_class = \"PriceClass_200\"\n\n  restrictions {\n    geo_restriction {\n      restriction_type = \"whitelist\"\n      locations        = [\"US\", \"CA\", \"GB\", \"DE\", \"IN\", \"IR\"]\n    }\n  }\n\n  tags = {\n    Environment = \"development\"\n    Name        = \"my-tag\"\n  }\n\n  viewer_certificate {\n    cloudfront_default_certificate = true\n  }\n}\n\n# to get the Cloud front URL if doamin/alias is not configured\noutput \"cloudfront_domain_name\" {\n  value = aws_cloudfront_distribution.s3_distribution.domain_name\n}\n```\n\n**Code:** https://github.com/omerbsezer/Fast-Terraform/blob/main/samples/s3-cloudfront-static-website/cloudfront.tf\n\n![image](https://user-images.githubusercontent.com/10358317/234043230-49318380-a869-430f-a209-60c5cf367cdd.png)\n\n- Run:\n \n```\nterraform init\nterraform validate\nterraform plan\nterraform apply\n```\n- After apply command, provisioning: \n\n  ![image](https://user-images.githubusercontent.com/10358317/234037248-3be6fbe0-a14f-48e9-b8cb-93d77d932da9.png)\n\n  ![image](https://user-images.githubusercontent.com/10358317/234036899-095e2fe2-aaa4-4a41-a37c-00adc21761a2.png)\n\n- On AWS S3:\n\n  ![image](https://user-images.githubusercontent.com/10358317/234034144-3747b63c-2ca7-4030-9900-7d081fc2c530.png)  \n\n  ![image](https://user-images.githubusercontent.com/10358317/234034725-085b9286-9c78-4770-a9a2-d60d5cb3e4b8.png)\n\n- On AWS CloudFront:\n\n  ![image](https://user-images.githubusercontent.com/10358317/234035736-38d68314-4dfd-4147-a921-9356b313b259.png)\n\n  ![image](https://user-images.githubusercontent.com/10358317/234036235-5d41b526-8bac-41d8-87dc-cf503069e117.png)\n\n  ![image](https://user-images.githubusercontent.com/10358317/234036566-040e8e0f-9972-487f-b533-f60058f6f7f5.png)\n\n- On Browser, website: index.html:\n\n  ![image](https://user-images.githubusercontent.com/10358317/234033141-ee41e25e-e5e6-4962-a21d-ed155eb25197.png)\n  \n  ![image](https://user-images.githubusercontent.com/10358317/234033367-79f23b83-7e7c-415b-a06f-9c73541e4660.png)\n\n- WebSite: error.html\n\n  ![image](https://user-images.githubusercontent.com/10358317/234033656-8a1d5671-530b-4347-968d-d8b144fda7ff.png)\n\n- Finally, destroy infrastructure:\n\n```\nterraform destroy -auto-approve\n```\n\n- Destroying takes time:\n\n  ![image](https://user-images.githubusercontent.com/10358317/234040293-3e4f285d-4ef3-483f-bd4d-3ffb41d94b73.png)\n\n  ![image](https://user-images.githubusercontent.com/10358317/234040667-e9b5c723-15fa-4d05-a628-eb15e4714e10.png)\n\n## Reference\n- Website Source Code: https://github.com/StartBootstrap/startbootstrap-freelancer\n- https://towardsaws.com/provision-a-static-website-on-aws-s3-and-cloudfront-using-terraform-d8004a8f629a\n"
  },
  {
    "path": "SAMPLE09-GitlabServer-on-Premise-GitlabRunner-on-EC2.md",
    "content": "## SAMPLE-09: Running Gitlab Server using Docker on Local Machine and Making Connection to Provisioned Gitlab Runner on EC2 in Home Internet without Using VPN\n\nThis sample shows:\n- how to run Gitlab Server using Docker on WSL2 on-premise,\n- how to redirect external traffic to docker container port (Gitlab server),\n- how to configure on-premise PC network configuration,\n- how to run EC2 and install docker, gitlab-runner on EC2,\n- how to register Gitlab runner on EC2 to Gitlab Server on-premise (in Home),\n- how to run job on EC2 and returns artifacts to Gitlab Server on-premise (in Home).\n\n**Code:** https://github.com/omerbsezer/Fast-Terraform/blob/main/samples/gitlabserver-on-premise-runner-on-EC2/\n\n### Prerequisite\n\n- You should have a look following lab: \n  - [LAB-00: Terraform Install, AWS Configuration with Terraform](https://github.com/omerbsezer/Fast-Terraform/blob/main/LAB00-Terraform-Install-AWS-Configuration.md)\n\n## Steps\n\n- Run Gitlab Server on WSL2, run: docker-compose up -d\n\n```\n# docker-compose.yml\nversion: '3.6'\nservices:\n  web:\n    image: 'gitlab/gitlab-ee:latest'\n    restart: always\n    hostname: 'gitlab.example.com'\n    environment:\n      GITLAB_OMNIBUS_CONFIG: |\n        external_url 'http://gitlab.example.com'\n        #external_url 'https://gitlab.example.com'\n      DOCKER_HOST: '192.168.178.28'\n    ports:\n      - '150:80'\n      - '443:443'\n      - '22:22'\n    volumes:\n      - '/home/omer/gitlab-tmp/config:/etc/gitlab'\n      - '/home/omer/gitlab-tmp/logs:/var/log/gitlab'\n      - '/home/omer/gitlab-tmp/data:/var/opt/gitlab'\n    shm_size: '256m'\n```\n\n**Code:** https://github.com/omerbsezer/Fast-Terraform/blob/main/samples/gitlabserver-on-premise-runner-on-EC2/docker-compose.yml\n\n- Run the following in where the dockercompose.yml is present:\n\n```\ndocker-compose up -d\n# if u don't know the username and password\ndocker container ls -a\ndocker exec -it git-server_web_1 bash\n> gitlab-rake gitlab:password:reset  # run in the container\n> username: root\n> password:987aws12345\n> Password successfully updated for user with username root.\n> exit\n```\n\n![image](https://github.com/omerbsezer/Fast-Terraform/assets/10358317/0c122fd7-645a-40c3-bfb6-799d9c2fcd82)\n\n- If you run docker in the WSL, call browser in the WSL: \"sensible-browser http://gitlab.example.com:150/\"\n\n  ![image](https://github.com/omerbsezer/Fast-Terraform/assets/10358317/f3e6d11a-6b6e-4ab6-a8c6-01c718090243)\n\n- This runs on 127.0.0.1:150 when you run \"netstat -an\" on windows, but we want to run it on the host machine IP \"192.168.178.28:150\"\n- Use PORT Proxy from 127.0.0.1:150 to 192.168.178.28:150\n\n```\nnetsh interface portproxy add v4tov4 listenport=150 connectaddress=127.0.0.1 connectport=150 listenaddress=192.168.178.28 protocol=tcp\n# for delete: netsh interface portproxy delete v4tov4 listenport=150 listenaddress=192.168.178.28 protocol=tcp\n```\n\n- Now, when it runs on both hostIP:150 and 127.0.0.1:150. This requires to NAT Forwarding\n\n  ![image](https://github.com/omerbsezer/Fast-Terraform/assets/10358317/f1419f87-f3ef-4666-b4d8-9bb6fd3e0295)\n\n- On Network Config, make connection (ethernet or wireless) to static IP 192.168.178.28.\n  \n  ![image](https://github.com/omerbsezer/Fast-Terraform/assets/10358317/437d7e0b-5a76-4a94-999b-a9c6dfc07f67)\n\n- On the modem switch, enable NAT Forwarding, this enables that external traffic redirects to the host machine: 192.168.178.1 => Internet.Permit Access => PC, TCP Port 150 through 150, external 150.\n \n- Test on browser (gitlab server runs) on 192.168.178.28:150:\n\n- On 'C:\\Windows\\System32\\drivers\\etc\\host' file, add '127.0.0.1 gitlab.example.com', test with 'gitlab.example.com' on browser on-premise:\n  \n  ![image](https://github.com/omerbsezer/Fast-Terraform/assets/10358317/2349083d-c9b2-4ad2-980a-24839d169e76)\n\n- Close/pause the firewall to reach the service from outside.\n- Learn the external IP with googling 'what is my IP', and test 'externalIP:150' on browser:\n\n  ![image](https://github.com/omerbsezer/Fast-Terraform/assets/10358317/1a692453-4b6e-4bc6-9898-bfe31f28ee1d)\n\n- Create EC2 on AWS with:\n\n**Code:** https://github.com/omerbsezer/Fast-Terraform/blob/main/samples/gitlabserver-on-premise-runner-on-EC2/main.tf\n\n```\nterraform init\nterraform plan\nterraform apply\n```\n\n- Make SSH to Ubuntu\n\n```\nssh -i .\\testkey.pem ubuntu@UbuntuPublicIP\n```\n\n- While launching the EC2, docker and gitlab-runner were installed on it. \n- Run 'curl http://externalIP:150', if it works, the connection was done to gitlab server on-premise\n\n- Register gitlab-runner using 'sudo gitlab-runner register', url: http://gitlab.example.com:150/, token from Gitlab Server > Admin > CI > Runners > Register new Runner (for shared-runner), add tag: ec2-shared, executable: docker, and alpine.\n\n  ![image](https://github.com/omerbsezer/Fast-Terraform/assets/10358317/d6187256-775f-4abc-a76b-c81fa1b462fd)\n\n- Runners was added, to configure to see the local URL:\n  - 'nano /etc/gitlab-runner/config.toml', url = \"http://gitlab.example.com:150/\", add extra =>  'clone_url = \"http://88.xx.xx.xx:150\"' (externalIP:150), \n  - Restart gitlab-runner on EC2: 'sudo gitlab-runner restart'\n\n  ![image](https://github.com/omerbsezer/Fast-Terraform/assets/10358317/8d97fbde-6e04-4038-bcbb-d7cafc1fb7c1)\n\n- List runners on EC2 'sudo gitlab-runner list': \n  \n  ![image](https://github.com/omerbsezer/Fast-Terraform/assets/10358317/b889a30a-1f0a-4668-b1a4-44633a448e46)\n  \n- Builds => gitlab runners run on EC2, responds to results to Gitlab Server on-premise: \n  \n  ![image](https://github.com/omerbsezer/Fast-Terraform/assets/10358317/67e7e90f-caa1-462d-9125-02dd324519a6)\n  \n- Running jobs on EC2:\n\n  ![image](https://github.com/omerbsezer/Fast-Terraform/assets/10358317/8964536b-5df5-427e-bb45-9091fc07ed29)\n\n## References:\n- https://nagachiang.github.io/gitlab-ci-gitlab-runner-cant-fetch-changes-from-repository/#\n\n \n"
  },
  {
    "path": "SAMPLE10-MLOps-SageMaker-GitHub-Codepipeline-CodeBuild-CodeDeploy.md",
    "content": "## SAMPLE-10: Implementing MLOps Pipeline using GitHub, AWS CodePipeline, AWS CodeBuild, AWS CodeDeploy, and AWS Sagemaker (Endpoint)\n\nThis sample shows:\n- how to create MLOps Pipeline \n- how to use GitHub Hooks (Getting Source Code from Github to CodePipeline)\n- how to create Build CodePipeline (Source, Build), CodeBuild (modelbuild_buildspec.yml), Deploy CodePipeline (Source, Build, DeployStaging, DeployProd), CodeBuild (modeldeploy_buildspec.yml)\n- how to save the model and artifacts on S3\n- how to create and test models using Notebooks\n\n**Notes:**\n- Original Source code was pulled, updated, and adapted:\n  - https://github.com/aws-samples/aws-mlops-pipelines-terraform\n- \"Modelbuild_Pipeline\" and \"Modeldeploy_Pipeline\" are uploaded before. After applying terraform, Webhook in the CodePipeline pulls it from GitHub to inject it into AWS.\n- If you run it the first time, please open to request to AWS for the instance: \"ml.m5.xlarge\" (\"ResourceLimitExceeded\").\n  - https://repost.aws/knowledge-center/sagemaker-resource-limit-exceeded-error  \n\n**Code:** https://github.com/omerbsezer/Fast-Terraform/tree/main/samples/mlops-sagemaker-github-codepipeline-codebuild-codedeploy \n\n\n**Architecture:**\n- **Model Build Pipeline Source Code, modelbuild_pipeline:**  https://github.com/omerbsezer/modelbuild_pipeline \n- **Model Deploy Pipeline Source Code, modeldeploy_pipeline:** https://github.com/omerbsezer/modeldeploy_pipeline\n- AWS Code Pipeline for **Model Build** (CI):\n  - AWS Code Pipeline (**modelbuild_ci_pipeline.tf**)\n    - Stage: Source (Hook from GitHub: **modelbuild_hooks.tf**)\n    - Stage: Build (**modelbuild_codebuild.tf: artifacts, environment, source (modelbuild_buildspec.yml: run build pipeline)**)\n  - Sagemaker Data Pipeline (**modelbuild_pipeline project: pipeline.py**):\n    - Preprocessing Step (**modelbuild_pipeline project: pipeline.py => preprocess.py**)\n    - Model Training Step (**modelbuild_pipeline project: pipeline.py => XGB BuiltIn Container**)\n    - Evaluation Step (**modelbuild_pipeline project: pipeline.py => evaluate.py, ConditionStep to evaluate model quality**)\n    - Registering Model Step (**modelbuild_pipeline project: pipeline.py => RegisterModel**)\n- AWS Code Pipeline for **Model Deploy** (CD):\n  - AWS Code Pipeline (**modeldeploy_cd_pipeline.tf**)\n    - Stage: Source (Hook from GitHub: **modeldeploy_hooks.tf**)\n    - Stage: Build (**modeldeploy_codebuild.tf: artifacts, environment, source (modeldeploy_buildspec.yml: run deploy pipeline => modeldeploy_pipeline project: build.py,  cloud formation to create endpoint)**)  \n    - Stage: DeployStaging:\n      - Action: Deploy (**Cloudformation, DeployResourcesStaging: modeldeploy_pipeline project => endpoint-config-template.yml**)\n      - Action: Build (**Test Staging: modeldeploy_testbuild.tf => modeldeploy_pipeline project: test/test_buildspec.yml**)\n      - Action: Approval (**Manual Approval by User**)\n    - Stage: DeployProd:\n      - Action: Deploy (**Cloudformation, DeployResourcesProd: modeldeploy_pipeline project => endpoint-config-template.yml**)\n- Notebooks (for testing) (region: us-east-1)\n  - End2end.ipynb\n    - https://github.com/omerbsezer/Fast-Terraform/blob/main/samples/mlops-sagemaker-github-codepipeline-codebuild-codedeploy/Notebooks/SageMaker_Customer_Churn_XGB_end2end.ipynb\n  - Pipeline.ipynb (Sagemaker Data Pipeline)\n    - https://github.com/omerbsezer/Fast-Terraform/blob/main/samples/mlops-sagemaker-github-codepipeline-codebuild-codedeploy/Notebooks/SageMaker_Customer_Churn_XGB_Pipeline.ipynb  \n    \n   ![image](https://github.com/omerbsezer/Fast-Terraform/assets/10358317/09c0ac8a-0fe5-4877-8440-b29a22bad5cf)\n\n\n### Prerequisite\n\n- You should have a look following lab: \n  - [LAB-00: Terraform Install, AWS Configuration with Terraform](https://github.com/omerbsezer/Fast-Terraform/blob/main/LAB00-Terraform-Install-AWS-Configuration.md)\n\n\n## Steps\n- Before running Terraform, upload \"Modelbuild_Pipeline\" and \"Modeldeploy_Pipeline\" in your GitHub account.\n- Run:\n\n```\ncd terraform\nterraform init\nterraform validate\nterraform plan\nterraform apply\n```\n\n- After run:\n\n  ![image](https://github.com/omerbsezer/Fast-Terraform/assets/10358317/7e2060d0-af1c-4b5e-af43-a100f163453b)\n\n- AWS CodePipeline:\n\n  ![image](https://github.com/omerbsezer/Fast-Terraform/assets/10358317/7daef38d-2901-4087-b990-3d8b3676783e)\n\n- ModelBuild:\n\n  ![image](https://github.com/omerbsezer/Fast-Terraform/assets/10358317/1bc7cfe7-a7b5-4155-b4a1-cbb8763a036d)\n\n- ModelBuild Log:\n\n  ![image](https://github.com/omerbsezer/Fast-Terraform/assets/10358317/72ba0e56-a66f-4427-b35c-5680ae681fc6)\n  \n- AWS S3:\n\n  ![image](https://github.com/omerbsezer/Fast-Terraform/assets/10358317/5b6da22e-7ec8-4a61-821b-3ebc8d272593)\n\n- ModelBuild was done successfully:\n\n  ![image](https://github.com/omerbsezer/Fast-Terraform/assets/10358317/9e4bad11-883e-463a-928e-d87834439e6f)\n\n- CloudWatch to see the training accuracy:\n\n  ![image](https://github.com/omerbsezer/Fast-Terraform/assets/10358317/fa0dbc0e-e3a0-48d2-8c75-309d6dcf9e19)\n\n- CloudWatch, Log Groups, Train Error:\n\n  ![image](https://github.com/omerbsezer/Fast-Terraform/assets/10358317/095870fb-ff0d-4ce8-bbe1-348779d9be25)\n    \n- ModelDeploy:\n\n  ![image](https://github.com/omerbsezer/Fast-Terraform/assets/10358317/a77c0467-3453-41dc-8f8c-c3995973bf82)\n\n  ![image](https://github.com/omerbsezer/Fast-Terraform/assets/10358317/6fb4beb5-3d17-459f-8b31-a487b07d39f1)\n\n- CloudFormation, stack: deploy-staging\n\n  ![image](https://github.com/omerbsezer/Fast-Terraform/assets/10358317/205f6a3e-1e68-4fc6-895b-d30810c4e50c)\n\n- SageMaker Dashboard, staging endpoint in service:\n\n  ![image](https://github.com/omerbsezer/Fast-Terraform/assets/10358317/4121d5c4-c2db-4a2d-8a83-c5b2183e334b)\n\n- SageMaker, Model:\n\n  ![image](https://github.com/omerbsezer/Fast-Terraform/assets/10358317/ab3e3090-5f5b-42aa-84ff-53cc17a9a380)\n\n- S3, Model, possible to download:\n\n  ![image](https://github.com/omerbsezer/Fast-Terraform/assets/10358317/09bdaf28-582a-45bc-b4b1-d053da0ec206)\n\n- Try Staging Endpoint with notebook (end2end.ipynb, last cell, enter the endpointname):\n\n```\nimport pandas as pd\nimport numpy as np\nimport sagemaker\nimport boto3\nfrom sagemaker import get_execution_role\n\ntest_data=pd.read_csv('test.csv',header=None)\ntestdata1=test_data.iloc[0:1,1:]\n\nruntime = boto3.client(\"sagemaker-runtime\")\nEndpoint_name='aws-ml-11052023-staging-0306' #<your endpoint name> # update to your own endpoint name\n\nprediction = runtime.invoke_endpoint(\n    EndpointName=Endpoint_name,\n    Body=testdata1.to_csv(header=False, index=False).encode(\"utf-8\"),\n    ContentType=\"text/csv\",\n    Accept= \"text/csv\",\n)\n\nprint(prediction[\"Body\"].read())\n```\n- Endpoint returned the result:\n\n  ![image](https://github.com/omerbsezer/Fast-Terraform/assets/10358317/58d56412-b3a2-42bc-978c-4c828d3d1af8)\n\n- Approve the Product on the CodePipeline:\n\n  ![image](https://github.com/omerbsezer/Fast-Terraform/assets/10358317/f2ee09ce-3d65-4448-9732-a5cc5a9277db)\n\n- SageMaker Dashboard, 2 Endpoints are in-service:\n\n  ![image](https://github.com/omerbsezer/Fast-Terraform/assets/10358317/cfd146dd-cbe5-4622-946f-0ca457597e26)\n\n- SageMaker, Prod Endpoint:\n\n  ![image](https://github.com/omerbsezer/Fast-Terraform/assets/10358317/444de0ff-f29d-42cd-b471-e17e4b13b904)\n\n- CloudFormation:\n\n  ![image](https://github.com/omerbsezer/Fast-Terraform/assets/10358317/f803e721-2d4c-4545-a0ba-d72a260cf2e0)\n\n- Test Prod Endpoint, returns results:\n\n  ![image](https://github.com/omerbsezer/Fast-Terraform/assets/10358317/e0ea3640-5b16-47ff-9fbf-cd1cdc81b974)\n\n- Delete Endpoints manually, if the endpoints are in-service, you have to pay their cost:\n\n  ![image](https://github.com/omerbsezer/Fast-Terraform/assets/10358317/2d30f570-ad34-4972-bee7-05a5058f7c3b)\n\n- Delete stacks manually in Cloudformation.\n- Download artifacts on S3:\n\n```\naws s3 sync s3://artifact-ml-11052023 C:\\Users\\oesezer\\Desktop\\aws-artifacts\n```\n\n- Downloaded to the local PC:\n\n  ![image](https://github.com/omerbsezer/Fast-Terraform/assets/10358317/d1e30b6c-7497-4913-a25b-9e1bbd92556e)\n\n- Destroy with \"terraform destroy\":\n\n  ![image](https://github.com/omerbsezer/Fast-Terraform/assets/10358317/cfcf5bc8-a3bc-4ef5-a661-ab6873aa5f65)\n\n- Check whether all created artifacts are deleted on CodePipeline, S3, CloudFormation, SageMaker, and CloudWatch (LogGroups) or not. If still some of the artifacts are in the AWS, please delete them all. \n\n## References\n- https://github.com/aws-samples/aws-mlops-pipelines-terraform\n"
  },
  {
    "path": "Terraform-Cheatsheet.md",
    "content": "## Terraform Cheatsheet\n\n### Table of Contents\n- [Help, Version](#help)\n- [Formatting](#formatting)\n- [Initialization](#init)\n- [Download and Install Modules](#download)\n- [Validation](#validation)\n- [Plan Your Infrastructure](#plan)\n- [Deploy Your Infrastructure](#deploy)\n- [Destroy Your Infrastructure](#destroy)\n- ['Taint' or 'Untaint' Your Resources](#taint)\n- [Refresh the State File](#refresh)\n- [Show Your State File](#show)\n- [Manipulate Your State File](#state)\n- [Import Existing Infrastructure](#import)\n- [Get Provider Information](#provider)\n- [Manage Your Workspaces](#workspace)\n- [View Your Outputs](#output)\n- [Release a Lock on Your Workspace](#release)\n- [Log In and Out to a Remote Host (Terraform Cloud)](#login)\n- [Produce a Dependency Diagram](#graph)\n- [Test Your Expressions](#test)\n\n### 1. Help, Version <a name=\"help\"></a>\n\n#### Get the general help for Terraform\n\n```\nterraform -help\n```\n\n#### Get the 'fmt' help for Terraform\n\n```\nterraform fmt -help\n```\n\n#### Get the Terraform version\n\n```\nterraform version\n```\n\n### 2. Formatting <a name=\"formatting\"></a>\n\n#### Format your Terraform configuration files using the HCL language standard\n\n```\nterraform fmt\n```\n\n#### Format files in subdirectories\n\n```\nterraform fmt --recursive\n```\n\n#### Display differences between original configuration files and formatting changes\n\n```\nterraform fmt --diff\n```\n\n#### Format Check (If files are formatted correctly, the exit status will be zero)\n\n```\nterraform fmt --check\n```\n \n### 3. Initialization <a name=\"init\"></a>\n\n#### Terraform Init Command (performs Backend Initialization, Child Module Installation, and Plugin Installation)\n\n```\nterraform init\n```\n\n#### Initialize the working directory, do not download plugins\n\n```\nterraform init -get-plugins=false\n```\n\n#### Initialize the working directory, don’t hold a state lock during backend migration\n\n```\nterraform init -lock=false\n```\n\n#### Initialize the working directory, and disable interactive prompts\n\n```\nterraform init -input=false\n```\n\n#### Reconfigure a backend, and attempt to migrate any existing state\n\n```\nterraform init -migrate-state\n```\n\n#### Initialize the working directory, do not verify plugins for Hashicorp signature\n\n```\nterraform init -verify-plugins=false\n```\n\n### 4. Download and Install Modules <a name=\"download\"></a>\n\nNote this is usually not required as this is part of the terraform init command.\n\n#### Download and installs modules needed for the configuration\n\n```\nterraform get\n```\n\n#### Check the versions of the already installed modules against the available modules and installs the newer versions if available\n\n```\nterraform get -update\n```\n\n### 5. Validation <a name=\"validation\"></a>\n\n#### Validate the configuration files in your directory and does not access any remote state or services\n- Terraform init should be run before 'validate' command.\n\n```\nterraform validate\n```\n\n#### To see easier the number of errors and warnings that you have\n\n```\nterraform validate -json\n```\n\n### 6. Plan Your Infrastructure <a name=\"plan\"></a>\n\n#### Plan will generate an execution plan\n\n```\nterraform plan\n```\n\n#### Save the plan file to a given path\n- Saved file can then be passed to the terraform apply command.\n\n```\nterraform plan -out=<path>\n```\n\n#### Create a plan to destroy all objects rather than the usual actions\n\n```\nterraform plan -destroy\n```\n\n### 7. Deploy Your Infrastructure <a name=\"deploy\"></a>\n\n#### Create or update infrastructure depending on the configuration files\n- By default, a plan will be generated first and will need to be approved (yes/no) before it is applied.\n\n```\nterraform apply\n```\n\n#### Apply changes without having to interactively type ‘yes’ to the plan\n- Useful in automation CI/CD pipelines.\n\n```\nterraform apply -auto-approve\n```\n\n#### Provide the file generated using the terraform plan -out command\n- If provided, Terraform will take the actions in the plan without any confirmation prompts.\n\n```\nterraform apply <planfilename>\n```\n\n#### Do not hold a state lock during the Terraform apply operation\n- Use with caution if other engineers might run concurrent commands against the same workspace.\n\n```\nterraform apply -lock=false\n```\n\n#### Specify the number of operations run in parallel\n\n```\nterraform apply -parallelism=<n>\n```\n\n#### Pass in a variable value\n\n```\nterraform apply -var=\"environment=dev\"\n```\n\n#### Pass in variables contained in a file\n\n```\nterraform apply -var-file=\"varfile.tfvars\"\n```\n\n#### Apply changes only to the targeted resource\n\n```\nterraform apply -target=\"module.appgw.0\"\n```\n\n### 8. Destroy Your Infrastructure <a name=\"destroy\"></a>\n\n#### Destroy the infrastructure managed by Terraform\n\n```\nterraform destroy\n```\n\n#### Destroy only the targeted resource\n\n```\nterraform destroy -target=\"module.appgw.0\"\n```\n\n#### Destroy the infrastructure without having to interactively type ‘yes’ to the plan\n- Useful in automation CI/CD pipelines.\n\n```\nterraform destroy --auto-approve\n```\n\n#### Destroy an instance of a resource created with for_each\n\n```\nterraform destroy -target=\"module.appgw.resource[\\\"key\\\"]\"\n```\n\n### 9. 'Taint' or 'Untaint' Your Resources  <a name=\"taint\"></a>\n- Use the taint command to mark a resource as not fully functional. It will be deleted and re-created.\n\n#### Taint a specified resource instance\n\n```\nterraform taint vm1.name\n```\n\n#### Untaint the already tainted resource instance\n\n```\nterraform untaint vm1.name\n```\n\n### 10. Refresh the State File <a name=\"refresh\"></a>\n\n#### Modify the state file with updated metadata containing information on the resources being managed in Terraform\n- Will not modify your infrastructure.\n\n```\nterraform refresh\n```\n\n### 11. Show Your State File <a name=\"show\"></a>\n\n#### Show the state file in a human-readable format\n\n```\nterraform show\n```\n\n#### Show the specific state file \n- If you want to read a specific state file, you can provide the path to it. If no path is provided, the current state file is shown.\n\n```\nterraform show <path to statefile>\n```\n\n### 12. Manipulate Your State File <a name=\"state\"></a>\n\n#### Lists out all the resources that are tracked in the current state file\n\n```\nterraform state list\n```\n\n#### Move an item in the state\n- Move an item in the state, for example, this is useful when you need to tell Terraform that an item has been renamed, e.g. terraform state mv vm1.oldname vm1.newname\n\n```\nterraform state mv\n```\n\n#### Get the current state and outputs it to a local file\n\n```\nterraform state pull > state.tfstate\n```\n\n#### Update remote state from the local state file\n\n```\nterraform state push \n```\n\n#### Replace a provider, useful when switching to using a custom provider registry\n\n```\nterraform state replace-provider hashicorp/azurerm customproviderregistry/azurerm\n```\n\n#### Remove the specified instance from the state file\n- Useful when a resource has been manually deleted outside of Terraform\n\n```\nterraform state rm\n```\n\n#### Show the specified resource in the state file\n\n```\nterraform state show <resourcename>\n```\n\n### 13. Import Existing Infrastructure <a name=\"import\"></a>\n\n#### Import Existing Infrastructure into Your Terraform State\n\n- Import a VM with id123 into the configuration defined in the configuration files under vm1.name\n\n```\nterraform import vm1.name -i id123\n```\n\n### 14. Get Provider Information <a name=\"provider\"></a>\n\n#### Display a tree of providers used in the configuration files and their requirements\n\n```\nterraform providers\n```\n\n### 15. Manage Your Workspaces <a name=\"workspace\"></a>\n\n#### Show the name of the current workspace\n\n```\nterraform workspace show\n```\n\n#### List your workspaces\n\n```\nterraform workspace list\n```\n\n#### Select a specified workspace\n\n```\nterraform workspace select <workspace name>\n```\n\n#### Create a new workspace with a specified name\n\n```\nterraform workspace new <workspace name>\n```\n\n#### Delete a specified workspace\n\n```\nterraform workspace delete <workspace name>\n```\n\n### 16. View Your Outputs <a name=\"output\"></a>\n\n#### List all the outputs currently held in your state file\n- These are displayed by default at the end of a terraform apply, this command can be useful if you want to view them independently.\n\n```\nterraform output\n```\n\n#### List the outputs held in the specified state file\n- '-state' option is ignored when the remote state is used.\n\n```\nterraform output -state=<path to state file>\n```\n\n#### List the outputs held in your state file in JSON format to make them machine-readable\n\n```\nterraform output -json\n```\n\n#### List a specific output held in your state file\n\n```\nterraform output vm1_public_ip\n```\n\n### 17. Release a Lock on Your Workspace <a name=\"release\"></a>\n\n#### Remove the lock with the specified lock ID from your workspace\n- Useful when a lock has become ‘stuck’, usually after an incomplete Terraform run.\n\n```\nterraform force-unlock <lock_id>\n```\n\n### 18. Log In and Out to a Remote Host (Terraform Cloud) <a name=\"login\"></a>\n\n#### Grab an API token for Terraform cloud (app.terraform.io) using your browser\n\n```\nterraform login\n```\n\n#### Log in to a specified host\n\n```\nterraform login <hostname>\n```\n\n#### Remove the credentials that are stored locally after logging in, by default for Terraform Cloud (app.terraform.io)\n\n```\nterraform logout\n```\n\n#### Remove the credentials that are stored locally after logging in for the specified hostname\n\n```\nterraform logout <hostname>\n```\n \n### 19. Produce a Dependency Diagram <a name=\"graph\"></a>\n\n#### Produce a graph in DOT language showing the dependencies between objects in the state file\n- This can then be rendered by a program called Graphwiz (amongst others).\n\n```\nterraform graph\n```\n\n#### Produce a dependency graph using a specified plan file (generated using terraform plan -out=tfplan)\n\n```\nterraform graph -plan=tfplan\n```\n\n#### Specify the type of graph to output, either plan, plan-refresh-only, plan-destroy, or apply\n\n```\nterraform graph -type=plan\n```\n\n#### You can see if there are any dependency cycles between the resources\n\n```\nterraform graph -draw-cycles\n```\n\n### 20. Test Your Expressions <a name=\"test\"></a>\n\n#### Allow testing and exploration of expressions on the interactive console using the command line\n\n```\nterraform console\n```\n\n## Reference\n- https://spacelift.io/blog/terraform-commands-cheat-sheet\n"
  },
  {
    "path": "labs/backend-remote-state/main.tf",
    "content": "terraform {\r\n  required_providers {\r\n    aws = {\r\n      source  = \"hashicorp/aws\"\r\n      version = \"~> 4.16\"\r\n    }\r\n  }\r\n\r\n  required_version = \">= 1.2.0\"\r\n\r\n  backend \"s3\" {\r\n    bucket = \"terraform-state\"\r\n    key = \"key/terraform.tfstate\"\r\n    region = \"eu-central-1\"\r\n  }\r\n}\r\n\r\nprovider \"aws\" {\r\n   region = \"eu-central-1\"\r\n}\r\n\r\nresource \"aws_instance\" \"instance\" {\r\n   ami           = \"ami-0d1ddd83282187d18\" # Ubuntu 22.04 eu-central-1 Frankfurt\r\n   instance_type = \"t2.nano\"\r\n\r\n   tags = {\r\n      Name = \"Basic Instance\"\r\n   }\r\n}\r\n"
  },
  {
    "path": "labs/basic-resource-ec2-ubuntu/main.tf",
    "content": "terraform {\r\n  required_providers {\r\n    aws = {\r\n      source  = \"hashicorp/aws\"\r\n      version = \"~> 4.16\"\r\n    }\r\n  }\r\n\r\n  required_version = \">= 1.2.0\"\r\n}\r\n\r\nprovider \"aws\" {\r\n\tregion = \"eu-central-1\"\r\n}\r\n\r\nresource \"aws_instance\" \"instance\" {\r\n\tami           = \"ami-0d1ddd83282187d18\" # Ubuntu 22.04 eu-central-1 Frankfurt\r\n\tinstance_type = \"t2.nano\"\r\n\r\n\ttags = {\r\n\t\tName = \"Basic Instance\"\r\n\t}\r\n}"
  },
  {
    "path": "labs/data-sources/main.tf",
    "content": "terraform {\r\n  required_providers {\r\n    aws = {\r\n      source  = \"hashicorp/aws\"\r\n      version = \"~> 4.16\"\r\n    }\r\n  }\r\n\r\n  required_version = \">= 1.2.0\"\r\n}\r\n\r\nprovider \"aws\" {\r\n\tregion = \"eu-central-1\"\r\n}\r\n\r\nresource \"aws_instance\" \"instance\" {\r\n\tami           = \"ami-0d1ddd83282187d18\" # Ubuntu 22.04 eu-central-1 Frankfurt\r\n\tinstance_type = \"t2.nano\"\r\n\r\n\ttags = {\r\n\t\tName = \"Basic Instance\"\r\n\t}\r\n}\r\n\r\n# with data source, new resource is not created.  \r\n# data source provides to fetch (read) or retrieve the data from AWS\r\n# filter/select the existed instances\r\n# depends_on if aws_instance.instance is created\r\n\r\ndata \"aws_instance\" \"data_instance\" {\r\n    filter {\r\n      name = \"tag:Name\"\r\n      values = [\"Basic Instance\"]\r\n    }\r\n\r\n    depends_on = [\r\n      aws_instance.instance\r\n    ]\r\n} \r\n\r\noutput \"instance_info\" {\r\n  value = data.aws_instance.data_instance\r\n}\r\n\r\noutput \"instance_public_ip\" {\r\n  value = data.aws_instance.data_instance.public_ip\r\n}\r\n"
  },
  {
    "path": "labs/dynamic-blocks/main.tf",
    "content": "terraform {\r\n  required_providers {\r\n    aws = {\r\n      source  = \"hashicorp/aws\"\r\n      version = \"~> 4.16\"\r\n    }\r\n  }\r\n\r\n  required_version = \">= 1.2.0\"\r\n}\r\n\r\nprovider \"aws\" {\r\n\tregion = \"eu-central-1\"\r\n}\r\n\r\nresource \"aws_vpc\" \"my_vpc\" {\r\n  cidr_block           = \"10.0.0.0/16\"\r\n  enable_dns_hostnames = true\r\n  tags = {\r\n    Name = \"My VPC\"\r\n  }\r\n}\r\n\r\nresource \"aws_subnet\" \"public\" {\r\n  vpc_id            = aws_vpc.my_vpc.id\r\n  cidr_block        = \"10.0.0.0/24\"\r\n  availability_zone = \"eu-central-1c\"\r\n  tags = {\r\n    Name = \"Public Subnet\"\r\n  }\r\n}\r\n\r\nresource \"aws_internet_gateway\" \"my_vpc_igw\" {\r\n  vpc_id = aws_vpc.my_vpc.id\r\n  tags = {\r\n    Name = \"My VPC - Internet Gateway\"\r\n  }\r\n}\r\n\r\nresource \"aws_route_table\" \"my_vpc_eu_central_1c_public\" {\r\n    vpc_id = aws_vpc.my_vpc.id\r\n    route {\r\n        cidr_block = \"0.0.0.0/0\"\r\n        gateway_id = aws_internet_gateway.my_vpc_igw.id\r\n    }\r\n    tags = {\r\n        Name = \"Public Subnet Route Table\"\r\n    }\r\n}\r\nresource \"aws_route_table_association\" \"my_vpc_eu_central_1c_public\" {\r\n    subnet_id      = aws_subnet.public.id\r\n    route_table_id = aws_route_table.my_vpc_eu_central_1c_public.id\r\n}\r\n\r\nlocals {\r\n   ingress_rules = [{\r\n      port        = 22\r\n      description = \"Ingress rules for port SSH\"\r\n   },\r\n   {\r\n      port        = 80\r\n      description = \"Ingress rules for port HTTP\"\r\n   },\r\n   {\r\n      port        = 443\r\n      description = \"Ingress rules for port HTTPS\"\r\n   }]\r\n}\r\n\r\nresource \"aws_security_group\" \"main\" {\r\n   name        = \"resource_with_dynamic_block\"\r\n   description = \"Allow SSH inbound connections\"\r\n   vpc_id      =  aws_vpc.my_vpc.id # todo: update it with data.aws_vpc.main.id\r\n\r\n   dynamic \"ingress\" {\r\n      for_each = local.ingress_rules\r\n\r\n      content {\r\n         description = ingress.value.description\r\n         from_port   = ingress.value.port\r\n         to_port     = ingress.value.port\r\n         protocol    = \"tcp\"\r\n         cidr_blocks = [\"0.0.0.0/0\"]\r\n      }\r\n   }\r\n\r\n   egress {\r\n    from_port       = 0\r\n    to_port         = 0\r\n    protocol        = \"-1\"\r\n    cidr_blocks     = [\"0.0.0.0/0\"]\r\n   }\r\n\r\n   tags = {\r\n      Name = \"AWS security group dynamic block\"\r\n   }\r\n}\r\n\r\nresource \"aws_instance\" \"ubuntu2204\" {\r\n  ami                         = \"ami-0d1ddd83282187d18\" # Ubuntu 22.04 eu-central-1 Frankfurt\r\n  instance_type               = \"t2.nano\"\r\n  key_name                    = \"testkey\"\r\n  vpc_security_group_ids      = [aws_security_group.main.id]\r\n  subnet_id                   = aws_subnet.public.id\r\n  associate_public_ip_address = true\r\n  tags = {\r\n    Name = \"Ubuntu 22.04\"\r\n  }\r\n}\r\n\r\noutput \"instance_ubuntu2204_public_ip\" {\r\n  value = \"${aws_instance.ubuntu2204.public_ip}\"\r\n}\r\n\r\n\r\n"
  },
  {
    "path": "labs/iamuser-metaargs-count-for-foreach-map/count/main.tf",
    "content": "# https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role\r\n# https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy_attachment\r\n# IAM users - roles - permissions\r\n# User         -> User Group -> Policy (Permission)\r\n# AWS Services -> Roles      -> Policy (Permission)\r\nterraform {\r\n  required_providers {\r\n    aws = {\r\n      source  = \"hashicorp/aws\"\r\n      version = \"~> 4.16\"\r\n    }\r\n  }\r\n\r\n  required_version = \">= 1.2.0\"\r\n}\r\n#####################################################\r\n# User - User Group Attachment (With Index Count)\r\nresource \"aws_iam_user_group_membership\" \"user1_group_attach\" {\r\n  user = aws_iam_user.user_example[0].name\r\n\r\n  groups = [\r\n    aws_iam_group.admin_group.name,\r\n    aws_iam_group.dev_group.name,\r\n  ]\r\n}\r\n\r\nresource \"aws_iam_user_group_membership\" \"user2_group_attach\" {\r\n  user = aws_iam_user.user_example[1].id\r\n\r\n  groups = [\r\n    aws_iam_group.admin_group.name\r\n  ]\r\n}\r\n\r\nresource \"aws_iam_user_group_membership\" \"user3_group_attach\" {\r\n  user = aws_iam_user.user_example[2].name\r\n\r\n  groups = [\r\n    aws_iam_group.dev_group.name\r\n  ]\r\n}\r\n#####################################################\r\n# User Group Definition\r\nresource \"aws_iam_group\" \"admin_group\" {\r\n  name = \"admin_group\"\r\n}\r\n\r\nresource \"aws_iam_group\" \"dev_group\" {\r\n  name = \"dev_group\"\r\n}\r\n#####################################################\r\n# Policy Definition, Policy-Group Attachment\r\ndata \"aws_iam_policy_document\" \"admin_policy\" {\r\n  statement {\r\n    effect    = \"Allow\"\r\n    actions   = [\"*\"]\r\n    resources = [\"*\"]\r\n  }\r\n}\r\nresource \"aws_iam_policy\" \"admin_policy\" {\r\n  name        = \"admin-policy\"\r\n  description = \"Admin policy\"\r\n  policy      = data.aws_iam_policy_document.admin_policy.json\r\n}\r\n\r\ndata \"aws_iam_policy_document\" \"ec2_policy\" {\r\n  statement {\r\n    effect    = \"Allow\"\r\n    actions   = [\"ec2:Describe*\"]\r\n    resources = [\"*\"]\r\n  }\r\n}\r\n\r\nresource \"aws_iam_policy\" \"ec2_policy\" {\r\n  name        = \"ec2-policy\"\r\n  description = \"EC2 policy\"\r\n  policy      = data.aws_iam_policy_document.ec2_policy.json\r\n}\r\n\r\n#####################################################\r\n# Policy Attachment to the Admin, Dev Group \r\nresource \"aws_iam_group_policy_attachment\" \"admin_group_admin_policy_attach\" {\r\n  group      = aws_iam_group.admin_group.name\r\n  policy_arn = aws_iam_policy.admin_policy.arn\r\n}\r\n\r\nresource \"aws_iam_group_policy_attachment\" \"dev_group_ec2_policy_attach\" {\r\n  group      = aws_iam_group.dev_group.name\r\n  policy_arn = aws_iam_policy.ec2_policy.arn\r\n}\r\n\r\n#####################################################\r\n# Username Definition\r\n# With Count\r\nresource \"aws_iam_user\" \"user_example\" {\r\n  count = length(var.user_names)\r\n  name  = var.user_names[count.index]\r\n}\r\n# count, use list \r\nvariable \"user_names\" {\r\n  description = \"IAM usernames\"\r\n  type        = list(string)\r\n  default     = [\"username1_admin_dev\", \"username2_admin\", \"username3_dev_ec2\"]\r\n}\r\n#####################################################\r\n# With for loop\r\noutput \"print_the_names\" {\r\n  value = [for name in var.user_names : name]\r\n}\r\n"
  },
  {
    "path": "labs/iamuser-metaargs-count-for-foreach-map/for_each/main.tf",
    "content": "# https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role\r\n# https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy_attachment\r\n# IAM users - roles - permissions\r\n# User         -> User Group -> Policy (Permission)\r\nterraform {\r\n  required_providers {\r\n    aws = {\r\n      source  = \"hashicorp/aws\"\r\n      version = \"~> 4.16\"\r\n    }\r\n  }\r\n\r\n  required_version = \">= 1.2.0\"\r\n}\r\n\r\n#####################################################\r\n# User - User Group Attachment (With Index Count)\r\nresource \"aws_iam_user_group_membership\" \"user1_group_attach\" {\r\n  user = aws_iam_user.user_example[\"username1_admin_dev\"].name\r\n\r\n  groups = [\r\n    aws_iam_group.admin_group.name,\r\n    aws_iam_group.dev_group.name,\r\n  ]\r\n}\r\n\r\nresource \"aws_iam_user_group_membership\" \"user2_group_attach\" {\r\n  user = aws_iam_user.user_example[\"username2_admin\"].id\r\n\r\n  groups = [\r\n    aws_iam_group.admin_group.name\r\n  ]\r\n}\r\n\r\nresource \"aws_iam_user_group_membership\" \"user3_group_attach\" {\r\n  user = aws_iam_user.user_example[\"username3_dev_s3\"].name\r\n\r\n  groups = [\r\n    aws_iam_group.dev_group.name\r\n  ]\r\n}\r\n#####################################################\r\n# User Group Definition\r\nresource \"aws_iam_group\" \"admin_group\" {\r\n  name = \"admin_group\"\r\n}\r\n\r\nresource \"aws_iam_group\" \"dev_group\" {\r\n  name = \"dev_group\"\r\n}\r\n#####################################################\r\n# Policy Definition, Policy-Group Attachment\r\ndata \"aws_iam_policy_document\" \"admin_policy\" {\r\n  statement {\r\n    effect    = \"Allow\"\r\n    actions   = [\"*\"]\r\n    resources = [\"*\"]\r\n  }\r\n}\r\nresource \"aws_iam_policy\" \"admin_policy\" {\r\n  name        = \"admin-policy\"\r\n  description = \"Admin policy\"\r\n  policy      = data.aws_iam_policy_document.admin_policy.json\r\n}\r\n\r\ndata \"aws_iam_policy_document\" \"s3_policy\" {\r\n  statement {\r\n    effect    = \"Allow\"\r\n    actions   = [\"s3:*\"]\r\n    resources = [\r\n      \"arn:aws:s3:::mybucket\",\r\n      \"arn:aws:s3:::mybucket/*\"\r\n    ]\r\n  }\r\n}\r\n\r\nresource \"aws_iam_policy\" \"s3_policy\" {\r\n  name        = \"s3-policy\"\r\n  description = \"S3 policy\"\r\n  policy      = data.aws_iam_policy_document.s3_policy.json\r\n}\r\n\r\n#####################################################\r\n# Policy Attachment to the Admin, Dev Group \r\nresource \"aws_iam_group_policy_attachment\" \"admin_group_admin_policy_attach\" {\r\n  group      = aws_iam_group.admin_group.name\r\n  policy_arn = aws_iam_policy.admin_policy.arn\r\n}\r\n\r\nresource \"aws_iam_group_policy_attachment\" \"dev_group_s3_policy_attach\" {\r\n  group      = aws_iam_group.dev_group.name\r\n  policy_arn = aws_iam_policy.s3_policy.arn\r\n}\r\n#####################################################\r\n# With for_each\r\nresource \"aws_iam_user\" \"user_example\" {\r\n  for_each = var.user_names\r\n  name  = each.value\r\n}\r\n# for each, use set instead of list\r\nvariable \"user_names\" {\r\n  description = \"IAM usernames\"\r\n  type        = set(string)\r\n  default     = [\"username1_admin_dev\", \"username2_admin\", \"username3_dev_s3\"]\r\n}\r\n#####################################################\r\n# With for loop\r\noutput \"print_the_names\" {\r\n  value = [for name in var.user_names : name]\r\n}\r\n"
  },
  {
    "path": "labs/iamuser-metaargs-count-for-foreach-map/map/main.tf",
    "content": "terraform {\r\n  required_providers {\r\n    aws = {\r\n      source  = \"hashicorp/aws\"\r\n      version = \"~> 4.16\"\r\n    }\r\n  }\r\n\r\n  required_version = \">= 1.2.0\"\r\n}\r\n\r\n#####################################################\r\n# With for_each\r\nresource \"aws_iam_user\" \"example\" {\r\n  for_each = var.user_names\r\n  name  = each.value\r\n}\r\n# With Map\r\nvariable \"user_names\" {\r\n  description = \"map\"\r\n  type        = map(string)\r\n  default     = {\r\n    user1      = \"username1\"\r\n    user2      = \"username2\"\r\n    user3      = \"username3\"\r\n  }\r\n}\r\n# with for loop on map \r\noutput \"user_with_roles\" {\r\n  value = [for name, role in var.user_names : \"${name} is the ${role}\"]\r\n}\r\n"
  },
  {
    "path": "labs/modules/main.tf",
    "content": "terraform {\r\n  required_providers {\r\n    aws = {\r\n      source  = \"hashicorp/aws\"\r\n      version = \"~> 4.16\"\r\n    }\r\n  }\r\n\r\n  required_version = \">= 1.2.0\"\r\n}\r\n\r\n\r\nmodule \"webserver-1\" {\r\n  source = \".//module1\"\r\n\r\n  instance_type     =   \"t2.nano\"\r\n  tag               =   \"Webserver1 - Module1 - 20.04\"\r\n  location          =   \"eu-central-1\"\r\n  availability_zone =   \"eu-central-1c\"\r\n  ami               =   \"ami-0e067cc8a2b58de59\" # Ubuntu 20.04 eu-central-1 Frankfurt\r\n\r\n}\r\n\r\nmodule \"webserver-2\" {\r\n  source = \".//module2\"\r\n\r\n  instance_type     =   \"t2.micro\"\r\n  tag               =   \"Webserver2 - Module2 - 22.04\"\r\n  location          =   \"eu-central-1\"\r\n  availability_zone =   \"eu-central-1a\"\r\n  ami               =   \"ami-0d1ddd83282187d18\" # Ubuntu 22.04 eu-central-1 Frankfurt\r\n}"
  },
  {
    "path": "labs/modules/module1/main.tf",
    "content": "terraform {\r\n  required_providers {\r\n    aws = {\r\n      source  = \"hashicorp/aws\"\r\n      version = \"~> 4.16\"\r\n    }\r\n  }\r\n\r\n  required_version = \">= 1.2.0\"\r\n}\r\n\r\nprovider \"aws\" {\r\n   region     = var.location\r\n}\r\n\r\nlocals {\r\n  staging_env = \"module1\"\r\n}\r\n\r\nresource \"aws_vpc\" \"my_vpc\" {\r\n  cidr_block           = \"10.0.0.0/16\"\r\n  enable_dns_hostnames = true\r\n  tags = {\r\n    Name = \"${local.staging_env}-vpc-tag\"\r\n  }\r\n}\r\n\r\nresource \"aws_subnet\" \"public\" {\r\n  vpc_id            = aws_vpc.my_vpc.id\r\n  cidr_block        = \"10.0.0.0/24\"\r\n  availability_zone = var.availability_zone\r\n  tags = {\r\n    Name = \"${local.staging_env}-subnet-tag\"\r\n  }\r\n}\r\n\r\nresource \"aws_internet_gateway\" \"igw\" {\r\n  vpc_id = aws_vpc.my_vpc.id\r\n  tags = {\r\n    Name = \"${local.staging_env}-Internet Gateway\"\r\n  }\r\n}\r\n\r\nresource \"aws_route_table\" \"rt\" {\r\n    vpc_id = aws_vpc.my_vpc.id\r\n    route {\r\n        cidr_block = \"0.0.0.0/0\"\r\n        gateway_id = aws_internet_gateway.igw.id\r\n    }\r\n    tags = {\r\n        Name = \"${local.staging_env}- Public Subnet Route Table\"\r\n    }\r\n}\r\nresource \"aws_route_table_association\" \"rta\" {\r\n    subnet_id      = aws_subnet.public.id\r\n    route_table_id = aws_route_table.rt.id\r\n}\r\n\r\nresource \"aws_security_group\" \"ssg\" {\r\n  name        = \"module1_security_group\"    # name should be different on modules\r\n  description = \"Allow SSH inbound connections\"\r\n  vpc_id      = aws_vpc.my_vpc.id\r\n  # for SSH\r\n  ingress {\r\n    from_port   = 22\r\n    to_port     = 22\r\n    protocol    = \"tcp\"\r\n    cidr_blocks = [\"0.0.0.0/0\"]\r\n  }\r\n  # for HTTP Apache Server\r\n  ingress {\r\n    from_port   = 80\r\n    to_port     = 80\r\n    protocol    = \"tcp\"\r\n    cidr_blocks = [\"0.0.0.0/0\"]\r\n  }\r\n  # for HTTPS Apache Server\r\n  ingress {\r\n    from_port   = 443\r\n    to_port     = 443\r\n    protocol    = \"tcp\"\r\n    cidr_blocks = [\"0.0.0.0/0\"]\r\n  }\r\n  egress {\r\n    from_port       = 0\r\n    to_port         = 0\r\n    protocol        = \"-1\"\r\n    cidr_blocks     = [\"0.0.0.0/0\"]\r\n  }\r\n  tags = {\r\n    Name = \"allow_ssh_sg\"\r\n  }\r\n}\r\n\r\nresource \"aws_instance\" \"ec2\" {\r\n   ami                         = var.ami\r\n   instance_type               = var.instance_type\r\n   subnet_id                   = aws_subnet.public.id\r\n   associate_public_ip_address = true\r\n   vpc_security_group_ids      = [aws_security_group.ssg.id]\r\n   user_data = <<-EOF\r\n\t\t           #! /bin/bash\r\n                           sudo apt-get update\r\n\t\t           sudo apt-get install -y apache2\r\n\t\t           sudo systemctl start apache2\r\n\t\t           sudo systemctl enable apache2\r\n\t\t           echo \"<h1>!! MODULE-1 !!:  Deployed via Terraform from $(hostname -f)</h1>\" | sudo tee /var/www/html/index.html\r\n  EOF\r\n  tags = {\r\n    Name = var.tag\r\n  }\r\n  \r\n}\r\n\r\n# output single values\r\noutput \"public_ip\" {\r\n  value = aws_instance.ec2.public_ip\r\n}\r\n\r\n"
  },
  {
    "path": "labs/modules/module1/variables.tf",
    "content": "variable \"instance_type\" {\r\n    type = string\r\n    description = \"EC2 Instance Type\"\r\n}\r\n\r\nvariable \"tag\" {\r\n    type = string\r\n    description = \"The tag for the EC2 instance\"\r\n}\r\n\r\nvariable \"location\" {\r\n    type = string\r\n    description = \"The project region\"\r\n    default = \"eu-central-1\"\r\n}\r\n\r\nvariable  \"availability_zone\" {\r\n    type = string\r\n    description = \"The project availability zone\"\r\n    default = \"eu-central-1c\"\r\n} \r\n\r\nvariable \"ami\" {\r\n    type = string\r\n    description = \"The project region\"\r\n}\r\n\r\n"
  },
  {
    "path": "labs/modules/module2/main.tf",
    "content": "terraform {\r\n  required_providers {\r\n    aws = {\r\n      source  = \"hashicorp/aws\"\r\n      version = \"~> 4.16\"\r\n    }\r\n  }\r\n\r\n  required_version = \">= 1.2.0\"\r\n}\r\n\r\nprovider \"aws\" {\r\n   region     = var.location\r\n}\r\n\r\nlocals {\r\n  staging_env = \"module2\"\r\n}\r\n\r\nresource \"aws_vpc\" \"my_vpc\" {\r\n  cidr_block           = \"10.5.0.0/16\"\r\n  enable_dns_hostnames = true\r\n  tags = {\r\n    Name = \"${local.staging_env}-vpc-tag\"\r\n  }\r\n}\r\n\r\nresource \"aws_subnet\" \"public\" {\r\n  vpc_id            = aws_vpc.my_vpc.id\r\n  cidr_block        = \"10.5.0.0/24\"\r\n  availability_zone = var.availability_zone\r\n  tags = {\r\n    Name = \"${local.staging_env}-subnet-tag\"\r\n  }\r\n}\r\n\r\nresource \"aws_internet_gateway\" \"igw\" {\r\n  vpc_id = aws_vpc.my_vpc.id\r\n  tags = {\r\n    Name = \"${local.staging_env}-Internet Gateway\"\r\n  }\r\n}\r\n\r\nresource \"aws_route_table\" \"rt\" {\r\n    vpc_id = aws_vpc.my_vpc.id\r\n    route {\r\n        cidr_block = \"0.0.0.0/0\"\r\n        gateway_id = aws_internet_gateway.igw.id\r\n    }\r\n    tags = {\r\n        Name = \"${local.staging_env}- Public Subnet Route Table\"\r\n    }\r\n}\r\nresource \"aws_route_table_association\" \"rta\" {\r\n    subnet_id      = aws_subnet.public.id\r\n    route_table_id = aws_route_table.rt.id\r\n}\r\n\r\nresource \"aws_security_group\" \"ssg\" {\r\n  name        = \"module2_security_group\"    # name should be different on modules\r\n  description = \"Allow SSH inbound connections\"\r\n  vpc_id      = aws_vpc.my_vpc.id\r\n  # for SSH\r\n  ingress {\r\n    from_port   = 22\r\n    to_port     = 22\r\n    protocol    = \"tcp\"\r\n    cidr_blocks = [\"0.0.0.0/0\"]\r\n  }\r\n  # for HTTP Apache Server\r\n  ingress {\r\n    from_port   = 80\r\n    to_port     = 80\r\n    protocol    = \"tcp\"\r\n    cidr_blocks = [\"0.0.0.0/0\"]\r\n  }\r\n  # for HTTPS Apache Server\r\n  ingress {\r\n    from_port   = 443\r\n    to_port     = 443\r\n    protocol    = \"tcp\"\r\n    cidr_blocks = [\"0.0.0.0/0\"]\r\n  }\r\n  egress {\r\n    from_port       = 0\r\n    to_port         = 0\r\n    protocol        = \"-1\"\r\n    cidr_blocks     = [\"0.0.0.0/0\"]\r\n  }\r\n  tags = {\r\n    Name = \"allow_ssh_sg\"\r\n  }\r\n}\r\n\r\nresource \"aws_instance\" \"ec2\" {\r\n   ami                         = var.ami\r\n   instance_type               = var.instance_type\r\n   subnet_id                   = aws_subnet.public.id\r\n   associate_public_ip_address = true\r\n   vpc_security_group_ids      = [aws_security_group.ssg.id]\r\n   user_data = <<-EOF\r\n\t\t           #! /bin/bash\r\n                           sudo apt-get update\r\n\t\t           sudo apt-get install -y apache2\r\n\t\t           sudo systemctl start apache2\r\n\t\t           sudo systemctl enable apache2\r\n\t\t           echo \"<h1>** MODULE-2 **:  Deployed via Terraform from $(hostname -f)</h1>\" | sudo tee /var/www/html/index.html\r\n  EOF\r\n  tags = {\r\n    Name = var.tag\r\n  }\r\n  \r\n}\r\n\r\n# output single values\r\noutput \"public_ip\" {\r\n  value = aws_instance.ec2.public_ip\r\n}\r\n\r\n"
  },
  {
    "path": "labs/modules/module2/variables.tf",
    "content": "variable \"instance_type\" {\r\n    type = string\r\n    description = \"EC2 Instance Type\"\r\n}\r\n\r\nvariable \"tag\" {\r\n    type = string\r\n    description = \"The tag for the EC2 instance\"\r\n}\r\n\r\nvariable \"location\" {\r\n    type = string\r\n    description = \"The project region\"\r\n    default = \"eu-central-1\"\r\n}\r\n\r\nvariable  \"availability_zone\" {\r\n    type = string\r\n    description = \"The project availability zone\"\r\n    default = \"eu-central-1c\"\r\n} \r\n\r\nvariable \"ami\" {\r\n    type = string\r\n    description = \"The project region\"\r\n}\r\n\r\n"
  },
  {
    "path": "labs/provisioners-nullresources/main.tf",
    "content": "terraform {\r\n  required_providers {\r\n    aws = {\r\n      source  = \"hashicorp/aws\"\r\n      version = \"~> 4.16\"\r\n    }\r\n  }\r\n  required_version = \">= 1.2.0\"\r\n}\r\n\r\nprovider \"aws\" {\r\n\tregion = \"eu-central-1\"\r\n}\r\n\r\nresource \"aws_vpc\" \"my_vpc\" {\r\n  cidr_block           = \"10.0.0.0/16\"\r\n  enable_dns_hostnames = true\r\n  tags = {\r\n    Name = \"My VPC\"\r\n  }\r\n}\r\n\r\nresource \"aws_subnet\" \"public\" {\r\n  vpc_id            = aws_vpc.my_vpc.id\r\n  cidr_block        = \"10.0.0.0/24\"\r\n  availability_zone = \"eu-central-1c\"\r\n  tags = {\r\n    Name = \"Public Subnet\"\r\n  }\r\n}\r\n\r\nresource \"aws_internet_gateway\" \"my_vpc_igw\" {\r\n  vpc_id = aws_vpc.my_vpc.id\r\n  tags = {\r\n    Name = \"My VPC - Internet Gateway\"\r\n  }\r\n}\r\n\r\nresource \"aws_route_table\" \"my_vpc_eu_central_1c_public\" {\r\n    vpc_id = aws_vpc.my_vpc.id\r\n    route {\r\n        cidr_block = \"0.0.0.0/0\"\r\n        gateway_id = aws_internet_gateway.my_vpc_igw.id\r\n    }\r\n    tags = {\r\n        Name = \"Public Subnet Route Table\"\r\n    }\r\n}\r\nresource \"aws_route_table_association\" \"my_vpc_eu_central_1c_public\" {\r\n    subnet_id      = aws_subnet.public.id\r\n    route_table_id = aws_route_table.my_vpc_eu_central_1c_public.id\r\n}\r\n\r\nresource \"aws_security_group\" \"allow_ssh\" {\r\n  name        = \"allow_ssh_sg\"\r\n  description = \"Allow SSH inbound connections\"\r\n  vpc_id      = aws_vpc.my_vpc.id\r\n  # for SSH\r\n  ingress {\r\n    from_port   = 22\r\n    to_port     = 22\r\n    protocol    = \"tcp\"\r\n    cidr_blocks = [\"0.0.0.0/0\"]\r\n  }\r\n  egress {\r\n    from_port       = 0\r\n    to_port         = 0\r\n    protocol        = \"-1\"\r\n    cidr_blocks     = [\"0.0.0.0/0\"]\r\n  }\r\n  tags = {\r\n    Name = \"allow_ssh_sg\"\r\n  }\r\n}\r\n\r\nresource \"aws_instance\" \"ubuntu2204\" {\r\n\r\n  ami                         = \"ami-0d1ddd83282187d18\" # Ubuntu 22.04 eu-central-1 Frankfurt\r\n  instance_type               = \"t2.nano\" \r\n  key_name                    = \"testkey\"\r\n  vpc_security_group_ids      = [aws_security_group.allow_ssh.id]\r\n  subnet_id                   = aws_subnet.public.id\r\n  associate_public_ip_address = true\r\n\r\n  tags = {\r\n    Name = \"Ubuntu 22.04\"\r\n  }\r\n\r\n  provisioner \"file\" {\r\n    source      = \"test-file.txt\" \r\n    destination = \"/home/ubuntu/test-file.txt\"\r\n  }\r\n\r\n  provisioner \"file\" {\r\n    content     = \"I want to copy this string to the destination file => server.txt (using provisioner file content)\"\r\n    destination = \"/home/ubuntu/server.txt\"\r\n  }\r\n  \r\n  provisioner \"remote-exec\" {\r\n    inline = [\r\n      \"touch hello.txt\",\r\n      \"echo helloworld remote-exec provisioner >> hello.txt\",\r\n    ]\r\n  }\r\n\r\n  connection {\r\n      type        = \"ssh\"\r\n      host        = self.public_ip\r\n      user        = \"ubuntu\"\r\n      private_key = file(\"testkey.pem\")\r\n      timeout     = \"4m\"\r\n   }\r\n}\r\n\r\nresource \"null_resource\" \"example\" {\r\n  provisioner \"local-exec\" {\r\n    command = \"'This is test file for null resource local-exec' >>  nullresource-generated.txt\"\r\n    interpreter = [\"PowerShell\", \"-Command\"]\r\n  }\r\n}\r\n\r\n"
  },
  {
    "path": "labs/provisioners-nullresources/test-file.txt",
    "content": "this is test file \r\ntransferring this file to remote instance with \"provisioner file\""
  },
  {
    "path": "labs/template/main.tf",
    "content": "terraform {\r\n  required_providers {\r\n    aws = {\r\n      source  = \"hashicorp/aws\"\r\n      version = \"~> 4.16\"\r\n    }\r\n  }\r\n\r\n  required_version = \">= 1.2.0\"\r\n}\r\n\r\nprovider \"aws\" {\r\n\tregion = \"eu-central-1\"\r\n}\r\n\r\nresource \"aws_iam_user\" \"newuser\" {\r\n  name = \"New-User\"     # must only contain alphanumeric characters, hyphens, underscores, commas, periods, @ symbols, plus and equals signs\r\n}\r\nresource \"aws_iam_access_key\" \"access_key\" {\r\n  user = aws_iam_user.newuser.name\r\n}\r\n\r\nresource \"aws_iam_user_policy\" \"instanceManageUser_assume_role\" {\r\n  name = \"EC2-S3-Lambda-DynamoDb-Policy\"\r\n  user = \"${aws_iam_user.newuser.name}\"\r\n  policy = templatefile(\"${path.module}/policy.tftpl\", {\r\n    ec2_policies = [\r\n      \"ec2:RunInstances\",\r\n      \"ec2:StopInstances\",\r\n      \"ec2:StartInstances\",\r\n      \"ec2:TerminateInstances\",\r\n      \"ec2:TerminateInstances\",\r\n      \"ec2:Describe*\",\r\n      \"ec2:CreateTags\",\r\n      \"ec2:RequestSpotInstances\"\r\n    ],\r\n    s3_policies = [\r\n      \"s3:Get*\",\r\n      \"s3:List*\",\r\n      \"s3:Describe*\",\r\n      \"s3-object-lambda:Get*\",\r\n      \"s3-object-lambda:List*\"\r\n    ],\r\n    lambda_policies = [\r\n      \"lambda:Create*\",\r\n      \"lambda:List*\",\r\n      \"lambda:Delete*\",\r\n      \"lambda:Get*\"\r\n    ],\r\n    dynamodb_policies = [\r\n      \"dynamodb:Describe*\",\r\n      \"dynamodb:Update*\",\r\n      \"dynamodb:Get*\",\r\n      \"dynamodb:List*\",\r\n      \"dynamodb:BatchGetItem\",\r\n      \"dynamodb:Query\",\r\n      \"dynamodb:Scan\",\r\n      \"dynamodb:PartiQLSelect\"\r\n    ],\r\n  })\r\n}\r\n\r\noutput \"secret_key\" {\r\n  value = aws_iam_access_key.access_key.secret\r\n  sensitive = true\r\n}\r\n\r\noutput \"access_key\" {\r\n  value = aws_iam_access_key.access_key.id\r\n}"
  },
  {
    "path": "labs/template/policy.tftpl",
    "content": "{\r\n    \"Version\": \"2012-10-17\",\r\n    \"Statement\": [\r\n        {\r\n            \"Effect\": \"Allow\",\r\n            \"Action\": ${jsonencode(ec2_policies)},\r\n            \"Resource\": \"*\"\r\n        },\r\n        {\r\n            \"Effect\": \"Allow\",\r\n            \"Action\": ${jsonencode(s3_policies)},\r\n            \"Resource\": \"*\"\r\n        },\r\n        {\r\n            \"Effect\": \"Allow\",\r\n            \"Action\": ${jsonencode(lambda_policies)},\r\n            \"Resource\": \"*\"\r\n        },\r\n         {\r\n            \"Effect\": \"Allow\",\r\n            \"Action\": ${jsonencode(dynamodb_policies)},\r\n            \"Resource\": \"*\"\r\n        }\r\n    ]\r\n}"
  },
  {
    "path": "labs/terraform-docker-without-cloud/main.tf",
    "content": "# windows, prerequisite: install docker on your system\r\n# details, usage: https://registry.terraform.io/providers/kreuzwerker/docker/latest/docs/resources/container\r\nterraform {\r\n  required_providers {\r\n    docker = {\r\n      source  = \"kreuzwerker/docker\"\r\n      version = \"~> 3.0.2\"\r\n    }\r\n  }\r\n}\r\n\r\nprovider \"docker\" {\r\n  host    =  \"npipe:////.//pipe//docker_engine\"\r\n}\r\n\r\nresource \"docker_image\" \"windows\" {\r\n  name         = \"mcr.microsoft.com/powershell:lts-windowsservercore-1809\"\r\n  keep_locally = true\r\n}\r\n\r\n# docker container run -p 80:8000 --name=tutorial -it mcr.microsoft.com/powershell:lts-windowsservercore-1809 powershell\r\nresource \"docker_container\" \"windows\" {\r\n  image = docker_image.windows.image_id\r\n  name  = \"tutorial\"\r\n  \r\n  stdin_open = true             # docker run -i\r\n  tty        = true             # docker run -t\r\n  \r\n  entrypoint = [\"powershell\"]\r\n  \r\n  ports {\r\n    internal = 80\r\n    external = 8000\r\n  }\r\n}\r\n\r\n#  docker container ls -a\r\n#  docker container exec -it tutorial powershell\r\n#  ls, exit\r\n#  terraform destroy -auto-approve\r\n"
  },
  {
    "path": "labs/variables-locals-output/main.tf",
    "content": "terraform {\r\n  required_providers {\r\n    aws = {\r\n      source  = \"hashicorp/aws\"\r\n      version = \"~> 4.16\"\r\n    }\r\n  }\r\n\r\n  required_version = \">= 1.2.0\"\r\n}\r\n\r\nprovider \"aws\" {\r\n   region     = var.location\r\n}\r\n\r\nlocals {\r\n  staging_env = \"staging\"\r\n}\r\n\r\nresource \"aws_vpc\" \"my_vpc\" {\r\n  cidr_block = \"10.0.0.0/16\"\r\n  enable_dns_hostnames = true\r\n  tags = {\r\n    Name = \"${local.staging_env}-vpc-tag\"\r\n  }\r\n}\r\n\r\nresource \"aws_subnet\" \"my_subnet\" {\r\n  vpc_id = aws_vpc.my_vpc.id\r\n  cidr_block = \"10.0.0.0/16\"\r\n  availability_zone = var.availability_zone\r\n  tags = {\r\n    Name = \"${local.staging_env}-subnet-tag\"\r\n  }\r\n}\r\n\r\nresource \"aws_internet_gateway\" \"my_vpc_igw\" {\r\n  vpc_id = aws_vpc.my_vpc.id\r\n  tags = {\r\n    Name = \"${local.staging_env}-Internet Gateway\"\r\n  }\r\n}\r\n\r\nresource \"aws_route_table\" \"my_vpc_eu_central_1c_public\" {\r\n    vpc_id = aws_vpc.my_vpc.id\r\n    route {\r\n        cidr_block = \"0.0.0.0/0\"\r\n        gateway_id = aws_internet_gateway.my_vpc_igw.id\r\n    }\r\n    tags = {\r\n        Name = \"${local.staging_env}- Public Subnet Route Table\"\r\n    }\r\n}\r\nresource \"aws_route_table_association\" \"my_vpc_eu_central_1c_public\" {\r\n    subnet_id      = aws_subnet.my_subnet.id\r\n    route_table_id = aws_route_table.my_vpc_eu_central_1c_public.id\r\n}\r\n\r\nresource \"aws_instance\" \"ec2_example\" {\r\n   \r\n   ami                         = var.ami\r\n   instance_type               = var.instance_type\r\n   subnet_id                   = aws_subnet.my_subnet.id\r\n   associate_public_ip_address = true\r\n   \r\n   tags = {\r\n           Name = var.tag\r\n   }\r\n}\r\n\r\n# output single values\r\noutput \"public_ip\" {\r\n  value = aws_instance.ec2_example.public_ip\r\n}\r\n\r\n# output single values\r\noutput \"public_dns\" {\r\n  value = aws_instance.ec2_example.public_dns\r\n} \r\n\r\n# output multiple values\r\noutput \"instance_ips\" {\r\n  value = {\r\n    public_ip  = aws_instance.ec2_example.public_ip\r\n    private_ip = aws_instance.ec2_example.private_ip\r\n  }\r\n} \r\n\r\n# terraform init \r\n\r\n# terraform plan --var-file=\"terraform-dev.tfvars\"\r\n# terraform apply --var-file=\"terraform-dev.tfvars\"\r\n# terraform destroy --var-file=\"terraform-dev.tfvars\"\r\n\r\n# terraform plan --var-file=\"terraform-prod.tfvars\"\r\n# terraform apply --var-file=\"terraform-prod.tfvars\"\r\n# terraform destroy --var-file=\"terraform-prod.tfvars\""
  },
  {
    "path": "labs/variables-locals-output/terraform-dev.tfvars",
    "content": " instance_type     =   \"t2.nano\"\r\n tag               =   \"EC2 Instance for DEV\"\r\n location          =   \"eu-central-1\"\r\n availability_zone =   \"eu-central-1c\"\r\n ami               =   \"ami-0e067cc8a2b58de59\" # Ubuntu 20.04 eu-central-1 Frankfurt\r\n "
  },
  {
    "path": "labs/variables-locals-output/terraform-prod.tfvars",
    "content": " instance_type     =   \"t2.micro\"\r\n tag               =   \"EC2 Instance for PROD\"\r\n location          =   \"eu-central-1\"\r\n availability_zone =   \"eu-central-1c\"\r\n ami               =   \"ami-0d1ddd83282187d18\" # Ubuntu 22.04 eu-central-1 Frankfurt\r\n "
  },
  {
    "path": "labs/variables-locals-output/variables.tf",
    "content": "variable \"instance_type\" {\r\n    type = string\r\n    description = \"EC2 Instance Type\"\r\n}\r\n\r\nvariable \"tag\" {\r\n    type = string\r\n    description = \"The tag for the EC2 instance\"\r\n}\r\n\r\nvariable \"location\" {\r\n    type = string\r\n    description = \"The project region\"\r\n    default = \"eu-central-1\"\r\n}\r\n\r\nvariable  \"availability_zone\" {\r\n    type = string\r\n    description = \"The project availability zone\"\r\n    default = \"eu-central-1c\"\r\n} \r\n\r\nvariable \"ami\" {\r\n    type = string\r\n    description = \"The project region\"\r\n}\r\n\r\n"
  },
  {
    "path": "labs/workspace/main.tf",
    "content": "terraform {\r\n  required_providers {\r\n    aws = {\r\n      source  = \"hashicorp/aws\"\r\n      version = \"~> 4.16\"\r\n    }\r\n  }\r\n\r\n  required_version = \">= 1.2.0\"\r\n}\r\n\r\nprovider \"aws\" {\r\n\tregion = var.location\r\n}\r\n\r\nlocals {\r\n    tag = \"${terraform.workspace} EC2\"\r\n}\r\n\r\nresource \"aws_instance\" \"instance\" {\r\n\tami           = var.ami\r\n\tinstance_type = var.instance_type\r\n\r\n\ttags = {\r\n\t\tName = local.tag\r\n\t}\r\n}\r\n"
  },
  {
    "path": "labs/workspace/terraform-dev.tfvars",
    "content": "instance_type     =   \"t2.nano\"\r\nlocation          =   \"eu-central-1\"\r\nami               =   \"ami-0e067cc8a2b58de59\" # Ubuntu 20.04 eu-central-1 Frankfurt\r\n"
  },
  {
    "path": "labs/workspace/terraform-prod.tfvars",
    "content": "instance_type     =   \"t2.micro\"\r\nlocation          =   \"eu-central-1\"\r\nami               =   \"ami-0d1ddd83282187d18\" # Ubuntu 22.04 eu-central-1 Frankfurt\r\n"
  },
  {
    "path": "labs/workspace/variables.tf",
    "content": "variable \"instance_type\" {\r\n    type = string\r\n    description = \"EC2 Instance Type\"\r\n}\r\n\r\nvariable \"location\" {\r\n    type = string\r\n    description = \"The project region\"\r\n    default = \"eu-central-1\"\r\n}\r\n\r\nvariable \"ami\" {\r\n    type = string\r\n    description = \"The project region\"\r\n}\r\n"
  },
  {
    "path": "samples/codecommit-codepipeline-codebuild-codedeploy-lambda-container/lambda_bootstrap/lambda/Dockerfile",
    "content": "FROM public.ecr.aws/lambda/python:3.8\nCOPY requirements.txt ${LAMBDA_TASK_ROOT}\nRUN pip3 install --no-cache-dir -r requirements.txt\nCOPY aws-lambda-url.py ${LAMBDA_TASK_ROOT}\n\nCMD [\"aws-lambda-url.lambda_handler\"]"
  },
  {
    "path": "samples/codecommit-codepipeline-codebuild-codedeploy-lambda-container/lambda_bootstrap/lambda/aws-lambda-url.py",
    "content": "from bs4 import BeautifulSoup\nimport requests\nimport boto3\n\nurl=\"https://search.longhornrealty.com/idx/results/listings?pt=4&a_propStatus%5B%5D=Active&ccz=city&idxID=c007&per=25&srt=newest&city%5B%5D=22332&city%5B%5D=45916\"\npage = requests.get(url)\n\n\ndef lambda_handler(event, context):\n    try:\n        soup = BeautifulSoup(page.content, \"html.parser\")\n        results = soup.find(id=\"idx-results-category-active\")\n        listings = results.find_all(\"article\")\n\n        for listing in listings:\n            prices = listing.find(\n                'div', {'class': 'idx-listing-card__price'}).get_text()\n            address_city = listing.find(\n                'span', {'class': 'idx-listing-card__address--City'}).get_text()\n            print(prices, address_city)\n    except Exception as e:\n        print(e)\n"
  },
  {
    "path": "samples/codecommit-codepipeline-codebuild-codedeploy-lambda-container/lambda_bootstrap/lambda/docker-test.sh",
    "content": "#!bin/bash\n\n#aws sts get-caller-identity\n\ndocker build . -t aws-lambda-url:0.0.1\n\ndocker run \\\n    -p 9000:8080 \\\n    -e AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID \\\n    -e AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY \\\n    -e AWS_SESSION_TOKEN=$AWS_SESSION_TOKEN \\\n    -e AWS_REGION=$AWS_REGION \\\n    aws-lambda-url:0.0.1"
  },
  {
    "path": "samples/codecommit-codepipeline-codebuild-codedeploy-lambda-container/lambda_bootstrap/lambda/requirements.txt",
    "content": "beautifulsoup4\nrequests"
  },
  {
    "path": "samples/codecommit-codepipeline-codebuild-codedeploy-lambda-container/lambda_bootstrap/main.tf",
    "content": "data \"aws_ecr_image\" \"lambda_image_latest\" {\n  repository_name = split(\"/\", var.ecr_repo_url)[1]\n  image_tag       = \"latest\"\n}\n\nresource \"aws_iam_role\" \"iam_for_lambda\" {\n  name               = \"${var.env_namespace}_lambda_role\"\n  assume_role_policy = <<EOF\n{\n    \"Version\": \"2012-10-17\",\n    \"Statement\": [\n        {\n            \"Effect\": \"Allow\",\n            \"Principal\": {\n                \"Service\": \"lambda.amazonaws.com\"\n            },\n            \"Action\": \"sts:AssumeRole\"\n        }\n    ]\n}\nEOF\n}\n\nresource \"aws_iam_role_policy\" \"iam_policy_for_lambda\" {\n  role   = aws_iam_role.iam_for_lambda.name\n  policy = <<POLICY\n{\n  \"Version\": \"2012-10-17\",\n  \"Statement\": [\n    {\n      \"Effect\": \"Allow\",\n      \"Resource\": [\n        \"${var.ecr_repo_arn}\"\n      ],\n      \"Action\": [\n        \"ecr:*\"\n      ]\n    },\n    {\n      \"Effect\": \"Allow\",\n      \"Resource\": [\n        \"*\"\n      ],\n      \"Action\": [\n        \"ecr:GetAuthorizationToken\"\n      ]\n    }\n  ]\n}\nPOLICY\n}\nresource \"aws_lambda_function\" \"main\" {\n  function_name    = \"${var.env_namespace}_lambda\"\n  image_uri        = \"${var.ecr_repo_url}:latest\"\n  package_type     = \"Image\"\n  role             = aws_iam_role.iam_for_lambda.arn\n  source_code_hash = data.aws_ecr_image.lambda_image_latest.id\n}"
  },
  {
    "path": "samples/codecommit-codepipeline-codebuild-codedeploy-lambda-container/lambda_bootstrap/outputs.tf",
    "content": "output \"lambda_arn\" {\n    value = aws_lambda_function.main.arn\n}"
  },
  {
    "path": "samples/codecommit-codepipeline-codebuild-codedeploy-lambda-container/lambda_bootstrap/providers.tf",
    "content": "provider \"aws\" {\r\n  region = \"eu-central-1\"\r\n}\r\n\r\nterraform {\r\n  required_version = \">= 0.15\"\r\n  required_providers {\r\n    aws = {\r\n      source  = \"hashicorp/aws\"\r\n      version = \"~> 4.15.1\"\r\n      # Will allow installation of 4.15.1 and 4.15.10 but not 4.16.0\r\n      # Get error when using 4.16.0\r\n    }\r\n  }\r\n}\r\n\r\n# terraform {\r\n#     backend \"s3\" {\r\n#       encrypt = true\r\n#       bucket = \"BUCKET_NAME\"\r\n#       key = \"states/lambda/terraform.tfstate\"\r\n#       region = \"eu-central-1\"\r\n#   }\r\n# }"
  },
  {
    "path": "samples/codecommit-codepipeline-codebuild-codedeploy-lambda-container/lambda_bootstrap/terraform.tfvars",
    "content": "env_namespace = \"\"\necr_repo_url = \"\"\necr_repo_arn = \"\""
  },
  {
    "path": "samples/codecommit-codepipeline-codebuild-codedeploy-lambda-container/lambda_bootstrap/variables.tf",
    "content": "variable \"env_namespace\" {\n    type = string\n    description = \"Value is coming from tfvars file that is being updated by buildspec environment variables\"\n}\nvariable \"ecr_repo_url\" {\n    type = string\n    description = \"Value is coming from tfvars file that is being updated by buildspec environment variables\"\n}\nvariable \"ecr_repo_arn\" {\n    type = string\n    description = \"Value is coming from tfvars file that is being updated by buildspec environment variables\"\n}"
  },
  {
    "path": "samples/codecommit-codepipeline-codebuild-codedeploy-lambda-container/main.tf",
    "content": "locals {\n  env_namespace         = join(\"_\", [var.org_name, var.team_name, var.project_id, var.env[\"dev\"]])\n  general_namespace     = join(\"_\", [var.org_name, var.team_name, var.project_id])\n  #s3 bucket naming based on best practices: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html\n  s3_bucket_namespace   = join(\"-\", [var.org_name, var.team_name, var.project_id, var.env[\"dev\"]])\n}\ndata \"aws_caller_identity\" \"current\" {}\nmodule \"codepipeline\" {\n  source                 = \"./modules/codepipeline\"\n  general_namespace      = local.general_namespace\n  env_namespace          = local.env_namespace\n  s3_bucket_namespace    = local.s3_bucket_namespace\n  codecommit_repo        = module.codecommit.codecommit_configs.repository_name\n  codecommit_branch      = module.codecommit.codecommit_configs.default_branch\n  codebuild_image        = var.codebuild_image\n  codebuild_type         = var.codebuild_type\n  codebuild_compute_type = var.codebuild_compute_type\n  ecr_repo_arn           = module.ecr.ecr_configs.ecr_repo_arn\n  build_args = [\n    {\n      name  = \"REPO_URI\"\n      value = module.ecr.ecr_configs.ecr_repo_url\n    },\n    {\n      name  = \"REPO_ARN\"\n      value = module.ecr.ecr_configs.ecr_repo_arn\n    },\n    {\n      name  = \"TERRAFORM_VERSION\"\n      value = var.terraform_ver\n    },\n    {\n      name  = \"ENV_NAMESPACE\"\n      value = local.env_namespace\n    },\n    {\n      name  = \"AWS_ACCOUNT_ID\"\n      value = data.aws_caller_identity.current.account_id\n    }\n  ]\n}\n\nmodule \"codecommit\" {\n  source            = \"./modules/codecommit\"\n  general_namespace = local.general_namespace\n  env_namespace     = local.env_namespace\n  codecommit_branch = var.codecommit_branch\n}\n\nmodule \"ecr\" {\n  source            = \"./modules/ecr\"\n  general_namespace = local.general_namespace\n  env_namespace     = local.env_namespace\n}"
  },
  {
    "path": "samples/codecommit-codepipeline-codebuild-codedeploy-lambda-container/modules/codecommit/main.tf",
    "content": "\ndata \"aws_caller_identity\" \"current\" {}\nresource \"aws_codecommit_repository\" \"codecommit_repo\" {\n  repository_name = \"${var.general_namespace}_code_repo\"\n  default_branch  = \"${var.codecommit_branch}\"\n  description     = \"Application repo for lambda ${var.general_namespace}\"\n}"
  },
  {
    "path": "samples/codecommit-codepipeline-codebuild-codedeploy-lambda-container/modules/codecommit/outputs.tf",
    "content": "output \"codecommit_configs\" {\n    value = {\n        repository_name         = aws_codecommit_repository.codecommit_repo.repository_name\n        default_branch          = aws_codecommit_repository.codecommit_repo.default_branch\n        clone_repository_url    = aws_codecommit_repository.codecommit_repo.clone_url_http\n    }\n}"
  },
  {
    "path": "samples/codecommit-codepipeline-codebuild-codedeploy-lambda-container/modules/codecommit/variables.tf",
    "content": "variable \"codecommit_branch\" {\n    type = string\n    default = \"master\"\n}\nvariable \"general_namespace\" {\n    type = string\n}\nvariable \"env_namespace\" {\n    type = string\n}"
  },
  {
    "path": "samples/codecommit-codepipeline-codebuild-codedeploy-lambda-container/modules/codepipeline/main.tf",
    "content": "locals {\n  projects  = [\"build\", \"deploy\"]\n}\nresource \"aws_s3_bucket\" \"codepipeline_bucket\" {\n  bucket = \"${var.s3_bucket_namespace}-codepipeline-bucket\"\n}\n\nresource \"aws_s3_bucket_ownership_controls\" \"codepipeline_bucket_ownership\" {\n  bucket = aws_s3_bucket.codepipeline_bucket.id\n  rule {\n    object_ownership = \"BucketOwnerPreferred\"\n  }\n}\n\nresource \"aws_s3_bucket_acl\" \"codepipeline_bucket_acl\" {\n  depends_on = [aws_s3_bucket_ownership_controls.codepipeline_bucket_ownership]\n  bucket = aws_s3_bucket.codepipeline_bucket.id\n  acl    = \"private\"\n}\n\nresource \"aws_codebuild_project\" \"project\" {\n    count           = length(local.projects)\n    name            = \"${var.env_namespace}_${local.projects[count.index]}\"\n    #name           = \"${var.org}_${var.name}_${var.attribute}_${var.env[\"dev\"]}_codebuild_docker_build\"\n    build_timeout   = \"5\" #The default is 60 minutes.\n    service_role    = aws_iam_role.lambda_codebuild_role.arn\n    artifacts {\n        type = \"CODEPIPELINE\"\n    }\n    environment {\n      compute_type                = var.codebuild_compute_type\n      image                       = var.codebuild_image\n      type                        = var.codebuild_type\n      #compute_type               = \"BUILD_GENERAL1_MEDIUM\"\n      #image                      = \"aws/codebuild/amazonlinux2-x86_64-standard:3.0\"\n      #type                       = \"LINUX_CONTAINER\"\n      image_pull_credentials_type = \"CODEBUILD\"\n      privileged_mode             = true\n\n      dynamic \"environment_variable\" {\n        for_each = var.build_args\n        content {\n          name  = environment_variable.value.name\n          value = environment_variable.value.value\n        }\n      }\n    }\n    source {\n        type      = \"CODEPIPELINE\"\n        buildspec = file(\"${path.module}/templates/buildspec_${local.projects[count.index]}.yml\")\n        #buildspec = file(\"${path.module}/stage1-buildspec.yml\")\n    }\n\n    source_version = \"master\"\n\n    tags = {\n        env = var.env_namespace\n    }\n}\n\nresource \"aws_codepipeline\" \"codepipeline\" {\n  name     = \"${var.env_namespace}_pipeline\"\n  role_arn = aws_iam_role.lambda_codepipeline_role.arn\n\n  artifact_store {\n    location = aws_s3_bucket.codepipeline_bucket.bucket\n    type     = \"S3\"\n  }\n\n  stage {\n    name = \"Source\"\n\n    action {\n      name     = \"Source\"\n      category = \"Source\"\n      owner    = \"AWS\"\n      provider = \"CodeCommit\"\n      version  = \"1\"\n      output_artifacts = [\n      \"source_output\"]\n\n      configuration = {\n        #BranchName     = aws_codecommit_repository.lambda_codecommit_repo.default_branch\n        BranchName      = var.codecommit_branch\n        RepositoryName  = var.codecommit_repo\n        #RepositoryName = aws_codecommit_repository.lambda_codecommit_repo.repository_name\n      }\n    }\n  }\n\n  stage {\n    name = \"Build\"\n\n    action {\n      name     = \"Docker_Build\"\n      category = \"Build\"\n      owner    = \"AWS\"\n      provider = \"CodeBuild\"\n      input_artifacts = [\n      \"source_output\"]\n      version = \"1\"\n\n      configuration = {\n        ProjectName = aws_codebuild_project.project[0].name\n      }\n    }\n  }\n\n  stage {\n    name = \"Deploy\"\n\n    action {\n      name     = \"Deploy_Docker\"\n      category = \"Build\"\n      owner    = \"AWS\"\n      provider = \"CodeBuild\"\n      input_artifacts = [\n      \"source_output\"]\n      version = \"1\"\n\n      configuration = {\n        ProjectName = aws_codebuild_project.project[1].name\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "samples/codecommit-codepipeline-codebuild-codedeploy-lambda-container/modules/codepipeline/outputs.tf",
    "content": "output \"codepipeline_configs\" {\n    value = {\n        codepipeline = aws_codepipeline.codepipeline.arn\n    }\n}\noutput \"deployment_role_arn\" {\n    value = aws_iam_role.lambda_codebuild_role.arn\n}"
  },
  {
    "path": "samples/codecommit-codepipeline-codebuild-codedeploy-lambda-container/modules/codepipeline/roles.tf",
    "content": "resource \"aws_iam_role\" \"lambda_codepipeline_role\" {\n  name = \"${var.env_namespace}_codepipeline_role\"\n\n  assume_role_policy = <<EOF\n{\n  \"Version\": \"2012-10-17\",\n  \"Statement\": [\n    {\n      \"Effect\": \"Allow\",\n      \"Principal\": {\n        \"Service\": \"codepipeline.amazonaws.com\"\n      },\n      \"Action\": \"sts:AssumeRole\"\n    }\n  ]\n}\nEOF\n}\n\nresource \"aws_iam_role_policy\" \"lambda_codepipeline_policy\" {\n  name = \"${var.env_namespace}_codepipeline_policy\"\n  role = aws_iam_role.lambda_codepipeline_role.id\n\n  policy = <<EOF\n{\n  \"Version\": \"2012-10-17\",\n  \"Statement\": [\n    {\n      \"Effect\":\"Allow\",\n      \"Action\": [\n        \"s3:GetObject\",\n        \"s3:GetObjectVersion\",\n        \"s3:GetBucketVersioning\",\n        \"s3:PutObject\"\n      ],\n      \"Resource\": [\n        \"${aws_s3_bucket.codepipeline_bucket.arn}\",\n        \"${aws_s3_bucket.codepipeline_bucket.arn}/*\"\n      ]\n    },\n    {\n      \"Effect\": \"Allow\",\n      \"Action\": [\n        \"codebuild:*\",\n        \"codecommit:*\"\n      ],\n      \"Resource\": \"*\"\n    }\n  ]\n}\nEOF\n}\n\nresource \"aws_iam_role\" \"lambda_codebuild_role\" {\n  name               = \"${var.env_namespace}_codebuild_role\"\n  assume_role_policy = <<EOF\n{\n  \"Version\": \"2012-10-17\",\n  \"Statement\": [\n    {\n      \"Effect\": \"Allow\",\n      \"Principal\": {\n        \"Service\": \"codebuild.amazonaws.com\"\n      },\n      \"Action\": \"sts:AssumeRole\"\n    }\n  ]\n}\nEOF\n}\n\nresource \"aws_iam_role_policy\" \"lambda_codebuild_role_policy\" {\n  role   = aws_iam_role.lambda_codebuild_role.name\n  policy = <<POLICY\n{\n  \"Version\": \"2012-10-17\",\n  \"Statement\": [\n    {\n      \"Effect\": \"Allow\",\n      \"Resource\": [\n        \"*\"\n      ],\n      \"Action\": [\n        \"logs:CreateLogGroup\",\n        \"logs:CreateLogStream\",\n        \"logs:PutLogEvents\",\n        \"sts:AssumeRole\",\n        \"codebuild:*\",\n        \"lambda:*\",\n        \"iam:AddRoleToInstanceProfile\",\n        \"iam:AttachRolePolicy\",\n        \"iam:CreateInstanceProfile\",\n        \"iam:CreatePolicy\",\n        \"iam:CreateRole\",\n        \"iam:GetRole\",\n        \"iam:ListAttachedRolePolicies\",\n        \"iam:ListPolicies\",\n        \"iam:ListRolePolicies\",\n        \"iam:ListRoles\",\n        \"iam:PassRole\",\n        \"iam:PutRolePolicy\",\n        \"iam:UpdateAssumeRolePolicy\",\n        \"iam:GetRolePolicy\"\n\n      ]\n    },\n    {\n      \"Effect\": \"Allow\",\n      \"Resource\": [\n        \"${var.ecr_repo_arn}\"\n      ],\n      \"Action\": [\n        \"ecr:*\"\n      ]\n    },\n    {\n      \"Effect\": \"Allow\",\n      \"Resource\": [\n        \"*\"\n      ],\n      \"Action\": [\n        \"ecr:GetAuthorizationToken\"\n      ]\n    },\n    {\n      \"Effect\": \"Allow\",\n      \"Action\": [\n        \"s3:*\"\n      ],\n      \"Resource\": [\n        \"${aws_s3_bucket.codepipeline_bucket.arn}\",\n        \"${aws_s3_bucket.codepipeline_bucket.arn}/*\",\n        \"arn:aws:s3:::BUCKET_NAME\",\n        \"arn:aws:s3:::BUCKET_NAME/*\"\n      ]\n    }\n  ]\n}\nPOLICY\n}"
  },
  {
    "path": "samples/codecommit-codepipeline-codebuild-codedeploy-lambda-container/modules/codepipeline/templates/buildspec_build.yml",
    "content": "\nversion: 0.2\n\nphases:\n  pre_build:\n    commands:\n      - echo Logging in to Amazon ECR...\n      - aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com\n      - IMAGE_URI=$REPO_URI:latest\n      - echo $IMAGE_URI\n  build:\n    commands:\n      - echo `ls -lrt`\n      - echo Build started on `date`\n      - echo Building the Docker image...          \n      - docker build -t $IMAGE_URI ./lambda_bootstrap/lambda/\n  post_build:\n    commands:\n      - bash -c \"if [ /\"$CODEBUILD_BUILD_SUCCEEDING/\" == /\"0/\" ]; then exit 1; fi\"\n      - echo Build completed on `date`\n      - echo Pushing the Docker image...\n      - docker push $IMAGE_URI\n"
  },
  {
    "path": "samples/codecommit-codepipeline-codebuild-codedeploy-lambda-container/modules/codepipeline/templates/buildspec_deploy.yml",
    "content": "\nversion: 0.2\n\nphases:\n  install:\n    runtime-versions:\n      python: 3.7\n    commands:\n      - tf_version=$TERRAFORM_VERSION\n      - wget https://releases.hashicorp.com/terraform/\"$TERRAFORM_VERSION\"/terraform_\"$TERRAFORM_VERSION\"_linux_amd64.zip\n      - unzip terraform_\"$TERRAFORM_VERSION\"_linux_amd64.zip\n      - mv terraform /usr/local/bin/\n      - curl -sSLo install.sh https://install.hclq.sh\n      - sh install.sh\n  pre_build:\n    commands:\n      - echo Logging into Amazon ECR...\n      - aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com\n  build:\n    commands:\n      - echo Build started on `date`\n      - terraform --version\n      - cd lambda_bootstrap/\n      - echo Updating ENV_namespace in terraform.tfvars\n      - cat terraform.tfvars | hclq set 'env_namespace' $ENV_NAMESPACE | hclq set 'ecr_repo_url' $REPO_URI | hclq set 'ecr_repo_arn' $REPO_ARN | tee terraform.tfvars\n      - terraform init -input=false\n      - terraform validate\n      - terraform apply -auto-approve"
  },
  {
    "path": "samples/codecommit-codepipeline-codebuild-codedeploy-lambda-container/modules/codepipeline/variables.tf",
    "content": "variable \"codecommit_branch\" {\n    type = string\n}\nvariable \"codecommit_repo\" {\n    type = string\n}\nvariable \"general_namespace\" {\n    type = string\n}\nvariable \"env_namespace\" {\n    type = string\n}\nvariable \"s3_bucket_namespace\" {\n    type = string\n}\nvariable \"ecr_repo_arn\" {\n    type = string\n}\nvariable \"codebuild_image\" {\n    type = string\n    default = \"aws/codebuild/amazonlinux2-x86_64-standard:3.0\"\n}\nvariable \"codebuild_type\" {\n    type = string\n    default = \"LINUX_CONTAINER\"\n}\nvariable \"codebuild_compute_type\" {\n    type = string\n    default = \"BUILD_GENERAL1_MEDIUM\"\n}\nvariable \"build_args\" {\n    type        = any\n}"
  },
  {
    "path": "samples/codecommit-codepipeline-codebuild-codedeploy-lambda-container/modules/ecr/main.tf",
    "content": "\ndata \"aws_caller_identity\" \"current\" {}\nresource \"aws_ecr_repository\" \"ecr_repo\" {\n  name                 = \"${var.general_namespace}_docker_repo\"\n  #image_tag_mutability = \"IMMUTABLE\" #a capability that prevents image tags from being overwritten\n  image_scanning_configuration {\n    scan_on_push = true #https://docs.aws.amazon.com/AmazonECR/latest/userguide/image-scanning.html\n  }\n  tags = {\n    env = var.env_namespace\n  }\n}"
  },
  {
    "path": "samples/codecommit-codepipeline-codebuild-codedeploy-lambda-container/modules/ecr/outputs.tf",
    "content": "output \"ecr_configs\" {\n    value = {\n        ecr_repo_url = aws_ecr_repository.ecr_repo.repository_url\n        ecr_repo_arn = aws_ecr_repository.ecr_repo.arn\n    }\n}"
  },
  {
    "path": "samples/codecommit-codepipeline-codebuild-codedeploy-lambda-container/modules/ecr/variables.tf",
    "content": "variable \"general_namespace\" {\n    type = string\n}\nvariable \"env_namespace\" {\n    type = string\n}"
  },
  {
    "path": "samples/codecommit-codepipeline-codebuild-codedeploy-lambda-container/outputs.tf",
    "content": "output \"codepipeline\" {\n    value = module.codepipeline.codepipeline_configs.codepipeline\n}\noutput \"codecommit\" {\n    value = module.codecommit.codecommit_configs.clone_repository_url\n}\noutput \"ecrrepo\" {\n    value = module.ecr.ecr_configs.ecr_repo_url\n}"
  },
  {
    "path": "samples/codecommit-codepipeline-codebuild-codedeploy-lambda-container/providers.tf",
    "content": "provider \"aws\" {\n  region = \"eu-central-1\"\n}\n\nterraform {\n  required_version = \">= 0.15\"\n  required_providers {\n    aws = {\n      source  = \"hashicorp/aws\"\n      version = \"~> 4.15.1\"\n      # Will allow installation of 4.15.1 and 4.15.10 but not 4.16.0\n      # Get error when using 4.16.0\n    }\n  }\n}\n\n# terraform {\n#     backend \"s3\" {\n#       encrypt = true\n#       bucket = \"BUCKET_NAME\"\n#       key = \"states/code/terraform.tfstate\"\n#       region = \"eu-central-1\"\n#   }\n# }\n"
  },
  {
    "path": "samples/codecommit-codepipeline-codebuild-codedeploy-lambda-container/terraform.tfvars",
    "content": "org_name   = \"org\"\nteam_name  = \"awsteam\"\nproject_id = \"lambda\"\nregion     = \"eu-central-1\"\nenv = {\n  \"dev\" = \"dev\"\n  \"qa\"  = \"qa\"\n}\ncodebuild_compute_type = \"BUILD_GENERAL1_MEDIUM\"\ncodebuild_image        = \"aws/codebuild/amazonlinux2-x86_64-standard:3.0\"\ncodebuild_type         = \"LINUX_CONTAINER\"\ncodecommit_branch      = \"master\"\n"
  },
  {
    "path": "samples/codecommit-codepipeline-codebuild-codedeploy-lambda-container/variables.tf",
    "content": "#Values are retrived from terraform.tfvars file\nvariable \"org_name\" {\n  description = \"Your Organization name\"\n  type        = string\n}\nvariable \"team_name\" {\n  description = \"Your Team name\"\n  type        = string\n}\nvariable \"project_id\" {\n  description = \"Your Project ID\"\n  type        = string\n}\nvariable \"env\" {\n  description = \"Your deployment environment\"\n  type        = map(any)\n  default = {\n    \"dev\" = \"dev\"\n  }\n}\nvariable \"region\" {\n  description = \"Your AWS Region\"\n  type        = string\n}\nvariable \"codebuild_type\" {\n  description = \"Your CodeBuild Project Type\"\n  type        = string\n}\nvariable \"codebuild_image\" {\n  description = \"Your CodeBuild Project Image\"\n  type        = string\n}\nvariable \"codebuild_compute_type\" {\n  description = \"Your CodeBuild Project Compute Type\"\n  type        = string\n}\nvariable \"codecommit_branch\" {\n  description = \"Your CodeCommit Branch\"\n  type        = string\n}\nvariable \"terraform_ver\" {\n    description = \"Terraform Version number for passing it to codebuild\"\n    default     = \"1.2.2\"\n    type        = string\n}"
  },
  {
    "path": "samples/ec2-ebs-efs/ebs.tf",
    "content": "# Creating EBS for Ubuntu\r\n# details: https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ebs_volume\r\nresource \"aws_ebs_volume\" \"ebs_ubuntu\" {\r\n  availability_zone = \"eu-central-1c\"\r\n  size = 20   # The size of the drive in GiBs.\r\n  type= \"gp2\" # default gp2. others: standard, gp2, gp3, io1, io2, sc1 or st1\r\n}\r\n\r\n# EBS-Ubuntu attachment\r\nresource \"aws_volume_attachment\" \"ubuntu2004_ebs_ubuntu\" {\r\n  device_name = \"/dev/sdh\"\r\n  volume_id   = \"${aws_ebs_volume.ebs_ubuntu.id}\"\r\n  instance_id = \"${aws_instance.ubuntu2004.id}\"\r\n}\r\n\r\n# Creating EBS for Windows\r\n# details: https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ebs_volume\r\nresource \"aws_ebs_volume\" \"ebs_windows\" {\r\n  availability_zone = \"eu-central-1c\"\r\n  size = 15   # The size of the drive in GiBs.\r\n  type= \"gp2\" # default gp2. others: standard, gp2, gp3, io1, io2, sc1 or st1\r\n}\r\n\r\n# EBS-Windows attachment\r\nresource \"aws_volume_attachment\" \"win2019_ebs_windows\" {\r\n  device_name = \"/dev/sdg\"\r\n  volume_id   = \"${aws_ebs_volume.ebs_windows.id}\"\r\n  instance_id = \"${aws_instance.win2019.id}\"\r\n}"
  },
  {
    "path": "samples/ec2-ebs-efs/efs.tf",
    "content": "# Creating Amazon EFS File system\r\n# Amazon EFS supports two lifecycle policies. Transition into IA and Transition out of IA\r\nresource \"aws_efs_file_system\" \"efs\" {\r\n  lifecycle_policy {\r\n    transition_to_ia = \"AFTER_30_DAYS\"\r\n  }\r\n  tags = {\r\n    Name = \"efs-example\"\r\n  }\r\n}\r\n\r\n# Creating the EFS access point for AWS EFS File system\r\nresource \"aws_efs_access_point\" \"access_point\" {\r\n  file_system_id = aws_efs_file_system.efs.id\r\n}\r\n\r\n# Creating the AWS EFS System policy to transition files into and out of the file system.\r\n# The EFS System Policy allows clients to mount, read and perform, write operations on File system \r\n# The communication of client and EFS is set using aws:secureTransport Option\r\nresource \"aws_efs_file_system_policy\" \"policy\" {\r\n  file_system_id = aws_efs_file_system.efs.id\r\n  policy = <<POLICY\r\n{\r\n    \"Version\": \"2012-10-17\",\r\n    \"Id\": \"Policy01\",\r\n    \"Statement\": [\r\n        {\r\n            \"Sid\": \"Statement\",\r\n            \"Effect\": \"Allow\",\r\n            \"Principal\": {\r\n                \"AWS\": \"*\"\r\n            },\r\n            \"Resource\": \"${aws_efs_file_system.efs.arn}\",\r\n            \"Action\": [\r\n                \"elasticfilesystem:ClientMount\",\r\n                \"elasticfilesystem:ClientRootAccess\",\r\n                \"elasticfilesystem:ClientWrite\"\r\n            ],\r\n            \"Condition\": {\r\n                \"Bool\": {\r\n                    \"aws:SecureTransport\": \"false\"\r\n                }\r\n            }\r\n        }\r\n    ]\r\n}\r\nPOLICY\r\n}\r\n\r\n# Creating the AWS EFS Mount point in a specified Subnet \r\nresource \"aws_efs_mount_target\" \"mount\" {\r\n  file_system_id = aws_efs_file_system.efs.id\r\n  subnet_id      = aws_subnet.public.id\r\n  security_groups = [aws_security_group.sg_config.id]  # open ingress 2049 port for EFS\r\n}\r\n\r\nresource \"null_resource\" \"configure_nfs\" {\r\n  depends_on = [aws_efs_mount_target.mount]\r\n   \r\n  connection {\r\n    type     = \"ssh\"\r\n    user     = \"ubuntu\"\r\n    private_key = file(\"testkey.pem\")\r\n    host     = aws_instance.ubuntu2004.public_ip\r\n  }\r\n\r\n  provisioner \"remote-exec\" {\r\n    inline = [\r\n      \"sudo apt install nfs-common -y\",\r\n      \"mkdir ~/efs\",\r\n      \"cd ~/efs\",\r\n      \"df -kh\"\r\n    ]\r\n  }\r\n}"
  },
  {
    "path": "samples/ec2-ebs-efs/main.tf",
    "content": "terraform {\r\n  required_providers {\r\n    aws = {\r\n      source  = \"hashicorp/aws\"\r\n      version = \"~> 5.81.0\"\r\n    }\r\n  }\r\n  required_version = \">= 1.10.2\"\r\n}\r\n\r\nprovider \"aws\" {\r\n\tregion = \"eu-central-1\"\r\n}\r\n\r\nresource \"aws_vpc\" \"my_vpc\" {\r\n  cidr_block           = \"10.0.0.0/16\"\r\n  enable_dns_hostnames = true\r\n  tags = {\r\n    Name = \"My VPC\"\r\n  }\r\n}\r\n\r\nresource \"aws_subnet\" \"public\" {\r\n  vpc_id            = aws_vpc.my_vpc.id\r\n  cidr_block        = \"10.0.0.0/24\"\r\n  availability_zone = \"eu-central-1c\"\r\n  tags = {\r\n    Name = \"Public Subnet\"\r\n  }\r\n}\r\n\r\nresource \"aws_internet_gateway\" \"my_vpc_igw\" {\r\n  vpc_id = aws_vpc.my_vpc.id\r\n  tags = {\r\n    Name = \"My VPC - Internet Gateway\"\r\n  }\r\n}\r\n\r\nresource \"aws_route_table\" \"my_vpc_eu_central_1c_public\" {\r\n    vpc_id = aws_vpc.my_vpc.id\r\n    route {\r\n        cidr_block = \"0.0.0.0/0\"\r\n        gateway_id = aws_internet_gateway.my_vpc_igw.id\r\n    }\r\n    tags = {\r\n        Name = \"Public Subnet Route Table\"\r\n    }\r\n}\r\nresource \"aws_route_table_association\" \"my_vpc_eu_central_1c_public\" {\r\n    subnet_id      = aws_subnet.public.id\r\n    route_table_id = aws_route_table.my_vpc_eu_central_1c_public.id\r\n}\r\n\r\nresource \"aws_security_group\" \"sg_config\" {\r\n  name        = \"allow_ssh_sg\"\r\n  description = \"Allow SSH inbound connections\"\r\n  vpc_id      = aws_vpc.my_vpc.id\r\n  # for SSH\r\n  ingress {\r\n    from_port        = 22\r\n    to_port          = 22\r\n    protocol         = \"tcp\"\r\n    cidr_blocks      = [\"0.0.0.0/0\"]\r\n  }\r\n  # for HTTP Apache Server\r\n  ingress {\r\n    from_port        = 80\r\n    to_port          = 80\r\n    protocol         = \"tcp\"\r\n    cidr_blocks      = [\"0.0.0.0/0\"]\r\n  }\r\n  # for RDP\r\n  ingress {\r\n    from_port        = 3389\r\n    to_port          = 3389\r\n    protocol         = \"tcp\"\r\n    cidr_blocks      = [\"0.0.0.0/0\"]\r\n  }\r\n  # for ping\r\n  ingress {\r\n    from_port        = -1\r\n    to_port          = -1\r\n    protocol         = \"icmp\"\r\n    cidr_blocks      = [\"10.0.0.0/16\"]\r\n  }\r\n  # EFS mount target, important to connect with NFS file system, it must be added.\r\n  ingress {\r\n    from_port        = 2049\r\n    to_port          = 2049\r\n    protocol         = \"tcp\"\r\n    cidr_blocks      = [\"0.0.0.0/0\"]\r\n  }\r\n  egress {\r\n    from_port       = 0\r\n    to_port         = 0\r\n    protocol        = \"-1\"\r\n    cidr_blocks     = [\"0.0.0.0/0\"]\r\n  }\r\n  tags = {\r\n    Name = \"allow_ssh_sg\"\r\n  }\r\n}\r\n\r\nresource \"aws_instance\" \"ubuntu2004\" {\r\n  ami                         = \"ami-0e067cc8a2b58de59\" # Ubuntu 20.04 eu-central-1 Frankfurt\r\n  instance_type               = \"t2.nano\"\r\n  key_name                    = \"testkey\"\r\n  vpc_security_group_ids      = [aws_security_group.sg_config.id]\r\n  subnet_id                   = aws_subnet.public.id\r\n  associate_public_ip_address = true\r\n  tags = {\r\n    Name = \"Ubuntu 20.04\"\r\n  }\r\n}\r\n\r\nresource \"aws_instance\" \"win2019\" {\r\n  ami                         = \"ami-02c2da541ae36c6fc\" # Windows 2019 Server eu-central-1 Frankfurt\r\n  instance_type               = \"t2.micro\"\r\n  key_name                    = \"testkey\"\r\n  vpc_security_group_ids      = [aws_security_group.sg_config.id]\r\n  subnet_id                   = aws_subnet.public.id  \r\n  associate_public_ip_address = true\r\n  tags = {\r\n    Name = \"Win 2019 Server\"\r\n  }\r\n}\r\n\r\noutput \"instance_ubuntu2004_public_ip\" {\r\n  value = \"${aws_instance.ubuntu2004.public_ip}\"\r\n}\r\n\r\noutput \"instance_win2019_public_ip\" {\r\n  value = \"${aws_instance.win2019.public_ip}\"\r\n}\r\n\r\n"
  },
  {
    "path": "samples/ec2-vpc-ubuntu-win-ssh-rdp/main.tf",
    "content": "terraform {\r\n  required_providers {\r\n    aws = {\r\n      source  = \"hashicorp/aws\"\r\n      version = \"~> 4.16\"\r\n    }\r\n  }\r\n  required_version = \">= 1.2.0\"\r\n}\r\n\r\n# VPC on which region\r\nprovider \"aws\" {\r\n\tregion = \"eu-central-1\"\r\n}\r\n\r\n# Creates a new VPC with a CIDR block of 10.0.0.0/16, which allows up to 65,536 IP addresses. DNS hostnames are enabled to allow DNS resolution inside the VPC. \r\nresource \"aws_vpc\" \"my_vpc\" {\r\n  cidr_block           = \"10.0.0.0/16\"\r\n  enable_dns_hostnames = true\r\n  tags = {\r\n    Name = \"My VPC\"\r\n  }\r\n}\r\n\r\n# Creates a public subnet within the VPC with a CIDR block of 10.0.0.0/24, which allows up to 256 IP addresses.\r\nresource \"aws_subnet\" \"public\" {\r\n  vpc_id            = aws_vpc.my_vpc.id\r\n  cidr_block        = \"10.0.0.0/24\"\r\n  availability_zone = \"eu-central-1c\"\r\n  tags = {\r\n    Name = \"Public Subnet\"\r\n  }\r\n}\r\n\r\n# Creates an IG and attaches it to the VPC, allowing instances in the VPC to communicate with the internet.\r\nresource \"aws_internet_gateway\" \"my_vpc_igw\" {\r\n  vpc_id = aws_vpc.my_vpc.id\r\n  tags = {\r\n    Name = \"My VPC - Internet Gateway\"\r\n  }\r\n}\r\n\r\n# The route table for the VPC allows all outbound traffic (0.0.0.0/0) to be routed through the internet gateway.\r\nresource \"aws_route_table\" \"my_vpc_eu_central_1c_public\" {\r\n    vpc_id = aws_vpc.my_vpc.id\r\n    route {\r\n        cidr_block = \"0.0.0.0/0\"\r\n        gateway_id = aws_internet_gateway.my_vpc_igw.id\r\n    }\r\n    tags = {\r\n        Name = \"Public Subnet Route Table\"\r\n    }\r\n}\r\n\r\n# Associates the route table with the public subnet, so the subnet can use the route to access the internet.\r\nresource \"aws_route_table_association\" \"my_vpc_eu_central_1c_public\" {\r\n    subnet_id      = aws_subnet.public.id\r\n    route_table_id = aws_route_table.my_vpc_eu_central_1c_public.id\r\n}\r\n\r\n# This SG is for only test/demo purpose. Please not leave open 22, 3389 for security reason if you have IG, and specific IP isn't defined.\r\n# Port 22 (SSH) for managing Linux instances. Port 80 (HTTP) for web traffic (Apache server). Port 3389 (RDP) for managing Windows instances. ICMP (ping), allowing pings from within the VPC.\r\n# Outbound traffic (egress): All outbound traffic is allowed (0.0.0.0/0).\r\nresource \"aws_security_group\" \"allow_ssh\" {\r\n  name        = \"allow_ssh_sg\"\r\n  description = \"Allow SSH inbound connections\"\r\n  vpc_id      = aws_vpc.my_vpc.id\r\n  # for SSH\r\n  ingress {\r\n    from_port   = 22\r\n    to_port     = 22\r\n    protocol    = \"tcp\"\r\n    cidr_blocks = [\"0.0.0.0/0\"]\r\n  }\r\n  # for HTTP Apache Server\r\n  ingress {\r\n    from_port   = 80\r\n    to_port     = 80\r\n    protocol    = \"tcp\"\r\n    cidr_blocks = [\"0.0.0.0/0\"]\r\n  }\r\n  # for RDP\r\n  ingress {\r\n    from_port        = 3389\r\n    to_port          = 3389\r\n    protocol         = \"tcp\"\r\n    cidr_blocks      = [\"0.0.0.0/0\"]\r\n  }\r\n  # for ping\r\n  ingress {\r\n    from_port        = -1\r\n    to_port          = -1\r\n    protocol         = \"icmp\"\r\n    cidr_blocks      = [\"10.0.0.0/16\"]\r\n  }\r\n  egress {\r\n    from_port       = 0\r\n    to_port         = 0\r\n    protocol        = \"-1\"\r\n    cidr_blocks     = [\"0.0.0.0/0\"]\r\n  }\r\n  tags = {\r\n    Name = \"allow_ssh_sg\"\r\n  }\r\n}\r\n\r\n# Create Ubuntu instance. The AMI value varies from region to region and from OS to OS.\r\n# SSH Key pair: testkey\r\n# The user data script installs and starts an Apache web server and sets up a simple HTML page with the instance hostname.\r\nresource \"aws_instance\" \"ubuntu2004\" {\r\n  ami                         = \"ami-0e067cc8a2b58de59\" # Ubuntu 20.04 eu-central-1 Frankfurt\r\n  instance_type               = \"t2.nano\"\r\n  key_name                    = \"testkey\"\r\n  vpc_security_group_ids      = [aws_security_group.allow_ssh.id]\r\n  subnet_id                   = aws_subnet.public.id\r\n  associate_public_ip_address = true\r\n  user_data = <<-EOF\r\n\t\t           #! /bin/bash\r\n                           sudo apt-get update\r\n\t\t           sudo apt-get install -y apache2\r\n\t\t           sudo systemctl start apache2\r\n\t\t           sudo systemctl enable apache2\r\n\t\t           echo \"<h1>Deployed via Terraform from $(hostname -f)</h1>\" | sudo tee /var/www/html/index.html\r\n  EOF\r\n  tags = {\r\n    Name = \"Ubuntu 20.04\"\r\n  }\r\n}\r\n\r\nresource \"aws_instance\" \"win2019\" {\r\n\tami                         = \"ami-02c2da541ae36c6fc\" # Windows 2019 Server eu-central-1 Frankfurt\r\n\tinstance_type               = \"t2.micro\"\r\n        key_name                    = \"testkey\"\r\n        vpc_security_group_ids      = [aws_security_group.allow_ssh.id]\r\n        subnet_id                   = aws_subnet.public.id  \r\n\tassociate_public_ip_address = true\r\n        tags = {\r\n\t\tName = \"Win 2019 Server\"\r\n\t}\r\n}\r\n\r\n# Output the public IP addresses of the Ubuntu and Windows EC2 instances\r\noutput \"instance_ubuntu2004_public_ip\" {\r\n  value = \"${aws_instance.ubuntu2004.public_ip}\"\r\n}\r\n\r\noutput \"instance_win2019_public_ip\" {\r\n  value = \"${aws_instance.win2019.public_ip}\"\r\n}\r\n"
  },
  {
    "path": "samples/ecr-ecs-elb-vpc-ecsservice-container/1_vpc.tf",
    "content": "# Internet Access -> IGW ->  Route Table -> Subnets\r\nterraform {\r\n  required_providers {\r\n    aws = {\r\n      source  = \"hashicorp/aws\"\r\n      version = \"~> 4.16\"\r\n    }\r\n  }\r\n  required_version = \">= 1.2.0\"\r\n}\r\n\r\nprovider \"aws\" {\r\n\tregion = \"eu-central-1\"\r\n}\r\n\r\nresource \"aws_vpc\" \"my_vpc\" {\r\n  cidr_block           = \"10.0.0.0/16\"\r\n  enable_dns_hostnames = true\r\n  tags = {\r\n    Name = \"My VPC\"\r\n  }\r\n}\r\n\r\nresource \"aws_subnet\" \"public_subnet_a\" {\r\n  availability_zone = \"eu-central-1a\"\r\n  vpc_id            = aws_vpc.my_vpc.id\r\n  cidr_block        = \"10.0.0.0/24\"\r\n  tags = {\r\n    Name = \"Public Subnet A\"\r\n  }\r\n}\r\n\r\nresource \"aws_subnet\" \"public_subnet_b\" {\r\n  availability_zone = \"eu-central-1b\"\r\n  vpc_id            = aws_vpc.my_vpc.id\r\n  cidr_block        = \"10.0.1.0/24\"\r\n  tags = {\r\n    Name = \"Public Subnet B\"\r\n  }\r\n}\r\n\r\nresource \"aws_subnet\" \"public_subnet_c\" {\r\n  availability_zone = \"eu-central-1c\"\r\n  vpc_id            = aws_vpc.my_vpc.id\r\n  cidr_block        = \"10.0.2.0/24\"\r\n  tags = {\r\n    Name = \"Public Subnet C\"\r\n  }\r\n}\r\n\r\nresource \"aws_internet_gateway\" \"igw\" {\r\n  vpc_id = aws_vpc.my_vpc.id\r\n  tags = {\r\n    Name = \"My VPC - Internet Gateway\"\r\n  }\r\n}\r\n\r\nresource \"aws_route_table\" \"route_table\" {\r\n    vpc_id = aws_vpc.my_vpc.id\r\n    route {\r\n        cidr_block = \"0.0.0.0/0\"\r\n        gateway_id = aws_internet_gateway.igw.id\r\n    }\r\n    tags = {\r\n        Name = \"Public Subnet Route Table\"\r\n    }\r\n}\r\n\r\nresource \"aws_route_table_association\" \"route_table_association1\" {\r\n    subnet_id      = aws_subnet.public_subnet_a.id\r\n    route_table_id = aws_route_table.route_table.id\r\n}\r\n\r\nresource \"aws_route_table_association\" \"route_table_association2\" {\r\n    subnet_id      = aws_subnet.public_subnet_b.id\r\n    route_table_id = aws_route_table.route_table.id\r\n}\r\n\r\nresource \"aws_route_table_association\" \"route_table_association3\" {\r\n    subnet_id      = aws_subnet.public_subnet_c.id\r\n    route_table_id = aws_route_table.route_table.id\r\n}"
  },
  {
    "path": "samples/ecr-ecs-elb-vpc-ecsservice-container/2_ecs.tf",
    "content": "# Getting data existed ECR\r\ndata \"aws_ecr_repository\" \"flask_app\" {\r\n  name = \"flask-app\"\r\n}\r\n\r\n# Creating ECS Cluster\r\nresource \"aws_ecs_cluster\" \"my_cluster\" {\r\n  name = \"my-cluster\" # Naming the cluster\r\n}\r\n\r\n# Creating ECS Task\r\nresource \"aws_ecs_task_definition\" \"flask_app_task\" {\r\n  family                   = \"flask-app-task\" \r\n  container_definitions    = <<DEFINITION\r\n  [\r\n    {\r\n      \"name\": \"flask-app-task\",\r\n      \"image\": \"${data.aws_ecr_repository.flask_app.repository_url}\",\r\n      \"essential\": true,\r\n      \"portMappings\": [\r\n        {\r\n          \"containerPort\": 5000,\r\n          \"hostPort\": 5000\r\n        }\r\n      ],\r\n      \"memory\": 512,\r\n      \"cpu\": 256\r\n    }\r\n  ]\r\n  DEFINITION\r\n  requires_compatibilities = [\"FARGATE\"] # Stating that we are using ECS Fargate\r\n  network_mode             = \"awsvpc\"    # Using awsvpc as our network mode as this is required for Fargate\r\n  memory                   = 512         # Specifying the memory our container requires\r\n  cpu                      = 256         # Specifying the CPU our container requires\r\n  execution_role_arn       = \"${aws_iam_role.ecsTaskExecutionRole.arn}\"\r\n}\r\n\r\n# Creating Role for ECS\r\nresource \"aws_iam_role\" \"ecsTaskExecutionRole\" {\r\n  name               = \"ecsTaskExecutionRole\"\r\n  assume_role_policy = \"${data.aws_iam_policy_document.assume_role_policy.json}\"\r\n}\r\n\r\ndata \"aws_iam_policy_document\" \"assume_role_policy\" {\r\n  statement {\r\n    actions = [\"sts:AssumeRole\"]\r\n\r\n    principals {\r\n      type        = \"Service\"\r\n      identifiers = [\"ecs-tasks.amazonaws.com\"]\r\n    }\r\n  }\r\n}\r\n\r\n# Role - Policy Attachment for ECS\r\nresource \"aws_iam_role_policy_attachment\" \"ecsTaskExecutionRole_policy\" {\r\n  role       = \"${aws_iam_role.ecsTaskExecutionRole.name}\"\r\n  policy_arn = \"arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy\"\r\n}"
  },
  {
    "path": "samples/ecr-ecs-elb-vpc-ecsservice-container/3_elb.tf",
    "content": "# Internet Access -> IGW -> LB Security Groups -> Application Load Balancer  (Listener 80) -> Target Groups  -> ECS Service -> ECS SG -> Tasks on each subnets \r\n\r\n# Creating Load Balancer (LB)\r\nresource \"aws_alb\" \"application_load_balancer\" {\r\n  name               = \"test-lb-tf\" # Naming our load balancer\r\n  load_balancer_type = \"application\"\r\n  subnets = [ \r\n    \"${aws_subnet.public_subnet_a.id}\",\r\n    \"${aws_subnet.public_subnet_b.id}\",\r\n    \"${aws_subnet.public_subnet_c.id}\"\r\n  ]\r\n  # Referencing the security group\r\n  security_groups = [\"${aws_security_group.load_balancer_security_group.id}\"]\r\n}\r\n\r\n# Creating a security group for LB\r\nresource \"aws_security_group\" \"load_balancer_security_group\" {\r\n  vpc_id      = aws_vpc.my_vpc.id\r\n  ingress {\r\n    from_port   = 80\r\n    to_port     = 80\r\n    protocol    = \"tcp\"\r\n    cidr_blocks = [\"0.0.0.0/0\"] # Allowing traffic in from all sources\r\n  }\r\n\r\n  egress {\r\n    from_port   = 0\r\n    to_port     = 0\r\n    protocol    = \"-1\"\r\n    cidr_blocks = [\"0.0.0.0/0\"]\r\n  }\r\n}\r\n\r\n# Creating LB Target Group\r\nresource \"aws_lb_target_group\" \"target_group\" {\r\n  name        = \"target-group\"\r\n  port        = 80\r\n  protocol    = \"HTTP\"\r\n  target_type = \"ip\"\r\n  vpc_id      = \"${aws_vpc.my_vpc.id}\" \r\n}\r\n\r\n# Creating LB Listener\r\nresource \"aws_lb_listener\" \"listener\" {\r\n  load_balancer_arn = \"${aws_alb.application_load_balancer.arn}\" # Referencing our load balancer\r\n  port              = \"80\"\r\n  protocol          = \"HTTP\"\r\n  default_action {\r\n    type             = \"forward\"\r\n    target_group_arn = \"${aws_lb_target_group.target_group.arn}\" # Referencing our target group\r\n  }\r\n}"
  },
  {
    "path": "samples/ecr-ecs-elb-vpc-ecsservice-container/4_ecs_service.tf",
    "content": "# Creating ECS Service\r\nresource \"aws_ecs_service\" \"my_first_service\" {\r\n  name            = \"my-first-service\"                             # Naming our first service\r\n  cluster         = \"${aws_ecs_cluster.my_cluster.id}\"             # Referencing our created Cluster\r\n  task_definition = \"${aws_ecs_task_definition.flask_app_task.arn}\" # Referencing the task our service will spin up\r\n  launch_type     = \"FARGATE\"\r\n  desired_count   = 3 # Setting the number of containers to 3\r\n\r\n  load_balancer {\r\n    target_group_arn = \"${aws_lb_target_group.target_group.arn}\" # Referencing our target group\r\n    container_name   = \"${aws_ecs_task_definition.flask_app_task.family}\"\r\n    container_port   = 5000 # Specifying the container port\r\n  }\r\n\r\n  network_configuration {\r\n    subnets          = [\"${aws_subnet.public_subnet_a.id}\", \"${aws_subnet.public_subnet_b.id}\", \"${aws_subnet.public_subnet_c.id}\"]\r\n    assign_public_ip = true                                                # Providing our containers with public IPs\r\n    security_groups  = [\"${aws_security_group.service_security_group.id}\"] # Setting the security group\r\n  }\r\n}\r\n\r\n# Creating SG for ECS Container Service, referencing the load balancer security group\r\nresource \"aws_security_group\" \"service_security_group\" {\r\n  vpc_id      = aws_vpc.my_vpc.id\r\n  ingress {\r\n    from_port = 0\r\n    to_port   = 0\r\n    protocol  = \"-1\"\r\n    # Only allowing traffic in from the load balancer security group\r\n    security_groups = [\"${aws_security_group.load_balancer_security_group.id}\"]\r\n  }\r\n\r\n  egress {\r\n    from_port   = 0\r\n    to_port     = 0\r\n    protocol    = \"-1\"\r\n    cidr_blocks = [\"0.0.0.0/0\"]\r\n  }\r\n}\r\n\r\n#Log the load balancer app URL\r\noutput \"app_url\" {\r\n  value = aws_alb.application_load_balancer.dns_name\r\n}"
  },
  {
    "path": "samples/ecr-ecs-elb-vpc-ecsservice-container/ecr/0_ecr.tf",
    "content": "terraform {\r\n  required_providers {\r\n    aws = {\r\n      source  = \"hashicorp/aws\"\r\n      version = \"~> 4.16\"\r\n    }\r\n  }\r\n  required_version = \">= 1.2.0\"\r\n}\r\n\r\n# Creating Elastic Container Repository for application\r\nresource \"aws_ecr_repository\" \"flask_app\" {\r\n  name = \"flask-app\"\r\n}\r\n\r\n\r\n# aws ecr get-login-password --region REGION | docker login --username AWS --password-stdin ID.dkr.ecr.REGION.amazonaws.com \r\n# docker build -t flask-app .\r\n# docker tag flask-app:latest ID.dkr.REGION.amazonaws.com/flask-app:latest \r\n# docker push ID.dkr.REGION.amazonaws.com/flask-app:latest"
  },
  {
    "path": "samples/ecr-ecs-elb-vpc-ecsservice-container/flask-app/Dockerfile",
    "content": "FROM python:3.8-slim-buster\r\n\r\nWORKDIR /app\r\n\r\nCOPY requirements.txt requirements.txt\r\n\r\nRUN pip3 install -r requirements.txt\r\n\r\nCOPY app .\r\n\r\nENV FLASK_APP=app\r\n\r\nENV FLASK_ENV=development\r\n\r\nEXPOSE 5000\r\n\r\nRUN python init_db.py\r\n\r\nCMD [ \"python3\", \"-m\" , \"flask\", \"run\", \"--host=0.0.0.0\",\"--port\",\"5000\"]"
  },
  {
    "path": "samples/ecr-ecs-elb-vpc-ecsservice-container/flask-app/README.md",
    "content": "## Flask-App Docker Image\r\n\r\n- Dockerfile is created for this sample.\r\n- App code is open source and taken:\r\n  - https://www.digitalocean.com/community/tutorials/how-to-make-a-web-application-using-flask-in-python-3\r\n  - https://github.com/do-community/flask_blog\r\n\r\n- To build Linux Container and  run on local:\r\n\r\n```\r\ndocker build -t flask-app .\r\ndocker container run -p 5000:5000 -d flask-app\r\n```\r\n\r\n![image](https://user-images.githubusercontent.com/10358317/232225583-253f20dc-4d95-43b3-a4a7-d156f2d0c886.png)\r\n\r\n\r\n- If you are using WSL2 on Windows, use sensible browser on WSL2\r\n\r\n```\r\nsensible-browser http://localhost:5000/\r\n```\r\n\r\n![image](https://user-images.githubusercontent.com/10358317/232225726-d02927fe-9d64-4fba-b279-ff7c0ec7dbc1.png)\r\n\r\n\r\n- For app, Thank you Digital Ocean!\r\n"
  },
  {
    "path": "samples/ecr-ecs-elb-vpc-ecsservice-container/flask-app/app/app.py",
    "content": "import sqlite3\nfrom flask import Flask, render_template, request, url_for, flash, redirect\nfrom werkzeug.exceptions import abort\n\n\ndef get_db_connection():\n    conn = sqlite3.connect('database.db')\n    conn.row_factory = sqlite3.Row\n    return conn\n\n\ndef get_post(post_id):\n    conn = get_db_connection()\n    post = conn.execute('SELECT * FROM posts WHERE id = ?',\n                        (post_id,)).fetchone()\n    conn.close()\n    if post is None:\n        abort(404)\n    return post\n\n\napp = Flask(__name__)\napp.config['SECRET_KEY'] = '99'\n\n\n@app.route('/')\ndef index():\n    conn = get_db_connection()\n    posts = conn.execute('SELECT * FROM posts').fetchall()\n    conn.close()\n    return render_template('index.html', posts=posts)\n\n\n@app.route('/<int:post_id>')\ndef post(post_id):\n    post = get_post(post_id)\n    return render_template('post.html', post=post)\n\n\n@app.route('/create', methods=('GET', 'POST'))\ndef create():\n    if request.method == 'POST':\n        title = request.form['title']\n        content = request.form['content']\n\n        if not title:\n            flash('Title is required!')\n        else:\n            conn = get_db_connection()\n            conn.execute('INSERT INTO posts (title, content) VALUES (?, ?)',\n                         (title, content))\n            conn.commit()\n            conn.close()\n            return redirect(url_for('index'))\n\n    return render_template('create.html')\n\n\n@app.route('/<int:id>/edit', methods=('GET', 'POST'))\ndef edit(id):\n    post = get_post(id)\n\n    if request.method == 'POST':\n        title = request.form['title']\n        content = request.form['content']\n\n        if not title:\n            flash('Title is required!')\n        else:\n            conn = get_db_connection()\n            conn.execute('UPDATE posts SET title = ?, content = ?'\n                         ' WHERE id = ?',\n                         (title, content, id))\n            conn.commit()\n            conn.close()\n            return redirect(url_for('index'))\n\n    return render_template('edit.html', post=post)\n\n\n@app.route('/<int:id>/delete', methods=('POST',))\ndef delete(id):\n    post = get_post(id)\n    conn = get_db_connection()\n    conn.execute('DELETE FROM posts WHERE id = ?', (id,))\n    conn.commit()\n    conn.close()\n    flash('\"{}\" was successfully deleted!'.format(post['title']))\n    return redirect(url_for('index'))\n"
  },
  {
    "path": "samples/ecr-ecs-elb-vpc-ecsservice-container/flask-app/app/hello.py",
    "content": "from flask import Flask, request, escape\n\napp = Flask(__name__)\n\n\n@app.route('/')\ndef hello():\n    return 'Hello, World!'\n\n\n@app.route('/greet')\ndef greet():\n    name = request.args['name']\n    return '''\n    <!DOCTYPE html>\n    <html lang=\"en\">\n    <head>\n        <meta charset=\"UTF-8\">\n        <title></title>\n    </head>\n    <body>\n        <h1>Hi {}</h1>\n    </body>\n    </html>'''.format(escape(name))\n"
  },
  {
    "path": "samples/ecr-ecs-elb-vpc-ecsservice-container/flask-app/app/init_db.py",
    "content": "import sqlite3\n\nconnection = sqlite3.connect('database.db')\n\n\nwith open('schema.sql') as f:\n    connection.executescript(f.read())\n\ncur = connection.cursor()\n\ncur.execute(\"INSERT INTO posts (title, content) VALUES (?, ?)\",\n            ('First Post', 'Content for the first post')\n            )\n\ncur.execute(\"INSERT INTO posts (title, content) VALUES (?, ?)\",\n            ('Second Post', 'Content for the second post')\n            )\n\nconnection.commit()\nconnection.close()\n"
  },
  {
    "path": "samples/ecr-ecs-elb-vpc-ecsservice-container/flask-app/app/schema.sql",
    "content": "DROP TABLE IF EXISTS posts;\n\nCREATE TABLE posts (\n    id INTEGER PRIMARY KEY AUTOINCREMENT,\n    created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n    title TEXT NOT NULL,\n    content TEXT NOT NULL\n);\n"
  },
  {
    "path": "samples/ecr-ecs-elb-vpc-ecsservice-container/flask-app/app/static/css/style.css",
    "content": "h1 {\n    border: 2px #eee solid;\n    color: brown;\n    text-align: center;\n    padding: 10px;\n}\n\n"
  },
  {
    "path": "samples/ecr-ecs-elb-vpc-ecsservice-container/flask-app/app/templates/base.html",
    "content": "<!doctype html>\n<html lang=\"en\">\n  <head>\n    <!-- Required meta tags -->\n    <meta charset=\"utf-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, shrink-to-fit=no\">\n\n    <!-- Bootstrap CSS -->\n    <link rel=\"stylesheet\" href=\"https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css\" integrity=\"sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T\" crossorigin=\"anonymous\">\n\n    <title>{% block title %} {% endblock %}</title>\n  </head>\n  <body>\n      <nav class=\"navbar navbar-expand-md navbar-light bg-light\">\n        <a class=\"navbar-brand\" href=\"{{ url_for('index')}}\">FlaskBlog</a>\n        <button class=\"navbar-toggler\" type=\"button\" data-toggle=\"collapse\" data-target=\"#navbarNav\" aria-controls=\"navbarNav\" aria-expanded=\"false\" aria-label=\"Toggle navigation\">\n            <span class=\"navbar-toggler-icon\"></span>\n        </button>\n        <div class=\"collapse navbar-collapse\" id=\"navbarNav\">\n            <ul class=\"navbar-nav\">\n            <li class=\"nav-item\">\n                <a class=\"nav-link\" href=\"#\">About</a>\n            </li>\n            <li class=\"nav-item\">\n                <a class=\"nav-link\" href=\"{{url_for('create')}}\">New Post</a>\n            </li>\n            </ul>\n        </div>\n      </nav>\n    <div class=\"container\">\n        {% for message in get_flashed_messages() %}\n            <div class=\"alert alert-danger\">{{ message }}</div>\n        {% endfor %}\n        {% block content %} {% endblock %}\n    </div>\n\n    <!-- Optional JavaScript -->\n    <!-- jQuery first, then Popper.js, then Bootstrap JS -->\n    <script src=\"https://code.jquery.com/jquery-3.3.1.slim.min.js\" integrity=\"sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo\" crossorigin=\"anonymous\"></script>\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js\" integrity=\"sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1\" crossorigin=\"anonymous\"></script>\n    <script src=\"https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js\" integrity=\"sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM\" crossorigin=\"anonymous\"></script>\n  </body>\n</html>\n\n"
  },
  {
    "path": "samples/ecr-ecs-elb-vpc-ecsservice-container/flask-app/app/templates/create.html",
    "content": "{% extends 'base.html' %}\n\n{% block content %}\n<h1>{% block title %} Create a New Post {% endblock %}</h1>\n\n<form method=\"post\">\n    <div class=\"form-group\">\n        <label for=\"title\">Title</label>\n        <input type=\"text\" name=\"title\"\n               placeholder=\"Post title\" class=\"form-control\"\n               value=\"{{ request.form['title'] }}\"></input>\n    </div>\n\n    <div class=\"form-group\">\n        <label for=\"content\">Content</label>\n        <textarea name=\"content\" placeholder=\"Post content\"\n                  class=\"form-control\">{{ request.form['content'] }}</textarea>\n    </div>\n    <div class=\"form-group\">\n        <button type=\"submit\" class=\"btn btn-primary\">Submit</button>\n    </div>\n</form>\n{% endblock %}\n"
  },
  {
    "path": "samples/ecr-ecs-elb-vpc-ecsservice-container/flask-app/app/templates/edit.html",
    "content": "{% extends 'base.html' %}\n\n{% block content %}\n<h1>{% block title %} Edit \"{{ post['title'] }}\" {% endblock %}</h1>\n\n<form method=\"post\">\n    <div class=\"form-group\">\n        <label for=\"title\">Title</label>\n        <input type=\"text\" name=\"title\" placeholder=\"Post title\"\n               class=\"form-control\"\n               value=\"{{ request.form['title'] or post['title'] }}\">\n        </input>\n    </div>\n\n    <div class=\"form-group\">\n        <label for=\"content\">Content</label>\n        <textarea name=\"content\" placeholder=\"Post content\"\n                  class=\"form-control\">{{ request.form['content'] or post['content'] }}</textarea>\n    </div>\n    <div class=\"form-group\">\n        <button type=\"submit\" class=\"btn btn-primary\">Submit</button>\n    </div>\n</form>\n<hr>\n<form action=\"{{ url_for('delete', id=post['id']) }}\" method=\"POST\">\n    <input type=\"submit\" value=\"Delete Post\"\n            class=\"btn btn-danger btn-sm\"\n            onclick=\"return confirm('Are you sure you want to delete this post?')\">\n</form>\n{% endblock %}\n\n"
  },
  {
    "path": "samples/ecr-ecs-elb-vpc-ecsservice-container/flask-app/app/templates/index.html",
    "content": "{% extends 'base.html' %}\n\n{% block content %}\n    <h1>{% block title %} Welcome to FlaskBlog {% endblock %}</h1>\n    {% for post in posts %}\n        <a href=\"{{ url_for('post', post_id=post['id']) }}\">\n            <h2>{{ post['title'] }}</h2>\n        </a>\n        <span class=\"badge badge-primary\">{{ post['created'] }}</span>\n        <a href=\"{{ url_for('edit', id=post['id']) }}\">\n            <span class=\"badge badge-warning\">Edit</span>\n        </a>\n        <hr>\n    {% endfor %}\n{% endblock %}\n"
  },
  {
    "path": "samples/ecr-ecs-elb-vpc-ecsservice-container/flask-app/app/templates/post.html",
    "content": "{% extends 'base.html' %}\n\n{% block content %}\n    <h2>{% block title %} {{ post['title'] }} {% endblock %}</h2>\n    <span class=\"badge badge-primary\">{{ post['created'] }}</span>\n    <p>{{ post['content'] }}</p>\n{% endblock %}\n"
  },
  {
    "path": "samples/ecr-ecs-elb-vpc-ecsservice-container/flask-app/requirements.txt",
    "content": "flask\r\ndb-sqlite3\r\nWerkzeug"
  },
  {
    "path": "samples/eks-managed-node-blueprint/README.md",
    "content": "## Modules\n\n- Terraform EKS Module:\n  - https://registry.terraform.io/modules/terraform-aws-modules/eks/aws/latest\n  - https://github.com/terraform-aws-modules/terraform-aws-eks\n- Kubernetes Addons:\n  - https://github.com/aws-ia/terraform-aws-eks-blueprints/modules/kubernetes-addons\n- Terraform VPC Module:\n  - https://registry.terraform.io/modules/terraform-aws-modules/vpc/aws/latest\n  - https://github.com/terraform-aws-modules/terraform-aws-vpc  \n  \n"
  },
  {
    "path": "samples/eks-managed-node-blueprint/main.tf",
    "content": "terraform {\r\n  required_providers {\r\n   aws = {\r\n      source  = \"hashicorp/aws\"\r\n      version = \">= 4.47\"\r\n    }\r\n    kubernetes = {\r\n      source  = \"hashicorp/kubernetes\"\r\n      version = \">= 2.10\"\r\n    }\r\n    helm = {\r\n      source  = \"hashicorp/helm\"\r\n      version = \">= 2.4.1\"\r\n    }\r\n  }\r\n  required_version = \">= 1.2.0\"\r\n}\r\n\r\nprovider \"aws\" {\r\n  region = local.region\r\n}\r\n\r\nprovider \"kubernetes\" {\r\n  host                   = module.eks.cluster_endpoint\r\n  cluster_ca_certificate = base64decode(module.eks.cluster_certificate_authority_data)\r\n  token                  = data.aws_eks_cluster_auth.this.token\r\n}\r\n\r\nprovider \"helm\" {\r\n  kubernetes {\r\n    host                   = module.eks.cluster_endpoint\r\n    cluster_ca_certificate = base64decode(module.eks.cluster_certificate_authority_data)\r\n    token                  = data.aws_eks_cluster_auth.this.token\r\n  }\r\n}\r\n\r\ndata \"aws_eks_cluster_auth\" \"this\" {\r\n  name = module.eks.cluster_name\r\n}\r\n\r\ndata \"aws_availability_zones\" \"available\" {}\r\n\r\nlocals {\r\n  name   = basename(path.cwd)\r\n  region = \"eu-central-1\"\r\n\r\n  cluster_version = \"1.24\"\r\n\r\n  vpc_cidr = \"10.0.0.0/16\"\r\n  azs      = slice(data.aws_availability_zones.available.names, 0, 3)\r\n\r\n  tags = {\r\n    Blueprint  = local.name\r\n    GithubRepo = \"github.com/aws-ia/terraform-aws-eks-blueprints\"\r\n  }\r\n}\r\n\r\n################################################################################\r\n# Cluster\r\n################################################################################\r\n\r\n#tfsec:ignore:aws-eks-enable-control-plane-logging\r\nmodule \"eks\" {\r\n  source  = \"terraform-aws-modules/eks/aws\"\r\n  version = \"~> 19.12\"\r\n\r\n  cluster_name                   = local.name\r\n  cluster_version                = local.cluster_version\r\n  cluster_endpoint_public_access = true\r\n\r\n  # EKS Addons\r\n  cluster_addons = {\r\n    coredns    = {}\r\n    kube-proxy = {}\r\n    vpc-cni    = {}\r\n  }\r\n\r\n  vpc_id     = module.vpc.vpc_id\r\n  subnet_ids = module.vpc.private_subnets\r\n\r\n  eks_managed_node_groups = {\r\n    initial = {\r\n      instance_types = [\"m5.large\"]\r\n\r\n      min_size     = 1\r\n      max_size     = 3\r\n      desired_size = 2\r\n    }\r\n  }\r\n\r\n  tags = local.tags\r\n}\r\n\r\n################################################################################\r\n# Kubernetes Addons\r\n################################################################################\r\n\r\nmodule \"eks_blueprints_kubernetes_addons\" {\r\n  source = \"github.com/aws-ia/terraform-aws-eks-blueprints/modules/kubernetes-addons\"\r\n  \r\n  eks_cluster_id       = module.eks.cluster_name\r\n  eks_cluster_endpoint = module.eks.cluster_endpoint\r\n  eks_oidc_provider    = module.eks.oidc_provider\r\n  eks_cluster_version  = module.eks.cluster_version\r\n\r\n  # Add-ons\r\n  enable_metrics_server     = true\r\n  enable_cluster_autoscaler = true\r\n  eks_worker_security_group_id = module.eks.cluster_security_group_id\r\n\r\n  tags = local.tags\r\n}\r\n\r\n################################################################################\r\n# Supporting Resources\r\n################################################################################\r\n\r\nmodule \"vpc\" {\r\n  source  = \"terraform-aws-modules/vpc/aws\"\r\n  version = \"~> 4.0\"\r\n\r\n  name = local.name\r\n  cidr = local.vpc_cidr\r\n\r\n  azs             = local.azs\r\n  private_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 4, k)]\r\n  public_subnets  = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 48)]\r\n\r\n  enable_nat_gateway = true\r\n  single_nat_gateway = true\r\n\r\n  public_subnet_tags = {\r\n    \"kubernetes.io/role/elb\" = 1\r\n  }\r\n\r\n  private_subnet_tags = {\r\n    \"kubernetes.io/role/internal-elb\" = 1\r\n  }\r\n\r\n  tags = local.tags\r\n}\r\n\r\noutput \"configure_kubectl\" {\r\n  description = \"Configure kubectl: make sure you're logged in with the correct AWS profile and run the following command to update your kubeconfig\"\r\n  value       = \"aws eks --region ${local.region} update-kubeconfig --name ${module.eks.cluster_name}\"\r\n}"
  },
  {
    "path": "samples/gitlabserver-on-premise-runner-on-EC2/docker-compose.yml",
    "content": "# Gitlab Server on WSL2 (Linux)\r\nversion: '3.6'\r\nservices:\r\n  web:\r\n    image: 'gitlab/gitlab-ee:latest'\r\n    restart: always\r\n    hostname: 'gitlab.example.com'\r\n    environment:\r\n      GITLAB_OMNIBUS_CONFIG: |\r\n        external_url 'http://gitlab.example.com'\r\n        #external_url 'https://gitlab.example.com'\r\n    ports:\r\n      - '150:80'\r\n      - '443:443'\r\n      - '22:22'\r\n    volumes:\r\n      - '/home/omer/gitlab-tmp/config:/etc/gitlab'\r\n      - '/home/omer/gitlab-tmp/logs:/var/log/gitlab'\r\n      - '/home/omer/gitlab-tmp/data:/var/opt/gitlab'\r\n    shm_size: '256m'"
  },
  {
    "path": "samples/gitlabserver-on-premise-runner-on-EC2/main.tf",
    "content": "terraform {\r\n  required_providers {\r\n    aws = {\r\n      source  = \"hashicorp/aws\"\r\n      version = \"~> 4.16\"\r\n    }\r\n  }\r\n  required_version = \">= 1.2.0\"\r\n}\r\n\r\nprovider \"aws\" {\r\n\tregion = \"eu-central-1\"\r\n}\r\n\r\nresource \"aws_vpc\" \"my_vpc\" {\r\n  cidr_block           = \"10.0.0.0/16\"\r\n  enable_dns_hostnames = true\r\n  tags = {\r\n    Name = \"My VPC\"\r\n  }\r\n}\r\n\r\nresource \"aws_subnet\" \"public\" {\r\n  vpc_id            = aws_vpc.my_vpc.id\r\n  cidr_block        = \"10.0.0.0/24\"\r\n  availability_zone = \"eu-central-1c\"\r\n  tags = {\r\n    Name = \"Public Subnet\"\r\n  }\r\n}\r\n\r\nresource \"aws_internet_gateway\" \"my_vpc_igw\" {\r\n  vpc_id = aws_vpc.my_vpc.id\r\n  tags = {\r\n    Name = \"My VPC - Internet Gateway\"\r\n  }\r\n}\r\n\r\nresource \"aws_route_table\" \"my_vpc_eu_central_1c_public\" {\r\n    vpc_id = aws_vpc.my_vpc.id\r\n    route {\r\n        cidr_block = \"0.0.0.0/0\"\r\n        gateway_id = aws_internet_gateway.my_vpc_igw.id\r\n    }\r\n    tags = {\r\n        Name = \"Public Subnet Route Table\"\r\n    }\r\n}\r\nresource \"aws_route_table_association\" \"my_vpc_eu_central_1c_public\" {\r\n    subnet_id      = aws_subnet.public.id\r\n    route_table_id = aws_route_table.my_vpc_eu_central_1c_public.id\r\n}\r\n\r\nresource \"aws_security_group\" \"allow_ssh\" {\r\n  name        = \"allow_ssh_sg\"\r\n  description = \"Allow SSH inbound connections\"\r\n  vpc_id      = aws_vpc.my_vpc.id\r\n  # for SSH\r\n  ingress {\r\n    from_port   = 22\r\n    to_port     = 22\r\n    protocol    = \"tcp\"\r\n    cidr_blocks = [\"0.0.0.0/0\"]\r\n  }\r\n  # for HTTP \r\n  ingress {\r\n    from_port   = 80\r\n    to_port     = 80\r\n    protocol    = \"tcp\"\r\n    cidr_blocks = [\"0.0.0.0/0\"]\r\n  }\r\n  # for HTTP \r\n  ingress {\r\n    from_port   = 150\r\n    to_port     = 150\r\n    protocol    = \"tcp\"\r\n    cidr_blocks = [\"0.0.0.0/0\"]\r\n  }\r\n  # for HTTPS \r\n  ingress {\r\n    from_port   = 443\r\n    to_port     = 443\r\n    protocol    = \"tcp\"\r\n    cidr_blocks = [\"0.0.0.0/0\"]\r\n  }\r\n  # for RDP\r\n  ingress {\r\n    from_port        = 3389\r\n    to_port          = 3389\r\n    protocol         = \"tcp\"\r\n    cidr_blocks      = [\"0.0.0.0/0\"]\r\n  }\r\n  # for ping\r\n  ingress {\r\n    from_port        = -1\r\n    to_port          = -1\r\n    protocol         = \"icmp\"\r\n    cidr_blocks      = [\"10.0.0.0/16\"]\r\n  }\r\n  egress {\r\n    from_port       = 0\r\n    to_port         = 0\r\n    protocol        = \"-1\"\r\n    cidr_blocks     = [\"0.0.0.0/0\"]\r\n  }\r\n  tags = {\r\n    Name = \"allow_ssh_sg\"\r\n  }\r\n}\r\n\r\nresource \"aws_instance\" \"ubuntu2004\" {\r\n  ami                         = \"ami-0e067cc8a2b58de59\" # Ubuntu 20.04 eu-central-1 Frankfurt\r\n  instance_type               = \"t2.micro\"\r\n  key_name                    = \"testkey\"\r\n  vpc_security_group_ids      = [aws_security_group.allow_ssh.id]\r\n  subnet_id                   = aws_subnet.public.id\r\n  associate_public_ip_address = true\r\n  user_data = <<-EOF\r\n\t\t       #! /bin/bash\r\n               sudo apt-get update\r\n               sudo apt-get install ca-certificates curl gnupg -y\r\n               sudo install -m 0755 -d /etc/apt/keyrings\r\n               curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg\r\n               sudo chmod a+r /etc/apt/keyrings/docker.gpg\r\n               echo \\\r\n                 \"deb [arch=\"$(dpkg --print-architecture)\" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \\\r\n                 \"$(. /etc/os-release && echo \"$VERSION_CODENAME\")\" stable\" | \\\r\n                 sudo tee /etc/apt/sources.list.d/docker.list > /dev/null\r\n               sudo apt-get update\r\n               sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y\r\n               sudo docker run hello-world\r\n               curl -L \"https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh\" | sudo bash\r\n               sudo apt-get install gitlab-runner\r\n  EOF\r\n  tags = {\r\n    Name = \"Ubuntu 20.04\"\r\n  }\r\n}\r\n\r\n\r\noutput \"instance_ubuntu2004_public_ip\" {\r\n  value = \"${aws_instance.ubuntu2004.public_ip}\"\r\n}\r\n\r\n"
  },
  {
    "path": "samples/gitlabserver-on-premise-runner-on-EC2/test-gitlab-runner/docker-windows/Dockerfile",
    "content": "# escape=`\r\n\r\nFROM mcr.microsoft.com/windows/servercore:1809\r\n\r\n# Restore the default Windows shell for correct batch processing.\r\nSHELL [\"cmd\", \"/S\", \"/C\"]\r\n\r\n# install choco (win package manager like apt-get)\r\nRUN @\"%SystemRoot%\\System32\\WindowsPowerShell\\v1.0\\powershell.exe\" -NoProfile -InputFormat None -ExecutionPolicy Bypass -Command \"iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))\" && SET \"PATH=%PATH%;%ALLUSERSPROFILE%\\chocolatey\\bin\"\r\n\r\n# install python3.7\r\nRUN choco install -y python --version=3.7.2 `\r\n    && set PATH=%PATH%;C:\\Python37\\\r\n\r\nRUN choco install pwsh --version=7.3.3  -y\r\n\r\nCMD [\"powershell.exe\", \"-NoLogo\", \"-ExecutionPolicy\", \"Bypass\"]"
  },
  {
    "path": "samples/gitlabserver-on-premise-runner-on-EC2/test-gitlab-runner/gitlab-ci.yml",
    "content": ".image-linux: &image-linux\r\n  image: 'python:3.7'\r\n\r\n.image-windows: &image-windows\r\n  image: 'omerbsezer/python:3.7-windowsservercore-1809'\r\n\r\nstages:\r\n  - build_debug\r\n  - run_test\r\n\r\nworkflow:\r\n  rules:\r\n    - if: $CI_COMMIT_BRANCH == \"main\"\r\n\r\n.build_linux: &build_linux\r\n  <<: *image-linux\r\n  script:\r\n    - python --version\r\n    - pip install -r requirements.txt\r\n    - pwd\r\n    - pylint --version\r\n    - pylint -d C0301 src/*.py\r\n  tags:\r\n    - ec2-shared\r\n\r\n.build_windows: &build_windows\r\n  <<: *image-windows\r\n  script:\r\n    - whoami\r\n    - python --version\r\n    - pip install -r requirements.txt\r\n    - pwd\r\n    - pylint --version\r\n    - cd src/; pylint -d C0301 main.py\r\n  tags:\r\n    - ec2-shared-windows\r\n\r\nbuild_linux_debug:\r\n  <<: *build_linux\r\n  stage: build_debug\r\n\r\nbuild_windows_debug:\r\n  extends: .build_windows\r\n  stage: build_debug\r\n\r\nrun_linux_test:\r\n  <<: *image-linux\r\n  stage: run_test\r\n  needs:\r\n    - build_linux_debug\r\n  script:\r\n    - python --version\r\n    - pip install -r requirements.txt\r\n    - cd test/;pytest -v\r\n  coverage: '/lines: \\d+\\.\\d+/'\r\n  tags:\r\n    - ec2-shared\r\n\r\nrun_windows_test:\r\n  <<: *image-windows\r\n  stage: run_test\r\n  needs:\r\n    - build_windows_debug\r\n  script:\r\n    - python --version\r\n    - pip install -r requirements.txt\r\n    - cd test/;pytest -v\r\n  tags:\r\n    - ec2-shared-windows\r\n\r\n      \r\n\r\n\r\n"
  },
  {
    "path": "samples/gitlabserver-on-premise-runner-on-EC2/test-gitlab-runner/requirements.txt",
    "content": "pylint==2.4.4\r\npytest==5.3.5"
  },
  {
    "path": "samples/gitlabserver-on-premise-runner-on-EC2/test-gitlab-runner/src/__init__.py",
    "content": ""
  },
  {
    "path": "samples/gitlabserver-on-premise-runner-on-EC2/test-gitlab-runner/src/main.py",
    "content": "'''\r\nThis file is example\r\n'''\r\n\r\ndef func(number: int) -> int:\r\n    '''\r\n    This function increases\r\n    '''\r\n    return number + 1\r\n\r\nif __name__ == '__main__':\r\n    print('Running Python File...')\r\n    A = 3\r\n    print(f'{A} + 1 =', func(A))\r\n"
  },
  {
    "path": "samples/gitlabserver-on-premise-runner-on-EC2/test-gitlab-runner/test/__init__.py",
    "content": ""
  },
  {
    "path": "samples/gitlabserver-on-premise-runner-on-EC2/test-gitlab-runner/test/test_main.py",
    "content": "import pytest \r\nfrom src.main import func\r\n\r\ndef test_answer():\r\n    assert func(3) == 4\r\n"
  },
  {
    "path": "samples/lambda-container-apigateway-flaskapp/1_lambda.tf",
    "content": "terraform {\r\n  required_providers {\r\n    aws = {\r\n      source  = \"hashicorp/aws\"\r\n      version = \"~> 4.16\"\r\n    }\r\n  }\r\n  required_version = \">= 1.2.0\"\r\n}\r\n\r\n# Create IAM Role for lambda\r\nresource \"aws_iam_role\" \"lambda_role\" {\r\n name   = \"aws_lambda_role\"\r\n assume_role_policy = <<EOF\r\n{\r\n  \"Version\": \"2012-10-17\",\r\n  \"Statement\": [\r\n    {\r\n      \"Action\": \"sts:AssumeRole\",\r\n      \"Principal\": {\r\n        \"Service\": \"lambda.amazonaws.com\"\r\n      },\r\n      \"Effect\": \"Allow\",\r\n      \"Sid\": \"\"\r\n    }\r\n  ]\r\n}\r\nEOF\r\n}\r\n\r\n# IAM policy for the lambda\r\nresource \"aws_iam_policy\" \"iam_policy_for_lambda\" {\r\n\r\n  name         = \"aws_iam_policy_for_aws_lambda_role\"\r\n  path         = \"/\"\r\n  description  = \"AWS IAM Policy for managing aws lambda role\"\r\n  policy = <<EOF\r\n{\r\n  \"Version\": \"2012-10-17\",\r\n  \"Statement\": [\r\n    {\r\n      \"Action\": [\r\n        \"logs:CreateLogGroup\",\r\n        \"logs:CreateLogStream\",\r\n        \"logs:PutLogEvents\"\r\n      ],\r\n      \"Resource\": \"arn:aws:logs:*:*:*\",\r\n      \"Effect\": \"Allow\"\r\n    }\r\n  ]\r\n}\r\nEOF\r\n}\r\n\r\n# Role - Policy Attachment\r\nresource \"aws_iam_role_policy_attachment\" \"attach_iam_policy_to_iam_role\" {\r\n  role        = aws_iam_role.lambda_role.name\r\n  policy_arn  = aws_iam_policy.iam_policy_for_lambda.arn\r\n}\r\n\r\n# Getting data existed ECR\r\ndata \"aws_ecr_repository\" \"flask_app_serverless\" {\r\n  name = \"flask-app-serverless\"\r\n}\r\n\r\n# Lambda Function, in terraform ${path.module} is the current directory.\r\nresource \"aws_lambda_function\" \"lambda_function\" {\r\n function_name                  = \"Lambda-Function\"\r\n role                           = aws_iam_role.lambda_role.arn\r\n # tag is required, \"source image ... is not valid\" error will pop up\r\n image_uri    = \"${data.aws_ecr_repository.flask_app_serverless.repository_url}:latest\"\r\n package_type = \"Image\"\r\n depends_on   = [aws_iam_role_policy_attachment.attach_iam_policy_to_iam_role]\r\n}\r\n\r\n# With Lambda permission, API Gateway can invoke Lambda \r\nresource \"aws_lambda_permission\" \"apigw\" {\r\n statement_id  = \"AllowAPIGatewayInvoke\"\r\n action        = \"lambda:InvokeFunction\"\r\n function_name = aws_lambda_function.lambda_function.function_name\r\n principal     = \"apigateway.amazonaws.com\"\r\n # The \"/*/*\" portion grants access from any method on any resource within the API Gateway REST API.\r\n source_arn = \"${aws_api_gateway_rest_api.example.execution_arn}/*/*\"\r\n}\r\n\r\n"
  },
  {
    "path": "samples/lambda-container-apigateway-flaskapp/2_api_gateway.tf",
    "content": "# Create API Gateway with Rest API type\r\nresource \"aws_api_gateway_rest_api\" \"example\" {\r\n  name        = \"Serverless\"\r\n  description = \"Serverless Application using Terraform\"\r\n}\r\n\r\nresource \"aws_api_gateway_resource\" \"proxy\" {\r\n   rest_api_id = aws_api_gateway_rest_api.example.id\r\n   parent_id   = aws_api_gateway_rest_api.example.root_resource_id\r\n   path_part   = \"{proxy+}\"     # with proxy, this resource will match any request path\r\n}\r\n\r\nresource \"aws_api_gateway_method\" \"proxy\" {\r\n   rest_api_id   = aws_api_gateway_rest_api.example.id\r\n   resource_id   = aws_api_gateway_resource.proxy.id\r\n   http_method   = \"ANY\"       # with ANY, it allows any request method to be used, all incoming requests will match this resource\r\n   authorization = \"NONE\"\r\n}\r\n\r\n# API Gateway - Lambda Connection\r\nresource \"aws_api_gateway_integration\" \"lambda\" {\r\n   rest_api_id = aws_api_gateway_rest_api.example.id\r\n   resource_id = aws_api_gateway_method.proxy.resource_id\r\n   http_method = aws_api_gateway_method.proxy.http_method\r\n   integration_http_method = \"POST\"\r\n   type                    = \"AWS_PROXY\"  # With AWS_PROXY, it causes API gateway to call into the API of another AWS service\r\n   uri                     = aws_lambda_function.lambda_function.invoke_arn\r\n}\r\n\r\n# The proxy resource cannot match an empty path at the root of the API. \r\n# To handle that, a similar configuration must be applied to the root resource that is built in to the REST API object\r\nresource \"aws_api_gateway_method\" \"proxy_root\" {\r\n   rest_api_id   = aws_api_gateway_rest_api.example.id\r\n   resource_id   = aws_api_gateway_rest_api.example.root_resource_id\r\n   http_method   = \"ANY\"\r\n   authorization = \"NONE\"\r\n}\r\n\r\nresource \"aws_api_gateway_integration\" \"lambda_root\" {\r\n   rest_api_id = aws_api_gateway_rest_api.example.id\r\n   resource_id = aws_api_gateway_method.proxy_root.resource_id\r\n   http_method = aws_api_gateway_method.proxy_root.http_method\r\n   integration_http_method = \"POST\"\r\n   type                    = \"AWS_PROXY\"  # With AWS_PROXY, it causes API gateway to call into the API of another AWS service\r\n   uri                     = aws_lambda_function.lambda_function.invoke_arn\r\n}\r\n\r\n# Deploy API Gateway\r\nresource \"aws_api_gateway_deployment\" \"example\" {\r\n   depends_on = [\r\n     aws_api_gateway_integration.lambda,\r\n     aws_api_gateway_integration.lambda_root,\r\n   ]\r\n   rest_api_id = aws_api_gateway_rest_api.example.id\r\n   stage_name  = \"test\"\r\n}\r\n\r\n# Output to the URL \r\noutput \"base_url\" {\r\n  value = aws_api_gateway_deployment.example.invoke_url\r\n}"
  },
  {
    "path": "samples/lambda-container-apigateway-flaskapp/ecr/0_ecr.tf",
    "content": "terraform {\r\n  required_providers {\r\n    aws = {\r\n      source  = \"hashicorp/aws\"\r\n      version = \"~> 4.16\"\r\n    }\r\n  }\r\n  required_version = \">= 1.2.0\"\r\n}\r\n\r\n# Creating Elastic Container Repository for application\r\nresource \"aws_ecr_repository\" \"flask_app_serverless\" {\r\n  name = \"flask-app-serverless\"\r\n}\r\n\r\n\r\n# aws ecr get-login-password --region REGION | docker login --username AWS --password-stdin ID.dkr.ecr.REGION.amazonaws.com \r\n# docker build -t flask-app-serverless .\r\n# docker tag flask-app-serverless:latest ID.dkr.REGION.amazonaws.com/flask-app-serverless:latest \r\n# docker push ID.dkr.REGION.amazonaws.com/flask-app-serverless:latest"
  },
  {
    "path": "samples/lambda-container-apigateway-flaskapp/flask-app-serverless/Dockerfile",
    "content": "FROM public.ecr.aws/lambda/python:3.7\r\n\r\nWORKDIR ${LAMBDA_TASK_ROOT}\r\n\r\nCOPY app ${LAMBDA_TASK_ROOT}\r\n\r\nCOPY requirements.txt requirements.txt\r\n\r\nRUN pip3 install -r requirements.txt --target \"${LAMBDA_TASK_ROOT}\"\r\n\r\nENV FLASK_APP=app\r\n\r\nENV FLASK_ENV=development\r\n\r\nEXPOSE 5000\r\n\r\nRUN python init_db.py\r\n\r\nCMD [\"app.handler\"]"
  },
  {
    "path": "samples/lambda-container-apigateway-flaskapp/flask-app-serverless/README.md",
    "content": "## Flask-App Serverless Docker Image for Lambda Container\r\n\r\n- Dockerfile is created for this sample, for specific Lambda container usage.\r\n- App.py is updated\r\n  - importing \"serverless_wsgi, shlex, subprocess\" libraries\r\n  - handler return is updated:\r\n    - \"serverless_wsgi.handle_request(app, event, context)\"\r\n  - sqlite db file copies to \"/tmp/\" directory, because lambda allows only the files under \"/tmp/\" to have write permission\t\r\n    - \"subprocess.check_output(shlex.split(\"cp database.db /tmp/database.db\"))\"\r\n    - \"subprocess.check_output(shlex.split(\"/bin/chmod 777 /tmp/database.db\"))\"\r\n\r\n- Build Docker image:\r\n\r\n```\r\ndocker build -t flask-app-serverless .\r\n```\r\n\r\n- Source code is pulled from:\r\n  - https://www.digitalocean.com/community/tutorials/how-to-make-a-web-application-using-flask-in-python-3\r\n  - https://github.com/do-community/flask_blog\r\n\r\n- For app, Thank you Digital Ocean for the sample Flask app!"
  },
  {
    "path": "samples/lambda-container-apigateway-flaskapp/flask-app-serverless/app/app.py",
    "content": "import serverless_wsgi  # https://pypi.org/project/serverless-wsgi/\nimport sqlite3\nfrom flask import Flask, render_template, request, url_for, flash, redirect\nfrom werkzeug.exceptions import abort\nimport shlex\nimport subprocess\n\n# this is out of the invoked lambda handler, works while starting lambda function\n# copy the db file to \"/tmp/\" to use lambda ephemeral (temporary) storage, \n# because lambda allows only the files under \"/tmp/\" to have write permission\nsubprocess.check_output(shlex.split(\"cp database.db /tmp/database.db\"))\nsubprocess.check_output(shlex.split(\"/bin/chmod 777 /tmp/database.db\"))\n    \ndef get_db_connection():\n    conn = sqlite3.connect('/tmp/database.db')\n    conn.row_factory = sqlite3.Row\n    return conn\n\n\ndef get_post(post_id):\n    conn = get_db_connection()\n    post = conn.execute('SELECT * FROM posts WHERE id = ?',\n                        (post_id,)).fetchone()\n    conn.close()\n    if post is None:\n        abort(404)\n    return post\n\n\napp = Flask(__name__)\napp.config['SECRET_KEY'] = '99'\n\n\n@app.route('/')\ndef index():\n    conn = get_db_connection()\n    posts = conn.execute('SELECT * FROM posts').fetchall()\n    conn.close()\n    return render_template('index.html', posts=posts)\n\n\n@app.route('/<int:post_id>')\ndef post(post_id):\n    post = get_post(post_id)\n    return render_template('post.html', post=post)\n\n\n@app.route('/create', methods=('GET', 'POST'))\ndef create():\n    if request.method == 'POST':\n        title = request.form['title']\n        content = request.form['content']\n\n        if not title:\n            flash('Title is required!')\n        else:\n            conn = get_db_connection()\n            conn.execute('INSERT INTO posts (title, content) VALUES (?, ?)',\n                         (title, content))\n            conn.commit()\n            conn.close()\n            return redirect(url_for('index'))\n\n    return render_template('create.html')\n\n\n@app.route('/<int:id>/edit', methods=('GET', 'POST'))\ndef edit(id):\n    post = get_post(id)\n\n    if request.method == 'POST':\n        title = request.form['title']\n        content = request.form['content']\n\n        if not title:\n            flash('Title is required!')\n        else:\n            conn = get_db_connection()\n            conn.execute('UPDATE posts SET title = ?, content = ?'\n                         ' WHERE id = ?',\n                         (title, content, id))\n            conn.commit()\n            conn.close()\n            return redirect(url_for('index'))\n\n    return render_template('edit.html', post=post)\n\n\n@app.route('/<int:id>/delete', methods=('POST',))\ndef delete(id):\n    post = get_post(id)\n    conn = get_db_connection()\n    conn.execute('DELETE FROM posts WHERE id = ?', (id,))\n    conn.commit()\n    conn.close()\n    flash('\"{}\" was successfully deleted!'.format(post['title']))\n    return redirect(url_for('index'))\n\n    \ndef handler(event, context):\n    return serverless_wsgi.handle_request(app, event, context)    \n"
  },
  {
    "path": "samples/lambda-container-apigateway-flaskapp/flask-app-serverless/app/hello.py",
    "content": "from flask import Flask, request, escape\n\napp = Flask(__name__)\n\n\n@app.route('/')\ndef hello():\n    return 'Hello, World!'\n\n\n@app.route('/greet')\ndef greet():\n    name = request.args['name']\n    return '''\n    <!DOCTYPE html>\n    <html lang=\"en\">\n    <head>\n        <meta charset=\"UTF-8\">\n        <title></title>\n    </head>\n    <body>\n        <h1>Hi {}</h1>\n    </body>\n    </html>'''.format(escape(name))\n"
  },
  {
    "path": "samples/lambda-container-apigateway-flaskapp/flask-app-serverless/app/init_db.py",
    "content": "import sqlite3\n\nconnection = sqlite3.connect('database.db')\n\n\nwith open('schema.sql') as f:\n    connection.executescript(f.read())\n\ncur = connection.cursor()\n\ncur.execute(\"INSERT INTO posts (title, content) VALUES (?, ?)\",\n            ('First Post', 'Content for the first post')\n            )\n\ncur.execute(\"INSERT INTO posts (title, content) VALUES (?, ?)\",\n            ('Second Post', 'Content for the second post')\n            )\n\nconnection.commit()\nconnection.close()\n"
  },
  {
    "path": "samples/lambda-container-apigateway-flaskapp/flask-app-serverless/app/schema.sql",
    "content": "DROP TABLE IF EXISTS posts;\n\nCREATE TABLE posts (\n    id INTEGER PRIMARY KEY AUTOINCREMENT,\n    created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n    title TEXT NOT NULL,\n    content TEXT NOT NULL\n);\n"
  },
  {
    "path": "samples/lambda-container-apigateway-flaskapp/flask-app-serverless/app/static/css/style.css",
    "content": "h1 {\n    border: 2px #eee solid;\n    color: brown;\n    text-align: center;\n    padding: 10px;\n}\n\n"
  },
  {
    "path": "samples/lambda-container-apigateway-flaskapp/flask-app-serverless/app/templates/base.html",
    "content": "<!doctype html>\n<html lang=\"en\">\n  <head>\n    <!-- Required meta tags -->\n    <meta charset=\"utf-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, shrink-to-fit=no\">\n\n    <!-- Bootstrap CSS -->\n    <link rel=\"stylesheet\" href=\"https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css\" integrity=\"sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T\" crossorigin=\"anonymous\">\n\n    <title>{% block title %} {% endblock %}</title>\n  </head>\n  <body>\n      <nav class=\"navbar navbar-expand-md navbar-light bg-light\">\n        <a class=\"navbar-brand\" href=\"{{ url_for('index')}}\">FlaskBlog</a>\n        <button class=\"navbar-toggler\" type=\"button\" data-toggle=\"collapse\" data-target=\"#navbarNav\" aria-controls=\"navbarNav\" aria-expanded=\"false\" aria-label=\"Toggle navigation\">\n            <span class=\"navbar-toggler-icon\"></span>\n        </button>\n        <div class=\"collapse navbar-collapse\" id=\"navbarNav\">\n            <ul class=\"navbar-nav\">\n            <li class=\"nav-item\">\n                <a class=\"nav-link\" href=\"#\">About</a>\n            </li>\n            <li class=\"nav-item\">\n                <a class=\"nav-link\" href=\"{{url_for('create')}}\">New Post</a>\n            </li>\n            </ul>\n        </div>\n      </nav>\n    <div class=\"container\">\n        {% for message in get_flashed_messages() %}\n            <div class=\"alert alert-danger\">{{ message }}</div>\n        {% endfor %}\n        {% block content %} {% endblock %}\n    </div>\n\n    <!-- Optional JavaScript -->\n    <!-- jQuery first, then Popper.js, then Bootstrap JS -->\n    <script src=\"https://code.jquery.com/jquery-3.3.1.slim.min.js\" integrity=\"sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo\" crossorigin=\"anonymous\"></script>\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js\" integrity=\"sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1\" crossorigin=\"anonymous\"></script>\n    <script src=\"https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js\" integrity=\"sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM\" crossorigin=\"anonymous\"></script>\n  </body>\n</html>\n\n"
  },
  {
    "path": "samples/lambda-container-apigateway-flaskapp/flask-app-serverless/app/templates/create.html",
    "content": "{% extends 'base.html' %}\n\n{% block content %}\n<h1>{% block title %} Create a New Post {% endblock %}</h1>\n\n<form method=\"post\">\n    <div class=\"form-group\">\n        <label for=\"title\">Title</label>\n        <input type=\"text\" name=\"title\"\n               placeholder=\"Post title\" class=\"form-control\"\n               value=\"{{ request.form['title'] }}\"></input>\n    </div>\n\n    <div class=\"form-group\">\n        <label for=\"content\">Content</label>\n        <textarea name=\"content\" placeholder=\"Post content\"\n                  class=\"form-control\">{{ request.form['content'] }}</textarea>\n    </div>\n    <div class=\"form-group\">\n        <button type=\"submit\" class=\"btn btn-primary\">Submit</button>\n    </div>\n</form>\n{% endblock %}\n"
  },
  {
    "path": "samples/lambda-container-apigateway-flaskapp/flask-app-serverless/app/templates/edit.html",
    "content": "{% extends 'base.html' %}\n\n{% block content %}\n<h1>{% block title %} Edit \"{{ post['title'] }}\" {% endblock %}</h1>\n\n<form method=\"post\">\n    <div class=\"form-group\">\n        <label for=\"title\">Title</label>\n        <input type=\"text\" name=\"title\" placeholder=\"Post title\"\n               class=\"form-control\"\n               value=\"{{ request.form['title'] or post['title'] }}\">\n        </input>\n    </div>\n\n    <div class=\"form-group\">\n        <label for=\"content\">Content</label>\n        <textarea name=\"content\" placeholder=\"Post content\"\n                  class=\"form-control\">{{ request.form['content'] or post['content'] }}</textarea>\n    </div>\n    <div class=\"form-group\">\n        <button type=\"submit\" class=\"btn btn-primary\">Submit</button>\n    </div>\n</form>\n<hr>\n<form action=\"{{ url_for('delete', id=post['id']) }}\" method=\"POST\">\n    <input type=\"submit\" value=\"Delete Post\"\n            class=\"btn btn-danger btn-sm\"\n            onclick=\"return confirm('Are you sure you want to delete this post?')\">\n</form>\n{% endblock %}\n\n"
  },
  {
    "path": "samples/lambda-container-apigateway-flaskapp/flask-app-serverless/app/templates/index.html",
    "content": "{% extends 'base.html' %}\n\n{% block content %}\n    <h1>{% block title %} Welcome to FlaskBlog {% endblock %}</h1>\n    {% for post in posts %}\n        <a href=\"{{ url_for('post', post_id=post['id']) }}\">\n            <h2>{{ post['title'] }}</h2>\n        </a>\n        <span class=\"badge badge-primary\">{{ post['created'] }}</span>\n        <a href=\"{{ url_for('edit', id=post['id']) }}\">\n            <span class=\"badge badge-warning\">Edit</span>\n        </a>\n        <hr>\n    {% endfor %}\n{% endblock %}\n"
  },
  {
    "path": "samples/lambda-container-apigateway-flaskapp/flask-app-serverless/app/templates/post.html",
    "content": "{% extends 'base.html' %}\n\n{% block content %}\n    <h2>{% block title %} {{ post['title'] }} {% endblock %}</h2>\n    <span class=\"badge badge-primary\">{{ post['created'] }}</span>\n    <p>{{ post['content'] }}</p>\n{% endblock %}\n"
  },
  {
    "path": "samples/lambda-container-apigateway-flaskapp/flask-app-serverless/requirements.txt",
    "content": "flask\r\ndb-sqlite3\r\nWerkzeug\r\nserverless-wsgi>=2.0.2\r\nushlex"
  },
  {
    "path": "samples/lambda-role-policy-apigateway-python/api-gateway.tf",
    "content": "# Create API Gateway with Rest API type\r\nresource \"aws_api_gateway_rest_api\" \"example\" {\r\n  name        = \"Serverless\"\r\n  description = \"Serverless Application using Terraform\"\r\n}\r\n\r\n# Defines a resource in the API Gateway that will capture any request path. The path_part = \"{proxy+}\" allows API Gateway to match all requests that have any path pattern, enabling dynamic routing.\r\nresource \"aws_api_gateway_resource\" \"proxy\" {\r\n   rest_api_id = aws_api_gateway_rest_api.example.id\r\n   parent_id   = aws_api_gateway_rest_api.example.root_resource_id\r\n   path_part   = \"{proxy+}\"     # with proxy, this resource will match any request path\r\n}\r\n\r\n# Configures to allow any HTTP method (GET, POST, DELETE, etc.) and does not require any specific authorization. It's set for the previously defined proxy resource.\r\nresource \"aws_api_gateway_method\" \"proxy\" {\r\n   rest_api_id   = aws_api_gateway_rest_api.example.id\r\n   resource_id   = aws_api_gateway_resource.proxy.id\r\n   http_method   = \"ANY\"       # with ANY, it allows any request method to be used, all incoming requests will match this resource\r\n   authorization = \"NONE\"\r\n}\r\n\r\n# API Gateway - Lambda Connection\r\n# The AWS_PROXY type means API Gateway will directly pass the request details (method, headers, body, path parameters, etc.) to the Lambda function\r\nresource \"aws_api_gateway_integration\" \"lambda\" {\r\n   rest_api_id = aws_api_gateway_rest_api.example.id\r\n   resource_id = aws_api_gateway_method.proxy.resource_id\r\n   http_method = aws_api_gateway_method.proxy.http_method\r\n   integration_http_method = \"POST\"\r\n   type                    = \"AWS_PROXY\"  # With AWS_PROXY, it causes API gateway to call into the API of another AWS service\r\n   uri                     = aws_lambda_function.lambda_function.invoke_arn\r\n}\r\n\r\n# The proxy resource cannot match an empty path at the root of the API. API GW doesn't route requests to the root (/) path using the proxy, so a separate method and integration for the root resource are required.\r\n# To handle that, a similar configuration must be applied to the root resource that is built in to the REST API object.\r\n# This ensures that requests to the root (e.g., https://api.example.com/) are also forwarded to the Lambda function.\r\nresource \"aws_api_gateway_method\" \"proxy_root\" {\r\n   rest_api_id   = aws_api_gateway_rest_api.example.id\r\n   resource_id   = aws_api_gateway_rest_api.example.root_resource_id\r\n   http_method   = \"ANY\"\r\n   authorization = \"NONE\"\r\n}\r\n\r\nresource \"aws_api_gateway_integration\" \"lambda_root\" {\r\n   rest_api_id = aws_api_gateway_rest_api.example.id\r\n   resource_id = aws_api_gateway_method.proxy_root.resource_id\r\n   http_method = aws_api_gateway_method.proxy_root.http_method\r\n   integration_http_method = \"POST\"\r\n   type                    = \"AWS_PROXY\"  # With AWS_PROXY, it causes API gateway to call into the API of another AWS service\r\n   uri                     = aws_lambda_function.lambda_function.invoke_arn\r\n}\r\n\r\n# Deploy API Gateway\r\n# Deploys the API to the specified stage (test stage). The depends_on ensures that the API is not deployed until both the Lambda integrations (for proxy and root) are complete.\r\nresource \"aws_api_gateway_deployment\" \"example\" {\r\n   depends_on = [\r\n     aws_api_gateway_integration.lambda,\r\n     aws_api_gateway_integration.lambda_root,\r\n   ]\r\n   rest_api_id = aws_api_gateway_rest_api.example.id\r\n   stage_name  = \"test\"\r\n}\r\n\r\n# Output to the URL \r\noutput \"base_url\" {\r\n  value = aws_api_gateway_deployment.example.invoke_url\r\n}\r\n"
  },
  {
    "path": "samples/lambda-role-policy-apigateway-python/code/main.py",
    "content": "def lambda_handler(event, context):\r\n   content = \"\"\"\r\n   <html>\r\n   <h1> Hello Website running on Lambda! Deployed via Terraform </h1>\r\n   </html>\r\n   \"\"\"\r\n   response ={\r\n     \"statusCode\": 200,\r\n     \"body\": content,\r\n     \"headers\": {\"Content-Type\": \"text/html\",}, \r\n   }\r\n   return response"
  },
  {
    "path": "samples/lambda-role-policy-apigateway-python/lambda.tf",
    "content": "terraform {\r\n  required_providers {\r\n    aws = {\r\n      source  = \"hashicorp/aws\"\r\n      version = \"~> 4.16\"\r\n    }\r\n  }\r\n  required_version = \">= 1.2.0\"\r\n}\r\n\r\n# Create IAM Role for lambda\r\n# The assume_role_policy defines who or what can assume this role. In this case, it allows lambda to assume the role, which is necessary for Lambda functions to execute with this role's permissions.\r\n# The policy allows STS (Security Token Service) to manage temporary credentials for the Lambda service.\r\nresource \"aws_iam_role\" \"lambda_role\" {\r\n name   = \"aws_lambda_role\"\r\n assume_role_policy = <<EOF\r\n{\r\n  \"Version\": \"2012-10-17\",\r\n  \"Statement\": [\r\n    {\r\n      \"Action\": \"sts:AssumeRole\",\r\n      \"Principal\": {\r\n        \"Service\": \"lambda.amazonaws.com\"\r\n      },\r\n      \"Effect\": \"Allow\",\r\n      \"Sid\": \"\"\r\n    }\r\n  ]\r\n}\r\nEOF\r\n}\r\n\r\n# The policy gives permissions for Lambda to create log groups, log streams, and put log events in CloudWatch Logs.\r\n# Necessary permissions for Lambda to output logs for monitoring and debugging.\r\nresource \"aws_iam_policy\" \"iam_policy_for_lambda\" {\r\n\r\n  name         = \"aws_iam_policy_for_aws_lambda_role\"\r\n  path         = \"/\"\r\n  description  = \"AWS IAM Policy for managing aws lambda role\"\r\n  policy = <<EOF\r\n{\r\n  \"Version\": \"2012-10-17\",\r\n  \"Statement\": [\r\n    {\r\n      \"Action\": [\r\n        \"logs:CreateLogGroup\",\r\n        \"logs:CreateLogStream\",\r\n        \"logs:PutLogEvents\"\r\n      ],\r\n      \"Resource\": \"arn:aws:logs:*:*:*\",\r\n      \"Effect\": \"Allow\"\r\n    }\r\n  ]\r\n}\r\nEOF\r\n}\r\n\r\n# Role - Policy Attachment\r\nresource \"aws_iam_role_policy_attachment\" \"attach_iam_policy_to_iam_role\" {\r\n  role        = aws_iam_role.lambda_role.name\r\n  policy_arn  = aws_iam_policy.iam_policy_for_lambda.arn\r\n}\r\n\r\n# Zipping the code, lambda wants the code as zip file\r\ndata \"archive_file\" \"zip_the_python_code\" {\r\n type        = \"zip\"\r\n source_dir  = \"${path.module}/code/\"\r\n output_path = \"${path.module}/code/main.zip\"\r\n}\r\n\r\n# Lambda Function, in terraform ${path.module} is the current directory.\r\nresource \"aws_lambda_function\" \"lambda_function\" {\r\n filename                       = \"${path.module}/code/main.zip\"\r\n function_name                  = \"Lambda-Function\"\r\n role                           = aws_iam_role.lambda_role.arn\r\n handler                        = \"main.lambda_handler\"\r\n runtime                        = \"python3.8\"\r\n depends_on                     = [aws_iam_role_policy_attachment.attach_iam_policy_to_iam_role]\r\n}\r\n\r\n# With Lambda permission, API Gateway can invoke Lambda \r\nresource \"aws_lambda_permission\" \"apigw\" {\r\n statement_id  = \"AllowAPIGatewayInvoke\"\r\n action        = \"lambda:InvokeFunction\"\r\n function_name = aws_lambda_function.lambda_function.function_name\r\n principal     = \"apigateway.amazonaws.com\"\r\n # The \"/*/*\" portion grants access from any method on any resource within the API Gateway REST API.\r\n source_arn = \"${aws_api_gateway_rest_api.example.execution_arn}/*/*\"\r\n}\r\n\r\n"
  },
  {
    "path": "samples/mlops-sagemaker-github-codepipeline-codebuild-codedeploy/Notebooks/SageMaker_Customer_Churn_XGB_Pipeline.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"attachments\": {},\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## SageMaker Model Building and Deployment using SageMaker Workflow Pipeline\"\n   ]\n  },\n  {\n   \"attachments\": {},\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"\\n\",\n    \"In this notebook we show how to use Amazon SageMaker to develop, train, tune and deploy a XGBoost model. Sythetic customer churn data is used. \\n\",\n    \"\\n\",\n    \"The data is in AWS public S3 bucket: s3://sagemaker-sample-files/datasets/tabular/synthetic/churn.txt\\n\",\n    \"\\n\",\n    \"Sklearn Processor is used to process the raw data.\\n\",\n    \"\\n\",\n    \"* XGBoost https://sagemaker.readthedocs.io/en/stable/frameworks/xgboost/using_xgboost.html?highlight=xgboost\\n\",\n    \"* Doc https://sagemaker.readthedocs.io/en/stable/using_sklearn.html\\n\",\n    \"* SDK https://sagemaker.readthedocs.io/en/stable/sagemaker.sklearn.html\\n\",\n    \"* boto3 https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/sagemaker.html#client\\n\",\n    \" \\n\",\n    \"**This sample is provided for demonstration purposes, make sure to conduct appropriate testing if derivating this code for your own use-cases!**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"%matplotlib inline\\n\",\n    \"import os\\n\",\n    \"import time\\n\",\n    \"import logging\\n\",\n    \"import pandas as pd\\n\",\n    \"import numpy as np\\n\",\n    \"import sagemaker\\n\",\n    \"import json\\n\",\n    \"import boto3\\n\",\n    \"from sagemaker import get_execution_role\\n\",\n    \"\\n\",\n    \"sm_client = boto3.client('sagemaker')\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"from sagemaker.estimator import Estimator\\n\",\n    \"from sagemaker.inputs import TrainingInput\\n\",\n    \"from sagemaker.model_metrics import MetricsSource, ModelMetrics\\n\",\n    \"from sagemaker.processing import ProcessingInput, ProcessingOutput, ScriptProcessor\\n\",\n    \"from sagemaker.sklearn.processing import SKLearnProcessor\\n\",\n    \"from sagemaker.workflow.condition_step import ConditionStep\\n\",\n    \"from sagemaker.workflow.conditions import ConditionGreaterThanOrEqualTo\\n\",\n    \"from sagemaker.workflow.functions import JsonGet\\n\",\n    \"from sagemaker.workflow.parameters import ParameterInteger, ParameterString\\n\",\n    \"from sagemaker.workflow.pipeline import Pipeline\\n\",\n    \"from sagemaker.workflow.properties import PropertyFile\\n\",\n    \"from sagemaker.workflow.step_collections import RegisterModel\\n\",\n    \"from sagemaker.workflow.steps import ProcessingStep, TrainingStep\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# Retrieve the bucket\\n\",\n    \"sagemaker_session = sagemaker.Session()\\n\",\n    \"bucket = sagemaker_session.default_bucket()  # this could also be a hard-coded bucket name\\n\",\n    \"region = sagemaker_session.boto_region_name\\n\",\n    \"print(region)\\n\",\n    \"role = get_execution_role()\\n\",\n    \"\\n\",\n    \"project_name = \\\"test_pro\\\"\\n\",\n    \"project_id = \\\"test_id\\\"\\n\",\n    \"#model_package_group_name = project_name\\n\",\n    \"print(f\\\"sagemaker role arn <{role}>\\\")\\n\",\n    \"\\n\",\n    \"assert(len(project_name) <= 15 ) # the project name should not have more than 15 chars\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"print(bucket)\"\n   ]\n  },\n  {\n   \"attachments\": {},\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Load Raw Data to S3\"\n   ]\n  },\n  {\n   \"attachments\": {},\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"Load raw data from the public S3 bucket to your own S3 bucket.\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"!aws s3 cp s3://sagemaker-sample-files/datasets/tabular/synthetic/churn.txt s3://{bucket}/sagemaker/DEMO-xgboost-churn/data/RawData.csv \"\n   ]\n  },\n  {\n   \"attachments\": {},\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Prepare script to be used by preprocessing job and model evaluation\"\n   ]\n  },\n  {\n   \"attachments\": {},\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"Create preprocessing script. This script will be used by SageMaker process job instance to preocess raw data.\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"%%writefile preprocess.py\\n\",\n    \"\\n\",\n    \"\\\"\\\"\\\"Preprocess the customer churn dataset.\\\"\\\"\\\"\\n\",\n    \"\\n\",\n    \"import argparse\\n\",\n    \"import logging\\n\",\n    \"import pathlib\\n\",\n    \"\\n\",\n    \"import boto3\\n\",\n    \"import numpy as np\\n\",\n    \"import pandas as pd\\n\",\n    \"\\n\",\n    \"logger = logging.getLogger()\\n\",\n    \"logger.setLevel(logging.INFO)\\n\",\n    \"logger.addHandler(logging.StreamHandler())\\n\",\n    \"\\n\",\n    \"if __name__ == \\\"__main__\\\":\\n\",\n    \"    logger.info(\\\"Starting preprocessing.\\\")\\n\",\n    \"    parser = argparse.ArgumentParser()\\n\",\n    \"    parser.add_argument(\\\"--input-data\\\", type=str, required=True)\\n\",\n    \"    args = parser.parse_args()\\n\",\n    \"\\n\",\n    \"    base_dir = \\\"/opt/ml/processing\\\"\\n\",\n    \"    pathlib.Path(f\\\"{base_dir}/data\\\").mkdir(parents=True, exist_ok=True)\\n\",\n    \"    input_data = args.input_data\\n\",\n    \"    print(input_data)\\n\",\n    \"    bucket = input_data.split(\\\"/\\\")[2]\\n\",\n    \"    key = \\\"/\\\".join(input_data.split(\\\"/\\\")[3:])\\n\",\n    \"\\n\",\n    \"    logger.info(\\\"Downloading data from bucket: %s, key: %s\\\", bucket, key)\\n\",\n    \"    fn = f\\\"{base_dir}/data/raw-data.csv\\\"\\n\",\n    \"    s3 = boto3.resource(\\\"s3\\\")\\n\",\n    \"    s3.Bucket(bucket).download_file(key, fn)\\n\",\n    \"\\n\",\n    \"    logger.info(\\\"Reading downloaded data.\\\")\\n\",\n    \"\\n\",\n    \"    # read in csv\\n\",\n    \"    df = pd.read_csv(fn)\\n\",\n    \"\\n\",\n    \"    # drop the \\\"Phone\\\" feature column\\n\",\n    \"    df = df.drop([\\\"Phone\\\"], axis=1)\\n\",\n    \"\\n\",\n    \"    # Change the data type of \\\"Area Code\\\"\\n\",\n    \"    df[\\\"Area Code\\\"] = df[\\\"Area Code\\\"].astype(object)\\n\",\n    \"\\n\",\n    \"    # Drop several other columns\\n\",\n    \"    df = df.drop([\\\"Day Charge\\\", \\\"Eve Charge\\\", \\\"Night Charge\\\", \\\"Intl Charge\\\"], axis=1)\\n\",\n    \"\\n\",\n    \"    # Convert categorical variables into dummy/indicator variables.\\n\",\n    \"    model_data = pd.get_dummies(df)\\n\",\n    \"\\n\",\n    \"    # Create one binary classification target column\\n\",\n    \"    model_data = pd.concat(\\n\",\n    \"        [\\n\",\n    \"            model_data[\\\"Churn?_True.\\\"],\\n\",\n    \"            model_data.drop([\\\"Churn?_False.\\\", \\\"Churn?_True.\\\"], axis=1),\\n\",\n    \"        ],\\n\",\n    \"        axis=1,\\n\",\n    \"    )\\n\",\n    \"\\n\",\n    \"    # Split the data\\n\",\n    \"    train_data, validation_data, test_data = np.split(\\n\",\n    \"        model_data.sample(frac=1, random_state=1729),\\n\",\n    \"        [int(0.7 * len(model_data)), int(0.9 * len(model_data))],\\n\",\n    \"    )\\n\",\n    \"\\n\",\n    \"    pd.DataFrame(train_data).to_csv(\\n\",\n    \"        f\\\"{base_dir}/train/train.csv\\\", header=False, index=False\\n\",\n    \"    )\\n\",\n    \"    pd.DataFrame(validation_data).to_csv(\\n\",\n    \"        f\\\"{base_dir}/validation/validation.csv\\\", header=False, index=False\\n\",\n    \"    )\\n\",\n    \"    pd.DataFrame(test_data).to_csv(\\n\",\n    \"        f\\\"{base_dir}/test/test.csv\\\", header=False, index=False\\n\",\n    \"    )\\n\"\n   ]\n  },\n  {\n   \"attachments\": {},\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"### Prepare evaluation script\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"%%writefile evaluate.py\\n\",\n    \"\\n\",\n    \"\\\"\\\"\\\"Evaluation script for measuring model accuracy.\\\"\\\"\\\"\\n\",\n    \"\\n\",\n    \"import json\\n\",\n    \"import os\\n\",\n    \"import tarfile\\n\",\n    \"import logging\\n\",\n    \"import pickle\\n\",\n    \"\\n\",\n    \"import pandas as pd\\n\",\n    \"import xgboost\\n\",\n    \"\\n\",\n    \"logger = logging.getLogger()\\n\",\n    \"logger.setLevel(logging.INFO)\\n\",\n    \"logger.addHandler(logging.StreamHandler())\\n\",\n    \"\\n\",\n    \"# May need to import additional metrics depending on what you are measuring.\\n\",\n    \"# See https://docs.aws.amazon.com/sagemaker/latest/dg/model-monitor-model-quality-metrics.html\\n\",\n    \"from sklearn.metrics import classification_report, roc_auc_score, accuracy_score\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == \\\"__main__\\\":\\n\",\n    \"    model_path = \\\"/opt/ml/processing/model/model.tar.gz\\\"\\n\",\n    \"    with tarfile.open(model_path) as tar:\\n\",\n    \"        tar.extractall(path=\\\"..\\\")\\n\",\n    \"\\n\",\n    \"    logger.debug(\\\"Loading xgboost model.\\\")\\n\",\n    \"    model = pickle.load(open(\\\"xgboost-model\\\", \\\"rb\\\"))\\n\",\n    \"\\n\",\n    \"    print(\\\"Loading test input data\\\")\\n\",\n    \"    test_path = \\\"/opt/ml/processing/test/test.csv\\\"\\n\",\n    \"    df = pd.read_csv(test_path, header=None)\\n\",\n    \"\\n\",\n    \"    logger.debug(\\\"Reading test data.\\\")\\n\",\n    \"    y_test = df.iloc[:, 0].to_numpy()\\n\",\n    \"    df.drop(df.columns[0], axis=1, inplace=True)\\n\",\n    \"    X_test = xgboost.DMatrix(df.values)\\n\",\n    \"\\n\",\n    \"    logger.info(\\\"Performing predictions against test data.\\\")\\n\",\n    \"    predictions = model.predict(X_test)\\n\",\n    \"\\n\",\n    \"    print(\\\"Creating classification evaluation report\\\")\\n\",\n    \"    acc = accuracy_score(y_test, predictions.round())\\n\",\n    \"    auc = roc_auc_score(y_test, predictions.round())\\n\",\n    \"\\n\",\n    \"    # The metrics reported can change based on the model used, but it must be a specific name per (https://docs.aws.amazon.com/sagemaker/latest/dg/model-monitor-model-quality-metrics.html)\\n\",\n    \"    report_dict = {\\n\",\n    \"        \\\"binary_classification_metrics\\\": {\\n\",\n    \"            \\\"accuracy\\\": {\\n\",\n    \"                \\\"value\\\": acc,\\n\",\n    \"                \\\"standard_deviation\\\" : \\\"NaN\\\"\\n\",\n    \"            },\\n\",\n    \"            \\\"auc\\\" : {\\n\",\n    \"                \\\"value\\\" : auc,\\n\",\n    \"                \\\"standard_deviation\\\": \\\"NaN\\\"\\n\",\n    \"            },\\n\",\n    \"        },\\n\",\n    \"    }\\n\",\n    \"    evaluation_output_path = '/opt/ml/processing/evaluation/evaluation.json'\\n\",\n    \"    with open(evaluation_output_path, 'w') as f:\\n\",\n    \"        f.write(json.dumps(report_dict))\\n\",\n    \"    \\n\"\n   ]\n  },\n  {\n   \"attachments\": {},\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Define Model Building Pipeline\"\n   ]\n  },\n  {\n   \"attachments\": {},\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \" Pipeline input parameters are listed below. \"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"processing_instance_count = ParameterInteger(name=\\\"ProcessingInstanceCount\\\", default_value=1)\\n\",\n    \"processing_instance_type = ParameterString(\\n\",\n    \"        name=\\\"ProcessingInstanceType\\\", default_value=\\\"ml.m5.xlarge\\\"\\n\",\n    \"    )\\n\",\n    \"\\n\",\n    \"training_instance_type = ParameterString(\\n\",\n    \"        name=\\\"TrainingInstanceType\\\", default_value=\\\"ml.m5.xlarge\\\"\\n\",\n    \"    )\\n\",\n    \"\\n\",\n    \"model_approval_status = ParameterString(\\n\",\n    \"        name=\\\"ModelApprovalStatus\\\",\\n\",\n    \"        default_value=\\\"Approved\\\",  # ModelApprovalStatus can be set to a default of \\\"Approved\\\" if you don't want manual approval.\\n\",\n    \"    )\\n\",\n    \"\\n\",\n    \"input_data = ParameterString(\\n\",\n    \"        name=\\\"InputDataUrl\\\",\\n\",\n    \"        default_value=f\\\"s3://{sagemaker_session.default_bucket()}/sagemaker/DEMO-xgboost-churn/data/RawData.csv\\\",  # Change this to point to the s3 location of your raw input data.\\n\",\n    \"    )\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"model_package_group_name=\\\"CustomerChurnPackageGroup\\\"  # Choose any name\\n\",\n    \"#pipeline_name=\\\"CustomerChurnDemoPipe2\\\"  # \\n\",\n    \"base_job_prefix=\\\"CustomerChurn\\\"  # Choose any name\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"from time import strftime,gmtime\\n\",\n    \"pipeline_name = 'CustomerChurn-Pipe-' + strftime(\\\"%M%S\\\", gmtime())\"\n   ]\n  },\n  {\n   \"attachments\": {},\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"The below defines a SageMaker model buidling pipeline using workflow. \"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# Processing step for feature engineering\\n\",\n    \"sklearn_processor = SKLearnProcessor(\\n\",\n    \"    framework_version=\\\"0.23-1\\\",\\n\",\n    \"    instance_type=processing_instance_type,\\n\",\n    \"    instance_count=processing_instance_count,\\n\",\n    \"    base_job_name=f\\\"{base_job_prefix}/sklearn-CustomerChurn-preprocess\\\",  # choose any name\\n\",\n    \"    sagemaker_session=sagemaker_session,\\n\",\n    \"    role=role,\\n\",\n    \")\\n\",\n    \"step_process = ProcessingStep(\\n\",\n    \"    name=\\\"CustomerChurnProcess\\\",  # choose any name\\n\",\n    \"    processor=sklearn_processor,\\n\",\n    \"    outputs=[\\n\",\n    \"        ProcessingOutput(output_name=\\\"train\\\", source=\\\"/opt/ml/processing/train\\\"),\\n\",\n    \"        ProcessingOutput(output_name=\\\"validation\\\", source=\\\"/opt/ml/processing/validation\\\"),\\n\",\n    \"        ProcessingOutput(output_name=\\\"test\\\", source=\\\"/opt/ml/processing/test\\\"),\\n\",\n    \"    ],\\n\",\n    \"    code=(\\\"preprocess.py\\\"),\\n\",\n    \"    job_arguments=[\\\"--input-data\\\", input_data],\\n\",\n    \")\\n\",\n    \"# Training step for generating model artifacts\\n\",\n    \"model_path = f\\\"s3://{sagemaker_session.default_bucket()}/{base_job_prefix}/CustomerChurnTrain\\\"\\n\",\n    \"image_uri = sagemaker.image_uris.retrieve(\\n\",\n    \"    framework=\\\"xgboost\\\",  # we are using the Sagemaker built in xgboost algorithm\\n\",\n    \"    region=region,\\n\",\n    \"    version=\\\"1.0-1\\\",\\n\",\n    \"    py_version=\\\"py3\\\",\\n\",\n    \"    instance_type=training_instance_type,\\n\",\n    \")\\n\",\n    \"xgb_train = Estimator(\\n\",\n    \"    image_uri=image_uri,\\n\",\n    \"    instance_type=training_instance_type,\\n\",\n    \"    instance_count=1,\\n\",\n    \"    output_path=model_path,\\n\",\n    \"    base_job_name=f\\\"{base_job_prefix}/CustomerChurn-train\\\",\\n\",\n    \"    sagemaker_session=sagemaker_session,\\n\",\n    \"    role=role,\\n\",\n    \")\\n\",\n    \"xgb_train.set_hyperparameters(\\n\",\n    \"    objective=\\\"binary:logistic\\\",\\n\",\n    \"    num_round=50,\\n\",\n    \"    max_depth=5,\\n\",\n    \"    eta=0.2,\\n\",\n    \"    gamma=4,\\n\",\n    \"    min_child_weight=6,\\n\",\n    \"    subsample=0.7,\\n\",\n    \"    silent=0,\\n\",\n    \")\\n\",\n    \"step_train = TrainingStep(\\n\",\n    \"    name=\\\"CustomerChurnTrain\\\",\\n\",\n    \"    estimator=xgb_train,\\n\",\n    \"    inputs={\\n\",\n    \"        \\\"train\\\": TrainingInput(\\n\",\n    \"            s3_data=step_process.properties.ProcessingOutputConfig.Outputs[\\n\",\n    \"                \\\"train\\\"\\n\",\n    \"            ].S3Output.S3Uri,\\n\",\n    \"            content_type=\\\"text/csv\\\",\\n\",\n    \"        ),\\n\",\n    \"        \\\"validation\\\": TrainingInput(\\n\",\n    \"            s3_data=step_process.properties.ProcessingOutputConfig.Outputs[\\n\",\n    \"                \\\"validation\\\"\\n\",\n    \"            ].S3Output.S3Uri,\\n\",\n    \"            content_type=\\\"text/csv\\\",\\n\",\n    \"        ),\\n\",\n    \"    },\\n\",\n    \")\\n\",\n    \"# Processing step for evaluation\\n\",\n    \"script_eval = ScriptProcessor(\\n\",\n    \"    image_uri=image_uri,\\n\",\n    \"    command=[\\\"python3\\\"],\\n\",\n    \"    instance_type=processing_instance_type,\\n\",\n    \"    instance_count=1,\\n\",\n    \"    base_job_name=f\\\"{base_job_prefix}/script-CustomerChurn-eval\\\",\\n\",\n    \"    sagemaker_session=sagemaker_session,\\n\",\n    \"    role=role,\\n\",\n    \")\\n\",\n    \"evaluation_report = PropertyFile(\\n\",\n    \"    name=\\\"EvaluationReport\\\",\\n\",\n    \"    output_name=\\\"evaluation\\\",\\n\",\n    \"    path=\\\"evaluation.json\\\",\\n\",\n    \")\\n\",\n    \"step_eval = ProcessingStep(\\n\",\n    \"    name=\\\"CustomerChurnEval\\\",\\n\",\n    \"    processor=script_eval,\\n\",\n    \"    inputs=[\\n\",\n    \"        ProcessingInput(\\n\",\n    \"            source=step_train.properties.ModelArtifacts.S3ModelArtifacts,\\n\",\n    \"            destination=\\\"/opt/ml/processing/model\\\",\\n\",\n    \"        ),\\n\",\n    \"        ProcessingInput(\\n\",\n    \"            source=step_process.properties.ProcessingOutputConfig.Outputs[\\n\",\n    \"                \\\"test\\\"\\n\",\n    \"            ].S3Output.S3Uri,\\n\",\n    \"            destination=\\\"/opt/ml/processing/test\\\",\\n\",\n    \"        ),\\n\",\n    \"    ],\\n\",\n    \"    outputs=[\\n\",\n    \"        ProcessingOutput(output_name=\\\"evaluation\\\", source=\\\"/opt/ml/processing/evaluation\\\"),\\n\",\n    \"    ],\\n\",\n    \"    code=(\\\"evaluate.py\\\"),\\n\",\n    \"    property_files=[evaluation_report],\\n\",\n    \")\\n\",\n    \"# Register model step that will be conditionally executed\\n\",\n    \"model_metrics = ModelMetrics(\\n\",\n    \"    model_statistics=MetricsSource(\\n\",\n    \"        s3_uri=\\\"{}/evaluation.json\\\".format(\\n\",\n    \"            step_eval.arguments[\\\"ProcessingOutputConfig\\\"][\\\"Outputs\\\"][0][\\\"S3Output\\\"][\\\"S3Uri\\\"]\\n\",\n    \"        ),\\n\",\n    \"        content_type=\\\"application/json\\\",\\n\",\n    \"    )\\n\",\n    \")\\n\",\n    \"# Register model step that will be conditionally executed\\n\",\n    \"step_register = RegisterModel(\\n\",\n    \"    name=\\\"CustomerChurnRegisterModel\\\",\\n\",\n    \"    estimator=xgb_train,\\n\",\n    \"    model_data=step_train.properties.ModelArtifacts.S3ModelArtifacts,\\n\",\n    \"    content_types=[\\\"text/csv\\\"],\\n\",\n    \"    response_types=[\\\"text/csv\\\"],\\n\",\n    \"    inference_instances=[\\\"ml.t2.medium\\\", \\\"ml.m5.large\\\"],\\n\",\n    \"    transform_instances=[\\\"ml.m5.large\\\"],\\n\",\n    \"    model_package_group_name=model_package_group_name,\\n\",\n    \"    approval_status=model_approval_status,\\n\",\n    \"    model_metrics=model_metrics,\\n\",\n    \")\\n\",\n    \"# Condition step for evaluating model quality and branching execution\\n\",\n    \"cond_lte = ConditionGreaterThanOrEqualTo(  # You can change the condition here\\n\",\n    \"    left=JsonGet(\\n\",\n    \"        step_name=step_eval.name,\\n\",\n    \"        property_file=evaluation_report,\\n\",\n    \"        json_path=\\\"binary_classification_metrics.accuracy.value\\\",  # This should follow the structure of your report_dict defined in the evaluate.py file.\\n\",\n    \"    ),\\n\",\n    \"    right=0.8,  # You can change the threshold here\\n\",\n    \")\\n\",\n    \"step_cond = ConditionStep(\\n\",\n    \"    name=\\\"CustomerChurnAccuracyCond\\\",\\n\",\n    \"    conditions=[cond_lte],\\n\",\n    \"    if_steps=[step_register],\\n\",\n    \"    else_steps=[],\\n\",\n    \")\\n\",\n    \"\\n\",\n    \"# Pipeline instance\\n\",\n    \"pipeline = Pipeline(\\n\",\n    \"    name=pipeline_name,\\n\",\n    \"    parameters=[\\n\",\n    \"        processing_instance_type,\\n\",\n    \"        processing_instance_count,\\n\",\n    \"        training_instance_type,\\n\",\n    \"        model_approval_status,\\n\",\n    \"        input_data,\\n\",\n    \"    ],\\n\",\n    \"    steps=[step_process, step_train, step_eval, step_cond],\\n\",\n    \"    sagemaker_session=sagemaker_session,\\n\",\n    \")\"\n   ]\n  },\n  {\n   \"attachments\": {},\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Create Pipeline\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"from botocore.exceptions import ClientError, ValidationError\\n\",\n    \"\\n\",\n    \"try:\\n\",\n    \"    response = pipeline.create(role_arn=role)\\n\",\n    \"except ClientError as e:\\n\",\n    \"    error = e.response[\\\"Error\\\"]\\n\",\n    \"    if error[\\\"Code\\\"] == \\\"ValidationError\\\" and \\\"Pipeline names must be unique within\\\" in error[\\\"Message\\\"]:\\n\",\n    \"        print(error[\\\"Message\\\"])\\n\",\n    \"        response = pipeline.describe()\\n\",\n    \"    else:\\n\",\n    \"        raise\\n\",\n    \"\\n\",\n    \"pipeline_arn = response[\\\"PipelineArn\\\"]\\n\",\n    \"sm_client.add_tags(\\n\",\n    \"    ResourceArn=pipeline_arn,\\n\",\n    \"    Tags=[\\n\",\n    \"        {'Key': 'sagemaker:project-name', 'Value': project_name },\\n\",\n    \"        {'Key': 'sagemaker:project-id', 'Value': project_id }\\n\",\n    \"    ]\\n\",\n    \")\\n\",\n    \"print(pipeline_arn)\"\n   ]\n  },\n  {\n   \"attachments\": {},\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Run Pipeline\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"start_response = pipeline.start()\\n\",\n    \"\\n\",\n    \"pipeline_execution_arn = start_response.arn\\n\",\n    \"print(pipeline_execution_arn)\\n\",\n    \"\\n\",\n    \"while True:\\n\",\n    \"    resp = sm_client.describe_pipeline_execution(PipelineExecutionArn=pipeline_execution_arn)\\n\",\n    \"    if resp['PipelineExecutionStatus'] == 'Executing':\\n\",\n    \"        print('Running...')\\n\",\n    \"    else:\\n\",\n    \"        print(resp['PipelineExecutionStatus'], pipeline_execution_arn)\\n\",\n    \"        break\\n\",\n    \"    time.sleep(15)\"\n   ]\n  },\n  {\n   \"attachments\": {},\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Approve the model to kick-off the deployment process\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# list all packages and select the latest one\\n\",\n    \"packages = sm_client.list_model_packages(ModelPackageGroupName=model_package_group_name)['ModelPackageSummaryList']\\n\",\n    \"packages = sorted(packages, key=lambda x: x['CreationTime'], reverse=True)\\n\",\n    \"\\n\",\n    \"latest_model_package_arn = packages[0]['ModelPackageArn']\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"sm_client.list_model_packages(ModelPackageGroupName=model_package_group_name)['ModelPackageSummaryList']\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"print(latest_model_package_arn)\"\n   ]\n  },\n  {\n   \"attachments\": {},\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Approve model\\n\",\n    \"Approval permission controlled by IAM role\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"model_package_update_response = sm_client.update_model_package(\\n\",\n    \"    ModelPackageArn=latest_model_package_arn,\\n\",\n    \"    ModelApprovalStatus=\\\"Approved\\\",\\n\",\n    \")\"\n   ]\n  },\n  {\n   \"attachments\": {},\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Get Approved model\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"model_details=sm_client.describe_model_package(ModelPackageName=latest_model_package_arn)\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"model_data=model_details['InferenceSpecification']['Containers'][0]['ModelDataUrl']\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"image_path=model_details['InferenceSpecification']['Containers'][0]['Image']\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"model_data\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"image_path\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"!mkdir pipeline_model\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"!aws s3 cp {model_data} ./pipeline_model\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"import tarfile\\n\",\n    \"# open file\\n\",\n    \"file = tarfile.open('./pipeline_model/model.tar.gz')\\n\",\n    \"  \\n\",\n    \"# extracting file\\n\",\n    \"file.extractall('./pipeline_model')\\n\",\n    \"  \\n\",\n    \"file.close()\"\n   ]\n  },\n  {\n   \"attachments\": {},\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Make prediction using Local Model\"\n   ]\n  },\n  {\n   \"attachments\": {},\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"A model is created in the SageMaker notebook instance instead of using SageMaker endpoint instance. The local model in the notebook instance is used to check predictions within the notebook. \"\n   ]\n  },\n  {\n   \"attachments\": {},\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"Steps:\\n\",\n    \"1. Install XGboost library on the Notebook instance if not installed. \\n\",\n    \"2. Load the trained model.\\n\",\n    \"3. Use test data to make predictions.\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"!pip install xgboost\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"import xgboost as xgb\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"import joblib\\n\",\n    \"loaded_model = joblib.load(\\\"./pipeline_model/xgboost-model\\\")\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"test_data=pd.read_csv('test.csv',header=None)\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"X=test_data.iloc[0:1,1:]\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"X.shape\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"xgtest = xgb.DMatrix(X.values)\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"loaded_model.predict(xgtest)\"\n   ]\n  },\n  {\n   \"attachments\": {},\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Create Endpoint\"\n   ]\n  },\n  {\n   \"attachments\": {},\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"Create Model and deploy an endpoint\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"from time import strftime,gmtime\\n\",\n    \"model_name = 'CustomerChurn-model-' + strftime(\\\"%M%S\\\", gmtime())\\n\",\n    \"model_version_arn=latest_model_package_arn\\n\",\n    \"\\n\",\n    \"print(\\\"Model name : {}\\\".format(model_name))\\n\",\n    \"\\n\",\n    \"create_model_response = sm_client.create_model(\\n\",\n    \"    ModelName = model_name,\\n\",\n    \"    ExecutionRoleArn = role,  \\n\",\n    \"    PrimaryContainer = {\\n\",\n    \"        \\\"ModelPackageName\\\": model_version_arn,\\n\",\n    \"        \\n\",\n    \"    }\\n\",\n    \"    \\n\",\n    \") \\n\",\n    \"print(\\\"Model arn : {}\\\".format(create_model_response[\\\"ModelArn\\\"]))\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"#Create endpointconfig\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"endpoint_config_name = 'Test-EndpointConfig-' + strftime(\\\"%Y-%m-%d-%H-%M-%S\\\", gmtime())\\n\",\n    \"print(endpoint_config_name)\\n\",\n    \"create_endpoint_config_response = sm_client.create_endpoint_config(\\n\",\n    \"    EndpointConfigName = endpoint_config_name,\\n\",\n    \"    ProductionVariants=[{\\n\",\n    \"        'InstanceType':'ml.t2.medium',\\n\",\n    \"        'InitialVariantWeight':1,\\n\",\n    \"        'InitialInstanceCount':1,\\n\",\n    \"        'ModelName':model_name,\\n\",\n    \"        'VariantName':'AllTraffic'}])\\n\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"#Deploy endpoint\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"endpoint_name = 'Test-endpoint-' + strftime(\\\"%Y-%m-%d-%H-%M-%S\\\", gmtime())\\n\",\n    \"print(\\\"EndpointName={}\\\".format(endpoint_name))\\n\",\n    \"\\n\",\n    \"create_endpoint_response = sm_client.create_endpoint(\\n\",\n    \"    EndpointName=endpoint_name,\\n\",\n    \"    EndpointConfigName=endpoint_config_name)\\n\",\n    \"print(create_endpoint_response['EndpointArn'])\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"sm_client.describe_endpoint(EndpointName=endpoint_name)\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"def wait_for_response(client, endpoint_name, poll_interval=30):\\n\",\n    \"    ### Wait until the job finishes\\n\",\n    \"    status = 'Creating'\\n\",\n    \"    while(status == 'Creating'):\\n\",\n    \"        response = client.describe_endpoint(EndpointName=endpoint_name)\\n\",\n    \"        status = response['EndpointStatus']\\n\",\n    \"        print('Creating job is still in status: {} ...'.format(status))\\n\",\n    \"        if status == 'Failed':\\n\",\n    \"            message = response['FailureReason']\\n\",\n    \"            logging.info('Endpoint Creation failed with the following error: {}'.format(message))\\n\",\n    \"            print('Endpoint failed with the following error: {}'.format(message))\\n\",\n    \"            raise Exception('Creating Endpoint failed')\\n\",\n    \"        logging.info(\\\"Creating job is still in status: \\\" + status)\\n\",\n    \"        time.sleep(poll_interval)\\n\",\n    \"\\n\",\n    \"    if status == 'InService':\\n\",\n    \"        logging.info(\\\"Creating job ended with status: \\\" + status)\\n\",\n    \"        print('Creating job ended with status: {}'.format(status))\\n\",\n    \"    else:\\n\",\n    \"        raise Exception('Creating job stopped')\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"wait_for_response(sm_client, endpoint_name, poll_interval=30)\"\n   ]\n  },\n  {\n   \"attachments\": {},\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Invoke Endpoint\"\n   ]\n  },\n  {\n   \"attachments\": {},\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"Invoke the endpoint to make predictions.\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"test_data=pd.read_csv('test.csv',header=None)\\n\",\n    \"testdata1=test_data.iloc[0:1,1:]\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"runtime = boto3.client(\\\"sagemaker-runtime\\\")\\n\",\n    \"Endpoint_name=endpoint_name\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"%time\\n\",\n    \"# csv serialization\\n\",\n    \"\\n\",\n    \"prediction = runtime.invoke_endpoint(\\n\",\n    \"    EndpointName=Endpoint_name,\\n\",\n    \"    Body=testdata1.to_csv(header=False, index=False).encode(\\\"utf-8\\\"),\\n\",\n    \"    ContentType=\\\"text/csv\\\",\\n\",\n    \"    Accept= \\\"text/csv\\\",\\n\",\n    \")\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"print(prediction[\\\"Body\\\"].read())\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 11,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"b'0.18987475335597992,0.9903860092163086,0.003180732252076268,0.010586234740912914,0.5162394046783447'\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"import pandas as pd\\n\",\n    \"import numpy as np\\n\",\n    \"import sagemaker\\n\",\n    \"import boto3\\n\",\n    \"from sagemaker import get_execution_role\\n\",\n    \"\\n\",\n    \"test_data=pd.read_csv('test.csv',header=None)\\n\",\n    \"testdata1=test_data.iloc[0:5,1:]\\n\",\n    \"\\n\",\n    \"runtime = boto3.client(\\\"sagemaker-runtime\\\")\\n\",\n    \"Endpoint_name= ''  #<your endpoint name> # update to your own endpoint name\\n\",\n    \"\\n\",\n    \"prediction = runtime.invoke_endpoint(\\n\",\n    \"    EndpointName=Endpoint_name,\\n\",\n    \"    Body=testdata1.to_csv(header=False, index=False).encode(\\\"utf-8\\\"),\\n\",\n    \"    ContentType=\\\"text/csv\\\",\\n\",\n    \"    Accept= \\\"text/csv\\\",\\n\",\n    \")\\n\",\n    \"\\n\",\n    \"print(prediction[\\\"Body\\\"].read())\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"instance_type\": \"ml.t3.medium\",\n  \"kernelspec\": {\n   \"display_name\": \"Python 3.9.13 64-bit\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.9.10\"\n  },\n  \"vscode\": {\n   \"interpreter\": {\n    \"hash\": \"aee8b7b246df8f9039afb4144a1f6fd8d2ca17a180786b69acc140d282b71a49\"\n   }\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 4\n}\n"
  },
  {
    "path": "samples/mlops-sagemaker-github-codepipeline-codebuild-codedeploy/Notebooks/SageMaker_Customer_Churn_XGB_end2end.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"attachments\": {},\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## SageMaker Model Building and Deployment \"\n   ]\n  },\n  {\n   \"attachments\": {},\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"\\n\",\n    \"In this notebook we show how to use Amazon SageMaker to develop, train, tune and deploy a XGBoost model. Sythetic customer churn data is used. \\n\",\n    \"\\n\",\n    \"The data is in AWS public S3 bucket: s3://sagemaker-sample-files/datasets/tabular/synthetic/churn.txt\\n\",\n    \"\\n\",\n    \"Sklearn Processor is used to process the raw data.\\n\",\n    \"\\n\",\n    \"* XGBoost https://sagemaker.readthedocs.io/en/stable/frameworks/xgboost/using_xgboost.html?highlight=xgboost\\n\",\n    \"* Doc https://sagemaker.readthedocs.io/en/stable/using_sklearn.html\\n\",\n    \"* SDK https://sagemaker.readthedocs.io/en/stable/sagemaker.sklearn.html\\n\",\n    \"* boto3 https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/sagemaker.html#client\\n\",\n    \" \\n\",\n    \"**This sample is provided for demonstration purposes, make sure to conduct appropriate testing if derivating this code for your own use-cases!**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"%matplotlib inline\\n\",\n    \"import os\\n\",\n    \"import time\\n\",\n    \"import logging\\n\",\n    \"import pandas as pd\\n\",\n    \"import numpy as np\\n\",\n    \"import sagemaker\\n\",\n    \"import json\\n\",\n    \"import boto3\\n\",\n    \"from sagemaker import get_execution_role\\n\",\n    \"\\n\",\n    \"sm_client = boto3.client('sagemaker')\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stderr\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"\\n\",\n      \"An error occurred (EntityAlreadyExists) when calling the CreateRole operation: Role with name Sagemaker-custom-role already exists.\\n\"\n     ]\n    },\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"{\\n\",\n      \"    \\\"AttachedPolicies\\\": [\\n\",\n      \"        {\\n\",\n      \"            \\\"PolicyName\\\": \\\"AmazonSageMakerFullAccess\\\",\\n\",\n      \"            \\\"PolicyArn\\\": \\\"arn:aws:iam::aws:policy/AmazonSageMakerFullAccess\\\"\\n\",\n      \"        }\\n\",\n      \"    ]\\n\",\n      \"}\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"# create Sagemaker Full Access Assume Role, https://repost.aws/knowledge-center/iam-assume-role-cli\\n\",\n    \"!aws iam create-role --role-name Sagemaker-custom-role --assume-role-policy-document file://assume-role.json\\n\",\n    \"!aws iam attach-role-policy --role-name Sagemaker-custom-role --policy-arn \\\"arn:aws:iam::aws:policy/AmazonSageMakerFullAccess\\\"\\n\",\n    \"!aws iam list-attached-role-policies --role-name Sagemaker-custom-role\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# Retrieve the bucket\\n\",\n    \"sagemaker_session = sagemaker.Session()\\n\",\n    \"bucket = sagemaker_session.default_bucket()  # this could also be a hard-coded bucket name\\n\",\n    \"region = sagemaker_session.boto_region_name\\n\",\n    \"print(region)\\n\",\n    \"\\n\",\n    \"try:\\n\",\n    \"    role = sagemaker.get_execution_role()\\n\",\n    \"except ValueError:\\n\",\n    \"    iam = boto3.client('iam')\\n\",\n    \"    role = iam.get_role(RoleName='Sagemaker-custom-role')['Role']['Arn']\\n\",\n    \"print(role)\\n\",\n    \"\\n\",\n    \"project_name = \\\"test_pro\\\"\\n\",\n    \"project_id = \\\"test_id\\\"\\n\",\n    \"print(f\\\"sagemaker role arn <{role}>\\\")\\n\",\n    \"\\n\",\n    \"assert(len(project_name) <= 15 ) # the project name should not have more than 15 chars\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"print(bucket)\"\n   ]\n  },\n  {\n   \"attachments\": {},\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Load Raw Data to S3\"\n   ]\n  },\n  {\n   \"attachments\": {},\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"Load raw data from the public S3 bucket to your own S3 bucket.\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"!aws s3 cp s3://sagemaker-sample-files/datasets/tabular/synthetic/churn.txt s3://{bucket}/sagemaker/DEMO-xgboost-churn/data/RawData.csv \"\n   ]\n  },\n  {\n   \"attachments\": {},\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Prepare script to process raw data\"\n   ]\n  },\n  {\n   \"attachments\": {},\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"Create preprocessing script. This script will be used by SageMaker process job instance to preocess raw data.\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 6,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting preprocess.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile preprocess.py\\n\",\n    \"\\n\",\n    \"\\\"\\\"\\\"Preprocess the customer churn dataset.\\\"\\\"\\\"\\n\",\n    \"\\n\",\n    \"import argparse\\n\",\n    \"import logging\\n\",\n    \"import pathlib\\n\",\n    \"\\n\",\n    \"import boto3\\n\",\n    \"import numpy as np\\n\",\n    \"import pandas as pd\\n\",\n    \"\\n\",\n    \"logger = logging.getLogger()\\n\",\n    \"logger.setLevel(logging.INFO)\\n\",\n    \"logger.addHandler(logging.StreamHandler())\\n\",\n    \"\\n\",\n    \"if __name__ == \\\"__main__\\\":\\n\",\n    \"    logger.info(\\\"Starting preprocessing.\\\")\\n\",\n    \"    parser = argparse.ArgumentParser()\\n\",\n    \"    parser.add_argument(\\\"--input-data\\\", type=str, required=True)\\n\",\n    \"    args = parser.parse_args()\\n\",\n    \"\\n\",\n    \"    base_dir = \\\"/opt/ml/processing\\\"\\n\",\n    \"    pathlib.Path(f\\\"{base_dir}/data\\\").mkdir(parents=True, exist_ok=True)\\n\",\n    \"    input_data = args.input_data\\n\",\n    \"    print(input_data)\\n\",\n    \"    bucket = input_data.split(\\\"/\\\")[2]\\n\",\n    \"    key = \\\"/\\\".join(input_data.split(\\\"/\\\")[3:])\\n\",\n    \"\\n\",\n    \"    logger.info(\\\"Downloading data from bucket: %s, key: %s\\\", bucket, key)\\n\",\n    \"    fn = f\\\"{base_dir}/data/raw-data.csv\\\"\\n\",\n    \"    s3 = boto3.resource(\\\"s3\\\")\\n\",\n    \"    s3.Bucket(bucket).download_file(key, fn)\\n\",\n    \"\\n\",\n    \"    logger.info(\\\"Reading downloaded data.\\\")\\n\",\n    \"\\n\",\n    \"    # read in csv\\n\",\n    \"    df = pd.read_csv(fn)\\n\",\n    \"\\n\",\n    \"    # drop the \\\"Phone\\\" feature column\\n\",\n    \"    df = df.drop([\\\"Phone\\\"], axis=1)\\n\",\n    \"\\n\",\n    \"    # Change the data type of \\\"Area Code\\\"\\n\",\n    \"    df[\\\"Area Code\\\"] = df[\\\"Area Code\\\"].astype(object)\\n\",\n    \"\\n\",\n    \"    # Drop several other columns\\n\",\n    \"    df = df.drop([\\\"Day Charge\\\", \\\"Eve Charge\\\", \\\"Night Charge\\\", \\\"Intl Charge\\\"], axis=1)\\n\",\n    \"\\n\",\n    \"    # Convert categorical variables into dummy/indicator variables.\\n\",\n    \"    model_data = pd.get_dummies(df)\\n\",\n    \"\\n\",\n    \"    # Create one binary classification target column\\n\",\n    \"    model_data = pd.concat(\\n\",\n    \"        [\\n\",\n    \"            model_data[\\\"Churn?_True.\\\"],\\n\",\n    \"            model_data.drop([\\\"Churn?_False.\\\", \\\"Churn?_True.\\\"], axis=1),\\n\",\n    \"        ],\\n\",\n    \"        axis=1,\\n\",\n    \"    )\\n\",\n    \"\\n\",\n    \"    # Split the data\\n\",\n    \"    train_data, validation_data, test_data = np.split(\\n\",\n    \"        model_data.sample(frac=1, random_state=1729),\\n\",\n    \"        [int(0.7 * len(model_data)), int(0.9 * len(model_data))],\\n\",\n    \"    )\\n\",\n    \"\\n\",\n    \"    pd.DataFrame(train_data).to_csv(\\n\",\n    \"        f\\\"{base_dir}/train/train.csv\\\", header=False, index=False\\n\",\n    \"    )\\n\",\n    \"    pd.DataFrame(validation_data).to_csv(\\n\",\n    \"        f\\\"{base_dir}/validation/validation.csv\\\", header=False, index=False\\n\",\n    \"    )\\n\",\n    \"    pd.DataFrame(test_data).to_csv(\\n\",\n    \"        f\\\"{base_dir}/test/test.csv\\\", header=False, index=False\\n\",\n    \"    )\\n\"\n   ]\n  },\n  {\n   \"attachments\": {},\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Prepare data for model training\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 7,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"from sagemaker.workflow.parameters import ParameterInteger, ParameterString\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 8,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"processing_instance_count = ParameterInteger(name=\\\"ProcessingInstanceCount\\\", default_value=1)\\n\",\n    \"processing_instance_type = ParameterString(\\n\",\n    \"        name=\\\"ProcessingInstanceType\\\", default_value=\\\"ml.m5.xlarge\\\"\\n\",\n    \"    )\\n\",\n    \"\\n\",\n    \"training_instance_type = ParameterString(\\n\",\n    \"        name=\\\"TrainingInstanceType\\\", default_value=\\\"ml.m5.xlarge\\\"\\n\",\n    \"    )\\n\",\n    \"\\n\",\n    \"model_approval_status = ParameterString(\\n\",\n    \"        name=\\\"ModelApprovalStatus\\\",\\n\",\n    \"        default_value=\\\"Approved\\\",  # ModelApprovalStatus can be set to a default of \\\"Approved\\\" if you don't want manual approval.\\n\",\n    \"    )\\n\",\n    \"\\n\",\n    \"input_data = ParameterString(\\n\",\n    \"        name=\\\"InputDataUrl\\\",\\n\",\n    \"        default_value=f\\\"s3://{sagemaker_session.default_bucket()}/sagemaker/DEMO-xgboost-churn/data/RawData.csv\\\",  # Change this to point to the s3 location of your raw input data.\\n\",\n    \"    )\"\n   ]\n  },\n  {\n   \"attachments\": {},\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"SageMaker Process instance with sklearn image is used to process raw data.\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 9,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"from sagemaker.sklearn.processing import SKLearnProcessor\\n\",\n    \"\\n\",\n    \"sklearn_processor = SKLearnProcessor(\\n\",\n    \"    framework_version=\\\"0.23-1\\\",\\n\",\n    \"    role=role,\\n\",\n    \"    instance_type= \\\"ml.m5.xlarge\\\", #\\\"local\\\", \\n\",\n    \"    instance_count= 1, \\n\",\n    \"    sagemaker_session=sagemaker_session\\n\",\n    \")\\n\"\n   ]\n  },\n  {\n   \"attachments\": {},\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"Processed data is saved back to S3 bucket.\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"from sagemaker.processing import ProcessingInput, ProcessingOutput\\n\",\n    \"\\n\",\n    \"input_data=f\\\"s3://{sagemaker_session.default_bucket()}/sagemaker/DEMO-xgboost-churn/data/RawData.csv\\\"\\n\",\n    \"\\n\",\n    \"sklearn_processor.run(\\n\",\n    \"    code=\\\"preprocess.py\\\", \\n\",\n    \"    inputs=[\\n\",\n    \"         ProcessingInput(source=f\\\"s3://{sagemaker_session.default_bucket()}/sagemaker/DEMO-xgboost-churn/data/RawData.csv\\\", destination=\\\"/opt/ml/processing/input\\\"),\\n\",\n    \"    ], \\n\",\n    \"    outputs=[\\n\",\n    \"        ProcessingOutput(output_name=\\\"train\\\", source=\\\"/opt/ml/processing/train\\\"),\\n\",\n    \"        ProcessingOutput(output_name=\\\"validation\\\", source=\\\"/opt/ml/processing/validation\\\"),\\n\",\n    \"        ProcessingOutput(output_name=\\\"test\\\", source=\\\"/opt/ml/processing/test\\\"),\\n\",\n    \"    ],\\n\",\n    \"    arguments=[\\\"--input-data\\\", input_data],\\n\",\n    \")\\n\",\n    \"\\n\",\n    \"preprocessing_job_description = sklearn_processor.jobs[-1].describe()\"\n   ]\n  },\n  {\n   \"attachments\": {},\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Model Training\"\n   ]\n  },\n  {\n   \"attachments\": {},\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"Get training and validation data paths.\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 11,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"s3_input_train=preprocessing_job_description['ProcessingOutputConfig']['Outputs'][0]['S3Output']['S3Uri']\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 12,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"s3_input_validation=preprocessing_job_description['ProcessingOutputConfig']['Outputs'][1]['S3Output']['S3Uri']\"\n   ]\n  },\n  {\n   \"attachments\": {},\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"Define XGBoost model\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 13,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"from sagemaker.inputs import TrainingInput\\n\",\n    \"\\n\",\n    \"content_type = \\\"csv\\\"\\n\",\n    \"train_input = TrainingInput(s3_input_train, content_type=content_type)\\n\",\n    \"validation_input = TrainingInput(s3_input_validation, content_type=content_type)\\n\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 14,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"import sagemaker\\n\",\n    \"from sagemaker.serializers import CSVSerializer\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 15,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"prefix = 'sagemaker/xgboost_cutomer_churn'\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 16,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stderr\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"INFO:sagemaker.image_uris:Ignoring unnecessary instance type: None.\\n\"\n     ]\n    },\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"683313688378.dkr.ecr.us-east-1.amazonaws.com/sagemaker-xgboost:1.2-1\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"container=sagemaker.image_uris.retrieve(\\\"xgboost\\\", region, \\\"1.2-1\\\")\\n\",\n    \"print(container)\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 17,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# initialize hyperparameters\\n\",\n    \"hyperparameters = {\\n\",\n    \"        \\\"max_depth\\\":\\\"5\\\",\\n\",\n    \"        \\\"eta\\\":\\\"0.2\\\",\\n\",\n    \"        \\\"gamma\\\":\\\"4\\\",\\n\",\n    \"        \\\"min_child_weight\\\":\\\"6\\\",\\n\",\n    \"        \\\"subsample\\\":\\\"0.7\\\",\\n\",\n    \"        \\\"objective\\\":\\\"binary:logistic\\\",\\n\",\n    \"        \\\"num_round\\\":\\\"50\\\"}\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 18,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"xgb = sagemaker.estimator.Estimator(container,\\n\",\n    \"                                    role, \\n\",\n    \"                                    instance_count=1, \\n\",\n    \"                                    instance_type='ml.m4.xlarge',\\n\",\n    \"                                    hyperparameters=hyperparameters,\\n\",\n    \"                                    output_path='s3://{}/{}/output'.format(bucket, prefix),\\n\",\n    \"                                    sagemaker_session=sagemaker_session)\"\n   ]\n  },\n  {\n   \"attachments\": {},\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"Train the XGboost model\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 19,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stderr\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"INFO:sagemaker:Creating training-job with name: sagemaker-xgboost-2023-06-20-11-47-20-805\\n\"\n     ]\n    },\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"2023-06-20 11:47:21 Starting - Starting the training job...\\n\",\n      \"2023-06-20 11:47:46 Starting - Preparing the instances for training......\\n\",\n      \"2023-06-20 11:48:53 Downloading - Downloading input data...\\n\",\n      \"2023-06-20 11:49:23 Training - Downloading the training image......\\n\",\n      \"2023-06-20 11:50:13 Training - Training image download completed. Training in progress..[2023-06-20 11:50:30.215 ip-10-2-118-242.ec2.internal:7 INFO utils.py:27] RULE_JOB_STOP_SIGNAL_FILENAME: None\\n\",\n      \"INFO:sagemaker-containers:Imported framework sagemaker_xgboost_container.training\\n\",\n      \"INFO:sagemaker-containers:Failed to parse hyperparameter objective value binary:logistic to Json.\\n\",\n      \"Returning the value itself\\n\",\n      \"INFO:sagemaker-containers:No GPUs detected (normal if no gpus installed)\\n\",\n      \"INFO:sagemaker_xgboost_container.training:Running XGBoost Sagemaker in algorithm mode\\n\",\n      \"INFO:root:Determined delimiter of CSV input is ','\\n\",\n      \"INFO:root:Determined delimiter of CSV input is ','\\n\",\n      \"INFO:root:Determined delimiter of CSV input is ','\\n\",\n      \"INFO:root:Determined delimiter of CSV input is ','\\n\",\n      \"INFO:root:Single node training.\\n\",\n      \"[2023-06-20 11:50:30.332 ip-10-2-118-242.ec2.internal:7 INFO json_config.py:91] Creating hook from json_config at /opt/ml/input/config/debughookconfig.json.\\n\",\n      \"[2023-06-20 11:50:30.333 ip-10-2-118-242.ec2.internal:7 INFO hook.py:199] tensorboard_dir has not been set for the hook. SMDebug will not be exporting tensorboard summaries.\\n\",\n      \"[2023-06-20 11:50:30.333 ip-10-2-118-242.ec2.internal:7 INFO profiler_config_parser.py:102] User has disabled profiler.\\n\",\n      \"[2023-06-20 11:50:30.334 ip-10-2-118-242.ec2.internal:7 INFO hook.py:253] Saving to /opt/ml/output/tensors\\n\",\n      \"[2023-06-20 11:50:30.334 ip-10-2-118-242.ec2.internal:7 INFO state_store.py:77] The checkpoint config file /opt/ml/input/config/checkpointconfig.json does not exist.\\n\",\n      \"INFO:root:Debug hook created from config\\n\",\n      \"INFO:root:Train matrix has 3500 rows and 99 columns\\n\",\n      \"INFO:root:Validation matrix has 1000 rows\\n\",\n      \"[0]#011train-error:0.12486#011validation-error:0.13200\\n\",\n      \"[2023-06-20 11:50:30.348 ip-10-2-118-242.ec2.internal:7 INFO hook.py:413] Monitoring the collections: metrics\\n\",\n      \"[2023-06-20 11:50:30.351 ip-10-2-118-242.ec2.internal:7 INFO hook.py:476] Hook is writing from the hook with pid: 7\\n\",\n      \"[1]#011train-error:0.10200#011validation-error:0.10700\\n\",\n      \"[2]#011train-error:0.08971#011validation-error:0.09900\\n\",\n      \"[3]#011train-error:0.09257#011validation-error:0.09900\\n\",\n      \"[4]#011train-error:0.09257#011validation-error:0.09600\\n\",\n      \"[5]#011train-error:0.08971#011validation-error:0.09100\\n\",\n      \"[6]#011train-error:0.08514#011validation-error:0.08700\\n\",\n      \"[7]#011train-error:0.08171#011validation-error:0.08300\\n\",\n      \"[8]#011train-error:0.07686#011validation-error:0.08000\\n\",\n      \"[9]#011train-error:0.07486#011validation-error:0.08100\\n\",\n      \"[10]#011train-error:0.07257#011validation-error:0.07800\\n\",\n      \"[11]#011train-error:0.06943#011validation-error:0.07600\\n\",\n      \"[12]#011train-error:0.06914#011validation-error:0.07700\\n\",\n      \"[13]#011train-error:0.06971#011validation-error:0.07900\\n\",\n      \"[14]#011train-error:0.06629#011validation-error:0.08000\\n\",\n      \"[15]#011train-error:0.06514#011validation-error:0.07700\\n\",\n      \"[16]#011train-error:0.06571#011validation-error:0.07700\\n\",\n      \"[17]#011train-error:0.06429#011validation-error:0.07500\\n\",\n      \"[18]#011train-error:0.06371#011validation-error:0.07500\\n\",\n      \"[19]#011train-error:0.06429#011validation-error:0.07300\\n\",\n      \"[20]#011train-error:0.06400#011validation-error:0.07300\\n\",\n      \"[21]#011train-error:0.06400#011validation-error:0.07200\\n\",\n      \"[22]#011train-error:0.06400#011validation-error:0.07200\\n\",\n      \"[23]#011train-error:0.06371#011validation-error:0.07300\\n\",\n      \"[24]#011train-error:0.06257#011validation-error:0.07300\\n\",\n      \"[25]#011train-error:0.06086#011validation-error:0.07100\\n\",\n      \"[26]#011train-error:0.06086#011validation-error:0.07000\\n\",\n      \"[27]#011train-error:0.05914#011validation-error:0.06900\\n\",\n      \"[28]#011train-error:0.05771#011validation-error:0.06900\\n\",\n      \"[29]#011train-error:0.05771#011validation-error:0.06900\\n\",\n      \"[30]#011train-error:0.05743#011validation-error:0.06500\\n\",\n      \"[31]#011train-error:0.05543#011validation-error:0.06700\\n\",\n      \"[32]#011train-error:0.05600#011validation-error:0.06800\\n\",\n      \"[33]#011train-error:0.05400#011validation-error:0.07000\\n\",\n      \"[34]#011train-error:0.05343#011validation-error:0.06700\\n\",\n      \"[35]#011train-error:0.05314#011validation-error:0.07100\\n\",\n      \"[36]#011train-error:0.05286#011validation-error:0.07100\\n\",\n      \"[37]#011train-error:0.05286#011validation-error:0.07200\\n\",\n      \"[38]#011train-error:0.05257#011validation-error:0.07000\\n\",\n      \"[39]#011train-error:0.05343#011validation-error:0.06800\\n\",\n      \"[40]#011train-error:0.05257#011validation-error:0.06800\\n\",\n      \"[41]#011train-error:0.05286#011validation-error:0.06900\\n\",\n      \"[42]#011train-error:0.05143#011validation-error:0.06800\\n\",\n      \"[43]#011train-error:0.05029#011validation-error:0.06700\\n\",\n      \"[44]#011train-error:0.05029#011validation-error:0.06700\\n\",\n      \"[45]#011train-error:0.04914#011validation-error:0.06700\\n\",\n      \"[46]#011train-error:0.04914#011validation-error:0.06700\\n\",\n      \"[47]#011train-error:0.04943#011validation-error:0.06800\\n\",\n      \"[48]#011train-error:0.04971#011validation-error:0.06800\\n\",\n      \"[49]#011train-error:0.04886#011validation-error:0.06800\\n\",\n      \"\\n\",\n      \"2023-06-20 11:50:50 Uploading - Uploading generated training model\\n\",\n      \"2023-06-20 11:50:50 Completed - Training job completed\\n\",\n      \"Training seconds: 117\\n\",\n      \"Billable seconds: 117\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"xgb.fit({'train': train_input, 'validation': validation_input})\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 20,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"sm_boto3 = boto3.client(\\\"sagemaker\\\")\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"artifact = sm_boto3.describe_training_job(\\n\",\n    \"    TrainingJobName=xgb.latest_training_job.name\\n\",\n    \")[\\\"ModelArtifacts\\\"][\\\"S3ModelArtifacts\\\"]\\n\",\n    \"\\n\",\n    \"print(\\\"Model artifact persisted at \\\" + artifact)\"\n   ]\n  },\n  {\n   \"attachments\": {},\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Create Endpoint\"\n   ]\n  },\n  {\n   \"attachments\": {},\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"Create an endpoint using SageMaker SDK\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 22,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stderr\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"INFO:sagemaker:Creating model with name: sagemaker-xgboost-2023-06-20-12-03-03-421\\n\",\n      \"INFO:sagemaker:Creating endpoint-config with name sagemaker-xgboost-2023-06-20-12-03-03-421\\n\",\n      \"INFO:sagemaker:Creating endpoint with name sagemaker-xgboost-2023-06-20-12-03-03-421\\n\"\n     ]\n    },\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"-----------!\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"xgb_predictor = xgb.deploy(\\n\",\n    \"initial_instance_count = 1,\\n\",\n    \"instance_type = 'ml.m4.xlarge',\\n\",\n    \"serializer = CSVSerializer())\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 23,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Endpoint name: sagemaker-xgboost-2023-06-20-12-03-03-421\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"print(f'Endpoint name: {xgb_predictor.endpoint_name}')\"\n   ]\n  },\n  {\n   \"attachments\": {},\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Invoke Endpoint\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 24,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"data\": {\n      \"text/plain\": [\n       \"array([ 21.        ,   0.        ,   0.84385859,   3.        ,\\n\",\n       \"         1.34772502,   0.        ,   4.74977594, 350.        ,\\n\",\n       \"         4.38414605,   8.        ,   7.        ,   0.        ,\\n\",\n       \"         0.        ,   0.        ,   0.        ,   0.        ,\\n\",\n       \"         0.        ,   0.        ,   0.        ,   0.        ,\\n\",\n       \"         0.        ,   0.        ,   0.        ,   0.        ,\\n\",\n       \"         0.        ,   0.        ,   0.        ,   0.        ,\\n\",\n       \"         0.        ,   0.        ,   0.        ,   0.        ,\\n\",\n       \"         0.        ,   0.        ,   1.        ,   0.        ,\\n\",\n       \"         0.        ,   0.        ,   0.        ,   0.        ,\\n\",\n       \"         0.        ,   0.        ,   0.        ,   0.        ,\\n\",\n       \"         0.        ,   0.        ,   0.        ,   0.        ,\\n\",\n       \"         0.        ,   0.        ,   0.        ,   0.        ,\\n\",\n       \"         0.        ,   0.        ,   0.        ,   0.        ,\\n\",\n       \"         0.        ,   0.        ,   0.        ,   0.        ,\\n\",\n       \"         0.        ,   0.        ,   0.        ,   0.        ,\\n\",\n       \"         0.        ,   0.        ,   0.        ,   0.        ,\\n\",\n       \"         0.        ,   0.        ,   0.        ,   0.        ,\\n\",\n       \"         0.        ,   0.        ,   0.        ,   0.        ,\\n\",\n       \"         0.        ,   1.        ,   0.        ,   0.        ,\\n\",\n       \"         0.        ,   0.        ,   0.        ,   0.        ,\\n\",\n       \"         0.        ,   0.        ,   0.        ,   0.        ,\\n\",\n       \"         0.        ,   0.        ,   0.        ,   0.        ,\\n\",\n       \"         0.        ,   0.        ,   0.        ,   1.        ,\\n\",\n       \"         0.        ,   1.        ,   0.        ])\"\n      ]\n     },\n     \"execution_count\": 24,\n     \"metadata\": {},\n     \"output_type\": \"execute_result\"\n    }\n   ],\n   \"source\": [\n    \"test_data=pd.read_csv('test.csv',header=None)\\n\",\n    \"test_data.to_numpy()[2,1:]\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"def predict(data, rows=500):\\n\",\n    \"    split_array = np.array_split(data, int(data.shape[0] / float(rows) + 1))\\n\",\n    \"    predictions = ''\\n\",\n    \"    for array in split_array:\\n\",\n    \"        predictions = ','.join([predictions, xgb_predictor.predict(array).decode('utf-8')])\\n\",\n    \"\\n\",\n    \"    return np.fromstring(predictions[1:], sep=',')\\n\",\n    \"\\n\",\n    \"predictions = predict(test_data.to_numpy()[:1,1:])  #test_data.to_numpy()[2,1:]\\n\",\n    \"predictions\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# Another way of invoking ML Endpoint model\\n\",\n    \"import pandas as pd\\n\",\n    \"import numpy as np\\n\",\n    \"import sagemaker\\n\",\n    \"import boto3\\n\",\n    \"from sagemaker import get_execution_role\\n\",\n    \"\\n\",\n    \"test_data=pd.read_csv('test.csv',header=None)\\n\",\n    \"testdata1=test_data.iloc[0:1,1:]\\n\",\n    \"\\n\",\n    \"runtime = boto3.client(\\\"sagemaker-runtime\\\")\\n\",\n    \"Endpoint_name='' #<your endpoint name> # update to your own endpoint name\\n\",\n    \"\\n\",\n    \"prediction = runtime.invoke_endpoint(\\n\",\n    \"    EndpointName=Endpoint_name,\\n\",\n    \"    Body=testdata1.to_csv(header=False, index=False).encode(\\\"utf-8\\\"),\\n\",\n    \"    ContentType=\\\"text/csv\\\",\\n\",\n    \"    Accept= \\\"text/csv\\\",\\n\",\n    \")\\n\",\n    \"\\n\",\n    \"print(prediction[\\\"Body\\\"].read())\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"instance_type\": \"ml.t3.medium\",\n  \"kernelspec\": {\n   \"display_name\": \"Python 3.9.13 64-bit\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.9.10\"\n  },\n  \"vscode\": {\n   \"interpreter\": {\n    \"hash\": \"aee8b7b246df8f9039afb4144a1f6fd8d2ca17a180786b69acc140d282b71a49\"\n   }\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 4\n}\n"
  },
  {
    "path": "samples/mlops-sagemaker-github-codepipeline-codebuild-codedeploy/Notebooks/assume-role.json",
    "content": "{\r\n    \"Version\": \"2012-10-17\",\r\n    \"Statement\": {\r\n      \"Effect\": \"Allow\",\r\n      \"Principal\": {\r\n        \"Service\": \"sagemaker.amazonaws.com\"\r\n      },\r\n      \"Action\": \"sts:AssumeRole\"\r\n    }\r\n  }"
  },
  {
    "path": "samples/mlops-sagemaker-github-codepipeline-codebuild-codedeploy/Notebooks/preprocess.py",
    "content": "\r\n\"\"\"Preprocess the customer churn dataset.\"\"\"\r\n\r\nimport argparse\r\nimport logging\r\nimport pathlib\r\n\r\nimport boto3\r\nimport numpy as np\r\nimport pandas as pd\r\n\r\nlogger = logging.getLogger()\r\nlogger.setLevel(logging.INFO)\r\nlogger.addHandler(logging.StreamHandler())\r\n\r\nif __name__ == \"__main__\":\r\n    logger.info(\"Starting preprocessing.\")\r\n    parser = argparse.ArgumentParser()\r\n    parser.add_argument(\"--input-data\", type=str, required=True)\r\n    args = parser.parse_args()\r\n\r\n    base_dir = \"/opt/ml/processing\"\r\n    pathlib.Path(f\"{base_dir}/data\").mkdir(parents=True, exist_ok=True)\r\n    input_data = args.input_data\r\n    print(input_data)\r\n    bucket = input_data.split(\"/\")[2]\r\n    key = \"/\".join(input_data.split(\"/\")[3:])\r\n\r\n    logger.info(\"Downloading data from bucket: %s, key: %s\", bucket, key)\r\n    fn = f\"{base_dir}/data/raw-data.csv\"\r\n    s3 = boto3.resource(\"s3\")\r\n    s3.Bucket(bucket).download_file(key, fn)\r\n\r\n    logger.info(\"Reading downloaded data.\")\r\n\r\n    # read in csv\r\n    df = pd.read_csv(fn)\r\n\r\n    # drop the \"Phone\" feature column\r\n    df = df.drop([\"Phone\"], axis=1)\r\n\r\n    # Change the data type of \"Area Code\"\r\n    df[\"Area Code\"] = df[\"Area Code\"].astype(object)\r\n\r\n    # Drop several other columns\r\n    df = df.drop([\"Day Charge\", \"Eve Charge\", \"Night Charge\", \"Intl Charge\"], axis=1)\r\n\r\n    # Convert categorical variables into dummy/indicator variables.\r\n    model_data = pd.get_dummies(df)\r\n\r\n    # Create one binary classification target column\r\n    model_data = pd.concat(\r\n        [\r\n            model_data[\"Churn?_True.\"],\r\n            model_data.drop([\"Churn?_False.\", \"Churn?_True.\"], axis=1),\r\n        ],\r\n        axis=1,\r\n    )\r\n\r\n    # Split the data\r\n    train_data, validation_data, test_data = np.split(\r\n        model_data.sample(frac=1, random_state=1729),\r\n        [int(0.7 * len(model_data)), int(0.9 * len(model_data))],\r\n    )\r\n\r\n    pd.DataFrame(train_data).to_csv(\r\n        f\"{base_dir}/train/train.csv\", header=False, index=False\r\n    )\r\n    pd.DataFrame(validation_data).to_csv(\r\n        f\"{base_dir}/validation/validation.csv\", header=False, index=False\r\n    )\r\n    pd.DataFrame(test_data).to_csv(\r\n        f\"{base_dir}/test/test.csv\", header=False, index=False\r\n    )\r\n"
  },
  {
    "path": "samples/mlops-sagemaker-github-codepipeline-codebuild-codedeploy/Notebooks/test.csv",
    "content": "0,62,0,5.072152061281491,5,6.600411338234018,2,3.5335010789441563,300,4.3952998987652565,7,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,1,0\n1,5,0,12.524227291335833,2,5.639471129269478,5,4.937219265876419,150,5.881787271425925,5,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n0,21,0,0.8438585898741922,3,1.3477250198014177,0,4.749775942599953,350,4.384146052764612,8,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n0,140,0,1.5811272910168768,8,7.3775905213788375,7,0.9399315726440474,300,6.9385711004493835,2,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,1,0\n1,101,400,5.234842890778278,1,2.7653548502051604,0,3.273098301114429,150,2.272057243256864,5,9,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n1,191,100,13.261102943769288,4,7.5674336500916075,4,4.305871058339482,150,4.768465663991106,4,3,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n1,107,300,10.797385169320467,5,6.9036193200866345,3,5.873994160867474,50,4.367043721283685,6,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n1,61,0,3.1719593708600997,5,7.192612132482753,1,2.1608903709588896,300,4.1725829829553325,6,10,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n1,5,400,7.926101580060937,4,4.19841302997281,0,4.285823889017822,0,4.125243927916747,6,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n1,165,0,13.10751352294834,3,7.128330808041529,1,3.747842976185972,150,4.3366879448093565,5,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n1,145,0,5.412983516279031,4,5.451053001131731,2,4.345574208183886,150,4.436816058258618,6,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n0,6,800,4.644654672912286,4,4.976604355618264,1,3.904821995610174,300,6.5209533901819325,7,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n0,43,1000,2.4022389683615955,2,7.167245410036478,5,3.514748674657301,400,3.8790466129275685,7,3,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n1,91,200,3.5172870115881976,3,7.716675314653963,4,4.399084344077369,300,7.069764416625022,4,9,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n1,58,200,13.993779163308034,1,7.4884614188499645,0,4.678051392172893,100,5.168536721709961,7,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n1,83,0,10.97330933640862,5,6.715210074686393,5,4.445928260891968,50,3.3325412623157336,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n1,190,0,8.724732983848599,3,5.966910030336059,0,3.3335471666270413,150,5.063433052142923,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n0,88,0,5.750111730098722,0,6.2327747735663666,4,4.795221920336285,350,5.572824406489756,7,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n1,156,200,5.1702616975494005,4,6.592128328345924,5,3.615887758182837,250,6.551662013538478,6,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n1,197,0,6.2308892345889415,6,4.6954222766517315,4,4.266959766420346,100,5.927521209999223,5,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,1,0\n1,112,100,8.903061898626081,3,6.820250469491564,4,5.276664785860079,200,5.070820955481431,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n0,173,600,1.58906009281176,9,4.929693100462329,5,1.152582715882058,400,5.494604688571808,7,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n0,96,0,2.166957389777683,6,4.251841594388217,4,2.4090576869492044,250,5.292283549147358,1,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,1,0\n1,107,400,4.191367223514582,5,5.778070318580312,4,4.7119789127823335,200,3.690976993873412,4,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n1,109,600,6.073256457271514,5,5.9446484262614225,1,4.4847003525447455,100,4.384511529669742,6,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,1\n0,9,0,7.1930507838181565,6,6.812657528748512,3,5.1175606692131295,250,6.612280690303956,3,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n1,176,300,7.370589433750022,3,5.4953890624108865,0,2.7693563032703787,150,5.7444432413047775,5,7,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n0,191,500,3.26272884502842,5,3.333865180649779,3,0.1912923125392343,450,6.175005323578705,8,8,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n1,191,300,9.134363142233354,3,7.236420366122483,1,2.1594117583172263,200,6.107121818617013,4,5,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n0,171,400,1.9576360316901276,3,13.622096683112519,11,3.4000000594176942,350,5.293506869746435,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,1\n0,126,600,3.1386345622459477,3,5.458623067450995,8,7.247459567295912,350,6.07511890908642,6,3,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n0,34,800,1.0707922754713532,3,2.8400122919361963,0,3.753240530235272,250,5.254966045933761,5,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n1,72,0,5.6135577711716405,3,4.737083184184555,0,1.0293862977108752,200,3.659161262883,3,11,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n0,56,0,0.8335649817333309,6,3.023889496147825,9,6.277701042909107,400,4.236313499700168,5,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,1,0\n0,80,700,2.2152994338764835,3,2.8175945607662727,2,4.3685788345780034,250,6.53312520517945,5,5,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n0,144,0,0.6583152207945444,3,3.4244439503870936,7,3.9502602999030914,450,4.001984939824158,7,5,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n1,147,0,4.510065490323991,4,7.877171596310296,4,3.3786161033673454,300,5.95205237614821,6,7,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n0,48,0,5.993166566752341,3,7.47694598939632,0,4.724791324836182,300,5.379847958785653,5,6,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n1,192,0,8.95151123321183,5,5.666876397010085,10,4.833996263971553,150,5.8213075410374575,5,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,0\n1,142,0,6.8239545695522095,5,4.416190139225511,5,2.6686557540248184,150,2.2279503669012515,5,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n1,41,0,8.716702825690648,0,6.292468606501443,3,4.400542761094472,200,5.097634075063606,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n1,150,0,10.55670832656788,5,6.490773884048323,3,3.375279210541684,200,3.942929874901617,7,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n1,22,800,0.21991214610946666,6,3.5625771407323463,1,4.654536177169347,150,3.0000940404797194,6,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n1,8,400,6.245780645742607,2,8.082050430410893,1,1.9551033647754927,300,4.02962306200388,4,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,1\n0,4,0,3.638722868927605,7,5.130774493971593,7,1.6907936291012682,400,4.134665794243514,4,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,1,0\n1,133,0,6.392764083227192,3,5.477191555385828,7,4.607713062633139,200,4.882654730298678,7,7,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n0,54,0,0.4773054336010265,4,1.3779552075288404,4,2.4122496285096293,300,6.233604144638955,6,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n0,193,0,6.245705952341785,2,3.1701268330522434,0,6.170605431010399,150,6.9692906237589805,4,6,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n1,56,400,6.900851194117602,2,7.206169147583297,0,3.0703283587766688,250,4.990579029864615,5,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,1\n0,136,800,0.6593742708325729,3,3.678297127366572,0,2.944623747249629,350,2.902868829574311,8,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,1\n0,129,500,5.1743189948837385,4,0.24700439554894515,1,1.79685837743258,200,6.213403175893767,4,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n1,145,0,8.05388123748296,4,4.025921884452133,6,5.838149674650571,100,4.89829921947485,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n1,178,200,4.858360132120028,2,5.6401550102603055,4,4.0631868617759785,200,4.142877191538647,5,8,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n0,97,0,4.4782271246415934,5,6.182245808651588,3,2.5566850882793157,300,5.385089545881749,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,1,0\n0,68,0,10.788749464127914,2,4.2903886273526926,3,5.049848359503602,250,3.3947143976752105,9,13,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,1,0\n1,41,300,8.921947659672423,2,7.20746201697345,3,5.146790351163575,200,4.650730438144174,8,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n0,54,0,7.644363774543796,1,3.3168972770138048,1,5.358881263015425,150,5.661151728025391,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,1,0\n0,75,700,1.2687337723540173,3,2.5287478822678833,5,3.7735855781125625,450,2.245779327608127,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,1\n0,52,0,3.757761834701122,3,0.272629544428173,1,5.500355043050583,200,4.306713991581266,5,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,1,0\n0,117,0,2.9609540314750005,3,0.7183731900535184,6,6.795121741546263,100,4.197708240560753,5,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n0,170,900,5.347709418242579,1,5.840103942698557,0,4.571734133371468,300,6.4724968607295885,5,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n1,64,600,5.164436929276945,7,4.035108533328375,3,4.502057513677036,100,6.8305447077487065,6,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n1,63,0,6.2396484176790175,3,7.536391812678818,0,1.7592503757642397,300,5.3670672853144055,6,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n0,131,600,0.9875595653989784,6,6.175227962540504,0,2.2764653663263275,250,5.636307744132725,3,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,1\n0,51,0,7.1672973733552885,4,0.6566813836612706,6,1.3964756660620283,400,5.693333714125637,7,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n1,70,400,2.92249249189642,4,5.72778609146583,0,2.6987849453774144,150,3.7216081564883448,3,10,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n1,171,500,10.483478079156104,5,7.3405599007239255,0,4.10504118810189,100,5.952831195166314,6,4,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n0,167,0,3.113960464062869,1,0.6566159175951212,6,7.394805629244548,300,5.113610474102175,7,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n1,119,400,6.553884755812585,5,5.691525622220866,3,3.2243379426274865,150,4.553336031270004,8,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1\n1,37,400,6.866377585526288,5,4.434219915065822,2,2.9929196853652438,100,5.455255153877922,5,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,1\n1,168,0,8.360324980132965,4,5.5027395973683,0,4.6727181968521565,50,3.4270889211734814,6,2,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n1,121,400,6.842377948201992,5,4.878651944404614,3,5.854214767256348,50,4.799332204133772,7,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,1\n1,92,400,8.57172165154155,4,7.853096077363831,0,5.669361832473407,100,6.057799899034017,7,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n0,142,400,1.785026473540988,4,3.2688444191341364,4,2.5327780127273742,350,5.395348700614924,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n0,152,0,5.521783873536278,2,3.5886131302047053,0,3.8815291954256415,200,5.434408025663743,6,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,1,0\n0,174,500,2.1887716216230806,3,4.215586765357034,2,2.8765230549503027,300,4.4773835948048815,6,7,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n0,133,0,0.8513656521017126,1,3.084311708501469,0,3.8595466989126974,200,3.3401629353442037,5,6,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n1,28,600,10.173097510204084,3,3.580092068586684,1,5.737090885738459,50,2.9007136006517387,7,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n0,42,1000,6.832749017672322,3,4.692591349315839,2,5.3600918544594816,250,4.422123764220787,5,8,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n0,111,400,3.9654389422694236,4,4.8137197032979735,1,1.5988074095141631,300,4.344859533223321,5,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n0,38,500,3.5444788416742807,0,2.4689672038192905,1,6.74498761847515,100,5.614614204717064,4,5,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n1,82,700,2.331272605740953,7,4.491012696475102,3,5.62348099322925,150,5.325664633630066,5,7,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n0,92,400,1.9358009631669688,5,7.307724939015656,10,4.661041694068195,400,5.826937879210751,3,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n0,84,400,7.524442667667318,8,5.15245183950096,0,3.19640441046818,150,4.610251612076812,4,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,1\n1,79,100,3.5351298895519925,1,5.094098286789706,1,1.9471320531137384,250,6.2705967932862965,1,12,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n0,156,300,2.5179491282559603,2,3.7030962078182608,3,5.731945457775653,100,5.834670335351329,3,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n0,190,0,4.662284546738933,4,7.16056963637891,11,2.740543663702855,550,4.406507550581475,7,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n0,19,0,10.090807264044221,4,3.477445863375781,5,6.7970681899174705,200,5.41062277737135,7,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n0,154,0,5.644725973871345,3,1.0292777268751403,4,6.837087072652331,300,5.401068663449248,7,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,0\n0,108,0,2.453215979109556,3,1.6307207471629268,2,4.257160596108476,200,5.777424281338522,6,7,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n0,104,0,3.8285722209486313,5,5.915796553658232,5,3.702564429248035,400,5.43188549592684,7,5,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n0,37,0,1.0706075330280065,4,5.879947166640197,7,2.7190763262094717,300,4.805393185961638,6,4,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n0,99,600,4.237453299042395,2,2.482097486208458,5,6.028405204069117,400,4.805237911747788,7,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n0,170,0,1.60851276557735,5,6.525856772993443,6,5.221557072061891,400,4.3649224588076265,4,4,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n0,166,800,6.677695497580171,3,3.551554396302285,5,4.275957714482779,250,5.316108189703966,6,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,1\n0,163,0,1.1515280694580097,5,3.190118784026024,3,3.4657830800960125,350,2.947144128696129,5,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n1,130,0,3.6060481784173817,4,2.366844877726582,0,5.163225478279801,100,3.0836698758534644,5,7,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n1,127,400,7.526318546400898,3,2.8669976051386983,0,4.714480597588897,50,6.081809102028246,3,4,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n0,198,600,1.8164858821899443,4,2.790770062456788,3,3.114852435486136,150,5.845825762025638,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n1,24,0,8.865414865831484,2,9.364471484314397,1,3.449408024649772,350,4.37773213343382,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,1,0\n1,140,300,9.749438740516396,2,4.586405059700144,0,4.299905320387655,100,3.1637621363839745,4,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n0,137,0,6.825367809954172,1,2.3930011214151574,4,6.35095815887334,100,3.776455630617503,5,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n0,145,400,6.31502045182136,1,10.215112048769317,6,5.4416574514027225,250,5.058715311714279,4,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n0,194,400,0.4801116110106287,4,3.1083536614740437,3,2.9076099520473697,350,5.142910338581296,5,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,1\n0,35,0,3.9326962809471167,4,6.293803584051488,5,2.900464141275462,150,6.564485971249485,3,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,1,0\n1,138,0,4.324565707176873,1,4.770968090681833,5,4.77245703937839,250,5.762332876539076,3,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n1,52,300,6.731929327187362,1,3.5477926021894834,2,3.1240925284611243,150,7.219820358632264,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1\n0,65,500,2.2375758360847504,7,1.4050580786902884,2,2.826430290311802,250,4.825124929667343,5,6,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n1,174,500,4.5727455217268815,0,6.1171517498951244,4,2.3841932029217605,250,6.48991206420007,8,6,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n1,68,0,5.858054793746227,2,4.8889974646261205,0,3.9241533205961514,200,6.201631436169157,1,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,1,0\n0,117,200,0.990852618833202,6,2.5336763096047967,6,2.8780306101069435,250,5.50481967431014,4,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n0,129,0,6.8204270824737545,5,3.609959504808451,3,0.1836575613400937,300,6.725165971988252,4,4,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n0,131,0,5.910436853619442,7,7.39790682023806,0,3.716214801959797,250,3.9198128402085914,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n1,64,500,7.443132643365009,4,6.869382354608447,2,2.196485637261908,150,4.082949328932225,6,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,1\n0,82,0,6.017525467259013,3,2.6391734417868578,5,5.954566404065707,100,5.4538955981834905,3,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n1,67,0,7.01206025191567,4,5.228994317146423,3,3.728660447833296,100,3.701069368937144,6,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1,0\n0,64,0,6.765260230151925,3,2.597736658859452,5,6.833813092546656,100,5.3930570184141065,3,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,1,0\n1,24,0,9.737355149245614,4,7.667280935087709,2,4.05421101847263,150,4.3489908506460155,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,1,0\n0,137,300,1.7770145900107686,6,1.3603755853158268,8,3.1517214788508534,150,4.1394259772706645,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1\n0,5,900,0.29224870305414896,4,0.9290174294726129,1,3.3154052573547697,250,5.218604922112606,4,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1\n0,81,0,4.452010896223797,5,6.302822972924805,5,3.8728760258385013,200,4.383680980125602,3,4,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n0,168,100,0.4558437946867802,3,2.0831031647609404,5,2.814194100508538,250,4.410159277795752,5,6,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n1,28,400,9.697617467117297,4,8.746120758125539,0,3.1520636732076364,250,2.7512349136613814,6,4,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n1,98,0,3.7289758087955223,3,4.168914493360851,0,4.209233178947034,200,3.893749146268578,3,7,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n0,40,600,0.8268127296167798,1,0.12842917494780348,5,6.978311671116115,350,2.90833743857586,9,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n1,28,0,7.290016013045093,6,5.693553067060982,2,3.3328717961041567,150,6.140655719434045,6,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n0,134,0,4.60948231933355,5,4.1251018496617995,5,2.9806214646245577,300,3.81536972241166,3,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n0,32,0,3.4147156596366326,2,7.490226940432567,4,5.082978180028384,400,4.95159780877618,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n0,96,200,1.4039852562168258,3,4.1475599586175695,4,2.3199484226249143,150,5.9198942137188855,2,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n1,45,0,4.655580242568126,2,5.120947154461071,2,3.3534314890240844,250,2.36613746666891,5,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n0,180,0,0.5576690717904436,5,4.066840569534241,10,3.2476931567340337,200,5.575908117895988,6,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n1,64,200,9.847548068282515,2,7.689864080753567,5,3.1270694268689048,250,5.372191131660175,6,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n1,47,0,6.4398995363528355,2,7.468014492103308,8,3.8549130078993215,350,4.31392690821174,5,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n1,14,0,3.3391551988419703,3,3.546650156358998,9,5.1878197214965045,250,5.618847930919343,2,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,1,0\n0,128,0,1.8628788070966955,4,2.332914680331377,0,1.8795255868098173,250,6.446399185761446,6,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n0,198,700,1.6322376379929942,5,1.0637798397789604,2,5.334472451734622,150,3.7490254907327523,4,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n0,75,0,2.4095552873708703,5,3.99680916216097,3,2.8959651340496704,300,4.7228274072374425,4,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n0,90,0,1.6506062575654363,3,4.886340331526571,6,3.79298210081794,350,6.512670698694322,8,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n0,106,0,1.968927836395041,5,4.261306988121953,1,2.421793612789178,200,5.100687054277968,5,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n1,192,0,8.691290644201013,5,3.438595242753145,6,4.729950191251903,100,4.865835802567951,5,4,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n0,166,700,0.4942978926021322,3,1.5014994850758452,2,4.270916388668969,250,3.036846111202582,4,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n0,105,700,0.2638425596197633,6,7.908305441511286,8,2.240406027874579,500,5.187505143485703,7,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,1\n1,123,300,9.192170574286127,2,7.688682135320477,1,1.2270216665784428,250,3.9405537236251114,4,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n1,84,0,10.804369824247685,0,7.761981461963079,2,2.858448981132692,300,5.454865905316142,5,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n0,74,0,6.7377646663648845,3,4.9840948179142135,0,4.239082550296988,200,5.711875928084365,6,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n1,83,0,7.5689104571614765,1,4.1905430230894805,1,4.355836787294551,150,5.984610149660307,3,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n1,169,0,8.583950590073053,3,7.118482145046679,3,4.62697795453237,250,3.2415870570213814,4,3,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n0,39,700,3.558794016046836,1,2.9626493586295704,3,5.1324250562317975,250,5.021697221340407,6,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n0,52,0,0.6393232536017059,2,1.7096063547882387,6,4.151370921420087,150,5.330589060466255,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n0,137,900,2.2767698896689503,3,6.750955593647605,2,1.5134886580911942,400,4.661362517686082,6,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,1\n0,197,500,4.32449288802909,4,1.877205371638984,0,3.8717115081134494,200,4.739246916857281,4,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1\n1,184,0,11.404578865809786,6,4.526665332629225,4,7.576258845577537,0,4.301090112605774,5,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,1,0\n0,60,500,2.6611749029207004,2,7.0090058437682154,7,5.886802517075047,300,3.095087728136656,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n1,59,200,9.154732432967977,2,7.435691937791688,1,4.4562393899040975,200,2.726307229217338,4,6,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n0,12,700,5.1176881450129486,3,4.875820958217969,0,0.19968017405586205,300,4.326276245415393,4,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n1,200,0,9.120015661297057,3,3.714014877743797,0,2.896091999371422,100,5.539216255530237,4,6,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n1,112,100,10.578212200996724,4,7.843785695223782,2,3.57719590291427,200,6.084146631317549,5,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n0,160,500,7.017395434200541,4,0.5776925005749414,3,2.0575542689559265,300,6.143861250045692,5,6,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n0,93,0,2.305242536984184,5,3.79015033562527,0,4.098174040185547,300,5.39751970055067,5,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,1,0\n1,50,0,13.950739845915596,2,5.4795308357291095,5,3.0924033108145097,100,4.517298409652257,9,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,1\n1,100,0,7.760349335386204,3,4.422454730959796,5,5.001718449362356,150,4.801346676479901,2,4,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n0,29,0,6.500784104134398,3,3.071936440711884,0,5.002592893532568,400,6.527709903309313,11,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n1,104,300,9.891526467585326,2,4.739329271596307,1,3.7682487742876565,100,5.044228849210463,5,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n0,89,800,4.889667016380352,4,3.2655174441016475,0,4.8154691443122575,250,5.8783509735551736,5,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n1,164,0,13.495078620714393,1,6.980782873245256,4,4.533284576875214,150,6.8054618685184805,7,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n0,93,400,8.456998095440653,3,5.357314827344238,2,5.202608293057869,250,4.6006365059196845,6,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n0,96,300,0.6095853061654289,7,2.9758527495567697,4,1.2394433362628607,350,5.417299665132466,6,6,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n1,191,200,15.342823996492386,5,4.12844427547333,3,6.432561475298468,0,5.429031157066772,6,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n0,2,0,0.2231589994614982,3,1.1853359114865478,4,2.9466136717931364,100,4.343582069302854,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n1,85,0,11.3978644314101,0,4.9188051623428395,4,3.7780775884425006,200,3.671362847044031,2,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n0,12,0,7.946946415851912,3,5.296915595628083,3,7.199382083322368,300,2.960056893535181,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,1,0\n0,36,600,3.630396413978605,4,4.172281443206944,2,5.4971702305925385,300,4.569952096465747,5,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n1,65,400,4.51060048163301,1,4.180499166548862,3,2.7591202282567187,200,5.687487944010358,4,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n0,143,600,5.0207562527058585,0,1.8729025002248108,1,5.060002035016284,150,5.105513582198227,6,9,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n0,161,400,2.435762518609035,7,8.652909584574825,4,2.03581415189993,300,4.366317321378866,5,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n1,147,0,7.174579537589968,0,5.25247332034121,0,1.898277431624085,250,4.460356465085017,4,6,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n0,156,0,0.6175685014999948,1,2.720824248057812,2,1.6957922803471923,300,4.309515194264952,8,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n0,144,700,0.1378976862428516,4,6.52897096761099,6,3.578811615922075,400,4.7869663027162845,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n0,34,0,3.79224718211522,3,1.2314203313515169,3,3.69468147081852,150,3.971925735902713,6,8,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n1,195,100,12.395279499846705,3,7.7749625581230415,0,3.457246390714676,150,4.058253705182331,4,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n1,121,400,7.521307946498242,5,4.6925248347784265,4,4.23085898527518,150,5.439294899850979,5,5,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n0,114,0,0.5066452178980967,2,3.0312259326208615,9,5.718765774708929,450,5.236299660993272,8,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n1,6,500,5.543081092296838,7,5.958614795297402,1,3.020830309560613,150,3.806518268696888,6,8,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n0,165,0,1.9282298114993344,4,0.4099907046528237,4,5.071458056400501,150,3.1711126229287494,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n1,56,200,10.065406044298603,4,6.5691577261818885,2,2.7454271102736696,100,4.36652958299001,5,6,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n1,78,400,3.4456804303422626,5,3.093716791536016,6,4.6033884479393565,200,7.651653766614838,4,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,1\n0,84,500,3.958706548155816,3,1.7866869443076523,3,5.057073608609729,250,5.426001753101845,4,7,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n1,121,0,14.757466890206167,4,9.858675410426358,2,4.581345529520802,200,6.202084825793787,10,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n0,173,600,7.321513422089577,4,4.315261856988873,3,3.3061274939104126,200,5.068036167550713,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,1\n0,79,0,4.081603136099142,4,3.1470377514517067,3,4.089380381568284,300,5.499476546028536,5,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,1,0\n1,59,0,6.025338398844389,3,2.8800763586089264,2,2.4099417870445183,150,3.7650196871375634,2,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1,0\n0,195,800,1.2191553480367503,2,2.380178348927373,2,5.017027641071305,300,5.225276911519521,7,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n0,106,0,1.2093337750010784,0,0.9172082859453408,5,4.077288981109769,200,6.2426100932975945,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n1,89,500,5.7716622281661625,5,6.060755910496043,4,3.3344473741839864,200,3.2080715669941,5,6,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n1,198,0,7.031440916088082,6,8.981313911585444,1,4.736539791541329,250,4.348453413971458,6,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n1,94,0,7.473582686027497,5,4.050605578742251,5,3.696224841635321,100,4.866697468102236,7,7,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n1,156,400,5.570861030272894,5,6.210256626271432,2,4.672340556139983,200,6.6959760257523815,3,6,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n1,17,0,9.77581497587324,3,8.462488229962641,3,3.6365363633233567,250,7.995808233470321,8,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,1,0\n0,150,0,5.46458708918195,3,6.8162820558122945,8,6.397382119161984,250,5.8379885341837365,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n0,72,0,0.5775488122629849,4,0.7939542357989477,5,5.1733977932080615,300,5.503087816218492,6,5,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n1,169,100,7.0769641075584495,4,5.225739840107572,3,2.852041414618542,150,2.994182982148692,4,8,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n0,175,400,1.2171262085247152,3,2.5240098113228444,6,2.5511916655681546,150,5.040414417604283,5,3,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n1,30,0,5.994060190089742,4,5.831328948592219,4,1.8110498309340657,150,6.47353826693768,4,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,1,0\n0,154,700,2.8471237334130928,3,5.383645347929363,2,3.1253778567249606,400,5.3848517744017075,6,6,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n1,10,0,15.679044256397779,6,7.607809010905927,4,5.347523169530901,50,3.275728118868676,7,2,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n0,156,0,4.169806460400138,4,7.659805937876575,4,3.672182208625871,350,4.8820286191333695,4,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,1,0\n1,17,0,6.621073129126527,5,7.1324519224373075,5,4.777130699406611,200,7.254987670508845,6,6,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n1,184,200,8.056710311691809,3,4.796317591077699,7,5.744380853055467,100,5.052492803412385,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,1\n0,128,700,3.205405597925865,0,1.6971000651456314,1,5.635752862802787,250,6.474828175226968,6,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1\n1,56,0,3.971236468506421,0,6.532678999945098,0,3.8263723018646463,300,2.9049373178357976,4,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n0,177,0,2.09276989531031,5,8.390969555515499,2,1.9584236753966595,350,5.204256596502035,6,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,1,0\n0,173,700,2.7986231451067662,3,2.9871116388931633,2,2.545116494516538,300,4.760984406577483,5,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n0,99,0,1.9292831282234435,6,3.7193683693682478,3,2.62711760091222,350,5.522773782377926,5,6,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n1,52,0,0.0895337655500299,3,5.780109332962973,5,4.2392635796157405,400,3.613828981554537,2,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,0\n0,52,500,5.007708132840347,4,5.0002799896539205,4,3.6935223394669614,200,3.8214290801789135,4,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n1,173,500,3.5454318266320097,1,4.016981600249371,4,0.6904126604777332,200,4.9264703009885285,3,8,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n0,183,0,4.208577874294827,2,3.2374608124753173,2,3.3852056170126277,300,4.4295527308256295,8,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n1,198,400,10.719792932197235,6,9.439815289308056,6,7.931765189159093,150,2.5935840105290224,9,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n1,108,300,4.566259212043191,3,3.0704775147551664,3,5.0204490284411225,200,4.692714829223918,2,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n1,80,600,8.094781454605076,4,5.268670214873822,0,2.6517094380664186,150,4.71698829706455,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n1,38,600,6.594239917484003,4,4.8724874472957005,2,6.218568256843129,100,4.488744471066721,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n0,136,700,1.3080840351670373,3,3.5316437075482323,2,3.799771831628848,200,6.146108401779194,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n1,11,0,8.652643839367661,4,5.912721361331087,5,5.030123730323028,200,4.692480121209352,6,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n1,168,100,10.986138880049081,3,6.033296085784093,3,3.019161843660074,200,6.47762455062349,8,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n0,168,500,2.6662011343711414,1,3.108439565905265,3,5.539324647785474,250,7.088358851890714,5,7,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n1,13,0,9.425316562973313,3,5.5686984717073225,1,4.024949634896204,100,3.994961940679565,4,7,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n0,106,600,0.6187907608657621,3,4.158614710692878,3,4.1675483238322535,350,5.701499727267264,6,5,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n1,82,700,3.4216461190398864,5,6.763163144801933,1,4.225188185087438,250,4.1477222636371645,7,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,1\n1,91,500,11.370720828387675,1,7.801939526258888,0,4.4560985227408505,200,7.297788687858166,7,2,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n1,150,200,11.576985201625805,5,10.590615023286915,5,3.5559700613467538,250,3.6641024572992777,8,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n0,100,400,4.796070546251724,1,5.161618922597127,4,6.872085438900911,150,5.429283824079398,1,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n0,191,0,5.805228233234426,1,5.374096909817811,4,5.729189465248842,400,6.569277138741213,7,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n1,125,300,6.900981584788616,2,5.281042176214202,2,4.279352416698846,200,5.391115428710593,3,5,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n0,126,0,3.816301464693282,2,5.420409753405697,9,8.989510760940297,250,4.142588527377276,5,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n0,152,0,1.5276827129234345,2,2.87411613449966,7,3.983030867706958,150,5.178725587041378,2,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n0,27,0,0.5052799815618458,6,5.806945600467063,7,1.7340047335410644,300,4.545258994583228,4,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,1,0\n0,95,0,0.050595916890978636,2,0.3236705601211236,2,4.090669737254672,200,4.563195862043757,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n1,92,0,10.656271235224748,4,4.943316463450077,2,4.375848030615428,100,4.158447080217171,5,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,1,0\n0,150,0,1.3306615427520478,2,1.2940422443074393,2,3.9849343129580963,200,5.0665584877135865,6,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,1,0\n1,194,0,10.010985700812848,4,6.773600195935902,4,5.201800739870512,150,3.6921046460245206,6,4,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n1,58,0,8.601301061957955,3,4.564508614483281,4,3.2356693481191123,100,4.063134130270493,6,8,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n0,129,0,2.3350424200703577,5,6.7734429122488375,6,2.8472268904640328,350,4.711906455621764,3,2,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n0,134,0,0.1531755682416227,4,1.9628036136122382,2,5.363325717274781,300,3.881205427388447,6,6,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n0,116,0,2.3316206951780867,2,5.6192910193017624,2,3.333289979525901,250,5.405833498412256,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,1,0\n1,179,400,10.292922650358888,4,5.463122885055424,1,3.723713369700555,100,4.507743799724453,6,4,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n0,2,0,2.2710665175537925,2,2.204608968788204,0,5.32198763471242,200,4.42577645906518,5,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1,0\n1,63,300,8.957848422820248,2,6.580991176278281,3,5.90354159267677,200,5.489467809024824,7,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1\n0,172,700,1.4768953832200546,5,0.1948725443651318,0,3.463206368665504,200,5.318383212248226,5,7,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n0,76,0,2.068338269363032,4,2.2794157562070545,4,3.771888033391649,300,5.458535321353168,6,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n1,117,0,10.63137547498156,4,10.279355595751394,2,3.292709028449973,250,4.855138314015852,12,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,1,0\n1,10,0,6.478759285987907,3,6.702655031583746,1,4.0111180583575985,250,5.3667149824191815,5,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n1,55,500,3.8509123658239317,5,3.458048749493947,3,4.218917055928625,150,5.510206090311774,4,8,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n1,46,400,9.333840042316881,4,6.341943316477273,0,3.3593410210175914,150,4.613052488623438,7,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n1,128,300,9.226466415155492,6,7.153196814714036,1,4.50796922205483,150,6.048436315729601,6,5,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n1,13,0,9.661583775060206,2,5.095779420859566,1,3.66136768306703,100,5.298557090944331,4,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n0,145,0,4.433946224805883,4,6.164412200315546,1,3.919256002229007,300,3.150420718033125,6,7,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n0,170,0,1.21939981008828,6,7.5510861412222114,9,2.70165375133939,200,5.433183548684144,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n1,93,0,5.130962541565151,3,5.007669918951094,1,3.4213819459985917,200,5.936048861174805,4,6,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n1,114,0,12.277307273251955,2,6.756966284802611,2,3.1626863387760427,150,4.671007752954163,5,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,1,0\n1,119,0,4.785056250631675,1,4.43423861820334,5,3.872155050466376,250,6.3859569126957485,5,6,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n0,27,500,2.3363305324699173,3,0.3988852516709596,5,4.707320801619401,300,5.65068211911736,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n1,177,200,3.747253126842136,2,6.406400234941579,2,2.258410451019728,300,6.754390336911137,1,8,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n1,193,0,7.101619607481427,3,1.8895438041589452,5,5.6788635781022565,100,4.908463327400812,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n0,22,700,1.6686011763535165,3,3.725937901010942,1,1.9239475387185068,300,5.527073904605674,8,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,1\n0,68,600,3.721949606798596,6,2.38556517848904,1,2.845924122076388,250,5.895878729348175,7,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,1\n0,182,500,4.666779517171845,0,6.204288877570367,5,5.740598587631299,250,5.172386108218452,5,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,1\n0,160,800,0.8043837750233012,2,2.7249139125898245,3,3.9365134019499934,300,5.1431985411336125,7,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n1,122,0,6.466980435676723,3,6.583793038235246,0,3.927845599539042,250,5.184683860486057,2,8,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n0,126,0,1.1129122965677514,4,2.7716229115183832,1,2.7244902156686712,300,7.028834399724233,7,8,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n0,113,100,6.530987045104951,4,1.1065566702528409,4,3.0518807764322133,100,5.7387165183921285,2,4,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n0,192,500,2.7324481087447583,6,7.438365887428817,7,0.6850870501098258,350,6.3933379371746035,4,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n0,87,0,5.472753147448547,5,2.164659314505137,6,1.1399867202285412,350,4.498819165205923,5,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n1,23,600,8.216964433622277,4,7.55023013715765,0,4.4771038703749815,200,4.6440974605822625,6,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n1,6,400,7.272365123917245,3,6.248245303274068,0,2.177913632991244,150,5.852783849693241,7,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n1,146,0,3.7556719208528815,5,5.29428849058569,3,5.956389800481657,150,4.361227295637823,6,7,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n1,152,200,7.195300497099818,2,5.2646809623987085,5,4.113217903013926,200,4.761339856491924,4,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,1\n1,98,0,6.666329530302683,4,3.169978608306933,4,3.462688168355574,150,5.053545612903013,3,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n1,183,400,4.5251696631984,5,2.73017087328121,6,4.4852885928624975,100,5.893220896590557,5,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,1\n0,56,700,0.3846698205961738,10,7.087236547984822,1,0.6049363361738109,550,5.6582591502438,6,9,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n1,150,0,8.735239799298267,3,6.959893299031696,1,2.839336261311169,150,5.342917777959636,6,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n1,41,0,12.752871343995546,4,5.583948721274501,2,4.536555855654519,50,3.5532356277831267,5,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n0,61,0,0.6278529903229888,3,0.4709838442759153,1,4.1288417857687145,250,3.2960538931759884,7,7,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n1,58,500,6.22661300717709,3,8.999674185525322,0,4.29909802600909,300,3.7397488710794256,8,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n0,35,500,5.140424247384729,5,6.574796848952554,2,5.161299543737007,200,6.738178477096996,3,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1\n0,35,0,2.05796533167263,2,9.928294967184547,4,3.0493925828612465,300,5.12281547162478,6,3,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n0,15,0,0.9086520827083122,6,2.219255452043128,0,1.3791466082173809,350,4.552201940018407,7,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n0,152,100,1.6716897418637098,5,1.59322795325726,3,4.4809262996512285,200,6.628742198960067,3,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n1,62,200,9.340109935820298,3,7.837501790351053,6,3.7945424617242063,250,4.874846180334741,8,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n1,137,100,10.340911993857887,5,7.716276628920164,3,2.632981897016559,200,5.790073565287898,7,7,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n0,148,500,0.8761671247690526,0,3.801816868486324,1,4.172187834374139,300,6.254749149630939,10,8,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n1,29,600,7.5101376193830705,5,6.891976612403107,2,2.02878389459824,200,5.392913241515123,5,6,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n1,161,0,5.7357982471065725,4,4.240546510048774,2,5.685126940039082,100,4.134161546476268,8,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n1,77,500,6.723846319350875,3,4.832989596439403,3,5.407792771746653,150,6.786841059104193,4,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,1\n1,72,100,7.634205397880316,5,5.550220406711137,3,3.942355053486194,200,5.2405552322613005,4,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n1,109,400,6.232516073006338,2,7.401403139218218,0,3.5591974949311465,250,7.149768436141103,6,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n0,176,400,4.090563157700574,2,4.582795753572059,7,3.3300000070016047,350,3.074718426409195,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n0,185,200,2.3644146952258693,3,5.781596229875518,5,2.700227741096503,200,6.241097539823759,4,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n1,129,0,8.490898274004287,5,5.912629024096301,1,3.711982906839941,100,5.219172472179271,6,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n1,159,200,7.021202523757397,5,6.983686646080811,5,4.561158932412691,250,4.446251786505126,4,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n0,20,900,1.7339492478034209,0,3.274847417815822,2,3.556915899728798,350,6.501046979240647,7,6,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n1,190,500,7.282764199678618,5,5.618324974574307,0,3.745206767481886,100,3.8875959173413412,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n1,153,100,9.547135664104557,3,4.281478659043356,7,2.977235746983001,150,4.7409415756739035,7,6,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n1,57,200,8.580651658920651,5,5.713050083390041,1,3.612266680447029,100,6.490181632486293,5,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,1\n1,125,0,5.451430606217252,2,4.614823365324272,0,2.2004494287388274,100,6.369748199949233,6,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,1,0\n1,72,0,3.828206205754449,4,3.7662003626903866,4,2.4735600310317403,200,5.234642992004925,7,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,1,0\n1,163,100,16.897529354153928,5,8.177616093065312,3,5.7270460819944775,100,4.931918414332554,5,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n1,24,0,10.311418270901056,7,5.228084240924392,6,5.464869257732481,50,5.790633871409267,6,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n0,113,600,0.5186814408540803,1,1.4516128869210243,0,0.9956224575657622,250,7.039914108260103,8,9,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n1,90,500,3.7682365685272767,2,6.908166494225906,2,4.505805883240245,300,4.8578798362019375,4,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1\n0,33,700,0.8544833773904967,2,3.800313664929375,7,4.44052833698736,450,4.349945251610467,6,4,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n1,43,500,7.668287998761293,6,6.8302115266298715,1,3.4398075559661963,150,5.1568502201813695,8,5,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n1,182,0,13.019325152874934,3,6.214163620473848,4,2.175615067529848,150,4.688646475028292,7,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n1,190,300,5.752132281896131,2,7.493617251397722,2,1.7518190257351909,250,7.8080045290770705,7,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n0,25,400,0.9558255694353691,5,1.3848051990052537,2,2.5697669263895153,250,4.1021834006294435,7,6,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n0,144,0,4.8712520888869975,2,4.830823570743477,4,4.263651955367925,250,4.953383701341995,7,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n0,4,1000,4.237402103904462,3,6.587320803489084,1,3.1399947379685944,300,4.25807780497461,11,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n1,128,0,6.605379278405966,5,8.118672001160762,0,2.17251981145697,250,4.643112529507304,9,8,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n1,162,0,16.164527149647874,4,11.038385332281747,1,3.622965532567009,200,4.338718644399108,8,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n1,193,0,5.190992621312807,1,4.122644719803498,1,2.335126098738893,150,4.2574797062545855,5,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n1,193,0,4.680872026439213,5,4.556796507038864,2,2.8566575550986806,200,6.771131799495,6,8,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n1,168,0,5.099966034644754,2,3.602989072149713,1,5.713789224244003,200,7.1880168617433045,4,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n1,123,0,8.072828724655729,4,9.370346753784382,2,5.746874475237781,250,4.294831741192406,5,2,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n0,23,1100,2.331034311710047,1,2.154107222792945,2,6.260367008917291,350,5.351510438526537,10,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,1\n1,140,0,8.783615008474,4,7.144719980420513,2,3.2547780571539637,150,4.231996657132538,8,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n1,101,0,7.807451515655797,3,5.272054466193652,5,3.856629430464515,200,3.8325087957395385,4,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n0,36,0,1.7234893433443703,6,3.387582385380199,5,2.2114860044952955,300,3.3107317920325183,2,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,1,0\n0,2,0,3.579489242194448,3,3.273732226380017,5,2.731500951740915,300,5.5847860849845326,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n1,147,0,0.981805621946272,4,5.051746759115275,0,2.690484464812217,250,6.066130284273648,5,9,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n0,31,800,8.820347301086146,0,2.309639015735519,0,9.496316501399988,200,5.399324167410707,8,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n1,67,300,13.358312108660927,4,7.81216008586679,1,4.102268489162111,0,6.0132593365527285,8,2,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n1,86,0,8.832601771879133,2,6.514991099485358,4,5.061867993015911,250,3.554604964933752,5,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n0,153,500,2.7458023383080286,3,2.5606692829316566,3,3.2732403516690365,250,4.516001863409675,6,4,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n1,186,0,1.2524603263484972,3,4.95197077171325,5,3.1009001444540125,300,5.613394193256223,4,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,1,0\n0,174,600,1.3429924825515118,6,2.4823337218504102,3,3.438656788681122,350,3.7883893109589266,7,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n1,140,0,5.705663260653293,4,5.077386308881577,5,4.1801058803722,200,6.0750852054331705,2,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n1,178,0,4.153946594042634,4,5.3212298226625165,1,3.900966759290864,200,5.351170822945559,2,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n0,125,700,3.2288115508536808,1,4.764362334699068,2,3.138309418694469,250,6.138844195567017,6,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n1,65,800,7.202082036419872,7,6.201128833715554,3,5.47790964889235,50,4.871287017813428,8,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n0,4,600,2.771617512997256,4,4.364061919991247,0,2.3705283354610067,250,4.932623700590908,6,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,1\n1,86,700,6.471225256958407,6,7.370264814487764,0,4.6862705491274665,200,4.270550262871728,6,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,1\n1,172,300,8.737569511328386,1,7.823843875906676,2,2.5462625094193667,250,4.5472128158660094,7,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,1\n1,80,0,7.464251608190335,3,5.43704142952778,2,3.8127799417698167,150,5.074269366789778,4,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n1,121,0,7.23203135765498,2,8.599432986024576,3,2.0453764218671626,250,5.723951494567604,6,7,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n1,124,0,2.322310246221602,3,6.171197586561068,4,2.0297561905706933,350,5.443081813258486,4,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n0,40,0,5.026895179371855,5,5.867449560163732,2,5.3941199076670046,250,5.194531323235776,4,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,1,0\n0,133,400,0.32636834718955393,6,5.287543123865229,5,3.8789503560135934,300,4.836874764175335,3,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n1,12,600,5.73085019472309,4,4.9487281195225545,0,5.179324498229724,150,4.271697950161746,3,6,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n1,125,0,6.295474694786253,5,4.636438334472579,6,5.976295431918776,100,4.0629564061378325,5,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n0,151,600,0.8295735708334302,1,2.7659429955671935,3,3.1694063443313216,250,6.845664385036043,4,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1\n1,150,0,12.381786830606137,3,7.696715338014494,6,5.051486884610852,150,6.680727239429363,6,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n1,142,300,10.081762931774175,2,8.902149704135983,0,4.026830955858474,250,6.2943068415867,5,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n1,16,0,7.748160199003287,1,4.912464750148366,1,0.8936878770680616,150,3.3030485475696403,4,8,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n0,30,600,3.1841099559925587,3,4.693183123685866,1,5.154936416185087,150,5.453368453090713,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n1,124,0,6.350164019046546,6,6.174900893663557,4,5.097930527525358,150,4.88224683079949,3,6,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n0,72,0,1.711691181009578,0,4.239773023490659,0,3.4329543465751264,150,5.2848899372421565,4,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n0,45,700,0.08608664149002633,3,4.375054536230333,2,5.816351600093507,300,4.852053899466614,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,1\n1,5,200,8.70828391579197,1,8.627271703675758,5,5.636551523948169,300,4.67349254438222,7,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n0,69,600,3.9218629530764098,3,0.6606131042461412,1,7.736648678199284,200,3.596103745060788,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n0,35,300,3.7176052771152217,2,4.409190837789851,7,7.13117324753869,250,4.554213583888281,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n1,45,600,4.5608518930732265,2,4.944372153388863,2,2.561613046988089,250,4.545869571815807,5,6,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n1,162,500,3.4643117855529733,2,6.068858381223543,0,3.4540353293752437,300,4.302254354388332,4,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,1\n0,2,0,1.7695607334034582,5,1.6089231888263678,9,4.989532702088363,400,3.4222179563881507,4,5,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n1,32,400,7.902175173918209,4,2.8111907798829137,5,4.996498095766689,100,6.210908069199926,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,1\n1,80,0,1.085652294078468,5,5.405487403007681,2,3.044118363987888,150,5.134650126014571,5,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n1,147,0,10.410876190439387,5,6.121556471532603,8,5.716964359653233,150,6.3937412385141394,7,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n0,11,400,0.939121952033796,4,3.1721278212207813,4,4.005080598445405,100,4.408897375640574,1,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1\n1,190,500,9.117224646292255,5,8.075639431989769,2,5.479068220121814,150,4.056899770885953,7,2,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n0,19,0,3.4150939695694245,5,2.277511240124201,9,3.859251694820836,400,4.809225331217407,7,3,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n0,105,600,0.7906868387085622,6,3.1167133010364565,2,1.6423256127936259,300,4.805656284207709,7,9,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n0,132,700,3.0453496549352645,4,3.2039850589683416,1,2.583618810916924,250,4.947075014860911,6,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n1,81,0,6.636607431046803,3,5.243057753931001,5,4.890138215680539,250,4.929006120121176,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n0,111,700,11.61561855906364,2,9.791103721307325,0,5.144235388828281,250,4.413320414031617,4,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n1,63,0,4.5282735632075095,3,6.3245079156658335,4,3.306024788314458,250,4.499637351924905,4,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n0,138,800,7.741945996788541,4,6.376694040524103,5,6.395538148973062,450,5.372021717900632,8,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,1\n1,39,400,13.177610718689596,4,4.409394182273072,4,5.387005444342339,50,5.0384372725533915,9,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n1,175,0,3.579378082507744,5,8.260249381460827,4,4.011491811726569,300,3.720274864405501,7,8,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n1,61,500,4.7398025962454025,4,6.85463330321082,5,3.9282621548592696,250,3.9290953874809067,7,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,1\n0,77,800,9.616257414206443,3,6.358484995084198,2,6.5415345339342545,400,5.863795728835018,9,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n0,172,0,3.278958928189128,5,8.39292667973588,7,2.492052966458528,350,5.74160731150651,3,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n1,117,400,4.598860801783222,2,7.808073313775782,1,3.2365918773049,300,4.166398742388497,6,7,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n1,45,400,7.731493775183103,2,7.360375812486478,2,4.007538287225746,150,5.173537335489105,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,1\n0,135,0,4.251071234568392,0,6.265121835794682,3,4.084317363702906,400,3.9737478971542255,7,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n0,75,800,4.096505082265394,4,6.526019593432657,6,5.877901357478603,450,3.897035526916493,8,4,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n0,184,0,4.441940301145067,0,4.9670194511800405,5,6.455427143717861,150,4.324242410898774,3,5,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n1,114,400,10.903889422654872,4,5.94560153315781,0,3.4625965890525747,50,5.770841302549707,5,4,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n0,121,0,0.8680204353948895,4,8.143065809441643,5,2.9617998436900534,300,5.808890829049492,5,3,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n1,33,0,7.582888237894733,0,6.48423168801367,5,2.2408520315334437,300,5.28203929660044,5,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n0,103,500,0.5245685665295303,1,0.28610424963229075,1,3.7735330721084748,200,3.9466501233458313,5,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n0,196,0,3.6311733430357545,4,4.791796820126766,1,3.5142891976834534,300,5.022606908941649,7,7,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n1,96,0,7.825095257219669,3,3.9108393882877706,5,5.973246286486098,100,4.670561350861977,9,4,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n1,119,300,11.222733173038659,4,8.790412518408457,2,5.640198021607943,200,2.838309022078189,7,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n0,104,0,3.3222737479269933,0,0.4211701898739193,8,5.6260808270645635,250,5.4426854122342405,6,3,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n0,144,0,2.03714227959798,4,5.492746928986063,1,2.2377564829224594,350,5.839744470213581,7,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n0,154,0,8.300781924816599,4,8.452148804697984,2,4.128373678913023,300,4.876769153332254,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,1,0\n0,87,900,6.009231992802834,2,5.6210552664653015,4,5.680514544078957,300,4.792492303383079,7,4,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n1,146,400,9.199506645307947,4,6.43408233408802,4,4.269726606055725,150,5.929763083245461,5,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,1\n0,68,0,3.011957528550816,2,3.8970066289113774,3,6.559714446915987,200,4.484529962650568,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n0,161,0,0.8750888338032947,4,4.910024025155372,6,6.199675838597956,250,4.818097217071443,2,4,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n1,39,200,11.728271755532527,5,4.09663766730641,6,6.051995673543075,50,7.398623651663463,5,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n0,48,500,2.5212854833114857,5,3.6501197971396833,2,2.2913860860392594,350,4.823343163989403,3,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n0,107,100,2.8878546565428995,3,4.5562627663108515,7,5.884113629653702,150,4.950048668440645,4,3,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n1,102,0,9.192087167342276,6,4.840815521361356,4,4.31075807989866,50,6.061406069462437,8,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n0,158,0,7.213736897257496,2,6.442340844993111,0,2.741375998273816,300,4.71182575175518,8,9,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n1,29,0,8.964728798907764,4,5.8091222623564365,4,4.894734571177769,150,5.774637224313871,6,4,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n0,173,0,3.1558803149309025,5,4.784470359791851,5,0.9940596994459144,350,4.6640475689465966,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,1,0\n1,29,0,10.998575000374574,4,7.857770654985572,0,4.801264920143264,100,5.465171315528816,9,5,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n0,23,300,1.6889451601238368,7,5.361661512632631,3,0.9040703590319136,250,5.428092425840154,4,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n0,147,400,5.197832608292192,5,6.321280543933318,7,2.6726332679307347,350,3.221425079130088,3,3,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n0,149,0,4.736840876560535,4,6.05628037462207,2,4.109512323666607,250,5.760405980115267,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n0,62,700,5.772571396509483,5,6.160102572316878,2,5.112252502577195,250,5.35204894077084,3,5,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n1,7,400,9.599980957164156,4,7.453305968540617,1,3.365096599098407,200,6.310066719552332,7,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n1,187,0,7.977263663298243,4,4.686295984424088,0,5.896823775297217,150,6.5383057565317975,5,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n0,13,700,5.074851995952561,0,7.490495794207447,4,6.769123675093255,300,5.154998420799467,5,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n1,195,300,7.526700560937034,4,4.286264573987019,0,3.1120772271192445,100,5.53922497251585,4,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n0,8,0,3.554673386488379,5,6.708317539515628,8,5.183700165173073,350,1.965165510812758,5,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1,0\n1,79,0,8.121589035436397,2,5.35648780269926,6,5.143066213388522,250,4.0606659658451845,6,5,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n1,54,0,3.1099119303952296,5,3.5561353154444664,1,4.6293822634704735,100,4.443912261332633,3,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n0,99,0,2.453977438012467,4,6.4158779597528435,0,2.6755034924742223,200,4.231484152117522,4,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n0,135,0,7.352076648066445,1,3.858050880901196,3,5.467269065664805,150,5.9513230437775615,5,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n1,139,0,13.101611271839127,6,8.309973084283289,0,4.753709911900351,100,5.198858922258305,8,3,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n1,58,500,3.0465926420297116,3,3.796879374780633,1,1.667252875753241,200,5.139821894166252,2,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n0,107,0,6.121453891068121,3,2.6943221052721564,3,0.2401502044049666,350,5.249664676732693,4,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,0\n0,49,0,2.2614336709512246,5,5.948743524178817,4,2.8304592212591704,450,5.476154007823283,8,6,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n0,138,0,0.8681725666970506,5,2.460251019509019,0,1.498162569573926,250,4.863824825582304,5,8,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n1,85,0,7.046521773893682,4,7.075284362293796,0,3.482121463267041,250,6.5263627283512475,2,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,1,0\n0,180,0,5.3046485073221845,3,5.855006551300042,1,6.588823283246683,150,4.9579221771628275,2,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,0\n1,199,400,7.551988433384826,6,6.0777041722714324,7,5.844004216161753,200,6.349252380780863,7,5,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n0,165,500,0.7588488417679349,4,1.1435516944270998,3,3.4296486763119063,250,3.024971708248711,6,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n0,66,600,1.693085502727956,4,3.4958882145390286,1,4.258217005408347,400,4.705002241392402,7,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n0,153,300,7.091816251238053,5,10.272569384051419,10,5.125592606018309,350,4.760267796842014,6,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n1,168,0,7.828809358390637,3,7.335539331202911,3,3.378262833703332,250,6.914875549226965,6,7,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n1,180,500,0.2735726458662073,5,1.7713788667451782,6,5.896292233254432,200,4.8929083340376565,3,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,1\n1,81,100,10.201260697281253,4,4.744525017977616,2,1.4522387013895797,100,5.177574873310874,6,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,1\n0,3,700,3.2189918811087352,4,0.730951233962081,5,4.441998339831212,400,4.406390086333511,6,4,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n0,64,0,3.457787572720441,2,0.6577357687696619,6,5.876279055950304,100,5.943248636260141,2,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,1,0\n1,162,0,4.034886371101552,6,3.350960773127548,0,5.954435000701926,50,4.884715138003465,3,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1,0\n1,30,0,9.189129286472216,3,5.6759964866394474,2,4.260741937685662,150,3.8909391433171803,3,6,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n0,182,500,1.3975597623478864,3,3.462628622735194,5,4.048250819388513,350,4.262375681171017,8,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n1,174,0,6.014333998298228,2,5.653403064832974,0,4.0308247896479035,250,5.149838433132491,6,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n0,197,500,1.1974629498044478,4,6.849415949562934,4,2.3574203137108642,350,5.459583665975996,4,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n1,48,600,5.324478774508263,4,6.320753609718956,1,3.8939130008194014,200,4.6278463708329385,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n0,68,800,5.228037169441588,6,8.325166621591336,4,3.965539732670925,350,4.211120651050317,6,5,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n0,141,500,1.8039073833729429,0,8.357507945265535,0,2.6242985145215223,400,5.798783370256835,6,7,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n1,84,0,7.91953953530074,3,5.673053285002254,4,3.4065472142911637,250,5.5892441817070315,2,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,1,0\n1,140,0,4.854800843294177,3,4.121944911126091,3,4.0302372555053125,200,5.614852705873023,4,8,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n0,177,400,11.031323017243338,2,8.713140561060808,3,6.9411527116276135,250,5.154735283886264,5,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n0,47,0,3.3110295203308144,3,0.6114452674813124,11,4.5433442663604495,350,4.804588147201908,6,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n1,35,300,4.287592127036311,2,3.8567619123740715,1,3.657358784324745,150,4.831109128613154,4,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n0,88,0,2.1216931869051177,1,4.071063694971662,0,2.551061617387336,150,6.392443482788724,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,1,0\n1,105,0,0.9720518089265928,3,7.7380740771292835,2,1.6666196940705484,350,5.375677954083702,5,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n0,61,0,4.7281781577773625,5,2.075976649883163,3,5.973814386663673,200,3.7458796980160667,6,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n0,99,0,2.755629186355804,1,1.3826795511924286,4,5.918787798349575,300,4.764011458076945,6,6,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n1,43,500,8.441610635984148,3,5.431942446194513,0,4.2701023815033725,150,6.2464862550499785,2,5,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n0,49,0,0.6756861822433802,3,1.909871615538096,3,3.1087267110895183,200,4.604699021930412,7,4,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n1,97,600,7.019000917847654,7,4.649786858223724,3,3.5711388523405336,0,6.290167096881478,5,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,1\n1,106,600,6.65581051421857,4,6.512468781939198,0,3.4025918274461966,150,6.59949784455581,8,5,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n0,50,200,2.0551487783682107,2,3.5186872160368887,6,6.5932653643248225,200,4.987097609316327,5,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n0,163,600,2.5279154246948763,6,3.5549129759379587,3,3.376108848867156,300,3.9585252202335024,7,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n0,86,700,3.932101848443183,1,5.4172755255614575,1,3.77464329837501,250,6.754927138555567,6,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n1,178,200,8.899662261422524,1,7.183830331536481,1,1.2110154576768664,200,4.8366964533057315,5,6,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n0,18,0,2.8378412966328157,5,2.970262205973612,1,3.158801580245888,250,4.8010370780400144,7,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,1,0\n0,167,1200,5.983074325020446,3,6.663035438066317,0,4.567146211102722,350,5.2115743973707245,8,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,1\n1,134,400,7.7133454089639,7,5.3823394528330315,0,3.2067969254021094,100,5.274015128833618,5,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n1,67,0,9.160468443350677,3,5.668370353138284,6,5.156926282115425,150,2.9638260573389066,7,2,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n0,69,300,2.0125197792772305,4,2.208641617967265,6,2.4963623412809635,250,5.7719430226324375,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n0,158,500,0.4791905890859241,3,6.868683938333696,8,6.8440623663542866,250,4.286309986106692,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,1\n0,24,0,2.874327517790653,0,5.010041576744663,2,3.3411385997766936,350,4.267412129131272,7,4,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n1,6,0,5.846556947089861,3,3.1164943096670026,1,3.941683800753169,50,6.1110318754534525,5,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n0,140,800,1.5155339343463368,4,1.0406001508290963,2,5.206303643485744,350,4.583501368923301,8,6,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n1,196,0,10.116189344367724,2,7.101833874085107,1,2.086303297179572,250,2.1823671374236304,4,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,1,0\n0,181,300,0.25417886660500244,3,3.5101268031812514,6,3.767753515586662,250,6.8779118950984275,3,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n1,167,0,4.705224275179245,3,7.063070227553313,3,6.162911756666057,250,3.6216936057568265,6,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n0,102,0,0.3568397129744918,2,2.9080249852472417,7,3.4662705397581983,250,3.8435315688293312,5,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n0,143,400,0.8482268106534514,3,1.3404611494777097,5,4.039720989162665,200,4.747484680224677,4,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n0,86,0,1.3735305541210083,3,2.579185798514777,2,6.275145323152556,250,5.051759848827503,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n0,22,0,5.513984837965664,1,4.2525118787025695,2,5.011393160597116,300,3.3317293097887237,9,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,0\n0,30,0,1.4105653003660423,4,6.478880981111883,0,2.4728259929914014,400,3.8879456326629214,8,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n0,53,0,6.96810884065032,0,2.3491662007511778,2,5.258726192531723,150,3.999345649876908,3,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,1,0\n0,28,0,0.8355731162595097,5,3.9022632558048183,0,1.0255538301442255,300,6.844759435258736,6,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n1,167,300,5.032755926574869,3,5.350524323930786,2,3.5139265988711124,200,5.414258827287863,7,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n0,12,800,5.336233283057791,1,4.5440722620802765,0,5.5884306657675165,350,6.173600501724334,8,9,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n0,150,0,0.6880559322601371,3,0.736563548562347,1,2.704656281514044,250,3.748287545808711,9,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,1,0\n0,141,0,4.47439526991695,4,0.22469970151381613,3,0.4131798029624054,350,4.853366777174074,8,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n1,130,300,4.7967352368415614,5,7.090931103100372,1,3.5152165016782813,200,4.159869046656222,4,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n1,194,0,7.630530643122491,2,6.734497114494169,0,4.591040383175488,200,4.723798724879954,7,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n1,185,0,10.144767993064047,3,6.239292593362298,3,3.8334447031054473,150,3.4579756179773025,4,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n0,178,0,4.113598389963926,5,6.166345934560348,5,5.724720712620798,200,3.867966086575637,4,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,1,0\n1,95,0,5.968038137119581,6,6.8570738402713225,5,7.125352624315068,100,5.556147221870629,6,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n1,88,0,3.784946701372887,6,2.8975262387986254,3,5.7384209267982405,50,7.8472695186646195,4,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0\n0,99,0,6.970549983004397,0,7.403363137690379,3,5.562602831060912,350,5.190369028589666,7,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,1,0\n1,71,0,7.390948297118487,5,5.208541669797309,1,5.613518503524021,100,4.644341065658332,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n0,73,0,1.614325648430193,5,5.736865858000349,3,0.7341793775927323,300,3.9909208896564317,8,9,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n0,190,0,2.528129598219966,3,1.6356761209747828,0,3.5478870483538034,150,4.177822962858156,5,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,1,0\n1,5,200,7.774450344703282,3,5.635926349730963,4,4.135892027495111,150,3.894515545906768,7,6,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n0,46,0,0.030402536452707633,7,5.465951147469727,0,2.7045092828731465,450,6.122231846402133,7,8,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0\n1,88,500,3.011483361619748,1,5.216294437717832,2,1.8155991865064265,200,6.235281038355072,4,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1\n1,98,300,11.300033638432755,2,9.533078320116383,1,3.644060633271567,250,6.240388247916959,6,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1\n1,42,0,6.724411692000152,5,6.117244663258974,3,4.623102029382443,150,4.1194165953621225,5,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,1,0\n1,139,0,8.484852958099115,0,6.625929738768878,0,0.9369274471547816,300,5.136757011455005,6,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,1\n1,122,100,11.045656402288408,7,9.70031751822358,6,5.3149351855549805,200,4.8724892374814335,6,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1\n"
  },
  {
    "path": "samples/mlops-sagemaker-github-codepipeline-codebuild-codedeploy/modelbuild_pipeline/README.md",
    "content": "# modelbuild_pipeline\n"
  },
  {
    "path": "samples/mlops-sagemaker-github-codepipeline-codebuild-codedeploy/modelbuild_pipeline/pipelines/__init__.py",
    "content": ""
  },
  {
    "path": "samples/mlops-sagemaker-github-codepipeline-codebuild-codedeploy/modelbuild_pipeline/pipelines/__version__.py",
    "content": "\"\"\"Metadata for the pipelines package.\"\"\"\n\n__title__ = \"pipelines\"\n__description__ = \"pipelines - template package\"\n__version__ = \"0.0.1\"\n__author__ = \"<Your Name>\"\n__author_email__ = \"<your-email@python.org>\"\n__license__ = \"Apache 2.0\"\n__url__ = \"<https://your-website>\"\n"
  },
  {
    "path": "samples/mlops-sagemaker-github-codepipeline-codebuild-codedeploy/modelbuild_pipeline/pipelines/_utils.py",
    "content": "# Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"). You\n# may not use this file except in compliance with the License. A copy of\n# the License is located at\n#\n#     http://aws.amazon.com/apache2.0/\n#\n# or in the \"license\" file accompanying this file. This file is\n# distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF\n# ANY KIND, either express or implied. See the License for the specific\n# language governing permissions and limitations under the License.\n\"\"\"Provides utilities for SageMaker Pipeline CLI.\"\"\"\nfrom __future__ import absolute_import\n\nimport ast\n\n\ndef get_pipeline_driver(module_name, passed_args=None):\n    \"\"\"Gets the driver for generating your pipeline definition.\n\n    Pipeline modules must define a get_pipeline() module-level method.\n\n    Args:\n        module_name: The module name of your pipeline.\n        passed_args: Optional passed arguments that your pipeline may be templated by.\n\n    Returns:\n        The SageMaker Workflow pipeline.\n    \"\"\"\n    _imports = __import__(module_name, fromlist=[\"get_pipeline\"])\n    kwargs = convert_struct(passed_args)\n    return _imports.get_pipeline(**kwargs)\n\n\ndef convert_struct(str_struct=None):\n    return ast.literal_eval(str_struct) if str_struct else {}\n"
  },
  {
    "path": "samples/mlops-sagemaker-github-codepipeline-codebuild-codedeploy/modelbuild_pipeline/pipelines/customer_churn/__init__.py",
    "content": ""
  },
  {
    "path": "samples/mlops-sagemaker-github-codepipeline-codebuild-codedeploy/modelbuild_pipeline/pipelines/customer_churn/evaluate.py",
    "content": "# Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"). You\n# may not use this file except in compliance with the License. A copy of\n# the License is located at\n#\n#     http://aws.amazon.com/apache2.0/\n#\n# or in the \"license\" file accompanying this file. This file is\n# distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF\n# ANY KIND, either express or implied. See the License for the specific\n# language governing permissions and limitations under the License.\n\"\"\"Evaluation script for measuring model accuracy.\"\"\"\n\nimport json\nimport os\nimport tarfile\nimport logging\nimport pickle\n\nimport pandas as pd\nimport xgboost\n\nlogger = logging.getLogger()\nlogger.setLevel(logging.INFO)\nlogger.addHandler(logging.StreamHandler())\n\n# May need to import additional metrics depending on what you are measuring.\n# See https://docs.aws.amazon.com/sagemaker/latest/dg/model-monitor-model-quality-metrics.html\nfrom sklearn.metrics import classification_report, roc_auc_score, accuracy_score\n\n\nif __name__ == \"__main__\":\n    model_path = \"/opt/ml/processing/model/model.tar.gz\"\n    with tarfile.open(model_path) as tar:\n        tar.extractall(path=\"..\")\n\n    logger.debug(\"Loading xgboost model.\")\n    model = pickle.load(open(\"xgboost-model\", \"rb\"))\n\n    print(\"Loading test input data\")\n    test_path = \"/opt/ml/processing/test/test.csv\"\n    df = pd.read_csv(test_path, header=None)\n\n    logger.debug(\"Reading test data.\")\n    y_test = df.iloc[:, 0].to_numpy()\n    df.drop(df.columns[0], axis=1, inplace=True)\n    X_test = xgboost.DMatrix(df.values)\n\n    logger.info(\"Performing predictions against test data.\")\n    predictions = model.predict(X_test)\n\n    print(\"Creating classification evaluation report\")\n    acc = accuracy_score(y_test, predictions.round())\n    auc = roc_auc_score(y_test, predictions.round())\n\n    # The metrics reported can change based on the model used, but it must be a specific name per (https://docs.aws.amazon.com/sagemaker/latest/dg/model-monitor-model-quality-metrics.html)\n    report_dict = {\n        \"binary_classification_metrics\": {\n            \"accuracy\": {\n                \"value\": acc,\n                \"standard_deviation\" : \"NaN\"\n            },\n            \"auc\" : {\n                \"value\" : auc,\n                \"standard_deviation\": \"NaN\"\n            },\n        },\n    }\n    evaluation_output_path = '/opt/ml/processing/evaluation/evaluation.json'\n    with open(evaluation_output_path, 'w') as f:\n        f.write(json.dumps(report_dict))\n    "
  },
  {
    "path": "samples/mlops-sagemaker-github-codepipeline-codebuild-codedeploy/modelbuild_pipeline/pipelines/customer_churn/pipeline.py",
    "content": "# Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"). You\n# may not use this file except in compliance with the License. A copy of\n# the License is located at\n#\n#     http://aws.amazon.com/apache2.0/\n#\n# or in the \"license\" file accompanying this file. This file is\n# distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF\n# ANY KIND, either express or implied. See the License for the specific\n# language governing permissions and limitations under the License.\n\"\"\"Example workflow pipeline script for CustomerChurn pipeline.\n\n                                               . -RegisterModel\n                                              .\n    Process-> Train -> Evaluate -> Condition .\n                                              .\n                                               . -(stop)\n\nImplements a get_pipeline(**kwargs) method.\n\"\"\"\n\nimport os\n\nimport boto3\nimport sagemaker\nimport sagemaker.session\nfrom sagemaker.estimator import Estimator\nfrom sagemaker.inputs import TrainingInput\nfrom sagemaker.model_metrics import MetricsSource, ModelMetrics\nfrom sagemaker.processing import ProcessingInput, ProcessingOutput, ScriptProcessor\nfrom sagemaker.sklearn.processing import SKLearnProcessor\nfrom sagemaker.workflow.condition_step import ConditionStep\nfrom sagemaker.workflow.conditions import ConditionGreaterThanOrEqualTo\nfrom sagemaker.workflow.functions import JsonGet\nfrom sagemaker.workflow.parameters import ParameterInteger, ParameterString\nfrom sagemaker.workflow.pipeline import Pipeline\nfrom sagemaker.workflow.properties import PropertyFile\nfrom sagemaker.workflow.step_collections import RegisterModel\nfrom sagemaker.workflow.steps import ProcessingStep, TrainingStep\n\nBASE_DIR = os.path.dirname(os.path.realpath(__file__))\n\n\ndef get_session(region, default_bucket):\n    \"\"\"Gets the sagemaker session based on the region.\n\n    Args:\n        region: the aws region to start the session\n        default_bucket: the bucket to use for storing the artifacts\n\n    Returns:\n        `sagemaker.session.Session instance\n    \"\"\"\n\n    boto_session = boto3.Session(region_name=region)\n\n    sagemaker_client = boto_session.client(\"sagemaker\")\n    runtime_client = boto_session.client(\"sagemaker-runtime\")\n    return sagemaker.session.Session(\n        boto_session=boto_session,\n        sagemaker_client=sagemaker_client,\n        sagemaker_runtime_client=runtime_client,\n        default_bucket=default_bucket,\n    )\n\n\ndef get_pipeline(\n    region,\n    role=None,\n    default_bucket=None,\n    model_package_group_name=\"CustomerChurnPackageGroup\",  # Choose any name\n    pipeline_name=\"CustomerChurnDemo-p-ewf8t7lvhivm\",  # You can find your pipeline name in the Studio UI (project -> Pipelines -> name)\n    base_job_prefix=\"CustomerChurn\",  # Choose any name\n):\n    \"\"\"Gets a SageMaker ML Pipeline instance working with on CustomerChurn data.\n\n    Args:\n        region: AWS region to create and run the pipeline.\n        role: IAM role to create and run steps and pipeline.\n        default_bucket: the bucket to use for storing the artifacts\n\n    Returns:\n        an instance of a pipeline\n    \"\"\"\n    sagemaker_session = get_session(region, default_bucket)\n    if role is None:\n        role = sagemaker.session.get_execution_role(sagemaker_session)\n\n    # Parameters for pipeline execution\n    processing_instance_count = ParameterInteger(name=\"ProcessingInstanceCount\", default_value=1)\n    processing_instance_type = ParameterString(\n        name=\"ProcessingInstanceType\", default_value=\"ml.m5.xlarge\"\n    )\n    training_instance_type = ParameterString(\n        name=\"TrainingInstanceType\", default_value=\"ml.m5.xlarge\"\n    )\n    model_approval_status = ParameterString(\n        name=\"ModelApprovalStatus\",\n        default_value=\"Approved\",  # ModelApprovalStatus can be set to a default of \"Approved\" if you don't want manual approval.\n    )\n    input_data = ParameterString(\n        name=\"InputDataUrl\",\n        default_value=f\"s3://{sagemaker_session.default_bucket()}/sagemaker/DEMO-xgboost-churn/data/RawData.csv\",  # Change this to point to the s3 location of your raw input data.\n    )\n\n    # Processing step for feature engineering\n    sklearn_processor = SKLearnProcessor(\n        framework_version=\"0.23-1\",\n        instance_type=processing_instance_type,\n        instance_count=processing_instance_count,\n        base_job_name=f\"{base_job_prefix}/sklearn-CustomerChurn-preprocess\",  # choose any name\n        sagemaker_session=sagemaker_session,\n        role=role,\n    )\n    step_process = ProcessingStep(\n        name=\"CustomerChurnProcess\",  # choose any name\n        processor=sklearn_processor,\n        outputs=[\n            ProcessingOutput(output_name=\"train\", source=\"/opt/ml/processing/train\"),\n            ProcessingOutput(output_name=\"validation\", source=\"/opt/ml/processing/validation\"),\n            ProcessingOutput(output_name=\"test\", source=\"/opt/ml/processing/test\"),\n        ],\n        code=os.path.join(BASE_DIR, \"preprocess.py\"),\n        job_arguments=[\"--input-data\", input_data],\n    )\n\n    # Training step for generating model artifacts\n    model_path = f\"s3://{sagemaker_session.default_bucket()}/{base_job_prefix}/CustomerChurnTrain\"\n    image_uri = sagemaker.image_uris.retrieve(\n        framework=\"xgboost\",  # we are using the Sagemaker built in xgboost algorithm\n        region=region,\n        version=\"1.0-1\",\n        py_version=\"py3\",\n        instance_type=training_instance_type,\n    )\n    xgb_train = Estimator(\n        image_uri=image_uri,\n        instance_type=training_instance_type,\n        instance_count=1,\n        output_path=model_path,\n        base_job_name=f\"{base_job_prefix}/CustomerChurn-train\",\n        sagemaker_session=sagemaker_session,\n        role=role,\n    )\n    xgb_train.set_hyperparameters(\n        objective=\"binary:logistic\",\n        num_round=50,\n        max_depth=5,\n        eta=0.2,\n        gamma=4,\n        min_child_weight=6,\n        subsample=0.7,\n        silent=0,\n    )\n    step_train = TrainingStep(\n        name=\"CustomerChurnTrain\",\n        estimator=xgb_train,\n        inputs={\n            \"train\": TrainingInput(\n                s3_data=step_process.properties.ProcessingOutputConfig.Outputs[\n                    \"train\"\n                ].S3Output.S3Uri,\n                content_type=\"text/csv\",\n            ),\n            \"validation\": TrainingInput(\n                s3_data=step_process.properties.ProcessingOutputConfig.Outputs[\n                    \"validation\"\n                ].S3Output.S3Uri,\n                content_type=\"text/csv\",\n            ),\n        },\n    )\n\n    # Processing step for evaluation\n    script_eval = ScriptProcessor(\n        image_uri=image_uri,\n        command=[\"python3\"],\n        instance_type=processing_instance_type,\n        instance_count=1,\n        base_job_name=f\"{base_job_prefix}/script-CustomerChurn-eval\",\n        sagemaker_session=sagemaker_session,\n        role=role,\n    )\n    evaluation_report = PropertyFile(\n        name=\"EvaluationReport\",\n        output_name=\"evaluation\",\n        path=\"evaluation.json\",\n    )\n    step_eval = ProcessingStep(\n        name=\"CustomerChurnEval\",\n        processor=script_eval,\n        inputs=[\n            ProcessingInput(\n                source=step_train.properties.ModelArtifacts.S3ModelArtifacts,\n                destination=\"/opt/ml/processing/model\",\n            ),\n            ProcessingInput(\n                source=step_process.properties.ProcessingOutputConfig.Outputs[\n                    \"test\"\n                ].S3Output.S3Uri,\n                destination=\"/opt/ml/processing/test\",\n            ),\n        ],\n        outputs=[\n            ProcessingOutput(output_name=\"evaluation\", source=\"/opt/ml/processing/evaluation\"),\n        ],\n        code=os.path.join(BASE_DIR, \"evaluate.py\"),\n        property_files=[evaluation_report],\n    )\n\n    # Register model step that will be conditionally executed\n    model_metrics = ModelMetrics(\n        model_statistics=MetricsSource(\n            s3_uri=\"{}/evaluation.json\".format(\n                step_eval.arguments[\"ProcessingOutputConfig\"][\"Outputs\"][0][\"S3Output\"][\"S3Uri\"]\n            ),\n            content_type=\"application/json\",\n        )\n    )\n\n    # Register model step that will be conditionally executed\n    step_register = RegisterModel(\n        name=\"CustomerChurnRegisterModel\",\n        estimator=xgb_train,\n        model_data=step_train.properties.ModelArtifacts.S3ModelArtifacts,\n        content_types=[\"text/csv\"],\n        response_types=[\"text/csv\"],\n        inference_instances=[\"ml.t2.medium\", \"ml.m5.large\"],\n        transform_instances=[\"ml.m5.large\"],\n        model_package_group_name=model_package_group_name,\n        approval_status=model_approval_status,\n        model_metrics=model_metrics,\n    )\n\n    # Condition step for evaluating model quality and branching execution\n    cond_lte = ConditionGreaterThanOrEqualTo(  # You can change the condition here\n        left=JsonGet(\n            step_name=step_eval.name,\n            property_file=evaluation_report,\n            json_path=\"binary_classification_metrics.accuracy.value\",  # This should follow the structure of your report_dict defined in the evaluate.py file.\n        ),\n        right=0.8,  # You can change the threshold here\n    )\n    step_cond = ConditionStep(\n        name=\"CustomerChurnAccuracyCond\",\n        conditions=[cond_lte],\n        if_steps=[step_register],\n        else_steps=[],\n    )\n\n    # Pipeline instance\n    pipeline = Pipeline(\n        name=pipeline_name,\n        parameters=[\n            processing_instance_type,\n            processing_instance_count,\n            training_instance_type,\n            model_approval_status,\n            input_data,\n        ],\n        steps=[step_process, step_train, step_eval, step_cond],\n        sagemaker_session=sagemaker_session,\n    )\n    return pipeline\n"
  },
  {
    "path": "samples/mlops-sagemaker-github-codepipeline-codebuild-codedeploy/modelbuild_pipeline/pipelines/customer_churn/preprocess.py",
    "content": "# Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"). You\n# may not use this file except in compliance with the License. A copy of\n# the License is located at\n#\n#     http://aws.amazon.com/apache2.0/\n#\n# or in the \"license\" file accompanying this file. This file is\n# distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF\n# ANY KIND, either express or implied. See the License for the specific\n# language governing permissions and limitations under the License.\n\"\"\"Feature engineers the customer churn dataset.\"\"\"\nimport argparse\nimport logging\nimport pathlib\n\nimport boto3\nimport numpy as np\nimport pandas as pd\n\nlogger = logging.getLogger()\nlogger.setLevel(logging.INFO)\nlogger.addHandler(logging.StreamHandler())\n\nif __name__ == \"__main__\":\n    logger.info(\"Starting preprocessing.\")\n    parser = argparse.ArgumentParser()\n    parser.add_argument(\"--input-data\", type=str, required=True)\n    args = parser.parse_args()\n\n    base_dir = \"/opt/ml/processing\"\n    pathlib.Path(f\"{base_dir}/data\").mkdir(parents=True, exist_ok=True)\n    input_data = args.input_data\n    print(input_data)\n    bucket = input_data.split(\"/\")[2]\n    key = \"/\".join(input_data.split(\"/\")[3:])\n\n    logger.info(\"Downloading data from bucket: %s, key: %s\", bucket, key)\n    fn = f\"{base_dir}/data/raw-data.csv\"\n    s3 = boto3.resource(\"s3\")\n    s3.Bucket(bucket).download_file(key, fn)\n\n    logger.info(\"Reading downloaded data.\")\n\n    # read in csv\n    df = pd.read_csv(fn)\n\n    # drop the \"Phone\" feature column\n    df = df.drop([\"Phone\"], axis=1)\n\n    # Change the data type of \"Area Code\"\n    df[\"Area Code\"] = df[\"Area Code\"].astype(object)\n\n    # Drop several other columns\n    df = df.drop([\"Day Charge\", \"Eve Charge\", \"Night Charge\", \"Intl Charge\"], axis=1)\n\n    # Convert categorical variables into dummy/indicator variables.\n    model_data = pd.get_dummies(df)\n\n    # Create one binary classification target column\n    model_data = pd.concat(\n        [\n            model_data[\"Churn?_True.\"],\n            model_data.drop([\"Churn?_False.\", \"Churn?_True.\"], axis=1),\n        ],\n        axis=1,\n    )\n\n    # Split the data\n    train_data, validation_data, test_data = np.split(\n        model_data.sample(frac=1, random_state=1729),\n        [int(0.7 * len(model_data)), int(0.9 * len(model_data))],\n    )\n\n    pd.DataFrame(train_data).to_csv(\n        f\"{base_dir}/train/train.csv\", header=False, index=False\n    )\n    pd.DataFrame(validation_data).to_csv(\n        f\"{base_dir}/validation/validation.csv\", header=False, index=False\n    )\n    pd.DataFrame(test_data).to_csv(\n        f\"{base_dir}/test/test.csv\", header=False, index=False\n    )\n"
  },
  {
    "path": "samples/mlops-sagemaker-github-codepipeline-codebuild-codedeploy/modelbuild_pipeline/pipelines/get_pipeline_definition.py",
    "content": "# Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"). You\n# may not use this file except in compliance with the License. A copy of\n# the License is located at\n#\n#     http://aws.amazon.com/apache2.0/\n#\n# or in the \"license\" file accompanying this file. This file is\n# distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF\n# ANY KIND, either express or implied. See the License for the specific\n# language governing permissions and limitations under the License.\n\"\"\"A CLI to get pipeline definitions from pipeline modules.\"\"\"\nfrom __future__ import absolute_import\n\nimport argparse\nimport sys\n\nfrom pipelines._utils import get_pipeline_driver\n\n\ndef main():  # pragma: no cover\n    \"\"\"The main harness that gets the pipeline definition JSON.\n\n    Prints the json to stdout or saves to file.\n    \"\"\"\n    parser = argparse.ArgumentParser(\"Gets the pipeline definition for the pipeline script.\")\n\n    parser.add_argument(\n        \"-n\",\n        \"--module-name\",\n        dest=\"module_name\",\n        type=str,\n        help=\"The module name of the pipeline to import.\",\n    )\n    parser.add_argument(\n        \"-f\",\n        \"--file-name\",\n        dest=\"file_name\",\n        type=str,\n        default=None,\n        help=\"The file to output the pipeline definition json to.\",\n    )\n    parser.add_argument(\n        \"-kwargs\",\n        \"--kwargs\",\n        dest=\"kwargs\",\n        default=None,\n        help=\"Dict string of keyword arguments for the pipeline generation (if supported)\",\n    )\n    args = parser.parse_args()\n\n    if args.module_name is None:\n        parser.print_help()\n        sys.exit(2)\n\n    try:\n        pipeline = get_pipeline_driver(args.module_name, args.kwargs)\n        content = pipeline.definition()\n        if args.file_name:\n            with open(args.file_name, \"w\") as f:\n                f.write(content)\n        else:\n            print(content)\n    except Exception as e:  # pylint: disable=W0703\n        print(f\"Exception: {e}\")\n        sys.exit(1)\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "samples/mlops-sagemaker-github-codepipeline-codebuild-codedeploy/modelbuild_pipeline/pipelines/run_pipeline.py",
    "content": "# Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"). You\n# may not use this file except in compliance with the License. A copy of\n# the License is located at\n#\n#     http://aws.amazon.com/apache2.0/\n#\n# or in the \"license\" file accompanying this file. This file is\n# distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF\n# ANY KIND, either express or implied. See the License for the specific\n# language governing permissions and limitations under the License.\n\"\"\"A CLI to create or update and run pipelines.\"\"\"\nfrom __future__ import absolute_import\n\nimport argparse\nimport json\nimport sys\n\nfrom pipelines._utils import get_pipeline_driver, convert_struct\n\n\ndef main():  # pragma: no cover\n    \"\"\"The main harness that creates or updates and runs the pipeline.\n\n    Creates or updates the pipeline and runs it.\n    \"\"\"\n    parser = argparse.ArgumentParser(\n        \"Creates or updates and runs the pipeline for the pipeline script.\"\n    )\n\n    parser.add_argument(\n        \"-n\",\n        \"--module-name\",\n        dest=\"module_name\",\n        type=str,\n        help=\"The module name of the pipeline to import.\",\n    )\n    parser.add_argument(\n        \"-kwargs\",\n        \"--kwargs\",\n        dest=\"kwargs\",\n        default=None,\n        help=\"Dict string of keyword arguments for the pipeline generation (if supported)\",\n    )\n    parser.add_argument(\n        \"-role-arn\",\n        \"--role-arn\",\n        dest=\"role_arn\",\n        type=str,\n        help=\"The role arn for the pipeline service execution role.\",\n    )\n    parser.add_argument(\n        \"-description\",\n        \"--description\",\n        dest=\"description\",\n        type=str,\n        default=None,\n        help=\"The description of the pipeline.\",\n    )\n    parser.add_argument(\n        \"-tags\",\n        \"--tags\",\n        dest=\"tags\",\n        default=None,\n        help=\"\"\"List of dict strings of '[{\"Key\": \"string\", \"Value\": \"string\"}, ..]'\"\"\",\n    )\n    args = parser.parse_args()\n\n    if args.module_name is None or args.role_arn is None:\n        parser.print_help()\n        sys.exit(2)\n    tags = convert_struct(args.tags)\n\n    try:\n        pipeline = get_pipeline_driver(args.module_name, args.kwargs)\n        print(\"###### Creating/updating a SageMaker Pipeline with the following definition:\")\n        parsed = json.loads(pipeline.definition())\n        print(json.dumps(parsed, indent=2, sort_keys=True))\n\n        upsert_response = pipeline.upsert(\n            role_arn=args.role_arn, description=args.description, tags=tags\n        )\n        print(\"\\n###### Created/Updated SageMaker Pipeline: Response received:\")\n        print(upsert_response)\n\n        execution = pipeline.start()\n        print(f\"\\n###### Execution started with PipelineExecutionArn: {execution.arn}\")\n\n        print(\"Waiting for the execution to finish...\")\n        execution.wait()\n        print(\"\\n#####Execution completed. Execution step details:\")\n\n        print(execution.list_steps())\n        # Todo print the status?\n    except Exception as e:  # pylint: disable=W0703\n        print(f\"Exception: {e}\")\n        sys.exit(1)\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "samples/mlops-sagemaker-github-codepipeline-codebuild-codedeploy/modelbuild_pipeline/setup.cfg",
    "content": "[tool:pytest]\naddopts =\n    -vv\ntestpaths = tests\n\n[aliases]\ntest=pytest\n\n[metadata]\ndescription-file = README.md\nlicense_file = LICENSE\n\n[wheel]\nuniversal = 1\n"
  },
  {
    "path": "samples/mlops-sagemaker-github-codepipeline-codebuild-codedeploy/modelbuild_pipeline/setup.py",
    "content": "import os\nimport setuptools\n\n\nabout = {}\nhere = os.path.abspath(os.path.dirname(__file__))\nwith open(os.path.join(here, \"pipelines\", \"__version__.py\")) as f:\n    exec(f.read(), about)\n\n\nwith open(\"README.md\", \"r\") as f:\n    readme = f.read()\n\n\nrequired_packages = [\"sagemaker\"]\nextras = {\n    \"test\": [\n        \"black\",\n        \"coverage\",\n        \"flake8\",\n        \"mock\",\n        \"pydocstyle\",\n        \"pytest\",\n        \"pytest-cov\",\n        \"sagemaker\",\n        \"tox\",\n    ]\n}\nsetuptools.setup(\n    name=about[\"__title__\"],\n    description=about[\"__description__\"],\n    version=about[\"__version__\"],\n    author=about[\"__author__\"],\n    author_email=[\"__author_email__\"],\n    long_description=readme,\n    long_description_content_type=\"text/markdown\",\n    url=about[\"__url__\"],\n    license=about[\"__license__\"],\n    packages=setuptools.find_packages(),\n    include_package_data=True,\n    python_requires=\">=3.6\",\n    install_requires=required_packages,\n    extras_require=extras,\n    entry_points={\n        \"console_scripts\": [\n            \"get-pipeline-definition=pipelines.get_pipeline_definition:main\",\n            \"run-pipeline=pipelines.run_pipeline:main\",\n        ]\n    },\n    classifiers=[\n        \"Development Status :: 3 - Alpha\",\n        \"Intended Audience :: Developers\",\n        \"Natural Language :: English\",\n        \"Programming Language :: Python\",\n        \"Programming Language :: Python :: 3\",\n        \"Programming Language :: Python :: 3.6\",\n        \"Programming Language :: Python :: 3.7\",\n        \"Programming Language :: Python :: 3.8\",\n    ],\n)\n"
  },
  {
    "path": "samples/mlops-sagemaker-github-codepipeline-codebuild-codedeploy/modelbuild_pipeline/tests/test_pipelines.py",
    "content": "import pytest\n\n\n@pytest.mark.xfail\ndef test_that_you_wrote_tests():\n    assert False, \"No tests written\"\n\n\ndef test_pipelines_importable():\n    import pipelines  # noqa: F401\n"
  },
  {
    "path": "samples/mlops-sagemaker-github-codepipeline-codebuild-codedeploy/modelbuild_pipeline/tox.ini",
    "content": "# Tox (http://tox.testrun.org/) is a tool for running tests\n# in multiple virtualenvs. This configuration file will run the\n# test suite on all supported python versions. To use it, \"pip install tox\"\n# and then run \"tox\" from this directory.\n\n[tox]\nenvlist = black-format,flake8,pydocstyle,py{36,37,38}\n\n[flake8]\nmax-line-length = 120\nexclude =\n    build/\n    .git\n    __pycache__\n    .tox\n    venv/\n\nmax-complexity = 10\n\nignore =\n    C901,\n    E203,  # whitespace before ':': Black disagrees with and explicitly violates this.\n    FI10,\n    FI12,\n    FI13,\n    FI14,\n    FI15,\n    FI16,\n    FI17,\n    FI18,  # __future__ import \"annotations\" missing -> check only Python 3.7 compatible\n    FI50,\n    FI51,\n    FI52,\n    FI53,\n    FI54,\n    FI55,\n    FI56,\n    FI57,\n    W503\n\nrequire-code = True\n\n[testenv]\ncommands =\n    pytest --cov=pipelines --cov-append {posargs}\n    coverage report --fail-under=0\ndeps = .[test]\ndepends =\n    {py36,py37,py38}: clean\n\n[testenv:flake8]\nskipdist = true\nskip_install = true\ndeps = flake8\ncommands = flake8\n\n[testenv:black-format]\ndeps = black\ncommands =\n    black -l 100 ./\n\n[testenv:black-check]\ndeps = black\ncommands =\n    black -l 100 --check ./\n\n[testenv:clean]\nskip_install = true\ndeps = coverage\ncommands = coverage erase\n\n[testenv:pydocstyle]\ndeps = pydocstyle\ncommands = \n    pydocstyle pipelines\n"
  },
  {
    "path": "samples/mlops-sagemaker-github-codepipeline-codebuild-codedeploy/modeldeploy_pipeline/README.md",
    "content": "# modeldeploy_pipeline\n"
  },
  {
    "path": "samples/mlops-sagemaker-github-codepipeline-codebuild-codedeploy/modeldeploy_pipeline/build.py",
    "content": "import argparse\nimport json\nimport logging\nimport os\n\nimport boto3\nfrom botocore.exceptions import ClientError\n\nlogger = logging.getLogger(__name__)\nsm_client = boto3.client(\"sagemaker\")\n\n\ndef get_approved_package(model_package_group_name):\n    \"\"\"Gets the latest approved model package for a model package group.\n\n    Args:\n        model_package_group_name: The model package group name.\n\n    Returns:\n        The SageMaker Model Package ARN.\n    \"\"\"\n    try:\n        # Get the latest approved model package\n        response = sm_client.list_model_packages(\n            ModelPackageGroupName=model_package_group_name,\n            ModelApprovalStatus=\"Approved\",\n            SortBy=\"CreationTime\",\n            MaxResults=100,\n        )\n        approved_packages = response[\"ModelPackageSummaryList\"]\n\n        # Fetch more packages if none returned with continuation token\n        while len(approved_packages) == 0 and \"NextToken\" in response:\n            logger.debug(\"Getting more packages for token: {}\".format(response[\"NextToken\"]))\n            response = sm_client.list_model_packages(\n                ModelPackageGroupName=model_package_group_name,\n                ModelApprovalStatus=\"Approved\",\n                SortBy=\"CreationTime\",\n                MaxResults=100,\n                NextToken=response[\"NextToken\"],\n            )\n            approved_packages.extend(response[\"ModelPackageSummaryList\"])\n\n        # Return error if no packages found\n        if len(approved_packages) == 0:\n            error_message = (\n                f\"No approved ModelPackage found for ModelPackageGroup: {model_package_group_name}\"\n            )\n            logger.error(error_message)\n            raise Exception(error_message)\n\n        # Return the pmodel package arn\n        model_package_arn = approved_packages[0][\"ModelPackageArn\"]\n        logger.info(f\"Identified the latest approved model package: {model_package_arn}\")\n        return model_package_arn\n    except ClientError as e:\n        error_message = e.response[\"Error\"][\"Message\"]\n        logger.error(error_message)\n        raise Exception(error_message)\n\n\ndef extend_config(args, model_package_arn, stage_config):\n    \"\"\"\n    Extend the stage configuration with additional parameters and tags based.\n    \"\"\"\n    # Verify that config has parameters and tags sections\n    if not \"Parameters\" in stage_config or not \"StageName\" in stage_config[\"Parameters\"]:\n        raise Exception(\"Configuration file must include SageName parameter\")\n    if not \"Tags\" in stage_config:\n        stage_config[\"Tags\"] = {}\n    # Create new params and tags\n    new_params = {\n        \"SageMakerProjectName\": args.sagemaker_project_name,\n        \"ModelPackageName\": model_package_arn,\n        \"ModelExecutionRoleArn\": args.model_execution_role,\n    }\n    new_tags = {\n        \"sagemaker:deployment-stage\": stage_config[\"Parameters\"][\"StageName\"],\n        \"sagemaker:project-id\": args.sagemaker_project_id,\n        \"sagemaker:project-name\": args.sagemaker_project_name,\n    }\n    return {\n        \"Parameters\": {**stage_config[\"Parameters\"], **new_params},\n        \"Tags\": {**stage_config.get(\"Tags\", {}), **new_tags},\n    }\n\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser()\n    parser.add_argument(\"--log-level\", type=str, default=os.environ.get(\"LOGLEVEL\", \"INFO\").upper())\n    parser.add_argument(\"--model-execution-role\", type=str, required=True)\n    parser.add_argument(\"--model-package-group-name\", type=str, required=True)\n    parser.add_argument(\"--sagemaker-project-id\", type=str, required=True)\n    parser.add_argument(\"--sagemaker-project-name\", type=str, required=True)\n    parser.add_argument(\"--import-staging-config\", type=str, default=\"staging-config.json\")\n    parser.add_argument(\"--import-prod-config\", type=str, default=\"prod-config.json\")\n    parser.add_argument(\"--export-staging-config\", type=str, default=\"staging-config-export.json\")\n    parser.add_argument(\"--export-prod-config\", type=str, default=\"prod-config-export.json\")\n    args, _ = parser.parse_known_args()\n\n    # Configure logging to output the line number and message\n    log_format = \"%(levelname)s: [%(filename)s:%(lineno)s] %(message)s\"\n    logging.basicConfig(format=log_format, level=args.log_level)\n\n    # Get the latest approved package\n    model_package_arn = get_approved_package(args.model_package_group_name)\n\n    # Write the staging config\n    with open(args.import_staging_config, \"r\") as f:\n        staging_config = extend_config(args, model_package_arn, json.load(f))\n    logger.debug(\"Staging config: {}\".format(json.dumps(staging_config, indent=4)))\n    with open(args.export_staging_config, \"w\") as f:\n        json.dump(staging_config, f, indent=4)\n\n    # Write the prod config\n    with open(args.import_prod_config, \"r\") as f:\n        prod_config = extend_config(args, model_package_arn, json.load(f))\n    logger.debug(\"Prod config: {}\".format(json.dumps(prod_config, indent=4)))\n    with open(args.export_prod_config, \"w\") as f:\n        json.dump(prod_config, f, indent=4)\n"
  },
  {
    "path": "samples/mlops-sagemaker-github-codepipeline-codebuild-codedeploy/modeldeploy_pipeline/endpoint-config-template.yml",
    "content": "Description:\n  This template is built and deployed by the infrastructure pipeline in various stages (staging/production) as required.\n  It specifies the resources that need to be created, like the SageMaker Endpoint. It can be extended to include resources like\n  AutoScalingPolicy, API Gateway, etc,. as required.\nParameters:\n  SageMakerProjectName:\n    Type: String\n    Description: Name of the project\n    MinLength: 1\n    MaxLength: 32\n    AllowedPattern: ^[a-zA-Z](-*[a-zA-Z0-9])*\n  ModelExecutionRoleArn:\n    Type: String\n    Description: Execution role used for deploying the model.\n  ModelPackageName:\n    Type: String\n    Description: The trained Model Package Name\n  StageName:\n    Type: String\n    Description:\n      The name for a project pipeline stage, such as Staging or Prod, for\n      which resources are provisioned and deployed.\n  EndpointInstanceCount:\n    Type: Number\n    Description: Number of instances to launch for the endpoint.\n    MinValue: 1\n  EndpointInstanceType:\n    Type: String\n    Description: The ML compute instance type for the endpoint.\n\nResources:\n  Model:\n    Type: AWS::SageMaker::Model\n    Properties:\n      PrimaryContainer:\n        ModelPackageName: !Ref ModelPackageName\n      ExecutionRoleArn: !Ref ModelExecutionRoleArn\n\n  EndpointConfig:\n    Type: AWS::SageMaker::EndpointConfig\n    Properties:\n      ProductionVariants:\n        - InitialInstanceCount: !Ref EndpointInstanceCount\n          InitialVariantWeight: 1.0\n          InstanceType: !Ref EndpointInstanceType\n          ModelName: !GetAtt Model.ModelName\n          VariantName: AllTraffic\n\n  Endpoint:\n    Type: AWS::SageMaker::Endpoint\n    Properties:\n      EndpointName: !Sub ${SageMakerProjectName}-${StageName}\n      EndpointConfigName: !GetAtt EndpointConfig.EndpointConfigName\n"
  },
  {
    "path": "samples/mlops-sagemaker-github-codepipeline-codebuild-codedeploy/modeldeploy_pipeline/fix_model_permission.py",
    "content": "import argparse\nimport boto3\nimport json\nimport os\nimport logging\nfrom botocore.exceptions import ClientError\n\n# this script is a workaround to fix some permission issues with the file\n# created for the model and stored in an S3 bucket\n\ns3_client = boto3.client('s3')\nsm_client = boto3.client('sagemaker')\n \nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser()\n    parser.add_argument(\"--log-level\", type=str, default=os.environ.get(\"LOGLEVEL\", \"INFO\").upper())\n    parser.add_argument(\"--prod-config-file\", type=str, default=\"prod-config-export.json\")\n\n    args, _ = parser.parse_known_args()\n\n    # Configure logging to output the line number and message\n    log_format = \"%(levelname)s: [%(filename)s:%(lineno)s] %(message)s\"\n    logging.basicConfig(format=log_format, level=args.log_level)\n\n    # first retrieve the name of the package that will be deployed\n    model_package_name = None\n    with open(args.prod_config_file, 'r') as f:\n        for param in json.loads(f.read()):\n            if param.get('ParameterKey') == 'ModelPackageName':\n                model_package_name = param.get('ParameterValue')\n    if model_package_name is None:\n        raise Exception(\"Configuration file must include ModelPackageName parameter\")\n        \n    # then, describe it to get the S3 URL of the model\n    resp = sm_client.describe_model_package(ModelPackageName=model_package_name)\n    model_data_url = resp['InferenceSpecification']['Containers'][0]['ModelDataUrl']\n    _,_,bucket_name,key = model_data_url.split('/', 3)\n\n    # finally, copy the file to override the permissions\n    with open('/tmp/model.tar.gz', 'wb') as data:\n        s3_client.download_fileobj(bucket_name, key, data)\n    with open('/tmp/model.tar.gz', 'rb') as data:\n        s3_client.upload_fileobj(data, bucket_name, key)\n \n"
  },
  {
    "path": "samples/mlops-sagemaker-github-codepipeline-codebuild-codedeploy/modeldeploy_pipeline/prod-config.json",
    "content": "{\n  \"Parameters\": {\n    \"StageName\": \"prod-0306\",\n    \"EndpointInstanceCount\": \"1\",\n    \"EndpointInstanceType\": \"ml.m5.large\"\n  }\n}"
  },
  {
    "path": "samples/mlops-sagemaker-github-codepipeline-codebuild-codedeploy/modeldeploy_pipeline/setup.py",
    "content": "import argparse\nimport json\nimport logging\nimport os\nimport argparse\nimport boto3\nfrom botocore.exceptions import ClientError\n\nlogger = logging.getLogger(__name__)\nsm_client = boto3.client(\"sagemaker\")\norg_client = boto3.client(\"organizations\")\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser()\n    parser.add_argument(\"--log-level\", type=str, default=os.environ.get(\"LOGLEVEL\", \"INFO\").upper())\n    parser.add_argument(\"--sagemaker-project-id\", type=str, required=True)\n    parser.add_argument(\"--sagemaker-project-name\", type=str, required=True)\n    parser.add_argument(\"--model-package-group-name\", type=str, required=True)\n    parser.add_argument(\"--organizational-unit-staging-id\", type=str, required=True)\n    parser.add_argument(\"--organizational-unit-prod-id\", type=str, required=True)\n\n    args, _ = parser.parse_known_args()\n\n    # Configure logging to output the line number and message\n    log_format = \"%(levelname)s: [%(filename)s:%(lineno)s] %(message)s\"\n    logging.basicConfig(format=log_format, level=args.log_level)\n    model_package_group_arn = None \n    # Create model package group if necessary\n    try:\n        # check if the model package group exists\n        resp = sm_client.describe_model_package_group(\n            ModelPackageGroupName=args.model_package_group_name)\n        model_package_group_arn = resp['ModelPackageGroupArn']\n    except ClientError as e:\n        if e.response['Error']['Code'] == 'ValidationException':\n            # it doesn't exist, lets create a new one\n            resp = sm_client.create_model_package_group(\n                ModelPackageGroupName=args.model_package_group_name,\n                ModelPackageGroupDescription=\"Multi account model group\",\n                Tags=[\n                    {'Key': 'sagemaker:project-name', 'Value': args.sagemaker_project_name},\n                    {'Key': 'sagemaker:project-id', 'Value': args.sagemaker_project_id},\n                ]\n            )\n            model_package_group_arn = resp['ModelPackageGroupArn']\n        else:\n            raise e\n    staging_ou_id = args.organizational_unit_staging_id\n    prod_ou_id = args.organizational_unit_prod_id\n\n    # finally, we need to update the model package group policy\n    # Get the account principals based on staging and prod ids\n    staging_accounts = [i['Id'] for i in org_client.list_accounts_for_parent(ParentId=staging_ou_id)['Accounts']]\n    prod_accounts = [i['Id'] for i in org_client.list_accounts_for_parent(ParentId=prod_ou_id)['Accounts']]\n    # update the policy\n    sm_client.put_model_package_group_policy(\n        ModelPackageGroupName=args.model_package_group_name,\n        ResourcePolicy=json.dumps({\n            'Version': '2012-10-17',\n            'Statement': [{\n                'Sid': 'Stmt1527884065456',\n                'Effect': 'Allow',\n                'Principal': {'AWS': ['arn:aws:iam::%s:root' % i for i in staging_accounts + prod_accounts] },\n                'Action': 'sagemaker:CreateModel',\n                'Resource': '%s/*' % model_package_group_arn.replace('model-package-group', 'model-package')\n            }]\n        })\n    )\n            \n    \n"
  },
  {
    "path": "samples/mlops-sagemaker-github-codepipeline-codebuild-codedeploy/modeldeploy_pipeline/staging-config.json",
    "content": "{\n  \"Parameters\": {\n    \"StageName\": \"staging-0306\",\n    \"EndpointInstanceCount\": \"1\",\n    \"EndpointInstanceType\": \"ml.m5.large\"\n  }\n}\n"
  },
  {
    "path": "samples/mlops-sagemaker-github-codepipeline-codebuild-codedeploy/modeldeploy_pipeline/test/test.py",
    "content": "import argparse\nimport json\nimport logging\nimport os\n\nimport boto3\nfrom botocore.exceptions import ClientError\n\nlogger = logging.getLogger(__name__)\nsm_client = boto3.client(\"sagemaker\")\n\n\ndef invoke_endpoint(endpoint_name):\n    \"\"\"\n    Add custom logic here to invoke the endpoint and validate reponse\n    \"\"\"\n    return {\"endpoint_name\": endpoint_name, \"success\": True}\n\n\ndef test_endpoint(endpoint_name):\n    \"\"\"\n    Describe the endpoint and ensure InSerivce, then invoke endpoint.  Raises exception on error.\n    \"\"\"\n    error_message = None\n    try:\n        # Ensure endpoint is in service\n        response = sm_client.describe_endpoint(EndpointName=endpoint_name)\n        status = response[\"EndpointStatus\"]\n        if status != \"InService\":\n            error_message = f\"SageMaker endpoint: {endpoint_name} status: {status} not InService\"\n            logger.error(error_message)\n            raise Exception(error_message)\n\n        # Output if endpoint has data capture enbaled\n        endpoint_config_name = response[\"EndpointConfigName\"]\n        response = sm_client.describe_endpoint_config(EndpointConfigName=endpoint_config_name)\n        if \"DataCaptureConfig\" in response and response[\"DataCaptureConfig\"][\"EnableCapture\"]:\n            logger.info(f\"data capture enabled for endpoint config {endpoint_config_name}\")\n\n        # Call endpoint to handle\n        return invoke_endpoint(endpoint_name)\n    except ClientError as e:\n        error_message = e.response[\"Error\"][\"Message\"]\n        logger.error(error_message)\n        raise Exception(error_message)\n\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser()\n    parser.add_argument(\"--log-level\", type=str, default=os.environ.get(\"LOGLEVEL\", \"INFO\").upper())\n    parser.add_argument(\"--import-build-config\", type=str, required=True)\n    parser.add_argument(\"--export-test-results\", type=str, required=True)\n    args, _ = parser.parse_known_args()\n\n    # Configure logging to output the line number and message\n    log_format = \"%(levelname)s: [%(filename)s:%(lineno)s] %(message)s\"\n    logging.basicConfig(format=log_format, level=args.log_level)\n\n    # Load the build config\n    with open(args.import_build_config, \"r\") as f:\n        config = json.load(f)\n\n    # Get the endpoint name from sagemaker project name\n    endpoint_name = \"{}-{}\".format(\n        config[\"Parameters\"][\"SageMakerProjectName\"], config[\"Parameters\"][\"StageName\"]\n    )\n    results = test_endpoint(endpoint_name)\n\n    # Print results and write to file\n    logger.debug(json.dumps(results, indent=4))\n    with open(args.export_test_results, \"w\") as f:\n        json.dump(results, f, indent=4)\n"
  },
  {
    "path": "samples/mlops-sagemaker-github-codepipeline-codebuild-codedeploy/modeldeploy_pipeline/test/test_buildspec.yml",
    "content": "version: 0.2\n\nphases:\n  install:\n    runtime-versions:\n      python: 3.8\n  build:\n    commands:\n      # Call the test python code\n      - python test/test.py --import-build-config $CODEBUILD_SRC_DIR_BuildArtifact/staging-config-export.json --export-test-results ${EXPORT_TEST_RESULTS}\n      # Show the test results file\n      - cat ${EXPORT_TEST_RESULTS}\n\nartifacts:\n  files:\n    - ${EXPORT_TEST_RESULTS}\n"
  },
  {
    "path": "samples/mlops-sagemaker-github-codepipeline-codebuild-codedeploy/modeldeploy_pipeline/test/test_buildspec_singleaccount.yml",
    "content": "version: 0.2\n\nphases:\n  install:\n    runtime-versions:\n      python: 3.8\n  build:\n    commands:\n      # Call the test python code\n      - python test/test.py --import-build-config $CODEBUILD_SRC_DIR_BuildArtifact/staging-config-export.json --export-test-results ${EXPORT_TEST_RESULTS}\n      # Show the test results file\n      - cat ${EXPORT_TEST_RESULTS}\n\nartifacts:\n  files:\n    - ${EXPORT_TEST_RESULTS}\n"
  },
  {
    "path": "samples/mlops-sagemaker-github-codepipeline-codebuild-codedeploy/modeldeploy_pipeline/test/test_singleaccount.py",
    "content": "import argparse\nimport json\nimport logging\nimport os\n\nimport boto3\nfrom botocore.exceptions import ClientError\n\nlogger = logging.getLogger(__name__)\nsm_client = boto3.client(\"sagemaker\")\n\n\ndef invoke_endpoint(endpoint_name):\n    \"\"\"\n    Add custom logic here to invoke the endpoint and validate reponse\n    \"\"\"\n    return {\"endpoint_name\": endpoint_name, \"success\": True}\n\n\ndef test_endpoint(endpoint_name):\n    \"\"\"\n    Describe the endpoint and ensure InSerivce, then invoke endpoint.  Raises exception on error.\n    \"\"\"\n    error_message = None\n    try:\n        # Ensure endpoint is in service\n        response = sm_client.describe_endpoint(EndpointName=endpoint_name)\n        status = response[\"EndpointStatus\"]\n        if status != \"InService\":\n            error_message = f\"SageMaker endpoint: {endpoint_name} status: {status} not InService\"\n            logger.error(error_message)\n            raise Exception(error_message)\n\n        # Output if endpoint has data capture enbaled\n        endpoint_config_name = response[\"EndpointConfigName\"]\n        response = sm_client.describe_endpoint_config(EndpointConfigName=endpoint_config_name)\n        if \"DataCaptureConfig\" in response and response[\"DataCaptureConfig\"][\"EnableCapture\"]:\n            logger.info(f\"data capture enabled for endpoint config {endpoint_config_name}\")\n\n        # Call endpoint to handle\n        return invoke_endpoint(endpoint_name)\n    except ClientError as e:\n        error_message = e.response[\"Error\"][\"Message\"]\n        logger.error(error_message)\n        raise Exception(error_message)\n\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser()\n    parser.add_argument(\"--log-level\", type=str, default=os.environ.get(\"LOGLEVEL\", \"INFO\").upper())\n    parser.add_argument(\"--import-build-config\", type=str, required=True)\n    parser.add_argument(\"--export-test-results\", type=str, required=True)\n    args, _ = parser.parse_known_args()\n\n    # Configure logging to output the line number and message\n    log_format = \"%(levelname)s: [%(filename)s:%(lineno)s] %(message)s\"\n    logging.basicConfig(format=log_format, level=args.log_level)\n\n    # Load the build config\n    with open(args.import_build_config, \"r\") as f:\n        config = json.load(f)\n\n    # Get the endpoint name from sagemaker project name\n    endpoint_name = \"{}-{}\".format(\n        config[\"Parameters\"][\"SageMakerProjectName\"], config[\"Parameters\"][\"StageName\"]\n    )\n    results = test_endpoint(endpoint_name)\n\n    # Print results and write to file\n    logger.debug(json.dumps(results, indent=4))\n    with open(args.export_test_results, \"w\") as f:\n        json.dump(results, f, indent=4)\n"
  },
  {
    "path": "samples/mlops-sagemaker-github-codepipeline-codebuild-codedeploy/terraform/events.tf",
    "content": "resource \"aws_cloudwatch_event_rule\" \"sm_model_registry_rule\" {\n  name        = \"sm-model-registry-event-rule\"\n  description = \"Capture new model registry\"\n\n  event_pattern = <<EOF\n{\n  \"source\": [\n     \"aws.sagemaker\"\n ],\n \"detail-type\": [\n     \"SageMaker Model Package State Change\"\n ],\n \"detail\": {\n     \"ModelPackageGroupName\": [\"${var.project_name}-${var.project_id}\"    \n]\n }\n}\nEOF\n}\n\nresource \"aws_cloudwatch_event_target\" \"sm_model_registry\" {\n  rule      = aws_cloudwatch_event_rule.sm_model_registry_rule.name\n  target_id = \"sagemaker-${var.project_name}-registry-trigger\"\n  arn       = aws_codepipeline.sm_cd_pipeline.arn\n  role_arn  = aws_iam_role.tf_mlops_role.arn\n}\n"
  },
  {
    "path": "samples/mlops-sagemaker-github-codepipeline-codebuild-codedeploy/terraform/iam_roles.tf",
    "content": "\nresource \"aws_iam_role\" \"tf_mlops_role\" {\n  assume_role_policy = jsonencode(\n    {\n      Statement = [\n        {\n          Action = \"sts:AssumeRole\"\n          Effect = \"Allow\"\n          Principal = {\n            Service = [\n          \"firehose.amazonaws.com\",\n          \"glue.amazonaws.com\",\n          \"apigateway.amazonaws.com\",\n          \"lambda.amazonaws.com\",\n          \"events.amazonaws.com\",\n          \"states.amazonaws.com\",\n          \"sagemaker.amazonaws.com\",\n          \"cloudformation.amazonaws.com\",\n          \"codebuild.amazonaws.com\",\n          \"codepipeline.amazonaws.com\"\n        ]\n          }\n        },\n      ]\n      Version = \"2012-10-17\"\n    }\n  )\n  force_detach_policies = false\n  max_session_duration  = 3600\n  name                  = \"tf-mlops-role-${var.env}-1007\"\n  path                  = \"/service-role/\"\n  tags                  = {}\n}\n\nresource \"aws_iam_policy\" \"tf_mlops_policy\" {\n  description = \"Policy used in trust relationship with CodeBuild (${var.env})\"\n  name        = \"tf-mlops-policy-${var.env}-1007\"\n  path        = \"/service-role/\"\n  policy = jsonencode(\n    {\n      Statement = [\n        {\n          Action : [\n            \"iam:PassRole\"\n          ],\n          Resource : \"*\",\n          Effect : \"Allow\"\n        },\n        {\n          \"Effect\" = \"Allow\",\n          \"Action\" = [\n            \"s3:*\"\n          ],\n          \"Resource\" = [\n            \"arn:aws:s3:::*\",\n            \"arn:aws:s3:::*\"\n          ]\n        },\n        {\n          \"Action\" : [\n            \"logs:CreateLogGroup\",\n            \"logs:CreateLogStream\",\n            \"logs:PutLogEvents\"\n          ],\n          \"Effect\" : \"Allow\",\n          \"Resource\" : \"arn:aws:logs:*\"\n        },\n\n        {\n            \"Action\": [\n                \"codepipeline:StartPipelineExecution\"\n            ],\n            \"Resource\": \"arn:aws:codepipeline:*:*:*\",\n            \"Effect\": \"Allow\"\n        },\n        {\n            \"Action\": [\n                \"events:DeleteRule\",\n                \"events:DescribeRule\",\n                \"events:PutRule\",\n                \"events:PutTargets\",\n                \"events:RemoveTargets\"\n            ],\n            \"Resource\": [\n                \"arn:aws:events:*:*:rule/*\"\n            ],\n            \"Effect\": \"Allow\"\n        },\n        {\n            \"Effect\": \"Allow\",\n            \"Action\": [\n                \"sagemaker:*\"\n            ],\n            \"NotResource\": [\n                \"arn:aws:sagemaker:*:*:domain/*\",\n                \"arn:aws:sagemaker:*:*:user-profile/*\",\n                \"arn:aws:sagemaker:*:*:app/*\",\n                \"arn:aws:sagemaker:*:*:flow-definition/*\"\n            ]\n        },\n        {\n            \"Effect\": \"Allow\",\n            \"Action\": [\n                \"sagemaker:CreatePresignedDomainUrl\",\n                \"sagemaker:DescribeDomain\",\n                \"sagemaker:ListDomains\",\n                \"sagemaker:DescribeUserProfile\",\n                \"sagemaker:ListUserProfiles\",\n                \"sagemaker:*App\",\n                \"sagemaker:ListApps\"\n            ],\n            \"Resource\": \"*\"\n        },\n        {\n            \"Effect\": \"Allow\",\n            \"Action\": \"sagemaker:*\",\n            \"Resource\": [\n                \"arn:aws:sagemaker:*:*:flow-definition/*\"\n            ],\n            \"Condition\": {\n                \"StringEqualsIfExists\": {\n                    \"sagemaker:WorkteamType\": [\n                        \"private-crowd\",\n                        \"vendor-crowd\"\n                    ]\n                }\n            }\n        },\n        {\n            \"Action\": [\n                \"cloudformation:CreateChangeSet\",\n                \"cloudformation:CreateStack\",\n                \"cloudformation:DescribeChangeSet\",\n                \"cloudformation:DeleteChangeSet\",\n                \"cloudformation:DeleteStack\",\n                \"cloudformation:DescribeStacks\",\n                \"cloudformation:ExecuteChangeSet\",\n                \"cloudformation:SetStackPolicy\",\n                \"cloudformation:UpdateStack\"\n            ],\n            \"Resource\": \"arn:aws:cloudformation:*:*:stack/*\",\n            \"Effect\": \"Allow\"\n        },\n        {\n            \"Action\": [\n                \"codebuild:BatchGetBuilds\",\n                \"codebuild:StartBuild\"\n            ],\n            \"Resource\": [\n                \"arn:aws:codebuild:*:*:project/*\",\n                \"arn:aws:codebuild:*:*:build/*\"\n            ],\n            \"Effect\": \"Allow\"\n        },\n        {\n            \"Action\": [\n                \"states:DescribeExecution\",\n                \"states:GetExecutionHistory\",\n                \"states:StartExecution\",\n                \"states:StopExecution\",\n                \"states:UpdateStateMachine\"\n            ],\n            \"Resource\": [\n                \"arn:aws:states:*:*:statemachine:*sagemaker*\",\n                \"arn:aws:states:*:*:execution:*sagemaker*:*\"\n            ],\n            \"Effect\": \"Allow\"\n        },\n        {\n            \"Effect\": \"Allow\",\n            \"Action\": [\n                \"secretsmanager:DescribeSecret\",\n                \"secretsmanager:GetSecretValue\",\n                \"secretsmanager:CreateSecret\"\n            ],\n            \"Resource\": [\n                \"arn:aws:secretsmanager:*:*:secret:AmazonSageMaker-*\"\n            ]\n        },\n        {\n            \"Effect\": \"Allow\",\n            \"Action\": [\n                \"secretsmanager:DescribeSecret\",\n                \"secretsmanager:GetSecretValue\"\n            ],\n            \"Resource\": \"*\",\n            \"Condition\": {\n                \"StringEquals\": {\n                    \"secretsmanager:ResourceTag/SageMaker\": \"true\"\n                }\n            }\n        },\n        {\n            \"Effect\": \"Allow\",\n            \"Action\": [\n                \"s3:CreateBucket\",\n                \"s3:GetBucketLocation\",\n                \"s3:ListBucket\",\n                \"s3:ListAllMyBuckets\",\n                \"s3:GetBucketCors\",\n                \"s3:PutBucketCors\"\n            ],\n            \"Resource\": \"*\"\n        },\n        {\n            \"Effect\": \"Allow\",\n            \"Action\": [\n                \"s3:GetBucketAcl\",\n                \"s3:PutObjectAcl\"\n            ],\n            \"Resource\": [\n                \"arn:aws:s3:::*SageMaker*\",\n                \"arn:aws:s3:::*Sagemaker*\",\n                \"arn:aws:s3:::*sagemaker*\"\n            ]\n        },\n        {\n            \"Action\": [\n                \"ecr:BatchCheckLayerAvailability\",\n                \"ecr:BatchGetImage\",\n                \"ecr:Describe*\",\n                \"ecr:GetAuthorizationToken\",\n                \"ecr:GetDownloadUrlForLayer\"\n            ],\n            \"Resource\": \"*\",\n            \"Effect\": \"Allow\"\n        },\n        {\n            \"Effect\": \"Allow\",\n            \"Action\": [\n                \"ecr:BatchDeleteImage\",\n                \"ecr:CompleteLayerUpload\",\n                \"ecr:CreateRepository\",\n                \"ecr:DeleteRepository\",\n                \"ecr:InitiateLayerUpload\",\n                \"ecr:PutImage\",\n                \"ecr:UploadLayerPart\"\n            ],\n            \"Resource\": [\n                \"arn:aws:ecr:*:*:repository/sagemaker-*\"\n            ]\n        },\n        {\n            \"Action\": \"iam:CreateServiceLinkedRole\",\n            \"Effect\": \"Allow\",\n            \"Resource\": \"arn:aws:iam::*:role/aws-service-role/sagemaker.application-autoscaling.amazonaws.com/AWSServiceRoleForApplicationAutoScaling_SageMakerEndpoint\",\n            \"Condition\": {\n                \"StringLike\": {\n                    \"iam:AWSServiceName\": \"sagemaker.application-autoscaling.amazonaws.com\"\n                }\n            }\n        },\n        {\n            \"Effect\": \"Allow\",\n            \"Action\": \"iam:CreateServiceLinkedRole\",\n            \"Resource\": \"*\",\n            \"Condition\": {\n                \"StringEquals\": {\n                    \"iam:AWSServiceName\": \"robomaker.amazonaws.com\"\n                }\n            }\n        },\n        {\n            \"Effect\": \"Allow\",\n            \"Action\": [\n                \"sns:Subscribe\",\n                \"sns:CreateTopic\"\n            ],\n            \"Resource\": [\n                \"arn:aws:sns:*:*:*SageMaker*\",\n                \"arn:aws:sns:*:*:*Sagemaker*\",\n                \"arn:aws:sns:*:*:*sagemaker*\"\n            ]\n        },\n        {\n            \"Effect\": \"Allow\",\n            \"Action\": [\n                \"iam:PassRole\"\n            ],\n            \"Resource\": \"arn:aws:iam::*:role/*AmazonSageMaker*\",\n            \"Condition\": {\n                \"StringEquals\": {\n                    \"iam:PassedToService\": [\n                        \"glue.amazonaws.com\",\n                        \"robomaker.amazonaws.com\",\n                        \"states.amazonaws.com\"\n                    ]\n                }\n            }\n        },\n        {\n            \"Effect\": \"Allow\",\n            \"Action\": [\n                \"iam:PassRole\"\n            ],\n            \"Resource\": \"arn:aws:iam::*:role/*\",\n            \"Condition\": {\n                \"StringEquals\": {\n                    \"iam:PassedToService\": \"sagemaker.amazonaws.com\"\n                }\n            }\n        }\n      ]\n      Version = \"2012-10-17\"\n    }\n  )\n}\n\n\nresource \"aws_iam_role_policy_attachment\" \"tf_mlops_policy_attachment\" {\n  role       = aws_iam_role.tf_mlops_role.name\n  policy_arn = aws_iam_policy.tf_mlops_policy.arn\n}\n"
  },
  {
    "path": "samples/mlops-sagemaker-github-codepipeline-codebuild-codedeploy/terraform/main.tf",
    "content": "terraform {\n  required_providers {\n    aws = {\n      source  = \"hashicorp/aws\"\n      version = \"~> 4.16\"\n    }\n  }\n  required_version = \">= 1.2.0\"\n}\n\nprovider \"aws\" {\n  region  = var.region\n}\n\nprovider \"github\" {\n  token   = var.github_token\n  owner   = var.repository_owner\n  version = \"~> 4.0.0\"\n}\n\nprovider \"random\" {\n  version = \"~> 3.0.0\"\n}\n\nprovider \"template\" {\n  version = \"~> 2.2.0\"\n}\n"
  },
  {
    "path": "samples/mlops-sagemaker-github-codepipeline-codebuild-codedeploy/terraform/modelbuild_buildspec.yml",
    "content": "version: 0.2\n\nphases:\n  install:\n    runtime-versions:\n      python: 3.8\n    commands:\n      - pip install --upgrade --force-reinstall . awscli\n      - aws s3 cp s3://sagemaker-sample-files/datasets/tabular/synthetic/churn.txt s3://${ARTIFACT_BUCKET}/sagemaker/DEMO-xgboost-churn/data/RawData.csv \n  build:\n    commands:\n      - export PYTHONUNBUFFERED=TRUE\n      - export SAGEMAKER_PROJECT_NAME_ID=\"${SAGEMAKER_PROJECT_NAME}-${SAGEMAKER_PROJECT_ID}\" \n      - |\n        run-pipeline --module-name pipelines.customer_churn.pipeline \\\n          --role-arn ${SAGEMAKER_PIPELINE_ROLE_ARN} \\\n          --tags \"[{\\\"Key\\\":\\\"sagemaker:project-name\\\", \\\"Value\\\":\\\"${SAGEMAKER_PROJECT_NAME}\\\"}, {\\\"Key\\\":\\\"sagemaker:project-id\\\", \\\"Value\\\":\\\"${SAGEMAKER_PROJECT_ID}\\\"}]\" \\\n          --kwargs \"{\\\"region\\\":\\\"${AWS_REGION}\\\",\\\"role\\\":\\\"${SAGEMAKER_PIPELINE_ROLE_ARN}\\\",\\\"default_bucket\\\":\\\"${ARTIFACT_BUCKET}\\\",\\\"pipeline_name\\\":\\\"${SAGEMAKER_PROJECT_NAME_ID}\\\",\\\"model_package_group_name\\\":\\\"${SAGEMAKER_PROJECT_NAME_ID}\\\",\\\"base_job_prefix\\\":\\\"${SAGEMAKER_PROJECT_NAME_ID}\\\"}\"\n      - echo \"Create/Update of the SageMaker Pipeline and execution completed.\"\n \n"
  },
  {
    "path": "samples/mlops-sagemaker-github-codepipeline-codebuild-codedeploy/terraform/modelbuild_ci_pipeline.tf",
    "content": "#data \"aws_caller_identity\" \"current\" {}\nresource \"aws_codepipeline\" \"sm_ci_pipeline\" {\n  name     = \"modelbuild-pipeline\"\n  role_arn = aws_iam_role.tf_mlops_role.arn\n  tags = {\n    Environment = var.env\n  }\n\n  artifact_store {\n    location = aws_s3_bucket.artifacts_bucket.bucket\n    type     = \"S3\"\n  }\n\n  stage {\n    name = \"Source\"\n\n    action {\n      category = \"Source\"\n      configuration = {\n        \"Branch\"               = var.repository_branch\n        \"Owner\"                = var.repository_owner\n        \"PollForSourceChanges\" = \"false\"\n        \"Repo\"                 = var.build_repository_name\n        OAuthToken             = var.github_token\n      }\n\n      input_artifacts = []\n      name            = \"Source\"\n      output_artifacts = [\n        \"SourceArtifact\",\n      ]\n      owner     = \"ThirdParty\"\n      provider  = \"GitHub\"\n      run_order = 1\n      version   = \"1\"\n    }\n  }\n\n  stage {\n    name = \"Build\"\n\n    action {\n      category = \"Build\"\n      configuration = {\n        \"ProjectName\" = \"tf-mlops-modelbuild\"\n      }\n      input_artifacts = [\n        \"SourceArtifact\",\n      ]\n      name = \"Build\"\n      output_artifacts = [\n        \"BuildArtifact\",\n      ]\n      owner     = \"AWS\"\n      provider  = \"CodeBuild\"\n      run_order = 1\n      version   = \"1\"\n    }\n  }\n\n}\n"
  },
  {
    "path": "samples/mlops-sagemaker-github-codepipeline-codebuild-codedeploy/terraform/modelbuild_codebuild.tf",
    "content": "data \"template_file\" \"buildspec\" {\n  template = file(\"modelbuild_buildspec.yml\")  # connect to buildspec file\n  vars = {\n    env = var.env\n    SAGEMAKER_PROJECT_NAME=var.project_name\n    SAGEMAKER_PROJECT_ID=var.project_id\n    ARTIFACT_BUCKET=var.artifacts_bucket_name\n    SAGEMAKER_PIPELINE_ROLE_ARN=aws_iam_role.tf_mlops_role.arn\n    AWS_REGION=var.region\n    SAGEMAKER_PROJECT_NAME_ID=\"${var.project_name}-${var.project_id}\"\n  }\n}\n\nresource \"aws_codebuild_project\" \"tf_mlops_modelbuild\" {\n  badge_enabled  = false\n  build_timeout  = 60\n  name           = \"tf-mlops-modelbuild\"\n  queued_timeout = 480\n  service_role   = aws_iam_role.tf_mlops_role.arn\n  tags = {\n    Environment = var.env\n  }\n\n  artifacts {\n    encryption_disabled    = false\n    name                   = \"tf-mlops-modelbuild-${var.env}\"\n    override_artifact_name = false\n    packaging              = \"NONE\"\n    type                   = \"CODEPIPELINE\"\n  }\n\n  environment {\n    compute_type                = \"BUILD_GENERAL1_SMALL\"\n    image                       = \"aws/codebuild/amazonlinux2-x86_64-standard:2.0\"\n    image_pull_credentials_type = \"CODEBUILD\"\n    privileged_mode             = false\n    type                        = \"LINUX_CONTAINER\"\n    environment_variable {\n      name  = \"environment\"\n      type  = \"PLAINTEXT\"\n      value = var.env\n    }\n    environment_variable {\n      name  = \"SAGEMAKER_PROJECT_NAME\"\n      type  = \"PLAINTEXT\"\n      value = var.project_name\n    }\n    environment_variable {\n      name  = \"SAGEMAKER_PROJECT_ID\"\n      type  = \"PLAINTEXT\"\n      value = var.project_id\n    }\n    environment_variable {\n      name  = \"ARTIFACT_BUCKET\"\n      type  = \"PLAINTEXT\"\n      value = var.artifacts_bucket_name\n    }\n    environment_variable {\n      name  = \"SAGEMAKER_PIPELINE_ROLE_ARN\"\n      type  = \"PLAINTEXT\"\n      value = aws_iam_role.tf_mlops_role.arn\n    }\n    environment_variable {\n      name  = \"AWS_REGION\"\n      type  = \"PLAINTEXT\"\n      value = var.region\n    }\n  }\n\n  logs_config {\n    cloudwatch_logs {\n      status = \"ENABLED\"\n    }\n\n    s3_logs {\n      encryption_disabled = false\n      status              = \"DISABLED\"\n    }\n  }\n\n  source {\n    buildspec           = data.template_file.buildspec.rendered  # connect to buildspec file\n    git_clone_depth     = 0\n    insecure_ssl        = false\n    report_build_status = false\n    type                = \"CODEPIPELINE\"\n  }\n}\n"
  },
  {
    "path": "samples/mlops-sagemaker-github-codepipeline-codebuild-codedeploy/terraform/modelbuild_hooks.tf",
    "content": "resource \"aws_codepipeline_webhook\" \"buildpipeline_webhook\" {\n  authentication  = \"GITHUB_HMAC\"\n  name            = \"codepipeline-webhook\"\n  target_action   = \"Source\"\n  target_pipeline = aws_codepipeline.sm_ci_pipeline.name  # connect to codepipeline\n\n  authentication_configuration {\n    secret_token = random_string.build_github_secret.result\n  }\n\n  filter {\n    json_path    = \"$.ref\"\n    match_equals = \"refs/heads/{Branch}\"\n  }\n  tags = {}\n}\n\nresource \"github_repository_webhook\" \"build_github_hook\" {\n  repository = var.build_repository_name\n  events     = [\"push\"]\n\n  configuration {\n    url          = aws_codepipeline_webhook.buildpipeline_webhook.url\n    insecure_ssl = \"0\"\n    content_type = \"json\"\n    secret       = random_string.build_github_secret.result\n  }\n}\n\nresource \"random_string\" \"build_github_secret\" {\n  length  = 99\n  special = false\n}\n"
  },
  {
    "path": "samples/mlops-sagemaker-github-codepipeline-codebuild-codedeploy/terraform/modeldeploy_buildspec.yml",
    "content": "version: 0.2\n\nphases:\n  install:\n    runtime-versions:\n      python: 3.8\n    commands:\n      # Upgrade AWS CLI to the latest version\n      - pip install --upgrade --force-reinstall botocore boto3 awscli\n\n  build:\n    commands:\n      # Export the staging and production configuration files\n      - python build.py --model-execution-role \"$MODEL_EXECUTION_ROLE_ARN\" --model-package-group-name \"$SOURCE_MODEL_PACKAGE_GROUP_NAME\" --sagemaker-project-id \"$SAGEMAKER_PROJECT_ID\" --sagemaker-project-name \"$SAGEMAKER_PROJECT_NAME\" --export-staging-config $EXPORT_TEMPLATE_STAGING_CONFIG --export-prod-config $EXPORT_TEMPLATE_PROD_CONFIG\n\n      # Package the infrastucture as code defined in endpoint-config-template.yml by using AWS CloudFormation.\n      # Note that the Environment Variables like ARTIFACT_BUCKET, SAGEMAKER_PROJECT_NAME etc,. used below are expected to be setup by the\n      # CodeBuild resource in the infra pipeline (in the ServiceCatalog product)\n      - aws cloudformation package --template endpoint-config-template.yml --s3-bucket $ARTIFACT_BUCKET --output-template $EXPORT_TEMPLATE_NAME\n\n      # Print the files to verify contents\n      - cat $EXPORT_TEMPLATE_STAGING_CONFIG\n      - cat $EXPORT_TEMPLATE_PROD_CONFIG\n\nartifacts:\n  files:\n    - $EXPORT_TEMPLATE_NAME\n    - $EXPORT_TEMPLATE_STAGING_CONFIG\n    - $EXPORT_TEMPLATE_PROD_CONFIG\n"
  },
  {
    "path": "samples/mlops-sagemaker-github-codepipeline-codebuild-codedeploy/terraform/modeldeploy_cd_pipeline.tf",
    "content": "#data \"aws_caller_identity\" \"current\" {}\nresource \"aws_codepipeline\" \"sm_cd_pipeline\" {\n  name     = \"modeldeploy-pipeline\"\n  role_arn = aws_iam_role.tf_mlops_role.arn\n  tags = {\n    Environment = var.env\n  }\n\n  artifact_store {\n    location = aws_s3_bucket.artifacts_bucket.bucket\n    type     = \"S3\"\n  }\n\n  stage {\n    name = \"Source\"\n\n    action {\n      category = \"Source\"\n      configuration = {\n        \"Branch\"               = var.repository_branch\n        \"Owner\"                = var.repository_owner\n        \"PollForSourceChanges\" = \"false\"\n        \"Repo\"                 = var.deploy_repository_name\n        OAuthToken             = var.github_token\n      }\n\n      input_artifacts = []\n      name            = \"Source\"\n      output_artifacts = [\n        \"SourceArtifact\",\n      ]\n      owner     = \"ThirdParty\"\n      provider  = \"GitHub\"\n      run_order = 1\n      version   = \"1\"\n    }\n  }\n\n  stage {\n    name = \"Build\"\n\n    action {\n      category = \"Build\"\n      configuration = {\n        \"ProjectName\" = \"tf-mlops-deploybuild\"  # connect to codebuild, alternative: aws_codebuild_project.tf_mlops_deploybuild.name\n      }\n      input_artifacts = [\n        \"SourceArtifact\",\n      ]\n      name = \"Build\"\n      output_artifacts = [\n        \"BuildArtifact\",\n      ]\n      owner     = \"AWS\"\n      provider  = \"CodeBuild\"\n      run_order = 1\n      version   = \"1\"\n    }\n  }\n\n  stage {\n    name = \"DeployStaging\"\n\n    action {\n      category = \"Deploy\"\n      configuration = {\n        \"ActionMode\": \"REPLACE_ON_FAILURE\",\n        \"Capabilities\": \"CAPABILITY_NAMED_IAM\",\n        \"RoleArn\": aws_iam_role.tf_mlops_role.arn,\n        \"StackName\": \"sagemaker-${var.project_name}-${var.project_id}-deploy-staging\",\n        \"TemplateConfiguration\": \"BuildArtifact::staging-config-export.json\",\n        \"TemplatePath\": \"BuildArtifact::template-export.yml\"\n\n      }\n      input_artifacts = [\n        \"BuildArtifact\",\n      ]\n      name = \"DeployResourcesStaging\"\n      owner     = \"AWS\"\n      provider  = \"CloudFormation\"\n      run_order = 1\n      version   = \"1\"\n    }\n\n    action {\n      category = \"Build\"\n      configuration = {\n        \"ProjectName\" = \"tf-mlops-testbuild\",  # connect to codebuild, alternative: aws_codebuild_project.tf_mlops_testbuild.name\n        \"PrimarySource\" = \"SourceArtifact\"\n      }\n      input_artifacts = [\n        \"SourceArtifact\",\"BuildArtifact\"\n      ]\n      name = \"TestStaging\"\n      output_artifacts = [\n        \"TestArtifact\",\n      ]\n      owner     = \"AWS\"\n      provider  = \"CodeBuild\"\n      run_order = 2\n      version   = \"1\"\n    }\n\n    action {\n      category = \"Approval\"\n      configuration = {\n        \"CustomData\"= \"Approve this model for Production\"\n      }\n      name = \"ApproveDeployment\"\n      owner     = \"AWS\"\n      provider  = \"Manual\"\n      run_order = 3\n      version   = \"1\"\n    }\n  }\n  stage {\n    name = \"DeployProd\"\n\n    action {\n      category = \"Deploy\"\n      configuration = {\n        \"ActionMode\": \"CREATE_UPDATE\",\n        \"RoleArn\": aws_iam_role.tf_mlops_role.arn,\n        \"Capabilities\": \"CAPABILITY_NAMED_IAM\",\n        \"StackName\": \"sagemaker-${var.project_name}-${var.project_id}-deploy-prod\",\n        \"TemplateConfiguration\": \"BuildArtifact::prod-config-export.json\",\n        \"TemplatePath\": \"BuildArtifact::template-export.yml\"\n      }\n      input_artifacts = [\n        \"BuildArtifact\",\n      ]\n      name = \"DeployResourcesProd\"\n      owner     = \"AWS\"\n      provider  = \"CloudFormation\"\n      run_order = 1\n      version   = \"1\"\n    }\n  }\n\n}\n"
  },
  {
    "path": "samples/mlops-sagemaker-github-codepipeline-codebuild-codedeploy/terraform/modeldeploy_codebuild.tf",
    "content": "data \"template_file\" \"deploybuildspec\" {\n  template = file(\"modeldeploy_buildspec.yml\")  # connect to buildspec file\n  vars = {\n    env = var.env\n    SAGEMAKER_PROJECT_NAME=var.project_name\n    SAGEMAKER_PROJECT_ID=var.project_id\n    ARTIFACT_BUCKET=var.artifacts_bucket_name\n    MODEL_EXECUTION_ROLE_ARN=aws_iam_role.tf_mlops_role.arn\n    AWS_REGION=var.region\n    SOURCE_MODEL_PACKAGE_GROUP_NAME=\"${var.project_name}-${var.project_id}\"\n    EXPORT_TEMPLATE_NAME=\"template-export.yml\"\n    EXPORT_TEMPLATE_STAGING_CONFIG=\"staging-config-export.json\"\n    EXPORT_TEMPLATE_PROD_CONFIG=\"prod-config-export.json\"\n\n  }\n}\n\nresource \"aws_codebuild_project\" \"tf_mlops_deploybuild\" {\n  badge_enabled  = false\n  build_timeout  = 60\n  name           = \"tf-mlops-deploybuild\"\n  queued_timeout = 480\n  service_role   = aws_iam_role.tf_mlops_role.arn\n  tags = {\n    Environment = var.env\n  }\n\n  artifacts {\n    encryption_disabled    = false\n    name                   = \"tf-mlops-deploybuild-${var.env}\"\n    override_artifact_name = false\n    packaging              = \"NONE\"\n    type                   = \"CODEPIPELINE\"\n  }\n\n  environment {\n    compute_type                = \"BUILD_GENERAL1_SMALL\"\n    image                       = \"aws/codebuild/amazonlinux2-x86_64-standard:3.0\"\n    image_pull_credentials_type = \"CODEBUILD\"\n    privileged_mode             = false\n    type                        = \"LINUX_CONTAINER\"\n    environment_variable {\n      name  = \"environment\"\n      type  = \"PLAINTEXT\"\n      value = var.env\n    }\n    environment_variable {\n      name  = \"SAGEMAKER_PROJECT_NAME\"\n      type  = \"PLAINTEXT\"\n      value = var.project_name\n    }\n    environment_variable {\n      name  = \"SAGEMAKER_PROJECT_ID\"\n      type  = \"PLAINTEXT\"\n      value = var.project_id\n    }\n    environment_variable {\n      name  = \"ARTIFACT_BUCKET\"\n      type  = \"PLAINTEXT\"\n      value = var.artifacts_bucket_name\n    }\n    environment_variable {\n      name  = \"MODEL_EXECUTION_ROLE_ARN\"\n      type  = \"PLAINTEXT\"\n      value = aws_iam_role.tf_mlops_role.arn\n    }\n    environment_variable {\n      name  = \"SOURCE_MODEL_PACKAGE_GROUP_NAME\"\n      type  = \"PLAINTEXT\"\n      value = \"${var.project_name}-${var.project_id}\"\n    }\n    environment_variable {\n      name  = \"AWS_REGION\"\n      type  = \"PLAINTEXT\"\n      value = var.region\n    }\n    environment_variable {\n      name  = \"EXPORT_TEMPLATE_NAME\"\n      type  = \"PLAINTEXT\"\n      value = \"template-export.yml\"\n    }\n    environment_variable {\n      name  = \"EXPORT_TEMPLATE_STAGING_CONFIG\"\n      type  = \"PLAINTEXT\"\n      value = \"staging-config-export.json\"\n    }\n    environment_variable {\n      name  = \"EXPORT_TEMPLATE_PROD_CONFIG\"\n      type  = \"PLAINTEXT\"\n      value = \"prod-config-export.json\"\n    }\n  }\n\n  logs_config {\n    cloudwatch_logs {\n      status = \"ENABLED\"\n    }\n\n    s3_logs {\n      encryption_disabled = false\n      status              = \"DISABLED\"\n    }\n  }\n\n  source {\n    buildspec           = data.template_file.deploybuildspec.rendered  # connect to buildspec file\n    git_clone_depth     = 0\n    insecure_ssl        = false\n    report_build_status = false\n    type                = \"CODEPIPELINE\"\n  }\n}\n"
  },
  {
    "path": "samples/mlops-sagemaker-github-codepipeline-codebuild-codedeploy/terraform/modeldeploy_hooks.tf",
    "content": "resource \"aws_codepipeline_webhook\" \"deploy_webhook\" {\n  authentication  = \"GITHUB_HMAC\"\n  name            = \"deploypipeline-webhook\"\n  target_action   = \"Source\"\n  target_pipeline = aws_codepipeline.sm_cd_pipeline.name  # connect to codepipeline\n\n  authentication_configuration {\n    secret_token = random_string.deploy_github_secret.result\n  }\n\n  filter {\n    json_path    = \"$.ref\"\n    match_equals = \"refs/heads/{Branch}\"\n  }\n  tags = {}\n}\n\nresource \"github_repository_webhook\" \"deploy_hook\" {\n  repository = var.deploy_repository_name\n  events     = [\"push\"]\n\n  configuration {\n    url          = aws_codepipeline_webhook.deploy_webhook.url\n    insecure_ssl = \"0\"\n    content_type = \"json\"\n    secret       = random_string.deploy_github_secret.result\n  }\n}\n\nresource \"random_string\" \"deploy_github_secret\" {\n  length  = 99\n  special = false\n}\n"
  },
  {
    "path": "samples/mlops-sagemaker-github-codepipeline-codebuild-codedeploy/terraform/modeldeploy_testbuild.tf",
    "content": "resource \"aws_codebuild_project\" \"tf_mlops_testbuild\" {\n  badge_enabled  = false\n  build_timeout  = 60\n  name           = \"tf-mlops-testbuild\"\n  queued_timeout = 480\n  service_role   = aws_iam_role.tf_mlops_role.arn\n  tags = {\n    Environment = var.env\n  }\n\n  artifacts {\n    encryption_disabled    = false\n    name                   = \"tf-mlops-testbuild-${var.env}\"\n    override_artifact_name = false\n    packaging              = \"NONE\"\n    type                   = \"CODEPIPELINE\"\n  }\n\n  environment {\n    compute_type                = \"BUILD_GENERAL1_SMALL\"\n    image                       = \"aws/codebuild/amazonlinux2-x86_64-standard:2.0\"\n    image_pull_credentials_type = \"CODEBUILD\"\n    privileged_mode             = false\n    type                        = \"LINUX_CONTAINER\"\n    environment_variable {\n      name  = \"environment\"\n      type  = \"PLAINTEXT\"\n      value = var.env\n    }\n    environment_variable {\n      name  = \"SAGEMAKER_PROJECT_NAME\"\n      type  = \"PLAINTEXT\"\n      value = var.project_name\n    }\n    environment_variable {\n      name  = \"SAGEMAKER_PROJECT_ID\"\n      type  = \"PLAINTEXT\"\n      value = var.project_id\n    }\n    environment_variable {\n      name  = \"AWS_REGION\"\n      type  = \"PLAINTEXT\"\n      value = var.region\n    }\n    environment_variable {\n      name  = \"BUILD_CONFIG\"\n      type  = \"PLAINTEXT\"\n      value = \"staging-config-export.json\"\n    }\n    environment_variable {\n      name  = \"EXPORT_TEST_RESULTS\"\n      type  = \"PLAINTEXT\"\n      value = \"test-results.json\"\n    }\n  }\n\n  logs_config {\n    cloudwatch_logs {\n      status = \"ENABLED\"\n    }\n\n    s3_logs {\n      encryption_disabled = false\n      status              = \"DISABLED\"\n    }\n  }\n\n  source {\n    buildspec           = \"test/test_buildspec.yml\"\n    git_clone_depth     = 0\n    insecure_ssl        = false\n    report_build_status = false\n    type                = \"CODEPIPELINE\"\n  }\n}\n"
  },
  {
    "path": "samples/mlops-sagemaker-github-codepipeline-codebuild-codedeploy/terraform/s3.tf",
    "content": "resource \"aws_s3_bucket\" \"artifacts_bucket\" {\n  bucket        = var.artifacts_bucket_name\n  force_destroy = true\n}\n"
  },
  {
    "path": "samples/mlops-sagemaker-github-codepipeline-codebuild-codedeploy/terraform/terraform.tfvars",
    "content": "repository_branch      = \"main\" #\"<your branch>\"\nenv                    = \"dev\"\nproject_name           = \"<project_name>\" #\"aws-ml-11052023\"\nproject_id             = \"<project_id>\" #\"04052023\" \nregion                 = \"us-east-1\" \nrepository_owner       = \"<your id>\"\nbuild_repository_name  = \"modelbuild_pipeline\"\ndeploy_repository_name = \"modeldeploy_pipeline\"\nartifacts_bucket_name  = \"<your bucket name>\" # \"artifact-ml-11052023\" #join(\"-\", [var.project_name, var.project_id, var.env]) \ngithub_token           = \"<your token>\" # to pull modelbuild and modeldeploy"
  },
  {
    "path": "samples/mlops-sagemaker-github-codepipeline-codebuild-codedeploy/terraform/variables.tf",
    "content": "variable \"repository_branch\" {\n  description = \"Repository branch to connect to\"\n  default     = \"<your branch>\"\n}\nvariable \"env\" {\n  description = \"Deployment environment\"\n  default     = \"dev\"\n}\nvariable \"project_name\" {\n  description = \"Project name\"\n  default     = \"<project_name>\"\n}\nvariable \"project_id\" {\n  description = \"Project ID\"\n  default     = \"<project_id>\"\n}\nvariable \"region\" {\n  description = \"AWS region\"\n  default     = \"us-east-1\"\n}\n\nvariable \"repository_owner\" {\n  description = \"GitHub repository owner\"\n  default     = \"<your id>\"\n}\n\nvariable \"build_repository_name\" {\n  description = \"GitHub repository name\"\n  default     = \"modelbuild_pipeline\"\n}\n\nvariable \"deploy_repository_name\" {\n  description = \"GitHub repository name\"\n  default     = \"modeldeploy_pipeline\"\n}\n\nvariable \"artifacts_bucket_name\" {\n  description = \"S3 Bucket for storing artifacts\"\n  default     = \"<your bucket name>\"\n}\n\nvariable \"github_token\" {\n  description = \"GitHub token\"\n  default     = \"<your token>\"\n}\n"
  },
  {
    "path": "samples/s3-cloudfront-static-website/cloudfront.tf",
    "content": "locals {\r\n  s3_origin_id = \"s3-my-website2023\"\r\n}\r\n\r\nresource \"aws_cloudfront_origin_access_identity\" \"origin_access_identity\" {\r\n  comment = \"s3-my-website2023\"\r\n}\r\n\r\nresource \"aws_cloudfront_distribution\" \"s3_distribution\" {\r\n  origin {\r\n    domain_name = aws_s3_bucket.mybucket.bucket_regional_domain_name\r\n    origin_id   = local.s3_origin_id\r\n\r\n    s3_origin_config {\r\n      origin_access_identity = aws_cloudfront_origin_access_identity.origin_access_identity.cloudfront_access_identity_path\r\n    }\r\n  }\r\n\r\n  enabled             = true\r\n  is_ipv6_enabled     = true\r\n  comment             = \"my-cloudfront\"\r\n  default_root_object = \"index.html\"\r\n\r\n  # Configure logging here if required \t\r\n  #logging_config {\r\n  #  include_cookies = false\r\n  #  bucket          = \"mylogs.s3.amazonaws.com\"\r\n  #  prefix          = \"myprefix\"\r\n  #}\r\n\r\n  # If you have domain configured use it here \r\n  #aliases = [\"mywebsite.example.com\", \"s3-static-web-dev.example.com\"]\r\n\r\n  default_cache_behavior {\r\n    allowed_methods  = [\"DELETE\", \"GET\", \"HEAD\", \"OPTIONS\", \"PATCH\", \"POST\", \"PUT\"]\r\n    cached_methods   = [\"GET\", \"HEAD\"]\r\n    target_origin_id = local.s3_origin_id\r\n\r\n    forwarded_values {\r\n      query_string = false\r\n\r\n      cookies {\r\n        forward = \"none\"\r\n      }\r\n    }\r\n\r\n    viewer_protocol_policy = \"allow-all\"\r\n    min_ttl                = 0\r\n    default_ttl            = 3600\r\n    max_ttl                = 86400\r\n  }\r\n\r\n  # Cache behavior with precedence 0\r\n  ordered_cache_behavior {\r\n    path_pattern     = \"/content/immutable/*\"\r\n    allowed_methods  = [\"GET\", \"HEAD\", \"OPTIONS\"]\r\n    cached_methods   = [\"GET\", \"HEAD\", \"OPTIONS\"]\r\n    target_origin_id = local.s3_origin_id\r\n\r\n    forwarded_values {\r\n      query_string = false\r\n      headers      = [\"Origin\"]\r\n\r\n      cookies {\r\n        forward = \"none\"\r\n      }\r\n    }\r\n\r\n    min_ttl                = 0\r\n    default_ttl            = 86400\r\n    max_ttl                = 31536000\r\n    compress               = true\r\n    viewer_protocol_policy = \"redirect-to-https\"\r\n  }\r\n\r\n  # Cache behavior with precedence 1\r\n  ordered_cache_behavior {\r\n    path_pattern     = \"/content/*\"\r\n    allowed_methods  = [\"GET\", \"HEAD\", \"OPTIONS\"]\r\n    cached_methods   = [\"GET\", \"HEAD\"]\r\n    target_origin_id = local.s3_origin_id\r\n\r\n    forwarded_values {\r\n      query_string = false\r\n\r\n      cookies {\r\n        forward = \"none\"\r\n      }\r\n    }\r\n\r\n    min_ttl                = 0\r\n    default_ttl            = 3600\r\n    max_ttl                = 86400\r\n    compress               = true\r\n    viewer_protocol_policy = \"redirect-to-https\"\r\n  }\r\n\r\n  price_class = \"PriceClass_200\"\r\n\r\n  restrictions {\r\n    geo_restriction {\r\n      restriction_type = \"whitelist\"\r\n      locations        = [\"US\", \"CA\", \"GB\", \"DE\", \"IN\", \"IR\"]\r\n    }\r\n  }\r\n\r\n  tags = {\r\n    Environment = \"development\"\r\n    Name        = \"my-tag\"\r\n  }\r\n\r\n  viewer_certificate {\r\n    cloudfront_default_certificate = true\r\n  }\r\n}\r\n\r\n# to get the Cloud front URL if doamin/alias is not configured\r\noutput \"cloudfront_domain_name\" {\r\n  value = aws_cloudfront_distribution.s3_distribution.domain_name\r\n}\r\n"
  },
  {
    "path": "samples/s3-cloudfront-static-website/s3.tf",
    "content": "terraform {\r\n  required_providers {\r\n    aws = {\r\n      source  = \"hashicorp/aws\"\r\n      version = \"~> 4.16\"\r\n    }\r\n  }\r\n  required_version = \">= 1.2.0\"\r\n}\r\n\r\nprovider \"aws\" {\r\n  region  = \"eu-central-1\"\r\n}\r\n\r\nresource \"aws_s3_bucket\" \"mybucket\" {\r\n  bucket = \"s3-mybucket-website2023\"\r\n  acl    = \"private\"\r\n  # Add specefic S3 policy in the s3-policy.json on the same directory\r\n  # policy = file(\"s3-policy.json\")\r\n\r\n  versioning {\r\n    enabled = false\r\n  }\r\n\r\n  website {\r\n    index_document = \"index.html\"\r\n    error_document = \"error.html\"\r\n\t\r\n\t# Add routing rules if required\r\n    # routing_rules = <<EOF\r\n    #                [{\r\n    #                    \"Condition\": {\r\n    #                        \"KeyPrefixEquals\": \"docs/\"\r\n    #                    },\r\n    #                    \"Redirect\": {\r\n    #                        \"ReplaceKeyPrefixWith\": \"documents/\"\r\n    #                    }\r\n    #                }]\r\n    #                EOF\r\n  }\r\n\r\n  tags = {\r\n    Environment = \"development\"\r\n    Name        = \"my-tag\"\r\n  }\r\n\r\n}\r\n\r\n#Upload files of your static website\r\nresource \"aws_s3_bucket_object\" \"html\" {\r\n  for_each = fileset(\"${path.module}/website/\", \"*.html\")\r\n\r\n  bucket = aws_s3_bucket.mybucket.bucket\r\n  key    = each.value\r\n  source = \"${path.module}/website/${each.value}\"\r\n  etag   = filemd5(\"${path.module}/website/${each.value}\")\r\n  content_type = \"text/html\"\r\n}\r\n\r\nresource \"aws_s3_bucket_object\" \"svg\" {\r\n  for_each = fileset(\"${path.module}/website/\", \"**/*.svg\")\r\n\r\n  bucket = aws_s3_bucket.mybucket.bucket\r\n  key    = each.value\r\n  source = \"${path.module}/website/${each.value}\"\r\n  etag   = filemd5(\"${path.module}/website/${each.value}\")\r\n  content_type = \"image/svg+xml\"\r\n}\r\n\r\nresource \"aws_s3_bucket_object\" \"css\" {\r\n  for_each = fileset(\"${path.module}/website/\", \"**/*.css\")\r\n\r\n  bucket = aws_s3_bucket.mybucket.bucket\r\n  key    = each.value\r\n  source = \"${path.module}/website/${each.value}\"\r\n  etag   = filemd5(\"${path.module}/website/${each.value}\")\r\n  content_type = \"text/css\"\r\n}\r\n\r\nresource \"aws_s3_bucket_object\" \"js\" {\r\n  for_each = fileset(\"${path.module}/website/\", \"**/*.js\")\r\n\r\n  bucket = aws_s3_bucket.mybucket.bucket\r\n  key    = each.value\r\n  source = \"${path.module}/website/${each.value}\"\r\n  etag   = filemd5(\"${path.module}/website/${each.value}\")\r\n  content_type = \"application/javascript\"\r\n}\r\n\r\n\r\nresource \"aws_s3_bucket_object\" \"images\" {\r\n  for_each = fileset(\"${path.module}/website/\", \"**/*.png\")\r\n\r\n  bucket = aws_s3_bucket.mybucket.bucket\r\n  key    = each.value\r\n  source = \"${path.module}/website/${each.value}\"\r\n  etag   = filemd5(\"${path.module}/website/${each.value}\")\r\n  content_type = \"image/png\"\r\n}\r\n\r\nresource \"aws_s3_bucket_object\" \"json\" {\r\n  for_each = fileset(\"${path.module}/website/\", \"**/*.json\")\r\n\r\n  bucket = aws_s3_bucket.mybucket.bucket\r\n  key    = each.value\r\n  source = \"${path.module}/website/${each.value}\"\r\n  etag   = filemd5(\"${path.module}/website/${each.value}\")\r\n  content_type = \"application/json\"\r\n}\r\n# Add more aws_s3_bucket_object for the type of files you want to upload\r\n# The reason for having multiple aws_s3_bucket_object with file type is to make sure\r\n# we add the correct content_type for the file in S3. Otherwise website load may have issues\r\n\r\n# Print the files processed so far\r\noutput \"fileset-results\" {\r\n  value = fileset(\"${path.module}/website/\", \"**/*\")\r\n}\r\n\r\ndata \"aws_iam_policy_document\" \"s3_policy\" {\r\n  statement {\r\n    actions   = [\"s3:GetObject\"]\r\n    resources = [\"${aws_s3_bucket.mybucket.arn}/*\"]\r\n\r\n    principals {\r\n      type        = \"AWS\"\r\n      identifiers = [aws_cloudfront_origin_access_identity.origin_access_identity.iam_arn]\r\n    }\r\n  }\r\n}\r\n\r\nresource \"aws_s3_bucket_policy\" \"mybucket\" {\r\n  bucket = aws_s3_bucket.mybucket.id\r\n  policy = data.aws_iam_policy_document.s3_policy.json\r\n}\r\n\r\nresource \"aws_s3_bucket_public_access_block\" \"mybucket\" {\r\n  bucket = aws_s3_bucket.mybucket.id\r\n\r\n  block_public_acls       = true\r\n  block_public_policy     = true\r\n  //ignore_public_acls      = true\r\n  //restrict_public_buckets = true\r\n}"
  },
  {
    "path": "samples/s3-cloudfront-static-website/website/css/styles.css",
    "content": "@charset \"UTF-8\";\n/*!\n* Start Bootstrap - Freelancer v7.0.7 (https://startbootstrap.com/theme/freelancer)\n* Copyright 2013-2023 Start Bootstrap\n* Licensed under MIT (https://github.com/StartBootstrap/startbootstrap-freelancer/blob/master/LICENSE)\n*/\n/*!\n * Bootstrap  v5.2.3 (https://getbootstrap.com/)\n * Copyright 2011-2022 The Bootstrap Authors\n * Copyright 2011-2022 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n */\n:root {\n  --bs-blue: #0d6efd;\n  --bs-indigo: #6610f2;\n  --bs-purple: #6f42c1;\n  --bs-pink: #d63384;\n  --bs-red: #dc3545;\n  --bs-orange: #fd7e14;\n  --bs-yellow: #ffc107;\n  --bs-green: #198754;\n  --bs-teal: #1abc9c;\n  --bs-cyan: #0dcaf0;\n  --bs-black: #000;\n  --bs-white: #fff;\n  --bs-gray: #6c757d;\n  --bs-gray-dark: #343a40;\n  --bs-gray-100: #f8f9fa;\n  --bs-gray-200: #e9ecef;\n  --bs-gray-300: #dee2e6;\n  --bs-gray-400: #ced4da;\n  --bs-gray-500: #adb5bd;\n  --bs-gray-600: #6c757d;\n  --bs-gray-700: #495057;\n  --bs-gray-800: #343a40;\n  --bs-gray-900: #212529;\n  --bs-primary: #1abc9c;\n  --bs-secondary: #2c3e50;\n  --bs-success: #198754;\n  --bs-info: #0dcaf0;\n  --bs-warning: #ffc107;\n  --bs-danger: #dc3545;\n  --bs-light: #f8f9fa;\n  --bs-dark: #212529;\n  --bs-primary-rgb: 26, 188, 156;\n  --bs-secondary-rgb: 44, 62, 80;\n  --bs-success-rgb: 25, 135, 84;\n  --bs-info-rgb: 13, 202, 240;\n  --bs-warning-rgb: 255, 193, 7;\n  --bs-danger-rgb: 220, 53, 69;\n  --bs-light-rgb: 248, 249, 250;\n  --bs-dark-rgb: 33, 37, 41;\n  --bs-white-rgb: 255, 255, 255;\n  --bs-black-rgb: 0, 0, 0;\n  --bs-body-color-rgb: 33, 37, 41;\n  --bs-body-bg-rgb: 255, 255, 255;\n  --bs-font-sans-serif: \"Lato\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n  --bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;\n  --bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));\n  --bs-body-font-family: var(--bs-font-sans-serif);\n  --bs-body-font-size: 1rem;\n  --bs-body-font-weight: 400;\n  --bs-body-line-height: 1.5;\n  --bs-body-color: #212529;\n  --bs-body-bg: #fff;\n  --bs-border-width: 0.125rem;\n  --bs-border-style: solid;\n  --bs-border-color: #dee2e6;\n  --bs-border-color-translucent: rgba(0, 0, 0, 0.175);\n  --bs-border-radius: 0.5rem;\n  --bs-border-radius-sm: 0.25rem;\n  --bs-border-radius-lg: 0.75rem;\n  --bs-border-radius-xl: 1rem;\n  --bs-border-radius-2xl: 2rem;\n  --bs-border-radius-pill: 50rem;\n  --bs-link-color: #1abc9c;\n  --bs-link-hover-color: #15967d;\n  --bs-code-color: #d63384;\n  --bs-highlight-bg: #fff3cd;\n}\n\n*,\n*::before,\n*::after {\n  box-sizing: border-box;\n}\n\n@media (prefers-reduced-motion: no-preference) {\n  :root {\n    scroll-behavior: smooth;\n  }\n}\n\nbody {\n  margin: 0;\n  font-family: var(--bs-body-font-family);\n  font-size: var(--bs-body-font-size);\n  font-weight: var(--bs-body-font-weight);\n  line-height: var(--bs-body-line-height);\n  color: var(--bs-body-color);\n  text-align: var(--bs-body-text-align);\n  background-color: var(--bs-body-bg);\n  -webkit-text-size-adjust: 100%;\n  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\n\nhr {\n  margin: 1rem 0;\n  color: inherit;\n  border: 0;\n  border-top: 0.125rem solid;\n  opacity: 0.25;\n}\n\nh6, .h6, h5, .h5, h4, .h4, h3, .h3, h2, .h2, h1, .h1 {\n  margin-top: 0;\n  margin-bottom: 0.5rem;\n  font-family: \"Montserrat\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n  font-weight: 700;\n  line-height: 1.2;\n}\n\nh1, .h1 {\n  font-size: calc(1.375rem + 1.5vw);\n}\n@media (min-width: 1200px) {\n  h1, .h1 {\n    font-size: 2.5rem;\n  }\n}\n\nh2, .h2 {\n  font-size: calc(1.325rem + 0.9vw);\n}\n@media (min-width: 1200px) {\n  h2, .h2 {\n    font-size: 2rem;\n  }\n}\n\nh3, .h3 {\n  font-size: calc(1.3rem + 0.6vw);\n}\n@media (min-width: 1200px) {\n  h3, .h3 {\n    font-size: 1.75rem;\n  }\n}\n\nh4, .h4 {\n  font-size: calc(1.275rem + 0.3vw);\n}\n@media (min-width: 1200px) {\n  h4, .h4 {\n    font-size: 1.5rem;\n  }\n}\n\nh5, .h5 {\n  font-size: 1.25rem;\n}\n\nh6, .h6 {\n  font-size: 1rem;\n}\n\np {\n  margin-top: 0;\n  margin-bottom: 1rem;\n}\n\nabbr[title] {\n  -webkit-text-decoration: underline dotted;\n          text-decoration: underline dotted;\n  cursor: help;\n  -webkit-text-decoration-skip-ink: none;\n          text-decoration-skip-ink: none;\n}\n\naddress {\n  margin-bottom: 1rem;\n  font-style: normal;\n  line-height: inherit;\n}\n\nol,\nul {\n  padding-left: 2rem;\n}\n\nol,\nul,\ndl {\n  margin-top: 0;\n  margin-bottom: 1rem;\n}\n\nol ol,\nul ul,\nol ul,\nul ol {\n  margin-bottom: 0;\n}\n\ndt {\n  font-weight: 700;\n}\n\ndd {\n  margin-bottom: 0.5rem;\n  margin-left: 0;\n}\n\nblockquote {\n  margin: 0 0 1rem;\n}\n\nb,\nstrong {\n  font-weight: bolder;\n}\n\nsmall, .small {\n  font-size: 0.875em;\n}\n\nmark, .mark {\n  padding: 0.1875em;\n  background-color: var(--bs-highlight-bg);\n}\n\nsub,\nsup {\n  position: relative;\n  font-size: 0.75em;\n  line-height: 0;\n  vertical-align: baseline;\n}\n\nsub {\n  bottom: -0.25em;\n}\n\nsup {\n  top: -0.5em;\n}\n\na {\n  color: var(--bs-link-color);\n  text-decoration: underline;\n}\na:hover {\n  color: var(--bs-link-hover-color);\n}\n\na:not([href]):not([class]), a:not([href]):not([class]):hover {\n  color: inherit;\n  text-decoration: none;\n}\n\npre,\ncode,\nkbd,\nsamp {\n  font-family: var(--bs-font-monospace);\n  font-size: 1em;\n}\n\npre {\n  display: block;\n  margin-top: 0;\n  margin-bottom: 1rem;\n  overflow: auto;\n  font-size: 0.875em;\n}\npre code {\n  font-size: inherit;\n  color: inherit;\n  word-break: normal;\n}\n\ncode {\n  font-size: 0.875em;\n  color: var(--bs-code-color);\n  word-wrap: break-word;\n}\na > code {\n  color: inherit;\n}\n\nkbd {\n  padding: 0.1875rem 0.375rem;\n  font-size: 0.875em;\n  color: var(--bs-body-bg);\n  background-color: var(--bs-body-color);\n  border-radius: 0.25rem;\n}\nkbd kbd {\n  padding: 0;\n  font-size: 1em;\n}\n\nfigure {\n  margin: 0 0 1rem;\n}\n\nimg,\nsvg {\n  vertical-align: middle;\n}\n\ntable {\n  caption-side: bottom;\n  border-collapse: collapse;\n}\n\ncaption {\n  padding-top: 0.5rem;\n  padding-bottom: 0.5rem;\n  color: #6c757d;\n  text-align: left;\n}\n\nth {\n  text-align: inherit;\n  text-align: -webkit-match-parent;\n}\n\nthead,\ntbody,\ntfoot,\ntr,\ntd,\nth {\n  border-color: inherit;\n  border-style: solid;\n  border-width: 0;\n}\n\nlabel {\n  display: inline-block;\n}\n\nbutton {\n  border-radius: 0;\n}\n\nbutton:focus:not(:focus-visible) {\n  outline: 0;\n}\n\ninput,\nbutton,\nselect,\noptgroup,\ntextarea {\n  margin: 0;\n  font-family: inherit;\n  font-size: inherit;\n  line-height: inherit;\n}\n\nbutton,\nselect {\n  text-transform: none;\n}\n\n[role=button] {\n  cursor: pointer;\n}\n\nselect {\n  word-wrap: normal;\n}\nselect:disabled {\n  opacity: 1;\n}\n\n[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator {\n  display: none !important;\n}\n\nbutton,\n[type=button],\n[type=reset],\n[type=submit] {\n  -webkit-appearance: button;\n}\nbutton:not(:disabled),\n[type=button]:not(:disabled),\n[type=reset]:not(:disabled),\n[type=submit]:not(:disabled) {\n  cursor: pointer;\n}\n\n::-moz-focus-inner {\n  padding: 0;\n  border-style: none;\n}\n\ntextarea {\n  resize: vertical;\n}\n\nfieldset {\n  min-width: 0;\n  padding: 0;\n  margin: 0;\n  border: 0;\n}\n\nlegend {\n  float: left;\n  width: 100%;\n  padding: 0;\n  margin-bottom: 0.5rem;\n  font-size: calc(1.275rem + 0.3vw);\n  line-height: inherit;\n}\n@media (min-width: 1200px) {\n  legend {\n    font-size: 1.5rem;\n  }\n}\nlegend + * {\n  clear: left;\n}\n\n::-webkit-datetime-edit-fields-wrapper,\n::-webkit-datetime-edit-text,\n::-webkit-datetime-edit-minute,\n::-webkit-datetime-edit-hour-field,\n::-webkit-datetime-edit-day-field,\n::-webkit-datetime-edit-month-field,\n::-webkit-datetime-edit-year-field {\n  padding: 0;\n}\n\n::-webkit-inner-spin-button {\n  height: auto;\n}\n\n[type=search] {\n  outline-offset: -2px;\n  -webkit-appearance: textfield;\n}\n\n/* rtl:raw:\n[type=\"tel\"],\n[type=\"url\"],\n[type=\"email\"],\n[type=\"number\"] {\n  direction: ltr;\n}\n*/\n::-webkit-search-decoration {\n  -webkit-appearance: none;\n}\n\n::-webkit-color-swatch-wrapper {\n  padding: 0;\n}\n\n::file-selector-button {\n  font: inherit;\n  -webkit-appearance: button;\n}\n\noutput {\n  display: inline-block;\n}\n\niframe {\n  border: 0;\n}\n\nsummary {\n  display: list-item;\n  cursor: pointer;\n}\n\nprogress {\n  vertical-align: baseline;\n}\n\n[hidden] {\n  display: none !important;\n}\n\n.lead {\n  font-size: 1.25rem;\n  font-weight: 300;\n}\n\n.display-1 {\n  font-size: calc(1.625rem + 4.5vw);\n  font-weight: 300;\n  line-height: 1.2;\n}\n@media (min-width: 1200px) {\n  .display-1 {\n    font-size: 5rem;\n  }\n}\n\n.display-2 {\n  font-size: calc(1.575rem + 3.9vw);\n  font-weight: 300;\n  line-height: 1.2;\n}\n@media (min-width: 1200px) {\n  .display-2 {\n    font-size: 4.5rem;\n  }\n}\n\n.display-3 {\n  font-size: calc(1.525rem + 3.3vw);\n  font-weight: 300;\n  line-height: 1.2;\n}\n@media (min-width: 1200px) {\n  .display-3 {\n    font-size: 4rem;\n  }\n}\n\n.display-4 {\n  font-size: calc(1.475rem + 2.7vw);\n  font-weight: 300;\n  line-height: 1.2;\n}\n@media (min-width: 1200px) {\n  .display-4 {\n    font-size: 3.5rem;\n  }\n}\n\n.display-5 {\n  font-size: calc(1.425rem + 2.1vw);\n  font-weight: 300;\n  line-height: 1.2;\n}\n@media (min-width: 1200px) {\n  .display-5 {\n    font-size: 3rem;\n  }\n}\n\n.display-6 {\n  font-size: calc(1.375rem + 1.5vw);\n  font-weight: 300;\n  line-height: 1.2;\n}\n@media (min-width: 1200px) {\n  .display-6 {\n    font-size: 2.5rem;\n  }\n}\n\n.list-unstyled {\n  padding-left: 0;\n  list-style: none;\n}\n\n.list-inline {\n  padding-left: 0;\n  list-style: none;\n}\n\n.list-inline-item {\n  display: inline-block;\n}\n.list-inline-item:not(:last-child) {\n  margin-right: 0.5rem;\n}\n\n.initialism {\n  font-size: 0.875em;\n  text-transform: uppercase;\n}\n\n.blockquote {\n  margin-bottom: 1rem;\n  font-size: 1.25rem;\n}\n.blockquote > :last-child {\n  margin-bottom: 0;\n}\n\n.blockquote-footer {\n  margin-top: -1rem;\n  margin-bottom: 1rem;\n  font-size: 0.875em;\n  color: #6c757d;\n}\n.blockquote-footer::before {\n  content: \"— \";\n}\n\n.img-fluid {\n  max-width: 100%;\n  height: auto;\n}\n\n.img-thumbnail {\n  padding: 0.25rem;\n  background-color: #fff;\n  border: 0.125rem solid var(--bs-border-color);\n  border-radius: 0.5rem;\n  max-width: 100%;\n  height: auto;\n}\n\n.figure {\n  display: inline-block;\n}\n\n.figure-img {\n  margin-bottom: 0.5rem;\n  line-height: 1;\n}\n\n.figure-caption {\n  font-size: 0.875em;\n  color: #6c757d;\n}\n\n.container,\n.container-fluid,\n.container-xxl,\n.container-xl,\n.container-lg,\n.container-md,\n.container-sm {\n  --bs-gutter-x: 1.5rem;\n  --bs-gutter-y: 0;\n  width: 100%;\n  padding-right: calc(var(--bs-gutter-x) * 0.5);\n  padding-left: calc(var(--bs-gutter-x) * 0.5);\n  margin-right: auto;\n  margin-left: auto;\n}\n\n@media (min-width: 576px) {\n  .container-sm, .container {\n    max-width: 540px;\n  }\n}\n@media (min-width: 768px) {\n  .container-md, .container-sm, .container {\n    max-width: 720px;\n  }\n}\n@media (min-width: 992px) {\n  .container-lg, .container-md, .container-sm, .container {\n    max-width: 960px;\n  }\n}\n@media (min-width: 1200px) {\n  .container-xl, .container-lg, .container-md, .container-sm, .container {\n    max-width: 1140px;\n  }\n}\n@media (min-width: 1400px) {\n  .container-xxl, .container-xl, .container-lg, .container-md, .container-sm, .container {\n    max-width: 1320px;\n  }\n}\n.row {\n  --bs-gutter-x: 1.5rem;\n  --bs-gutter-y: 0;\n  display: flex;\n  flex-wrap: wrap;\n  margin-top: calc(-1 * var(--bs-gutter-y));\n  margin-right: calc(-0.5 * var(--bs-gutter-x));\n  margin-left: calc(-0.5 * var(--bs-gutter-x));\n}\n.row > * {\n  flex-shrink: 0;\n  width: 100%;\n  max-width: 100%;\n  padding-right: calc(var(--bs-gutter-x) * 0.5);\n  padding-left: calc(var(--bs-gutter-x) * 0.5);\n  margin-top: var(--bs-gutter-y);\n}\n\n.col {\n  flex: 1 0 0%;\n}\n\n.row-cols-auto > * {\n  flex: 0 0 auto;\n  width: auto;\n}\n\n.row-cols-1 > * {\n  flex: 0 0 auto;\n  width: 100%;\n}\n\n.row-cols-2 > * {\n  flex: 0 0 auto;\n  width: 50%;\n}\n\n.row-cols-3 > * {\n  flex: 0 0 auto;\n  width: 33.3333333333%;\n}\n\n.row-cols-4 > * {\n  flex: 0 0 auto;\n  width: 25%;\n}\n\n.row-cols-5 > * {\n  flex: 0 0 auto;\n  width: 20%;\n}\n\n.row-cols-6 > * {\n  flex: 0 0 auto;\n  width: 16.6666666667%;\n}\n\n.col-auto {\n  flex: 0 0 auto;\n  width: auto;\n}\n\n.col-1 {\n  flex: 0 0 auto;\n  width: 8.33333333%;\n}\n\n.col-2 {\n  flex: 0 0 auto;\n  width: 16.66666667%;\n}\n\n.col-3 {\n  flex: 0 0 auto;\n  width: 25%;\n}\n\n.col-4 {\n  flex: 0 0 auto;\n  width: 33.33333333%;\n}\n\n.col-5 {\n  flex: 0 0 auto;\n  width: 41.66666667%;\n}\n\n.col-6 {\n  flex: 0 0 auto;\n  width: 50%;\n}\n\n.col-7 {\n  flex: 0 0 auto;\n  width: 58.33333333%;\n}\n\n.col-8 {\n  flex: 0 0 auto;\n  width: 66.66666667%;\n}\n\n.col-9 {\n  flex: 0 0 auto;\n  width: 75%;\n}\n\n.col-10 {\n  flex: 0 0 auto;\n  width: 83.33333333%;\n}\n\n.col-11 {\n  flex: 0 0 auto;\n  width: 91.66666667%;\n}\n\n.col-12 {\n  flex: 0 0 auto;\n  width: 100%;\n}\n\n.offset-1 {\n  margin-left: 8.33333333%;\n}\n\n.offset-2 {\n  margin-left: 16.66666667%;\n}\n\n.offset-3 {\n  margin-left: 25%;\n}\n\n.offset-4 {\n  margin-left: 33.33333333%;\n}\n\n.offset-5 {\n  margin-left: 41.66666667%;\n}\n\n.offset-6 {\n  margin-left: 50%;\n}\n\n.offset-7 {\n  margin-left: 58.33333333%;\n}\n\n.offset-8 {\n  margin-left: 66.66666667%;\n}\n\n.offset-9 {\n  margin-left: 75%;\n}\n\n.offset-10 {\n  margin-left: 83.33333333%;\n}\n\n.offset-11 {\n  margin-left: 91.66666667%;\n}\n\n.g-0,\n.gx-0 {\n  --bs-gutter-x: 0;\n}\n\n.g-0,\n.gy-0 {\n  --bs-gutter-y: 0;\n}\n\n.g-1,\n.gx-1 {\n  --bs-gutter-x: 0.25rem;\n}\n\n.g-1,\n.gy-1 {\n  --bs-gutter-y: 0.25rem;\n}\n\n.g-2,\n.gx-2 {\n  --bs-gutter-x: 0.5rem;\n}\n\n.g-2,\n.gy-2 {\n  --bs-gutter-y: 0.5rem;\n}\n\n.g-3,\n.gx-3 {\n  --bs-gutter-x: 1rem;\n}\n\n.g-3,\n.gy-3 {\n  --bs-gutter-y: 1rem;\n}\n\n.g-4,\n.gx-4 {\n  --bs-gutter-x: 1.5rem;\n}\n\n.g-4,\n.gy-4 {\n  --bs-gutter-y: 1.5rem;\n}\n\n.g-5,\n.gx-5 {\n  --bs-gutter-x: 3rem;\n}\n\n.g-5,\n.gy-5 {\n  --bs-gutter-y: 3rem;\n}\n\n@media (min-width: 576px) {\n  .col-sm {\n    flex: 1 0 0%;\n  }\n  .row-cols-sm-auto > * {\n    flex: 0 0 auto;\n    width: auto;\n  }\n  .row-cols-sm-1 > * {\n    flex: 0 0 auto;\n    width: 100%;\n  }\n  .row-cols-sm-2 > * {\n    flex: 0 0 auto;\n    width: 50%;\n  }\n  .row-cols-sm-3 > * {\n    flex: 0 0 auto;\n    width: 33.3333333333%;\n  }\n  .row-cols-sm-4 > * {\n    flex: 0 0 auto;\n    width: 25%;\n  }\n  .row-cols-sm-5 > * {\n    flex: 0 0 auto;\n    width: 20%;\n  }\n  .row-cols-sm-6 > * {\n    flex: 0 0 auto;\n    width: 16.6666666667%;\n  }\n  .col-sm-auto {\n    flex: 0 0 auto;\n    width: auto;\n  }\n  .col-sm-1 {\n    flex: 0 0 auto;\n    width: 8.33333333%;\n  }\n  .col-sm-2 {\n    flex: 0 0 auto;\n    width: 16.66666667%;\n  }\n  .col-sm-3 {\n    flex: 0 0 auto;\n    width: 25%;\n  }\n  .col-sm-4 {\n    flex: 0 0 auto;\n    width: 33.33333333%;\n  }\n  .col-sm-5 {\n    flex: 0 0 auto;\n    width: 41.66666667%;\n  }\n  .col-sm-6 {\n    flex: 0 0 auto;\n    width: 50%;\n  }\n  .col-sm-7 {\n    flex: 0 0 auto;\n    width: 58.33333333%;\n  }\n  .col-sm-8 {\n    flex: 0 0 auto;\n    width: 66.66666667%;\n  }\n  .col-sm-9 {\n    flex: 0 0 auto;\n    width: 75%;\n  }\n  .col-sm-10 {\n    flex: 0 0 auto;\n    width: 83.33333333%;\n  }\n  .col-sm-11 {\n    flex: 0 0 auto;\n    width: 91.66666667%;\n  }\n  .col-sm-12 {\n    flex: 0 0 auto;\n    width: 100%;\n  }\n  .offset-sm-0 {\n    margin-left: 0;\n  }\n  .offset-sm-1 {\n    margin-left: 8.33333333%;\n  }\n  .offset-sm-2 {\n    margin-left: 16.66666667%;\n  }\n  .offset-sm-3 {\n    margin-left: 25%;\n  }\n  .offset-sm-4 {\n    margin-left: 33.33333333%;\n  }\n  .offset-sm-5 {\n    margin-left: 41.66666667%;\n  }\n  .offset-sm-6 {\n    margin-left: 50%;\n  }\n  .offset-sm-7 {\n    margin-left: 58.33333333%;\n  }\n  .offset-sm-8 {\n    margin-left: 66.66666667%;\n  }\n  .offset-sm-9 {\n    margin-left: 75%;\n  }\n  .offset-sm-10 {\n    margin-left: 83.33333333%;\n  }\n  .offset-sm-11 {\n    margin-left: 91.66666667%;\n  }\n  .g-sm-0,\n  .gx-sm-0 {\n    --bs-gutter-x: 0;\n  }\n  .g-sm-0,\n  .gy-sm-0 {\n    --bs-gutter-y: 0;\n  }\n  .g-sm-1,\n  .gx-sm-1 {\n    --bs-gutter-x: 0.25rem;\n  }\n  .g-sm-1,\n  .gy-sm-1 {\n    --bs-gutter-y: 0.25rem;\n  }\n  .g-sm-2,\n  .gx-sm-2 {\n    --bs-gutter-x: 0.5rem;\n  }\n  .g-sm-2,\n  .gy-sm-2 {\n    --bs-gutter-y: 0.5rem;\n  }\n  .g-sm-3,\n  .gx-sm-3 {\n    --bs-gutter-x: 1rem;\n  }\n  .g-sm-3,\n  .gy-sm-3 {\n    --bs-gutter-y: 1rem;\n  }\n  .g-sm-4,\n  .gx-sm-4 {\n    --bs-gutter-x: 1.5rem;\n  }\n  .g-sm-4,\n  .gy-sm-4 {\n    --bs-gutter-y: 1.5rem;\n  }\n  .g-sm-5,\n  .gx-sm-5 {\n    --bs-gutter-x: 3rem;\n  }\n  .g-sm-5,\n  .gy-sm-5 {\n    --bs-gutter-y: 3rem;\n  }\n}\n@media (min-width: 768px) {\n  .col-md {\n    flex: 1 0 0%;\n  }\n  .row-cols-md-auto > * {\n    flex: 0 0 auto;\n    width: auto;\n  }\n  .row-cols-md-1 > * {\n    flex: 0 0 auto;\n    width: 100%;\n  }\n  .row-cols-md-2 > * {\n    flex: 0 0 auto;\n    width: 50%;\n  }\n  .row-cols-md-3 > * {\n    flex: 0 0 auto;\n    width: 33.3333333333%;\n  }\n  .row-cols-md-4 > * {\n    flex: 0 0 auto;\n    width: 25%;\n  }\n  .row-cols-md-5 > * {\n    flex: 0 0 auto;\n    width: 20%;\n  }\n  .row-cols-md-6 > * {\n    flex: 0 0 auto;\n    width: 16.6666666667%;\n  }\n  .col-md-auto {\n    flex: 0 0 auto;\n    width: auto;\n  }\n  .col-md-1 {\n    flex: 0 0 auto;\n    width: 8.33333333%;\n  }\n  .col-md-2 {\n    flex: 0 0 auto;\n    width: 16.66666667%;\n  }\n  .col-md-3 {\n    flex: 0 0 auto;\n    width: 25%;\n  }\n  .col-md-4 {\n    flex: 0 0 auto;\n    width: 33.33333333%;\n  }\n  .col-md-5 {\n    flex: 0 0 auto;\n    width: 41.66666667%;\n  }\n  .col-md-6 {\n    flex: 0 0 auto;\n    width: 50%;\n  }\n  .col-md-7 {\n    flex: 0 0 auto;\n    width: 58.33333333%;\n  }\n  .col-md-8 {\n    flex: 0 0 auto;\n    width: 66.66666667%;\n  }\n  .col-md-9 {\n    flex: 0 0 auto;\n    width: 75%;\n  }\n  .col-md-10 {\n    flex: 0 0 auto;\n    width: 83.33333333%;\n  }\n  .col-md-11 {\n    flex: 0 0 auto;\n    width: 91.66666667%;\n  }\n  .col-md-12 {\n    flex: 0 0 auto;\n    width: 100%;\n  }\n  .offset-md-0 {\n    margin-left: 0;\n  }\n  .offset-md-1 {\n    margin-left: 8.33333333%;\n  }\n  .offset-md-2 {\n    margin-left: 16.66666667%;\n  }\n  .offset-md-3 {\n    margin-left: 25%;\n  }\n  .offset-md-4 {\n    margin-left: 33.33333333%;\n  }\n  .offset-md-5 {\n    margin-left: 41.66666667%;\n  }\n  .offset-md-6 {\n    margin-left: 50%;\n  }\n  .offset-md-7 {\n    margin-left: 58.33333333%;\n  }\n  .offset-md-8 {\n    margin-left: 66.66666667%;\n  }\n  .offset-md-9 {\n    margin-left: 75%;\n  }\n  .offset-md-10 {\n    margin-left: 83.33333333%;\n  }\n  .offset-md-11 {\n    margin-left: 91.66666667%;\n  }\n  .g-md-0,\n  .gx-md-0 {\n    --bs-gutter-x: 0;\n  }\n  .g-md-0,\n  .gy-md-0 {\n    --bs-gutter-y: 0;\n  }\n  .g-md-1,\n  .gx-md-1 {\n    --bs-gutter-x: 0.25rem;\n  }\n  .g-md-1,\n  .gy-md-1 {\n    --bs-gutter-y: 0.25rem;\n  }\n  .g-md-2,\n  .gx-md-2 {\n    --bs-gutter-x: 0.5rem;\n  }\n  .g-md-2,\n  .gy-md-2 {\n    --bs-gutter-y: 0.5rem;\n  }\n  .g-md-3,\n  .gx-md-3 {\n    --bs-gutter-x: 1rem;\n  }\n  .g-md-3,\n  .gy-md-3 {\n    --bs-gutter-y: 1rem;\n  }\n  .g-md-4,\n  .gx-md-4 {\n    --bs-gutter-x: 1.5rem;\n  }\n  .g-md-4,\n  .gy-md-4 {\n    --bs-gutter-y: 1.5rem;\n  }\n  .g-md-5,\n  .gx-md-5 {\n    --bs-gutter-x: 3rem;\n  }\n  .g-md-5,\n  .gy-md-5 {\n    --bs-gutter-y: 3rem;\n  }\n}\n@media (min-width: 992px) {\n  .col-lg {\n    flex: 1 0 0%;\n  }\n  .row-cols-lg-auto > * {\n    flex: 0 0 auto;\n    width: auto;\n  }\n  .row-cols-lg-1 > * {\n    flex: 0 0 auto;\n    width: 100%;\n  }\n  .row-cols-lg-2 > * {\n    flex: 0 0 auto;\n    width: 50%;\n  }\n  .row-cols-lg-3 > * {\n    flex: 0 0 auto;\n    width: 33.3333333333%;\n  }\n  .row-cols-lg-4 > * {\n    flex: 0 0 auto;\n    width: 25%;\n  }\n  .row-cols-lg-5 > * {\n    flex: 0 0 auto;\n    width: 20%;\n  }\n  .row-cols-lg-6 > * {\n    flex: 0 0 auto;\n    width: 16.6666666667%;\n  }\n  .col-lg-auto {\n    flex: 0 0 auto;\n    width: auto;\n  }\n  .col-lg-1 {\n    flex: 0 0 auto;\n    width: 8.33333333%;\n  }\n  .col-lg-2 {\n    flex: 0 0 auto;\n    width: 16.66666667%;\n  }\n  .col-lg-3 {\n    flex: 0 0 auto;\n    width: 25%;\n  }\n  .col-lg-4 {\n    flex: 0 0 auto;\n    width: 33.33333333%;\n  }\n  .col-lg-5 {\n    flex: 0 0 auto;\n    width: 41.66666667%;\n  }\n  .col-lg-6 {\n    flex: 0 0 auto;\n    width: 50%;\n  }\n  .col-lg-7 {\n    flex: 0 0 auto;\n    width: 58.33333333%;\n  }\n  .col-lg-8 {\n    flex: 0 0 auto;\n    width: 66.66666667%;\n  }\n  .col-lg-9 {\n    flex: 0 0 auto;\n    width: 75%;\n  }\n  .col-lg-10 {\n    flex: 0 0 auto;\n    width: 83.33333333%;\n  }\n  .col-lg-11 {\n    flex: 0 0 auto;\n    width: 91.66666667%;\n  }\n  .col-lg-12 {\n    flex: 0 0 auto;\n    width: 100%;\n  }\n  .offset-lg-0 {\n    margin-left: 0;\n  }\n  .offset-lg-1 {\n    margin-left: 8.33333333%;\n  }\n  .offset-lg-2 {\n    margin-left: 16.66666667%;\n  }\n  .offset-lg-3 {\n    margin-left: 25%;\n  }\n  .offset-lg-4 {\n    margin-left: 33.33333333%;\n  }\n  .offset-lg-5 {\n    margin-left: 41.66666667%;\n  }\n  .offset-lg-6 {\n    margin-left: 50%;\n  }\n  .offset-lg-7 {\n    margin-left: 58.33333333%;\n  }\n  .offset-lg-8 {\n    margin-left: 66.66666667%;\n  }\n  .offset-lg-9 {\n    margin-left: 75%;\n  }\n  .offset-lg-10 {\n    margin-left: 83.33333333%;\n  }\n  .offset-lg-11 {\n    margin-left: 91.66666667%;\n  }\n  .g-lg-0,\n  .gx-lg-0 {\n    --bs-gutter-x: 0;\n  }\n  .g-lg-0,\n  .gy-lg-0 {\n    --bs-gutter-y: 0;\n  }\n  .g-lg-1,\n  .gx-lg-1 {\n    --bs-gutter-x: 0.25rem;\n  }\n  .g-lg-1,\n  .gy-lg-1 {\n    --bs-gutter-y: 0.25rem;\n  }\n  .g-lg-2,\n  .gx-lg-2 {\n    --bs-gutter-x: 0.5rem;\n  }\n  .g-lg-2,\n  .gy-lg-2 {\n    --bs-gutter-y: 0.5rem;\n  }\n  .g-lg-3,\n  .gx-lg-3 {\n    --bs-gutter-x: 1rem;\n  }\n  .g-lg-3,\n  .gy-lg-3 {\n    --bs-gutter-y: 1rem;\n  }\n  .g-lg-4,\n  .gx-lg-4 {\n    --bs-gutter-x: 1.5rem;\n  }\n  .g-lg-4,\n  .gy-lg-4 {\n    --bs-gutter-y: 1.5rem;\n  }\n  .g-lg-5,\n  .gx-lg-5 {\n    --bs-gutter-x: 3rem;\n  }\n  .g-lg-5,\n  .gy-lg-5 {\n    --bs-gutter-y: 3rem;\n  }\n}\n@media (min-width: 1200px) {\n  .col-xl {\n    flex: 1 0 0%;\n  }\n  .row-cols-xl-auto > * {\n    flex: 0 0 auto;\n    width: auto;\n  }\n  .row-cols-xl-1 > * {\n    flex: 0 0 auto;\n    width: 100%;\n  }\n  .row-cols-xl-2 > * {\n    flex: 0 0 auto;\n    width: 50%;\n  }\n  .row-cols-xl-3 > * {\n    flex: 0 0 auto;\n    width: 33.3333333333%;\n  }\n  .row-cols-xl-4 > * {\n    flex: 0 0 auto;\n    width: 25%;\n  }\n  .row-cols-xl-5 > * {\n    flex: 0 0 auto;\n    width: 20%;\n  }\n  .row-cols-xl-6 > * {\n    flex: 0 0 auto;\n    width: 16.6666666667%;\n  }\n  .col-xl-auto {\n    flex: 0 0 auto;\n    width: auto;\n  }\n  .col-xl-1 {\n    flex: 0 0 auto;\n    width: 8.33333333%;\n  }\n  .col-xl-2 {\n    flex: 0 0 auto;\n    width: 16.66666667%;\n  }\n  .col-xl-3 {\n    flex: 0 0 auto;\n    width: 25%;\n  }\n  .col-xl-4 {\n    flex: 0 0 auto;\n    width: 33.33333333%;\n  }\n  .col-xl-5 {\n    flex: 0 0 auto;\n    width: 41.66666667%;\n  }\n  .col-xl-6 {\n    flex: 0 0 auto;\n    width: 50%;\n  }\n  .col-xl-7 {\n    flex: 0 0 auto;\n    width: 58.33333333%;\n  }\n  .col-xl-8 {\n    flex: 0 0 auto;\n    width: 66.66666667%;\n  }\n  .col-xl-9 {\n    flex: 0 0 auto;\n    width: 75%;\n  }\n  .col-xl-10 {\n    flex: 0 0 auto;\n    width: 83.33333333%;\n  }\n  .col-xl-11 {\n    flex: 0 0 auto;\n    width: 91.66666667%;\n  }\n  .col-xl-12 {\n    flex: 0 0 auto;\n    width: 100%;\n  }\n  .offset-xl-0 {\n    margin-left: 0;\n  }\n  .offset-xl-1 {\n    margin-left: 8.33333333%;\n  }\n  .offset-xl-2 {\n    margin-left: 16.66666667%;\n  }\n  .offset-xl-3 {\n    margin-left: 25%;\n  }\n  .offset-xl-4 {\n    margin-left: 33.33333333%;\n  }\n  .offset-xl-5 {\n    margin-left: 41.66666667%;\n  }\n  .offset-xl-6 {\n    margin-left: 50%;\n  }\n  .offset-xl-7 {\n    margin-left: 58.33333333%;\n  }\n  .offset-xl-8 {\n    margin-left: 66.66666667%;\n  }\n  .offset-xl-9 {\n    margin-left: 75%;\n  }\n  .offset-xl-10 {\n    margin-left: 83.33333333%;\n  }\n  .offset-xl-11 {\n    margin-left: 91.66666667%;\n  }\n  .g-xl-0,\n  .gx-xl-0 {\n    --bs-gutter-x: 0;\n  }\n  .g-xl-0,\n  .gy-xl-0 {\n    --bs-gutter-y: 0;\n  }\n  .g-xl-1,\n  .gx-xl-1 {\n    --bs-gutter-x: 0.25rem;\n  }\n  .g-xl-1,\n  .gy-xl-1 {\n    --bs-gutter-y: 0.25rem;\n  }\n  .g-xl-2,\n  .gx-xl-2 {\n    --bs-gutter-x: 0.5rem;\n  }\n  .g-xl-2,\n  .gy-xl-2 {\n    --bs-gutter-y: 0.5rem;\n  }\n  .g-xl-3,\n  .gx-xl-3 {\n    --bs-gutter-x: 1rem;\n  }\n  .g-xl-3,\n  .gy-xl-3 {\n    --bs-gutter-y: 1rem;\n  }\n  .g-xl-4,\n  .gx-xl-4 {\n    --bs-gutter-x: 1.5rem;\n  }\n  .g-xl-4,\n  .gy-xl-4 {\n    --bs-gutter-y: 1.5rem;\n  }\n  .g-xl-5,\n  .gx-xl-5 {\n    --bs-gutter-x: 3rem;\n  }\n  .g-xl-5,\n  .gy-xl-5 {\n    --bs-gutter-y: 3rem;\n  }\n}\n@media (min-width: 1400px) {\n  .col-xxl {\n    flex: 1 0 0%;\n  }\n  .row-cols-xxl-auto > * {\n    flex: 0 0 auto;\n    width: auto;\n  }\n  .row-cols-xxl-1 > * {\n    flex: 0 0 auto;\n    width: 100%;\n  }\n  .row-cols-xxl-2 > * {\n    flex: 0 0 auto;\n    width: 50%;\n  }\n  .row-cols-xxl-3 > * {\n    flex: 0 0 auto;\n    width: 33.3333333333%;\n  }\n  .row-cols-xxl-4 > * {\n    flex: 0 0 auto;\n    width: 25%;\n  }\n  .row-cols-xxl-5 > * {\n    flex: 0 0 auto;\n    width: 20%;\n  }\n  .row-cols-xxl-6 > * {\n    flex: 0 0 auto;\n    width: 16.6666666667%;\n  }\n  .col-xxl-auto {\n    flex: 0 0 auto;\n    width: auto;\n  }\n  .col-xxl-1 {\n    flex: 0 0 auto;\n    width: 8.33333333%;\n  }\n  .col-xxl-2 {\n    flex: 0 0 auto;\n    width: 16.66666667%;\n  }\n  .col-xxl-3 {\n    flex: 0 0 auto;\n    width: 25%;\n  }\n  .col-xxl-4 {\n    flex: 0 0 auto;\n    width: 33.33333333%;\n  }\n  .col-xxl-5 {\n    flex: 0 0 auto;\n    width: 41.66666667%;\n  }\n  .col-xxl-6 {\n    flex: 0 0 auto;\n    width: 50%;\n  }\n  .col-xxl-7 {\n    flex: 0 0 auto;\n    width: 58.33333333%;\n  }\n  .col-xxl-8 {\n    flex: 0 0 auto;\n    width: 66.66666667%;\n  }\n  .col-xxl-9 {\n    flex: 0 0 auto;\n    width: 75%;\n  }\n  .col-xxl-10 {\n    flex: 0 0 auto;\n    width: 83.33333333%;\n  }\n  .col-xxl-11 {\n    flex: 0 0 auto;\n    width: 91.66666667%;\n  }\n  .col-xxl-12 {\n    flex: 0 0 auto;\n    width: 100%;\n  }\n  .offset-xxl-0 {\n    margin-left: 0;\n  }\n  .offset-xxl-1 {\n    margin-left: 8.33333333%;\n  }\n  .offset-xxl-2 {\n    margin-left: 16.66666667%;\n  }\n  .offset-xxl-3 {\n    margin-left: 25%;\n  }\n  .offset-xxl-4 {\n    margin-left: 33.33333333%;\n  }\n  .offset-xxl-5 {\n    margin-left: 41.66666667%;\n  }\n  .offset-xxl-6 {\n    margin-left: 50%;\n  }\n  .offset-xxl-7 {\n    margin-left: 58.33333333%;\n  }\n  .offset-xxl-8 {\n    margin-left: 66.66666667%;\n  }\n  .offset-xxl-9 {\n    margin-left: 75%;\n  }\n  .offset-xxl-10 {\n    margin-left: 83.33333333%;\n  }\n  .offset-xxl-11 {\n    margin-left: 91.66666667%;\n  }\n  .g-xxl-0,\n  .gx-xxl-0 {\n    --bs-gutter-x: 0;\n  }\n  .g-xxl-0,\n  .gy-xxl-0 {\n    --bs-gutter-y: 0;\n  }\n  .g-xxl-1,\n  .gx-xxl-1 {\n    --bs-gutter-x: 0.25rem;\n  }\n  .g-xxl-1,\n  .gy-xxl-1 {\n    --bs-gutter-y: 0.25rem;\n  }\n  .g-xxl-2,\n  .gx-xxl-2 {\n    --bs-gutter-x: 0.5rem;\n  }\n  .g-xxl-2,\n  .gy-xxl-2 {\n    --bs-gutter-y: 0.5rem;\n  }\n  .g-xxl-3,\n  .gx-xxl-3 {\n    --bs-gutter-x: 1rem;\n  }\n  .g-xxl-3,\n  .gy-xxl-3 {\n    --bs-gutter-y: 1rem;\n  }\n  .g-xxl-4,\n  .gx-xxl-4 {\n    --bs-gutter-x: 1.5rem;\n  }\n  .g-xxl-4,\n  .gy-xxl-4 {\n    --bs-gutter-y: 1.5rem;\n  }\n  .g-xxl-5,\n  .gx-xxl-5 {\n    --bs-gutter-x: 3rem;\n  }\n  .g-xxl-5,\n  .gy-xxl-5 {\n    --bs-gutter-y: 3rem;\n  }\n}\n.table {\n  --bs-table-color: var(--bs-body-color);\n  --bs-table-bg: transparent;\n  --bs-table-border-color: var(--bs-border-color);\n  --bs-table-accent-bg: transparent;\n  --bs-table-striped-color: var(--bs-body-color);\n  --bs-table-striped-bg: rgba(0, 0, 0, 0.05);\n  --bs-table-active-color: var(--bs-body-color);\n  --bs-table-active-bg: rgba(0, 0, 0, 0.1);\n  --bs-table-hover-color: var(--bs-body-color);\n  --bs-table-hover-bg: rgba(0, 0, 0, 0.075);\n  width: 100%;\n  margin-bottom: 1rem;\n  color: var(--bs-table-color);\n  vertical-align: top;\n  border-color: var(--bs-table-border-color);\n}\n.table > :not(caption) > * > * {\n  padding: 0.5rem 0.5rem;\n  background-color: var(--bs-table-bg);\n  border-bottom-width: 0.125rem;\n  box-shadow: inset 0 0 0 9999px var(--bs-table-accent-bg);\n}\n.table > tbody {\n  vertical-align: inherit;\n}\n.table > thead {\n  vertical-align: bottom;\n}\n\n.table-group-divider {\n  border-top: 0.25rem solid currentcolor;\n}\n\n.caption-top {\n  caption-side: top;\n}\n\n.table-sm > :not(caption) > * > * {\n  padding: 0.25rem 0.25rem;\n}\n\n.table-bordered > :not(caption) > * {\n  border-width: 0.125rem 0;\n}\n.table-bordered > :not(caption) > * > * {\n  border-width: 0 0.125rem;\n}\n\n.table-borderless > :not(caption) > * > * {\n  border-bottom-width: 0;\n}\n.table-borderless > :not(:first-child) {\n  border-top-width: 0;\n}\n\n.table-striped > tbody > tr:nth-of-type(odd) > * {\n  --bs-table-accent-bg: var(--bs-table-striped-bg);\n  color: var(--bs-table-striped-color);\n}\n\n.table-striped-columns > :not(caption) > tr > :nth-child(even) {\n  --bs-table-accent-bg: var(--bs-table-striped-bg);\n  color: var(--bs-table-striped-color);\n}\n\n.table-active {\n  --bs-table-accent-bg: var(--bs-table-active-bg);\n  color: var(--bs-table-active-color);\n}\n\n.table-hover > tbody > tr:hover > * {\n  --bs-table-accent-bg: var(--bs-table-hover-bg);\n  color: var(--bs-table-hover-color);\n}\n\n.table-primary {\n  --bs-table-color: #000;\n  --bs-table-bg: #d1f2eb;\n  --bs-table-border-color: #bcdad4;\n  --bs-table-striped-bg: #c7e6df;\n  --bs-table-striped-color: #000;\n  --bs-table-active-bg: #bcdad4;\n  --bs-table-active-color: #000;\n  --bs-table-hover-bg: #c1e0d9;\n  --bs-table-hover-color: #000;\n  color: var(--bs-table-color);\n  border-color: var(--bs-table-border-color);\n}\n\n.table-secondary {\n  --bs-table-color: #000;\n  --bs-table-bg: #d5d8dc;\n  --bs-table-border-color: #c0c2c6;\n  --bs-table-striped-bg: #cacdd1;\n  --bs-table-striped-color: #000;\n  --bs-table-active-bg: #c0c2c6;\n  --bs-table-active-color: #000;\n  --bs-table-hover-bg: #c5c8cc;\n  --bs-table-hover-color: #000;\n  color: var(--bs-table-color);\n  border-color: var(--bs-table-border-color);\n}\n\n.table-success {\n  --bs-table-color: #000;\n  --bs-table-bg: #d1e7dd;\n  --bs-table-border-color: #bcd0c7;\n  --bs-table-striped-bg: #c7dbd2;\n  --bs-table-striped-color: #000;\n  --bs-table-active-bg: #bcd0c7;\n  --bs-table-active-color: #000;\n  --bs-table-hover-bg: #c1d6cc;\n  --bs-table-hover-color: #000;\n  color: var(--bs-table-color);\n  border-color: var(--bs-table-border-color);\n}\n\n.table-info {\n  --bs-table-color: #000;\n  --bs-table-bg: #cff4fc;\n  --bs-table-border-color: #badce3;\n  --bs-table-striped-bg: #c5e8ef;\n  --bs-table-striped-color: #000;\n  --bs-table-active-bg: #badce3;\n  --bs-table-active-color: #000;\n  --bs-table-hover-bg: #bfe2e9;\n  --bs-table-hover-color: #000;\n  color: var(--bs-table-color);\n  border-color: var(--bs-table-border-color);\n}\n\n.table-warning {\n  --bs-table-color: #000;\n  --bs-table-bg: #fff3cd;\n  --bs-table-border-color: #e6dbb9;\n  --bs-table-striped-bg: #f2e7c3;\n  --bs-table-striped-color: #000;\n  --bs-table-active-bg: #e6dbb9;\n  --bs-table-active-color: #000;\n  --bs-table-hover-bg: #ece1be;\n  --bs-table-hover-color: #000;\n  color: var(--bs-table-color);\n  border-color: var(--bs-table-border-color);\n}\n\n.table-danger {\n  --bs-table-color: #000;\n  --bs-table-bg: #f8d7da;\n  --bs-table-border-color: #dfc2c4;\n  --bs-table-striped-bg: #eccccf;\n  --bs-table-striped-color: #000;\n  --bs-table-active-bg: #dfc2c4;\n  --bs-table-active-color: #000;\n  --bs-table-hover-bg: #e5c7ca;\n  --bs-table-hover-color: #000;\n  color: var(--bs-table-color);\n  border-color: var(--bs-table-border-color);\n}\n\n.table-light {\n  --bs-table-color: #000;\n  --bs-table-bg: #f8f9fa;\n  --bs-table-border-color: #dfe0e1;\n  --bs-table-striped-bg: #ecedee;\n  --bs-table-striped-color: #000;\n  --bs-table-active-bg: #dfe0e1;\n  --bs-table-active-color: #000;\n  --bs-table-hover-bg: #e5e6e7;\n  --bs-table-hover-color: #000;\n  color: var(--bs-table-color);\n  border-color: var(--bs-table-border-color);\n}\n\n.table-dark {\n  --bs-table-color: #fff;\n  --bs-table-bg: #212529;\n  --bs-table-border-color: #373b3e;\n  --bs-table-striped-bg: #2c3034;\n  --bs-table-striped-color: #fff;\n  --bs-table-active-bg: #373b3e;\n  --bs-table-active-color: #fff;\n  --bs-table-hover-bg: #323539;\n  --bs-table-hover-color: #fff;\n  color: var(--bs-table-color);\n  border-color: var(--bs-table-border-color);\n}\n\n.table-responsive {\n  overflow-x: auto;\n  -webkit-overflow-scrolling: touch;\n}\n\n@media (max-width: 575.98px) {\n  .table-responsive-sm {\n    overflow-x: auto;\n    -webkit-overflow-scrolling: touch;\n  }\n}\n@media (max-width: 767.98px) {\n  .table-responsive-md {\n    overflow-x: auto;\n    -webkit-overflow-scrolling: touch;\n  }\n}\n@media (max-width: 991.98px) {\n  .table-responsive-lg {\n    overflow-x: auto;\n    -webkit-overflow-scrolling: touch;\n  }\n}\n@media (max-width: 1199.98px) {\n  .table-responsive-xl {\n    overflow-x: auto;\n    -webkit-overflow-scrolling: touch;\n  }\n}\n@media (max-width: 1399.98px) {\n  .table-responsive-xxl {\n    overflow-x: auto;\n    -webkit-overflow-scrolling: touch;\n  }\n}\n.form-label {\n  margin-bottom: 0.5rem;\n}\n\n.col-form-label {\n  padding-top: 0.5rem;\n  padding-bottom: 0.5rem;\n  margin-bottom: 0;\n  font-size: inherit;\n  line-height: 1.5;\n}\n\n.col-form-label-lg {\n  padding-top: 0.625rem;\n  padding-bottom: 0.625rem;\n  font-size: 1.25rem;\n}\n\n.col-form-label-sm {\n  padding-top: 0.375rem;\n  padding-bottom: 0.375rem;\n  font-size: 0.875rem;\n}\n\n.form-text {\n  margin-top: 0.25rem;\n  font-size: 0.875em;\n  color: #6c757d;\n}\n\n.form-control {\n  display: block;\n  width: 100%;\n  padding: 0.375rem 0.75rem;\n  font-size: 1rem;\n  font-weight: 400;\n  line-height: 1.5;\n  color: #212529;\n  background-color: #fff;\n  background-clip: padding-box;\n  border: 0.125rem solid #ced4da;\n  -webkit-appearance: none;\n     -moz-appearance: none;\n          appearance: none;\n  border-radius: 0.5rem;\n  transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n@media (prefers-reduced-motion: reduce) {\n  .form-control {\n    transition: none;\n  }\n}\n.form-control[type=file] {\n  overflow: hidden;\n}\n.form-control[type=file]:not(:disabled):not([readonly]) {\n  cursor: pointer;\n}\n.form-control:focus {\n  color: #212529;\n  background-color: #fff;\n  border-color: #8ddece;\n  outline: 0;\n  box-shadow: 0 0 0 0.25rem rgba(26, 188, 156, 0.25);\n}\n.form-control::-webkit-date-and-time-value {\n  height: 1.5em;\n}\n.form-control::-moz-placeholder {\n  color: #6c757d;\n  opacity: 1;\n}\n.form-control::placeholder {\n  color: #6c757d;\n  opacity: 1;\n}\n.form-control:disabled {\n  background-color: #e9ecef;\n  opacity: 1;\n}\n.form-control::file-selector-button {\n  padding: 0.375rem 0.75rem;\n  margin: -0.375rem -0.75rem;\n  -webkit-margin-end: 0.75rem;\n          margin-inline-end: 0.75rem;\n  color: #212529;\n  background-color: #e9ecef;\n  pointer-events: none;\n  border-color: inherit;\n  border-style: solid;\n  border-width: 0;\n  border-inline-end-width: 0.125rem;\n  border-radius: 0;\n  transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n@media (prefers-reduced-motion: reduce) {\n  .form-control::file-selector-button {\n    transition: none;\n  }\n}\n.form-control:hover:not(:disabled):not([readonly])::file-selector-button {\n  background-color: #dde0e3;\n}\n\n.form-control-plaintext {\n  display: block;\n  width: 100%;\n  padding: 0.375rem 0;\n  margin-bottom: 0;\n  line-height: 1.5;\n  color: #212529;\n  background-color: transparent;\n  border: solid transparent;\n  border-width: 0.125rem 0;\n}\n.form-control-plaintext:focus {\n  outline: 0;\n}\n.form-control-plaintext.form-control-sm, .form-control-plaintext.form-control-lg {\n  padding-right: 0;\n  padding-left: 0;\n}\n\n.form-control-sm {\n  min-height: calc(1.5em + 0.75rem);\n  padding: 0.25rem 0.5rem;\n  font-size: 0.875rem;\n  border-radius: 0.25rem;\n}\n.form-control-sm::file-selector-button {\n  padding: 0.25rem 0.5rem;\n  margin: -0.25rem -0.5rem;\n  -webkit-margin-end: 0.5rem;\n          margin-inline-end: 0.5rem;\n}\n\n.form-control-lg {\n  min-height: calc(1.5em + 1.25rem);\n  padding: 0.5rem 1rem;\n  font-size: 1.25rem;\n  border-radius: 0.75rem;\n}\n.form-control-lg::file-selector-button {\n  padding: 0.5rem 1rem;\n  margin: -0.5rem -1rem;\n  -webkit-margin-end: 1rem;\n          margin-inline-end: 1rem;\n}\n\ntextarea.form-control {\n  min-height: calc(1.5em + 1rem);\n}\ntextarea.form-control-sm {\n  min-height: calc(1.5em + 0.75rem);\n}\ntextarea.form-control-lg {\n  min-height: calc(1.5em + 1.25rem);\n}\n\n.form-control-color {\n  width: 3rem;\n  height: calc(1.5em + 1rem);\n  padding: 0.375rem;\n}\n.form-control-color:not(:disabled):not([readonly]) {\n  cursor: pointer;\n}\n.form-control-color::-moz-color-swatch {\n  border: 0 !important;\n  border-radius: 0.5rem;\n}\n.form-control-color::-webkit-color-swatch {\n  border-radius: 0.5rem;\n}\n.form-control-color.form-control-sm {\n  height: calc(1.5em + 0.75rem);\n}\n.form-control-color.form-control-lg {\n  height: calc(1.5em + 1.25rem);\n}\n\n.form-select {\n  display: block;\n  width: 100%;\n  padding: 0.375rem 2.25rem 0.375rem 0.75rem;\n  -moz-padding-start: calc(0.75rem - 3px);\n  font-size: 1rem;\n  font-weight: 400;\n  line-height: 1.5;\n  color: #212529;\n  background-color: #fff;\n  background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e\");\n  background-repeat: no-repeat;\n  background-position: right 0.75rem center;\n  background-size: 16px 12px;\n  border: 0.125rem solid #ced4da;\n  border-radius: 0.5rem;\n  transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n  -webkit-appearance: none;\n     -moz-appearance: none;\n          appearance: none;\n}\n@media (prefers-reduced-motion: reduce) {\n  .form-select {\n    transition: none;\n  }\n}\n.form-select:focus {\n  border-color: #8ddece;\n  outline: 0;\n  box-shadow: 0 0 0 0.25rem rgba(26, 188, 156, 0.25);\n}\n.form-select[multiple], .form-select[size]:not([size=\"1\"]) {\n  padding-right: 0.75rem;\n  background-image: none;\n}\n.form-select:disabled {\n  background-color: #e9ecef;\n}\n.form-select:-moz-focusring {\n  color: transparent;\n  text-shadow: 0 0 0 #212529;\n}\n\n.form-select-sm {\n  padding-top: 0.25rem;\n  padding-bottom: 0.25rem;\n  padding-left: 0.5rem;\n  font-size: 0.875rem;\n  border-radius: 0.25rem;\n}\n\n.form-select-lg {\n  padding-top: 0.5rem;\n  padding-bottom: 0.5rem;\n  padding-left: 1rem;\n  font-size: 1.25rem;\n  border-radius: 0.75rem;\n}\n\n.form-check {\n  display: block;\n  min-height: 1.5rem;\n  padding-left: 1.5em;\n  margin-bottom: 0.125rem;\n}\n.form-check .form-check-input {\n  float: left;\n  margin-left: -1.5em;\n}\n\n.form-check-reverse {\n  padding-right: 1.5em;\n  padding-left: 0;\n  text-align: right;\n}\n.form-check-reverse .form-check-input {\n  float: right;\n  margin-right: -1.5em;\n  margin-left: 0;\n}\n\n.form-check-input {\n  width: 1em;\n  height: 1em;\n  margin-top: 0.25em;\n  vertical-align: top;\n  background-color: #fff;\n  background-repeat: no-repeat;\n  background-position: center;\n  background-size: contain;\n  border: 1px solid rgba(0, 0, 0, 0.25);\n  -webkit-appearance: none;\n     -moz-appearance: none;\n          appearance: none;\n  -webkit-print-color-adjust: exact;\n          print-color-adjust: exact;\n}\n.form-check-input[type=checkbox] {\n  border-radius: 0.25em;\n}\n.form-check-input[type=radio] {\n  border-radius: 50%;\n}\n.form-check-input:active {\n  filter: brightness(90%);\n}\n.form-check-input:focus {\n  border-color: #8ddece;\n  outline: 0;\n  box-shadow: 0 0 0 0.25rem rgba(26, 188, 156, 0.25);\n}\n.form-check-input:checked {\n  background-color: #1abc9c;\n  border-color: #1abc9c;\n}\n.form-check-input:checked[type=checkbox] {\n  background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m6 10 3 3 6-6'/%3e%3c/svg%3e\");\n}\n.form-check-input:checked[type=radio] {\n  background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='2' fill='%23fff'/%3e%3c/svg%3e\");\n}\n.form-check-input[type=checkbox]:indeterminate {\n  background-color: #1abc9c;\n  border-color: #1abc9c;\n  background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10h8'/%3e%3c/svg%3e\");\n}\n.form-check-input:disabled {\n  pointer-events: none;\n  filter: none;\n  opacity: 0.5;\n}\n.form-check-input[disabled] ~ .form-check-label, .form-check-input:disabled ~ .form-check-label {\n  cursor: default;\n  opacity: 0.5;\n}\n\n.form-switch {\n  padding-left: 2.5em;\n}\n.form-switch .form-check-input {\n  width: 2em;\n  margin-left: -2.5em;\n  background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%280, 0, 0, 0.25%29'/%3e%3c/svg%3e\");\n  background-position: left center;\n  border-radius: 2em;\n  transition: background-position 0.15s ease-in-out;\n}\n@media (prefers-reduced-motion: reduce) {\n  .form-switch .form-check-input {\n    transition: none;\n  }\n}\n.form-switch .form-check-input:focus {\n  background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%238ddece'/%3e%3c/svg%3e\");\n}\n.form-switch .form-check-input:checked {\n  background-position: right center;\n  background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e\");\n}\n.form-switch.form-check-reverse {\n  padding-right: 2.5em;\n  padding-left: 0;\n}\n.form-switch.form-check-reverse .form-check-input {\n  margin-right: -2.5em;\n  margin-left: 0;\n}\n\n.form-check-inline {\n  display: inline-block;\n  margin-right: 1rem;\n}\n\n.btn-check {\n  position: absolute;\n  clip: rect(0, 0, 0, 0);\n  pointer-events: none;\n}\n.btn-check[disabled] + .btn, .btn-check:disabled + .btn {\n  pointer-events: none;\n  filter: none;\n  opacity: 0.65;\n}\n\n.form-range {\n  width: 100%;\n  height: 1.5rem;\n  padding: 0;\n  background-color: transparent;\n  -webkit-appearance: none;\n     -moz-appearance: none;\n          appearance: none;\n}\n.form-range:focus {\n  outline: 0;\n}\n.form-range:focus::-webkit-slider-thumb {\n  box-shadow: 0 0 0 1px #fff, 0 0 0 0.25rem rgba(26, 188, 156, 0.25);\n}\n.form-range:focus::-moz-range-thumb {\n  box-shadow: 0 0 0 1px #fff, 0 0 0 0.25rem rgba(26, 188, 156, 0.25);\n}\n.form-range::-moz-focus-outer {\n  border: 0;\n}\n.form-range::-webkit-slider-thumb {\n  width: 1rem;\n  height: 1rem;\n  margin-top: -0.25rem;\n  background-color: #1abc9c;\n  border: 0;\n  border-radius: 1rem;\n  -webkit-transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n  transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n  -webkit-appearance: none;\n          appearance: none;\n}\n@media (prefers-reduced-motion: reduce) {\n  .form-range::-webkit-slider-thumb {\n    -webkit-transition: none;\n    transition: none;\n  }\n}\n.form-range::-webkit-slider-thumb:active {\n  background-color: #baebe1;\n}\n.form-range::-webkit-slider-runnable-track {\n  width: 100%;\n  height: 0.5rem;\n  color: transparent;\n  cursor: pointer;\n  background-color: #dee2e6;\n  border-color: transparent;\n  border-radius: 1rem;\n}\n.form-range::-moz-range-thumb {\n  width: 1rem;\n  height: 1rem;\n  background-color: #1abc9c;\n  border: 0;\n  border-radius: 1rem;\n  -moz-transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n  transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n  -moz-appearance: none;\n       appearance: none;\n}\n@media (prefers-reduced-motion: reduce) {\n  .form-range::-moz-range-thumb {\n    -moz-transition: none;\n    transition: none;\n  }\n}\n.form-range::-moz-range-thumb:active {\n  background-color: #baebe1;\n}\n.form-range::-moz-range-track {\n  width: 100%;\n  height: 0.5rem;\n  color: transparent;\n  cursor: pointer;\n  background-color: #dee2e6;\n  border-color: transparent;\n  border-radius: 1rem;\n}\n.form-range:disabled {\n  pointer-events: none;\n}\n.form-range:disabled::-webkit-slider-thumb {\n  background-color: #adb5bd;\n}\n.form-range:disabled::-moz-range-thumb {\n  background-color: #adb5bd;\n}\n\n.form-floating {\n  position: relative;\n}\n.form-floating > .form-control,\n.form-floating > .form-control-plaintext,\n.form-floating > .form-select {\n  height: 5.5rem;\n  line-height: 1.25;\n}\n.form-floating > label {\n  position: absolute;\n  top: 0;\n  left: 0;\n  width: 100%;\n  height: 100%;\n  padding: 1.5rem 0;\n  overflow: hidden;\n  text-align: start;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n  pointer-events: none;\n  border: 0.125rem solid transparent;\n  transform-origin: 0 0;\n  transition: opacity 0.1s ease-in-out, transform 0.1s ease-in-out;\n}\n@media (prefers-reduced-motion: reduce) {\n  .form-floating > label {\n    transition: none;\n  }\n}\n.form-floating > .form-control,\n.form-floating > .form-control-plaintext {\n  padding: 1.5rem 0;\n}\n.form-floating > .form-control::-moz-placeholder, .form-floating > .form-control-plaintext::-moz-placeholder {\n  color: transparent;\n}\n.form-floating > .form-control::placeholder,\n.form-floating > .form-control-plaintext::placeholder {\n  color: transparent;\n}\n.form-floating > .form-control:not(:-moz-placeholder-shown), .form-floating > .form-control-plaintext:not(:-moz-placeholder-shown) {\n  padding-top: 2.5rem;\n  padding-bottom: 1.5rem;\n}\n.form-floating > .form-control:focus, .form-floating > .form-control:not(:placeholder-shown),\n.form-floating > .form-control-plaintext:focus,\n.form-floating > .form-control-plaintext:not(:placeholder-shown) {\n  padding-top: 2.5rem;\n  padding-bottom: 1.5rem;\n}\n.form-floating > .form-control:-webkit-autofill,\n.form-floating > .form-control-plaintext:-webkit-autofill {\n  padding-top: 2.5rem;\n  padding-bottom: 1.5rem;\n}\n.form-floating > .form-select {\n  padding-top: 2.5rem;\n  padding-bottom: 1.5rem;\n}\n.form-floating > .form-control:not(:-moz-placeholder-shown) ~ label {\n  opacity: 0.65;\n  transform: scale(0.65) translateY(-0.5rem) translateX(0rem);\n}\n.form-floating > .form-control:focus ~ label,\n.form-floating > .form-control:not(:placeholder-shown) ~ label,\n.form-floating > .form-control-plaintext ~ label,\n.form-floating > .form-select ~ label {\n  opacity: 0.65;\n  transform: scale(0.65) translateY(-0.5rem) translateX(0rem);\n}\n.form-floating > .form-control:-webkit-autofill ~ label {\n  opacity: 0.65;\n  transform: scale(0.65) translateY(-0.5rem) translateX(0rem);\n}\n.form-floating > .form-control-plaintext ~ label {\n  border-width: 0.125rem 0;\n}\n\n.input-group {\n  position: relative;\n  display: flex;\n  flex-wrap: wrap;\n  align-items: stretch;\n  width: 100%;\n}\n.input-group > .form-control,\n.input-group > .form-select,\n.input-group > .form-floating {\n  position: relative;\n  flex: 1 1 auto;\n  width: 1%;\n  min-width: 0;\n}\n.input-group > .form-control:focus,\n.input-group > .form-select:focus,\n.input-group > .form-floating:focus-within {\n  z-index: 5;\n}\n.input-group .btn {\n  position: relative;\n  z-index: 2;\n}\n.input-group .btn:focus {\n  z-index: 5;\n}\n\n.input-group-text {\n  display: flex;\n  align-items: center;\n  padding: 0.375rem 0.75rem;\n  font-size: 1rem;\n  font-weight: 400;\n  line-height: 1.5;\n  color: #212529;\n  text-align: center;\n  white-space: nowrap;\n  background-color: #e9ecef;\n  border: 0.125rem solid #ced4da;\n  border-radius: 0.5rem;\n}\n\n.input-group-lg > .form-control,\n.input-group-lg > .form-select,\n.input-group-lg > .input-group-text,\n.input-group-lg > .btn {\n  padding: 0.5rem 1rem;\n  font-size: 1.25rem;\n  border-radius: 0.75rem;\n}\n\n.input-group-sm > .form-control,\n.input-group-sm > .form-select,\n.input-group-sm > .input-group-text,\n.input-group-sm > .btn {\n  padding: 0.25rem 0.5rem;\n  font-size: 0.875rem;\n  border-radius: 0.25rem;\n}\n\n.input-group-lg > .form-select,\n.input-group-sm > .form-select {\n  padding-right: 3rem;\n}\n\n.input-group:not(.has-validation) > :not(:last-child):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating),\n.input-group:not(.has-validation) > .dropdown-toggle:nth-last-child(n+3),\n.input-group:not(.has-validation) > .form-floating:not(:last-child) > .form-control,\n.input-group:not(.has-validation) > .form-floating:not(:last-child) > .form-select {\n  border-top-right-radius: 0;\n  border-bottom-right-radius: 0;\n}\n.input-group.has-validation > :nth-last-child(n+3):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating),\n.input-group.has-validation > .dropdown-toggle:nth-last-child(n+4),\n.input-group.has-validation > .form-floating:nth-last-child(n+3) > .form-control,\n.input-group.has-validation > .form-floating:nth-last-child(n+3) > .form-select {\n  border-top-right-radius: 0;\n  border-bottom-right-radius: 0;\n}\n.input-group > :not(:first-child):not(.dropdown-menu):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback) {\n  margin-left: -0.125rem;\n  border-top-left-radius: 0;\n  border-bottom-left-radius: 0;\n}\n.input-group > .form-floating:not(:first-child) > .form-control,\n.input-group > .form-floating:not(:first-child) > .form-select {\n  border-top-left-radius: 0;\n  border-bottom-left-radius: 0;\n}\n\n.valid-feedback {\n  display: none;\n  width: 100%;\n  margin-top: 0.25rem;\n  font-size: 0.875em;\n  color: #198754;\n}\n\n.valid-tooltip {\n  position: absolute;\n  top: 100%;\n  z-index: 5;\n  display: none;\n  max-width: 100%;\n  padding: 0.25rem 0.5rem;\n  margin-top: 0.1rem;\n  font-size: 0.875rem;\n  color: #fff;\n  background-color: rgba(25, 135, 84, 0.9);\n  border-radius: 0.5rem;\n}\n\n.was-validated :valid ~ .valid-feedback,\n.was-validated :valid ~ .valid-tooltip,\n.is-valid ~ .valid-feedback,\n.is-valid ~ .valid-tooltip {\n  display: block;\n}\n\n.was-validated .form-control:valid, .form-control.is-valid {\n  border-color: #198754;\n  padding-right: calc(1.5em + 0.75rem);\n  background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23198754' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e\");\n  background-repeat: no-repeat;\n  background-position: right calc(0.375em + 0.1875rem) center;\n  background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);\n}\n.was-validated .form-control:valid:focus, .form-control.is-valid:focus {\n  border-color: #198754;\n  box-shadow: 0 0 0 0.25rem rgba(25, 135, 84, 0.25);\n}\n\n.was-validated textarea.form-control:valid, textarea.form-control.is-valid {\n  padding-right: calc(1.5em + 0.75rem);\n  background-position: top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem);\n}\n\n.was-validated .form-select:valid, .form-select.is-valid {\n  border-color: #198754;\n}\n.was-validated .form-select:valid:not([multiple]):not([size]), .was-validated .form-select:valid:not([multiple])[size=\"1\"], .form-select.is-valid:not([multiple]):not([size]), .form-select.is-valid:not([multiple])[size=\"1\"] {\n  padding-right: 4.125rem;\n  background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e\"), url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23198754' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e\");\n  background-position: right 0.75rem center, center right 2.25rem;\n  background-size: 16px 12px, calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);\n}\n.was-validated .form-select:valid:focus, .form-select.is-valid:focus {\n  border-color: #198754;\n  box-shadow: 0 0 0 0.25rem rgba(25, 135, 84, 0.25);\n}\n\n.was-validated .form-control-color:valid, .form-control-color.is-valid {\n  width: calc(3rem + calc(1.5em + 0.75rem));\n}\n\n.was-validated .form-check-input:valid, .form-check-input.is-valid {\n  border-color: #198754;\n}\n.was-validated .form-check-input:valid:checked, .form-check-input.is-valid:checked {\n  background-color: #198754;\n}\n.was-validated .form-check-input:valid:focus, .form-check-input.is-valid:focus {\n  box-shadow: 0 0 0 0.25rem rgba(25, 135, 84, 0.25);\n}\n.was-validated .form-check-input:valid ~ .form-check-label, .form-check-input.is-valid ~ .form-check-label {\n  color: #198754;\n}\n\n.form-check-inline .form-check-input ~ .valid-feedback {\n  margin-left: 0.5em;\n}\n\n.was-validated .input-group > .form-control:not(:focus):valid, .input-group > .form-control:not(:focus).is-valid,\n.was-validated .input-group > .form-select:not(:focus):valid,\n.input-group > .form-select:not(:focus).is-valid,\n.was-validated .input-group > .form-floating:not(:focus-within):valid,\n.input-group > .form-floating:not(:focus-within).is-valid {\n  z-index: 3;\n}\n\n.invalid-feedback {\n  display: none;\n  width: 100%;\n  margin-top: 0.25rem;\n  font-size: 0.875em;\n  color: #dc3545;\n}\n\n.invalid-tooltip {\n  position: absolute;\n  top: 100%;\n  z-index: 5;\n  display: none;\n  max-width: 100%;\n  padding: 0.25rem 0.5rem;\n  margin-top: 0.1rem;\n  font-size: 0.875rem;\n  color: #fff;\n  background-color: rgba(220, 53, 69, 0.9);\n  border-radius: 0.5rem;\n}\n\n.was-validated :invalid ~ .invalid-feedback,\n.was-validated :invalid ~ .invalid-tooltip,\n.is-invalid ~ .invalid-feedback,\n.is-invalid ~ .invalid-tooltip {\n  display: block;\n}\n\n.was-validated .form-control:invalid, .form-control.is-invalid {\n  border-color: #dc3545;\n  padding-right: calc(1.5em + 0.75rem);\n  background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e\");\n  background-repeat: no-repeat;\n  background-position: right calc(0.375em + 0.1875rem) center;\n  background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);\n}\n.was-validated .form-control:invalid:focus, .form-control.is-invalid:focus {\n  border-color: #dc3545;\n  box-shadow: 0 0 0 0.25rem rgba(220, 53, 69, 0.25);\n}\n\n.was-validated textarea.form-control:invalid, textarea.form-control.is-invalid {\n  padding-right: calc(1.5em + 0.75rem);\n  background-position: top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem);\n}\n\n.was-validated .form-select:invalid, .form-select.is-invalid {\n  border-color: #dc3545;\n}\n.was-validated .form-select:invalid:not([multiple]):not([size]), .was-validated .form-select:invalid:not([multiple])[size=\"1\"], .form-select.is-invalid:not([multiple]):not([size]), .form-select.is-invalid:not([multiple])[size=\"1\"] {\n  padding-right: 4.125rem;\n  background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e\"), url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e\");\n  background-position: right 0.75rem center, center right 2.25rem;\n  background-size: 16px 12px, calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);\n}\n.was-validated .form-select:invalid:focus, .form-select.is-invalid:focus {\n  border-color: #dc3545;\n  box-shadow: 0 0 0 0.25rem rgba(220, 53, 69, 0.25);\n}\n\n.was-validated .form-control-color:invalid, .form-control-color.is-invalid {\n  width: calc(3rem + calc(1.5em + 0.75rem));\n}\n\n.was-validated .form-check-input:invalid, .form-check-input.is-invalid {\n  border-color: #dc3545;\n}\n.was-validated .form-check-input:invalid:checked, .form-check-input.is-invalid:checked {\n  background-color: #dc3545;\n}\n.was-validated .form-check-input:invalid:focus, .form-check-input.is-invalid:focus {\n  box-shadow: 0 0 0 0.25rem rgba(220, 53, 69, 0.25);\n}\n.was-validated .form-check-input:invalid ~ .form-check-label, .form-check-input.is-invalid ~ .form-check-label {\n  color: #dc3545;\n}\n\n.form-check-inline .form-check-input ~ .invalid-feedback {\n  margin-left: 0.5em;\n}\n\n.was-validated .input-group > .form-control:not(:focus):invalid, .input-group > .form-control:not(:focus).is-invalid,\n.was-validated .input-group > .form-select:not(:focus):invalid,\n.input-group > .form-select:not(:focus).is-invalid,\n.was-validated .input-group > .form-floating:not(:focus-within):invalid,\n.input-group > .form-floating:not(:focus-within).is-invalid {\n  z-index: 4;\n}\n\n.btn {\n  --bs-btn-padding-x: 0.75rem;\n  --bs-btn-padding-y: 0.375rem;\n  --bs-btn-font-family: ;\n  --bs-btn-font-size: 1rem;\n  --bs-btn-font-weight: 400;\n  --bs-btn-line-height: 1.5;\n  --bs-btn-color: #212529;\n  --bs-btn-bg: transparent;\n  --bs-btn-border-width: 0.125rem;\n  --bs-btn-border-color: transparent;\n  --bs-btn-border-radius: 0.5rem;\n  --bs-btn-hover-border-color: transparent;\n  --bs-btn-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);\n  --bs-btn-disabled-opacity: 0.65;\n  --bs-btn-focus-box-shadow: 0 0 0 0.25rem rgba(var(--bs-btn-focus-shadow-rgb), .5);\n  display: inline-block;\n  padding: var(--bs-btn-padding-y) var(--bs-btn-padding-x);\n  font-family: var(--bs-btn-font-family);\n  font-size: var(--bs-btn-font-size);\n  font-weight: var(--bs-btn-font-weight);\n  line-height: var(--bs-btn-line-height);\n  color: var(--bs-btn-color);\n  text-align: center;\n  text-decoration: none;\n  vertical-align: middle;\n  cursor: pointer;\n  -webkit-user-select: none;\n     -moz-user-select: none;\n          user-select: none;\n  border: var(--bs-btn-border-width) solid var(--bs-btn-border-color);\n  border-radius: var(--bs-btn-border-radius);\n  background-color: var(--bs-btn-bg);\n  transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n@media (prefers-reduced-motion: reduce) {\n  .btn {\n    transition: none;\n  }\n}\n.btn:hover {\n  color: var(--bs-btn-hover-color);\n  background-color: var(--bs-btn-hover-bg);\n  border-color: var(--bs-btn-hover-border-color);\n}\n.btn-check + .btn:hover {\n  color: var(--bs-btn-color);\n  background-color: var(--bs-btn-bg);\n  border-color: var(--bs-btn-border-color);\n}\n.btn:focus-visible {\n  color: var(--bs-btn-hover-color);\n  background-color: var(--bs-btn-hover-bg);\n  border-color: var(--bs-btn-hover-border-color);\n  outline: 0;\n  box-shadow: var(--bs-btn-focus-box-shadow);\n}\n.btn-check:focus-visible + .btn {\n  border-color: var(--bs-btn-hover-border-color);\n  outline: 0;\n  box-shadow: var(--bs-btn-focus-box-shadow);\n}\n.btn-check:checked + .btn, :not(.btn-check) + .btn:active, .btn:first-child:active, .btn.active, .btn.show {\n  color: var(--bs-btn-active-color);\n  background-color: var(--bs-btn-active-bg);\n  border-color: var(--bs-btn-active-border-color);\n}\n.btn-check:checked + .btn:focus-visible, :not(.btn-check) + .btn:active:focus-visible, .btn:first-child:active:focus-visible, .btn.active:focus-visible, .btn.show:focus-visible {\n  box-shadow: var(--bs-btn-focus-box-shadow);\n}\n.btn:disabled, .btn.disabled, fieldset:disabled .btn {\n  color: var(--bs-btn-disabled-color);\n  pointer-events: none;\n  background-color: var(--bs-btn-disabled-bg);\n  border-color: var(--bs-btn-disabled-border-color);\n  opacity: var(--bs-btn-disabled-opacity);\n}\n\n.btn-primary {\n  --bs-btn-color: #fff;\n  --bs-btn-bg: #1abc9c;\n  --bs-btn-border-color: #1abc9c;\n  --bs-btn-hover-color: #fff;\n  --bs-btn-hover-bg: #16a085;\n  --bs-btn-hover-border-color: #15967d;\n  --bs-btn-focus-shadow-rgb: 60, 198, 171;\n  --bs-btn-active-color: #fff;\n  --bs-btn-active-bg: #15967d;\n  --bs-btn-active-border-color: #148d75;\n  --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n  --bs-btn-disabled-color: #fff;\n  --bs-btn-disabled-bg: #1abc9c;\n  --bs-btn-disabled-border-color: #1abc9c;\n}\n\n.btn-secondary {\n  --bs-btn-color: #fff;\n  --bs-btn-bg: #2c3e50;\n  --bs-btn-border-color: #2c3e50;\n  --bs-btn-hover-color: #fff;\n  --bs-btn-hover-bg: #253544;\n  --bs-btn-hover-border-color: #233240;\n  --bs-btn-focus-shadow-rgb: 76, 91, 106;\n  --bs-btn-active-color: #fff;\n  --bs-btn-active-bg: #233240;\n  --bs-btn-active-border-color: #212f3c;\n  --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n  --bs-btn-disabled-color: #fff;\n  --bs-btn-disabled-bg: #2c3e50;\n  --bs-btn-disabled-border-color: #2c3e50;\n}\n\n.btn-success {\n  --bs-btn-color: #fff;\n  --bs-btn-bg: #198754;\n  --bs-btn-border-color: #198754;\n  --bs-btn-hover-color: #fff;\n  --bs-btn-hover-bg: #157347;\n  --bs-btn-hover-border-color: #146c43;\n  --bs-btn-focus-shadow-rgb: 60, 153, 110;\n  --bs-btn-active-color: #fff;\n  --bs-btn-active-bg: #146c43;\n  --bs-btn-active-border-color: #13653f;\n  --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n  --bs-btn-disabled-color: #fff;\n  --bs-btn-disabled-bg: #198754;\n  --bs-btn-disabled-border-color: #198754;\n}\n\n.btn-info {\n  --bs-btn-color: #000;\n  --bs-btn-bg: #0dcaf0;\n  --bs-btn-border-color: #0dcaf0;\n  --bs-btn-hover-color: #000;\n  --bs-btn-hover-bg: #31d2f2;\n  --bs-btn-hover-border-color: #25cff2;\n  --bs-btn-focus-shadow-rgb: 11, 172, 204;\n  --bs-btn-active-color: #000;\n  --bs-btn-active-bg: #3dd5f3;\n  --bs-btn-active-border-color: #25cff2;\n  --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n  --bs-btn-disabled-color: #000;\n  --bs-btn-disabled-bg: #0dcaf0;\n  --bs-btn-disabled-border-color: #0dcaf0;\n}\n\n.btn-warning {\n  --bs-btn-color: #000;\n  --bs-btn-bg: #ffc107;\n  --bs-btn-border-color: #ffc107;\n  --bs-btn-hover-color: #000;\n  --bs-btn-hover-bg: #ffca2c;\n  --bs-btn-hover-border-color: #ffc720;\n  --bs-btn-focus-shadow-rgb: 217, 164, 6;\n  --bs-btn-active-color: #000;\n  --bs-btn-active-bg: #ffcd39;\n  --bs-btn-active-border-color: #ffc720;\n  --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n  --bs-btn-disabled-color: #000;\n  --bs-btn-disabled-bg: #ffc107;\n  --bs-btn-disabled-border-color: #ffc107;\n}\n\n.btn-danger {\n  --bs-btn-color: #fff;\n  --bs-btn-bg: #dc3545;\n  --bs-btn-border-color: #dc3545;\n  --bs-btn-hover-color: #fff;\n  --bs-btn-hover-bg: #bb2d3b;\n  --bs-btn-hover-border-color: #b02a37;\n  --bs-btn-focus-shadow-rgb: 225, 83, 97;\n  --bs-btn-active-color: #fff;\n  --bs-btn-active-bg: #b02a37;\n  --bs-btn-active-border-color: #a52834;\n  --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n  --bs-btn-disabled-color: #fff;\n  --bs-btn-disabled-bg: #dc3545;\n  --bs-btn-disabled-border-color: #dc3545;\n}\n\n.btn-light {\n  --bs-btn-color: #000;\n  --bs-btn-bg: #f8f9fa;\n  --bs-btn-border-color: #f8f9fa;\n  --bs-btn-hover-color: #000;\n  --bs-btn-hover-bg: #d3d4d5;\n  --bs-btn-hover-border-color: #c6c7c8;\n  --bs-btn-focus-shadow-rgb: 211, 212, 213;\n  --bs-btn-active-color: #000;\n  --bs-btn-active-bg: #c6c7c8;\n  --bs-btn-active-border-color: #babbbc;\n  --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n  --bs-btn-disabled-color: #000;\n  --bs-btn-disabled-bg: #f8f9fa;\n  --bs-btn-disabled-border-color: #f8f9fa;\n}\n\n.btn-dark {\n  --bs-btn-color: #fff;\n  --bs-btn-bg: #212529;\n  --bs-btn-border-color: #212529;\n  --bs-btn-hover-color: #fff;\n  --bs-btn-hover-bg: #424649;\n  --bs-btn-hover-border-color: #373b3e;\n  --bs-btn-focus-shadow-rgb: 66, 70, 73;\n  --bs-btn-active-color: #fff;\n  --bs-btn-active-bg: #4d5154;\n  --bs-btn-active-border-color: #373b3e;\n  --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n  --bs-btn-disabled-color: #fff;\n  --bs-btn-disabled-bg: #212529;\n  --bs-btn-disabled-border-color: #212529;\n}\n\n.btn-outline-primary {\n  --bs-btn-color: #1abc9c;\n  --bs-btn-border-color: #1abc9c;\n  --bs-btn-hover-color: #fff;\n  --bs-btn-hover-bg: #1abc9c;\n  --bs-btn-hover-border-color: #1abc9c;\n  --bs-btn-focus-shadow-rgb: 26, 188, 156;\n  --bs-btn-active-color: #fff;\n  --bs-btn-active-bg: #1abc9c;\n  --bs-btn-active-border-color: #1abc9c;\n  --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n  --bs-btn-disabled-color: #1abc9c;\n  --bs-btn-disabled-bg: transparent;\n  --bs-btn-disabled-border-color: #1abc9c;\n  --bs-gradient: none;\n}\n\n.btn-outline-secondary {\n  --bs-btn-color: #2c3e50;\n  --bs-btn-border-color: #2c3e50;\n  --bs-btn-hover-color: #fff;\n  --bs-btn-hover-bg: #2c3e50;\n  --bs-btn-hover-border-color: #2c3e50;\n  --bs-btn-focus-shadow-rgb: 44, 62, 80;\n  --bs-btn-active-color: #fff;\n  --bs-btn-active-bg: #2c3e50;\n  --bs-btn-active-border-color: #2c3e50;\n  --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n  --bs-btn-disabled-color: #2c3e50;\n  --bs-btn-disabled-bg: transparent;\n  --bs-btn-disabled-border-color: #2c3e50;\n  --bs-gradient: none;\n}\n\n.btn-outline-success {\n  --bs-btn-color: #198754;\n  --bs-btn-border-color: #198754;\n  --bs-btn-hover-color: #fff;\n  --bs-btn-hover-bg: #198754;\n  --bs-btn-hover-border-color: #198754;\n  --bs-btn-focus-shadow-rgb: 25, 135, 84;\n  --bs-btn-active-color: #fff;\n  --bs-btn-active-bg: #198754;\n  --bs-btn-active-border-color: #198754;\n  --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n  --bs-btn-disabled-color: #198754;\n  --bs-btn-disabled-bg: transparent;\n  --bs-btn-disabled-border-color: #198754;\n  --bs-gradient: none;\n}\n\n.btn-outline-info {\n  --bs-btn-color: #0dcaf0;\n  --bs-btn-border-color: #0dcaf0;\n  --bs-btn-hover-color: #000;\n  --bs-btn-hover-bg: #0dcaf0;\n  --bs-btn-hover-border-color: #0dcaf0;\n  --bs-btn-focus-shadow-rgb: 13, 202, 240;\n  --bs-btn-active-color: #000;\n  --bs-btn-active-bg: #0dcaf0;\n  --bs-btn-active-border-color: #0dcaf0;\n  --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n  --bs-btn-disabled-color: #0dcaf0;\n  --bs-btn-disabled-bg: transparent;\n  --bs-btn-disabled-border-color: #0dcaf0;\n  --bs-gradient: none;\n}\n\n.btn-outline-warning {\n  --bs-btn-color: #ffc107;\n  --bs-btn-border-color: #ffc107;\n  --bs-btn-hover-color: #000;\n  --bs-btn-hover-bg: #ffc107;\n  --bs-btn-hover-border-color: #ffc107;\n  --bs-btn-focus-shadow-rgb: 255, 193, 7;\n  --bs-btn-active-color: #000;\n  --bs-btn-active-bg: #ffc107;\n  --bs-btn-active-border-color: #ffc107;\n  --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n  --bs-btn-disabled-color: #ffc107;\n  --bs-btn-disabled-bg: transparent;\n  --bs-btn-disabled-border-color: #ffc107;\n  --bs-gradient: none;\n}\n\n.btn-outline-danger {\n  --bs-btn-color: #dc3545;\n  --bs-btn-border-color: #dc3545;\n  --bs-btn-hover-color: #fff;\n  --bs-btn-hover-bg: #dc3545;\n  --bs-btn-hover-border-color: #dc3545;\n  --bs-btn-focus-shadow-rgb: 220, 53, 69;\n  --bs-btn-active-color: #fff;\n  --bs-btn-active-bg: #dc3545;\n  --bs-btn-active-border-color: #dc3545;\n  --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n  --bs-btn-disabled-color: #dc3545;\n  --bs-btn-disabled-bg: transparent;\n  --bs-btn-disabled-border-color: #dc3545;\n  --bs-gradient: none;\n}\n\n.btn-outline-light {\n  --bs-btn-color: #f8f9fa;\n  --bs-btn-border-color: #f8f9fa;\n  --bs-btn-hover-color: #000;\n  --bs-btn-hover-bg: #f8f9fa;\n  --bs-btn-hover-border-color: #f8f9fa;\n  --bs-btn-focus-shadow-rgb: 248, 249, 250;\n  --bs-btn-active-color: #000;\n  --bs-btn-active-bg: #f8f9fa;\n  --bs-btn-active-border-color: #f8f9fa;\n  --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n  --bs-btn-disabled-color: #f8f9fa;\n  --bs-btn-disabled-bg: transparent;\n  --bs-btn-disabled-border-color: #f8f9fa;\n  --bs-gradient: none;\n}\n\n.btn-outline-dark {\n  --bs-btn-color: #212529;\n  --bs-btn-border-color: #212529;\n  --bs-btn-hover-color: #fff;\n  --bs-btn-hover-bg: #212529;\n  --bs-btn-hover-border-color: #212529;\n  --bs-btn-focus-shadow-rgb: 33, 37, 41;\n  --bs-btn-active-color: #fff;\n  --bs-btn-active-bg: #212529;\n  --bs-btn-active-border-color: #212529;\n  --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n  --bs-btn-disabled-color: #212529;\n  --bs-btn-disabled-bg: transparent;\n  --bs-btn-disabled-border-color: #212529;\n  --bs-gradient: none;\n}\n\n.btn-link {\n  --bs-btn-font-weight: 400;\n  --bs-btn-color: var(--bs-link-color);\n  --bs-btn-bg: transparent;\n  --bs-btn-border-color: transparent;\n  --bs-btn-hover-color: var(--bs-link-hover-color);\n  --bs-btn-hover-border-color: transparent;\n  --bs-btn-active-color: var(--bs-link-hover-color);\n  --bs-btn-active-border-color: transparent;\n  --bs-btn-disabled-color: #6c757d;\n  --bs-btn-disabled-border-color: transparent;\n  --bs-btn-box-shadow: none;\n  --bs-btn-focus-shadow-rgb: 60, 198, 171;\n  text-decoration: underline;\n}\n.btn-link:focus-visible {\n  color: var(--bs-btn-color);\n}\n.btn-link:hover {\n  color: var(--bs-btn-hover-color);\n}\n\n.btn-lg, .btn-group-lg > .btn {\n  --bs-btn-padding-y: 0.5rem;\n  --bs-btn-padding-x: 1rem;\n  --bs-btn-font-size: 1.25rem;\n  --bs-btn-border-radius: 0.75rem;\n}\n\n.btn-sm, .btn-group-sm > .btn {\n  --bs-btn-padding-y: 0.25rem;\n  --bs-btn-padding-x: 0.5rem;\n  --bs-btn-font-size: 0.875rem;\n  --bs-btn-border-radius: 0.25rem;\n}\n\n.fade {\n  transition: opacity 0.15s linear;\n}\n@media (prefers-reduced-motion: reduce) {\n  .fade {\n    transition: none;\n  }\n}\n.fade:not(.show) {\n  opacity: 0;\n}\n\n.collapse:not(.show) {\n  display: none;\n}\n\n.collapsing {\n  height: 0;\n  overflow: hidden;\n  transition: height 0.35s ease;\n}\n@media (prefers-reduced-motion: reduce) {\n  .collapsing {\n    transition: none;\n  }\n}\n.collapsing.collapse-horizontal {\n  width: 0;\n  height: auto;\n  transition: width 0.35s ease;\n}\n@media (prefers-reduced-motion: reduce) {\n  .collapsing.collapse-horizontal {\n    transition: none;\n  }\n}\n\n.dropup,\n.dropend,\n.dropdown,\n.dropstart,\n.dropup-center,\n.dropdown-center {\n  position: relative;\n}\n\n.dropdown-toggle {\n  white-space: nowrap;\n}\n.dropdown-toggle::after {\n  display: inline-block;\n  margin-left: 0.255em;\n  vertical-align: 0.255em;\n  content: \"\";\n  border-top: 0.3em solid;\n  border-right: 0.3em solid transparent;\n  border-bottom: 0;\n  border-left: 0.3em solid transparent;\n}\n.dropdown-toggle:empty::after {\n  margin-left: 0;\n}\n\n.dropdown-menu {\n  --bs-dropdown-zindex: 1000;\n  --bs-dropdown-min-width: 10rem;\n  --bs-dropdown-padding-x: 0;\n  --bs-dropdown-padding-y: 0.5rem;\n  --bs-dropdown-spacer: 0.125rem;\n  --bs-dropdown-font-size: 1rem;\n  --bs-dropdown-color: #212529;\n  --bs-dropdown-bg: #fff;\n  --bs-dropdown-border-color: var(--bs-border-color-translucent);\n  --bs-dropdown-border-radius: 0.5rem;\n  --bs-dropdown-border-width: 0.125rem;\n  --bs-dropdown-inner-border-radius: 0.375rem;\n  --bs-dropdown-divider-bg: var(--bs-border-color-translucent);\n  --bs-dropdown-divider-margin-y: 0.5rem;\n  --bs-dropdown-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);\n  --bs-dropdown-link-color: #212529;\n  --bs-dropdown-link-hover-color: #1e2125;\n  --bs-dropdown-link-hover-bg: #e9ecef;\n  --bs-dropdown-link-active-color: #fff;\n  --bs-dropdown-link-active-bg: #1abc9c;\n  --bs-dropdown-link-disabled-color: #adb5bd;\n  --bs-dropdown-item-padding-x: 1rem;\n  --bs-dropdown-item-padding-y: 0.25rem;\n  --bs-dropdown-header-color: #6c757d;\n  --bs-dropdown-header-padding-x: 1rem;\n  --bs-dropdown-header-padding-y: 0.5rem;\n  position: absolute;\n  z-index: var(--bs-dropdown-zindex);\n  display: none;\n  min-width: var(--bs-dropdown-min-width);\n  padding: var(--bs-dropdown-padding-y) var(--bs-dropdown-padding-x);\n  margin: 0;\n  font-size: var(--bs-dropdown-font-size);\n  color: var(--bs-dropdown-color);\n  text-align: left;\n  list-style: none;\n  background-color: var(--bs-dropdown-bg);\n  background-clip: padding-box;\n  border: var(--bs-dropdown-border-width) solid var(--bs-dropdown-border-color);\n  border-radius: var(--bs-dropdown-border-radius);\n}\n.dropdown-menu[data-bs-popper] {\n  top: 100%;\n  left: 0;\n  margin-top: var(--bs-dropdown-spacer);\n}\n\n.dropdown-menu-start {\n  --bs-position: start;\n}\n.dropdown-menu-start[data-bs-popper] {\n  right: auto;\n  left: 0;\n}\n\n.dropdown-menu-end {\n  --bs-position: end;\n}\n.dropdown-menu-end[data-bs-popper] {\n  right: 0;\n  left: auto;\n}\n\n@media (min-width: 576px) {\n  .dropdown-menu-sm-start {\n    --bs-position: start;\n  }\n  .dropdown-menu-sm-start[data-bs-popper] {\n    right: auto;\n    left: 0;\n  }\n  .dropdown-menu-sm-end {\n    --bs-position: end;\n  }\n  .dropdown-menu-sm-end[data-bs-popper] {\n    right: 0;\n    left: auto;\n  }\n}\n@media (min-width: 768px) {\n  .dropdown-menu-md-start {\n    --bs-position: start;\n  }\n  .dropdown-menu-md-start[data-bs-popper] {\n    right: auto;\n    left: 0;\n  }\n  .dropdown-menu-md-end {\n    --bs-position: end;\n  }\n  .dropdown-menu-md-end[data-bs-popper] {\n    right: 0;\n    left: auto;\n  }\n}\n@media (min-width: 992px) {\n  .dropdown-menu-lg-start {\n    --bs-position: start;\n  }\n  .dropdown-menu-lg-start[data-bs-popper] {\n    right: auto;\n    left: 0;\n  }\n  .dropdown-menu-lg-end {\n    --bs-position: end;\n  }\n  .dropdown-menu-lg-end[data-bs-popper] {\n    right: 0;\n    left: auto;\n  }\n}\n@media (min-width: 1200px) {\n  .dropdown-menu-xl-start {\n    --bs-position: start;\n  }\n  .dropdown-menu-xl-start[data-bs-popper] {\n    right: auto;\n    left: 0;\n  }\n  .dropdown-menu-xl-end {\n    --bs-position: end;\n  }\n  .dropdown-menu-xl-end[data-bs-popper] {\n    right: 0;\n    left: auto;\n  }\n}\n@media (min-width: 1400px) {\n  .dropdown-menu-xxl-start {\n    --bs-position: start;\n  }\n  .dropdown-menu-xxl-start[data-bs-popper] {\n    right: auto;\n    left: 0;\n  }\n  .dropdown-menu-xxl-end {\n    --bs-position: end;\n  }\n  .dropdown-menu-xxl-end[data-bs-popper] {\n    right: 0;\n    left: auto;\n  }\n}\n.dropup .dropdown-menu[data-bs-popper] {\n  top: auto;\n  bottom: 100%;\n  margin-top: 0;\n  margin-bottom: var(--bs-dropdown-spacer);\n}\n.dropup .dropdown-toggle::after {\n  display: inline-block;\n  margin-left: 0.255em;\n  vertical-align: 0.255em;\n  content: \"\";\n  border-top: 0;\n  border-right: 0.3em solid transparent;\n  border-bottom: 0.3em solid;\n  border-left: 0.3em solid transparent;\n}\n.dropup .dropdown-toggle:empty::after {\n  margin-left: 0;\n}\n\n.dropend .dropdown-menu[data-bs-popper] {\n  top: 0;\n  right: auto;\n  left: 100%;\n  margin-top: 0;\n  margin-left: var(--bs-dropdown-spacer);\n}\n.dropend .dropdown-toggle::after {\n  display: inline-block;\n  margin-left: 0.255em;\n  vertical-align: 0.255em;\n  content: \"\";\n  border-top: 0.3em solid transparent;\n  border-right: 0;\n  border-bottom: 0.3em solid transparent;\n  border-left: 0.3em solid;\n}\n.dropend .dropdown-toggle:empty::after {\n  margin-left: 0;\n}\n.dropend .dropdown-toggle::after {\n  vertical-align: 0;\n}\n\n.dropstart .dropdown-menu[data-bs-popper] {\n  top: 0;\n  right: 100%;\n  left: auto;\n  margin-top: 0;\n  margin-right: var(--bs-dropdown-spacer);\n}\n.dropstart .dropdown-toggle::after {\n  display: inline-block;\n  margin-left: 0.255em;\n  vertical-align: 0.255em;\n  content: \"\";\n}\n.dropstart .dropdown-toggle::after {\n  display: none;\n}\n.dropstart .dropdown-toggle::before {\n  display: inline-block;\n  margin-right: 0.255em;\n  vertical-align: 0.255em;\n  content: \"\";\n  border-top: 0.3em solid transparent;\n  border-right: 0.3em solid;\n  border-bottom: 0.3em solid transparent;\n}\n.dropstart .dropdown-toggle:empty::after {\n  margin-left: 0;\n}\n.dropstart .dropdown-toggle::before {\n  vertical-align: 0;\n}\n\n.dropdown-divider {\n  height: 0;\n  margin: var(--bs-dropdown-divider-margin-y) 0;\n  overflow: hidden;\n  border-top: 1px solid var(--bs-dropdown-divider-bg);\n  opacity: 1;\n}\n\n.dropdown-item {\n  display: block;\n  width: 100%;\n  padding: var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x);\n  clear: both;\n  font-weight: 400;\n  color: var(--bs-dropdown-link-color);\n  text-align: inherit;\n  text-decoration: none;\n  white-space: nowrap;\n  background-color: transparent;\n  border: 0;\n}\n.dropdown-item:hover, .dropdown-item:focus {\n  color: var(--bs-dropdown-link-hover-color);\n  background-color: var(--bs-dropdown-link-hover-bg);\n}\n.dropdown-item.active, .dropdown-item:active {\n  color: var(--bs-dropdown-link-active-color);\n  text-decoration: none;\n  background-color: var(--bs-dropdown-link-active-bg);\n}\n.dropdown-item.disabled, .dropdown-item:disabled {\n  color: var(--bs-dropdown-link-disabled-color);\n  pointer-events: none;\n  background-color: transparent;\n}\n\n.dropdown-menu.show {\n  display: block;\n}\n\n.dropdown-header {\n  display: block;\n  padding: var(--bs-dropdown-header-padding-y) var(--bs-dropdown-header-padding-x);\n  margin-bottom: 0;\n  font-size: 0.875rem;\n  color: var(--bs-dropdown-header-color);\n  white-space: nowrap;\n}\n\n.dropdown-item-text {\n  display: block;\n  padding: var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x);\n  color: var(--bs-dropdown-link-color);\n}\n\n.dropdown-menu-dark {\n  --bs-dropdown-color: #dee2e6;\n  --bs-dropdown-bg: #343a40;\n  --bs-dropdown-border-color: var(--bs-border-color-translucent);\n  --bs-dropdown-box-shadow: ;\n  --bs-dropdown-link-color: #dee2e6;\n  --bs-dropdown-link-hover-color: #fff;\n  --bs-dropdown-divider-bg: var(--bs-border-color-translucent);\n  --bs-dropdown-link-hover-bg: rgba(255, 255, 255, 0.15);\n  --bs-dropdown-link-active-color: #fff;\n  --bs-dropdown-link-active-bg: #1abc9c;\n  --bs-dropdown-link-disabled-color: #adb5bd;\n  --bs-dropdown-header-color: #adb5bd;\n}\n\n.btn-group,\n.btn-group-vertical {\n  position: relative;\n  display: inline-flex;\n  vertical-align: middle;\n}\n.btn-group > .btn,\n.btn-group-vertical > .btn {\n  position: relative;\n  flex: 1 1 auto;\n}\n.btn-group > .btn-check:checked + .btn,\n.btn-group > .btn-check:focus + .btn,\n.btn-group > .btn:hover,\n.btn-group > .btn:focus,\n.btn-group > .btn:active,\n.btn-group > .btn.active,\n.btn-group-vertical > .btn-check:checked + .btn,\n.btn-group-vertical > .btn-check:focus + .btn,\n.btn-group-vertical > .btn:hover,\n.btn-group-vertical > .btn:focus,\n.btn-group-vertical > .btn:active,\n.btn-group-vertical > .btn.active {\n  z-index: 1;\n}\n\n.btn-toolbar {\n  display: flex;\n  flex-wrap: wrap;\n  justify-content: flex-start;\n}\n.btn-toolbar .input-group {\n  width: auto;\n}\n\n.btn-group {\n  border-radius: 0.5rem;\n}\n.btn-group > :not(.btn-check:first-child) + .btn,\n.btn-group > .btn-group:not(:first-child) {\n  margin-left: -0.125rem;\n}\n.btn-group > .btn:not(:last-child):not(.dropdown-toggle),\n.btn-group > .btn.dropdown-toggle-split:first-child,\n.btn-group > .btn-group:not(:last-child) > .btn {\n  border-top-right-radius: 0;\n  border-bottom-right-radius: 0;\n}\n.btn-group > .btn:nth-child(n+3),\n.btn-group > :not(.btn-check) + .btn,\n.btn-group > .btn-group:not(:first-child) > .btn {\n  border-top-left-radius: 0;\n  border-bottom-left-radius: 0;\n}\n\n.dropdown-toggle-split {\n  padding-right: 0.5625rem;\n  padding-left: 0.5625rem;\n}\n.dropdown-toggle-split::after, .dropup .dropdown-toggle-split::after, .dropend .dropdown-toggle-split::after {\n  margin-left: 0;\n}\n.dropstart .dropdown-toggle-split::before {\n  margin-right: 0;\n}\n\n.btn-sm + .dropdown-toggle-split, .btn-group-sm > .btn + .dropdown-toggle-split {\n  padding-right: 0.375rem;\n  padding-left: 0.375rem;\n}\n\n.btn-lg + .dropdown-toggle-split, .btn-group-lg > .btn + .dropdown-toggle-split {\n  padding-right: 0.75rem;\n  padding-left: 0.75rem;\n}\n\n.btn-group-vertical {\n  flex-direction: column;\n  align-items: flex-start;\n  justify-content: center;\n}\n.btn-group-vertical > .btn,\n.btn-group-vertical > .btn-group {\n  width: 100%;\n}\n.btn-group-vertical > .btn:not(:first-child),\n.btn-group-vertical > .btn-group:not(:first-child) {\n  margin-top: -0.125rem;\n}\n.btn-group-vertical > .btn:not(:last-child):not(.dropdown-toggle),\n.btn-group-vertical > .btn-group:not(:last-child) > .btn {\n  border-bottom-right-radius: 0;\n  border-bottom-left-radius: 0;\n}\n.btn-group-vertical > .btn ~ .btn,\n.btn-group-vertical > .btn-group:not(:first-child) > .btn {\n  border-top-left-radius: 0;\n  border-top-right-radius: 0;\n}\n\n.nav {\n  --bs-nav-link-padding-x: 1rem;\n  --bs-nav-link-padding-y: 0.5rem;\n  --bs-nav-link-font-weight: ;\n  --bs-nav-link-color: var(--bs-link-color);\n  --bs-nav-link-hover-color: var(--bs-link-hover-color);\n  --bs-nav-link-disabled-color: #6c757d;\n  display: flex;\n  flex-wrap: wrap;\n  padding-left: 0;\n  margin-bottom: 0;\n  list-style: none;\n}\n\n.nav-link {\n  display: block;\n  padding: var(--bs-nav-link-padding-y) var(--bs-nav-link-padding-x);\n  font-size: var(--bs-nav-link-font-size);\n  font-weight: var(--bs-nav-link-font-weight);\n  color: var(--bs-nav-link-color);\n  text-decoration: none;\n  transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out;\n}\n@media (prefers-reduced-motion: reduce) {\n  .nav-link {\n    transition: none;\n  }\n}\n.nav-link:hover, .nav-link:focus {\n  color: var(--bs-nav-link-hover-color);\n}\n.nav-link.disabled {\n  color: var(--bs-nav-link-disabled-color);\n  pointer-events: none;\n  cursor: default;\n}\n\n.nav-tabs {\n  --bs-nav-tabs-border-width: 0.125rem;\n  --bs-nav-tabs-border-color: #dee2e6;\n  --bs-nav-tabs-border-radius: 0.5rem;\n  --bs-nav-tabs-link-hover-border-color: #e9ecef #e9ecef #dee2e6;\n  --bs-nav-tabs-link-active-color: #495057;\n  --bs-nav-tabs-link-active-bg: #fff;\n  --bs-nav-tabs-link-active-border-color: #dee2e6 #dee2e6 #fff;\n  border-bottom: var(--bs-nav-tabs-border-width) solid var(--bs-nav-tabs-border-color);\n}\n.nav-tabs .nav-link {\n  margin-bottom: calc(-1 * var(--bs-nav-tabs-border-width));\n  background: none;\n  border: var(--bs-nav-tabs-border-width) solid transparent;\n  border-top-left-radius: var(--bs-nav-tabs-border-radius);\n  border-top-right-radius: var(--bs-nav-tabs-border-radius);\n}\n.nav-tabs .nav-link:hover, .nav-tabs .nav-link:focus {\n  isolation: isolate;\n  border-color: var(--bs-nav-tabs-link-hover-border-color);\n}\n.nav-tabs .nav-link.disabled, .nav-tabs .nav-link:disabled {\n  color: var(--bs-nav-link-disabled-color);\n  background-color: transparent;\n  border-color: transparent;\n}\n.nav-tabs .nav-link.active,\n.nav-tabs .nav-item.show .nav-link {\n  color: var(--bs-nav-tabs-link-active-color);\n  background-color: var(--bs-nav-tabs-link-active-bg);\n  border-color: var(--bs-nav-tabs-link-active-border-color);\n}\n.nav-tabs .dropdown-menu {\n  margin-top: calc(-1 * var(--bs-nav-tabs-border-width));\n  border-top-left-radius: 0;\n  border-top-right-radius: 0;\n}\n\n.nav-pills {\n  --bs-nav-pills-border-radius: 0.5rem;\n  --bs-nav-pills-link-active-color: #fff;\n  --bs-nav-pills-link-active-bg: #1abc9c;\n}\n.nav-pills .nav-link {\n  background: none;\n  border: 0;\n  border-radius: var(--bs-nav-pills-border-radius);\n}\n.nav-pills .nav-link:disabled {\n  color: var(--bs-nav-link-disabled-color);\n  background-color: transparent;\n  border-color: transparent;\n}\n.nav-pills .nav-link.active,\n.nav-pills .show > .nav-link {\n  color: var(--bs-nav-pills-link-active-color);\n  background-color: var(--bs-nav-pills-link-active-bg);\n}\n\n.nav-fill > .nav-link,\n.nav-fill .nav-item {\n  flex: 1 1 auto;\n  text-align: center;\n}\n\n.nav-justified > .nav-link,\n.nav-justified .nav-item {\n  flex-basis: 0;\n  flex-grow: 1;\n  text-align: center;\n}\n\n.nav-fill .nav-item .nav-link,\n.nav-justified .nav-item .nav-link {\n  width: 100%;\n}\n\n.tab-content > .tab-pane {\n  display: none;\n}\n.tab-content > .active {\n  display: block;\n}\n\n.navbar {\n  --bs-navbar-padding-x: 0;\n  --bs-navbar-padding-y: 0.5rem;\n  --bs-navbar-color: rgba(0, 0, 0, 0.55);\n  --bs-navbar-hover-color: rgba(0, 0, 0, 0.7);\n  --bs-navbar-disabled-color: rgba(0, 0, 0, 0.3);\n  --bs-navbar-active-color: rgba(0, 0, 0, 0.9);\n  --bs-navbar-brand-padding-y: 0.3125rem;\n  --bs-navbar-brand-margin-end: 1rem;\n  --bs-navbar-brand-font-size: 1.25rem;\n  --bs-navbar-brand-color: rgba(0, 0, 0, 0.9);\n  --bs-navbar-brand-hover-color: rgba(0, 0, 0, 0.9);\n  --bs-navbar-nav-link-padding-x: 0.5rem;\n  --bs-navbar-toggler-padding-y: 0.25rem;\n  --bs-navbar-toggler-padding-x: 0.75rem;\n  --bs-navbar-toggler-font-size: 1.25rem;\n  --bs-navbar-toggler-icon-bg: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%280, 0, 0, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e\");\n  --bs-navbar-toggler-border-color: rgba(0, 0, 0, 0.1);\n  --bs-navbar-toggler-border-radius: 0.5rem;\n  --bs-navbar-toggler-focus-width: 0.25rem;\n  --bs-navbar-toggler-transition: box-shadow 0.15s ease-in-out;\n  position: relative;\n  display: flex;\n  flex-wrap: wrap;\n  align-items: center;\n  justify-content: space-between;\n  padding: var(--bs-navbar-padding-y) var(--bs-navbar-padding-x);\n}\n.navbar > .container,\n.navbar > .container-fluid,\n.navbar > .container-sm,\n.navbar > .container-md,\n.navbar > .container-lg,\n.navbar > .container-xl,\n.navbar > .container-xxl {\n  display: flex;\n  flex-wrap: inherit;\n  align-items: center;\n  justify-content: space-between;\n}\n.navbar-brand {\n  padding-top: var(--bs-navbar-brand-padding-y);\n  padding-bottom: var(--bs-navbar-brand-padding-y);\n  margin-right: var(--bs-navbar-brand-margin-end);\n  font-size: var(--bs-navbar-brand-font-size);\n  color: var(--bs-navbar-brand-color);\n  text-decoration: none;\n  white-space: nowrap;\n}\n.navbar-brand:hover, .navbar-brand:focus {\n  color: var(--bs-navbar-brand-hover-color);\n}\n\n.navbar-nav {\n  --bs-nav-link-padding-x: 0;\n  --bs-nav-link-padding-y: 0.5rem;\n  --bs-nav-link-font-weight: ;\n  --bs-nav-link-color: var(--bs-navbar-color);\n  --bs-nav-link-hover-color: var(--bs-navbar-hover-color);\n  --bs-nav-link-disabled-color: var(--bs-navbar-disabled-color);\n  display: flex;\n  flex-direction: column;\n  padding-left: 0;\n  margin-bottom: 0;\n  list-style: none;\n}\n.navbar-nav .show > .nav-link,\n.navbar-nav .nav-link.active {\n  color: var(--bs-navbar-active-color);\n}\n.navbar-nav .dropdown-menu {\n  position: static;\n}\n\n.navbar-text {\n  padding-top: 0.5rem;\n  padding-bottom: 0.5rem;\n  color: var(--bs-navbar-color);\n}\n.navbar-text a,\n.navbar-text a:hover,\n.navbar-text a:focus {\n  color: var(--bs-navbar-active-color);\n}\n\n.navbar-collapse {\n  flex-basis: 100%;\n  flex-grow: 1;\n  align-items: center;\n}\n\n.navbar-toggler {\n  padding: var(--bs-navbar-toggler-padding-y) var(--bs-navbar-toggler-padding-x);\n  font-size: var(--bs-navbar-toggler-font-size);\n  line-height: 1;\n  color: var(--bs-navbar-color);\n  background-color: transparent;\n  border: var(--bs-border-width) solid var(--bs-navbar-toggler-border-color);\n  border-radius: var(--bs-navbar-toggler-border-radius);\n  transition: var(--bs-navbar-toggler-transition);\n}\n@media (prefers-reduced-motion: reduce) {\n  .navbar-toggler {\n    transition: none;\n  }\n}\n.navbar-toggler:hover {\n  text-decoration: none;\n}\n.navbar-toggler:focus {\n  text-decoration: none;\n  outline: 0;\n  box-shadow: 0 0 0 var(--bs-navbar-toggler-focus-width);\n}\n\n.navbar-toggler-icon {\n  display: inline-block;\n  width: 1.5em;\n  height: 1.5em;\n  vertical-align: middle;\n  background-image: var(--bs-navbar-toggler-icon-bg);\n  background-repeat: no-repeat;\n  background-position: center;\n  background-size: 100%;\n}\n\n.navbar-nav-scroll {\n  max-height: var(--bs-scroll-height, 75vh);\n  overflow-y: auto;\n}\n\n@media (min-width: 576px) {\n  .navbar-expand-sm {\n    flex-wrap: nowrap;\n    justify-content: flex-start;\n  }\n  .navbar-expand-sm .navbar-nav {\n    flex-direction: row;\n  }\n  .navbar-expand-sm .navbar-nav .dropdown-menu {\n    position: absolute;\n  }\n  .navbar-expand-sm .navbar-nav .nav-link {\n    padding-right: var(--bs-navbar-nav-link-padding-x);\n    padding-left: var(--bs-navbar-nav-link-padding-x);\n  }\n  .navbar-expand-sm .navbar-nav-scroll {\n    overflow: visible;\n  }\n  .navbar-expand-sm .navbar-collapse {\n    display: flex !important;\n    flex-basis: auto;\n  }\n  .navbar-expand-sm .navbar-toggler {\n    display: none;\n  }\n  .navbar-expand-sm .offcanvas {\n    position: static;\n    z-index: auto;\n    flex-grow: 1;\n    width: auto !important;\n    height: auto !important;\n    visibility: visible !important;\n    background-color: transparent !important;\n    border: 0 !important;\n    transform: none !important;\n    transition: none;\n  }\n  .navbar-expand-sm .offcanvas .offcanvas-header {\n    display: none;\n  }\n  .navbar-expand-sm .offcanvas .offcanvas-body {\n    display: flex;\n    flex-grow: 0;\n    padding: 0;\n    overflow-y: visible;\n  }\n}\n@media (min-width: 768px) {\n  .navbar-expand-md {\n    flex-wrap: nowrap;\n    justify-content: flex-start;\n  }\n  .navbar-expand-md .navbar-nav {\n    flex-direction: row;\n  }\n  .navbar-expand-md .navbar-nav .dropdown-menu {\n    position: absolute;\n  }\n  .navbar-expand-md .navbar-nav .nav-link {\n    padding-right: var(--bs-navbar-nav-link-padding-x);\n    padding-left: var(--bs-navbar-nav-link-padding-x);\n  }\n  .navbar-expand-md .navbar-nav-scroll {\n    overflow: visible;\n  }\n  .navbar-expand-md .navbar-collapse {\n    display: flex !important;\n    flex-basis: auto;\n  }\n  .navbar-expand-md .navbar-toggler {\n    display: none;\n  }\n  .navbar-expand-md .offcanvas {\n    position: static;\n    z-index: auto;\n    flex-grow: 1;\n    width: auto !important;\n    height: auto !important;\n    visibility: visible !important;\n    background-color: transparent !important;\n    border: 0 !important;\n    transform: none !important;\n    transition: none;\n  }\n  .navbar-expand-md .offcanvas .offcanvas-header {\n    display: none;\n  }\n  .navbar-expand-md .offcanvas .offcanvas-body {\n    display: flex;\n    flex-grow: 0;\n    padding: 0;\n    overflow-y: visible;\n  }\n}\n@media (min-width: 992px) {\n  .navbar-expand-lg {\n    flex-wrap: nowrap;\n    justify-content: flex-start;\n  }\n  .navbar-expand-lg .navbar-nav {\n    flex-direction: row;\n  }\n  .navbar-expand-lg .navbar-nav .dropdown-menu {\n    position: absolute;\n  }\n  .navbar-expand-lg .navbar-nav .nav-link {\n    padding-right: var(--bs-navbar-nav-link-padding-x);\n    padding-left: var(--bs-navbar-nav-link-padding-x);\n  }\n  .navbar-expand-lg .navbar-nav-scroll {\n    overflow: visible;\n  }\n  .navbar-expand-lg .navbar-collapse {\n    display: flex !important;\n    flex-basis: auto;\n  }\n  .navbar-expand-lg .navbar-toggler {\n    display: none;\n  }\n  .navbar-expand-lg .offcanvas {\n    position: static;\n    z-index: auto;\n    flex-grow: 1;\n    width: auto !important;\n    height: auto !important;\n    visibility: visible !important;\n    background-color: transparent !important;\n    border: 0 !important;\n    transform: none !important;\n    transition: none;\n  }\n  .navbar-expand-lg .offcanvas .offcanvas-header {\n    display: none;\n  }\n  .navbar-expand-lg .offcanvas .offcanvas-body {\n    display: flex;\n    flex-grow: 0;\n    padding: 0;\n    overflow-y: visible;\n  }\n}\n@media (min-width: 1200px) {\n  .navbar-expand-xl {\n    flex-wrap: nowrap;\n    justify-content: flex-start;\n  }\n  .navbar-expand-xl .navbar-nav {\n    flex-direction: row;\n  }\n  .navbar-expand-xl .navbar-nav .dropdown-menu {\n    position: absolute;\n  }\n  .navbar-expand-xl .navbar-nav .nav-link {\n    padding-right: var(--bs-navbar-nav-link-padding-x);\n    padding-left: var(--bs-navbar-nav-link-padding-x);\n  }\n  .navbar-expand-xl .navbar-nav-scroll {\n    overflow: visible;\n  }\n  .navbar-expand-xl .navbar-collapse {\n    display: flex !important;\n    flex-basis: auto;\n  }\n  .navbar-expand-xl .navbar-toggler {\n    display: none;\n  }\n  .navbar-expand-xl .offcanvas {\n    position: static;\n    z-index: auto;\n    flex-grow: 1;\n    width: auto !important;\n    height: auto !important;\n    visibility: visible !important;\n    background-color: transparent !important;\n    border: 0 !important;\n    transform: none !important;\n    transition: none;\n  }\n  .navbar-expand-xl .offcanvas .offcanvas-header {\n    display: none;\n  }\n  .navbar-expand-xl .offcanvas .offcanvas-body {\n    display: flex;\n    flex-grow: 0;\n    padding: 0;\n    overflow-y: visible;\n  }\n}\n@media (min-width: 1400px) {\n  .navbar-expand-xxl {\n    flex-wrap: nowrap;\n    justify-content: flex-start;\n  }\n  .navbar-expand-xxl .navbar-nav {\n    flex-direction: row;\n  }\n  .navbar-expand-xxl .navbar-nav .dropdown-menu {\n    position: absolute;\n  }\n  .navbar-expand-xxl .navbar-nav .nav-link {\n    padding-right: var(--bs-navbar-nav-link-padding-x);\n    padding-left: var(--bs-navbar-nav-link-padding-x);\n  }\n  .navbar-expand-xxl .navbar-nav-scroll {\n    overflow: visible;\n  }\n  .navbar-expand-xxl .navbar-collapse {\n    display: flex !important;\n    flex-basis: auto;\n  }\n  .navbar-expand-xxl .navbar-toggler {\n    display: none;\n  }\n  .navbar-expand-xxl .offcanvas {\n    position: static;\n    z-index: auto;\n    flex-grow: 1;\n    width: auto !important;\n    height: auto !important;\n    visibility: visible !important;\n    background-color: transparent !important;\n    border: 0 !important;\n    transform: none !important;\n    transition: none;\n  }\n  .navbar-expand-xxl .offcanvas .offcanvas-header {\n    display: none;\n  }\n  .navbar-expand-xxl .offcanvas .offcanvas-body {\n    display: flex;\n    flex-grow: 0;\n    padding: 0;\n    overflow-y: visible;\n  }\n}\n.navbar-expand {\n  flex-wrap: nowrap;\n  justify-content: flex-start;\n}\n.navbar-expand .navbar-nav {\n  flex-direction: row;\n}\n.navbar-expand .navbar-nav .dropdown-menu {\n  position: absolute;\n}\n.navbar-expand .navbar-nav .nav-link {\n  padding-right: var(--bs-navbar-nav-link-padding-x);\n  padding-left: var(--bs-navbar-nav-link-padding-x);\n}\n.navbar-expand .navbar-nav-scroll {\n  overflow: visible;\n}\n.navbar-expand .navbar-collapse {\n  display: flex !important;\n  flex-basis: auto;\n}\n.navbar-expand .navbar-toggler {\n  display: none;\n}\n.navbar-expand .offcanvas {\n  position: static;\n  z-index: auto;\n  flex-grow: 1;\n  width: auto !important;\n  height: auto !important;\n  visibility: visible !important;\n  background-color: transparent !important;\n  border: 0 !important;\n  transform: none !important;\n  transition: none;\n}\n.navbar-expand .offcanvas .offcanvas-header {\n  display: none;\n}\n.navbar-expand .offcanvas .offcanvas-body {\n  display: flex;\n  flex-grow: 0;\n  padding: 0;\n  overflow-y: visible;\n}\n\n.navbar-dark {\n  --bs-navbar-color: rgba(255, 255, 255, 0.55);\n  --bs-navbar-hover-color: rgba(255, 255, 255, 0.75);\n  --bs-navbar-disabled-color: rgba(255, 255, 255, 0.25);\n  --bs-navbar-active-color: #fff;\n  --bs-navbar-brand-color: #fff;\n  --bs-navbar-brand-hover-color: #fff;\n  --bs-navbar-toggler-border-color: rgba(255, 255, 255, 0.1);\n  --bs-navbar-toggler-icon-bg: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e\");\n}\n\n.card {\n  --bs-card-spacer-y: 1rem;\n  --bs-card-spacer-x: 1rem;\n  --bs-card-title-spacer-y: 0.5rem;\n  --bs-card-border-width: 0.125rem;\n  --bs-card-border-color: var(--bs-border-color-translucent);\n  --bs-card-border-radius: 0.5rem;\n  --bs-card-box-shadow: ;\n  --bs-card-inner-border-radius: 0.375rem;\n  --bs-card-cap-padding-y: 0.5rem;\n  --bs-card-cap-padding-x: 1rem;\n  --bs-card-cap-bg: rgba(0, 0, 0, 0.03);\n  --bs-card-cap-color: ;\n  --bs-card-height: ;\n  --bs-card-color: ;\n  --bs-card-bg: #fff;\n  --bs-card-img-overlay-padding: 1rem;\n  --bs-card-group-margin: 0.75rem;\n  position: relative;\n  display: flex;\n  flex-direction: column;\n  min-width: 0;\n  height: var(--bs-card-height);\n  word-wrap: break-word;\n  background-color: var(--bs-card-bg);\n  background-clip: border-box;\n  border: var(--bs-card-border-width) solid var(--bs-card-border-color);\n  border-radius: var(--bs-card-border-radius);\n}\n.card > hr {\n  margin-right: 0;\n  margin-left: 0;\n}\n.card > .list-group {\n  border-top: inherit;\n  border-bottom: inherit;\n}\n.card > .list-group:first-child {\n  border-top-width: 0;\n  border-top-left-radius: var(--bs-card-inner-border-radius);\n  border-top-right-radius: var(--bs-card-inner-border-radius);\n}\n.card > .list-group:last-child {\n  border-bottom-width: 0;\n  border-bottom-right-radius: var(--bs-card-inner-border-radius);\n  border-bottom-left-radius: var(--bs-card-inner-border-radius);\n}\n.card > .card-header + .list-group,\n.card > .list-group + .card-footer {\n  border-top: 0;\n}\n\n.card-body {\n  flex: 1 1 auto;\n  padding: var(--bs-card-spacer-y) var(--bs-card-spacer-x);\n  color: var(--bs-card-color);\n}\n\n.card-title {\n  margin-bottom: var(--bs-card-title-spacer-y);\n}\n\n.card-subtitle {\n  margin-top: calc(-0.5 * var(--bs-card-title-spacer-y));\n  margin-bottom: 0;\n}\n\n.card-text:last-child {\n  margin-bottom: 0;\n}\n\n.card-link + .card-link {\n  margin-left: var(--bs-card-spacer-x);\n}\n\n.card-header {\n  padding: var(--bs-card-cap-padding-y) var(--bs-card-cap-padding-x);\n  margin-bottom: 0;\n  color: var(--bs-card-cap-color);\n  background-color: var(--bs-card-cap-bg);\n  border-bottom: var(--bs-card-border-width) solid var(--bs-card-border-color);\n}\n.card-header:first-child {\n  border-radius: var(--bs-card-inner-border-radius) var(--bs-card-inner-border-radius) 0 0;\n}\n\n.card-footer {\n  padding: var(--bs-card-cap-padding-y) var(--bs-card-cap-padding-x);\n  color: var(--bs-card-cap-color);\n  background-color: var(--bs-card-cap-bg);\n  border-top: var(--bs-card-border-width) solid var(--bs-card-border-color);\n}\n.card-footer:last-child {\n  border-radius: 0 0 var(--bs-card-inner-border-radius) var(--bs-card-inner-border-radius);\n}\n\n.card-header-tabs {\n  margin-right: calc(-0.5 * var(--bs-card-cap-padding-x));\n  margin-bottom: calc(-1 * var(--bs-card-cap-padding-y));\n  margin-left: calc(-0.5 * var(--bs-card-cap-padding-x));\n  border-bottom: 0;\n}\n.card-header-tabs .nav-link.active {\n  background-color: var(--bs-card-bg);\n  border-bottom-color: var(--bs-card-bg);\n}\n\n.card-header-pills {\n  margin-right: calc(-0.5 * var(--bs-card-cap-padding-x));\n  margin-left: calc(-0.5 * var(--bs-card-cap-padding-x));\n}\n\n.card-img-overlay {\n  position: absolute;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  padding: var(--bs-card-img-overlay-padding);\n  border-radius: var(--bs-card-inner-border-radius);\n}\n\n.card-img,\n.card-img-top,\n.card-img-bottom {\n  width: 100%;\n}\n\n.card-img,\n.card-img-top {\n  border-top-left-radius: var(--bs-card-inner-border-radius);\n  border-top-right-radius: var(--bs-card-inner-border-radius);\n}\n\n.card-img,\n.card-img-bottom {\n  border-bottom-right-radius: var(--bs-card-inner-border-radius);\n  border-bottom-left-radius: var(--bs-card-inner-border-radius);\n}\n\n.card-group > .card {\n  margin-bottom: var(--bs-card-group-margin);\n}\n@media (min-width: 576px) {\n  .card-group {\n    display: flex;\n    flex-flow: row wrap;\n  }\n  .card-group > .card {\n    flex: 1 0 0%;\n    margin-bottom: 0;\n  }\n  .card-group > .card + .card {\n    margin-left: 0;\n    border-left: 0;\n  }\n  .card-group > .card:not(:last-child) {\n    border-top-right-radius: 0;\n    border-bottom-right-radius: 0;\n  }\n  .card-group > .card:not(:last-child) .card-img-top,\n  .card-group > .card:not(:last-child) .card-header {\n    border-top-right-radius: 0;\n  }\n  .card-group > .card:not(:last-child) .card-img-bottom,\n  .card-group > .card:not(:last-child) .card-footer {\n    border-bottom-right-radius: 0;\n  }\n  .card-group > .card:not(:first-child) {\n    border-top-left-radius: 0;\n    border-bottom-left-radius: 0;\n  }\n  .card-group > .card:not(:first-child) .card-img-top,\n  .card-group > .card:not(:first-child) .card-header {\n    border-top-left-radius: 0;\n  }\n  .card-group > .card:not(:first-child) .card-img-bottom,\n  .card-group > .card:not(:first-child) .card-footer {\n    border-bottom-left-radius: 0;\n  }\n}\n\n.accordion {\n  --bs-accordion-color: #212529;\n  --bs-accordion-bg: #fff;\n  --bs-accordion-transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out, border-radius 0.15s ease;\n  --bs-accordion-border-color: var(--bs-border-color);\n  --bs-accordion-border-width: 0.125rem;\n  --bs-accordion-border-radius: 0.5rem;\n  --bs-accordion-inner-border-radius: 0.375rem;\n  --bs-accordion-btn-padding-x: 1.25rem;\n  --bs-accordion-btn-padding-y: 1rem;\n  --bs-accordion-btn-color: #212529;\n  --bs-accordion-btn-bg: var(--bs-accordion-bg);\n  --bs-accordion-btn-icon: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23212529'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e\");\n  --bs-accordion-btn-icon-width: 1.25rem;\n  --bs-accordion-btn-icon-transform: rotate(-180deg);\n  --bs-accordion-btn-icon-transition: transform 0.2s ease-in-out;\n  --bs-accordion-btn-active-icon: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%2317a98c'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e\");\n  --bs-accordion-btn-focus-border-color: #8ddece;\n  --bs-accordion-btn-focus-box-shadow: 0 0 0 0.25rem rgba(26, 188, 156, 0.25);\n  --bs-accordion-body-padding-x: 1.25rem;\n  --bs-accordion-body-padding-y: 1rem;\n  --bs-accordion-active-color: #17a98c;\n  --bs-accordion-active-bg: #e8f8f5;\n}\n\n.accordion-button {\n  position: relative;\n  display: flex;\n  align-items: center;\n  width: 100%;\n  padding: var(--bs-accordion-btn-padding-y) var(--bs-accordion-btn-padding-x);\n  font-size: 1rem;\n  color: var(--bs-accordion-btn-color);\n  text-align: left;\n  background-color: var(--bs-accordion-btn-bg);\n  border: 0;\n  border-radius: 0;\n  overflow-anchor: none;\n  transition: var(--bs-accordion-transition);\n}\n@media (prefers-reduced-motion: reduce) {\n  .accordion-button {\n    transition: none;\n  }\n}\n.accordion-button:not(.collapsed) {\n  color: var(--bs-accordion-active-color);\n  background-color: var(--bs-accordion-active-bg);\n  box-shadow: inset 0 calc(-1 * var(--bs-accordion-border-width)) 0 var(--bs-accordion-border-color);\n}\n.accordion-button:not(.collapsed)::after {\n  background-image: var(--bs-accordion-btn-active-icon);\n  transform: var(--bs-accordion-btn-icon-transform);\n}\n.accordion-button::after {\n  flex-shrink: 0;\n  width: var(--bs-accordion-btn-icon-width);\n  height: var(--bs-accordion-btn-icon-width);\n  margin-left: auto;\n  content: \"\";\n  background-image: var(--bs-accordion-btn-icon);\n  background-repeat: no-repeat;\n  background-size: var(--bs-accordion-btn-icon-width);\n  transition: var(--bs-accordion-btn-icon-transition);\n}\n@media (prefers-reduced-motion: reduce) {\n  .accordion-button::after {\n    transition: none;\n  }\n}\n.accordion-button:hover {\n  z-index: 2;\n}\n.accordion-button:focus {\n  z-index: 3;\n  border-color: var(--bs-accordion-btn-focus-border-color);\n  outline: 0;\n  box-shadow: var(--bs-accordion-btn-focus-box-shadow);\n}\n\n.accordion-header {\n  margin-bottom: 0;\n}\n\n.accordion-item {\n  color: var(--bs-accordion-color);\n  background-color: var(--bs-accordion-bg);\n  border: var(--bs-accordion-border-width) solid var(--bs-accordion-border-color);\n}\n.accordion-item:first-of-type {\n  border-top-left-radius: var(--bs-accordion-border-radius);\n  border-top-right-radius: var(--bs-accordion-border-radius);\n}\n.accordion-item:first-of-type .accordion-button {\n  border-top-left-radius: var(--bs-accordion-inner-border-radius);\n  border-top-right-radius: var(--bs-accordion-inner-border-radius);\n}\n.accordion-item:not(:first-of-type) {\n  border-top: 0;\n}\n.accordion-item:last-of-type {\n  border-bottom-right-radius: var(--bs-accordion-border-radius);\n  border-bottom-left-radius: var(--bs-accordion-border-radius);\n}\n.accordion-item:last-of-type .accordion-button.collapsed {\n  border-bottom-right-radius: var(--bs-accordion-inner-border-radius);\n  border-bottom-left-radius: var(--bs-accordion-inner-border-radius);\n}\n.accordion-item:last-of-type .accordion-collapse {\n  border-bottom-right-radius: var(--bs-accordion-border-radius);\n  border-bottom-left-radius: var(--bs-accordion-border-radius);\n}\n\n.accordion-body {\n  padding: var(--bs-accordion-body-padding-y) var(--bs-accordion-body-padding-x);\n}\n\n.accordion-flush .accordion-collapse {\n  border-width: 0;\n}\n.accordion-flush .accordion-item {\n  border-right: 0;\n  border-left: 0;\n  border-radius: 0;\n}\n.accordion-flush .accordion-item:first-child {\n  border-top: 0;\n}\n.accordion-flush .accordion-item:last-child {\n  border-bottom: 0;\n}\n.accordion-flush .accordion-item .accordion-button, .accordion-flush .accordion-item .accordion-button.collapsed {\n  border-radius: 0;\n}\n\n.breadcrumb {\n  --bs-breadcrumb-padding-x: 0;\n  --bs-breadcrumb-padding-y: 0;\n  --bs-breadcrumb-margin-bottom: 1rem;\n  --bs-breadcrumb-bg: ;\n  --bs-breadcrumb-border-radius: ;\n  --bs-breadcrumb-divider-color: #6c757d;\n  --bs-breadcrumb-item-padding-x: 0.5rem;\n  --bs-breadcrumb-item-active-color: #6c757d;\n  display: flex;\n  flex-wrap: wrap;\n  padding: var(--bs-breadcrumb-padding-y) var(--bs-breadcrumb-padding-x);\n  margin-bottom: var(--bs-breadcrumb-margin-bottom);\n  font-size: var(--bs-breadcrumb-font-size);\n  list-style: none;\n  background-color: var(--bs-breadcrumb-bg);\n  border-radius: var(--bs-breadcrumb-border-radius);\n}\n\n.breadcrumb-item + .breadcrumb-item {\n  padding-left: var(--bs-breadcrumb-item-padding-x);\n}\n.breadcrumb-item + .breadcrumb-item::before {\n  float: left;\n  padding-right: var(--bs-breadcrumb-item-padding-x);\n  color: var(--bs-breadcrumb-divider-color);\n  content: var(--bs-breadcrumb-divider, \"/\") /* rtl: var(--bs-breadcrumb-divider, \"/\") */;\n}\n.breadcrumb-item.active {\n  color: var(--bs-breadcrumb-item-active-color);\n}\n\n.pagination {\n  --bs-pagination-padding-x: 0.75rem;\n  --bs-pagination-padding-y: 0.375rem;\n  --bs-pagination-font-size: 1rem;\n  --bs-pagination-color: var(--bs-link-color);\n  --bs-pagination-bg: #fff;\n  --bs-pagination-border-width: 0.125rem;\n  --bs-pagination-border-color: #dee2e6;\n  --bs-pagination-border-radius: 0.5rem;\n  --bs-pagination-hover-color: var(--bs-link-hover-color);\n  --bs-pagination-hover-bg: #e9ecef;\n  --bs-pagination-hover-border-color: #dee2e6;\n  --bs-pagination-focus-color: var(--bs-link-hover-color);\n  --bs-pagination-focus-bg: #e9ecef;\n  --bs-pagination-focus-box-shadow: 0 0 0 0.25rem rgba(26, 188, 156, 0.25);\n  --bs-pagination-active-color: #fff;\n  --bs-pagination-active-bg: #1abc9c;\n  --bs-pagination-active-border-color: #1abc9c;\n  --bs-pagination-disabled-color: #6c757d;\n  --bs-pagination-disabled-bg: #fff;\n  --bs-pagination-disabled-border-color: #dee2e6;\n  display: flex;\n  padding-left: 0;\n  list-style: none;\n}\n\n.page-link {\n  position: relative;\n  display: block;\n  padding: var(--bs-pagination-padding-y) var(--bs-pagination-padding-x);\n  font-size: var(--bs-pagination-font-size);\n  color: var(--bs-pagination-color);\n  text-decoration: none;\n  background-color: var(--bs-pagination-bg);\n  border: var(--bs-pagination-border-width) solid var(--bs-pagination-border-color);\n  transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n@media (prefers-reduced-motion: reduce) {\n  .page-link {\n    transition: none;\n  }\n}\n.page-link:hover {\n  z-index: 2;\n  color: var(--bs-pagination-hover-color);\n  background-color: var(--bs-pagination-hover-bg);\n  border-color: var(--bs-pagination-hover-border-color);\n}\n.page-link:focus {\n  z-index: 3;\n  color: var(--bs-pagination-focus-color);\n  background-color: var(--bs-pagination-focus-bg);\n  outline: 0;\n  box-shadow: var(--bs-pagination-focus-box-shadow);\n}\n.page-link.active, .active > .page-link {\n  z-index: 3;\n  color: var(--bs-pagination-active-color);\n  background-color: var(--bs-pagination-active-bg);\n  border-color: var(--bs-pagination-active-border-color);\n}\n.page-link.disabled, .disabled > .page-link {\n  color: var(--bs-pagination-disabled-color);\n  pointer-events: none;\n  background-color: var(--bs-pagination-disabled-bg);\n  border-color: var(--bs-pagination-disabled-border-color);\n}\n\n.page-item:not(:first-child) .page-link {\n  margin-left: -0.125rem;\n}\n.page-item:first-child .page-link {\n  border-top-left-radius: var(--bs-pagination-border-radius);\n  border-bottom-left-radius: var(--bs-pagination-border-radius);\n}\n.page-item:last-child .page-link {\n  border-top-right-radius: var(--bs-pagination-border-radius);\n  border-bottom-right-radius: var(--bs-pagination-border-radius);\n}\n\n.pagination-lg {\n  --bs-pagination-padding-x: 1.5rem;\n  --bs-pagination-padding-y: 0.75rem;\n  --bs-pagination-font-size: 1.25rem;\n  --bs-pagination-border-radius: 0.75rem;\n}\n\n.pagination-sm {\n  --bs-pagination-padding-x: 0.5rem;\n  --bs-pagination-padding-y: 0.25rem;\n  --bs-pagination-font-size: 0.875rem;\n  --bs-pagination-border-radius: 0.25rem;\n}\n\n.badge {\n  --bs-badge-padding-x: 0.65em;\n  --bs-badge-padding-y: 0.35em;\n  --bs-badge-font-size: 0.75em;\n  --bs-badge-font-weight: 700;\n  --bs-badge-color: #fff;\n  --bs-badge-border-radius: 0.5rem;\n  display: inline-block;\n  padding: var(--bs-badge-padding-y) var(--bs-badge-padding-x);\n  font-size: var(--bs-badge-font-size);\n  font-weight: var(--bs-badge-font-weight);\n  line-height: 1;\n  color: var(--bs-badge-color);\n  text-align: center;\n  white-space: nowrap;\n  vertical-align: baseline;\n  border-radius: var(--bs-badge-border-radius);\n}\n.badge:empty {\n  display: none;\n}\n\n.btn .badge {\n  position: relative;\n  top: -1px;\n}\n\n.alert {\n  --bs-alert-bg: transparent;\n  --bs-alert-padding-x: 1rem;\n  --bs-alert-padding-y: 1rem;\n  --bs-alert-margin-bottom: 1rem;\n  --bs-alert-color: inherit;\n  --bs-alert-border-color: transparent;\n  --bs-alert-border: 0.125rem solid var(--bs-alert-border-color);\n  --bs-alert-border-radius: 0.5rem;\n  position: relative;\n  padding: var(--bs-alert-padding-y) var(--bs-alert-padding-x);\n  margin-bottom: var(--bs-alert-margin-bottom);\n  color: var(--bs-alert-color);\n  background-color: var(--bs-alert-bg);\n  border: var(--bs-alert-border);\n  border-radius: var(--bs-alert-border-radius);\n}\n\n.alert-heading {\n  color: inherit;\n}\n\n.alert-link {\n  font-weight: 700;\n}\n\n.alert-dismissible {\n  padding-right: 3rem;\n}\n.alert-dismissible .btn-close {\n  position: absolute;\n  top: 0;\n  right: 0;\n  z-index: 2;\n  padding: 1.25rem 1rem;\n}\n\n.alert-primary {\n  --bs-alert-color: #10715e;\n  --bs-alert-bg: #d1f2eb;\n  --bs-alert-border-color: #baebe1;\n}\n.alert-primary .alert-link {\n  color: #0d5a4b;\n}\n\n.alert-secondary {\n  --bs-alert-color: #1a2530;\n  --bs-alert-bg: #d5d8dc;\n  --bs-alert-border-color: #c0c5cb;\n}\n.alert-secondary .alert-link {\n  color: #151e26;\n}\n\n.alert-success {\n  --bs-alert-color: #0f5132;\n  --bs-alert-bg: #d1e7dd;\n  --bs-alert-border-color: #badbcc;\n}\n.alert-success .alert-link {\n  color: #0c4128;\n}\n\n.alert-info {\n  --bs-alert-color: #087990;\n  --bs-alert-bg: #cff4fc;\n  --bs-alert-border-color: #b6effb;\n}\n.alert-info .alert-link {\n  color: #066173;\n}\n\n.alert-warning {\n  --bs-alert-color: #997404;\n  --bs-alert-bg: #fff3cd;\n  --bs-alert-border-color: #ffecb5;\n}\n.alert-warning .alert-link {\n  color: #7a5d03;\n}\n\n.alert-danger {\n  --bs-alert-color: #842029;\n  --bs-alert-bg: #f8d7da;\n  --bs-alert-border-color: #f5c2c7;\n}\n.alert-danger .alert-link {\n  color: #6a1a21;\n}\n\n.alert-light {\n  --bs-alert-color: #959596;\n  --bs-alert-bg: #fefefe;\n  --bs-alert-border-color: #fdfdfe;\n}\n.alert-light .alert-link {\n  color: #777778;\n}\n\n.alert-dark {\n  --bs-alert-color: #141619;\n  --bs-alert-bg: #d3d3d4;\n  --bs-alert-border-color: #bcbebf;\n}\n.alert-dark .alert-link {\n  color: #101214;\n}\n\n@keyframes progress-bar-stripes {\n  0% {\n    background-position-x: 1rem;\n  }\n}\n.progress {\n  --bs-progress-height: 1rem;\n  --bs-progress-font-size: 0.75rem;\n  --bs-progress-bg: #e9ecef;\n  --bs-progress-border-radius: 0.5rem;\n  --bs-progress-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.075);\n  --bs-progress-bar-color: #fff;\n  --bs-progress-bar-bg: #1abc9c;\n  --bs-progress-bar-transition: width 0.6s ease;\n  display: flex;\n  height: var(--bs-progress-height);\n  overflow: hidden;\n  font-size: var(--bs-progress-font-size);\n  background-color: var(--bs-progress-bg);\n  border-radius: var(--bs-progress-border-radius);\n}\n\n.progress-bar {\n  display: flex;\n  flex-direction: column;\n  justify-content: center;\n  overflow: hidden;\n  color: var(--bs-progress-bar-color);\n  text-align: center;\n  white-space: nowrap;\n  background-color: var(--bs-progress-bar-bg);\n  transition: var(--bs-progress-bar-transition);\n}\n@media (prefers-reduced-motion: reduce) {\n  .progress-bar {\n    transition: none;\n  }\n}\n\n.progress-bar-striped {\n  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-size: var(--bs-progress-height) var(--bs-progress-height);\n}\n\n.progress-bar-animated {\n  animation: 1s linear infinite progress-bar-stripes;\n}\n@media (prefers-reduced-motion: reduce) {\n  .progress-bar-animated {\n    animation: none;\n  }\n}\n\n.list-group {\n  --bs-list-group-color: #212529;\n  --bs-list-group-bg: #fff;\n  --bs-list-group-border-color: rgba(0, 0, 0, 0.125);\n  --bs-list-group-border-width: 0.125rem;\n  --bs-list-group-border-radius: 0.5rem;\n  --bs-list-group-item-padding-x: 1rem;\n  --bs-list-group-item-padding-y: 0.5rem;\n  --bs-list-group-action-color: #495057;\n  --bs-list-group-action-hover-color: #495057;\n  --bs-list-group-action-hover-bg: #f8f9fa;\n  --bs-list-group-action-active-color: #212529;\n  --bs-list-group-action-active-bg: #e9ecef;\n  --bs-list-group-disabled-color: #6c757d;\n  --bs-list-group-disabled-bg: #fff;\n  --bs-list-group-active-color: #fff;\n  --bs-list-group-active-bg: #1abc9c;\n  --bs-list-group-active-border-color: #1abc9c;\n  display: flex;\n  flex-direction: column;\n  padding-left: 0;\n  margin-bottom: 0;\n  border-radius: var(--bs-list-group-border-radius);\n}\n\n.list-group-numbered {\n  list-style-type: none;\n  counter-reset: section;\n}\n.list-group-numbered > .list-group-item::before {\n  content: counters(section, \".\") \". \";\n  counter-increment: section;\n}\n\n.list-group-item-action {\n  width: 100%;\n  color: var(--bs-list-group-action-color);\n  text-align: inherit;\n}\n.list-group-item-action:hover, .list-group-item-action:focus {\n  z-index: 1;\n  color: var(--bs-list-group-action-hover-color);\n  text-decoration: none;\n  background-color: var(--bs-list-group-action-hover-bg);\n}\n.list-group-item-action:active {\n  color: var(--bs-list-group-action-active-color);\n  background-color: var(--bs-list-group-action-active-bg);\n}\n\n.list-group-item {\n  position: relative;\n  display: block;\n  padding: var(--bs-list-group-item-padding-y) var(--bs-list-group-item-padding-x);\n  color: var(--bs-list-group-color);\n  text-decoration: none;\n  background-color: var(--bs-list-group-bg);\n  border: var(--bs-list-group-border-width) solid var(--bs-list-group-border-color);\n}\n.list-group-item:first-child {\n  border-top-left-radius: inherit;\n  border-top-right-radius: inherit;\n}\n.list-group-item:last-child {\n  border-bottom-right-radius: inherit;\n  border-bottom-left-radius: inherit;\n}\n.list-group-item.disabled, .list-group-item:disabled {\n  color: var(--bs-list-group-disabled-color);\n  pointer-events: none;\n  background-color: var(--bs-list-group-disabled-bg);\n}\n.list-group-item.active {\n  z-index: 2;\n  color: var(--bs-list-group-active-color);\n  background-color: var(--bs-list-group-active-bg);\n  border-color: var(--bs-list-group-active-border-color);\n}\n.list-group-item + .list-group-item {\n  border-top-width: 0;\n}\n.list-group-item + .list-group-item.active {\n  margin-top: calc(-1 * var(--bs-list-group-border-width));\n  border-top-width: var(--bs-list-group-border-width);\n}\n\n.list-group-horizontal {\n  flex-direction: row;\n}\n.list-group-horizontal > .list-group-item:first-child:not(:last-child) {\n  border-bottom-left-radius: var(--bs-list-group-border-radius);\n  border-top-right-radius: 0;\n}\n.list-group-horizontal > .list-group-item:last-child:not(:first-child) {\n  border-top-right-radius: var(--bs-list-group-border-radius);\n  border-bottom-left-radius: 0;\n}\n.list-group-horizontal > .list-group-item.active {\n  margin-top: 0;\n}\n.list-group-horizontal > .list-group-item + .list-group-item {\n  border-top-width: var(--bs-list-group-border-width);\n  border-left-width: 0;\n}\n.list-group-horizontal > .list-group-item + .list-group-item.active {\n  margin-left: calc(-1 * var(--bs-list-group-border-width));\n  border-left-width: var(--bs-list-group-border-width);\n}\n\n@media (min-width: 576px) {\n  .list-group-horizontal-sm {\n    flex-direction: row;\n  }\n  .list-group-horizontal-sm > .list-group-item:first-child:not(:last-child) {\n    border-bottom-left-radius: var(--bs-list-group-border-radius);\n    border-top-right-radius: 0;\n  }\n  .list-group-horizontal-sm > .list-group-item:last-child:not(:first-child) {\n    border-top-right-radius: var(--bs-list-group-border-radius);\n    border-bottom-left-radius: 0;\n  }\n  .list-group-horizontal-sm > .list-group-item.active {\n    margin-top: 0;\n  }\n  .list-group-horizontal-sm > .list-group-item + .list-group-item {\n    border-top-width: var(--bs-list-group-border-width);\n    border-left-width: 0;\n  }\n  .list-group-horizontal-sm > .list-group-item + .list-group-item.active {\n    margin-left: calc(-1 * var(--bs-list-group-border-width));\n    border-left-width: var(--bs-list-group-border-width);\n  }\n}\n@media (min-width: 768px) {\n  .list-group-horizontal-md {\n    flex-direction: row;\n  }\n  .list-group-horizontal-md > .list-group-item:first-child:not(:last-child) {\n    border-bottom-left-radius: var(--bs-list-group-border-radius);\n    border-top-right-radius: 0;\n  }\n  .list-group-horizontal-md > .list-group-item:last-child:not(:first-child) {\n    border-top-right-radius: var(--bs-list-group-border-radius);\n    border-bottom-left-radius: 0;\n  }\n  .list-group-horizontal-md > .list-group-item.active {\n    margin-top: 0;\n  }\n  .list-group-horizontal-md > .list-group-item + .list-group-item {\n    border-top-width: var(--bs-list-group-border-width);\n    border-left-width: 0;\n  }\n  .list-group-horizontal-md > .list-group-item + .list-group-item.active {\n    margin-left: calc(-1 * var(--bs-list-group-border-width));\n    border-left-width: var(--bs-list-group-border-width);\n  }\n}\n@media (min-width: 992px) {\n  .list-group-horizontal-lg {\n    flex-direction: row;\n  }\n  .list-group-horizontal-lg > .list-group-item:first-child:not(:last-child) {\n    border-bottom-left-radius: var(--bs-list-group-border-radius);\n    border-top-right-radius: 0;\n  }\n  .list-group-horizontal-lg > .list-group-item:last-child:not(:first-child) {\n    border-top-right-radius: var(--bs-list-group-border-radius);\n    border-bottom-left-radius: 0;\n  }\n  .list-group-horizontal-lg > .list-group-item.active {\n    margin-top: 0;\n  }\n  .list-group-horizontal-lg > .list-group-item + .list-group-item {\n    border-top-width: var(--bs-list-group-border-width);\n    border-left-width: 0;\n  }\n  .list-group-horizontal-lg > .list-group-item + .list-group-item.active {\n    margin-left: calc(-1 * var(--bs-list-group-border-width));\n    border-left-width: var(--bs-list-group-border-width);\n  }\n}\n@media (min-width: 1200px) {\n  .list-group-horizontal-xl {\n    flex-direction: row;\n  }\n  .list-group-horizontal-xl > .list-group-item:first-child:not(:last-child) {\n    border-bottom-left-radius: var(--bs-list-group-border-radius);\n    border-top-right-radius: 0;\n  }\n  .list-group-horizontal-xl > .list-group-item:last-child:not(:first-child) {\n    border-top-right-radius: var(--bs-list-group-border-radius);\n    border-bottom-left-radius: 0;\n  }\n  .list-group-horizontal-xl > .list-group-item.active {\n    margin-top: 0;\n  }\n  .list-group-horizontal-xl > .list-group-item + .list-group-item {\n    border-top-width: var(--bs-list-group-border-width);\n    border-left-width: 0;\n  }\n  .list-group-horizontal-xl > .list-group-item + .list-group-item.active {\n    margin-left: calc(-1 * var(--bs-list-group-border-width));\n    border-left-width: var(--bs-list-group-border-width);\n  }\n}\n@media (min-width: 1400px) {\n  .list-group-horizontal-xxl {\n    flex-direction: row;\n  }\n  .list-group-horizontal-xxl > .list-group-item:first-child:not(:last-child) {\n    border-bottom-left-radius: var(--bs-list-group-border-radius);\n    border-top-right-radius: 0;\n  }\n  .list-group-horizontal-xxl > .list-group-item:last-child:not(:first-child) {\n    border-top-right-radius: var(--bs-list-group-border-radius);\n    border-bottom-left-radius: 0;\n  }\n  .list-group-horizontal-xxl > .list-group-item.active {\n    margin-top: 0;\n  }\n  .list-group-horizontal-xxl > .list-group-item + .list-group-item {\n    border-top-width: var(--bs-list-group-border-width);\n    border-left-width: 0;\n  }\n  .list-group-horizontal-xxl > .list-group-item + .list-group-item.active {\n    margin-left: calc(-1 * var(--bs-list-group-border-width));\n    border-left-width: var(--bs-list-group-border-width);\n  }\n}\n.list-group-flush {\n  border-radius: 0;\n}\n.list-group-flush > .list-group-item {\n  border-width: 0 0 var(--bs-list-group-border-width);\n}\n.list-group-flush > .list-group-item:last-child {\n  border-bottom-width: 0;\n}\n\n.list-group-item-primary {\n  color: #10715e;\n  background-color: #d1f2eb;\n}\n.list-group-item-primary.list-group-item-action:hover, .list-group-item-primary.list-group-item-action:focus {\n  color: #10715e;\n  background-color: #bcdad4;\n}\n.list-group-item-primary.list-group-item-action.active {\n  color: #fff;\n  background-color: #10715e;\n  border-color: #10715e;\n}\n\n.list-group-item-secondary {\n  color: #1a2530;\n  background-color: #d5d8dc;\n}\n.list-group-item-secondary.list-group-item-action:hover, .list-group-item-secondary.list-group-item-action:focus {\n  color: #1a2530;\n  background-color: #c0c2c6;\n}\n.list-group-item-secondary.list-group-item-action.active {\n  color: #fff;\n  background-color: #1a2530;\n  border-color: #1a2530;\n}\n\n.list-group-item-success {\n  color: #0f5132;\n  background-color: #d1e7dd;\n}\n.list-group-item-success.list-group-item-action:hover, .list-group-item-success.list-group-item-action:focus {\n  color: #0f5132;\n  background-color: #bcd0c7;\n}\n.list-group-item-success.list-group-item-action.active {\n  color: #fff;\n  background-color: #0f5132;\n  border-color: #0f5132;\n}\n\n.list-group-item-info {\n  color: #087990;\n  background-color: #cff4fc;\n}\n.list-group-item-info.list-group-item-action:hover, .list-group-item-info.list-group-item-action:focus {\n  color: #087990;\n  background-color: #badce3;\n}\n.list-group-item-info.list-group-item-action.active {\n  color: #fff;\n  background-color: #087990;\n  border-color: #087990;\n}\n\n.list-group-item-warning {\n  color: #997404;\n  background-color: #fff3cd;\n}\n.list-group-item-warning.list-group-item-action:hover, .list-group-item-warning.list-group-item-action:focus {\n  color: #997404;\n  background-color: #e6dbb9;\n}\n.list-group-item-warning.list-group-item-action.active {\n  color: #fff;\n  background-color: #997404;\n  border-color: #997404;\n}\n\n.list-group-item-danger {\n  color: #842029;\n  background-color: #f8d7da;\n}\n.list-group-item-danger.list-group-item-action:hover, .list-group-item-danger.list-group-item-action:focus {\n  color: #842029;\n  background-color: #dfc2c4;\n}\n.list-group-item-danger.list-group-item-action.active {\n  color: #fff;\n  background-color: #842029;\n  border-color: #842029;\n}\n\n.list-group-item-light {\n  color: #959596;\n  background-color: #fefefe;\n}\n.list-group-item-light.list-group-item-action:hover, .list-group-item-light.list-group-item-action:focus {\n  color: #959596;\n  background-color: #e5e5e5;\n}\n.list-group-item-light.list-group-item-action.active {\n  color: #fff;\n  background-color: #959596;\n  border-color: #959596;\n}\n\n.list-group-item-dark {\n  color: #141619;\n  background-color: #d3d3d4;\n}\n.list-group-item-dark.list-group-item-action:hover, .list-group-item-dark.list-group-item-action:focus {\n  color: #141619;\n  background-color: #bebebf;\n}\n.list-group-item-dark.list-group-item-action.active {\n  color: #fff;\n  background-color: #141619;\n  border-color: #141619;\n}\n\n.btn-close {\n  box-sizing: content-box;\n  width: 1em;\n  height: 1em;\n  padding: 0.25em 0.25em;\n  color: #000;\n  background: transparent url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23000'%3e%3cpath d='M.293.293a1 1 0 0 1 1.414 0L8 6.586 14.293.293a1 1 0 1 1 1.414 1.414L9.414 8l6.293 6.293a1 1 0 0 1-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 0 1-1.414-1.414L6.586 8 .293 1.707a1 1 0 0 1 0-1.414z'/%3e%3c/svg%3e\") center/1em auto no-repeat;\n  border: 0;\n  border-radius: 0.5rem;\n  opacity: 0.5;\n}\n.btn-close:hover {\n  color: #000;\n  text-decoration: none;\n  opacity: 0.75;\n}\n.btn-close:focus {\n  outline: 0;\n  box-shadow: 0 0 0 0.25rem rgba(26, 188, 156, 0.25);\n  opacity: 1;\n}\n.btn-close:disabled, .btn-close.disabled {\n  pointer-events: none;\n  -webkit-user-select: none;\n     -moz-user-select: none;\n          user-select: none;\n  opacity: 0.25;\n}\n\n.btn-close-white {\n  filter: invert(1) grayscale(100%) brightness(200%);\n}\n\n.toast {\n  --bs-toast-zindex: 1090;\n  --bs-toast-padding-x: 0.75rem;\n  --bs-toast-padding-y: 0.5rem;\n  --bs-toast-spacing: 1.5rem;\n  --bs-toast-max-width: 350px;\n  --bs-toast-font-size: 0.875rem;\n  --bs-toast-color: ;\n  --bs-toast-bg: rgba(255, 255, 255, 0.85);\n  --bs-toast-border-width: 0.125rem;\n  --bs-toast-border-color: var(--bs-border-color-translucent);\n  --bs-toast-border-radius: 0.5rem;\n  --bs-toast-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);\n  --bs-toast-header-color: #6c757d;\n  --bs-toast-header-bg: rgba(255, 255, 255, 0.85);\n  --bs-toast-header-border-color: rgba(0, 0, 0, 0.05);\n  width: var(--bs-toast-max-width);\n  max-width: 100%;\n  font-size: var(--bs-toast-font-size);\n  color: var(--bs-toast-color);\n  pointer-events: auto;\n  background-color: var(--bs-toast-bg);\n  background-clip: padding-box;\n  border: var(--bs-toast-border-width) solid var(--bs-toast-border-color);\n  box-shadow: var(--bs-toast-box-shadow);\n  border-radius: var(--bs-toast-border-radius);\n}\n.toast.showing {\n  opacity: 0;\n}\n.toast:not(.show) {\n  display: none;\n}\n\n.toast-container {\n  --bs-toast-zindex: 1090;\n  position: absolute;\n  z-index: var(--bs-toast-zindex);\n  width: -moz-max-content;\n  width: max-content;\n  max-width: 100%;\n  pointer-events: none;\n}\n.toast-container > :not(:last-child) {\n  margin-bottom: var(--bs-toast-spacing);\n}\n\n.toast-header {\n  display: flex;\n  align-items: center;\n  padding: var(--bs-toast-padding-y) var(--bs-toast-padding-x);\n  color: var(--bs-toast-header-color);\n  background-color: var(--bs-toast-header-bg);\n  background-clip: padding-box;\n  border-bottom: var(--bs-toast-border-width) solid var(--bs-toast-header-border-color);\n  border-top-left-radius: calc(var(--bs-toast-border-radius) - var(--bs-toast-border-width));\n  border-top-right-radius: calc(var(--bs-toast-border-radius) - var(--bs-toast-border-width));\n}\n.toast-header .btn-close {\n  margin-right: calc(-0.5 * var(--bs-toast-padding-x));\n  margin-left: var(--bs-toast-padding-x);\n}\n\n.toast-body {\n  padding: var(--bs-toast-padding-x);\n  word-wrap: break-word;\n}\n\n.modal {\n  --bs-modal-zindex: 1055;\n  --bs-modal-width: 500px;\n  --bs-modal-padding: 1rem;\n  --bs-modal-margin: 0.5rem;\n  --bs-modal-color: ;\n  --bs-modal-bg: #fff;\n  --bs-modal-border-color: var(--bs-border-color-translucent);\n  --bs-modal-border-width: 0.125rem;\n  --bs-modal-border-radius: 0.75rem;\n  --bs-modal-box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);\n  --bs-modal-inner-border-radius: 0.625rem;\n  --bs-modal-header-padding-x: 1rem;\n  --bs-modal-header-padding-y: 1rem;\n  --bs-modal-header-padding: 1rem 1rem;\n  --bs-modal-header-border-color: var(--bs-border-color);\n  --bs-modal-header-border-width: 0.125rem;\n  --bs-modal-title-line-height: 1.5;\n  --bs-modal-footer-gap: 0.5rem;\n  --bs-modal-footer-bg: ;\n  --bs-modal-footer-border-color: var(--bs-border-color);\n  --bs-modal-footer-border-width: 0.125rem;\n  position: fixed;\n  top: 0;\n  left: 0;\n  z-index: var(--bs-modal-zindex);\n  display: none;\n  width: 100%;\n  height: 100%;\n  overflow-x: hidden;\n  overflow-y: auto;\n  outline: 0;\n}\n\n.modal-dialog {\n  position: relative;\n  width: auto;\n  margin: var(--bs-modal-margin);\n  pointer-events: none;\n}\n.modal.fade .modal-dialog {\n  transition: transform 0.3s ease-out;\n  transform: translate(0, -50px);\n}\n@media (prefers-reduced-motion: reduce) {\n  .modal.fade .modal-dialog {\n    transition: none;\n  }\n}\n.modal.show .modal-dialog {\n  transform: none;\n}\n.modal.modal-static .modal-dialog {\n  transform: scale(1.02);\n}\n\n.modal-dialog-scrollable {\n  height: calc(100% - var(--bs-modal-margin) * 2);\n}\n.modal-dialog-scrollable .modal-content {\n  max-height: 100%;\n  overflow: hidden;\n}\n.modal-dialog-scrollable .modal-body {\n  overflow-y: auto;\n}\n\n.modal-dialog-centered {\n  display: flex;\n  align-items: center;\n  min-height: calc(100% - var(--bs-modal-margin) * 2);\n}\n\n.modal-content {\n  position: relative;\n  display: flex;\n  flex-direction: column;\n  width: 100%;\n  color: var(--bs-modal-color);\n  pointer-events: auto;\n  background-color: var(--bs-modal-bg);\n  background-clip: padding-box;\n  border: var(--bs-modal-border-width) solid var(--bs-modal-border-color);\n  border-radius: var(--bs-modal-border-radius);\n  outline: 0;\n}\n\n.modal-backdrop {\n  --bs-backdrop-zindex: 1050;\n  --bs-backdrop-bg: #000;\n  --bs-backdrop-opacity: 0.5;\n  position: fixed;\n  top: 0;\n  left: 0;\n  z-index: var(--bs-backdrop-zindex);\n  width: 100vw;\n  height: 100vh;\n  background-color: var(--bs-backdrop-bg);\n}\n.modal-backdrop.fade {\n  opacity: 0;\n}\n.modal-backdrop.show {\n  opacity: var(--bs-backdrop-opacity);\n}\n\n.modal-header {\n  display: flex;\n  flex-shrink: 0;\n  align-items: center;\n  justify-content: space-between;\n  padding: var(--bs-modal-header-padding);\n  border-bottom: var(--bs-modal-header-border-width) solid var(--bs-modal-header-border-color);\n  border-top-left-radius: var(--bs-modal-inner-border-radius);\n  border-top-right-radius: var(--bs-modal-inner-border-radius);\n}\n.modal-header .btn-close {\n  padding: calc(var(--bs-modal-header-padding-y) * 0.5) calc(var(--bs-modal-header-padding-x) * 0.5);\n  margin: calc(-0.5 * var(--bs-modal-header-padding-y)) calc(-0.5 * var(--bs-modal-header-padding-x)) calc(-0.5 * var(--bs-modal-header-padding-y)) auto;\n}\n\n.modal-title {\n  margin-bottom: 0;\n  line-height: var(--bs-modal-title-line-height);\n}\n\n.modal-body {\n  position: relative;\n  flex: 1 1 auto;\n  padding: var(--bs-modal-padding);\n}\n\n.modal-footer {\n  display: flex;\n  flex-shrink: 0;\n  flex-wrap: wrap;\n  align-items: center;\n  justify-content: flex-end;\n  padding: calc(var(--bs-modal-padding) - var(--bs-modal-footer-gap) * 0.5);\n  background-color: var(--bs-modal-footer-bg);\n  border-top: var(--bs-modal-footer-border-width) solid var(--bs-modal-footer-border-color);\n  border-bottom-right-radius: var(--bs-modal-inner-border-radius);\n  border-bottom-left-radius: var(--bs-modal-inner-border-radius);\n}\n.modal-footer > * {\n  margin: calc(var(--bs-modal-footer-gap) * 0.5);\n}\n\n@media (min-width: 576px) {\n  .modal {\n    --bs-modal-margin: 1.75rem;\n    --bs-modal-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);\n  }\n  .modal-dialog {\n    max-width: var(--bs-modal-width);\n    margin-right: auto;\n    margin-left: auto;\n  }\n  .modal-sm {\n    --bs-modal-width: 300px;\n  }\n}\n@media (min-width: 992px) {\n  .modal-lg,\n  .modal-xl {\n    --bs-modal-width: 800px;\n  }\n}\n@media (min-width: 1200px) {\n  .modal-xl {\n    --bs-modal-width: 1140px;\n  }\n}\n.modal-fullscreen {\n  width: 100vw;\n  max-width: none;\n  height: 100%;\n  margin: 0;\n}\n.modal-fullscreen .modal-content {\n  height: 100%;\n  border: 0;\n  border-radius: 0;\n}\n.modal-fullscreen .modal-header,\n.modal-fullscreen .modal-footer {\n  border-radius: 0;\n}\n.modal-fullscreen .modal-body {\n  overflow-y: auto;\n}\n\n@media (max-width: 575.98px) {\n  .modal-fullscreen-sm-down {\n    width: 100vw;\n    max-width: none;\n    height: 100%;\n    margin: 0;\n  }\n  .modal-fullscreen-sm-down .modal-content {\n    height: 100%;\n    border: 0;\n    border-radius: 0;\n  }\n  .modal-fullscreen-sm-down .modal-header,\n  .modal-fullscreen-sm-down .modal-footer {\n    border-radius: 0;\n  }\n  .modal-fullscreen-sm-down .modal-body {\n    overflow-y: auto;\n  }\n}\n@media (max-width: 767.98px) {\n  .modal-fullscreen-md-down {\n    width: 100vw;\n    max-width: none;\n    height: 100%;\n    margin: 0;\n  }\n  .modal-fullscreen-md-down .modal-content {\n    height: 100%;\n    border: 0;\n    border-radius: 0;\n  }\n  .modal-fullscreen-md-down .modal-header,\n  .modal-fullscreen-md-down .modal-footer {\n    border-radius: 0;\n  }\n  .modal-fullscreen-md-down .modal-body {\n    overflow-y: auto;\n  }\n}\n@media (max-width: 991.98px) {\n  .modal-fullscreen-lg-down {\n    width: 100vw;\n    max-width: none;\n    height: 100%;\n    margin: 0;\n  }\n  .modal-fullscreen-lg-down .modal-content {\n    height: 100%;\n    border: 0;\n    border-radius: 0;\n  }\n  .modal-fullscreen-lg-down .modal-header,\n  .modal-fullscreen-lg-down .modal-footer {\n    border-radius: 0;\n  }\n  .modal-fullscreen-lg-down .modal-body {\n    overflow-y: auto;\n  }\n}\n@media (max-width: 1199.98px) {\n  .modal-fullscreen-xl-down {\n    width: 100vw;\n    max-width: none;\n    height: 100%;\n    margin: 0;\n  }\n  .modal-fullscreen-xl-down .modal-content {\n    height: 100%;\n    border: 0;\n    border-radius: 0;\n  }\n  .modal-fullscreen-xl-down .modal-header,\n  .modal-fullscreen-xl-down .modal-footer {\n    border-radius: 0;\n  }\n  .modal-fullscreen-xl-down .modal-body {\n    overflow-y: auto;\n  }\n}\n@media (max-width: 1399.98px) {\n  .modal-fullscreen-xxl-down {\n    width: 100vw;\n    max-width: none;\n    height: 100%;\n    margin: 0;\n  }\n  .modal-fullscreen-xxl-down .modal-content {\n    height: 100%;\n    border: 0;\n    border-radius: 0;\n  }\n  .modal-fullscreen-xxl-down .modal-header,\n  .modal-fullscreen-xxl-down .modal-footer {\n    border-radius: 0;\n  }\n  .modal-fullscreen-xxl-down .modal-body {\n    overflow-y: auto;\n  }\n}\n.tooltip {\n  --bs-tooltip-zindex: 1080;\n  --bs-tooltip-max-width: 200px;\n  --bs-tooltip-padding-x: 0.5rem;\n  --bs-tooltip-padding-y: 0.25rem;\n  --bs-tooltip-margin: ;\n  --bs-tooltip-font-size: 0.875rem;\n  --bs-tooltip-color: #fff;\n  --bs-tooltip-bg: #000;\n  --bs-tooltip-border-radius: 0.5rem;\n  --bs-tooltip-opacity: 0.9;\n  --bs-tooltip-arrow-width: 0.8rem;\n  --bs-tooltip-arrow-height: 0.4rem;\n  z-index: var(--bs-tooltip-zindex);\n  display: block;\n  padding: var(--bs-tooltip-arrow-height);\n  margin: var(--bs-tooltip-margin);\n  font-family: var(--bs-font-sans-serif);\n  font-style: normal;\n  font-weight: 400;\n  line-height: 1.5;\n  text-align: left;\n  text-align: start;\n  text-decoration: none;\n  text-shadow: none;\n  text-transform: none;\n  letter-spacing: normal;\n  word-break: normal;\n  white-space: normal;\n  word-spacing: normal;\n  line-break: auto;\n  font-size: var(--bs-tooltip-font-size);\n  word-wrap: break-word;\n  opacity: 0;\n}\n.tooltip.show {\n  opacity: var(--bs-tooltip-opacity);\n}\n.tooltip .tooltip-arrow {\n  display: block;\n  width: var(--bs-tooltip-arrow-width);\n  height: var(--bs-tooltip-arrow-height);\n}\n.tooltip .tooltip-arrow::before {\n  position: absolute;\n  content: \"\";\n  border-color: transparent;\n  border-style: solid;\n}\n\n.bs-tooltip-top .tooltip-arrow, .bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow {\n  bottom: 0;\n}\n.bs-tooltip-top .tooltip-arrow::before, .bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow::before {\n  top: -1px;\n  border-width: var(--bs-tooltip-arrow-height) calc(var(--bs-tooltip-arrow-width) * 0.5) 0;\n  border-top-color: var(--bs-tooltip-bg);\n}\n\n/* rtl:begin:ignore */\n.bs-tooltip-end .tooltip-arrow, .bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow {\n  left: 0;\n  width: var(--bs-tooltip-arrow-height);\n  height: var(--bs-tooltip-arrow-width);\n}\n.bs-tooltip-end .tooltip-arrow::before, .bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow::before {\n  right: -1px;\n  border-width: calc(var(--bs-tooltip-arrow-width) * 0.5) var(--bs-tooltip-arrow-height) calc(var(--bs-tooltip-arrow-width) * 0.5) 0;\n  border-right-color: var(--bs-tooltip-bg);\n}\n\n/* rtl:end:ignore */\n.bs-tooltip-bottom .tooltip-arrow, .bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow {\n  top: 0;\n}\n.bs-tooltip-bottom .tooltip-arrow::before, .bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow::before {\n  bottom: -1px;\n  border-width: 0 calc(var(--bs-tooltip-arrow-width) * 0.5) var(--bs-tooltip-arrow-height);\n  border-bottom-color: var(--bs-tooltip-bg);\n}\n\n/* rtl:begin:ignore */\n.bs-tooltip-start .tooltip-arrow, .bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow {\n  right: 0;\n  width: var(--bs-tooltip-arrow-height);\n  height: var(--bs-tooltip-arrow-width);\n}\n.bs-tooltip-start .tooltip-arrow::before, .bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow::before {\n  left: -1px;\n  border-width: calc(var(--bs-tooltip-arrow-width) * 0.5) 0 calc(var(--bs-tooltip-arrow-width) * 0.5) var(--bs-tooltip-arrow-height);\n  border-left-color: var(--bs-tooltip-bg);\n}\n\n/* rtl:end:ignore */\n.tooltip-inner {\n  max-width: var(--bs-tooltip-max-width);\n  padding: var(--bs-tooltip-padding-y) var(--bs-tooltip-padding-x);\n  color: var(--bs-tooltip-color);\n  text-align: center;\n  background-color: var(--bs-tooltip-bg);\n  border-radius: var(--bs-tooltip-border-radius);\n}\n\n.popover {\n  --bs-popover-zindex: 1070;\n  --bs-popover-max-width: 276px;\n  --bs-popover-font-size: 0.875rem;\n  --bs-popover-bg: #fff;\n  --bs-popover-border-width: 0.125rem;\n  --bs-popover-border-color: var(--bs-border-color-translucent);\n  --bs-popover-border-radius: 0.75rem;\n  --bs-popover-inner-border-radius: 0.625rem;\n  --bs-popover-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);\n  --bs-popover-header-padding-x: 1rem;\n  --bs-popover-header-padding-y: 0.5rem;\n  --bs-popover-header-font-size: 1rem;\n  --bs-popover-header-color: ;\n  --bs-popover-header-bg: #f0f0f0;\n  --bs-popover-body-padding-x: 1rem;\n  --bs-popover-body-padding-y: 1rem;\n  --bs-popover-body-color: #212529;\n  --bs-popover-arrow-width: 1rem;\n  --bs-popover-arrow-height: 0.5rem;\n  --bs-popover-arrow-border: var(--bs-popover-border-color);\n  z-index: var(--bs-popover-zindex);\n  display: block;\n  max-width: var(--bs-popover-max-width);\n  font-family: var(--bs-font-sans-serif);\n  font-style: normal;\n  font-weight: 400;\n  line-height: 1.5;\n  text-align: left;\n  text-align: start;\n  text-decoration: none;\n  text-shadow: none;\n  text-transform: none;\n  letter-spacing: normal;\n  word-break: normal;\n  white-space: normal;\n  word-spacing: normal;\n  line-break: auto;\n  font-size: var(--bs-popover-font-size);\n  word-wrap: break-word;\n  background-color: var(--bs-popover-bg);\n  background-clip: padding-box;\n  border: var(--bs-popover-border-width) solid var(--bs-popover-border-color);\n  border-radius: var(--bs-popover-border-radius);\n}\n.popover .popover-arrow {\n  display: block;\n  width: var(--bs-popover-arrow-width);\n  height: var(--bs-popover-arrow-height);\n}\n.popover .popover-arrow::before, .popover .popover-arrow::after {\n  position: absolute;\n  display: block;\n  content: \"\";\n  border-color: transparent;\n  border-style: solid;\n  border-width: 0;\n}\n\n.bs-popover-top > .popover-arrow, .bs-popover-auto[data-popper-placement^=top] > .popover-arrow {\n  bottom: calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width));\n}\n.bs-popover-top > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=top] > .popover-arrow::before, .bs-popover-top > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=top] > .popover-arrow::after {\n  border-width: var(--bs-popover-arrow-height) calc(var(--bs-popover-arrow-width) * 0.5) 0;\n}\n.bs-popover-top > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=top] > .popover-arrow::before {\n  bottom: 0;\n  border-top-color: var(--bs-popover-arrow-border);\n}\n.bs-popover-top > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=top] > .popover-arrow::after {\n  bottom: var(--bs-popover-border-width);\n  border-top-color: var(--bs-popover-bg);\n}\n\n/* rtl:begin:ignore */\n.bs-popover-end > .popover-arrow, .bs-popover-auto[data-popper-placement^=right] > .popover-arrow {\n  left: calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width));\n  width: var(--bs-popover-arrow-height);\n  height: var(--bs-popover-arrow-width);\n}\n.bs-popover-end > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=right] > .popover-arrow::before, .bs-popover-end > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=right] > .popover-arrow::after {\n  border-width: calc(var(--bs-popover-arrow-width) * 0.5) var(--bs-popover-arrow-height) calc(var(--bs-popover-arrow-width) * 0.5) 0;\n}\n.bs-popover-end > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=right] > .popover-arrow::before {\n  left: 0;\n  border-right-color: var(--bs-popover-arrow-border);\n}\n.bs-popover-end > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=right] > .popover-arrow::after {\n  left: var(--bs-popover-border-width);\n  border-right-color: var(--bs-popover-bg);\n}\n\n/* rtl:end:ignore */\n.bs-popover-bottom > .popover-arrow, .bs-popover-auto[data-popper-placement^=bottom] > .popover-arrow {\n  top: calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width));\n}\n.bs-popover-bottom > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=bottom] > .popover-arrow::before, .bs-popover-bottom > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=bottom] > .popover-arrow::after {\n  border-width: 0 calc(var(--bs-popover-arrow-width) * 0.5) var(--bs-popover-arrow-height);\n}\n.bs-popover-bottom > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=bottom] > .popover-arrow::before {\n  top: 0;\n  border-bottom-color: var(--bs-popover-arrow-border);\n}\n.bs-popover-bottom > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=bottom] > .popover-arrow::after {\n  top: var(--bs-popover-border-width);\n  border-bottom-color: var(--bs-popover-bg);\n}\n.bs-popover-bottom .popover-header::before, .bs-popover-auto[data-popper-placement^=bottom] .popover-header::before {\n  position: absolute;\n  top: 0;\n  left: 50%;\n  display: block;\n  width: var(--bs-popover-arrow-width);\n  margin-left: calc(-0.5 * var(--bs-popover-arrow-width));\n  content: \"\";\n  border-bottom: var(--bs-popover-border-width) solid var(--bs-popover-header-bg);\n}\n\n/* rtl:begin:ignore */\n.bs-popover-start > .popover-arrow, .bs-popover-auto[data-popper-placement^=left] > .popover-arrow {\n  right: calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width));\n  width: var(--bs-popover-arrow-height);\n  height: var(--bs-popover-arrow-width);\n}\n.bs-popover-start > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=left] > .popover-arrow::before, .bs-popover-start > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=left] > .popover-arrow::after {\n  border-width: calc(var(--bs-popover-arrow-width) * 0.5) 0 calc(var(--bs-popover-arrow-width) * 0.5) var(--bs-popover-arrow-height);\n}\n.bs-popover-start > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=left] > .popover-arrow::before {\n  right: 0;\n  border-left-color: var(--bs-popover-arrow-border);\n}\n.bs-popover-start > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=left] > .popover-arrow::after {\n  right: var(--bs-popover-border-width);\n  border-left-color: var(--bs-popover-bg);\n}\n\n/* rtl:end:ignore */\n.popover-header {\n  padding: var(--bs-popover-header-padding-y) var(--bs-popover-header-padding-x);\n  margin-bottom: 0;\n  font-size: var(--bs-popover-header-font-size);\n  color: var(--bs-popover-header-color);\n  background-color: var(--bs-popover-header-bg);\n  border-bottom: var(--bs-popover-border-width) solid var(--bs-popover-border-color);\n  border-top-left-radius: var(--bs-popover-inner-border-radius);\n  border-top-right-radius: var(--bs-popover-inner-border-radius);\n}\n.popover-header:empty {\n  display: none;\n}\n\n.popover-body {\n  padding: var(--bs-popover-body-padding-y) var(--bs-popover-body-padding-x);\n  color: var(--bs-popover-body-color);\n}\n\n.carousel {\n  position: relative;\n}\n\n.carousel.pointer-event {\n  touch-action: pan-y;\n}\n\n.carousel-inner {\n  position: relative;\n  width: 100%;\n  overflow: hidden;\n}\n.carousel-inner::after {\n  display: block;\n  clear: both;\n  content: \"\";\n}\n\n.carousel-item {\n  position: relative;\n  display: none;\n  float: left;\n  width: 100%;\n  margin-right: -100%;\n  -webkit-backface-visibility: hidden;\n          backface-visibility: hidden;\n  transition: transform 0.6s ease-in-out;\n}\n@media (prefers-reduced-motion: reduce) {\n  .carousel-item {\n    transition: none;\n  }\n}\n\n.carousel-item.active,\n.carousel-item-next,\n.carousel-item-prev {\n  display: block;\n}\n\n.carousel-item-next:not(.carousel-item-start),\n.active.carousel-item-end {\n  transform: translateX(100%);\n}\n\n.carousel-item-prev:not(.carousel-item-end),\n.active.carousel-item-start {\n  transform: translateX(-100%);\n}\n\n.carousel-fade .carousel-item {\n  opacity: 0;\n  transition-property: opacity;\n  transform: none;\n}\n.carousel-fade .carousel-item.active,\n.carousel-fade .carousel-item-next.carousel-item-start,\n.carousel-fade .carousel-item-prev.carousel-item-end {\n  z-index: 1;\n  opacity: 1;\n}\n.carousel-fade .active.carousel-item-start,\n.carousel-fade .active.carousel-item-end {\n  z-index: 0;\n  opacity: 0;\n  transition: opacity 0s 0.6s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .carousel-fade .active.carousel-item-start,\n  .carousel-fade .active.carousel-item-end {\n    transition: none;\n  }\n}\n\n.carousel-control-prev,\n.carousel-control-next {\n  position: absolute;\n  top: 0;\n  bottom: 0;\n  z-index: 1;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  width: 15%;\n  padding: 0;\n  color: #fff;\n  text-align: center;\n  background: none;\n  border: 0;\n  opacity: 0.5;\n  transition: opacity 0.15s ease;\n}\n@media (prefers-reduced-motion: reduce) {\n  .carousel-control-prev,\n  .carousel-control-next {\n    transition: none;\n  }\n}\n.carousel-control-prev:hover, .carousel-control-prev:focus,\n.carousel-control-next:hover,\n.carousel-control-next:focus {\n  color: #fff;\n  text-decoration: none;\n  outline: 0;\n  opacity: 0.9;\n}\n\n.carousel-control-prev {\n  left: 0;\n}\n\n.carousel-control-next {\n  right: 0;\n}\n\n.carousel-control-prev-icon,\n.carousel-control-next-icon {\n  display: inline-block;\n  width: 2rem;\n  height: 2rem;\n  background-repeat: no-repeat;\n  background-position: 50%;\n  background-size: 100% 100%;\n}\n\n/* rtl:options: {\n  \"autoRename\": true,\n  \"stringMap\":[ {\n    \"name\"    : \"prev-next\",\n    \"search\"  : \"prev\",\n    \"replace\" : \"next\"\n  } ]\n} */\n.carousel-control-prev-icon {\n  background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z'/%3e%3c/svg%3e\");\n}\n\n.carousel-control-next-icon {\n  background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e\");\n}\n\n.carousel-indicators {\n  position: absolute;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  z-index: 2;\n  display: flex;\n  justify-content: center;\n  padding: 0;\n  margin-right: 15%;\n  margin-bottom: 1rem;\n  margin-left: 15%;\n  list-style: none;\n}\n.carousel-indicators [data-bs-target] {\n  box-sizing: content-box;\n  flex: 0 1 auto;\n  width: 30px;\n  height: 3px;\n  padding: 0;\n  margin-right: 3px;\n  margin-left: 3px;\n  text-indent: -999px;\n  cursor: pointer;\n  background-color: #fff;\n  background-clip: padding-box;\n  border: 0;\n  border-top: 10px solid transparent;\n  border-bottom: 10px solid transparent;\n  opacity: 0.5;\n  transition: opacity 0.6s ease;\n}\n@media (prefers-reduced-motion: reduce) {\n  .carousel-indicators [data-bs-target] {\n    transition: none;\n  }\n}\n.carousel-indicators .active {\n  opacity: 1;\n}\n\n.carousel-caption {\n  position: absolute;\n  right: 15%;\n  bottom: 1.25rem;\n  left: 15%;\n  padding-top: 1.25rem;\n  padding-bottom: 1.25rem;\n  color: #fff;\n  text-align: center;\n}\n\n.carousel-dark .carousel-control-prev-icon,\n.carousel-dark .carousel-control-next-icon {\n  filter: invert(1) grayscale(100);\n}\n.carousel-dark .carousel-indicators [data-bs-target] {\n  background-color: #000;\n}\n.carousel-dark .carousel-caption {\n  color: #000;\n}\n\n.spinner-grow,\n.spinner-border {\n  display: inline-block;\n  width: var(--bs-spinner-width);\n  height: var(--bs-spinner-height);\n  vertical-align: var(--bs-spinner-vertical-align);\n  border-radius: 50%;\n  animation: var(--bs-spinner-animation-speed) linear infinite var(--bs-spinner-animation-name);\n}\n\n@keyframes spinner-border {\n  to {\n    transform: rotate(360deg) /* rtl:ignore */;\n  }\n}\n.spinner-border {\n  --bs-spinner-width: 2rem;\n  --bs-spinner-height: 2rem;\n  --bs-spinner-vertical-align: -0.125em;\n  --bs-spinner-border-width: 0.25em;\n  --bs-spinner-animation-speed: 0.75s;\n  --bs-spinner-animation-name: spinner-border;\n  border: var(--bs-spinner-border-width) solid currentcolor;\n  border-right-color: transparent;\n}\n\n.spinner-border-sm {\n  --bs-spinner-width: 1rem;\n  --bs-spinner-height: 1rem;\n  --bs-spinner-border-width: 0.2em;\n}\n\n@keyframes spinner-grow {\n  0% {\n    transform: scale(0);\n  }\n  50% {\n    opacity: 1;\n    transform: none;\n  }\n}\n.spinner-grow {\n  --bs-spinner-width: 2rem;\n  --bs-spinner-height: 2rem;\n  --bs-spinner-vertical-align: -0.125em;\n  --bs-spinner-animation-speed: 0.75s;\n  --bs-spinner-animation-name: spinner-grow;\n  background-color: currentcolor;\n  opacity: 0;\n}\n\n.spinner-grow-sm {\n  --bs-spinner-width: 1rem;\n  --bs-spinner-height: 1rem;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .spinner-border,\n  .spinner-grow {\n    --bs-spinner-animation-speed: 1.5s;\n  }\n}\n.offcanvas, .offcanvas-xxl, .offcanvas-xl, .offcanvas-lg, .offcanvas-md, .offcanvas-sm {\n  --bs-offcanvas-zindex: 1045;\n  --bs-offcanvas-width: 400px;\n  --bs-offcanvas-height: 30vh;\n  --bs-offcanvas-padding-x: 1rem;\n  --bs-offcanvas-padding-y: 1rem;\n  --bs-offcanvas-color: ;\n  --bs-offcanvas-bg: #fff;\n  --bs-offcanvas-border-width: 0.125rem;\n  --bs-offcanvas-border-color: var(--bs-border-color-translucent);\n  --bs-offcanvas-box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);\n}\n\n@media (max-width: 575.98px) {\n  .offcanvas-sm {\n    position: fixed;\n    bottom: 0;\n    z-index: var(--bs-offcanvas-zindex);\n    display: flex;\n    flex-direction: column;\n    max-width: 100%;\n    color: var(--bs-offcanvas-color);\n    visibility: hidden;\n    background-color: var(--bs-offcanvas-bg);\n    background-clip: padding-box;\n    outline: 0;\n    transition: transform 0.3s ease-in-out;\n  }\n}\n@media (max-width: 575.98px) and (prefers-reduced-motion: reduce) {\n  .offcanvas-sm {\n    transition: none;\n  }\n}\n@media (max-width: 575.98px) {\n  .offcanvas-sm.offcanvas-start {\n    top: 0;\n    left: 0;\n    width: var(--bs-offcanvas-width);\n    border-right: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n    transform: translateX(-100%);\n  }\n}\n@media (max-width: 575.98px) {\n  .offcanvas-sm.offcanvas-end {\n    top: 0;\n    right: 0;\n    width: var(--bs-offcanvas-width);\n    border-left: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n    transform: translateX(100%);\n  }\n}\n@media (max-width: 575.98px) {\n  .offcanvas-sm.offcanvas-top {\n    top: 0;\n    right: 0;\n    left: 0;\n    height: var(--bs-offcanvas-height);\n    max-height: 100%;\n    border-bottom: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n    transform: translateY(-100%);\n  }\n}\n@media (max-width: 575.98px) {\n  .offcanvas-sm.offcanvas-bottom {\n    right: 0;\n    left: 0;\n    height: var(--bs-offcanvas-height);\n    max-height: 100%;\n    border-top: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n    transform: translateY(100%);\n  }\n}\n@media (max-width: 575.98px) {\n  .offcanvas-sm.showing, .offcanvas-sm.show:not(.hiding) {\n    transform: none;\n  }\n}\n@media (max-width: 575.98px) {\n  .offcanvas-sm.showing, .offcanvas-sm.hiding, .offcanvas-sm.show {\n    visibility: visible;\n  }\n}\n@media (min-width: 576px) {\n  .offcanvas-sm {\n    --bs-offcanvas-height: auto;\n    --bs-offcanvas-border-width: 0;\n    background-color: transparent !important;\n  }\n  .offcanvas-sm .offcanvas-header {\n    display: none;\n  }\n  .offcanvas-sm .offcanvas-body {\n    display: flex;\n    flex-grow: 0;\n    padding: 0;\n    overflow-y: visible;\n    background-color: transparent !important;\n  }\n}\n\n@media (max-width: 767.98px) {\n  .offcanvas-md {\n    position: fixed;\n    bottom: 0;\n    z-index: var(--bs-offcanvas-zindex);\n    display: flex;\n    flex-direction: column;\n    max-width: 100%;\n    color: var(--bs-offcanvas-color);\n    visibility: hidden;\n    background-color: var(--bs-offcanvas-bg);\n    background-clip: padding-box;\n    outline: 0;\n    transition: transform 0.3s ease-in-out;\n  }\n}\n@media (max-width: 767.98px) and (prefers-reduced-motion: reduce) {\n  .offcanvas-md {\n    transition: none;\n  }\n}\n@media (max-width: 767.98px) {\n  .offcanvas-md.offcanvas-start {\n    top: 0;\n    left: 0;\n    width: var(--bs-offcanvas-width);\n    border-right: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n    transform: translateX(-100%);\n  }\n}\n@media (max-width: 767.98px) {\n  .offcanvas-md.offcanvas-end {\n    top: 0;\n    right: 0;\n    width: var(--bs-offcanvas-width);\n    border-left: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n    transform: translateX(100%);\n  }\n}\n@media (max-width: 767.98px) {\n  .offcanvas-md.offcanvas-top {\n    top: 0;\n    right: 0;\n    left: 0;\n    height: var(--bs-offcanvas-height);\n    max-height: 100%;\n    border-bottom: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n    transform: translateY(-100%);\n  }\n}\n@media (max-width: 767.98px) {\n  .offcanvas-md.offcanvas-bottom {\n    right: 0;\n    left: 0;\n    height: var(--bs-offcanvas-height);\n    max-height: 100%;\n    border-top: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n    transform: translateY(100%);\n  }\n}\n@media (max-width: 767.98px) {\n  .offcanvas-md.showing, .offcanvas-md.show:not(.hiding) {\n    transform: none;\n  }\n}\n@media (max-width: 767.98px) {\n  .offcanvas-md.showing, .offcanvas-md.hiding, .offcanvas-md.show {\n    visibility: visible;\n  }\n}\n@media (min-width: 768px) {\n  .offcanvas-md {\n    --bs-offcanvas-height: auto;\n    --bs-offcanvas-border-width: 0;\n    background-color: transparent !important;\n  }\n  .offcanvas-md .offcanvas-header {\n    display: none;\n  }\n  .offcanvas-md .offcanvas-body {\n    display: flex;\n    flex-grow: 0;\n    padding: 0;\n    overflow-y: visible;\n    background-color: transparent !important;\n  }\n}\n\n@media (max-width: 991.98px) {\n  .offcanvas-lg {\n    position: fixed;\n    bottom: 0;\n    z-index: var(--bs-offcanvas-zindex);\n    display: flex;\n    flex-direction: column;\n    max-width: 100%;\n    color: var(--bs-offcanvas-color);\n    visibility: hidden;\n    background-color: var(--bs-offcanvas-bg);\n    background-clip: padding-box;\n    outline: 0;\n    transition: transform 0.3s ease-in-out;\n  }\n}\n@media (max-width: 991.98px) and (prefers-reduced-motion: reduce) {\n  .offcanvas-lg {\n    transition: none;\n  }\n}\n@media (max-width: 991.98px) {\n  .offcanvas-lg.offcanvas-start {\n    top: 0;\n    left: 0;\n    width: var(--bs-offcanvas-width);\n    border-right: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n    transform: translateX(-100%);\n  }\n}\n@media (max-width: 991.98px) {\n  .offcanvas-lg.offcanvas-end {\n    top: 0;\n    right: 0;\n    width: var(--bs-offcanvas-width);\n    border-left: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n    transform: translateX(100%);\n  }\n}\n@media (max-width: 991.98px) {\n  .offcanvas-lg.offcanvas-top {\n    top: 0;\n    right: 0;\n    left: 0;\n    height: var(--bs-offcanvas-height);\n    max-height: 100%;\n    border-bottom: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n    transform: translateY(-100%);\n  }\n}\n@media (max-width: 991.98px) {\n  .offcanvas-lg.offcanvas-bottom {\n    right: 0;\n    left: 0;\n    height: var(--bs-offcanvas-height);\n    max-height: 100%;\n    border-top: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n    transform: translateY(100%);\n  }\n}\n@media (max-width: 991.98px) {\n  .offcanvas-lg.showing, .offcanvas-lg.show:not(.hiding) {\n    transform: none;\n  }\n}\n@media (max-width: 991.98px) {\n  .offcanvas-lg.showing, .offcanvas-lg.hiding, .offcanvas-lg.show {\n    visibility: visible;\n  }\n}\n@media (min-width: 992px) {\n  .offcanvas-lg {\n    --bs-offcanvas-height: auto;\n    --bs-offcanvas-border-width: 0;\n    background-color: transparent !important;\n  }\n  .offcanvas-lg .offcanvas-header {\n    display: none;\n  }\n  .offcanvas-lg .offcanvas-body {\n    display: flex;\n    flex-grow: 0;\n    padding: 0;\n    overflow-y: visible;\n    background-color: transparent !important;\n  }\n}\n\n@media (max-width: 1199.98px) {\n  .offcanvas-xl {\n    position: fixed;\n    bottom: 0;\n    z-index: var(--bs-offcanvas-zindex);\n    display: flex;\n    flex-direction: column;\n    max-width: 100%;\n    color: var(--bs-offcanvas-color);\n    visibility: hidden;\n    background-color: var(--bs-offcanvas-bg);\n    background-clip: padding-box;\n    outline: 0;\n    transition: transform 0.3s ease-in-out;\n  }\n}\n@media (max-width: 1199.98px) and (prefers-reduced-motion: reduce) {\n  .offcanvas-xl {\n    transition: none;\n  }\n}\n@media (max-width: 1199.98px) {\n  .offcanvas-xl.offcanvas-start {\n    top: 0;\n    left: 0;\n    width: var(--bs-offcanvas-width);\n    border-right: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n    transform: translateX(-100%);\n  }\n}\n@media (max-width: 1199.98px) {\n  .offcanvas-xl.offcanvas-end {\n    top: 0;\n    right: 0;\n    width: var(--bs-offcanvas-width);\n    border-left: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n    transform: translateX(100%);\n  }\n}\n@media (max-width: 1199.98px) {\n  .offcanvas-xl.offcanvas-top {\n    top: 0;\n    right: 0;\n    left: 0;\n    height: var(--bs-offcanvas-height);\n    max-height: 100%;\n    border-bottom: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n    transform: translateY(-100%);\n  }\n}\n@media (max-width: 1199.98px) {\n  .offcanvas-xl.offcanvas-bottom {\n    right: 0;\n    left: 0;\n    height: var(--bs-offcanvas-height);\n    max-height: 100%;\n    border-top: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n    transform: translateY(100%);\n  }\n}\n@media (max-width: 1199.98px) {\n  .offcanvas-xl.showing, .offcanvas-xl.show:not(.hiding) {\n    transform: none;\n  }\n}\n@media (max-width: 1199.98px) {\n  .offcanvas-xl.showing, .offcanvas-xl.hiding, .offcanvas-xl.show {\n    visibility: visible;\n  }\n}\n@media (min-width: 1200px) {\n  .offcanvas-xl {\n    --bs-offcanvas-height: auto;\n    --bs-offcanvas-border-width: 0;\n    background-color: transparent !important;\n  }\n  .offcanvas-xl .offcanvas-header {\n    display: none;\n  }\n  .offcanvas-xl .offcanvas-body {\n    display: flex;\n    flex-grow: 0;\n    padding: 0;\n    overflow-y: visible;\n    background-color: transparent !important;\n  }\n}\n\n@media (max-width: 1399.98px) {\n  .offcanvas-xxl {\n    position: fixed;\n    bottom: 0;\n    z-index: var(--bs-offcanvas-zindex);\n    display: flex;\n    flex-direction: column;\n    max-width: 100%;\n    color: var(--bs-offcanvas-color);\n    visibility: hidden;\n    background-color: var(--bs-offcanvas-bg);\n    background-clip: padding-box;\n    outline: 0;\n    transition: transform 0.3s ease-in-out;\n  }\n}\n@media (max-width: 1399.98px) and (prefers-reduced-motion: reduce) {\n  .offcanvas-xxl {\n    transition: none;\n  }\n}\n@media (max-width: 1399.98px) {\n  .offcanvas-xxl.offcanvas-start {\n    top: 0;\n    left: 0;\n    width: var(--bs-offcanvas-width);\n    border-right: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n    transform: translateX(-100%);\n  }\n}\n@media (max-width: 1399.98px) {\n  .offcanvas-xxl.offcanvas-end {\n    top: 0;\n    right: 0;\n    width: var(--bs-offcanvas-width);\n    border-left: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n    transform: translateX(100%);\n  }\n}\n@media (max-width: 1399.98px) {\n  .offcanvas-xxl.offcanvas-top {\n    top: 0;\n    right: 0;\n    left: 0;\n    height: var(--bs-offcanvas-height);\n    max-height: 100%;\n    border-bottom: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n    transform: translateY(-100%);\n  }\n}\n@media (max-width: 1399.98px) {\n  .offcanvas-xxl.offcanvas-bottom {\n    right: 0;\n    left: 0;\n    height: var(--bs-offcanvas-height);\n    max-height: 100%;\n    border-top: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n    transform: translateY(100%);\n  }\n}\n@media (max-width: 1399.98px) {\n  .offcanvas-xxl.showing, .offcanvas-xxl.show:not(.hiding) {\n    transform: none;\n  }\n}\n@media (max-width: 1399.98px) {\n  .offcanvas-xxl.showing, .offcanvas-xxl.hiding, .offcanvas-xxl.show {\n    visibility: visible;\n  }\n}\n@media (min-width: 1400px) {\n  .offcanvas-xxl {\n    --bs-offcanvas-height: auto;\n    --bs-offcanvas-border-width: 0;\n    background-color: transparent !important;\n  }\n  .offcanvas-xxl .offcanvas-header {\n    display: none;\n  }\n  .offcanvas-xxl .offcanvas-body {\n    display: flex;\n    flex-grow: 0;\n    padding: 0;\n    overflow-y: visible;\n    background-color: transparent !important;\n  }\n}\n\n.offcanvas {\n  position: fixed;\n  bottom: 0;\n  z-index: var(--bs-offcanvas-zindex);\n  display: flex;\n  flex-direction: column;\n  max-width: 100%;\n  color: var(--bs-offcanvas-color);\n  visibility: hidden;\n  background-color: var(--bs-offcanvas-bg);\n  background-clip: padding-box;\n  outline: 0;\n  transition: transform 0.3s ease-in-out;\n}\n@media (prefers-reduced-motion: reduce) {\n  .offcanvas {\n    transition: none;\n  }\n}\n.offcanvas.offcanvas-start {\n  top: 0;\n  left: 0;\n  width: var(--bs-offcanvas-width);\n  border-right: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n  transform: translateX(-100%);\n}\n.offcanvas.offcanvas-end {\n  top: 0;\n  right: 0;\n  width: var(--bs-offcanvas-width);\n  border-left: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n  transform: translateX(100%);\n}\n.offcanvas.offcanvas-top {\n  top: 0;\n  right: 0;\n  left: 0;\n  height: var(--bs-offcanvas-height);\n  max-height: 100%;\n  border-bottom: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n  transform: translateY(-100%);\n}\n.offcanvas.offcanvas-bottom {\n  right: 0;\n  left: 0;\n  height: var(--bs-offcanvas-height);\n  max-height: 100%;\n  border-top: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n  transform: translateY(100%);\n}\n.offcanvas.showing, .offcanvas.show:not(.hiding) {\n  transform: none;\n}\n.offcanvas.showing, .offcanvas.hiding, .offcanvas.show {\n  visibility: visible;\n}\n\n.offcanvas-backdrop {\n  position: fixed;\n  top: 0;\n  left: 0;\n  z-index: 1040;\n  width: 100vw;\n  height: 100vh;\n  background-color: #000;\n}\n.offcanvas-backdrop.fade {\n  opacity: 0;\n}\n.offcanvas-backdrop.show {\n  opacity: 0.5;\n}\n\n.offcanvas-header {\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  padding: var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x);\n}\n.offcanvas-header .btn-close {\n  padding: calc(var(--bs-offcanvas-padding-y) * 0.5) calc(var(--bs-offcanvas-padding-x) * 0.5);\n  margin-top: calc(-0.5 * var(--bs-offcanvas-padding-y));\n  margin-right: calc(-0.5 * var(--bs-offcanvas-padding-x));\n  margin-bottom: calc(-0.5 * var(--bs-offcanvas-padding-y));\n}\n\n.offcanvas-title {\n  margin-bottom: 0;\n  line-height: 1.5;\n}\n\n.offcanvas-body {\n  flex-grow: 1;\n  padding: var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x);\n  overflow-y: auto;\n}\n\n.placeholder {\n  display: inline-block;\n  min-height: 1em;\n  vertical-align: middle;\n  cursor: wait;\n  background-color: currentcolor;\n  opacity: 0.5;\n}\n.placeholder.btn::before {\n  display: inline-block;\n  content: \"\";\n}\n\n.placeholder-xs {\n  min-height: 0.6em;\n}\n\n.placeholder-sm {\n  min-height: 0.8em;\n}\n\n.placeholder-lg {\n  min-height: 1.2em;\n}\n\n.placeholder-glow .placeholder {\n  animation: placeholder-glow 2s ease-in-out infinite;\n}\n\n@keyframes placeholder-glow {\n  50% {\n    opacity: 0.2;\n  }\n}\n.placeholder-wave {\n  -webkit-mask-image: linear-gradient(130deg, #000 55%, rgba(0, 0, 0, 0.8) 75%, #000 95%);\n          mask-image: linear-gradient(130deg, #000 55%, rgba(0, 0, 0, 0.8) 75%, #000 95%);\n  -webkit-mask-size: 200% 100%;\n          mask-size: 200% 100%;\n  animation: placeholder-wave 2s linear infinite;\n}\n\n@keyframes placeholder-wave {\n  100% {\n    -webkit-mask-position: -200% 0%;\n            mask-position: -200% 0%;\n  }\n}\n.clearfix::after {\n  display: block;\n  clear: both;\n  content: \"\";\n}\n\n.text-bg-primary {\n  color: #fff !important;\n  background-color: RGBA(26, 188, 156, var(--bs-bg-opacity, 1)) !important;\n}\n\n.text-bg-secondary {\n  color: #fff !important;\n  background-color: RGBA(44, 62, 80, var(--bs-bg-opacity, 1)) !important;\n}\n\n.text-bg-success {\n  color: #fff !important;\n  background-color: RGBA(25, 135, 84, var(--bs-bg-opacity, 1)) !important;\n}\n\n.text-bg-info {\n  color: #000 !important;\n  background-color: RGBA(13, 202, 240, var(--bs-bg-opacity, 1)) !important;\n}\n\n.text-bg-warning {\n  color: #000 !important;\n  background-color: RGBA(255, 193, 7, var(--bs-bg-opacity, 1)) !important;\n}\n\n.text-bg-danger {\n  color: #fff !important;\n  background-color: RGBA(220, 53, 69, var(--bs-bg-opacity, 1)) !important;\n}\n\n.text-bg-light {\n  color: #000 !important;\n  background-color: RGBA(248, 249, 250, var(--bs-bg-opacity, 1)) !important;\n}\n\n.text-bg-dark {\n  color: #fff !important;\n  background-color: RGBA(33, 37, 41, var(--bs-bg-opacity, 1)) !important;\n}\n\n.link-primary {\n  color: #1abc9c !important;\n}\n.link-primary:hover, .link-primary:focus {\n  color: #15967d !important;\n}\n\n.link-secondary {\n  color: #2c3e50 !important;\n}\n.link-secondary:hover, .link-secondary:focus {\n  color: #233240 !important;\n}\n\n.link-success {\n  color: #198754 !important;\n}\n.link-success:hover, .link-success:focus {\n  color: #146c43 !important;\n}\n\n.link-info {\n  color: #0dcaf0 !important;\n}\n.link-info:hover, .link-info:focus {\n  color: #3dd5f3 !important;\n}\n\n.link-warning {\n  color: #ffc107 !important;\n}\n.link-warning:hover, .link-warning:focus {\n  color: #ffcd39 !important;\n}\n\n.link-danger {\n  color: #dc3545 !important;\n}\n.link-danger:hover, .link-danger:focus {\n  color: #b02a37 !important;\n}\n\n.link-light {\n  color: #f8f9fa !important;\n}\n.link-light:hover, .link-light:focus {\n  color: #f9fafb !important;\n}\n\n.link-dark {\n  color: #212529 !important;\n}\n.link-dark:hover, .link-dark:focus {\n  color: #1a1e21 !important;\n}\n\n.ratio {\n  position: relative;\n  width: 100%;\n}\n.ratio::before {\n  display: block;\n  padding-top: var(--bs-aspect-ratio);\n  content: \"\";\n}\n.ratio > * {\n  position: absolute;\n  top: 0;\n  left: 0;\n  width: 100%;\n  height: 100%;\n}\n\n.ratio-1x1 {\n  --bs-aspect-ratio: 100%;\n}\n\n.ratio-4x3 {\n  --bs-aspect-ratio: 75%;\n}\n\n.ratio-16x9 {\n  --bs-aspect-ratio: 56.25%;\n}\n\n.ratio-21x9 {\n  --bs-aspect-ratio: 42.8571428571%;\n}\n\n.fixed-top {\n  position: fixed;\n  top: 0;\n  right: 0;\n  left: 0;\n  z-index: 1030;\n}\n\n.fixed-bottom {\n  position: fixed;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  z-index: 1030;\n}\n\n.sticky-top {\n  position: sticky;\n  top: 0;\n  z-index: 1020;\n}\n\n.sticky-bottom {\n  position: sticky;\n  bottom: 0;\n  z-index: 1020;\n}\n\n@media (min-width: 576px) {\n  .sticky-sm-top {\n    position: sticky;\n    top: 0;\n    z-index: 1020;\n  }\n  .sticky-sm-bottom {\n    position: sticky;\n    bottom: 0;\n    z-index: 1020;\n  }\n}\n@media (min-width: 768px) {\n  .sticky-md-top {\n    position: sticky;\n    top: 0;\n    z-index: 1020;\n  }\n  .sticky-md-bottom {\n    position: sticky;\n    bottom: 0;\n    z-index: 1020;\n  }\n}\n@media (min-width: 992px) {\n  .sticky-lg-top {\n    position: sticky;\n    top: 0;\n    z-index: 1020;\n  }\n  .sticky-lg-bottom {\n    position: sticky;\n    bottom: 0;\n    z-index: 1020;\n  }\n}\n@media (min-width: 1200px) {\n  .sticky-xl-top {\n    position: sticky;\n    top: 0;\n    z-index: 1020;\n  }\n  .sticky-xl-bottom {\n    position: sticky;\n    bottom: 0;\n    z-index: 1020;\n  }\n}\n@media (min-width: 1400px) {\n  .sticky-xxl-top {\n    position: sticky;\n    top: 0;\n    z-index: 1020;\n  }\n  .sticky-xxl-bottom {\n    position: sticky;\n    bottom: 0;\n    z-index: 1020;\n  }\n}\n.hstack {\n  display: flex;\n  flex-direction: row;\n  align-items: center;\n  align-self: stretch;\n}\n\n.vstack {\n  display: flex;\n  flex: 1 1 auto;\n  flex-direction: column;\n  align-self: stretch;\n}\n\n.visually-hidden,\n.visually-hidden-focusable:not(:focus):not(:focus-within) {\n  position: absolute !important;\n  width: 1px !important;\n  height: 1px !important;\n  padding: 0 !important;\n  margin: -1px !important;\n  overflow: hidden !important;\n  clip: rect(0, 0, 0, 0) !important;\n  white-space: nowrap !important;\n  border: 0 !important;\n}\n\n.stretched-link::after {\n  position: absolute;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  z-index: 1;\n  content: \"\";\n}\n\n.text-truncate {\n  overflow: hidden;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.vr {\n  display: inline-block;\n  align-self: stretch;\n  width: 1px;\n  min-height: 1em;\n  background-color: currentcolor;\n  opacity: 0.25;\n}\n\n.align-baseline {\n  vertical-align: baseline !important;\n}\n\n.align-top {\n  vertical-align: top !important;\n}\n\n.align-middle {\n  vertical-align: middle !important;\n}\n\n.align-bottom {\n  vertical-align: bottom !important;\n}\n\n.align-text-bottom {\n  vertical-align: text-bottom !important;\n}\n\n.align-text-top {\n  vertical-align: text-top !important;\n}\n\n.float-start {\n  float: left !important;\n}\n\n.float-end {\n  float: right !important;\n}\n\n.float-none {\n  float: none !important;\n}\n\n.opacity-0 {\n  opacity: 0 !important;\n}\n\n.opacity-25 {\n  opacity: 0.25 !important;\n}\n\n.opacity-50 {\n  opacity: 0.5 !important;\n}\n\n.opacity-75 {\n  opacity: 0.75 !important;\n}\n\n.opacity-100 {\n  opacity: 1 !important;\n}\n\n.overflow-auto {\n  overflow: auto !important;\n}\n\n.overflow-hidden {\n  overflow: hidden !important;\n}\n\n.overflow-visible {\n  overflow: visible !important;\n}\n\n.overflow-scroll {\n  overflow: scroll !important;\n}\n\n.d-inline {\n  display: inline !important;\n}\n\n.d-inline-block {\n  display: inline-block !important;\n}\n\n.d-block {\n  display: block !important;\n}\n\n.d-grid {\n  display: grid !important;\n}\n\n.d-table {\n  display: table !important;\n}\n\n.d-table-row {\n  display: table-row !important;\n}\n\n.d-table-cell {\n  display: table-cell !important;\n}\n\n.d-flex {\n  display: flex !important;\n}\n\n.d-inline-flex {\n  display: inline-flex !important;\n}\n\n.d-none {\n  display: none !important;\n}\n\n.shadow {\n  box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15) !important;\n}\n\n.shadow-sm {\n  box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075) !important;\n}\n\n.shadow-lg {\n  box-shadow: 0 1rem 3rem rgba(0, 0, 0, 0.175) !important;\n}\n\n.shadow-none {\n  box-shadow: none !important;\n}\n\n.position-static {\n  position: static !important;\n}\n\n.position-relative {\n  position: relative !important;\n}\n\n.position-absolute {\n  position: absolute !important;\n}\n\n.position-fixed {\n  position: fixed !important;\n}\n\n.position-sticky {\n  position: sticky !important;\n}\n\n.top-0 {\n  top: 0 !important;\n}\n\n.top-50 {\n  top: 50% !important;\n}\n\n.top-100 {\n  top: 100% !important;\n}\n\n.bottom-0 {\n  bottom: 0 !important;\n}\n\n.bottom-50 {\n  bottom: 50% !important;\n}\n\n.bottom-100 {\n  bottom: 100% !important;\n}\n\n.start-0 {\n  left: 0 !important;\n}\n\n.start-50 {\n  left: 50% !important;\n}\n\n.start-100 {\n  left: 100% !important;\n}\n\n.end-0 {\n  right: 0 !important;\n}\n\n.end-50 {\n  right: 50% !important;\n}\n\n.end-100 {\n  right: 100% !important;\n}\n\n.translate-middle {\n  transform: translate(-50%, -50%) !important;\n}\n\n.translate-middle-x {\n  transform: translateX(-50%) !important;\n}\n\n.translate-middle-y {\n  transform: translateY(-50%) !important;\n}\n\n.border {\n  border: var(--bs-border-width) var(--bs-border-style) var(--bs-border-color) !important;\n}\n\n.border-0 {\n  border: 0 !important;\n}\n\n.border-top {\n  border-top: var(--bs-border-width) var(--bs-border-style) var(--bs-border-color) !important;\n}\n\n.border-top-0 {\n  border-top: 0 !important;\n}\n\n.border-end {\n  border-right: var(--bs-border-width) var(--bs-border-style) var(--bs-border-color) !important;\n}\n\n.border-end-0 {\n  border-right: 0 !important;\n}\n\n.border-bottom {\n  border-bottom: var(--bs-border-width) var(--bs-border-style) var(--bs-border-color) !important;\n}\n\n.border-bottom-0 {\n  border-bottom: 0 !important;\n}\n\n.border-start {\n  border-left: var(--bs-border-width) var(--bs-border-style) var(--bs-border-color) !important;\n}\n\n.border-start-0 {\n  border-left: 0 !important;\n}\n\n.border-primary {\n  --bs-border-opacity: 1;\n  border-color: rgba(var(--bs-primary-rgb), var(--bs-border-opacity)) !important;\n}\n\n.border-secondary {\n  --bs-border-opacity: 1;\n  border-color: rgba(var(--bs-secondary-rgb), var(--bs-border-opacity)) !important;\n}\n\n.border-success {\n  --bs-border-opacity: 1;\n  border-color: rgba(var(--bs-success-rgb), var(--bs-border-opacity)) !important;\n}\n\n.border-info {\n  --bs-border-opacity: 1;\n  border-color: rgba(var(--bs-info-rgb), var(--bs-border-opacity)) !important;\n}\n\n.border-warning {\n  --bs-border-opacity: 1;\n  border-color: rgba(var(--bs-warning-rgb), var(--bs-border-opacity)) !important;\n}\n\n.border-danger {\n  --bs-border-opacity: 1;\n  border-color: rgba(var(--bs-danger-rgb), var(--bs-border-opacity)) !important;\n}\n\n.border-light {\n  --bs-border-opacity: 1;\n  border-color: rgba(var(--bs-light-rgb), var(--bs-border-opacity)) !important;\n}\n\n.border-dark {\n  --bs-border-opacity: 1;\n  border-color: rgba(var(--bs-dark-rgb), var(--bs-border-opacity)) !important;\n}\n\n.border-white {\n  --bs-border-opacity: 1;\n  border-color: rgba(var(--bs-white-rgb), var(--bs-border-opacity)) !important;\n}\n\n.border-1 {\n  --bs-border-width: 1px;\n}\n\n.border-2 {\n  --bs-border-width: 2px;\n}\n\n.border-3 {\n  --bs-border-width: 3px;\n}\n\n.border-4 {\n  --bs-border-width: 4px;\n}\n\n.border-5 {\n  --bs-border-width: 5px;\n}\n\n.border-opacity-10 {\n  --bs-border-opacity: 0.1;\n}\n\n.border-opacity-25 {\n  --bs-border-opacity: 0.25;\n}\n\n.border-opacity-50 {\n  --bs-border-opacity: 0.5;\n}\n\n.border-opacity-75 {\n  --bs-border-opacity: 0.75;\n}\n\n.border-opacity-100 {\n  --bs-border-opacity: 1;\n}\n\n.w-25 {\n  width: 25% !important;\n}\n\n.w-50 {\n  width: 50% !important;\n}\n\n.w-75 {\n  width: 75% !important;\n}\n\n.w-100 {\n  width: 100% !important;\n}\n\n.w-auto {\n  width: auto !important;\n}\n\n.mw-100 {\n  max-width: 100% !important;\n}\n\n.vw-100 {\n  width: 100vw !important;\n}\n\n.min-vw-100 {\n  min-width: 100vw !important;\n}\n\n.h-25 {\n  height: 25% !important;\n}\n\n.h-50 {\n  height: 50% !important;\n}\n\n.h-75 {\n  height: 75% !important;\n}\n\n.h-100 {\n  height: 100% !important;\n}\n\n.h-auto {\n  height: auto !important;\n}\n\n.mh-100 {\n  max-height: 100% !important;\n}\n\n.vh-100 {\n  height: 100vh !important;\n}\n\n.min-vh-100 {\n  min-height: 100vh !important;\n}\n\n.flex-fill {\n  flex: 1 1 auto !important;\n}\n\n.flex-row {\n  flex-direction: row !important;\n}\n\n.flex-column {\n  flex-direction: column !important;\n}\n\n.flex-row-reverse {\n  flex-direction: row-reverse !important;\n}\n\n.flex-column-reverse {\n  flex-direction: column-reverse !important;\n}\n\n.flex-grow-0 {\n  flex-grow: 0 !important;\n}\n\n.flex-grow-1 {\n  flex-grow: 1 !important;\n}\n\n.flex-shrink-0 {\n  flex-shrink: 0 !important;\n}\n\n.flex-shrink-1 {\n  flex-shrink: 1 !important;\n}\n\n.flex-wrap {\n  flex-wrap: wrap !important;\n}\n\n.flex-nowrap {\n  flex-wrap: nowrap !important;\n}\n\n.flex-wrap-reverse {\n  flex-wrap: wrap-reverse !important;\n}\n\n.justify-content-start {\n  justify-content: flex-start !important;\n}\n\n.justify-content-end {\n  justify-content: flex-end !important;\n}\n\n.justify-content-center {\n  justify-content: center !important;\n}\n\n.justify-content-between {\n  justify-content: space-between !important;\n}\n\n.justify-content-around {\n  justify-content: space-around !important;\n}\n\n.justify-content-evenly {\n  justify-content: space-evenly !important;\n}\n\n.align-items-start {\n  align-items: flex-start !important;\n}\n\n.align-items-end {\n  align-items: flex-end !important;\n}\n\n.align-items-center {\n  align-items: center !important;\n}\n\n.align-items-baseline {\n  align-items: baseline !important;\n}\n\n.align-items-stretch {\n  align-items: stretch !important;\n}\n\n.align-content-start {\n  align-content: flex-start !important;\n}\n\n.align-content-end {\n  align-content: flex-end !important;\n}\n\n.align-content-center {\n  align-content: center !important;\n}\n\n.align-content-between {\n  align-content: space-between !important;\n}\n\n.align-content-around {\n  align-content: space-around !important;\n}\n\n.align-content-stretch {\n  align-content: stretch !important;\n}\n\n.align-self-auto {\n  align-self: auto !important;\n}\n\n.align-self-start {\n  align-self: flex-start !important;\n}\n\n.align-self-end {\n  align-self: flex-end !important;\n}\n\n.align-self-center {\n  align-self: center !important;\n}\n\n.align-self-baseline {\n  align-self: baseline !important;\n}\n\n.align-self-stretch {\n  align-self: stretch !important;\n}\n\n.order-first {\n  order: -1 !important;\n}\n\n.order-0 {\n  order: 0 !important;\n}\n\n.order-1 {\n  order: 1 !important;\n}\n\n.order-2 {\n  order: 2 !important;\n}\n\n.order-3 {\n  order: 3 !important;\n}\n\n.order-4 {\n  order: 4 !important;\n}\n\n.order-5 {\n  order: 5 !important;\n}\n\n.order-last {\n  order: 6 !important;\n}\n\n.m-0 {\n  margin: 0 !important;\n}\n\n.m-1 {\n  margin: 0.25rem !important;\n}\n\n.m-2 {\n  margin: 0.5rem !important;\n}\n\n.m-3 {\n  margin: 1rem !important;\n}\n\n.m-4 {\n  margin: 1.5rem !important;\n}\n\n.m-5 {\n  margin: 3rem !important;\n}\n\n.m-auto {\n  margin: auto !important;\n}\n\n.mx-0 {\n  margin-right: 0 !important;\n  margin-left: 0 !important;\n}\n\n.mx-1 {\n  margin-right: 0.25rem !important;\n  margin-left: 0.25rem !important;\n}\n\n.mx-2 {\n  margin-right: 0.5rem !important;\n  margin-left: 0.5rem !important;\n}\n\n.mx-3 {\n  margin-right: 1rem !important;\n  margin-left: 1rem !important;\n}\n\n.mx-4 {\n  margin-right: 1.5rem !important;\n  margin-left: 1.5rem !important;\n}\n\n.mx-5 {\n  margin-right: 3rem !important;\n  margin-left: 3rem !important;\n}\n\n.mx-auto {\n  margin-right: auto !important;\n  margin-left: auto !important;\n}\n\n.my-0 {\n  margin-top: 0 !important;\n  margin-bottom: 0 !important;\n}\n\n.my-1 {\n  margin-top: 0.25rem !important;\n  margin-bottom: 0.25rem !important;\n}\n\n.my-2 {\n  margin-top: 0.5rem !important;\n  margin-bottom: 0.5rem !important;\n}\n\n.my-3 {\n  margin-top: 1rem !important;\n  margin-bottom: 1rem !important;\n}\n\n.my-4 {\n  margin-top: 1.5rem !important;\n  margin-bottom: 1.5rem !important;\n}\n\n.my-5 {\n  margin-top: 3rem !important;\n  margin-bottom: 3rem !important;\n}\n\n.my-auto {\n  margin-top: auto !important;\n  margin-bottom: auto !important;\n}\n\n.mt-0 {\n  margin-top: 0 !important;\n}\n\n.mt-1 {\n  margin-top: 0.25rem !important;\n}\n\n.mt-2 {\n  margin-top: 0.5rem !important;\n}\n\n.mt-3 {\n  margin-top: 1rem !important;\n}\n\n.mt-4 {\n  margin-top: 1.5rem !important;\n}\n\n.mt-5 {\n  margin-top: 3rem !important;\n}\n\n.mt-auto {\n  margin-top: auto !important;\n}\n\n.me-0 {\n  margin-right: 0 !important;\n}\n\n.me-1 {\n  margin-right: 0.25rem !important;\n}\n\n.me-2 {\n  margin-right: 0.5rem !important;\n}\n\n.me-3 {\n  margin-right: 1rem !important;\n}\n\n.me-4 {\n  margin-right: 1.5rem !important;\n}\n\n.me-5 {\n  margin-right: 3rem !important;\n}\n\n.me-auto {\n  margin-right: auto !important;\n}\n\n.mb-0 {\n  margin-bottom: 0 !important;\n}\n\n.mb-1 {\n  margin-bottom: 0.25rem !important;\n}\n\n.mb-2 {\n  margin-bottom: 0.5rem !important;\n}\n\n.mb-3 {\n  margin-bottom: 1rem !important;\n}\n\n.mb-4 {\n  margin-bottom: 1.5rem !important;\n}\n\n.mb-5 {\n  margin-bottom: 3rem !important;\n}\n\n.mb-auto {\n  margin-bottom: auto !important;\n}\n\n.ms-0 {\n  margin-left: 0 !important;\n}\n\n.ms-1 {\n  margin-left: 0.25rem !important;\n}\n\n.ms-2 {\n  margin-left: 0.5rem !important;\n}\n\n.ms-3 {\n  margin-left: 1rem !important;\n}\n\n.ms-4 {\n  margin-left: 1.5rem !important;\n}\n\n.ms-5 {\n  margin-left: 3rem !important;\n}\n\n.ms-auto {\n  margin-left: auto !important;\n}\n\n.p-0 {\n  padding: 0 !important;\n}\n\n.p-1 {\n  padding: 0.25rem !important;\n}\n\n.p-2 {\n  padding: 0.5rem !important;\n}\n\n.p-3 {\n  padding: 1rem !important;\n}\n\n.p-4 {\n  padding: 1.5rem !important;\n}\n\n.p-5 {\n  padding: 3rem !important;\n}\n\n.px-0 {\n  padding-right: 0 !important;\n  padding-left: 0 !important;\n}\n\n.px-1 {\n  padding-right: 0.25rem !important;\n  padding-left: 0.25rem !important;\n}\n\n.px-2 {\n  padding-right: 0.5rem !important;\n  padding-left: 0.5rem !important;\n}\n\n.px-3 {\n  padding-right: 1rem !important;\n  padding-left: 1rem !important;\n}\n\n.px-4 {\n  padding-right: 1.5rem !important;\n  padding-left: 1.5rem !important;\n}\n\n.px-5 {\n  padding-right: 3rem !important;\n  padding-left: 3rem !important;\n}\n\n.py-0 {\n  padding-top: 0 !important;\n  padding-bottom: 0 !important;\n}\n\n.py-1 {\n  padding-top: 0.25rem !important;\n  padding-bottom: 0.25rem !important;\n}\n\n.py-2 {\n  padding-top: 0.5rem !important;\n  padding-bottom: 0.5rem !important;\n}\n\n.py-3 {\n  padding-top: 1rem !important;\n  padding-bottom: 1rem !important;\n}\n\n.py-4 {\n  padding-top: 1.5rem !important;\n  padding-bottom: 1.5rem !important;\n}\n\n.py-5 {\n  padding-top: 3rem !important;\n  padding-bottom: 3rem !important;\n}\n\n.pt-0 {\n  padding-top: 0 !important;\n}\n\n.pt-1 {\n  padding-top: 0.25rem !important;\n}\n\n.pt-2 {\n  padding-top: 0.5rem !important;\n}\n\n.pt-3 {\n  padding-top: 1rem !important;\n}\n\n.pt-4 {\n  padding-top: 1.5rem !important;\n}\n\n.pt-5 {\n  padding-top: 3rem !important;\n}\n\n.pe-0 {\n  padding-right: 0 !important;\n}\n\n.pe-1 {\n  padding-right: 0.25rem !important;\n}\n\n.pe-2 {\n  padding-right: 0.5rem !important;\n}\n\n.pe-3 {\n  padding-right: 1rem !important;\n}\n\n.pe-4 {\n  padding-right: 1.5rem !important;\n}\n\n.pe-5 {\n  padding-right: 3rem !important;\n}\n\n.pb-0 {\n  padding-bottom: 0 !important;\n}\n\n.pb-1 {\n  padding-bottom: 0.25rem !important;\n}\n\n.pb-2 {\n  padding-bottom: 0.5rem !important;\n}\n\n.pb-3 {\n  padding-bottom: 1rem !important;\n}\n\n.pb-4 {\n  padding-bottom: 1.5rem !important;\n}\n\n.pb-5 {\n  padding-bottom: 3rem !important;\n}\n\n.ps-0 {\n  padding-left: 0 !important;\n}\n\n.ps-1 {\n  padding-left: 0.25rem !important;\n}\n\n.ps-2 {\n  padding-left: 0.5rem !important;\n}\n\n.ps-3 {\n  padding-left: 1rem !important;\n}\n\n.ps-4 {\n  padding-left: 1.5rem !important;\n}\n\n.ps-5 {\n  padding-left: 3rem !important;\n}\n\n.gap-0 {\n  gap: 0 !important;\n}\n\n.gap-1 {\n  gap: 0.25rem !important;\n}\n\n.gap-2 {\n  gap: 0.5rem !important;\n}\n\n.gap-3 {\n  gap: 1rem !important;\n}\n\n.gap-4 {\n  gap: 1.5rem !important;\n}\n\n.gap-5 {\n  gap: 3rem !important;\n}\n\n.font-monospace {\n  font-family: var(--bs-font-monospace) !important;\n}\n\n.fs-1 {\n  font-size: calc(1.375rem + 1.5vw) !important;\n}\n\n.fs-2 {\n  font-size: calc(1.325rem + 0.9vw) !important;\n}\n\n.fs-3 {\n  font-size: calc(1.3rem + 0.6vw) !important;\n}\n\n.fs-4 {\n  font-size: calc(1.275rem + 0.3vw) !important;\n}\n\n.fs-5 {\n  font-size: 1.25rem !important;\n}\n\n.fs-6 {\n  font-size: 1rem !important;\n}\n\n.fst-italic {\n  font-style: italic !important;\n}\n\n.fst-normal {\n  font-style: normal !important;\n}\n\n.fw-light {\n  font-weight: 300 !important;\n}\n\n.fw-lighter {\n  font-weight: lighter !important;\n}\n\n.fw-normal {\n  font-weight: 400 !important;\n}\n\n.fw-bold {\n  font-weight: 700 !important;\n}\n\n.fw-semibold {\n  font-weight: 600 !important;\n}\n\n.fw-bolder {\n  font-weight: bolder !important;\n}\n\n.lh-1 {\n  line-height: 1 !important;\n}\n\n.lh-sm {\n  line-height: 1.25 !important;\n}\n\n.lh-base {\n  line-height: 1.5 !important;\n}\n\n.lh-lg {\n  line-height: 2 !important;\n}\n\n.text-start {\n  text-align: left !important;\n}\n\n.text-end {\n  text-align: right !important;\n}\n\n.text-center {\n  text-align: center !important;\n}\n\n.text-decoration-none {\n  text-decoration: none !important;\n}\n\n.text-decoration-underline {\n  text-decoration: underline !important;\n}\n\n.text-decoration-line-through {\n  text-decoration: line-through !important;\n}\n\n.text-lowercase {\n  text-transform: lowercase !important;\n}\n\n.text-uppercase {\n  text-transform: uppercase !important;\n}\n\n.text-capitalize {\n  text-transform: capitalize !important;\n}\n\n.text-wrap {\n  white-space: normal !important;\n}\n\n.text-nowrap {\n  white-space: nowrap !important;\n}\n\n/* rtl:begin:remove */\n.text-break {\n  word-wrap: break-word !important;\n  word-break: break-word !important;\n}\n\n/* rtl:end:remove */\n.text-primary {\n  --bs-text-opacity: 1;\n  color: rgba(var(--bs-primary-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-secondary {\n  --bs-text-opacity: 1;\n  color: rgba(var(--bs-secondary-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-success {\n  --bs-text-opacity: 1;\n  color: rgba(var(--bs-success-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-info {\n  --bs-text-opacity: 1;\n  color: rgba(var(--bs-info-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-warning {\n  --bs-text-opacity: 1;\n  color: rgba(var(--bs-warning-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-danger {\n  --bs-text-opacity: 1;\n  color: rgba(var(--bs-danger-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-light {\n  --bs-text-opacity: 1;\n  color: rgba(var(--bs-light-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-dark {\n  --bs-text-opacity: 1;\n  color: rgba(var(--bs-dark-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-black {\n  --bs-text-opacity: 1;\n  color: rgba(var(--bs-black-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-white {\n  --bs-text-opacity: 1;\n  color: rgba(var(--bs-white-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-body {\n  --bs-text-opacity: 1;\n  color: rgba(var(--bs-body-color-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-muted {\n  --bs-text-opacity: 1;\n  color: #6c757d !important;\n}\n\n.text-black-50 {\n  --bs-text-opacity: 1;\n  color: rgba(0, 0, 0, 0.5) !important;\n}\n\n.text-white-50 {\n  --bs-text-opacity: 1;\n  color: rgba(255, 255, 255, 0.5) !important;\n}\n\n.text-reset {\n  --bs-text-opacity: 1;\n  color: inherit !important;\n}\n\n.text-opacity-25 {\n  --bs-text-opacity: 0.25;\n}\n\n.text-opacity-50 {\n  --bs-text-opacity: 0.5;\n}\n\n.text-opacity-75 {\n  --bs-text-opacity: 0.75;\n}\n\n.text-opacity-100 {\n  --bs-text-opacity: 1;\n}\n\n.bg-primary {\n  --bs-bg-opacity: 1;\n  background-color: rgba(var(--bs-primary-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-secondary {\n  --bs-bg-opacity: 1;\n  background-color: rgba(var(--bs-secondary-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-success {\n  --bs-bg-opacity: 1;\n  background-color: rgba(var(--bs-success-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-info {\n  --bs-bg-opacity: 1;\n  background-color: rgba(var(--bs-info-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-warning {\n  --bs-bg-opacity: 1;\n  background-color: rgba(var(--bs-warning-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-danger {\n  --bs-bg-opacity: 1;\n  background-color: rgba(var(--bs-danger-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-light {\n  --bs-bg-opacity: 1;\n  background-color: rgba(var(--bs-light-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-dark {\n  --bs-bg-opacity: 1;\n  background-color: rgba(var(--bs-dark-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-black {\n  --bs-bg-opacity: 1;\n  background-color: rgba(var(--bs-black-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-white {\n  --bs-bg-opacity: 1;\n  background-color: rgba(var(--bs-white-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-body {\n  --bs-bg-opacity: 1;\n  background-color: rgba(var(--bs-body-bg-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-transparent {\n  --bs-bg-opacity: 1;\n  background-color: transparent !important;\n}\n\n.bg-opacity-10 {\n  --bs-bg-opacity: 0.1;\n}\n\n.bg-opacity-25 {\n  --bs-bg-opacity: 0.25;\n}\n\n.bg-opacity-50 {\n  --bs-bg-opacity: 0.5;\n}\n\n.bg-opacity-75 {\n  --bs-bg-opacity: 0.75;\n}\n\n.bg-opacity-100 {\n  --bs-bg-opacity: 1;\n}\n\n.bg-gradient {\n  background-image: var(--bs-gradient) !important;\n}\n\n.user-select-all {\n  -webkit-user-select: all !important;\n     -moz-user-select: all !important;\n          user-select: all !important;\n}\n\n.user-select-auto {\n  -webkit-user-select: auto !important;\n     -moz-user-select: auto !important;\n          user-select: auto !important;\n}\n\n.user-select-none {\n  -webkit-user-select: none !important;\n     -moz-user-select: none !important;\n          user-select: none !important;\n}\n\n.pe-none {\n  pointer-events: none !important;\n}\n\n.pe-auto {\n  pointer-events: auto !important;\n}\n\n.rounded {\n  border-radius: var(--bs-border-radius) !important;\n}\n\n.rounded-0 {\n  border-radius: 0 !important;\n}\n\n.rounded-1 {\n  border-radius: var(--bs-border-radius-sm) !important;\n}\n\n.rounded-2 {\n  border-radius: var(--bs-border-radius) !important;\n}\n\n.rounded-3 {\n  border-radius: var(--bs-border-radius-lg) !important;\n}\n\n.rounded-4 {\n  border-radius: var(--bs-border-radius-xl) !important;\n}\n\n.rounded-5 {\n  border-radius: var(--bs-border-radius-2xl) !important;\n}\n\n.rounded-circle {\n  border-radius: 50% !important;\n}\n\n.rounded-pill {\n  border-radius: var(--bs-border-radius-pill) !important;\n}\n\n.rounded-top {\n  border-top-left-radius: var(--bs-border-radius) !important;\n  border-top-right-radius: var(--bs-border-radius) !important;\n}\n\n.rounded-end {\n  border-top-right-radius: var(--bs-border-radius) !important;\n  border-bottom-right-radius: var(--bs-border-radius) !important;\n}\n\n.rounded-bottom {\n  border-bottom-right-radius: var(--bs-border-radius) !important;\n  border-bottom-left-radius: var(--bs-border-radius) !important;\n}\n\n.rounded-start {\n  border-bottom-left-radius: var(--bs-border-radius) !important;\n  border-top-left-radius: var(--bs-border-radius) !important;\n}\n\n.visible {\n  visibility: visible !important;\n}\n\n.invisible {\n  visibility: hidden !important;\n}\n\n@media (min-width: 576px) {\n  .float-sm-start {\n    float: left !important;\n  }\n  .float-sm-end {\n    float: right !important;\n  }\n  .float-sm-none {\n    float: none !important;\n  }\n  .d-sm-inline {\n    display: inline !important;\n  }\n  .d-sm-inline-block {\n    display: inline-block !important;\n  }\n  .d-sm-block {\n    display: block !important;\n  }\n  .d-sm-grid {\n    display: grid !important;\n  }\n  .d-sm-table {\n    display: table !important;\n  }\n  .d-sm-table-row {\n    display: table-row !important;\n  }\n  .d-sm-table-cell {\n    display: table-cell !important;\n  }\n  .d-sm-flex {\n    display: flex !important;\n  }\n  .d-sm-inline-flex {\n    display: inline-flex !important;\n  }\n  .d-sm-none {\n    display: none !important;\n  }\n  .flex-sm-fill {\n    flex: 1 1 auto !important;\n  }\n  .flex-sm-row {\n    flex-direction: row !important;\n  }\n  .flex-sm-column {\n    flex-direction: column !important;\n  }\n  .flex-sm-row-reverse {\n    flex-direction: row-reverse !important;\n  }\n  .flex-sm-column-reverse {\n    flex-direction: column-reverse !important;\n  }\n  .flex-sm-grow-0 {\n    flex-grow: 0 !important;\n  }\n  .flex-sm-grow-1 {\n    flex-grow: 1 !important;\n  }\n  .flex-sm-shrink-0 {\n    flex-shrink: 0 !important;\n  }\n  .flex-sm-shrink-1 {\n    flex-shrink: 1 !important;\n  }\n  .flex-sm-wrap {\n    flex-wrap: wrap !important;\n  }\n  .flex-sm-nowrap {\n    flex-wrap: nowrap !important;\n  }\n  .flex-sm-wrap-reverse {\n    flex-wrap: wrap-reverse !important;\n  }\n  .justify-content-sm-start {\n    justify-content: flex-start !important;\n  }\n  .justify-content-sm-end {\n    justify-content: flex-end !important;\n  }\n  .justify-content-sm-center {\n    justify-content: center !important;\n  }\n  .justify-content-sm-between {\n    justify-content: space-between !important;\n  }\n  .justify-content-sm-around {\n    justify-content: space-around !important;\n  }\n  .justify-content-sm-evenly {\n    justify-content: space-evenly !important;\n  }\n  .align-items-sm-start {\n    align-items: flex-start !important;\n  }\n  .align-items-sm-end {\n    align-items: flex-end !important;\n  }\n  .align-items-sm-center {\n    align-items: center !important;\n  }\n  .align-items-sm-baseline {\n    align-items: baseline !important;\n  }\n  .align-items-sm-stretch {\n    align-items: stretch !important;\n  }\n  .align-content-sm-start {\n    align-content: flex-start !important;\n  }\n  .align-content-sm-end {\n    align-content: flex-end !important;\n  }\n  .align-content-sm-center {\n    align-content: center !important;\n  }\n  .align-content-sm-between {\n    align-content: space-between !important;\n  }\n  .align-content-sm-around {\n    align-content: space-around !important;\n  }\n  .align-content-sm-stretch {\n    align-content: stretch !important;\n  }\n  .align-self-sm-auto {\n    align-self: auto !important;\n  }\n  .align-self-sm-start {\n    align-self: flex-start !important;\n  }\n  .align-self-sm-end {\n    align-self: flex-end !important;\n  }\n  .align-self-sm-center {\n    align-self: center !important;\n  }\n  .align-self-sm-baseline {\n    align-self: baseline !important;\n  }\n  .align-self-sm-stretch {\n    align-self: stretch !important;\n  }\n  .order-sm-first {\n    order: -1 !important;\n  }\n  .order-sm-0 {\n    order: 0 !important;\n  }\n  .order-sm-1 {\n    order: 1 !important;\n  }\n  .order-sm-2 {\n    order: 2 !important;\n  }\n  .order-sm-3 {\n    order: 3 !important;\n  }\n  .order-sm-4 {\n    order: 4 !important;\n  }\n  .order-sm-5 {\n    order: 5 !important;\n  }\n  .order-sm-last {\n    order: 6 !important;\n  }\n  .m-sm-0 {\n    margin: 0 !important;\n  }\n  .m-sm-1 {\n    margin: 0.25rem !important;\n  }\n  .m-sm-2 {\n    margin: 0.5rem !important;\n  }\n  .m-sm-3 {\n    margin: 1rem !important;\n  }\n  .m-sm-4 {\n    margin: 1.5rem !important;\n  }\n  .m-sm-5 {\n    margin: 3rem !important;\n  }\n  .m-sm-auto {\n    margin: auto !important;\n  }\n  .mx-sm-0 {\n    margin-right: 0 !important;\n    margin-left: 0 !important;\n  }\n  .mx-sm-1 {\n    margin-right: 0.25rem !important;\n    margin-left: 0.25rem !important;\n  }\n  .mx-sm-2 {\n    margin-right: 0.5rem !important;\n    margin-left: 0.5rem !important;\n  }\n  .mx-sm-3 {\n    margin-right: 1rem !important;\n    margin-left: 1rem !important;\n  }\n  .mx-sm-4 {\n    margin-right: 1.5rem !important;\n    margin-left: 1.5rem !important;\n  }\n  .mx-sm-5 {\n    margin-right: 3rem !important;\n    margin-left: 3rem !important;\n  }\n  .mx-sm-auto {\n    margin-right: auto !important;\n    margin-left: auto !important;\n  }\n  .my-sm-0 {\n    margin-top: 0 !important;\n    margin-bottom: 0 !important;\n  }\n  .my-sm-1 {\n    margin-top: 0.25rem !important;\n    margin-bottom: 0.25rem !important;\n  }\n  .my-sm-2 {\n    margin-top: 0.5rem !important;\n    margin-bottom: 0.5rem !important;\n  }\n  .my-sm-3 {\n    margin-top: 1rem !important;\n    margin-bottom: 1rem !important;\n  }\n  .my-sm-4 {\n    margin-top: 1.5rem !important;\n    margin-bottom: 1.5rem !important;\n  }\n  .my-sm-5 {\n    margin-top: 3rem !important;\n    margin-bottom: 3rem !important;\n  }\n  .my-sm-auto {\n    margin-top: auto !important;\n    margin-bottom: auto !important;\n  }\n  .mt-sm-0 {\n    margin-top: 0 !important;\n  }\n  .mt-sm-1 {\n    margin-top: 0.25rem !important;\n  }\n  .mt-sm-2 {\n    margin-top: 0.5rem !important;\n  }\n  .mt-sm-3 {\n    margin-top: 1rem !important;\n  }\n  .mt-sm-4 {\n    margin-top: 1.5rem !important;\n  }\n  .mt-sm-5 {\n    margin-top: 3rem !important;\n  }\n  .mt-sm-auto {\n    margin-top: auto !important;\n  }\n  .me-sm-0 {\n    margin-right: 0 !important;\n  }\n  .me-sm-1 {\n    margin-right: 0.25rem !important;\n  }\n  .me-sm-2 {\n    margin-right: 0.5rem !important;\n  }\n  .me-sm-3 {\n    margin-right: 1rem !important;\n  }\n  .me-sm-4 {\n    margin-right: 1.5rem !important;\n  }\n  .me-sm-5 {\n    margin-right: 3rem !important;\n  }\n  .me-sm-auto {\n    margin-right: auto !important;\n  }\n  .mb-sm-0 {\n    margin-bottom: 0 !important;\n  }\n  .mb-sm-1 {\n    margin-bottom: 0.25rem !important;\n  }\n  .mb-sm-2 {\n    margin-bottom: 0.5rem !important;\n  }\n  .mb-sm-3 {\n    margin-bottom: 1rem !important;\n  }\n  .mb-sm-4 {\n    margin-bottom: 1.5rem !important;\n  }\n  .mb-sm-5 {\n    margin-bottom: 3rem !important;\n  }\n  .mb-sm-auto {\n    margin-bottom: auto !important;\n  }\n  .ms-sm-0 {\n    margin-left: 0 !important;\n  }\n  .ms-sm-1 {\n    margin-left: 0.25rem !important;\n  }\n  .ms-sm-2 {\n    margin-left: 0.5rem !important;\n  }\n  .ms-sm-3 {\n    margin-left: 1rem !important;\n  }\n  .ms-sm-4 {\n    margin-left: 1.5rem !important;\n  }\n  .ms-sm-5 {\n    margin-left: 3rem !important;\n  }\n  .ms-sm-auto {\n    margin-left: auto !important;\n  }\n  .p-sm-0 {\n    padding: 0 !important;\n  }\n  .p-sm-1 {\n    padding: 0.25rem !important;\n  }\n  .p-sm-2 {\n    padding: 0.5rem !important;\n  }\n  .p-sm-3 {\n    padding: 1rem !important;\n  }\n  .p-sm-4 {\n    padding: 1.5rem !important;\n  }\n  .p-sm-5 {\n    padding: 3rem !important;\n  }\n  .px-sm-0 {\n    padding-right: 0 !important;\n    padding-left: 0 !important;\n  }\n  .px-sm-1 {\n    padding-right: 0.25rem !important;\n    padding-left: 0.25rem !important;\n  }\n  .px-sm-2 {\n    padding-right: 0.5rem !important;\n    padding-left: 0.5rem !important;\n  }\n  .px-sm-3 {\n    padding-right: 1rem !important;\n    padding-left: 1rem !important;\n  }\n  .px-sm-4 {\n    padding-right: 1.5rem !important;\n    padding-left: 1.5rem !important;\n  }\n  .px-sm-5 {\n    padding-right: 3rem !important;\n    padding-left: 3rem !important;\n  }\n  .py-sm-0 {\n    padding-top: 0 !important;\n    padding-bottom: 0 !important;\n  }\n  .py-sm-1 {\n    padding-top: 0.25rem !important;\n    padding-bottom: 0.25rem !important;\n  }\n  .py-sm-2 {\n    padding-top: 0.5rem !important;\n    padding-bottom: 0.5rem !important;\n  }\n  .py-sm-3 {\n    padding-top: 1rem !important;\n    padding-bottom: 1rem !important;\n  }\n  .py-sm-4 {\n    padding-top: 1.5rem !important;\n    padding-bottom: 1.5rem !important;\n  }\n  .py-sm-5 {\n    padding-top: 3rem !important;\n    padding-bottom: 3rem !important;\n  }\n  .pt-sm-0 {\n    padding-top: 0 !important;\n  }\n  .pt-sm-1 {\n    padding-top: 0.25rem !important;\n  }\n  .pt-sm-2 {\n    padding-top: 0.5rem !important;\n  }\n  .pt-sm-3 {\n    padding-top: 1rem !important;\n  }\n  .pt-sm-4 {\n    padding-top: 1.5rem !important;\n  }\n  .pt-sm-5 {\n    padding-top: 3rem !important;\n  }\n  .pe-sm-0 {\n    padding-right: 0 !important;\n  }\n  .pe-sm-1 {\n    padding-right: 0.25rem !important;\n  }\n  .pe-sm-2 {\n    padding-right: 0.5rem !important;\n  }\n  .pe-sm-3 {\n    padding-right: 1rem !important;\n  }\n  .pe-sm-4 {\n    padding-right: 1.5rem !important;\n  }\n  .pe-sm-5 {\n    padding-right: 3rem !important;\n  }\n  .pb-sm-0 {\n    padding-bottom: 0 !important;\n  }\n  .pb-sm-1 {\n    padding-bottom: 0.25rem !important;\n  }\n  .pb-sm-2 {\n    padding-bottom: 0.5rem !important;\n  }\n  .pb-sm-3 {\n    padding-bottom: 1rem !important;\n  }\n  .pb-sm-4 {\n    padding-bottom: 1.5rem !important;\n  }\n  .pb-sm-5 {\n    padding-bottom: 3rem !important;\n  }\n  .ps-sm-0 {\n    padding-left: 0 !important;\n  }\n  .ps-sm-1 {\n    padding-left: 0.25rem !important;\n  }\n  .ps-sm-2 {\n    padding-left: 0.5rem !important;\n  }\n  .ps-sm-3 {\n    padding-left: 1rem !important;\n  }\n  .ps-sm-4 {\n    padding-left: 1.5rem !important;\n  }\n  .ps-sm-5 {\n    padding-left: 3rem !important;\n  }\n  .gap-sm-0 {\n    gap: 0 !important;\n  }\n  .gap-sm-1 {\n    gap: 0.25rem !important;\n  }\n  .gap-sm-2 {\n    gap: 0.5rem !important;\n  }\n  .gap-sm-3 {\n    gap: 1rem !important;\n  }\n  .gap-sm-4 {\n    gap: 1.5rem !important;\n  }\n  .gap-sm-5 {\n    gap: 3rem !important;\n  }\n  .text-sm-start {\n    text-align: left !important;\n  }\n  .text-sm-end {\n    text-align: right !important;\n  }\n  .text-sm-center {\n    text-align: center !important;\n  }\n}\n@media (min-width: 768px) {\n  .float-md-start {\n    float: left !important;\n  }\n  .float-md-end {\n    float: right !important;\n  }\n  .float-md-none {\n    float: none !important;\n  }\n  .d-md-inline {\n    display: inline !important;\n  }\n  .d-md-inline-block {\n    display: inline-block !important;\n  }\n  .d-md-block {\n    display: block !important;\n  }\n  .d-md-grid {\n    display: grid !important;\n  }\n  .d-md-table {\n    display: table !important;\n  }\n  .d-md-table-row {\n    display: table-row !important;\n  }\n  .d-md-table-cell {\n    display: table-cell !important;\n  }\n  .d-md-flex {\n    display: flex !important;\n  }\n  .d-md-inline-flex {\n    display: inline-flex !important;\n  }\n  .d-md-none {\n    display: none !important;\n  }\n  .flex-md-fill {\n    flex: 1 1 auto !important;\n  }\n  .flex-md-row {\n    flex-direction: row !important;\n  }\n  .flex-md-column {\n    flex-direction: column !important;\n  }\n  .flex-md-row-reverse {\n    flex-direction: row-reverse !important;\n  }\n  .flex-md-column-reverse {\n    flex-direction: column-reverse !important;\n  }\n  .flex-md-grow-0 {\n    flex-grow: 0 !important;\n  }\n  .flex-md-grow-1 {\n    flex-grow: 1 !important;\n  }\n  .flex-md-shrink-0 {\n    flex-shrink: 0 !important;\n  }\n  .flex-md-shrink-1 {\n    flex-shrink: 1 !important;\n  }\n  .flex-md-wrap {\n    flex-wrap: wrap !important;\n  }\n  .flex-md-nowrap {\n    flex-wrap: nowrap !important;\n  }\n  .flex-md-wrap-reverse {\n    flex-wrap: wrap-reverse !important;\n  }\n  .justify-content-md-start {\n    justify-content: flex-start !important;\n  }\n  .justify-content-md-end {\n    justify-content: flex-end !important;\n  }\n  .justify-content-md-center {\n    justify-content: center !important;\n  }\n  .justify-content-md-between {\n    justify-content: space-between !important;\n  }\n  .justify-content-md-around {\n    justify-content: space-around !important;\n  }\n  .justify-content-md-evenly {\n    justify-content: space-evenly !important;\n  }\n  .align-items-md-start {\n    align-items: flex-start !important;\n  }\n  .align-items-md-end {\n    align-items: flex-end !important;\n  }\n  .align-items-md-center {\n    align-items: center !important;\n  }\n  .align-items-md-baseline {\n    align-items: baseline !important;\n  }\n  .align-items-md-stretch {\n    align-items: stretch !important;\n  }\n  .align-content-md-start {\n    align-content: flex-start !important;\n  }\n  .align-content-md-end {\n    align-content: flex-end !important;\n  }\n  .align-content-md-center {\n    align-content: center !important;\n  }\n  .align-content-md-between {\n    align-content: space-between !important;\n  }\n  .align-content-md-around {\n    align-content: space-around !important;\n  }\n  .align-content-md-stretch {\n    align-content: stretch !important;\n  }\n  .align-self-md-auto {\n    align-self: auto !important;\n  }\n  .align-self-md-start {\n    align-self: flex-start !important;\n  }\n  .align-self-md-end {\n    align-self: flex-end !important;\n  }\n  .align-self-md-center {\n    align-self: center !important;\n  }\n  .align-self-md-baseline {\n    align-self: baseline !important;\n  }\n  .align-self-md-stretch {\n    align-self: stretch !important;\n  }\n  .order-md-first {\n    order: -1 !important;\n  }\n  .order-md-0 {\n    order: 0 !important;\n  }\n  .order-md-1 {\n    order: 1 !important;\n  }\n  .order-md-2 {\n    order: 2 !important;\n  }\n  .order-md-3 {\n    order: 3 !important;\n  }\n  .order-md-4 {\n    order: 4 !important;\n  }\n  .order-md-5 {\n    order: 5 !important;\n  }\n  .order-md-last {\n    order: 6 !important;\n  }\n  .m-md-0 {\n    margin: 0 !important;\n  }\n  .m-md-1 {\n    margin: 0.25rem !important;\n  }\n  .m-md-2 {\n    margin: 0.5rem !important;\n  }\n  .m-md-3 {\n    margin: 1rem !important;\n  }\n  .m-md-4 {\n    margin: 1.5rem !important;\n  }\n  .m-md-5 {\n    margin: 3rem !important;\n  }\n  .m-md-auto {\n    margin: auto !important;\n  }\n  .mx-md-0 {\n    margin-right: 0 !important;\n    margin-left: 0 !important;\n  }\n  .mx-md-1 {\n    margin-right: 0.25rem !important;\n    margin-left: 0.25rem !important;\n  }\n  .mx-md-2 {\n    margin-right: 0.5rem !important;\n    margin-left: 0.5rem !important;\n  }\n  .mx-md-3 {\n    margin-right: 1rem !important;\n    margin-left: 1rem !important;\n  }\n  .mx-md-4 {\n    margin-right: 1.5rem !important;\n    margin-left: 1.5rem !important;\n  }\n  .mx-md-5 {\n    margin-right: 3rem !important;\n    margin-left: 3rem !important;\n  }\n  .mx-md-auto {\n    margin-right: auto !important;\n    margin-left: auto !important;\n  }\n  .my-md-0 {\n    margin-top: 0 !important;\n    margin-bottom: 0 !important;\n  }\n  .my-md-1 {\n    margin-top: 0.25rem !important;\n    margin-bottom: 0.25rem !important;\n  }\n  .my-md-2 {\n    margin-top: 0.5rem !important;\n    margin-bottom: 0.5rem !important;\n  }\n  .my-md-3 {\n    margin-top: 1rem !important;\n    margin-bottom: 1rem !important;\n  }\n  .my-md-4 {\n    margin-top: 1.5rem !important;\n    margin-bottom: 1.5rem !important;\n  }\n  .my-md-5 {\n    margin-top: 3rem !important;\n    margin-bottom: 3rem !important;\n  }\n  .my-md-auto {\n    margin-top: auto !important;\n    margin-bottom: auto !important;\n  }\n  .mt-md-0 {\n    margin-top: 0 !important;\n  }\n  .mt-md-1 {\n    margin-top: 0.25rem !important;\n  }\n  .mt-md-2 {\n    margin-top: 0.5rem !important;\n  }\n  .mt-md-3 {\n    margin-top: 1rem !important;\n  }\n  .mt-md-4 {\n    margin-top: 1.5rem !important;\n  }\n  .mt-md-5 {\n    margin-top: 3rem !important;\n  }\n  .mt-md-auto {\n    margin-top: auto !important;\n  }\n  .me-md-0 {\n    margin-right: 0 !important;\n  }\n  .me-md-1 {\n    margin-right: 0.25rem !important;\n  }\n  .me-md-2 {\n    margin-right: 0.5rem !important;\n  }\n  .me-md-3 {\n    margin-right: 1rem !important;\n  }\n  .me-md-4 {\n    margin-right: 1.5rem !important;\n  }\n  .me-md-5 {\n    margin-right: 3rem !important;\n  }\n  .me-md-auto {\n    margin-right: auto !important;\n  }\n  .mb-md-0 {\n    margin-bottom: 0 !important;\n  }\n  .mb-md-1 {\n    margin-bottom: 0.25rem !important;\n  }\n  .mb-md-2 {\n    margin-bottom: 0.5rem !important;\n  }\n  .mb-md-3 {\n    margin-bottom: 1rem !important;\n  }\n  .mb-md-4 {\n    margin-bottom: 1.5rem !important;\n  }\n  .mb-md-5 {\n    margin-bottom: 3rem !important;\n  }\n  .mb-md-auto {\n    margin-bottom: auto !important;\n  }\n  .ms-md-0 {\n    margin-left: 0 !important;\n  }\n  .ms-md-1 {\n    margin-left: 0.25rem !important;\n  }\n  .ms-md-2 {\n    margin-left: 0.5rem !important;\n  }\n  .ms-md-3 {\n    margin-left: 1rem !important;\n  }\n  .ms-md-4 {\n    margin-left: 1.5rem !important;\n  }\n  .ms-md-5 {\n    margin-left: 3rem !important;\n  }\n  .ms-md-auto {\n    margin-left: auto !important;\n  }\n  .p-md-0 {\n    padding: 0 !important;\n  }\n  .p-md-1 {\n    padding: 0.25rem !important;\n  }\n  .p-md-2 {\n    padding: 0.5rem !important;\n  }\n  .p-md-3 {\n    padding: 1rem !important;\n  }\n  .p-md-4 {\n    padding: 1.5rem !important;\n  }\n  .p-md-5 {\n    padding: 3rem !important;\n  }\n  .px-md-0 {\n    padding-right: 0 !important;\n    padding-left: 0 !important;\n  }\n  .px-md-1 {\n    padding-right: 0.25rem !important;\n    padding-left: 0.25rem !important;\n  }\n  .px-md-2 {\n    padding-right: 0.5rem !important;\n    padding-left: 0.5rem !important;\n  }\n  .px-md-3 {\n    padding-right: 1rem !important;\n    padding-left: 1rem !important;\n  }\n  .px-md-4 {\n    padding-right: 1.5rem !important;\n    padding-left: 1.5rem !important;\n  }\n  .px-md-5 {\n    padding-right: 3rem !important;\n    padding-left: 3rem !important;\n  }\n  .py-md-0 {\n    padding-top: 0 !important;\n    padding-bottom: 0 !important;\n  }\n  .py-md-1 {\n    padding-top: 0.25rem !important;\n    padding-bottom: 0.25rem !important;\n  }\n  .py-md-2 {\n    padding-top: 0.5rem !important;\n    padding-bottom: 0.5rem !important;\n  }\n  .py-md-3 {\n    padding-top: 1rem !important;\n    padding-bottom: 1rem !important;\n  }\n  .py-md-4 {\n    padding-top: 1.5rem !important;\n    padding-bottom: 1.5rem !important;\n  }\n  .py-md-5 {\n    padding-top: 3rem !important;\n    padding-bottom: 3rem !important;\n  }\n  .pt-md-0 {\n    padding-top: 0 !important;\n  }\n  .pt-md-1 {\n    padding-top: 0.25rem !important;\n  }\n  .pt-md-2 {\n    padding-top: 0.5rem !important;\n  }\n  .pt-md-3 {\n    padding-top: 1rem !important;\n  }\n  .pt-md-4 {\n    padding-top: 1.5rem !important;\n  }\n  .pt-md-5 {\n    padding-top: 3rem !important;\n  }\n  .pe-md-0 {\n    padding-right: 0 !important;\n  }\n  .pe-md-1 {\n    padding-right: 0.25rem !important;\n  }\n  .pe-md-2 {\n    padding-right: 0.5rem !important;\n  }\n  .pe-md-3 {\n    padding-right: 1rem !important;\n  }\n  .pe-md-4 {\n    padding-right: 1.5rem !important;\n  }\n  .pe-md-5 {\n    padding-right: 3rem !important;\n  }\n  .pb-md-0 {\n    padding-bottom: 0 !important;\n  }\n  .pb-md-1 {\n    padding-bottom: 0.25rem !important;\n  }\n  .pb-md-2 {\n    padding-bottom: 0.5rem !important;\n  }\n  .pb-md-3 {\n    padding-bottom: 1rem !important;\n  }\n  .pb-md-4 {\n    padding-bottom: 1.5rem !important;\n  }\n  .pb-md-5 {\n    padding-bottom: 3rem !important;\n  }\n  .ps-md-0 {\n    padding-left: 0 !important;\n  }\n  .ps-md-1 {\n    padding-left: 0.25rem !important;\n  }\n  .ps-md-2 {\n    padding-left: 0.5rem !important;\n  }\n  .ps-md-3 {\n    padding-left: 1rem !important;\n  }\n  .ps-md-4 {\n    padding-left: 1.5rem !important;\n  }\n  .ps-md-5 {\n    padding-left: 3rem !important;\n  }\n  .gap-md-0 {\n    gap: 0 !important;\n  }\n  .gap-md-1 {\n    gap: 0.25rem !important;\n  }\n  .gap-md-2 {\n    gap: 0.5rem !important;\n  }\n  .gap-md-3 {\n    gap: 1rem !important;\n  }\n  .gap-md-4 {\n    gap: 1.5rem !important;\n  }\n  .gap-md-5 {\n    gap: 3rem !important;\n  }\n  .text-md-start {\n    text-align: left !important;\n  }\n  .text-md-end {\n    text-align: right !important;\n  }\n  .text-md-center {\n    text-align: center !important;\n  }\n}\n@media (min-width: 992px) {\n  .float-lg-start {\n    float: left !important;\n  }\n  .float-lg-end {\n    float: right !important;\n  }\n  .float-lg-none {\n    float: none !important;\n  }\n  .d-lg-inline {\n    display: inline !important;\n  }\n  .d-lg-inline-block {\n    display: inline-block !important;\n  }\n  .d-lg-block {\n    display: block !important;\n  }\n  .d-lg-grid {\n    display: grid !important;\n  }\n  .d-lg-table {\n    display: table !important;\n  }\n  .d-lg-table-row {\n    display: table-row !important;\n  }\n  .d-lg-table-cell {\n    display: table-cell !important;\n  }\n  .d-lg-flex {\n    display: flex !important;\n  }\n  .d-lg-inline-flex {\n    display: inline-flex !important;\n  }\n  .d-lg-none {\n    display: none !important;\n  }\n  .flex-lg-fill {\n    flex: 1 1 auto !important;\n  }\n  .flex-lg-row {\n    flex-direction: row !important;\n  }\n  .flex-lg-column {\n    flex-direction: column !important;\n  }\n  .flex-lg-row-reverse {\n    flex-direction: row-reverse !important;\n  }\n  .flex-lg-column-reverse {\n    flex-direction: column-reverse !important;\n  }\n  .flex-lg-grow-0 {\n    flex-grow: 0 !important;\n  }\n  .flex-lg-grow-1 {\n    flex-grow: 1 !important;\n  }\n  .flex-lg-shrink-0 {\n    flex-shrink: 0 !important;\n  }\n  .flex-lg-shrink-1 {\n    flex-shrink: 1 !important;\n  }\n  .flex-lg-wrap {\n    flex-wrap: wrap !important;\n  }\n  .flex-lg-nowrap {\n    flex-wrap: nowrap !important;\n  }\n  .flex-lg-wrap-reverse {\n    flex-wrap: wrap-reverse !important;\n  }\n  .justify-content-lg-start {\n    justify-content: flex-start !important;\n  }\n  .justify-content-lg-end {\n    justify-content: flex-end !important;\n  }\n  .justify-content-lg-center {\n    justify-content: center !important;\n  }\n  .justify-content-lg-between {\n    justify-content: space-between !important;\n  }\n  .justify-content-lg-around {\n    justify-content: space-around !important;\n  }\n  .justify-content-lg-evenly {\n    justify-content: space-evenly !important;\n  }\n  .align-items-lg-start {\n    align-items: flex-start !important;\n  }\n  .align-items-lg-end {\n    align-items: flex-end !important;\n  }\n  .align-items-lg-center {\n    align-items: center !important;\n  }\n  .align-items-lg-baseline {\n    align-items: baseline !important;\n  }\n  .align-items-lg-stretch {\n    align-items: stretch !important;\n  }\n  .align-content-lg-start {\n    align-content: flex-start !important;\n  }\n  .align-content-lg-end {\n    align-content: flex-end !important;\n  }\n  .align-content-lg-center {\n    align-content: center !important;\n  }\n  .align-content-lg-between {\n    align-content: space-between !important;\n  }\n  .align-content-lg-around {\n    align-content: space-around !important;\n  }\n  .align-content-lg-stretch {\n    align-content: stretch !important;\n  }\n  .align-self-lg-auto {\n    align-self: auto !important;\n  }\n  .align-self-lg-start {\n    align-self: flex-start !important;\n  }\n  .align-self-lg-end {\n    align-self: flex-end !important;\n  }\n  .align-self-lg-center {\n    align-self: center !important;\n  }\n  .align-self-lg-baseline {\n    align-self: baseline !important;\n  }\n  .align-self-lg-stretch {\n    align-self: stretch !important;\n  }\n  .order-lg-first {\n    order: -1 !important;\n  }\n  .order-lg-0 {\n    order: 0 !important;\n  }\n  .order-lg-1 {\n    order: 1 !important;\n  }\n  .order-lg-2 {\n    order: 2 !important;\n  }\n  .order-lg-3 {\n    order: 3 !important;\n  }\n  .order-lg-4 {\n    order: 4 !important;\n  }\n  .order-lg-5 {\n    order: 5 !important;\n  }\n  .order-lg-last {\n    order: 6 !important;\n  }\n  .m-lg-0 {\n    margin: 0 !important;\n  }\n  .m-lg-1 {\n    margin: 0.25rem !important;\n  }\n  .m-lg-2 {\n    margin: 0.5rem !important;\n  }\n  .m-lg-3 {\n    margin: 1rem !important;\n  }\n  .m-lg-4 {\n    margin: 1.5rem !important;\n  }\n  .m-lg-5 {\n    margin: 3rem !important;\n  }\n  .m-lg-auto {\n    margin: auto !important;\n  }\n  .mx-lg-0 {\n    margin-right: 0 !important;\n    margin-left: 0 !important;\n  }\n  .mx-lg-1 {\n    margin-right: 0.25rem !important;\n    margin-left: 0.25rem !important;\n  }\n  .mx-lg-2 {\n    margin-right: 0.5rem !important;\n    margin-left: 0.5rem !important;\n  }\n  .mx-lg-3 {\n    margin-right: 1rem !important;\n    margin-left: 1rem !important;\n  }\n  .mx-lg-4 {\n    margin-right: 1.5rem !important;\n    margin-left: 1.5rem !important;\n  }\n  .mx-lg-5 {\n    margin-right: 3rem !important;\n    margin-left: 3rem !important;\n  }\n  .mx-lg-auto {\n    margin-right: auto !important;\n    margin-left: auto !important;\n  }\n  .my-lg-0 {\n    margin-top: 0 !important;\n    margin-bottom: 0 !important;\n  }\n  .my-lg-1 {\n    margin-top: 0.25rem !important;\n    margin-bottom: 0.25rem !important;\n  }\n  .my-lg-2 {\n    margin-top: 0.5rem !important;\n    margin-bottom: 0.5rem !important;\n  }\n  .my-lg-3 {\n    margin-top: 1rem !important;\n    margin-bottom: 1rem !important;\n  }\n  .my-lg-4 {\n    margin-top: 1.5rem !important;\n    margin-bottom: 1.5rem !important;\n  }\n  .my-lg-5 {\n    margin-top: 3rem !important;\n    margin-bottom: 3rem !important;\n  }\n  .my-lg-auto {\n    margin-top: auto !important;\n    margin-bottom: auto !important;\n  }\n  .mt-lg-0 {\n    margin-top: 0 !important;\n  }\n  .mt-lg-1 {\n    margin-top: 0.25rem !important;\n  }\n  .mt-lg-2 {\n    margin-top: 0.5rem !important;\n  }\n  .mt-lg-3 {\n    margin-top: 1rem !important;\n  }\n  .mt-lg-4 {\n    margin-top: 1.5rem !important;\n  }\n  .mt-lg-5 {\n    margin-top: 3rem !important;\n  }\n  .mt-lg-auto {\n    margin-top: auto !important;\n  }\n  .me-lg-0 {\n    margin-right: 0 !important;\n  }\n  .me-lg-1 {\n    margin-right: 0.25rem !important;\n  }\n  .me-lg-2 {\n    margin-right: 0.5rem !important;\n  }\n  .me-lg-3 {\n    margin-right: 1rem !important;\n  }\n  .me-lg-4 {\n    margin-right: 1.5rem !important;\n  }\n  .me-lg-5 {\n    margin-right: 3rem !important;\n  }\n  .me-lg-auto {\n    margin-right: auto !important;\n  }\n  .mb-lg-0 {\n    margin-bottom: 0 !important;\n  }\n  .mb-lg-1 {\n    margin-bottom: 0.25rem !important;\n  }\n  .mb-lg-2 {\n    margin-bottom: 0.5rem !important;\n  }\n  .mb-lg-3 {\n    margin-bottom: 1rem !important;\n  }\n  .mb-lg-4 {\n    margin-bottom: 1.5rem !important;\n  }\n  .mb-lg-5 {\n    margin-bottom: 3rem !important;\n  }\n  .mb-lg-auto {\n    margin-bottom: auto !important;\n  }\n  .ms-lg-0 {\n    margin-left: 0 !important;\n  }\n  .ms-lg-1 {\n    margin-left: 0.25rem !important;\n  }\n  .ms-lg-2 {\n    margin-left: 0.5rem !important;\n  }\n  .ms-lg-3 {\n    margin-left: 1rem !important;\n  }\n  .ms-lg-4 {\n    margin-left: 1.5rem !important;\n  }\n  .ms-lg-5 {\n    margin-left: 3rem !important;\n  }\n  .ms-lg-auto {\n    margin-left: auto !important;\n  }\n  .p-lg-0 {\n    padding: 0 !important;\n  }\n  .p-lg-1 {\n    padding: 0.25rem !important;\n  }\n  .p-lg-2 {\n    padding: 0.5rem !important;\n  }\n  .p-lg-3 {\n    padding: 1rem !important;\n  }\n  .p-lg-4 {\n    padding: 1.5rem !important;\n  }\n  .p-lg-5 {\n    padding: 3rem !important;\n  }\n  .px-lg-0 {\n    padding-right: 0 !important;\n    padding-left: 0 !important;\n  }\n  .px-lg-1 {\n    padding-right: 0.25rem !important;\n    padding-left: 0.25rem !important;\n  }\n  .px-lg-2 {\n    padding-right: 0.5rem !important;\n    padding-left: 0.5rem !important;\n  }\n  .px-lg-3 {\n    padding-right: 1rem !important;\n    padding-left: 1rem !important;\n  }\n  .px-lg-4 {\n    padding-right: 1.5rem !important;\n    padding-left: 1.5rem !important;\n  }\n  .px-lg-5 {\n    padding-right: 3rem !important;\n    padding-left: 3rem !important;\n  }\n  .py-lg-0 {\n    padding-top: 0 !important;\n    padding-bottom: 0 !important;\n  }\n  .py-lg-1 {\n    padding-top: 0.25rem !important;\n    padding-bottom: 0.25rem !important;\n  }\n  .py-lg-2 {\n    padding-top: 0.5rem !important;\n    padding-bottom: 0.5rem !important;\n  }\n  .py-lg-3 {\n    padding-top: 1rem !important;\n    padding-bottom: 1rem !important;\n  }\n  .py-lg-4 {\n    padding-top: 1.5rem !important;\n    padding-bottom: 1.5rem !important;\n  }\n  .py-lg-5 {\n    padding-top: 3rem !important;\n    padding-bottom: 3rem !important;\n  }\n  .pt-lg-0 {\n    padding-top: 0 !important;\n  }\n  .pt-lg-1 {\n    padding-top: 0.25rem !important;\n  }\n  .pt-lg-2 {\n    padding-top: 0.5rem !important;\n  }\n  .pt-lg-3 {\n    padding-top: 1rem !important;\n  }\n  .pt-lg-4 {\n    padding-top: 1.5rem !important;\n  }\n  .pt-lg-5 {\n    padding-top: 3rem !important;\n  }\n  .pe-lg-0 {\n    padding-right: 0 !important;\n  }\n  .pe-lg-1 {\n    padding-right: 0.25rem !important;\n  }\n  .pe-lg-2 {\n    padding-right: 0.5rem !important;\n  }\n  .pe-lg-3 {\n    padding-right: 1rem !important;\n  }\n  .pe-lg-4 {\n    padding-right: 1.5rem !important;\n  }\n  .pe-lg-5 {\n    padding-right: 3rem !important;\n  }\n  .pb-lg-0 {\n    padding-bottom: 0 !important;\n  }\n  .pb-lg-1 {\n    padding-bottom: 0.25rem !important;\n  }\n  .pb-lg-2 {\n    padding-bottom: 0.5rem !important;\n  }\n  .pb-lg-3 {\n    padding-bottom: 1rem !important;\n  }\n  .pb-lg-4 {\n    padding-bottom: 1.5rem !important;\n  }\n  .pb-lg-5 {\n    padding-bottom: 3rem !important;\n  }\n  .ps-lg-0 {\n    padding-left: 0 !important;\n  }\n  .ps-lg-1 {\n    padding-left: 0.25rem !important;\n  }\n  .ps-lg-2 {\n    padding-left: 0.5rem !important;\n  }\n  .ps-lg-3 {\n    padding-left: 1rem !important;\n  }\n  .ps-lg-4 {\n    padding-left: 1.5rem !important;\n  }\n  .ps-lg-5 {\n    padding-left: 3rem !important;\n  }\n  .gap-lg-0 {\n    gap: 0 !important;\n  }\n  .gap-lg-1 {\n    gap: 0.25rem !important;\n  }\n  .gap-lg-2 {\n    gap: 0.5rem !important;\n  }\n  .gap-lg-3 {\n    gap: 1rem !important;\n  }\n  .gap-lg-4 {\n    gap: 1.5rem !important;\n  }\n  .gap-lg-5 {\n    gap: 3rem !important;\n  }\n  .text-lg-start {\n    text-align: left !important;\n  }\n  .text-lg-end {\n    text-align: right !important;\n  }\n  .text-lg-center {\n    text-align: center !important;\n  }\n}\n@media (min-width: 1200px) {\n  .float-xl-start {\n    float: left !important;\n  }\n  .float-xl-end {\n    float: right !important;\n  }\n  .float-xl-none {\n    float: none !important;\n  }\n  .d-xl-inline {\n    display: inline !important;\n  }\n  .d-xl-inline-block {\n    display: inline-block !important;\n  }\n  .d-xl-block {\n    display: block !important;\n  }\n  .d-xl-grid {\n    display: grid !important;\n  }\n  .d-xl-table {\n    display: table !important;\n  }\n  .d-xl-table-row {\n    display: table-row !important;\n  }\n  .d-xl-table-cell {\n    display: table-cell !important;\n  }\n  .d-xl-flex {\n    display: flex !important;\n  }\n  .d-xl-inline-flex {\n    display: inline-flex !important;\n  }\n  .d-xl-none {\n    display: none !important;\n  }\n  .flex-xl-fill {\n    flex: 1 1 auto !important;\n  }\n  .flex-xl-row {\n    flex-direction: row !important;\n  }\n  .flex-xl-column {\n    flex-direction: column !important;\n  }\n  .flex-xl-row-reverse {\n    flex-direction: row-reverse !important;\n  }\n  .flex-xl-column-reverse {\n    flex-direction: column-reverse !important;\n  }\n  .flex-xl-grow-0 {\n    flex-grow: 0 !important;\n  }\n  .flex-xl-grow-1 {\n    flex-grow: 1 !important;\n  }\n  .flex-xl-shrink-0 {\n    flex-shrink: 0 !important;\n  }\n  .flex-xl-shrink-1 {\n    flex-shrink: 1 !important;\n  }\n  .flex-xl-wrap {\n    flex-wrap: wrap !important;\n  }\n  .flex-xl-nowrap {\n    flex-wrap: nowrap !important;\n  }\n  .flex-xl-wrap-reverse {\n    flex-wrap: wrap-reverse !important;\n  }\n  .justify-content-xl-start {\n    justify-content: flex-start !important;\n  }\n  .justify-content-xl-end {\n    justify-content: flex-end !important;\n  }\n  .justify-content-xl-center {\n    justify-content: center !important;\n  }\n  .justify-content-xl-between {\n    justify-content: space-between !important;\n  }\n  .justify-content-xl-around {\n    justify-content: space-around !important;\n  }\n  .justify-content-xl-evenly {\n    justify-content: space-evenly !important;\n  }\n  .align-items-xl-start {\n    align-items: flex-start !important;\n  }\n  .align-items-xl-end {\n    align-items: flex-end !important;\n  }\n  .align-items-xl-center {\n    align-items: center !important;\n  }\n  .align-items-xl-baseline {\n    align-items: baseline !important;\n  }\n  .align-items-xl-stretch {\n    align-items: stretch !important;\n  }\n  .align-content-xl-start {\n    align-content: flex-start !important;\n  }\n  .align-content-xl-end {\n    align-content: flex-end !important;\n  }\n  .align-content-xl-center {\n    align-content: center !important;\n  }\n  .align-content-xl-between {\n    align-content: space-between !important;\n  }\n  .align-content-xl-around {\n    align-content: space-around !important;\n  }\n  .align-content-xl-stretch {\n    align-content: stretch !important;\n  }\n  .align-self-xl-auto {\n    align-self: auto !important;\n  }\n  .align-self-xl-start {\n    align-self: flex-start !important;\n  }\n  .align-self-xl-end {\n    align-self: flex-end !important;\n  }\n  .align-self-xl-center {\n    align-self: center !important;\n  }\n  .align-self-xl-baseline {\n    align-self: baseline !important;\n  }\n  .align-self-xl-stretch {\n    align-self: stretch !important;\n  }\n  .order-xl-first {\n    order: -1 !important;\n  }\n  .order-xl-0 {\n    order: 0 !important;\n  }\n  .order-xl-1 {\n    order: 1 !important;\n  }\n  .order-xl-2 {\n    order: 2 !important;\n  }\n  .order-xl-3 {\n    order: 3 !important;\n  }\n  .order-xl-4 {\n    order: 4 !important;\n  }\n  .order-xl-5 {\n    order: 5 !important;\n  }\n  .order-xl-last {\n    order: 6 !important;\n  }\n  .m-xl-0 {\n    margin: 0 !important;\n  }\n  .m-xl-1 {\n    margin: 0.25rem !important;\n  }\n  .m-xl-2 {\n    margin: 0.5rem !important;\n  }\n  .m-xl-3 {\n    margin: 1rem !important;\n  }\n  .m-xl-4 {\n    margin: 1.5rem !important;\n  }\n  .m-xl-5 {\n    margin: 3rem !important;\n  }\n  .m-xl-auto {\n    margin: auto !important;\n  }\n  .mx-xl-0 {\n    margin-right: 0 !important;\n    margin-left: 0 !important;\n  }\n  .mx-xl-1 {\n    margin-right: 0.25rem !important;\n    margin-left: 0.25rem !important;\n  }\n  .mx-xl-2 {\n    margin-right: 0.5rem !important;\n    margin-left: 0.5rem !important;\n  }\n  .mx-xl-3 {\n    margin-right: 1rem !important;\n    margin-left: 1rem !important;\n  }\n  .mx-xl-4 {\n    margin-right: 1.5rem !important;\n    margin-left: 1.5rem !important;\n  }\n  .mx-xl-5 {\n    margin-right: 3rem !important;\n    margin-left: 3rem !important;\n  }\n  .mx-xl-auto {\n    margin-right: auto !important;\n    margin-left: auto !important;\n  }\n  .my-xl-0 {\n    margin-top: 0 !important;\n    margin-bottom: 0 !important;\n  }\n  .my-xl-1 {\n    margin-top: 0.25rem !important;\n    margin-bottom: 0.25rem !important;\n  }\n  .my-xl-2 {\n    margin-top: 0.5rem !important;\n    margin-bottom: 0.5rem !important;\n  }\n  .my-xl-3 {\n    margin-top: 1rem !important;\n    margin-bottom: 1rem !important;\n  }\n  .my-xl-4 {\n    margin-top: 1.5rem !important;\n    margin-bottom: 1.5rem !important;\n  }\n  .my-xl-5 {\n    margin-top: 3rem !important;\n    margin-bottom: 3rem !important;\n  }\n  .my-xl-auto {\n    margin-top: auto !important;\n    margin-bottom: auto !important;\n  }\n  .mt-xl-0 {\n    margin-top: 0 !important;\n  }\n  .mt-xl-1 {\n    margin-top: 0.25rem !important;\n  }\n  .mt-xl-2 {\n    margin-top: 0.5rem !important;\n  }\n  .mt-xl-3 {\n    margin-top: 1rem !important;\n  }\n  .mt-xl-4 {\n    margin-top: 1.5rem !important;\n  }\n  .mt-xl-5 {\n    margin-top: 3rem !important;\n  }\n  .mt-xl-auto {\n    margin-top: auto !important;\n  }\n  .me-xl-0 {\n    margin-right: 0 !important;\n  }\n  .me-xl-1 {\n    margin-right: 0.25rem !important;\n  }\n  .me-xl-2 {\n    margin-right: 0.5rem !important;\n  }\n  .me-xl-3 {\n    margin-right: 1rem !important;\n  }\n  .me-xl-4 {\n    margin-right: 1.5rem !important;\n  }\n  .me-xl-5 {\n    margin-right: 3rem !important;\n  }\n  .me-xl-auto {\n    margin-right: auto !important;\n  }\n  .mb-xl-0 {\n    margin-bottom: 0 !important;\n  }\n  .mb-xl-1 {\n    margin-bottom: 0.25rem !important;\n  }\n  .mb-xl-2 {\n    margin-bottom: 0.5rem !important;\n  }\n  .mb-xl-3 {\n    margin-bottom: 1rem !important;\n  }\n  .mb-xl-4 {\n    margin-bottom: 1.5rem !important;\n  }\n  .mb-xl-5 {\n    margin-bottom: 3rem !important;\n  }\n  .mb-xl-auto {\n    margin-bottom: auto !important;\n  }\n  .ms-xl-0 {\n    margin-left: 0 !important;\n  }\n  .ms-xl-1 {\n    margin-left: 0.25rem !important;\n  }\n  .ms-xl-2 {\n    margin-left: 0.5rem !important;\n  }\n  .ms-xl-3 {\n    margin-left: 1rem !important;\n  }\n  .ms-xl-4 {\n    margin-left: 1.5rem !important;\n  }\n  .ms-xl-5 {\n    margin-left: 3rem !important;\n  }\n  .ms-xl-auto {\n    margin-left: auto !important;\n  }\n  .p-xl-0 {\n    padding: 0 !important;\n  }\n  .p-xl-1 {\n    padding: 0.25rem !important;\n  }\n  .p-xl-2 {\n    padding: 0.5rem !important;\n  }\n  .p-xl-3 {\n    padding: 1rem !important;\n  }\n  .p-xl-4 {\n    padding: 1.5rem !important;\n  }\n  .p-xl-5 {\n    padding: 3rem !important;\n  }\n  .px-xl-0 {\n    padding-right: 0 !important;\n    padding-left: 0 !important;\n  }\n  .px-xl-1 {\n    padding-right: 0.25rem !important;\n    padding-left: 0.25rem !important;\n  }\n  .px-xl-2 {\n    padding-right: 0.5rem !important;\n    padding-left: 0.5rem !important;\n  }\n  .px-xl-3 {\n    padding-right: 1rem !important;\n    padding-left: 1rem !important;\n  }\n  .px-xl-4 {\n    padding-right: 1.5rem !important;\n    padding-left: 1.5rem !important;\n  }\n  .px-xl-5 {\n    padding-right: 3rem !important;\n    padding-left: 3rem !important;\n  }\n  .py-xl-0 {\n    padding-top: 0 !important;\n    padding-bottom: 0 !important;\n  }\n  .py-xl-1 {\n    padding-top: 0.25rem !important;\n    padding-bottom: 0.25rem !important;\n  }\n  .py-xl-2 {\n    padding-top: 0.5rem !important;\n    padding-bottom: 0.5rem !important;\n  }\n  .py-xl-3 {\n    padding-top: 1rem !important;\n    padding-bottom: 1rem !important;\n  }\n  .py-xl-4 {\n    padding-top: 1.5rem !important;\n    padding-bottom: 1.5rem !important;\n  }\n  .py-xl-5 {\n    padding-top: 3rem !important;\n    padding-bottom: 3rem !important;\n  }\n  .pt-xl-0 {\n    padding-top: 0 !important;\n  }\n  .pt-xl-1 {\n    padding-top: 0.25rem !important;\n  }\n  .pt-xl-2 {\n    padding-top: 0.5rem !important;\n  }\n  .pt-xl-3 {\n    padding-top: 1rem !important;\n  }\n  .pt-xl-4 {\n    padding-top: 1.5rem !important;\n  }\n  .pt-xl-5 {\n    padding-top: 3rem !important;\n  }\n  .pe-xl-0 {\n    padding-right: 0 !important;\n  }\n  .pe-xl-1 {\n    padding-right: 0.25rem !important;\n  }\n  .pe-xl-2 {\n    padding-right: 0.5rem !important;\n  }\n  .pe-xl-3 {\n    padding-right: 1rem !important;\n  }\n  .pe-xl-4 {\n    padding-right: 1.5rem !important;\n  }\n  .pe-xl-5 {\n    padding-right: 3rem !important;\n  }\n  .pb-xl-0 {\n    padding-bottom: 0 !important;\n  }\n  .pb-xl-1 {\n    padding-bottom: 0.25rem !important;\n  }\n  .pb-xl-2 {\n    padding-bottom: 0.5rem !important;\n  }\n  .pb-xl-3 {\n    padding-bottom: 1rem !important;\n  }\n  .pb-xl-4 {\n    padding-bottom: 1.5rem !important;\n  }\n  .pb-xl-5 {\n    padding-bottom: 3rem !important;\n  }\n  .ps-xl-0 {\n    padding-left: 0 !important;\n  }\n  .ps-xl-1 {\n    padding-left: 0.25rem !important;\n  }\n  .ps-xl-2 {\n    padding-left: 0.5rem !important;\n  }\n  .ps-xl-3 {\n    padding-left: 1rem !important;\n  }\n  .ps-xl-4 {\n    padding-left: 1.5rem !important;\n  }\n  .ps-xl-5 {\n    padding-left: 3rem !important;\n  }\n  .gap-xl-0 {\n    gap: 0 !important;\n  }\n  .gap-xl-1 {\n    gap: 0.25rem !important;\n  }\n  .gap-xl-2 {\n    gap: 0.5rem !important;\n  }\n  .gap-xl-3 {\n    gap: 1rem !important;\n  }\n  .gap-xl-4 {\n    gap: 1.5rem !important;\n  }\n  .gap-xl-5 {\n    gap: 3rem !important;\n  }\n  .text-xl-start {\n    text-align: left !important;\n  }\n  .text-xl-end {\n    text-align: right !important;\n  }\n  .text-xl-center {\n    text-align: center !important;\n  }\n}\n@media (min-width: 1400px) {\n  .float-xxl-start {\n    float: left !important;\n  }\n  .float-xxl-end {\n    float: right !important;\n  }\n  .float-xxl-none {\n    float: none !important;\n  }\n  .d-xxl-inline {\n    display: inline !important;\n  }\n  .d-xxl-inline-block {\n    display: inline-block !important;\n  }\n  .d-xxl-block {\n    display: block !important;\n  }\n  .d-xxl-grid {\n    display: grid !important;\n  }\n  .d-xxl-table {\n    display: table !important;\n  }\n  .d-xxl-table-row {\n    display: table-row !important;\n  }\n  .d-xxl-table-cell {\n    display: table-cell !important;\n  }\n  .d-xxl-flex {\n    display: flex !important;\n  }\n  .d-xxl-inline-flex {\n    display: inline-flex !important;\n  }\n  .d-xxl-none {\n    display: none !important;\n  }\n  .flex-xxl-fill {\n    flex: 1 1 auto !important;\n  }\n  .flex-xxl-row {\n    flex-direction: row !important;\n  }\n  .flex-xxl-column {\n    flex-direction: column !important;\n  }\n  .flex-xxl-row-reverse {\n    flex-direction: row-reverse !important;\n  }\n  .flex-xxl-column-reverse {\n    flex-direction: column-reverse !important;\n  }\n  .flex-xxl-grow-0 {\n    flex-grow: 0 !important;\n  }\n  .flex-xxl-grow-1 {\n    flex-grow: 1 !important;\n  }\n  .flex-xxl-shrink-0 {\n    flex-shrink: 0 !important;\n  }\n  .flex-xxl-shrink-1 {\n    flex-shrink: 1 !important;\n  }\n  .flex-xxl-wrap {\n    flex-wrap: wrap !important;\n  }\n  .flex-xxl-nowrap {\n    flex-wrap: nowrap !important;\n  }\n  .flex-xxl-wrap-reverse {\n    flex-wrap: wrap-reverse !important;\n  }\n  .justify-content-xxl-start {\n    justify-content: flex-start !important;\n  }\n  .justify-content-xxl-end {\n    justify-content: flex-end !important;\n  }\n  .justify-content-xxl-center {\n    justify-content: center !important;\n  }\n  .justify-content-xxl-between {\n    justify-content: space-between !important;\n  }\n  .justify-content-xxl-around {\n    justify-content: space-around !important;\n  }\n  .justify-content-xxl-evenly {\n    justify-content: space-evenly !important;\n  }\n  .align-items-xxl-start {\n    align-items: flex-start !important;\n  }\n  .align-items-xxl-end {\n    align-items: flex-end !important;\n  }\n  .align-items-xxl-center {\n    align-items: center !important;\n  }\n  .align-items-xxl-baseline {\n    align-items: baseline !important;\n  }\n  .align-items-xxl-stretch {\n    align-items: stretch !important;\n  }\n  .align-content-xxl-start {\n    align-content: flex-start !important;\n  }\n  .align-content-xxl-end {\n    align-content: flex-end !important;\n  }\n  .align-content-xxl-center {\n    align-content: center !important;\n  }\n  .align-content-xxl-between {\n    align-content: space-between !important;\n  }\n  .align-content-xxl-around {\n    align-content: space-around !important;\n  }\n  .align-content-xxl-stretch {\n    align-content: stretch !important;\n  }\n  .align-self-xxl-auto {\n    align-self: auto !important;\n  }\n  .align-self-xxl-start {\n    align-self: flex-start !important;\n  }\n  .align-self-xxl-end {\n    align-self: flex-end !important;\n  }\n  .align-self-xxl-center {\n    align-self: center !important;\n  }\n  .align-self-xxl-baseline {\n    align-self: baseline !important;\n  }\n  .align-self-xxl-stretch {\n    align-self: stretch !important;\n  }\n  .order-xxl-first {\n    order: -1 !important;\n  }\n  .order-xxl-0 {\n    order: 0 !important;\n  }\n  .order-xxl-1 {\n    order: 1 !important;\n  }\n  .order-xxl-2 {\n    order: 2 !important;\n  }\n  .order-xxl-3 {\n    order: 3 !important;\n  }\n  .order-xxl-4 {\n    order: 4 !important;\n  }\n  .order-xxl-5 {\n    order: 5 !important;\n  }\n  .order-xxl-last {\n    order: 6 !important;\n  }\n  .m-xxl-0 {\n    margin: 0 !important;\n  }\n  .m-xxl-1 {\n    margin: 0.25rem !important;\n  }\n  .m-xxl-2 {\n    margin: 0.5rem !important;\n  }\n  .m-xxl-3 {\n    margin: 1rem !important;\n  }\n  .m-xxl-4 {\n    margin: 1.5rem !important;\n  }\n  .m-xxl-5 {\n    margin: 3rem !important;\n  }\n  .m-xxl-auto {\n    margin: auto !important;\n  }\n  .mx-xxl-0 {\n    margin-right: 0 !important;\n    margin-left: 0 !important;\n  }\n  .mx-xxl-1 {\n    margin-right: 0.25rem !important;\n    margin-left: 0.25rem !important;\n  }\n  .mx-xxl-2 {\n    margin-right: 0.5rem !important;\n    margin-left: 0.5rem !important;\n  }\n  .mx-xxl-3 {\n    margin-right: 1rem !important;\n    margin-left: 1rem !important;\n  }\n  .mx-xxl-4 {\n    margin-right: 1.5rem !important;\n    margin-left: 1.5rem !important;\n  }\n  .mx-xxl-5 {\n    margin-right: 3rem !important;\n    margin-left: 3rem !important;\n  }\n  .mx-xxl-auto {\n    margin-right: auto !important;\n    margin-left: auto !important;\n  }\n  .my-xxl-0 {\n    margin-top: 0 !important;\n    margin-bottom: 0 !important;\n  }\n  .my-xxl-1 {\n    margin-top: 0.25rem !important;\n    margin-bottom: 0.25rem !important;\n  }\n  .my-xxl-2 {\n    margin-top: 0.5rem !important;\n    margin-bottom: 0.5rem !important;\n  }\n  .my-xxl-3 {\n    margin-top: 1rem !important;\n    margin-bottom: 1rem !important;\n  }\n  .my-xxl-4 {\n    margin-top: 1.5rem !important;\n    margin-bottom: 1.5rem !important;\n  }\n  .my-xxl-5 {\n    margin-top: 3rem !important;\n    margin-bottom: 3rem !important;\n  }\n  .my-xxl-auto {\n    margin-top: auto !important;\n    margin-bottom: auto !important;\n  }\n  .mt-xxl-0 {\n    margin-top: 0 !important;\n  }\n  .mt-xxl-1 {\n    margin-top: 0.25rem !important;\n  }\n  .mt-xxl-2 {\n    margin-top: 0.5rem !important;\n  }\n  .mt-xxl-3 {\n    margin-top: 1rem !important;\n  }\n  .mt-xxl-4 {\n    margin-top: 1.5rem !important;\n  }\n  .mt-xxl-5 {\n    margin-top: 3rem !important;\n  }\n  .mt-xxl-auto {\n    margin-top: auto !important;\n  }\n  .me-xxl-0 {\n    margin-right: 0 !important;\n  }\n  .me-xxl-1 {\n    margin-right: 0.25rem !important;\n  }\n  .me-xxl-2 {\n    margin-right: 0.5rem !important;\n  }\n  .me-xxl-3 {\n    margin-right: 1rem !important;\n  }\n  .me-xxl-4 {\n    margin-right: 1.5rem !important;\n  }\n  .me-xxl-5 {\n    margin-right: 3rem !important;\n  }\n  .me-xxl-auto {\n    margin-right: auto !important;\n  }\n  .mb-xxl-0 {\n    margin-bottom: 0 !important;\n  }\n  .mb-xxl-1 {\n    margin-bottom: 0.25rem !important;\n  }\n  .mb-xxl-2 {\n    margin-bottom: 0.5rem !important;\n  }\n  .mb-xxl-3 {\n    margin-bottom: 1rem !important;\n  }\n  .mb-xxl-4 {\n    margin-bottom: 1.5rem !important;\n  }\n  .mb-xxl-5 {\n    margin-bottom: 3rem !important;\n  }\n  .mb-xxl-auto {\n    margin-bottom: auto !important;\n  }\n  .ms-xxl-0 {\n    margin-left: 0 !important;\n  }\n  .ms-xxl-1 {\n    margin-left: 0.25rem !important;\n  }\n  .ms-xxl-2 {\n    margin-left: 0.5rem !important;\n  }\n  .ms-xxl-3 {\n    margin-left: 1rem !important;\n  }\n  .ms-xxl-4 {\n    margin-left: 1.5rem !important;\n  }\n  .ms-xxl-5 {\n    margin-left: 3rem !important;\n  }\n  .ms-xxl-auto {\n    margin-left: auto !important;\n  }\n  .p-xxl-0 {\n    padding: 0 !important;\n  }\n  .p-xxl-1 {\n    padding: 0.25rem !important;\n  }\n  .p-xxl-2 {\n    padding: 0.5rem !important;\n  }\n  .p-xxl-3 {\n    padding: 1rem !important;\n  }\n  .p-xxl-4 {\n    padding: 1.5rem !important;\n  }\n  .p-xxl-5 {\n    padding: 3rem !important;\n  }\n  .px-xxl-0 {\n    padding-right: 0 !important;\n    padding-left: 0 !important;\n  }\n  .px-xxl-1 {\n    padding-right: 0.25rem !important;\n    padding-left: 0.25rem !important;\n  }\n  .px-xxl-2 {\n    padding-right: 0.5rem !important;\n    padding-left: 0.5rem !important;\n  }\n  .px-xxl-3 {\n    padding-right: 1rem !important;\n    padding-left: 1rem !important;\n  }\n  .px-xxl-4 {\n    padding-right: 1.5rem !important;\n    padding-left: 1.5rem !important;\n  }\n  .px-xxl-5 {\n    padding-right: 3rem !important;\n    padding-left: 3rem !important;\n  }\n  .py-xxl-0 {\n    padding-top: 0 !important;\n    padding-bottom: 0 !important;\n  }\n  .py-xxl-1 {\n    padding-top: 0.25rem !important;\n    padding-bottom: 0.25rem !important;\n  }\n  .py-xxl-2 {\n    padding-top: 0.5rem !important;\n    padding-bottom: 0.5rem !important;\n  }\n  .py-xxl-3 {\n    padding-top: 1rem !important;\n    padding-bottom: 1rem !important;\n  }\n  .py-xxl-4 {\n    padding-top: 1.5rem !important;\n    padding-bottom: 1.5rem !important;\n  }\n  .py-xxl-5 {\n    padding-top: 3rem !important;\n    padding-bottom: 3rem !important;\n  }\n  .pt-xxl-0 {\n    padding-top: 0 !important;\n  }\n  .pt-xxl-1 {\n    padding-top: 0.25rem !important;\n  }\n  .pt-xxl-2 {\n    padding-top: 0.5rem !important;\n  }\n  .pt-xxl-3 {\n    padding-top: 1rem !important;\n  }\n  .pt-xxl-4 {\n    padding-top: 1.5rem !important;\n  }\n  .pt-xxl-5 {\n    padding-top: 3rem !important;\n  }\n  .pe-xxl-0 {\n    padding-right: 0 !important;\n  }\n  .pe-xxl-1 {\n    padding-right: 0.25rem !important;\n  }\n  .pe-xxl-2 {\n    padding-right: 0.5rem !important;\n  }\n  .pe-xxl-3 {\n    padding-right: 1rem !important;\n  }\n  .pe-xxl-4 {\n    padding-right: 1.5rem !important;\n  }\n  .pe-xxl-5 {\n    padding-right: 3rem !important;\n  }\n  .pb-xxl-0 {\n    padding-bottom: 0 !important;\n  }\n  .pb-xxl-1 {\n    padding-bottom: 0.25rem !important;\n  }\n  .pb-xxl-2 {\n    padding-bottom: 0.5rem !important;\n  }\n  .pb-xxl-3 {\n    padding-bottom: 1rem !important;\n  }\n  .pb-xxl-4 {\n    padding-bottom: 1.5rem !important;\n  }\n  .pb-xxl-5 {\n    padding-bottom: 3rem !important;\n  }\n  .ps-xxl-0 {\n    padding-left: 0 !important;\n  }\n  .ps-xxl-1 {\n    padding-left: 0.25rem !important;\n  }\n  .ps-xxl-2 {\n    padding-left: 0.5rem !important;\n  }\n  .ps-xxl-3 {\n    padding-left: 1rem !important;\n  }\n  .ps-xxl-4 {\n    padding-left: 1.5rem !important;\n  }\n  .ps-xxl-5 {\n    padding-left: 3rem !important;\n  }\n  .gap-xxl-0 {\n    gap: 0 !important;\n  }\n  .gap-xxl-1 {\n    gap: 0.25rem !important;\n  }\n  .gap-xxl-2 {\n    gap: 0.5rem !important;\n  }\n  .gap-xxl-3 {\n    gap: 1rem !important;\n  }\n  .gap-xxl-4 {\n    gap: 1.5rem !important;\n  }\n  .gap-xxl-5 {\n    gap: 3rem !important;\n  }\n  .text-xxl-start {\n    text-align: left !important;\n  }\n  .text-xxl-end {\n    text-align: right !important;\n  }\n  .text-xxl-center {\n    text-align: center !important;\n  }\n}\n@media (min-width: 1200px) {\n  .fs-1 {\n    font-size: 2.5rem !important;\n  }\n  .fs-2 {\n    font-size: 2rem !important;\n  }\n  .fs-3 {\n    font-size: 1.75rem !important;\n  }\n  .fs-4 {\n    font-size: 1.5rem !important;\n  }\n}\n@media print {\n  .d-print-inline {\n    display: inline !important;\n  }\n  .d-print-inline-block {\n    display: inline-block !important;\n  }\n  .d-print-block {\n    display: block !important;\n  }\n  .d-print-grid {\n    display: grid !important;\n  }\n  .d-print-table {\n    display: table !important;\n  }\n  .d-print-table-row {\n    display: table-row !important;\n  }\n  .d-print-table-cell {\n    display: table-cell !important;\n  }\n  .d-print-flex {\n    display: flex !important;\n  }\n  .d-print-inline-flex {\n    display: inline-flex !important;\n  }\n  .d-print-none {\n    display: none !important;\n  }\n}\nhtml {\n  height: 100%;\n  scroll-padding-top: calc(4.5rem - 1px);\n}\n\n.page-section {\n  padding: 6rem 0;\n}\n.page-section .page-section-heading {\n  font-size: 2.25rem;\n  line-height: 2rem;\n}\n@media (min-width: 992px) {\n  .page-section .page-section-heading {\n    font-size: 3rem;\n    line-height: 2.5rem;\n  }\n}\n\n.divider-custom {\n  margin: 1.25rem 0 1.5rem;\n  width: 100%;\n  display: flex;\n  justify-content: center;\n  align-items: center;\n}\n.divider-custom .divider-custom-line {\n  width: 100%;\n  max-width: 7rem;\n  height: 0.25rem;\n  background-color: #2c3e50;\n  border-radius: 1rem;\n  border-color: #2c3e50;\n}\n.divider-custom .divider-custom-line:first-child {\n  margin-right: 1rem;\n}\n.divider-custom .divider-custom-line:last-child {\n  margin-left: 1rem;\n}\n.divider-custom .divider-custom-icon {\n  color: #2c3e50;\n  font-size: 2rem;\n}\n.divider-custom.divider-light .divider-custom-line {\n  background-color: #fff;\n}\n.divider-custom.divider-light .divider-custom-icon {\n  color: #fff;\n}\n\n.btn-xl {\n  padding: 1rem 1.75rem;\n  font-size: 1.25rem;\n}\n\n.btn-social {\n  border-radius: 100%;\n  display: inline-flex;\n  width: 3.25rem;\n  height: 3.25rem;\n  font-size: 1.25rem;\n  justify-content: center;\n  align-items: center;\n}\n\n#mainNav {\n  padding-top: 1rem;\n  padding-bottom: 1rem;\n  font-family: \"Montserrat\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n  font-weight: 700;\n}\n#mainNav .navbar-brand {\n  color: #fff;\n}\n#mainNav .navbar-nav {\n  margin-top: 1rem;\n}\n#mainNav .navbar-nav li.nav-item a.nav-link {\n  color: #fff;\n}\n#mainNav .navbar-nav li.nav-item a.nav-link:hover {\n  color: #1abc9c;\n}\n#mainNav .navbar-nav li.nav-item a.nav-link:active, #mainNav .navbar-nav li.nav-item a.nav-link:focus {\n  color: #fff;\n}\n#mainNav .navbar-nav li.nav-item a.nav-link.active {\n  color: #1abc9c;\n}\n#mainNav .navbar-toggler {\n  font-size: 80%;\n  padding: 0.8rem;\n}\n\n@media (min-width: 992px) {\n  #mainNav {\n    padding-top: 1.5rem;\n    padding-bottom: 1.5rem;\n    transition: padding-top 0.3s, padding-bottom 0.3s;\n  }\n  #mainNav .navbar-brand {\n    font-size: 1.75em;\n    transition: font-size 0.3s;\n  }\n  #mainNav .navbar-nav {\n    margin-top: 0;\n  }\n  #mainNav .navbar-nav > li.nav-item > a.nav-link.active {\n    color: #fff;\n    background: #1abc9c;\n  }\n  #mainNav .navbar-nav > li.nav-item > a.nav-link.active:active, #mainNav .navbar-nav > li.nav-item > a.nav-link.active:focus, #mainNav .navbar-nav > li.nav-item > a.nav-link.active:hover {\n    color: #fff;\n    background: #1abc9c;\n  }\n  #mainNav.navbar-shrink {\n    padding-top: 0.5rem;\n    padding-bottom: 0.5rem;\n  }\n  #mainNav.navbar-shrink .navbar-brand {\n    font-size: 1.5em;\n  }\n}\n.form-floating input.form-control,\n.form-floating textarea.form-control {\n  font-size: 1.5rem;\n  border-left: 0;\n  border-right: 0;\n  border-top: 0;\n  border-radius: 0;\n  border-width: 1px;\n}\n.form-floating input.form-control:focus,\n.form-floating textarea.form-control:focus {\n  box-shadow: none;\n}\n.form-floating label {\n  font-size: 1.5rem;\n  color: #6c757d;\n}\n\n.masthead {\n  padding-top: calc(6rem + 74px);\n  padding-bottom: 6rem;\n}\n.masthead .masthead-heading {\n  font-size: 2.75rem;\n  line-height: 2.75rem;\n}\n.masthead .masthead-subheading {\n  font-size: 1.25rem;\n}\n.masthead .masthead-avatar {\n  width: 15rem;\n}\n\n@media (min-width: 992px) {\n  .masthead {\n    padding-top: calc(6rem + 104px);\n    padding-bottom: 6rem;\n  }\n  .masthead .masthead-heading {\n    font-size: 4rem;\n    line-height: 3.5rem;\n  }\n  .masthead .masthead-subheading {\n    font-size: 1.5rem;\n  }\n}\n.portfolio .portfolio-item {\n  cursor: pointer;\n  position: relative;\n  display: block;\n  max-width: 25rem;\n  border-radius: 0.5rem;\n  overflow: hidden;\n}\n.portfolio .portfolio-item .portfolio-item-caption {\n  position: absolute;\n  top: 0;\n  left: 0;\n  transition: all 0.2s ease-in-out;\n  opacity: 0;\n  background-color: rgba(26, 188, 156, 0.9);\n}\n.portfolio .portfolio-item .portfolio-item-caption:hover {\n  opacity: 1;\n}\n.portfolio .portfolio-item .portfolio-item-caption .portfolio-item-caption-content {\n  font-size: 1.5rem;\n}\n\n.portfolio-modal .btn-close {\n  color: #1abc9c;\n  font-size: 2rem;\n  padding: 1rem;\n}\n.portfolio-modal .portfolio-modal-title {\n  font-size: 2.25rem;\n  line-height: 2rem;\n}\n@media (min-width: 992px) {\n  .portfolio-modal .portfolio-modal-title {\n    font-size: 3rem;\n    line-height: 2.5rem;\n  }\n}\n\n.footer {\n  padding-top: 5rem;\n  padding-bottom: 5rem;\n  background-color: #2c3e50;\n  color: #fff;\n}\n\n.copyright {\n  background-color: #1a252f;\n}"
  },
  {
    "path": "samples/s3-cloudfront-static-website/website/error.html",
    "content": "<!DOCTYPE html>\r\n<html lang=\"en\">\r\n    <head>\r\n        <meta charset=\"utf-8\" />\r\n        <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, shrink-to-fit=no\" />\r\n        <meta name=\"description\" content=\"\" />\r\n        <meta name=\"author\" content=\"\" />\r\n        <title>Freelancer - Start Bootstrap Theme</title>\r\n        <!-- Favicon-->\r\n        <link rel=\"icon\" type=\"image/x-icon\" href=\"assets/favicon.ico\" />\r\n        <!-- Font Awesome icons (free version)-->\r\n        <script src=\"https://use.fontawesome.com/releases/v6.3.0/js/all.js\" crossorigin=\"anonymous\"></script>\r\n        <!-- Google fonts-->\r\n        <link href=\"https://fonts.googleapis.com/css?family=Montserrat:400,700\" rel=\"stylesheet\" type=\"text/css\" />\r\n        <link href=\"https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic\" rel=\"stylesheet\" type=\"text/css\" />\r\n        <!-- Core theme CSS (includes Bootstrap)-->\r\n        <link href=\"css/styles.css\" rel=\"stylesheet\" />\r\n    </head>\r\n    <body id=\"page-top\">\r\n        <!-- Navigation-->\r\n        <nav class=\"navbar navbar-expand-lg bg-secondary text-uppercase fixed-top\" id=\"mainNav\">\r\n            <div class=\"container\">\r\n                <a class=\"navbar-brand\" href=\"#page-top\">Start Bootstrap</a>\r\n                <button class=\"navbar-toggler text-uppercase font-weight-bold bg-primary text-white rounded\" type=\"button\" data-bs-toggle=\"collapse\" data-bs-target=\"#navbarResponsive\" aria-controls=\"navbarResponsive\" aria-expanded=\"false\" aria-label=\"Toggle navigation\">\r\n                    Menu\r\n                    <i class=\"fas fa-bars\"></i>\r\n                </button>\r\n                <div class=\"collapse navbar-collapse\" id=\"navbarResponsive\">\r\n                    <ul class=\"navbar-nav ms-auto\">\r\n                        <li class=\"nav-item mx-0 mx-lg-1\"><a class=\"nav-link py-3 px-0 px-lg-3 rounded\" href=\"#portfolio\">Portfolio</a></li>\r\n                        <li class=\"nav-item mx-0 mx-lg-1\"><a class=\"nav-link py-3 px-0 px-lg-3 rounded\" href=\"#about\">About</a></li>\r\n                        <li class=\"nav-item mx-0 mx-lg-1\"><a class=\"nav-link py-3 px-0 px-lg-3 rounded\" href=\"#contact\">Contact</a></li>\r\n                    </ul>\r\n                </div>\r\n            </div>\r\n        </nav>\r\n        <!-- Masthead-->\r\n        <header class=\"masthead bg-primary text-white text-center\">\r\n            <div class=\"container d-flex align-items-center flex-column\">\r\n                <!-- Masthead Avatar Image-->\r\n                <img class=\"masthead-avatar mb-5\" src=\"assets/img/avataaars.svg\" alt=\"...\" />\r\n                <!-- Masthead Heading-->\r\n                <h1 class=\"masthead-heading text-uppercase mb-0\">404 Error</h1>\r\n                <!-- Icon Divider-->\r\n                <div class=\"divider-custom divider-light\">\r\n                    <div class=\"divider-custom-line\"></div>\r\n                    <div class=\"divider-custom-icon\"><i class=\"fas fa-star\"></i></div>\r\n                    <div class=\"divider-custom-line\"></div>\r\n                </div>\r\n                <!-- Masthead Subheading-->\r\n                <p class=\"masthead-subheading font-weight-light mb-0\">Error Occured!</p>\r\n            </div>\r\n        </header>\r\n        <!-- Footer-->\r\n        <footer class=\"footer text-center\">\r\n            <div class=\"container\">\r\n                <div class=\"row\">\r\n                    <!-- Footer Location-->\r\n                    <div class=\"col-lg-4 mb-5 mb-lg-0\">\r\n                        <h4 class=\"text-uppercase mb-4\">Location</h4>\r\n                        <p class=\"lead mb-0\">\r\n                            2215 John Daniel Drive\r\n                            <br />\r\n                            Clark, MO 65243\r\n                        </p>\r\n                    </div>\r\n                    <!-- Footer Social Icons-->\r\n                    <div class=\"col-lg-4 mb-5 mb-lg-0\">\r\n                        <h4 class=\"text-uppercase mb-4\">Around the Web</h4>\r\n                        <a class=\"btn btn-outline-light btn-social mx-1\" href=\"#!\"><i class=\"fab fa-fw fa-facebook-f\"></i></a>\r\n                        <a class=\"btn btn-outline-light btn-social mx-1\" href=\"#!\"><i class=\"fab fa-fw fa-twitter\"></i></a>\r\n                        <a class=\"btn btn-outline-light btn-social mx-1\" href=\"#!\"><i class=\"fab fa-fw fa-linkedin-in\"></i></a>\r\n                        <a class=\"btn btn-outline-light btn-social mx-1\" href=\"#!\"><i class=\"fab fa-fw fa-dribbble\"></i></a>\r\n                    </div>\r\n                    <!-- Footer About Text-->\r\n                    <div class=\"col-lg-4\">\r\n                        <h4 class=\"text-uppercase mb-4\">About Freelancer</h4>\r\n                        <p class=\"lead mb-0\">\r\n                            Freelance is a free to use, MIT licensed Bootstrap theme created by\r\n                            <a href=\"http://startbootstrap.com\">Start Bootstrap</a>\r\n                            .\r\n                        </p>\r\n                    </div>\r\n                </div>\r\n            </div>\r\n        </footer>\r\n        <!-- Copyright Section-->\r\n        <div class=\"copyright py-4 text-center text-white\">\r\n            <div class=\"container\"><small>Copyright &copy; Your Website 2023</small></div>\r\n        </div>\r\n        <!-- Portfolio Modals-->\r\n        <!-- Portfolio Modal 1-->\r\n        <div class=\"portfolio-modal modal fade\" id=\"portfolioModal1\" tabindex=\"-1\" aria-labelledby=\"portfolioModal1\" aria-hidden=\"true\">\r\n            <div class=\"modal-dialog modal-xl\">\r\n                <div class=\"modal-content\">\r\n                    <div class=\"modal-header border-0\"><button class=\"btn-close\" type=\"button\" data-bs-dismiss=\"modal\" aria-label=\"Close\"></button></div>\r\n                    <div class=\"modal-body text-center pb-5\">\r\n                        <div class=\"container\">\r\n                            <div class=\"row justify-content-center\">\r\n                                <div class=\"col-lg-8\">\r\n                                    <!-- Portfolio Modal - Title-->\r\n                                    <h2 class=\"portfolio-modal-title text-secondary text-uppercase mb-0\">Log Cabin</h2>\r\n                                    <!-- Icon Divider-->\r\n                                    <div class=\"divider-custom\">\r\n                                        <div class=\"divider-custom-line\"></div>\r\n                                        <div class=\"divider-custom-icon\"><i class=\"fas fa-star\"></i></div>\r\n                                        <div class=\"divider-custom-line\"></div>\r\n                                    </div>\r\n                                    <!-- Portfolio Modal - Image-->\r\n                                    <img class=\"img-fluid rounded mb-5\" src=\"assets/img/portfolio/cabin.png\" alt=\"...\" />\r\n                                    <!-- Portfolio Modal - Text-->\r\n                                    <p class=\"mb-4\">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Mollitia neque assumenda ipsam nihil, molestias magnam, recusandae quos quis inventore quisquam velit asperiores, vitae? Reprehenderit soluta, eos quod consequuntur itaque. Nam.</p>\r\n                                    <button class=\"btn btn-primary\" data-bs-dismiss=\"modal\">\r\n                                        <i class=\"fas fa-xmark fa-fw\"></i>\r\n                                        Close Window\r\n                                    </button>\r\n                                </div>\r\n                            </div>\r\n                        </div>\r\n                    </div>\r\n                </div>\r\n            </div>\r\n        </div>\r\n        <!-- Portfolio Modal 2-->\r\n        <div class=\"portfolio-modal modal fade\" id=\"portfolioModal2\" tabindex=\"-1\" aria-labelledby=\"portfolioModal2\" aria-hidden=\"true\">\r\n            <div class=\"modal-dialog modal-xl\">\r\n                <div class=\"modal-content\">\r\n                    <div class=\"modal-header border-0\"><button class=\"btn-close\" type=\"button\" data-bs-dismiss=\"modal\" aria-label=\"Close\"></button></div>\r\n                    <div class=\"modal-body text-center pb-5\">\r\n                        <div class=\"container\">\r\n                            <div class=\"row justify-content-center\">\r\n                                <div class=\"col-lg-8\">\r\n                                    <!-- Portfolio Modal - Title-->\r\n                                    <h2 class=\"portfolio-modal-title text-secondary text-uppercase mb-0\">Tasty Cake</h2>\r\n                                    <!-- Icon Divider-->\r\n                                    <div class=\"divider-custom\">\r\n                                        <div class=\"divider-custom-line\"></div>\r\n                                        <div class=\"divider-custom-icon\"><i class=\"fas fa-star\"></i></div>\r\n                                        <div class=\"divider-custom-line\"></div>\r\n                                    </div>\r\n                                    <!-- Portfolio Modal - Image-->\r\n                                    <img class=\"img-fluid rounded mb-5\" src=\"assets/img/portfolio/cake.png\" alt=\"...\" />\r\n                                    <!-- Portfolio Modal - Text-->\r\n                                    <p class=\"mb-4\">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Mollitia neque assumenda ipsam nihil, molestias magnam, recusandae quos quis inventore quisquam velit asperiores, vitae? Reprehenderit soluta, eos quod consequuntur itaque. Nam.</p>\r\n                                    <button class=\"btn btn-primary\" data-bs-dismiss=\"modal\">\r\n                                        <i class=\"fas fa-xmark fa-fw\"></i>\r\n                                        Close Window\r\n                                    </button>\r\n                                </div>\r\n                            </div>\r\n                        </div>\r\n                    </div>\r\n                </div>\r\n            </div>\r\n        </div>\r\n        <!-- Portfolio Modal 3-->\r\n        <div class=\"portfolio-modal modal fade\" id=\"portfolioModal3\" tabindex=\"-1\" aria-labelledby=\"portfolioModal3\" aria-hidden=\"true\">\r\n            <div class=\"modal-dialog modal-xl\">\r\n                <div class=\"modal-content\">\r\n                    <div class=\"modal-header border-0\"><button class=\"btn-close\" type=\"button\" data-bs-dismiss=\"modal\" aria-label=\"Close\"></button></div>\r\n                    <div class=\"modal-body text-center pb-5\">\r\n                        <div class=\"container\">\r\n                            <div class=\"row justify-content-center\">\r\n                                <div class=\"col-lg-8\">\r\n                                    <!-- Portfolio Modal - Title-->\r\n                                    <h2 class=\"portfolio-modal-title text-secondary text-uppercase mb-0\">Circus Tent</h2>\r\n                                    <!-- Icon Divider-->\r\n                                    <div class=\"divider-custom\">\r\n                                        <div class=\"divider-custom-line\"></div>\r\n                                        <div class=\"divider-custom-icon\"><i class=\"fas fa-star\"></i></div>\r\n                                        <div class=\"divider-custom-line\"></div>\r\n                                    </div>\r\n                                    <!-- Portfolio Modal - Image-->\r\n                                    <img class=\"img-fluid rounded mb-5\" src=\"assets/img/portfolio/circus.png\" alt=\"...\" />\r\n                                    <!-- Portfolio Modal - Text-->\r\n                                    <p class=\"mb-4\">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Mollitia neque assumenda ipsam nihil, molestias magnam, recusandae quos quis inventore quisquam velit asperiores, vitae? Reprehenderit soluta, eos quod consequuntur itaque. Nam.</p>\r\n                                    <button class=\"btn btn-primary\" data-bs-dismiss=\"modal\">\r\n                                        <i class=\"fas fa-xmark fa-fw\"></i>\r\n                                        Close Window\r\n                                    </button>\r\n                                </div>\r\n                            </div>\r\n                        </div>\r\n                    </div>\r\n                </div>\r\n            </div>\r\n        </div>\r\n        <!-- Portfolio Modal 4-->\r\n        <div class=\"portfolio-modal modal fade\" id=\"portfolioModal4\" tabindex=\"-1\" aria-labelledby=\"portfolioModal4\" aria-hidden=\"true\">\r\n            <div class=\"modal-dialog modal-xl\">\r\n                <div class=\"modal-content\">\r\n                    <div class=\"modal-header border-0\"><button class=\"btn-close\" type=\"button\" data-bs-dismiss=\"modal\" aria-label=\"Close\"></button></div>\r\n                    <div class=\"modal-body text-center pb-5\">\r\n                        <div class=\"container\">\r\n                            <div class=\"row justify-content-center\">\r\n                                <div class=\"col-lg-8\">\r\n                                    <!-- Portfolio Modal - Title-->\r\n                                    <h2 class=\"portfolio-modal-title text-secondary text-uppercase mb-0\">Controller</h2>\r\n                                    <!-- Icon Divider-->\r\n                                    <div class=\"divider-custom\">\r\n                                        <div class=\"divider-custom-line\"></div>\r\n                                        <div class=\"divider-custom-icon\"><i class=\"fas fa-star\"></i></div>\r\n                                        <div class=\"divider-custom-line\"></div>\r\n                                    </div>\r\n                                    <!-- Portfolio Modal - Image-->\r\n                                    <img class=\"img-fluid rounded mb-5\" src=\"assets/img/portfolio/game.png\" alt=\"...\" />\r\n                                    <!-- Portfolio Modal - Text-->\r\n                                    <p class=\"mb-4\">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Mollitia neque assumenda ipsam nihil, molestias magnam, recusandae quos quis inventore quisquam velit asperiores, vitae? Reprehenderit soluta, eos quod consequuntur itaque. Nam.</p>\r\n                                    <button class=\"btn btn-primary\" data-bs-dismiss=\"modal\">\r\n                                        <i class=\"fas fa-xmark fa-fw\"></i>\r\n                                        Close Window\r\n                                    </button>\r\n                                </div>\r\n                            </div>\r\n                        </div>\r\n                    </div>\r\n                </div>\r\n            </div>\r\n        </div>\r\n        <!-- Portfolio Modal 5-->\r\n        <div class=\"portfolio-modal modal fade\" id=\"portfolioModal5\" tabindex=\"-1\" aria-labelledby=\"portfolioModal5\" aria-hidden=\"true\">\r\n            <div class=\"modal-dialog modal-xl\">\r\n                <div class=\"modal-content\">\r\n                    <div class=\"modal-header border-0\"><button class=\"btn-close\" type=\"button\" data-bs-dismiss=\"modal\" aria-label=\"Close\"></button></div>\r\n                    <div class=\"modal-body text-center pb-5\">\r\n                        <div class=\"container\">\r\n                            <div class=\"row justify-content-center\">\r\n                                <div class=\"col-lg-8\">\r\n                                    <!-- Portfolio Modal - Title-->\r\n                                    <h2 class=\"portfolio-modal-title text-secondary text-uppercase mb-0\">Locked Safe</h2>\r\n                                    <!-- Icon Divider-->\r\n                                    <div class=\"divider-custom\">\r\n                                        <div class=\"divider-custom-line\"></div>\r\n                                        <div class=\"divider-custom-icon\"><i class=\"fas fa-star\"></i></div>\r\n                                        <div class=\"divider-custom-line\"></div>\r\n                                    </div>\r\n                                    <!-- Portfolio Modal - Image-->\r\n                                    <img class=\"img-fluid rounded mb-5\" src=\"assets/img/portfolio/safe.png\" alt=\"...\" />\r\n                                    <!-- Portfolio Modal - Text-->\r\n                                    <p class=\"mb-4\">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Mollitia neque assumenda ipsam nihil, molestias magnam, recusandae quos quis inventore quisquam velit asperiores, vitae? Reprehenderit soluta, eos quod consequuntur itaque. Nam.</p>\r\n                                    <button class=\"btn btn-primary\" data-bs-dismiss=\"modal\">\r\n                                        <i class=\"fas fa-xmark fa-fw\"></i>\r\n                                        Close Window\r\n                                    </button>\r\n                                </div>\r\n                            </div>\r\n                        </div>\r\n                    </div>\r\n                </div>\r\n            </div>\r\n        </div>\r\n        <!-- Portfolio Modal 6-->\r\n        <div class=\"portfolio-modal modal fade\" id=\"portfolioModal6\" tabindex=\"-1\" aria-labelledby=\"portfolioModal6\" aria-hidden=\"true\">\r\n            <div class=\"modal-dialog modal-xl\">\r\n                <div class=\"modal-content\">\r\n                    <div class=\"modal-header border-0\"><button class=\"btn-close\" type=\"button\" data-bs-dismiss=\"modal\" aria-label=\"Close\"></button></div>\r\n                    <div class=\"modal-body text-center pb-5\">\r\n                        <div class=\"container\">\r\n                            <div class=\"row justify-content-center\">\r\n                                <div class=\"col-lg-8\">\r\n                                    <!-- Portfolio Modal - Title-->\r\n                                    <h2 class=\"portfolio-modal-title text-secondary text-uppercase mb-0\">Submarine</h2>\r\n                                    <!-- Icon Divider-->\r\n                                    <div class=\"divider-custom\">\r\n                                        <div class=\"divider-custom-line\"></div>\r\n                                        <div class=\"divider-custom-icon\"><i class=\"fas fa-star\"></i></div>\r\n                                        <div class=\"divider-custom-line\"></div>\r\n                                    </div>\r\n                                    <!-- Portfolio Modal - Image-->\r\n                                    <img class=\"img-fluid rounded mb-5\" src=\"assets/img/portfolio/submarine.png\" alt=\"...\" />\r\n                                    <!-- Portfolio Modal - Text-->\r\n                                    <p class=\"mb-4\">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Mollitia neque assumenda ipsam nihil, molestias magnam, recusandae quos quis inventore quisquam velit asperiores, vitae? Reprehenderit soluta, eos quod consequuntur itaque. Nam.</p>\r\n                                    <button class=\"btn btn-primary\" data-bs-dismiss=\"modal\">\r\n                                        <i class=\"fas fa-xmark fa-fw\"></i>\r\n                                        Close Window\r\n                                    </button>\r\n                                </div>\r\n                            </div>\r\n                        </div>\r\n                    </div>\r\n                </div>\r\n            </div>\r\n        </div>\r\n        <!-- Bootstrap core JS-->\r\n        <script src=\"https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js\"></script>\r\n        <!-- Core theme JS-->\r\n        <script src=\"js/scripts.js\"></script>\r\n        <!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *-->\r\n        <!-- * *                               SB Forms JS                               * *-->\r\n        <!-- * * Activate your form at https://startbootstrap.com/solution/contact-forms * *-->\r\n        <!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *-->\r\n        <script src=\"https://cdn.startbootstrap.com/sb-forms-latest.js\"></script>\r\n    </body>\r\n</html>\r\n"
  },
  {
    "path": "samples/s3-cloudfront-static-website/website/index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n    <head>\n        <meta charset=\"utf-8\" />\n        <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, shrink-to-fit=no\" />\n        <meta name=\"description\" content=\"\" />\n        <meta name=\"author\" content=\"\" />\n        <title>Freelancer - Start Bootstrap Theme</title>\n        <!-- Favicon-->\n        <link rel=\"icon\" type=\"image/x-icon\" href=\"assets/favicon.ico\" />\n        <!-- Font Awesome icons (free version)-->\n        <script src=\"https://use.fontawesome.com/releases/v6.3.0/js/all.js\" crossorigin=\"anonymous\"></script>\n        <!-- Google fonts-->\n        <link href=\"https://fonts.googleapis.com/css?family=Montserrat:400,700\" rel=\"stylesheet\" type=\"text/css\" />\n        <link href=\"https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic\" rel=\"stylesheet\" type=\"text/css\" />\n        <!-- Core theme CSS (includes Bootstrap)-->\n        <link href=\"css/styles.css\" rel=\"stylesheet\" />\n    </head>\n    <body id=\"page-top\">\n        <!-- Navigation-->\n        <nav class=\"navbar navbar-expand-lg bg-secondary text-uppercase fixed-top\" id=\"mainNav\">\n            <div class=\"container\">\n                <a class=\"navbar-brand\" href=\"#page-top\">Start Bootstrap</a>\n                <button class=\"navbar-toggler text-uppercase font-weight-bold bg-primary text-white rounded\" type=\"button\" data-bs-toggle=\"collapse\" data-bs-target=\"#navbarResponsive\" aria-controls=\"navbarResponsive\" aria-expanded=\"false\" aria-label=\"Toggle navigation\">\n                    Menu\n                    <i class=\"fas fa-bars\"></i>\n                </button>\n                <div class=\"collapse navbar-collapse\" id=\"navbarResponsive\">\n                    <ul class=\"navbar-nav ms-auto\">\n                        <li class=\"nav-item mx-0 mx-lg-1\"><a class=\"nav-link py-3 px-0 px-lg-3 rounded\" href=\"#portfolio\">Portfolio</a></li>\n                        <li class=\"nav-item mx-0 mx-lg-1\"><a class=\"nav-link py-3 px-0 px-lg-3 rounded\" href=\"#about\">About</a></li>\n                        <li class=\"nav-item mx-0 mx-lg-1\"><a class=\"nav-link py-3 px-0 px-lg-3 rounded\" href=\"#contact\">Contact</a></li>\n                    </ul>\n                </div>\n            </div>\n        </nav>\n        <!-- Masthead-->\n        <header class=\"masthead bg-primary text-white text-center\">\n            <div class=\"container d-flex align-items-center flex-column\">\n                <!-- Masthead Avatar Image-->\n                <img class=\"masthead-avatar mb-5\" src=\"assets/img/avataaars.svg\" alt=\"...\" />\n                <!-- Masthead Heading-->\n                <h1 class=\"masthead-heading text-uppercase mb-0\">Start Bootstrap</h1>\n                <!-- Icon Divider-->\n                <div class=\"divider-custom divider-light\">\n                    <div class=\"divider-custom-line\"></div>\n                    <div class=\"divider-custom-icon\"><i class=\"fas fa-star\"></i></div>\n                    <div class=\"divider-custom-line\"></div>\n                </div>\n                <!-- Masthead Subheading-->\n                <p class=\"masthead-subheading font-weight-light mb-0\">Graphic Artist - Web Designer - Illustrator</p>\n            </div>\n        </header>\n        <!-- Portfolio Section-->\n        <section class=\"page-section portfolio\" id=\"portfolio\">\n            <div class=\"container\">\n                <!-- Portfolio Section Heading-->\n                <h2 class=\"page-section-heading text-center text-uppercase text-secondary mb-0\">Portfolio</h2>\n                <!-- Icon Divider-->\n                <div class=\"divider-custom\">\n                    <div class=\"divider-custom-line\"></div>\n                    <div class=\"divider-custom-icon\"><i class=\"fas fa-star\"></i></div>\n                    <div class=\"divider-custom-line\"></div>\n                </div>\n                <!-- Portfolio Grid Items-->\n                <div class=\"row justify-content-center\">\n                    <!-- Portfolio Item 1-->\n                    <div class=\"col-md-6 col-lg-4 mb-5\">\n                        <div class=\"portfolio-item mx-auto\" data-bs-toggle=\"modal\" data-bs-target=\"#portfolioModal1\">\n                            <div class=\"portfolio-item-caption d-flex align-items-center justify-content-center h-100 w-100\">\n                                <div class=\"portfolio-item-caption-content text-center text-white\"><i class=\"fas fa-plus fa-3x\"></i></div>\n                            </div>\n                            <img class=\"img-fluid\" src=\"assets/img/portfolio/cabin.png\" alt=\"...\" />\n                        </div>\n                    </div>\n                    <!-- Portfolio Item 2-->\n                    <div class=\"col-md-6 col-lg-4 mb-5\">\n                        <div class=\"portfolio-item mx-auto\" data-bs-toggle=\"modal\" data-bs-target=\"#portfolioModal2\">\n                            <div class=\"portfolio-item-caption d-flex align-items-center justify-content-center h-100 w-100\">\n                                <div class=\"portfolio-item-caption-content text-center text-white\"><i class=\"fas fa-plus fa-3x\"></i></div>\n                            </div>\n                            <img class=\"img-fluid\" src=\"assets/img/portfolio/cake.png\" alt=\"...\" />\n                        </div>\n                    </div>\n                    <!-- Portfolio Item 3-->\n                    <div class=\"col-md-6 col-lg-4 mb-5\">\n                        <div class=\"portfolio-item mx-auto\" data-bs-toggle=\"modal\" data-bs-target=\"#portfolioModal3\">\n                            <div class=\"portfolio-item-caption d-flex align-items-center justify-content-center h-100 w-100\">\n                                <div class=\"portfolio-item-caption-content text-center text-white\"><i class=\"fas fa-plus fa-3x\"></i></div>\n                            </div>\n                            <img class=\"img-fluid\" src=\"assets/img/portfolio/circus.png\" alt=\"...\" />\n                        </div>\n                    </div>\n                    <!-- Portfolio Item 4-->\n                    <div class=\"col-md-6 col-lg-4 mb-5 mb-lg-0\">\n                        <div class=\"portfolio-item mx-auto\" data-bs-toggle=\"modal\" data-bs-target=\"#portfolioModal4\">\n                            <div class=\"portfolio-item-caption d-flex align-items-center justify-content-center h-100 w-100\">\n                                <div class=\"portfolio-item-caption-content text-center text-white\"><i class=\"fas fa-plus fa-3x\"></i></div>\n                            </div>\n                            <img class=\"img-fluid\" src=\"assets/img/portfolio/game.png\" alt=\"...\" />\n                        </div>\n                    </div>\n                    <!-- Portfolio Item 5-->\n                    <div class=\"col-md-6 col-lg-4 mb-5 mb-md-0\">\n                        <div class=\"portfolio-item mx-auto\" data-bs-toggle=\"modal\" data-bs-target=\"#portfolioModal5\">\n                            <div class=\"portfolio-item-caption d-flex align-items-center justify-content-center h-100 w-100\">\n                                <div class=\"portfolio-item-caption-content text-center text-white\"><i class=\"fas fa-plus fa-3x\"></i></div>\n                            </div>\n                            <img class=\"img-fluid\" src=\"assets/img/portfolio/safe.png\" alt=\"...\" />\n                        </div>\n                    </div>\n                    <!-- Portfolio Item 6-->\n                    <div class=\"col-md-6 col-lg-4\">\n                        <div class=\"portfolio-item mx-auto\" data-bs-toggle=\"modal\" data-bs-target=\"#portfolioModal6\">\n                            <div class=\"portfolio-item-caption d-flex align-items-center justify-content-center h-100 w-100\">\n                                <div class=\"portfolio-item-caption-content text-center text-white\"><i class=\"fas fa-plus fa-3x\"></i></div>\n                            </div>\n                            <img class=\"img-fluid\" src=\"assets/img/portfolio/submarine.png\" alt=\"...\" />\n                        </div>\n                    </div>\n                </div>\n            </div>\n        </section>\n        <!-- About Section-->\n        <section class=\"page-section bg-primary text-white mb-0\" id=\"about\">\n            <div class=\"container\">\n                <!-- About Section Heading-->\n                <h2 class=\"page-section-heading text-center text-uppercase text-white\">About</h2>\n                <!-- Icon Divider-->\n                <div class=\"divider-custom divider-light\">\n                    <div class=\"divider-custom-line\"></div>\n                    <div class=\"divider-custom-icon\"><i class=\"fas fa-star\"></i></div>\n                    <div class=\"divider-custom-line\"></div>\n                </div>\n                <!-- About Section Content-->\n                <div class=\"row\">\n                    <div class=\"col-lg-4 ms-auto\"><p class=\"lead\">Freelancer is a free bootstrap theme created by Start Bootstrap. The download includes the complete source files including HTML, CSS, and JavaScript as well as optional SASS stylesheets for easy customization.</p></div>\n                    <div class=\"col-lg-4 me-auto\"><p class=\"lead\">You can create your own custom avatar for the masthead, change the icon in the dividers, and add your email address to the contact form to make it fully functional!</p></div>\n                </div>\n                <!-- About Section Button-->\n                <div class=\"text-center mt-4\">\n                    <a class=\"btn btn-xl btn-outline-light\" href=\"https://startbootstrap.com/theme/freelancer/\">\n                        <i class=\"fas fa-download me-2\"></i>\n                        Free Download!\n                    </a>\n                </div>\n            </div>\n        </section>\n        <!-- Contact Section-->\n        <section class=\"page-section\" id=\"contact\">\n            <div class=\"container\">\n                <!-- Contact Section Heading-->\n                <h2 class=\"page-section-heading text-center text-uppercase text-secondary mb-0\">Contact Me</h2>\n                <!-- Icon Divider-->\n                <div class=\"divider-custom\">\n                    <div class=\"divider-custom-line\"></div>\n                    <div class=\"divider-custom-icon\"><i class=\"fas fa-star\"></i></div>\n                    <div class=\"divider-custom-line\"></div>\n                </div>\n                <!-- Contact Section Form-->\n                <div class=\"row justify-content-center\">\n                    <div class=\"col-lg-8 col-xl-7\">\n                        <!-- * * * * * * * * * * * * * * *-->\n                        <!-- * * SB Forms Contact Form * *-->\n                        <!-- * * * * * * * * * * * * * * *-->\n                        <!-- This form is pre-integrated with SB Forms.-->\n                        <!-- To make this form functional, sign up at-->\n                        <!-- https://startbootstrap.com/solution/contact-forms-->\n                        <!-- to get an API token!-->\n                        <form id=\"contactForm\" data-sb-form-api-token=\"API_TOKEN\">\n                            <!-- Name input-->\n                            <div class=\"form-floating mb-3\">\n                                <input class=\"form-control\" id=\"name\" type=\"text\" placeholder=\"Enter your name...\" data-sb-validations=\"required\" />\n                                <label for=\"name\">Full name</label>\n                                <div class=\"invalid-feedback\" data-sb-feedback=\"name:required\">A name is required.</div>\n                            </div>\n                            <!-- Email address input-->\n                            <div class=\"form-floating mb-3\">\n                                <input class=\"form-control\" id=\"email\" type=\"email\" placeholder=\"name@example.com\" data-sb-validations=\"required,email\" />\n                                <label for=\"email\">Email address</label>\n                                <div class=\"invalid-feedback\" data-sb-feedback=\"email:required\">An email is required.</div>\n                                <div class=\"invalid-feedback\" data-sb-feedback=\"email:email\">Email is not valid.</div>\n                            </div>\n                            <!-- Phone number input-->\n                            <div class=\"form-floating mb-3\">\n                                <input class=\"form-control\" id=\"phone\" type=\"tel\" placeholder=\"(123) 456-7890\" data-sb-validations=\"required\" />\n                                <label for=\"phone\">Phone number</label>\n                                <div class=\"invalid-feedback\" data-sb-feedback=\"phone:required\">A phone number is required.</div>\n                            </div>\n                            <!-- Message input-->\n                            <div class=\"form-floating mb-3\">\n                                <textarea class=\"form-control\" id=\"message\" type=\"text\" placeholder=\"Enter your message here...\" style=\"height: 10rem\" data-sb-validations=\"required\"></textarea>\n                                <label for=\"message\">Message</label>\n                                <div class=\"invalid-feedback\" data-sb-feedback=\"message:required\">A message is required.</div>\n                            </div>\n                            <!-- Submit success message-->\n                            <!---->\n                            <!-- This is what your users will see when the form-->\n                            <!-- has successfully submitted-->\n                            <div class=\"d-none\" id=\"submitSuccessMessage\">\n                                <div class=\"text-center mb-3\">\n                                    <div class=\"fw-bolder\">Form submission successful!</div>\n                                    To activate this form, sign up at\n                                    <br />\n                                    <a href=\"https://startbootstrap.com/solution/contact-forms\">https://startbootstrap.com/solution/contact-forms</a>\n                                </div>\n                            </div>\n                            <!-- Submit error message-->\n                            <!---->\n                            <!-- This is what your users will see when there is-->\n                            <!-- an error submitting the form-->\n                            <div class=\"d-none\" id=\"submitErrorMessage\"><div class=\"text-center text-danger mb-3\">Error sending message!</div></div>\n                            <!-- Submit Button-->\n                            <button class=\"btn btn-primary btn-xl disabled\" id=\"submitButton\" type=\"submit\">Send</button>\n                        </form>\n                    </div>\n                </div>\n            </div>\n        </section>\n        <!-- Footer-->\n        <footer class=\"footer text-center\">\n            <div class=\"container\">\n                <div class=\"row\">\n                    <!-- Footer Location-->\n                    <div class=\"col-lg-4 mb-5 mb-lg-0\">\n                        <h4 class=\"text-uppercase mb-4\">Location</h4>\n                        <p class=\"lead mb-0\">\n                            2215 John Daniel Drive\n                            <br />\n                            Clark, MO 65243\n                        </p>\n                    </div>\n                    <!-- Footer Social Icons-->\n                    <div class=\"col-lg-4 mb-5 mb-lg-0\">\n                        <h4 class=\"text-uppercase mb-4\">Around the Web</h4>\n                        <a class=\"btn btn-outline-light btn-social mx-1\" href=\"#!\"><i class=\"fab fa-fw fa-facebook-f\"></i></a>\n                        <a class=\"btn btn-outline-light btn-social mx-1\" href=\"#!\"><i class=\"fab fa-fw fa-twitter\"></i></a>\n                        <a class=\"btn btn-outline-light btn-social mx-1\" href=\"#!\"><i class=\"fab fa-fw fa-linkedin-in\"></i></a>\n                        <a class=\"btn btn-outline-light btn-social mx-1\" href=\"#!\"><i class=\"fab fa-fw fa-dribbble\"></i></a>\n                    </div>\n                    <!-- Footer About Text-->\n                    <div class=\"col-lg-4\">\n                        <h4 class=\"text-uppercase mb-4\">About Freelancer</h4>\n                        <p class=\"lead mb-0\">\n                            Freelance is a free to use, MIT licensed Bootstrap theme created by\n                            <a href=\"http://startbootstrap.com\">Start Bootstrap</a>\n                            .\n                        </p>\n                    </div>\n                </div>\n            </div>\n        </footer>\n        <!-- Copyright Section-->\n        <div class=\"copyright py-4 text-center text-white\">\n            <div class=\"container\"><small>Copyright &copy; Your Website 2023</small></div>\n        </div>\n        <!-- Portfolio Modals-->\n        <!-- Portfolio Modal 1-->\n        <div class=\"portfolio-modal modal fade\" id=\"portfolioModal1\" tabindex=\"-1\" aria-labelledby=\"portfolioModal1\" aria-hidden=\"true\">\n            <div class=\"modal-dialog modal-xl\">\n                <div class=\"modal-content\">\n                    <div class=\"modal-header border-0\"><button class=\"btn-close\" type=\"button\" data-bs-dismiss=\"modal\" aria-label=\"Close\"></button></div>\n                    <div class=\"modal-body text-center pb-5\">\n                        <div class=\"container\">\n                            <div class=\"row justify-content-center\">\n                                <div class=\"col-lg-8\">\n                                    <!-- Portfolio Modal - Title-->\n                                    <h2 class=\"portfolio-modal-title text-secondary text-uppercase mb-0\">Log Cabin</h2>\n                                    <!-- Icon Divider-->\n                                    <div class=\"divider-custom\">\n                                        <div class=\"divider-custom-line\"></div>\n                                        <div class=\"divider-custom-icon\"><i class=\"fas fa-star\"></i></div>\n                                        <div class=\"divider-custom-line\"></div>\n                                    </div>\n                                    <!-- Portfolio Modal - Image-->\n                                    <img class=\"img-fluid rounded mb-5\" src=\"assets/img/portfolio/cabin.png\" alt=\"...\" />\n                                    <!-- Portfolio Modal - Text-->\n                                    <p class=\"mb-4\">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Mollitia neque assumenda ipsam nihil, molestias magnam, recusandae quos quis inventore quisquam velit asperiores, vitae? Reprehenderit soluta, eos quod consequuntur itaque. Nam.</p>\n                                    <button class=\"btn btn-primary\" data-bs-dismiss=\"modal\">\n                                        <i class=\"fas fa-xmark fa-fw\"></i>\n                                        Close Window\n                                    </button>\n                                </div>\n                            </div>\n                        </div>\n                    </div>\n                </div>\n            </div>\n        </div>\n        <!-- Portfolio Modal 2-->\n        <div class=\"portfolio-modal modal fade\" id=\"portfolioModal2\" tabindex=\"-1\" aria-labelledby=\"portfolioModal2\" aria-hidden=\"true\">\n            <div class=\"modal-dialog modal-xl\">\n                <div class=\"modal-content\">\n                    <div class=\"modal-header border-0\"><button class=\"btn-close\" type=\"button\" data-bs-dismiss=\"modal\" aria-label=\"Close\"></button></div>\n                    <div class=\"modal-body text-center pb-5\">\n                        <div class=\"container\">\n                            <div class=\"row justify-content-center\">\n                                <div class=\"col-lg-8\">\n                                    <!-- Portfolio Modal - Title-->\n                                    <h2 class=\"portfolio-modal-title text-secondary text-uppercase mb-0\">Tasty Cake</h2>\n                                    <!-- Icon Divider-->\n                                    <div class=\"divider-custom\">\n                                        <div class=\"divider-custom-line\"></div>\n                                        <div class=\"divider-custom-icon\"><i class=\"fas fa-star\"></i></div>\n                                        <div class=\"divider-custom-line\"></div>\n                                    </div>\n                                    <!-- Portfolio Modal - Image-->\n                                    <img class=\"img-fluid rounded mb-5\" src=\"assets/img/portfolio/cake.png\" alt=\"...\" />\n                                    <!-- Portfolio Modal - Text-->\n                                    <p class=\"mb-4\">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Mollitia neque assumenda ipsam nihil, molestias magnam, recusandae quos quis inventore quisquam velit asperiores, vitae? Reprehenderit soluta, eos quod consequuntur itaque. Nam.</p>\n                                    <button class=\"btn btn-primary\" data-bs-dismiss=\"modal\">\n                                        <i class=\"fas fa-xmark fa-fw\"></i>\n                                        Close Window\n                                    </button>\n                                </div>\n                            </div>\n                        </div>\n                    </div>\n                </div>\n            </div>\n        </div>\n        <!-- Portfolio Modal 3-->\n        <div class=\"portfolio-modal modal fade\" id=\"portfolioModal3\" tabindex=\"-1\" aria-labelledby=\"portfolioModal3\" aria-hidden=\"true\">\n            <div class=\"modal-dialog modal-xl\">\n                <div class=\"modal-content\">\n                    <div class=\"modal-header border-0\"><button class=\"btn-close\" type=\"button\" data-bs-dismiss=\"modal\" aria-label=\"Close\"></button></div>\n                    <div class=\"modal-body text-center pb-5\">\n                        <div class=\"container\">\n                            <div class=\"row justify-content-center\">\n                                <div class=\"col-lg-8\">\n                                    <!-- Portfolio Modal - Title-->\n                                    <h2 class=\"portfolio-modal-title text-secondary text-uppercase mb-0\">Circus Tent</h2>\n                                    <!-- Icon Divider-->\n                                    <div class=\"divider-custom\">\n                                        <div class=\"divider-custom-line\"></div>\n                                        <div class=\"divider-custom-icon\"><i class=\"fas fa-star\"></i></div>\n                                        <div class=\"divider-custom-line\"></div>\n                                    </div>\n                                    <!-- Portfolio Modal - Image-->\n                                    <img class=\"img-fluid rounded mb-5\" src=\"assets/img/portfolio/circus.png\" alt=\"...\" />\n                                    <!-- Portfolio Modal - Text-->\n                                    <p class=\"mb-4\">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Mollitia neque assumenda ipsam nihil, molestias magnam, recusandae quos quis inventore quisquam velit asperiores, vitae? Reprehenderit soluta, eos quod consequuntur itaque. Nam.</p>\n                                    <button class=\"btn btn-primary\" data-bs-dismiss=\"modal\">\n                                        <i class=\"fas fa-xmark fa-fw\"></i>\n                                        Close Window\n                                    </button>\n                                </div>\n                            </div>\n                        </div>\n                    </div>\n                </div>\n            </div>\n        </div>\n        <!-- Portfolio Modal 4-->\n        <div class=\"portfolio-modal modal fade\" id=\"portfolioModal4\" tabindex=\"-1\" aria-labelledby=\"portfolioModal4\" aria-hidden=\"true\">\n            <div class=\"modal-dialog modal-xl\">\n                <div class=\"modal-content\">\n                    <div class=\"modal-header border-0\"><button class=\"btn-close\" type=\"button\" data-bs-dismiss=\"modal\" aria-label=\"Close\"></button></div>\n                    <div class=\"modal-body text-center pb-5\">\n                        <div class=\"container\">\n                            <div class=\"row justify-content-center\">\n                                <div class=\"col-lg-8\">\n                                    <!-- Portfolio Modal - Title-->\n                                    <h2 class=\"portfolio-modal-title text-secondary text-uppercase mb-0\">Controller</h2>\n                                    <!-- Icon Divider-->\n                                    <div class=\"divider-custom\">\n                                        <div class=\"divider-custom-line\"></div>\n                                        <div class=\"divider-custom-icon\"><i class=\"fas fa-star\"></i></div>\n                                        <div class=\"divider-custom-line\"></div>\n                                    </div>\n                                    <!-- Portfolio Modal - Image-->\n                                    <img class=\"img-fluid rounded mb-5\" src=\"assets/img/portfolio/game.png\" alt=\"...\" />\n                                    <!-- Portfolio Modal - Text-->\n                                    <p class=\"mb-4\">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Mollitia neque assumenda ipsam nihil, molestias magnam, recusandae quos quis inventore quisquam velit asperiores, vitae? Reprehenderit soluta, eos quod consequuntur itaque. Nam.</p>\n                                    <button class=\"btn btn-primary\" data-bs-dismiss=\"modal\">\n                                        <i class=\"fas fa-xmark fa-fw\"></i>\n                                        Close Window\n                                    </button>\n                                </div>\n                            </div>\n                        </div>\n                    </div>\n                </div>\n            </div>\n        </div>\n        <!-- Portfolio Modal 5-->\n        <div class=\"portfolio-modal modal fade\" id=\"portfolioModal5\" tabindex=\"-1\" aria-labelledby=\"portfolioModal5\" aria-hidden=\"true\">\n            <div class=\"modal-dialog modal-xl\">\n                <div class=\"modal-content\">\n                    <div class=\"modal-header border-0\"><button class=\"btn-close\" type=\"button\" data-bs-dismiss=\"modal\" aria-label=\"Close\"></button></div>\n                    <div class=\"modal-body text-center pb-5\">\n                        <div class=\"container\">\n                            <div class=\"row justify-content-center\">\n                                <div class=\"col-lg-8\">\n                                    <!-- Portfolio Modal - Title-->\n                                    <h2 class=\"portfolio-modal-title text-secondary text-uppercase mb-0\">Locked Safe</h2>\n                                    <!-- Icon Divider-->\n                                    <div class=\"divider-custom\">\n                                        <div class=\"divider-custom-line\"></div>\n                                        <div class=\"divider-custom-icon\"><i class=\"fas fa-star\"></i></div>\n                                        <div class=\"divider-custom-line\"></div>\n                                    </div>\n                                    <!-- Portfolio Modal - Image-->\n                                    <img class=\"img-fluid rounded mb-5\" src=\"assets/img/portfolio/safe.png\" alt=\"...\" />\n                                    <!-- Portfolio Modal - Text-->\n                                    <p class=\"mb-4\">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Mollitia neque assumenda ipsam nihil, molestias magnam, recusandae quos quis inventore quisquam velit asperiores, vitae? Reprehenderit soluta, eos quod consequuntur itaque. Nam.</p>\n                                    <button class=\"btn btn-primary\" data-bs-dismiss=\"modal\">\n                                        <i class=\"fas fa-xmark fa-fw\"></i>\n                                        Close Window\n                                    </button>\n                                </div>\n                            </div>\n                        </div>\n                    </div>\n                </div>\n            </div>\n        </div>\n        <!-- Portfolio Modal 6-->\n        <div class=\"portfolio-modal modal fade\" id=\"portfolioModal6\" tabindex=\"-1\" aria-labelledby=\"portfolioModal6\" aria-hidden=\"true\">\n            <div class=\"modal-dialog modal-xl\">\n                <div class=\"modal-content\">\n                    <div class=\"modal-header border-0\"><button class=\"btn-close\" type=\"button\" data-bs-dismiss=\"modal\" aria-label=\"Close\"></button></div>\n                    <div class=\"modal-body text-center pb-5\">\n                        <div class=\"container\">\n                            <div class=\"row justify-content-center\">\n                                <div class=\"col-lg-8\">\n                                    <!-- Portfolio Modal - Title-->\n                                    <h2 class=\"portfolio-modal-title text-secondary text-uppercase mb-0\">Submarine</h2>\n                                    <!-- Icon Divider-->\n                                    <div class=\"divider-custom\">\n                                        <div class=\"divider-custom-line\"></div>\n                                        <div class=\"divider-custom-icon\"><i class=\"fas fa-star\"></i></div>\n                                        <div class=\"divider-custom-line\"></div>\n                                    </div>\n                                    <!-- Portfolio Modal - Image-->\n                                    <img class=\"img-fluid rounded mb-5\" src=\"assets/img/portfolio/submarine.png\" alt=\"...\" />\n                                    <!-- Portfolio Modal - Text-->\n                                    <p class=\"mb-4\">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Mollitia neque assumenda ipsam nihil, molestias magnam, recusandae quos quis inventore quisquam velit asperiores, vitae? Reprehenderit soluta, eos quod consequuntur itaque. Nam.</p>\n                                    <button class=\"btn btn-primary\" data-bs-dismiss=\"modal\">\n                                        <i class=\"fas fa-xmark fa-fw\"></i>\n                                        Close Window\n                                    </button>\n                                </div>\n                            </div>\n                        </div>\n                    </div>\n                </div>\n            </div>\n        </div>\n        <!-- Bootstrap core JS-->\n        <script src=\"https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js\"></script>\n        <!-- Core theme JS-->\n        <script src=\"js/scripts.js\"></script>\n        <!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *-->\n        <!-- * *                               SB Forms JS                               * *-->\n        <!-- * * Activate your form at https://startbootstrap.com/solution/contact-forms * *-->\n        <!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *-->\n        <script src=\"https://cdn.startbootstrap.com/sb-forms-latest.js\"></script>\n    </body>\n</html>\n"
  },
  {
    "path": "samples/s3-cloudfront-static-website/website/js/scripts.js",
    "content": "/*!\n* Start Bootstrap - Freelancer v7.0.7 (https://startbootstrap.com/theme/freelancer)\n* Copyright 2013-2023 Start Bootstrap\n* Licensed under MIT (https://github.com/StartBootstrap/startbootstrap-freelancer/blob/master/LICENSE)\n*/\n//\n// Scripts\n// \n\nwindow.addEventListener('DOMContentLoaded', event => {\n\n    // Navbar shrink function\n    var navbarShrink = function () {\n        const navbarCollapsible = document.body.querySelector('#mainNav');\n        if (!navbarCollapsible) {\n            return;\n        }\n        if (window.scrollY === 0) {\n            navbarCollapsible.classList.remove('navbar-shrink')\n        } else {\n            navbarCollapsible.classList.add('navbar-shrink')\n        }\n\n    };\n\n    // Shrink the navbar \n    navbarShrink();\n\n    // Shrink the navbar when page is scrolled\n    document.addEventListener('scroll', navbarShrink);\n\n    // Activate Bootstrap scrollspy on the main nav element\n    const mainNav = document.body.querySelector('#mainNav');\n    if (mainNav) {\n        new bootstrap.ScrollSpy(document.body, {\n            target: '#mainNav',\n            rootMargin: '0px 0px -40%',\n        });\n    };\n\n    // Collapse responsive navbar when toggler is visible\n    const navbarToggler = document.body.querySelector('.navbar-toggler');\n    const responsiveNavItems = [].slice.call(\n        document.querySelectorAll('#navbarResponsive .nav-link')\n    );\n    responsiveNavItems.map(function (responsiveNavItem) {\n        responsiveNavItem.addEventListener('click', () => {\n            if (window.getComputedStyle(navbarToggler).display !== 'none') {\n                navbarToggler.click();\n            }\n        });\n    });\n\n});\n"
  }
]