├── .editorconfig ├── .github ├── ISSUE_TEMPLATE │ ├── Bug_report.md │ ├── Feature_request.md │ └── Support_question.md ├── release-drafter.yml ├── settings.yml ├── stale.yml └── workflows │ ├── linter.yml │ ├── pr-title.yml │ └── release.draft.yml ├── .gitignore ├── .pre-commit-config.yaml ├── .tflint.hcl ├── LICENSE ├── Makefile ├── README.md ├── examples ├── README.md └── basic │ ├── README.md │ └── main.tf ├── main.tf ├── outputs.tf ├── renovate.json ├── variables.tf └── versions.tf /.editorconfig: -------------------------------------------------------------------------------- 1 | [*] 2 | end_of_line = lf 3 | charset = utf-8 4 | indent_style = space 5 | indent_size = 2 6 | insert_final_newline = true 7 | trim_trailing_whitespace = true 8 | 9 | [*.py] 10 | indent_style = space 11 | indent_size = 4 12 | max_line_length = 140 13 | 14 | [*.sh] 15 | indent_style = space 16 | indent_size = 2 17 | 18 | [Makefile] 19 | indent_style = tab 20 | 21 | [*.{tf,tfvars}] 22 | indent_size = 2 23 | indent_style = space 24 | 25 | [*.{yml,yaml}] 26 | indent_style = space 27 | indent_size = 2 28 | 29 | [*.feature] 30 | indent_size = 2 31 | 32 | [*.{json,tpl}] 33 | indent_style = space 34 | indent_size = 2 35 | 36 | [Jenkinsfile] 37 | indent_size = 2 38 | indent_style = space 39 | 40 | [*.{xml,config,props,targets,nuspec,resx,ruleset,vsixmanifest,vsct}] 41 | indent_size = 2 42 | 43 | [{*.scala,*.sbt}] 44 | indent_size = 2 45 | max_line_length = 80 46 | 47 | [{*.hcl,*.conf}] 48 | indent_size = 2 49 | max_line_length = 100 50 | 51 | # JS 52 | [*.js, **/*.js] 53 | indent_size = 4 54 | indent_style = space 55 | 56 | [{package.json}] 57 | indent_size = 2 58 | indent_style = space 59 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/Bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 🐛 Bug Report 3 | about: If something isn't working as expected 🤔. 4 | 5 | --- 6 | 7 | ## Bug Report 8 | 9 | ### Steps to Reproduce: 10 | 1. ...step 1 description... 11 | 2. ...step 2 description... 12 | 3. ...step 3 description... 13 | 14 | ### Expected Result: 15 | ...description of what you expected to see... 16 | 17 | ### Actual Result: 18 | ...what actually happened, including full exceptions (please include the entire stack trace, including "caused by" entries), log entries, screen shots etc. where appropriate... 19 | 20 | ### Environment: 21 | ...version and build of the project, OS and runtime versions, virtualised environment (if any), etc. ... 22 | 23 | ### Additional Context: 24 | ...add any other context about the problem here. If applicable, add screenshots to help explain... -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/Feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 🚀 Feature Request 3 | about: I have a suggestion (and may want to implement it 🙂)! 4 | 5 | --- 6 | 7 | ## Feature Request 8 | 9 | ### Description of Problem: 10 | ...what *problem* are you trying to solve that the project doesn't currently solve? 11 | 12 | ...please resist the temptation to describe your request in terms of a solution. Job Story form ("When [triggering condition], I want to [motivation/goal], so I can [outcome].") can help ensure you're expressing a problem statement. 13 | 14 | ### Potential Solutions: 15 | ...clearly and concisely describe what you want to happen. Add any considered drawbacks. 16 | 17 | ... if you've considered alternatives, clearly and concisely describe those too. -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/Support_question.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 🤗 Support Question 3 | about: If you have a question about configuration, usage, etc. 💬 4 | 5 | --- 6 | 7 | ## Support Question 8 | 9 | ...ask your question here. 10 | 11 | ...be sure to search existing issues since someone might have already asked something similar. -------------------------------------------------------------------------------- /.github/release-drafter.yml: -------------------------------------------------------------------------------- 1 | # Configuration for Release Drafter: https://github.com/toolmantim/release-drafter 2 | _extends: .github 3 | -------------------------------------------------------------------------------- /.github/settings.yml: -------------------------------------------------------------------------------- 1 | # These settings are synced to GitHub by https://probot.github.io/apps/settings/ 2 | _extends: .github 3 | 4 | repository: 5 | # See https://developer.github.com/v3/repos/#edit for all available settings. 6 | name: terraform-module-blueprint 7 | description: "ℹ️ Terraform module blueprint." 8 | homepage: https://ivankatliarchuk.github.io 9 | topics: ivank, terraform, terraform-module 10 | private: false 11 | has_issues: true 12 | has_projects: false 13 | has_wiki: false 14 | has_downloads: false 15 | has_pages: true 16 | is_template: true 17 | default_branch: master 18 | allow_squash_merge: true 19 | allow_merge_commit: true 20 | allow_rebase_merge: true 21 | delete_branch_on_merge: true 22 | enable_automated_security_fixes: true 23 | enable_vulnerability_alerts: false 24 | 25 | branches: 26 | - name: master 27 | -------------------------------------------------------------------------------- /.github/stale.yml: -------------------------------------------------------------------------------- 1 | # Configuration for https://github.com/probot/stale 2 | _extends: .github 3 | -------------------------------------------------------------------------------- /.github/workflows/linter.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: linter 3 | # This workflow is triggered on pushes to the repository. 4 | on: 5 | push: 6 | pull_request: 7 | branches: 8 | - main 9 | - master 10 | workflow_dispatch: 11 | 12 | jobs: 13 | terraform-validate: 14 | name: code format 15 | runs-on: ubuntu-latest 16 | steps: 17 | - uses: actions/checkout@master 18 | # https://github.com/hashicorp/setup-terraform 19 | - uses: hashicorp/setup-terraform@v3.1.1 20 | 21 | - name: Cache terraform folder 22 | uses: actions/cache@v4.0.2 23 | with: 24 | path: ./.terraform 25 | key: terraform 26 | 27 | - name: terraform fmt 28 | run: terraform fmt -check -recursive -diff 29 | continue-on-error: true 30 | 31 | - name: terraform init 32 | run: | 33 | terraform version 34 | terraform init 35 | 36 | - name: terraform validate 37 | run: terraform validate 38 | 39 | tflint: 40 | name: "tflint" 41 | runs-on: ubuntu-latest 42 | steps: 43 | - uses: actions/checkout@v4 44 | - uses: actions/cache@v4.0.2 45 | name: Cache tflint plugin dir 46 | with: 47 | path: ~/.tflint.d/plugins 48 | key: ${{ matrix.os }}-tflint-${{ hashFiles('.tflint.hcl') }} 49 | - uses: terraform-linters/setup-tflint@v4.0.0 50 | name: setup tflint 51 | - name: init tflint 52 | run: tflint --init --config .tflint.hcl 53 | - name: run tflint 54 | run: tflint -f compact --config .tflint.hcl 55 | -------------------------------------------------------------------------------- /.github/workflows/pr-title.yml: -------------------------------------------------------------------------------- 1 | name: 'validate-pr-title' 2 | 3 | on: 4 | pull_request_target: 5 | types: 6 | - opened 7 | - edited 8 | - synchronize 9 | 10 | jobs: 11 | main: 12 | name: validate pr title 13 | runs-on: ubuntu-latest 14 | steps: 15 | # Please look up the latest version from 16 | # https://github.com/amannn/action-semantic-pull-request/releases 17 | - uses: amannn/action-semantic-pull-request@v5.5.2 18 | env: 19 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 20 | with: 21 | # Configure which types are allowed. 22 | # Default: https://github.com/commitizen/conventional-commit-types 23 | types: | 24 | fix 25 | feat 26 | docs 27 | ci 28 | chore 29 | # Configure that a scope must always be provided. 30 | requireScope: false 31 | # If `subjectPattern` is configured, you can use this property to override 32 | # the default error message that is shown when the pattern doesn't match. 33 | # The variables `subject` and `title` can be used within the message. 34 | subjectPatternError: | 35 | The subject "{subject}" found in the pull request title "{title}" 36 | didn't match the configured pattern. Please ensure that the subject 37 | starts with an uppercase character. 38 | # For work-in-progress PRs you can typically use draft pull requests 39 | # from Github. However, private repositories on the free plan don't have 40 | # this option and therefore this action allows you to opt-in to using the 41 | # special "[WIP]" prefix to indicate this state. This will avoid the 42 | # validation of the PR title and the pull request checks remain pending. 43 | # Note that a second check will be reported if this is enabled. 44 | wip: true 45 | # When using "Squash and merge" on a PR with only one commit, GitHub 46 | # will suggest using that commit message instead of the PR title for the 47 | # merge commit, and it's easy to commit this by mistake. Enable this option 48 | # to also validate the commit message for one commit PRs. 49 | validateSingleCommit: false 50 | -------------------------------------------------------------------------------- /.github/workflows/release.draft.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: release.draft 3 | 4 | on: 5 | push: 6 | branches: 7 | - master 8 | workflow_dispatch: 9 | inputs: 10 | prerelease: 11 | description: Is this a pre-release 12 | required: true 13 | default: true 14 | type: boolean 15 | publish: 16 | description: Publish release 17 | required: false 18 | default: false 19 | type: boolean 20 | bump: 21 | description: 'Bumping (#major, #minor or #patch)' 22 | required: false 23 | default: patch 24 | type: choice 25 | options: 26 | - 'patch' 27 | - 'minor' 28 | - 'major' 29 | 30 | jobs: 31 | draft-a-release: 32 | runs-on: ubuntu-latest 33 | steps: 34 | 35 | - uses: actions/checkout@v4 36 | 37 | - name: check next version 38 | uses: anothrNick/github-tag-action@1.69.0 39 | id: tag 40 | env: 41 | DRY_RUN: true 42 | WITH_V: true 43 | DEFAULT_BUMP: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.bump || 'patch' }} 44 | 45 | - name: release-draft 46 | uses: release-drafter/release-drafter@v6.0.0 47 | if: "!contains(github.event.head_commit.message, 'skip')" 48 | id: release 49 | env: 50 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 51 | with: 52 | publish: ${{ github.event.inputs.publish }} 53 | prerelease: ${{ github.event.inputs.prerelease }} 54 | tag: ${{ steps.tag.outputs.new_tag }} 55 | 56 | - name: check-version 57 | run: | 58 | echo "release it: ${{ github.event.inputs.prerelease }}" 59 | echo "out: ${{ steps.release.name }}" 60 | echo "tag: ${{ steps.release.outputs.tag_name }}" 61 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Local .terraform directories 2 | **/.terraform/* 3 | 4 | # .tfstate files 5 | *.tfstate 6 | *.tfstate.* 7 | 8 | # .tfvars files 9 | *.tfvars 10 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | repos: 2 | - repo: https://github.com/pre-commit/pre-commit-hooks 3 | rev: v5.0.0 4 | hooks: 5 | - id: check-added-large-files 6 | args: ['--maxkb=500'] 7 | - id: check-executables-have-shebangs 8 | - id: pretty-format-json 9 | args: ['--autofix', '--no-sort-keys', '--indent=2'] 10 | - id: check-byte-order-marker 11 | - id: check-case-conflict 12 | - id: check-executables-have-shebangs 13 | - id: check-merge-conflict 14 | - id: check-symlinks 15 | - id: detect-private-key 16 | - id: check-merge-conflict 17 | - id: detect-aws-credentials 18 | args: ['--allow-missing-credentials'] 19 | - repo: https://github.com/antonbabenko/pre-commit-terraform 20 | rev: v1.99.1 21 | hooks: 22 | - id: terraform_fmt 23 | - id: terraform_docs 24 | - id: terraform_tflint 25 | -------------------------------------------------------------------------------- /.tflint.hcl: -------------------------------------------------------------------------------- 1 | config { 2 | module = false 3 | } 4 | 5 | plugin "aws" { 6 | enabled = true 7 | version = "0.30.0" 8 | source = "github.com/terraform-linters/tflint-ruleset-aws" 9 | } 10 | 11 | rule "terraform_comment_syntax" { 12 | enabled = true 13 | } 14 | 15 | rule "terraform_deprecated_index" { 16 | enabled = true 17 | } 18 | 19 | rule "terraform_deprecated_interpolation" { 20 | enabled = true 21 | } 22 | 23 | rule "terraform_documented_outputs" { 24 | enabled = true 25 | } 26 | 27 | rule "terraform_documented_variables" { 28 | enabled = true 29 | } 30 | 31 | rule "terraform_module_pinned_source" { 32 | enabled = true 33 | style = "flexible" 34 | } 35 | 36 | rule "terraform_module_version" { 37 | enabled = true 38 | } 39 | 40 | rule "terraform_naming_convention" { 41 | enabled = true 42 | format = "snake_case" 43 | } 44 | 45 | rule "terraform_standard_module_structure" { 46 | enabled = true 47 | } 48 | 49 | rule "terraform_typed_variables" { 50 | enabled = true 51 | } 52 | 53 | rule "terraform_unused_declarations" { 54 | enabled = true 55 | } 56 | 57 | rule "terraform_unused_required_providers" { 58 | enabled = true 59 | } 60 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Ivan Katliarchuk, https://github.com/ivankatliarchuk 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | SHELL = /bin/bash 2 | .ONESHELL: 3 | .SHELLFLAGS := -eu -o pipefail -c 4 | MAKEFLAGS += --warn-undefined-variables 5 | MAKEFLAGS += --no-builtin-rules 6 | 7 | .PHONY: pre-commit changelog release 8 | 9 | # -include $(shell curl -sSL -o .build-harness "https://git.io/build-harness"; echo .build-harness) 10 | 11 | help/local: 12 | @cat Makefile* | grep -E '^[a-zA-Z_-]+:.*?## .*$$' | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' 13 | 14 | help: help/local 15 | 16 | hooks: ## Commit hooks setup 17 | @pre-commit install 18 | @pre-commit gc 19 | 20 | validate: ## Validate with pre-commit hooks 21 | @pre-commit run --all-files 22 | 23 | init: ## Test diff 24 | @terraform init 25 | 26 | format: ## Terraform format 27 | @terraform format 28 | 29 | cleanup: ## Clean resources 30 | @find . -type d -name ".terraform" -prune -exec rm -rf {} \; 31 | @find . -type f -name ".terraform.lock.hcl" -prune -exec rm {} \; 32 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Module Blueprint 2 | 3 | Terraform module blueprint 4 | 5 | --- 6 | 7 | [![linter](https://github.com/terraform-module/terraform-module-blueprint/actions/workflows/linter.yml/badge.svg)](https://github.com/terraform-module/terraform-module-blueprint/actions/workflows/linter.yml) 8 | [![release.draft](https://github.com/terraform-module/terraform-module-blueprint/actions/workflows/release.draft.yml/badge.svg)](https://github.com/terraform-module/terraform-module-blueprint/actions/workflows/release.draft.yml) 9 | 10 | [![](https://img.shields.io/github/license/terraform-module/terraform-module-blueprint)](https://github.com/terraform-module/terraform-module-blueprint) 11 | ![](https://img.shields.io/github/v/tag/terraform-module/terraform-module-blueprint) 12 | ![](https://img.shields.io/issues/github/terraform-module/terraform-module-blueprint) 13 | ![](https://img.shields.io/github/issues/terraform-module/terraform-module-blueprint) 14 | ![](https://img.shields.io/github/issues-closed/terraform-module/terraform-module-blueprint) 15 | [![](https://img.shields.io/github/languages/code-size/terraform-module/terraform-module-blueprint)](https://github.com/terraform-module/terraform-module-blueprint) 16 | [![](https://img.shields.io/github/repo-size/terraform-module/terraform-module-blueprint)](https://github.com/terraform-module/terraform-module-blueprint) 17 | ![](https://img.shields.io/github/languages/top/terraform-module/terraform-module-blueprint?color=green&logo=terraform&logoColor=blue) 18 | ![](https://img.shields.io/github/commit-activity/m/terraform-module/terraform-module-blueprint) 19 | ![](https://img.shields.io/github/contributors/terraform-module/terraform-module-blueprint) 20 | ![](https://img.shields.io/github/last-commit/terraform-module/terraform-module-blueprint) 21 | [![Maintenance](https://img.shields.io/badge/Maintenu%3F-oui-green.svg)](https://GitHub.com/terraform-module/terraform-module-blueprint/graphs/commit-activity) 22 | [![GitHub forks](https://img.shields.io/github/forks/terraform-module/terraform-module-blueprint.svg?style=social&label=Fork)](https://github.com/terraform-module/terraform-module-blueprint) 23 | 24 | --- 25 | 26 | ## Documentation 27 | 28 | - [TFLint Rules](https://github.com/terraform-linters/tflint/tree/master/docs/rules) 29 | 30 | ## Usage example 31 | 32 | IMPORTANT: The master branch is used in source just as an example. In your code, do not pin to master because there may be breaking changes between releases. Instead pin to the release tag (e.g. ?ref=tags/x.y.z) of one of our [latest releases](https://github.com/terraform-module/terraform-module-blueprint/releases). 33 | 34 | ```hcl 35 | module "blueprint" { 36 | source = "terraform-module/blueprint" 37 | version = "0.0.0" 38 | # insert required variables here 39 | } 40 | ``` 41 | 42 | ## Examples 43 | 44 | See `examples` directory for working examples to reference 45 | 46 | - [Examples Dir](https://github.com/terraform-module/module-blueprint/tree/master/examples/) 47 | 48 | ## Assumptions 49 | 50 | ## Available features 51 | 52 | 53 | ## Requirements 54 | 55 | | Name | Version | 56 | |------|---------| 57 | | [terraform](#requirement\_terraform) | >= 1 | 58 | 59 | ## Providers 60 | 61 | No providers. 62 | 63 | ## Modules 64 | 65 | No modules. 66 | 67 | ## Resources 68 | 69 | No resources. 70 | 71 | ## Inputs 72 | 73 | | Name | Description | Type | Default | Required | 74 | |------|-------------|------|---------|:--------:| 75 | | [variable](#input\_variable) | defaul,description,type | `string` | `"variable"` | no | 76 | 77 | ## Outputs 78 | 79 | | Name | Description | 80 | |------|-------------| 81 | | [used](#output\_used) | used value | 82 | 83 | 84 | 85 | ### :memo: Guidelines 86 | 87 | - :memo: Use a succinct title and description. 88 | - :bug: Bugs & feature requests can be be opened 89 | - :signal_strength: Support questions are better asked on [Stack Overflow](https://stackoverflow.com/) 90 | - :blush: Be nice, civil and polite ([as always](http://contributor-covenant.org/version/1/4/)). 91 | 92 | ## License 93 | 94 | Copyright 2019 Ivan Katliarhcuk 95 | 96 | MIT Licensed. See [LICENSE](./LICENSE) for full details. 97 | 98 | ## How to Contribute 99 | 100 | Submit a pull request 101 | 102 | # Authors 103 | 104 | Currently maintained by [Ivan Katliarchuk](https://github.com/ivankatliarchuk) and these [awesome contributors](https://github.com/terraform-module/terraform-module-blueprint/graphs/contributors). 105 | 106 | [![ForTheBadge uses-git](http://ForTheBadge.com/images/badges/uses-git.svg)](https://GitHub.com/) 107 | 108 | ## Terraform Registry 109 | 110 | - [Module](https://registry.terraform.io/modules/terraform-module/todo/aws) 111 | 112 | ## Resources 113 | 114 | - [Terraform modules](https://registry.terraform.io/namespaces/terraform-module) 115 | 116 | ## Clone Me 117 | 118 | [**Create a repository using this template →**][template.generate] 119 | 120 | 121 | [template.generate]: https://github.com/terraform-module/terraform-module-blueprint/generate 122 | -------------------------------------------------------------------------------- /examples/README.md: -------------------------------------------------------------------------------- 1 | # Examples 2 | 3 | Please note - the examples provided serve two primary means: 4 | 5 | 1. Show users working examples of the various ways in which the module can be configured and features supported 6 | 1. A means of testing/validating module changes 7 | 8 | Please do not mistake the examples provided as "best practices". It is up to users to consult the AWS service documentation for best practices, usage recommendations, etc. 9 | -------------------------------------------------------------------------------- /examples/basic/README.md: -------------------------------------------------------------------------------- 1 | # Example 2 | 3 | Configuration in this directory creates a MySQL Aurora cluster. 4 | 5 | ## Usage 6 | 7 | To run this example you need to execute: 8 | 9 | ```bash 10 | $ terraform init 11 | $ terraform plan 12 | $ terraform apply 13 | ``` 14 | 15 | Note that this example may create resources which cost money. Run `terraform destroy` when you don't need these resources. 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /examples/basic/main.tf: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Supporting Resources 3 | ################################################################################ 4 | 5 | ################################################################################ 6 | # Resources 7 | ################################################################################ 8 | 9 | ################################################################################ 10 | # OUTPUTS 11 | ################################################################################ 12 | -------------------------------------------------------------------------------- /main.tf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/terraform-module/terraform-module-blueprint/eba015b401e4c295715d185b0d87781b7398fd84/main.tf -------------------------------------------------------------------------------- /outputs.tf: -------------------------------------------------------------------------------- 1 | output "used" { 2 | description = "used value" 3 | value = var.variable 4 | } 5 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "config:base" 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /variables.tf: -------------------------------------------------------------------------------- 1 | variable "variable" { 2 | default = "variable" 3 | description = "defaul,description,type" 4 | type = string 5 | } 6 | -------------------------------------------------------------------------------- /versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">= 1" 3 | } 4 | --------------------------------------------------------------------------------