diff --git a/CHANGELOG.md b/CHANGELOG.md index c67448893..4b83caaa3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ ### Parser - Datasets - - Added the followinf datasets for all entities: + - Added the following datasets for all entities: - Value destroyed - Value created - Spent Output Profit Ratio (SOPR) @@ -27,13 +27,22 @@ - Realized Price 0.1th Percentile - Node - Added a `node.args` file where you can set the path to your node `datadir` and where you can add additional args (you can see the syntax in `parser/README.md`) +- Price + - Improved error message when price cannot be found ### App - General - Added a backup API in case the main one fails or is offline + - Complete redesign of the datasets object + - Removed import of routes in JSON in favor for hardcoded typed routes in string format which resulted in: + - + A much lighter app + - + Better Lighthouse score + - - Slower Typescript server + - Fixed datasets with null values crashing their fetch function - Chart - Fixed series color being set to default ones after hovering the legend + - Fixed chart starting showing candlesticks and quickly switching to a line when it should've started directly with the line - Settings - Removed the horizontal scroll bar which was unintended diff --git a/README.md b/README.md index 39ce349be..7cf8cb36a 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,7 @@ Big features that are planned, in no particular order: - **Datasets by block timestamp**: In addition to having datasets by block date and block height - **Descriptions**: Add text to describe all charts and what they mean - **Start9 Add-on**: By making the whole suite much easier to self-host, it's quite rough right now +- **API Documentation**: Highly needed to explain what's what _Maybe_: diff --git a/app/package.json b/app/package.json index ab5da7a0e..3ffe44e56 100644 --- a/app/package.json +++ b/app/package.json @@ -21,7 +21,7 @@ "@solid-primitives/intersection-observer": "^2.1.6", "@solid-primitives/resize-observer": "^2.0.26", "lean-qr": "^2.3.4", - "lightweight-charts": "^4.1.6", + "lightweight-charts": "^4.1.7", "solid-js": "^1.8.18" }, "devDependencies": { @@ -36,12 +36,12 @@ "rollup-plugin-visualizer": "^5.12.0", "tailwindcss": "^3.4.4", "typescript": "^5.5.3", - "unplugin-auto-import": "^0.17.6", + "unplugin-auto-import": "^0.18.0", "unplugin-icons": "^0.19.0", "vite": "^5.3.3", "vite-plugin-pwa": "^0.20.0", "vite-plugin-solid": "^2.10.2", "workbox-window": "^7.1.0", - "wrangler": "^3.63.2" + "wrangler": "^3.64.0" } } diff --git a/app/pnpm-lock.yaml b/app/pnpm-lock.yaml index 7427138a6..60f04d41d 100644 --- a/app/pnpm-lock.yaml +++ b/app/pnpm-lock.yaml @@ -21,8 +21,8 @@ dependencies: specifier: ^2.3.4 version: 2.3.4 lightweight-charts: - specifier: ^4.1.6 - version: 4.1.6 + specifier: ^4.1.7 + version: 4.1.7 solid-js: specifier: ^1.8.18 version: 1.8.18 @@ -62,8 +62,8 @@ devDependencies: specifier: ^5.5.3 version: 5.5.3 unplugin-auto-import: - specifier: ^0.17.6 - version: 0.17.6(rollup@2.79.1) + specifier: ^0.18.0 + version: 0.18.0(rollup@2.79.1) unplugin-icons: specifier: ^0.19.0 version: 0.19.0 @@ -80,8 +80,8 @@ devDependencies: specifier: ^7.1.0 version: 7.1.0 wrangler: - specifier: ^3.63.2 - version: 3.63.2 + specifier: ^3.64.0 + version: 3.64.0 packages: @@ -135,25 +135,25 @@ packages: picocolors: 1.0.1 dev: true - /@babel/compat-data@7.24.7: - resolution: {integrity: sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw==} + /@babel/compat-data@7.24.8: + resolution: {integrity: sha512-c4IM7OTg6k1Q+AJ153e2mc2QVTezTwnb4VzquwcyiEzGnW0Kedv4do/TrkU98qPeC5LNiMt/QXwIjzYXLBpyZg==} engines: {node: '>=6.9.0'} dev: true - /@babel/core@7.24.7: - resolution: {integrity: sha512-nykK+LEK86ahTkX/3TgauT0ikKoNCfKHEaZYTUVupJdTLzGNvrblu4u6fa7DhZONAltdf8e662t/abY8idrd/g==} + /@babel/core@7.24.8: + resolution: {integrity: sha512-6AWcmZC/MZCO0yKys4uhg5NlxL0ESF3K6IAaoQ+xSXvPyPyxNWRafP+GDbI88Oh68O7QkJgmEtedWPM9U0pZNg==} engines: {node: '>=6.9.0'} dependencies: '@ampproject/remapping': 2.3.0 '@babel/code-frame': 7.24.7 - '@babel/generator': 7.24.7 - '@babel/helper-compilation-targets': 7.24.7 - '@babel/helper-module-transforms': 7.24.7(@babel/core@7.24.7) - '@babel/helpers': 7.24.7 - '@babel/parser': 7.24.7 + '@babel/generator': 7.24.8 + '@babel/helper-compilation-targets': 7.24.8 + '@babel/helper-module-transforms': 7.24.8(@babel/core@7.24.8) + '@babel/helpers': 7.24.8 + '@babel/parser': 7.24.8 '@babel/template': 7.24.7 - '@babel/traverse': 7.24.7 - '@babel/types': 7.24.7 + '@babel/traverse': 7.24.8 + '@babel/types': 7.24.8 convert-source-map: 2.0.0 debug: 4.3.5 gensync: 1.0.0-beta.2 @@ -163,11 +163,11 @@ packages: - supports-color dev: true - /@babel/generator@7.24.7: - resolution: {integrity: sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA==} + /@babel/generator@7.24.8: + resolution: {integrity: sha512-47DG+6F5SzOi0uEvK4wMShmn5yY0mVjVJoWTphdY2B4Rx9wHgjK7Yhtr0ru6nE+sn0v38mzrWOlah0p/YlHHOQ==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.24.7 + '@babel/types': 7.24.8 '@jridgewell/gen-mapping': 0.3.5 '@jridgewell/trace-mapping': 0.3.25 jsesc: 2.5.2 @@ -177,43 +177,43 @@ packages: resolution: {integrity: sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.24.7 + '@babel/types': 7.24.8 dev: true /@babel/helper-builder-binary-assignment-operator-visitor@7.24.7: resolution: {integrity: sha512-xZeCVVdwb4MsDBkkyZ64tReWYrLRHlMN72vP7Bdm3OUOuyFZExhsHUUnuWnm2/XOlAJzR0LfPpB56WXZn0X/lA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/traverse': 7.24.7 - '@babel/types': 7.24.7 + '@babel/traverse': 7.24.8 + '@babel/types': 7.24.8 transitivePeerDependencies: - supports-color dev: true - /@babel/helper-compilation-targets@7.24.7: - resolution: {integrity: sha512-ctSdRHBi20qWOfy27RUb4Fhp07KSJ3sXcuSvTrXrc4aG8NSYDo1ici3Vhg9bg69y5bj0Mr1lh0aeEgTvc12rMg==} + /@babel/helper-compilation-targets@7.24.8: + resolution: {integrity: sha512-oU+UoqCHdp+nWVDkpldqIQL/i/bvAv53tRqLG/s+cOXxe66zOYLU7ar/Xs3LdmBihrUMEUhwu6dMZwbNOYDwvw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/compat-data': 7.24.7 - '@babel/helper-validator-option': 7.24.7 + '@babel/compat-data': 7.24.8 + '@babel/helper-validator-option': 7.24.8 browserslist: 4.23.2 lru-cache: 5.1.1 semver: 6.3.1 dev: true - /@babel/helper-create-class-features-plugin@7.24.7(@babel/core@7.24.7): - resolution: {integrity: sha512-kTkaDl7c9vO80zeX1rJxnuRpEsD5tA81yh11X1gQo+PhSti3JS+7qeZo9U4RHobKRiFPKaGK3svUAeb8D0Q7eg==} + /@babel/helper-create-class-features-plugin@7.24.8(@babel/core@7.24.8): + resolution: {integrity: sha512-4f6Oqnmyp2PP3olgUMmOwC3akxSm5aBYraQ6YDdKy7NcAMkDECHWG0DEnV6M2UAkERgIBhYt8S27rURPg7SxWA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.24.7 + '@babel/core': 7.24.8 '@babel/helper-annotate-as-pure': 7.24.7 '@babel/helper-environment-visitor': 7.24.7 '@babel/helper-function-name': 7.24.7 - '@babel/helper-member-expression-to-functions': 7.24.7 + '@babel/helper-member-expression-to-functions': 7.24.8 '@babel/helper-optimise-call-expression': 7.24.7 - '@babel/helper-replace-supers': 7.24.7(@babel/core@7.24.7) + '@babel/helper-replace-supers': 7.24.7(@babel/core@7.24.8) '@babel/helper-skip-transparent-expression-wrappers': 7.24.7 '@babel/helper-split-export-declaration': 7.24.7 semver: 6.3.1 @@ -221,26 +221,26 @@ packages: - supports-color dev: true - /@babel/helper-create-regexp-features-plugin@7.24.7(@babel/core@7.24.7): + /@babel/helper-create-regexp-features-plugin@7.24.7(@babel/core@7.24.8): resolution: {integrity: sha512-03TCmXy2FtXJEZfbXDTSqq1fRJArk7lX9DOFC/47VthYcxyIOx+eXQmdo6DOQvrbpIix+KfXwvuXdFDZHxt+rA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.24.7 + '@babel/core': 7.24.8 '@babel/helper-annotate-as-pure': 7.24.7 regexpu-core: 5.3.2 semver: 6.3.1 dev: true - /@babel/helper-define-polyfill-provider@0.6.2(@babel/core@7.24.7): + /@babel/helper-define-polyfill-provider@0.6.2(@babel/core@7.24.8): resolution: {integrity: sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 dependencies: - '@babel/core': 7.24.7 - '@babel/helper-compilation-targets': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 + '@babel/core': 7.24.8 + '@babel/helper-compilation-targets': 7.24.8 + '@babel/helper-plugin-utils': 7.24.8 debug: 4.3.5 lodash.debounce: 4.0.8 resolve: 1.22.8 @@ -252,7 +252,7 @@ packages: resolution: {integrity: sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.24.7 + '@babel/types': 7.24.8 dev: true /@babel/helper-function-name@7.24.7: @@ -260,22 +260,22 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@babel/template': 7.24.7 - '@babel/types': 7.24.7 + '@babel/types': 7.24.8 dev: true /@babel/helper-hoist-variables@7.24.7: resolution: {integrity: sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.24.7 + '@babel/types': 7.24.8 dev: true - /@babel/helper-member-expression-to-functions@7.24.7: - resolution: {integrity: sha512-LGeMaf5JN4hAT471eJdBs/GK1DoYIJ5GCtZN/EsL6KUiiDZOvO/eKE11AMZJa2zP4zk4qe9V2O/hxAmkRc8p6w==} + /@babel/helper-member-expression-to-functions@7.24.8: + resolution: {integrity: sha512-LABppdt+Lp/RlBxqrh4qgf1oEH/WxdzQNDJIu5gC/W1GyvPVrOBiItmmM8wan2fm4oYqFuFfkXmlGpLQhPY8CA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/traverse': 7.24.7 - '@babel/types': 7.24.7 + '@babel/traverse': 7.24.8 + '@babel/types': 7.24.8 transitivePeerDependencies: - supports-color dev: true @@ -284,26 +284,26 @@ packages: resolution: {integrity: sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.24.7 + '@babel/types': 7.24.8 dev: true /@babel/helper-module-imports@7.24.7: resolution: {integrity: sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/traverse': 7.24.7 - '@babel/types': 7.24.7 + '@babel/traverse': 7.24.8 + '@babel/types': 7.24.8 transitivePeerDependencies: - supports-color dev: true - /@babel/helper-module-transforms@7.24.7(@babel/core@7.24.7): - resolution: {integrity: sha512-1fuJEwIrp+97rM4RWdO+qrRsZlAeL1lQJoPqtCYWv0NL115XM93hIH4CSRln2w52SqvmY5hqdtauB6QFCDiZNQ==} + /@babel/helper-module-transforms@7.24.8(@babel/core@7.24.8): + resolution: {integrity: sha512-m4vWKVqvkVAWLXfHCCfff2luJj86U+J0/x+0N3ArG/tP0Fq7zky2dYwMbtPmkc/oulkkbjdL3uWzuoBwQ8R00Q==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.24.7 + '@babel/core': 7.24.8 '@babel/helper-environment-visitor': 7.24.7 '@babel/helper-module-imports': 7.24.7 '@babel/helper-simple-access': 7.24.7 @@ -317,21 +317,21 @@ packages: resolution: {integrity: sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.24.7 + '@babel/types': 7.24.8 dev: true - /@babel/helper-plugin-utils@7.24.7: - resolution: {integrity: sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==} + /@babel/helper-plugin-utils@7.24.8: + resolution: {integrity: sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==} engines: {node: '>=6.9.0'} dev: true - /@babel/helper-remap-async-to-generator@7.24.7(@babel/core@7.24.7): + /@babel/helper-remap-async-to-generator@7.24.7(@babel/core@7.24.8): resolution: {integrity: sha512-9pKLcTlZ92hNZMQfGCHImUpDOlAgkkpqalWEeftW5FBya75k8Li2ilerxkM/uBEj01iBZXcCIB/bwvDYgWyibA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.24.7 + '@babel/core': 7.24.8 '@babel/helper-annotate-as-pure': 7.24.7 '@babel/helper-environment-visitor': 7.24.7 '@babel/helper-wrap-function': 7.24.7 @@ -339,15 +339,15 @@ packages: - supports-color dev: true - /@babel/helper-replace-supers@7.24.7(@babel/core@7.24.7): + /@babel/helper-replace-supers@7.24.7(@babel/core@7.24.8): resolution: {integrity: sha512-qTAxxBM81VEyoAY0TtLrx1oAEJc09ZK67Q9ljQToqCnA+55eNwCORaxlKyu+rNfX86o8OXRUSNUnrtsAZXM9sg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.24.7 + '@babel/core': 7.24.8 '@babel/helper-environment-visitor': 7.24.7 - '@babel/helper-member-expression-to-functions': 7.24.7 + '@babel/helper-member-expression-to-functions': 7.24.8 '@babel/helper-optimise-call-expression': 7.24.7 transitivePeerDependencies: - supports-color @@ -357,8 +357,8 @@ packages: resolution: {integrity: sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==} engines: {node: '>=6.9.0'} dependencies: - '@babel/traverse': 7.24.7 - '@babel/types': 7.24.7 + '@babel/traverse': 7.24.8 + '@babel/types': 7.24.8 transitivePeerDependencies: - supports-color dev: true @@ -367,8 +367,8 @@ packages: resolution: {integrity: sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==} engines: {node: '>=6.9.0'} dependencies: - '@babel/traverse': 7.24.7 - '@babel/types': 7.24.7 + '@babel/traverse': 7.24.8 + '@babel/types': 7.24.8 transitivePeerDependencies: - supports-color dev: true @@ -377,11 +377,11 @@ packages: resolution: {integrity: sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.24.7 + '@babel/types': 7.24.8 dev: true - /@babel/helper-string-parser@7.24.7: - resolution: {integrity: sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==} + /@babel/helper-string-parser@7.24.8: + resolution: {integrity: sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==} engines: {node: '>=6.9.0'} dev: true @@ -390,8 +390,8 @@ packages: engines: {node: '>=6.9.0'} dev: true - /@babel/helper-validator-option@7.24.7: - resolution: {integrity: sha512-yy1/KvjhV/ZCL+SM7hBrvnZJ3ZuT9OuZgIJAGpPEToANvc3iM6iDvBnRjtElWibHU6n8/LPR/EjX9EtIEYO3pw==} + /@babel/helper-validator-option@7.24.8: + resolution: {integrity: sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==} engines: {node: '>=6.9.0'} dev: true @@ -401,18 +401,18 @@ packages: dependencies: '@babel/helper-function-name': 7.24.7 '@babel/template': 7.24.7 - '@babel/traverse': 7.24.7 - '@babel/types': 7.24.7 + '@babel/traverse': 7.24.8 + '@babel/types': 7.24.8 transitivePeerDependencies: - supports-color dev: true - /@babel/helpers@7.24.7: - resolution: {integrity: sha512-NlmJJtvcw72yRJRcnCmGvSi+3jDEg8qFu3z0AFoymmzLx5ERVWyzd9kVXr7Th9/8yIJi2Zc6av4Tqz3wFs8QWg==} + /@babel/helpers@7.24.8: + resolution: {integrity: sha512-gV2265Nkcz7weJJfvDoAEVzC1e2OTDpkGbEsebse8koXUJUXPsCMi7sRo/+SPMuMZ9MtUPnGwITTnQnU5YjyaQ==} engines: {node: '>=6.9.0'} dependencies: '@babel/template': 7.24.7 - '@babel/types': 7.24.7 + '@babel/types': 7.24.8 dev: true /@babel/highlight@7.24.7: @@ -425,911 +425,911 @@ packages: picocolors: 1.0.1 dev: true - /@babel/parser@7.24.7: - resolution: {integrity: sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==} + /@babel/parser@7.24.8: + resolution: {integrity: sha512-WzfbgXOkGzZiXXCqk43kKwZjzwx4oulxZi3nq2TYL9mOjQv6kYwul9mz6ID36njuL7Xkp6nJEfok848Zj10j/w==} engines: {node: '>=6.0.0'} hasBin: true dependencies: - '@babel/types': 7.24.7 + '@babel/types': 7.24.8 dev: true - /@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.24.7(@babel/core@7.24.7): + /@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.24.7(@babel/core@7.24.8): resolution: {integrity: sha512-TiT1ss81W80eQsN+722OaeQMY/G4yTb4G9JrqeiDADs3N8lbPMGldWi9x8tyqCW5NLx1Jh2AvkE6r6QvEltMMQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.24.7 + '@babel/core': 7.24.8 '@babel/helper-environment-visitor': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 + '@babel/helper-plugin-utils': 7.24.8 dev: true - /@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.24.7(@babel/core@7.24.7): + /@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.24.7(@babel/core@7.24.8): resolution: {integrity: sha512-unaQgZ/iRu/By6tsjMZzpeBZjChYfLYry6HrEXPoz3KmfF0sVBQ1l8zKMQ4xRGLWVsjuvB8nQfjNP/DcfEOCsg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 + '@babel/core': 7.24.8 + '@babel/helper-plugin-utils': 7.24.8 dev: true - /@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.24.7(@babel/core@7.24.7): + /@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.24.7(@babel/core@7.24.8): resolution: {integrity: sha512-+izXIbke1T33mY4MSNnrqhPXDz01WYhEf3yF5NbnUtkiNnm+XBZJl3kNfoK6NKmYlz/D07+l2GWVK/QfDkNCuQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.13.0 dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 + '@babel/core': 7.24.8 + '@babel/helper-plugin-utils': 7.24.8 '@babel/helper-skip-transparent-expression-wrappers': 7.24.7 - '@babel/plugin-transform-optional-chaining': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-optional-chaining': 7.24.8(@babel/core@7.24.8) transitivePeerDependencies: - supports-color dev: true - /@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.24.7(@babel/core@7.24.7): + /@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.24.7(@babel/core@7.24.8): resolution: {integrity: sha512-utA4HuR6F4Vvcr+o4DnjL8fCOlgRFGbeeBEGNg3ZTrLFw6VWG5XmUrvcQ0FjIYMU2ST4XcR2Wsp7t9qOAPnxMg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.24.7 + '@babel/core': 7.24.8 '@babel/helper-environment-visitor': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 + '@babel/helper-plugin-utils': 7.24.8 dev: true - /@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.24.7): + /@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.24.8): resolution: {integrity: sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.7 + '@babel/core': 7.24.8 dev: true - /@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.24.7): + /@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.24.8): resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 + '@babel/core': 7.24.8 + '@babel/helper-plugin-utils': 7.24.8 dev: true - /@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.24.7): + /@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.24.8): resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 + '@babel/core': 7.24.8 + '@babel/helper-plugin-utils': 7.24.8 dev: true - /@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.24.7): + /@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.24.8): resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 + '@babel/core': 7.24.8 + '@babel/helper-plugin-utils': 7.24.8 dev: true - /@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.24.7): + /@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.24.8): resolution: {integrity: sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 + '@babel/core': 7.24.8 + '@babel/helper-plugin-utils': 7.24.8 dev: true - /@babel/plugin-syntax-export-namespace-from@7.8.3(@babel/core@7.24.7): + /@babel/plugin-syntax-export-namespace-from@7.8.3(@babel/core@7.24.8): resolution: {integrity: sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 + '@babel/core': 7.24.8 + '@babel/helper-plugin-utils': 7.24.8 dev: true - /@babel/plugin-syntax-import-assertions@7.24.7(@babel/core@7.24.7): + /@babel/plugin-syntax-import-assertions@7.24.7(@babel/core@7.24.8): resolution: {integrity: sha512-Ec3NRUMoi8gskrkBe3fNmEQfxDvY8bgfQpz6jlk/41kX9eUjvpyqWU7PBP/pLAvMaSQjbMNKJmvX57jP+M6bPg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 + '@babel/core': 7.24.8 + '@babel/helper-plugin-utils': 7.24.8 dev: true - /@babel/plugin-syntax-import-attributes@7.24.7(@babel/core@7.24.7): + /@babel/plugin-syntax-import-attributes@7.24.7(@babel/core@7.24.8): resolution: {integrity: sha512-hbX+lKKeUMGihnK8nvKqmXBInriT3GVjzXKFriV3YC6APGxMbP8RZNFwy91+hocLXq90Mta+HshoB31802bb8A==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 + '@babel/core': 7.24.8 + '@babel/helper-plugin-utils': 7.24.8 dev: true - /@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.24.7): + /@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.24.8): resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 + '@babel/core': 7.24.8 + '@babel/helper-plugin-utils': 7.24.8 dev: true - /@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.24.7): + /@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.24.8): resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 + '@babel/core': 7.24.8 + '@babel/helper-plugin-utils': 7.24.8 dev: true - /@babel/plugin-syntax-jsx@7.24.7(@babel/core@7.24.7): + /@babel/plugin-syntax-jsx@7.24.7(@babel/core@7.24.8): resolution: {integrity: sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 + '@babel/core': 7.24.8 + '@babel/helper-plugin-utils': 7.24.8 dev: true - /@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.24.7): + /@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.24.8): resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 + '@babel/core': 7.24.8 + '@babel/helper-plugin-utils': 7.24.8 dev: true - /@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.24.7): + /@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.24.8): resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 + '@babel/core': 7.24.8 + '@babel/helper-plugin-utils': 7.24.8 dev: true - /@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.24.7): + /@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.24.8): resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 + '@babel/core': 7.24.8 + '@babel/helper-plugin-utils': 7.24.8 dev: true - /@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.24.7): + /@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.24.8): resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 + '@babel/core': 7.24.8 + '@babel/helper-plugin-utils': 7.24.8 dev: true - /@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.24.7): + /@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.24.8): resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 + '@babel/core': 7.24.8 + '@babel/helper-plugin-utils': 7.24.8 dev: true - /@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.24.7): + /@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.24.8): resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 + '@babel/core': 7.24.8 + '@babel/helper-plugin-utils': 7.24.8 dev: true - /@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.24.7): + /@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.24.8): resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 + '@babel/core': 7.24.8 + '@babel/helper-plugin-utils': 7.24.8 dev: true - /@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.24.7): + /@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.24.8): resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 + '@babel/core': 7.24.8 + '@babel/helper-plugin-utils': 7.24.8 dev: true - /@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.24.7): + /@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.24.8): resolution: {integrity: sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.24.7 - '@babel/helper-create-regexp-features-plugin': 7.24.7(@babel/core@7.24.7) - '@babel/helper-plugin-utils': 7.24.7 + '@babel/core': 7.24.8 + '@babel/helper-create-regexp-features-plugin': 7.24.7(@babel/core@7.24.8) + '@babel/helper-plugin-utils': 7.24.8 dev: true - /@babel/plugin-transform-arrow-functions@7.24.7(@babel/core@7.24.7): + /@babel/plugin-transform-arrow-functions@7.24.7(@babel/core@7.24.8): resolution: {integrity: sha512-Dt9LQs6iEY++gXUwY03DNFat5C2NbO48jj+j/bSAz6b3HgPs39qcPiYt77fDObIcFwj3/C2ICX9YMwGflUoSHQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 + '@babel/core': 7.24.8 + '@babel/helper-plugin-utils': 7.24.8 dev: true - /@babel/plugin-transform-async-generator-functions@7.24.7(@babel/core@7.24.7): + /@babel/plugin-transform-async-generator-functions@7.24.7(@babel/core@7.24.8): resolution: {integrity: sha512-o+iF77e3u7ZS4AoAuJvapz9Fm001PuD2V3Lp6OSE4FYQke+cSewYtnek+THqGRWyQloRCyvWL1OkyfNEl9vr/g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.7 + '@babel/core': 7.24.8 '@babel/helper-environment-visitor': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - '@babel/helper-remap-async-to-generator': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.24.7) + '@babel/helper-plugin-utils': 7.24.8 + '@babel/helper-remap-async-to-generator': 7.24.7(@babel/core@7.24.8) + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.24.8) transitivePeerDependencies: - supports-color dev: true - /@babel/plugin-transform-async-to-generator@7.24.7(@babel/core@7.24.7): + /@babel/plugin-transform-async-to-generator@7.24.7(@babel/core@7.24.8): resolution: {integrity: sha512-SQY01PcJfmQ+4Ash7NE+rpbLFbmqA2GPIgqzxfFTL4t1FKRq4zTms/7htKpoCUI9OcFYgzqfmCdH53s6/jn5fA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.7 + '@babel/core': 7.24.8 '@babel/helper-module-imports': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - '@babel/helper-remap-async-to-generator': 7.24.7(@babel/core@7.24.7) + '@babel/helper-plugin-utils': 7.24.8 + '@babel/helper-remap-async-to-generator': 7.24.7(@babel/core@7.24.8) transitivePeerDependencies: - supports-color dev: true - /@babel/plugin-transform-block-scoped-functions@7.24.7(@babel/core@7.24.7): + /@babel/plugin-transform-block-scoped-functions@7.24.7(@babel/core@7.24.8): resolution: {integrity: sha512-yO7RAz6EsVQDaBH18IDJcMB1HnrUn2FJ/Jslc/WtPPWcjhpUJXU/rjbwmluzp7v/ZzWcEhTMXELnnsz8djWDwQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 + '@babel/core': 7.24.8 + '@babel/helper-plugin-utils': 7.24.8 dev: true - /@babel/plugin-transform-block-scoping@7.24.7(@babel/core@7.24.7): + /@babel/plugin-transform-block-scoping@7.24.7(@babel/core@7.24.8): resolution: {integrity: sha512-Nd5CvgMbWc+oWzBsuaMcbwjJWAcp5qzrbg69SZdHSP7AMY0AbWFqFO0WTFCA1jxhMCwodRwvRec8k0QUbZk7RQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 + '@babel/core': 7.24.8 + '@babel/helper-plugin-utils': 7.24.8 dev: true - /@babel/plugin-transform-class-properties@7.24.7(@babel/core@7.24.7): + /@babel/plugin-transform-class-properties@7.24.7(@babel/core@7.24.8): resolution: {integrity: sha512-vKbfawVYayKcSeSR5YYzzyXvsDFWU2mD8U5TFeXtbCPLFUqe7GyCgvO6XDHzje862ODrOwy6WCPmKeWHbCFJ4w==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.7 - '@babel/helper-create-class-features-plugin': 7.24.7(@babel/core@7.24.7) - '@babel/helper-plugin-utils': 7.24.7 + '@babel/core': 7.24.8 + '@babel/helper-create-class-features-plugin': 7.24.8(@babel/core@7.24.8) + '@babel/helper-plugin-utils': 7.24.8 transitivePeerDependencies: - supports-color dev: true - /@babel/plugin-transform-class-static-block@7.24.7(@babel/core@7.24.7): + /@babel/plugin-transform-class-static-block@7.24.7(@babel/core@7.24.8): resolution: {integrity: sha512-HMXK3WbBPpZQufbMG4B46A90PkuuhN9vBCb5T8+VAHqvAqvcLi+2cKoukcpmUYkszLhScU3l1iudhrks3DggRQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.12.0 dependencies: - '@babel/core': 7.24.7 - '@babel/helper-create-class-features-plugin': 7.24.7(@babel/core@7.24.7) - '@babel/helper-plugin-utils': 7.24.7 - '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.24.7) + '@babel/core': 7.24.8 + '@babel/helper-create-class-features-plugin': 7.24.8(@babel/core@7.24.8) + '@babel/helper-plugin-utils': 7.24.8 + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.24.8) transitivePeerDependencies: - supports-color dev: true - /@babel/plugin-transform-classes@7.24.7(@babel/core@7.24.7): - resolution: {integrity: sha512-CFbbBigp8ln4FU6Bpy6g7sE8B/WmCmzvivzUC6xDAdWVsjYTXijpuuGJmYkAaoWAzcItGKT3IOAbxRItZ5HTjw==} + /@babel/plugin-transform-classes@7.24.8(@babel/core@7.24.8): + resolution: {integrity: sha512-VXy91c47uujj758ud9wx+OMgheXm4qJfyhj1P18YvlrQkNOSrwsteHk+EFS3OMGfhMhpZa0A+81eE7G4QC+3CA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.7 + '@babel/core': 7.24.8 '@babel/helper-annotate-as-pure': 7.24.7 - '@babel/helper-compilation-targets': 7.24.7 + '@babel/helper-compilation-targets': 7.24.8 '@babel/helper-environment-visitor': 7.24.7 '@babel/helper-function-name': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - '@babel/helper-replace-supers': 7.24.7(@babel/core@7.24.7) + '@babel/helper-plugin-utils': 7.24.8 + '@babel/helper-replace-supers': 7.24.7(@babel/core@7.24.8) '@babel/helper-split-export-declaration': 7.24.7 globals: 11.12.0 transitivePeerDependencies: - supports-color dev: true - /@babel/plugin-transform-computed-properties@7.24.7(@babel/core@7.24.7): + /@babel/plugin-transform-computed-properties@7.24.7(@babel/core@7.24.8): resolution: {integrity: sha512-25cS7v+707Gu6Ds2oY6tCkUwsJ9YIDbggd9+cu9jzzDgiNq7hR/8dkzxWfKWnTic26vsI3EsCXNd4iEB6e8esQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 + '@babel/core': 7.24.8 + '@babel/helper-plugin-utils': 7.24.8 '@babel/template': 7.24.7 dev: true - /@babel/plugin-transform-destructuring@7.24.7(@babel/core@7.24.7): - resolution: {integrity: sha512-19eJO/8kdCQ9zISOf+SEUJM/bAUIsvY3YDnXZTupUCQ8LgrWnsG/gFB9dvXqdXnRXMAM8fvt7b0CBKQHNGy1mw==} + /@babel/plugin-transform-destructuring@7.24.8(@babel/core@7.24.8): + resolution: {integrity: sha512-36e87mfY8TnRxc7yc6M9g9gOB7rKgSahqkIKwLpz4Ppk2+zC2Cy1is0uwtuSG6AE4zlTOUa+7JGz9jCJGLqQFQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 + '@babel/core': 7.24.8 + '@babel/helper-plugin-utils': 7.24.8 dev: true - /@babel/plugin-transform-dotall-regex@7.24.7(@babel/core@7.24.7): + /@babel/plugin-transform-dotall-regex@7.24.7(@babel/core@7.24.8): resolution: {integrity: sha512-ZOA3W+1RRTSWvyqcMJDLqbchh7U4NRGqwRfFSVbOLS/ePIP4vHB5e8T8eXcuqyN1QkgKyj5wuW0lcS85v4CrSw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.7 - '@babel/helper-create-regexp-features-plugin': 7.24.7(@babel/core@7.24.7) - '@babel/helper-plugin-utils': 7.24.7 + '@babel/core': 7.24.8 + '@babel/helper-create-regexp-features-plugin': 7.24.7(@babel/core@7.24.8) + '@babel/helper-plugin-utils': 7.24.8 dev: true - /@babel/plugin-transform-duplicate-keys@7.24.7(@babel/core@7.24.7): + /@babel/plugin-transform-duplicate-keys@7.24.7(@babel/core@7.24.8): resolution: {integrity: sha512-JdYfXyCRihAe46jUIliuL2/s0x0wObgwwiGxw/UbgJBr20gQBThrokO4nYKgWkD7uBaqM7+9x5TU7NkExZJyzw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 + '@babel/core': 7.24.8 + '@babel/helper-plugin-utils': 7.24.8 dev: true - /@babel/plugin-transform-dynamic-import@7.24.7(@babel/core@7.24.7): + /@babel/plugin-transform-dynamic-import@7.24.7(@babel/core@7.24.8): resolution: {integrity: sha512-sc3X26PhZQDb3JhORmakcbvkeInvxz+A8oda99lj7J60QRuPZvNAk9wQlTBS1ZynelDrDmTU4pw1tyc5d5ZMUg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.24.7) + '@babel/core': 7.24.8 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.24.8) dev: true - /@babel/plugin-transform-exponentiation-operator@7.24.7(@babel/core@7.24.7): + /@babel/plugin-transform-exponentiation-operator@7.24.7(@babel/core@7.24.8): resolution: {integrity: sha512-Rqe/vSc9OYgDajNIK35u7ot+KeCoetqQYFXM4Epf7M7ez3lWlOjrDjrwMei6caCVhfdw+mIKD4cgdGNy5JQotQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.7 + '@babel/core': 7.24.8 '@babel/helper-builder-binary-assignment-operator-visitor': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 + '@babel/helper-plugin-utils': 7.24.8 transitivePeerDependencies: - supports-color dev: true - /@babel/plugin-transform-export-namespace-from@7.24.7(@babel/core@7.24.7): + /@babel/plugin-transform-export-namespace-from@7.24.7(@babel/core@7.24.8): resolution: {integrity: sha512-v0K9uNYsPL3oXZ/7F9NNIbAj2jv1whUEtyA6aujhekLs56R++JDQuzRcP2/z4WX5Vg/c5lE9uWZA0/iUoFhLTA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.24.7) + '@babel/core': 7.24.8 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.24.8) dev: true - /@babel/plugin-transform-for-of@7.24.7(@babel/core@7.24.7): + /@babel/plugin-transform-for-of@7.24.7(@babel/core@7.24.8): resolution: {integrity: sha512-wo9ogrDG1ITTTBsy46oGiN1dS9A7MROBTcYsfS8DtsImMkHk9JXJ3EWQM6X2SUw4x80uGPlwj0o00Uoc6nEE3g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 + '@babel/core': 7.24.8 + '@babel/helper-plugin-utils': 7.24.8 '@babel/helper-skip-transparent-expression-wrappers': 7.24.7 transitivePeerDependencies: - supports-color dev: true - /@babel/plugin-transform-function-name@7.24.7(@babel/core@7.24.7): + /@babel/plugin-transform-function-name@7.24.7(@babel/core@7.24.8): resolution: {integrity: sha512-U9FcnA821YoILngSmYkW6FjyQe2TyZD5pHt4EVIhmcTkrJw/3KqcrRSxuOo5tFZJi7TE19iDyI1u+weTI7bn2w==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.7 - '@babel/helper-compilation-targets': 7.24.7 + '@babel/core': 7.24.8 + '@babel/helper-compilation-targets': 7.24.8 '@babel/helper-function-name': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 + '@babel/helper-plugin-utils': 7.24.8 dev: true - /@babel/plugin-transform-json-strings@7.24.7(@babel/core@7.24.7): + /@babel/plugin-transform-json-strings@7.24.7(@babel/core@7.24.8): resolution: {integrity: sha512-2yFnBGDvRuxAaE/f0vfBKvtnvvqU8tGpMHqMNpTN2oWMKIR3NqFkjaAgGwawhqK/pIN2T3XdjGPdaG0vDhOBGw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.24.7) + '@babel/core': 7.24.8 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.24.8) dev: true - /@babel/plugin-transform-literals@7.24.7(@babel/core@7.24.7): + /@babel/plugin-transform-literals@7.24.7(@babel/core@7.24.8): resolution: {integrity: sha512-vcwCbb4HDH+hWi8Pqenwnjy+UiklO4Kt1vfspcQYFhJdpthSnW8XvWGyDZWKNVrVbVViI/S7K9PDJZiUmP2fYQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 + '@babel/core': 7.24.8 + '@babel/helper-plugin-utils': 7.24.8 dev: true - /@babel/plugin-transform-logical-assignment-operators@7.24.7(@babel/core@7.24.7): + /@babel/plugin-transform-logical-assignment-operators@7.24.7(@babel/core@7.24.8): resolution: {integrity: sha512-4D2tpwlQ1odXmTEIFWy9ELJcZHqrStlzK/dAOWYyxX3zT0iXQB6banjgeOJQXzEc4S0E0a5A+hahxPaEFYftsw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.24.7) + '@babel/core': 7.24.8 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.24.8) dev: true - /@babel/plugin-transform-member-expression-literals@7.24.7(@babel/core@7.24.7): + /@babel/plugin-transform-member-expression-literals@7.24.7(@babel/core@7.24.8): resolution: {integrity: sha512-T/hRC1uqrzXMKLQ6UCwMT85S3EvqaBXDGf0FaMf4446Qx9vKwlghvee0+uuZcDUCZU5RuNi4781UQ7R308zzBw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 + '@babel/core': 7.24.8 + '@babel/helper-plugin-utils': 7.24.8 dev: true - /@babel/plugin-transform-modules-amd@7.24.7(@babel/core@7.24.7): + /@babel/plugin-transform-modules-amd@7.24.7(@babel/core@7.24.8): resolution: {integrity: sha512-9+pB1qxV3vs/8Hdmz/CulFB8w2tuu6EB94JZFsjdqxQokwGa9Unap7Bo2gGBGIvPmDIVvQrom7r5m/TCDMURhg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.7 - '@babel/helper-module-transforms': 7.24.7(@babel/core@7.24.7) - '@babel/helper-plugin-utils': 7.24.7 + '@babel/core': 7.24.8 + '@babel/helper-module-transforms': 7.24.8(@babel/core@7.24.8) + '@babel/helper-plugin-utils': 7.24.8 transitivePeerDependencies: - supports-color dev: true - /@babel/plugin-transform-modules-commonjs@7.24.7(@babel/core@7.24.7): - resolution: {integrity: sha512-iFI8GDxtevHJ/Z22J5xQpVqFLlMNstcLXh994xifFwxxGslr2ZXXLWgtBeLctOD63UFDArdvN6Tg8RFw+aEmjQ==} + /@babel/plugin-transform-modules-commonjs@7.24.8(@babel/core@7.24.8): + resolution: {integrity: sha512-WHsk9H8XxRs3JXKWFiqtQebdh9b/pTk4EgueygFzYlTKAg0Ud985mSevdNjdXdFBATSKVJGQXP1tv6aGbssLKA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.7 - '@babel/helper-module-transforms': 7.24.7(@babel/core@7.24.7) - '@babel/helper-plugin-utils': 7.24.7 + '@babel/core': 7.24.8 + '@babel/helper-module-transforms': 7.24.8(@babel/core@7.24.8) + '@babel/helper-plugin-utils': 7.24.8 '@babel/helper-simple-access': 7.24.7 transitivePeerDependencies: - supports-color dev: true - /@babel/plugin-transform-modules-systemjs@7.24.7(@babel/core@7.24.7): + /@babel/plugin-transform-modules-systemjs@7.24.7(@babel/core@7.24.8): resolution: {integrity: sha512-GYQE0tW7YoaN13qFh3O1NCY4MPkUiAH3fiF7UcV/I3ajmDKEdG3l+UOcbAm4zUE3gnvUU+Eni7XrVKo9eO9auw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.7 + '@babel/core': 7.24.8 '@babel/helper-hoist-variables': 7.24.7 - '@babel/helper-module-transforms': 7.24.7(@babel/core@7.24.7) - '@babel/helper-plugin-utils': 7.24.7 + '@babel/helper-module-transforms': 7.24.8(@babel/core@7.24.8) + '@babel/helper-plugin-utils': 7.24.8 '@babel/helper-validator-identifier': 7.24.7 transitivePeerDependencies: - supports-color dev: true - /@babel/plugin-transform-modules-umd@7.24.7(@babel/core@7.24.7): + /@babel/plugin-transform-modules-umd@7.24.7(@babel/core@7.24.8): resolution: {integrity: sha512-3aytQvqJ/h9z4g8AsKPLvD4Zqi2qT+L3j7XoFFu1XBlZWEl2/1kWnhmAbxpLgPrHSY0M6UA02jyTiwUVtiKR6A==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.7 - '@babel/helper-module-transforms': 7.24.7(@babel/core@7.24.7) - '@babel/helper-plugin-utils': 7.24.7 + '@babel/core': 7.24.8 + '@babel/helper-module-transforms': 7.24.8(@babel/core@7.24.8) + '@babel/helper-plugin-utils': 7.24.8 transitivePeerDependencies: - supports-color dev: true - /@babel/plugin-transform-named-capturing-groups-regex@7.24.7(@babel/core@7.24.7): + /@babel/plugin-transform-named-capturing-groups-regex@7.24.7(@babel/core@7.24.8): resolution: {integrity: sha512-/jr7h/EWeJtk1U/uz2jlsCioHkZk1JJZVcc8oQsJ1dUlaJD83f4/6Zeh2aHt9BIFokHIsSeDfhUmju0+1GPd6g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.24.7 - '@babel/helper-create-regexp-features-plugin': 7.24.7(@babel/core@7.24.7) - '@babel/helper-plugin-utils': 7.24.7 + '@babel/core': 7.24.8 + '@babel/helper-create-regexp-features-plugin': 7.24.7(@babel/core@7.24.8) + '@babel/helper-plugin-utils': 7.24.8 dev: true - /@babel/plugin-transform-new-target@7.24.7(@babel/core@7.24.7): + /@babel/plugin-transform-new-target@7.24.7(@babel/core@7.24.8): resolution: {integrity: sha512-RNKwfRIXg4Ls/8mMTza5oPF5RkOW8Wy/WgMAp1/F1yZ8mMbtwXW+HDoJiOsagWrAhI5f57Vncrmr9XeT4CVapA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 + '@babel/core': 7.24.8 + '@babel/helper-plugin-utils': 7.24.8 dev: true - /@babel/plugin-transform-nullish-coalescing-operator@7.24.7(@babel/core@7.24.7): + /@babel/plugin-transform-nullish-coalescing-operator@7.24.7(@babel/core@7.24.8): resolution: {integrity: sha512-Ts7xQVk1OEocqzm8rHMXHlxvsfZ0cEF2yomUqpKENHWMF4zKk175Y4q8H5knJes6PgYad50uuRmt3UJuhBw8pQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.24.7) + '@babel/core': 7.24.8 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.24.8) dev: true - /@babel/plugin-transform-numeric-separator@7.24.7(@babel/core@7.24.7): + /@babel/plugin-transform-numeric-separator@7.24.7(@babel/core@7.24.8): resolution: {integrity: sha512-e6q1TiVUzvH9KRvicuxdBTUj4AdKSRwzIyFFnfnezpCfP2/7Qmbb8qbU2j7GODbl4JMkblitCQjKYUaX/qkkwA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.24.7) + '@babel/core': 7.24.8 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.24.8) dev: true - /@babel/plugin-transform-object-rest-spread@7.24.7(@babel/core@7.24.7): + /@babel/plugin-transform-object-rest-spread@7.24.7(@babel/core@7.24.8): resolution: {integrity: sha512-4QrHAr0aXQCEFni2q4DqKLD31n2DL+RxcwnNjDFkSG0eNQ/xCavnRkfCUjsyqGC2OviNJvZOF/mQqZBw7i2C5Q==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.7 - '@babel/helper-compilation-targets': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.24.7) - '@babel/plugin-transform-parameters': 7.24.7(@babel/core@7.24.7) + '@babel/core': 7.24.8 + '@babel/helper-compilation-targets': 7.24.8 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.24.8) + '@babel/plugin-transform-parameters': 7.24.7(@babel/core@7.24.8) dev: true - /@babel/plugin-transform-object-super@7.24.7(@babel/core@7.24.7): + /@babel/plugin-transform-object-super@7.24.7(@babel/core@7.24.8): resolution: {integrity: sha512-A/vVLwN6lBrMFmMDmPPz0jnE6ZGx7Jq7d6sT/Ev4H65RER6pZ+kczlf1DthF5N0qaPHBsI7UXiE8Zy66nmAovg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - '@babel/helper-replace-supers': 7.24.7(@babel/core@7.24.7) + '@babel/core': 7.24.8 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/helper-replace-supers': 7.24.7(@babel/core@7.24.8) transitivePeerDependencies: - supports-color dev: true - /@babel/plugin-transform-optional-catch-binding@7.24.7(@babel/core@7.24.7): + /@babel/plugin-transform-optional-catch-binding@7.24.7(@babel/core@7.24.8): resolution: {integrity: sha512-uLEndKqP5BfBbC/5jTwPxLh9kqPWWgzN/f8w6UwAIirAEqiIVJWWY312X72Eub09g5KF9+Zn7+hT7sDxmhRuKA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.24.7) + '@babel/core': 7.24.8 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.24.8) dev: true - /@babel/plugin-transform-optional-chaining@7.24.7(@babel/core@7.24.7): - resolution: {integrity: sha512-tK+0N9yd4j+x/4hxF3F0e0fu/VdcxU18y5SevtyM/PCFlQvXbR0Zmlo2eBrKtVipGNFzpq56o8WsIIKcJFUCRQ==} + /@babel/plugin-transform-optional-chaining@7.24.8(@babel/core@7.24.8): + resolution: {integrity: sha512-5cTOLSMs9eypEy8JUVvIKOu6NgvbJMnpG62VpIHrTmROdQ+L5mDAaI40g25k5vXti55JWNX5jCkq3HZxXBQANw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 + '@babel/core': 7.24.8 + '@babel/helper-plugin-utils': 7.24.8 '@babel/helper-skip-transparent-expression-wrappers': 7.24.7 - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.24.7) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.24.8) transitivePeerDependencies: - supports-color dev: true - /@babel/plugin-transform-parameters@7.24.7(@babel/core@7.24.7): + /@babel/plugin-transform-parameters@7.24.7(@babel/core@7.24.8): resolution: {integrity: sha512-yGWW5Rr+sQOhK0Ot8hjDJuxU3XLRQGflvT4lhlSY0DFvdb3TwKaY26CJzHtYllU0vT9j58hc37ndFPsqT1SrzA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 + '@babel/core': 7.24.8 + '@babel/helper-plugin-utils': 7.24.8 dev: true - /@babel/plugin-transform-private-methods@7.24.7(@babel/core@7.24.7): + /@babel/plugin-transform-private-methods@7.24.7(@babel/core@7.24.8): resolution: {integrity: sha512-COTCOkG2hn4JKGEKBADkA8WNb35TGkkRbI5iT845dB+NyqgO8Hn+ajPbSnIQznneJTa3d30scb6iz/DhH8GsJQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.7 - '@babel/helper-create-class-features-plugin': 7.24.7(@babel/core@7.24.7) - '@babel/helper-plugin-utils': 7.24.7 + '@babel/core': 7.24.8 + '@babel/helper-create-class-features-plugin': 7.24.8(@babel/core@7.24.8) + '@babel/helper-plugin-utils': 7.24.8 transitivePeerDependencies: - supports-color dev: true - /@babel/plugin-transform-private-property-in-object@7.24.7(@babel/core@7.24.7): + /@babel/plugin-transform-private-property-in-object@7.24.7(@babel/core@7.24.8): resolution: {integrity: sha512-9z76mxwnwFxMyxZWEgdgECQglF2Q7cFLm0kMf8pGwt+GSJsY0cONKj/UuO4bOH0w/uAel3ekS4ra5CEAyJRmDA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.7 + '@babel/core': 7.24.8 '@babel/helper-annotate-as-pure': 7.24.7 - '@babel/helper-create-class-features-plugin': 7.24.7(@babel/core@7.24.7) - '@babel/helper-plugin-utils': 7.24.7 - '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.24.7) + '@babel/helper-create-class-features-plugin': 7.24.8(@babel/core@7.24.8) + '@babel/helper-plugin-utils': 7.24.8 + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.24.8) transitivePeerDependencies: - supports-color dev: true - /@babel/plugin-transform-property-literals@7.24.7(@babel/core@7.24.7): + /@babel/plugin-transform-property-literals@7.24.7(@babel/core@7.24.8): resolution: {integrity: sha512-EMi4MLQSHfd2nrCqQEWxFdha2gBCqU4ZcCng4WBGZ5CJL4bBRW0ptdqqDdeirGZcpALazVVNJqRmsO8/+oNCBA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 + '@babel/core': 7.24.8 + '@babel/helper-plugin-utils': 7.24.8 dev: true - /@babel/plugin-transform-regenerator@7.24.7(@babel/core@7.24.7): + /@babel/plugin-transform-regenerator@7.24.7(@babel/core@7.24.8): resolution: {integrity: sha512-lq3fvXPdimDrlg6LWBoqj+r/DEWgONuwjuOuQCSYgRroXDH/IdM1C0IZf59fL5cHLpjEH/O6opIRBbqv7ELnuA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 + '@babel/core': 7.24.8 + '@babel/helper-plugin-utils': 7.24.8 regenerator-transform: 0.15.2 dev: true - /@babel/plugin-transform-reserved-words@7.24.7(@babel/core@7.24.7): + /@babel/plugin-transform-reserved-words@7.24.7(@babel/core@7.24.8): resolution: {integrity: sha512-0DUq0pHcPKbjFZCfTss/pGkYMfy3vFWydkUBd9r0GHpIyfs2eCDENvqadMycRS9wZCXR41wucAfJHJmwA0UmoQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 + '@babel/core': 7.24.8 + '@babel/helper-plugin-utils': 7.24.8 dev: true - /@babel/plugin-transform-shorthand-properties@7.24.7(@babel/core@7.24.7): + /@babel/plugin-transform-shorthand-properties@7.24.7(@babel/core@7.24.8): resolution: {integrity: sha512-KsDsevZMDsigzbA09+vacnLpmPH4aWjcZjXdyFKGzpplxhbeB4wYtury3vglQkg6KM/xEPKt73eCjPPf1PgXBA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 + '@babel/core': 7.24.8 + '@babel/helper-plugin-utils': 7.24.8 dev: true - /@babel/plugin-transform-spread@7.24.7(@babel/core@7.24.7): + /@babel/plugin-transform-spread@7.24.7(@babel/core@7.24.8): resolution: {integrity: sha512-x96oO0I09dgMDxJaANcRyD4ellXFLLiWhuwDxKZX5g2rWP1bTPkBSwCYv96VDXVT1bD9aPj8tppr5ITIh8hBng==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 + '@babel/core': 7.24.8 + '@babel/helper-plugin-utils': 7.24.8 '@babel/helper-skip-transparent-expression-wrappers': 7.24.7 transitivePeerDependencies: - supports-color dev: true - /@babel/plugin-transform-sticky-regex@7.24.7(@babel/core@7.24.7): + /@babel/plugin-transform-sticky-regex@7.24.7(@babel/core@7.24.8): resolution: {integrity: sha512-kHPSIJc9v24zEml5geKg9Mjx5ULpfncj0wRpYtxbvKyTtHCYDkVE3aHQ03FrpEo4gEe2vrJJS1Y9CJTaThA52g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 + '@babel/core': 7.24.8 + '@babel/helper-plugin-utils': 7.24.8 dev: true - /@babel/plugin-transform-template-literals@7.24.7(@babel/core@7.24.7): + /@babel/plugin-transform-template-literals@7.24.7(@babel/core@7.24.8): resolution: {integrity: sha512-AfDTQmClklHCOLxtGoP7HkeMw56k1/bTQjwsfhL6pppo/M4TOBSq+jjBUBLmV/4oeFg4GWMavIl44ZeCtmmZTw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 + '@babel/core': 7.24.8 + '@babel/helper-plugin-utils': 7.24.8 dev: true - /@babel/plugin-transform-typeof-symbol@7.24.7(@babel/core@7.24.7): - resolution: {integrity: sha512-VtR8hDy7YLB7+Pet9IarXjg/zgCMSF+1mNS/EQEiEaUPoFXCVsHG64SIxcaaI2zJgRiv+YmgaQESUfWAdbjzgg==} + /@babel/plugin-transform-typeof-symbol@7.24.8(@babel/core@7.24.8): + resolution: {integrity: sha512-adNTUpDCVnmAE58VEqKlAA6ZBlNkMnWD0ZcW76lyNFN3MJniyGFZfNwERVk8Ap56MCnXztmDr19T4mPTztcuaw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 + '@babel/core': 7.24.8 + '@babel/helper-plugin-utils': 7.24.8 dev: true - /@babel/plugin-transform-unicode-escapes@7.24.7(@babel/core@7.24.7): + /@babel/plugin-transform-unicode-escapes@7.24.7(@babel/core@7.24.8): resolution: {integrity: sha512-U3ap1gm5+4edc2Q/P+9VrBNhGkfnf+8ZqppY71Bo/pzZmXhhLdqgaUl6cuB07O1+AQJtCLfaOmswiNbSQ9ivhw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 + '@babel/core': 7.24.8 + '@babel/helper-plugin-utils': 7.24.8 dev: true - /@babel/plugin-transform-unicode-property-regex@7.24.7(@babel/core@7.24.7): + /@babel/plugin-transform-unicode-property-regex@7.24.7(@babel/core@7.24.8): resolution: {integrity: sha512-uH2O4OV5M9FZYQrwc7NdVmMxQJOCCzFeYudlZSzUAHRFeOujQefa92E74TQDVskNHCzOXoigEuoyzHDhaEaK5w==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.7 - '@babel/helper-create-regexp-features-plugin': 7.24.7(@babel/core@7.24.7) - '@babel/helper-plugin-utils': 7.24.7 + '@babel/core': 7.24.8 + '@babel/helper-create-regexp-features-plugin': 7.24.7(@babel/core@7.24.8) + '@babel/helper-plugin-utils': 7.24.8 dev: true - /@babel/plugin-transform-unicode-regex@7.24.7(@babel/core@7.24.7): + /@babel/plugin-transform-unicode-regex@7.24.7(@babel/core@7.24.8): resolution: {integrity: sha512-hlQ96MBZSAXUq7ltkjtu3FJCCSMx/j629ns3hA3pXnBXjanNP0LHi+JpPeA81zaWgVK1VGH95Xuy7u0RyQ8kMg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.7 - '@babel/helper-create-regexp-features-plugin': 7.24.7(@babel/core@7.24.7) - '@babel/helper-plugin-utils': 7.24.7 + '@babel/core': 7.24.8 + '@babel/helper-create-regexp-features-plugin': 7.24.7(@babel/core@7.24.8) + '@babel/helper-plugin-utils': 7.24.8 dev: true - /@babel/plugin-transform-unicode-sets-regex@7.24.7(@babel/core@7.24.7): + /@babel/plugin-transform-unicode-sets-regex@7.24.7(@babel/core@7.24.8): resolution: {integrity: sha512-2G8aAvF4wy1w/AGZkemprdGMRg5o6zPNhbHVImRz3lss55TYCBd6xStN19rt8XJHq20sqV0JbyWjOWwQRwV/wg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.24.7 - '@babel/helper-create-regexp-features-plugin': 7.24.7(@babel/core@7.24.7) - '@babel/helper-plugin-utils': 7.24.7 + '@babel/core': 7.24.8 + '@babel/helper-create-regexp-features-plugin': 7.24.7(@babel/core@7.24.8) + '@babel/helper-plugin-utils': 7.24.8 dev: true - /@babel/preset-env@7.24.7(@babel/core@7.24.7): - resolution: {integrity: sha512-1YZNsc+y6cTvWlDHidMBsQZrZfEFjRIo/BZCT906PMdzOyXtSLTgqGdrpcuTDCXyd11Am5uQULtDIcCfnTc8fQ==} + /@babel/preset-env@7.24.8(@babel/core@7.24.8): + resolution: {integrity: sha512-vObvMZB6hNWuDxhSaEPTKCwcqkAIuDtE+bQGn4XMXne1DSLzFVY8Vmj1bm+mUQXYNN8NmaQEO+r8MMbzPr1jBQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/compat-data': 7.24.7 - '@babel/core': 7.24.7 - '@babel/helper-compilation-targets': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - '@babel/helper-validator-option': 7.24.7 - '@babel/plugin-bugfix-firefox-class-in-computed-class-key': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.24.7) - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.24.7) - '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.24.7) - '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.24.7) - '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.24.7) - '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.24.7) - '@babel/plugin-syntax-import-assertions': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-syntax-import-attributes': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.24.7) - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.24.7) - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.24.7) - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.24.7) - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.24.7) - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.24.7) - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.24.7) - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.24.7) - '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.24.7) - '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.24.7) - '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.24.7) - '@babel/plugin-transform-arrow-functions': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-async-generator-functions': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-async-to-generator': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-block-scoped-functions': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-block-scoping': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-class-properties': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-class-static-block': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-classes': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-computed-properties': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-destructuring': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-dotall-regex': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-duplicate-keys': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-dynamic-import': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-exponentiation-operator': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-export-namespace-from': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-for-of': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-function-name': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-json-strings': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-literals': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-logical-assignment-operators': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-member-expression-literals': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-modules-amd': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-modules-commonjs': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-modules-systemjs': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-modules-umd': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-named-capturing-groups-regex': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-new-target': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-nullish-coalescing-operator': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-numeric-separator': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-object-rest-spread': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-object-super': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-optional-catch-binding': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-optional-chaining': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-parameters': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-private-methods': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-private-property-in-object': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-property-literals': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-regenerator': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-reserved-words': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-shorthand-properties': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-spread': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-sticky-regex': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-template-literals': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-typeof-symbol': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-unicode-escapes': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-unicode-property-regex': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-unicode-regex': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-unicode-sets-regex': 7.24.7(@babel/core@7.24.7) - '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.24.7) - babel-plugin-polyfill-corejs2: 0.4.11(@babel/core@7.24.7) - babel-plugin-polyfill-corejs3: 0.10.4(@babel/core@7.24.7) - babel-plugin-polyfill-regenerator: 0.6.2(@babel/core@7.24.7) + '@babel/compat-data': 7.24.8 + '@babel/core': 7.24.8 + '@babel/helper-compilation-targets': 7.24.8 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/helper-validator-option': 7.24.8 + '@babel/plugin-bugfix-firefox-class-in-computed-class-key': 7.24.7(@babel/core@7.24.8) + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.24.7(@babel/core@7.24.8) + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.24.7(@babel/core@7.24.8) + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.24.7(@babel/core@7.24.8) + '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.24.8) + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.24.8) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.24.8) + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.24.8) + '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.24.8) + '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.24.8) + '@babel/plugin-syntax-import-assertions': 7.24.7(@babel/core@7.24.8) + '@babel/plugin-syntax-import-attributes': 7.24.7(@babel/core@7.24.8) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.24.8) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.24.8) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.24.8) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.24.8) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.24.8) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.24.8) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.24.8) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.24.8) + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.24.8) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.24.8) + '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.24.8) + '@babel/plugin-transform-arrow-functions': 7.24.7(@babel/core@7.24.8) + '@babel/plugin-transform-async-generator-functions': 7.24.7(@babel/core@7.24.8) + '@babel/plugin-transform-async-to-generator': 7.24.7(@babel/core@7.24.8) + '@babel/plugin-transform-block-scoped-functions': 7.24.7(@babel/core@7.24.8) + '@babel/plugin-transform-block-scoping': 7.24.7(@babel/core@7.24.8) + '@babel/plugin-transform-class-properties': 7.24.7(@babel/core@7.24.8) + '@babel/plugin-transform-class-static-block': 7.24.7(@babel/core@7.24.8) + '@babel/plugin-transform-classes': 7.24.8(@babel/core@7.24.8) + '@babel/plugin-transform-computed-properties': 7.24.7(@babel/core@7.24.8) + '@babel/plugin-transform-destructuring': 7.24.8(@babel/core@7.24.8) + '@babel/plugin-transform-dotall-regex': 7.24.7(@babel/core@7.24.8) + '@babel/plugin-transform-duplicate-keys': 7.24.7(@babel/core@7.24.8) + '@babel/plugin-transform-dynamic-import': 7.24.7(@babel/core@7.24.8) + '@babel/plugin-transform-exponentiation-operator': 7.24.7(@babel/core@7.24.8) + '@babel/plugin-transform-export-namespace-from': 7.24.7(@babel/core@7.24.8) + '@babel/plugin-transform-for-of': 7.24.7(@babel/core@7.24.8) + '@babel/plugin-transform-function-name': 7.24.7(@babel/core@7.24.8) + '@babel/plugin-transform-json-strings': 7.24.7(@babel/core@7.24.8) + '@babel/plugin-transform-literals': 7.24.7(@babel/core@7.24.8) + '@babel/plugin-transform-logical-assignment-operators': 7.24.7(@babel/core@7.24.8) + '@babel/plugin-transform-member-expression-literals': 7.24.7(@babel/core@7.24.8) + '@babel/plugin-transform-modules-amd': 7.24.7(@babel/core@7.24.8) + '@babel/plugin-transform-modules-commonjs': 7.24.8(@babel/core@7.24.8) + '@babel/plugin-transform-modules-systemjs': 7.24.7(@babel/core@7.24.8) + '@babel/plugin-transform-modules-umd': 7.24.7(@babel/core@7.24.8) + '@babel/plugin-transform-named-capturing-groups-regex': 7.24.7(@babel/core@7.24.8) + '@babel/plugin-transform-new-target': 7.24.7(@babel/core@7.24.8) + '@babel/plugin-transform-nullish-coalescing-operator': 7.24.7(@babel/core@7.24.8) + '@babel/plugin-transform-numeric-separator': 7.24.7(@babel/core@7.24.8) + '@babel/plugin-transform-object-rest-spread': 7.24.7(@babel/core@7.24.8) + '@babel/plugin-transform-object-super': 7.24.7(@babel/core@7.24.8) + '@babel/plugin-transform-optional-catch-binding': 7.24.7(@babel/core@7.24.8) + '@babel/plugin-transform-optional-chaining': 7.24.8(@babel/core@7.24.8) + '@babel/plugin-transform-parameters': 7.24.7(@babel/core@7.24.8) + '@babel/plugin-transform-private-methods': 7.24.7(@babel/core@7.24.8) + '@babel/plugin-transform-private-property-in-object': 7.24.7(@babel/core@7.24.8) + '@babel/plugin-transform-property-literals': 7.24.7(@babel/core@7.24.8) + '@babel/plugin-transform-regenerator': 7.24.7(@babel/core@7.24.8) + '@babel/plugin-transform-reserved-words': 7.24.7(@babel/core@7.24.8) + '@babel/plugin-transform-shorthand-properties': 7.24.7(@babel/core@7.24.8) + '@babel/plugin-transform-spread': 7.24.7(@babel/core@7.24.8) + '@babel/plugin-transform-sticky-regex': 7.24.7(@babel/core@7.24.8) + '@babel/plugin-transform-template-literals': 7.24.7(@babel/core@7.24.8) + '@babel/plugin-transform-typeof-symbol': 7.24.8(@babel/core@7.24.8) + '@babel/plugin-transform-unicode-escapes': 7.24.7(@babel/core@7.24.8) + '@babel/plugin-transform-unicode-property-regex': 7.24.7(@babel/core@7.24.8) + '@babel/plugin-transform-unicode-regex': 7.24.7(@babel/core@7.24.8) + '@babel/plugin-transform-unicode-sets-regex': 7.24.7(@babel/core@7.24.8) + '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.24.8) + babel-plugin-polyfill-corejs2: 0.4.11(@babel/core@7.24.8) + babel-plugin-polyfill-corejs3: 0.10.4(@babel/core@7.24.8) + babel-plugin-polyfill-regenerator: 0.6.2(@babel/core@7.24.8) core-js-compat: 3.37.1 semver: 6.3.1 transitivePeerDependencies: - supports-color dev: true - /@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.24.7): + /@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.24.8): resolution: {integrity: sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==} peerDependencies: '@babel/core': ^7.0.0-0 || ^8.0.0-0 <8.0.0 dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - '@babel/types': 7.24.7 + '@babel/core': 7.24.8 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/types': 7.24.8 esutils: 2.0.3 dev: true @@ -1337,8 +1337,8 @@ packages: resolution: {integrity: sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==} dev: true - /@babel/runtime@7.24.7: - resolution: {integrity: sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==} + /@babel/runtime@7.24.8: + resolution: {integrity: sha512-5F7SDGs1T72ZczbRwbGO9lQi0NLjQxzl6i4lJxLxfW9U5UluCSyEJeniWvnhl3/euNiqQVbo8zruhsDfid0esA==} engines: {node: '>=6.9.0'} dependencies: regenerator-runtime: 0.14.1 @@ -1349,33 +1349,33 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@babel/code-frame': 7.24.7 - '@babel/parser': 7.24.7 - '@babel/types': 7.24.7 + '@babel/parser': 7.24.8 + '@babel/types': 7.24.8 dev: true - /@babel/traverse@7.24.7: - resolution: {integrity: sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA==} + /@babel/traverse@7.24.8: + resolution: {integrity: sha512-t0P1xxAPzEDcEPmjprAQq19NWum4K0EQPjMwZQZbHt+GiZqvjCHjj755Weq1YRPVzBI+3zSfvScfpnuIecVFJQ==} engines: {node: '>=6.9.0'} dependencies: '@babel/code-frame': 7.24.7 - '@babel/generator': 7.24.7 + '@babel/generator': 7.24.8 '@babel/helper-environment-visitor': 7.24.7 '@babel/helper-function-name': 7.24.7 '@babel/helper-hoist-variables': 7.24.7 '@babel/helper-split-export-declaration': 7.24.7 - '@babel/parser': 7.24.7 - '@babel/types': 7.24.7 + '@babel/parser': 7.24.8 + '@babel/types': 7.24.8 debug: 4.3.5 globals: 11.12.0 transitivePeerDependencies: - supports-color dev: true - /@babel/types@7.24.7: - resolution: {integrity: sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==} + /@babel/types@7.24.8: + resolution: {integrity: sha512-SkSBEHwwJRU52QEVZBmMBnE5Ux2/6WU1grdYyOhpbCNxbmJrDuDCphBzKZSO3taf0zztp+qkWlymE5tVL5l0TA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/helper-string-parser': 7.24.7 + '@babel/helper-string-parser': 7.24.8 '@babel/helper-validator-identifier': 7.24.7 to-fast-properties: 2.0.0 dev: true @@ -1876,11 +1876,11 @@ packages: '@vue/compiler-sfc': optional: true dependencies: - '@babel/core': 7.24.7 - '@babel/generator': 7.24.7 - '@babel/parser': 7.24.7 - '@babel/traverse': 7.24.7 - '@babel/types': 7.24.7 + '@babel/core': 7.24.8 + '@babel/generator': 7.24.8 + '@babel/parser': 7.24.8 + '@babel/traverse': 7.24.8 + '@babel/types': 7.24.8 prettier: 3.3.2 semver: 7.6.2 transitivePeerDependencies: @@ -2013,7 +2013,7 @@ packages: dev: true optional: true - /@rollup/plugin-babel@5.3.1(@babel/core@7.24.7)(rollup@2.79.1): + /@rollup/plugin-babel@5.3.1(@babel/core@7.24.8)(rollup@2.79.1): resolution: {integrity: sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==} engines: {node: '>= 10.0.0'} peerDependencies: @@ -2024,7 +2024,7 @@ packages: '@types/babel__core': optional: true dependencies: - '@babel/core': 7.24.7 + '@babel/core': 7.24.8 '@babel/helper-module-imports': 7.24.7 '@rollup/pluginutils': 3.1.0(rollup@2.79.1) rollup: 2.79.1 @@ -2306,8 +2306,8 @@ packages: /@types/babel__core@7.20.5: resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} dependencies: - '@babel/parser': 7.24.7 - '@babel/types': 7.24.7 + '@babel/parser': 7.24.8 + '@babel/types': 7.24.8 '@types/babel__generator': 7.6.8 '@types/babel__template': 7.4.4 '@types/babel__traverse': 7.20.6 @@ -2316,20 +2316,20 @@ packages: /@types/babel__generator@7.6.8: resolution: {integrity: sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==} dependencies: - '@babel/types': 7.24.7 + '@babel/types': 7.24.8 dev: true /@types/babel__template@7.4.4: resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} dependencies: - '@babel/parser': 7.24.7 - '@babel/types': 7.24.7 + '@babel/parser': 7.24.8 + '@babel/types': 7.24.8 dev: true /@types/babel__traverse@7.20.6: resolution: {integrity: sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==} dependencies: - '@babel/types': 7.24.7 + '@babel/types': 7.24.8 dev: true /@types/estree@0.0.39: @@ -2522,62 +2522,62 @@ packages: possible-typed-array-names: 1.0.0 dev: true - /babel-plugin-jsx-dom-expressions@0.37.23(@babel/core@7.24.7): + /babel-plugin-jsx-dom-expressions@0.37.23(@babel/core@7.24.8): resolution: {integrity: sha512-Y/r8LyLi/njnwPTaDuPEReWk30FJ1KplloYvcFUhHmiH1F7yVVj5mWojD7mbO/IruKyvOs9OIPUoeMi3Z++J4w==} peerDependencies: '@babel/core': ^7.20.12 dependencies: - '@babel/core': 7.24.7 + '@babel/core': 7.24.8 '@babel/helper-module-imports': 7.18.6 - '@babel/plugin-syntax-jsx': 7.24.7(@babel/core@7.24.7) - '@babel/types': 7.24.7 + '@babel/plugin-syntax-jsx': 7.24.7(@babel/core@7.24.8) + '@babel/types': 7.24.8 html-entities: 2.3.3 validate-html-nesting: 1.2.2 dev: true - /babel-plugin-polyfill-corejs2@0.4.11(@babel/core@7.24.7): + /babel-plugin-polyfill-corejs2@0.4.11(@babel/core@7.24.8): resolution: {integrity: sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 dependencies: - '@babel/compat-data': 7.24.7 - '@babel/core': 7.24.7 - '@babel/helper-define-polyfill-provider': 0.6.2(@babel/core@7.24.7) + '@babel/compat-data': 7.24.8 + '@babel/core': 7.24.8 + '@babel/helper-define-polyfill-provider': 0.6.2(@babel/core@7.24.8) semver: 6.3.1 transitivePeerDependencies: - supports-color dev: true - /babel-plugin-polyfill-corejs3@0.10.4(@babel/core@7.24.7): + /babel-plugin-polyfill-corejs3@0.10.4(@babel/core@7.24.8): resolution: {integrity: sha512-25J6I8NGfa5YkCDogHRID3fVCadIR8/pGl1/spvCkzb6lVn6SR3ojpx9nOn9iEBcUsjY24AmdKm5khcfKdylcg==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 dependencies: - '@babel/core': 7.24.7 - '@babel/helper-define-polyfill-provider': 0.6.2(@babel/core@7.24.7) + '@babel/core': 7.24.8 + '@babel/helper-define-polyfill-provider': 0.6.2(@babel/core@7.24.8) core-js-compat: 3.37.1 transitivePeerDependencies: - supports-color dev: true - /babel-plugin-polyfill-regenerator@0.6.2(@babel/core@7.24.7): + /babel-plugin-polyfill-regenerator@0.6.2(@babel/core@7.24.8): resolution: {integrity: sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 dependencies: - '@babel/core': 7.24.7 - '@babel/helper-define-polyfill-provider': 0.6.2(@babel/core@7.24.7) + '@babel/core': 7.24.8 + '@babel/helper-define-polyfill-provider': 0.6.2(@babel/core@7.24.8) transitivePeerDependencies: - supports-color dev: true - /babel-preset-solid@1.8.18(@babel/core@7.24.7): + /babel-preset-solid@1.8.18(@babel/core@7.24.8): resolution: {integrity: sha512-ky0FA4cCS9dk+xYBBItHoxtbRnaDIOGpmHLFqKPaR81hpMbJBOiLOZia2hT0JBwx4zn/D2OjMRvRr6kqtRMoUw==} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.24.7 - babel-plugin-jsx-dom-expressions: 0.37.23(@babel/core@7.24.7) + '@babel/core': 7.24.8 + babel-plugin-jsx-dom-expressions: 0.37.23(@babel/core@7.24.8) dev: true /balanced-match@1.0.2: @@ -2635,7 +2635,7 @@ packages: hasBin: true dependencies: caniuse-lite: 1.0.30001641 - electron-to-chromium: 1.4.823 + electron-to-chromium: 1.4.825 node-releases: 2.0.14 update-browserslist-db: 1.1.0(browserslist@4.23.2) dev: true @@ -3101,8 +3101,8 @@ packages: jake: 10.9.1 dev: true - /electron-to-chromium@1.4.823: - resolution: {integrity: sha512-4h+oPeAiGQOHFyUJOqpoEcPj/xxlicxBzOErVeYVMMmAiXUXsGpsFd0QXBMaUUbnD8hhSfLf9uw+MlsoIA7j5w==} + /electron-to-chromium@1.4.825: + resolution: {integrity: sha512-OCcF+LwdgFGcsYPYC5keEEFC2XT0gBhrYbeGzHCx7i9qRFbzO/AqTmc/C/1xNhJj+JA7rzlN7mpBuStshh96Cg==} dev: true /emoji-regex@8.0.0: @@ -4077,8 +4077,8 @@ packages: - supports-color dev: true - /lightweight-charts@4.1.6: - resolution: {integrity: sha512-6NLRhYGSOorEXQireN+/Fh25lU2vzvHAcPujQZOqQGB/QGereMsoyLhuX5mz4odXune01mKhhmd8UTYIgRDGqg==} + /lightweight-charts@4.1.7: + resolution: {integrity: sha512-/np9mQ8GXThrvJvxx4iSTZl/PvIhqG0bVQe7V+N0SO9E7e25VLglHf5M6eQFGDmwcOWNTLztH2fF0PmZ/sVq9g==} dependencies: fancy-canvas: 2.1.0 dev: false @@ -4930,7 +4930,7 @@ packages: /regenerator-transform@0.15.2: resolution: {integrity: sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==} dependencies: - '@babel/runtime': 7.24.7 + '@babel/runtime': 7.24.8 dev: true /regexp.prototype.flags@1.5.2: @@ -5220,9 +5220,9 @@ packages: peerDependencies: solid-js: ^1.3 dependencies: - '@babel/generator': 7.24.7 + '@babel/generator': 7.24.8 '@babel/helper-module-imports': 7.24.7 - '@babel/types': 7.24.7 + '@babel/types': 7.24.8 solid-js: 1.8.18 transitivePeerDependencies: - supports-color @@ -5750,8 +5750,8 @@ packages: engines: {node: '>= 10.0.0'} dev: true - /unplugin-auto-import@0.17.6(rollup@2.79.1): - resolution: {integrity: sha512-dmX0Pex5DzMzVuALkexboOZvh51fL/BD6aoPO7qHoTYGlQp0GRKsREv2KMF1lzYI9SXKQiRxAjwzbQnrFFNydQ==} + /unplugin-auto-import@0.18.0(rollup@2.79.1): + resolution: {integrity: sha512-DZcj8tceMpwuZgBPM9hhKd7v05WAYCUc/qYjxV7vGbeVCGsQ8SHWumCyOYBDqYzkPd4FlQkuh+OH0cWgdCjcdw==} engines: {node: '>=14'} peerDependencies: '@nuxt/kit': ^3.2.2 @@ -5884,9 +5884,9 @@ packages: '@testing-library/jest-dom': optional: true dependencies: - '@babel/core': 7.24.7 + '@babel/core': 7.24.8 '@types/babel__core': 7.20.5 - babel-preset-solid: 1.8.18(@babel/core@7.24.7) + babel-preset-solid: 1.8.18(@babel/core@7.24.8) merge-anything: 5.1.7 solid-js: 1.8.18 solid-refresh: 0.6.3(solid-js@1.8.18) @@ -6021,10 +6021,10 @@ packages: engines: {node: '>=16.0.0'} dependencies: '@apideck/better-ajv-errors': 0.3.6(ajv@8.16.0) - '@babel/core': 7.24.7 - '@babel/preset-env': 7.24.7(@babel/core@7.24.7) - '@babel/runtime': 7.24.7 - '@rollup/plugin-babel': 5.3.1(@babel/core@7.24.7)(rollup@2.79.1) + '@babel/core': 7.24.8 + '@babel/preset-env': 7.24.8(@babel/core@7.24.8) + '@babel/runtime': 7.24.8 + '@rollup/plugin-babel': 5.3.1(@babel/core@7.24.8)(rollup@2.79.1) '@rollup/plugin-node-resolve': 15.2.3(rollup@2.79.1) '@rollup/plugin-replace': 2.4.2(rollup@2.79.1) '@rollup/plugin-terser': 0.4.4(rollup@2.79.1) @@ -6162,8 +6162,8 @@ packages: '@cloudflare/workerd-windows-64': 1.20240701.0 dev: true - /wrangler@3.63.2: - resolution: {integrity: sha512-c7F46JtBGTIQehTOgfGbxfDMYgO9AjC70CXVSohxHiF9ajHz56HEV2k3aowhJJiP3MBB8sJMm8rdG10f5zUs+w==} + /wrangler@3.64.0: + resolution: {integrity: sha512-q2VQADJXzuOkXs9KIfPSx7UCZHBoxsqSNbJDLkc2pHpGmsyNQXsJRqjMoTg/Kls7O3K9A7EGnzGr7+Io2vE6AQ==} engines: {node: '>=16.17.0'} hasBin: true peerDependencies: diff --git a/app/src/app/components/background.tsx b/app/src/app/components/background.tsx index 355103987..c07dc1455 100644 --- a/app/src/app/components/background.tsx +++ b/app/src/app/components/background.tsx @@ -104,8 +104,7 @@ function Line({ mode: SL<"Scroll" | "Static">; focused: Accessor; }) { - const shuffled = shuffle([...texts]); - shuffled.pop(); + const shuffled = shuffle(texts).slice(0, 10); const joined = shuffled.join(". "); return ( diff --git a/app/src/app/components/frames/chart/components/chart.tsx b/app/src/app/components/frames/chart/components/chart.tsx index 1406e0ee1..c457a0acb 100644 --- a/app/src/app/components/frames/chart/components/chart.tsx +++ b/app/src/app/components/frames/chart/components/chart.tsx @@ -1,4 +1,5 @@ import { requestIdleCallbackPossible } from "/src/env"; +import { applySeriesList } from "/src/scripts/presets/apply"; import { createRWS } from "/src/solid/rws"; export function Chart({ @@ -22,7 +23,6 @@ export function Chart({ if (requestIdleCallbackPossible) { const idleCallback = requestIdleCallback(() => { - console.log("idle"); wasIdle.set(true); cancelIdleCallback(idleCallback); }); @@ -32,7 +32,6 @@ export function Chart({ }); } else { const timeout = setTimeout(() => { - console.log("timeout"); wasIdle.set(true); }, 500); @@ -51,7 +50,7 @@ export function Chart({ untrack(() => { try { console.log(`preset: ${preset.id}`); - preset.applyPreset({ + applySeriesList({ charts, parentDiv: div, datasets, @@ -59,6 +58,9 @@ export function Chart({ legendSetter, dark, activeIds, + priceScaleOptions: preset.priceScaleOptions, + top: preset.top, + bottom: preset.bottom, }); } catch (error) { console.error("chart: render: failed", error); diff --git a/app/src/app/components/frames/chart/components/legend.tsx b/app/src/app/components/frames/chart/components/legend.tsx index b8c8f9bb3..f8cdd964d 100644 --- a/app/src/app/components/frames/chart/components/legend.tsx +++ b/app/src/app/components/frames/chart/components/legend.tsx @@ -164,7 +164,7 @@ export function Legend({ : undefined } > - + )} diff --git a/app/src/scripts/datasets/consts/age.ts b/app/src/scripts/datasets/consts/age.ts index 8cd5e4066..6783eec84 100644 --- a/app/src/scripts/datasets/consts/age.ts +++ b/app/src/scripts/datasets/consts/age.ts @@ -1,10 +1,12 @@ export const xthCohorts = [ { + id: "sth", key: "sth", name: "Short Term Holders", legend: "STH", }, { + id: "lth", key: "lth", name: "Long Term Holders", legend: "LTH", @@ -12,75 +14,86 @@ export const xthCohorts = [ ] as const; export const upToCohorts = [ - { key: "up_to_1d", name: "Up To 1 Day", legend: "1D" }, - { key: "up_to_1w", name: "Up To 1 Week", legend: "1W" }, - { key: "up_to_1m", name: "Up To 1 Month", legend: "1M" }, - { key: "up_to_2m", name: "Up To 2 Months", legend: "2M" }, - { key: "up_to_3m", name: "Up To 3 Months", legend: "3M" }, - { key: "up_to_4m", name: "Up To 4 Months", legend: "4M" }, - { key: "up_to_5m", name: "Up To 5 Months", legend: "5M" }, - { key: "up_to_6m", name: "Up To 6 Months", legend: "6M" }, - { key: "up_to_1y", name: "Up To 1 Year", legend: "1Y" }, - { key: "up_to_2y", name: "Up To 2 Years", legend: "2Y" }, - { key: "up_to_3y", name: "Up To 3 Years", legend: "3Y" }, - { key: "up_to_5y", name: "Up To 5 Years", legend: "5Y" }, - { key: "up_to_7y", name: "Up To 7 Years", legend: "7Y" }, - { key: "up_to_10y", name: "Up To 10 Years", legend: "10Y" }, - { key: "up_to_15y", name: "Up To 15 Years", legend: "15Y" }, + { id: "up-to-1d", key: "up_to_1d", name: "Up To 1 Day", legend: "1D" }, + { id: "up-to-1w", key: "up_to_1w", name: "Up To 1 Week", legend: "1W" }, + { id: "up-to-1m", key: "up_to_1m", name: "Up To 1 Month", legend: "1M" }, + { id: "up-to-2m", key: "up_to_2m", name: "Up To 2 Months", legend: "2M" }, + { id: "up-to-3m", key: "up_to_3m", name: "Up To 3 Months", legend: "3M" }, + { id: "up-to-4m", key: "up_to_4m", name: "Up To 4 Months", legend: "4M" }, + { id: "up-to-5m", key: "up_to_5m", name: "Up To 5 Months", legend: "5M" }, + { id: "up-to-6m", key: "up_to_6m", name: "Up To 6 Months", legend: "6M" }, + { id: "up-to-1y", key: "up_to_1y", name: "Up To 1 Year", legend: "1Y" }, + { id: "up-to-2y", key: "up_to_2y", name: "Up To 2 Years", legend: "2Y" }, + { id: "up-to-3y", key: "up_to_3y", name: "Up To 3 Years", legend: "3Y" }, + { id: "up-to-5y", key: "up_to_5y", name: "Up To 5 Years", legend: "5Y" }, + { id: "up-to-7y", key: "up_to_7y", name: "Up To 7 Years", legend: "7Y" }, + { id: "up-to-10y", key: "up_to_10y", name: "Up To 10 Years", legend: "10Y" }, + { id: "up-to-15y", key: "up_to_15y", name: "Up To 15 Years", legend: "15Y" }, ] as const; export const fromXToYCohorts = [ { + id: "from-1d-to-1w", key: "from_1d_to_1w", name: "From 1 Day To 1 Week", legend: "1D - 1W", }, { + id: "from-1w-to-1m", key: "from_1w_to_1m", name: "From 1 Week To 1 Month", legend: "1W - 1M", }, { + id: "from-1m-to-3m", key: "from_1m_to_3m", name: "From 1 Month To 3 Months", legend: "1M - 3M", }, { + id: "from-3m-to-6m", key: "from_3m_to_6m", name: "From 3 Months To 6 Months", legend: "3M - 6M", }, { + id: "from-6m-to-1y", key: "from_6m_to_1y", name: "From 6 Months To 1 Year", legend: "6M - 1Y", }, { + id: "from-1y-to-2y", key: "from_1y_to_2y", name: "From 1 Year To 2 Years", legend: "1Y - 2Y", }, { + id: "from-2y-to-3y", key: "from_2y_to_3y", name: "From 2 Years To 3 Years", legend: "2Y - 3Y", }, { + id: "from-3y-to-5y", key: "from_3y_to_5y", name: "From 3 Years To 5 Years", legend: "3Y - 5Y", }, { + id: "from-5y-to-7y", key: "from_5y_to_7y", name: "From 5 Years To 7 Years", legend: "5Y - 7Y", }, { + id: "from-7y-to-10y", key: "from_7y_to_10y", name: "From 7 Years To 10 Years", legend: "7Y - 10Y", }, { + id: "from-10y-to-15y", key: "from_10y_to_15y", name: "From 10 Years To 15 Years", legend: "10Y - 15Y", @@ -89,26 +102,31 @@ export const fromXToYCohorts = [ export const fromXCohorts = [ { + id: "from-1y", key: "from_1y", name: "From 1 Year", legend: "1Y+", }, { + id: "from-2y", key: "from_2y", name: "From 2 Years", legend: "2Y+", }, { + id: "from-4y", key: "from_4y", name: "From 4 Years", legend: "4Y+", }, { + id: "from-10y", key: "from_10y", name: "From 10 Years", legend: "10Y+", }, { + id: "from-15y", key: "from_15y", name: "From 15 Years", legend: "15Y+", @@ -116,27 +134,28 @@ export const fromXCohorts = [ ] as const; export const yearCohorts = [ - { key: "year_2009", name: "2009" }, - { key: "year_2010", name: "2010" }, - { key: "year_2011", name: "2011" }, - { key: "year_2012", name: "2012" }, - { key: "year_2013", name: "2013" }, - { key: "year_2014", name: "2014" }, - { key: "year_2015", name: "2015" }, - { key: "year_2016", name: "2016" }, - { key: "year_2017", name: "2017" }, - { key: "year_2018", name: "2018" }, - { key: "year_2019", name: "2019" }, - { key: "year_2020", name: "2020" }, - { key: "year_2021", name: "2021" }, - { key: "year_2022", name: "2022" }, - { key: "year_2023", name: "2023" }, - { key: "year_2024", name: "2024" }, + { id: "year-2009", key: "year_2009", name: "2009" }, + { id: "year-2010", key: "year_2010", name: "2010" }, + { id: "year-2011", key: "year_2011", name: "2011" }, + { id: "year-2012", key: "year_2012", name: "2012" }, + { id: "year-2013", key: "year_2013", name: "2013" }, + { id: "year-2014", key: "year_2014", name: "2014" }, + { id: "year-2015", key: "year_2015", name: "2015" }, + { id: "year-2016", key: "year_2016", name: "2016" }, + { id: "year-2017", key: "year_2017", name: "2017" }, + { id: "year-2018", key: "year_2018", name: "2018" }, + { id: "year-2019", key: "year_2019", name: "2019" }, + { id: "year-2020", key: "year_2020", name: "2020" }, + { id: "year-2021", key: "year_2021", name: "2021" }, + { id: "year-2022", key: "year_2022", name: "2022" }, + { id: "year-2023", key: "year_2023", name: "2023" }, + { id: "year-2024", key: "year_2024", name: "2024" }, ] as const; export const ageCohorts = [ { key: "", + id: "", name: "", }, ...xthCohorts, diff --git a/app/src/scripts/datasets/consts/liquidities.ts b/app/src/scripts/datasets/consts/liquidities.ts index 1346d3728..04daf28b6 100644 --- a/app/src/scripts/datasets/consts/liquidities.ts +++ b/app/src/scripts/datasets/consts/liquidities.ts @@ -1,11 +1,13 @@ export const liquidities = [ { key: "illiquid", + id: "illiquid", name: "Illiquid", }, - { key: "liquid", name: "Liquid" }, + { key: "liquid", id: "liquid", name: "Liquid" }, { key: "highly_liquid", + id: "highly-liquid", name: "Highly Liquid", }, ] as const; diff --git a/app/src/scripts/datasets/consts/percentiles.ts b/app/src/scripts/datasets/consts/percentiles.ts index c082802fd..96a967c0e 100644 --- a/app/src/scripts/datasets/consts/percentiles.ts +++ b/app/src/scripts/datasets/consts/percentiles.ts @@ -1,114 +1,133 @@ export const percentiles = [ { key: "median_price_paid", + id: "median-price-paid", name: "Median", title: "Median Paid", value: 50, }, { key: "95p_price_paid", + id: "95p-price-paid", name: `95%`, title: `95th Percentile Paid`, value: 95, }, { key: "90p_price_paid", + id: "90p-price-paid", name: `90%`, title: `90th Percentile Paid`, value: 90, }, { key: "85p_price_paid", + id: "85p-price-paid", name: `85%`, title: `85th Percentile Paid`, value: 85, }, { key: "80p_price_paid", + id: "80p-price-paid", name: `80%`, title: `80th Percentile Paid`, value: 80, }, { key: "75p_price_paid", + id: "75p-price-paid", name: `75%`, title: `75th Percentile Paid`, value: 75, }, { key: "70p_price_paid", + id: "70p-price-paid", name: `70%`, title: `70th Percentile Paid`, value: 70, }, { key: "65p_price_paid", + id: "65p-price-paid", name: `65%`, title: `65th Percentile Paid`, value: 65, }, { key: "60p_price_paid", + id: "60p-price-paid", name: `60%`, title: `60th Percentile Paid`, value: 60, }, { key: "55p_price_paid", + id: "55p-price-paid", name: `55%`, title: `55th Percentile Paid`, value: 55, }, { key: "45p_price_paid", + id: "45p-price-paid", name: `45%`, title: `45th Percentile Paid`, value: 45, }, { key: "40p_price_paid", + id: "40p-price-paid", name: `40%`, title: `40th Percentile Paid`, value: 40, }, { key: "35p_price_paid", + id: "35p-price-paid", name: `35%`, title: `35th Percentile Paid`, value: 35, }, { key: "30p_price_paid", + id: "30p-price-paid", name: `30%`, title: `30th Percentile Paid`, value: 30, }, { key: "25p_price_paid", + id: "25p-price-paid", name: `25%`, title: `25th Percentile Paid`, value: 25, }, { key: "20p_price_paid", + id: "20p-price-paid", name: `20%`, title: `20th Percentile Paid`, value: 20, }, { key: "15p_price_paid", + id: "15p-price-paid", name: `15%`, title: `15th Percentile Paid`, value: 15, }, { key: "10p_price_paid", + id: "10p-price-paid", name: `10%`, title: `10th Percentile Paid`, value: 10, }, { key: "05p_price_paid", + id: "05p-price-paid", name: `5%`, title: `5th Percentile Paid`, value: 5, diff --git a/app/src/scripts/datasets/consts/types.d.ts b/app/src/scripts/datasets/consts/types.d.ts index 3a38ac7ae..d837bfafa 100644 --- a/app/src/scripts/datasets/consts/types.d.ts +++ b/app/src/scripts/datasets/consts/types.d.ts @@ -1,18 +1,24 @@ -type AgeCohortKey = (typeof import("./age").ageCohorts)[number]["key"]; +type AgeCohortId = (typeof import("./age").ageCohorts)[number]["id"]; -type AddressCohortKey = +type AgeCohortIdSub = Exclude; + +type AddressCohortId = (typeof import("./address").addressCohorts)[number]["key"]; -type LiquidityKey = (typeof import("./liquidities").liquidities)[number]["key"]; +type LiquidityId = (typeof import("./liquidities").liquidities)[number]["id"]; -type AddressCohortKeySplitByLiquidity = `${LiquidityKey}_${AddressCohortKey}`; +type AddressCohortIdSplitByLiquidity = `${LiquidityId}-${AddressCohortId}`; -type AnyCohortKey = AgeCohortKey | AddressCohortKey; +type AnyCohortId = AgeCohortId | AddressCohortId; -type AnyPossibleCohortKey = - | AnyCohortKey - | AddressCohortKeySplitByLiquidity - | LiquidityKey; +type AnyPossibleCohortId = + | AnyCohortId + | AddressCohortIdSplitByLiquidity + | LiquidityId; + +type AnyDatasetPrefix = + | "" + | `${AgeCohortIdSub | AddressCohortId | AddressCohortIdSplitByLiquidity | LiquidityId}-`; type AverageName = (typeof import("./averages").averages)[number]["key"]; @@ -20,3 +26,5 @@ type TotalReturnKey = (typeof import("./returns").totalReturns)[number]["key"]; type CompoundReturnKey = (typeof import("./returns").compoundReturns)[number]["key"]; + +type PercentileId = (typeof import("./percentiles").percentiles)[number]["id"]; diff --git a/app/src/scripts/datasets/index.ts b/app/src/scripts/datasets/index.ts index 6b17d752d..465f526db 100644 --- a/app/src/scripts/datasets/index.ts +++ b/app/src/scripts/datasets/index.ts @@ -1,23 +1,49 @@ -import groupedKeysToURLPath from "/src/../../datasets/grouped_keys_to_url_path.json"; - -import { createDateDatasets } from "./date"; -import { createHeightDatasets } from "./height"; +import { createResourceDataset } from "./resource"; export const scales = ["date" as const, "height" as const]; export const HEIGHT_CHUNK_SIZE = 10_000; export function createDatasets() { - const date = createDateDatasets({ - groupedKeysToURLPath: groupedKeysToURLPath.date, - }); + const date = new Map>(); + const height = new Map>(); - const height = createHeightDatasets({ - groupedKeysToURLPath: groupedKeysToURLPath.height, - }); + function getOrImport( + scale: Scale, + path: DatasetPath, + ): ResourceDataset { + if (scale === "date") { + const found = date.get(path as any); + if (found) return found as ResourceDataset; + } else { + const found = height.get(path as any); + if (found) return found as ResourceDataset; + } + + let dataset: ResourceDataset; + + if (path === `/${scale}-to-ohlc`) { + dataset = createResourceDataset({ + scale, + path, + }); + } else { + dataset = createResourceDataset({ + scale, + path, + }); + } + + if (scale === "date") { + date.set(path as any, dataset as any); + } else { + height.set(path as any, dataset as any); + } + + return dataset; + } return { - date, - height, - } satisfies Record; + getOrImport, + }; } diff --git a/app/src/scripts/datasets/resource.ts b/app/src/scripts/datasets/resource.ts index aef38adab..b4b3d625a 100644 --- a/app/src/scripts/datasets/resource.ts +++ b/app/src/scripts/datasets/resource.ts @@ -30,224 +30,239 @@ export function createResourceDataset< "https://api-bkp.satonomics.xyz" }${path}`; - const fetchedJSONs = new Array( - (new Date().getFullYear() - new Date("2009-01-01").getFullYear() + 2) * - (scale === "date" ? 1 : 6), - ) - .fill(null) - .map((): FetchedResult => { - const json = createRWS | null>(null); + return createRoot((dispose) => { + const fetchedJSONs = new Array( + (new Date().getFullYear() - new Date("2009-01-01").getFullYear() + 2) * + (scale === "date" ? 1 : 6), + ) + .fill(null) + .map((): FetchedResult => { + const json = createRWS | null>(null); - return { - at: null, - json, - loading: false, - vec: createMemo(() => { - const map = json()?.dataset.map || null; + return { + at: null, + json, + loading: false, + vec: createMemo(() => { + const map = json()?.dataset.map || null; - if (!map) { - return null; - } - - const chunkId = json()?.chunk.id!; - - if (Array.isArray(map)) { - const values = new Array(map.length); - - for (let i = 0; i < map.length; i++) { - const value = map[i]; - - values[i] = { - time: (chunkId + i) as Time, - ...(typeof value !== "number" && value !== null - ? { ...(value as OHLC), value: value.close } - : { value: value === null ? NaN : (value as number) }), - } as any as Value; + if (!map) { + return null; } - return values; - } else { - return Object.entries(map).map( - ([date, value]) => - ({ - time: date, + const chunkId = json()?.chunk.id!; + + if (Array.isArray(map)) { + const values = new Array(map.length); + + for (let i = 0; i < map.length; i++) { + const value = map[i]; + + values[i] = { + time: (chunkId + i) as Time, ...(typeof value !== "number" && value !== null ? { ...(value as OHLC), value: value.close } : { value: value === null ? NaN : (value as number) }), - }) as any as Value, - ); - } - }), - }; - }) as FetchedResult[]; + } as any as Value; + } - const _fetch = async (id: number) => { - const index = chunkIdToIndex(scale, id); + return values; + } else { + return Object.entries(map).map( + ([date, value]) => + ({ + time: date, + ...(typeof value !== "number" && value !== null + ? { ...(value as OHLC), value: value.close } + : { value: value === null ? NaN : (value as number) }), + }) as any as Value, + ); + } + }), + }; + }) as FetchedResult[]; - if ( - index < 0 || - (scale === "date" && id > new Date().getUTCFullYear()) || - (scale === "height" && - id > 165 * 365 * (new Date().getUTCFullYear() - 2009)) - ) { - return; - } - - const fetched = fetchedJSONs.at(index); - - if (scale === "height" && index > 0) { - const length = fetchedJSONs.at(index - 1)?.vec()?.length; - - if (length !== undefined && length < HEIGHT_CHUNK_SIZE) { - return; - } - } - - if (!fetched || fetched.loading) { - return; - } else if (fetched.at) { - const diff = new Date().getTime() - fetched.at.getTime(); + const _fetch = async (id: number) => { + const index = chunkIdToIndex(scale, id); if ( - diff < ONE_MINUTE_IN_MS || - (index < fetchedJSONs.findLastIndex((json) => json.at) && - diff < ONE_HOUR_IN_MS) + index < 0 || + (scale === "date" && id > new Date().getUTCFullYear()) || + (scale === "height" && + id > 165 * 365 * (new Date().getUTCFullYear() - 2009)) ) { return; } - } - fetched.loading = true; + const fetched = fetchedJSONs.at(index); - let cache: Cache | undefined; + if (scale === "height" && index > 0) { + const length = fetchedJSONs.at(index - 1)?.vec()?.length; - const urlWithQuery = `${baseURL}?chunk=${id}`; - const backupUrlWithQuery = `${backupURL}?chunk=${id}`; - - if (!fetched.json()) { - try { - cache = await caches.open("resources"); - - const cachedResponse = await cache.match(urlWithQuery); - - if (cachedResponse) { - const json = await convertResponseToJSON(cachedResponse); - - if (json) { - console.log(`cache: ${path}?chunk=${id}`); - - fetched.json.set(() => json); - } - } - } catch {} - } - - if (!navigator.onLine) { - fetched.loading = false; - return; - } - - let fetchedResponse: Response | undefined; - - try { - fetchedResponse = await fetch(urlWithQuery); - - if (!fetchedResponse.ok) { - throw Error; - } - } catch { - try { - fetchedResponse = await fetch(backupUrlWithQuery); - } catch { - fetched.loading = false; - return; - } - - if (!fetchedResponse || !fetchedResponse.ok) { - fetched.loading = false; - return; - } - } - - const clonedResponse = fetchedResponse.clone(); - - const json = await convertResponseToJSON(fetchedResponse); - - if (!json) { - fetched.loading = false; - return; - } - - console.log(`fetch: ${path}?chunk=${id}`); - - const previousMap = fetched.json()?.dataset.map; - const newMap = json.dataset.map; - - const previousLength = Object.keys(previousMap || []).length; - const newLength = Object.keys(newMap).length; - - if (!newLength) { - fetched.loading = false; - return; - } - - if (previousLength && previousLength === newLength) { - const previousLastValue = Object.values(previousMap || []).at(-1); - const newLastValue = Object.values(newMap).at(-1); - - if (typeof newLastValue === "number") { - if (previousLastValue === newLastValue) { - fetched.at = new Date(); - fetched.loading = false; + if (length !== undefined && length < HEIGHT_CHUNK_SIZE) { return; } - } else { - const previousLastOHLC = previousLastValue as OHLC; - const newLastOHLC = newLastValue as OHLC; + } + + if (!fetched || fetched.loading) { + return; + } else if (fetched.at) { + const diff = new Date().getTime() - fetched.at.getTime(); if ( - previousLastOHLC.open === newLastOHLC.open && - previousLastOHLC.high === newLastOHLC.high && - previousLastOHLC.low === newLastOHLC.low && - previousLastOHLC.close === newLastOHLC.close + diff < ONE_MINUTE_IN_MS || + (index < fetchedJSONs.findLastIndex((json) => json.at) && + diff < ONE_HOUR_IN_MS) ) { - fetched.loading = false; - fetched.at = new Date(); return; } } - } - fetched.json.set(() => json); + fetched.loading = true; - function saveToCache() { - cache?.put(urlWithQuery, clonedResponse); - } + let cache: Cache | undefined; - if (requestIdleCallbackPossible) { - requestIdleCallback(saveToCache); - } else { - setTimeout(saveToCache, 1); - } + const urlWithQuery = `${baseURL}?chunk=${id}`; + const backupUrlWithQuery = `${backupURL}?chunk=${id}`; - fetched.at = new Date(); - fetched.loading = false; - }; + if (!fetched.json()) { + try { + cache = await caches.open("resources"); - const resource: ResourceDataset = { - scale, - url: baseURL, - fetch: _fetch, - fetchedJSONs, - drop() { - fetchedJSONs.forEach((fetched) => { - fetched.at = null; - fetched.json.set(null); - }); - }, - }; + const cachedResponse = await cache.match(urlWithQuery); - return resource; + if (cachedResponse) { + const json = await convertResponseToJSON( + cachedResponse, + ); + + if (json) { + console.log(`cache: ${path}?chunk=${id}`); + + fetched.json.set(() => json); + } + } + } catch {} + } + + if (!navigator.onLine) { + fetched.loading = false; + return; + } + + let fetchedResponse: Response | undefined; + + const fetchConfig: RequestInit = { + signal: AbortSignal.timeout(5000), + }; + + try { + fetchedResponse = await fetch(urlWithQuery, fetchConfig); + + if (!fetchedResponse.ok) { + throw Error; + } + } catch { + try { + fetchedResponse = await fetch(backupUrlWithQuery, fetchConfig); + } catch { + fetched.loading = false; + return; + } + + if (!fetchedResponse || !fetchedResponse.ok) { + fetched.loading = false; + return; + } + } + + const clonedResponse = fetchedResponse.clone(); + + const json = await convertResponseToJSON(fetchedResponse); + + if (!json) { + fetched.loading = false; + return; + } + + console.log(`fetch: ${path}?chunk=${id}`); + + const previousMap = fetched.json()?.dataset.map; + const newMap = json.dataset.map; + + const previousLength = Object.keys(previousMap || []).length; + const newLength = Object.keys(newMap).length; + + if (!newLength) { + fetched.loading = false; + return; + } + + if (previousLength && previousLength === newLength) { + const previousLastValue = Object.values(previousMap || []).at(-1); + const newLastValue = Object.values(newMap).at(-1); + + if (newLastValue === null && previousLastValue === null) { + fetched.at = new Date(); + fetched.loading = false; + return; + } else if (typeof newLastValue === "number") { + if (previousLastValue === newLastValue) { + fetched.at = new Date(); + fetched.loading = false; + return; + } + } else { + const previousLastOHLC = previousLastValue as OHLC; + const newLastOHLC = newLastValue as OHLC; + + if ( + previousLastOHLC.open === newLastOHLC.open && + previousLastOHLC.high === newLastOHLC.high && + previousLastOHLC.low === newLastOHLC.low && + previousLastOHLC.close === newLastOHLC.close + ) { + fetched.loading = false; + fetched.at = new Date(); + return; + } + } + } + + fetched.json.set(() => json); + + async function saveToCache() { + try { + await cache?.put(urlWithQuery, clonedResponse); + } catch (_) {} + } + + if (requestIdleCallbackPossible) { + requestIdleCallback(saveToCache); + } else { + setTimeout(saveToCache, 1); + } + + fetched.at = new Date(); + fetched.loading = false; + }; + + const resource: ResourceDataset = { + scale, + url: baseURL, + fetch: _fetch, + fetchedJSONs, + drop() { + dispose(); + fetchedJSONs.forEach((fetched) => { + fetched.at = null; + fetched.json.set(null); + }); + }, + }; + + return resource; + }); } async function convertResponseToJSON< diff --git a/app/src/scripts/datasets/types.d.ts b/app/src/scripts/datasets/types.d.ts index d1f8ac587..afb0a6527 100644 --- a/app/src/scripts/datasets/types.d.ts +++ b/app/src/scripts/datasets/types.d.ts @@ -1,9 +1,5 @@ type Datasets = ReturnType; -type DateDatasets = Datasets["date"]; -type HeightDatasets = Datasets["height"]; -type AnyDatasets = DateDatasets | HeightDatasets; - type ResourceScale = (typeof import("./index").scales)[index]; type DatasetValue = T & Valued; @@ -92,3 +88,15 @@ interface OHLC { type GroupedKeysToURLPath = typeof import("/src/../../datasets/grouped_keys_to_url_path.json"); + +type DateDatasetPath = import("/src/../../datasets/paths").DatePath; + +type HeightDatasetPath = import("/src/../../datasets/paths").HeightPath; + +type LastDataPath = import("/src/../../datasets/paths").LastPath; + +type DatasetPath = Scale extends "date" + ? DateDatasetPath + : HeightDatasetPath; + +type AnyDatasetPath = DateDatasetPath | HeightDatasetPath; diff --git a/app/src/scripts/lightweightCharts/create.ts b/app/src/scripts/lightweightCharts/create.ts index 4b405b118..1cee67b44 100644 --- a/app/src/scripts/lightweightCharts/create.ts +++ b/app/src/scripts/lightweightCharts/create.ts @@ -16,7 +16,7 @@ export function createChart( priceScaleOptions, }: { dark: Accessor; - priceScaleOptions: DeepPartialPriceScaleOptions; + priceScaleOptions?: DeepPartialPriceScaleOptions; }, ) { console.log(`chart: create (scale: ${scale})`); diff --git a/app/src/scripts/lightweightCharts/horzScaleBehavior.ts b/app/src/scripts/lightweightCharts/horzScaleBehavior.ts index aeeb22e84..e04d414dc 100644 --- a/app/src/scripts/lightweightCharts/horzScaleBehavior.ts +++ b/app/src/scripts/lightweightCharts/horzScaleBehavior.ts @@ -2,7 +2,7 @@ // https://github.com/tradingview/lightweight-charts/blob/master/tests/e2e/graphics/test-cases/horizontal-price-scale.js -import { type IHorzScaleBehavior } from "lightweight-charts"; +import type { IHorzScaleBehavior } from "lightweight-charts"; export class HorzScaleBehaviorHeight implements IHorzScaleBehavior { options() {} diff --git a/app/src/scripts/lightweightCharts/legend.ts b/app/src/scripts/lightweightCharts/legend.ts index 8828df95a..afdc26deb 100644 --- a/app/src/scripts/lightweightCharts/legend.ts +++ b/app/src/scripts/lightweightCharts/legend.ts @@ -19,6 +19,7 @@ export function createSeriesLegend({ visible: _visible, dataset, }: { + scale: Scale; id: string; presetId: string; title: string; diff --git a/app/src/scripts/lightweightCharts/markers.ts b/app/src/scripts/lightweightCharts/markers.ts index be4a8fcdc..88bef2f3f 100644 --- a/app/src/scripts/lightweightCharts/markers.ts +++ b/app/src/scripts/lightweightCharts/markers.ts @@ -1,6 +1,7 @@ import { colors } from "/src/scripts/utils/colors"; import { chunkIdToIndex } from "../datasets/resource"; +import { dateFromTime } from "../utils/date"; import { valueToString } from "../utils/locale"; export function setMinMaxMarkers({ @@ -55,11 +56,7 @@ export function setMinMaxMarkers({ let number; if (scale === "date") { - const date = - typeof data.time === "string" - ? new Date(data.time) - : // @ts-ignore - new Date(data.time.year, data.time.month, data.time.day); + const date = dateFromTime(data.time); number = date.getTime(); diff --git a/app/src/scripts/lightweightCharts/time.ts b/app/src/scripts/lightweightCharts/time.ts index 796d7af1c..1837c5fd6 100644 --- a/app/src/scripts/lightweightCharts/time.ts +++ b/app/src/scripts/lightweightCharts/time.ts @@ -64,35 +64,22 @@ export function initTimeScale({ scale, activeIds, exactRange, - charts, + chart, }: { scale: ResourceScale; activeIds: RWS; exactRange: RWS; - charts: ChartObject[]; + chart: IChartApi; }) { - const firstChart = charts.at(0)?.chart; - - if (!firstChart) return; - - firstChart.timeScale().subscribeVisibleTimeRangeChange((range) => { + chart.timeScale().subscribeVisibleTimeRangeChange((range) => { if (!range) return; exactRange.set(range); - debouncedsetActiveIds({ exactRange: range, activeIds: activeIds }); + debouncedSetActiveIds({ exactRange: range, activeIds: activeIds }); debouncedSaveTimeRange({ scale, range }); }); - - const range = exactRange(); - - run(async () => { - if (range) { - await tick(); - firstChart.timeScale().setVisibleRange(range); - } - }); } function getLocalStorageKey(scale: ResourceScale) { @@ -142,7 +129,7 @@ export function setActiveIds({ } } -const debouncedsetActiveIds = debounce(setActiveIds, 100); +const debouncedSetActiveIds = debounce(setActiveIds, 100); function saveTimeRange({ scale, diff --git a/app/src/scripts/presets/addresses/index.ts b/app/src/scripts/presets/addresses/index.ts index d0c6d25ac..eab3fbb0c 100644 --- a/app/src/scripts/presets/addresses/index.ts +++ b/app/src/scripts/presets/addresses/index.ts @@ -4,14 +4,9 @@ import { } from "../../datasets/consts/address"; import { liquidities } from "../../datasets/consts/liquidities"; import { colors } from "../../utils/colors"; -import { applySeriesList, SeriesType } from "../apply"; import { createCohortPresetList } from "../templates/cohort"; -export function createPresets({ - scale, -}: { - scale: ResourceScale; -}): PartialPresetFolder { +export function createPresets(scale: ResourceScale): PartialPresetFolder { return { name: "Addresses", tree: [ @@ -21,18 +16,13 @@ export function createPresets({ title: `Total Non Empty Address`, description: "", icon: IconTablerWallet, - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: `Total Non Empty Address`, - color: colors.bitcoin, - dataset: params.datasets[scale].address_count, - }, - ], - }); - }, + bottom: [ + { + title: `Total Non Empty Address`, + color: colors.bitcoin, + datasetPath: `/${scale}-to-address-count`, + }, + ], }, { scale, @@ -40,18 +30,13 @@ export function createPresets({ title: `New Addresses`, description: "", icon: IconTablerSparkles, - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: `New Addresses`, - color: colors.white, - dataset: params.datasets[scale].created_addresses, - }, - ], - }); - }, + bottom: [ + { + title: `New Addresses`, + color: colors.white, + datasetPath: `/${scale}-to-created-addresses`, + }, + ], }, { scale, @@ -59,18 +44,13 @@ export function createPresets({ title: `Total Addresses Created`, description: "", icon: IconTablerArchive, - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: `Total Addresses Created`, - color: colors.bitcoin, - dataset: params.datasets[scale].created_addresses, - }, - ], - }); - }, + bottom: [ + { + title: `Total Addresses Created`, + color: colors.bitcoin, + datasetPath: `/${scale}-to-created-addresses`, + }, + ], }, { scale, @@ -78,18 +58,13 @@ export function createPresets({ title: `Total Empty Addresses`, description: "", icon: IconTablerTrash, - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: `Total Empty Addresses`, - color: colors.darkWhite, - dataset: params.datasets[scale].empty_addresses, - }, - ], - }); - }, + bottom: [ + { + title: `Total Empty Addresses`, + color: colors.darkWhite, + datasetPath: `/${scale}-to-empty-addresses`, + }, + ], }, { name: "By Size", @@ -98,7 +73,7 @@ export function createPresets({ scale, color: colors[key], name, - datasetKey: key, + datasetId: key, }), ), }, @@ -110,7 +85,7 @@ export function createPresets({ scale, color: colors[key], name, - datasetKey: key, + datasetId: key, }), ), }, @@ -118,47 +93,47 @@ export function createPresets({ } satisfies PartialPresetFolder; } -function createAddressPresetFolder({ +function createAddressPresetFolder({ scale, color, name, - datasetKey, + datasetId, }: { - scale: Scale; + scale: ResourceScale; name: string; - datasetKey: AddressCohortKey; + datasetId: AddressCohortId; color: Color; }): PartialPresetFolder { return { name, tree: [ - createAddressCountPreset({ scale, name, datasetKey, color }), + createAddressCountPreset({ scale, name, datasetId, color }), ...createCohortPresetList({ title: name, scale, name, color, - datasetKey, + datasetId, }), createLiquidityFolder({ scale, name, - datasetKey, + datasetId, color, }), ], }; } -export function createLiquidityFolder({ +export function createLiquidityFolder({ scale, color, name, - datasetKey, + datasetId, }: { - scale: Scale; + scale: ResourceScale; name: string; - datasetKey: AddressCohortKey | ""; + datasetId: AddressCohortId | ""; color: Color; }): PartialPresetFolder { return { @@ -171,43 +146,36 @@ export function createLiquidityFolder({ name: `${liquidity.name} ${name}`, scale, color, - datasetKey: !datasetKey - ? liquidity.key - : `${liquidity.key}_${datasetKey}`, + datasetId: !datasetId ? liquidity.id : `${liquidity.id}-${datasetId}`, }), }), ), }; } -export function createAddressCountPreset({ +export function createAddressCountPreset({ scale, color, name, - datasetKey, + datasetId, }: { - scale: Scale; + scale: ResourceScale; name: string; - datasetKey: AddressCohortKey; + datasetId: AddressCohortId; color: Color; }): PartialPreset { + const addressCount: SeriesConfig = { + title: "Address Count", + color, + datasetPath: `/${scale}-to-${datasetId}-address-count`, + }; + return { scale, name: `Address Count`, title: `${name} Address Count`, icon: IconTablerAddressBook, - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Address Count", - color, - dataset: params.datasets[scale][`${datasetKey}_address_count`], - }, - ], - }); - }, description: "", + bottom: [addressCount], }; } diff --git a/app/src/scripts/presets/apply.ts b/app/src/scripts/presets/apply.ts index 2729b35a0..84b24095e 100644 --- a/app/src/scripts/presets/apply.ts +++ b/app/src/scripts/presets/apply.ts @@ -19,62 +19,13 @@ import { } from "../lightweightCharts/time"; import { setWhitespace } from "../lightweightCharts/whitespace"; import { colors } from "../utils/colors"; +import { dateFromTime, getNumberOfDaysBetweenTwoDates } from "../utils/date"; import { debounce } from "../utils/debounce"; import { stringToId } from "../utils/id"; import { webSockets } from "../ws"; +import { SeriesType } from "./enums"; -export enum SeriesType { - Line, - Based, - Histogram, - Candlestick, -} - -type SeriesConfig = - | { - dataset: ResourceDataset; - color?: Color; - topColor?: Color; - bottomColor?: Color; - colors?: undefined; - seriesType: SeriesType.Based; - title: string; - options?: BaselineSeriesOptions; - priceScaleOptions?: DeepPartialPriceScaleOptions; - defaultVisible?: boolean; - } - | { - dataset: ResourceDataset; - color?: Color; - colors?: Color[]; - seriesType: SeriesType.Histogram; - title: string; - options?: DeepPartialHistogramOptions; - priceScaleOptions?: DeepPartialPriceScaleOptions; - defaultVisible?: boolean; - } - | { - dataset: ResourceDataset; - seriesType: SeriesType.Candlestick; - priceScaleOptions?: DeepPartialPriceScaleOptions; - colors?: undefined; - color?: undefined; - options?: DeepPartialLineOptions; - defaultVisible?: boolean; - title: string; - } - | { - dataset: ResourceDataset; - color: Color; - colors?: undefined; - seriesType?: SeriesType.Line; - title: string; - options?: DeepPartialLineOptions; - priceScaleOptions?: DeepPartialPriceScaleOptions; - defaultVisible?: boolean; - }; - -export function applySeriesList({ +export function applySeriesList({ parentDiv, charts: reactiveChartList, top, @@ -92,15 +43,15 @@ export function applySeriesList({ parentDiv: HTMLDivElement; preset: Preset; legendSetter: Setter; - priceDataset?: ResourceDataset; + priceDataset?: AnyDatasetPath; priceOptions?: PriceSeriesOptions; - priceScaleOptions?: DeepPartialPriceScaleOptions; - top?: SeriesConfig[]; - bottom?: SeriesConfig[]; + // priceScaleOptions?: DeepPartialPriceScaleOptions; + // top?: SeriesConfig[]; + // bottom?: SeriesConfig[]; datasets: Datasets; dark: Accessor; activeIds: RWS; -}) { +} & PresetParams) { // --- // Reset states // --- @@ -145,22 +96,20 @@ export function applySeriesList({ const charts = [top || [], bottom] .flatMap((list) => (list ? [list] : [])) - .flatMap((seriesConfigList, index) => { - if (index !== 0 && seriesConfigList.length === 0) { + .flatMap((seriesConfigList, chartIndex) => { + if (chartIndex !== 0 && seriesConfigList.length === 0) { return []; } const div = document.createElement("div"); - div.className = "w-full cursor-crosshair min-h-0 border-lighter"; + div.className = "w-full cursor-crosshair min-h-0 border-lighter h-full"; parentDiv.appendChild(div); const chart = createChart(scale, div, { dark, - priceScaleOptions: { - ...priceScaleOptions, - }, + priceScaleOptions, }); if (!chart) { @@ -170,8 +119,28 @@ export function applySeriesList({ const whitespace = setWhitespace(chart, scale); - if (exactRange()) { - chart.timeScale().setVisibleRange(exactRange()); + const range = exactRange(); + + if (range) { + chart.timeScale().setVisibleRange(range); + } + + if (chartIndex === 0) { + initTimeScale({ + scale, + chart, + activeIds: activeIds, + exactRange, + }); + + if (range) { + updateVisiblePriceSeriesType({ + scale, + chart, + priceSeriesType, + timeRange: range, + }); + } } // const whitespace = new Array | undefined>( @@ -223,6 +192,10 @@ export function applySeriesList({ const chartLegend: SeriesLegend[] = []; + onCleanup(() => { + chartLegend.length = 0; + }); + const markerCallback = () => setMinMaxMarkers({ scale, @@ -241,12 +214,11 @@ export function applySeriesList({ createEffect(on([exactRange, dark], debouncedSetMinMaxMarkers)); - if (index === 0) { - const dataset = - priceDataset || - (datasets[preset.scale as Scale].price as unknown as NonNullable< - typeof priceDataset - >); + if (chartIndex === 0) { + const datasetPath = + priceDataset || (`/${scale}-to-ohlc` satisfies AnyDatasetPath); + + const dataset = datasets.getOrImport(scale, datasetPath); activeDatasets.push(dataset); @@ -258,11 +230,12 @@ export function applySeriesList({ }; function createPriceSeries(seriesType: PriceSeriesType) { - let seriesConfig: SeriesConfig; + let seriesConfig: SeriesConfig; if (seriesType === "Candlestick") { seriesConfig = { - dataset, + // @ts-ignore + datasetPath, title, seriesType: SeriesType.Candlestick, options: priceOptions, @@ -270,7 +243,8 @@ export function applySeriesList({ }; } else { seriesConfig = { - dataset, + // @ts-ignore + datasetPath, title, color: colors.white, options: priceOptions?.seriesOptions, @@ -279,6 +253,8 @@ export function applySeriesList({ } const priceSeries = createSeriesGroup({ + scale, + datasets, index: -1, activeIds, seriesConfig, @@ -319,9 +295,13 @@ export function applySeriesList({ } seriesConfigList.reverse().forEach((seriesConfig, index) => { - activeDatasets.push(seriesConfig.dataset); + const dataset = datasets.getOrImport(scale, seriesConfig.datasetPath); + + activeDatasets.push(dataset); createSeriesGroup({ + scale, + datasets, activeIds: activeIds, index, seriesConfig, @@ -358,10 +338,11 @@ export function applySeriesList({ charts.forEach((chart) => { if (chart.legendList.some((legend) => legend.drawn())) { chart.div.style.border = ""; + chart.div.style.maxHeight = "100%"; visibleCharts.push(chart); } else { - chart.div.style.height = "100%"; - // chart.div.style.height = "0px"; + // chart.div.style.height = "100%"; + chart.div.style.maxHeight = "0px"; chart.div.style.border = "none"; } }); @@ -384,13 +365,6 @@ export function applySeriesList({ 50, ); - initTimeScale({ - scale, - charts, - activeIds: activeIds, - exactRange, - }); - const activeDatasetsLength = activeDatasets.length; createEffect(() => { const range = activeIds(); @@ -410,21 +384,22 @@ export function applySeriesList({ for (let i = 0; i < charts.length; i++) { const chart = charts[i].chart; - chart.timeScale().subscribeVisibleLogicalRangeChange((timeRange) => { - if (!timeRange) return; + chart.timeScale().subscribeVisibleLogicalRangeChange((logicalRange) => { + if (!logicalRange) return; // Must be the chart with the visible timeScale if (i === lastChartIndex) { - debouncedUpdateVisiblePriceSeriesType( + debouncedUpdateVisiblePriceSeriesType({ + scale, chart, - timeRange, + logicalRange, priceSeriesType, - ); + }); } for (let j = 0; j <= lastChartIndex; j++) { if (i !== j) { - charts[j].chart.timeScale().setVisibleLogicalRange(timeRange); + charts[j].chart.timeScale().setVisibleLogicalRange(logicalRange); } } }); @@ -454,15 +429,38 @@ export function applySeriesList({ reactiveChartList.set(() => charts.map(({ chart }) => chart)); } -function updateVisiblePriceSeriesType( - chart: IChartApi, - range: LogicalRange, - priceSeriesType: RWS, -) { +export function updateVisiblePriceSeriesType({ + scale, + chart, + logicalRange, + timeRange, + priceSeriesType, +}: { + scale: ResourceScale; + chart: IChartApi; + logicalRange?: LogicalRange; + timeRange?: TimeRange; + priceSeriesType: RWS; +}) { try { const width = chart.timeScale().width(); - const ratio = (range.to - range.from) / width; + let ratio: number; + + if (logicalRange) { + ratio = (logicalRange.to - logicalRange.from) / width; + } else if (timeRange) { + if (scale === "date") { + ratio = getNumberOfDaysBetweenTwoDates( + dateFromTime(timeRange.from), + dateFromTime(timeRange.to), + ); + } else { + ratio = ((timeRange.to as number) - (timeRange.from as number)) / width; + } + } else { + throw Error(); + } if (ratio <= 0.5) { priceSeriesType.set("Candlestick"); @@ -473,6 +471,8 @@ function updateVisiblePriceSeriesType( } function createSeriesGroup({ + scale, + datasets, activeIds, seriesConfig, preset, @@ -484,8 +484,10 @@ function createSeriesGroup({ debouncedSetMinMaxMarkers, dark, }: { + scale: Scale; + datasets: Datasets; activeIds: Accessor; - seriesConfig: SeriesConfig; + seriesConfig: SeriesConfig; preset: Preset; chart: IChartApi; index: number; @@ -496,7 +498,7 @@ function createSeriesGroup({ dark: Accessor; }) { const { - dataset, + datasetPath, title, colors, color, @@ -506,13 +508,17 @@ function createSeriesGroup({ priceScaleOptions, } = seriesConfig; - const scale = preset.scale; + const dataset = datasets.getOrImport( + scale, + datasetPath as DatasetPath, + ); const seriesList: RWS< ISeriesApi<"Baseline" | "Line" | "Histogram" | "Candlestick"> | undefined >[] = new Array(dataset.fetchedJSONs.length); const legend = createSeriesLegend({ + scale, id: stringToId(title), presetId: preset.id, title, @@ -532,12 +538,15 @@ function createSeriesGroup({ createEffect(() => { const values = json.vec(); + if (!values) return; if (seriesIndex > 0) { let previous = chartLegend.at(seriesIndex - 1)?.seriesList[index]; - if (!previous?.()) return; + if (!previous?.()) { + return; + } } untrack(() => { diff --git a/app/src/scripts/presets/blocks/index.ts b/app/src/scripts/presets/blocks/index.ts index 81beb3bbc..67b9d73fb 100644 --- a/app/src/scripts/presets/blocks/index.ts +++ b/app/src/scripts/presets/blocks/index.ts @@ -1,5 +1,4 @@ import { colors } from "../../utils/colors"; -import { applySeriesList, SeriesType } from "../apply"; export function createPresets() { const scale: ResourceScale = "date"; @@ -13,18 +12,13 @@ export function createPresets() { name: "Height", title: "Block Height", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Height", - color: colors.bitcoin, - dataset: params.datasets.date.last_height, - }, - ], - }); - }, + bottom: [ + { + title: "Height", + color: colors.bitcoin, + datasetPath: `/date-to-last-height`, + }, + ], }, { scale, @@ -36,37 +30,32 @@ export function createPresets() { name: "Daily Sum", title: "Daily Sum Of Blocks Mined", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Target", - color: colors.white, - dataset: params.datasets.date.blocks_mined_1d_target, - options: { - lineStyle: 3, - }, - }, - { - title: "1W Avg.", - color: colors.momentumYellow, - dataset: params.datasets.date.blocks_mined_1w_sma, - defaultVisible: false, - }, - { - title: "1M Avg.", - color: colors.bitcoin, - dataset: params.datasets.date.blocks_mined_1m_sma, - }, - { - title: "Mined", - color: colors.darkBitcoin, - dataset: params.datasets.date.blocks_mined, - }, - ], - }); - }, + bottom: [ + { + title: "Target", + color: colors.white, + datasetPath: `/date-to-blocks-mined-1d-target`, + options: { + lineStyle: 3, + }, + }, + { + title: "1W Avg.", + color: colors.momentumYellow, + datasetPath: `/date-to-blocks-mined-1w-sma`, + defaultVisible: false, + }, + { + title: "1M Avg.", + color: colors.bitcoin, + datasetPath: `/date-to-blocks-mined-1m-sma`, + }, + { + title: "Mined", + color: colors.darkBitcoin, + datasetPath: `/date-to-blocks-mined`, + }, + ], }, { scale, @@ -74,26 +63,21 @@ export function createPresets() { name: "Weekly Sum", title: "Weekly Sum Of Blocks Mined", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Target", - color: colors.white, - dataset: params.datasets.date.blocks_mined_1w_target, - options: { - lineStyle: 3, - }, - }, - { - title: "Sum Mined", - color: colors.bitcoin, - dataset: params.datasets.date.blocks_mined_1w_sum, - }, - ], - }); - }, + bottom: [ + { + title: "Target", + color: colors.white, + datasetPath: `/date-to-blocks-mined-1w-target`, + options: { + lineStyle: 3, + }, + }, + { + title: "Sum Mined", + color: colors.bitcoin, + datasetPath: `/date-to-blocks-mined-1w-sum`, + }, + ], }, { scale, @@ -101,26 +85,21 @@ export function createPresets() { name: "Monthly Sum", title: "Monthly Sum Of Blocks Mined", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Target", - color: colors.white, - dataset: params.datasets.date.blocks_mined_1m_target, - options: { - lineStyle: 3, - }, - }, - { - title: "Sum Mined", - color: colors.bitcoin, - dataset: params.datasets.date.blocks_mined_1m_sum, - }, - ], - }); - }, + bottom: [ + { + title: "Target", + color: colors.white, + datasetPath: `/date-to-blocks-mined-1m-target`, + options: { + lineStyle: 3, + }, + }, + { + title: "Sum Mined", + color: colors.bitcoin, + datasetPath: `/date-to-blocks-mined-1m-sum`, + }, + ], }, { scale, @@ -128,26 +107,21 @@ export function createPresets() { name: "Yearly Sum", title: "Yearly Sum Of Blocks Mined", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Target", - color: colors.white, - dataset: params.datasets.date.blocks_mined_1y_target, - options: { - lineStyle: 3, - }, - }, - { - title: "Sum Mined", - color: colors.bitcoin, - dataset: params.datasets.date.blocks_mined_1y_sum, - }, - ], - }); - }, + bottom: [ + { + title: "Target", + color: colors.white, + datasetPath: `/date-to-blocks-mined-1y-target`, + options: { + lineStyle: 3, + }, + }, + { + title: "Sum Mined", + color: colors.bitcoin, + datasetPath: `/date-to-blocks-mined-1y-sum`, + }, + ], }, { scale, @@ -155,18 +129,13 @@ export function createPresets() { name: "Total", title: "Total Blocks Mined", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Mined", - color: colors.bitcoin, - dataset: params.datasets.date.total_blocks_mined, - }, - ], - }); - }, + bottom: [ + { + title: "Mined", + color: colors.bitcoin, + datasetPath: `/date-to-total-blocks-mined`, + }, + ], }, ], }, @@ -176,18 +145,13 @@ export function createPresets() { name: "Cumulative Size", title: "Cumulative Block Size", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Size (MB)", - color: colors.darkWhite, - dataset: params.datasets.date.cumulative_block_size, - }, - ], - }); - }, + bottom: [ + { + title: "Size (MB)", + color: colors.darkWhite, + datasetPath: `/date-to-cumulative-block-size`, + }, + ], }, ], } satisfies PartialPresetFolder; diff --git a/app/src/scripts/presets/coinblocks/index.ts b/app/src/scripts/presets/coinblocks/index.ts index 0b12d67e5..4bb36214c 100644 --- a/app/src/scripts/presets/coinblocks/index.ts +++ b/app/src/scripts/presets/coinblocks/index.ts @@ -1,11 +1,7 @@ import { colors } from "../../utils/colors"; -import { applySeriesList, SeriesType } from "../apply"; +import { SeriesType } from "../enums"; -export function createPresets({ - scale, -}: { - scale: Scale; -}) { +export function createPresets(scale: ResourceScale) { return { name: "Cointime Economics", tree: [ @@ -18,38 +14,33 @@ export function createPresets({ name: "All", title: "All Cointime Prices", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - top: [ - { - title: "Vaulted Price", - color: colors.vaultedness, - dataset: params.datasets[scale].vaulted_price, - }, - { - title: "Active Price", - color: colors.liveliness, - dataset: params.datasets[scale].active_price, - }, - { - title: "True Market Mean", - color: colors.trueMarketMeanPrice, - dataset: params.datasets[scale].true_market_mean, - }, - { - title: "Realized Price", - color: colors.bitcoin, - dataset: params.datasets[scale].realized_price, - }, - { - title: "Cointime", - color: colors.cointimePrice, - dataset: params.datasets[scale].cointime_price, - }, - ], - }); - }, + top: [ + { + title: "Vaulted Price", + color: colors.vaultedness, + datasetPath: `/${scale}-to-vaulted-price`, + }, + { + title: "Active Price", + color: colors.liveliness, + datasetPath: `/${scale}-to-active-price`, + }, + { + title: "True Market Mean", + color: colors.trueMarketMeanPrice, + datasetPath: `/${scale}-to-true-market-mean`, + }, + { + title: "Realized Price", + color: colors.bitcoin, + datasetPath: `/${scale}-to-realized-price`, + }, + { + title: "Cointime", + color: colors.cointimePrice, + datasetPath: `/${scale}-to-cointime-price`, + }, + ], }, { name: "Active", @@ -60,18 +51,13 @@ export function createPresets({ name: "Price", title: "Active Price", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - top: [ - { - title: "Active Price", - color: colors.liveliness, - dataset: params.datasets[scale].active_price, - }, - ], - }); - }, + top: [ + { + title: "Active Price", + color: colors.liveliness, + datasetPath: `/${scale}-to-active-price`, + }, + ], }, ], }, @@ -84,18 +70,13 @@ export function createPresets({ name: "Price", title: "Vaulted Price", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - top: [ - { - title: "Vaulted Price", - color: colors.vaultedness, - dataset: params.datasets[scale].vaulted_price, - }, - ], - }); - }, + top: [ + { + title: "Vaulted Price", + color: colors.vaultedness, + datasetPath: `/${scale}-to-vaulted-price`, + }, + ], }, ], }, @@ -108,18 +89,13 @@ export function createPresets({ name: "Price", title: "True Market Mean", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - top: [ - { - title: "True Market Mean", - color: colors.trueMarketMeanPrice, - dataset: params.datasets[scale].true_market_mean, - }, - ], - }); - }, + top: [ + { + title: "True Market Mean", + color: colors.trueMarketMeanPrice, + datasetPath: `/${scale}-to-true-market-mean`, + }, + ], }, ], }, @@ -132,18 +108,13 @@ export function createPresets({ name: "Price", title: "Cointime Price", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - top: [ - { - title: "Cointime", - color: colors.cointimePrice, - dataset: params.datasets[scale].cointime_price, - }, - ], - }); - }, + top: [ + { + title: "Cointime", + color: colors.cointimePrice, + datasetPath: `/${scale}-to-cointime-price`, + }, + ], }, ], }, @@ -158,36 +129,31 @@ export function createPresets({ name: "All", title: "Cointime Capitalizations", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - priceScaleOptions: { - mode: 1, - }, - bottom: [ - { - title: "Market Cap", - color: colors.white, - dataset: params.datasets[scale].market_cap, - }, - { - title: "Realized Cap", - color: colors.realizedCap, - dataset: params.datasets[scale].realized_cap, - }, - { - title: "Investor Cap", - color: colors.investorCap, - dataset: params.datasets[scale].investor_cap, - }, - { - title: "Thermo Cap", - color: colors.thermoCap, - dataset: params.datasets[scale].thermo_cap, - }, - ], - }); + priceScaleOptions: { + mode: 1, }, + bottom: [ + { + title: "Market Cap", + color: colors.white, + datasetPath: `/${scale}-to-market-cap`, + }, + { + title: "Realized Cap", + color: colors.realizedCap, + datasetPath: `/${scale}-to-realized-cap`, + }, + { + title: "Investor Cap", + color: colors.investorCap, + datasetPath: `/${scale}-to-investor-cap`, + }, + { + title: "Thermo Cap", + color: colors.thermoCap, + datasetPath: `/${scale}-to-thermo-cap`, + }, + ], }, { scale, @@ -195,21 +161,16 @@ export function createPresets({ name: "Thermo Cap", title: "Thermo Cap", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - priceScaleOptions: { - mode: 1, - }, - bottom: [ - { - title: "Thermo Cap", - color: colors.thermoCap, - dataset: params.datasets[scale].thermo_cap, - }, - ], - }); + priceScaleOptions: { + mode: 1, }, + bottom: [ + { + title: "Thermo Cap", + color: colors.thermoCap, + datasetPath: `/${scale}-to-thermo-cap`, + }, + ], }, { scale, @@ -217,21 +178,17 @@ export function createPresets({ name: "Investor Cap", title: "Investor Cap", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - priceScaleOptions: { - mode: 1, - }, - bottom: [ - { - title: "Investor Cap", - color: colors.investorCap, - dataset: params.datasets[scale].investor_cap, - }, - ], - }); + + priceScaleOptions: { + mode: 1, }, + bottom: [ + { + title: "Investor Cap", + color: colors.investorCap, + datasetPath: `/${scale}-to-investor-cap`, + }, + ], }, { scale, @@ -239,19 +196,13 @@ export function createPresets({ name: "Thermo Cap To Investor Cap Ratio", title: "Thermo Cap To Investor Cap Ratio (%)", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Ratio", - color: colors.bitcoin, - dataset: - params.datasets[scale].thermo_cap_to_investor_cap_ratio, - }, - ], - }); - }, + bottom: [ + { + title: "Ratio", + color: colors.bitcoin, + datasetPath: `/${scale}-to-thermo-cap-to-investor-cap-ratio`, + }, + ], }, ], }, @@ -264,28 +215,23 @@ export function createPresets({ name: "All", title: "All Coinblocks", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Coinblocks Created", - color: colors.coinblocksCreated, - dataset: params.datasets[scale].coinblocks_created, - }, - { - title: "Coinblocks Destroyed", - color: colors.coinblocksDestroyed, - dataset: params.datasets[scale].coinblocks_destroyed, - }, - { - title: "Coinblocks Stored", - color: colors.coinblocksStored, - dataset: params.datasets[scale].coinblocks_stored, - }, - ], - }); - }, + bottom: [ + { + title: "Coinblocks Created", + color: colors.coinblocksCreated, + datasetPath: `/${scale}-to-coinblocks-created`, + }, + { + title: "Coinblocks Destroyed", + color: colors.coinblocksDestroyed, + datasetPath: `/${scale}-to-coinblocks-destroyed`, + }, + { + title: "Coinblocks Stored", + color: colors.coinblocksStored, + datasetPath: `/${scale}-to-coinblocks-stored`, + }, + ], }, { scale, @@ -293,18 +239,13 @@ export function createPresets({ name: "Created", title: "Coinblocks Created", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Coinblocks Created", - color: colors.coinblocksCreated, - dataset: params.datasets[scale].coinblocks_created, - }, - ], - }); - }, + bottom: [ + { + title: "Coinblocks Created", + color: colors.coinblocksCreated, + datasetPath: `/${scale}-to-coinblocks-created`, + }, + ], }, { scale, @@ -312,18 +253,14 @@ export function createPresets({ name: "Destroyed", title: "Coinblocks Destroyed", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Coinblocks Destroyed", - color: colors.coinblocksDestroyed, - dataset: params.datasets[scale].coinblocks_destroyed, - }, - ], - }); - }, + + bottom: [ + { + title: "Coinblocks Destroyed", + color: colors.coinblocksDestroyed, + datasetPath: `/${scale}-to-coinblocks-destroyed`, + }, + ], }, { scale, @@ -331,18 +268,13 @@ export function createPresets({ name: "Stored", title: "Coinblocks Stored", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Coinblocks Stored", - color: colors.coinblocksStored, - dataset: params.datasets[scale].coinblocks_stored, - }, - ], - }); - }, + bottom: [ + { + title: "Coinblocks Stored", + color: colors.coinblocksStored, + datasetPath: `/${scale}-to-coinblocks-stored`, + }, + ], }, ], }, @@ -355,31 +287,23 @@ export function createPresets({ name: "All", title: "All Cumulative Coinblocks", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Cumulative Coinblocks Created", - color: colors.coinblocksCreated, - dataset: - params.datasets[scale].cumulative_coinblocks_created, - }, - { - title: "Cumulative Coinblocks Destroyed", - color: colors.coinblocksDestroyed, - dataset: - params.datasets[scale].cumulative_coinblocks_destroyed, - }, - { - title: "Cumulative Coinblocks Stored", - color: colors.coinblocksStored, - dataset: - params.datasets[scale].cumulative_coinblocks_stored, - }, - ], - }); - }, + bottom: [ + { + title: "Cumulative Coinblocks Created", + color: colors.coinblocksCreated, + datasetPath: `/${scale}-to-cumulative-coinblocks-created`, + }, + { + title: "Cumulative Coinblocks Destroyed", + color: colors.coinblocksDestroyed, + datasetPath: `/${scale}-to-cumulative-coinblocks-destroyed`, + }, + { + title: "Cumulative Coinblocks Stored", + color: colors.coinblocksStored, + datasetPath: `/${scale}-to-cumulative-coinblocks-stored`, + }, + ], }, { scale, @@ -387,19 +311,13 @@ export function createPresets({ name: "Created", title: "Cumulative Coinblocks Created", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Cumulative Coinblocks Created", - color: colors.coinblocksCreated, - dataset: - params.datasets[scale].cumulative_coinblocks_created, - }, - ], - }); - }, + bottom: [ + { + title: "Cumulative Coinblocks Created", + color: colors.coinblocksCreated, + datasetPath: `/${scale}-to-cumulative-coinblocks-created`, + }, + ], }, { scale, @@ -407,19 +325,13 @@ export function createPresets({ name: "Destroyed", title: "Cumulative Coinblocks Destroyed", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Cumulative Coinblocks Destroyed", - color: colors.coinblocksDestroyed, - dataset: - params.datasets[scale].cumulative_coinblocks_destroyed, - }, - ], - }); - }, + bottom: [ + { + title: "Cumulative Coinblocks Destroyed", + color: colors.coinblocksDestroyed, + datasetPath: `/${scale}-to-cumulative-coinblocks-destroyed`, + }, + ], }, { scale, @@ -427,19 +339,13 @@ export function createPresets({ name: "Stored", title: "Cumulative Coinblocks Stored", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Cumulative Coinblocks Stored", - color: colors.coinblocksStored, - dataset: - params.datasets[scale].cumulative_coinblocks_stored, - }, - ], - }); - }, + bottom: [ + { + title: "Cumulative Coinblocks Stored", + color: colors.coinblocksStored, + datasetPath: `/${scale}-to-cumulative-coinblocks-stored`, + }, + ], }, ], }, @@ -452,18 +358,13 @@ export function createPresets({ name: "Liveliness - Activity", title: "Liveliness (Activity)", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Liveliness", - color: colors.liveliness, - dataset: params.datasets[scale].liveliness, - }, - ], - }); - }, + bottom: [ + { + title: "Liveliness", + color: colors.liveliness, + datasetPath: `/${scale}-to-liveliness`, + }, + ], }, { scale, @@ -471,18 +372,13 @@ export function createPresets({ name: "Vaultedness", title: "Vaultedness", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Vaultedness", - color: colors.vaultedness, - dataset: params.datasets[scale].vaultedness, - }, - ], - }); - }, + bottom: [ + { + title: "Vaultedness", + color: colors.vaultedness, + datasetPath: `/${scale}-to-vaultedness`, + }, + ], }, { scale, @@ -490,23 +386,18 @@ export function createPresets({ name: "Versus", title: "Liveliness V. Vaultedness", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Liveliness", - color: colors.liveliness, - dataset: params.datasets[scale].liveliness, - }, - { - title: "Vaultedness", - color: colors.vaultedness, - dataset: params.datasets[scale].vaultedness, - }, - ], - }); - }, + bottom: [ + { + title: "Liveliness", + color: colors.liveliness, + datasetPath: `/${scale}-to-liveliness`, + }, + { + title: "Vaultedness", + color: colors.vaultedness, + datasetPath: `/${scale}-to-vaultedness`, + }, + ], }, { scale, @@ -514,19 +405,13 @@ export function createPresets({ name: "Activity To Vaultedness Ratio", title: "Activity To Vaultedness Ratio", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Activity To Vaultedness Ratio", - color: colors.activityToVaultednessRatio, - dataset: - params.datasets[scale].activity_to_vaultedness_ratio, - }, - ], - }); - }, + bottom: [ + { + title: "Activity To Vaultedness Ratio", + color: colors.activityToVaultednessRatio, + datasetPath: `/${scale}-to-activity-to-vaultedness-ratio`, + }, + ], }, { scale, @@ -534,24 +419,18 @@ export function createPresets({ name: "Concurrent Liveliness - Supply Adjusted Coindays Destroyed", title: "Concurrent Liveliness - Supply Adjusted Coindays Destroyed", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Concurrent Liveliness 14d Median", - color: colors.darkLiveliness, - dataset: - params.datasets[scale].concurrent_liveliness_2w_median, - }, - { - title: "Concurrent Liveliness", - color: colors.liveliness, - dataset: params.datasets[scale].concurrent_liveliness, - }, - ], - }); - }, + bottom: [ + { + title: "Concurrent Liveliness 14d Median", + color: colors.darkLiveliness, + datasetPath: `/${scale}-to-concurrent-liveliness-2w-median`, + }, + { + title: "Concurrent Liveliness", + color: colors.liveliness, + datasetPath: `/${scale}-to-concurrent-liveliness`, + }, + ], }, { scale, @@ -559,26 +438,20 @@ export function createPresets({ name: "Liveliness Incremental Change", title: "Liveliness Incremental Change", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Liveliness Incremental Change", - color: colors.darkLiveliness, - seriesType: SeriesType.Based, - dataset: params.datasets[scale].liveliness_net_change, - }, - { - title: "Liveliness Incremental Change 14 Day Median", - color: colors.liveliness, - seriesType: SeriesType.Based, - dataset: - params.datasets[scale].liveliness_net_change_2w_median, - }, - ], - }); - }, + bottom: [ + { + title: "Liveliness Incremental Change", + color: colors.darkLiveliness, + seriesType: SeriesType.Based, + datasetPath: `/${scale}-to-liveliness-net-change`, + }, + { + title: "Liveliness Incremental Change 14 Day Median", + color: colors.liveliness, + seriesType: SeriesType.Based, + datasetPath: `/${scale}-to-liveliness-net-change-2w-median`, + }, + ], }, ], }, @@ -591,18 +464,13 @@ export function createPresets({ name: "Vaulted", title: "Vaulted Supply", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Vaulted Supply", - color: colors.vaultedness, - dataset: params.datasets[scale].vaulted_supply, - }, - ], - }); - }, + bottom: [ + { + title: "Vaulted Supply", + color: colors.vaultedness, + datasetPath: `/${scale}-to-vaulted-supply`, + }, + ], }, { scale, @@ -610,18 +478,14 @@ export function createPresets({ name: "Active", title: "Active Supply", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Active Supply", - color: colors.liveliness, - dataset: params.datasets[scale].active_supply, - }, - ], - }); - }, + + bottom: [ + { + title: "Active Supply", + color: colors.liveliness, + datasetPath: `/${scale}-to-active-supply`, + }, + ], }, { scale, @@ -629,28 +493,24 @@ export function createPresets({ name: "Vaulted V. Active", title: "Vaulted V. Active", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Circulating Supply", - color: colors.coinblocksCreated, - dataset: params.datasets[scale].supply, - }, - { - title: "Vaulted Supply", - color: colors.vaultedness, - dataset: params.datasets[scale].vaulted_supply, - }, - { - title: "Active Supply", - color: colors.liveliness, - dataset: params.datasets[scale].active_supply, - }, - ], - }); - }, + + bottom: [ + { + title: "Circulating Supply", + color: colors.coinblocksCreated, + datasetPath: `/${scale}-to-supply`, + }, + { + title: "Vaulted Supply", + color: colors.vaultedness, + datasetPath: `/${scale}-to-vaulted-supply`, + }, + { + title: "Active Supply", + color: colors.liveliness, + datasetPath: `/${scale}-to-active-supply`, + }, + ], }, // TODO: Fix, Bad data // { @@ -670,13 +530,13 @@ export function createPresets({ // id: 'min-vaulted', // title: 'Min Vaulted Supply', // color: colors.vaultedness, - // dataset: params.params.datasets[scale].dateToMinVaultedSupply, + // dataset: params.`/${scale}-to-dateToMinVaultedSupply, // }, // { // id: 'max-active', // title: 'Max Active Supply', // color: colors.liveliness, - // dataset: params.params.datasets[scale].dateToMaxActiveSupply, + // dataset: params.`/${scale}-to-dateToMaxActiveSupply, // }, // ], // }) @@ -688,18 +548,13 @@ export function createPresets({ name: "Vaulted Net Change", title: "Vaulted Supply Net Change", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Vaulted Supply Net Change", - color: colors.vaultedness, - dataset: params.datasets[scale].vaulted_supply, - }, - ], - }); - }, + bottom: [ + { + title: "Vaulted Supply Net Change", + color: colors.vaultedness, + datasetPath: `/${scale}-to-vaulted-supply`, + }, + ], }, { scale, @@ -707,18 +562,13 @@ export function createPresets({ name: "Active Net Change", title: "Active Supply Net Change", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Active Supply Net Change", - color: colors.liveliness, - dataset: params.datasets[scale].active_supply_net_change, - }, - ], - }); - }, + bottom: [ + { + title: "Active Supply Net Change", + color: colors.liveliness, + datasetPath: `/${scale}-to-active-supply-net-change`, + }, + ], }, { scale, @@ -726,26 +576,20 @@ export function createPresets({ name: "Active VS. Vaulted 90D Net Change", title: "Active VS. Vaulted 90 Day Supply Net Change", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Active Supply Net Change", - color: colors.liveliness, - dataset: params.datasets[scale].active_supply_3m_net_change, - seriesType: SeriesType.Based, - }, - { - title: "Vaulted Supply Net Change", - color: colors.vaultedPrice, - seriesType: SeriesType.Based, - dataset: - params.datasets[scale].vaulted_supply_3m_net_change, - }, - ], - }); - }, + bottom: [ + { + title: "Active Supply Net Change", + color: colors.liveliness, + datasetPath: `/${scale}-to-active-supply-3m-net-change`, + seriesType: SeriesType.Based, + }, + { + title: "Vaulted Supply Net Change", + color: colors.vaultedPrice, + seriesType: SeriesType.Based, + datasetPath: `/${scale}-to-vaulted-supply-3m-net-change`, + }, + ], }, // TODO: Fix, Bad data // { @@ -766,7 +610,7 @@ export function createPresets({ // title: 'Vaulted Supply Annualized Net Change', // color: colors.vaultedness, // dataset: - // params.datasets[scale].vaultedAnnualizedSupplyNetChange, + // `/${scale}-to-vaultedAnnualizedSupplyNetChange, // }, // ], // }) @@ -791,13 +635,13 @@ export function createPresets({ // id: 'vaulting-rate', // title: 'Vaulting Rate', // color: colors.vaultedness, - // dataset: params.datasets[scale].vaultingRate, + // dataset: `/${scale}-to-vaultingRate, // }, // { // id: 'nominal-inflation-rate', // title: 'Nominal Inflation Rate', // color: colors.orange, - // dataset: params.params.datasets[scale].dateToYearlyInflationRate, + // dataset: params.`/${scale}-to-dateToYearlyInflationRate, // }, // ], // }) @@ -838,7 +682,7 @@ export function createPresets({ // // id: 'active', // // title: 'Active Supply', // // color: colors.liveliness, - // // dataset: params.datasets[scale].activeSupply, + // // dataset: `/${scale}-to-activeSupply, // // }, // ], // }) @@ -851,28 +695,23 @@ export function createPresets({ name: "In Profit", title: "Cointime Supply In Profit", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Circulating Supply", - color: colors.coinblocksCreated, - dataset: params.datasets[scale].supply, - }, - { - title: "Vaulted Supply", - color: colors.vaultedness, - dataset: params.datasets[scale].vaulted_supply, - }, - { - title: "Supply in profit", - color: colors.bitcoin, - dataset: params.datasets[scale].supply_in_profit, - }, - ], - }); - }, + bottom: [ + { + title: "Circulating Supply", + color: colors.coinblocksCreated, + datasetPath: `/${scale}-to-supply`, + }, + { + title: "Vaulted Supply", + color: colors.vaultedness, + datasetPath: `/${scale}-to-vaulted-supply`, + }, + { + title: "Supply in profit", + color: colors.bitcoin, + datasetPath: `/${scale}-to-supply-in-profit`, + }, + ], }, { scale, @@ -880,28 +719,23 @@ export function createPresets({ name: "In Loss", title: "Cointime Supply In Loss", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Circulating Supply", - color: colors.coinblocksCreated, - dataset: params.datasets[scale].supply, - }, - { - title: "Active Supply", - color: colors.liveliness, - dataset: params.datasets[scale].active_supply, - }, - { - title: "Supply in Loss", - color: colors.bitcoin, - dataset: params.datasets[scale].supply_in_loss, - }, - ], - }); - }, + bottom: [ + { + title: "Circulating Supply", + color: colors.coinblocksCreated, + datasetPath: `/${scale}-to-supply`, + }, + { + title: "Active Supply", + color: colors.liveliness, + datasetPath: `/${scale}-to-active-supply`, + }, + { + title: "Supply in Loss", + color: colors.bitcoin, + datasetPath: `/${scale}-to-supply-in-loss`, + }, + ], }, ], }, @@ -911,28 +745,21 @@ export function createPresets({ name: "Cointime Yearly Inflation Rate", title: "Cointime-Adjusted Yearly Inflation Rate (%)", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - priceScaleOptions: { - mode: 1, - }, - bottom: [ - { - title: "Cointime Adjusted", - color: colors.coinblocksCreated, - dataset: - params.datasets[scale] - .cointime_adjusted_yearly_inflation_rate, - }, - { - title: "Nominal", - color: colors.bitcoin, - dataset: params.datasets[scale].yearly_inflation_rate, - }, - ], - }); + priceScaleOptions: { + mode: 1, }, + bottom: [ + { + title: "Cointime Adjusted", + color: colors.coinblocksCreated, + datasetPath: `/${scale}-to-cointime-adjusted-yearly-inflation-rate`, + }, + { + title: "Nominal", + color: colors.bitcoin, + datasetPath: `/${scale}-to-yearly-inflation-rate`, + }, + ], }, { scale, @@ -940,26 +767,21 @@ export function createPresets({ name: "Cointime Velocity", title: "Cointime-Adjusted Transactions Velocity", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - priceScaleOptions: { - mode: 1, - }, - bottom: [ - { - title: "Cointime Adjusted", - color: colors.coinblocksCreated, - dataset: params.datasets[scale].cointime_adjusted_velocity, - }, - { - title: "Nominal", - color: colors.bitcoin, - dataset: params.datasets[scale].transaction_velocity, - }, - ], - }); + priceScaleOptions: { + mode: 1, }, + bottom: [ + { + title: "Cointime Adjusted", + color: colors.coinblocksCreated, + datasetPath: `/${scale}-to-cointime-adjusted-velocity`, + }, + { + title: "Nominal", + color: colors.bitcoin, + datasetPath: `/${scale}-to-transaction-velocity`, + }, + ], }, ], } satisfies PartialPresetFolder; diff --git a/app/src/scripts/presets/enums.ts b/app/src/scripts/presets/enums.ts new file mode 100644 index 000000000..8fdbc9aea --- /dev/null +++ b/app/src/scripts/presets/enums.ts @@ -0,0 +1,6 @@ +export const enum SeriesType { + Line, + Based, + Histogram, + Candlestick, +} diff --git a/app/src/scripts/presets/hodlers/index.ts b/app/src/scripts/presets/hodlers/index.ts index 1f9224b80..1997f858b 100644 --- a/app/src/scripts/presets/hodlers/index.ts +++ b/app/src/scripts/presets/hodlers/index.ts @@ -6,10 +6,9 @@ import { yearCohorts, } from "../../datasets/consts/age"; import { colors } from "../../utils/colors"; -import { applySeriesList } from "../apply"; import { createCohortPresetFolder } from "../templates/cohort"; -export function createPresets({ scale }: { scale: ResourceScale }) { +export function createPresets(scale: ResourceScale) { return { name: "Hodlers", tree: [ @@ -19,91 +18,80 @@ export function createPresets({ scale }: { scale: ResourceScale }) { title: `Hodl Supply`, description: "", icon: IconTablerRipple, - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: `24h`, - color: colors.up_to_1d, - dataset: - params.datasets.date - .up_to_1d_supply_to_circulating_supply_ratio, - }, + bottom: [ + { + title: `24h`, + color: colors.up_to_1d, + datasetPath: `/date-to-up-to-1d-supply-to-circulating-supply-ratio`, + }, - ...fromXToYCohorts.map(({ key, name, legend }) => ({ - title: legend, - color: colors[key], - dataset: - params.datasets.date[ - `${key}_supply_to_circulating_supply_ratio` - ], - })), + ...fromXToYCohorts.map(({ key, id, name, legend }) => ({ + title: legend, + color: colors[key], + datasetPath: + `/date-to-${id}-supply-to-circulating-supply-ratio` as const, + })), - { - title: `15y+`, - color: colors.from_15y, - dataset: - params.datasets.date - .from_15y_supply_to_circulating_supply_ratio, - }, - ], - }); - }, + { + title: `15y+`, + color: colors.from_15y, + datasetPath: `/date-to-from-15y-supply-to-circulating-supply-ratio`, + }, + ], }, - ...xthCohorts.map(({ key, name, legend }) => + ...xthCohorts.map(({ key, id, name, legend }) => createCohortPresetFolder({ scale, color: colors[key], name: legend, - datasetKey: key, + datasetId: id, title: name, }), ), { name: "Up To X", - tree: upToCohorts.map(({ key, name }) => + tree: upToCohorts.map(({ key, id, name }) => createCohortPresetFolder({ scale, color: colors[key], name, - datasetKey: key, + datasetId: id, title: name, }), ), }, { name: "From X To Y", - tree: fromXToYCohorts.map(({ key, name }) => + tree: fromXToYCohorts.map(({ key, id, name }) => createCohortPresetFolder({ scale, color: colors[key], name, - datasetKey: key, + datasetId: id, title: name, }), ), }, { name: "From X", - tree: fromXCohorts.map(({ key, name }) => + tree: fromXCohorts.map(({ key, id, name }) => createCohortPresetFolder({ scale, color: colors[key], name, - datasetKey: key, + datasetId: id, title: name, }), ), }, { name: "Years", - tree: yearCohorts.map(({ key, name }) => + tree: yearCohorts.map(({ key, id, name }) => createCohortPresetFolder({ scale, color: colors[key], name, - datasetKey: key, + datasetId: id, title: name, }), ), diff --git a/app/src/scripts/presets/index.ts b/app/src/scripts/presets/index.ts index 3196e7df3..ae6a12ac5 100644 --- a/app/src/scripts/presets/index.ts +++ b/app/src/scripts/presets/index.ts @@ -42,19 +42,19 @@ export function createPresets(): Presets { ...createCohortPresetList({ scale: "date", color: colors.bitcoin, - datasetKey: "", + datasetId: "", name: "", title: "", }), createLiquidityFolder({ scale: "date", color: colors.bitcoin, - datasetKey: "", + datasetId: "", name: "", }), - createHodlersPresets({ scale: "date" }), - createAddressesPresets({ scale: "date" }), - createCoinblocksPresets({ scale: "date" }), + createHodlersPresets("date"), + createAddressesPresets("date"), + createCoinblocksPresets("date"), ], } satisfies PartialPresetFolder, { @@ -68,18 +68,18 @@ export function createPresets(): Presets { scale: "height", color: colors.bitcoin, name: "", - datasetKey: "", + datasetId: "", title: "", }), createLiquidityFolder({ scale: "height", color: colors.bitcoin, - datasetKey: "", + datasetId: "", name: "", }), - createHodlersPresets({ scale: "height" }), - createAddressesPresets({ scale: "height" }), - createCoinblocksPresets({ scale: "height" }), + createHodlersPresets("height"), + createAddressesPresets("height"), + createCoinblocksPresets("height"), ] : [], } satisfies PartialPresetFolder, diff --git a/app/src/scripts/presets/market/averages/index.ts b/app/src/scripts/presets/market/averages/index.ts index f945edb2c..21c173eba 100644 --- a/app/src/scripts/presets/market/averages/index.ts +++ b/app/src/scripts/presets/market/averages/index.ts @@ -1,8 +1,6 @@ import { averages } from "/src/scripts/datasets/date"; import { colors } from "/src/scripts/utils/colors"; -import { applySeriesList } from "../../apply"; - export function createPresets(): PartialPresetFolder { const scale: ResourceScale = "date"; @@ -14,17 +12,12 @@ export function createPresets(): PartialPresetFolder { icon: IconTablerMathAvg, name: "All", title: "All Averages", - applyPreset(params) { - return applySeriesList({ - ...params, - top: averages.map((average) => ({ - title: average.key.toUpperCase(), - color: colors[`_${average.key}`], - dataset: params.datasets.date[`price_${average.key}_sma`], - })), - }); - }, description: "", + top: averages.map((average) => ({ + title: average.key.toUpperCase(), + color: colors[`_${average.key}`], + datasetPath: `/date-to-price-${average.key}-sma`, + })), }, ...averages.map(({ name, key }) => createPresetFolder({ @@ -55,17 +48,12 @@ function createPresetFolder({ description: "", icon: IconTablerMathAvg, title: `${name} Moving Average`, - applyPreset(params) { - return applySeriesList({ - ...params, - top: [ - { - title: `SMA`, - color, - dataset: params.datasets.date[`price_${key}_sma`], - }, - ], - }); - }, + top: [ + { + title: `SMA`, + color, + datasetPath: `/date-to-price-${key}-sma`, + }, + ], } satisfies PartialPreset; } diff --git a/app/src/scripts/presets/market/index.ts b/app/src/scripts/presets/market/index.ts index 5ebc350ea..667c1d93b 100644 --- a/app/src/scripts/presets/market/index.ts +++ b/app/src/scripts/presets/market/index.ts @@ -1,5 +1,4 @@ import { colors } from "../../utils/colors"; -import { applySeriesList } from "../apply"; import { createPresets as createAveragesPresets } from "./averages"; import { createPresets as createIndicatorsPresets } from "./indicators"; import { createPresets as createReturnsPresets } from "./returns"; @@ -13,9 +12,6 @@ export function createPresets(scale: ResourceScale) { icon: IconTablerCurrencyDollar, name: "Price", title: "Market Price", - applyPreset(params) { - return applySeriesList(params); - }, description: "", }, { @@ -23,19 +19,14 @@ export function createPresets(scale: ResourceScale) { icon: IconTablerInfinity, name: "Capitalization", title: "Market Capitalization", - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Market Cap.", - dataset: params.datasets[scale].market_cap, - color: colors.bitcoin, - }, - ], - }); - }, description: "", + bottom: [ + { + title: "Market Cap.", + datasetPath: `/${scale}-to-market-cap`, + color: colors.bitcoin, + }, + ], }, ...(scale === "date" ? ([ diff --git a/app/src/scripts/presets/market/returns/index.ts b/app/src/scripts/presets/market/returns/index.ts index 1d1c95d15..5d2a7b2ac 100644 --- a/app/src/scripts/presets/market/returns/index.ts +++ b/app/src/scripts/presets/market/returns/index.ts @@ -3,7 +3,7 @@ import { totalReturns, } from "/src/scripts/datasets/consts/returns"; -import { applySeriesList, SeriesType } from "../../apply"; +import { SeriesType } from "../../enums"; export function createPresets() { return { @@ -17,7 +17,7 @@ export function createPresets() { scale: "date", name, title: `${name} Total`, - key: `${key}_total`, + key: `${key}-total`, }), ), ], @@ -30,7 +30,7 @@ export function createPresets() { scale: "date", name, title: `${name} Compound`, - key: `${key}_compound`, + key: `${key}-compound`, }), ), ], @@ -48,7 +48,7 @@ function createPreset({ scale: ResourceScale; name: string; title: string; - key: `${TotalReturnKey}_total` | `${CompoundReturnKey}_compound`; + key: `${TotalReturnKey}-total` | `${CompoundReturnKey}-compound`; }): PartialPreset { return { scale, @@ -56,17 +56,12 @@ function createPreset({ description: "", icon: IconTablerReceiptTax, title: `${title} Return`, - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: `Return (%)`, - seriesType: SeriesType.Based, - dataset: params.datasets.date[`price_${key}_return`], - }, - ], - }); - }, + bottom: [ + { + title: `Return (%)`, + seriesType: SeriesType.Based, + datasetPath: `/date-to-price-${key}-return`, + }, + ], }; } diff --git a/app/src/scripts/presets/miners/index.ts b/app/src/scripts/presets/miners/index.ts index 58a288f19..67fd346f8 100644 --- a/app/src/scripts/presets/miners/index.ts +++ b/app/src/scripts/presets/miners/index.ts @@ -1,5 +1,5 @@ import { colors } from "../../utils/colors"; -import { applySeriesList, SeriesType } from "../apply"; +import { SeriesType } from "../enums"; export function createPresets(scale: ResourceScale) { return { @@ -19,18 +19,13 @@ export function createPresets(scale: ResourceScale) { name: "In Bitcoin", title: "Last Coinbase (In Bitcoin)", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Last", - color: colors.bitcoin, - dataset: params.datasets[scale].last_coinbase, - }, - ], - }); - }, + bottom: [ + { + title: "Last", + color: colors.bitcoin, + datasetPath: `/${scale}-to-last-coinbase`, + }, + ], }, { scale, @@ -38,19 +33,13 @@ export function createPresets(scale: ResourceScale) { name: "In Dollars", title: "Last Coinbase (In Dollars)", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Last", - color: colors.dollars, - dataset: - params.datasets[scale].last_coinbase_in_dollars, - }, - ], - }); - }, + bottom: [ + { + title: "Last", + color: colors.dollars, + datasetPath: `/${scale}-to-last-coinbase-in-dollars`, + }, + ], }, ], }, @@ -64,18 +53,13 @@ export function createPresets(scale: ResourceScale) { name: "In Bitcoin", title: "Daily Sum Of Bitcoin Coinbases", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Coinbases (Bitcoin)", - color: colors.bitcoin, - dataset: params.datasets[scale].coinbase, - }, - ], - }); - }, + bottom: [ + { + title: "Coinbases (Bitcoin)", + color: colors.bitcoin, + datasetPath: `/${scale}-to-coinbase`, + }, + ], }, { scale, @@ -83,19 +67,13 @@ export function createPresets(scale: ResourceScale) { name: "In Dollars", title: "Daily Sum Of Dollar Coinbases", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Coinbases (Dollars)", - color: colors.dollars, - dataset: - params.datasets[scale].coinbase_in_dollars, - }, - ], - }); - }, + bottom: [ + { + title: "Coinbases (Dollars)", + color: colors.dollars, + datasetPath: `/${scale}-to-coinbase-in-dollars`, + }, + ], }, ], }, @@ -109,18 +87,13 @@ export function createPresets(scale: ResourceScale) { name: "In Bitcoin", title: "Yearly Sum Of Bitcoin Coinbases", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Coinbases (Bitcoin)", - color: colors.bitcoin, - dataset: params.datasets[scale].coinbase_1y_sum, - }, - ], - }); - }, + bottom: [ + { + title: "Coinbases (Bitcoin)", + color: colors.bitcoin, + datasetPath: `/${scale}-to-coinbase-1y-sum`, + }, + ], }, { scale, @@ -128,20 +101,13 @@ export function createPresets(scale: ResourceScale) { name: "In Dollars", title: "Yearly Sum Of Dollar Coinbases", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Coinbases (Dollars)", - color: colors.dollars, - dataset: - params.datasets[scale] - .coinbase_in_dollars_1y_sum, - }, - ], - }); - }, + bottom: [ + { + title: "Coinbases (Dollars)", + color: colors.dollars, + datasetPath: `/${scale}-to-coinbase-in-dollars-1y-sum`, + }, + ], }, ], }, @@ -155,19 +121,13 @@ export function createPresets(scale: ResourceScale) { name: "In Bitcoin", title: "Cumulative Bitcoin Coinbases", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Coinbases (Bitcoin)", - color: colors.bitcoin, - dataset: - params.datasets[scale].cumulative_coinbase, - }, - ], - }); - }, + bottom: [ + { + title: "Coinbases (Bitcoin)", + color: colors.bitcoin, + datasetPath: `/${scale}-to-cumulative-coinbase`, + }, + ], }, { scale, @@ -175,20 +135,13 @@ export function createPresets(scale: ResourceScale) { name: "In Dollars", title: "Cumulative Dollar Coinbases", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Coinbases (Dollars)", - color: colors.dollars, - dataset: - params.datasets[scale] - .cumulative_coinbase_in_dollars, - }, - ], - }); - }, + bottom: [ + { + title: "Coinbases (Dollars)", + color: colors.dollars, + datasetPath: `/${scale}-to-cumulative-coinbase-in-dollars`, + }, + ], }, ], }, @@ -211,19 +164,13 @@ export function createPresets(scale: ResourceScale) { name: "In Bitcoin", title: "Last Subsidy (In Bitcoin)", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - - bottom: [ - { - title: "Last", - color: colors.bitcoin, - dataset: params.datasets[scale].last_subsidy, - }, - ], - }); - }, + bottom: [ + { + title: "Last", + color: colors.bitcoin, + datasetPath: `/${scale}-to-last-subsidy`, + }, + ], }, { scale, @@ -231,19 +178,13 @@ export function createPresets(scale: ResourceScale) { name: "In Dollars", title: "Last Subsidy (In Dollars)", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Last", - color: colors.dollars, - dataset: - params.datasets[scale].last_subsidy_in_dollars, - }, - ], - }); - }, + bottom: [ + { + title: "Last", + color: colors.dollars, + datasetPath: `/${scale}-to-last-subsidy-in-dollars`, + }, + ], }, ], }, @@ -257,18 +198,13 @@ export function createPresets(scale: ResourceScale) { name: "In Bitcoin", title: "Daily Sum Of Bitcoin Subsidies", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Subsidies (Bitcoin)", - color: colors.bitcoin, - dataset: params.datasets[scale].subsidy, - }, - ], - }); - }, + bottom: [ + { + title: "Subsidies (Bitcoin)", + color: colors.bitcoin, + datasetPath: `/${scale}-to-subsidy`, + }, + ], }, { scale, @@ -276,19 +212,13 @@ export function createPresets(scale: ResourceScale) { name: "In Dollars", title: "Daily Sum Of Dollar Subsidies", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Subsidies (Dollars)", - color: colors.dollars, - dataset: - params.datasets[scale].subsidy_in_dollars, - }, - ], - }); - }, + bottom: [ + { + title: "Subsidies (Dollars)", + color: colors.dollars, + datasetPath: `/${scale}-to-subsidy-in-dollars`, + }, + ], }, ], }, @@ -302,18 +232,13 @@ export function createPresets(scale: ResourceScale) { name: "In Bitcoin", title: "Yearly Sum Of Bitcoin Subsidies", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Subsidies (Bitcoin)", - color: colors.bitcoin, - dataset: params.datasets[scale].subsidy_1y_sum, - }, - ], - }); - }, + bottom: [ + { + title: "Subsidies (Bitcoin)", + color: colors.bitcoin, + datasetPath: `/${scale}-to-subsidy-1y-sum`, + }, + ], }, { scale, @@ -321,20 +246,13 @@ export function createPresets(scale: ResourceScale) { name: "In Dollars", title: "Yearly Sum Of Dollar Subsidies", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Subsidies (Dollars)", - color: colors.dollars, - dataset: - params.datasets[scale] - .subsidy_in_dollars_1y_sum, - }, - ], - }); - }, + bottom: [ + { + title: "Subsidies (Dollars)", + color: colors.dollars, + datasetPath: `/${scale}-to-subsidy-in-dollars-1y-sum`, + }, + ], }, ], }, @@ -348,19 +266,13 @@ export function createPresets(scale: ResourceScale) { name: "In Bitcoin", title: "Cumulative Bitcoin Subsidies", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Subsidies (Bitcoin)", - color: colors.bitcoin, - dataset: - params.datasets[scale].cumulative_subsidy, - }, - ], - }); - }, + bottom: [ + { + title: "Subsidies (Bitcoin)", + color: colors.bitcoin, + datasetPath: `/${scale}-to-cumulative-subsidy`, + }, + ], }, { scale, @@ -368,20 +280,13 @@ export function createPresets(scale: ResourceScale) { name: "In Dollars", title: "Cumulative Dollar Subsidies", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Subsidies (Dollars)", - color: colors.dollars, - dataset: - params.datasets[scale] - .cumulative_subsidy_in_dollars, - }, - ], - }); - }, + bottom: [ + { + title: "Subsidies (Dollars)", + color: colors.dollars, + datasetPath: `/${scale}-to-cumulative-subsidy-in-dollars`, + }, + ], }, ], }, @@ -404,18 +309,13 @@ export function createPresets(scale: ResourceScale) { name: "In Bitcoin", title: "Last Fees (In Bitcoin)", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Last", - color: colors.bitcoin, - dataset: params.datasets[scale].last_fees, - }, - ], - }); - }, + bottom: [ + { + title: "Last", + color: colors.bitcoin, + datasetPath: `/${scale}-to-last-fees`, + }, + ], }, { scale, @@ -423,19 +323,13 @@ export function createPresets(scale: ResourceScale) { name: "In Dollars", title: "Last Fees (In Dollars)", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Last", - color: colors.dollars, - dataset: - params.datasets[scale].last_fees_in_dollars, - }, - ], - }); - }, + bottom: [ + { + title: "Last", + color: colors.dollars, + datasetPath: `/${scale}-to-last-fees-in-dollars`, + }, + ], }, ], }, @@ -449,18 +343,13 @@ export function createPresets(scale: ResourceScale) { name: "In Bitcoin", title: "Daily Sum Of Bitcoin Fees", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Fees (Bitcoin)", - color: colors.bitcoin, - dataset: params.datasets[scale].fees, - }, - ], - }); - }, + bottom: [ + { + title: "Fees (Bitcoin)", + color: colors.bitcoin, + datasetPath: `/${scale}-to-fees`, + }, + ], }, { scale, @@ -468,18 +357,13 @@ export function createPresets(scale: ResourceScale) { name: "In Dollars", title: "Daily Sum Of Dollar Fees", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Fees (Dollars)", - color: colors.dollars, - dataset: params.datasets[scale].fees_in_dollars, - }, - ], - }); - }, + bottom: [ + { + title: "Fees (Dollars)", + color: colors.dollars, + datasetPath: `/${scale}-to-fees-in-dollars`, + }, + ], }, ], }, @@ -493,18 +377,13 @@ export function createPresets(scale: ResourceScale) { name: "In Bitcoin", title: "Yearly Sum Of Bitcoin Fees", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Fees (Bitcoin)", - color: colors.bitcoin, - dataset: params.datasets[scale].fees_1y_sum, - }, - ], - }); - }, + bottom: [ + { + title: "Fees (Bitcoin)", + color: colors.bitcoin, + datasetPath: `/${scale}-to-fees-1y-sum`, + }, + ], }, { scale, @@ -512,19 +391,13 @@ export function createPresets(scale: ResourceScale) { name: "In Dollars", title: "Yearly Sum Of Dollar Fees", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Fees (Dollars)", - color: colors.dollars, - dataset: - params.datasets[scale].fees_in_dollars_1y_sum, - }, - ], - }); - }, + bottom: [ + { + title: "Fees (Dollars)", + color: colors.dollars, + datasetPath: `/${scale}-to-fees-in-dollars-1y-sum`, + }, + ], }, ], }, @@ -538,18 +411,13 @@ export function createPresets(scale: ResourceScale) { name: "In Bitcoin", title: "Cumulative Bitcoin Fees", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Fees (Bitcoin)", - color: colors.bitcoin, - dataset: params.datasets[scale].cumulative_fees, - }, - ], - }); - }, + bottom: [ + { + title: "Fees (Bitcoin)", + color: colors.bitcoin, + datasetPath: `/${scale}-to-cumulative-fees`, + }, + ], }, { scale, @@ -557,20 +425,13 @@ export function createPresets(scale: ResourceScale) { name: "In Dollars", title: "Cumulative Dollar Fees", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Fees (Dollars)", - color: colors.dollars, - dataset: - params.datasets[scale] - .cumulative_fees_in_dollars, - }, - ], - }); - }, + bottom: [ + { + title: "Fees (Dollars)", + color: colors.dollars, + datasetPath: `/${scale}-to-cumulative-fees-in-dollars`, + }, + ], }, ], }, @@ -585,23 +446,18 @@ export function createPresets(scale: ResourceScale) { name: "Subsidy V. Fees", title: "Subsidy V. Fees", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Subsidy (%)", - color: colors.bitcoin, - dataset: params.datasets[scale].subsidy_to_coinbase_ratio, - }, - { - title: "Fees (%)", - color: colors.darkBitcoin, - dataset: params.datasets[scale].fees_to_coinbase_ratio, - }, - ], - }); - }, + bottom: [ + { + title: "Subsidy (%)", + color: colors.bitcoin, + datasetPath: `/${scale}-to-subsidy-to-coinbase-ratio`, + }, + { + title: "Fees (%)", + color: colors.darkBitcoin, + datasetPath: `/${scale}-to-fees-to-coinbase-ratio`, + }, + ], }, ...(scale === "date" @@ -612,21 +468,16 @@ export function createPresets(scale: ResourceScale) { name: "Puell Multiple", title: "Puell Multiple", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - priceScaleOptions: { - mode: 1, - }, - bottom: [ - { - title: "Multiple", - color: colors.bitcoin, - dataset: params.datasets.date.puell_multiple, - }, - ], - }); + priceScaleOptions: { + mode: 1, }, + bottom: [ + { + title: "Multiple", + color: colors.bitcoin, + datasetPath: `/date-to-puell-multiple`, + }, + ], }, { @@ -635,79 +486,62 @@ export function createPresets(scale: ResourceScale) { name: "Hash Rate", title: "Hash Rate (EH/s)", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - priceScaleOptions: { - mode: 1, - }, - bottom: [ - { - title: "1M SMA", - color: colors.momentumYellow, - dataset: params.datasets.date.hash_rate_1m_sma, - }, - { - title: "1W SMA", - color: colors.bitcoin, - dataset: params.datasets.date.hash_rate_1w_sma, - }, - { - title: "Rate", - color: colors.darkBitcoin, - dataset: params.datasets.date.hash_rate, - }, - ], - }); + priceScaleOptions: { + mode: 1, }, + bottom: [ + { + title: "1M SMA", + color: colors.momentumYellow, + datasetPath: `/date-to-hash-rate-1m-sma`, + }, + { + title: "1W SMA", + color: colors.bitcoin, + datasetPath: `/date-to-hash-rate-1w-sma`, + }, + { + title: "Rate", + color: colors.darkBitcoin, + datasetPath: `/date-to-hash-rate`, + }, + ], }, - { scale, icon: IconTablerRibbonHealth, name: "Hash Ribbon", title: "Hash Ribbon (EH/s)", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - priceScaleOptions: { - mode: 1, - }, - bottom: [ - { - title: "1M SMA", - color: colors.profit, - dataset: params.datasets.date.hash_rate_1m_sma, - }, - { - title: "2M SMA", - color: colors.loss, - dataset: params.datasets.date.hash_rate_2m_sma, - }, - ], - }); + priceScaleOptions: { + mode: 1, }, + bottom: [ + { + title: "1M SMA", + color: colors.profit, + datasetPath: `/date-to-hash-rate-1m-sma`, + }, + { + title: "2M SMA", + color: colors.loss, + datasetPath: `/date-to-hash-rate-2m-sma`, + }, + ], }, - { scale, icon: IconTablerTag, name: "Hash Price", title: "Hash Price", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Price ($/PH/s)", - color: colors.dollars, - dataset: params.datasets.date.hash_price, - }, - ], - }); - }, + bottom: [ + { + title: "Price ($/PH/s)", + color: colors.dollars, + datasetPath: `/date-to-hash-price`, + }, + ], }, ] satisfies PartialPreset[]) : []), @@ -718,21 +552,16 @@ export function createPresets(scale: ResourceScale) { name: "Difficulty", title: "Difficulty", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - priceScaleOptions: { - mode: 1, - }, - bottom: [ - { - title: "Difficulty", - color: colors.bitcoin, - dataset: params.datasets[scale].difficulty, - }, - ], - }); + priceScaleOptions: { + mode: 1, }, + bottom: [ + { + title: "Difficulty", + color: colors.bitcoin, + datasetPath: `/${scale}-to-difficulty`, + }, + ], }, ...(scale === "date" @@ -743,18 +572,13 @@ export function createPresets(scale: ResourceScale) { name: "Difficulty Adjustment", title: "Difficulty Adjustment", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Adjustment (%)", - seriesType: SeriesType.Based, - dataset: params.datasets[scale].difficulty_adjustment, - }, - ], - }); - }, + bottom: [ + { + title: "Adjustment (%)", + seriesType: SeriesType.Based, + datasetPath: `/${scale}-to-difficulty-adjustment`, + }, + ], }, ] satisfies PartialPreset[]) : []), @@ -765,21 +589,16 @@ export function createPresets(scale: ResourceScale) { name: "Annualized Issuance", title: "Annualized Issuance", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - priceScaleOptions: { - mode: 1, - }, - bottom: [ - { - title: "Issuance", - color: colors.bitcoin, - dataset: params.datasets[scale].annualized_issuance, - }, - ], - }); + priceScaleOptions: { + mode: 1, }, + bottom: [ + { + title: "Issuance", + color: colors.bitcoin, + datasetPath: `/${scale}-to-annualized-issuance`, + }, + ], }, { @@ -788,21 +607,16 @@ export function createPresets(scale: ResourceScale) { name: "Yearly Inflation Rate", title: "Yearly Inflation Rate", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - priceScaleOptions: { - mode: 1, - }, - bottom: [ - { - title: "Rate (%)", - color: colors.bitcoin, - dataset: params.datasets[scale].yearly_inflation_rate, - }, - ], - }); + priceScaleOptions: { + mode: 1, }, + bottom: [ + { + title: "Rate (%)", + color: colors.bitcoin, + datasetPath: `/${scale}-to-yearly-inflation-rate`, + }, + ], }, // For scale === "height" diff --git a/app/src/scripts/presets/templates/cohort.ts b/app/src/scripts/presets/templates/cohort.ts deleted file mode 100644 index 727b575b4..000000000 --- a/app/src/scripts/presets/templates/cohort.ts +++ /dev/null @@ -1,880 +0,0 @@ -import { percentiles } from "../../datasets/consts/percentiles"; -import { colors } from "../../utils/colors"; -import { applySeriesList, SeriesType } from "../apply"; - -export function createCohortPresetFolder({ - scale, - color, - name, - datasetKey, - title, -}: { - scale: Scale; - name: string; - datasetKey: AnyPossibleCohortKey; - color: Color; - title: string; -}) { - return { - name, - tree: createCohortPresetList({ - title, - name, - scale, - color, - datasetKey, - }), - } satisfies PartialPresetFolder; -} - -export function createCohortPresetList({ - name, - scale, - color, - datasetKey, - title, -}: { - name: string; - scale: Scale; - datasetKey: AnyPossibleCohortKey; - title: string; - color: Color; -}) { - const datasetPrefix = datasetKey - ? (`${datasetKey}_` as const) - : ("" as const); - - return [ - { - name: "UTXOs", - tree: [ - { - scale, - name: `Count`, - title: `${title} Unspent Transaction Outputs Count`, - icon: () => IconTablerTicket, - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Count", - color, - dataset: params.datasets[scale][`${datasetPrefix}utxo_count`], - }, - ], - }); - }, - description: "", - }, - ], - }, - { - name: "Realized", - tree: [ - { - scale, - name: `Price`, - title: `${title} Realized Price`, - description: "", - icon: () => IconTablerTag, - applyPreset(params) { - return applySeriesList({ - ...params, - top: [ - { - title: "Realized Price", - color, - dataset: - params.datasets[scale][`${datasetPrefix}realized_price`], - }, - ], - }); - }, - }, - { - scale, - name: `Capitalization`, - title: `${title} Realized Capitalization`, - icon: () => IconTablerPigMoney, - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: `${name} Realized Cap.`, - color, - dataset: - params.datasets[scale][`${datasetPrefix}realized_cap`], - }, - ...(datasetKey - ? [ - { - title: "Realized Cap.", - color: colors.bitcoin, - dataset: params.datasets[scale].realized_cap, - defaultVisible: false, - }, - ] - : []), - ], - }); - }, - description: "", - }, - { - scale, - name: `Capitalization 1M Net Change`, - title: `${title} Realized Capitalization 1 Month Net Change`, - icon: () => IconTablerStatusChange, - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: `Net Change`, - seriesType: SeriesType.Based, - dataset: - params.datasets[scale][ - `${datasetPrefix}realized_cap_1m_net_change` - ], - }, - ], - }); - }, - description: "", - }, - { - scale, - name: `Profit`, - title: `${title} Realized Profit`, - icon: () => IconTablerCash, - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Realized Profit", - dataset: - params.datasets[scale][`${datasetPrefix}realized_profit`], - color: colors.profit, - }, - ], - }); - }, - description: "", - }, - { - scale, - name: "Loss", - title: `${title} Realized Loss`, - icon: () => IconTablerCoffin, - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Realized Loss", - dataset: - params.datasets[scale][`${datasetPrefix}realized_loss`], - color: colors.loss, - }, - ], - }); - }, - description: "", - }, - { - scale, - name: `PNL`, - title: `${title} Realized Profit And Loss`, - icon: () => IconTablerArrowsVertical, - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Profit", - color: colors.profit, - dataset: - params.datasets[scale][`${datasetPrefix}realized_profit`], - seriesType: SeriesType.Based, - }, - { - title: "Loss", - color: colors.loss, - dataset: - params.datasets[scale][ - `${datasetPrefix}negative_realized_loss` - ], - seriesType: SeriesType.Based, - }, - ], - }); - }, - description: "", - }, - { - scale, - name: `Net PNL`, - title: `${title} Net Realized Profit And Loss`, - icon: () => IconTablerScale, - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Net PNL", - seriesType: SeriesType.Based, - dataset: - params.datasets[scale][ - `${datasetPrefix}net_realized_profit_and_loss` - ], - }, - ], - }); - }, - description: "", - }, - { - scale, - name: `Net PNL Relative To Market Cap`, - title: `${title} Net Realized Profit And Loss Relative To Market Capitalization`, - icon: () => IconTablerDivide, - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Net", - seriesType: SeriesType.Based, - dataset: - params.datasets[scale][ - `${datasetPrefix}net_realized_profit_and_loss_to_market_cap_ratio` - ], - }, - ], - }); - }, - description: "", - }, - { - scale, - name: `Cumulative Profit`, - title: `${title} Cumulative Realized Profit`, - icon: () => IconTablerSum, - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Cumulative Realized Profit", - color: colors.profit, - dataset: - params.datasets[scale][ - `${datasetPrefix}cumulative_realized_profit` - ], - }, - ], - }); - }, - description: "", - }, - { - scale, - name: "Cumulative Loss", - title: `${title} Cumulative Realized Loss`, - icon: () => IconTablerSum, - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Cumulative Realized Loss", - color: colors.loss, - dataset: - params.datasets[scale][ - `${datasetPrefix}cumulative_realized_loss` - ], - }, - ], - }); - }, - description: "", - }, - { - scale, - name: `Cumulative Net PNL`, - title: `${title} Cumulative Net Realized Profit And Loss`, - icon: () => IconTablerSum, - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Cumulative Net Realized PNL", - seriesType: SeriesType.Based, - dataset: - params.datasets[scale][ - `${datasetPrefix}cumulative_net_realized_profit_and_loss` - ], - }, - ], - }); - }, - description: "", - }, - { - scale, - name: `Cumulative Net PNL 30 Day Change`, - title: `${title} Cumulative Net Realized Profit And Loss 30 Day Change`, - icon: () => IconTablerTimeDuration30, - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Cumulative Net Realized PNL 30d Change", - dataset: - params.datasets[scale][ - `${datasetPrefix}cumulative_net_realized_profit_and_loss_1m_net_change` - ], - seriesType: SeriesType.Based, - }, - ], - }); - }, - description: "", - }, - ], - }, - { - name: "Unrealized", - tree: [ - { - scale, - name: `Profit`, - title: `${title} Unrealized Profit`, - icon: () => IconTablerMoodDollar, - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Profit", - dataset: - params.datasets[scale][`${datasetPrefix}unrealized_profit`], - color: colors.profit, - }, - ], - }); - }, - description: "", - }, - - { - scale, - name: "Loss", - title: `${title} Unrealized Loss`, - icon: () => IconTablerMoodSadDizzy, - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Loss", - dataset: - params.datasets[scale][`${datasetPrefix}unrealized_loss`], - color: colors.loss, - }, - ], - }); - }, - description: "", - }, - { - scale, - name: `PNL`, - title: `${title} Unrealized Profit And Loss`, - icon: () => IconTablerArrowsVertical, - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Profit", - color: colors.profit, - dataset: - params.datasets[scale][`${datasetPrefix}unrealized_profit`], - seriesType: SeriesType.Based, - }, - { - title: "Loss", - color: colors.loss, - dataset: - params.datasets[scale][ - `${datasetPrefix}negative_unrealized_loss` - ], - seriesType: SeriesType.Based, - }, - ], - }); - }, - description: "", - }, - { - scale, - name: `Net PNL`, - title: `${title} Net Unrealized Profit And Loss`, - icon: () => IconTablerScale, - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Net Unrealized PNL", - dataset: - params.datasets[scale][ - `${datasetPrefix}net_unrealized_profit_and_loss` - ], - seriesType: SeriesType.Based, - }, - ], - }); - }, - description: "", - }, - { - scale, - name: `Net PNL Relative To Market Cap`, - title: `${title} Net Unrealized Profit And Loss Relative To Total Market Capitalization`, - icon: () => IconTablerDivide, - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Relative Net Unrealized PNL", - dataset: - params.datasets[scale][ - `${datasetPrefix}net_unrealized_profit_and_loss_to_market_cap_ratio` - ], - seriesType: SeriesType.Based, - }, - ], - }); - }, - description: "", - }, - ], - }, - { - name: "Supply", - tree: [ - { - name: "Absolute", - tree: [ - { - scale, - name: "All", - title: `${title} Profit And Loss`, - icon: () => IconTablerArrowsCross, - description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "In Profit", - color: colors.profit, - dataset: - params.datasets[scale][ - `${datasetPrefix}supply_in_profit` - ], - }, - { - title: "In Loss", - color: colors.loss, - dataset: - params.datasets[scale][ - `${datasetPrefix}supply_in_loss` - ], - }, - { - title: "Total", - color: colors.white, - dataset: params.datasets[scale][`${datasetPrefix}supply`], - }, - { - title: "Halved Total", - color: colors.gray, - dataset: - params.datasets[scale][`${datasetPrefix}halved_supply`], - options: { - lineStyle: 4, - }, - }, - ], - }); - }, - }, - { - scale, - name: `Total`, - title: `${title} Total supply`, - icon: () => IconTablerSum, - description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Supply", - color, - dataset: params.datasets[scale][`${datasetPrefix}supply`], - }, - ], - }); - }, - }, - { - scale, - name: "In Profit", - title: `${title} Supply In Profit`, - icon: () => IconTablerTrendingUp, - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Supply", - color: colors.profit, - dataset: - params.datasets[scale][ - `${datasetPrefix}supply_in_profit` - ], - }, - ], - }); - }, - description: "", - }, - { - scale, - name: "In Loss", - title: `${title} Supply In Loss`, - icon: () => IconTablerTrendingDown, - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Supply", - color: colors.loss, - dataset: - params.datasets[scale][ - `${datasetPrefix}supply_in_loss` - ], - }, - ], - }); - }, - description: "", - }, - ], - }, - { - name: "Relative To Circulating", - tree: [ - { - scale, - name: "All", - title: `${title} Profit And Loss Relative To Circulating Supply`, - icon: () => IconTablerArrowsCross, - description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "In Profit", - color: colors.profit, - dataset: - params.datasets[scale][ - `${datasetPrefix}supply_in_profit_to_circulating_supply_ratio` - ], - }, - { - title: "In Loss", - color: colors.loss, - dataset: - params.datasets[scale][ - `${datasetPrefix}supply_in_loss_to_circulating_supply_ratio` - ], - }, - { - title: "100%", - color: colors.white, - dataset: - params.datasets[scale][ - `${datasetPrefix}supply_to_circulating_supply_ratio` - ], - }, - { - title: "50%", - color: colors.gray, - dataset: - params.datasets[scale][ - `${datasetPrefix}halved_supply_to_circulating_supply_ratio` - ], - options: { - lineStyle: 4, - }, - }, - ], - }); - }, - }, - { - scale, - name: `Total`, - title: `${title} Total supply Relative To Circulating Supply`, - icon: () => IconTablerSum, - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Supply", - color, - dataset: - params.datasets[scale][ - `${datasetPrefix}supply_to_circulating_supply_ratio` - ], - }, - ], - }); - }, - description: "", - }, - { - scale, - name: "In Profit", - title: `${title} Supply In Profit Relative To Circulating Supply`, - icon: () => IconTablerTrendingUp, - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Supply", - color: colors.profit, - dataset: - params.datasets[scale][ - `${datasetPrefix}supply_in_profit_to_circulating_supply_ratio` - ], - }, - ], - }); - }, - description: "", - }, - { - scale, - name: "In Loss", - title: `${title} Supply In Loss Relative To Circulating Supply`, - icon: () => IconTablerTrendingDown, - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Supply", - color: colors.loss, - dataset: - params.datasets[scale][ - `${datasetPrefix}supply_in_loss_to_circulating_supply_ratio` - ], - }, - ], - }); - }, - description: "", - }, - ], - }, - { - name: "Relative To Own", - tree: [ - { - scale, - name: "All", - title: `${title} Supply In Profit And Loss Relative To Own Supply`, - icon: () => IconTablerArrowsCross, - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "In Profit", - dataset: - params.datasets[scale][ - `${datasetPrefix}supply_in_profit_to_own_supply_ratio` - ], - color: colors.profit, - }, - { - title: "In Loss", - color: colors.loss, - dataset: - params.datasets[scale][ - `${datasetPrefix}supply_in_loss_to_own_supply_ratio` - ], - }, - { - title: "100%", - color: colors.white, - dataset: params.datasets[scale][100], - options: { - lastValueVisible: false, - }, - }, - { - title: "50%", - color: colors.gray, - dataset: params.datasets[scale][50], - options: { - lineStyle: 4, - lastValueVisible: false, - }, - }, - ], - }); - }, - description: "", - }, - { - scale, - name: "In Profit", - title: `${title} Supply In Profit Relative To Own Supply`, - icon: () => IconTablerTrendingUp, - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Supply", - color: colors.profit, - dataset: - params.datasets[scale][ - `${datasetPrefix}supply_in_profit_to_own_supply_ratio` - ], - }, - ], - }); - }, - description: "", - }, - { - scale, - name: "In Loss", - title: `${title} Supply In Loss Relative To Own Supply`, - icon: () => IconTablerTrendingDown, - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Supply", - color: colors.loss, - dataset: - params.datasets[scale][ - `${datasetPrefix}supply_in_loss_to_own_supply_ratio` - ], - }, - ], - }); - }, - description: "", - }, - ], - }, - // createMomentumPresetFolder({ - // datasets: datasets[scale], - // scale, - // id: `${scale}-${id}-supply-in-profit-and-loss-percentage-self`, - // title: `${title} Supply In Profit And Loss (% Self)`, - // datasetKey: `${datasetKey}SupplyPNL%Self`, - // }), - ], - }, - { - name: "Prices Paid", - tree: [ - { - scale, - name: `Average`, - title: `${title} Average Price Paid - Realized Price`, - icon: () => IconTablerMathAvg, - applyPreset(params) { - return applySeriesList({ - ...params, - top: [ - { - title: "Average", - color, - dataset: - params.datasets[scale][`${datasetPrefix}realized_price`], - }, - ], - }); - }, - description: "", - }, - { - scale, - name: `Deciles`, - title: `${title} deciles`, - icon: () => IconTablerSquareHalf, - applyPreset(params) { - return applySeriesList({ - ...params, - top: percentiles - .filter(({ value }) => Number(value) % 10 === 0) - .map(({ name, key }) => ({ - dataset: params.datasets[scale][`${datasetPrefix}${key}`], - color, - title: name, - })), - }); - }, - description: "", - }, - ...percentiles.map( - (percentile): PartialPreset => ({ - scale, - name: percentile.name, - title: `${title} ${percentile.title}`, - icon: () => IconTablerSquareHalf, - applyPreset(params) { - return applySeriesList({ - ...params, - top: [ - { - title: percentile.name, - color, - dataset: - params.datasets[scale][ - `${datasetPrefix}${percentile.key}` - ], - }, - ], - }); - }, - description: "", - }), - ), - ], - }, - ] satisfies PartialPresetTree; -} diff --git a/app/src/scripts/presets/templates/cohort/index.ts b/app/src/scripts/presets/templates/cohort/index.ts new file mode 100644 index 000000000..1c95448e0 --- /dev/null +++ b/app/src/scripts/presets/templates/cohort/index.ts @@ -0,0 +1,77 @@ +import { createCohortPresetPricesPaidFolder } from "./pricesPaid"; +import { createCohortPresetRealizedFolder } from "./realized"; +import { createCohortPresetSupplyFolder } from "./supply"; +import { createCohortPresetUnrealizedFolder } from "./unrealized"; +import { createCohortPresetUTXOFolder } from "./utxo"; + +export function createCohortPresetFolder({ + scale, + color, + name, + datasetId, + title, +}: { + scale: ResourceScale; + name: string; + datasetId: AnyPossibleCohortId; + color: Color; + title: string; +}) { + return { + name, + tree: createCohortPresetList({ + title, + name, + scale, + color, + datasetId: datasetId, + }), + } satisfies PartialPresetFolder; +} + +export function createCohortPresetList({ + name, + scale, + color, + datasetId, + title, +}: { + name: string; + scale: ResourceScale; + datasetId: AnyPossibleCohortId; + title: string; + color: Color; +}) { + return [ + createCohortPresetUTXOFolder({ + color, + datasetId, + scale, + title, + }), + createCohortPresetRealizedFolder({ + color, + datasetId, + scale, + title, + }), + createCohortPresetUnrealizedFolder({ + color, + datasetId, + scale, + title, + }), + createCohortPresetSupplyFolder({ + color, + datasetId, + scale, + title, + }), + createCohortPresetPricesPaidFolder({ + color, + datasetId, + scale, + title, + }), + ] satisfies PartialPresetTree; +} diff --git a/app/src/scripts/presets/templates/cohort/pricesPaid.ts b/app/src/scripts/presets/templates/cohort/pricesPaid.ts new file mode 100644 index 000000000..617f33a7e --- /dev/null +++ b/app/src/scripts/presets/templates/cohort/pricesPaid.ts @@ -0,0 +1,79 @@ +import { percentiles } from "/src/scripts/datasets/consts/percentiles"; + +import { datasetIdToPrefix } from "./utils"; + +export function createCohortPresetPricesPaidFolder({ + scale, + color, + datasetId, + title, +}: { + scale: ResourceScale; + datasetId: AnyPossibleCohortId; + title: string; + color: Color; +}): PartialPresetFolder { + return { + name: "Prices Paid", + tree: [ + { + scale, + name: `Average`, + title: `${title} Average Price Paid - Realized Price`, + description: "", + icon: () => IconTablerMathAvg, + top: [ + { + title: "Average", + color, + datasetPath: `/${scale as ResourceScale}-to-${datasetIdToPrefix(datasetId)}realized-price`, + }, + ], + }, + { + scale, + name: `Deciles`, + title: `${title} deciles`, + icon: () => IconTablerSquareHalf, + description: "", + top: percentiles + .filter(({ value }) => Number(value) % 10 === 0) + .map(({ name, id }) => { + const datasetPath = generatePath(scale, datasetId, id); + + return { + datasetPath, + color, + title: name, + }; + }), + }, + ...percentiles.map( + (percentile): PartialPreset => ({ + scale, + name: percentile.name, + title: `${title} ${percentile.title}`, + description: "", + icon: () => IconTablerSquareHalf, + top: [ + { + title: percentile.name, + color, + datasetPath: generatePath(scale, datasetId, percentile.id), + }, + ], + }), + ), + ], + }; +} + +function generatePath( + scale: ResourceScale, + cohortId: AnyPossibleCohortId, + id: PercentileId, +): AnyDatasetPath { + const datasetPrefix = datasetIdToPrefix(cohortId); + + return `/${scale}-to-${datasetPrefix}${id}` as const; +} diff --git a/app/src/scripts/presets/templates/cohort/realized.ts b/app/src/scripts/presets/templates/cohort/realized.ts new file mode 100644 index 000000000..913aa1fbb --- /dev/null +++ b/app/src/scripts/presets/templates/cohort/realized.ts @@ -0,0 +1,209 @@ +import { colors } from "/src/scripts/utils/colors"; + +import { SeriesType } from "../../enums"; +import { datasetIdToPrefix } from "./utils"; + +export function createCohortPresetRealizedFolder({ + scale, + color, + datasetId, + title, +}: { + scale: ResourceScale; + datasetId: AnyPossibleCohortId; + title: string; + color: Color; +}): PartialPresetFolder { + const datasetPrefix = datasetIdToPrefix(datasetId); + + return { + name: "Realized", + tree: [ + { + scale, + name: `Price`, + title: `${title} Realized Price`, + description: "", + icon: () => IconTablerTag, + top: [ + { + title: "Realized Price", + color, + datasetPath: `/${scale}-to-${datasetPrefix}realized-price`, + }, + ], + }, + { + scale, + name: `Capitalization`, + title: `${title} Realized Capitalization`, + description: "", + icon: () => IconTablerPigMoney, + bottom: [ + { + title: `${name} Realized Cap.`, + color, + datasetPath: `/${scale}-to-${datasetPrefix}realized-cap`, + }, + ...(datasetId + ? ([ + { + title: "Realized Cap.", + color: colors.bitcoin, + datasetPath: `/${scale}-to-realized-cap`, + defaultVisible: false, + }, + ] as const) + : []), + ], + }, + { + scale, + name: `Capitalization 1M Net Change`, + title: `${title} Realized Capitalization 1 Month Net Change`, + description: "", + icon: () => IconTablerStatusChange, + bottom: [ + { + title: `Net Change`, + seriesType: SeriesType.Based, + datasetPath: `/${scale}-to-${datasetPrefix}realized-cap-1m-net-change`, + }, + ], + }, + { + scale, + name: `Profit`, + title: `${title} Realized Profit`, + description: "", + icon: () => IconTablerCash, + bottom: [ + { + title: "Realized Profit", + datasetPath: `/${scale}-to-${datasetPrefix}realized-profit`, + color: colors.profit, + }, + ], + }, + { + scale, + name: "Loss", + title: `${title} Realized Loss`, + description: "", + icon: () => IconTablerCoffin, + bottom: [ + { + title: "Realized Loss", + datasetPath: `/${scale}-to-${datasetPrefix}realized-loss`, + color: colors.loss, + }, + ], + }, + { + scale, + name: `PNL`, + title: `${title} Realized Profit And Loss`, + description: "", + icon: () => IconTablerArrowsVertical, + bottom: [ + { + title: "Profit", + color: colors.profit, + datasetPath: `/${scale}-to-${datasetPrefix}realized-profit`, + seriesType: SeriesType.Based, + }, + { + title: "Loss", + color: colors.loss, + datasetPath: `/${scale}-to-${datasetPrefix}negative-realized-loss`, + seriesType: SeriesType.Based, + }, + ], + }, + { + scale, + name: `Net PNL`, + title: `${title} Net Realized Profit And Loss`, + description: "", + icon: () => IconTablerScale, + bottom: [ + { + title: "Net PNL", + seriesType: SeriesType.Based, + datasetPath: `/${scale}-to-${datasetPrefix}net-realized-profit-and-loss`, + }, + ], + }, + { + scale, + name: `Net PNL Relative To Market Cap`, + title: `${title} Net Realized Profit And Loss Relative To Market Capitalization`, + description: "", + icon: () => IconTablerDivide, + bottom: [ + { + title: "Net", + seriesType: SeriesType.Based, + datasetPath: `/${scale}-to-${datasetPrefix}net-realized-profit-and-loss-to-market-cap-ratio`, + }, + ], + }, + { + scale, + name: `Cumulative Profit`, + title: `${title} Cumulative Realized Profit`, + description: "", + icon: () => IconTablerSum, + bottom: [ + { + title: "Cumulative Realized Profit", + color: colors.profit, + datasetPath: `/${scale}-to-${datasetPrefix}cumulative-realized-profit`, + }, + ], + }, + { + scale, + name: "Cumulative Loss", + title: `${title} Cumulative Realized Loss`, + description: "", + icon: () => IconTablerSum, + bottom: [ + { + title: "Cumulative Realized Loss", + color: colors.loss, + datasetPath: `/${scale}-to-${datasetPrefix}cumulative-realized-loss`, + }, + ], + }, + { + scale, + name: `Cumulative Net PNL`, + title: `${title} Cumulative Net Realized Profit And Loss`, + description: "", + icon: () => IconTablerSum, + bottom: [ + { + title: "Cumulative Net Realized PNL", + seriesType: SeriesType.Based, + datasetPath: `/${scale}-to-${datasetPrefix}cumulative-net-realized-profit-and-loss`, + }, + ], + }, + { + scale, + name: `Cumulative Net PNL 30 Day Change`, + title: `${title} Cumulative Net Realized Profit And Loss 30 Day Change`, + description: "", + icon: () => IconTablerTimeDuration30, + bottom: [ + { + title: "Cumulative Net Realized PNL 30d Change", + datasetPath: `/${scale}-to-${datasetPrefix}cumulative-net-realized-profit-and-loss-1m-net-change`, + seriesType: SeriesType.Based, + }, + ], + }, + ], + }; +} diff --git a/app/src/scripts/presets/templates/cohort/supply.ts b/app/src/scripts/presets/templates/cohort/supply.ts new file mode 100644 index 000000000..3543d76a3 --- /dev/null +++ b/app/src/scripts/presets/templates/cohort/supply.ts @@ -0,0 +1,258 @@ +import { colors } from "/src/scripts/utils/colors"; + +import { datasetIdToPrefix } from "./utils"; + +export function createCohortPresetSupplyFolder({ + scale, + color, + datasetId, + title, +}: { + scale: ResourceScale; + datasetId: AnyPossibleCohortId; + title: string; + color: Color; +}): PartialPresetFolder { + const datasetPrefix = datasetIdToPrefix(datasetId); + + return { + name: "Supply", + tree: [ + { + name: "Absolute", + tree: [ + { + scale, + name: "All", + title: `${title} Profit And Loss`, + icon: () => IconTablerArrowsCross, + description: "", + + bottom: [ + { + title: "In Profit", + color: colors.profit, + datasetPath: `/${scale}-to-${datasetPrefix}supply-in-profit`, + }, + { + title: "In Loss", + color: colors.loss, + datasetPath: `/${scale}-to-${datasetPrefix}supply-in-loss`, + }, + { + title: "Total", + color: colors.white, + datasetPath: `/${scale}-to-${datasetPrefix}supply`, + }, + { + title: "Halved Total", + color: colors.gray, + datasetPath: `/${scale}-to-${datasetPrefix}halved-supply`, + options: { + lineStyle: 4, + }, + }, + ], + }, + { + scale, + name: `Total`, + title: `${title} Total supply`, + icon: () => IconTablerSum, + description: "", + bottom: [ + { + title: "Supply", + color, + datasetPath: `/${scale}-to-${datasetPrefix}supply`, + }, + ], + }, + { + scale, + name: "In Profit", + title: `${title} Supply In Profit`, + description: "", + icon: () => IconTablerTrendingUp, + bottom: [ + { + title: "Supply", + color: colors.profit, + datasetPath: `/${scale}-to-${datasetPrefix}supply-in-profit`, + }, + ], + }, + { + scale, + name: "In Loss", + title: `${title} Supply In Loss`, + description: "", + icon: () => IconTablerTrendingDown, + bottom: [ + { + title: "Supply", + color: colors.loss, + datasetPath: `/${scale}-to-${datasetPrefix}supply-in-loss`, + }, + ], + }, + ], + }, + { + name: "Relative To Circulating", + tree: [ + { + scale, + name: "All", + title: `${title} Profit And Loss Relative To Circulating Supply`, + description: "", + icon: () => IconTablerArrowsCross, + bottom: [ + { + title: "In Profit", + color: colors.profit, + datasetPath: `/${scale}-to-${datasetPrefix}supply-in-profit-to-circulating-supply-ratio`, + }, + { + title: "In Loss", + color: colors.loss, + datasetPath: `/${scale}-to-${datasetPrefix}supply-in-loss-to-circulating-supply-ratio`, + }, + { + title: "100%", + color: colors.white, + datasetPath: `/${scale}-to-${datasetPrefix}supply-to-circulating-supply-ratio`, + }, + { + title: "50%", + color: colors.gray, + datasetPath: `/${scale}-to-${datasetPrefix}halved-supply-to-circulating-supply-ratio`, + options: { + lineStyle: 4, + }, + }, + ], + }, + { + scale, + name: `Total`, + title: `${title} Total supply Relative To Circulating Supply`, + description: "", + icon: () => IconTablerSum, + bottom: [ + { + title: "Supply", + color, + datasetPath: `/${scale}-to-${datasetPrefix}supply-to-circulating-supply-ratio`, + }, + ], + }, + { + scale, + name: "In Profit", + title: `${title} Supply In Profit Relative To Circulating Supply`, + description: "", + icon: () => IconTablerTrendingUp, + bottom: [ + { + title: "Supply", + color: colors.profit, + datasetPath: `/${scale}-to-${datasetPrefix}supply-in-profit-to-circulating-supply-ratio`, + }, + ], + }, + { + scale, + name: "In Loss", + title: `${title} Supply In Loss Relative To Circulating Supply`, + description: "", + icon: () => IconTablerTrendingDown, + bottom: [ + { + title: "Supply", + color: colors.loss, + datasetPath: `/${scale}-to-${datasetPrefix}supply-in-loss-to-circulating-supply-ratio`, + }, + ], + }, + ], + }, + { + name: "Relative To Own", + tree: [ + { + scale, + name: "All", + title: `${title} Supply In Profit And Loss Relative To Own Supply`, + description: "", + icon: () => IconTablerArrowsCross, + bottom: [ + { + title: "In Profit", + color: colors.profit, + datasetPath: `/${scale}-to-${datasetPrefix}supply-in-profit-to-own-supply-ratio`, + }, + { + title: "In Loss", + color: colors.loss, + datasetPath: `/${scale}-to-${datasetPrefix}supply-in-loss-to-own-supply-ratio`, + }, + { + title: "100%", + color: colors.white, + datasetPath: `/${scale}-to-100`, + options: { + lastValueVisible: false, + }, + }, + { + title: "50%", + color: colors.gray, + datasetPath: `/${scale}-to-50`, + options: { + lineStyle: 4, + lastValueVisible: false, + }, + }, + ], + }, + { + scale, + name: "In Profit", + title: `${title} Supply In Profit Relative To Own Supply`, + description: "", + icon: () => IconTablerTrendingUp, + bottom: [ + { + title: "Supply", + color: colors.profit, + datasetPath: `/${scale}-to-${datasetPrefix}supply-in-profit-to-own-supply-ratio`, + }, + ], + }, + { + scale, + name: "In Loss", + title: `${title} Supply In Loss Relative To Own Supply`, + description: "", + icon: () => IconTablerTrendingDown, + bottom: [ + { + title: "Supply", + color: colors.loss, + datasetPath: `/${scale}-to-${datasetPrefix}supply-in-loss-to-own-supply-ratio`, + }, + ], + }, + ], + }, + // createMomentumPresetFolder({ + // datasets: datasets[scale], + // scale, + // id: `${scale}-${id}-supply-in-profit-and-loss-percentage-self`, + // title: `${title} Supply In Profit And Loss (% Self)`, + // datasetId: `${datasetId}SupplyPNL%Self`, + // }), + ], + }; +} diff --git a/app/src/scripts/presets/templates/cohort/unrealized.ts b/app/src/scripts/presets/templates/cohort/unrealized.ts new file mode 100644 index 000000000..f23748d3f --- /dev/null +++ b/app/src/scripts/presets/templates/cohort/unrealized.ts @@ -0,0 +1,101 @@ +import { colors } from "/src/scripts/utils/colors"; + +import { SeriesType } from "../../enums"; +import { datasetIdToPrefix } from "./utils"; + +export function createCohortPresetUnrealizedFolder({ + scale, + color, + datasetId, + title, +}: { + scale: ResourceScale; + datasetId: AnyPossibleCohortId; + title: string; + color: Color; +}): PartialPresetFolder { + const datasetPrefix = datasetIdToPrefix(datasetId); + + return { + name: "Unrealized", + tree: [ + { + scale, + name: `Profit`, + title: `${title} Unrealized Profit`, + description: "", + icon: () => IconTablerMoodDollar, + bottom: [ + { + title: "Profit", + datasetPath: `/${scale}-to-${datasetPrefix}unrealized-profit`, + color: colors.profit, + }, + ], + }, + { + scale, + name: "Loss", + title: `${title} Unrealized Loss`, + description: "", + icon: () => IconTablerMoodSadDizzy, + bottom: [ + { + title: "Loss", + datasetPath: `/${scale}-to-${datasetPrefix}unrealized-loss`, + color: colors.loss, + }, + ], + }, + { + scale, + name: `PNL`, + title: `${title} Unrealized Profit And Loss`, + description: "", + icon: () => IconTablerArrowsVertical, + bottom: [ + { + title: "Profit", + color: colors.profit, + datasetPath: `/${scale}-to-${datasetPrefix}unrealized-profit`, + seriesType: SeriesType.Based, + }, + { + title: "Loss", + color: colors.loss, + datasetPath: `/${scale}-to-${datasetPrefix}negative-unrealized-loss`, + seriesType: SeriesType.Based, + }, + ], + }, + { + scale, + name: `Net PNL`, + title: `${title} Net Unrealized Profit And Loss`, + description: "", + icon: () => IconTablerScale, + bottom: [ + { + title: "Net Unrealized PNL", + datasetPath: `/${scale}-to-${datasetPrefix}net-unrealized-profit-and-loss`, + seriesType: SeriesType.Based, + }, + ], + }, + { + scale, + name: `Net PNL Relative To Market Cap`, + title: `${title} Net Unrealized Profit And Loss Relative To Total Market Capitalization`, + description: "", + icon: () => IconTablerDivide, + bottom: [ + { + title: "Relative Net Unrealized PNL", + datasetPath: `/${scale}-to-${datasetPrefix}net-unrealized-profit-and-loss-to-market-cap-ratio`, + seriesType: SeriesType.Based, + }, + ], + }, + ], + }; +} diff --git a/app/src/scripts/presets/templates/cohort/utils.ts b/app/src/scripts/presets/templates/cohort/utils.ts new file mode 100644 index 000000000..190986547 --- /dev/null +++ b/app/src/scripts/presets/templates/cohort/utils.ts @@ -0,0 +1,5 @@ +export function datasetIdToPrefix( + datasetId: AnyPossibleCohortId, +): AnyDatasetPrefix { + return datasetId ? (`${datasetId}-` as const) : ("" as const); +} diff --git a/app/src/scripts/presets/templates/cohort/utxo.ts b/app/src/scripts/presets/templates/cohort/utxo.ts new file mode 100644 index 000000000..9135560dc --- /dev/null +++ b/app/src/scripts/presets/templates/cohort/utxo.ts @@ -0,0 +1,35 @@ +import { datasetIdToPrefix } from "./utils"; + +export function createCohortPresetUTXOFolder({ + scale, + color, + datasetId, + title, +}: { + scale: ResourceScale; + datasetId: AnyPossibleCohortId; + title: string; + color: Color; +}): PartialPresetFolder { + const datasetPrefix = datasetIdToPrefix(datasetId); + + return { + name: "UTXOs", + tree: [ + { + scale, + name: `Count`, + title: `${title} Unspent Transaction Outputs Count`, + description: "", + icon: () => IconTablerTicket, + bottom: [ + { + title: "Count", + color, + datasetPath: `/${scale}-to-${datasetPrefix}utxo-count`, + }, + ], + }, + ], + }; +} diff --git a/app/src/scripts/presets/templates/momentum.ts b/app/src/scripts/presets/templates/momentum.ts index 2331f5f34..5d764f223 100644 --- a/app/src/scripts/presets/templates/momentum.ts +++ b/app/src/scripts/presets/templates/momentum.ts @@ -24,13 +24,13 @@ // scale, // id, // title, -// datasetKey, +// datasetId, // }: { // datasets: Record<`${Key}${MomentumKey}`, Dataset>; // scale: Scale; // id: string; // title: string; -// datasetKey: Key; +// datasetId: Key; // }): PartialPresetFolder { // return { // id: `${scale}-${id}-momentum`, @@ -50,7 +50,7 @@ // title: "Momentum", // colors: colors.momentum, // seriesType: SeriesType.Histogram, -// dataset: datasets[`${datasetKey}Momentum`], +// dataset: datasets[`${datasetId}Momentum`], // options: { // priceScaleId: PRICE_SCALE_MOMENTUM_ID, // lastValueVisible: false, @@ -82,7 +82,7 @@ // { // title: "Bitcoin Returns", // dataset: -// datasets[`${datasetKey}MomentumBLSHBitcoinReturns`], +// datasets[`${datasetId}MomentumBLSHBitcoinReturns`], // color: colors.bitcoin, // }, // ], @@ -106,7 +106,7 @@ // list: [ // { // title: "Dollar Returns", -// dataset: datasets[`${datasetKey}MomentumBLSHDollarReturns`], +// dataset: datasets[`${datasetId}MomentumBLSHDollarReturns`], // color: colors.dollars, // }, // ], diff --git a/app/src/scripts/presets/templates/ratio.ts b/app/src/scripts/presets/templates/ratio.ts index e740586a7..3ecc4ca4e 100644 --- a/app/src/scripts/presets/templates/ratio.ts +++ b/app/src/scripts/presets/templates/ratio.ts @@ -22,7 +22,7 @@ // scale, // id, // title, -// datasetKey, +// datasetId, // color, // }: { // datasets: Record<`${Key}${RatioKey}`, Dataset>; @@ -30,7 +30,7 @@ // id: string; // title: string; // color: string; -// datasetKey: Key; +// datasetId: Key; // }): PartialPresetFolder { // return { // id: `${scale}-${id}-ratio`, @@ -52,7 +52,7 @@ // { // title: "Ratio", // seriesType: SeriesType.Based, -// dataset: datasets[`${datasetKey}Ratio`], +// dataset: datasets[`${datasetId}Ratio`], // options: { // base: 1, // }, @@ -83,7 +83,7 @@ // title: "Ratio", // seriesType: SeriesType.Based, // color: colors.gray, -// dataset: datasets[`${datasetKey}Ratio`], +// dataset: datasets[`${datasetId}Ratio`], // options: { // base: 1, // }, @@ -91,12 +91,12 @@ // { // title: "7 Day Moving Average", // color: colors.closes7DMA, -// dataset: datasets[`${datasetKey}Ratio7DayMovingAverage`], +// dataset: datasets[`${datasetId}Ratio7DayMovingAverage`], // }, // { // title: "1 Year Moving Average", // color: colors.closes1YMA, -// dataset: datasets[`${datasetKey}Ratio1YearMovingAverage`], +// dataset: datasets[`${datasetId}Ratio1YearMovingAverage`], // }, // ], // }); @@ -108,7 +108,7 @@ // scale, // id: `${scale}-${id}-ratio-averages`, // title: `${title} Ratio Moving Averages`, -// datasetKey: `${datasetKey}Ratio`, +// datasetId: `${datasetId}Ratio`, // }), // ], // }, @@ -135,7 +135,7 @@ // title: "Ratio", // color: colors.white, // seriesType: SeriesType.Based, -// dataset: datasets[`${datasetKey}Ratio`], +// dataset: datasets[`${datasetId}Ratio`], // options: { // base: 1, // options: { @@ -147,20 +147,20 @@ // { // id: "99.9-percentile", // title: "99.9th Percentile", -// dataset: datasets[`${datasetKey}Ratio99.9Percentile`], +// dataset: datasets[`${datasetId}Ratio99.9Percentile`], // color: colors.extremeMax, // }, // { // id: "99.5-percentile", // title: "99.5th Percentile", // color: colors.extremeMiddle, -// dataset: datasets[`${datasetKey}Ratio99.5Percentile`], +// dataset: datasets[`${datasetId}Ratio99.5Percentile`], // }, // { // id: "99-percentile", // title: "99th Percentile", // color: colors.extremeMin, -// dataset: datasets[`${datasetKey}Ratio99Percentile`], +// dataset: datasets[`${datasetId}Ratio99Percentile`], // }, // ], // }); @@ -185,7 +185,7 @@ // title: "Ratio", // color: colors.white, // seriesType: SeriesType.Based, -// dataset: datasets[`${datasetKey}Ratio`], +// dataset: datasets[`${datasetId}Ratio`], // options: { // base: 1, // options: { @@ -198,19 +198,19 @@ // id: "1-percentile", // title: "1st Percentile", // color: colors.extremeMin, -// dataset: datasets[`${datasetKey}Ratio1Percentile`], +// dataset: datasets[`${datasetId}Ratio1Percentile`], // }, // { // id: "0.5-percentile", // title: "0.5th Percentile", // color: colors.extremeMiddle, -// dataset: datasets[`${datasetKey}Ratio0.5Percentile`], +// dataset: datasets[`${datasetId}Ratio0.5Percentile`], // }, // { // id: "0.1-percentile", // title: "0.1th Percentile", // color: colors.extremeMax, -// dataset: datasets[`${datasetKey}Ratio0.1Percentile`], +// dataset: datasets[`${datasetId}Ratio0.1Percentile`], // }, // ], // }); @@ -231,19 +231,19 @@ // id: "99.9-percentile", // title: "99.9th Percentile", // color: colors.extremeMax, -// dataset: datasets[`${datasetKey}Ratio99.9Price`], +// dataset: datasets[`${datasetId}Ratio99.9Price`], // }, // { // id: "99.5-percentile", // title: "99.5th Percentile", // color: colors.extremeMiddle, -// dataset: datasets[`${datasetKey}Ratio99.5Price`], +// dataset: datasets[`${datasetId}Ratio99.5Price`], // }, // { // id: "99-percentile", // title: "99th Percentile", // color: colors.extremeMin, -// dataset: datasets[`${datasetKey}Ratio99Price`], +// dataset: datasets[`${datasetId}Ratio99Price`], // }, // ], // }); @@ -264,19 +264,19 @@ // id: "1-percentile", // title: "1st Percentile", // color: colors.extremeMin, -// dataset: datasets[`${datasetKey}Ratio1Price`], +// dataset: datasets[`${datasetId}Ratio1Price`], // }, // { // id: "0.5-percentile", // title: "0.5th Percentile", // color: colors.extremeMiddle, -// dataset: datasets[`${datasetKey}Ratio0.5Price`], +// dataset: datasets[`${datasetId}Ratio0.5Price`], // }, // { // id: "0.1-percentile", // title: "0.1th Percentile", // color: colors.extremeMax, -// dataset: datasets[`${datasetKey}Ratio0.1Price`], +// dataset: datasets[`${datasetId}Ratio0.1Price`], // }, // ], // }); diff --git a/app/src/scripts/presets/transactions/index.ts b/app/src/scripts/presets/transactions/index.ts index 55aec464f..f71bd2d41 100644 --- a/app/src/scripts/presets/transactions/index.ts +++ b/app/src/scripts/presets/transactions/index.ts @@ -1,5 +1,4 @@ import { colors } from "../../utils/colors"; -import { applySeriesList } from "../apply"; export function createPresets(scale: ResourceScale) { return { @@ -11,28 +10,23 @@ export function createPresets(scale: ResourceScale) { name: "Count", title: "Transaction Count", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "1M SMA", - color: colors.momentumYellow, - dataset: params.datasets[scale].transaction_count_1m_sma, - }, - { - title: "1W SMA", - color: colors.bitcoin, - dataset: params.datasets[scale].transaction_count_1w_sma, - }, - { - title: "Raw", - color: colors.darkBitcoin, - dataset: params.datasets[scale].transaction_count, - }, - ], - }); - }, + bottom: [ + { + title: "1M SMA", + color: colors.momentumYellow, + datasetPath: `/${scale}-to-transaction-count-1m-sma`, + }, + { + title: "1W SMA", + color: colors.bitcoin, + datasetPath: `/${scale}-to-transaction-count-1w-sma`, + }, + { + title: "Raw", + color: colors.darkBitcoin, + datasetPath: `/${scale}-to-transaction-count`, + }, + ], }, { @@ -44,28 +38,23 @@ export function createPresets(scale: ResourceScale) { name: "In Bitcoin", title: "Transaction Volume", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "1M SMA", - color: colors.momentumYellow, - dataset: params.datasets[scale].transaction_volume_1m_sma, - }, - { - title: "1W SMA", - color: colors.bitcoin, - dataset: params.datasets[scale].transaction_volume_1w_sma, - }, - { - title: "Raw", - color: colors.darkBitcoin, - dataset: params.datasets[scale].transaction_volume, - }, - ], - }); - }, + bottom: [ + { + title: "1M SMA", + color: colors.momentumYellow, + datasetPath: `/${scale}-to-transaction-volume-1m-sma`, + }, + { + title: "1W SMA", + color: colors.bitcoin, + datasetPath: `/${scale}-to-transaction-volume-1w-sma`, + }, + { + title: "Raw", + color: colors.darkBitcoin, + datasetPath: `/${scale}-to-transaction-volume`, + }, + ], }, { scale, @@ -73,36 +62,26 @@ export function createPresets(scale: ResourceScale) { name: "In Dollars", title: "Transaction Volume In Dollars", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - priceScaleOptions: { - mode: 1, - }, - bottom: [ - { - title: "1M SMA", - color: colors.lightDollars, - dataset: - params.datasets[scale] - .transaction_volume_in_dollars_1m_sma, - }, - { - title: "1W SMA", - color: colors.dollars, - dataset: - params.datasets[scale] - .transaction_volume_in_dollars_1w_sma, - }, - { - title: "Raw", - color: colors.darkDollars, - dataset: - params.datasets[scale].transaction_volume_in_dollars, - }, - ], - }); + priceScaleOptions: { + mode: 1, }, + bottom: [ + { + title: "1M SMA", + color: colors.lightDollars, + datasetPath: `/${scale}-to-transaction-volume-in-dollars-1m-sma`, + }, + { + title: "1W SMA", + color: colors.dollars, + datasetPath: `/${scale}-to-transaction-volume-in-dollars-1w-sma`, + }, + { + title: "Raw", + color: colors.darkDollars, + datasetPath: `/${scale}-to-transaction-volume-in-dollars`, + }, + ], }, ], }, @@ -116,19 +95,13 @@ export function createPresets(scale: ResourceScale) { name: "In Bitcoin", title: "Annualized Transaction Volume", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Volume", - color: colors.bitcoin, - dataset: - params.datasets[scale].annualized_transaction_volume, - }, - ], - }); - }, + bottom: [ + { + title: "Volume", + color: colors.bitcoin, + datasetPath: `/${scale}-to-annualized-transaction-volume`, + }, + ], }, { scale, @@ -136,20 +109,13 @@ export function createPresets(scale: ResourceScale) { name: "In Dollars", title: "Annualized Transaction Volume In Dollars", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Volume", - color: colors.dollars, - dataset: - params.datasets[scale] - .annualized_transaction_volume_in_dollars, - }, - ], - }); - }, + bottom: [ + { + title: "Volume", + color: colors.dollars, + datasetPath: `/${scale}-to-annualized-transaction-volume-in-dollars`, + }, + ], }, ], }, @@ -159,18 +125,13 @@ export function createPresets(scale: ResourceScale) { name: "Velocity", title: "Transactions Velocity", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "Transactions Velocity", - color: colors.bitcoin, - dataset: params.datasets[scale].transaction_velocity, - }, - ], - }); - }, + bottom: [ + { + title: "Transactions Velocity", + color: colors.bitcoin, + datasetPath: `/${scale}-to-transaction-velocity`, + }, + ], }, { scale, @@ -178,28 +139,23 @@ export function createPresets(scale: ResourceScale) { name: "Per Second", title: "Transactions Per Second", description: "", - applyPreset(params) { - return applySeriesList({ - ...params, - bottom: [ - { - title: "1M SMA", - color: colors.lightBitcoin, - dataset: params.datasets[scale].transactions_per_second_1m_sma, - }, - { - title: "1W SMA", - color: colors.bitcoin, - dataset: params.datasets[scale].transactions_per_second_1w_sma, - }, - { - title: "Raw", - color: colors.darkBitcoin, - dataset: params.datasets[scale].transactions_per_second, - }, - ], - }); - }, + bottom: [ + { + title: "1M SMA", + color: colors.lightBitcoin, + datasetPath: `/${scale}-to-transactions-per-second-1m-sma`, + }, + { + title: "1W SMA", + color: colors.bitcoin, + datasetPath: `/${scale}-to-transactions-per-second-1w-sma`, + }, + { + title: "Raw", + color: colors.darkBitcoin, + datasetPath: `/${scale}-to-transactions-per-second`, + }, + ], }, ], } satisfies PartialPresetFolder; diff --git a/app/src/scripts/presets/types.d.ts b/app/src/scripts/presets/types.d.ts index f990c67f8..72e7656ee 100644 --- a/app/src/scripts/presets/types.d.ts +++ b/app/src/scripts/presets/types.d.ts @@ -1,11 +1,16 @@ -interface PartialPreset { +interface PresetParams { + priceScaleOptions?: DeepPartialPriceScaleOptions; + top?: SeriesConfig[]; + bottom?: SeriesConfig[]; +} + +type PartialPreset = { scale: ResourceScale; icon?: () => JSXElement; name: string; title: string; - applyPreset: ApplyPreset; description: string; -} +} & PresetParams; interface Preset extends PartialPreset { id: string; @@ -19,15 +24,15 @@ type FilePath = { name: string; }[]; -type ApplyPreset = (params: { - charts: RWS; - parentDiv: HTMLDivElement; - datasets: Datasets; - preset: Preset; - legendSetter: Setter; - dark: Accessor; - activeIds: RWS; -}) => void; +// type ApplyPreset = (params: { +// charts: RWS; +// parentDiv: HTMLDivElement; +// datasets: Datasets; +// preset: Preset; +// legendSetter: Setter; +// dark: Accessor; +// activeIds: RWS; +// }) => void; interface PartialPresetFolder { name: string; @@ -41,8 +46,6 @@ interface PresetFolder extends PartialPresetFolder { type PartialPresetTree = (PartialPreset | PartialPresetFolder)[]; type PresetTree = (Preset | PresetFolder)[]; -// type PresetList = Preset[]; -// type FavoritePresets = Accessor; type PresetsHistory = { date: Date; preset: Preset }[]; type PresetsHistorySignal = RWS; @@ -70,3 +73,53 @@ interface ChartObject { legendList: SeriesLegend[]; debouncedSetMinMaxMarkers: VoidFunction; } + +type EnumSeriesType = typeof import("./enums").SeriesType; + +type SeriesConfig = + | { + // datasetPath: DatasetPath; + datasetPath: AnyDatasetPath; + color?: Color; + topColor?: Color; + bottomColor?: Color; + colors?: undefined; + seriesType: EnumSeriesType["Based"]; + title: string; + options?: BaselineSeriesOptions; + priceScaleOptions?: DeepPartialPriceScaleOptions; + defaultVisible?: boolean; + } + | { + // datasetPath: DatasetPath; + datasetPath: AnyDatasetPath; + color?: Color; + colors?: Color[]; + seriesType: EnumSeriesType["Histogram"]; + title: string; + options?: DeepPartialHistogramOptions; + priceScaleOptions?: DeepPartialPriceScaleOptions; + defaultVisible?: boolean; + } + | { + // datasetPath: DatasetPath; + datasetPath: AnyDatasetPath; + seriesType: EnumSeriesType["Candlestick"]; + priceScaleOptions?: DeepPartialPriceScaleOptions; + colors?: undefined; + color?: undefined; + options?: DeepPartialLineOptions; + defaultVisible?: boolean; + title: string; + } + | { + // datasetPath: DatasetPath; + datasetPath: AnyDatasetPath; + color: Color; + colors?: undefined; + seriesType?: EnumSeriesType["Line"]; + title: string; + options?: DeepPartialLineOptions; + priceScaleOptions?: DeepPartialPriceScaleOptions; + defaultVisible?: boolean; + }; diff --git a/app/src/scripts/utils/date.ts b/app/src/scripts/utils/date.ts index ce7fc32e3..8b6ea915f 100644 --- a/app/src/scripts/utils/date.ts +++ b/app/src/scripts/utils/date.ts @@ -4,3 +4,10 @@ export const dateToString = (date: Date) => date.toJSON().split("T")[0]; export const getNumberOfDaysBetweenTwoDates = (oldest: Date, youngest: Date) => Math.round(Math.abs((youngest.getTime() - oldest.getTime()) / ONE_DAY_IN_MS)); + +export function dateFromTime(time: Time) { + return typeof time === "string" + ? new Date(time) + : // @ts-ignore + new Date(time.year, time.month, time.day); +} diff --git a/app/src/styles.css b/app/src/styles.css index e52712405..62066914a 100644 --- a/app/src/styles.css +++ b/app/src/styles.css @@ -6,7 +6,7 @@ @font-face { font-family: "Lexend"; - font-display: "swap"; + font-display: "auto"; src: url("/fonts/Lexend.var.woff2") format("woff2"); font-weight: 100 900; font-optical-sizing: auto; diff --git a/app/src/types/auto-imports.d.ts b/app/src/types/auto-imports.d.ts index a43c41fbf..9f19a2083 100644 --- a/app/src/types/auto-imports.d.ts +++ b/app/src/types/auto-imports.d.ts @@ -101,6 +101,7 @@ declare global { const IconTablerCurrencyYuan: typeof import('~icons/tabler/currency-yuan.jsx')['default'] const IconTablerCurrencyZloty: typeof import('~icons/tabler/currency-zloty.jsx')['default'] const IconTablerCut: typeof import('~icons/tabler/cut.jsx')['default'] + const IconTablerDatabaseExport: typeof import('~icons/tabler/database-export.jsx')['default'] const IconTablerDice: (typeof import("~icons/tabler/dice.jsx"))["default"] const IconTablerDice1: typeof import('~icons/tabler/dice1.jsx')['default'] const IconTablerDice1Filled: typeof import('~icons/tabler/dice1-filled.jsx')['default'] @@ -120,6 +121,8 @@ declare global { const IconTablerDollar: typeof import('~icons/tabler/dollar.jsx')['default'] const IconTablerDollarReceipt: (typeof import("~icons/tabler/dollar-receipt.jsx"))["default"] const IconTablerDoor: (typeof import("~icons/tabler/door.jsx"))["default"] + const IconTablerDownlaod: typeof import('~icons/tabler/downlaod.jsx')['default'] + const IconTablerDownload: typeof import('~icons/tabler/download.jsx')['default'] const IconTablerExternalLink: typeof import('~icons/tabler/external-link.jsx')['default'] const IconTablerFeather: typeof import('~icons/tabler/feather.jsx')['default'] const IconTablerFile: typeof import('~icons/tabler/file.jsx')['default'] diff --git a/parser/src/actions/parse.rs b/parser/src/actions/parse.rs index a0cc431f5..65b65b99a 100644 --- a/parser/src/actions/parse.rs +++ b/parser/src/actions/parse.rs @@ -12,6 +12,7 @@ use crate::{ Databases, TxidToTxData, TxoutIndexToAddressIndex, TxoutIndexToAmount, }, datasets::{AllDatasets, InsertData}, + log, states::{ AddressCohortsInputStates, AddressCohortsOutputStates, AddressCohortsRealizedStates, States, UTXOCohortsOneShotStates, UTXOCohortsSentStates, @@ -53,6 +54,8 @@ pub fn parse( timestamp, }: ParseData, ) { + // log(&format!("{height}")); + // If false, expect that the code is flawless // or create a 0 value txid database let enable_check_if_txout_value_is_zero_in_db: bool = true; @@ -539,10 +542,6 @@ pub fn parse( } }); - // if !txin_ordered_tx_datas.is_empty() { - // panic!("txin_ordered_tx_indexes should've been fully consumed"); - // } - let mut utxo_cohorts_sent_states = UTXOCohortsSentStates::default(); let mut utxo_cohorts_one_shot_states = UTXOCohortsOneShotStates::default(); // let mut utxo_cohorts_received_states = UTXOCohortsReceivedStates::default(); diff --git a/parser/src/states/cohorts_states/utxo/cohort_durable_states.rs b/parser/src/states/cohorts_states/utxo/cohort_durable_states.rs index f6bdfe7f4..dbc3b977d 100644 --- a/parser/src/states/cohorts_states/utxo/cohort_durable_states.rs +++ b/parser/src/states/cohorts_states/utxo/cohort_durable_states.rs @@ -61,6 +61,8 @@ impl UTXOCohortDurableStates { dbg!( report, "cents_to_amount decrement failed", + rounded_price, + price, amount, utxo_count ); diff --git a/parser/src/states/cohorts_states/utxo/cohorts_durable_states.rs b/parser/src/states/cohorts_states/utxo/cohorts_durable_states.rs index a134064a0..60ea38795 100644 --- a/parser/src/states/cohorts_states/utxo/cohorts_durable_states.rs +++ b/parser/src/states/cohorts_states/utxo/cohorts_durable_states.rs @@ -129,7 +129,10 @@ impl UTXOCohortsDurableStates { self.initial_filtered_apply(&days_old, &year, |state| { state .decrement(amount, utxo_count, block_data.price) - .unwrap(); + .unwrap_or_else(|report| { + dbg!(report, block_data, sent_data, previous_last_block_data); + panic!() + }); }) } diff --git a/server/restart-cloudflared.sh b/server/restart-cloudflared.sh new file mode 100755 index 000000000..fa1695f7a --- /dev/null +++ b/server/restart-cloudflared.sh @@ -0,0 +1,4 @@ +sudo launchctl stop com.cloudflare.cloudflared +sudo launchctl unload /Library/LaunchDaemons/com.cloudflare.cloudflared.plist +sudo launchctl load /Library/LaunchDaemons/com.cloudflare.cloudflared.plist +sudo launchctl start com.cloudflare.cloudflared diff --git a/server/src/main.rs b/server/src/main.rs index bb8191a6b..da6916a19 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -38,7 +38,7 @@ async fn main() -> color_eyre::Result<()> { let routes = Routes::build(); - routes.generate_grouped_keys_to_url_path_file(); + routes.generate_front_end_files(); let state = AppState { routes: Arc::new(routes), diff --git a/server/src/routes.rs b/server/src/routes.rs index 954c85006..39a994e3c 100644 --- a/server/src/routes.rs +++ b/server/src/routes.rs @@ -1,4 +1,7 @@ -use std::collections::{BTreeMap, HashMap}; +use std::{ + collections::{BTreeMap, HashMap}, + fs, +}; use derive_deref::{Deref, DerefMut}; use itertools::Itertools; @@ -87,29 +90,57 @@ impl Routes { routes } - pub fn generate_grouped_keys_to_url_path_file(&self) { - let transform = |map: &HashMap| -> BTreeMap { + pub fn generate_front_end_files(&self) { + self.generate_json_group_files(); + self.generate_definition_files(); + } + + fn generate_json_group_files(&self) { + let map_to_group = |map: &HashMap| -> BTreeMap { map.iter() .map(|(key, route)| (key.to_owned(), route.url_path.to_owned())) .collect() }; - let date_paths = transform(&self.date); - let height_paths = transform(&self.height); - let last_paths = transform(&self.last); + let date_group = map_to_group(&self.date); + let height_group = map_to_group(&self.height); + let last_group = map_to_group(&self.last); - let paths = Paths(Grouped { - date: date_paths, - height: height_paths, - last: last_paths, + let groups = Paths(Grouped { + date: date_group, + height: height_group, + last: last_group, }); let _ = Json::export( &format!("{DATASETS_PATH}/grouped_keys_to_url_path.json"), - &paths, + &groups, ); } + fn generate_definition_files(&self) { + let map_to_type = |name: &str, map: &HashMap| -> String { + let paths = map + .values() + .map(|route| format!("\"{}\"", route.url_path)) + .join(" | "); + + format!("export type {}Path = {};\n", name, paths) + }; + + let date_type = map_to_type("Date", &self.date); + + let height_type = map_to_type("Height", &self.height); + + let last_type = map_to_type("Last", &self.last); + + fs::write( + format!("{DATASETS_PATH}/paths.d.ts"), + format!("{date_type}\n{height_type}\n{last_type}"), + ) + .unwrap(); + } + pub fn to_full_paths(&self, host: String) -> Paths { let url = { let scheme = if host.contains("0.0.0.0") || host.contains("localhost") {