From 717edcc728ef3775f56c25e8e2edf5010e2b237a Mon Sep 17 00:00:00 2001 From: Jose Storopoli Date: Thu, 15 Aug 2024 14:35:52 -0300 Subject: [PATCH] feat: initial commit --- .gitattributes | 4 + .github/ISSUE_TEMPLATE/bug_report.md | 32 + .github/ISSUE_TEMPLATE/epic.md | 46 + .github/ISSUE_TEMPLATE/new_document.md | 35 + .../ISSUE_TEMPLATE/question_clarification.md | 29 + .github/ISSUE_TEMPLATE/update_document.md | 32 + .github/PULL_REQUEST_TEMPLATE.md | 61 + .github/dependabot.yml | 6 + .github/workflows/check.yml | 46 + .github/workflows/mkdocs.yml | 61 + .gitignore | 15 + .prettierignore | 1 + .prettierrc.yaml | 10 + .vscode/extensions.json | 8 + .vscode/settings.json | 20 + README.md | 80 + cspell.json | 18 + docs/assets/favicon.png | Bin 0 -> 22140 bytes docs/assets/logo.png | Bin 0 -> 64973 bytes docs/index.md | 70 + docs/javascripts/mathjax.js | 20 + docs/security.txt | 3 + docs/stylesheets/extra.css | 16 + docs/technical/architecture.md | 6 + docs/technical/bitcoin-bridge.md | 147 ++ docs/technical/comparing-ethereum.md | 32 + docs/technical/node-types.md | 91 + docs/technical/specs.md | 24 + docs/technical/transaction-lifecycle.md | 131 ++ eslint.config.mjs | 47 + justfile | 73 + mkdocs.yml | 87 + package.json | 26 + pnpm-lock.yaml | 1546 +++++++++++++++++ project-words.txt | 38 + style-guide.md | 317 ++++ 36 files changed, 3178 insertions(+) create mode 100644 .gitattributes create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/epic.md create mode 100644 .github/ISSUE_TEMPLATE/new_document.md create mode 100644 .github/ISSUE_TEMPLATE/question_clarification.md create mode 100644 .github/ISSUE_TEMPLATE/update_document.md create mode 100644 .github/PULL_REQUEST_TEMPLATE.md create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/check.yml create mode 100644 .github/workflows/mkdocs.yml create mode 100644 .gitignore create mode 100644 .prettierignore create mode 100644 .prettierrc.yaml create mode 100644 .vscode/extensions.json create mode 100644 .vscode/settings.json create mode 100644 README.md create mode 100644 cspell.json create mode 100644 docs/assets/favicon.png create mode 100644 docs/assets/logo.png create mode 100644 docs/index.md create mode 100644 docs/javascripts/mathjax.js create mode 100644 docs/security.txt create mode 100644 docs/stylesheets/extra.css create mode 100644 docs/technical/architecture.md create mode 100644 docs/technical/bitcoin-bridge.md create mode 100644 docs/technical/comparing-ethereum.md create mode 100644 docs/technical/node-types.md create mode 100644 docs/technical/specs.md create mode 100644 docs/technical/transaction-lifecycle.md create mode 100644 eslint.config.mjs create mode 100644 justfile create mode 100644 mkdocs.yml create mode 100644 package.json create mode 100644 pnpm-lock.yaml create mode 100644 project-words.txt create mode 100644 style-guide.md diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..e45ce91 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,4 @@ +docs/javascripts/* linguist-vendored +eslint.config.mjs linguist-generated +package-lock.json linguist-generated +package.json linguist-generated diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..42008f5 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,32 @@ +--- +name: Bug Report +about: Report an issue or bug in the documentation +title: "[BUG] " +labels: bug +assignees: "" +--- + +## Bug Report + +**Document Title:** + +**Current URL/Location:** + +**Description of Issue:** (What is the issue? Typo, broken link, +incorrect information, etc.) + +**Expected Behavior:** (What should the correct information be?) + +--- + +### Additional Information + +Include any other relevant information, screenshots, +or logs that might help in resolving the issue. + +--- + +### Checklist + +- [ ] I have searched the existing issues for related topics. +- [ ] I have provided all necessary information to reproduce the issue. diff --git a/.github/ISSUE_TEMPLATE/epic.md b/.github/ISSUE_TEMPLATE/epic.md new file mode 100644 index 0000000..22ff732 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/epic.md @@ -0,0 +1,46 @@ +--- +name: Epic +about: A parent issue that tracks multiple sub-issues +title: "[EPIC] " +labels: epic +assignees: "" +--- + +## Epic Overview + +**Description:** +Provide a clear and concise description of the overall goal of this epic. +Include any relevant background information. + +--- + +### Sub-Issues + +List the sub-issues that are part of this epic. +These should be created as separate issues and linked here. + +- [ ] #SubIssue1 +- [ ] #SubIssue2 +- [ ] #SubIssue3 + +--- + +### Success Criteria + +Describe what success looks like for this epic. +Include any measurable outcomes or key results. + +--- + +### Additional Information + +Include any other relevant information, screenshots, +or notes that might help in tracking and completing this epic. + +--- + +### Checklist + +- [ ] All sub-issues are created and linked +- [ ] Description and success criteria are clear +- [ ] Epic is assigned to the appropriate milestone diff --git a/.github/ISSUE_TEMPLATE/new_document.md b/.github/ISSUE_TEMPLATE/new_document.md new file mode 100644 index 0000000..7a2f699 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/new_document.md @@ -0,0 +1,35 @@ +--- +name: New Document +about: Suggest a new document to be added to the documentation +title: "[NEW DOC] " +labels: documentation +assignees: "" +--- + +## New Document Request + +**Title:** + +**Purpose:** (Why is this document needed? What problem does it solve?) + +**Target Audience:** (Who is the intended reader? Beginners, +advanced users, developers, etc.) + +**Key Sections:** (List out the main sections or headings that should be included) + +**References:** (Any external resources, links, +or documents that should be referenced or included) + +--- + +### Additional Information + +Include any other relevant information, screenshots, +or notes that might help in creating this new document. + +--- + +### Checklist + +- [ ] I have searched the existing issues for related topics. +- [ ] I have outlined the main sections and purpose. diff --git a/.github/ISSUE_TEMPLATE/question_clarification.md b/.github/ISSUE_TEMPLATE/question_clarification.md new file mode 100644 index 0000000..b2b33c8 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/question_clarification.md @@ -0,0 +1,29 @@ +--- +name: Question/Clarification +about: Ask a question or request a clarification about the documentation +title: "[QUESTION] " +labels: question +assignees: "" +--- + +## Question/Clarification + +**Document Title:** + +**Current URL/Location:** + +**Specific Question:** (What is your question or what needs to be clarified?) + +--- + +### Additional Information + +Include any other relevant information that might help in addressing your +question or clarification. + +--- + +### Checklist + +- [ ] I have searched the existing issues for related topics. +- [ ] I have provided all necessary information to understand the request. diff --git a/.github/ISSUE_TEMPLATE/update_document.md b/.github/ISSUE_TEMPLATE/update_document.md new file mode 100644 index 0000000..b8efcf0 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/update_document.md @@ -0,0 +1,32 @@ +--- +name: Update Document +about: Suggest an update to an existing document +title: "[UPDATE DOC] " +labels: documentation +assignees: "" +--- + +## Update Document Request + +**Document Title:** + +**Current URL/Location:** + +**Changes Required:** (Describe what needs to be added, updated, or removed) + +**Reason for Update:** (Why is this update needed? Is it outdated, incorrect, +or missing information?) + +--- + +### Additional Information + +Include any other relevant information, screenshots, +or notes that might help in updating this document. + +--- + +### Checklist + +- [ ] I have searched the existing issues for related topics. +- [ ] The changes reflect the current state of the project. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..869b1b6 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,61 @@ +# Documentation Pull Request Template + +## Description + +Provide a brief description of the changes in this pull request. +Explain the purpose and scope of the document, the problem it solves, +or the improvement it provides. + +--- + +## Type of Change + +- [ ] New Document +- [ ] Update to Existing Document +- [ ] Bug Fix +- [ ] Question/clarification +- [ ] Other (please describe): + +--- + +## Related Issues + +Link any related issues or pull requests here. +Use the format `Fixes #issue-number` to automatically close the related issue +when this pull request is merged. + +--- + +## Checklist + +- [ ] I have reviewed the existing documentation to avoid duplication. +- [ ] The new or updated document includes clear and concise information. +- [ ] All relevant sections (e.g., introduction, usage examples, references) + are included. +- [ ] The document follows the project's style guide and formatting rules. +- [ ] I have included any necessary references or external resources. +- [ ] Spellcheck and grammar check have been performed. +- [ ] (For updates) I have verified that the changes reflect the current state + of the project. + +--- + +## Additional Information + +Include any other relevant information, screenshots, +or notes that might help in reviewing this pull request. + +--- + +## Reviewer Checklist + +- [ ] The purpose and scope of the document are clear. +- [ ] The document is easy to understand and follow. +- [ ] There are no typos or grammatical errors. +- [ ] All necessary sections are included and well-structured. +- [ ] The document is consistent with the project's style guide. +- [ ] Any referenced links or resources are valid and appropriate. + +--- + +**Thank you for contributing to our documentation!** diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..8ac6b8c --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,6 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "monthly" diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml new file mode 100644 index 0000000..3956d21 --- /dev/null +++ b/.github/workflows/check.yml @@ -0,0 +1,46 @@ +name: Lint + +on: [pull_request] + +jobs: + lint: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Install Node.js + uses: actions/setup-node@v4 + with: + node-version: 20 + + - name: Set up pnpm + uses: pnpm/action-setup@v4 + with: + version: "9" + run_install: false + + - name: Get pnpm store directory + shell: bash + run: | + echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV + + - uses: actions/cache@v4 + name: Setup pnpm cache + with: + path: ${{ env.STORE_PATH }} + key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} + restore-keys: | + ${{ runner.os }}-pnpm-store- + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Check formatting + run: pnpm format:check + + - name: Run ESLint + run: pnpm lint:check + + - name: Run Spellcheck + run: pnpm spell:check diff --git a/.github/workflows/mkdocs.yml b/.github/workflows/mkdocs.yml new file mode 100644 index 0000000..b6e823a --- /dev/null +++ b/.github/workflows/mkdocs.yml @@ -0,0 +1,61 @@ +name: mkdocs + +on: + push: + branches: + - master + - main + pull_request: + +permissions: + contents: write + +jobs: + build: + name: Build documentation + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: 3.x + + - name: Install dependencies + run: pip install mkdocs-material + + - name: Build documentation + run: mkdocs build --strict + + - name: Upload site as artifact + if: ${{ github.event_name == 'pull_request' }} + uses: actions/upload-artifact@v4 + with: + name: mkdocs-site-preview + path: site # Upload the `site` directory generated by MkDocs + + deploy: + name: Deploy GitHub Pages + if: github.ref == 'refs/heads/master' || github.ref == 'refs/heads/main' + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Configure Git Credentials + run: | + git config user.name github-actions[bot] + git config user.email 41898282+github-actions[bot]@users.noreply.github.com + + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: 3.x + + - name: Install dependencies + run: pip install mkdocs-material + + - name: Deploy GitHub Pages + run: mkdocs gh-deploy --force diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4cfb3f0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,15 @@ +# mkdocs-material build +site/ +.cache +__pycache__ + +# IDE files +.vscode/ +.idea/ + +# JavaScript build artifacts +node_modules/ +.pnpm-store/ + +# macOS files +.DS_Store diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..eeeb7be --- /dev/null +++ b/.prettierignore @@ -0,0 +1 @@ +pnpm-lock.yaml \ No newline at end of file diff --git a/.prettierrc.yaml b/.prettierrc.yaml new file mode 100644 index 0000000..10d1f2c --- /dev/null +++ b/.prettierrc.yaml @@ -0,0 +1,10 @@ +# number of characters per line +printWidth: 80 +# convert tabs to spaces +useTabs: false +# number of spaces per tab +tabWidth: 2 +# do not wrap prose in markdown based on `printWidth` +proseWrap: preserve +# use double quotes +singleQuote: false diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..d72c7f7 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,8 @@ +{ + "recommendations": [ + "yzhang.markdown-all-in-one", + "streetsidesoftware.code-spell-checker", + "esbenp.prettier-vscode", + "dbaeumer.vscode-eslint" + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..4a8e89e --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,20 @@ +{ + "eslint.codeActionsOnSave.mode": "problems", + "eslint.format.enable": false, + "eslint.run": "onSave", + "eslint.probe": ["html", "json", "markdown"], + "prettier.configPath": ".prettierrc.yaml", + "prettier.requireConfig": true, + "prettier.prettierPath": "./node_modules/prettier", + "yaml.schemas": { + "https://squidfunk.github.io/mkdocs-material/schema.json": "mkdocs.yml" + }, + "yaml.customTags": [ + "!ENV scalar", + "!ENV sequence", + "!relative scalar", + "tag:yaml.org,2002:python/name:material.extensions.emoji.to_svg", + "tag:yaml.org,2002:python/name:material.extensions.emoji.twemoji", + "tag:yaml.org,2002:python/name:pymdownx.superfences.fence_code_format" + ] +} diff --git a/README.md b/README.md new file mode 100644 index 0000000..51d0ad4 --- /dev/null +++ b/README.md @@ -0,0 +1,80 @@ +# Strata - Public Docs + +This repository contains all private devnet documentation related to [Strata](https://stratabtc.org). + +## Getting Started + +1. Clone this repository: + + ```bash + git clone https://github.com/alpenlabs/docs.git + ``` + +2. Install required dependencies. + + ```bash + wget -qO- https://get.pnpm.io/install.sh | sh - # install pnpm + pnpm install + ``` + +3. Install `mkdocs-material`: + + ```bash + pip install mkdocs-material + ``` + +> [!NOTE] +> Alternatively you can use the `mkdocs-material` Docker image: +> +> ```bash +> docker pull squidfunk/mkdocs-material +> ``` + +## Making Changes + +You can add your changes by editing/creating the markdown files in the +appropriate location in the repository. Make sure that you adhere to our +[style guide](./style-guide.md). + +To preview your changes, run the following command: + +```bash +mkdocs serve +``` + +> [!NOTE] +> If you are using the Docker image, you can run the following command: +> +> ```bash +> docker run --rm -u "$(id -u):$(id -g)" -v "$PWD":/docs -p 8000:8000 squidfunk/mkdocs-material +> ``` + +Your preview should be available at . + +## Contributing + +Before you push any changes or create a PR, please run the following: + +```bash +# check that everything is formatted correctly +pnpm format:check + +# check that there are no spelling errors +pnpm spell:check + +# check that all documents follow the markdownlint rules +pnpm lint:check +``` + +Errors in any of the above commands will cause the CI to fail. +Formatting and lint issues can be fixed with the following: + +```bash +pnpm format:fix + +pnpm lint:fix +``` + +It is best to let your editor help you with these things so that you are not +caught by surprise when the CI checks run. This repo includes settings for +`vscode` that will help you get feedback from your editor as early as possible. diff --git a/cspell.json b/cspell.json new file mode 100644 index 0000000..dbcda78 --- /dev/null +++ b/cspell.json @@ -0,0 +1,18 @@ +{ + "$schema": "https://raw.githubusercontent.com/streetsidesoftware/cspell/main/cspell.schema.json", + "version": "0.2", + "dictionaryDefinitions": [ + { + "name": "project-words", + "path": "./project-words.txt", + "addWords": true + } + ], + "dictionaries": ["project-words"], + "ignorePaths": [ + "node_modules", + "/project-words.txt", + "*.json", + "pnpm-lock.yaml" + ] +} diff --git a/docs/assets/favicon.png b/docs/assets/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..f29686d921b9886dad153d9d74a16ef31436c858 GIT binary patch literal 22140 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�vGlv2vPvCR?MrF~J@AjB*sDkJaH}Wa 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 z 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 BnE_4@eyX?Qt1U4Fml@^Dek88d;o)FPgK3pl&br z{n0d#rdvj5`bt=O_LhGvPryFv*bT83U6hnNo-S%{n?AEXcYPAU!_(nzw)VKJ^936E z1pl90t&l|Hhj|ur2lT+|RyQwEg(ms41Icf-aS9=EGKE)EltO*t6vYg&u|wS(2fk&s zDMxi5xtjsyrD0_5FqHPNJst1$>@bbt(2*1`u9Y&jVF0T4pBd^XhkGq0cLB8VQ- zw_U9Es7#KOI_;$VGw^M(X~01IWOj1eqHNi}qH@-i;OV@hMRb8B^g_j)62ob?!C8R@ zENs?&8IUhG_Txq^>q;TR{GKX^K9_ds@BIK;;bvNN?-{dK@uO$2H>%Cg*Qn-wN~*_v zvT@8ALO8`lV(s20>1c7%2OGzmC5mE!IxsqO?gd|Y)%u4@^&W)|Y`5;B*BuZmAM@!w zNcwQS5eJ#`cgCMJMM=sz1yw~Y zBWdVfOPIy6V#-#kJzF5pUm*>0hE3$J#4C<#Vi;y7R(`iUJX4CUZ#+xs$GTbQU^5lO z8BHxCx!g{=epgiTXGI-zY>_s(tl)jkbA(q4=QgONe6mUeMZ2PSdyOzYUPaRk_o!L! zE;}H>Euaxa662ZsuzNVUaI0f%!F3vKjEk^;gIuqCmtIz9tHR0qUwDpND=gIW2aBgq zywf-L&rA#Jy2bb^=%h4LG!U&d5gwpYBx;176@X-u2olPtI9S|_AA{;@rk0WOP|SX# zP@M9jNJ~5W-y9nD%7IMgeOAeOF>!(`-q*u4lF;J#c*>z{KM8^cneUzW0~@18^`=jlUY^11=&yP)rq z@EVA;AF$xda%EnQ(y!JOdWbZwQTniFSpe?NR)NUO|JaH|aCYjE zTgC0s zAX~i%7fA;=yl~1u4!K(`pMXsRXRcpC&`(Z!dDtPEUdn(XS!6iP^%k-n0z&~91n8X_ zsCslo-&tY&@xad@dFTdh+|@u=a`;`J46_|8#V8voPsBbdVuLW>dL0z5tdp}R8H>C7 zzgn20pG|yMQ2r{I1{+4dP@HDI-_YzI`*9x$$*B6I z_8J5$Z-Grt)R4Iw7dzr`kTdrjw;eSWo?_F~3t!3S=R6x6Xx&k(-Cp;4qo35y+-O*gT+`O%VQ zVxC@xMoIjs8rb1dx#v+3jR|G(fG;x@&Y@K|3Iq+wQ$u`rBeN*@&&LiYkh|59Th8{& z)IOecIVWV>Sb8$3hO_(vWiSs^Y(}s!`fth_0p4~mx_sGlWsgsc$w_-7K^-I}&D|pB zM?ZMb%7=JhaCQpNTFEY;brkKFCVOMFS_xPzX->T)qE{HYjYJj;^;!F`!)7@FZFk1+ zP*AvZvS2OPwXF5fqpaSmrqY6)z2J;y&}*-HngT*&O;iPx-B72X=RTKRYsJael{-1i zEb;?FgKh7rsW+?wA2o-&{8T^n>g^$?TrH-#b}<-iFHHVRuny`|MiZOHq>$NDJj}Ea z)Lj<7;POTpf#9Yf7t}zCR5?UF zWeCEK`1zrR|4hOKc>QDvo#Rtyl;$H?it7`_3T$6`--|2Y7fd16$S29#nyqpbU(`>kqCtUfyC1dnY`lMh_l0-6j`Xeg>WA$ z^>aib1Fwj{19QJesNpUD)m8!C(r4nIZ=VAxc?2n}$~M6C2y*1qINv=5u*5Up)i!?t z$6Ik_g%*@pr*Eh8gceb6EPW9d9)_p^^4$syYUr*V$V&`x)TdNFV~;C4D>7dUd@;e) z)@PR;k6h(3RPm`N<{)#yYqI^0!1Ns>Lp^XReE2SW3cs&JL8Td0NCQqfqu2+L8jrFs zgQQL_nT=x{kEbdpq0u>W+(>2fS0B4VE19y(g0eK{H zHczb+S@+Q?gSCwZimJ(PZM}f;PK8UoZt{+1H7}DAfsV?EQ@v>J@7|pY@+Kcd7@JNj zzP#vtvkHC0e!Ygn!BQAf%blNQPXpcICuGogS=|@%;NtP3(b@L&Y+jTGG*rJBZQd_R znO=6RS3-+t{1*QGaukFiFDj?Om0SQ{s^N?wEy9o$}0W*#dXNlk@)+1+g`KxNy)|?@m^jw zRXZH(Z&7v%7fyR6?eSPqEBSQ=M?AFU&erhOII_SSG;yHHs$;3pX6%2oW} zhwYC08PS%3r=(X9Gj*_%TFx2N(OCw6TNJLiRp~rXS+}T-vu}llZLbAxliK2M#br9^-=DT$-&y8NJu35v+%k}dk zAJ1vw;=!F>%+{?UF($rjN_0T~(oFk#N#L0pM68= zG7MU@#YLVfyDy0{N2^~hi+vePb4cZ(8Zg>RT%JsCY($R;A2OgF6`i2Wo^L^UgJ%n_Uhfu06H&n!;}_fD&11>Oxfd3_oxC;)&4-WD(2H z47FqbUzy1-XDcWEvW1kD15#obg2fKk?q1Fpf7E#jcQG2&EeXU{L^k|_xYkl;1smNy zFW9F0l=c`D9556;c66CSojD;nP+XFMD0SB!5uto^hD*d5svS6h&PruSBa?NQ9kfZ)nc#Idyo3yp^s)Ny)bfnlJUG*Dxmwh z)XKXjs1JO=<%g-!#f2Lmq{z+%`An-}01R6m|0`PEy8Qi_qpIY@L4drY70Si-Fxzq0 zu@NivSVqP1nNJ79ETZ-v&!7?K=iYjIt$gZmLS!+B;T1$pF}~jOFa7dNN1L0 zOLQyMOe-TpZpS;M#fGLL@a5mgC~GJwRYYdV#1HpxF0d?n7LLkQ^cV>*KSl zKs=y&i>()FpX;{_R_Hd(VDks&zQbyFl44@slX#lVq%SU#Bz}Z*iai9oK3nw`>Fr({ z_oD?Dvx;^MUtL(ald&jfPz%KTESqG}hCi5BeT|=}Q%eYowf4iNAXw;b zc$%No8yt0WO+WETJbk7`fsh%U1h-?)uiJ5&CHxa!#X!ib@{5>D9!=8m*+jBUGo4wc zDE4Cup zpdQtbb%r`Bx<#u6<8g`fwBGhZVn*OAV(NNzx#wxbPDeyJ!M0)hulx;6jvce7C_|R3 zmH+Y`q(O@;(=y#p>aTpi`evt0V6bd=N|F|AkvpE2EZ3+G&F_ImKk@a+v;v>iV|HcLjo1inT48*TxJ^mb!dpRZ`>9PHl;C9-(`*kL}MK zAvyt*s;s6`gdHw`GOU%?@4fV(<1io|!Z4-x30}AL*OOfpX3NiiiG1XFq}KevF-Oy{ z^u)mkeLLG!Pr<$qf2EVBvHt!JL5y1J=0>59{S}G; zT)`E9t1Jqm^g*TXInYWp!VX=rVshFM$S7xf*;Ues-8ReOaD_XVl;CZ=3r8faRd07+ z@(TATvVHBsh<0o+vas71CiU*5zs_aYh(&HLN_7W9OyuzlB07VOjoReyhL(07b=up? z57chXD?EQ)l3d+F2frsQ4RDDatJZy#w*I=UayIbbA?KRPB5afL?9Ai zQf1MNjWSH)aR(%=OQ-FG30^Xo*gS(ZOp{(k(&ITK%6csY6h0U1kBs)`4`MEJ?6*v$ zL4o@bfyfAwi}-yHf^Hnv_AXeQ+vF$P{j#ccZo}ihE{6UvAM&1>pU}Vk{9VPAXUfL@ z-wP1+@5R<-_J?e?x0OtAK&a0+)V&qSX(eAjK$=NE7o(N^AvkAENg3KR3@xu=Z^#zr zXVHYHtV7loKCjy2=;bi;p0|OD^;+j!VcG zzFtD7m6h#cSxz5UK6{{V)n65OD=feB!=8L=`-$NVBR(I((lHG%eUE?E(yDMdd`g-z zGsq-l$O4zMoXQK4$vID3_lr+=a4s!V(oL5jWcT74nbdi+NTvKLtRBxnQPw!fNALq2 zCU~GF*nQr~7SGA6KE|6E{kkPD;*hnI@(FnicuG6=UdPk%B*6ndCf;bN`UR3HU+M=Rt`Yba# z+e=1Ay-{F7AxbOL@rg}7qOOQZ* z$ub^cyJh@De9i@2?F`Vjn0w*6{74hBv({Gq=xZb#X~S1lmLcg*y|HU3IQ0?4jI%S? z3{TFnZ;YZnsDeG|Z*}r2ffs?q6gZTzT-x@$0c{vdjdoJ!^U0b zvUp>k8&eQTl}s_V9or_YG^#I@WMTb+asn5`nfxKG$m;IOWcn8Wul$3WEJBp?Qy^%O z$Pg)*h$;ngwUuhW%{qD9xdoJ{0eXLP6doD^z7ZB}k@&HEg|NupqGhdCT$+yep|4Lj zcWg3t#s0F-83X?7d=ryoSSG#^o}d{D!%rbS765QkDy7l}d5H>=H;VB>)Vlcc*4%nX zb%L-{5aE+-E+KVf4zkU1Nj_rQws`7LhU0emyI~(*DkwmEJmP*0>K{B@MHcIliteJX zXOtn2ll_((1JHEL*@tLWvfV!m>UNaBK!_->w~DPgE1cqvLC>X8PFq7%?cJ}IfBd5d zjHL&h%3JRc*7G=mP#-$!(VB^4wcTGq`*;N=79dAQT7r$uAp03m>MvC?Z{vfG8PcrUr}c$A4F@csVFhiQ-Xy&0Q+uuv4YVvGok6+9BA~BqYs}0?tA#$; zQO~zH@u96NsZ3b3?27-<_1*XKPW{r&h*^ijT+ba8$r8s)O?`mFe2$4AQQs zC*6)scZzQs+Q-*V7(=D$8-x(+M6|X0kfv6cZ28Pr3+9Av;_0scL`@bZQ|d5Pmz#0s z(c=Y*;x~6Nz~;AzC^u(rHryjYXy*XS`w@8 z2PDV)rEvaLfF2%Mh@&s8Jfvj5)9$qD=%Sv=U0A{GO_Tn|w?Bz&h8EdaFSM}|A^(xH z-{T{y5tU!C0Kl$tX*8ItsBD6TL-d51CMMX6^1H zM|qE|-n07ru6tpdR;i0_nl@6p!>;D|WU=Ei$(S%PS2FRicqoiNg)(DunJ_nU`3tCG z`i@SrX{h@K6$&;-soZMLmaq(~AP1KznaBnty&D+I-;#6G4Je!wTc79Ry{asoTW}wT z{G@u~7q(Jt?#o{Hw~tezEoPvdkDia{5X_Eu9^N2fxgDbQ{lBZ^fD)Kt(!aeb#{@8p zI2DJq`3r@5SG~QCG0x8h5@}z#`>}Gr3o2sh*Z_k|l+{1Z!mlD&XHTjY?HTPJ>FaRu z2zxgW0RLDwEq*oW##C<~aP80c`$A|{xRYEH%*UHs@eaH2W5QHef(Q;9!^6xnbq2?RUWx)`Ym_Ooa@iOHF`fnx)`2&e7rwpyY;H$7vQ~(DmUUc zTCG7Z`keXgX{gvcN}xMH$sG%5de#1#F|qEE_ZFq{$JJk66BSY)317yyrpVrJly9N0 zYlRLld`r&m^AeU~{n)odX_`y3^64b0&k+G{-}#6b?Zcl58=SUWs&&Tu{tP=iK<`g~ z)G-Fi>OPq5Ec^DVK`92~#MASJTVNch2RZJ-BImF3Pf~o_!Kc9~;8U05P7>Cn5|3Gq zvDoaWB_+vHiVx-*DckF`x$iV^Jim<9UEKQlkvB<6pkVsv9ytqbN4Ly5iWyZ}uyY6> zJXSs4>bkZSipYP~uAT3;?5!?srEHtM8+)H!`T03#ZHG6u{3n9huuAIbZJ|RGdzRxEqqFYP*3@A zwHR6)0KaztRff=GrjehqiWGVjEtVA{XVV27YlU>n-TM$q z6ya_{t?0CvyoLCZ=hO!uDJ2v0Km+K&mV@*Jb3-<6JL$tC&RWcy|B#mcJgiWySE5~r5_s@ zdZMDCAKqb0CqE8}%5jVhwU4CwI7MuKx!+PORL6g04eGP-PPwnmI0F8hwX6G$#PNV^)h*`DHB?csspo8-E8EX9E*#itM{5I{mp-YI_bvuj25n zk*$>4`p@vbuNHE^C~g5K`G<|4CYx+F$9|yBunXR6%XlTjo(X64U+|qPp<9}p_tln^ z6zJi#`{cV;%ZK<;X=Do=Ur5M2Gg|dTZ%CUUgcMM|Uz`B;sGfEpU1OqeJ8X_+T(=;> zB+l~MtA)3PlZ~pevE#!5sjjQS^mz7&T1Pt_w6@S-^Wh`TIRq4VjGXe?AG1oX{|Bto zp!(J@dDg@IaPgGW)pmSiys#MfVPCF-x{4$M8vo0Z`{ZK2U_qQfU;DnYvEeASm|-;2 zQxc+jZEeJS?5h^~_qX6KVQ`n7JXAgrhgmso2Ksg;6VSyDp;X!CDf;*93FZ$9HKanU zh5bIZW4-fyP0wV&n%>eS%=VgxUmPVZmwpH`M;{&E2B{o1`>EwlR_0{+P2H=mwl@+v zx;Xp7?mvR3f7#Ri3bQdi$2Y(NFr`(GEQ+*JHvJpyLo6~xSE212O$#lOuih>hgGZmj zD7UJ1!$yc1%<+B%8ZqK=@?AeNde($Ba#5)y#p6^GwjIRLo|u`ifC!f0DqTGuF;P+K z{6aB4A}SH$%E=svCDdX>Zz!%UQH*ZFw%NWdwO2{8r-UiaIDZ0w>vA@ZfO2Auxt_@J zsD!yk)#A>VrkpSSlM0&Z@Z!?i8^3bfuKV_wdQUc9n-UUsDG421!PioS#bPt*NmbLe zLwL8F({uDt(!^YCG5G<%p>3Gdj)r)zo4N0{bhoXVwy}u7+&R9D$*~)C;z~mY>D}(! zA$FpOc&^cFe~}UOh~p)fRMsF6_4m11GrE6hh0B#FKeG2pB?+z-kw4d-j@ilU?o`zM zCL1HpFj|d+OR);h?D_SJA04Ymi@Zvm^BZ==biIAcQeMTg?26DH0iGU70;7oMnrEE5 zn+I(##f15*7xw8$P4$e|9kd;jyU`f& zF5nayZUzXm{)J&h^;sq9+%HG-lgAc&TQJ<0?#`zVcGEv_2{*`zt{=RorUy?Qz|Gs0 zWMwZBMPn1KbL<#Sgy>T~p#t72x=vXfT_nGk5{c~g`<6;(zbMsU&~sb6UkKK1#i41n0szZA&LD!F?WfIdKAeE73j(>y}FyPLBT)n zo{4bH-zuHeU?3&9a&|?gTlZUD9fm85N)ev$?Ul{_;)$eAe|&02n`ttUA9*DCck0|= zGNZtHxkqm4TTg7SJW_2_Nn275(|yDp2`>j|m0e;9=1#{~Z{3o^1vTN+PDZ?EohOR7 z)FsEMCkq{QBE)+wtaML2T0?u*?cKE|Pl>qr*NHjwycrvL&6UT{&3qgcp#(bBl~S2j zuRYhkxG(pu)a$m4OXa?IYXr+f@g=@KkcR>#O zf`)Gsy6)hApqEX3surI@+Pmp{ynlC zna-UX9J~rm>^CSd@Px$aOofBFwy7+?WaAk2*5Xs{zwQ-+a;!!@Zg*#RlZe#()oHpn z5;dq^TI%Hv9d^15@@m|gl@P`vAzc_jss(>6e8H`2UQ^iv=T%SA`GG*;X{L?lLpL1;G}(PA$WNkWTyXDH|)hAjNpEgJb< zJ9s>{QI#o1PN3`7M4G#p|93Ja!4r|&1HqsDS0LI^pUDklo#V6%0JX|Rf^JmBNTo~v zi@aQWdVR;HeNb*C_gc`oUPn~F%~yHus6KVs>G;2L@HU(s4*-+7GuEyTeW!W9SU9@n zv*K3qPJUBU7fg~Do+pmAeP7&5_&%nKnK8d*P%zIrm-lH%yT0wPnS|7ALhpr&kDrlZ ziBgN`o%EiGKXQ2?eoM+-c)lIpcKwyo#zY$r&XmN3dYf&NNB)MUz{2<547A}3#eu>! zBtgg9t50=#Pwi%Sap2&k9!R-rv1eEb-Gi=S*q&JYRw{k{>XbD+yg#22Rj7du-$w8a z6J^71#_m{{K37p5jTx)`PuTTJK?|Dz4hLAs>u(%_)JkgW#buBrAsQ!*x~Xsf{prk!_Nxv6#z!xM7P9< z)KP?a7uq$WQc04Vc8Msfk4ZQyI`ld$){4|_!v&lwn0i3Z`<315+Em;M-@SU+`s^2w zMcv-ZJampall1vKt5K|UCyMt{-=Jl$ zV}LjLY&)P9jIC6dNny_mN*0Ol_WN?3%wAq}#OHR~TXMuh=h}D^hL+ctZMhJhD|z+> zwi+HWrs-GOCEB-o{jYztzV?=C-2hlZURzt;R`!a>{r;n0&s?f^DDP20!1Q0CPAmsb z4S+;9l8xk`bQrdB7%g_Vp0ts{z+?lfz^V$ zN6yT7dz^KgibG5~D8LxzqSCq2U}&&x)=kn5k;fz@QBI7%M+!;GPK&} zp}*5E!gu>m*M48H{7+7$yG?wSXagEX)drAhmRk(eyKU0b(#|(&Tgwg04TCHfjZ^9W ztY4%~K+70CX1-;<6m3B0HJ z2IBmf9^T@!W(#{Tc2H@yQYGIcbfR$^WJ-@24GW@h5jA1#n^C*1{X|Tx%3R07Vulq*KiF)G{dV!>62U2hgcc)F;)FKE4 z9;8d@E%^_zR$o)Ja#@0Rkw4l3aON{-6GS>QL(ICUL|WZ1^knQ~9s$wNy4WyZi-Nv$ z!M2`eH*Xb8C2zkLa5f-b#bs{Hp&P%rONt=M+V>k<<&3OX&;G3iP=HP_jZ-ZV?91j0xg8JEEeiIV&)2Q?JhwUP#7{kNsVc}}In{K+*g+V&7wE6R?dp1^ z)71}6Uv@Yyxi=mFBh7w7<<97%BzF$jV29b>M%z2zuo62Aqe%4pltdPjm*KerIR*xq zun&2~tRh?`-+}7@`gGS*1hP39&vzQv$N6_WBr3~SI?q#2HKWMNVytdCe%sJ*`TM-6 zyt$W1nU)gL38Efh3#gTvK!U52G-EHz(IB%PNH33$0P2%E`Nbr>sV%vZ``=&i1hN}_ z1F)F(137(KjI>(`tQky>lESFSB!2V)BMk=F=Q~x#6Ik`nLa1TJb{AN|c_-17pshtr z)3DgxR5u>8U~JWTHII=~+!xoB;?BICB9}gDS7ne1kJU_U9k#STL$N*^cy?~$vjWcc z!otS+&?jN~ngc@6=}@_|)@D4)_jp&oCqtKMH&>zWj$Z!@p+NNNxd&!$X;|ZB#OQ!a?HiRo*B;VbuzB+HnwLR`a0^a#z`@V+1@bw4TnrUfDiUz| zz4`1iT}yiuyRP{TblARe<&XWk&Odp%g?T;+d#|3pA)>E@87@(*8zVHOB_?lGNBUdT zSi>RWO4-hAsE9qr(%=*{3-m(ccgDJ^r`>N5XU`w*^ZMJB=<)VuU;K6b36_h`KJ&5o zOk3WL(Qe23nWxRMk?p&sgGJ9n>Wb|)T=!u!jOvE7;zl?w*)57(a^tW8RNYf#NUYPtGY`NU71`{>w) zX!APy5J9atCpTGU+28jN-KyLh&to3_qH@K52DrCvtyLWU>4R(ZVh;}h_LAL}m)e!* za55Z4&oi#ks%z^hf~R>`H*tX)+R}*^DiMoyfnL)MXOqz6=eIv|ugy}A1P5>8vrg$( zd;#U{Q2wXL3hmgS{=lF6!8Ffv`VJQF{gzKN*1+~J{VmBMC5auoRnvvi{(mrI2VE`y zF(&DpiLy$9fgDeNnjWjIp7yMv=p9d>J|dMKAwbS2&2(tBjy<~_l)hip9D#Uarl0w5 ziG$fXXfc_n`uQFntmd!xE9sy}J{8hEaZ2Kh{^IGFvFes;s^gBcf9Q%bu{%f?ySsc=MfAK8(dE!Lms3Wu?(Db?7Wjn3AhqRRZ;i8}u}+xQ1w_G1oi@`)V29hBhb;8j|97g@*bSX>5Q)^b^zVJxO<*|`7h zGmuWKKvqj`!t; zRgQ?vOSn5fFGFp7_8hOKKE#o3`T|WuPFdO4asc?D`fxr~{5?YSJ#-!{!rA#m6n;)EUE5IeH)W+N}fyRpeQ5=y)C!a;$ zt(VypHo}$?&Cnm@`z;H^?b@7@RLa-6cU>uYHioS)DD8%T;WdUS+VmBcU$84 zjS-0vtd~9y$mcLWSYqDX3y=ug#;5!d zaU#)^&o9=g-9Gc`_gO!=!2z<<+4E5>_B-R9u?$vE^sBf^uK($INS=`WZsGU11!;{R_9I2%aDVDBHTMTx{d zujFabESng5fmc)?Qfc>slmkWN)=vjiE6-HvD4G=1ia}ZOjD~;Sv5S^%Q}TcEcKJa|zZqli?SyDn4uSQlR4Ya>n;SD> zmB4;C-P|YbY8*Zs_h@g+(-%g=JnNNl?_|1;lV?z1JOW zS_s`99X{_RQ2{ZFaw8H;DX!eLQ$(VC19Ao$Y@h`*)ZIswXPo7ZlT+2V<=Vex8w99( z$zn9w-2W5xjCK1+wRQAOQU2Z=Cygm9(m%woVvR@wq8_j1%@WYuI}x{Ocr%ydR^?$X>vF0`-?skNn*3Jt8IZo0-g82(YZyoZvca%{Uu)enT|$ z+~V4AHfA-FjQOn4u1ki)4F8nfF^{Te_x;20T-gZ- zrCs9R)@4msC}XAw%$p6NCS~U%Kiq@=EIRR9N&B2Gsxj_Kd7t!xAPKy)JKkkxQLHv+ z?+gc8AP@TqVMM?5vp}^yOQhznKH-4xY0iwwb4>g~S;ME?!IPUd!5B(FZ$xryNT%%L zy8suSyTpH(+r`d*iuUz?I(_oi27TTQe~P^Ecj5lIB>eCdS+X&F^0u}ipOdAkJ`fUL zcHj3O^HMK1oLO9diIs+Zd$cBo$0W(k|Ehfx-on7aQlGR%v`d5dlua$Ki z?uNq_)p1%Kwf}0O)fa4vm6OlDnTdNMk+BPhkY(Sj(}+y9Ro+B5e_adW>2AXz_JK%i ztYdXY-;pzcL!SQBv>6g3rqFA#c{LG<#9`{kj;Avtu&>thSsg5Ok}GvL@|Hh(9TEID z+k!cB4cGL@1P4v|%JDGrS6)z8RS)U~-O6V*_Jb>A=zgY_h;(X32X1!;S^2gr`uF@w;KR6K3H&Uxqw2czh;aZkaT z;IjD|SN#8^#Lh$?u5;V6s4U~lP`UF4C{=isy$|a$l9(fG_!n3t)xxLV1w1?;o9{4K z7xj3o87K`r8yzB&Nhh}MqIMo(J16z-!!@@dYMi|)f2~Tn$Cd}dB6!lvQQuJM_#dOP zB=DyaVML9hzT_)}Y1`S1DckrCx-P_EfBK2_wur2TAA%zla~_;LPqPt`(`Hyn1 zd{-PPl!VXup51o_mg-JoW_k!|F zi9A&L28|m&SJqbm(r{i5H<88thC5?A)UlF}^@X%qT?E{%bn!d!dP%k_XNlejk0PmZ z{rCC=NUe~0c_A?L$zOE==KoiiRp@qwJMz8rOm{QP>%a_??vH=KvG>rSsbr*D@M9K2kpL zjc7Xh0P+{0$p%aL)yvO8Hj|OR>Ku|?^#y}7>Z*M0DF7yXf$7Y*(`~o-UWjZf9|J#r z>nmPTfjn!NpZ8(x&Y%)-@6B}16R$Czai`0DLGr0}ipzTPJc~}0Z0xw~llotDp^#u# zUhPSJx~6h&1XY)h@Ex*`qxS>_iR~|aY~<~6bADlSuMI~SFX9bp;p|xfhJ**3AwiK0 z=2)DWD>D^hlb0svhi(o*V)J3FP!Pi7Hq+VAxXy^=*?(1R+tfSj_9BboHR!>Kag+Z; zVwCSGdKVTS$f=H}=C9FqQ}(?+s1Q=pQaJ8*Gw9IKbY|T2%wO|}%c%?w!1X-0iHpo4 zAOHA0EOe8`nPmMe`h@(#F3{y8Q7X{ip{ zn96G~c# z`%SRU^C;yZKqlODT7KVQcisQMDKU2{=HwYeTrcJH)-gs3;=%Qo7#?iieTRr;2JZkc z7XhQ=zbinTI1#W+-VqN#9QzC+v%#GCbhPHVC!Yhkvf#C1)0axZwKES%N6-HFGDhb- zaFIO}Y7TFzZSlbtJI>p(c9J1;KU{P#(1URkC`?lBguJ^kdpJF_>kz9CAenM_cIGE> z*YP6k+|3%u6S(=?gf-!e(1Jlh@%2%UnNsOg!loJU&8j=}-vto6J#3GoQ{h@2iZXY? z`~JWCPw}o{J1FC2keP^SXNGk5*e*M71gkSFngeJ26q$Swzdy%zf0YdT*8-56fM;^x zBCKrwg=)%0;uAoxBWKS}kWZ1UuCRj$9!r~+N3N}Twl9pv@(-(T_aC7TaMw|GPc0<4 z%WRGhwr}hK25;qrHu~E;?*WGpe5WI)r`RU^rfg|fO*k_N2XWUA#9jO-#NvptGZ8xt4`(_wS925gHkP-jQA3SNUzngum>`|*i9W9}MaJ35xo6l>0Z!#J&dDMl@gMsH;a>qa zu=)!YoaJr9>~j3VOZsBtJs#U*%W>Wa48!oh#MTU|XJ*tLxj}$}x0gN(H2&Tp9u;oHd8vxAu^(r=C;zc&y6KhCft3cBuw(#F*h55BW6Z~z6INT92B#BlrDV((t zSx)gBn+$B<9_n{?d|je11hM}0{f+OTXM$d`3_E80h3l_S;Lc5^?EgF6^J)^NQK&xO zT}i9dGZ42$Md1!H1<7Nk5|$lzx|V?z!8HyKegM`I9L9mzE%_VK4@qBa>)bXv7(f)S zIMR%L3x86$;}8fRMtm;3q5L33LQQ6|zFqH!-jiqcM|)k%#F6=wwZM+)hBa+}foFaN zjzXIf*QE#Klzp+3sv%m3T8tnPSpGt;LT|1fX4Lmr#OY{syp5l9_(|PKdAp$@?*QB@6^1QgT=s zih!BDyLcIE0|BV1W%72^GyjuSQoA30o0ejG;1E+yRRG}$C5Pa{Nq(O|Dq~A^AqKV- zy%TShI{B}c)3_&a_(c%Z?DjJGP2GLn984V689aZ;Bb8_>@8^p(2TE%b8QQJivYTor$h#`es0K z4(jtAe_qM^TM`*E1M)pRzJEs{xk}-(nzl+2mi?8?dHd-Z@5Y&<(06x_7PZ=o;nkTd z9np2&>c%{vBakX6bNG&Tvi(e{#W)SC!|G>>1Bn67M)&f3OW!u@w<7|oq06&aZQT`w zOQkbD9`uKXJ<1_Lg2?WXh|RBy`czLK^R?KWDrb%geS zc2IQA1jsozA4Mm$3|k{9f_#6gwK_f(gMzNt@Z5BPx8MP%5Pr{rLjcJmofWs8Kf1ME zM&OaWSqxb?qcS7>iVXI-3Wl5mj9OieW1~c`va7FvQ3tK@5Uh6D2J^zh=xBU2Fgl@h z=I#}mJJgt#`9i$+?7LhQFE<;s+@2rWhO>D4JzMYdBtM@OuoRwuM+|EC8G1H$PMIh! zuX>s7`}tNu4!$7z4tJf5K#5JhlJ;-p2_!`@dZGq#GGqjvHOw52F_(PU(r@G0SK{EH z38l1upYH%go=*~T=vD5@XG$T*I*Tl9b;}QID0lAQT2SV7rktA&oKbLzqy(HyplATwl8$$`2vC_c_4eiCSc-IQ9tA}e@SBi9 z=$F;KzVX;~dwMYSPk*PLfSn0235WQQadw5R@1!ubP3cC0bc+Q(hf*Nptz&uAz?N&& zERS@aKY6ko(=P0*8MAR}A;Djk3Jyf=SpK+$U^{eEvNp^Uu-HM~NRtyWr2NIz&%HcL z1!0%9B+gwie>-*4@XdSPk=9~kJrSXCfS^cY9#=IQrB!GH2Lk? zQ?vsqr#c^&S^k(0RGaFlD3pG9teW5lXA2;Sh3lI^RPW&S6*ofr1sJwC@BvFD@ec7^ z(42^aX}u!?6jJ$l5xlz&q?y%vl2oQk-W&JP7|!{%~#HnN#MJh^UUt(7FH**4wt96|;L zxGcI1WhK|c>dGIXHy;4q&-+s#j?6i|7<)Qy;b6Q#8r}Tv)f0r&s^w@5aibUT-Uv5M z;zU-nJ>;o3zMefLjstqqpPiK)MW72-&(x0OfLvi~J3Z<{jt0n?7Q0@}0X zZS3D{+uxPqNPLlxaAO|O#6%H&rmuG7gB9H>t*`X80cqvhP@Y_iM&hY`g{^gjTE2;6 zG-KO!NdAEx@J!)aAr*XGioM_H0#RCy`-~~Z#}GiRomqS`CX*%sNe(ar0n3$%x@CyR zfQZ1unP}B97mkOd1cc&_MDwr)WjkYyCQlYymMD}|=(29(cCaxHk2grRdX{pB`|IR- zz6#i8Q+{4e7HJ(^ZMQ)CG_`Pz_@b@ZtU3yprHw`=Gf+H3=#$Cd+s1MYURUi+kN(IH z%R8=~EOO1qYWN?N_8Ujw;q=Smu65F+228#b|1y8`VFl^j7BwicK(zn8Jd!H;5h;E$ zDi-?ZY+dD?nOQ>%Azw``woT$*hIn`v67!uupqjl^6&2WiFB~k~0InNuN2!)^@tQ+8 zNVJAU+HK2f)+C@B9ypO&HgszD_g zU;A1%*YK7U|D=HL@z_*a6bWerz~-G@iLGcDzV9h6!(!OXp0Pl{?RSfvA=| z0N9R!{%$810^t7Gp82DTT!2S?3Ku7%OHD`y^;_@i==oH*L+m$crW#KYq(^_McjNr; zX9PxvLmii_Y`e_Aoz%9JqX-gSS&L~`Eb&0}Z!%%o*4@b=`wVHJlP&#c-F2TMK0O>g z6EK4@&ME69^cMmc4EjN~hp>k%LUMvMmXhRkKE{5w22Ohetk8!j+3vfJ9a&kp#`Rgn zz$CLej^My~k6($l^q-m}J+*Jgp#U^^Hh<8I4NwTIxiQ1vqJ_d{dhzHHOII{7gH-fp zq$RTQwNR43F_ICTan7xWv}VMu;XES^*?GK3wwI8)Y$Rs}ucAkCr#bNh19~fumQ{8k z))%Kx+V0K{Q%!HITQGV1R!5Z`KyU-(U-l>^gJRVV2({gHM@7fZ9Y)d>XO6|1mK-v_ z+T8fYR0Qhp?(cj7%$e^Sc^pd8I#xNxc*coJZ%&j~lFZ2w+t4cGX+w5~LL6l-W^?rX zhAV1EP#G}~KlbsDF!Hry_|}yn?5~-_a(~1y0iFAs6kJ{46Z$dr`L`y%@;gJNhMP}7T@x*Ka7 zCQh(kV0eLSiJ32*rq8z~%LU3gj@wVtt`@N{igM}EnT7N1yltgqxe;GXJY9E^Hu-=x ziPf0Jo=fd}?Eyu_x2S)h{5)lskOaD`;E$kUofz|^ixw8S4?QC3iu89Ji81;V zFT9K$_{2?9R68EdcCzLp+OLmVj-igK&x0yKzlm$2zW3Q7I%nlH-v8ppD&LoAk+=fz zTo*{%Lx{(F+^#NOI>}aEmhRGiin2v?BuDvhObo4$%e{naWy-q%)$fzmi7J!OyXrYW zY>Q?V~Fcid)Gx8UcL>TW5A;kLG6#H{UE6 z(y8N?S5G=#%fza(aen4m0QqzN+$#_FBgyal$q%eLH$lX+^(BNV6;?G(@n{S8P_mdJ z>WKH~KO=95F@~dDcgOb1*H$iMiIgJ{etUOinbDZQcpE!szxw&wnx-PXVm;XP&{yr( z(7wBcN|PdH$5_ooP2GpIwW0xVD&**6@cLq`f_J>&Z?Ti3MOGn<{$CKlxrCn5Die~E zT>*h2>h8R=8XW&58M=jn;oww(ebR=J<~dtx@mM<>Xj;{>kg&w;wRc2I#Hx}3FoNju z4MOYtYzy18#9U$iMP*9-LtYNV4rs)BPnX;Vny$B^pi;lkn8lIu*9rP7(BZ&pWZd5& zD$(#P1I-&Z{pZrzT_O3Kq}nP#M7?u(@Bp>#==&IL@fMm6i@L0rEG(c-D0Bn1zgXjG<<{2nXAhLQj8wHu#1s z5l)B~3EG+g^*fk0f0q{>8`Xy{5@WAt-a?pozwk|-c*K#T%&f3v%&h2hg25~#Q}VML z{ELd@=WPyxe{m_i#qJ?CmmRsMxZRvsKp=#)YFs*Y#-d0>RW(ZN%X(AJM_-D7pxw>9 zvbCX5GKoMv)6*%2_@v_>Y()xHy}tAF+qkXs4aG^XKY-i)_y%n)z-AW!r>-x&86jeSqxsFKYiOT$ureUI*s7F7k>l zUb*`D=AK;T3d~*(dh5USrtad@?|evxDCMkYw_Nj#AsS)ur@^3iZmKCzJXS0XrPyd? zBv}>f&87+erW(#XL1?@J>#E>{)V@7Xt4BG4_HiJ7{R!3BZ3g3RQDR%-5FZQ22uy&c zx8sJMvD?6U?u}I@xsw<&$fSiK1a~|WOc@kMFAeBzZK+C;xH+~rm(UzIA{Ohdp7s_Q z)tGt8n8;`nW(A*eIphzf+x!u7`ELvP@x*1KJ5_Pr2?xvLENrlnf(VrD6|0DVLvSGx zP9U_~g-}_6k)7Egmq~QF0Z6J=%;sz)cv1$54gWkpx_5rLEVIpXA(V#!BF?*4U*U+U z>rbwnru`P*1rxo<+6{#LA{8NEty@}gv zOH^X)?Kd0bj&s` zRt`F2LC?%LiFL2?{6o^z1bU9`XY38MDQiGyR1zf(1Y=Sw%YBJ@5RYX0%Z_-4`jBVj z0e_n@hGRymuxE=zja(pp5>VL_=~^L(eleceJGg@_OAqd^0zhoYK{2FR|M-< zLIS{T+QTbeNm=9xS=rtkvnBnZZC5^K6jnXBo`-RKL4bY7pyE_4LnqGwr#wm7xNl8)Piq=r^*3g_0`)LCc2v#>2|?NZ4OY zKRcQ4fd_qoTF|No@|dM3(JmbhCCHq`T-mo)&0*hZO5Lf?%QX>i^U#(?)qGJeyJ@{Q z2o!A!Y4w*NRTtZqcbtPx?BywT_@~SpKjxFrjnCcwl&gcT$`L8HO5)*%uxPfbuj}bO z@4lsE(581Ig!wIB?kRL<8qx5yzTC1D!p(-Cij`BLeH}X?Z_F`#EBc3m%bY+|^pDmc zr7LW|A^ykHUd*LQOAikZ;1ouX_KTiJ7U>$ei>Hb;gSM8iIVkuewtr-@crJxaGWH>TS;;rdpjKKYbS)x&FY} zjSfEX=uaGfnC3V~1BXfjlDi#J*BBGMdXnsuGtHQ^6pVqQmcV)z1p@g~l)3|-%QTRM%Tq*vWk)6> z(#9=x2+iHd*qU49m zNyUh6DkRMe_GXrT>dVxdQ-UZ=zjMO+6_(dKmoHixtYX7L4Dk39N_)J5@(q)2st74% z2e1XJ$C^o)!zF|)$skbHnKn>pRQPS*jBC`@k`cO7%#jR&MBFs_B7 zeVE%YtB!EmO`HfSl1#|qbpIT53DTx+v0gaSw?i%W2+^TX@S&w%eh~a+Bk>U84K2sH z7ah`2Swufsrs0)B`p3`YPp>{*RC*)j<#|SM;6+O_6H3EA$jc;6GbSuSQ@Jf0y&*0y z`FXM$15DM*Rc3$_zVJ-+v$%BjBl$7u$^0BN!uR9NoBSN>`8w1x8kD0_;@9|f0*Hdg zyw#I7eZa0UL7-uhC=~VrHkon|5Kz5z&$GoBg8C!192*j|pbdENvg>e=-EYEHb)t<@ z=mIJ7Lr&vR{yF?^7PId`X#+T#nh+(A-tYwPn1U`#4~IsTY^Unx7^s*XTti>q{3r@- z_-gyjE!>B`4x|jd5U`@BGn5S*ztLi{)0I+BEROM2Xxn(I|s;#M%|n zP}IS$5bfJOC(LZyDf-q7_MUsd3W=EY3nc2W{7qP3K|CI>e@0v z-`87aqp{@mrxHT&+CUQX-ooh!eW8!RWbR)m?6BiT3b#nu;{}a_%(#x0Ru~z=xJjH5 zI6S+}D_u@n){(Ria3vg&ly$~t$Inh~i+NtT>gz%*v`4FkOen>@RcVa*k-AXzw1*@1 zGe$J4dK<%MdSM$GnbviR0!LZqt1@E&rCES$#ZvOePOnp zw9pzOsg5;|S%A`p^Q^^2ipRDyeWo))GK?svO?zNaaLD#$W@KRGMeWQPV|iAUcMsuq zP!f2t*R}!JY;NGtmx|%#Ywe0Wo^7Du=Uq;6RllH!=l+~-nGb+ozgAX+Um)`-?@8nf9iw5RYP zEeNaU9VwG=EXn^ELgA^uLZrD=`uKMI81p=;J`M!Psyjtf6^{tl&uFA&Xl+MTCruU^ zdUtRj?eTtJQ+~wJVMi%4B4HzL^t=Cf6R&S;TxVSRs)W@woMWCuST?#jS28hqvJODH zFfavUY`lKx>qEd;$MVP8#N~muylhk;SFH3jEg4Wdz*8Qp3-3kbZCxu;K!KD5_qg2( z>W>Dq8Ls6>>H!Eg8G&t~dxwP#mZ+LU+KTjH{9`E-pbFcBg!99{s!ZS8CZIy{Z>)7; zXA3#d2pZ8d(WA)Bz&iUxBl`ecX=ER4Laf^$UaRpdTRr*H>eK418-hk zn6eX{c+JoV(xZil&TswkbW>5X2|1^4Kg^h#@IUMs`&7Rs@QpHw8H}@8&!_evY}-4H zutQV~@9ofJ%mzNqVS;mDs8Q@Lc2C_!@3n%bsmi&gM7SF*Sn?b{`#ifkhuZe>uClN1 zUSA;;WU?V|&2e-GQjb4bkD<3-WcuGn3Rof2{`ls$*YIn zlRx6=O+?aeDTHM!Z{SSERF4|c(kB~;s>y_uO=E}ofY1Im7EQpN@}Rx6wN>!B=z{Q4 z0w5swvjJRPGN*c$Itx4|JDr1GUq|M3yq!6MH~%60`um|um4+WQPNk?WRjL(Mf5&&1 zCi%|d8oz-iSigbCoR#O}f@+M~g{W9+nl&7SvMb~dfmIvL!FG@jvNmSIa@@46sd+!i; zQVGkR@BPDtJaP<(OC}`WD-Fcm)HV$y41ei`KC|0*SS1(X1e$W*Di4U|`DpVPi}B7q z=U`Z8`o8I>q_K%CtYBybg~v4%qmh~&h~pl7#sm;9ZH3K~P?>V@bD28gNMd7s&wH|~ zkMlJrzfw5)vi+5Sj=J-n&!ac#}05Bjrm} zQJ4=v`cm%qSEf28?K#v_7&p z1O*3yhGxip_e=yFf=7$bJqa$QPo9dGdig)Fz}8bIh5B3mNso@7nm$!N0q#_F6-0B! zvCBDr>%0PGSAun;XyvQymQT5z4-ogqY7Y$p0ydc(-uaJnV8&xw7R`(<<*vIQ34)2T zTtih_T`iqsieRWBddOQ7U>B*6wQHrBN{}xAPX?G{Y5yGApsAMxYYY99hJQe%(S#*p*JteenjGcTra4FBmo z;dac+i@`{3;)T7B#I(M;{v$M=DbYdfwTnjqig!!bM>`1{=?y$0$c}3)pjO;E@tG6* zm}@;Vyfmz$eIo$cUVl&}bRFq^foGvo>UUS^p5@dXd=+8KJRER6udFVuDY=%UVx?ZL zD|f3km;)y{{|`Cjn4|M)we6|Q#<#n&6mMm!-qQUug9ih{4RpA;n9$UY_k9R%hDwNp z%8{JoNdDTPr?~CV3jNi%62VH(3*fWgtVVVSez$dCFzeg=8s=Ii4Fj?1X-=P4s(XE3 zRPMgs#ywn!TDc)>({AfX3L$hKaU^z{*8HrDEJoVQmsKmoZl(e=XY@pQbaGzrvV-O* z!y`ycVZNZHE-HLM2rO3UzvFdSFl|Q?VX42bu}9bj-YazlXHUkM^C5+ROc9r_R*-39 z3l~SqJ47ivPvzg{_8KP0q&J(yY!2SeHoog35N}Xiey~@jrx2QTfh(ADxI}x*d)*O? zd@5n}wn@=BU18DlS_bcg3-vls(uISql3xhw>gACT8CGqp0b+!`qq9Ek&D`6$+d#AH?`pFxZyqb2AlKF@asg#kh4-lXUhtgaF}+nr%`@Ta zB5a}S3sDz#^NHD~e9ynKdEbFF7bOuBn(_;)sNOqrvArK1{QiVd{q+#wH{J{FWl+qI zaQL%aR8_CqI;Hqn;1r~HK-`nG0a3?Z^Vg3Qx1yuTN~M|sUH6c5pJqk~Bd=NhNV~+4 z>HKA~)r)w8ns)Pc;QF*McHzHV;CJY!vEZ8)t><&SUJ!UwsxDT5Qz;~_X}o9GBP8oh z;wYc6w}I5wDaIV<6rA?=8~<%e!zbF!CzXIzKuQ4E{gRXlw__?T#eGq@#;8 zDu>I%dR7eS6keYDHZ&m<8b*P>En!JwqZL5dgKlMBFO3QHsD0m4^ zy$fe!u#FtJKe`qO;uh)?+gIvfN-W|ko!ERLnM>)@Iiv0D>LJ(<$9q zS3J2e%wsYqIhAF@AkbyDO=X1OqoEOnKbXva!f3`N7sgPNZ3y)z#^^yFKdq2Dx*kzO z1d?i&3cLOsNlZdRpsvqQT)v7yImU7Q=@Ikj9^opIE0F0$)_?l$ujN?saNhL>Hj(4# ze{|(8=}oDVVzTtEfPJpTrns#RLs%u9J0o^+4Mke8-VHaS_IbE1nj=KVB(YXp;{VJ0ubL#vF%Ur|ztfZq``n?c!Qmo7o_b0efauA{L<>`3d zVr`H9V8~tY)}ZGxS*0RZlSj>5`RGI5!-=ndNca$RO9qh?7TCmqpKARW08ASdNY0kd zcrH6BCe6LxOZaA6x$5d|uH(DiuLNC!4P-RYFID^Iw(a(vq-A`36$i3x3a06z9FD@d znT371xLxv5@1?I-@zY&SeRd&kg$e~#1o&d$Ic@VeRL;@q z?o4UB8(sB2+Z-N4bHv>8qUD__rg0uJf+lkd)ynHuM>gA!J^cY(EhIO#@k-&_!zDC? z52r`*P89QU82xA6Z4e_~;o@#g(}Jvd4?-<@tGs7&9uozF z#yDMbE_CDUS7-N)DDleha;256a*!HKgmn-5EVN6&8; zC1c3$wr`aZzauGtN8EvD!eWfy`Cz}?92!}pM_i$roj8-Dsb1dj1PWe}ISvkak0zLJ zXuR*Hj0$hf%Ho<+3?V|-I_prckEs-)=U@Lozx`=z*%n_i?y0Y!uCmPKpA};B7_W3M zc1GISb{|Jfuvb9zF0vP7UN&1nZ`^3uqmUr>e;@OK`zz&xTf1q|U6qcMV{UL^g;c?$+-N&qZ*gj7m0zEp>R5{*dC{la!r5uKA>_%|8X7Z+=9xRb{O-E|Lq=h+B zy3Jenn6G7-%{fk1^&3Cp#W#MlMALUR8`friDCM8cIp`|o$dVMCnCZE8WU5<;e%T(K zcZ$TlzhI3A)@ZzOHqUmz<=~ljK9BZV>jihtxb2vsU;0L$J>;17Ho+=*u0Vu!wKmiT zFY&eiWorQU$lR!;u9^QUPfpfcX}-%@k0 z<(bdrrc0K0^~h(418d51MeHcGp2cm?<{ruvl7i=oZWF&Qn~1-}8U5uVCo7u1+)Cp8 z-0kpEhpBw5-gslh#m5-}KIHsM#j(-;g_!Lqob$+C-=c0yr3=NeYrfA5&K5@dI(Q9X z^F4LO-9B`h!WYa8Ig0M>eLCD3yXS(X)Igkv^F)3%X|tn5d}h9ymDhzU>$VQ|pzgOMhT*HD#yM zcg0fK+_(ApFCuG6`$!n8b6I>G?4NaT&dYqIX>MYTnXJy5rd)=!;C7Ws@+}cVEd$5d zB5#NBw3X%Cir4nr?JhJaxF?s0ijQp1*yWu6^j1@aWOM>caMg&UX^BrzN~OStYG#<-7rJ{@Rgs@|<6d}$pHWJF z{{FeZni^_!9oLYus;Bjp_RQI9Q$NDRL(B*I`W5+}oD@+cu)ZlZJ~QCAAvwBDCtKS4 zcwe_<9*&L<n@W7IJNhOo#QNZ}FBZFCus-9IpI^f-jQ%m#uA6t@G}qpH!!%%R(c??Y~tF+=NeUYNK|o zBK6ZoN?yl6uv3X4IlIwo}Fvd{3#Y7AjFy9V$@6%vRI(kzNb z>+SoX?P=qsT)8iLEapgA?lIo!2z+ zwtEkLk5HW+ey=&-es(JBp}3AEdn9~|%j)M6*O#q;{c_yQsT*`pz4Tdysi6<0vQwkH zrQ$PBj)zGQ%xctFx_Y0~NkKo~!SOD)s_)v7@fQ!XTVC+LrcDuEzLzTLo4bo zS_CDsZ1JCg)q9AF7hc6vQ4ROdB z;DK(4rEHjStHwTSGCe<)+xN#vtl&6l&bBkuJWTd+%%6`ZwT24%9}}}Taw=aoLB@^q za>q8&yE{XT!erYSS0{6-={pynJ-W4}4Yv>5eB4ZD5KQztAz!(vRC1}^mG6?eyuQI< z3B>BF%?;|LfW;f$U9fX25NF@uQ0zDRm?XR%Hyz_5xOcwlUYSU=xIO)}cEN?Jf$e-K z!KE(_JvVMJS-nQH=CWBT*N`-=6gNsyrN?)MYKCPirtY#3M)CjpubQe0d0X)n@$^^q zd#%ayjS4*I$wK~h=&|X@+p6odYWgzz#{2s7m!{|XvzBMh_bipdj9X4@c}<%e*W`{Z z_^x`}cPLDJwv?^^B>q|)zHnl-c88|4kk+2zJA18tlQ9F|NtGz&nF|r(1B2R=6BuXI zKiL2L{gbq?)}BE)vW-?aEaNXoW)1q!X0{8=Wt|8cx2q3BZ%6Sijb87a0lrzd__}y{ zwo8tmHzkL~-8f4%FH=Qpg$bud)#Cd-e+_)uikM11C*534X%VeG1A_doUD_v0-hb-2 zYCQF6msU-8dS7!)HGRk8*hl}W2jyvr4l}N?<79Q1qft{8lQU!AL#^o2|EdaWh2f8v z2@I7C^4s1I#&azRvm{$d@jpm-e2pPpbYSMf19AJ8Y~^%g@yYL2kJBg8tJfS46W5AP zuaJ9L4ta#ka(@!m{nZ4s^cE56APPmM?wro;ncwDN(qyrf-1S&*WWv=$YG5 zwwU|x*;i}^X8yQxB$4nkqOak=84b8EYMQ-BbITX+G)|Tx9;>cEMpJ7^B=T#P&TK)k z7C(q1wJzeC#`sa>jdhW=yQW2hN;ChV=EauGb3+YVpC=JRu{W!R6bHRYdNk!aQ{R z`-Qv_Mf-KP<2Bolqg=a?*QQ2{clIm(nh9=}M8->tCMR=TiuOC-Ek;*D99TRa8MT3h&8 z`{yXmUK$^R8*BcWs1JSC>}@l?cj<#1Ut8K&3ixwLz+`C+zUWt6dgIC~y7OhaU}Q+leT+^`j!Dbm^&cr-%c@YHc0( zn(me>#w~)V%wP8(-LMWRNMxaWIcNOW~<$P zU3zs{w=qB(5vUNY99iB8WDCmtcDW_LkNX9G4D!^ZdoL(5i_f(F2D|tE`#0g@S_XD< z3Yg(N1B%rIfyK-F`=)mh8){Ux7LUWNn@oxJdgEu8zU5@lTUq{N(kOWAhsVw%(v>*# z@sqz@_1=X_g#9zsD+#mYcU3`?bYbzq?`{n|9+&B?(1UppJS#OY)~~pB@!FHajnb9d zoBR5@tF`r!>n77Dz=n&U0+(iLV@jo5VjYaDbS-R>>^U9^9z;fZ@d?)d=Dbu?#R`C^ z+P7B>1n>?k{Yb7R@GoB9-^t$F5q&b9+Na0A_crui^D?)bO6xaWvv~Q*LH6JyuIWsLA$M58w+U?iv zFI)1P!K_JRPa&hz`3kNTbM?~QS94@30n*wqqv<7s8kwVfDD$O{jy_BrNI7sO3I=R; zN={*NFU|SwG1BS9d*4Z9As%IPEm=ca4|zZWY>Yej#Kr4=IGA%?Tvf+O!po> zcJT>*IvG|qjzl7=TH6Tz5}1nkvJ{D>%W72IbaJxiaAi#d|$rY=R~{$%|HrfWdIthqOn?pzMN)#kDmMqSzh#-P(a>-2Q?eSiMSrDwPffD7oP zHF^L27(Aop7UP7Q?zqaYao*ZXdYKQNTJ@SUuxz#NKI7Y$F1{9Z8kp~wp^o}Hh6eQiVzEOdFKvtz}Y z*v+WcrAMX}n$;9`MZ#li5{%vGA3Wl`j*g%F_1trpo%aP>cEEy!n-B+DU=vGXBbHXA z=?Xafp_W~6dE;qkbOZQ@_weVI9{w+U?Ja3H_*yMHPx8RPlm6xM~wIO zbAg4*_Tb4Jp3I>Wd5@8nR4|8OG7`iPi6#A)kpE0yws%fPA~xpIaII62vE(GoS4H&A z^?yMARZ~M7=eI49!e%UfHb;|egd0ZFJZi9u|1*43_dW&R#)xrhzv8dw7$WiIX%I*! zUEV?@3tTpH4-R9%=)0&!qs>b8tl81O;|f2he}eCdcE zqDfk^BpfOMb0hpX82hA#bS!+GqPA~``ElvH_@&9_xPB9xuUITaq;&IFgZD9a*?z>4 zQX7qU#nnsJj)P-QHsTLO*Jf%+zXUT{-`jV0ZjVig%yhx89lOn*zd$nkCG+sqO)%ev zFdu-=WCoX1E`8c-T|^F@>@)6Lo(UJXe^EhPUY1J{X)EsT?{`pM`aHqs5hH@ITs&6R z@UO7x(tC~kQpA|?qJD=Z?}kHg=SlEaY=O%ASXTzW>d&fsdvCP6U)zTf))6nsH z;dl6TwS|g<{hTIXH=|q%V9C=u<;LFCv<*QI-Cs_`R+-r_8wY#z*5ZB%t(rrp-3s3B z`-T_r_FkG!>u-oMYzgymXezF*aDgpwEhm9DH$R#i*-8!v7hlM+@#1`jA-+9g{9aCi z@{7n$P(+jwk%myuvy+cx~Cdx>g-UwQ;t)@+jbg!gi zNyheHLN@H%1ewdu6UU^#!D6Odb@P^LSHRgd-q8ywDOvjG>s8svFrUq_UKf@{_KRy_ zx7W9|)kln*=g5*pyoG+fKb$SL%CVO90EC#=z(=`kEeeFAm)C^v^H;eE9IXj<_9@RdU|}YqwWt&HwNG-!=1n&ptc2BMv05>Q=W|Jnh+W zpnJFOtW>BH^q*w%_v)m5F~wEKLH)B@S$LVyAbNZEj<>h7{ql3XH_PmuqwYCtQ_<&- zaensMFX3&mhLt5(*9rHpT^gBDTwEA^Y5F1Y@4%w=+TX*|Ze99&@}BnW_kH_dV_d+R ztL+uAVginCUX$BpUAC*7N9?zXXL1NI4a}PD&-4G!xj4W7RbRSoE?$SXUKk{}*~{Nl zoceSJcrNnimwRT-uFds~?~MBc^k|Oh^8NDj{#WPb)$KcHu5WKpe(Cb!_5ScEHxSf| zePgq7?tQah?_U#V?cNV;hWTgZz3YtQo1(JT_weW6)3g2FZYaNU>CX*F%BzO!O?b7X zc=O7+{_C^6KVRFnOc%#(L7&b!J#de+m2xBa)N)@oJ>22NVGyd?kZ%Vig} zMYdSRn%O*$yK!#$=eFnfulJriyf}UaczBB+)H%71C>|0--A*@5*DIS>QgFO)xyK~A wz5mXgo9y0uZu;TR&jkCo9Cb2mdKI;Vst05~R2`Tzg` literal 0 HcmV?d00001 diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..638c547 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,70 @@ +# Introduction to Strata + +!!! note + + Strata's devnet will be launching soon. + To build on devnet, + please apply using the devnet form on our [website](https://stratabtc.org/). + +Strata gives developers the freedom to program nearly +any locking conditions for BTC imaginable, +limited only by the Strata block size and gas limits. +This enables developers to create new kinds of applications for BTC +with features such as: + +- **New signature types**, "provide a valid `P-256` signature to authorize a transfer" + +- **Vaults**, "transfers must wait `N` days after being initiated to be effectuated, + and can be cancelled in the mean time" + +- **Transfer limits**, "only `X%` or less of the current balance + can be immediately with a single signature, + larger amounts can only be transferred with multiple signatures" + +- **Strong privacy**, "transaction details are end-to-end encrypted + and verified using a zero-knowledge proof" + +- **Economically secured zero-confirmation payments**, + "if a double-spend from this sender is reported, + the reporter gets to claim the sender's full wallet balance" + +- **Financial transactions**, + "if enough BTC is locked as collateral to maintain up + to `X%` loan-to-value ratio, + then up to N of this other asset can be borrowed" + +... and many more possibilities. + +Technically speaking, +**Strata is a work-in-progress EVM-compatible validity rollup on bitcoin**. +Let's break down what this means: + +- **EVM-compatible**: The Strata block producer runs a client that is based on + [Reth](https://github.com/paradigmxyz/reth), + an Ethereum execution client. + So far, no changes have been made that affect compatibility with the EVM spec. + If you can deploy a smart contract to Ethereum, + you can deploy it to Strata with no changes. + +- **Validity rollup**: Every Strata state transition is proven to + be valid using cryptographic validity proofs, + which clients can use for fast, low-cost verification. + +- **On bitcoin**: Strata uses bitcoin for consensus and data availability. + When a Strata block gets confirmed on bitcoin, + the only way to reorganize this block is to reorganize + the bitcoin block that the Strata block was confirmed in. + +You can find detailed technical information in the +[How Strata works](technical/specs.md) +section of this documentation. + +!!! note + + During the devnet phase, + Strata will be running on a private bitcoin signet, + and will use signet blocks to store state commitments + rather than the complete Strata state data, + making Strata function more like a commit chain than a rollup. + Support for full onchain data availability + and for running Strata on bitcoin mainnet are planned for future releases. diff --git a/docs/javascripts/mathjax.js b/docs/javascripts/mathjax.js new file mode 100644 index 0000000..fe408ae --- /dev/null +++ b/docs/javascripts/mathjax.js @@ -0,0 +1,20 @@ +window.MathJax = { + tex: { + tags: "ams", // adds label capability + inlineMath: [["\\(", "\\)"]], + displayMath: [["\\[", "\\]"]], + processEscapes: true, + processEnvironments: true, + }, + options: { + ignoreHtmlClass: ".*|", + processHtmlClass: "arithmatex", + }, +}; + +document$.subscribe(() => { + MathJax.startup.output.clearCache(); + MathJax.typesetClear(); + MathJax.texReset(); + MathJax.typesetPromise(); +}); diff --git a/docs/security.txt b/docs/security.txt new file mode 100644 index 0000000..fe7b243 --- /dev/null +++ b/docs/security.txt @@ -0,0 +1,3 @@ +Contact: https://github.com/alpenlabs/strata/issues +Expires: 2026-01-01T04:59:00.000Z +Preferred-Languages: en diff --git a/docs/stylesheets/extra.css b/docs/stylesheets/extra.css new file mode 100644 index 0000000..bf1c94b --- /dev/null +++ b/docs/stylesheets/extra.css @@ -0,0 +1,16 @@ +:root { + --md-accent-fg-color: #bc512f; + --md-accent-fg-color--light: #bc512f; + --md-accent-fg-color--dark: #bc512f; + --md-accent-bg-color: #bc512f; + --md-accent-bg-color--light: #bc512f; + --md-accent-bg-color--dark: #bc512f; +} + +.red { + color: red; +} + +.green { + color: green; +} diff --git a/docs/technical/architecture.md b/docs/technical/architecture.md new file mode 100644 index 0000000..1c2b0bf --- /dev/null +++ b/docs/technical/architecture.md @@ -0,0 +1,6 @@ +# System Architecture + +- System architecture diagram, showing the major components (each labelled with + a number) and how they interact +- Based on the component labels on the diagram, write a numbered list of + components and an explanation about what each one does diff --git a/docs/technical/bitcoin-bridge.md b/docs/technical/bitcoin-bridge.md new file mode 100644 index 0000000..1724fdc --- /dev/null +++ b/docs/technical/bitcoin-bridge.md @@ -0,0 +1,147 @@ +# Bitcoin Bridge + +The Bitcoin bridge is a two-way peg program between Bitcoin and Alpen Labs' rollup. +It is a federated bridge, where a group of operators +sign transactions to move funds into the rollup, +whereas the user can withdraw funds from the rollup with the guarantee +that at least one operator is honest. + +!!! info + + The current bridge design assumes an N-of-N cooperation amongst + the bridge operators. + Future designs will enhance the security model of the bridge operation. + +The deposit flow is composed of a Deposit Request Transaction (DRT) +which is fulfilled by the bridge federation with a Deposit Transaction (DT). +The user should provide an Execution Layer (EL) address to receive the funds +in the rollup. + +The withdrawal request is assigned to an operator that fulfills it +with the Bridge's funds with a Withdrawal Transaction (WT), +and then collects the signatures from the bridge federation. + +!!! note + + Deposits and withdrawals are allowed in a denomination of $D$ BTC where + $D = 10 \ \text{BTC}$ is a value predefined by the bridge federation. + +!!! info + + All the multisigs in the deposit and withdraw follows + the [MuSig2](https://github.com/bitcoin/bips/blob/master/bip-0327.mediawiki) + protocol, where signatures are aggregated into a single signature + that validates all $n$ participants' partial signatures. + +## Deposit + +The deposit process is initiated by the user, +who sends 10[^fees] BTC to a P2TR address, where: + +[^fees]: The user must pay the Bitcoin network fees for both the Deposit Request and Deposit Transactions. + +1. The key path spend is unspendable, following + [BIP 341](https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki#constructing-and-spending-taproot-outputs) + with a "NUMS"[^nums] point added to the random scalar + $r = \text{0x82758434e13488368e0781c4a94019d3d6722f854d26c15d2d157acd1f464723}$. + +[^nums]: + "Nothing Up My Sleeve" (NUMS) point, + i.e., a point with unknown discrete logarithm, chosen as $H = lift_x(G)$ + where $G$ is the secp256k1 generator point, + as per [BIP 341](https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki#constructing-and-spending-taproot-outputs). + An unspendable pubkey is a point on the curve whose discrete log + is not known with respect to the generator point $G$. + This can be verified by revealing the random scalar $r$ + used to generate the pubkey by shifting the NUMS point. + +1. The script path spend has two paths: + 1. "deposit path", an $n$-of-$n$ multisig path, + where $n$ is the number of operators in the bridge. + 1. "take back" path, + which allows the user to take back their funds if the bridge fails to + move funds from the Deposit Request Transaction (DRT) + into the bridge address within a two-week period, + i.e. it is time-locked and the user provides a signature to spend it. + +This transaction has some metadata attached to it, in the form of an `OP_RETURN` +output, that can be up to 80-bytes long (according to Bitcoin consensus rules); +and is composed of the following data: + +1. Magic bytes in the form `OP_PUSHBYTES_11 `. + These take $1 + 11 = 12$ bytes and are used to identify the bridge. +1. "Take back" TapLeaf hash as `OP_PUSHBYTES_32 `. + These take $1 + 32 = 33$ bytes and are used to validate the + Deposit Request Transaction (DRT), + while also necessary for the control block required + to spend the P2TR output via the $n$-of-$n$ Tapscript. +1. Execution layer (EL) Address as `OP_PUSHBYTES_20 `. + The Execution Layer (EL) address is the address in the rollup where + the user wants to receive the funds (sBTC) in the rollup. + It is a 20-byte Ethereum Virtual Machine (EVM) address. + This is $1 + 20 = 21$ bytes long. + +The bridge monitors the blockchain for incoming transactions, +which can be detected by the `OP_RETURN` output. +Once the bridge detects the Deposit Request Transaction (DRT), +it verifies the "take back" TapLeaf hash, the multisig pubkey path, +and the full Taproot commitment. + +If the Deposit Request Transaction (DRT) is valid, +the bridge operators fulfill the deposit with a Deposit Transaction (DT) +that transfers the BTC to the bridge address's UTXO set +and also mints the same amount of sBTC in the rollup to +the Execution Layer (EL) address provided by the user. + +Below in the figure is the deposit flow: + +```mermaid +sequenceDiagram + participant User + participant Bitcoin + participant Bridge + + User->>Bitcoin: DRT + Bitcoin->>Bitcoin: DRT + Bitcoin->>Bridge: DRT + Bridge->>Bridge: DRT + Bridge->>Bitcoin: DRT-DT + Bitcoin->>Bitcoin: DT + Bridge->>Bridge: Mint +``` + +## Withdrawal + +All withdrawals take place through the bridge's UTXO set. + +The user requests a withdrawal in the rollup and an operator is assigned to +fulfill the request in the Bitcoin network: + +1. The user requests a withdrawal from the rollup making sure to burn the + same amount of `sBTC`. +1. The assigned operator creates and signs a Withdrawal Transaction + (WT) where they spend 10 BTC from the Bridge Address' UTXO set, + while subtracting the operator's fee and the transaction fee; + and requests the other $N−1$ operators to sign + the Withdrawal Transaction. +1. Once all the signatures have been aggregated, the transaction is submitted to + the Bitcoin network. +1. Once the transaction is confirmed, + the withdrawal request is fulfilled. + +The withdrawal flow is shown below: + +```mermaid +sequenceDiagram + participant User + participant Operator + participant Bridge + participant Bitcoin + + User->>User: Burn + User->>Bridge: Withdrawal + Bridge->>Operator: Duty + Operator->>Bitcoin: WT + Operator->>Operator: WT + Bitcoin->>Bitcoin: WT +``` diff --git a/docs/technical/comparing-ethereum.md b/docs/technical/comparing-ethereum.md new file mode 100644 index 0000000..bb36eb4 --- /dev/null +++ b/docs/technical/comparing-ethereum.md @@ -0,0 +1,32 @@ +# Comparing Strata and Ethereum + +## EVM compatibility + +Strata is an EVM-compatible blockchain. +The execution client used by the Strata block producer is based on reth +and is fully compatible with the EVM spec. +During the devnet phase, Strata can be considered a Type 1 zkEVM. + +!!! note + + In a future release, + Strata developers plan to introduce changes + that will result in a Type 2.5 zkEVM rating. + Watch the Strata [issues repo](https://github.com/alpenlabs/strata/issues) + to stay up to date with proposed consensus changes. + +## Blockchain functionality + +Comparing differences in how Strata and Ethereum functionally operate: + + + +| | Strata | Ethereum | +| ---------------- | ------------------------------------------------------------------------------------------------------ | -------------- | +| Consensus: | Proof of Work | Proof of Stake | +| Gas asset: | BTC | ETH | +| Block gas limit: | 8,000,000 | 30,000,000 | +| Block time: | ~5s | ~12s | +| Finality: | Probabilistic, blocks are confirmed in
batches on a private bitcoin signet
about once per hour | ~15m | + + diff --git a/docs/technical/node-types.md b/docs/technical/node-types.md new file mode 100644 index 0000000..7ce4c38 --- /dev/null +++ b/docs/technical/node-types.md @@ -0,0 +1,91 @@ +# Node Types + +Strata consists of different types of nodes, +each serving specific roles within the network. + +- **Full node**: responsible for maintaining a local copy of + and validating the entire Strata state +- **Sequencer node**: full node that has the additional responsibility + of ordering transactions and producing new Strata blocks. +- **Bridge node**: full node that has the additional responsibility + of facilitating the transfer of assets between bitcoin and Strata. + +## Node comparison table + + + +| Network | Feature | Full node | Sequencer node | Bridge node | +| :--------------------- | :------------------------------------------------- | -------------------------- | -------------------------- | -------------------------- | +| **Strata** | **storage** of blocks and state | :material-check:{ .green } | :material-close:{ .red } | :material-close:{ .red } | +| **Strata** | **validation** of incoming blocks and transactions | :material-check:{ .green } | :material-close:{ .red } | :material-close:{ .red } | +| **Strata** | **RPC**-endpoint | :material-check:{ .green } | :material-close:{ .red } | :material-close:{ .red } | +| **Strata** | **relay** of transactions and blocks | :material-check:{ .green } | :material-check:{ .green } | :material-close:{ .red } | +| **Strata** | **sequence** of incoming transactions | :material-close:{ .red } | :material-check:{ .green } | :material-close:{ .red } | +| **Strata** | **construction** of new blocks | :material-close:{ .red } | :material-check:{ .green } | :material-close:{ .red } | +| **Strata** | **broadcast** of new blocks | :material-close:{ .red } | :material-check:{ .green } | :material-close:{ .red } | +| **Strata** | **execution** of incoming transactions | :material-check:{ .green } | :material-check:{ .green } | :material-close:{ .red } | +| **Bitcoin** | **writing** of batch data | :material-close:{ .red } | :material-check:{ .green } | :material-close:{ .red } | +| **Bitcoin** | **monitoring** of deposit transactions | :material-close:{ .red } | :material-close:{ .red } | :material-check:{ .green } | +| **Bitcoin** | **processing** of withdrawal requests | :material-close:{ .red } | :material-close:{ .red } | :material-check:{ .green } | +| **Bitcoin**/**Strata** | **Ensuring** secure BTC transfers | :material-close:{ .red } | :material-close:{ .red } | :material-check:{ .green } | + + + +## Full node + +A Strata full node is responsible for maintaining +and validating the entire state of the Strata chain. + +**Key features**: + +- Stores the complete history of Strata blocks and state. +- Validates incoming Strata blocks and transactions. +- Serves RPC requests for chain data. +- Participates in the network by relaying transactions and blocks. + +## Sequencer node + +A sequencer node is a specialized full node that has +the additional responsibility of ordering transactions +and producing new Strata blocks. + +**Key features**: + +- All features of a _full node_. +- Receives and orders incoming transactions. +- Executes transactions to produce new Strata blocks. +- Interacts with the bitcoin node write batch metadata to bitcoin. +- Serves Strata blocks to other full nodes via RPC. + +## Bridge node + +A bridge node facilitates the transfer of assets between +bitcoin and Strata. + +**Key features**: + +- Monitors bitcoin for deposit transactions. +- Processes Strata withdrawal requests. +- Interacts with both bitcoin and Strata to ensure secure BTC transfers. + +## Key differences between node types + + + +1. **Block production**: + - _Only_ sequencer nodes produce and relay new Strata blocks. + - Full nodes and bridge nodes validate blocks + but do _not_ produce or relay them. +2. **Network interactions**: + - Sequencer nodes have the most complex network interactions, + dealing with both Strata transaction intake and bitcoin checkpoints. + - Bridge nodes interact extensively with both bitcoin + and Strata for BTC transfers. + - Full nodes primarily interact within the Strata network. +3. **Resource requirements**: + - Sequencer nodes typically require the most resources + due to their block production responsibilities. + - Full nodes require significant storage for the entire state history. + - Bridge nodes require reliable connections to both bitcoin and Strata. + + diff --git a/docs/technical/specs.md b/docs/technical/specs.md new file mode 100644 index 0000000..e78725a --- /dev/null +++ b/docs/technical/specs.md @@ -0,0 +1,24 @@ +# Specifications + +Some introductory text here about the specifications. + +## Parameters + +Another introductory text here about parameters. + +### Block Time + +Something about block time. + +### Gas Limit + +Something about gas limit. + +## Precompiles + +All precompiles supported, including rollup-specific precompiles. + +## Addresses + +Any "system" addresses related to rollup operations or that would otherwise be +helpful for users to know about diff --git a/docs/technical/transaction-lifecycle.md b/docs/technical/transaction-lifecycle.md new file mode 100644 index 0000000..877cf49 --- /dev/null +++ b/docs/technical/transaction-lifecycle.md @@ -0,0 +1,131 @@ +# Transaction lifecycle + +This document describes the journey of Strata transactions +from initiation to finalization. + +## Transaction initiation and propagation + +For devnet, Strata supports both Externally Owned Account (EOA) transactions +and account abstraction transactions (referred to as UserOperations) +as defined in ERC-4337. +EOA transactions can be initiated by users through any EVM-compatible wallet +that is connected to a Strata full node. +For account abstraction, we provide a bundler that accepts UserOperations +and relays them to a full node we have deployed. +On devnet, each full node is directly connected to a full node run by Alpen Labs, +which in turn is connected to the sequencer (also run by Alpen Labs). +This setup helps reduce propagation time, +given the relatively small number of full nodes expected. +Ultimately, all user transactions reach the sequencer through +this full node. + +## Block building + +The sequencer orders the EVM transactions received based on +the default algorithm used by Reth, +which is to prioritize the transactions with higher effective gas price, +respecting the account nonce ordering (ascending). +A block is constructed every 5 seconds, and it includes: + +- A header with metadata (timestamp, block number, etc.) +- An L1 segment (information from the bitcoin chain) +- An execution segment (includes the actual EVM transactions and related info) + +The block is executed against the current Strata chain state, +during which the pending withdrawals and deposits are processed +and the chain state is updated. +The chain state primarily includes: + +- EVM state +- Strata’s view of the bitcoin state + (eg. current "safe" bitcoin block, blocks that may reorg, etc.) +- List of current bridge operators +- Pending deposit and withdrawal info +- Auxiliary info about the Strata chain e.g. latest Strata block, + current slot and checkpoint period, etc. More about checkpointing below. + +After the block is executed and verified, the block is added to the blockchain +and is relayed to the prover and full nodes, who are all polling for new blocks. + +## Batch building + +A batch represents a collection of blocks associated with a single checkpoint, +which includes a proof of state transition and state commitments, +written to bitcoin in a bitcoin transaction. +The process of building a new batch checkpoint begins when the checkpoint for +the previous batch is detected on bitcoin. +The first block of the new batch follows immediately after +the final block of the previous batch - this applies to both the Strata +and bitcoin batches. +The final block in the Strata batch is chosen to be +the latest block in the Strata chain, +while the final block in the bitcoin batch is the most recent "safe" block on +the bitcoin chain as seen by the sequencer. +A safe block is one that has been sufficiently buried in the bitcoin chain +to be resistant to reorganization. + +Once the sequencer decides on the ranges for the new batch checkpoint, +the prover begins constructing +an aggregated proof of state transition for that batch. +Once the proof is ready, it is prepared to be written to bitcoin, +along with the checkpoint information. + +## Proving + +The prover starts proving the state transition for a Strata block as soon as +it is constructed by the sequencer, +retrieving all the inputs necessary for proof generation from the sequencer. +Since block construction by the sequencer is faster than +the proof generation for a block, +proof generation of multiple blocks happen in parallel. +When it is time to construct a proof for a new batch, +the prover retrieves previous proof information, +the new batch checkpoint information, and the relevant bitcoin chain, +and the prover starts two parallel processes: + +1. constructing a recursive proof in proper order from + the individual state transition proofs of + each Strata block generated for this batch, and +2. constructing a proof by reading the bitcoin chain for the given range, + verifying its validity, + and verifying that all relevant transactions in the bitcoin chain, + such as deposits and the previous batch proof, are included in the Strata chain. + Both of these proofs are then recursively combined to create the batch proof. + +The batch proof proves the following: + +- The input bitcoin chain is valid and corresponds to the range of this batch. +- Every transaction in the bitcoin chain was scanned and all + the relevant transactions + (such as the previous checkpoint transaction and deposit transactions) + are properly extracted. +- The previous batch proof in the extracted checkpoint is valid. +- All deposits initiated on bitcoin are included in the Strata batch. +- The current batch starts immediately after the last block of the previous batch. +- Execution of the Strata blocks in this batch produces a valid state transition. + +The batch proof is recursive, +so by verifying the latest batch proof a client can verify that +the Strata state transitions from genesis to the latest block included included +in the batch are valid. +This batch proof is passed to the sequencer for writing to bitcoin. + +## Batch checkpoint + +Once the batch proof is ready, +the proof is included in the checkpoint which is signed by the sequencer, +compressed, and serialized into bytes. +The sequencer then creates bitcoin transactions with +an [envelope](https://docs.ordinals.com/inscriptions.html) that contains +the signed checkpoint data along with Strata chain information such as +the blockchain name and version. + +The transactions are then broadcast to the bitcoin network +and eventually confirmed in a bitcoin block. + +### Batch finalization + +Once the bitcoin block containing the batch checkpoint +is sufficiently buried in the blockchain, +full nodes consider the Strata batch committed to in the checkpoint, +and all transactions in that batch, to be finalized. diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 0000000..9a252a4 --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,47 @@ +import markdownlint from "eslint-plugin-markdownlint"; +import eslintConfigPrettier from "eslint-config-prettier"; +import parser from "eslint-plugin-markdownlint/parser.js"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; +import js from "@eslint/js"; +import { FlatCompat } from "@eslint/eslintrc"; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); +const compat = new FlatCompat({ + baseDirectory: __dirname, + recommendedConfig: js.configs.recommended, + allConfig: js.configs.all, +}); + +export default [ + { + plugins: { + markdownlint, + eslintConfigPrettier, + }, + }, + ...compat.extends("plugin:markdownlint/recommended").map((config) => ({ + ...config, + files: ["**/*.md"], + })), + { + files: ["**/*.md"], + + languageOptions: { + parser, + }, + + rules: { + "markdownlint/md033": "off", // inline HTML + "markdownlint/md046": "off", // code block style + "markdownlint/md024": [ + "error", + { + // duplicate headings + siblings_only: true, + }, + ], + }, + }, +]; diff --git a/justfile b/justfile new file mode 100644 index 0000000..32247c9 --- /dev/null +++ b/justfile @@ -0,0 +1,73 @@ +alias s := serve + +# List everything +default: + @just --list + +# Serve the site localling +serve: + @echo "Serving the site locally" + @echo "If this fails you might need either to install mkdocs-material or run 'just serve-docker' instead" + mkdocs serve + +# Serve the site locally using Docker +serve-docker: + @echo "Serving the site locally using Docker" + docker run --rm -u "$(id -u):$(id -g)" -v "$PWD":/docs -p 8000:8000 squidfunk/mkdocs-material + +# Make everything ready for a PR +pr: + @just format-check + @just lint-check + @just spell-check + @echo "PR checks complete!" + +# Check for spelling errors +spell-check: + @echo "Checking for spelling errors" + pnpm spell:check + +# Add a word to the dictionary +spell-add *WORDS: + @echo "Adding {{ WORDS }} to the dictionary" + for word in {{ WORDS }}; do echo $word >> project-words.txt; done + +# Sort the dictionary +spell-sort: + @echo "Sorting the dictionary" + sort -o project-words.txt project-words.txt + +# Check for formatting errors +format-check: + @echo "Checking for formatting errors" + pnpm format:check + +# Fix formatting errors +format-fix: + @echo "Fixing formatting errors" + pnpm format:fix + +# Check for lint errors +lint-check: + @echo "Checking for lint errors" + pnpm lint:check + +# Fix lint errors +lint-fix: + @echo "Fixing lint errors" + pnpm lint:fix + +# Install pnpm +pnpm-install: + @echo "Installing pnpm" + wget -qO- https://get.pnpm.io/install.sh | sh + +# Install NPM dependencies +npm-install: + @echo "Installing NPM dependencies" + pnpm install + +# Clean the NPM cache +npm-clean: + @echo "Cleaning NPM cache" + rm -rf node_modules/ .pnpm-store/ diff --git a/mkdocs.yml b/mkdocs.yml new file mode 100644 index 0000000..48b0a34 --- /dev/null +++ b/mkdocs.yml @@ -0,0 +1,87 @@ +# yaml-language-server: $schema=https://squidfunk.github.io/mkdocs-material/schema.json +site_name: Documentation +site_url: https://docs.stratabtc.org +repo_url: https://github.com/alpenlabs/strata +repo_name: "" +plugins: + - search +theme: + name: material + logo: assets/logo.png + icon: + repo: fontawesome/brands/github + favicon: assets/favicon.png + palette: + - scheme: default + primary: white + accent: custom + toggle: + icon: material/brightness-7 + name: Switch to dark mode + - scheme: slate + primary: black + accent: custom + toggle: + icon: material/brightness-4 + name: Switch to light mode + font: + text: Inter + code: Roboto Mono + features: + - navigation.instant + - navigation.footer + - search.suggest + - search.highlight + - toc.follow + - toc.integrate + - content.code.copy + - content.code.annotate +extra: + homepage: https://stratabtc.org + generator: false +markdown_extensions: + - tables + - toc: + permalink: true + - attr_list + - md_in_html + - footnotes + - admonition + - pymdownx.details + - pymdownx.highlight: + anchor_linenums: true + line_spans: __span + linenums: true + pygments_lang_class: true + - pymdownx.inlinehilite + - pymdownx.snippets + - pymdownx.arithmatex: + generic: true + - pymdownx.emoji: + emoji_index: !!python/name:material.extensions.emoji.twemoji + emoji_generator: !!python/name:material.extensions.emoji.to_svg + - pymdownx.superfences: + custom_fences: + - name: mermaid + class: mermaid + format: !!python/name:pymdownx.superfences.fence_code_format +extra_javascript: + - javascripts/mathjax.js + - https://unpkg.com/mathjax@3/es5/tex-mml-chtml.js +extra_css: + - stylesheets/extra.css + +nav: + - Introduction to Strata: index.md + - How Strata Works: + - Specifications: technical/specs.md + - System Architecture: technical/architecture.md + - Transaction Lifecycle: technical/transaction-lifecycle.md + - Bitcoin Bridge: technical/bitcoin-bridge.md + - Node Types: technical/node-types.md + - Comparing Strata and Ethereum: technical/comparing-ethereum.md + - Community: + - Website: https://stratabtc.org + - GitHub: https://github.com/alpenlabs/strata + - Telegram: https://t.me/Strata_Community + - Twitter: https://twitter.com/Strata_BTC diff --git a/package.json b/package.json new file mode 100644 index 0000000..26da152 --- /dev/null +++ b/package.json @@ -0,0 +1,26 @@ +{ + "name": "alpen-docs", + "version": "0.1.0", + "description": "Public documentation related to Alpen Labs products.", + "scripts": { + "lint:check": "eslint .", + "lint:fix": "eslint --fix .", + "spell:check": "cspell lint \"**/*.md\"", + "format:check": "prettier --config .prettierrc.yaml --check .", + "format:fix": "prettier --config .prettierrc.yaml --write .", + "sort:project-words": "sort -o project-words.txt project-words.txt" + }, + "keywords": [], + "type": "module", + "author": "", + "license": "MIT", + "devDependencies": { + "@eslint/eslintrc": "^3.1.0", + "@eslint/js": "^9.5.0", + "cspell": "^8.9.0", + "eslint": "^9.5.0", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-markdownlint": "^0.6.0", + "prettier": "^3.3.2" + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..3df8d57 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,1546 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + devDependencies: + '@eslint/eslintrc': + specifier: ^3.1.0 + version: 3.1.0 + '@eslint/js': + specifier: ^9.5.0 + version: 9.5.0 + cspell: + specifier: ^8.9.0 + version: 8.9.0 + eslint: + specifier: ^9.5.0 + version: 9.5.0 + eslint-config-prettier: + specifier: ^9.1.0 + version: 9.1.0(eslint@9.5.0) + eslint-plugin-markdownlint: + specifier: ^0.6.0 + version: 0.6.0(eslint@9.5.0) + prettier: + specifier: ^3.3.2 + version: 3.3.2 + +packages: + + '@cspell/cspell-bundled-dicts@8.9.0': + resolution: {integrity: sha512-Dxfuva7zlcI2X/PulDI7bfJBB1De4OuulR2prVpDuGLk3zAiFO7t4d2bmdWxfowhtm1agSqY03uZOTk8fTppuQ==} + engines: {node: '>=18'} + + '@cspell/cspell-json-reporter@8.9.0': + resolution: {integrity: sha512-+m2HoYTqdI76Zt27CyCpFCAxEUlTMnJnC76MpuQEd21C72qXWmaYdcVzJ7GnVXtTY6cofefUy/X3zgkUBW/bqg==} + engines: {node: '>=18'} + + '@cspell/cspell-pipe@8.9.0': + resolution: {integrity: sha512-N3Nv9F/1LyUabd1lda+N7tU+UpY7lp8mZvG7ZTxhoB8vfw/Yf3f8NlQ5awSYear2Q+N0RoGyyLaaqUY6nUQvOQ==} + engines: {node: '>=18'} + + '@cspell/cspell-resolver@8.9.0': + resolution: {integrity: sha512-52FCYcrZZhdAKkGoHss000nUk2mHkujxHJOfh+KMh2p15igmPW0AR7/VFKSS7zVkkLfAhQfWxoqQLkoE+yvccA==} + engines: {node: '>=18'} + + '@cspell/cspell-service-bus@8.9.0': + resolution: {integrity: sha512-R8MlY3dp4my/VZp2xhvkUcXbLsTZUSNuxsOFzpPYLQhtrei0ReEcaDTg2JEU1wfHnREGG8GYlWh9BEryx8AZYA==} + engines: {node: '>=18'} + + '@cspell/cspell-types@8.9.0': + resolution: {integrity: sha512-YeL14G+tIh92WvO5K9+WBCjckRQAApeSNkIavx+7+IF+MUoGPvVbTA881q15zwoPRPtOJQ8wEbI6zJH5ykKFfw==} + engines: {node: '>=18'} + + '@cspell/dict-ada@4.0.2': + resolution: {integrity: sha512-0kENOWQeHjUlfyId/aCM/mKXtkEgV0Zu2RhUXCBr4hHo9F9vph+Uu8Ww2b0i5a4ZixoIkudGA+eJvyxrG1jUpA==} + + '@cspell/dict-aws@4.0.2': + resolution: {integrity: sha512-aNGHWSV7dRLTIn8WJemzLoMF62qOaiUQlgnsCwH5fRCD/00gsWCwg106pnbkmK4AyabyxzneOV4dfecDJWkSxw==} + + '@cspell/dict-bash@4.1.3': + resolution: {integrity: sha512-tOdI3QVJDbQSwPjUkOiQFhYcu2eedmX/PtEpVWg0aFps/r6AyjUQINtTgpqMYnYuq8O1QUIQqnpx21aovcgZCw==} + + '@cspell/dict-companies@3.1.2': + resolution: {integrity: sha512-OwR5i1xbYuJX7FtHQySmTy3iJtPV1rZQ3jFCxFGwrA1xRQ4rtRcDQ+sTXBCIAoJHkXa84f9J3zsngOKmMGyS/w==} + + '@cspell/dict-cpp@5.1.10': + resolution: {integrity: sha512-BmIF0sAz2BgGEOwzYIeEm9ALneDjd1tcTbFbo+A1Hcq3zOKP8yViSgxS9CEN30KOZIyph6Tldp531UPEpoEl0Q==} + + '@cspell/dict-cryptocurrencies@5.0.0': + resolution: {integrity: sha512-Z4ARIw5+bvmShL+4ZrhDzGhnc9znaAGHOEMaB/GURdS/jdoreEDY34wdN0NtdLHDO5KO7GduZnZyqGdRoiSmYA==} + + '@cspell/dict-csharp@4.0.2': + resolution: {integrity: sha512-1JMofhLK+4p4KairF75D3A924m5ERMgd1GvzhwK2geuYgd2ZKuGW72gvXpIV7aGf52E3Uu1kDXxxGAiZ5uVG7g==} + + '@cspell/dict-css@4.0.12': + resolution: {integrity: sha512-vGBgPM92MkHQF5/2jsWcnaahOZ+C6OE/fPvd5ScBP72oFY9tn5GLuomcyO0z8vWCr2e0nUSX1OGimPtcQAlvSw==} + + '@cspell/dict-dart@2.0.3': + resolution: {integrity: sha512-cLkwo1KT5CJY5N5RJVHks2genFkNCl/WLfj+0fFjqNR+tk3tBI1LY7ldr9piCtSFSm4x9pO1x6IV3kRUY1lLiw==} + + '@cspell/dict-data-science@2.0.1': + resolution: {integrity: sha512-xeutkzK0eBe+LFXOFU2kJeAYO6IuFUc1g7iRLr7HeCmlC4rsdGclwGHh61KmttL3+YHQytYStxaRBdGAXWC8Lw==} + + '@cspell/dict-django@4.1.0': + resolution: {integrity: sha512-bKJ4gPyrf+1c78Z0Oc4trEB9MuhcB+Yg+uTTWsvhY6O2ncFYbB/LbEZfqhfmmuK/XJJixXfI1laF2zicyf+l0w==} + + '@cspell/dict-docker@1.1.7': + resolution: {integrity: sha512-XlXHAr822euV36GGsl2J1CkBIVg3fZ6879ZOg5dxTIssuhUOCiV2BuzKZmt6aIFmcdPmR14+9i9Xq+3zuxeX0A==} + + '@cspell/dict-dotnet@5.0.2': + resolution: {integrity: sha512-UD/pO2A2zia/YZJ8Kck/F6YyDSpCMq0YvItpd4YbtDVzPREfTZ48FjZsbYi4Jhzwfvc6o8R56JusAE58P+4sNQ==} + + '@cspell/dict-elixir@4.0.3': + resolution: {integrity: sha512-g+uKLWvOp9IEZvrIvBPTr/oaO6619uH/wyqypqvwpmnmpjcfi8+/hqZH8YNKt15oviK8k4CkINIqNhyndG9d9Q==} + + '@cspell/dict-en-common-misspellings@2.0.2': + resolution: {integrity: sha512-LA8BO0RaoJD+ExHzK5mz+t9RQ0HaBPDxgR4JTfG8YKJP5keO+pFMH9ZMZphKPjW46QYUZb6Ta1HIRikBEOZfYw==} + + '@cspell/dict-en-gb@1.1.33': + resolution: {integrity: sha512-tKSSUf9BJEV+GJQAYGw5e+ouhEe2ZXE620S7BLKe3ZmpnjlNG9JqlnaBhkIMxKnNFkLY2BP/EARzw31AZnOv4g==} + + '@cspell/dict-en_us@4.3.22': + resolution: {integrity: sha512-UegkIQhKkTLGarpYNV5ybW2JHzuxhDMOF9q9TW37iG8YoHp5jeVW3C0p3cH9nHWMwEjPinJFfxBd1LPRxGv5dQ==} + + '@cspell/dict-filetypes@3.0.4': + resolution: {integrity: sha512-IBi8eIVdykoGgIv5wQhOURi5lmCNJq0we6DvqKoPQJHthXbgsuO1qrHSiUVydMiQl/XvcnUWTMeAlVUlUClnVg==} + + '@cspell/dict-fonts@4.0.0': + resolution: {integrity: sha512-t9V4GeN/m517UZn63kZPUYP3OQg5f0OBLSd3Md5CU3eH1IFogSvTzHHnz4Wqqbv8NNRiBZ3HfdY/pqREZ6br3Q==} + + '@cspell/dict-fsharp@1.0.1': + resolution: {integrity: sha512-23xyPcD+j+NnqOjRHgW3IU7Li912SX9wmeefcY0QxukbAxJ/vAN4rBpjSwwYZeQPAn3fxdfdNZs03fg+UM+4yQ==} + + '@cspell/dict-fullstack@3.1.8': + resolution: {integrity: sha512-YRlZupL7uqMCtEBK0bDP9BrcPnjDhz7m4GBqCc1EYqfXauHbLmDT8ELha7T/E7wsFKniHSjzwDZzhNXo2lusRQ==} + + '@cspell/dict-gaming-terms@1.0.5': + resolution: {integrity: sha512-C3riccZDD3d9caJQQs1+MPfrUrQ+0KHdlj9iUR1QD92FgTOF6UxoBpvHUUZ9YSezslcmpFQK4xQQ5FUGS7uWfw==} + + '@cspell/dict-git@3.0.0': + resolution: {integrity: sha512-simGS/lIiXbEaqJu9E2VPoYW1OTC2xrwPPXNXFMa2uo/50av56qOuaxDrZ5eH1LidFXwoc8HROCHYeKoNrDLSw==} + + '@cspell/dict-golang@6.0.9': + resolution: {integrity: sha512-etDt2WQauyEQDA+qPS5QtkYTb2I9l5IfQftAllVoB1aOrT6bxxpHvMEpJ0Hsn/vezxrCqa/BmtUbRxllIxIuSg==} + + '@cspell/dict-google@1.0.1': + resolution: {integrity: sha512-dQr4M3n95uOhtloNSgB9tYYGXGGEGEykkFyRtfcp5pFuEecYUa0BSgtlGKx9RXVtJtKgR+yFT/a5uQSlt8WjqQ==} + + '@cspell/dict-haskell@4.0.1': + resolution: {integrity: sha512-uRrl65mGrOmwT7NxspB4xKXFUenNC7IikmpRZW8Uzqbqcu7ZRCUfstuVH7T1rmjRgRkjcIjE4PC11luDou4wEQ==} + + '@cspell/dict-html-symbol-entities@4.0.0': + resolution: {integrity: sha512-HGRu+48ErJjoweR5IbcixxETRewrBb0uxQBd6xFGcxbEYCX8CnQFTAmKI5xNaIt2PKaZiJH3ijodGSqbKdsxhw==} + + '@cspell/dict-html@4.0.5': + resolution: {integrity: sha512-p0brEnRybzSSWi8sGbuVEf7jSTDmXPx7XhQUb5bgG6b54uj+Z0Qf0V2n8b/LWwIPJNd1GygaO9l8k3HTCy1h4w==} + + '@cspell/dict-java@5.0.7': + resolution: {integrity: sha512-ejQ9iJXYIq7R09BScU2y5OUGrSqwcD+J5mHFOKbduuQ5s/Eh/duz45KOzykeMLI6KHPVxhBKpUPBWIsfewECpQ==} + + '@cspell/dict-julia@1.0.1': + resolution: {integrity: sha512-4JsCLCRhhLMLiaHpmR7zHFjj1qOauzDI5ZzCNQS31TUMfsOo26jAKDfo0jljFAKgw5M2fEG7sKr8IlPpQAYrmQ==} + + '@cspell/dict-k8s@1.0.5': + resolution: {integrity: sha512-Cj+/ZV4S+MKlwfocSJZqe/2UAd/sY8YtlZjbK25VN1nCnrsKrBjfkX29vclwSj1U9aJg4Z9jw/uMjoaKu9ZrpQ==} + + '@cspell/dict-latex@4.0.0': + resolution: {integrity: sha512-LPY4y6D5oI7D3d+5JMJHK/wxYTQa2lJMSNxps2JtuF8hbAnBQb3igoWEjEbIbRRH1XBM0X8dQqemnjQNCiAtxQ==} + + '@cspell/dict-lorem-ipsum@4.0.0': + resolution: {integrity: sha512-1l3yjfNvMzZPibW8A7mQU4kTozwVZVw0AvFEdy+NcqtbxH+TvbSkNMqROOFWrkD2PjnKG0+Ea0tHI2Pi6Gchnw==} + + '@cspell/dict-lua@4.0.3': + resolution: {integrity: sha512-lDHKjsrrbqPaea13+G9s0rtXjMO06gPXPYRjRYawbNmo4E/e3XFfVzeci3OQDQNDmf2cPOwt9Ef5lu2lDmwfJg==} + + '@cspell/dict-makefile@1.0.0': + resolution: {integrity: sha512-3W9tHPcSbJa6s0bcqWo6VisEDTSN5zOtDbnPabF7rbyjRpNo0uHXHRJQF8gAbFzoTzBBhgkTmrfSiuyQm7vBUQ==} + + '@cspell/dict-monkeyc@1.0.6': + resolution: {integrity: sha512-oO8ZDu/FtZ55aq9Mb67HtaCnsLn59xvhO/t2mLLTHAp667hJFxpp7bCtr2zOrR1NELzFXmKln/2lw/PvxMSvrA==} + + '@cspell/dict-node@5.0.1': + resolution: {integrity: sha512-lax/jGz9h3Dv83v8LHa5G0bf6wm8YVRMzbjJPG/9rp7cAGPtdrga+XANFq+B7bY5+jiSA3zvj10LUFCFjnnCCg==} + + '@cspell/dict-npm@5.0.16': + resolution: {integrity: sha512-ZWPnLAziEcSCvV0c8k9Qj88pfMu+wZwM5Qks87ShsfBgI8uLZ9tGHravA7gmjH1Gd7Bgxy2ulvXtSqIWPh1lew==} + + '@cspell/dict-php@4.0.8': + resolution: {integrity: sha512-TBw3won4MCBQ2wdu7kvgOCR3dY2Tb+LJHgDUpuquy3WnzGiSDJ4AVelrZdE1xu7mjFJUr4q48aB21YT5uQqPZA==} + + '@cspell/dict-powershell@5.0.4': + resolution: {integrity: sha512-eosDShapDgBWN9ULF7+sRNdUtzRnUdsfEdBSchDm8FZA4HOqxUSZy3b/cX/Rdw0Fnw0AKgk0kzgXw7tS6vwJMQ==} + + '@cspell/dict-public-licenses@2.0.7': + resolution: {integrity: sha512-KlBXuGcN3LE7tQi/GEqKiDewWGGuopiAD0zRK1QilOx5Co8XAvs044gk4MNIQftc8r0nHeUI+irJKLGcR36DIQ==} + + '@cspell/dict-python@4.2.1': + resolution: {integrity: sha512-9X2jRgyM0cxBoFQRo4Zc8oacyWnXi+0/bMI5FGibZNZV4y/o9UoFEr6agjU260/cXHTjIdkX233nN7eb7dtyRg==} + + '@cspell/dict-r@2.0.1': + resolution: {integrity: sha512-KCmKaeYMLm2Ip79mlYPc8p+B2uzwBp4KMkzeLd5E6jUlCL93Y5Nvq68wV5fRLDRTf7N1LvofkVFWfDcednFOgA==} + + '@cspell/dict-ruby@5.0.2': + resolution: {integrity: sha512-cIh8KTjpldzFzKGgrqUX4bFyav5lC52hXDKo4LbRuMVncs3zg4hcSf4HtURY+f2AfEZzN6ZKzXafQpThq3dl2g==} + + '@cspell/dict-rust@4.0.4': + resolution: {integrity: sha512-v9/LcZknt/Xq7m1jdTWiQEtmkVVKdE1etAfGL2sgcWpZYewEa459HeWndNA0gfzQrpWX9sYay18mt7pqClJEdA==} + + '@cspell/dict-scala@5.0.2': + resolution: {integrity: sha512-v97ClgidZt99JUm7OjhQugDHmhx4U8fcgunHvD/BsXWjXNj4cTr0m0YjofyZoL44WpICsNuFV9F/sv9OM5HUEw==} + + '@cspell/dict-software-terms@3.4.6': + resolution: {integrity: sha512-Cap+WL4iM9NgwxdVIa93aDEGKGNm1t+DLJTnjoWkGHXxSBPG8Kcbnlss6mTtwLv9/NYPmQsmJi5qHXruuHx2ow==} + + '@cspell/dict-sql@2.1.3': + resolution: {integrity: sha512-SEyTNKJrjqD6PAzZ9WpdSu6P7wgdNtGV2RV8Kpuw1x6bV+YsSptuClYG+JSdRExBTE6LwIe1bTklejUp3ZP8TQ==} + + '@cspell/dict-svelte@1.0.2': + resolution: {integrity: sha512-rPJmnn/GsDs0btNvrRBciOhngKV98yZ9SHmg8qI6HLS8hZKvcXc0LMsf9LLuMK1TmS2+WQFAan6qeqg6bBxL2Q==} + + '@cspell/dict-swift@2.0.1': + resolution: {integrity: sha512-gxrCMUOndOk7xZFmXNtkCEeroZRnS2VbeaIPiymGRHj5H+qfTAzAKxtv7jJbVA3YYvEzWcVE2oKDP4wcbhIERw==} + + '@cspell/dict-terraform@1.0.0': + resolution: {integrity: sha512-Ak+vy4HP/bOgzf06BAMC30+ZvL9mzv21xLM2XtfnBLTDJGdxlk/nK0U6QT8VfFLqJ0ZZSpyOxGsUebWDCTr/zQ==} + + '@cspell/dict-typescript@3.1.5': + resolution: {integrity: sha512-EkIwwNV/xqEoBPJml2S16RXj65h1kvly8dfDLgXerrKw6puybZdvAHerAph6/uPTYdtLcsPyJYkPt5ISOJYrtw==} + + '@cspell/dict-vue@3.0.0': + resolution: {integrity: sha512-niiEMPWPV9IeRBRzZ0TBZmNnkK3olkOPYxC1Ny2AX4TGlYRajcW0WUtoSHmvvjZNfWLSg2L6ruiBeuPSbjnG6A==} + + '@cspell/dynamic-import@8.9.0': + resolution: {integrity: sha512-UYa2Xlf/Bg9b7lUlKn59Z6XhHtE00z5kgzkKCGAdS0W27i2qUZJHW3FfiKfknWLNLzfj7cVUAq2IHjbumbx9ow==} + engines: {node: '>=18.0'} + + '@cspell/strong-weak-map@8.9.0': + resolution: {integrity: sha512-HE0rkwtJ4/4QuXpJW1r4GIK+jhs2SYK4IACf3EE2mJufOWF4YxgfWwKBgztKE/0RDMJcxyvn/ubLUCnNClNfdg==} + engines: {node: '>=18'} + + '@cspell/url@8.9.0': + resolution: {integrity: sha512-FaHTEx6OBVKlkX7VgAPofBZ5vIdxNWYalb0uZwJ5FCc/PCMIF5l91DQGQxRMas3qzRACR911kJamPdeK/3qilw==} + engines: {node: '>=18.0'} + + '@eslint-community/eslint-utils@4.4.0': + resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + + '@eslint-community/regexpp@4.10.1': + resolution: {integrity: sha512-Zm2NGpWELsQAD1xsJzGQpYfvICSsFkEpU0jxBjfdC6uNEWXcHnfs9hScFWtXVDVl+rBQJGrl4g1vcKIejpH9dA==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + '@eslint/config-array@0.16.0': + resolution: {integrity: sha512-/jmuSd74i4Czf1XXn7wGRWZCuyaUZ330NH1Bek0Pplatt4Sy1S5haN21SCLLdbeKslQ+S0wEJ+++v5YibSi+Lg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/eslintrc@3.1.0': + resolution: {integrity: sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/js@9.5.0': + resolution: {integrity: sha512-A7+AOT2ICkodvtsWnxZP4Xxk3NbZ3VMHd8oihydLRGrJgqqdEz1qSeEgXYyT/Cu8h1TWWsQRejIx48mtjZ5y1w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/object-schema@2.1.4': + resolution: {integrity: sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@humanwhocodes/module-importer@1.0.1': + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + + '@humanwhocodes/retry@0.3.0': + resolution: {integrity: sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew==} + engines: {node: '>=18.18'} + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn@8.12.0: + resolution: {integrity: sha512-RTvkC4w+KNXrM39/lWCUaG0IbRkWdCv7W/IOW9oU6SawyxulvkQy5HQPVTKxEjczcUvapcrw3cFx/60VN/NRNw==} + engines: {node: '>=0.4.0'} + hasBin: true + + ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-regex@6.0.1: + resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} + engines: {node: '>=12'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + array-timsort@1.0.3: + resolution: {integrity: sha512-/+3GRL7dDAGEfM6TseQk/U+mi18TU2Ms9I3UlLdUMhz2hbvGNTKdj9xniwXfUqgYhHxRx0+8UnKkvlNwVU+cWQ==} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + + chalk-template@1.1.0: + resolution: {integrity: sha512-T2VJbcDuZQ0Tb2EWwSotMPJjgpy1/tGee1BTpUNsGZ/qgNjV2t7Mvu+d4600U564nbLesN1x2dPL+xii174Ekg==} + engines: {node: '>=14.16'} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + chalk@5.3.0: + resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + + clear-module@4.1.2: + resolution: {integrity: sha512-LWAxzHqdHsAZlPlEyJ2Poz6AIs384mPeqLVCru2p0BrP9G/kVGuhNyZYClLO6cXlnuJjzC8xtsJIuMjKqLXoAw==} + engines: {node: '>=8'} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + commander@12.1.0: + resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} + engines: {node: '>=18'} + + comment-json@4.2.3: + resolution: {integrity: sha512-SsxdiOf064DWoZLH799Ata6u7iV658A11PlWtZATDlXPpKGJnbJZ5Z24ybixAi+LUUqJ/GKowAejtC5GFUG7Tw==} + engines: {node: '>= 6'} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + + cross-spawn@7.0.3: + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + engines: {node: '>= 8'} + + cspell-config-lib@8.9.0: + resolution: {integrity: sha512-1FQketvqo6IktnyC2ishEIzfqSX2DNhsfpb0MIG/nNeG5KvbjSeozOZpfyrALVqhPUJZVWfMP3+N0/hj3AzH+g==} + engines: {node: '>=18'} + + cspell-dictionary@8.9.0: + resolution: {integrity: sha512-IsFyWsn9P979xoJ0PgWHdyjxVcDYe5nVmHMgJRecQ5LLhl2gFkOmsu+aYIh2qlHCLmcbzH31Me2x7Fd+jA6AXw==} + engines: {node: '>=18'} + + cspell-gitignore@8.9.0: + resolution: {integrity: sha512-/iw+iqFLgySqW7xJ+kDHtC0mRjajDM1/jvnu4pUoxU9cRanCEqg2IAA/BET+n3ZEs/etsl8P4MB0lgWE98Z15g==} + engines: {node: '>=18'} + hasBin: true + + cspell-glob@8.9.0: + resolution: {integrity: sha512-j96SMMzT5Nz0nKCUECLkoyPEEms4hXKm/S7Vj80A356TFglTJD/yYiMKfWUamCVPm8UYODCz7W0s/liR7gSBSw==} + engines: {node: '>=18'} + + cspell-grammar@8.9.0: + resolution: {integrity: sha512-oZEOE64lLc0clLGOJeqc5d1Yzc1fUtXQAAeLIrS+uoVM7nA1SqgIEv1JBjp3R++8jQKLjS5n7v16VW5A/yk67w==} + engines: {node: '>=18'} + hasBin: true + + cspell-io@8.9.0: + resolution: {integrity: sha512-8KHERgqlg8KKpn04Owg2VY1Di2dSiwV/v63bUFxsGb8ORGIQ1VcydxtANwWuugUrZvtVrSFsbuU2fK/LRmAnoQ==} + engines: {node: '>=18'} + + cspell-lib@8.9.0: + resolution: {integrity: sha512-k347TQs1QRUyyHWHYQxPJddApos/irFousr9W/M/jEkYTTKzMMfaXK8m20kBSnlJ+BOUMa+f8d+KPEw6QLwtJQ==} + engines: {node: '>=18'} + + cspell-trie-lib@8.9.0: + resolution: {integrity: sha512-fQNQyFoeZA7b66jvhGaUYPzsS6gmPRJa6RcEpw2onP41S+IyLO6egubUu/qq8Hn1ebgJe/0Pc4fzkgv6MfV3tQ==} + engines: {node: '>=18'} + + cspell@8.9.0: + resolution: {integrity: sha512-lDYu5p/XU3rqiNjMV46s92yJ7SfVyzAy03OtCJ94fopegZwFLjqZvqoy509ccP/0sHmiv83oTed8LP6Fm3kjpw==} + engines: {node: '>=18'} + hasBin: true + + debug@4.3.5: + resolution: {integrity: sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + + env-paths@3.0.0: + resolution: {integrity: sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + eslint-config-prettier@9.1.0: + resolution: {integrity: sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==} + hasBin: true + peerDependencies: + eslint: '>=7.0.0' + + eslint-plugin-markdownlint@0.6.0: + resolution: {integrity: sha512-idYAzR2k7tQ+zL6UC17I/zzkqM0t6/k50uGgO39tabryqVkJh8Qe57fhBhe7QN+17yqIVqFB9YJFzBCAOdSXjw==} + engines: {node: '>=10'} + peerDependencies: + eslint: '>=7.5.0' + + eslint-scope@8.0.1: + resolution: {integrity: sha512-pL8XjgP4ZOmmwfFE8mEhSxA7ZY4C+LWyqjQ3o4yWkkmD0qcMT9kkW3zWHOczhWcjTSgqycYAgwSlXvZltv65og==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-visitor-keys@4.0.0: + resolution: {integrity: sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint@9.5.0: + resolution: {integrity: sha512-+NAOZFrW/jFTS3dASCGBxX1pkFD0/fsO+hfAkJ4TyYKwgsXZbqzrw+seCYFCcPCYXvnD67tAnglU7GQTz6kcVw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + hasBin: true + + espree@10.1.0: + resolution: {integrity: sha512-M1M6CpiE6ffoigIOWYO9UDP8TMUw9kqb21tf+08IgDYjCsOvCuDt4jQcZmoYxx+w7zlKw9/N0KXfto+I8/FrXA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + + esquery@1.5.0: + resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==} + engines: {node: '>=0.10'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-equals@5.0.1: + resolution: {integrity: sha512-WF1Wi8PwwSY7/6Kx0vKXtw8RwuSGoM1bvDaJbu7MxDlR1vovZjIAKrnzyrThgAjm6JDTu0fVgWXDlMGspodfoQ==} + engines: {node: '>=6.0.0'} + + fast-glob@3.3.2: + resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} + engines: {node: '>=8.6.0'} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + + fastq@1.17.1: + resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} + + file-entry-cache@8.0.0: + resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} + engines: {node: '>=16.0.0'} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + find-up-simple@1.0.0: + resolution: {integrity: sha512-q7Us7kcjj2VMePAa02hDAF6d+MzsdsAWEwYyOpwUtlerRBkOEPBCRZrAV4XfcSN8fHAgaD0hP7miwoay6DCprw==} + engines: {node: '>=18'} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + flat-cache@4.0.1: + resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} + engines: {node: '>=16'} + + flatted@3.3.1: + resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} + + gensequence@7.0.0: + resolution: {integrity: sha512-47Frx13aZh01afHJTB3zTtKIlFI6vWY+MYCN9Qpew6i52rfKjnhCF/l1YlC8UmEMvvntZZ6z4PiCcmyuedR2aQ==} + engines: {node: '>=18'} + + get-stdin@9.0.0: + resolution: {integrity: sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA==} + engines: {node: '>=12'} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + + global-directory@4.0.1: + resolution: {integrity: sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==} + engines: {node: '>=18'} + + globals@14.0.0: + resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} + engines: {node: '>=18'} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + has-own-prop@2.0.0: + resolution: {integrity: sha512-Pq0h+hvsVm6dDEa8x82GnLSYHOzNDt7f0ddFa3FqcQlgzEiptPqL+XrOJNavjOzSYiYWIrgeVYYgGlLmnxwilQ==} + engines: {node: '>=8'} + + ignore@5.3.1: + resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==} + engines: {node: '>= 4'} + + import-fresh@3.3.0: + resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} + engines: {node: '>=6'} + + import-meta-resolve@4.1.0: + resolution: {integrity: sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==} + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + ini@4.1.1: + resolution: {integrity: sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-path-inside@3.0.3: + resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} + engines: {node: '>=8'} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + + linkify-it@5.0.0: + resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + + markdown-it@14.1.0: + resolution: {integrity: sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==} + hasBin: true + + markdownlint-micromark@0.1.9: + resolution: {integrity: sha512-5hVs/DzAFa8XqYosbEAEg6ok6MF2smDj89ztn9pKkCtdKHVdPQuGMH7frFfYL9mLkvfFe4pTyAMffLbjf3/EyA==} + engines: {node: '>=18'} + + markdownlint@0.34.0: + resolution: {integrity: sha512-qwGyuyKwjkEMOJ10XN6OTKNOVYvOIi35RNvDLNxTof5s8UmyGHlCdpngRHoRGNvQVGuxO3BJ7uNSgdeX166WXw==} + engines: {node: '>=18'} + + mdurl@2.0.0: + resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + micromatch@4.0.7: + resolution: {integrity: sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==} + engines: {node: '>=8.6'} + + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + parent-module@2.0.0: + resolution: {integrity: sha512-uo0Z9JJeWzv8BG+tRcapBKNJ0dro9cLyczGzulS6EfeyAdeC9sbojtW6XwvYxJkEne9En+J2XEl4zyglVeIwFg==} + engines: {node: '>=8'} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + + prettier@3.3.2: + resolution: {integrity: sha512-rAVeHYMcv8ATV5d508CFdn+8/pHPpXeIid1DdrPwXnaAdH7cqjVbpJaT5eq4yRAFU/lsbwYwSF/n5iNrdJHPQA==} + engines: {node: '>=14'} + hasBin: true + + punycode.js@2.3.1: + resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==} + engines: {node: '>=6'} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + repeat-string@1.6.1: + resolution: {integrity: sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==} + engines: {node: '>=0.10'} + + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + + reusify@1.0.4: + resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + semver@7.6.2: + resolution: {integrity: sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==} + engines: {node: '>=10'} + hasBin: true + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + engines: {node: '>=12'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + text-table@0.2.0: + resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + + uc.micro@2.1.0: + resolution: {integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==} + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + vscode-languageserver-textdocument@1.0.11: + resolution: {integrity: sha512-X+8T3GoiwTVlJbicx/sIAF+yuJAqz8VvwJyoMVhwEMoEKE/fkDmrqUgDMyBECcM2A2frVZIUj5HI/ErRXCfOeA==} + + vscode-uri@3.0.8: + resolution: {integrity: sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + + xdg-basedir@5.1.0: + resolution: {integrity: sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ==} + engines: {node: '>=12'} + + yaml@2.4.5: + resolution: {integrity: sha512-aBx2bnqDzVOyNKfsysjA2ms5ZlnjSAW2eG3/L5G/CSujfjLJTJsEw1bGw8kCf04KodQWk1pxlGnZ56CRxiawmg==} + engines: {node: '>= 14'} + hasBin: true + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + +snapshots: + + '@cspell/cspell-bundled-dicts@8.9.0': + dependencies: + '@cspell/dict-ada': 4.0.2 + '@cspell/dict-aws': 4.0.2 + '@cspell/dict-bash': 4.1.3 + '@cspell/dict-companies': 3.1.2 + '@cspell/dict-cpp': 5.1.10 + '@cspell/dict-cryptocurrencies': 5.0.0 + '@cspell/dict-csharp': 4.0.2 + '@cspell/dict-css': 4.0.12 + '@cspell/dict-dart': 2.0.3 + '@cspell/dict-django': 4.1.0 + '@cspell/dict-docker': 1.1.7 + '@cspell/dict-dotnet': 5.0.2 + '@cspell/dict-elixir': 4.0.3 + '@cspell/dict-en-common-misspellings': 2.0.2 + '@cspell/dict-en-gb': 1.1.33 + '@cspell/dict-en_us': 4.3.22 + '@cspell/dict-filetypes': 3.0.4 + '@cspell/dict-fonts': 4.0.0 + '@cspell/dict-fsharp': 1.0.1 + '@cspell/dict-fullstack': 3.1.8 + '@cspell/dict-gaming-terms': 1.0.5 + '@cspell/dict-git': 3.0.0 + '@cspell/dict-golang': 6.0.9 + '@cspell/dict-google': 1.0.1 + '@cspell/dict-haskell': 4.0.1 + '@cspell/dict-html': 4.0.5 + '@cspell/dict-html-symbol-entities': 4.0.0 + '@cspell/dict-java': 5.0.7 + '@cspell/dict-julia': 1.0.1 + '@cspell/dict-k8s': 1.0.5 + '@cspell/dict-latex': 4.0.0 + '@cspell/dict-lorem-ipsum': 4.0.0 + '@cspell/dict-lua': 4.0.3 + '@cspell/dict-makefile': 1.0.0 + '@cspell/dict-monkeyc': 1.0.6 + '@cspell/dict-node': 5.0.1 + '@cspell/dict-npm': 5.0.16 + '@cspell/dict-php': 4.0.8 + '@cspell/dict-powershell': 5.0.4 + '@cspell/dict-public-licenses': 2.0.7 + '@cspell/dict-python': 4.2.1 + '@cspell/dict-r': 2.0.1 + '@cspell/dict-ruby': 5.0.2 + '@cspell/dict-rust': 4.0.4 + '@cspell/dict-scala': 5.0.2 + '@cspell/dict-software-terms': 3.4.6 + '@cspell/dict-sql': 2.1.3 + '@cspell/dict-svelte': 1.0.2 + '@cspell/dict-swift': 2.0.1 + '@cspell/dict-terraform': 1.0.0 + '@cspell/dict-typescript': 3.1.5 + '@cspell/dict-vue': 3.0.0 + + '@cspell/cspell-json-reporter@8.9.0': + dependencies: + '@cspell/cspell-types': 8.9.0 + + '@cspell/cspell-pipe@8.9.0': {} + + '@cspell/cspell-resolver@8.9.0': + dependencies: + global-directory: 4.0.1 + + '@cspell/cspell-service-bus@8.9.0': {} + + '@cspell/cspell-types@8.9.0': {} + + '@cspell/dict-ada@4.0.2': {} + + '@cspell/dict-aws@4.0.2': {} + + '@cspell/dict-bash@4.1.3': {} + + '@cspell/dict-companies@3.1.2': {} + + '@cspell/dict-cpp@5.1.10': {} + + '@cspell/dict-cryptocurrencies@5.0.0': {} + + '@cspell/dict-csharp@4.0.2': {} + + '@cspell/dict-css@4.0.12': {} + + '@cspell/dict-dart@2.0.3': {} + + '@cspell/dict-data-science@2.0.1': {} + + '@cspell/dict-django@4.1.0': {} + + '@cspell/dict-docker@1.1.7': {} + + '@cspell/dict-dotnet@5.0.2': {} + + '@cspell/dict-elixir@4.0.3': {} + + '@cspell/dict-en-common-misspellings@2.0.2': {} + + '@cspell/dict-en-gb@1.1.33': {} + + '@cspell/dict-en_us@4.3.22': {} + + '@cspell/dict-filetypes@3.0.4': {} + + '@cspell/dict-fonts@4.0.0': {} + + '@cspell/dict-fsharp@1.0.1': {} + + '@cspell/dict-fullstack@3.1.8': {} + + '@cspell/dict-gaming-terms@1.0.5': {} + + '@cspell/dict-git@3.0.0': {} + + '@cspell/dict-golang@6.0.9': {} + + '@cspell/dict-google@1.0.1': {} + + '@cspell/dict-haskell@4.0.1': {} + + '@cspell/dict-html-symbol-entities@4.0.0': {} + + '@cspell/dict-html@4.0.5': {} + + '@cspell/dict-java@5.0.7': {} + + '@cspell/dict-julia@1.0.1': {} + + '@cspell/dict-k8s@1.0.5': {} + + '@cspell/dict-latex@4.0.0': {} + + '@cspell/dict-lorem-ipsum@4.0.0': {} + + '@cspell/dict-lua@4.0.3': {} + + '@cspell/dict-makefile@1.0.0': {} + + '@cspell/dict-monkeyc@1.0.6': {} + + '@cspell/dict-node@5.0.1': {} + + '@cspell/dict-npm@5.0.16': {} + + '@cspell/dict-php@4.0.8': {} + + '@cspell/dict-powershell@5.0.4': {} + + '@cspell/dict-public-licenses@2.0.7': {} + + '@cspell/dict-python@4.2.1': + dependencies: + '@cspell/dict-data-science': 2.0.1 + + '@cspell/dict-r@2.0.1': {} + + '@cspell/dict-ruby@5.0.2': {} + + '@cspell/dict-rust@4.0.4': {} + + '@cspell/dict-scala@5.0.2': {} + + '@cspell/dict-software-terms@3.4.6': {} + + '@cspell/dict-sql@2.1.3': {} + + '@cspell/dict-svelte@1.0.2': {} + + '@cspell/dict-swift@2.0.1': {} + + '@cspell/dict-terraform@1.0.0': {} + + '@cspell/dict-typescript@3.1.5': {} + + '@cspell/dict-vue@3.0.0': {} + + '@cspell/dynamic-import@8.9.0': + dependencies: + import-meta-resolve: 4.1.0 + + '@cspell/strong-weak-map@8.9.0': {} + + '@cspell/url@8.9.0': {} + + '@eslint-community/eslint-utils@4.4.0(eslint@9.5.0)': + dependencies: + eslint: 9.5.0 + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.10.1': {} + + '@eslint/config-array@0.16.0': + dependencies: + '@eslint/object-schema': 2.1.4 + debug: 4.3.5 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + + '@eslint/eslintrc@3.1.0': + dependencies: + ajv: 6.12.6 + debug: 4.3.5 + espree: 10.1.0 + globals: 14.0.0 + ignore: 5.3.1 + import-fresh: 3.3.0 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@eslint/js@9.5.0': {} + + '@eslint/object-schema@2.1.4': {} + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/retry@0.3.0': {} + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.17.1 + + acorn-jsx@5.3.2(acorn@8.12.0): + dependencies: + acorn: 8.12.0 + + acorn@8.12.0: {} + + ajv@6.12.6: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + ansi-regex@5.0.1: {} + + ansi-regex@6.0.1: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + argparse@2.0.1: {} + + array-timsort@1.0.3: {} + + balanced-match@1.0.2: {} + + brace-expansion@1.1.11: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + callsites@3.1.0: {} + + chalk-template@1.1.0: + dependencies: + chalk: 5.3.0 + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + chalk@5.3.0: {} + + clear-module@4.1.2: + dependencies: + parent-module: 2.0.0 + resolve-from: 5.0.0 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + commander@12.1.0: {} + + comment-json@4.2.3: + dependencies: + array-timsort: 1.0.3 + core-util-is: 1.0.3 + esprima: 4.0.1 + has-own-prop: 2.0.0 + repeat-string: 1.6.1 + + concat-map@0.0.1: {} + + core-util-is@1.0.3: {} + + cross-spawn@7.0.3: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + cspell-config-lib@8.9.0: + dependencies: + '@cspell/cspell-types': 8.9.0 + comment-json: 4.2.3 + yaml: 2.4.5 + + cspell-dictionary@8.9.0: + dependencies: + '@cspell/cspell-pipe': 8.9.0 + '@cspell/cspell-types': 8.9.0 + cspell-trie-lib: 8.9.0 + fast-equals: 5.0.1 + gensequence: 7.0.0 + + cspell-gitignore@8.9.0: + dependencies: + cspell-glob: 8.9.0 + find-up-simple: 1.0.0 + + cspell-glob@8.9.0: + dependencies: + micromatch: 4.0.7 + + cspell-grammar@8.9.0: + dependencies: + '@cspell/cspell-pipe': 8.9.0 + '@cspell/cspell-types': 8.9.0 + + cspell-io@8.9.0: + dependencies: + '@cspell/cspell-service-bus': 8.9.0 + '@cspell/url': 8.9.0 + + cspell-lib@8.9.0: + dependencies: + '@cspell/cspell-bundled-dicts': 8.9.0 + '@cspell/cspell-pipe': 8.9.0 + '@cspell/cspell-resolver': 8.9.0 + '@cspell/cspell-types': 8.9.0 + '@cspell/dynamic-import': 8.9.0 + '@cspell/strong-weak-map': 8.9.0 + '@cspell/url': 8.9.0 + clear-module: 4.1.2 + comment-json: 4.2.3 + cspell-config-lib: 8.9.0 + cspell-dictionary: 8.9.0 + cspell-glob: 8.9.0 + cspell-grammar: 8.9.0 + cspell-io: 8.9.0 + cspell-trie-lib: 8.9.0 + env-paths: 3.0.0 + fast-equals: 5.0.1 + gensequence: 7.0.0 + import-fresh: 3.3.0 + resolve-from: 5.0.0 + vscode-languageserver-textdocument: 1.0.11 + vscode-uri: 3.0.8 + xdg-basedir: 5.1.0 + + cspell-trie-lib@8.9.0: + dependencies: + '@cspell/cspell-pipe': 8.9.0 + '@cspell/cspell-types': 8.9.0 + gensequence: 7.0.0 + + cspell@8.9.0: + dependencies: + '@cspell/cspell-json-reporter': 8.9.0 + '@cspell/cspell-pipe': 8.9.0 + '@cspell/cspell-types': 8.9.0 + '@cspell/dynamic-import': 8.9.0 + chalk: 5.3.0 + chalk-template: 1.1.0 + commander: 12.1.0 + cspell-gitignore: 8.9.0 + cspell-glob: 8.9.0 + cspell-io: 8.9.0 + cspell-lib: 8.9.0 + fast-glob: 3.3.2 + fast-json-stable-stringify: 2.1.0 + file-entry-cache: 8.0.0 + get-stdin: 9.0.0 + semver: 7.6.2 + strip-ansi: 7.1.0 + vscode-uri: 3.0.8 + + debug@4.3.5: + dependencies: + ms: 2.1.2 + + deep-is@0.1.4: {} + + entities@4.5.0: {} + + env-paths@3.0.0: {} + + escape-string-regexp@4.0.0: {} + + eslint-config-prettier@9.1.0(eslint@9.5.0): + dependencies: + eslint: 9.5.0 + + eslint-plugin-markdownlint@0.6.0(eslint@9.5.0): + dependencies: + eslint: 9.5.0 + markdownlint: 0.34.0 + + eslint-scope@8.0.1: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-visitor-keys@3.4.3: {} + + eslint-visitor-keys@4.0.0: {} + + eslint@9.5.0: + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@9.5.0) + '@eslint-community/regexpp': 4.10.1 + '@eslint/config-array': 0.16.0 + '@eslint/eslintrc': 3.1.0 + '@eslint/js': 9.5.0 + '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.3.0 + '@nodelib/fs.walk': 1.2.8 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.3 + debug: 4.3.5 + escape-string-regexp: 4.0.0 + eslint-scope: 8.0.1 + eslint-visitor-keys: 4.0.0 + espree: 10.1.0 + esquery: 1.5.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 8.0.0 + find-up: 5.0.0 + glob-parent: 6.0.2 + ignore: 5.3.1 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + is-path-inside: 3.0.3 + json-stable-stringify-without-jsonify: 1.0.1 + levn: 0.4.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.4 + strip-ansi: 6.0.1 + text-table: 0.2.0 + transitivePeerDependencies: + - supports-color + + espree@10.1.0: + dependencies: + acorn: 8.12.0 + acorn-jsx: 5.3.2(acorn@8.12.0) + eslint-visitor-keys: 4.0.0 + + esprima@4.0.1: {} + + esquery@1.5.0: + dependencies: + estraverse: 5.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@5.3.0: {} + + esutils@2.0.3: {} + + fast-deep-equal@3.1.3: {} + + fast-equals@5.0.1: {} + + fast-glob@3.3.2: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.7 + + fast-json-stable-stringify@2.1.0: {} + + fast-levenshtein@2.0.6: {} + + fastq@1.17.1: + dependencies: + reusify: 1.0.4 + + file-entry-cache@8.0.0: + dependencies: + flat-cache: 4.0.1 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + find-up-simple@1.0.0: {} + + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + flat-cache@4.0.1: + dependencies: + flatted: 3.3.1 + keyv: 4.5.4 + + flatted@3.3.1: {} + + gensequence@7.0.0: {} + + get-stdin@9.0.0: {} + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + global-directory@4.0.1: + dependencies: + ini: 4.1.1 + + globals@14.0.0: {} + + has-flag@4.0.0: {} + + has-own-prop@2.0.0: {} + + ignore@5.3.1: {} + + import-fresh@3.3.0: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + import-meta-resolve@4.1.0: {} + + imurmurhash@0.1.4: {} + + ini@4.1.1: {} + + is-extglob@2.1.1: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-number@7.0.0: {} + + is-path-inside@3.0.3: {} + + isexe@2.0.0: {} + + js-yaml@4.1.0: + dependencies: + argparse: 2.0.1 + + json-buffer@3.0.1: {} + + json-schema-traverse@0.4.1: {} + + json-stable-stringify-without-jsonify@1.0.1: {} + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + + linkify-it@5.0.0: + dependencies: + uc.micro: 2.1.0 + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + lodash.merge@4.6.2: {} + + markdown-it@14.1.0: + dependencies: + argparse: 2.0.1 + entities: 4.5.0 + linkify-it: 5.0.0 + mdurl: 2.0.0 + punycode.js: 2.3.1 + uc.micro: 2.1.0 + + markdownlint-micromark@0.1.9: {} + + markdownlint@0.34.0: + dependencies: + markdown-it: 14.1.0 + markdownlint-micromark: 0.1.9 + + mdurl@2.0.0: {} + + merge2@1.4.1: {} + + micromatch@4.0.7: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.11 + + ms@2.1.2: {} + + natural-compare@1.4.0: {} + + optionator@0.9.4: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + + parent-module@2.0.0: + dependencies: + callsites: 3.1.0 + + path-exists@4.0.0: {} + + path-key@3.1.1: {} + + picomatch@2.3.1: {} + + prelude-ls@1.2.1: {} + + prettier@3.3.2: {} + + punycode.js@2.3.1: {} + + punycode@2.3.1: {} + + queue-microtask@1.2.3: {} + + repeat-string@1.6.1: {} + + resolve-from@4.0.0: {} + + resolve-from@5.0.0: {} + + reusify@1.0.4: {} + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + semver@7.6.2: {} + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-ansi@7.1.0: + dependencies: + ansi-regex: 6.0.1 + + strip-json-comments@3.1.1: {} + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + text-table@0.2.0: {} + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + type-check@0.4.0: + dependencies: + prelude-ls: 1.2.1 + + uc.micro@2.1.0: {} + + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + + vscode-languageserver-textdocument@1.0.11: {} + + vscode-uri@3.0.8: {} + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + word-wrap@1.2.5: {} + + xdg-basedir@5.1.0: {} + + yaml@2.4.5: {} + + yocto-queue@0.1.0: {} diff --git a/project-words.txt b/project-words.txt new file mode 100644 index 0000000..a865957 --- /dev/null +++ b/project-words.txt @@ -0,0 +1,38 @@ +NUMS +PUSHBYTES +Taproot +Tapscript +Taptree +alpen +bcoin +bibt +bitcoinj +blockquotes +btcd +checkpointing +counterparty +cpfp +cryptosystem +devnet +endhint +hashpower +incentivized +infty +libbitcoin +mainchain +mermaidjs +mkdocs +multisigs +offchain +println +pseudocode +pubkey +satoshis +secp +snarknado +squidfunk +timelock +txid +unspendable +utxo +Ðapp diff --git a/style-guide.md b/style-guide.md new file mode 100644 index 0000000..caea8dc --- /dev/null +++ b/style-guide.md @@ -0,0 +1,317 @@ +# Documentation style guide + +Alpen Labs documentation follow the following guidelines. +Please adhere to these guidelines when contributing to the documentation. + +We are using a simple documentation framework called +[`mkdocs-material`](https://squidfunk.github.io/mkdocs-material/) +that is built on top of `Markdown` files. + +## General guidelines + +- **Clarity**: Write clear and concise documentation. + Only add technical terms or jargons if they add clarity to the concept being + described. At the same time, avoid skipping details for the sake of + conciseness. +- **Consistency**: Ensure consistency in terms, formatting, and style throughout + the documentation. +- **Accuracy**: Keep information accurate and up-to-date. Verify facts and + details before including them in the documentation. +- **Audience**: Consider the target audience (beginners, advanced users, + developers) and tailor the content accordingly. + +## Language and tone + +- **Voice**: Use active voice whenever possible. + - Active: "The system processes the data." + - Passive: "The data is processed by the system." +- **Tone**: Use a friendly and professional tone. +- **Grammar**: Use correct grammar and punctuation. Avoid contractions. +- **Terminology**: Use consistent terminology throughout the documentation. + Define any technical terms or acronyms when first introduced. + +## Bitcoin-related guidelines + +- **Bitcoin**: The word "bitcoin" is not capitalized if referring to either + the asset, the network, or the protocol. "Bitcoin" is capitalized if it is + the first word in a sentence or if it is a proper noun that is part of something's + name e.g. Bitcoin Core. + - The ticker symbol for the native asset of the bitcoin blockchain is BTC. +- **Blockchain**: The word "blockchain" is not capitalized unless it is a proper + noun part of something's name e.g. "Blockchain Inc." + - The word “blockchain” is a one word (i.e. not “block chain”) + [concrete noun](https://medium.com/@ryanshea/blockchain-terminology-a-grammar-usage-guide-ff54c95167bb) + and should always be preceded by either a possessive noun, “a”, or “the” e.g. + “bitcoin’s blockchain”, “a blockchain”, or “the blockchain”. +- **Decentralized applications**: The abbreviation of “decentralized application” + is “dapp”. Not “DApp”, “dApp”, or “Ðapp”. + - There is an ongoing debate over whether the term “decentralized application” + is useful to begin with, at least in user-facing communications. In light of + this, we should generally refer to a so-called "decentralized application" as + an "app" or maybe more specifically "web app" or "mobile app" rather than a "dapp". + If it is actually decentralized in some way, we can describe how in specific + detail if the context calls for it. +- **Zero-knowledge**: The term "zero-knowledge" as in "zero-knowledge proof" + (or "zk" for short) was originally defined as "those proofs that contain no + additional knowledge other than the correctness of the proposition in question". + However the term has since been used colloquially to describe any cryptosystem + that enables sub-linear verification of computation using a validity proof, + whether it is actually zero-knowledge or not. Due to this common usage and + understanding we therefore accept the use of "zero-knowledge" or "zk" as + synonymous with verifiable computation and may use these terms this same way + throughout the documentation. + +## File organization + +- **Directory structure**: Organize documentation files in a logical and + consistent directory structure. + + - Example: + + ```plaintext + docs/ + ├── bridge-specs/ + │ ├── index.md + │ ├── deposit-path.md + │ └── withdrawal-path.md + └── rollup-specs/ + ├── index.md + ├── prover.md + └── consensus-state-machine.md + ``` + +- **File naming**: Use descriptive and consistent file names. Use hyphens to + separate words. + - Example: `basic-usage.md` +- **Index Files**: Use the index files (`index.md`) to provide the table + of contents for the doc. + +## Formatting + +- **Commas**: Always use an Oxford comma (“Note that a, b, and c are…”). +- **Spelling**: Use American English spelling of a word when the spelling + varies by locale. +- **Capitalization**: Page titles and headings should be in sentence case. + This means that the first word is always capitalized and all other words + except proper nouns and acronyms are lowercase. +- **Numbers**: Use numbers for numeric parameters, no matter how short the + number e.g. 1 block, 5 seconds, 10 KB, etc. +- **Line Length**: Keep lines of text to a reasonable length (80 characters) + for readability. +- **Headings**: Use hierarchical headings (H1, H2, H3, H4) to organize content. + - H1: `# Title` + - H2: `## Subtitle` + - H3: `### Section` + - H4: `#### Subsection` +- **Lists**: + - Use unordered lists (`-`) for bullet points. + - Use ordered lists (`1.`) for step-by-step instructions. + Note that ordered lists should start from `1.` for each step. + This ensures that the numbering is consistent across the document while also + producing sane diffs in version control. + - Lists should always be in alphabetical, numerical, or chronological order, unless + there’s a good reason for them not to be. +- **Bullet points** + - Use a period (full stop) after every bullet point that is a sentence. + - Use a period after every bullet point that completes the introductory stem. + - Use no punctuation after bullets that are fragment sentences and do not + complete the stem. + - Use all complete sentences or all fragments, but not a mixture. + - Use no punctuation after bullets that only contain one word e.g. There are + multiple implementations of bitcoin, including: + - Bitcoin Core + - bcoin + - bitcoinj + - btcd + - libbitcoin +- **Emphasis**: + - Use `_italic_` for emphasis. + - Use `**bold**` for strong emphasis. +- **Blockquotes**: Use `>` for blockquotes to highlight important notes or + quotes. +- **Tables**: Use tables for structured data. + + - Example: + + ```markdown + | Header 1 | Header 2 | + | -------- | -------- | + | Cell 1 | Cell 2 | + ``` + +- **Admonitions**: Use `!!!` for admonitions. Please refer to the + [`mkdocs-material` documentation](https://squidfunk.github.io/mkdocs-material/reference/admonitions/). + + - Examples: + + ```markdown + !!! note + + Useful information that users should know, even when skimming content. + + !!! info + + Additional information that provides context or clarification + + !!! tip + + Helpful advice for doing things better or more easily. + + !!! warning + + Urgent info that needs immediate user attention to avoid problems. + + !!! danger + + Advises about risks or negative outcomes of certain actions. + ``` + +- **Equations**: Use `$` for inline equations and `$$` for block equations. + You can also label them if needed for reference. + Example: + + ```markdown + There are $N^2$ different BitVM games. + ``` + + For block equations, use new-line separators. + Example: + + ```markdown + The parameters ought to have the following relationship: + + $$ + d < \frac{p + q}{2} + $$ + ``` + + Finally, here's how you can label equations: + + ```markdown + $$ + \begin{equation} + \int_0^\infty \frac{x^3}{e^x-1}\,dx = \frac{\pi^4}{15} + \label{eq:sample} + \end{equation} + $$ + ``` + +- **Time format**: The format to use for dates is either YYYY-MM-DD if numeric + (e.g 2020-12-31) or Month D(st)(th)(D, YYYY) if spelled out (e.g. January 1st + or December 31, 2020). + - Related: all times are communicated in UTC and specified as such to avoid + the confusion of “Daylight Savings Time”, which is inconsistently implemented + across the world + ([even within the same country](https://en.wikipedia.org/wiki/Daylight_saving_time_in_the_United_States#Local_DST_observance)) + and is [generally a scourge on humanity](https://www.inc.com/jessica-stillman/experts-to-public-daylight-savings-time-is-a-434m-problem-we-could-easily-fix.html). + An exception would be if there is an event being held locally in a specific + time zone and there's no need to specify a time zone because all attendees will + be in that time zone. In this case, the local time zone does not need to be + specified unless the event is also being live-streamed so that people worldwide + can watch online; here, both the local time zone and UTC time should be + specified e.g. “17:00 EDT / 21:00 UTC”. + +## Code and Commands + +- **Inline Code**: Use backticks for inline code snippets. + - Example: `inline code` +- **Code Blocks**: Use triple backticks for multi-line code blocks. + Specify the language for syntax highlighting. + Use annotations to provide context or explanations for code blocks. + Annotations should be prefixed with language-specific comment characters, + and should be followed by a footnote with the same id as the annotation. + + - Examples: + + ```python + def example_fn(): + print("Hello, World!") + ``` + + ```rust + fn example_fn() { + println!("Hello, World!"); + } + ``` + + ```python + # This code has an annotation at the end of the print function call. + # You should add a footnote with the same id as the annotation, i.e. (1). + def example_fn(): + print("Hello, World!") # (1) + ``` + +- **Commands**: Prefix shell commands with `$` to distinguish them from code + blocks. + + - Example: + + ```bash + git clone https://github.com/your-user/your-repo.git + ``` + +## Links and References + +- **Internal Links**: Use relative links for internal references within the + documentation. + - Example: `[Section Title](#section-title)` +- **External Links**: Use absolute URLs for external references. + - Example: `[External Resource](https://example.com)` +- **References**: Cite any external resources, documents, or articles + appropriately. +- **Footnotes**: Use footnotes to add some extra relevant information. These can + be used to display texts when hovering on certain words. Footnotes can be + multiline as well. To start a new line, prefix it with two spaces. + + - Example: + + ```markdown + At least one of the operators must be functional[^1] to prevent theft of + funds from this address. + + [^1]: + We use the term "functional" to describe an operator who is correctly + following the protocol rules. An operator that is not functional is + called "faulty". + ``` + +## Images and Diagrams + +- **Images**: Use clear and relevant images to support the text. + Don't forget to add captions. + + - Example: + + ```markdown +

+ ![Image title](https://dummyimage.com/600x400/){ width="300" } +
Image caption
+
+ ``` + +- **Diagrams**: Use diagrams to illustrate complex concepts. `mkdocs-material` + has support for [`mermaidjs`](https://mermaid.js.org/), which can be included + with the following syntax: + + ```mermaidjs + graph LR + A[Start] --> B{Error?}; + B -->|Yes| C[Hmm...]; + C --> D[Debug]; + D --> B; + B ---->|No| E[Yay!]; + ``` + +## Commit message format + +Make your commit messages descriptive, concise and in the imperative form. +When in doubt, follow these excellent guides: + +- [Write Better Commits, Build Better Projects](https://github.blog/2022-06-30-write-better-commits-build-better-projects/) +- [A Note About Git Commit Messages](https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html) + +--- + +**Thank you for contributing to our documentation! +Adhering to this style guide helps maintain high-quality and consistent +documentation.**