What changed, and why it matters
This commit is a large repository import or merge that adds many project files (documentation, CI, Docker, helper scripts, dependency lock file, etc.) and makes one small functional change: it allows users to configure the Bitcoin P2P network 'magic' bytes on networks other than signet. Previously this option was restricted to signet. The change is intended to support custom testing networks. There is no direct evidence in the commit of a security vulnerability, but it slightly increases the chance of misconfiguration when connecting to custom or test networks.
Review the actual code change that exposes the magic option to confirm it still enforces sensible defaults and validates the supplied value. If running on a custom network, ensure the configured magic matches the connected bitcoind's network to avoid accidental connection to an unintended chain or peer. No urgent patch is indicated by this commit alone.
Security signals we found
New configuration option exposes network magic override beyond signet
Large repository import obscures the precise code change
No validation or bounds checking on the magic value is visible in the diff
No vendor security disclosure or advisory references present
Evidence from the diff
The commit title ‘multi: expose configurable magic on non-signet’ describes a minor configuration change: the signet-only ‘magic’ option is now available for other networks. The diff supplied, however, is almost entirely an initial import of project files (Cargo.lock, README, docs, Dockerfiles, GitHub templates, contrib scripts) rather than a focused patch. The actual code change is not visible in the provided diff. The change lets operators override the P2P network magic value, which is normally hard-coded per network. This is useful for custom test networks but means the daemon will trust the configured magic when validating P2P messages. No validation logic changes are shown. No CVE, advisory, or vendor security statement is present.
Changed components
src/config.rsinternal/config_specification.tomlsrc/daemon.rssrc/p2p.rsInspect captured patch +12271 / −0
diff --git a/.cargo/audit.toml b/.cargo/audit.toml
new file mode 100644
index 0000000..b28486d
--- /dev/null
+++ b/.cargo/audit.toml
@@ -0,0 +1 @@
+[advisories]
diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 0000000..30f8bb2
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,11 @@
+.*
+_*
+contrib
+db*
+dist
+doc
+Dockerfile
+examples
+scripts
+target
+tests
diff --git a/.github/ISSUE_TEMPLATE/bug.md b/.github/ISSUE_TEMPLATE/bug.md
new file mode 100644
index 0000000..3abca6d
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug.md
@@ -0,0 +1,59 @@
+---
+name: Bug report
+about: Generic bug report
+title: 'Bug:'
+labels: bug
+assignees: ''
+
+---
+
+<!--
+ IMPORTANT: IF YOU DON'T FILL THIS TEMPLATE COMPLETELY IT WILL TAKE MORE TIME FOR US TO HELP YOU!
+ SOME EXTERNAL ELECTRS GUIDES SUCH AS RASPIBOLT ARE OUTDATED AND DO NOT WORK SO SHOULD NOT BE FOLLOWED!
+ Please try with OUR usage instructions first.
+
+ If you use electrs integrated into other project report the bug to their project
+ (unless you are the project author who found the bug is in electrs itself)!
+-->
+
+**Describe the bug**
+A clear and concise description of what the bug is.
+
+**Electrs version**
+Which version of `electrs` do you use? Please try to use newest version if possible.
+If it's not the newest version why you can't try the newest one?
+
+**To Reproduce**
+Steps to reproduce the behavior:
+1. Configure and start electrs
+2. Connect with electrum client XYZ
+3. Wait
+4. See error
+
+**Expected behavior**
+A clear and concise description of what you expected to happen.
+
+**Configuration**
+<!-- repeat the whole details block if you use multiple config files -->
+
+<details>
+<summary>electrs.toml</summary>
+
+```
+type error message here
+```
+
+</details>
+
+Environment variables: `ELECTRS_X=Y;...`
+Arguments: `--foo`
+
+**System running electrs**
+ - Deployment method: manual (which guide did you follow?)/native OS package/Docker
+ - OS name and version (name of distribution and version in case of Linux)
+
+**Electrum client**
+Client name (if not upstream desktop Electrum) and version:
+
+**Additional context**
+Add any other context about the problem here.
diff --git a/.github/ISSUE_TEMPLATE/build_problem.md b/.github/ISSUE_TEMPLATE/build_problem.md
new file mode 100644
index 0000000..55a242a
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/build_problem.md
@@ -0,0 +1,50 @@
+---
+name: Build problem
+about: Building of electrs failed
+title: 'Build:'
+labels: bug, build
+assignees: Kixunil
+
+---
+
+<!--
+ IMPORTANT: IF YOU DON'T FILL THIS TEMPLATE COMPLETELY IT WILL TAKE MORE TIME FOR US TO HELP YOU!
+ SOME EXTERNAL ELECTRS GUIDES SUCH AS RASPIBOLT ARE OUTDATED AND DO NOT WORK SO SHOULD NOT BE FOLLOWED!
+ Please try with OUR usage instructions first.
+
+ If your build died with SIGKILL, try clearing up some RAM.
+ If you have a low-memory device (such as RPi) try cross-compilation first.
+-->
+
+**Have you read the documentation?**
+Yes. (Please, read usage.md first if you did not.)
+
+**Did you double-check that you installed all dependencies?**
+Yes. (Please, double check the dependencies if you didn't.)
+
+**Which command failed?**
+`cargo build`
+
+**What was the error message?**
+
+<details>
+<summary>Error message</summary>
+
+```
+type error message here
+```
+
+</details>
+
+**System**
+OS name and version: (If Linux, the distribution name and version)
+rustc version: (run `rustc --version`)
+cargo version: (run `cargo --version`; not guaranteed to be same as rustc version!)
+
+**Compilation**
+Linking: static/dynamic
+Cross compilation: yes/no
+Target architecture: (uname -m on Linux if not cross-compiling)
+
+**Additional context**
+Any additional information that seems to be relevant.
diff --git a/.github/ISSUE_TEMPLATE/config_problem.md b/.github/ISSUE_TEMPLATE/config_problem.md
new file mode 100644
index 0000000..8db2a89
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/config_problem.md
@@ -0,0 +1,46 @@
+---
+name: Configuration problem
+about: The configuration behaves unexpectedly
+title: 'Config:'
+labels: bug
+assignees: Kixunil
+
+---
+
+<!--
+ IMPORTANT: IF YOU DON'T FILL THIS TEMPLATE COMPLETELY IT WILL TAKE MORE TIME FOR US TO HELP YOU!
+ SOME EXTERNAL ELECTRS GUIDES SUCH AS RASPIBOLT ARE OUTDATED AND DO NOT WORK SO SHOULD NOT BE FOLLOWED!
+ Please try with OUR usage instructions first.
+
+ If you're inexperienced with service configuration consider using automated options such as https://deb.ln-ask.me
+-->
+
+**Have you read the documentation?**
+Yes. (Please, read usage.md first if you did not.)
+
+**How did you configure electrs?**
+
+<!-- repeat the whole details block if you use multiple config files -->
+
+<details>
+<summary>electrs.toml</summary>
+
+```
+type error message here
+```
+
+</details>
+
+Environment variables: `ELECTRS_X=Y;...`
+Arguments: `--foo`
+
+**Debug output of configuration**
+```
+Enter the debug output of configuration shown at start of electrs
+```
+
+**Expected behavior**
+How did you expect `electrs` to be configured
+
+**Actual behavior**
+How does `electrs` behave?
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
new file mode 100644
index 0000000..86a3e23
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature_request.md
@@ -0,0 +1,20 @@
+---
+name: Feature request
+about: Generic feature request
+title: 'Feature:'
+labels: enhancement
+assignees: ''
+
+---
+
+**Is your feature request related to a problem? Please describe.**
+A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
+
+**Describe the solution you'd like**
+A clear and concise description of what you want to happen.
+
+**Describe alternatives you've considered**
+A clear and concise description of any alternative solutions or features you've considered.
+
+**Additional context**
+Add any other context or screenshots about the feature request here.
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 0000000..53f8242
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,6 @@
+version: 2
+updates:
+ - package-ecosystem: "cargo"
+ directory: "/"
+ schedule:
+ interval: "weekly"
diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml
new file mode 100644
index 0000000..8141838
--- /dev/null
+++ b/.github/workflows/rust.yml
@@ -0,0 +1,59 @@
+name: electrs
+
+on:
+ push:
+ branches:
+ - master
+ pull_request:
+ schedule:
+ - cron: "0 0 * * *" # once a day
+
+jobs:
+ build:
+ name: Build
+
+ runs-on: ${{ matrix.os }}
+
+ strategy:
+ matrix:
+ os: [ubuntu-latest, windows-latest]
+ build-args:
+ [
+ --locked --no-default-features,
+ --locked
+ ]
+ include:
+ - os: ubuntu-latest
+ build-args: --locked --features metrics_process
+
+ steps:
+ - uses: actions/checkout@v3
+ - uses: dtolnay/rust-toolchain@stable
+ with:
+ components: rustfmt, clippy
+
+ - name: Install Rust
+ run: rustup component add rustfmt clippy
+
+ - name: Format
+ run: cargo fmt --all -- --check
+
+ - name: Build
+ run: cargo build ${{ matrix.build-args }} --all
+
+ - name: Test
+ run: cargo test ${{ matrix.build-args }} --all
+
+ - name: Clippy
+ run: cargo clippy -- -D warnings
+
+ integration:
+ name: Integration
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v3
+ - name: Build
+ run: docker build -f Dockerfile.ci . --rm -t electrs:tests
+ - name: Test
+ run: docker run -v $PWD/contrib/:/contrib -v $PWD/tests/:/tests --rm electrs:tests bash /tests/run.sh
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..12aeff5
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,16 @@
+target
+/db*/
+_*/
+*.log
+*.sublime*
+*~
+*.pyc
+.env
+*.dat
+electrs.toml
+data/
+tests/bitcoin-*
+tests/bin
+.idea/
+*.txt
+*.json
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..6d9d1b4
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,91 @@
+# Contributing to electrs
+
+:+1::tada: First off, thanks for taking the time to contribute! :tada::+1:
+
+The following is a set of guidelines for contributing to this project! These are
+mostly guidelines, not rules. Use your best judgment, and feel free to propose
+changes to this document in a pull request.
+
+## General
+
+Electrs project operates an open contributor model where anyone is
+welcome to contribute towards development in the form of peer review,
+documentation, testing and patches.
+
+Anyone is invited to contribute without regard to technical experience,
+"expertise", OSS experience, age, or other concern. However, the development of
+standards & reference implementations demands a high-level of rigor, adversarial
+thinking, thorough testing and risk-minimization. Any bug may cost users real
+money. That being said, we deeply welcome people contributing for the first time
+to an open source project or pick up Rust while contributing. Don't be shy,
+you'll learn.
+
+
+## Contribution workflow
+
+The codebase is maintained using the "contributor workflow" where everyone
+without exception contributes patch proposals using "pull requests". This
+facilitates social contribution, easy testing and peer review.
+
+To contribute a patch, the workflow is a as follows:
+
+1. Fork repository
+2. Create topic branch
+3. Commit patches
+
+Please keep commits should atomic and diffs easy to read. For this reason
+do not mix any formatting fixes or code moves with actual code changes.
+Further, each commit, individually, should compile and pass tests, in order to
+ensure git bisect and other automated tools function properly.
+
+Please cover every new feature with unit tests.
+
+When refactoring, structure your PR to make it easy to review and don't hesitate
+to split it into multiple small, focused PRs.
+
+To facilitate communication with other contributors, the project is making use
+of GitHub's "assignee" field. First check that no one is assigned and then
+comment suggesting that you're working on it. If someone is already assigned,
+don't hesitate to ask if the assigned party or previous commenters are still
+working on it if it has been awhile.
+
+
+## Preparing PRs
+
+The main library development happens in the `master` branch. This branch must
+always compile without errors (using GitHub CI). All external contributions are
+made within PRs into this branch.
+
+Prerequisites that a PR must satisfy for merging into the `master` branch:
+* final commit within the PR must compile and pass unit tests with no error
+* final commit of the PR must be properly formatted and linted
+* be based on the recent `master` tip from the original repository at
+ <https://github.com/romanz/electrs>.
+
+## Checking if the PR will pass the GitHub CI
+PR authors may also find it useful to run the following script locally in order
+to check that their code satisfies all the requirements of the GitHub workflows and doesn't fail
+automated build.
+
+You can run the following command from the root of the project:
+```
+./contrib/testChanges.sh
+```
+
+
+### Peer review
+
+Anyone may participate in peer review which is expressed by comments in the pull
+request. Typically, reviewers will review the code for obvious errors, as well as
+test out the patch set and opine on the technical merits of the patch. Please,
+first review PR on the conceptual level before focusing on code style or
+grammar fixes.
+
+
+### Formatting
+
+The repository currently does use `rustfmt` for all the formatting needs. Running the automated
+script mentioned above would format all your code for you :)
+
+## Ending Notes
+Get cracking, have fun, and do ask for help when in doubt!
\ No newline at end of file
diff --git a/Cargo.lock b/Cargo.lock
new file mode 100644
index 0000000..86b3d0a
--- /dev/null
+++ b/Cargo.lock
@@ -0,0 +1,1534 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "aho-corasick"
+version = "1.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "anyhow"
+version = "1.0.80"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5ad32ce52e4161730f7098c077cd2ed6229b5804ccf99e5366be1ab72a98b4e1"
+
+[[package]]
+name = "arrayvec"
+version = "0.7.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711"
+
+[[package]]
+name = "ascii"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d92bec98840b8f03a5ff5413de5293bfcd8bf96467cf5452609f939ec6f5de16"
+
+[[package]]
+name = "autocfg"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
+
+[[package]]
+name = "base58ck"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2c8d66485a3a2ea485c1913c4572ce0256067a5377ac8c75c4960e1cda98605f"
+dependencies = [
+ "bitcoin-internals",
+ "bitcoin_hashes",
+]
+
+[[package]]
+name = "base64"
+version = "0.13.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
+
+[[package]]
+name = "bech32"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d965446196e3b7decd44aa7ee49e31d630118f90ef12f97900f262eb915c951d"
+
+[[package]]
+name = "bindgen"
+version = "0.63.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "36d860121800b2a9a94f9b5604b332d5cffb234ce17609ea479d723dbc9d3885"
+dependencies = [
+ "bitflags 1.3.2",
+ "cexpr",
+ "clang-sys",
+ "lazy_static",
+ "lazycell",
+ "peeking_take_while",
+ "proc-macro2",
+ "quote",
+ "regex",
+ "rustc-hash",
+ "shlex",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "bitcoin"
+version = "0.32.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ce6bc65742dea50536e35ad42492b234c27904a27f0abdcbce605015cb4ea026"
+dependencies = [
+ "base58ck",
+ "bech32",
+ "bitcoin-internals",
+ "bitcoin-io",
+ "bitcoin-units",
+ "bitcoin_hashes",
+ "hex-conservative",
+ "hex_lit",
+ "secp256k1",
+ "serde",
+]
+
+[[package]]
+name = "bitcoin-internals"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "30bdbe14aa07b06e6cfeffc529a1f099e5fbe249524f8125358604df99a4bed2"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "bitcoin-io"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "340e09e8399c7bd8912f495af6aa58bea0c9214773417ffaa8f6460f93aaee56"
+
+[[package]]
+name = "bitcoin-test-data"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0c188654f9dce3bc6ce1bfa9c49777ad514bcad37e421b5f53e9d0ee10603f34"
+
+[[package]]
+name = "bitcoin-units"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cb54da0b28892f3c52203a7191534033e051b6f4b52bc15480681b57b7e036f5"
+dependencies = [
+ "bitcoin-internals",
+ "serde",
+]
+
+[[package]]
+name = "bitcoin_hashes"
+version = "0.14.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bb18c03d0db0247e147a21a6faafd5a7eb851c743db062de72018b6b7e8e4d16"
+dependencies = [
+ "bitcoin-io",
+ "hex-conservative",
+ "serde",
+]
+
+[[package]]
+name = "bitcoin_slices"
+version = "0.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0d2eede678354292a3e0c066e1c113f9868c705dfa8f91346d6b6f7c294205b0"
+dependencies = [
+ "bitcoin",
+ "bitcoin_hashes",
+ "sha2",
+]
+
+[[package]]
+name = "bitcoincore-rpc"
+version = "0.19.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "aedd23ae0fd321affb4bbbc36126c6f49a32818dc6b979395d24da8c9d4e80ee"
+dependencies = [
+ "bitcoincore-rpc-json",
+ "jsonrpc",
+ "log",
+ "serde",
+ "serde_json",
+]
+
+[[package]]
+name = "bitcoincore-rpc-json"
+version = "0.19.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d8909583c5fab98508e80ef73e5592a651c954993dc6b7739963257d19f0e71a"
+dependencies = [
+ "bitcoin",
+ "serde",
+ "serde_json",
+]
+
+[[package]]
+name = "bitflags"
+version = "1.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
+
+[[package]]
+name = "bitflags"
+version = "2.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07"
+
+[[package]]
+name = "block-buffer"
+version = "0.10.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
+dependencies = [
+ "generic-array",
+]
+
+[[package]]
+name = "byteorder"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
+
+[[package]]
+name = "bzip2-sys"
+version = "0.1.11+1.0.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc"
+dependencies = [
+ "cc",
+ "libc",
+ "pkg-config",
+]
+
+[[package]]
+name = "cargo_toml"
+version = "0.15.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1521c5948ab432e084eabee0c9e4e965483f73156eaa0b04fc192e3f61205438"
+dependencies = [
+ "serde",
+ "toml 0.7.1",
+]
+
+[[package]]
+name = "cc"
+version = "1.0.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0"
+dependencies = [
+ "jobserver",
+ "libc",
+]
+
+[[package]]
+name = "cexpr"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766"
+dependencies = [
+ "nom",
+]
+
+[[package]]
+name = "cfg-if"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+
+[[package]]
+name = "chunked_transfer"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6e4de3bc4ea267985becf712dc6d9eed8b04c953b3fcfb339ebc87acd9804901"
+
+[[package]]
+name = "clang-sys"
+version = "1.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c688fc74432808e3eb684cae8830a86be1d66a2bd58e1f248ed0960a590baf6f"
+dependencies = [
+ "glob",
+ "libc",
+ "libloading",
+]
+
+[[package]]
+name = "configure_me"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d03c1fbdead926855bdafee8ddf16cd42efb3c75d8cde8c87f8937b99510b39d"
+dependencies = [
+ "parse_arg",
+ "serde",
+ "serde_derive",
+ "toml 0.5.11",
+]
+
+[[package]]
+name = "configure_me_codegen"
+version = "0.4.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5e56840275667a19b0e8ab80219c81fb0bd924e567366d9f12aa385fb45511ea"
+dependencies = [
+ "cargo_toml",
+ "fmt2io",
+ "serde",
+ "serde_derive",
+ "toml 0.5.11",
+ "unicode-segmentation",
+ "void",
+]
+
+[[package]]
+name = "cpufeatures"
+version = "0.2.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "crossbeam-channel"
+version = "0.5.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "06ba6d68e24814cb8de6bb986db8222d3a027d15872cabc0d18817bc3c0e4471"
+dependencies = [
+ "crossbeam-utils",
+]
+
+[[package]]
+name = "crossbeam-deque"
+version = "0.8.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fca89a0e215bab21874660c67903c5f143333cab1da83d041c7ded6053774751"
+dependencies = [
+ "cfg-if",
+ "crossbeam-epoch",
+ "crossbeam-utils",
+]
+
+[[package]]
+name = "crossbeam-epoch"
+version = "0.9.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2d2fe95351b870527a5d09bf563ed3c97c0cffb87cf1c78a591bf48bb218d9aa"
+dependencies = [
+ "autocfg",
+ "cfg-if",
+ "crossbeam-utils",
+ "memoffset",
+]
+
+[[package]]
+name = "crossbeam-utils"
+version = "0.8.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c3a430a770ebd84726f584a90ee7f020d28db52c6d02138900f22341f866d39c"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "crypto-common"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
+dependencies = [
+ "generic-array",
+ "typenum",
+]
+
+[[package]]
+name = "ctrlc"
+version = "3.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b467862cc8610ca6fc9a1532d7777cee0804e678ab45410897b9396495994a0b"
+dependencies = [
+ "nix",
+ "windows-sys 0.52.0",
+]
+
+[[package]]
+name = "digest"
+version = "0.10.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
+dependencies = [
+ "block-buffer",
+ "crypto-common",
+]
+
+[[package]]
+name = "dirs-next"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1"
+dependencies = [
+ "cfg-if",
+ "dirs-sys-next",
+]
+
+[[package]]
+name = "dirs-sys-next"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d"
+dependencies = [
+ "libc",
+ "redox_users",
+ "winapi",
+]
+
+[[package]]
+name = "either"
+version = "1.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"
+
+[[package]]
+name = "electrs"
+version = "0.10.8"
+dependencies = [
+ "anyhow",
+ "bitcoin",
+ "bitcoin-test-data",
+ "bitcoin_slices",
+ "bitcoincore-rpc",
+ "configure_me",
+ "configure_me_codegen",
+ "crossbeam-channel",
+ "ctrlc",
+ "dirs-next",
+ "electrs-rocksdb",
+ "env_logger",
+ "hex_lit",
+ "log",
+ "parking_lot",
+ "prometheus",
+ "rayon",
+ "serde",
+ "serde_derive",
+ "serde_json",
+ "signal-hook",
+ "tempfile",
+ "tiny_http",
+]
+
+[[package]]
+name = "electrs-librocksdb-sys"
+version = "0.9.0-e3+7.8.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b34c24ce2a4d41fe320cea3a9b703b50efea6c2dd4a6d5b0cdbb6ee81636932f"
+dependencies = [
+ "bindgen",
+ "bzip2-sys",
+ "cc",
+ "glob",
+ "libc",
+ "libz-sys",
+ "zstd-sys",
+]
+
+[[package]]
+name = "electrs-rocksdb"
+version = "0.19.0-e3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1f33e74754aaacc3ff9ace8d3278a7f1be1173104d1960ea18f36386f0feec1e"
+dependencies = [
+ "electrs-librocksdb-sys",
+ "libc",
+]
+
+[[package]]
+name = "env_logger"
+version = "0.10.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580"
+dependencies = [
+ "humantime",
+ "is-terminal",
+ "log",
+ "regex",
+ "termcolor",
+]
+
+[[package]]
+name = "errno"
+version = "0.3.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245"
+dependencies = [
+ "libc",
+ "windows-sys 0.52.0",
+]
+
+[[package]]
+name = "fastrand"
+version = "2.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6"
+
+[[package]]
+name = "fmt2io"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6b6129284da9f7e5296cc22183a63f24300e945e297705dcc0672f7df01d62c8"
+
+[[package]]
+name = "fnv"
+version = "1.0.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
+
+[[package]]
+name = "generic-array"
+version = "0.14.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
+dependencies = [
+ "typenum",
+ "version_check",
+]
+
+[[package]]
+name = "getrandom"
+version = "0.2.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "wasi",
+]
+
+[[package]]
+name = "glob"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
+
+[[package]]
+name = "hashbrown"
+version = "0.12.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
+
+[[package]]
+name = "hermit-abi"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7"
+
+[[package]]
+name = "hex"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
+
+[[package]]
+name = "hex-conservative"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e1aa273bf451e37ed35ced41c71a5e2a4e29064afb104158f2514bcd71c2c986"
+dependencies = [
+ "arrayvec",
+]
+
+[[package]]
+name = "hex_lit"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3011d1213f159867b13cfd6ac92d2cd5f1345762c63be3554e84092d85a50bbd"
+
+[[package]]
+name = "httpdate"
+version = "1.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
+
+[[package]]
+name = "humantime"
+version = "2.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
+
+[[package]]
+name = "indexmap"
+version = "1.9.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
+dependencies = [
+ "autocfg",
+ "hashbrown",
+]
+
+[[package]]
+name = "io-lifetimes"
+version = "1.0.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2"
+dependencies = [
+ "hermit-abi",
+ "libc",
+ "windows-sys 0.48.0",
+]
+
+[[package]]
+name = "is-terminal"
+version = "0.4.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b"
+dependencies = [
+ "hermit-abi",
+ "rustix 0.38.40",
+ "windows-sys 0.48.0",
+]
+
+[[package]]
+name = "itoa"
+version = "1.0.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c"
+
+[[package]]
+name = "jobserver"
+version = "0.1.26"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "jsonrpc"
+version = "0.18.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3662a38d341d77efecb73caf01420cfa5aa63c0253fd7bc05289ef9f6616e1bf"
+dependencies = [
+ "base64",
+ "minreq",
+ "serde",
+ "serde_json",
+]
+
+[[package]]
+name = "lazy_static"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
+
+[[package]]
+name = "lazycell"
+version = "1.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
+
+[[package]]
+name = "libc"
+version = "0.2.162"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "18d287de67fe55fd7e1581fe933d965a5a9477b38e949cfa9f8574ef01506398"
+
+[[package]]
+name = "libloading"
+version = "0.7.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f"
+dependencies = [
+ "cfg-if",
+ "winapi",
+]
+
+[[package]]
+name = "libredox"
+version = "0.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8"
+dependencies = [
+ "bitflags 2.4.1",
+ "libc",
+ "redox_syscall",
+]
+
+[[package]]
+name = "libz-sys"
+version = "1.1.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d97137b25e321a73eef1418d1d5d2eda4d77e12813f8e6dead84bc52c5870a7b"
+dependencies = [
+ "cc",
+ "pkg-config",
+ "vcpkg",
+]
+
+[[package]]
+name = "linux-raw-sys"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4"
+
+[[package]]
+name = "linux-raw-sys"
+version = "0.4.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
+
+[[package]]
+name = "lock_api"
+version = "0.4.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45"
+dependencies = [
+ "autocfg",
+ "scopeguard",
+]
+
+[[package]]
+name = "log"
+version = "0.4.22"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
+
+[[package]]
+name = "memchr"
+version = "2.6.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167"
+
+[[package]]
+name = "memoffset"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
+name = "minimal-lexical"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
+
+[[package]]
+name = "minreq"
+version = "2.11.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6fdef521c74c2884a4f3570bcdb6d2a77b3c533feb6b27ac2ae72673cc221c64"
+dependencies = [
+ "log",
+ "serde",
+ "serde_json",
+]
+
+[[package]]
+name = "nix"
+version = "0.27.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053"
+dependencies = [
+ "bitflags 2.4.1",
+ "cfg-if",
+ "libc",
+]
+
+[[package]]
+name = "nom"
+version = "7.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
+dependencies = [
+ "memchr",
+ "minimal-lexical",
+]
+
+[[package]]
+name = "nom8"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ae01545c9c7fc4486ab7debaf2aad7003ac19431791868fb2e8066df97fad2f8"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "once_cell"
+version = "1.19.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
+
+[[package]]
+name = "parking_lot"
+version = "0.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
+dependencies = [
+ "lock_api",
+ "parking_lot_core",
+]
+
+[[package]]
+name = "parking_lot_core"
+version = "0.9.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "redox_syscall",
+ "smallvec",
+ "windows-targets 0.48.5",
+]
+
+[[package]]
+name = "parse_arg"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "14248cc8eced350e20122a291613de29e4fa129ba2731818c4cdbb44fccd3e55"
+
+[[package]]
+name = "peeking_take_while"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
+
+[[package]]
+name = "pkg-config"
+version = "0.3.28"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "69d3587f8a9e599cc7ec2c00e331f71c4e69a5f9a4b8a6efd5b07466b9736f9a"
+
+[[package]]
+name = "ppv-lite86"
+version = "0.2.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.71"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "75cb1540fadbd5b8fbccc4dddad2734eba435053f725621c070711a14bb5f4b8"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "procfs"
+version = "0.14.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b1de8dacb0873f77e6aefc6d71e044761fcc68060290f5b1089fcdf84626bb69"
+dependencies = [
+ "bitflags 1.3.2",
+ "byteorder",
+ "hex",
+ "lazy_static",
+ "rustix 0.36.17",
+]
+
+[[package]]
+name = "prometheus"
+version = "0.13.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "449811d15fbdf5ceb5c1144416066429cf82316e2ec8ce0c1f6f8a02e7bbcf8c"
+dependencies = [
+ "cfg-if",
+ "fnv",
+ "lazy_static",
+ "libc",
+ "memchr",
+ "parking_lot",
+ "procfs",
+ "protobuf",
+ "thiserror",
+]
+
+[[package]]
+name = "protobuf"
+version = "2.28.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "106dd99e98437432fed6519dedecfade6a06a73bb7b2a1e019fdd2bee5778d94"
+
+[[package]]
+name = "quote"
+version = "1.0.33"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "rand"
+version = "0.8.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
+dependencies = [
+ "libc",
+ "rand_chacha",
+ "rand_core",
+]
+
+[[package]]
+name = "rand_chacha"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
+dependencies = [
+ "ppv-lite86",
+ "rand_core",
+]
+
+[[package]]
+name = "rand_core"
+version = "0.6.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
+dependencies = [
+ "getrandom",
+]
+
+[[package]]
+name = "rayon"
+version = "1.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa"
+dependencies = [
+ "either",
+ "rayon-core",
+]
+
+[[package]]
+name = "rayon-core"
+version = "1.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2"
+dependencies = [
+ "crossbeam-deque",
+ "crossbeam-utils",
+]
+
+[[package]]
+name = "redox_syscall"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa"
+dependencies = [
+ "bitflags 1.3.2",
+]
+
+[[package]]
+name = "redox_users"
+version = "0.4.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4"
+dependencies = [
+ "getrandom",
+ "libredox",
+ "thiserror",
+]
+
+[[package]]
+name = "regex"
+version = "1.9.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ebee201405406dbf528b8b672104ae6d6d63e6d118cb10e4d51abbc7b58044ff"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-automata",
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-automata"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "59b23e92ee4318893fa3fe3e6fb365258efbfe6ac6ab30f090cdcbb7aa37efa9"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-syntax"
+version = "0.7.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da"
+
+[[package]]
+name = "rustc-hash"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
+
+[[package]]
+name = "rustix"
+version = "0.36.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "305efbd14fde4139eb501df5f136994bb520b033fa9fbdce287507dc23b8c7ed"
+dependencies = [
+ "bitflags 1.3.2",
+ "errno",
+ "io-lifetimes",
+ "libc",
+ "linux-raw-sys 0.1.4",
+ "windows-sys 0.45.0",
+]
+
+[[package]]
+name = "rustix"
+version = "0.38.40"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "99e4ea3e1cdc4b559b8e5650f9c8e5998e3e5c1343b4eaf034565f32318d63c0"
+dependencies = [
+ "bitflags 2.4.1",
+ "errno",
+ "libc",
+ "linux-raw-sys 0.4.14",
+ "windows-sys 0.52.0",
+]
+
+[[package]]
+name = "ryu"
+version = "1.0.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c"
+
+[[package]]
+name = "scopeguard"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
+
+[[package]]
+name = "secp256k1"
+version = "0.29.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0e0cc0f1cf93f4969faf3ea1c7d8a9faed25918d96affa959720823dfe86d4f3"
+dependencies = [
+ "bitcoin_hashes",
+ "rand",
+ "secp256k1-sys",
+ "serde",
+]
+
+[[package]]
+name = "secp256k1-sys"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1433bd67156263443f14d603720b082dd3121779323fce20cba2aa07b874bc1b"
+dependencies = [
+ "cc",
+]
+
+[[package]]
+name = "serde"
+version = "1.0.171"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "30e27d1e4fd7659406c492fd6cfaf2066ba8773de45ca75e855590f856dc34a9"
+dependencies = [
+ "serde_derive",
+]
+
+[[package]]
+name = "serde_derive"
+version = "1.0.171"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "389894603bd18c46fa56231694f8d827779c0951a667087194cf9de94ed24682"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.42",
+]
+
+[[package]]
+name = "serde_json"
+version = "1.0.109"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cb0652c533506ad7a2e353cce269330d6afd8bdfb6d75e0ace5b35aacbd7b9e9"
+dependencies = [
+ "itoa",
+ "ryu",
+ "serde",
+]
+
+[[package]]
+name = "serde_spanned"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0efd8caf556a6cebd3b285caf480045fcc1ac04f6bd786b09a6f11af30c4fcf4"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "sha2"
+version = "0.10.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8"
+dependencies = [
+ "cfg-if",
+ "cpufeatures",
+ "digest",
+]
+
+[[package]]
+name = "shlex"
+version = "1.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
+
+[[package]]
+name = "signal-hook"
+version = "0.3.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801"
+dependencies = [
+ "libc",
+ "signal-hook-registry",
+]
+
+[[package]]
+name = "signal-hook-registry"
+version = "1.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "smallvec"
+version = "1.13.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7"
+
+[[package]]
+name = "syn"
+version = "1.0.109"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "syn"
+version = "2.0.42"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5b7d0a2c048d661a1a59fcd7355baa232f7ed34e0ee4df2eef3c1c1c0d3852d8"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "tempfile"
+version = "3.14.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c"
+dependencies = [
+ "cfg-if",
+ "fastrand",
+ "once_cell",
+ "rustix 0.38.40",
+ "windows-sys 0.59.0",
+]
+
+[[package]]
+name = "termcolor"
+version = "1.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755"
+dependencies = [
+ "winapi-util",
+]
+
+[[package]]
+name = "thiserror"
+version = "1.0.55"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6e3de26b0965292219b4287ff031fcba86837900fe9cd2b34ea8ad893c0953d2"
+dependencies = [
+ "thiserror-impl",
+]
+
+[[package]]
+name = "thiserror-impl"
+version = "1.0.55"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "268026685b2be38d7103e9e507c938a1fcb3d7e6eb15e87870b617bf37b6d581"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.42",
+]
+
+[[package]]
+name = "tiny_http"
+version = "0.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "389915df6413a2e74fb181895f933386023c71110878cd0825588928e64cdc82"
+dependencies = [
+ "ascii",
+ "chunked_transfer",
+ "httpdate",
+ "log",
+]
+
+[[package]]
+name = "toml"
+version = "0.5.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "toml"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "772c1426ab886e7362aedf4abc9c0d1348a979517efedfc25862944d10137af0"
+dependencies = [
+ "serde",
+ "serde_spanned",
+ "toml_datetime",
+ "toml_edit",
+]
+
+[[package]]
+name = "toml_datetime"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3ab8ed2edee10b50132aed5f331333428b011c99402b5a534154ed15746f9622"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "toml_edit"
+version = "0.19.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "90a238ee2e6ede22fb95350acc78e21dc40da00bb66c0334bde83de4ed89424e"
+dependencies = [
+ "indexmap",
+ "nom8",
+ "serde",
+ "serde_spanned",
+ "toml_datetime",
+]
+
+[[package]]
+name = "typenum"
+version = "1.17.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
+
+[[package]]
+name = "unicode-segmentation"
+version = "1.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36"
+
+[[package]]
+name = "vcpkg"
+version = "0.2.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
+
+[[package]]
+name = "version_check"
+version = "0.9.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
+
+[[package]]
+name = "void"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
+
+[[package]]
+name = "wasi"
+version = "0.11.0+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
+
+[[package]]
+name = "winapi"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
+dependencies = [
+ "winapi-i686-pc-windows-gnu",
+ "winapi-x86_64-pc-windows-gnu",
+]
+
+[[package]]
+name = "winapi-i686-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
+
+[[package]]
+name = "winapi-util"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596"
+dependencies = [
+ "winapi",
+]
+
+[[package]]
+name = "winapi-x86_64-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
+
+[[package]]
+name = "windows-sys"
+version = "0.45.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
+dependencies = [
+ "windows-targets 0.42.2",
+]
+
+[[package]]
+name = "windows-sys"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
+dependencies = [
+ "windows-targets 0.48.5",
+]
+
+[[package]]
+name = "windows-sys"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
+dependencies = [
+ "windows-targets 0.52.6",
+]
+
+[[package]]
+name = "windows-sys"
+version = "0.59.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
+dependencies = [
+ "windows-targets 0.52.6",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071"
+dependencies = [
+ "windows_aarch64_gnullvm 0.42.2",
+ "windows_aarch64_msvc 0.42.2",
+ "windows_i686_gnu 0.42.2",
+ "windows_i686_msvc 0.42.2",
+ "windows_x86_64_gnu 0.42.2",
+ "windows_x86_64_gnullvm 0.42.2",
+ "windows_x86_64_msvc 0.42.2",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
+dependencies = [
+ "windows_aarch64_gnullvm 0.48.5",
+ "windows_aarch64_msvc 0.48.5",
+ "windows_i686_gnu 0.48.5",
+ "windows_i686_msvc 0.48.5",
+ "windows_x86_64_gnu 0.48.5",
+ "windows_x86_64_gnullvm 0.48.5",
+ "windows_x86_64_msvc 0.48.5",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
+dependencies = [
+ "windows_aarch64_gnullvm 0.52.6",
+ "windows_aarch64_msvc 0.52.6",
+ "windows_i686_gnu 0.52.6",
+ "windows_i686_gnullvm",
+ "windows_i686_msvc 0.52.6",
+ "windows_x86_64_gnu 0.52.6",
+ "windows_x86_64_gnullvm 0.52.6",
+ "windows_x86_64_msvc 0.52.6",
+]
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
+
+[[package]]
+name = "windows_i686_gnullvm"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
+
+[[package]]
+name = "zstd-sys"
+version = "2.0.8+zstd.1.5.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5556e6ee25d32df2586c098bbfa278803692a20d0ab9565e049480d52707ec8c"
+dependencies = [
+ "cc",
+ "libc",
+ "pkg-config",
+]
diff --git a/Cargo.toml b/Cargo.toml
new file mode 100644
index 0000000..ea621b8
--- /dev/null
+++ b/Cargo.toml
@@ -0,0 +1,65 @@
+[package]
+name = "electrs"
+version = "0.10.8"
+authors = ["Roman Zeyde <me@romanzey.de>"]
+description = "An efficient re-implementation of Electrum Server in Rust"
+license = "MIT"
+homepage = "https://github.com/romanz/electrs"
+repository = "https://github.com/romanz/electrs"
+keywords = ["bitcoin", "electrum", "server", "index", "database"]
+documentation = "https://docs.rs/electrs/"
+readme = "README.md"
+edition = "2021"
+rust-version = "1.63.0"
+build = "build.rs"
+
+[features]
+default = ["metrics"]
+metrics = ["prometheus", "tiny_http"]
+metrics_process = ["prometheus/process"]
+
+[package.metadata.configure_me]
+spec = "internal/config_specification.toml"
+
+[dependencies]
+anyhow = "1.0"
+bitcoin = { version = "0.32.5", features = ["serde", "rand-std"] }
+bitcoin_slices = { version = "0.9", features = ["bitcoin", "sha2"] }
+bitcoincore-rpc = { version = "0.19.0" }
+configure_me = "0.4"
+crossbeam-channel = "0.5"
+dirs-next = "2.0"
+env_logger = "0.10"
+log = "0.4"
+parking_lot = "0.12"
+prometheus = { version = "0.13", optional = true }
+rayon = "1.9"
+serde = "1.0"
+serde_derive = "1.0, <=1.0.171" # avoid precompiled binaries (https://github.com/serde-rs/serde/issues/2538)
+serde_json = "1.0"
+tiny_http = { version = "0.12", optional = true }
+
+[target.'cfg(windows)'.dependencies]
+ctrlc = "=3.4.2"
+
+[target.'cfg(not(windows))'.dependencies]
+signal-hook = "0.3"
+
+[dependencies.electrs-rocksdb]
+version = "0.19.0-e3"
+
+default-features = false
+# ZSTD is used for data compression
+# Snappy is only for checking old DB
+features = ["zstd", "snappy"]
+
+[build-dependencies]
+configure_me_codegen = { version = "0.4.8", default-features = false }
+
+[dev-dependencies]
+bitcoin-test-data = "0.2.0"
+hex_lit = "0.1.1"
+tempfile = "3.14"
+
+[profile.release]
+lto = true
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..c8ec506
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,24 @@
+# Important: This file is provided for demonstration purposes and may NOT be suitable for production use.
+# The maintainers of electrs are not deeply familiar with Docker, so you should DYOR.
+# If you are not familiar with Docker either it's probably be safer to NOT use it.
+
+FROM debian:bookworm-slim AS base
+RUN apt-get update -qqy
+RUN apt-get install -qqy librocksdb-dev curl
+
+### Electrum Rust Server ###
+FROM base AS electrs-build
+RUN apt-get install -qqy cargo clang cmake
+
+# Install electrs
+WORKDIR /build/electrs
+COPY . .
+ENV ROCKSDB_INCLUDE_DIR=/usr/include
+ENV ROCKSDB_LIB_DIR=/usr/lib
+RUN cargo install --locked --path .
+
+FROM base AS result
+# Copy the binaries
+COPY --from=electrs-build /root/.cargo/bin/electrs /usr/bin/electrs
+
+WORKDIR /
diff --git a/Dockerfile.ci b/Dockerfile.ci
new file mode 100644
index 0000000..18806c7
--- /dev/null
+++ b/Dockerfile.ci
@@ -0,0 +1,47 @@
+# Important: This file is provided for demonstration purposes and may NOT be suitable for production use.
+# The maintainers of electrs are not deeply familiar with Docker, so you should DYOR.
+# If you are not familiar with Docker either it's probably be safer to NOT use it.
+
+FROM debian:bookworm-slim as base
+RUN apt-get update -qqy
+RUN apt-get install -qqy librocksdb-dev wget
+
+### Electrum Rust Server ###
+FROM base as electrs-build
+RUN apt-get install -qqy cargo clang cmake
+
+# Install electrs
+WORKDIR /build/electrs
+COPY . .
+ENV ROCKSDB_INCLUDE_DIR=/usr/include
+ENV ROCKSDB_LIB_DIR=/usr/lib
+RUN cargo install --locked --path .
+
+### Bitcoin Core ###
+FROM base as bitcoin-build
+# Download
+WORKDIR /build/bitcoin
+ARG ARCH=x86_64
+ARG BITCOIND_VERSION=28.0
+RUN wget -q https://bitcoincore.org/bin/bitcoin-core-$BITCOIND_VERSION/bitcoin-$BITCOIND_VERSION-$ARCH-linux-gnu.tar.gz
+RUN tar xvf bitcoin-$BITCOIND_VERSION-$ARCH-linux-gnu.tar.gz
+RUN mv -v bitcoin-$BITCOIND_VERSION/bin/bitcoind .
+RUN mv -v bitcoin-$BITCOIND_VERSION/bin/bitcoin-cli .
+
+FROM base as result
+# Copy the binaries
+COPY --from=electrs-build /root/.cargo/bin/electrs /usr/bin/electrs
+COPY --from=bitcoin-build /build/bitcoin/bitcoind /build/bitcoin/bitcoin-cli /usr/bin/
+RUN bitcoind -version && bitcoin-cli -version
+
+### Electrum ###
+# Clone latest Electrum wallet and a few test tools
+WORKDIR /build/
+RUN apt-get install -qqy git libsecp256k1-1 python3-cryptography python3-setuptools python3-venv python3-pip jq curl
+RUN git clone --recurse-submodules https://github.com/spesmilo/electrum/ && cd electrum/ && git log -1
+RUN python3 -m venv --system-site-packages venv && \
+ ELECTRUM_ECC_DONT_COMPILE=1 venv/bin/pip install -e electrum/ && \
+ ln /build/venv/bin/electrum /usr/bin/electrum
+
+RUN electrum version --offline
+WORKDIR /
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..e0333ae
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,19 @@
+Copyright (C) 2018, Roman Zeyde.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..14d8e7d
--- /dev/null
+++ b/README.md
@@ -0,0 +1,72 @@
+
+
+# Electrum Server in Rust
+
+[](https://github.com/romanz/electrs/actions)
+[](http://makeapullrequest.com)
+[](https://crates.io/crates/electrs)
+[](https://gitter.im/romanz/electrs)
+
+An efficient re-implementation of Electrum Server, inspired by [ElectrumX](https://github.com/kyuupichan/electrumx), [Electrum Personal Server](https://github.com/chris-belcher/electrum-personal-server) and [bitcoincore-indexd](https://github.com/jonasschnelli/bitcoincore-indexd).
+
+The motivation behind this project is to enable a user to self host an Electrum server,
+with required hardware resources not much beyond those of a [full node](https://en.bitcoin.it/wiki/Full_node#Why_should_you_use_a_full_node_wallet).
+The server indexes the entire Bitcoin blockchain, and the resulting index enables fast queries for any given user wallet,
+allowing the user to keep real-time track of balances and transaction history using the [Electrum wallet](https://electrum.org/).
+Since it runs on the user's own machine, there is no need for the wallet to communicate with external Electrum servers,
+thus preserving the privacy of the user's addresses and balances.
+
+[BTC Prague 2024 dev/hack/day](https://btcprague.com/dev-hack-day/) slides are here: https://bit.ly/electrs
+
+
+## Usage
+
+**Please prefer to use OUR usage guide!**
+
+External guides can be out-of-date and have various problems.
+At least double-check that the guide you're using is actively maintained.
+If you can't use our guide, please ask about what you don't understand or consider using automated deployments.
+
+Note that this implementation of Electrum server is optimized for **personal/small-scale (family/friends) usage**.
+It's a bad idea to run it publicly as it'd expose you to DoS and maybe also other attacks.
+If you want to run a public server you may be interested in the [Blockstream fork of electrs](https://github.com/Blockstream/electrs)
+which is better optimized for public usage at the cost of consuming *significantly* more resources.
+
+ * [Installation from source](doc/install.md)
+ * [Pre-built binaries](doc/binaries.md) (No official binaries available but a beta repository is available for installation)
+ * [Configuration](doc/config.md)
+ * [Usage](doc/usage.md)
+ * [Monitoring](doc/monitoring.md)
+ * [Upgrading](doc/upgrading.md) - **contains information about important changes from older versions**
+
+## Features
+
+ * Supports Electrum protocol [v1.4](https://electrumx-spesmilo.readthedocs.io/en/latest/protocol.html)
+ * Maintains an index over transaction inputs and outputs, allowing fast balance queries
+ * Fast synchronization of the Bitcoin blockchain (~6.5 hours for ~504GB @ August 2023) using HDD storage.
+ * Low index storage overhead (~10%), relying on a local full node for transaction retrieval
+ * Efficient mempool tracker (allowing better fee [estimation](https://github.com/spesmilo/electrum/blob/59c1d03f018026ac301c4e74facfc64da8ae4708/RELEASE-NOTES#L34-L46))
+ * Low CPU & memory usage (after initial indexing)
+ * [`txindex`](https://github.com/bitcoinbook/bitcoinbook/blob/develop/ch03.asciidoc#txindex) is not required for the Bitcoin node
+ * Uses a single [RocksDB](https://github.com/spacejam/rust-rocksdb) database, for better consistency and crash recovery
+
+## Altcoins
+
+Altcoins are **not supported**!
+Forks of Bitcoin codebase that relax the consensus rules (hard forks) are also **not supported**.
+
+You may be able to find a fork of electrs that does support them, look around or make your own, just don't file issues/PRs here.
+
+## Index database
+
+The database schema is described [here](doc/schema.md).
+
+## Contributing
+
+All contributions to this project are welcome. Please refer to the [Contributing Guidelines](CONTRIBUTING.md) for more details.
+
+## Logo
+
+[Our logo](logo/) is generously provided by [Dominik Průša](https://github.com/DominoPrusa) under the MIT license.
+Based on the [Electrum logo](https://github.com/spesmilo/electrum/blob/master/LICENCE)
+and the [Rust language logo](https://www.rust-lang.org/policies/media-guide).
diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md
new file mode 100644
index 0000000..25f77c7
--- /dev/null
+++ b/RELEASE-NOTES.md
@@ -0,0 +1,406 @@
+# 0.10.8 (Dec 30 2024)
+
+* Separate blocks reading & index writing into scoped threads
+* Set HTTP `Content-Type` header for Prometheus response
+* Use `ctrlc` in place of `signal-hook` on Windows
+* Don't deserialize transactions if not needed
+* Run CI only on `master` branch and PRs
+* Update dependencies (`bitcoin`, `bitcoin_slices`, `crossbeam-channel`, `tempfile`)
+
+
+# 0.10.7 (Nov 05 2024)
+
+* Support testnet4
+* Enable LTO in release build
+* Don't sync mempool when bitcoind mempool is not yet loaded
+* Update dependencies (`bitcoin`, `bitcoin_slices`)
+
+# 0.10.6 (Sep 29 2024)
+
+* Update dependencies (`bitcoin`, `configure_me_codegen`, `crossbeam-channel`, `log`)
+* Deprecate unused config option `timestamp`
+* Don't fail if bitcoind fee estimation is disabled
+* Save on allocations by using fixed size types for database rows
+* Add BTC Prague 2024 dev/hack/day slides
+
+# 0.10.5 (May 18 2024)
+
+* Update dependencies (`bitcoin`, `bitcoin_slices`, `bitcoincore-rpc`, `rayon`)
+* Support latest bitcoind (https://github.com/rust-bitcoin/rust-bitcoincore-rpc/pull/353 & https://github.com/rust-bitcoin/rust-bitcoincore-rpc/pull/356)
+
+# 0.10.4 (Mar 15 2024)
+
+* Don't fail mempool sync on missing transactions (#997)
+* Update dependencies (`anyhow`, `crossbeam-channel`, `log`, `secp256k1`, `secp256k1-sys`, `smallvec`, `tempfile`, `termcolor`, `thiserror`, `thiserror-impl`)
+
+# 0.10.3 (Feb 10 2024)
+
+* Update dependencies (`serde_json`, `tempfile`, `env_logger`, `rayon`, `bitcoin`, `crossbeam-channel`, `shlex`)
+* Fix build on Debian 12 (#1001)
+
+# 0.10.2 (Dec 31 2023)
+
+* Use batched RPC to fetch mempool entries & transactions (#979)
+* Avoid redundant recomputation of fee histogram bins (#971)
+* Explain behavior of config file loading (#964)
+* Don't flush when nothing is written to DB (#958)
+* Allow setting RocksDB log directory (#959)
+* Upgrade `bitcoin` to 0.31.0 (#941)
+* Update dependencies (#953, #951, #980)
+
+# 0.10.1 (Nov 01 2023)
+
+* Fix build failure on Raspberry Pi 4 (32bit) (#940)
+* Return first txid-matching transaction (#933)
+* Add txid collision scanner (#928)
+* Optimize indexing via `bitcoin_slices` (#927)
+* Optimize index querying via `bitcoin_slices` (#913)
+* Avoid precompiled 'serde_derive' >=1.0.172 (#924)
+* Allow exiting mempool sync on SIGINT (#917)
+* Allow skipping merkle proof downloads in `history.py` (#915)
+* Remove IndexResult and index into db::WriteBatch (#914)
+* Dockerfile: re-add curl for the second time, so it can be used for docker health checks (#912)
+* Reuse buffer in p2p handling (#910)
+* Preallocate serialized vector of HashPrefixRow (#909)
+* Less verbose logging when bitcoind is warming up (#908)
+* Drop Cirrus CI due to flakiness (#948)
+* Update dependencies (`anyhow`, `bitcoin`, `electrs-rocksdb`, `rayon`, `rustix`, `serde`, `serde_derive`, `serde_json`, `signal-hook`, `syn`, `tempfile`)
+
+
+# 0.10.0 (Jul 22 2023)
+
+* Add ARM build and integration tests in Cirrus CI
+
+# 0.10.0-rc.1 (Jun 21 2023)
+
+* Bump MSRV to 1.63.0 and update Rust edition to 2021 (#773)
+* Update dependencies (`anyhow`, `configure_me_codegen`, `electrs-rocksdb`, `env_logger`, `parking_lot`, `prometheus`, `rayon`, `serde`, `serde_derive`, `serde_json`)
+ - Please note that [dynamic linking with RocksDB](doc/install.md) now requires [RocksDB 7.8.3](https://packages.debian.org/bookworm/librocksdb-dev) (instead of 6.11.4)!
+
+# 0.9.14 (Jun 10 2023)
+
+* Fix 'server.version' support for version range (#887)
+* Allow not waiting for block download before sync (#888)
+* Fix typo in config_specification.toml (#883)
+* Bump bitcoind version used in CI (#882)
+* Prefix Prometheus metrics with 'electrs_' (#881)
+* Fixup error handling in Prometheus HTTP server (#880)
+* Add address->scripthash conversion tool
+* Update dependencies (crossbeam-channel, jsonrpc, bitcoincore-rpc, serde_json, tempfile)
+
+# 0.9.13 (Mar 31 2023)
+
+* Upgrade dependencies (`bitcoin` & `bitcoincore-rpc` #865, `crossbeam-channel` #854, `serde_json` #855, `tempfile` #850)
+* Don't panic on unexpected magic (#861)
+* contrib: rename xpub into get_balance (#627)
+
+# 0.9.12 (Feb 25 2023)
+
+* Update dependencies (`serde_json`, `signal-hook`, `electrs-bitcoincore-rpc`, `electrs-rocksdb`)
+* Add `CONTRIBUTING.md` (#838)
+* Add `blockchain.transaction.id_from_pos` RPC (#836)
+* Add `blockchain.scripthash.unsubscribe` RPC (#833)
+* Support IPv6 connections (#792)
+
+# 0.9.11 (Jan 5 2023)
+
+* Update dependencies (`secp256k1`, `serde_json`, `configure_me_codegen`, `env_logger`, `electrs-rocksdb`)
+* Improve error logging in case of p2p error (#807)
+
+# 0.9.10 (Nov 3 2022)
+
+* Update dependencies (`bitcoin`, `bitcoincore-rpc`, `tiny_http`, `serde_json`, `env_logger`)
+* Fix mempool fee rate formatting (#761)
+* Allow configuring signet p2p magic (#762, #768)
+* Don't panic in case of an invalid block header height (#786)
+
+# 0.9.9 (Jul 12 2022)
+
+* Update dependencies (`anyhow`, `crossbeam-channel`, `crossbeam-utils`, `regex`, `serde`, `serde from `, `serde_json`, `signal-hook`)
+* Don't log scripthash (#737)
+
+# 0.9.8 (Jun 3 2022)
+
+* Update dependencies (`serde_json`, `serde`, `bitcoin`, `bitcoincore-rpc`, `rayon`, `log`)
+* Support new Electrum release `getbalance` response format (#717)
+
+# 0.9.7 (Apr 30 2022)
+
+* Add build matrix to test all features in CI (#706)
+* Install and run cargo-bloat in CI (#705)
+* Add guide for other Ubuntu & Debian releases to compile and install librocksdb (#696)
+* Update dependencies (`anyhow`, `log`, `crossbeam-channel`, `rayon`)
+
+# 0.9.6 (Mar 4 2022)
+
+* Allow skipping default config files (#686)
+* Update dependencies (`anyhow`, `serde-json`)
+
+# 0.9.5 (Feb 4 2022)
+
+* Update dependencies (`serde-json`, `serde`, `tempfile`, `crossbeam-channel`)
+* Fix `txid` index collision handling (#653)
+* Use `bitcoincore_rpc`'s `getblockchaininfo` implementation (#656)
+
+# 0.9.4 (Dec 30 2021)
+
+* Update dependencies (`anyhow`, `serde`, `serde_json`, `signal-hook`)
+* Improve p2p receiving metrics (#633)
+* Warn on attempt to connect over SSL (#634)
+* Disable `index_lookup_limit` by default (#635)
+* Parse p2p messages in a separate thread (#638)
+* Add server loop-related metrics
+
+# 0.9.3 (Nov 20 2021)
+
+* Support basic RPC handling during initial sync (#543)
+* Update MSRV requirements to Rust 1.48 (#603)
+* Bump `env_logger` to 0.9 (#604)
+* Monitor RocksDB statistics via Prometheus (#605)
+* Don't warn when queried with unsubscribed scripthashes (#609)
+* Allow skipping merkle proofs' during subscription (#610)
+* Remove `verbose` configuration (#615)
+* Add `curl` to `Dockerfile` (#624)
+
+# 0.9.2 (Oct 31 2021)
+
+* Add a feature to ignore default config files (#396)
+* Support Rust 1.48.0 and test on Debian 11 (#455)
+* Allow multiple scripthashes' subscription in parallel(#464)
+* Ignore `cargo audit` warning in `tiny_http` (#575)
+* Re-organize and split documentation (#583)
+* Use `/electrs:$VERSION/` in p2p 'user-agent' (#585)
+* Build rocksdb with conditional SSE support (#595)
+* Ignore 'addr' p2p messages (#596)
+
+# 0.9.1 (Oct 19 2021)
+
+* Initialize chain height metric (#515)
+* Don't shutdown write-side before all responses are sent back (#523)
+* Use p2p protocol to replace waitfornewblock hidden RPC (#526)
+* Use correct Prometheus buckets for size and duration (#528)
+* Don't ignore signals during IBD (#533)
+* Expose index DB size as a Prometheus gauge metric (#544)
+* Add p2p protocol monitoring (#546)
+* Fix contrib/xpub.py support for ypub/zpub keys (#549)
+* Rewrite and simplify p2p message receiving thread (#550)
+* Re-introduce mempool vsize and txs' count metrics (#557, #562, #563)
+* Allow RPC connection before initial sync is over (#558)
+
+# 0.9.0 (Sep 30 2021)
+
+**IMPORTANT: This release contains major changes, please read carefully!**
+
+The four main things to watch out for:
+
+* Database schema changed - this will cause **reindex after upgrade**.
+* `mainnet` subdirectory was renamed to `bitcoin`, you should delete `mainnet` after successful reindex.
+* We now use **bitcoin p2p protocol** to fetch blocks - some configurations may not work.
+* Trace log level now logs much more information - make sure it's not used in production.
+
+See [upgrading](doc/upgrading.md) section of our docs to learn more.
+
+Full list of changes:
+
+* Add electrs logo (#510)
+
+## 0.9.0-rc2 (Sep 23 2021)
+
+* Prevent panic during logging of p2p messages (#490)
+* Don't collect process' Prometheus metrics by default (#492)
+* Support initial sync resume (#494)
+
+## 0.9.0-rc1 (Sep 17 2021)
+
+* Fix incorrect ordering of same-block transactions (#297)
+* Change DB index format and use Zstd compression (instead of Snappy)
+* The database will be reindexed automatically when it encounters old version (#477)
+* Don't use bitcoind JSON RPC for fetching blocks (#373)
+* Use p2p protocol for headers and block fetching only.
+ This is safer than reading `blk*dat` files and faster than JSON RPC.
+* Support Electrum JSON RPC batching and errors
+* Use `rust-bitcoincore-rpc` crate
+* Increase default `index_lookup_limit` to 200
+* Implement 'blockchain.scripthash.listunspent' RPC (#475)
+* Update RocksDB to 6.11.4 (#473)
+* Allow logging configuration via `RUST_LOG` environment variable (using `env_logger`)
+
+# 0.8.12 (14 Sep 2021)
+
+* Fail if `cookie` is specified (#478)
+* Move usage in README up and recommend our guide (#463)
+* A bunch of improvements to issue templates (#462)
+
+# 0.8.11 (18 Aug 2021)
+
+* Update dependencies (#401, #402)
+* Add python example in RPC examples (#415, #417)
+* Add regtest and signet networks in examples (#425)
+* Clippy fixes (#430)
+* CI fixes (#437, #438, #441)
+* Update relevant versions (#450)
+* Drop unused compression algorithms for RocksDB
+
+# 0.8.10 (14 May 2021)
+
+* Fix JSONRPC errors' handling (#398, #390)
+* Optimize Dockerfile (#387, #388, #392)
+* Fix signet default port (https://github.com/romanz/electrs/b53178c140e575b0527a70ead566d50c7fe6cb1f)
+
+# 0.8.9 (19 Mar 2021)
+
+* Use non-batched RPC to reduce bitcoind memory usage (#373)
+* Fix inverted logic of deprecation (#379)
+* Ignore individual mempool transaction fetch fails (#381)
+* Increase default wait_duration_secs to 10s (#384)
+
+# 0.8.8 (22 Feb 2021)
+
+* Deprecate `--cookie` configuration (@Kixunil)
+* Update dependencies (@Kixunil)
+* Improve documentation (@Kixunil)
+
+# 0.8.7 (15 Jan 2021)
+
+* Support signet (#239)
+
+# 0.8.6 (25 Nov 2020)
+* [Fix](https://github.com/romanz/electrs/commit/c88a0dc331eb16163276becf98fcc020565d97eb) Electrum fee histogram duplicates
+* [Fix](https://github.com/romanz/electrs/commit/8f2f53303a62321e3ccd1a8dc42b46c63629a03f) Electrum protocol negotiation
+* Update multiple crates (@kixunil): [lru](#333), [prometheus](#334), [dirs-next](#335)
+* Support Rust 1.41.1 (for Debian stable)
+* [Update](https://github.com/romanz/electrs/commit/af6ff09a275ec12b6fd0d6a101637f4710902a3c) bitcoin crate (@dr-orlovsky)
+* [Fix](https://github.com/romanz/electrs/commit/4764dccbbe4cd04a6dc79771a686847d8e6e2edf) a deadlock when shutting down (@kixunil)
+
+# 0.8.5 (1 July 2020)
+
+* Add a 'blocks_dir' option (@darosior)
+* Return fee for unconfirmed transactions history (for Electrum 4.0)
+* Handle SIGUSR1 for external notifications
+
+# 0.8.4 (3 June 2020)
+
+* Update to latest rust-bitcoin (@dr-orlovsky)
+* Fix deadlock and refactor RPC threading (@Kixunil)
+
+# 0.8.3 (30 Jan 2020)
+
+* Fix memory leak (@champo)
+
+# 0.8.2 (6 Dec 2019)
+
+* Downgrade rust-rocksdb to 0.12.2 (https://github.com/romanz/electrs/issues/193)
+
+# 0.8.1 (20 Nov 2019)
+
+* Allow setting `--cookie-file` path via configuration (@Kixunil)
+* Bump rust-rocksdb to 0.13.0, using RockDB 6.2.4
+
+# 0.8.0 (28 Oct 2019)
+
+* Use `configure_me` instead of `clap` to support config files, environment variables and man pages (@Kixunil)
+* Don't accept `--cookie` via CLI arguments (@Kixunil)
+* Define cache size in MB instead of number of elements (@dagurval)
+* Support Rust >=1.34 (for Debian)
+* Bump rust-rocksdb to 0.12.3, using RockDB 6.1.2
+* Bump bitcoin crate to 0.21 (@MichelKansou)
+
+# 0.7.1 (27 July 2019)
+
+* Allow stopping bulk indexing via SIGINT/SIGTERM
+* Cache list of transaction IDs for blocks (@dagurval)
+
+# 0.7.0 (13 June 2019)
+
+* Support Bitcoin Core 0.18
+* Build with LTO
+* Allow building with latest Rust (via feature flag)
+* Use iterators instead of returning vectors (@Kixunil)
+* Use atomics instead of `Mutex<u64>` (@Kixunil)
+* Better handling invalid blocks (@azuchi)
+
+# 0.6.2 (17 May 2019)
+
+* Support Rust 1.32 (for Debian)
+
+# 0.6.1 (9 May 2019)
+
+* Fix crash during initial sync
+* Switch to `signal-hook` crate
+
+# 0.6.0 (29 Apr 2019)
+
+* Update to Rust 1.34
+* Prefix Prometheus metrics with 'electrs_'
+* Update RocksDB crate to 0.12.1
+* Update Bitcoin crate to 0.18
+* Support latest bitcoind mempool entry vsize field name
+* Fix "chain-trimming" reorgs
+* Serve by default on IPv4 localhost
+
+# 0.5.0 (3 Mar 2019)
+
+* Limit query results, to prevent RPC server to get stuck (see `--txid-limit` flag)
+* Update RocksDB crate to 0.11
+* Update Bitcoin crate to 0.17
+
+# 0.4.3 (23 Dec 2018)
+
+* Support Rust 2018 edition (1.31)
+* Upgrade to Electrum protocol 1.4 (from 1.2)
+* Let server banner be configurable via command-line flag
+* Improve query.get_merkle_proof() performance
+
+# 0.4.2 (22 Nov 2018)
+
+* Update to rust-bitcoin 0.15.1
+* Use bounded LRU cache for transaction retrieval
+* Support 'server.ping' and partially 'blockchain.block.header' Electrum RPC
+
+# 0.4.1 (14 Oct 2018)
+
+* Don't run full compaction after initial import is over (when using JSONRPC)
+
+# 0.4.0 (22 Sep 2018)
+
+* Optimize for low-memory systems by using different RocksDB settings
+* Rename `--skip_bulk_import` flag to `--jsonrpc-import`
+
+# 0.3.2 (14 Sep 2018)
+
+* Optimize block headers processing during startup
+* Handle TCP disconnections during long RPCs
+* Use # of CPUs for bulk indexing threads
+* Update rust-bitcoin to 0.14
+* Optimize block headers processing during startup
+
+
+# 0.3.1 (20 Aug 2018)
+
+* Reconnect to bitcoind only on transient errors
+* Poll mempool after transaction broadcasting
+
+# 0.3.0 (14 Aug 2018)
+
+* Optimize for low-memory systems
+* Improve compaction performance
+* Handle disconnections from bitcoind by retrying
+* Make `blk*.dat` ingestion more robust
+* Support regtest network
+* Support more Electrum RPC methods
+* Export more Prometheus metrics (CPU, RAM, file descriptors)
+* Add `scripts/run.sh` for building and running `electrs`
+* Add some Python tools (as API usage examples)
+* Change default Prometheus monitoring ports
+
+# 0.2.0 (14 Jul 2018)
+
+* Allow specifying custom bitcoind data directory
+* Allow specifying JSONRPC cookie from commandline
+* Improve initial bulk indexing performance
+* Support 32-bit systems
+
+# 0.1.0 (2 Jul 2018)
+
+* Announcement: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2018-July/016190.html
+* Published to https://crates.io/electrs and https://docs.rs/electrs
diff --git a/TODO.md b/TODO.md
new file mode 100644
index 0000000..9736158
--- /dev/null
+++ b/TODO.md
@@ -0,0 +1,14 @@
+# Electrum
+
+* Snapshot DB after successful indexing - and run queries on the latest snapshot
+* Update height to -1 for txns with any [unconfirmed input](https://electrumx.readthedocs.io/en/latest/protocol-basics.html#status)
+
+# Rust
+
+* Use [bytes](https://carllerche.github.io/bytes/bytes/index.html) instead of `Vec<u8>` when possible
+* Use generators instead of vectors
+* Use proper HTTP parser for JSONRPC replies over persistent connection
+
+# Performance
+
+* Consider https://github.com/facebook/rocksdb/wiki/RocksDB-Tuning-Guide#difference-of-spinning-disk
diff --git a/build.rs b/build.rs
new file mode 100644
index 0000000..edd1c49
--- /dev/null
+++ b/build.rs
@@ -0,0 +1,3 @@
+fn main() {
+ configure_me_codegen::build_script_auto().unwrap_or_else(|error| error.report_and_exit())
+}
diff --git a/contrib/.gitignore b/contrib/.gitignore
new file mode 100644
index 0000000..1d17dae
--- /dev/null
+++ b/contrib/.gitignore
@@ -0,0 +1 @@
+.venv
diff --git a/contrib/client.py b/contrib/client.py
new file mode 100644
index 0000000..5c561f2
--- /dev/null
+++ b/contrib/client.py
@@ -0,0 +1,27 @@
+import json
+import socket
+
+class Client:
+ def __init__(self, addr):
+ self.s = socket.create_connection(addr)
+ self.f = self.s.makefile('r')
+ self.id = 0
+
+ def call(self, requests):
+ requests = list(requests)
+ for request in requests:
+ request['id'] = self.id
+ request['jsonrpc'] = '2.0'
+ self.id += 1
+
+ msg = json.dumps(requests) + '\n'
+ self.s.sendall(msg.encode('ascii'))
+ response = json.loads(self.f.readline())
+ try:
+ return [r['result'] for r in response]
+ except KeyError:
+ raise ValueError(response)
+
+
+def request(method, *args):
+ return {'method': method, 'params': list(args)}
diff --git a/contrib/daemon.py b/contrib/daemon.py
new file mode 100644
index 0000000..85c7351
--- /dev/null
+++ b/contrib/daemon.py
@@ -0,0 +1,41 @@
+import binascii
+import json
+import os
+import socket
+
+
+class Daemon:
+ def __init__(self, port, cookie_dir):
+ self.sock = socket.create_connection(('localhost', port))
+ self.fd = self.sock.makefile()
+ path = os.path.join(os.path.expanduser(cookie_dir), '.cookie')
+ cookie = binascii.b2a_base64(open(path, 'rb').read())
+ self.cookie = cookie.decode('ascii').strip()
+ self.index = 0
+
+ def request(self, method, params_list):
+ obj = [{"method": method, "params": params, "id": self.index}
+ for params in params_list]
+ request = json.dumps(obj)
+
+ msg = ('POST / HTTP/1.1\n'
+ 'Authorization: Basic {}\n'
+ 'Content-Length: {}\n\n'
+ '{}'.format(self.cookie, len(request), request))
+ self.sock.sendall(msg.encode('ascii'))
+
+ status = self.fd.readline().strip()
+ while True:
+ if self.fd.readline().strip():
+ continue # skip headers
+ else:
+ break # next line will contain the response
+
+ data = self.fd.readline().strip()
+ replies = json.loads(data)
+ for reply in replies:
+ assert reply['error'] is None, reply
+ assert reply['id'] == self.index
+
+ self.index += 1
+ return [d['result'] for d in replies]
diff --git a/contrib/get_balance.py b/contrib/get_balance.py
new file mode 100755
index 0000000..5d26b26
--- /dev/null
+++ b/contrib/get_balance.py
@@ -0,0 +1,134 @@
+#!/usr/bin/env python3
+import argparse
+import base58
+import hashlib
+import sys
+
+from logbook import Logger, StreamHandler
+
+import client
+
+log = Logger("get_balance")
+
+
+prefix_dict = {
+ 'mainnet': {
+ 'xpub': '0488b21e', # P2PKH or P2SH - m/44'/0'
+ 'ypub': '049d7cb2', # P2WPKH in P2SH - m/49'/0'
+ 'zpub': '04b24746', # P2WPKH - m/84'/0'
+ },
+ 'testnet': {
+ 'tpub': '043587cf', # P2PKH or P2SH - m/44'/1'
+ 'upub': '044a5262', # P2WPKH in P2SH - m/49'/1'
+ 'vpub': '045f1cf6', # P2WPKH - m/84'/1'
+ },
+ 'regtest': {
+ },
+}
+
+
+def convert_key(key, target_prefix, network_name):
+ decoded_key_bytes = base58.b58decode_check(key)
+ target_key_bytes = (
+ bytes.fromhex(prefix_dict[network_name][target_prefix]) +
+ decoded_key_bytes[4:])
+ return base58.b58encode_check(target_key_bytes).decode('ascii')
+
+
+def compute_xpub_balance(xpub, conn, network, details):
+ total = 0
+ for change in (0, 1):
+ empty = 0
+ for n in range(1000):
+ address = xpub.subkey(change).subkey(n).address()
+ script = network.parse.address(address).script()
+ script_hash = hashlib.sha256(script).digest()[::-1].hex()
+ # conn.call([client.request('blockchain.scripthash.subscribe',
+ # script_hash)])
+ result, = conn.call(
+ [client.request('blockchain.scripthash.get_history',
+ script_hash)])
+ ntx = len(result)
+ if len(result):
+ log.debug(result)
+ result, = conn.call(
+ [client.request('blockchain.scripthash.get_balance',
+ script_hash)])
+ confirmed = result['confirmed'] / 1e8
+ total += confirmed
+
+ log.debug(
+ '{}/{}: {} -> {} BTC confirmed, {} BTC unconfirmed, '
+ '{} txs balance = {} BTC', change, n, address,
+ result["confirmed"] / 1e8, result["unconfirmed"] / 1e8, ntx,
+ total)
+
+ if confirmed or ntx:
+ empty = 0
+ if confirmed > 0:
+ details[address] = confirmed
+ else:
+ empty += 1
+ if empty >= 10:
+ break
+ return total
+
+
+def compute_address_balance(address, conn, network):
+ script = network.parse.address(address).script()
+ script_hash = hashlib.sha256(script).digest()[::-1].hex()
+ result, = conn.call(
+ [client.request('blockchain.scripthash.get_balance',
+ script_hash)])
+ return result['confirmed'] / 1e8
+
+
+def main():
+ parser = argparse.ArgumentParser()
+ parser.add_argument('--host', default='localhost')
+ parser.add_argument('--network', default='mainnet',
+ choices=['mainnet', 'testnet', 'regtest'])
+ parser.add_argument('address')
+ args = parser.parse_args()
+
+ if args.network == 'regtest':
+ port = 60401
+ from pycoin.symbols.xrt import network
+ elif args.network == 'testnet':
+ port = 60001
+ from pycoin.symbols.xtn import network
+ elif args.network == 'mainnet':
+ port = 50001
+ from pycoin.symbols.btc import network
+ else:
+ raise ValueError(f"unknown network: {args.network}")
+
+ conn = client.Client((args.host, port))
+ total = 0
+ xpub = (network.parse.bip32(args.address) or
+ network.parse.bip49(args.address) or
+ network.parse.bip84(args.address))
+
+ if xpub is None:
+ total = compute_address_balance(args.address, conn, network)
+ else:
+ details = {}
+ total = compute_xpub_balance(xpub, conn, network, details)
+
+ for prefix in prefix_dict[args.network]:
+ if args.address[:4] != prefix:
+ key = convert_key(args.address, prefix, args.network)
+ log.debug('Trying with {}', key)
+ xpub = (network.parse.bip32(key) or network.parse.bip49(key)
+ or network.parse.bip84(key))
+ total += compute_xpub_balance(xpub, conn, network, details)
+
+ for addr in details:
+ log.info('{} balance: {} BTC', addr, details[addr])
+
+ log.info('total balance: {} BTC', total)
+
+
+if __name__ == '__main__':
+ with StreamHandler(sys.stderr, level='DEBUG').applicationbound():
+ main()
diff --git a/contrib/get_balance.sh b/contrib/get_balance.sh
new file mode 120000
index 0000000..a7906e5
--- /dev/null
+++ b/contrib/get_balance.sh
@@ -0,0 +1 @@
+venv_wrapper.sh
\ No newline at end of file
diff --git a/contrib/get_tip.py b/contrib/get_tip.py
new file mode 100755
index 0000000..a851a0d
--- /dev/null
+++ b/contrib/get_tip.py
@@ -0,0 +1,16 @@
+#!/usr/bin/env python3
+import argparse
+import client
+import json
+
+def main():
+ parser = argparse.ArgumentParser()
+ parser.add_argument("host")
+ parser.add_argument("port", type=int)
+ args = parser.parse_args()
+
+ conn = client.Client((args.host, args.port))
+ print(conn.call([client.request("blockchain.headers.subscribe")]))
+
+if __name__ == '__main__':
+ main()
diff --git a/contrib/get_tx.py b/contrib/get_tx.py
new file mode 100755
index 0000000..655540b
--- /dev/null
+++ b/contrib/get_tx.py
@@ -0,0 +1,17 @@
+#!/usr/bin/env python3
+import argparse
+import client
+import json
+
+def main():
+ parser = argparse.ArgumentParser()
+ parser.add_argument('--host', default='localhost')
+ parser.add_argument("txid")
+ args = parser.parse_args()
+
+ conn = client.Client((args.host, 50001))
+ tx, = conn.call([client.request("blockchain.transaction.get", args.txid, True)])
+ print(json.dumps(tx))
+
+if __name__ == "__main__":
+ main()
diff --git a/contrib/health_check.py b/contrib/health_check.py
new file mode 100755
index 0000000..9f2879e
--- /dev/null
+++ b/contrib/health_check.py
@@ -0,0 +1,16 @@
+#!/usr/bin/env python3
+import argparse
+import client
+import json
+
+def main():
+ parser = argparse.ArgumentParser()
+ parser.add_argument("host")
+ parser.add_argument("port", type=int)
+ args = parser.parse_args()
+
+ conn = client.Client((args.host, args.port))
+ print(json.dumps(conn.call([client.request("server.version", "health_check", "1.4")])))
+
+if __name__ == '__main__':
+ main()
diff --git a/contrib/history.py b/contrib/history.py
new file mode 100755
index 0000000..ac4867e
--- /dev/null
+++ b/contrib/history.py
@@ -0,0 +1,163 @@
+#!/usr/bin/env python3
+import argparse
+import datetime
+import hashlib
+import io
+import sys
+
+from logbook import Logger, StreamHandler
+import prettytable
+
+import client
+
+log = Logger('electrum')
+
+
+def _script_hash(script):
+ return hashlib.sha256(script).digest()[::-1].hex()
+
+
+def show_rows(rows, field_names):
+ t = prettytable.PrettyTable()
+ t.field_names = field_names
+ t.add_rows(rows)
+ for f in t.field_names:
+ if "mBTC" in f:
+ t.align[f] = "r"
+ print(t)
+
+
+def main():
+ parser = argparse.ArgumentParser()
+ parser.add_argument('--host', default='localhost')
+ parser.add_argument('--network', default='mainnet')
+ parser.add_argument('address', nargs='+')
+ parser.add_argument('--only-subscribe', action='store_true', default=False)
+ parser.add_argument('--no-merkle-proofs', action='store_true', default=False)
+ args = parser.parse_args()
+
+ if args.network == 'regtest':
+ port = 60401
+ from pycoin.symbols.xrt import network
+ elif args.network == 'testnet':
+ port = 60001
+ from pycoin.symbols.xtn import network
+ elif args.network == 'mainnet':
+ port = 50001
+ from pycoin.symbols.btc import network
+ else:
+ raise ValueError(f"unknown network: {args.network}")
+
+ hostport = (args.host, port)
+ log.info('connecting to {}:{}', *hostport)
+ conn = client.Client(hostport)
+
+ tip, = conn.call([client.request('blockchain.headers.subscribe')])
+
+ script_hashes = [
+ _script_hash(network.parse.address(addr).script())
+ for addr in args.address
+ ]
+
+ conn.call(
+ client.request('blockchain.scripthash.subscribe', script_hash)
+ for script_hash in script_hashes
+ )
+ log.info('subscribed to {} scripthashes', len(script_hashes))
+ if args.only_subscribe:
+ return
+
+ balances = conn.call(
+ client.request('blockchain.scripthash.get_balance', script_hash)
+ for script_hash in script_hashes
+ )
+
+ unspents = conn.call(
+ client.request('blockchain.scripthash.listunspent', script_hash)
+ for script_hash in script_hashes
+ )
+ for addr, balance, unspent in sorted(zip(args.address, balances, unspents), key=lambda v: v[0]):
+ if unspent:
+ log.debug("{}: confirmed={:,.5f} mBTC, unconfirmed={:,.5f} mBTC",
+ addr, balance["confirmed"] / 1e5, balance["unconfirmed"] / 1e5)
+ for u in unspent:
+ log.debug("\t{}:{} = {:,.5f} mBTC {}",
+ u["tx_hash"], u["tx_pos"], u["value"] / 1e5,
+ f'@ {u["height"]}' if u["height"] else "")
+
+ histories = conn.call(
+ client.request('blockchain.scripthash.get_history', script_hash)
+ for script_hash in script_hashes
+ )
+ txids_map = dict(
+ (tx['tx_hash'], tx['height'] if tx['height'] > 0 else None)
+ for history in histories
+ for tx in history
+ )
+ log.info('got history of {} transactions', len(txids_map))
+
+ txs = map(network.tx.from_hex, conn.call(
+ client.request('blockchain.transaction.get', txid)
+ for txid in txids_map.keys()
+ ))
+ txs_map = dict(zip(txids_map.keys(), txs))
+ log.info('loaded {} transactions', len(txids_map))
+
+ confirmed_txids = {txid: height for txid, height in txids_map.items() if height is not None}
+
+ heights = set(confirmed_txids.values())
+ def _parse_header(header):
+ return network.block.parse_as_header(io.BytesIO(bytes.fromhex(header)))
+ headers = map(_parse_header, conn.call(
+ client.request('blockchain.block.header', height)
+ for height in heights
+ ))
+ def _parse_timestamp(header):
+ return datetime.datetime.utcfromtimestamp(header.timestamp).strftime('%Y-%m-%dT%H:%M:%SZ')
+ timestamps = map(_parse_timestamp, headers)
+ timestamps_map = dict(zip(heights, timestamps))
+ log.info('loaded {} header timestamps', len(heights))
+
+ if args.no_merkle_proofs:
+ return
+
+ proofs = conn.call(
+ client.request('blockchain.transaction.get_merkle', txid, height)
+ for txid, height in confirmed_txids.items()
+ )
+ log.info('loaded {} merkle proofs', len(proofs)) # TODO: verify proofs
+
+ sorted_txdata = sorted(
+ (proof['block_height'], proof['pos'], txid)
+ for proof, txid in zip(proofs, confirmed_txids)
+ )
+
+ utxos = {}
+ balance = 0
+
+ rows = []
+ script_hashes = set(script_hashes)
+ for block_height, block_pos, txid in sorted_txdata:
+ tx_obj = txs_map[txid]
+ for txi in tx_obj.txs_in:
+ utxos.pop((str(txi.previous_hash), txi.previous_index), None)
+
+ for index, txo in enumerate(tx_obj.txs_out):
+ if _script_hash(txo.puzzle_script()) in script_hashes:
+ utxos[(txid, index)] = txo
+
+ diff = sum(txo.coin_value for txo in utxos.values()) - balance
+ balance += diff
+ confirmations = tip['height'] - block_height + 1
+ rows.append([txid, timestamps_map[block_height], block_height, confirmations, f'{diff/1e5:,.5f}', f'{balance/1e5:,.5f}'])
+ show_rows(rows, ["txid", "block timestamp", "height", "confirmations", "delta (mBTC)", "total (mBTC)"])
+
+ tip_header = _parse_header(tip['hex'])
+ log.info('tip={}, height={} @ {}', tip_header.id(), tip['height'], _parse_timestamp(tip_header))
+
+ unconfirmed = {txs_map[txid] for txid, height in txids_map.items() if height is None}
+ # TODO: show unconfirmed balance
+
+if __name__ == '__main__':
+ StreamHandler(sys.stderr).push_application()
+ main()
diff --git a/contrib/history.sh b/contrib/history.sh
new file mode 120000
index 0000000..a7906e5
--- /dev/null
+++ b/contrib/history.sh
@@ -0,0 +1 @@
+venv_wrapper.sh
\ No newline at end of file
diff --git a/contrib/local-electrum.bash b/contrib/local-electrum.bash
new file mode 100755
index 0000000..8886cec
--- /dev/null
+++ b/contrib/local-electrum.bash
@@ -0,0 +1,9 @@
+#!/bin/bash
+set -eux
+
+ADDR=127.0.0.1 # localhost
+PORT=50001 # default mainnet Electrum RPC port
+PROTOCOL=t # TCP (no SSL)
+
+# Use only local Electrum server:
+electrum --oneserver --server="$ADDR:$PORT:$PROTOCOL" $*
diff --git a/contrib/mempool.py b/contrib/mempool.py
new file mode 100755
index 0000000..0cf57b8
--- /dev/null
+++ b/contrib/mempool.py
@@ -0,0 +1,41 @@
+#!/usr/bin/env python3
+
+import argparse
+from daemon import Daemon
+
+import numpy as np
+import matplotlib.pyplot as plt
+
+
+def main():
+ parser = argparse.ArgumentParser()
+ parser.add_argument('--testnet', action='store_true')
+ args = parser.parse_args()
+
+ if args.testnet:
+ d = Daemon(port=18332, cookie_dir='~/.bitcoin/testnet3')
+ else:
+ d = Daemon(port=8332, cookie_dir='~/.bitcoin')
+
+ txids, = d.request('getrawmempool', [[False]])
+ txids = list(map(lambda a: [a], txids))
+
+ entries = d.request('getmempoolentry', txids)
+ entries = [{'fee': e['fees']['base']*1e8, 'vsize': e['vsize']} for e in entries]
+ for e in entries:
+ e['rate'] = e['fee'] / e['vsize'] # sat/vbyte
+ entries.sort(key=lambda e: e['rate'], reverse=True)
+
+ vsize = np.array([e['vsize'] for e in entries]).cumsum()
+ rate = np.array([e['rate'] for e in entries])
+
+ plt.semilogy(vsize / 1e6, rate, '-')
+ plt.xlabel('Mempool size (MB)')
+ plt.ylabel('Fee rate (sat/vbyte)')
+ plt.title('{} transactions'.format(len(entries)))
+ plt.grid()
+ plt.show()
+
+
+if __name__ == '__main__':
+ main()
diff --git a/contrib/script_hash.py b/contrib/script_hash.py
new file mode 100755
index 0000000..47a62fe
--- /dev/null
+++ b/contrib/script_hash.py
@@ -0,0 +1,31 @@
+#!/usr/bin/env python3
+import argparse
+import datetime
+import hashlib
+import io
+import sys
+
+
+def main():
+ parser = argparse.ArgumentParser()
+ parser.add_argument('--network', default='mainnet')
+ args = parser.parse_args()
+
+ if args.network == 'regtest':
+ from pycoin.symbols.xrt import network
+ elif args.network == 'testnet':
+ from pycoin.symbols.xtn import network
+ elif args.network == 'mainnet':
+ from pycoin.symbols.btc import network
+ else:
+ raise ValueError(f"unknown network: {args.network}")
+
+ for line in sys.stdin:
+ addr = line.strip()
+ script = network.parse.address(addr).script()
+ script_hash = hashlib.sha256(script).digest()
+ print(script_hash[::-1].hex())
+
+
+if __name__ == '__main__':
+ main()
\ No newline at end of file
diff --git a/contrib/script_hash.sh b/contrib/script_hash.sh
new file mode 120000
index 0000000..a7906e5
--- /dev/null
+++ b/contrib/script_hash.sh
@@ -0,0 +1 @@
+venv_wrapper.sh
\ No newline at end of file
diff --git a/contrib/testChanges.sh b/contrib/testChanges.sh
new file mode 100755
index 0000000..80fd800
--- /dev/null
+++ b/contrib/testChanges.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+cd `dirname $0`/..
+cargo build --locked --no-default-features --all
+cargo build --locked --no-default-features --all
+cargo build --locked --all
+cargo build --locked --features metrics_process --all
+cargo fmt
+cargo clippy -- -D warnings
+cargo test --locked --all
diff --git a/contrib/tx_fee.py b/contrib/tx_fee.py
new file mode 100755
index 0000000..370b230
--- /dev/null
+++ b/contrib/tx_fee.py
@@ -0,0 +1,28 @@
+#!/usr/bin/env python3
+import argparse
+import client
+
+def main():
+ parser = argparse.ArgumentParser()
+ parser.add_argument('--host', default='localhost')
+ parser.add_argument("txid")
+ args = parser.parse_args()
+
+ conn = client.Client((args.host, 50001))
+ tx, = conn.call([client.request("blockchain.transaction.get", args.txid, True)])
+ requests = []
+ for vin in tx["vin"]:
+ prev_txid = vin["txid"]
+ requests.append(client.request("blockchain.transaction.get", prev_txid, True))
+
+ fee = 0
+ for vin, prev_tx in zip(tx["vin"], conn.call(requests)):
+ txo = prev_tx["vout"][vin["vout"]]
+ fee += txo["value"]
+
+ fee -= sum(vout["value"] for vout in tx["vout"])
+
+ print(f'vSize = {tx["vsize"]}, Fee = {1e3 * fee:.2f} mBTC = {1e8 * fee / tx["vsize"]:.2f} sat/vB')
+
+if __name__ == "__main__":
+ main()
diff --git a/contrib/venv_wrapper.sh b/contrib/venv_wrapper.sh
new file mode 100755
index 0000000..bb218ad
--- /dev/null
+++ b/contrib/venv_wrapper.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+
+set -e
+
+cd -- "$( dirname -- "${BASH_SOURCE[0]}" )"
+
+cmd="$(basename -- "${BASH_SOURCE[0]}" .sh)".py
+
+if [ "$1" = "--venv" ]; then
+ shift
+ if [ ! -d .venv ]; then
+ python -m venv .venv
+ .venv/bin/pip install pycoin logbook prettytable base58
+ fi
+ PATH=$PWD/.venv/bin:$PATH
+fi
+
+exec python "$cmd" "$@"
diff --git a/doc/binaries.md b/doc/binaries.md
new file mode 100644
index 0000000..4f59e79
--- /dev/null
+++ b/doc/binaries.md
@@ -0,0 +1,23 @@
+## Native OS packages
+
+There are currently no official/stable binary packages.
+
+However, there's a [*beta* repository for Debian 10](https://deb.ln-ask.me) (should work on recent Ubuntu, but not tested well-enough)
+The repository provides several significant advantages:
+
+* Everything is completely automatic - after installing `electrs` via `apt`, it's running and will automatically run on reboot, restart after crash..
+ It also connects to bitcoind out-of-the-box, no messing with config files or anything else.
+ It just works.
+* Prebuilt binaries save you a lot of time.
+ The binary installation of all the components is under 3 minutes on common hardware.
+ Building from source is much longer.
+* The repository contains some security hardening out-of-the-box - separate users for services, use of [btc-rpc-proxy](https://github.com/Kixunil/btc-rpc-proxy), etc.
+
+And two disadvantages:
+
+* It's currently not trivial to independently verify the built packages, so you may need to trust the author of the repository.
+ The build is now deterministic but nobody verified it independently yet.
+* The repository is considered beta.
+ electrs seems to work well so far but was not tested heavily.
+ The author of the repository is also a contributor to `electrs` and appreciates [bug reports](https://github.com/Kixunil/cryptoanarchy-deb-repo-builder/issues),
+ [test reports](https://github.com/Kixunil/cryptoanarchy-deb-repo-builder/issues/61), and other contributions.
diff --git a/doc/config.md b/doc/config.md
new file mode 100644
index 0000000..3784b20
--- /dev/null
+++ b/doc/config.md
@@ -0,0 +1,197 @@
+## Manual configuration
+
+This applies only if you do **not** use some other automated systems such as Debian packages.
+If you use automated systems, refer to their documentation first!
+
+### Bitcoind configuration
+
+Pruning must be turned **off** for `electrs` to work.
+`txindex` is allowed but unnecessary for `electrs`.
+However, you might still need it if you run other services (e.g.`eclair`).
+The option `maxconnections` (if used) should be set to 12 or more for bitcoind to accept inbound p2p connections.
+Note that setting `maxuploadtarget` may cause p2p-based sync to fail - so consider using `-whitelist=download@127.0.0.1` to disable the limit for local p2p connections.
+
+The highly recommended way of authenticating `electrs` is using cookie file.
+It's the most [secure](https://github.com/Kixunil/security_writings/blob/master/cookie_files.md) and robust method.
+Set `rpccookiefile` option of `bitcoind` to a file within an existing directory which it can access.
+You can skip it if you're running both daemons under the same user and with the default directories.
+
+`electrs` will wait for `bitcoind` to sync, however, you will be unable to use it until the syncing is done.
+
+Example command for running `bitcoind` (assuming same user, default dirs):
+
+```bash
+$ bitcoind -server=1 -txindex=0 -prune=0
+```
+### Electrs configuration
+
+**Note:** this documentation may occasionally become stale. We recommend running `electrs --help` to get an up-to-date list of options.
+
+Electrs can be configured using command line, environment variables and configuration files (or their combination).
+It is highly recommended to use configuration files for any non-trivial setups since it's easier to manage.
+If you're setting password manually instead of cookie files, configuration file is the only way to set it due to security reasons.
+
+**Important:** you must configure `db_dir` to be either an empty directory or previously used by `electrs`!
+The contents of this directory is considered **internal to `electrs`** and any tampering that is **not** explicitly allowed by documentation
+can lead to serious problems! Currently the *only* permitted operation is *deleting whole `mainnet` subdirectory when upgrading to version 0.9.0* - see the upgrading section.
+
+#### Configuration files and priorities
+
+The Toml-formatted config files ([an example here](config_example.toml)) are (from lowest priority to highest): `/etc/electrs/config.toml`, `~/.electrs/config.toml`, `./electrs.toml`.
+They are loaded if they *exist* and ignored if not however, to aid debugging, any other error when opening them such as permission error will make electrs exit with error.
+
+The options in highest-priority config files override options set in lowest-priority config files.
+If loading these files is undesirable (common in case of protected systemd services), use the `--skip-default-conf-files` argument to prevent it.
+
+**Environment variables** override options in config files and finally **arguments** override everything else.
+
+There are two special arguments `--conf` which reads the specified file and `--conf-dir`, which read all the files in the specified directory.
+
+The options in those files override **everything** that was set previously, **including arguments** that were passed before these two special arguments.
+
+In general, later arguments override previous ones.
+It is a good practice to use these special arguments at the beginning of the command line in order to avoid confusion.
+
+**Naming convention**
+
+For each command line argument an **environment variable** of the same name with `ELECTRS_` prefix, upper case letters and underscores instead of hyphens exists
+(e.g. you can use `ELECTRS_ELECTRUM_RPC_ADDR` instead of `--electrum-rpc-addr`).
+
+Similarly, for each such argument an option in config file exists with underscores instead of hyphens (e.g. `electrum_rpc_addr`).
+
+You need to use `true` value in case of flags (e.g. `timestamp = true`).
+
+**Authentication**
+
+In addition, config files support `auth` option to specify username and password.
+This is not available using command line or environment variables for security reasons (other applications could read it otherwise).
+**Important note**: `auth` is different from `cookie_file`, which points to a file containing the cookie instead of being the cookie itself!
+
+If you are using `-rpcuser=USER` and `-rpcpassword=PASSWORD` of `bitcoind` for authentication, please use `auth="USER:PASSWORD"` option in one of the [config files](config.md#configuration-files-and-priorities).
+Otherwise, [`~/.bitcoin/.cookie`](https://github.com/bitcoin/bitcoin/blob/0212187fc624ea4a02fc99bc57ebd413499a9ee1/contrib/debian/examples/bitcoin.conf#L70-L72) will be used as the default cookie file,
+allowing this server to use bitcoind JSONRPC interface.
+
+Note: there was a `cookie` option in the version 0.8.7 and below, it's now deprecated - do **not** use, it will be removed.
+Please read upgrade notes if you're upgrading to a newer version.
+
+## Connecting an Electrum client ##
+
+To connect to your Electrs server, you will need to point Electrum to your server using the `ip_address:port` syntax. You will notice that most default servers in Electrum use the `50002` port (which is for SSL connections), while Electrs serves port `50001` and does not provide SSL out of the box.
+
+You would need to either use a webserver to provide SSL (see _SSL connection_ below), or connect without SSL. To tell Electrum to connect to your server without SSL, you need to add `:t` after the port (ie: `localhost:50001:t`). Please note that this is not secure and therefore recommended only for local connections.
+
+Electrs will listen by default on `127.0.0.1:50001`, which means it will only serve clients in the local machine. This is configured via the `electrum_rpc_addr` setting and if you wish to connect from another machine, you need to change it to `0.0.0.0:50001`. This is less secure though, and the recommended way to access Electrs remotely is to keep listening on `127.0.0.1` and tunnel to your server.
+
+## Extra configuration suggestions
+
+### SSL connection
+
+In order to use a secure connection, you can also use [NGINX as an SSL endpoint](https://docs.nginx.com/nginx/admin-guide/security-controls/terminating-ssl-tcp/#)
+by placing the following block in `nginx.conf`.
+Notice that while electrs doesn't use HTTP the configuration below uses raw TCP stream which works.
+
+```nginx
+stream {
+ upstream electrs {
+ server 127.0.0.1:50001;
+ }
+
+ server {
+ listen 50002 ssl;
+ proxy_pass electrs;
+
+ ssl_certificate /path/to/example.crt;
+ ssl_certificate_key /path/to/example.key;
+ ssl_session_cache shared:SSL:1m;
+ ssl_session_timeout 4h;
+ ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
+ ssl_prefer_server_ciphers on;
+ }
+}
+```
+
+```bash
+$ sudo systemctl restart nginx
+$ electrum --oneserver --server=example:50002:s
+```
+
+Note: If you are connecting to electrs from Eclair Mobile or another similar client which does not allow self-signed SSL certificates, you can obtain a free SSL certificate as follows:
+
+1. Follow the instructions at https://certbot.eff.org/ to install the certbot on your system.
+2. When certbot obtains the SSL certificates for you, change the SSL paths in the nginx template above as follows:
+```
+ssl_certificate /etc/letsencrypt/live/<your-domain>/fullchain.pem;
+ssl_certificate_key /etc/letsencrypt/live/<your-domain>/privkey.pem;
+```
+
+### Tor hidden service
+
+Install Tor on your server and client machines (assuming Ubuntu/Debian):
+
+```
+$ sudo apt install tor
+```
+
+Add the following config to `/etc/tor/torrc`:
+```
+HiddenServiceDir /var/lib/tor/electrs_hidden_service/
+HiddenServiceVersion 3
+HiddenServicePort 50001 127.0.0.1:50001
+```
+
+If you use [the *beta* Debian repository](binaries.md#cnative-os-packages),
+it is cleaner to install `tor-hs-patch-config` using `apt` and then placing the configuration into a file inside `/etc/tor/hidden-services.d`.
+
+Restart the service:
+```
+$ sudo systemctl restart tor
+```
+
+Note: your server's onion address is stored under:
+```
+$ sudo cat /var/lib/tor/electrs_hidden_service/hostname
+<your-onion-address>.onion
+```
+
+On your client machine, run the following command (assuming Tor proxy service runs on port 9050):
+```
+$ electrum --oneserver --server <your-onion-address>.onion:50001:t --proxy socks5:127.0.0.1:9050
+```
+
+For more details, see http://docs.electrum.org/en/latest/tor.html.
+
+### Sample Systemd Unit File
+
+If you use [the *beta* Debian repository](binaries.md#cnative-os-packages), you should skip this section,
+as the appropriate systemd unit file is installed automatically.
+
+You may wish to have systemd manage electrs so that it's "always on".
+Here is a sample unit file (which assumes that the bitcoind unit file is `bitcoind.service`):
+
+```
+[Unit]
+Description=Electrs
+After=bitcoind.service
+
+[Service]
+WorkingDirectory=/home/bitcoin/electrs
+ExecStart=/home/bitcoin/electrs/target/release/electrs --log-filters INFO --db-dir ./db --electrum-rpc-addr="127.0.0.1:50001"
+User=bitcoin
+Group=bitcoin
+Type=simple
+KillMode=process
+TimeoutSec=60
+Restart=always
+RestartSec=60
+
+Environment="RUST_BACKTRACE=1"
+
+# Hardening measures
+PrivateTmp=true
+ProtectSystem=full
+NoNewPrivileges=true
+MemoryDenyWriteExecute=true
+
+[Install]
+WantedBy=multi-user.target
+```
diff --git a/doc/config_example.toml b/doc/config_example.toml
new file mode 100644
index 0000000..1272ddb
--- /dev/null
+++ b/doc/config_example.toml
@@ -0,0 +1,31 @@
+# DO NOT EDIT THIS FILE DIRECTLY - COPY IT FIRST!
+# If you edit this, you will cry a lot during update and will not want to live anymore!
+
+# This is an EXAMPLE of how configuration file should look like.
+# Do NOT blindly copy this and expect it to work for you!
+# If you don't know what you're doing consider using automated setup or ask an experienced friend.
+
+# This example contains only the most important settings.
+# See docs or electrs man page for advanced settings.
+
+# File where bitcoind stores the cookie, usually file .cookie in its datadir
+cookie_file = "/var/run/bitcoin-mainnet/cookie"
+
+# The listening RPC address of bitcoind, port is usually 8332
+daemon_rpc_addr = "127.0.0.1:8332"
+
+# The listening P2P address of bitcoind, port is usually 8333
+daemon_p2p_addr = "127.0.0.1:8333"
+
+# Directory where the index should be stored. It should have at least 70GB of free space.
+db_dir = "/some/fast/storage/with/big/size"
+
+# bitcoin means mainnet. Don't set to anything else unless you're a developer.
+network = "bitcoin"
+
+# The address on which electrs should listen. Warning: 0.0.0.0 is probably a bad idea!
+# Tunneling is the recommended way to access electrs remotely.
+electrum_rpc_addr = "127.0.0.1:50001"
+
+# How much information about internal workings should electrs print. Increase before reporting a bug.
+log_filters = "INFO"
diff --git a/doc/cookie_deprecation.md b/doc/cookie_deprecation.md
new file mode 100644
index 0000000..953dfc0
--- /dev/null
+++ b/doc/cookie_deprecation.md
@@ -0,0 +1,33 @@
+# Deprecation of cookie option
+
+## What?
+
+As of 0.8.8 the `cookie` option is deprecated and it will be removed.
+A new `auth` option was added.
+If you don't use the `cookie` option, you're not affected and don't need to read this.
+Note that this is different from `cookie_file`.
+
+## Why?
+
+The option was confusing:
+
+* If you entered the path to cookie file (usually `~/.bitcoin/.cookie`), it wouldn't work.
+* If you copied the contents of cookie file into it, `electrs` would break at the next restart of the system.
+* If you used a script to fix the above run before `electrs` starts, it'd still break if `bitcoind` restarted for any reason.
+* If you used `BindsTo` option of systemd, you'd solve the issue but introduce needless downtime and waste of performance.
+* Entering `username:password` was the only valid use of `cookie` but it had nothing to do with cookie.
+
+## What to do?
+
+If you're installing `electrs` for the first time, just don't use `cookie`.
+If you're updating, reconsider the motivation above.
+If you used copying script, just use `cookie_file` to get the cookie directly.
+If you also used `BindsTo`, we recommend removing it.
+If you used fixed username and password because you didn't know about cookie or did it before `cookie_file` was implemented, reconsider using cookie authentication.
+If you really have to use fixed username and password, specify them using `auth` option (`username:password` like before) and remove the `cookie` option.
+
+## When the option will be removed?
+
+Probably in a few months.
+It'll still be detected and turned into explicit error for a while to make sure people really see the message and know what's going on.
+You can see [the tracking issue #371](https://github.com/romanz/electrs/issues/371) to monitor the progress of the change.
diff --git a/doc/install.md b/doc/install.md
new file mode 100644
index 0000000..b5d8a65
--- /dev/null
+++ b/doc/install.md
@@ -0,0 +1,271 @@
+## Quickstart
+
+<details>
+<summary>Building from source on an Ubuntu 21.10 VM:</summary>
+
+```bash
+$ sudo apt update
+$ sudo apt install -y clang cmake build-essential git cargo
+$ git clone https://github.com/romanz/electrs
+$ cd electrs
+$ cargo build --locked --release
+$ ./target/release/electrs --version # should print the latest version
+```
+
+</details>
+
+[](https://asciinema.org/a/XKznxilP4O7lCZiVZ9vZNd5vx?speed=3)
+
+## Manual installation from source
+
+**See below for automated/binary installation options.**
+
+### Build dependencies
+
+Note for Raspberry Pi 4 owners: the old versions of OS/toolchains produce broken binaries.
+Make sure to use latest OS! (see #226)
+
+Install [recent Rust](https://rustup.rs/) (1.63.0+, `apt install cargo` is preferred for Debian 12),
+[latest Bitcoin Core](https://bitcoincore.org/en/download/) (0.21+)
+and [latest Electrum wallet](https://electrum.org/#download) (4.0+).
+
+Also, install the following packages (on Debian or Ubuntu):
+```bash
+$ sudo apt update
+$ sudo apt install clang cmake build-essential # for building 'rust-rocksdb'
+```
+
+There are two ways to compile `electrs`: by statically linking to `librocksdb` or dynamically linking.
+
+The advantages of static linking:
+
+* The binary is self-contained and doesn't need other dependencies, it can be transferred to other machine without worrying
+* The binary should work pretty much with every common distro
+* Different library installed elsewhere doesn't affect the behavior of `electrs`
+
+The advantages of dynamic linking:
+
+* If a (security) bug is found in the library, you only need to upgrade/recompile the library to fix it, no need to recompile `electrs`
+* Updating rocksdb can be as simple as `apt upgrade`
+* The build is significantly faster (if you already have the binary version of the library from packages)
+* The build is deterministic
+* Cross compilation is more reliable
+* If another application is also using `rocksdb`, you don't store it on disk and in RAM twice
+
+If you decided to use dynamic linking, you will also need to install the library ([7.8.3 release](https://github.com/facebook/rocksdb/releases/tag/v7.8.3) is required).
+On [Debian 12 (bookworm)](https://packages.debian.org/bookworm/librocksdb-dev) and [Ubuntu 23.04 (lunar)](https://packages.ubuntu.com/lunar/librocksdb-dev):
+
+```bash
+$ sudo apt install librocksdb-dev=7.8.3-2
+```
+
+For other versions of Debian or Ubuntu, you can build librocksdb and install inside `/usr/local` directory using following command.
+
+```bash
+$ sudo apt install -y libgflags-dev libsnappy-dev zlib1g-dev libbz2-dev liblz4-dev libzstd-dev
+$ git clone -b v7.8.3 --depth 1 https://github.com/facebook/rocksdb && cd rocksdb
+$ make shared_lib -j $(nproc) && sudo make install-shared
+$ cd .. && rm -r rocksdb
+```
+
+#### Preparing for cross compilation
+
+Cross compilation can save you some time since you can compile `electrs` for a slower computer (like Raspberry Pi) on a faster machine
+even with different CPU architecture.
+Skip this if it's not your case.
+
+If you want to cross-compile, you need to install some additional packages.
+These cross compilation instructions use `aarch64`/`arm64` + Linux as an example.
+(The resulting binary should work on RPi 4 with aarch64-enabled OS).
+Change to your desired architecture/OS.
+
+If you use Debian (or a derived distribution) you need to enable the target architecture:
+
+```
+$ sudo dpkg --add-architecture arm64
+$ sudo apt update
+```
+
+If you use `cargo` from the repository
+
+```bash
+$ sudo apt install gcc-aarch64-linux-gnu g++-aarch64-linux-gnu libc6-dev:arm64 libstd-rust-dev:arm64
+```
+
+If you use Rustup:
+
+```bash
+$ sudo apt install gcc-aarch64-linux-gnu g++-aarch64-linux-gnu libc6-dev:arm64
+$ rustup target add aarch64-unknown-linux-gnu
+```
+
+If you decided to use the system rocksdb (recommended if the target OS supports it), you need the version from the other architecture:
+
+```bash
+$ sudo apt install librocksdb-dev:arm64
+```
+
+#### Preparing for cross compilation on a different (Debian-based) OS distribution/version
+*Note: Unless you run into the below mentioned libc (GLIBC) version issue, avoiding the approach described in this section is faster and requires less disk space on the build host. You may want to try the above cross compilation approach first and only use this one here as the last resort.*
+
+If your build system runs on a different OS distribution and/or release than the target system electrs is going to run on, you may run into `GLIBC` version issues like:
+```
+$ ./electrs --help
+./electrs: /lib/arm-linux-gnueabihf/libm.so.6: version `GLIBC_2.29' not found (required by ./electrs)
+```
+
+To cross-compile electrs for a different (Debian based) target distribution you can use a [debootstrap](https://wiki.debian.org/Debootstrap) based approach. For example your build system may be a 64-bit Debian `stable` (bullseye) system and you want to cross-compile for an armv7l (32-bit) Debian `oldstable` (buster) target, like an Odroid HC1/HC2.
+
+Install and setup debootstrap:
+
+```
+sudo apt install debootstrap
+```
+
+Next, create working directory for a `buster` based system and set it up:
+```
+mkdir debootstrap-buster
+sudo debootstrap buster debootstrap-buster http://deb.debian.org/debian/
+```
+(This takes a while to download.)
+
+Next, mount proc, sys and dev to the target system:
+```
+sudo mount -t proc /proc debootstrap-buster/proc
+sudo mount --rbind /sys debootstrap-buster/sys
+sudo mount --rbind /dev debootstrap-buster/dev
+```
+
+If you have checked out the electrs git repository somewhere already and don't want to have a duplicate copy inside the debootstrap working directory, just mount bind the exiting directory into the chroot:
+```
+sudo mkdir -p debootstrap-buster/mnt/electrs
+sudo mount --rbind ./electrs debootstrap-buster/mnt/electrs
+```
+
+chroot into the `buster` system and install the required dependencies to build electrs with a statically linked rocksdb:
+```
+sudo chroot debootstrap-buster /bin/bash
+
+apt install curl
+curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
+source "$HOME/.cargo/env"
+apt install clang cmake build-essential
+
+# install target specific cross compiler (armhf/gnueabihf)
+apt install gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf libc6-dev-armhf-cross
+rustup target add arm-unknown-linux-gnueabihf
+```
+
+Cross-compile `electrs` release with a statically linked rocksdb for armv7l (armhf) with libatomic inside `buster` chroot: *(bindgen needs an include path to the sources (header files) provided by the libc6-dev-armhf-cross package)*
+```
+cd /mnt/electrs/
+BINDGEN_EXTRA_CLANG_ARGS="-target arm-linux-gnueabihf -I/usr/arm-linux-gnueabihf/include/"\
+RUSTFLAGS="-C linker=arm-linux-gnueabihf-gcc -C linker-args=-latomic"\
+cargo build --locked --release --target arm-unknown-linux-gnueabihf
+```
+
+The built electrs binary will be in `/mnt/electrs/target/arm-unknown-linux-gnueabihf/release` within the chroot or can be accessed from outside the chroot respectively.
+
+#### Preparing man page generation (optional)
+
+Optionally, you may install [`cfg_me`](https://github.com/Kixunil/cfg_me) tool for generating the manual page.
+The easiest way is to run `cargo install cfg_me`.
+
+#### Download electrs
+
+```bash
+$ git clone https://github.com/romanz/electrs
+$ cd electrs
+```
+
+### Build
+
+Note: you need to have enough free RAM to build `electrs`.
+The build will fail otherwise.
+Close those 100 old tabs in the browser. ;)
+
+#### Cargo features
+
+By default `electrs` builds with Prometheus support.
+However this causes problems on some platforms.
+If you don't need Prometheus you may disable it using `--no-default-features` argument to `cargo build`/`cargo install`.
+
+#### Static linking
+
+First build should take ~20 minutes:
+```bash
+$ cargo build --locked --release
+```
+
+If RocksDB build fails with "`undefined reference to __atomic_*`" linker errors
+(usually happens on a 32-bit OS), set the following environment variable:
+```bash
+$ RUSTFLAGS="-C link-args=-latomic" cargo build --locked --release
+```
+Relevant issues: [#134](https://github.com/romanz/electrs/issues/134) and [#391](https://github.com/romanz/electrs/issues/391).
+
+#### Dynamic linking
+
+Note that if you have previously done a static linking build, it is recommended to clean the build artifacts to avoid build errors (e.g. https://github.com/romanz/electrs/issues/1001):
+```
+$ cargo clean
+```
+
+```
+$ ROCKSDB_INCLUDE_DIR=/usr/include ROCKSDB_LIB_DIR=/usr/lib cargo build --locked --release
+```
+
+Or if you have installed librocksdb from source
+
+```
+$ ROCKSDB_INCLUDE_DIR=/usr/local/include ROCKSDB_LIB_DIR=/usr/local/lib cargo build --locked --release
+```
+
+#### Cross compilation
+
+Run one of the commands above (depending on linking type) with argument `--target aarch64-unknown-linux-gnu` and prepended with env vars: `BINDGEN_EXTRA_CLANG_ARGS="-target gcc-aarch64-linux-gnu" RUSTFLAGS="-C linker=aarch64-linux-gnu-gcc"`
+
+E.g. for dynamic linking case:
+
+```
+$ ROCKSDB_INCLUDE_DIR=/usr/include ROCKSDB_LIB_DIR=/usr/lib BINDGEN_EXTRA_CLANG_ARGS="-target gcc-aarch64-linux-gnu" RUSTFLAGS="-C linker=aarch64-linux-gnu-gcc" cargo build --locked --release --target aarch64-unknown-linux-gnu
+```
+
+It's a bit long but sufficient! You will find the resulting binary in `target/aarch64-unknown-linux-gnu/release/electrs` - copy it to your target machine.
+
+#### Generating man pages
+
+If you installed `cfg_me` to generate man page, you can run `cfg_me man` to see it right away or `cfg_me -o electrs.1 man` to save it into a file (`electrs.1`).
+
+## Docker-based installation from source
+
+**Important**: The `Dockerfile` is provided for demonstration purposes and may NOT be suitable for production use.
+The maintainers of electrs are not deeply familiar with Docker, so you should DYOR.
+If you are not familiar with Docker either it's probably be safer to NOT use it.
+
+Note: currently Docker installation links statically
+
+Note: health check only works if Prometheus is running on port 4224 inside container
+
+```bash
+$ docker build -t electrs-app .
+$ mkdir db
+$ docker run --network host \
+ --volume $HOME/.bitcoin:/home/user/.bitcoin:ro \
+ --volume $PWD/db:/home/user/db \
+ --env ELECTRS_DB_DIR=/home/user/db \
+ --rm -i -t electrs-app
+```
+
+If not using the host-network, you probably want to expose the ports for electrs and Prometheus like so:
+
+```bash
+$ docker run --volume $HOME/.bitcoin:/home/user/.bitcoin:ro \
+ --volume $PWD/db:/home/user/db \
+ --env ELECTRS_DB_DIR=/home/user/db \
+ --env ELECTRS_ELECTRUM_RPC_ADDR=0.0.0.0:50001 \
+ --env ELECTRS_MONITORING_ADDR=0.0.0.0:4224 \
+ --rm -i -t electrs-app
+```
+
+To access the server from outside Docker, add `-p 50001:50001 -p 4224:4224` but be aware of the security risks. Good practice is to group containers that needs access to the server inside the same Docker network and not expose the ports to the outside world.
diff --git a/doc/monitoring.md b/doc/monitoring.md
new file mode 100644
index 0000000..bca9806
--- /dev/null
+++ b/doc/monitoring.md
@@ -0,0 +1,22 @@
+## Monitoring
+
+Indexing and serving metrics are exported via [Prometheus](https://github.com/tikv/rust-prometheus):
+
+```bash
+$ sudo apt install prometheus
+```
+
+Add `electrs` job to `scrape_configs` section in `/etc/prometheus/prometheus.yml`:
+
+```
+ - job_name: electrs
+ static_configs:
+ - targets: ['localhost:4224']
+```
+
+Restart and check the collected metrics:
+
+```
+$ sudo systemctl restart prometheus
+$ firefox 'http://localhost:9090/graph?g0.range_input=1h&g0.expr=index_height&g0.tab=0'
+```
diff --git a/doc/schema.md b/doc/schema.md
new file mode 100644
index 0000000..ab8af29
--- /dev/null
+++ b/doc/schema.md
@@ -0,0 +1,53 @@
+# Index Schema
+
+The index is stored at a single RocksDB database using the following column families.
+Most of the data is stored in key-only DB rows (i.e. having empty values).
+
+## Transaction outputs' index (`funding`)
+
+Allows efficiently finding all funding transactions for a specific address:
+
+| Script Hash Prefix | Confirmed Block Height |
+| -------------------- | ---------------------- |
+| `SHA256(script)[:8]` | `height as u32` |
+
+## Transaction inputs' index (`spending`)
+
+Allows efficiently finding spending transaction of a specific output:
+
+| Previous Outpoint Prefix | Confirmed Block Height |
+| ------------------------ | ---------------------- |
+| `txid[:8] as u64 + vout` | `height as u32` |
+
+
+## Transaction ID index (`txid`)
+
+In order to save storage space, we map the 8-byte transaction ID prefix to its confirmed block height:
+
+| Txid Prefix | Confirmed height |
+| ----------- | ---------------- |
+| `txid[:8]` | `height as u32` |
+
+Note that this mapping allows us to use `getrawtransaction` RPC to retrieve actual transaction data from without `-txindex` enabled
+(by explicitly specifying the [blockhash](https://github.com/bitcoin/bitcoin/commit/497d0e014cc79d46531d570e74e4aeae72db602d)).
+
+## Headers (`headers`)
+
+For faster loading, we store all block headers in RocksDB:
+
+| Serialized header |
+| ----------------------- |
+| `header as BlockHeader` |
+
+In addition, we also store the chain tip:
+
+| Key | | Value |
+| --- | - | ------------------------ |
+| `T` | | `blockhash as BlockHash` |
+
+## Configuration (`config`)
+
+| Key | | Value |
+| --- | - | --------------------------- |
+| `C` | | `serialized config as JSON` |
+
diff --git a/doc/upgrading.md b/doc/upgrading.md
new file mode 100644
index 0000000..a1de2a2
--- /dev/null
+++ b/doc/upgrading.md
@@ -0,0 +1,90 @@
+### Important changes from versions older than 0.9.3
+
+* If you use `verbose` (or `-v` argument), switch to `log_filters` (or `RUST_LOG` environment variable).
+ Please note that it allows to set per-module filters, but module naming is considered unstable.
+ If you have used `-vv` (the value suggested in the documentation), switch to `--log-filters INFO`:
+
+
+|Log filter|Old `verbose` value|Description |
+|----------|-------------------|----------------------------------------------------------------------|
+|ERROR | 0|Only fatal errors |
+|WARN | 1|Things that could indicate serious problems |
+|INFO | 2|Various significant events and suggestions |
+|DEBUG | 3|Details that could be useful when debugging - only use when debugging!|
+|TRACE | 4|**Very** detailed information - only use when debugging! |
+
+
+### Important changes from versions older than 0.9.0
+
+In 0.9.0 we have changed the RocksDB index format to optimize electrs performance.
+We also use Bitcoin P2P protocol instead of reading blocks from disk or JSON RPC.
+Some guides were suggesting trace log level and we started to trace much more information.
+
+Upgrading checklist:
+
+* Make sure you upgrade at time when you don't need to use electrs for a while.
+ Because of reindex electrs will be unable to serve your requests for a few hours.
+ (The exact time depends on your hardware.)
+ If you wish to check the database without reindexing run electrs with `--no-auto-reindex`.
+* If you have less than 60 GB of free space delete `mainnet` subdirectory inside your `db_dir` *before* running the new version.
+ Note however if you have less than 60 GB of free space you should consider extending your storage soon
+ since in the worst case scenario you will run out of space in ~100 days.
+* Make sure to allow accesses to bitcoind from local address, ideally whitelist it using `whitelist=download@127.0.0.1` bitcoind option.
+ Either don't use `maxconnections` bitcoind option or set it to 12 or more.
+* If you use non-default P2P port (or address) for bitcoind adjust `electrs` configuration.
+* If you still didn't migrate `cookie` electrs option you have to now - see below.
+* Remove unsupported options from configuration (`blocks_dir`, `jsonrpc_import`, `bulk_index_threads`, `tx_cache_size_mb`, `blocktxids_cache_size_mb`)
+* Rename `txid_limit` to `index_lookup_limit` if used
+* If you use `verbose = 4` (or `-vvvv` argument) lower it down to `2` (`-vv`) for production use.
+ Keeping it would waste resources because we utilize it more now.
+* **After reindexing**, if you did **not** delete `mainnet` subdirectory within `db_dir` check that `electrs` works as expected and then *delete whole `mainnet` subdirectory*.
+* If you are using our Dockerfile, please make sure to re-map the DB volume (see [the section above](docker.md#docker-based-installation-from-source)).
+
+### Important changes from version older than 0.8.8
+
+**If you're upgrading from version 0.8.7 to a higher version and used `cookie` option you should change your configuration!**
+The `cookie` option was deprecated and **will be removed eventually**!
+If you had actual cookie (from `~/bitcoin/.cookie` file) specified in `cookie` option, this was wrong as it wouldn't get updated when needed.
+It's strongly recommended to use proper cookie authentication using `cookie_file`.
+If you really have to use fixed username and password, explicitly specified in `bitcoind` config, use `auth` option instead.
+Users of `btc-rpc-proxy` using `public:public` need to use `auth` too.
+You can read [a detailed explanation of cookie deprecation with motivation explained](cookie_deprecation.md).
+
+### General upgrading guide
+
+As with any other application, you need to remember how you installed `electrs` to upgrade it.
+If you don't then here's a little help: run `which electrs` and compare the output
+
+* If you got an error you didn't install `electrs` into your system in any way, it's probably sitting in the `target/release` directory of source
+* If the path starts with `/bin/` then either you have used packaging system or you made a mistake the first time (non-packaged binaries must go to `/usr/local/bin`)
+* If the path starts with `/usr/local/bin` you most likely copied electrs there after building
+* If the path starts with `/home/YOUR_USERNAME/.cargo/bin` you most likely ran `cargo install`
+
+### Upgrading distribution package
+
+If you used Debian packaging system you only need this:
+
+```
+sudo apt update
+sudo apt upgrade
+```
+
+Similarly for other distributions - use their respective commands.
+If a new version of `electrs` is not yet in the package system, try wait a few days or contact the maintainers of the packages if it's been a long time.
+
+### Upgrading manual installation
+
+1. Enter your `electrs` source directory, usually in `~/` but some people like to put it in something like `~/sources`.
+ If you've deleted it, you need to `git clone` again.
+2. `git checkout master`
+3. `git pull`
+4. Strongly recommended: `git verify-tag v0.9.1` (fix the version number if we've forgotten to update the docs ;)) should show "Good signature from 15C8 C357 4AE4 F1E2 5F3F 35C5 87CA E5FA 4691 7CBB"
+5. `git checkout v0.9.1`
+6. If you used static linking: `cargo build --locked --release`.
+ If you used dynamic linking `ROCKSDB_INCLUDE_DIR=/usr/include ROCKSDB_LIB_DIR=/usr/lib cargo build --locked --release`.
+ If you don't remember which linking you used, you probably used static.
+ This step will take a few tens of minutes (but dynamic linking is a bit faster), go grab a coffee.
+ Also remember that you need enough free RAM, the build will die otherwise
+7. If you've previously copied `electrs` into `/usr/local/bin` run: sudo `cp target/release/electrs /usr/local/bin`
+ If you've previously installed `electrs` using `cargo install`: `cargo install --locked --path . -f`
+8. If you've manually configured systemd service: `sudo systemctl restart electrs`
diff --git a/doc/usage.md b/doc/usage.md
new file mode 100644
index 0000000..196232e
--- /dev/null
+++ b/doc/usage.md
@@ -0,0 +1,124 @@
+## Quickstart
+
+<details>
+<summary>Assuming Bitcoin Core 0.21+ is installed on the same machine (with the standard configuration at `~/.bitcoin/bitcoin.conf`):</summary>
+
+```bash
+$ bitcoind -server=1 -prune=0 &
+$ # ... wait until the chain is synced (e.g. using `bitcoin-cli getblockchaininfo`)
+$ electrs --log-filters=INFO --db-dir ./db --daemon-dir ~/.bitcoin --network bitcoin
+```
+
+</details>
+
+[](https://asciinema.org/a/zRNZp5HsBDi5rAlGWU7470Pzl?speed=3)
+
+## Usage
+
+First index sync should take ~6.5 hours for ~504GB @ August 2023 (on a dual core Intel CPU @ 3.3 GHz, 8 GB RAM, 1TB WD Blue HDD):
+```bash
+$ du -ch ~/.bitcoin/blocks/blk*.dat | tail -n1
+336G total
+
+$ ./target/release/electrs --network bitcoin --db-dir ./db --daemon-dir /home/user/.bitcoin
+Starting electrs 0.10.0 on x86_64 linux with Config { network: Bitcoin, db_path: "./db/bitcoin", daemon_dir: "/home/user/.bitcoin", daemon_auth: CookieFile("/home/user/.bitcoin/.cookie"), daemon_rpc_addr: 127.0.0.1:8332, daemon_p2p_addr: 127.0.0.1:8333, electrum_rpc_addr: 127.0.0.1:50001, monitoring_addr: 127.0.0.1:4224, wait_duration: 10s, jsonrpc_timeout: 15s, index_batch_size: 10, index_lookup_limit: None, reindex_last_blocks: 0, auto_reindex: true, ignore_mempool: false, sync_once: false, skip_block_download_wait: false, disable_electrum_rpc: false, server_banner: "Welcome to electrs 0.10.0 (Electrum Rust Server)!", magic: f9beb4d9, args: [] }
+[2023-08-16T19:17:11.193Z INFO electrs::metrics::metrics_impl] serving Prometheus metrics on 127.0.0.1:4224
+[2023-08-16T19:17:11.193Z INFO electrs::server] serving Electrum RPC on 127.0.0.1:50001
+[2023-08-16T19:17:12.355Z INFO electrs::db] "./db/bitcoin": 0 SST files, 0 GB, 0 Grows
+[2023-08-16T19:17:12.446Z INFO electrs::index] indexing 2000 blocks: [1..2000]
+[2023-08-16T19:17:12.866Z INFO electrs::chain] chain updated: tip=00000000dfd5d65c9d8561b4b8f60a63018fe3933ecb131fb37f905f87da951a, height=2000
+[2023-08-16T19:17:12.879Z INFO electrs::index] indexing 2000 blocks: [2001..4000]
+[2023-08-16T19:17:13.227Z INFO electrs::chain] chain updated: tip=00000000922e2aa9e84a474350a3555f49f06061fd49df50a9352f156692a842, height=4000
+[2023-08-16T19:17:13.238Z INFO electrs::index] indexing 2000 blocks: [4001..6000]
+[2023-08-16T19:17:13.587Z INFO electrs::chain] chain updated: tip=00000000dbbb79792303bdd1c6c4d7ab9c21bba0667213c2eca955e11230c5a5, height=6000
+[2023-08-16T19:17:13.598Z INFO electrs::index] indexing 2000 blocks: [6001..8000]
+[2023-08-16T19:17:13.950Z INFO electrs::chain] chain updated: tip=0000000094fbacdffec05aea9847000522a258c269ae37a74a818afb96fc27d9, height=8000
+[2023-08-16T19:17:13.961Z INFO electrs::index] indexing 2000 blocks: [8001..10000]
+<...>
+[2023-08-17T00:13:16.443Z INFO electrs::index] indexing 2000 blocks: [798001..800000]
+[2023-08-17T00:14:58.310Z INFO electrs::chain] chain updated: tip=00000000000000000002a7c4c1e48d76c5a37902165a270156b7a8d72728a054, height=800000
+[2023-08-17T00:14:58.325Z INFO electrs::index] indexing 2000 blocks: [800001..802000]
+[2023-08-17T00:16:36.425Z INFO electrs::chain] chain updated: tip=0000000000000000000311b41f1d611f977b024b947568c1dd760704360f148a, height=802000
+[2023-08-17T00:16:36.437Z INFO electrs::index] indexing 1534 blocks: [802001..803534]
+[2023-08-17T00:17:51.338Z INFO electrs::chain] chain updated: tip=00000000000000000003c0cd1b62ed8bb502e24bcbfeee16e81d6ea33d026263, height=803534
+[2023-08-17T00:18:00.592Z INFO electrs::db] starting config compaction
+[2023-08-17T00:18:00.778Z INFO electrs::db] starting headers compaction
+[2023-08-17T00:18:00.870Z INFO electrs::db] starting txid compaction
+[2023-08-17T00:33:34.370Z INFO electrs::db] starting funding compaction
+[2023-08-17T01:03:56.784Z INFO electrs::db] starting spending compaction
+[2023-08-17T01:35:05.983Z INFO electrs::db] finished full compaction
+[2023-08-17T01:36:23.300Z INFO electrs::index] indexing 5 blocks: [803535..803539]
+[2023-08-17T01:36:23.646Z INFO electrs::chain] chain updated: tip=000000000000000000006a3aaddd4b643607b33e000f1200d35005c330ecfa88, height=803539
+[2023-08-17T01:41:26.009Z INFO electrs::index] indexing 1 blocks: [803540..803540]
+[2023-08-17T01:41:26.143Z INFO electrs::chain] chain updated: tip=00000000000000000003266d31db92629b64241eef7ce708244f6d6283b080b4, height=803540
+[2023-08-17T01:42:42.999Z INFO electrs::index] indexing 1 blocks: [803541..803541]
+[2023-08-17T01:42:43.153Z INFO electrs::chain] chain updated: tip=00000000000000000000884a77c8b8ad2fb0c25510a3251bf5ef57f0db275146, height=803541
+```
+You can specify options via command-line parameters, environment variables or using config files.
+See the documentation above.
+
+Note that the final DB size should be ~10% of the `blk*.dat` files, but it may increase to ~20% at the end of the initial sync (just before the [full compaction is invoked](https://github.com/facebook/rocksdb/wiki/Manual-Compaction)).
+
+It should take roughly 18 hours to sync and compact the index on an ODROID-HC1 with 8 CPU cores @ 2GHz, 2GB RAM, and an SSD using the command above.
+
+The index database is stored here:
+```bash
+$ du db/
+42G db/mainnet/
+```
+
+See [extra configuration suggestions](config.md#extra-configuration-suggestions) that you might want to consider.
+
+## Electrum client
+
+If you happen to use the Electrum client from [the *beta* Debian repository](binaries.md#cnative-os-packages), it's pre-configured out-of-the-box already
+Read below otherwise.
+
+There's a prepared script for launching `electrum` in such way to connect only to the local `electrs` instance to protect your privacy.
+
+```bash
+$ ./contrib/local-electrum.bash
++ ADDR=127.0.0.1
++ PORT=50001
++ PROTOCOL=t
++ electrum --oneserver --server=127.0.0.1:50001:t
+<snip>
+```
+
+You can persist Electrum configuration (see `~/.electrum/config`) using:
+```bash
+$ electrum setconfig oneserver true
+$ electrum setconfig server 127.0.0.1:50001:t
+$ electrum # will connect only to the local server
+```
+
+## RPC examples
+
+You can invoke any supported RPC using `netcat`, for example:
+
+```
+$ echo '{"jsonrpc": "2.0", "method": "server.version", "params": ["", "1.4"], "id": 0}' | netcat 127.0.0.1 50001
+{"id":0,"jsonrpc":"2.0","result":["electrs 0.9.0","1.4"]}
+```
+
+For more complex tasks, you may need to convert addresses to
+[script hashes](https://electrumx-spesmilo.readthedocs.io/en/latest/protocol-basics.html#script-hashes) - see
+[contrib/history.py](https://github.com/romanz/electrs/blob/master/contrib/history.py) for getting an address balance and history:
+
+```
+$ ./contrib/history.sh --venv 144STc7gcb9XCp6t4hvrcUEKg9KemivsCR
+[2021-08-18 13:56:40.254317] INFO: electrum: connecting to localhost:50001
+[2021-08-18 13:56:40.574461] INFO: electrum: subscribed to 1 scripthashes
+[2021-08-18 13:56:40.645072] DEBUG: electrum: 0.00000 mBTC (total)
+[2021-08-18 13:56:40.710279] INFO: electrum: got history of 2 transactions
+[2021-08-18 13:56:40.769064] INFO: electrum: loaded 2 transactions
+[2021-08-18 13:56:40.835569] INFO: electrum: loaded 2 header timestamps
+[2021-08-18 13:56:40.900560] INFO: electrum: loaded 2 merkle proofs
++------------------------------------------------------------------+----------------------+--------+---------------+--------------+--------------+
+| txid | block timestamp | height | confirmations | delta (mBTC) | total (mBTC) |
++------------------------------------------------------------------+----------------------+--------+---------------+--------------+--------------+
+| 34b6411d004f279622d0a45a4558746e1fa74323c5c01e9c0bb0a3277781a0d0 | 2020-07-25T08:33:57Z | 640699 | 55689 | 126.52436 | 126.52436 |
+| e58916ca945639c657de137b30bd29e213e4c9fc8e04652c1abc2922909fb8fd | 2020-07-25T21:20:35Z | 640775 | 55613 | -126.52436 | 0.00000 |
++------------------------------------------------------------------+----------------------+--------+---------------+--------------+--------------+
+[2021-08-18 13:56:40.902677] INFO: electrum: tip=00000000000000000009d7590d32ca52ad0b8a4cdfee43e28e6dfcd11cafeaac, height=696387 @ 2021-08-18T13:47:19Z
+```
diff --git a/examples/tx_collisions.rs b/examples/tx_collisions.rs
new file mode 100644
index 0000000..839a508
--- /dev/null
+++ b/examples/tx_collisions.rs
@@ -0,0 +1,31 @@
+use anyhow::{Context, Result};
+use electrs_rocksdb::{ColumnFamilyDescriptor, IteratorMode, Options, DB};
+
+fn main() -> Result<()> {
+ let path = std::env::args().nth(1).context("missing DB path")?;
+ let cf_names = DB::list_cf(&Options::default(), &path)?;
+ let cfs: Vec<_> = cf_names
+ .iter()
+ .map(|name| ColumnFamilyDescriptor::new(name, Options::default()))
+ .collect();
+ let db = DB::open_cf_descriptors(&Options::default(), &path, cfs)?;
+ let cf = db.cf_handle("txid").context("missing column family")?;
+
+ let mut state: Option<(u64, u32)> = None;
+ for row in db.iterator_cf(cf, IteratorMode::Start) {
+ let (curr, _value) = row?;
+ let curr_prefix = u64::from_le_bytes(curr[..8].try_into()?);
+ let curr_height = u32::from_le_bytes(curr[8..].try_into()?);
+
+ if let Some((prev_prefix, prev_height)) = state {
+ if prev_prefix == curr_prefix {
+ eprintln!(
+ "prefix={:x} heights: {} {}",
+ curr_prefix, prev_height, curr_height
+ );
+ };
+ }
+ state = Some((curr_prefix, curr_height));
+ }
+ Ok(())
+}
diff --git a/internal/README.md b/internal/README.md
new file mode 100644
index 0000000..1a1e651
--- /dev/null
+++ b/internal/README.md
@@ -0,0 +1,3 @@
+# electrs-internal files
+
+**Nothing for users here, just for developers. ;)**
diff --git a/internal/config_specification.toml b/internal/config_specification.toml
new file mode 100644
index 0000000..a65c97e
--- /dev/null
+++ b/internal/config_specification.toml
@@ -0,0 +1,147 @@
+[general]
+env_prefix = "ELECTRS"
+conf_file_param = "conf"
+conf_dir_param = "conf_dir"
+skip_default_conf_files_switch = "skip_default_conf_files"
+doc = """
+An efficient re-implementation of Electrum Server, inspired by ElectrumX, Electrum Personal Server and bitcoincore-indexd.
+
+The motivation behind this project is to enable a user to run his own Electrum server, with required hardware resources not much beyond those of a full node. The server indexes the entire Bitcoin blockchain, and the resulting index enables fast queries for any given user wallet, allowing the user to keep real-time track of his balances and his transaction history using the Electrum wallet. Since it runs on the user's own machine, there is no need for the wallet to communicate with external Electrum servers, thus preserving the privacy of the user's addresses and balances."""
+
+[[switch]]
+name = "verbose"
+abbr = "v"
+doc = "Increase logging verbosity"
+count = true
+
+[[switch]]
+name = "timestamp"
+doc = "Prepend log lines with a timestamp"
+
+[[switch]]
+name = "auto_reindex"
+doc = "Automatically reindex the database if it's inconsistent or in old format"
+default = true
+
+[[param]]
+name = "db_dir"
+type = "std::path::PathBuf"
+doc = "Directory to store index database (default: ./db/)"
+default = "\"./db\".into()"
+
+[[param]]
+name = "db_log_dir"
+type = "std::path::PathBuf"
+doc = "Directory to store index database internal log (default: same as specified by `db_dir`)"
+
+[[param]]
+name = "daemon_dir"
+type = "std::path::PathBuf"
+doc = "Data directory of Bitcoind (default: ~/.bitcoin/)"
+default = "crate::config::default_daemon_dir()"
+
+[[param]]
+name = "auth"
+type = "String"
+doc = "JSONRPC authentication ('USER:PASSWORD', default: use cookie file)"
+# Force the user to use config file in order to avoid password leaks
+argument = false
+env_var = false
+
+[[param]]
+name = "cookie_file"
+type = "std::path::PathBuf"
+doc = "JSONRPC authentication cookie file (default: ~/.bitcoin/.cookie)"
+# This is safe to configure on command line.
+
+[[param]]
+name = "network"
+type = "crate::config::BitcoinNetwork"
+convert_into = "::bitcoin::Network"
+doc = "Select Bitcoin network type ('bitcoin', 'testnet', 'testnet4', 'regtest' or 'signet')"
+default = "Default::default()"
+
+[[param]]
+name = "electrum_rpc_addr"
+type = "crate::config::ResolvAddr"
+doc = "Electrum server JSONRPC 'addr:port' to listen on (default: '127.0.0.1:50001' for mainnet, '127.0.0.1:60001' for testnet, '127.0.0.1:60401' for regtest and '127.0.0.1:60601' for signet)"
+
+[[param]]
+name = "daemon_rpc_addr"
+type = "crate::config::ResolvAddr"
+doc = "Bitcoin daemon JSONRPC 'addr:port' to connect (default: 127.0.0.1:8332 for mainnet, 127.0.0.1:18332 for testnet, 127.0.0.1:18443 for regtest and 127.0.0.1:18554 for signet)"
+[[param]]
+name = "daemon_p2p_addr"
+type = "crate::config::ResolvAddr"
+doc = "Bitcoin daemon p2p 'addr:port' to connect (default: 127.0.0.1:8333 for mainnet, 127.0.0.1:18333 for testnet, 127.0.0.1:18444 for regtest and 127.0.0.1:38333 for signet)"
+
+[[param]]
+name = "monitoring_addr"
+type = "crate::config::ResolvAddr"
+doc = "Prometheus monitoring 'addr:port' to listen on (default: 127.0.0.1:4224 for mainnet, 127.0.0.1:14224 for testnet, 127.0.0.1:24224 for regtest and 127.0.0.1:34224 for signet)"
+
+[[param]]
+name = "wait_duration_secs"
+type = "u64"
+doc = "Duration to wait between bitcoind polling"
+default = "10"
+
+[[param]]
+name = "jsonrpc_timeout_secs"
+type = "u64"
+doc = "Duration to wait until bitcoind JSON-RPC timeouts (must be greater than wait_duration_secs)."
+default = "15"
+
+[[param]]
+name = "index_batch_size"
+type = "usize"
+doc = "Number of blocks to get in a single p2p protocol request from bitcoind"
+default = "10"
+
+[[switch]]
+name = "ignore_mempool"
+doc = "Don't sync mempool - queries will show only confirmed transactions."
+
+[[switch]]
+name = "disable_electrum_rpc"
+doc = "Disable Electrum RPC server - only sync and index blocks."
+
+[[switch]]
+name = "sync_once"
+doc = "Exit after the initial sync is over (don't start Electrum server)."
+
+[[switch]]
+name = "skip_block_download_wait"
+doc = "Don't wait for block download to finish before starting sync."
+
+[[switch]]
+name = "version"
+doc = "Print out the program version."
+
+[[param]]
+name = "index_lookup_limit"
+type = "usize"
+doc = "Number of transactions to lookup before returning an error, to prevent 'too popular' addresses from causing the RPC server to get stuck (0 - disable the limit)"
+default = "0"
+
+[[param]]
+name = "reindex_last_blocks"
+type = "usize"
+doc = "Number of last blocks to reindex (used for testing)"
+default = "0"
+
+[[param]]
+name = "server_banner"
+type = "String"
+doc = "The banner to be shown in the Electrum console"
+default = "concat!(\"Welcome to electrs \", env!(\"CARGO_PKG_VERSION\"), \" (Electrum Rust Server)!\").to_owned()"
+
+[[param]]
+name = "log_filters"
+type = "String"
+doc = "Logging filters, overriding `RUST_LOG` environment variable (see https://docs.rs/env_logger/ for details)"
+
+[[param]]
+name = "magic"
+type = "String"
+doc = "network magic for custom network in hex format, as found in Bitcoin Core logs"
diff --git a/logo/icon.svg b/logo/icon.svg
new file mode 100644
index 0000000..740b4ec
--- /dev/null
+++ b/logo/icon.svg
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 24.1.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 85.3 85.3" style="enable-background:new 0 0 85.3 85.3;" xml:space="preserve">
+<style type="text/css">
+ .st0{fill:#083766;}
+ .st1{fill:#FFFFFF;}
+ .st2{fill:none;stroke:#1250A9;stroke-width:1.9869;stroke-miterlimit:10;}
+ .st3{fill:none;stroke:#1859D1;stroke-width:1.9869;stroke-miterlimit:10;}
+ .st4{fill:none;stroke:#1853FF;stroke-width:1.9869;stroke-miterlimit:10;}
+</style>
+<g>
+ <path class="st0" d="M84.7,41.6L84.7,41.6l-3.6-2.2c0-0.4-0.1-0.7-0.1-1l3.1-2.9c0.3-0.3,0.4-0.7,0.4-1.1c-0.1-0.4-0.4-0.8-0.8-0.9
+ L79.8,32c-0.1-0.3-0.2-0.7-0.3-1l2.5-3.4c0.3-0.3,0.3-0.8,0.1-1.2c-0.2-0.4-0.5-0.7-0.9-0.8L77,24.9c-0.2-0.3-0.3-0.6-0.5-0.9
+ l1.8-3.8c0.2-0.4,0.1-0.8-0.1-1.2c-0.2-0.4-0.6-0.6-1.1-0.5l-4.2,0.1c-0.2-0.3-0.4-0.5-0.7-0.8l1-4.1c0.1-0.4,0-0.9-0.3-1.2
+ c-0.3-0.3-0.7-0.4-1.2-0.3l-4.1,1c-0.3-0.2-0.5-0.4-0.8-0.7l0.2-4.2c0-0.4-0.2-0.8-0.6-1.1C66,7,65.5,6.9,65.2,7.1l-3.8,1.7
+ c-0.3-0.2-0.6-0.3-0.9-0.5l-0.7-4.2c-0.1-0.4-0.4-0.8-0.8-0.9c-0.4-0.2-0.9-0.1-1.2,0.1l-3.4,2.5c-0.3-0.1-0.7-0.2-1-0.3l-1.5-3.9
+ c-0.1-0.4-0.5-0.7-0.9-0.8c-0.4-0.1-0.9,0.1-1.1,0.4L47,4.3c-0.3,0-0.7-0.1-1-0.1l-2.2-3.6C43.5,0.2,43.1,0,42.7,0
+ c-0.4,0-0.8,0.2-1.1,0.6l-2.2,3.6c-0.3,0-0.7,0.1-1,0.1l-2.9-3.1c-0.3-0.3-0.7-0.4-1.1-0.4c-0.4,0.1-0.8,0.4-0.9,0.8L32,5.5
+ c-0.3,0.1-0.7,0.2-1,0.3l-3.4-2.5c-0.3-0.3-0.8-0.3-1.2-0.1c-0.4,0.2-0.7,0.5-0.7,0.9l-0.7,4.2c-0.3,0.2-0.6,0.3-0.9,0.5l-3.8-1.7
+ C19.8,6.9,19.3,7,19,7.2c-0.4,0.2-0.6,0.6-0.6,1.1l0.1,4.2c-0.3,0.2-0.5,0.4-0.8,0.7l-4.1-1c-0.4-0.1-0.9,0-1.2,0.3
+ c-0.3,0.3-0.4,0.7-0.3,1.2l1,4.1c-0.2,0.3-0.4,0.5-0.7,0.8l-4.2-0.1c-0.4,0-0.8,0.2-1.1,0.5c-0.2,0.4-0.3,0.8-0.1,1.2L8.9,24
+ c-0.2,0.3-0.3,0.6-0.5,0.9l-4.1,0.7c-0.4,0.1-0.8,0.4-0.9,0.8c-0.2,0.4-0.1,0.8,0.1,1.2l2.5,3.4c-0.1,0.3-0.2,0.7-0.3,1l-3.9,1.5
+ c-0.4,0.1-0.7,0.5-0.8,0.9c-0.1,0.4,0.1,0.9,0.4,1.1l3.1,2.9c0,0.3-0.1,0.7-0.1,1l-3.6,2.2h0C0.2,41.8,0,42.2,0,42.7
+ c0,0.4,0.2,0.8,0.6,1l3.6,2.2c0,0.3,0.1,0.7,0.1,1l-3.1,2.9c-0.3,0.3-0.5,0.7-0.4,1.1c0.1,0.4,0.4,0.8,0.8,0.9l3.9,1.5
+ c0.1,0.3,0.2,0.7,0.3,1l-2.5,3.4c-0.2,0.3-0.3,0.8-0.1,1.2c0.1,0.4,0.5,0.7,0.9,0.7l4.1,0.7c0.2,0.3,0.3,0.6,0.5,0.9l-1.7,3.8
+ c-0.2,0.4-0.1,0.8,0.1,1.2c0.2,0.4,0.6,0.6,1.1,0.5l4.2-0.1c0.2,0.3,0.4,0.5,0.7,0.8l-1,4.1c-0.1,0.4,0,0.8,0.3,1.1
+ c0.3,0.3,0.7,0.4,1.2,0.3l4.1-1c0.3,0.2,0.5,0.4,0.8,0.7L18.4,77c0,0.4,0.2,0.8,0.6,1.1c0.3,0.2,0.8,0.3,1.2,0.1l3.8-1.7
+ c0.3,0.2,0.6,0.3,0.9,0.5l0.7,4.1c0.1,0.4,0.4,0.8,0.7,0.9c0.4,0.2,0.8,0.1,1.2-0.1l3.4-2.5c0.3,0.1,0.7,0.2,1,0.3l1.5,3.9
+ c0.1,0.4,0.5,0.7,0.9,0.8c0.4,0.1,0.9-0.1,1.1-0.4l2.9-3.1c0.4,0,0.7,0.1,1,0.1l2.2,3.6c0.2,0.4,0.6,0.6,1.1,0.6
+ c0.4,0,0.8-0.2,1.1-0.6l2.2-3.6c0.3,0,0.7-0.1,1-0.1l2.9,3.1c0.3,0.3,0.7,0.5,1.1,0.4c0.4-0.1,0.8-0.4,0.9-0.8l1.5-3.9
+ c0.3-0.1,0.7-0.2,1-0.3l3.4,2.5c0.4,0.2,0.8,0.3,1.2,0.1c0.4-0.2,0.7-0.5,0.7-0.9l0.7-4.1c0.3-0.2,0.6-0.3,0.9-0.5l3.8,1.7
+ c0.4,0.2,0.8,0.1,1.2-0.1c0.4-0.2,0.6-0.6,0.5-1.1l-0.2-4.2c0.3-0.2,0.5-0.4,0.8-0.7l4.1,1c0.4,0.1,0.9,0,1.2-0.3
+ c0.3-0.3,0.4-0.7,0.3-1.1l-1-4.1c0.2-0.3,0.4-0.5,0.7-0.8l4.2,0.1c0.4,0,0.8-0.2,1.1-0.5c0.2-0.4,0.3-0.8,0.1-1.2l-1.7-3.8
+ c0.2-0.3,0.3-0.6,0.5-0.9l4.1-0.7c0.4-0.1,0.8-0.3,0.9-0.7c0.2-0.4,0.1-0.9-0.1-1.2l-2.4-3.4c0.1-0.3,0.2-0.7,0.3-1l3.9-1.5
+ c0.4-0.2,0.7-0.5,0.8-0.9c0.1-0.4-0.1-0.8-0.4-1.1L81.1,47c0-0.3,0.1-0.7,0.1-1l3.6-2.2c0.4-0.2,0.6-0.6,0.6-1
+ C85.3,42.2,85.1,41.8,84.7,41.6z M62.4,66.6c-1.1,0.9-2.4,1.8-3.6,2.6c-4.7,2.9-10.3,4.5-16.3,4.5c-3.4,0-6.7-0.5-9.8-1.6
+ c-0.1,0-0.2-0.1-0.4-0.1c-1.1-0.4-2.1-0.8-3.2-1.2v0C28.1,70.3,27,69.7,26,69c-1.2-0.8-2.4-1.6-3.5-2.5c-0.9-0.7-1.7-1.5-2.5-2.3
+ l-0.1,0l-0.1,0c-1-1.1-2-2.2-2.9-3.4c0,0,0.1,0,0.1,0c-3.4-4.6-5.5-10.1-6-16.1h0c0-0.2,0-0.3,0-0.5c0-0.2,0-0.3,0-0.4
+ c0-0.1,0-0.3,0-0.4c0-0.3,0-0.5,0-0.8v-0.1l0,0c0-0.8,0-1.6,0.1-2.4c0-0.2,0-0.4,0.1-0.7h0l0.2-0.1c0.1-1.2,0.3-2.4,0.6-3.5
+ c0.4-1.6,0.8-3.2,1.4-4.8c0.5-1.3,1.1-2.6,1.8-3.9L15,27c2.3-4,5.5-7.5,9.2-10.1c0.1-0.1,0.3-0.2,0.4-0.3c4.4-3.1,9.6-5,15.3-5.4
+ c0.8-0.1,1.7-0.1,2.5-0.1c0.8,0,1.5,0,2.2,0.1c12.3,0.9,22.6,8.8,26.9,19.8c0.6,1.6,1.1,3.2,1.5,4.8c0.5,2.2,0.7,4.4,0.7,6.7
+ C73.9,52.1,69.4,60.9,62.4,66.6z"/>
+ <circle class="st1" cx="42.7" cy="42.7" r="33.5"/>
+ <g>
+ <ellipse class="st2" cx="42.7" cy="42.8" rx="27.2" ry="13.6"/>
+
+ <ellipse transform="matrix(0.8957 -0.4447 0.4447 0.8957 -14.4551 23.4064)" class="st3" cx="42.7" cy="42.5" rx="13.6" ry="27.2"/>
+ <path class="st4" d="M30.6,67.1c6.7,3.3,17.6-4.9,24.2-18.3s6.6-27-0.1-30.4"/>
+
+ <ellipse transform="matrix(0.4447 -0.8957 0.8957 0.4447 -14.6426 61.9687)" class="st4" cx="42.7" cy="42.8" rx="27.2" ry="13.6"/>
+ <path class="st3" d="M30.6,18.2c6.7-3.3,17.6,4.9,24.2,18.3s6.6,27-0.1,30.4S37.2,62,30.5,48.6"/>
+ <path class="st2" d="M69.8,42.8c0,7.5-12.2,13.6-27.2,13.6s-27.2-6.1-27.2-13.6"/>
+ </g>
+ <g id="Layer_x0020_1_3_">
+ <g id="_1421344023328_3_">
+ <path class="st0" d="M50.1,40.8L50.1,40.8c0.3-2.2-1.3-3.3-3.6-4.1l0.7-2.9l-1.8-0.4l-0.7,2.8c-0.5-0.1-0.9-0.2-1.4-0.3l0.7-2.9
+ l-1.8-0.4l-0.7,2.9c-0.4-0.1-0.8-0.2-1.1-0.3v0L38,34.6l-0.5,1.9c0,0,1.3,0.3,1.3,0.3c0.7,0.2,0.8,0.6,0.8,1l-0.8,3.3
+ c0,0,0.1,0,0.2,0.1c-0.1,0-0.1,0-0.2,0l-1.2,4.7c-0.1,0.2-0.3,0.5-0.8,0.4c-0.1,0-1.3-0.3-1.3-0.3l-0.9,2l2.3,0.6
+ c0.4,0.1,0.8,0.2,1.3,0.3l-0.7,3l1.8,0.4l0.7-2.9c0.5,0.1,0.9,0.3,1.4,0.4l-0.7,2.9l1.8,0.4l0.7-2.9c3,0.6,5.3,0.3,6.3-2.4
+ c0.8-2.2,0-3.5-1.6-4.3C49,43.1,49.9,42.4,50.1,40.8z M46.1,46.5c-0.5,2.2-4.3,1-5.5,0.7l1-3.9C42.8,43.6,46.6,44.2,46.1,46.5z
+ M46.6,40.8c-0.5,2-3.6,1-4.6,0.7l0.9-3.5C43.9,38.2,47.2,38.7,46.6,40.8z"/>
+ <path class="st0" d="M50.1,40.8L50.1,40.8c0.3-2.2-1.3-3.3-3.6-4.1l0.7-2.9l-1.8-0.4l-0.7,2.8c-0.5-0.1-0.9-0.2-1.4-0.3l0.7-2.9
+ l-1.8-0.4l-0.7,2.9c-0.4-0.1-0.8-0.2-1.1-0.3v0L38,34.6l-0.5,1.9c0,0,1.3,0.3,1.3,0.3c0.7,0.2,0.8,0.6,0.8,1l-0.8,3.3
+ c0,0,0.1,0,0.2,0.1c-0.1,0-0.1,0-0.2,0l-1.2,4.7c-0.1,0.2-0.3,0.5-0.8,0.4c-0.1,0-1.3-0.3-1.3-0.3l-0.9,2l2.3,0.6
+ c0.4,0.1,0.8,0.2,1.3,0.3l-0.7,3l1.8,0.4l0.7-2.9c0.5,0.1,0.9,0.3,1.4,0.4l-0.7,2.9l1.8,0.4l0.7-2.9c3,0.6,5.3,0.3,6.3-2.4
+ c0.8-2.2,0-3.5-1.6-4.3C49,43.1,49.9,42.4,50.1,40.8z M46.1,46.5c-0.5,2.2-4.3,1-5.5,0.7l1-3.9C42.8,43.6,46.6,44.2,46.1,46.5z
+ M46.6,40.8c-0.5,2-3.6,1-4.6,0.7l0.9-3.5C43.9,38.2,47.2,38.7,46.6,40.8z"/>
+ </g>
+ </g>
+</g>
+</svg>
diff --git a/logo/logo.svg b/logo/logo.svg
new file mode 100644
index 0000000..c9268b1
--- /dev/null
+++ b/logo/logo.svg
@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 24.1.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 307.8 85.3" style="enable-background:new 0 0 307.8 85.3;" xml:space="preserve">
+<style type="text/css">
+ .st0{fill:#083766;}
+ .st1{fill:#FFFFFF;}
+ .st2{fill:none;stroke:#1250A9;stroke-width:1.9704;stroke-miterlimit:10;}
+ .st3{fill:none;stroke:#1859D1;stroke-width:1.9704;stroke-miterlimit:10;}
+ .st4{fill:none;stroke:#1853FF;stroke-width:1.9704;stroke-miterlimit:10;}
+ .st5{fill:#1853FF;}
+</style>
+<g>
+ <path class="st0" d="M85,41.6L85,41.6l-3.6-2.2c0-0.4-0.1-0.7-0.1-1l3.1-2.8c0.3-0.3,0.4-0.7,0.4-1.1c-0.1-0.4-0.4-0.8-0.8-0.9
+ L80.1,32c-0.1-0.3-0.2-0.7-0.3-1l2.4-3.4c0.3-0.3,0.3-0.8,0.1-1.2c-0.2-0.4-0.5-0.7-0.9-0.7l-4.1-0.7c-0.2-0.3-0.3-0.6-0.5-0.9
+ l1.7-3.8c0.2-0.4,0.1-0.8-0.1-1.2c-0.2-0.4-0.6-0.6-1.1-0.5l-4.2,0.1c-0.2-0.3-0.4-0.5-0.7-0.8l1-4.1c0.1-0.4,0-0.8-0.3-1.1
+ c-0.3-0.3-0.7-0.4-1.2-0.3l-4.1,1c-0.3-0.2-0.5-0.4-0.8-0.7l0.2-4.2c0-0.4-0.2-0.8-0.5-1.1c-0.4-0.2-0.8-0.3-1.2-0.1l-3.8,1.7
+ c-0.3-0.2-0.6-0.3-0.9-0.5l-0.7-4.1c-0.1-0.4-0.4-0.8-0.7-0.9c-0.4-0.2-0.8-0.1-1.2,0.1l-3.4,2.4c-0.3-0.1-0.7-0.2-1-0.3l-1.5-3.9
+ c-0.1-0.4-0.5-0.7-0.9-0.8c-0.4-0.1-0.8,0.1-1.1,0.4l-2.8,3.1c-0.3,0-0.7-0.1-1-0.1l-2.2-3.6c-0.2-0.4-0.6-0.6-1-0.6
+ c-0.4,0-0.8,0.2-1,0.6l-2.2,3.6c-0.3,0-0.7,0.1-1,0.1l-2.9-3.1c-0.3-0.3-0.7-0.4-1.1-0.4c-0.4,0.1-0.8,0.4-0.9,0.8l-1.5,3.9
+ c-0.3,0.1-0.7,0.2-1,0.3l-3.4-2.4c-0.3-0.3-0.8-0.3-1.2-0.1c-0.4,0.2-0.7,0.5-0.7,0.9l-0.7,4.1c-0.3,0.2-0.6,0.3-0.9,0.5L21,7.4
+ c-0.4-0.2-0.8-0.1-1.2,0.1c-0.4,0.2-0.6,0.6-0.5,1.1l0.1,4.2c-0.3,0.2-0.5,0.4-0.8,0.7l-4.1-1c-0.4-0.1-0.9,0-1.1,0.3
+ c-0.3,0.3-0.4,0.7-0.3,1.1l1,4.1c-0.2,0.3-0.4,0.5-0.7,0.8l-4.2-0.1c-0.4,0-0.8,0.2-1.1,0.5c-0.2,0.4-0.3,0.8-0.1,1.2l1.7,3.8
+ c-0.2,0.3-0.3,0.6-0.5,0.9l-4.1,0.7c-0.4,0.1-0.8,0.4-0.9,0.7c-0.2,0.4-0.1,0.8,0.1,1.2L6.8,31c-0.1,0.3-0.2,0.7-0.3,1l-3.9,1.5
+ c-0.4,0.1-0.7,0.5-0.8,0.9c-0.1,0.4,0.1,0.8,0.4,1.1l3.1,2.8c0,0.3-0.1,0.7-0.1,1l-3.6,2.2h0c-0.4,0.2-0.6,0.6-0.6,1
+ c0,0.4,0.2,0.8,0.6,1l3.5,2.2c0,0.3,0.1,0.7,0.1,1l-3.1,2.8c-0.3,0.3-0.4,0.7-0.4,1.1c0.1,0.4,0.4,0.8,0.8,0.9l3.9,1.5
+ c0.1,0.3,0.2,0.7,0.3,1l-2.4,3.4c-0.2,0.3-0.3,0.8-0.1,1.2c0.1,0.4,0.5,0.7,0.9,0.7l4.1,0.7c0.2,0.3,0.3,0.6,0.5,0.9L8,65
+ c-0.2,0.4-0.1,0.8,0.1,1.2c0.2,0.4,0.6,0.6,1.1,0.5l4.2-0.1c0.2,0.3,0.4,0.5,0.7,0.8l-1,4.1c-0.1,0.4,0,0.8,0.3,1.1
+ c0.3,0.3,0.7,0.4,1.1,0.3l4.1-1c0.3,0.2,0.5,0.4,0.8,0.7l-0.1,4.2c0,0.4,0.2,0.8,0.6,1.1c0.3,0.2,0.8,0.3,1.2,0.1l3.8-1.7
+ c0.3,0.2,0.6,0.3,0.9,0.5l0.7,4.1c0.1,0.4,0.3,0.8,0.7,0.9c0.4,0.2,0.8,0.1,1.2-0.1l3.4-2.4c0.3,0.1,0.7,0.2,1,0.3l1.5,3.9
+ c0.1,0.4,0.5,0.7,0.9,0.8c0.4,0.1,0.8-0.1,1.1-0.4l2.8-3.1c0.4,0,0.7,0.1,1,0.1l2.2,3.5c0.2,0.4,0.6,0.6,1.1,0.6
+ c0.4,0,0.8-0.2,1-0.6l2.2-3.5c0.3,0,0.7-0.1,1-0.1l2.9,3.1c0.3,0.3,0.7,0.4,1.1,0.4c0.4-0.1,0.8-0.4,0.9-0.8l1.5-3.9
+ c0.3-0.1,0.7-0.2,1-0.3l3.4,2.4c0.4,0.2,0.8,0.3,1.2,0.1c0.4-0.2,0.7-0.5,0.7-0.9l0.7-4.1c0.3-0.2,0.6-0.3,0.9-0.5l3.8,1.7
+ c0.4,0.2,0.8,0.1,1.2-0.1c0.4-0.2,0.6-0.6,0.5-1.1l-0.2-4.2c0.3-0.2,0.5-0.4,0.8-0.7l4.1,1c0.4,0.1,0.9,0,1.1-0.3
+ c0.3-0.3,0.4-0.7,0.3-1.1l-1-4.1c0.2-0.3,0.4-0.5,0.7-0.8l4.2,0.1c0.4,0,0.8-0.2,1.1-0.5c0.2-0.4,0.3-0.8,0.1-1.2l-1.7-3.8
+ c0.2-0.3,0.3-0.6,0.5-0.9l4.1-0.7c0.4-0.1,0.8-0.3,0.9-0.7c0.2-0.4,0.1-0.8-0.1-1.2l-2.4-3.4c0.1-0.3,0.2-0.7,0.3-1l3.9-1.5
+ c0.4-0.2,0.7-0.5,0.8-0.9c0.1-0.4-0.1-0.8-0.4-1.1l-3.1-2.8c0-0.3,0.1-0.7,0.1-1l3.6-2.2c0.4-0.2,0.6-0.6,0.6-1
+ C85.6,42.2,85.4,41.8,85,41.6z M62.9,66.4c-1.1,0.9-2.3,1.8-3.6,2.6c-4.7,2.9-10.2,4.5-16.1,4.5c-3.4,0-6.6-0.5-9.7-1.5
+ c-0.1,0-0.2-0.1-0.4-0.1C32,71.5,31,71.1,30,70.6v0c-1.1-0.5-2.2-1.1-3.2-1.7c-1.2-0.7-2.4-1.6-3.4-2.5c-0.9-0.7-1.7-1.5-2.5-2.3
+ l-0.1,0l-0.1,0c-1-1-2-2.2-2.9-3.4c0,0,0.1,0,0.1,0c-3.3-4.5-5.5-10-5.9-16h0c0-0.2,0-0.3,0-0.5c0-0.2,0-0.3,0-0.4
+ c0-0.1,0-0.3,0-0.4c0-0.3,0-0.5,0-0.8v-0.1l0,0c0-0.8,0-1.6,0.1-2.4c0-0.2,0-0.4,0.1-0.7h0l0.2-0.1c0.1-1.2,0.3-2.4,0.5-3.5
+ c0.3-1.6,0.8-3.2,1.4-4.7c0.5-1.3,1.1-2.6,1.8-3.8l-0.1-0.1c2.3-4,5.4-7.4,9.1-10c0.1-0.1,0.3-0.2,0.4-0.3c4.4-3,9.6-5,15.2-5.4
+ c0.8-0.1,1.7-0.1,2.5-0.1c0.8,0,1.5,0,2.2,0.1c12.2,0.9,22.4,8.7,26.7,19.6c0.6,1.5,1.1,3.1,1.5,4.8c0.5,2.1,0.7,4.4,0.7,6.6
+ C74.3,52.1,69.9,60.7,62.9,66.4z"/>
+ <circle class="st1" cx="43.3" cy="42.7" r="33.2"/>
+ <g>
+ <ellipse class="st2" cx="43.3" cy="42.7" rx="27" ry="13.5"/>
+ <ellipse transform="matrix(0.8957 -0.4447 0.4447 0.8957 -14.3862 23.6936)" class="st3" cx="43.3" cy="42.5" rx="13.5" ry="27"/>
+ <path class="st4" d="M31.3,66.9c6.7,3.3,17.4-4.8,24-18.2s6.6-26.8-0.1-30.1"/>
+ <ellipse transform="matrix(0.4447 -0.8957 0.8957 0.4447 -14.2784 62.5448)" class="st4" cx="43.3" cy="42.8" rx="27" ry="13.5"/>
+ <path class="st3" d="M31.4,18.4c6.7-3.3,17.4,4.8,24,18.2s6.6,26.8-0.1,30.1s-17.4-4.8-24-18.2"/>
+ <path class="st2" d="M70.3,42.7c0,7.4-12.1,13.5-27,13.5s-27-6-27-13.5"/>
+ </g>
+ <g id="Layer_x0020_1_2_">
+ <g id="_1421344023328_2_">
+ <path class="st0" d="M50.7,40.8L50.7,40.8c0.3-2.1-1.3-3.3-3.5-4l0.7-2.9l-1.8-0.4l-0.7,2.8C45,36.1,44.5,36,44,35.9l0.7-2.8
+ L43,32.6l-0.7,2.9c-0.4-0.1-0.8-0.2-1.1-0.3v0l-2.4-0.6l-0.5,1.9c0,0,1.3,0.3,1.3,0.3c0.7,0.2,0.8,0.6,0.8,1l-0.8,3.3
+ c0,0,0.1,0,0.2,0.1c-0.1,0-0.1,0-0.2,0l-1.2,4.6c-0.1,0.2-0.3,0.5-0.8,0.4c-0.1,0-1.3-0.3-1.3-0.3l-0.9,2l2.3,0.6
+ c0.4,0.1,0.8,0.2,1.3,0.3l-0.7,2.9l1.8,0.4l0.7-2.9c0.5,0.1,0.9,0.2,1.4,0.4l-0.7,2.9l1.8,0.4l0.7-2.9c3,0.6,5.3,0.3,6.2-2.4
+ c0.8-2.2,0-3.4-1.6-4.3C49.6,43.1,50.5,42.4,50.7,40.8z M46.7,46.4c-0.5,2.2-4.2,1-5.4,0.7l1-3.9C43.4,43.6,47.3,44.2,46.7,46.4z
+ M47.2,40.8c-0.5,2-3.6,1-4.6,0.7l0.9-3.5C44.6,38.2,47.8,38.7,47.2,40.8z"/>
+ <path class="st0" d="M50.7,40.8L50.7,40.8c0.3-2.1-1.3-3.3-3.5-4l0.7-2.9l-1.8-0.4l-0.7,2.8C45,36.1,44.5,36,44,35.9l0.7-2.8
+ L43,32.6l-0.7,2.9c-0.4-0.1-0.8-0.2-1.1-0.3v0l-2.4-0.6l-0.5,1.9c0,0,1.3,0.3,1.3,0.3c0.7,0.2,0.8,0.6,0.8,1l-0.8,3.3
+ c0,0,0.1,0,0.2,0.1c-0.1,0-0.1,0-0.2,0l-1.2,4.6c-0.1,0.2-0.3,0.5-0.8,0.4c-0.1,0-1.3-0.3-1.3-0.3l-0.9,2l2.3,0.6
+ c0.4,0.1,0.8,0.2,1.3,0.3l-0.7,2.9l1.8,0.4l0.7-2.9c0.5,0.1,0.9,0.2,1.4,0.4l-0.7,2.9l1.8,0.4l0.7-2.9c3,0.6,5.3,0.3,6.2-2.4
+ c0.8-2.2,0-3.4-1.6-4.3C49.6,43.1,50.5,42.4,50.7,40.8z M46.7,46.4c-0.5,2.2-4.2,1-5.4,0.7l1-3.9C43.4,43.6,47.3,44.2,46.7,46.4z
+ M47.2,40.8c-0.5,2-3.6,1-4.6,0.7l0.9-3.5C44.6,38.2,47.8,38.7,47.2,40.8z"/>
+ </g>
+ </g>
+</g>
+<g>
+ <g>
+ <path class="st0" d="M116.4,60.2c-1.6-0.6-2.9-1.5-4-2.6c-1.1-1.1-2-2.4-2.6-3.9c-0.6-1.5-0.9-3.1-0.9-4.9v-1c0-2,0.3-3.8,0.9-5.4
+ c0.6-1.6,1.5-3,2.6-4.1c1.1-1.1,2.4-2,3.8-2.7c1.5-0.6,3-0.9,4.7-0.9c1.8,0,3.5,0.3,4.9,0.9c1.4,0.6,2.6,1.5,3.6,2.6
+ c1,1.1,1.7,2.4,2.2,4c0.5,1.5,0.7,3.2,0.7,5v2.4h-17.7v0.1c0.2,1.1,0.4,2,0.8,2.8c0.4,0.8,0.9,1.4,1.5,2c0.6,0.6,1.4,1.1,2.2,1.5
+ c0.9,0.3,1.8,0.5,2.8,0.5c1.4,0,2.7-0.3,3.9-0.8s2.2-1.3,3-2.3l3,2.9c-0.8,1.2-2.1,2.3-3.9,3.3c-1.8,1-3.9,1.5-6.4,1.5
+ C119.7,61.2,118,60.9,116.4,60.2z M118.7,39.7c-0.7,0.3-1.3,0.7-1.8,1.2c-0.5,0.6-1,1.2-1.3,2c-0.4,0.8-0.6,1.6-0.8,2.6h12v-0.4
+ c0-0.7-0.1-1.5-0.4-2.2s-0.6-1.4-1.1-1.9c-0.5-0.5-1.1-1-1.8-1.3c-0.7-0.3-1.5-0.5-2.5-0.5C120.1,39.3,119.4,39.4,118.7,39.7z"/>
+ <path class="st0" d="M153.5,24.5V56h7.7v4.7h-21.5V56h8.1V29.2h-8.1v-4.7H153.5z"/>
+ <path class="st0" d="M174.3,60.2c-1.6-0.6-2.9-1.5-4-2.6c-1.1-1.1-2-2.4-2.6-3.9c-0.6-1.5-0.9-3.1-0.9-4.9v-1c0-2,0.3-3.8,0.9-5.4
+ c0.6-1.6,1.5-3,2.6-4.1c1.1-1.1,2.4-2,3.8-2.7c1.5-0.6,3-0.9,4.7-0.9c1.8,0,3.5,0.3,4.9,0.9c1.4,0.6,2.6,1.5,3.6,2.6
+ c1,1.1,1.7,2.4,2.2,4c0.5,1.5,0.7,3.2,0.7,5v2.4h-17.7v0.1c0.2,1.1,0.4,2,0.8,2.8c0.4,0.8,0.9,1.4,1.5,2c0.6,0.6,1.4,1.1,2.2,1.5
+ s1.8,0.5,2.8,0.5c1.4,0,2.7-0.3,3.9-0.8s2.2-1.3,3-2.3l3,2.9c-0.8,1.2-2.1,2.3-3.9,3.3c-1.8,1-3.9,1.5-6.4,1.5
+ C177.6,61.2,175.9,60.9,174.3,60.2z M176.6,39.7c-0.7,0.3-1.3,0.7-1.8,1.2c-0.5,0.6-1,1.2-1.3,2s-0.6,1.6-0.8,2.6h12v-0.4
+ c0-0.7-0.1-1.5-0.4-2.2s-0.6-1.4-1.1-1.9c-0.5-0.5-1.1-1-1.8-1.3c-0.7-0.3-1.5-0.5-2.5-0.5C178,39.3,177.3,39.4,176.6,39.7z"/>
+ <path class="st0" d="M209.7,56.3c0.7-0.2,1.2-0.5,1.7-0.9c0.5-0.4,0.9-0.9,1.2-1.4c0.3-0.5,0.4-1.1,0.4-1.8h5.3
+ c0,1.2-0.3,2.4-0.8,3.5c-0.6,1.1-1.3,2-2.3,2.8c-1,0.8-2.1,1.5-3.4,1.9c-1.3,0.5-2.6,0.7-4,0.7c-2,0-3.7-0.3-5.2-1
+ c-1.5-0.7-2.7-1.6-3.7-2.8c-1-1.2-1.7-2.5-2.2-4.1c-0.5-1.5-0.8-3.2-0.8-5v-0.8c0-1.7,0.2-3.4,0.7-4.9c0.5-1.6,1.2-2.9,2.2-4.1
+ c1-1.2,2.2-2.1,3.7-2.8c1.5-0.7,3.2-1,5.1-1c1.5,0,3,0.2,4.3,0.7c1.3,0.5,2.4,1.1,3.4,2c0.9,0.8,1.7,1.9,2.2,3
+ c0.5,1.2,0.8,2.5,0.8,3.9h-5.3c0-0.7-0.1-1.3-0.4-2c-0.3-0.6-0.6-1.1-1.1-1.6c-0.5-0.5-1.1-0.8-1.7-1.1c-0.7-0.3-1.4-0.4-2.2-0.4
+ c-1.2,0-2.2,0.2-2.9,0.7c-0.8,0.5-1.4,1.1-1.9,1.9c-0.5,0.8-0.8,1.6-1,2.6c-0.2,1-0.3,2-0.3,3v0.8c0,1,0.1,2.1,0.3,3.1
+ s0.5,1.9,1,2.6c0.5,0.8,1.1,1.4,1.9,1.9c0.8,0.5,1.8,0.7,2.9,0.7C208.4,56.6,209.1,56.5,209.7,56.3z"/>
+ <path class="st0" d="M236.9,35.2h9.6v4.2h-9.6v12.2c0,0.9,0.1,1.7,0.3,2.4c0.2,0.6,0.5,1.1,1,1.5c0.4,0.4,0.9,0.6,1.5,0.8
+ c0.6,0.2,1.2,0.2,1.9,0.2c0.5,0,1,0,1.5-0.1c0.5,0,1-0.1,1.5-0.2c0.5-0.1,0.9-0.1,1.3-0.2c0.4-0.1,0.8-0.2,1-0.2l0.6,3.9
+ c-0.4,0.3-0.9,0.5-1.5,0.6s-1.2,0.3-1.8,0.5c-0.7,0.1-1.3,0.2-2.1,0.3c-0.7,0.1-1.4,0.1-2.1,0.1c-1.3,0-2.5-0.2-3.5-0.5
+ s-2-0.9-2.8-1.7c-0.8-0.7-1.4-1.7-1.8-2.9c-0.4-1.2-0.6-2.6-0.6-4.2V39.4H225v-4.2h6.2V29h5.7V35.2z"/>
+ <path class="st5" d="M274.8,34.9c0.9,0.1,1.5,0.3,2,0.4l-0.8,5.6c-0.9-0.2-1.7-0.3-2.6-0.4c-0.8-0.1-1.7-0.1-2.5-0.1
+ c-0.9,0-1.8,0.1-2.5,0.3c-0.8,0.2-1.4,0.5-2,0.9c-0.6,0.4-1.2,0.9-1.6,1.4c-0.4,0.6-0.8,1.2-1.1,2v15.7h-5.6V35.2h5.3l0.2,3.5
+ l0,0.6c1-1.4,2.3-2.6,3.7-3.4c1.5-0.8,3.1-1.2,4.8-1.2C273.1,34.7,273.9,34.8,274.8,34.9z"/>
+ <path class="st5" d="M299.9,52.6c-0.2-0.3-0.5-0.7-1-1c-0.5-0.3-1.1-0.5-1.9-0.8c-0.8-0.3-1.8-0.5-2.9-0.7c-1.5-0.3-2.8-0.7-4-1.1
+ c-1.2-0.4-2.3-1-3.1-1.6c-0.9-0.6-1.5-1.3-2-2.1c-0.5-0.8-0.7-1.8-0.7-2.9c0-1,0.2-2,0.7-3c0.5-0.9,1.2-1.8,2.1-2.5
+ c0.9-0.7,2-1.3,3.3-1.7c1.3-0.4,2.7-0.6,4.3-0.6c1.7,0,3.2,0.2,4.6,0.6c1.4,0.4,2.5,1,3.4,1.7c0.9,0.7,1.6,1.6,2.1,2.6
+ c0.5,1,0.8,2.1,0.8,3.2h-5.6c0-0.5-0.1-0.9-0.3-1.4s-0.5-0.8-0.9-1.2c-0.4-0.4-1-0.7-1.7-1c-0.7-0.2-1.5-0.4-2.4-0.4
+ c-0.8,0-1.6,0.1-2.2,0.3c-0.6,0.2-1.2,0.4-1.6,0.7c-0.4,0.3-0.7,0.6-0.9,1c-0.2,0.4-0.3,0.8-0.3,1.2c0,0.4,0.1,0.8,0.3,1.2
+ c0.2,0.4,0.5,0.7,0.9,0.9c0.4,0.3,1,0.5,1.7,0.8c0.7,0.2,1.7,0.4,2.8,0.6c1.6,0.3,3,0.6,4.3,1c1.3,0.4,2.4,0.9,3.3,1.5
+ c0.9,0.6,1.6,1.4,2.1,2.2c0.5,0.8,0.8,1.9,0.8,3c0,1.1-0.3,2.2-0.8,3.1c-0.5,0.9-1.3,1.8-2.2,2.4c-1,0.7-2.1,1.2-3.5,1.6
+ c-1.4,0.4-2.9,0.6-4.5,0.6c-1.8,0-3.5-0.2-4.9-0.7c-1.4-0.5-2.6-1.1-3.6-1.9c-1-0.8-1.7-1.7-2.2-2.7s-0.8-2.1-0.8-3.1h5.5
+ c0,0.8,0.3,1.5,0.6,2s0.8,1,1.4,1.3c0.5,0.3,1.2,0.6,1.9,0.7c0.7,0.1,1.4,0.2,2.1,0.2c1,0,1.8-0.1,2.6-0.3s1.3-0.5,1.8-0.8
+ c0.4-0.3,0.6-0.6,0.8-0.9s0.3-0.7,0.3-1.1C300.1,53.4,300.1,53,299.9,52.6z"/>
+ </g>
+</g>
+</svg>
diff --git a/logo/manual.pdf b/logo/manual.pdf
new file mode 100644
index 0000000..ede9dd3
--- /dev/null
+++ b/logo/manual.pdf
@@ -0,0 +1,2479 @@
+%PDF-1.5
%����
+1 0 obj
<</Metadata 2 0 R/OCProperties<</D<</ON[9 0 R]/Order 10 0 R/RBGroups[]>>/OCGs[9 0 R]>>/Pages 3 0 R/Type/Catalog>>
endobj
2 0 obj
<</Length 42391/Subtype/XML/Type/Metadata>>stream
+<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
+<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 6.0-c002 79.164360, 2020/02/13-01:07:22 ">
+ <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
+ <rdf:Description rdf:about=""
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:xmp="http://ns.adobe.com/xap/1.0/"
+ xmlns:xmpGImg="http://ns.adobe.com/xap/1.0/g/img/"
+ xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/"
+ xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#"
+ xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#"
+ xmlns:illustrator="http://ns.adobe.com/illustrator/1.0/"
+ xmlns:xmpTPg="http://ns.adobe.com/xap/1.0/t/pg/"
+ xmlns:stDim="http://ns.adobe.com/xap/1.0/sType/Dimensions#"
+ xmlns:stFnt="http://ns.adobe.com/xap/1.0/sType/Font#"
+ xmlns:xmpG="http://ns.adobe.com/xap/1.0/g/"
+ xmlns:pdf="http://ns.adobe.com/pdf/1.3/">
+ <dc:format>application/pdf</dc:format>
+ <dc:title>
+ <rdf:Alt>
+ <rdf:li xml:lang="x-default">logo-electrs-manual</rdf:li>
+ </rdf:Alt>
+ </dc:title>
+ <xmp:MetadataDate>2021-09-28T14:56:55+02:00</xmp:MetadataDate>
+ <xmp:ModifyDate>2021-09-28T14:56:55+02:00</xmp:ModifyDate>
+ <xmp:CreateDate>2021-09-28T14:56:55+02:00</xmp:CreateDate>
+ <xmp:CreatorTool>Adobe Illustrator 24.1 (Macintosh)</xmp:CreatorTool>
+ <xmp:Thumbnails>
+ <rdf:Alt>
+ <rdf:li rdf:parseType="Resource">
+ <xmpGImg:width>256</xmpGImg:width>
+ <xmpGImg:height>72</xmpGImg:height>
+ <xmpGImg:format>JPEG</xmpGImg:format>
+ <xmpGImg:image>/9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA
AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK
DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f
Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgASAEAAwER
AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA
AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB
UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE
1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ
qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy
obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp
0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo
+DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A9U4q7FXYq7FXYq7FXYq7
FUlk0LVZ7u6a51qdrCZke3tIUjgaAxyJIOM0YEjA8OLBtiCQcnxDuY0w/wDMjWfJ+h3ts3mHzhf6
Ld3Np6KQ23qOJFVZEMxhhikCsWlryoN1FOmW4oylyFteSURzLX5eebPI+q6pO2j+dL7WpbK1kkur
W/LxoI6xgz8ZYYP7vh1XpyNeoxyY5DnGlhOJ5FGt+fH5UBip10VBptbXZH3iGmX/AMmZ/wCb9o/W
w/OYu/7061n8x/JOjWVje6jqkcVtqSCWxdUklMkZAbmFiV2C0I3IyGDQZspIhGzHny/SznqIQAJP
Nry5+ZPknzJdyWejaotzcxIZXiaOWE8BsSPWSOtO9MOo7Oz4Rc40PgfuRj1OOZqJSt/zu/K9HZDr
YJUkErb3TCo22IiIP0Znj2c1xF+H/so/8U1/nsP877CzHTtRsdSsYL+xmW4s7lBJBMnRlPfff6Dm
nzYZY5mExUhzcmMhIWOSIytkll95X8uahNLPfaZbXM06NFNJLErsyOqqysSNwVRR9GSEyOqDEMKu
PN3kfypq95o/lDQDqmvy0fUbPRIEqpVnCm6mFEUq3IfEagnpvlwxykLkaHm1GcYmgLPkqr+bsmnz
xJ5r8tal5dtpnEaahMq3FqGYkIJJYOQQt8PX37CuPgX9JBXxq5imf21zbXVtFdWsqT206LLBPEwd
HRxyV0ZahlYGoIzHIpuBVMVdirsVS/W7HVb20SLTdTbSp1kDNcJDFOWQAgpxlBUVJBr12yUSBzCC
EH/hZWtdWtpdRvHj1dneQ+pxaF3jSOsDAVjC+nyVRtUnDx8vJHCgbryPcz3M8/8AiTVo/Wb4USdV
WNeKDiihAOsZIJ/mOEZPII4fNkGmWJsbX6ubia6/eSyCW4cySUkkZwvI/spy4r7DIE2yARWBLsVd
irsVdirsVdirsVdirsVdirsVdir5b/5y3t5x5t0a4MbfV2sPTWWh4F1mcleXSoDA0zZaE+k+9wdX
zDGv+cftOv7vXfMRtreSYDQL6IlFJHqShVjSv8zHoO+X5pAGN/zg1YQTfuLDGVlYqwKspoynYgjO
jda9W/NKxvYPKnkOSaCSNF0hImZlIAeitxNejUNaZR2PMGeUA/xuRrInhh7nfkLa3M3nWZ4omkSO
wuRIygkLzXitT7nYZb23MDCLP8QRoATP4F546PG7I6lHQlWVhQgjYgg524IIsOA+uvyit57f8uND
injaKT0Wbg4oeLyuymh8VYHPJe3piWsyEGxf6A9JowRijbL81DkpH561ybQvJ2s6vB/f2VpLLCaV
pIFIQ0o1aNTtk8ceKQDGcqiS800TTItN8s6bp0MNtM0wE2ualqRWZZtRms1vpJZVcqJEgtmcqZXA
B4/62bbBVymSdhe2218NX0uVculuFIbAff31f2BIPIPnGPWba1nbT47nS5Xv4Lq2lJ9Z7S2tA9zB
LJIzJMlJIXiV/smq8lUDMzJ+8xzs0Rw+7iMtiO7biBrnz3LVCVEd2/yrf9FPQfyduZLf/Efln15L
mz0G/wCGmSylmcWVzGJ4IyzDfgrU69NqDaui1A5Hvc7CeY7nouY7c7FXYq44q1irsVWvIiCrH6MV
Uvr1tSvI/wDAt/TFVVJEcVU/Riq7FXYqxX/laXkj/ltm/wCkO8/6o5Z4UmHGHf8AK0vJH/LbN/0h
3n/VHHwpLxhiXnLzNomtyn9H+YXsbeWBIbiNrDUWLGK4WcUMYioJOHpv34k5ZCJHMfcxlIHqwx9B
06SEWr/mFqIh+sLKZ1stS+smNWUspc1UtJTk7cftKp8RlvEf5v3NdeaxdERZreb/AJWLeSNauskc
T6bqXpN8L1V1DAkKW+DfYV64eL+j9oWvNlvk3XNO8v63eXV35rm1TT7sH/R5tP1ASRfEzqsb0ZeI
L03WtMqnEkcvuZxNHmzb/laXkj/ltm/6Q7z/AKo5V4UmfGG0/NDyS7qi3sxZiAB9TvBufnDj4Ul4
wyrK2aSeafLdxrtrHBDrF9o/Avyl0+RYncMtAGYqx+E/EKfqycJ8PS2Mo31pZ5V8r3WhLdC41zUN
ba5YMG1GRH9OjOxEYRUCgmTp4AAbADGc+LoAiMa62gP8BXw1CW+j81aykslw9wkfrxvCgk29JYZI
3iKKuygqadetDmR+aFVwR5dzX4Ju+IpzrmiTapBbRR6ld6ebeZZnktHWNpQoIMch4n4WruBleDMI
EnhjKx16M5w4upCl5c8uTaKJVfV7/VBKsar9flEpT0xxqpCru3VvE5LUagZK9MY/1RSMePh6k+9L
rryRfT3puk8z6vbn6y9wsMUsXpKryLIIeDRsCiFKLyr8JKmoNMy4dpRjHh8HEfTW4N8qvnzP3782
BwEm+KTKI1ZY1VnMjKAC7UBYgdTQAb+wzWE2XIC7AqX+YdFttc0K/wBHuSVgv4JLd2AqV9RSOVO9
DvTJRlwm0SFinhyS6O1pB5W83qdM81aXCtlKwmS3j1C2j/d2tzG916dtPQRcCs1OS8uPhm402Wr3
9J77Nd423F30604E4g7H6h+Bz2Q1nZ+UvKq2C6/NaXpsnLW+lWE8Ey3POMpHDFbW4V5Hkles0txR
aKqfEN8yM2pjwGOGwD387vmT7vpAvmTs1xx0Rx71+P7beqflX5e1bT9KvtZ1xBFrnmS6fUr23Ff3
CyCkMHxBW/dx0BBGxqM0eaYJocg5+KJAs8yzbKW12KuxVxxVrFUJf3Dxx8YzRqjkfAYqooSUBJqS
OuKu4rWtBXxxVSuSwQFSQa7EdcVRdhcvIPTl3kAqD4gbYqi8VbxVjfmrzXcaZPHp2m2yXWpyRG4d
p5BDbQQhggeaTc1dzxRQPiNakKCRdixcZa8mThQHlnz3c3t9DY6pFbg3bFLK9snZ4XlVGkMUqOA8
TlEZk+0GCtupFDZm0xgLY48vEyrUNT03Tbf6zqN3DZW/JU9a4kWJObmirycgVY7AZjAE8m0kDmic
CVqSxOXVHVmjbjIAQSrUDUNOhowOKrsVdirH7+z863Ul7DDf2djas0ZsJ4Yne4ULKjOsvqFozzjD
LsO9cmDFibWavpXmq4ulmsPMCacBBGk1v9WjljDgTF5V9QlhzZo6AnYIfHEEdykHvTbSIr63023h
1G9W/vkXjPeBFiErVPxCNdl+WRPPZIRnJa8aip6DvgS3irsVdirsVdirXJfh3HxbL77V2+jFUv1n
y/oGv2gttXsbfUbcElFnRZAp6EqT9k9jTJRkY8kGIPNB6H5D8maFcfWdI0a0srmlBPFEokFeVaOa
sK8yNu22GWSUuZYxhEcgnuQZuxV2KuxVxxVrFUpvZHhQh42eWQ8Y0UV5MfA9MVYt548j3fmddN9L
UpNONk5dhGCasaUYEFd1p8/ArvXJ0+cY7sXYacuIzreqVpfJeqSXDynzRqixvLNL6KtCqj1fsoKR
ghY9uIFPfIRygfwhJxnvKc21o9jZw2z3Mt4xmISa4YGQiSQkKWAFQgag9hgzZBOXEAI+Q5M4RoVd
ukn1r9MWcGnxxfU0ZjqM0gdnCigEaKDGoLVLcyxpxpwPKqwFVuk3bIDkUt4qwTz3oeqfpT9M2UFx
dQTWsdpeJYuq3UTQSySQyxKwIdf38iuB8Q2YA8aZl6bKIndozQJ3DHPy58jXVsdLs4bS7s9G0a6N
8Jr4GNpZjC0QSKF1SWjc+TtIBx4gJ9pqXavURlsO6vtv8fsa8OIjmmWuflTr97q3mS/tdfATXolh
W2uopZUhQPExFFmQHh6REe23I+9caOYAAVybJYiSd+ajffk/r15qGr303mL1W1SWKZrV45/q5Kbm
ORFuFYxof7sBqrtvhGcAAVyU4TZ3R9n+UyW91qXK6iks9UvbW/uqxyieQwIiyxPJ6pBSQqzdK1c1
Jy/T644jxAb8JA8r68uiJYL+ae+U/KF1oWq6zdyX31i31OUSQ2wRlEIDuwHJmcn4XC/JfDYT12vj
nx44iNGA3Pfy8vK/iuHCYEm+bJs1jkOxVivnqO2tbaLUYtCs9Z1GaSKyK3ckVvSFxJX95Kr1C+o3
wgVIY++WY+66YS9zzKLVPKUxuItP/L7QbslmWkV1ptGijnZXYggPQRqrVC7E0y+pdZH7Wux3BqXz
ToF/PFb3fkby/eramO1t4Vv9MM6BVdWhCSUVWiCKOPOlCPCgeAj+I/avEO4J1pP5y3cIt7H/AA5Z
2FnHBG9nCurWFRahCsYEYYUoQoFKingaAxOHz+xIyeSrb/nP5iaZ4rry9Z2p5pBCzaxYmszoJCWq
y0RVIY78qHYdcBwjv+xfEPcun/OfXkup4IfLttOiB5Y7r9LWscPopTkXZwOLLyFVpXuKjfHwB3/Y
nxD3PQPKeuTa5oUGqSwxwNcNIUjimS4T01kZY2EkZZG5oA2x75TONGmyJsKl95b0i+1O31O5idr2
1XjBKs00YUVJ+wjqh+0dyMRIgUpASvUPIXlO60i10S4t5msbL4rSNZZy0XKBrb4ZAxcfu3bv1364
RkINoMBVJYv5S/l6Vi42V0I0WiqtxeAENGkZrR6kFYhWvXevU5LxpI8MMi0ltB0o/oWzlYS8pbn6
u7SyyVmkMrsS/JvtOaDw6ZWTbICkzNzEBUhwNh9h++3hgSuWVGbiKg0rQqV2HzAxVfirsVccVdTF
XUxVJ7XULG9Er2dzFcrFK8MrQusgWRD8SNxJoy9wd8JBHNAIKvgSozj99aHsJlr9xGKptirsVbxV
2KuxV2KuxV2KuxV2KuxVj3nny1qHmHSI7GxvYrGVJ1maS4tku42VFYcDG5XqWBqDXbJ45CJYyjYY
Xafk1qtpHAY9S0/6xEzF2TTIYw4mm9WUOx9SVgP2AHXcAsTSmWnMPwWHhp/5f/Kvy1aWPDW9M0zV
b4MwF4bC3jPpsKcSAu53PI9yTkJZT0JDIQHVNv8AlX3kcABdCslC9AsCKNlKgmgFSATQ9q7ZHxJd
6eAdzUX5d+Q4tPbTk8v2H1FnMrW5t42Qua/EQQd99vDHxJXdrwDuRFx5K8oXMoluNGspZFPIM8EZ
oTQ13H+SPuwCcu9eEJpaWdpZwCC0hS3gDMwiiUIoaRi7nitB8TMSffATbJVwKokSG5fgyj4ErUE9
29xirHfNHnbS/KmmWs2ozc7m6ASwsIYzJc3Eg4jhDGG5OautaDauWY8ZlyYTmI82DHXvzAXXz5pk
8i6jJahaRR/WLQzonFkP+ihzLXjvxr1J65Z4UeXELYeJL+azvyv500rzXpz3OmXA9W3lSO9s5Y2j
uLeQSceE0ZbkhqhpXKsmMxO7OExLkyACQXCc2B+BqUBHdfEnIM1bFXYq44q4Yq7FXjC6nDDf2vma
xto9P1KbVoLHUbeMcFubS9MUdJ0X7UiyT+rFITyPFh9n4c2ebGOED+jfx3/QPucOE9783q2axzFG
evO3O200da/61MVTbFXYq3irsVdirsVdirsVdirsVSC+u/O7yX0Njp1lCkZT9H3k108nqj1UEnqw
rCnp/uuZFJG3pkwIsTa3VH8+/XoH0qPTvqLwgXENyZjLHOVkJZXSiugb0xSgJ36Yjh6qbS6S4/Nz
gTFaaKWVSOLyXILsIVIIpstZ+Qp2XxOS9Hmj1Mwi9X0k9YKJeI9QISV5U34k0NK5UzXYq7FXYq7F
XYqxrzR5zs/L15FHPbyzPcxhkKUC0QtUcj1apG39lSAgl5vpWoDWPN3mTX1RbjUoh+hfLLTH0Fto
o7JrqedWeKNuTh6qeJamwbh8WbDDDaIP07E+e9OJOW5PXkPkxi9806cnnE6VFYaeeemvezehCRCb
Y2xna3khEg4zrbgyLJz586Ly4nNxjyzEhjBl9VXf8V8+X03tXKt6txJAc6HL7P1/pZTeX0+i+ePL
WuyLx1G5jk0jzSsLLMtyYLOG9inDKjVbgQSfh7DlwFTp9SI+rh+i7j5CyKczGTYvnyPyeoeX/M2n
667PaLJG8AKyxygAjlxII4lhQ0P3ZrnLTvFXYq44q7FXYq8+0rybrUuqQ32um3itLG5ku7HR7NGe
E3DJ6a3M8zrH6kir9gBAAfiJZtxk5c/Fy7qaIYqO7L2dEFXYKPEmmYzeovIskkKxnm3qxk8d6AMC
Tt7Yqm+KuxVvFXYq7FXYq7FXYq7FXYq7FUp1rT9J4XGpahcz28EUH+kSJczQRrFGslWIjdRXjK1T
16fyikok8gxNc2Fadr+h2GsHVGttfishyLXF3qDz26IwNXk057uSeNAAWq1uOAFTxAzIOGZj+z9N
V9rUMgvr+PJ6UjpIiyRsHRwGR1NQQdwQRmK3t4q7FXYq7FXYqovFHLJNFKgkikjVXRgCrKSwIIPU
HFXjvm7S4PK2uanf6lZi58meaoYnvrpE9STTdShT00uhHGiHi4kBqrNJUM3QUOw0uYgxI+qJ+Y7n
Eywq7+k/YWOnTvKMN5ca3batoiaZMAXhbWCZ2dPiRWmRPrDQK9GCf3vQdqZtRqcYH8fifzuAcvdf
1Vtf0uL4Xu4ff+NvtZN5K0ePzH5g0bVLK0Nv5N8qQtFpE0sQik1C/mZYprxomRiF/dk1Zg/Kh/aI
zUanKTZP1SPyHc5eGHKvpj9r14RRJd80RVeRWaRgACxHBQWPfYAZguUrYq7FXHFXVxV1cVdirjir
WKuxV2Kt4q7FXYq7FXYq7FXYq7FXYqkHnvTbzUPLNxDZxfWJoprW7+qf7/S0uY7h4N/9+pEU+nLM
RqTDILDyS31Pj56j1Ya0l3FweGDSoHU3zysJdzYGT6ws7tIEbmiqooX5AbbeU4+ER3gbdOY68nBA
PHf4+TM73yj+YcXlTyjpmh6oljcaUsKauvMqGVEUBVYI/NIiCOJFGHXNYMkOKRI5uWYSoAFLn8l/
mdE0seiS2ehWsmty6jJDbXBIeCZUAqBAo+FoyzJSj8t+m8vEh132Y8Eum26ItPJX5jU0a51LU3u7
vTNSNxdRLfyxpPE9sY3YFYBxX1vjEJBATkoIrTAckN6HMdyRCW1lM28sefYptHlg1Z3aO8kn1dZr
mRo2hMymNETh0EAYUrTkeh6jajW6QiYMP4QIVEXdbk7/AM77Pk1eFk2o9d9/x0Z7mhcx2KoeQJ9Y
YuHoUUApzpsW/lxVSjitntVilSVlZAsiMJSCCKEEHFWDSeR9Dbz1FPF5cgXTUj5TXDWqUaQhm5K3
ENXkwH39sn4su8sPDj3M5eO3WJEjWVVUoFVRKAFVh0HsMgzVYwn1hSgegRgS/Om5X+bFURirsVdi
rsVdirsVdirsVdirsVf/2Q==</xmpGImg:image>
+ </rdf:li>
+ </rdf:Alt>
+ </xmp:Thumbnails>
+ <xmpMM:InstanceID>uuid:85aa9f39-374a-4543-b780-692900efcfd8</xmpMM:InstanceID>
+ <xmpMM:DocumentID>xmp.did:7ea84e42-dbd6-44b6-aa4a-ae890787dcc6</xmpMM:DocumentID>
+ <xmpMM:OriginalDocumentID>uuid:5D20892493BFDB11914A8590D31508C8</xmpMM:OriginalDocumentID>
+ <xmpMM:RenditionClass>proof:pdf</xmpMM:RenditionClass>
+ <xmpMM:DerivedFrom rdf:parseType="Resource">
+ <stRef:instanceID>xmp.iid:398274e3-b6fb-4d1f-b6a1-e910efd5cf2f</stRef:instanceID>
+ <stRef:documentID>xmp.did:398274e3-b6fb-4d1f-b6a1-e910efd5cf2f</stRef:documentID>
+ <stRef:originalDocumentID>uuid:5D20892493BFDB11914A8590D31508C8</stRef:originalDocumentID>
+ <stRef:renditionClass>default</stRef:renditionClass>
+ </xmpMM:DerivedFrom>
+ <xmpMM:History>
+ <rdf:Seq>
+ <rdf:li rdf:parseType="Resource">
+ <stEvt:action>saved</stEvt:action>
+ <stEvt:instanceID>xmp.iid:1476678f-4225-4c9c-a267-6046897ef9a3</stEvt:instanceID>
+ <stEvt:when>2021-09-28T12:55:52+02:00</stEvt:when>
+ <stEvt:softwareAgent>Adobe Illustrator 24.1 (Macintosh)</stEvt:softwareAgent>
+ <stEvt:changed>/</stEvt:changed>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <stEvt:action>saved</stEvt:action>
+ <stEvt:instanceID>xmp.iid:7ea84e42-dbd6-44b6-aa4a-ae890787dcc6</stEvt:instanceID>
+ <stEvt:when>2021-09-28T14:56:53+02:00</stEvt:when>
+ <stEvt:softwareAgent>Adobe Illustrator 24.1 (Macintosh)</stEvt:softwareAgent>
+ <stEvt:changed>/</stEvt:changed>
+ </rdf:li>
+ </rdf:Seq>
+ </xmpMM:History>
+ <illustrator:StartupProfile>Print</illustrator:StartupProfile>
+ <illustrator:CreatorSubTool>Adobe Illustrator</illustrator:CreatorSubTool>
+ <xmpTPg:HasVisibleOverprint>False</xmpTPg:HasVisibleOverprint>
+ <xmpTPg:HasVisibleTransparency>False</xmpTPg:HasVisibleTransparency>
+ <xmpTPg:NPages>1</xmpTPg:NPages>
+ <xmpTPg:MaxPageSize rdf:parseType="Resource">
+ <stDim:w>595.276000</stDim:w>
+ <stDim:h>841.890000</stDim:h>
+ <stDim:unit>Points</stDim:unit>
+ </xmpTPg:MaxPageSize>
+ <xmpTPg:Fonts>
+ <rdf:Bag>
+ <rdf:li rdf:parseType="Resource">
+ <stFnt:fontName>RobotoMono-Regular</stFnt:fontName>
+ <stFnt:fontFamily>Roboto Mono</stFnt:fontFamily>
+ <stFnt:fontFace>Regular</stFnt:fontFace>
+ <stFnt:fontType>TrueType</stFnt:fontType>
+ <stFnt:versionString>Version 3.000</stFnt:versionString>
+ <stFnt:composite>False</stFnt:composite>
+ <stFnt:fontFileName>RobotoMono-VariableFont_wght.ttf</stFnt:fontFileName>
+ </rdf:li>
+ </rdf:Bag>
+ </xmpTPg:Fonts>
+ <xmpTPg:PlateNames>
+ <rdf:Seq>
+ <rdf:li>Cyan</rdf:li>
+ <rdf:li>Magenta</rdf:li>
+ <rdf:li>Yellow</rdf:li>
+ <rdf:li>Black</rdf:li>
+ </rdf:Seq>
+ </xmpTPg:PlateNames>
+ <xmpTPg:SwatchGroups>
+ <rdf:Seq>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:groupName>Default Swatch Group</xmpG:groupName>
+ <xmpG:groupType>0</xmpG:groupType>
+ <xmpG:Colorants>
+ <rdf:Seq>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>White</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>255</xmpG:red>
+ <xmpG:green>255</xmpG:green>
+ <xmpG:blue>255</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>Black</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>29</xmpG:red>
+ <xmpG:green>29</xmpG:green>
+ <xmpG:blue>27</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>CMYK Red</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>226</xmpG:red>
+ <xmpG:green>6</xmpG:green>
+ <xmpG:blue>19</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>CMYK Yellow</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>255</xmpG:red>
+ <xmpG:green>236</xmpG:green>
+ <xmpG:blue>0</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>CMYK Green</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>0</xmpG:red>
+ <xmpG:green>149</xmpG:green>
+ <xmpG:blue>64</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>CMYK Cyan</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>0</xmpG:red>
+ <xmpG:green>158</xmpG:green>
+ <xmpG:blue>226</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>CMYK Blue</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>49</xmpG:red>
+ <xmpG:green>39</xmpG:green>
+ <xmpG:blue>130</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>CMYK Magenta</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>229</xmpG:red>
+ <xmpG:green>0</xmpG:green>
+ <xmpG:blue>126</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>C=15 M=100 Y=90 K=10</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>189</xmpG:red>
+ <xmpG:green>22</xmpG:green>
+ <xmpG:blue>34</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>C=0 M=90 Y=85 K=0</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>229</xmpG:red>
+ <xmpG:green>51</xmpG:green>
+ <xmpG:blue>42</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>C=0 M=80 Y=95 K=0</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>232</xmpG:red>
+ <xmpG:green>78</xmpG:green>
+ <xmpG:blue>27</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>C=0 M=50 Y=100 K=0</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>242</xmpG:red>
+ <xmpG:green>145</xmpG:green>
+ <xmpG:blue>0</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>C=0 M=35 Y=85 K=0</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>248</xmpG:red>
+ <xmpG:green>177</xmpG:green>
+ <xmpG:blue>51</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>C=5 M=0 Y=90 K=0</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>252</xmpG:red>
+ <xmpG:green>234</xmpG:green>
+ <xmpG:blue>13</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>C=20 M=0 Y=100 K=0</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>221</xmpG:red>
+ <xmpG:green>219</xmpG:green>
+ <xmpG:blue>0</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>C=50 M=0 Y=100 K=0</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>147</xmpG:red>
+ <xmpG:green>192</xmpG:green>
+ <xmpG:blue>31</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>C=75 M=0 Y=100 K=0</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>57</xmpG:red>
+ <xmpG:green>169</xmpG:green>
+ <xmpG:blue>53</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>C=85 M=10 Y=100 K=10</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>0</xmpG:red>
+ <xmpG:green>141</xmpG:green>
+ <xmpG:blue>54</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>C=90 M=30 Y=95 K=30</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>0</xmpG:red>
+ <xmpG:green>102</xmpG:green>
+ <xmpG:blue>51</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>C=75 M=0 Y=75 K=0</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>45</xmpG:red>
+ <xmpG:green>171</xmpG:green>
+ <xmpG:blue>102</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>C=80 M=10 Y=45 K=0</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>0</xmpG:red>
+ <xmpG:green>160</xmpG:green>
+ <xmpG:blue>153</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>C=70 M=15 Y=0 K=0</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>53</xmpG:red>
+ <xmpG:green>168</xmpG:green>
+ <xmpG:blue>224</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>C=85 M=50 Y=0 K=0</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>29</xmpG:red>
+ <xmpG:green>112</xmpG:green>
+ <xmpG:blue>183</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>C=100 M=95 Y=5 K=0</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>45</xmpG:red>
+ <xmpG:green>46</xmpG:green>
+ <xmpG:blue>130</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>C=100 M=100 Y=25 K=25</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>41</xmpG:red>
+ <xmpG:green>35</xmpG:green>
+ <xmpG:blue>92</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>C=75 M=100 Y=0 K=0</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>102</xmpG:red>
+ <xmpG:green>36</xmpG:green>
+ <xmpG:blue>130</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>C=50 M=100 Y=0 K=0</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>148</xmpG:red>
+ <xmpG:green>27</xmpG:green>
+ <xmpG:blue>128</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>C=35 M=100 Y=35 K=10</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>162</xmpG:red>
+ <xmpG:green>25</xmpG:green>
+ <xmpG:blue>91</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>C=10 M=100 Y=50 K=0</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>214</xmpG:red>
+ <xmpG:green>11</xmpG:green>
+ <xmpG:blue>81</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>C=0 M=95 Y=20 K=0</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>230</xmpG:red>
+ <xmpG:green>27</xmpG:green>
+ <xmpG:blue>114</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>C=25 M=25 Y=40 K=0</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>202</xmpG:red>
+ <xmpG:green>186</xmpG:green>
+ <xmpG:blue>159</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>C=40 M=45 Y=50 K=5</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>163</xmpG:red>
+ <xmpG:green>137</xmpG:green>
+ <xmpG:blue>122</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>C=50 M=50 Y=60 K=25</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>122</xmpG:red>
+ <xmpG:green>106</xmpG:green>
+ <xmpG:blue>88</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>C=55 M=60 Y=65 K=40</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>99</xmpG:red>
+ <xmpG:green>78</xmpG:green>
+ <xmpG:blue>66</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>C=25 M=40 Y=65 K=0</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>201</xmpG:red>
+ <xmpG:green>157</xmpG:green>
+ <xmpG:blue>102</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>C=30 M=50 Y=75 K=10</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>177</xmpG:red>
+ <xmpG:green>127</xmpG:green>
+ <xmpG:blue>73</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>C=35 M=60 Y=80 K=25</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>146</xmpG:red>
+ <xmpG:green>95</xmpG:green>
+ <xmpG:blue>54</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>C=40 M=65 Y=90 K=35</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>126</xmpG:red>
+ <xmpG:green>78</xmpG:green>
+ <xmpG:blue>36</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>C=40 M=70 Y=100 K=50</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>104</xmpG:red>
+ <xmpG:green>59</xmpG:green>
+ <xmpG:blue>17</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>C=50 M=70 Y=80 K=70</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>66</xmpG:red>
+ <xmpG:green>41</xmpG:green>
+ <xmpG:blue>24</xmpG:blue>
+ </rdf:li>
+ </rdf:Seq>
+ </xmpG:Colorants>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:groupName>Grays</xmpG:groupName>
+ <xmpG:groupType>1</xmpG:groupType>
+ <xmpG:Colorants>
+ <rdf:Seq>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>C=0 M=0 Y=0 K=100</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>29</xmpG:red>
+ <xmpG:green>29</xmpG:green>
+ <xmpG:blue>27</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>C=0 M=0 Y=0 K=90</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>60</xmpG:red>
+ <xmpG:green>60</xmpG:green>
+ <xmpG:blue>59</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>C=0 M=0 Y=0 K=80</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>87</xmpG:red>
+ <xmpG:green>87</xmpG:green>
+ <xmpG:blue>86</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>C=0 M=0 Y=0 K=70</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>111</xmpG:red>
+ <xmpG:green>111</xmpG:green>
+ <xmpG:blue>110</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>C=0 M=0 Y=0 K=60</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>134</xmpG:red>
+ <xmpG:green>134</xmpG:green>
+ <xmpG:blue>134</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>C=0 M=0 Y=0 K=50</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>156</xmpG:red>
+ <xmpG:green>155</xmpG:green>
+ <xmpG:blue>155</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>C=0 M=0 Y=0 K=40</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>177</xmpG:red>
+ <xmpG:green>177</xmpG:green>
+ <xmpG:blue>177</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>C=0 M=0 Y=0 K=30</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>198</xmpG:red>
+ <xmpG:green>198</xmpG:green>
+ <xmpG:blue>197</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>C=0 M=0 Y=0 K=20</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>217</xmpG:red>
+ <xmpG:green>217</xmpG:green>
+ <xmpG:blue>217</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>C=0 M=0 Y=0 K=10</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>236</xmpG:red>
+ <xmpG:green>236</xmpG:green>
+ <xmpG:blue>236</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>C=0 M=0 Y=0 K=5</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>245</xmpG:red>
+ <xmpG:green>245</xmpG:green>
+ <xmpG:blue>245</xmpG:blue>
+ </rdf:li>
+ </rdf:Seq>
+ </xmpG:Colorants>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:groupName>Brights</xmpG:groupName>
+ <xmpG:groupType>1</xmpG:groupType>
+ <xmpG:Colorants>
+ <rdf:Seq>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>C=0 M=100 Y=100 K=0</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>226</xmpG:red>
+ <xmpG:green>6</xmpG:green>
+ <xmpG:blue>19</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>C=0 M=75 Y=100 K=0</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>233</xmpG:red>
+ <xmpG:green>90</xmpG:green>
+ <xmpG:blue>12</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>C=0 M=10 Y=95 K=0</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>255</xmpG:red>
+ <xmpG:green>221</xmpG:green>
+ <xmpG:blue>0</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>C=85 M=10 Y=100 K=0</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>0</xmpG:red>
+ <xmpG:green>151</xmpG:green>
+ <xmpG:blue>58</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>C=100 M=90 Y=0 K=0</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>40</xmpG:red>
+ <xmpG:green>52</xmpG:green>
+ <xmpG:blue>138</xmpG:blue>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <xmpG:swatchName>C=60 M=90 Y=0 K=0</xmpG:swatchName>
+ <xmpG:mode>RGB</xmpG:mode>
+ <xmpG:type>PROCESS</xmpG:type>
+ <xmpG:red>129</xmpG:red>
+ <xmpG:green>53</xmpG:green>
+ <xmpG:blue>138</xmpG:blue>
+ </rdf:li>
+ </rdf:Seq>
+ </xmpG:Colorants>
+ </rdf:li>
+ </rdf:Seq>
+ </xmpTPg:SwatchGroups>
+ <pdf:Producer>Adobe PDF library 15.00</pdf:Producer>
+ </rdf:Description>
+ </rdf:RDF>
+</x:xmpmeta>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<?xpacket end="w"?>
endstream
endobj
3 0 obj
<</Count 4/Kids[5 0 R 6 0 R 7 0 R 11 0 R]/Type/Pages>>
endobj
5 0 obj
<</ArtBox[0.0 420.24 595.276 629.214]/BleedBox[0.0 0.0 595.276 841.89]/Contents 12 0 R/CropBox[0.0 0.0 595.276 841.89]/LastModified(D:20210928145655+02'00')/MediaBox[0.0 0.0 595.276 841.89]/Parent 3 0 R/PieceInfo<</Illustrator 13 0 R>>/Resources<</ExtGState<</GS0 14 0 R>>/Font<</TT0 8 0 R>>/ProcSet[/PDF/Text]/Properties<</MC0 9 0 R>>>>/Thumb 15 0 R/TrimBox[0.0 0.0 595.276 841.89]/Type/Page>>
endobj
6 0 obj
<</ArtBox[0.0 107.252 554.331 774.782]/BleedBox[0.0 0.0 595.276 841.89]/Contents 16 0 R/CropBox[0.0 0.0 595.276 841.89]/LastModified(D:20210928145655+02'00')/MediaBox[0.0 0.0 595.276 841.89]/Parent 3 0 R/PieceInfo<</Illustrator 13 0 R>>/Resources<</ExtGState<</GS0 14 0 R>>/Font<</TT0 8 0 R>>/ProcSet[/PDF/Text]/Properties<</MC0 9 0 R>>>>/Thumb 17 0 R/TrimBox[0.0 0.0 595.276 841.89]/Type/Page>>
endobj
7 0 obj
<</ArtBox[0.0 119.407 380.847 783.527]/BleedBox[0.0 0.0 595.276 841.89]/Contents 18 0 R/CropBox[0.0 0.0 595.276 841.89]/LastModified(D:20210928145655+02'00')/MediaBox[0.0 0.0 595.276 841.89]/Parent 3 0 R/PieceInfo<</Illustrator 13 0 R>>/Resources<</ExtGState<</GS0 14 0 R>>/Font<</TT0 8 0 R>>/ProcSet[/PDF/Text]/Properties<</MC0 9 0 R>>>>/Thumb 19 0 R/TrimBox[0.0 0.0 595.276 841.89]/Type/Page>>
endobj
11 0 obj
<</ArtBox[0.657425 173.041 551.673 774.782]/BleedBox[0.0 0.0 595.276 841.89]/Contents 20 0 R/CropBox[0.0 0.0 595.276 841.89]/LastModified(D:20210928145655+02'00')/MediaBox[0.0 0.0 595.276 841.89]/Parent 3 0 R/PieceInfo<</Illustrator 13 0 R>>/Resources<</ExtGState<</GS0 14 0 R>>/Font<</TT0 8 0 R>>/ProcSet[/PDF/Text]/Properties<</MC0 9 0 R>>>>/Thumb 21 0 R/TrimBox[0.0 0.0 595.276 841.89]/Type/Page>>
endobj
20 0 obj
<</Filter/FlateDecode/Length 23362>>stream
+H�l�ˎ�I
�����w�/�+�-�-fu#M�/�wYU TRf����O���������~�?|~�;�r���QW�������_�>NW�>��(�J��W��H�_����=��������������߿�����:�|��ʺ[�{���=~z��Hג�����]渞G����%[�?~ʱ_�
~��,�C�s�[������O��\��e�ν]�2�����.KǴr'��,��9__��4������{�κ$w�_��"���绗7�Sa�"눺Y˫���u�<W�}/�;�z��������N%[n���BT��Pk(j��%m��'H�����Ps�YK��a���
+�dž6�d��+�Y���q�L���1;�^ɫf�k��;���uZ����Z^���ިq�4�[����|,�VB.�r��ؑ���J�%Ěf�3\(��
�ǡ)��qDRɄ�n���K�U�5\�mZ�gyHy���U�4_��J��u�x҇ҹ-��\3?/}w[���|�f���8ơ�g����v�Ԓ������Թ��CW���U�Yy��رnW��Gz���S�ŜwR3�~��FrU]��4FF�%�ގ�Z�v'v���&�:��Z�GyR6��j��J��}��^څWS,M!Ω���E�(� ,lX�4�pf��lM�9$o�\�JG�N�gȣ@:U�L�mC���6���З
�v�:Y�N���]�+�{.ZG��5-����(�w�zv6��s�H �"e��<�����j-������е��尺^�jFsQ��V�(���y����V�Y�p�V�V{�e��y�ȧL�\�r��iFI9���85J���Fns�S�bNㄒ�?�%@.����)�hF3)l��
+�^�sB�e7�,+j �cEv��v6U�Bv�-�� ��Kd�Nw�]a��k�S�(��"�ˬ�
�hv����W�&IpV�&p�h��T"kŁjM���Љz@U<+����-p
+h�Ԇ��mC7��ͧ�b�
H��0bO�s^�Q��b9`bJ���Lʻ,��Ӧ:p��|1ܓ\\Q�3J��
+♢Ѹޣd{d�z2Ճ�Uåvy�J�@���k�VB�W�:��}�����@>9���KWJ�$�[r�+��]C�-������'d�Xe&�<���w�����i��!�h���_�v��}����@�����G4V����\�'�ͥ�ߖkP
+ <����u����l�m�V�f�Vp��Rn�z���o$���\�~���B��9��!�S�`���
+�U��5��(4nM�r%6 #v
+U���dv��%�P�Q��Ct�$4Mp0KS<�?ӽ�Z�3�Ԛ⠼��R���H��E��c$6�@m��dpt�[����%�nZaJ=
+����D�fD��[/jv��%Ťn�8�~T�}��`�����*�,��J!�3I���_J�ǝaV��}�0�zI<T��ѱ�UV5���7u��U�
�O@0*�X��11�)k\u�����JWh�*8 慡�
+��L���k]�vҼ^_�U��E�%x�b�Vu������Qk�{�U%F��H�k3+%9���ʯ9iS)Q��&��}�3s��@0s���*j�JU�s�����N��s����"�ֆХ�+�OOM��2=.�I-��r�'��7X�Ķ<G�2�9G��s���ʚ�ŀ?��2R �l��2����6�ԏY36�IӔ
5CV�plҿC�5,��H����x��&��Չ�'�Q]銅H&ZKik�{����[�r�s�g�~Ve����:x�&�jY���`;�k�i�Hn��z��!J+��Y�0��x���������u�)
.5�i�
�_�E��1��P}���&�m����K~F9����Jl�u�T,�p��o(p�����=A���Ԥ��睇���>Է��kF�7,�vP
+�*(�
+�iX��(�A!��^��g^�?�)Ms9Tiít���~��x��٤��>�/V͊鄋�&���eD�'���%�~gOy�2�T4y�MҘ��G�u���`]�di���}1z��]��@�g_� �~�yN�X�)���o�F�P�������Q�3�cPª�0�i�C�wHIB6ȱx����Գ1����/j��9��O�T�f��(e#��D�!���35���:�\��FD��U���3�I�S�wp��`�v��<Ύe�!��4,^)�
0h�,�5�*����n�4�����/� O+p�$|{�Z���..�-rP��Ն/�i�:�*H���#˛@�w[4�i.�zV���J�G
3�p�j�^���WMף5�4��~B|�|E���k/9/����?�}4D��M�Ef�������~y������>~~���˕}��]��G�5�Tv���O�DZ�O C���������Ev;DI�|�5^��J�qf
�������yL}��g=������f��o���pZ�����7/���c�ݪ�v����_)�.%8�����DX6
���DT5x��(i~tS^�t��n�Nv��*��!T��ܯ�D]���!�!��=�A� �h�C`���,(�@2F�8a��P���t� T6tR�ed�|�e����N��t&������2ǎ,ׁ�_��
H����[���
�Rm|GU`>N �Ża�{
��\�y����(�i�'Y:�����/����b��V���?��_�MPM1�
+�}E�<��%�Lk��� �D������l5��QX�0��I����Y����2��g��I� ��R0�f����f%Y6|��'��Vl%�X�:��kq�UI�ˉ�,vS��DvL��f��?]9�(�*�C�A�YN�3�X��?�L���������n甆V�5��5d��.2ڱ��=��B�&5�؎��\�@��B��I+�����$g0j��|b���H�g�."/��z!u��}��h��#Q�����JO�N�[߅�ϟ��M��Z":R=��;*k9�f�?ďSqv+<�(IG<(كܔ_���t�8� ԁb#K�(�D���"j�:Ь^���v�
+� f�"��BT���R�er�=��Z1jhi�$��a�:u�ju%��/_���&�Ĩ]�!��P�('�k�
+�Z�}M+X�a!w�ʺm�
����"�D��f��ˇj
���-z����;��~z3�B@��$�/ ��|�L[x>�|L�v��cRu��2�-���\�
+~�a�8��k�"&�s�qRReC���5��� {�X��B�8�>r4�ܕ�h$(5"�i�'p)��j�@��U���'5pdw�l�L�V��A����塁Z�,��M{�VM�0�~��1��9�r��E�@PaW�$}a�f�w^��<��:?GP��N�c!�`��c�U����NM��r2I�W*��W�M�I��ae��7G�Vl��o]Jjn
��"�87��bkIRމ
+W0��Y���d"岇�'+��b�nޟI�ޖ��3&S�|v��9�lFy�z��U#lÀ���L�O#��̜��+}�����I�=2�ўG�E��\Tg��u��G0���|'��~��#Wr�t����o�+�~~WH�ɜ+�J�g�ɭ��z�/�?.�b�n�t��r{�͊G�=ד����<7)ۤ���ޒ�ܧS.��U��N')���oj#-��S ��-I�3MS�2Bͳ33n�a3=o�skS�r�K�����%'W�M#�X��͚e���:�tv@��yDz��'���r�o��}r���x�`�p#C6{NA&Xc��3�Ǐtٕhޯg����;�V7���k�hh�I�"�]�i���y��±^��7��1����
+Uw4�J��8^cs�������>9�9�g����d����,�C�
+���%���m*r�R��]�����}>L�ɡ��2
?�˭�w愐���n�-��9����'�@�����(��G�IS_��=���>_I��N{T�3+`u�7[o�us괨a��9��m_��Y�z�q@���:��"Z�P�R�a�zZH��P���m��
+��y����ߞwc^�:bU�:���yE���l#j�NJ-���d�nv��ZJ��� _��RE�HY噯��I�W�l��{�"e3�����H]�71|�6k5�{��"�כݚF"�)��\��$��g��4��\D������K����w�t�T�e�PTK�;�a
U��,���z{G���k�Ⰺ���?4��pr�ġ0�r�J%9���W���WX�0�u/��� 5��T:�Q�2�9��Z/��'Y�[mT�jk��r����A��]�=���آ�IfB���c�Z���' �V�����a�@1gt�qF�I�)��}�B�=[g ��y$��NZu��U�}�)�Sϴ^kZO�cܗ:pY�j�Co�4tU�#�Z�)��N/[0BS:�ݗ��Ͽ��y��^B� ���>})$����Ee,\:"3�ͯ�Q^-�U']�'����Q�,�W�(����WW�uؖ�R��v{�BC��#ʗ�~*w3 �����j1�h1m�T����ݑܝ�c�o����=���*�pb�l��B�w.u�3���"���T�����$u)R}�����/ꉯ�6�z�|<l`�`H��ME��\`�ec]Y&h�
+L�©w%~��!��m-�o�k��V���Z�@��@`o��*�*L:P�*�w�?d�^�M(O��a��F�Ԝ�������.@�!�[�ڰL� ^ݿ+8{$�a�2��1*�Fȥ�:;���@G�Ա��1p�Y2��[�2����ބ�U2�J�ߝ*1Y��j�)��u[.]E��d8;H����@�L����1Q�mB�\�UK��LR�W��E�q$�D��i����T5@)(b�"��Cd�{�s�����چj�R��ť���ݷ����q1�+ ��7���4�g�����d�J�a-�e��=@��X���F[����pL��-�;SʅD�H�
4� V�c��ۯy�����~$We`B�ۿ/�$wԋ*I
+�I")nS
L������m:��}Oס�h�@�ԗ���R=�����ën����u�+�)���[IL���kՍ{j�\����
p��F`n-%��spbR4-�����+�����S�t�sp�fm����v��R��-�iZ�#�{����^�5sx�������48k3��ʀ%��k��}��,���[��C����/�{ʇm�%4�E����(���T�x|�ݪt�j� c3�PY����ȼ�]�Z�be@dRO�B���Hx��fT*�A}+�?u<
+��S�.����Q�*�ˮu�R�vpO�4��QY���\���)�f�2+)���08�C�beS���h��XB=d��-t'H�9�)�o�}��E@����b?x�^Y��|J���\7^|%�SLq�Y�m#l8}�V���@����%|�
+���)�6�CT��PxT}"�P!A=�!�~"��nu��}�ٔ�Pa��q�ULMn����7�U���C�XqpR����L��ؕ:����������?���T��2��!�n�q3��T��Ae�*PXީׂ�;�\tF+Tv5"?���W˩�T�
+<�8>��'!���w�^,Z�Gf�O�����M��(���hzRB�2O��*Z;:��&�}��2�)u
U��O<(5Ż2���e���a�Ɓ�9W���c��:y'��-O��+��%���,X���8��_ޞm ����܈2:�Z>�*V�ϼ������;O��Ot���;0�)
+��g�+��%�c���N�ͺ_R���#�Nc�=��0"_�5��u��$�I �������\ܔ O�;r�)�KE���l϶�w����J�����kRl��v���3ym��໖��@5Ռ^��Ro
+��b�YW����&M:n=��Mq���*"*��y�������퓎��������VR���*,u��������d`�j�{Z�c�T��v>�m�y��U�$]%��}�g���*^-�'�����j寭�����ǣ�;���'O�Ց=�3� ;��t��A�P��:�ȑI��?C�v�Q���
f�
��LJSWaj�&\2]�cs�Y����[A�Z!�h��� �G�� ���g���J�B��fiB8�{�P��<������N�翿�WR᳡��x�g�<� %��b5niaa���Vb"=9&��ˣ�ryv��R�e]=�U�Q��V��\���qlDƴ�'MJo���`7(:[wt<Z�L7��e,��&�����COQ|kEJ3[�b��N�A'��h��������B�hb��+ ��]�Z��d�R|T��{.��*���;�%�%~7����ǥ,x�o4�}������<�h5��f&���}��ϗtK�T��c/ܭ�X�662�Y����+!M��ta�o�{�tŲG2�m=1(��%�����ԕز���EZ�� �� m��tX�և����jD�>
��ir����WKβ�<C�d��wKh<�.��X�{�t9�/=�m,J�_�P����7�m�9wu<�]J
+X��%͊l�|H�=b���Zͮ��O��T����͌\�(���������W��ɲ?�W�i]�+d�S�T�����Y�#.�8C�sP�Q�����b9W,PK�H�`���#��H/ֲ����u�^��ك< _"�~IC�&蜓��
�uQ-�P�lf��Tp>�N��%6�¿Ӳ���ۯ���'�R�-?����`���������ze9Q�L��<��L:ǾPP�y���YB�l=B$*��S��B"�f2lXͨ�aE7s����A>�\+�
���}x���N��e<�"o���s�iå�V1�ohB���5=2:��X�\��-B�x)(T]WD�ё��)�5�+��e�;�}�B�dZۙt�>�\���l��l��رyu�:©�;��B�;��Ei��}ܿP��s���3&�\��mO"^��d=�5���@!>Zw�B�na�ќ3��=���/B5�Ɲ��z&���zN��~��Ri���O�+�2�t���2<�F�Z�Ƿ�]���^�g�p�7�s`������=����~�����Pa��sC����r��N�m�v�$\�O&���&�9i5�9�$�>���WE16G��M��/�"�7ָjg��j��j�U突DB��/RzVN��{Cs��@�O���Ȉ�q�/Ul�#�!-
+@G����Q�/Z+�^ʪ�$���a�C?�c��;����v���?�|o�t�5�
+^�P�
>w�J�x�75Ѽ�ǰ�g�^�6�{��I)B�b<R8��V�GJ�uQ����/0?������`��ꮉ�1~�e�d�<�|������b�z���v.�������I3��VunG�RAT�4�RhW�v�i�0��{���ۯ*��l>:����)��l���F"u�Gj�<�ߥm����[I���ES�H.�_wB��K4�U��Fا��;���R��L
+����v����K�hAy�l�'0�L�T�UaQ-%N���Us�
+s�(z�Vh|)����T����TՍ�ڈUՑf�oD��M�l\I�-9��)5�4C�~jj[b�-k��J�yx�l~��m*�ݚ��Q���QBΝ�E��/D,/:���3��"���UI�H+����U�NU�cϗ%����'7��1��.Ox�e�=>���U�n��;g�w7��;T=<<�w�6ϸ�7�i�������{�����$-�S��[9��U�4�N7������T��@�@���Ա����5�ֻ^�B�]K<�2�[^����nj�υ�T����BA��i����VB���X^���x��4�ҟ�U��-B* 0#J���Eč@lO���.]�L��Dby����Ҥ���� ����W��! �ZR�+�Q2n�lhǜ�j��l7�7Ljښ�坴��i�*Vc�z�WƮi�R01Ma�����2Y���VԷnP��[�G�&�/aϏ
+����0��?��1q��+���q�����dU>�L}-wA��8��:vҿ+m9 �ӂS�B��@�Rn(P�߫qv�x,$u��gܯ}�]&".���nC�������{V���W�b. av�bk��u�/!���3%j�:��T:��5p�I��A�r�^�?I+�*g^���dR��yg���,��g�ؼp~�h�xz��Av�����Uv ���6�G��(UA�������,ʐ���VTFQ5�2?��x�z��ÈRn�R��<�Y.��'rEB���!
�����{�4S�:�q��5Lg�^�����J�^�B
���]?�
+��� �R�Ώ�Y���vK��&2��%��LЅg�*S�zP��g�CZɝʩ������|&?��A}��u�O�0
7<4�R�Z/)�����B����_ظ]��v) �ҍ��
+*�R���\r�8b ��)�c$���Vk�����=�7Ұ��*���!䩷!��1E���"���T��Uf(�e�!7�=�c�z��nG��]�iE�#F��s�(.��:��غ��O���C��h\-=)�Y��zx8���[n�Se31�ϘUm�tx��qe�k�1��Y�����������x�곳&B�'.W$)O�V�I���7˹L��?�.��^i��tyͲ> �.�-�����ؙ�$E무��;Q�˾�Yp�d;^�_
+*IZ��
7(�}�Gj'�I����e�-}?j5�u���,l����dB����Z�yZ��f���5oXO:���
+V�#���ӫ��N�}��KS��\�LF2��'��|l�ʓ!L�K��͊'/�S�zС1��[�1����l���!�Ɍ4G���B=�"��Z���߶Ӽ&1�b��֎�ܣ���6��-)\��C�vؼy�u���������}�Ę��|�.���e����,�m�Q�3Yv�eI/""�)�-�ٵ4�o���N��M8�V�b��/CP8�O��5�j�'�K�
e���m��5�.k��`���J�r�Ѵ�*u��x��h�Y6�Jr!_kYZb,�vM�Uӗ�_�HC��I�4m��9��ڢz��Z�L*�,b��my��ج&;\s��'Á��Ԯү�wk�0a6dD�Ц��h��b��]��}l��H�D�N���������K�;�Qru&��4���S*;a ��������ޚ���~ގ��"U"�?���n
+������Vh�ז��u�1�1���u��n'��RW?j|+��LL���8�v���nY�`��.�l:((���6��_ְ��,������m��
+a����Îb��?5�����d�⠃W���� �$�Gp��u�(���l�:�%m����M�gZ �(�_�؛��}�h�����5`�J3$��tE��cj����Td���~CSM�����O�j�;�%��D��tk"++���VY��k3��
W5�sG�[�����m�J5*io*t9��j�ɐ��`�܅�\ۭ�}Ů�:�ؠ r6U�f��+�2���W��-l�e���t�
��CWo�|'������Z�P��^?j���,=^�9��=�0$�j�Ω�aDŽ����\�4e5��&���\���ᔤJ�٧��8nV�9ӵ0X��Vd6���]���;m��f<=��T���R?��"<����/n�Y���K�)tq�*�U<q_e�՚/&ܨ��G�Qm�"O:�
Պ?�>d���ܘ
+d726��a��^D����9���n��B�U�{w���T>=kM>X>JU?Ut�P�J?���.V�m����t,���R-S~�)b|L9��I��2�`�[��w �\�K�r�OK8�� ���ߖ�T�K'B��)K2�SZQZ^�I8����j̢�bI�zi���ݰ�g���`�����R=�O�"��Gʰ*
+Q����1?���I�u�� L�w�e�$�?+1�]�
+�n�͛/�!�t��qIq3K
+���=��<�yVknH�k7+�
+vS���X��TMT��:��~δ_�US[����*���vAfQTC�_���13B����|-1�;?�ng�_C����靯�mύ����L�}{Xt���oſz�L��c[�TVI�v�䅺�N��.�;|aW�t���1�
e��V�y�Q�u8G!��Ѥ�o�vN���U�c�-\�y
��߯$�>���q=_0?#�����p�HP��y'�[�qM}24��6UN�$sED�����ЩF;!]��VoI0b6����a��7�0L��~���L���.p`-{���hC�����1�r�-o$E7`��
+7�4����K���f �Gֻ��:�tj�YEs����0�r���OLN�o�V��,�g��
+��,v
+̏�v0iN��4W�7n�����ܱXj�a���p㒡��a�_��\�z��;v5.�#��ٲJ�>�M S��k�d�?��e4w��nVWZ�cC�v�gV��t���������@u��FO
+�b�s����� ܡ�%�k���ɑ�ZN�'o�O�YG~�s������e� ����ogL�.�آv�!̼W�;5��U=NwH���7�`v�����qM���[
+��J���KT��� c���q�8Y�
���3K�|���#�`:8bם`q���S�g�1��t���e��
+����xf�䐣� �{in��J��'&ZV�e�X��k<|�!���p�G���\��M�$�L����_.����z{���S�Xx���d'��Lq��v+�p�Q���u,".���
����d��ԋ�
��Ye�Q���-�<��q��"ձNcr�R�R O�����+T$岠��}6�̚�Z/�5�©��jEГ:���Ӽ��)v"V��.�j�OY7Dh�:Q�tX���r�8�\�W� �ǩ��C�?�e�5'm�d_��&]{8R���+KL6�bf��\�1�osxH*�ַ�n�P� Jm�;�qMd�5ǁI6�mL�4`;� d�d8�̖�rf~W�u�kW���j-�c��<V�� [+m�n�>�Y��[@!�t��6Le�;1����mk˱|
�c���1r'�Ӛ��-����)g�&{�B��B��ݍ���IMg$*3�jص���1����F��hVQ䊾�����܁5J=S۫��u�b��,|+rN�Z��o�=%Ϫ�AT8�i��Ֆ)UM��S�vP~��M�_���V|�5��b��e�0�Ok�}z{TZ�����>�nO��j��+M��@�e��J���+V`�s^s����=�';�W�8ZV�a��0���
Z�y����l�v�x��9а�+�"����/f����H��V��^����9��j����М� �An�D;ʤ96� 0ֹb��3�)�P�!e�ϫ
�<�l�CÖ��#t�B�����vX��n��y���}��&�5ySc�}�m���_���\+�IlӒ���_�)β���������dV˗2�^�m}ww�5��ѥ�f��"�B��A{��'ֲz5�&Σ�cF�X���vJ�q@�xQ���)=���I�mg�yM��~<�u9t�J�S~E���̢#�Gl4�Bz6"�܊m�#
��"���A�����}Ǽ
+2��!��V \������>�`���"�_�l<W��{��c߿���-b�� �n��LD^&uwq��͚ś�(-f�іQ����[�v9-5�_����4�~����^
���v��KO�q J�cq�z!sQ���rĜ���4FE)��<��JU�5Fo�[P�%�wi|!��.�a����2�b/� �{��M/m�Q���Oٙ���4�U`Q0��Κl��-�]�:�L�?²�y���Sb�Ha����M�%G;��os���²���!0$��D%j��&��kɽ�"�[�N���e���1��@��UwV��NW1kJ��ꦘ��H�4��y�7�M�-ZX���٪GWd�0B^���`P�v2q�w맽T��ۇ�Zu��!�Ãm�*�{Xt�Ћ>ҋ���� �;�|#�G8J�d�����I9�R���Z�:�Ђ2��)�#3�c���\�ͬ��e"��D���V U<i�i���)s
N�]��\\����y���N2$�R�b�MF2Fj ��F�d�W4���~3��;�i�>���sXX
�X�I��$qZѿX1F�#�$>h��۳������G�5[*�h�0��=T'g}8�3�2�y60v����ƽ�nR�͎U檮��@��H��l�r��׆��ߢ����7\�d׆:��xև`��J�y�Z̷Q'��qX��c�*���/�r�Y:�L�?�a���_þ�%�pT����M�ZL`����Rwt����x�l�6/^��b�q�
Ґ>�mu7��t1$�ՂD%+a�9�N��)�����g�У�^�uฎgOS��b����)���P{1틡�q��)���ّڌ%�+���pY��4��w|bOLp�u���ҹ��|c𬷻1�Ͱ&�t��췲d�=��\�Zx���n��Խ�
�:�U�6˨e�Ho[�q�-ǹ��ť�.��5�]�,���ּ�T_���.e��k���SG$$-]���b!p�L/L
@��#��GrAY�(�/;��@&˟�ː_��Ι�a(���X���I���P5~�e�U-&(I��U+�n��� ���I�50����j�.�4��@{S�~�"d�)�a�}���� ^r:P�v�j��I��w��hu:�V��9�<��;NNxx:x�R�7���Aό�؞RXi��ɶn��݆�nzm'���/ͬ6+�OkO�7����N���R5���H`�/`�ѻZE̗����FS;�NjR^EX���H:G��U<���"��,.����=1j`v������^bM/zG����ل��m%\Ϲ���������d-.=T��c�g#/����߬�������y?���1�YJ�~[�l�،�O>�dCn☮|��Y$��ϙTl��^�8WH�V%�~lk$�@k�1W+����\�&���Nu尫@l{
+�T}�bO����.�Nk]A�H��-~2�%Lk;�0`������1���G��gy'FT/�LYʳ��,%�sf������}.�4���B��c�Y^fs}���bMu9!)J<�O��z������r� ��<c�
++iw����s����?he���_s���y��ߵ)x��+�"��g �i��Cp`����,�J�1cH����Ii55��qP� ����}�����$��ѹ��rj���ӲP��������
[��s��Q�:^�a䟃�7Mt��}�g�B��q�&y�N����f/(�ѸSg��"�4��3W_��0F�q|��x2�t���u����I߇/XՀ����_��-�v��;ʦnn��ʌ.���{j)F���}y?݈
+���u$�@'Wxx���
+W<Ht�St>´%���c��f�}e��U��Y���$5�o��CBPhYh�B�c�uF��AS`��Z�'�c�PZhZ;�9��Jq%�쌙b.=�V:�c�'S�=�SJv6{��eT+?Y�J,�/@*��(�94�Ne��TӲ�)�Jy�(Y��|[t�_�;,�3=��ٞ9���+٪��b���4�,@rQ��$��-q
+�.�*$,腬j�W��v|c1Y�qFim��I[�$pnj�e���r�_���e j�2d�ڛH�@���I{[ <��n���z2�a3<�&��2KƼ��[r��|)���gݙ���v
+Z��ӧ�����h�4(��2���� �<H�i��3h�f��-a�D@�@�4�&�h�ItcYӈi�
+����Ҫ���F�dK
+�s��f�3��m�̮vr�8�����UwX���.�7=�z���w��-�^ؖc�N����ߡ�ff&@y���f2+��K*B �����5K!oK%���@��ZU��6F�O�]�)���递�3�A��^R���?���L�Y�S�<.�Ї�/ާ^T�c�{�Ld��3��X��Jq��`Ϳ.�aG�ԟ���Ľ�3�5?#In�u�e���ኊ}��L����|��n:C�ҷ�b�H����sC���C�:q(}O
a�[��ǐ���-�$"1o��{���ǿ��{�Xk�
+�3��eU��E��i�Џ��$Ҹ"nx�>��-O��0��ٙ��S�k�}:��~3��z����)/�I�"��)��j����@�@#!T������#��g�a�2����nnn&�z>@�G�y{<��D<�D�J׳���.��)u�?�QX� ,�`��:�n�HG�� A�V�W3!�vͥ`����Z��~4�}��a�vh��e �i+h�{>���
l�$�By���oT��B%+V6&*�2�����3Ɠ�5�B�
+%����
�e\���6ԝǾv��<�9�����f:Z�N�F4qo��!��d��~���$�Fl�_/:�D!�QR�3�1N�Ƚ?8�������fz�~n*cF�@�IX��Xm��)�gwoF �3�k
�Z ��: d�4�:%Գ�-��{[Lo�e$G�;kMЬѬ���03�������M�r��6WEs`纷&ka��g�����s����(���"u�k�T���U8�
/���,ԑ%��:��D���d�'��`�nE"���)��F��P��������K�/��C(�Rw�(�?�%��m
+��܌������b������r�D�4�D���*7�'e��]�8s��r�UuSJ1�%�"i�%�П�J�� ��?�J�|���i[�lsU�s*sG�Ԗf
F(~����,Z�����݃�c������#}V�R1CO��[0|�v��&�//��T.��-��@��K�� >o�3����8YD/�i���v�;4�;��g��}��p�M'�j�ⳏMz��IE�1V�Cr�,���僴��Y����g��!�D��)5�ۉ
+��($����y��@�u�B���nqc�g�9�Q�ֱiA#9LB���<�ۇ�CK�D���#(Sm�l&�Ő����{`�i���vN��{#�$|�m�$��������i6|�/��p�����#)6�T�n83gҖ�sP��-K�K��.��
+/���TV~�#������c@=O��3
=�fB���_�Z�*�)D�� ��j��U,����?,"b֣���ʹV�m�I�?8B()�%�w��|
�3'����?�^�V�����e5�(�Y��2��%�Xw�g5�+$�
+wo��fU�ܢ�}Ѿ�-�n\��+�C�U���_c��w=Fg�m��}��:��Y4����S��(��r
��lt���W��7�]sH��)���?};6�������a&�F<�g�*i��9����_^�����o��������?{��Ψ��1$�3ʼn������d.��K�)X������,J�@��j����K���SՂ�4�8�vfO���L,�?(��=��W�sR�1�]����MC��иb�b5��v�QPE�
-�M~ѴHF��1�n���x/,�=˰��-kv(}�
��=�[�KD�*X)0���2z#ǒ
++d�u8MM t��}�` ����fo�[�鲀��V�ռH�y}�-�o']�`#�lA%
ͫ�L>��k�c
�Ԗ��v]�&�!�B��L�����>�P��Z:w�|��vILO�H2-�Hb��b6���E�fX��xVӳO@�a���UcL�HSRFD�ʳP�XP��Ь�c<�f��n�����!L�P@S�c���"j�vH҆��C@t�ia����i���>��*u=�1�M����>�q����y��vY��>��0�N$�+}^OigA�)�k� �`, �$$]���yA�+L�����L���ƈ��S��w5J�I*�;�<��H�t�ڙ����uf�D���a#�ӊ��ws�'�*������뤕�-}���_U]�w��Y��&���SX�n]�F{, /:�Ue��j�Z��D3\\�cZ��o�X���`�b�6b����o�B뾉�����&,]-�j����\�7�\�$n�X�x����Бu&�I�F�卶P㪢�g��d� �O��g�K���|��&�ᦶZN��/u��_tWzUp�F�U$�3 /D:�"�!E�ʍ���#@��7�eڠ1��]Ģ��A�xV/�e�z�/�H
�M������$�صm�fw��V�*�Y���/�$�"�&xLJ������k2ሎ��\!�F��y�>9Ks��[+�Ru�E �I�Ռ�?މi>�xNE�UT���DZ��d(PR�1��!�:���fm8IAy�[>��\4�0W8��'��
�(k�8�`�J���RX��qS�u�� R+�*�N`���f愊�"��n�Kih�iu�jN���P��yE85J&��(��-���iz�j{7
H}��#zQ{��
w�F0����;���"oz]�BLo<�ҍU��,�
+J��L��=uܽ?+���� 4I]�Xq[�tEؒ[�������v)��
�k#wH���>G;�p�MԜH�a<+ʖ,%ޫqBa��3==�����I�+�J��� �h��v�o��T�����^JNN�3�&�)J����S
+�!��òb͔�o�݊G�8i�].!�ebA�&UL���9 �&
+�,M����椌�(���^��75/
*�i�K�z{Č�����F��Jkʏ=xC]3�S�-W��)��)N�; v��
+n�J�����4�d�42�F~Nt��{)�J|�p�Z��7t
+��S�epXG�4Fn��ĐU��(l��n5q�ς�R����bd���q�BE�@a��#$s�eN��-8�i.E��G�
�[���QuV�:�]���
�x��� ��# ��E��!��ϡ����
��^{]$���[��x����ims��� �9�� �Ü�h��Z¥u�.�@������t;v�L�`tvSt�C���������/g� w�ξf
�Y:�m��טba(�1��r
8ªԜ����V�Ȼ�>�Ð�3X ��;sW�[�q�^Wͺ�}��M��C��J�<f>��# �D��~[��� N�_��$7����</�BL?�h-�H��^H ���G|2�j@;m����nnn�b+Go<=<��D�o��)Dn%�i�z�����G�/Z�rTf��o�@.���t9g06�G��kF� 9�����v�֑}����
+�Ko�e��/=R�%���b&Pq�����+�����Ͻ��:��wVq�%���)���J�O��t�=�wH����?.,q�[f8.�&�h�c%����C���gڭ�B��9;͍��2�˛��I_%�*6i��yl�7���
+)�:jdPYAſ�M��lz��Y`�n��'���1�9�ڙ�(�:{������;ԛ<Tl
�.c��Ë���W�u��-�$�|/�:�8[,�-w�@�%0����|�%Č|!����]H.
��X+�C9ܽ��lW>LI3�fq8�����d�Џ��8Vs��U��\��N�?)|�+�����;�P=�E�Q
+�OH�*��G���ĉA@��#�ǵK�h1�).=~��6v!�tw��*.�*��1gߦ���R�i/HQF���⨼�F��ޕxۓ�TS�u�|���rDZ��T���*����]�a�7+�(��(P+����B��,��Z����PB����ߏ��l]BX�T�u�n[q�F��3��� v��x-���lzL�is%�k+��"_Rz�˘?-Ϥ���/D����hթ�h��LT(4[n?Zs����h�K��,�Y�p��*V�C�
+�Q��g���3����zĵ�' �`�/���x_��C�3vT�C�������3����"ng�g�wk$��'t*m|Ƌ^�\wDYA�'����L�+Q:d��RoPA�Pnؑ���O\�&��J��Zm�z`�i�Ί:a������,7���̼b�~'fv@N�~<t'^�s�){n��G\����ޙh1oV���0�#y�k�)�����<���!;ݢ&�xd�Z����Э�t�K3ž�T�iW������&j�EX�������?ؗ�������:5"�S?8�Dy�xZ��ԟ�Ca��:剠�qj���u.*��%ieC���P��\j�ʵ\��ɑ��]g�z*�~u2Q��L�e���Ğ�.���v]��|�(�0�����
0*"4+��-9tNp[�<1gZG��n���N��RG�T?ik�'�R`�L�$�u4�,BwK,�]��
+���̖gg�Pe����=�yH�?��<�K~����Hla�+��P��dXޚ�XG�;�YrwoZ����ǟr����o���O�?]M��^��@�>~{���M�A|jJ!=��EAe����S�g�c'�6����ۦ�{���@�˒��QbEy:V�W��?=DY
+ֿ�4��f�����~��h�=U[�FӲ-eGvy?��̨j��B�������������������N��_��[��"
+�����E��2Tj�~�R�!���,L::���J�lE��ךF�Q���w�i���r ����9�S��U�Xԙ:���eő^Jy7�m�ܾ�O߫��=��h�����R�D���£(�v�~����K,��J1���R%%��u?�y=��5|] ����g��&����틳��ڮ�nW������8����}������y��?8���C;⧪W+�yq4%��[���qt=wy���w��W��u�J�l�F�B�ÃiD�Q�S{��/��_�N�b6�^�(A�D��4����I�v���9A����s�m��;U�T\��+�f5��"�"}���=c��Tb�_�pU87>B�{�C�S%)(�%5GR\�z�֦�Z(�%9N�K�`#4�I��|��5'Z7Z�����s�+�S����PMZe�o�c��`�/%�c�J��٤k�N%������R���z���/-���� ��(�#n!?�2${�-b� �k�2r��~�>����zs�[M��,-���jm{̑��לeD>C�w�.����)��&���p�9r�@P�"���V15�V�}��(������x&n��V��;h`�u}��ܻ��!�n,�t�g�ia�nam5<�������7Vl#���I��awǑ�����9n��
+�҅⳩��u��(d>,u�z�ž)�F���{ʰ�GV$����&� G
7v�]��^r��F���E4�Ι�z���<�ȫg��iF��V�PT���,�����yۋ�+j��p���T� I���t~IM��<���C�o�IO
+!�R���_h�nBj� FG:9`+��li��Ll)�Eb�����ܡ������d�A���"g�"y�/���-d��ʒ�q�C>����t����JK౨����¸m9YZ2����g��l�
/˿�IbN9Uҙ��u��o+:�T��Ё:9-�j��i�u��9v6K�^���*^[[�IX�S M,s��)_FY��g�Nئ\D
o+0�3LB>26�@�z'���C ��i8�j`�tS���"?��jj܋���T�^�tQ"0�=d���d]b1e�����]��Y K�Ks��zs2Ec1'�;�;�W]Z���ݶ�������W���i�����{����Daʕ=/���K�|]�~��8s��+��m��9������G�?G{��z�t}� ������0){�����0��.��գ�3]a�G-��1���w�7/�ce��iC������K����������$��)2�]��Vf����[P��� �$rL��w����g1�E�o�V,���ujKu�J�1��{���4�w+4�P�N�*��f����
+Qg��-�SYs�]d�SًZ$�U�u�q�g[(�"����B�+����9#F�{ۗ.��M-н�/!�Q�](������b"������(�CⷰW����&�d���u!��J�7�Y��|Ly@�r+�GL �i�ƕJX�P����I"+�m]N.���.��8����_�:�]E4�_ѡ Z��G
+���-Bwd��g=j���XD����o����Uk�ZZ~���-��Ā���L�Gn�~0YtGsV����ʴ9=�l9����h(��E)����QQ�*���uC&%���I���i(�ܮ1�]2w��Lb����z·�k�ЙZ����TM���
+���0���X�j��x��"0f�Y�?2���'v������d�t��g^�Q0)5�#��\�Բ��������$ε+77�2��A ª�-��4"�|�oe-(y?�s��J*�Q
+�H^���U�Eܓ�ԥk�S���+S��w#̠�;����Pb���W�c{���T�F�+H�ґ/
����-cI�/%����n�KC.����|�J9���ʢW<b�U����e״�%�ptIIP�i�*b�㘬4�J*�-I��P��څ:(N�7����!C����.˽ �9W��rn�2"ܤ.dҾHag
R�!�)��1Lͬ@X��\JP>�9F���0-�ve��dȢ���Q�ͷ5 �(~�.F�Z�Y)+�оS>Ǻ!I=_�"���¤���8�c8��f�}ł��lj�H���"���+�l�R�^��X�,=�^����V�4�K!��0�m^ƹ��.�r��q�y�*`��i���W֢=��N��Y'�C��SO٥��B�F�F-�b \h֧y�S��@�:U�<�V�:�]���~Q�4w����1�X�i{�:�"�bH����UH�>�YY�P'�T�AA���"��V=J��ol������+.�����a�D�a��{��g:���C��ɢ &�9�;��� ����fS���<9���|XN�ɜ+�n�������ԧ>�4�Ҭ}6���������ar�&�-�%,8�I��Dx���Mv"�-dZ���%��-�0y��=B��d��F&��%w���|Đ���I���P�,�/4�C��=X}9tG�ɪ���8l�[���*?��23���jA[ﭳ[��x��-�=;o��x�F���<G.A�+�uoT��xo'D��Sp�;6��T_�R�l`HN�*�K�'�P��F�ۛ��UO"�‷H�g ���� ���¡2N��f�zK;Ƣ����$$�3&��[1+윝��)���<�q����y���EM��d���X-�@*����Kѓ��3,�$�"V|ӳVX~�>�M�\l�D8��Z���.�@����u),�i�5k��TՈ�\���q�/ ��s��>�j�������Hԭ�s�cQ؛�͢�9jC����
+Ƙ>n�oV��;d�Š�ڡ��v�@|5��6��(TUݱ/��j�u+�&�Bdh�rPk/�P��ֺu\��ڡ��/fbMo��]$���(�Ņ��
�~������f#Z)��3y<3�1��LrW��bM��RB���@�$c6͡�IUf�!�(�!kD7�{�^�M��|c�,�.�0|���қ��Λ�1Q����WH��=+�+z���n�\�a�X�.�m1:�Gl���1��B:߃�|-Lu�m1���ϱ��~R�L��q.�zo��'-*�+��&�t��]A�"݄���$Y��Z���yF�&d�����)P���!j���'��=������N?dG���b��W�xe62��(��[.�O*(
+'���*�d=E�&2_5�ֳ2"���V�Ռ�z۹@��G3J�8�yhc��]� ��>��� �ۣ�.d{>�6�5_Ҙ�����s�x�����s^90��˾@�����tb�{ �{rx>�ޠ�!i��'E���;���a�!��b��zP�f�d|�m�E"b�|{,I83���l˾�/ ����8�߬�̾�t���S�ђ�IkY,@���"�oJ}��@+1��x�"�[�l�����292g-����H.�҉.�����[K�c)��w�ƻ̶B��Ũ��eT� Cs�"�7=������*�����O�����T�R�l������?���v��5�O��HTV�)���Ym+i�~�;K«>mw�S�L�(i���꿾������#�7Vf�}���4p����ե�Q�ao�א�⓮_�ڻ!��H��<�^|�빌����/r'mj��Xo�ğ���3��D�z�����e�'�JS�+�%����D���@P� ����b̡�k�B6����i$�����Sg�{e��$/�I�MQD��e��?�"���2S�x�^��/o@�
+̖ȴ�\�l�
+c���8»|:��!C[�믣��Vh�)��:�ed��ρe(���!�]zS?���og
]�ؤ7 l�T��]L_���ST_?���c\_��b'1�+�
+���;����N�tb�?�e���Ħ6�l�e�j��Sj��Zʽ��h��(��0�}���+��>e�e:ޭW��|���K�eT)�J �m%C'%�(i�|%�:�O:��{w�1��n����i��ܙ%Z����)� -�$T7T�:h4�E�N9[���{w�OϺ?���VZaQq\Q!��Lr�p��) �
��z�M��u7��F��Z)�N�@HCS%�����j�ZY
+����LD�j������Ǝ�3��T����<Gf%�k���/K��9�B�'�Qj� $A�d�q��:���Jȭ(g�ok�{%éAM����kӘ�D���#"d�9;�iKR�y+c��'uui�f��z��7�;��B��l��7�n���bl�j�Է�}���-ͼ3�y���Ic5��2l�˵���/�V�7�L�.TT�L�4�x{Fa���4��C��"v��6�P(R%h����s27�$�������+����|Õo��
W�߸����_d������7�dn�T������w?>|�����6��������_���/��0;ف�
endstream
endobj
21 0 obj
<</BitsPerComponent 8/ColorSpace 22 0 R/Filter[/ASCII85Decode/FlateDecode]/Height 105/Length 501/Width 74>>stream
+8;Z\6>B5B>&H'`h5B_)Y^,Bpqn&'S93m2"Hh)IN/+I,Gk;\kZ/D;-lqU-eAh!<rrN
+Lo2Sl`s2>H$Y`E[LnkR@r<cKP$\+7)"TQpP'Rp6L[CmZZ)CF1gm)k']#*sm[1_u5G
+DF"jI#>8(!=?n^^X'-[1VWC]hI;H$rl^GS$0*$knot$a\^ok/p]afpP+q(V?5h$"=
+>OgCc/iBV``<7q0W8ce*6.MgsM\iU$(f"&5]:FG"r)%T@e`LXm9"f/g?Cp.K`r.8b
+K.3%$l%,ZNq8CiMKNNH62_0\-Uf6+.DX%iG<IC5;!E1.;'/f:bI(rJD&J4][.=$eU
+UaFLD!OY"+>aEpR(%s"-/@tb2_g/iI\8)bHfM(f"(<S',;p]VP3.:5uGm[="S:n^@
+J\0o.A;VB/]I`NY:]*?6($EeH9[p.+'ipo:h#Y(SpiC)n=d!JkHK[Qq-Ap\Bl0`on
+6hl1nBr@3KX\epG9NV>,L_L2M6?0ql!1R38KE~>
endstream
endobj
22 0 obj
[/Indexed/DeviceRGB 255 23 0 R]
endobj
23 0 obj
<</Filter[/ASCII85Decode/FlateDecode]/Length 428>>stream
+8;X]O>EqN@%''O_@%e@?J;%+8(9e>X=MR6S?i^YgA3=].HDXF.R$lIL@"pJ+EP(%0
+b]6ajmNZn*!='OQZeQ^Y*,=]?C.B+\Ulg9dhD*"iC[;*=3`oP1[!S^)?1)IZ4dup`
+E1r!/,*0[*9.aFIR2&b-C#s<Xl5FH@[<=!#6V)uDBXnIr.F>oRZ7Dl%MLY\.?d>Mn
+6%Q2oYfNRF$$+ON<+]RUJmC0I<jlL.oXisZ;SYU[/7#<&37rclQKqeJe#,UF7Rgb1
+VNWFKf>nDZ4OTs0S!saG>GGKUlQ*Q?45:CI&4J'_2j<etJICj7e7nPMb=O6S7UOH<
+PO7r\I.Hu&e0d&E<.')fERr/l+*W,)q^D*ai5<uuLX.7g/>$XKrcYp0n+Xl_nU*O(
+l[$6Nn+Z_Nq0]s7hs]`XX1nZ8&94a\~>
endstream
endobj
9 0 obj
<</Intent 24 0 R/Name(Layer 1)/Type/OCG/Usage 25 0 R>>
endobj
24 0 obj
[/View/Design]
endobj
25 0 obj
<</CreatorInfo<</Creator(Adobe Illustrator 24.1)/Subtype/Artwork>>>>
endobj
8 0 obj
<</BaseFont/KHHVMX+RobotoMono-Regular/Encoding/WinAnsiEncoding/FirstChar 32/FontDescriptor 26 0 R/LastChar 122/Subtype/TrueType/Type/Font/Widths[600 0 0 600 0 0 0 0 0 0 0 0 0 600 600 0 600 600 600 600 600 600 600 600 600 600 0 0 0 0 0 0 0 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 0 0 0 0 0 0 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600]>>
endobj
26 0 obj
<</Ascent 1048/CapHeight 711/Descent -271/Flags 34/FontBBox[-498 -271 785 1048]/FontFamily(Roboto Mono)/FontFile2 27 0 R/FontName/KHHVMX+RobotoMono-Regular/FontStretch/Normal/FontWeight 400/ItalicAngle 0/StemV 88/Type/FontDescriptor/XHeight 528>>
endobj
27 0 obj
<</Filter/FlateDecode/Length 13541/Length1 24418>>stream
+H��VgxUU]k����{���y, �iaX�I0�@�)�$�Q���;�R���{�A��A�$o�#�s�_~ߜ��}�9w��κw�u_j�[ (�t(D�th��v�E�1U��5�B������I �{��A={b��@M�[�wBl֚Vx��%��m��O��D�ԁy�9��hb����uZ^���I���_'��OlRB�%�cl8����Kͽ^o&�19%!/�['�������p�4k���R�+%�M�'Ʀ�A8�`~ �0����<{'��p3.H����H;����A^�W�5y]:J'�,]$Y�J7�.�'��C����Sk�I���Y2Jޓ2Sf����M��<��̕�2T�!�S#ce�����V}&K�s�B>��2N�˗�,��TV�*Y-ke�����Q6��2Q6�$�"d�l�ɲU��6�!�e���G>��2M��T9(����rXf�9*������=��w�&i{ςZ�.[�Qm���X��X��h��؈6،C���A<��<��G��x7��;�����bKa<�0��(��|VbM�dm>�M�����l��l˶8�v�I���qF����tI�?�8��!<�g��� �|n���Sr�/��CE����Q��Q��B�참�S@X�Tt��Ѧ[��g�ü����QCI�|�;����n��F(�*�cw��xC��q��e�<"ϙb7���'_�M����"��~��u���e�N��a=���H���ԉv✾�g�s�9�d:�=�������w���������n)����
+nU��[�}�m⦺i�<w��Y�'�DD�_D���]}��������������wv��V�0��z]4D'�b0f�Y\j�I�<���Y��8�0ct����^��1���S�i�u�dg��s�9�d9w<�)慷�7�;�����q�[�-�n�q������\��w:�q(�;=�8<��X��m3l�ߜ��H��u��M0����I�I��c�hh��6T�ޛ��·��mE����'/
\�m�y�BVd��������0�?*sk�ꌕ+��ꙑ��g���f����2���S�O�#��.�p�w�wap��%-*k����n����-������\���^��?m�Z�Ş��1�7L6�3EW6�7�f��17�y����v��t��Ͷ�_�M=ob�a4&�
��-L�;�^V�0C1]0��`z�#ba��Cgs��VK0S�qh�7𞤚[t�1�6b'��OЃ=��0��Q�9�L�̛fc>�c Va)V�K��l��]���P'p���4��?����ߙ7�F[�0������%Y��X�|�����&���9T
��y6g6cc��j.3��yT,f>cyK��S���,�/X������y] �e,gQl`9�gY ��<q35|{�vч��b7�&��b/#����|�4�)2=̊8�J8��8�geְ4Λ��d5�cm�@K\��2�"2Y����Y|��5W�W�7́��%�aS\gk�����p�<��7?��W��\�>_c2β~��X@1X��ك�؝q��.��@��|[N�i9��|G.J����dJ��%��4��t�ʡ�|�a�-�s�|'���\������)�8V~���k<?�N�ۜ������4y��-90������U9[�Q��p��r�s��)�м-�ЂZHk.ҢZL��K��*��\õ\�%������7ki-�-Z�[��V�p�GxP��ԫ�y��yD]}V#x��x\Oje�B?3��KZU��&o�9=�'�8o��]=���+��!�>T��E��>�=�l��6�n���%"*���Z�Cwjm}N35Kw�n�H��ѽ*a�O�I~)�G��>�u���B����ʃ�8��~��|�,ˇ���j%Y�tZ�-Y�eI�%c���c��<-IH�d�0ǐiRH
+!�
�!ڡ��&әdzAih�`HcL8��oW��t���|���{������]#S�����oЉ.�+�*9�p��
+\��8BJ�T| ���e��L�mx9���I�q;�����}���D�{h>���v���>b5i%�k�~b1Dt�6��!�&�����m<̛���l2�����Ưy��vϯ>A���qÏjѼ�ditD�ɟ��2�T�Ё ��pzQv�>ۈ��^�V�`h%4ʠQ\ڌ��f!������]�A�@��jf�??����
Ow��I��^]� ����b��u�
+
�jM�� ���U��?`T@��xW�1�M1�-bi��YXG�@�� 4T%�Ye3G���yr[�w����3R�m7"*|�e����6�oN#ڛ����o����;3�f��p>C祤J���vUe
+,cպ�U����궻���J%�5EQu��M����k�H�
+
��T��|���~kq������}�|ޠ1�`SM����ƃ������s$"̆�C�B�D��b˃�Ӿ`6#���d��mAk;>�,���s"ߐ�.<����+���6S�&��&K�����F悜���+OT�7d��s(+�i�X7��l���i���D'��B�*6vV�N��w�C��:<�����=�Ec1�� 7#Й�L�&��(L�S5�d�(: �d�}��xrK�b f�,�9%:Kg���?ED&&�$�$��8�l%�n�T9�e2�H�-�k���EMkg�N������*q�3j!-Ǵ��;5t�A���"g����`5�[�ZKQ3�d�uK�O�.�9?w �t���p����/��c�m��/�+���OI�->}|��
G��m���� ���1y�P�ǰ>���W�����q�c����J�1A~9d}�X����0���s��b��8F�T�Y�(i4) �|�w�<�/�Bq�S��v�6W�e�z��^�W�~��� I0�#�� 9�����$����KF7c�&/9Jn����$��
+������C��w��jx�!E0�@B���?�/�F\K����I��X�!�m���>����]��b�c�ɐ�?I���"�gpQ�o<���S���Pk�|�A���|Z[/%XXK��hEg��4����VS�.�Ά��E�:��U*��U<h��d C1�(1)���m���� 9)A�JLJ6sT��V�p��ɉ��H�/#��yyfS^�`E�P�H�G�W��,FC��p� R�ut���,��hu�ü�~��c.jf��Z�nv����V��BsF�Y,{���,�>��h/��j��H$8��Ϛ ~�i4�ѴyH`�R��@g�a��A�~�S�q�.{�����I�d+�k��,����_�o�3{�t�r��7��L���dOc�.��Q���S(T����M�r
���T��TM����Z�"�}�5%'&�JH2�(y֔��Dv���\��R`��ޞW���v�� ���&��$�ʸh\f���ͪ�(i�E�r�g��`_\h�����q����C���`�ڥ/tJ�u�S2�_(Y�q���Й~�:q���鳵j��R���L�)#ˏ��8E��s0�0���W���tH��
��]�y6i/!�iSbKD�)��%��<miXxk��ku��9�� ��b�W=�'B��-s���z���Z�^�iq��4�.�L����ǃ�ڐ�sde�Ϡ�E��H�B�f�큮_��l6��\Fzj�JUe5U+�N�6;��]~g�}OK�f�����(����ݷ��F�'r���{���^rsl�q���� �.�Pr�0��� s�y,$�ߑ��a�ݮ�Q#��Q���[�E�/�a
�����u!|y���������T?�R�l�Sf��N̆��8��7�2�[�C��tq�i��dH��ɜ2����A������ ���\�O�rkB|����Ph���[��iꝒb������X��ql�k�q��h?_�THC_&��x�d�ƨ�4D�7�?�<�L0S���2P��/���9t�D��{��˩��r&>�ጱ��X`��K�C�>�@���|0��䇣W�>�8$5�]�A�ۥ���+��\�Q/$�4��H'F,���(F���^�<XR�qk��E�4����8RJ�WN��N���E�M��e�ʃ�8��v%�,yu��]iwuX��ӒV�e�4��6��ll�1�SpBLZ����!���i�������6�J�i�i-���2MZy��ҷ�%C3��>�|����{���-N���g���6�Xz\�5��Αr{�Q���zܻ��ĵ:��8suNס�ͣ�Z�J!��L�F��� ���Jz�Jm��~�+���s�\-M{�7Ev~ϰM��l����F�6n��,vY)?^�!Q�Ե[S�aW�M����U.3�r�rz�&�2��� ��UJP��l�ۮ7Yps����`�ڂ�,C[�7G���]5�%�ר�>�9�:��lu[WO�M���fK��v
+��>4���1d1�����O��P}���mn#�X�ޱK�x<o��t���Ç��cXq>���K����|�&�ZZ��Z([��O���*�_��^�����Z|-�!�~V�刦�=�L��,����˞���R@r�8���
7�՝n46��6д��#�r�͉�*�?D�������ܸ���8Oc��y��q�'��+��m�Ҡ1x,J���6��F_9��г��kAF�n �����wF�[��mI6{�+�E3&N(q�L�UcK��uvkOV���_f/[��}��1���l��4��z��k6Yx��Aen���:�G�P�e� @�h0���
S�1��dW�Q�)k|;Kr� &�����*�1`��+$"�p�=�9u�?Q�z^6�p/�4��Un^P���#�$/����p�t?��F�p��ܗ����i~���z7��ެT�I{olәH$6I���5AR.s�tiG��1P3\j�2�����h��ưz������
o��CZG��(cY.�{i�Jy嘂��e�M��u�u��Tu��V�c����(��B� w�L�tHOX�����!�F{� �դ��߽(Z�+��ǿ~.�U!>������ˠ���O#u�
��F�#d wQ8�}�}i�1Gq��n�82�+�*Q�Jq�Ąp'��F$�*�$YW�*�
+X��k��C,|5e`���`�"!��6WU��p�d�C�c���ܽ\��
S-`��X��$�����E�
'��Zm8�GZ����G��f��c[D5��s4r����Y��$�'�"���ۄ�� �&�R����ʣt
Y�}_�"��
+���G'&�Q����� [�|��%�?C^ >��锅3b�ݭ��J�E�6K��"�JjҨ-R���`X��ux��R��$�K�Q���0^�]$�VI�.Ã� ͕�\W)�������B��oXk`4T)dv
ȹƁ|rf�sf��E\��f~��9�����)�.�|�V�wx頺��P�sc�F��u�aGzsǙ@��ƈ�� {@Ŗ����yu�o�ߵJ�ϒÙd⧣�.%�L"yit�'�d���X�i�32�`�O7��j�G������Q|���xv����|��x���:�!�#�6J��zyY^�@�Ny�N�uZ���'C!�
�N
����z�-�=�t��i�a����{��zPh�h;�_��{��rm��
�����}%�y��mڋUca�w��M��Y����/ʲ�����P���?Jq����� �#�@w��IR�(i\�i
+�����+�
+����g�F�ޒ�͋|4�Q9�9�ރU�!����gO`�!��g~Q@���^
+�����-=������t�ݟ@���k mU��ᕇ���������(���������36h4��M�Ns�G�Y���ݑ��M��D4z�/��ԫI�l5��k�B�!v~�sцx~cCk?C���U�I�o����뛼���[�[�ր��V�]z�O��0���sϸ����5�j���J�A��Ͼ
�9� ~{� �+F9��2�|�E�Nr��
+��;����t�HR��S�B��:7(Nqw/�x��u-Z�P��Ag�Pi5�1T|��|l�x��n��3b� �9)����?�ժ����;zO��h�y�H��Ԋ>Wܷ�B8�j/�f/p� ^��R���bF�#���0�_wE�����t�B��V��R��~HK�������'����7�'([���jq���ק�z[I����)�
+�/���nd"Ed�B8�qw����ϋA�pP���U�-x�"2��̚57RC�B��v��F������wY�����H6c�*#�ZY���)��8�s}����v�t�K$ShO�F�U�p���d���<X���#����c����2^-@M^Y�܄���U��#o�yHᑐy�� o��N�ն�U��Z��]|��l�����[u|vٺ���8��3�պێ����ٸ��������{�=���{��)"!���E�I�)���i�Ϛh��%uh���`�1d;��9�F�%��߶�a0Z\�
+�d�^[.QD�JiE�~�D���
��-*��
+�F�ܟv�N/�ي���M��Z�V(T3ܪ���U�juTk�����;�F$�]G�2(J$����e����nnx��8��
khD#�����En���w��F2]U�j^�`���]�q�l��P�k�)�8�B��˲���ʺ�dZ�W�[��.2�z�LH�l�Vm�hZ,.�ahQ��^�3�(���|��|��h�vm�nR��8�j2�*ʨ��99�k|�c�EH�s-�
+�Xl�6��4�fg�ߏ��fN�ϖH�r���,�a;U�t�T��SR�ܼ5O�>��f}K�Ԃ)��������R
�iؓ��b�L,��%τCIƝ!6X��x�^��L�Db���� a�O�M���O9o���8a�3v��,���\q�<�b>�68Կd3R�q7f�`��ܹ��0��ҨT*%�C�;��8�b�����3�2�Z�;Uj�t��I��1�ML�B�eiL�ԎEM{u���99'��MVu��E/�þ6C�h� �!3�G#�
+��<�;h�xc����坰Ir����u�5'���e��4M��ךRc�k48VNr?ά��P��k�"#c&%˔3D�Z�-w���ys�mN�5w`A]��Z�Ԋkz23-�)IqqK�<g�N}�^m
��x���2�g�7R�)A����u�)�_�q�IH'x/�PPF>{���*�d�3ڏ�/���f�7��ʕ�#l�iv�\Yh1;���Y�E�qҒuvX��J.���v�"R ����Q�Ad��8 t�H$b[Rr�D,Hnة�7u��
i�q�9�� �
�pqn�M��U���iB��h����TV���R�##�*AeJ�D��b!eZ�D"WHde�WJ;<��#K(t���*}ګ�g���Bɛ+���K�� �<�&T4�嘍��e���K��k��U�SƧҏw�m������Q*b&&�����;Y��Y���V��zaC�5�lr�$M�h��]:��6^�f�n��������>3��e{���p2ǝg����s+�k�+fUn˫���oh��m�4����ϝ��/��0�a�v�Ub�v)�kS��%Tr-D��E�>X)���`��Yn�8X��O��r?��~I��d{��lO73�g��빶�=���s�xO7���K=4Z7��#M���ȃ�D�y�Ϧ�N�������/AG߬���Ƚ>���������r:F�h/
�9�O�q�iD��C�J�諥Z�,� RHvX���Ɂ_7�ohua�%���%�ݎ�*�.T��B'!+��'��8�fC���b�et�v�������D*�S��4TJ�X�3H9C��C۩���D������B�ˬ�=D��%����nS����{v�
�B�����&ffG���˺X���n�k9V�6G�sh5L�#'�e�Ji �`ܛT�=���X�;��u��B���@�^��\�E����;�Go�����^d��^��a��h���g�(�=�<�`���G�s�[q>��>�/ѺxL�܅��F?���h�О�g�V��~��;|���|.�}��� �1|}�62�c�!���'�슁Ƿ0."n���P�H�����k��=W�S$�c��dX-�K#{��<j�Zm�
ث��i�6�U�!�-K���
��.�KDe�E�;� =��{d%�I��a:J���w`��=H�0/<�w=m��-�5��k��?��v*�܃��6����:<W��1`^;���((������{d�BZ �`L}��XA���~/0���O⻏� ���t�(ڵao�C�j����������� }�]s0����Jz��d�u),�)�Ӌ�����Md6x���E<�-��B��O�A���ZLdA��Il���a�k����>�oh'����aX�ۈ��kЦ��f,�����G�� ���eD�
.I��<g`tނV��]p�+��
+z��zO0�C���6��O���c��zBs�<������C͘lIX{�Q���s�s����<���=�q9��X�.Ft��c�6�g_��g��!�6�kZ)fryÛoz1_��@dm��H[yy��ͳ���[�m�:^�s�A�,@�]��H��l�p3���@���g}#��8"%�1�o\���U��'�߸�=��5��ùց=i�ړvzr��C�M��~L&���������[ׯy������Z��}'n�[p h)Z$@M�!�����w�@��mq�����{o.´3oޛ7����9���v����9_ܳc��:��fŧ&q�C�~݆i����Q�?����yz���疶sX�dmk��V_Xob�$�;��!�F���/�=�{i=�ի�>�e�q��Z\F^TFC��e����>�q��0�V����C�5�;&s�u����)�i��+g_�9Χ]\]\"]���s�rm���խ��������+���Ou_��#�G�� ���=�{����Z�_��t�KI�)�)�)���H bn�(��F��/~��O)/�W�x�O(�����rֵ6�Yj�y'I�H��x�U�v�>��堬}�HI�yɅAv�Q�c�}�ڀ��qg����x�U<X�λKJֲ����v�Sq��������SB��e�6F��2Zj��R�����0HQI3m1��Ei��Վ�����!�5�����
�4��X-Q��� �G��E�W���[�ourA)���[��H�~�T��/��D뷕� ��,�ꭰˢ�����&1F5�����+�:"l+:�<?�eQ�f�(���a��&=Fw�I����]��?X��ETzA�҇d-����{n���&\�=�#l��_��O��#l>���B慩�;Z�E=孧��9���3���ɍ�����ڭ���ܪ;@�Bu$J�a��[-��i�����5�!�.��pO>��C�m������F~*�,?[���ld��|�jz��z���~�̄�d|��k��W�El��ZdrHN!�5C}�W�O���k��h��/�0���P[KIi��,Uԯ�jEu�s�ƪ�fVm�]AjQ]-<�
+Z�)�k
��»Z�Ri�K#i�0���Q��Sy&��>�Z�F�,Y���<�������_�Y ��G٢i�dS��DT&ɬ�j���
+�TV�jq�"�N��-ske'��e�C��"�X��V�^�H��cY��%%�dU�5^�Zr)+��EvI�-}e�®�2\�i�r�Җ]�`�x�셋��|YW�I(�%�A�9<�$��H&{d��~�@J��;���i�N ��C�V#2"2#��ِ]�"r"���䖣�c����ȇ��C�.�P�PX������9�����-��J�J����w� eQNn��D��ޝHi���$Q�,mPE>j�XP���E5T��-jH; 5�
j�6�G�Ġ�tԌ퀺����P
�6�k� ��D:K4�n�]�"�*��\z -��rC�#��Zz"RzK�6��m��h�t@G��N���En��f�9-g䬜��2R.�%��nrQ.����b�(K�z�'z�7��/��?` a0�`�,�0���(�������10�0S0�d*�cfbfc�b�cbc �b�#+��`Vc
�b~�zl�Fl�fl�V�����a;v`'va7�`/�a?� �0��(��1� ��)����9��\�%\�\�5\�
��-����=��<�#<�<�3<���+����;��|D� i�@G:љ.t���AOz1 �2�3S2S3
�2�33233���٘�9�����y�C_�e>�� �0��(�a1~��,��,��,��X��X�X��X�UX�����2I��d�/ce�l`
0�5Y���=�X�u���#�>�!�'6f6e�1���gKF�[3�mE۲�ٞ1����$�ؙ]ؕ�؝=ؓ�؛}ؗ�؟8��8�C8��8�#8��8�c8���3�s'r's
+�r�sgrgs�r�srs �r�3�+���pWs
�r�zn�Fn�fn�V�����q;wp'wq7�p/�q?� �0��(��1� ��)����9��^�%^�^�5^�
��-����=��>�#>�>�3>���+����;��~d�Cc��q4N�ٸW�f܍��4^&�Ij���&�IiR��&�Ikҙ�&��h2��&��6YM6���09M.���1>���Evu���d�������q��o��Y�mH8Ďɳ�s�2(�����$�{���{���{�+f��@�:#��9��+������\������QBTQÃ�`<���p<�h���&6p-\�&�p�h�
+��v����>���x$�G�1x,G����.��C�0���&q���[���� x"��'�)x*����x&��g�9x.����x!^��%x)^���x%^�W�5x-^���
x#ބ7�-x+ކ��x'ޅw�=x/އ��� >��#�(>����$>�O�3�,>����"��/�+�*�����&��o�;�.�����!~��'�)~����%~�_�7�-~����#��?�/�+�����'���?�/��;���3���M����<t};}���N��q8qҁ��ƽ�q�;7�cdw}o�bx}o���;���h�a �6���
G׆�ʹٵ����=I[�#m���VϛWhy this scored 21/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.