diff --git a/.circleci/config.yml b/.circleci/config.yml index 1282cff68..02f3b073f 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,8 +1,6 @@ version: 2.1 - orbs: slack: circleci/slack@4.10.1 - parameters: ci_builder_image: type: string @@ -10,7 +8,6 @@ parameters: base_image: type: string default: ubuntu-2204:2022.07.1 - commands: notify-failures-on-develop: description: "Notify Slack" @@ -24,7 +21,6 @@ commands: event: fail template: basic_fail_1 branch_pattern: develop - jobs: lint-specs: docker: @@ -37,10 +33,6 @@ jobs: - run: name: markdown lint command: just lint-specs-md-check - - run: - name: toc lint - command: just lint-specs-toc-check - lint-links: machine: image: <> @@ -51,18 +43,16 @@ jobs: command: just lint-links - notify-failures-on-develop: channel: C055R639XT9 #notify-link-check - workflows: specs-check: when: not: - equal: [ scheduled_pipeline, << pipeline.trigger_source >> ] + equal: [scheduled_pipeline, << pipeline.trigger_source >>] jobs: - lint-specs - scheduled-links-check: when: - equal: [ build_daily, <> ] + equal: [build_daily, <>] jobs: - lint-links: context: slack diff --git a/.github/workflows/deploy.yaml b/.github/workflows/deploy.yaml new file mode 100644 index 000000000..c7205be36 --- /dev/null +++ b/.github/workflows/deploy.yaml @@ -0,0 +1,35 @@ +name: Book Deployment +on: + push: + branches: + - main +jobs: + publish: + runs-on: ubuntu-latest + permissions: + contents: write + deployments: write + name: Publish to GitHub Pages + steps: + - name: Checkout sources + uses: actions/checkout@v4 + - name: Install Rust stable toolchain + uses: dtolnay/rust-toolchain@stable + - uses: Swatinem/rust-cache@v2 + with: + cache-on-failure: true + - name: Setup mdbook + uses: peaceiris/actions-mdbook@v1 + with: + mdbook-version: "latest" + - name: Install mdbook plugins + run: | + cargo install mdbook-katex mdbook-toc mdbook-linkcheck mdbook-mermaid + - name: Build book + run: mdbook build + - name: Deploy + uses: peaceiris/actions-gh-pages@v3 + if: ${{ github.ref == 'refs/heads/main' }} + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./book/html diff --git a/.gitignore b/.gitignore index 394522f42..20cafdeb4 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,4 @@ -node_modules/** \ No newline at end of file +# Rendered book +book/ + +node_modules/** diff --git a/.markdownlint.json b/.markdownlint.json index ba6003836..2e23f6c74 100644 --- a/.markdownlint.json +++ b/.markdownlint.json @@ -7,6 +7,7 @@ "tables": false }, "no-blanks-blockquote": false, + "no-empty-links": false, "single-title": false, "no-emphasis-as-heading": false } diff --git a/Justfile b/Justfile index 771bc89f5..f3ee9f43f 100644 --- a/Justfile +++ b/Justfile @@ -7,10 +7,10 @@ lint-specs-md-check: lint-specs-md-fix: npx markdownlint-cli2-fix "./specs/**/*.md" -lint-specs-toc-check: - npx doctoc '--title=**Table of Contents**' ./specs - lint-links: docker run --init -it -v `pwd`:/input lycheeverse/lychee --verbose --no-progress --exclude-loopback \ --exclude twitter.com --exclude explorer.optimism.io --exclude linux-mips.org --exclude vitalik.ca \ - --exclude-mail /input/README.md "/input/specs/**/*.md" \ No newline at end of file + --exclude-mail /input/README.md "/input/specs/**/*.md" + +serve: + mdbook serve diff --git a/README.md b/README.md index c42a46d02..f5644634e 100644 --- a/README.md +++ b/README.md @@ -1,63 +1,34 @@ - -# Optimism Bedrock specs - -This directory contains the plain english specs for Optimism, a minimal optimistic rollup protocol -that maintains 1:1 compatibility with Ethereum. - -## Specification Contents - -- [Introduction](specs/introduction.md) -- [Overview](specs/overview.md) -- [Deposits](specs/deposits.md) -- [Withdrawals](specs/withdrawals.md) -- [Execution Engine](specs/exec-engine.md) -- [L2 Output Root Proposals](specs/proposals.md) -- [Rollup Node](specs/rollup-node.md) -- [Rollup Node P2p](specs/rollup-node-p2p.md) -- [L2 Chain Derivation](specs/derivation.md) -- [Superchain Upgrades](specs/superchain-upgrades.md) -- [System Config](specs/system_config.md) -- [Batch Submitter](specs/batcher.md) -- [Guaranteed Gas Market](specs/guaranteed-gas-market.md) -- [Messengers](specs/messengers.md) -- [Bridges](specs/bridges.md) -- [Predeploys](specs/predeploys.md) -- [Glossary](specs/glossary.md) - -### Experimental - -Specifications of new features in active development. - -- [Fault Proof](specs/fault-proof.md) -- [Dispute Game Interface](specs/dispute-game-interface.md) -- [Fault Dispute Game](specs/fault-dispute-game.md) -- [Cannon VM](specs/cannon-fault-proof-vm.md) - -## Design Goals - -Our aim is to design a protocol specification that is: - -- **Fast:** When users send transactions, they get reliable confirmations with low-latency. - For example when swapping on Uniswap you should see that your transaction succeed in less than 2 - seconds. -- **Scalable:** It should be possible to handle an enormous number of transactions - per second which will enable the system to charge low fees. - V1.0 will enable Optimism to scale up to and even past the gas limit on L1. - Later iterations should scale much further. -- **Modular:** Our designs will use modularity to reduce complexity and enable parallel - contributions. Coming up with good conceptual frameworks & composable atoms of software enables us - to build extremely complex software even when any one person cannot hold that much in their brain. -- **Minimal:** Rollups should be minimal to best take advantage of the battle-tested infrastructure - (like Geth) that already runs Ethereum. An ideal optimistic rollup design should be representable - as a *diff* against Ethereum client software. -- **Developer Driven:** Our designs will be developer driven to ensure we are actually building - something that people want to use. We must constantly engage with the developers who will be using - our software to avoid creating a system no one wants to use. -- **Clear and Readable:** The specs we write are written to be read. So tight feedback loop with the - systems team consuming the spec is also key! -- **Secure:** This is self-evident. - User’s assets are at stake. Every component of the system must be incredibly secure. -- **Decentralizable:** Optimism must be designed to avail itself of the security and - censorship-resistant guarantees achieved by a decentralized system. - Currently centralized components of the system should have a clear path towards decentralization. - Already decentralized components of the system should be protected and preserved. +
+
+
+ Optimism +
+

Optimism is Ethereum, scaled.

+
+
+ +## OP Stack Specification + +This repository contains the [Specs Book](https://static.optimism.io/specs). + +## Contributing + +### Dependencies + +**Rust Toolchain** + +```sh +curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh +``` + +**`mdbook` + plugins** + +```sh +cargo install mdbook mdbook-katex mdbook-toc mdbook-linkcheck mdbook-mermaid +``` + +### Serving the book locally + +```sh +mdbook serve +``` diff --git a/book.toml b/book.toml new file mode 100644 index 000000000..411654b0e --- /dev/null +++ b/book.toml @@ -0,0 +1,22 @@ +[book] +authors = ["optimism-collective"] +language = "en" +multilingual = false +src = "specs" +title = "OP Stack Specification" + +[preprocessor.katex] +after = ["links"] + +[preprocessor.toc] +command = "mdbook-toc" +renderer = ["html"] + +[preprocessor.mermaid] +command = "mdbook-mermaid" + +[output.html] +default-theme = "ayu" +additional-js = ["specs/static/solidity.min.js", "specs/static/mermaid.min.js", "specs/static/mermaid-init.js"] + +[output.linkcheck] diff --git a/package.json b/package.json index 4f1c3b9a9..d92a19e68 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,6 @@ "pnpm": ">=8" }, "dependencies": { - "doctoc": "^2.2.0", "markdownlint-cli2": "0.4.0" } -} \ No newline at end of file +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 13db3c43a..d70f4262e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5,9 +5,6 @@ settings: excludeLinksFromLockfile: false dependencies: - doctoc: - specifier: ^2.2.0 - version: 2.2.0 markdownlint-cli2: specifier: 0.4.0 version: 0.4.0 @@ -35,42 +32,6 @@ packages: fastq: 1.16.0 dev: false - /@textlint/ast-node-types@12.6.1: - resolution: {integrity: sha512-uzlJ+ZsCAyJm+lBi7j0UeBbj+Oy6w/VWoGJ3iHRHE5eZ8Z4iK66mq+PG/spupmbllLtz77OJbY89BYqgFyjXmA==} - dev: false - - /@textlint/markdown-to-ast@12.6.1: - resolution: {integrity: sha512-T0HO+VrU9VbLRiEx/kH4+gwGMHNMIGkp0Pok+p0I33saOOLyhfGvwOKQgvt2qkxzQEV2L5MtGB8EnW4r5d3CqQ==} - dependencies: - '@textlint/ast-node-types': 12.6.1 - debug: 4.3.4 - mdast-util-gfm-autolink-literal: 0.1.3 - remark-footnotes: 3.0.0 - remark-frontmatter: 3.0.0 - remark-gfm: 1.0.0 - remark-parse: 9.0.0 - traverse: 0.6.8 - unified: 9.2.2 - transitivePeerDependencies: - - supports-color - dev: false - - /@types/mdast@3.0.15: - resolution: {integrity: sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==} - dependencies: - '@types/unist': 2.0.10 - dev: false - - /@types/unist@2.0.10: - resolution: {integrity: sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==} - dev: false - - /anchor-markdown-header@0.5.7: - resolution: {integrity: sha512-AmikqcK15r3q99hPvTa1na9n3eLkW0uE+RL9BZMSgwYalQeDnNXbYrN06BIcBPfGlmsGIE2jvkuvl/x0hyPF5Q==} - dependencies: - emoji-regex: 6.1.3 - dev: false - /argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} dev: false @@ -80,10 +41,6 @@ packages: engines: {node: '>=12'} dev: false - /bail@1.0.5: - resolution: {integrity: sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==} - dev: false - /braces@3.0.2: resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} engines: {node: '>=8'} @@ -91,34 +48,6 @@ packages: fill-range: 7.0.1 dev: false - /ccount@1.1.0: - resolution: {integrity: sha512-vlNK021QdI7PNeiUh/lKkC/mNHHfV0m/Ad5JoI0TYtlBnJAslM/JIkm/tGC88bkLIwO6OQ5uV6ztS6kVAtCDlg==} - dev: false - - /character-entities-legacy@1.1.4: - resolution: {integrity: sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==} - dev: false - - /character-entities@1.2.4: - resolution: {integrity: sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==} - dev: false - - /character-reference-invalid@1.1.4: - resolution: {integrity: sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==} - dev: false - - /debug@4.3.4: - resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - dependencies: - ms: 2.1.2 - dev: false - /dir-glob@3.0.1: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} engines: {node: '>=8'} @@ -126,73 +55,10 @@ packages: path-type: 4.0.0 dev: false - /doctoc@2.2.0: - resolution: {integrity: sha512-PtiyaS+S3kcMbpx6x2V0S+PeDKisxmjEFnZsuYkkj4Lh3ObozJuuYh9dM4+sX02Ouuty8RF2LOCnIbpu/hWy/A==} - hasBin: true - dependencies: - '@textlint/markdown-to-ast': 12.6.1 - anchor-markdown-header: 0.5.7 - htmlparser2: 7.2.0 - minimist: 1.2.8 - underscore: 1.13.6 - update-section: 0.3.3 - transitivePeerDependencies: - - supports-color - dev: false - - /dom-serializer@1.4.1: - resolution: {integrity: sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==} - dependencies: - domelementtype: 2.3.0 - domhandler: 4.3.1 - entities: 2.2.0 - dev: false - - /domelementtype@2.3.0: - resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} - dev: false - - /domhandler@4.3.1: - resolution: {integrity: sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==} - engines: {node: '>= 4'} - dependencies: - domelementtype: 2.3.0 - dev: false - - /domutils@2.8.0: - resolution: {integrity: sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==} - dependencies: - dom-serializer: 1.4.1 - domelementtype: 2.3.0 - domhandler: 4.3.1 - dev: false - - /emoji-regex@6.1.3: - resolution: {integrity: sha512-73/zxHTjP2N2FQf0J5ngNjxP9LqG2krUshxYaowI8HxZQsiL2pYJc3k9/O93fc5/lCSkZv+bQ5Esk6k6msiSvg==} - dev: false - /entities@2.1.0: resolution: {integrity: sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==} dev: false - /entities@2.2.0: - resolution: {integrity: sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==} - dev: false - - /entities@3.0.1: - resolution: {integrity: sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==} - engines: {node: '>=0.12'} - dev: false - - /escape-string-regexp@4.0.0: - resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} - engines: {node: '>=10'} - dev: false - - /extend@3.0.2: - resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} - dev: false - /fast-glob@3.3.2: resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} engines: {node: '>=8.6.0'} @@ -210,12 +76,6 @@ packages: reusify: 1.0.4 dev: false - /fault@1.0.4: - resolution: {integrity: sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==} - dependencies: - format: 0.2.2 - dev: false - /fill-range@7.0.1: resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} engines: {node: '>=8'} @@ -223,11 +83,6 @@ packages: to-regex-range: 5.0.1 dev: false - /format@0.2.2: - resolution: {integrity: sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==} - engines: {node: '>=0.4.x'} - dev: false - /glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -247,40 +102,11 @@ packages: slash: 4.0.0 dev: false - /htmlparser2@7.2.0: - resolution: {integrity: sha512-H7MImA4MS6cw7nbyURtLPO1Tms7C5H602LRETv95z1MxO/7CP7rDVROehUYeYBUYEON94NXXDEPmZuq+hX4sog==} - dependencies: - domelementtype: 2.3.0 - domhandler: 4.3.1 - domutils: 2.8.0 - entities: 3.0.1 - dev: false - /ignore@5.3.0: resolution: {integrity: sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==} engines: {node: '>= 4'} dev: false - /is-alphabetical@1.0.4: - resolution: {integrity: sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==} - dev: false - - /is-alphanumerical@1.0.4: - resolution: {integrity: sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==} - dependencies: - is-alphabetical: 1.0.4 - is-decimal: 1.0.4 - dev: false - - /is-buffer@2.0.5: - resolution: {integrity: sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==} - engines: {node: '>=4'} - dev: false - - /is-decimal@1.0.4: - resolution: {integrity: sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==} - dev: false - /is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} @@ -293,30 +119,17 @@ packages: is-extglob: 2.1.1 dev: false - /is-hexadecimal@1.0.4: - resolution: {integrity: sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==} - dev: false - /is-number@7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} dev: false - /is-plain-obj@2.1.0: - resolution: {integrity: sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==} - engines: {node: '>=8'} - dev: false - /linkify-it@3.0.3: resolution: {integrity: sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==} dependencies: uc.micro: 1.0.6 dev: false - /longest-streak@2.0.4: - resolution: {integrity: sha512-vM6rUVCVUJJt33bnmHiZEvr7wPT78ztX7rojL+LW51bHtLh6HTjx84LA5W4+oa6aKEJA7jJu5LR6vQRBpA5DVg==} - dev: false - /markdown-it@12.3.2: resolution: {integrity: sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==} hasBin: true @@ -328,12 +141,6 @@ packages: uc.micro: 1.0.6 dev: false - /markdown-table@2.0.0: - resolution: {integrity: sha512-Ezda85ToJUBhM6WGaG6veasyym+Tbs3cMAw/ZhOPqXiYsr0jgocBV3j3nx+4lk47plLlIqjwuTm/ywVI+zjJ/A==} - dependencies: - repeat-string: 1.6.1 - dev: false - /markdownlint-cli2-formatter-default@0.0.3(markdownlint-cli2@0.4.0): resolution: {integrity: sha512-QEAJitT5eqX1SNboOD+SO/LNBpu4P4je8JlR02ug2cLQAqmIhh8IJnSK7AcaHBHhNADqdGydnPpQOpsNcEEqCw==} peerDependencies: @@ -367,97 +174,6 @@ packages: markdown-it: 12.3.2 dev: false - /mdast-util-find-and-replace@1.1.1: - resolution: {integrity: sha512-9cKl33Y21lyckGzpSmEQnIDjEfeeWelN5s1kUW1LwdB0Fkuq2u+4GdqcGEygYxJE8GVqCl0741bYXHgamfWAZA==} - dependencies: - escape-string-regexp: 4.0.0 - unist-util-is: 4.1.0 - unist-util-visit-parents: 3.1.1 - dev: false - - /mdast-util-footnote@0.1.7: - resolution: {integrity: sha512-QxNdO8qSxqbO2e3m09KwDKfWiLgqyCurdWTQ198NpbZ2hxntdc+VKS4fDJCmNWbAroUdYnSthu+XbZ8ovh8C3w==} - dependencies: - mdast-util-to-markdown: 0.6.5 - micromark: 2.11.4 - transitivePeerDependencies: - - supports-color - dev: false - - /mdast-util-from-markdown@0.8.5: - resolution: {integrity: sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ==} - dependencies: - '@types/mdast': 3.0.15 - mdast-util-to-string: 2.0.0 - micromark: 2.11.4 - parse-entities: 2.0.0 - unist-util-stringify-position: 2.0.3 - transitivePeerDependencies: - - supports-color - dev: false - - /mdast-util-frontmatter@0.2.0: - resolution: {integrity: sha512-FHKL4w4S5fdt1KjJCwB0178WJ0evnyyQr5kXTM3wrOVpytD0hrkvd+AOOjU9Td8onOejCkmZ+HQRT3CZ3coHHQ==} - dependencies: - micromark-extension-frontmatter: 0.2.2 - dev: false - - /mdast-util-gfm-autolink-literal@0.1.3: - resolution: {integrity: sha512-GjmLjWrXg1wqMIO9+ZsRik/s7PLwTaeCHVB7vRxUwLntZc8mzmTsLVr6HW1yLokcnhfURsn5zmSVdi3/xWWu1A==} - dependencies: - ccount: 1.1.0 - mdast-util-find-and-replace: 1.1.1 - micromark: 2.11.4 - transitivePeerDependencies: - - supports-color - dev: false - - /mdast-util-gfm-strikethrough@0.2.3: - resolution: {integrity: sha512-5OQLXpt6qdbttcDG/UxYY7Yjj3e8P7X16LzvpX8pIQPYJ/C2Z1qFGMmcw+1PZMUM3Z8wt8NRfYTvCni93mgsgA==} - dependencies: - mdast-util-to-markdown: 0.6.5 - dev: false - - /mdast-util-gfm-table@0.1.6: - resolution: {integrity: sha512-j4yDxQ66AJSBwGkbpFEp9uG/LS1tZV3P33fN1gkyRB2LoRL+RR3f76m0HPHaby6F4Z5xr9Fv1URmATlRRUIpRQ==} - dependencies: - markdown-table: 2.0.0 - mdast-util-to-markdown: 0.6.5 - dev: false - - /mdast-util-gfm-task-list-item@0.1.6: - resolution: {integrity: sha512-/d51FFIfPsSmCIRNp7E6pozM9z1GYPIkSy1urQ8s/o4TC22BZ7DqfHFWiqBD23bc7J3vV1Fc9O4QIHBlfuit8A==} - dependencies: - mdast-util-to-markdown: 0.6.5 - dev: false - - /mdast-util-gfm@0.1.2: - resolution: {integrity: sha512-NNkhDx/qYcuOWB7xHUGWZYVXvjPFFd6afg6/e2g+SV4r9q5XUcCbV4Wfa3DLYIiD+xAEZc6K4MGaE/m0KDcPwQ==} - dependencies: - mdast-util-gfm-autolink-literal: 0.1.3 - mdast-util-gfm-strikethrough: 0.2.3 - mdast-util-gfm-table: 0.1.6 - mdast-util-gfm-task-list-item: 0.1.6 - mdast-util-to-markdown: 0.6.5 - transitivePeerDependencies: - - supports-color - dev: false - - /mdast-util-to-markdown@0.6.5: - resolution: {integrity: sha512-XeV9sDE7ZlOQvs45C9UKMtfTcctcaj/pGwH8YLbMHoMOXNNCn2LsqVQOqrF1+/NU8lKDAqozme9SCXWyo9oAcQ==} - dependencies: - '@types/unist': 2.0.10 - longest-streak: 2.0.4 - mdast-util-to-string: 2.0.0 - parse-entities: 2.0.0 - repeat-string: 1.6.1 - zwitch: 1.0.5 - dev: false - - /mdast-util-to-string@2.0.0: - resolution: {integrity: sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==} - dev: false - /mdurl@1.0.1: resolution: {integrity: sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==} dev: false @@ -467,78 +183,6 @@ packages: engines: {node: '>= 8'} dev: false - /micromark-extension-footnote@0.3.2: - resolution: {integrity: sha512-gr/BeIxbIWQoUm02cIfK7mdMZ/fbroRpLsck4kvFtjbzP4yi+OPVbnukTc/zy0i7spC2xYE/dbX1Sur8BEDJsQ==} - dependencies: - micromark: 2.11.4 - transitivePeerDependencies: - - supports-color - dev: false - - /micromark-extension-frontmatter@0.2.2: - resolution: {integrity: sha512-q6nPLFCMTLtfsctAuS0Xh4vaolxSFUWUWR6PZSrXXiRy+SANGllpcqdXFv2z07l0Xz/6Hl40hK0ffNCJPH2n1A==} - dependencies: - fault: 1.0.4 - dev: false - - /micromark-extension-gfm-autolink-literal@0.5.7: - resolution: {integrity: sha512-ePiDGH0/lhcngCe8FtH4ARFoxKTUelMp4L7Gg2pujYD5CSMb9PbblnyL+AAMud/SNMyusbS2XDSiPIRcQoNFAw==} - dependencies: - micromark: 2.11.4 - transitivePeerDependencies: - - supports-color - dev: false - - /micromark-extension-gfm-strikethrough@0.6.5: - resolution: {integrity: sha512-PpOKlgokpQRwUesRwWEp+fHjGGkZEejj83k9gU5iXCbDG+XBA92BqnRKYJdfqfkrRcZRgGuPuXb7DaK/DmxOhw==} - dependencies: - micromark: 2.11.4 - transitivePeerDependencies: - - supports-color - dev: false - - /micromark-extension-gfm-table@0.4.3: - resolution: {integrity: sha512-hVGvESPq0fk6ALWtomcwmgLvH8ZSVpcPjzi0AjPclB9FsVRgMtGZkUcpE0zgjOCFAznKepF4z3hX8z6e3HODdA==} - dependencies: - micromark: 2.11.4 - transitivePeerDependencies: - - supports-color - dev: false - - /micromark-extension-gfm-tagfilter@0.3.0: - resolution: {integrity: sha512-9GU0xBatryXifL//FJH+tAZ6i240xQuFrSL7mYi8f4oZSbc+NvXjkrHemeYP0+L4ZUT+Ptz3b95zhUZnMtoi/Q==} - dev: false - - /micromark-extension-gfm-task-list-item@0.3.3: - resolution: {integrity: sha512-0zvM5iSLKrc/NQl84pZSjGo66aTGd57C1idmlWmE87lkMcXrTxg1uXa/nXomxJytoje9trP0NDLvw4bZ/Z/XCQ==} - dependencies: - micromark: 2.11.4 - transitivePeerDependencies: - - supports-color - dev: false - - /micromark-extension-gfm@0.3.3: - resolution: {integrity: sha512-oVN4zv5/tAIA+l3GbMi7lWeYpJ14oQyJ3uEim20ktYFAcfX1x3LNlFGGlmrZHt7u9YlKExmyJdDGaTt6cMSR/A==} - dependencies: - micromark: 2.11.4 - micromark-extension-gfm-autolink-literal: 0.5.7 - micromark-extension-gfm-strikethrough: 0.6.5 - micromark-extension-gfm-table: 0.4.3 - micromark-extension-gfm-tagfilter: 0.3.0 - micromark-extension-gfm-task-list-item: 0.3.3 - transitivePeerDependencies: - - supports-color - dev: false - - /micromark@2.11.4: - resolution: {integrity: sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA==} - dependencies: - debug: 4.3.4 - parse-entities: 2.0.0 - transitivePeerDependencies: - - supports-color - dev: false - /micromatch@4.0.4: resolution: {integrity: sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==} engines: {node: '>=8.6'} @@ -547,25 +191,6 @@ packages: picomatch: 2.3.1 dev: false - /minimist@1.2.8: - resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - dev: false - - /ms@2.1.2: - resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} - dev: false - - /parse-entities@2.0.0: - resolution: {integrity: sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==} - dependencies: - character-entities: 1.2.4 - character-entities-legacy: 1.1.4 - character-reference-invalid: 1.1.4 - is-alphanumerical: 1.0.4 - is-decimal: 1.0.4 - is-hexadecimal: 1.0.4 - dev: false - /path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} @@ -580,44 +205,6 @@ packages: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} dev: false - /remark-footnotes@3.0.0: - resolution: {integrity: sha512-ZssAvH9FjGYlJ/PBVKdSmfyPc3Cz4rTWgZLI4iE/SX8Nt5l3o3oEjv3wwG5VD7xOjktzdwp5coac+kJV9l4jgg==} - dependencies: - mdast-util-footnote: 0.1.7 - micromark-extension-footnote: 0.3.2 - transitivePeerDependencies: - - supports-color - dev: false - - /remark-frontmatter@3.0.0: - resolution: {integrity: sha512-mSuDd3svCHs+2PyO29h7iijIZx4plX0fheacJcAoYAASfgzgVIcXGYSq9GFyYocFLftQs8IOmmkgtOovs6d4oA==} - dependencies: - mdast-util-frontmatter: 0.2.0 - micromark-extension-frontmatter: 0.2.2 - dev: false - - /remark-gfm@1.0.0: - resolution: {integrity: sha512-KfexHJCiqvrdBZVbQ6RopMZGwaXz6wFJEfByIuEwGf0arvITHjiKKZ1dpXujjH9KZdm1//XJQwgfnJ3lmXaDPA==} - dependencies: - mdast-util-gfm: 0.1.2 - micromark-extension-gfm: 0.3.3 - transitivePeerDependencies: - - supports-color - dev: false - - /remark-parse@9.0.0: - resolution: {integrity: sha512-geKatMwSzEXKHuzBNU1z676sGcDcFoChMK38TgdHJNAYfFtsfHDQG7MoJAjs6sgYMqyLduCYWDIWZIxiPeafEw==} - dependencies: - mdast-util-from-markdown: 0.8.5 - transitivePeerDependencies: - - supports-color - dev: false - - /repeat-string@1.6.1: - resolution: {integrity: sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==} - engines: {node: '>=0.10'} - dev: false - /reusify@1.0.4: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} @@ -646,77 +233,11 @@ packages: is-number: 7.0.0 dev: false - /traverse@0.6.8: - resolution: {integrity: sha512-aXJDbk6SnumuaZSANd21XAo15ucCDE38H4fkqiGsc3MhCK+wOlZvLP9cB/TvpHT0mOyWgC4Z8EwRlzqYSUzdsA==} - engines: {node: '>= 0.4'} - dev: false - - /trough@1.0.5: - resolution: {integrity: sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==} - dev: false - /uc.micro@1.0.6: resolution: {integrity: sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==} dev: false - /underscore@1.13.6: - resolution: {integrity: sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==} - dev: false - - /unified@9.2.2: - resolution: {integrity: sha512-Sg7j110mtefBD+qunSLO1lqOEKdrwBFBrR6Qd8f4uwkhWNlbkaqwHse6e7QvD3AP/MNoJdEDLaf8OxYyoWgorQ==} - dependencies: - '@types/unist': 2.0.10 - bail: 1.0.5 - extend: 3.0.2 - is-buffer: 2.0.5 - is-plain-obj: 2.1.0 - trough: 1.0.5 - vfile: 4.2.1 - dev: false - - /unist-util-is@4.1.0: - resolution: {integrity: sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==} - dev: false - - /unist-util-stringify-position@2.0.3: - resolution: {integrity: sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==} - dependencies: - '@types/unist': 2.0.10 - dev: false - - /unist-util-visit-parents@3.1.1: - resolution: {integrity: sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg==} - dependencies: - '@types/unist': 2.0.10 - unist-util-is: 4.1.0 - dev: false - - /update-section@0.3.3: - resolution: {integrity: sha512-BpRZMZpgXLuTiKeiu7kK0nIPwGdyrqrs6EDSaXtjD/aQ2T+qVo9a5hRC3HN3iJjCMxNT/VxoLGQ7E/OzE5ucnw==} - dev: false - - /vfile-message@2.0.4: - resolution: {integrity: sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==} - dependencies: - '@types/unist': 2.0.10 - unist-util-stringify-position: 2.0.3 - dev: false - - /vfile@4.2.1: - resolution: {integrity: sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==} - dependencies: - '@types/unist': 2.0.10 - is-buffer: 2.0.5 - unist-util-stringify-position: 2.0.3 - vfile-message: 2.0.4 - dev: false - /yaml@1.10.2: resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} engines: {node: '>= 6'} dev: false - - /zwitch@1.0.5: - resolution: {integrity: sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==} - dev: false diff --git a/specs/SUMMARY.md b/specs/SUMMARY.md new file mode 100644 index 000000000..f8b2d7d70 --- /dev/null +++ b/specs/SUMMARY.md @@ -0,0 +1,36 @@ +# Summary + +- [Root](./root.md) +- [Introduction](./introduction.md) +- [OP Stack Protocol](./protocol/overview.md) + - [Bridges](./protocol/bridges.md) + - [Messengers](./protocol/messengers.md) + - [Deposits](./protocol/deposits.md) + - [Withdrawals](./protocol/withdrawals.md) + - [Guaranteed Gas Market](./protocol/guaranteed-gas-market.md) + - [Proposals](./protocol/proposals.md) + - [Clients]() + - [Execution Engine](./protocol/exec-engine.md) + - [Rollup Node](./protocol/rollup-node.md) + - [Rollup Node P2P](./protocol/rollup-node-p2p.md) + - [Derivation](./protocol/derivation.md) + - [Span Batches](./protocol/span-batches.md) + - [Batch Submitter](./protocol/batcher.md) + - [Safe Liveness Checking](./protocol/safe-liveness-checking.md) + - [Predeploys](./protocol/predeploys.md) + - [Preinstalls](./protocol/preinstalls.md) + - [Superchain]() + - [Superchain Configuration](./protocol/superchain-configuration.md) + - [Superchain Upgrades](./protocol/superchain-upgrades.md) + - [System Config](./protocol/system_config.md) +- [Experimental]() + - [Fault Proof](./experimental/fault-proof/index.md) + - [Cannon Fault Proof VM](./experimental/fault-proof/cannon-fault-proof-vm.md) + - [Dispute Game Interface](./experimental/fault-proof/dispute-game-interface.md) + - [Fault Dispute Game](./experimental/fault-proof/fault-dispute-game.md) + - [Honest Challenger](./experimental/fault-proof/honest-challenger-fdg.md) +- [Glossary](./glossary.md) +- [Meta](./meta/index.md) + - [Linting](./meta/linting.md) + - [Versioning](./meta/versioning.md) + - [Markdown Style](./meta/markdown-style.md) diff --git a/specs/bond-manager.md b/specs/bond-manager.md deleted file mode 100644 index 7791b2e20..000000000 --- a/specs/bond-manager.md +++ /dev/null @@ -1,80 +0,0 @@ -# Bond Manager Interface - - - -**Table of Contents** - -- [Overview](#overview) -- [The Bond Problem](#the-bond-problem) - - [Simple Bond](#simple-bond) - - [Variable Bond](#variable-bond) - - - -## Overview - -In the context of permissionless output proposals, bonds are a value that must -be attached to an output proposal. In this case, the bond will be paid in ether. - -By requiring a bond to be posted with an output proposal, spam and invalid outputs -are disincentivized. Explicitly, if invalid outputs are proposed, challenge agents -can delete the invalid output via a [dispute-game](dispute-game-interface.md) and seize the -proposer's bond. So, posting invalid outputs is directly disincentivized in this way -since the proposer would lose their bond if the challenge agents seize it. - -Concretely, outputs will be permissionlessly proposed to the `L2OutputOracle` contract. -When submitting an output proposal, the ether value is sent as the bond. This bond is -then held by a bond manager contract. The bond manager contract is responsible for -both the [dispute-games](dispute-game-interface.md) and the `L2OutputOracle` (further detailed -in [proposals](proposals.md)). - -The bond manager will need to handle bond logic for a variety of different -[dispute-games](dispute-game-interface.md). In the simplest "attestation" dispute game, -bonds will not be required since the attestors are a permissioned set of trusted entities. -But in more complex games, such as the fault dispute game, challengers and defenders -perform a series of alternating onchain transactions requiring bonds at each step. - -## The Bond Problem - -At its core, the bond manager is straightforward - it escrows or holds ether and can be claimed -at maturity or seized if forfeited. But the uncertainty of introducing bonds lies in the -bond _sizing_, i.e. how much should a bond be? Sizing bonds correctly is a function of -the bond invariant: the bond must be greater than or equal to the cost of the next step. -If bonds are priced too low, then the bond invariant is violated and there isn't an economic -incentive to execute the next step. If bonds are priced too high, then the actors posting -bonds can be priced out. - -Below, we outline two different approaches to sizing bonds and the tradeoffs of each. - -### Simple Bond - -The _Simple Bond_ is a very conservative approach to bond management, establishing a **fixed** bond -size. The idea behind simple bond pricing is to establish the worst case gas cost for -the next step in the dispute game. - -With this approach, the size of the bond is computed up-front when a dispute game is created. -For example, in an attestation dispute game, this bond size can be computed as such: - -```md -bond_size = (signer_threshold * (challenge_gas + security overhead)) + resolution_gas(signer_threshold) -``` - -Notice that since the bond size is linearly proportional to the number of signers, the economic -security a given bond size provides decreases as the number of signers increases. Also note, the -`resolution_gas` function is split out from the `challenge_gas` cost because only the _last_ challenger -will pay for the gas cost to resolve the game in the attestation dispute game. - -Working backwards, if we assume the number of signers to be `5`, a negligible resolution gas cost, and -a `100,000` gas cost to progress the game, then the bond size should cover `500,000` gas. Meaning, a bond -of `1 ether` would cover the cost of progressing the game for `5` signers as long as the gas price -(base fee) does not exceed `2,000 gwei` for the entire finalization window. It would be prohibitively -expensive to keep the settlement layer base fee this high. - -### Variable Bond - -Better bond heuristics can be used to establish a bond price that accounts for -the time-weighted gas price. One instance of this called _Variable Bonds_ use a -separate oracle contract, `GasPriceFluctuationTracker`, that tracks gas fluctuations -within a pre-determined bounds. This replaces the ideal solution of tracking -challenge costs over all L1 blocks, but provides a reasonable bounds. The initial -actors posting this bond are responsible for funding this contract. diff --git a/specs/cannon-fault-proof-vm.md b/specs/experimental/fault-proof/cannon-fault-proof-vm.md similarity index 74% rename from specs/cannon-fault-proof-vm.md rename to specs/experimental/fault-proof/cannon-fault-proof-vm.md index 4a1e9ce7a..69a69fbb0 100644 --- a/specs/cannon-fault-proof-vm.md +++ b/specs/experimental/fault-proof/cannon-fault-proof-vm.md @@ -1,24 +1,8 @@ -# Cannon Fault Proof Virtual Machine Specification +# Cannon Fault Proof Virtual Machine - - **Table of Contents** -- [Overview](#overview) -- [State](#state) - - [State Hash](#state-hash) -- [Memory](#memory) - - [Heap](#heap) -- [Delay Slots](#delay-slots) -- [Syscalls](#syscalls) -- [I/O](#io) - - [Standard Streams](#standard-streams) - - [Hint Communication](#hint-communication) - - [Pre-image Communication](#pre-image-communication) - - [Pre-image I/O Alignment](#pre-image-io-alignment) -- [Exceptions](#exceptions) - - + ## Overview @@ -27,7 +11,7 @@ a minimal Linux-based system running on big-endian 32-bit MIPS32 architecture. A lot of its behaviors are copied from Linux/MIPS with a few tweaks made for fault proofs. For the rest of this doc, we refer to the Cannon FPVM as simply the FPVM. -Operationally, the FPVM is a state transition function. This state transition is referred to as a *Step*, +Operationally, the FPVM is a state transition function. This state transition is referred to as a _Step_, that executes a single instruction. We say the VM is a function $f$, given an input state $S_{pre}$, steps on a single instruction encoded in the state to produce a new state $S_{post}$. $$f(S_{pre}) \rightarrow S_{post}$$ @@ -44,7 +28,7 @@ It consists of the following fields: 3. `preimageOffset` - The 32-bit value of the last requested pre-image offset. 4. `pc` - 32-bit program counter. 5. `nextPC` - 32-bit next program counter. Note that this value may not always be $pc+4$ - when executing a branch/jump delay slot. + when executing a branch/jump delay slot. 6. `lo` - 32-bit MIPS LO special register. 7. `hi` - 32-bit MIPS HI special register. 8. `heap` - 32-bit base address of the most recent memory allocation via mmap. @@ -126,15 +110,15 @@ syscall calling conventions and general syscall handling behavior. However, the FPVM supports a subset of Linux/MIPS syscalls with slightly different behaviors. The following table list summarizes the supported syscalls and their behaviors. -| $v0 | system call | $a0 | $a1 | $a2 | Effect | -| -- | -- | -- | -- | -- | -- | -| 4090 | mmap | uint32 addr | uint32 len | | Allocates a page from the heap. See [heap](#heap) for details. | -| 4045 | brk | | | | Returns a fixed address for the program break at `0x40000000` | -| 4120 | clone | | | | Returns 1 | -| 4246 | exit_group | uint8 exit_code | | | Sets the Exited and ExitCode states to `true` and `$a0` respectively. | -| 4003 | read | uint32 fd | char *buf | uint32 count | Similar behavior as Linux/MIPS with support for unaligned reads. See [I/O](#io) for more details. | -| 4004 | write | uint32 fd | char *buf | uint32 count | Similar behavior as Linux/MIPS with support for unaligned writes. See [I/O](#io) for more details. | -| 4055 | fcntl | uint32 fd | int32 cmd | | Similar behavior as Linux/MIPS. Only the `F_GETFL` (3) cmd is supported. Sets errno to `0x16` for all other commands | +| \$v0 | system call | \$a0 | \$a1 | \$a2 | Effect | +| ---- | ----------- | --------------- | ---------- | ------------ | -------------------------------------------------------------------------------------------------------------------- | +| 4090 | mmap | uint32 addr | uint32 len | 🚫 | Allocates a page from the heap. See [heap](#heap) for details. | +| 4045 | brk | 🚫 | 🚫 | 🚫 | Returns a fixed address for the program break at `0x40000000` | +| 4120 | clone | 🚫 | 🚫 | 🚫 | Returns 1 | +| 4246 | exit_group | uint8 exit_code | 🚫 | 🚫 | Sets the Exited and ExitCode states to `true` and `$a0` respectively. | +| 4003 | read | uint32 fd | char \*buf | uint32 count | Similar behavior as Linux/MIPS with support for unaligned reads. See [I/O](#io) for more details. | +| 4004 | write | uint32 fd | char \*buf | uint32 count | Similar behavior as Linux/MIPS with support for unaligned writes. See [I/O](#io) for more details. | +| 4055 | fcntl | uint32 fd | int32 cmd | 🚫 | Similar behavior as Linux/MIPS. Only the `F_GETFL` (3) cmd is supported. Sets errno to `0x16` for all other commands | For all of the above syscalls, an error is indicated by setting the return register (`$v0`) to `0xFFFFFFFF` (-1) and `errno` (`$a3`) is set accordingly. @@ -147,15 +131,16 @@ Note that the above syscalls have identical syscall numbers and ABIs as Linux/MI ## I/O The VM does not support Linux open(2). However, the VM can read from and write to a predefined set of file descriptors. -| Name | File descriptor | Description | -| ---- | --------------- | ----------- | -| stdin | 0 | read-only standard input stream. | -| stdout | 1 | write-only standard output stream. | -| stderr | 2 | write-only standard error stream. | -| hint response | 3 | read-only. Used to read the status of [pre-image hinting](fault-proof.md#hinting). | -| hint request | 4 | write-only. Used to provide [pre-image hints](fault-proof.md#hinting) | -| pre-image response | 5 | read-only. Used to [read pre-images](fault-proof.md#pre-image-communication). | -| pre-image request | 6 | write-only. Used to [request pre-images](fault-proof.md#pre-image-communication). | + +| Name | File descriptor | Description | +| ------------------ | --------------- | ---------------------------------------------------------------------------- | +| stdin | 0 | read-only standard input stream. | +| stdout | 1 | write-only standard output stream. | +| stderr | 2 | write-only standard error stream. | +| hint response | 3 | read-only. Used to read the status of [pre-image hinting](index.md#hinting). | +| hint request | 4 | write-only. Used to provide [pre-image hints](index.md#hinting) | +| pre-image response | 5 | read-only. Used to [read pre-images](index.md#pre-image-communication). | +| pre-image request | 6 | write-only. Used to [request pre-images](index.md#pre-image-communication). | Syscalls referencing unknown file descriptors fail with an `EBADF` errno as done on Linux. @@ -209,7 +194,7 @@ The FPVM may raise an exception rather than output a post-state to signal an inv transition. Nominally, the FPVM must raise an exception in at least the following cases: - Invalid instruction (either via an invalid opcode or an instruction referencing registers -outside the general purpose registers). + outside the general purpose registers). - Pre-image read at an offset larger than the size of the pre-image. - Delay slot contains branch/jump instruction types. diff --git a/specs/dispute-game-interface.md b/specs/experimental/fault-proof/dispute-game-interface.md similarity index 96% rename from specs/dispute-game-interface.md rename to specs/experimental/fault-proof/dispute-game-interface.md index 74b269eee..7ba4e4d44 100644 --- a/specs/dispute-game-interface.md +++ b/specs/experimental/fault-proof/dispute-game-interface.md @@ -1,15 +1,8 @@ # Dispute Game Interface - - **Table of Contents** -- [Overview](#overview) -- [Types](#types) -- [`DisputeGameFactory` Interface](#disputegamefactory-interface) -- [`DisputeGame` Interface](#disputegame-interface) - - + ## Overview diff --git a/specs/fault-dispute-game.md b/specs/experimental/fault-proof/fault-dispute-game.md similarity index 95% rename from specs/fault-dispute-game.md rename to specs/experimental/fault-proof/fault-dispute-game.md index e4e11c134..d1756b67b 100644 --- a/specs/fault-dispute-game.md +++ b/specs/experimental/fault-proof/fault-dispute-game.md @@ -1,37 +1,12 @@ # Fault Dispute Game - - **Table of Contents** -- [Overview](#overview) -- [Definitions](#definitions) - - [Virtual Machine (VM)](#virtual-machine-vm) - - [PreimageOracle](#preimageoracle) - - [Execution Trace](#execution-trace) - - [Claims](#claims) - - [DAG](#dag) - - [Subgame](#subgame) - - [Game Tree](#game-tree) - - [Position](#position) - - [GAME_DURATION](#game_duration) -- [Game Mechanics](#game-mechanics) - - [Actors](#actors) - - [Moves](#moves) - - [Attack](#attack) - - [Defend](#defend) - - [Step](#step) - - [Step Types](#step-types) - - [PreimageOracle Interaction](#preimageoracle-interaction) - - [Team Dynamics](#team-dynamics) - - [Game Clock](#game-clock) - - [Resolution](#resolution) - - + -[g-output-root]: glossary.md#L2-output-root +[g-output-root]: ../../glossary.md#L2-output-root ## Overview @@ -115,7 +90,7 @@ $2^{d-1}$ positions, where $d$ is the `MAX_GAME_DEPTH` (unless $d=0$, in which c The full game tree, with a layer of the tree allocated to output bisection, and sub-trees after an arbitrary split depth, looks like: -![ob-tree](assets/ob-tree.png) +![ob-tree](../../static/assets/ob-tree.png) ### Position @@ -176,7 +151,7 @@ The attack position relative to a node can be calculated by multiplying its gind To illustrate this, here's a Game Tree highlighting an attack on a Claim positioned at 6. -![Attacking node 6](assets/attack.png) +![Attacking node 6](../../static/assets/attack.png) Attacking the node at 6 moves creates a new claim positioned at 12. @@ -185,14 +160,14 @@ Attacking the node at 6 moves creates a new claim positioned at 12. The logical move against a claim when you agree with both it and its parent. A defense at the relative position to a node, `n`, in the Game Tree commits to the first half of n + 1’s trace range. -![Defend at 4](assets/defend.png) +![Defend at 4](../../static/assets/defend.png) Note that because of this, some nodes may never exist within the Game Tree. However, they're not necessary as these nodes have complimentary, valid positions with the same trace index within the tree. For example, a Position with gindex 5 has the same trace index as another Position with gindex 2. We can verify that all trace indices have valid moves within the game: -![Game Tree Showing All Valid Move Positions](assets/valid-moves.png) +![Game Tree Showing All Valid Move Positions](../../static/assets/valid-moves.png) There may be multiple claims at the same position, so long as their `ClaimHash` are unique. diff --git a/specs/honest-challenger-fdg.md b/specs/experimental/fault-proof/honest-challenger-fdg.md similarity index 87% rename from specs/honest-challenger-fdg.md rename to specs/experimental/fault-proof/honest-challenger-fdg.md index 48ea5d241..351af2130 100644 --- a/specs/honest-challenger-fdg.md +++ b/specs/experimental/fault-proof/honest-challenger-fdg.md @@ -1,17 +1,8 @@ # Honest Challenger (Fault Dispute Game) - - **Table of Contents** -- [Overview](#overview) -- [FDG Responses](#fdg-responses) - - [Root Claims](#root-claims) - - [Counter Claims](#counter-claims) - - [Steps](#steps) -- [Resolution](#resolution) - - + The honest challenger is an agent interacting in the [Fault Dispute Game](fault-dispute-game.md) (FDG) that supports honest claims and disputes false claims. @@ -42,13 +33,13 @@ When a `FaultDisputeGame` is created, the honest challenger has two possible cor to its root claim: 1. [**Attack**](fault-dispute-game.md#attack) if they disagree with the root claim. -The root claim commits to the entire execution trace, so the first move here is to -attack with the [ClaimHash](fault-dispute-game.md#claims) at the midpoint -instruction within their execution trace. + The root claim commits to the entire execution trace, so the first move here is to + attack with the [ClaimHash](fault-dispute-game.md#claims) at the midpoint + instruction within their execution trace. 2. **Do Nothing** if they agree with the root claim. They do nothing because if the root -claim is left un-countered, the game resolves to their agreement. -NOTE: The honest challenger will still track this game in order to defend any subsequent -claims made against the root claim - in effect, "playing the game". + claim is left un-countered, the game resolves to their agreement. + NOTE: The honest challenger will still track this game in order to defend any subsequent + claims made against the root claim - in effect, "playing the game". ### Counter Claims diff --git a/specs/fault-proof.md b/specs/experimental/fault-proof/index.md similarity index 89% rename from specs/fault-proof.md rename to specs/experimental/fault-proof/index.md index f94e300ee..e3c709c85 100644 --- a/specs/fault-proof.md +++ b/specs/experimental/fault-proof/index.md @@ -1,38 +1,8 @@ # Fault Proof - - **Table of Contents** -- [Overview](#overview) -- [Pre-image Oracle](#pre-image-oracle) - - [Pre-image key types](#pre-image-key-types) - - [Type `0`: Zero key](#type-0-zero-key) - - [Type `1`: Local key](#type-1-local-key) - - [Type `2`: Global keccak256 key](#type-2-global-keccak256-key) - - [Type `3`: Global generic key](#type-3-global-generic-key) - - [Type `4-128`: reserved range](#type-4-128-reserved-range) - - [Type `129-255`: application usage](#type-129-255-application-usage) - - [Bootstrapping](#bootstrapping) - - [Hinting](#hinting) - - [Pre-image communication](#pre-image-communication) -- [Fault Proof Program](#fault-proof-program) - - [Prologue](#prologue) - - [Main content](#main-content) - - [Epilogue](#epilogue) - - [Pre-image hinting routes](#pre-image-hinting-routes) - - [`l1-block-header `](#l1-block-header-blockhash) - - [`l1-transactions `](#l1-transactions-blockhash) - - [`l1-receipts `](#l1-receipts-blockhash) - - [`l2-block-header `](#l2-block-header-blockhash) - - [`l2-transactions `](#l2-transactions-blockhash) - - [`l2-code `](#l2-code-codehash) - - [`l2-state-node `](#l2-state-node-nodehash) - - [`l2-output `](#l2-output-outputroot) -- [Fault Proof VM](#fault-proof-vm) -- [Fault Proof Interactive Dispute Game](#fault-proof-interactive-dispute-game) - - + ## Overview @@ -48,7 +18,7 @@ and contribute to proof diversity when resolving a dispute. "Stateless execution" of the program, and its individual instructions, refers to reproducing the exact same computation by authenticating the inputs with a [Pre-image Oracle][oracle]. -![Diagram of Program and VM architecture](assets/fault-proof.svg) +![Diagram of Program and VM architecture](../../static/assets/fault-proof.svg) ## Pre-image Oracle @@ -156,7 +126,7 @@ a local lookup for type `1`, or global one for `2`, and optionally support other ### Hinting There is one more form of optional communication between client and server: pre-image hinting. -Hinting is optional, and *is a no-op* in a L1 VM implementation. +Hinting is optional, and _is a no-op_ in a L1 VM implementation. The hint itself comes at very low cost onchain: the hint can be a single `write` sys-call, which is instant as the memory to write as hint does not actually need to be loaded as part of the onchain proof. @@ -247,7 +217,7 @@ The program is bootstrapped with two primary inputs: Bootstrapping happens through special input requests to the host of the program. -Additionally, there are *implied* inputs, which are *derived from the above primary inputs*, +Additionally, there are _implied_ inputs, which are _derived from the above primary inputs_, but can be overridden for testing purposes: - `l2_head`: the L2 block hash that will be perceived as the previously agreed upon tip of the L2 chain, @@ -273,8 +243,9 @@ During testing a simplified prologue that loads the overrides may be used. To verify a claim about L2 state, the program first reproduces the L2 state by applying L1 data to prior agreed L2 history. -This process is also known as the [L2 derivation process](derivation.md), -and matches the processing in the [rollup node](rollup-node.md) and [execution-engine](exec-engine.md). +This process is also known as the [L2 derivation process](../../protocol/derivation.md), +and matches the processing in the [rollup node](../../protocol/rollup-node.md) and +[execution-engine](../../protocol/exec-engine.md). The difference is that rather than retrieving inputs from an RPC and applying state changes to disk, the inputs are loaded through the [pre-image oracle][oracle] and the changes accumulate in memory. @@ -328,7 +299,8 @@ to then make a statement about the claim with the final exit code. A disputed output-root may be disproven by first producing the output-root, and then comparing it: 1. Retrieve the output attributes from the L2 chain view: the state-root, block-hash, withdrawals storage-root. -2. Compute the output-root, as the [proposer should compute it](proposals.md#l2-output-commitment-construction). +2. Compute the output-root, as the + [proposer should compute it](../../protocol/proposals.md#l2-output-commitment-construction). 3. If the output-root matches the `claim`, exit with code 0. Otherwise, exit with code 1. > Note: the dispute game interface is actively changing, and may require additional claim assertions. @@ -376,7 +348,8 @@ Requests the host to prepare the L2 MPT node preimage with the given ` #### `l2-output ` Requests the host to prepare the L2 Output at the l2 output root ``. -The L2 Output is the preimage of a [computed output root](proposals.md#l2-output-commitment-construction). +The L2 Output is the preimage of a +[computed output root](../../protocol/proposals.md#l2-output-commitment-construction). ## Fault Proof VM @@ -399,9 +372,11 @@ Refer to the documentation of the fault proof VM for further usage information. Fault Proof VMs: - [Cannon]: big-endian 32-bit MIPS proof, by OP Labs, in active development. +- [cannon-rs]: Rust implementation of `Cannon`, by `@clabby`, in active development. - [Asterisc]: little-endian 64-bit RISC-V proof, by `@protolambda`, in active development. [Cannon]: https://github.com/ethereum-optimism/cannon +[cannon-rs]: https://github.com/anton-rs/cannon-rs [Asterisc]: https://github.com/protolambda/asterisc ## Fault Proof Interactive Dispute Game diff --git a/specs/glossary.md b/specs/glossary.md index e1f05d27d..b827b3d59 100644 --- a/specs/glossary.md +++ b/specs/glossary.md @@ -1,80 +1,10 @@ # Glossary - - **Table of Contents** -- [General Terms](#general-terms) - - [Layer 1 (L1)](#layer-1-l1) - - [Layer 2 (L2)](#layer-2-l2) - - [Block](#block) - - [EOA](#eoa) - - [Merkle Patricia Trie](#merkle-patricia-trie) - - [Chain Re-Organization](#chain-re-organization) - - [Predeployed Contract ("Predeploy")](#predeployed-contract-predeploy) - - [Preinstalled Contract ("Preinstall")](#preinstalled-contract-preinstall) - - [Receipt](#receipt) - - [Transaction Type](#transaction-type) - - [Fork Choice Rule](#fork-choice-rule) - - [Priority Gas Auction](#priority-gas-auction) -- [Sequencing](#sequencing) - - [Sequencer](#sequencer) - - [Sequencing Window](#sequencing-window) - - [Sequencing Epoch](#sequencing-epoch) - - [L1 Origin](#l1-origin) -- [Deposits](#deposits) - - [Deposited Transaction](#deposited-transaction) - - [L1 Attributes Deposited Transaction](#l1-attributes-deposited-transaction) - - [User-Deposited Transaction](#user-deposited-transaction) - - [Depositing Call](#depositing-call) - - [Depositing Transaction](#depositing-transaction) - - [Depositor](#depositor) - - [Deposited Transaction Type](#deposited-transaction-type) - - [Deposit Contract](#deposit-contract) -- [Withdrawals](#withdrawals) - - [Relayer](#relayer) - - [Finalization Period](#finalization-period) -- [Batch Submission](#batch-submission) - - [Data Availability](#data-availability) - - [Data Availability Provider](#data-availability-provider) - - [Sequencer Batch](#sequencer-batch) - - [Channel](#channel) - - [Channel Frame](#channel-frame) - - [Batcher](#batcher) - - [Batcher Transaction](#batcher-transaction) - - [Channel Timeout](#channel-timeout) -- [L2 Output Root Proposals](#l2-output-root-proposals) - - [Proposer](#proposer) -- [L2 Chain Derivation](#l2-chain-derivation) - - [L2 Derivation Inputs](#l2-derivation-inputs) - - [System Configuration](#system-configuration) - - [Payload Attributes](#payload-attributes) - - [L2 Genesis Block](#l2-genesis-block) - - [L2 Chain Inception](#l2-chain-inception) - - [Safe L2 Block](#safe-l2-block) - - [Safe L2 Head](#safe-l2-head) - - [Unsafe L2 Block](#unsafe-l2-block) - - [Unsafe L2 Head](#unsafe-l2-head) - - [Unsafe Block Consolidation](#unsafe-block-consolidation) - - [Finalized L2 Head](#finalized-l2-head) -- [Other L2 Chain Concepts](#other-l2-chain-concepts) - - [Address Aliasing](#address-aliasing) - - [Rollup Node](#rollup-node) - - [Rollup Driver](#rollup-driver) - - [L1 Attributes Predeployed Contract](#l1-attributes-predeployed-contract) - - [L2 Output Root](#l2-output-root) - - [L2 Output Oracle Contract](#l2-output-oracle-contract) - - [Validator](#validator) - - [Fault Proof](#fault-proof) - - [Time Slot](#time-slot) - - [Block Time](#block-time) - - [Unsafe Sync](#unsafe-sync) -- [Execution Engine Concepts](#execution-engine-concepts) - - [Execution Engine](#execution-engine) - - - ------------------------------------------------------------------------------------------------------------------------- + + +--- # General Terms @@ -97,7 +27,7 @@ refers to the Ethereum blockchain. Can refer to an [L1] block, or to an [L2] block, which are structured similarly. -A block is a sequential list of transactions, along with a couple of properties stored in the *header* of the block. A +A block is a sequential list of transactions, along with a couple of properties stored in the _header_ of the block. A description of these properties can be found in code comments [here][nano-header], or in the [Ethereum yellow paper (pdf)][yellow], section 4.3. @@ -136,7 +66,7 @@ L1 re-orgs can happen because of network conditions or attacks. L2 re-orgs are a A contract placed in the L2 genesis state (i.e. at the start of the chain). -All predeploy contracts are specified in the [predeploys specification][./predeploys.md]. +All predeploy contracts are specified in the [predeploys specification](./protocol/predeploys.md). ## Preinstalled Contract ("Preinstall") @@ -146,7 +76,7 @@ A contract placed in the L2 genesis state (i.e. at the start of the chain). Thes security guarantees as [predeploys](#predeployed-contract-predeploy), but are general use contracts made available to improve the L2's UX. -All preinstall contracts are specified in the [preinstalls specification][./preinstalls.md]. +All preinstall contracts are specified in the [preinstalls specification](./protocol/preinstalls.md). ## Receipt @@ -188,7 +118,7 @@ parties (like being the first deposit or submitting a deposit before there is no PGAs tend to have negative externalities on the network due to a large amount of transactions being submitted in a very short amount of time. ------------------------------------------------------------------------------------------------------------------------- +--- # Sequencing @@ -244,7 +174,7 @@ for more details. The L1 origin of an L2 block is the L1 block corresponding to its [sequencing epoch][sequencing-epoch]. ------------------------------------------------------------------------------------------------------------------------- +--- # Deposits @@ -253,30 +183,28 @@ The L1 origin of an L2 block is the L1 block corresponding to its [sequencing ep In general, a deposit is an L2 transaction derived from an L1 block (by the [rollup driver]). While transaction deposits are notably (but not only) used to "deposit" (bridge) ETH and tokens to L2, the word -*deposit* should be understood as "a transaction *deposited* to L2 from L1". +_deposit_ should be understood as "a transaction _deposited_ to L2 from L1". -This term *deposit* is somewhat ambiguous as these "transactions" exist at multiple levels. This section disambiguates +This term _deposit_ is somewhat ambiguous as these "transactions" exist at multiple levels. This section disambiguates all deposit-related terms. -Notably, a *deposit* can refer to: +Notably, a _deposit_ can refer to: -- A [deposited transaction][deposited] (on L2) that is part of a [deposit block][deposit-block]. +- A [deposited transaction][deposited] (on L2) that is part of a deposit block. - A [depositing call][depositing-call] that causes a [deposited transaction][deposited] to be derived. - The event/log data generated by the [depositing call][depositing-call], which is what the [rollup driver] reads to derive the [deposited transaction][deposited]. -We sometimes also talk about *user deposit* which is a similar term that explicitly excludes [L1 attributes deposited +We sometimes also talk about _user deposit_ which is a similar term that explicitly excludes [L1 attributes deposited transactions][l1-attr-deposit]. Deposits are specified in the [deposits specification][deposits-spec]. -[deposits-spec]: deposits.md - ## Deposited Transaction [deposited]: glossary.md#deposited-transaction -A *deposited transaction* is a L2 transaction that was derived from L1 and included in a L2 block. +A _deposited transaction_ is a L2 transaction that was derived from L1 and included in a L2 block. There are two kinds of deposited transactions: @@ -285,38 +213,36 @@ There are two kinds of deposited transactions: - [User-deposited transactions][user-deposited], which are transactions derived from an L1 call to the [deposit contract][deposit-contract]. -[deposits-spec]: deposits.md - ## L1 Attributes Deposited Transaction [l1-attr-deposit]: glossary.md#l1-attributes-deposited-transaction -An *L1 attributes deposited transaction* is [deposited transaction][deposited] that is used to register the L1 block +An _L1 attributes deposited transaction_ is [deposited transaction][deposited] that is used to register the L1 block attributes (number, timestamp, ...) on L2 via a call to the [L1 Attributes Predeployed Contract][l1-attr-predeploy]. That contract can then be used to read the attributes of the L1 block corresponding to the current L2 block. L1 attributes deposited transactions are specified in the [L1 Attributes Deposit][l1-attributes-tx-spec] section of the deposits specification. -[l1-attributes-tx-spec]: deposits.md#l1-attributes-deposited-transaction +[l1-attributes-tx-spec]: ./protocol/deposits.md#l1-attributes-deposited-transaction ## User-Deposited Transaction [user-deposited]: glossary.md#user-deposited-transaction -A *user-deposited transaction* is a [deposited transaction][deposited] which is derived from an L1 call to the [deposit - contract][deposit-contract] (a [depositing call][depositing-call]). +A _user-deposited transaction_ is a [deposited transaction][deposited] which is derived from an L1 call to the [deposit +contract][deposit-contract] (a [depositing call][depositing-call]). User-deposited transactions are specified in the [Transaction Deposits][tx-deposits-spec] section of the deposits specification. -[tx-deposits-spec]: deposits.md#user-deposited-transactions +[tx-deposits-spec]: ./protocol/deposits.md#user-deposited-transactions ## Depositing Call [depositing-call]: glossary.md#depositing-call -A *depositing call* is an L1 call to the [deposit contract][deposit-contract], which will be derived to a +A _depositing call_ is an L1 call to the [deposit contract][deposit-contract], which will be derived to a [user-deposited transaction][user-deposited] by the [rollup driver]. This call specifies all the data (destination, value, calldata, ...) for the deposited transaction. @@ -325,40 +251,40 @@ This call specifies all the data (destination, value, calldata, ...) for the dep [depositing-tx]: glossary.md#depositing-transaction -A *depositing transaction* is an L1 transaction that makes one or more [depositing calls][depositing-call]. +A _depositing transaction_ is an L1 transaction that makes one or more [depositing calls][depositing-call]. ## Depositor [depositor]: glossary.md#depositor -The *depositor* is the L1 account (contract or [EOA]) that makes (is the `msg.sender` of) the [depositing -call][depositing-call]. The *depositor* is **NOT** the originator of the depositing transaction (i.e. `tx.origin`). +The _depositor_ is the L1 account (contract or [EOA]) that makes (is the `msg.sender` of) the [depositing +call][depositing-call]. The _depositor_ is **NOT** the originator of the depositing transaction (i.e. `tx.origin`). ## Deposited Transaction Type [deposit-tx-type]: glossary.md#deposited-transaction-type -The *deposited transaction type* is an [EIP-2718] [transaction type][transaction-type], which specifies the input fields +The _deposited transaction type_ is an [EIP-2718] [transaction type][transaction-type], which specifies the input fields and correct handling of a [deposited transaction][deposited]. See the [corresponding section][spec-deposit-tx-type] of the deposits spec for more information. -[spec-deposit-tx-type]: deposits.md#the-deposited-transaction-type +[spec-deposit-tx-type]: ./protocol/deposits.md#the-deposited-transaction-type ## Deposit Contract [deposit-contract]: glossary.md#deposit-contract -The *deposit contract* is an [L1] contract to which [EOAs][EOA] and contracts may send [deposits]. The deposits are -emitted as log records (in Solidity, these are called *events*) for consumption by [rollup nodes][rollup-node]. +The _deposit contract_ is an [L1] contract to which [EOAs][EOA] and contracts may send [deposits]. The deposits are +emitted as log records (in Solidity, these are called _events_) for consumption by [rollup nodes][rollup-node]. Advanced note: the deposits are not stored in calldata because they can be sent by contracts, in which case the calldata -is part of the *internal* execution between contracts, and this intermediate calldata is not captured in one of the +is part of the _internal_ execution between contracts, and this intermediate calldata is not captured in one of the [Merkle Patricia Trie roots][mpt] included in the L1 block. -cf. [Deposits Specification](deposits.md) +cf. [Deposits Specification][deposits-spec] ------------------------------------------------------------------------------------------------------------------------- +--- # Withdrawals @@ -368,11 +294,11 @@ cf. [Deposits Specification](deposits.md) In general, a withdrawal is a transaction sent from L2 to L1 that may transfer data and/or value. -The term *withdrawal* is somewhat ambiguous as these "transactions" exist at multiple levels. In order to differentiate - between the L1 and L2 components of a withdrawal we introduce the following terms: +The term _withdrawal_ is somewhat ambiguous as these "transactions" exist at multiple levels. In order to differentiate +between the L1 and L2 components of a withdrawal we introduce the following terms: -- A *withdrawal initiating transaction* refers specifically to a transaction on L2 sent to the Withdrawals predeploy. -- A *withdrawal finalizing transaction* refers specifically to an L1 transaction which finalizes and relays the +- A _withdrawal initiating transaction_ refers specifically to a transaction on L2 sent to the Withdrawals predeploy. +- A _withdrawal finalizing transaction_ refers specifically to an L1 transaction which finalizes and relays the withdrawal. ## Relayer @@ -385,15 +311,15 @@ An EOA on L1 which finalizes a withdrawal by submitting the data necessary to ve [finalization-period]: glossary.md#finalization-period -The finalization period β€” sometimes also called *withdrawal delay* β€” is the minimum amount of time (in seconds) that -must elapse before a [withdrawal][withrawals] can be finalized. +The finalization period β€” sometimes also called _withdrawal delay_ β€” is the minimum amount of time (in seconds) that +must elapse before a [withdrawal][withdrawals] can be finalized. The finalization period is necessary to afford sufficient time for [validators][validator] to make a [fault proof][fault-proof]. > **TODO** specify current value for finalization period ------------------------------------------------------------------------------------------------------------------------- +--- # Batch Submission @@ -401,9 +327,9 @@ proof][fault-proof]. ## Data Availability - [data-availability]: glossary.md#data-availability +[data-availability]: glossary.md#data-availability -Data availability is the guarantee that some data will be "available" (i.e. *retrievable*) during a reasonably long time +Data availability is the guarantee that some data will be "available" (i.e. _retrievable_) during a reasonably long time window. In Optimism's case, the data in question are [sequencer batches][sequencer-batch] that [validators][validator] need in order to verify the sequencer's work and validate the L2 chain. @@ -419,7 +345,7 @@ that is when data availability is the most crucial, as it is needed to perform a A data availability provider is a service that can be used to make data available. See the [Data Availability][data-availability] for more information on what this means. -Ideally, a good data availability provider provides strong *verifiable* guarantees of data availability +Ideally, a good data availability provider provides strong _verifiable_ guarantees of data availability Currently, the only supported data availability provider is Ethereum call data. [Ethereum data blobs][eip4844] will be supported when they get deployed on Ethereum. @@ -451,10 +377,10 @@ include in a single batcher transaction. A channel is uniquely identified by its timestamp (UNIX time at which the channel was created) and a random value. See the [Frame Format][frame-format] section of the L2 Chain Derivation specification for more information. -[frame-format]: derivation.md#frame-format +[frame-format]: ./protocol/derivation.md#frame-format On the side of the [rollup node][rollup-node] (which is the consumer of channels), a channel is considered to be -*opened* if its final frame (explicitly marked as such) has not been read, or closed otherwise. +_opened_ if its final frame (explicitly marked as such) has not been read, or closed otherwise. ## Channel Frame @@ -507,11 +433,11 @@ The purpose of channel timeouts is dual: channels. This is particularly relevant during L1 re-orgs, see the [Resetting Channel Buffering][reset-channel-buffer] section of the L2 Chain Derivation specification for more information. -[reset-channel-buffer]: derivation.md#resetting-channel-buffering +[reset-channel-buffer]: ./protocol/derivation.md#resetting-channel-buffering > **TODO** specify `CHANNEL_TIMEOUT` ------------------------------------------------------------------------------------------------------------------------- +--- # L2 Output Root Proposals @@ -526,7 +452,7 @@ L2OutputOracle contract on L1 (the settlement layer). To do this, the proposer p the latest output root derived from the latest finalized L1 block. It then takes the output root and submits it to the L2OutputOracle contract on the settlement layer (L1). ------------------------------------------------------------------------------------------------------------------------- +--- # L2 Chain Derivation @@ -560,7 +486,7 @@ L2 derivation inputs include: [system-config]: glossary.md#system-configuration This term refers to the collection of dynamically configurable rollup parameters maintained -by the [`SystemConfig`](system_config.md) contract on L1 and read by the L2 [derivation] process. +by the [`SystemConfig`][system-config] contract on L1 and read by the L2 [derivation] process. These parameters enable keys to be rotated regularly and external cost parameters to be adjusted without the network upgrade overhead of a hardfork. @@ -574,11 +500,11 @@ then passed to the [execution engine][execution-engine] to construct L2 blocks. The payload attributes object essentially encodes [a block without output properties][block]. Payload attributes are originally specified in the [Ethereum Engine API specification][engine-api], which we expand in -the [Execution Engine Specification](exec-engine.md). +the [Execution Engine Specification][exec-engine]. See also the [Building The Payload Attributes][building-payload-attr] section of the rollup node specification. -[building-payload-attr]: rollup-node.md#building-the-payload-attributes +[building-payload-attr]: ./protocol/rollup-node.md#building-the-payload-attributes ## L2 Genesis Block @@ -596,11 +522,11 @@ The state of the L2 genesis block comprises: The timestamp of the L2 genesis block must be a multiple of the [block time][block-time] (i.e. a even number, since the block time is 2 seconds). -When updating the rollup protocol to a new version, we may perform a *squash fork*, a process that entails the creation +When updating the rollup protocol to a new version, we may perform a _squash fork_, a process that entails the creation of a new L2 genesis block. This new L2 genesis block will have block number `X + 1`, where `X` is the block number of the final L2 block before the update. -A squash fork is not to be confused with a *re-genesis*, a similar process that we employed in the past, which also +A squash fork is not to be confused with a _re-genesis_, a similar process that we employed in the past, which also resets L2 block numbers, such that the new L2 genesis block has number 0. We will not employ re-genesis in the future. Squash forks are superior to re-geneses because they avoid duplicating L2 block numbers, which breaks a lot of external @@ -654,18 +580,18 @@ chain match the oldest unsafe L2 block exactly. See the [Engine Queue section][engine-queue] of the L2 chain derivatiaon spec for more information. -[engine-queue]: derivation.md#engine-queue +[engine-queue]: ./protocol/derivation.md#engine-queue ## Finalized L2 Head [finalized-l2-head]: glossary.md#finalized-l2-head -The finalized L2 head is the highest L2 block that can be derived from *[finalized][finality]* L1 blocks β€” i.e. L1 +The finalized L2 head is the highest L2 block that can be derived from _[finalized][finality]_ L1 blocks β€” i.e. L1 blocks older than two L1 epochs (64 L1 [time slots][time-slot]). [finality]: https://hackmd.io/@prysmaticlabs/finality ------------------------------------------------------------------------------------------------------------------------- +--- # Other L2 Chain Concepts @@ -676,7 +602,7 @@ blocks older than two L1 epochs (64 L1 [time slots][time-slot]). When a contract submits a [deposit][deposits] from L1 to L2, its address (as returned by `ORIGIN` and `CALLER`) will be aliased with a modified representation of the address of a contract. -- cf. [Deposit Specification](deposits.md#address-aliasing) +- cf. [Deposit Specification](./protocol/deposits.md#address-aliasing) ## Rollup Node @@ -685,7 +611,7 @@ aliased with a modified representation of the address of a contract. The rollup node is responsible for [deriving the L2 chain][derivation] from the L1 chain (L1 [blocks][block] and their associated [receipts][receipt]). -The rollup node can run either in *validator* or *sequencer* mode. +The rollup node can run either in _validator_ or _sequencer_ mode. In sequencer mode, the rollup node receives L2 transactions from users, which it uses to create L2 blocks. These are then submitted to a [data availability provider][avail-provider] via [batch submission][batch-submission]. The L2 chain @@ -695,7 +621,7 @@ In validator mode, the rollup node performs derivation as indicated above, but i chain by getting blocks directly from the sequencer, in which case derivation serves to validate the sequencer's behaviour. -A rollup node running in validator mode is sometimes called *a replica*. +A rollup node running in validator mode is sometimes called _a replica_. > **TODO** expand this to include output root submission @@ -718,7 +644,7 @@ from the L1 chain (L1 [blocks][block] and their associated [receipts][receipt]). A [predeployed contract][predeploy] on L2 that can be used to retrieve the L1 block attributes of L1 blocks with a given block number or a given block hash. -cf. [L1 Attributes Predeployed Contract Specification](deposits.md#l1-attributes-predeployed-contract) +cf. [L1 Attributes Predeployed Contract Specification](./protocol/deposits.md#l1-attributes-predeployed-contract) ## L2 Output Root @@ -726,7 +652,7 @@ cf. [L1 Attributes Predeployed Contract Specification](deposits.md#l1-attributes A 32 byte value which serves as a commitment to the current state of the L2 chain. -cf. [Proposing L2 output commitments](proposals.md#l2-output-root-proposals-specification) +cf. [Proposing L2 output commitments](./protocol/proposals.md#l2-output-root-proposals-specification) ## L2 Output Oracle Contract @@ -751,10 +677,10 @@ proof][fault-proof]. [fault-proof]: glossary.md#fault-proof -An on-chain *interactive* proof, performed by [validators][validator], that demonstrates that a [sequencer] provided +An on-chain _interactive_ proof, performed by [validators][validator], that demonstrates that a [sequencer] provided erroneous [output roots][l2-output]. -cf. [Fault Proofs](fault-proof.md) +cf. [Fault Proofs](./experimental/fault-proof/index.md) ## Time Slot @@ -787,7 +713,7 @@ the [sequencer][sequencer]. These unsafe blocks will later need to be confirmed by the L1 chain (via [unsafe block consolidation][consolidation]). ------------------------------------------------------------------------------------------------------------------------- +--- # Execution Engine Concepts @@ -808,13 +734,18 @@ using transactions [derived from L1 blocks][derivation]. In these specifications, "execution engine" always refer to the L2 execution engine, unless otherwise specified. -- cf. [Execution Engine Specification](exec-engine.md) +- cf. [Execution Engine Specification][exec-engine] -[derivation-spec]: derivation.md -[rollup-node-spec]: rollup-node.md + +[deposits-spec]: ./protocol/deposits.md +[system-config]: ./protocol/system_config.md +[exec-engine]: ./protocol/exec-engine.md +[derivation-spec]: ./protocol/derivation.md +[rollup-node-spec]: ./protocol/rollup-node.md + [mpt-details]: https://github.com/norswap/nanoeth/blob/d4c0c89cc774d4225d16970aa44c74114c1cfa63/src/com/norswap/nanoeth/trees/patricia/README.md [trie]: https://en.wikipedia.org/wiki/Trie [bloom filter]: https://en.wikipedia.org/wiki/Bloom_filter diff --git a/specs/introduction.md b/specs/introduction.md index 530fdfc6f..4909c17ba 100644 --- a/specs/introduction.md +++ b/specs/introduction.md @@ -1,25 +1,8 @@ # Introduction - - **Table of Contents** -- [Foundations](#foundations) - - [What is Ethereum scalability?](#what-is-ethereum-scalability) - - [What is an Optimistic Rollup?](#what-is-an-optimistic-rollup) - - [What is EVM Equivalence?](#what-is-evm-equivalence) - - [🎢 All together now 🎢](#-all-together-now-) -- [Protocol Guarantees](#protocol-guarantees) -- [Network Participants](#network-participants) - - [Users](#users) - - [Sequencers](#sequencers) - - [Verifiers](#verifiers) -- [Key Interaction Diagrams](#key-interaction-diagrams) - - [Depositing and Sending Transactions](#depositing-and-sending-transactions) - - [Withdrawing](#withdrawing) -- [Next Steps](#next-steps) - - + Optimism is an _EVM equivalent_, _optimistic rollup_ protocol designed to _scale Ethereum_ while remaining maximally compatible with existing Ethereum infrastructure. This document provides an overview of the protocol to provide context @@ -59,17 +42,21 @@ anywhere. In order to scale Ethereum without sacrificing security, we must preserve 3 critical properties of Ethereum layer 1: liveness, availability, and validity. -1. **Liveness** - Anyone must be able to extend the rollup chain by sending transactions at any time. - - There are two ways transactions can be sent to the rollup chain: 1) via the sequencer, and 2) directly on layer 1. -The sequencer provides low latency & low cost transactions, while sending transactions directly to layer 1 provides -censorship resistance. -1. **Availability** - Anyone must be able to download the rollup chain. - - All information required to derive the chain is embedded into layer 1 blocks. That way as long as the layer 1 -chain is available, so is the rollup. -1. **Validity** - All transactions must be correctly executed and all withdrawals correctly processed. - - The rollup state and withdrawals are managed on an L1 contract called the `L2OutputOracle`. This oracle is -guaranteed to _only_ finalize correct (ie. valid) rollup block hashes given a **single honest verifier** assumption. If -there is ever an invalid block hash asserted on layer 1, an honest verifier will prove it is invalid and win a bond. +1. **Liveness** + - Anyone must be able to extend the rollup chain by sending transactions at any time. + - There are two ways transactions can be sent to the rollup chain: 1) via the sequencer, and 2) directly on layer 1. + The sequencer provides low latency & low cost transactions, while sending transactions directly to layer 1 provides + censorship resistance. +1. **Availability** + - Anyone must be able to download the rollup chain. + - All information required to derive the chain is embedded into layer 1 blocks. That way as long as the layer 1 + chain is available, so is the rollup. +1. **Validity** + - All transactions must be correctly executed and all withdrawals correctly processed. + - The rollup state and withdrawals are managed on an L1 contract called the `L2OutputOracle`. This oracle is + guaranteed to _only_ finalize correct (ie. valid) rollup block hashes given a **single honest verifier** + assumption. If there is ever an invalid block hash asserted on layer 1, an honest verifier will prove it is + invalid and win a bond. **Footnote**: There are two main ways to enforce validity of a rollup: fault proofs (optimistic rollup) and validity proofs (zkRollup). For the purposes of this spec we only focus on fault proofs but it is worth noting that validity @@ -79,7 +66,7 @@ proofs can also be plugged in once they have been made feasible. There are three actors in Optimism: users, sequencers, and verifiers. -![Network Overview](assets/network-participants-overview.svg) +![Network Overview](./static/assets/network-participants-overview.svg) ### Users @@ -103,9 +90,9 @@ The sequencer: 2. Observes on-chain transactions (primarily, deposit events coming from L1) 3. Consolidates both kinds of transactions into L2 blocks with a specific ordering. 4. Propagates consolidated L2 blocks to L1, by submitting two things as calldata to L1: - - The pending off-chain transactions accepted in step 1. - - Sufficient information about the ordering of the on-chain transactions to successfully reconstruct the blocks -from step 3., purely by watching L1. + - The pending off-chain transactions accepted in step 1. + - Sufficient information about the ordering of the on-chain transactions to successfully reconstruct the blocks + from step 3., purely by watching L1. The sequencer also provides access to block data as early as step 3., so that users may access real-time state in advance of L1 confirmation if they so choose. @@ -131,28 +118,29 @@ Users will often begin their L2 journey by depositing ETH from L1. Once they have ETH to pay fees, they'll start sending transactions on L2. The following diagram demonstrates this interaction and all key Optimism components which are or should be utilized: -![Diagram of Depositing and Sending Transactions](assets/sequencer-handling-deposits-and-transactions.svg) +![Diagram of Depositing and Sending Transactions](./static/assets/sequencer-handling-deposits-and-transactions.svg) Links to components mentioned in this diagram: -- [Rollup Node](rollup-node.md) -- [Execution Engine](exec-engine.md) - -- [L2 Output Oracle](proposals.md#l2-output-oracle-smart-contract) -- [L2 Output Submitter](proposals.md#proposing-l2-output-commitments) - + +- [Rollup Node](./protocol/rollup-node.md) +- [Execution Engine](./protocol/exec-engine.md) +- [L2 Output Oracle](./protocol/proposals.md#l2-output-oracle-smart-contract) +- [L2 Output Submitter](./protocol/proposals.md#proposing-l2-output-commitments) + + ### Withdrawing Just as important as depositing, it is critical that users can withdraw from the rollup. Withdrawals are initiated by normal transactions on L2, but then completed using a transaction on L1 after the dispute period has elapsed. -![Diagram of Withdrawing](assets/user-withdrawing-to-l1.svg) +![Diagram of Withdrawing](./static/assets/user-withdrawing-to-l1.svg) Links to components mentioned in this diagram: -- [L2 Output Oracle](proposals.md#l2-output-oracle-smart-contract) +- [L2 Output Oracle](./protocol/proposals.md#l2-output-oracle-smart-contract) ## Next Steps diff --git a/specs/meta/README.md b/specs/meta/index.md similarity index 75% rename from specs/meta/README.md rename to specs/meta/index.md index 5039d5a6c..fcfbdd3dc 100644 --- a/specs/meta/README.md +++ b/specs/meta/index.md @@ -1,8 +1,7 @@ - # Meta Processes This directory describes processes that we use to lint/test the specification. - [Linting](linting.md): how to lint source files. - [Markdown Style Guide](markdown-style.md): how to format and structure Markdown files. -- [Devnet introduction](devnet.md): how to run a devnet. +- [Versioning](versioning.md) diff --git a/specs/meta/linting.md b/specs/meta/linting.md index c5301da79..642c1aac4 100644 --- a/specs/meta/linting.md +++ b/specs/meta/linting.md @@ -1,13 +1,8 @@ # Linting - - **Table of Contents** -- [Markdown](#markdown) -- [Go](#go) - - + ## Markdown @@ -16,18 +11,18 @@ See - [markdownlint rule reference](https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md) - [example .markdownlint.json file](https://github.com/DavidAnson/markdownlint/blob/main/schema/.markdownlint.jsonc) -Justification for linting rules in [.markdownlint.json](/.markdownlint.json): +Justification for linting rules in +[.markdownlint.json](https://github.com/ethereum-optimism/specs/blob/main/.markdownlint.json): -- *line_length* (`!strict && stern`): don't trip up on url lines -- *no-blanks-blockquote*: enable multiple consecutive blockquotes separated by white lines -- *single-title*: enable reusing `

` for content -- *no-emphasis-as-heading*: enable emphasized paragraphs +- _line_length_ (`!strict && stern`): don't trip up on url lines +- _no-blanks-blockquote_: enable multiple consecutive blockquotes separated by white lines +- _single-title_: enable reusing `

` for content +- _no-emphasis-as-heading_: enable emphasized paragraphs ```shell pnpm i # Install dependencies pnpm lint:specs:check # Run linter pnpm lint:specs:fix # Fix lint issues -pnpm lint:specs:toc # Update TOC docs # Check links docker run --init -it -v `pwd`:/input lycheeverse/lychee --verbose --no-progress --exclude-loopback --exclude twitter.com --exclude-mail /input/README.md "/input/specs/**/*.md" @@ -43,11 +38,7 @@ You can install cargo (the Rust package manager) via [rustup]. [lychee-ci]: https://github.com/lycheeverse/lychee-action/blob/f76b8412c668f78311212d16d33c4784a7d8762c/Dockerfile [rustup]: https://www.rust-lang.org/tools/install -To update the TOC, we run [doctoc], installed through the dev-dependencies in `package.json`. - -[doctoc]: https://github.com/thlorenz/doctoc - -## Go +# Go See @@ -57,8 +48,8 @@ See Justification for linting rules: -- *asciicheck*: no symbol names with invisible unicode and such -- *goimports*: group local and external import +- _asciicheck_: no symbol names with invisible unicode and such +- _goimports_: group local and external import ```shell # Install linter globally (should not affect go.mod) diff --git a/specs/meta/markdown-style.md b/specs/meta/markdown-style.md index 81ee837c4..c47fcaf49 100644 --- a/specs/meta/markdown-style.md +++ b/specs/meta/markdown-style.md @@ -1,15 +1,8 @@ # Markdown Style Guide - - **Table of Contents** -- [Linting](#linting) -- [Links](#links) - - [Glossary](#glossary) -- [Internal (In-File) Links](#internal-in-file-links) - - + ## Linting diff --git a/specs/meta/versioning.md b/specs/meta/versioning.md index 381a3a5a3..44344bbf3 100644 --- a/specs/meta/versioning.md +++ b/specs/meta/versioning.md @@ -1,14 +1,8 @@ # Versioning - - **Table of Contents** -- [Go modules](#go-modules) - - [versioning process](#versioning-process) -- [Typescript](#typescript) - - + ## Go modules diff --git a/specs/batcher.md b/specs/protocol/batcher.md similarity index 98% rename from specs/batcher.md rename to specs/protocol/batcher.md index 91e42404c..475561c51 100644 --- a/specs/batcher.md +++ b/specs/protocol/batcher.md @@ -1,4 +1,3 @@ - # Batch Submitter The batch submitter, also referred to as the batcher, is the entity submitting the L2 sequencer data to L1, diff --git a/specs/bridges.md b/specs/protocol/bridges.md similarity index 89% rename from specs/bridges.md rename to specs/protocol/bridges.md index 3c87747b2..e55ded2bd 100644 --- a/specs/bridges.md +++ b/specs/protocol/bridges.md @@ -1,13 +1,8 @@ # Standard Bridges - - **Table of Contents** -- [Token Depositing](#token-depositing) -- [Upgradability](#upgradability) - - + The standard bridges are responsible for allowing cross domain ETH and ERC20 token transfers. They are built on top of the cross domain diff --git a/specs/deposits.md b/specs/protocol/deposits.md similarity index 86% rename from specs/deposits.md rename to specs/protocol/deposits.md index a354a6c36..9044f7a89 100644 --- a/specs/deposits.md +++ b/specs/protocol/deposits.md @@ -1,49 +1,27 @@ # Deposits -[g-transaction-type]: glossary.md#transaction-type -[g-derivation]: glossary.md#L2-chain-derivation -[g-deposited]: glossary.md#deposited -[g-deposits]: glossary.md#deposits -[g-l1-attr-deposit]: glossary.md#l1-attributes-deposited-transaction -[g-user-deposited]: glossary.md#user-deposited-transaction -[g-eoa]: glossary.md#eoa -[g-exec-engine]: glossary.md#execution-engine + +[g-transaction-type]: ../glossary.md#transaction-type +[g-derivation]: ../glossary.md#L2-chain-derivation +[g-deposited]: ../glossary.md#deposited +[g-deposits]: ../glossary.md#deposits +[g-l1-attr-deposit]: ../glossary.md#l1-attributes-deposited-transaction +[g-user-deposited]: ../glossary.md#user-deposited-transaction +[g-eoa]: ../glossary.md#eoa +[g-exec-engine]: ../glossary.md#execution-engine [Deposited transactions][g-deposited], also known as [deposits][g-deposits] are transactions which are initiated on L1, and executed on L2. This document outlines a new [transaction type][g-transaction-type] for deposits. It also describes how deposits are initiated on L1, along with the authorization and validation conditions on L2. -**Vocabulary note**: *deposited transaction* refers specifically to an L2 transaction, while -*deposit* can refer to the transaction at various stages (for instance when it is deposited on L1). +**Vocabulary note**: _deposited transaction_ refers specifically to an L2 transaction, while +_deposit_ can refer to the transaction at various stages (for instance when it is deposited on L1). - - **Table of Contents** -- [The Deposited Transaction Type](#the-deposited-transaction-type) - - [Source hash computation](#source-hash-computation) - - [Kinds of Deposited Transactions](#kinds-of-deposited-transactions) - - [Validation and Authorization of Deposited Transactions](#validation-and-authorization-of-deposited-transactions) - - [Execution](#execution) - - [Nonce Handling](#nonce-handling) -- [Deposit Receipt](#deposit-receipt) -- [L1 Attributes Deposited Transaction](#l1-attributes-deposited-transaction) - - [L1 Attributes Deposited Transaction Calldata](#l1-attributes-deposited-transaction-calldata) - - [L1 Attributes - Bedrock, Canyon, Delta](#l1-attributes---bedrock-canyon-delta) - - [L1 Attributes - Ecotone](#l1-attributes---ecotone) -- [Special Accounts on L2](#special-accounts-on-l2) - - [L1 Attributes Depositor Account](#l1-attributes-depositor-account) - - [L1 Attributes Predeployed Contract](#l1-attributes-predeployed-contract) - - [L1 Attributes Predeployed Contract: Reference Implementation](#l1-attributes-predeployed-contract-reference-implementation) - - [Ecotone L1Block upgrade](#ecotone-l1block-upgrade) -- [User-Deposited Transactions](#user-deposited-transactions) - - [Deposit Contract](#deposit-contract) - - [Address Aliasing](#address-aliasing) - - [Deposit Contract Implementation: Optimism Portal](#deposit-contract-implementation-optimism-portal) - - + ## The Deposited Transaction Type @@ -86,7 +64,7 @@ In contrast to [EIP-155] transactions, this transaction type: - Includes new `sourceHash`, `from`, `mint`, and `isSystemTx` attributes. API responses contain these as additional fields. -[EIP-155]:https://eips.ethereum.org/EIPS/eip-155 +[EIP-155]: https://eips.ethereum.org/EIPS/eip-155 We select `0x7E` because transaction type identifiers are currently allowed to go up to `0x7F`. Picking a high identifier minimizes the risk that the identifier will be used be claimed by another @@ -183,7 +161,7 @@ Any non-EVM state-transition error emitted by the EVM execution is processed in Finally, after the above processing, the execution post-processing runs the same: i.e. the gas pool and receipt are processed identical to a regular transaction. Starting with the Regolith upgrade however, the receipt of deposit transactions is extended with an additional -`depositNonce` value, storing the `nonce` value of the `from` sender as registered *before* the EVM processing. +`depositNonce` value, storing the `nonce` value of the `from` sender as registered _before_ the EVM processing. Note that the gas used as stated by the execution output is subtracted from the gas pool, but this execution output value has special edge cases before the Regolith upgrade. @@ -243,7 +221,7 @@ attributes predeployed contract][predeploy]. This transaction MUST have the following values: 1. `from` is `0xdeaddeaddeaddeaddeaddeaddeaddeaddead0001` (the address of the -[L1 Attributes depositor account][depositor-account]) + [L1 Attributes depositor account][depositor-account]) 2. `to` is `0x4200000000000000000000000000000000000015` (the address of the [L1 attributes predeployed contract][predeploy]). 3. `mint` is `0` @@ -251,7 +229,7 @@ This transaction MUST have the following values: 5. `gasLimit` is set to 150,000,000 prior to the Regolith upgrade, and 1,000,000 after. 6. `isSystemTx` is set to `true` prior to the Regolith upgrade, and `false` after. 7. `data` is an encoded call to the [L1 attributes predeployed contract][predeploy] that -depends on the upgrades that are active (see below). + depends on the upgrades that are active (see below). This system-initiated transaction for L1 attributes is not charged any ETH for its allocated `gasLimit`, as it is considered part of state-transition processing. @@ -262,7 +240,7 @@ This system-initiated transaction for L1 attributes is not charged any ETH for i The `data` field of the L1 attributes deposited transaction is an [ABI][ABI] encoded call to the `setL1BlockValues()` function with correct values associated with the corresponding L1 block -(cf. [reference implementation][l1-attr-ref-implem]). +(cf. [reference implementation][l1-attr-ref-implem]). #### L1 Attributes - Ecotone @@ -279,18 +257,18 @@ The overall calldata layout is as follows: [ecotone-upgrade-txs]: derivation.md#network-upgrade-automation-transactions -| Input arg | Type | Calldata bytes | Segment | -| ----------------- | ----------- | -------------- | --------| -| {0x440a5e20} | | 0-3 | n/a | -| baseFeeScalar | uint32 | 4-7 | 1 | -| blobBaseFeeScalar | uint32 | 8-11 | | -| sequenceNumber | uint64 | 12-19 | | -| l1BlockTimestamp | uint64 | 20-27 | | -| l1BlockNumber | uint64 | 28-35 | | -| basefee | uint256 | 36-67 | 2 | -| blobBaseFee | uint256 | 68-99 | 3 | -| l1BlockHash | bytes32 | 100-131 | 4 | -| batcherHash | bytes32 | 132-163 | 5 | +| Input arg | Type | Calldata bytes | Segment | +| ----------------- | ------- | -------------- | ------- | +| {0x440a5e20} | | 0-3 | n/a | +| baseFeeScalar | uint32 | 4-7 | 1 | +| blobBaseFeeScalar | uint32 | 8-11 | | +| sequenceNumber | uint64 | 12-19 | | +| l1BlockTimestamp | uint64 | 20-27 | | +| l1BlockNumber | uint64 | 28-35 | | +| basefee | uint256 | 36-67 | 2 | +| blobBaseFee | uint256 | 68-99 | 3 | +| l1BlockHash | bytes32 | 100-131 | 4 | +| batcherHash | bytes32 | 132-163 | 5 | Total calldata length MUST be exactly 164 bytes, implying the sixth and final segment is only partially filled. This helps to slow database growth as every L2 block includes a L1 Attributes @@ -412,7 +390,7 @@ transaction are determined by the corresponding `TransactionDeposited` event emi 1. `from` is unchanged from the emitted value (though it may have been transformed to an alias in `OptimismPortal`, the deposit feed contract). 2. `to` is any 20-byte address (including the zero address) - - In case of a contract creation (cf. `isCreation`), this address is set to `null`. + - In case of a contract creation (cf. `isCreation`), this address is set to `null`. 3. `mint` is set to the emitted value. 4. `value` is set to the emitted value. 5. `gaslimit` is unchanged from the emitted value. It must be at least 21000. @@ -420,7 +398,7 @@ transaction are determined by the corresponding `TransactionDeposited` event emi 7. `data` is unchanged from the emitted value. Depending on the value of `isCreation` it is handled as either calldata or contract initialization code. 8. `isSystemTx` is set by the rollup node for certain transactions that have unmetered execution. - It is `false` for user deposited transactions + It is `false` for user deposited transactions ### Deposit Contract diff --git a/specs/derivation.md b/specs/protocol/derivation.md similarity index 89% rename from specs/derivation.md rename to specs/protocol/derivation.md index b0bf514df..c446ecf54 100644 --- a/specs/derivation.md +++ b/specs/protocol/derivation.md @@ -1,106 +1,57 @@ # L2 Chain Derivation Specification -[g-derivation]: glossary.md#L2-chain-derivation -[g-payload-attr]: glossary.md#payload-attributes -[g-block]: glossary.md#block -[g-exec-engine]: glossary.md#execution-engine -[g-reorg]: glossary.md#chain-re-organization -[g-receipts]: glossary.md#receipt -[g-inception]: glossary.md#L2-chain-inception -[g-deposit-contract]: glossary.md#deposit-contract -[g-deposited]: glossary.md#deposited-transaction -[g-l1-attr-deposit]: glossary.md#l1-attributes-deposited-transaction -[g-l1-origin]: glossary.md#l1-origin -[g-user-deposited]: glossary.md#user-deposited-transaction -[g-deposits]: glossary.md#deposits -[g-deposit-contract]: glossary.md#deposit-contract -[g-l1-attr-predeploy]: glossary.md#l1-attributes-predeployed-contract -[g-depositing-call]: glossary.md#depositing-call -[g-depositing-transaction]: glossary.md#depositing-transaction -[g-sequencing]: glossary.md#sequencing -[g-sequencer]: glossary.md#sequencer -[g-sequencing-epoch]: glossary.md#sequencing-epoch -[g-sequencing-window]: glossary.md#sequencing-window -[g-sequencer-batch]: glossary.md#sequencer-batch -[g-l2-genesis]: glossary.md#l2-genesis-block -[g-l2-chain-inception]: glossary.md#L2-chain-inception -[g-l2-genesis-block]: glossary.md#l2-genesis-block -[g-batcher-transaction]: glossary.md#batcher-transaction -[g-avail-provider]: glossary.md#data-availability-provider -[g-batcher]: glossary.md#batcher -[g-l2-output]: glossary.md#l2-output-root -[g-fault-proof]: glossary.md#fault-proof -[g-channel]: glossary.md#channel -[g-channel-frame]: glossary.md#channel-frame -[g-rollup-node]: glossary.md#rollup-node -[g-channel-timeout]: glossary.md#channel-timeout -[g-block-time]: glossary.md#block-time -[g-time-slot]: glossary.md#time-slot -[g-consolidation]: glossary.md#unsafe-block-consolidation -[g-safe-l2-head]: glossary.md#safe-l2-head -[g-safe-l2-block]: glossary.md#safe-l2-block -[g-unsafe-l2-head]: glossary.md#unsafe-l2-head -[g-unsafe-l2-block]: glossary.md#unsafe-l2-block -[g-unsafe-sync]: glossary.md#unsafe-sync -[g-l1-origin]: glossary.md#l1-origin -[g-deposit-tx-type]: glossary.md#deposited-transaction-type -[g-finalized-l2-head]: glossary.md#finalized-l2-head -[g-system-config]: glossary.md#system-configuration - - - + +[g-derivation]: ../glossary.md#L2-chain-derivation +[g-payload-attr]: ../glossary.md#payload-attributes +[g-block]: ../glossary.md#block +[g-exec-engine]: ../glossary.md#execution-engine +[g-reorg]: ../glossary.md#chain-re-organization +[g-receipts]: ../glossary.md#receipt +[g-inception]: ../glossary.md#L2-chain-inception +[g-deposit-contract]: ../glossary.md#deposit-contract +[g-deposited]: ../glossary.md#deposited-transaction +[g-l1-attr-deposit]: ../glossary.md#l1-attributes-deposited-transaction +[g-l1-origin]: ../glossary.md#l1-origin +[g-user-deposited]: ../glossary.md#user-deposited-transaction +[g-deposits]: ../glossary.md#deposits +[g-deposit-contract]: ../glossary.md#deposit-contract +[g-l1-attr-predeploy]: ../glossary.md#l1-attributes-predeployed-contract +[g-depositing-call]: ../glossary.md#depositing-call +[g-depositing-transaction]: ../glossary.md#depositing-transaction +[g-sequencing]: ../glossary.md#sequencing +[g-sequencer]: ../glossary.md#sequencer +[g-sequencing-epoch]: ../glossary.md#sequencing-epoch +[g-sequencing-window]: ../glossary.md#sequencing-window +[g-sequencer-batch]: ../glossary.md#sequencer-batch +[g-l2-genesis]: ../glossary.md#l2-genesis-block +[g-l2-chain-inception]: ../glossary.md#L2-chain-inception +[g-l2-genesis-block]: ../glossary.md#l2-genesis-block +[g-batcher-transaction]: ../glossary.md#batcher-transaction +[g-avail-provider]: ../glossary.md#data-availability-provider +[g-batcher]: ../glossary.md#batcher +[g-l2-output]: ../glossary.md#l2-output-root +[g-fault-proof]: ../glossary.md#fault-proof +[g-channel]: ../glossary.md#channel +[g-channel-frame]: ../glossary.md#channel-frame +[g-rollup-node]: ../glossary.md#rollup-node +[g-channel-timeout]: ../glossary.md#channel-timeout +[g-block-time]: ../glossary.md#block-time +[g-time-slot]: ../glossary.md#time-slot +[g-consolidation]: ../glossary.md#unsafe-block-consolidation +[g-safe-l2-head]: ../glossary.md#safe-l2-head +[g-safe-l2-block]: ../glossary.md#safe-l2-block +[g-unsafe-l2-head]: ../glossary.md#unsafe-l2-head +[g-unsafe-l2-block]: ../glossary.md#unsafe-l2-block +[g-unsafe-sync]: ../glossary.md#unsafe-sync +[g-l1-origin]: ../glossary.md#l1-origin +[g-deposit-tx-type]: ../glossary.md#deposited-transaction-type +[g-finalized-l2-head]: ../glossary.md#finalized-l2-head +[g-system-config]: ../glossary.md#system-configuration + **Table of Contents** -- [Overview](#overview) - - [Eager Block Derivation](#eager-block-derivation) -- [Batch Submission](#batch-submission) - - [Sequencing & Batch Submission Overview](#sequencing--batch-submission-overview) - - [Batch Submission Wire Format](#batch-submission-wire-format) - - [Batcher Transaction Format](#batcher-transaction-format) - - [Frame Format](#frame-format) - - [Channel Format](#channel-format) - - [Batch Format](#batch-format) -- [Architecture](#architecture) - - [L2 Chain Derivation Pipeline](#l2-chain-derivation-pipeline) - - [L1 Traversal](#l1-traversal) - - [L1 Retrieval](#l1-retrieval) - - [Ecotone: Blob Retrieval](#ecotone-blob-retrieval) - - [Blob Encoding](#blob-encoding) - - [Frame Queue](#frame-queue) - - [Channel Bank](#channel-bank) - - [Pruning](#pruning) - - [Timeouts](#timeouts) - - [Reading](#reading) - - [Loading frames](#loading-frames) - - [Channel Reader (Batch Decoding)](#channel-reader-batch-decoding) - - [Batch Queue](#batch-queue) - - [Payload Attributes Derivation](#payload-attributes-derivation) - - [Engine Queue](#engine-queue) - - [Engine API usage](#engine-api-usage) - - [Bedrock, Canyon, Delta: API Usage](#bedrock-canyon-delta-api-usage) - - [Ecotone: API Usage](#ecotone-api-usage) - - [Forkchoice synchronization](#forkchoice-synchronization) - - [L1-consolidation: payload attributes matching](#l1-consolidation-payload-attributes-matching) - - [L1-sync: payload attributes processing](#l1-sync-payload-attributes-processing) - - [Processing unsafe payload attributes](#processing-unsafe-payload-attributes) - - [Resetting the Pipeline](#resetting-the-pipeline) - - [Finding the sync starting point](#finding-the-sync-starting-point) - - [Resetting derivation stages](#resetting-derivation-stages) - - [About reorgs Post-Merge](#about-reorgs-post-merge) -- [Deriving Payload Attributes](#deriving-payload-attributes) - - [Deriving the Transaction List](#deriving-the-transaction-list) - - [Network upgrade automation transactions](#network-upgrade-automation-transactions) - - [Ecotone](#ecotone) - - [L1Block Deployment](#l1block-deployment) - - [GasPriceOracle Deployment](#gaspriceoracle-deployment) - - [L1Block Proxy Update](#l1block-proxy-update) - - [GasPriceOracle Proxy Update](#gaspriceoracle-proxy-update) - - [GasPriceOracle Enable Ecotone](#gaspriceoracle-enable-ecotone) - - [Beacon block roots contract deployment (EIP-4788)](#beacon-block-roots-contract-deployment-eip-4788) - - [Building Individual Payload Attributes](#building-individual-payload-attributes) - - + # Overview @@ -143,6 +94,7 @@ Each L2 `block` with origin `l1_origin` is subject to the following constraints denominated in seconds): - `block.timestamp = prev_l2_timestamp + l2_block_time` + - `prev_l2_timestamp` is the timestamp of the L2 block immediately preceding this one. If there is no preceding block, then this is the genesis block, and its timestamp is explicitly specified. @@ -161,7 +113,7 @@ chain inception. The second constraint ensures that an L2 block timestamp never precedes its L1 origin timestamp, and is never more than `max_sequencer_drift` ahead of it, except only in the unusual case where it might prohibit an L2 block from being produced every l2_block_time seconds. (Such cases might arise -for example under a proof-of-work L1 that sees a period of rapid L1 block production.) In either +for example under a proof-of-work L1 that sees a period of rapid L1 block production.) In either case, the sequencer enforces `len(batch.transactions) == 0` while `max_sequencer_drift` is exceeded. See [Batch Queue](#batch-queue) for more details. @@ -180,13 +132,13 @@ drifting further and further ahead. Deriving an L2 block requires that we have constructed its sequencer batch and derived all L2 blocks and state updates prior to it. This means we can typically derive the L2 blocks of an epoch -*eagerly* without waiting on the full sequencing window. The full sequencing window is required +_eagerly_ without waiting on the full sequencing window. The full sequencing window is required before derivation only in the very worst case where some portion of the sequencer batch for the first block of the epoch appears in the very last L1 block of the window. Note that this only -applies to *block* derivation. Sequencer batches can still be derived and tentatively queued +applies to _block_ derivation. Sequencer batches can still be derived and tentatively queued without deriving blocks from them. ------------------------------------------------------------------------------------------------------------------------- +--- # Batch Submission @@ -254,7 +206,7 @@ data-availability layer may support. All of this is illustrated in the following diagram. Explanations below. -![batch derivation chain diagram](assets/batch-deriv-chain.svg) +![batch derivation chain diagram](../static/assets/batch-deriv-chain.svg) The first line represents L1 blocks with their numbers. The boxes under the L1 blocks represent [batcher transactions][g-batcher-transaction] included within the block. The squiggles under the L1 blocks represent @@ -316,7 +268,7 @@ interacting with the [execution-engine API][exec-engine]. Batcher transactions are encoded as `version_byte ++ rollup_payload` (where `++` denotes concatenation). | `version_byte` | `rollup_payload` | -|----------------|------------------------------------------------| +| -------------- | ---------------------------------------------- | | 0 | `frame ...` (one or more frames, concatenated) | Unknown versions make the batcher transaction invalid (it must be ignored by the rollup node). @@ -353,7 +305,7 @@ to simplify packing of frames with varying content length. where: - `channel_id` is an opaque identifier for the channel. It should not be reused and is suggested to be random; however, -outside of timeout rules, it is not checked for validity + outside of timeout rules, it is not checked for validity - `frame_number` identifies the index of the frame within the channel - `frame_data_length` is the length of `frame_data` in bytes. It is capped to 1,000,000 bytes. - `frame_data` is a sequence of bytes belonging to the channel, logically after the bytes from the previous frames @@ -404,7 +356,7 @@ Recall that a batch contains a list of transactions to be included in a specific A batch is encoded as `batch_version ++ content`, where `content` depends on the `batch_version`: | `batch_version` | `content` | -|-----------------|------------------------------------------------------------------------------------| +| --------------- | ---------------------------------------------------------------------------------- | | 0 | `rlp_encode([parent_hash, epoch_number, epoch_hash, timestamp, transaction_list])` | where: @@ -426,7 +378,7 @@ Unknown versions make the batch invalid (it must be ignored by the rollup node), The `epoch_number` and the `timestamp` must also respect the constraints listed in the [Batch Queue][batch-queue] section, otherwise the batch is considered invalid and will be ignored. ------------------------------------------------------------------------------------------------------------------------- +--- # Architecture @@ -457,7 +409,7 @@ Our architecture decomposes the derivation process into a pipeline made up of th The data flows from the start (outer) of the pipeline towards the end (inner). From the innermost stage the data is pulled from the outermost stage. -However, data is *processed* in reverse order. Meaning that if there is any data to be processed in the last stage, it +However, data is _processed_ in reverse order. Meaning that if there is any data to be processed in the last stage, it will be processed first. Processing proceeds in "steps" that can be taken at each stage. We try to take as many steps as possible in the last (most inner) stage before taking any steps in its outer stage, etc. @@ -474,7 +426,7 @@ Let's briefly describe each stage of the pipeline. ### L1 Traversal -In the *L1 Traversal* stage, we simply read the header of the next L1 block. In normal operations, these will be new +In the _L1 Traversal_ stage, we simply read the header of the next L1 block. In normal operations, these will be new L1 blocks as they get created, though we can also read old blocks while syncing, or in case of an L1 [re-org][g-reorg]. Upon traversal of the L1 block, the [system configuration][g-system-config] copy used by the L1 retrieval stage is @@ -482,7 +434,7 @@ updated, such that the batch-sender authentication is always accurate to the exa ### L1 Retrieval -In the *L1 Retrieval* stage, we read the block we get from the outer stage (L1 traversal), and +In the _L1 Retrieval_ stage, we read the block we get from the outer stage (L1 traversal), and extract data from its [batcher transactions][g-batcher-transaction]. A batcher transaction is one with the following properties: @@ -506,9 +458,9 @@ treat transactions of transaction-type == `0x03` (`BLOB_TX_TYPE`) differently. I transaction is a blob transaction, then its calldata MUST be ignored should it be present. Instead: - For each blob hash in `blob_versioned_hashes`, retrieve the blob that matches it. A blob may be - retrieved from any of a number different sources. Retrieval from a local beacon-node, through - the `/eth/v1/beacon/blob_sidecars/` endpoint, with `indices` filter to skip unrelated blobs, is - recommended. For each retrieved blob: + retrieved from any of a number different sources. Retrieval from a local beacon-node, through + the `/eth/v1/beacon/blob_sidecars/` endpoint, with `indices` filter to skip unrelated blobs, is + recommended. For each retrieved blob: - The blob SHOULD (MUST, if the source is untrusted) be cryptographically verified against its versioned hash. - If the blob has a [valid encoding](#blob-encoding), decode it into its continuous byte-string @@ -598,7 +550,7 @@ See [Batcher transaction format](#batcher-transaction-format) and [Frame format] ### Channel Bank -The *Channel Bank* stage is responsible for managing buffering from the channel bank that was written to by the L1 +The _Channel Bank_ stage is responsible for managing buffering from the channel bank that was written to by the L1 retrieval stage. A step in the channel bank stage tries to read data from channels that are "ready". Channels are currently fully buffered until read or dropped, @@ -606,7 +558,7 @@ streaming channels may be supported in a future version of the ChannelBank. To bound resource usage, the Channel Bank prunes based on channel size, and times out old channels. -Channels are recorded in FIFO order in a structure called the *channel queue*. A channel is added to the channel +Channels are recorded in FIFO order in a structure called the _channel queue_. A channel is added to the channel queue the first time a frame belonging to the channel is seen. #### Pruning @@ -658,7 +610,7 @@ Frame insertion conditions: - New frames matching timed-out channels that have not yet been pruned from the channel-bank are dropped. - Duplicate frames (by frame number) for frames that have not been pruned from the channel-bank are dropped. - Duplicate closes (new frame `is_last == 1`, but the channel has already seen a closing frame and has not yet been - pruned from the channel-bank) are dropped. + pruned from the channel-bank) are dropped. If a frame is closing (`is_last == 1`) any existing higher-numbered frames are removed from the channel. @@ -676,7 +628,7 @@ See [Batch Format][batch-format] for decompression and decoding specification. [batch-queue]: #batch-queue -During the *Batch Buffering* stage, we reorder batches by their timestamps. If batches are missing for some [time +During the _Batch Buffering_ stage, we reorder batches by their timestamps. If batches are missing for some [time slots][g-time-slot] and a valid batch with a higher timestamp exists, this stage also generates empty batches to fill the gaps. @@ -705,8 +657,8 @@ Definitions: - `batch` as defined in the [Batch format section][batch-format]. - `epoch = safe_l2_head.l1_origin` a [L1 origin][g-l1-origin] coupled to the batch, with properties: `number` (L1 block number), `hash` (L1 block hash), and `timestamp` (L1 block timestamp). -- `inclusion_block_number` is the L1 block number when `batch` was first *fully* derived, - i.e. decoded and output by the previous stage. +- `inclusion_block_number` is the L1 block number when `batch` was first _fully_ derived, + i.e. decoded and output by the previous stage. - `next_timestamp = safe_l2_head.timestamp + block_time` is the expected L2 timestamp the next batch should have, see [block time information][g-block-time]. - `next_epoch` may not be known yet, but would be the L1 block after `epoch` if available. @@ -758,7 +710,7 @@ then an empty batch can be derived with the following properties: - `epoch_num = epoch.number` - `epoch_hash = epoch.hash` - If the batch is the first batch of the epoch, that epoch is used instead of advancing the epoch to ensure that -there is at least one L2 block per epoch. + there is at least one L2 block per epoch. - `epoch_num = epoch.number` - `epoch_hash = epoch.hash` - Otherwise, @@ -767,7 +719,7 @@ there is at least one L2 block per epoch. ### Payload Attributes Derivation -In the *Payload Attributes Derivation* stage, we convert the batches we get from the previous stage into instances of +In the _Payload Attributes Derivation_ stage, we convert the batches we get from the previous stage into instances of the [`PayloadAttributes`][g-payload-attr] structure. Such a structure encodes the transactions that need to figure into a block, as well as other block inputs (timestamp, fee recipient, etc). Payload attributes derivation is detailed in the section [Deriving Payload Attributes section][deriving-payload-attr] below. @@ -777,7 +729,7 @@ The system configuration is updated with L1 log events whenever the L1 epoch ref ### Engine Queue -In the *Engine Queue* stage, the previously derived `PayloadAttributes` structures are buffered and sent to the +In the _Engine Queue_ stage, the previously derived `PayloadAttributes` structures are buffered and sent to the [execution engine][g-exec-engine] to be executed and converted into a proper L2 block. The stage maintains references to three L2 blocks: @@ -915,13 +867,13 @@ Engine][exec-engine-comm] section. The payload attributes are then processed with a sequence of: - [Engine: Fork choice updated](#engine-api-usage) with current forkchoice state of the stage, and the attributes to -start block building. + start block building. - Non-deterministic sources, like the tx-pool, must be disabled to reconstruct the expected block. - [Engine: Get Payload](#engine-api-usage) to retrieve the payload, by the payload-ID in the result of the previous -step. + step. - [Engine: New Payload](#engine-api-usage) to import the new payload into the execution engine. - [Engine: Fork Choice Updated](#engine-api-usage) to make the new payload canonical, - now with a change of both `safe` and `unsafe` fields to refer to the payload, and no payload attributes. + now with a change of both `safe` and `unsafe` fields to refer to the payload, and no payload attributes. Engine API Error handling: @@ -1050,7 +1002,7 @@ without dispute (fault proof challenge window), a name-collision with the proof- [merge]: https://ethereum.org/en/upgrades/merge/ [l1-finality]: https://ethereum.org/en/developers/docs/consensus-mechanisms/pos/#finality ------------------------------------------------------------------------------------------------------------------------- +--- # Deriving Payload Attributes @@ -1074,17 +1026,17 @@ for the target L2 block number. [Remember][batch-format] that the batch includes epoch][g-sequencing-epoch] number, an L2 timestamp, and a transaction list. This block is part of a [sequencing epoch][g-sequencing-epoch], -whose number matches that of an L1 block (its *[L1 origin][g-l1-origin]*). +whose number matches that of an L1 block (its _[L1 origin][g-l1-origin]_). This L1 block is used to derive L1 attributes and (for the first L2 block in the epoch) user deposits. Therefore, a [`PayloadAttributesV2`][expanded-payload] object must include the following transactions: - one or more [deposited transactions][g-deposited], of two kinds: - - a single *[L1 attributes deposited transaction][g-l1-attr-deposit]*, derived from the L1 origin. - - for the first L2 block in the epoch, zero or more *[user-deposited transactions][g-user-deposited]*, derived from + - a single _[L1 attributes deposited transaction][g-l1-attr-deposit]_, derived from the L1 origin. + - for the first L2 block in the epoch, zero or more _[user-deposited transactions][g-user-deposited]_, derived from the [receipts][g-receipts] of the L1 origin. - zero or more [network upgrade automation transactions]: special transactions to perform network upgrades. -- zero or more *[sequenced transactions][g-sequencing]*: regular transactions signed by L2 users, included in the +- zero or more _[sequenced transactions][g-sequencing]_: regular transactions signed by L2 users, included in the sequencer batch. Transactions **must** appear in this order in the payload attributes. @@ -1131,7 +1083,7 @@ A deposit transaction is derived with the following attributes: - `mint`: `0` - `value`: `0` - `gasLimit`: `375,000` -- `data`: `0x60806040523480156100105...` ([full bytecode](bytecode/ecotone-l1-block-deployment.txt)) +- `data`: `0x60806040523480156100105...` ([full bytecode](../static/bytecode/ecotone-l1-block-deployment.txt)) - `sourceHash`: `0x877a6077205782ea15a6dc8699fa5ebcec5e0f4389f09cb8eda09488231346f8`, computed with the "Upgrade-deposited" type, with `intent = "Ecotone: L1 Block Deployment" @@ -1172,7 +1124,7 @@ A deposit transaction is derived with the following attributes: - `mint`: `0` - `value`: `0` - `gasLimit`: `1,000,000` -- `data`: `0x60806040523480156100...` ([full bytecode](bytecode/ecotone-gas-price-oracle-deployment.txt)) +- `data`: `0x60806040523480156100...` ([full bytecode](../static/bytecode/ecotone-gas-price-oracle-deployment.txt)) - `sourceHash`: `0xa312b4510adf943510f05fcc8f15f86995a5066bd83ce11384688ae20e6ecf42` computed with the "Upgrade-deposited" type, with `intent = "Ecotone: Gas Price Oracle Deployment" diff --git a/specs/exec-engine.md b/specs/protocol/exec-engine.md similarity index 87% rename from specs/exec-engine.md rename to specs/protocol/exec-engine.md index 7aa4fc852..8f053588d 100644 --- a/specs/exec-engine.md +++ b/specs/protocol/exec-engine.md @@ -1,38 +1,8 @@ # L2 Execution Engine - - **Table of Contents** -- [1559 Parameters](#1559-parameters) -- [Deposited transaction processing](#deposited-transaction-processing) - - [Deposited transaction boundaries](#deposited-transaction-boundaries) -- [Fees](#fees) - - [Fee Vaults](#fee-vaults) - - [Priority fees (Sequencer Fee Vault)](#priority-fees-sequencer-fee-vault) - - [Base fees (Base Fee Vault)](#base-fees-base-fee-vault) - - [L1-Cost fees (L1 Fee Vault)](#l1-cost-fees-l1-fee-vault) - - [Pre-Ecotone](#pre-ecotone) - - [Ecotone L1-Cost fee changes (EIP-4844 DA)](#ecotone-l1-cost-fee-changes-eip-4844-da) -- [Engine API](#engine-api) - - [`engine_forkchoiceUpdatedV2`](#engine_forkchoiceupdatedv2) - - [Extended PayloadAttributesV2](#extended-payloadattributesv2) - - [`engine_forkchoiceUpdatedV3`](#engine_forkchoiceupdatedv3) - - [Extended PayloadAttributesV3](#extended-payloadattributesv3) - - [`engine_newPayloadV2`](#engine_newpayloadv2) - - [`engine_newPayloadV3`](#engine_newpayloadv3) - - [`engine_getPayloadV2`](#engine_getpayloadv2) - - [`engine_getPayloadV3`](#engine_getpayloadv3) - - [Extended Response](#extended-response) - - [`engine_signalSuperchainV1`](#engine_signalsuperchainv1) -- [Networking](#networking) -- [Sync](#sync) - - [Happy-path sync](#happy-path-sync) - - [Worst-case sync](#worst-case-sync) -- [Ecotone: disable Blob-transactions](#ecotone-disable-blob-transactions) -- [Ecotone: Beacon Block Root](#ecotone-beacon-block-root) - - + This document outlines the modifications, configuration and usage of a L1 execution engine for L2. @@ -68,7 +38,7 @@ To process deposited transactions safely, the deposits MUST be authenticated fir - Part of sync towards a trusted block hash (trusted through previous Engine API instruction) Deposited transactions MUST never be consumed from the transaction pool. -*The transaction pool can be disabled in a deposits-only rollup* +_The transaction pool can be disabled in a deposits-only rollup_ ## Fees @@ -83,8 +53,8 @@ fee payments are not registered as internal EVM calls, and thus distinguished be These are hardcoded addresses, pointing at pre-deployed proxy contracts. The proxies are backed by vault contract deployments, based on `FeeVault`, to route vault funds to L1 securely. -| Vault Name | Predeploy | -|---------------------|----------------------------------------------------------| +| Vault Name | Predeploy | +| ------------------- | ------------------------------------------------------ | | Sequencer Fee Vault | [`SequencerFeeVault`](predeploys.md#SequencerFeeVault) | | Base Fee Vault | [`BaseFeeVault`](predeploys.md#BaseFeeVault) | | L1 Fee Vault | [`L1FeeVault`](predeploys.md#L1FeeVault) | @@ -115,11 +85,11 @@ Before Ecotone activation, L1 cost is calculated as: in Wei and `uint256` range) Where: -- `rollupDataGas` is determined from the *full* encoded transaction +- `rollupDataGas` is determined from the _full_ encoded transaction (standard EIP-2718 transaction encoding, including signature fields): - Before Regolith fork: `rollupDataGas = zeroes * 4 + (ones + 68) * 16` - The addition of `68` non-zero bytes is a remnant of a pre-Bedrock L1-cost accounting function, - which accounted for the worst-case non-zero bytes addition to complement unsigned transactions, unlike Bedrock. + which accounted for the worst-case non-zero bytes addition to complement unsigned transactions, unlike Bedrock. - With Regolith fork: `rollupDataGas = zeroes * 4 + ones * 16` - `l1FeeOverhead` is the Gas Price Oracle `overhead` value. - `l1FeeScalar` is the Gas Price Oracle `scalar` value. @@ -155,7 +125,7 @@ Where: - the computation is an unlimited precision integer computation, with the result in Wei and having `uint256` range. -- zeoroes and ones are the count of zero and non-zero bytes respectively in the *full* encoded +- zeoroes and ones are the count of zero and non-zero bytes respectively in the _full_ encoded signed transaction. - `l1BaseFee` is the L1 base fee of the latest L1 origin registered in the L2 chain. @@ -196,7 +166,7 @@ and optionally initiates block production (`payloadAttributes` argument). Within the rollup, the types of forkchoice updates translate as: - `headBlockHash`: block hash of the head of the canonical chain. Labeled `"unsafe"` in user JSON-RPC. - Nodes may apply L2 blocks out of band ahead of time, and then reorg when L1 data conflicts. + Nodes may apply L2 blocks out of band ahead of time, and then reorg when L1 data conflicts. - `safeBlockHash`: block hash of the canonical chain, derived from L1 data, unlikely to reorg. - `finalizedBlockHash`: irreversible block hash, matches lower boundary of the dispute period. @@ -275,7 +245,7 @@ PayloadAttributesV3: { } ``` -The requirements of this object are the same as extended [`PayloadAttributesV2`][#extended-payloadattributesv2] with +The requirements of this object are the same as extended [`PayloadAttributesV2`](#extended-payloadattributesv2) with the addition of `parentBeaconBlockRoot` which is the parent beacon block root from the L1 origin block of the L2 block. The `parentBeaconBlockRoot` must be nil for Bedrock/Canyon/Delta payloads. @@ -333,8 +303,8 @@ Types: ```javascript SuperchainSignal: { - recommended: ProtocolVersion - required: ProtocolVersion + recommended: ProtocolVersion; + required: ProtocolVersion; } ``` @@ -358,7 +328,7 @@ This may include halting the engine, with consent of the execution engine operat ## Networking The execution engine can acquire all data through the rollup node, as derived from L1: -*P2P networking is strictly optional.* +_P2P networking is strictly optional._ However, to not bottleneck on L1 data retrieval speed, the P2P network functionality SHOULD be enabled, serving: @@ -367,7 +337,7 @@ However, to not bottleneck on L1 data retrieval speed, the P2P network functiona - Transaction pool (consumed by sequencer nodes) - State sync (happy-path for fast trustless db replication) - Historical block header and body retrieval - - *New blocks are acquired through the consensus layer instead (rollup node)* + - _New blocks are acquired through the consensus layer instead (rollup node)_ No modifications to L1 network functionality are required, except configuration: @@ -400,17 +370,17 @@ as the engine implementation can sync state faster through methods like [snap-sy 1. The rollup node informs the engine of the L2 chain head, unconditionally (part of regular node operation): - Bedrock / Canyon / Delta Payloads - - [`engine_newPayloadV2`][engine_newPayloadV2] is called with latest L2 block received from P2P. - - [`engine_forkchoiceUpdatedV2`][engine_forkchoiceUpdatedV2] is called with the current - `unsafe`/`safe`/`finalized` L2 block hashes. + - [`engine_newPayloadV2`][engine_newPayloadV2] is called with latest L2 block received from P2P. + - [`engine_forkchoiceUpdatedV2`][engine_forkchoiceUpdatedV2] is called with the current + `unsafe`/`safe`/`finalized` L2 block hashes. - Ecotone Payloads - - [`engine_newPayloadV3`][engine_newPayloadV3] is called with latest L2 block received from P2P. - - [`engine_forkchoiceUpdatedV3`][engine_forkchoiceUpdatedV3] is called with the current - `unsafe`/`safe`/`finalized` L2 block hashes. + - [`engine_newPayloadV3`][engine_newPayloadV3] is called with latest L2 block received from P2P. + - [`engine_forkchoiceUpdatedV3`][engine_forkchoiceUpdatedV3] is called with the current + `unsafe`/`safe`/`finalized` L2 block hashes. 2. The engine requests headers from peers, in reverse till the parent hash matches the local chain 3. The engine catches up: - a) A form of state sync is activated towards the finalized or head block hash - b) A form of block sync pulls block bodies and processes towards head block hash + a) A form of state sync is activated towards the finalized or head block hash + b) A form of block sync pulls block bodies and processes towards head block hash The exact P2P based sync is out of scope for the L2 specification: the operation within the engine is the exact same as with L1 (although with an EVM that supports deposits). @@ -471,6 +441,7 @@ For the Ecotone upgrade, this entails that: [PayloadAttributesV3]: https://github.com/ethereum/execution-apis/blob/cea7eeb642052f4c2e03449dc48296def4aafc24/src/engine/cancun.md#payloadattributesv3 [PayloadAttributesV2]: https://github.com/ethereum/execution-apis/blob/584905270d8ad665718058060267061ecfd79ca5/src/engine/shanghai.md#PayloadAttributesV2 [ExecutionPayloadV1]: https://github.com/ethereum/execution-apis/blob/769c53c94c4e487337ad0edea9ee0dce49c79bfa/src/engine/specification.md#ExecutionPayloadV1 +[ExecutionPayloadV2]: https://github.com/ethereum/execution-apis/blob/main/src/engine/shanghai.md#executionpayloadv2 [engine_forkchoiceUpdatedV3]: https://github.com/ethereum/execution-apis/blob/cea7eeb642052f4c2e03449dc48296def4aafc24/src/engine/cancun.md#engine_forkchoiceupdatedv3 [engine_forkchoiceUpdatedV2]: https://github.com/ethereum/execution-apis/blob/584905270d8ad665718058060267061ecfd79ca5/src/engine/shanghai.md#engine_forkchoiceupdatedv2 [engine_newPayloadV2]: https://github.com/ethereum/execution-apis/blob/584905270d8ad665718058060267061ecfd79ca5/src/engine/shanghai.md#engine_newpayloadv2 diff --git a/specs/guaranteed-gas-market.md b/specs/protocol/guaranteed-gas-market.md similarity index 92% rename from specs/guaranteed-gas-market.md rename to specs/protocol/guaranteed-gas-market.md index ca379c2fd..99e67d4cb 100644 --- a/specs/guaranteed-gas-market.md +++ b/specs/protocol/guaranteed-gas-market.md @@ -1,18 +1,10 @@ # Guaranteed Gas Fee Market - - **Table of Contents** -- [Gas Stipend](#gas-stipend) -- [Default Values](#default-values) -- [Limiting Guaranteed Gas](#limiting-guaranteed-gas) -- [Rationale for burning L1 Gas](#rationale-for-burning-l1-gas) -- [On Preventing Griefing Attacks](#on-preventing-griefing-attacks) + - - -[Deposited transactions](glossary.md#deposited-transaction) are transactions on L2 that are +[Deposited transactions](../glossary.md#deposited-transaction) are transactions on L2 that are initiated on L1. The gas that they use on L2 is bought on L1 via a gas burn (or a direct payment in the future). We maintain a fee market and hard cap on the amount of gas provided to all deposits in a single L1 block. diff --git a/specs/messengers.md b/specs/protocol/messengers.md similarity index 90% rename from specs/messengers.md rename to specs/protocol/messengers.md index 73007c247..bea90baa7 100644 --- a/specs/messengers.md +++ b/specs/protocol/messengers.md @@ -1,17 +1,8 @@ # Cross Domain Messengers - - **Table of Contents** -- [Message Passing](#message-passing) -- [Upgradability](#upgradability) -- [Message Versioning](#message-versioning) - - [Message Version 0](#message-version-0) - - [Message Version 1](#message-version-1) -- [Backwards Compatibility Notes](#backwards-compatibility-notes) - - + The cross domain messengers are responsible for providing a higher level API for developers who are interested in sending cross domain messages. They allow for diff --git a/specs/overview.md b/specs/protocol/overview.md similarity index 82% rename from specs/overview.md rename to specs/protocol/overview.md index ae9bdc45c..85b2d684a 100644 --- a/specs/overview.md +++ b/specs/protocol/overview.md @@ -1,65 +1,51 @@ # Optimism Overview - - **Table of Contents** -- [Architecture Design Goals](#architecture-design-goals) -- [Components](#components) - - [L1 Components](#l1-components) - - [L2 Components](#l2-components) - - [Transaction/Block Propagation](#transactionblock-propagation) -- [Key Interactions In Depth](#key-interactions-in-depth) - - [Deposits](#deposits) - - [Block Derivation](#block-derivation) - - [Overview](#overview) - - [Epochs and the Sequencing Window](#epochs-and-the-sequencing-window) - - [Block Derivation Loop](#block-derivation-loop) - - [Engine API](#engine-api) - - + This document is a high-level technical overview of the Optimism protocol. It aims to explain how the protocol works in an informal manner, and direct readers to other parts of the specification so that they may learn more. -This document assumes you've read the [introduction](introduction.md). +This document assumes you've read the [introduction](../introduction.md). ## Architecture Design Goals - **Execution-Level EVM Equivalence:** The developer experience should be identical to L1 except where L2 introduces a -fundamental difference. + fundamental difference. - No special compiler. - No unexpected gas costs. - Transaction traces work out-of-the-box. - All existing Ethereum tooling works - all you have to do is change the chain ID. - **Maximal compatibility with ETH1 nodes:** The implementation should minimize any differences with a vanilla Geth -node, and leverage as many existing L1 standards as possible. + node, and leverage as many existing L1 standards as possible. - The execution engine/rollup node uses the ETH2 Engine API to build the canonical L2 chain. - The execution engine leverages Geth's existing mempool and sync implementations, including snap sync. - **Minimize state and complexity:** - Whenever possible, services contributing to the rollup infrastructure are stateless. - Stateful services can recover to full operation from a fresh DB using the peer-to-peer network and on-chain sync -mechanisms. + mechanisms. - Running a replica is as simple as running a Geth node. ## Components -![Components](assets/components.svg) +![Components](../static/assets/components.svg) ### L1 Components - **OptimismPortal**: A feed of L2 transactions which originated as smart contract calls in the L1 state. - The `OptimismPortal` contract emits `TransactionDeposited` events, which the rollup driver reads in order to process -deposits. + deposits. - Deposits are guaranteed to be reflected in the L2 state within the _sequencing window_. - Beware that _transactions_ are deposited, not tokens. However deposited transactions are a key part of implementing -token deposits (tokens are locked on L1, then minted on L2 via a deposited transaction). + token deposits (tokens are locked on L1, then minted on L2 via a deposited transaction). - **BatchInbox**: An L1 address to which the Batch Submitter submits transaction batches. + - Transaction batches include L2 transaction calldata, timestamps, and ordering information. - The BatchInbox is a regular EOA address. This lets us pass on gas cost savings by not executing any EVM code. -- **L2OutputOracle**: A smart contract that stores [L2 output roots](glossary.md#l2-output) for use with withdrawals -and fault proofs. +- **L2OutputOracle**: A smart contract that stores [L2 output roots](../glossary.md#l2-output) for use with withdrawals + and fault proofs. ### L2 Components @@ -77,7 +63,7 @@ and fault proofs. - Sync state to other L2 nodes for fast onboarding. - Serves the Engine API to the rollup node. - **Batch Submitter** - - A background process that submits [transaction batches](glossary.md#sequencer-batch) to the `BatchInbox` address. + - A background process that submits [transaction batches](../glossary.md#sequencer-batch) to the `BatchInbox` address. - **Output Submitter** - A background process that submits L2 output commitments to the `L2OutputOracle`. @@ -95,7 +81,7 @@ however, and is provided as a convenience to lower latency for verifiers and the The below diagram illustrates how the sequencer and verifiers fit together: -![Propagation](assets/propagation.svg) +![Propagation](../static/assets/propagation.svg) ## Key Interactions In Depth @@ -142,7 +128,7 @@ worth of blocks has passed, i.e. after L1 block number `n + SEQUENCING_WINDOW_SI Each epoch contains at least one block. Every block in the epoch contains an L1 info transaction which contains contextual information about L1 such as the block hash and timestamp. The first block in the epoch also contains all deposits initiated via the `OptimismPortal` contract on L1. All L2 blocks can also contain _sequenced transactions_, -i.e. transactions submitted directly to the sequencer. +i.e. transactions submitted directly to the sequencer. Whenever the sequencer creates a new L2 block for a given epoch, it must submit it to L1 as part of a _batch_, within the epoch's sequencing window (i.e. the batch must land before L1 block `n + SEQUENCING_WINDOW_SIZE`). These batches are @@ -163,7 +149,7 @@ the L2 chain at worst after `SEQUENCING_WINDOW_SIZE` L1 blocks have passed. The following diagram describes this relationship, and how L2 blocks are derived from L1 blocks (L1 info transactions have been elided): -![Epochs and Sequencing Windows](assets/sequencer-block-gen.svg) +![Epochs and Sequencing Windows](../static/assets/sequencer-block-gen.svg) #### Block Derivation Loop @@ -174,7 +160,7 @@ derivation function performs the following steps: 1. Downloads deposit and transaction batch data for each block in the sequencing window. 2. Converts the deposit and transaction batch data into payload attributes for the Engine API. 3. Submits the payload attributes to the Engine API, where they are converted into blocks and added to the canonical -chain. + chain. This process is then repeated with incrementing epochs until the tip of L1 is reached. @@ -186,17 +172,17 @@ object and send it to the execution engine. The execution engine will then conve block, and add it to the chain. The basic sequence of the rollup driver is as follows: 1. Call [fork choice updated][EngineAPIVersion] with the payload attributes object. We'll skip over the details of the -fork choice state parameter for now - just know that one of its fields is the L2 chain's `headBlockHash`, and that it -is set to the block hash of the tip of the L2 chain. The Engine API returns a payload ID. + fork choice state parameter for now - just know that one of its fields is the L2 chain's `headBlockHash`, and that it + is set to the block hash of the tip of the L2 chain. The Engine API returns a payload ID. 2. Call [get payload][EngineAPIVersion] with the payload ID returned in step 1. The engine API returns a payload object -that includes a block hash as one of its fields. + that includes a block hash as one of its fields. 3. Call [new payload][EngineAPIVersion] with the payload returned in step 2. (Ectone blocks, must use V3, pre-Ecotone -blocks MUST use the V2 version) + blocks MUST use the V2 version) 4. Call [fork choice updated][EngineAPIVersion] with the fork choice parameter's `headBlockHash` set to the block hash -returned in step 2. The tip of the L2 chain is now the block created in step 1. + returned in step 2. The tip of the L2 chain is now the block created in step 1. [EngineAPIVersion]: derivation.md#engine-api-usage The swimlane diagram below visualizes the process: -![Engine API](assets/engine.svg) +![Engine API](../static/assets/engine.svg) diff --git a/specs/predeploys.md b/specs/protocol/predeploys.md similarity index 81% rename from specs/predeploys.md rename to specs/protocol/predeploys.md index 5d9a54143..bc19da197 100644 --- a/specs/predeploys.md +++ b/specs/protocol/predeploys.md @@ -1,35 +1,12 @@ # Predeploys - - **Table of Contents** -- [Overview](#overview) -- [LegacyMessagePasser](#legacymessagepasser) -- [L2ToL1MessagePasser](#l2tol1messagepasser) -- [DeployerWhitelist](#deployerwhitelist) -- [LegacyERC20ETH](#legacyerc20eth) -- [WETH9](#weth9) -- [L2CrossDomainMessenger](#l2crossdomainmessenger) -- [L2StandardBridge](#l2standardbridge) -- [L1BlockNumber](#l1blocknumber) -- [GasPriceOracle](#gaspriceoracle) -- [L1Block](#l1block) -- [ProxyAdmin](#proxyadmin) -- [SequencerFeeVault](#sequencerfeevault) -- [OptimismMintableERC20Factory](#optimismmintableerc20factory) -- [OptimismMintableERC721Factory](#optimismmintableerc721factory) -- [BaseFeeVault](#basefeevault) -- [L1FeeVault](#l1feevault) -- [SchemaRegistry](#schemaregistry) -- [EAS](#eas) -- [create2Deployer](#create2deployer) - - + ## Overview -[Predeployed smart contracts](glossary.md#predeployed-contract-predeploy) exist on Optimism +[Predeployed smart contracts](../glossary.md#predeployed-contract-predeploy) exist on Optimism at predetermined addresses in the genesis state. They are similar to precompiles but instead run directly in the EVM instead of running native code outside of the EVM. @@ -48,29 +25,29 @@ The following table includes each of the predeploys. The system version indicates when the predeploy was introduced. The possible values are `Legacy` or `Bedrock` or `Canyon`. Deprecated contracts should not be used. -| Name | Address | Introduced | Deprecated | Proxied | -| ----------------------------------------- | ------------------------------------------ | ----------- | ---------- | ------- | -| LegacyMessagePasser | 0x4200000000000000000000000000000000000000 | Legacy | Yes | Yes | -| DeployerWhitelist | 0x4200000000000000000000000000000000000002 | Legacy | Yes | Yes | -| LegacyERC20ETH | 0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000 | Legacy | Yes | No | -| WETH9 | 0x4200000000000000000000000000000000000006 | Legacy | No | No | -| L2CrossDomainMessenger | 0x4200000000000000000000000000000000000007 | Legacy | No | Yes | -| L2StandardBridge | 0x4200000000000000000000000000000000000010 | Legacy | No | Yes | -| SequencerFeeVault | 0x4200000000000000000000000000000000000011 | Legacy | No | Yes | -| OptimismMintableERC20Factory | 0x4200000000000000000000000000000000000012 | Legacy | No | Yes | -| L1BlockNumber | 0x4200000000000000000000000000000000000013 | Legacy | Yes | Yes | -| GasPriceOracle | 0x420000000000000000000000000000000000000F | Legacy | No | Yes | -| GovernanceToken | 0x4200000000000000000000000000000000000042 | Legacy | No | No | -| L1Block | 0x4200000000000000000000000000000000000015 | Bedrock | No | Yes | -| L2ToL1MessagePasser | 0x4200000000000000000000000000000000000016 | Bedrock | No | Yes | -| L2ERC721Bridge | 0x4200000000000000000000000000000000000014 | Legacy | No | Yes | -| OptimismMintableERC721Factory | 0x4200000000000000000000000000000000000017 | Bedrock | No | Yes | -| ProxyAdmin | 0x4200000000000000000000000000000000000018 | Bedrock | No | Yes | -| BaseFeeVault | 0x4200000000000000000000000000000000000019 | Bedrock | No | Yes | -| L1FeeVault | 0x420000000000000000000000000000000000001a | Bedrock | No | Yes | -| SchemaRegistry | 0x4200000000000000000000000000000000000020 | Bedrock | No | Yes | -| EAS | 0x4200000000000000000000000000000000000021 | Bedrock | No | Yes | -| create2Deployer | 0x13b0D85CcB8bf860b6b79AF3029fCA081AE9beF2 | Canyon | No | No | +| Name | Address | Introduced | Deprecated | Proxied | +| ----------------------------- | ------------------------------------------ | ---------- | ---------- | ------- | +| LegacyMessagePasser | 0x4200000000000000000000000000000000000000 | Legacy | Yes | Yes | +| DeployerWhitelist | 0x4200000000000000000000000000000000000002 | Legacy | Yes | Yes | +| LegacyERC20ETH | 0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000 | Legacy | Yes | No | +| WETH9 | 0x4200000000000000000000000000000000000006 | Legacy | No | No | +| L2CrossDomainMessenger | 0x4200000000000000000000000000000000000007 | Legacy | No | Yes | +| L2StandardBridge | 0x4200000000000000000000000000000000000010 | Legacy | No | Yes | +| SequencerFeeVault | 0x4200000000000000000000000000000000000011 | Legacy | No | Yes | +| OptimismMintableERC20Factory | 0x4200000000000000000000000000000000000012 | Legacy | No | Yes | +| L1BlockNumber | 0x4200000000000000000000000000000000000013 | Legacy | Yes | Yes | +| GasPriceOracle | 0x420000000000000000000000000000000000000F | Legacy | No | Yes | +| GovernanceToken | 0x4200000000000000000000000000000000000042 | Legacy | No | No | +| L1Block | 0x4200000000000000000000000000000000000015 | Bedrock | No | Yes | +| L2ToL1MessagePasser | 0x4200000000000000000000000000000000000016 | Bedrock | No | Yes | +| L2ERC721Bridge | 0x4200000000000000000000000000000000000014 | Legacy | No | Yes | +| OptimismMintableERC721Factory | 0x4200000000000000000000000000000000000017 | Bedrock | No | Yes | +| ProxyAdmin | 0x4200000000000000000000000000000000000018 | Bedrock | No | Yes | +| BaseFeeVault | 0x4200000000000000000000000000000000000019 | Bedrock | No | Yes | +| L1FeeVault | 0x420000000000000000000000000000000000001a | Bedrock | No | Yes | +| SchemaRegistry | 0x4200000000000000000000000000000000000020 | Bedrock | No | Yes | +| EAS | 0x4200000000000000000000000000000000000021 | Bedrock | No | Yes | +| create2Deployer | 0x13b0D85CcB8bf860b6b79AF3029fCA081AE9beF2 | Canyon | No | No | ## LegacyMessagePasser @@ -257,7 +234,7 @@ to 6, and the old `scalar` and `overhead` values are ignored. Address: `0x4200000000000000000000000000000000000015` -[l1-block-predeploy]: glossary.md#l1-attributes-predeployed-contract +[l1-block-predeploy]: ../glossary.md#l1-attributes-predeployed-contract The [L1Block][l1-block-predeploy] was introduced in Bedrock and is responsible for maintaining L1 context in L2. This allows for L1 state to be accessed in L2. diff --git a/specs/preinstalls.md b/specs/protocol/preinstalls.md similarity index 88% rename from specs/preinstalls.md rename to specs/protocol/preinstalls.md index 0a4e3aec3..a8d8208c4 100644 --- a/specs/preinstalls.md +++ b/specs/protocol/preinstalls.md @@ -1,33 +1,19 @@ # Preinstalls - - **Table of Contents** -- [Overview](#overview) -- [Safe](#safe) -- [SafeL2](#safel2) -- [MultiSend](#multisend) -- [MultiSendCallOnly](#multisendcallonly) -- [SafeSingletonFactory](#safesingletonfactory) -- [Multicall3](#multicall3) -- [Arachnid's Deterministic Deployment Proxy](#arachnids-deterministic-deployment-proxy) -- [Permit2](#permit2) -- [ERC-4337 EntryPoint](#erc-4337-entrypoint) -- [ERC-4337 SenderCreator](#erc-4337-sendercreator) - - + ## Overview -[Preinstalled smart contracts](glossary.md#preinstalled-contract-preinstall) exist on Optimism +[Preinstalled smart contracts](../glossary.md#preinstalled-contract-preinstall) exist on Optimism at predetermined addresses in the genesis state. They are similar to precompiles but instead run directly in the EVM instead of running native code outside of the EVM and are developed by third parties unaffiliated with the Optimism Collective. These preinstalls are commonly deployed smart contracts that are being placed at genesis for convenience. It's important to note that these contracts do not have the same security guarantees -as [Predeployed smart contracts](glossary.md#predeployed-contract-predeploy). +as [Predeployed smart contracts](../glossary.md#predeployed-contract-predeploy). The following table includes each of the preinstalls. diff --git a/specs/proposals.md b/specs/protocol/proposals.md similarity index 91% rename from specs/proposals.md rename to specs/protocol/proposals.md index 6a93b7940..da04c77dc 100644 --- a/specs/proposals.md +++ b/specs/protocol/proposals.md @@ -2,22 +2,12 @@ -[g-rollup-node]: glossary.md#rollup-node -[g-mpt]: glossary.md#merkle-patricia-trie +[g-rollup-node]: ../glossary.md#rollup-node +[g-mpt]: ../glossary.md#merkle-patricia-trie - - **Table of Contents** -- [Proposing L2 Output Commitments](#proposing-l2-output-commitments) - - [L2OutputOracle v1.0.0](#l2outputoracle-v100) -- [L2 Output Commitment Construction](#l2-output-commitment-construction) -- [L2 Output Oracle Smart Contract](#l2-output-oracle-smart-contract) - - [Configuration](#configuration) -- [Security Considerations](#security-considerations) - - [L1 Reorgs](#l1-reorgs) - - + After processing one or more blocks the outputs will need to be synchronized with the settlement layer (L1) for trustless execution of L2-to-L1 messaging, such as withdrawals. diff --git a/specs/rollup-node-p2p.md b/specs/protocol/rollup-node-p2p.md similarity index 92% rename from specs/rollup-node-p2p.md rename to specs/protocol/rollup-node-p2p.md index 8c9791281..ba9b2ce65 100644 --- a/specs/rollup-node-p2p.md +++ b/specs/protocol/rollup-node-p2p.md @@ -7,7 +7,7 @@ without relying on a single centralized endpoint. This also enables faster historical sync to be bootstrapped by providing block headers to sync towards, and only having to compare the L2 chain inputs to the L1 data as compared to processing everything one block at a time. -The rollup node will *always* prioritize L1 and reorganize to match the canonical chain. +The rollup node will _always_ prioritize L1 and reorganize to match the canonical chain. The L2 data retrieved via the P2P interface is strictly a speculative extension, also known as the "unsafe" chain, to improve the happy case performance. @@ -25,44 +25,9 @@ This document only specifies the composition and configuration of these network These components have their own standards, implementations in Go/Rust/Java/Nim/JS/more, and are adopted by several other blockchains, most notably the [L1 consensus layer (Eth2)][eth2-p2p]. - - **Table of Contents** -- [P2P configuration](#p2p-configuration) - - [Identification](#identification) - - [Discv5](#discv5) - - [Structure](#structure) - - [LibP2P](#libp2p) - - [Transport](#transport) - - [Dialing](#dialing) - - [NAT](#nat) - - [Peer management](#peer-management) - - [Transport security](#transport-security) - - [Protocol negotiation](#protocol-negotiation) - - [Identify](#identify) - - [Ping](#ping) - - [Multiplexing](#multiplexing) - - [GossipSub](#gossipsub) - - [Content-based message identification](#content-based-message-identification) - - [Message compression and limits](#message-compression-and-limits) - - [Message ID computation](#message-id-computation) - - [Heartbeat and parameters](#heartbeat-and-parameters) - - [Topic configuration](#topic-configuration) - - [Topic validation](#topic-validation) -- [Gossip Topics](#gossip-topics) - - [`blocksv1`](#blocksv1) - - [`blocksv2`](#blocksv2) - - [`blocksv3`](#blocksv3) - - [Block encoding](#block-encoding) - - [Block signatures](#block-signatures) - - [Block validation](#block-validation) - - [Block processing](#block-processing) - - [Block topic scoring parameters](#block-topic-scoring-parameters) -- [Req-Resp](#req-resp) - - [`payload_by_number`](#payload_by_number) - - + ## P2P configuration @@ -417,7 +382,7 @@ A `res = 0` response should be verified to: A `res > 0` response code should not be accepted. The result code is helpful for debugging, but the client should regard any error like any other unanswered request, as the responding peer cannot be trusted. ----- +--- [libp2p]: https://libp2p.io/ [discv5]: https://github.com/ethereum/devp2p/blob/master/discv5/discv5.md diff --git a/specs/rollup-node.md b/specs/protocol/rollup-node.md similarity index 84% rename from specs/rollup-node.md rename to specs/protocol/rollup-node.md index 3fe947b49..e5ff3dee4 100644 --- a/specs/rollup-node.md +++ b/specs/protocol/rollup-node.md @@ -1,14 +1,15 @@ # Rollup Node Specification -[g-rollup-node]: glossary.md#rollup-node -[g-derivation]: glossary.md#L2-chain-derivation -[g-payload-attr]: glossary.md#payload-attributes -[g-block]: glossary.md#block -[g-exec-engine]: glossary.md#execution-engine -[g-reorg]: glossary.md#re-organization -[g-rollup-driver]: glossary.md#rollup-driver -[g-receipts]: glossary.md#receipt + +[g-rollup-node]: ../glossary.md#rollup-node +[g-derivation]: ../glossary.md#L2-chain-derivation +[g-payload-attr]: ../glossary.md#payload-attributes +[g-block]: ../glossary.md#block +[g-exec-engine]: ../glossary.md#execution-engine +[g-reorg]: ../glossary.md#re-organization +[g-rollup-driver]: ../glossary.md#rollup-driver +[g-receipts]: ../glossary.md#receipt The [rollup node][g-rollup-node] is the component responsible for [deriving the L2 chain][g-derivation] from L1 blocks (and their associated [receipts][g-receipts]). @@ -16,22 +17,9 @@ The [rollup node][g-rollup-node] is the component responsible for [deriving the The part of the rollup node that derives the L2 chain is called the [rollup driver][g-rollup-driver]. This document is currently only concerned with the specification of the rollup driver. - - **Table of Contents** -- [Driver](#driver) - - [Derivation](#derivation) -- [L2 Output RPC method](#l2-output-rpc-method) - - [Structures](#structures) - - [BlockID](#blockid) - - [L1BlockRef](#l1blockref) - - [L2BlockRef](#l2blockref) - - [SyncStatus](#syncstatus) - - [Output Method API](#output-method-api) -- [Protocol Version tracking](#protocol-version-tracking) - - + ## Driver diff --git a/specs/safe-liveness-checking.md b/specs/protocol/safe-liveness-checking.md similarity index 83% rename from specs/safe-liveness-checking.md rename to specs/protocol/safe-liveness-checking.md index 3bf65b63b..7a7a927c7 100644 --- a/specs/safe-liveness-checking.md +++ b/specs/protocol/safe-liveness-checking.md @@ -1,27 +1,8 @@ # Safe Liveness Checking - - **Table of Contents** -- [Liveness checking Mechanism](#liveness-checking-mechanism) -- [Liveness checking methodology](#liveness-checking-methodology) - - [The liveness guard](#the-liveness-guard) - - [The liveness module](#the-liveness-module) - - [Owner removal call flow](#owner-removal-call-flow) - - [Shutdown](#shutdown) - - [Security Properties](#security-properties) - - [In the guard](#in-the-guard) - - [In the module](#in-the-module) - - [Interdependency between the guard and module](#interdependency-between-the-guard-and-module) -- [Operational considerations](#operational-considerations) - - [Manual validation of new owner liveness](#manual-validation-of-new-owner-liveness) - - [Deploying the liveness checking system](#deploying-the-liveness-checking-system) - - [Modify the liveness checking system](#modify-the-liveness-checking-system) - - [Replacing the module](#replacing-the-module) - - [Replacing the guard](#replacing-the-guard) - - + ## Liveness checking Mechanism @@ -101,8 +82,8 @@ sequenceDiagram ### Shutdown In the unlikely event that the signer set (`N`) is reduced below the allowed minimum number of - owners, then (and only then) is a shutdown mechanism activated which removes the existing - signers, and hands control of the multisig over to a predetermined entity. +owners, then (and only then) is a shutdown mechanism activated which removes the existing +signers, and hands control of the multisig over to a predetermined entity. ### Security Properties @@ -126,7 +107,7 @@ The following security properties must be upheld: 1. During a shutdown the module correctly removes all signers, and converts the safe to a 1 of 1. 1. The module only removes an owner if they have not demonstrated liveness during the interval, or - if enough other owners have been removed to activate the shutdown mechanism. + if enough other owners have been removed to activate the shutdown mechanism. 1. The module correctly sets the Safe's threshold upon removing a signer. Note: neither the module nor guard attempt to prevent a quorum of owners from removing either the liveness @@ -158,8 +139,7 @@ therefore be done prior to adding a new owner. The module and guard are intended to be deployed and installed on the safe in the following sequence: -1. Deploy the guard contract - 2. The guard's constructor will read the Safe's owners and set a timestamp +1. Deploy the guard contract 2. The guard's constructor will read the Safe's owners and set a timestamp 1. Deploy the module. 1. Set the guard on the safe. 1. Enable the module on the safe. diff --git a/specs/span-batches.md b/specs/protocol/span-batches.md similarity index 89% rename from specs/span-batches.md rename to specs/protocol/span-batches.md index 0091885b5..731fcef47 100644 --- a/specs/span-batches.md +++ b/specs/protocol/span-batches.md @@ -1,37 +1,16 @@ # Span-batches -[g-deposit-tx-type]: glossary.md#deposited-transaction-type - - +[g-deposit-tx-type]: ../glossary.md#deposited-transaction-type + **Table of Contents** -- [Introduction](#introduction) -- [Span batch format](#span-batch-format) - - [Max span-batch size](#max-span-batch-size) - - [Future batch-format extension](#future-batch-format-extension) -- [Span batch Activation Rule](#span-batch-activation-rule) -- [Optimization Strategies](#optimization-strategies) - - [Truncating information and storing only necessary data](#truncating-information-and-storing-only-necessary-data) - - [`tx_data_headers` removal from initial specs](#tx_data_headers-removal-from-initial-specs) - - [`Chain ID` removal from initial specs](#chain-id-removal-from-initial-specs) - - [Reorganization of constant length transaction fields](#reorganization-of-constant-length-transaction-fields) - - [RLP encoding for only variable length fields](#rlp-encoding-for-only-variable-length-fields) - - [Store `y_parity` and `protected_bit` instead of `v`](#store-y_parity-and-protected_bit-instead-of-v) - - [Adjust `txs` Data Layout for Better Compression](#adjust-txs-data-layout-for-better-compression) - - [`fee_recipients` Encoding Scheme](#fee_recipients-encoding-scheme) -- [How derivation works with Span Batch?](#how-derivation-works-with-span-batch) -- [Integration](#integration) - - [Channel Reader (Batch Decoding)](#channel-reader-batch-decoding) - - [Batch Queue](#batch-queue) - - [Batcher](#batcher) - - + > The span-batches spec is experimental :shipit: > -> *this feature is in active R&D and not yet part of any hard fork +> \*this feature is in active R&D and not yet part of any hard fork ## Introduction @@ -69,12 +48,12 @@ Span-batches address these inefficiencies, with a new batch format version. [span-batch-format]: #span-batch-format Note that span-batches, unlike previous singular batches, -encode *a range of consecutive* L2 blocks at the same time. +encode _a range of consecutive_ L2 blocks at the same time. Introduce version `1` to the [batch-format](derivation.md#batch-format) table: | `batch_version` | `content` | -|-----------------|---------------------| +| --------------- | ------------------- | | 1 | `prefix ++ payload` | Notation: @@ -83,7 +62,7 @@ Notation: - `span_start`: first L2 block in the span - `span_end`: last L2 block in the span - `uvarint`: unsigned Base128 varint, as defined in [protobuf spec] -- `rlp_encode`: a function that encodes a batch according to the [RLP format], +- `rlp_encode`: a function that encodes a batch according to the RLP format, and `[x, y, z]` denotes a list containing items `x`, `y` and `z` [protobuf spec]: https://protobuf.dev/programming-guides/encoding/#varints @@ -108,7 +87,7 @@ Where: - `block_tx_counts`: for each block, a `uvarint` of `len(block.transactions)`. - `txs`: L2 transactions which is reorganized and encoded as below. - `txs = contract_creation_bits ++ y_parity_bits ++ - tx_sigs ++ tx_tos ++ tx_datas ++ tx_nonces ++ tx_gases ++ protected_bits` +tx_sigs ++ tx_tos ++ tx_datas ++ tx_nonces ++ tx_gases ++ protected_bits` - `contract_creation_bits`: standard bitlist of `sum(block_tx_counts)` bits: 1 bit per L2 transactions, indicating if transaction is a contract creation transaction. - `y_parity_bits`: standard bitlist of `sum(block_tx_counts)` bits: @@ -123,7 +102,7 @@ Where: - `1`: ([EIP-2930]): `0x01 ++ rlp_encode(value, gasPrice, data, accessList)` - `2`: ([EIP-1559]): `0x02 ++ rlp_encode(value, max_priority_fee_per_gas, max_fee_per_gas, data, access_list)` - `tx_nonces`: concatenated list of `uvarint` of `nonce` field. - - `tx_gases`: concatenated list of `uvarint` of gas limits. + - `tx_gases`: concatenated list of `uvarint` of gas limits. - `legacy`: `gasLimit` - `1`: ([EIP-2930]): `gasLimit` - `2`: ([EIP-1559]): `gas_limit` @@ -153,7 +132,7 @@ This is an experimental extension of the span-batch format, and not activated wi Introduce version `2` to the [batch-format](derivation.md#batch-format) table: | `batch_version` | `content` | -|-----------------|---------------------| +| --------------- | ------------------- | | 2 | `prefix ++ payload` | Where: @@ -227,7 +206,7 @@ Deposit transactions are excluded in batches and are never written at L1 so excl ### Adjust `txs` Data Layout for Better Compression -There are (8 choose 2) * 6! = 20160 permutations of ordering fields of `txs`. +There are (8 choose 2) \* 6! = 20160 permutations of ordering fields of `txs`. It is not 8! because `contract_creation_bits` must be first decoded in order to decode `tx_tos`. We experimented to find out the best layout for compression. It turned out placing random data together(`TxSigs`, `TxTos`, `TxDatas`), @@ -309,7 +288,7 @@ Span-batch rules, in validation order: - `batch.parent_check != prev_l2_block.hash[:20]` -> `drop`: i.e. the checked part of the parent hash must be equal to the same part of the corresponding L2 block hash. - Sequencing-window checks: - - Note: The sequencing window is enforced for the *batch as a whole*: + - Note: The sequencing window is enforced for the _batch as a whole_: if the batch was partially invalid instead, it would drop the oldest L2 blocks, which makes the later L2 blocks invalid. - Variables: @@ -330,7 +309,7 @@ Span-batch rules, in validation order: - `start_epoch_num < prev_l2_block.l1_origin.number` -> `drop`: epoch number cannot be older than the origin of parent block - Max Sequencer time-drift checks: - - Note: The max time-drift is enforced for the *batch as a whole*, to keep the possible output variants small. + - Note: The max time-drift is enforced for the _batch as a whole_, to keep the possible output variants small. - Variables: - `block_input`: an L2 block from the span-batch, with L1 origin as derived from the `origin_bits` and now established canonical L1 chain. diff --git a/specs/superchain-configuration.md b/specs/protocol/superchain-configuration.md similarity index 80% rename from specs/superchain-configuration.md rename to specs/protocol/superchain-configuration.md index 3abf6916e..e2b389972 100644 --- a/specs/superchain-configuration.md +++ b/specs/protocol/superchain-configuration.md @@ -3,17 +3,9 @@ The SuperchainConfig contract is used to manage global configuration values for multiple OP Chains within a single Superchain network. - - **Table of Contents** -- [Configurable values](#configurable-values) -- [Configuration data flow](#configuration-data-flow) - - [Pausability](#pausability) - - [Paused identifiers](#paused-identifiers) - - [Scope of pausability](#scope-of-pausability) - - + ## Configurable values diff --git a/specs/superchain-upgrades.md b/specs/protocol/superchain-upgrades.md similarity index 91% rename from specs/superchain-upgrades.md rename to specs/protocol/superchain-upgrades.md index c574335a9..ca12b1dff 100644 --- a/specs/superchain-upgrades.md +++ b/specs/protocol/superchain-upgrades.md @@ -11,33 +11,9 @@ as well as the default Superchain Targets. Activation rule parameters of network upgrades are configured as part of the Superchain Target specification: chains following the same Superchain Target upgrade synchronously. - - **Table of Contents** -- [Protocol Version](#protocol-version) - - [Protocol Version Format](#protocol-version-format) - - [Build identifier](#build-identifier) - - [Major versions](#major-versions) - - [Minor versions](#minor-versions) - - [Patch versions](#patch-versions) - - [Pre-releases](#pre-releases) - - [Protocol Version Exposure](#protocol-version-exposure) -- [Superchain Target](#superchain-target) - - [Superchain Version signaling](#superchain-version-signaling) - - [`ProtocolVersions` L1 contract](#protocolversions-l1-contract) -- [Activation rules](#activation-rules) - - [L2 Block-number based activation (deprecated)](#l2-block-number-based-activation-deprecated) - - [L2 Block-timestamp based activation](#l2-block-timestamp-based-activation) -- [OP-Stack Protocol versions](#op-stack-protocol-versions) -- [Post-Bedrock Network upgrades](#post-bedrock-network-upgrades) - - [Regolith](#regolith) -- [Canyon](#canyon) -- [Delta](#delta) -- [Ecotone](#ecotone) -- [Fjord](#fjord) - - + ## Protocol Version @@ -147,7 +123,7 @@ hardforks already expose the change of functionality upon activation as required and the Protocol Version is meant for offchain usage only. The protocol version indicates support rather than activation of functionality. There is one exception however: signaling by onchain components to offchain components. -More about this in [Superchain Version signaling]. +More about this in [Superchain Version signaling](#superchain-version-signaling). ## Superchain Target @@ -280,7 +256,7 @@ Summary of changes: The [deposit specification](deposits.md) specifies the deposit changes of the Regolith upgrade in more detail. The [execution engine specification](exec-engine.md) specifies the L1 cost function difference. -The Regolith upgrade uses a *L2 block-timestamp* activation-rule, and is specified in both the +The Regolith upgrade uses a _L2 block-timestamp_ activation-rule, and is specified in both the rollup-node (`regolith_time`) and execution engine (`config.regolithTime`). ## Canyon @@ -300,7 +276,7 @@ The Canyon upgrade contains the Shapella upgrade from L1 and some minor protocol - [Adds the deposit nonce & deposit nonce version to the deposit receipt hash](deposits.md#deposit-receipt) - [Deploys the create2Deployer to `0x13b0D85CcB8bf860b6b79AF3029fCA081AE9beF2`](predeploys.md#create2deployer) -The Canyon upgrade uses a *L2 block-timestamp* activation-rule, and is specified in both the +The Canyon upgrade uses a _L2 block-timestamp_ activation-rule, and is specified in both the rollup-node (`canyon_time`) and execution engine (`config.canyonTime`). Shanghai time in the execution engine should be set to the same time as the Canyon time. @@ -308,7 +284,7 @@ execution engine should be set to the same time as the Canyon time. The Delta upgrade consists of a single consensus-layer feature: [Span Batches](span-batches.md). -The Delta upgrade uses a *L2 block-timestamp* activation-rule, and is specified only in the rollup-node (`delta_time`). +The Delta upgrade uses a _L2 block-timestamp_ activation-rule, and is specified only in the rollup-node (`delta_time`). ## Ecotone @@ -327,7 +303,7 @@ Dencun Upgrade: - [EIP-6780: SELFDESTRUCT only in same transaction](https://eips.ethereum.org/EIPS/eip-6780) - [EIP-7516: BLOBBASEFEE opcode](https://eips.ethereum.org/EIPS/eip-7516) - [BLOBBASEFEE always pushes 1 onto the stack](exec-engine.md#ecotone-disable-blob-transactions) -- Deneb (Consensus Layer): *not applicable to L2* +- Deneb (Consensus Layer): _not applicable to L2_ - [EIP-7044: Perpetually Valid Signed Voluntary Exits](https://eips.ethereum.org/EIPS/eip-7044) - [EIP-7045: Increase Max Attestation Inclusion Slot](https://eips.ethereum.org/EIPS/eip-7045) - [EIP-7514: Add Max Epoch Churn Limit](https://eips.ethereum.org/EIPS/eip-7514) diff --git a/specs/system_config.md b/specs/protocol/system_config.md similarity index 88% rename from specs/system_config.md rename to specs/protocol/system_config.md index b3eb9a829..4279cef47 100644 --- a/specs/system_config.md +++ b/specs/protocol/system_config.md @@ -1,20 +1,8 @@ # System Config - - **Table of Contents** -- [System config contents (version 0)](#system-config-contents-version-0) - - [`batcherHash` (`bytes32`)](#batcherhash-bytes32) - - [Scalars](#scalars) - - [Pre-Ecotone `scalar`, `overhead` (`uint256,uint256`)](#pre-ecotone-scalar-overhead-uint256uint256) - - [Ecotone `scalar`, `overhead` (`uint256,uint256`) change](#ecotone-scalar-overhead-uint256uint256-change) - - [`gasLimit` (`uint64`)](#gaslimit-uint64) - - [`unsafeBlockSigner` (`address`)](#unsafeblocksigner-address) -- [Writing the system config](#writing-the-system-config) -- [Reading the system config](#reading-the-system-config) - - + The `SystemConfig` is a contract on L1 that can emit rollup configuration changes as log events. The rollup [block derivation process](derivation.md) picks up on these log events and applies the changes. @@ -36,7 +24,7 @@ to enable more extensive redundancy and/or rotation configurations. ### Scalars The L1 fee parameters, also known as Gas Price Oracle (GPO) parameters, are used to compute the L1 -data fee applied to an L2 transaction. The specific parameters used depend on the upgrades that +data fee applied to an L2 transaction. The specific parameters used depend on the upgrades that are active. Fee parameter updates are signaled to L2 through the `GAS_CONFIG` log-event of the `SystemConfig`. @@ -56,7 +44,7 @@ After Ecotone activation: The `scalar` is encoded as big-endian `uint256`, interpreted as `bytes32`, and composed as following: -*Byte ranges are indicated with `[` (inclusive) and `)` (exclusive). +\*Byte ranges are indicated with `[` (inclusive) and `)` (exclusive). - `0`: scalar-version byte - `[1, 32)`: depending scalar-version: diff --git a/specs/withdrawals.md b/specs/protocol/withdrawals.md similarity index 88% rename from specs/withdrawals.md rename to specs/protocol/withdrawals.md index d025e5f71..4c5a99e63 100644 --- a/specs/withdrawals.md +++ b/specs/protocol/withdrawals.md @@ -2,13 +2,13 @@ -[g-deposits]: glossary.md#deposits -[g-deposited]: glossary.md#deposited-transaction -[deposit-tx-type]: glossary.md#deposited-transaction-type -[g-withdrawal]: glossary.md#withdrawal -[g-mpt]: glossary.md#merkle-patricia-trie -[g-relayer]: glossary.md#withdrawals -[g-execution-engine]: glossary.md#execution-engine +[g-deposits]: ../glossary.md#deposits +[g-deposited]: ../glossary.md#deposited-transaction +[deposit-tx-type]: ../glossary.md#deposited-transaction-type +[g-withdrawal]: ../glossary.md#withdrawal +[g-mpt]: ../glossary.md#merkle-patricia-trie +[g-relayer]: ../glossary.md#withdrawals +[g-execution-engine]: ../glossary.md#execution-engine [Withdrawals][g-withdrawal] are cross domain transactions which are initiated on L2, and finalized by a transaction executed on L1. Notably, withdrawals may be used by an L2 account to call an L1 contract, or to transfer ETH from @@ -34,23 +34,9 @@ In this way, withdrawals are different from [deposits][g-deposits] which make us [execution engine][g-execution-engine] client. Rather, withdrawals transaction must use smart contracts on L1 for finalization. - - **Table of Contents** -- [Withdrawal Flow](#withdrawal-flow) - - [On L2](#on-l2) - - [On L1](#on-l1) -- [The L2ToL1MessagePasser Contract](#the-l2tol1messagepasser-contract) - - [Addresses are not Aliased on Withdrawals](#addresses-are-not-aliased-on-withdrawals) -- [The Optimism Portal Contract](#the-optimism-portal-contract) -- [Withdrawal Verification and Finalization](#withdrawal-verification-and-finalization) -- [Security Considerations](#security-considerations) - - [Key Properties of Withdrawal Verification](#key-properties-of-withdrawal-verification) - - [Handling Successfully Verified Messages That Fail When Relayed](#handling-successfully-verified-messages-that-fail-when-relayed) - - [OptimismPortal can send arbitrary messages on L1](#optimismportal-can-send-arbitrary-messages-on-l1) - - + ## Withdrawal Flow diff --git a/specs/root.md b/specs/root.md new file mode 100644 index 000000000..935312f95 --- /dev/null +++ b/specs/root.md @@ -0,0 +1,63 @@ +# OP Stack Specs + +This directory contains the plain english specs for Optimism, a minimal optimistic rollup protocol +that maintains 1:1 compatibility with Ethereum. + +## Specification Contents + +- [Introduction](introduction.md) +- [Overview](protocol/overview.md) +- [Deposits](protocol/deposits.md) +- [Withdrawals](protocol/withdrawals.md) +- [Execution Engine](protocol/exec-engine.md) +- [L2 Output Root Proposals](protocol/proposals.md) +- [Rollup Node](protocol/rollup-node.md) +- [Rollup Node P2p](protocol/rollup-node-p2p.md) +- [L2 Chain Derivation](protocol/derivation.md) +- [Superchain Upgrades](protocol/superchain-upgrades.md) +- [System Config](protocol/system_config.md) +- [Batch Submitter](protocol/batcher.md) +- [Guaranteed Gas Market](protocol/guaranteed-gas-market.md) +- [Messengers](protocol/messengers.md) +- [Bridges](protocol/bridges.md) +- [Predeploys](protocol/predeploys.md) +- [Glossary](glossary.md) + +### Experimental + +Specifications of new features in active development. + +- [Fault Proof](./experimental/fault-proof/index.md) + - [Dispute Game Interface](./experimental/fault-proof/dispute-game-interface.md) + - [Fault Dispute Game](./experimental/fault-proof/fault-dispute-game.md) + - [Honest Challenger Behavior](./experimental/fault-proof/honest-challenger-fdg.md) + - [Cannon VM](./experimental/fault-proof/cannon-fault-proof-vm.md) + +## Design Goals + +Our aim is to design a protocol specification that is: + +- **Fast:** When users send transactions, they get reliable confirmations with low-latency. + For example when swapping on Uniswap you should see that your transaction succeed in less than 2 + seconds. +- **Scalable:** It should be possible to handle an enormous number of transactions + per second which will enable the system to charge low fees. + V1.0 will enable Optimism to scale up to and even past the gas limit on L1. + Later iterations should scale much further. +- **Modular:** Our designs will use modularity to reduce complexity and enable parallel + contributions. Coming up with good conceptual frameworks & composable atoms of software enables us + to build extremely complex software even when any one person cannot hold that much in their brain. +- **Minimal:** Rollups should be minimal to best take advantage of the battle-tested infrastructure + (like Geth) that already runs Ethereum. An ideal optimistic rollup design should be representable + as a _diff_ against Ethereum client software. +- **Developer Driven:** Our designs will be developer driven to ensure we are actually building + something that people want to use. We must constantly engage with the developers who will be using + our software to avoid creating a system no one wants to use. +- **Clear and Readable:** The specs we write are written to be read. So tight feedback loop with the + systems team consuming the spec is also key! +- **Secure:** This is self-evident. + User’s assets are at stake. Every component of the system must be incredibly secure. +- **Decentralizable:** Optimism must be designed to avail itself of the security and + censorship-resistant guarantees achieved by a decentralized system. + Currently centralized components of the system should have a clear path towards decentralization. + Already decentralized components of the system should be protected and preserved. diff --git a/specs/assets/attack.png b/specs/static/assets/attack.png similarity index 100% rename from specs/assets/attack.png rename to specs/static/assets/attack.png diff --git a/specs/assets/batch-deriv-chain.svg b/specs/static/assets/batch-deriv-chain.svg similarity index 100% rename from specs/assets/batch-deriv-chain.svg rename to specs/static/assets/batch-deriv-chain.svg diff --git a/specs/assets/batch-deriv-pipeline.svg b/specs/static/assets/batch-deriv-pipeline.svg similarity index 100% rename from specs/assets/batch-deriv-pipeline.svg rename to specs/static/assets/batch-deriv-pipeline.svg diff --git a/specs/assets/challenger_attestation.png b/specs/static/assets/challenger_attestation.png similarity index 100% rename from specs/assets/challenger_attestation.png rename to specs/static/assets/challenger_attestation.png diff --git a/specs/assets/challenger_attestation_dispute_game_created.png b/specs/static/assets/challenger_attestation_dispute_game_created.png similarity index 100% rename from specs/assets/challenger_attestation_dispute_game_created.png rename to specs/static/assets/challenger_attestation_dispute_game_created.png diff --git a/specs/assets/challenger_attestation_output_proposed.png b/specs/static/assets/challenger_attestation_output_proposed.png similarity index 100% rename from specs/assets/challenger_attestation_output_proposed.png rename to specs/static/assets/challenger_attestation_output_proposed.png diff --git a/specs/assets/components.svg b/specs/static/assets/components.svg similarity index 100% rename from specs/assets/components.svg rename to specs/static/assets/components.svg diff --git a/specs/assets/defend.png b/specs/static/assets/defend.png similarity index 100% rename from specs/assets/defend.png rename to specs/static/assets/defend.png diff --git a/specs/assets/derivation-1.svg b/specs/static/assets/derivation-1.svg similarity index 100% rename from specs/assets/derivation-1.svg rename to specs/static/assets/derivation-1.svg diff --git a/specs/assets/derivation-2.svg b/specs/static/assets/derivation-2.svg similarity index 100% rename from specs/assets/derivation-2.svg rename to specs/static/assets/derivation-2.svg diff --git a/specs/assets/derivation-3.svg b/specs/static/assets/derivation-3.svg similarity index 100% rename from specs/assets/derivation-3.svg rename to specs/static/assets/derivation-3.svg diff --git a/specs/assets/engine.svg b/specs/static/assets/engine.svg similarity index 100% rename from specs/assets/engine.svg rename to specs/static/assets/engine.svg diff --git a/specs/assets/fault-proof.svg b/specs/static/assets/fault-proof.svg similarity index 100% rename from specs/assets/fault-proof.svg rename to specs/static/assets/fault-proof.svg diff --git a/specs/assets/network-participants-overview.svg b/specs/static/assets/network-participants-overview.svg similarity index 100% rename from specs/assets/network-participants-overview.svg rename to specs/static/assets/network-participants-overview.svg diff --git a/specs/assets/ob-tree.png b/specs/static/assets/ob-tree.png similarity index 100% rename from specs/assets/ob-tree.png rename to specs/static/assets/ob-tree.png diff --git a/specs/assets/propagation.svg b/specs/static/assets/propagation.svg similarity index 100% rename from specs/assets/propagation.svg rename to specs/static/assets/propagation.svg diff --git a/specs/assets/sequencer-block-gen.svg b/specs/static/assets/sequencer-block-gen.svg similarity index 100% rename from specs/assets/sequencer-block-gen.svg rename to specs/static/assets/sequencer-block-gen.svg diff --git a/specs/assets/sequencer-handling-deposits-and-transactions.svg b/specs/static/assets/sequencer-handling-deposits-and-transactions.svg similarity index 100% rename from specs/assets/sequencer-handling-deposits-and-transactions.svg rename to specs/static/assets/sequencer-handling-deposits-and-transactions.svg diff --git a/specs/assets/user-withdrawing-to-l1.svg b/specs/static/assets/user-withdrawing-to-l1.svg similarity index 100% rename from specs/assets/user-withdrawing-to-l1.svg rename to specs/static/assets/user-withdrawing-to-l1.svg diff --git a/specs/assets/valid-moves.png b/specs/static/assets/valid-moves.png similarity index 100% rename from specs/assets/valid-moves.png rename to specs/static/assets/valid-moves.png diff --git a/specs/assets/verifier-executing-fraud-proof.svg b/specs/static/assets/verifier-executing-fraud-proof.svg similarity index 100% rename from specs/assets/verifier-executing-fraud-proof.svg rename to specs/static/assets/verifier-executing-fraud-proof.svg diff --git a/specs/bytecode/ecotone-gas-price-oracle-deployment.txt b/specs/static/bytecode/ecotone-gas-price-oracle-deployment.txt similarity index 100% rename from specs/bytecode/ecotone-gas-price-oracle-deployment.txt rename to specs/static/bytecode/ecotone-gas-price-oracle-deployment.txt diff --git a/specs/bytecode/ecotone-l1-block-deployment.txt b/specs/static/bytecode/ecotone-l1-block-deployment.txt similarity index 100% rename from specs/bytecode/ecotone-l1-block-deployment.txt rename to specs/static/bytecode/ecotone-l1-block-deployment.txt diff --git a/specs/static/custom.css b/specs/static/custom.css new file mode 100644 index 000000000..0eb07ea20 --- /dev/null +++ b/specs/static/custom.css @@ -0,0 +1,27 @@ +kbd { + --kbd-color-background: rgb(247, 247, 247); + --kbd-color-border: #cbcccd; + --kbd-color-text: rgb(34, 35, 37); + + background-color: var(--kbd-color-background); + color: var(--kbd-color-text); + + border-radius: 0.25rem; + + border: 1px solid var(--kbd-color-border); + + box-shadow: 0 2px 0 1px var(--kbd-color-border); + + cursor: default; + + font-size: 0.75em; + + line-height: 1; + + text-align: center; + + padding: 2px 5px; + + position: relative; + top: -1px; +} diff --git a/specs/static/mermaid-init.js b/specs/static/mermaid-init.js new file mode 100644 index 000000000..313a6e8bc --- /dev/null +++ b/specs/static/mermaid-init.js @@ -0,0 +1 @@ +mermaid.initialize({startOnLoad:true}); diff --git a/specs/static/mermaid.min.js b/specs/static/mermaid.min.js new file mode 100644 index 000000000..8c7ea4e4e --- /dev/null +++ b/specs/static/mermaid.min.js @@ -0,0 +1,1282 @@ +/* MIT Licensed. Copyright (c) 2014 - 2022 Knut Sveidqvist */ +/* For license information please see https://github.com/mermaid-js/mermaid/blob/v9.2.2/LICENSE */ +(function(jr,wn){typeof exports=="object"&&typeof module<"u"?module.exports=wn():typeof define=="function"&&define.amd?define(wn):(jr=typeof globalThis<"u"?globalThis:jr||self,jr.mermaid=wn())})(this,function(){"use strict";var Ost=Object.defineProperty;var Fst=(jr,wn,fn)=>wn in jr?Ost(jr,wn,{enumerable:!0,configurable:!0,writable:!0,value:fn}):jr[wn]=fn;var vl=(jr,wn,fn)=>(Fst(jr,typeof wn!="symbol"?wn+"":wn,fn),fn);var jr=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{};function wn(t){var e=t.default;if(typeof e=="function"){var r=function(){return e.apply(this,arguments)};r.prototype=e.prototype}else r={};return Object.defineProperty(r,"__esModule",{value:!0}),Object.keys(t).forEach(function(n){var i=Object.getOwnPropertyDescriptor(t,n);Object.defineProperty(r,n,i.get?i:{enumerable:!0,get:function(){return t[n]}})}),r}function fn(t){throw new Error('Could not dynamically require "'+t+'". Please configure the dynamicRequireTargets or/and ignoreDynamicRequires option of @rollup/plugin-commonjs appropriately for this require call to work.')}var y_={exports:{}};(function(t,e){(function(r,n){t.exports=n()})(jr,function(){var r;function n(){return r.apply(null,arguments)}function i(g){return g instanceof Array||Object.prototype.toString.call(g)==="[object Array]"}function a(g){return g!=null&&Object.prototype.toString.call(g)==="[object Object]"}function s(g,E){return Object.prototype.hasOwnProperty.call(g,E)}function o(g){if(Object.getOwnPropertyNames)return Object.getOwnPropertyNames(g).length===0;for(var E in g)if(s(g,E))return;return 1}function l(g){return g===void 0}function u(g){return typeof g=="number"||Object.prototype.toString.call(g)==="[object Number]"}function h(g){return g instanceof Date||Object.prototype.toString.call(g)==="[object Date]"}function d(g,E){for(var I=[],O=g.length,G=0;G>>0,O=0;Oue(g)?(ht=g+1,xt-ue(g)):(ht=g,xt);return{year:ht,dayOfYear:Mt}}function Ke(g,E,I){var O,G,ht=Ie(g.year(),E,I),ht=Math.floor((g.dayOfYear()-ht-1)/7)+1;return ht<1?O=ht+wr(G=g.year()-1,E,I):ht>wr(g.year(),E,I)?(O=ht-wr(g.year(),E,I),G=g.year()+1):(G=g.year(),O=ht),{week:O,year:G}}function wr(g,G,I){var O=Ie(g,G,I),G=Ie(g+1,G,I);return(ue(g)-O+G)/7}Y("w",["ww",2],"wo","week"),Y("W",["WW",2],"Wo","isoWeek"),W("week","w"),W("isoWeek","W"),Z("week",5),Z("isoWeek",5),ft("w",at),ft("ww",at,fe),ft("W",at),ft("WW",at,fe),we(["w","ww","W","WW"],function(g,E,I,O){E[O.substr(0,1)]=q(g)});function Ge(g,E){return g.slice(E,7).concat(g.slice(0,E))}Y("d",0,"do","day"),Y("dd",0,0,function(g){return this.localeData().weekdaysMin(this,g)}),Y("ddd",0,0,function(g){return this.localeData().weekdaysShort(this,g)}),Y("dddd",0,0,function(g){return this.localeData().weekdays(this,g)}),Y("e",0,0,"weekday"),Y("E",0,0,"isoWeekday"),W("day","d"),W("weekday","e"),W("isoWeekday","E"),Z("day",11),Z("weekday",11),Z("isoWeekday",11),ft("d",at),ft("e",at),ft("E",at),ft("dd",function(g,E){return E.weekdaysMinRegex(g)}),ft("ddd",function(g,E){return E.weekdaysShortRegex(g)}),ft("dddd",function(g,E){return E.weekdaysRegex(g)}),we(["dd","ddd","dddd"],function(g,E,I,O){O=I._locale.weekdaysParse(g,O,I._strict),O!=null?E.d=O:m(I).invalidWeekday=g}),we(["d","e","E"],function(g,E,I,O){E[O]=q(g)});var Ze="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),qt="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),st="Su_Mo_Tu_We_Th_Fr_Sa".split("_"),At=Tt,Nt=Tt,Jt=Tt;function ze(){function g(Ot,de){return de.length-Ot.length}for(var E,I,O,G=[],ht=[],xt=[],Mt=[],Vt=0;Vt<7;Vt++)O=p([2e3,1]).day(Vt),E=Dt(this.weekdaysMin(O,"")),I=Dt(this.weekdaysShort(O,"")),O=Dt(this.weekdays(O,"")),G.push(E),ht.push(I),xt.push(O),Mt.push(E),Mt.push(I),Mt.push(O);G.sort(g),ht.sort(g),xt.sort(g),Mt.sort(g),this._weekdaysRegex=new RegExp("^("+Mt.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+xt.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+ht.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+G.join("|")+")","i")}function Pe(){return this.hours()%12||12}function qe(g,E){Y(g,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),E)})}function Tr(g,E){return E._meridiemParse}Y("H",["HH",2],0,"hour"),Y("h",["hh",2],0,Pe),Y("k",["kk",2],0,function(){return this.hours()||24}),Y("hmm",0,0,function(){return""+Pe.apply(this)+N(this.minutes(),2)}),Y("hmmss",0,0,function(){return""+Pe.apply(this)+N(this.minutes(),2)+N(this.seconds(),2)}),Y("Hmm",0,0,function(){return""+this.hours()+N(this.minutes(),2)}),Y("Hmmss",0,0,function(){return""+this.hours()+N(this.minutes(),2)+N(this.seconds(),2)}),qe("a",!0),qe("A",!1),W("hour","h"),Z("hour",13),ft("a",Tr),ft("A",Tr),ft("H",at),ft("h",at),ft("k",at),ft("HH",at,fe),ft("hh",at,fe),ft("kk",at,fe),ft("hmm",It),ft("hmmss",Lt),ft("Hmm",It),ft("Hmmss",Lt),Qt(["H","HH"],bt),Qt(["k","kk"],function(g,E,I){g=q(g),E[bt]=g===24?0:g}),Qt(["a","A"],function(g,E,I){I._isPm=I._locale.isPM(g),I._meridiem=g}),Qt(["h","hh"],function(g,E,I){E[bt]=q(g),m(I).bigHour=!0}),Qt("hmm",function(g,E,I){var O=g.length-2;E[bt]=q(g.substr(0,O)),E[Et]=q(g.substr(O)),m(I).bigHour=!0}),Qt("hmmss",function(g,E,I){var O=g.length-4,G=g.length-2;E[bt]=q(g.substr(0,O)),E[Et]=q(g.substr(O,2)),E[kt]=q(g.substr(G)),m(I).bigHour=!0}),Qt("Hmm",function(g,E,I){var O=g.length-2;E[bt]=q(g.substr(0,O)),E[Et]=q(g.substr(O))}),Qt("Hmmss",function(g,E,I){var O=g.length-4,G=g.length-2;E[bt]=q(g.substr(0,O)),E[Et]=q(g.substr(O,2)),E[kt]=q(g.substr(G))}),Tt=U("Hours",!0);var Ve,va={calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},longDateFormat:{LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},invalidDate:"Invalid date",ordinal:"%d",dayOfMonthOrdinalParse:/\d{1,2}/,relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",w:"a week",ww:"%d weeks",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},months:ne,monthsShort:ve,week:{dow:0,doy:6},weekdays:Ze,weekdaysMin:st,weekdaysShort:qt,meridiemParse:/[ap]\.?m?\.?/i},Ce={},Wi={};function E0(g){return g&&g.toLowerCase().replace("_","-")}function _u(g){for(var E,I,O,G,ht=0;ht=E&&function(xt,Mt){for(var Vt=Math.min(xt.length,Mt.length),Ot=0;Ot=E-1)break;E--}ht++}return Ve}function Ln(g){var E;if(Ce[g]===void 0&&!0&&t&&t.exports&&g.match("^[^/\\\\]*$")!=null)try{E=Ve._abbr,fn("./locale/"+g),Xt(E)}catch{Ce[g]=null}return Ce[g]}function Xt(g,E){return g&&((E=l(E)?ce(g):ee(g,E))?Ve=E:typeof console<"u"&&console.warn&&console.warn("Locale "+g+" not found. Did you forget to load it?")),Ve._abbr}function ee(g,E){if(E===null)return delete Ce[g],null;var I,O=va;if(E.abbr=g,Ce[g]!=null)L("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),O=Ce[g]._config;else if(E.parentLocale!=null)if(Ce[E.parentLocale]!=null)O=Ce[E.parentLocale]._config;else{if((I=Ln(E.parentLocale))==null)return Wi[E.parentLocale]||(Wi[E.parentLocale]=[]),Wi[E.parentLocale].push({name:g,config:E}),null;O=I._config}return Ce[g]=new w(B(O,E)),Wi[g]&&Wi[g].forEach(function(G){ee(G.name,G.config)}),Xt(g),Ce[g]}function ce(g){var E;if(!(g=g&&g._locale&&g._locale._abbr?g._locale._abbr:g))return Ve;if(!i(g)){if(E=Ln(g))return E;g=[g]}return _u(g)}function Pt(g){var E=g._a;return E&&m(g).overflow===-2&&(E=E[zt]<0||11yt(E[Ft],E[zt])?wt:E[bt]<0||24wr(ht,Vt,Ot)?m(O)._overflowWeeks=!0:de!=null?m(O)._overflowWeekday=!0:(ie=oe(ht,xt,Mt,Vt,Ot),O._a[Ft]=ie.year,O._dayOfYear=ie.dayOfYear)),g._dayOfYear!=null&&(G=Gi(g._a[Ft],I[Ft]),(g._dayOfYear>ue(G)||g._dayOfYear===0)&&(m(g)._overflowDayOfYear=!0),de=Hr(G,0,g._dayOfYear),g._a[zt]=de.getUTCMonth(),g._a[wt]=de.getUTCDate()),E=0;E<3&&g._a[E]==null;++E)g._a[E]=er[E]=I[E];for(;E<7;E++)g._a[E]=er[E]=g._a[E]==null?E===2?1:0:g._a[E];g._a[bt]===24&&g._a[Et]===0&&g._a[kt]===0&&g._a[Ut]===0&&(g._nextDay=!0,g._a[bt]=0),g._d=(g._useUTC?Hr:_a).apply(null,er),ht=g._useUTC?g._d.getUTCDay():g._d.getDay(),g._tzm!=null&&g._d.setUTCMinutes(g._d.getUTCMinutes()-g._tzm),g._nextDay&&(g._a[bt]=24),g._w&&g._w.d!==void 0&&g._w.d!==ht&&(m(g).weekdayMismatch=!0)}}function vu(g){if(g._f===n.ISO_8601)A0(g);else if(g._f===n.RFC_2822)Hi(g);else{g._a=[],m(g).empty=!0;for(var E,I,O,G,ht,xt=""+g._i,Mt=xt.length,Vt=0,Ot=lt(g._f,g._locale).match(z)||[],de=Ot.length,ie=0;ieg.valueOf():g.valueOf()"}),P.toJSON=function(){return this.isValid()?this.toISOString():null},P.toString=function(){return this.clone().locale("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")},P.unix=function(){return Math.floor(this.valueOf()/1e3)},P.valueOf=function(){return this._d.valueOf()-6e4*(this._offset||0)},P.creationData=function(){return{input:this._i,format:this._f,locale:this._locale,isUTC:this._isUTC,strict:this._strict}},P.eraName=function(){for(var g,E=this.localeData().eras(),I=0,O=E.length;Ithis.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()},P.isLocal=function(){return!!this.isValid()&&!this._isUTC},P.isUtcOffset=function(){return!!this.isValid()&&this._isUTC},P.isUtc=rR,P.isUTC=rR,P.zoneAbbr=function(){return this._isUTC?"UTC":""},P.zoneName=function(){return this._isUTC?"Coordinated Universal Time":""},P.dates=R("dates accessor is deprecated. Use date instead.",ls),P.months=R("months accessor is deprecated. Use month instead",se),P.years=R("years accessor is deprecated. Use year instead",N0),P.zone=R("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",function(g,E){return g!=null?(this.utcOffset(g=typeof g!="string"?-g:g,E),this):-this.utcOffset()}),P.isDSTShifted=R("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",function(){if(!l(this._isDSTShifted))return this._isDSTShifted;var g,E={};return T(E,this),(E=M0(E))._a?(g=(E._isUTC?p:De)(E._a),this._isDSTShifted=this.isValid()&&0{},debug:(...t)=>{},info:(...t)=>{},warn:(...t)=>{},error:(...t)=>{},fatal:(...t)=>{}},D0=function(t="fatal"){let e=ji.fatal;typeof t=="string"?(t=t.toLowerCase(),t in ji&&(e=ji[t])):typeof t=="number"&&(e=t),H.trace=()=>{},H.debug=()=>{},H.info=()=>{},H.warn=()=>{},H.error=()=>{},H.fatal=()=>{},e<=ji.fatal&&(H.fatal=console.error?console.error.bind(console,Nn("FATAL"),"color: orange"):console.log.bind(console,"\x1B[35m",Nn("FATAL"))),e<=ji.error&&(H.error=console.error?console.error.bind(console,Nn("ERROR"),"color: orange"):console.log.bind(console,"\x1B[31m",Nn("ERROR"))),e<=ji.warn&&(H.warn=console.warn?console.warn.bind(console,Nn("WARN"),"color: orange"):console.log.bind(console,"\x1B[33m",Nn("WARN"))),e<=ji.info&&(H.info=console.info?console.info.bind(console,Nn("INFO"),"color: lightblue"):console.log.bind(console,"\x1B[34m",Nn("INFO"))),e<=ji.debug&&(H.debug=console.debug?console.debug.bind(console,Nn("DEBUG"),"color: lightgreen"):console.log.bind(console,"\x1B[32m",Nn("DEBUG"))),e<=ji.trace&&(H.trace=console.debug?console.debug.bind(console,Nn("TRACE"),"color: lightgreen"):console.log.bind(console,"\x1B[32m",Nn("TRACE")))},Nn=t=>`%c${Xn().format("ss.SSS")} : ${t} : `;var O0={};Object.defineProperty(O0,"__esModule",{value:!0});var ki=O0.sanitizeUrl=void 0,bR=/^([^\w]*)(javascript|data|vbscript)/im,_R=/&#(\w+)(^\w|;)?/g,vR=/[\u0000-\u001F\u007F-\u009F\u2000-\u200D\uFEFF]/gim,xR=/^([^:]+):/gm,kR=[".","/"];function wR(t){return kR.indexOf(t[0])>-1}function TR(t){return t.replace(_R,function(e,r){return String.fromCharCode(r)})}function ER(t){var e=TR(t||"").replace(vR,"").trim();if(!e)return"about:blank";if(wR(e))return e;var r=e.match(xR);if(!r)return e;var n=r[0];return bR.test(n)?"about:blank":e}ki=O0.sanitizeUrl=ER;function Qe(t,e){return t==null||e==null?NaN:te?1:t>=e?0:NaN}function m_(t,e){return t==null||e==null?NaN:et?1:e>=t?0:NaN}function ku(t){let e,r,n;t.length!==2?(e=Qe,r=(o,l)=>Qe(t(o),l),n=(o,l)=>t(o)-l):(e=t===Qe||t===m_?t:CR,r=t,n=t);function i(o,l,u=0,h=o.length){if(u>>1;r(o[d],l)<0?u=d+1:h=d}while(u>>1;r(o[d],l)<=0?u=d+1:h=d}while(uu&&n(o[d-1],l)>-n(o[d],l)?d-1:d}return{left:i,center:s,right:a}}function CR(){return 0}function b_(t){return t===null?NaN:+t}function*__(t,e){if(e===void 0)for(let r of t)r!=null&&(r=+r)>=r&&(yield r);else{let r=-1;for(let n of t)(n=e(n,++r,t))!=null&&(n=+n)>=n&&(yield n)}}const v_=ku(Qe),x_=v_.right,SR=v_.left,AR=ku(b_).center,cs=x_;function MR(t,e){if(!((e=+e)>=0))throw new RangeError("invalid r");let r=t.length;if(!((r=Math.floor(r))>=0))throw new RangeError("invalid length");if(!r||!e)return t;const n=F0(e),i=t.slice();return n(t,i,0,r,1),n(i,t,0,r,1),n(t,i,0,r,1),t}const k_=w_(F0),LR=w_(RR);function w_(t){return function(e,r,n=r){if(!((r=+r)>=0))throw new RangeError("invalid rx");if(!((n=+n)>=0))throw new RangeError("invalid ry");let{data:i,width:a,height:s}=e;if(!((a=Math.floor(a))>=0))throw new RangeError("invalid width");if(!((s=Math.floor(s!==void 0?s:i.length/a))>=0))throw new RangeError("invalid height");if(!a||!s||!r&&!n)return e;const o=r&&t(r),l=n&&t(n),u=i.slice();return o&&l?(ro(o,u,i,a,s),ro(o,i,u,a,s),ro(o,u,i,a,s),no(l,i,u,a,s),no(l,u,i,a,s),no(l,i,u,a,s)):o?(ro(o,i,u,a,s),ro(o,u,i,a,s),ro(o,i,u,a,s)):l&&(no(l,i,u,a,s),no(l,u,i,a,s),no(l,i,u,a,s)),e}}function ro(t,e,r,n,i){for(let a=0,s=n*i;a{i<<=2,a<<=2,s<<=2,e(r,n,i+0,a+0,s),e(r,n,i+1,a+1,s),e(r,n,i+2,a+2,s),e(r,n,i+3,a+3,s)}}function F0(t){const e=Math.floor(t);if(e===t)return IR(t);const r=t-e,n=2*t+1;return(i,a,s,o,l)=>{if(!((o-=l)>=s))return;let u=e*a[s];const h=l*e,d=h+l;for(let f=s,p=s+h;f{if(!((a-=s)>=i))return;let o=t*n[i];const l=s*t;for(let u=i,h=i+l;u=n&&++r;else{let n=-1;for(let i of t)(i=e(i,++n,t))!=null&&(i=+i)>=i&&++r}return r}function NR(t){return t.length|0}function BR(t){return!(t>0)}function DR(t){return typeof t!="object"||"length"in t?t:Array.from(t)}function OR(t){return e=>t(...e)}function FR(...t){const e=typeof t[t.length-1]=="function"&&OR(t.pop());t=t.map(DR);const r=t.map(NR),n=t.length-1,i=new Array(n+1).fill(0),a=[];if(n<0||r.some(BR))return a;for(;;){a.push(i.map((o,l)=>t[l][o]));let s=n;for(;++i[s]===r[s];){if(s===0)return e?a.map(e):a;i[s--]=0}}}function PR(t,e){var r=0,n=0;return Float64Array.from(t,e===void 0?i=>r+=+i||0:i=>r+=+e(i,n++,t)||0)}function T_(t,e){let r=0,n,i=0,a=0;if(e===void 0)for(let s of t)s!=null&&(s=+s)>=s&&(n=s-i,i+=n/++r,a+=n*(s-i));else{let s=-1;for(let o of t)(o=e(o,++s,t))!=null&&(o=+o)>=o&&(n=o-i,i+=n/++r,a+=n*(o-i))}if(r>1)return a/(r-1)}function E_(t,e){const r=T_(t,e);return r&&Math.sqrt(r)}function xl(t,e){let r,n;if(e===void 0)for(const i of t)i!=null&&(r===void 0?i>=i&&(r=n=i):(r>i&&(r=i),n=a&&(r=n=a):(r>a&&(r=a),n0){for(s=e[--r];r>0&&(n=s,i=e[--r],s=n+i,a=i-(s-n),!a););r>0&&(a<0&&e[r-1]<0||a>0&&e[r-1]>0)&&(i=a*2,n=s+i,i==n-s&&(s=n))}return s}}function qR(t,e){const r=new _r;if(e===void 0)for(let n of t)(n=+n)&&r.add(n);else{let n=-1;for(let i of t)(i=+e(i,++n,t))&&r.add(i)}return+r}function VR(t,e){const r=new _r;let n=-1;return Float64Array.from(t,e===void 0?i=>r.add(+i||0):i=>r.add(+e(i,++n,t)||0))}class kl extends Map{constructor(e,r=A_){if(super(),Object.defineProperties(this,{_intern:{value:new Map},_key:{value:r}}),e!=null)for(const[n,i]of e)this.set(n,i)}get(e){return super.get(P0(this,e))}has(e){return super.has(P0(this,e))}set(e,r){return super.set(C_(this,e),r)}delete(e){return super.delete(S_(this,e))}}class us extends Set{constructor(e,r=A_){if(super(),Object.defineProperties(this,{_intern:{value:new Map},_key:{value:r}}),e!=null)for(const n of e)this.add(n)}has(e){return super.has(P0(this,e))}add(e){return super.add(C_(this,e))}delete(e){return super.delete(S_(this,e))}}function P0({_intern:t,_key:e},r){const n=e(r);return t.has(n)?t.get(n):r}function C_({_intern:t,_key:e},r){const n=e(r);return t.has(n)?t.get(n):(t.set(n,r),r)}function S_({_intern:t,_key:e},r){const n=e(r);return t.has(n)&&(r=t.get(n),t.delete(n)),r}function A_(t){return t!==null&&typeof t=="object"?t.valueOf():t}function io(t){return t}function M_(t,...e){return ao(t,io,io,e)}function L_(t,...e){return ao(t,Array.from,io,e)}function R_(t,e){for(let r=1,n=e.length;ri.pop().map(([a,s])=>[...i,a,s]));return t}function zR(t,...e){return R_(L_(t,...e),e)}function YR(t,e,...r){return R_(N_(t,e,...r),r)}function I_(t,e,...r){return ao(t,io,e,r)}function N_(t,e,...r){return ao(t,Array.from,e,r)}function UR(t,...e){return ao(t,io,B_,e)}function WR(t,...e){return ao(t,Array.from,B_,e)}function B_(t){if(t.length!==1)throw new Error("duplicate key");return t[0]}function ao(t,e,r,n){return function i(a,s){if(s>=n.length)return r(a);const o=new kl,l=n[s++];let u=-1;for(const h of a){const d=l(h,++u,a),f=o.get(d);f?f.push(h):o.set(d,[h])}for(const[h,d]of o)o.set(h,i(d,s));return e(o)}(t,0)}function D_(t,e){return Array.from(e,r=>t[r])}function q0(t,...e){if(typeof t[Symbol.iterator]!="function")throw new TypeError("values is not iterable");t=Array.from(t);let[r]=e;if(r&&r.length!==2||e.length>1){const n=Uint32Array.from(t,(i,a)=>a);return e.length>1?(e=e.map(i=>t.map(i)),n.sort((i,a)=>{for(const s of e){const o=so(s[i],s[a]);if(o)return o}})):(r=t.map(r),n.sort((i,a)=>so(r[i],r[a]))),D_(t,n)}return t.sort(V0(r))}function V0(t=Qe){if(t===Qe)return so;if(typeof t!="function")throw new TypeError("compare is not a function");return(e,r)=>{const n=t(e,r);return n||n===0?n:(t(r,r)===0)-(t(e,e)===0)}}function so(t,e){return(t==null||!(t>=t))-(e==null||!(e>=e))||(te?1:0)}function HR(t,e,r){return(e.length!==2?q0(I_(t,e,r),([n,i],[a,s])=>Qe(i,s)||Qe(n,a)):q0(M_(t,r),([n,i],[a,s])=>e(i,s)||Qe(n,a))).map(([n])=>n)}var GR=Array.prototype,jR=GR.slice;function Tu(t){return()=>t}var z0=Math.sqrt(50),Y0=Math.sqrt(10),U0=Math.sqrt(2);function hs(t,e,r){var n,i=-1,a,s,o;if(e=+e,t=+t,r=+r,t===e&&r>0)return[t];if((n=e0){let l=Math.round(t/o),u=Math.round(e/o);for(l*oe&&--u,s=new Array(a=u-l+1);++ie&&--u,s=new Array(a=u-l+1);++i=0?(a>=z0?10:a>=Y0?5:a>=U0?2:1)*Math.pow(10,i):-Math.pow(10,-i)/(a>=z0?10:a>=Y0?5:a>=U0?2:1)}function wl(t,e,r){var n=Math.abs(e-t)/Math.max(0,r),i=Math.pow(10,Math.floor(Math.log(n)/Math.LN10)),a=n/i;return a>=z0?i*=10:a>=Y0?i*=5:a>=U0&&(i*=2),e0?(t=Math.floor(t/i)*i,e=Math.ceil(e/i)*i):i<0&&(t=Math.ceil(t*i)/i,e=Math.floor(e*i)/i),n=i}}function W0(t){return Math.ceil(Math.log(wu(t))/Math.LN2)+1}function F_(){var t=io,e=xl,r=W0;function n(i){Array.isArray(i)||(i=Array.from(i));var a,s=i.length,o,l,u=new Array(s);for(a=0;a=f)if(b>=f&&e===xl){const k=oo(d,f,x);isFinite(k)&&(k>0?f=(Math.floor(f/k)+1)*k:k<0&&(f=(Math.ceil(f*-k)+1)/-k))}else p.pop()}for(var m=p.length;p[0]<=d;)p.shift(),--m;for(;p[m-1]>f;)p.pop(),--m;var _=new Array(m+1),y;for(a=0;a<=m;++a)y=_[a]=[],y.x0=a>0?p[a-1]:d,y.x1=a0)for(a=0;a=n)&&(r=n);else{let n=-1;for(let i of t)(i=e(i,++n,t))!=null&&(r=i)&&(r=i)}return r}function H0(t,e){let r,n=-1,i=-1;if(e===void 0)for(const a of t)++i,a!=null&&(r=a)&&(r=a,n=i);else for(let a of t)(a=e(a,++i,t))!=null&&(r=a)&&(r=a,n=i);return n}function Tl(t,e){let r;if(e===void 0)for(const n of t)n!=null&&(r>n||r===void 0&&n>=n)&&(r=n);else{let n=-1;for(let i of t)(i=e(i,++n,t))!=null&&(r>i||r===void 0&&i>=i)&&(r=i)}return r}function G0(t,e){let r,n=-1,i=-1;if(e===void 0)for(const a of t)++i,a!=null&&(r>a||r===void 0&&a>=a)&&(r=a,n=i);else for(let a of t)(a=e(a,++i,t))!=null&&(r>a||r===void 0&&a>=a)&&(r=a,n=i);return n}function Eu(t,e,r=0,n=t.length-1,i){for(i=i===void 0?so:V0(i);n>r;){if(n-r>600){const l=n-r+1,u=e-r+1,h=Math.log(l),d=.5*Math.exp(2*h/3),f=.5*Math.sqrt(h*d*(l-d)/l)*(u-l/2<0?-1:1),p=Math.max(r,Math.floor(e-u*d/l+f)),m=Math.min(n,Math.floor(e+(l-u)*d/l+f));Eu(t,e,p,m,i)}const a=t[e];let s=r,o=n;for(El(t,r,e),i(t[n],a)>0&&El(t,r,n);s0;)--o}i(t[r],a)===0?El(t,r,o):(++o,El(t,o,n)),o<=e&&(r=o+1),e<=o&&(n=o-1)}return t}function El(t,e,r){const n=t[e];t[e]=t[r],t[r]=n}function P_(t,e=Qe){let r,n=!1;if(e.length===1){let i;for(const a of t){const s=e(a);(n?Qe(s,i)>0:Qe(s,s)===0)&&(r=a,i=s,n=!0)}}else for(const i of t)(n?e(i,r)>0:e(i,i)===0)&&(r=i,n=!0);return r}function Cl(t,e,r){if(t=Float64Array.from(__(t,r)),!!(n=t.length)){if((e=+e)<=0||n<2)return Tl(t);if(e>=1)return lo(t);var n,i=(n-1)*e,a=Math.floor(i),s=lo(Eu(t,a).subarray(0,a+1)),o=Tl(t.subarray(a+1));return s+(o-s)*(i-a)}}function q_(t,e,r=b_){if(!!(n=t.length)){if((e=+e)<=0||n<2)return+r(t[0],0,t);if(e>=1)return+r(t[n-1],n-1,t);var n,i=(n-1)*e,a=Math.floor(i),s=+r(t[a],a,t),o=+r(t[a+1],a+1,t);return s+(o-s)*(i-a)}}function V_(t,e,r){if(t=Float64Array.from(__(t,r)),!!(n=t.length)){if((e=+e)<=0||n<2)return G0(t);if(e>=1)return H0(t);var n,i=Math.floor((n-1)*e),a=(o,l)=>so(t[o],t[l]),s=Eu(Uint32Array.from(t,(o,l)=>l),i,0,n-1,a);return P_(s.subarray(0,i+1),o=>t[o])}}function $R(t,e,r){return Math.ceil((r-e)/(2*(Cl(t,.75)-Cl(t,.25))*Math.pow(wu(t),-1/3)))}function XR(t,e,r){return Math.ceil((r-e)*Math.cbrt(wu(t))/(3.49*E_(t)))}function KR(t,e){let r=0,n=0;if(e===void 0)for(let i of t)i!=null&&(i=+i)>=i&&(++r,n+=i);else{let i=-1;for(let a of t)(a=e(a,++i,t))!=null&&(a=+a)>=a&&(++r,n+=a)}if(r)return n/r}function ZR(t,e){return Cl(t,.5,e)}function QR(t,e){return V_(t,.5,e)}function*JR(t){for(const e of t)yield*e}function j0(t){return Array.from(JR(t))}function tI(t,e){const r=new kl;if(e===void 0)for(let a of t)a!=null&&a>=a&&r.set(a,(r.get(a)||0)+1);else{let a=-1;for(let s of t)(s=e(s,++a,t))!=null&&s>=s&&r.set(s,(r.get(s)||0)+1)}let n,i=0;for(const[a,s]of r)s>i&&(i=s,n=a);return n}function eI(t,e=rI){const r=[];let n,i=!1;for(const a of t)i&&r.push(e(n,a)),n=a,i=!0;return r}function rI(t,e){return[t,e]}function Ca(t,e,r){t=+t,e=+e,r=(i=arguments.length)<2?(e=t,t=0,1):i<3?1:+r;for(var n=-1,i=Math.max(0,Math.ceil((e-t)/r))|0,a=new Array(i);++ne(r[o],r[l]);let a,s;return Uint32Array.from(r,(o,l)=>l).sort(e===Qe?(o,l)=>so(r[o],r[l]):V0(i)).forEach((o,l)=>{const u=i(o,a===void 0?o:a);u>=0?((a===void 0||u>0)&&(a=o,s=l),n[o]=s):n[o]=NaN}),n}function iI(t,e=Qe){let r,n=!1;if(e.length===1){let i;for(const a of t){const s=e(a);(n?Qe(s,i)<0:Qe(s,s)===0)&&(r=a,i=s,n=!0)}}else for(const i of t)(n?e(i,r)<0:e(i,i)===0)&&(r=i,n=!0);return r}function z_(t,e=Qe){if(e.length===1)return G0(t,e);let r,n=-1,i=-1;for(const a of t)++i,(n<0?e(a,a)===0:e(a,r)<0)&&(r=a,n=i);return n}function aI(t,e=Qe){if(e.length===1)return H0(t,e);let r,n=-1,i=-1;for(const a of t)++i,(n<0?e(a,a)===0:e(a,r)>0)&&(r=a,n=i);return n}function sI(t,e){const r=z_(t,e);return r<0?void 0:r}const oI=Y_(Math.random);function Y_(t){return function(r,n=0,i=r.length){let a=i-(n=+n);for(;a;){const s=t()*a--|0,o=r[a+n];r[a+n]=r[s+n],r[s+n]=o}return r}}function lI(t,e){let r=0;if(e===void 0)for(let n of t)(n=+n)&&(r+=n);else{let n=-1;for(let i of t)(i=+e(i,++n,t))&&(r+=i)}return r}function U_(t){if(!(a=t.length))return[];for(var e=-1,r=Tl(t,cI),n=new Array(r);++ee(r,n,t))}function gI(t,e,r){if(typeof e!="function")throw new TypeError("reducer is not a function");const n=t[Symbol.iterator]();let i,a,s=-1;if(arguments.length<3){if({done:i,value:r}=n.next(),i)return;++s}for(;{done:i,value:a}=n.next(),!i;)r=e(r,a,++s,t);return r}function yI(t){if(typeof t[Symbol.iterator]!="function")throw new TypeError("values is not iterable");return Array.from(t).reverse()}function mI(t,...e){t=new us(t);for(const r of e)for(const n of r)t.delete(n);return t}function bI(t,e){const r=e[Symbol.iterator](),n=new us;for(const i of t){if(n.has(i))return!1;let a,s;for(;({value:a,done:s}=r.next())&&!s;){if(Object.is(i,a))return!1;n.add(a)}}return!0}function _I(t,...e){t=new us(t),e=e.map(vI);t:for(const r of t)for(const n of e)if(!n.has(r)){t.delete(r);continue t}return t}function vI(t){return t instanceof us?t:new us(t)}function W_(t,e){const r=t[Symbol.iterator](),n=new Set;for(const i of e){const a=H_(i);if(n.has(a))continue;let s,o;for(;{value:s,done:o}=r.next();){if(o)return!1;const l=H_(s);if(n.add(l),Object.is(a,l))break}}return!0}function H_(t){return t!==null&&typeof t=="object"?t.valueOf():t}function xI(t,e){return W_(e,t)}function kI(...t){const e=new us;for(const r of t)for(const n of r)e.add(n);return e}function wI(t){return t}var Cu=1,Su=2,$0=3,Sl=4,G_=1e-6;function TI(t){return"translate("+t+",0)"}function EI(t){return"translate(0,"+t+")"}function CI(t){return e=>+t(e)}function SI(t,e){return e=Math.max(0,t.bandwidth()-e*2)/2,t.round()&&(e=Math.round(e)),r=>+t(r)+e}function AI(){return!this.__axis}function Au(t,e){var r=[],n=null,i=null,a=6,s=6,o=3,l=typeof window<"u"&&window.devicePixelRatio>1?0:.5,u=t===Cu||t===Sl?-1:1,h=t===Sl||t===Su?"x":"y",d=t===Cu||t===$0?TI:EI;function f(p){var m=n==null?e.ticks?e.ticks.apply(e,r):e.domain():n,_=i==null?e.tickFormat?e.tickFormat.apply(e,r):wI:i,y=Math.max(a,0)+o,b=e.range(),x=+b[0]+l,k=+b[b.length-1]+l,T=(e.bandwidth?SI:CI)(e.copy(),l),C=p.selection?p.selection():p,M=C.selectAll(".domain").data([null]),S=C.selectAll(".tick").data(m,e).order(),R=S.exit(),A=S.enter().append("g").attr("class","tick"),L=S.select("line"),v=S.select("text");M=M.merge(M.enter().insert("path",".tick").attr("class","domain").attr("stroke","currentColor")),S=S.merge(A),L=L.merge(A.append("line").attr("stroke","currentColor").attr(h+"2",u*a)),v=v.merge(A.append("text").attr("fill","currentColor").attr(h,u*y).attr("dy",t===Cu?"0em":t===$0?"0.71em":"0.32em")),p!==C&&(M=M.transition(p),S=S.transition(p),L=L.transition(p),v=v.transition(p),R=R.transition(p).attr("opacity",G_).attr("transform",function(B){return isFinite(B=T(B))?d(B+l):this.getAttribute("transform")}),A.attr("opacity",G_).attr("transform",function(B){var w=this.parentNode.__axis;return d((w&&isFinite(w=w(B))?w:T(B))+l)})),R.remove(),M.attr("d",t===Sl||t===Su?s?"M"+u*s+","+x+"H"+l+"V"+k+"H"+u*s:"M"+l+","+x+"V"+k:s?"M"+x+","+u*s+"V"+l+"H"+k+"V"+u*s:"M"+x+","+l+"H"+k),S.attr("opacity",1).attr("transform",function(B){return d(T(B)+l)}),L.attr(h+"2",u*a),v.attr(h,u*y).text(_),C.filter(AI).attr("fill","none").attr("font-size",10).attr("font-family","sans-serif").attr("text-anchor",t===Su?"start":t===Sl?"end":"middle"),C.each(function(){this.__axis=T})}return f.scale=function(p){return arguments.length?(e=p,f):e},f.ticks=function(){return r=Array.from(arguments),f},f.tickArguments=function(p){return arguments.length?(r=p==null?[]:Array.from(p),f):r.slice()},f.tickValues=function(p){return arguments.length?(n=p==null?null:Array.from(p),f):n&&n.slice()},f.tickFormat=function(p){return arguments.length?(i=p,f):i},f.tickSize=function(p){return arguments.length?(a=s=+p,f):a},f.tickSizeInner=function(p){return arguments.length?(a=+p,f):a},f.tickSizeOuter=function(p){return arguments.length?(s=+p,f):s},f.tickPadding=function(p){return arguments.length?(o=+p,f):o},f.offset=function(p){return arguments.length?(l=+p,f):l},f}function j_(t){return Au(Cu,t)}function MI(t){return Au(Su,t)}function $_(t){return Au($0,t)}function LI(t){return Au(Sl,t)}var RI={value:()=>{}};function fs(){for(var t=0,e=arguments.length,r={},n;t=0&&(n=r.slice(i+1),r=r.slice(0,i)),r&&!e.hasOwnProperty(r))throw new Error("unknown type: "+r);return{type:r,name:n}})}Mu.prototype=fs.prototype={constructor:Mu,on:function(t,e){var r=this._,n=II(t+"",r),i,a=-1,s=n.length;if(arguments.length<2){for(;++a0)for(var r=new Array(i),n=0,i,a;n=0&&(e=t.slice(0,r))!=="xmlns"&&(t=t.slice(r+1)),K0.hasOwnProperty(e)?{space:K0[e],local:t}:t}function BI(t){return function(){var e=this.ownerDocument,r=this.namespaceURI;return r===X0&&e.documentElement.namespaceURI===X0?e.createElement(t):e.createElementNS(r,t)}}function DI(t){return function(){return this.ownerDocument.createElementNS(t.space,t.local)}}function Lu(t){var e=Al(t);return(e.local?DI:BI)(e)}function OI(){}function Ru(t){return t==null?OI:function(){return this.querySelector(t)}}function FI(t){typeof t!="function"&&(t=Ru(t));for(var e=this._groups,r=e.length,n=new Array(r),i=0;i=k&&(k=x+1);!(C=y[k])&&++k=0;)(s=n[i])&&(a&&s.compareDocumentPosition(a)^4&&a.parentNode.insertBefore(s,a),a=s);return this}function oN(t){t||(t=lN);function e(d,f){return d&&f?t(d.__data__,f.__data__):!d-!f}for(var r=this._groups,n=r.length,i=new Array(n),a=0;ae?1:t>=e?0:NaN}function cN(){var t=arguments[0];return arguments[0]=this,t.apply(null,arguments),this}function uN(){return Array.from(this)}function hN(){for(var t=this._groups,e=0,r=t.length;e1?this.each((e==null?kN:typeof e=="function"?TN:wN)(t,e,r==null?"":r)):ds(this.node(),t)}function ds(t,e){return t.style.getPropertyValue(e)||J0(t).getComputedStyle(t,null).getPropertyValue(e)}function CN(t){return function(){delete this[t]}}function SN(t,e){return function(){this[t]=e}}function AN(t,e){return function(){var r=e.apply(this,arguments);r==null?delete this[t]:this[t]=r}}function MN(t,e){return arguments.length>1?this.each((e==null?CN:typeof e=="function"?AN:SN)(t,e)):this.node()[t]}function J_(t){return t.trim().split(/^|\s+/)}function td(t){return t.classList||new t5(t)}function t5(t){this._node=t,this._names=J_(t.getAttribute("class")||"")}t5.prototype={add:function(t){var e=this._names.indexOf(t);e<0&&(this._names.push(t),this._node.setAttribute("class",this._names.join(" ")))},remove:function(t){var e=this._names.indexOf(t);e>=0&&(this._names.splice(e,1),this._node.setAttribute("class",this._names.join(" ")))},contains:function(t){return this._names.indexOf(t)>=0}};function e5(t,e){for(var r=td(t),n=-1,i=e.length;++n=0&&(r=e.slice(n+1),e=e.slice(0,n)),{type:e,name:r}})}function nB(t){return function(){var e=this.__on;if(!!e){for(var r=0,n=-1,i=e.length,a;rTn(r,e))}function Nu(t){return typeof t=="string"?new $r([document.querySelectorAll(t)],[document.documentElement]):new $r([K_(t)],ed)}const pB={passive:!1},Ml={capture:!0,passive:!1};function nd(t){t.stopImmediatePropagation()}function co(t){t.preventDefault(),t.stopImmediatePropagation()}function Bu(t){var e=t.document.documentElement,r=St(t).on("dragstart.drag",co,Ml);"onselectstart"in e?r.on("selectstart.drag",co,Ml):(e.__noselect=e.style.MozUserSelect,e.style.MozUserSelect="none")}function Du(t,e){var r=t.document.documentElement,n=St(t).on("dragstart.drag",null);e&&(n.on("click.drag",co,Ml),setTimeout(function(){n.on("click.drag",null)},0)),"onselectstart"in r?n.on("selectstart.drag",null):(r.style.MozUserSelect=r.__noselect,delete r.__noselect)}const Ou=t=>()=>t;function id(t,{sourceEvent:e,subject:r,target:n,identifier:i,active:a,x:s,y:o,dx:l,dy:u,dispatch:h}){Object.defineProperties(this,{type:{value:t,enumerable:!0,configurable:!0},sourceEvent:{value:e,enumerable:!0,configurable:!0},subject:{value:r,enumerable:!0,configurable:!0},target:{value:n,enumerable:!0,configurable:!0},identifier:{value:i,enumerable:!0,configurable:!0},active:{value:a,enumerable:!0,configurable:!0},x:{value:s,enumerable:!0,configurable:!0},y:{value:o,enumerable:!0,configurable:!0},dx:{value:l,enumerable:!0,configurable:!0},dy:{value:u,enumerable:!0,configurable:!0},_:{value:h}})}id.prototype.on=function(){var t=this._.on.apply(this._,arguments);return t===this._?this:t};function gB(t){return!t.ctrlKey&&!t.button}function yB(){return this.parentNode}function mB(t,e){return e==null?{x:t.x,y:t.y}:e}function bB(){return navigator.maxTouchPoints||"ontouchstart"in this}function _B(){var t=gB,e=yB,r=mB,n=bB,i={},a=fs("start","drag","end"),s=0,o,l,u,h,d=0;function f(T){T.on("mousedown.drag",p).filter(n).on("touchstart.drag",y).on("touchmove.drag",b,pB).on("touchend.drag touchcancel.drag",x).style("touch-action","none").style("-webkit-tap-highlight-color","rgba(0,0,0,0)")}function p(T,C){if(!(h||!t.call(this,T,C))){var M=k(this,e.call(this,T,C),T,C,"mouse");!M||(St(T.view).on("mousemove.drag",m,Ml).on("mouseup.drag",_,Ml),Bu(T.view),nd(T),u=!1,o=T.clientX,l=T.clientY,M("start",T))}}function m(T){if(co(T),!u){var C=T.clientX-o,M=T.clientY-l;u=C*C+M*M>d}i.mouse("drag",T)}function _(T){St(T.view).on("mousemove.drag mouseup.drag",null),Du(T.view,u),co(T),i.mouse("end",T)}function y(T,C){if(!!t.call(this,T,C)){var M=T.changedTouches,S=e.call(this,T,C),R=M.length,A,L;for(A=0;A>8&15|e>>4&240,e>>4&15|e&240,(e&15)<<4|e&15,1):r===8?Fu(e>>24&255,e>>16&255,e>>8&255,(e&255)/255):r===4?Fu(e>>12&15|e>>8&240,e>>8&15|e>>4&240,e>>4&15|e&240,((e&15)<<4|e&15)/255):null):(e=xB.exec(t))?new Er(e[1],e[2],e[3],1):(e=kB.exec(t))?new Er(e[1]*255/100,e[2]*255/100,e[3]*255/100,1):(e=wB.exec(t))?Fu(e[1],e[2],e[3],e[4]):(e=TB.exec(t))?Fu(e[1]*255/100,e[2]*255/100,e[3]*255/100,e[4]):(e=EB.exec(t))?f5(e[1],e[2]/100,e[3]/100,1):(e=CB.exec(t))?f5(e[1],e[2]/100,e[3]/100,e[4]):s5.hasOwnProperty(t)?c5(s5[t]):t==="transparent"?new Er(NaN,NaN,NaN,0):null}function c5(t){return new Er(t>>16&255,t>>8&255,t&255,1)}function Fu(t,e,r,n){return n<=0&&(t=e=r=NaN),new Er(t,e,r,n)}function ad(t){return t instanceof Sa||(t=Aa(t)),t?(t=t.rgb(),new Er(t.r,t.g,t.b,t.opacity)):new Er}function po(t,e,r,n){return arguments.length===1?ad(t):new Er(t,e,r,n==null?1:n)}function Er(t,e,r,n){this.r=+t,this.g=+e,this.b=+r,this.opacity=+n}uo(Er,po,Ll(Sa,{brighter(t){return t=t==null?ho:Math.pow(ho,t),new Er(this.r*t,this.g*t,this.b*t,this.opacity)},darker(t){return t=t==null?gs:Math.pow(gs,t),new Er(this.r*t,this.g*t,this.b*t,this.opacity)},rgb(){return this},clamp(){return new Er(ys(this.r),ys(this.g),ys(this.b),Pu(this.opacity))},displayable(){return-.5<=this.r&&this.r<255.5&&-.5<=this.g&&this.g<255.5&&-.5<=this.b&&this.b<255.5&&0<=this.opacity&&this.opacity<=1},hex:u5,formatHex:u5,formatHex8:MB,formatRgb:h5,toString:h5}));function u5(){return`#${ms(this.r)}${ms(this.g)}${ms(this.b)}`}function MB(){return`#${ms(this.r)}${ms(this.g)}${ms(this.b)}${ms((isNaN(this.opacity)?1:this.opacity)*255)}`}function h5(){const t=Pu(this.opacity);return`${t===1?"rgb(":"rgba("}${ys(this.r)}, ${ys(this.g)}, ${ys(this.b)}${t===1?")":`, ${t})`}`}function Pu(t){return isNaN(t)?1:Math.max(0,Math.min(1,t))}function ys(t){return Math.max(0,Math.min(255,Math.round(t)||0))}function ms(t){return t=ys(t),(t<16?"0":"")+t.toString(16)}function f5(t,e,r,n){return n<=0?t=e=r=NaN:r<=0||r>=1?t=e=NaN:e<=0&&(t=NaN),new Kn(t,e,r,n)}function d5(t){if(t instanceof Kn)return new Kn(t.h,t.s,t.l,t.opacity);if(t instanceof Sa||(t=Aa(t)),!t)return new Kn;if(t instanceof Kn)return t;t=t.rgb();var e=t.r/255,r=t.g/255,n=t.b/255,i=Math.min(e,r,n),a=Math.max(e,r,n),s=NaN,o=a-i,l=(a+i)/2;return o?(e===a?s=(r-n)/o+(r0&&l<1?0:s,new Kn(s,o,l,t.opacity)}function qu(t,e,r,n){return arguments.length===1?d5(t):new Kn(t,e,r,n==null?1:n)}function Kn(t,e,r,n){this.h=+t,this.s=+e,this.l=+r,this.opacity=+n}uo(Kn,qu,Ll(Sa,{brighter(t){return t=t==null?ho:Math.pow(ho,t),new Kn(this.h,this.s,this.l*t,this.opacity)},darker(t){return t=t==null?gs:Math.pow(gs,t),new Kn(this.h,this.s,this.l*t,this.opacity)},rgb(){var t=this.h%360+(this.h<0)*360,e=isNaN(t)||isNaN(this.s)?0:this.s,r=this.l,n=r+(r<.5?r:1-r)*e,i=2*r-n;return new Er(sd(t>=240?t-240:t+120,i,n),sd(t,i,n),sd(t<120?t+240:t-120,i,n),this.opacity)},clamp(){return new Kn(p5(this.h),Vu(this.s),Vu(this.l),Pu(this.opacity))},displayable(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1},formatHsl(){const t=Pu(this.opacity);return`${t===1?"hsl(":"hsla("}${p5(this.h)}, ${Vu(this.s)*100}%, ${Vu(this.l)*100}%${t===1?")":`, ${t})`}`}}));function p5(t){return t=(t||0)%360,t<0?t+360:t}function Vu(t){return Math.max(0,Math.min(1,t||0))}function sd(t,e,r){return(t<60?e+(r-e)*t/60:t<180?r:t<240?e+(r-e)*(240-t)/60:e)*255}const g5=Math.PI/180,y5=180/Math.PI,zu=18,m5=.96422,b5=1,_5=.82521,v5=4/29,go=6/29,x5=3*go*go,LB=go*go*go;function k5(t){if(t instanceof Zn)return new Zn(t.l,t.a,t.b,t.opacity);if(t instanceof Ti)return T5(t);t instanceof Er||(t=ad(t));var e=ud(t.r),r=ud(t.g),n=ud(t.b),i=od((.2225045*e+.7168786*r+.0606169*n)/b5),a,s;return e===r&&r===n?a=s=i:(a=od((.4360747*e+.3850649*r+.1430804*n)/m5),s=od((.0139322*e+.0971045*r+.7141733*n)/_5)),new Zn(116*i-16,500*(a-i),200*(i-s),t.opacity)}function RB(t,e){return new Zn(t,0,0,e==null?1:e)}function Yu(t,e,r,n){return arguments.length===1?k5(t):new Zn(t,e,r,n==null?1:n)}function Zn(t,e,r,n){this.l=+t,this.a=+e,this.b=+r,this.opacity=+n}uo(Zn,Yu,Ll(Sa,{brighter(t){return new Zn(this.l+zu*(t==null?1:t),this.a,this.b,this.opacity)},darker(t){return new Zn(this.l-zu*(t==null?1:t),this.a,this.b,this.opacity)},rgb(){var t=(this.l+16)/116,e=isNaN(this.a)?t:t+this.a/500,r=isNaN(this.b)?t:t-this.b/200;return e=m5*ld(e),t=b5*ld(t),r=_5*ld(r),new Er(cd(3.1338561*e-1.6168667*t-.4906146*r),cd(-.9787684*e+1.9161415*t+.033454*r),cd(.0719453*e-.2289914*t+1.4052427*r),this.opacity)}}));function od(t){return t>LB?Math.pow(t,1/3):t/x5+v5}function ld(t){return t>go?t*t*t:x5*(t-v5)}function cd(t){return 255*(t<=.0031308?12.92*t:1.055*Math.pow(t,1/2.4)-.055)}function ud(t){return(t/=255)<=.04045?t/12.92:Math.pow((t+.055)/1.055,2.4)}function w5(t){if(t instanceof Ti)return new Ti(t.h,t.c,t.l,t.opacity);if(t instanceof Zn||(t=k5(t)),t.a===0&&t.b===0)return new Ti(NaN,0=1?(r=1,e-1):Math.floor(r*e),i=t[n],a=t[n+1],s=n>0?t[n-1]:2*i-a,o=n()=>t;function I5(t,e){return function(r){return t+r*e}}function BB(t,e,r){return t=Math.pow(t,r),e=Math.pow(e,r)-t,r=1/r,function(n){return Math.pow(t+n*e,r)}}function Gu(t,e){var r=e-t;return r?I5(t,r>180||r<-180?r-360*Math.round(r/360):r):Hu(isNaN(t)?e:t)}function DB(t){return(t=+t)==1?Cr:function(e,r){return r-e?BB(e,r,t):Hu(isNaN(e)?r:e)}}function Cr(t,e){var r=e-t;return r?I5(t,r):Hu(isNaN(t)?e:t)}const Nl=function t(e){var r=DB(e);function n(i,a){var s=r((i=po(i)).r,(a=po(a)).r),o=r(i.g,a.g),l=r(i.b,a.b),u=Cr(i.opacity,a.opacity);return function(h){return i.r=s(h),i.g=o(h),i.b=l(h),i.opacity=u(h),i+""}}return n.gamma=t,n}(1);function N5(t){return function(e){var r=e.length,n=new Array(r),i=new Array(r),a=new Array(r),s,o;for(s=0;sr&&(a=e.slice(r,a),o[s]?o[s]+=a:o[++s]=a),(n=n[0])===(i=i[0])?o[s]?o[s]+=i:o[++s]=i:(o[++s]=null,l.push({i:s,x:Bn(n,i)})),r=gd.lastIndex;return r180?h+=360:h-u>180&&(u+=360),f.push({i:d.push(i(d)+"rotate(",null,n)-2,x:Bn(u,h)})):h&&d.push(i(d)+"rotate("+h+n)}function o(u,h,d,f){u!==h?f.push({i:d.push(i(d)+"skewX(",null,n)-2,x:Bn(u,h)}):h&&d.push(i(d)+"skewX("+h+n)}function l(u,h,d,f,p,m){if(u!==d||h!==f){var _=p.push(i(p)+"scale(",null,",",null,")");m.push({i:_-4,x:Bn(u,d)},{i:_-2,x:Bn(h,f)})}else(d!==1||f!==1)&&p.push(i(p)+"scale("+d+","+f+")")}return function(u,h){var d=[],f=[];return u=t(u),h=t(h),a(u.translateX,u.translateY,h.translateX,h.translateY,d,f),s(u.rotate,h.rotate,d,f),o(u.skewX,h.skewX,d,f),l(u.scaleX,u.scaleY,h.scaleX,h.scaleY,d,f),u=h=null,function(p){for(var m=-1,_=f.length,y;++m<_;)d[(y=f[m]).i]=y.x(p);return d.join("")}}}var Y5=z5(YB,"px, ","px)","deg)"),U5=z5(UB,", ",")",")"),WB=1e-12;function W5(t){return((t=Math.exp(t))+1/t)/2}function HB(t){return((t=Math.exp(t))-1/t)/2}function GB(t){return((t=Math.exp(2*t))-1)/(t+1)}const H5=function t(e,r,n){function i(a,s){var o=a[0],l=a[1],u=a[2],h=s[0],d=s[1],f=s[2],p=h-o,m=d-l,_=p*p+m*m,y,b;if(_=0&&t._call.call(void 0,e),t=t._next;--yo}function tv(){_s=(Zu=Fl.now())+Qu,yo=Bl=0;try{J5()}finally{yo=0,eD(),_s=0}}function tD(){var t=Fl.now(),e=t-Zu;e>Z5&&(Qu-=e,Zu=t)}function eD(){for(var t,e=Ku,r,n=1/0;e;)e._call?(n>e._time&&(n=e._time),t=e,e=e._next):(r=e._next,e._next=null,e=t?t._next=r:Ku=r);Ol=t,bd(n)}function bd(t){if(!yo){Bl&&(Bl=clearTimeout(Bl));var e=t-_s;e>24?(t<1/0&&(Bl=setTimeout(tv,t-Fl.now()-Qu)),Dl&&(Dl=clearInterval(Dl))):(Dl||(Zu=Fl.now(),Dl=setInterval(tD,Z5)),yo=1,Q5(tv))}}function _d(t,e,r){var n=new ql;return e=e==null?0:+e,n.restart(i=>{n.stop(),t(i+e)},e,r),n}function rD(t,e,r){var n=new ql,i=e;return e==null?(n.restart(t,e,r),n):(n._restart=n.restart,n.restart=function(a,s,o){s=+s,o=o==null?Pl():+o,n._restart(function l(u){u+=i,n._restart(l,i+=s,o),a(u)},s,o)},n.restart(t,e,r),n)}var nD=fs("start","end","cancel","interrupt"),iD=[],ev=0,vd=1,xd=2,th=3,rv=4,kd=5,eh=6;function rh(t,e,r,n,i,a){var s=t.__transition;if(!s)t.__transition={};else if(r in s)return;aD(t,r,{name:e,index:n,group:i,on:nD,tween:iD,time:a.time,delay:a.delay,duration:a.duration,ease:a.ease,timer:null,state:ev})}function wd(t,e){var r=Jn(t,e);if(r.state>ev)throw new Error("too late; already scheduled");return r}function Ei(t,e){var r=Jn(t,e);if(r.state>th)throw new Error("too late; already running");return r}function Jn(t,e){var r=t.__transition;if(!r||!(r=r[e]))throw new Error("transition not found");return r}function aD(t,e,r){var n=t.__transition,i;n[e]=r,r.timer=Ju(a,0,r.time);function a(u){r.state=vd,r.timer.restart(s,r.delay,r.time),r.delay<=u&&s(u-r.delay)}function s(u){var h,d,f,p;if(r.state!==vd)return l();for(h in n)if(p=n[h],p.name===r.name){if(p.state===th)return _d(s);p.state===rv?(p.state=eh,p.timer.stop(),p.on.call("interrupt",t,t.__data__,p.index,p.group),delete n[h]):+hxd&&n.state=0&&(e=e.slice(0,r)),!e||e==="start"})}function DD(t,e,r){var n,i,a=BD(e)?wd:Ei;return function(){var s=a(this,t),o=s.on;o!==n&&(i=(n=o).copy()).on(e,r),s.on=i}}function OD(t,e){var r=this._id;return arguments.length<2?Jn(this.node(),r).on.on(t):this.each(DD(r,t,e))}function FD(t){return function(){var e=this.parentNode;for(var r in this.__transition)if(+r!==t)return;e&&e.removeChild(this)}}function PD(){return this.on("end.remove",FD(this._id))}function qD(t){var e=this._name,r=this._id;typeof t!="function"&&(t=Ru(t));for(var n=this._groups,i=n.length,a=new Array(i),s=0;s+t;function oO(t){return t*t}function lO(t){return t*(2-t)}function ov(t){return((t*=2)<=1?t*t:--t*(2-t)+1)/2}function cO(t){return t*t*t}function uO(t){return--t*t*t+1}function Ed(t){return((t*=2)<=1?t*t*t:(t-=2)*t*t+2)/2}var Cd=3,hO=function t(e){e=+e;function r(n){return Math.pow(n,e)}return r.exponent=t,r}(Cd),fO=function t(e){e=+e;function r(n){return 1-Math.pow(1-n,e)}return r.exponent=t,r}(Cd),lv=function t(e){e=+e;function r(n){return((n*=2)<=1?Math.pow(n,e):2-Math.pow(2-n,e))/2}return r.exponent=t,r}(Cd),cv=Math.PI,uv=cv/2;function dO(t){return+t==1?1:1-Math.cos(t*uv)}function pO(t){return Math.sin(t*uv)}function hv(t){return(1-Math.cos(cv*t))/2}function La(t){return(Math.pow(2,-10*t)-.0009765625)*1.0009775171065494}function gO(t){return La(1-+t)}function yO(t){return 1-La(t)}function fv(t){return((t*=2)<=1?La(1-t):2-La(t-1))/2}function mO(t){return 1-Math.sqrt(1-t*t)}function bO(t){return Math.sqrt(1- --t*t)}function dv(t){return((t*=2)<=1?1-Math.sqrt(1-t*t):Math.sqrt(1-(t-=2)*t)+1)/2}var Sd=4/11,_O=6/11,vO=8/11,xO=3/4,kO=9/11,wO=10/11,TO=15/16,EO=21/22,CO=63/64,nh=1/Sd/Sd;function SO(t){return 1-Vl(1-t)}function Vl(t){return(t=+t)vd&&n.name===e)return new Ci([[t]],OO,e,+i)}return null}const Rd=t=>()=>t;function PO(t,{sourceEvent:e,target:r,selection:n,mode:i,dispatch:a}){Object.defineProperties(this,{type:{value:t,enumerable:!0,configurable:!0},sourceEvent:{value:e,enumerable:!0,configurable:!0},target:{value:r,enumerable:!0,configurable:!0},selection:{value:n,enumerable:!0,configurable:!0},mode:{value:i,enumerable:!0,configurable:!0},_:{value:a}})}function qO(t){t.stopImmediatePropagation()}function Id(t){t.preventDefault(),t.stopImmediatePropagation()}var yv={name:"drag"},Nd={name:"space"},bo={name:"handle"},_o={name:"center"};const{abs:mv,max:Or,min:Fr}=Math;function bv(t){return[+t[0],+t[1]]}function Bd(t){return[bv(t[0]),bv(t[1])]}var ih={name:"x",handles:["w","e"].map(zl),input:function(t,e){return t==null?null:[[+t[0],e[0][1]],[+t[1],e[1][1]]]},output:function(t){return t&&[t[0][0],t[1][0]]}},ah={name:"y",handles:["n","s"].map(zl),input:function(t,e){return t==null?null:[[e[0][0],+t[0]],[e[1][0],+t[1]]]},output:function(t){return t&&[t[0][1],t[1][1]]}},VO={name:"xy",handles:["n","w","e","s","nw","ne","sw","se"].map(zl),input:function(t){return t==null?null:Bd(t)},output:function(t){return t}},Xi={overlay:"crosshair",selection:"move",n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},_v={e:"w",w:"e",nw:"ne",ne:"nw",se:"sw",sw:"se"},vv={n:"s",s:"n",nw:"sw",ne:"se",se:"ne",sw:"nw"},zO={overlay:1,selection:1,n:null,e:1,s:null,w:-1,nw:-1,ne:1,se:1,sw:-1},YO={overlay:1,selection:1,n:-1,e:null,s:1,w:null,nw:-1,ne:-1,se:1,sw:1};function zl(t){return{type:t}}function UO(t){return!t.ctrlKey&&!t.button}function WO(){var t=this.ownerSVGElement||this;return t.hasAttribute("viewBox")?(t=t.viewBox.baseVal,[[t.x,t.y],[t.x+t.width,t.y+t.height]]):[[0,0],[t.width.baseVal.value,t.height.baseVal.value]]}function HO(){return navigator.maxTouchPoints||"ontouchstart"in this}function Dd(t){for(;!t.__brush;)if(!(t=t.parentNode))return;return t.__brush}function GO(t){return t[0][0]===t[1][0]||t[0][1]===t[1][1]}function jO(t){var e=t.__brush;return e?e.dim.output(e.selection):null}function $O(){return Od(ih)}function XO(){return Od(ah)}function KO(){return Od(VO)}function Od(t){var e=WO,r=UO,n=HO,i=!0,a=fs("start","brush","end"),s=6,o;function l(y){var b=y.property("__brush",_).selectAll(".overlay").data([zl("overlay")]);b.enter().append("rect").attr("class","overlay").attr("pointer-events","all").attr("cursor",Xi.overlay).merge(b).each(function(){var k=Dd(this).extent;St(this).attr("x",k[0][0]).attr("y",k[0][1]).attr("width",k[1][0]-k[0][0]).attr("height",k[1][1]-k[0][1])}),y.selectAll(".selection").data([zl("selection")]).enter().append("rect").attr("class","selection").attr("cursor",Xi.selection).attr("fill","#777").attr("fill-opacity",.3).attr("stroke","#fff").attr("shape-rendering","crispEdges");var x=y.selectAll(".handle").data(t.handles,function(k){return k.type});x.exit().remove(),x.enter().append("rect").attr("class",function(k){return"handle handle--"+k.type}).attr("cursor",function(k){return Xi[k.type]}),y.each(u).attr("fill","none").attr("pointer-events","all").on("mousedown.brush",f).filter(n).on("touchstart.brush",f).on("touchmove.brush",p).on("touchend.brush touchcancel.brush",m).style("touch-action","none").style("-webkit-tap-highlight-color","rgba(0,0,0,0)")}l.move=function(y,b,x){y.tween?y.on("start.brush",function(k){h(this,arguments).beforestart().start(k)}).on("interrupt.brush end.brush",function(k){h(this,arguments).end(k)}).tween("brush",function(){var k=this,T=k.__brush,C=h(k,arguments),M=T.selection,S=t.input(typeof b=="function"?b.apply(this,arguments):b,T.extent),R=Ma(M,S);function A(L){T.selection=L===1&&S===null?null:R(L),u.call(k),C.brush()}return M!==null&&S!==null?A:A(1)}):y.each(function(){var k=this,T=arguments,C=k.__brush,M=t.input(typeof b=="function"?b.apply(k,T):b,C.extent),S=h(k,T).beforestart();vs(k),C.selection=M===null?null:M,u.call(k),S.start(x).brush(x).end(x)})},l.clear=function(y,b){l.move(y,null,b)};function u(){var y=St(this),b=Dd(this).selection;b?(y.selectAll(".selection").style("display",null).attr("x",b[0][0]).attr("y",b[0][1]).attr("width",b[1][0]-b[0][0]).attr("height",b[1][1]-b[0][1]),y.selectAll(".handle").style("display",null).attr("x",function(x){return x.type[x.type.length-1]==="e"?b[1][0]-s/2:b[0][0]-s/2}).attr("y",function(x){return x.type[0]==="s"?b[1][1]-s/2:b[0][1]-s/2}).attr("width",function(x){return x.type==="n"||x.type==="s"?b[1][0]-b[0][0]+s:s}).attr("height",function(x){return x.type==="e"||x.type==="w"?b[1][1]-b[0][1]+s:s})):y.selectAll(".selection,.handle").style("display","none").attr("x",null).attr("y",null).attr("width",null).attr("height",null)}function h(y,b,x){var k=y.__brush.emitter;return k&&(!x||!k.clean)?k:new d(y,b,x)}function d(y,b,x){this.that=y,this.args=b,this.state=y.__brush,this.active=0,this.clean=x}d.prototype={beforestart:function(){return++this.active===1&&(this.state.emitter=this,this.starting=!0),this},start:function(y,b){return this.starting?(this.starting=!1,this.emit("start",y,b)):this.emit("brush",y),this},brush:function(y,b){return this.emit("brush",y,b),this},end:function(y,b){return--this.active===0&&(delete this.state.emitter,this.emit("end",y,b)),this},emit:function(y,b,x){var k=St(this.that).datum();a.call(y,this.that,new PO(y,{sourceEvent:b,target:l,selection:t.output(this.state.selection),mode:x,dispatch:a}),k)}};function f(y){if(o&&!y.touches||!r.apply(this,arguments))return;var b=this,x=y.target.__data__.type,k=(i&&y.metaKey?x="overlay":x)==="selection"?yv:i&&y.altKey?_o:bo,T=t===ah?null:zO[x],C=t===ih?null:YO[x],M=Dd(b),S=M.extent,R=M.selection,A=S[0][0],L,v,B=S[0][1],w,D,N=S[1][0],z,X,ct=S[1][1],J,Y,$=0,lt=0,ut,W=T&&C&&i&&y.shiftKey,tt,K,it=Array.from(y.touches||[y],at=>{const It=at.identifier;return at=Tn(at,b),at.point0=at.slice(),at.identifier=It,at});vs(b);var Z=h(b,arguments,!0).beforestart();if(x==="overlay"){R&&(ut=!0);const at=[it[0],it[1]||it[0]];M.selection=R=[[L=t===ah?A:Fr(at[0][0],at[1][0]),w=t===ih?B:Fr(at[0][1],at[1][1])],[z=t===ah?N:Or(at[0][0],at[1][0]),J=t===ih?ct:Or(at[0][1],at[1][1])]],it.length>1&&F(y)}else L=R[0][0],w=R[0][1],z=R[1][0],J=R[1][1];v=L,D=w,X=z,Y=J;var V=St(b).attr("pointer-events","none"),Q=V.selectAll(".overlay").attr("cursor",Xi[x]);if(y.touches)Z.moved=U,Z.ended=j;else{var q=St(y.view).on("mousemove.brush",U,!0).on("mouseup.brush",j,!0);i&&q.on("keydown.brush",P,!0).on("keyup.brush",et,!0),Bu(y.view)}u.call(b),Z.start(y,k.name);function U(at){for(const It of at.changedTouches||[at])for(const Lt of it)Lt.identifier===It.identifier&&(Lt.cur=Tn(It,b));if(W&&!tt&&!K&&it.length===1){const It=it[0];mv(It.cur[0]-It[0])>mv(It.cur[1]-It[1])?K=!0:tt=!0}for(const It of it)It.cur&&(It[0]=It.cur[0],It[1]=It.cur[1]);ut=!0,Id(at),F(at)}function F(at){const It=it[0],Lt=It.point0;var Rt;switch($=It[0]-Lt[0],lt=It[1]-Lt[1],k){case Nd:case yv:{T&&($=Or(A-L,Fr(N-z,$)),v=L+$,X=z+$),C&&(lt=Or(B-w,Fr(ct-J,lt)),D=w+lt,Y=J+lt);break}case bo:{it[1]?(T&&(v=Or(A,Fr(N,it[0][0])),X=Or(A,Fr(N,it[1][0])),T=1),C&&(D=Or(B,Fr(ct,it[0][1])),Y=Or(B,Fr(ct,it[1][1])),C=1)):(T<0?($=Or(A-L,Fr(N-L,$)),v=L+$,X=z):T>0&&($=Or(A-z,Fr(N-z,$)),v=L,X=z+$),C<0?(lt=Or(B-w,Fr(ct-w,lt)),D=w+lt,Y=J):C>0&&(lt=Or(B-J,Fr(ct-J,lt)),D=w,Y=J+lt));break}case _o:{T&&(v=Or(A,Fr(N,L-$*T)),X=Or(A,Fr(N,z+$*T))),C&&(D=Or(B,Fr(ct,w-lt*C)),Y=Or(B,Fr(ct,J+lt*C)));break}}X0&&(L=v-$),C<0?J=Y-lt:C>0&&(w=D-lt),k=Nd,Q.attr("cursor",Xi.selection),F(at));break}default:return}Id(at)}function et(at){switch(at.keyCode){case 16:{W&&(tt=K=W=!1,F(at));break}case 18:{k===_o&&(T<0?z=X:T>0&&(L=v),C<0?J=Y:C>0&&(w=D),k=bo,F(at));break}case 32:{k===Nd&&(at.altKey?(T&&(z=X-$*T,L=v+$*T),C&&(J=Y-lt*C,w=D+lt*C),k=_o):(T<0?z=X:T>0&&(L=v),C<0?J=Y:C>0&&(w=D),k=bo),Q.attr("cursor",Xi[x]),F(at));break}default:return}Id(at)}}function p(y){h(this,arguments).moved(y)}function m(y){h(this,arguments).ended(y)}function _(){var y=this.__brush||{selection:null};return y.extent=Bd(e.apply(this,arguments)),y.dim=t,y}return l.extent=function(y){return arguments.length?(e=typeof y=="function"?y:Rd(Bd(y)),l):e},l.filter=function(y){return arguments.length?(r=typeof y=="function"?y:Rd(!!y),l):r},l.touchable=function(y){return arguments.length?(n=typeof y=="function"?y:Rd(!!y),l):n},l.handleSize=function(y){return arguments.length?(s=+y,l):s},l.keyModifiers=function(y){return arguments.length?(i=!!y,l):i},l.on=function(){var y=a.on.apply(a,arguments);return y===a?l:y},l}var xv=Math.abs,vo=Math.cos,xo=Math.sin,kv=Math.PI,sh=kv/2,wv=kv*2,Tv=Math.max,Fd=1e-12;function Pd(t,e){return Array.from({length:e-t},(r,n)=>t+n)}function ZO(t){return function(e,r){return t(e.source.value+e.target.value,r.source.value+r.target.value)}}function QO(){return qd(!1,!1)}function JO(){return qd(!1,!0)}function tF(){return qd(!0,!1)}function qd(t,e){var r=0,n=null,i=null,a=null;function s(o){var l=o.length,u=new Array(l),h=Pd(0,l),d=new Array(l*l),f=new Array(l),p=0,m;o=Float64Array.from({length:l*l},e?(_,y)=>o[y%l][y/l|0]:(_,y)=>o[y/l|0][y%l]);for(let _=0;_n(u[y],u[b]));for(const y of h){const b=_;if(t){const x=Pd(~l+1,l).filter(k=>k<0?o[~k*l+y]:o[y*l+k]);i&&x.sort((k,T)=>i(k<0?-o[~k*l+y]:o[y*l+k],T<0?-o[~T*l+y]:o[y*l+T]));for(const k of x)if(k<0){const T=d[~k*l+y]||(d[~k*l+y]={source:null,target:null});T.target={index:y,startAngle:_,endAngle:_+=o[~k*l+y]*p,value:o[~k*l+y]}}else{const T=d[y*l+k]||(d[y*l+k]={source:null,target:null});T.source={index:y,startAngle:_,endAngle:_+=o[y*l+k]*p,value:o[y*l+k]}}f[y]={index:y,startAngle:b,endAngle:_,value:u[y]}}else{const x=Pd(0,l).filter(k=>o[y*l+k]||o[k*l+y]);i&&x.sort((k,T)=>i(o[y*l+k],o[y*l+T]));for(const k of x){let T;if(yxs)if(!(Math.abs(h*o-l*u)>xs)||!i)this._+="L"+(this._x1=t)+","+(this._y1=e);else{var f=r-a,p=n-s,m=o*o+l*l,_=f*f+p*p,y=Math.sqrt(m),b=Math.sqrt(d),x=i*Math.tan((Vd-Math.acos((m+d-_)/(2*y*b)))/2),k=x/b,T=x/y;Math.abs(k-1)>xs&&(this._+="L"+(t+k*u)+","+(e+k*h)),this._+="A"+i+","+i+",0,0,"+ +(h*f>u*p)+","+(this._x1=t+T*o)+","+(this._y1=e+T*l)}},arc:function(t,e,r,n,i,a){t=+t,e=+e,r=+r,a=!!a;var s=r*Math.cos(n),o=r*Math.sin(n),l=t+s,u=e+o,h=1^a,d=a?n-i:i-n;if(r<0)throw new Error("negative radius: "+r);this._x1===null?this._+="M"+l+","+u:(Math.abs(this._x1-l)>xs||Math.abs(this._y1-u)>xs)&&(this._+="L"+l+","+u),r&&(d<0&&(d=d%zd+zd),d>eF?this._+="A"+r+","+r+",0,1,"+h+","+(t-s)+","+(e-o)+"A"+r+","+r+",0,1,"+h+","+(this._x1=l)+","+(this._y1=u):d>xs&&(this._+="A"+r+","+r+",0,"+ +(d>=Vd)+","+h+","+(this._x1=t+r*Math.cos(i))+","+(this._y1=e+r*Math.sin(i))))},rect:function(t,e,r,n){this._+="M"+(this._x0=this._x1=+t)+","+(this._y0=this._y1=+e)+"h"+ +r+"v"+ +n+"h"+-r+"Z"},toString:function(){return this._}};var rF=Array.prototype.slice;function ks(t){return function(){return t}}function nF(t){return t.source}function iF(t){return t.target}function Ev(t){return t.radius}function aF(t){return t.startAngle}function sF(t){return t.endAngle}function oF(){return 0}function lF(){return 10}function Cv(t){var e=nF,r=iF,n=Ev,i=Ev,a=aF,s=sF,o=oF,l=null;function u(){var h,d=e.apply(this,arguments),f=r.apply(this,arguments),p=o.apply(this,arguments)/2,m=rF.call(arguments),_=+n.apply(this,(m[0]=d,m)),y=a.apply(this,m)-sh,b=s.apply(this,m)-sh,x=+i.apply(this,(m[0]=f,m)),k=a.apply(this,m)-sh,T=s.apply(this,m)-sh;if(l||(l=h=Ra()),p>Fd&&(xv(b-y)>p*2+Fd?b>y?(y+=p,b-=p):(y-=p,b+=p):y=b=(y+b)/2,xv(T-k)>p*2+Fd?T>k?(k+=p,T-=p):(k-=p,T+=p):k=T=(k+T)/2),l.moveTo(_*vo(y),_*xo(y)),l.arc(0,0,_,y,b),y!==k||b!==T)if(t){var C=+t.apply(this,arguments),M=x-C,S=(k+T)/2;l.quadraticCurveTo(0,0,M*vo(k),M*xo(k)),l.lineTo(x*vo(S),x*xo(S)),l.lineTo(M*vo(T),M*xo(T))}else l.quadraticCurveTo(0,0,x*vo(k),x*xo(k)),l.arc(0,0,x,k,T);if(l.quadraticCurveTo(0,0,_*vo(y),_*xo(y)),l.closePath(),h)return l=null,h+""||null}return t&&(u.headRadius=function(h){return arguments.length?(t=typeof h=="function"?h:ks(+h),u):t}),u.radius=function(h){return arguments.length?(n=i=typeof h=="function"?h:ks(+h),u):n},u.sourceRadius=function(h){return arguments.length?(n=typeof h=="function"?h:ks(+h),u):n},u.targetRadius=function(h){return arguments.length?(i=typeof h=="function"?h:ks(+h),u):i},u.startAngle=function(h){return arguments.length?(a=typeof h=="function"?h:ks(+h),u):a},u.endAngle=function(h){return arguments.length?(s=typeof h=="function"?h:ks(+h),u):s},u.padAngle=function(h){return arguments.length?(o=typeof h=="function"?h:ks(+h),u):o},u.source=function(h){return arguments.length?(e=h,u):e},u.target=function(h){return arguments.length?(r=h,u):r},u.context=function(h){return arguments.length?(l=h==null?null:h,u):l},u}function cF(){return Cv()}function uF(){return Cv(lF)}var hF=Array.prototype,Sv=hF.slice;function fF(t,e){return t-e}function dF(t){for(var e=0,r=t.length,n=t[r-1][1]*t[0][0]-t[r-1][0]*t[0][1];++e()=>t;function pF(t,e){for(var r=-1,n=e.length,i;++rn!=p>n&&r<(f-u)*(n-h)/(p-h)+u&&(i=-i)}return i}function yF(t,e,r){var n;return mF(t,e,r)&&bF(t[n=+(t[0]===e[0])],r[n],e[n])}function mF(t,e,r){return(e[0]-t[0])*(r[1]-t[1])===(r[0]-t[0])*(e[1]-t[1])}function bF(t,e,r){return t<=e&&e<=r||r<=e&&e<=t}function _F(){}var Ki=[[],[[[1,1.5],[.5,1]]],[[[1.5,1],[1,1.5]]],[[[1.5,1],[.5,1]]],[[[1,.5],[1.5,1]]],[[[1,1.5],[.5,1]],[[1,.5],[1.5,1]]],[[[1,.5],[1,1.5]]],[[[1,.5],[.5,1]]],[[[.5,1],[1,.5]]],[[[1,1.5],[1,.5]]],[[[.5,1],[1,.5]],[[1.5,1],[1,1.5]]],[[[1.5,1],[1,.5]]],[[[.5,1],[1.5,1]]],[[[1,1.5],[1.5,1]]],[[[.5,1],[1,1.5]]],[]];function Ud(){var t=1,e=1,r=W0,n=l;function i(u){var h=r(u);if(Array.isArray(h))h=h.slice().sort(fF);else{const d=xl(u),f=wl(d[0],d[1],h);h=hs(Math.floor(d[0]/f)*f,Math.floor(d[1]/f-1)*f,h)}return h.map(d=>a(u,d))}function a(u,h){var d=[],f=[];return s(u,h,function(p){n(p,u,h),dF(p)>0?d.push([p]):f.push(p)}),f.forEach(function(p){for(var m=0,_=d.length,y;m<_;++m)if(pF((y=d[m])[0],p)!==-1){y.push(p);return}}),{type:"MultiPolygon",value:h,coordinates:d}}function s(u,h,d){var f=new Array,p=new Array,m,_,y,b,x,k;for(m=_=-1,b=u[0]>=h,Ki[b<<1].forEach(T);++m=h,Ki[y|b<<1].forEach(T);for(Ki[b<<0].forEach(T);++_=h,x=u[_*t]>=h,Ki[b<<1|x<<2].forEach(T);++m=h,k=x,x=u[_*t+m+1]>=h,Ki[y|b<<1|x<<2|k<<3].forEach(T);Ki[b|x<<3].forEach(T)}for(m=-1,x=u[_*t]>=h,Ki[x<<2].forEach(T);++m=h,Ki[x<<2|k<<3].forEach(T);Ki[x<<3].forEach(T);function T(C){var M=[C[0][0]+m,C[0][1]+_],S=[C[1][0]+m,C[1][1]+_],R=o(M),A=o(S),L,v;(L=p[R])?(v=f[A])?(delete p[L.end],delete f[v.start],L===v?(L.ring.push(S),d(L.ring)):f[L.start]=p[v.end]={start:L.start,end:v.end,ring:L.ring.concat(v.ring)}):(delete p[L.end],L.ring.push(S),p[L.end=A]=L):(L=f[A])?(v=p[R])?(delete f[L.start],delete p[v.end],L===v?(L.ring.push(S),d(L.ring)):f[v.start]=p[L.end]={start:v.start,end:L.end,ring:v.ring.concat(L.ring)}):(delete f[L.start],L.ring.unshift(M),f[L.start=R]=L):f[R]=p[A]={start:R,end:A,ring:[M,S]}}}function o(u){return u[0]*2+u[1]*(t+1)*4}function l(u,h,d){u.forEach(function(f){var p=f[0],m=f[1],_=p|0,y=m|0,b,x=h[y*t+_];p>0&&p0&&m=0&&d>=0))throw new Error("invalid size");return t=h,e=d,i},i.thresholds=function(u){return arguments.length?(r=typeof u=="function"?u:Array.isArray(u)?Ia(Sv.call(u)):Ia(u),i):r},i.smooth=function(u){return arguments.length?(n=u?l:_F,i):n===l},i}function vF(t){return t[0]}function xF(t){return t[1]}function kF(){return 1}function wF(){var t=vF,e=xF,r=kF,n=960,i=500,a=20,s=2,o=a*3,l=n+o*2>>s,u=i+o*2>>s,h=Ia(20);function d(x){var k=new Float32Array(l*u),T=Math.pow(2,-s),C=-1;for(const w of x){var M=(t(w,++C,x)+o)*T,S=(e(w,C,x)+o)*T,R=+r(w,C,x);if(M>=0&&M=0&&SM*C))(k).map((M,S)=>(M.value=+T[S],p(M)))}f.contours=function(x){var k=d(x),T=Ud().size([l,u]),C=Math.pow(2,2*s),M=S=>{S=+S;var R=p(T.contour(k,S*C));return R.value=S,R};return Object.defineProperty(M,"max",{get:()=>lo(k)/C}),M};function p(x){return x.coordinates.forEach(m),x}function m(x){x.forEach(_)}function _(x){x.forEach(y)}function y(x){x[0]=x[0]*Math.pow(2,s)-o,x[1]=x[1]*Math.pow(2,s)-o}function b(){return o=a*3,l=n+o*2>>s,u=i+o*2>>s,f}return f.x=function(x){return arguments.length?(t=typeof x=="function"?x:Ia(+x),f):t},f.y=function(x){return arguments.length?(e=typeof x=="function"?x:Ia(+x),f):e},f.weight=function(x){return arguments.length?(r=typeof x=="function"?x:Ia(+x),f):r},f.size=function(x){if(!arguments.length)return[n,i];var k=+x[0],T=+x[1];if(!(k>=0&&T>=0))throw new Error("invalid size");return n=k,i=T,b()},f.cellSize=function(x){if(!arguments.length)return 1<=1))throw new Error("invalid cell size");return s=Math.floor(Math.log(x)/Math.LN2),b()},f.thresholds=function(x){return arguments.length?(h=typeof x=="function"?x:Array.isArray(x)?Ia(Sv.call(x)):Ia(x),f):h},f.bandwidth=function(x){if(!arguments.length)return Math.sqrt(a*(a+1));if(!((x=+x)>=0))throw new Error("invalid bandwidth");return a=(Math.sqrt(4*x*x+1)-1)/2,b()},f}const Zi=11102230246251565e-32,Pr=134217729,TF=(3+8*Zi)*Zi;function Wd(t,e,r,n,i){let a,s,o,l,u=e[0],h=n[0],d=0,f=0;h>u==h>-u?(a=u,u=e[++d]):(a=h,h=n[++f]);let p=0;if(du==h>-u?(s=u+a,o=a-(s-u),u=e[++d]):(s=h+a,o=a-(s-h),h=n[++f]),a=s,o!==0&&(i[p++]=o);du==h>-u?(s=a+u,l=s-a,o=a-(s-l)+(u-l),u=e[++d]):(s=a+h,l=s-a,o=a-(s-l)+(h-l),h=n[++f]),a=s,o!==0&&(i[p++]=o);for(;d=D||-w>=D||(d=t-A,o=t-(A+d)+(d-i),d=r-L,u=r-(L+d)+(d-i),d=e-v,l=e-(v+d)+(d-a),d=n-B,h=n-(B+d)+(d-a),o===0&&l===0&&u===0&&h===0)||(D=AF*s+TF*Math.abs(w),w+=A*h+B*o-(v*u+L*l),w>=D||-w>=D))return w;T=o*B,f=Pr*o,p=f-(f-o),m=o-p,f=Pr*B,_=f-(f-B),y=B-_,C=m*y-(T-p*_-m*_-p*y),M=l*L,f=Pr*l,p=f-(f-l),m=l-p,f=Pr*L,_=f-(f-L),y=L-_,S=m*y-(M-p*_-m*_-p*y),b=C-S,d=C-b,Xr[0]=C-(b+d)+(d-S),x=T+b,d=x-T,k=T-(x-d)+(b-d),b=k-M,d=k-b,Xr[1]=k-(b+d)+(d-M),R=x+b,d=R-x,Xr[2]=x-(R-d)+(b-d),Xr[3]=R;const N=Wd(4,ko,4,Xr,Av);T=A*h,f=Pr*A,p=f-(f-A),m=A-p,f=Pr*h,_=f-(f-h),y=h-_,C=m*y-(T-p*_-m*_-p*y),M=v*u,f=Pr*v,p=f-(f-v),m=v-p,f=Pr*u,_=f-(f-u),y=u-_,S=m*y-(M-p*_-m*_-p*y),b=C-S,d=C-b,Xr[0]=C-(b+d)+(d-S),x=T+b,d=x-T,k=T-(x-d)+(b-d),b=k-M,d=k-b,Xr[1]=k-(b+d)+(d-M),R=x+b,d=R-x,Xr[2]=x-(R-d)+(b-d),Xr[3]=R;const z=Wd(N,Av,4,Xr,Mv);T=o*h,f=Pr*o,p=f-(f-o),m=o-p,f=Pr*h,_=f-(f-h),y=h-_,C=m*y-(T-p*_-m*_-p*y),M=l*u,f=Pr*l,p=f-(f-l),m=l-p,f=Pr*u,_=f-(f-u),y=u-_,S=m*y-(M-p*_-m*_-p*y),b=C-S,d=C-b,Xr[0]=C-(b+d)+(d-S),x=T+b,d=x-T,k=T-(x-d)+(b-d),b=k-M,d=k-b,Xr[1]=k-(b+d)+(d-M),R=x+b,d=R-x,Xr[2]=x-(R-d)+(b-d),Xr[3]=R;const X=Wd(z,Mv,4,Xr,Lv);return Lv[X-1]}function oh(t,e,r,n,i,a){const s=(e-a)*(r-i),o=(t-i)*(n-a),l=s-o;if(s===0||o===0||s>0!=o>0)return l;const u=Math.abs(s+o);return Math.abs(l)>=CF*u?l:-MF(t,e,r,n,i,a,u)}const Rv=Math.pow(2,-52),lh=new Uint32Array(512);class ch{static from(e,r=BF,n=DF){const i=e.length,a=new Float64Array(i*2);for(let s=0;s>1;if(r>0&&typeof e[0]!="number")throw new Error("Expected coords to contain numbers.");this.coords=e;const n=Math.max(2*r-5,0);this._triangles=new Uint32Array(n*3),this._halfedges=new Int32Array(n*3),this._hashSize=Math.ceil(Math.sqrt(r)),this._hullPrev=new Uint32Array(r),this._hullNext=new Uint32Array(r),this._hullTri=new Uint32Array(r),this._hullHash=new Int32Array(this._hashSize).fill(-1),this._ids=new Uint32Array(r),this._dists=new Float64Array(r),this.update()}update(){const{coords:e,_hullPrev:r,_hullNext:n,_hullTri:i,_hullHash:a}=this,s=e.length>>1;let o=1/0,l=1/0,u=-1/0,h=-1/0;for(let L=0;Lu&&(u=v),B>h&&(h=B),this._ids[L]=L}const d=(o+u)/2,f=(l+h)/2;let p=1/0,m,_,y;for(let L=0;L0&&(_=L,p=v)}let k=e[2*_],T=e[2*_+1],C=1/0;for(let L=0;Lw&&(L[v++]=D,w=this._dists[D])}this.hull=L.subarray(0,v),this.triangles=new Uint32Array(0),this.halfedges=new Uint32Array(0);return}if(oh(b,x,k,T,M,S)<0){const L=_,v=k,B=T;_=y,k=M,T=S,y=L,M=v,S=B}const R=NF(b,x,k,T,M,S);this._cx=R.x,this._cy=R.y;for(let L=0;L0&&Math.abs(D-v)<=Rv&&Math.abs(N-B)<=Rv||(v=D,B=N,w===m||w===_||w===y))continue;let z=0;for(let $=0,lt=this._hashKey(D,N);$=0;)if(X=ct,X===z){X=-1;break}if(X===-1)continue;let J=this._addTriangle(X,w,n[X],-1,-1,i[X]);i[w]=this._legalize(J+2),i[X]=J,A++;let Y=n[X];for(;ct=n[Y],oh(D,N,e[2*Y],e[2*Y+1],e[2*ct],e[2*ct+1])<0;)J=this._addTriangle(Y,w,ct,i[w],-1,i[Y]),i[w]=this._legalize(J+2),n[Y]=Y,A--,Y=ct;if(X===z)for(;ct=r[X],oh(D,N,e[2*ct],e[2*ct+1],e[2*X],e[2*X+1])<0;)J=this._addTriangle(ct,w,X,-1,i[X],i[ct]),this._legalize(J+2),i[ct]=J,n[X]=X,A--,X=ct;this._hullStart=r[w]=X,n[X]=r[Y]=w,n[w]=Y,a[this._hashKey(D,N)]=w,a[this._hashKey(e[2*X],e[2*X+1])]=X}this.hull=new Uint32Array(A);for(let L=0,v=this._hullStart;L0?3-r:1+r)/4}function Hd(t,e,r,n){const i=t-r,a=e-n;return i*i+a*a}function RF(t,e,r,n,i,a,s,o){const l=t-s,u=e-o,h=r-s,d=n-o,f=i-s,p=a-o,m=l*l+u*u,_=h*h+d*d,y=f*f+p*p;return l*(d*y-_*p)-u*(h*y-_*f)+m*(h*p-d*f)<0}function IF(t,e,r,n,i,a){const s=r-t,o=n-e,l=i-t,u=a-e,h=s*s+o*o,d=l*l+u*u,f=.5/(s*u-o*l),p=(u*h-o*d)*f,m=(s*d-l*h)*f;return p*p+m*m}function NF(t,e,r,n,i,a){const s=r-t,o=n-e,l=i-t,u=a-e,h=s*s+o*o,d=l*l+u*u,f=.5/(s*u-o*l),p=t+(u*h-o*d)*f,m=e+(s*d-l*h)*f;return{x:p,y:m}}function wo(t,e,r,n){if(n-r<=20)for(let i=r+1;i<=n;i++){const a=t[i],s=e[a];let o=i-1;for(;o>=r&&e[t[o]]>s;)t[o+1]=t[o--];t[o+1]=a}else{const i=r+n>>1;let a=r+1,s=n;Ul(t,i,a),e[t[r]]>e[t[n]]&&Ul(t,r,n),e[t[a]]>e[t[n]]&&Ul(t,a,n),e[t[r]]>e[t[a]]&&Ul(t,r,a);const o=t[a],l=e[o];for(;;){do a++;while(e[t[a]]l);if(s=s-r?(wo(t,e,a,n),wo(t,e,r,s-1)):(wo(t,e,r,s-1),wo(t,e,a,n))}}function Ul(t,e,r){const n=t[e];t[e]=t[r],t[r]=n}function BF(t){return t[0]}function DF(t){return t[1]}const Iv=1e-6;class ws{constructor(){this._x0=this._y0=this._x1=this._y1=null,this._=""}moveTo(e,r){this._+=`M${this._x0=this._x1=+e},${this._y0=this._y1=+r}`}closePath(){this._x1!==null&&(this._x1=this._x0,this._y1=this._y0,this._+="Z")}lineTo(e,r){this._+=`L${this._x1=+e},${this._y1=+r}`}arc(e,r,n){e=+e,r=+r,n=+n;const i=e+n,a=r;if(n<0)throw new Error("negative radius");this._x1===null?this._+=`M${i},${a}`:(Math.abs(this._x1-i)>Iv||Math.abs(this._y1-a)>Iv)&&(this._+="L"+i+","+a),n&&(this._+=`A${n},${n},0,1,1,${e-n},${r}A${n},${n},0,1,1,${this._x1=i},${this._y1=a}`)}rect(e,r,n,i){this._+=`M${this._x0=this._x1=+e},${this._y0=this._y1=+r}h${+n}v${+i}h${-n}Z`}value(){return this._||null}}class Gd{constructor(){this._=[]}moveTo(e,r){this._.push([e,r])}closePath(){this._.push(this._[0].slice())}lineTo(e,r){this._.push([e,r])}value(){return this._.length?this._:null}}class Nv{constructor(e,[r,n,i,a]=[0,0,960,500]){if(!((i=+i)>=(r=+r))||!((a=+a)>=(n=+n)))throw new Error("invalid bounds");this.delaunay=e,this._circumcenters=new Float64Array(e.points.length*2),this.vectors=new Float64Array(e.points.length*2),this.xmax=i,this.xmin=r,this.ymax=a,this.ymin=n,this._init()}update(){return this.delaunay.update(),this._init(),this}_init(){const{delaunay:{points:e,hull:r,triangles:n},vectors:i}=this,a=this.circumcenters=this._circumcenters.subarray(0,n.length/3*2);for(let p=0,m=0,_=n.length,y,b;p<_;p+=3,m+=2){const x=n[p]*2,k=n[p+1]*2,T=n[p+2]*2,C=e[x],M=e[x+1],S=e[k],R=e[k+1],A=e[T],L=e[T+1],v=S-C,B=R-M,w=A-C,D=L-M,N=(v*D-B*w)*2;if(Math.abs(N)<1e-9){let z=1e9;const X=n[0]*2;z*=Math.sign((e[X]-C)*D-(e[X+1]-M)*w),y=(C+A)/2-z*D,b=(M+L)/2+z*w}else{const z=1/N,X=v*v+B*B,ct=w*w+D*D;y=C+(D*X-B*ct)*z,b=M+(v*ct-w*X)*z}a[m]=y,a[m+1]=b}let s=r[r.length-1],o,l=s*4,u,h=e[2*s],d,f=e[2*s+1];i.fill(0);for(let p=0;p1;)a-=2;for(let s=2;s4)for(let s=0;s0){if(r>=this.ymax)return null;(s=(this.ymax-r)/i)0){if(e>=this.xmax)return null;(s=(this.xmax-e)/n)this.xmax?2:0)|(rthis.ymax?8:0)}}const OF=2*Math.PI,To=Math.pow;function FF(t){return t[0]}function PF(t){return t[1]}function qF(t){const{triangles:e,coords:r}=t;for(let n=0;n1e-10)return!1}return!0}function VF(t,e,r){return[t+Math.sin(t+e)*r,e+Math.cos(t-e)*r]}class jd{static from(e,r=FF,n=PF,i){return new jd("length"in e?zF(e,r,n,i):Float64Array.from(YF(e,r,n,i)))}constructor(e){this._delaunator=new ch(e),this.inedges=new Int32Array(e.length/2),this._hullIndex=new Int32Array(e.length/2),this.points=this._delaunator.coords,this._init()}update(){return this._delaunator.update(),this._init(),this}_init(){const e=this._delaunator,r=this.points;if(e.hull&&e.hull.length>2&&qF(e)){this.collinear=Int32Array.from({length:r.length/2},(f,p)=>p).sort((f,p)=>r[2*f]-r[2*p]||r[2*f+1]-r[2*p+1]);const l=this.collinear[0],u=this.collinear[this.collinear.length-1],h=[r[2*l],r[2*l+1],r[2*u],r[2*u+1]],d=1e-8*Math.hypot(h[3]-h[1],h[2]-h[0]);for(let f=0,p=r.length/2;f0&&(this.triangles=new Int32Array(3).fill(-1),this.halfedges=new Int32Array(3).fill(-1),this.triangles[0]=i[0],s[i[0]]=1,i.length===2&&(s[i[1]]=0,this.triangles[1]=i[1],this.triangles[2]=i[1]))}voronoi(e){return new Nv(this,e)}*neighbors(e){const{inedges:r,hull:n,_hullIndex:i,halfedges:a,triangles:s,collinear:o}=this;if(o){const d=o.indexOf(e);d>0&&(yield o[d-1]),d=0&&a!==n&&a!==i;)n=a;return a}_step(e,r,n){const{inedges:i,hull:a,_hullIndex:s,halfedges:o,triangles:l,points:u}=this;if(i[e]===-1||!u.length)return(e+1)%(u.length>>1);let h=e,d=To(r-u[e*2],2)+To(n-u[e*2+1],2);const f=i[e];let p=f;do{let m=l[p];const _=To(r-u[m*2],2)+To(n-u[m*2+1],2);if(_9999?"+"+dn(t,6):dn(t,4)}function HF(t){var e=t.getUTCHours(),r=t.getUTCMinutes(),n=t.getUTCSeconds(),i=t.getUTCMilliseconds();return isNaN(t)?"Invalid Date":WF(t.getUTCFullYear())+"-"+dn(t.getUTCMonth()+1,2)+"-"+dn(t.getUTCDate(),2)+(i?"T"+dn(e,2)+":"+dn(r,2)+":"+dn(n,2)+"."+dn(i,3)+"Z":n?"T"+dn(e,2)+":"+dn(r,2)+":"+dn(n,2)+"Z":r||e?"T"+dn(e,2)+":"+dn(r,2)+"Z":"")}function uh(t){var e=new RegExp('["'+t+` +\r]`),r=t.charCodeAt(0);function n(d,f){var p,m,_=i(d,function(y,b){if(p)return p(y,b-1);m=y,p=f?UF(y,f):Dv(y)});return _.columns=m||[],_}function i(d,f){var p=[],m=d.length,_=0,y=0,b,x=m<=0,k=!1;d.charCodeAt(m-1)===Wl&&--m,d.charCodeAt(m-1)===Kd&&--m;function T(){if(x)return $d;if(k)return k=!1,Bv;var M,S=_,R;if(d.charCodeAt(S)===Xd){for(;_++=m?x=!0:(R=d.charCodeAt(_++))===Wl?k=!0:R===Kd&&(k=!0,d.charCodeAt(_)===Wl&&++_),d.slice(S+1,M-1).replace(/""/g,'"')}for(;_hh(e,r).then(n=>new DOMParser().parseFromString(n,t))}const mP=Zd("application/xml");var bP=Zd("text/html"),_P=Zd("image/svg+xml");function vP(t,e){var r,n=1;t==null&&(t=0),e==null&&(e=0);function i(){var a,s=r.length,o,l=0,u=0;for(a=0;a=(d=(o+u)/2))?o=d:u=d,(y=r>=(f=(l+h)/2))?l=f:h=f,i=a,!(a=a[b=y<<1|_]))return i[b]=s,t;if(p=+t._x.call(null,a.data),m=+t._y.call(null,a.data),e===p&&r===m)return s.next=a,i?i[b]=s:t._root=s,t;do i=i?i[b]=new Array(4):t._root=new Array(4),(_=e>=(d=(o+u)/2))?o=d:u=d,(y=r>=(f=(l+h)/2))?l=f:h=f;while((b=y<<1|_)===(x=(m>=f)<<1|p>=d));return i[x]=a,i[b]=s,t}function kP(t){var e,r,n=t.length,i,a,s=new Array(n),o=new Array(n),l=1/0,u=1/0,h=-1/0,d=-1/0;for(r=0;rh&&(h=i),ad&&(d=a));if(l>h||u>d)return this;for(this.cover(l,u).cover(h,d),r=0;rt||t>=i||n>e||e>=a;)switch(u=(eh||(o=m.y0)>d||(l=m.x1)=b)<<1|t>=y)&&(m=f[f.length-1],f[f.length-1]=f[f.length-1-_],f[f.length-1-_]=m)}else{var x=t-+this._x.call(null,p.data),k=e-+this._y.call(null,p.data),T=x*x+k*k;if(T=(f=(s+l)/2))?s=f:l=f,(_=d>=(p=(o+u)/2))?o=p:u=p,e=r,!(r=r[y=_<<1|m]))return this;if(!r.length)break;(e[y+1&3]||e[y+2&3]||e[y+3&3])&&(n=e,b=y)}for(;r.data!==t;)if(i=r,!(r=r.next))return this;return(a=r.next)&&delete r.next,i?(a?i.next=a:delete i.next,this):e?(a?e[y]=a:delete e[y],(r=e[0]||e[1]||e[2]||e[3])&&r===(e[3]||e[2]||e[1]||e[0])&&!r.length&&(n?n[b]=r:this._root=r),this):(this._root=a,this)}function AP(t){for(var e=0,r=t.length;ef.index){var v=p-R.x-R.vx,B=m-R.y-R.vy,w=v*v+B*B;wp+L||Mm+L||Su.r&&(u.r=u[h].r)}function l(){if(!!e){var u,h=e.length,d;for(r=new Array(h),u=0;u[e(C,M,s),C])),T;for(y=0,o=new Array(b);y(t=(YP*t+UP)%Uv)/Uv}function HP(t){return t.x}function GP(t){return t.y}var jP=10,$P=Math.PI*(3-Math.sqrt(5));function XP(t){var e,r=1,n=.001,i=1-Math.pow(n,1/300),a=0,s=.6,o=new Map,l=Ju(d),u=fs("tick","end"),h=WP();t==null&&(t=[]);function d(){f(),u.call("tick",e),r1?(y==null?o.delete(_):o.set(_,m(y)),e):o.get(_)},find:function(_,y,b){var x=0,k=t.length,T,C,M,S,R;for(b==null?b=1/0:b*=b,x=0;x1?(u.on(_,y),e):u.on(_)}}}function KP(){var t,e,r,n,i=vr(-30),a,s=1,o=1/0,l=.81;function u(p){var m,_=t.length,y=fh(t,HP,GP).visitAfter(d);for(n=p,m=0;m<_;++m)e=t[m],y.visit(f)}function h(){if(!!t){var p,m=t.length,_;for(a=new Array(m),p=0;p=o)return;(p.data!==e||p.next)&&(b===0&&(b=Na(r),T+=b*b),x===0&&(x=Na(r),T+=x*x),T=1e21?t.toLocaleString("en").replace(/,/g,""):t.toString(10)}function dh(t,e){if((r=(t=e?t.toExponential(e-1):t.toExponential()).indexOf("e"))<0)return null;var r,n=t.slice(0,r);return[n.length>1?n[0]+n.slice(2):n,+t.slice(r+1)]}function Eo(t){return t=dh(Math.abs(t)),t?t[1]:NaN}function eq(t,e){return function(r,n){for(var i=r.length,a=[],s=0,o=t[0],l=0;i>0&&o>0&&(l+o+1>n&&(o=Math.max(1,n-l)),a.push(r.substring(i-=o,i+o)),!((l+=o+1)>n));)o=t[s=(s+1)%t.length];return a.reverse().join(e)}}function rq(t){return function(e){return e.replace(/[0-9]/g,function(r){return t[+r]})}}var nq=/^(?:(.)?([<>=^]))?([+\-( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?(~)?([a-z%])?$/i;function Co(t){if(!(e=nq.exec(t)))throw new Error("invalid format: "+t);var e;return new ph({fill:e[1],align:e[2],sign:e[3],symbol:e[4],zero:e[5],width:e[6],comma:e[7],precision:e[8]&&e[8].slice(1),trim:e[9],type:e[10]})}Co.prototype=ph.prototype;function ph(t){this.fill=t.fill===void 0?" ":t.fill+"",this.align=t.align===void 0?">":t.align+"",this.sign=t.sign===void 0?"-":t.sign+"",this.symbol=t.symbol===void 0?"":t.symbol+"",this.zero=!!t.zero,this.width=t.width===void 0?void 0:+t.width,this.comma=!!t.comma,this.precision=t.precision===void 0?void 0:+t.precision,this.trim=!!t.trim,this.type=t.type===void 0?"":t.type+""}ph.prototype.toString=function(){return this.fill+this.align+this.sign+this.symbol+(this.zero?"0":"")+(this.width===void 0?"":Math.max(1,this.width|0))+(this.comma?",":"")+(this.precision===void 0?"":"."+Math.max(0,this.precision|0))+(this.trim?"~":"")+this.type};function iq(t){t:for(var e=t.length,r=1,n=-1,i;r0&&(n=0);break}return n>0?t.slice(0,n)+t.slice(i+1):t}var Wv;function aq(t,e){var r=dh(t,e);if(!r)return t+"";var n=r[0],i=r[1],a=i-(Wv=Math.max(-8,Math.min(8,Math.floor(i/3)))*3)+1,s=n.length;return a===s?n:a>s?n+new Array(a-s+1).join("0"):a>0?n.slice(0,a)+"."+n.slice(a):"0."+new Array(1-a).join("0")+dh(t,Math.max(0,e+a-1))[0]}function Hv(t,e){var r=dh(t,e);if(!r)return t+"";var n=r[0],i=r[1];return i<0?"0."+new Array(-i).join("0")+n:n.length>i+1?n.slice(0,i+1)+"."+n.slice(i+1):n+new Array(i-n.length+2).join("0")}const Gv={"%":(t,e)=>(t*100).toFixed(e),b:t=>Math.round(t).toString(2),c:t=>t+"",d:tq,e:(t,e)=>t.toExponential(e),f:(t,e)=>t.toFixed(e),g:(t,e)=>t.toPrecision(e),o:t=>Math.round(t).toString(8),p:(t,e)=>Hv(t*100,e),r:Hv,s:aq,X:t=>Math.round(t).toString(16).toUpperCase(),x:t=>Math.round(t).toString(16)};function jv(t){return t}var $v=Array.prototype.map,Xv=["y","z","a","f","p","n","\xB5","m","","k","M","G","T","P","E","Z","Y"];function Kv(t){var e=t.grouping===void 0||t.thousands===void 0?jv:eq($v.call(t.grouping,Number),t.thousands+""),r=t.currency===void 0?"":t.currency[0]+"",n=t.currency===void 0?"":t.currency[1]+"",i=t.decimal===void 0?".":t.decimal+"",a=t.numerals===void 0?jv:rq($v.call(t.numerals,String)),s=t.percent===void 0?"%":t.percent+"",o=t.minus===void 0?"\u2212":t.minus+"",l=t.nan===void 0?"NaN":t.nan+"";function u(d){d=Co(d);var f=d.fill,p=d.align,m=d.sign,_=d.symbol,y=d.zero,b=d.width,x=d.comma,k=d.precision,T=d.trim,C=d.type;C==="n"?(x=!0,C="g"):Gv[C]||(k===void 0&&(k=12),T=!0,C="g"),(y||f==="0"&&p==="=")&&(y=!0,f="0",p="=");var M=_==="$"?r:_==="#"&&/[boxX]/.test(C)?"0"+C.toLowerCase():"",S=_==="$"?n:/[%p]/.test(C)?s:"",R=Gv[C],A=/[defgprs%]/.test(C);k=k===void 0?6:/[gprs]/.test(C)?Math.max(1,Math.min(21,k)):Math.max(0,Math.min(20,k));function L(v){var B=M,w=S,D,N,z;if(C==="c")w=R(v)+w,v="";else{v=+v;var X=v<0||1/v<0;if(v=isNaN(v)?l:R(Math.abs(v),k),T&&(v=iq(v)),X&&+v==0&&m!=="+"&&(X=!1),B=(X?m==="("?m:o:m==="-"||m==="("?"":m)+B,w=(C==="s"?Xv[8+Wv/3]:"")+w+(X&&m==="("?")":""),A){for(D=-1,N=v.length;++Dz||z>57){w=(z===46?i+v.slice(D+1):v.slice(D))+w,v=v.slice(0,D);break}}}x&&!y&&(v=e(v,1/0));var ct=B.length+v.length+w.length,J=ct>1)+B+v+w+J.slice(ct);break;default:v=J+B+v+w;break}return a(v)}return L.toString=function(){return d+""},L}function h(d,f){var p=u((d=Co(d),d.type="f",d)),m=Math.max(-8,Math.min(8,Math.floor(Eo(f)/3)))*3,_=Math.pow(10,-m),y=Xv[8+m/3];return function(b){return p(_*b)+y}}return{format:u,formatPrefix:h}}var gh,yh,Jd;Zv({thousands:",",grouping:[3],currency:["$",""]});function Zv(t){return gh=Kv(t),yh=gh.format,Jd=gh.formatPrefix,gh}function Qv(t){return Math.max(0,-Eo(Math.abs(t)))}function Jv(t,e){return Math.max(0,Math.max(-8,Math.min(8,Math.floor(Eo(e)/3)))*3-Eo(Math.abs(t)))}function t6(t,e){return t=Math.abs(t),e=Math.abs(e)-t,Math.max(0,Eo(e)-Eo(t))+1}var te=1e-6,Hl=1e-12,Ae=Math.PI,rr=Ae/2,mh=Ae/4,Qr=Ae*2,Ue=180/Ae,re=Ae/180,Ne=Math.abs,So=Math.atan,Jr=Math.atan2,Kt=Math.cos,bh=Math.ceil,e6=Math.exp,t2=Math.hypot,_h=Math.log,e2=Math.pow,Ht=Math.sin,Dn=Math.sign||function(t){return t>0?1:t<0?-1:0},Sr=Math.sqrt,r2=Math.tan;function r6(t){return t>1?0:t<-1?Ae:Math.acos(t)}function tn(t){return t>1?rr:t<-1?-rr:Math.asin(t)}function n6(t){return(t=Ht(t/2))*t}function Je(){}function vh(t,e){t&&a6.hasOwnProperty(t.type)&&a6[t.type](t,e)}var i6={Feature:function(t,e){vh(t.geometry,e)},FeatureCollection:function(t,e){for(var r=t.features,n=-1,i=r.length;++n=0?1:-1,i=n*r,a=Kt(e),s=Ht(e),o=s2*s,l=a2*a+o*Kt(i),u=o*n*Ht(i);xh.add(Jr(u,l)),i2=t,a2=a,s2=s}function cq(t){return kh=new _r,ti(t,Si),kh*2}function wh(t){return[Jr(t[1],t[0]),tn(t[2])]}function Cs(t){var e=t[0],r=t[1],n=Kt(r);return[n*Kt(e),n*Ht(e),Ht(r)]}function Th(t,e){return t[0]*e[0]+t[1]*e[1]+t[2]*e[2]}function Ao(t,e){return[t[1]*e[2]-t[2]*e[1],t[2]*e[0]-t[0]*e[2],t[0]*e[1]-t[1]*e[0]]}function o2(t,e){t[0]+=e[0],t[1]+=e[1],t[2]+=e[2]}function Eh(t,e){return[t[0]*e,t[1]*e,t[2]*e]}function Ch(t){var e=Sr(t[0]*t[0]+t[1]*t[1]+t[2]*t[2]);t[0]/=e,t[1]/=e,t[2]/=e}var tr,pn,nr,En,Ss,u6,h6,Mo,Gl,Ba,Qi,Ji={point:l2,lineStart:d6,lineEnd:p6,polygonStart:function(){Ji.point=g6,Ji.lineStart=uq,Ji.lineEnd=hq,Gl=new _r,Si.polygonStart()},polygonEnd:function(){Si.polygonEnd(),Ji.point=l2,Ji.lineStart=d6,Ji.lineEnd=p6,xh<0?(tr=-(nr=180),pn=-(En=90)):Gl>te?En=90:Gl<-te&&(pn=-90),Qi[0]=tr,Qi[1]=nr},sphere:function(){tr=-(nr=180),pn=-(En=90)}};function l2(t,e){Ba.push(Qi=[tr=t,nr=t]),eEn&&(En=e)}function f6(t,e){var r=Cs([t*re,e*re]);if(Mo){var n=Ao(Mo,r),i=[n[1],-n[0],0],a=Ao(i,n);Ch(a),a=wh(a);var s=t-Ss,o=s>0?1:-1,l=a[0]*Ue*o,u,h=Ne(s)>180;h^(o*SsEn&&(En=u)):(l=(l+360)%360-180,h^(o*SsEn&&(En=e))),h?tCn(tr,nr)&&(nr=t):Cn(t,nr)>Cn(tr,nr)&&(tr=t):nr>=tr?(tnr&&(nr=t)):t>Ss?Cn(tr,t)>Cn(tr,nr)&&(nr=t):Cn(t,nr)>Cn(tr,nr)&&(tr=t)}else Ba.push(Qi=[tr=t,nr=t]);eEn&&(En=e),Mo=r,Ss=t}function d6(){Ji.point=f6}function p6(){Qi[0]=tr,Qi[1]=nr,Ji.point=l2,Mo=null}function g6(t,e){if(Mo){var r=t-Ss;Gl.add(Ne(r)>180?r+(r>0?360:-360):r)}else u6=t,h6=e;Si.point(t,e),f6(t,e)}function uq(){Si.lineStart()}function hq(){g6(u6,h6),Si.lineEnd(),Ne(Gl)>te&&(tr=-(nr=180)),Qi[0]=tr,Qi[1]=nr,Mo=null}function Cn(t,e){return(e-=t)<0?e+360:e}function fq(t,e){return t[0]-e[0]}function y6(t,e){return t[0]<=t[1]?t[0]<=e&&e<=t[1]:eCn(n[0],n[1])&&(n[1]=i[1]),Cn(i[0],n[1])>Cn(n[0],n[1])&&(n[0]=i[0])):a.push(n=i);for(s=-1/0,r=a.length-1,e=0,n=a[r];e<=r;n=i,++e)i=a[e],(o=Cn(n[1],i[0]))>s&&(s=o,tr=i[0],nr=n[1])}return Ba=Qi=null,tr===1/0||pn===1/0?[[NaN,NaN],[NaN,NaN]]:[[tr,pn],[nr,En]]}var jl,Sh,Ah,Mh,Lh,Rh,Ih,Nh,c2,u2,h2,m6,b6,en,rn,nn,ei={sphere:Je,point:f2,lineStart:_6,lineEnd:v6,polygonStart:function(){ei.lineStart=yq,ei.lineEnd=mq},polygonEnd:function(){ei.lineStart=_6,ei.lineEnd=v6}};function f2(t,e){t*=re,e*=re;var r=Kt(e);$l(r*Kt(t),r*Ht(t),Ht(e))}function $l(t,e,r){++jl,Ah+=(t-Ah)/jl,Mh+=(e-Mh)/jl,Lh+=(r-Lh)/jl}function _6(){ei.point=pq}function pq(t,e){t*=re,e*=re;var r=Kt(e);en=r*Kt(t),rn=r*Ht(t),nn=Ht(e),ei.point=gq,$l(en,rn,nn)}function gq(t,e){t*=re,e*=re;var r=Kt(e),n=r*Kt(t),i=r*Ht(t),a=Ht(e),s=Jr(Sr((s=rn*a-nn*i)*s+(s=nn*n-en*a)*s+(s=en*i-rn*n)*s),en*n+rn*i+nn*a);Sh+=s,Rh+=s*(en+(en=n)),Ih+=s*(rn+(rn=i)),Nh+=s*(nn+(nn=a)),$l(en,rn,nn)}function v6(){ei.point=f2}function yq(){ei.point=bq}function mq(){x6(m6,b6),ei.point=f2}function bq(t,e){m6=t,b6=e,t*=re,e*=re,ei.point=x6;var r=Kt(e);en=r*Kt(t),rn=r*Ht(t),nn=Ht(e),$l(en,rn,nn)}function x6(t,e){t*=re,e*=re;var r=Kt(e),n=r*Kt(t),i=r*Ht(t),a=Ht(e),s=rn*a-nn*i,o=nn*n-en*a,l=en*i-rn*n,u=t2(s,o,l),h=tn(u),d=u&&-h/u;c2.add(d*s),u2.add(d*o),h2.add(d*l),Sh+=h,Rh+=h*(en+(en=n)),Ih+=h*(rn+(rn=i)),Nh+=h*(nn+(nn=a)),$l(en,rn,nn)}function _q(t){jl=Sh=Ah=Mh=Lh=Rh=Ih=Nh=0,c2=new _r,u2=new _r,h2=new _r,ti(t,ei);var e=+c2,r=+u2,n=+h2,i=t2(e,r,n);return iAe?t+Math.round(-t/Qr)*Qr:t,e]}p2.invert=p2;function g2(t,e,r){return(t%=Qr)?e||r?d2(w6(t),T6(e,r)):w6(t):e||r?T6(e,r):p2}function k6(t){return function(e,r){return e+=t,[e>Ae?e-Qr:e<-Ae?e+Qr:e,r]}}function w6(t){var e=k6(t);return e.invert=k6(-t),e}function T6(t,e){var r=Kt(t),n=Ht(t),i=Kt(e),a=Ht(e);function s(o,l){var u=Kt(l),h=Kt(o)*u,d=Ht(o)*u,f=Ht(l),p=f*r+h*n;return[Jr(d*i-p*a,h*r-f*n),tn(p*i+d*a)]}return s.invert=function(o,l){var u=Kt(l),h=Kt(o)*u,d=Ht(o)*u,f=Ht(l),p=f*i-d*a;return[Jr(d*i+f*a,h*r+p*n),tn(p*r-h*n)]},s}function E6(t){t=g2(t[0]*re,t[1]*re,t.length>2?t[2]*re:0);function e(r){return r=t(r[0]*re,r[1]*re),r[0]*=Ue,r[1]*=Ue,r}return e.invert=function(r){return r=t.invert(r[0]*re,r[1]*re),r[0]*=Ue,r[1]*=Ue,r},e}function C6(t,e,r,n,i,a){if(!!r){var s=Kt(e),o=Ht(e),l=n*r;i==null?(i=e+n*Qr,a=e-l/2):(i=S6(s,i),a=S6(s,a),(n>0?ia)&&(i+=n*Qr));for(var u,h=i;n>0?h>a:h1&&t.push(t.pop().concat(t.shift()))},result:function(){var r=t;return t=[],e=null,r}}}function Bh(t,e){return Ne(t[0]-e[0])=0;--o)i.point((d=h[o])[0],d[1]);else n(f.x,f.p.x,-1,i);f=f.p}f=f.o,h=f.z,p=!p}while(!f.v);i.lineEnd()}}}function L6(t){if(!!(e=t.length)){for(var e,r=0,n=t[0],i;++r=0?1:-1,L=A*R,v=L>Ae,B=y*M;if(l.add(Jr(B*A*Ht(L),b*S+B*Kt(L))),s+=v?R+A*Qr:R,v^m>=r^T>=r){var w=Ao(Cs(p),Cs(k));Ch(w);var D=Ao(a,w);Ch(D);var N=(v^R>=0?-1:1)*tn(D[2]);(n>N||n===N&&(w[0]||w[1]))&&(o+=v^R>=0?1:-1)}}return(s<-te||s0){for(l||(i.polygonStart(),l=!0),i.lineStart(),M=0;M1&&T&2&&C.push(C.pop().concat(C.shift())),h.push(C.filter(xq))}}return f}}function xq(t){return t.length>1}function kq(t,e){return((t=t.x)[0]<0?t[1]-rr-te:rr-t[1])-((e=e.x)[0]<0?e[1]-rr-te:rr-e[1])}const m2=I6(function(){return!0},wq,Eq,[-Ae,-rr]);function wq(t){var e=NaN,r=NaN,n=NaN,i;return{lineStart:function(){t.lineStart(),i=1},point:function(a,s){var o=a>0?Ae:-Ae,l=Ne(a-e);Ne(l-Ae)0?rr:-rr),t.point(n,r),t.lineEnd(),t.lineStart(),t.point(o,r),t.point(a,r),i=0):n!==o&&l>=Ae&&(Ne(e-n)te?So((Ht(e)*(a=Kt(n))*Ht(r)-Ht(n)*(i=Kt(e))*Ht(t))/(i*a*s)):(e+n)/2}function Eq(t,e,r,n){var i;if(t==null)i=r*rr,n.point(-Ae,i),n.point(0,i),n.point(Ae,i),n.point(Ae,0),n.point(Ae,-i),n.point(0,-i),n.point(-Ae,-i),n.point(-Ae,0),n.point(-Ae,i);else if(Ne(t[0]-e[0])>te){var a=t[0]0,i=Ne(e)>te;function a(h,d,f,p){C6(p,t,r,f,h,d)}function s(h,d){return Kt(h)*Kt(d)>e}function o(h){var d,f,p,m,_;return{lineStart:function(){m=p=!1,_=1},point:function(y,b){var x=[y,b],k,T=s(y,b),C=n?T?0:u(y,b):T?u(y+(y<0?Ae:-Ae),b):0;if(!d&&(m=p=T)&&h.lineStart(),T!==p&&(k=l(d,x),(!k||Bh(d,k)||Bh(x,k))&&(x[2]=1)),T!==p)_=0,T?(h.lineStart(),k=l(x,d),h.point(k[0],k[1])):(k=l(d,x),h.point(k[0],k[1],2),h.lineEnd()),d=k;else if(i&&d&&n^T){var M;!(C&f)&&(M=l(x,d,!0))&&(_=0,n?(h.lineStart(),h.point(M[0][0],M[0][1]),h.point(M[1][0],M[1][1]),h.lineEnd()):(h.point(M[1][0],M[1][1]),h.lineEnd(),h.lineStart(),h.point(M[0][0],M[0][1],3)))}T&&(!d||!Bh(d,x))&&h.point(x[0],x[1]),d=x,p=T,f=C},lineEnd:function(){p&&h.lineEnd(),d=null},clean:function(){return _|(m&&p)<<1}}}function l(h,d,f){var p=Cs(h),m=Cs(d),_=[1,0,0],y=Ao(p,m),b=Th(y,y),x=y[0],k=b-x*x;if(!k)return!f&&h;var T=e*b/k,C=-e*x/k,M=Ao(_,y),S=Eh(_,T),R=Eh(y,C);o2(S,R);var A=M,L=Th(S,A),v=Th(A,A),B=L*L-v*(Th(S,S)-1);if(!(B<0)){var w=Sr(B),D=Eh(A,(-L-w)/v);if(o2(D,S),D=wh(D),!f)return D;var N=h[0],z=d[0],X=h[1],ct=d[1],J;z0^D[1]<(Ne(D[0]-N)Ae^(N<=D[0]&&D[0]<=z)){var ut=Eh(A,(-L+w)/v);return o2(ut,S),[D,wh(ut)]}}}function u(h,d){var f=n?t:Ae-t,p=0;return h<-f?p|=1:h>f&&(p|=2),d<-f?p|=4:d>f&&(p|=8),p}return I6(s,o,a,n?[0,-t]:[-Ae,t-Ae])}function Cq(t,e,r,n,i,a){var s=t[0],o=t[1],l=e[0],u=e[1],h=0,d=1,f=l-s,p=u-o,m;if(m=r-s,!(!f&&m>0)){if(m/=f,f<0){if(m0){if(m>d)return;m>h&&(h=m)}if(m=i-s,!(!f&&m<0)){if(m/=f,f<0){if(m>d)return;m>h&&(h=m)}else if(f>0){if(m0)){if(m/=p,p<0){if(m0){if(m>d)return;m>h&&(h=m)}if(m=a-o,!(!p&&m<0)){if(m/=p,p<0){if(m>d)return;m>h&&(h=m)}else if(p>0){if(m0&&(t[0]=s+h*f,t[1]=o+h*p),d<1&&(e[0]=s+d*f,e[1]=o+d*p),!0}}}}}var Xl=1e9,Oh=-Xl;function Fh(t,e,r,n){function i(u,h){return t<=u&&u<=r&&e<=h&&h<=n}function a(u,h,d,f){var p=0,m=0;if(u==null||(p=s(u,d))!==(m=s(h,d))||l(u,h)<0^d>0)do f.point(p===0||p===3?t:r,p>1?n:e);while((p=(p+d+4)%4)!==m);else f.point(h[0],h[1])}function s(u,h){return Ne(u[0]-t)0?0:3:Ne(u[0]-r)0?2:1:Ne(u[1]-e)0?1:0:h>0?3:2}function o(u,h){return l(u.x,h.x)}function l(u,h){var d=s(u,1),f=s(h,1);return d!==f?d-f:d===0?h[1]-u[1]:d===1?u[0]-h[0]:d===2?u[1]-h[1]:h[0]-u[0]}return function(u){var h=u,d=A6(),f,p,m,_,y,b,x,k,T,C,M,S={point:R,lineStart:B,lineEnd:w,polygonStart:L,polygonEnd:v};function R(N,z){i(N,z)&&h.point(N,z)}function A(){for(var N=0,z=0,X=p.length;zn&&(W-lt)*(n-ut)>(tt-ut)*(t-lt)&&++N:tt<=n&&(W-lt)*(n-ut)<(tt-ut)*(t-lt)&&--N;return N}function L(){h=d,f=[],p=[],M=!0}function v(){var N=A(),z=M&&N,X=(f=j0(f)).length;(z||X)&&(u.polygonStart(),z&&(u.lineStart(),a(null,null,1,u),u.lineEnd()),X&&M6(f,o,N,a,u),u.polygonEnd()),h=u,f=p=m=null}function B(){S.point=D,p&&p.push(m=[]),C=!0,T=!1,x=k=NaN}function w(){f&&(D(_,y),b&&T&&d.rejoin(),f.push(d.result())),S.point=R,T&&h.lineEnd()}function D(N,z){var X=i(N,z);if(p&&m.push([N,z]),C)_=N,y=z,b=X,C=!1,X&&(h.lineStart(),h.point(N,z));else if(X&&T)h.point(N,z);else{var ct=[x=Math.max(Oh,Math.min(Xl,x)),k=Math.max(Oh,Math.min(Xl,k))],J=[N=Math.max(Oh,Math.min(Xl,N)),z=Math.max(Oh,Math.min(Xl,z))];Cq(ct,J,t,e,r,n)?(T||(h.lineStart(),h.point(ct[0],ct[1])),h.point(J[0],J[1]),X||h.lineEnd(),M=!1):X&&(h.lineStart(),h.point(N,z),M=!1)}x=N,k=z,T=X}return S}}function Sq(){var t=0,e=0,r=960,n=500,i,a,s;return s={stream:function(o){return i&&a===o?i:i=Fh(t,e,r,n)(a=o)},extent:function(o){return arguments.length?(t=+o[0][0],e=+o[0][1],r=+o[1][0],n=+o[1][1],i=a=null,s):[[t,e],[r,n]]}}}var b2,_2,Ph,qh,Ro={sphere:Je,point:Je,lineStart:Aq,lineEnd:Je,polygonStart:Je,polygonEnd:Je};function Aq(){Ro.point=Lq,Ro.lineEnd=Mq}function Mq(){Ro.point=Ro.lineEnd=Je}function Lq(t,e){t*=re,e*=re,_2=t,Ph=Ht(e),qh=Kt(e),Ro.point=Rq}function Rq(t,e){t*=re,e*=re;var r=Ht(e),n=Kt(e),i=Ne(t-_2),a=Kt(i),s=Ht(i),o=n*s,l=qh*r-Ph*n*a,u=Ph*r+qh*n*a;b2.add(Jr(Sr(o*o+l*l),u)),_2=t,Ph=r,qh=n}function B6(t){return b2=new _r,ti(t,Ro),+b2}var v2=[null,null],Iq={type:"LineString",coordinates:v2};function Vh(t,e){return v2[0]=t,v2[1]=e,B6(Iq)}var D6={Feature:function(t,e){return zh(t.geometry,e)},FeatureCollection:function(t,e){for(var r=t.features,n=-1,i=r.length;++n0&&(i=Vh(t[a],t[a-1]),i>0&&r<=i&&n<=i&&(r+n-i)*(1-Math.pow((r-n)/i,2))te}).map(f)).concat(Ca(bh(a/u)*u,i,u).filter(function(k){return Ne(k%d)>te}).map(p))}return b.lines=function(){return x().map(function(k){return{type:"LineString",coordinates:k}})},b.outline=function(){return{type:"Polygon",coordinates:[m(n).concat(_(s).slice(1),m(r).reverse().slice(1),_(o).reverse().slice(1))]}},b.extent=function(k){return arguments.length?b.extentMajor(k).extentMinor(k):b.extentMinor()},b.extentMajor=function(k){return arguments.length?(n=+k[0][0],r=+k[1][0],o=+k[0][1],s=+k[1][1],n>r&&(k=n,n=r,r=k),o>s&&(k=o,o=s,s=k),b.precision(y)):[[n,o],[r,s]]},b.extentMinor=function(k){return arguments.length?(e=+k[0][0],t=+k[1][0],a=+k[0][1],i=+k[1][1],e>t&&(k=e,e=t,t=k),a>i&&(k=a,a=i,i=k),b.precision(y)):[[e,a],[t,i]]},b.step=function(k){return arguments.length?b.stepMajor(k).stepMinor(k):b.stepMinor()},b.stepMajor=function(k){return arguments.length?(h=+k[0],d=+k[1],b):[h,d]},b.stepMinor=function(k){return arguments.length?(l=+k[0],u=+k[1],b):[l,u]},b.precision=function(k){return arguments.length?(y=+k,f=z6(a,i,90),p=Y6(e,t,y),m=z6(o,s,90),_=Y6(n,r,y),b):y},b.extentMajor([[-180,-90+te],[180,90-te]]).extentMinor([[-180,-80-te],[180,80+te]])}function Dq(){return U6()()}function Oq(t,e){var r=t[0]*re,n=t[1]*re,i=e[0]*re,a=e[1]*re,s=Kt(n),o=Ht(n),l=Kt(a),u=Ht(a),h=s*Kt(r),d=s*Ht(r),f=l*Kt(i),p=l*Ht(i),m=2*tn(Sr(n6(a-n)+s*l*n6(i-r))),_=Ht(m),y=m?function(b){var x=Ht(b*=m)/_,k=Ht(m-b)/_,T=k*h+x*f,C=k*d+x*p,M=k*o+x*u;return[Jr(C,T)*Ue,Jr(M,Sr(T*T+C*C))*Ue]}:function(){return[r*Ue,n*Ue]};return y.distance=m,y}const Kl=t=>t;var x2=new _r,k2=new _r,W6,H6,w2,T2,Da={point:Je,lineStart:Je,lineEnd:Je,polygonStart:function(){Da.lineStart=Fq,Da.lineEnd=qq},polygonEnd:function(){Da.lineStart=Da.lineEnd=Da.point=Je,x2.add(Ne(k2)),k2=new _r},result:function(){var t=x2/2;return x2=new _r,t}};function Fq(){Da.point=Pq}function Pq(t,e){Da.point=G6,W6=w2=t,H6=T2=e}function G6(t,e){k2.add(T2*t-w2*e),w2=t,T2=e}function qq(){G6(W6,H6)}const j6=Da;var Io=1/0,Yh=Io,Zl=-Io,Uh=Zl,Vq={point:zq,lineStart:Je,lineEnd:Je,polygonStart:Je,polygonEnd:Je,result:function(){var t=[[Io,Yh],[Zl,Uh]];return Zl=Uh=-(Yh=Io=1/0),t}};function zq(t,e){tZl&&(Zl=t),eUh&&(Uh=e)}const Wh=Vq;var E2=0,C2=0,Ql=0,Hh=0,Gh=0,No=0,S2=0,A2=0,Jl=0,$6,X6,Ai,Mi,ri={point:As,lineStart:K6,lineEnd:Z6,polygonStart:function(){ri.lineStart=Wq,ri.lineEnd=Hq},polygonEnd:function(){ri.point=As,ri.lineStart=K6,ri.lineEnd=Z6},result:function(){var t=Jl?[S2/Jl,A2/Jl]:No?[Hh/No,Gh/No]:Ql?[E2/Ql,C2/Ql]:[NaN,NaN];return E2=C2=Ql=Hh=Gh=No=S2=A2=Jl=0,t}};function As(t,e){E2+=t,C2+=e,++Ql}function K6(){ri.point=Yq}function Yq(t,e){ri.point=Uq,As(Ai=t,Mi=e)}function Uq(t,e){var r=t-Ai,n=e-Mi,i=Sr(r*r+n*n);Hh+=i*(Ai+t)/2,Gh+=i*(Mi+e)/2,No+=i,As(Ai=t,Mi=e)}function Z6(){ri.point=As}function Wq(){ri.point=Gq}function Hq(){Q6($6,X6)}function Gq(t,e){ri.point=Q6,As($6=Ai=t,X6=Mi=e)}function Q6(t,e){var r=t-Ai,n=e-Mi,i=Sr(r*r+n*n);Hh+=i*(Ai+t)/2,Gh+=i*(Mi+e)/2,No+=i,i=Mi*t-Ai*e,S2+=i*(Ai+t),A2+=i*(Mi+e),Jl+=i*3,As(Ai=t,Mi=e)}const J6=ri;function tx(t){this._context=t}tx.prototype={_radius:4.5,pointRadius:function(t){return this._radius=t,this},polygonStart:function(){this._line=0},polygonEnd:function(){this._line=NaN},lineStart:function(){this._point=0},lineEnd:function(){this._line===0&&this._context.closePath(),this._point=NaN},point:function(t,e){switch(this._point){case 0:{this._context.moveTo(t,e),this._point=1;break}case 1:{this._context.lineTo(t,e);break}default:{this._context.moveTo(t+this._radius,e),this._context.arc(t,e,this._radius,0,Qr);break}}},result:Je};var M2=new _r,L2,ex,rx,tc,ec,jh={point:Je,lineStart:function(){jh.point=jq},lineEnd:function(){L2&&nx(ex,rx),jh.point=Je},polygonStart:function(){L2=!0},polygonEnd:function(){L2=null},result:function(){var t=+M2;return M2=new _r,t}};function jq(t,e){jh.point=nx,ex=tc=t,rx=ec=e}function nx(t,e){tc-=t,ec-=e,M2.add(Sr(tc*tc+ec*ec)),tc=t,ec=e}const ix=jh;function ax(){this._string=[]}ax.prototype={_radius:4.5,_circle:sx(4.5),pointRadius:function(t){return(t=+t)!==this._radius&&(this._radius=t,this._circle=null),this},polygonStart:function(){this._line=0},polygonEnd:function(){this._line=NaN},lineStart:function(){this._point=0},lineEnd:function(){this._line===0&&this._string.push("Z"),this._point=NaN},point:function(t,e){switch(this._point){case 0:{this._string.push("M",t,",",e),this._point=1;break}case 1:{this._string.push("L",t,",",e);break}default:{this._circle==null&&(this._circle=sx(this._radius)),this._string.push("M",t,",",e,this._circle);break}}},result:function(){if(this._string.length){var t=this._string.join("");return this._string=[],t}else return null}};function sx(t){return"m0,"+t+"a"+t+","+t+" 0 1,1 0,"+-2*t+"a"+t+","+t+" 0 1,1 0,"+2*t+"z"}function $q(t,e){var r=4.5,n,i;function a(s){return s&&(typeof r=="function"&&i.pointRadius(+r.apply(this,arguments)),ti(s,n(i))),i.result()}return a.area=function(s){return ti(s,n(j6)),j6.result()},a.measure=function(s){return ti(s,n(ix)),ix.result()},a.bounds=function(s){return ti(s,n(Wh)),Wh.result()},a.centroid=function(s){return ti(s,n(J6)),J6.result()},a.projection=function(s){return arguments.length?(n=s==null?(t=null,Kl):(t=s).stream,a):t},a.context=function(s){return arguments.length?(i=s==null?(e=null,new ax):new tx(e=s),typeof r!="function"&&i.pointRadius(r),a):e},a.pointRadius=function(s){return arguments.length?(r=typeof s=="function"?s:(i.pointRadius(+s),+s),a):r},a.projection(t).context(e)}function Xq(t){return{stream:rc(t)}}function rc(t){return function(e){var r=new R2;for(var n in t)r[n]=t[n];return r.stream=e,r}}function R2(){}R2.prototype={constructor:R2,point:function(t,e){this.stream.point(t,e)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}};function I2(t,e,r){var n=t.clipExtent&&t.clipExtent();return t.scale(150).translate([0,0]),n!=null&&t.clipExtent(null),ti(r,t.stream(Wh)),e(Wh.result()),n!=null&&t.clipExtent(n),t}function $h(t,e,r){return I2(t,function(n){var i=e[1][0]-e[0][0],a=e[1][1]-e[0][1],s=Math.min(i/(n[1][0]-n[0][0]),a/(n[1][1]-n[0][1])),o=+e[0][0]+(i-s*(n[1][0]+n[0][0]))/2,l=+e[0][1]+(a-s*(n[1][1]+n[0][1]))/2;t.scale(150*s).translate([o,l])},r)}function N2(t,e,r){return $h(t,[[0,0],e],r)}function B2(t,e,r){return I2(t,function(n){var i=+e,a=i/(n[1][0]-n[0][0]),s=(i-a*(n[1][0]+n[0][0]))/2,o=-a*n[0][1];t.scale(150*a).translate([s,o])},r)}function D2(t,e,r){return I2(t,function(n){var i=+e,a=i/(n[1][1]-n[0][1]),s=-a*n[0][0],o=(i-a*(n[1][1]+n[0][1]))/2;t.scale(150*a).translate([s,o])},r)}var ox=16,Kq=Kt(30*re);function lx(t,e){return+e?Qq(t,e):Zq(t)}function Zq(t){return rc({point:function(e,r){e=t(e,r),this.stream.point(e[0],e[1])}})}function Qq(t,e){function r(n,i,a,s,o,l,u,h,d,f,p,m,_,y){var b=u-n,x=h-i,k=b*b+x*x;if(k>4*e&&_--){var T=s+f,C=o+p,M=l+m,S=Sr(T*T+C*C+M*M),R=tn(M/=S),A=Ne(Ne(M)-1)e||Ne((b*w+x*D)/k-.5)>.3||s*f+o*p+l*m2?N[2]%360*re:0,w()):[o*Ue,l*Ue,u*Ue]},v.angle=function(N){return arguments.length?(d=N%360*re,w()):d*Ue},v.reflectX=function(N){return arguments.length?(f=N?-1:1,w()):f<0},v.reflectY=function(N){return arguments.length?(p=N?-1:1,w()):p<0},v.precision=function(N){return arguments.length?(M=lx(S,C=N*N),D()):Sr(C)},v.fitExtent=function(N,z){return $h(v,N,z)},v.fitSize=function(N,z){return N2(v,N,z)},v.fitWidth=function(N,z){return B2(v,N,z)},v.fitHeight=function(N,z){return D2(v,N,z)};function w(){var N=cx(r,0,0,f,p,d).apply(null,e(a,s)),z=cx(r,n-N[0],i-N[1],f,p,d);return h=g2(o,l,u),S=d2(e,z),R=d2(h,S),M=lx(S,C),D()}function D(){return A=L=null,v}return function(){return e=t.apply(this,arguments),v.invert=e.invert&&B,w()}}function F2(t){var e=0,r=Ae/3,n=O2(t),i=n(e,r);return i.parallels=function(a){return arguments.length?n(e=a[0]*re,r=a[1]*re):[e*Ue,r*Ue]},i}function rV(t){var e=Kt(t);function r(n,i){return[n*e,Ht(i)/e]}return r.invert=function(n,i){return[n/e,tn(i*e)]},r}function ux(t,e){var r=Ht(t),n=(r+Ht(e))/2;if(Ne(n)=.12&&y<.234&&_>=-.425&&_<-.214?i:y>=.166&&y<.234&&_>=-.214&&_<-.115?s:r).invert(f)},h.stream=function(f){return t&&e===f?t:t=nV([r.stream(e=f),i.stream(f),s.stream(f)])},h.precision=function(f){return arguments.length?(r.precision(f),i.precision(f),s.precision(f),d()):r.precision()},h.scale=function(f){return arguments.length?(r.scale(f),i.scale(f*.35),s.scale(f),h.translate(r.translate())):r.scale()},h.translate=function(f){if(!arguments.length)return r.translate();var p=r.scale(),m=+f[0],_=+f[1];return n=r.translate(f).clipExtent([[m-.455*p,_-.238*p],[m+.455*p,_+.238*p]]).stream(u),a=i.translate([m-.307*p,_+.201*p]).clipExtent([[m-.425*p+te,_+.12*p+te],[m-.214*p-te,_+.234*p-te]]).stream(u),o=s.translate([m-.205*p,_+.212*p]).clipExtent([[m-.214*p+te,_+.166*p+te],[m-.115*p-te,_+.234*p-te]]).stream(u),d()},h.fitExtent=function(f,p){return $h(h,f,p)},h.fitSize=function(f,p){return N2(h,f,p)},h.fitWidth=function(f,p){return B2(h,f,p)},h.fitHeight=function(f,p){return D2(h,f,p)};function d(){return t=e=null,h}return h.scale(1070)}function fx(t){return function(e,r){var n=Kt(e),i=Kt(r),a=t(n*i);return a===1/0?[2,0]:[a*i*Ht(e),a*Ht(r)]}}function nc(t){return function(e,r){var n=Sr(e*e+r*r),i=t(n),a=Ht(i),s=Kt(i);return[Jr(e*a,n*s),tn(n&&r*a/n)]}}var P2=fx(function(t){return Sr(2/(1+t))});P2.invert=nc(function(t){return 2*tn(t/2)});function aV(){return Li(P2).scale(124.75).clipAngle(180-.001)}var q2=fx(function(t){return(t=r6(t))&&t/Ht(t)});q2.invert=nc(function(t){return t});function sV(){return Li(q2).scale(79.4188).clipAngle(180-.001)}function ic(t,e){return[t,_h(r2((rr+e)/2))]}ic.invert=function(t,e){return[t,2*So(e6(e))-rr]};function oV(){return dx(ic).scale(961/Qr)}function dx(t){var e=Li(t),r=e.center,n=e.scale,i=e.translate,a=e.clipExtent,s=null,o,l,u;e.scale=function(d){return arguments.length?(n(d),h()):n()},e.translate=function(d){return arguments.length?(i(d),h()):i()},e.center=function(d){return arguments.length?(r(d),h()):r()},e.clipExtent=function(d){return arguments.length?(d==null?s=o=l=u=null:(s=+d[0][0],o=+d[0][1],l=+d[1][0],u=+d[1][1]),h()):s==null?null:[[s,o],[l,u]]};function h(){var d=Ae*n(),f=e(E6(e.rotate()).invert([0,0]));return a(s==null?[[f[0]-d,f[1]-d],[f[0]+d,f[1]+d]]:t===ic?[[Math.max(f[0]-d,s),o],[Math.min(f[0]+d,l),u]]:[[s,Math.max(f[1]-d,o)],[l,Math.min(f[1]+d,u)]])}return h()}function Kh(t){return r2((rr+t)/2)}function px(t,e){var r=Kt(t),n=t===e?Ht(t):_h(r/Kt(e))/_h(Kh(e)/Kh(t)),i=r*e2(Kh(t),n)/n;if(!n)return ic;function a(s,o){i>0?o<-rr+te&&(o=-rr+te):o>rr-te&&(o=rr-te);var l=i/e2(Kh(o),n);return[l*Ht(n*s),i-l*Kt(n*s)]}return a.invert=function(s,o){var l=i-o,u=Dn(n)*Sr(s*s+l*l),h=Jr(s,Ne(l))*Dn(l);return l*n<0&&(h-=Ae*Dn(s)*Dn(l)),[h/n,2*So(e2(i/u,1/n))-rr]},a}function lV(){return F2(px).scale(109.5).parallels([30,30])}function ac(t,e){return[t,e]}ac.invert=ac;function cV(){return Li(ac).scale(152.63)}function gx(t,e){var r=Kt(t),n=t===e?Ht(t):(r-Kt(e))/(e-t),i=r/n+t;if(Ne(n)te&&--n>0);return[t/(.8707+(a=r*r)*(-.131979+a*(-.013791+a*a*a*(.003971-.001529*a)))),r]};function gV(){return Li(Y2).scale(175.295)}function U2(t,e){return[Kt(e)*Ht(t),Ht(e)]}U2.invert=nc(tn);function yV(){return Li(U2).scale(249.5).clipAngle(90+te)}function W2(t,e){var r=Kt(e),n=1+Kt(t)*r;return[r*Ht(t)/n,Ht(e)/n]}W2.invert=nc(function(t){return 2*So(t)});function mV(){return Li(W2).scale(250).clipAngle(142)}function H2(t,e){return[_h(r2((rr+e)/2)),-t]}H2.invert=function(t,e){return[-e,2*So(e6(t))-rr]};function bV(){var t=dx(H2),e=t.center,r=t.rotate;return t.center=function(n){return arguments.length?e([-n[1],n[0]]):(n=e(),[n[1],-n[0]])},t.rotate=function(n){return arguments.length?r([n[0],n[1],n.length>2?n[2]+90:90]):(n=r(),[n[0],n[1],n[2]-90])},r([0,0,90]).scale(159.155)}function _V(t,e){return t.parent===e.parent?1:2}function vV(t){return t.reduce(xV,0)/t.length}function xV(t,e){return t+e.x}function kV(t){return 1+t.reduce(wV,0)}function wV(t,e){return Math.max(t,e.y)}function TV(t){for(var e;e=t.children;)t=e[0];return t}function EV(t){for(var e;e=t.children;)t=e[e.length-1];return t}function CV(){var t=_V,e=1,r=1,n=!1;function i(a){var s,o=0;a.eachAfter(function(f){var p=f.children;p?(f.x=vV(p),f.y=kV(p)):(f.x=s?o+=t(f,s):0,f.y=0,s=f)});var l=TV(a),u=EV(a),h=l.x-t(l,u)/2,d=u.x+t(u,l)/2;return a.eachAfter(n?function(f){f.x=(f.x-a.x)*e,f.y=(a.y-f.y)*r}:function(f){f.x=(f.x-h)/(d-h)*e,f.y=(1-(a.y?f.y/a.y:1))*r})}return i.separation=function(a){return arguments.length?(t=a,i):t},i.size=function(a){return arguments.length?(n=!1,e=+a[0],r=+a[1],i):n?null:[e,r]},i.nodeSize=function(a){return arguments.length?(n=!0,e=+a[0],r=+a[1],i):n?[e,r]:null},i}function SV(t){var e=0,r=t.children,n=r&&r.length;if(!n)e=1;else for(;--n>=0;)e+=r[n].value;t.value=e}function AV(){return this.eachAfter(SV)}function MV(t,e){let r=-1;for(const n of this)t.call(e,n,++r,this);return this}function LV(t,e){for(var r=this,n=[r],i,a,s=-1;r=n.pop();)if(t.call(e,r,++s,this),i=r.children)for(a=i.length-1;a>=0;--a)n.push(i[a]);return this}function RV(t,e){for(var r=this,n=[r],i=[],a,s,o,l=-1;r=n.pop();)if(i.push(r),a=r.children)for(s=0,o=a.length;s=0;)r+=n[i].value;e.value=r})}function BV(t){return this.eachBefore(function(e){e.children&&e.children.sort(t)})}function DV(t){for(var e=this,r=OV(e,t),n=[e];e!==r;)e=e.parent,n.push(e);for(var i=n.length;t!==r;)n.splice(i,0,t),t=t.parent;return n}function OV(t,e){if(t===e)return t;var r=t.ancestors(),n=e.ancestors(),i=null;for(t=r.pop(),e=n.pop();t===e;)i=t,t=r.pop(),e=n.pop();return i}function FV(){for(var t=this,e=[t];t=t.parent;)e.push(t);return e}function PV(){return Array.from(this)}function qV(){var t=[];return this.eachBefore(function(e){e.children||t.push(e)}),t}function VV(){var t=this,e=[];return t.each(function(r){r!==t&&e.push({source:r.parent,target:r})}),e}function*zV(){var t=this,e,r=[t],n,i,a;do for(e=r.reverse(),r=[];t=e.pop();)if(yield t,n=t.children)for(i=0,a=n.length;i=0;--o)i.push(a=s[o]=new Ms(s[o])),a.parent=n,a.depth=n.depth+1;return r.eachBefore(yx)}function YV(){return G2(this).eachBefore(HV)}function UV(t){return t.children}function WV(t){return Array.isArray(t)?t[1]:null}function HV(t){t.data.value!==void 0&&(t.value=t.data.value),t.data=t.data.data}function yx(t){var e=0;do t.height=e;while((t=t.parent)&&t.height<++e)}function Ms(t){this.data=t,this.depth=this.height=0,this.parent=null}Ms.prototype=G2.prototype={constructor:Ms,count:AV,each:MV,eachAfter:RV,eachBefore:LV,find:IV,sum:NV,sort:BV,path:DV,ancestors:FV,descendants:PV,leaves:qV,links:VV,copy:YV,[Symbol.iterator]:zV};function Qh(t){return t==null?null:mx(t)}function mx(t){if(typeof t!="function")throw new Error;return t}function Ls(){return 0}function Bo(t){return function(){return t}}const GV=1664525,jV=1013904223,bx=4294967296;function j2(){let t=1;return()=>(t=(GV*t+jV)%bx)/bx}function $V(t){return typeof t=="object"&&"length"in t?t:Array.from(t)}function XV(t,e){let r=t.length,n,i;for(;r;)i=e()*r--|0,n=t[r],t[r]=t[i],t[i]=n;return t}function KV(t){return _x(t,j2())}function _x(t,e){for(var r=0,n=(t=XV(Array.from(t),e)).length,i=[],a,s;r0&&r*r>n*n+i*i}function $2(t,e){for(var r=0;r1e-6?(v+Math.sqrt(v*v-4*L*B))/(2*L):B/v);return{x:n+M+S*w,y:i+R+A*w,r:w}}function kx(t,e,r){var n=t.x-e.x,i,a,s=t.y-e.y,o,l,u=n*n+s*s;u?(a=e.r+r.r,a*=a,l=t.r+r.r,l*=l,a>l?(i=(u+l-a)/(2*u),o=Math.sqrt(Math.max(0,l/u-i*i)),r.x=t.x-i*n-o*s,r.y=t.y-i*s+o*n):(i=(u+a-l)/(2*u),o=Math.sqrt(Math.max(0,a/u-i*i)),r.x=e.x+i*n-o*s,r.y=e.y+i*s+o*n)):(r.x=e.x+r.r,r.y=e.y)}function wx(t,e){var r=t.r+e.r-1e-6,n=e.x-t.x,i=e.y-t.y;return r>0&&r*r>n*n+i*i}function Tx(t){var e=t._,r=t.next._,n=e.r+r.r,i=(e.x*r.r+r.x*e.r)/n,a=(e.y*r.r+r.y*e.r)/n;return i*i+a*a}function tf(t){this._=t,this.next=null,this.previous=null}function Ex(t,e){if(!(a=(t=$V(t)).length))return 0;var r,n,i,a,s,o,l,u,h,d,f;if(r=t[0],r.x=0,r.y=0,!(a>1))return r.r;if(n=t[1],r.x=-n.r,n.x=r.r,n.y=0,!(a>2))return r.r+n.r;kx(n,r,i=t[2]),r=new tf(r),n=new tf(n),i=new tf(i),r.next=i.previous=n,n.next=r.previous=i,i.next=n.previous=r;t:for(l=3;llz(r(T,C,i))),x=b.map(Lx),k=new Set(b).add("");for(const T of x)k.has(T)||(k.add(T),b.push(T),x.push(Lx(T)),a.push(K2));s=(T,C)=>b[C],o=(T,C)=>x[C]}for(h=0,l=a.length;h=0&&(p=a[b],p.data===K2);--b)p.data=null}if(d.parent=iz,d.eachBefore(function(b){b.depth=b.parent.depth+1,--l}).eachBefore(yx),d.parent=null,l>0)throw new Error("cycle");return d}return n.id=function(i){return arguments.length?(t=Qh(i),n):t},n.parentId=function(i){return arguments.length?(e=Qh(i),n):e},n.path=function(i){return arguments.length?(r=Qh(i),n):r},n}function lz(t){t=`${t}`;let e=t.length;return Z2(t,e-1)&&!Z2(t,e-2)&&(t=t.slice(0,-1)),t[0]==="/"?t:`/${t}`}function Lx(t){let e=t.length;if(e<2)return"";for(;--e>1&&!Z2(t,e););return t.slice(0,e)}function Z2(t,e){if(t[e]==="/"){let r=0;for(;e>0&&t[--e]==="\\";)++r;if((r&1)===0)return!0}return!1}function cz(t,e){return t.parent===e.parent?1:2}function Q2(t){var e=t.children;return e?e[0]:t.t}function J2(t){var e=t.children;return e?e[e.length-1]:t.t}function uz(t,e,r){var n=r/(e.i-t.i);e.c-=n,e.s+=r,t.c+=n,e.z+=r,e.m+=r}function hz(t){for(var e=0,r=0,n=t.children,i=n.length,a;--i>=0;)a=n[i],a.z+=e,a.m+=e,e+=a.s+(r+=a.c)}function fz(t,e,r){return t.a.parent===e.parent?t.a:r}function ef(t,e){this._=t,this.parent=null,this.children=null,this.A=null,this.a=this,this.z=0,this.m=0,this.c=0,this.s=0,this.t=null,this.i=e}ef.prototype=Object.create(Ms.prototype);function dz(t){for(var e=new ef(t,0),r,n=[e],i,a,s,o;r=n.pop();)if(a=r._.children)for(r.children=new Array(o=a.length),s=o-1;s>=0;--s)n.push(i=r.children[s]=new ef(a[s],s)),i.parent=r;return(e.parent=new ef(null,0)).children=[e],e}function pz(){var t=cz,e=1,r=1,n=null;function i(u){var h=dz(u);if(h.eachAfter(a),h.parent.m=-h.z,h.eachBefore(s),n)u.eachBefore(l);else{var d=u,f=u,p=u;u.eachBefore(function(x){x.xf.x&&(f=x),x.depth>p.depth&&(p=x)});var m=d===f?1:t(d,f)/2,_=m-d.x,y=e/(f.x+m+_),b=r/(p.depth||1);u.eachBefore(function(x){x.x=(x.x+_)*y,x.y=x.depth*b})}return u}function a(u){var h=u.children,d=u.parent.children,f=u.i?d[u.i-1]:null;if(h){hz(u);var p=(h[0].z+h[h.length-1].z)/2;f?(u.z=f.z+t(u._,f._),u.m=u.z-p):u.z=p}else f&&(u.z=f.z+t(u._,f._));u.parent.A=o(u,f,u.parent.A||d[0])}function s(u){u._.x=u.z+u.parent.m,u.m+=u.parent.m}function o(u,h,d){if(h){for(var f=u,p=u,m=h,_=f.parent.children[0],y=f.m,b=p.m,x=m.m,k=_.m,T;m=J2(m),f=Q2(f),m&&f;)_=Q2(_),p=J2(p),p.a=u,T=m.z+x-f.z-y+t(m._,f._),T>0&&(uz(fz(m,u,d),u,T),y+=T,b+=T),x+=m.m,y+=f.m,k+=_.m,b+=p.m;m&&!J2(p)&&(p.t=m,p.m+=x-b),f&&!Q2(_)&&(_.t=f,_.m+=y-k,d=u)}return d}function l(u){u.x*=e,u.y=u.depth*r}return i.separation=function(u){return arguments.length?(t=u,i):t},i.size=function(u){return arguments.length?(n=!1,e=+u[0],r=+u[1],i):n?null:[e,r]},i.nodeSize=function(u){return arguments.length?(n=!0,e=+u[0],r=+u[1],i):n?[e,r]:null},i}function rf(t,e,r,n,i){for(var a=t.children,s,o=-1,l=a.length,u=t.value&&(i-r)/t.value;++ox&&(x=u),M=y*y*C,k=Math.max(x/M,M/b),k>T){y-=u;break}T=k}s.push(l={value:y,dice:p1?n:1)},r}(Rx);function gz(){var t=Nx,e=!1,r=1,n=1,i=[0],a=Ls,s=Ls,o=Ls,l=Ls,u=Ls;function h(f){return f.x0=f.y0=0,f.x1=r,f.y1=n,f.eachBefore(d),i=[0],e&&f.eachBefore(Ax),f}function d(f){var p=i[f.depth],m=f.x0+p,_=f.y0+p,y=f.x1-p,b=f.y1-p;y=f-1){var x=a[d];x.x0=m,x.y0=_,x.x1=y,x.y1=b;return}for(var k=u[d],T=p/2+k,C=d+1,M=f-1;C>>1;u[S]b-_){var L=p?(m*A+y*R)/p:y;h(d,C,R,m,_,L,b),h(C,f,A,L,_,y,b)}else{var v=p?(_*A+b*R)/p:b;h(d,C,R,m,_,y,v),h(C,f,A,m,v,y,b)}}}function mz(t,e,r,n,i){(t.depth&1?rf:hc)(t,e,r,n,i)}const bz=function t(e){function r(n,i,a,s,o){if((l=n._squarify)&&l.ratio===e)for(var l,u,h,d,f=-1,p,m=l.length,_=n.value;++f1?n:1)},r}(Rx);function _z(t){for(var e=-1,r=t.length,n,i=t[r-1],a=0;++e1&&xz(t[r[n-2]],t[r[n-1]],t[i])<=0;)--n;r[n++]=i}return r.slice(0,n)}function wz(t){if((r=t.length)<3)return null;var e,r,n=new Array(r),i=new Array(r);for(e=0;e=0;--e)u.push(t[n[a[e]][2]]);for(e=+o;ea!=o>a&&i<(s-l)*(a-u)/(o-u)+l&&(h=!h),s=l,o=u;return h}function Ez(t){for(var e=-1,r=t.length,n=t[r-1],i,a,s=n[0],o=n[1],l=0;++e1);return n+i*o*Math.sqrt(-2*Math.log(s)/s)}}return r.source=t,r}(Ir),Az=function t(e){var r=tp.source(e);function n(){var i=r.apply(this,arguments);return function(){return Math.exp(i())}}return n.source=t,n}(Ir),Dx=function t(e){function r(n){return(n=+n)<=0?()=>0:function(){for(var i=0,a=n;a>1;--a)i+=e();return i+a*e()}}return r.source=t,r}(Ir),Mz=function t(e){var r=Dx.source(e);function n(i){if((i=+i)==0)return e;var a=r(i);return function(){return a()/i}}return n.source=t,n}(Ir),Lz=function t(e){function r(n){return function(){return-Math.log1p(-e())/n}}return r.source=t,r}(Ir),Rz=function t(e){function r(n){if((n=+n)<0)throw new RangeError("invalid alpha");return n=1/-n,function(){return Math.pow(1-e(),n)}}return r.source=t,r}(Ir),Iz=function t(e){function r(n){if((n=+n)<0||n>1)throw new RangeError("invalid p");return function(){return Math.floor(e()+n)}}return r.source=t,r}(Ir),Ox=function t(e){function r(n){if((n=+n)<0||n>1)throw new RangeError("invalid p");return n===0?()=>1/0:n===1?()=>1:(n=Math.log1p(-n),function(){return 1+Math.floor(Math.log1p(-e())/n)})}return r.source=t,r}(Ir),ep=function t(e){var r=tp.source(e)();function n(i,a){if((i=+i)<0)throw new RangeError("invalid k");if(i===0)return()=>0;if(a=a==null?1:+a,i===1)return()=>-Math.log1p(-e())*a;var s=(i<1?i+1:i)-1/3,o=1/(3*Math.sqrt(s)),l=i<1?()=>Math.pow(e(),1/i):()=>1;return function(){do{do var u=r(),h=1+o*u;while(h<=0);h*=h*h;var d=1-e()}while(d>=1-.0331*u*u*u*u&&Math.log(d)>=.5*u*u+s*(1-h+Math.log(h)));return s*h*l()*a}}return n.source=t,n}(Ir),Fx=function t(e){var r=ep.source(e);function n(i,a){var s=r(i),o=r(a);return function(){var l=s();return l===0?0:l/(l+o())}}return n.source=t,n}(Ir),Px=function t(e){var r=Ox.source(e),n=Fx.source(e);function i(a,s){return a=+a,(s=+s)>=1?()=>a:s<=0?()=>0:function(){for(var o=0,l=a,u=s;l*u>16&&l*(1-u)>16;){var h=Math.floor((l+1)*u),d=n(h,l-h+1)();d<=u?(o+=h,l-=h,u=(u-d)/(1-d)):(l=h-1,u/=d)}for(var f=u<.5,p=f?u:1-u,m=r(p),_=m(),y=0;_<=l;++y)_+=m();return o+(f?y:l-y)}}return i.source=t,i}(Ir),Nz=function t(e){function r(n,i,a){var s;return(n=+n)==0?s=o=>-Math.log(o):(n=1/n,s=o=>Math.pow(o,n)),i=i==null?0:+i,a=a==null?1:+a,function(){return i+a*s(-Math.log1p(-e()))}}return r.source=t,r}(Ir),Bz=function t(e){function r(n,i){return n=n==null?0:+n,i=i==null?1:+i,function(){return n+i*Math.tan(Math.PI*e())}}return r.source=t,r}(Ir),Dz=function t(e){function r(n,i){return n=n==null?0:+n,i=i==null?1:+i,function(){var a=e();return n+i*Math.log(a/(1-a))}}return r.source=t,r}(Ir),Oz=function t(e){var r=ep.source(e),n=Px.source(e);function i(a){return function(){for(var s=0,o=a;o>16;){var l=Math.floor(.875*o),u=r(l)();if(u>o)return s+n(l-1,o/u)();s+=l,o-=u}for(var h=-Math.log1p(-e()),d=0;h<=o;++d)h-=Math.log1p(-e());return s+d}}return i.source=t,i}(Ir),Fz=1664525,Pz=1013904223,qx=1/4294967296;function qz(t=Math.random()){let e=(0<=t&&t<1?t/qx:Math.abs(t))|0;return()=>(e=Fz*e+Pz|0,qx*(e>>>0))}function On(t,e){switch(arguments.length){case 0:break;case 1:this.range(t);break;default:this.range(e).domain(t);break}return this}function ta(t,e){switch(arguments.length){case 0:break;case 1:{typeof t=="function"?this.interpolator(t):this.range(t);break}default:{this.domain(t),typeof e=="function"?this.interpolator(e):this.range(e);break}}return this}const rp=Symbol("implicit");function nf(){var t=new kl,e=[],r=[],n=rp;function i(a){let s=t.get(a);if(s===void 0){if(n!==rp)return n;t.set(a,s=e.push(a)-1)}return r[s%r.length]}return i.domain=function(a){if(!arguments.length)return e.slice();e=[],t=new kl;for(const s of a)t.has(s)||t.set(s,e.push(s)-1);return i},i.range=function(a){return arguments.length?(r=Array.from(a),i):r.slice()},i.unknown=function(a){return arguments.length?(n=a,i):n},i.copy=function(){return nf(e,r).unknown(n)},On.apply(i,arguments),i}function np(){var t=nf().unknown(void 0),e=t.domain,r=t.range,n=0,i=1,a,s,o=!1,l=0,u=0,h=.5;delete t.unknown;function d(){var f=e().length,p=ie&&(r=t,t=e,e=r),function(n){return Math.max(t,Math.min(e,n))}}function Uz(t,e,r){var n=t[0],i=t[1],a=e[0],s=e[1];return i2?Wz:Uz,l=u=null,d}function d(f){return f==null||isNaN(f=+f)?a:(l||(l=o(t.map(n),e,r)))(n(s(f)))}return d.invert=function(f){return s(i((u||(u=o(e,t.map(n),Bn)))(f)))},d.domain=function(f){return arguments.length?(t=Array.from(f,af),h()):t.slice()},d.range=function(f){return arguments.length?(e=Array.from(f),h()):e.slice()},d.rangeRound=function(f){return e=Array.from(f),r=ju,h()},d.clamp=function(f){return arguments.length?(s=f?!0:an,h()):s!==an},d.interpolate=function(f){return arguments.length?(r=f,h()):r},d.unknown=function(f){return arguments.length?(a=f,d):a},function(f,p){return n=f,i=p,h()}}function ap(){return sf()(an,an)}function Yx(t,e,r,n){var i=wl(t,e,r),a;switch(n=Co(n==null?",f":n),n.type){case"s":{var s=Math.max(Math.abs(t),Math.abs(e));return n.precision==null&&!isNaN(a=Jv(i,s))&&(n.precision=a),Jd(n,s)}case"":case"e":case"g":case"p":case"r":{n.precision==null&&!isNaN(a=t6(i,Math.max(Math.abs(t),Math.abs(e))))&&(n.precision=a-(n.type==="e"));break}case"f":case"%":{n.precision==null&&!isNaN(a=Qv(i))&&(n.precision=a-(n.type==="%")*2);break}}return yh(n)}function Oa(t){var e=t.domain;return t.ticks=function(r){var n=e();return hs(n[0],n[n.length-1],r==null?10:r)},t.tickFormat=function(r,n){var i=e();return Yx(i[0],i[i.length-1],r==null?10:r,n)},t.nice=function(r){r==null&&(r=10);var n=e(),i=0,a=n.length-1,s=n[i],o=n[a],l,u,h=10;for(o0;){if(u=oo(s,o,r),u===l)return n[i]=s,n[a]=o,e(n);if(u>0)s=Math.floor(s/u)*u,o=Math.ceil(o/u)*u;else if(u<0)s=Math.ceil(s*u)/u,o=Math.floor(o*u)/u;else break;l=u}return t},t}function sp(){var t=ap();return t.copy=function(){return fc(t,sp())},On.apply(t,arguments),Oa(t)}function Ux(t){var e;function r(n){return n==null||isNaN(n=+n)?e:n}return r.invert=r,r.domain=r.range=function(n){return arguments.length?(t=Array.from(n,af),r):t.slice()},r.unknown=function(n){return arguments.length?(e=n,r):e},r.copy=function(){return Ux(t).unknown(e)},t=arguments.length?Array.from(t,af):[0,1],Oa(r)}function Wx(t,e){t=t.slice();var r=0,n=t.length-1,i=t[r],a=t[n],s;return aMath.pow(t,e)}function Xz(t){return t===Math.E?Math.log:t===10&&Math.log10||t===2&&Math.log2||(t=Math.log(t),e=>Math.log(e)/t)}function jx(t){return(e,r)=>-t(-e,r)}function op(t){const e=t(Hx,Gx),r=e.domain;let n=10,i,a;function s(){return i=Xz(n),a=$z(n),r()[0]<0?(i=jx(i),a=jx(a),t(Hz,Gz)):t(Hx,Gx),e}return e.base=function(o){return arguments.length?(n=+o,s()):n},e.domain=function(o){return arguments.length?(r(o),s()):r()},e.ticks=o=>{const l=r();let u=l[0],h=l[l.length-1];const d=h0){for(;f<=p;++f)for(m=1;mh)break;b.push(_)}}else for(;f<=p;++f)for(m=n-1;m>=1;--m)if(_=f>0?m/a(-f):m*a(f),!(_h)break;b.push(_)}b.length*2{if(o==null&&(o=10),l==null&&(l=n===10?"s":","),typeof l!="function"&&(!(n%1)&&(l=Co(l)).precision==null&&(l.trim=!0),l=yh(l)),o===1/0)return l;const u=Math.max(1,n*o/e.ticks().length);return h=>{let d=h/a(Math.round(i(h)));return d*nr(Wx(r(),{floor:o=>a(Math.floor(i(o))),ceil:o=>a(Math.ceil(i(o)))})),e}function $x(){const t=op(sf()).domain([1,10]);return t.copy=()=>fc(t,$x()).base(t.base()),On.apply(t,arguments),t}function Xx(t){return function(e){return Math.sign(e)*Math.log1p(Math.abs(e/t))}}function Kx(t){return function(e){return Math.sign(e)*Math.expm1(Math.abs(e))*t}}function lp(t){var e=1,r=t(Xx(e),Kx(e));return r.constant=function(n){return arguments.length?t(Xx(e=+n),Kx(e)):e},Oa(r)}function Zx(){var t=lp(sf());return t.copy=function(){return fc(t,Zx()).constant(t.constant())},On.apply(t,arguments)}function Qx(t){return function(e){return e<0?-Math.pow(-e,t):Math.pow(e,t)}}function Kz(t){return t<0?-Math.sqrt(-t):Math.sqrt(t)}function Zz(t){return t<0?-t*t:t*t}function cp(t){var e=t(an,an),r=1;function n(){return r===1?t(an,an):r===.5?t(Kz,Zz):t(Qx(r),Qx(1/r))}return e.exponent=function(i){return arguments.length?(r=+i,n()):r},Oa(e)}function up(){var t=cp(sf());return t.copy=function(){return fc(t,up()).exponent(t.exponent())},On.apply(t,arguments),t}function Qz(){return up.apply(null,arguments).exponent(.5)}function Jx(t){return Math.sign(t)*t*t}function Jz(t){return Math.sign(t)*Math.sqrt(Math.abs(t))}function t8(){var t=ap(),e=[0,1],r=!1,n;function i(a){var s=Jz(t(a));return isNaN(s)?n:r?Math.round(s):s}return i.invert=function(a){return t.invert(Jx(a))},i.domain=function(a){return arguments.length?(t.domain(a),i):t.domain()},i.range=function(a){return arguments.length?(t.range((e=Array.from(a,af)).map(Jx)),i):e.slice()},i.rangeRound=function(a){return i.range(a).round(!0)},i.round=function(a){return arguments.length?(r=!!a,i):r},i.clamp=function(a){return arguments.length?(t.clamp(a),i):t.clamp()},i.unknown=function(a){return arguments.length?(n=a,i):n},i.copy=function(){return t8(t.domain(),e).round(r).clamp(t.clamp()).unknown(n)},On.apply(i,arguments),Oa(i)}function e8(){var t=[],e=[],r=[],n;function i(){var s=0,o=Math.max(1,e.length);for(r=new Array(o-1);++s0?r[o-1]:t[0],o=r?[n[r-1],e]:[n[u-1],n[u]]},s.unknown=function(l){return arguments.length&&(a=l),s},s.thresholds=function(){return n.slice()},s.copy=function(){return r8().domain([t,e]).range(i).unknown(a)},On.apply(Oa(s),arguments)}function n8(){var t=[.5],e=[0,1],r,n=1;function i(a){return a!=null&&a<=a?e[cs(t,a,0,n)]:r}return i.domain=function(a){return arguments.length?(t=Array.from(a),n=Math.min(t.length,e.length-1),i):t.slice()},i.range=function(a){return arguments.length?(e=Array.from(a),n=Math.min(t.length,e.length-1),i):e.slice()},i.invertExtent=function(a){var s=e.indexOf(a);return[t[s-1],t[s]]},i.unknown=function(a){return arguments.length?(r=a,i):r},i.copy=function(){return n8().domain(t).range(e).unknown(r)},On.apply(i,arguments)}var hp=new Date,fp=new Date;function xr(t,e,r,n){function i(a){return t(a=arguments.length===0?new Date:new Date(+a)),a}return i.floor=function(a){return t(a=new Date(+a)),a},i.ceil=function(a){return t(a=new Date(a-1)),e(a,1),t(a),a},i.round=function(a){var s=i(a),o=i.ceil(a);return a-s0))return l;do l.push(u=new Date(+a)),e(a,o),t(a);while(u=s)for(;t(s),!a(s);)s.setTime(s-1)},function(s,o){if(s>=s)if(o<0)for(;++o<=0;)for(;e(s,-1),!a(s););else for(;--o>=0;)for(;e(s,1),!a(s););})},r&&(i.count=function(a,s){return hp.setTime(+a),fp.setTime(+s),t(hp),t(fp),Math.floor(r(hp,fp))},i.every=function(a){return a=Math.floor(a),!isFinite(a)||!(a>0)?null:a>1?i.filter(n?function(s){return n(s)%a===0}:function(s){return i.count(0,s)%a===0}):i}),i}var of=xr(function(){},function(t,e){t.setTime(+t+e)},function(t,e){return e-t});of.every=function(t){return t=Math.floor(t),!isFinite(t)||!(t>0)?null:t>1?xr(function(e){e.setTime(Math.floor(e/t)*t)},function(e,r){e.setTime(+e+r*t)},function(e,r){return(r-e)/t}):of};const dp=of;var i8=of.range;const ea=1e3,Fn=ea*60,ra=Fn*60,Rs=ra*24,pp=Rs*7,a8=Rs*30,gp=Rs*365;var s8=xr(function(t){t.setTime(t-t.getMilliseconds())},function(t,e){t.setTime(+t+e*ea)},function(t,e){return(e-t)/ea},function(t){return t.getUTCSeconds()});const Fa=s8;var o8=s8.range,l8=xr(function(t){t.setTime(t-t.getMilliseconds()-t.getSeconds()*ea)},function(t,e){t.setTime(+t+e*Fn)},function(t,e){return(e-t)/Fn},function(t){return t.getMinutes()});const yp=l8;var tY=l8.range,c8=xr(function(t){t.setTime(t-t.getMilliseconds()-t.getSeconds()*ea-t.getMinutes()*Fn)},function(t,e){t.setTime(+t+e*ra)},function(t,e){return(e-t)/ra},function(t){return t.getHours()});const mp=c8;var eY=c8.range,u8=xr(t=>t.setHours(0,0,0,0),(t,e)=>t.setDate(t.getDate()+e),(t,e)=>(e-t-(e.getTimezoneOffset()-t.getTimezoneOffset())*Fn)/Rs,t=>t.getDate()-1);const dc=u8;var rY=u8.range;function Is(t){return xr(function(e){e.setDate(e.getDate()-(e.getDay()+7-t)%7),e.setHours(0,0,0,0)},function(e,r){e.setDate(e.getDate()+r*7)},function(e,r){return(r-e-(r.getTimezoneOffset()-e.getTimezoneOffset())*Fn)/pp})}var Do=Is(0),pc=Is(1),h8=Is(2),f8=Is(3),Ns=Is(4),d8=Is(5),p8=Is(6),g8=Do.range,nY=pc.range,iY=h8.range,aY=f8.range,sY=Ns.range,oY=d8.range,lY=p8.range,y8=xr(function(t){t.setDate(1),t.setHours(0,0,0,0)},function(t,e){t.setMonth(t.getMonth()+e)},function(t,e){return e.getMonth()-t.getMonth()+(e.getFullYear()-t.getFullYear())*12},function(t){return t.getMonth()});const bp=y8;var cY=y8.range,_p=xr(function(t){t.setMonth(0,1),t.setHours(0,0,0,0)},function(t,e){t.setFullYear(t.getFullYear()+e)},function(t,e){return e.getFullYear()-t.getFullYear()},function(t){return t.getFullYear()});_p.every=function(t){return!isFinite(t=Math.floor(t))||!(t>0)?null:xr(function(e){e.setFullYear(Math.floor(e.getFullYear()/t)*t),e.setMonth(0,1),e.setHours(0,0,0,0)},function(e,r){e.setFullYear(e.getFullYear()+r*t)})};const Pa=_p;var uY=_p.range,m8=xr(function(t){t.setUTCSeconds(0,0)},function(t,e){t.setTime(+t+e*Fn)},function(t,e){return(e-t)/Fn},function(t){return t.getUTCMinutes()});const vp=m8;var hY=m8.range,b8=xr(function(t){t.setUTCMinutes(0,0,0)},function(t,e){t.setTime(+t+e*ra)},function(t,e){return(e-t)/ra},function(t){return t.getUTCHours()});const xp=b8;var fY=b8.range,_8=xr(function(t){t.setUTCHours(0,0,0,0)},function(t,e){t.setUTCDate(t.getUTCDate()+e)},function(t,e){return(e-t)/Rs},function(t){return t.getUTCDate()-1});const gc=_8;var dY=_8.range;function Bs(t){return xr(function(e){e.setUTCDate(e.getUTCDate()-(e.getUTCDay()+7-t)%7),e.setUTCHours(0,0,0,0)},function(e,r){e.setUTCDate(e.getUTCDate()+r*7)},function(e,r){return(r-e)/pp})}var Oo=Bs(0),yc=Bs(1),v8=Bs(2),x8=Bs(3),Ds=Bs(4),k8=Bs(5),w8=Bs(6),T8=Oo.range,pY=yc.range,gY=v8.range,yY=x8.range,mY=Ds.range,bY=k8.range,_Y=w8.range,E8=xr(function(t){t.setUTCDate(1),t.setUTCHours(0,0,0,0)},function(t,e){t.setUTCMonth(t.getUTCMonth()+e)},function(t,e){return e.getUTCMonth()-t.getUTCMonth()+(e.getUTCFullYear()-t.getUTCFullYear())*12},function(t){return t.getUTCMonth()});const kp=E8;var vY=E8.range,wp=xr(function(t){t.setUTCMonth(0,1),t.setUTCHours(0,0,0,0)},function(t,e){t.setUTCFullYear(t.getUTCFullYear()+e)},function(t,e){return e.getUTCFullYear()-t.getUTCFullYear()},function(t){return t.getUTCFullYear()});wp.every=function(t){return!isFinite(t=Math.floor(t))||!(t>0)?null:xr(function(e){e.setUTCFullYear(Math.floor(e.getUTCFullYear()/t)*t),e.setUTCMonth(0,1),e.setUTCHours(0,0,0,0)},function(e,r){e.setUTCFullYear(e.getUTCFullYear()+r*t)})};const qa=wp;var xY=wp.range;function C8(t,e,r,n,i,a){const s=[[Fa,1,ea],[Fa,5,5*ea],[Fa,15,15*ea],[Fa,30,30*ea],[a,1,Fn],[a,5,5*Fn],[a,15,15*Fn],[a,30,30*Fn],[i,1,ra],[i,3,3*ra],[i,6,6*ra],[i,12,12*ra],[n,1,Rs],[n,2,2*Rs],[r,1,pp],[e,1,a8],[e,3,3*a8],[t,1,gp]];function o(u,h,d){const f=hy).right(s,f);if(p===s.length)return t.every(wl(u/gp,h/gp,d));if(p===0)return dp.every(Math.max(wl(u,h,d),1));const[m,_]=s[f/s[p-1][2]53)return null;"w"in U||(U.w=1),"Z"in U?(j=Ep(mc(U.y,0,1)),P=j.getUTCDay(),j=P>4||P===0?yc.ceil(j):yc(j),j=gc.offset(j,(U.V-1)*7),U.y=j.getUTCFullYear(),U.m=j.getUTCMonth(),U.d=j.getUTCDate()+(U.w+6)%7):(j=Tp(mc(U.y,0,1)),P=j.getDay(),j=P>4||P===0?pc.ceil(j):pc(j),j=dc.offset(j,(U.V-1)*7),U.y=j.getFullYear(),U.m=j.getMonth(),U.d=j.getDate()+(U.w+6)%7)}else("W"in U||"U"in U)&&("w"in U||(U.w="u"in U?U.u%7:"W"in U?1:0),P="Z"in U?Ep(mc(U.y,0,1)).getUTCDay():Tp(mc(U.y,0,1)).getDay(),U.m=0,U.d="W"in U?(U.w+6)%7+U.W*7-(P+5)%7:U.w+U.U*7-(P+6)%7);return"Z"in U?(U.H+=U.Z/100|0,U.M+=U.Z%100,Ep(U)):Tp(U)}}function R(V,Q,q,U){for(var F=0,j=Q.length,P=q.length,et,at;F=P)return-1;if(et=Q.charCodeAt(F++),et===37){if(et=Q.charAt(F++),at=C[et in I8?Q.charAt(F++):et],!at||(U=at(V,q,U))<0)return-1}else if(et!=q.charCodeAt(U++))return-1}return U}function A(V,Q,q){var U=u.exec(Q.slice(q));return U?(V.p=h.get(U[0].toLowerCase()),q+U[0].length):-1}function L(V,Q,q){var U=p.exec(Q.slice(q));return U?(V.w=m.get(U[0].toLowerCase()),q+U[0].length):-1}function v(V,Q,q){var U=d.exec(Q.slice(q));return U?(V.w=f.get(U[0].toLowerCase()),q+U[0].length):-1}function B(V,Q,q){var U=b.exec(Q.slice(q));return U?(V.m=x.get(U[0].toLowerCase()),q+U[0].length):-1}function w(V,Q,q){var U=_.exec(Q.slice(q));return U?(V.m=y.get(U[0].toLowerCase()),q+U[0].length):-1}function D(V,Q,q){return R(V,e,Q,q)}function N(V,Q,q){return R(V,r,Q,q)}function z(V,Q,q){return R(V,n,Q,q)}function X(V){return s[V.getDay()]}function ct(V){return a[V.getDay()]}function J(V){return l[V.getMonth()]}function Y(V){return o[V.getMonth()]}function $(V){return i[+(V.getHours()>=12)]}function lt(V){return 1+~~(V.getMonth()/3)}function ut(V){return s[V.getUTCDay()]}function W(V){return a[V.getUTCDay()]}function tt(V){return l[V.getUTCMonth()]}function K(V){return o[V.getUTCMonth()]}function it(V){return i[+(V.getUTCHours()>=12)]}function Z(V){return 1+~~(V.getUTCMonth()/3)}return{format:function(V){var Q=M(V+="",k);return Q.toString=function(){return V},Q},parse:function(V){var Q=S(V+="",!1);return Q.toString=function(){return V},Q},utcFormat:function(V){var Q=M(V+="",T);return Q.toString=function(){return V},Q},utcParse:function(V){var Q=S(V+="",!0);return Q.toString=function(){return V},Q}}}var I8={"-":"",_:" ",0:"0"},Ar=/^\s*\d+/,kY=/^%/,wY=/[\\^$*+?|[\]().{}]/g;function Oe(t,e,r){var n=t<0?"-":"",i=(n?-t:t)+"",a=i.length;return n+(a[e.toLowerCase(),r]))}function EY(t,e,r){var n=Ar.exec(e.slice(r,r+1));return n?(t.w=+n[0],r+n[0].length):-1}function CY(t,e,r){var n=Ar.exec(e.slice(r,r+1));return n?(t.u=+n[0],r+n[0].length):-1}function SY(t,e,r){var n=Ar.exec(e.slice(r,r+2));return n?(t.U=+n[0],r+n[0].length):-1}function AY(t,e,r){var n=Ar.exec(e.slice(r,r+2));return n?(t.V=+n[0],r+n[0].length):-1}function MY(t,e,r){var n=Ar.exec(e.slice(r,r+2));return n?(t.W=+n[0],r+n[0].length):-1}function N8(t,e,r){var n=Ar.exec(e.slice(r,r+4));return n?(t.y=+n[0],r+n[0].length):-1}function B8(t,e,r){var n=Ar.exec(e.slice(r,r+2));return n?(t.y=+n[0]+(+n[0]>68?1900:2e3),r+n[0].length):-1}function LY(t,e,r){var n=/^(Z)|([+-]\d\d)(?::?(\d\d))?/.exec(e.slice(r,r+6));return n?(t.Z=n[1]?0:-(n[2]+(n[3]||"00")),r+n[0].length):-1}function RY(t,e,r){var n=Ar.exec(e.slice(r,r+1));return n?(t.q=n[0]*3-3,r+n[0].length):-1}function IY(t,e,r){var n=Ar.exec(e.slice(r,r+2));return n?(t.m=n[0]-1,r+n[0].length):-1}function D8(t,e,r){var n=Ar.exec(e.slice(r,r+2));return n?(t.d=+n[0],r+n[0].length):-1}function NY(t,e,r){var n=Ar.exec(e.slice(r,r+3));return n?(t.m=0,t.d=+n[0],r+n[0].length):-1}function O8(t,e,r){var n=Ar.exec(e.slice(r,r+2));return n?(t.H=+n[0],r+n[0].length):-1}function BY(t,e,r){var n=Ar.exec(e.slice(r,r+2));return n?(t.M=+n[0],r+n[0].length):-1}function DY(t,e,r){var n=Ar.exec(e.slice(r,r+2));return n?(t.S=+n[0],r+n[0].length):-1}function OY(t,e,r){var n=Ar.exec(e.slice(r,r+3));return n?(t.L=+n[0],r+n[0].length):-1}function FY(t,e,r){var n=Ar.exec(e.slice(r,r+6));return n?(t.L=Math.floor(n[0]/1e3),r+n[0].length):-1}function PY(t,e,r){var n=kY.exec(e.slice(r,r+1));return n?r+n[0].length:-1}function qY(t,e,r){var n=Ar.exec(e.slice(r));return n?(t.Q=+n[0],r+n[0].length):-1}function VY(t,e,r){var n=Ar.exec(e.slice(r));return n?(t.s=+n[0],r+n[0].length):-1}function F8(t,e){return Oe(t.getDate(),e,2)}function zY(t,e){return Oe(t.getHours(),e,2)}function YY(t,e){return Oe(t.getHours()%12||12,e,2)}function UY(t,e){return Oe(1+dc.count(Pa(t),t),e,3)}function P8(t,e){return Oe(t.getMilliseconds(),e,3)}function WY(t,e){return P8(t,e)+"000"}function HY(t,e){return Oe(t.getMonth()+1,e,2)}function GY(t,e){return Oe(t.getMinutes(),e,2)}function jY(t,e){return Oe(t.getSeconds(),e,2)}function $Y(t){var e=t.getDay();return e===0?7:e}function XY(t,e){return Oe(Do.count(Pa(t)-1,t),e,2)}function q8(t){var e=t.getDay();return e>=4||e===0?Ns(t):Ns.ceil(t)}function KY(t,e){return t=q8(t),Oe(Ns.count(Pa(t),t)+(Pa(t).getDay()===4),e,2)}function ZY(t){return t.getDay()}function QY(t,e){return Oe(pc.count(Pa(t)-1,t),e,2)}function JY(t,e){return Oe(t.getFullYear()%100,e,2)}function tU(t,e){return t=q8(t),Oe(t.getFullYear()%100,e,2)}function eU(t,e){return Oe(t.getFullYear()%1e4,e,4)}function rU(t,e){var r=t.getDay();return t=r>=4||r===0?Ns(t):Ns.ceil(t),Oe(t.getFullYear()%1e4,e,4)}function nU(t){var e=t.getTimezoneOffset();return(e>0?"-":(e*=-1,"+"))+Oe(e/60|0,"0",2)+Oe(e%60,"0",2)}function V8(t,e){return Oe(t.getUTCDate(),e,2)}function iU(t,e){return Oe(t.getUTCHours(),e,2)}function aU(t,e){return Oe(t.getUTCHours()%12||12,e,2)}function sU(t,e){return Oe(1+gc.count(qa(t),t),e,3)}function z8(t,e){return Oe(t.getUTCMilliseconds(),e,3)}function oU(t,e){return z8(t,e)+"000"}function lU(t,e){return Oe(t.getUTCMonth()+1,e,2)}function cU(t,e){return Oe(t.getUTCMinutes(),e,2)}function uU(t,e){return Oe(t.getUTCSeconds(),e,2)}function hU(t){var e=t.getUTCDay();return e===0?7:e}function fU(t,e){return Oe(Oo.count(qa(t)-1,t),e,2)}function Y8(t){var e=t.getUTCDay();return e>=4||e===0?Ds(t):Ds.ceil(t)}function dU(t,e){return t=Y8(t),Oe(Ds.count(qa(t),t)+(qa(t).getUTCDay()===4),e,2)}function pU(t){return t.getUTCDay()}function gU(t,e){return Oe(yc.count(qa(t)-1,t),e,2)}function yU(t,e){return Oe(t.getUTCFullYear()%100,e,2)}function mU(t,e){return t=Y8(t),Oe(t.getUTCFullYear()%100,e,2)}function bU(t,e){return Oe(t.getUTCFullYear()%1e4,e,4)}function _U(t,e){var r=t.getUTCDay();return t=r>=4||r===0?Ds(t):Ds.ceil(t),Oe(t.getUTCFullYear()%1e4,e,4)}function vU(){return"+0000"}function U8(){return"%"}function W8(t){return+t}function H8(t){return Math.floor(+t/1e3)}var Fo,vc,G8,lf,Cp;j8({dateTime:"%x, %X",date:"%-m/%-d/%Y",time:"%-I:%M:%S %p",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});function j8(t){return Fo=R8(t),vc=Fo.format,G8=Fo.parse,lf=Fo.utcFormat,Cp=Fo.utcParse,Fo}var $8="%Y-%m-%dT%H:%M:%S.%LZ";function xU(t){return t.toISOString()}var kU=Date.prototype.toISOString?xU:lf($8);const wU=kU;function TU(t){var e=new Date(t);return isNaN(e)?null:e}var EU=+new Date("2000-01-01T00:00:00.000Z")?TU:Cp($8);const CU=EU;function SU(t){return new Date(t)}function AU(t){return t instanceof Date?+t:+new Date(+t)}function Sp(t,e,r,n,i,a,s,o,l,u){var h=ap(),d=h.invert,f=h.domain,p=u(".%L"),m=u(":%S"),_=u("%I:%M"),y=u("%I %p"),b=u("%a %d"),x=u("%b %d"),k=u("%B"),T=u("%Y");function C(M){return(l(M)e(i/(t.length-1)))},r.quantiles=function(n){return Array.from({length:n+1},(i,a)=>Cl(t,a/n))},r.copy=function(){return J8(e).domain(t)},ta.apply(r,arguments)}function uf(){var t=0,e=.5,r=1,n=1,i,a,s,o,l,u=an,h,d=!1,f;function p(_){return isNaN(_=+_)?f:(_=.5+((_=+h(_))-a)*(n*_B5(t[t.length-1]);var n7=new Array(3).concat("d8b365f5f5f55ab4ac","a6611adfc27d80cdc1018571","a6611adfc27df5f5f580cdc1018571","8c510ad8b365f6e8c3c7eae55ab4ac01665e","8c510ad8b365f6e8c3f5f5f5c7eae55ab4ac01665e","8c510abf812ddfc27df6e8c3c7eae580cdc135978f01665e","8c510abf812ddfc27df6e8c3f5f5f5c7eae580cdc135978f01665e","5430058c510abf812ddfc27df6e8c3c7eae580cdc135978f01665e003c30","5430058c510abf812ddfc27df6e8c3f5f5f5c7eae580cdc135978f01665e003c30").map(Ee);const YU=We(n7);var i7=new Array(3).concat("af8dc3f7f7f77fbf7b","7b3294c2a5cfa6dba0008837","7b3294c2a5cff7f7f7a6dba0008837","762a83af8dc3e7d4e8d9f0d37fbf7b1b7837","762a83af8dc3e7d4e8f7f7f7d9f0d37fbf7b1b7837","762a839970abc2a5cfe7d4e8d9f0d3a6dba05aae611b7837","762a839970abc2a5cfe7d4e8f7f7f7d9f0d3a6dba05aae611b7837","40004b762a839970abc2a5cfe7d4e8d9f0d3a6dba05aae611b783700441b","40004b762a839970abc2a5cfe7d4e8f7f7f7d9f0d3a6dba05aae611b783700441b").map(Ee);const UU=We(i7);var a7=new Array(3).concat("e9a3c9f7f7f7a1d76a","d01c8bf1b6dab8e1864dac26","d01c8bf1b6daf7f7f7b8e1864dac26","c51b7de9a3c9fde0efe6f5d0a1d76a4d9221","c51b7de9a3c9fde0eff7f7f7e6f5d0a1d76a4d9221","c51b7dde77aef1b6dafde0efe6f5d0b8e1867fbc414d9221","c51b7dde77aef1b6dafde0eff7f7f7e6f5d0b8e1867fbc414d9221","8e0152c51b7dde77aef1b6dafde0efe6f5d0b8e1867fbc414d9221276419","8e0152c51b7dde77aef1b6dafde0eff7f7f7e6f5d0b8e1867fbc414d9221276419").map(Ee);const WU=We(a7);var s7=new Array(3).concat("998ec3f7f7f7f1a340","5e3c99b2abd2fdb863e66101","5e3c99b2abd2f7f7f7fdb863e66101","542788998ec3d8daebfee0b6f1a340b35806","542788998ec3d8daebf7f7f7fee0b6f1a340b35806","5427888073acb2abd2d8daebfee0b6fdb863e08214b35806","5427888073acb2abd2d8daebf7f7f7fee0b6fdb863e08214b35806","2d004b5427888073acb2abd2d8daebfee0b6fdb863e08214b358067f3b08","2d004b5427888073acb2abd2d8daebf7f7f7fee0b6fdb863e08214b358067f3b08").map(Ee);const HU=We(s7);var o7=new Array(3).concat("ef8a62f7f7f767a9cf","ca0020f4a58292c5de0571b0","ca0020f4a582f7f7f792c5de0571b0","b2182bef8a62fddbc7d1e5f067a9cf2166ac","b2182bef8a62fddbc7f7f7f7d1e5f067a9cf2166ac","b2182bd6604df4a582fddbc7d1e5f092c5de4393c32166ac","b2182bd6604df4a582fddbc7f7f7f7d1e5f092c5de4393c32166ac","67001fb2182bd6604df4a582fddbc7d1e5f092c5de4393c32166ac053061","67001fb2182bd6604df4a582fddbc7f7f7f7d1e5f092c5de4393c32166ac053061").map(Ee);const GU=We(o7);var l7=new Array(3).concat("ef8a62ffffff999999","ca0020f4a582bababa404040","ca0020f4a582ffffffbababa404040","b2182bef8a62fddbc7e0e0e09999994d4d4d","b2182bef8a62fddbc7ffffffe0e0e09999994d4d4d","b2182bd6604df4a582fddbc7e0e0e0bababa8787874d4d4d","b2182bd6604df4a582fddbc7ffffffe0e0e0bababa8787874d4d4d","67001fb2182bd6604df4a582fddbc7e0e0e0bababa8787874d4d4d1a1a1a","67001fb2182bd6604df4a582fddbc7ffffffe0e0e0bababa8787874d4d4d1a1a1a").map(Ee);const jU=We(l7);var c7=new Array(3).concat("fc8d59ffffbf91bfdb","d7191cfdae61abd9e92c7bb6","d7191cfdae61ffffbfabd9e92c7bb6","d73027fc8d59fee090e0f3f891bfdb4575b4","d73027fc8d59fee090ffffbfe0f3f891bfdb4575b4","d73027f46d43fdae61fee090e0f3f8abd9e974add14575b4","d73027f46d43fdae61fee090ffffbfe0f3f8abd9e974add14575b4","a50026d73027f46d43fdae61fee090e0f3f8abd9e974add14575b4313695","a50026d73027f46d43fdae61fee090ffffbfe0f3f8abd9e974add14575b4313695").map(Ee);const $U=We(c7);var u7=new Array(3).concat("fc8d59ffffbf91cf60","d7191cfdae61a6d96a1a9641","d7191cfdae61ffffbfa6d96a1a9641","d73027fc8d59fee08bd9ef8b91cf601a9850","d73027fc8d59fee08bffffbfd9ef8b91cf601a9850","d73027f46d43fdae61fee08bd9ef8ba6d96a66bd631a9850","d73027f46d43fdae61fee08bffffbfd9ef8ba6d96a66bd631a9850","a50026d73027f46d43fdae61fee08bd9ef8ba6d96a66bd631a9850006837","a50026d73027f46d43fdae61fee08bffffbfd9ef8ba6d96a66bd631a9850006837").map(Ee);const XU=We(u7);var h7=new Array(3).concat("fc8d59ffffbf99d594","d7191cfdae61abdda42b83ba","d7191cfdae61ffffbfabdda42b83ba","d53e4ffc8d59fee08be6f59899d5943288bd","d53e4ffc8d59fee08bffffbfe6f59899d5943288bd","d53e4ff46d43fdae61fee08be6f598abdda466c2a53288bd","d53e4ff46d43fdae61fee08bffffbfe6f598abdda466c2a53288bd","9e0142d53e4ff46d43fdae61fee08be6f598abdda466c2a53288bd5e4fa2","9e0142d53e4ff46d43fdae61fee08bffffbfe6f598abdda466c2a53288bd5e4fa2").map(Ee);const KU=We(h7);var f7=new Array(3).concat("e5f5f999d8c92ca25f","edf8fbb2e2e266c2a4238b45","edf8fbb2e2e266c2a42ca25f006d2c","edf8fbccece699d8c966c2a42ca25f006d2c","edf8fbccece699d8c966c2a441ae76238b45005824","f7fcfde5f5f9ccece699d8c966c2a441ae76238b45005824","f7fcfde5f5f9ccece699d8c966c2a441ae76238b45006d2c00441b").map(Ee);const ZU=We(f7);var d7=new Array(3).concat("e0ecf49ebcda8856a7","edf8fbb3cde38c96c688419d","edf8fbb3cde38c96c68856a7810f7c","edf8fbbfd3e69ebcda8c96c68856a7810f7c","edf8fbbfd3e69ebcda8c96c68c6bb188419d6e016b","f7fcfde0ecf4bfd3e69ebcda8c96c68c6bb188419d6e016b","f7fcfde0ecf4bfd3e69ebcda8c96c68c6bb188419d810f7c4d004b").map(Ee);const QU=We(d7);var p7=new Array(3).concat("e0f3dba8ddb543a2ca","f0f9e8bae4bc7bccc42b8cbe","f0f9e8bae4bc7bccc443a2ca0868ac","f0f9e8ccebc5a8ddb57bccc443a2ca0868ac","f0f9e8ccebc5a8ddb57bccc44eb3d32b8cbe08589e","f7fcf0e0f3dbccebc5a8ddb57bccc44eb3d32b8cbe08589e","f7fcf0e0f3dbccebc5a8ddb57bccc44eb3d32b8cbe0868ac084081").map(Ee);const JU=We(p7);var g7=new Array(3).concat("fee8c8fdbb84e34a33","fef0d9fdcc8afc8d59d7301f","fef0d9fdcc8afc8d59e34a33b30000","fef0d9fdd49efdbb84fc8d59e34a33b30000","fef0d9fdd49efdbb84fc8d59ef6548d7301f990000","fff7ecfee8c8fdd49efdbb84fc8d59ef6548d7301f990000","fff7ecfee8c8fdd49efdbb84fc8d59ef6548d7301fb300007f0000").map(Ee);const tW=We(g7);var y7=new Array(3).concat("ece2f0a6bddb1c9099","f6eff7bdc9e167a9cf02818a","f6eff7bdc9e167a9cf1c9099016c59","f6eff7d0d1e6a6bddb67a9cf1c9099016c59","f6eff7d0d1e6a6bddb67a9cf3690c002818a016450","fff7fbece2f0d0d1e6a6bddb67a9cf3690c002818a016450","fff7fbece2f0d0d1e6a6bddb67a9cf3690c002818a016c59014636").map(Ee);const eW=We(y7);var m7=new Array(3).concat("ece7f2a6bddb2b8cbe","f1eef6bdc9e174a9cf0570b0","f1eef6bdc9e174a9cf2b8cbe045a8d","f1eef6d0d1e6a6bddb74a9cf2b8cbe045a8d","f1eef6d0d1e6a6bddb74a9cf3690c00570b0034e7b","fff7fbece7f2d0d1e6a6bddb74a9cf3690c00570b0034e7b","fff7fbece7f2d0d1e6a6bddb74a9cf3690c00570b0045a8d023858").map(Ee);const rW=We(m7);var b7=new Array(3).concat("e7e1efc994c7dd1c77","f1eef6d7b5d8df65b0ce1256","f1eef6d7b5d8df65b0dd1c77980043","f1eef6d4b9dac994c7df65b0dd1c77980043","f1eef6d4b9dac994c7df65b0e7298ace125691003f","f7f4f9e7e1efd4b9dac994c7df65b0e7298ace125691003f","f7f4f9e7e1efd4b9dac994c7df65b0e7298ace125698004367001f").map(Ee);const nW=We(b7);var _7=new Array(3).concat("fde0ddfa9fb5c51b8a","feebe2fbb4b9f768a1ae017e","feebe2fbb4b9f768a1c51b8a7a0177","feebe2fcc5c0fa9fb5f768a1c51b8a7a0177","feebe2fcc5c0fa9fb5f768a1dd3497ae017e7a0177","fff7f3fde0ddfcc5c0fa9fb5f768a1dd3497ae017e7a0177","fff7f3fde0ddfcc5c0fa9fb5f768a1dd3497ae017e7a017749006a").map(Ee);const iW=We(_7);var v7=new Array(3).concat("edf8b17fcdbb2c7fb8","ffffcca1dab441b6c4225ea8","ffffcca1dab441b6c42c7fb8253494","ffffccc7e9b47fcdbb41b6c42c7fb8253494","ffffccc7e9b47fcdbb41b6c41d91c0225ea80c2c84","ffffd9edf8b1c7e9b47fcdbb41b6c41d91c0225ea80c2c84","ffffd9edf8b1c7e9b47fcdbb41b6c41d91c0225ea8253494081d58").map(Ee);const aW=We(v7);var x7=new Array(3).concat("f7fcb9addd8e31a354","ffffccc2e69978c679238443","ffffccc2e69978c67931a354006837","ffffccd9f0a3addd8e78c67931a354006837","ffffccd9f0a3addd8e78c67941ab5d238443005a32","ffffe5f7fcb9d9f0a3addd8e78c67941ab5d238443005a32","ffffe5f7fcb9d9f0a3addd8e78c67941ab5d238443006837004529").map(Ee);const sW=We(x7);var k7=new Array(3).concat("fff7bcfec44fd95f0e","ffffd4fed98efe9929cc4c02","ffffd4fed98efe9929d95f0e993404","ffffd4fee391fec44ffe9929d95f0e993404","ffffd4fee391fec44ffe9929ec7014cc4c028c2d04","ffffe5fff7bcfee391fec44ffe9929ec7014cc4c028c2d04","ffffe5fff7bcfee391fec44ffe9929ec7014cc4c02993404662506").map(Ee);const oW=We(k7);var w7=new Array(3).concat("ffeda0feb24cf03b20","ffffb2fecc5cfd8d3ce31a1c","ffffb2fecc5cfd8d3cf03b20bd0026","ffffb2fed976feb24cfd8d3cf03b20bd0026","ffffb2fed976feb24cfd8d3cfc4e2ae31a1cb10026","ffffccffeda0fed976feb24cfd8d3cfc4e2ae31a1cb10026","ffffccffeda0fed976feb24cfd8d3cfc4e2ae31a1cbd0026800026").map(Ee);const lW=We(w7);var T7=new Array(3).concat("deebf79ecae13182bd","eff3ffbdd7e76baed62171b5","eff3ffbdd7e76baed63182bd08519c","eff3ffc6dbef9ecae16baed63182bd08519c","eff3ffc6dbef9ecae16baed64292c62171b5084594","f7fbffdeebf7c6dbef9ecae16baed64292c62171b5084594","f7fbffdeebf7c6dbef9ecae16baed64292c62171b508519c08306b").map(Ee);const cW=We(T7);var E7=new Array(3).concat("e5f5e0a1d99b31a354","edf8e9bae4b374c476238b45","edf8e9bae4b374c47631a354006d2c","edf8e9c7e9c0a1d99b74c47631a354006d2c","edf8e9c7e9c0a1d99b74c47641ab5d238b45005a32","f7fcf5e5f5e0c7e9c0a1d99b74c47641ab5d238b45005a32","f7fcf5e5f5e0c7e9c0a1d99b74c47641ab5d238b45006d2c00441b").map(Ee);const uW=We(E7);var C7=new Array(3).concat("f0f0f0bdbdbd636363","f7f7f7cccccc969696525252","f7f7f7cccccc969696636363252525","f7f7f7d9d9d9bdbdbd969696636363252525","f7f7f7d9d9d9bdbdbd969696737373525252252525","fffffff0f0f0d9d9d9bdbdbd969696737373525252252525","fffffff0f0f0d9d9d9bdbdbd969696737373525252252525000000").map(Ee);const hW=We(C7);var S7=new Array(3).concat("efedf5bcbddc756bb1","f2f0f7cbc9e29e9ac86a51a3","f2f0f7cbc9e29e9ac8756bb154278f","f2f0f7dadaebbcbddc9e9ac8756bb154278f","f2f0f7dadaebbcbddc9e9ac8807dba6a51a34a1486","fcfbfdefedf5dadaebbcbddc9e9ac8807dba6a51a34a1486","fcfbfdefedf5dadaebbcbddc9e9ac8807dba6a51a354278f3f007d").map(Ee);const fW=We(S7);var A7=new Array(3).concat("fee0d2fc9272de2d26","fee5d9fcae91fb6a4acb181d","fee5d9fcae91fb6a4ade2d26a50f15","fee5d9fcbba1fc9272fb6a4ade2d26a50f15","fee5d9fcbba1fc9272fb6a4aef3b2ccb181d99000d","fff5f0fee0d2fcbba1fc9272fb6a4aef3b2ccb181d99000d","fff5f0fee0d2fcbba1fc9272fb6a4aef3b2ccb181da50f1567000d").map(Ee);const dW=We(A7);var M7=new Array(3).concat("fee6cefdae6be6550d","feeddefdbe85fd8d3cd94701","feeddefdbe85fd8d3ce6550da63603","feeddefdd0a2fdae6bfd8d3ce6550da63603","feeddefdd0a2fdae6bfd8d3cf16913d948018c2d04","fff5ebfee6cefdd0a2fdae6bfd8d3cf16913d948018c2d04","fff5ebfee6cefdd0a2fdae6bfd8d3cf16913d94801a636037f2704").map(Ee);const pW=We(M7);function gW(t){return t=Math.max(0,Math.min(1,t)),"rgb("+Math.max(0,Math.min(255,Math.round(-4.54-t*(35.34-t*(2381.73-t*(6402.7-t*(7024.72-t*2710.57)))))))+", "+Math.max(0,Math.min(255,Math.round(32.49+t*(170.73+t*(52.82-t*(131.46-t*(176.58-t*67.37)))))))+", "+Math.max(0,Math.min(255,Math.round(81.24+t*(442.36-t*(2482.43-t*(6167.24-t*(6614.94-t*2475.67)))))))+")"}const yW=Xu(Qn(300,.5,0),Qn(-240,.5,1));var mW=Xu(Qn(-100,.75,.35),Qn(80,1.5,.8)),bW=Xu(Qn(260,.75,.35),Qn(80,1.5,.8)),hf=Qn();function _W(t){(t<0||t>1)&&(t-=Math.floor(t));var e=Math.abs(t-.5);return hf.h=360*t-100,hf.s=1.5-1.5*e,hf.l=.8-.9*e,hf+""}var ff=po(),vW=Math.PI/3,xW=Math.PI*2/3;function kW(t){var e;return t=(.5-t)*Math.PI,ff.r=255*(e=Math.sin(t))*e,ff.g=255*(e=Math.sin(t+vW))*e,ff.b=255*(e=Math.sin(t+xW))*e,ff+""}function wW(t){return t=Math.max(0,Math.min(1,t)),"rgb("+Math.max(0,Math.min(255,Math.round(34.61+t*(1172.33-t*(10793.56-t*(33300.12-t*(38394.49-t*14825.05)))))))+", "+Math.max(0,Math.min(255,Math.round(23.31+t*(557.33+t*(1225.33-t*(3574.96-t*(1073.77+t*707.56)))))))+", "+Math.max(0,Math.min(255,Math.round(27.2+t*(3211.1-t*(15327.97-t*(27814-t*(22569.18-t*6838.66)))))))+")"}function df(t){var e=t.length;return function(r){return t[Math.max(0,Math.min(e-1,Math.floor(r*e)))]}}const TW=df(Ee("44015444025645045745055946075a46085c460a5d460b5e470d60470e6147106347116447136548146748166848176948186a481a6c481b6d481c6e481d6f481f70482071482173482374482475482576482677482878482979472a7a472c7a472d7b472e7c472f7d46307e46327e46337f463480453581453781453882443983443a83443b84433d84433e85423f854240864241864142874144874045884046883f47883f48893e49893e4a893e4c8a3d4d8a3d4e8a3c4f8a3c508b3b518b3b528b3a538b3a548c39558c39568c38588c38598c375a8c375b8d365c8d365d8d355e8d355f8d34608d34618d33628d33638d32648e32658e31668e31678e31688e30698e306a8e2f6b8e2f6c8e2e6d8e2e6e8e2e6f8e2d708e2d718e2c718e2c728e2c738e2b748e2b758e2a768e2a778e2a788e29798e297a8e297b8e287c8e287d8e277e8e277f8e27808e26818e26828e26828e25838e25848e25858e24868e24878e23888e23898e238a8d228b8d228c8d228d8d218e8d218f8d21908d21918c20928c20928c20938c1f948c1f958b1f968b1f978b1f988b1f998a1f9a8a1e9b8a1e9c891e9d891f9e891f9f881fa0881fa1881fa1871fa28720a38620a48621a58521a68522a78522a88423a98324aa8325ab8225ac8226ad8127ad8128ae8029af7f2ab07f2cb17e2db27d2eb37c2fb47c31b57b32b67a34b67935b77937b87838b9773aba763bbb753dbc743fbc7340bd7242be7144bf7046c06f48c16e4ac16d4cc26c4ec36b50c46a52c56954c56856c66758c7655ac8645cc8635ec96260ca6063cb5f65cb5e67cc5c69cd5b6ccd5a6ece5870cf5773d05675d05477d1537ad1517cd2507fd34e81d34d84d44b86d54989d5488bd6468ed64590d74393d74195d84098d83e9bd93c9dd93ba0da39a2da37a5db36a8db34aadc32addc30b0dd2fb2dd2db5de2bb8de29bade28bddf26c0df25c2df23c5e021c8e020cae11fcde11dd0e11cd2e21bd5e21ad8e219dae319dde318dfe318e2e418e5e419e7e419eae51aece51befe51cf1e51df4e61ef6e620f8e621fbe723fde725"));var EW=df(Ee("00000401000501010601010802010902020b02020d03030f03031204041405041606051806051a07061c08071e0907200a08220b09240c09260d0a290e0b2b100b2d110c2f120d31130d34140e36150e38160f3b180f3d19103f1a10421c10441d11471e114920114b21114e22115024125325125527125829115a2a115c2c115f2d11612f116331116533106734106936106b38106c390f6e3b0f703d0f713f0f72400f74420f75440f764510774710784910784a10794c117a4e117b4f127b51127c52137c54137d56147d57157e59157e5a167e5c167f5d177f5f187f601880621980641a80651a80671b80681c816a1c816b1d816d1d816e1e81701f81721f817320817521817621817822817922827b23827c23827e24828025828125818326818426818627818827818928818b29818c29818e2a81902a81912b81932b80942c80962c80982d80992d809b2e7f9c2e7f9e2f7fa02f7fa1307ea3307ea5317ea6317da8327daa337dab337cad347cae347bb0357bb2357bb3367ab5367ab73779b83779ba3878bc3978bd3977bf3a77c03a76c23b75c43c75c53c74c73d73c83e73ca3e72cc3f71cd4071cf4070d0416fd2426fd3436ed5446dd6456cd8456cd9466bdb476adc4869de4968df4a68e04c67e24d66e34e65e44f64e55064e75263e85362e95462ea5661eb5760ec5860ed5a5fee5b5eef5d5ef05f5ef1605df2625df2645cf3655cf4675cf4695cf56b5cf66c5cf66e5cf7705cf7725cf8745cf8765cf9785df9795df97b5dfa7d5efa7f5efa815ffb835ffb8560fb8761fc8961fc8a62fc8c63fc8e64fc9065fd9266fd9467fd9668fd9869fd9a6afd9b6bfe9d6cfe9f6dfea16efea36ffea571fea772fea973feaa74feac76feae77feb078feb27afeb47bfeb67cfeb77efeb97ffebb81febd82febf84fec185fec287fec488fec68afec88cfeca8dfecc8ffecd90fecf92fed194fed395fed597fed799fed89afdda9cfddc9efddea0fde0a1fde2a3fde3a5fde5a7fde7a9fde9aafdebacfcecaefceeb0fcf0b2fcf2b4fcf4b6fcf6b8fcf7b9fcf9bbfcfbbdfcfdbf")),CW=df(Ee("00000401000501010601010802010a02020c02020e03021004031204031405041706041907051b08051d09061f0a07220b07240c08260d08290e092b10092d110a30120a32140b34150b37160b39180c3c190c3e1b0c411c0c431e0c451f0c48210c4a230c4c240c4f260c51280b53290b552b0b572d0b592f0a5b310a5c320a5e340a5f3609613809623909633b09643d09653e0966400a67420a68440a68450a69470b6a490b6a4a0c6b4c0c6b4d0d6c4f0d6c510e6c520e6d540f6d550f6d57106e59106e5a116e5c126e5d126e5f136e61136e62146e64156e65156e67166e69166e6a176e6c186e6d186e6f196e71196e721a6e741a6e751b6e771c6d781c6d7a1d6d7c1d6d7d1e6d7f1e6c801f6c82206c84206b85216b87216b88226a8a226a8c23698d23698f24699025689225689326679526679727669827669a28659b29649d29649f2a63a02a63a22b62a32c61a52c60a62d60a82e5fa92e5eab2f5ead305dae305cb0315bb1325ab3325ab43359b63458b73557b93556ba3655bc3754bd3853bf3952c03a51c13a50c33b4fc43c4ec63d4dc73e4cc83f4bca404acb4149cc4248ce4347cf4446d04545d24644d34743d44842d54a41d74b3fd84c3ed94d3dda4e3cdb503bdd513ade5238df5337e05536e15635e25734e35933e45a31e55c30e65d2fe75e2ee8602de9612bea632aeb6429eb6628ec6726ed6925ee6a24ef6c23ef6e21f06f20f1711ff1731df2741cf3761bf37819f47918f57b17f57d15f67e14f68013f78212f78410f8850ff8870ef8890cf98b0bf98c0af98e09fa9008fa9207fa9407fb9606fb9706fb9906fb9b06fb9d07fc9f07fca108fca309fca50afca60cfca80dfcaa0ffcac11fcae12fcb014fcb216fcb418fbb61afbb81dfbba1ffbbc21fbbe23fac026fac228fac42afac62df9c72ff9c932f9cb35f8cd37f8cf3af7d13df7d340f6d543f6d746f5d949f5db4cf4dd4ff4df53f4e156f3e35af3e55df2e661f2e865f2ea69f1ec6df1ed71f1ef75f1f179f2f27df2f482f3f586f3f68af4f88ef5f992f6fa96f8fb9af9fc9dfafda1fcffa4")),SW=df(Ee("0d088710078813078916078a19068c1b068d1d068e20068f2206902406912605912805922a05932c05942e05952f059631059733059735049837049938049a3a049a3c049b3e049c3f049c41049d43039e44039e46039f48039f4903a04b03a14c02a14e02a25002a25102a35302a35502a45601a45801a45901a55b01a55c01a65e01a66001a66100a76300a76400a76600a76700a86900a86a00a86c00a86e00a86f00a87100a87201a87401a87501a87701a87801a87a02a87b02a87d03a87e03a88004a88104a78305a78405a78606a68707a68808a68a09a58b0aa58d0ba58e0ca48f0da4910ea3920fa39410a29511a19613a19814a099159f9a169f9c179e9d189d9e199da01a9ca11b9ba21d9aa31e9aa51f99a62098a72197a82296aa2395ab2494ac2694ad2793ae2892b02991b12a90b22b8fb32c8eb42e8db52f8cb6308bb7318ab83289ba3388bb3488bc3587bd3786be3885bf3984c03a83c13b82c23c81c33d80c43e7fc5407ec6417dc7427cc8437bc9447aca457acb4679cc4778cc4977cd4a76ce4b75cf4c74d04d73d14e72d24f71d35171d45270d5536fd5546ed6556dd7566cd8576bd9586ada5a6ada5b69db5c68dc5d67dd5e66de5f65de6164df6263e06363e16462e26561e26660e3685fe4695ee56a5de56b5de66c5ce76e5be76f5ae87059e97158e97257ea7457eb7556eb7655ec7754ed7953ed7a52ee7b51ef7c51ef7e50f07f4ff0804ef1814df1834cf2844bf3854bf3874af48849f48948f58b47f58c46f68d45f68f44f79044f79143f79342f89441f89540f9973ff9983ef99a3efa9b3dfa9c3cfa9e3bfb9f3afba139fba238fca338fca537fca636fca835fca934fdab33fdac33fdae32fdaf31fdb130fdb22ffdb42ffdb52efeb72dfeb82cfeba2cfebb2bfebd2afebe2afec029fdc229fdc328fdc527fdc627fdc827fdca26fdcb26fccd25fcce25fcd025fcd225fbd324fbd524fbd724fad824fada24f9dc24f9dd25f8df25f8e125f7e225f7e425f6e626f6e826f5e926f5eb27f4ed27f3ee27f3f027f2f227f1f426f1f525f0f724f0f921"));function xe(t){return function(){return t}}const L7=Math.abs,qr=Math.atan2,na=Math.cos,AW=Math.max,Po=Math.min,gn=Math.sin,He=Math.sqrt,Vr=1e-12,za=Math.PI,pf=za/2,Ya=2*za;function MW(t){return t>1?0:t<-1?za:Math.acos(t)}function R7(t){return t>=1?pf:t<=-1?-pf:Math.asin(t)}function LW(t){return t.innerRadius}function RW(t){return t.outerRadius}function IW(t){return t.startAngle}function NW(t){return t.endAngle}function BW(t){return t&&t.padAngle}function DW(t,e,r,n,i,a,s,o){var l=r-t,u=n-e,h=s-i,d=o-a,f=d*l-h*u;if(!(f*fD*D+N*N&&(R=L,A=v),{cx:R,cy:A,x01:-h,y01:-d,x11:R*(i/C-1),y11:A*(i/C-1)}}function yf(){var t=LW,e=RW,r=xe(0),n=null,i=IW,a=NW,s=BW,o=null;function l(){var u,h,d=+t.apply(this,arguments),f=+e.apply(this,arguments),p=i.apply(this,arguments)-pf,m=a.apply(this,arguments)-pf,_=L7(m-p),y=m>p;if(o||(o=u=Ra()),fVr))o.moveTo(0,0);else if(_>Ya-Vr)o.moveTo(f*na(p),f*gn(p)),o.arc(0,0,f,p,m,!y),d>Vr&&(o.moveTo(d*na(m),d*gn(m)),o.arc(0,0,d,m,p,y));else{var b=p,x=m,k=p,T=m,C=_,M=_,S=s.apply(this,arguments)/2,R=S>Vr&&(n?+n.apply(this,arguments):He(d*d+f*f)),A=Po(L7(f-d)/2,+r.apply(this,arguments)),L=A,v=A,B,w;if(R>Vr){var D=R7(R/d*gn(S)),N=R7(R/f*gn(S));(C-=D*2)>Vr?(D*=y?1:-1,k+=D,T-=D):(C=0,k=T=(p+m)/2),(M-=N*2)>Vr?(N*=y?1:-1,b+=N,x-=N):(M=0,b=x=(p+m)/2)}var z=f*na(b),X=f*gn(b),ct=d*na(T),J=d*gn(T);if(A>Vr){var Y=f*na(x),$=f*gn(x),lt=d*na(k),ut=d*gn(k),W;if(_Vr?v>Vr?(B=gf(lt,ut,z,X,f,v,y),w=gf(Y,$,ct,J,f,v,y),o.moveTo(B.cx+B.x01,B.cy+B.y01),vVr)||!(C>Vr)?o.lineTo(ct,J):L>Vr?(B=gf(ct,J,Y,$,d,-L,y),w=gf(z,X,lt,ut,d,-L,y),o.lineTo(B.cx+B.x01,B.cy+B.y01),L=f;--p)o.point(x[p],k[p]);o.lineEnd(),o.areaEnd()}y&&(x[d]=+t(_,d,h),k[d]=+e(_,d,h),o.point(n?+n(_,d,h):x[d],r?+r(_,d,h):k[d]))}if(b)return o=null,b+""||null}function u(){return Ua().defined(i).curve(s).context(a)}return l.x=function(h){return arguments.length?(t=typeof h=="function"?h:xe(+h),n=null,l):t},l.x0=function(h){return arguments.length?(t=typeof h=="function"?h:xe(+h),l):t},l.x1=function(h){return arguments.length?(n=h==null?null:typeof h=="function"?h:xe(+h),l):n},l.y=function(h){return arguments.length?(e=typeof h=="function"?h:xe(+h),r=null,l):e},l.y0=function(h){return arguments.length?(e=typeof h=="function"?h:xe(+h),l):e},l.y1=function(h){return arguments.length?(r=h==null?null:typeof h=="function"?h:xe(+h),l):r},l.lineX0=l.lineY0=function(){return u().x(t).y(e)},l.lineY1=function(){return u().x(t).y(r)},l.lineX1=function(){return u().x(n).y(e)},l.defined=function(h){return arguments.length?(i=typeof h=="function"?h:xe(!!h),l):i},l.curve=function(h){return arguments.length?(s=h,a!=null&&(o=s(a)),l):s},l.context=function(h){return arguments.length?(h==null?a=o=null:o=s(a=h),l):a},l}function FW(t,e){return et?1:e>=t?0:NaN}function PW(t){return t}function B7(){var t=PW,e=FW,r=null,n=xe(0),i=xe(Ya),a=xe(0);function s(o){var l,u=(o=mf(o)).length,h,d,f=0,p=new Array(u),m=new Array(u),_=+n.apply(this,arguments),y=Math.min(Ya,Math.max(-Ya,i.apply(this,arguments)-_)),b,x=Math.min(Math.abs(y)/u,a.apply(this,arguments)),k=x*(y<0?-1:1),T;for(l=0;l0&&(f+=T);for(e!=null?p.sort(function(C,M){return e(m[C],m[M])}):r!=null&&p.sort(function(C,M){return r(o[C],o[M])}),l=0,d=f?(y-u*k)/f:0;l0?T*d:0)+k,m[h]={data:o[h],index:l,value:T,startAngle:_,endAngle:b,padAngle:x};return m}return s.value=function(o){return arguments.length?(t=typeof o=="function"?o:xe(+o),s):t},s.sortValues=function(o){return arguments.length?(e=o,r=null,s):e},s.sort=function(o){return arguments.length?(r=o,e=null,s):r},s.startAngle=function(o){return arguments.length?(n=typeof o=="function"?o:xe(+o),s):n},s.endAngle=function(o){return arguments.length?(i=typeof o=="function"?o:xe(+o),s):i},s.padAngle=function(o){return arguments.length?(a=typeof o=="function"?o:xe(+o),s):a},s}var D7=Ip(yn);function O7(t){this._curve=t}O7.prototype={areaStart:function(){this._curve.areaStart()},areaEnd:function(){this._curve.areaEnd()},lineStart:function(){this._curve.lineStart()},lineEnd:function(){this._curve.lineEnd()},point:function(t,e){this._curve.point(e*Math.sin(t),e*-Math.cos(t))}};function Ip(t){function e(r){return new O7(t(r))}return e._curve=t,e}function xc(t){var e=t.curve;return t.angle=t.x,delete t.x,t.radius=t.y,delete t.y,t.curve=function(r){return arguments.length?e(Ip(r)):e()._curve},t}function F7(){return xc(Ua().curve(D7))}function P7(){var t=N7().curve(D7),e=t.curve,r=t.lineX0,n=t.lineX1,i=t.lineY0,a=t.lineY1;return t.angle=t.x,delete t.x,t.startAngle=t.x0,delete t.x0,t.endAngle=t.x1,delete t.x1,t.radius=t.y,delete t.y,t.innerRadius=t.y0,delete t.y0,t.outerRadius=t.y1,delete t.y1,t.lineStartAngle=function(){return xc(r())},delete t.lineX0,t.lineEndAngle=function(){return xc(n())},delete t.lineX1,t.lineInnerRadius=function(){return xc(i())},delete t.lineY0,t.lineOuterRadius=function(){return xc(a())},delete t.lineY1,t.curve=function(s){return arguments.length?e(Ip(s)):e()._curve},t}function kc(t,e){return[(e=+e)*Math.cos(t-=Math.PI/2),e*Math.sin(t)]}class q7{constructor(e,r){this._context=e,this._x=r}areaStart(){this._line=0}areaEnd(){this._line=NaN}lineStart(){this._point=0}lineEnd(){(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line}point(e,r){switch(e=+e,r=+r,this._point){case 0:{this._point=1,this._line?this._context.lineTo(e,r):this._context.moveTo(e,r);break}case 1:this._point=2;default:{this._x?this._context.bezierCurveTo(this._x0=(this._x0+e)/2,this._y0,this._x0,r,e,r):this._context.bezierCurveTo(this._x0,this._y0=(this._y0+r)/2,e,this._y0,e,r);break}}this._x0=e,this._y0=r}}class qW{constructor(e){this._context=e}lineStart(){this._point=0}lineEnd(){}point(e,r){if(e=+e,r=+r,this._point++===0)this._x0=e,this._y0=r;else{const n=kc(this._x0,this._y0),i=kc(this._x0,this._y0=(this._y0+r)/2),a=kc(e,this._y0),s=kc(e,r);this._context.moveTo(...n),this._context.bezierCurveTo(...i,...a,...s)}}}function V7(t){return new q7(t,!0)}function z7(t){return new q7(t,!1)}function VW(t){return new qW(t)}function zW(t){return t.source}function YW(t){return t.target}function bf(t){let e=zW,r=YW,n=Lp,i=Rp,a=null,s=null;function o(){let l;const u=OW.call(arguments),h=e.apply(this,u),d=r.apply(this,u);if(a==null&&(s=t(l=Ra())),s.lineStart(),u[0]=h,s.point(+n.apply(this,u),+i.apply(this,u)),u[0]=d,s.point(+n.apply(this,u),+i.apply(this,u)),s.lineEnd(),l)return s=null,l+""||null}return o.source=function(l){return arguments.length?(e=l,o):e},o.target=function(l){return arguments.length?(r=l,o):r},o.x=function(l){return arguments.length?(n=typeof l=="function"?l:xe(+l),o):n},o.y=function(l){return arguments.length?(i=typeof l=="function"?l:xe(+l),o):i},o.context=function(l){return arguments.length?(l==null?a=s=null:s=t(a=l),o):a},o}function UW(){return bf(V7)}function WW(){return bf(z7)}function HW(){const t=bf(VW);return t.angle=t.x,delete t.x,t.radius=t.y,delete t.y,t}const GW=He(3),Y7={draw(t,e){const r=He(e+Po(e/28,.75))*.59436,n=r/2,i=n*GW;t.moveTo(0,r),t.lineTo(0,-r),t.moveTo(-i,-n),t.lineTo(i,n),t.moveTo(-i,n),t.lineTo(i,-n)}},_f={draw(t,e){const r=He(e/za);t.moveTo(r,0),t.arc(0,0,r,0,Ya)}},U7={draw(t,e){const r=He(e/5)/2;t.moveTo(-3*r,-r),t.lineTo(-r,-r),t.lineTo(-r,-3*r),t.lineTo(r,-3*r),t.lineTo(r,-r),t.lineTo(3*r,-r),t.lineTo(3*r,r),t.lineTo(r,r),t.lineTo(r,3*r),t.lineTo(-r,3*r),t.lineTo(-r,r),t.lineTo(-3*r,r),t.closePath()}},W7=He(1/3),jW=W7*2,H7={draw(t,e){const r=He(e/jW),n=r*W7;t.moveTo(0,-r),t.lineTo(n,0),t.lineTo(0,r),t.lineTo(-n,0),t.closePath()}},G7={draw(t,e){const r=He(e)*.62625;t.moveTo(0,-r),t.lineTo(r,0),t.lineTo(0,r),t.lineTo(-r,0),t.closePath()}},j7={draw(t,e){const r=He(e-Po(e/7,2))*.87559;t.moveTo(-r,0),t.lineTo(r,0),t.moveTo(0,r),t.lineTo(0,-r)}},$7={draw(t,e){const r=He(e),n=-r/2;t.rect(n,n,r,r)}},X7={draw(t,e){const r=He(e)*.4431;t.moveTo(r,r),t.lineTo(r,-r),t.lineTo(-r,-r),t.lineTo(-r,r),t.closePath()}},$W=.8908130915292852,K7=gn(za/10)/gn(7*za/10),XW=gn(Ya/10)*K7,KW=-na(Ya/10)*K7,Z7={draw(t,e){const r=He(e*$W),n=XW*r,i=KW*r;t.moveTo(0,-r),t.lineTo(n,i);for(let a=1;a<5;++a){const s=Ya*a/5,o=na(s),l=gn(s);t.lineTo(l*r,-o*r),t.lineTo(o*n-l*i,l*n+o*i)}t.closePath()}},Np=He(3),Q7={draw(t,e){const r=-He(e/(Np*3));t.moveTo(0,r*2),t.lineTo(-Np*r,-r),t.lineTo(Np*r,-r),t.closePath()}},ZW=He(3),J7={draw(t,e){const r=He(e)*.6824,n=r/2,i=r*ZW/2;t.moveTo(0,-r),t.lineTo(i,n),t.lineTo(-i,n),t.closePath()}},Pn=-.5,qn=He(3)/2,Bp=1/He(12),QW=(Bp/2+1)*3,tk={draw(t,e){const r=He(e/QW),n=r/2,i=r*Bp,a=n,s=r*Bp+r,o=-a,l=s;t.moveTo(n,i),t.lineTo(a,s),t.lineTo(o,l),t.lineTo(Pn*n-qn*i,qn*n+Pn*i),t.lineTo(Pn*a-qn*s,qn*a+Pn*s),t.lineTo(Pn*o-qn*l,qn*o+Pn*l),t.lineTo(Pn*n+qn*i,Pn*i-qn*n),t.lineTo(Pn*a+qn*s,Pn*s-qn*a),t.lineTo(Pn*o+qn*l,Pn*l-qn*o),t.closePath()}},ek={draw(t,e){const r=He(e-Po(e/6,1.7))*.6189;t.moveTo(-r,-r),t.lineTo(r,r),t.moveTo(-r,r),t.lineTo(r,-r)}},rk=[_f,U7,H7,$7,Z7,Q7,tk],JW=[_f,j7,ek,J7,Y7,X7,G7];function tH(t,e){let r=null;t=typeof t=="function"?t:xe(t||_f),e=typeof e=="function"?e:xe(e===void 0?64:+e);function n(){let i;if(r||(r=i=Ra()),t.apply(this,arguments).draw(r,+e.apply(this,arguments)),i)return r=null,i+""||null}return n.type=function(i){return arguments.length?(t=typeof i=="function"?i:xe(i),n):t},n.size=function(i){return arguments.length?(e=typeof i=="function"?i:xe(+i),n):e},n.context=function(i){return arguments.length?(r=i==null?null:i,n):r},n}function Wa(){}function vf(t,e,r){t._context.bezierCurveTo((2*t._x0+t._x1)/3,(2*t._y0+t._y1)/3,(t._x0+2*t._x1)/3,(t._y0+2*t._y1)/3,(t._x0+4*t._x1+e)/6,(t._y0+4*t._y1+r)/6)}function xf(t){this._context=t}xf.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},lineEnd:function(){switch(this._point){case 3:vf(this,this._x1,this._y1);case 2:this._context.lineTo(this._x1,this._y1);break}(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;break;case 2:this._point=3,this._context.lineTo((5*this._x0+this._x1)/6,(5*this._y0+this._y1)/6);default:vf(this,t,e);break}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e}};function Os(t){return new xf(t)}function nk(t){this._context=t}nk.prototype={areaStart:Wa,areaEnd:Wa,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._y0=this._y1=this._y2=this._y3=this._y4=NaN,this._point=0},lineEnd:function(){switch(this._point){case 1:{this._context.moveTo(this._x2,this._y2),this._context.closePath();break}case 2:{this._context.moveTo((this._x2+2*this._x3)/3,(this._y2+2*this._y3)/3),this._context.lineTo((this._x3+2*this._x2)/3,(this._y3+2*this._y2)/3),this._context.closePath();break}case 3:{this.point(this._x2,this._y2),this.point(this._x3,this._y3),this.point(this._x4,this._y4);break}}},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._x2=t,this._y2=e;break;case 1:this._point=2,this._x3=t,this._y3=e;break;case 2:this._point=3,this._x4=t,this._y4=e,this._context.moveTo((this._x0+4*this._x1+t)/6,(this._y0+4*this._y1+e)/6);break;default:vf(this,t,e);break}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e}};function ik(t){return new nk(t)}function ak(t){this._context=t}ak.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},lineEnd:function(){(this._line||this._line!==0&&this._point===3)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3;var r=(this._x0+4*this._x1+t)/6,n=(this._y0+4*this._y1+e)/6;this._line?this._context.lineTo(r,n):this._context.moveTo(r,n);break;case 3:this._point=4;default:vf(this,t,e);break}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e}};function sk(t){return new ak(t)}function ok(t,e){this._basis=new xf(t),this._beta=e}ok.prototype={lineStart:function(){this._x=[],this._y=[],this._basis.lineStart()},lineEnd:function(){var t=this._x,e=this._y,r=t.length-1;if(r>0)for(var n=t[0],i=e[0],a=t[r]-n,s=e[r]-i,o=-1,l;++o<=r;)l=o/r,this._basis.point(this._beta*t[o]+(1-this._beta)*(n+l*a),this._beta*e[o]+(1-this._beta)*(i+l*s));this._x=this._y=null,this._basis.lineEnd()},point:function(t,e){this._x.push(+t),this._y.push(+e)}};const eH=function t(e){function r(n){return e===1?new xf(n):new ok(n,e)}return r.beta=function(n){return t(+n)},r}(.85);function kf(t,e,r){t._context.bezierCurveTo(t._x1+t._k*(t._x2-t._x0),t._y1+t._k*(t._y2-t._y0),t._x2+t._k*(t._x1-e),t._y2+t._k*(t._y1-r),t._x2,t._y2)}function Dp(t,e){this._context=t,this._k=(1-e)/6}Dp.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:kf(this,this._x1,this._y1);break}(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2,this._x1=t,this._y1=e;break;case 2:this._point=3;default:kf(this,t,e);break}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};const rH=function t(e){function r(n){return new Dp(n,e)}return r.tension=function(n){return t(+n)},r}(0);function Op(t,e){this._context=t,this._k=(1-e)/6}Op.prototype={areaStart:Wa,areaEnd:Wa,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._x5=this._y0=this._y1=this._y2=this._y3=this._y4=this._y5=NaN,this._point=0},lineEnd:function(){switch(this._point){case 1:{this._context.moveTo(this._x3,this._y3),this._context.closePath();break}case 2:{this._context.lineTo(this._x3,this._y3),this._context.closePath();break}case 3:{this.point(this._x3,this._y3),this.point(this._x4,this._y4),this.point(this._x5,this._y5);break}}},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._x3=t,this._y3=e;break;case 1:this._point=2,this._context.moveTo(this._x4=t,this._y4=e);break;case 2:this._point=3,this._x5=t,this._y5=e;break;default:kf(this,t,e);break}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};const nH=function t(e){function r(n){return new Op(n,e)}return r.tension=function(n){return t(+n)},r}(0);function Fp(t,e){this._context=t,this._k=(1-e)/6}Fp.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._point=0},lineEnd:function(){(this._line||this._line!==0&&this._point===3)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3,this._line?this._context.lineTo(this._x2,this._y2):this._context.moveTo(this._x2,this._y2);break;case 3:this._point=4;default:kf(this,t,e);break}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};const iH=function t(e){function r(n){return new Fp(n,e)}return r.tension=function(n){return t(+n)},r}(0);function Pp(t,e,r){var n=t._x1,i=t._y1,a=t._x2,s=t._y2;if(t._l01_a>Vr){var o=2*t._l01_2a+3*t._l01_a*t._l12_a+t._l12_2a,l=3*t._l01_a*(t._l01_a+t._l12_a);n=(n*o-t._x0*t._l12_2a+t._x2*t._l01_2a)/l,i=(i*o-t._y0*t._l12_2a+t._y2*t._l01_2a)/l}if(t._l23_a>Vr){var u=2*t._l23_2a+3*t._l23_a*t._l12_a+t._l12_2a,h=3*t._l23_a*(t._l23_a+t._l12_a);a=(a*u+t._x1*t._l23_2a-e*t._l12_2a)/h,s=(s*u+t._y1*t._l23_2a-r*t._l12_2a)/h}t._context.bezierCurveTo(n,i,a,s,t._x2,t._y2)}function lk(t,e){this._context=t,this._alpha=e}lk.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:this.point(this._x2,this._y2);break}(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){if(t=+t,e=+e,this._point){var r=this._x2-t,n=this._y2-e;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(r*r+n*n,this._alpha))}switch(this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;break;case 2:this._point=3;default:Pp(this,t,e);break}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};const aH=function t(e){function r(n){return e?new lk(n,e):new Dp(n,0)}return r.alpha=function(n){return t(+n)},r}(.5);function ck(t,e){this._context=t,this._alpha=e}ck.prototype={areaStart:Wa,areaEnd:Wa,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._x5=this._y0=this._y1=this._y2=this._y3=this._y4=this._y5=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){switch(this._point){case 1:{this._context.moveTo(this._x3,this._y3),this._context.closePath();break}case 2:{this._context.lineTo(this._x3,this._y3),this._context.closePath();break}case 3:{this.point(this._x3,this._y3),this.point(this._x4,this._y4),this.point(this._x5,this._y5);break}}},point:function(t,e){if(t=+t,e=+e,this._point){var r=this._x2-t,n=this._y2-e;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(r*r+n*n,this._alpha))}switch(this._point){case 0:this._point=1,this._x3=t,this._y3=e;break;case 1:this._point=2,this._context.moveTo(this._x4=t,this._y4=e);break;case 2:this._point=3,this._x5=t,this._y5=e;break;default:Pp(this,t,e);break}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};const sH=function t(e){function r(n){return e?new ck(n,e):new Op(n,0)}return r.alpha=function(n){return t(+n)},r}(.5);function uk(t,e){this._context=t,this._alpha=e}uk.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){(this._line||this._line!==0&&this._point===3)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){if(t=+t,e=+e,this._point){var r=this._x2-t,n=this._y2-e;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(r*r+n*n,this._alpha))}switch(this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3,this._line?this._context.lineTo(this._x2,this._y2):this._context.moveTo(this._x2,this._y2);break;case 3:this._point=4;default:Pp(this,t,e);break}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};const oH=function t(e){function r(n){return e?new uk(n,e):new Fp(n,0)}return r.alpha=function(n){return t(+n)},r}(.5);function hk(t){this._context=t}hk.prototype={areaStart:Wa,areaEnd:Wa,lineStart:function(){this._point=0},lineEnd:function(){this._point&&this._context.closePath()},point:function(t,e){t=+t,e=+e,this._point?this._context.lineTo(t,e):(this._point=1,this._context.moveTo(t,e))}};function fk(t){return new hk(t)}function dk(t){return t<0?-1:1}function pk(t,e,r){var n=t._x1-t._x0,i=e-t._x1,a=(t._y1-t._y0)/(n||i<0&&-0),s=(r-t._y1)/(i||n<0&&-0),o=(a*i+s*n)/(n+i);return(dk(a)+dk(s))*Math.min(Math.abs(a),Math.abs(s),.5*Math.abs(o))||0}function gk(t,e){var r=t._x1-t._x0;return r?(3*(t._y1-t._y0)/r-e)/2:e}function qp(t,e,r){var n=t._x0,i=t._y0,a=t._x1,s=t._y1,o=(a-n)/3;t._context.bezierCurveTo(n+o,i+o*e,a-o,s-o*r,a,s)}function wf(t){this._context=t}wf.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=this._t0=NaN,this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x1,this._y1);break;case 3:qp(this,this._t0,gk(this,this._t0));break}(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){var r=NaN;if(t=+t,e=+e,!(t===this._x1&&e===this._y1)){switch(this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;break;case 2:this._point=3,qp(this,gk(this,r=pk(this,t,e)),r);break;default:qp(this,this._t0,r=pk(this,t,e));break}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e,this._t0=r}}};function yk(t){this._context=new mk(t)}(yk.prototype=Object.create(wf.prototype)).point=function(t,e){wf.prototype.point.call(this,e,t)};function mk(t){this._context=t}mk.prototype={moveTo:function(t,e){this._context.moveTo(e,t)},closePath:function(){this._context.closePath()},lineTo:function(t,e){this._context.lineTo(e,t)},bezierCurveTo:function(t,e,r,n,i,a){this._context.bezierCurveTo(e,t,n,r,a,i)}};function bk(t){return new wf(t)}function _k(t){return new yk(t)}function vk(t){this._context=t}vk.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x=[],this._y=[]},lineEnd:function(){var t=this._x,e=this._y,r=t.length;if(r)if(this._line?this._context.lineTo(t[0],e[0]):this._context.moveTo(t[0],e[0]),r===2)this._context.lineTo(t[1],e[1]);else for(var n=xk(t),i=xk(e),a=0,s=1;s=0;--e)i[e]=(s[e]-i[e+1])/a[e];for(a[r-1]=(t[r]+i[r-1])/2,e=0;e=0&&(this._t=1-this._t,this._line=1-this._line)},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;default:{if(this._t<=0)this._context.lineTo(this._x,e),this._context.lineTo(t,e);else{var r=this._x*(1-this._t)+t*this._t;this._context.lineTo(r,this._y),this._context.lineTo(r,e)}break}}this._x=t,this._y=e}};function wk(t){return new Tf(t,.5)}function Tk(t){return new Tf(t,0)}function Ek(t){return new Tf(t,1)}function qo(t,e){if((s=t.length)>1)for(var r=1,n,i,a=t[e[0]],s,o=a.length;r=0;)r[e]=e;return r}function lH(t,e){return t[e]}function cH(t){const e=[];return e.key=t,e}function uH(){var t=xe([]),e=Vo,r=qo,n=lH;function i(a){var s=Array.from(t.apply(this,arguments),cH),o,l=s.length,u=-1,h;for(const d of a)for(o=0,++u;o0){for(var r,n,i=0,a=t[0].length,s;i0)for(var r,n=0,i,a,s,o,l,u=t[e[0]].length;n0?(i[0]=s,i[1]=s+=a):a<0?(i[1]=o,i[0]=o+=a):(i[0]=0,i[1]=a)}function dH(t,e){if((i=t.length)>0){for(var r=0,n=t[e[0]],i,a=n.length;r0)||!((a=(i=t[e[0]]).length)>0))){for(var r=0,n=1,i,a,s;na&&(a=i,r=e);return r}function Sk(t){var e=t.map(Ak);return Vo(t).sort(function(r,n){return e[r]-e[n]})}function Ak(t){for(var e=0,r=-1,n=t.length,i;++r()=>t;function _H(t,{sourceEvent:e,target:r,transform:n,dispatch:i}){Object.defineProperties(this,{type:{value:t,enumerable:!0,configurable:!0},sourceEvent:{value:e,enumerable:!0,configurable:!0},target:{value:r,enumerable:!0,configurable:!0},transform:{value:n,enumerable:!0,configurable:!0},_:{value:i}})}function Ri(t,e,r){this.k=t,this.x=e,this.y=r}Ri.prototype={constructor:Ri,scale:function(t){return t===1?this:new Ri(this.k*t,this.x,this.y)},translate:function(t,e){return t===0&e===0?this:new Ri(this.k,this.x+this.k*t,this.y+this.k*e)},apply:function(t){return[t[0]*this.k+this.x,t[1]*this.k+this.y]},applyX:function(t){return t*this.k+this.x},applyY:function(t){return t*this.k+this.y},invert:function(t){return[(t[0]-this.x)/this.k,(t[1]-this.y)/this.k]},invertX:function(t){return(t-this.x)/this.k},invertY:function(t){return(t-this.y)/this.k},rescaleX:function(t){return t.copy().domain(t.range().map(this.invertX,this).map(t.invert,t))},rescaleY:function(t){return t.copy().domain(t.range().map(this.invertY,this).map(t.invert,t))},toString:function(){return"translate("+this.x+","+this.y+") scale("+this.k+")"}};var Cf=new Ri(1,0,0);Mk.prototype=Ri.prototype;function Mk(t){for(;!t.__zoom;)if(!(t=t.parentNode))return Cf;return t.__zoom}function Vp(t){t.stopImmediatePropagation()}function wc(t){t.preventDefault(),t.stopImmediatePropagation()}function vH(t){return(!t.ctrlKey||t.type==="wheel")&&!t.button}function xH(){var t=this;return t instanceof SVGElement?(t=t.ownerSVGElement||t,t.hasAttribute("viewBox")?(t=t.viewBox.baseVal,[[t.x,t.y],[t.x+t.width,t.y+t.height]]):[[0,0],[t.width.baseVal.value,t.height.baseVal.value]]):[[0,0],[t.clientWidth,t.clientHeight]]}function Lk(){return this.__zoom||Cf}function kH(t){return-t.deltaY*(t.deltaMode===1?.05:t.deltaMode?1:.002)*(t.ctrlKey?10:1)}function wH(){return navigator.maxTouchPoints||"ontouchstart"in this}function TH(t,e,r){var n=t.invertX(e[0][0])-r[0][0],i=t.invertX(e[1][0])-r[1][0],a=t.invertY(e[0][1])-r[0][1],s=t.invertY(e[1][1])-r[1][1];return t.translate(i>n?(n+i)/2:Math.min(0,n)||Math.max(0,i),s>a?(a+s)/2:Math.min(0,a)||Math.max(0,s))}function EH(){var t=vH,e=xH,r=TH,n=kH,i=wH,a=[0,1/0],s=[[-1/0,-1/0],[1/0,1/0]],o=250,l=H5,u=fs("start","zoom","end"),h,d,f,p=500,m=150,_=0,y=10;function b(D){D.property("__zoom",Lk).on("wheel.zoom",R,{passive:!1}).on("mousedown.zoom",A).on("dblclick.zoom",L).filter(i).on("touchstart.zoom",v).on("touchmove.zoom",B).on("touchend.zoom touchcancel.zoom",w).style("-webkit-tap-highlight-color","rgba(0,0,0,0)")}b.transform=function(D,N,z,X){var ct=D.selection?D.selection():D;ct.property("__zoom",Lk),D!==ct?C(D,N,z,X):ct.interrupt().each(function(){M(this,arguments).event(X).start().zoom(null,typeof N=="function"?N.apply(this,arguments):N).end()})},b.scaleBy=function(D,N,z,X){b.scaleTo(D,function(){var ct=this.__zoom.k,J=typeof N=="function"?N.apply(this,arguments):N;return ct*J},z,X)},b.scaleTo=function(D,N,z,X){b.transform(D,function(){var ct=e.apply(this,arguments),J=this.__zoom,Y=z==null?T(ct):typeof z=="function"?z.apply(this,arguments):z,$=J.invert(Y),lt=typeof N=="function"?N.apply(this,arguments):N;return r(k(x(J,lt),Y,$),ct,s)},z,X)},b.translateBy=function(D,N,z,X){b.transform(D,function(){return r(this.__zoom.translate(typeof N=="function"?N.apply(this,arguments):N,typeof z=="function"?z.apply(this,arguments):z),e.apply(this,arguments),s)},null,X)},b.translateTo=function(D,N,z,X,ct){b.transform(D,function(){var J=e.apply(this,arguments),Y=this.__zoom,$=X==null?T(J):typeof X=="function"?X.apply(this,arguments):X;return r(Cf.translate($[0],$[1]).scale(Y.k).translate(typeof N=="function"?-N.apply(this,arguments):-N,typeof z=="function"?-z.apply(this,arguments):-z),J,s)},X,ct)};function x(D,N){return N=Math.max(a[0],Math.min(a[1],N)),N===D.k?D:new Ri(N,D.x,D.y)}function k(D,N,z){var X=N[0]-z[0]*D.k,ct=N[1]-z[1]*D.k;return X===D.x&&ct===D.y?D:new Ri(D.k,X,ct)}function T(D){return[(+D[0][0]+ +D[1][0])/2,(+D[0][1]+ +D[1][1])/2]}function C(D,N,z,X){D.on("start.zoom",function(){M(this,arguments).event(X).start()}).on("interrupt.zoom end.zoom",function(){M(this,arguments).event(X).end()}).tween("zoom",function(){var ct=this,J=arguments,Y=M(ct,J).event(X),$=e.apply(ct,J),lt=z==null?T($):typeof z=="function"?z.apply(ct,J):z,ut=Math.max($[1][0]-$[0][0],$[1][1]-$[0][1]),W=ct.__zoom,tt=typeof N=="function"?N.apply(ct,J):N,K=l(W.invert(lt).concat(ut/W.k),tt.invert(lt).concat(ut/tt.k));return function(it){if(it===1)it=tt;else{var Z=K(it),V=ut/Z[2];it=new Ri(V,lt[0]-Z[0]*V,lt[1]-Z[1]*V)}Y.zoom(null,it)}})}function M(D,N,z){return!z&&D.__zooming||new S(D,N)}function S(D,N){this.that=D,this.args=N,this.active=0,this.sourceEvent=null,this.extent=e.apply(D,N),this.taps=0}S.prototype={event:function(D){return D&&(this.sourceEvent=D),this},start:function(){return++this.active===1&&(this.that.__zooming=this,this.emit("start")),this},zoom:function(D,N){return this.mouse&&D!=="mouse"&&(this.mouse[1]=N.invert(this.mouse[0])),this.touch0&&D!=="touch"&&(this.touch0[1]=N.invert(this.touch0[0])),this.touch1&&D!=="touch"&&(this.touch1[1]=N.invert(this.touch1[0])),this.that.__zoom=N,this.emit("zoom"),this},end:function(){return--this.active===0&&(delete this.that.__zooming,this.emit("end")),this},emit:function(D){var N=St(this.that).datum();u.call(D,this.that,new _H(D,{sourceEvent:this.sourceEvent,target:b,type:D,transform:this.that.__zoom,dispatch:u}),N)}};function R(D,...N){if(!t.apply(this,arguments))return;var z=M(this,N).event(D),X=this.__zoom,ct=Math.max(a[0],Math.min(a[1],X.k*Math.pow(2,n.apply(this,arguments)))),J=Tn(D);if(z.wheel)(z.mouse[0][0]!==J[0]||z.mouse[0][1]!==J[1])&&(z.mouse[1]=X.invert(z.mouse[0]=J)),clearTimeout(z.wheel);else{if(X.k===ct)return;z.mouse=[J,X.invert(J)],vs(this),z.start()}wc(D),z.wheel=setTimeout(Y,m),z.zoom("mouse",r(k(x(X,ct),z.mouse[0],z.mouse[1]),z.extent,s));function Y(){z.wheel=null,z.end()}}function A(D,...N){if(f||!t.apply(this,arguments))return;var z=D.currentTarget,X=M(this,N,!0).event(D),ct=St(D.view).on("mousemove.zoom",lt,!0).on("mouseup.zoom",ut,!0),J=Tn(D,z),Y=D.clientX,$=D.clientY;Bu(D.view),Vp(D),X.mouse=[J,this.__zoom.invert(J)],vs(this),X.start();function lt(W){if(wc(W),!X.moved){var tt=W.clientX-Y,K=W.clientY-$;X.moved=tt*tt+K*K>_}X.event(W).zoom("mouse",r(k(X.that.__zoom,X.mouse[0]=Tn(W,z),X.mouse[1]),X.extent,s))}function ut(W){ct.on("mousemove.zoom mouseup.zoom",null),Du(W.view,X.moved),wc(W),X.event(W).end()}}function L(D,...N){if(!!t.apply(this,arguments)){var z=this.__zoom,X=Tn(D.changedTouches?D.changedTouches[0]:D,this),ct=z.invert(X),J=z.k*(D.shiftKey?.5:2),Y=r(k(x(z,J),X,ct),e.apply(this,N),s);wc(D),o>0?St(this).transition().duration(o).call(C,Y,X,D):St(this).call(b.transform,Y,X,D)}}function v(D,...N){if(!!t.apply(this,arguments)){var z=D.touches,X=z.length,ct=M(this,N,D.changedTouches.length===X).event(D),J,Y,$,lt;for(Vp(D),Y=0;Y"u"||!Reflect.construct||Reflect.construct.sham)return!1;if(typeof Proxy=="function")return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){})),!0}catch{return!1}}function Sf(t,e,r){return SH()?Sf=Reflect.construct:Sf=function(i,a,s){var o=[null];o.push.apply(o,a);var l=Function.bind.apply(i,o),u=new l;return s&&zp(u,s.prototype),u},Sf.apply(null,arguments)}function ni(t){return AH(t)||MH(t)||LH(t)||RH()}function AH(t){if(Array.isArray(t))return Yp(t)}function MH(t){if(typeof Symbol<"u"&&t[Symbol.iterator]!=null||t["@@iterator"]!=null)return Array.from(t)}function LH(t,e){if(!!t){if(typeof t=="string")return Yp(t,e);var r=Object.prototype.toString.call(t).slice(8,-1);if(r==="Object"&&t.constructor&&(r=t.constructor.name),r==="Map"||r==="Set")return Array.from(t);if(r==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r))return Yp(t,e)}}function Yp(t,e){(e==null||e>t.length)&&(e=t.length);for(var r=0,n=new Array(e);r1?r-1:0),i=1;i/gm),GH=Ii(/^data-[\-\w.\u00B7-\uFFFF]/),jH=Ii(/^aria-[\-\w]+$/),$H=Ii(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i),XH=Ii(/^(?:\w+script|data):/i),KH=Ii(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g),ZH=Ii(/^html$/i),QH=function(){return typeof window>"u"?null:window},JH=function(e,r){if(Ha(e)!=="object"||typeof e.createPolicy!="function")return null;var n=null,i="data-tt-policy-suffix";r.currentScript&&r.currentScript.hasAttribute(i)&&(n=r.currentScript.getAttribute(i));var a="dompurify"+(n?"#"+n:"");try{return e.createPolicy(a,{createHTML:function(o){return o},createScriptURL:function(o){return o}})}catch{return console.warn("TrustedTypes policy "+a+" could not be created."),null}};function Pk(){var t=arguments.length>0&&arguments[0]!==void 0?arguments[0]:QH(),e=function(st){return Pk(st)};if(e.version="2.4.0",e.removed=[],!t||!t.document||t.document.nodeType!==9)return e.isSupported=!1,e;var r=t.document,n=t.document,i=t.DocumentFragment,a=t.HTMLTemplateElement,s=t.Node,o=t.Element,l=t.NodeFilter,u=t.NamedNodeMap,h=u===void 0?t.NamedNodeMap||t.MozNamedAttrMap:u,d=t.HTMLFormElement,f=t.DOMParser,p=t.trustedTypes,m=o.prototype,_=Lf(m,"cloneNode"),y=Lf(m,"nextSibling"),b=Lf(m,"childNodes"),x=Lf(m,"parentNode");if(typeof a=="function"){var k=n.createElement("template");k.content&&k.content.ownerDocument&&(n=k.content.ownerDocument)}var T=JH(p,r),C=T?T.createHTML(""):"",M=n,S=M.implementation,R=M.createNodeIterator,A=M.createDocumentFragment,L=M.getElementsByTagName,v=r.importNode,B={};try{B=Fs(n).documentMode?n.documentMode:{}}catch{}var w={};e.isSupported=typeof x=="function"&&S&&typeof S.createHTMLDocument<"u"&&B!==9;var D=WH,N=HH,z=GH,X=jH,ct=XH,J=KH,Y=$H,$=null,lt=Me({},[].concat(ni(Bk),ni(Hp),ni(Gp),ni(jp),ni(Dk))),ut=null,W=Me({},[].concat(ni(Ok),ni($p),ni(Fk),ni(Rf))),tt=Object.seal(Object.create(null,{tagNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},attributeNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},allowCustomizedBuiltInElements:{writable:!0,configurable:!1,enumerable:!0,value:!1}})),K=null,it=null,Z=!0,V=!0,Q=!1,q=!1,U=!1,F=!1,j=!1,P=!1,et=!1,at=!1,It=!0,Lt=!1,Rt="user-content-",Ct=!0,pt=!1,mt={},vt=null,Tt=Me({},["annotation-xml","audio","colgroup","desc","foreignobject","head","iframe","math","mi","mn","mo","ms","mtext","noembed","noframes","noscript","plaintext","script","style","svg","template","thead","title","video","xmp"]),ft=null,le=Me({},["audio","video","img","source","image","track"]),Dt=null,Gt=Me({},["alt","class","for","id","label","name","pattern","placeholder","role","summary","title","value","style","xmlns"]),$t="http://www.w3.org/1998/Math/MathML",Qt="http://www.w3.org/2000/svg",we="http://www.w3.org/1999/xhtml",jt=we,Ft=!1,zt,wt=["application/xhtml+xml","text/html"],bt="text/html",Et,kt=null,Ut=n.createElement("form"),gt=function(st){return st instanceof RegExp||st instanceof Function},he=function(st){kt&&kt===st||((!st||Ha(st)!=="object")&&(st={}),st=Fs(st),zt=wt.indexOf(st.PARSER_MEDIA_TYPE)===-1?zt=bt:zt=st.PARSER_MEDIA_TYPE,Et=zt==="application/xhtml+xml"?function(At){return At}:Mf,$="ALLOWED_TAGS"in st?Me({},st.ALLOWED_TAGS,Et):lt,ut="ALLOWED_ATTR"in st?Me({},st.ALLOWED_ATTR,Et):W,Dt="ADD_URI_SAFE_ATTR"in st?Me(Fs(Gt),st.ADD_URI_SAFE_ATTR,Et):Gt,ft="ADD_DATA_URI_TAGS"in st?Me(Fs(le),st.ADD_DATA_URI_TAGS,Et):le,vt="FORBID_CONTENTS"in st?Me({},st.FORBID_CONTENTS,Et):Tt,K="FORBID_TAGS"in st?Me({},st.FORBID_TAGS,Et):{},it="FORBID_ATTR"in st?Me({},st.FORBID_ATTR,Et):{},mt="USE_PROFILES"in st?st.USE_PROFILES:!1,Z=st.ALLOW_ARIA_ATTR!==!1,V=st.ALLOW_DATA_ATTR!==!1,Q=st.ALLOW_UNKNOWN_PROTOCOLS||!1,q=st.SAFE_FOR_TEMPLATES||!1,U=st.WHOLE_DOCUMENT||!1,P=st.RETURN_DOM||!1,et=st.RETURN_DOM_FRAGMENT||!1,at=st.RETURN_TRUSTED_TYPE||!1,j=st.FORCE_BODY||!1,It=st.SANITIZE_DOM!==!1,Lt=st.SANITIZE_NAMED_PROPS||!1,Ct=st.KEEP_CONTENT!==!1,pt=st.IN_PLACE||!1,Y=st.ALLOWED_URI_REGEXP||Y,jt=st.NAMESPACE||we,st.CUSTOM_ELEMENT_HANDLING&>(st.CUSTOM_ELEMENT_HANDLING.tagNameCheck)&&(tt.tagNameCheck=st.CUSTOM_ELEMENT_HANDLING.tagNameCheck),st.CUSTOM_ELEMENT_HANDLING&>(st.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)&&(tt.attributeNameCheck=st.CUSTOM_ELEMENT_HANDLING.attributeNameCheck),st.CUSTOM_ELEMENT_HANDLING&&typeof st.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements=="boolean"&&(tt.allowCustomizedBuiltInElements=st.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements),q&&(V=!1),et&&(P=!0),mt&&($=Me({},ni(Dk)),ut=[],mt.html===!0&&(Me($,Bk),Me(ut,Ok)),mt.svg===!0&&(Me($,Hp),Me(ut,$p),Me(ut,Rf)),mt.svgFilters===!0&&(Me($,Gp),Me(ut,$p),Me(ut,Rf)),mt.mathMl===!0&&(Me($,jp),Me(ut,Fk),Me(ut,Rf))),st.ADD_TAGS&&($===lt&&($=Fs($)),Me($,st.ADD_TAGS,Et)),st.ADD_ATTR&&(ut===W&&(ut=Fs(ut)),Me(ut,st.ADD_ATTR,Et)),st.ADD_URI_SAFE_ATTR&&Me(Dt,st.ADD_URI_SAFE_ATTR,Et),st.FORBID_CONTENTS&&(vt===Tt&&(vt=Fs(vt)),Me(vt,st.FORBID_CONTENTS,Et)),Ct&&($["#text"]=!0),U&&Me($,["html","head","body"]),$.table&&(Me($,["tbody"]),delete K.tbody),sn&&sn(st),kt=st)},yt=Me({},["mi","mo","mn","ms","mtext"]),ne=Me({},["foreignobject","desc","title","annotation-xml"]),ve=Me({},["title","style","font","a","script"]),ye=Me({},Hp);Me(ye,Gp),Me(ye,YH);var be=Me({},jp);Me(be,UH);var Te=function(st){var At=x(st);(!At||!At.tagName)&&(At={namespaceURI:we,tagName:"template"});var Nt=Mf(st.tagName),Jt=Mf(At.tagName);return st.namespaceURI===Qt?At.namespaceURI===we?Nt==="svg":At.namespaceURI===$t?Nt==="svg"&&(Jt==="annotation-xml"||yt[Jt]):Boolean(ye[Nt]):st.namespaceURI===$t?At.namespaceURI===we?Nt==="math":At.namespaceURI===Qt?Nt==="math"&&ne[Jt]:Boolean(be[Nt]):st.namespaceURI===we?At.namespaceURI===Qt&&!ne[Jt]||At.namespaceURI===$t&&!yt[Jt]?!1:!be[Nt]&&(ve[Nt]||!ye[Nt]):!1},Wt=function(st){Tc(e.removed,{element:st});try{st.parentNode.removeChild(st)}catch{try{st.outerHTML=C}catch{st.remove()}}},se=function(st,At){try{Tc(e.removed,{attribute:At.getAttributeNode(st),from:At})}catch{Tc(e.removed,{attribute:null,from:At})}if(At.removeAttribute(st),st==="is"&&!ut[st])if(P||et)try{Wt(At)}catch{}else try{At.setAttribute(st,"")}catch{}},me=function(st){var At,Nt;if(j)st=""+st;else{var Jt=PH(st,/^[\r\n\t ]+/);Nt=Jt&&Jt[0]}zt==="application/xhtml+xml"&&(st=''+st+"");var ze=T?T.createHTML(st):st;if(jt===we)try{At=new f().parseFromString(ze,zt)}catch{}if(!At||!At.documentElement){At=S.createDocument(jt,"template",null);try{At.documentElement.innerHTML=Ft?"":ze}catch{}}var Pe=At.body||At.documentElement;return st&&Nt&&Pe.insertBefore(n.createTextNode(Nt),Pe.childNodes[0]||null),jt===we?L.call(At,U?"html":"body")[0]:U?At.documentElement:Pe},ue=function(st){return R.call(st.ownerDocument||st,st,l.SHOW_ELEMENT|l.SHOW_COMMENT|l.SHOW_TEXT,null,!1)},_a=function(st){return st instanceof d&&(typeof st.nodeName!="string"||typeof st.textContent!="string"||typeof st.removeChild!="function"||!(st.attributes instanceof h)||typeof st.removeAttribute!="function"||typeof st.setAttribute!="function"||typeof st.namespaceURI!="string"||typeof st.insertBefore!="function")},Hr=function(st){return Ha(s)==="object"?st instanceof s:st&&Ha(st)==="object"&&typeof st.nodeType=="number"&&typeof st.nodeName=="string"},Ie=function(st,At,Nt){!w[st]||FH(w[st],function(Jt){Jt.call(e,At,Nt,kt)})},oe=function(st){var At;if(Ie("beforeSanitizeElements",st,null),_a(st)||on(/[\u0080-\uFFFF]/,st.nodeName))return Wt(st),!0;var Nt=Et(st.nodeName);if(Ie("uponSanitizeElement",st,{tagName:Nt,allowedTags:$}),st.hasChildNodes()&&!Hr(st.firstElementChild)&&(!Hr(st.content)||!Hr(st.content.firstElementChild))&&on(/<[/\w]/g,st.innerHTML)&&on(/<[/\w]/g,st.textContent)||Nt==="select"&&on(/